Postgis几何边界上的两个最近点

Posted

技术标签:

【中文标题】Postgis几何边界上的两个最近点【英文标题】:Two closest points on boundary of Postgis geometry 【发布时间】:2012-08-21 23:26:47 【问题描述】:

我有一个表geofences 存储了多边形的geometry

我还有一个点A,它位于几何内部。我要做的是找到距点A 最接近的两个点,它们位于多边形几何的表面上。

PostGIS 中的功能:

CREATE OR REPLACE FUNCTION accuracyCheck(Polygon geometry
                                        ,decimal lat
                                        ,decimal lon)
  RETURNS VARCHAR AS
$BODY$

DECLARE height DECIMAL;
DECLARE accuracy VARCHAR(250);

BEGIN 

CREATE TEMPORARY TABLE closePointStorage AS
SELECT ST_AsText(ST_ClosestPoint(geometry
                                ,ST_GeomFromText('POINT(lat lon)',0)
                                )
                ) AS closestPoint
FROM  (
   SELECT ST_GeomFromText(geometry) as geometry
   FROM gfe_geofences
   WHERE is_active=true
   ) As tempName;

CREATE TEMPORARY TABLE areaStorage ON COMMIT DROP AS
SELECT ST_Area(ST_GeomFromText('Polygon((23.0808622876029 96.1304006624291
                                        ,28.0808622876029 99.1304006624291
                                        ,100              200
                                        ,23.0808622876029 96.1304006624291
                                        ))'
                              ,0)
              ) AS area;

CREATE TEMPORARY TABLE distanceStorage ON COMMIT DROP AS
SELECT ST_Distance(
          ST_GeomFromText('POINT(23.0808622876029 96.1304006624291)',-1)
         ,ST_GeomFromText('POINT(28.0808622876029 99.1304006624291)',-1)
         ) AS distance;

height = (SELECT area FROM areaStorage)
        /(0.5*(SELECT distance FROM distanceStorage));

IF height < (SELECT radius_meters
             FROM gfe_geofences Where is_active=true) THEN
   accuracy = "FullConfirm";
   RETURN accuracy;
ELSE
   accuracy = "PartiallyConfirm";
   RETURN accuracy;
END IF;

END;
$BODY$ LANGUAGE plpgsql;

我只想在多边形几何的边界上找到两个点。就像我从查询中找到的一样:

CREATE TEMPORARY TABLE closePointStorage AS
SELECT ST_AsText(ST_ClosestPoint(geometry
                                ,ST_GeomFromText('POINT(lat lon)',0)
                                )
                ) AS closestPoint 
FROM  (
   SELECT ST_GeomFromText(geometry) as geometry
   FROM gfe_geofences
   WHERE is_active=true
   ) 
AS tempName;

除此之外,我必须再找到一个距离大于上面找到的点但小于其余点的点。

【问题讨论】:

双纬度1 = Math.toRadians(26.5534d);双 lon1 = Math.toRadians(75.4925d);双 lat2 = Math.toRadians(28.3650d);双 lon2 = Math.toRadians(77.1232d);双 dellat = (lat2 - lat1);双德隆 = (lon2 - lon1);双 R = 6371;双 a = Math.sin((dellat) / 2) * Math.sin((dellat) / 2) + Math.cos(lat1) * Math.cos(lat2) * Math.sin((dellon) / 2) * Math.sin((dellon) / 2);双 c = 2 * (Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)));双 d = R * c; System.out.println("km = " + d); 在循环中计算每个点与点 A 的几何距离,并找出与所有点的两个最小或最小距离。 如果您只关心几何中的点,而不关心点之间的线段,您可以将多边形的边界转换为 MULTIPOINT,找到最近的点,将其删除,然后找到第二个最近点。 很难解读您添加的评论。为此目的,使用适当的格式更新您的问题。还要在您的问题中为大功能添加一些解释:它应该做什么?它到底在哪里失败?结果应该是什么样子(示例值)? 如果您关心线段上的点,则第二近点的定义不明确。假设您有直线 y=1,点 x=2,y=2。直线上最近的点是 x=2, y=1。第二个最近的点将是“紧邻”x=2, y=1,但对于您选择的任何点(例如 x=2.01,y=1),还有另一个更接近的点(x=2.005,y=1)。 【参考方案1】:

我假设您想找到最接近相关点的多边形边缘

获取点'C'到线[A,B]的距离'd' 首先平移所有点,使 A 位于 0,0

B -= A  //vector subtraction
C -= A

然后对 B 进行归一化,使其长度为 1.0

len = sqrt( B . B) //dotproduct of two vectors is the length squared
B /= len  //scalar divide by length

从 A 中找出与 C 成直角的长度

dotp = B . C  //dot product again
closestPointOnLine =  B * dotp  //scalar multiply

现在获取距离

diff = (C - ClosestPointOnLine)
d = sqrt(diff . diff)  

不确定如何在 SQL 中执行此操作。您需要对多边形上的每条边执行上述操作,然后找到最小值 'd'

顺便说一下,B 和 C 的叉积的符号现在会告诉您该点是否在多边形内部

【讨论】:

你的算法很好,可以理解,你的努力,我会尝试在 Sql 中使用相同的,因为我的依赖是让这种算法只在 sql 中实现。【参考方案2】:

1) 有点左场的想法,但是要找到离目的地最近的第二点,为什么不找到离你已经找到的点最近的点呢?

2) 或者,更贴近您的具体问题,

在点的某个合理范围内找到点的集合, 找到该集合与多边形边界上的点集合的交集(我猜这可能是另一个 PostGIS 函数;有一段时间没有使用 postG,所以我不确定)

3) 进一步进入左侧字段,将一些数据集转储到 Mongo 并使用 $near 函数...http://docs.mongodb.org/manual/reference/operator/near/

【讨论】:

【参考方案3】:

如果包含线,边界多边形上通常没有第二个最近点。就像没有第二个最接近零的实数一样。 要么你只想考虑角落的点,就像马库斯建议的那样。 或者你只有一个最近的点。

【讨论】:

【参考方案4】:

使用 ST_DumpPoints() 转储多边形的点,然后从 ST_Distance 到 A 限制 2 的顺序中选择。 ?

所以它有点像

SELECT * from ST_DumpPoints(poly) order by ST_Distance(A,geom) asc limit 2;

(假设这是一个内部选择,其中 poly 是多边形,A 是要比较的点,geom 是要比较的多边形中的一个点的几何列)

【讨论】:

这自然不会选择直线上的点,只会选择多边形定义中的点。此外,如果您可以按距离的平方排序它们会更快。

以上是关于Postgis几何边界上的两个最近点的主要内容,如果未能解决你的问题,请参考以下文章

如何在postgis中找到几何半径?

如何从实际上在 Postgis 中的多边形内的多边形中获取最近点

POSTGIS:错误:对混合 SRID 几何图形的操作。试图用两个不同的 SRIDS/表找到重叠的几何

PostGIS官方教程汇总目录

如何在 Sequelize ORM 中插入 PostGIS GEOMETRY 点?

将 PostGIS 与 ormLite 一起使用