Tengo una base de datos enorme con una red de carreteras y el tipo de geometría es MULTILINESTRING . Me gustaría filtrar las MULTILINESTRINGS con errores topológicos. Tanto las líneas del lado izquierdo como del lado derecho son registros uno a uno, formados por dos líneas. Ahora en el lado derecho se conectan, por lo que realmente no me molesta, puedo fusionarlos más tarde sin un error topológico. Sin embargo, en el lado izquierdo no se conectan, pero siguen siendo un registro.
Lo que he probado hasta ahora:
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 ))) )Si pudiera decir que las MULTILINESTRINGS se componen de un máximo de dos líneas, supongo que funcionaría. Desafortunadamente, algunos de ellos están formados por 10-20 líneas, y no puedo estar seguro de que las partes de la línea se sigan en orden ascendente o descendente. Entonces, en mi opinión, extender mi script SQL no es una opción.
(Estoy usando QGIS con una base de datos PostGIS, pero también poseo ArcMap).
Si simplemente está buscando una manera de identificar qué MultiLineStrings contienen más de una línea, simplemente puede usar ST_LineMerge , luego ST_Dump y contar las LineStrings regresan. En caso de que una geometría contenga líneas no continuas, la consulta devolverá un recuento mayor que 1, por ejemplo
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) Otra alternativa es usar ST_NumGeometries después de aplicar ST_LineMerge , por ejemplo
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)Puede usar esta función para verificar si la cadena multilínea está conectada:
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;$$;