8

I have a grid that has about 30 rows with approx 15 columns each.

I want to label them as A1,A2,B1,B2 etc (Alphabet row, integer is column). Is there any way to do this programatically?

There is no fixed number of columns in a row, so we can not say that after every x columns the next item is B etc.

If necessary I guess we can compare the y on the top right of each grid and when it changes Row A becomes B but I am hoping that there is an easier way of doing this in SQL (Mapinfo) or QGIS.

Unfortunately, I don't have access to ArcGIS grid tool that does this.

I used "QGIS--Vector--Research--Vector Grid" to make the grid.

Another way of asking this is, can this QGIS tool be modified to include grid numbering like in the ArcGIS equivalent Grid Index Features (Cartography) and also ideally the surrounding map numbers.

I am also happy to use a mapbasic program to do this.

2
  • Could you use the coordinates to determine what row/column a certain cell is at? I would image that the cells are of a specific width/height which could be used to determine "how far away" from the start point a given cell is Commented Feb 14, 2016 at 19:03
  • @PeterHorsbøllMøller yes this could work and I included this in my question but I am hoping that someone already has a solution for this. It would be great to look at the code behind the arcgis tools mentioned to see what they did.
    – GeorgeC
    Commented Feb 14, 2016 at 21:11

1 Answer 1

4

You can use pyqgis with the string and collections.defaultdict libraries.

Add a field named label of string/text type, change Grid to the name of your layer below and execute:

import string
from collections import defaultdict as dd

layer = QgsProject.instance().mapLayersByName('Grid')[0]
features = [f for f in layer.getFeatures()] #List all features
features.sort(key=lambda x: x.geometry().centroid().asPoint().y(), reverse=True) #Sort by y coordinate

rows = dd(list) #Create a defaultdict list which will have y coordinate (/the row identifier) as key and all features in that row as a list

for feature in features: 
    rowid = round(feature.geometry().centroid().asPoint().y())
    rows[rowid].append(feature)
# {6901627: [<qgis._core.QgsFeature object at 0x7f7804a1a160>,..., 
# 6896627: [<qgis._core.QgsFeature object at 0x7f7804a1a550>, <qgis._core.QgsFeature object at 0x7f7804a11af0>,

for rowid, featurelist in rows.items(): #Now sort each feature list by x coordinate
    rows[rowid] = sorted(rows[rowid], key=lambda x: x.geometry().centroid().asPoint().x())

fieldindex = layer.fields().indexFromName('label')
attributemap = {}
for row, letter, (_, features) in zip(rows, string.ascii_uppercase, rows.items()): #For each row
    for e, feature in enumerate(features, 1): #For each feature in the rows list of ids
        attributemap[feature.id()] = {fieldindex:letter+str(e)} #Store feature id and row letter and number as value
#attributemap is now 0: {1: 'A1'}, 3: {1: 'A2'}, 11: {1: 'A3'}, ...
layer.dataProvider().changeAttributeValues(attributemap)

(The code became complicated because I removed some grid cells):

enter image description here

3
  • in QGIS 3.25 I am getting Windows fatal exception: access violation. Is there an easy fix to using this code in 3x. I assume your answer was for v2x as it's 6y old now.
    – GeorgeC
    Commented May 9, 2022 at 2:03
  • This crashes Qgis 3.32.1 Windows 11 :-(
    – br8k
    Commented Aug 7, 2023 at 18:34
  • It is working for me on Windows 11 QGIS 3.28. Another solution you can use is: gis.stackexchange.com/questions/344161/…
    – Bera
    Commented Aug 13, 2023 at 16:20

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.