Skip to content

Improve distance calculation #46

@esgn

Description

@esgn

Improve GeoJSON distance computation on WGS84

Context

src/helpers/distance.js currently computes geometry distance in two steps:

  1. JSTS DistanceOp.nearestPoints(a, b) selects the nearest points between two GeoJSON geometries.
  2. Turf distance measures the haversine distance between those two points and returns meters.

This is useful and fast, but still approximate: JSTS selects nearest points in planar lon/lat coordinates, not with a geodesic distance on WGS84. Only the final point-to-point measurement is spherical.

Problem

There does not seem to be an off-the-shelf JavaScript library that computes the minimum distance between two arbitrary GeoJSON geometries using WGS84 ellipsoidal distance.

Existing tools cover only parts of the problem:

  • JSTS handles geometry topology and nearest points, but treats lon/lat as planar coordinates.
  • Turf distance provides spherical point-to-point distance, not ellipsoidal geometry-to-geometry distance.
  • Turf pointToLineDistance handles point-to-line distance, but is not a full arbitrary geometry-to-geometry engine.
  • GeographicLib for JavaScript provides accurate WGS84 geodesic primitives, but no full GeoJSON geometry distance engine.
  • geographiclib-geodesic on npm exposes GeographicLib geodesic calculations for JavaScript.

This can affect distance-based ordering, for example when sorting nearby parcels or WFS features.

Goal

Keep the current public API: distance(gA, gB) -> number, returning meters.

Expected behavior:

  • input GeoJSON is lon/lat WGS84, [longitude, latitude];
  • return distance in meters;
  • return 0 when geometries intersect, touch, overlap, or contain each other;
  • support Point, MultiPoint, LineString, MultiLineString, Polygon, MultiPolygon, and GeometryCollection;
  • ignore Z/M coordinates;
  • fail explicitly on invalid or unsupported geometries.

Possible solutions

1. Keep current implementation and document the approximation

Use JSTS for nearest points and Turf distance for final haversine distance.

Pros: simple, fast, already works.

Cons: nearest-point selection is still planar in lon/lat, so ordering can be wrong in edge cases.

2. Use a local metric projection per distance computation

Project both geometries to a local metric plane centered on the query point or on the combined geometry bbox, then use JSTS planar distance in meters.

Possible projections:

  • local equirectangular projection;
  • local Transverse Mercator;
  • local Azimuthal Equidistant.

Pros: much better than raw lon/lat degrees, fast, keeps JSTS for geometry distance, generic enough for small local WFS searches.

Cons: still approximate, accuracy decreases with larger distances/geometries, needs careful choice of projection center, antimeridian/polar cases should be documented or handled separately.

3. Build a lightweight geodesic GeoJSON distance engine

Use JSTS only for the initial topological 0 check, then compute candidates ourselves with GeographicLib / geographiclib-geodesic:

  • point-point: WGS84 inverse distance;
  • point-segment: minimize distance along the geodesic segment;
  • segment-segment: detect crossing, otherwise compare endpoint-to-segment distances;
  • split long segments if needed for numeric stability.

Pros: more correct and generic.

Cons: more complex, needs careful tests and benchmarks.

Tests to add

  • point / point;
  • point / line;
  • line / point;
  • point inside polygon returns 0;
  • intersecting lines return 0;
  • multipoints, multilines, multipolygons, geometry collections;
  • degenerate geometries with duplicate coordinates;
  • regression case where nearest in lon/lat degrees differs from nearest in meters;
  • integration tests ensuring urbanisme, SUP, and parcel distances are returned in meters.

Acceptance criteria

  • distance(gA, gB) still returns meters.
  • Existing callers do not need API changes.
  • Intersections and containment return 0.
  • Unit tests lock the output unit.
  • Known parcel-ordering edge cases are covered.
  • Performance remains acceptable on realistic WFS geometries.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions