diff options
author | Dmitrii Morozov <dmitrii.morozov@sbb.ch> | 2025-04-29 15:28:14 +0200 |
---|---|---|
committer | Dmitrii Morozov <dmitrii.morozov@sbb.ch> | 2025-04-29 15:28:14 +0200 |
commit | 646ad4a014ae13bc9112cdad6a29aca7ed05e035 (patch) | |
tree | 6bc666ccae29dba51f9410be2cebc82016815ffc | |
parent | 76b77cc81b073ce75b1dc2594140b96da5b07089 (diff) |
Add route preview, optimized logic
-rw-r--r-- | index.html | 121 |
1 files changed, 79 insertions, 42 deletions
@@ -2,77 +2,114 @@ <html lang="en"> <head> <meta charset="UTF-8"> - <title>Calimoto GPX (rtept) to Google Maps Directions - Fixed Start/End</title> + <title>Calimoto GPX to Google Maps - Flexible Start/End</title> + <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" /> <style> body { font-family: Arial, sans-serif; margin: 2em; } - input[type="file"] { margin-bottom: 1em; } + label, select, input[type="file"] { margin-bottom: 1em; display: block; } #result { margin-top: 1em; } + #map { height: 500px; margin-top: 1em; border: 1px solid #ccc; } a { word-break: break-word; } </style> </head> <body> -<h1>Calimoto GPX (rtept) to Google Maps Directions (Fixed Start/End Point)</h1> +<h1>Calimoto GPX to Google Maps Directions</h1> + +<label for="mode">Start/end point:</label> +<select id="mode"> + <option value="office">Use predefined start/end (Office)</option> + <option value="original">Use original GPX start/end</option> +</select> <input type="file" id="gpxfile" accept=".gpx" /> <div id="result"></div> +<div id="map"></div> +<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script> <script> -document.getElementById('gpxfile').addEventListener('change', function(event) { + let map = L.map('map').setView([46.962153, 7.446944], 13); + L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { + attribution: '© OpenStreetMap contributors' + }).addTo(map); + let routeLine; // to reuse and update the route line + document.getElementById('gpxfile').addEventListener('change', function(event) { + // Predefined start/end point (Office) + const fixedStartLat = 46.962153; + const fixedStartLon = 7.446944; + const fixedStart = `${fixedStartLat},${fixedStartLon}`; + const file = event.target.files[0]; if (!file) return; - // Define your new fixed start/end point - const startLat = 46.962153; // Your new latitude - const startLon = 7.446944; // Your new longitude - const startPoint = `${startLat},${startLon}`; + const mode = document.getElementById('mode').value; const reader = new FileReader(); reader.onload = function(e) { - const parser = new DOMParser(); - const xmlDoc = parser.parseFromString(e.target.result, "application/xml"); + const parser = new DOMParser(); + const xmlDoc = parser.parseFromString(e.target.result, "application/xml"); - const routePoints = xmlDoc.getElementsByTagName('rtept'); - if (routePoints.length < 3) { - document.getElementById('result').innerHTML = "Not enough <rtept> points in this file."; - return; - } + const routePoints = xmlDoc.getElementsByTagName('rtept'); + if (routePoints.length < 3) { + document.getElementById('result').innerHTML = "Not enough <rtept> points."; + return; + } - const coords = []; - // Skip first and last points - for (let i = 1; i < routePoints.length - 1; i++) { - const lat = routePoints[i].getAttribute('lat'); - const lon = routePoints[i].getAttribute('lon'); - coords.push(lat + "," + lon); - } + const coords = []; + let startCoord = ""; + let endCoord = ""; - const MAX_WAYPOINTS = 23; // Google Maps limit: start + waypoints + end - - let selectedCoords = []; - if (coords.length <= (MAX_WAYPOINTS - 2)) { - selectedCoords = coords; - } else { - // Shrink points smartly - const intermediatePoints = MAX_WAYPOINTS - 2; // 1 for start, 1 for end - const interval = coords.length / intermediatePoints; - for (let i = 1; i < intermediatePoints - 1; i++) { - const index = Math.round(i * interval); - if (index >= coords.length) break; - selectedCoords.push(coords[index]); - } + for (let i = 0; i < routePoints.length; i++) { + const lat = routePoints[i].getAttribute('lat'); + const lon = routePoints[i].getAttribute('lon'); + coords.push(lat + "," + lon); + } + + if (mode === "original") { + startCoord = routePoints[0].getAttribute('lat') + "," + routePoints[0].getAttribute('lon'); + endCoord = routePoints[routePoints.length - 1].getAttribute('lat') + "," + routePoints[routePoints.length - 1].getAttribute('lon'); + } else if (mode === "office") { + startCoord = fixedStart; + endCoord = fixedStart; + } + + const MAX_WAYPOINTS = 23; + let selectedCoords = []; + const availableSlots = MAX_WAYPOINTS - 2; + + if (coords.length <= availableSlots) { + selectedCoords = coords; + } else { + const interval = coords.length / availableSlots; + for (let i = 1; i < availableSlots - 1; i++) { + const index = Math.round(i * interval); + if (index >= coords.length) break; + selectedCoords.push(coords[index]); } + } + + const fullCoords = [startCoord, ...selectedCoords, endCoord]; + const baseUrl = "https://www.google.com/maps/dir/"; + const url = baseUrl + fullCoords.join('/'); - // Build final path: start -> route -> end - const fullCoords = [startPoint, ...selectedCoords, startPoint]; + document.getElementById('result').innerHTML = ` + <p><strong>Directions Link:</strong></p> + <p><a href="${url}" target="_blank">${url}</a></p> + `; - const baseUrl = "https://www.google.com/maps/dir/"; - const url = baseUrl + fullCoords.join('/'); + // Draw route preview on map + const latLngs = fullCoords.map(pt => { + const [lat, lon] = pt.split(',').map(Number); + return [lat, lon]; + }); - document.getElementById('result').innerHTML = `<p><strong>Directions Link:</strong></p><p><a href="${url}" target="_blank">${url}</a></p>`; + if (routeLine) map.removeLayer(routeLine); + routeLine = L.polyline(latLngs, { color: 'blue', weight: 4 }).addTo(map); + map.fitBounds(routeLine.getBounds()); }; reader.readAsText(file); -}); + }); </script> </body> |