热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:建筑物多边形化简系列之去除冗余点

本文由编程笔记#小编为大家整理,主要介绍了建筑物多边形化简系列之去除冗余点相关的知识,希望对你有一定的参考价值。制图综合和建筑物数据处理等都涉及到建筑物多边形的化简。制图综合中,由于比例
本文由编程笔记#小编为大家整理,主要介绍了建筑物多边形化简系列之去除冗余点相关的知识,希望对你有一定的参考价值。

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

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

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

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

1)冗余点

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

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

2)基本思想

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

3)代码实现

// 去除冗余点,zf,0717
void CGeoPolygon::RemoveRedundant(void)
{
for(int i = 0;i {
vector temp; //用于存放冗余点的下标
bool odinary = true; //设定状态,以确定三点单元的首点
int count = 0; //记录删除的点数,一旦有正常情况恢复为0
int ptsNum = circles[i]->pts.size();
for(int n = 0;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 tempPoints; //定义临时点集
if(tempPoints.size()!=0) vector().swap(tempPoints); //防止点集不为空
for(int j = 0;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
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 temp, int i)
{
bool answer = false;
for(int j = 0;j {
if(i == temp[j]) answer = true;
if(answer) break;
}
return answer;
}

4)效果展示

去除冗余点之前

 技术分享图片

去除冗余点之后

技术分享图片

5)小结

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



推荐阅读
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • C++中的三角函数计算及其应用
    本文介绍了C++中的三角函数的计算方法和应用,包括计算余弦、正弦、正切值以及反三角函数求对应的弧度制角度的示例代码。代码中使用了C++的数学库和命名空间,通过赋值和输出语句实现了三角函数的计算和结果显示。通过学习本文,读者可以了解到C++中三角函数的基本用法和应用场景。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
author-avatar
哥小名叫青蛙
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有