diff --git a/examples/get-started/pure-js/arcgis-globe/README.md b/examples/get-started/pure-js/arcgis-globe/README.md new file mode 100644 index 000000000000..990fb9d141f0 --- /dev/null +++ b/examples/get-started/pure-js/arcgis-globe/README.md @@ -0,0 +1,23 @@ +
+ +
+ +## 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. diff --git a/examples/get-started/pure-js/arcgis-globe/app.js b/examples/get-started/pure-js/arcgis-globe/app.js new file mode 100644 index 000000000000..e999dc995350 --- /dev/null +++ b/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()] + }); + } +); diff --git a/examples/get-started/pure-js/arcgis-globe/index.html b/examples/get-started/pure-js/arcgis-globe/index.html new file mode 100644 index 000000000000..9a1dc6259e93 --- /dev/null +++ b/examples/get-started/pure-js/arcgis-globe/index.html @@ -0,0 +1,22 @@ + + + + + deck.gl w/ Esri ArcGIS API for JavaScript example + + + + +
+ + + diff --git a/examples/get-started/pure-js/arcgis-globe/package.json b/examples/get-started/pure-js/arcgis-globe/package.json new file mode 100644 index 000000000000..927748ad2883 --- /dev/null +++ b/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" + } +} diff --git a/examples/get-started/pure-js/arcgis-globe/webpack.config.js b/examples/get-started/pure-js/arcgis-globe/webpack.config.js new file mode 100644 index 000000000000..0bacc22fac40 --- /dev/null +++ b/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); diff --git a/modules/arcgis/src/deck-renderer.js b/modules/arcgis/src/deck-renderer.js index 5bd62b59f602..8d1679421868 100644 --- a/modules/arcgis/src/deck-renderer.js +++ b/modules/arcgis/src/deck-renderer.js @@ -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); @@ -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 }); } }