我需要一个比需要的更大(更密集)的激光雷达测量点(经度,纬度和海拔)的地形定义列表,并在二维网格的基础上对其进行分解。这样做的目的是使用经度、纬度(x,y)值,最终得到基于NxN(即1米x 1米)维度网格的点,从而消除超出需要的点目标是确定抽取后网格中每个点的高程,而不是将高程用作抽取规则本身的一部分。
一个实际的或精确的结构化网格不是必要的,也不是这里的目标,我只使用网格术语来最好地将我想象为点云的其余部分之后,以我们在某个半径(即1米)内总是有一个点的方式来减少它。有可能有一个比网格更好的术语。
我想用脚本或编程语言自己编写代码/脚本,如果我可以从抽取算法开始,或者使用一个可能已经存在的项目中的命令行工具,这个项目可以运行在Ubuntu上,并从我们的应用程序调用作为系统调用。这种方法不需要使用基于GUI的软件或工具来解决这个问题它需要成为一组自动化步骤的一部分。
数据当前存在于选项卡分隔的值文件中,但是如果使用数据库/SQL查询驱动的算法将更好/更快,则可以将数据加载到SQLite数据库文件中。理想的脚本语言将是Ruby或Python,但可以是任何真正的,如果已经存在C/C++/C库,那么我们就可以为我们的需要打包。
思想?
更新
明确使用这个被抽取列表的结果:给定用户的位置(经纬度已知),列表中最接近的点是什么,依次是它的高程?当然,我们现在可以这样做了,但是我们有更多的数据,所以我们只想放松数据的密度,以便如果我们能够使用一个被抽取的列表和完整的列表,在一个公差距离(即1米)内找到最近的点。列表中的经纬度值是十进制GPS(即38.686190027656,-121.11013105991036)
最佳答案
第1部分:抽取版
加载数据
从表格文件加载数据(根据使用的分隔符更改sep
):
# installed as dependency
import pandas as pd
# https://github.com/daavoo/pyntcloud
from pyntcloud import PyntCloud
dense = PyntCloud(pd.read_csv("example.tsv",
sep='\t',
names=["x","y","z"]))
这就是我创建的示例的外观:
建立体素网格
通过测量文件中的经纬度(以米为单位),可以生成网格,如下所示:
grid_id = dense.add_structure("voxelgrid",
sizes=[1, 1,None],
bb_cuboid=False)
voxelgrid = dense.voxelgrids[grid_id]
该体素网格沿
x
(纬度)和y
(经度)维度的大小为1。生成大量版本
decimated=密集。获取样本(“体素网格质心”,体素网格=网格ID)
毁灭是一个核(n,3)数组。您可以将其存储在SQL数据库等中供以后使用。
第2部分:查询
选项A:查询体素网格
获取每个网格单元的平均高度
您可以知道,为网格中的每个单元格获取一个平均值为
z
(高度)的向量:z_mean = voxelgrid.get_feature_vector(mode="z_mean")
使用用户位置查询网格:
用户位置=np.random.rand(100000,2)
添加一列零,因为查询需要3D(这不影响结果):
users_location = np.c_[ users_location, np.zeros(users_location.shape[0]) ]
每个用户都是:
users_cell = voxelgrid.query(users_location)
最后,得到每个用户对应的高度:
users_altitude = z_mean[users_cell]
选项B:使用抽取版本进行查询
建立一个毁灭之树:
从scipy.space导入cKDTree
Kdt=ckdtree(已删除)
使用用户位置查询KDTree:
用户位置=np.random.rand(100000,2)
users_location=np.c_u[用户位置,np.0(用户位置。形状[0])
距离,索引=kdt.query(用户位置,k=1,n个作业=-1)
另外,您可以使用pickle保存和更新体素网格:
pickle.dump(voxelgrid, open("voxelgrid.pkl", "wb"))
voxelgrid = pickle.load(open("voxelgrid.pkl", "rb"))