@mapmap/maps 0.1.0 → 0.2.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 +165 -3
- package/dist/index.d.ts +935 -131
- package/dist/index.js +1353 -37
- package/dist/index.js.map +1 -1
- package/llms-sdk.txt +131 -0
- package/package.json +3 -2
package/llms-sdk.txt
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# @mapmap/maps — agent integration guide
|
|
2
|
+
|
|
3
|
+
You are integrating the MapMap Maps SDK: a thin TypeScript wrapper over
|
|
4
|
+
MapLibre GL JS that renders a MapMap-branded map (signed territory PMTiles)
|
|
5
|
+
with routing, places, reachability rings and effects against the MapMap
|
|
6
|
+
gateway (default https://api.mapmap.ai). ESM only. British English docs.
|
|
7
|
+
|
|
8
|
+
## Install and initialise
|
|
9
|
+
|
|
10
|
+
npm install @mapmap/maps maplibre-gl pmtiles
|
|
11
|
+
|
|
12
|
+
maplibre-gl and pmtiles are PEER dependencies: the app must own exactly ONE
|
|
13
|
+
copy of maplibre-gl. Two copies break the WebGL context, styles and the
|
|
14
|
+
pmtiles protocol registration (the SDK console.errors `[duplicate-maplibre]`
|
|
15
|
+
when it detects this).
|
|
16
|
+
|
|
17
|
+
import { MapMapMap } from "@mapmap/maps";
|
|
18
|
+
import "maplibre-gl/dist/maplibre-gl.css"; // required CSS
|
|
19
|
+
|
|
20
|
+
const map = new MapMapMap({ container: "map", apiKey: "snk_…" });
|
|
21
|
+
await map.whenReady();
|
|
22
|
+
|
|
23
|
+
GOTCHA (the number-one blank-map cause): the container must have a real
|
|
24
|
+
height. A bare `<div id="map">` resolves to 0px and MapLibre renders an
|
|
25
|
+
invisible canvas with no error. Fix: `#map { height: 100vh; }`. The SDK
|
|
26
|
+
console.errors `[container-zero-height]` when it detects this.
|
|
27
|
+
|
|
28
|
+
## Get an API key (self-serve, no account)
|
|
29
|
+
|
|
30
|
+
curl -X POST https://api.mapmap.ai/v1/keys \
|
|
31
|
+
-H "Content-Type: application/json" \
|
|
32
|
+
-d '{"email": "you@example.co.uk", "accept_tos": true}'
|
|
33
|
+
|
|
34
|
+
The key (`snk_…`) is shown once; store it as a secret. A verification email
|
|
35
|
+
raises the initial rate limits. All SDK classes reuse the map's
|
|
36
|
+
`apiKey`/`baseUrl` automatically.
|
|
37
|
+
|
|
38
|
+
## Routing (cars, walking, trucks/ADR)
|
|
39
|
+
|
|
40
|
+
import { RouteLayer } from "@mapmap/maps";
|
|
41
|
+
const routes = new RouteLayer(map);
|
|
42
|
+
const route = await routes.route(
|
|
43
|
+
{ lng: -0.1278, lat: 51.5074 },
|
|
44
|
+
{ lng: -1.8904, lat: 52.4862 },
|
|
45
|
+
{ profile: "truck", truck: { heightM: 4.0, weightT: 40, hazmat: true, tunnelCode: "C" } },
|
|
46
|
+
);
|
|
47
|
+
// route: { distanceM, durationS, geometry (GeoJSON LineString), raw }
|
|
48
|
+
|
|
49
|
+
`routes.routePath([a, b, c])` for via points; `routes.clear()` removes the
|
|
50
|
+
line. Coordinates accept `[lng, lat]`, `{lng, lat}` or `{lon, lat}` — never
|
|
51
|
+
lat-first. Pass `{ voice: true, banner: true, language: "en-GB" }` for
|
|
52
|
+
turn-by-turn instructions (see `extractGuidance`, `GuidanceBanner`, `speak`).
|
|
53
|
+
|
|
54
|
+
## Markers, clustering, store finder
|
|
55
|
+
|
|
56
|
+
import { PlacesLayer } from "@mapmap/maps";
|
|
57
|
+
const stores = new PlacesLayer(map, {
|
|
58
|
+
places: [{ id: "s1", name: "Soho", lat: 51.51, lon: -0.13 }],
|
|
59
|
+
cluster: true, // default: clustered count badges
|
|
60
|
+
fitBounds: true,
|
|
61
|
+
popup: (p) => `<strong>${p.name}</strong>`,
|
|
62
|
+
});
|
|
63
|
+
stores.nearest({ lat, lon }, 3); // haversine
|
|
64
|
+
await stores.nearestByDriveTime({ lat, lon }, { n: 3 }); // gateway /matrix
|
|
65
|
+
|
|
66
|
+
## Walkability rings (isochrones)
|
|
67
|
+
|
|
68
|
+
import { IsochroneLayer } from "@mapmap/maps";
|
|
69
|
+
const rings = new IsochroneLayer(map);
|
|
70
|
+
await rings.showReachability({
|
|
71
|
+
origin: { lat: 51.5074, lon: -0.1278 },
|
|
72
|
+
mode: "walk", // "walk" | "cycle" | "drive" | "truck" | raw costing
|
|
73
|
+
minutes: [5, 10, 15],
|
|
74
|
+
});
|
|
75
|
+
rings.clear();
|
|
76
|
+
|
|
77
|
+
Renders graduated-opacity fills, contour outlines and "N min" labels from
|
|
78
|
+
the gateway's POST /isochrone (Valhalla). Returns the GeoJSON
|
|
79
|
+
FeatureCollection for your own use.
|
|
80
|
+
|
|
81
|
+
## Cinematic flythrough + scrollytelling
|
|
82
|
+
|
|
83
|
+
import { flythrough, bindFlythroughToScroll } from "@mapmap/maps";
|
|
84
|
+
const replay = flythrough(map, route, { pitch: 60, durationMs: 15000 });
|
|
85
|
+
replay.play(); // also: pause, stop, seek(0..1), speed
|
|
86
|
+
replay.onProgress((t) => { /* 0..1 */ });
|
|
87
|
+
// Scroll-driven storytelling: scrolling scrubs the camera along the route.
|
|
88
|
+
const unbind = bindFlythroughToScroll(replay, document.querySelector("#story"));
|
|
89
|
+
|
|
90
|
+
## Route effects (flowing energy ribbon)
|
|
91
|
+
|
|
92
|
+
map.setRouteEffect("flow"); // attaches to the drawn route
|
|
93
|
+
map.setRouteEffect("flow", { color: "#ff7a1f", width: 12, speed: 0.8 });
|
|
94
|
+
map.setRouteEffect(null); // plain line again
|
|
95
|
+
|
|
96
|
+
First-party GLSL in a MapLibre custom layer. Honours
|
|
97
|
+
prefers-reduced-motion (static gradient); falls back silently to the plain
|
|
98
|
+
route line if WebGL setup fails. Styles compiled from a theme with an
|
|
99
|
+
`effects` block (`{"effects": {"route": "flow", "params": {…}}}`) carry
|
|
100
|
+
`metadata["mapmap:effects"]` and auto-enable the ribbon; an explicit
|
|
101
|
+
`setRouteEffect(…)` call always wins.
|
|
102
|
+
|
|
103
|
+
## Navigation extras
|
|
104
|
+
|
|
105
|
+
- `NavigationCamera` — turnkey chase cam for live GPS fixes (`follow`,
|
|
106
|
+
`overview`, auto-recentre). Use `flythrough` for replays, this for real
|
|
107
|
+
navigation. Not supported under globe projection.
|
|
108
|
+
- `PositionPuck` — current-position marker with heading.
|
|
109
|
+
- `GuidanceBanner` / `extractGuidance` / `speak` — visual + spoken
|
|
110
|
+
turn-by-turn from route responses.
|
|
111
|
+
- Voice: request `{ voice: true }` on routes and feed `speak()`; a
|
|
112
|
+
dedicated `voice` module provides platform speech-synthesis helpers.
|
|
113
|
+
- Themes: `style:` accepts "light", "dark", or a MapMap Studio Theme JSON
|
|
114
|
+
(palette slots + layer overrides + optional `effects`). `buildStyle()`
|
|
115
|
+
compiles one without a map.
|
|
116
|
+
|
|
117
|
+
## Error diagnosis
|
|
118
|
+
|
|
119
|
+
The SDK self-diagnoses the classic failures — one actionable console.error
|
|
120
|
+
per issue per page, each tagged and linking https://mapmap.ai/docs:
|
|
121
|
+
`[container-zero-height]`, `[container-detached]`, `[duplicate-maplibre]`,
|
|
122
|
+
`[webgl-unavailable]`, `[invalid-api-key]` (a 401 usually means a missing,
|
|
123
|
+
mistyped or revoked `snk_…` key — issue one via POST /v1/keys).
|
|
124
|
+
|
|
125
|
+
Gateway errors are RFC 9457 problem+json; SDK exceptions surface their
|
|
126
|
+
`title`/`detail` in the message.
|
|
127
|
+
|
|
128
|
+
## Attribution
|
|
129
|
+
|
|
130
|
+
"© OpenStreetMap contributors © OpenMapTiles" is legally required, baked
|
|
131
|
+
into every style, and not removable. Do not attempt to hide it.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mapmap/maps",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "MapMap Maps SDK — a thin, well-typed MapLibre GL JS wrapper that drops a MapMap-branded map with signed territory tiles and OSRM-compatible truck/ADR routing into any web app.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"author": "Precode Ltd",
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
"files": [
|
|
19
19
|
"dist",
|
|
20
20
|
"README.md",
|
|
21
|
-
"LICENSE"
|
|
21
|
+
"LICENSE",
|
|
22
|
+
"llms-sdk.txt"
|
|
22
23
|
],
|
|
23
24
|
"scripts": {
|
|
24
25
|
"build": "tsup",
|