如何使用liblas获取存储在las点的'data'字段中的内容?

时间:2013-11-20 18:36:05

标签: python lidar

我正在处理mulipulse激光雷达数据,该数据沿着飞行路径中的多条线路收集点。我正在尝试确定las文件中各个行的名称和数量。我在python中使用liblas模块。

我发现this documentation解释了存储在las文件中的不同字段。它在页面的最底部提到了一个数据字段(get_data和set_data)。

标题中的“点数据格式”和“点数据记录长度”为此“数据”字段留出空间。我的标题说我为数据字段留出了28个字节,并且数据字段中存储了28个值。第19个值(至少在两个不同传感器的两个数据集中)是指行号。我在单脉冲数据中有一个值,在多脉冲数据中有4个值。

我想知道这个字段中存储的内容是否存在标准,或者它是否是专有的。

另外,作为获取每条扫描线名称的方法,我编写了以下代码:

import liblas
from liblas import file as lasfile

# Get parameters
las_file = r"E:\Testing\00101.las"

f = lasfile.File(las_file, mode='r')

line_list = []
counter = 0
for p in f:
    line_num = p.data[18]
    if line_num not in line_list:
        line_list.append(line_num)
    counter += 1
print line_list

导致以下错误:

Traceback (most recent call last):
  File "D:\Tools\Python_Scripts\point_info.py", line 46, in <module>
    line_num = p.data[18]
  File "C:\Python27\ArcGIS10.1\lib\site-packages\liblas\point.py", line 560, in get_data
    length = self.header.data_record_length
  File "C:\Python27\ArcGIS10.1\lib\site-packages\liblas\point.py", line 546, in get_header
    return header.Header(handle=core.las.LASPoint_GetHeader(self.handle))
WindowsError: [Error -529697949] Windows Error 0xE06D7363

有没有人更了解存储在las点/标题中的行号?任何人都可以解释错误吗?它似乎在我得到错误之前分配了近2gb的ram。我在win xp上,所以我猜它是一个内存错误,但我不明白为什么访问这个'data'字段会占用内存。任何帮助是极大的赞赏。

1 个答案:

答案 0 :(得分:1)

我并不假装自己是这方面的专家,但我对GIS数据很感兴趣,所以这引起了我的兴趣。我在我的Fedora 19系统上安装了liblas及其依赖项,并使用了liblas附带的示例数据文件。

使用你的代码我遇到了同样的问题,看着我的所有记忆被吃掉了。我不知道为什么会发生这种情况 - 也许不必要的引用会阻止垃圾收集器像我们希望的那样工作。这可能是固定的,但我不会尝试。

我确实注意到liblas模块的一些有趣功能,并决定尝试它们。我相信你可以得到你想要的数据。

打开文件后,请查看标题中的XML说明。

h = f.get_header()
print(h.get_xml())

很难看(随意使用xml.dom.minidom或lxml.etree),但在我的示例文件中,它显示了点数据的字节布局(我的也有28个字节)。在我的中,偏移18是分配给点源ID的单个短(2个字节)。您应该可以使用p.data[18:19]p.get_data()[18:19]p.point_source_idp.get_point_source_id()来检索此内容。不幸的是data引用会占用内存而p.point_source_id有一个错误(错误修复请求提交给开发人员)。如果我们更改您的代码以使用最后一个访问方法,一切似乎都可以正常工作。因此,请在for循环中尝试此操作:

for p in f:
    line_num = p.get_point_source_id()
    if line_num not in line_list:
        line_list.append(line_num)
    counter += 1

请注意

counter == h.get_count()

如果您只想要一组唯一的点源ID值...

line_set = set(p.get_point_source_id() for p in f)

希望您的数据值也可以p.get_point_source_id()获得。请在评论中告诉我它是如何工作的。干杯!