spatial query

Segmentar líneas (split line with point)

Hola  :

después de un prolongado tiempo de ausencia por motivos laborales, a pedido de unos amigos de foro, les dejo una «entrada»  respecto a la segmentación de líneas con puntos que se intersectan a lo largo de su geometría.

he aquí el ejercicio:

cuenca_0

 

«El río Vichaycocha  tiene a lo largo de su recorrido varios afluentes y tributarios que lo alimentan, se desea segmentarlo en cada interseccion para un mejor aprovechamiento del recurso hídrico».

Para desarrollar este ejercicio haremos lo siguiente:

  1. Buscaremos las intersecciones entre el río , afluentes y tributarios.
  2. Generaremos el índice y la geometría que representa la posición de cada intersección a lo largo de las líneas (lo llamaremos así a los ríos, afluentes y tributarios).
  3. Reconstruir  los ríos, afluentes y tributarios.

Solución

  1. Usamos la función st_intersections para encontrar los puntos que intersectan entre las mismas líneas.

 

  select distinct on (id_rio)id_rio ,nombre,geom from (

        select a.nombre nombre,a.id_rio id_rio,st_intersection(a.geom,b.geom) geom from rios a
        inner join rios b
        on st_intersects(a.geom,b.geom) and a.id_rio <> b.id_rio ---Puntos que se intersectan
        
    )t1-- para seleccionar los únicos ya que se duplican al intersectar recurremente puntos y líneas

Como vemos en el gráfico siguiente se han generado las intersecciones entre la líneas (punto rojo), pero vemos un detalle para recunstruir totalmente el río, necesitamos agregar el punto inicial y final de la línea (punto azul).

select nombre,id_rio,st_startpoint(geom) from rios
union all
select nombre,st_endpoint(geom) from rios

cuenca_1

2. Para generar el índice y la geometría de la posición de cada intersección  a lo largo de la línea usaremos la función st_line_locate_point    , usaremos los puntos intersectados y lo rankeramos (dense_rank—>función ventana) ordenados por el mismo índice de la posición. (Lo insertaremos en una tabla temporal)

Para asegurarnos que exista un nodo en cada intersección, haremos un buffer muy pequeño a los puntos intersectados.

select dense_rank() over(partition by a.id_rio order by a.id_rio,a.gid ,st_line_locate_point(a.geom,b.geom)) id,st_line_locate_point(a.geom,b.geom) fraccion_inicial,
 a.geom,a.id_rio,a.nombre from rios a
inner join 
    ( interseccion_rios 
    ) b
on st_intersects (a.geom,st_buffer(b.geom,0.0000000008980532)) and st_dwithin(a.geom,b.geom,0.000000898)

como vemos  en el gráfico se ha generado la fracción de la posición del punto.

cuenca_indice

3. Ya solo nos queda regenerar la línea con la función st_line_substring , que nos pide los siguientes parámetros : geometría, fraccion inicial y final.Para la fracción final repetir el paso 2

select id_rio,nombre, st_line_substring(geom,frac_in,frac_fin) from tabla_temp

segmentados

Listo  una geometría por cada interseccion, espero los sirva y compartan el conocimiento

!!!!!!!Olvidense del arcgis!!!!!!!!