Meridian.CRS (Meridian v0.1.0)

Copy Markdown View Source

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

bbox(graph)

@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.

compute_edge_weights(mg, opts \\ [])

@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

distance(graph, from_id, to_id)

@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

reproject(g, to_crs)

@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.

same_crs?(arg1, arg2)

@spec same_crs?(Meridian.Graph.t(), Meridian.Graph.t()) :: boolean()

Returns true if both graphs declare the same CRS.