package com.ximple.eofms.util.postjts;
|
|
import java.awt.Rectangle;
|
import java.awt.Shape;
|
import java.awt.geom.AffineTransform;
|
import java.awt.geom.PathIterator;
|
import java.awt.geom.Point2D;
|
import java.awt.geom.Rectangle2D;
|
|
import com.vividsolutions.jts.geom.Coordinate;
|
import com.vividsolutions.jts.geom.CoordinateSequence;
|
import com.vividsolutions.jts.geom.Envelope;
|
import com.vividsolutions.jts.geom.Geometry;
|
import com.vividsolutions.jts.geom.GeometryCollection;
|
import com.vividsolutions.jts.geom.GeometryFactory;
|
import com.vividsolutions.jts.geom.LineString;
|
import com.vividsolutions.jts.geom.LinearRing;
|
import com.vividsolutions.jts.geom.Point;
|
import com.vividsolutions.jts.geom.Polygon;
|
import com.vividsolutions.jts.geom.impl.PackedCoordinateSequence;
|
|
public class JTSShape implements Shape
|
{
|
static GeometryFactory fac = new GeometryFactory();
|
|
Geometry geom;
|
|
final static LinearRing[] NOSHELLS = {};
|
|
public JTSShape(Geometry _geom)
|
{
|
this.geom = _geom;
|
}
|
|
public JTSShape(JtsGeometry _geom)
|
{
|
this(_geom.getGeometry());
|
}
|
|
public boolean contains(Point2D p)
|
{
|
return contains(p.getX(), p.getY());
|
}
|
|
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)
|
{
|
return contains(r.getMinX(), r.getMinY(), r.getWidth(), r.getHeight());
|
}
|
|
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)
|
{
|
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()
|
{
|
Envelope env = geom.getEnvelopeInternal();
|
return new Rectangle2D.Double(env.getMinX(), env.getMaxX(), env.getWidth(), env.getHeight());
|
}
|
|
public Rectangle getBounds()
|
{
|
// We deal simple code for efficiency here, the getBounds() rounding
|
// rules are ugly...
|
return getBounds2D().getBounds();
|
}
|
|
public PathIterator getPathIterator(AffineTransform at)
|
{
|
return getPathIterator(geom, at);
|
}
|
|
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)
|
{
|
return intersects(r.getMinX(), r.getMinY(), r.getWidth(), r.getHeight());
|
}
|
|
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)
|
{
|
return new PointPathIterator((Point) geometry, _at);
|
} else if (geometry instanceof LineString)
|
{
|
return new LineStringPathIterator((LineString) geometry, _at);
|
} else if (geometry instanceof Polygon)
|
{
|
return new PolygonPathIterator((Polygon) geometry, _at);
|
} else
|
{
|
return new GeometryCollectionPathIterator((GeometryCollection) geometry, _at);
|
}
|
}
|
|
public static abstract class GeometryPathIterator implements PathIterator
|
{
|
|
protected final AffineTransform at;
|
protected int index = 0;
|
|
GeometryPathIterator(AffineTransform _at)
|
{
|
this.at = _at;
|
}
|
|
public final int getWindingRule()
|
{
|
return PathIterator.WIND_EVEN_ODD;
|
}
|
|
public void next()
|
{
|
index++;
|
}
|
}
|
|
public static class PointPathIterator extends GeometryPathIterator
|
{
|
final Point p;
|
|
public PointPathIterator(Point _p, AffineTransform _at)
|
{
|
super(_at);
|
p = _p;
|
}
|
|
public int currentSegment(float[] coords)
|
{
|
switch (index)
|
{
|
case 0:
|
coords[0] = (float) p.getX();
|
coords[1] = (float) p.getY();
|
at.transform(coords, 0, coords, 0, 1);
|
return PathIterator.SEG_MOVETO;
|
case 1:
|
return PathIterator.SEG_CLOSE;
|
default:
|
throw new IllegalStateException();
|
}
|
}
|
|
public int currentSegment(double[] coords)
|
{
|
switch (index)
|
{
|
case 0:
|
coords[0] = p.getX();
|
coords[1] = p.getY();
|
at.transform(coords, 0, coords, 0, 1);
|
return PathIterator.SEG_MOVETO;
|
case 1:
|
return PathIterator.SEG_CLOSE;
|
default:
|
throw new IllegalStateException();
|
}
|
}
|
|
public boolean isDone()
|
{
|
return index > 1;
|
}
|
}
|
|
public static class LineStringPathIterator extends GeometryPathIterator
|
{
|
CoordinateSequence cs;
|
|
final boolean isRing;
|
|
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)
|
{
|
cs = _cs;
|
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())
|
{
|
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())
|
{
|
return PathIterator.SEG_CLOSE;
|
} else
|
{
|
throw new IllegalStateException();
|
}
|
}
|
|
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())
|
{
|
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())
|
{
|
return PathIterator.SEG_CLOSE;
|
} else
|
{
|
throw new IllegalStateException();
|
}
|
}
|
|
public boolean isDone()
|
{
|
return isRing ? index > cs.size() : index >= cs.size();
|
}
|
}
|
|
public static class PolygonPathIterator extends LineStringPathIterator
|
{
|
final Polygon pg;
|
int outerindex = -1;
|
|
public PolygonPathIterator(Polygon _pg, AffineTransform _at)
|
{
|
super(_pg.getExteriorRing(), _at);
|
pg = _pg;
|
index = -1;
|
}
|
|
public boolean isDone()
|
{
|
return outerindex >= pg.getNumInteriorRing();
|
}
|
|
public void next()
|
{
|
super.next();
|
if (super.isDone())
|
{
|
outerindex++;
|
if (outerindex < pg.getNumInteriorRing())
|
{
|
super.reInit(pg.getInteriorRingN(outerindex).getCoordinateSequence());
|
}
|
}
|
}
|
}
|
|
public static class GeometryCollectionPathIterator extends GeometryPathIterator
|
{
|
final GeometryCollection coll;
|
GeometryPathIterator current;
|
|
public GeometryCollectionPathIterator(GeometryCollection _coll, AffineTransform _at)
|
{
|
super(_at);
|
coll = _coll;
|
current = getPathIterator(coll.getGeometryN(index), _at);
|
}
|
|
public boolean isDone()
|
{
|
return index > coll.getNumGeometries();
|
}
|
|
public void next()
|
{
|
current.next();
|
if (current.isDone())
|
{
|
index++;
|
if (index < coll.getNumGeometries())
|
{
|
current = getPathIterator(coll.getGeometryN(index), at);
|
}
|
}
|
}
|
|
public int currentSegment(float[] coords)
|
{
|
return current.currentSegment(coords);
|
}
|
|
public int currentSegment(double[] coords)
|
{
|
return current.currentSegment(coords);
|
}
|
}
|
}
|