@nika-js/onlymap 0.6.7 → 0.6.13

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.
Files changed (35) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +17 -3
  3. package/dist/{LercDecode.es-BzboSQ2U.js → LercDecode.es-DB1mYTrm.js} +1 -1
  4. package/dist/attribute-resolution.d.ts +2 -0
  5. package/dist/{basemap-pWXbFGjp.js → basemap-CDp9EsvL.js} +1 -1
  6. package/dist/classify.d.ts +62 -0
  7. package/dist/draw-controller.d.ts +4 -1
  8. package/dist/elements/om-map.d.ts +21 -1
  9. package/dist/{geoparquet-BPl1T2Or.js → geoparquet-CI3o8X5-.js} +1 -1
  10. package/dist/html-data.d.ts +1 -1
  11. package/dist/{index-CqsQz9Bp.js → index-BJh0t_nt.js} +2 -2
  12. package/dist/{index-iVMlGZS9.js → index-Bue-53Xo.js} +1 -1
  13. package/dist/{index-CAuq7wRs.js → index-CnKC1yuV.js} +13565 -13225
  14. package/dist/{index-Bgx3CJru.js → index-DMu0qL9C.js} +1 -1
  15. package/dist/{index-B9a6f006.js → index-Dio4lUCZ.js} +1 -1
  16. package/dist/layers/marker-icons.d.ts +12 -1
  17. package/dist/layers/route-layer.d.ts +32 -0
  18. package/dist/layers/tracking-layer.d.ts +3 -0
  19. package/dist/{lerc-BgzbFAc7.js → lerc-B1LFm9ra.js} +2 -2
  20. package/dist/onlymap.standalone.js +31212 -30872
  21. package/dist/onlymapjs.js +1 -1
  22. package/dist/programmatic.d.ts +19 -0
  23. package/dist/{raster-DtyMY54Z.js → raster-DQ1dS7mZ.js} +2 -2
  24. package/dist/{raster-pipeline-BmHRCUEb.js → raster-pipeline-mXzwFf0A.js} +1 -1
  25. package/dist/runtime-core.d.ts +22 -1
  26. package/dist/testing.d.ts +4 -1
  27. package/dist/version.d.ts +1 -1
  28. package/dist/{zarr-CTpFZo_m.js → zarr-BSoVUvcs.js} +2 -2
  29. package/docs/routing.md +23 -4
  30. package/docs/testing.md +1 -1
  31. package/llms.txt +7 -5
  32. package/onlymapjs.html-data.json +48 -1
  33. package/package.json +3 -2
  34. package/skills/onlymapjs/SKILL.md +6 -5
  35. package/skills/onlymapjs/references/syntax.md +7 -5
@@ -16,8 +16,8 @@ Vite/npm project:
16
16
  Static CDN page (raw-file CDNs only — unpkg/jsDelivr; never esm.sh or another rebundling CDN, which duplicates the WebGL runtime and breaks layer shaders):
17
17
 
18
18
  ```html
19
- <link rel="stylesheet" href="https://unpkg.com/@nika-js/onlymap@0.6.7/dist/onlymapjs.css">
20
- <script type="module" src="https://unpkg.com/@nika-js/onlymap@0.6.7"></script>
19
+ <link rel="stylesheet" href="https://unpkg.com/@nika-js/onlymap@0.6.13/dist/onlymapjs.css">
20
+ <script type="module" src="https://unpkg.com/@nika-js/onlymap@0.6.13"></script>
21
21
  ```
22
22
 
23
23
  Always include `onlymapjs.css` — it carries the MapLibre basemap styles and the no-JS fallback rules (`<om-fallback>` / default banner). For the fallback to work in script-disabled previews it must load without JavaScript: a real `<link rel="stylesheet">` or inlined `<style>` on no-build pages (a bundler-emitted stylesheet is fine in npm projects).
@@ -290,12 +290,14 @@ No server setup is needed: a static host serves Zarr's extensionless chunk keys
290
290
  The same ~15-line shape works for any OSRM-dialect endpoint (a self-hosted OSRM, Mapbox Directions with a token) by swapping the base URL. OSRM returns `geometries=geojson` natively, so no polyline decoding is needed.
291
291
  - `color`/`casing-color` style the line (defaults `#2563eb`/`#0f172a`).
292
292
  - `follow="fit-route"` auto-fits the camera once the route resolves — no manual `flyToBounds` needed.
293
+ - Reading the result back: the map dispatches `om-route-resolved` on every resolve (`detail = {layerId, route}` — normalized geometry/distanceMeters/durationSec/legs/bounds; `MapController` twin: `onRouteResolved`). Use it for readouts, ETAs, or driving anything off the computed geometry — never re-fetch what the provider already returned.
294
+ - Tail modes: `progress-from="<tracking-layer-id>"` links the route to a Tracking layer, and `tail` picks how the TRAVELED portion renders — `tail="none"` (client view: only current position → destination renders, origin pin dropped too), `tail="dim"` (operator view: traveled portion darkened — `tail-color` overrides the default ~35%-brightness derivation), default full (split ignored). The split is the marker's interpolated position projected onto the route line, advancing per frame with the glide. All three attributes are one mechanism — validation warns on partial wiring (tail without progress-from, progress-from without tail, tail-color outside dim, an unknown progress-from id).
293
295
  - `Tracking` renders ONE moving entity's current position with bearing-derived icon rotation — expands into an `IconLayer`.
294
296
  - `get-position` (required, a normal compiled accessor like any curated layer) reads position off `data` — the LAST row is "the" tracked position (v1 = one entity per layer; a fleet is one `Tracking` layer per vehicle).
295
297
  - Live updates ride the ORDINARY `data`/`source` mechanism (a `wss://` stream + `OmMap.registerSource`, or anything else that changes `data`) — there is no separate tracking-subscription API.
296
298
  - `bearing-field` (default `"bearing"`) names the plain data field to rotate the icon by (checks `properties.<field>` on a GeoJSON row, `<field>` directly on a flat row).
297
299
  - `interpolate-ms` (default `1000`) is how long the marker glides between two position fixes (the per-frame channel — no re-render, no accessor recompute) instead of jumping; `follow="follow"` eases the camera along with it, timed to the same duration.
298
- - `color`/`size` style the default arrow icon (defaults `#2563eb`/`28`px).
300
+ - `color`/`size` style the marker (defaults `#2563eb`/`28`px); `icon="arrow|car|motorcycle"` picks its shape (default arrow) — all nose-up SVGs baked in `color`, so rotation and tinting work for every shape; unknown names fall back to the arrow (validation warns).
299
301
 
300
302
  External layer classes become manifest types via `OmMap.registerLayer({type, deckClass, props})`. Build them on `@nika-js/onlymap/deck` (the bundled `CompositeLayer`/`TileLayer`/… re-exports — a separately-installed deck.gl is a different class hierarchy and breaks in the renderer); function-valued props ride the subclass's `static defaultProps`; register at module top level before the manifest mounts. Full recipe: docs/custom-layers.md.
301
303
 
@@ -434,7 +436,7 @@ Built-ins:
434
436
  - `filter`
435
437
  - `draw` — sketch-capture toolbar: `modes="point line polygon"` (default all three), `target="<name>"` (default `sketch`, bound via `data="draw:<target>"`), `save="both|download|file-system"`, `autosave="<localStorage key>"`. `export-3d` (bare = GLB default, `="b3dm"` wraps it for Cesium/3D-Tiles pipelines) adds an "Export 3D" button (spec: issue #34 — region export) — deliberately separate from `save` (that's the drawn shape's own GeoJSON; `export-3d` exports the 3D `Tile3DLayer`/`BIMLayer` content found INSIDE the drawn footprint). Outline a polygon over loaded 3D content, close it, click "Export 3D": clips every loaded tile's triangles to the footprint (a plain 2D clip — no elevation-picking involved), re-frames them to a local coordinate frame at the footprint's own centroid (portable — opens correctly in Blender/three.js/etc. without ECEF-scale support), and downloads it, each triangle carrying its own source color (baked as vertex colors). No textures — BIM/IFC materials are flat colors, not textured meshes. The export only pulls in currently-VISIBLE 3D Tiles/BIM layers — one hidden via `visible="false"` (or the `toggle-layer` action) is excluded, with a distinct console warning distinguishing "nothing has loaded yet" from "everything loaded is hidden." Validation warns on an unrecognized `export-3d` value.
436
438
  - `clip-box` — native UI over the map's `clip-box-*` scene-state attributes (see the `<om-map>` section above): six number inputs (min/max × lng/lat/elevation), invert/highlight checkboxes, and a clear button, all wired through `set-clip-box`. Manifest is the source of truth — the panel re-syncs from the attributes on every render, so undo/redo and story-scrub move the inputs too.
437
- - `measure` — geodesic ruler: `modes="distance area volume"` (space-separated; default `distance area`), `units="metric|imperial|nautical"`. Click the map to place points; live per-segment + total labels render on the map, and a totals panel + a `units` toggle sit in the widget. Distance is haversine on the WGS84 mean sphere (≤0.56% vs. the true geodesic); area is the spherical-excess integral. Nautical shows nmi for length and falls back to metric for area. Reuses the draw capture stack (measure and draw are mutually exclusive); the geometry is ephemeral (never saved, never an undo step). Consume the reading programmatically via the `om-measure` event on `<om-map>` (`detail = {mode, units, totalMeters, segments, areaMeters2, perimeterMeters, poleWarning, cutMeters3, fillMeters3, netMeters3, totalMeters3, cutAdjustedMeters3, fillAdjustedMeters3, swell, shrink, cutMassKg, fillMassKg, cellSizeM, gsdM, cutErrorM3, fillErrorM3, nodataFraction, baseSurface, stale, profileSeries}` — `profileSeries` points are `{x: metres from the first vertex, y: elevation m}`, with `vertexIndex` present only on samples that ARE a drawn corner (filter a chart on `isValid(datum.vertexIndex)`; vertex 0 is the leftmost point, and with `profile` on the map badges the first two vertices `1 · Start` and `2` in draw order — 1-based display, field stays 0-based — so clockwise vs counter-clockwise is stated, not inferred; two is the minimum that fixes a direction and stays constant however many corners there are, while the chart marks them all) — everything from `cutMeters3` on is volume-mode-only, populating once a footprint closes). `volume` mode outlines a polygon footprint the same way `area` does — double-click (or Enter) closes it, and it turns solid teal to signal it's ready — then a double-headed arrow gizmo (fixed screen-pixel size, unbounded drag distance) appears at the centroid: drag it up to fill, down to cut, panel reads Cut/Fill/Net (signed, fill−cut)/Total (unsigned, cut+fill) volume + Area/Perimeter live — always RAW geometric figures, never altered by `swell`/`shrink`. REQUIRES `terrain` on `<om-map>` (validation warns a `volume` mode with none): the math is a REAL per-cell grid integration (issue #35) — closing a footprint bulk-loads its covering DEM tiles and integrates terrain-vs-base per cell on a metric tangent-plane grid (cell size = the DEM's GSD at the ring's latitude, scanline point-in-polygon, bilinear tile-seam-correct sampling, worker-offloaded with a synchronous fallback), reporting mixed cut AND fill within one footprint on undulating ground plus `cellSizeM`/`gsdM`/`cutErrorM3`/`fillErrorM3` (± = per-cell cellArea × 1.5 × GSD, summed per side) and `nodataFraction` on the readout. `base-surface` picks the reference surface: `custom` (default — the gizmo's draggable target plane, re-summed live from the cached grid during a drag) or boundary-derived stockpile strategies with NO gizmo (`triangulated` boundary TIN — the drone-survey default, `plane` least-squares, `lowest`/`highest`/`average`). No terrain (or a failed tile fetch) falls back to the flat single-elevation approximation with no error figures rather than erroring. Five more volume-only attributes, all no-ops without `volume` in `modes` (validation warns): `base-surface` (above); `profile` — closing a footprint also samples elevation around its own perimeter, dispatched on `profileSeries` for a paired `dynamic-chart` widget to plot, updating live from the first vertex (debounced on hover, immediate on each new vertex) while sketching, not just on close; `deadband` (m³, default 0) — zeroes a Cut/Fill figure below the threshold; `density` (t/m³ metric, lb/yd³ imperial) and `swell`/`shrink` (multipliers, default 1×) populate a SEPARATE Material section instead of touching Cut/Fill/Net/Total — standard Bank/Loose/Compacted convention: `cutAdjustedMeters3` = raw cut × swell (loose/haul volume, bigger — excavating adds air voids), `fillAdjustedMeters3` = raw fill ÷ shrink (loose/borrow volume needed, also bigger — raw fill is already a compacted target void), `cutMassKg`/`fillMassKg` from the RAW volume (mass-conserving — swell/shrink change volume via air voids, not the mass of material). The widget only renders the Material section once at least one of `density`/`swell`/`shrink` is configured — no separate toggle. `stale` flags the brief window between a footprint committing and its elevation sample resolving.
439
+ - `measure` — geodesic ruler: `modes="distance area volume"` (space-separated; default `distance area`), `units="metric|imperial|nautical"`. Click the map to place points; live per-segment + total labels render on the map, and a totals panel + a `units` toggle sit in the widget. Distance is haversine on the WGS84 mean sphere (≤0.56% vs. the true geodesic); area is the spherical-excess integral. Nautical shows nmi for length and falls back to metric for area. Reuses the draw capture stack (measure and draw are mutually exclusive); the geometry is ephemeral (never saved, never an undo step). Consume the reading programmatically via the `om-measure` event on `<om-map>` (`detail = {mode, units, totalMeters, segments, areaMeters2, perimeterMeters, poleWarning, cutMeters3, fillMeters3, netMeters3, totalMeters3, cutAdjustedMeters3, fillAdjustedMeters3, swell, shrink, cutMassKg, fillMassKg, cellSizeM, gsdM, cutErrorM3, fillErrorM3, nodataFraction, baseSurface, stale, profileSeries}` — `profileSeries` points are `{x: metres from the first vertex, y: elevation m}`, with `vertexIndex` present only on samples that ARE a drawn corner (filter a chart on `isValid(datum.vertexIndex)`; vertex 0 is the leftmost point, and with `profile` on the map badges the first two vertices `1 · Start` and `2` in draw order — 1-based display, field stays 0-based — so clockwise vs counter-clockwise is stated, not inferred; two is the minimum that fixes a direction and stays constant however many corners there are, while the chart marks them all) — everything from `cutMeters3` on is volume-mode-only, populating once a footprint closes). `volume` mode outlines a polygon footprint the same way `area` does — double-click, touch double-tap, or Enter closes it, and it turns solid teal to signal it's ready — then a double-headed arrow gizmo (fixed screen-pixel size, unbounded drag distance) appears at the centroid: drag it up to fill, down to cut, panel reads Cut/Fill/Net (signed, fill−cut)/Total (unsigned, cut+fill) volume + Area/Perimeter live — always RAW geometric figures, never altered by `swell`/`shrink`. REQUIRES `terrain` on `<om-map>` (validation warns a `volume` mode with none): the math is a REAL per-cell grid integration (issue #35) — closing a footprint bulk-loads its covering DEM tiles and integrates terrain-vs-base per cell on a metric tangent-plane grid (cell size = the DEM's GSD at the ring's latitude, scanline point-in-polygon, bilinear tile-seam-correct sampling, worker-offloaded with a synchronous fallback), reporting mixed cut AND fill within one footprint on undulating ground plus `cellSizeM`/`gsdM`/`cutErrorM3`/`fillErrorM3` (± = per-cell cellArea × 1.5 × GSD, summed per side) and `nodataFraction` on the readout. `base-surface` picks the reference surface: `custom` (default — the gizmo's draggable target plane, re-summed live from the cached grid during a drag) or boundary-derived stockpile strategies with NO gizmo (`triangulated` boundary TIN — the drone-survey default, `plane` least-squares, `lowest`/`highest`/`average`). No terrain (or a failed tile fetch) falls back to the flat single-elevation approximation with no error figures rather than erroring. Five more volume-only attributes, all no-ops without `volume` in `modes` (validation warns): `base-surface` (above); `profile` — closing a footprint also samples elevation around its own perimeter, dispatched on `profileSeries` for a paired `dynamic-chart` widget to plot, updating live from the first vertex (debounced on hover, immediate on each new vertex) while sketching, not just on close; `deadband` (m³, default 0) — zeroes a Cut/Fill figure below the threshold; `density` (t/m³ metric, lb/yd³ imperial) and `swell`/`shrink` (multipliers, default 1×) populate a SEPARATE Material section instead of touching Cut/Fill/Net/Total — standard Bank/Loose/Compacted convention: `cutAdjustedMeters3` = raw cut × swell (loose/haul volume, bigger — excavating adds air voids), `fillAdjustedMeters3` = raw fill ÷ shrink (loose/borrow volume needed, also bigger — raw fill is already a compacted target void), `cutMassKg`/`fillMassKg` from the RAW volume (mass-conserving — swell/shrink change volume via air voids, not the mass of material). The widget only renders the Material section once at least one of `density`/`swell`/`shrink` is configured — no separate toggle. `stale` flags the brief window between a footprint committing and its elevation sample resolving.
438
440
  - `vega-lite`
439
441
  - `dynamic-chart` — same Vega-Lite rendering as `vega-lite`, but data-driven by a live DOM event instead of a layer/`ctx.data`: `on="<event-name>"` (required — the event to listen for on `<om-map>`), `series-field="<name>"` (default `series`) reads `event.detail[seriesField]` as the chart's `data.values` and re-embeds on every event where that field is a present array; `width` (fixed, default 280) and `title` work the same as `vega-lite`. The child `<script type="application/json">` spec is the same Vega-Lite mark/encoding shape, minus `data` (supplied live). A feature "freezes" the chart for free by simply not including the field on a later event (e.g. switching modes) — the widget has no separate pause API, it just does nothing when the field is absent. Built for a feature that computes its own series as the user interacts (a drawn line's elevation profile updating vertex-by-vertex) and has no layer of its own to bind to.
440
442
  - `player`
@@ -710,7 +712,7 @@ Use a normal GeoJSON layer bound to a draw store plus a draw widget:
710
712
  autosave="my-sketch"></om-widget>
711
713
  ```
712
714
 
713
- The draw widget supports points, lines, polygons, delete-last, clear, save, and autosave. Lines/polygons close with double-click or Enter; Escape cancels the in-progress shape.
715
+ The draw widget supports points, lines, polygons, delete-last, clear, save, and autosave. Lines/polygons close with double-click, touch double-tap (detected by the library — iOS WebViews never synthesize `dblclick`), Enter, or the toolbar's Finish button; Escape cancels the in-progress shape.
714
716
 
715
717
  ### 3D
716
718