Thursday 27 December 2018

Avoiding labeling features if overlapped by another layer in QGIS?


With QGIS 2.12.2, how can I set up layer labeling to avoid placing labels where features from another layer already exist?


For example, if I have a stream/river polyline layer that contains lake "centerlines", and I place a "lake" polygon layer above it in the drawing order, I don't want the river layer to place a label inside the lake. Instead, I would rather have the river labeled outside of the lake (as needed). That way, I can place labels from the lakes layer and I don't run into label collisions.


Here is an example, where (I have intentionally put the lines on top for visual purposes) what I am hoping to achieve is no river center-line labels shown inside the lake polygon: Lines are labeling inside polygon



Answer



Automated labelling is a really hard problem, but feature geometry is not so bad.


Even if you can get placement to work adequately most of the time, there are likely to be exceptions. Some of these you will notice and may be able to address. Others you won't notice when making a large map or tileset because you can't pour over every inch of your map at a variety of scales. Almost always you will have the urge to move some automatically-placed labels manually, from a cartographic perspective.



As I suggested in my comment, I'd make the problem easier for the labelling engine. In this case, I would do this by defining my rivers as a table view*, with river geometries clipped to respect lake boundaries. That way, there are no river features inside lakes to be labelled, and no label collisions.


* I assume the use of a RDBMS here, like PostgreSQL/PostGIS, for convenience and the ability to only update your authoritative source of data and have the view work itself out without your intervention. But you can also do some work upfront with static files to clip and delete features, but I don't recommend this if you ever plan to revisit a map.


Example:


Starting with two shapefiles (could be database tables) of rivers and lakes, with rivers intersecting lakes and causing labelling issues that are hard to resolve completely and confidently:


enter image description here


Bring these into Postgres if you need to with shp2pgsql:


shp2pgsql -s 4326 /data/lake public.lakes | psql -d mydb


shp2pgsql -s 4326 /data/river public.rivers | psql -d mydb


Then define a view with ST_Difference:


CREATE OR REPLACE VIEW rivers_clipped AS

SELECT r.id, ST_Difference(r.geom, l.geom) AS geom, r.name
FROM public.rivers AS r, public.lakes AS l;

Add the view to your layout:


enter image description here


Although the problem in my example is deliberately fabricated, the styles in the two river layers (original and view) are the same, and they are placed on top of the lake in the drawing order. When you update the lakes or rivers geometries, you won't need to do much more than refresh the rendering.


enter image description here


No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...