| 3,7 → 3,7 |
| * |
| * This file is part of Hibernate Spatial, an extension to the |
| * hibernate ORM solution for geographic data. |
| * |
| * |
| * Copyright © 2007 Geovise BVBA |
| * Copyright © 2007 K.U. Leuven LRD, Spatial Applications Division, Belgium |
| * |
| 28,22 → 28,10 |
| */ |
| package org.hibernatespatial.oracle; |
| |
| import java.lang.reflect.Array; |
| import java.sql.Connection; |
| import java.sql.PreparedStatement; |
| import java.sql.SQLException; |
| import java.sql.Types; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import com.vividsolutions.jts.algorithm.CGAlgorithms; |
| import com.vividsolutions.jts.geom.*; |
| import oracle.jdbc.driver.OracleConnection; |
| import oracle.sql.ARRAY; |
| import oracle.sql.ArrayDescriptor; |
| import oracle.sql.Datum; |
| import oracle.sql.NUMBER; |
| import oracle.sql.STRUCT; |
| import oracle.sql.StructDescriptor; |
| |
| import oracle.sql.*; |
| import org.hibernate.HibernateException; |
| import org.hibernatespatial.AbstractDBGeometryType; |
| import org.hibernatespatial.Circle; |
| 52,1532 → 40,1522 |
| import org.hibernatespatial.mgeom.MCoordinate; |
| import org.hibernatespatial.mgeom.MLineString; |
| |
| import com.vividsolutions.jts.algorithm.CGAlgorithms; |
| 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 java.sql.*; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| /** |
| * Implements Oracle 9i/10g/11g SDO_GEOMETRY type. |
| * |
| * |
| * @author Karel Maesen |
| */ |
| public class SDOGeometryType extends AbstractDBGeometryType { |
| |
| private static final int[] geometryTypes = new int[] { Types.STRUCT }; |
| private static final int[] geometryTypes = new int[]{Types.STRUCT}; |
| |
| private static String SQL_TYPE_NAME = "MDSYS.SDO_GEOMETRY"; |
| private static String SQL_TYPE_NAME = "MDSYS.SDO_GEOMETRY"; |
| |
| private static ConnectionFinder connectionFinder = new DefaultConnectionFinder(); |
| private static ConnectionFinder connectionFinder = new DefaultConnectionFinder(); |
| |
| static ConnectionFinder getConnectionFinder() { |
| return connectionFinder; |
| } |
| static ConnectionFinder getConnectionFinder() { |
| return connectionFinder; |
| } |
| |
| static void setConnectionFinder(ConnectionFinder finder) { |
| connectionFinder = finder; |
| } |
| static void setConnectionFinder(ConnectionFinder finder) { |
| connectionFinder = finder; |
| } |
| |
| static void setSQLTypeName(String typeName) { |
| SQL_TYPE_NAME = typeName; |
| } |
| static void setSQLTypeName(String typeName) { |
| SQL_TYPE_NAME = typeName; |
| } |
| |
| static String getSQLTypeName() { |
| return SQL_TYPE_NAME; |
| } |
| static String getSQLTypeName() { |
| return SQL_TYPE_NAME; |
| } |
| |
| @Override |
| public void nullSafeSet(PreparedStatement st, Object value, int index) |
| throws HibernateException, SQLException { |
| if (value == null) { |
| st.setNull(index, sqlTypes()[0], SQL_TYPE_NAME); |
| } else { |
| Geometry jtsGeom = (Geometry) value; |
| try { |
| Object dbGeom = conv2DBGeometry(jtsGeom, getConnectionFinder() |
| .find(st.getConnection())); |
| st.setObject(index, dbGeom); |
| } catch (FinderException e) { |
| throw new HibernateException(e); |
| } |
| } |
| } |
| @Override |
| public void nullSafeSet(PreparedStatement st, Object value, int index) |
| throws HibernateException, SQLException { |
| if (value == null) { |
| st.setNull(index, sqlTypes()[0], SQL_TYPE_NAME); |
| } else { |
| Geometry jtsGeom = (Geometry) value; |
| try { |
| Object dbGeom = conv2DBGeometry(jtsGeom, getConnectionFinder() |
| .find(st.getConnection())); |
| st.setObject(index, dbGeom); |
| } catch (FinderException e) { |
| throw new HibernateException(e); |
| } |
| } |
| } |
| |
| @Override |
| public Object conv2DBGeometry(Geometry jtsGeom, Connection connection) { |
| SDO_GEOMETRY geom = convertJTSGeometry(jtsGeom); |
| if (geom != null) |
| try { |
| return SDO_GEOMETRY.store(geom, (OracleConnection) connection); |
| } catch (SQLException e) { |
| throw new HibernateSpatialException( |
| "Problem during conversion from JTS to SDO_GEOMETRY", e); |
| } |
| else { |
| throw new UnsupportedOperationException("Conversion of " |
| + jtsGeom.getClass().getSimpleName() |
| + " to Oracle STRUCT not supported"); |
| } |
| } |
| @Override |
| public Object conv2DBGeometry(Geometry jtsGeom, Connection connection) { |
| SDO_GEOMETRY geom = convertJTSGeometry(jtsGeom); |
| if (geom != null) |
| try { |
| return SDO_GEOMETRY.store(geom, (OracleConnection) connection); |
| } catch (SQLException e) { |
| throw new HibernateSpatialException( |
| "Problem during conversion from JTS to SDO_GEOMETRY", e); |
| } |
| else { |
| throw new UnsupportedOperationException("Conversion of " |
| + jtsGeom.getClass().getSimpleName() |
| + " to Oracle STRUCT not supported"); |
| } |
| } |
| |
| private SDO_GEOMETRY convertJTSGeometry(Geometry jtsGeom) { |
| SDO_GEOMETRY geom = null; |
| if (jtsGeom instanceof Point) { |
| geom = convertJTSPoint((Point) jtsGeom); |
| } else if (jtsGeom instanceof LineString) { |
| geom = convertJTSLineString((LineString) jtsGeom); |
| } else if (jtsGeom instanceof Polygon) { |
| geom = convertJTSPolygon((Polygon) jtsGeom); |
| } else if (jtsGeom instanceof MultiPoint) { |
| geom = convertJTSMultiPoint((MultiPoint) jtsGeom); |
| } else if (jtsGeom instanceof MultiLineString) { |
| geom = convertJTSMultiLineString((MultiLineString) jtsGeom); |
| } else if (jtsGeom instanceof MultiPolygon) { |
| geom = convertJTSMultiPolygon((MultiPolygon) jtsGeom); |
| } else if (jtsGeom instanceof GeometryCollection) { |
| geom = convertJTSGeometryCollection((GeometryCollection) jtsGeom); |
| } |
| return geom; |
| } |
| private SDO_GEOMETRY convertJTSGeometry(Geometry jtsGeom) { |
| SDO_GEOMETRY geom = null; |
| if (jtsGeom instanceof Point) { |
| geom = convertJTSPoint((Point) jtsGeom); |
| } else if (jtsGeom instanceof LineString) { |
| geom = convertJTSLineString((LineString) jtsGeom); |
| } else if (jtsGeom instanceof Polygon) { |
| geom = convertJTSPolygon((Polygon) jtsGeom); |
| } else if (jtsGeom instanceof MultiPoint) { |
| geom = convertJTSMultiPoint((MultiPoint) jtsGeom); |
| } else if (jtsGeom instanceof MultiLineString) { |
| geom = convertJTSMultiLineString((MultiLineString) jtsGeom); |
| } else if (jtsGeom instanceof MultiPolygon) { |
| geom = convertJTSMultiPolygon((MultiPolygon) jtsGeom); |
| } else if (jtsGeom instanceof GeometryCollection) { |
| geom = convertJTSGeometryCollection((GeometryCollection) jtsGeom); |
| } |
| return geom; |
| } |
| |
| private SDO_GEOMETRY convertJTSGeometryCollection( |
| GeometryCollection collection) { |
| SDO_GEOMETRY[] sdoElements = new SDO_GEOMETRY[collection |
| .getNumGeometries()]; |
| for (int i = 0; i < collection.getNumGeometries(); i++) { |
| Geometry geom = collection.getGeometryN(i); |
| sdoElements[i] = convertJTSGeometry(geom); |
| } |
| SDO_GEOMETRY ccollect = SDO_GEOMETRY.join(sdoElements); |
| ccollect.setSRID(collection.getSRID()); |
| return ccollect; |
| } |
| private SDO_GEOMETRY convertJTSGeometryCollection( |
| GeometryCollection collection) { |
| SDO_GEOMETRY[] sdoElements = new SDO_GEOMETRY[collection |
| .getNumGeometries()]; |
| for (int i = 0; i < collection.getNumGeometries(); i++) { |
| Geometry geom = collection.getGeometryN(i); |
| sdoElements[i] = convertJTSGeometry(geom); |
| } |
| SDO_GEOMETRY ccollect = SDO_GEOMETRY.join(sdoElements); |
| ccollect.setSRID(collection.getSRID()); |
| return ccollect; |
| } |
| |
| private SDO_GEOMETRY convertJTSMultiPolygon(MultiPolygon multiPolygon) { |
| int dim = getCoordDimension(multiPolygon); |
| int lrsPos = getCoordinateLrsPosition(multiPolygon); |
| SDO_GEOMETRY geom = new SDO_GEOMETRY(); |
| geom.setGType(new SDO_GTYPE(dim, lrsPos, TypeGeometry.MULTIPOLYGON)); |
| geom.setSRID(multiPolygon.getSRID()); |
| for (int i = 0; i < multiPolygon.getNumGeometries(); i++) { |
| try { |
| Polygon pg = (Polygon) multiPolygon.getGeometryN(i); |
| addPolygon(geom, pg); |
| } catch (Exception e) { |
| throw new RuntimeException( |
| "Found geometry that was not a geometry in MultiPolygon"); |
| } |
| } |
| return geom; |
| } |
| private SDO_GEOMETRY convertJTSMultiPolygon(MultiPolygon multiPolygon) { |
| int dim = getCoordDimension(multiPolygon); |
| int lrsPos = getCoordinateLrsPosition(multiPolygon); |
| SDO_GEOMETRY geom = new SDO_GEOMETRY(); |
| geom.setGType(new SDO_GTYPE(dim, lrsPos, TypeGeometry.MULTIPOLYGON)); |
| geom.setSRID(multiPolygon.getSRID()); |
| for (int i = 0; i < multiPolygon.getNumGeometries(); i++) { |
| try { |
| Polygon pg = (Polygon) multiPolygon.getGeometryN(i); |
| addPolygon(geom, pg); |
| } catch (Exception e) { |
| throw new RuntimeException( |
| "Found geometry that was not a geometry in MultiPolygon"); |
| } |
| } |
| return geom; |
| } |
| |
| private SDO_GEOMETRY convertJTSLineString(LineString lineString) { |
| int dim = getCoordDimension(lineString); |
| int lrsPos = getCoordinateLrsPosition(lineString); |
| boolean isLrs = lrsPos > 0; |
| Double[] ordinates = convertCoordinates(lineString.getCoordinates(), |
| dim, isLrs); |
| SDO_GEOMETRY geom = new SDO_GEOMETRY(); |
| geom.setGType(new SDO_GTYPE(dim, lrsPos, TypeGeometry.LINE)); |
| geom.setSRID(lineString.getSRID()); |
| ELEM_INFO info = new ELEM_INFO(1); |
| info.setElement(0, 1, ElementType.LINE_STRAITH_SEGMENTS, 0); |
| geom.setInfo(info); |
| geom.setOrdinates(new ORDINATES(ordinates)); |
| return geom; |
| private SDO_GEOMETRY convertJTSLineString(LineString lineString) { |
| int dim = getCoordDimension(lineString); |
| int lrsPos = getCoordinateLrsPosition(lineString); |
| boolean isLrs = lrsPos > 0; |
| Double[] ordinates = convertCoordinates(lineString.getCoordinates(), |
| dim, isLrs); |
| SDO_GEOMETRY geom = new SDO_GEOMETRY(); |
| geom.setGType(new SDO_GTYPE(dim, lrsPos, TypeGeometry.LINE)); |
| geom.setSRID(lineString.getSRID()); |
| ELEM_INFO info = new ELEM_INFO(1); |
| info.setElement(0, 1, ElementType.LINE_STRAITH_SEGMENTS, 0); |
| geom.setInfo(info); |
| geom.setOrdinates(new ORDINATES(ordinates)); |
| return geom; |
| |
| } |
| } |
| |
| private SDO_GEOMETRY convertJTSMultiPoint(MultiPoint multiPoint) { |
| int dim = getCoordDimension(multiPoint); |
| int lrsDim = getCoordinateLrsPosition(multiPoint); |
| boolean isLrs = (lrsDim != 0); |
| SDO_GEOMETRY geom = new SDO_GEOMETRY(); |
| geom.setGType(new SDO_GTYPE(dim, lrsDim, TypeGeometry.MULTIPOINT)); |
| geom.setSRID(multiPoint.getSRID()); |
| ELEM_INFO info = new ELEM_INFO(multiPoint.getNumPoints()); |
| int oordinatesOffset = 1; |
| Double[] ordinates = new Double[] {}; |
| for (int i = 0; i < multiPoint.getNumPoints(); i++) { |
| info.setElement(i, oordinatesOffset, ElementType.POINT, 0); |
| ordinates = convertAddCoordinates(ordinates, multiPoint |
| .getGeometryN(i).getCoordinates(), dim, isLrs); |
| oordinatesOffset = ordinates.length + 1; |
| } |
| geom.setInfo(info); |
| geom.setOrdinates(new ORDINATES(ordinates)); |
| return geom; |
| } |
| private SDO_GEOMETRY convertJTSMultiPoint(MultiPoint multiPoint) { |
| int dim = getCoordDimension(multiPoint); |
| int lrsDim = getCoordinateLrsPosition(multiPoint); |
| boolean isLrs = (lrsDim != 0); |
| SDO_GEOMETRY geom = new SDO_GEOMETRY(); |
| geom.setGType(new SDO_GTYPE(dim, lrsDim, TypeGeometry.MULTIPOINT)); |
| geom.setSRID(multiPoint.getSRID()); |
| ELEM_INFO info = new ELEM_INFO(multiPoint.getNumPoints()); |
| int oordinatesOffset = 1; |
| Double[] ordinates = new Double[]{}; |
| for (int i = 0; i < multiPoint.getNumPoints(); i++) { |
| info.setElement(i, oordinatesOffset, ElementType.POINT, 0); |
| ordinates = convertAddCoordinates(ordinates, multiPoint |
| .getGeometryN(i).getCoordinates(), dim, isLrs); |
| oordinatesOffset = ordinates.length + 1; |
| } |
| geom.setInfo(info); |
| geom.setOrdinates(new ORDINATES(ordinates)); |
| return geom; |
| } |
| |
| private SDO_GEOMETRY convertJTSPoint(Point jtsGeom) { |
| int dim = getCoordDimension(jtsGeom); |
| private SDO_GEOMETRY convertJTSPoint(Point jtsGeom) { |
| int dim = getCoordDimension(jtsGeom); |
| |
| int lrsDim = getCoordinateLrsPosition(jtsGeom); |
| boolean isLrs = (lrsDim != 0); |
| int lrsDim = getCoordinateLrsPosition(jtsGeom); |
| boolean isLrs = (lrsDim != 0); |
| |
| Double[] coord = convertCoordinates(jtsGeom.getCoordinates(), dim, |
| isLrs); |
| SDO_GEOMETRY geom = new SDO_GEOMETRY(); |
| geom.setGType(new SDO_GTYPE(dim, lrsDim, TypeGeometry.POINT)); |
| geom.setSRID(jtsGeom.getSRID()); |
| ELEM_INFO info = new ELEM_INFO(1); |
| info.setElement(0, 1, ElementType.POINT, 1); |
| geom.setInfo(info); |
| geom.setOrdinates(new ORDINATES(coord)); |
| return geom; |
| } |
| Double[] coord = convertCoordinates(jtsGeom.getCoordinates(), dim, |
| isLrs); |
| SDO_GEOMETRY geom = new SDO_GEOMETRY(); |
| geom.setGType(new SDO_GTYPE(dim, lrsDim, TypeGeometry.POINT)); |
| geom.setSRID(jtsGeom.getSRID()); |
| ELEM_INFO info = new ELEM_INFO(1); |
| info.setElement(0, 1, ElementType.POINT, 1); |
| geom.setInfo(info); |
| geom.setOrdinates(new ORDINATES(coord)); |
| return geom; |
| } |
| |
| private SDO_GEOMETRY convertJTSPolygon(Polygon polygon) { |
| int dim = getCoordDimension(polygon); |
| int lrsPos = getCoordinateLrsPosition(polygon); |
| SDO_GEOMETRY geom = new SDO_GEOMETRY(); |
| geom.setGType(new SDO_GTYPE(dim, lrsPos, TypeGeometry.POLYGON)); |
| geom.setSRID(polygon.getSRID()); |
| addPolygon(geom, polygon); |
| return geom; |
| } |
| private SDO_GEOMETRY convertJTSPolygon(Polygon polygon) { |
| int dim = getCoordDimension(polygon); |
| int lrsPos = getCoordinateLrsPosition(polygon); |
| SDO_GEOMETRY geom = new SDO_GEOMETRY(); |
| geom.setGType(new SDO_GTYPE(dim, lrsPos, TypeGeometry.POLYGON)); |
| geom.setSRID(polygon.getSRID()); |
| addPolygon(geom, polygon); |
| return geom; |
| } |
| |
| private void addPolygon(SDO_GEOMETRY geom, Polygon polygon) { |
| int numInteriorRings = polygon.getNumInteriorRing(); |
| ELEM_INFO info = new ELEM_INFO(numInteriorRings + 1); |
| int ordinatesPreviousOffset = 0; |
| if (geom.getOrdinates() != null) { |
| ordinatesPreviousOffset = geom.getOrdinates().getOrdinateArray().length; |
| } |
| int ordinatesOffset = ordinatesPreviousOffset + 1; |
| Double[] ordinates = new Double[] {}; |
| for (int i = 0; i < info.getSize(); i++) { |
| ElementType et; |
| Coordinate[] coords; |
| if (i == 0) { |
| et = ElementType.EXTERIOR_RING_STRAIGHT_SEGMENTS; |
| coords = polygon.getExteriorRing().getCoordinates(); |
| if (!CGAlgorithms.isCCW(coords)) { |
| coords = reverseRing(coords); |
| } |
| } else { |
| et = ElementType.INTERIOR_RING_STRAIGHT_SEGMENTS; |
| coords = polygon.getInteriorRingN(i - 1).getCoordinates(); |
| if (CGAlgorithms.isCCW(coords)) { |
| coords = reverseRing(coords); |
| } |
| } |
| info.setElement(i, ordinatesOffset, et, 0); |
| ordinates = convertAddCoordinates(ordinates, coords, geom |
| .getDimension(), geom.isLRSGeometry()); |
| ordinatesOffset = ordinatesPreviousOffset + ordinates.length + 1; |
| } |
| geom.addElement(info); |
| geom.addOrdinates(ordinates); |
| } |
| private void addPolygon(SDO_GEOMETRY geom, Polygon polygon) { |
| int numInteriorRings = polygon.getNumInteriorRing(); |
| ELEM_INFO info = new ELEM_INFO(numInteriorRings + 1); |
| int ordinatesPreviousOffset = 0; |
| if (geom.getOrdinates() != null) { |
| ordinatesPreviousOffset = geom.getOrdinates().getOrdinateArray().length; |
| } |
| int ordinatesOffset = ordinatesPreviousOffset + 1; |
| Double[] ordinates = new Double[]{}; |
| for (int i = 0; i < info.getSize(); i++) { |
| ElementType et; |
| Coordinate[] coords; |
| if (i == 0) { |
| et = ElementType.EXTERIOR_RING_STRAIGHT_SEGMENTS; |
| coords = polygon.getExteriorRing().getCoordinates(); |
| if (!CGAlgorithms.isCCW(coords)) { |
| coords = reverseRing(coords); |
| } |
| } else { |
| et = ElementType.INTERIOR_RING_STRAIGHT_SEGMENTS; |
| coords = polygon.getInteriorRingN(i - 1).getCoordinates(); |
| if (CGAlgorithms.isCCW(coords)) { |
| coords = reverseRing(coords); |
| } |
| } |
| info.setElement(i, ordinatesOffset, et, 0); |
| ordinates = convertAddCoordinates(ordinates, coords, geom |
| .getDimension(), geom.isLRSGeometry()); |
| ordinatesOffset = ordinatesPreviousOffset + ordinates.length + 1; |
| } |
| geom.addElement(info); |
| geom.addOrdinates(ordinates); |
| } |
| |
| private SDO_GEOMETRY convertJTSMultiLineString( |
| MultiLineString multiLineString) { |
| int dim = getCoordDimension(multiLineString); |
| int lrsDim = getCoordinateLrsPosition(multiLineString); |
| boolean isLrs = (lrsDim != 0); |
| SDO_GEOMETRY geom = new SDO_GEOMETRY(); |
| geom.setGType(new SDO_GTYPE(dim, lrsDim, TypeGeometry.MULTILINE)); |
| geom.setSRID(multiLineString.getSRID()); |
| ELEM_INFO info = new ELEM_INFO(multiLineString.getNumGeometries()); |
| int oordinatesOffset = 1; |
| Double[] ordinates = new Double[] {}; |
| for (int i = 0; i < multiLineString.getNumGeometries(); i++) { |
| info.setElement(i, oordinatesOffset, |
| ElementType.LINE_STRAITH_SEGMENTS, 0); |
| ordinates = convertAddCoordinates(ordinates, multiLineString |
| .getGeometryN(i).getCoordinates(), dim, isLrs); |
| oordinatesOffset = ordinates.length + 1; |
| } |
| geom.setInfo(info); |
| geom.setOrdinates(new ORDINATES(ordinates)); |
| return geom; |
| } |
| private SDO_GEOMETRY convertJTSMultiLineString( |
| MultiLineString multiLineString) { |
| int dim = getCoordDimension(multiLineString); |
| int lrsDim = getCoordinateLrsPosition(multiLineString); |
| boolean isLrs = (lrsDim != 0); |
| SDO_GEOMETRY geom = new SDO_GEOMETRY(); |
| geom.setGType(new SDO_GTYPE(dim, lrsDim, TypeGeometry.MULTILINE)); |
| geom.setSRID(multiLineString.getSRID()); |
| ELEM_INFO info = new ELEM_INFO(multiLineString.getNumGeometries()); |
| int oordinatesOffset = 1; |
| Double[] ordinates = new Double[]{}; |
| for (int i = 0; i < multiLineString.getNumGeometries(); i++) { |
| info.setElement(i, oordinatesOffset, |
| ElementType.LINE_STRAITH_SEGMENTS, 0); |
| ordinates = convertAddCoordinates(ordinates, multiLineString |
| .getGeometryN(i).getCoordinates(), dim, isLrs); |
| oordinatesOffset = ordinates.length + 1; |
| } |
| geom.setInfo(info); |
| geom.setOrdinates(new ORDINATES(ordinates)); |
| return geom; |
| } |
| |
| private Double[] convertAddCoordinates(Double[] ordinates, |
| Coordinate[] coordinates, int dim, boolean isLrs) { |
| Double[] no = convertCoordinates(coordinates, dim, isLrs); |
| Double[] newordinates = new Double[ordinates.length + no.length]; |
| System.arraycopy(ordinates, 0, newordinates, 0, ordinates.length); |
| System.arraycopy(no, 0, newordinates, ordinates.length, no.length); |
| return newordinates; |
| } |
| private Double[] convertAddCoordinates(Double[] ordinates, |
| Coordinate[] coordinates, int dim, boolean isLrs) { |
| Double[] no = convertCoordinates(coordinates, dim, isLrs); |
| Double[] newordinates = new Double[ordinates.length + no.length]; |
| System.arraycopy(ordinates, 0, newordinates, 0, ordinates.length); |
| System.arraycopy(no, 0, newordinates, ordinates.length, no.length); |
| return newordinates; |
| } |
| |
| /** |
| * Convert the coordinates to a double array for purposes of persisting them |
| * to the database. Note that Double.NaN values are to be converted to null |
| * values in the array. |
| * |
| * @param coordinates |
| * Coordinates to be converted to the array |
| * @param dim |
| * Coordinate dimension |
| * @param isLrs |
| * true if the coordinates contain measures |
| * @return |
| */ |
| private Double[] convertCoordinates(Coordinate[] coordinates, int dim, |
| boolean isLrs) { |
| if (dim > 4) |
| throw new IllegalArgumentException( |
| "Dim parameter value cannot be greater than 4"); |
| Double[] converted = new Double[coordinates.length * dim]; |
| for (int i = 0; i < coordinates.length; i++) { |
| MCoordinate c = MCoordinate.convertCoordinate(coordinates[i]); |
| /** |
| * Convert the coordinates to a double array for purposes of persisting them |
| * to the database. Note that Double.NaN values are to be converted to null |
| * values in the array. |
| * |
| * @param coordinates Coordinates to be converted to the array |
| * @param dim Coordinate dimension |
| * @param isLrs true if the coordinates contain measures |
| * @return |
| */ |
| private Double[] convertCoordinates(Coordinate[] coordinates, int dim, |
| boolean isLrs) { |
| if (dim > 4) |
| throw new IllegalArgumentException( |
| "Dim parameter value cannot be greater than 4"); |
| Double[] converted = new Double[coordinates.length * dim]; |
| for (int i = 0; i < coordinates.length; i++) { |
| MCoordinate c = MCoordinate.convertCoordinate(coordinates[i]); |
| |
| // set the X and Y values |
| converted[i * dim] = toDouble(c.x); |
| converted[i * dim + 1] = toDouble(c.y); |
| if (dim == 3) |
| converted[i * dim + 2] = isLrs ? toDouble(c.m) : toDouble(c.z); |
| else if (dim == 4) { |
| converted[i * dim + 2] = toDouble(c.z); |
| converted[i * dim + 3] = toDouble(c.m); |
| } |
| } |
| return converted; |
| } |
| // set the X and Y values |
| converted[i * dim] = toDouble(c.x); |
| converted[i * dim + 1] = toDouble(c.y); |
| if (dim == 3) |
| converted[i * dim + 2] = isLrs ? toDouble(c.m) : toDouble(c.z); |
| else if (dim == 4) { |
| converted[i * dim + 2] = toDouble(c.z); |
| converted[i * dim + 3] = toDouble(c.m); |
| } |
| } |
| return converted; |
| } |
| |
| /** |
| * This method converts a double primitive to a Double wrapper instance, but |
| * treats a Double.NaN value as null. |
| * |
| * @param d |
| * the value to be converted |
| * @return A Double instance of d, Null if the parameter is Double.NaN |
| */ |
| private Double toDouble(double d) { |
| return Double.isNaN(d) ? null : d; |
| } |
| /** |
| * This method converts a double primitive to a Double wrapper instance, but |
| * treats a Double.NaN value as null. |
| * |
| * @param d the value to be converted |
| * @return A Double instance of d, Null if the parameter is Double.NaN |
| */ |
| private Double toDouble(double d) { |
| return Double.isNaN(d) ? null : d; |
| } |
| |
| /** |
| * Return the dimension required for building the gType in the SDO_GEOMETRY |
| * object. Has support for LRS type geometries. |
| * |
| * @param geom |
| * and instance of the Geometry class from which the dimension is |
| * being extracted. |
| * @return number of dimensions for purposes of creating the |
| * SDO_GEOMETRY.SDO_GTYPE |
| */ |
| private int getCoordDimension(Geometry geom) { |
| // This is awkward, I have to create an MCoordinate to discover what the |
| // dimension is. |
| // This shall be cleaner if MCoordinate.getOrdinate(int ordinateIndex) |
| // is moved to the |
| // Coordinate class |
| MCoordinate c = MCoordinate.convertCoordinate(geom.getCoordinate()); |
| int d = 0; |
| if (c != null) { |
| if (!Double.isNaN(c.x)) |
| d++; |
| if (!Double.isNaN(c.y)) |
| d++; |
| if (!Double.isNaN(c.z)) |
| d++; |
| if (!Double.isNaN(c.m)) |
| d++; |
| } |
| return d; |
| } |
| /** |
| * Return the dimension required for building the gType in the SDO_GEOMETRY |
| * object. Has support for LRS type geometries. |
| * |
| * @param geom and instance of the Geometry class from which the dimension is |
| * being extracted. |
| * @return number of dimensions for purposes of creating the |
| * SDO_GEOMETRY.SDO_GTYPE |
| */ |
| private int getCoordDimension(Geometry geom) { |
| // This is awkward, I have to create an MCoordinate to discover what the |
| // dimension is. |
| // This shall be cleaner if MCoordinate.getOrdinate(int ordinateIndex) |
| // is moved to the |
| // Coordinate class |
| MCoordinate c = MCoordinate.convertCoordinate(geom.getCoordinate()); |
| int d = 0; |
| if (c != null) { |
| if (!Double.isNaN(c.x)) |
| d++; |
| if (!Double.isNaN(c.y)) |
| d++; |
| if (!Double.isNaN(c.z)) |
| d++; |
| if (!Double.isNaN(c.m)) |
| d++; |
| } |
| return d; |
| } |
| |
| /** |
| * Returns the lrs measure position for purposes of building the gType for |
| * an oracle geometry. At this point and time, I'll have to assume that the |
| * measure is always put at the end of the ordinate tuple, even though it |
| * technically wouldn't have to. This method bases its decision on whether |
| * the first coordinate has a measure value, as measure are required for the |
| * very first and last measure in a CoordinateSequence. If there is no |
| * measure value, 0 is returned. |
| * |
| * @param geom |
| * and instance of the Geometry class from which the lrs position |
| * is being extracted. |
| * @return the lrs position for the SDO_GEOMETRY.SDO_GTYPE |
| */ |
| private int getCoordinateLrsPosition(Geometry geom) { |
| MCoordinate c = MCoordinate.convertCoordinate(geom.getCoordinate()); |
| int measurePos = 0; |
| if (c != null && !Double.isNaN(c.m)) { |
| measurePos = (Double.isNaN(c.z)) ? 3 : 4; |
| } |
| return measurePos; |
| } |
| /** |
| * Returns the lrs measure position for purposes of building the gType for |
| * an oracle geometry. At this point and time, I'll have to assume that the |
| * measure is always put at the end of the ordinate tuple, even though it |
| * technically wouldn't have to. This method bases its decision on whether |
| * the first coordinate has a measure value, as measure are required for the |
| * very first and last measure in a CoordinateSequence. If there is no |
| * measure value, 0 is returned. |
| * |
| * @param geom and instance of the Geometry class from which the lrs position |
| * is being extracted. |
| * @return the lrs position for the SDO_GEOMETRY.SDO_GTYPE |
| */ |
| private int getCoordinateLrsPosition(Geometry geom) { |
| MCoordinate c = MCoordinate.convertCoordinate(geom.getCoordinate()); |
| int measurePos = 0; |
| if (c != null && !Double.isNaN(c.m)) { |
| measurePos = (Double.isNaN(c.z)) ? 3 : 4; |
| } |
| return measurePos; |
| } |
| |
| @Override |
| public Geometry convert2JTS(Object struct) { |
| if (struct == null) { |
| return null; |
| } |
| @Override |
| public Geometry convert2JTS(Object struct) { |
| if (struct == null) { |
| return null; |
| } |
| |
| SDO_GEOMETRY sdoGeom = SDO_GEOMETRY.load((STRUCT) struct); |
| return convert2JTS(sdoGeom); |
| } |
| SDO_GEOMETRY sdoGeom = SDO_GEOMETRY.load((Struct) struct); |
| return convert2JTS(sdoGeom); |
| } |
| |
| public Geometry convert2JTS(SDO_GEOMETRY sdoGeom) { |
| int dim = sdoGeom.getGType().getDimension(); |
| int lrsDim = sdoGeom.getGType().getLRSDimension(); |
| public Geometry convert2JTS(SDO_GEOMETRY sdoGeom) { |
| int dim = sdoGeom.getGType().getDimension(); |
| int lrsDim = sdoGeom.getGType().getLRSDimension(); |
| |
| switch (sdoGeom.getGType().getTypeGeometry()) { |
| case POINT: |
| return convertSDOPoint(sdoGeom); |
| case LINE: |
| return convertSDOLine(dim, lrsDim, sdoGeom); |
| case POLYGON: |
| return convertSDOPolygon(dim, lrsDim, sdoGeom); |
| case MULTIPOINT: |
| return convertSDOMultiPoint(dim, lrsDim, sdoGeom); |
| case MULTILINE: |
| return convertSDOMultiLine(dim, lrsDim, sdoGeom); |
| case MULTIPOLYGON: |
| return convertSDOMultiPolygon(dim, lrsDim, sdoGeom); |
| case COLLECTION: |
| return convertSDOCollection(dim, lrsDim, sdoGeom); |
| default: |
| throw new IllegalArgumentException("Type not supported: " |
| + sdoGeom.getGType().getTypeGeometry()); |
| } |
| switch (sdoGeom.getGType().getTypeGeometry()) { |
| case POINT: |
| return convertSDOPoint(sdoGeom); |
| case LINE: |
| return convertSDOLine(dim, lrsDim, sdoGeom); |
| case POLYGON: |
| return convertSDOPolygon(dim, lrsDim, sdoGeom); |
| case MULTIPOINT: |
| return convertSDOMultiPoint(dim, lrsDim, sdoGeom); |
| case MULTILINE: |
| return convertSDOMultiLine(dim, lrsDim, sdoGeom); |
| case MULTIPOLYGON: |
| return convertSDOMultiPolygon(dim, lrsDim, sdoGeom); |
| case COLLECTION: |
| return convertSDOCollection(dim, lrsDim, sdoGeom); |
| default: |
| throw new IllegalArgumentException("Type not supported: " |
| + sdoGeom.getGType().getTypeGeometry()); |
| } |
| |
| } |
| } |
| |
| private Geometry convertSDOCollection(int dim, int lrsDim, |
| SDO_GEOMETRY sdoGeom) { |
| List<Geometry> geometries = new ArrayList<Geometry>(); |
| for (SDO_GEOMETRY elemGeom : sdoGeom.getElementGeometries()) { |
| geometries.add(convert2JTS(elemGeom)); |
| } |
| Geometry[] geomArray = new Geometry[geometries.size()]; |
| return getGeometryFactory().createGeometryCollection( |
| geometries.toArray(geomArray)); |
| } |
| private Geometry convertSDOCollection(int dim, int lrsDim, |
| SDO_GEOMETRY sdoGeom) { |
| List<Geometry> geometries = new ArrayList<Geometry>(); |
| for (SDO_GEOMETRY elemGeom : sdoGeom.getElementGeometries()) { |
| geometries.add(convert2JTS(elemGeom)); |
| } |
| Geometry[] geomArray = new Geometry[geometries.size()]; |
| return getGeometryFactory().createGeometryCollection( |
| geometries.toArray(geomArray)); |
| } |
| |
| private Point convertSDOPoint(SDO_GEOMETRY sdoGeom) { |
| Double[] ordinates = sdoGeom.getOrdinates().getOrdinateArray(); |
| if (ordinates.length == 0) { |
| if (sdoGeom.getDimension() == 2) { |
| ordinates = new Double[] { sdoGeom.getPoint().x, |
| sdoGeom.getPoint().y }; |
| } else { |
| ordinates = new Double[] { sdoGeom.getPoint().x, |
| sdoGeom.getPoint().y, sdoGeom.getPoint().z }; |
| } |
| } |
| CoordinateSequence cs = convertOrdinateArray(ordinates, sdoGeom); |
| Point point = getGeometryFactory().createPoint(cs); |
| private Point convertSDOPoint(SDO_GEOMETRY sdoGeom) { |
| Double[] ordinates = sdoGeom.getOrdinates().getOrdinateArray(); |
| if (ordinates.length == 0) { |
| if (sdoGeom.getDimension() == 2) { |
| ordinates = new Double[]{sdoGeom.getPoint().x, |
| sdoGeom.getPoint().y}; |
| } else { |
| ordinates = new Double[]{sdoGeom.getPoint().x, |
| sdoGeom.getPoint().y, sdoGeom.getPoint().z}; |
| } |
| } |
| CoordinateSequence cs = convertOrdinateArray(ordinates, sdoGeom); |
| Point point = getGeometryFactory().createPoint(cs); |
| |
| point.setSRID(sdoGeom.getSRID()); |
| return point; |
| } |
| point.setSRID(sdoGeom.getSRID()); |
| return point; |
| } |
| |
| private MultiPoint convertSDOMultiPoint(int dim, int lrsDim, |
| SDO_GEOMETRY sdoGeom) { |
| Double[] ordinates = sdoGeom.getOrdinates().getOrdinateArray(); |
| CoordinateSequence cs = convertOrdinateArray(ordinates, sdoGeom); |
| MultiPoint multipoint = getGeometryFactory().createMultiPoint(cs); |
| multipoint.setSRID(sdoGeom.getSRID()); |
| return multipoint; |
| } |
| private MultiPoint convertSDOMultiPoint(int dim, int lrsDim, |
| SDO_GEOMETRY sdoGeom) { |
| Double[] ordinates = sdoGeom.getOrdinates().getOrdinateArray(); |
| CoordinateSequence cs = convertOrdinateArray(ordinates, sdoGeom); |
| MultiPoint multipoint = getGeometryFactory().createMultiPoint(cs); |
| multipoint.setSRID(sdoGeom.getSRID()); |
| return multipoint; |
| } |
| |
| private LineString convertSDOLine(int dim, int lrsDim, SDO_GEOMETRY sdoGeom) { |
| boolean lrs = sdoGeom.isLRSGeometry(); |
| ELEM_INFO info = sdoGeom.getInfo(); |
| CoordinateSequence cs = null; |
| private LineString convertSDOLine(int dim, int lrsDim, SDO_GEOMETRY sdoGeom) { |
| boolean lrs = sdoGeom.isLRSGeometry(); |
| ELEM_INFO info = sdoGeom.getInfo(); |
| CoordinateSequence cs = null; |
| |
| int i = 0; |
| while (i < info.getSize()) { |
| if (info.getElementType(i).isCompound()) { |
| int numCompounds = info.getNumCompounds(i); |
| cs = add(cs, getCompoundCSeq(i + 1, i + numCompounds, sdoGeom)); |
| i += 1 + numCompounds; |
| } else { |
| cs = add(cs, getElementCSeq(i, sdoGeom, false)); |
| i++; |
| } |
| } |
| int i = 0; |
| while (i < info.getSize()) { |
| if (info.getElementType(i).isCompound()) { |
| int numCompounds = info.getNumCompounds(i); |
| cs = add(cs, getCompoundCSeq(i + 1, i + numCompounds, sdoGeom)); |
| i += 1 + numCompounds; |
| } else { |
| cs = add(cs, getElementCSeq(i, sdoGeom, false)); |
| i++; |
| } |
| } |
| |
| LineString ls = lrs ? getGeometryFactory().createMLineString(cs) |
| : getGeometryFactory().createLineString(cs); |
| ls.setSRID(sdoGeom.getSRID()); |
| return ls; |
| } |
| LineString ls = lrs ? getGeometryFactory().createMLineString(cs) |
| : getGeometryFactory().createLineString(cs); |
| ls.setSRID(sdoGeom.getSRID()); |
| return ls; |
| } |
| |
| private MultiLineString convertSDOMultiLine(int dim, int lrsDim, |
| SDO_GEOMETRY sdoGeom) { |
| boolean lrs = sdoGeom.isLRSGeometry(); |
| ELEM_INFO info = sdoGeom.getInfo(); |
| LineString[] lines = lrs ? new MLineString[sdoGeom.getInfo().getSize()] |
| : new LineString[sdoGeom.getInfo().getSize()]; |
| int i = 0; |
| while (i < info.getSize()) { |
| CoordinateSequence cs = null; |
| if (info.getElementType(i).isCompound()) { |
| int numCompounds = info.getNumCompounds(i); |
| cs = add(cs, getCompoundCSeq(i + 1, i + numCompounds, sdoGeom)); |
| LineString line = lrs ? getGeometryFactory().createMLineString( |
| cs) : getGeometryFactory().createLineString(cs); |
| lines[i] = line; |
| i += 1 + numCompounds; |
| } else { |
| cs = add(cs, getElementCSeq(i, sdoGeom, false)); |
| LineString line = lrs ? getGeometryFactory().createMLineString( |
| cs) : getGeometryFactory().createLineString(cs); |
| lines[i] = line; |
| i++; |
| } |
| } |
| private MultiLineString convertSDOMultiLine(int dim, int lrsDim, |
| SDO_GEOMETRY sdoGeom) { |
| boolean lrs = sdoGeom.isLRSGeometry(); |
| ELEM_INFO info = sdoGeom.getInfo(); |
| LineString[] lines = lrs ? new MLineString[sdoGeom.getInfo().getSize()] |
| : new LineString[sdoGeom.getInfo().getSize()]; |
| int i = 0; |
| while (i < info.getSize()) { |
| CoordinateSequence cs = null; |
| if (info.getElementType(i).isCompound()) { |
| int numCompounds = info.getNumCompounds(i); |
| cs = add(cs, getCompoundCSeq(i + 1, i + numCompounds, sdoGeom)); |
| LineString line = lrs ? getGeometryFactory().createMLineString( |
| cs) : getGeometryFactory().createLineString(cs); |
| lines[i] = line; |
| i += 1 + numCompounds; |
| } else { |
| cs = add(cs, getElementCSeq(i, sdoGeom, false)); |
| LineString line = lrs ? getGeometryFactory().createMLineString( |
| cs) : getGeometryFactory().createLineString(cs); |
| lines[i] = line; |
| i++; |
| } |
| } |
| |
| MultiLineString mls = lrs ? getGeometryFactory() |
| .createMultiMLineString((MLineString[]) lines) |
| : getGeometryFactory().createMultiLineString(lines); |
| mls.setSRID(sdoGeom.getSRID()); |
| return mls; |
| MultiLineString mls = lrs ? getGeometryFactory() |
| .createMultiMLineString((MLineString[]) lines) |
| : getGeometryFactory().createMultiLineString(lines); |
| mls.setSRID(sdoGeom.getSRID()); |
| return mls; |
| |
| } |
| } |
| |
| private Geometry convertSDOPolygon(int dim, int lrsDim, SDO_GEOMETRY sdoGeom) { |
| LinearRing shell = null; |
| LinearRing[] holes = new LinearRing[sdoGeom.getNumElements() - 1]; |
| ELEM_INFO info = sdoGeom.getInfo(); |
| int i = 0; |
| int idxInteriorRings = 0; |
| while (i < info.getSize()) { |
| CoordinateSequence cs = null; |
| int numCompounds = 0; |
| if (info.getElementType(i).isCompound()) { |
| numCompounds = info.getNumCompounds(i); |
| cs = add(cs, getCompoundCSeq(i + 1, i + numCompounds, sdoGeom)); |
| } else { |
| cs = add(cs, getElementCSeq(i, sdoGeom, false)); |
| } |
| if (info.getElementType(i).isInteriorRing()) { |
| holes[idxInteriorRings] = getGeometryFactory() |
| .createLinearRing(cs); |
| holes[idxInteriorRings].setSRID(sdoGeom.getSRID()); |
| idxInteriorRings++; |
| } else { |
| shell = getGeometryFactory().createLinearRing(cs); |
| shell.setSRID(sdoGeom.getSRID()); |
| } |
| i += 1 + numCompounds; |
| } |
| Polygon polygon = getGeometryFactory().createPolygon(shell, holes); |
| polygon.setSRID(sdoGeom.getSRID()); |
| return polygon; |
| } |
| private Geometry convertSDOPolygon(int dim, int lrsDim, SDO_GEOMETRY sdoGeom) { |
| LinearRing shell = null; |
| LinearRing[] holes = new LinearRing[sdoGeom.getNumElements() - 1]; |
| ELEM_INFO info = sdoGeom.getInfo(); |
| int i = 0; |
| int idxInteriorRings = 0; |
| while (i < info.getSize()) { |
| CoordinateSequence cs = null; |
| int numCompounds = 0; |
| if (info.getElementType(i).isCompound()) { |
| numCompounds = info.getNumCompounds(i); |
| cs = add(cs, getCompoundCSeq(i + 1, i + numCompounds, sdoGeom)); |
| } else { |
| cs = add(cs, getElementCSeq(i, sdoGeom, false)); |
| } |
| if (info.getElementType(i).isInteriorRing()) { |
| holes[idxInteriorRings] = getGeometryFactory() |
| .createLinearRing(cs); |
| holes[idxInteriorRings].setSRID(sdoGeom.getSRID()); |
| idxInteriorRings++; |
| } else { |
| shell = getGeometryFactory().createLinearRing(cs); |
| shell.setSRID(sdoGeom.getSRID()); |
| } |
| i += 1 + numCompounds; |
| } |
| Polygon polygon = getGeometryFactory().createPolygon(shell, holes); |
| polygon.setSRID(sdoGeom.getSRID()); |
| return polygon; |
| } |
| |
| private MultiPolygon convertSDOMultiPolygon(int dim, int lrsDim, |
| SDO_GEOMETRY sdoGeom) { |
| List<LinearRing> holes = new ArrayList<LinearRing>(); |
| List<Polygon> polygons = new ArrayList<Polygon>(); |
| ELEM_INFO info = sdoGeom.getInfo(); |
| LinearRing shell = null; |
| int i = 0; |
| while (i < info.getSize()) { |
| CoordinateSequence cs = null; |
| int numCompounds = 0; |
| if (info.getElementType(i).isCompound()) { |
| numCompounds = info.getNumCompounds(i); |
| cs = add(cs, getCompoundCSeq(i + 1, i + numCompounds, sdoGeom)); |
| } else { |
| cs = add(cs, getElementCSeq(i, sdoGeom, false)); |
| } |
| if (info.getElementType(i).isInteriorRing()) { |
| LinearRing lr = getGeometryFactory().createLinearRing(cs); |
| lr.setSRID(sdoGeom.getSRID()); |
| holes.add(lr); |
| } else { |
| if (shell != null) { |
| Polygon polygon = getGeometryFactory().createPolygon(shell, |
| holes.toArray(new LinearRing[holes.size()])); |
| polygon.setSRID(sdoGeom.getSRID()); |
| polygons.add(polygon); |
| shell = null; |
| } |
| shell = getGeometryFactory().createLinearRing(cs); |
| shell.setSRID(sdoGeom.getSRID()); |
| holes = new ArrayList<LinearRing>(); |
| } |
| i += 1 + numCompounds; |
| } |
| if (shell != null) { |
| Polygon polygon = getGeometryFactory().createPolygon(shell, |
| holes.toArray(new LinearRing[holes.size()])); |
| polygon.setSRID(sdoGeom.getSRID()); |
| polygons.add(polygon); |
| } |
| MultiPolygon multiPolygon = getGeometryFactory().createMultiPolygon( |
| polygons.toArray(new Polygon[polygons.size()])); |
| multiPolygon.setSRID(sdoGeom.getSRID()); |
| return multiPolygon; |
| } |
| private MultiPolygon convertSDOMultiPolygon(int dim, int lrsDim, |
| SDO_GEOMETRY sdoGeom) { |
| List<LinearRing> holes = new ArrayList<LinearRing>(); |
| List<Polygon> polygons = new ArrayList<Polygon>(); |
| ELEM_INFO info = sdoGeom.getInfo(); |
| LinearRing shell = null; |
| int i = 0; |
| while (i < info.getSize()) { |
| CoordinateSequence cs = null; |
| int numCompounds = 0; |
| if (info.getElementType(i).isCompound()) { |
| numCompounds = info.getNumCompounds(i); |
| cs = add(cs, getCompoundCSeq(i + 1, i + numCompounds, sdoGeom)); |
| } else { |
| cs = add(cs, getElementCSeq(i, sdoGeom, false)); |
| } |
| if (info.getElementType(i).isInteriorRing()) { |
| LinearRing lr = getGeometryFactory().createLinearRing(cs); |
| lr.setSRID(sdoGeom.getSRID()); |
| holes.add(lr); |
| } else { |
| if (shell != null) { |
| Polygon polygon = getGeometryFactory().createPolygon(shell, |
| holes.toArray(new LinearRing[holes.size()])); |
| polygon.setSRID(sdoGeom.getSRID()); |
| polygons.add(polygon); |
| shell = null; |
| } |
| shell = getGeometryFactory().createLinearRing(cs); |
| shell.setSRID(sdoGeom.getSRID()); |
| holes = new ArrayList<LinearRing>(); |
| } |
| i += 1 + numCompounds; |
| } |
| if (shell != null) { |
| Polygon polygon = getGeometryFactory().createPolygon(shell, |
| holes.toArray(new LinearRing[holes.size()])); |
| polygon.setSRID(sdoGeom.getSRID()); |
| polygons.add(polygon); |
| } |
| MultiPolygon multiPolygon = getGeometryFactory().createMultiPolygon( |
| polygons.toArray(new Polygon[polygons.size()])); |
| multiPolygon.setSRID(sdoGeom.getSRID()); |
| return multiPolygon; |
| } |
| |
| /** |
| * Gets the CoordinateSequence corresponding to a compound element. |
| * |
| * @param idxFirst |
| * the first sub-element of the compound element |
| * @param idxLast |
| * the last sub-element of the compound element |
| * @param sdoGeom |
| * the SDO_GEOMETRY that holds the compound element. |
| * @return |
| */ |
| private CoordinateSequence getCompoundCSeq(int idxFirst, int idxLast, |
| SDO_GEOMETRY sdoGeom) { |
| CoordinateSequence cs = null; |
| for (int i = idxFirst; i <= idxLast; i++) { |
| // pop off the last element as it is added with the next |
| // coordinate sequence |
| if (cs != null && cs.size() > 0) { |
| Coordinate[] coordinates = cs.toCoordinateArray(); |
| Coordinate[] newCoordinates = new Coordinate[coordinates.length - 1]; |
| System.arraycopy(coordinates, 0, newCoordinates, 0, |
| coordinates.length - 1); |
| cs = getGeometryFactory().getCoordinateSequenceFactory() |
| .create(newCoordinates); |
| } |
| cs = add(cs, getElementCSeq(i, sdoGeom, (i < idxLast))); |
| } |
| return cs; |
| } |
| /** |
| * Gets the CoordinateSequence corresponding to a compound element. |
| * |
| * @param idxFirst the first sub-element of the compound element |
| * @param idxLast the last sub-element of the compound element |
| * @param sdoGeom the SDO_GEOMETRY that holds the compound element. |
| * @return |
| */ |
| private CoordinateSequence getCompoundCSeq(int idxFirst, int idxLast, |
| SDO_GEOMETRY sdoGeom) { |
| CoordinateSequence cs = null; |
| for (int i = idxFirst; i <= idxLast; i++) { |
| // pop off the last element as it is added with the next |
| // coordinate sequence |
| if (cs != null && cs.size() > 0) { |
| Coordinate[] coordinates = cs.toCoordinateArray(); |
| Coordinate[] newCoordinates = new Coordinate[coordinates.length - 1]; |
| System.arraycopy(coordinates, 0, newCoordinates, 0, |
| coordinates.length - 1); |
| cs = getGeometryFactory().getCoordinateSequenceFactory() |
| .create(newCoordinates); |
| } |
| cs = add(cs, getElementCSeq(i, sdoGeom, (i < idxLast))); |
| } |
| return cs; |
| } |
| |
| /** |
| * Gets the CoordinateSequence corresponding to an element. |
| * |
| * @param i |
| * @param sdoGeom |
| * @return |
| */ |
| private CoordinateSequence getElementCSeq(int i, SDO_GEOMETRY sdoGeom, |
| boolean hasNextSE) { |
| ElementType type = sdoGeom.getInfo().getElementType(i); |
| Double[] elemOrdinates = extractOrdinatesOfElement(i, sdoGeom, |
| hasNextSE); |
| CoordinateSequence cs = null; |
| if (type.isStraightSegment()) { |
| cs = convertOrdinateArray(elemOrdinates, sdoGeom); |
| } else if (type.isArcSegment() || type.isCircle()) { |
| Coordinate[] linearized = linearize(elemOrdinates, sdoGeom |
| .getDimension(), sdoGeom.isLRSGeometry(), type.isCircle()); |
| cs = getGeometryFactory().getCoordinateSequenceFactory().create( |
| linearized); |
| } else if (type.isRect()) { |
| cs = convertOrdinateArray(elemOrdinates, sdoGeom); |
| Coordinate ll = cs.getCoordinate(0); |
| Coordinate ur = cs.getCoordinate(1); |
| Coordinate lr = new Coordinate(ur.x, ll.y); |
| Coordinate ul = new Coordinate(ll.x, ur.y); |
| if (type.isExteriorRing()) { |
| cs = getGeometryFactory().getCoordinateSequenceFactory() |
| .create(new Coordinate[] { ll, lr, ur, ul, ll }); |
| } else { |
| cs = getGeometryFactory().getCoordinateSequenceFactory() |
| .create(new Coordinate[] { ll, ul, ur, lr, ll }); |
| } |
| } else { |
| throw new RuntimeException("Unexpected Element type in compound: " |
| + type); |
| } |
| return cs; |
| } |
| /** |
| * Gets the CoordinateSequence corresponding to an element. |
| * |
| * @param i |
| * @param sdoGeom |
| * @return |
| */ |
| private CoordinateSequence getElementCSeq(int i, SDO_GEOMETRY sdoGeom, |
| boolean hasNextSE) { |
| ElementType type = sdoGeom.getInfo().getElementType(i); |
| Double[] elemOrdinates = extractOrdinatesOfElement(i, sdoGeom, |
| hasNextSE); |
| CoordinateSequence cs = null; |
| if (type.isStraightSegment()) { |
| cs = convertOrdinateArray(elemOrdinates, sdoGeom); |
| } else if (type.isArcSegment() || type.isCircle()) { |
| Coordinate[] linearized = linearize(elemOrdinates, sdoGeom |
| .getDimension(), sdoGeom.isLRSGeometry(), type.isCircle()); |
| cs = getGeometryFactory().getCoordinateSequenceFactory().create( |
| linearized); |
| } else if (type.isRect()) { |
| cs = convertOrdinateArray(elemOrdinates, sdoGeom); |
| Coordinate ll = cs.getCoordinate(0); |
| Coordinate ur = cs.getCoordinate(1); |
| Coordinate lr = new Coordinate(ur.x, ll.y); |
| Coordinate ul = new Coordinate(ll.x, ur.y); |
| if (type.isExteriorRing()) { |
| cs = getGeometryFactory().getCoordinateSequenceFactory() |
| .create(new Coordinate[]{ll, lr, ur, ul, ll}); |
| } else { |
| cs = getGeometryFactory().getCoordinateSequenceFactory() |
| .create(new Coordinate[]{ll, ul, ur, lr, ll}); |
| } |
| } else { |
| throw new RuntimeException("Unexpected Element type in compound: " |
| + type); |
| } |
| return cs; |
| } |
| |
| private CoordinateSequence add(CoordinateSequence seq1, |
| CoordinateSequence seq2) { |
| if (seq1 == null) { |
| return seq2; |
| } |
| if (seq2 == null) { |
| return seq1; |
| } |
| Coordinate[] c1 = seq1.toCoordinateArray(); |
| Coordinate[] c2 = seq2.toCoordinateArray(); |
| Coordinate[] c3 = new Coordinate[c1.length + c2.length]; |
| System.arraycopy(c1, 0, c3, 0, c1.length); |
| System.arraycopy(c2, 0, c3, c1.length, c2.length); |
| return getGeometryFactory().getCoordinateSequenceFactory().create(c3); |
| } |
| private CoordinateSequence add(CoordinateSequence seq1, |
| CoordinateSequence seq2) { |
| if (seq1 == null) { |
| return seq2; |
| } |
| if (seq2 == null) { |
| return seq1; |
| } |
| Coordinate[] c1 = seq1.toCoordinateArray(); |
| Coordinate[] c2 = seq2.toCoordinateArray(); |
| Coordinate[] c3 = new Coordinate[c1.length + c2.length]; |
| System.arraycopy(c1, 0, c3, 0, c1.length); |
| System.arraycopy(c2, 0, c3, c1.length, c2.length); |
| return getGeometryFactory().getCoordinateSequenceFactory().create(c3); |
| } |
| |
| private Double[] extractOrdinatesOfElement(int element, |
| SDO_GEOMETRY sdoGeom, boolean hasNextSE) { |
| int start = sdoGeom.getInfo().getOrdinatesOffset(element); |
| if (element < sdoGeom.getInfo().getSize() - 1) { |
| int end = sdoGeom.getInfo().getOrdinatesOffset(element + 1); |
| // if this is a subelement of a compound geometry, |
| // the last point is the first point of |
| // the next subelement. |
| if (hasNextSE) { |
| end += sdoGeom.getDimension(); |
| } |
| return sdoGeom.getOrdinates().getOrdinatesArray(start, end); |
| } else { |
| return sdoGeom.getOrdinates().getOrdinatesArray(start); |
| } |
| } |
| private Double[] extractOrdinatesOfElement(int element, |
| SDO_GEOMETRY sdoGeom, boolean hasNextSE) { |
| int start = sdoGeom.getInfo().getOrdinatesOffset(element); |
| if (element < sdoGeom.getInfo().getSize() - 1) { |
| int end = sdoGeom.getInfo().getOrdinatesOffset(element + 1); |
| // if this is a subelement of a compound geometry, |
| // the last point is the first point of |
| // the next subelement. |
| if (hasNextSE) { |
| end += sdoGeom.getDimension(); |
| } |
| return sdoGeom.getOrdinates().getOrdinatesArray(start, end); |
| } else { |
| return sdoGeom.getOrdinates().getOrdinatesArray(start); |
| } |
| } |
| |
| private CoordinateSequence convertOrdinateArray(Double[] oordinates, |
| SDO_GEOMETRY sdoGeom) { |
| int dim = sdoGeom.getDimension(); |
| Coordinate[] coordinates = new Coordinate[oordinates.length / dim]; |
| int zDim = sdoGeom.getZDimension() - 1; |
| int lrsDim = sdoGeom.getLRSDimension() - 1; |
| for (int i = 0; i < coordinates.length; i++) { |
| if (dim == 2) |
| coordinates[i] = new Coordinate(oordinates[i * dim], |
| oordinates[i * dim + 1]); |
| else if (dim == 3) { |
| if (sdoGeom.isLRSGeometry()) { |
| coordinates[i] = MCoordinate.create2dWithMeasure( |
| oordinates[i * dim], // X |
| oordinates[i * dim + 1], // Y |
| oordinates[i * dim + lrsDim]); // M |
| } else { |
| coordinates[i] = new Coordinate(oordinates[i * dim], // X |
| oordinates[i * dim + 1], // Y |
| oordinates[i * dim + zDim]); // Z |
| } |
| } else if (dim == 4) { |
| // This must be an LRS Geometry |
| if (!sdoGeom.isLRSGeometry()) |
| throw new HibernateSpatialException( |
| "4 dimensional Geometries must be LRS geometry"); |
| coordinates[i] = MCoordinate.create3dWithMeasure(oordinates[i |
| * dim], // X |
| oordinates[i * dim + 1], // Y |
| oordinates[i * dim + zDim], // Z |
| oordinates[i * dim + lrsDim]); // M |
| } |
| } |
| return getGeometryFactory().getCoordinateSequenceFactory().create( |
| coordinates); |
| } |
| private CoordinateSequence convertOrdinateArray(Double[] oordinates, |
| SDO_GEOMETRY sdoGeom) { |
| int dim = sdoGeom.getDimension(); |
| Coordinate[] coordinates = new Coordinate[oordinates.length / dim]; |
| int zDim = sdoGeom.getZDimension() - 1; |
| int lrsDim = sdoGeom.getLRSDimension() - 1; |
| for (int i = 0; i < coordinates.length; i++) { |
| if (dim == 2) |
| coordinates[i] = new Coordinate(oordinates[i * dim], |
| oordinates[i * dim + 1]); |
| else if (dim == 3) { |
| if (sdoGeom.isLRSGeometry()) { |
| coordinates[i] = MCoordinate.create2dWithMeasure( |
| oordinates[i * dim], // X |
| oordinates[i * dim + 1], // Y |
| oordinates[i * dim + lrsDim]); // M |
| } else { |
| coordinates[i] = new Coordinate(oordinates[i * dim], // X |
| oordinates[i * dim + 1], // Y |
| oordinates[i * dim + zDim]); // Z |
| } |
| } else if (dim == 4) { |
| // This must be an LRS Geometry |
| if (!sdoGeom.isLRSGeometry()) |
| throw new HibernateSpatialException( |
| "4 dimensional Geometries must be LRS geometry"); |
| coordinates[i] = MCoordinate.create3dWithMeasure(oordinates[i |
| * dim], // X |
| oordinates[i * dim + 1], // Y |
| oordinates[i * dim + zDim], // Z |
| oordinates[i * dim + lrsDim]); // M |
| } |
| } |
| return getGeometryFactory().getCoordinateSequenceFactory().create( |
| coordinates); |
| } |
| |
| // reverses ordinates in a coordinate array in-place |
| private Coordinate[] reverseRing(Coordinate[] ar) { |
| for (int i = 0; i < ar.length / 2; i++) { |
| Coordinate cs = ar[i]; |
| ar[i] = ar[ar.length - 1 - i]; |
| ar[ar.length - 1 - i] = cs; |
| } |
| return ar; |
| } |
| // reverses ordinates in a coordinate array in-place |
| |
| /** |
| * Linearizes arcs and circles. |
| * |
| * @param arcOrdinates |
| * arc or circle coordinates |
| * @param dim |
| * coordinate dimension |
| * @param lrs |
| * whether this is an lrs geometry |
| * @param entireCirlce |
| * whether the whole arc should be linearized |
| * @return linearized interpolation of arcs or circle |
| */ |
| private Coordinate[] linearize(Double[] arcOrdinates, int dim, boolean lrs, |
| boolean entireCirlce) { |
| Coordinate[] linearizedCoords = new Coordinate[0]; |
| // CoordDim is the dimension that includes only non-measure (X,Y,Z) |
| // ordinates in its value |
| int coordDim = lrs ? dim - 1 : dim; |
| // this only works with 2-Dimensional geometries, since we use |
| // JGeometry linearization; |
| if (coordDim != 2) |
| throw new IllegalArgumentException( |
| "Can only linearize 2D arc segments, but geometry is " |
| + dim + "D."); |
| int numOrd = dim; |
| while (numOrd < arcOrdinates.length) { |
| numOrd = numOrd - dim; |
| double x1 = arcOrdinates[numOrd++]; |
| double y1 = arcOrdinates[numOrd++]; |
| double m1 = lrs ? arcOrdinates[numOrd++] : Double.NaN; |
| double x2 = arcOrdinates[numOrd++]; |
| double y2 = arcOrdinates[numOrd++]; |
| double m2 = lrs ? arcOrdinates[numOrd++] : Double.NaN; |
| double x3 = arcOrdinates[numOrd++]; |
| double y3 = arcOrdinates[numOrd++]; |
| double m3 = lrs ? arcOrdinates[numOrd++] : Double.NaN; |
| private Coordinate[] reverseRing(Coordinate[] ar) { |
| for (int i = 0; i < ar.length / 2; i++) { |
| Coordinate cs = ar[i]; |
| ar[i] = ar[ar.length - 1 - i]; |
| ar[ar.length - 1 - i] = cs; |
| } |
| return ar; |
| } |
| |
| Coordinate[] coords; |
| if (entireCirlce) { |
| coords = Circle.linearizeCircle(x1, y1, x2, y2, x3, y3); |
| } else { |
| coords = Circle.linearizeArc(x1, y1, x2, y2, x3, y3); |
| } |
| /** |
| * Linearizes arcs and circles. |
| * |
| * @param arcOrdinates arc or circle coordinates |
| * @param dim coordinate dimension |
| * @param lrs whether this is an lrs geometry |
| * @param entireCirlce whether the whole arc should be linearized |
| * @return linearized interpolation of arcs or circle |
| */ |
| private Coordinate[] linearize(Double[] arcOrdinates, int dim, boolean lrs, |
| boolean entireCirlce) { |
| Coordinate[] linearizedCoords = new Coordinate[0]; |
| // CoordDim is the dimension that includes only non-measure (X,Y,Z) |
| // ordinates in its value |
| int coordDim = lrs ? dim - 1 : dim; |
| // this only works with 2-Dimensional geometries, since we use |
| // JGeometry linearization; |
| if (coordDim != 2) |
| throw new IllegalArgumentException( |
| "Can only linearize 2D arc segments, but geometry is " |
| + dim + "D."); |
| int numOrd = dim; |
| while (numOrd < arcOrdinates.length) { |
| numOrd = numOrd - dim; |
| double x1 = arcOrdinates[numOrd++]; |
| double y1 = arcOrdinates[numOrd++]; |
| double m1 = lrs ? arcOrdinates[numOrd++] : Double.NaN; |
| double x2 = arcOrdinates[numOrd++]; |
| double y2 = arcOrdinates[numOrd++]; |
| double m2 = lrs ? arcOrdinates[numOrd++] : Double.NaN; |
| double x3 = arcOrdinates[numOrd++]; |
| double y3 = arcOrdinates[numOrd++]; |
| double m3 = lrs ? arcOrdinates[numOrd++] : Double.NaN; |
| |
| // if this is an LRS geometry, fill the measure values into |
| // the linearized array |
| if (lrs) { |
| MCoordinate[] mcoord = new MCoordinate[coords.length]; |
| int lastIndex = coords.length - 1; |
| mcoord[0] = MCoordinate.create2dWithMeasure(x1, y1, m1); |
| mcoord[lastIndex] = MCoordinate.create2dWithMeasure(x3, y3, m3); |
| // convert the middle coordinates to MCoordinate |
| for (int i = 1; i < lastIndex; i++) { |
| mcoord[i] = MCoordinate.convertCoordinate(coords[i]); |
| // if we happen to split on the middle measure, then |
| // assign it |
| if (Double.compare(mcoord[i].x, x2) == 0 |
| && Double.compare(mcoord[i].y, y2) == 0) { |
| mcoord[i].m = m2; |
| } |
| } |
| coords = mcoord; |
| } |
| Coordinate[] coords; |
| if (entireCirlce) { |
| coords = Circle.linearizeCircle(x1, y1, x2, y2, x3, y3); |
| } else { |
| coords = Circle.linearizeArc(x1, y1, x2, y2, x3, y3); |
| } |
| |
| // if this is not the first arcsegment, the first linearized |
| // point is already in linearizedArc, so disregard this. |
| int resultBegin = 1; |
| if (linearizedCoords.length == 0) |
| resultBegin = 0; |
| // if this is an LRS geometry, fill the measure values into |
| // the linearized array |
| if (lrs) { |
| MCoordinate[] mcoord = new MCoordinate[coords.length]; |
| int lastIndex = coords.length - 1; |
| mcoord[0] = MCoordinate.create2dWithMeasure(x1, y1, m1); |
| mcoord[lastIndex] = MCoordinate.create2dWithMeasure(x3, y3, m3); |
| // convert the middle coordinates to MCoordinate |
| for (int i = 1; i < lastIndex; i++) { |
| mcoord[i] = MCoordinate.convertCoordinate(coords[i]); |
| // if we happen to split on the middle measure, then |
| // assign it |
| if (Double.compare(mcoord[i].x, x2) == 0 |
| && Double.compare(mcoord[i].y, y2) == 0) { |
| mcoord[i].m = m2; |
| } |
| } |
| coords = mcoord; |
| } |
| |
| int destPos = linearizedCoords.length; |
| Coordinate[] tmpCoords = new Coordinate[linearizedCoords.length |
| + coords.length - resultBegin]; |
| System.arraycopy(linearizedCoords, 0, tmpCoords, 0, |
| linearizedCoords.length); |
| System.arraycopy(coords, resultBegin, tmpCoords, destPos, |
| coords.length - resultBegin); |
| // if this is not the first arcsegment, the first linearized |
| // point is already in linearizedArc, so disregard this. |
| int resultBegin = 1; |
| if (linearizedCoords.length == 0) |
| resultBegin = 0; |
| |
| linearizedCoords = tmpCoords; |
| } |
| return linearizedCoords; |
| } |
| int destPos = linearizedCoords.length; |
| Coordinate[] tmpCoords = new Coordinate[linearizedCoords.length |
| + coords.length - resultBegin]; |
| System.arraycopy(linearizedCoords, 0, tmpCoords, 0, |
| linearizedCoords.length); |
| System.arraycopy(coords, resultBegin, tmpCoords, destPos, |
| coords.length - resultBegin); |
| |
| @Override |
| public int[] sqlTypes() { |
| return geometryTypes; |
| } |
| linearizedCoords = tmpCoords; |
| } |
| return linearizedCoords; |
| } |
| |
| public static String arrayToString(Object array) { |
| if (array == null || Array.getLength(array) == 0) { |
| return "()"; |
| } |
| int length = Array.getLength(array); |
| StringBuilder stb = new StringBuilder(); |
| stb.append("(").append(Array.get(array, 0)); |
| for (int i = 1; i < length; i++) { |
| stb.append(",").append(Array.get(array, i)); |
| } |
| stb.append(")"); |
| return stb.toString(); |
| } |
| @Override |
| public int[] sqlTypes() { |
| return geometryTypes; |
| } |
| |
| public enum TypeGeometry { |
| public static String arrayToString(Object array) { |
| if (array == null || java.lang.reflect.Array.getLength(array) == 0) { |
| return "()"; |
| } |
| int length = java.lang.reflect.Array.getLength(array); |
| StringBuilder stb = new StringBuilder(); |
| stb.append("(").append(java.lang.reflect.Array.get(array, 0)); |
| for (int i = 1; i < length; i++) { |
| stb.append(",").append(java.lang.reflect.Array.get(array, i)); |
| } |
| stb.append(")"); |
| return stb.toString(); |
| } |
| |
| UNKNOWN_GEOMETRY(0), POINT(1), LINE(2), POLYGON(3), COLLECTION(4), MULTIPOINT( |
| 5), MULTILINE(6), MULTIPOLYGON(7), SOLID(8), MULTISOLID(9); |
| public enum TypeGeometry { |
| |
| private int gtype = 0; |
| UNKNOWN_GEOMETRY(0), POINT(1), LINE(2), POLYGON(3), COLLECTION(4), MULTIPOINT( |
| 5), MULTILINE(6), MULTIPOLYGON(7), SOLID(8), MULTISOLID(9); |
| |
| TypeGeometry(int gtype) { |
| this.gtype = gtype; |
| } |
| private int gtype = 0; |
| |
| int intValue() { |
| return this.gtype; |
| } |
| TypeGeometry(int gtype) { |
| this.gtype = gtype; |
| } |
| |
| static TypeGeometry parse(int v) { |
| for (TypeGeometry gt : values()) { |
| if (gt.intValue() == v) { |
| return gt; |
| } |
| } |
| throw new RuntimeException("Value " + v |
| + " isn't a valid TypeGeometry value"); |
| } |
| int intValue() { |
| return this.gtype; |
| } |
| |
| } |
| static TypeGeometry parse(int v) { |
| for (TypeGeometry gt : values()) { |
| if (gt.intValue() == v) { |
| return gt; |
| } |
| } |
| throw new RuntimeException("Value " + v |
| + " isn't a valid TypeGeometry value"); |
| } |
| |
| public static enum ElementType { |
| UNSUPPORTED(0, true), POINT(1, 1), ORIENTATION(1, 0), POINT_CLUSTER(1, |
| true), LINE_STRAITH_SEGMENTS(2, 1), LINE_ARC_SEGMENTS(2, 2), INTERIOR_RING_STRAIGHT_SEGMENTS( |
| 2003, 1), EXTERIOR_RING_STRAIGHT_SEGMENTS(1003, 1), INTERIOR_RING_ARC_SEGMENTS( |
| 2003, 2), EXTERIOR_RING_ARC_SEGMENTS(1003, 2), INTERIOR_RING_RECT( |
| 2003, 3), EXTERIOR_RING_RECT(1003, 3), INTERIOR_RING_CIRCLE( |
| 2003, 4), EXTERIOR_RING_CIRCLE(1003, 4), COMPOUND_LINE(4, true), COMPOUND_EXTERIOR_RING( |
| 1005, true), COMPOUND_INTERIOR_RING(2005, true); |
| } |
| |
| private int etype; |
| public static enum ElementType { |
| UNSUPPORTED(0, true), POINT(1, 1), ORIENTATION(1, 0), POINT_CLUSTER(1, |
| true), LINE_STRAITH_SEGMENTS(2, 1), LINE_ARC_SEGMENTS(2, 2), INTERIOR_RING_STRAIGHT_SEGMENTS( |
| 2003, 1), EXTERIOR_RING_STRAIGHT_SEGMENTS(1003, 1), INTERIOR_RING_ARC_SEGMENTS( |
| 2003, 2), EXTERIOR_RING_ARC_SEGMENTS(1003, 2), INTERIOR_RING_RECT( |
| 2003, 3), EXTERIOR_RING_RECT(1003, 3), INTERIOR_RING_CIRCLE( |
| 2003, 4), EXTERIOR_RING_CIRCLE(1003, 4), COMPOUND_LINE(4, true), COMPOUND_EXTERIOR_RING( |
| 1005, true), COMPOUND_INTERIOR_RING(2005, true); |
| |
| private int interpretation = 2; |
| private int etype; |
| |
| private boolean compound = false; |
| private int interpretation = 2; |
| |
| private ElementType(int etype, int interp) { |
| this.etype = etype; |
| this.interpretation = interp; |
| private boolean compound = false; |
| |
| } |
| private ElementType(int etype, int interp) { |
| this.etype = etype; |
| this.interpretation = interp; |
| |
| private ElementType(int etype, boolean compound) { |
| this.etype = etype; |
| this.compound = compound; |
| } |
| } |
| |
| public int getEType() { |
| return this.etype; |
| } |
| private ElementType(int etype, boolean compound) { |
| this.etype = etype; |
| this.compound = compound; |
| } |
| |
| public int getInterpretation() { |
| return this.interpretation; |
| } |
| public int getEType() { |
| return this.etype; |
| } |
| |
| /** |
| * @return true, if the SDO_INTERPRETATION value is the number of points |
| * or compounds in the element. |
| */ |
| public boolean isCompound() { |
| return this.compound; |
| } |
| public int getInterpretation() { |
| return this.interpretation; |
| } |
| |
| public boolean isLine() { |
| return (etype == 2 || etype == 4); |
| } |
| /** |
| * @return true, if the SDO_INTERPRETATION value is the number of points |
| * or compounds in the element. |
| */ |
| public boolean isCompound() { |
| return this.compound; |
| } |
| |
| public boolean isInteriorRing() { |
| return (etype == 2003 || etype == 2005); |
| } |
| public boolean isLine() { |
| return (etype == 2 || etype == 4); |
| } |
| |
| public boolean isExteriorRing() { |
| return (etype == 1003 || etype == 1005); |
| } |
| public boolean isInteriorRing() { |
| return (etype == 2003 || etype == 2005); |
| } |
| |
| public boolean isStraightSegment() { |
| return (interpretation == 1); |
| } |
| public boolean isExteriorRing() { |
| return (etype == 1003 || etype == 1005); |
| } |
| |
| public boolean isArcSegment() { |
| return (interpretation == 2); |
| } |
| public boolean isStraightSegment() { |
| return (interpretation == 1); |
| } |
| |
| public boolean isCircle() { |
| return (interpretation == 4); |
| } |
| public boolean isArcSegment() { |
| return (interpretation == 2); |
| } |
| |
| public boolean isRect() { |
| return (interpretation == 3); |
| } |
| public boolean isCircle() { |
| return (interpretation == 4); |
| } |
| |
| public static ElementType parseType(int etype, int interpretation) { |
| for (ElementType t : values()) { |
| if (t.etype == etype) { |
| if (t.isCompound() |
| || t.getInterpretation() == interpretation) { |
| return t; |
| } |
| } |
| } |
| throw new RuntimeException( |
| "Can't determine ElementType from etype:" + etype |
| + " and interp.:" + interpretation); |
| } |
| public boolean isRect() { |
| return (interpretation == 3); |
| } |
| |
| } |
| public static ElementType parseType(int etype, int interpretation) { |
| for (ElementType t : values()) { |
| if (t.etype == etype) { |
| if (t.isCompound() |
| || t.getInterpretation() == interpretation) { |
| return t; |
| } |
| } |
| } |
| throw new RuntimeException( |
| "Can't determine ElementType from etype:" + etype |
| + " and interp.:" + interpretation); |
| } |
| |
| public static class SDO_GTYPE { |
| } |
| |
| private int dimension = 2; |
| public static class SDO_GTYPE { |
| |
| private int lrsDimension = 0; |
| private int dimension = 2; |
| |
| private TypeGeometry typeGeometry = TypeGeometry.UNKNOWN_GEOMETRY; |
| private int lrsDimension = 0; |
| |
| public SDO_GTYPE(int dimension, int lrsDimension, |
| TypeGeometry typeGeometry) { |
| setDimension(dimension); |
| setLrsDimension(lrsDimension); |
| setTypeGeometry(typeGeometry); |
| } |
| private TypeGeometry typeGeometry = TypeGeometry.UNKNOWN_GEOMETRY; |
| |
| public int getDimension() { |
| return dimension; |
| } |
| public SDO_GTYPE(int dimension, int lrsDimension, |
| TypeGeometry typeGeometry) { |
| setDimension(dimension); |
| setLrsDimension(lrsDimension); |
| setTypeGeometry(typeGeometry); |
| } |
| |
| public void setDimension(int dimension) { |
| if (dimension < 2 || dimension > 4) { |
| throw new IllegalArgumentException( |
| "Dimension can only be 2,3 or 4."); |
| } |
| this.dimension = dimension; |
| } |
| public int getDimension() { |
| return dimension; |
| } |
| |
| public TypeGeometry getTypeGeometry() { |
| return typeGeometry; |
| } |
| public void setDimension(int dimension) { |
| if (dimension < 2 || dimension > 4) { |
| throw new IllegalArgumentException( |
| "Dimension can only be 2,3 or 4."); |
| } |
| this.dimension = dimension; |
| } |
| |
| public void setTypeGeometry(TypeGeometry typeGeometry) { |
| public TypeGeometry getTypeGeometry() { |
| return typeGeometry; |
| } |
| |
| this.typeGeometry = typeGeometry; |
| } |
| public void setTypeGeometry(TypeGeometry typeGeometry) { |
| |
| public int getLRSDimension() { |
| if (this.lrsDimension > 0) { |
| return this.lrsDimension; |
| } else if (this.lrsDimension == 0 && this.dimension == 4) { |
| return 4; |
| } |
| return 0; |
| } |
| this.typeGeometry = typeGeometry; |
| } |
| |
| public int getZDimension() { |
| if (this.dimension > 2) { |
| if (!isLRSGeometry()) { |
| return this.dimension; |
| } else { |
| return (getLRSDimension() < this.dimension ? 4 : 3); |
| } |
| } |
| return 0; |
| } |
| public int getLRSDimension() { |
| if (this.lrsDimension > 0) { |
| return this.lrsDimension; |
| } else if (this.lrsDimension == 0 && this.dimension == 4) { |
| return 4; |
| } |
| return 0; |
| } |
| |
| public boolean isLRSGeometry() { |
| return (this.lrsDimension > 0 || (this.lrsDimension == 0 && this.dimension == 4)); |
| } |
| public int getZDimension() { |
| if (this.dimension > 2) { |
| if (!isLRSGeometry()) { |
| return this.dimension; |
| } else { |
| return (getLRSDimension() < this.dimension ? 4 : 3); |
| } |
| } |
| return 0; |
| } |
| |
| public void setLrsDimension(int lrsDimension) { |
| if (lrsDimension != 0 && lrsDimension > this.dimension) { |
| throw new IllegalArgumentException( |
| "lrsDimension must be 0 or lower or equal to dimenstion."); |
| } |
| this.lrsDimension = lrsDimension; |
| } |
| public boolean isLRSGeometry() { |
| return (this.lrsDimension > 0 || (this.lrsDimension == 0 && this.dimension == 4)); |
| } |
| |
| public int intValue() { |
| int v = this.dimension * 1000; |
| v += lrsDimension * 100; |
| v += typeGeometry.intValue(); |
| return v; |
| } |
| public void setLrsDimension(int lrsDimension) { |
| if (lrsDimension != 0 && lrsDimension > this.dimension) { |
| throw new IllegalArgumentException( |
| "lrsDimension must be 0 or lower or equal to dimenstion."); |
| } |
| this.lrsDimension = lrsDimension; |
| } |
| |
| public static SDO_GTYPE parse(int v) { |
| int dim = v / 1000; |
| v -= dim * 1000; |
| int lrsDim = v / 100; |
| v -= lrsDim * 100; |
| TypeGeometry typeGeometry = TypeGeometry.parse(v); |
| return new SDO_GTYPE(dim, lrsDim, typeGeometry); |
| } |
| public int intValue() { |
| int v = this.dimension * 1000; |
| v += lrsDimension * 100; |
| v += typeGeometry.intValue(); |
| return v; |
| } |
| |
| public static SDO_GTYPE parse(Datum datum) { |
| public static SDO_GTYPE parse(int v) { |
| int dim = v / 1000; |
| v -= dim * 1000; |
| int lrsDim = v / 100; |
| v -= lrsDim * 100; |
| TypeGeometry typeGeometry = TypeGeometry.parse(v); |
| return new SDO_GTYPE(dim, lrsDim, typeGeometry); |
| } |
| |
| try { |
| int v = ((NUMBER) datum).intValue(); |
| return parse(v); |
| } catch (Exception e) { |
| throw new RuntimeException(e); |
| } |
| public static SDO_GTYPE parse(Object datum) { |
| |
| } |
| try { |
| int v = ((Number) datum).intValue(); |
| return parse(v); |
| } catch (Exception e) { |
| throw new RuntimeException(e); |
| } |
| |
| public String toString() { |
| return Integer.toString(this.intValue()); |
| } |
| } |
| } |
| |
| public static class SDO_POINT { |
| public double x = 0.0; |
| public String toString() { |
| return Integer.toString(this.intValue()); |
| } |
| } |
| |
| public double y = 0.0; |
| public static class SDO_POINT { |
| public double x = 0.0; |
| |
| public double z = Double.NaN; |
| public double y = 0.0; |
| |
| public SDO_POINT(STRUCT struct) { |
| try { |
| Datum[] data = struct.getOracleAttributes(); |
| this.x = ((NUMBER) data[0]).doubleValue(); |
| this.y = ((NUMBER) data[1]).doubleValue(); |
| if (data[2] != null) { |
| this.z = ((NUMBER) data[1]).doubleValue(); |
| } |
| } catch (SQLException e) { |
| throw new RuntimeException(e); |
| } |
| } |
| public double z = Double.NaN; |
| |
| public String toString() { |
| StringBuilder stb = new StringBuilder(); |
| stb.append("(").append(x).append(",").append(y).append(",").append( |
| z).append(")"); |
| return stb.toString(); |
| } |
| public SDO_POINT(Struct struct) { |
| try { |
| Object[] data = struct.getAttributes(); |
| this.x = ((Number) data[0]).doubleValue(); |
| this.y = ((Number) data[1]).doubleValue(); |
| if (data[2] != null) { |
| this.z = ((Number) data[1]).doubleValue(); |
| } |
| } catch (SQLException e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| } |
| public String toString() { |
| StringBuilder stb = new StringBuilder(); |
| stb.append("(").append(x).append(",").append(y).append(",").append( |
| z).append(")"); |
| return stb.toString(); |
| } |
| |
| public static class ELEM_INFO { |
| } |
| |
| private static final String TYPE_NAME = "MDSYS.SDO_ELEM_INFO_ARRAY"; |
| private static int[] toIntArray(Array array) throws SQLException { |
| Number[] numAr = (Number[]) array.getArray(); |
| int[] result = new int[numAr.length]; |
| int i = 0; |
| for (Number number : numAr) { |
| result[i++] = number.intValue(); |
| } |
| return result; |
| } |
| |
| private int[] triplets; |
| public static class ELEM_INFO { |
| |
| public ELEM_INFO(int size) { |
| this.triplets = new int[3 * size]; |
| } |
| private static final String TYPE_NAME = "MDSYS.SDO_ELEM_INFO_ARRAY"; |
| |
| public ELEM_INFO(int[] elem_info) { |
| this.triplets = elem_info; |
| } |
| private int[] triplets; |
| |
| public ELEM_INFO(ARRAY array) { |
| if (array == null) { |
| this.triplets = new int[] {}; |
| return; |
| } |
| try { |
| triplets = array.getIntArray(); |
| } catch (Exception e) { |
| throw new RuntimeException(e); |
| } |
| } |
| public ELEM_INFO(int size) { |
| this.triplets = new int[3 * size]; |
| } |
| |
| public int[] getElements() { |
| return this.triplets; |
| } |
| public ELEM_INFO(int[] elem_info) { |
| this.triplets = elem_info; |
| } |
| |
| public int getSize() { |
| return this.triplets.length / 3; |
| } |
| public ELEM_INFO(Array array) { |
| if (array == null) { |
| this.triplets = new int[]{}; |
| return; |
| } |
| try { |
| triplets = toIntArray(array); |
| } catch (Exception e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| public int getOrdinatesOffset(int i) { |
| return this.triplets[i * 3]; |
| } |
| |
| public void setOrdinatesOffset(int i, int offset) { |
| this.triplets[i * 3] = offset; |
| } |
| public int[] getElements() { |
| return this.triplets; |
| } |
| |
| public ElementType getElementType(int i) { |
| int etype = this.triplets[i * 3 + 1]; |
| int interp = this.triplets[i * 3 + 2]; |
| ElementType et = ElementType.parseType(etype, interp); |
| return et; |
| } |
| public int getSize() { |
| return this.triplets.length / 3; |
| } |
| |
| public boolean isCompound(int i) { |
| return getElementType(i).isCompound(); |
| } |
| public int getOrdinatesOffset(int i) { |
| return this.triplets[i * 3]; |
| } |
| |
| public int getNumCompounds(int i) { |
| if (getElementType(i).isCompound()) { |
| return this.triplets[i * 3 + 2]; |
| } else { |
| return 1; |
| } |
| } |
| public void setOrdinatesOffset(int i, int offset) { |
| this.triplets[i * 3] = offset; |
| } |
| |
| public void setElement(int i, int ordinatesOffset, ElementType et, |
| int numCompounds) { |
| if (i > getSize()) { |
| throw new RuntimeException( |
| "Attempted to set more elements in ELEM_INFO Array than capacity."); |
| } |
| this.triplets[i * 3] = ordinatesOffset; |
| this.triplets[i * 3 + 1] = et.getEType(); |
| this.triplets[i * 3 + 2] = et.isCompound() ? numCompounds : et |
| .getInterpretation(); |
| } |
| public ElementType getElementType(int i) { |
| int etype = this.triplets[i * 3 + 1]; |
| int interp = this.triplets[i * 3 + 2]; |
| ElementType et = ElementType.parseType(etype, interp); |
| return et; |
| } |
| |
| public String toString() { |
| return arrayToString(this.triplets); |
| } |
| public boolean isCompound(int i) { |
| return getElementType(i).isCompound(); |
| } |
| |
| public void addElement(int[] element) { |
| int[] newTriplets = new int[this.triplets.length + element.length]; |
| System.arraycopy(this.triplets, 0, newTriplets, 0, |
| this.triplets.length); |
| System.arraycopy(element, 0, newTriplets, this.triplets.length, |
| element.length); |
| this.triplets = newTriplets; |
| } |
| public int getNumCompounds(int i) { |
| if (getElementType(i).isCompound()) { |
| return this.triplets[i * 3 + 2]; |
| } else { |
| return 1; |
| } |
| } |
| |
| public void addElement(ELEM_INFO element) { |
| this.addElement(element.getElements()); |
| } |
| public void setElement(int i, int ordinatesOffset, ElementType et, |
| int numCompounds) { |
| if (i > getSize()) { |
| throw new RuntimeException( |
| "Attempted to set more elements in ELEM_INFO Array than capacity."); |
| } |
| this.triplets[i * 3] = ordinatesOffset; |
| this.triplets[i * 3 + 1] = et.getEType(); |
| this.triplets[i * 3 + 2] = et.isCompound() ? numCompounds : et |
| .getInterpretation(); |
| } |
| |
| public int[] getElement(int i) { |
| int[] ea = null; |
| if (this.getElementType(i).isCompound()) { |
| int numCompounds = this.getNumCompounds(i); |
| ea = new int[numCompounds + 1]; |
| } else { |
| ea = new int[3]; |
| } |
| System.arraycopy(this.triplets, 3 * i, ea, 0, ea.length); |
| return ea; |
| } |
| public String toString() { |
| return arrayToString(this.triplets); |
| } |
| |
| public ARRAY toOracleArray(Connection conn) throws SQLException { |
| ArrayDescriptor arrayDescriptor = ArrayDescriptor.createDescriptor( |
| TYPE_NAME, conn); |
| return new ARRAY(arrayDescriptor, conn, this.triplets); |
| } |
| } |
| public void addElement(int[] element) { |
| int[] newTriplets = new int[this.triplets.length + element.length]; |
| System.arraycopy(this.triplets, 0, newTriplets, 0, |
| this.triplets.length); |
| System.arraycopy(element, 0, newTriplets, this.triplets.length, |
| element.length); |
| this.triplets = newTriplets; |
| } |
| |
| public static class ORDINATES { |
| public void addElement(ELEM_INFO element) { |
| this.addElement(element.getElements()); |
| } |
| |
| private static final String TYPE_NAME = "MDSYS.SDO_ORDINATE_ARRAY"; |
| public int[] getElement(int i) { |
| int[] ea = null; |
| if (this.getElementType(i).isCompound()) { |
| int numCompounds = this.getNumCompounds(i); |
| ea = new int[numCompounds + 1]; |
| } else { |
| ea = new int[3]; |
| } |
| System.arraycopy(this.triplets, 3 * i, ea, 0, ea.length); |
| return ea; |
| } |
| |
| private Double[] ordinates; |
| public ARRAY toOracleArray(Connection conn) throws SQLException { |
| ArrayDescriptor arrayDescriptor = ArrayDescriptor.createDescriptor( |
| TYPE_NAME, conn); |
| return new ARRAY(arrayDescriptor, conn, this.triplets); |
| } |
| } |
| |
| public ORDINATES(Double[] ordinates) { |
| this.ordinates = ordinates; |
| } |
| public static class ORDINATES { |
| |
| public ORDINATES(ARRAY array) { |
| if (array == null) { |
| this.ordinates = new Double[] {}; |
| return; |
| } |
| try { |
| Number[] ords = (Number[]) array.getArray(); |
| this.ordinates = new Double[ords.length]; |
| for (int i = 0; i < ords.length; i++) { |
| this.ordinates[i] = ords[i] != null ? ords[i].doubleValue() |
| : Double.NaN; |
| } |
| } catch (Exception e) { |
| throw new RuntimeException(e); |
| } |
| } |
| private static final String TYPE_NAME = "MDSYS.SDO_ORDINATE_ARRAY"; |
| |
| public Double[] getOrdinateArray() { |
| return this.ordinates; |
| } |
| private Double[] ordinates; |
| |
| public Double[] getOrdinatesArray(int startPosition, int endPosition) { |
| Double[] a = new Double[endPosition - startPosition]; |
| System.arraycopy(this.ordinates, startPosition - 1, a, 0, a.length); |
| return a; |
| } |
| public ORDINATES(Double[] ordinates) { |
| this.ordinates = ordinates; |
| } |
| |
| public Double[] getOrdinatesArray(int startPosition) { |
| Double[] a = new Double[this.ordinates.length - (startPosition - 1)]; |
| System.arraycopy(this.ordinates, startPosition - 1, a, 0, a.length); |
| return a; |
| } |
| public ORDINATES(Array array) { |
| if (array == null) { |
| this.ordinates = new Double[]{}; |
| return; |
| } |
| try { |
| Number[] ords = (Number[]) array.getArray(); |
| this.ordinates = new Double[ords.length]; |
| for (int i = 0; i < ords.length; i++) { |
| this.ordinates[i] = ords[i] != null ? ords[i].doubleValue() |
| : Double.NaN; |
| } |
| } catch (Exception e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| public String toString() { |
| return arrayToString(this.ordinates); |
| } |
| public Double[] getOrdinateArray() { |
| return this.ordinates; |
| } |
| |
| public void addOrdinates(Double[] ordinatesToAdd) { |
| Double[] newOrdinates = new Double[this.ordinates.length |
| + ordinatesToAdd.length]; |
| System.arraycopy(this.ordinates, 0, newOrdinates, 0, |
| this.ordinates.length); |
| System.arraycopy(ordinatesToAdd, 0, newOrdinates, |
| this.ordinates.length, ordinatesToAdd.length); |
| this.ordinates = newOrdinates; |
| } |
| public Double[] getOrdinatesArray(int startPosition, int endPosition) { |
| Double[] a = new Double[endPosition - startPosition]; |
| System.arraycopy(this.ordinates, startPosition - 1, a, 0, a.length); |
| return a; |
| } |
| |
| public ARRAY toOracleArray(Connection conn) throws SQLException { |
| ArrayDescriptor arrayDescriptor = ArrayDescriptor.createDescriptor( |
| TYPE_NAME, conn); |
| return new ARRAY(arrayDescriptor, conn, this.ordinates); |
| } |
| public Double[] getOrdinatesArray(int startPosition) { |
| Double[] a = new Double[this.ordinates.length - (startPosition - 1)]; |
| System.arraycopy(this.ordinates, startPosition - 1, a, 0, a.length); |
| return a; |
| } |
| |
| } |
| public String toString() { |
| return arrayToString(this.ordinates); |
| } |
| |
| public static class SDO_GEOMETRY { |
| public void addOrdinates(Double[] ordinatesToAdd) { |
| Double[] newOrdinates = new Double[this.ordinates.length |
| + ordinatesToAdd.length]; |
| System.arraycopy(this.ordinates, 0, newOrdinates, 0, |
| this.ordinates.length); |
| System.arraycopy(ordinatesToAdd, 0, newOrdinates, |
| this.ordinates.length, ordinatesToAdd.length); |
| this.ordinates = newOrdinates; |
| } |
| |
| private static final String TYPE_NAME = "MDSYS.SDO_GEOMETRY"; |
| public ARRAY toOracleArray(Connection conn) throws SQLException { |
| ArrayDescriptor arrayDescriptor = ArrayDescriptor.createDescriptor( |
| TYPE_NAME, conn); |
| return new ARRAY(arrayDescriptor, conn, this.ordinates); |
| } |
| |
| private SDO_GTYPE gtype; |
| } |
| |
| private int srid; |
| public static class SDO_GEOMETRY { |
| |
| private SDO_POINT point; |
| private static final String TYPE_NAME = "MDSYS.SDO_GEOMETRY"; |
| |
| private ELEM_INFO info; |
| private SDO_GTYPE gtype; |
| |
| private ORDINATES ordinates; |
| private int srid; |
| |
| public SDO_GEOMETRY() { |
| private SDO_POINT point; |
| |
| } |
| private ELEM_INFO info; |
| |
| /** |
| * This joins an array of SDO_GEOMETRIES to a SDO_GEOMETRY of type |
| * COLLECTION |
| * |
| * @param sdoElements |
| * @return |
| */ |
| public static SDO_GEOMETRY join(SDO_GEOMETRY[] sdoElements) { |
| SDO_GEOMETRY sdoCollection = new SDO_GEOMETRY(); |
| if (sdoElements == null || sdoElements.length == 0) { |
| sdoCollection.setGType(new SDO_GTYPE(2, 0, |
| TypeGeometry.COLLECTION)); |
| } else { |
| SDO_GEOMETRY firstElement = sdoElements[0]; |
| int dim = firstElement.getGType().getDimension(); |
| int lrsDim = firstElement.getGType().getLRSDimension(); |
| sdoCollection.setGType(new SDO_GTYPE(dim, lrsDim, |
| TypeGeometry.COLLECTION)); |
| int ordinatesOffset = 1; |
| for (int i = 0; i < sdoElements.length; i++) { |
| ELEM_INFO element = sdoElements[i].getInfo(); |
| Double[] ordinates = sdoElements[i].getOrdinates() |
| .getOrdinateArray(); |
| if (element != null && element.getSize() > 0) { |
| int shift = ordinatesOffset |
| - element.getOrdinatesOffset(0); |
| shiftOrdinateOffset(element, shift); |
| sdoCollection.addElement(element); |
| sdoCollection.addOrdinates(ordinates); |
| ordinatesOffset += ordinates.length; |
| } |
| } |
| } |
| return sdoCollection; |
| } |
| private ORDINATES ordinates; |
| |
| public ELEM_INFO getInfo() { |
| return info; |
| } |
| public SDO_GEOMETRY() { |
| |
| public void setInfo(ELEM_INFO info) { |
| this.info = info; |
| } |
| } |
| |
| public SDO_GTYPE getGType() { |
| return gtype; |
| } |
| /** |
| * This joins an array of SDO_GEOMETRIES to a SDO_GEOMETRY of type |
| * COLLECTION |
| * |
| * @param sdoElements |
| * @return |
| */ |
| public static SDO_GEOMETRY join(SDO_GEOMETRY[] sdoElements) { |
| SDO_GEOMETRY sdoCollection = new SDO_GEOMETRY(); |
| if (sdoElements == null || sdoElements.length == 0) { |
| sdoCollection.setGType(new SDO_GTYPE(2, 0, |
| TypeGeometry.COLLECTION)); |
| } else { |
| SDO_GEOMETRY firstElement = sdoElements[0]; |
| int dim = firstElement.getGType().getDimension(); |
| int lrsDim = firstElement.getGType().getLRSDimension(); |
| sdoCollection.setGType(new SDO_GTYPE(dim, lrsDim, |
| TypeGeometry.COLLECTION)); |
| int ordinatesOffset = 1; |
| for (int i = 0; i < sdoElements.length; i++) { |
| ELEM_INFO element = sdoElements[i].getInfo(); |
| Double[] ordinates = sdoElements[i].getOrdinates() |
| .getOrdinateArray(); |
| if (element != null && element.getSize() > 0) { |
| int shift = ordinatesOffset |
| - element.getOrdinatesOffset(0); |
| shiftOrdinateOffset(element, shift); |
| sdoCollection.addElement(element); |
| sdoCollection.addOrdinates(ordinates); |
| ordinatesOffset += ordinates.length; |
| } |
| } |
| } |
| return sdoCollection; |
| } |
| |
| public void setGType(SDO_GTYPE gtype) { |
| this.gtype = gtype; |
| } |
| public ELEM_INFO getInfo() { |
| return info; |
| } |
| |
| public ORDINATES getOrdinates() { |
| return ordinates; |
| } |
| public void setInfo(ELEM_INFO info) { |
| this.info = info; |
| } |
| |
| public void setOrdinates(ORDINATES ordinates) { |
| this.ordinates = ordinates; |
| } |
| public SDO_GTYPE getGType() { |
| return gtype; |
| } |
| |
| public SDO_POINT getPoint() { |
| return point; |
| } |
| public void setGType(SDO_GTYPE gtype) { |
| this.gtype = gtype; |
| } |
| |
| public void setPoint(SDO_POINT point) { |
| this.point = point; |
| } |
| public ORDINATES getOrdinates() { |
| return ordinates; |
| } |
| |
| public int getSRID() { |
| return srid; |
| } |
| public void setOrdinates(ORDINATES ordinates) { |
| this.ordinates = ordinates; |
| } |
| |
| public void setSRID(int srid) { |
| this.srid = srid; |
| } |
| public SDO_POINT getPoint() { |
| return point; |
| } |
| |
| public static SDO_GEOMETRY load(STRUCT struct) { |
| public void setPoint(SDO_POINT point) { |
| this.point = point; |
| } |
| |
| Datum[] data; |
| try { |
| data = struct.getOracleAttributes(); |
| } catch (SQLException e) { |
| throw new RuntimeException(e); |
| } |
| public int getSRID() { |
| return srid; |
| } |
| |
| SDO_GEOMETRY geom = new SDO_GEOMETRY(); |
| geom.setGType(SDO_GTYPE.parse(data[0])); |
| geom.setSRID(data[1]); |
| if (data[2] != null) { |
| geom.setPoint(new SDO_POINT((STRUCT) data[2])); |
| } |
| geom.setInfo(new ELEM_INFO((ARRAY) data[3])); |
| geom.setOrdinates(new ORDINATES((ARRAY) data[4])); |
| public void setSRID(int srid) { |
| this.srid = srid; |
| } |
| |
| return geom; |
| } |
| public static SDO_GEOMETRY load(Struct struct) { |
| |
| public static STRUCT store(SDO_GEOMETRY geom, Connection conn) |
| throws SQLException { |
| StructDescriptor structDescriptor = StructDescriptor |
| .createDescriptor(TYPE_NAME, conn); |
| Datum[] attributes = new Datum[5]; |
| attributes[0] = new NUMBER(geom.getGType().intValue()); |
| if (geom.getSRID() > 0) { |
| attributes[1] = new NUMBER(geom.getSRID()); |
| } else { |
| attributes[1] = null; |
| } |
| attributes[3] = geom.getInfo().toOracleArray(conn); |
| attributes[4] = geom.getOrdinates().toOracleArray(conn); |
| return new STRUCT(structDescriptor, conn, attributes); |
| Object[] data; |
| try { |
| data = struct.getAttributes(); |
| } catch (SQLException e) { |
| throw new RuntimeException(e); |
| } |
| |
| } |
| SDO_GEOMETRY geom = new SDO_GEOMETRY(); |
| geom.setGType(SDO_GTYPE.parse(data[0])); |
| geom.setSRID(data[1]); |
| if (data[2] != null) { |
| geom.setPoint(new SDO_POINT((Struct) data[2])); |
| } |
| geom.setInfo(new ELEM_INFO((Array) data[3])); |
| geom.setOrdinates(new ORDINATES((Array) data[4])); |
| |
| private void setSRID(Datum datum) { |
| if (datum == null) { |
| this.srid = 0; |
| return; |
| } |
| try { |
| this.srid = new Integer(((NUMBER) datum).intValue()); |
| } catch (Exception e) { |
| throw new RuntimeException(e); |
| } |
| } |
| return geom; |
| } |
| |
| public boolean isLRSGeometry() { |
| return gtype.isLRSGeometry(); |
| } |
| public static STRUCT store(SDO_GEOMETRY geom, Connection conn) |
| throws SQLException { |
| StructDescriptor structDescriptor = StructDescriptor |
| .createDescriptor(TYPE_NAME, conn); |
| Datum[] attributes = new Datum[5]; |
| attributes[0] = new NUMBER(geom.getGType().intValue()); |
| if (geom.getSRID() > 0) { |
| attributes[1] = new NUMBER(geom.getSRID()); |
| } else { |
| attributes[1] = null; |
| } |
| attributes[3] = geom.getInfo().toOracleArray(conn); |
| attributes[4] = geom.getOrdinates().toOracleArray(conn); |
| return new STRUCT(structDescriptor, conn, attributes); |
| |
| public int getDimension() { |
| return gtype.getDimension(); |
| } |
| } |
| |
| public int getLRSDimension() { |
| return gtype.getLRSDimension(); |
| } |
| private void setSRID(Object datum) { |
| if (datum == null) { |
| this.srid = 0; |
| return; |
| } |
| try { |
| this.srid = new Integer(((Number) datum).intValue()); |
| } catch (Exception e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| public int getZDimension() { |
| return gtype.getZDimension(); |
| } |
| public boolean isLRSGeometry() { |
| return gtype.isLRSGeometry(); |
| } |
| |
| /** |
| * Gets the number of elements or compound elements. |
| * |
| * Subelements of a compound element are not counted. |
| * |
| * @return the number of elements |
| */ |
| public int getNumElements() { |
| int cnt = 0; |
| int i = 0; |
| while (i < info.getSize()) { |
| if (info.getElementType(i).isCompound()) { |
| int numCompounds = info.getNumCompounds(i); |
| i += 1 + numCompounds; |
| } else { |
| i++; |
| } |
| cnt++; |
| } |
| return cnt; |
| } |
| public int getDimension() { |
| return gtype.getDimension(); |
| } |
| |
| public String toString() { |
| StringBuilder stb = new StringBuilder(); |
| stb.append("(").append(gtype).append(",").append(srid).append(",") |
| .append(point).append(",").append(info).append(",").append( |
| ordinates).append(")"); |
| return stb.toString(); |
| } |
| public int getLRSDimension() { |
| return gtype.getLRSDimension(); |
| } |
| |
| public void addOrdinates(Double[] newOrdinates) { |
| if (this.ordinates == null) { |
| this.ordinates = new ORDINATES(newOrdinates); |
| } else { |
| this.ordinates.addOrdinates(newOrdinates); |
| } |
| } |
| public int getZDimension() { |
| return gtype.getZDimension(); |
| } |
| |
| public void addElement(ELEM_INFO element) { |
| if (this.info == null) { |
| this.info = element; |
| } else { |
| this.info.addElement(element); |
| } |
| } |
| /** |
| * Gets the number of elements or compound elements. |
| * <p/> |
| * Subelements of a compound element are not counted. |
| * |
| * @return the number of elements |
| */ |
| public int getNumElements() { |
| int cnt = 0; |
| int i = 0; |
| while (i < info.getSize()) { |
| if (info.getElementType(i).isCompound()) { |
| int numCompounds = info.getNumCompounds(i); |
| i += 1 + numCompounds; |
| } else { |
| i++; |
| } |
| cnt++; |
| } |
| return cnt; |
| } |
| |
| /** |
| * If this SDO_GEOMETRY is a COLLECTION, this method returns an array of |
| * the SDO_GEOMETRIES that make up the collection. If not a Collection, |
| * an array containing this SDO_GEOMETRY is returned. |
| * |
| * @return collection elements as individual SDO_GEOMETRIES |
| */ |
| public SDO_GEOMETRY[] getElementGeometries() { |
| if (getGType().getTypeGeometry() == TypeGeometry.COLLECTION) { |
| List<SDO_GEOMETRY> elements = new ArrayList<SDO_GEOMETRY>(); |
| int i = 0; |
| while (i < this.getNumElements()) { |
| ElementType et = this.getInfo().getElementType(i); |
| int next = i + 1; |
| // if the element is an exterior ring, or a compound |
| // element, then this geometry spans multiple elements. |
| if (et.isExteriorRing()) { // then next element is the |
| // first non-interior ring |
| while (next < this.getNumElements()) { |
| if (!this.getInfo().getElementType(next) |
| .isInteriorRing()) { |
| break; |
| } |
| next++; |
| } |
| } else if (et.isCompound()) { |
| next = i + this.getInfo().getNumCompounds(i) + 1; |
| } |
| SDO_GEOMETRY elemGeom = new SDO_GEOMETRY(); |
| SDO_GTYPE elemGtype = deriveGTYPE(this.getInfo() |
| .getElementType(i), this); |
| elemGeom.setGType(elemGtype); |
| elemGeom.setSRID(this.getSRID()); |
| ELEM_INFO elemInfo = new ELEM_INFO(this.getInfo() |
| .getElement(i)); |
| shiftOrdinateOffset(elemInfo, -elemInfo |
| .getOrdinatesOffset(0) + 1); |
| elemGeom.setInfo(elemInfo); |
| int startPosition = this.getInfo().getOrdinatesOffset(i); |
| ORDINATES elemOrdinates = null; |
| if (next < this.getNumElements()) { |
| int endPosition = this.getInfo().getOrdinatesOffset( |
| next); |
| elemOrdinates = new ORDINATES(this.getOrdinates() |
| .getOrdinatesArray(startPosition, endPosition)); |
| } else { |
| elemOrdinates = new ORDINATES(this.getOrdinates() |
| .getOrdinatesArray(startPosition)); |
| } |
| elemGeom.setOrdinates(elemOrdinates); |
| elements.add(elemGeom); |
| i = next; |
| } |
| return elements.toArray(new SDO_GEOMETRY[elements.size()]); |
| } else { |
| return new SDO_GEOMETRY[] { this }; |
| } |
| } |
| public String toString() { |
| StringBuilder stb = new StringBuilder(); |
| stb.append("(").append(gtype).append(",").append(srid).append(",") |
| .append(point).append(",").append(info).append(",").append( |
| ordinates).append(")"); |
| return stb.toString(); |
| } |
| |
| private static void shiftOrdinateOffset(ELEM_INFO elemInfo, int offset) { |
| for (int i = 0; i < elemInfo.getSize(); i++) { |
| int newOffset = elemInfo.getOrdinatesOffset(i) + offset; |
| elemInfo.setOrdinatesOffset(i, newOffset); |
| } |
| } |
| public void addOrdinates(Double[] newOrdinates) { |
| if (this.ordinates == null) { |
| this.ordinates = new ORDINATES(newOrdinates); |
| } else { |
| this.ordinates.addOrdinates(newOrdinates); |
| } |
| } |
| |
| } |
| public void addElement(ELEM_INFO element) { |
| if (this.info == null) { |
| this.info = element; |
| } else { |
| this.info.addElement(element); |
| } |
| } |
| |
| private static SDO_GTYPE deriveGTYPE(ElementType elementType, |
| SDO_GEOMETRY origGeom) { |
| switch (elementType) { |
| case POINT: |
| case ORIENTATION: |
| return new SDO_GTYPE(origGeom.getDimension(), origGeom |
| .getLRSDimension(), TypeGeometry.POINT); |
| case POINT_CLUSTER: |
| return new SDO_GTYPE(origGeom.getDimension(), origGeom |
| .getLRSDimension(), TypeGeometry.MULTIPOINT); |
| case LINE_ARC_SEGMENTS: |
| case LINE_STRAITH_SEGMENTS: |
| case COMPOUND_LINE: |
| return new SDO_GTYPE(origGeom.getDimension(), origGeom |
| .getLRSDimension(), TypeGeometry.LINE); |
| case COMPOUND_EXTERIOR_RING: |
| /** |
| * If this SDO_GEOMETRY is a COLLECTION, this method returns an array of |
| * the SDO_GEOMETRIES that make up the collection. If not a Collection, |
| * an array containing this SDO_GEOMETRY is returned. |
| * |
| * @return collection elements as individual SDO_GEOMETRIES |
| */ |
| public SDO_GEOMETRY[] getElementGeometries() { |
| if (getGType().getTypeGeometry() == TypeGeometry.COLLECTION) { |
| List<SDO_GEOMETRY> elements = new ArrayList<SDO_GEOMETRY>(); |
| int i = 0; |
| while (i < this.getNumElements()) { |
| ElementType et = this.getInfo().getElementType(i); |
| int next = i + 1; |
| // if the element is an exterior ring, or a compound |
| // element, then this geometry spans multiple elements. |
| if (et.isExteriorRing()) { // then next element is the |
| // first non-interior ring |
| while (next < this.getNumElements()) { |
| if (!this.getInfo().getElementType(next) |
| .isInteriorRing()) { |
| break; |
| } |
| next++; |
| } |
| } else if (et.isCompound()) { |
| next = i + this.getInfo().getNumCompounds(i) + 1; |
| } |
| SDO_GEOMETRY elemGeom = new SDO_GEOMETRY(); |
| SDO_GTYPE elemGtype = deriveGTYPE(this.getInfo() |
| .getElementType(i), this); |
| elemGeom.setGType(elemGtype); |
| elemGeom.setSRID(this.getSRID()); |
| ELEM_INFO elemInfo = new ELEM_INFO(this.getInfo() |
| .getElement(i)); |
| shiftOrdinateOffset(elemInfo, -elemInfo |
| .getOrdinatesOffset(0) + 1); |
| elemGeom.setInfo(elemInfo); |
| int startPosition = this.getInfo().getOrdinatesOffset(i); |
| ORDINATES elemOrdinates = null; |
| if (next < this.getNumElements()) { |
| int endPosition = this.getInfo().getOrdinatesOffset( |
| next); |
| elemOrdinates = new ORDINATES(this.getOrdinates() |
| .getOrdinatesArray(startPosition, endPosition)); |
| } else { |
| elemOrdinates = new ORDINATES(this.getOrdinates() |
| .getOrdinatesArray(startPosition)); |
| } |
| elemGeom.setOrdinates(elemOrdinates); |
| elements.add(elemGeom); |
| i = next; |
| } |
| return elements.toArray(new SDO_GEOMETRY[elements.size()]); |
| } else { |
| return new SDO_GEOMETRY[]{this}; |
| } |
| } |
| |
| private static void shiftOrdinateOffset(ELEM_INFO elemInfo, int offset) { |
| for (int i = 0; i < elemInfo.getSize(); i++) { |
| int newOffset = elemInfo.getOrdinatesOffset(i) + offset; |
| elemInfo.setOrdinatesOffset(i, newOffset); |
| } |
| } |
| |
| } |
| |
| private static SDO_GTYPE deriveGTYPE(ElementType elementType, |
| SDO_GEOMETRY origGeom) { |
| switch (elementType) { |
| case POINT: |
| case ORIENTATION: |
| return new SDO_GTYPE(origGeom.getDimension(), origGeom |
| .getLRSDimension(), TypeGeometry.POINT); |
| case POINT_CLUSTER: |
| return new SDO_GTYPE(origGeom.getDimension(), origGeom |
| .getLRSDimension(), TypeGeometry.MULTIPOINT); |
| case LINE_ARC_SEGMENTS: |
| case LINE_STRAITH_SEGMENTS: |
| case COMPOUND_LINE: |
| return new SDO_GTYPE(origGeom.getDimension(), origGeom |
| .getLRSDimension(), TypeGeometry.LINE); |
| case COMPOUND_EXTERIOR_RING: |
| case EXTERIOR_RING_ARC_SEGMENTS: |
| case EXTERIOR_RING_CIRCLE: |
| case EXTERIOR_RING_RECT: |