UNPKG

@trailstash/ultra

Version:

A web based tool for making MapLibre GL maps with data from sources such as Overpass, GeoJSON, GPX, KML, TCX, etc

106 lines (102 loc) 2.57 kB
import { fetchIfHTTP } from "./util.js"; import { gpx } from "@tmcw/togeojson"; const layers = (source) => [ { id: "ultra-gpx-line-casing", type: "line", source: "ultra", layout: { "line-cap": "round", "line-join": "round", }, paint: { "line-color": "rgb(164, 112, 179)", "line-opacity": 0.8, "line-width": 2, "line-gap-width": 5, }, }, { id: "ultra-gpx-line", type: "line", source: "ultra", layout: { "line-cap": "round", "line-join": "round", }, paint: { "line-color": "rgb(226, 126, 255)", "line-opacity": 0.5, "line-width": 5, }, }, { id: `${source}-gpx-dir`, type: "symbol", source, filter: ["==", ["geometry-type"], "LineString"], layout: { "symbol-placement": "line", "symbol-spacing": 50, "icon-image": "maki:triangle", "icon-rotate": 90, "icon-size": 0.3, }, paint: { "icon-color": "rgb(164, 112, 179)", "icon-halo-color": "rgb(226, 126, 255)", "icon-halo-width": 1, }, }, { id: `${source}-gpx-poi`, type: "symbol", source, filter: ["==", ["geometry-type"], "Point"], layout: { "icon-anchor": "bottom", "icon-image": "maki:marker", "icon-overlap": "always", "text-field": ["get", "name"], "text-variable-anchor": ["bottom-left", "bottom-right"], "text-justify": "auto", "text-radial-offset": 1, }, paint: { "icon-color": "rgba(255, 255, 51, 1)", "icon-halo-color": "rgba(51, 51, 51, 0.8)", "icon-halo-width": 1, "icon-halo-blur": 2, "text-color": "#333", "text-halo-color": "rgba(255,255,255,0.8)", "text-halo-width": 1.5, }, }, ]; const detect = async (query) => { query = await fetchIfHTTP(query); const doc = new window.DOMParser().parseFromString(query, "text/xml"); if ( !doc.querySelector("parsererror") && Array.from(doc.childNodes).some((x) => x.nodeName === "gpx") ) { return true; } }; export default { source: async function (query, controller) { let doc = new window.DOMParser().parseFromString(query, "text/xml"); if (doc.querySelector("parsererror")) { const resp = await fetch(query.trim(), { signal: controller.signal }); doc = new window.DOMParser().parseFromString( await resp.text(), "text/xml", ); } const data = gpx(doc); return { type: "geojson", data, generateId: true }; }, layers, detect, fitBounds: true, };