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="../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>