Packages
geo
0.13.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/geo_json.ex
defmodule Geo.JSON do
alias Geo.Point
alias Geo.LineString
alias Geo.Polygon
alias Geo.MultiPoint
alias Geo.MultiLineString
alias Geo.MultiPolygon
alias Geo.GeometryCollection
@moduledoc """
Converts to and from GeoJSON
```
json = "{ \"type\": \"Point\", \"coordinates\": [100.0, 0.0] }"
geom = Geo.JSON.decode(json)
Geo.Point[coordinates: {100.0, 0.0}, srid: nil]
Geo.JSON.encode(geom)
"{ \"type\": \"Point\", \"coordinates\": [100.0, 0.0] }"
```
"""
@doc """
Takes a GeoJSON string and returns a Geometry
"""
@spec decode(binary) :: Geo.geometry
def decode(geo_json) do
decoded_json = json_decode(geo_json)
case Map.has_key?(decoded_json, :geometries) do
true ->
geometries = Enum.map(decoded_json.geometries,
fn(x) -> do_decode(x.type, x.coordinates) end)
%GeometryCollection{ geometries: geometries }
false ->
do_decode(decoded_json.type, decoded_json.coordinates)
end
end
defp do_decode("Point", [x, y]) do
%Point{ coordinates: {x, y}}
end
defp do_decode("LineString", coordinates) do
coordinates = Enum.map(coordinates, &List.to_tuple(&1))
%LineString{ coordinates: coordinates }
end
defp do_decode("Polygon", coordinates) do
coordinates = Enum.map(coordinates, fn(sub_coordinates) ->
Enum.map(sub_coordinates, &List.to_tuple(&1))
end)
%Polygon{ coordinates: coordinates }
end
defp do_decode("MultiPoint", coordinates) do
coordinates = Enum.map(coordinates, &List.to_tuple(&1))
%MultiPoint{ coordinates: coordinates }
end
defp do_decode("MultiLineString", coordinates) do
coordinates = Enum.map(coordinates, fn(sub_coordinates) ->
Enum.map(sub_coordinates, &List.to_tuple(&1))
end)
%MultiLineString{ coordinates: coordinates }
end
defp do_decode("MultiPolygon", coordinates) do
coordinates = Enum.map(coordinates, fn(sub_coordinates) ->
Enum.map(sub_coordinates, fn(third_sub_coordinates) ->
Enum.map(third_sub_coordinates, &List.to_tuple(&1))
end)
end)
%MultiPolygon{ coordinates: coordinates }
end
@doc """
Takes a Geometry and returns a geoJSON string
"""
@spec encode(Geo.geometry) :: binary
def encode(%GeometryCollection{ geometries: geometries, srid: srid }) do
%{ type: "GeometryCollection", geometries: Enum.map(geometries, &do_encode(&1))}
|> add_crs(srid)
|> json_encode
end
def encode(geom) do
do_encode(geom)
|> add_crs(geom.srid)
|> json_encode
end
defp do_encode(%Point{ coordinates: {x, y} }) do
%{ type: "Point", coordinates: [x, y] }
end
defp do_encode(%LineString{ coordinates: coordinates }) do
coordinates = Enum.map(coordinates, &Tuple.to_list(&1))
%{ type: "LineString", coordinates: coordinates }
end
defp do_encode(%Polygon{ coordinates: coordinates }) do
coordinates = Enum.map(coordinates, fn(sub_coordinates) ->
Enum.map(sub_coordinates, &Tuple.to_list(&1))
end)
%{ type: "Polygon", coordinates: coordinates }
end
defp do_encode(%MultiPoint{ coordinates: coordinates }) do
coordinates = Enum.map(coordinates, &Tuple.to_list(&1))
%{ type: "MultiPoint", coordinates: coordinates }
end
defp do_encode(%MultiLineString{ coordinates: coordinates }) do
coordinates = Enum.map(coordinates, fn(sub_coordinates) ->
Enum.map(sub_coordinates, &Tuple.to_list(&1))
end)
%{ type: "MultiLineString", coordinates: coordinates }
end
defp do_encode(%MultiPolygon{ coordinates: coordinates }) do
coordinates = Enum.map(coordinates, fn(sub_coordinates) ->
Enum.map(sub_coordinates, fn(third_sub_coordinates) ->
Enum.map(third_sub_coordinates, &Tuple.to_list(&1))
end)
end)
%{ type: "MultiPolygon", coordinates: coordinates }
end
defp add_crs(map, nil) do
map
end
defp add_crs(map, srid) do
Map.put(map, :crs, %{type: "name", properties: %{name: "EPSG#{srid}"}})
end
defp json_encode(data) do
Poison.encode!(data)
end
defp json_decode(json) do
Poison.decode!(json, keys: :atoms)
end
end