Module: H3::Traversal

Extended by:
Bindings::Base
Included in:
H3
Defined in:
lib/h3/traversal.rb

Overview

Grid traversal functions

Instance Method Summary collapse

Methods included from Bindings::Base

extended

Instance Method Details

#h3_distance(origin, h3_index) ⇒ Integer

Derive the distance between two H3 indexes.

Examples:

Derive the distance between two H3 indexes.

H3.h3_distance(617700169983721471, 617700169959866367)
5

Parameters:

  • origin (Integer)

    Origin H3 index

  • h3_index (Integer)

    H3 index

Returns:

  • (Integer)

    Distance between indexes.



33
# File 'lib/h3/traversal.rb', line 33

attach_function :h3_distance, :h3Distance, [ :h3_index, :h3_index], :int

#hex_range(origin, k) ⇒ Array<Integer>

Derives H3 indexes within k distance of the origin H3 index.

Similar to #k_ring, except that an error is raised when one of the indexes returned is a pentagon or is in the pentagon distortion area.

k-ring 0 is defined as the origin index, k-ring 1 is defined as k-ring 0 and all neighboring indexes, and so on.

Output is inserted into the array in order of increasing distance from the origin.

Examples:

Derive the hex range for a given H3 index with k of 0.

H3.hex_range(617700169983721471, 0)
[617700169983721471]

Derive the hex range for a given H3 index with k of 1.

H3.hex_range(617700169983721471, 1)
[
  617700169983721471, 617700170047946751, 617700169984245759,
  617700169982672895, 617700169983983615, 617700170044276735,
  617700170044014591
]

Parameters:

  • origin (Integer)

    Origin H3 index

  • k (Integer)

    K distance.

Returns:

  • (Array<Integer>)

    Array of H3 indexes within the k-range.

Raises:

  • (ArgumentError)

    Raised if the range contains a pentagon.



63
64
65
66
67
68
69
# File 'lib/h3/traversal.rb', line 63

def hex_range(origin, k)
  max_hexagons = max_kring_size(k)
  hexagons = FFI::MemoryPointer.new(:ulong_long, max_hexagons)
  pentagonal_distortion = Bindings::Private.hex_range(origin, k, hexagons)
  raise(ArgumentError, "Specified hexagon range contains a pentagon") if pentagonal_distortion
  hexagons.read_array_of_ulong_long(max_hexagons).reject(&:zero?)
end

#hex_range_distances(origin, k) ⇒ Hash

Derives the hex range for the given origin at k distance, sub-grouped by distance.

Examples:

Derive hex range at distance 2

H3.hex_range_distances(617700169983721471, 2)
{
  0 => [617700169983721471],
  1 = >[
    617700170047946751, 617700169984245759, 617700169982672895,
    617700169983983615, 617700170044276735, 617700170044014591
  ],
  2 => [
    617700170048995327, 617700170047684607, 617700170048471039,
    617700169988177919, 617700169983197183, 617700169983459327,
    617700169982935039, 617700175096053759, 617700175097102335,
    617700170043752447, 617700170043490303, 617700170045063167
  ]
}

Parameters:

  • origin (Integer)

    Origin H3 index.

  • k (Integer)

    K distance.

Returns:

  • (Hash)

    Hex range grouped by distance.

Raises:

  • (ArgumentError)

    Raised when the hex range contains a pentagon.



220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/h3/traversal.rb', line 220

def hex_range_distances(origin, k)
  max_out_size = max_kring_size(k)
  out = FFI::MemoryPointer.new(H3_INDEX, max_out_size)
  distances = FFI::MemoryPointer.new(:int, max_out_size)
  pentagonal_distortion = Bindings::Private.hex_range_distances(origin, k, out, distances)
  raise(ArgumentError, "Specified hexagon range contains a pentagon") if pentagonal_distortion

  hexagons = out.read_array_of_ulong_long(max_out_size)
  distances = distances.read_array_of_int(max_out_size)

  Hash[
    distances.zip(hexagons).group_by(&:first).map { |d, hs| [d, hs.map(&:last)] }
  ]
end

#hex_ranges(h3_set, k, grouped: true) ⇒ Hash

Derives H3 indexes within k distance for each H3 index in the set.

Examples:

Derive the hex ranges for a given H3 set with k of 0.

H3.hex_ranges([617700169983721471, 617700169982672895], 1)
{
  617700169983721471 => [
    [617700169983721471],
    [
      617700170047946751, 617700169984245759, 617700169982672895,
      617700169983983615, 617700170044276735, 617700170044014591
    ]
  ],
  617700169982672895 = > [
    [617700169982672895],
    [
      617700169984245759, 617700169983197183, 617700169983459327,
      617700169982935039, 617700169983983615, 617700169983721471
    ]
  ]
}

Derive the hex ranges for a given H3 set with k of 0 ungrouped.

H3.hex_ranges([617700169983721471, 617700169982672895], 1, grouped: false)
[
  617700169983721471, 617700170047946751, 617700169984245759,
  617700169982672895, 617700169983983615, 617700170044276735,
  617700170044014591, 617700169982672895, 617700169984245759,
  617700169983197183, 617700169983459327, 617700169982935039,
  617700169983983615, 617700169983721471
]

Parameters:

  • h3_set (Array<Integer>)

    Set of H3 indexes

  • k (Integer)

    K distance.

  • grouped (Boolean) (defaults to: true)

    Whether to group the output. Default true.

Returns:

  • (Hash)

    Hash of H3 index keys, with array values grouped by k-ring.

Raises:

  • (ArgumentError)

    Raised if any of the ranges contains a pentagon.

See Also:



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/h3/traversal.rb', line 180

def hex_ranges(h3_set, k, grouped: true)
  h3_range_indexes = hex_ranges_ungrouped(h3_set, k)
  return h3_range_indexes unless grouped
  out = {}
  h3_range_indexes.each_slice(max_kring_size(k)).each do |indexes|
    h3_index = indexes.first

    out[h3_index] = 0.upto(k).map do |j|
      start  = j == 0 ? 0 : max_kring_size(j-1)
      length = max_hex_ring_size(j)
      indexes.slice(start, length)
    end
  end
  out
end

#hex_ring(origin, k) ⇒ Array<Integer>

Derives the hollow hexagonal ring centered at origin with sides of length k.

An error is raised when one of the indexes returned is a pentagon or is in the pentagon distortion area.

Examples:

Derive the hex ring for the H3 index at k = 1

H3.hex_ring(617700169983721471, 1)
[
  617700170044014591, 617700170047946751, 617700169984245759,
  617700169982672895, 617700169983983615, 617700170044276735
]

Parameters:

  • origin (Integer)

    Origin H3 index.

  • k (Integer)

    K distance.

Returns:

  • (Array<Integer>)

    Array of H3 indexes within the hex ring.

Raises:

  • (ArgumentError)

    Raised if the hex ring contains a pentagon.



117
118
119
120
121
122
123
# File 'lib/h3/traversal.rb', line 117

def hex_ring(origin, k)
  max_hexagons = max_hex_ring_size(k)
  hexagons = FFI::MemoryPointer.new(:ulong_long, max_hexagons)
  pentagonal_distortion = Bindings::Private.hex_ring(origin, k, hexagons)
  raise(ArgumentError, "The hex ring contains a pentagon") if pentagonal_distortion
  hexagons.read_array_of_ulong_long(max_hexagons).reject(&:zero?)
end

#k_ring(origin, k) ⇒ Array<Integer>

Derives H3 indexes within k distance of the origin H3 index.

k-ring 0 is defined as the origin index, k-ring 1 is defined as k-ring 0 and all neighboring indexes, and so on.

Examples:

Derive the k-ring for a given H3 index with k of 0.

H3.k_ring(617700169983721471, 0)
[617700169983721471]

Derive the k-ring for a given H3 index with k of 1.

H3.k_ring(617700169983721471, 1)
[
  617700169983721471, 617700170047946751, 617700169984245759,
  617700169982672895, 617700169983983615, 617700170044276735,
  617700170044014591
]

Parameters:

  • origin (Integer)

    Origin H3 index

  • k (Integer)

    K distance.

Returns:

  • (Array<Integer>)

    Array of H3 indexes within the k-range.



92
93
94
95
96
97
# File 'lib/h3/traversal.rb', line 92

def k_ring(origin, k)
  max_hexagons = max_kring_size(k)
  hexagons = FFI::MemoryPointer.new(:ulong_long, max_hexagons)
  Bindings::Private.k_ring(origin, k, hexagons)
  hexagons.read_array_of_ulong_long(max_hexagons).reject(&:zero?)
end

#k_ring_distances(origin, k) ⇒ Hash

Derives the k-ring for the given origin at k distance, sub-grouped by distance.

Examples:

Derive k-ring at distance 2

H3.k_ring_distances(617700169983721471, 2)
{
  0 => [617700169983721471],
  1 = >[
    617700170047946751, 617700169984245759, 617700169982672895,
    617700169983983615, 617700170044276735, 617700170044014591
  ],
  2 => [
    617700170048995327, 617700170047684607, 617700170048471039,
    617700169988177919, 617700169983197183, 617700169983459327,
    617700169982935039, 617700175096053759, 617700175097102335,
    617700170043752447, 617700170043490303, 617700170045063167
  ]
}

Parameters:

  • origin (Integer)

    Origin H3 index.

  • k (Integer)

    K distance.

Returns:

  • (Hash)

    Hash of k-ring distances grouped by distance.



257
258
259
260
261
262
263
264
265
266
267
268
269
# File 'lib/h3/traversal.rb', line 257

def k_ring_distances(origin, k)
  max_out_size = max_kring_size(k)
  out = FFI::MemoryPointer.new(H3_INDEX, max_out_size)
  distances = FFI::MemoryPointer.new(:int, max_out_size)
  Bindings::Private.k_ring_distances(origin, k, out, distances)

  hexagons = out.read_array_of_ulong_long(max_out_size)
  distances = distances.read_array_of_int(max_out_size)

  Hash[
    distances.zip(hexagons).group_by(&:first).map { |d, hs| [d, hs.map(&:last)] }
  ]
end

#max_hex_ring_size(k) ⇒ Integer

Derive the maximum hex ring size for a given distance k.

NOTE: This method is not part of the H3 API and is added to this binding for convenience.

Examples:

Derive maximum hex ring size for k distance 6.

H3.max_hex_ring_size(6)
36

Parameters:

  • k (Integer)

    K distance.

Returns:

  • (Integer)

    Maximum hex ring size.



136
137
138
# File 'lib/h3/traversal.rb', line 136

def max_hex_ring_size(k)
  k.zero? ? 1 : 6 * k
end

#max_kring_size(k) ⇒ Integer

Derive the maximum k-ring size for distance k.

Examples:

Derive the maximum k-ring size for k=5

H3.max_kring_size(5)
91

Parameters:

  • k (Integer)

    K value.

Returns:

  • (Integer)

    Maximum k-ring size.



19
# File 'lib/h3/traversal.rb', line 19

attach_function :max_kring_size, :maxKringSize, [ :int ], :int