/**
*
*/
package org.geotools.arcsde.data;
import org.geotools.geometry.jts.LiteCoordinateSequenceFactory;
import com.esri.sde.sdk.client.SeRow;
import com.esri.sde.sdk.client.SeShape;
import com.esri.sde.sdk.geom.GeometryFactory;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.MultiPolygon;
import com.vividsolutions.jts.geom.Polygon;
/**
* This is an experimental implementation of {@link com.esri.sde.sdk.geom.GeometryFactory} that
* creates JTS geometries directly by calling {@link SeRow#getGeometry(GeometryFactory, int)},
* instead of fetching an {@link SeShape} through {@link SeRow#getShape(int)} and then converting it
* to a JTS geometry. This is work in progress and _experimental_, though.
*
* @source $URL:
* http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/datastore/src/main/java/org
* /geotools/arcsde/data/SeToJTSGeometryFactory.java $
*/
public class SeToJTSGeometryFactory implements GeometryFactory {
protected static com.vividsolutions.jts.geom.GeometryFactory gf = new com.vividsolutions.jts.geom.GeometryFactory(
new LiteCoordinateSequenceFactory());
private SeToJTSGeometryFactory delegate;
public void init(final int type, final int numParts, final int numPoints) {
if (type == SeShape.TYPE_POLYGON) {
delegate = new PolygonFactory();
} else if (type == SeShape.TYPE_MULTI_POLYGON) {
delegate = new MultiPolygonFactory();
} else {
throw new IllegalArgumentException("Unhandled geometry type: " + type);
}
delegate.init(numParts, numPoints);
}
protected void init(int numParts, int numPoints) {
// do-nothing, override as needed
}
public void envelope(double minx, double miny, double maxx, double maxy) {
// System.out.println("envelope: " + minx + "," + miny + "," + maxx + "," + maxy);
}
public Geometry getGeometry() {
return delegate.getGeometry();
}
public void newPart(final int numSubParts) {
delegate.newPart(numSubParts);
}
public void newSubPart(final int numPoints) {
delegate.newSubPart(numPoints);
}
public void newPoint(final double x, final double y) {
delegate.newPoint(x, y);
}
public void newPoint(double x, double y, double m) {
newPoint(x, y);
}
public void newPoint(double x, double y, double m, double z) {
newPoint(x, y);
}
public void partOffsets(int[] partOffsets) {
// System.out.println(Arrays.toString(partOffsets));
}
/**
*
*
*/
private static final class PolygonFactory extends SeToJTSGeometryFactory {
private LinearRing[] subparts;
private CoordinateSequence currCoordSeq;
private int subPartNo;
private int currPartNumPoints;
private int currPointNo;
@Override
protected void init(int numParts, int numPoints) {
subPartNo = -1;
currCoordSeq = null;
}
@Override
public Polygon getGeometry() {
LinearRing shell = subparts[0];
LinearRing[] holes = null;
if (subparts.length > 1) {
holes = new LinearRing[subparts.length - 1];
System.arraycopy(subparts, 0, holes, 0, holes.length);
}
Polygon poly = gf.createPolygon(shell, holes);
return poly;
}
@Override
public void newPart(final int numSubParts) {
subparts = new LinearRing[numSubParts];
subPartNo = -1;
}
@Override
public void newSubPart(final int numPoints) {
this.subPartNo++;
this.currPartNumPoints = numPoints;
this.currPointNo = 0;
final int dimension = 2;
this.currCoordSeq = gf.getCoordinateSequenceFactory().create(numPoints, dimension);
}
@Override
public void newPoint(final double x, final double y) {
this.currCoordSeq.setOrdinate(this.currPointNo, 0, x);
this.currCoordSeq.setOrdinate(this.currPointNo, 1, y);
currPointNo++;
if (currPointNo == this.currPartNumPoints) {
this.subparts[this.subPartNo] = gf.createLinearRing(this.currCoordSeq);
}
}
}
/**
*
*
*/
private static final class MultiPolygonFactory extends SeToJTSGeometryFactory {
private SeToJTSGeometryFactory.PolygonFactory polygonFactory;
private Polygon[] parts;
private int partNo;
@Override
protected void init(int numParts, int numPoints) {
this.parts = new Polygon[numParts];
polygonFactory = new PolygonFactory();
this.partNo = -1;
}
@Override
public Geometry getGeometry() {
if (parts.length > 0) {
parts[parts.length - 1] = polygonFactory.getGeometry();
}
MultiPolygon mp = gf.createMultiPolygon(parts);
return mp;
}
@Override
public void newPart(final int numSubParts) {
if (this.partNo > -1) {
Polygon poly = polygonFactory.getGeometry();
this.parts[partNo] = poly;
}
this.partNo++;
polygonFactory.init(1, -1);
polygonFactory.newPart(numSubParts);
}
@Override
public void newSubPart(final int numPoints) {
polygonFactory.newSubPart(numPoints);
}
@Override
public void newPoint(final double x, final double y) {
polygonFactory.newPoint(x, y);
}
}
}