OpenLayers 3+Geoserver+PostGIS實現點選查詢
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
});
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));
完畢!
總結
觸類旁通,融會貫通,一個問題的解決一定有很多方式,並非“自古華山一條路”,當然,不同的路的目的相同,風景當然是各異。我們已經起碼能使用5種方法去獲取點選查詢的結果。那麼一般人就會疑問,5種方法究竟誰好誰壞了? 其實方法沒有好壞,只有是否合適。
1 第一種,第二種方法:向量資料,一定要加到map的客戶端,才能使用,如果是wms圖層就不能用了。
2 第三種方法:wms圖層,這時候前兩種向量方式沒法處理,第三種方法就可以解決這個問題。
3 第四種方法:一二三無論向量還是wms,都是要載入到客戶端才能使用,但有時候因需求不同導致的,Geoserver釋出的圖層不載入到客戶端,那麼就都不能使用了。但只要被髮布了,通過wfs的url請求就一定能查詢到結果,即使這個查詢物件不在客戶端而在服務端。
4 第五種方法:與第四種方法一樣,因為業務需求不同導致,有時資料連發布都沒釋出,僅僅停留在資料庫中,而要求能夠查詢,這時候第五個方法即可。當然資料庫中的方法,一般用在大資料量,複雜事務查詢中使用較好。單單一個點選查詢使用有點牛刀殺雞。
關於Ol3+GeoServer+PostGIS框架交流請進入qq群:445307545
關於Ol3交流請進入qq群:274788071
有償GIS技術指導請聯絡:674834420