Offseting a line

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Offseting a line

aaime
Administrator
Hi,
I'm looking for code that performs a unidirectional offset
of a line. The closest thing I've found is OffesetCurveBuilder,
but it builds a full buffer around the line, whilst I want it
just on one side (left side for a positive distance, rigth side
for a negative one).

Before I try to hack the OffsetCurveBuilder into doing what I need
(rounded corners are fine, thought not required), is there anything
already done and available around?

Cheers
Andrea

--
Andrea Aime
OpenGeo - http://opengeo.org
Expert service straight from the developers.
_______________________________________________
jts-devel mailing list
[hidden email]
http://lists.refractions.net/mailman/listinfo/jts-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Offseting a line

Jeff Adams-4
Are you talking about shifting the line to a new location (keeping it a line), or doing a half buffer (now you have a polygon)?

I wrote code to shift a line to the line's left or right, if that's what you're trying to do I can provide that.  I believe I posted my first solution to this forum, but I later discovered it was flawed and have a better (and much simpler) one now.

On Thu, Nov 13, 2008 at 6:11 AM, Andrea Aime <[hidden email]> wrote:
Hi,
I'm looking for code that performs a unidirectional offset
of a line. The closest thing I've found is OffesetCurveBuilder,
but it builds a full buffer around the line, whilst I want it
just on one side (left side for a positive distance, rigth side
for a negative one).

Before I try to hack the OffsetCurveBuilder into doing what I need
(rounded corners are fine, thought not required), is there anything
already done and available around?

Cheers
Andrea

--
Andrea Aime
OpenGeo - http://opengeo.org
Expert service straight from the developers.
_______________________________________________
jts-devel mailing list
[hidden email]
http://lists.refractions.net/mailman/listinfo/jts-devel


_______________________________________________
jts-devel mailing list
[hidden email]
http://lists.refractions.net/mailman/listinfo/jts-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Offseting a line

aaime
Administrator
Jeff Adams ha scritto:
> Are you talking about shifting the line to a new location (keeping it a
> line), or doing a half buffer (now you have a polygon)?
>
> I wrote code to shift a line to the line's left or right, if that's what
> you're trying to do I can provide that.  I believe I posted my first
> solution to this forum, but I later discovered it was flawed and have a
> better (and much simpler) one now.

Just shift a linestring, but the whole linestring, not just a segment.
Whether shifting produces rounded corners or not, that's not relevant
to me, provided the shifted result is connected.

So if you have some code, I would be very glad to take it :)
Oh, it would eventually end up in GeoTools (or JTS if Martin wants).

Cheers
Andrea

--
Andrea Aime
OpenGeo - http://opengeo.org
Expert service straight from the developers.
_______________________________________________
jts-devel mailing list
[hidden email]
http://lists.refractions.net/mailman/listinfo/jts-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Offseting a line

Jeff Adams-4
I have a feeling I'm not understanding you exactly, since in my case there are no generated corners?  I just move all the points in the line by a given x/y amount.  Here's my code (sorry it's csharp, I'm using NTS):

        /// <summary>
        /// Moves a line the given distance to either the "left" or
        /// "right" of the line.  The average angle of the line is calculated
        /// via the endpoints and "left" and "right" are 90 degrees to either direction.
        /// </summary>
        /// <param name="input">The line to shift.</param>
        /// <param name="toTheRight">If true, move to the right.
        ///                          If false, move to the left.</param>
        /// <param name="distance">How far to shift the line.</param>
        /// <returns>A new line, identical to the input except all points in it are
        ///          moved to the left or right.</returns>
        public static ILineString ShiftLine(ILineString input, bool toTheRight,
            double distance)
        {
            if (input.NumPoints < 2)
            {
                throw new ArgumentException("Cannot shift a line with less than two points: " + input);
            }
            IPoint point0 = input.StartPoint;
            IPoint point1 = input.EndPoint;
            // Calculate the angle of the line.
            double avgAngle = Math.Atan2(point1.Y - point0.Y, point1.X - point0.X);
            // Now turn to the right or left.
            if (toTheRight)
            {
                avgAngle -= Math.PI / 2;
            }
            else
            {
                avgAngle += Math.PI / 2;
            }
            // Now convert back to an x/y offset.
            double yOffset = Math.Sin(avgAngle) * distance;
            double xOffset = Math.Cos(avgAngle) * distance;
            ICoordinate[] shiftedCoords = new ICoordinate[input.NumPoints];
            for (int i = 0; i < shiftedCoords.Length; i++)
            {
                IPoint p = input.GetPointN(i);
                shiftedCoords[i] = new Coordinate(p.X + xOffset, p.Y + yOffset);
            }
            return new LineString(shiftedCoords);
        }
 
As you can see I took a pretty simple approach.  I'm shifting street centerlines, I'm not sure the behavior will necessarily be what you want if you are dealing with very non-straight lines.  However this actually produces better results than my original, more complicated, logic where I tried to take the angle of every segment separately and compute a real "average" direction based on how long each segment was relative to the others.  In one way of looking at it, the start point and end point are the average slope, assuming you're using reasonably square units (Oh yeah, I doubt this will work well if you're drawing lines from Austrailia to Greenland).

Jeff


On Thu, Nov 13, 2008 at 9:09 AM, Andrea Aime <[hidden email]> wrote:
Jeff Adams ha scritto:

Are you talking about shifting the line to a new location (keeping it a line), or doing a half buffer (now you have a polygon)?

I wrote code to shift a line to the line's left or right, if that's what you're trying to do I can provide that.  I believe I posted my first solution to this forum, but I later discovered it was flawed and have a better (and much simpler) one now.

Just shift a linestring, but the whole linestring, not just a segment.
Whether shifting produces rounded corners or not, that's not relevant
to me, provided the shifted result is connected.

So if you have some code, I would be very glad to take it :)
Oh, it would eventually end up in GeoTools (or JTS if Martin wants).


Cheers
Andrea

--
Andrea Aime
OpenGeo - http://opengeo.org
Expert service straight from the developers.
_______________________________________________
jts-devel mailing list
[hidden email]
http://lists.refractions.net/mailman/listinfo/jts-devel


_______________________________________________
jts-devel mailing list
[hidden email]
http://lists.refractions.net/mailman/listinfo/jts-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Offseting a line

Martin Davis
In reply to this post by aaime
There's nothing in JTS which does exactly this right now (although as
you point out OffsetCurveBuilder provides the basis for something).  The
tricky part is removing all the "closing lines" which OCB adds, and also
deciding how to handle situations where the offset curve self-intersects
(I think an appropriate strategy is to follow the "outside" of the curve).

Stephen Wong from Safe added an enhancement to GEOS to provide this - it
would be worth looking at this to see how to back-port it.  I will try
and get to this, but if someone else wants to take this on that would be
great.

Martin

Andrea Aime wrote:

> Hi,
> I'm looking for code that performs a unidirectional offset
> of a line. The closest thing I've found is OffesetCurveBuilder,
> but it builds a full buffer around the line, whilst I want it
> just on one side (left side for a positive distance, rigth side
> for a negative one).
>
> Before I try to hack the OffsetCurveBuilder into doing what I need
> (rounded corners are fine, thought not required), is there anything
> already done and available around?
>
> Cheers
> Andrea
>

--
Martin Davis
Senior Technical Architect
Refractions Research, Inc.
(250) 383-3022

_______________________________________________
jts-devel mailing list
[hidden email]
http://lists.refractions.net/mailman/listinfo/jts-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Offseting a line

aaime
Administrator
Martin Davis ha scritto:

> There's nothing in JTS which does exactly this right now (although as
> you point out OffsetCurveBuilder provides the basis for something).  The
> tricky part is removing all the "closing lines" which OCB adds, and also
> deciding how to handle situations where the offset curve self-intersects
> (I think an appropriate strategy is to follow the "outside" of the curve).
>
> Stephen Wong from Safe added an enhancement to GEOS to provide this - it
> would be worth looking at this to see how to back-port it.  I will try
> and get to this, but if someone else wants to take this on that would be
> great.

It took me a while to find it but yeas, here it is:
http://trac.osgeo.org/geos/ticket/215

Ugh, the patch looks big, and I guess I only need a very small
part of it... I'll see whether I can contribute back a java
patch for JTS or not.

But looking at the pictures here:
http://trac.osgeo.org/geos/attachment/ticket/215/singlesidedbuffer.jpg
it fits what I need _exactly_ :)
This is great!

Cheers
Andrea

--
Andrea Aime
OpenGeo - http://opengeo.org
Expert service straight from the developers.
_______________________________________________
jts-devel mailing list
[hidden email]
http://lists.refractions.net/mailman/listinfo/jts-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Offseting a line

Martin Davis
Sounds good, Andrea.  I don't think the patch looks all that big - and
the port across should be pretty easy, I think.  If you get stuck send
me the code you wind up with and I'll try and take it from there.

Martin

Andrea Aime wrote:

> Martin Davis ha scritto:
>> There's nothing in JTS which does exactly this right now (although as
>> you point out OffsetCurveBuilder provides the basis for something).  
>> The tricky part is removing all the "closing lines" which OCB adds,
>> and also deciding how to handle situations where the offset curve
>> self-intersects (I think an appropriate strategy is to follow the
>> "outside" of the curve).
>>
>> Stephen Wong from Safe added an enhancement to GEOS to provide this -
>> it would be worth looking at this to see how to back-port it.  I will
>> try and get to this, but if someone else wants to take this on that
>> would be great.
>
> It took me a while to find it but yeas, here it is:
> http://trac.osgeo.org/geos/ticket/215
>
> Ugh, the patch looks big, and I guess I only need a very small
> part of it... I'll see whether I can contribute back a java
> patch for JTS or not.
>
> But looking at the pictures here:
> http://trac.osgeo.org/geos/attachment/ticket/215/singlesidedbuffer.jpg
> it fits what I need _exactly_ :)
> This is great!
>
> Cheers
> Andrea
>

--
Martin Davis
Senior Technical Architect
Refractions Research, Inc.
(250) 383-3022

_______________________________________________
jts-devel mailing list
[hidden email]
http://lists.refractions.net/mailman/listinfo/jts-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Quadtree results?

Jones, Patrick L.
Howdy,

        Does the list that a query(Envelope searchEnv) on a Quadtree returns always have the returned items in the same order?  I have two overlapping Envelopes which I have inserted into Quadtree. If I do a query on the Quadtree where the searchEnv is in the overlapping area will the result list always have the envelopes in the same order?



Coordinate c1 = new Coordinate(0.0,0.0);
Coordinate c2 = new Coordinate(2.0,2.0);
Coordinate c3 = new Coordinate(1.0,0.0);
Coordinate c4 = new Coordinate(3.0,2.0);


// e1 overlaps e2
Envelope e1 = new Envelope(c1,c2);
Envelope e2 = new Envelope(c3,c4);

Coordinate pt = new Coordinate(1.5,1.0); // a pt in both e1 and e2
Envelope inner = new Envelope(pt);

Quadtree qtree = new Quadtree();
       
 qtree.insert(e1,c1);
 qtree.insert(e2,c2);
 
 List list = qtree.query(inner);  // will list always have c1 and c2 in the same order?

Thanx,

Pat

_______________________________________________
jts-devel mailing list
[hidden email]
http://lists.refractions.net/mailman/listinfo/jts-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Quadtree results?

Martin Davis
I'll say no, just to be safe.  This certainly isn't in the contract of
Quadtree (and I don't think it's a desirable constraint to have to
meet).  It may currently have that behaviour, but if so that's just a
happy coincidence.



Jones, Patrick L. wrote:

> Howdy,
>
> Does the list that a query(Envelope searchEnv) on a Quadtree returns always have the returned items in the same order?  I have two overlapping Envelopes which I have inserted into Quadtree. If I do a query on the Quadtree where the searchEnv is in the overlapping area will the result list always have the envelopes in the same order?
>
>
>
> Coordinate c1 = new Coordinate(0.0,0.0);
> Coordinate c2 = new Coordinate(2.0,2.0);
> Coordinate c3 = new Coordinate(1.0,0.0);
> Coordinate c4 = new Coordinate(3.0,2.0);
>
>
> // e1 overlaps e2
> Envelope e1 = new Envelope(c1,c2);
> Envelope e2 = new Envelope(c3,c4);
>
> Coordinate pt = new Coordinate(1.5,1.0); // a pt in both e1 and e2
> Envelope inner = new Envelope(pt);
>
> Quadtree qtree = new Quadtree();
>
>  qtree.insert(e1,c1);
>  qtree.insert(e2,c2);
>  
>  List list = qtree.query(inner);  // will list always have c1 and c2 in the same order?
>
> Thanx,
>
> Pat
>
> _______________________________________________
> jts-devel mailing list
> [hidden email]
> http://lists.refractions.net/mailman/listinfo/jts-devel
>
>  

--
Martin Davis
Senior Technical Architect
Refractions Research, Inc.
(250) 383-3022

_______________________________________________
jts-devel mailing list
[hidden email]
http://lists.refractions.net/mailman/listinfo/jts-devel
Loading...