forked from geodmms/xdgnjobs

?? ?
2008-06-13 b31e88f14407d5321a7adb1dd62c9bbac24d0515
update for EOFM-117 createSchemaTexts and createNewSchemaTexts
12 files modified
6 files added
2346 ■■■■■ changed files
.gitattributes 6 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexChainElement.java 43 ●●●● patch | view | raw | blame | history
xdgnjobs/ximple-jobcarrier/src/main/resources/log4j.properties 2 ●●● patch | view | raw | blame | history
xdgnjobs/ximple-jobcarrier/src/main/resources/quartz_jobs.xml 4 ●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateLineStringStrategy.java 2 ●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateLineTextStrategy.java 2 ●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/context/mysql/GeneralDgnConvertMySQLJobContext.java 16 ●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/context/postgis/AbstractDgnToPostGISJobContext.java 350 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/context/postgis/AbstractOracleToPostGISJobContext.java 23 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/context/postgis/GeneralDgnConvertPostGISJobContext.java 109 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/context/postgis/IndexDgnConvertPostGISJobContext.java 86 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/FeatureTypeBuilderUtil.java 68 ●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/postjts/JTSShape.java 339 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/postjts/JtsBinaryParser.java 287 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/postjts/JtsBinaryWriter.java 469 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/postjts/JtsGeometry.java 187 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/postjts/JtsGisWrapper.java 173 ●●●●● patch | view | raw | blame | history
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/postjts/JtsWrapper.java 180 ●●●●● patch | view | raw | blame | history
.gitattributes
@@ -122,6 +122,12 @@
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/TPCLIDConverter.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/TWD97GeometryConverterDecorator.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/TWDDatumConverter.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/postjts/JTSShape.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/postjts/JtsBinaryParser.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/postjts/JtsBinaryWriter.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/postjts/JtsGeometry.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/postjts/JtsGisWrapper.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/postjts/JtsWrapper.java svneol=native#text/plain
xdgnjobs/ximple-spatialjob/src/main/resources/com/ximple/eofms/filter/ElementDispatcherRules.xml svneol=native#text/xml
xdgnjobs/ximple-spatialjob/src/main/resources/com/ximple/eofms/filter/FeatureClassificationRules.xml svneol=native#text/xml
xdgnjobs/ximple-spatialjob/src/main/resources/conf/ConvertShpFilterForLayer.xml svneol=native#text/xml
xdgnjobs/ximple-dgnio/src/main/java/com/ximple/io/dgn7/ComplexChainElement.java
@@ -11,6 +11,8 @@
import com.vividsolutions.jts.geom.CoordinateList;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.MultiLineString;
import com.vividsolutions.jts.geom.LineString;
/**
 * ComplexChainElement
@@ -148,36 +150,8 @@
    public Geometry toGeometry(GeometryFactory factory)
    {
        if (size() == 1)
        {
            Element element = (Element) get(0);
        ArrayList<LineString> lineStrings = new ArrayList<LineString>();
            if (element instanceof LineStringElement)
            {
                if (((LineStringElement) element).getVerticeSize() == 0 || ((LineStringElement) element).getVerticeSize() > 1)
                {
                    return ((LineStringElement) element).toGeometry(factory);
                }
            } else if (element instanceof LineElement)
            {
                if (((LineElement) element).getVertices().length == 0 || ((LineElement) element).getVertices().length > 1)
                {
                    return ((LineElement) element).toGeometry(factory);
                }
            } else
            {
                if (element instanceof GeometryConverter)
                {
                    return ((GeometryConverter) element).toGeometry(factory);
                }
                return null;
            }
        }
        CoordinateList pts = new CoordinateList();
        for (ListIterator it = listIterator(); it.hasNext();)
        {
            Element element = (Element) it.next();
@@ -186,7 +160,7 @@
            {
                if (((LineStringElement) element).getVerticeSize() == 0 || ((LineStringElement) element).getVerticeSize() > 1)
                {
                    pts.add(((LineStringElement) element).toGeometry(factory).getCoordinates(), true);
                    lineStrings.add((LineString) ((LineStringElement) element).toGeometry(factory));
                }
            } else if (element instanceof LineElement)
@@ -194,15 +168,18 @@
                if (((LineElement) element).getVertices().length == 0 || ((LineElement) element).getVertices().length > 1)
                {
                    pts.add(((LineElement) element).toGeometry(factory).getCoordinates(), true);
                    lineStrings.add((LineString) ((LineElement) element).toGeometry(factory));
                }
            } else if (element instanceof ArcElement)
            {
                pts.add(((ArcElement) element).toGeometry(factory).getCoordinates(), true);
                lineStrings.add((LineString) ((ArcElement) element).toGeometry(factory));
            }
        }
        return factory.createLineString(pts.toCoordinateArray());
        LineString[] lines = lineStrings.toArray(new LineString[lineStrings.size()]);
        if ((lines == null) || (lines.length == 0))
            return null;
        return factory.createMultiLineString(lines);
    }
    public double getElementSize()
xdgnjobs/ximple-jobcarrier/src/main/resources/log4j.properties
@@ -25,4 +25,4 @@
# Print messages of level INFO or above for examples
log4j.logger.org.cavaness.quartzbook=INFO
log4j.logger.com.ximple.eofms=DEBUG
log4j.logger.com.ximple.eofms=INFO
xdgnjobs/ximple-jobcarrier/src/main/resources/quartz_jobs.xml
@@ -76,7 +76,7 @@
        </entry>
        <entry>
          <key>CONVERTDB</key>
          <value>true</value>
          <value>false</value>
        </entry>
        <entry>
          <key>CONVERTFILE</key>
@@ -108,7 +108,7 @@
        </entry>
        <entry>
          <key>COPYCONNECTIVITYMODE</key>
          <value>true</value>
          <value>false</value>
        </entry>
      </job-data-map>
    </job-detail>
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateLineStringStrategy.java
@@ -60,7 +60,7 @@
    {
        if (!typeBuilders.containsKey(featureName))
        {
            FeatureTypeBuilder typeBuilder = FeatureTypeBuilderUtil.createLineStringFeatureTypeBuilder(featureName);
            FeatureTypeBuilder typeBuilder = FeatureTypeBuilderUtil.createLineFeatureTypeBuilder(featureName);
            typeBuilders.put(featureName, typeBuilder);
            fireFeatureTypeEvent(new FeatureTypeEvent(this, typeBuilder.getFeatureType()));
        }
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/filter/CreateLineTextStrategy.java
@@ -63,7 +63,7 @@
    {
        if (!typeBuilders.containsKey(featureName))
        {
            FeatureTypeBuilder typeBuilder = FeatureTypeBuilderUtil.createLineStringFeatureTypeBuilder(featureName);
            FeatureTypeBuilder typeBuilder = FeatureTypeBuilderUtil.createLineFeatureTypeBuilder(featureName);
            typeBuilders.put(featureName, typeBuilder);
            fireFeatureTypeEvent(new FeatureTypeEvent(this, typeBuilder.getFeatureType()));
        }
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/context/mysql/GeneralDgnConvertMySQLJobContext.java
@@ -417,7 +417,7 @@
        String typeName;
        if (element instanceof TextElement)
        {
            typeName = getFeatureBaseName() + "P";
            typeName = getFeatureBaseName() + "_P";
            if (!featureTypes.containsKey(typeName))
            {
                featureTypes.put(typeName, createPointFeatureElement(typeName));
@@ -425,7 +425,7 @@
            return featureTypes.get(typeName);
        } else if (element instanceof TextNodeElement)
        {
            typeName = getFeatureBaseName() + "P";
            typeName = getFeatureBaseName() + "_P";
            if (!featureTypes.containsKey(typeName))
            {
                featureTypes.put(typeName, createPointFeatureElement(typeName));
@@ -435,7 +435,7 @@
        {
            if (element instanceof ShapeElement)
            {
                typeName = getFeatureBaseName() + "R";
                typeName = getFeatureBaseName() + "_R";
                if (!featureTypes.containsKey(typeName))
                {
                    featureTypes.put(typeName, createLineFeatureElement(typeName));
@@ -443,7 +443,7 @@
                return featureTypes.get(typeName);
            } else
            {
                typeName = getFeatureBaseName() + "L";
                typeName = getFeatureBaseName() + "_L";
                if (!featureTypes.containsKey(typeName))
                {
                    featureTypes.put(typeName, createLineFeatureElement(typeName));
@@ -452,7 +452,7 @@
            }
        } else if (element instanceof LineElement)
        {
            typeName = getFeatureBaseName() + "L";
            typeName = getFeatureBaseName() + "_L";
            if (!featureTypes.containsKey(typeName))
            {
                featureTypes.put(typeName, createLineFeatureElement(typeName));
@@ -460,7 +460,7 @@
            return featureTypes.get(typeName);
        } else if (element instanceof ComplexChainElement)
        {
            typeName = getFeatureBaseName() + "L";
            typeName = getFeatureBaseName() + "_ML";
            if (!featureTypes.containsKey(typeName))
            {
                featureTypes.put(typeName, createLineFeatureElement(typeName));
@@ -468,7 +468,7 @@
            return featureTypes.get(typeName);
        } else if (element instanceof ArcElement)
        {
            typeName = getFeatureBaseName() + "A";
            typeName = getFeatureBaseName() + "_A";
            if (!featureTypes.containsKey(typeName))
            {
                featureTypes.put(typeName, createArcFeatureElement(typeName));
@@ -476,7 +476,7 @@
            return featureTypes.get(typeName);
        } else if (element instanceof EllipseElement)
        {
            typeName = getFeatureBaseName() + "R";
            typeName = getFeatureBaseName() + "_R";
            if (!featureTypes.containsKey(typeName))
            {
                featureTypes.put(typeName, createEllipseFeatureElement(typeName));
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/context/postgis/AbstractDgnToPostGISJobContext.java
@@ -4,6 +4,7 @@
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
@@ -44,28 +45,31 @@
import com.vividsolutions.jts.io.WKTWriter;
import com.ximple.eofms.jobs.context.AbstractDgnFileJobContext;
import com.ximple.eofms.util.postjts.JtsBinaryWriter;
public abstract class AbstractDgnToPostGISJobContext extends AbstractDgnFileJobContext
{
    private static Map<String, Class> GEOM_TYPE_MAP = new HashMap<String, Class>();
    private static Map<String, Class> GEOM3D_TYPE_MAP = new HashMap<String, Class>();
    static
    {
        GEOM_TYPE_MAP.put("GEOMETRY", Geometry.class);
        GEOM_TYPE_MAP.put("POINT", Point.class);
        GEOM_TYPE_MAP.put("POINTM", Point.class);
        GEOM_TYPE_MAP.put("LINESTRING", LineString.class);
        GEOM_TYPE_MAP.put("LINESTRINGM", LineString.class);
        GEOM_TYPE_MAP.put("POLYGON", Polygon.class);
        GEOM_TYPE_MAP.put("POLYGONM", Polygon.class);
        GEOM_TYPE_MAP.put("MULTIPOINT", MultiPoint.class);
        GEOM_TYPE_MAP.put("MULTIPOINTM", MultiPoint.class);
        GEOM_TYPE_MAP.put("MULTILINESTRING", MultiLineString.class);
        GEOM_TYPE_MAP.put("MULTILINESTRINGM", MultiLineString.class);
        GEOM_TYPE_MAP.put("MULTIPOLYGON", MultiPolygon.class);
        GEOM_TYPE_MAP.put("MULTIPOLYGONM", MultiPolygon.class);
        GEOM_TYPE_MAP.put("GEOMETRYCOLLECTION", GeometryCollection.class);
        GEOM_TYPE_MAP.put("GEOMETRYCOLLECTIONM", GeometryCollection.class);
        GEOM3D_TYPE_MAP.put("POINTM", Point.class);
        GEOM3D_TYPE_MAP.put("LINESTRINGM", LineString.class);
        GEOM3D_TYPE_MAP.put("POLYGONM", Polygon.class);
        GEOM3D_TYPE_MAP.put("MULTIPOINTM", MultiPoint.class);
        GEOM3D_TYPE_MAP.put("MULTILINESTRINGM", MultiLineString.class);
        GEOM3D_TYPE_MAP.put("MULTIPOLYGONM", MultiPolygon.class);
        GEOM3D_TYPE_MAP.put("GEOMETRYCOLLECTIONM", GeometryCollection.class);
    }
    private static Map<Class, String> CLASS_MAPPINGS = new HashMap<Class, String>();
@@ -112,12 +116,14 @@
     */
    private static final int MAX_ALLOWED_VALUE = 10485760;
    protected static final int BATCHSIZE = 25;
    // protected static final int BATCHSIZE = 2048;
    protected static final int BATCHSIZE = 256;
    /**
     * Well Known Text writer (from JTS).
     */
    protected static WKTWriter geometryWriter = new WKTWriter();
    protected static JtsBinaryWriter binaryWriter = new JtsBinaryWriter();
    protected PostgisDataStore targetDataStore;
    private Connection connection;
@@ -228,6 +234,46 @@
        conn.commit();
    }
    protected String dropGeometryColumn(String dbSchema, String tableName, String geomField)
    {
        StringBuilder sb = new StringBuilder();
        sb.append("SELECT DropGeometryColumn('");
        sb.append(dbSchema);
        sb.append("','");
        sb.append(tableName);
        sb.append("','");
        sb.append(geomField);
        sb.append("')");
        getLogger().info("Execute-" + sb.toString());
        return sb.toString();
    }
    private String addGeometryColumn(String dbSchema, String tableName, GeometryAttributeType geometryAttribute, int srid)
    {
        StringBuilder sql;
        String typeName = getGeometrySQLTypeName(geometryAttribute.getBinding());
        if (typeName == null)
        {
            getLogger().warn("Error: " + geometryAttribute.getLocalName() + " unknown type!!!");
            throw new RuntimeException("Error: " + geometryAttribute.getLocalName() + " unknown type!!!");
        }
        sql = new StringBuilder("SELECT AddGeometryColumn('");
        sql.append(dbSchema);
        sql.append("','");
        sql.append(tableName);
        sql.append("','");
        sql.append(geometryAttribute.getLocalName());
        sql.append("','");
        sql.append(srid);
        sql.append("','");
        sql.append(typeName);
        sql.append("', 2);");
        //prints statement for later reuse
        return sql.toString();
    }
    public ArrayList<String> createSchemaTexts(FeatureType featureType) throws IOException
    {
        String tableName = featureType.getTypeName();
@@ -246,7 +292,7 @@
        {
            StringBuffer sql = new StringBuffer("CREATE TABLE ");
            sql.append(encodeSchemaTableName(tableName));
            sql.append(" (");
            sql.append(" ( gid serial PRIMARY KEY, ");
            sql.append(makeSqlCreate(attributeType));
            sql.append(");");
@@ -406,6 +452,7 @@
                        result.add(sqlStr);
                    }
                    /*
                    if (!typeName.equals("GEOMETRY"))
                    {
                        sql = new StringBuffer("ALTER TABLE ");
@@ -426,7 +473,7 @@
                            result.add(sqlStr);
                        }
                    }
                    */
                } else
                {
                    getLogger().warn("Error: " + geomAttribute.getLocalName() + " unknown type!!!");
@@ -476,6 +523,103 @@
        if (!shouldExecute)
        {
            throw new IOException("The table " + tableName + " already exists.");
        }
        return result;
    }
    public ArrayList<String> createNewSchemaTexts(FeatureType featureType) throws IOException
    {
        String origintableName = featureType.getTypeName();
        String tableName = origintableName.toLowerCase();
        ArrayList<String> result = new ArrayList<String>();
        AttributeType[] attributeType = featureType.getAttributeTypes();
        // String dbSchema = targetDataStore.getDatabaseSchemaName();
        Connection con = getConnection();
        boolean shouldDrop = tablePresent(tableName, con);
        if (shouldDrop)
        {
            String sqlStr = "DROP TABLE " + encodeSchemaTableName(tableName) + ";";
            getLogger().info(sqlStr);
            result.add(sqlStr);
        }
        StringBuffer sql = new StringBuffer("CREATE TABLE ");
        sql.append(encodeSchemaTableName(tableName));
        sql.append(" ( gid serial PRIMARY KEY, ");
        sql.append(makeNonGeomSqlCreate(attributeType));
        sql.append(");");
        String sqlStr = sql.toString();
        getLogger().info(sqlStr);
        result.add(sqlStr);
        for (AttributeType anAttributeType : attributeType)
        {
            if (!(anAttributeType instanceof GeometryAttributeType))
            {
                continue;
            }
            GeometryAttributeType geomAttribute = (GeometryAttributeType) anAttributeType;
            if (shouldDrop)
            {
            sqlStr = dropGeometryColumn("", tableName, geomAttribute.getLocalName());
            getLogger().info(sqlStr);
            result.add(sqlStr);
            }
            CoordinateReferenceSystem refSys = geomAttribute.getCoordinateSystem();
            int SRID;
            if (refSys != null)
            {
                try
                {
                    Set ident = refSys.getIdentifiers();
                    if ((ident == null || ident.isEmpty()) && refSys == DefaultGeographicCRS.WGS84)
                    {
                        SRID = 4326;
                    } else
                    {
                        String code = ((NamedIdentifier) ident.toArray()[0]).getCode();
                        SRID = Integer.parseInt(code);
                    }
                } catch (Exception e)
                {
                    getLogger().warn("SRID could not be determined");
                    SRID = -1;
                }
            } else
            {
                SRID = -1;
            }
            sqlStr = addGeometryColumn("", tableName, geomAttribute, SRID);
            getLogger().info(sqlStr);
            result.add(sqlStr);
            String indexName = tableName.replace('-', '_');
            //also build a spatial index on each geometry column.
            sql = new StringBuffer("CREATE INDEX spatial_");
            sql.append(indexName);
            sql.append("_");
            sql.append(anAttributeType.getLocalName().toLowerCase());
            sql.append(" ON ");
            sql.append(encodeSchemaTableName(tableName));
            sql.append(" USING GIST (");
            sql.append(encodeSchemaColumnName(anAttributeType.getLocalName()));
            sql.append(" gist_geometry_ops);");
            sqlStr = sql.toString();
            getLogger().info(sqlStr);
            result.add(sqlStr);
        }
        return result;
@@ -553,6 +697,96 @@
                {
                    typeName = "GEOMETRY";
                } else if (typeName.equals("VARCHAR"))
                {
                    int length = -1;
                    Filter f = anAttributeType.getRestriction();
                    if (f != null && f != Filter.EXCLUDE && f != Filter.INCLUDE &&
                            (f instanceof PropertyIsLessThan || f instanceof PropertyIsLessThanOrEqualTo))
                    {
                        try
                        {
                            BinaryComparisonOperator cf = (BinaryComparisonOperator) f;
                            if (cf.getExpression1() instanceof LengthFunction)
                            {
                                length = Integer.parseInt(((Literal) cf.getExpression2()).getValue().toString());
                            } else
                            {
                                if (cf.getExpression2() instanceof LengthFunction)
                                {
                                    length = Integer.parseInt(((Literal) cf.getExpression1()).getValue().toString());
                                }
                            }
                        } catch (NumberFormatException e)
                        {
                            length = 256;
                        }
                    } else
                    {
                        length = 256;
                    }
                    if (length < 1)
                    {
                        getLogger().warn("FeatureType did not specify string length; defaulted to 256");
                        length = 256;
                    } else if (length > MAX_ALLOWED_VALUE)
                    {
                        length = MAX_ALLOWED_VALUE;
                    }
                    typeName = typeName + "(" + length + ")";
                }
                if (!anAttributeType.isNillable())
                {
                    typeName = typeName + " NOT NULL";
                }
                //TODO review!!! Is toString() always OK???
                Object defaultValue = anAttributeType.createDefaultValue();
                if (defaultValue != null)
                {
                    typeName = typeName + " DEFAULT '"
                            + defaultValue.toString() + "'";
                }
                buf.append(" \"").append(anAttributeType.getLocalName()).append("\" ").append(typeName).append(",");
            } else
            {
                String msg;
                if (anAttributeType == null)
                {
                    msg = "AttributeType was null!";
                } else
                {
                    msg = "Type '" + anAttributeType.getBinding() + "' not supported!";
                }
                throw (new IOException(msg));
            }
        }
        return buf.deleteCharAt(buf.length() - 1);
    }
    private StringBuffer makeNonGeomSqlCreate(AttributeType[] attributeType)
            throws IOException
    {
        StringBuffer buf = new StringBuffer("");
        for (AttributeType anAttributeType : attributeType)
        {
            String typeName;
            typeName = CLASS_MAPPINGS.get(anAttributeType.getBinding());
            if (typeName == null)
            {
                typeName = GEOM_CLASS_MAPPINGS.get(anAttributeType.getBinding());
                if (typeName != null) continue;
            }
            if (typeName != null)
            {
                if (typeName.equals("VARCHAR"))
                {
                    int length = -1;
                    Filter f = anAttributeType.getRestriction();
@@ -729,6 +963,38 @@
        return (statementSQL.toString());
    }
    protected String makePrepareInsertSql(FeatureType featureType)
    {
        String tableName = encodeSchemaTableName(featureType.getTypeName());
        AttributeType[] attributeTypes = featureType.getAttributeTypes();
        String attrValue;
        StringBuffer statementSQL = new StringBuffer("INSERT INTO " + tableName + " (");
        // encode insertion for attributes, but remember to avoid auto-increment ones,
        // they may be included in the feature type as well
        for (AttributeType attributeType : attributeTypes)
        {
            String attName = attributeType.getLocalName();
            String colName = encodeSchemaColumnName(attName);
            statementSQL.append(colName).append(",");
        }
        statementSQL.setCharAt(statementSQL.length() - 1, ')');
        statementSQL.append(" VALUES (");
        for (AttributeType attributeType : attributeTypes)
        {
            statementSQL.append(" ? ,");
        }
        statementSQL.setCharAt(statementSQL.length() - 1, ')');
        return (statementSQL.toString());
    }
    protected String addQuotes(Object value)
    {
        String retString;
@@ -765,12 +1031,72 @@
        return encodeName(colName);
    }
    public String encodeSchemaTableName(String tableName) {
    public String encodeSchemaTableName(String tableName)
    {
        return schemaEnabled ? ("\"" + targetDataStore.getDatabaseSchemaName() + "\".\"" + tableName + "\"")
                             : ("\"" + tableName + "\"");
    }
    public String encodeSchemaColumnName(String columnName) {
    public String encodeSchemaColumnName(String columnName)
    {
        return "\"" + columnName + "\"";
    }
    protected void bindFeatureParameters(PreparedStatement pstmt, Feature feature) throws SQLException
    {
        FeatureType featureType = feature.getFeatureType();
        AttributeType[] attributeTypes = featureType.getAttributeTypes();
        Object[] attributes = feature.getAttributes(null);
        for (int i = 0; i < attributeTypes.length; i++)
        {
            if (attributeTypes[i] instanceof GeometryAttributeType)
            {
                pstmt.setBytes(i + 1, binaryWriter.writeBinary((Geometry) attributes[i]));
            } else
            {
                if (attributeTypes[i].getBinding().equals(Short.class))
                {
                    pstmt.setShort(i + 1, (Short) attributes[i]);
                } else if (attributeTypes[i].getBinding().equals(Integer.class))
                {
                    pstmt.setInt(i + 1, (Short) attributes[i]);
                } else if (attributeTypes[i].getBinding().equals(Long.class))
                {
                    pstmt.setLong(i + 1, (Long) attributes[i]);
                } else if (attributeTypes[i].getBinding().equals(String.class))
                {
                    pstmt.setString(i + 1, (String) attributes[i]);
                } else if (attributeTypes[i].getBinding().equals(Float.class))
                {
                    pstmt.setFloat(i + 1, (Float) attributes[i]);
                } else if (attributeTypes[i].getBinding().equals(Double.class))
                {
                    pstmt.setDouble(i + 1, (Double) attributes[i]);
                } else if (attributeTypes[i].getBinding().equals(Boolean.class))
                {
                    pstmt.setBoolean(i + 1, (Boolean) attributes[i]);
                } else if (attributeTypes[i].getBinding().equals(BigDecimal.class))
                {
                    pstmt.setBigDecimal(i + 1, (BigDecimal) attributes[i]);
                } else if (attributeTypes[i].getBinding().equals(java.sql.Date.class))
                {
                    pstmt.setDate(i + 1, (java.sql.Date) attributes[i]);
                } else if (attributeTypes[i].getBinding().equals(java.sql.Time.class))
                {
                    pstmt.setTime(i + 1, (java.sql.Time) attributes[i]);
                } else if (attributeTypes[i].getBinding().equals(java.sql.Timestamp.class))
                {
                    pstmt.setTimestamp(i + 1, (java.sql.Timestamp) attributes[i]);
                } else if (attributeTypes[i].getBinding().equals(java.util.Date.class))
                {
                    java.sql.Date sDate = new java.sql.Date(((java.util.Date) attributes[i]).getTime());
                    pstmt.setDate(i + 1, sDate);
                }
            }
        }
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/context/postgis/AbstractOracleToPostGISJobContext.java
@@ -44,28 +44,31 @@
import com.vividsolutions.jts.io.WKBWriter;
import com.ximple.eofms.jobs.context.AbstractOracleJobContext;
import com.ximple.eofms.util.postjts.JtsBinaryWriter;
public abstract class AbstractOracleToPostGISJobContext extends AbstractOracleJobContext
{
    private static Map<String, Class> GEOM_TYPE_MAP = new HashMap<String, Class>();
    private static Map<String, Class> GEOM3D_TYPE_MAP = new HashMap<String, Class>();
    static
    {
        GEOM_TYPE_MAP.put("GEOMETRY", Geometry.class);
        GEOM_TYPE_MAP.put("POINT", Point.class);
        GEOM_TYPE_MAP.put("POINTM", Point.class);
        GEOM_TYPE_MAP.put("LINESTRING", LineString.class);
        GEOM_TYPE_MAP.put("LINESTRINGM", LineString.class);
        GEOM_TYPE_MAP.put("POLYGON", Polygon.class);
        GEOM_TYPE_MAP.put("POLYGONM", Polygon.class);
        GEOM_TYPE_MAP.put("MULTIPOINT", MultiPoint.class);
        GEOM_TYPE_MAP.put("MULTIPOINTM", MultiPoint.class);
        GEOM_TYPE_MAP.put("MULTILINESTRING", MultiLineString.class);
        GEOM_TYPE_MAP.put("MULTILINESTRINGM", MultiLineString.class);
        GEOM_TYPE_MAP.put("MULTIPOLYGON", MultiPolygon.class);
        GEOM_TYPE_MAP.put("MULTIPOLYGONM", MultiPolygon.class);
        GEOM_TYPE_MAP.put("GEOMETRYCOLLECTION", GeometryCollection.class);
        GEOM_TYPE_MAP.put("GEOMETRYCOLLECTIONM", GeometryCollection.class);
        GEOM3D_TYPE_MAP.put("POINTM", Point.class);
        GEOM3D_TYPE_MAP.put("LINESTRINGM", LineString.class);
        GEOM3D_TYPE_MAP.put("POLYGONM", Polygon.class);
        GEOM3D_TYPE_MAP.put("MULTIPOINTM", MultiPoint.class);
        GEOM3D_TYPE_MAP.put("MULTILINESTRINGM", MultiLineString.class);
        GEOM3D_TYPE_MAP.put("MULTIPOLYGONM", MultiPolygon.class);
        GEOM3D_TYPE_MAP.put("GEOMETRYCOLLECTIONM", GeometryCollection.class);
    }
    private static Map<Class, String> CLASS_MAPPINGS = new HashMap<Class, String>();
@@ -112,15 +115,15 @@
     */
    private static final int MAX_ALLOWED_VALUE = 10485760;
    protected static final int BATCHSIZE = 25;
    protected static final int BATCHSIZE = 256;
    /**
     * Well Known Text writer (from JTS).
     */
    protected static WKTWriter geometryWriter = new WKTWriter();
    protected static JtsBinaryWriter binaryWriter = new JtsBinaryWriter();
    protected PostgisDataStore targetDataStore;
    private Connection connection;
    protected boolean schemaEnabled = true;
@@ -252,7 +255,7 @@
        {
            StringBuffer sql = new StringBuffer("CREATE TABLE ");
            sql.append(encodeSchemaTableName(tableName));
            sql.append(" (");
            sql.append(" ( gid serial PRIMARY KEY, ");
            sql.append(makeSqlCreate(attributeType));
            sql.append(");");
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/context/postgis/GeneralDgnConvertPostGISJobContext.java
@@ -3,7 +3,6 @@
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -12,26 +11,19 @@
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.PreparedStatement;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.transaction.memory.PessimisticMapWrapper;
import org.apache.commons.transaction.util.CommonsLoggingLogger;
import org.apache.commons.transaction.util.LoggerFacade;
import org.geotools.data.DataStore;
import org.geotools.data.FeatureWriter;
import org.geotools.data.Transaction;
import org.geotools.data.DefaultTransaction;
import org.geotools.data.DataSourceException;
import org.geotools.data.FeatureStore;
import org.geotools.feature.Feature;
import org.geotools.feature.FeatureType;
import org.geotools.feature.FeatureTypeBuilder;
import org.geotools.feature.IllegalAttributeException;
import org.geotools.feature.SchemaException;
import org.geotools.feature.SimpleFeature;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureCollections;
import org.postgresql.util.PSQLException;
import com.vividsolutions.jts.geom.Geometry;
@@ -58,7 +50,7 @@
    static final LoggerFacade sLogger = new CommonsLoggingLogger(logger);
    static final GeometryFactory geometryFactory = new GeometryFactory();
    private HashMap<FeatureType, ArrayList<String>> txFeaturesContext = new HashMap<FeatureType, ArrayList<String>>();
    private HashMap<FeatureType, ArrayList<Feature>> txFeaturesContext = new HashMap<FeatureType, ArrayList<Feature>>();
    private TreeMap<String, FeatureTypeBuilder> typeBuilders = new TreeMap<String, FeatureTypeBuilder>();
    private TreeMap<String, FeatureType> featureTypes = new TreeMap<String, FeatureType>();
@@ -66,6 +58,8 @@
    private TWD97GeometryConverterDecorator convertDecorator = null;
    private String featureBaseName = null;
    private boolean dropTableMode = true;
    private int accumulate = 0;
    public GeneralDgnConvertPostGISJobContext(String dataPath, DataStore targetDataStore)
    {
@@ -102,18 +96,26 @@
            if (!txFeaturesContext.containsKey(feature.getFeatureType()))
            {
                txFeaturesContext.put(feature.getFeatureType(), new ArrayList<String>());
                txFeaturesContext.put(feature.getFeatureType(), new ArrayList<Feature>());
            }
            ArrayList<String> arrayList = txFeaturesContext.get(feature.getFeatureType());
            ArrayList<Feature> arrayList = txFeaturesContext.get(feature.getFeatureType());
            if (feature.getDefaultGeometry() != null && !feature.getDefaultGeometry().isEmpty())
                arrayList.add(makeInsertSql(feature, -1));
            {
                arrayList.add(feature);
                accumulate++;
            }
        } else
        {
            logger.info("Unknown Element :" + element.getType() + ", lv=" + element.getLevelIndex());
        }
        if (accumulate > BATCHSIZE)
        {
            commitTransaction();
        }
    }
    private Transaction transaction;
    // private Transaction transaction;
    public void startTransaction()
    {
@@ -154,18 +156,22 @@
                FeatureType featureType = it.next();
                logger.debug("Begin Save into PostGIS:" + featureType.getTypeName());
                ArrayList<String> stmtTexts = txFeaturesContext.get(featureType);
                String bindingStmt = makePrepareInsertSql(featureType, -1);
                ArrayList<Feature> features = txFeaturesContext.get(featureType);
                Connection conn = getConnection();
                boolean autoCommit = conn.getAutoCommit();
                conn.setAutoCommit(true);
                PreparedStatement pstmt = conn.prepareStatement(bindingStmt);
                for (String stmtText : stmtTexts)
                for (Feature feature : features)
                {
                    currentStmt = stmtText;
                    Statement stmt = conn.createStatement();
                    // currentStmt = feature;
                    // Statement stmt = conn.createStatement();
                    try
                    {
                        stmt.execute(stmtText);
                        // stmt.execute(feature);
                        bindFeatureParameters(pstmt, feature);
                        pstmt.execute();
                    } catch (PSQLException e)
                    {
                        if (currentStmt != null)
@@ -174,24 +180,29 @@
                        }
                        logger.error(e.getServerErrorMessage());
                        logger.error(e.getMessage(), e);
                        /*
                    } finally {
                        stmt.close();
                        */
                    }
                    /*
                    if ((i % BATCHSIZE) != 0)
                    {
                        stmt.addBatch(stmtText);
                        stmt.addBatch(feature);
                    } else {
                        stmt.addBatch(stmtText);
                        stmt.addBatch(feature);
                        stmt.executeBatch();
                    }
                    i++;
                    */
                }
                stmtTexts.clear();
                pstmt.close();
                features.clear();
                conn.setAutoCommit(autoCommit);
                logger.debug("End Save into PostGIS:" + featureType.getTypeName());
            }
            accumulate = 0;
        } catch (SQLException e)
        {
            logger.error(e.getMessage(), e);
@@ -221,11 +232,33 @@
        return typeBuilders.get(featureName).getFeatureType();
    }
    public FeatureType createPolygonFeatureElement(String featureName) throws SchemaException
    {
        if (!typeBuilders.containsKey(featureName))
        {
            FeatureTypeBuilder typeBuilder = FeatureTypeBuilderUtil.createNormalPolygonFeatureTypeBuilder(featureName);
            typeBuilders.put(featureName, typeBuilder);
            clearFeatureData(typeBuilder);
        }
        return typeBuilders.get(featureName).getFeatureType();
    }
    public FeatureType createLineFeatureElement(String featureName) throws SchemaException
    {
        if (!typeBuilders.containsKey(featureName))
        {
            FeatureTypeBuilder typeBuilder = FeatureTypeBuilderUtil.createNormalLineFeatureTypeBuilder(featureName);
            typeBuilders.put(featureName, typeBuilder);
            clearFeatureData(typeBuilder);
        }
        return typeBuilders.get(featureName).getFeatureType();
    }
    public FeatureType createMultiLineFeatureElement(String featureName) throws SchemaException
    {
        if (!typeBuilders.containsKey(featureName))
        {
            FeatureTypeBuilder typeBuilder = FeatureTypeBuilderUtil.createNormalMultiLineFeatureTypeBuilder(featureName);
            typeBuilders.put(featureName, typeBuilder);
            clearFeatureData(typeBuilder);
        }
@@ -431,7 +464,8 @@
        String typeName;
        if (element instanceof TextElement)
        {
            typeName = getFeatureBaseName() + "P";
            typeName = getFeatureBaseName() + "_P";
            typeName = typeName.toLowerCase();
            if (!featureTypes.containsKey(typeName))
            {
                featureTypes.put(typeName, createPointFeatureElement(typeName));
@@ -439,7 +473,8 @@
            return featureTypes.get(typeName);
        } else if (element instanceof TextNodeElement)
        {
            typeName = getFeatureBaseName() + "P";
            typeName = getFeatureBaseName() + "_P";
            typeName = typeName.toLowerCase();
            if (!featureTypes.containsKey(typeName))
            {
                featureTypes.put(typeName, createPointFeatureElement(typeName));
@@ -449,15 +484,17 @@
        {
            if (element instanceof ShapeElement)
            {
                typeName = getFeatureBaseName() + "R";
                typeName = getFeatureBaseName() + "_R";
                typeName = typeName.toLowerCase();
                if (!featureTypes.containsKey(typeName))
                {
                    featureTypes.put(typeName, createLineFeatureElement(typeName));
                    featureTypes.put(typeName, createPolygonFeatureElement(typeName));
                }
                return featureTypes.get(typeName);
            } else
            {
                typeName = getFeatureBaseName() + "L";
                typeName = getFeatureBaseName() + "_L";
                typeName = typeName.toLowerCase();
                if (!featureTypes.containsKey(typeName))
                {
                    featureTypes.put(typeName, createLineFeatureElement(typeName));
@@ -466,7 +503,8 @@
            }
        } else if (element instanceof LineElement)
        {
            typeName = getFeatureBaseName() + "L";
            typeName = getFeatureBaseName() + "_L";
            typeName = typeName.toLowerCase();
            if (!featureTypes.containsKey(typeName))
            {
                featureTypes.put(typeName, createLineFeatureElement(typeName));
@@ -474,15 +512,17 @@
            return featureTypes.get(typeName);
        } else if (element instanceof ComplexChainElement)
        {
            typeName = getFeatureBaseName() + "L";
            typeName = getFeatureBaseName() + "_ML";
            typeName = typeName.toLowerCase();
            if (!featureTypes.containsKey(typeName))
            {
                featureTypes.put(typeName, createLineFeatureElement(typeName));
                featureTypes.put(typeName, createMultiLineFeatureElement(typeName));
            }
            return featureTypes.get(typeName);
        } else if (element instanceof ArcElement)
        {
            typeName = getFeatureBaseName() + "A";
            typeName = getFeatureBaseName() + "_A";
            typeName = typeName.toLowerCase();
            if (!featureTypes.containsKey(typeName))
            {
                featureTypes.put(typeName, createArcFeatureElement(typeName));
@@ -490,7 +530,8 @@
            return featureTypes.get(typeName);
        } else if (element instanceof EllipseElement)
        {
            typeName = getFeatureBaseName() + "R";
            typeName = getFeatureBaseName() + "_R";
            typeName = typeName.toLowerCase();
            if (!featureTypes.containsKey(typeName))
            {
                featureTypes.put(typeName, createEllipseFeatureElement(typeName));
@@ -546,7 +587,7 @@
                            typeBuilder.getFeatureType().getDefaultGeometry().getLocalName());
                    dropTable(conn, featureName);
                    ArrayList<String> schemaTexts = createSchemaTexts(typeBuilder.getFeatureType());
                    ArrayList<String> schemaTexts = createNewSchemaTexts(typeBuilder.getFeatureType());
                    for (String stmtText : schemaTexts)
                    {
                        Statement stmt = conn.createStatement();
@@ -569,7 +610,7 @@
            try
            {
                Connection conn = targetDataStore.getConnection(Transaction.AUTO_COMMIT);
                ArrayList<String> schemaTexts = createSchemaTexts(typeBuilder.getFeatureType());
                ArrayList<String> schemaTexts = createNewSchemaTexts(typeBuilder.getFeatureType());
                for (String stmtText : schemaTexts)
                {
                    Statement stmt = conn.createStatement();
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/jobs/context/postgis/IndexDgnConvertPostGISJobContext.java
@@ -6,6 +6,7 @@
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -46,7 +47,7 @@
    static final GeometryFactory geometryFactory = new GeometryFactory();
    TWD97GeometryConverterDecorator convertDecorator = new TWD97GeometryConverterDecorator();
    private HashMap<FeatureType, ArrayList<String>> txFeaturesContext = new HashMap<FeatureType, ArrayList<String>>();
    private HashMap<FeatureType, ArrayList<Feature>> txFeaturesContext = new HashMap<FeatureType, ArrayList<Feature>>();
    private FeatureTypeBuilder typeBuilderPnt = null;
    private FeatureTypeBuilder typeBuilderRect = null;
@@ -54,6 +55,7 @@
    private FeatureType featureType2 = null;
    private boolean dropTableMode = true;
    private int accumulate = 0;
    public IndexDgnConvertPostGISJobContext(String dataPath, DataStore targetDataStore)
    {
@@ -77,10 +79,10 @@
        if (!txFeaturesContext.containsKey(feature.getFeatureType()))
        {
            txFeaturesContext.put(feature.getFeatureType(), new ArrayList<String>());
            txFeaturesContext.put(feature.getFeatureType(), new ArrayList<Feature>());
        }
        ArrayList<String> arrayList = txFeaturesContext.get(feature.getFeatureType());
        arrayList.add(makeInsertSql(feature, -1));
        ArrayList<Feature> arrayList = txFeaturesContext.get(feature.getFeatureType());
        arrayList.add(feature);
        feature = createFeature2((TextElement) element);
        if (feature == null)
@@ -92,10 +94,16 @@
        if (!txFeaturesContext.containsKey(feature.getFeatureType()))
        {
            txFeaturesContext.put(feature.getFeatureType(), new ArrayList<String>());
            txFeaturesContext.put(feature.getFeatureType(), new ArrayList<Feature>());
        }
        arrayList = txFeaturesContext.get(feature.getFeatureType());
        arrayList.add(makeInsertSql(feature, -1));
        arrayList.add(feature);
        accumulate++;
        if (accumulate > BATCHSIZE)
        {
            commitTransaction();
        }
    }
    public void startTransaction()
@@ -136,20 +144,22 @@
                FeatureType featureType = it.next();
                logger.debug("Begin Save PostGIS:" + featureType.getTypeName());
                ArrayList<String> stmtTexts = txFeaturesContext.get(featureType);
                String bindingStmt = makePrepareInsertSql(featureType, -1);
                ArrayList<Feature> features = txFeaturesContext.get(featureType);
                Connection conn = getConnection();
                boolean autoCommit = conn.getAutoCommit();
                conn.setAutoCommit(true);
                // conn.setAutoCommit(false);
                // Statement stmt = conn.createStatement();
                // int i = 0;
                for (String stmtText : stmtTexts)
                PreparedStatement pstmt = conn.prepareStatement(bindingStmt);
                for (Feature feature : features)
                {
                    currentStmt = stmtText;
                    Statement stmt = conn.createStatement();
                    // currentStmt = feature;
                    // Statement stmt = conn.createStatement();
                    try
                    {
                        stmt.execute(stmtText);
                        // stmt.execute(feature);
                        bindFeatureParameters(pstmt, feature);
                        pstmt.execute();
                    } catch (PSQLException e)
                    {
                        if (currentStmt != null)
@@ -158,19 +168,11 @@
                        }
                        logger.error(e.getServerErrorMessage());
                        logger.error(e.getMessage(), e);
                        /*
                    } finally {
                        stmt.close();
                    }
                    /*
                    if ((i % BATCHSIZE) != 0)
                    {
                        stmt.addBatch(stmtText);
                    } else {
                        stmt.addBatch(stmtText);
                        stmt.executeBatch();
                    }
                    i++;
                    */
                    }
                }
                /*
                if ((i % BATCHSIZE) != 0)
@@ -178,11 +180,15 @@
                    stmt.executeBatch();
                }
                stmt.close();
                stmtTexts.clear();
                */
                pstmt.close();
                features.clear();
                conn.setAutoCommit(autoCommit);
                logger.debug("End Save PostGIS:" + featureType.getTypeName());
            }
            accumulate = 0;
        } catch (PSQLException e)
        {
            if (currentStmt != null)
@@ -221,10 +227,22 @@
                    Connection conn = targetDataStore.getConnection(Transaction.AUTO_COMMIT);
                    if (dropTableMode)
                    {
                        try
                        {
                        dropGeometryColumn(conn, featureName,
                                typeBuilderRect.getFeatureType().getDefaultGeometry().getLocalName());
                        } catch (PSQLException e)
                        {
                            logger.debug(e.getMessage(), e);
                        }
                        try
                        {
                        dropTable(conn, featureName);
                        ArrayList<String> schemaTexts = createSchemaTexts(typeBuilderRect.getFeatureType());
                        } catch (PSQLException e)
                        {
                            logger.debug(e.getMessage(), e);
                        }
                        ArrayList<String> schemaTexts = createNewSchemaTexts(typeBuilderRect.getFeatureType());
                        for (String stmtText : schemaTexts)
                        {
                            Statement stmt = conn.createStatement();
@@ -248,7 +266,7 @@
                try
                {
                    Connection conn = targetDataStore.getConnection(Transaction.AUTO_COMMIT);
                    ArrayList<String> schemaTexts = createSchemaTexts(typeBuilderRect.getFeatureType());
                    ArrayList<String> schemaTexts = createNewSchemaTexts(typeBuilderRect.getFeatureType());
                    for (String stmtText : schemaTexts)
                    {
                        Statement stmt = conn.createStatement();
@@ -284,7 +302,7 @@
                                typeBuilderPnt.getFeatureType().getDefaultGeometry().getLocalName());
                        dropTable(conn, featureName);
                        ArrayList<String> schemaTexts = createSchemaTexts(typeBuilderPnt.getFeatureType());
                        ArrayList<String> schemaTexts = createNewSchemaTexts(typeBuilderPnt.getFeatureType());
                        for (String stmtText : schemaTexts)
                        {
                            Statement stmt = conn.createStatement();
@@ -308,7 +326,7 @@
                try
                {
                    Connection conn = targetDataStore.getConnection(Transaction.AUTO_COMMIT);
                    ArrayList<String> schemaTexts = createSchemaTexts(typeBuilderPnt.getFeatureType());
                    ArrayList<String> schemaTexts = createNewSchemaTexts(typeBuilderPnt.getFeatureType());
                    for (String stmtText : schemaTexts)
                    {
                        Statement stmt = conn.createStatement();
@@ -337,14 +355,14 @@
            String tpclid = textElement.getText();
            Envelope extent = TPCLIDConverter.convertTpclIdToEnvelope(tpclid);
            Geometry geom = geometryFactory.createLinearRing(new Coordinate[]
            Geometry geom = geometryFactory.createPolygon(geometryFactory.createLinearRing(new Coordinate[]
                    {
                            TWDDatumConverter.fromTM2ToTWD97(new Coordinate(extent.getMinX(), extent.getMinY())),
                            TWDDatumConverter.fromTM2ToTWD97(new Coordinate(extent.getMaxX(), extent.getMinY())),
                            TWDDatumConverter.fromTM2ToTWD97(new Coordinate(extent.getMaxX(), extent.getMaxY())),
                            TWDDatumConverter.fromTM2ToTWD97(new Coordinate(extent.getMinX(), extent.getMaxY())),
                            TWDDatumConverter.fromTM2ToTWD97(new Coordinate(extent.getMinX(), extent.getMinY())),
                    });
                    }), null);
            return featureType.create(new Object[]{
                    geom,
@@ -396,7 +414,7 @@
            {
                dgnname = dgnname.substring(0, i);
            }
            featureType = createFeatureElement(dgnname);
            featureType = createFeatureElement(dgnname.toLowerCase());
        }
        return createFeature(featureType, element);
    }
@@ -411,8 +429,8 @@
            {
                dgnname = dgnname.substring(0, i);
            }
            dgnname = dgnname + "P";
            featureType2 = createFeatureElement2(dgnname);
            dgnname = dgnname + "_p";
            featureType2 = createFeatureElement2(dgnname.toLowerCase());
        }
        return createFeature2(featureType2, element);
    }
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/FeatureTypeBuilderUtil.java
@@ -3,9 +3,11 @@
import org.geotools.feature.AttributeTypeFactory;
import org.geotools.feature.FeatureTypeBuilder;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.MultiLineString;
public final class FeatureTypeBuilderUtil
{
@@ -14,7 +16,7 @@
    public static FeatureTypeBuilder createNormalPointFeatureTypeBuilder(String featureName)
    {
        FeatureTypeBuilder typeBuilder = FeatureTypeBuilder.newInstance(featureName);
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("geom", Geometry.class, true));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("geom", Point.class, true));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("symcolor", String.class, false, 12, ""));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("font", Short.class, false, 1, (short) 0));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("just", Short.class, false, 1, (short) 0));
@@ -28,7 +30,27 @@
    public static FeatureTypeBuilder createNormalLineFeatureTypeBuilder(String featureName)
    {
        FeatureTypeBuilder typeBuilder = FeatureTypeBuilder.newInstance(featureName);
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("geom", Geometry.class, true));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("geom", LineString.class, true));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("symcolor", String.class, false, 12, ""));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("symweight", Short.class, false, 1, (short) 0));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("symstyle", Short.class, false, 1, (short) 0));
        return typeBuilder;
    }
    public static FeatureTypeBuilder createNormalMultiLineFeatureTypeBuilder(String featureName)
    {
        FeatureTypeBuilder typeBuilder = FeatureTypeBuilder.newInstance(featureName);
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("geom", MultiLineString.class, true));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("symcolor", String.class, false, 12, ""));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("symweight", Short.class, false, 1, (short) 0));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("symstyle", Short.class, false, 1, (short) 0));
        return typeBuilder;
    }
    public static FeatureTypeBuilder createNormalPolygonFeatureTypeBuilder(String featureName)
    {
        FeatureTypeBuilder typeBuilder = FeatureTypeBuilder.newInstance(featureName);
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("geom", Polygon.class, true));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("symcolor", String.class, false, 12, ""));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("symweight", Short.class, false, 1, (short) 0));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("symstyle", Short.class, false, 1, (short) 0));
@@ -50,7 +72,7 @@
    public static FeatureTypeBuilder createNormalEllipseFeatureTypeBuilder(String featureName)
    {
        return createNormalLineFeatureTypeBuilder(featureName);
        return createNormalPolygonFeatureTypeBuilder(featureName);
        /*
        FeatureTypeBuilder typeBuilder = FeatureTypeBuilder.newInstance(featureName);
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("geom", Geometry.class, false));
@@ -64,7 +86,7 @@
    public static FeatureTypeBuilder createNormalIndexFeatureTypeBuilder(String featureName)
    {
        FeatureTypeBuilder typeBuilder = FeatureTypeBuilder.newInstance(featureName);
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("geom", Geometry.class, true));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("geom", Polygon.class, true));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("x1", Double.class, false, 1, 0.0));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("y1", Double.class, false, 1, 0.0));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("x2", Double.class, false, 1, 0.0));
@@ -80,7 +102,7 @@
    {
        FeatureTypeBuilder typeBuilder = FeatureTypeBuilder.newInstance(featureName);
        typeBuilder = FeatureTypeBuilder.newInstance(featureName);
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("geom", Geometry.class, true));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("geom", Point.class, true));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("symcolor", String.class, false, 12, ""));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("symweight", Short.class, false, 1, (short) 0));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("symstyle", Short.class, false, 1, (short) 0));
@@ -95,7 +117,7 @@
    public static FeatureTypeBuilder createPointFeatureTypeBuilder(String featureName)
    {
        FeatureTypeBuilder typeBuilder = FeatureTypeBuilder.newInstance(featureName);
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("geom", Geometry.class, false));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("geom", Point.class, false));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("tid", Short.class, false));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("oid", Long.class, false));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("cid", Short.class, false));
@@ -115,7 +137,7 @@
    public static FeatureTypeBuilder createSymbolFeatureTypeBuilder(String featureName)
    {
        FeatureTypeBuilder typeBuilder = FeatureTypeBuilder.newInstance(featureName);
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("geom", Geometry.class, false));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("geom", Point.class, false));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("tid", Short.class, false));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("oid", Long.class, false));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("cid", Short.class, false));
@@ -134,10 +156,8 @@
    public static FeatureTypeBuilder createPolygonFeatureTypeBuilder(String featureName)
    {
        return createLineStringFeatureTypeBuilder(featureName);
        /*
        FeatureTypeBuilder typeBuilder = FeatureTypeBuilder.newInstance(featureName);
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("geom", Geometry.class, false));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("geom", Polygon.class, false));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("tid", Short.class, false));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("oid", Long.class));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("cid", Short.class, false));
@@ -147,13 +167,27 @@
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("symweight", Short.class, false));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("symstyle", Short.class, false));
        return typeBuilder;
        */
    }
    public static FeatureTypeBuilder createLineStringFeatureTypeBuilder(String featureName)
    public static FeatureTypeBuilder createLineFeatureTypeBuilder(String featureName)
    {
        FeatureTypeBuilder typeBuilder = FeatureTypeBuilder.newInstance(featureName);
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("geom", Geometry.class, false));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("geom", LineString.class, false));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("tid", Short.class, false));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("oid", Long.class, false));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("cid", Short.class, false));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("lid", Short.class, false));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("level", Short.class, false));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("symcolor", String.class, false, 12));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("symweight", Short.class, false));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("symstyle", Short.class, false));
        return typeBuilder;
    }
    public static FeatureTypeBuilder createMultiLineFeatureTypeBuilder(String featureName)
    {
        FeatureTypeBuilder typeBuilder = FeatureTypeBuilder.newInstance(featureName);
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("geom", MultiLineString.class, false));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("tid", Short.class, false));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("oid", Long.class, false));
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("cid", Short.class, false));
@@ -167,7 +201,7 @@
    public static FeatureTypeBuilder createEllipseFeatureTypeBuilder(String featureName)
    {
        return createLineStringFeatureTypeBuilder(featureName);
        return createPolygonFeatureTypeBuilder(featureName);
        /*
        FeatureTypeBuilder typeBuilder = FeatureTypeBuilder.newInstance(featureName);
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("geom", Geometry.class, false));
@@ -185,7 +219,7 @@
    public static FeatureTypeBuilder createArcFeatureTypeBuilder(String featureName)
    {
        return createLineStringFeatureTypeBuilder(featureName);
        return createLineFeatureTypeBuilder(featureName);
        /*
        FeatureTypeBuilder typeBuilder = FeatureTypeBuilder.newInstance(featureName);
        typeBuilder.addType(AttributeTypeFactory.newAttributeType("geom", Geometry.class, false));
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/postjts/JTSShape.java
New file
@@ -0,0 +1,339 @@
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);
        }
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/postjts/JtsBinaryParser.java
New file
@@ -0,0 +1,287 @@
/*
 * JtsBinaryParser.java
 *
 * Binary Parser for JTS - relies on org.postgis V1.0.0+ package.
 *
 * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation, either version 2.1 of the License.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or visit the web at
 * http://www.gnu.org.
 *
 * $Id$
 */
package com.ximple.eofms.util.postjts;
import org.postgis.binary.ByteGetter;
import org.postgis.binary.ByteGetter.BinaryByteGetter;
import org.postgis.binary.ByteGetter.StringByteGetter;
import org.postgis.binary.ValueGetter;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryCollection;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.MultiLineString;
import com.vividsolutions.jts.geom.MultiPoint;
import com.vividsolutions.jts.geom.MultiPolygon;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
import com.vividsolutions.jts.geom.impl.PackedCoordinateSequence;
/**
 * Parse binary representation of geometries. Currently, only text rep (hexed)
 * implementation is tested.
 * <p/>
 * It should be easy to add char[] and CharSequence ByteGetter instances,
 * although the latter one is not compatible with older jdks.
 * <p/>
 * I did not implement real unsigned 32-bit integers or emulate them with long,
 * as both java Arrays and Strings currently can have only 2^31-1 elements
 * (bytes), so we cannot even get or build Geometries with more than approx.
 * 2^28 coordinates (8 bytes each).
 *
 * @author Markus Schaber, markus.schaber@logix-tt.com
 */
public class JtsBinaryParser
{
    /**
     * Get the appropriate ValueGetter for my endianness
     *
     * @param bytes The appropriate Byte Getter
     * @return the ValueGetter
     */
    public static ValueGetter valueGetterForEndian(ByteGetter bytes)
    {
        if (bytes.get(0) == ValueGetter.XDR.NUMBER)
        { // XDR
            return new ValueGetter.XDR(bytes);
        } else if (bytes.get(0) == ValueGetter.NDR.NUMBER)
        {
            return new ValueGetter.NDR(bytes);
        } else
        {
            throw new IllegalArgumentException("Unknown Endian type:" + bytes.get(0));
        }
    }
    /**
     * Parse a hex encoded geometry
     */
    public Geometry parse(String value)
    {
        StringByteGetter bytes = new ByteGetter.StringByteGetter(value);
        return parseGeometry(valueGetterForEndian(bytes));
    }
    /**
     * Parse a binary encoded geometry.
     */
    public Geometry parse(byte[] value)
    {
        BinaryByteGetter bytes = new ByteGetter.BinaryByteGetter(value);
        return parseGeometry(valueGetterForEndian(bytes));
    }
    /**
     * Parse a geometry starting at offset.
     */
    protected Geometry parseGeometry(ValueGetter data)
    {
        return parseGeometry(data, 0, false);
    }
    /**
     * Parse with a known geometry factory
     */
    protected Geometry parseGeometry(ValueGetter data, int srid, boolean inheritSrid)
    {
        byte endian = data.getByte(); // skip and test endian flag
        if (endian != data.endian)
        {
            throw new IllegalArgumentException("Endian inconsistency!");
        }
        int typeword = data.getInt();
        int realtype = typeword & 0x1FFFFFFF; // cut off high flag bits
        boolean haveZ = (typeword & 0x80000000) != 0;
        boolean haveM = (typeword & 0x40000000) != 0;
        boolean haveS = (typeword & 0x20000000) != 0;
        if (haveS)
        {
            int newsrid = data.getInt();
            if (inheritSrid && newsrid != srid)
            {
                throw new IllegalArgumentException("Inconsistent srids in complex geometry: " + srid + ", " + newsrid);
            } else
            {
                srid = newsrid;
            }
        } else if (!inheritSrid)
        {
            srid = -1;
        }
        Geometry result;
        switch (realtype)
        {
        case org.postgis.Geometry.POINT:
            result = parsePoint(data, haveZ, haveM);
            break;
        case org.postgis.Geometry.LINESTRING:
            result = parseLineString(data, haveZ, haveM);
            break;
        case org.postgis.Geometry.POLYGON:
            result = parsePolygon(data, haveZ, haveM, srid);
            break;
        case org.postgis.Geometry.MULTIPOINT:
            result = parseMultiPoint(data, srid);
            break;
        case org.postgis.Geometry.MULTILINESTRING:
            result = parseMultiLineString(data, srid);
            break;
        case org.postgis.Geometry.MULTIPOLYGON:
            result = parseMultiPolygon(data, srid);
            break;
        case org.postgis.Geometry.GEOMETRYCOLLECTION:
            result = parseCollection(data, srid);
            break;
        default:
            throw new IllegalArgumentException("Unknown Geometry Type!");
        }
        result.setSRID(srid);
        return result;
    }
    private Point parsePoint(ValueGetter data, boolean haveZ, boolean haveM)
    {
        double X = data.getDouble();
        double Y = data.getDouble();
        Point result;
        if (haveZ)
        {
            double Z = data.getDouble();
            result = JtsGeometry.geofac.createPoint(new Coordinate(X, Y, Z));
        } else
        {
            result = JtsGeometry.geofac.createPoint(new Coordinate(X, Y));
        }
        if (haveM)
        { // skip M value
            data.getDouble();
        }
        return result;
    }
    /**
     * Parse an Array of "full" Geometries
     */
    private void parseGeometryArray(ValueGetter data, Geometry[] container, int srid)
    {
        for (int i = 0; i < container.length; i++)
        {
            container[i] = parseGeometry(data, srid, true);
        }
    }
    /**
     * Parse an Array of "slim" Points (without endianness and type, part of
     * LinearRing and Linestring, but not MultiPoint!
     *
     * @param haveZ
     * @param haveM
     */
    private CoordinateSequence parseCS(ValueGetter data, boolean haveZ, boolean haveM)
    {
        int count = data.getInt();
        int dims = haveZ ? 3 : 2;
        CoordinateSequence cs = new PackedCoordinateSequence.Double(count, dims);
        for (int i = 0; i < count; i++)
        {
            for (int d = 0; d < dims; d++)
            {
                cs.setOrdinate(i, d, data.getDouble());
            }
            if (haveM)
            { // skip M value
                data.getDouble();
            }
        }
        return cs;
    }
    private MultiPoint parseMultiPoint(ValueGetter data, int srid)
    {
        Point[] points = new Point[data.getInt()];
        parseGeometryArray(data, points, srid);
        return JtsGeometry.geofac.createMultiPoint(points);
    }
    private LineString parseLineString(ValueGetter data, boolean haveZ, boolean haveM)
    {
        return JtsGeometry.geofac.createLineString(parseCS(data, haveZ, haveM));
    }
    private LinearRing parseLinearRing(ValueGetter data, boolean haveZ, boolean haveM)
    {
        return JtsGeometry.geofac.createLinearRing(parseCS(data, haveZ, haveM));
    }
    private Polygon parsePolygon(ValueGetter data, boolean haveZ, boolean haveM, int srid)
    {
        int holecount = data.getInt() - 1;
        LinearRing[] rings = new LinearRing[holecount];
        LinearRing shell = parseLinearRing(data, haveZ, haveM);
        shell.setSRID(srid);
        for (int i = 0; i < holecount; i++)
        {
            rings[i] = parseLinearRing(data, haveZ, haveM);
            rings[i].setSRID(srid);
        }
        return JtsGeometry.geofac.createPolygon(shell, rings);
    }
    private MultiLineString parseMultiLineString(ValueGetter data, int srid)
    {
        int count = data.getInt();
        LineString[] strings = new LineString[count];
        parseGeometryArray(data, strings, srid);
        return JtsGeometry.geofac.createMultiLineString(strings);
    }
    private MultiPolygon parseMultiPolygon(ValueGetter data, int srid)
    {
        int count = data.getInt();
        Polygon[] polys = new Polygon[count];
        parseGeometryArray(data, polys, srid);
        return JtsGeometry.geofac.createMultiPolygon(polys);
    }
    private GeometryCollection parseCollection(ValueGetter data, int srid)
    {
        int count = data.getInt();
        Geometry[] geoms = new Geometry[count];
        parseGeometryArray(data, geoms, srid);
        return JtsGeometry.geofac.createGeometryCollection(geoms);
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/postjts/JtsBinaryWriter.java
New file
@@ -0,0 +1,469 @@
/*
 * JtsBinaryWriter.java
 *
 * PostGIS extension for PostgreSQL JDBC driver - Binary Writer
 *
 * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation, either version 2.1 of the License.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or visit the web at
 * http://www.gnu.org.
 *
 * $Id$
 */
package com.ximple.eofms.util.postjts;
import org.postgis.binary.ByteSetter;
import org.postgis.binary.ValueSetter;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryCollection;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.MultiLineString;
import com.vividsolutions.jts.geom.MultiPoint;
import com.vividsolutions.jts.geom.MultiPolygon;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
/**
 * Create binary representation of geometries. Currently, only text rep (hexed)
 * implementation is tested. Supports only 2 dimensional geometries.
 * <p/>
 * It should be easy to add char[] and CharSequence ByteGetter instances,
 * although the latter one is not compatible with older jdks.
 * <p/>
 * I did not implement real unsigned 32-bit integers or emulate them with long,
 * as both java Arrays and Strings currently can have only 2^31-1 elements
 * (bytes), so we cannot even get or build Geometries with more than approx.
 * 2^28 coordinates (8 bytes each).
 *
 * @author markus.schaber@logi-track.com
 */
public class JtsBinaryWriter
{
    /**
     * Get the appropriate ValueGetter for my endianness
     *
     * @param bytes The appropriate Byte Getter
     * @return the ValueGetter
     */
    public static ValueSetter valueSetterForEndian(ByteSetter bytes, byte endian)
    {
        if (endian == ValueSetter.XDR.NUMBER)
        { // XDR
            return new ValueSetter.XDR(bytes);
        } else if (endian == ValueSetter.NDR.NUMBER)
        {
            return new ValueSetter.NDR(bytes);
        } else
        {
            throw new IllegalArgumentException("Unknown Endian type:" + endian);
        }
    }
    /**
     * Write a hex encoded geometry
     * <p/>
     * Currently, geometries with more than 2 dimensions and measures are not
     * cleanly supported, but SRID is honored.
     */
    public String writeHexed(Geometry geom, byte REP)
    {
        int length = estimateBytes(geom);
        ByteSetter.StringByteSetter bytes = new ByteSetter.StringByteSetter(length);
        writeGeometry(geom, valueSetterForEndian(bytes, REP));
        return bytes.result();
    }
    public String writeHexed(Geometry geom)
    {
        return writeHexed(geom, ValueSetter.NDR.NUMBER);
    }
    /**
     * Write a binary encoded geometry.
     * <p/>
     * Currently, geometries with more than 2 dimensions and measures are not
     * cleanly supported, but SRID is honored.
     */
    public byte[] writeBinary(Geometry geom, byte REP)
    {
        int length = estimateBytes(geom);
        ByteSetter.BinaryByteSetter bytes = new ByteSetter.BinaryByteSetter(length);
        writeGeometry(geom, valueSetterForEndian(bytes, REP));
        return bytes.result();
    }
    public byte[] writeBinary(Geometry geom)
    {
        return writeBinary(geom, ValueSetter.NDR.NUMBER);
    }
    /**
     * Parse a geometry starting at offset.
     */
    protected void writeGeometry(Geometry geom, ValueSetter dest)
    {
        final int dimension;
        if (geom == null)
        {
            throw new NullPointerException();
        } else if (geom.isEmpty())
        {
            // don't set any flag bits
            dimension = 0;
        } else
        {
            dimension = getCoordDim(geom);
            if (dimension < 2 || dimension > 4)
            {
                throw new IllegalArgumentException("Unsupported geometry dimensionality: " + dimension);
            }
        }
        // write endian flag
        dest.setByte(dest.endian);
        // write typeword
        final int plaintype = getWKBType(geom);
        int typeword = plaintype;
        if (dimension == 3 || dimension == 4)
        {
            typeword |= 0x80000000;
        }
        if (dimension == 4)
        {
            typeword |= 0x40000000;
        }
        final boolean haveSrid = checkSrid(geom);
        if (haveSrid)
        {
            typeword |= 0x20000000;
        }
        dest.setInt(typeword);
        if (haveSrid)
        {
            dest.setInt(geom.getSRID());
        }
        switch (plaintype)
        {
        case org.postgis.Geometry.POINT:
            writePoint((Point) geom, dest);
            break;
        case org.postgis.Geometry.LINESTRING:
            writeLineString((LineString) geom, dest);
            break;
        case org.postgis.Geometry.POLYGON:
            writePolygon((Polygon) geom, dest);
            break;
        case org.postgis.Geometry.MULTIPOINT:
            writeMultiPoint((MultiPoint) geom, dest);
            break;
        case org.postgis.Geometry.MULTILINESTRING:
            writeMultiLineString((MultiLineString) geom, dest);
            break;
        case org.postgis.Geometry.MULTIPOLYGON:
            writeMultiPolygon((MultiPolygon) geom, dest);
            break;
        case org.postgis.Geometry.GEOMETRYCOLLECTION:
            writeCollection((GeometryCollection) geom, dest);
            break;
        default:
            throw new IllegalArgumentException("Unknown Geometry Type: " + plaintype);
        }
    }
    public static int getWKBType(Geometry geom)
    {
        // We always write emtpy geometries as emtpy collections - for OpenGIS
        // conformance
        if (geom.isEmpty())
        {
            return org.postgis.Geometry.GEOMETRYCOLLECTION;
        } else if (geom instanceof Point)
        {
            return org.postgis.Geometry.POINT;
        } else if (geom instanceof com.vividsolutions.jts.geom.LineString)
        {
            return org.postgis.Geometry.LINESTRING;
        } else if (geom instanceof com.vividsolutions.jts.geom.Polygon)
        {
            return org.postgis.Geometry.POLYGON;
        } else if (geom instanceof MultiPoint)
        {
            return org.postgis.Geometry.MULTIPOINT;
        } else if (geom instanceof MultiLineString)
        {
            return org.postgis.Geometry.MULTILINESTRING;
        } else if (geom instanceof com.vividsolutions.jts.geom.MultiPolygon)
        {
            return org.postgis.Geometry.MULTIPOLYGON;
        }
        if (geom instanceof com.vividsolutions.jts.geom.GeometryCollection)
        {
            return org.postgis.Geometry.GEOMETRYCOLLECTION;
        } else
        {
            throw new IllegalArgumentException("Unknown Geometry Type: " + geom.getClass().getName());
        }
    }
    /**
     * Writes a "slim" Point (without endiannes, srid ant type, only the
     * ordinates and measure. Used by writeGeometry.
     */
    private void writePoint(Point geom, ValueSetter dest)
    {
        writeCoordinates(geom.getCoordinateSequence(), getCoordDim(geom), dest);
    }
    /**
     * Write a Coordinatesequence, part of LinearRing and Linestring, but not
     * MultiPoint!
     */
    private void writeCoordinates(CoordinateSequence seq, int dims, ValueSetter dest)
    {
        for (int i = 0; i < seq.size(); i++)
        {
            for (int d = 0; d < dims; d++)
            {
                dest.setDouble(seq.getOrdinate(i, d));
            }
        }
    }
    private void writeMultiPoint(MultiPoint geom, ValueSetter dest)
    {
        dest.setInt(geom.getNumPoints());
        for (int i = 0; i < geom.getNumPoints(); i++)
        {
            writeGeometry(geom.getGeometryN(i), dest);
        }
    }
    private void writeLineString(LineString geom, ValueSetter dest)
    {
        dest.setInt(geom.getNumPoints());
        writeCoordinates(geom.getCoordinateSequence(), getCoordDim(geom), dest);
    }
    private void writePolygon(Polygon geom, ValueSetter dest)
    {
        dest.setInt(geom.getNumInteriorRing() + 1);
        writeLineString(geom.getExteriorRing(), dest);
        for (int i = 0; i < geom.getNumInteriorRing(); i++)
        {
            writeLineString(geom.getInteriorRingN(i), dest);
        }
    }
    private void writeMultiLineString(MultiLineString geom, ValueSetter dest)
    {
        writeGeometryArray(geom, dest);
    }
    private void writeMultiPolygon(MultiPolygon geom, ValueSetter dest)
    {
        writeGeometryArray(geom, dest);
    }
    private void writeCollection(GeometryCollection geom, ValueSetter dest)
    {
        writeGeometryArray(geom, dest);
    }
    private void writeGeometryArray(Geometry geom, ValueSetter dest)
    {
        dest.setInt(geom.getNumGeometries());
        for (int i = 0; i < geom.getNumGeometries(); i++)
        {
            writeGeometry(geom.getGeometryN(i), dest);
        }
    }
    /**
     * Estimate how much bytes a geometry will need in WKB.
     */
    protected int estimateBytes(Geometry geom)
    {
        int result = 0;
        // write endian flag
        result += 1;
        // write typeword
        result += 4;
        if (checkSrid(geom))
        {
            result += 4;
        }
        switch (getWKBType(geom))
        {
        case org.postgis.Geometry.POINT:
            result += estimatePoint((Point) geom);
            break;
        case org.postgis.Geometry.LINESTRING:
            result += estimateLineString((LineString) geom);
            break;
        case org.postgis.Geometry.POLYGON:
            result += estimatePolygon((Polygon) geom);
            break;
        case org.postgis.Geometry.MULTIPOINT:
            result += estimateMultiPoint((MultiPoint) geom);
            break;
        case org.postgis.Geometry.MULTILINESTRING:
            result += estimateMultiLineString((MultiLineString) geom);
            break;
        case org.postgis.Geometry.MULTIPOLYGON:
            result += estimateMultiPolygon((MultiPolygon) geom);
            break;
        case org.postgis.Geometry.GEOMETRYCOLLECTION:
            result += estimateCollection((GeometryCollection) geom);
            break;
        default:
            throw new IllegalArgumentException("Unknown Geometry Type: " + getWKBType(geom));
        }
        return result;
    }
    private boolean checkSrid(Geometry geom)
    {
        final int srid = geom.getSRID();
        // SRID is default 0 with jts geometries
        return (srid != -1) && (srid != 0);
    }
    private int estimatePoint(Point geom)
    {
        return 8 * getCoordDim(geom);
    }
    /**
     * Write an Array of "full" Geometries
     */
    private int estimateGeometryArray(Geometry container)
    {
        int result = 0;
        for (int i = 0; i < container.getNumGeometries(); i++)
        {
            result += estimateBytes(container.getGeometryN(i));
        }
        return result;
    }
    /**
     * Estimate an array of "fat" Points
     */
    private int estimateMultiPoint(MultiPoint geom)
    {
        // int size
        int result = 4;
        if (geom.getNumGeometries() > 0)
        {
            // We can shortcut here, compared to estimateGeometryArray, as all
            // subgeoms have the same fixed size
            result += geom.getNumGeometries() * estimateBytes(geom.getGeometryN(0));
        }
        return result;
    }
    private int estimateLineString(LineString geom)
    {
        if (geom == null || geom.getNumGeometries() == 0)
        {
            return 0;
        } else
        {
            return 4 + 8 * getCoordSequenceDim(geom.getCoordinateSequence()) * geom.getCoordinateSequence().size();
        }
    }
    private int estimatePolygon(Polygon geom)
    {
        // int length
        int result = 4;
        result += estimateLineString(geom.getExteriorRing());
        for (int i = 0; i < geom.getNumInteriorRing(); i++)
        {
            result += estimateLineString(geom.getInteriorRingN(i));
        }
        return result;
    }
    private int estimateMultiLineString(MultiLineString geom)
    {
        // 4-byte count + subgeometries
        return 4 + estimateGeometryArray(geom);
    }
    private int estimateMultiPolygon(MultiPolygon geom)
    {
        // 4-byte count + subgeometries
        return 4 + estimateGeometryArray(geom);
    }
    private int estimateCollection(GeometryCollection geom)
    {
        // 4-byte count + subgeometries
        return 4 + estimateGeometryArray(geom);
    }
    public static final int getCoordDim(Geometry geom)
    {
        if (geom.isEmpty())
        {
            return 0;
        }
        if (geom instanceof Point)
        {
            return getCoordSequenceDim(((Point) geom).getCoordinateSequence());
        } else if (geom instanceof LineString)
        {
            return getCoordSequenceDim(((LineString) geom).getCoordinateSequence());
        } else if (geom instanceof Polygon)
        {
            return getCoordSequenceDim(((Polygon) geom).getExteriorRing().getCoordinateSequence());
        } else
        {
            return getCoordDim(geom.getGeometryN(0));
        }
    }
    public static final int getCoordSequenceDim(CoordinateSequence coords)
    {
        if (coords == null || coords.size() == 0)
            return 0;
        // JTS has a really strange way to handle dimensions!
        // Just have a look at PackedCoordinateSequence and
        // CoordinateArraySequence
        int dimensions = coords.getDimension();
        if (dimensions == 3)
        {
            // CoordinateArraySequence will always return 3, so we have to
            // check, if
            // the third ordinate contains NaN, then the geom is actually
            // 2-dimensional
            return Double.isNaN(coords.getOrdinate(0, CoordinateSequence.Z)) ? 2 : 3;
        } else
        {
            return dimensions;
        }
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/postjts/JtsGeometry.java
New file
@@ -0,0 +1,187 @@
/*
 * JtsGeometry.java
 *
 * Wrapper for PostgreSQL JDBC driver to allow transparent reading and writing
 * of JTS geometries
 *
 * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation, either version 2.1 of the License.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or visit the web at
 * http://www.gnu.org.
 *
 * $Id$
 */
package com.ximple.eofms.util.postjts;
import java.sql.SQLException;
import org.postgresql.util.PGobject;
import com.vividsolutions.jts.geom.CoordinateSequenceFactory;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryCollection;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Polygon;
import com.vividsolutions.jts.geom.PrecisionModel;
import com.vividsolutions.jts.geom.impl.PackedCoordinateSequenceFactory;
import com.vividsolutions.jts.io.WKTReader;
/**
 * JTS Geometry SQL wrapper. Supports PostGIS 1.x (lwgeom hexwkb) for writing
 * and both PostGIS 0.x (EWKT) and 1.x (lwgeom hexwkb) for reading.
 *
 * @author Markus Schaber
 */
public class JtsGeometry extends PGobject
{
    /* JDK 1.5 Serialization */
    private static final long serialVersionUID = 0x100;
    Geometry geom;
    final static JtsBinaryParser bp = new JtsBinaryParser();
    final static JtsBinaryWriter bw = new JtsBinaryWriter();
    final static PrecisionModel prec = new PrecisionModel();
    final static CoordinateSequenceFactory csfac = PackedCoordinateSequenceFactory.DOUBLE_FACTORY;
    final static GeometryFactory geofac = new GeometryFactory(prec, 0, csfac);
    static final WKTReader reader = new WKTReader(geofac);
    /**
     * Constructor called by JDBC drivers
     */
    public JtsGeometry()
    {
        setType("geometry");
    }
    public JtsGeometry(Geometry geom)
    {
        this();
        this.geom = geom;
    }
    public JtsGeometry(String value) throws SQLException
    {
        this();
        setValue(value);
    }
    public void setValue(String value) throws SQLException
    {
        geom = geomFromString(value);
    }
    public static Geometry geomFromString(String value) throws SQLException
    {
        try
        {
            value = value.trim();
            if (value.startsWith("00") || value.startsWith("01"))
            {
                return bp.parse(value);
            } else
            {
                Geometry result;
                // no srid := 0 in JTS world
                int srid = 0;
                // break up geometry into srid and wkt
                if (value.startsWith("SRID="))
                {
                    String[] temp = value.split(";");
                    value = temp[1].trim();
                    srid = Integer.parseInt(temp[0].substring(5));
                }
                result = reader.read(value);
                setSridRecurse(result, srid);
                return result;
            }
        } catch (Exception E)
        {
            E.printStackTrace();
            throw new SQLException("Error parsing SQL data:" + E);
        }
    }
    /**
     * Recursively set a srid for the geometry and all subgeometries
     */
    public static void setSridRecurse(final Geometry geom, final int srid)
    {
        geom.setSRID(srid);
        if (geom instanceof GeometryCollection)
        {
            final int subcnt = geom.getNumGeometries();
            for (int i = 0; i < subcnt; i++)
            {
                setSridRecurse(geom.getGeometryN(i), srid);
            }
        } else if (geom instanceof Polygon)
        {
            Polygon poly = (Polygon) geom;
            poly.getExteriorRing().setSRID(srid);
            final int subcnt = poly.getNumInteriorRing();
            for (int i = 0; i < subcnt; i++)
            {
                poly.getInteriorRingN(i).setSRID(srid);
            }
        }
    }
    public Geometry getGeometry()
    {
        return geom;
    }
    public String toString()
    {
        return geom.toString();
    }
    public String getValue()
    {
        return bw.writeHexed(getGeometry());
    }
    public Object clone()
    {
        JtsGeometry obj = new JtsGeometry(geom);
        obj.setType(type);
        return obj;
    }
    public boolean equals(Object obj)
    {
        if ((obj != null) && (obj instanceof JtsGeometry))
        {
            Geometry other = ((JtsGeometry) obj).geom;
            if (this.geom == other)
            { // handles identity as well as both
                // ==null
                return true;
            } else if (this.geom != null && other != null)
            {
                return other.equals(this.geom);
            }
        }
        return false;
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/postjts/JtsGisWrapper.java
New file
@@ -0,0 +1,173 @@
/*
 * JtsWrapper.java
 *
 * Allows transparent usage of JTS Geometry classes via PostgreSQL JDBC driver
 * connected to a PostGIS enabled PostgreSQL server.
 *
 * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation, either version 2.1 of the License.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or visit the web at
 * http://www.gnu.org.
 *
 * $Id$
 */
package com.ximple.eofms.util.postjts;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import org.postgresql.Driver;
import org.postgresql.PGConnection;
/**
 * JtsGisWrapper
 * <p/>
 * Wraps the PostGreSQL Driver to add the JTS/PostGIS Object Classes.
 * <p/>
 * This method currently works with J2EE DataSource implementations, and with
 * DriverManager framework.
 * <p/>
 * Simply replace the "jdbc:postgresql:" with a "jdbc:postgresql_JTS" in the
 * jdbc URL.
 *
 * @author markus.schaber@logix-tt.com
 */
public class JtsGisWrapper extends Driver
{
    private static final String POSTGRES_PROTOCOL = "jdbc:postgresql:";
    private static final String POSTGIS_PROTOCOL = "jdbc:postgresql_JTS:";
    public static final String REVISION = "$Revision: 1977 $";
    public JtsGisWrapper()
    {
        super();
    }
    static
    {
        try
        {
            // Analogy to org.postgresql.Driver
            java.sql.DriverManager.registerDriver(new JtsGisWrapper());
        } catch (SQLException e)
        {
            e.printStackTrace();
        }
    }
    /**
     * Creates a postgresql connection, and then adds the PostGIS data types to
     * it calling addpgtypes()
     *
     * @param url  the URL of the database to connect to
     * @param info a list of arbitrary tag/value pairs as connection arguments
     * @return a connection to the URL or null if it isnt us
     * @throws SQLException if a database access error occurs
     * @see java.sql.Driver#connect
     * @see org.postgresql.Driver
     */
    public java.sql.Connection connect(String url, Properties info) throws SQLException
    {
        url = mangleURL(url);
        Connection result = super.connect(url, info);
        addGISTypes((PGConnection) result);
        return result;
    }
    /**
     * adds the JTS/PostGIS Data types to a PG Connection.
     *
     * @param pgconn
     * @throws SQLException
     */
    public static void addGISTypes(PGConnection pgconn) throws SQLException
    {
        pgconn.addDataType("geometry", JtsGeometry.class);
        pgconn.addDataType("box3d", org.postgis.PGbox3d.class);
        pgconn.addDataType("box2d", org.postgis.PGbox2d.class);
    }
    /**
     * Mangles the PostGIS URL to return the original PostGreSQL URL
     * @param url url
     * @return string
     * @throws java.sql.SQLException error
     */
    public static String mangleURL(String url) throws SQLException
    {
        if (url.startsWith(POSTGIS_PROTOCOL))
        {
            return POSTGRES_PROTOCOL + url.substring(POSTGIS_PROTOCOL.length());
        } else
        {
            throw new SQLException("Unknown protocol or subprotocol in url " + url);
        }
    }
    /**
     * Returns true if the driver thinks it can open a connection to the given
     * URL. Typically, drivers will return true if they understand the
     * subprotocol specified in the URL and false if they don't. Our protocols
     * start with jdbc:postgresql_postGIS:
     *
     * @param url the URL of the driver
     * @return true if this driver accepts the given URL
     * @throws SQLException if a database-access error occurs (Dont know why
     *                      it would *shrug*)
     * @see java.sql.Driver#acceptsURL
     */
    public boolean acceptsURL(String url) throws SQLException
    {
        try
        {
            url = mangleURL(url);
        } catch (SQLException e)
        {
            return false;
        }
        return super.acceptsURL(url);
    }
    /**
     * Gets the underlying drivers major version number
     *
     * @return the drivers major version number
     */
    public int getMajorVersion()
    {
        return super.getMajorVersion();
    }
    /**
     * Get the underlying drivers minor version number
     *
     * @return the drivers minor version number
     */
    public int getMinorVersion()
    {
        return super.getMinorVersion();
    }
    /**
     * Returns our own CVS version plus postgres Version
     */
    public static String getVersion()
    {
        return "JtsGisWrapper " + REVISION + ", wrapping " + Driver.getVersion();
    }
}
xdgnjobs/ximple-spatialjob/src/main/java/com/ximple/eofms/util/postjts/JtsWrapper.java
New file
@@ -0,0 +1,180 @@
/*
 * JtsWrapper.java
 *
 * Allows transparent usage of JTS Geometry classes via PostgreSQL JDBC driver
 * connected to a PostGIS enabled PostgreSQL server.
 *
 * (C) 2005 Markus Schaber, markus.schaber@logix-tt.com
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation, either version 2.1 of the License.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or visit the web at
 * http://www.gnu.org.
 *
 * $Id$
 */
package com.ximple.eofms.util.postjts;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.postgresql.Driver;
import org.postgresql.PGConnection;
/**
 * DriverWrapper
 * <p/>
 * Wraps the PostGreSQL Driver to add the JTS/PostGIS Object Classes.
 * <p/>
 * This method currently works with J2EE DataSource implementations, and with
 * DriverManager framework.
 * <p/>
 * Simply replace the "jdbc:postgresql:" with a "jdbc:postgres_jts:" in the jdbc
 * URL.
 * <p/>
 * When using the drivermanager, you need to initialize JtsWrapper instead of
 * (or in addition to) org.postgresql.Driver. When using a J2EE DataSource
 * implementation, set the driver class property in the datasource config, the
 * following works for jboss:
 * <p/>
 * &lt;driver-class&gt;org.postgis.jts.PostGisWrapper&lt;/driver-class&gt;
 *
 * @author markus.schaber@logix-tt.com
 */
public class JtsWrapper extends Driver
{
    protected static final Logger logger = Logger.getLogger("org.postgis.DriverWrapper");
    private static final String POSTGRES_PROTOCOL = "jdbc:postgresql:";
    private static final String POSTGIS_PROTOCOL = "jdbc:postgres_jts:";
    public static final String REVISION = "$Revision: 2570 $";
    public JtsWrapper()
    {
        super();
    }
    static
    {
        try
        {
            // Try to register ourself to the DriverManager
            java.sql.DriverManager.registerDriver(new JtsWrapper());
        } catch (SQLException e)
        {
            logger.log(Level.WARNING, "Error registering PostgreSQL Jts Wrapper Driver", e);
        }
    }
    /**
     * Creates a postgresql connection, and then adds the JTS GIS data types to
     * it calling addpgtypes()
     *
     * @param url  the URL of the database to connect to
     * @param info a list of arbitrary tag/value pairs as connection arguments
     * @return a connection to the URL or null if it isnt us
     * @throws SQLException if a database access error occurs
     * @see java.sql.Driver#connect
     * @see org.postgresql.Driver
     */
    public java.sql.Connection connect(String url, Properties info) throws SQLException
    {
        url = mangleURL(url);
        Connection result = super.connect(url, info);
        addGISTypes((PGConnection) result);
        return result;
    }
    /**
     * adds the JTS/PostGIS Data types to a PG Connection.
     *
     * @param pgconn  postgres connection
     * @throws SQLException error
     */
    public static void addGISTypes(PGConnection pgconn) throws SQLException
    {
        pgconn.addDataType("geometry", JtsGeometry.class);
    }
    /**
     * Mangles the PostGIS URL to return the original PostGreSQL URL
     * @param url url
     * @return string
     * @throws java.sql.SQLException erroe
     */
    public static String mangleURL(String url) throws SQLException
    {
        if (url.startsWith(POSTGIS_PROTOCOL))
        {
            return POSTGRES_PROTOCOL + url.substring(POSTGIS_PROTOCOL.length());
        } else
        {
            throw new SQLException("Unknown protocol or subprotocol in url " + url);
        }
    }
    /**
     * Check whether the driver thinks he can handle the given URL.
     *
     * @param url the URL of the driver
     * @return true if this driver accepts the given URL
     * @throws SQLException Passed through from the underlying PostgreSQL
     *                      driver, should not happen.
     * @see java.sql.Driver#acceptsURL
     */
    public boolean acceptsURL(String url) throws SQLException
    {
        try
        {
            url = mangleURL(url);
        } catch (SQLException e)
        {
            return false;
        }
        return super.acceptsURL(url);
    }
    /**
     * Gets the underlying drivers major version number
     *
     * @return the drivers major version number
     */
    public int getMajorVersion()
    {
        return super.getMajorVersion();
    }
    /**
     * Get the underlying drivers minor version number
     *
     * @return the drivers minor version number
     */
    public int getMinorVersion()
    {
        return super.getMinorVersion();
    }
    /**
     * Returns our own CVS version plus postgres Version
     * @return version
     */
    public static String getVersion()
    {
        return "JtsGisWrapper " + REVISION + ", wrapping " + Driver.getVersion();
    }
}