/** * Geodesy (spec: issue #20 "Measure widget — geodesic distance and area"). * * Pure spherical math on a sphere of the WGS84 MEAN radius (2a + b)/3 = * 6 371 008.7714 m. A sphere, not the ellipsoid: documented accuracy vs. the * true WGS84 geodesic is ≤ 0.56% worst case (near-meridional lines), typically * < 0.3%. Deliberately NOT Vincenty (fails to converge near antipodes) and NOT * a Karney/GeographicLib port (overkill for v1) — but every signature takes the * radius, so an ellipsoidal `geodesic="ellipsoidal"` opt-in can slot in later * without touching callers. Haversine uses GL's numerically-guarded form * `2R·asin(min(1, √h))`. Area is the Chamberlain–Duquette line integral (the * JPL formulation Turf's area uses), returning |signed area| so self- * intersecting lobes cancel. */ /** WGS84 mean radius (2a + b)/3, with a = 6378137 m, 1/f = 298.257223563. */ export declare const WGS84_MEAN_RADIUS_M = 6371008.7714; /** The sphere radius (m) current measurements resolve against. */ export declare function getMeasureRadiusMeters(): number; /** Override the measure radius (e.g. a non-Earth body). Non-positive values reset to WGS84. */ export declare function setMeasureRadiusMeters(radiusMeters: number): void; export type LngLat = [number, number]; /** Haversine great-circle distance in meters (guarded `2R·asin(min(1, √h))`). */ export declare function distanceMeters(a: LngLat, b: LngLat, radius?: number): number; /** Total haversine length of a polyline in meters (0 for < 2 points). */ export declare function pathLengthMeters(points: LngLat[], radius?: number): number; /** * Web Mercator ground resolution — meters per screen pixel at a latitude and * zoom. The one formula four controllers used to carry inline (draw close * guard, clip-box handle radius, measure hover tolerance, filter histogram). * `minCosLat` clamps the cosine near the poles (the clip-box gizmo needs a * floor so handle hit radii stay finite above ~84°); the default 0 keeps the * exact classic formula. */ export declare function metersPerPixel(latitude: number, zoom: number, minCosLat?: number): number; export interface PathSample { position: LngLat; /** Cumulative distance (m) from the path's start. */ distance: number; /** Index into the ORIGINAL input points when this sample IS one of them (see `resamplePathWithVertices`); absent for interpolated samples. */ vertexIndex?: number; } /** * `count` evenly-spaced points along a multi-segment polyline, by cumulative * distance (spec item E — elevation-profile samples). Walks the segment * lengths to find which segment each target distance falls in, then * `intermediate()`s within it — a straight generalization of that function * from "interpolate one segment" to "interpolate a whole path." `count=1` * returns just the start point; `points.length < 2` returns each input point * at distance 0 (nothing to interpolate); a zero-length path (every point * coincident) returns `count` copies of the start point at distance 0. */ export declare function resamplePath(points: LngLat[], count: number): PathSample[]; export declare function resamplePathWithVertices(points: LngLat[], count: number): PathSample[]; /** Drop a trailing vertex that duplicates the first (a closed ring → open list). */ export declare function openRing(ring: LngLat[]): LngLat[]; /** * Spherical polygon area in m² via the Chamberlain–Duquette line integral (the * exact index form Turf's `ringArea` uses, so results match Turf's fixtures). * Returns the ABSOLUTE value; ring winding and self-intersection lobes cancel. * Pass the OPEN ring (a trailing duplicate of the first point is tolerated). */ export declare function ringAreaMeters2(ring: LngLat[], radius?: number): number; /** Perimeter of a ring in meters (closes the ring implicitly). */ export declare function ringPerimeterMeters(ring: LngLat[], radius?: number): number; /** * Does this ring wind around a pole? The Chamberlain–Duquette integral * misreports a pole-enclosing ring, so the widget refuses an area for one. * Test: sum the per-edge longitude steps normalized to (−180, 180]; a ring that * does NOT enclose a pole nets ~0, one that circles a pole nets ~±360. */ export declare function ringEnclosesPole(ring: LngLat[]): boolean; /** * Point a `fraction` of the way from `a` to `b` along the great-circle path * (spherical slerp) — spec item E's evenly-spaced elevation-profile samples * need this; only the f=0.5 special case (`midpoint`) existed before. * Antimeridian-safe (interpolates the Cartesian unit vectors, not lng/lat * directly, so a segment crossing ±180° doesn't wrap the wrong way). * `f=0` returns `a`, `f=1` returns `b`. Returns [lng (normalized to * (−180, 180]), lat]. */ export declare function intermediate(a: LngLat, b: LngLat, fraction: number): LngLat; /** * Great-circle midpoint of a segment — `intermediate(a, b, 0.5)`, kept as its * own name since "the point halfway along a segment" is the common case * (badge label anchors) and reads better than a bare 0.5 at every call site. */ export declare function midpoint(a: LngLat, b: LngLat): LngLat;