View on GitHub

leaflet-city-mapper

A small 3D rendering engine for leaflet

leaflet-city-mapper

NPM version License

Your data, on a rotated and pitched Leaflet map: a small 3D rendering engine (WebGPU) packaged onto standard L.Layer. Available sources: extruded GeoJSON, glTF models, raster PMTiles and terrain layers.

Leaflet 3D City Mapper

For a working example see one of the following demos:

How to use

Load Leaflet (the only runtime dependency), then this plugin:

<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9/dist/leaflet.css">
<script src="https://unpkg.com/leaflet@1.9/dist/leaflet.js"></script>
<script src="https://unpkg.com/leaflet-city-mapper@0.0.3/dist/leaflet-city-mapper.js"></script>

And then set an approriate source param to layer constructor:

new L.Layer({ source: .. })

For example, here you can use a geojson object, like this:

const buildings = new L.Layer({
  source: {
    type: 'geojson',
    url: GeoJSON,
    style: ({ properties }) => ({ top: properties.height, color: properties.color }),
    tooltip: ({ properties }) => `${properties.name}: ${properties.height} m`,
  },
}).addTo(map);

The build produces a single self-contained dist/leaflet-city-mapper.js bundle; Leaflet remains an external dependency. Vector/raster and feature initializers run on demand, while shared scene, rendering, geometry, glTF and PMTiles source lives in focused folders under src/.

Raster imagery blends coarse-to-fine on the terrain, retaining depth occlusion for 3D objects.

Time and walk controls

const time = new L.Control.Time({ position: 'bottomright' });
new L.Control.Layers({}, { Shadows: time.layer.addTo(map) }).addTo(map);
const walk = new L.Control.Walk({ speed: 6, distance: 20 }).addTo(map);

Time stays under Shadows in the layers control; its checkbox enables/disables the clock, sky and shadows together. Use time.addTo(map) instead for a standalone control. time.time and time.live expose the selected UTC time and live mode. Walk exposes walk.walker (latlng, heading, phase); W/S move, A/D turn, drag looks around and Esc exits. Both controls support remove() and re-adding. These replace the former sunlight and walk layer source types.

Update demo data

The Paris example makes extensive use of PMTiles to ensure offline access / long-term availability of the map. To update them:

npm run pmtiles
node build/pmtiles.js --only=trees
node build/pmtiles.js --jobs=6

All archives use the buildings bbox (default: 2.26,48.835,2.38,48.885). Use --bbox=west,south,east,north to override it.

Build Guide

Within your local development environment:

git clone git@github.com:Raruto/leaflet-city-mapper.git
cd ./leaflet-city-mapper

npm i         # install dependencies
npm run dev   # start dev server at: http://localhost:8080
npm run build # generate "dist" files (once)
npm run test  # build and run browser tests

After that you can start developing inside the src folder (eg. open “http://localhost:8080/examples” in your browser to preview changes).

Source layout

src/
  index.js           Public entry point and source registration
  constants/         Exported module-level const bindings
  camera/            Camera API, projection and animation
  controls/          Compass, dragging, touch and resizing
  core/              Leaflet layer integration, events, mutations and overlays
  scene/             Source routing, lifecycle, graph nodes and transforms
  sources/           GeoJSON and streamed source geometry
  picking/           Raycasting, highlighting and feature interaction
  rendering/         Frame stages, roof atlases, pipelines, meshes and textures
  shadows/           Directional shadow maps, bounds and cache
  lighting/          Point lights and spatial light grids
  shaders/           Material shader generation
  geometry/          Trees, lights, bridges, primitives and Leaflet vector geometry
  triangulation/     Polygon triangulation and ring operations
  collision/         Mesh intersection and collision queries
  models/            glTF loading, decoding and materials
  archives/          PMTiles archive reading and decompression
  raster/            Raster tile loading, attachment and lifecycle
  traffic/           Routes, scheduling, simulation, loading and rendering
  vehicles/          Vehicle model geometry
  terrain/           Terrain loading and sampling
  sunlight/          Sun, moon, sky and time controls
  walk/              First-person walking
  utils/             Shared colour and numeric helpers

Compatibile with: Leaflet 1.9.4 compatible! Leaflet 2.x compatible!