map-zero 0.1.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/CHANGELOG.md +13 -0
- package/LICENSE +21 -0
- package/README.md +220 -0
- package/docs/api.md +66 -0
- package/docs/architecture.md +87 -0
- package/docs/cartography.md +77 -0
- package/docs/cesium.md +107 -0
- package/docs/openlayers.md +98 -0
- package/docs/styles.md +103 -0
- package/package.json +51 -0
- package/packages/cesium/package.json +13 -0
- package/packages/cesium/src/index.js +405 -0
- package/packages/ol/package.json +14 -0
- package/packages/ol/src/index.js +1705 -0
- package/packages/ol/src/labels.js +977 -0
- package/src/3dtiles/b3dm.js +38 -0
- package/src/3dtiles/clipper-surfaces.js +317 -0
- package/src/3dtiles/export.js +768 -0
- package/src/3dtiles/extrude.js +301 -0
- package/src/3dtiles/flat.js +531 -0
- package/src/3dtiles/glb.js +178 -0
- package/src/3dtiles/gpkg-buildings.js +240 -0
- package/src/3dtiles/gpkg-features.js +157 -0
- package/src/3dtiles/tileset.js +75 -0
- package/src/build.js +134 -0
- package/src/cli.js +656 -0
- package/src/export-pmtiles.js +962 -0
- package/src/geometry-read.js +50 -0
- package/src/gpkg-read.js +460 -0
- package/src/gpkg.js +567 -0
- package/src/html.js +593 -0
- package/src/layers.js +357 -0
- package/src/manifest.js +29 -0
- package/src/mvt.js +2593 -0
- package/src/ol.js +5 -0
- package/src/osm.js +2110 -0
- package/src/pmtiles-worker.js +70 -0
- package/src/pmtiles.js +260 -0
- package/src/server.js +720 -0
- package/src/style-command.js +78 -0
- package/src/style-filters.js +76 -0
- package/src/style-presets.js +93 -0
- package/src/style-themes.js +235 -0
- package/src/style.js +13 -0
- package/src/tile-cache.js +59 -0
- package/src/utils.js +222 -0
- package/styles/presets/light.json +4655 -0
- package/styles/presets/monochrome.json +4655 -0
- package/styles/presets/neon-dark-3d.json +90 -0
- package/styles/presets/neon-dark.json +4690 -0
- package/styles/presets/tactical.json +4690 -0
- package/styles/themes/neon-dark.theme.json +20 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0
|
|
4
|
+
|
|
5
|
+
Initial alpha release.
|
|
6
|
+
|
|
7
|
+
- Build `.mapzero` packages from OSM PBF extracts.
|
|
8
|
+
- Store normalized map data in GeoPackage.
|
|
9
|
+
- Serve dynamic MVT tiles locally.
|
|
10
|
+
- Export static vector PMTiles.
|
|
11
|
+
- Export Cesium 3D Tiles.
|
|
12
|
+
- Provide OpenLayers and Cesium integration helpers.
|
|
13
|
+
- Provide external JSON style presets and compact themes.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Marcos Pérez
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# map-zero
|
|
2
|
+
|
|
3
|
+
Offline vector map packages from OpenStreetMap, ready for GeoPackage, PMTiles, and 3D Tiles.
|
|
4
|
+
|
|
5
|
+
`map-zero` turns an OSM PBF extract into a portable `.mapzero` folder. The package keeps source data in GeoPackage, can export static PMTiles for fast web delivery, and can export Cesium 3D Tiles for 3D visualization. It is designed for local-first workflows: no API tokens, no hosted map service, no external data service at runtime.
|
|
6
|
+
|
|
7
|
+
When you export PMTiles or 3D Tiles, the map can be hosted serverlessly as static files. The dynamic Node server is only needed for on-demand MVT generation from `data.gpkg` or for local inspection.
|
|
8
|
+
|
|
9
|
+
> Early alpha. The format and APIs are usable, but still evolving.
|
|
10
|
+
|
|
11
|
+
## What It Does
|
|
12
|
+
|
|
13
|
+
- Builds offline map packages from `.osm.pbf`
|
|
14
|
+
- Stores normalized OSM layers in `data.gpkg`
|
|
15
|
+
- Serves dynamic MVT tiles locally
|
|
16
|
+
- Exports static vector `tiles.pmtiles`
|
|
17
|
+
- Exports Cesium `3dtiles/`
|
|
18
|
+
- Includes a minimal OpenLayers viewer
|
|
19
|
+
- Includes a minimal Cesium viewer
|
|
20
|
+
- Provides framework-agnostic OpenLayers and Cesium helpers
|
|
21
|
+
- Uses external JSON styles and compact themes
|
|
22
|
+
|
|
23
|
+
Supported logical layers include `roads`, `buildings`, `water`, `landuse`, `railways`, `boundaries`, `pois`, and `aip` for aeronautical/AIP-style data. Older `aviation` layer names are still accepted as compatibility aliases.
|
|
24
|
+
|
|
25
|
+
## Why
|
|
26
|
+
|
|
27
|
+
Most map stacks assume online tiles, external APIs, or a heavier database/server setup. `map-zero` is for small-to-medium offline packages that should be easy to build, inspect, host, and embed:
|
|
28
|
+
|
|
29
|
+
- one folder per map
|
|
30
|
+
- GeoPackage as the editable/source container
|
|
31
|
+
- PMTiles for static, serverless 2D vector maps
|
|
32
|
+
- 3D Tiles for static, serverless Cesium scenes
|
|
33
|
+
- OpenLayers and Cesium integration without owning your app
|
|
34
|
+
|
|
35
|
+
## Quick Start
|
|
36
|
+
|
|
37
|
+
Install dependencies:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm install
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Download an OSM PBF extract:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
mkdir -p data
|
|
47
|
+
wget https://download.geofabrik.de/europe/spain/madrid-latest.osm.pbf \
|
|
48
|
+
-O data/madrid.osm.pbf
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Build a package:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
node src/cli.js build ./data/madrid.osm.pbf --out ./madrid.mapzero
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Serve it:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
node src/cli.js serve ./madrid.mapzero --port 8080 --open
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Open:
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
http://localhost:8080
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`serve` is mainly a local preview and inspection command. It is also useful when you want dynamic MVT generated directly from `data.gpkg`. It is not required to deploy a map after exporting PMTiles or 3D Tiles.
|
|
70
|
+
|
|
71
|
+
By default, `build` infers the PBF bbox and extracts every supported layer. For a cropped package:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
node src/cli.js build ./data/spain.osm.pbf \
|
|
75
|
+
--bbox -3.9,40.3,-3.5,40.6 \
|
|
76
|
+
--out ./madrid.mapzero
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Package Structure
|
|
80
|
+
|
|
81
|
+
```text
|
|
82
|
+
madrid.mapzero/
|
|
83
|
+
data.gpkg # normalized OSM features
|
|
84
|
+
manifest.json # package metadata
|
|
85
|
+
tiles.pmtiles # optional static MVT archive
|
|
86
|
+
3dtiles/ # optional Cesium 3D Tiles
|
|
87
|
+
styles/
|
|
88
|
+
neon-dark.json
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
`data.gpkg` is the source for dynamic MVT, PMTiles export, and 3D Tiles export. Styles are JSON files outside the GeoPackage so the same data can be rendered by different viewers.
|
|
92
|
+
|
|
93
|
+
## PMTiles
|
|
94
|
+
|
|
95
|
+
Export static vector tiles:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
node src/cli.js pmtiles ./madrid.mapzero
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
For large regional packages, keep max zoom lower:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
node src/cli.js pmtiles ./andalucia.mapzero --minzoom 8 --maxzoom 12 --workers 4
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
When `tiles.pmtiles` is present in `manifest.json`, the built-in OpenLayers viewer uses it automatically. Without PMTiles, the server falls back to dynamic MVT generation from `data.gpkg`.
|
|
108
|
+
|
|
109
|
+
PMTiles is a single static file with HTTP range requests. It can be served from static hosting, object storage, nginx, GitHub Pages-style hosting, or any CDN that supports range requests.
|
|
110
|
+
|
|
111
|
+
Use `map-zero serve` to preview the package locally; use your normal static hosting stack to publish the generated PMTiles package.
|
|
112
|
+
|
|
113
|
+
## 3D Tiles
|
|
114
|
+
|
|
115
|
+
Export Cesium-ready 3D Tiles:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
node src/cli.js 3dtiles ./madrid.mapzero
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Buildings are extruded. Roads, railways, boundaries, water, landuse, and AIP/aeronautical features are exported as flat cartographic meshes. The Cesium viewer is available at:
|
|
122
|
+
|
|
123
|
+
```text
|
|
124
|
+
http://localhost:8080/cesium
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
3D Tiles are also static files. Once exported, they do not need the map-zero Node server; Cesium can load them from any normal static web server.
|
|
128
|
+
|
|
129
|
+
Use `map-zero serve` to preview the Cesium output locally; use static hosting to publish the exported `3dtiles/` folder.
|
|
130
|
+
|
|
131
|
+
## OpenLayers Usage
|
|
132
|
+
|
|
133
|
+
Use `@map-zero/ol` to add a package to an existing OpenLayers map:
|
|
134
|
+
|
|
135
|
+
```js
|
|
136
|
+
import Map from 'ol/Map.js';
|
|
137
|
+
import View from 'ol/View.js';
|
|
138
|
+
import { addMapZeroToOpenLayers } from '@map-zero/ol';
|
|
139
|
+
|
|
140
|
+
const map = new Map({
|
|
141
|
+
target: 'map',
|
|
142
|
+
layers: [],
|
|
143
|
+
view: new View({ center: [0, 0], zoom: 12 })
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
const controller = await addMapZeroToOpenLayers(map, {
|
|
147
|
+
id: 'madrid',
|
|
148
|
+
manifestUrl: './madrid.mapzero/manifest.json'
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
controller.setVisible('buildings', false);
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
The helper reuses the same MVT + WebGL rendering path as the built-in viewer. It supports dynamic HTTP MVT and static vector PMTiles.
|
|
155
|
+
|
|
156
|
+
See [docs/openlayers.md](docs/openlayers.md).
|
|
157
|
+
|
|
158
|
+
## Cesium Usage
|
|
159
|
+
|
|
160
|
+
Use `@map-zero/cesium` to add exported 3D Tiles to an existing Cesium viewer:
|
|
161
|
+
|
|
162
|
+
```js
|
|
163
|
+
import { Viewer } from 'cesium';
|
|
164
|
+
import { addMapZeroToCesium } from '@map-zero/cesium';
|
|
165
|
+
|
|
166
|
+
const viewer = new Viewer('cesiumContainer');
|
|
167
|
+
|
|
168
|
+
const controller = await addMapZeroToCesium(viewer, {
|
|
169
|
+
id: 'huelva',
|
|
170
|
+
manifestUrl: './huelva.mapzero/manifest.json',
|
|
171
|
+
style: 'cesium'
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
controller.setOpacity('buildings', 0.8);
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
The helper does not take over your Cesium scene. Lighting, terrain, atmosphere, fog, and background remain under application control unless you explicitly opt into map-zero scene defaults.
|
|
178
|
+
|
|
179
|
+
See [docs/cesium.md](docs/cesium.md).
|
|
180
|
+
|
|
181
|
+
## Styles And Themes
|
|
182
|
+
|
|
183
|
+
Apply a bundled preset:
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
node src/cli.js style ./madrid.mapzero --preset neon-dark
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Apply a compact theme:
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
node src/cli.js style ./madrid.mapzero --theme neon-dark
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Most users should edit compact theme JSON instead of full renderer-ready style presets.
|
|
196
|
+
|
|
197
|
+
See [docs/styles.md](docs/styles.md) and [docs/cartography.md](docs/cartography.md).
|
|
198
|
+
|
|
199
|
+
## Documentation
|
|
200
|
+
|
|
201
|
+
- [Architecture](docs/architecture.md)
|
|
202
|
+
- [Styles and themes](docs/styles.md)
|
|
203
|
+
- [Cartography and POIs](docs/cartography.md)
|
|
204
|
+
- [OpenLayers integration](docs/openlayers.md)
|
|
205
|
+
- [Cesium integration](docs/cesium.md)
|
|
206
|
+
- [HTTP API](docs/api.md)
|
|
207
|
+
|
|
208
|
+
## Current Limitations
|
|
209
|
+
|
|
210
|
+
- Early alpha package format and APIs
|
|
211
|
+
- Readonly packages; editing OSM data is not supported
|
|
212
|
+
- Labels are available in the OpenLayers path but are still limited
|
|
213
|
+
- PMTiles export is supported; MBTiles export is not
|
|
214
|
+
- Cesium export is focused on extruded buildings and flat cartographic context layers
|
|
215
|
+
- 3D Tiles labels, terrain clamping, advanced metadata, and regional LOD optimization are still future work
|
|
216
|
+
- The built-in viewers still load OpenLayers/Cesium from public CDNs, although map data and PMTiles dependencies are local
|
|
217
|
+
|
|
218
|
+
## License
|
|
219
|
+
|
|
220
|
+
MIT
|
package/docs/api.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# HTTP API
|
|
2
|
+
|
|
3
|
+
`map-zero serve` starts a readonly local server for one `.mapzero` package.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
node src/cli.js serve ./madrid.mapzero --port 8080 --open
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
The HTTP API is only required for dynamic GeoPackage-backed serving and local inspection. If you export `tiles.pmtiles` or `3dtiles/`, those artifacts can be served as static files without the map-zero Node server.
|
|
10
|
+
|
|
11
|
+
## Viewer Routes
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
GET /
|
|
15
|
+
GET /cesium
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Package Routes
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
GET /manifest.json
|
|
22
|
+
GET /styles/:name
|
|
23
|
+
GET /tiles.pmtiles
|
|
24
|
+
GET /3dtiles/:layer/tileset.json
|
|
25
|
+
GET /3dtiles/:layer/tiles/:tile.b3dm
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`tiles.pmtiles` is served with range request support.
|
|
29
|
+
|
|
30
|
+
## Metadata Routes
|
|
31
|
+
|
|
32
|
+
```text
|
|
33
|
+
GET /api/info
|
|
34
|
+
GET /api/layers
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Examples:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
curl http://127.0.0.1:8080/api/info
|
|
41
|
+
curl http://127.0.0.1:8080/api/layers
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Dynamic MVT Routes
|
|
45
|
+
|
|
46
|
+
Combined layers:
|
|
47
|
+
|
|
48
|
+
```text
|
|
49
|
+
GET /api/tiles/:z/:x/:y.mvt?layers=roads,water
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Single layer:
|
|
53
|
+
|
|
54
|
+
```text
|
|
55
|
+
GET /api/tiles/:layer/:z/:x/:y.mvt
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Example:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
curl 'http://127.0.0.1:8080/api/tiles/14/8030/6165.mvt?layers=roads,water'
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The dynamic tile path validates layers against the package manifest and uses the same MVT generation logic as PMTiles export.
|
|
65
|
+
|
|
66
|
+
`aip` is the canonical aeronautical/AIP layer name. `aviation` remains accepted as a compatibility alias for older packages.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
`map-zero` separates the data pipeline from the rendering helpers:
|
|
4
|
+
|
|
5
|
+
- OSM PBF is parsed into a normalized GeoPackage.
|
|
6
|
+
- Dynamic MVT, PMTiles export, and 3D Tiles export read from that GeoPackage.
|
|
7
|
+
- Styles live outside the GeoPackage as JSON.
|
|
8
|
+
- OpenLayers and Cesium helpers add map-zero packages to existing viewers without owning the application.
|
|
9
|
+
|
|
10
|
+
## Core Pipeline
|
|
11
|
+
|
|
12
|
+
- `src/cli.js`: command wiring, argument parsing, terminal progress output.
|
|
13
|
+
- `src/build.js`: package build orchestration and output folder creation.
|
|
14
|
+
- `src/osm.js`: streamed OSM PBF scan, temporary SQLite build store, geometry extraction.
|
|
15
|
+
- `src/layers.js`: logical layer definitions, OSM tag matching, layer property normalization.
|
|
16
|
+
- `src/gpkg.js`: GeoPackage creation and incremental feature writes.
|
|
17
|
+
- `src/gpkg-read.js`: readonly GeoPackage metadata and tile feature queries.
|
|
18
|
+
- `src/geometry-read.js`: GeoPackage binary geometry decoding.
|
|
19
|
+
|
|
20
|
+
## 2D Tile Pipeline
|
|
21
|
+
|
|
22
|
+
- `src/mvt.js`: shared MVT generation, server-side filtering, detail policy, generalization.
|
|
23
|
+
- `src/server.js`: readonly Fastify API, dynamic MVT routes, cache and viewer assets.
|
|
24
|
+
- `src/tile-cache.js`: in-memory LRU cache and in-flight tile request coalescing support.
|
|
25
|
+
- `src/export-pmtiles.js`: PMTiles export orchestration and progress.
|
|
26
|
+
- `src/pmtiles-worker.js`: worker-thread tile generation for PMTiles export.
|
|
27
|
+
- `src/pmtiles.js`: PMTiles archive writer utilities.
|
|
28
|
+
|
|
29
|
+
Dynamic serving and PMTiles export both call the same `src/mvt.js` tile generation functions.
|
|
30
|
+
|
|
31
|
+
## 3D Tiles Pipeline
|
|
32
|
+
|
|
33
|
+
- `src/3dtiles/export.js`: 3D Tiles export orchestration.
|
|
34
|
+
- `src/3dtiles/gpkg-buildings.js`: readonly building queries and height extraction.
|
|
35
|
+
- `src/3dtiles/gpkg-features.js`: readonly feature queries for non-building layers.
|
|
36
|
+
- `src/3dtiles/extrude.js`: building footprint extrusion.
|
|
37
|
+
- `src/3dtiles/clipper-surfaces.js`: buffered/dissolved line surfaces for cartographic layers.
|
|
38
|
+
- `src/3dtiles/flat.js`: flat polygon and point-derived surfaces.
|
|
39
|
+
- `src/3dtiles/glb.js`: minimal unlit GLB generation.
|
|
40
|
+
- `src/3dtiles/b3dm.js`: B3DM wrapper.
|
|
41
|
+
- `src/3dtiles/tileset.js`: tileset JSON generation.
|
|
42
|
+
|
|
43
|
+
The Cesium export currently favors top-down cartographic fidelity over street-level realism. Roads and other line layers are converted to flat surfaces rather than GPU-only line primitives so the output is portable 3D Tiles geometry.
|
|
44
|
+
|
|
45
|
+
## Style And Rendering
|
|
46
|
+
|
|
47
|
+
- `src/style-presets.js`: full preset loading and layer filtering.
|
|
48
|
+
- `src/style-themes.js`: compact theme expansion into full style JSON.
|
|
49
|
+
- `src/style.js`: compatibility re-export for style APIs.
|
|
50
|
+
- `src/style-command.js`: `map-zero style` command implementation.
|
|
51
|
+
- `styles/presets/*.json`: full renderer-ready style presets.
|
|
52
|
+
- `styles/themes/*.theme.json`: compact user-editable themes.
|
|
53
|
+
- `packages/ol/src/index.js`: framework-agnostic OpenLayers layer helper.
|
|
54
|
+
- `packages/ol/src/labels.js`: optional OpenLayers text label layer.
|
|
55
|
+
- `packages/cesium/src/index.js`: framework-agnostic Cesium helper.
|
|
56
|
+
- `src/html.js`: built-in OpenLayers and Cesium viewer shells.
|
|
57
|
+
|
|
58
|
+
## Package Layout
|
|
59
|
+
|
|
60
|
+
```text
|
|
61
|
+
example.mapzero/
|
|
62
|
+
data.gpkg
|
|
63
|
+
manifest.json
|
|
64
|
+
tiles.pmtiles
|
|
65
|
+
3dtiles/
|
|
66
|
+
styles/
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`data.gpkg` is the source of truth after build. PMTiles and 3D Tiles can be regenerated from it without rebuilding from OSM.
|
|
70
|
+
|
|
71
|
+
## Serving Modes
|
|
72
|
+
|
|
73
|
+
`map-zero` supports two deployment models:
|
|
74
|
+
|
|
75
|
+
- **Dynamic local server**: Node reads `data.gpkg` and generates MVT on demand.
|
|
76
|
+
- **Static/serverless hosting**: exported `tiles.pmtiles` and `3dtiles/` are served as static files.
|
|
77
|
+
|
|
78
|
+
PMTiles and 3D Tiles do not require a map-zero runtime server after export. The local server remains useful for inspection, development, and dynamic GeoPackage-backed tiles.
|
|
79
|
+
|
|
80
|
+
## Refactor Notes
|
|
81
|
+
|
|
82
|
+
- `src/mvt.js`: tile filtering, generalization and encoding are still coupled. A future refactor can split query filters, generalization and MVT encoding.
|
|
83
|
+
- `src/osm.js`: streamed parser and disk-backed build pipeline are coupled. A future refactor can split temp-store access and geometry builders.
|
|
84
|
+
- `src/export-pmtiles.js`: export planning, worker scheduling and PMTiles staging are coupled. A future refactor can split estimation/progress from worker orchestration.
|
|
85
|
+
- `packages/ol/src/index.js`: source creation, style interpretation and layer creation are coupled. A future refactor can split source adapters from WebGL style generation.
|
|
86
|
+
|
|
87
|
+
These are implementation notes, not public API.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Cartography
|
|
2
|
+
|
|
3
|
+
`map-zero` currently ships with tactical/neon-oriented styles. The defaults prioritize infrastructure and operational context over consumer map content.
|
|
4
|
+
|
|
5
|
+
## Roads
|
|
6
|
+
|
|
7
|
+
Road styling uses `highway=*` plus related properties such as `bridge`, `tunnel`, `layer`, `service`, and `access`.
|
|
8
|
+
|
|
9
|
+
The default 2D style uses:
|
|
10
|
+
|
|
11
|
+
- mostly uniform road widths
|
|
12
|
+
- opaque casing/body strokes
|
|
13
|
+
- hierarchy through color, brightness, min zoom, and subtle casing differences
|
|
14
|
+
- limited major road labels
|
|
15
|
+
|
|
16
|
+
This keeps roads visually connected without topology merging.
|
|
17
|
+
|
|
18
|
+
## Labels
|
|
19
|
+
|
|
20
|
+
OpenLayers labels are optional and sparse by default:
|
|
21
|
+
|
|
22
|
+
- major road refs
|
|
23
|
+
- AIP/aeronautical names/refs
|
|
24
|
+
- selected operational POIs
|
|
25
|
+
|
|
26
|
+
Local street labels are disabled by default. Labels are filtered to avoid raw OSM taxonomy values such as `yes`, `generator`, `tower`, `pharmacy`, or `fuel` appearing as text.
|
|
27
|
+
|
|
28
|
+
## POI Categories
|
|
29
|
+
|
|
30
|
+
The default presets treat POIs as operational infrastructure rather than a consumer city guide.
|
|
31
|
+
|
|
32
|
+
Visible categories include:
|
|
33
|
+
|
|
34
|
+
- `transport`: rail, subway, bus, ferry, airport, fuel/charging infrastructure
|
|
35
|
+
- `emergency`: hospitals, clinics, police, fire stations, shelters
|
|
36
|
+
- `government`: town halls, courts, prisons, embassies, government offices
|
|
37
|
+
- `energy`: power plants, substations, generators, towers, transformers, lines
|
|
38
|
+
- `communications`: communications towers, masts, antennas, radar-style infrastructure
|
|
39
|
+
- `protected`: protected areas, nature reserves, national parks
|
|
40
|
+
- `industrial`: industrial, logistics, refinery, depot, storage infrastructure
|
|
41
|
+
- `military`: military-tagged sites, bunkers, barracks, checkpoints, airbases, naval bases
|
|
42
|
+
|
|
43
|
+
Hidden by default:
|
|
44
|
+
|
|
45
|
+
- restaurants, cafes, bars, pubs
|
|
46
|
+
- shops and generic commercial POIs
|
|
47
|
+
- hotels, attractions, generic tourism
|
|
48
|
+
- generic leisure and entertainment
|
|
49
|
+
|
|
50
|
+
Dynamic MVT serving applies POI category filtering before encoding. PMTiles exports use the same rules.
|
|
51
|
+
|
|
52
|
+
## AIP / Aeronautical Data
|
|
53
|
+
|
|
54
|
+
The `aip` layer extracts OSM `aeroway=*` nodes, ways, and simple polygon relations. It preserves:
|
|
55
|
+
|
|
56
|
+
- `id`
|
|
57
|
+
- `name`
|
|
58
|
+
- `aeroway`
|
|
59
|
+
- `ref`
|
|
60
|
+
- `surface`
|
|
61
|
+
- `width`
|
|
62
|
+
- `length`
|
|
63
|
+
|
|
64
|
+
Runways, taxiways, aprons, terminals, aerodromes, launchpads, and helipads are represented when present in OSM. Some OSM data lacks physical width tags; 3D export uses class-based fallback widths in those cases.
|
|
65
|
+
|
|
66
|
+
Dense operational point classes such as navigation aids, gates, thresholds, windsocks, and towers are hidden by default in the 2D style to avoid clutter.
|
|
67
|
+
|
|
68
|
+
`aviation` is still accepted as a compatibility alias for older packages and commands. The public layer name is now `aip`, which leaves room to merge richer aeronautical sources such as ARINC424-derived data into the same domain later.
|
|
69
|
+
|
|
70
|
+
## Boundaries
|
|
71
|
+
|
|
72
|
+
Boundary styling uses `admin_level` where available:
|
|
73
|
+
|
|
74
|
+
- national and regional boundaries are stronger
|
|
75
|
+
- local boundaries are subtle
|
|
76
|
+
|
|
77
|
+
In Cesium, boundaries are exported as flat contour surfaces rather than filled administrative polygons.
|
package/docs/cesium.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Cesium Integration
|
|
2
|
+
|
|
3
|
+
The Cesium helper adds exported 3D Tiles to an existing Cesium viewer. It does not create or own the viewer.
|
|
4
|
+
|
|
5
|
+
```js
|
|
6
|
+
import { Viewer } from 'cesium';
|
|
7
|
+
import { addMapZeroToCesium } from '@map-zero/cesium';
|
|
8
|
+
|
|
9
|
+
const viewer = new Viewer('cesiumContainer');
|
|
10
|
+
|
|
11
|
+
const controller = await addMapZeroToCesium(viewer, {
|
|
12
|
+
id: 'huelva',
|
|
13
|
+
manifestUrl: './huelva.mapzero/manifest.json',
|
|
14
|
+
style: 'cesium'
|
|
15
|
+
});
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Export 3D Tiles
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
node src/cli.js 3dtiles ./huelva.mapzero
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
By default, the exporter writes all supported 3D layers:
|
|
25
|
+
|
|
26
|
+
- `buildings`
|
|
27
|
+
- `landuse`
|
|
28
|
+
- `water`
|
|
29
|
+
- `aip`
|
|
30
|
+
- `railways`
|
|
31
|
+
- `roads`
|
|
32
|
+
- `boundaries`
|
|
33
|
+
|
|
34
|
+
Use `--layers` for a smaller export:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
node src/cli.js 3dtiles ./huelva.mapzero --layers buildings,roads
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Buildings are extruded. Heights use `height`, then `building:levels * 3`, then the configured default height.
|
|
41
|
+
|
|
42
|
+
Non-building layers are exported as flat cartographic meshes:
|
|
43
|
+
|
|
44
|
+
- roads, railways, and boundaries become buffered/dissolved line surfaces
|
|
45
|
+
- landuse, water, and AIP/aeronautical polygons become flat indexed surfaces
|
|
46
|
+
- AIP points such as helipads can become small flat markers
|
|
47
|
+
|
|
48
|
+
## Scene Configuration
|
|
49
|
+
|
|
50
|
+
The helper does not change global Cesium scene settings by default. Applications control terrain, fog, atmosphere, lighting, and background.
|
|
51
|
+
|
|
52
|
+
Optional tactical defaults:
|
|
53
|
+
|
|
54
|
+
```js
|
|
55
|
+
await addMapZeroToCesium(viewer, {
|
|
56
|
+
manifestUrl: './huelva.mapzero/manifest.json',
|
|
57
|
+
style: 'cesium',
|
|
58
|
+
applyDefaultSceneStyle: true
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
You can also provide your own scene hook:
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
await addMapZeroToCesium(viewer, {
|
|
66
|
+
manifestUrl: './huelva.mapzero/manifest.json',
|
|
67
|
+
configureScene(viewer) {
|
|
68
|
+
viewer.scene.fog.enabled = false;
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Multiple Packages
|
|
74
|
+
|
|
75
|
+
```js
|
|
76
|
+
const madrid = await addMapZeroToCesium(viewer, {
|
|
77
|
+
id: 'madrid',
|
|
78
|
+
manifestUrl: './madrid.mapzero/manifest.json'
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const huelva = await addMapZeroToCesium(viewer, {
|
|
82
|
+
id: 'huelva',
|
|
83
|
+
manifestUrl: './huelva.mapzero/manifest.json'
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
madrid.setVisible('buildings', false);
|
|
87
|
+
huelva.destroy();
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Each controller owns only its package primitives.
|
|
91
|
+
|
|
92
|
+
## Controller
|
|
93
|
+
|
|
94
|
+
```js
|
|
95
|
+
controller.setVisible('buildings', true);
|
|
96
|
+
controller.setOpacity('buildings', 0.7);
|
|
97
|
+
controller.destroy();
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The module exports:
|
|
101
|
+
|
|
102
|
+
- `loadMapZeroManifest`
|
|
103
|
+
- `loadMapZeroStyle`
|
|
104
|
+
- `createMapZeroCesiumTilesets`
|
|
105
|
+
- `addMapZeroToCesium`
|
|
106
|
+
- `applyMapZeroCesiumSceneStyle`
|
|
107
|
+
- `createMapZeroCesiumStyle`
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# OpenLayers Integration
|
|
2
|
+
|
|
3
|
+
The OpenLayers helper adds a map-zero package to an existing map. It does not create or own the map.
|
|
4
|
+
|
|
5
|
+
```js
|
|
6
|
+
import Map from 'ol/Map.js';
|
|
7
|
+
import View from 'ol/View.js';
|
|
8
|
+
import { addMapZeroToOpenLayers } from '@map-zero/ol';
|
|
9
|
+
|
|
10
|
+
const map = new Map({
|
|
11
|
+
target: 'map',
|
|
12
|
+
layers: [],
|
|
13
|
+
view: new View({ center: [0, 0], zoom: 12 })
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const controller = await addMapZeroToOpenLayers(map, {
|
|
17
|
+
id: 'madrid',
|
|
18
|
+
manifestUrl: './madrid.mapzero/manifest.json'
|
|
19
|
+
});
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Sources
|
|
23
|
+
|
|
24
|
+
The helper supports:
|
|
25
|
+
|
|
26
|
+
- PMTiles vector MVT when `manifest.tiles.format === "pmtiles"`
|
|
27
|
+
- dynamic MVT from the map-zero server otherwise
|
|
28
|
+
|
|
29
|
+
You can force a source mode:
|
|
30
|
+
|
|
31
|
+
```js
|
|
32
|
+
await addMapZeroToOpenLayers(map, {
|
|
33
|
+
manifestUrl: './madrid.mapzero/manifest.json',
|
|
34
|
+
source: 'pmtiles' // 'auto', 'pmtiles', or 'dynamic'
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Multiple Packages
|
|
39
|
+
|
|
40
|
+
Each call creates an isolated package instance:
|
|
41
|
+
|
|
42
|
+
```js
|
|
43
|
+
const madrid = await addMapZeroToOpenLayers(map, {
|
|
44
|
+
id: 'madrid',
|
|
45
|
+
manifestUrl: './madrid.mapzero/manifest.json',
|
|
46
|
+
zIndexBase: 1000
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const huelva = await addMapZeroToOpenLayers(map, {
|
|
50
|
+
id: 'huelva',
|
|
51
|
+
manifestUrl: './huelva.mapzero/manifest.json',
|
|
52
|
+
zIndexBase: 2000
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
madrid.setVisible('roads', false);
|
|
56
|
+
huelva.destroy();
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Internal layer ids are namespaced by instance. The public controller still uses logical layer ids.
|
|
60
|
+
|
|
61
|
+
## Shared Styles
|
|
62
|
+
|
|
63
|
+
Style objects can be loaded once and reused:
|
|
64
|
+
|
|
65
|
+
```js
|
|
66
|
+
import { loadMapZeroStyle } from '@map-zero/ol';
|
|
67
|
+
|
|
68
|
+
const style = await loadMapZeroStyle('./styles/neon-dark.json');
|
|
69
|
+
|
|
70
|
+
await addMapZeroToOpenLayers(map, {
|
|
71
|
+
id: 'madrid',
|
|
72
|
+
manifestUrl: './madrid.mapzero/manifest.json',
|
|
73
|
+
style
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
await addMapZeroToOpenLayers(map, {
|
|
77
|
+
id: 'huelva',
|
|
78
|
+
manifestUrl: './huelva.mapzero/manifest.json',
|
|
79
|
+
style
|
|
80
|
+
});
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Shared style objects are treated as readonly.
|
|
84
|
+
|
|
85
|
+
## Controller
|
|
86
|
+
|
|
87
|
+
```js
|
|
88
|
+
controller.setVisible('buildings', false);
|
|
89
|
+
controller.setOpacity('roads', 0.8);
|
|
90
|
+
controller.destroy();
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The module exports:
|
|
94
|
+
|
|
95
|
+
- `loadMapZeroManifest`
|
|
96
|
+
- `loadMapZeroStyle`
|
|
97
|
+
- `createMapZeroOpenLayersLayers`
|
|
98
|
+
- `addMapZeroToOpenLayers`
|