由于本人最近在进行建筑物数据处理的项目,遇到了较多的问题,同时也收获了很多知识。所有打算写一个建筑物处理的系列博客。
要处理建筑物多边形,首先得理解结构关系,这是所有实现处理的基础。建筑物多边形是由一条条封闭的环(线状)组成,环是由一组首尾相同的点组成,所以对建筑物多边形的处理实质是对环和点处理。
实际项目中,所给的数据是非常凌乱的,杂质非常多。下图是初始的建筑物多边形数据,我们可以发现:局部有大量黑色点,放大发现并不是黑色,而是多边形中环太小太多,数据量大且杂,分布非常广泛。另外程序运行速度非常慢。这两点说明需要对数据进行过滤处理,即对噪点环进行过滤删除处理。
局部放大发现黑点是小环,即噪点环。
1)噪点环
顾名思义就是图上的噪点,只不过噪点不是点,而是一个个小环,这些环特点为:面积小;数量多且分布广;明显不是建筑物多边形;这些小环与正常的建筑物的环实质上只有面积上的差别,小环面积很小。
要进行建筑物化简得到最终成功,必须先除去这些噪点环,否则由于环数量太大导致程序运行缓慢甚至卡死。
2)去除的思路
上面提到这些小环与正常的建筑物的环实质上只有面积上的差别,小环面积很小。所以可以设置一个面积阈值,把小于这个阈值的环一律舍弃,保留大于面积阈值的环。阈值的设定需要根据实际的项目要求。
3)代码实现
// zf,按面积过滤,0701 void CGeoPolygon::ObjectFilterByArea(void) { //按面积 vector<int> temp; //定义数组,存噪点环 if(circleAreaList.size()!=0) vector<double>().swap(circleAreaList); //数组设定为空 for(int i = 0;i<circles.size();i++) //遍历环数组 { double circlearea = circles[i]->getArea(circles[i]->pts); //获取环的面积 circleAreaList.push_back(circlearea); if(circlearea<=100000) temp.push_back(i); //*****设定阈值*****,当面积小于阈值,噪点环数组添加该数值 } vector<CGeoPolyline*> tempPolyline; //定义新的无噪点环的环数组 if(tempPolyline.size()!=0) vector<CGeoPolyline*>().swap(tempPolyline); //防止环数组不为空 for(int j = 0;j<circles.size();j++) //添加非噪点环到数组中 { bool answer = isContained(temp,j); //判断j是否存在temp中,若存在说明为冗余环,新circles中不应有此环 if(answer == false) //若不存在说明不为冗余环,新circles应存此环 tempPolyline.push_back(circles[j]); } tempPolyline.swap(circles); //交换,得到去除冗余环之后的环circles }