All versions of this documentation
X

Vector layers and GeoJSON

This demo shows how to add custom layers when in Geo mode and how to make the Ogma graph coordinate with such custom layers. In the demo below try to drag a node around the map and see the orange shapes gets updated.
GeoJSON Europe shape source: Github repo.
Note: Linkurious SAS makes no warranty, expressed or implied, as to the shapes borders obtained from the use of the GeoJSON on the website.

Open in a new window.
          <!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <link rel="stylesheet"
    href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.5.1/leaflet.css" />
  <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.5.1/leaflet.js">
  </script>
  <script src="https://unpkg.com/unfetch@4.1.0/dist/unfetch.umd.js"></script>
  <script
    src="https://unpkg.com/@mapbox/leaflet-pip@latest/leaflet-pip.js"></script>
  <script src="../build/ogma.min.js"></script>
  <style>
    html,
    body {
      margin: 0;
    }

    #graph-container {
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
      position: absolute;
      margin: 0;
      overflow: hidden;
    }
  </style>
</head>

<body>
  <div id="graph-container"></div>

  <script>
    'use strict';

    // This demo uses 2 external dependencies in addition to Leaflet and Ogma for the example code:
    // * leaflet-pip: a leaflet plugin to check if a point is within a GeoJSON shape
    // * lodash.debounce: a debounce function implementation
    // feel free to replace them with your custom ones if you need to

    Ogma.libraries['leaflet'] = L;

    let graph = {
      nodes: [
        {
          id: 'Station A',
          data: { latitude: 48.858838, longitude: 2.343436 },
          attributes: { radius: 10, text: 'Drag me!', x: 0, y: 0 }
        },
        {
          id: 'Station B',
          data: { latitude: 51.509615, longitude: -0.134514 },
          attributes: { radius: 10, text: 'Drag me!', x: 100, y: 0 }
        }
      ],
      edges: [
        {
          id: 'Eurostar',
          source: 'Station A',
          target: 'Station B',
          attributes: { width: 5, text: 'Eurostar' }
        }
      ]
    };

    let ogma = new Ogma({
      graph: graph,
      container: 'graph-container'
    });

    // this is the reference to the layer we're going to add to the leaflet map
    let countriesShapesLayer;

    // fetch the GeoJSON data
    function getGeoJSONData() {
      return ogma.fetch('files/eu-shapes.geojson').then(function (response) {
        return JSON.parse(response);
      });
    }

    function updateShapesVisibility(nodeList) {
      // for each node check if it's inside a country shape and return the country name
      let countries = nodeList.getGeoCoordinates().map(function (coords) {
        // list of country polygons that contain the provided node point
        let polygons = leafletPip.pointInLayer(
          L.latLng([coords.latitude, coords.longitude]),
          countriesShapesLayer,
          true
        );
        // just return the first one: countries do not overlap, the array is made of a single element.
        return polygons[0];
      });
      // now iterate through all country shapes in the layer and set the opacity
      countriesShapesLayer.getLayers().forEach(function (country) {
        let isInside = countries.indexOf(country) > -1;
        // play with
        country.setStyle({
          opacity: isInside ? 1 : 0,
          fillOpacity: isInside ? 0.2 : 0
        });
      });
    }
    // Enable Geo mode making the nodes draggable
    ogma.geo
      .enable({ disableNodeDragging: false })
      .then(function () {
        // load the geoJSON data
        return getGeoJSONData();
      })
      .then(function (shapesData) {
        // ask the map from Ogma
        let map = ogma.geo.getMap();
        // add a custom layer to the map
        countriesShapesLayer = L.geoJSON(shapesData, {
          style: {
            color: '#ff7800',
            weight: 5
          }
        }).addTo(map);
        // now apply a filter based on the graph
        let nodeList = ogma.getNodes();
        updateShapesVisibility(nodeList);

        // When a node is dragged update the map
        // debounce the update for performance reason: ogma is pretty fast at notify but the
        // leafletPip.pointInLayer method is calculationally heavy
        ogma.events.onDragProgress(function () {
          requestAnimationFrame(function () {
            return updateShapesVisibility(nodeList);
          });
        });

        // set the center in europe
        return ogma.geo.setView(49.429053, 15.140625, 4);
      });
  </script>
</body>

</html>