openlayers中單擊獲取要素


openlayers中單擊獲取要素

版權聲明:本文為博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
本文鏈接: https://blog.csdn.net/xcymorningsun/article/details/82492384

目錄

 

 

一、引言

 

二、前台方法

 

1、interaction中select方法

 

2、map中forEachFeatureAtPixel方法

 

三、gis server方法

 

1、wms中getfeatureinfo

 

2、wfs中getfeature

 

四、后台方法

 

五、空間數據庫方法

 

六、總結

 


 

一、引言

 

以前在做arcgis js開發的時候,就開始糾結單擊獲取要素使用哪種方法,當時是因為arcgis server正好提供了arcgis定制的服務IdentifyTask,所以當時用了arcgis server查詢的。

總結一下查詢方法有如下幾種:

這四種各有優缺點,下面詳細介紹前兩種方法,后面兩種方法涉及到的知識比較多,不方便展開,僅提供思路==

 

二、前台方法

 

1、interaction中select方法

 

針對矢量數據源,openlayers中提供了select交互類方面鼠標選擇。

  1.  
    /*overlay*/
  2.  
    // Popup showing the position the user clicked
  3.  
    var popup = new ol.Overlay({
  4.  
    element: document.getElementById('popup'),
  5.  
    autoPan:true,
  6.  
    autoPanMargin:100,
  7.  
    positioning:'center-right'
  8.  
    });
  9.  
    map.addOverlay(popup);
  10.  
     
  11.  
    /*select*/
  12.  
    var selectSingleClick = new ol.interaction.Select();
  13.  
    map.addInteraction(selectSingleClick);
  14.  
    /*前端第一種*/
  15.  
    selectSingleClick.on( 'select', function(e) {
  16.  
    var features=e.target.getFeatures().getArray();
  17.  
    var element = popup.getElement();
  18.  
    if (features.length>0)
  19.  
    {
  20.  
    var feature=features[0];
  21.  
    var type=feature.getGeometry().getType();
  22.  
    var property=feature.getProperties();
  23.  
    var coordinate = ol.extent.getCenter(feature.getGeometry().getExtent());
  24.  
    var hdms="點名:"+property["Text"];
  25.  
    hdms=hdms+ "<br/>";
  26.  
    hdms = hdms+ "圖層名::"+property["Layer"];
  27.  
    hdms=hdms+ "<br/>";
  28.  
    hdms = hdms+ "位置:"+coordinate[0]+"-"+coordinate[1];
  29.  
     
  30.  
    $(element).popover( 'destroy');
  31.  
    popup.setPosition(coordinate);
  32.  
    // the keys are quoted to prevent renaming in ADVANCED mode.
  33.  
    $(element).popover({
  34.  
    'placement': 'top',
  35.  
    'animation': false,
  36.  
    'html': true,
  37.  
    'content': hdms
  38.  
    });
  39.  
    $(element).popover( 'show');
  40.  
    }
  41.  
    else
  42.  
    {
  43.  
    $(element).popover( 'destroy');
  44.  
     
  45.  
    }
  46.  
     
  47.  
    });

這里popup是個overlay覆蓋物,用於彈出框顯示得到的feature要素。

 

2、map中forEachFeatureAtPixel方法

 

針對矢量數據源,通過鼠標點擊坐標與map坐標對比,獲取選中要素,openlayers提供了相關函數。

  1.  
    /*前端第二種*/
  2.  
    map.on( "click", function(e) {
  3.  
    var element = popup.getElement();
  4.  
    $(element).popover( 'destroy');
  5.  
    map.forEachFeatureAtPixel(e.pixel, function (feature, layer) {
  6.  
    //do something
  7.  
    var type=feature.getGeometry().getType();
  8.  
    var property=feature.getProperties();
  9.  
    var coordinate = ol.extent.getCenter(feature.getGeometry().getExtent());
  10.  
    var hdms="點名:"+property["Text"];
  11.  
    hdms=hdms+ "<br/>";
  12.  
    hdms = hdms+ "圖層名::"+property["Layer"];
  13.  
    hdms=hdms+ "<br/>";
  14.  
    hdms = hdms+ "位置:"+coordinate[0]+"-"+coordinate[1];
  15.  
     
  16.  
    $(element).popover( 'destroy');
  17.  
    popup.setPosition(coordinate);
  18.  
    // the keys are quoted to prevent renaming in ADVANCED mode.
  19.  
    $(element).popover({
  20.  
    'placement': 'top',
  21.  
    'animation': false,
  22.  
    'html': true,
  23.  
    'content': hdms
  24.  
    });
  25.  
    $(element).popover( 'show');
  26.  
    })
  27.  
    });

這里省略了popup,與上個例子中類似。

 

三、gis server方法

 

1、wms中getfeatureinfo

 

針對沒有顯示到地圖上,但是有wms的圖層數據,我們可以使用getfeatureinfo從geoserver(或者其他支持wms的gis服務器)獲取要素,這個是跟ogc標准相關的,與具體的gis服務器無關。

  1.  
    var format = 'image/png';
  2.  
    var wmsLayer = new ol.layer.Tile({
  3.  
    //visible: false,
  4.  
    source: new ol.source.TileWMS({
  5.  
    url: 'http://localhost:8080/geoserver/xcy/wms',
  6.  
    params: {'FORMAT': format,
  7.  
    'VERSION': '1.1.1',
  8.  
    tiled: true,
  9.  
    "STYLES": '',
  10.  
    "LAYERS": 'xcy:polygon'
  11.  
    //"exceptions": 'application/vnd.ogc.se_inimage',
  12.  
    //tilesOrigin: 8176078.237520734 + "," + 704818.0275364731
  13.  
    },
  14.  
    serverType: 'geoserver',
  15.  
    crossOrigin: 'anonymous'
  16.  
    })
  17.  
    });
  18.  
     
  19.  
    map.on( 'singleclick', function(evt) {
  20.  
    document.getElementById('info').innerHTML = '';
  21.  
    var viewResolution = /** @type {number} */ (view.getResolution());
  22.  
    var url = wmsLayer.getSource().getGetFeatureInfoUrl(
  23.  
    evt.coordinate, viewResolution, 'EPSG:3857',
  24.  
    { 'INFO_FORMAT': 'application/json'});
  25.  
    var element = popup.getElement();
  26.  
    $(element).popover( 'destroy');
  27.  
     
  28.  
    if (url) {
  29.  
    $.ajax({
  30.  
    type: "GET",
  31.  
    url: url,
  32.  
    dataType:'json',
  33.  
    //data: {id:1001},//也可以是字符串鏈接"id=1001",建議用對象
  34.  
    success: function(data){
  35.  
    console.log("返回的數據: " + data.features[0].properties.Layer);
  36.  
    var layer=data.features[0].properties.Layer;
  37.  
    var hdms = "圖層名::"+layer;
  38.  
     
  39.  
    $(element).popover({
  40.  
    'placement': 'top',
  41.  
    'animation': false,
  42.  
    'html': true,
  43.  
    'content': hdms
  44.  
    });
  45.  
    popup.setPosition(evt.coordinate);
  46.  
    $(element).popover( 'show');
  47.  
    }
  48.  
    });
  49.  
     
  50.  
    }
  51.  
    });

首先獲取wms的當前圖層,然后拼接wms服務getfeatureinfo的url拼接,這里使用的函數獲取,也可以直接按照ogc標准自己拼接url。

 

2、wfs中getfeature

 

針對沒有顯示到地圖上但是有wfs服務的圖層數據,可以使用getfeature的方法從gis服務器中獲取要素信息,只要服務器提供ogc標准的wfs服務即可,它與wms的區別是wms中getfeatureinfo只是通過點獲取要素信息,方法比較單一,而wfs中getfeature可以使用filter進行復雜的空間查詢和屬性查詢,還可以通過bbox過濾空間信息。

  1.  
    /*gis server第二種*/
  2.  
    map.on( 'click',mapClick);
  3.  
    //點擊地圖查詢
  4.  
    function mapClick(evt)
  5.  
    {
  6.  
    var element = popup.getElement();
  7.  
    $(element).popover( 'destroy');
  8.  
     
  9.  
    var coor=evt.coordinate;
  10.  
    coor=coor.join( ',');
  11.  
    //注意這里直接將點坐標提交,與圖層做intersrct分析,對於面圖層是沒關系的。如果是查詢,點或者線圖形,一定要將coor先設置一個容差,經行buffer之后的圖形,再去與圖層疊加分析。不設置容差幾乎就找不到了
  12.  
    //圖層的圖形字段是geom,不同圖層的圖形字段都要自己先看下自己的,有的是the_geom,有的是shape等等,具體分析即可。
  13.  
    var filter='filter=<Filter xmlns="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml"><Intersects><PropertyName>the_geom</PropertyName><gml:Point><gml:coordinates>'+coor+'</gml:coordinates></gml:Point></Intersects></Filter>'
  14.  
     
  15.  
    $.ajax({
  16.  
    type: "GET",
  17.  
    //url: "http://localhost:8080/geoserver/xcy/wfs?service=WFS&request=GetFeature&version=1.1.0&typename=xcy:polygon&outputFormat=json&CQL_FILTER=EntityHand='7E25'",
  18.  
    //屬性查詢
  19.  
    //url: "http://localhost:8080/geoserver/xcy/wfs?service=WFS&request=GetFeature&version=1.1.0&typename=xcy:polygon&outputFormat=json&PROPERTYNAME=Layer&FEATUREID=polygon.2",
  20.  
    //空間查詢
  21.  
    url: 'http://localhost:8080/geoserver/xcy/wfs?service=WFS&request=GetFeature&version=1.1.0&typename=xcy:polygon&outputFormat=json&'+filter ,
  22.  
     
  23.  
    dataType:'json',
  24.  
    success: function(data){
  25.  
    console.log("返回的數據: " + data.features[0].properties.Layer);
  26.  
    var layer=data.features[0].properties.Layer;
  27.  
    var hdms = "圖層名::"+layer;
  28.  
     
  29.  
    $(element).popover({
  30.  
    'placement': 'top',
  31.  
    'animation': false,
  32.  
    'html': true,
  33.  
    'content': hdms
  34.  
    });
  35.  
    popup.setPosition(evt.coordinate);
  36.  
    $(element).popover( 'show');
  37.  
    }
  38.  
     
  39.  
    });
  40.  
    }

前兩個url是屬性查詢,使用的url是通過filter進行一個點的空間查詢,詳細wfs服務可以查看http://docs.opengeospatial.org/is/04-094r1/04-094r1.html#118

空間查詢還是比較復雜的,filter中的xml還需詳細理解一下。

 

四、后台方法

 

最近出了個紅芯瀏覽器,用的谷歌的內核,包裝了下外表就說自主研發的,讓人啼笑皆非,不過在碼農的世界里沒有利益,有現成的可以解決問題還是要善於借鑒的,這里可以使用AE或者geotool。

AE是arcgis的,C#陣營可以使用;geotool是開源的,java陣營比較方便。

 

首先使用正常的web框架,將點擊坐標參數傳到后台,用geojson或者自定義字符串隨意,只要你能解析出來;

后台集成了AE或者geotool之后可以通過里面的空間分析或者屬性分析工具,查出要查詢的要素;

最后使用json返回,格式你自己定咯;

 

 

五、空間數據庫方法

 

這種方法與后台方法類似,縣將點擊坐標參數傳到后台,只不過沒有使用的AE或者geotool來進行空間分析,而是直接使用空間數據庫中的空間查詢sql語句來查詢數據,然后提交到后台,后台提交到前台顯示。

執行sql如下: select * from t where ST_Intersect(t.geom,ST_GeomfromText('Point(x y)',3857));

 

六、總結

 

這幾種方法沒有絕對的好與壞,只是適合不適合的問題。

  • 前台:矢量數據,必須加載到地圖,如果沒有加載或者是wms就不可以了。這種方法比較方便,僅學習openlayers就可以,但是換了前端js框架就完戲;

 

  • gis server:數據發布為wms或者wfs,不必須加載到地圖。可以看作提供地圖數據的普通server,只要數據被發布就可以查詢到,而且符合ogc標准,許多外部的數據可以為我所用;

 

  • 后台:提供接口,不必須加載到地圖,相當於使用第三方庫做了一個gis server。不符合ogc發布標准,但是定制化程度高,不過依賴第三方庫,不用gis server發布數據,AE還要收費的;

 

  • 空間數據庫:提供接口,不必須加載到地圖,相當於在空間數據庫基礎上做了gis server。不符合ogc發布標准,定制化程度高,不依賴第三方庫,不用gis server發布數據,需要數據庫空間拓展,相對於后台方法比較適合處理大量數據,一個點擊事件用數據庫有點高射炮打蚊子了==

 

一個點擊獲取要素搞這么多種方法,有必要搞得這么復雜么?是的,單獨從解決問題的角度我們並沒有必要這么做,但是從這個過程中鍛煉的是一種思想,數據從前台、后台、普通server、gis server、數據庫等獲取的各種手段,這個不僅在點擊事件有這么多種方法,往大里講整個系統架構也無非是這么幾種。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM