Crescendo uma geometria PostGIS em uma porcentagem

10

Estou procurando uma maneira de adicionar um buffer em torno de uma geometria PostGIS, mas o tamanho do buffer deve depender do tamanho da geometria. Ou seja, eu quero que cada geometria seja ampliada em, digamos, 5%.

A ideia é procurar geometrias cruzadas, mas pode haver um erro de até 5% associado a cada uma delas que eu quero levar em consideração.

Alguém sabe a melhor maneira de fazer isso?

O banco de dados já tem um milhão de linhas, então eu prefiro que seja bastante rápido.

James Baker
fonte
2
5% do que? Presumindo que você esteja usando polígonos, é 5% da maior largura, largura mais estreita, caixa delimitadora, distância de um vértice do centróide ...? Se você está falando de pontos ou linhas, faz ainda menos sentido!
MerseyViking
Eu acho que a distância do vértice-centróide - ou possivelmente um aumento de 5% na área também seria bom. Aumentar a caixa delimitadora é bom se a geometria for dimensionada para preencher essa caixa delimitadora. Todas as geometrias são polígonos fechados (a grande maioria sendo quadrilateral).
James Baker

Respostas:

8

Os comentários sugerem que os 5% não precisam ser atingidos com alta precisão. (Se o fizer, vai levar um longo tempo para tamponar um milhão de polígonos!) Podemos, portanto, invocar o princípio Pizza : linearmente rescaling um recurso 2D por um fator a rescales sua área por um ^ 2.

Aqui está como o raciocínio é:

  • Quando a forma não é muito complicada - especialmente se for convexa -, o buffer produz um resultado comparável ao redimensionar a forma em torno de um ponto central. (É importante compreender, porém, que o buffer é não sempre equivalente a um reescalonamento para outros usos diferentes discos formas. Para algumas formas côncavas, um "tampão" calculado através rescaling realmente não podem incluir partes da própria forma original! Portanto, em última instância que irá calcular um tampão genuíno da forma, mas apenas estão usando essa equivalência aproximada como uma heurística para estimar o quanto a buffer por.)

  • Se a área tamponada for 5% maior, a quantidade de redimensionamento deverá, portanto, ser sqrt (1 + 5/100), que é próximo a 1.025: ou seja, devemos expandir a forma em 2,5% em todas as direções .

  • Da mesma forma, se pensarmos na forma como tendo um "diâmetro" (igual a uma distância típica), seu raio deve aumentar em 2,5%. Isso é igual a 2,5% / 2 = 1,25% do diâmetro.

  • Podemos estimar um diâmetro típico da caixa delimitadora da forma. Use, digamos, uma média aritmética ou geométrica dos comprimentos laterais da caixa.

Isso sugere o seguinte fluxo de trabalho:

  1. Obtenha a caixa delimitadora da forma.

  2. Seja e a média dos comprimentos laterais da caixa.

  3. Buffer a forma em 1,25% de e ; ou seja, por (5/100) / 4 * e .

Como as etapas 1 e 2 exigem muito pouco cálculo, isso se oferece como uma das soluções mais rápidas possíveis. Como verificação da precisão, você pode (é claro) computar as áreas das formas armazenadas em buffer e compará-las às áreas originais para ver até que ponto elas atingem o aumento de 5% desejado. Às vezes, as áreas protegidas serão ainda mais do que 5% maiores, mas deve ser raro que sejam menores e é impossível que sejam consideravelmente menores.

Exemplos

Como verificação e ilustração, vamos considerar algumas formas simples.

  1. Um disco de raio r tem uma caixa delimitadora com lados de comprimento 2 r . Nossa fórmula calcula e = (5/100) / 4 * 2 * r = r / 40. A forma em buffer obviamente é um disco concêntrico de raio r + r / 40 = 1,025 r . A área antiga era pi * r ^ 2 enquanto a nova área é pi * (1.025 r ) ^ 2 = pi * 1.0506 * r ^ 2, que é 5,06% maior.

  2. Um rectângulo com os lados paralelos aos eixos de coordenadas de comprimentos de r e sde e = ( r + s ) / 2. A área adicional do buffer do retângulo vem de quatro retângulos de largura (5/100) / 4 e = e / 80 = ( r + s ) / 160 nas bordas dos lados, mais quatro quartos de círculo de raio e / 80 nos cantos. Negligenciando os quartos de círculo, que serão pequenos em comparação com as outras áreas, a nova área total é igual a

    2 ( r + s ) * ( r + s ) / 160 = ( r ^ 2 + s ^ 2 + 2 r * s ) / 80.

    Quando r e s não são muito diferentes, podemos descobrir que r ^ 2 + s ^ 2 é aproximadamente 2 r * s . Essa aproximação simplifica a nova área total para 4 r * s / 80 = 5% da área original de r * s , conforme pretendido.

whuber
fonte
4

Você deseja usar uma combinação de ST_Scale ( http://postgis.net/docs/ST_Scale.html ) e ST_Translate ( http://postgis.net/docs/ST_Translate.html ), eu acho. Temos um exemplo disso no PostGIS in Action e semelhante no capítulo 8. Se você não possui o livro, pode fazer o download do código para esse capítulo aqui:

http://www.postgis.us/chapter_08

Trecho do livro Veja o exemplo 8.26:

    -- Listing 8.26 Combining Scale and Translation to maintain centroid
    SELECT xfactor, yfactor, 
       ST_Translate(ST_Scale(hex.the_geom, xfactor, yfactor), 
       ST_X(ST_Centroid(the_geom))*(1 - xfactor), 
       ST_Y(ST_Centroid(the_geom))*(1 - yfactor) ) As scaled_geometry
    FROM 
 ( SELECT ST_GeomFromText('POLYGON((0 0,64 64,64 128,0 192,-64 128,-64 64,0 0))') As the_geom)  As hex
    CROSS JOIN (SELECT x*0.5 As xfactor 
        FROM generate_series(1,4) As x) As xf
    CROSS JOIN (SELECT y*0.5 As yfactor
        FROM generate_series(1,4) As y) As yf;
LR1234567
fonte
Trabalho. Agora parece haver também ST_Transscalemas de alguma forma eu não posso figura como fazer esse trabalho ...
N1000
0

É muito tarde para a festa, mas recentemente desenvolvi uma função PostGIS personalizada que faz isso, além de reduzi-la, se necessário:

ST_Dilate

wfgeo
fonte