OpenLayers + deck.gl

by felixp

HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>OpenLayers + deck.gl</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/ol.css">
  </head>
  <body>
    <div id="map" class="map"></div>
    <script src="https://unpkg.com/[email protected]/dist/elm-pep.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/ol.js"></script>
   <script src="https://unpkg.com/[email protected]/dist.min.js"></script>
   <script src="https://unpkg.com/@deck.gl/[email protected]/dist.min.js"></script>
  </body>
</html>

CSS

body {
  margin: 0;
}

.map {
  position: absolute;
  width: 100%;
  height: 100%;
  font-size: medium;
}

JavaScript

// Example of basemap rendered using Openlayers with deck.gl overlay

// Datasource: Natural Earth http://www.naturalearthdata.com/ via geojson.xyz
const AIR_PORTS =
  'https://gist.githubusercontent.com/klokan/2decd22216fa98ab1a259119084866be/raw/dad9197761541083371fb41038394a8e5e21264a/ne_10m_airports.geojson';

// deck.gl layers to display
const layers = [
  new deck.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})`)
  }),
  new deck.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
  })
];

// Create deck instance
const deckGL = new deck.Deck({
  initialViewState: {
    longitude: 0,
    latitude: 0,
    zoom: 1
  },
  controller: false,
  parent: document.getElementById('map'),
  style: {
    pointerEvents: 'none',
    'z-index': 1
  },
  layers
});

// Sync deck view with OL view
const deckLayer = new ol.layer.Layer({
  render: function({
    size,
    viewState
  }) {
    const [width, height] = size;
    const [longitude, latitude] = ol.proj.toLonLat(viewState.center);
    const zoom = viewState.zoom - 1;
    const bearing = (-viewState.rotation * 180) / Math.PI;
    const deckViewState = {
      bearing,
      longitude,
      latitude,
      zoom
    };
    deckGL.setProps({
      width,
      height,
      viewState: deckViewState
    });
    deckGL.redraw();
  }
});

//...