前言
有一个工具。
可以在线编辑geojson数据。
主要功能是,在线编辑建筑,增删改,主要数据是面积和高度。面积由轨迹数组组成。
轨迹数组:features.geometry.coordinates。
高度是:features.properties.Height。
编辑了可以导出成一份geojson文件,也可导出成obj文件。
今天遇到的问题是,如果我想知道我编辑了多少个建筑,怎么办?
经过
原则上可以在编辑的过程中记录,但这样做不是很好。
- 已经改了的文件,没办法重新处理
- 增加工作量
- 增加逻辑处理,影响性能
过程
- 最简单的方法是,直接使用for循环,遍历两份数据,如果能够找到相同的数据,即是未修改,否则修改+1.
- 但是这样做有两个问题。
- 因为精度问题,导入的原始数据和导出的数据,就算没改变,也会有差异,因为小数点足足有14位。
- 直接循环时间复杂度是O(n2)。
怎么办呢?
经过测试,发现两份数据在保留4位小数点的时候,是一致的。
所以可以把数据取4个小数点。
数据差异的问题已经解决了。
但是时间复杂度还没解决。
于是决定用空间换时间。
算法
用一个对象,把每一个建筑的轨迹存储到哈希之中,哈希的值为建筑的高度。
如:
features.properties.Height = 9
features.geometry.coordinates = [[[114.35098683912278, 36.13595280429963],[114.35098693920013, 36.13582170962971]]]
则存储为:
let obj = {}
obj['114.3509-36.1359-114.3509-36.1358'] = 9
因为不同建筑的高度、轨迹不同,所以同一份数据的哈希是唯一的。
第一份数据存储起来,跟第二份数据比较,记录下不相同的数据,就可以找到改变的数据。
备注
为了避免哈希重复,在记录哈希的时候需要做一个重复判断。
附录
import gai from './assets/gai.js'
import yuan from './assets/yuan.js'
let gaiobj = {}
let yuanobj = {}
for(let i = 0; i < yuan.features.length; i++){
let features = yuan.features[i]
let properties = features.properties
let geometry = features.geometry
let coordinates = geometry.coordinates[0]
let lnglat = coordinates[0]
let height = Number(properties.Height || properties.height)
let key = ''
lnglat.forEach(xy => {
let [x, y] = xy
key += x.toFixed(4) + '-'+ y.toFixed(4) + '-'
})
if(yuanobj[key]){
console.log('key1', key)
}
yuanobj[key] = height
}
let change = 0
for(let i = 0; i < gai.features.length; i++){
let features = gai.features[i]
let properties = features.properties
let geometry = features.geometry
let coordinates = geometry.coordinates[0]
let lnglat = coordinates[0]
let height = Number(properties.Height || properties.height)
let key = ''
lnglat.forEach(xy => {
let [x, y] = xy
key += x.toFixed(4) + '-'+ y.toFixed(4) + '-'
})
if(gaiobj[key]){
console.log('key2', key)
}
gaiobj[key] = height
if(yuanobj[key] != gaiobj[key]){
change ++
}
}
console.log('已经改变了的建筑:', change)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。