-
Notifications
You must be signed in to change notification settings - Fork 214
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
Missing input combinations in intersection() and introduction of tupled-output. #650
Conversation
Remove unused metafunctions.
… L/L. In such case the algorithm expects a pair of tuple containing at least range of points and range of linestrings. Linear and PointLike parts of the output are returned separately.
7e03012
to
e6b1f6e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am in general ok with this interface. The only drawback I see is that the user has to know the types of the geometries for the output tuple which is different for each pair of input geometry types. However, if this intended for advanced users maybe it's ok since there is also the simple interface.
@vissarion It would be possible to always pass all of them and the algorithm will pick the right ones. The assertion in the |
Interesting PR - I wanted to check it today, but have to postpone it again a bit. Will look soon. Thanks. |
… in tuple-related code.
I'm going to add support for all missing combinations in |
…(L/A). Remove OLD_LA_BEHAVIOR code as it is disabled by default, not tested and makes the implementation more complex.
3a7c046
to
d8c8078
Compare
d8c8078
to
07abb6a
Compare
@vissarion @barendgehrels Ok, I think the PR is ready for review. I don't plan to add anything more for now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this PR. I am ok with merging.
} | ||
}; | ||
|
||
// TODO: Ideally this should be done in one call of intersection_insert |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is missing for this? Is more work on intersection_insert
needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This implementation for Areal/Areal calls intersection_insert
for other combinations several times. This means that partition is called and then turns are analysed several times. However, overlay stuff called by the old/basic Areal/Areal implementation (when the output is MultiPolygon instead of tuple) has all of the information needed to generate the result in one call, so to generate Areal + Linear + PointLike output.
I decided to not modify it mainly because it could interfere with @barendgehrels work on rescaling. The code is also more complex than in case of Linear geometries, with enriching turns, storing states in turns and visitors which are not clear to me. So I'd prefer to leave it to @barendgehrels or do it when he's done with rescaling. Maybe rewrite it, maybe for C++11/14, etc. In short, it was simpler this way.
@barendgehrels what do you think about it? |
@barendgehrels the release is comming. Master branch will be closed on Apr 1 for major changes like this one. What should I do with this PR? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@barendgehrels the release is comming. Master branch will be closed on Apr 1 for major changes like this one. What should I do with this PR?
Thanks for the heads up, sorry for the delay.
It looks very good in general! I did not dive into all the details, but I'm OK with merging it, if you're confident that it is all fine.
>::type | ||
>::type | ||
> | ||
struct intersection_areal_areal_ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why the trailing _
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because below the name intersection_areal_areal
was already used. The original one. And I needed to distinguish between the original behavior and the handling of Tuples. Would you prefer a different name?
>::type pointlike_out_type; | ||
|
||
// NOTE: The same robust_policy is used in each call of | ||
// intersection_insert. Is that correct? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, and hopefully we will get rid of it...
@barendgehrels Ok, thanks! |
In this PR I add implementation for missing input combinations of
intersection
(1) and enhance the existing interface allowing to pass multiple output geometries at once (2). An alternative adding more output arguments to intersection would also be possible (3).There are also some issues with intersection which I'd prefer not to address in this PR (4).
1. Missing input combinations
Added implementation for:
2. Enhanced tupled-output interface
Added implementation for:
Actually what is required are Ranges of Points, Linestrings or Polygons.
2.1. The problem
Consider two linestrings:
The result of the intersection is a linestring and a point:
The function however is able to only take a range of linestrings (or multi-linestring) as output geometry. So the result of the operation for the data above is:
with the point represented as degenerated linestring. This forces the user to either ignore it and potentially get wrong results from other operations after passing this multi-linestring or to traverse the result and filter-out the degenerated linestrings.
It's more complex than that because for different combinations of input geometries different results are generated. E.g. for Linear ∩ Areal -> Linear the points are ignored, so not even represented as degenerated lineatrings. Furthermore for Linear ∩ Areal -> PointLike the result contains all intersection points. So without 2 separate calls and further analysis of the outputs it is impossible to calcualte the correct result of the intersection of Linear ∩ Areal.
2.2. The solution
Allow the user to optionally pass a collection of output geometries. I decided to allow
std::pair
andstd::tuple
(the latter conditionally) because they are the standard andboost::tuple
because we already depend on it and at least for now still support C++03. This is how the code looks like:2.3. The implementation
Internally we pass single-geometry extracted from multi-geometry as template argument and output iterator of multi-geometry into
intersection_insert
algorithm which then appends the resulting single-geometries to the output using the output iterator and returns this iterator. So it more or less follows the interface of STL algorithms. I decided to not change that (at least for now*). So what is done in theintersection
is:back_insert_iterator
s is created from tuple of ranges/multi-geometriesintersection_insert
GeometryOut
as linestring) or the optional behavior (GeometryOut
as tuple) and uses the types and objects accordingly.* In general I think it would be good to simplify and redesign set operations slightly. The interfaces could be made more clear (e.g. the behavior not changing based on output). I'd deprecate some of the combinations which doesn't make sense or at least moved to a separate algorithm. Like returning the intersection points, unless I'm missing what's their purpose. Going through
intersection_insert
from all operations is also confusing. Different operations can have different outputs even for the same input (e.g. difference of linear geometries can not generate points but the intersection can). Internally they callintersection_insert
with the same interface for both. But redesigning set operations is not the intention of this PR.3. Enhanced interface taking more arguments.
An alternative to (2) could be the interface taking more than one output geometry. For example if the input was two polygons the user would be forced to pass three ranges for pointlike, linear and areal portions of the output (plus optional strategy). E.g.:
I'm not sure whether or not it's more clear because we also need to pass optional strategy so all of these arguments would be optional which may be not clear for the user.
4. The issues
For various combinations unnecessary points can be returned. These are points that are intersecting other portions of the output and can be generated e.g. for touching exterior and interior rings or linear rings touching at the endpoints. This is the old behavior of the intersection and I didn't change that. In order to address this issue we'd have to modify L/L and P/L implementation to check the resulting points whether or not they should really be returned. But this is the existing behavior which I don't want to change in this PR.