Skip to content

Improve distance computation and add distance tool - #183

Merged
esgn merged 11 commits into
mainfrom
138/distance-tool
Oct 2, 2026
Merged

esgn merged 11 commits into
mainfrom
138/distance-tool

Conversation

@LionelZoubritzky-IGN

@LionelZoubritzky-IGN LionelZoubritzky-IGN commented Jul 28, 2026 •

Copy link
Copy Markdown
Contributor

Description

Adds a distance tool that returns the distance in meters between two lon/lat points. Also rewrites the geometry-to-geometry distance helper behind urbanisme, assiette_sup, parcellaire-express and the WFS distance_to_filter_center.

Related issues (if applicable)

Closes #138, supersedes #156

Motivation

The old helper picked the nearest pair of points in a plain lon/lat plane, then measured the haversine distance between them. Away from the equator a degree of longitude is shorter than a degree of latitude, so it could pick the wrong pair, and the distance was only approximate.

Implementation

  • src/helpers/distance.ts works in three steps:

    1. Settle the zero-distance cases (touch, overlap, containment). This is skipped when the bounding boxes are apart.
    2. Find a starting pair with a planar search in an equirectangular projection, centered on the middle latitude of the two geometries' bounding boxes.
    3. Refine that pair in an azimuthal equidistant projection centered on the current best pair, until a pass gains less than 5 mm.

    Facets are indexed in a tree, so the cost grows roughly linearly with the number of vertices. The helper now returns { distance, point1, point2 }, and callers are updated. Geometries that cross the antimeridian are rejected (RFC 7946 says to split them).

  • There are two point metrics: spherical (haversine, the default) and ellipsoidal (WGS84 geodesic, through geographiclib-geodesic).

  • DistanceTool exposes both metrics as profile and rounds the result to the centimeter.

  • Timed tests move to *.perf.test.ts and run one file at a time with npm run test:perf, which verify:fast now chains.

Checklist

  • The PR is focused and of a reasonable size.
  • The commit history is clean.
  • Relevant documentation has been updated.
  • Relevant tests have been added or updated.

@LionelZoubritzky-IGN LionelZoubritzky-IGN changed the title 138/distance tool Improve distance computation and add distance tool Jul 28, 2026
@LionelZoubritzky-IGN
LionelZoubritzky-IGN force-pushed the 138/distance-tool branch 2 times, most recently from a0ce3c6 to 95059e1 Compare July 29, 2026 16:50
@LionelZoubritzky-IGN

This comment was marked as outdated.

@LionelZoubritzky-IGN
LionelZoubritzky-IGN force-pushed the 138/distance-tool branch 2 times, most recently from 5fc4332 to 9e064c5 Compare August 3, 2026 11:29
@LionelZoubritzky-IGN LionelZoubritzky-IGN linked an issue Aug 3, 2026 that may be closed by this pull request
@LionelZoubritzky-IGN
LionelZoubritzky-IGN changed the base branch from main to 142-gpfschemastore0.2.0 August 17, 2026 13:50
@LionelZoubritzky-IGN
LionelZoubritzky-IGN force-pushed the 138/distance-tool branch 4 times, most recently from 11b7333 to e9d9b0b Compare August 19, 2026 14:48
@LionelZoubritzky-IGN
LionelZoubritzky-IGN marked this pull request as ready for review August 19, 2026 15:28
@mborne mborne added this to the v0.12.x - New Geospatial Tools milestone Sep 7, 2026
Base automatically changed from 142-gpfschemastore0.2.0 to main September 21, 2026 12:19
@esgn
esgn force-pushed the 138/distance-tool branch from 98d8ff4 to c12fc3d Compare October 1, 2026 14:57
@esgn esgn mentioned this pull request Oct 2, 2026
4 tasks done
Comment thread test/helpers/distance.test.ts Outdated
esgn added 3 commits October 2, 2026 11:32
node-vincenty (0.0.6, unmaintained, untyped) returns an undefined distance for antipodal or nearly antipodal points, which the wrapper let through. Karney's algorithm always converges; over 40,000 random pairs it differs from Vincenty by at most 0.56 mm. The hand-written node-vincenty types and their tsconfig.test.json entry go away.
The distance tool profiles `direct` and `vincenty` become `spherical` (still the default) and `ellipsoidal`, and the helper's `distanceVincenty` and its `"haversine"`/`"vincenty"` metrics become `ellipsoidalDistance` and `"spherical"`/`"ellipsoidal"`: since the switch to geographiclib, nothing runs Vincenty's formula anymore.
esgn and others added 5 commits October 2, 2026 11:32
jsts indexes facets in chunks of 6 segments, so a line of 6k+1 vertices ends with a single-vertex chunk whose location carries the last vertex index. getSegment then read a vertex past the end and threw a TypeError, which failed urbanisme and assiette_sup calls whose nearest object is a line reached at its end, and silently nulled distance_to_filter_center. Clamp the index to the last segment.
The result is rounded to the centimeter, so 0.5 cm, not 1 mm. Drop "coûteuse", the cost being a few microseconds, and the default already published by the schema.
Wall-clock assertions failed whenever other test files ran in parallel. The four timed tests move to *.perf.test.ts files, which test:perf (vitest.perf.config.mts) runs one file at a time and verify:fast chains after test:unit. The 500-vertex distance test now times the median of warm runs, under 15 ms.
@esgn
esgn merged commit bfe16d5 into main Oct 2, 2026
6 checks passed
@esgn
esgn deleted the 138/distance-tool branch October 2, 2026 12:23
esgn added a commit that referenced this pull request Oct 2, 2026
The rebase brought back "plus précise et coûteuse, précision à 1mm" instead of the 0.5 cm wording merged in #183, and the new ", " join produced "suivi :, `spherical`". Join the profile lines as before.
LionelZoubritzky-IGN pushed a commit that referenced this pull request Oct 2, 2026
* fix(itinerary): route with Valhalla, like the travel time isochrones

The distance tool used bdtopo-osrm while travel_time_filter isochrones use bdtopo-valhalla, so the two could disagree by up to 12% on walking times. Reuse TRAVEL_TIME_RESOURCE for the itinerary.

* fix(distance): restore the ellipsoidal precision lost in the rebase

The rebase brought back "plus précise et coûteuse, précision à 1mm" instead of the 0.5 cm wording merged in #183, and the new ", " join produced "suivi :, `spherical`". Join the profile lines as before.

* fix(distance): keep a tenth of a minute in the travel time

Rounding to the whole minute turned a 40-second walk into 1 or even 0 minutes.

* docs(distance): say which profiles return a travel time

`profile` always has a value (`spherical` by default), so "lorsqu'un profil est renseigné" was always true.

* fix(distance): round the itinerary distance to the centimeter

The spherical and ellipsoidal profiles already round to the centimeter; the itinerary passed the service value through as is.
esgn added a commit that referenced this pull request Oct 2, 2026
…l` (#207)

* feat: Implement itinerary services

* feat: plug itinerary into distance tool

* 138/review and fix (#208)

* fix(itinerary): route with Valhalla, like the travel time isochrones

The distance tool used bdtopo-osrm while travel_time_filter isochrones use bdtopo-valhalla, so the two could disagree by up to 12% on walking times. Reuse TRAVEL_TIME_RESOURCE for the itinerary.

* fix(distance): restore the ellipsoidal precision lost in the rebase

The rebase brought back "plus précise et coûteuse, précision à 1mm" instead of the 0.5 cm wording merged in #183, and the new ", " join produced "suivi :, `spherical`". Join the profile lines as before.

* fix(distance): keep a tenth of a minute in the travel time

Rounding to the whole minute turned a 40-second walk into 1 or even 0 minutes.

* docs(distance): say which profiles return a travel time

`profile` always has a value (`spherical` by default), so "lorsqu'un profil est renseigné" was always true.

* fix(distance): round the itinerary distance to the centimeter

The spherical and ellipsoidal profiles already round to the centimeter; the itinerary passed the service value through as is.

---------

Co-authored-by: Emmanuel S. <5435148+esgn@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Distance between two points tool Improve distance calculation

3 participants