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:错误:对混合 SRID 几何图形的操作。试图用两个不同的 SRIDS/表找到重叠的几何