Coordinate Reference System utilities.
Meridian defaults to WGS-84 (EPSG:4326). This module provides helpers for distance calculations that respect the graph's declared CRS, and stubs for reprojection.
Summary
Functions
Returns the bounding box of a graph as {min_lon, min_lat, max_lon, max_lat}.
Computes edge weights for all edges as the geographic distance between their endpoint nodes.
Returns the great-circle distance between two nodes in meters.
Reprojects all node geometries to a new CRS.
Returns true if both graphs declare the same CRS.
Functions
@spec bbox(Meridian.Graph.t()) :: {float(), float(), float(), float()} | nil
Returns the bounding box of a graph as {min_lon, min_lat, max_lon, max_lat}.
Returns nil if the graph has no geometries.
@spec compute_edge_weights( Meridian.Graph.t(), keyword() ) :: Meridian.Graph.t()
Computes edge weights for all edges as the geographic distance between their endpoint nodes.
Returns a new Meridian.Graph where every edge weight has been replaced
by the computed distance in meters. Edges whose endpoints lack point
geometries are left unchanged.
Options
:round— round to N decimal places (default: no rounding)
Examples
iex> g = Meridian.Graph.new()
iex> g = g
...> |> Meridian.Graph.add_node(:a, %{geometry: %Geo.Point{coordinates: {0.0, 0.0}}})
...> |> Meridian.Graph.add_node(:b, %{geometry: %Geo.Point{coordinates: {0.0, 1.0}}})
...> |> Meridian.Graph.add_edge_ensure(:a, :b, nil)
iex> g = Meridian.CRS.compute_edge_weights(g)
iex> [{:a, :b, weight}] = Meridian.Graph.edges(g)
iex> weight > 110_000 and weight < 112_000
true
@spec distance(Meridian.Graph.t(), Yog.node_id(), Yog.node_id()) :: float() | nil
Returns the great-circle distance between two nodes in meters.
Requires that both nodes have %Geo.Point{} geometries in their data.
Currently assumes the graph is in WGS-84.
Returns nil if either node lacks a point geometry.
Examples
iex> g = Meridian.Graph.new()
iex> g = g
...> |> Meridian.Graph.add_node(:a, %{geometry: %Geo.Point{coordinates: {-73.9857, 40.7484}}})
...> |> Meridian.Graph.add_node(:b, %{geometry: %Geo.Point{coordinates: {-73.9851, 40.7489}}})
iex> dist = Meridian.CRS.distance(g, :a, :b)
iex> is_float(dist) and dist > 0
true
iex> g = Meridian.Graph.new() |> Meridian.Graph.add_node(:a, %{foo: 1})
iex> Meridian.CRS.distance(g, :a, :b)
nil
@spec reproject(Meridian.Graph.t(), String.t()) :: Meridian.Graph.t()
Reprojects all node geometries to a new CRS.
Note: Currently a stub. Real reprojection requires a PROJ binding. The CRS field is updated but coordinates are not transformed.
@spec same_crs?(Meridian.Graph.t(), Meridian.Graph.t()) :: boolean()
Returns true if both graphs declare the same CRS.