vgrid-maplibre
Version:
DGGS Visualization for MapLibre GL JS
184 lines (162 loc) • 6.08 kB
HTML
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>QTM 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 QTMGrid from "https://unpkg.com/vgrid-maplibre/QTM/QTMGrid.js";
// import QTMGrid from './QTMGrid.js';
const config = {
lng: 106.706585,
lat: 10.775326,
zoom: 0
};
let currentPopup = null;
// Initialize MapLibre map
const map = new maplibregl.Map({
container: 'map', // Map container ID
// style: 'https://raw.githubusercontent.com/opengeoshub/vstyles/main/vstyles/omt/fiord/fiord.json',
// style: 'https://demotiles.maplibre.org/style.json', // MapLibre style URL
// 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,
});
map.on('style.load', () => {
map.addControl(new maplibregl.GlobeControl());
try {
const qtmGrid = new QTMGrid(map, {
color: 'rgba(255, 0, 0, 1)',
width: 1.5,
redraw: 'move',
});
console.log('QTM Grid added successfully.');
} catch (error) {
console.error('Failed to add QTM Grid:', error);
}
});
// Wait for the source to become available before adding label layer
map.on('sourcedata', (e) => {
if (
e.sourceId === 'qtm-grid' &&
map.getSource('qtm-grid') &&
!map.getLayer('qtm-labels')
) {
map.addLayer({
id: 'qtm-labels',
type: 'symbol',
source: 'qtm-grid',
layout: {
'text-field': ['get', 'qtm_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: ['qtm-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>QTM ID: </strong> ${feature.properties.qtm_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: ['qtm-grid-layer'] });
if (!features.length) {
alert("No QTM 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.qtm_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 = 'qtm-grid-export.geojson';
a.click();
URL.revokeObjectURL(url);
}
window.exportToGeoJSON = exportToGeoJSON;
</script>
</body>
</html>