Current section

Files

Jump to
geo lib geo wkt encoder.ex
Raw

lib/geo/wkt/encoder.ex

defmodule Geo.WKT.Encoder do
@moduledoc false
alias Geo.{
Point,
PointZ,
PointM,
PointZM,
LineString,
LineStringZ,
Polygon,
PolygonZ,
MultiPoint,
MultiPointZ,
MultiLineString,
MultiLineStringZ,
MultiPolygon,
MultiPolygonZ,
GeometryCollection
}
@doc """
Takes a Geometry and returns a WKT string
"""
@spec encode(Geo.geometry()) :: {:ok, binary} | {:error, Exception.t()}
def encode(geom) do
{:ok, encode!(geom)}
rescue
exception ->
{:error, exception}
end
@doc """
Takes a Geometry and returns a WKT string
"""
@spec encode!(Geo.geometry()) :: binary
def encode!(geom) do
get_srid_binary(geom.srid) <> do_encode(geom)
end
defp do_encode(%Point{coordinates: {x, y}}) do
"POINT(#{x} #{y})"
end
defp do_encode(%PointZ{coordinates: {x, y, z}}) do
"POINT Z(#{x} #{y} #{z})"
end
defp do_encode(%PointM{coordinates: {x, y, m}}) do
"POINT M(#{x} #{y} #{m})"
end
defp do_encode(%PointZM{coordinates: {x, y, z, m}}) do
"POINT ZM(#{x} #{y} #{z} #{m})"
end
defp do_encode(%LineString{coordinates: coordinates}) do
coordinate_string = create_line_string_str(coordinates)
"LINESTRING#{coordinate_string}"
end
defp do_encode(%LineStringZ{coordinates: coordinates}) do
coordinate_string = create_line_string_str(coordinates)
"LINESTRINGZ#{coordinate_string}"
end
defp do_encode(%Polygon{coordinates: coordinates}) do
coordinate_string = create_polygon_str(coordinates)
"POLYGON#{coordinate_string}"
end
defp do_encode(%PolygonZ{coordinates: coordinates}) do
coordinate_string = create_polygon_str(coordinates)
"POLYGON#{coordinate_string}"
end
defp do_encode(%MultiPoint{coordinates: coordinates}) do
coordinate_string = create_line_string_str(coordinates)
"MULTIPOINT#{coordinate_string}"
end
defp do_encode(%MultiPointZ{coordinates: coordinates}) do
coordinate_string = create_line_string_str(coordinates)
"MULTIPOINTZ#{coordinate_string}"
end
defp do_encode(%MultiLineString{coordinates: coordinates}) do
coordinate_string = create_polygon_str(coordinates)
"MULTILINESTRING#{coordinate_string}"
end
defp do_encode(%MultiLineStringZ{coordinates: coordinates}) do
coordinate_string = create_polygon_str(coordinates)
"MULTILINESTRINGZ#{coordinate_string}"
end
defp do_encode(%MultiPolygon{coordinates: coordinates}) do
coordinate_string = create_multi_polygon_str(coordinates)
"MULTIPOLYGON#{coordinate_string}"
end
defp do_encode(%MultiPolygonZ{coordinates: coordinates}) do
coordinate_string = create_multi_polygon_str(coordinates)
"MULTIPOLYGONZ#{coordinate_string}"
end
defp do_encode(%GeometryCollection{geometries: geometries}) do
geom_str = Enum.map(geometries, &do_encode(&1)) |> Enum.join(",")
"GEOMETRYCOLLECTION(#{geom_str})"
end
defp create_line_string_str(coordinates) do
coordinate_str =
coordinates
|> Enum.map(&create_coord_str(&1))
|> Enum.join(",")
"(#{coordinate_str})"
end
defp create_polygon_str(coordinates) do
coordinate_str =
coordinates
|> Enum.map(&create_line_string_str(&1))
|> Enum.join(",")
"(#{coordinate_str})"
end
defp create_multi_polygon_str(coordinates) do
coordinate_str =
coordinates
|> Enum.map(&create_polygon_str(&1))
|> Enum.join(",")
"(#{coordinate_str})"
end
defp create_coord_str({x, y}), do: "#{x} #{y}"
defp create_coord_str({x, y, z}), do: "#{x} #{y} #{z}"
defp get_srid_binary(nil), do: ""
defp get_srid_binary(0), do: ""
defp get_srid_binary(srid), do: "SRID=#{srid};"
end