我正在从一个geojson文件中加载多个点,并希望删除数据中存在的重复项(尽管ID不同,但某些要素的属性相等)。为了实现这个目标,我想找出
在
ol.Feature
对象是否与其他ol.Feature
对象相等。在
ol.Feature
对象上是否已经定义了相等性,还是我必须自己定义它?ol.Feature
对象是否与其他ol.Feature
对象相等。ol.Feature
对象上是否已经定义了相等性,还是我必须自己定义它?getFeatureById
(来自图层或源)或方法getId
(来自单个要素)。我创建了一个可工作的示例,并在您按下按钮时删除重复的要素。请注意,我们获取属性name和tag,并将它们转换为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>
两个具有完全相同属性的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);
}
}
我认为,说什么时候功能相等很大程度上取决于视角和用例,这就是为什么把定义相等留给用户的原因。有些人可能会说,如果两个功能具有相同的几何形状(1),则它们是相等的。其他人可能会说,功能需要具有相同的属性(2),甚至需要同时满足(3)。
要检查属性相等,建议定义对于您相等定义而言重要的属性。然后,您可以使用类似以下代码来检查两个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)坐标是否相同。以下是一些更多的考虑:
例如:线段A:点A-点B和线段B:点B-点A
甚至是这样:多边形A:点A-点B-点C-点A和多边形B:点B-点C-点A-点B