¿Crear buffers unilaterales o líneas paralelas en PostGIS?

19

Estoy buscando una manera de crear los llamados buffers unilaterales o líneas paralelas en PostGIS. Ejemplo: 1. búfer, 2. un lado, 3. ambos lados

texto alternativo

Encontré un poco de discusión en la lista de correo de 2009 e información de que se ha implementado en GEOS , pero nada sobre el estado actual de PostGIS.

En caso de que la función aún no esté implementada, ¿conoce alguna solución alternativa? ¿Es posible cortar un lado de un búfer normal?

bajo oscuro
fuente
Entonces, ¿está buscando un equivalente a "offset" en AutoCAD?
dassouki
@dassouki: Lo siento, no sé AutoCAD. Pero creo que UMN Mapserver tiene una opción de "desplazamiento" que haría lo que estoy buscando.
oscuro
¿Cómo crear buffers unilaterales o líneas paralelas, a partir de una tabla que tiene 600 líneas?
Bienvenido al sitio. Si el conjunto actual de respuestas no resuelve su problema, debe abrirlo como una nueva pregunta (e indicar por qué esta pregunta no responde a su problema). Dentro del formato del sitio, este no es un lugar apropiado para hacer esta declaración, ya que no es una respuesta a la pregunta.
Andy W
¿Cómo puedo crear líneas paralelas en una tabla MULTILINESTRING?
Felipe Costa

Respuestas:

13

Se suponía que los búferes de un solo lado debían aterrizar en 1.5 , pero me parece que si bien los estilos aterrizaron, la unilateralidad no lo logró. Sin embargo, hay un parche actual que expone GEOSSingleSidedBuffery realiza el búfer de un solo lado como se esperaba , bajo el nombre ST_OffsetCurve; ver más antecedentes en el boleto # 413 . En uso:

select ST_AsText(ST_OffsetCurve(
ST_GeomFromText('LINESTRING(10 10,10 20, 20 20 )'),
1,'right', 'join=mitre mitre_limit=5.0'));
--------------
LINESTRING(20 19,11 19,11 10)
scw
fuente
Hola, estoy tratando de usar esta solución, pero no uso postgis con frecuencia: he probado esta consulta y obtengo algunos valores de salida, pero ¿cómo los traduzco en características? Solo quiero las líneas al final, ya sea como parte de la tabla original o como una nueva. Esta es mi consulta: seleccione ST_AsText (ST_OffsetCurve (test_data_.geom, test_data_.buffer_dis, 'join = mitre mitre_limit = 5.0')) de test_data_;
kflaw
@kflaw: probablemente ya haya descubierto esto, pero solo necesita agregar al comienzo de la consulta: "crear nueva tabla como" o para una vista, "crear o reemplazar vista nueva vista como" seguido de la instrucción select.
jbalk
4

Esta muestra crea dos polígonos a cada lado de una cadena lineal. Requiere PostGIS 1.5 o superior. No estoy seguro de qué tan bien hará frente a las líneas que se cruzan.

SELECT ST_AsText(geom)

FROM ST_Dump ((

SELECT 
  ST_Polygonize(GEOMUNION(ST_Boundary(ST_Buffer(the_geom, 0.5, 'endcap=flat join=round')), the_geom)) AS buffer_sides 
FROM
  (SELECT ST_GeomFromText('LINESTRING(1 1, 1 5, 5 5)') AS the_geom) AS table1

));

Produce:

                        st_astext

------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------
 POLYGON((0.5 5,0.509607359798385 5.09754516100806,0.538060233744357 5.19134171618254,0.584265193848727 5.2777851165098,
0.646446609406726 5.35355339059327,0.722214883490199 5.41573480615127,0.808658283817455 5.46193976625564,0.9024548389919
36 5.49039264020162,1 5.5,5 5.5,5 5,1 5,1 1,0.5 1,0.5 5))
 POLYGON((5 5,5 4.5,1.5 4.5,1.5 1,1 1,1 5,5 5))
(2 rows)

El código funciona de la siguiente manera:

  1. Buffer la cadena de líneas usando ST_Buffer Aprovechamos la función PostGIS 1.5 que admite tapas finales personalizadas para no especificar ninguna tapa final. Ver ejemplo a continuación.
  2. Divida el polígono protegido en dos, usando la línea original, usando el método documentado en la wiki .

Esto podría mejorarse para hacer frente a las líneas de cruce automático en el futuro.

Una cadena lineal amortiguada con una tapa plana

fmark
fuente
3

Esta modificación crea dos cadenas lineales paralelas. Requiere PostGIS 1.5 o superior.

geometría requerida o wkt, y distancia en el búfer


SELECT astext(
     st_removepoint( 
     st_removepoint(        st_linemerge(ST_Difference(st_boundary(geom),ST_GeomFromText('LINESTRING(1 1, 1 5, 5 5)')))         ,0),
      st_npoints(st_linemerge(ST_Difference(st_boundary(geom),ST_GeomFromText('LINESTRING(1 1, 1 5, 5 5)'))))-2)

    ) as parallel
    FROM ST_Dump ((
    SELECT 
    ST_Polygonize(st_union(ST_Boundary(ST_Buffer(geometria, 0.5, 'endcap=flat join=mitre mitre_limit=5.0')), geometria)) AS buffer_sides 
    FROM
    (SELECT ST_GeomFromText('LINESTRING(1 1, 1 5, 5 5)') 
        AS geometria) AS tabla))

-------------- RESULTADOS

"LINESTRING(0.5 1,0.5 5.5,5 5.5)"
"LINESTRING(5 4.5,1.5 4.5,1.5 1)"

Dante Fuster
fuente
0

Como todavía no puedo comentar aquí, agrego esta respuesta

SCW da la mejor respuesta,

select ST_AsText(ST_OffsetCurve(
ST_GeomFromText('LINESTRING(10 10,10 20, 20 20 )'),
1, 'right', 'join=mitre mitre_limit=5.0'));
--------------
LINESTRING(20 19,11 19,11 10)

Pero parece que la función cambia
http://postgis.refractions.net/docs/ST_OffsetCurve.html

Ahora el 'right'parámetro no es necesario. El uso de la distancia positiva creará el lado izquierdo y la distancia negativa creará el lado derecho

Tampoco se necesita parche con mi postgis

SELECT PostGIS_full_version();
"POSTGIS="2.0.3 r11132" GEOS="3.3.8-CAPI-1.7.8" 
PROJ="Rel. 4.8.0, 6 March 2012" GDAL="GDAL 1.9.2, 
released 2012/10/08" LIBXML="2.7.8" LIBJSON="UNKNOWN" RASTER"
Juan carlos oropeza
fuente