基于PostGIS的曲线拐点计算

这篇具有很好参考价值的文章主要介绍了基于PostGIS的曲线拐点计算。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在这篇博文中,我将介绍一种查找曲线拐点的方法。 一个简单的理解方式:将曲线想象成我们正在行驶的道路,我们想要找到我们停止右转并开始左转或反之的点,如下所示:

我们将展示解决方案的草图和 PostGIS 中的实际实施。 我认为这是一个很好的展示在数据库中实现 GIS 算法的有用技术的简单示例。

基于PostGIS的曲线拐点计算

推荐:用 NSDT设计器 快速搭建可编程3D场景。

1、解决方案的草图

这个问题可以用非常标准的二维计算几何资源来解决。 特别是,使用叉积作为检测点位于给定直线左侧还是右侧的方法在这里很有用。 以下伪代码基于行列式:

function isLeft(Point a, Point b, Point c){ 
	return ((b.X - a.X)*(c.Y - a.Y) - (b.Y - a.Y)*(c.X - a.X)) > 0; 
}

总的来说,我反对实现你自己的计算几何代码:数学公式的直接翻译通常会遇到舍入错误、极端情况和明显的低效率问题。 你最好使用优秀的计算几何库之一,例如:GEOS,它最初是作为 JTS 的一个移植,或 CGAL。 无论如何你都可能在使用它们,因为它们位于许多 GIS 软件堆栈的底部。 这适用于任何非平凡的数学(线性代数、优化……)。 记住:浮点数不是实数。

在这种情况下,我更关心实用性而不是纯粹的效率,使用 SQLs 数字类型以牺牲速度为代价提供任意精度的算术,防止了我们在双精度时会遇到的一些舍入错误,节省了 我们自己实施快速健壮的谓词。

2、PostGIS 实现

长期以来,我一直认为 Postgres/PostGIS 是地理空间分析的最佳工作台(证明我错了)。 在许多用例中,能够直接在存储数据的地方执行分析是无与伦比的。 必须编写 SQL 脚本对于某些用户来说可能是一种倒退,但在数据工作流的可重现性和可追溯性方面很有用。

在这种特殊情况下,我们假设我们的输入是一个包含 LineString 几何特征的表格,每个几何特征都有其唯一标识符。 当然,在任何计算之前,都会对几何图形进行适当的索引和有效性测试。 在开发过程中,通过感兴趣的区域将计算限制在数据的子集内,以缩短测试结果和参数的迭代过程也很有用。

解决方案的草图是:

  • 简化几何结构以避免噪声(误报)。 ST_Simplify 或 ST_SimplifyPreserveTopology 就足够了。
  • 分解点,跟踪原始几何图形,这可以使用 generate_series 和 ST_DumpPoints 轻松完成。
  • 我们需要 3 个点来计算 isLeft:2 个来定义段,1个是要测试的点。 因此,对于沿 LineString 的每个点,我们得到该点本身和前 2 个点的 X、Y 坐标。 我们将检查当前点相对于前两个点定义的线段的位置。 这也意味着当检测到转折点时,将是该段的最后一个点,即:前一个点。 我发现通过 Posgres 窗口函数这个计算出奇的简单。
  • 使用以上几点来计算 isLeft 的度量。
  • 选择此度量更改的点。

像往常一样,良好的代码实践通常也适用于数据库。 特别是,CTE 可用于阐明查询,就像在任何编程语言中命名变量或函数一样:以实现重用,同时通过提供描述性名称来增强可读性。 任何在该语言中通常被认为是正常的令人眼花缭乱的 SQL 查询都没有任何借口。

查看草图解决方案并与以下实现进行对比以了解我的意思:

WITH 
  -- Optional: area of interest.
  aoi AS (
    SELECT ST_SetSRID(
          ST_MakeBox2D(
            ST_Point(467399,4671999),
            ST_Point(470200,4674000))
          ,25831) 
        AS geom
  ),
  -- Simplify geometries to avoid excessive noise. Tolerance is empiric and depends on application
  simplified AS (
    SELECT oid as contour_id, ST_Simplify(input_contours.geom, 0.2) AS geom 
    FROM input_contours, aoi
    WHERE input_contours.geom && aoi.geom
  ), 
  -- Explode points generating index and keeping track of original curve
  points AS (
    SELECT contour_id,
        generate_series(1, st_numpoints(geom)) AS npoint,
        (ST_DumpPoints(geom)).geom AS geom
    FROM simplified
  ), 
  -- Get the numeric values for X an Y of the current point 
  coords AS (
    SELECT *, st_x(geom)::numeric AS cx, st_y(geom)::numeric AS cy
    FROM points    
    ORDER BY contour_id, npoint
  ),
  -- Add the values of the 2 previous points inside the same linestring
  -- LAG and PARTITION BY do all the work here.
  segments AS (
    SELECT *, 
      LAG(geom, 1)        over (PARTITION BY contour_id) AS prev_geom, 
      LAG(cx::numeric, 2) over (PARTITION BY contour_id) AS ax, 
      LAG(cy::numeric, 2) over (PARTITION BY contour_id) AS ay, 
      LAG(cx::numeric, 1) over (PARTITION BY contour_id) AS bx, 
      LAG(cy::numeric, 1) over (PARTITION BY contour_id) AS by
    FROM coords
    ORDER BY contour_id, npoint
  ),
  det AS (
    SELECT *, 
      (((bx-ax)*(cy-ay)) - ((by-ay)*(cx-ax))) AS det -- cross product in 2d
    FROM segments
  ),
  -- Uses the SIGN multipliaction as a proxy for XOR (change in convexity) 
  convexity AS (
    SELECT *, 
      SIGN(det) * SIGN(lag(det, 1) OVER (PARTITION BY contour_id))
AS change
    FROM det
  )
SELECT contour_id, npoint, prev_geom AS geom
FROM convexity
WHERE change = -1
ORDER BY contour_id, npoint

以下是示例区域的结果:
基于PostGIS的曲线拐点计算


原文链接:PostGIS曲线拐点计算 — BimAnt文章来源地址https://www.toymoban.com/news/detail-443858.html

到了这里,关于基于PostGIS的曲线拐点计算的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 希望所有计算机学生能看到这篇c语言教程

    大部分程序员走入编程世界第一个学习的语言就是C语言。 作为一门古老的编程语言,c语言拥有48年的发展历程。 C语言是学习计算机程序设计语言的入门语言。最全面的编程面试网站 C语言是一门偏底层的语言,学好它,可以让你更好的了解计算机。 学会了C语言,你就能学

    2024年02月01日
    浏览(46)
  • c++计算贝塞尔曲线(折线平滑为曲线)坐标方法

    效果可查看上一篇博文: js手动画平滑曲线,贝塞尔曲线拟合 【代码】js手动画平滑曲线,贝塞尔曲线拟合。 https://blog.csdn.net/qiufeng_xinqing/article/details/131711963?spm=1001.2014.3001.5502 代码如下:

    2024年02月16日
    浏览(37)
  • 计算机图形学中的曲线问题——拉格朗日插值曲线绘制实践

    限于篇幅,我们将在这篇文章中介绍拉格朗日插值曲线绘制实践,主文章链接: GGN_2015 计算机图形学中的曲线问题 在主文章中我们已经介绍了拉格朗日插值函数的绘制方法。给定一个函数必须通过的点的集合,保证任意两点 x x x 指不同,我们就能构造出一条拉格朗日插值函

    2024年02月14日
    浏览(46)
  • 曲线拟合的数值方法——《数值计算方法》

    《数值计算方法》系列总目录 第一章 误差序列实验 第二章 非线性方程f(x)=0求根的数值方法 第三章 CAD模型旋转和AX=B的数值方法 第四章 插值与多项式逼近的数值计算方法 第五章 曲线拟合的数值方法 第六章 数值微分计算方法 第七章 数值积分计算方法 第八章 数值优化方法

    2024年02月07日
    浏览(52)
  • 【计算机图形学】曲线和曲面

    模块5 曲线和曲面 一 实验目的 编写曲线和曲面的算法 二 实验内容 1 :绘制Bezier曲线,并采用自行设计输入和交互修改数据点的方式。 实验结果如下图所示: 第一步:输入特征多边形的顶点个数,并按照顺序输入顶点的坐标。 第二步:点击左键生成bezier曲线(白色部分)和

    2024年02月06日
    浏览(45)
  • 椭圆曲线加密算法(ECC)——计算问题

    椭圆曲线加密算法,简称ECC,是基于椭圆曲线数学理论实现的一种非对称加密算法。 一般情况下,椭圆曲线可用下列方程式来表示,其中a,b,c,d为系数。 E:y2=ax3+ bx2+cx+d 题目:已知点G=(2,7)在椭圆曲线E11(1,6)上,计算2G的值。 ! 1这里设Q为椭圆曲线上的一个点,叫做基点

    2024年02月11日
    浏览(40)
  • 【MATLAB】matlab曲线拟合与矩阵计算技巧

    目录 1.曲线拟合定义 2.数据预处理 3.数据拟合 4.数据拟合matlab编程例子 5.数据拟合函数表 6.matlab中常用插值方法 7.矩阵的特征值分解         在实际工程应用和科学实践中,经常需要寻求两个(或多个)变量间的关系,而实际去只能 通过观测得到一些离散的数据点。针对这

    2024年02月02日
    浏览(45)
  • 为了解决小程序tabbar闪烁的问题,我将小程序重构成了 SPA

    (日落西山,每次看到此景,我总是会想到明朝(明朝那些事儿第六部的标题,日落西山)) 目录 前言 官网自定义tabbar 猜测bug产生原因 解决闪烁问题 写在最后 几个月前,因工作需求,我开发了一个小程序,当时遇到了一个需求,是关于tabbar权限的问题。小程序的用户分两

    2024年02月03日
    浏览(36)
  • 我将青春奉献给了我喜欢的事情,却让我无法解决温

    时间过的很快,3 年的疫情就这么过去了,留下的却是紧张的社会氛围。 目前已经在计算机行业 7 年了,记得那是 2015 年,当时我也才 15 岁,正在读初二。那会特别喜欢别人的网站,比如卡盟,还有代挂等等别人的那些网站,然后我入坑了。我那会百度怎么做一个网站,然后

    2024年02月11日
    浏览(40)
  • 提取图像中的曲线并用于计算(MATLAB)

    应小姐姐所邀 原因是小姐姐拿到供应商的一张图表,但是没有具体的数值,更糟糕的是她还想对图中的几条曲线求和。。。。 在这个提供了一种使用matlab提取曲线的方式; 1、首先根据图表颜色筛选出曲线的像素点坐标(彩色图像) 2、根据图像的像素和实际标注额尺寸进行

    2024年02月13日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包