multilinestrings: instead of computing the turns for each linestring
(through bg::intersects) and then again for the entire multilinestring,
avoid computing the turns for the individual linestrings in the multilinestring
and compute and process all multilinestring turns together;
besides the optimization this approach fixes a bug in bg::intersects in the
context of simplicity testing: bg::intersects cannot detect the intersection
occuring when a boundary point of linestring is also an internal point of the
linestring, as in LINESTRING(4 1,10 8,4 6,4 1,10 5,10 3), for example;
as a class (to match the friend declaration inside it);
fix bug in initialization of the m_has_less_than_two_elements boolean member variable
for open ranges;
was considering a simple closed linestring (living inside a multilinestring)
as non-simple because it was wrongly detecting the turn associated with the
first and last (closing) point as an unacceptable turn;
fix: allow such turns acceptable;
For last Linear segment collinear opposite to A segment the pk point was
also used in a check inside collinear_opposite handler. But in the case of
the last segment pk was invalid and set to one of the L points. So the
result of the check was "random".
Remove the symmetry from uncertain u/u handling. Set I/E and B/E only for
rings containing only u/u, not for both geometries.
Also replace int with signed_index_type for ring index.
Linestring/MultiPolygon case when the first IP is the u/u for a Polygon in
which the LS is not contained (starting inside). In such cases the
algorithm was detecting the LS in exterior of MultiPolygon.
MultiLinestring/Areal case when the last IP of the first Linestring was
u/u and previously the Linestring was inside. In such case the last
boundary endpoint was not taken into account.
the closing_iterator was not working for empty ranges as it was trying
to append the first range item of an empty range to the end of the range;
the proposed fix changes the index of the last item in the closing iterator's
range to be 0 instead of 1 when the range is empty;
For a case when a last segment of linear geometry was collinear-opposite
to areal's segment and had an endpoint inside the areal's segment the turn
for the first IP wasn't generated, only the one of the endpoint.
The exit_watcher state wasn't cleared for first_in_range and
m_interior_detected set, so e.g. if the first linestring was detected as
entering but not detected as exiting afterwards. Furthermore, for such
linestring the last boundary point wasn't checked and the result set
accordingly.
point (turn) w.r.t. a segment, where all segments are rescaled. This should
result in a trustable point-in-piece route and obsolete the near_offsetted
workaround.
Includes unit test
Without this, if the intersection of endpoints is checked using only the
ratios, the intersecting endpoints may not be detected as such. This is
important for floating-point coordinates/ratios.