0

The following script (written by Mr. Ujaval Gandhi) is used to list neighboring polygons and add them to the attribute table.

from qgis.utils import iface
from PyQt5.QtCore import QVariant

_NAME_FIELD = 'NAME'

_SUM_FIELD = 'POP_EST'


_NEW_NEIGHBORS_FIELD = 'NEIGHBORS'
_NEW_SUM_FIELD = 'SUM'

layer = iface.activeLayer()


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

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


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


for f in feature_dict.values():
    print 'Working on %s' % f[_NAME_FIELD]
    geom = f.geometry()

    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[_NEW_NEIGHBORS_FIELD] = ','.join(neighbors)
    f[_NEW_SUM_FIELD] = neighbors_sum

    layer.updateFeature(f)

layer.commitChanges()
print 'Processing complete.'

With some polygons the script works very well, but when the layer contains several tens of thousands of polygons, the script starts and QGIS crashes immediately.

Any idea to solve this problem?

1
  • does QGis say why it is crashing? out of memory?
    – Ian Turton
    Jan 23, 2022 at 11:16

2 Answers 2

4

The following Field Calculator expression works with the World Map vector layer that ships with QGIS. It takes a few seconds to complete, I have no idea how well it would perform on a layer with tens of thousands of polygons, however.

aggregate(layer:= @layer,       -- use the current layer
          aggregate:= 'concatenate',
          expression:= "NAME",  -- the attribute that you wish to list
          filter:= intersects($geometry, geometry(@parent))
                  and "NAME" <> attribute(@parent, 'NAME'),  -- <> is to skip the intersection of the current feature with itself. use single quotes for the field name inside the attribute function, but double quotes outside
          concatenator:=',')

enter image description here

0

I solved my problem by modifying the script. specifically, I replaced the line

f[_NEW_NEIGHBORS_FIELD] = ','.join(neighbors)

with

f[_NEW_NEIGHBORS_FIELD] = ','.join(map(str(neighbors))

I got a result for an initial layer of 325042 lines!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.