defmodule Mobilizon.GraphQL.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