You need a custom function which I have translated from my Java translation of the OS Visual Basic to python. Insert the following into a new Function in the Expression Function editor (see this class for more details of how to do this).
from qgis.core import *
from qgis.gui import *
gridLetters = [["SV", "SQ", "SL", "SF", "SA", "NV", "NQ", "NL", "NF", "NA", "HV", "HQ", "HL"],
["SW", "SR", "SM", "SG", "SB", "NW", "NR", "NM", "NG", "NB", "HW", "HR", "HM"],
["SX", "SS", "SN", "SH", "SC", "NX", "NS", "NN", "NH", "NC", "HX", "HS", "HN"],
["SY", "ST", "SO", "SJ", "SD", "NY", "NT", "NO", "NJ", "ND", "HY", "HT", "HO"],
["SZ", "SU", "SP", "SK", "SE", "NZ", "NU", "NP", "NK", "NE", "HZ", "HU", "HP"],
["TV", "TQ", "TL", "TF", "TA", "OV", "OQ", "OL", "OF", "OA", "JV", "JQ", "JL"],
["TW", "TR", "TM", "TG", "TB", "OW", "OR", "OM", "OG", "OB", "JW", "JR", "JM"]]
@qgsfunction(args='auto' , group='Custom', usesgeometry=True)
def gridSquare(size, geometry, feature, parent):
centroid = geometry.centroid()
easting = centroid.asPoint().x()
northing = centroid.asPoint().y()
xText = "%06d" % easting
yText = "%07d" % northing
x = int(xText[:1])
y = int(yText[:2])
gl = gridLetters[x][y]
result = gl
if size == 100:
return result
elif size == 10:
return gl + xText[1:2] + yText[2:3]
elif size == 1:
return gl + xText[1:3] + yText[2:4]
elif size == .1:
return gl + xText[1:4] + yText[2:5]
elif size == .01:
return gl + xText[1:5] + yText[2:6]
elif size == .001:
return gl + xText[1:6] + yText[2:7]
You can then use expressions like:
gridSquare(.1, $geometry)
to get output like TF392033
or gridSquare(1, $geometry)
to get TF3903
. In a layout you should be able to do something like:
[%gridSquare(.1, map_get(item_variables('Map 1'), 'map_extent_center'))%]
but I can only get NULL as a response to any of the item_variables
function calls - may be my map isn't called Map 1
?
Update - if I rename my map to map
then this works:
Map Centre is at [%gridSquare(.1, map_get(item_variables('map'), 'map_extent_center'))%]
Update
I've packaged this into a QGIS plugin (experimental) which should show up in the repository soonish. In the meantime you can get it from https://github.com/ianturton/osgridref