| | |
| | | import com.vividsolutions.jts.geom.Point; |
| | | import com.vividsolutions.jts.geom.Polygon; |
| | | import com.vividsolutions.jts.geom.impl.PackedCoordinateSequence; |
| | | import org.geotools.geometry.jts.JTSFactoryFinder; |
| | | |
| | | public class JTSShape implements Shape |
| | | { |
| | | static GeometryFactory fac = new GeometryFactory(); |
| | | public class JTSShape implements Shape { |
| | | static GeometryFactory fac = JTSFactoryFinder.getGeometryFactory(null); |
| | | |
| | | Geometry geom; |
| | | |
| | | final static LinearRing[] NOSHELLS = {}; |
| | | |
| | | public JTSShape(Geometry _geom) |
| | | { |
| | | public JTSShape(Geometry _geom) { |
| | | this.geom = _geom; |
| | | } |
| | | |
| | | public JTSShape(JtsGeometry _geom) |
| | | { |
| | | public JTSShape(JtsGeometry _geom) { |
| | | this(_geom.getGeometry()); |
| | | } |
| | | |
| | | public boolean contains(Point2D p) |
| | | { |
| | | public boolean contains(Point2D p) { |
| | | return contains(p.getX(), p.getY()); |
| | | } |
| | | |
| | | public boolean contains(double x, double y) |
| | | { |
| | | public boolean contains(double x, double y) { |
| | | Coordinate c = new Coordinate(x, y); |
| | | Point p = fac.createPoint(c); |
| | | return geom.contains(p); |
| | | } |
| | | |
| | | public boolean contains(Rectangle2D r) |
| | | { |
| | | public boolean contains(Rectangle2D r) { |
| | | return contains(r.getMinX(), r.getMinY(), r.getWidth(), r.getHeight()); |
| | | } |
| | | |
| | | public boolean contains(double x, double y, double w, double h) |
| | | { |
| | | public boolean contains(double x, double y, double w, double h) { |
| | | Polygon p = createRect(x, y, w, h); |
| | | return geom.contains(p); |
| | | } |
| | | |
| | | protected Polygon createRect(double x, double y, double w, double h) |
| | | { |
| | | protected Polygon createRect(double x, double y, double w, double h) { |
| | | double[] arr = {x, y, x + w, y, x + w, y + h, x, y + h, x, y}; |
| | | PackedCoordinateSequence shell = new PackedCoordinateSequence.Double(arr, 2); |
| | | Polygon p = fac.createPolygon(fac.createLinearRing(shell), NOSHELLS); |
| | | return p; |
| | | } |
| | | |
| | | public Rectangle2D getBounds2D() |
| | | { |
| | | public Rectangle2D getBounds2D() { |
| | | Envelope env = geom.getEnvelopeInternal(); |
| | | return new Rectangle2D.Double(env.getMinX(), env.getMaxX(), env.getWidth(), env.getHeight()); |
| | | } |
| | | |
| | | public Rectangle getBounds() |
| | | { |
| | | public Rectangle getBounds() { |
| | | // We deal simple code for efficiency here, the getBounds() rounding |
| | | // rules are ugly... |
| | | return getBounds2D().getBounds(); |
| | | } |
| | | |
| | | public PathIterator getPathIterator(AffineTransform at) |
| | | { |
| | | public PathIterator getPathIterator(AffineTransform at) { |
| | | return getPathIterator(geom, at); |
| | | } |
| | | |
| | | public PathIterator getPathIterator(AffineTransform at, double flatness) |
| | | { |
| | | public PathIterator getPathIterator(AffineTransform at, double flatness) { |
| | | // we don't have much work here, as we only have linear segments, no |
| | | // "flattening" necessary. |
| | | return getPathIterator(at); |
| | | } |
| | | |
| | | public boolean intersects(Rectangle2D r) |
| | | { |
| | | public boolean intersects(Rectangle2D r) { |
| | | return intersects(r.getMinX(), r.getMinY(), r.getWidth(), r.getHeight()); |
| | | } |
| | | |
| | | public boolean intersects(double x, double y, double w, double h) |
| | | { |
| | | public boolean intersects(double x, double y, double w, double h) { |
| | | Polygon p = createRect(x, y, w, h); |
| | | return geom.intersects(p); |
| | | } |
| | | |
| | | public static GeometryPathIterator getPathIterator(Geometry geometry, AffineTransform _at) |
| | | { |
| | | if (geometry instanceof Point) |
| | | { |
| | | public static GeometryPathIterator getPathIterator(Geometry geometry, AffineTransform _at) { |
| | | if (geometry instanceof Point) { |
| | | return new PointPathIterator((Point) geometry, _at); |
| | | } else if (geometry instanceof LineString) |
| | | { |
| | | } else if (geometry instanceof LineString) { |
| | | return new LineStringPathIterator((LineString) geometry, _at); |
| | | } else if (geometry instanceof Polygon) |
| | | { |
| | | } else if (geometry instanceof Polygon) { |
| | | return new PolygonPathIterator((Polygon) geometry, _at); |
| | | } else |
| | | { |
| | | } else { |
| | | return new GeometryCollectionPathIterator((GeometryCollection) geometry, _at); |
| | | } |
| | | } |
| | | |
| | | public static abstract class GeometryPathIterator implements PathIterator |
| | | { |
| | | public static abstract class GeometryPathIterator implements PathIterator { |
| | | |
| | | protected final AffineTransform at; |
| | | protected int index = 0; |
| | | |
| | | GeometryPathIterator(AffineTransform _at) |
| | | { |
| | | GeometryPathIterator(AffineTransform _at) { |
| | | this.at = _at; |
| | | } |
| | | |
| | | public final int getWindingRule() |
| | | { |
| | | public final int getWindingRule() { |
| | | return PathIterator.WIND_EVEN_ODD; |
| | | } |
| | | |
| | | public void next() |
| | | { |
| | | public void next() { |
| | | index++; |
| | | } |
| | | } |
| | | |
| | | public static class PointPathIterator extends GeometryPathIterator |
| | | { |
| | | public static class PointPathIterator extends GeometryPathIterator { |
| | | final Point p; |
| | | |
| | | public PointPathIterator(Point _p, AffineTransform _at) |
| | | { |
| | | public PointPathIterator(Point _p, AffineTransform _at) { |
| | | super(_at); |
| | | p = _p; |
| | | } |
| | | |
| | | public int currentSegment(float[] coords) |
| | | { |
| | | switch (index) |
| | | { |
| | | public int currentSegment(float[] coords) { |
| | | switch (index) { |
| | | case 0: |
| | | coords[0] = (float) p.getX(); |
| | | coords[1] = (float) p.getY(); |
| | |
| | | } |
| | | } |
| | | |
| | | public int currentSegment(double[] coords) |
| | | { |
| | | switch (index) |
| | | { |
| | | public int currentSegment(double[] coords) { |
| | | switch (index) { |
| | | case 0: |
| | | coords[0] = p.getX(); |
| | | coords[1] = p.getY(); |
| | |
| | | } |
| | | } |
| | | |
| | | public boolean isDone() |
| | | { |
| | | public boolean isDone() { |
| | | return index > 1; |
| | | } |
| | | } |
| | | |
| | | public static class LineStringPathIterator extends GeometryPathIterator |
| | | { |
| | | public static class LineStringPathIterator extends GeometryPathIterator { |
| | | CoordinateSequence cs; |
| | | |
| | | final boolean isRing; |
| | | |
| | | public LineStringPathIterator(LineString ls, AffineTransform _at) |
| | | { |
| | | public LineStringPathIterator(LineString ls, AffineTransform _at) { |
| | | super(_at); |
| | | cs = ls.getCoordinateSequence(); |
| | | isRing = ls instanceof LinearRing; |
| | |
| | | /** |
| | | * only to be called from PolygonPathIterator subclass |
| | | */ |
| | | protected void reInit(CoordinateSequence _cs) |
| | | { |
| | | protected void reInit(CoordinateSequence _cs) { |
| | | cs = _cs; |
| | | index = 0; |
| | | } |
| | | |
| | | public int currentSegment(float[] coords) |
| | | { |
| | | if (index == 0) |
| | | { |
| | | public int currentSegment(float[] coords) { |
| | | if (index == 0) { |
| | | coords[0] = (float) cs.getOrdinate(index, 0); |
| | | coords[1] = (float) cs.getOrdinate(index, 1); |
| | | at.transform(coords, 0, coords, 0, 1); |
| | | return PathIterator.SEG_MOVETO; |
| | | } else if (index < cs.size()) |
| | | { |
| | | } else if (index < cs.size()) { |
| | | coords[0] = (float) cs.getOrdinate(index, 0); |
| | | coords[1] = (float) cs.getOrdinate(index, 1); |
| | | at.transform(coords, 0, coords, 0, 1); |
| | | return PathIterator.SEG_LINETO; |
| | | } else if (isRing && index == cs.size()) |
| | | { |
| | | } else if (isRing && index == cs.size()) { |
| | | return PathIterator.SEG_CLOSE; |
| | | } else |
| | | { |
| | | } else { |
| | | throw new IllegalStateException(); |
| | | } |
| | | } |
| | | |
| | | public int currentSegment(double[] coords) |
| | | { |
| | | if (index == 0) |
| | | { |
| | | public int currentSegment(double[] coords) { |
| | | if (index == 0) { |
| | | coords[0] = cs.getOrdinate(index, 0); |
| | | coords[1] = cs.getOrdinate(index, 1); |
| | | at.transform(coords, 0, coords, 0, 1); |
| | | return PathIterator.SEG_MOVETO; |
| | | } else if (index < cs.size()) |
| | | { |
| | | } else if (index < cs.size()) { |
| | | coords[0] = cs.getOrdinate(index, 0); |
| | | coords[1] = cs.getOrdinate(index, 1); |
| | | at.transform(coords, 0, coords, 0, 1); |
| | | return PathIterator.SEG_LINETO; |
| | | } else if (isRing && index == cs.size()) |
| | | { |
| | | } else if (isRing && index == cs.size()) { |
| | | return PathIterator.SEG_CLOSE; |
| | | } else |
| | | { |
| | | } else { |
| | | throw new IllegalStateException(); |
| | | } |
| | | } |
| | | |
| | | public boolean isDone() |
| | | { |
| | | public boolean isDone() { |
| | | return isRing ? index > cs.size() : index >= cs.size(); |
| | | } |
| | | } |
| | | |
| | | public static class PolygonPathIterator extends LineStringPathIterator |
| | | { |
| | | public static class PolygonPathIterator extends LineStringPathIterator { |
| | | final Polygon pg; |
| | | int outerindex = -1; |
| | | |
| | | public PolygonPathIterator(Polygon _pg, AffineTransform _at) |
| | | { |
| | | public PolygonPathIterator(Polygon _pg, AffineTransform _at) { |
| | | super(_pg.getExteriorRing(), _at); |
| | | pg = _pg; |
| | | index = -1; |
| | | } |
| | | |
| | | public boolean isDone() |
| | | { |
| | | public boolean isDone() { |
| | | return outerindex >= pg.getNumInteriorRing(); |
| | | } |
| | | |
| | | public void next() |
| | | { |
| | | public void next() { |
| | | super.next(); |
| | | if (super.isDone()) |
| | | { |
| | | if (super.isDone()) { |
| | | outerindex++; |
| | | if (outerindex < pg.getNumInteriorRing()) |
| | | { |
| | | if (outerindex < pg.getNumInteriorRing()) { |
| | | super.reInit(pg.getInteriorRingN(outerindex).getCoordinateSequence()); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | public static class GeometryCollectionPathIterator extends GeometryPathIterator |
| | | { |
| | | public static class GeometryCollectionPathIterator extends GeometryPathIterator { |
| | | final GeometryCollection coll; |
| | | GeometryPathIterator current; |
| | | |
| | | public GeometryCollectionPathIterator(GeometryCollection _coll, AffineTransform _at) |
| | | { |
| | | public GeometryCollectionPathIterator(GeometryCollection _coll, AffineTransform _at) { |
| | | super(_at); |
| | | coll = _coll; |
| | | current = getPathIterator(coll.getGeometryN(index), _at); |
| | | } |
| | | |
| | | public boolean isDone() |
| | | { |
| | | public boolean isDone() { |
| | | return index > coll.getNumGeometries(); |
| | | } |
| | | |
| | | public void next() |
| | | { |
| | | public void next() { |
| | | current.next(); |
| | | if (current.isDone()) |
| | | { |
| | | if (current.isDone()) { |
| | | index++; |
| | | if (index < coll.getNumGeometries()) |
| | | { |
| | | if (index < coll.getNumGeometries()) { |
| | | current = getPathIterator(coll.getGeometryN(index), at); |
| | | } |
| | | } |
| | | } |
| | | |
| | | public int currentSegment(float[] coords) |
| | | { |
| | | public int currentSegment(float[] coords) { |
| | | return current.currentSegment(coords); |
| | | } |
| | | |
| | | public int currentSegment(double[] coords) |
| | | { |
| | | public int currentSegment(double[] coords) { |
| | | return current.currentSegment(coords); |
| | | } |
| | | } |