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

fix: set turns in closed clusters as non traversable #1248

Conversation

barendgehrels
Copy link
Collaborator

No description provided.

// If the cluster is completely closed, mark it as not traversable.
for (auto index : cluster.second.turn_indices)
{
m_turns[index].is_turn_traversable = false;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is the main fix. Especially for linestrings, with flat end, there were many turns, completely closed, but still marked as traversable. This could cause the buffer fail (no or partial output)

{}
//! Number of spikes, where a segment goes to the cluster point
//! and leaves immediately in the opposite direction.
std::size_t spike_count{0};
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This (and related code) is also necessary, to have a way out from a cluster which is closed, but where still is a way in and out. This is also related to floating point issues - the part between the spike legs might be indetectable

// The turns are not part of the same cluster,
// or one is clustered and the other is not.
// This is not corresponding.
continue;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This was earlier not possible. But now that clusters are detected before, the start turn and its corresponding turn should be located on the same cluster.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We might be able to delete the corresponding_turn functions because of this.
Will check that, but if possible, it will be a different PR

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It cannot be deleted, but it might be simplified

return to_start && to_start_index ? 5
: to_start ? 4
: next_in_same_cluster ? 2
: 3
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The values just define the ordering. There is now 1 extra, lowest ordering: spike out

Copy link
Member

Choose a reason for hiding this comment

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

Is there a comment that explain this orderings?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

✅ the comment was a bit above, but I didn't update it. Thanks.
Comment is moved to function description, and a short comment here.

test_buffer("case3", "MULTILINESTRING((-18.00000000002045652536253328435122966766357421875 10.4999999997948929575386500800959765911102294921875,-2.99999999998012700785920969792641699314117431640625 10.4999999997948929575386500800959765911102294921875),(-2.99999999998012700785920969792641699314117431640625 10.4999999997948929575386500800959765911102294921875,18.00000000002045652536253328435122966766357421875 10.4999999997948947338954894803464412689208984375),(-2.99999999998012700785920969792641699314117431640625 10.4999999997948929575386500800959765911102294921875,11.99999999996175148453403380699455738067626953125 -10.49999999983214848953139153309166431427001953125))",
{6.0, 4.5, 1.5}, 429.831);
test_buffer("case4", "MULTILINESTRING((-18.00000000002045652536253328435122966766357421875 10.4999999997948929575386500800959765911102294921875,-2.99999999998012700785920969792641699314117431640625 10.4999999997948929575386500800959765911102294921875),(-2.99999999998012700785920969792641699314117431640625 10.4999999997948929575386500800959765911102294921875,18.00000000002045652536253328435122966766357421875 10.4999999997948947338954894803464412689208984375),(-2.99999999998012700785920969792641699314117431640625 10.4999999997948929575386500800959765911102294921875,17.99999999995061017443731543608009815216064453125 -4.5000000001943778471513724070973694324493408203125))",
{6.0, 4.5, 1.5}, 423.195);
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Cases 3 and 4 were failing before the fixes

@barendgehrels barendgehrels force-pushed the fix/buffer-linestring-turn-in-piece branch from 142d505 to a1e8572 Compare February 25, 2024 10:49
= detail::overlay::handle_colocations
bool has_colocations = false;

if (BOOST_GEOMETRY_CONDITION (! is_buffer))
Copy link
Member

Choose a reason for hiding this comment

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

BOOST_GEOMETRY_CONSTEXPR could be used instead.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sure, I'll change it

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

As soon as your PR is merged ;-)

Copy link
Member

Choose a reason for hiding this comment

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

Ok, but in case you wasn't aware, this macro is already in develop:
https://github.com/boostorg/geometry/blob/develop/include/boost/geometry/util/constexpr.hpp

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

👍 right! Will update on Wednesday

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

✅ this one is updated, it is a new block and has an else branch

@@ -357,7 +356,7 @@ inline bool handle_colocations(Turns& turns, Clusters& clusters,
{
std::cout << kv.first << std::endl;
for (auto const& toi : kv.second)
{
{
Copy link
Member

Choose a reason for hiding this comment

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

probably wrong indent

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Reverse1,
Reverse2,
OverlayType
>(clusters, turns, target_operation,
Copy link
Member

Choose a reason for hiding this comment

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

target_operation is known at compile-time. It could be passed as template parameter and then checked with if BOOST_GEOMETRY_CONSTEXPR inside gather_cluster_properties. But a different PR would probably be better for this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Will do it in another PR indeed. Not today.

@@ -475,7 +489,8 @@ inline void gather_cluster_properties(Clusters& clusters, Turns& turns,
turn_operation_type& op = turn.operations[ranked.operation_index];

if (set_startable
&& for_operation == operation_union && cinfo.open_count == 0)
&& for_operation == operation_union
Copy link
Member

Choose a reason for hiding this comment

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

Here is the condition for if constexpr. Or is it not always the case that for_operation is known at compile-time?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, it is known. I'll update.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I didn't update this one, and the ones below.
Because for_operation is passed as a normal parameter.
This needs more refactoring and it is better to separate that.

@@ -791,6 +794,24 @@ public :
return false;
}

if (is_union && cinfo.open_count == 0 && cinfo.spike_count > 0)
Copy link
Member

Choose a reason for hiding this comment

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

is_union is static const so I guess it can cause warnings.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

indeed, I'll update.
Thanks for your quick review.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Similarly here: not updated. Here it was not passed, but it is used in many places like this in this source file. And they should all be updated.
I guess, because of the combination of conditions, there are no warnings (not sure though). In other places it was combined as well, in this source.
So also this should go to another PR.

@awulkiew
Copy link
Member

Thanks for the PR and the detailed explanation of changes. :)

Copy link
Member

@vissarion vissarion left a comment

Choose a reason for hiding this comment

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

Thanks, LGTM in general.

return to_start && to_start_index ? 5
: to_start ? 4
: next_in_same_cluster ? 2
: 3
Copy link
Member

Choose a reason for hiding this comment

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

Is there a comment that explain this orderings?

<
polygon_t
>(mls,
std::back_inserter(result),
Copy link
Member

Choose a reason for hiding this comment

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

indentation issue here.

Copy link
Collaborator Author

@barendgehrels barendgehrels Feb 28, 2024

Choose a reason for hiding this comment

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

DistanceStrategy const& distance,
OutputRange &output_range) const
{
const auto result =
Copy link
Member

Choose a reason for hiding this comment

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

Maybe auto const which seems that is more common as a style in BG?
Also why not auto const&?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes it is. But on my office it's not, so I sometimes don't switch at the right moment...
Thanks.
BTW, in this case it should not be & because it's an assignment from a function result. (Though, technically, it's in line with C++ specs)

Copy link
Collaborator Author

@barendgehrels barendgehrels Feb 28, 2024

Choose a reason for hiding this comment

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

>(m_clusters, m_turns, detail::overlay::operation_union,
offsetted_rings, offsetted_rings, m_strategy);

for (const auto& cluster : m_clusters)
Copy link
Member

Choose a reason for hiding this comment

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

auto const&?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

if (cluster.second.open_count == 0 && cluster.second.spike_count == 0)
{
// If the cluster is completely closed, mark it as not traversable.
for (auto index : cluster.second.turn_indices)
Copy link
Member

Choose a reason for hiding this comment

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

what about auto const& here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Indeed. Will fix later today. Same for your similar comments, thanks.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

for (auto const& cluster : m_clusters)
{
bool is_traversable = false;
for (auto index : cluster.second.turn_indices)
Copy link
Member

Choose a reason for hiding this comment

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

similarly, what about using auto const& here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

}
if (is_traversable)
{
for (auto index : cluster.second.turn_indices)
Copy link
Member

Choose a reason for hiding this comment

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

same here

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@barendgehrels barendgehrels force-pushed the fix/buffer-linestring-turn-in-piece branch from a1e8572 to 5dae1a0 Compare February 28, 2024 16:20
@barendgehrels barendgehrels merged commit acaed28 into boostorg:develop Feb 28, 2024
23 checks passed
@barendgehrels barendgehrels deleted the fix/buffer-linestring-turn-in-piece branch February 28, 2024 16:34
@vissarion vissarion added this to the 1.85 milestone Apr 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants