Rendering text labels when labels length exceeds the length of the line #13

Open
artemp opened this Issue Oct 11, 2011 · 18 comments

5 participants

@artemp
Mapnik member

We are building tiles where the point size of line labels can exceed the width of the line. In these case, labels are applied very sparsely (see example tiles).

I don't have a complete example to share, since it would require access to our database, but let me know if you can't reproduce it. I can try to get something out of rundemo.py.

Please feel free to contact me if you need more information or testing.

@artemp
Mapnik member

[reid@umn.edu] 171_449.png was uploaded in error and can be removed.

@artemp
Mapnik member

[artem] At the moment there are no attempts to find text placement if length of geometry is less than text length : source:/trunk/src/placement_finder.cpp@452#L213

What are the options?

  1. Place text label on straight line between start/end points?
  2. ???
@artemp
Mapnik member

[paul] Replying to [comment:2 artem]:

What are the options?

  1. Place text label on straight line between start/end points?
  2. ???

For my applications, the common case is a straight street segment. So having the text label extend proportionally beyond the start and end points of the feature is acceptable.

If I were styling my map and the above behavior were implemented, and a particular were /not/ straight, I would expect the label to follow the feature as currently implemented, and then as it goes "off the edges," it would retain the angle of the last character drawn, like a vector extending out from each end.

@artemp
Mapnik member

[paul] For an example, I want to label "arterial" streets, highlighted here in red:

[[Image(highlighted.png)]]

(It's worth remembering that these actually individual blocks that combine to appear to be contiguous streets; here is the "inverse", so you can see where the arterial segments are:)

[[Image(segments.png)]]

If I use point placement of the labels, say 9pt font size, I get this:

[[Image(pointplacement.png)]]

I could control minimum distance and spacing at this point but would still get suboptimal results. Labels need to follow the line of the street. Changing to line placement, labels disappear at 9pt, so changing to a very small size just to see if it works at all (3pt) yields:

[[Image(3ptlabels.png)]]

Increasing the font size starts to knock out most labels, as they get longer than the length of the underlying feature/block:

[[Image(4ptlabels.png)]]

What I desire is this (mocked-up by hand in the GIMP):

[[Image(desired.png)]]

If [http://local.google.com/?ie=UTF8&ll=41.95582,-87.705917&spn=0.016149,0.028067&z=15&om=1 Google] can do it, so should Mapnik ;)

@artemp
Mapnik member

[dave] I think the strange placement is caused by the text renderer not handling multi-linestrings nicely.
If you could send me a small shapefile that can cause it I will investigate it.

@artemp
Mapnik member

[rpriedhorsky] A ping on this bug. I just upgraded to 0.5.1 and it's still present.

The fix that I would really like to see is joining of separate but adjacent linestrings with the same name within mapnik. I had thought (and stated earlier) that this joining could be done in the database. I have not been able to figure out how to do this. The best I can do is to bring the linestrings together as multilinestrings (potentially with gaps), and this still has severe performance problems.

Bottom line: it may still be possible to do this in the database, but I'm not a PostGIS noob and in any case it seems rough to require users to write complex, tricky queries to get this (fairly basic IMO) functionality working.

I have attached two files. 232_2432.png is a rendering taken from our PostGIS database. There should be more labels here: all but the narrowest streets should be labeled at reasonable intervals.

The second attachment is a shapefile extract of our database for the same region as the tile. It is missing a few properties but I don't think they will be missed for this purpose.

Please let me know how I can help improve Mapnik in this aspect. Thanks!

@artemp
Mapnik member

[springmeyer] Reid, collecting geometries like you mention above should now be possible, in a performant way, using PostGIS and the BBOX substitution and the ST_COLLECT or ST_UNION (ideally in postgis >=1.4) functions (along with a GROUP BY) as seen in #415.

New readers: See this long thread: http://lists.berlios.de/pipermail/mapnik-users/2008-January/000553.html

...culminates in solution to pre-process shapefile geometries by collecting adjacent linestring segments into multilinestrings, which can also be done on-the-fly when using a postgis datasource (see examples with #415).

Also: http://lists.berlios.de/pipermail/mapnik-users/2009-October/002384.html

@artemp
Mapnik member

[springmeyer] see also: https://savannah.nongnu.org/bugs/?27467

In a brief discussion with #maposmatic developers we considered that various potential solutions to label overflow could be to:

1) continue the line/char placement in the angle of last char placement (straight)
2) continue in an interpolated arc (curved)
3) attempt to break the line to create a shorter-wrapped line (break)

@artemp
Mapnik member

[Ldp] Option 3 is what I usually see used in commercial city maps.

Also, I've never really understood why the ticket would say 'exceeds width of the line', when clearly the length of the line was meant. The width of a line has no impact whatsoever on the label. Changing the ticket title accordingly.

@artemp
Mapnik member

[springmeyer] automatically shrinking text is an option:

http://hansvandermaarel.wordpress.com/2010/03/22/street-name-length-vs-street-length/

@artemp
Mapnik member

[artem] Ok, as a first attempt to solve this issue we could try :

  • extending first and last segments (as suggested by Paul)
  • consider point placement
  • placement along extended straight line between first and last vertex

This should be optional e.g symbolizer paramater.

@emacgillavry

Our current approach uses PostGIS is to chain neighbouring road segments that have the same name. We also take into account other attributes that may influence the rendering of the street name (e.g. colour of the halo determined by the type of road and colour of the text determined by whether it is in a tunnel or not) To prevent all the road segments named "high street" to be one geometry in the database, we subsequently dump the chained segments like so:

CREATE TABLE nw_named as select name, frc, fow, freeway, net2class, oneway, shieldnum, feattyp, partstruc,
(ST_Dump(ST_Linemerge(ST_Union(geom3857)))).geom AS geom3857 FROM nw where "name" IS NOT NULL
GROUP BY name,frc,fow,freeway,net2class,oneway,shieldnum,feattyp,partstruc;

Another approach to shorten the labels instead of using a condensed font, suggested in the blog posting by fellow countryman Hans van der Maarel, would be to offer the label placement routine multiple columns from the database with ever shorter versions of the street name. From Hans' example:

  • Oscar Van Kesbeeckstraat
  • O. van Kesbeeckstraat
  • O. van Kesbeeckstr.
  • O. v. Kesbeeckstr.

For now, you could join the table with the road segment geometries with the table containing the street name spelling alternatives and order the joined table by the length of the street name. Longer street names are placed before their shorter spelling alternatives. Downside: it exponentially grows the already huge table of road segments.

@springmeyer springmeyer was assigned May 9, 2013
@Andrey-VI

Still a must have feature.
QGIS default Parallel placement:
_placement_line

@flippmoke
Mapnik member

Not sure if this is still an issue closing for now

@flippmoke flippmoke closed this Apr 25, 2015
@Andrey-VI

Is this really has been fixed?

@springmeyer
Mapnik member

Right, not fixed and we should expose and option to do what QGIS allows. Thanks for the graphic @Andrey-VI.

@springmeyer springmeyer reopened this Apr 25, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment