Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decluttering mode by style #13566

Merged
merged 5 commits into from
May 6, 2022
Merged

Conversation

cns-solutions-admin
Copy link
Contributor

As requested e.g. in #7475, this improves decluttering by being able to state per (image) style, how this style should be decluttered:

  • declutter => declutter as before
  • obstacle => draw image/text, but use it as obstacle for styles with mode "declutter"
  • none => do not declutter

Decluttering still only happens, if the layer also has declutter = true.

@cns-solutions-admin
Copy link
Contributor Author

I named the property declutterMode, because

  • it strongly hints that it is only used, if the layer's declutter = true
  • it is easier to understand than mapbox's allowOverlap and ignorePlacement
  • we can easily add other modes later on

I have also implemented support for decluttering in ol-mapbox-style. PR will follow, when this is accepted.

@cns-solutions-admin
Copy link
Contributor Author

Build errors (doc type links) fixed.

@github-actions
Copy link

📦 Preview the examples and docs from this branch here: https://deploy-preview-13566--ol-site.netlify.app/.

Copy link
Member

@ahocevar ahocevar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your work on this, @cns-solutions-admin!

Instead of introducing a DeclutterMode text enum, you could simply create a typedef with a union type. Something like:

/** @typedef {"none" | "obstacle" | "declutter"} DeclutterMode */

Eventually, we'll be changing all string enums in the library to union types.

To make sure that this new feature can be maintained, it would be important to add tests. In this case, two rendering tests (one for each new mode) would be appropriate.

Of course it would be nice to have this new option also for Text styles, but that does not need to be part of this pull request.

Finally, would you be able to squash the commits in a way that the pull request does not contain any merge commits? A single commit for the whole pull request would also work.

@cns-solutions-admin
Copy link
Contributor Author

I succeeded in squashing everything into one commit.
I added a rendering test for both modes based on the other decluttering test.
I left the DeclutterMode enum to be consistent with the other enums - unless everyone uses typescript, this way is safer.

@ahocevar
Copy link
Member

ahocevar commented Apr 21, 2022

Thanks for your continued effort on this, @cns-solutions-admin.

I left the DeclutterMode enum to be consistent with the other enums - unless everyone uses typescript, this way is safer.

We'll be removing these enums, see #12696. We do have the tooling in place (npm run typecheck) to ensure correct values with union types, and the generated d.ts files do not work with enums. For example, the return type for the getDeclutterMode() API method you introduced, will be broken from the start if you stick with the enum.

@ahocevar
Copy link
Member

The rendering test does not test the difference between none and obstacle mode. If there were e.g. other features rendered on top of the red and blue circles, it could be shown that with none mode (on top of blue) the other features would be drawn, but not with obstacle mode (on top of red).

@cns-solutions-admin
Copy link
Contributor Author

Based on your comments "you could..." and "eventually, ...", I assumed that it was better to use the enum for now.
It's changed now and the test is also improved.

Copy link
Member

@ahocevar ahocevar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In ahocevar@bbd58ea, I tried to make the test more readable. And by doing so, I saw something I have no explanation for:
actual
Why are the red circles on top of the c-orange label?

new Feature({
geometry: new Point([center[0], center[1]]),
text: 'center',
zIndex: 2,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to set a zIndex property on any of the features in this test - you're not using them in the style.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You introduced a typo: "zindex" instead of "zIndex". Thus the red circles were not used for the orange labels, as those were on top of the red layer.

But this highlighted that I somehow did not commit the continue in the executor: the obstacles are used in the declutter executor to be added to the declutter tree, but rendered in the normal executor - so that they are behind the labels (in the test they were also rendered in the declutter executor thus being drawn on top of the label).

Fixed the executor and updated the test with your version + fix + additional blue circle/text to test

  • that objects (red) cannot be obstacles for layers with a higher z index (blue)
  • that the obstacles (red) are drawn behind layers with a higher z index (blue)

Allows to specify for each image style, whether the image
should be decluttered, always drawn but still serving as
obstacle, or drawn without being an obstacle for other
images/texts.

The layer must still have declutter = true set for this
property to have any effect.
Copy link
Member

@ahocevar ahocevar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the new behavior is what I would expect. I added two more comments regarding the tests. When these are addressed, I think this is ready for prime time.

}),
]);
// circles are always drawn,
// texts are decluttered against each other and the layer 1 circles/texts
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For readability, please refer to the color instead of the layer number everywhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comments improved.

const sourceRed = new VectorSource();
sourceRed.addFeatures([
new Feature({
geometry: new Point([center[0] + 1000, center[1] + 1000 - 200]),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous version with the overlapping red circles was better, to show that they do serve as obstacle, but are rendered even if they overlap.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, reverted zoom, moved orange circles' text to left with xOffset to show at least one label.

Comment on lines 30 to 31
// circles are always drawn, but serve as obstacles,
// texts are decluttered against each other and the circles
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this comment is not applicable. declutterMode declutter here, so if you had more blue circles overlapping this one, they wouldn't be rendered.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed when improving comments.

ahocevar
ahocevar previously approved these changes May 5, 2022
Copy link
Member

@ahocevar ahocevar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your effort on this, @cns-solutions-admin

@ahocevar ahocevar dismissed their stale review May 5, 2022 12:00

Rendering test mismatch

@ahocevar
Copy link
Member

ahocevar commented May 5, 2022

Now we have a rendering test mismatch. The actual result does not show the e-cyan label for the cyan layer:
actual

@cns-solutions-admin
Copy link
Contributor Author

This is weird. Locally the test works.

@ahocevar
Copy link
Member

ahocevar commented May 5, 2022

I doubt that a difference in font rendering would cause this label to disappear, but I'll try in interactive mode to see what happens when zooming in/out a bit.

@ahocevar
Copy link
Member

ahocevar commented May 5, 2022

This is really weird. The results are quite stable when zooming in/out locally.

@ahocevar
Copy link
Member

ahocevar commented May 5, 2022

@cns-solutions-admin Maybe you could cherry-pick 134462c, so we can see if the tests pass then. Or you could grant maintainers access to this pull request's branch, then I could push that change here directly.

@cns-solutions-admin
Copy link
Contributor Author

Done. Seems that the font on my computer is a bit smaller/slimmer.

@ahocevar
Copy link
Member

ahocevar commented May 6, 2022

Now it looks good. You have to update the reference image in your branch with the one from the CI, or give me access to this pull request's branch, or cherry-pick 9d17d92.

@cns-solutions-admin
Copy link
Contributor Author

CI image downloaded, committed and pushed.
Seems that giving access to branches is not possible for organization accounts.

Copy link
Member

@ahocevar ahocevar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your continued effort on this, @cns-solutions-admin

@ahocevar ahocevar merged commit 71f3780 into openlayers:main May 6, 2022
@marcjansen
Copy link
Member

Very nice collaboration here.

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