Modify

Opened 22 months ago

Last modified 14 months ago

#22695 new enhancement

MAPCSS, Note on: icon-rotation: way; text-rotation: way; coordinate transformation, documentation

Reported by: mikeho Owned by: team
Priority: normal Milestone:
Component: Core Version:
Keywords: mapcss, text and icon rotation Cc: gaben

Description

Hallo,

I have some comments on the MAPCSS implementation based on my experience of displaying railway signals:

0- Preliminary remark:

Direction is given in degrees in the world coordinate system: 0° - north, 90° - east, 180° - south, 270° - west.
In the usual coordinate system, the x-axis is oriented from west to east, the y-axis from south to north (example JOSM: text-offset-y) or from north to south (example screen, JOSM: icon-offset-y).

1- icon-rotation: way

node[...] {... icon-rotation: way; ...} 

The icon is rotated along the y-axis. This results in a 90° counter-clockwise rotation of the icon. I haven't found a way to correct this (e.g. icon-rotation: way + 90deg; or icon-rotation: get_angle_of(way) + 90deg; (function 'get_angle_of' does not exist).

My solution: Currently, corresponding images must be stored for: 0° for normal, +90° rotated for forward, +270° rotated for backward orientation.

In the documentation corresponding hints are missing, see https://josm.openstreetmap.de/wiki/Help/Styles/MapCSSImplementation

In the further development of the MAPCSS implementation in JOSM, the mathematical change of the rotation (... way + 90deg ... should be possible) should be taken into account. Addition: The coordinate system should rotate accordingly (not ... icon-rotation: way; ... (y-axis to the right of way), but ... icon-rotation: (way + 90deg); .... here: x-axis right of way)

2- Coordinate system: icon-rotation: way;

node[...] {... icon-rotation: way; ...} 

The coordinate system rotates with: that's good !

3- Coordinate system: text-rotation: way;

node[...] {... text-rotation: way; ...} 

Coordinate system does not rotate with. The result is that text can be moved in the west-east direction, but not relative to the way. With the consequence that text (e.g. value of a button) cannot be placed exactly above the icon.

I suggest (urgently) to create an additional possibility for positioning the text in the rotated coordinate system, e.g. text-offset-x, text-offset-y or rotated-text-offset-x, rotated-text-offset-y (analogous to icon-offset-x, text-offset-y).

4- Documentation

Appropriate documentation is welcome, see: https://josm.openstreetmap.de/wiki/Help/Styles/MapCSSImplementation. It helps Newcommer to understand and apply.

best begrads
mikeho

Attachments (11)

JOSM_demo.zip (1.6 KB ) - added by mikeho 22 months ago.
0001-Fix-mapcss-rotation-offset-for-rotation-way.patch (2.4 KB ) - added by Woazboat 22 months ago.
0002-Add-parent_way_angle-mapcss-function.patch (3.1 KB ) - added by Woazboat 22 months ago.
icon-text-rotation.pdf (36.4 KB ) - added by mikeho 22 months ago.
Screenshot from 2023-02-15 21-13-39.png (80.5 KB ) - added by marcello@… 22 months ago.
Screenshot Icon and Text Offset and Rotated
direction_of_osm_way.zip (1.5 KB ) - added by mikeho 21 months ago.
maxspeed_as_text.mapcss (1.3 KB ) - added by mikeho 21 months ago.
switch.zip (17.4 KB ) - added by mikeho 21 months ago.
railway_signal_ger.zip (544.3 KB ) - added by mikeho 21 months ago.
text-rotation.1.patch (1.5 KB ) - added by marcello@… 21 months ago.
Rotate text around node
Screenshot_20230220_133732.png (62.8 KB ) - added by marcello@… 21 months ago.
Screenshot of railway speed limit sign with rotated text

Download all attachments as: .zip

Change History (32)

by mikeho, 22 months ago

Attachment: JOSM_demo.zip added

comment:1 by Woazboat, 22 months ago

Okay so there's multiple TODOs here:
1) *-rotation: way; needs to be documented
2) 90 degree offset of *-rotation: way; compared to *-rotation: <fixed angle>

The 90 degree offset occurs because https://josm.openstreetmap.de/browser/josm/trunk/src/org/openstreetmap/josm/tools/RotationAngle.java#L37 uses Geometry.getSegmentAngle, which calculates the angle using Math.atan2 and therefore the rotation starting from the x-axis (east) in counter clockwise direction. The icon rotation is relative to the icon and therefore 'starts' at the y-axis (north) going in the clockwise direction.
The returned angle is correctly inverted to fix the rotation angle, but the 90° offset is not corrected. This can be fixed by adding an offset of - Math.PI/2 to the angle (+Math.PI/2 if done after inversion).

Last edited 22 months ago by Woazboat (previous) (diff)

comment:2 by Woazboat, 22 months ago

I added two patches that (1) fix the 90° offset and (2) add a parent_way_angle mapcss function (as discussed here)

I don't have my usual dev setup at the moment so the patches might be in the incorrect format

comment:3 by Woazboat, 22 months ago

See #22703, #22704

comment:4 by mikeho, 22 months ago

When will the function "rotation_parent_way" be available?

I have attached a file to illustrate the challenge. It is important that the rotated text, in the coordinate system rotated on the parent way, can be moved (offset-x, offset-Y) as well as the icon. Only this allows the exact positioning of the individual elements (icons and texts) to an composed icon.

by mikeho, 22 months ago

Attachment: icon-text-rotation.pdf added

comment:5 by Woazboat, 22 months ago

The function will be called parent_way_angle. Check #22704 for status updates related to that.
Offset relative to the rotated coordinate system is pending until someone implements it

comment:6 by Klumbumbus, 22 months ago

Summary: MAPCSS, Note on: icon-rotation: way; text-rotation: way; coordinate transformation, documentationMAPCSS, Note on: icon-rotation: way; text-rotation: way; coordinate transformation, documentation [patch]

in reply to:  1 comment:7 by skyper, 22 months ago

Summary: MAPCSS, Note on: icon-rotation: way; text-rotation: way; coordinate transformation, documentation [patch]MAPCSS, Note on: icon-rotation: way; text-rotation: way; coordinate transformation, documentation

Patches are in separate tickets now.

Replying to Woazboat:

Okay so there's multiple TODOs here:
1) *-rotation: way; needs to be documented

It is a wiki, feel free to add and update the documentation.

comment:8 by taylor.smock, 22 months ago

In 18661/josm:

Fix #22703, see #22695, #22704: 90° offset of icon-rotation: way; in mapcss (patch by Woazboat, modified)

This is due to Geometry.getSegmentAngle getting the rotation from the positive
x-axis instead of the positive y-axis, but this is easily corrected by
subtracting 90 degrees (pi/2) from the calculation.

The previous behavior differed from the static rotation angle behavior, which
uses the positive y-axis.

comment:9 by marcello@…, 22 months ago

I think I have this problem already solved in my 'personal edition' of JOSM.

Demonstration of rotated icon + text + additional panels:

https://raw.githubusercontent.com/MarcelloPerathoner/josm/develop/demo/rotation.png

My implementation adds a mapcss-function heading(), that you use this way:

node.sign[direction=forward] {
    icon-rotation: heading();
}
node.sign[direction=backward] {
    icon-rotation: eval(heading() + 3.14);
}

You can test my version starting here:

https://github.com/MarcelloPerathoner/josm

The traffic-sign stylesheet is in the incubating directory.

If you like this, I can create a pull-request.

in reply to:  9 ; comment:10 by Woazboat, 22 months ago

Replying to marcello@…:

My implementation adds a mapcss-function heading(), that you use this way:

Sounds similar to #22704

What's missing is the text rotation and offset anchor (i.e. whether the offset should also be rotated)

comment:11 by Woazboat, 22 months ago

But if you have made improvements for josm, why keep them in your 'personal implementation' and not upstream them?

comment:12 by marcello@…, 22 months ago

Similar, but mine is more flexible: you can rotate forward and backward and any other angle you want in relation to the way.

I don't quite see why you'd want to rotate around any other centerpoint than the node itself. Can you name a use case? If there's a use case for more complex transformations we should better implement all transformation functions like in CSS, so that you can say, e.g.:

text-transform: translate(-x, -y, rotate(heading() + 3.14, translate(x, y))); or
icon-transform: matrix(a, b, c, d, e, f);

As for why I'm not upstreaming: I would, but I doubt the maintainers would accept so big a patch and its hard to split up into smaller ones because its all connected. But the rotation thingie would split off easily.

in reply to:  12 ; comment:13 by Woazboat, 22 months ago

Replying to marcello@…:

Similar, but mine is more flexible: you can rotate forward and backward and any other angle you want in relation to the way.

Not sure why it would be more flexible? The only difference is the name of the function and that your version tries to pick the 'correct' parent ways by itself vs. the one in #22704 uses the one matched via mapcss child selectors.

I don't quite see why you'd want to rotate around any other centerpoint than the node itself. Can you name a use case? If there's a use case for more complex transformations we should better implement all transformation functions like in CSS, so that you can say, e.g.:

text-transform: translate(-x, -y, rotate(heading() + 3.14, translate(x, y))); or
icon-transform: matrix(a, b, c, d, e, f);

The center point would still be the node, only the translation coordinate system would be rotated. As for use cases, ask the OP of this issue who requested this.

in reply to:  13 ; comment:14 by marcello@…, 22 months ago

Replying to Woazboat:

Not sure why it would be more flexible? The only difference is the name of the function and that your version tries to pick the 'correct' parent ways by itself vs. the one in #22704 uses the one matched via mapcss child selectors.

I meant that icon-rotation: way does not allow to specify a backward-facing sign. (Or does it? Its undocumented.)

The function parent_way_angle OTOH needs to be told exactly one way to use. It does not bisect angles. What happens if the node is at a junction of two ways, as many traffic signs are?

My function works well at the junction of two ways. It also bisects the angle, which looks slightly better.

The use case illustrated in the PDF is fully covered by my version.

BTW. in your patch 0002 you refer to the "child selector" but your link points to the "link selector".

by marcello@…, 22 months ago

Screenshot Icon and Text Offset and Rotated

comment:15 by marcello@…, 22 months ago

Demo of the use case of the OP: icon and text offset from the way and rotated. The traffic sign is one SVG, the additional panel is another SVG in a different layer, the text is taken from a tag. Everything rotates around the node as centerpoint (which is the red blob).

https://josm.openstreetmap.de/attachment/ticket/22695/Screenshot from 2023-02-15 21-13-39.png

in reply to:  14 comment:16 by Woazboat, 22 months ago

Replying to marcello@…:

Replying to Woazboat:

Not sure why it would be more flexible? The only difference is the name of the function and that your version tries to pick the 'correct' parent ways by itself vs. the one in #22704 uses the one matched via mapcss child selectors.

I meant that icon-rotation: way does not allow to specify a backward-facing sign. (Or does it? Its undocumented.)

Ah, no that has a fixed rotation in the way direction. I was referring to the parent_way_angle() mapcss function though.

The function parent_way_angle OTOH needs to be told exactly one way to use. It does not bisect angles. What happens if the node is at a junction of two ways, as many traffic signs are?

My function works well at the junction of two ways. It also bisects the angle, which looks slightly better.

Being able to specifically select the parent way via the child selector is a feature. If there are multiple potential parents, the matching code IIRC simply picks the first one (could be that I'm misremembering this). That's a limitation of the mapcss matching though and not specific to this function.
Your parent discovery method is useful if there is no specified parent or if there are multiple, so maybe that could be merged together.
The angle was chosen to be similar to the already existing implementation for *-rotation: way;. It would be confusing if those two used different angles. Bisecting angles would probably be better, but that'd have to be changed for both *-rotation: way; and for parent_way_angle().

The use case illustrated in the PDF is fully covered by my version.

The missing pieces would be useful to have in josm.

BTW. in your patch 0002 you refer to the "child selector" but your link points to the "link selector".

Ah, true. I think that's because the documentation for the parent object in the mapcss environment linked to the LinkSelector and I copied that.

in reply to:  10 comment:17 by Woazboat, 22 months ago

Replying to Woazboat:

offset anchor (i.e. whether the offset should also be rotated)

Replying to Woazboat:

The center point would still be the node, only the translation coordinate system would be rotated.

This is similar to what I meant, just with an additional option to use the icon/text rotation as the reference: https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/#paint-symbol-icon-translate-anchor
Frame of reference is probably the better term.

comment:18 by mikeho, 21 months ago

Note regarding the above discussion:
OK - there are styles that do not need rotation. Three examples are attached (direction of osm-way, maxspeed as text, railway switches).
For railroad signals the rotation of the icon and the text is required. I have attached this style - in the current development state - as well.
Signals are usually tagged only to nodes that belong to a way. The possible ambiguity can therefore be neglected in my opinion.

by mikeho, 21 months ago

Attachment: direction_of_osm_way.zip added

by mikeho, 21 months ago

Attachment: maxspeed_as_text.mapcss added

by mikeho, 21 months ago

Attachment: switch.zip added

by mikeho, 21 months ago

Attachment: railway_signal_ger.zip added

by marcello@…, 21 months ago

Attachment: text-rotation.1.patch added

Rotate text around node

comment:19 by marcello@…, 21 months ago

Can you apply the patch and see if it fixes your problem?

by marcello@…, 21 months ago

Screenshot of railway speed limit sign with rotated text

comment:20 by StephaneP, 14 months ago

I hope that we will see this in Josm soon !

comment:21 by gaben, 14 months ago

Cc: gaben added

I was thinking about a feature some time ago. For give way and passing place - if they have sides defined - would be very useful. Although, I believe it requires some testing to see how these small icons behave with rotation.

Modify Ticket

Change Properties
Set your email in Preferences
Action
as new The owner will remain team.
as The resolution will be set. Next status will be 'closed'.
to The owner will be changed from team to the specified user.
Next status will be 'needinfo'. The owner will be changed from team to mikeho.
as duplicate The resolution will be set to duplicate. Next status will be 'closed'. The specified ticket will be cross-referenced with this ticket.
The owner will be changed from team to anonymous. Next status will be 'assigned'.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.