Sorting grid cells in fishnet grid by location and number using QGIS?

I am using QGIS 3.2.0 on a Mac (and also have QGIS 2), and I have a fishnet grid (probably created in Arc) that comprises of nearly 2 million grid cells. As a result, every change I make to the attribute table takes hours, so I can't experiment as I would usually.

I need to label each grid cell such that the north-westernmost cell is "1", and the numbers proceed by rows, until the last number goes into the south-easternmost cell. Using the row-number doesn't work, as that's not how the table is sorted. I've done this before, but cannot remember how.

• You want to give each fishnet an ID, starting from top left, ending at bottom right? – BERA Sep 22 '18 at 18:31
• Yes, exactly that. – StripyDonkey Sep 22 '18 at 18:37

You can use pyqgis.

Script will:

1. List all centroid x,y with id
2. Sort list by x and y
3. The ids are now in correct order - create a dictionary of id and sequential number using enumerate
4. Use dictionary with id as key and update field

Add your layer to the map, add a integer field to hold the numbers and execute. I have not tried it on millions of fishnet but about 20k. You might need to adjust the rounding of the coordinates, my coordinates are in meters and I round to zero decimals. For example change the zero in round(f.geometry().centroid().asPoint().x(),0)

layer = iface.activeLayer()
idfield = 'fishnetID' #Change to match the name of your field

coords = [[round(f.geometry().centroid().asPoint().x(),0),round(f.geometry().centroid().asPoint().y(),0),f.id()] for f in layer.getFeatures()]
coords.sort(key=lambda k: (k,-k), reverse=True)
order = [i for i in coords]
d = {k:v for (v,k) in list(enumerate(order))}

with edit(layer):
for feature in layer.getFeatures():
_=feature.setAttribute(feature.fieldNameIndex(idfield), d[feature.id()]+1)
_=layer.updateFeature(feature) 