-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(mapbox): support Maplibre globe projection #9296
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
## Example: Use deck.gl with Maplibre globe projection | ||
|
||
Uses [Vite](https://vitejs.dev/) to bundle and serve files. | ||
|
||
## Usage | ||
|
||
To install dependencies: | ||
|
||
```bash | ||
npm install | ||
# or | ||
yarn | ||
``` | ||
|
||
Commands: | ||
* `npm start` is the development target, to serve the app and hot reload. | ||
* `npm run build` is the production target, to create the final bundle and write to disk. | ||
|
||
### Basemap | ||
|
||
The basemap in this example is provided by [CARTO free basemap service](https://carto.com/basemaps). To use an alternative base map solution, visit [this guide](https://deck.gl/docs/get-started/using-with-map#using-other-basemap-services) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// deck.gl | ||
// SPDX-License-Identifier: MIT | ||
// Copyright (c) vis.gl contributors | ||
|
||
import {MapboxOverlay as DeckOverlay} from '@deck.gl/mapbox'; | ||
import {GeoJsonLayer, ArcLayer} from '@deck.gl/layers'; | ||
import maplibregl from 'maplibre-gl'; | ||
import 'maplibre-gl/dist/maplibre-gl.css'; | ||
|
||
// source: Natural Earth http://www.naturalearthdata.com/ via geojson.xyz | ||
const AIR_PORTS = | ||
'https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_10m_airports.geojson'; | ||
|
||
const map = new maplibregl.Map({ | ||
container: 'map', | ||
style: 'https://basemaps.cartocdn.com/gl/positron-gl-style/style.json', | ||
center: [0.45, 51.47], | ||
zoom: 0 | ||
}); | ||
|
||
const deckOverlay = new DeckOverlay({ | ||
interleaved: true, | ||
layers: [ | ||
new GeoJsonLayer({ | ||
id: 'airports', | ||
data: AIR_PORTS, | ||
// Styles | ||
filled: true, | ||
pointRadiusMinPixels: 2, | ||
pointRadiusScale: 2000, | ||
getPointRadius: f => 11 - f.properties.scalerank, | ||
getFillColor: [200, 0, 80, 180], | ||
// Interactive props | ||
pickable: true, | ||
autoHighlight: true, | ||
onClick: info => | ||
// eslint-disable-next-line | ||
info.object && alert(`${info.object.properties.name} (${info.object.properties.abbrev})`) | ||
// beforeId: 'watername_ocean' // In interleaved mode, render the layer under map labels | ||
}), | ||
new ArcLayer({ | ||
id: 'arcs', | ||
data: AIR_PORTS, | ||
parameters: { | ||
cullMode: 'none' | ||
}, | ||
dataTransform: d => d.features.filter(f => f.properties.scalerank < 4), | ||
// Styles | ||
getSourcePosition: f => [-0.4531566, 51.4709959], // London | ||
getTargetPosition: f => f.geometry.coordinates, | ||
getSourceColor: [0, 128, 200], | ||
getTargetColor: [200, 0, 80], | ||
getWidth: 1 | ||
}) | ||
] | ||
}); | ||
|
||
map.on('load', () => { | ||
map.setProjection({type: 'globe'}); | ||
map.addControl(deckOverlay); | ||
map.addControl(new maplibregl.NavigationControl()); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<!doctype html> | ||
<html> | ||
<head> | ||
<meta charset='UTF-8' /> | ||
<title>deck.gl example</title> | ||
<style> | ||
#map { | ||
position: fixed; | ||
top: 0; | ||
left: 0; | ||
right: 0; | ||
bottom: 0; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<div id="map"></div> | ||
<script type="module" src='app.js'></script> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
{ | ||
"name": "deckgl-example-pure-js-maplibre", | ||
"version": "0.0.0", | ||
"private": true, | ||
"license": "MIT", | ||
"scripts": { | ||
"start": "vite --open", | ||
"start-local": "vite --config ../../../vite.config.local.mjs", | ||
"build": "vite build" | ||
}, | ||
"dependencies": { | ||
"@deck.gl/core": "^9.0.0", | ||
"@deck.gl/layers": "^9.0.0", | ||
"@deck.gl/mapbox": "^9.0.0", | ||
"maplibre-gl": "5.0.0-pre.9" | ||
}, | ||
"devDependencies": { | ||
"vite": "^4.0.0" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -58,6 +58,10 @@ export type GlobeViewportOptions = { | |
nearZMultiplier?: number; | ||
/** Scaler for the far plane, 1 unit equals to the distance from the camera to the edge of the screen. Default `1` */ | ||
farZMultiplier?: number; | ||
/** Optionally override the near plane position. `nearZMultiplier` is ignored if `nearZ` is supplied. */ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A bit nervous about having these overrides, especially as There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree this can be confusing (and wasn't an easy thing to catch when I was first learning it). FWIW, web-mercator-viewport has had these same overrides for a long time. A warning would be nice.. the multipliers have defaults assigned, so we'd just need to assign those after checking the user-supplied values (or else, they'd always print). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This does look confusing and somewhat intimidating. I think these props were originally intended as a semi-undocumented escape hatch but now I seem to see these being "touched" in every PR... If not a coincidence, might be good to audit this API with an eye towards making it as fail proof as possible for new (and old) users. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
nearZ?: number; | ||
/** Optionally override the far plane position. `farZMultiplier` is ignored if `farZ` is supplied. */ | ||
farZ?: number; | ||
/** The resolution at which to turn flat features into 3D meshes, in degrees. Smaller numbers will generate more detailed mesh. Default `10` */ | ||
resolution?: number; | ||
}; | ||
|
@@ -94,7 +98,8 @@ export default class GlobeViewport extends Viewport { | |
// https://github.com/maplibre/maplibre-gl-js/blob/f8ab4b48d59ab8fe7b068b102538793bbdd4c848/src/geo/projection/globe_transform.ts#L575-L577 | ||
const scaleAdjust = 1 / Math.PI / Math.cos((latitude * Math.PI) / 180); | ||
const scale = Math.pow(2, zoom) * scaleAdjust; | ||
const farZ = altitude + (GLOBE_RADIUS * 2 * scale) / height; | ||
const nearZ = opts.nearZ ?? nearZMultiplier; | ||
const farZ = opts.farZ ?? (altitude + (GLOBE_RADIUS * 2 * scale) / height) * farZMultiplier; | ||
|
||
// Calculate view matrix | ||
const viewMatrix = new Matrix4().lookAt({eye: [0, -altitude, 0], up: [0, 0, 1]}); | ||
|
@@ -117,8 +122,8 @@ export default class GlobeViewport extends Viewport { | |
distanceScales: getDistanceScales(), | ||
fovy, | ||
focalDistance: altitude, | ||
near: nearZMultiplier, | ||
far: farZ * farZMultiplier | ||
near: nearZ, | ||
far: farZ | ||
}); | ||
|
||
this.scale = scale; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why rename/alias things? If we are not happy with the name, rename it at export? If trying to make code clearer a longer name might be needed? Any name that mentions either just Deck or Mapbox is going to be confusing