(一)建筑物多边形化简系列之去除冗余点

制图综合和建筑物数据处理等都涉及到建筑物多边形的化简。制图综合中,由于比例尺的变小,建筑物在小比例尺地图上所占面积变小,这意味着建筑物图形的形状精度也有一定的损失,为了更好地表示原有建筑物的特征(面积、图形和方向),需要对建筑物多边形进行化简。另外,从遥感影像提取的建筑物矢量数据需要经过图形化简等一系列操作才能作为可使用的数据。

由于本人最近在进行建筑物数据处理的项目,遇到了较多的问题,同时也收获了很多知识。所有打算写一个建筑物处理的系列博客。

首先明确,矢量数据结构中,建筑物多边形是由一些列环(circle)组成,环则由一串首尾相同的点构造。这意味着对建筑物多边形化简其实是对这些环(线状)处理,更具体地说,是对环的各个点进行处理(删除、移位)。

对建筑物多边形的化简到最后得到能较好拟合建筑物的成果多边形,这中间需要一系列操作。首先要进行去除冗余点的操作。

1)冗余点

对于建筑物多边形边界上的邻近三点,若它们所组成两条直线的夹角为平角(或零角),则该三点共线,且位于中间位置那个点的取舍对建筑物多边形的 几 何形状没有影响,因此该三点中位于中间位置那个点是冗余的。

需要注意的是由于数据采集误差、制图不规范等原因,使得地图上建筑物多边形边界上出现冗余点的情况很少,出于方法的合理性考虑,选取5°作为缓冲角度,对冗余点的定义做出以下修正定义:对于建筑物多边形边界上的邻近三点,若它们所组成两条直线的夹角与平角(或零角)相差的角度小于5°时,称该三点中位于中间位置的那个点为冗余点。

2)基本思想

取环上邻近三点作为一个单元,分析夹角:若夹角小于阈值,则删除中间点,加入下一个点构成新的分析单元;若夹角大于阈值,则保留中间点,继续遍历。

3)代码实现

// 去除冗余点,zf,0717
void CGeoPolygon::RemoveRedundant(void)
{
	for(int i = 0;i<circles.size();i++)  //遍历每个circles
	{
		vector<int> temp;                //用于存放冗余点的下标
		bool odinary = true;             //设定状态,以确定三点单元的首点
		int count = 0;                   //记录删除的点数,一旦有正常情况恢复为0
		int ptsNum = circles[i]->pts.size();
		for(int n = 0;n<ptsNum-2;n++)
		{
			CMyPoint*first,*middle,*last;  //定义三点
			if(odinary)   //正常,没有冗余点的情况
			{
				first = circles[i]->pts[n];
				middle = circles[i]->pts[n+1];
				last = circles[i]->pts[n+2];
			}
			else         //不正常,存在冗余点的情况
			{
				first = circles[i]->pts[n-count];   //存在冗余点,删除后判断冗余点之后的点是否为冗余点还需要之前三点单元的首点
				middle = circles[i]->pts[n+1];
				last = circles[i]->pts[n+2];
			}
			double angle = calAngle(first,middle,last);   //计算角度
			if(angle >= 10&&angle<=170)         //角度阈值设为10°(可根据需要调整),当角度大于阈值,情况正常,不需要去除点
			{
				odinary = true;
				count = 0;                 //记录删除的点数,一旦有正常情况恢复为0
			}
			else   // 存在冗余点
			{
				temp.push_back(n+1);     //记录冗余点在circles[i]->pts中下标
				odinary = false;         //情况不正常
				count++;                 //连续不正常时都要记录
			}
		}
		vector<CMyPoint*> tempPoints;    //定义临时点集
		if(tempPoints.size()!=0) vector<CMyPoint*>().swap(tempPoints); //防止点集不为空
		for(int j = 0;j<ptsNum;j++)
		{
			bool answer = isContained(temp,j);    //判断j是否存在temp中,若存在说明为冗余点,新点集中不应有此点
			if(answer == false)                   //若不存在说明不为冗余点,新点集应存此点
				tempPoints.push_back(circles[i]->pts[j]);
		}
		tempPoints.swap(circles[i]->pts);         //交换,得到去除冗余点之后的环circles[i]->pts
	}
}

  其中calAngle函数是计算三点的夹角,具体代码如下:

// 计算三点之间的角度,zf,0717,要#include<math.h>
double CGeoPolygon::calAngle(CMyPoint* p1, CMyPoint* p2, CMyPoint* p3)
{
	double x1 = p1->Getx();
	double y1 = p1->Gety();
	double x2 = p2->Getx();
	double y2 = p2->Gety();
	double x3 = p3->Getx();
	double y3 = p3->Gety();

	double angle,p1p2,p2p3,p1p3;
	p1p2 = sqrt(((x1 - x2) * (x1 - x2) + (y1 -y2) * (y1 -y2)));
	p2p3 = sqrt(((x3 - x2) * (x3 - x2) + (y3 -y2) * (y3 -y2)));
	p1p3 = sqrt(((x1 - x3) * (x1 - x3) + (y1 -y3) * (y1 -y3)));
	angle = acos((p1p2 * p1p2 + p2p3 * p2p3 - p1p3 * p1p3) / (2 * p1p2 * p2p3)) * 180.0 / 3.1415926;
	if(angle<0)
		angle = angle*(-1);
    return angle;
}

  isContained函数判断某个数是不是在数组中,见下

// 判断某个数是不是在数组中,zf,0717
bool CGeoPolygon::isContained(vector<int> temp, int i)
{
	bool answer = false;
	for(int j = 0;j<temp.size();j++)
	{
		if(i == temp[j]) answer = true;
		if(answer) break;
	}
	return answer;
}

4)效果展示

去除冗余点之前

去除冗余点之后

5)小结

去除冗余点是建筑物化简的第一步,虽然看起来前后差别不大,但是细细观察还是有一定区别,更近一步的化简将在下一篇博客中讲述。

原文地址:https://www.cnblogs.com/fan-0802-WHU/p/9326735.html

时间: 2024-10-11 15:56:54

(一)建筑物多边形化简系列之去除冗余点的相关文章

(二)建筑物多边形化简系列——多边形点数化简

1.目的实验发现,一个多边形由多个环,每个环的点数数量都比较大,这直接导致程序处理速度非常慢.为了简化图形,加快程序运行速度,为方便后期拟合建筑物,打算对建筑物原始数据进行化简. 2.做法化简的内容是去除部分建筑物多边形的点,采取保留一半点的做法,观察每次化简后图形与原始图形的差别. 3.实施对去除噪点环之后的建筑物多边形数据进行处理. 处理的方法是对半,函数为: // 0904,zf,保留一半的点 void CGeoPolygon::GetHalfPoints(void) { for(int

word表格转html后去除冗余代码

word可以另存为html文件,通过这个功能,可以快速实现网页展示word内容,特别是表格的编辑,它包含tr.td.th.rowspan.colspan等内容,直接写比较繁琐. 但word转换过来的html默认是带有很多格式代码,那么如何去除这些冗余代码,只保留主内容呢? 本来是打算从网上找工具的,但发现没有现成的,一般都是推荐用工具的文本替换来去除,这样不能复用.因此,本人采用nodejs写了一小段代码,来去除冗余代码. 主要思路是: nodejs读取html文件的文本内容 用substrin

28、cd-hit去除冗余序列

转载:http://blog.sina.com.cn/s/blog_670445240101nidy.html 网址:http://cd-hit.org :http://www.bioinformatics.org/cd-hit/ : 下载:http://www.bioinformatics.org/cd-hit/ CD-HIT  去冗余,也可以叫做相似序列的聚类. 简介:CD-HIT stands for Cluster Database at High Identity with Toler

小酌重构系列[12]&mdash;&mdash;去除上帝类

关于上帝类 神说:"要有光",就有了光.--<圣经>.上帝要是会写程序,他写的类一定是"上帝类".程序员不是上帝,不要妄想成为上帝,但程序员可以写出"上帝类".上帝是唯一的,上帝的光芒照耀人间,上帝是很爱面子的,他知道程序员写了"上帝类",抢了他的风头,于是他降下神罚要惩戒程序员.--既然你写了"上帝类",那么就将你流放到艰难地修改和痛苦的维护的炼狱中,在地狱之火中永久地熬炼. 你看,上帝也是有

批处理系列(11) - 去除指定字符之前或之后的文件名

本篇熟悉"tokens=1-3 delims=.-"结合操作 需要提前调整截取范围,分割字符,过滤文件类型,文件原名.新命名 @echo off setlocal enabledelayedexpansion title 去除指定字符之前或之后的文件名 by:小可([email protected]) @echo 需要提前调整截取范围,分割字符,过滤文件,调整文件前后名 rem tokens=有时表示提取全部. rem tokens=m表示提取第m列. rem tokens=m,n表示

(14/24) css进阶:(入门)去除冗余的css

在平时的项目开发中,我们会引入一些框架,比如:Bootstrap,但是在项目中通常我们只使用它的一小部分,还有部分是冗余的.更有甚有时候需求更改,带来DOM结构的更改,这时候我们可能无暇关注CSS样式,会造成很多冗余的CSS.我们得想办法消除冗余的CSS,如果靠人工去剔除,吃力又容易出错,因此,此节我们来学习一下用webpack如何消除未使用的CSS. PurifyCSS 使用PurifyCSS可以大大减少CSS冗余,消除框架中未使用的CSS,初步达到按需引入的效果. 1.如何在webpack中

一个利用正则表达式进行代码重构,去除冗余代码的例子

refact之前:大量的重复代码 refact之后:用map消除了重复代码. 现在的分支里每次执行检查都要先 var usRegx = /XXXX/. 实际上通过字面量定义了一个正则表达式对象,开销比定义一个String大.其实没必要每次都定义,可以把map定义在controller的一个全局属性上. 执行这段代码就可看出字符串常量和正则表达式字面量的性能差异: var N = 100000000; console.time("normal string"); for( var i =

编码原理详解(一)----简介

本节开始,给大家系列介绍一下关于编码原理的相关知识,可能会涉及到部分算法的知识,也就意味着会相对枯燥一些,笔者尽自己所能,努力的追求简单,同时把原理清晰的呈现给大家. 一.编码 编码已经是一个老声长谈的问题了,为什么会有编码,原因是原始图像视频的数据量很惊人,不便于传输,之前的文章有介绍,感兴趣可以回去温习下哦:为什么可以编码,原因是图像与图像之间有很多的相似,也就冗余的信息,单一图像内部,相邻区域的像素,相关性也很强,这就为编码创造了前提. 二.编码原理简单介绍 编码的前提是冗余,那么编码的目

R-CNN,SPP-NET, Fast-R-CNN,Faster-R-CNN, YOLO, SSD系列

就是想保存下来,没有其他用意 原博文:http://blog.csdn.net/qq_26898461/article/details/53467968 3. 空间定位与检测 参考信息<基于深度学习的目标检测研究进展> 3.1 计算机视觉任务 3.2 传统目标检测方法 传统目标检测流程: 1)区域选择(穷举策略:采用滑动窗口,且设置不同的大小,不同的长宽比对图像进行遍历,时间复杂度高) 2)特征提取(SIFT.HOG等:形态多样性.光照变化多样性.背景多样性使得特征鲁棒性差) 3)分类器(主要