WebGIS开发中,点击查询是最常用的一种查询方式,在ArcGIS api 中,这种查询叫IdentifyTask,主要作用是前台提交参数,交ArcServer查询分析返回。本文从开源框架的角度,从前台到服务端到数据库等多个角度,多种方式实现点击查询。干货如下:
1.1 Select控制器
对于矢量数据,Ol3中的官网demo提供了一个Select控件,实现鼠标的选择查询,代码如下:
//定义select控制器 var select= new ol.interaction.Select(); map.addInteraction(select);//map加载该控件,默认是激活可用的 select.on('select', function(e) { console.log(e.selected); //打印已选择的Feature });
具体Example参考:
1.2 map的click事件
该方法,通过鼠标点击的坐标,与当前矢量图层做相交分析查询,得到查询的要素及其所属的Layer对象
//地图单机事件 map.on('singleclick',mapClick); function mapClick(e){ var pixel = map.getEventPixel(e.originalEvent); var featureInfo = map.forEachFeatureAtPixel(pixel, function (feature, layer) { return {feature:feature,layer:layer}; }); if (featureInfo!==undefined&&featureInfo!==null &&featureInfo.layer!==null) { console.log('打印选择要素'); console.log(featureInfo .feature); console.log('打印选择要素所属Layer'); console.log(featureInfo .layer); } }
1.3 WMS图层的GetFeatureInfo
对于矢量图层,我们可以通过第一,第二种方法实现点击查询。但是,很多时候我们底图是wms服务,这时候我们可以通过wms协议的GetFeatureInfo实现点点选查询。
//模拟查询的wms图层名称比如是wmsLayer //该wmsLayer的数据源是墨卡托的3857举例 map.on('click',mapClick); function mapClick(evt){ var viewResolution = map.getView().getResolution(); var url = wmsLayer.getSource().getGetFeatureInfoUrl( evt.coordinate, viewResolution, 'EPSG:3857', { 'INFO_FORMAT': 'text/javascript',//geoserver支持jsonp才能输出为jsonp的格式 'FEATURE_COUNT': 50 //点击查询能返回的数量上限 }); $.ajax({ type: 'GET', url:url, dataType: 'jsonp', jsonp:'format_options', jsonpCallback:"callback:success_jsonpCallback" }); } //回调函数接收查询结果 var geojsonFormat=new ol.format.GeoJSON({defaultDataProjection:"EPSG:3857"}); function success_jsonpCallback(res) { var features=geojsonFormat.readFeatures(res); console.log('点击查询返回的结果如下:'); console.log(features); }
1.4 通过Geoserver的wfs查询
wfs可以通过Filter提交条件或者图形进行属性查询或者空间查询,本段用干货来表达如何使用wfs查询。
map.on('click',mapClick); //点击地图查询 function mapClick(evt) { var coor=evt.coordinate; coor=coor.join(','); //注意这里直接将点坐标提交,与图层做intersrct分析,对于面图层是没关系的。如果是查询,点或者线图形,一定要将coor先设置一个容差,经行buffer之后的图形,再去与图层叠加分析。不设置容差几乎就找不到了 //图层的图形字段是geom,不同图层的图形字段都要自己先看下自己的,有的是the_geom,有的是shape等等,具体分析即可。 var FILTER='<Filter xmlns="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml"><Intersects><PropertyName>geom</PropertyName><gml:Point><gml:coordinates>'+coor+'</gml:coordinates></gml:Point> </Intersects></Filter>'; getFeature({ typename:'road:road_grid',//查询的服务图层名称 filter:FILTER,//查询条件 callback:'getIdentifyroadGrid'//查询的回调函数 }); } var geojsonFormat=new ol.format.GeoJSON({defaultDataProjection:"EPSG:3857"}); function getIdentifyroadGrid(res) { var features=geojsonFormat.readFeatures(res); console.log('点击查询返回的结果如下:'); console.log(features); } //请求wfs数据 function getFeature(options) { $.ajax(gisserverhost+'geoserver/wfs',{ type: 'GET', data: { service: 'WFS', version: '1.1.0', request: 'GetFeature', typename: options.typename, srsname: options.srid, outputFormat: 'text/javascript', viewparams:options.viewparams, bbox:(options.extent===undefined)?undefined:options.extent.join(',') + ','+options.srid, filter:options.filter }, dataType: 'jsonp', jsonpCallback:'callback:'+options.callback, jsonp:'format_options' }); }
1.5 通过PostGIS实现点击查询
pg的方法真要用起来应该是最简单的。就是将点击的地理坐标发送到后台提交数据库执行下。
//其他省略,假设x,y是前台点击地图获取的坐标,坐标系假设只3857。 //这里假设后台获取了参数拼接sql提交数据库
执行sql如下: select * from t where ST_Intersect(t.geom,ST_GeomfromText('Point(x y)',3857));
完毕!
总结