【问题标题】:Easiest way to check for OL3 feature equality检查 OL3 功能相等性的最简单方法
【发布时间】:2017-01-17 17:35:47
【问题描述】:

我正在从 geojson 文件加载多个点,并希望删除数据中存在的重复项(对于某些功能,尽管 ID 是相同的属性)。为了达到这个目标,我想知道ol.Feature 对象是否等于 到其他ol.Feature 对象。

平等是在 ol.Feature 对象上以某种方式定义的,还是我必须自己定义?

【问题讨论】:

    标签: javascript openlayers-3 point


    【解决方案1】:

    您应该遍历每个功能并获取其属性。 ID 总是不同的,这就是为什么不能使用方法getFeatureById(来自层或源)或方法getId(来自单个特征)。

    我创建了一个活生生的例子,当你按下按钮时它正在工作并删除重复的功能。

    请注意,我们正在获取属性 nametag 并将它们转换为 JSON 变量以便轻松比较它们,但您可以选择适合您需要的属性.

    var features = [];
    var point1 = ol.proj.transform([-50, 4.678], 'EPSG:4326', 'EPSG:3857');
    var point2 = ol.proj.transform([20, 4.678], 'EPSG:4326', 'EPSG:3857');
    
    var feature1 = new ol.Feature({
      geometry: new ol.geom.Point(point1),
      name: "First",
      tag: "TAG"
    });
    var feature2 = new ol.Feature({
      geometry: new ol.geom.Point(point2),
      name: "Second",
      tag: "TAG"
    });
    
    features.push(feature1);
    features.push(feature2);
    features.push(new ol.Feature({
      geometry: new ol.geom.Point(point1),
      name: "First",
      tag: "TAG"
    }));
    
    var vectorSource = new ol.source.Vector({
    	features: features
    });
    
    var vectorLayer = new ol.layer.Vector({
    	source: vectorSource
    });
    
    var map = new ol.Map({
      layers: [
        new ol.layer.Tile({
          source: new ol.source.OSM()
        }),
        vectorLayer
      ],
      target: 'map',
      view: new ol.View({
        center: [0, 0],
        zoom: 2
      })
    });
    
    document.getElementById("btn").onclick = function(){
      var totalProperties = [];
      vectorSource.getFeatures().forEach(function(feature){
        var propertiesThis = {},
            p = feature.getProperties();
    
        for (var i in p) {
          if (i === 'name' || i === 'tag') {
            propertiesThis[i] = p[i];
          }
        }
        var jsonProperties = JSON.stringify(propertiesThis);
        
        if (totalProperties.indexOf(jsonProperties) === -1) {
          totalProperties.push(jsonProperties);
        } else {
          vectorSource.removeFeature(feature);
          console.log(propertiesThis['name'] + " feature removed")
        }
      });
    };
    <link href="https://openlayers.org/en/v3.20.1/css/ol.css" rel="stylesheet"/>
    <script src="https://openlayers.org/en/v3.20.1/build/ol.js"></script>
    <div id="map" class="map" tabindex="0"></div>
    
    <button id="btn">Remove duplicates</button>

    【讨论】:

      【解决方案2】:

      我认为在很大程度上取决于视角和用例来说明特征何时相等,这就是为什么要让用户定义相等的原因。有些人可能会说,如果特征共享(完全相同)相同的几何图形(1),则它们是相等的。其他人可能会说特征需要具有相同的属性(2),甚至两者都有(3)

      要检查属性相等性,我建议定义对相等性定义重要的属性。然后您可以使用类似的代码来检查 2 个ol.Feature 对象是否相等:

      // Define your important properties    
      var mySelectedProperties = ["importantProperty", "anotherImportantProperty", "propertyX"];
      
      // Check for property equality between two ol.Feature objects
      function areEqual(featureA, featureB){
          var equal = true;
          for(let property of mySelectedProperties){
              if(featureA.get(property) != featureB.get(property)){
                  equal = false;        
                  return equal ;
              }
          }
          return equal;
      }
      

      对于几何相等,您可能需要检查 (x & y) 坐标是否相同。这里还有一些注意事项:

      • 2 个几何图形可能看起来相同,但坐标顺序不同:

      例如:lineA:pointA-pointBlineB:pointB-pointA

      甚至这个:polygonA: pointA-pointB-pointC-pointApolygonB: pointB-pointC-pointA-pointB

      • 对于某些特征,说几何形状与另一个几何形状非常接近以致它可能代表相同的特征可能是有意义的...(例如(小)测量误差或浮点不准确)。

      【讨论】:

      • 好主意。几何考虑对 LineString 功能帮助很大!
      【解决方案3】:

      两个具有完全相同属性的ol.Feature 对象不会彼此相等。

      所以是的,您需要手动清除重复项。您说 id 始终是唯一的,但其余的有时可能是相同的。在这种情况下,您可以循环使用您的功能。对于每一个,获取所有属性的 JSON 字符串(id 和几何图形除外)并比较新的特征集合。

      你可以这样做(未经测试,但这可以给你一个想法):

      var uniqueFeatures =  [];
      var feature;
      var properties;
      var json;
      var jsons = [];
      for (var i = 0, ii = features.length; i < ii; i++) {
        feature = features[0];
      
        // Stringify the properties of the feature
        properties = feature.getProperties();
        var props4json;
        for (var key in properties) {
          if (key !== 'id' && key !== 'geometry') {
            props4json[key] = properties[key];
          }
        }
        json = JSON.stringify(props4json);
      
        // Check if the stringified properties exist...
        // if not, we have a new unique feature.
        if (jsons.indexOf(json) === -1) {
          jsons.push(json);
          uniqueFeatures(feature);
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-12-24
        • 2020-02-11
        • 2011-04-15
        • 1970-01-01
        • 2014-09-03
        • 1970-01-01
        • 2020-04-26
        相关资源
        最近更新 更多