//$Header: /home/deegree/jail/deegreerepository/deegree/src/org/deegree/io/datastore/sql/oracle/JGeometryAdapter.java,v 1.13 2006/11/09 17:42:52 mschneider Exp $ /*---------------- FILE HEADER ------------------------------------------ This file is part of deegree. Copyright (C) 2001-2006 by: Department of Geography, University of Bonn http://www.giub.uni-bonn.de/deegree/ lat/lon GmbH http://www.lat-lon.de This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Contact: Andreas Poth lat/lon GmbH Aennchenstraße 19 53177 Bonn Germany E-Mail: poth@lat-lon.de Jens Fitzke lat/lon GmbH Aennchenstraße 19 53177 Bonn Germany E-Mail: jens.fitzke@uni-bonn.de ---------------------------------------------------------------------------*/ package org.deegree.io.datastore.sql.oracle; import java.util.ArrayList; import java.util.List; import oracle.spatial.geometry.JGeometry; import org.deegree.model.crs.CoordinateSystem; import org.deegree.model.spatialschema.Curve; import org.deegree.model.spatialschema.Geometry; import org.deegree.model.spatialschema.GeometryException; import org.deegree.model.spatialschema.GeometryFactory; import org.deegree.model.spatialschema.MultiCurve; import org.deegree.model.spatialschema.MultiPoint; import org.deegree.model.spatialschema.MultiSurface; import org.deegree.model.spatialschema.Point; import org.deegree.model.spatialschema.Position; import org.deegree.model.spatialschema.Ring; import org.deegree.model.spatialschema.Surface; /** * Adapter between deegree <code>Geometry</code> objects and Oracle <code>JGeometry</code> * objects. * * @author <a href="mailto:schneider@lat-lon.de">Markus Schneider </A> * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a> * @author last edited by: $Author: mschneider $ * * @version $Revision: 1.13 $, $Date: 2006/11/09 17:42:52 $ */ public class JGeometryAdapter { private JGeometryAdapter() { // avoid instantiation } /** * Converts a deegree <code>Geometry</code> instance to a corresponding Oracle * <code>JGeometry</code> object. * * @param geometry * deegree <code>Geometry</code> to be converted * @param srid * coordinate system for created Oracle <code>JGeometry</code> objects * @return corresponding Oracle <code>JGeometry</code> * @throws GeometryException */ public static JGeometry export( Geometry geometry, int srid ) throws GeometryException { JGeometry jGeometry = null; if ( geometry instanceof Point ) { jGeometry = exportPoint( (Point) geometry, srid ); } else if ( geometry instanceof MultiPoint ) { jGeometry = exportMultiPoint( (MultiPoint) geometry, srid ); } else if ( geometry instanceof Curve ) { jGeometry = exportCurve( (Curve) geometry, srid ); } else if ( geometry instanceof MultiCurve ) { jGeometry = exportMultiCurve( (MultiCurve) geometry, srid ); } else if ( geometry instanceof Surface ) { jGeometry = exportSurface( (Surface) geometry, srid ); } else if ( geometry instanceof MultiSurface ) { jGeometry = exportMultiSurface( (MultiSurface) geometry, srid ); } else { throw new GeometryException( "Cannot export geometry of type '" + geometry.getClass() + "' to Oracle JGeometry: Unsupported type." ); } return jGeometry; } /** * Converts an Oracle <code>JGeometry</code> instance to a corresponding deegree * <code>Geometry</code> object. * * @param jGeometry * Oracle <code>JGeometry</code> to be converted * @param crs * coordinate system of the created deegree <code>Geometry</code> object * @return corresponding deegree <code>Geometry</code> * @throws GeometryException */ public static Geometry wrap( JGeometry jGeometry, CoordinateSystem crs ) throws GeometryException { Geometry geo = null; switch ( jGeometry.getType() ) { case JGeometry.GTYPE_POINT: geo = wrapPoint( jGeometry, crs ); break; case JGeometry.GTYPE_CURVE: geo = wrapCurve( jGeometry, crs ); break; case JGeometry.GTYPE_POLYGON: geo = wrapSurface( jGeometry, crs ); break; case JGeometry.GTYPE_MULTIPOINT: geo = wrapMultiPoint( jGeometry, crs ); break; case JGeometry.GTYPE_MULTICURVE: geo = wrapMultiCurve( jGeometry, crs ); break; case JGeometry.GTYPE_MULTIPOLYGON: geo = wrapMultiSurface( jGeometry, crs ); break; case JGeometry.GTYPE_COLLECTION: default: { throw new GeometryException( "Cannot export Oracle JGeometry of type '" + jGeometry.getType() + "' to deegree geometry: Unsupported type." ); } } return geo; } /** * Creates an Oracle <code>JGeometry</code> with type <code>GTYPE_POINT</code> from a * <code>Point</code>. * * @param point * @param srid * coordinate system for created Oracle <code>JGeometry</code> objects */ private static JGeometry exportPoint( Point point, int srid ) { int dimension = point.getCoordinateDimension(); double[] coords = point.getAsArray(); if ( dimension == 2 ) { coords = new double[] { coords[0], coords[1] }; } else { coords = new double[] { coords[0], coords[1], coords[2] }; } return JGeometry.createPoint( coords, point.getCoordinateDimension(), srid ); } /** * Creates an Oracle <code>JGeometry</code> with type <code>GTYPE_MULTIPOINT</code> from a * <code>MultiPoint</code>. * * @param multiPoint * @param srid * coordinate system for created Oracle <code>JGeometry</code> objects */ private static JGeometry exportMultiPoint( MultiPoint multiPoint, int srid ) { Point[] points = multiPoint.getAllPoints(); int dimension = multiPoint.getCoordinateDimension(); Object[] coords = new Object[points.length]; for ( int i = 0; i < coords.length; i++ ) { double[] d = points[i].getAsArray(); if ( dimension == 2 ) { coords[i] = new double[] { d[0], d[1] }; } else { coords[i] = new double[] { d[0], d[1], d[2] }; } } return JGeometry.createMultiPoint( coords, multiPoint.getCoordinateDimension(), srid ); } /** * Creates an Oracle <code>JGeometry</code> with type <code>GTYPE_CURVE</code> from a * <code>Curve</code>. * * @param curve * @param srid * coordinate system for created Oracle <code>JGeometry</code> objects */ private static JGeometry exportCurve( Curve curve, int srid ) throws GeometryException { int dimension = curve.getCoordinateDimension(); Position[] positions = curve.getAsLineString().getPositions(); double[] ordinates = new double[positions.length * dimension]; int ordinateIndex = 0; for ( int i = 0; i < positions.length; i++ ) { double[] position = positions[i].getAsArray(); for ( int j = 0; j < dimension; j++ ) { ordinates[ordinateIndex++] = position[j]; } } return JGeometry.createLinearLineString( ordinates, dimension, srid ); } /** * Creates an Oracle <code>JGeometry</code> with type <code>GTYPE_MULTICURVE</code> from a * <code>MultiCurve</code>. * * @param multiCurve * @param srid * coordinate system for created Oracle <code>JGeometry</code> objects * @throws GeometryException */ private static JGeometry exportMultiCurve( MultiCurve multiCurve, int srid ) throws GeometryException { int dimension = multiCurve.getCoordinateDimension(); Curve[] curves = multiCurve.getAllCurves(); Object[] coords = new Object[curves.length]; for ( int i = 0; i < curves.length; i++ ) { Position[] positions = curves[i].getAsLineString().getPositions(); double[] ordinates = new double[positions.length * dimension]; int ordinateIndex = 0; for ( int j = 0; j < positions.length; j++ ) { double[] position = positions[i].getAsArray(); for ( int k = 0; k < dimension; k++ ) { ordinates[ordinateIndex++] = position[k]; } } coords[i] = ordinates; } return JGeometry.createLinearMultiLineString( coords, dimension, srid ); } /** * Creates an Oracle <code>JGeometry</code> with type <code>GTYPE_POLYGON</code> from a * <code>Surface</code>. * * @param surface * @param srid * coordinate system for created Oracle <code>JGeometry</code> objects * @throws GeometryException */ private static JGeometry exportSurface( Surface surface, int srid ) { int dimension = surface.getCoordinateDimension(); Ring exteriorRing = surface.getSurfaceBoundary().getExteriorRing(); Ring[] interiorRings = surface.getSurfaceBoundary().getInteriorRings(); Object[] coords = null; if ( interiorRings != null ) { coords = new Object[1 + interiorRings.length]; } else { coords = new Object[1]; } // counter for rings int ringIndex = 0; Position[] positions = exteriorRing.getPositions(); double[] ringOrdinates = new double[positions.length * dimension]; int ordinateIndex = 0; // process exterior ring for ( int i = 0; i < positions.length; i++ ) { double[] ordinates = positions[i].getAsArray(); for ( int j = 0; j < dimension; j++ ) { ringOrdinates[ordinateIndex++] = ordinates[j]; } } coords[ringIndex++] = ringOrdinates; // process interior rings if ( interiorRings != null ) { for ( int interiorRingIndex = 0; interiorRingIndex < interiorRings.length; interiorRingIndex++ ) { positions = interiorRings[interiorRingIndex].getPositions(); ringOrdinates = new double[positions.length * dimension]; ordinateIndex = 0; for ( int i = 0; i < positions.length; i++ ) { double[] ordinates = positions[i].getAsArray(); for ( int j = 0; j < dimension; j++ ) { ringOrdinates[ordinateIndex++] = ordinates[j]; } } coords[ringIndex++] = ringOrdinates; } } return JGeometry.createLinearPolygon( coords, dimension, srid ); } /** * Creates an Oracle <code>JGeometry</code> with type <code>GTYPE_MULTIPOLYGON</code> from a * <code>MultiSurface</code>. * * @param multiSurface * @param srid * coordinate system for created Oracle <code>JGeometry</code> objects * @throws GeometryException */ private static JGeometry exportMultiSurface( MultiSurface multiSurface, int srid ) { List<Integer> elemInfoList = new ArrayList<Integer>( 50 ); List<Double> ordinateList = new ArrayList<Double>( 5000 ); Surface[] surfaces = multiSurface.getAllSurfaces(); int ordinateIdx = 1; int dimension = multiSurface.getCoordinateDimension(); // for each surface for ( int surfaceIdx = 0; surfaceIdx < surfaces.length; surfaceIdx++ ) { Surface surface = surfaces[surfaceIdx]; // process exterior ring Ring exteriorRing = surface.getSurfaceBoundary().getExteriorRing(); Position[] positions = exteriorRing.getPositions(); elemInfoList.add( new Integer( ordinateIdx ) ); elemInfoList.add( new Integer( 1003 ) ); elemInfoList.add( new Integer( 1 ) ); for ( int i = 0; i < positions.length; i++ ) { double[] ordinates = positions[i].getAsArray(); for ( int j = 0; j < dimension; j++ ) { ordinateList.add( new Double( ordinates[j] ) ); ordinateIdx++; } } // process interior rings Ring[] interiorRings = surface.getSurfaceBoundary().getInteriorRings(); if ( interiorRings != null ) { for ( int interiorRingIdx = 0; interiorRingIdx < interiorRings.length; interiorRingIdx++ ) { positions = interiorRings[interiorRingIdx].getPositions(); elemInfoList.add( new Integer( ordinateIdx ) ); elemInfoList.add( new Integer( 2003 ) ); elemInfoList.add( new Integer( 1 ) ); for ( int i = 0; i < positions.length; i++ ) { double[] ordinates = positions[i].getAsArray(); for ( int j = 0; j < dimension; j++ ) { ordinateList.add( new Double( ordinates[j] ) ); ordinateIdx++; } } } } } int[] elemInfo = new int[elemInfoList.size()]; for ( int i = 0; i < elemInfo.length; i++ ) { elemInfo[i] = elemInfoList.get( i ).intValue(); } double[] ordinates = new double[ordinateList.size()]; for ( int i = 0; i < ordinates.length; i++ ) { ordinates[i] = ordinateList.get( i ).doubleValue(); } return new JGeometry( JGeometry.GTYPE_MULTIPOLYGON, srid, elemInfo, ordinates ); } /** * Creates a <code>Point</code> from an Oracle <code>JGeometry</code> with type * <code>GTYPE_POINT</code>. * * @param geometry * Oracle SDO geometry (must be of type <code>GTYPE_POINT</code>) * @param crs * coordinate system of the created deegree <code>Geometry</code> object * @return deegree geometry * */ private static Point wrapPoint( JGeometry geometry, CoordinateSystem crs ) { double[] ord = geometry.getPoint(); Position pos = GeometryFactory.createPosition( ord ); return GeometryFactory.createPoint( pos, crs ); } /** * Creates a <code>MultiPoint</code> from an Oracle <code>JGeometry</code> with type * <code>GTYPE_MULTIPOINT</code>. * * @param geometry * Oracle SDO geometry (must be of type <code>GTYPE_MULTIPOINT</code>) * @param crs * coordinate system of the created deegree <code>Geometry</code> object * @return deegree geometry * @throws GeometryException * */ private static MultiPoint wrapMultiPoint( JGeometry geometry, CoordinateSystem crs ) { Point[] points = new Point[geometry.getNumPoints()]; double[] ordinates = geometry.getOrdinatesArray(); int dimension = geometry.getDimensions(); for ( int i = 0; i < points.length; i++ ) { double[] pointOrdinates = new double[dimension]; for ( int j = 0; j < dimension; j++ ) { pointOrdinates[j] = ordinates[i * dimension + j]; } Position position = GeometryFactory.createPosition( pointOrdinates ); points[i] = GeometryFactory.createPoint( position, crs ); } return GeometryFactory.createMultiPoint( points ); } /** * Creates a <code>Curve</code> from an Oracle <code>JGeometry</code> with type * <code>GTYPE_CURVE</code>. * * @param geometry * Oracle SDO geometry (must be of type <code>GTYPE_CURVE</code>) * @param crs * coordinate system of the created deegree <code>Geometry</code> object * @return deegree geometry * @throws GeometryException */ private static Curve wrapCurve( JGeometry geometry, CoordinateSystem crs ) throws GeometryException { return GeometryFactory.createCurve( geometry.getOrdinatesArray(), geometry.getDimensions(), crs ); } /** * Creates a <code>MultiCurve</code> from an Oracle <code>JGeometry</code> with type * <code>GTYPE_MULTICURVE</code>. * * @param geometry * Oracle SDO geometry (must be of type <code>GTYPE_MULTICURVE</code>) * @param crs * coordinate system of the created deegree <code>Geometry</code> object * @return deegree geometry * @throws GeometryException */ private static MultiCurve wrapMultiCurve( JGeometry geometry, CoordinateSystem crs ) throws GeometryException { Object[] ooe = geometry.getOrdinatesOfElements(); int dim = geometry.getDimensions(); Curve[] curves = new Curve[ooe.length]; for ( int i = 0; i < ooe.length; i++ ) { curves[i] = GeometryFactory.createCurve( (double[]) ooe[i], dim, crs ); } return GeometryFactory.createMultiCurve( curves ); } /** * Creates a <code>Surface</code> from an Oracle <code>JGeometry</code> with type * <code>GTYPE_POLYGON</code>. * * @param geometry * Oracle SDO geometry (must be of type <code>GTYPE_POLYGON</code>) * @param crs * coordinate system of the created deegree <code>Geometry</code> object * @return deegree geometry * @throws GeometryException */ private static Surface wrapSurface( JGeometry geometry, CoordinateSystem crs ) throws GeometryException { Object[] ooe = geometry.getOrdinatesOfElements(); int dim = geometry.getDimensions(); double[] exteriorRingOrdinates = (double[]) ooe[0]; double[][] interiorRingsOrdinates = null; if ( exteriorRingOrdinates.length == 4 ) { // it's a box double[] tmp = new double[10]; tmp[0] = exteriorRingOrdinates[0]; tmp[1] = exteriorRingOrdinates[1]; tmp[2] = exteriorRingOrdinates[0]; tmp[3] = exteriorRingOrdinates[3]; tmp[4] = exteriorRingOrdinates[2]; tmp[5] = exteriorRingOrdinates[3]; tmp[6] = exteriorRingOrdinates[2]; tmp[7] = exteriorRingOrdinates[1]; tmp[8] = exteriorRingOrdinates[0]; tmp[9] = exteriorRingOrdinates[1]; exteriorRingOrdinates = tmp; } else { if ( ooe.length > 1 ) { interiorRingsOrdinates = new double[ooe.length - 1][]; for ( int i = 0; i < ooe.length - 1; i++ ) { interiorRingsOrdinates[i] = (double[]) ooe[i + 1]; } } } return GeometryFactory.createSurface( exteriorRingOrdinates, interiorRingsOrdinates, dim, crs ); } /** * Creates a <code>MultiSurface</code> from an Oracle <code>JGeometry</code> with type * <code>GTYPE_MULTIPOLYGON</code>. * * @param geometry * Oracle SDO geometry (must be of type <code>GTYPE_MULTIPOLYGON</code>) * @param crs * coordinate system of the created deegree <code>Geometry</code> object * @return deegree geometry * @throws GeometryException */ private static MultiSurface wrapMultiSurface( JGeometry geometry, CoordinateSystem crs ) throws GeometryException { Object[] ooe = geometry.getOrdinatesOfElements(); int dim = geometry.getDimensions(); List<Surface> list = new ArrayList<Surface>( 100 ); int i = 0; while ( i < ooe.length ) { double[] ext = (double[]) ooe[i++]; Surface surf = GeometryFactory.createSurface( ext, null, dim, crs ); boolean within = false; List<double []> temp = new ArrayList<double []>( 100 ); if ( i < ooe.length - 1 ) { do { double[] ord = (double[]) ooe[i++]; double[] pnt = new double[dim]; for ( int j = 0; j < pnt.length; j++ ) { pnt[j] = ord[j]; } Position pos = GeometryFactory.createPosition( pnt ); within = surf.contains( pos ); if ( within ) { temp.add( ord ); } } while ( within && i < ooe.length ); i--; } double[][] in = new double[temp.size()][]; in = temp.toArray( in ); list.add( GeometryFactory.createSurface( ext, in, dim, crs ) ); } Surface[] polys = new Surface[list.size()]; polys = list.toArray( polys ); return GeometryFactory.createMultiSurface( polys ); } } /* ******************************************************************** Changes to this class. What the people have been up to: $Log: JGeometryAdapter.java,v $ Revision 1.13 2006/11/09 17:42:52 mschneider Fixed footer. Revision 1.12 2006/09/19 14:55:03 mschneider Fixed warnings. Revision 1.11 2006/08/24 06:40:05 poth File header corrected Revision 1.10 2006/07/04 19:10:31 poth ArrayList initialization changed for exporting Multisurfaces - initial size increased Revision 1.9 2006/06/01 12:16:51 mschneider Fixed header + footer. Added use of Generics. ********************************************************************** */