defmodule GeoMeasure.Utils do @moduledoc """ Contains utility functions to aid the correct handling of data in GeoMeasure. """ @doc """ Checks if neither of the tuple elements is nil. """ @doc since: "0.0.1" @spec tuple_not_nil!(tuple) :: ArgumentError def tuple_not_nil!(tpl) when is_tuple(tpl) do tpl |> Tuple.to_list() |> Enum.map(fn x -> if is_nil(x) do raise ArgumentError, message: "Tuple contains nil value: {#{inspect(tpl)}}" end end) end @spec remove_m_values([{number, number, number} | {number, number, number, number}]) :: [ {number, number} | {number, number, number} ] def remove_m_values(coords) when is_list(coords) do Enum.map(coords, fn {a, b, _c} -> {a, b} {a, b, c, _d} -> {a, b, c} _ -> raise ArgumentError, message: "Wrong tuple size: {#{inspect(coords)}}" end) end @spec remove_z_values([{number, number, number} | {number, number, number, number}]) :: [ {number, number} | {number, number, number} ] def remove_z_values(coords) when is_list(coords) do Enum.map(coords, fn {a, b, _c} -> {a, b} {a, b, _c, d} -> {a, b, d} _ -> raise ArgumentError, message: "Wrong tuple size: {#{inspect(coords)}}" end) end @spec linestringz_to_linestring(Geo.LineStringZ.t()) :: Geo.LineString.t() def linestringz_to_linestring(%Geo.LineStringZ{coordinates: coords}) do %Geo.LineString{coordinates: remove_z_values(coords)} end @spec linestringzm_to_linestring(Geo.LineStringZM.t()) :: Geo.LineString.t() def linestringzm_to_linestring(%Geo.LineStringZM{coordinates: coords}) do linestring_coords = remove_m_values(coords) |> remove_z_values() %Geo.LineString{coordinates: linestring_coords} end @spec polygonz_to_polygon(Geo.PolygonZ.t()) :: Geo.Polygon.t() def polygonz_to_polygon(%Geo.PolygonZ{coordinates: coords}) do polygon_coords = Enum.map(coords, &remove_z_values/1) %Geo.Polygon{coordinates: polygon_coords} end end