5 votos

¿Cómo dividir líneas con PostGIS y ver el resultado en QGIS?

Tengo dos tablas, una de ellas contiene líneas (test_line) y el otro contiene los puntos en los vértices de las líneas (test_line_vertex). enter image description here

Quiero dividir la línea en segmentos individuales basados en los vértices. He intentado de la siguiente consulta:

CREATE TABLE test_intersect AS    
SELECT ST_Split(a.wkb_geometry,b.wkb_geometry)
FROM test_line as a,
    test_line_vertex as b;

Devuelve correctamente las filas con los segmentos de línea, pero cuando trato de mostrar en QGIS esto me demuestra que algo está mal. El tipo espacial no está definido y no puedo ver las líneas en QGIS. Así que yo supongo que algo está mal con mi consulta. Cualquier ayuda es muy apreciada.

enter image description here

4voto

Patrick Puntos 20392

EDITAR

Hay un plpgsql función es la de este post que se divide una Línea con múltiples puntos.

Sin embargo, también se puede hacer en una consulta, mediante generate_series, ST_Line_Locate_Point y ST_GeometryN para obtener cuchillo puntos y ST_Line_Substring para dividir la línea. Lo que usted prefiera, os dejo a vosotros, esta consulta no es exactamente concisa.

 CREATE TABLE sometable AS
 WITH 
 lines as (SELECT ST_GeomFromText('LINESTRING(0 0, 2 2, 10 10, 15 15, 20 20)') as geom),
 points as (SELECT ST_GeomFromText('MultiPoint((0 0), (2 2), (10 10), (15 15), (20 20))') as geom),
 numgeoms (pt_count) as (SELECT st_numgeometries(geom) + 1 as pt_count FROM points),
 knife_points as (
   SELECT x as segment, CASE WHEN x = 0 then 0 
     WHEN x = (select pt_count from numgeoms) THEN 1 ELSE  
     ST_Line_Locate_Point(l.geom, ST_GeometryN(p.geom,x)) END as line_fraction_end, 
     CASE WHEN x = 1 THEN 0  else 
     ST_Line_Locate_Point(l.geom, ST_GeometryN(p.geom,x-1)) END as line_fraction_start 
   FROM points p, lines l, (SELECT generate_series(0, (SELECT pt_count from numgeoms)) as x ) g),
   segments as 
    (SELECT ST_Line_Substring(geom, line_fraction_start, line_fraction_end) as geom, segment 
     FROM knife_points, lines WHERE segment >0 )
   SELECT geom, segment from segments 
   WHERE ST_GeometryType(geom) = 'ST_LineString';

donde habría que reemplazar las líneas iniciales y puntos de tablas con su propio. Sospecho que esta consulta podría ser simplificado un poco por el uso de plomo o lag, para obtener calcular cada una de las sucesivas par de cuchillo puntos, pero no funciona.

La salida de la anterior,

 LINESTRING(0 0,2 2)     |       2
 LINESTRING(2 2,10 10)   |       3
 LINESTRING(10 10,15 15) |       4
 LINESTRING(15 15,20 20) |       5

Post Original:

Usted debe combinar con ST_Dump, para obtener el constituyente Linestrings, y su uso como wkb_geom o algún otro alias, para evitar la salida se llamaba por el nombre de la función, como en el st_split que usted está viendo. Algo así como:

CREATE TABLE test_intersect AS    
SELECT (ST_Dump(ST_Split(a.wkb_geometry, b.wkb_geometry))).geom as wkb_geom,
row_number() over() ad gid
FROM 
   test_line as a,
   test_line_vertex as b;

Usted querrá un id también, o más de QGIS se carga, pero no mostrar, sus líneas.

Usted también puede poner un WHERE ST_GeometryType(geom) = 'ST_LineString' en tu consulta, para obtener sólo Linestrings de vuelta de ST_Dump, como la consulta siguiente se muestra:

WITH geoms (geom) as 
  (SELECT ST_Union(ST_GeomFromText('LINESTRING(0 0, 10 10)'),
                  ST_GeomFromText('POINT(20 20)'))),
dumped (geom, id) as
 (SELECT (ST_DUMP(geom)).geom, row_number() over() as id FROM geoms)
SELECT id, geom from dumped WHERE  ST_GeometryType(geom) = 'ST_LineString';

que después de unioning una línea y el punto a GeometryCollection en la primera consulta de CTE, se acaba de dar de nuevo un LineString. En tu caso, sólo tienes que tener LineStrings, pero pensé que iba a ponerlo en la integridad, como las operaciones, tales como ST_Split y ST_Union a menudo produce el temido GeometryCollection.

0voto

Bill B Puntos 137

Cuando trato de la solución

me sale el siguiente error:

"ERROR: más de una fila devuelta por una subconsulta que usa como una expresión" con la siguiente consulta sql:

CREATE TABLE osm.roads_separado AS

 WITH 

 lines as (SELECT geom from osm.lines),
 points as (SELECT geom from osm.points),
 numgeoms (pt_count) as (SELECT st_numgeometries(geom) + 1 as pt_count FROM osm.points),

 knife_points as (

   SELECT x as segment, CASE WHEN x = 0 then 0 
     WHEN x = (select pt_count from numgeoms) THEN 1 ELSE  
     ST_Line_Locate_Point(l.geom, ST_GeometryN(p.geom,x)) END as line_fraction_end, 
     CASE WHEN x = 1 THEN 0  else 
     ST_Line_Locate_Point(l.geom, ST_GeometryN(p.geom,x-1)) END as line_fraction_start 
   FROM points p, lines l, (SELECT generate_series(0, (SELECT pt_count from numgeoms)) as x ) g
 ),

 segments as (
   SELECT ST_Line_Substring(geom, line_fraction_start, line_fraction_end) as geom, segment 
     FROM knife_points, lines WHERE segment >0 
 )

 SELECT 
 geom, 
 segment 

 from segments 
 WHERE ST_GeometryType(geom) = 'ST_LineString';

¿Por qué? Hay gran cantidad de líneas y puntos.

¿Qué necesito cambiar? ¡TXS!

(lo siento no pude agregar comentario en solución!)

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X