Optimierte Routenplanung mit Google Maps und FileMaker
In der heutigen digitalen Arbeitswelt spielen nahtlose Integrationen zwischen verschiedenen Systemen eine entscheidende Rolle. Besonders bei der Optimierung von Routen für Außendienstmitarbeiter oder Logistikunternehmen ist es wichtig, sowohl Zeit als auch Kosten zu sparen. Dieser Blog-Post zeigt, wie man Google Maps für die dynamische Routenplanung nutzt und gleichzeitig Daten in FileMaker integriert.
Das Problem
Viele Unternehmen stehen vor der Herausforderung, eine Vielzahl von Wegpunkten (Aufträgen) optimal zu sortieren, um eine effiziente Route zu erstellen. Dies erfordert Tools, die nicht nur Kartenansichten bereitstellen, sondern auch die Reihenfolge der Stopps optimieren und diese Informationen zurück an das System (in diesem Fall FileMaker) senden können.
Die Lösung
Das folgende PHP-Script löst dieses Problem, indem es: 1. Google Maps API verwendet, um Wegpunkte zu optimieren. 2. Die optimierte Reihenfolge als Liste darstellt. 3. Ein FileMaker-Script auslöst, um diese Daten für weitere Prozesse zu nutzen.
Der erste Schritt steht darin die Daten die benötigt werden innerhalb von FileMaker zu sammeln. Dies ist möglich über die Erstellung einer Variable per Listenfunktion, SQL oder per Schleife. Wie auch immer die Umsetzung erfolgt, am Ende benötigen wir eine URL die wir an unser PHP-Script senden können. Enthalten sein müssen, die Geo-Daten und natürlich eindeutige IDs aus FileMaker damit diese Daten später auch wieder in FileMaker verarbeitet werden können. Eine URL sollte diesen Aufbau haben: https://dein-server.de/maps.php?json=true&origin=52.5212262,13.3340740 &destination=52.5070279,13.345529 &waypoints=52.4897075,13.3290075|52.4902317,13.355636|52.5037865,13.3271369|52.504083,13.3386575&auftrag=24501|24510|24547|24551|24573|24580&facilities=6039|1940|4540|5036|6634|6545 Diese werden dann über den FM-Befehl, -AUS URL einfügen- übergeben. Wie der Aufbau innerhalb von FileMaker funktioniert ist selbstredend. Ein WebViewer innerhalb von FileMaker muss natürlich vorhanden sein. Die Rückgabe muss an den WebViewer z.B. eine globale Variable erfolgen.
Das PHP Script:
<?php
// API-Schlüssel für Google Maps
$apiKey = 'Ihr_Google_Maps_API_Schlüssel';
// Werte aus GET-Parametern holen oder Standardwerte setzen
$origin = isset($_GET['origin']) ? $_GET['origin'] : '52.515956,13.388512';
$destination = isset($_GET['destination']) ? $_GET['destination'] : '52.4981845,13.4610157';
$waypoints = isset($_GET['waypoints']) ? $_GET['waypoints'] : '';
$auftrag = isset($_GET['auftrag']) ? explode('|', $_GET['auftrag']) : [];
$facilities = isset($_GET['facilities']) ? explode('|', $_GET['facilities']) : [];
// Wegpunkte in ein Array umwandeln
$waypointsArray = explode('|', $waypoints);
?>
- Origin (Startpunkt)
Der Origin ist der Ausgangspunkt der Route. • Es handelt sich um die Position, von der die Route beginnt. • In der Regel wird sie als geografische Koordinate angegeben (z. B. 52.515956,13.388512 für Berlin). • Beispiel: Eine zentrale Lagerhalle oder der Startpunkt eines Fahrers.
- Destination (Endpunkt)
Die Destination ist das Ziel der Route. • Es ist der Punkt, an dem die Route endet. • Ähnlich wie der Origin wird auch die Destination als geografische Koordinate angegeben. • Beispiel: Der Zielort eines Lieferauftrags.
- Waypoint (Zwischenstation)
Ein Waypoint ist eine oder mehrere Zwischenstationen entlang der Route. • Es handelt sich um Orte, die der Fahrer besuchen muss, bevor er sein Ziel (Destination) erreicht. • Waypoints können ebenfalls als Koordinaten (z. B. 52.5062585,13.2845797) angegeben werden. • Sie werden oft verwendet, um Stopps bei Kunden, Lieferstationen oder Servicepunkten darzustellen. • Google Maps erlaubt, mehrere Waypoints anzugeben, um komplexe Routen zu erstellen.
Das Script liest die Parameter origin, destination, waypoints, auftrag, und facilities, um sie für die Routenplanung vorzubereiten. Diese Parameter könnten direkt aus einer FileMaker-Datenbank oder einer anderen Quelle kommen.
Die Routenoptimierung
Das Herzstück des Scripts ist die Funktion initMap():
function initMap() { const map = new google.maps.Map(document.getElementById(‘map’), { zoom: 13, center: { lat: , lng: }, });
const directionsService = new google.maps.DirectionsService();
const directionsRenderer = new google.maps.DirectionsRenderer({ map: map });
directionsService.route(
{
origin: locations[0].position,
destination: locations[locations.length - 1].position,
waypoints: locations.slice(1, -1).map(location => ({
location: location.position,
stopover: true,
})),
travelMode: google.maps.TravelMode.DRIVING,
optimizeWaypoints: true,
},
(result, status) => {
if (status === 'OK') {
directionsRenderer.setDirections(result);
const waypointOrder = result.routes[0].waypoint_order.map(index => locations[index + 1].label);
optimizedOrder = [locations[0].label, ...waypointOrder, locations[locations.length - 1].label];
} else {
console.error('Error:', status);
}
}
);
}
Die Funktion ruft die Google Maps Directions API auf, um die optimale Reihenfolge der Wegpunkte zu berechnen. Diese Reihenfolge wird in optimizedOrder gespeichert.
Integration mit FileMaker
Das Script enthält einen Button, der die optimierte Reihenfolge an ein FileMaker-Script übergibt:
function sendToFileMaker() {
if (optimizedOrder.length > 0) {
const filemakerUrl = fmp://$/DEINE_DATEI?script=(0002)_Planung_Direkt_aus_Maps_holen¶m=${encodeURIComponent(optimizedOrder.join('\n'))}
;
window.location.href = filemakerUrl;
} else {
alert(‘Die Route ist noch nicht optimiert. Bitte warten.');
}
}
Dieser Button ermöglicht es, die optimierten Daten direkt in FileMaker zu laden, wo sie für weitere Aktionen wie die Gruppierung von Aufträgen oder Berichte verwendet werden können.
Vorteile der Lösung 1. Zeitersparnis: Die API optimiert die Route automatisch. 2. Nahtlose Integration: Die Übergabe an FileMaker erfolgt reibungslos. 3. Flexibilität: Die Darstellung in der Karte ermöglicht eine visuelle Kontrolle der Route. 4. Erweiterbarkeit: Zusätzliche Funktionen wie das Hinzufügen von z.B. Anlagen können leicht integriert werden.
Fazit
Dieses Script ist eine effektive Lösung für Unternehmen, die ihre Logistikprozesse optimieren möchten. Durch die Kombination von Google Maps und FileMaker wird eine leistungsstarke, flexible und leicht implementierbare Lösung geschaffen.
Als Anmerkung ist allerdings zu beachten, in diesem Fall können nur 10 Punkte verarbeitet werden. Dies erfordert eine Vorauswahl der an Google zu übergebenen Punkte. Dies kann direkt schon über die Google APIs erfolgen oder z.B. die Haversche Formel.
Zum Überblick das gesamte Script:
// Werte aus GET-Parametern holen oder Standardwerte setzen
$origin = isset($_GET['origin']) ? $_GET['origin'] : '52.515956,13.388512';
$destination = isset($_GET['destination']) ? $_GET['destination'] : '52.4981845,13.4610157';
$waypoints = isset($_GET['waypoints']) ? $_GET['waypoints'] : '';
$auftrag = isset($_GET['auftrag']) ? explode('|', $_GET['auftrag']) : [];
$facilities = isset($_GET['facilities']) ? explode('|', $_GET['facilities']) : [];
// Wegpunkte in ein Array umwandeln um Anzeige über PIN
$waypointsArray = explode('|', $waypoints);
?>
<!DOCTYPE html>
<html>
<head>
<title>Dynamische Route</title>
<script src="https://maps.googleapis.com/maps/api/js?key=DEIN_API_KEY"></script>
<script>
let optimizedOrder = []; // Variable für die optimierte Reihenfolge
function initMap() {
// Initialisiere die Karte
const map = new google.maps.Map(document.getElementById('map'), {
zoom: 13,
center: { lat: <?php echo explode(',', $origin)[0]; ?>, lng: <?php echo explode(',', $origin)[1]; ?> },
});
const locations = [
{
position: { lat: <?php echo explode(',', $origin)[0]; ?>, lng: <?php echo explode(',', $origin)[1]; ?> },
label: '<?php echo $auftrag[0] ?? "Start"; ?>',
facilities: '<?php echo $facilities[0] ?? "Keine Anlagen"; ?>',
},
<?php foreach ($waypointsArray as $index => $point): ?>
{
position: { lat: <?php echo explode(',', $point)[0]; ?>, lng: <?php echo explode(',', $point)[1]; ?> },
label: '<?php echo $auftrag[$index + 1] ?? "Waypoint"; ?>',
facilities: `<?php echo str_replace(',', '<br>', $facilities[$index + 1] ?? "Keine Anlagen"); ?>`,
},
<?php endforeach; ?>
{
position: { lat: <?php echo explode(',', $destination)[0]; ?>, lng: <?php echo explode(',', $destination)[1]; ?> },
label: '<?php echo $auftrag[count($auftrag) - 1] ?? "Ziel"; ?>',
facilities: '<?php echo $facilities[count($facilities) - 1] ?? "Keine Anlagen"; ?>',
}
];
// Details zu Markern und Kreisen hinzufügen
locations.forEach((location) => {
const marker = new google.maps.Marker({
position: location.position,
map: map,
label: {
text: location.label,
color: '#000',
fontSize: '12px',
fontWeight: 'bold',
},
});
});
map.fitBounds(bounds);
}
function sendToFileMaker() {
if (optimizedOrder.length > 0) {
const filemakerUrl = `fmp://$/DEINE_DATEI?script=Planung¶m=${encodeURIComponent(optimizedOrder.join('\n'))}`;
window.location.href = filemakerUrl;
} else {
alert('Die Route ist noch nicht optimiert. Bitte warten.');
}
}
</script>
</head>
<body onload="initMap()">
<div id="map" style="width: 100%; height: 80%;"></div>
<button onclick="sendToFileMaker()">Optimierte Reihenfolge senden</button>
</body>
</html>