Skip to content
This repository

minimum-distance not respected across features when placing text #995

Open
springmeyer opened this Issue December 16, 2011 · 17 comments

4 participants

Dane Springmeyer Artem Pavlenko Axel Haustant Bonnasseau
Dane Springmeyer
Owner

minimum-distance works across features/layers for shields, but not for text placed along lines.

Fixing this properly will require a deep dive, but a brute for workaround appears to be:

diff --git a/src/placement_finder.cpp b/src/placement_finder.cpp
index b055a93..f4c20ec 100644
--- a/src/placement_finder.cpp
+++ b/src/placement_finder.cpp
@@ -910,7 +910,8 @@ bool placement_finder<DetectorT>::test_placement(std::auto_ptr<text_path> const&

         if (!detector_.extent().intersects(e) ||
             (!p.allow_overlap &&
-             !detector_.has_placement(e, info_.get_string(), pi.get_actual_minimum_distance())
+             !detector_.has_point_placement(e, pi.get_actual_minimum_distance())
+             //!detector_.has_placement(e, info_.get_string(), pi.get_actual_minimum_distance())
             )
            )
         {

See also: http://support.mapbox.com/discussions/tilemill/299-how-to-stop-labels-repeating-so-close-to-each-other

Dane Springmeyer
Owner

/cc @ajashton - fyi on that workaround. Tomorrow I'll take a look at a more proper fix.

Dane Springmeyer
Owner

also need to take a look at how this is handled or not handled for markers. Basically the task is to ensure that the functionality added for find_point_placement in 3f47de0#L2R486 works for text placement along lines

Artem Pavlenko
Owner
artemp commented July 13, 2012

@springmeyer @herm - ok, testing..

line placement for Text seems to work, but Markers are not using minimum-distance. Should we add minimum-distance to MarkersSymbolizer ?

Dane Springmeyer
Owner
Artem Pavlenko
Owner
artemp commented July 13, 2012

@springmeyer - ok, on my TODO list

Artem Pavlenko
Owner
artemp commented July 16, 2012

@springmeyer - this all boils down to :

has_placement test

if (itr->box.intersects(box) || (text == itr->text  && itr->box.intersects(bigger_box)))

has_point_placement test

if (itr->box.intersects(bigger_box))

The first one (currently used) looks ok to me.

Dane Springmeyer
Owner

okay, I will look into this more, assigning back to me.

Axel Haustant

Is there something new on this ?
Spacing only is really hard to handle.
Minimum distance gives homogeneous text and having it working on shield would be a real benefit!

Dane Springmeyer

@noirbizarre - can you say more about what you are struggling with? At this point I actually think the behavior is correct, but this ticket is open until I can write several tests to enforce it does not regress.

Axel Haustant

I just tested it: it's working in fact.
My bad.

I have some questions, but I will ask on IRC.

Bonnasseau

Hello,

when i look at the code, it seems to me that :

  • when text is placed at a point, minimum-distance ensures that no element (previous marker, shield, text) on the map is nearer this distance
  • when a shield is placed along a line, minimum-distance ensures that no element (previous marker, shield, text) on the map is nearer than this distance (like the previous one)
  • when a text is placed along a line, minimum-distance ensures that no similar text is nearer than this distance (either on this layer or not), but other elements can

It seems that minimum-distance along a line doesn't have the same meaning for shields and for texts. I am right ?

Bonnasseau

This issue seems to be addressed by the diff you provided at the top of the ticket. Are you still willing to commit it ?

Dane Springmeyer
Owner

@abonnasseau - do you have a test case? I think the tricky bit here when testing expected/consistent behavior is whether placement="line" or not. Both text and shield symbolizers default to placement="point", but very often existing stylesheets actually keep that default for shields, because it still "looks right" since the shield is supposed to be upright (vs. text which requires placement="line" to look right when a linear geometry is being used).

Bonnasseau

Here's a functional case : I'd like to be able to set a parameter to avoid the text from the street names to be too close to the points of interest, like in this screenshot :

max_distance

According to what minimun-distance does in the case placement="point", I thought it would be the same with placement="line".

The question is more semantic than technical, I understand that.

Dane Springmeyer
Owner

Cool, thanks. I will try to create a small testcase to isolate. I'm not comfortable making modifications without better regression tests.

Bonnasseau

Hello,

what I understand is that the expected behavious is the one described in the doc : "minimum-distance = Minimum distance between repeated labels such as street names or shield symbols (works across features)". That is not what is illustrated by the screenshot I sent on friday. What got me wrong in the first place was that I can't find a use case for this specific feature. Do you recall some ?

And considering text and shields on a point, what minimum-distance implements is rather a margin. It is not what is described in the doc, but might be widely used.

This leaves an uncoverd fonctionality : what if we want a margin on texts along a line ? Which is what I would want between "Rue Montmarte" and the metro shield "Grands Boulevards (Rue Montmarte)", on the screenshot.

Do you think we can find a functionnal issue without breaking existing templates ?
Or would we have to consider minimum-distance as a deprecated feature ad implement "margin" (on lines and points) and "same-text-margin" (only along lines ?) instead ?

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.