Martin,
For my case (near enough right angled corners) it works quite well.
Performance isn't too much of an issue as it only gets run a few times
and comparing that with downloading extra data from the DB it's negligible.
I just knocked together some code below to test it out, feel free to use
any of this, there are a bunch of utility methods and a class to visit
each segment of the line strings.
Paul
public static Polygon getMitredBuffer(final Polygon polygon,
final double distance) {
Geometry buffer = polygon;
LineString exteriorRing = polygon.getExteriorRing();
Geometry exteriorBuffer = getMitredBuffer(exteriorRing, distance);
buffer = buffer.union(exteriorBuffer);
for (int i = 0; i < polygon.getNumInteriorRing(); i++) {
LineString ring = polygon.getInteriorRingN(i);
Geometry bufferedRing = getMitredBuffer(ring, distance);
buffer = buffer.union(bufferedRing);
}
return (Polygon)buffer;
}
public static Polygon getMitredBuffer(final LineString lineString,
final double distance) {
LineStringMitredBuffer visitor = new LineStringMitredBuffer(distance);
visitLineSegments(lineString.getCoordinateSequence(), visitor);
return visitor.getBuffer();
}
public static Polygon getMitredBuffer(final LineSegment segment,
final double distance) {
double angle = segment.angle();
LineSegment extendedSegment = addLength(segment, distance, distance);
LineSegment clockwiseSegment = offset(extendedSegment, distance,
Angle.CLOCKWISE);
LineSegment counterClockwiseSegment = offset(extendedSegment, distance,
Angle.COUNTERCLOCKWISE);
Coordinate[] coords = new Coordinate[] {
clockwiseSegment.p0, clockwiseSegment.p1, counterClockwiseSegment.p1,
counterClockwiseSegment.p0, clockwiseSegment.p0
};
GeometryFactory factory = new GeometryFactory();
LinearRing exteriorRing = factory.createLinearRing(coords);
return factory.createPolygon(exteriorRing, null);
}
public static LineSegment offset(final LineSegment line,
final double distance, final int orientation) {
double angle = line.angle();
if (orientation == Angle.CLOCKWISE) {
angle -= Angle.PI_OVER_2;
} else {
angle += Angle.PI_OVER_2;
}
Coordinate c1 = offset(line.p0, angle, distance);
Coordinate c2 = offset(line.p1, angle, distance);
return new LineSegment(c1, c2);
}
public static Coordinate offset(final Coordinate coordinate,
final double angle, final double distance) {
double newX = coordinate.x + distance * Math.cos(angle);
double newY = coordinate.y + distance * Math.sin(angle);
Coordinate newCoordinate = new Coordinate(newX, newY);
return newCoordinate;
}
public static LineSegment addLength(final LineSegment line,
final double startDistance, final double endDistance) {
double angle = line.angle();
Coordinate c1 = offset(line.p0, angle, -startDistance);
Coordinate c2 = offset(line.p1, angle, endDistance);
return new LineSegment(c1, c2);
}
public static void visitLineSegments(final CoordinateSequence coords,
final LineSegmentVistor visitor) {
Coordinate previousCoordinate = coords.getCoordinate(0);
for (int i = 1; i < coords.size(); i++) {
Coordinate coordinate = coords.getCoordinate(i);
LineSegment segment = new LineSegment(previousCoordinate, coordinate);
if (segment.getLength() > 0) {
if (!visitor.visit(segment)) {
return;
}
}
previousCoordinate = coordinate;
}
}
public class LineStringMitredBuffer implements LineSegmentVistor {
private Polygon buffer;
private double distance;
public LineStringMitredBuffer(double distance) {
this.distance = distance;
}
public boolean visit(LineSegment segment) {
Polygon segmentBuffer = JtsGeometryUtil.getMitredBuffer(segment, distance);
if (buffer == null) {
buffer = segmentBuffer;
} else {
buffer = (Polygon)buffer.union(segmentBuffer);
}
return true;
}
/**
* @return the buffer
*/
public Polygon getBuffer() {
return buffer;
}
}
Martin Davis wrote:
> Paul,
>
> Actually on second thought this might not give you what you want. The
> problem will be when you union two line segments which aren't at right
> angles to each other - the square ends won't match up smoothly.
>
> I'd try it manually in JUMP first, anyway, just to see what's going to
> happen.
>
> I'm going to try and look at how easy this would be to add to the code
> base - it shouldn't be too hard to implement.
>
> Paul Austin wrote:
_______________________________________________
jts-devel mailing list
[email protected]
http://lists.refractions.net/mailman/listinfo/jts-devel