5

In the QGIS map composer, the options to draw coordinates along the grid are great. But is it possible to draw the coordinates to the grid crosses in the map? I can only see options to draw them along the frame. Is there any way to accomplish this via the GUI or an extra plugin? scripting? I could not find any answers or topics related to this. Update: anyone has any clue on how hard would this be to implement to QGIS? a plugin perhaps?

1
  • You can generate a grid using "Create grid" algorithm in the processing toolbox and generate points, assign the grid labels infos in the attributes and add it as layer. My main issue here is if you start to put a label on each cross instead of the borders of the frame, you will bloat your map as you will need to set for each cross the x and y labels coordinates.
    – ThomasG77
    Commented Jun 18, 2020 at 21:53

3 Answers 3

3

Unfortunately this feature is also missing in QGIS 3.26.3.

As long as it's not added as QGIS core feature, we could use PostGIS to build a more dynamic point marker grid. Therefore we need to create the new SQL function makegrid (Creating regular point grid inside polygon in PostGIS):

CREATE OR REPLACE FUNCTION public.makegrid(geometry,integer)
RETURNS geometry
LANGUAGE sql
AS $BODY$
SELECT ST_Collect(ST_SetSRID(ST_POINT(x, y), ST_SRID($1))) FROM
generate_series((floor(ST_XMIN($1)/$2)*$2)::int, ceiling(ST_XMAX($1))::int, $2) AS x,
generate_series((floor(ST_YMIN($1)/$2)*$2)::int, ceiling(ST_YMAX($1))::int, $2) AS y
WHERE st_intersects($1, ST_SetSRID(ST_POINT(x,y), ST_SRID($1)))
$BODY$;

Then we create our point grid as virtual layer using a PostGIS datasource. In my example I'm creating a 1000x1000m grid for a rectangular boundary in EPSG:31255 projection.

SELECT (ST_DUMP(makegrid(ST_MAKEENVELOPE(-44318,264977,154262,390916,31255),1000))).geom

We need to hardcode the grid boundaries, because QGIS doesn't allow variables in PostGIS queries by now. In the last step we style your grid markers and set the labels accordingly using $x and $y variables. enter image description here

1

There is another solution for this issue, creating dynamic point marker grids with the help of a Python expression function and a virtual QGIS layer (also see QGIS Python expression function - returning multiple values for use in a custom SQL query). To change the default grid spacing 1000 to another value, we have to create a custom QGIS project variable named grid_space or adapt the default value in the function getLayoutMapGridParam.

from qgis.core import qgsfunction,QgsProject,QgsExpressionContextUtils

@qgsfunction(args='auto', group='Custom')
def getLayoutMapGridParam(layoutname, feature, parent):
    layout = QgsProject.instance().layoutManager().layoutByName(layoutname)
    space = QgsExpressionContextUtils.projectScope(QgsProject.instance()).variable('grid_space')
    if not space:
        space = 1000
        QgsExpressionContextUtils.setProjectVariable(QgsProject.instance(), 'grid_space','1000')
    else:
        space = int(space)

    if layout:
        map = layout.referenceMap()
        if map:
            extent = map.extent()
            xmin = int(extent.xMinimum()/space)*space
            ymin = int(extent.yMinimum()/space)*space
            xcount = round(extent.width()/space,0)+1
            ycount = round(extent.height()/space,0)+1
            return '{"xmin":%s,"ymin":%s,"xcount":%s,"ycount":%s,"space":%s}' % (xmin,ymin,xcount,ycount,space)
    if not extent:
        return None

The following SQL for the virtual QGIS layer uses the reference map boundary of the layout myLayout and the hard coded CRS EPSG:31255. We need to comment the geometry column /*:point:31255*/ so that QGIS assigns the correct CRS.

WITH RECURSIVE   
    r(x) AS (
        SELECT getLayoutMapGridParam('myLayout') -> 'xmin'
        UNION ALL
        SELECT x+getLayoutMapGridParam('myLayout')->'space' FROM r
        LIMIT getLayoutMapGridParam('myLayout') -> 'xcount'
    ),
    c(y) AS (
        SELECT getLayoutMapGridParam('myLayout') -> 'ymin'
        UNION ALL
        SELECT y+getLayoutMapGridParam('myLayout')->'space' FROM c
        LIMIT getLayoutMapGridParam('myLayout') -> 'ycount'
    ) 
SELECT row_number() over() as id,geomfromtext('POINT('||r.x||' '||c.y||')',31255) as geom /*:point:31255*/ FROM r,c

Tip: It's always wise to limit the layer to a specific maximum scale.

Every time we change the boundary of the reference map or the value of the QGIS project variable grid_space, the point marker grid is automatically renewed.

If we don't want coordinates beneath every marker symbol, we can use rule based styling for the labels. enter image description here

enter image description here

-1

Yes you can certainly draw the coordinates on grids. Coordinates will appear on the grids ony when you set the grid units correctly with your map scale. If the map units are much larger than your map scale, coordinates will not appear on grids. I also had this problem and finally the problem was solved when I set the scale and map units correctly.

1
  • This will add the coordinates on the frame (outside) of the grid. The question is about coordinates inside the grid, at each grid crossing. Also it would be helpful if you provided the exact values you used to make it work.
    – til_b
    Commented Oct 19, 2022 at 8:38

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.