您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Overlay StravaGPX or KML files onto Waze Map Editor
当前为
// ==UserScript== // @name WME GPX/KML Overlay // @namespace https://www.waze.com/ // @version 1.0 // @description Overlay StravaGPX or KML files onto Waze Map Editor // @author Dosojintaizo // @license MIT/BSD/X11 // @include https://www.waze.com/editor* // @include https://www.waze.com/*/editor* // @include https://beta.waze.com/editor* // @include https://beta.waze.com/*/editor* // @require https://update.gf.qytechs.cn/scripts/520574/1502033/togeojson.js // @grant none // ==/UserScript== (function() { 'use strict'; if (W?.userscripts?.state.isReady) { initializeScript(); } else { document.addEventListener("wme-ready", initializeScript, { once: true }); } const overlays = []; async function initializeScript() { console.log("WME GPX/KML Overlay script initialized."); const { tabLabel, tabPane } = W.userscripts.registerSidebarTab("wme-strava-kml-overlay"); tabLabel.innerText = "Overlay"; tabLabel.title = "Import and manage GPX/KML overlays on the map"; tabPane.innerHTML = ` <div style="padding: 10px;"> <h3>Strava/KML Overlay</h3> <p>Import GPX or KML files to overlay them on the map.</p> <input type="file" id="fileInput" accept=".gpx,.kml" /> <div id="overlayList" style="margin-top: 20px;"></div> <div id="status" style="margin-top: 10px; color: green;"></div> </div> `; await W.userscripts.waitForElementConnected(tabPane); const fileInput = tabPane.querySelector("#fileInput"); const overlayList = tabPane.querySelector("#overlayList"); const status = tabPane.querySelector("#status"); fileInput.addEventListener("change", async (event) => { const file = event.target.files[0]; if (!file) { status.textContent = "No file selected."; return; } try { const text = await file.text(); let geoJSON; if (file.name.endsWith(".gpx")) { geoJSON = parseGPXToGeoJSON(text); } else if (file.name.endsWith(".kml")) { geoJSON = parseKMLToGeoJSON(text); } else { throw new Error("Unsupported file format. Please upload a GPX or KML file."); } addOverlay(file.name, geoJSON); status.textContent = "Overlay added successfully."; } catch (error) { console.error("Error processing file:", error); status.textContent = `Error: ${error.message}`; } }); } function parseGPXToGeoJSON(gpxText) { const parser = new DOMParser(); const gpxDoc = parser.parseFromString(gpxText, "application/xml"); return toGeoJSON.gpx(gpxDoc); } function parseKMLToGeoJSON(kmlText) { const parser = new DOMParser(); const kmlDoc = parser.parseFromString(kmlText, "application/xml"); return toGeoJSON.kml(kmlDoc); } function addOverlay(fileName, geoJSON) { const layerName = fileName; const vectorLayer = new OpenLayers.Layer.Vector(layerName, { styleMap: new OpenLayers.StyleMap({ "default": new OpenLayers.Style({ strokeColor: "#FFFF00", strokeWidth: 3, fillOpacity: 0.4, }), }), }); geoJSON.features.forEach((feature) => { if (feature.geometry && feature.geometry.coordinates) { feature.geometry.coordinates = removeZCoordinates(feature.geometry.coordinates); } const olGeometry = W.userscripts.toOLGeometry(feature.geometry); const vectorFeature = new OpenLayers.Feature.Vector(olGeometry); vectorLayer.addFeatures([vectorFeature]); }); W.map.addLayer(vectorLayer); const overlay = { name: fileName, layer: vectorLayer, color: "#FFFF00", width: 3, }; overlays.push(overlay); renderOverlayList(); } function removeZCoordinates(coords) { if (Array.isArray(coords[0])) { return coords.map(removeZCoordinates); } else if (coords.length >= 2) { return coords.slice(0, 2); } return coords; } function renderOverlayList() { const overlayList = document.getElementById("overlayList"); overlayList.innerHTML = ""; overlays.forEach((overlay, index) => { const item = document.createElement("div"); item.style.marginBottom = "10px"; const title = document.createElement("div"); title.textContent = overlay.name; title.style.fontWeight = "bold"; title.style.display = "inline-block"; title.style.marginRight = "10px"; const toggle = document.createElement("input"); toggle.type = "checkbox"; toggle.checked = true; toggle.addEventListener("change", () => { overlay.layer.setVisibility(toggle.checked); }); const gearIcon = document.createElement("span"); gearIcon.textContent = "⚙️"; gearIcon.style.cursor = "pointer"; gearIcon.style.marginLeft = "10px"; const trashIcon = document.createElement("span"); trashIcon.textContent = "🗑️"; trashIcon.style.cursor = "pointer"; trashIcon.style.marginLeft = "10px"; trashIcon.addEventListener("click", () => { W.map.removeLayer(overlay.layer); overlays.splice(index, 1); renderOverlayList(); }); const settings = document.createElement("div"); settings.style.display = "none"; settings.style.marginTop = "5px"; settings.style.border = "1px solid #ccc"; settings.style.padding = "5px"; const colorInput = document.createElement("input"); colorInput.type = "color"; colorInput.value = overlay.color; colorInput.addEventListener("input", (event) => { overlay.color = event.target.value; overlay.layer.styleMap.styles.default.defaultStyle.strokeColor = overlay.color; overlay.layer.redraw(); }); const widthInput = document.createElement("input"); widthInput.type = "number"; widthInput.value = overlay.width; widthInput.min = 1; widthInput.max = 10; widthInput.addEventListener("input", (event) => { overlay.width = parseInt(event.target.value, 10) || 1; overlay.layer.styleMap.styles.default.defaultStyle.strokeWidth = overlay.width; overlay.layer.redraw(); }); settings.appendChild(document.createTextNode("Line Color: ")); settings.appendChild(colorInput); settings.appendChild(document.createElement("br")); settings.appendChild(document.createTextNode("Line Width: ")); settings.appendChild(widthInput); gearIcon.addEventListener("click", () => { settings.style.display = settings.style.display === "none" ? "block" : "none"; }); item.appendChild(trashIcon); item.appendChild(toggle); item.appendChild(gearIcon); item.appendChild(title); item.appendChild(settings); overlayList.appendChild(item); }); } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址