39 lines
1.2 KiB
Elixir
39 lines
1.2 KiB
Elixir
|
defmodule MobilizonWeb.Schema.Custom.Point do
|
||
|
@moduledoc """
|
||
|
The geom scalar type allows Geo.PostGIS.Geometry strings to be passed in and out.
|
||
|
Requires `{:geo, "~> 3.0"},` package: https://github.com/elixir-ecto/ecto
|
||
|
"""
|
||
|
use Absinthe.Schema.Notation
|
||
|
|
||
|
scalar :point, name: "Point" do
|
||
|
description("""
|
||
|
The `Point` scalar type represents Point geographic information compliant string data,
|
||
|
represented as floats separated by a semi-colon. The geodetic system is WGS 84
|
||
|
""")
|
||
|
|
||
|
serialize(&encode/1)
|
||
|
parse(&decode/1)
|
||
|
end
|
||
|
|
||
|
@spec decode(Absinthe.Blueprint.Input.String.t()) :: {:ok, term()} | :error
|
||
|
@spec decode(Absinthe.Blueprint.Input.Null.t()) :: {:ok, nil}
|
||
|
defp decode(%Absinthe.Blueprint.Input.String{value: value}) do
|
||
|
with [_, _] = lonlat <- String.split(value, ";", trim: true),
|
||
|
[{lon, ""}, {lat, ""}] <- Enum.map(lonlat, &Float.parse(&1)) do
|
||
|
{:ok, %Geo.Point{coordinates: {lon, lat}, srid: 4326}}
|
||
|
else
|
||
|
_ -> :error
|
||
|
end
|
||
|
end
|
||
|
|
||
|
defp decode(%Absinthe.Blueprint.Input.Null{}) do
|
||
|
{:ok, nil}
|
||
|
end
|
||
|
|
||
|
defp decode(_) do
|
||
|
:error
|
||
|
end
|
||
|
|
||
|
defp encode(%Geo.Point{coordinates: {lon, lat}, srid: 4326}), do: "#{lon};#{lat}"
|
||
|
end
|