// ==UserScript== // @name AllTrails KML Downloader // @namespace http://tampermonkey.net/ // @version 2025-04-29 // @description This script adds a "Download KML" button to any trail on AllTrails.com // @match https://www.alltrails.com/trail/* // @grant GM_xmlhttpRequest // @grant GM_download // @require https://cdnjs.cloudflare.com/ajax/libs/mapbox-polyline/1.1.1/polyline.min.js // @license GNU GPLv3 // @downloadURL none // ==/UserScript== (function() { 'use strict'; // Add the "Download KML" button to the page function createDownloadButton() { const button = document.createElement('button'); button.textContent = 'Download KML'; button.style.position = 'fixed'; button.style.top = '10px'; button.style.right = '10px'; button.style.zIndex = '9999'; button.style.padding = '10px 15px'; button.style.background = '#4CAF50'; button.style.color = 'white'; button.style.border = 'none'; button.style.borderRadius = '5px'; button.style.fontSize = '16px'; button.style.cursor = 'pointer'; button.onclick = function() { fetchMapPageAndGenerateKML(); }; document.body.appendChild(button); } // Function to fetch map data via AJAX from the map page URL function fetchMapPageAndGenerateKML() { const trailUrl = window.location.href; // e.g., "https://www.alltrails.com/trail/us/florida/lake-myakka-trail" const mapUrl = trailUrl.replace('/trail/', '/explore/trail/') + '?mobileMap=false&initFlyover=true&flyoverReturnToTrail'; console.log(`Fetching map data from: ${mapUrl}`); GM_xmlhttpRequest({ method: 'GET', url: mapUrl, onload: function(response) { const mapPageHtml = response.responseText; const mapDataMatch = mapPageHtml.match(/
\n\n\n`; // Add routes (trails) routes.forEach(route => { route.lineSegments.forEach(segment => { const pointsData = segment.polyline.pointsData; // Decode the polyline (if pointsData is not already decoded) if (typeof pointsData === 'string') { const decodedPoints = polyline.decode(pointsData); let coordinates = decodedPoints.map(point => `${point[1]},${point[0]},0`).join(' '); kmlContent += ` ${trailName} ${coordinates} `; } else { console.error('pointsData is not a polyline string:', pointsData); } }); }); // Add waypoints (trail markers) waypoints.forEach(waypoint => { kmlContent += ` ${waypoint.name} ${waypoint.location.longitude},${waypoint.location.latitude},0 `; }); kmlContent += `\n`; // Trigger KML download const blob = new Blob([kmlContent], { type: 'application/vnd.google-earth.kml+xml' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `${trailName}.kml`; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); } // Initialize the script createDownloadButton(); })();