vgrid-maplibre
Version:
DGGS Visualization for MapLibre GL JS
184 lines (160 loc) • 6.59 kB
HTML
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tilecode 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 TilecodeGrid from "https://unpkg.com/vgrid-maplibre/Tilecode/TilecodeGrid.js";
// import TilecodeGrid from './tilecodeGrid.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());
// map.showTileBoundaries = true;
try {
const tilecodeGrid = new TilecodeGrid(map, {
color: 'rgba(255, 0, 0, 1)',
width: 1.5,
redraw: 'move',
});
console.log('Tilecode Grid added successfully.');
} catch (error) {
console.error('Failed to add Tilecode Grid:', error);
}
});
// Uncomment to display tilecode label
map.on('sourcedata', (e) => {
if (
e.sourceId === 'tilecode-grid' &&
map.getSource('tilecode-grid') &&
!map.getLayer('tilecode-labels')
) {
map.addLayer({
id: 'tilecode-labels',
type: 'symbol',
source: 'tilecode-grid',
layout: {
'text-field': ['get', 'tilecode_id'],
'text-size': 12,
},
paint: {
// 'text-color': 'red', // halo color
'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: ['tilecode-grid-layer']
});
if (features.length) {
const feature = features[0]; // Select the first feature if there are multiple
const popupContent = `
<strong>Tilecode: </strong> ${feature.properties.tilecode_id} <br>
<strong>Quadkey: </strong> ${feature.properties.quadkey_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: ['tilecode-grid-layer'] });
if (!features.length) {
alert("No tilecode 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.tilecode_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 = 'tilecode-grid-export.geojson';
a.click();
URL.revokeObjectURL(url);
}
window.exportToGeoJSON = exportToGeoJSON;
</script>
</body>
</html>