Group Symbolizer by hollinger · Pull Request #2160 · mapnik/mapnik · GitHub
Skip to content

Group Symbolizer#2160

Merged
springmeyer merged 15 commits into
mapnik:expr-v2from
MapQuest:expr-v2-group-symbolizer
Apr 3, 2014
Merged

Group Symbolizer#2160
springmeyer merged 15 commits into
mapnik:expr-v2from
MapQuest:expr-v2-group-symbolizer

Conversation

@hollinger

Copy link
Copy Markdown
Member

This pull request contains a new symbolizer, along with its implementation in each of the renderers.

The purpose of group symbolizer is to place multiple road shields or other labels grouped as single point placements on a feature. The individual labels in the group get positioned automatically by a group layout defined within the symbolizer. Multiple labels can be represented on a single feature using numbered column names. These numbered columns are matched to a single set of rules within the group symbolizer. This single set of style rules greatly simplifies the style definition needed to represent many different combinations of shields or labels.

For example:

<GroupSymbolizer num-columns="2">
    <SimpleLayout />
    <GroupRule>
        <Filter>[ref%].match('US ')</Filter>
        <PointSymbolizer file="us-shield.png"/>
        <TextSymbolizer>[num%]</TextSymbolizer>
    </GroupRule>
    <GroupRule>
        <Filter>[ref%].match('I ')</Filter>
        <PointSymbolizer file="interstate-shield.png"/>
        <TextSymbolizer>[num%]</TextSymbolizer>
    </GroupRule>
</GroupSymbolizer>

The above group symbolizer definition specifies two sets of columns per feature, and it references [ref%] and [num%] within its rules and symbolizers. As a result, the group symbolizer will look for column the following columns: [ref1], [num1], [ref2], and [num2]. Each set of columns will be matched to the rules separately. The default simple layout that is defined will arrange each of these labels in a horizontal row, centered on the placement point.

Currently, group symbolizer supports point, text, and shield symbolizers within the group rules. This could possibly be extended to include markers symbolizer. Group symbolizer is not designed to work with other symbolizers that are not label related.

Documentation on GroupSymbolizer can be found here: https://github.com/MapQuest/mapnik/wiki/GroupSymbolizer

hollinger and others added 13 commits February 18, 2014 11:07
This includes XML parsing of group symbolizer and related objects and
process_group_symbolizer method in the AGG renderer. This also includes
code to collect group symbolizer indexed columns, create sub features,
and match them to group rules.
This is done by creating a fake 'virtual' environment at a fake
point and running the symbolizer render code. The actual render
is saved in a thunk for after the group layout has been done.
This renders the saved information from previous calls to the
bounding box extraction code, offset by some amount which should
be determined from running the `placement_finder`. Note that this
doesn't implement that bit, just the rendering.
Create a group_symbolizer_helper for group placments, and extract some code from
text_symbolizer_helper into a base class to share with group_symbolizer_helper.
Also, move tolerance_iterator into its own header file. Use helper in
process_group_symbolizer to find placement positions.
Segfault was due to `glyph_position` structs keeping a pointer to
`glyph_info` objects which went out of scope at a different time.
The (rather ugly) fix for the moment is to copy that information
into the thunk object.
Move a lot of processing into a common process_group_symbolizer function.
Also, extract column collection out of process_group_symbolizer function.
This will reduce duplication needed for other renderers.
The first test shows how an obstacle under the group being displayed
will cause the whole group to not display. Above is an replica of
the same layout using non-grouped symbolizers, which shows that
only the parts which intersect the obstacle will not be drawn.

The second is a line placement test, which just tests placement
of groups on a line with variable spacing.

The third is a test of repeat key in group symbolizer.
The test shows two items with different repeat keys ("foo" and "bar")
and rows of other group symbolizers sensitive to either one. The
reference images show that the "bar"-sensitive rows are displaced
by the "bar" item, but not the "foo" item.
This uses the renderer_common header to do most of the heavy
lifting, but otherwise is very similar to the AGG renderer
implementation.

Add cairo ref images for group symbolizer tests.
Debug symbolizer is useful, and used in a bunch of tests. This
adds debug symbolizer support for Cairo to make it closer to the
capabilities of AGG.

Adding debug symbolizer for Cairo meant that red boxes appeared in
many of the visual test outputs. This commit replaces them with
the output, after visual inspection. They should now be closer to
the output of the AGG test cases.
Note that the "implementation" for SVG renderer is the same as
for other symbolizers there - i.e: empty.
This uses common process_group_symbolizer for most of the work.
Add reference grids for visual tests.
Boost::Python interface, and added a test to check that it works.
Looks like it fails at the moment due to other changes - a lot of
the python symbolizer tests show the same thing.
…-symbolizer

Conflicts:
	include/mapnik/attribute_collector.hpp
@springmeyer

Copy link
Copy Markdown
Member

@hollinger

Copy link
Copy Markdown
Member Author

It is good to have #2138 merged first. Although GroupSymbolizer builds on the concept of #2138, it is not directly an interface to that functionality. GroupSymbolizer is about placing several entire symbolizers into a single placement. The group symbolizer matches data to symbolizers in the rules, figures out an offset amount for each one based on the layout, and then renders those symbolizers on the offset points.

hollinger and others added 2 commits February 25, 2014 08:53
Update some test cases to use ShieldSymbolizer instead of point and text.
…-symbolizer

Conflicts:
	src/text/placement_finder.cpp
	tests/visual_tests/test.py
@springmeyer

Copy link
Copy Markdown
Member

noticing there appear to be some visual test image changes that look like the DebugSymbolizer was added and the images were committed accidentally. For an example see the shieldsymbolizer-* images.

@hollinger

Copy link
Copy Markdown
Member Author

A number of test cases included a debug symbolizer already, but debug symbolizer was only implemented in the agg renderer. A cairo renderer implementation of debug symbolizer was added in 7e25a22 which changed some of output images for cairo renderer only.

@springmeyer

Copy link
Copy Markdown
Member

aha, thanks did not see that.

@springmeyer

Copy link
Copy Markdown
Member

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants