如何在网站OpenLayers地图加载巴黎开放数据事故点位标记?
实现从巴黎开放数据API获取事故点位并在OpenLayers地图展示
核心步骤拆解
- 发起API请求获取事故数据,支持自定义筛选条件
- 解析返回数据中的坐标信息(处理
coordonnes字段) - 将解析后的点位转为OpenLayers要素并添加到地图
1. 构建带筛选条件的API请求地址
巴黎开放数据的Explore API支持通过where参数添加筛选条件,多个条件用AND/OR连接。示例如下:
const baseUrl = 'https://opendata.paris.fr/api/explore/v2.1/catalog/datasets/accidentologie0/records'; // 自定义筛选参数,可根据需求动态修改 const filters = { pim_bp: '1', com_arm_code: '75056', iris: '75101000' }; // 拼接where条件 const whereClause = Object.entries(filters) .map(([key, value]) => `${key}='${value}'`) .join(' AND '); // 完整请求地址,可调整limit控制返回数量 const requestUrl = `${baseUrl}?limit=100${whereClause ? `&where=${encodeURIComponent(whereClause)}` : ''}`;
2. 发起请求并解析坐标数据
使用原生fetch请求数据,解析返回的results数组,提取coordonnes中的经纬度(该字段为GeoPoint格式,包含lon和lat属性):
fetch(requestUrl) .then(response => response.json()) .then(data => { const features = data.results.map(accident => { // 解析坐标,优先用coordonnes,若有单独经纬度字段可替换 const { lon, lat } = accident.coordonnes; // 创建OpenLayers点要素 return new ol.Feature({ geometry: new ol.geom.Point(ol.proj.fromLonLat([lon, lat])), // 携带事故其他属性,用于后续交互展示 properties: accident }); }); // 将要素添加到矢量图层 vectorSource.addFeatures(features); }) .catch(error => console.error('数据请求失败:', error));
3. 整合到OpenLayers基础代码中
完整可运行示例代码:
<div id="map" style="width: 100%; height: 600px;"></div> <script src="https://cdn.jsdelivr.net/npm/ol@7.3.0/dist/ol.js"></script> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@7.3.0/ol.css"> <script> // 初始化地图 const map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ], view: new ol.View({ center: ol.proj.fromLonLat([2.3522, 48.8566]), // 巴黎中心坐标 zoom: 12 }) }); // 创建矢量数据源和图层 const vectorSource = new ol.source.Vector(); const vectorLayer = new ol.layer.Vector({ source: vectorSource, style: new ol.style.Style({ image: new ol.style.Icon({ src: 'https://cdn-icons-png.flaticon.com/512/126/126468.png', // 自定义标记图标,可替换 scale: 0.05 }) }) }); map.addLayer(vectorLayer); // 数据请求与添加标记 const baseUrl = 'https://opendata.paris.fr/api/explore/v2.1/catalog/datasets/accidentologie0/records'; const filters = { // 这里可根据需求动态修改筛选条件 }; const whereClause = Object.entries(filters) .map(([key, value]) => `${key}='${value}'`) .join(' AND '); const requestUrl = `${baseUrl}?limit=100${whereClause ? `&where=${encodeURIComponent(whereClause)}` : ''}`; fetch(requestUrl) .then(response => response.json()) .then(data => { const features = data.results.map(accident => { const { lon, lat } = accident.coordonnes; return new ol.Feature({ geometry: new ol.geom.Point(ol.proj.fromLonLat([lon, lat])), properties: accident }); }); vectorSource.addFeatures(features); }) .catch(error => console.error('数据请求失败:', error)); </script>
额外优化建议
- 动态筛选:通过页面表单收集用户输入的筛选条件,实时修改
filters对象并重新发起请求,同时调用vectorSource.clear()清空旧数据 - 点位交互:为标记添加点击事件,通过
ol.Overlay创建弹窗展示事故详细信息 - 分页处理:若数据量较大,使用API的
offset参数实现分页加载
内容的提问来源于stack exchange,提问作者leparc
相关产品推荐
相关产品推荐

