Mapy.cz plánování bodů trasy
Přidal Filip Kalousek dne
Úvod
Často se koukám na fórum nápovědy pro mapy.cz, narazil jsem tam už před nějakou dobou na dotaz na Získání vzdálenosti a času mezi průjezdními body
.
Rozhodl jsem se tedy podělit o moje nejrychlejší řešení na toto téma, neříkám nejúčinější / nejvhodnější, ale nejrychlejší.
Klasický setup webu
<head>
<script src="https://api.mapy.cz/loader.js"></script>
<script>
Loader.load();
</script>
</head>
<body>
<div class="results">
<ul></ul> <!-- PRO VKLÁDÁNÍ VÝSLEDKŮ -->
</div>
<div id="map"></div>
</body>
Inicializace konstant
const center = SMap.Coords.fromWGS84(15.339, 49.826); // Střed ČR
/* LOKACE JSOU STATICKY, OFC KLÍĎO TAHAT Z DATABÁZE, ALE O TOM TENTO PŘÍKLAD NENÍ*/
const locations = [{
points: [14.4341414, 50.0835494],
name: 'Praha',
},
{
points: [15.8327683, 50.2092283],
name: 'Hradec Králové',
},
{
points: [16.6078411, 49.2002211],
name: 'Brno'
},
{
points: [18.2820442, 49.8346453],
name: 'Ostrava'
}
];
Nastavení mapy
// Zahájení mapové instance
const m = new SMap(document.querySelector("#map"), center, 8);
m.addDefaultLayer(SMap.DEF_BASE).enable();
m.addDefaultControls();
// Vytvoříme vrstvu pro značky
const markerLayer = new SMap.Layer.Marker();
m.addLayer(markerLayer);
markerLayer.enable();
// Vytvoříme vrstvu pro vodící čáry
const geometryLayer = new SMap.Layer.Geometry();
m.addLayer(geometryLayer).enable();
Přidání značek do mapy
locations.forEach((point, i) => {
const position = SMap.Coords.fromWGS84(point.points[0], point.points[1]);
/* MÁM RADŠI VLASTNÍ VZHLED ZNAČEK )))*/
const marker = JAK.mel(
"div",
{ title: point.name, },
{
width: "0.75rem",
height: "0.75rem",
background: "#0c57fb",
borderRadius: "50%",
cursor: "pointer",
marginTop: "1.5rem"
}
);
// Vytvoříme značku a přidámejí do vrstvy pro značky
const pointMarker = new SMap.Marker(position, `marker-${i}`, { url: marker });
markerLayer.addMarker(pointMarker);
});
Plánování trasy
const results = document.querySelector(".results");
// Inicializujeme "metodu" která nám už hodí výsledek
const planRoute = (route) => {
const result = route.getResults();
const g = new SMap.Geometry(SMap.GEOMETRY_POLYLINE, null, result.geometry);
geometryLayer.addGeometry(g);
locations.map((point, i) => {
if (point.points[0] === route.getCoords()[0].x && point.points[1] === route.getCoords()[0].y) {
results.children[0].innerHTML += `
<li>
<p>
${point.name} ⏩ ${locations[i+1].name}
<br/>
<b>
🧳 ${Math.round(result.length / 1000)} km, 🕓 ${Math.round(result.time / 60)} minut
</b>
</p>
</li>`
}
});
}
locations.forEach((point, i) => {
if (i !== locations.length - 1) {
// Projedeme všechny trasy, musí mít začátek i konec, tak ošetříme, aby nehodilo
// chybu
const coords = [
SMap.Coords.fromWGS84(point.points[0], point.points[1]),
SMap.Coords.fromWGS84(locations[i + 1].points[0], locations[i + 1].points[1])
];
// Protože je toto ten nejjednodušší způsob, tak jsem zvolil kompromis, aby načítání trasy šlo postupně v našem případě PRG -> HK -> OST, tak je to v timeoutu
setTimeout(() => {
SMap.Route.route(coords, {
geometry: true
}).then(planRoute);
}, i * 100);
}
});