Packages
geo
1.4.0
4.1.0
4.0.1
4.0.0
3.6.0
3.5.1
3.5.0
3.4.3
3.4.2
3.4.1
3.4.0
3.3.8
3.3.7
3.3.5
3.3.4
3.3.3
3.3.2
3.3.1
3.3.0
3.2.0
3.1.0
3.0.0
2.1.0
2.0.0
1.5.0
1.4.1
1.4.0
1.3.1
1.3.0
1.2.1
1.2.0
1.1.2
1.1.1
1.1.0
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.18.0
0.17.0
0.16.1
0.16.0
0.15.2
0.15.1
0.15.0
0.14.0
0.13.0
0.12.0
0.11.2
0.11.1
0.11.0
0.10.1
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.0
0.7.2
0.7.1
0.6.1
0.5.1
Encodes and decodes WKB, WKT, and GeoJSON formats.
Current section
Files
Jump to
Current section
Files
lib/geo/utils.ex
defmodule Geo.Utils do
@moduledoc false
use Bitwise
@doc """
Turns a hex string or an integer of base 16 into its floating point
representation.
Takes an optional endian atom. Either :xdr for big endian or :ndr for little
endian. Defaults to :xdr
`
Geo.Utils.hex_to_float("40000000")
2.0
Geo.Utils.hex_to_float(0x40000000)
2.0
Geo.Utils.hex_to_float("3ff0000000000000")
1.0
Geo.Utils.hex_to_float(0x3ff0000000000000)
1.0
`
"""
def hex_to_float(hex) when is_integer(hex) or is_binary(hex) do
hex = if is_integer(hex), do: Integer.to_string(hex, 16), else: hex
case bit_size(hex) do
64 ->
<< value :: float-32 >> = << String.to_integer(hex, 16) :: integer-32 >>
value
128 ->
<< value :: float-64 >> = << String.to_integer(hex, 16) :: integer-64 >>
value
_ ->
raise( ArgumentError, message: "hex must be either 4 or 8 bytes long")
end
end
@doc """
Turns a float into a hex value. The size can either be 32 or 64.
"""
def float_to_hex(float, size) do
case size do
32 ->
<< value :: integer-32 >> = << float :: float-32 >>
value
64 ->
<< value :: integer-64 >> = << float :: float-64 >>
value
end
end
@doc """
Reverses the byte order of the given hex string.
```
Geo.Utils.reverse_byte_order("00000004")
"40000000"
Geo.Utils.reverse_byte_order("E6100000")
"000010E6"
```
"""
def reverse_byte_order("") do
""
end
def reverse_byte_order(hex) do
byte_range = Enum.to_list(0..(div( byte_size(hex) , 2) -1))
Enum.map(byte_range, fn(x) -> :binary.part(hex, x * 2, 2) end)
|> Enum.reverse
|> Enum.join
end
@doc """
Adds 0's to the right of hex string
"""
def pad_right(hex, size) do
if byte_size(hex) == size do
hex
else
hex <> repeat("0", size - byte_size(hex))
end
end
@doc """
Adds 0's to the left of hex string
"""
def pad_left(hex, size) do
if byte_size(hex) == size do
hex
else
repeat("0", size - byte_size(hex)) <> hex
end
end
@doc """
Repeats the char count number of times
"""
def repeat(char, count) do
Enum.map(1..count, fn(_x) -> char end) |> Enum.join
end
def endian_to_binary(:xdr) do
<<48,48>>
end
def endian_to_binary(:ndr) do
<<48,49>>
end
def binary_to_endian(<<48,49>>) do
:ndr
end
def binary_to_endian(<<48,48>>) do
:xdr
end
def hex_to_type(0x01) do
%Geo.Point{}
end
def hex_to_type(0x40_00_00_01) do
%Geo.PointM{}
end
def hex_to_type(0x80_00_00_01) do
%Geo.PointZ{}
end
def hex_to_type(0xC0_00_00_01) do
%Geo.PointZM{}
end
def hex_to_type(0x02) do
%Geo.LineString{}
end
def hex_to_type(0x03) do
%Geo.Polygon{}
end
def hex_to_type(0x04) do
%Geo.MultiPoint{}
end
def hex_to_type(0x05) do
%Geo.MultiLineString{}
end
def hex_to_type(0x06) do
%Geo.MultiPolygon{}
end
def hex_to_type(0x07) do
%Geo.GeometryCollection{}
end
def type_to_hex(geom, include_srid) do
value = if include_srid, do: 0x20000000, else: 0x00000000
value + do_type_to_hex(geom)
end
def do_type_to_hex(%Geo.Point{}) do
0x01
end
def do_type_to_hex(%Geo.PointM{}) do
0x40_00_00_01
end
def do_type_to_hex(%Geo.PointZ{}) do
0x80_00_00_01
end
def do_type_to_hex(%Geo.PointZM{}) do
0xC0_00_00_01
end
def do_type_to_hex(%Geo.LineString{}) do
0x02
end
def do_type_to_hex(%Geo.Polygon{}) do
0x03
end
def do_type_to_hex(%Geo.MultiPoint{}) do
0x04
end
def do_type_to_hex(%Geo.MultiLineString{}) do
0x05
end
def do_type_to_hex(%Geo.MultiPolygon{}) do
0x06
end
def do_type_to_hex(%Geo.GeometryCollection{}) do
0x07
end
end