Как проверить, действительно ли многострочный многострочный? - PullRequest
1 голос
/ 09 июля 2020

У меня огромная база данных с дорожной сетью и типом геометрии MULTILINESTRING . Я хотел бы отфильтровать MULTILINESTRINGS с топологическими ошибками. Обе строки слева и справа представляют собой запись, состоящую из двух строк. Теперь с правой стороны они подключаются, так что меня это особо не беспокоит, я могу объединить их позже без топологической ошибки. Однако с левой стороны они не соединяются, но они все равно являются одной записью. Многострочные Что я пробовал до сих пор:

SELECT gid 
FROM myschema.roads 
WHERE (
NOT ST_Equals(ST_Endpoint(ST_GeometryN(the_geom,1 )),ST_Startpoint(ST_GeometryN(the_geom,2 ))) 
    AND NOT ST_Equals(ST_Endpoint(ST_GeometryN(the_geom,2 )),ST_Startpoint(ST_GeometryN(the_geom,1 )))
)

Если бы я мог сказать, что MULTILINESTRINGS состоят максимум из двух строк, я полагаю, это сработает. К сожалению, некоторые из них состоят из 10-20 строк, и я не могу быть уверен, что части строки следуют друг за другом в порядке возрастания или убывания. Так что, на мой взгляд, расширение моего сценария SQL не вариант.

(Я использую QGIS с базой данных PostGIS, но у меня также есть ArcMap.)

Ответы [ 2 ]

3 голосов
/ 09 июля 2020

Если вы просто ищете способ определить, какие MultiLineStrings содержат более одной строки, вы можете просто использовать ST_LineMerge, затем ST_Dump и подсчитать возвращение LineStrings. Если геометрия содержит прерывистые линии, запрос вернет число больше 1, например

WITH j (geom) AS (
  VALUES ('MULTILINESTRING((10 10, 20 20, 10 40),(40 40, 30 30, 40 20, 30 10))'),
         ('MULTILINESTRING((10 10, 20 20, 10 40),(10 40, 30 30, 40 20, 30 10))'))
SELECT geom,(SELECT count(*) FROM ST_Dump(ST_LineMerge(geom))) 
FROM j;

                                geom                                 | count 
---------------------------------------------------------------------+-------
 MULTILINESTRING((10 10, 20 20, 10 40),(40 40, 30 30, 40 20, 30 10)) |     2
 MULTILINESTRING((10 10, 20 20, 10 40),(10 40, 30 30, 40 20, 30 10)) |     1
(2 Zeilen)

Другой альтернативой является использование ST_NumGeometries после применения ST_LineMerge, например

WITH j (geom) AS (
  VALUES ('MULTILINESTRING((10 10, 20 20, 10 40),(40 40, 30 30, 40 20, 30 10))'),
         ('MULTILINESTRING((10 10, 20 20, 10 40),(10 40, 30 30, 40 20, 30 10))'))
SELECT geom,ST_NumGeometries(ST_LineMerge(geom)) AS count
FROM j;
                                geom                                 | count 
---------------------------------------------------------------------+-------
 MULTILINESTRING((10 10, 20 20, 10 40),(40 40, 30 30, 40 20, 30 10)) |     2
 MULTILINESTRING((10 10, 20 20, 10 40),(10 40, 30 30, 40 20, 30 10)) |     1
(2 Zeilen)
1 голос
/ 09 июля 2020

Вы можете использовать эту функцию, чтобы проверить, подключена ли многострочная строка:

CREATE OR REPLACE FUNCTION is_connected(g geometry(MultiLineString)) RETURNS boolean
   LANGUAGE plpgsql AS
$$DECLARE
   i integer;
   point geometry := NULL;
   part geometry;
BEGIN
   FOR i IN 1..ST_NumGeometries(g) LOOP
      part := ST_GeometryN(g, i);

      IF NOT ST_Equals(point, ST_Startpoint(part)) THEN
         RETURN FALSE;
      END IF;

      point := ST_Endpoint(part);
   END LOOP;

   RETURN TRUE;
END;$$;
...