GIS矢量数据化简:一种改进的道格拉斯-普克算法以及C++实现
GIS领域的同志都知道,传统的道格拉斯-普克算法都是递归实现。然而有时候递归的层次太深的话会出现栈溢出的情况。在此,介绍一种非递归的算法。
要将递归算法改为非递归算法,一般情况下分为两种场景。第一种是问题定义是递归的,如阶乘、斐波那契数列等,对于这类问题,改为递归算法很简单,直接用迭代来做。另外一种是过程是递归的,如本文的道格拉斯-普克算法,对于这类问题呢,一般是用栈(stack)来记录中间结果,最后得到结果。
为了保证极值点的不被舍去,将曲线在弯曲极值点分为两段处理,弯曲极值点通过中间点与相邻两个顶点的角度度量。然而传统的Douglas-Peucker算法一般在计算过程中没有考虑到记录中间最大的距离的节点,造成循环时间长、递归嵌套层次太深,从而影响了程序的运行效率。本文提出一种结合栈数据结构的分段Douglas-Peucker算法,它从曲线的一端出发,首先将第一个点和最后一个点作为改进的Douglas-Peucker算法的工作区间,然后判断最远点的距离是否大于阈值,这样完成线要素的综合化简。改进D-P算法的具体步骤如下:
(1)寻找曲线曲率最大的点,将曲线以此点为界一分为二分成两部分,对于每一部分都有点列 。然后分别处理这两段曲线。
(2)对于第一段曲线,有矢量的离散点序列 ,设 并且 ,连接 组成一条线段。生成一个栈 ,将 点入栈 。
(3)在 之间的点中寻找与 线段距离最大的点,记为 。
(4)判断 点到 的距离是否小于阈值,若否,则设 ,并将 加入到特征点序列,将 压入栈 ,用线段连接 ,回到(3)。若是,执行第(5)步。
(5)判断 是否等于 的栈顶元素,若否,则设 、 , 表示栈顶,用线段连接 ,回到(3)。若是,执行(6)。
(6)判断 是否等于 ,若否,则设 、 ( 表示 的栈顶的下一点),用线段连接 ,栈顶元素出栈,回到(3)。
(7)当栈为空时,第一段曲线计算结束。处理第二段曲线,重复(1)~(7)。
改进算法的程序流程图如下图所示。
图 改进Douglas-Peucker流程图
本文提出的改进算法虽然在编程上面比较复杂,但是能够减少中间重复循环的次数。有了上面的流程图之后,那么代码就相对简单了。
void DouglasPeucker(LineVertex *V,int &i,int &j,double e)
{
double dist = ;
int f = ; //最大距离的点的序号
stack<int> tempVertex; //STL实现的栈
tempVertex.push(j); do
{
//循环i和j之间距离直线ij最大的点
FindSplit(*V,i,j,&f,&dist); if (dist > e) //大于阈值
{
(*V)[f].flag = true; j = f; //更新B值 tempVertex.push(f); //记录最大距离点,放入栈中存储
continue;
} else
{
if (!tempVertex.empty() && j != tempVertex.top()) //判断后一点是否和当前栈顶相等
{
i = f;
j = tempVertex.top();
continue;
}
else
{
if (j != V->size()) //判断最后一个点是否和当前线段的B点重合
{
i = j;
if (!tempVertex.empty())
{
deque<int> cont = tempVertex._Get_container();
if (cont.size() > ) //栈中至少还有两个点
{
j = cont[cont.size()-];
}
else if (cont.size() == ) //栈中只有一个点
{
j = cont[cont.size()-];
}
tempVertex.pop();
continue;
}
}
}
}
} while (!tempVertex.empty()); }
代码不是完整的,其中有调用到了另外一个函数,就是找曲线中离曲线两端点的直线的距离的最大值点,这个过程很简单,就不讲了,还有自己定义的一些数据结构,本文只是讲解这一种算法的思想,其中算法描述部分由公式,原文是在word中编辑的,如果看不懂就直接看流程图还清晰点。
文章来源:http://blog.csdn.net/zhouxuguang236/article/details/12313503
GIS矢量数据化简:一种改进的道格拉斯-普克算法以及C++实现的更多相关文章
- SSE图像算法优化系列十九:一种局部Gamma校正对比度增强算法及其SSE优化。
这是一篇2010年比较古老的文章了,是在QQ群里一位群友提到的,无聊下载看了下,其实也没有啥高深的理论,抽空实现了下,虽然不高大上,还是花了点时间和心思优化了代码,既然这样,就顺便分享下优化的思路和经 ...
- 两种方法实现Python二分查找算法
两种方法实现Python二分查找算法 一. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 arr=[1,3,6,9,10,20,30] def findnumber( ...
- [小专题]另一种字符串匹配的思路——Shift-And算法
吐槽:前两天打组队赛遇到一个字符串的题考了这个(见:http://acm.hdu.edu.cn/showproblem.php?pid=5972 ) 当时写了个KMP瞎搞然后TLE了(害),赛后去查了 ...
- K-means聚类算法的三种改进(K-means++,ISODATA,Kernel K-means)介绍与对比
一.概述 在本篇文章中将对四种聚类算法(K-means,K-means++,ISODATA和Kernel K-means)进行详细介绍,并利用数据集来真实地反映这四种算法之间的区别. 首先需要明确 ...
- GIS矢量大数据采集
1.使用什么工具采集 2.在哪个网站采集 3.采集哪一种数据 >>地理大数据公众号 >>大数据公众号 >>智能数据湖公众号 点.线.面.体 可视化 >> ...
- f-Strings:一种改进Python格式字符串的新方法
好消息是,F字符串在这里可以节省很多的时间.他们确实使格式化更容易.他们自Python 3.6开始加入标准库.您可以在PEP 498中阅读所有内容. 也称为“格式化字符串文字”,F字符串是开头有一个f ...
- 算法:Astar寻路算法改进,双向A*寻路算法
早前写了一篇关于A*算法的文章:<算法:Astar寻路算法改进> 最近在写个js的UI框架,顺便实现了一个js版本的A*算法,与之前不同的是,该A*算法是个双向A*. 双向A*有什么好处呢 ...
- 一种简单高效的音频降噪算法示例(附完整C代码)
近期比较忙, 抽空出来5.1开源献礼. 但凡学习音频降噪算法的朋友,肯定看过一个算法. <<语音增强-理论与实践>> 中提及到基于对数的最小均方误差的降噪算法,也就是LogMM ...
- 串的两种模式匹配方式(BF/KMP算法)
前言 串,又称作字符串,它是由0个或者多个字符所组成的有限序列,串同样可以采用顺序存储和链式存储两种方式进行存储,在主串中查找定位子串问题(模式匹配)是串中最重要的操作之一,而不同的算法实现有着不同的 ...
随机推荐
- linux命令学习之:ps
Linux中的ps命令是Process Status的缩写.ps命令用于报告当前系统的进程状态,列出系统中当前运行的那些进程.可以搭配kill指令随时中断.删除不必要的程序. 要对进程进行监测和控制, ...
- 32-改变eclipse默认的Tomcat部署路径
转载:https://www.cnblogs.com/helf/p/9433588.html eclipse中默认的项目部署路径是在项目的路径,不像myeclipse那样部署后项目在Tomcat的安装 ...
- connot connect to mysql 10061
根据我自己运行的情况,解决方法如下: 按windows+R, 输入services.msc查找服务,在服务与应用中找到MYsql服务,查看是否已启动.
- tomcat实现多端口、多域名访问(只针对一个tomcat)
说明:这个部分介绍如何在tomcat中进行配置,使同一个应用可以通过不同的端口号进行访问. 在某些需要进行安全控制的场景中会应用到.例如:不同地址段只能通过某个端口访问. 2 找到tomcat的主目录 ...
- ROS launch总结
1 运行Launch文件2 新建Launch文件3 在namespace中启动nodes 4 remapping names 5 其他的launch元素 1 运行Launch文件 Launch文 ...
- C# Convert.ToInt32和int.Parse转换null和空字符串时的不同表现
Convert.ToInt32最终调用的函数见下图: int.Parse调用的函数见下图: 具体的见https://www.cnblogs.com/leolis/p/3968943.html的博客,说 ...
- node.js下载安装
1.下载node.js在node中文网站,官方网站下载太慢 2.接着让我们点击下载链接,页面上呈现出你所需要下载的安装包,我们这里选择windows x64的安装包进行下载 3.安装node.js,一 ...
- C# oracle to_date 日期型 参数传值
C#操作oracle,date字段,使用参数传值 例子一,获取三小时前的记录 public static DataTable Query() { const string sSql = &qu ...
- PreparedStatement批量处理和事务
PreparedStatement批量处理和事务代码如下: /* * PreparedStatement: 1.addBatch() 将一组参数添加到 PreparedStatement对象内部 2. ...
- Ajax在jQuery中的应用 (4)向jsp提交表单数据
ajax技术带给我们的是良好的用户体验,同时,使用jquery可以简化开发,提高工作效率. 下面就介绍一下大致的开发步骤. 工具/原料 本文中使用的是 jquery-1.3.2.min.js 方法/步 ...