我正在使用postgis
' ST_LineLocatePoint
找出LineString
与给定Point
的最近点,并使用ST_LineInterpolatePoint
从返回的浮点数中提取Point
。
ST_LineLocatePoint
查询:
SELECT ST_AsText(ST_LineInterpolatePoint(foo.the_line,
ST_LineLocatePoint(foo.the_line,
ST_GeomFromText('POINT(12.962315 77.584841)')))) AS g
FROM (
SELECT ST_GeomFromText('LINESTRING(12.96145 77.58408,12.96219 77.58447,12.96302 77.58489,
12.96316 77.58496,12.96348 77.58511)') AS the_line
) AS foo;
输出:
g
------------------------------------------
POINT(12.9624389808159 77.5845959902924)
我所通过的linestring
究竟在哪里。演示显示here。
但是当我检查point
linestring
是否位于使用ST_Contains
的{{1}}时,它始终会返回false
,即使该点位于其中。
ST_Contains查询:
SELECT ST_Contains(ST_GeomFromText('LINESTRING(12.96145 77.58408,12.96219 77.58447,
12.96302 77.58489, 12.96316 77.58496, 12.96348 77.58511)'),
ST_GeomFromText('POINT(12.9624389808159 77.5845959902924)'));
输出
st_contains
-------------
f
我没有得到我做错的地方。任何人都可以帮助我。
Postgresql : 9.4
postgis : 2.1
答案 0 :(得分:2)
我没有得到我做错的地方。
我觉得你做得很好......前段时间我遇到了同样的问题......我用ST_ClosestPoint来定位线串上的点,然后用这一点剪切一个线串,但我可以& #39;吨。
遵循文件:
ST_ClosestPoint - 返回g1上的二维点 最接近g2。这是最短线的第一点。
所以我得到一个函数说的情况 - 这一点在一条线上,其他函数说 - 好的,但是我不能削减因为你的观点不在线......我很困惑你和我一样#39;现在......
在我的情况下,分辨率是绘制另一条线,它将与第一条线完全相交。在给定的点上,在第一行被切断后......
经过一番研究后,我发现问题是关于计算和写入的坐标的舍入。我向自己解释说,根据定义,线条是无限薄的,点是无限小的(它们没有区域),所以它们很容易错过对方 - 但它是我的推理,而且我'我不确定它是否好。我建议你使用st_intersects,但st_buffer或ST_DWithin功能非常低,距离也很短。
为了确保你的点位于一条线上,它必须是该线的一部分(例如LINESTRING(0 0,5 5)点(0 0)和(5 5)。点(3 3)示例因为它的坐标在没有任何舍入的情况下计算,所以可以正常工作。
答案 1 :(得分:1)
这实际上是一个非常常见的问题(很可能是重复的,但我很懒,找不到它。)
问题与数值精度有关,其中Point在LineString上不是完全,但距离它很小。有点像SELECT sin(pi())
不完全为零。
不是使用通常期望精确编码的DE-9IM spatial predicates(如包含或封面等),而是使用距离阈值较小的ST_DWithin等基于距离的技术。例如:
SELECT ST_Distance(the_point, the_line),
ST_Covers(the_point, the_line),
ST_DWithin(the_point, the_line, 1e-10)
FROM (
SELECT 'POINT(12.9624389808159 77.5845959902924)'::geometry AS the_point,
'LINESTRING(12.96145 77.58408,12.96219 77.58447,12.96302 77.58489,12.96316 77.58496,12.96348 77.58511)'::geometry AS the_line
) AS foo;
-[ RECORD 1 ]----------------------
st_distance | 1.58882185807825e-014
st_covers | f
st_dwithin | t
在这里你可以看到ST_DWithin表示该点在该行的一个非常小的距离内,因此它实际上包含该点。
答案 2 :(得分:0)
ST_Contains()
位于提供的true
内,则 geometry
仅返回geometry
。在您的情况下,point
必须在<{>} <{1}}内,这始终为linestring
,因为false
没有内部。
如果linestring
无法测试(ST_Covers()
)在之外,则应使用true
函数:geometry
提供point
(您的geometry
)。