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="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.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;

        var 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' } }
            ]
        };

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

        // this is the reference to the layer we're going to add to the leaflet map
        var 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
            var countries = nodeList.getGeoCoordinates().map(function (coords) {
                // list of country polygons that contain the provided node point
                var 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) {
                var 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
                var 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
                var 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(_.debounce(function () {
                    updateShapesVisibility(nodeList);
                }, 30));

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

    </script>
</body>

</html>