spat v0.2.0 Spat
Functions for dealing with indexes.
Link to this section Summary
Functions
Get the index adjacent to the another index given a certain offset
Decode an encoded packed grid index
Encode a packed grid index
Pack a grid index into a bitstring
Get the bounds a grid index references
Unpack a grid index from a bitstring
Link to this section Types
Link to this section Functions
adjacent(grid_index(), pos_integer(), pos_integer(), Spat.Coord.t(), [ {:addressing, address_modes()} ]) :: grid_index()
adjacent( packed_grid_index(), pos_integer(), pos_integer(), Spat.Coord.t(), packing_options() | unpacking_options() | [{:addressing, address_modes()}] ) :: packed_grid_index()
Get the index adjacent to the another index given a certain offset.
Addressing modes can be provided ([addressing: mode]
) to specify the behaviour when referencing an index that is beyond the maximum bounds. The possible addressing modes are:
:clamp
- Will clamp the bounds from min to max. (default):wrap
- Will start from the opposing side.
iex> bounds = Spat.Bounds.new({ 10, 10 })
...> point = {2.6,0}
...> subdivisions = 2
...> [index] = Spat.Geometry.Point.index(point, bounds, subdivisions)
...> Spat.to_bounds(Spat.adjacent(index, Spat.Coord.dimension(point), subdivisions, { 1, 2 }), bounds)
Spat.Bounds.new([5.0, 5.0], [7.5, 7.5])
iex> Spat.adjacent([0, 0], 2, 2, { 4, 0 }, addressing: :clamp)
[1, 1]
iex> Spat.adjacent([0, 0], 2, 2, { 5, 0 }, addressing: :clamp)
[1, 1]
iex> Spat.adjacent([0, 0], 2, 2, { 4, 0 }, addressing: :wrap)
[0, 0]
iex> Spat.adjacent([0, 0], 2, 2, { 5, 0 }, addressing: :wrap)
[0, 1]
iex> Spat.adjacent([0, 0], 2, 2, { -1, 0 }, addressing: :clamp)
[0, 0]
iex> Spat.adjacent([0, 0], 2, 2, { -1, 0 }, addressing: :wrap)
[1, 1]
iex> Spat.adjacent(Spat.pack([0, 0], 2), 2, 2, { 5, 0 }, addressing: :clamp)
Spat.pack([1, 1], 2)
iex> Spat.adjacent(Spat.pack([0, 0], 2), 2, 2, { 5, 0 }, addressing: :wrap)
Spat.pack([0, 1], 2)
iex> Spat.adjacent(Spat.pack([0, 0], 2), 2, 2, { -1, 0 }, addressing: :wrap)
Spat.pack([1, 1], 2)
iex> Spat.adjacent(Spat.pack([0, 1], 2), 2, 2, { 0, 0 })
Spat.pack([0, 1], 2)
iex> Spat.adjacent(Spat.pack([0, 1], 2, reverse: true), 2, 2, { 0, 0 }, reverse: true)
Spat.pack([0, 1], 2, reverse: true)
decode(encoded_index(), pos_integer(), pos_integer()) :: packed_grid_index()
Decode an encoded packed grid index.
iex> Spat.decode("A", 2, 1)
<<0 :: 2>>
iex> Spat.decode("A", 3, 1)
<<0 :: 3>>
iex> Spat.decode("AA", 2, 4)
<<0 :: 8>>
iex> Spat.decode("BCD", 6, 3)
<<1 :: 6, 2 :: 6, 3 :: 6>>
Encode a packed grid index.
The encoding is a URL safe string. While the encoding is equivalent to the Base
module's URL-safe base64 encoding (without padding), care should be taken if using those functions to encode/decode packed grid indexes. As packed grid indexes are bitstrings and not binaries, using the Base
module variants (or other third party base64 functions) may result in losing information.
If you do have a workflow that requires it to be compatible with base64 implementations, then it is recommended you pad the packed grid index so it's now a binary.
iex> Spat.encode(<<0 :: 2>>)
"A"
iex> Spat.encode(<<0 :: 3>>)
"A"
iex> Spat.encode(<<0 :: 8>>)
"AA"
iex> Spat.encode(<<1 :: 6, 2 :: 6, 3 :: 6>>)
"BCD"
pack(grid_index(), pos_integer(), packing_options()) :: packed_grid_index()
Pack a grid index into a bitstring.
iex> Spat.pack([0], 2)
<<0 :: 2>>
iex> Spat.pack([0], 3)
<<0 :: 3>>
iex> Spat.pack([], 2)
<<>>
iex> Spat.pack([0, 0, 0, 0], 2)
<<0 :: 8>>
iex> Spat.pack([1, 2, 3, 4], 2)
<<1 :: 2, 2 :: 2, 3 :: 2, 0 :: 2>>
iex> Spat.pack([1, 2, 3, 4], 2, reverse: true)
<<0 :: 2, 3 :: 2, 2 :: 2, 1 :: 2>>
iex> Spat.pack([1, 2, 3, 4], 3, reverse: true)
<<4 :: 3, 3 :: 3, 2 :: 3, 1 :: 3>>
iex> Spat.pack([1, 2, 3, 4000], 12, reverse: true)
<<4000 :: 12, 3 :: 12, 2 :: 12, 1 :: 12>>
to_bounds( grid_index() | packed_grid_index(), Spat.Bounds.t(), unpacking_options() ) :: Spat.Bounds.t()
Get the bounds a grid index references.
iex> bounds = Spat.Bounds.new({ 10, 10 })
...> point = {2.6,0}
...> subdivisions = 2
...> indexes = Spat.Geometry.Point.index(point, bounds, subdivisions)
...> Enum.map(indexes, &Spat.to_bounds(&1, bounds))
[Spat.Bounds.new([2.5, 0], [5.0, 2.5])]
iex> Spat.to_bounds([0], Spat.Bounds.new({ 10, 10 }))
Spat.Bounds.new([0, 0], [5.0, 5.0])
iex> Spat.to_bounds([1], Spat.Bounds.new({ 10, 10 }))
Spat.Bounds.new([5.0, 0], [10.0, 5.0])
iex> Spat.to_bounds([2], Spat.Bounds.new({ 10, 10 }))
Spat.Bounds.new([0, 5.0], [5.0, 10.0])
iex> Spat.to_bounds([3], Spat.Bounds.new({ 10, 10 }))
Spat.Bounds.new([5.0, 5.0], [10.0, 10.0])
iex> Spat.to_bounds([0, 0, 0], Spat.Bounds.new({ 10, 10 }))
Spat.Bounds.new([0, 0], [1.25, 1.25])
iex> Spat.to_bounds(Spat.pack([3], 2), Spat.Bounds.new({ 10, 10 }))
Spat.Bounds.new([5.0, 5.0], [10.0, 10.0])
iex> Spat.to_bounds(Spat.pack([0, 0, 0], 2), Spat.Bounds.new({ 10, 10 }))
Spat.Bounds.new([0, 0], [1.25, 1.25])
iex> Spat.to_bounds(Spat.pack([0, 0, 1], 2), Spat.Bounds.new({ 10, 10 }))
Spat.Bounds.new([1.25, 0], [2.5, 1.25])
iex> Spat.to_bounds(Spat.pack([0, 0, 1], 2, reverse: true), Spat.Bounds.new({ 10, 10 }), reverse: true)
Spat.Bounds.new([1.25, 0], [2.5, 1.25])
unpack(packed_grid_index(), pos_integer(), unpacking_options()) :: grid_index()
Unpack a grid index from a bitstring.
iex> Spat.unpack(<<0 :: 2>>, 2)
[0]
iex> Spat.unpack(<<0 :: 3>>, 3)
[0]
iex> Spat.unpack(<<>>, 2)
[]
iex> Spat.unpack(<<0 :: 8>>, 2)
[0, 0, 0, 0]
iex> Spat.unpack(<<1 :: 2, 2 :: 2, 3 :: 2, 0 :: 2>>, 2)
[1, 2, 3, 0]
iex> Spat.unpack(<<0 :: 2, 3 :: 2, 2 :: 2, 1 :: 2>>, 2, reverse: true)
[1, 2, 3, 0]
iex> Spat.unpack(<<4000 :: 12, 3 :: 12, 2 :: 12, 1 :: 12>>, 12, reverse: true)
[1, 2, 3, 4000]