查看本地GeoJSON文件(实验性)
使用文件系统访问API加载本地GeoJSON文件(实验性功能);
<!DOCTYPE html>
<html lang="en">
<head>
<title>查看本地GeoJSON文件(实验性)</title>
<meta property="og:description" content="使用文件系统访问API加载本地GeoJSON文件(实验性功能)" />
<meta charset='utf-8'>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel='stylesheet' href='https://unpkg.com/maplibre-gl@5.5.0/dist/maplibre-gl.css' />
<script src='https://unpkg.com/maplibre-gl@5.5.0/dist/maplibre-gl.js'></script>
<style>
body { margin: 0; padding: 0; }
html, body, #map { height: 100%; }
#btnOpenFile {
position: absolute;
top: 10px;
left: 10px;
z-index: 1;
padding: 8px 12px;
background: white;
border: 1px solid #ccc;
border-radius: 3px;
cursor: pointer;
font-family: 'Helvetica Neue', sans-serif;
}
</style>
</head>
<body>
<div id="map"></div>
<button id="btnOpenFile">选择本地GeoJSON文件</button>
<script>
// 此示例使用文件系统访问API,这是一项现代的Web API
// 它使Web应用能够与用户本地文件系统交互
// 目前仅在支持此API的浏览器中可用(如最新版Chrome)
// 创建地图
const map = new maplibregl.Map({
container: 'map',
style: 'https://api.maptiler.com/maps/streets/style.json?key=get_your_own_OpIi9ZULNHzrESv6T2vL',
center: [0, 0],
zoom: 1
});
const viewbutton = document.getElementById('btnOpenFile');
async function buttonClickHandler() {
// 使用文件系统访问API打开文件选择器,仅接受.geojson和.json文件
const [fileHandle] = await window.showOpenFilePicker({
types: [
{
description: 'GeoJSON Files',
accept: {
'application/geo+json': ['.geojson', '.json']
}
}
],
excludeAcceptAllOption: true,
multiple: false
});
// 读取文件内容
const file = await fileHandle.getFile();
const contents = await file.text();
// 将文件解析为JSON并作为数据源添加到地图
// 如果已存在源,先移除它
if (map.getSource('uploaded-source')) {
if (map.getLayer('uploaded-polygons')) {
map.removeLayer('uploaded-polygons');
}
map.removeSource('uploaded-source');
}
// 解析文件内容并添加到地图
try {
const geoJsonData = JSON.parse(contents);
map.addSource('uploaded-source', {
'type': 'geojson',
'data': geoJsonData
});
map.addLayer({
'id': 'uploaded-polygons',
'type': 'fill',
'source': 'uploaded-source',
'paint': {
'fill-color': '#888888',
'fill-outline-color': 'red',
'fill-opacity': 0.4
},
// 筛选多边形;如果要显示线条或点,
// 请添加更多带有不同筛选器的图层
'filter': ['==', '$type', 'Polygon']
});
// 自动调整地图视图以适应所加载的GeoJSON数据
try {
const bounds = new maplibregl.LngLatBounds();
geoJsonData.features.forEach(feature => {
if (feature.geometry && feature.geometry.coordinates) {
if (feature.geometry.type === 'Point') {
bounds.extend(feature.geometry.coordinates);
} else if (feature.geometry.type === 'LineString' || feature.geometry.type === 'Polygon') {
feature.geometry.coordinates.forEach(coord => {
// 对于多边形,coords是一个点数组,对于线条,coords是点本身
if (Array.isArray(coord[0])) {
coord.forEach(c => bounds.extend(c));
} else {
bounds.extend(coord);
}
});
}
}
});
if (!bounds.isEmpty()) {
map.fitBounds(bounds, { padding: 50 });
}
} catch (e) {
console.error('无法计算边界', e);
}
} catch (e) {
alert('无法解析GeoJSON文件: ' + e.message);
console.error('解析错误', e);
}
}
// 只有在浏览器支持文件系统访问API时才启用按钮
if ('showOpenFilePicker' in window) {
viewbutton.addEventListener('click', buttonClickHandler);
} else {
viewbutton.innerText = '您的浏览器不支持文件系统访问API';
viewbutton.disabled = true;
// 如果需要备选方案,可以尝试使用<input type="file">,但这会使用传统文件上传方式
}
</script>
</body>
</html>