Hallo,
a) sowohl auf der Website als auch in codepen.io finde ich die Funktion displayRouteOnMap
zweimal.
Bitte die erste löschen
b) getRouteData ist noch die alte Version, die versucht die Daten von Nominatim zu bekommen. Diese API gibt es nicht. Durch die Version in Beitrag #17 ersetzen, denn die zweite Version von displayRouteOnMap()
funktioniert nur mit der OSRM-API, die erste gar nicht.
// OSRM will Koordinaten haben: long,lat;long,lat; ...
async function getRouteData(start, ende) {
// Ermittle Route zwischen Start- und Endpunkt
// Hier verwendet: Demo-Server on OSRM
// API siehe https://project-osrm.org/docs/v5.5.1/api/#general-options
const apiUrl = `https://router.project-osrm.org/route/v1/car/${encodeURIComponent(start[1])},${encodeURIComponent(start[0])};${encodeURIComponent(ende[1])},${encodeURIComponent(ende[0])}?geometries=geojson&overview=simplified`;
// Abrufen der Routendaten
const response = await fetch(apiUrl);
if (!response.ok) {
throw new Error("Fehler beim Abrufen der Routendaten");
}
const routeData = await response.json();
return(routeData);
}
c) Wenn ich den Code der Reverse-Geocodierung in einer separaten HTML-Datei nutze, funktioniert dieser ohne Fehlermeldung.
pwaMarlem
(Pwa Marlem)
November 24, 2023, 8:44am
22
Hallo,
Vielen Dank für die Hilfe!
Codepen aktualisiert per FTP Dateien hochgeladen.
Die gute Nachricht ist, ich bekomme in der Browser-Konsole keine Fehlermeldung.
Die schlechte Nachricht ist, die Karte und die Route wird nicht angezeigt.
Weißt Du woran es liegt?
Vinzenz_Mai
(Vinzenz Mai)
November 24, 2023, 10:29am
23
Hallo,
ich vermute, ja: Dein div-Element, in dem die Karte angezeigt werden soll, ist versteckt, meins war es nicht. Deswegen wieder
in displayRouteOnMap ergänzen.
pwaMarlem
(Pwa Marlem)
November 24, 2023, 12:44pm
24
Du Held! Es funktioniert.
Codepen aktualisiert. Per FTP hochgeladen.
Allerdings wird die Karte von der Y-Position zu weit unten angezeigt.
Frage:
Wie kann ich das ändern?
Das ist in Deinem HTML-Code folgender Abschnitt:
<div id="parentElement">
<div id="response"></div>
<div id="mapid"></div>
</div>
Was die Karte nach unten schiebt, ist das div-Element mit id="response"
Ich vermute, dass Du das so nicht willst, sondern, dass die Karte Inhalt dieses Elementes ist. In diesem Falle wäre
<div id="parentElement">
<div id="response">
<div id="mapid"></div>
</div>
</div>
das Richtige.
Wenn das nicht der Fall ist, dann müsstest Du das response-DIV ausblenden (und wenn Du es wieder brauchst wieder einblenden). Das geht prinzipiell genauso, wie Du das Einblenden (das ich vergessen hatte) vom Kartenelement machst.
pwaMarlem
(Pwa Marlem)
November 24, 2023, 4:17pm
26
@Vinzenz_Mai
Du bist ein Held!
Es funktioniert auch auf meinem Smartphone.
Ich musste das div so ausblenden:
responseDiv.style.display = "none";
Hier nochmal der ganze Code:
// OSRM will Koordinaten haben: long,lat;long,lat; ...
async function getRouteData(start, ende) {
// Ermittle Route zwischen Start- und Endpunkt
// Hier verwendet: Demo-Server on OSRM
// API siehe https://project-osrm.org/docs/v5.5.1/api/#general-options
const apiUrl = `https://router.project-osrm.org/route/v1/car/${encodeURIComponent(start[1])},${encodeURIComponent(start[0])};${encodeURIComponent(ende[1])},${encodeURIComponent(ende[0])}?geometries=geojson&overview=simplified`;
// Abrufen der Routendaten
const response = await fetch(apiUrl);
if (!response.ok) {
throw new Error("Fehler beim Abrufen der Routendaten");
}
const routeData = await response.json();
return(routeData);
}
async function displayRouteOnMap(startAddress, endAddress) {
//Geocodiere Start- und Zieladresse
const startCoordinates = await geocodeAddress(startAddress);
const endCoordinates = await geocodeAddress(endAddress);
// Wenn erfolgreich
if (!(startCoordinates === undefined || endCoordinates === undefined)) {
// -------------------------------
// Räume auf, falls notwendig
// Map-Objekt
if (typeof map !== "undefined") {
map.off();
map.remove();
}
// Marker
if (markerStart) {
map.removeLayer(markerStart);
}
if (markerZiel) {
map.removeLayer(markerZiel);
}
// Markergruppe
if (group) {
map.removeLayer(group);
}
// -------------------------------
// Route ermitteln
const routeData = await getRouteData(startCoordinates, endCoordinates);
// -------------------------------
responseDiv.style.display = "none";
// Setze das Karten-DIV sichtbar
mapidDiv.style.display = "block";
// Darstellung auf der Karte
// Passender Kartenbereich vorbereiten
map = L.map('mapid').setView(
[
// lat ist im ersten Array-Element
(startCoordinates[0] + endCoordinates[0]) / 2,
(startCoordinates[1] + endCoordinates[1]) / 2,
], 14
);
// Kartenkacheln laden
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, <a href="https://openstreetmap.org/fixthemap">mitmachen/Fehler melden</a>'
}).addTo(map);
// Marker für Start und Zieladresse und gruppiere diese
var markerStart = L.marker([startCoordinates[0], startCoordinates[1]]).addTo(map);
var markerZiel = L.marker([endCoordinates[0], endCoordinates[1]]).addTo(map);
var group = new L.featureGroup([markerStart, markerZiel]);
// Zeige Routendaten an
const geometry = routeData.routes[0].geometry;
const route = L.geoJSON(geometry);
route.addTo(map);
// Passe die Anzeige an das Notwendige an
map.fitBounds(group.getBounds());
}
}
/**
* Zeigt eine Openstreetmap-Karte an
* @param {address} address der gesprochen werden soll.
*/
function showMapWithAddress(address) {
let vaddress = escapeHtml(address);
// Überprüfe, ob das map-Objekt bereits existiert
if (typeof map !== "undefined") {
map.off();
map.remove();
}
map = L.map("mapid");
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
attribution:
'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
}).addTo(map);
// Setze das Karten-DIV sichtbar
mapidDiv.style.display = "block";
let marker;
geocodeAddress(vaddress).then((coords) => {
if (coords) {
if (marker) {
map.removeLayer(marker);
}
responseDiv.style.display = "none";
marker = L.marker(coords).addTo(map);
// Setzen der Kartenposition basierend auf den geokodierten Koordinaten
map.setView(coords, 15);
} else {
alert("Geokodierung fehlgeschlagen: Adresse nicht gefunden");
}
});
}
async function geocodeAddress(vaddress) {
let url = `https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(vaddress)}`;
let coords;
const response = await fetch(url);
if (response.ok) {
data = await response.json();
if (data.length > 0) {
// Aus den Zeichenketten Kommazahlen machen
coords = [parseFloat(data[0].lat), parseFloat(data[0].lon)];
}
}
return coords;
}
/**
* Ruft Ortsnamen anhand von Latitude und Longitude ab und zeigt sie in der App an
* @param {number} latitude - Breitengrad
* @param {number} longitude - Längengrad
*/
function reverseGeocode(latitude, longitude, callback) {
const url = `https://nominatim.openstreetmap.org/reverse?format=json&lat=${latitude}&lon=${longitude}&zoom=18&addressdetails=1`;
fetch(url)
.then((response) => response.json())
.then((data) => {
if (data.display_name) {
const addressComponents = data.display_name.split(", ");
const locationName = addressComponents[addressComponents.length - 3];
callback(locationName);
} else {
console.error("Reverse-Geokodierung fehlgeschlagen");
callback(null);
}
})
.catch((error) => {
console.error("Fehler bei der Reverse Geokodierung: " + error);
callback(null);
});
}
Vielen, vielen vielen Dank für Deine Erklärungen und Deine Geduld!