Python PostGIS ST_ClosestPoint 函数
我在用我的Python脚本发出一个SQL命令时遇到了困难。到目前为止,我尝试了这些,第一种例子运行得很好,但其他的都不行。
#working SQL = "SELECT ST_Distance(ST_Transform(ST_GeomFromText(%s, 4326),27700),ST_Transform(ST_GeomFromText(%s, 4326),27700));"
#newPointSQL = "SELECT ST_ClosestPoint(ST_GeomFromText(%s),ST_GeomFromText(%s));"
#newPointSQL = "SELECT ST_As_Text(ST_ClosestPoint(ST_GeomFromText(%s), ST_GeomFromText(%s)));"
#newPointSQL = "SELECT ST_AsText(ST_ClosestPoint(ST_GeomFromEWKT(%s), ST_GeomFromText(%s)));"
#newPointSQL = "SELECT ST_AsText(ST_Line_Interpolate_Point(ST_GeomFromText(%s),ST_Line_Locate_Point(ST_GeomFromText(%s),ST_GeomFromText(%s))));"
newPointData = (correctionPathLine,pointToCorrect) - ( MULTILINESTRING((-3.16427109855617 55.9273798550064,-3.16462372283029 55.9273883602162)), POINT(-3.164667 55.92739))
我的数据提取得还不错,因为第一个SQL执行成功了。问题出在我使用ST_ClosestPoint函数的时候。有没有人能发现我哪里用错了?我是不是把ST_ClosestPoint用错了?在最后一个例子中,我确实修改了我的数据(以防有人注意到),但它还是无法执行。
1 个回答
0
我不知道你在处理什么样的几何图形,但我之前也遇到过类似的问题,特别是关于多条线段(MultiLineStrings)。我发现当多条线段无法合并时,ST_Line_Locate_Point这个函数就不管用了。你可以通过使用ST_LineMerge函数来判断多条线段是否可以合并。我根据以前的邮件列表写了一个pl/pgSQL函数,并且做了一些性能上的优化。这个函数只适用于多条线段和单条线段(LineStrings),不过可以很容易地修改成适用于多边形(Polygons)。首先,它会检查几何图形是否只有一个维度,如果是的话,你可以使用旧的ST_Line_Interpolate_Point和ST_Line_Locate_Point的组合。如果不是,那你就得对多条线段中的每一条线段都进行同样的操作。此外,我还添加了一个ST_LineMerge,以确保在1.5版本之前也能兼容:
CREATE OR REPLACE FUNCTION ST_MultiLine_Nearest_Point(amultiline geometry,apoint geometry)
RETURNS geometry AS
$BODY$
DECLARE
mindistance float8;
adistance float8;
nearestlinestring geometry;
nearestpoint geometry;
simplifiedline geometry;
line geometry;
BEGIN
simplifiedline:=ST_LineMerge(amultiline);
IF ST_NumGeometries(simplifiedline) <= 1 THEN
nearestpoint:=ST_Line_Interpolate_Point(simplifiedline, ST_Line_Locate_Point(simplifiedline,apoint) );
RETURN nearestpoint;
END IF;
-- *Change your mindistance according to your projection, it should be stupidly big*
mindistance := 100000;
FOR line IN SELECT (ST_Dump(simplifiedline)).geom as geom LOOP
adistance:=ST_Distance(apoint,line);
IF adistance < mindistance THEN
mindistance:=adistance;
nearestlinestring:=line;
END IF;
END LOOP;
RETURN ST_Line_Interpolate_Point(nearestlinestring,ST_Line_Locate_Point(nearestlinestring,apoint));
END;
$BODY$
LANGUAGE 'plpgsql' IMMUTABLE STRICT;
更新:
正如@Nicklas Avén所提到的,ST_Closest_Point()应该可以正常工作,ST_Closest_Point是在1.5版本中新增的。