# [OSM-talk] Playing with Mapnik rendering

Cameron Patrick cameron at patrick.wattle.id.au
Mon Jul 30 16:33:35 BST 2007

```Artem Pavlenko wrote:

> It works, but produces some artifacts. I think we can do better, but
> thanks again for your patch.
>
> http://artem.dev.openstreetmap.org/files/dy.png  - you can see 'd'

first thought - you'd have to build a new displaced line up front, since
there are many calculations that depend on this (e.g. you need to know
the length of the line when calculating the "ideal" placements).  I'm
not game to do this right now since it'd be relatively intrusive.  The
other mapnik features I wanted to add look like they might be similarly
intrusive - would probably need to make several trial label placements
and score them on "badness", a la TeX.

I'm also not sure if there's an easy way for Mapnik to tell if/how many
lines or areas a point is overlapping, something that'd help to avoid
the example I showed early where a road name overlaps a railway line.

I've attached a patch that makes sure the names of vertical roads are
rendered in a consistent direction (as mentioned by Robert Munro).

Cheers,

Cameron

-------------- next part --------------
Index: src/placement_finder.cpp
===================================================================
--- src/placement_finder.cpp	(revision 493)
+++ src/placement_finder.cpp	(working copy)
@@ -370,7 +370,7 @@

// angle text starts at and orientation
angle = atan2(-dy, dx);
-            orientation = fabs(angle) > M_PI/2 ? -1 : 1;
+            orientation = (angle > 0.55*M_PI || angle < -0.45*M_PI) ? -1 : 1;

distance -= target_distance;

@@ -448,12 +448,12 @@
if (displacement == 0.0) {
x -= (((double)string_height/2.0) - 1.0)*cos(render_angle+M_PI/2);
y += (((double)string_height/2.0) - 1.0)*sin(render_angle+M_PI/2);
-         } else if (displacement > 0.0) {
-           x -= ((displacement + (double)string_height) - 1.0)*cos(render_angle+M_PI/2);
-           y += ((displacement + (double)string_height) - 1.0)*sin(render_angle+M_PI/2);
+         } else if (displacement*orientation > 0.0) {
+           x -= ((fabs(displacement) - (double)string_height) + 1.0)*cos(render_angle+M_PI/2);
+           y += ((fabs(displacement) - (double)string_height) + 1.0)*sin(render_angle+M_PI/2);
} else { // displacement < 0
-           x -= ((displacement - (double)string_height) - 1.0)*cos(render_angle+M_PI/2);
-           y += ((displacement - (double)string_height) - 1.0)*sin(render_angle+M_PI/2);
+           x -= ((fabs(displacement) + (double)string_height) - 1.0)*cos(render_angle+M_PI/2);
+           y += ((fabs(displacement) + (double)string_height) - 1.0)*sin(render_angle+M_PI/2);
}
distance -= ci.width;
next_char_x = ci.width*cos(render_angle);
```