Skip to content

Commit

Permalink
Support ArcGIS globe
Browse files Browse the repository at this point in the history
  • Loading branch information
zakjan committed Jul 1, 2021
1 parent 33c1309 commit e423ea5
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 6 deletions.
23 changes: 23 additions & 0 deletions examples/get-started/pure-js/arcgis-globe/README.md
@@ -0,0 +1,23 @@
<div align="center">
<img width="150" heigth="150" src="https://webpack.js.org/assets/icon-square-big.svg" />
</div>

## Example: Use deck.gl with Esri ArcGIS API for JavaScript

This sample shows how to use the `@deck.gl/arcgis` module to add a deck.gl layer to an [ArcGIS JavaScript](https://developers.arcgis.com/javascript/) app.
Uses [Webpack](https://github.com/webpack/webpack) and the [ArcGIS Webpack plugin](https://github.com/Esri/arcgis-webpack-plugin)
to bundle files and serves it with [webpack-dev-server](https://webpack.js.org/guides/development/#webpack-dev-server).

## 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.
78 changes: 78 additions & 0 deletions examples/get-started/pure-js/arcgis-globe/app.js
@@ -0,0 +1,78 @@
import {loadArcGISModules} from '@deck.gl/arcgis';
import {GeoJsonLayer, ArcLayer} from '@deck.gl/layers';
import {_GlobeView as GlobeView} from '@deck.gl/core';

// 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';

loadArcGISModules(['esri/Map', 'esri/views/SceneView', 'esri/views/3d/externalRenderers']).then(
({DeckRenderer, modules}) => {
const [ArcGISMap, SceneView, externalRenderers] = modules;

// In the ArcGIS API for JavaScript the SceneView is responsible
// for displaying a Map, which usually contains at least a basemap.
// eslint-disable-next-line
const sceneView = new SceneView({
container: 'viewDiv',
map: new ArcGISMap({
basemap: 'dark-gray-vector',
layers: []
}),
center: [0.119167, 52.205276],
zoom: 5,
// disable sun
environment: {
lighting: {
date: new Date('null')
}
}
});

const renderer = new DeckRenderer(sceneView, {
getTooltip: info => info.object && info.object.properties.name,
layers: [
new GeoJsonLayer({
id: 'airports',
data: AIR_PORTS,
// Styles
filled: true,
pointRadiusMinPixels: 2,
pointRadiusScale: 2000,
getRadius: f => 11 - f.properties.scalerank,
getFillColor: [200, 0, 80, 180],
// Interactive props
pickable: true,
autoHighlight: true,
onClick: info =>
info.object &&
// eslint-disable-next-line
alert(`${info.object.properties.name} (${info.object.properties.abbrev})`)
}),
new ArcLayer({
id: 'arcs',
data: AIR_PORTS,
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
}),
new GeoJsonLayer({
id: 'land',
data: 'https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_50m_land.geojson',
filled: false,
getLineColor: [255, 255, 255, 127],
getLineWidth: 1,
lineWidthUnits: 'pixels'
})
]
});
externalRenderers.add(sceneView, renderer);
renderer.deckInstance.setProps({
views: [new GlobeView()]
});
}
);
22 changes: 22 additions & 0 deletions examples/get-started/pure-js/arcgis-globe/index.html
@@ -0,0 +1,22 @@
<!doctype html>
<html>
<head>
<meta charset='UTF-8' />
<title>deck.gl w/ Esri ArcGIS API for JavaScript example</title>
<link rel="stylesheet" href="https://js.arcgis.com/4.14/esri/themes/light/main.css"/>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="viewDiv"></div>
<script src='app.js'></script>
</body>
</html>
20 changes: 20 additions & 0 deletions examples/get-started/pure-js/arcgis-globe/package.json
@@ -0,0 +1,20 @@
{
"name": "pure-js-esri-arcgis-globe",
"version": "0.0.0",
"license": "MIT",
"scripts": {
"start": "webpack-dev-server --progress --hot --open",
"start-local": "webpack-dev-server --env.local --progress --hot --open",
"build": "webpack -p"
},
"dependencies": {
"@deck.gl/arcgis": "^8.1.0",
"@deck.gl/core": "^8.1.0",
"@deck.gl/layers": "^8.1.0"
},
"devDependencies": {
"webpack": "^4.20.2",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.1"
}
}
13 changes: 13 additions & 0 deletions examples/get-started/pure-js/arcgis-globe/webpack.config.js
@@ -0,0 +1,13 @@
// NOTE: To use this example standalone (e.g. outside of deck.gl repo)
// delete the local development overrides at the bottom of this file

const CONFIG = {
mode: 'development',

entry: {
app: './app.js'
}
};

// This line enables bundling against src in this repo rather than installed module
module.exports = env => (env ? require('../../../webpack.config.local')(CONFIG)(env) : CONFIG);
36 changes: 30 additions & 6 deletions modules/arcgis/src/deck-renderer.js
Expand Up @@ -2,6 +2,9 @@

import {initializeResources, render, finalizeResources} from './commons';

// ArcGIS Earth radius
const EARTH_RADIUS = 6378137;

// ArcGIS fov is corner-to-corner
function arcgisFOVToDeckAltitude(fov, aspectRatio) {
const D = Math.sqrt(1 + aspectRatio ** 2);
Expand Down Expand Up @@ -36,18 +39,39 @@ export default function createDeckRenderer(DeckProps, externalRenderers) {
render(context) {
const [width, height] = this.view.size;

render.call(this, {
gl: context.gl,
width,
height,
viewState: {
let viewState;
if (this.view.viewingMode === 'global') {
const altitude = this.view.camera.position.z / EARTH_RADIUS; // TODO
const zoom = EARTH_RADIUS / this.view.camera.position.z;
const zoom2 = Math.log2(zoom + 1); // TODO
console.log(this.view.camera.position.z, altitude, zoom, zoom2); // eslint-disable-line

viewState = {
latitude: this.view.center.latitude, // TODO: compute from this.view.camera.y, to support tilt?
longitude: this.view.center.longitude, // TODO: compute from this.view.camera.x, to support tilt?
altitude,
zoom: zoom2,
bearing: this.view.camera.heading,
pitch: this.view.camera.tilt
};
} else if (this.view.viewingMode === 'local') {
viewState = {
latitude: this.view.center.latitude,
longitude: this.view.center.longitude,
altitude: arcgisFOVToDeckAltitude(this.view.camera.fov, width / height),
zoom: this.view.zoom,
bearing: this.view.camera.heading,
pitch: this.view.camera.tilt
}
};
} else {
throw new Error('Invalid state');
}

render.call(this, {
gl: context.gl,
width,
height,
viewState
});
}
}
Expand Down

0 comments on commit e423ea5

Please sign in to comment.