All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.vividsolutions.jts.io.oracle.OraGeom Maven / Gradle / Ivy

The newest version!
/*
 * The JTS Topology Suite is a collection of Java classes that
 * implement the fundamental operations required to validate a given
 * geo-spatial data set to a known topological specification.
 *
 * Copyright (C) 2001 Vivid Solutions
 *
 * 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
 *
 * For more information, contact:
 *
 *     Vivid Solutions
 *     Suite #1A
 *     2328 Government Street
 *     Victoria BC  V8T 5G5
 *     Canada
 *
 *     (250)385-6040
 *     www.vividsolutions.com
 */
package com.vividsolutions.jts.io.oracle;

import java.text.DecimalFormat;
import java.text.NumberFormat;

import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryCollection;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.MultiLineString;
import com.vividsolutions.jts.geom.MultiPoint;
import com.vividsolutions.jts.geom.MultiPolygon;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;

/**
 * Represents the contents of an Oracle SDO_GEOMETRY structure.
 * Also provides code values and convenience methods for working
 * with SDO_GEOMETRY values.
 * 
 * @author Martin Davis
 *
 */
class OraGeom
{
	public static final int NULL_DIMENSION = -1;	

	private static NumberFormat fmt = new DecimalFormat("0.################");
	  
	public static final String SQL_NULL = "NULL";

  int gType;
  int srid;
  double[] point = null;
  int[] elemInfo = null;
  double[] ordinates = null;
  private int geomType;
  private int ordDim;
  private int lrsDim;

  public OraGeom(int gType, int srid, double[] ptType, int[] elemInfo, double[] ordinates)
  {
    this.gType = gType;
    this.srid = srid;
    this.point = ptType;
    this.elemInfo = elemInfo;
    this.ordinates = ordinates;
    geomType = gTypeGeomType(gType);
    ordDim = gTypeDim(gType);
    lrsDim = gTypeMeasureDim(gType);
  }

  public OraGeom(int gType, int srid, int[] elemInfo, double[] ordinates)
  {
    this(gType, srid, null, elemInfo, ordinates);
  }

  public OraGeom(int gType, int srid, double[] ptType)
  {
    this(gType, srid, ptType, null, null);
  }

  public int geomType()
  {
    return geomType;
  }

  public int ordDim()
  {
    return ordDim;
  }

  public int lrsDim()
  {
    return lrsDim;
  }
  
  public boolean isCompactPoint()
  {
    return lrsDim == 0 && geomType == OraGeom.GEOM_TYPE.POINT && point != null && elemInfo == null;
  }
  
  public boolean isEqual(OraGeom og)
  {
    if (gType != og.gType) return false;
//    if (srid != og.srid) return false;
    if (! isEqual(point, og.point))
        return false;
    // assume is defined by elemInfo and ordinates
    if (! isEqual(elemInfo, og.elemInfo)) 
      return false;
    if (! isEqual(ordinates, og.ordinates)) 
      return false;
    return true;
  }

  private boolean isEqual(double[] a1, double[] a2)
  {
    if (a2 == null || a1 == null) {
      return a2 == a1;
    }
    if (a1.length != a2.length) return false;
    for (int i = 0; i < a1.length; i++) {
      // check NaN == NaN
      if (Double.isNaN(a1[i]) && Double.isNaN(a2[i])) 
    	  continue;
      if (a1[i] != a2[i]) 
    	  return false;
    }
    return true;
  }
  private boolean isEqual(int[] a1, int[] a2)
  {
    if (a2 == null || a1 == null) {
      return a2 == a1;
    }
    if (a1.length != a2.length) return false;
    for (int i = 0; i < a1.length; i++) {
      if (a1[i] != a2[i]) return false;
    }
    return true;
  }
  
  public String toString()
  {
	  return toSQLString();
	  /*
	  return "GTYPE=" + gType 
			  + " SRID=" + srid
			  + " ELEM_INFO=" + toStringElemInfo(elemInfo)
			  + " ORDS=" + toString(ordinates);
			  */
  }
  
  public String toSQLString()
  {
  	StringBuffer buf = new StringBuffer();
  	buf.append("SDO_GEOMETRY(");
  	
  	buf.append(gType);
  	buf.append(",");
  	
  	buf.append(srid >= 0 ? String.valueOf(srid) : SQL_NULL);
  	buf.append(",");
  	
  	buf.append(toStringPointType());
  	buf.append(",");
  	
  	buf.append(toStringElemInfo());
  	buf.append(",");
  	
  	buf.append(toStringOrdinates());
  	buf.append(")");
  	
  	return buf.toString();
  }
  
  private String toString(double[] ordinates)
  {
    if (ordinates == null) return SQL_NULL;
    
    StringBuffer buf = new StringBuffer();
    for (int i = 0; i < ordinates.length; i++) {
      if (i > 0) {
        buf.append(",");
        // spacer between triplets
        if (i % ordDim == 0)
          buf.append("  ");
      }
      buf.append(number(ordinates[i]));
    }
    return buf.toString();
  }

  private static String number(double d)
  {
	 if (Double.isNaN(d)) return SQL_NULL;
	 return fmt.format(d);
  }
  
  public static String toStringElemInfo(int[] elemInfo)
  {
    if (elemInfo == null) return "null";
    StringBuffer buf = new StringBuffer();
    for (int i = 0; i < elemInfo.length; i++) {
      if (i > 0) {
        buf.append(",");
        // spacer between triplets
        if (i % 3 == 0)
          buf.append("  ");
      }
      buf.append(elemInfo[i]);
    }
    return buf.toString();
  }
  
  private Object toStringOrdinates() {
	  if (ordinates == null) {
		 return SQL_NULL;
	  }
	  return "SDO_ORDINATE_ARRAY(" + toString(ordinates) + ")"; 
  }

  private Object toStringElemInfo() {
	  if (elemInfo == null) {
		 return SQL_NULL;
	  }
	  return "SDO_ELEM_INFO_ARRAY(" + toStringElemInfo(elemInfo) + ")"; 
  }

  private Object toStringPointType() {
	  if (point == null) {
		 return SQL_NULL;
	  }
	  return "SDO_POINT_TYPE(" 
	  	+ number(point[0]) + ","
	  	+ number(point[1]) + ","
	  	+ number(point[2])
	  	+ ")"; 
  }

public int startingOffset(int elemIndex)
  {
    // if beyond actual elements, return "virtual" startingOffset
    if (((elemIndex * 3)) >= elemInfo.length) {
      return ordinates.length + 1;
    }
    return elemInfo[elemIndex * 3];
  }

  /**
   * Extracts the SDO_ELEM_INFO ETYPE value for a given triplet.
   *
   * @param elemIndex index of the triplet to read
   * @return ETYPE for indicated triplet, or -1 if the triplet index is out of range
   * 
   * @see ETYPE
   */
  public int eType(int elemIndex)
  {
    if (((elemIndex * 3) + 1) >= elemInfo.length) {
      return -1;
    }
    return elemInfo[(elemIndex * 3) + 1];
  }

  /**
   * Extracts the SDO_ELEM_INFO interpretation value (SDO_INTERPRETATION) for a given triplet.
   * 

* JTS valid interpretation values are: 1 for straight edges, 3 for rectangle * Other interpretation value include: 2 for arcs, 4 for circles * * @param elemIndex index of the triplet to read * @return interpretation value, or -1 if the triplet index is out of range */ public int interpretation(int elemIndex) { if (((elemIndex * 3) + 2) >= elemInfo.length) { return -1; } return elemInfo[(elemIndex * 3) + 2]; } public int ordinateLen() { if (ordinates != null) return ordinates.length; return 0; } public int numElements() { if (elemInfo == null) return 0; return elemInfo.length / 3; } /** * Computes the SDO_GTYPE code for the given D, L, and TT components. * * @param dim the coordinate dimension * @param lrsDim the measure dimension * @param geomType the geometry type code * @return the SDO_GTYPE code */ public static int gType(int dim, int lrsDim, int geomType) { return dim * 1000 + lrsDim * 100 + geomType; } /** * Returns the GTYPE GEOM_TYPE code * corresponding to the geometry type. * * @see OraGeom.GEOM_TYPE * * @param geom the geometry to compute the GEOM_TYPE for * @return geom type code, if known, or UNKNOWN */ static int geomType(Geometry geom) { if (geom == null) { return OraGeom.GEOM_TYPE.UNKNOWN_GEOMETRY; } else if (geom instanceof Point) { return OraGeom.GEOM_TYPE.POINT; } else if (geom instanceof LineString) { return OraGeom.GEOM_TYPE.LINE; } else if (geom instanceof Polygon) { return OraGeom.GEOM_TYPE.POLYGON; } else if (geom instanceof MultiPoint) { return OraGeom.GEOM_TYPE.MULTIPOINT; } else if (geom instanceof MultiLineString) { return OraGeom.GEOM_TYPE.MULTILINE; } else if (geom instanceof MultiPolygon) { return OraGeom.GEOM_TYPE.MULTIPOLYGON; } else if (geom instanceof GeometryCollection) { return OraGeom.GEOM_TYPE.COLLECTION; } return OraGeom.GEOM_TYPE.UNKNOWN_GEOMETRY; } /** * Extracts the coordinate dimension containing the Measure value from * an SDO_GTYPE code. * For a measured geometry this is 0, 3 or 4. 0 indicates that the last dimension is the measure dimension * For an non-measured geometry this is 0. * * @param gType an SDO_GTYPE code * @return the Measure dimension */ static int gTypeMeasureDim(int gType) { return (gType % 1000) / 100; } /** * Extracts the coordinate dimension from an SDO_GTYPE code. * * @param gType an SDO_GTYPE code * @return the coordinate dimension */ static int gTypeDim(int gType) { return gType / 1000; } /** * Extracts the GEOM_TYPE code from an SDO_GTYPE code. * * @param gType an SDO_GTYPE code * @return the GEOM_TYPE code */ static int gTypeGeomType(int gType) { return gType % 100; } /** * Extracts the SDO_ELEM_INFO start index (SDO_STARTING_OFFSET) in the ordinate array for a given triplet. * Starting offsets are 1-based indexes. * * @param elemInfo the SDO_ELEM_INFO array * @param tripletIndex index of the triplet to read * @return Starting Offset, or -1 if the triplet index is too large */ static int startingOffset(int[] elemInfo, int tripletIndex) { if (((tripletIndex * 3) + 0) >= elemInfo.length) { return -1; } return elemInfo[(tripletIndex * 3) + 0]; } /** * Extracts the SDO_ELEM_INFO interpretation value (SDO_INTERPRETATION) for a given triplet. *

* JTS valid interpretation values are: 1 for straight edges, 3 for rectangle * Other interpretation value include: 2 for arcs, 4 for circles * * @param elemInfo the SDO_ELEM_INFO array * @param tripletIndex index of the triplet to read * @return interpretation value, or -1 if the triplet index is too large */ static int interpretation(int[] elemInfo, int tripletIndex) { if (((tripletIndex * 3) + 2) >= elemInfo.length) { return -1; } return elemInfo[(tripletIndex * 3) + 2]; } /** * Extracts the SDO_ELEM_INFO ETYPE value for a given triplet. *

* @see OraGeom.ETYPE for an indication of possible values * * @param elemInfo the SDO_ELEM_INFO array * @param tripletIndex index of the triplet to read * @return ETYPE for indicated triplet, or -1 if the triplet index is too large */ static int eType(int[] elemInfo, int tripletIndex) { if (((tripletIndex * 3) + 1) >= elemInfo.length) { return -1; } return elemInfo[(tripletIndex * 3) + 1]; } /** * Codes used in SDO_INTERPRETATION attribute. * * @author Martin Davis * */ static final class INTERP { public static final int POINT = 1; public static final int LINESTRING = 1; public static final int POLYGON = 1; public static final int RECTANGLE = 3; } /** * Codes used to specify geometry type * These are used in the last two digits in a GTYPE value. */ static final class GEOM_TYPE { /** TT code representing Unknown type */ public static final int UNKNOWN_GEOMETRY = 00; /** TT code representing Point */ public static final int POINT = 01; /** TT code representing Line (or Curve) */ public static final int LINE = 02; /** TT code representing Polygon */ public static final int POLYGON = 03; /** TT code representing Collection */ public static final int COLLECTION = 04; /** TT code representing MultiPoint */ public static final int MULTIPOINT = 05; /** TT code representing MultiLine (or MultiCurve) */ public static final int MULTILINE = 06; /** TT code representing MULTIPOLYGON */ public static final int MULTIPOLYGON = 07; } /** * Codes used in the SDO_ETYPE attribute. * The code indicates the type of element denoted by an SDO_ELEM_INFO triplet. */ static final class ETYPE { /** ETYPE code representing Point */ public static final int POINT = 1; /** ETYPE code representing Line */ public static final int LINE = 2; /** ETYPE code representing Polygon ring * Shell or hole is determined by orientation (CCW or CW). * Now deprecated. */ public static final int POLYGON = 3; /** * ETYPE code representing exterior counterclockwise polygon ring */ public static final int POLYGON_EXTERIOR = 1003; /** ETYPE code representing interior clockwise polygon ring */ public static final int POLYGON_INTERIOR = 2003; } /** * Oracle types used by SDO_GEOMETRY */ public static final String TYPE_GEOMETRY = "MDSYS.SDO_GEOMETRY"; public static final String TYPE_ELEM_INFO_ARRAY = "MDSYS.SDO_ELEM_INFO_ARRAY"; public static final String TYPE_ORDINATE_ARRAY = "MDSYS.SDO_ORDINATE_ARRAY"; public static final String TYPE_POINT_TYPE = "MDSYS.SDO_POINT_TYPE"; /** * Value indicating a Null SRID. */ public static final int SRID_NULL = -1; }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy