Isochrone
Dieses Beispiel berechnet eine Isochrone – das von einem Punkt aus innerhalb einer bestimmten Reisezeit oder Reiseentfernung erreichbare Gebiet. Klicken Sie auf die Karte, um den Ausgangspunkt zu setzen; wechseln Sie zwischen Reisezeit und Entfernung sowie zwischen den Geschwindigkeitsprofilen, um zu sehen, wie sich das erreichbare Gebiet ändert.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://cdn.smartmaps.cloud/packages/smartmaps/smartmaps-gl/v2/umd/smartmaps-gl.min.js"></script>
<style>
body {
margin: 0;
padding: 0;
}
#map {
height: 100vh;
}
#controls {
position: absolute;
top: 10px;
left: 10px;
z-index: 1;
background: rgba(255, 255, 255, 0.9);
padding: 10px;
border-radius: 4px;
font: 13px sans-serif;
}
#controls label {
display: block;
margin-top: 6px;
}
#status {
margin-top: 8px;
max-width: 220px;
}
</style>
</head>
<body>
<div id="controls">
<strong>Click the map to place the origin</strong>
<label>
Mode:
<select id="mode">
<option value="time">Travel time</option>
<option value="distance">Distance</option>
</select>
</label>
<label id="value-label">
Minutes (max 60):
<input id="value" type="number" value="15" min="1" max="60" />
</label>
<label>
Speed profile:
<select id="profile">
<option value="FAST">Car - fast</option>
<option value="SLOW">Car - slow</option>
<option value="BICYCLE">Bicycle</option>
<option value="PEDESTRIAN">Pedestrian</option>
</select>
</label>
<div id="status"></div>
</div>
<div id="map"></div>
<script>
const map = new smartmapsgl.Map({
apiKey: '[INSERT API-KEY]',
container: 'map',
center: { lat: 49.02164948779226, lng: 8.439330018049352 },
zoom: 12,
style: smartmapsgl.MapStyle.LIGHT
});
const modeSelect = document.getElementById('mode');
const valueLabel = document.getElementById('value-label');
const valueInput = document.getElementById('value');
const profileSelect = document.getElementById('profile');
const statusEl = document.getElementById('status');
let marker = null;
modeSelect.addEventListener('change', () => {
const isTime = modeSelect.value === 'time';
valueLabel.firstChild.textContent = isTime ? 'Minutes (max 60): ' : 'Meters: ';
valueInput.value = isTime ? 15 : 5000;
});
function removeIsochroneLayer() {
if (map.getLayer('isochrone-fill')) map.removeLayer('isochrone-fill');
if (map.getLayer('isochrone-outline')) map.removeLayer('isochrone-outline');
if (map.getSource('isochrone')) map.removeSource('isochrone');
}
map.on('click', async (event) => {
statusEl.textContent = 'Calculating…';
if (marker) marker.remove();
marker = new smartmapsgl.Marker({ color: '#0A5FA0' }).setLngLat(event.lngLat).addTo(map);
const isTime = modeSelect.value === 'time';
const routingparams = {
type: 'ISOCHRONE',
isochroneGrid: '80',
speedProfile: profileSelect.value,
coordFormatOut: 'GEODECIMAL_POINT',
routingTimeMode: 'ARRIVAL',
timeInMinutes: isTime ? Number(valueInput.value) : null,
distanceInMeters: isTime ? null : Number(valueInput.value)
};
try {
const response = await fetch(
'https://www.yellowmap.de/api_rst/v2/geojson/route?apiKey=[INSERT API-KEY]',
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
type: 'FeatureCollection',
routingparams,
authentication: { channel: '' },
crs: { type: 'name', properties: { name: 'urn:ogc:def:crs:OGC:1.3:CRS84' } },
features: [
{
type: 'Feature',
geometry: { type: 'Point', coordinates: [event.lngLat.lng, event.lngLat.lat] },
properties: {}
}
]
})
}
);
if (!response.ok) throw new Error(`Server error: ${response.status}`);
const result = await response.json();
const polygon = result.features.find(
(feature) => feature.properties?.featureType === 'ISOCHRONE_OUTLINE_POLYGON'
);
if (!polygon) throw new Error('No isochrone in response');
removeIsochroneLayer();
map.addSource('isochrone', { type: 'geojson', data: polygon });
map.addLayer({
id: 'isochrone-fill',
type: 'fill',
source: 'isochrone',
paint: { 'fill-color': '#0A5FA0', 'fill-opacity': 0.25 }
});
map.addLayer({
id: 'isochrone-outline',
type: 'line',
source: 'isochrone',
paint: { 'line-color': '#0A5FA0', 'line-width': 2 }
});
const label = isTime ? `${valueInput.value} min` : `${valueInput.value} m`;
statusEl.textContent = `Area reachable within ${label} (${profileSelect.value.toLowerCase()}).`;
} catch (error) {
console.error('Error fetching isochrone:', error);
statusEl.textContent = 'Failed to calculate the isochrone. Please try again.';
}
});
</script>
</body>
</html>
Hinweise
timeInMinutesunddistanceInMetersschließen sich gegenseitig aus – setzen Sie den nicht verwendeten Wert aufnull, genau wie es der Modus-Umschalter oben tut.- Die Antwort ist eine
FeatureCollectionmit zwei Features: dem Umriss-Polygon (properties.featureType === "ISOCHRONE_OUTLINE_POLYGON") und dem Ursprungspunkt. Filtern Sie nachfeatureType, statt sich auf die Reihenfolge im Array zu verlassen. isochroneGrid(35–150) bestimmt, wie fein das Polygon berechnet wird – höhere Werte folgen dem Straßennetz genauer, benötigen aber mehr Rechenzeit.
Die vollständige Parameterliste finden Sie in der Isochrone-Referenz,
oder nutzen Sie die Bibliotheksversion, wenn Sie das
@smartmaps/routing-npm-Paket bevorzugen. Routenoptimierung
zeigt eine Isochrone in Kombination mit Matrix und Autocomplete in einem vollständigen
Logistikszenario.