UNPKG

vgrid-maplibre

Version:
186 lines (165 loc) 6.09 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>GARS DGGS</title> <link rel="stylesheet" href="https://unpkg.com/maplibre-gl/dist/maplibre-gl.css" /> <style> body { margin: 0; padding: 0; } #map { width: 100%; height: 100vh; } </style> </head> <body> <div id="map"></div> <script src="https://unpkg.com/maplibre-gl/dist/maplibre-gl.js"></script> <button onclick="exportToGeoJSON()" style="position: absolute; top: 10px; left: 10px;"> Export </button> <script type="module"> import GARSGrid from "https://unpkg.com/vgrid-maplibre/GARS/GARSGrid.js"; // import GARSGrid from './GARSGrid.js'; const config = { lng: 106.706585, lat: 10.775326, zoom: 6 }; let currentPopup = null; // Initialize MapLibre map const map = new maplibregl.Map({ container: 'map', // Map container ID // style: 'https://demotiles.maplibre.org/style.json', // MapLibre style URL // style: 'https://raw.githubusercontent.com/opengeoshub/vstyles/main/vstyles/omt/fiord/fiord.json', // style: 'https://raw.githubusercontent.com/opengeoshub/vstyles/main/vstyles/omt/positron/positron.json', style: 'https://raw.githubusercontent.com/opengeoshub/vstyles/main/vstyles/sbr/eclipse/eclipse.json', center: [config.lng, config.lat], zoom: config.zoom, }); // Add the gars Locator Grid when the map loads map.on('style.load', () => { map.addControl(new maplibregl.GlobeControl()); try { const garsGrid = new GARSGrid(map, { color: 'rgba(255, 0, 0, 1)', width: 1.5, minzoom: 6, redraw: 'move', }); console.log('GARS Grid added successfully.'); } catch (error) { console.error('Failed to add GARS Grid:', error); } }); // Wait for the source to become available before adding label layer map.on('sourcedata', (e) => { if ( e.sourceId === 'gars-grid' && map.getSource('gars-grid') && !map.getLayer('gars-labels') ) { map.addLayer({ id: 'gars-labels', type: 'symbol', source: 'gars-grid', layout: { 'text-field': ['get', 'gars_id'], 'text-size': 12, }, paint: { // 'text-color': 'rgba(255, 0, 0, 1)', 'text-halo-color': 'white', // halo color 'text-halo-width': 1, // halo width 'text-halo-blur': 0.2 // optional: smooth halo edges }, }); } }); map.on('click', (e) => { const features = map.queryRenderedFeatures(e.point, { layers: ['gars-grid-layer'] // This should match the layer name where hexagons are rendered }); if (features.length) { const feature = features[0]; // Select the first feature if there are multiple // Create a popup with the feature properties const popupContent = ` <strong>GARS ID: </strong> ${feature.properties.gars_id} <br> <strong>Resolution: </strong> ${feature.properties.resolution} <br> `; // Create a popup and set its coordinates const popup = new maplibregl.Popup() .setLngLat(e.lngLat) // Position the popup at the clicked location .setHTML(popupContent) // Set the HTML content for the popup .addTo(map); // Add the popup to the map currentPopup = popup; // Add a highlight layer if it doesn't exist yet if (!map.getLayer('highlight-layer')) { map.addLayer({ 'id': 'highlight-layer', 'type': 'fill', 'source': { 'type': 'geojson', 'data': { 'type': 'FeatureCollection', 'features': [] } }, 'paint': { 'fill-color': '#FF0000', // Red color for highlight 'fill-opacity': 0.2, // Set transparency of the highlight } }); } // Update the source of the highlight layer with the clicked feature's geometry map.getSource('highlight-layer').setData({ 'type': 'FeatureCollection', 'features': [feature] }); } }); map.on('contextmenu', () => { // Remove the highlight layer by clearing its source data if (map.getLayer('highlight-layer')) { map.getSource('highlight-layer').setData({ 'type': 'FeatureCollection', 'features': [] // Clear the data to remove the highlight }); } // Remove the current popup (if any) from the map if (currentPopup) { currentPopup.remove(); currentPopup = null; // Reset the currentPopup variable } }); function exportToGeoJSON() { const features = map.queryRenderedFeatures({ layers: ['gars-grid-layer'] }); if (!features.length) { alert("No GARS grid features found in the current viewport."); return; } // Remove duplicates (some tiles can appear multiple times) // const uniqueFeatures = Array.from(new Map( // features.map(f => [f.properties.gars_id, f]) // ).values()); const geojson = { type: 'FeatureCollection', features: features }; // Download as GeoJSON file const blob = new Blob([JSON.stringify(geojson, null, 2)], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'gars-grid-export.geojson'; a.click(); URL.revokeObjectURL(url); } window.exportToGeoJSON = exportToGeoJSON; </script> </body> </html>