2

I'm working on a shape file in qgis (2.8.4 Wien for Mac). In this file I have several points with about ten fields. What I'm interest in is to use two of these fields to set position of the label and the rotation of the symbol of the point: one field is the id of the point, the other one is the rotation.

I represent the point symbol as a triangle with a little line, and I rotate it according to the rotation field (I have no problem with this). The main problem is to place the label of the ID around the point in a specific position, according to the rotation, but without rotate it.

The rotation field contains, obviously, values from 0 to 359.

In the picture below, there is a sample of what I want to obtain:

result sample

I think is possible to use a offset function with sinus and cosinus, but the corresponding buttons are disabled on qgis interface.

There is a way to do this? Unfortunately this is a requirement of the work I'm doing.

2
  • Welcome! I found a similar question that might be helpful: gis.stackexchange.com/questions/93268/…
    – MaryBeth
    Dec 16, 2015 at 20:38
  • It is a similar question, but I want to maintain unrotaded label. I want to adjust around the point. Thank's
    – Lipsyor
    Dec 16, 2015 at 20:58

3 Answers 3

4

In addition to the linked answer from @MaryBeth in the comment, for QGIS 2.12.1 (lyon) there's now a data defined rule for "quadrant" or the position of the label.

In the labeling dialog, select the "Placement" tab and then check the radio bullet for "Around point".

Then there is an option to set an expression for the "Quadrant".

qgis quadrant option for data defined labelling

If you check the description, it tells you what it expects as input.

In this case, it expects an int (an integer).

Data defined override
Active: no   (ctrl|right-click toggles)
Expected input:
int
[0=Above Left|1=Above|2=Above Right|
3=Left|4=Over|5=Right|
6=Below Left|7=Below|8=Below Right]
Valid input types:
string, int, double
Current definition :
undefined

You can see where each number represents a place in the quadrant.

So you just have to setup CASE ELSE type expression here that looks at the rotation values in your rotation field.

eg,

CASE
  WHEN "rotation" = 45 THEN 2
  WHEN "rotation" = 90 THEN 6
ELSE 0
END

Your WHEN statement can use ranges as well,

WHEN "rotation" >= 0 AND "rotation" <= 50 THEN ...
3
  • It's a good idea. I'm stuck because I can set a quadrant function only for "offset from point" and not for "around point". It cause a little overlap of the label on the symbol.
    – Lipsyor
    Dec 16, 2015 at 21:38
  • @lypsyor If you set the quadrant using the "around point" option than you can adjust the "Distance" to something so that it doesn't overlap the symbol. How come you can't set the quadrant for "around point", is the quadrant option not there?
    – SaultDon
    Dec 16, 2015 at 22:14
  • Yep, I know. I prefer solution provided by @ndawson, because it sets position in continuos mode around point and, moreover, is more simple to write.
    – Lipsyor
    Dec 16, 2015 at 22:19
3

You could set the label Placement mode to "Offset from point", and then set a data defined override on the "Offset X,Y" field. This would require an expression like:

to_string("distance" * cos( "angle_radians" )) ||','|| to_string("distance" * sin( "angle_radians" ))

Where "distance" is your distance from point field and "angle_radians" the field containing the angle from the point in radians.

Note that for older QGIS versions "tostring" must be used instead of "to_string".

7
  • It doesn't work for me. Invalid expression.
    – Lipsyor
    Dec 16, 2015 at 21:35
  • Can you post your version of the expression?
    – ndawson
    Dec 16, 2015 at 21:46
  • Try the updated version
    – ndawson
    Dec 16, 2015 at 21:47
  • 2 * cos( "_rotation" * $pi / 180 ) ||','|| 2 * sin( "_rotation" * $pi / 180 )
    – Lipsyor
    Dec 16, 2015 at 21:49
  • It works! typo error: to_string had to be tostring
    – Lipsyor
    Dec 16, 2015 at 21:58
2

As SaultDon described, you can use an expression for the quadrant:

case
  when round(rotation / 360 * 8 + 1) % 8 = 0 then 1
  when round(rotation / 360 * 8 + 1) % 8 = 1 then 2
  when round(rotation / 360 * 8 + 1) % 8 = 2 then 5
  when round(rotation / 360 * 8 + 1) % 8 = 3 then 8
  when round(rotation / 360 * 8 + 1) % 8 = 4 then 7
  when round(rotation / 360 * 8 + 1) % 8 = 5 then 6
  when round(rotation / 360 * 8 + 1) % 8 = 6 then 3
  when round(rotation / 360 * 8 + 1) % 8 = 7 then 0
end

Edit: added +1 offset since you seem to wish the label to be in the next quadrant clockwise.

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.