Boost logo

Geometry :

Subject: [ggl] Understanding get_turns for linestring/polygon overlay
From: barend (barend.gehrels)
Date: 2011-02-01 17:00:10

Hi John,

-----Original Message-----
From: John Swensen <jpswensen_at_[hidden]>
To: Generic Geometry Library Discussion <ggl_at_[hidden]>
Date: Tue, 1 Feb 2011 15:06:26 -0500
Subject: Re: [ggl] Understanding get_turns for linestring/polygon overlay

On Feb 1, 2011, at 11:57 AM, Barend Gehrels wrote:

> Hi John,
> Welcome to the list!
> On 1-2-2011 16:25, John Swensen wrote:
>> I apologize if this email seems rudimentary. I am just getting into both
Boost and Boost.Geometry. From the mailing list, I have gleaned that
LineString/Polygon boolean operations are not implemented yet.
> That is right.
>> So, I am trying to implement it myself from some of the examples. I am
able to successfully create a polygon and a linestring and follow the
overlay example to get the list of turn points describing where they
intersect. However, I would like to take the list of turn points and create
two new polygons from that are divided by the turn points.
> So basically you are wishing a "cut operation", cut the polygon into
pieces. Very interesting.
>> So my questions are:
>> 1) Is there a way to insert the turn point into the outer ring easily?
> Yes, relatively easy. For each turn point you know the coordinate
(.point), and at which segment it intersects the polygon
(operations[0].seg_id). It must be able to insert a point there, though this
is not a Boost.Geometry standard way. Assuming you use the Boost.Geometry
polygon, you take the ring (if the ring_id is -1 it is the outer ring), and
using std:: you insert that point there.
>> 2) Is there a way to find the line segments of the outer ring that are
divided by the turn points?
> Yes, this is related and actually answered above.
> The basic case might be relatively easy to solve. However, as soon as
intersection points overlay on the vertices of the input polygons, it
becomes more complicated (or you can simply ignore those duplications). The
sample shows "entering" and "leaving", but as soon as the linestring touches
the polygon and does not intersect, it also becomes more complex. But not
>> If either of these are easy to find, then splitting my polygon into two
polygons should be straightforward. I'm just not sure if there is a "right"
way to do this. I could always go back and walk my way around the outer
ring doing the computation to see of the turn point lies on the line segment
and then splitting accordingly, but want to know if this is already
implemented and I just can't find it.
> No, it is not implemented, and you have the right approach. In case you
succeed and want to contribute this, I'm interested in the results.
> Regards, Barend

Thanks for pointing me in the right direction, however I think there is
something wrong with how I am trying it. When I add the following debug
output to my application, I don't get what I expected.

BOOST_FOREACH(turn_info const& turn, turns)
   std::cout << action << " polygon at " << boost::geometry::dsv(turn.point)
 << std::endl;
        std::cout << action << " polygon at " <<
boost::geometry::dsv(turn.point) << "with seg_id: " <<
turn.operations[0].seg_id.segment_index << std::endl;
      std::cout << "================" <<
turn.operations[0].seg_id.source_index << " " <<
turn.operations[0].seg_id.multi_index << " " <<
turn.operations[0].seg_id.ring_index << " " <<
turn.operations[0].seg_id.segment_index << std::endl;

I would have expected to see the ring_index be (-1), but I didn't expect for
the segment_index to be (0) for both turns. Just to give some background, I
have created the following simple triangle polygon
OriginalPolygon: (((100, 100), (200, 200), (200, 100)))

I then got the turns from a line that crossed it:
entering polygon at (168.749, 168.749)
================0 -1 -1 0
leaving polygon at (200, 151.114)
================0 -1 -1 0

I would have expected the segments to be numbered clockwise also and that
the "entering polygon" turn would be in segment 0 and the "leaving polygon
turn" would be in segment 1.
Source 0 is the first geometry and source 1 is the second geometry. So if
you follow the sample, source 0 is the linestring, source 1 is the polygon.
So I probably pointed you a bit wrong, by my remark operation[0].seg_id, it
should have been operation[1].seg_id for the polygon.

If I repeat your comments into the origional sample, and replace [0] by [1],
I get the right information:

Intersection of linestring/polygon
entering polygon at (0.666667, 2.33333)with seg_id: 0
================1 -1 -1 0
leaving polygon at (1.33333, 3.66667)with seg_id: 1
================1 -1 -1 1
entering polygon at (2.85714, 4.42857)with seg_id: 1
================1 -1 -1 1
leaving polygon at (3.76471, 3.82353)with seg_id: 2
================1 -1 -1 2

Where the segment_id's seem all right to me.

Regards, Barend

-------------- next part --------------
An HTML attachment was scrubbed...

Geometry list run by mateusz at