spatialthoughts / qgis-tutorials

Source files for sphinx-based website
http://www.qgistutorials.com
Apache License 2.0
62 stars 33 forks source link

Find Neighbor Polygons in a Layer — QGIS Tutorials and Tips #174

Closed utterances-bot closed 3 weeks ago

utterances-bot commented 2 months ago

Find Neighbor Polygons in a Layer — QGIS Tutorials and Tips

https://www.qgistutorials.com/en/docs/find_neighbor_polygons.html

asouzaindicia commented 2 months ago

I received an error when try to use the script, ChatGpt did some corrections and worked well. Here is the revised script if somebody need to use or if you want to replace.

Thanks a lot for this tutorial and script

################################################################################

Copyright 2014 Ujaval Gandhi

#

This program is free software; you can redistribute it and/or

modify it under the terms of the GNU General Public License

as published by the Free Software Foundation; either version 2

of the License, or (at your option) any later version.

#

This program is distributed in the hope that it will be useful,

but WITHOUT ANY WARRANTY; without even the implied warranty of

MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

GNU General Public License for more details.

#

You should have received a copy of the GNU General Public License

along with this program; if not, write to the Free Software

Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

# ################################################################################ from qgis.utils import iface from PyQt5.QtCore import QVariant # Updated for PyQt5 from qgis.core import QgsField, QgsFeature, QgsSpatialIndex

Replace the values below with values from your layer.

_NAME_FIELD = 'NAME' _SUM_FIELD = 'POP_EST'

Names of the new fields to be added to the layer

_NEW_NEIGHBORS_FIELD = 'NEIGHBORS' _NEW_SUM_FIELD = 'SUM'

layer = iface.activeLayer()

Create 2 new fields in the layer that will hold the list of neighbors and sum

of the chosen field.

layer.startEditing() layer.dataProvider().addAttributes( [QgsField(_NEW_NEIGHBORS_FIELD, QVariant.String), QgsField(_NEW_SUM_FIELD, QVariant.Int)]) layer.updateFields()

Create a dictionary of all features

feature_dict = {f.id(): f for f in layer.getFeatures()}

Build a spatial index

index = QgsSpatialIndex() for f in feature_dict.values(): index.insertFeature(f)

Loop through all features and find features that touch each feature

for f in feature_dict.values(): print(f'Working on {f[_NAME_FIELD]}') geom = f.geometry() intersecting_ids = index.intersects(geom.boundingBox())

neighbors = []
neighbors_sum = 0
for intersecting_id in intersecting_ids:
    intersecting_f = feature_dict[intersecting_id]

    if (f != intersecting_f and not intersecting_f.geometry().disjoint(geom)):
        neighbors.append(intersecting_f[_NAME_FIELD])
        neighbors_sum += intersecting_f[_SUM_FIELD]

f.setAttribute(_NEW_NEIGHBORS_FIELD, ','.join(neighbors))
f.setAttribute(_NEW_SUM_FIELD, neighbors_sum)
layer.updateFeature(f)

layer.commitChanges() print('Processing complete.')

spatialthoughts commented 1 month ago

Thanks for sharing. The code is very similar to what we teach in our PyQGIS class on how to compute neighbors using Actions. You can check it out https://courses.spatialthoughts.com/pyqgis-masterclass.html#selecting-neighbors