Since version 8.1.7, Oracle®
Spatial allows spatial data to be georeferenced. Geometries can be
georeferenced by associating a spatial reference ID (SRID) to each
geometry. Coordinate systems associated to these SRIDs are defined
in the table MDSYS.CS_SRS.
JViews Maps can import
these reference systems using their OpenGIS
WKT (Well Known Text) specifications, found in the MDSYS.CS_SRS
table. If your data is not georeferenced, there is no need to
change anything. The JViews
Maps classes in the
objectmodel
package handle both georeferenced and nongeoreferenced data.
For more information, see the Oracle Spatial documentation
(Coordinate Systems section) and Handling
spatial reference systems.
Classes for reading data from an Oracle Spatial object relational model database
The reader classes for Oracle Spatial object relational model
included in the package ilog.views.maps.format.oracle.objectmodel
are:
- IlvObjectSDOFeatureIterator for converting Oracle Spatial layer data into
IlvMapFeature
Objects. - IlvObjectSDOLayerMetaData and IlvObjectSDODimElement for representing metadata information for a given Spatial Layer.
- IlvObjectSDOKeyExtractor and IlvDefaultObjectSDOKeyExtractor for an optimized use of the load-on-demand.
- IlvObjectSDOLayer for implementing the load-on-demand for object Oracle Spatial data.
- IlvDefaultObjectSDOTileLoader, an optimized subclass of IlvSDOTileLoader is used by
IlvObjectSDOLayer
.
The IlvObjectSDOFeatureIterator class
This class reads data from the result of an SQL query to a
relational Oracle Spatial layer and converts the data into IlvMapFeature objects. The JViews Maps package
applications can handle Oracle Spatial data using this class in
a transparent way. The following example performs a query,
loading data from an Oracle Spatial layer named ROADS:
IlvSDOConnection connection = new IlvSDOConnection(url, userName, password); connection.createConnection(); IlvObjectSDOFeatureIterator iterator = new IlvObjectSDOFeatureIterator(connection.getConnection(), "select * from ROADS", // The name of the geometry column. "GEOMETRY", // No key ID. null, // Name of the x-ordinates column. "X", // Name of the y-ordinates column. "Y");
The result set of any query to an Oracle Spatial layer can be
used to initialize an IlvObjectSDOFeatureIterator, but the
column containing the geometry must be in the result set.
The features returned by the iterator
can have attributes and coordinate systems attached.
- Attributes: they can be retrieved by means of the method getAttributes.Any column of the layer that can be interpreted as a String, a float number, or an integer number is translated into attributes and set in the returned map feature. Moreover, if you instantiate the feature iterator with an ID name, the value of these features can be used to retrieve additional attributes (if any) from the database. See the getId method.This ID is used in the library essentially for load-on-demand optimization. If you give an ID name when instantiating the iterator, a large geometry that covers more than one tile is loaded just once.If you ignore the ID name, the
load()
method of each covered tile fully loads the large geometry. - Coordinate Systems: they can be retrieved by means of the getCoordinateSystem method. This coordinate system is the interpretation of the Well Known Text contained in the MDSYS.CS_SRS table corresponding to the SDO_SRID attached to the geometry read by the iterator. The interpretation is performed by the ilog.views.maps.srs.wkt package.This behavior can be bypassed by using setCoordinateSystem. For example, if you call this method, the coordinate system passed as a parameter is assigned to all the map features returned by the iterator.The Oracle SRID of the geometry that has been currently read by the iterator can be obtained by the getCurrentSRID.
The IlvObjectSDOLayerMetaData and IlvObjectSDODimElement classes
These two classes correspond to two data
structures defined in Oracle Spatial.
The
IlvObjectSDOLayerMetaData
class corresponds to the data contained in each row of the
(XXX_)SDO_GEOM_METADATA
view. This view contains information, called metadata, about Spatial layers. Each
Spatial user has the following views available in the schema
associated with that user (in Oracle 8.1.6+):
USER_SDO_GEOM_METADATA
Contains metadata information for all spatial tables owned by the user (schema). This is the only view that the user must keep up-to-date. For instance, theclose()
method ofIlvObjectSDOWriter
updates this view.ALL_SDO_GEOM_METADATA
Contains metadata information for all spatial tables on which the user has SELECT permission.DBA_SDO_GEOM_METADATA
Contains metadata information for all spatial tables on which the user has SELECT permission (if the user has the DBA role).
Each metadata view has the following
definition:
TABLE_NAME VARCHAR2(32), COLUMN_NAME VARCHAR2(32), DIMINFO MDSYS.SDO_DIM_ARRAY, SRID NUMBER
In addition, the
ALL_SDO_GEOM_METADATA
and
DBA_SDO_GEOM_METADATA
views have an
OWNER
column identifying the schema that owns the table specified in
TABLE_NAME
.
You do not need to build metadata by hand: the IlvObjectSDOUtil method can help you
retrieve the metadata directly from the database. For instance,
if a Spatial layer is called
ROADS
, then you can retrieve its metadata as follows:
IlvObjectSDOLayerMetaData metadata = IlvObjectSDOUtil.GetLayerMetaData(connection.getConnection() "ROADS", // You can pass the geometry column name as null: the first // metadata row that matches the layer name “ROADS” is then // returned. null, // You can pass the metadata view name as null: the default // is "(USER_)SDO_GEOM_METADATA". null, // You can pass the owner name as null: the name of the // current user is then taken as the owner name. null);
The
IlvObjectSDOLayerMetaData
class is then composed of the following elements that match the
(XXX_)SDO_GEOM_METADATA
view: the table name (the name of the Spatial layer), the
geometry column name (called
COLUMN_NAME
in the view, the name of the column of type
MDSYS.SDO_GEOMETRY
), the owner name, the optional SRID if the Spatial layer is
georeferenced, and an array of
IlvObjectSDODimElement
(called
DIMINFO
in the view).
The
IlvObjectSDODimElement
corresponds to the
MDSYS.SDO_DIM_ELEMENT
data type. The
MDSYS.SDO_DIM_ELEMENT
data type is defined in Oracle as:
Create Type SDO_DIM_ELEMENT as OBJECT ( SDO_DIMNAME VARCHAR2(64), SDO_LB NUMBER, SDO_UB NUMBER, SDO_TOLERANCE NUMBER);
The
DIM
element data type describes, for each Spatial Layer, its extent
for each dimension. For instance, for typical two-dimensional
geometries, the
DIM
element array of the metadata table has two entries. The first
entry describes the first dimension (x, longitude), the second
one describes the second dimension (y, latitude).
Note
In the
DIM
element array of the metadata table, the elements are supposed
to be ordered. For example, the first element of the array is
considered as the first dimension of the layer, and so on.
The IlvObjectSDOKeyExtractor and IlvDefaultObjectSDOKeyExtractor classes
The IlvObjectSDOKeyExtractor class is an
interface associated with feature iterators and tile loaders.
Its main purpose is to associate an object with the map feature
read by the iterator or the tile loader.
This object is supposed to be unique, so
that the next time the feature iterator meets the object, it is
not process the geometry in the corresponding row, considering
that this geometry has already been loaded.
The goal is to avoid multiple loading of the same geometry.
This interface extracts a key from a
ResultSet
using the
extractKey(java.sql.ResultSet)
method. The object returned can be extracted from one Table
column or multiple columns as soon as it constitutes a unique
object.
![multitile.gif](../usrprgmaps/_media/multitile_default.gif)
Example of Multiple Loading in
Load-On-demand
The red rectangle belongs to the tile (2, 2) and (2, 3). When
the
load
method of the tile (2, 2) is called, it loads the rectangle.
When the
load
method of the tile (2, 3) is called, the rectangle is loaded
again as soon as it intersects with this tile too, and the tile
loader has no way to know that this geometry has already been
loaded. You can avoid this by using the
IlvObjectSDOKeyExtractor
class.
The IlvDefaultObjectSDOKeyExtractor is a
default class that implements the key extraction behavior from
one Table column. For example,
given the previous schema let us suppose that the Spatial Layer
is:
GEOMETRY MDSYS.SDO_GEOMETRY, ID NUMBER
Note
The ID column does not need to be
described in Oracle as a key, when it contains unique values.
The
IlvDefaultObjectSDOKeyExtractor
used with this layer can be easily obtained in the following
way:
IlvDefaultObjectSDOKeyExtractor extractor = new IlvDefaultObjectSDOKeyExtractor("ID");
Then, this extractor can be associated with an
IlvObjectSDOLayer
, or an
IlvDefaultObjectSDOTileLoader
.
IlvObjectSDOLayer layer = new IlvObjectSDOLayer(connection, IlvObjectSDOUtil.GetLayerMetaData(...), 1000, 1000, "X", "Y", extractor, // used here null);
The IlvObjectSDOLayer class
This class implements load-on-demand for
an object Oracle Spatial data source. The default
implementation takes an Oracle Spatial layer for which a
spatial indexation has been performed and reads its content.
The following example creates an IlvObjectSDOLayer on an Oracle Spatial
layer named ROADS:
IlvSDOConnection connection = new IlvSDOConnection(url, userName, password); connection.createConnection(); IlvObjectSDOLayer layer = new IlvObjectSDOLayer(connection, // The name of the SDO layer. "ROADS", // Width of a tile in the database // coordinate system. 1500, // Height of a tile in the database // coordinate system. 1500, // Special handling of ID. null //Is not required. ); manager.addLayer(layer,-1);
The IlvDefaultObjectSDOTileLoader class
This class is a subclass of IlvSDOTileLoader and is used by the
IlvObjectSDOLayer
. It has some optimizations.
For example, the method setTileGroupingCount allows you to set
the number of tiles that are grouped in one unique query to the
database. In fact, each tile corresponds to a Spatial Query,
and if you have an average of
n
tiles to load each time you want to load on demand, you should
use
setTileGroupingCount(n)
, where all the n queries are grouped into one unique query
that is sent to the database once.
Note
If you want to handle some special operations on each
IlvMapFeature
retrieved in load-on-demand with the
IlvObjectSDOLayer
layer, you have to subclass the
IlvDefaultObjectSDOTileLoader
in order to override the
getFeatureIterator
method. In this method, you have to return an instance of a
subclass of
IlvObjectSDOFeatureIterator
where you have overridden the
getNextFeature
method (inside which you can perform your specific operations
on each
IlvMapFeature
returned by the layer). Finally, you have to set your subclass
of
IlvDefaultObjectSDOTileLoader
as the tile loader of the layer.
Another interesting method of this class is the setRequestParameters method.
This method allows you, for instance, to
set the spatial operator used to query the layer. The default
operator is SDO_FILTER.
Tiles shows a Spatial layer using a fixed
tiling of level 2. The red rectangle is the area queried by the
tile loader. If the SDO_FILTER operator is used (default case),
all the geometries belonging to the Oracle Spatial Tiles
intersecting with the red rectangle fit the request. In the
case of Tiles, all the geometries belonging to
the tiles (2,2), (2,3), (3,2), and (3,3), for example the line,
the point, the triangle, the circle, and the rectangle are
retrieved.
You may not want to retrieve the
geometries that do not explicitly intersect with the red
rectangle (for example, the circle and the rectangle geometries
here). In this case, you have two choices.
- The first choice is to keep the SDO_FILTER operator and to use the setClippingRequest method in order to let the tile loader perform a bounding box clipping check.
- The second choice is to use another spatial operator in Oracle which is SDO_RELATE. This operator is to be used with the following parameters: "
querytype=window mask=anyinteract
". This way, thesetClippingRequest()
is not needed anymore so that all the retrieved geometries are the ones that intersect with the red rectangle, for example the point, the triangle, and the line in Tiles.
Finally, note that the SDO_RELATE
Spatial operator is slower than the SDO_FILTER operator.
![tiles.gif](../usrprgmaps/_media/tiles_default.gif)
Tiles
Class for writing data to an Oracle Spatial object relational model database
This section presents the IlvObjectSDOWriter class, which allows you
to write map features into an Object Oracle Spatial database.
The class
IlvObjectSDOWriter
can write any IlvMapFeature or any IlvMapFeatureIterator whose features have a
geometry supported by Oracle Spatial 8i (vectorial geometries)
and write them to the database as in the following example:
IlvSDOConnection connection = new IlvSDOConnection(url, userName, password); connection.createConnection(); IlvObjectSDOWriter writer = new IlvObjectSDOWriter(connection.getConnection(), "MyLayer", // Layer name. "GEOMETRY", // Geometry column. "X", // X ordinate name. "Y", // Y ordinate name. true // Create table. ); IlvShapeFileReader reader = new IlvShapeFileReader("foo.shp",null); int saved_objects_count = writer.writeFeatureIterator(reader, false, // No attributes null );// No SRID writer.close(0.0, // Tolerance null );// No SRID
Note
In the case of the Oracle Spatial Object Model, some auxiliary
tables, like the
(USER_)SDO_GEOM_METADATA
view, need to be updated. It is very important to call the
method
IlvObjectSDOWriter.close()
once the data has been written through the
write()
method, so that the database is kept up-to-date.
The writeFeature method of the
IlvObjectSDOWriter
can also write the attributes of the feature.
The method writeFeature has a second argument that can
be set to
true
to save the attributes of the specified map feature. This
requires that the map feature has an IlvAttributeInfoProperty correctly set,
describing the attributes that match the Oracle Spatial layer
column names. This also requires that map feature has an IlvFeatureAttributeProperty IlvFeatureAttributeProperty that fits its IlvAttributeInfoProperty and has correct
values.
For instance, if you have an Oracle
Spatial layer called ROADS that has the following description in
the database:
Name |
Null? |
Type |
GEOMETRY |
MDSYS.SDO_GEOMETRY |
|
TYPE_DESC |
VARCHAR2(512) |
The third argument of the
writeFeature()
method allows you to set the SDO_SRID value of the written
SDO_GEOMETRY. The value of the SDO_SRID is exactly one of the
SRID values of the MDSYS.CS_SRS table, and it represents the
corresponding coordinate system for the written geometry.
The following code extract shows how to
write features with a unique attribute into the database:
IlvSDOConnection connection = new IlvSDOConnection(url, userName, password); connection.createConnection(); IlvObjectSDOWriter writer = new IlvObjectSDOWriter(connection.getConnection(), "myLayer", "GEOMETRY", "X", "Y", false); java.lang.String[] names = new String[1]; names[0] = "ATTRIBUTE_NAME"; java.lang.Class[] classes = new Class[1]; classes[0] = java.lang.String.class; boolean[] nullable = new boolean[1]; nullable[0] = true; // Creates the attribute info. IlvAttributeInfoProperty info = new IlvAttributeInfoProperty(names, classes, nullable); // Sets the attribute to feature. IlvFeatureAttribute[] attributes = new IlvFeatureAttribute[1]; attributes[0] = new IlvStringAttribute("MY FOO TYPE"); IlvFeatureAttributeProperty prop = new IlvFeatureAttributeProperty(info,attributes); feature.setAttributeInfo(info); feature.setAttributes(prop); // Writes the feature. try { writer.writeFeature(feature,true, null); // no SRID } catch (java.sql.SQLException e) { // Error. e.printStackTrace(); } writer.close(0.0, null); // no SRID
The writer can update rows in the SDO layer. This is based on a
key mechanism, where the row(s) having the value of the given key
are updated. The update is done through the following methods
from the IlvObjectSDOWriter class:
- updateFeatureAttributes based on an attribute property where you have to give the position of the key in the attribute list and you can update more than one column at the same time.
- updateFeatureAttribute where you update just one column (the new value is the
attributeToUpdate
passed as argument) given a key attribute.NoteAll the subclasses ofIlvMapGeometry
exceptIlvMapText
,IlvMapImage
, andIlvMapRaster
are supported by the object model writer.