/*
* GISToolkit - Geographical Information System Toolkit
* (C) 2003, Ithaqua Enterprises Inc.
*
* 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;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package gistoolkit.datasources.oracle;
import java.util.logging.Logger;
import gistoolkit.features.*;
import oracle.sdoapi.OraSpatialManager;
import oracle.sdoapi.geom.CoordPoint;
import oracle.sdoapi.geom.CoordPointImpl;
import oracle.sdoapi.geom.CurveString;
import oracle.sdoapi.geom.Geometry;
import oracle.sdoapi.geom.GeometryFactory;
/**
* Class to read the SDO format objects, and convert them to GISToolkit features.
*/
public class SDOParser {
private static final Logger LOGGER = Logger.getLogger("gistoolkit.datasources.oracle.SDOParser");
/** variable for creating the GeometryFactory asociated with this parser. */
private GeometryFactory myGeometryFactory = null;
/** Creates a new instance of SDOParser */
public SDOParser() {
myGeometryFactory = OraSpatialManager.getGeometryFactory();
}
/** Factory for creating SDO Geometries */
private oracle.sdoapi.geom.GeometryFactory mySDOFactory = null;
/** Converts a SDOPoint to a GISToolkit Point. */
private static Point convertSDOPoint(oracle.sdoapi.geom.Point inPoint){
return new Point(inPoint.getX(), inPoint.getY());
}
/** Converts a SDOLineString to a GISToolkit LineString. */
private static LineString convertSDOLineString(oracle.sdoapi.geom.LineString inLineString){
CoordPoint[] tempPoints = inLineString.getPointArray();
if (tempPoints == null) return null;
double[] tempXPoints = new double[tempPoints.length];
double[] tempYPoints = new double[tempPoints.length];
for (int i=0; i<tempPoints.length; i++){
tempXPoints[i] = tempPoints[i].getX();
tempYPoints[i] = tempPoints[i].getY();
}
return new LineString(tempXPoints, tempYPoints);
}
/** Converts a SDO Curve String to a GISToolkit LineString. */
private static LineString convertSDOCurveString(oracle.sdoapi.geom.CurveString inCurveString){
CoordPoint[] tempPoints = inCurveString.getPointArray();
if (tempPoints == null) return null;
double[] tempXPoints = new double[tempPoints.length];
double[] tempYPoints = new double[tempPoints.length];
for (int i=0; i<tempPoints.length; i++){
tempXPoints[i] = tempPoints[i].getX();
tempYPoints[i] = tempPoints[i].getY();
}
return new LineString(tempXPoints, tempYPoints);
}
/** Converts a SDO Curve String to a GISToolkit LinearRing. */
private static LinearRing convertSDOCurveStringToLinearRing(oracle.sdoapi.geom.CurveString inCurveString){
CoordPoint[] tempPoints = inCurveString.getPointArray();
if (tempPoints == null) return null;
double[] tempXPoints = new double[tempPoints.length];
double[] tempYPoints = new double[tempPoints.length];
for (int i=0; i<tempPoints.length; i++){
tempXPoints[i] = tempPoints[i].getX();
tempYPoints[i] = tempPoints[i].getY();
}
return new LinearRing(tempXPoints, tempYPoints);
}
/** Converts a SDO Polygon to a GISToolkit Polygon. */
private static Polygon convertSDOCurvePolygon(oracle.sdoapi.geom.CurvePolygon inPolygon){
// convert the external ring.
CurveString tempSDORing = inPolygon.getExteriorRing();
if (tempSDORing == null) return null;
LinearRing tempRing = convertSDOCurveStringToLinearRing(tempSDORing);
// convert the internal rings (holes).
CurveString[] tempSDOHoles = inPolygon.getInteriorRingArray();
LinearRing[] tempHoles = null;
if (tempSDOHoles != null){
tempHoles = new LinearRing[tempSDOHoles.length];
for (int i=0; i<tempSDOHoles.length; i++){
tempHoles[i] = convertSDOCurveStringToLinearRing(tempSDOHoles[i]);
}
}
// construct the polygon
return new Polygon(tempRing, tempHoles);
}
/** Converts a SDO MultiPoint to a GISToolkit MultiPoint. */
private static MultiPoint convertSDOMultiPoint(oracle.sdoapi.geom.MultiPoint inMultiPoint){
Geometry[] tempGeometries = inMultiPoint.getGeometryArray();
if (tempGeometries == null) return null;
double[] tempXs = new double[tempGeometries.length];
double[] tempYs = new double[tempGeometries.length];
for (int i=0; i<tempGeometries.length; i++){
tempXs[i] = ((oracle.sdoapi.geom.Point) tempGeometries[i]).getX();
tempYs[i] = ((oracle.sdoapi.geom.Point) tempGeometries[i]).getX();
}
return new MultiPoint(tempXs, tempYs);
}
/** Converts a SDO MultiCurveString to a GISToolkit MultiLineString. */
private static MultiLineString convertSDOMultiCurveString(oracle.sdoapi.geom.MultiCurveString inMultiCurveString){
Geometry[] tempGeometries = inMultiCurveString.getGeometryArray();
if (tempGeometries == null) return null;
LineString[] tempLineStrings = new LineString[tempGeometries.length];
for (int i=0; i<tempGeometries.length; i++){
tempLineStrings[i] = convertSDOCurveString((oracle.sdoapi.geom.CurveString) tempGeometries[i]);
}
return new MultiLineString(tempLineStrings);
}
/** Converts a SDO MultiCurvePolygon to a GISToolkit MultiPolygon. */
private static MultiPolygon convertSDOMultiCurvePolygon(oracle.sdoapi.geom.MultiCurvePolygon inMultiCurvePolygon){
Geometry[] tempGeometries = inMultiCurvePolygon.getGeometryArray();
if (tempGeometries == null) return null;
Polygon[] tempPolygons = new Polygon[tempGeometries.length];
for (int i=0; i<tempGeometries.length; i++){
tempPolygons[i] = convertSDOCurvePolygon((oracle.sdoapi.geom.CurvePolygon) tempGeometries[i]);
}
return new MultiPolygon(tempPolygons);
}
/**
* Converts an oracle geometry to a GISToolkit feature.
*
* If the geometry type is not recognized, or the geometry can not be parsed, then the return from this
* method will be null. Since the GISToolkit features do not support multi dimensional coordinates
* or curves, the geometries will be flattened and linearized if there are curves or elevations/measures
* in the source.
*/
public static Shape convertSDO(Geometry inGeometry){
if (inGeometry == null) return null;
Class tempType = inGeometry.getGeometryType();
Shape tempShape = null;
if (tempType.equals(oracle.sdoapi.geom.Point.class)) tempShape = convertSDOPoint((oracle.sdoapi.geom.Point) inGeometry);
else if (tempType.equals(oracle.sdoapi.geom.LineString.class)) tempShape = convertSDOLineString((oracle.sdoapi.geom.LineString) inGeometry);
else if (tempType.equals(oracle.sdoapi.geom.CurveString.class)) tempShape = convertSDOCurveString((oracle.sdoapi.geom.CurveString) inGeometry);
else if (tempType.equals(oracle.sdoapi.geom.Polygon.class)) tempShape = convertSDOCurvePolygon((oracle.sdoapi.geom.CurvePolygon) inGeometry);
else if (tempType.equals(oracle.sdoapi.geom.CurvePolygon.class)) tempShape = convertSDOCurvePolygon((oracle.sdoapi.geom.CurvePolygon) inGeometry);
else if (tempType.equals(oracle.sdoapi.geom.MultiPoint.class)) tempShape = convertSDOMultiPoint((oracle.sdoapi.geom.MultiPoint) inGeometry);
else if (tempType.equals(oracle.sdoapi.geom.MultiLineString.class)) tempShape = convertSDOMultiCurveString((oracle.sdoapi.geom.MultiCurveString) inGeometry);
else if (tempType.equals(oracle.sdoapi.geom.MultiCurveString.class)) tempShape = convertSDOMultiCurveString((oracle.sdoapi.geom.MultiCurveString) inGeometry);
else if (tempType.equals(oracle.sdoapi.geom.MultiPolygon.class)) tempShape = convertSDOMultiCurvePolygon((oracle.sdoapi.geom.MultiCurvePolygon) inGeometry);
else if (tempType.equals(oracle.sdoapi.geom.MultiCurvePolygon.class)) tempShape = convertSDOMultiCurvePolygon((oracle.sdoapi.geom.MultiCurvePolygon) inGeometry);
else{
String message = "Unhandled geometry type " + tempType.getName();
LOGGER.warning(message);
}
return tempShape;
}
/** Converts a GISToolkit point to an oracle SDOPoint. */
private oracle.sdoapi.geom.Point convertPoint(Point inPoint) throws oracle.sdoapi.geom.InvalidGeometryException {
return myGeometryFactory.createPoint(inPoint.getX(), inPoint.getY());
}
/** Converts a GISToolkit LineString to an oracle LineString. */
private oracle.sdoapi.geom.LineString convertLineString(LineString inLineString) throws oracle.sdoapi.geom.InvalidGeometryException {
double[] tempXs = inLineString.getXCoordinates();
double[] tempYs = inLineString.getYCoordinates();
CoordPoint[] tempPoints = new CoordPoint[tempXs.length];
for (int i=0; i<tempPoints.length; i++){
tempPoints[i] = new CoordPointImpl(tempXs[i], tempYs[i]);
}
return myGeometryFactory.createLineString(tempPoints);
}
/** Converts a GISToolkit LineString to an oracle LineString. */
private oracle.sdoapi.geom.LineString convertLinearRing(LinearRing inLinearRing) throws oracle.sdoapi.geom.InvalidGeometryException {
double[] tempXs = inLinearRing.getXCoordinates();
double[] tempYs = inLinearRing.getYCoordinates();
CoordPoint[] tempPoints = new CoordPoint[tempXs.length];
for (int i=0; i<tempPoints.length; i++){
tempPoints[i] = new CoordPointImpl(tempXs[i], tempYs[i]);
}
return myGeometryFactory.createLineString(tempPoints);
}
/** Converts a GISToolkit Polygon to an oracle Polygon. */
private oracle.sdoapi.geom.Polygon convertPolygon(Polygon inPolygon) throws oracle.sdoapi.geom.InvalidGeometryException {
LinearRing tempRing = inPolygon.getPosativeRing();
LinearRing[] tempHoles = inPolygon.getHoles();
oracle.sdoapi.geom.LineString tempSDOExtRing = convertLinearRing(tempRing);
oracle.sdoapi.geom.LineString[] tempSDOHoles = new oracle.sdoapi.geom.LineString[0];
if ((tempHoles != null)&&(tempHoles.length>0)){
tempSDOHoles = new oracle.sdoapi.geom.LineString[tempHoles.length];
for (int i=0; i<tempHoles.length; i++){
tempSDOHoles[i] = convertLinearRing(tempHoles[i]);
}
}
return myGeometryFactory.createPolygon(tempSDOExtRing, tempSDOHoles);
}
/** Converts a GISToolkit MultiPoint to an oracle MultiPoint. */
private oracle.sdoapi.geom.GeometryCollection convertMultiPoint(MultiPoint inMultiPoint) throws oracle.sdoapi.geom.InvalidGeometryException {
double[] tempXs = inMultiPoint.getXCoordinates();
double[] tempYs = inMultiPoint.getYCoordinates();
oracle.sdoapi.geom.Point[] tempPoints = new oracle.sdoapi.geom.Point[tempXs.length];
for (int i=0; i<tempXs.length; i++){
tempPoints[i] = myGeometryFactory.createPoint(tempXs[i], tempYs[i]);
}
return myGeometryFactory.createGeometryCollection(tempPoints);
}
/** Converts a GISToolkit MultiLineString to an Oracle MultiLineString. */
private oracle.sdoapi.geom.GeometryCollection convertMultiLineString(MultiLineString inMultiLineString) throws oracle.sdoapi.geom.InvalidGeometryException {
LineString[] tempLineStrings = inMultiLineString.getLines();
oracle.sdoapi.geom.LineString[] tempSDOLineStrings = new oracle.sdoapi.geom.LineString[tempLineStrings.length];
for (int i=0; i<tempLineStrings.length; i++){
tempSDOLineStrings[i] = convertLineString(tempLineStrings[i]);
}
return myGeometryFactory.createGeometryCollection(tempSDOLineStrings);
}
/** Converts a GISToolkit MultiPolygon to an Oracle MultiPolygon. */
private oracle.sdoapi.geom.GeometryCollection convertMultiPolygon(MultiPolygon inMultiPolygon) throws oracle.sdoapi.geom.InvalidGeometryException {
Polygon[] tempPolygons = inMultiPolygon.getPolygons();
oracle.sdoapi.geom.Polygon[] tempSDOPolygons = new oracle.sdoapi.geom.Polygon[tempPolygons.length];
for (int i=0; i<tempPolygons.length; i++){
tempSDOPolygons[i] = convertPolygon(tempPolygons[i]);
}
return myGeometryFactory.createGeometryCollection(tempSDOPolygons);
}
/**
* Converts an GISToolkit feature to an oracle geometry.
*
* Since the GISToolkit features are two dimensional and linear, the closest oracle equivalent will be used
* to express the feature. No attempt is made to preserve the Oracle dimensions or curves.
*/
public Geometry convert(Shape inFeature) throws oracle.sdoapi.geom.InvalidGeometryException {
if (inFeature == null) return null;
String tempType = inFeature.getShapeType();
Geometry tempGeometry = null;
if (tempType.equals(Shape.POINT)) tempGeometry = convertPoint((gistoolkit.features.Point) inFeature);
else if (tempType.equals(Shape.LINESTRING)) tempGeometry = convertLineString((gistoolkit.features.LineString) inFeature);
else if (tempType.equals(Shape.LINEARRING)) tempGeometry = convertLinearRing((gistoolkit.features.LinearRing) inFeature);
else if (tempType.equals(Shape.POLYGON)) tempGeometry = convertPolygon((gistoolkit.features.Polygon) inFeature);
else if (tempType.equals(Shape.MULTIPOINT)) tempGeometry = convertMultiPoint((gistoolkit.features.MultiPoint) inFeature);
else if (tempType.equals(Shape.MULTILINESTRING)) tempGeometry = convertMultiLineString((gistoolkit.features.MultiLineString) inFeature);
else if (tempType.equals(Shape.MULTIPOLYGON)) tempGeometry = convertMultiPolygon((gistoolkit.features.MultiPolygon) inFeature);
else{
String message = "Unhandled geometry type " + tempType;
LOGGER.warning(message);
}
return tempGeometry;
}
}