openlayers中单击获取要素

分类专栏: GIS 总结 OpenLayers
 
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。

目录

一、引言

二、前台方法

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、数据库等获取的各种手段,这个不仅在点击事件有这么多种方法,往大里讲整个系统架构也无非是这么几种。

openlayers中单击获取要素的更多相关文章

  1. ArcGIS Engine中如何获取Map中已经选择的要素呢

    1.使用IEnumFeturea对象获取map中的FeatureSelection,该方法可以获取所有图层的选择要素.IMap中的FeatureSelection可不是IFeatureSelectio ...

  2. ArcGIS Engine中如何获取Map中已经选择的要素呢(转)

    ArcGIS Engine中如何获取Map中已经选择的要素呢   1.使用IEnumFeturea对象获取map中的FeatureSelection,该方法可以获取所有图层的选择要素.IMap中的Fe ...

  3. C#+ArcGIS Engine 获取地图中选中的要素

    转自 C#+ArcGIS Engine 获取地图中选中的要素 C#+ArcGIS Engine 获取地图中选中的要素 提供一种简单遍历获取地图中选中要素的方法,代码如下: List<IFeatu ...

  4. OpenLayers中的球面墨卡托投影

    最近看OpenLayers,研究到地图投影时找到官方的文档,就翻译了一下,由于英文能力差,翻译不好的地方,请看原文 原文地址:http://docs.openlayers.org/library/sp ...

  5. Android自动化测试中AccessibilityService获取控件信息(1)

    Android自动化测试中AccessibilityService获取控件信息(1) 分类: android自动化测试2014-03-24 15:31 3455人阅读 评论(16) 收藏 举报 and ...

  6. WebAPI中无法获取Session对象的解决办法

    在MVC的WebApi中默认是没有开启Session会话支持的.需要在Global中重写Init方法来指定会话需要支持的类型 public override void Init() { PostAut ...

  7. android开发中fragment获取context

    在用到fragment时无法使用.this来指定当前context内容,android开发中fragment获取context,可以使用getActivity().getApplicationCont ...

  8. php开发中怎么获取服务端MAC地址?

    MAC(Media Access Control或者Medium Access Control)地址,意译为媒体访问控制,或称为物理地址.硬件地址,用来定义网络设备的位置.在php中如何获取MAC(M ...

  9. ASP.NET中gridview获取当前行的索引值

    在用GridView控件时,我们经常会碰到获取当前行的索引,通过索引进行许多操作.例如,可以获得当前行某一个控件元素:设置某一元素的值等等.下面结合实例介绍几种获得GridView当前行索引值的方法. ...

随机推荐

  1. 记.net3.5离线安装问题

    dism.exe /online /enable-feature /featurename:netfx3 /Source: X:\sourse\sxs pause 相关文件要相同版本的ISO中提取,否 ...

  2. DB-概念-数据库:数据库/Database

    ylbtech-DB-概念-数据库:数据库/Database 数据库是以一定方式储存在一起.能与多个用户共享.具有尽可能小的冗余度.与应用程序彼此独立的数据集合,可视为电子化的文件柜——存储电子文件的 ...

  3. 练习1-20 编写程序detab,将输入中的制表符替换成适当数目的空格.

    1.问题描述 编写程序detab,将输入中的制表符替换成适当数目的空格,使空格充满到下一个制表符终止位的地方. 假设制表符终止位的位置是固定的, 换句话说每隔n列就会出现一个制表符终止位. 2.描述 ...

  4. Java学习之线程间通信(双线程)

    线程间通讯:多个线程在处理同一资源,但是任务不同 练习一:双线程出现线程安全问题,需要使用同步,思考同步代码添加位置需求:银行账户存钱,显示谁在账户存钱了,存了多少钱分析:操作同一银行账户两个不同的操 ...

  5. 如何消去delphi Stringgrid重绘时产生重影

    procedure TForm1.Stringgrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGrid ...

  6. 距离矢量路由协议——RIP

    距离矢量路由协议RIP: 众所周知,RIP(Routing Information Protocol),即路由信息协议,是一种距离矢量路由协议,它与IGRP,OSPF等一样都是属于IGP(Interi ...

  7. [LeetCode] 627.交换性别

    给定一个 salary 表,如下所示,有 m = 男性 和 f = 女性 的值.交换所有的 f 和 m 值(例如,将所有 f 值更改为 m,反之亦然). 要求只使用一个更新(Update)语句,并且没 ...

  8. python列表之添加、修改和删除元素

    修改列表中的元素: subject= ['math', 'Chinese', 'English'] subject[0] = 'history' # 列表名[要修改元素的下标]=修改后的元素 prin ...

  9. Python的基础类型(int,bool,str):

    Python的基础类型(int,bool,str): 1.int -------> 整形:主要用力进行数字计算 2.string ------>字符串:可以保存少量数据并进行相关的操作 3 ...

  10. js高级编程思想

    js惰性思想: 能够执行一次就搞定绝对不会执行第二次 function createXHR(){ var xhr=null, falg=false, ary=[ function(){ return ...