Créer des tampons carrés autour des points dans QGIS avec Python?

8

J'ai des coordonnées x, y en lat / long et je dois créer des cellules carrées de 5x5 degrés autour d'eux, les coordonnées lat / long étant les centroïdes.

Ma première option est de créer un tampon autour des centroïdes avec 1 segment et une distance de 1/2 (5 °) * sqrt (2) (doit multiplier par sqrt (2) bc l'outil utilise le centroïde au coin du carré comme la distance tampon, par opposition au centre de gravité au bord), ce qui se traduit par des carrés latéraux autour de mes points, puis fait pivoter chaque entité de 45 degrés. Je préfère ne pas le faire car la distance n'est pas aussi précise et je ne sais pas comment faire tourner rapidement chaque fonction de tampon individuelle.

Ma deuxième option, qui semble beaucoup plus simple, consiste à créer un tampon autour des centroïdes avec la distance dont j'ai besoin ((1/2) * 5 °), puis à utiliser quelque chose comme l'outil Feature to Envelope d'ArcMap.

Je vois que quelqu'un a la même question ici et une réponse a été fournie, mais je ne sais pas comment le faire par programme.

srha
la source

Réponses:

20

Comme vous vous le demandez dans votre dernier paragraphe, pour faire cela par programmation avec PyQGIS, ce n'est pas très difficile. Vous pouvez essayer le code suivant. Cependant, j'ai utilisé un fichier de formes et des coordonnées projetées en mètres (le tampon a 1000 m). Vous auriez seulement besoin de faire quelques changements.

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)

Après avoir exécuté le code ci-dessus sur la console Python de QGIS, j'ai obtenu:

entrez la description de l'image ici

Ça marche.

Note d'édition:

Le code suivant introduit dans la table des attributs une colonne pour la coordonnée x, la coordonnée y et le numéro ID pour chaque point.

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)

Après avoir exécuté le nouveau code sur la console Python de QGIS, le résultat était:

entrez la description de l'image ici

xunilk
la source
Merci pour votre réponse. Comment pourrais-je modifier cela afin que les polygones de sortie finaux incluent les attributs des points?
srha
Quels attributs ponctuels?
xunilk
1
Ceci est une autre question, cependant, vous avez la réponse dans ma note d'édition .
xunilk
2
Pour quiconque essaie ceci sur QGIS 3 (2,99 au moment de la rédaction de ce commentaire), remplacez QgsMapLayerRegistryà la dernière ligne par QgsProject. Pour plus d'informations, voir ceci
Techie_Gus
1
-1 c'est la valeur par défaut pour un tampon complètement circulaire. En utilisant 1 obtient un tampon à quatre côtés, 2 obtient un tampon à huit côtés (4 + 4), 3 obtient un tampon à douze côtés (8 + 4) et ainsi de suite.
xunilk
4

QGIS 3 fournit une alternative rapide et sale: - Vector -> Outils de géotraitement -> Buffer

Sélectionnez votre calque de point comme calque d'entrée, assurez-vous que le style de capuchon d'extrémité est défini sur carré et que la distance doit être la moitié de la longueur du carré prévue (donc un carré de 1 km par côté doit avoir une distance de 500 m).

miln40
la source
1

Pour transformer des points en carrés, vous pouvez essayer de native:buffertraiter l'algorithme avec le END_CAP_STYLEparamètre défini sur 2(carré).

Attention! Les résultats peuvent varier et dépendent du système de coordonnées de la couche d'entrée. Dans exapmle, si vous utilisez WGS 84 et que vous définissez une distance, 5000cela entraînera une ligne carrée de 5000 degrés (et non mètres).

entrez la description de l'image ici

Testé avec 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

Exemple d'utilisation:

buffer_result = buffer(input=r'C:\input.shp', distance=5000, output=r'C:\output.shp')
print(buffer_result)
Camarade Che
la source