GeoHelm/app/openlayers-pgrouting.html

186 lines
5.1 KiB
HTML
Raw Normal View History

2024-01-27 19:04:46 +00:00
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>PgRouting Example</title>
<!-- CSS/JS for OpenLayers map -->
<link rel="stylesheet" href="https://openlayers.org/en/v6.1.1/css/ol.css" type="text/css">
<script src="https://openlayers.org/en/v6.1.1/build/ol.js"></script>
<style>
body {
padding: 0;
margin: 0;
}
html, body, #map {
height: 100%;
width: 100%;
font-family: sans-serif;
}
#meta {
background-color: rgba(255,255,255,0.75);
color: black;
z-index: 2;
position: absolute;
top: 10px;
left: 20px;
padding: 10px 20px;
margin: 0;
width: min-content;
}
</style>
</head>
<body>
<div id="meta">
<h2>PgRouting / pg_tileserv / pg_featureserv</h2>
<ul>
<li><a href="https://openlayers.org/">OpenLayers</a></li>
<li><a href="https://pgrouting.org/">PgRouting</a></li>
<li><a href="https://github.com/crunchydata/pg_tileserv">pg_tileserv</a></li>
<li><a href="https://github.com/crunchydata/pg_featureserv">pg_featureserv</a></li>
</ul>
<p>Click once to set a start point, and a second time to set an end point and generate a route.</p>
<p>Routes are node-to-node so clicks are interpretted as starting from the nearest node.</p>
</div>
<div id="map"></div>
<script>
//********************************************************************************/
// CONSTANTS
//********************************************************************************/
var serverName = 'MYLOCALHOST'
//********************************************************************************/
// BASE MAP (Raster tiles from wikimedia)
//********************************************************************************/
var baseLayer = new ol.layer.Tile({
source: new ol.source.XYZ({
url: "http://{1-4}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png"
})
});
//********************************************************************************/
// WAY LAYER (Vector tiles of all ways from pg_tileserv)
//********************************************************************************/
var vectorUrl = "http://" + serverName + ":7800/public.ways/{z}/{x}/{y}.pbf";
var vectorStyle = new ol.style.Style({
stroke: new ol.style.Stroke({
width: 3,
color: "#00000055"
})
});
var vectorLayer = new ol.layer.VectorTile({
source: new ol.source.VectorTile({
format: new ol.format.MVT(),
url: vectorUrl
}),
style: vectorStyle
});
//********************************************************************************/
// CLICK LAYER (One point for each click)
//********************************************************************************/
var clicks = [];
var clickSource = new ol.source.Vector({});
var clickLayer = new ol.layer.Vector({
source: clickSource,
style: new ol.style.Style({
image: new ol.style.RegularShape({
fill: new ol.style.Fill({
color: 'red'
}),
stroke: new ol.style.Stroke({
width: 1,
color: 'grey'
}),
points: 16,
radius: 10,
angle: Math.PI / 4
})
})
});
//********************************************************************************/
// ROUTE LAYER (GeoJSON source reading from pg_featureserv)
//********************************************************************************/
function routeUrl(coord1, coord2) {
var url = "http://" + serverName + ":9000/functions/boston_find_route/items.json";
url += "?from_lon=" + coord1[0];
url += "&from_lat=" + coord1[1];
url += "&to_lon=" + coord2[0];
url += "&to_lat=" + coord2[1];
url += "&limit=1000"
return url;
}
var routeSource = new ol.source.Vector({
format: new ol.format.GeoJSON(),
projection : 'EPSG:4326',
features: []
});
var routeLayer = new ol.layer.Vector({
title: 'Route',
source: routeSource,
style: new ol.style.Style({
stroke: new ol.style.Stroke({
width: 3,
color: "#ff0000"
})
})
});
//********************************************************************************/
// MAP SETUP (Layers and click action function)
//********************************************************************************/
var map = new ol.Map({
target: 'map',
view: new ol.View({
center: ol.proj.transform([-71.0526, 42.3553], 'EPSG:4326', 'EPSG:3857'),
zoom: 15
}),
layers: [baseLayer, vectorLayer, routeLayer, clickLayer]
});
map.on('singleclick', function(evt) {
// Click when we already have 2 clicks means a fresh start
if (clicks.length >= 2) {
clicks.length = 0;
clickSource.clear();
routeSource.clear();
}
// Add latest click to the map
clicks.push(ol.proj.transform(evt.coordinate, 'EPSG:3857', 'EPSG:4326'));
clickSource.addFeature(new ol.Feature({
geometry: new ol.geom.Point(evt.coordinate),
}));
// Have two clicks? Calculate route!
if (clicks.length == 2) {
var url = routeUrl(clicks[0], clicks[1]);
routeSource.setUrl(url);
routeSource.clear();
routeSource.refresh();
}
// Redraw with new elements
map.render();
});
</script>
</body>
</html>