@unmap/elevation 0.14.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @unmap/elevation
2
2
 
3
- Ground elevation anywhere in Canada, from NRCan's national 30 m DEM.
3
+ DEM elevation from the active unmap terrain release.
4
4
 
5
5
  ```ts
6
6
  import { Elevation } from "@unmap/elevation";
@@ -9,13 +9,18 @@ const elevation = new Elevation({ key: "um_live_..." });
9
9
  const [metres] = await elevation.get([-114.0719, 51.0447]);
10
10
  ```
11
11
 
12
- Heights are metres above the CGVD2013 geoid. `null` means the dataset covers nothing there; it
13
- never means sea level.
12
+ Heights are metres. After global Mapterhorn activation, source datums, native resolutions and
13
+ terrain/surface models vary; this is not a uniform bare-earth DTM. Before activation or after
14
+ Canadian rollback, MRDEM reports CGVD2013 and 30 m resolution. Check `/coverage.json` for the
15
+ active release. The client keeps returning an ordered `(number | null)[]`; `null` is missing data.
16
+ Direct HTTP responses expose `datum: "mixed"`, `resolution: null`, `model: "mixed"` and sampling
17
+ metadata for Mapterhorn. Its z12 0.5 m height increment is encoding precision, not accuracy.
14
18
 
15
19
  An unconfigured terrain archive throws `ElevationError` with status `404` and code `not_found`
16
20
  (`terrain archive not configured`). A terrain tile that will not decode is status `502` and code
17
21
  `upstream_error` (`elevation sample failed`). That `502` has no `Retry-After`. The client still
18
- retries it, on its own backoff. A coordinate the archive does not cover stays `null`.
22
+ retries it, on its own backoff. A coordinate the archive does not cover stays `null`. An unavailable selected global release
23
+ throws status `503`, code `service_unavailable`, without falling back to another DEM.
19
24
 
20
25
  `@unmap/sdk` exposes the same object as `unmap.elevation`. Full documentation:
21
26
  <https://unmap.dev/docs/apis/elevation>.
package/dist/index.d.ts CHANGED
@@ -46,8 +46,10 @@ declare class ElevationError extends UnmapError {
46
46
  /**
47
47
  * Typed client for the unmap elevation API (gateway `/elevation`).
48
48
  *
49
- * Heights are metres above CGVD2013. `null` means the dataset covers nothing at that coordinate;
50
- * it never means sea level, and the client does not substitute a number for it.
49
+ * Heights are metres in the active DEM's vertical datum. The global Mapterhorn mosaic mixes
50
+ * terrain/surface models and vertical datums; Canadian rollback uses CGVD2013. `null` means
51
+ * missing data, and the client does not substitute a number for it. See /coverage.json and
52
+ * the HTTP response's metadata for the active release and its limitations.
51
53
  */
52
54
  declare class Elevation {
53
55
  private readonly key;
@@ -56,7 +58,7 @@ declare class Elevation {
56
58
  private readonly retry;
57
59
  constructor(opts: ElevationOptions);
58
60
  /**
59
- * Ground elevation in metres, one entry per coordinate, in the order asked.
61
+ * DEM elevation in metres, one entry per coordinate, in the order asked.
60
62
  *
61
63
  * Always an array, whether you passed one coordinate or a thousand, so the single and batch
62
64
  * cases are the same call:
package/dist/index.js CHANGED
@@ -22,7 +22,7 @@ var Elevation = class {
22
22
  this.fetchImpl = opts.fetch ?? globalThis.fetch.bind(globalThis);
23
23
  }
24
24
  /**
25
- * Ground elevation in metres, one entry per coordinate, in the order asked.
25
+ * DEM elevation in metres, one entry per coordinate, in the order asked.
26
26
  *
27
27
  * Always an array, whether you passed one coordinate or a thousand, so the single and batch
28
28
  * cases are the same call:
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { DEFAULT_GATEWAY, UnmapError, fetchWithRetry, parseRetryAfter, type RetryPolicy } from \"@unmap/core\";\n\n/** [longitude, latitude]. Longitude first, everywhere in unmap. Not exported: `@unmap/routing`\n * already exports a `LngLat` of the same shape, and both packages land in `@unmap/sdk`'s star\n * exports, where two same-named exports would be a type error. */\ntype LngLat = [number, number];\n\nexport interface ElevationOptions {\n key: string;\n gateway?: string;\n fetch?: typeof fetch;\n /**\n * Retry policy for `429`, `502`, `503` and transport failures. `false` disables it.\n *\n * On by default. `Retry-After` is on a `429` other than `billing_required`, and on a container\n * `503`. A `502` has none: routing uses `routing_failed`, and `/elevation` uses\n * `upstream_error`. With no header the client backs off itself. A wait longer than\n * `maxDelayMs` (10 s) is not slept through; the error carries `retryAfterSeconds` instead.\n * See `RetryPolicy` in `@unmap/core`.\n */\n retry?: RetryPolicy | false;\n}\n\n/** The gateway's own cap. Checked here so an over-long batch fails without spending a call. */\nexport const MAX_ELEVATION_POINTS = 1000;\n\n/**\n * Cloudflare refuses a request URL longer than this at the edge, before the Worker runs.\n *\n * It bites well before `MAX_ELEVATION_POINTS` does. `URLSearchParams` percent-encodes both of\n * the batch separators (`,` becomes `%2C`, `|` becomes `%7C`), so a coordinate costs about six\n * bytes more than it reads, and a thousand six-decimal points is roughly 22 KB of URL. Past the\n * limit the request never reaches the gateway: the caller gets an edge 414 with no error\n * envelope to explain it, which is the least legible failure in the system. So the check is\n * here, against the real encoded URL, and the message says what actually fits.\n */\nexport const MAX_REQUEST_URL_BYTES = 16384;\n\n/** Headroom under the edge limit, so a proxy that appends a parameter cannot tip a request over. */\nconst URL_HEADROOM_BYTES = 256;\n\n/**\n * An elevation failure.\n *\n * Extends `UnmapError`, so `catch (e) { if (e instanceof UnmapError) }` catches this alongside\n * every other unmap client's errors. `instanceof ElevationError` keeps working, and `status` and `code`\n * are still where they were; `retryAfterSeconds` is new and comes from the header.\n */\nexport class ElevationError extends UnmapError {\n constructor(status: number, message: string, code?: string, retryAfterSeconds?: number) {\n super(status, message, code, retryAfterSeconds);\n this.name = \"ElevationError\";\n }\n}\n\ninterface ElevationResponse {\n elevations: (number | null)[];\n units: \"m\";\n datum: string;\n resolution: number;\n}\n\n/**\n * Typed client for the unmap elevation API (gateway `/elevation`).\n *\n * Heights are metres above CGVD2013. `null` means the dataset covers nothing at that coordinate;\n * it never means sea level, and the client does not substitute a number for it.\n */\nexport class Elevation {\n private readonly key: string;\n private readonly base: string;\n private readonly fetchImpl: typeof fetch;\n private readonly retry: RetryPolicy | false | undefined;\n\n constructor(opts: ElevationOptions) {\n this.retry = opts.retry;\n this.key = opts.key;\n this.base = (opts.gateway ?? DEFAULT_GATEWAY).replace(/\\/+$/, \"\");\n // Bound to globalThis for the same reason Router does it: a bare `fetch` stored on an\n // instance is invoked with that instance as its receiver, which browsers reject.\n this.fetchImpl = opts.fetch ?? globalThis.fetch.bind(globalThis);\n }\n\n /**\n * Ground elevation in metres, one entry per coordinate, in the order asked.\n *\n * Always an array, whether you passed one coordinate or a thousand, so the single and batch\n * cases are the same call:\n *\n * const [metres] = await unmap.elevation.get([-114.0719, 51.0447]);\n */\n async get(\n points: LngLat | LngLat[],\n opts: { signal?: AbortSignal } = {},\n ): Promise<(number | null)[]> {\n const list: LngLat[] = isSingle(points) ? [points] : points;\n if (list.length === 0) return [];\n if (list.length > MAX_ELEVATION_POINTS) {\n throw new ElevationError(400, `elevation.get takes at most ${MAX_ELEVATION_POINTS} coordinates`);\n }\n\n const q = new URLSearchParams({ key: this.key });\n if (list.length === 1) {\n // Safe: the length check above guarantees index 0 exists.\n const [lon, lat] = list[0]!;\n q.set(\"lon\", String(lon));\n q.set(\"lat\", String(lat));\n } else {\n q.set(\"points\", list.map(([lng, lat]) => `${lng},${lat}`).join(\"|\"));\n }\n\n const target = `${this.base}/elevation?${q}`;\n const bytes = new TextEncoder().encode(target).length;\n const budget = MAX_REQUEST_URL_BYTES - URL_HEADROOM_BYTES;\n if (bytes > budget) {\n // Scaled from the URL actually built, so the number quoted reflects this caller's own\n // coordinate precision rather than an average of somebody else's.\n const fits = Math.max(1, Math.floor((list.length * budget) / bytes));\n throw new ElevationError(\n 414,\n `elevation.get built a ${bytes} byte request URL; this client sends at most ${budget} ` +\n `bytes, keeping headroom under the edge's ${MAX_REQUEST_URL_BYTES} byte limit. Send ` +\n `at most about ${fits} of these coordinates per request (roughly 700 at six decimal ` +\n `places).`,\n );\n }\n\n const res = await fetchWithRetry(\n this.fetchImpl,\n target,\n { signal: opts.signal, headers: { accept: \"application/json\" } },\n this.retry,\n );\n if (!res.ok) throw await errorFrom(res);\n const body = (await res.json()) as ElevationResponse;\n return body.elevations;\n }\n}\n\n/** `[number, number]` is a coordinate; `[[number, number], ...]` is a list of them. */\nfunction isSingle(points: LngLat | LngLat[]): points is LngLat {\n return typeof points[0] === \"number\";\n}\n\nasync function errorFrom(res: { status: number; headers?: Headers; json(): Promise<unknown> }): Promise<ElevationError> {\n const fallback = `elevation ${res.status}`;\n let body: { error?: unknown; code?: unknown } | undefined;\n try {\n body = (await res.json()) as { error?: unknown; code?: unknown };\n } catch {\n body = undefined;\n }\n const reason = typeof body?.error === \"string\" ? body.error : undefined;\n const code = typeof body?.code === \"string\" ? body.code : undefined;\n const retryAfter = parseRetryAfter(res.headers?.get(\"retry-after\") ?? null) ?? undefined;\n return new ElevationError(res.status, reason ? `${reason} (${fallback})` : fallback, code, retryAfter);\n}\n\n// The shared error type and retry policy, re-exported so a caller who installed only this\n// package can `catch (e) { if (e instanceof UnmapError) }` without adding @unmap/core.\nexport { UnmapError, parseRetryAfter, type RetryPolicy } from \"@unmap/core\";\n"],"mappings":"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","names":["UnmapError","parseRetryAfter"]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { DEFAULT_GATEWAY, UnmapError, fetchWithRetry, parseRetryAfter, type RetryPolicy } from \"@unmap/core\";\n\n/** [longitude, latitude]. Longitude first, everywhere in unmap. Not exported: `@unmap/routing`\n * already exports a `LngLat` of the same shape, and both packages land in `@unmap/sdk`'s star\n * exports, where two same-named exports would be a type error. */\ntype LngLat = [number, number];\n\nexport interface ElevationOptions {\n key: string;\n gateway?: string;\n fetch?: typeof fetch;\n /**\n * Retry policy for `429`, `502`, `503` and transport failures. `false` disables it.\n *\n * On by default. `Retry-After` is on a `429` other than `billing_required`, and on a container\n * `503`. A `502` has none: routing uses `routing_failed`, and `/elevation` uses\n * `upstream_error`. With no header the client backs off itself. A wait longer than\n * `maxDelayMs` (10 s) is not slept through; the error carries `retryAfterSeconds` instead.\n * See `RetryPolicy` in `@unmap/core`.\n */\n retry?: RetryPolicy | false;\n}\n\n/** The gateway's own cap. Checked here so an over-long batch fails without spending a call. */\nexport const MAX_ELEVATION_POINTS = 1000;\n\n/**\n * Cloudflare refuses a request URL longer than this at the edge, before the Worker runs.\n *\n * It bites well before `MAX_ELEVATION_POINTS` does. `URLSearchParams` percent-encodes both of\n * the batch separators (`,` becomes `%2C`, `|` becomes `%7C`), so a coordinate costs about six\n * bytes more than it reads, and a thousand six-decimal points is roughly 22 KB of URL. Past the\n * limit the request never reaches the gateway: the caller gets an edge 414 with no error\n * envelope to explain it, which is the least legible failure in the system. So the check is\n * here, against the real encoded URL, and the message says what actually fits.\n */\nexport const MAX_REQUEST_URL_BYTES = 16384;\n\n/** Headroom under the edge limit, so a proxy that appends a parameter cannot tip a request over. */\nconst URL_HEADROOM_BYTES = 256;\n\n/**\n * An elevation failure.\n *\n * Extends `UnmapError`, so `catch (e) { if (e instanceof UnmapError) }` catches this alongside\n * every other unmap client's errors. `instanceof ElevationError` keeps working, and `status` and `code`\n * are still where they were; `retryAfterSeconds` is new and comes from the header.\n */\nexport class ElevationError extends UnmapError {\n constructor(status: number, message: string, code?: string, retryAfterSeconds?: number) {\n super(status, message, code, retryAfterSeconds);\n this.name = \"ElevationError\";\n }\n}\n\ninterface ElevationResponse {\n elevations: (number | null)[];\n units: \"m\";\n datum: string;\n resolution: number | null;\n model?: \"mixed\";\n sampling?: { zoom: number; tile_size: number; height_increment_m: number; interpolation: \"bilinear\" };\n}\n\n/**\n * Typed client for the unmap elevation API (gateway `/elevation`).\n *\n * Heights are metres in the active DEM's vertical datum. The global Mapterhorn mosaic mixes\n * terrain/surface models and vertical datums; Canadian rollback uses CGVD2013. `null` means\n * missing data, and the client does not substitute a number for it. See /coverage.json and\n * the HTTP response's metadata for the active release and its limitations.\n */\nexport class Elevation {\n private readonly key: string;\n private readonly base: string;\n private readonly fetchImpl: typeof fetch;\n private readonly retry: RetryPolicy | false | undefined;\n\n constructor(opts: ElevationOptions) {\n this.retry = opts.retry;\n this.key = opts.key;\n this.base = (opts.gateway ?? DEFAULT_GATEWAY).replace(/\\/+$/, \"\");\n // Bound to globalThis for the same reason Router does it: a bare `fetch` stored on an\n // instance is invoked with that instance as its receiver, which browsers reject.\n this.fetchImpl = opts.fetch ?? globalThis.fetch.bind(globalThis);\n }\n\n /**\n * DEM elevation in metres, one entry per coordinate, in the order asked.\n *\n * Always an array, whether you passed one coordinate or a thousand, so the single and batch\n * cases are the same call:\n *\n * const [metres] = await unmap.elevation.get([-114.0719, 51.0447]);\n */\n async get(\n points: LngLat | LngLat[],\n opts: { signal?: AbortSignal } = {},\n ): Promise<(number | null)[]> {\n const list: LngLat[] = isSingle(points) ? [points] : points;\n if (list.length === 0) return [];\n if (list.length > MAX_ELEVATION_POINTS) {\n throw new ElevationError(400, `elevation.get takes at most ${MAX_ELEVATION_POINTS} coordinates`);\n }\n\n const q = new URLSearchParams({ key: this.key });\n if (list.length === 1) {\n // Safe: the length check above guarantees index 0 exists.\n const [lon, lat] = list[0]!;\n q.set(\"lon\", String(lon));\n q.set(\"lat\", String(lat));\n } else {\n q.set(\"points\", list.map(([lng, lat]) => `${lng},${lat}`).join(\"|\"));\n }\n\n const target = `${this.base}/elevation?${q}`;\n const bytes = new TextEncoder().encode(target).length;\n const budget = MAX_REQUEST_URL_BYTES - URL_HEADROOM_BYTES;\n if (bytes > budget) {\n // Scaled from the URL actually built, so the number quoted reflects this caller's own\n // coordinate precision rather than an average of somebody else's.\n const fits = Math.max(1, Math.floor((list.length * budget) / bytes));\n throw new ElevationError(\n 414,\n `elevation.get built a ${bytes} byte request URL; this client sends at most ${budget} ` +\n `bytes, keeping headroom under the edge's ${MAX_REQUEST_URL_BYTES} byte limit. Send ` +\n `at most about ${fits} of these coordinates per request (roughly 700 at six decimal ` +\n `places).`,\n );\n }\n\n const res = await fetchWithRetry(\n this.fetchImpl,\n target,\n { signal: opts.signal, headers: { accept: \"application/json\" } },\n this.retry,\n );\n if (!res.ok) throw await errorFrom(res);\n const body = (await res.json()) as ElevationResponse;\n return body.elevations;\n }\n}\n\n/** `[number, number]` is a coordinate; `[[number, number], ...]` is a list of them. */\nfunction isSingle(points: LngLat | LngLat[]): points is LngLat {\n return typeof points[0] === \"number\";\n}\n\nasync function errorFrom(res: { status: number; headers?: Headers; json(): Promise<unknown> }): Promise<ElevationError> {\n const fallback = `elevation ${res.status}`;\n let body: { error?: unknown; code?: unknown } | undefined;\n try {\n body = (await res.json()) as { error?: unknown; code?: unknown };\n } catch {\n body = undefined;\n }\n const reason = typeof body?.error === \"string\" ? body.error : undefined;\n const code = typeof body?.code === \"string\" ? body.code : undefined;\n const retryAfter = parseRetryAfter(res.headers?.get(\"retry-after\") ?? null) ?? undefined;\n return new ElevationError(res.status, reason ? `${reason} (${fallback})` : fallback, code, retryAfter);\n}\n\n// The shared error type and retry policy, re-exported so a caller who installed only this\n// package can `catch (e) { if (e instanceof UnmapError) }` without adding @unmap/core.\nexport { UnmapError, parseRetryAfter, type RetryPolicy } from \"@unmap/core\";\n"],"mappings":"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","names":["UnmapError","parseRetryAfter"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@unmap/elevation",
3
- "version": "0.14.0",
4
- "description": "Typed client for the unmap elevation API (Canadian ground elevation)",
3
+ "version": "0.16.0",
4
+ "description": "Typed client for the unmap DEM elevation API",
5
5
  "license": "MIT",
6
6
  "keywords": [
7
7
  "unmap",
@@ -37,7 +37,7 @@
37
37
  "access": "public"
38
38
  },
39
39
  "dependencies": {
40
- "@unmap/core": "0.14.0"
40
+ "@unmap/core": "0.16.0"
41
41
  },
42
42
  "devDependencies": {
43
43
  "tsup": "^8.3.0",