Skip to content
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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions examples/get-started/pure-js/maplibre-globe/README.md
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)
62 changes: 62 additions & 0 deletions examples/get-started/pure-js/maplibre-globe/app.js
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';
Copy link
Collaborator

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

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());
});
20 changes: 20 additions & 0 deletions examples/get-started/pure-js/maplibre-globe/index.html
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>
20 changes: 20 additions & 0 deletions examples/get-started/pure-js/maplibre-globe/package.json
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"
}
}
11 changes: 8 additions & 3 deletions modules/core/src/viewports/globe-viewport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit nervous about having these overrides, especially as nearZ and nearZMultiplier do the same thing. Should we issue a warning if both are supplied?

Copy link
Collaborator

Choose a reason for hiding this comment

The 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).

Copy link
Collaborator

Choose a reason for hiding this comment

The 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.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ibgreen FWIW I was not changing them in my PR, that was just due to github getting confused. See updated PR

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;
};
Expand Down Expand Up @@ -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]});
Expand All @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions modules/core/src/views/globe-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ export type GlobeViewState = {
minZoom?: number;
/** Max zoom, default `20` */
maxZoom?: number;
/** The near plane position */
nearZ?: number;
/** The far plane position */
farZ?: number;
} & CommonViewState;

export type GlobeViewProps = {
Expand Down
4 changes: 4 additions & 0 deletions modules/core/src/views/map-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ export type MapViewState = {
maxPitch?: number;
/** Viewport center offsets from lng, lat in meters */
position?: number[];
/** The near plane position */
nearZ?: number;
/** The far plane position */
farZ?: number;
} & CommonViewState;

export type MapViewProps = {
Expand Down
Loading
Loading