Skip to content

Smooth parameter for TextSymbolizer #1484

Closed
gravitystorm opened this Issue Sep 14, 2012 · 7 comments

4 participants

@gravitystorm

When you draw a line with a smooth value, and you want to label along the line, you need to smooth the underlying line by the same amount. But there's no smooth parameter for TextSymbolizer.

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Map>
<Map background-color="white" srs="+proj=latlong +datum=WGS84">
    <Layer name="layer" srs="+proj=latlong +datum=WGS84">
        <StyleName>My Style</StyleName>
        <Datasource>
            <Parameter name="type">csv</Parameter>
            <Parameter name="inline">
              wkt
              "LINESTRING(0 0, 10 2, 10 5, 0 10)"</Parameter>
        </Datasource>
    </Layer>

    <Style name="My Style">
        <Rule>
            <LineSymbolizer stroke-width="2" smooth="0.8" />
            <LineSymbolizer stroke-width="0.2" stroke="#ff0000" />
            <TextSymbolizer face-name="DejaVu Sans Book" size="10" placement="line" spacing="20">'Bananas'</TextSymbolizer>
        </Rule>
    </Style>
</Map>

The desired outcome is to label the smooth black line, but the labels just follow the original geometery (in red)

@gravitystorm

I've updated this with a csv-plugin based testcase.

@springmeyer
Mapnik member

Yes, text symbolizer does not support smoothing/simplification/offsets, etc. The design of the text symbolizer_helpers (which handle text options) does not currently play nicely with the design of the vertex converters (generic framework for chaining transformations like affine, geo->screen, projection, and things like smoothing). So the task is to refactor the internal design so these code structures can work together. I think @herm has made some progress on this in the harfbuzz branch (where offsets work).

@herm
Mapnik member
herm commented Apr 15, 2013

Implementing the other vertex converters should be trivial in the harfbuzz branch. The main problem is that vertex_converters.hpp is extremely complicated code which uses lots of template wizardry. It really needs some documentation.

@herm
Mapnik member
herm commented Apr 15, 2013

Having looked at it again here is a completely new proposal for vertex_converters:

class vertex_source
{
public:
    virtual void rewind()=0;
    virtual bool vertex(double &x, double &y)=0;
};

class vertex_converter : public vertex_source
{
    public:
        virtual void set_input(vertex_source_ptr)=0;
};

class offset_converter : public vertex_converter
{
public:
    offset_converter(double offset);
    virtual void set_input(vertex_source_ptr);
    virtual void rewind();
    virtual bool vertex(double &x, double &y);
};

/* Create list of all active converters for this symbolizer. */
std::list<vertex_source_ptr> converters;
converters.push_back(boost::make_shared<offset_converter>(3.5));
converters.push_back(...);

/* Process list. */

vertex_source_ptr vs = GEOMETRY_FROM_DATABASE;
BOOST_FOREACH(vertex_source_ptr converter, converters)
{
    converter.set_input(vs);
    vs = converter;
}
render(vs);

The code is easy to understand/extend.

@springmeyer
Mapnik member

@artemp - can you comment on @herm's proposal above? I also wonder about ways to make vertex converters easier to work with. My understanding is that the template approach ensures near zero-overhead whereas the proposal above might incur more runtime overhead, but likely not noticeable.

@artemp artemp was assigned by springmeyer Jul 30, 2014
@artemp
Mapnik member
artemp commented Aug 6, 2014

added vertex_converters in 9835057

@springmeyer
Mapnik member

This is now implemented in master/upcoming Mapnik 3.x, tests added in d6c59d9, closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.