利用Geoserver的wfs BBOX范围查询及Openlayers解析GML,添加Marker

本文介绍如何使用GeoServer的WFS服务进行地理数据查询,并通过OpenLayers在地图上显示查询结果。主要涉及WFS 1.0.0版本的查询语法、构造XML请求以及使用Ajax发送请求的具体步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 在经历了无数实验摸索及相关大侠的耐心收终于对Geoserve的wfs查询有了一定了解,现写出一点总结。
以下方法描述了对Geoserver进行范围查询,并将查询结果在用OpenLayers在地图上画出的实现方法。

首先wfs查询分为1.0.0和1.1.0两个版本,这两个版本的查询filter格式是不一样的,我是以1.0的格式写的,各位朋友可以研究一下1.1写法。
另外向Geoserver服务器发送请求,这里用到了prototype,在这里的prototype只是简单的发送了一个ajax请求。
比如要进行一个简单的范围查询,这里需要两个点来确定一下矩形,如:116.374614,39.949336和116.391498,39.955299
还要指定一个图层,比如:MyGis下的type图层,还有就是确定要返回的字段,如:NAME和TYPE,
整个的查询xml字符串如下:
<wfs:GetFeature service='WFS' version='1.0.0' outputFormat='GML2'
 xmlns:topp='http://www.openplans.org/topp' xmlns:wfs='http://www.opengis.net/wfs'
 xmlns:ogc='http://www.opengis.net/ogc' xmlns:gml='http://www.opengis.net/gml'
 xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
 xsi:schemaLocation='http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-basic.xsd'>
<wfs:Query typeName='MyGis:type'>
<wfs:PropertyName>MyGis:NAME</wfs:PropertyName>
<wfs:PropertyName>MyGis:TYPE</wfs:PropertyName>
<ogc:Filter><ogc:BBOX><ogc:PropertyName>the_geom</ogc:PropertyName>
<gml:Box srsName='http://www.opengis.net/gml/srs/epsg.xml#4326'>
<gml:coordinates>116.374614,39.949336 116.391498,39.955299</gml:coordinates>
</gml:Box></ogc:BBOX></ogc:Filter>
</wfs:Query></wfs:GetFeature>

Geoserver wfs查询的地址为:http://localhost:8080/geoserver/wfs

于是用Ajax.Request,发送一个ajax请求,代码如下:
var myAjax = new Ajax.Request( 
                GIS_SERVER_URL, 
                {contentType: "application/xml", method: 'post', postBody: xmlPara, onComplete: showResponse} 
                );
以上参数中: GIS_SERVER_URL为Geoserver wfs查询的地址,xmlPara为查询的xml字符串,showResponse为查询返回后的处理函数,
showResponse函数如下:
function showResponse(req){
 //openlayers的GML解析器
 var gmlParse = new OpenLayers.Format.GML();
 var features = gmlParse.read(req.responseText);
 var icon = new OpenLayers.Icon('images/pp.gif');

 var feature, lonlat, marker;
 for(var feat in features){   
  feature = features[feat];
  lonlat = new OpenLayers.LonLat(feature.geometry.x,feature.geometry.y);   
  marker = new OpenLayers.Marker(lonlat,icon.clone());  
  //此处注册了鼠标的点击事件,可以在mousedown中做些事情  
  marker.events.register("mousedown", marker, mousedown); 
  //markers为OpenLayers.Layer.Markers 画点的层
  markers.addMarker(marker);      
 }
}

以上便完成wfs查询并用openlayers标画结果的任务。
另外wfs的GetFeature还有许多查询功能,在Geoserver的样例查询中,有一些例子,比如主键查询,Between查询,更全面的功能就要看OGC WFS的白皮书了,filter可以实现如sql语句中的功能,不过白皮书中的讲解也不是很详细(可能是自己E文不够好吧~~),朋友们可以互相讨论一下~~

 

大家顺便可以看看我的这个网站

<think>我们正在使用高德地图的LabelMarker来加载WFS服务中的点图层。由于用户之前提到了使用OpenLayers处理大量点,但这里明确要求使用高德地图,因此我们将按照高德地图的API来实现。 步骤: 1. 在Vue项目中引入高德地图JS API Loader。 2. 初始化地图。 3. 通过WFS服务获取GeoJSON格式的点数据(注意:WFS服务需要支持返回GeoJSON,或者我们进行转换)。 4. 解析GeoJSON,使用LabelMarker将每个点渲染为标签标注。 注意: - WFS服务通常返回的是GML格式,但我们可以通过设置outputFormat为application/json来获取GeoJSON。 - 高德地图使用的是国测局坐标系(GCJ-02),如果WFS服务返回的是WGS84坐标(EPSG:4326),需要转换。但是,高德地图的API在2.0版本中,使用LngLat时,如果是WGS84坐标,需要明确指定,或者使用高德提供的转换方法。 实现方案: 1. 安装依赖: ```bash npm install @amap/amap-jsapi-loader --save ``` 2. 在Vue组件中实现: 我们将创建一个Vue组件,在该组件中: - 使用AMapLoader加载高德地图API。 - 初始化地图。 - 定义WFS服务的URL(注意:需要支持跨域或通过代理解决跨域问题)。 - 使用fetch获取WFS服务的GeoJSON数据。 - 遍历GeoJSON中的每个点要素,创建LabelMarker添加到地图。 3. 坐标转换:如果WFS服务返回的是WGS84坐标(即EPSG:4326),而高德地图的底图是GCJ-02,那么我们需要将坐标转换。但是,高德地图的LngLat对象在创建时,如果传入的是WGS84坐标,需要设置第三个参数为true(表示是GPS坐标),这样地图会内部转换。但注意,LabelMarker的position参数要求是AMap.LngLat对象,我们在创建时传入经纬度数组,并设置第三个参数为true。 然而,根据高德地图JS API 2.0文档,LngLat类在构造时,可以传入[经度, 纬度]和是否使用GPS坐标(即WGS84)。但需要注意的是,高德地图的覆盖物(包括Marker)在设置位置时,如果传入的是GPS坐标,会自动转换到GCJ-02坐标系。因此,我们可以在创建LngLat对象时,将第三个参数设为true(表示传入的是GPS坐标)。 但是,LabelMarker的position属性要求是LngLat对象,因此我们可以这样创建: new AMap.LngLat(lng, lat, true) 4. 性能考虑:如果点数据量很大,使用LabelMarker可能会影响性能。我们可以考虑使用点聚合(MassMarks)或者使用WebGL渲染(但LabelMarker本身是Canvas渲染,且不支持WebGL)。如果数据量特别大(如百万级),可能需要考虑使用其他方案,比如使用OpenLayers(如用户参考的引用[1])或者使用高德地图的Loca组件(WebGL渲染)。但用户明确要求使用LabelMarker,所以这里假设数据量在可接受范围内。 5. 代码结构: 我们将创建一个Vue单文件组件(SFC),在mounted生命周期中初始化地图和加载数据。 具体代码实现如下:</think>### Vue中使用高德地图LabelMarker加载WFS点图层方案 在Vue中整合高德地图的LabelMarkerWFS服务加载点图层,需解决两个核心问题:**WFS数据获取**和**LabelMarker标注渲染**。以下是具体实现方案: --- ### 一、实现步骤 #### 1. 基础环境配置 ```bash npm install @amap/amap-jsapi-loader --save ``` #### 2. Vue组件实现(核心代码) ```vue <template> <div id="map-container" style="height: 600px"></div> </template> <script> import AMapLoader from '@amap/amap-jsapi-loader'; export default { data() { return { map: null, // 指定WFS点图层配置 wfsLayerConfig: { name: "POI点图层", url: "https://geoserver.example.com/wfs?service=WFS&request=GetFeature&typename=your_layer_name&outputFormat=application/json", labelField: "name", // 使用哪个属性字段作为标签文本 labelOptions: { color: "#3366FF", fontSize: 14, backgroundColor: "rgba(255,255,255,0.7)" } } }; }, async mounted() { await this.initMap(); this.loadWFSLayer(); }, methods: { async initMap() { const AMap = await AMapLoader.load({ key: "您的高德地图Key", // 申请的高德API Key version: "2.0", plugins: ['AMap.LabelMarker'] }); this.map = new AMap.Map("map-container", { zoom: 12, center: [116.40, 39.90] // 以北京为中心 }); }, async loadWFSLayer() { try { // 添加代理解决跨域问题(开发环境) const proxyUrl = process.env.NODE_ENV === 'development' ? '/geoserver-proxy' : ''; const response = await fetch(proxyUrl + this.wfsLayerConfig.url); const geojson = await response.json(); this.renderLabelMarkers(geojson); } catch (error) { console.error(`加载${this.wfsLayerConfig.name}失败:`, error); } }, renderLabelMarkers(geojson) { const AMap = window.AMap; geojson.features.forEach(feature => { // 获取点坐标(WGS84坐标系) const [lng, lat] = feature.geometry.coordinates; // 创建标签标注 new AMap.LabelMarker({ position: new AMap.LngLat(lng, lat, true), // true表示输入为GPS坐标(WGS84) text: { content: feature.properties[this.wfsLayerConfig.labelField], style: { ...this.wfsLayerConfig.labelOptions, padding: '3,5', borderRadius: '3px' } }, // 添加点击事件 clickable: true }).on('click', (e) => { console.log('点击标注:', feature.properties); this.$emit('marker-click', feature.properties); }).setMap(this.map); }); } }, beforeDestroy() { // 组件销毁时清理地图 if (this.map) this.map.destroy(); } }; </script> ``` --- ### 二、关键配置说明 1. **WFS服务参数** - `service=WFS&request=GetFeature`:固定参数 - `typename`:图层名称(替换为实际图层名) - `outputFormat=application/json`:确保返回GeoJSON格式 ```javascript url: "https://geoserver.example.com/wfs?service=WFS&request=GetFeature&typename=poi_layer&outputFormat=application/json" ``` 2. **跨域解决方案** ```javascript // vue.config.js module.exports = { devServer: { proxy: { '/geoserver-proxy': { target: 'http://your-geoserver-host', changeOrigin: true, pathRewrite: { '^/geoserver-proxy': '' } } } } } ``` 3. **坐标系统一处理** ```javascript position: new AMap.LngLat(lng, lat, true) // 第三个参数true表示WGS84坐标 ``` --- ### 三、性能优化建议 1. **数据筛选** ```javascript // WFS请求添加空间过滤参数 const bbox = this.map.getBounds().toBoundsString(); const url = `${baseUrl}&bbox=${bbox},EPSG:4326`; ``` 2. **按需渲染** ```javascript // 监听地图缩放事件 this.map.on('zoomchange', () => { if (this.map.getZoom() > 14) { this.loadDetailLayer(); } }); ``` 3. **使用WebGL渲染(大数据量)** ```javascript // 使用Loca组件处理10万+数据点 const loca = new Loca.Container({ map: this.map }); const scatter = new Loca.ScatterLayer({ zIndex: 10 }); ``` --- ### 四、常见问题解决 1. **坐标偏移问题** ```javascript // 使用高德坐标转换API AMap.convertFrom([lng, lat], 'gps', (status, result) => { if (status === 'complete') { const amapCoord = result.locations[0]; } }); ``` 2. **动态更新数据** ```javascript // 清空图层 this.map.clearMap(); // 重新加载数据 this.loadWFSLayer(); ``` 3. **样式自定义** ```javascript text: { content: `<div class="custom-label">${text}</div>`, style: { // 使用HTML内容 } } ``` > **注意事项**: > 1. 高德地图JS API需使用合规的商用授权 > 2. WFS服务需支持CORS或通过代理访问 > 3. 数据量过大时(>1万点)建议使用Loca组件[^1] --- ### 相关问题 1. 如何在高德地图中实现WFS服务的空间查询(如矩形框选)? 2. LabelMarker如何自定义HTML内容而不仅是文本? 3. 大量点数据(>10万)渲染的性能优化方案有哪些? 4. 如何实现WFS图层与高德底图的坐标系统一? 5. Vue中如何封装可复用的地图图层组件? [^1]: Vue+OpenLayers7入门到实战:使用webgl图层叠加超大量Point点要素 [^2]: vue+mars3d叠加影像服务
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值