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

attach_predicate_function, extended

Instance Method Details

#distance(origin, h3_index) ⇒ Integer

Derive the distance between two H3 indexes.

Examples:

Derive the distance between two H3 indexes.

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 :distance, :h3Distance, %i[h3_index h3_index], :k_distance

#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.



82
83
84
85
86
87
88
# File 'lib/h3/traversal.rb', line 82

def hex_range(origin, k)
  max_hexagons = max_kring_size(k)
  out = H3Indexes.of_size(max_hexagons)
  pentagonal_distortion = Bindings::Private.hex_range(origin, k, out)
  raise(ArgumentError, "Specified hexagon range contains a pentagon") if pentagonal_distortion
  out.read
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.



233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/h3/traversal.rb', line 233

def hex_range_distances(origin, k)
  max_out_size = max_kring_size(k)
  out = H3Indexes.of_size(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
  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:



199
200
201
202
203
204
205
206
207
# File 'lib/h3/traversal.rb', line 199

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

    out[h3_index] = k_rings_for_hex_range(indexes, k)
  end
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.



136
137
138
139
140
141
142
# File 'lib/h3/traversal.rb', line 136

def hex_ring(origin, k)
  max_hexagons = max_hex_ring_size(k)
  out = H3Indexes.of_size(max_hexagons)
  pentagonal_distortion = Bindings::Private.hex_ring(origin, k, out)
  raise(ArgumentError, "The hex ring contains a pentagon") if pentagonal_distortion
  out.read
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.



111
112
113
114
115
116
# File 'lib/h3/traversal.rb', line 111

def k_ring(origin, k)
  max_hexagons = max_kring_size(k)
  out = H3Indexes.of_size(max_hexagons)
  Bindings::Private.k_ring(origin, k, out)
  out.read
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.



270
271
272
273
274
275
276
277
278
279
280
281
282
# File 'lib/h3/traversal.rb', line 270

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

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

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

#line(origin, destination) ⇒ Array<Integer>

Derives the H3 indexes found in a line between an origin H3 index and a destination H3 index (inclusive of origin and destination).

Examples:

Derive the indexes found in a line.

H3.line(617700169983721471, 617700169959866367)
[
  617700169983721471, 617700169984245759, 617700169988177919,
  617700169986867199, 617700169987391487, 617700169959866367
]

Parameters:

  • origin (Integer)

    Origin H3 index.

  • destination (Integer)

    Destination H3 index.

Returns:

  • (Array<Integer>)

    H3 indexes

Raises:

  • (ArgumentError)

    Could not compute line



300
301
302
303
304
305
306
# File 'lib/h3/traversal.rb', line 300

def line(origin, destination)
  max_hexagons = line_size(origin, destination)
  hexagons = H3Indexes.of_size(max_hexagons)
  res = Bindings::Private.h3_line(origin, destination, hexagons)
  raise(ArgumentError, "Could not compute line") if res.negative?
  hexagons.read
end

#line_size(origin, destination) ⇒ Integer

Derive the number of hexagons present in a line between two H3 indexes.

This value is simply ‘h3_distance(origin, destination) + 1` when a line is computable.

Returns a negative number if a line cannot be computed e.g. a pentagon was encountered, or the hexagons are too far apart.

Examples:

Derive the number of hexagons present in a line between two H3 indexes.

H3.line_size(617700169983721471, 617700169959866367)
6

Parameters:

  • origin (Integer)

    Origin H3 index

  • destination (Integer)

    H3 index

Returns:

  • (Integer)

    Number of hexagons found between indexes.



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

attach_function :line_size, :h3LineSize, %i[h3_index h3_index], :int

#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.



155
156
157
# File 'lib/h3/traversal.rb', line 155

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, %i[k_distance], :int