Zpět na hlavní stránku

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);
    }
});

Hotový výsledek