OpenLayers 获取图层(ol.source.Vector类)中Features的各种方式

本文介绍如何在OpenLayers中操作矢量图层,包括获取图层源、遍历图层中的要素、获取所有要素及其顺序问题分析,并提供通过ID获取特定要素的方法。

目录

一、获取图层源

二、调用方法 

方法一:forEachFeature

方法二: getFeatures

1.1 featuresCollection_

1.2 featuresRtree_

方法三:getFeatureById


一、获取图层源

        所有方法都基于source层,所有需要先获得ol.source.Vector的实例

layerName.getSource()

二、调用方法 

方法一:forEachFeature

         该方法可以直接遍历图层源中的所有要素

            var num = 0;
            var b = false;
            pointSource.forEachFeature(function (item) {
                var name = item.get("PointName");
                if (name == startPointName || name == endPointName) {
                    var id = item.get("PointId");
                    deleteData("PointInfo", item, id);
                    num++;
                }
                if (num > 2) {
                    b = true;
                }
                return b;
            });

方法二: getFeatures

      该方法获取图层中的所有要素,并返回其组成的数组,getFeatures()函数获得的集合继承于array类所以可以调用JS自带的foreach函数

var features = pointSource.getFeatures();  //获取源数据中要素的集合
            features.forEach(function (item) {         
                var name = item.get("PointName");
                if (name == startPointName || name == endPointName) {
                    var id = item.get("PointId");
                    deleteData("PointInfo", item, id);
                }
            }); 

 其定义如下:

ol.source.Vector.prototype.getFeatures = function() {
  var features;
  if (this.featuresCollection_) {
    features = this.featuresCollection_.getArray();
  } else if (this.featuresRtree_) {
    features = this.featuresRtree_.getAll();
    if (!goog.object.isEmpty(this.nullGeometryFeatures_)) {
      goog.array.extend(
          features, goog.object.getValues(this.nullGeometryFeatures_));
    }
  }
  goog.asserts.assert(features !== undefined,
      'Neither featuresRtree_ nor featuresCollection_ are available');
  return features;
};

      函数首先检查 featuresCollection_ 是否为空,如果不为空,那么调用其 getArray 方法,featuresCollection_ 是一个 ol.Collection 对象,是 openlayers 对 javascript 的 Array 的进一步封装,其 getArray 方法就是返回对象内含的数组,数组中便包含着图层包含的所有要素;如果 featureCollection_ 为空,则进一步检查 featuresRtree_ 是否为空,如果不为空,则获取其中的所有要素,并获取 nullGeometryFeatures_ 中的所有要素,然后合并两个数组,返回;最后,如果都没有要素,那么就报错:“featuresRtree_ 和 featuresCollection_ 中都没有要素”,如果有要素,返回。

那么 featuresCollection_ 和 featuresRtree_ 是什么结构呢?下面我们一一说明。

1.1 featuresCollection_


       featuresCollection_ 是内含要素集合的 ol.Collection 对象,除非是 source 对象的 useSpatialIndex 设置为 false,或者其 features 属性设置为 ol.Collection 的要素集合,否则 featuresCollection_ 的值将是 null。

所以如果不是以上的配置,那么往往 getFeatures 方法是获取的 featuresRtree_ 中包含的要素集合。

1.2 featuresRtree_


featuresRtree_ 在 ol.source.Vector 其定义如下:

  /**
   * @private
   * @type {ol.structs.RBush.<ol.Feature>}
   */
  this.featuresRtree_ = useSpatialIndex ? new ol.structs.RBush() : null;

       类初始化时,首先检查 useSpatialIndex (其默认值为 true),如果是 true,那么将其初始化为 ol.structs.RBush 对象类型,否则为 null。那么这个 ol.structs.RBush 是什么类型呢?

       ol.structs.RBush 是 openlayers 对 RBush 的再次封装,RBush 是一个用于点和矩形的 2D 空间索引算法的高性能 javascript 实现,其基于优化的 R-tree 数据结构,支持批量插入。不了解GIS的可能对“空间索引”不是很了解,“空间索引”其实是一个特殊的数据结构,主要针对数据类型是点或者矩形,“空间索引”可以让你高效的执行将查询条件限定为一个矩形区域的查询,即“空间查询”,比循环检索所有条目有‘几百倍’的提升!“空间索引”普遍用于地图和数据可视化。

       我们从上面 getFeatures 的源码可以看到,其使用了 ol.structs.Rbush 的 getAll 方法,其 getAll 方法调用了 RBush 的 all( ) 方法,但是这个返回所有数据的方法,并不能保证其按照插入数据的顺序,这也很容易理解,我们来看 R-tree 在内存中的情况:


图1 R-tree在内存中的情况

       从图中可以看出,当插入一条数据,这条数据会被添加到其被包含的矩形区域中,但是并没有记录其插入时候的序号,所以当取出所有节点时,就并不能保证按照插入的顺序。

       所以我们并不能写出如下的代码,期待‘总是’得到“最后添加的要素”,之所以说‘总是’是因为,有时候可以得到,但并不稳定,我测试是,当超过10后就会出错:

var features = veclayer.getSource().getFeatures();
var feature_num = features.length;
var last_feature = features[feature_num-1];


方法三:getFeatureById


那么有没有其他的方法获得最后插入的要素呢?

       ol.source.Vector 还提供了一个方法:getFeatureById,我们可以通过要素的 id 来获取它,前提是你给要素设置了 id,通过 feature.setId(id) 设置,正如开篇提到的需求,在程序自动获取的情况下,我们可以设置一个计数器,每次添加要素就将计数器的值自增 1,然后将计数器的值设置为相应添加的要素的id,当获取到新的点位置时,通过计数器获取最后添加的要素,将其样式设置为普通样式即可。

总结
       本文主要讲了实时轨迹追踪问题的获取最后添加的要素的方法,并讨论了 ol.source.Vector 方法获取的要素为什么是没有规则的顺序的原因。
————————————————
版权声明:本文为优快云博主「庆祝亚运会」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/qingyafan/article/details/50478360

评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值