点概括
# coding:utf-8 import numpy as np import geopandas as gpd from shapely.geometry import Point, LineString from scipy import spatial class pointAbstract(): def __init__(self, pnts, method="keep", near=150): # 空间点概括 # 将near范围内的点聚合成 1 个 # pnts:[[lng,lat], ……] self.pnts = pnts self.method = method self.near = near def step(self): pps = [Point(_) for _ in self.pnts] gps = gpd.GeoDataFrame({"geometry": pps}, crs=4326) gps_ = gps.to_crs(4527) gps_["cds"] = gps_.geometry.apply(lambda x: (np.array(x)[0], np.array(x)[1])) pps_ = gps_.cds.values.tolist() dm = spatial.distance.cdist(pps_, pps_, metric='euclidean') tu = np.triu(dm, k=1) td = np.tril(np.ones_like(dm), k=0) tx = tu - td idx, idy = np.where((tx > -1) & (tx < self.near)) mark = [[x, y] for x, y in zip(idx, idy)] # 需要处理的 点对 _mark = set(list(range(len(self.pnts)))) - set(sum(mark, [])) if self.method == "keep": keep = [np.random.choice(_) for _ in mark] print(keep) keep.extend(_mark) res = [self.pnts[_] for _ in set(keep)] elif self.method == "move": res = [self.pnts[_] for _ in _mark] nps = [[(self.pnts[i][0] + self.pnts[j][0]) / 2, (self.pnts[i][1] + self.pnts[j][1]) / 2] for i, j in mark] res = res + nps return res def ptsAbstract(self, maxiter=300): count = 0 while 1: N = len(self.pnts) self.pnts = self.step() M = len(self.pnts) count = count+1 if count<maxiter else maxiter if M == N or count==maxiter: break return self.pnts if __name__ == '__main__': pnts = [[113.5, 34.78], [113.5, 34.799], [113.5, 34.78], [113.5, 34.799], [113.5, 34.799], [113.5, 34.7991], [113.5, 34.795], [113.5, 34.790]] pa = pointAbstract(pnts) res = pa.ptsAbstract()