This discussion is archived
1 Reply Latest reply: Apr 2, 2013 1:10 AM by Simon Greener RSS

Oracle java Spatial API

FlyingGuy Explorer
Currently Being Moderated
Hey there Folks...

As we all know, within the Oracle it is trivial to perform the following:
if sdo_anyinteract(geom1,geom2) = 'TRUE' then
do_some_stuff ;
end if;
We are setting up to pull in a live feed that delivers point referenced data and this data stream is unfiltered. The stream can put out 250K - 300K points ( with associated information ) about every 30 seconds, or about 40gigs of data every day. Our area of interest is a fraction of that, so we need to geo filter the data.

Each point comes as a bare long & lat so we have the basic information we need to perform the filter. While it is possible to do this filter quite simply by simply testing bounds within a rectangle we need something a bit more sophisticated so we want to do a polygon interaction, which the above code sprite would accomplish very neatly and simply, but would require the data to be sent to the database and either stored or rejected.

We are writing the feed code in Java so we thought it appropriate to perform the filter before the data is sent to the database. The issue is that I don't really see a way to do this or at least an obvious way to do this in either JGeometry or with in CompGeom.

Ideally the polygon used for the filter would be read from the database as an SDO object, then each data point would be typed as a Point2D and then an equivalent function to sdo_anyinteract() to qualify the point for inclusion into the stored data set.

Any advice on this would be appreciated.
  • 1. Re: Oracle java Spatial API
    Simon Greener Journeyer
    Currently Being Moderated
    I'm probably overlooking something but I don't think the Oracle Java code allows you to compare to objects to see if there is anyinteract.

    Certainly, the JTS Topology Suite does as can be seen from this method from my SC4O code.
        /**
         * ST_Relate
         *
         * Implements a license free version of sdo_geom.RELATE.
         * @note Supports SC4O named topological relationships and not Oracle specific keywords like OVERLAPBDYDISJOINT
         * @param _geom1 : STRUCT : First geometry
         * @param _mask : String : Mask containing DETERMINE, ANYINTERACT or a list of comma separated topological relationships
         * @param _geom2 : STRUCT : Second geometry
         * @param _precision : int    : Number of decimal places of precision of a geometry
         * @return String    : Result of comparison.
         * @throws SQLException
         * @history Simon Greener, November 2011, Original coding.
         * @copyright : Licensed under a Creative Commons Attribution-Share Alike 2.5 Australia License.
         * http://creativecommons.org/licenses/by-sa/2.5/au/
         */
        public static String ST_Relate(STRUCT _geom1,
                                       String _mask,
                                       STRUCT _geom2,
                                       int    _precision)
        throws SQLException 
        {
            // Check parameters
            //
            if ( _geom1 == null || _geom2 == null ) {
                throw new SQLException("One or other of supplied Sdo_Geometries is NULL.");
            }
            String mask = _mask;
            if ( Tools.isEmpty(_mask) ) {
              // make same as determine
              // 
              mask = "DETERMINE"; 
            }        
            String returnString = "";
            try
            {  
              // Extract SRIDs from SDO_GEOMETRYs make sure same
              //
              int SRID = SDO.getSRID(_geom1,SDO.SRID_NULL);
              if ( SRID != SDO.getSRID(_geom2,SDO.SRID_NULL) ) {
                  throw new SQLException("SRIDs of Sdo_Geometries must be equal");
              }
              
              // Convert Geometries
              //
              PrecisionModel  pm = new PrecisionModel(Tools.getPrecisionScale(_precision));
              GeometryFactory gf = new GeometryFactory(pm,SRID); 
              OraReader       or = new OraReader(gf);
              Geometry      geo1 = or.read(_geom1);
              Geometry      geo2 = or.read(_geom2);
              
              // Check converted geometries are valid
              //
              if (   geo1 == null  ) { throw new SQLException("Converted first geometry is NULL."); }
              if ( ! geo1.isValid()) { throw new SQLException("Converted first geometry is invalid."); }
              if (   geo2 == null  ) { throw new SQLException("Converted second geometry is NULL."); }
              if ( ! geo2.isValid()) { throw new SQLException("Converted second geometry is invalid." ); }
              
              // Now get relationship mask
              IntersectionMatrix im = RelateOp.relate(geo1,geo2);
              // Process relationship mask
              int dimGeo1 = geo1.getDimension();
              int dimGeo2 = geo2.getDimension();
              if ( im.isEquals(dimGeo1,dimGeo2)) {
                  returnString = "EQUAL";
              } else if ( im == null ) {
                  returnString = "UNKNOWN";
              } else {
                  ArrayList al = new ArrayList();
                  if ( im.isContains())                al.add("CONTAINS");
                  if ( im.isCoveredBy())               al.add("COVEREDBY");
                  if ( im.isCovers())                  al.add("COVERS");
                  if ( im.isCrosses( dimGeo1,dimGeo2)) al.add("CROSS"); 
                  if ( im.isDisjoint())                al.add("DISJOINT"); 
                  if ( im.isIntersects())              al.add("INTERSECTS");
                  if ( im.isOverlaps(dimGeo1,dimGeo2)) al.add("OVERLAP");
                  if ( im.isTouches( dimGeo1,dimGeo2)) al.add("TOUCH");
                  if ( im.isWithin())                  al.add("WITHIN");
                  // Now compare to user mask
                  //
                  if ( mask.equalsIgnoreCase("ANYINTERACT") ) {
                      // If the ANYINTERACT keyword is passed in mask, the
                      // function returns TRUE if two geometries not disjoint.
                      //
                      return al.size()==0
                             ?"UNKNOWN"
                             :(al.contains("DISJOINT")?"FALSE":"TRUE");
                  } else if ( mask.equalsIgnoreCase("DETERMINE") ) {
                      // If the DETERMINE keyword is passed in mask, return
                      // the one relationship keyword that best matches the geometries.
                      // 
                      Iterator iter = al.iterator();
                      returnString = "";
                      while (iter.hasNext()) {
                          returnString += (String)iter.next() +",";
                      }
                      // remove unwanted end ","
                      returnString = returnString.substring(0, returnString.length()-1);
                  } else {
                      // If a mask listing one or more relationships is passed in, 
                      // the function returns the name of the relationship if it
                      // is true for the pair of geometries. If all relationships 
                      // are false, the procedure returns FALSE.
                      //
                      StringTokenizer st = new StringTokenizer(mask.toUpperCase(),",");
                      String token = "";
                      returnString = "";
                      while ( st.hasMoreTokens() ) {
                          token = st.nextToken();
                          if ( al.contains(token) )
                              returnString += token + ",";
                      }
                      if ( returnString.length()==0 ) {
                          // Passed in relationships do not exist 
                          returnString = "FALSE";  
                      } else {
                          // remove unwanted end ","
                          returnString = returnString.substring(0, returnString.length()-1);
                      }
                  }
              }
            } catch(SQLException sqle) {
                System.err.println(sqle.getMessage());
                returnString = "UNKNOWN";
            } catch (Exception e) {
                returnString = "UNKNOWN";
            }
          return returnString;
        }
    regards
    Simon

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points