Python Postgis ST_ClosestPoint - PullRequest
       4

Python Postgis ST_ClosestPoint

1 голос
/ 09 декабря 2011

Я борюсь с командой SQL, созданной из моего скрипта Python. Вот то, что я пробовал до сих пор, первый пример работает нормально, а остальные нет.

#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_ClosetsPoint? В последнем примере я изменил свои данные (в случае, если кто-то это заметил), чтобы запустить их, но они все равно не будут выполнены.

1 Ответ

0 голосов
/ 09 декабря 2011

Я не знаю, с какой геометрией вы имеете дело, но раньше у меня были такие же проблемы с MultiLineStrings, я понял, что когда MultiLinestring не может быть объединен, функция ST_Line_Locate_Point не работает. может знать, если MultiLineString невозможно объединить с помощью функции ST_LineMerge ). Я создал функцию pl / pgSQL на основе старого списка рассылки, но добавил некоторые изменения производительности, она работает только с MultiLineStrings и LineStrings ( но может быть легко изменено для работы с полигонами). Сначала он проверяет, имеет ли геометрия только 1 измерение, если оно есть, вы можете использовать старую комбинацию ST_Line_Interpolate_Point и ST_Line_Locate_Point, если нет, то вы должны сделать то же самое для каждой LineString в MultiLineString. Также я добавил 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; 

UPDATE:

Как отмечает @Nicklas Avén, ST_Closest_Point () должен работать, ST_Closest_Point был добавлен в 1.5.

...