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

104 lines (92 loc) 2.72 kB
import * as maplibregl from "maplibre-gl"; import maplibreglStyle from "maplibre-gl/dist/maplibre-gl.css"; import { version as maplibreVersion } from "maplibre-gl/package.json"; import camelCase from "lodash.camelcase"; import kebabCase from "lodash.kebabcase"; const styleSheet = new CSSStyleSheet(); styleSheet.replaceSync(` ${maplibreglStyle} :host, .map { height: 100%; width: 100%; } `); const parseFloats = (value) => value.split(",").map(parseFloat); const properties = { mapStyle: { option: "style" }, zoom: { parseAttr: parseFloat }, center: { parseAttr: parseFloats }, pitch: { parseAttr: parseFloat }, bearing: { parseAttr: parseFloat }, maxBounds: { parseAttr: parseFloats }, bounds: { setter: "fitBounds", parseAttr: parseFloats }, }; class MapLibre extends HTMLElement { static observedAttributes = Object.keys(properties).map(kebabCase); options = {}; controls = []; #properties = {}; constructor() { super(); for (let [name, { option, setter, getter }] of Object.entries(properties)) { if (option === undefined) { option = name; } if (setter === undefined) { setter = camelCase(`set-${option}`); } if (getter === undefined) { getter = camelCase(`get-${option}`); } Object.defineProperty(this, name, { get: function () { if (this.map) { return this.map[getter](); } return this.#properties[option]; }, set: function (value) { if (this.map) { this.map[setter](value); } this.#properties[option] = value; }, }); } } attributeChangedCallback(name, oldValue, newValue) { const option = camelCase(name); if (properties[option]?.parseAttr) { this[option] = properties[option].parseAttr(newValue); } else { this[option] = newValue; } } async connectedCallback() { const shadow = this.attachShadow({ mode: "open" }); shadow.adoptedStyleSheets.push(styleSheet); const container = document.createElement("div"); container.classList.add("map"); shadow.appendChild(container); this.map = new maplibregl.Map({ ...this.options, ...this.#properties, container, }); for (const { type, options, position } of this.controls) { let control = type; if ( typeof type === "string" && type.endsWith("Control") && type in maplibregl ) { control = new maplibregl[type](options); } if (control) { this.map.addControl(control, position); } } } } export { MapLibre, maplibregl, maplibreVersion }; export default MapLibre;