Vector layers and GeoJSON
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.
<!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>