Object Model Classes
This section covers the following topics:
Classes for Reading Data from an Oracle Spatial Database
The reader classes for the Oracle SDO object model are:
To implement load-on-demand for object Oracle Spatial data.
IlvObjectSDOFeatureIterator
This class reads data from the result of an SQL query to a relational Oracle Spatial layer and converts it into
IlvMapFeature objects. Rogue Wave Views Maps applications can handle Oracle Spatial data using this class in a transparent manner. The following example of C++ code performs a query (using Rogue Wave DB Link), loading data from an Oracle Spatial layer named ROADS:
IlString query = IlString("SELECT * FROM ROADS"); IldDbms* myDbms = IldNewDbms("oracle81", "scott/tiger@myDomain"); IlvObjectSDOFeatureIterator* iterator = new IlvObjectSDOFeatureIterator(myDbms, "SELECT * FROM ROADS", // the name of the geometries column "Geometry", // no Key ID 0, // the name of the x ordinates column "X", // the 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 this iterator have attributes and can be retrieved through the method
getAttributes(). In fact, 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 this column is set to the identifier of each map feature and the identifiers of these features can be used to retrieve additional attributes (if any) from the database. See the method
getId(). This ID is used in the library for optimization reasons. If you give an ID name when instantiating the iterator, a “big” geometry that covers more than one tile will be loaded just once. If you ignore the ID name, the
load method of each covered tile will fully load the “big” geometry.
IlvObjectSDOLayer
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:
IldDbms* myDbms = IldNewDbms("oracle81", "scott/tiger@myDomain"); // You should create an adapter that fits your data. IlvMapAdapter* adapter = new IlvMapAdapter(0.5); IlvObjectSDOLayer* layer = new IlvObjectSDOLayer(adapter, myDbms, // The name of the SDO layer "ROADS". // Assume that the layer has only one // geometry column. 0, // Width of a tile in the database // coordinate system. 1500, // height of a tile in the database // coordinate system. 1500, // The name of the x-ordinates column "X". // The name of the y-ordinates column "Y". ); manager->addLayer(layer); |
You can also build a layer by ignoring the x and y column names. The default values are 0:
IlvObjectSDOLayer* layer = new IlvObjectSDOLayer(adapter, myDbms, "ROADS", 0, 1500, 1500); |
This way, the layer assumes that in the metadata table (SDO_GEOM_METADATA in Oracle 8.1.5 or USER_SDO_GEOM_METADATA in Oracle 8.1.6), the entry corresponding to the ROADS layer has the following shape:
‘ROADS’, ‘GEOMETRY’, SDO_DIM_ARRAY(SDO_DIM_ELEMENT(’X’, -180, 180, 0), SDO_DIM_ELEMENT(’Y’, -90, 90, 0));
The X element is assumed to be the first SDO_DIM_ELEMENT, and the Y element is assumed to be the second one.
IlvDefaultObjectSDOTileLoader
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 will be 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 will be grouped into one unique query that will be sent to the database once.
Another interesting method of this class is the setRequestParameters() method.
This method allows you to set the spatial operator used to query the layer. The default operator is SDO_FILTER.
Figure 5.1 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 that intersect with the red rectangle will fit the request. In the case of
Figure 5.1, all the geometries belonging to tiles (2,2), (2,3), (3,2), and (3,3), for example the line, the point, the triangle, the circle, and the rectangle will be 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). To do this, you can use another spatial operator in Oracle which is
SDO_RELATE. This operator is to be used with the following parameters:
"querytype=window mask=anyinteract". In this way, all the retrieved geometries are the ones that intersect with the red rectangle, for example the point, the triangle, and the line in
Figure 5.1.
Finally, note that the SDO_RELATE Spatial operator is slower than the SDO_FILTER operator.
Figure 5.1 Tiles
Class for Writing Data to an Oracle Spatial Database
This section presents the
IlvObjectSDOWriter class, which allows you to write map features into an Object Oracle Spatial database.
IlvObjectSDOWriter
The class
IlvObjectSDOWriter can write 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:
IldDbms* myDbms = IldNewDbms(“oracle8”, “scott/tiger@myDomain”); IlvObjectSDOWriter* writer = new IlvObjectSDOWriter(myDbms, “MyLayer”, “GEOMETRY”, “X”, “Y”, IlTrue); // Create a source feature iterator. IlvShapeFileReader* reader = new IlvShapeFileReader(“foo.shp”, 0); // Dump its content to the Oracle layer. IlvInt count; writer->writeFeatureIterator(reader, count); // calls close() |
Note: In the case of the Oracle Spatial Object model, some auxiliary tables, like the user metadata table, 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 write method of the
IlvObjectSDOWriter can also
write the attributes of the features.
The method
IlvObjectSDOWriter::writeFeature (
IlvMapFeature*
feature,
IlvBoolean saveAttributes) has a second argument that can be set to
IlTrue in order to save the attributes of the first argument, the map feature. This requires that the map feature has an
IlvFeatureAttributeInfo correctly set, describing the attributes that match the SDO layer column names. This also requires that map feature has an
IlvFeatureAttributeProperty that fits its
IlvFeatureAttributeInfo and has correct values. For example, if you have an SDO layer called
ROADS that has the following description in the database:
Name | Null? | Type |
GEOMETRY | | MDSYS.SDO_GEOMETRY |
TYPE_DESC | | VARCHAR2(512) |
you can write a map feature into the database this way:
IldDbms* myDbms = IldNewDbms("oracle81", "scott/tiger@myDomain"); IlvObjectSDOWriter* myWriter = new IlvObjectSDOWriter(myDbms, "ROADS", "GEOMETRY", "X", "Y", IlTrue); IlvMapFeature* feature = new IlvMapFeature(); // Construction of the IlvFeatureAttributeInfo: it can be done just once. IlvMapClassInfo** attributeClasses = new IlvMapClassInfo*[1]; IlvBoolean* nullable = new IlvBoolean[1]; nullable[0] = IlTrueIlTrue; attributeClasses[0] = IlvStringAttribute::ClassInfo(); char** names = new char*[1]; names[0] = new char[10]; //Exactly the same name as the layer column name. strcpy(names[0], "TYPE_DESC"); IlvFeatureAttributeInfo* info = new IlvFeatureAttributeInfo(1, names, attributeClasses, nullable); // The writing itself. IlvFeatureAttribute** attributes = new IlvFeatureAttribute*[1]; attributes[0] = new IlvStringAttribute("MY FOO TYPE"); IlvMapsError error; IlvFeatureAttributeProperty* prop = new IlvFeatureAttributeProperty(info, attributes, error); feature->setAttributeInfo(info); feature->setAttributes(prop); if (error == IlvMaps::NoError()) error = myWriter->writeFeature(feature, IlTrue); |
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 will be updated. The update is executed by means of the following methods:
updateFeatureAttributes (
IlvFeatureAttributeProperty*
attributes,
IlvUInt keyPos) - based on an attribute property where you have to give the position of the key in the attributes list and you can update more than one column at the same time.
updateFeatureAttribute (
const char* keyColumnName,
IlvFeatureAttribute*
keyAttribute,
const char* attributeColumnName,
IlvFeatureAttribute*
attributeToUpdate) - where you update just one column (the new value is the
attributeToUpdate passed as argument) given a KEY attribute.
Version 5.5.1
Copyright © 2012, Rogue Wave Software, Inc. All Rights Reserved.