Advanced format in TextSymbolizers #1807

Closed
plepe opened this Issue Apr 12, 2013 · 6 comments

Comments

Projects
None yet
3 participants
Contributor

plepe commented Apr 12, 2013

On the basemap of OpenStreetBrowser, labels of places with an English translation get a two-lined label, with the original name in the first line and - in a smaller font - the English name in a second. I created this by using two TextSymbolizers with increasing dy. See this image for an example:
170
Unfortunately, this keeps me from using the new placements, as the labels would get scrambled up, when one label is displaced (say) to the left and the other to the right.

Another example for advanced text rendering ist the 'Public Transport Overlay' in OpenStreetBrowser. Here, labels are printed with the ref's of the routes using that line. Tram lines get printed in red, buses in blue. I used two TextSymbolizers to print the ref's, that's why there's no ',' between the tram ref's and the bus ref's.
23031
I would like to improve readability by using just one Symbolizer and changing the text color inside the label.

Do you think it would be possible to change the font size resp. color inside a TextSymbolizer, e.g. by using some kind of markup? E.g.:
<font color='#ff0000'>1, 2 ,3</font>, <font color='#0000ff'>N1, N7</font>

Maybe we could simplify this markup by using control characters as markup indicators, e.g.:
\ecolor:#ff0000|font-size:10\eRED TEXT\eNORMAL TEXT

Looking forward to your ideas on this subject ...

Plepe.

PS: I'm deeply impressed, that my last issue #1533 was already solved :)

Contributor

plepe commented Apr 12, 2013

There isn't any documentation about this feature, is there? I couldn't find anything on the web. Anyway, this perfectly solves my first scenario. Thanks!

For my second scenario this solution is not perfect, but I think I can adapt to it. It would be even better, if even the format can be dynamic, but you can't expect anything :)

Plepe.

Member

herm commented Apr 12, 2013

You can do almost everything with the new formatting framework. You can even define your own formatting processor. It is quite easy. As a reference have a look at
https://github.com/mapnik/mapnik/blob/master/src/formatting/format.cpp
and
https://github.com/mapnik/mapnik/blob/master/src/formatting/expression.cpp

It's about 2/3 XML parsing and 1/3 real work. For easier prototyping you can even try to write the code in python. An example is in https://github.com/mapnik/mapnik/blob/master/tests/visual_tests/test_python.py
but don't be disappointed if it doesn't work. You would be the first person to use this for a real world application. I will try to fix any bugs you find.

Contributor

plepe commented Apr 14, 2013

It would be even better, if the format does not need to be known at compile time, like I could produce the XML in the database and Mapnik just prints the result.

But I can adapt to the current <ExpressionFormat> too ... great that it exists :-) But it does not fully work for me yet.

<TextSymbolizer ... fill="#000000">
<ExpressionFormat fill="[color]">[color]</ExpressionFormat>
</TextSymbolizer>

prints "#ff0000" on the line - but in black.

<ExpressionFormat fill="#ff0000">[color]</ExpressionFormat>

fails on startup with the following message:
2013-04-14 07:58:07 (D) renderd renderd[24279]: An error occurred while loading the map layer 'overlay_pt': Failed to parse expression: "#ff0000" in style 'ways_refs' in TextSymbolizer at line 192 of '/path/to/overlay_pt.mapnik'

<Format fill="#ff0000">[color]</Format>

does work though, as does

 <ExpressionFormat size="9">[color]</ExpressionFormat>

Maybe the fill-color may not be set yet via the ExpressionFormat?

Plepe.

PS: I'm using the harfbuzz branch.

@herm herm added a commit that referenced this issue Apr 14, 2013

@herm herm Enable color processing in ExpressionFormat.
Refs #1807.
6a075c6

@herm herm added a commit that referenced this issue Apr 14, 2013

@herm herm Add tests for 6a075c6.
Refs #1807.
abad0da
Member

herm commented Apr 14, 2013

Colors were disabled because efficient color parsing is currently difficult. It requires the parser object to be passed to each and every function that does color parsing. Otherwise a new parser is constructed every time (which is an expensive operation). I think the color parser could be made a singleton which is available everywhere. @artemp, @springmeyer: Do you agree on this?

I added the necessary functions now. Don't expect the performance to be great.

<ExpressionFormat fill="#ff0000">[color]</ExpressionFormat>

fails because #ff0000 is not a correct Expression. You need another pair of quotes:

<ExpressionFormat fill="'#ff0000'">[color]</ExpressionFormat>

herm was assigned Apr 14, 2013

Contributor

plepe commented Apr 15, 2013

Thanks for clarifying! Coloring texts works beautifully now. Can't really say about performance, my bottlenecks are in the database (I'm building a public transportation map, as you might have guessed from my test images). I'm doing a lot of querying, grouping, ...

Maybe there's a possibility to prepare those colors and reference them? I got only about 10 colors which will be used in those ExpressionFormats ...

Here's a preview of what I'm doing:
example - wien neubau
The label "49 -> 12A" between Siebensternplatz and Stiftsgasse is a label with the ExpressionFormat coloring.

Plepe.

plepe closed this Jul 14, 2014

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment