基于全球索引的点云切片发布处理
2022-02-22宋金秀谭弘武张洪雷杨大兵
宋金秀 谭弘武 张洪雷 王 成 杨大兵
(北京煜邦电力技术股份有限公司, 北京100089)
0 引言
目前,激光点云数据处理包括点云滤波、点云配准、点云分割与分类、点云三维重建等相关技术,而在点云三维瓦片处理方面的应用较少,且瓦片数据处理多为地图切片。
地图切片Web服务简称Web地图瓦片服务(Web Map Tile Service,WMTS),是开放地理空间信息联盟(Open Geospatial Consortium,OGC)提出的缓存技术标准,即在服务器端缓存被切割成一定大小瓦片的地图,对客户端只提供这些预先定义好的单个瓦片的服务,将更多的数据处理操作如图层叠加等放在客户端,从而缓解地理信息系统(Geographic Information System,GIS)服务器端数据处理的压力,改善用户体验[1-3]。WMTS使用瓦片矩阵集来表示切割后的地图。瓦片就是包含地理数据的矩形影像,一幅地图按一定的瓦片大小被切割成多个瓦片,形成瓦片矩阵,一个或多个瓦片矩阵即组成瓦片矩阵集[4]。不同的瓦片矩阵具有不同的分辨率,每个瓦片矩阵由瓦片矩阵标识符进行标识。
1 地图切片概况
随着科技的不断发展,用户对瓦片服务要求的提高,瓦片数据处理技术逐渐从地图切片向点云切片、模型切片等方向不断发展。而目前的点云切片处理多数针对局部数据处理,在数据追加和局部更新方面存在一定的不足,在处理海量数据时存在操作繁复、数据处理效率较低等问题[5]。而且针对某些特殊需求,如对已分类的点云数据进行特定类型切片处理,需要将特定类型的数据提取出来再进行切片处理,缺乏制定化和多功能的集成[6-7]。
因此,如何提供一种瓦片数据处理效率高、支持数据追加和局部更新的基于全球索引的点云切片处理方法,是本领域技术人员亟须解决的问题[8-10]。
2 全球索引点云切片发布设计
基于全球索引的点云切片发布处理包括:获取欲处理的原始点云数据;将所有原始点云数据的缩放级别进行统一;按照统一后的缩放级别对原始点云数据进行四叉树分块或八叉树分块,生成多个数据块,并对每个数据块进行全球索引,获得与每个数据块一一对应的索引值;分别按照每个数据块索引值遍历原有点云切片成果数据库中所有三维瓦片,并按照预设条件对原有点云切片成果数据库进行更新。基于全球索引切片发布处理可对激光点云数据进行全球索引瓦片划分,且支持数据追加和局部更新,并可针对不同类型的点云筛选进行瓦片划分。
全球索引的点云切片处理方法包括全球索引瓦片划分和数据追加及更新,其中全球索引瓦片划分方法包括:
(1)确定最大级别:统一级别,以方便融合处理。
(2)文件切割:文件太大,需要分割处理,避免内存溢出的问题。
(3)分块规则:前10级按全球经纬度进行分块;大于10级时,在10级瓦片的基础上按八叉树分块。
(4)缓存和融合:大文件切割后的小文件或者是和其他文件做增量处理时都需要进行融合。
(5)保存点云瓦片数据:数据追加及更新时需首先判断当前数据所在的瓦片,遍历成果数据库中所有瓦片并在缓存中读取与当前瓦片索引相同的瓦片;其次遍历所有点,根据点的网格索引从缓存的瓦片中查找有没有相同网格的点,有的话舍弃缓存中的点,缓存更新后若无相同的点,则将新读入的点全部追加进入缓存;最后将新的瓦片保存到成果数据库中。
3 基于全球索引的点云切片发布实现
3.1 全球索引点云切片发布
基于全球索引切片发布处理流程如图1所示。
图1 点云切片流程图
(1)预先进行参数设置(包括空间坐标参数、不切片类型和输出类型),并输入原始点云文件,即获取欲处理的原始点云数据。
(2)统一级别:将所有所述原始点云数据的缩放级别进行统一。
(3)文件切割及全球索引:按照统一后的缩放级别对所述原始点云数据进行四叉树分块或八叉树分块,生成多个数据块,并对每个数据块进行全球索引,获得与每个数据块一一对应的索引值。
(4)数据追加及更新:分别按照每个数据块索引值遍历原有点云切片成果数据库中所有三维瓦片,并按照预设条件对原有点云切片成果数据库进行更新。
3.2 全球索引瓦片划分
全球索引瓦片划分主要包括确定最大级别和瓦片划分两步,具体流程如图2所示。
图2 全球索引流程图
3.2.1统一级别
统一级别,以方便融合处理,若未指定则进行如下处理:
(1)判断是否预设有最大缩放级别i,若是,则将最大缩放级别i作为统一缩放级别;若否,则执行步骤2;
(2)取所述原始点云数据中间位置的点进行估算;
(3)计算所取点的包围盒以及包围盒的中心点坐标;
(4)计算包围盒所有点到中心点的平均距离L;若平均距离L大于预设的最大缩放级别i下的点云三维瓦片分辨率,则确定最大缩放级别为i;否则执行步骤5;
(5)i自增1;
(6)重复执行步骤4~5,直至平均距离L不大于预设的最大缩放级别i下的点云三维瓦片分辨率。
3.2.2全球瓦片划分
(1)全球瓦片划分规则为:0级时,1个瓦片的分辨率为赤道周长;1级时,1个瓦片的分辨率为赤道周长的1/2;2级时,1个瓦片的分辨率为赤道周长的1/4;N级时,1个瓦片的分辨率为赤道周长的1/2N;
(2)前10级按全球经纬度以四叉树分块进行处理,即0级时,全球两块瓦片分辨率为180度;1级时,全球4×2块瓦片分辨率为90°;N级时全球有2×2N个瓦片,1个瓦片的分辨率为180°的1/2N。当切片等级大于10级时,在10级瓦片的基础上按八叉树分块,八叉树分块是可看作是三维下的四叉树分块规则,即在平面xy和高程z上同时进行四叉树分块。
3.3 数据追加及更新
数据追加及更新流程如图3所示。
图3 数据追加及更新流程图
(1)确定当前数据块所对应的索引值;
(2)按照当前数据块的索引值遍历原有点云切片成果数据库中所有三维瓦片,判断原有点云切片成果数据库中是否存在与当前数据块索引值相同的原有三维瓦片;如果不存在,则将当前数据块新增至原有点云切片成果数据库;如果存在,则执行下一步骤;
(3)将当前数据块划分为网格,并确定每个网格点的索引值;
(4)按照当前数据块网格点索引值遍历与当前数据块索引值相同的原有三维瓦片的所有网格点,查找是否存在与当前数据块网格点索引值相同的原有网格点;如果存在,则将原有网格点替换为当前数据块网格点;如果不存在,则将当前数据块网格点追加至原有点云切片成果数据库。
3.4 点云数据切片程序实现
后台算法处理采用Visual C++开发语言,基于地理空间数据抽象库(Geospatial Data Abstraction Library,GDAL)和点云库(Point Cloud Library,PCL)开源库,实现基于全球索引的点云切片发布处理算法的代码工作,前端展示采用Direct3D进行三维数据加载渲染。C++点云切片发布处理部分代码如下所示:
∥获取点云数据所在瓦片索引号
int Xcount=int(GetData->m_PointHeader.X/Gridsize)+1;
int Ycount=int(GetData->m_PointHeader.Y/Gridsize)+1;
for(int i=0;i { for (int j=0;j { ∥计算得到当前瓦片数据范围 std::vector minx = minx miny= miny maxx = maxx>GetData->m_PointHeader.MaxX?GetData->m_PointHeader.MaxX:maxx; maxy = maxy>GetData->m_PointHeader.MaxY?GetData->m_PointHeader.MaxY:maxy; ∥构建新的瓦片数据 C_DataIndex *m_DataIndex=new C_DataIndex(); m_DataIndex->XY0[0]=minx-0.1; m_DataIndex->XY0[1]=miny-0.1; m_DataIndex->XY1[0]=maxx+0.1; m_DataIndex->XY1[1]=maxy+0.1; m_DataIndex->GridHigh=maxy-miny; m_DataIndex->GridWide=maxx-minx; ∥瓦片数据重新构建索引 m_DataIndex->SetGridIndex(GridPoints); for (size_t k=0;k { if (m_DataIndex->BlockInput[k].size()==0) continue; int _utm =get_utm(Prj); ∥点云数据平面坐标转换为经纬度数据UTMxy_to_latlon_deg(m_DataIndex->GridCoordinate[k].X-m_Gridsize/2,m_DataIndex->GridCoordinate[k].Y-m_Gridsize/2,_utm, false,m_miny,m_minx);UTMxy_to_latlon_deg(m_DataIndex->GridCoordinate[k].X+m_Gridsize/2,m_DataIndex->GridCoordinate[k].Y+m_Gridsize/2,_utm, false,m_maxy,m_maxx); std::vector vecUtmXY.resize(m_DataIndex->BlockInput[k].size()); ∥数据写入 if (!IsWrite) { OutLas->m_PointHeader.DataFormatId='2'; bool b_write = true; int isizeadd = OutGridPoints.size()+Points200.size(); if(isizeadd<200&&isizeadd b_write = false; ∥新的瓦片数据 if(b_write) { for (int ii=0;ii OutGridPoints.push_back(Points200[i]); Points200.clear(); std::vector OutLas->Points=OutGridPoints; OutLas->WriteLas(LASOutPathName); IsWrite=true; } ∥瓦片数据局部更新 else { int isi = Points200.size()+OutGridPoints.size(); for (int im=0;im Points200.push_back(OutGridPoints[im]); } } else SplitCloud::AppendLas(LASOutPathName,OutLas->m_PointHeader,OutGridPoints);∥数据更新追加 OutGridPoints.clear(); std::vector } } } 经过上述方法处理后的切片点云数据加载到Direct3D中,数据渲染支持海量数据无缝三维浏览显示。 经由上述的技术方案可知,与现有技术相比,本文公开提供了一种基于全球索引的点云切片处理方法,利用全球索引瓦片划分的方法,解决了在处理海量点云数据的过程中效率较低的问题,并且可以提供数据追加和更新等方式,为后续的数据更新和发布提供极大的便利。同时,可对分类后的点云数据进行特定类型数据的瓦片处理,在多功能集成上有较好的适用性。4 结束语