UNPKG

vgrid-maplibre

Version:
181 lines (157 loc) 6.31 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>A5 DGGS</title> <!-- MapLibre GL CSS --> <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> <!-- Map container --> <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 A5Grid from "https://unpkg.com/vgrid-maplibre/A5/A5Grid.js"; import A5Grid from './A5Grid.js'; // Initialize the map and grid const config = { lng: 106.706585, lat: 10.775326, zoom: 0 }; let currentPopup = null; const map = new maplibregl.Map({ container: 'map', // The ID of the HTML element where MapLibre will render center: [config.lng, config.lat], zoom: config.zoom, // 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', }) map.on('style.load', () => { map.addControl(new maplibregl.GlobeControl()); try { const a5Grid = new A5Grid(map, { color: 'rgba(255, 0, 0, 1)', width: 1.5, redraw: 'move', }); console.log('A5 Grid added successfully.'); } catch (error) { console.error('Failed to add A5 Grid:', error); } }); // Uncomment to display A5 label // map.on('sourcedata', (e) => { // if ( // e.sourceId === 'a5-grid' && // map.getSource('a5-grid') && // !map.getLayer('a5-labels') // ) { // map.addLayer({ // id: 'a5-labels', // type: 'symbol', // source: 'a5-grid', // layout: { // 'text-field': ['get', 'a5_id'], // 'text-size': 12, // }, // paint: { // 'text-halo-color': 'white', // halo color // 'text-halo-width': 1.5, // halo width // 'text-halo-blur': 0.5 // optional: smooth halo edges // }, // }); // } // }); map.on('click', (e) => { const features = map.queryRenderedFeatures(e.point, { layers: ['a5-grid-layer'] }); if (features.length) { const feature = features[0]; // Select the first feature if there are multiple const popupContent = ` <strong>A5 ID: </strong> ${feature.properties.a5_id} <br> <strong>Resolution: </strong> ${feature.properties.resolution} <br> `; const popup = new maplibregl.Popup() .setLngLat(e.lngLat) .setHTML(popupContent) .addTo(map); currentPopup = popup; if (!map.getLayer('highlight-layer')) { map.addLayer({ 'id': 'highlight-layer', 'type': 'fill', 'source': { 'type': 'geojson', 'data': { 'type': 'FeatureCollection', 'features': [] } }, 'paint': { 'fill-color': '#FF0000', 'fill-opacity': 0.2, } }); } map.getSource('highlight-layer').setData({ 'type': 'FeatureCollection', 'features': [feature] }); } }); map.on('contextmenu', () => { if (map.getLayer('highlight-layer')) { map.getSource('highlight-layer').setData({ 'type': 'FeatureCollection', 'features': [] }); } if (currentPopup) { currentPopup.remove(); currentPopup = null; } }); function exportToGeoJSON() { let features = map.queryRenderedFeatures({ layers: ['a5-grid-layer'] }); if (!features.length) { alert("No A5 grid features found in the current viewport."); return; } // Remove duplicates (some tiles can appear multiple times) // features = Array.from(new Map( // features.map(f => [f.properties.a5_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 = 'a5-grid-export.geojson'; a.click(); URL.revokeObjectURL(url); } window.exportToGeoJSON = exportToGeoJSON; </script> </body> </html>