Buat buffer persegi di sekitar titik dalam QGIS dengan Python?

8

Saya memiliki koordinat x, y di lat / panjang dan saya harus membuat sel persegi 5x5 derajat di sekitar mereka, dengan koordinat lat / panjang menjadi centroid.

Opsi pertama saya adalah membuat buffer di sekitar centroid dengan 1 segmen dan jarak 1/2 (5 °) * sqrt (2) (harus dikalikan dengan sqrt (2) bc alat menggunakan centroid ke sudut persegi sebagai jarak buffer, berlawanan dengan centroid ke edge), yang menghasilkan kotak menyamping di sekitar titik saya, lalu putar setiap fitur sebesar 45 derajat. Saya lebih suka tidak melakukan ini karena jaraknya tidak terlalu tepat dan saya tidak tahu cara memutar setiap fitur buffer secara cepat.

Opsi kedua saya, yang tampaknya jauh lebih sederhana, adalah membuat buffer di sekitar centroid dengan jarak yang saya butuhkan ((1/2) * 5 °) dan kemudian menggunakan sesuatu seperti alat ArcMap's Feature to Envelope.

Saya melihat bahwa seseorang memiliki pertanyaan yang sama di sini dan jawaban diberikan, tetapi saya tidak tahu bagaimana melakukannya secara terprogram.

srha
sumber

Jawaban:

20

Ketika Anda bertanya-tanya dalam paragraf terakhir Anda, untuk melakukannya secara terprogram dengan PyQGIS itu tidak terlalu sulit. Anda dapat mencoba kode selanjutnya. Namun, saya menggunakan shapefile dan koordinat yang diproyeksikan dalam meter (buffer memiliki 1000 m). Anda hanya perlu melakukan beberapa perubahan.

layer = iface.activeLayer()

feats = [ feat for feat in layer.getFeatures() ]

epsg = layer.crs().postgisSrid()

uri = "Polygon?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"

mem_layer = QgsVectorLayer(uri,
                           'square_buffer',
                           'memory')

prov = mem_layer.dataProvider()

for i, feat in enumerate(feats):
    new_feat = QgsFeature()
    new_feat.setAttributes([i])
    tmp_feat = feat.geometry().buffer(1000, -1).boundingBox().asWktPolygon()
    new_feat.setGeometry(QgsGeometry.fromWkt(tmp_feat))
    prov.addFeatures([new_feat])

QgsMapLayerRegistry.instance().addMapLayer(mem_layer)

Setelah menjalankan kode di atas di Python Console QGIS, saya mendapat:

masukkan deskripsi gambar di sini

Berhasil.

Catatan Pengeditan:

Kode berikutnya memperkenalkan pada tabel atribut sebuah kolom untuk koordinat x, koordinat y, dan nomor ID untuk setiap titik.

layer = iface.activeLayer()

feats = [ feat for feat in layer.getFeatures() ]

epsg = layer.crs().postgisSrid()

uri = "Polygon?crs=epsg:" + str(epsg) + "&field=id:integer&field=x:real&field=y:real&field=point_id:integer""&index=yes"

mem_layer = QgsVectorLayer(uri,
                           'square_buffer',
                           'memory')

prov = mem_layer.dataProvider()

for i, feat in enumerate(feats):
    point = feat.geometry().asPoint()
    new_feat = QgsFeature()
    new_feat.setAttributes([i, point[0], point[1], feat.id()])
    tmp_feat = feat.geometry().buffer(1000, -1).boundingBox().asWktPolygon()
    new_feat.setGeometry(QgsGeometry.fromWkt(tmp_feat))
    prov.addFeatures([new_feat])

QgsMapLayerRegistry.instance().addMapLayer(mem_layer)

Setelah menjalankan kode baru di Konsol Python QGIS, hasilnya adalah:

masukkan deskripsi gambar di sini

xunilk
sumber
Terima kasih atas jawaban Anda. Bagaimana saya akan memodifikasi ini sehingga poligon keluaran akhir menyertakan atribut poin?
srha
Atribut titik mana?
xunilk
1
Ini adalah pertanyaan lain, namun, Anda memiliki jawabannya di Catatan Editing saya .
xunilk
2
Bagi siapa pun yang mencoba ini pada QGIS 3 (2,99 pada saat menulis komentar ini), ganti QgsMapLayerRegistrydengan baris terakhir dengan QgsProject. Untuk info lebih lanjut, lihat ini
Techie_Gus
1
-1 itu adalah default untuk buffer yang sepenuhnya melingkar. Dengan menggunakan 1 mendapat penyangga empat sisi, 2 mendapat penyangga delapan sisi (4 + 4), 3 mendapat penyangga dua belas sisi (8 + 4) dan seterusnya.
xunilk
4

QGIS 3 menyediakan alternatif cepat dan kotor: - Vektor -> Alat geoproses -> Penyangga

Pilih layer titik Anda sebagai lapisan input, pastikan bahwa gaya tutup ujung diatur ke kotak dan jaraknya harus setengah dari panjang kotak yang dimaksudkan (sehingga kotak 1 km per sisi harus memiliki Jarak 500 m).

miln40
sumber
1

Untuk mengubah poin menjadi kuadrat, Anda dapat mencoba native:buffermemproses algoritme dengan END_CAP_STYLEparameter yang disetel ke 2(kotak).

Peringatan! Hasil dapat bervariasi dan tergantung pada sistem koordinat lapisan input. Dalam exapmle, jika Anda menggunakan WGS 84 dan mengatur jarak ke 5000ini akan menghasilkan garis persegi 5.000 derajat (bukan meter).

masukkan deskripsi gambar di sini

Diuji dengan pyQGIS 3.6.1:

def buffer(input, distance, output, before_processing_reproject_to_epsg_number=None):
    params = {'INPUT': input,
              'DISTANCE': distance,
              'END_CAP_STYLE': 2 , # - 0: Round - 1: Flat - 2: Square
              'DISSOLVE': False,
              'OUTPUT': output}
    feedback = qgis.core.QgsProcessingFeedback()
    alg_name = 'native:buffer'
    # print(processing.algorithmHelp(alg_name)) # tool tips
    result = processing.run(alg_name, params, feedback=feedback)
    return  result

Contoh penggunaan:

buffer_result = buffer(input=r'C:\input.shp', distance=5000, output=r'C:\output.shp')
print(buffer_result)
Kamerad Che
sumber