diff --git a/html/static/js/map-libre-test.js b/html/static/js/map-libre-test.js new file mode 100644 index 00000000..f0d455c8 --- /dev/null +++ b/html/static/js/map-libre-test.js @@ -0,0 +1,166 @@ +// A test of maplibre-gl in a custom element +class MapLibreTest extends HTMLElement { + constructor() { + super(); + + // Create a shadow DOM + this.attachShadow({ mode: "open" }); + + // Initial render + this.render(); + + this._map = null; + + // markers shown on the map + this._markers = []; + } + + // Lifecycle: when element is added to the DOM + connectedCallback() { + // Initialize the map when the element is added to the DOM + setTimeout(() => this._initializeMap(), 0); + } + + disconnectedCallback() { + if (this._map) { + this._map.remove(); + } + } + + // Lifecycle: watch these attributes for changes + static get observedAttributes() { + return ["latitude", "longitude", "zoom"]; + } + + // Lifecycle: respond to attribute changes + attributeChangedCallback(name, oldValue, newValue) { + // Only handle if map exists and values actually changed + if (!this._map || oldValue === newValue) return; + + if (name === "latitude" || name === "longitude") { + if (this.hasAttribute("latitude") && this.hasAttribute("longitude")) { + const lat = Number(this.getAttribute("latitude")); + const lng = Number(this.getAttribute("longitude")); + this._map.setCenter([lat, lng]); + } + } + + if (name === "zoom") { + this._map.setZoom(Number(newValue)); + } + } + + _initializeMap() { + const apiKey = this.getAttribute("api-key"); + const lat = Number(this.getAttribute("latitude") || 36.2); + const lng = Number(this.getAttribute("longitude") || -119.2); + const mapElement = this.shadowRoot.querySelector("#map"); + const tegola = this.getAttribute("tegola"); + const zoom = Number(this.getAttribute("zoom") || 15); + + this._map = new maplibregl.Map({ + container: mapElement, + center: { + lat: lat, + lng: lng, + }, + style: "https://tiles.stadiamaps.com/styles/alidade_smooth.json", // Style URL; see our documentation for more options + zoom: zoom, + }); + this._map.on("load", () => { + this.dispatchEvent(new CustomEvent("load"), { + bubbles: true, + composed: true, // Allows event to cross shadow DOM boundary + detail: { + map: this, + }, + }); + }); + } + + // Initial render of component + render() { + this.shadowRoot.innerHTML = ` + + +
+
+
+ `; + } + + addLayer(a) { + return this._map.addLayer(a); + } + addSource(a, b) { + return this._map.addSource(a, b); + } + jumpTo(args) { + return this._map.jumpTo(args); + } + on(a, b) { + return this._map.on(a, b); + } + once(a, b) { + return this._map.once(a, b); + } + queryRenderedFeatures(a) { + return this._map.queryRenderedFeatures(a); + } + + setMarker(coords) { + console.log("Setting map marker", coords); + this._map.jumpTo({ + center: coords, + zoom: 14, + }); + this._markers.forEach((marker) => marker.remove()); + + const marker = new mapboxgl.Marker({ + color: "#FF0000", + draggable: true, + }) + .setLngLat(coords) + .addTo(map); + marker.on("dragend", function (e) { + const markerDraggedEvent = new CustomEvent("markerdragend", { + detail: { + marker: marker, + }, + }); + mapContainer.dispatchEvent(markerDraggedEvent); + }); + this._markers = [marker]; + } + + SetLayoutProperty(layout, property, value) { + return this._map.setLayoutProperty(layout, property, value); + } +} + +customElements.define("map-libre-test", MapLibreTest); diff --git a/html/template/sync/pool-by-id.html b/html/template/sync/pool-by-id.html index e96e42d7..5fc20f54 100644 --- a/html/template/sync/pool-by-id.html +++ b/html/template/sync/pool-by-id.html @@ -2,6 +2,39 @@ {{ define "title" }}Pool Upload{{ end }} {{ define "extraheader" }} + + + {{ end }} {{ define "content" }}
@@ -56,6 +89,9 @@
+
+ +