// leaflet_map_component.js import { LitElement, html, css, } from 'https://cdn.jsdelivr.net/gh/lit/dist@3/core/lit-core.min.js'; import 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js'; // Leaflet CDN export class LeafletMapComponent extends LitElement { static properties = { center: {type: Array}, // Expecting [latitude, longitude] zoom: {type: Number}, markers: {type: Array}, // Array of marker objects clickEvent: {type: String}, // Event handler ID for clicks }; static styles = css` #map { height: 400px; /* Adjust map height as needed */ width: 100%; } `; constructor() { super(); this.center = [0.0, 0.0]; this.zoom = 13; this.markers = []; this.clickEvent = ''; this._map = null; // Internal Leaflet map instance } firstUpdated() { this._initializeMap(); } updated(changedProperties) { if (changedProperties.has('center') || changedProperties.has('zoom')) { this._updateMapView(); } if (changedProperties.has('markers')) { this._updateMarkers(); } } _initializeMap() { if (this._map) return; // Prevent re-initialization this._map = L.map(this.shadowRoot.querySelector('#map')).setView( this.center, this.zoom, ); L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 19, attribution: '© OpenStreetMap', }).addTo(this._map); this._map.on('click', (event) => { if (this.clickEvent) { this.dispatchEvent( new MesopEvent(this.clickEvent, { latlng: [event.latlng.lat, event.latlng.lng], // Send latlng back to Python }), ); } }); this._updateMarkers(); // Initial marker rendering } _updateMapView() { if (this._map) { this._map.setView(this.center, this.zoom); } } _updateMarkers() { if (!this._map) return; // Clear existing markers if (this._markerLayer) { this._map.removeLayer(this._markerLayer); } this._markerLayer = L.layerGroup().addTo(this._map); // Layer group for efficient marker management this.markers.forEach((markerData) => { const marker = L.marker(markerData.latlng); if (markerData.popup_content) { marker.bindPopup(markerData.popup_content); } marker.addTo(this._markerLayer); }); } render() { return html`
`; } } customElements.define('leaflet-map-component', LeafletMapComponent);