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 convert Oracle Spatial layer data into IlvMapFeature objects.
To implement load-on-demand for object Oracle Spatial data.
Abstract class to define Oracle queries for the IlvObjectSDOLayer. A subclass, IlvDefaultObjectSDOTileLoader, which has some optimizations, is used by IlvObjectSDOLayer.
IlvObjectSDOFeatureIterator
This class reads data from the result of an SQL query to a relational Oracle Spatial layer and converts it into IlvMapFeature objects. 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 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.
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 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 that intersect with the red rectangle will fit the request. In the case of Tiles, 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 Tiles.
Finally, note that the SDO_RELATE Spatial operator is slower than the SDO_FILTER operator.
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.
IlInt 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, IlUInt 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.
Note: All the subclasses of IlvMapGeometry except IlvMapText, IlvMapImage, and IlvMapRaster are supported by the object writer.
Published date: 05/24/2022
Last modified date: 02/24/2022