Menumbuhkan geometri PostGIS dengan persentase

10

Saya mencari cara untuk menambahkan buffer di sekitar geometri PostGIS, tetapi ukuran buffer harus tergantung pada ukuran geometri. Yaitu, saya ingin setiap geometri diperbesar dengan, katakanlah, 5%.

Idenya adalah saya sedang mencari geometri berpotongan, tetapi mungkin ada kesalahan hingga 5% terkait dengan masing-masing yang ingin saya perhitungkan.

Adakah yang tahu cara terbaik untuk melakukan ini?

Basis data memiliki hampir satu juta baris, jadi saya lebih suka itu cukup cepat.

James Baker
sumber
2
5% dari apa? Anggap Anda menggunakan poligon, apakah 5% dari lebar terbesar, lebar tersempit, kotak pembatas, jarak sebuah simpul dari pusat massa ...? Jika Anda berbicara tentang poin atau garis, maka itu bahkan lebih tidak masuk akal!
MerseyViking
Saya kira jarak vertex-centroid - atau mungkin peningkatan 5% di area juga akan baik-baik saja. Meningkatkan kotak pembatas baik-baik saja jika geometri diskalakan untuk kemudian mengisi kotak pembatas itu. Semua geometri adalah poligon tertutup (sebagian besar adalah segiempat).
James Baker

Jawaban:

8

Komentar menyarankan 5% tidak perlu dicapai dengan akurasi tinggi. (Jika tidak, itu akan mengambil lama waktu untuk buffer juta poligon!) Kita bisa karena itu memohon Pizza Prinsip : linear rescaling fitur 2D dengan faktor yang rescales wilayahnya oleh seorang ^ 2.

Beginilah alasannya:

  • Ketika bentuknya tidak terlalu berbelit-belit - terutama jika itu cembung - maka buffering menghasilkan hasil yang sebanding dengan menskors bentuk di sekitar titik pusat. (Meskipun demikian, penting untuk dipahami bahwa buffering tidak pernah setara dengan penskalaan untuk bentuk apa pun selain disk. Untuk beberapa bentuk cekung, "buffer" yang dihitung melalui penskalaan mungkin sebenarnya tidak termasuk bagian dari bentuk asli itu sendiri! kami akan menghitung buffer asli dari bentuk, tetapi hanya menggunakan perkiraan ekivalensi ini sebagai heuristik untuk memperkirakan berapa banyak buffer.)

  • Jika area yang disangga menjadi 5% lebih besar, maka jumlah pemasangan kembali oleh karena itu harus sqrt (1 + 5/100), yang dekat dengan 1,025: yaitu, kita harus ingin memperluas bentuk sebesar 2,5% ke segala arah .

  • Sama halnya, jika kita menganggap bentuk memiliki "diameter" (sama dengan jarak tipikal), jari - jarinya akan meningkat 2,5%. Itu sama dengan 2,5% / 2 = 1,25% dari diameter.

  • Kita dapat memperkirakan diameter tipikal dari kotak pembatas bentuk. Gunakan, katakanlah, rata-rata aritmatika atau geometris dari panjang sisi kotak.

Ini menyarankan alur kerja berikut:

  1. Dapatkan kotak pembatas bentuk.

  2. Biarkan e menjadi rata-rata dari panjang sisi kotak.

  3. Buffer bentuk sebesar 1,25% dari e ; yaitu, pada (5/100) / 4 * e .

Karena langkah 1 dan 2 membutuhkan perhitungan yang sangat sedikit, ini menawarkan dirinya sebagai salah satu solusi yang paling cepat. Sebagai pemeriksaan keakuratan, Anda dapat (tentu saja) menghitung area dari bentuk buffered dan membandingkannya dengan area asli untuk melihat seberapa dekat mereka dengan peningkatan 5% yang diinginkan. Kadang-kadang daerah yang disangga bahkan akan lebih dari 5% lebih besar, tetapi harus jarang bahwa mereka kurang, dan tidak mungkin bagi mereka untuk menjadi jauh lebih sedikit.

Contohnya

Sebagai tanda centang dan ilustrasi, mari kita pertimbangkan beberapa bentuk sederhana.

  1. Disk jari-jari r memiliki kotak pembatas dengan sisi panjang 2 r . Rumus kami menghitung e = (5/100) / 4 * 2 * r = r / 40. Bentuk buffered jelas adalah disk konsentris dengan jari-jari r + r / 40 = 1,025 r . Area lama adalah pi * r ^ 2 sedangkan area baru adalah pi * (1,025 r ) ^ 2 = pi * 1,0506 * r ^ 2, yang lebih besar 5,06%.

  2. Sebuah persegi panjang dengan sisi yang sejajar dengan koordinat sumbu dengan panjang r dan s menghasilkan e = ( r + s ) / 2. Area tambahan dari buffering persegi panjang berasal dari empat persegi panjang lebar (5/100) / 4 e = e / 80 = ( r + s ) / 160 yang membatasi sisi ditambah empat seperempat lingkaran jari-jari e / 80 di sudut-sudut. Mengabaikan kuartal-lingkaran, yang akan lebih kecil dibandingkan dengan daerah lain, total area baru sama

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

    Ketika r dan s tidak terlalu berbeda, kita dapat memperkirakan r ^ 2 + s ^ 2 kira-kira 2 r * s . Perkiraan ini menyederhanakan total area baru menjadi 4 r * s / 80 = 5% dari area asli r * s , sebagaimana dimaksud.

whuber
sumber
4

Anda ingin menggunakan kombinasi ST_Scale ( http://postgis.net/docs/ST_Scale.html ) dan ST_Translate ( http://postgis.net/docs/ST_Translate.html ) saya pikir. Kami memiliki contohnya di PostGIS in Action dan serupa di Bab 8. Jika Anda tidak memiliki buku, Anda dapat mengunduh kode untuk bab tersebut di sini:

http://www.postgis.us/chapter_08

Cuplikan dari buku Lihat contoh 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
sumber
Bekerja Sekarang tampaknya ada juga ST_Transscaletetapi entah bagaimana saya tidak tahu bagaimana cara membuatnya bekerja
n1000
0

Ini sangat terlambat untuk pesta, tetapi saya baru-baru ini mengembangkan fungsi PostGIS khusus yang melakukan ini, serta mengecilkannya jika perlu:

ST_Dilate

wfgeo
sumber