Criando buffers unilaterais ou linhas paralelas no PostGIS?

19

Estou procurando uma maneira de criar os chamados buffers unilaterais ou linhas paralelas no PostGIS. Exemplo: 1. buffer, 2. um lado, 3. ambos os lados

texto alternativo

Encontrei alguma discussão na lista de discussão de 2009 e informações que foram implementadas no GEOS , mas nada sobre o status atual do PostGIS.

Caso a função ainda não esteja implementada, você conhece alguma solução alternativa? É possível cortar um lado de um buffer normal?

underdark
fonte
Então, você está procurando um equivalente a "deslocamento" no AutoCAD?
dassouki
@dassouki: Desculpe, eu não conheço o AutoCAD. Mas acho que o UMN Mapserver tem uma opção "offset" que faria o que estou procurando.
Subterrâneo
Como criar buffers unilaterais ou linhas paralelas, a partir de uma tabela que possui 600 linhas?
Bem vindo ao site. Se o conjunto atual de respostas não resolver o seu problema, você deve abri-lo como uma nova pergunta (e indicar por que essa pergunta não responde ao seu problema). Dentro do formato do site, este não é um local apropriado para fazer essa afirmação, pois não é uma resposta para a pergunta.
Andy W
Como posso criar linhas paralelas em uma tabela MULTILINESTRING?
Felipe Costa

Respostas:

13

Os buffers unilaterais apropriados deveriam ter caído em 1,5 , mas parece-me que, embora os estilos aterrissem, o lado não o alcançou . No entanto, existe um conjunto de patches atual que expõe GEOSSingleSidedBuffere executa o buffer unilateral conforme o esperado , sob o nome ST_OffsetCurve; veja mais detalhes no ticket # 413 . Em 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
fonte
Oi Estou tentando usar esta solução, mas não use o postgis com frequência - testei essa consulta e obtive alguns valores de saída, mas como faço para traduzi-los em recursos? Eu só quero as linhas no final, como parte da tabela original ou uma nova.Esta é minha consulta: selecione ST_AsText (ST_OffsetCurve (test_data_.geom, test_data_.buffer_dis, 'join = mitre mitre_limit = 5.0')) de test_data_;
kflaw
@ kflaw - você provavelmente já descobriu isso, mas só precisa adicionar ao início da consulta: "criar nova tabela como" ou para uma visualização ", criar ou substituir a visualização nova visualização como" seguida pela instrução select.
jbalk
4

Este exemplo cria dois polígonos em ambos os lados de uma cadeia de linhas. Requer PostGIS 1.5 ou superior. Não tenho certeza de como ele irá lidar com as linhas que se cruzam.

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

));

Emite:

                        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)

O código funciona da seguinte maneira:

  1. Buffer a cadeia de linhas usando ST_Buffer. Aproveitamos o recurso PostGIS 1.5 que suporta tampas de extremidade personalizadas para não especificar limite de extremidade. Veja o exemplo abaixo.
  2. Divida o polígono em buffer em dois, usando a linha original, usando o método documentado no wiki .

Isso poderia ser melhorado para lidar com linhas de auto-cruzamento no futuro.

Uma cadeia de linhas em buffer com uma tampa de extremidade plana

fmark
fonte
3

Essa modificação cria duas cadeias de linhas paralelas. Requer PostGIS 1.5 ou superior.

geometria ou wkt necessária e distância no buffer


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
fonte
0

Como ainda não posso comentar aqui, adiciono esta resposta

O ACS dá a melhor resposta,

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)

Mas parece que a função muda
http://postgis.refractions.net/docs/ST_OffsetCurve.html

Agora o 'right'parâmetro não é necessário. Usar a distância positiva criará o lado esquerdo e a distância negativa criará o lado direito

Também não é necessário nenhum patch com meus 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
fonte