wiki:FDORfc60

FDO RFC 60 - Add OGC Annotation Support to the FDO API

This page contains a request for comments document (RFC) for the FDO Open Source project. More FDO RFCs can be found on the RFCs page.

Status

RFC Template Version1.1
Submission DateApril 13, 2011
Last ModifiedGreg Boone, April 13, 2011
AuthorGreg Boone
RFC StatusNot Ready For Review
Implementation StatusNot Started
Proposed Milestone3.7.0.0
Assigned PSC guide(s)Greg Boone
Voting History(vote date)
+1
+0
-0
-1

Overview

The RFC is being proposed in order to add formal OGC Annotation Support to the FDO API.

Since the FDO API will continue to be used by muliple types of clients as an interchange format, support for annotation/cartographic text will evenetually need to be added to the FDO API, and exposed through our providers.

The FDO representation of Annotation Text will be based (as closely as possible) on the OGC specification for cartographic text. The initial requirement would be to support the capabilities of Annotation Text so that the editing representation in our client would round-trip with full fidelity.

Motivation

Spatially placed text is a common requirement of applications. Many application have stored their text placement information in proprietary manners due lack of a consistent and usable standard. Although the mechanisms for text storage have tended to be compatible, the actual format for exchange has been sufficiently different, and, therefore, non-standardized to interfere with complete data exchange and common usage.

Annotation text is simply placed text that can carry either geographically-related or ad-hoc data and process-related information is displayable text. This text may be used for display in editors or in simpler maps. It is usually lacking in full cartographic quality, but may act as an approximation to such text as needed by any application.

The primary purpose of standardizing this concept is to enable any application using any version of Simple Features data storage or XML to read and write text objects that will describe where and how the text should be displayed. This design ensures that applications that do text placement should have no problem storing their results and that applications that comply with the standard should have no problem exchanging information on text and its placement. Unlike spatial geometries, text display is very dependent on client text rendering engines and the style and layout attributes applied. The spatial area covered by text is only partially determined by the locating geometry. Style and layout attributes along with the actual text and locating geometry are all needed to display text correctly. Thus, it is critical to have a place to store these attributes in the feature database. While it is impossible to guarantee absolute fidelity of display on all rendering systems, applications can interoperate at a useful level.

The most common perception of text display is for cartographic purposes, for printed maps of high technical and artistic quality. While this is a potential use of placed text, its more every-day use is for identification of features in any display, regardless of the purpose of that display. So both cartographic preprint and data collection edit displays have a requirement for placed-text, albeit at different levels of artistic quality. The purpose is still the same, to aid in the understanding of the “mapped” features, either for map use or feature edit and analysis.

Text can also be used for less precise annotation purposes and more for quick display of text labels that make a display more understandable. The text so placed may not even have any associations to real-world features, but may be used to store information pertinent to the process that the data is undergoing at the moment. Thus, in a data collecting and edit display, a particular placed text may be used to indicate an error in the data that needs to be resolved, such as “sliver,” “gap” and “loop” error in digitization. Here the annotation is placed near the geometric error, but is not necessarily associated to a particular feature, as much as to a portion or portions of feature geometry objects.

Annotation text can include text on maps derived from vector information, or text overlays for imagery for information not discernable from the image, such as place or street names. In most cases, applications that do this have certain rules for creating and re-creating text based on the dynamic view of the mapping application. While this standard is not targeted to those usages, there are some allowances for this type of storage if it is so desired. In particular, it is allowable to store text that does not scale with the map objects but instead has a fixed display size (expressed as “points”, 72 to the inch). However, there are some limitations on this usage particularly with spatial indexing.

A text object consists of an ordered list of independently placed text elements, possibly corresponding to individual lines of text in a multiline text display, and an envelope that approximates an outer limit of the text elements when placed. Each element has its own text attributes, but they are not used independently. The first element may set the attribute for all following elements and subsequent elements text attributes are only specified when a change is required. This behavior just extends that of the metadata text attributes to each element of the array.

A text object consists of a text string and information about its placement. The most important piece of information is the geometry to which the text is to refer, here referred to as the location geometry. A second geometry may be required to visually connect the placed text and the location geometry, especially where the location geometry is crowded in an area with other close-by features. This other geometry is referred to here as a leader line, and is a displayable curve of no geographic significance. If indexing is used, the envelope or minimum bounding box of the text is a handy piece of information that should be available. If unavailable, the envelope can be calculated from the processes of placing the text. Since this is often cumbersome, precalculating the envelope and storing it is often the most efficient manner to use this information. The other information associated to the annotation text is the various style information, such as the size of the text (usually in units appropriate to the display, such as pixels or points), the font used, characteristics of the font.

Proposed Solution

Supporting Annotations in Existing (Non-FDO) Schema

In order for the FDO API to be able to detect and support Annotation defined in existing schemas such as Oracle, the schema being read must support the Annotation metadata tables as mandated by the OGC Simple Feature Access Specification. The metadata can be exposed as a set of tables or views.

OGC Annotation Metadata Table

As specified in the OGC Simaple Access Specification, the following CREATE TABLE statement creates an appropriately structured table to be included in the schema, describing how text is stored in a feature table. This should be either an actual metadata table or an updateable view.

There is no requirement that the annotated feature have any other attributes. Unattributed annotations are in essence context-free, and may be used to place any text on the data, such as collection metadata or notes to user about unusual situations of which he may wish to be aware.

CREATE TABLE ANNOTATION_TEXT_METADATA AS
{
    F_TABLE_CATALOG AS CHARACTER VARYING NOT NULL,
    F_TABLE_SCHEMA AS CHARACTER VARYING NOT NULL,
    F_TABLE_NAME AS CHARACTER VARYING NOT NULL,
    F_TEXT_KEY_COLUMN AS CHARACTER VARYING NOT NULL,
    F_TEXT_ENVELOPE_COLUMN AS CHARACTER VARYING NOT NULL,
    A_ELEMENT_TABLE_CATALOG AS CHARACTER VARYING NOT NULL,
    A_ELEMENT_TABLE_SCHEMA AS CHARACTER VARYING NOT NULL,
    A_ELEMENT_TABLE_NAME AS CHARACTER VARYING NOT NULL,
    A_ELEMENT_TEXT_KEY_COLUMN AS CHARACTER VARYING NOT NULL
    A_ELEMENT_TEXT_SEQ_COLUMN AS CHARACTER VARYING NOT NULL
    A_ELEMENT_TEXT_VALUE_COLUMN AS CHARACTER VARYING NOT NULL,
    A_ELEMENT_TEXT_LEADERLINE_COLUMN AS CHARACTER VARYING NOT NULL,
    A_ELEMENT_TEXT_LOCATION_COLUMN AS CHARACTER VARYING NOT NULL,
    A_ELEMENT_TEXT_ATTRIBUTES_COLUMN AS CHARACTER VARYING NOT NULL,
    A_TEXT_DEFAULT_EXPRESSION AS CHARACTER VARYING,
    A_TEXT_DEFAULT_ATTRIBUTES AS CHARACTER VARYING
}

There are no constraints on rows in this table, allowing a single feature table/geometry column pair to be annotated using text from different feature table columns.

OGC Annotation Metadata Column Descriptions

The fields in the Annotations metadata information view are given in:

COLUMNSDESCRIPTION
F_TABLE_CATALOG,
F_TABLE_SCHEMA,
F_TABLE_NAME
The fully qualified name of the feature table containing the geometry column to be annotated.
F_TEXT_KEY_COLUMN,
F_TEXT_KEY_ENVELOPE_COLUMN
The names of the column in the feature table that contain: A KEY for the text to which the text elements can use as a point of aggregation. An ENVELOPE_COLUMN that contains a geometry object that acts as an envelope for the set of text elements in this text entity. This column should also be a valid geometry column.
A_ELEMENT_TABLE_CATALOG,
A_ELEMENT_TABLE_SCHEMA,
A_ELEMENT_TABLE_NAME
The fully qualified name of the text element table containing the text elements used for the F_Text columns column defined above
A_TEXT_ELEMENT_KEY_COLUMN,
A_TEXT_ELEMENT_SEQ_COLUMN,
A_TEXT_ELEMENT_VALUE_COLUMN,
A_TEXT_ELEMENT_LEADERLINE_COLUMN,
A_TEXT_ELEMENT_LOCATION_COLUMN,
A_TEXT_ELEMENT_ATTRIBUTES_COLUMN
The names of the columns in the ELEMENT_TABLE that contain:
The foreign KEY for the text entity as specified in the F_TEXT_KEY_COLUMN.
A sequence (SEQ) column which will be used to order the text elements in this text entity. Any sortable type is valid for this column in the table, although integers would be the obvious choice.
A text string VALUE for this text element.
The LEADERLINE for this text element ⎯ if it has one (should also be a geometry column).
The LOCATION for this text element (should also be a geometry column).
The local text ATTRIBUTES providing the opportunity to override the text attributes currently in force. This is an XML type, and will be a collection of XML elements each describing a text attribute of the current text element. Unspecified attributes take the value most recently defined.
A_TEXT_DEFAULT_EXPRESSION,
A_TEXT_DEFAULT_ATTRIBUTES
The default values for the corresponding “A_TEXT_” columns above, for cases where these columns are NULL in the feature table. They may be values or “query” expressions in terms of other columns in the database. These defaults shall be overridden on a row by row basis when the corresponding columns in the feature table row are not NULL.

Integrating Annotation Text Concepts into the FDO API

In order to support Annotation Text and the concepts outlined in the sections above, the object and metadata relationships defined by the OGC Simple Feature Access Specification will be incorporated into the FDO API as outlined in the sections below.

Annotation Text Definitions as an FDO Property Definition

Annotation Text and its logical metadata will be creatable, modifiable and describable via the FDO API schema. Annotation Text will be defined as properties on FDO Feature Classes and be exposed in the same manner as Geometry, Raster and Associations, via an FDO property definition class that derives from FdoPropertyDefinition. In this manner, class FdoAnnotationPropertyDefinition will be added to the API and will contain the definition of the schema, classes and properties that define the location of the Annotation components. These elements are the logical properties that are needed to store the annotation text value, envelope, leader line, location and text attributes. The schema, classes and properties identified by these metadata properties will in turn be accessible through their own FDO schema definitions.

Starting from an Existing Physical Schema

Let us use the following physical schema as a starting point for further discussion. In this example a Road table is used to capture the Location, Name and Width of road objects in a city. Associated to the Road table is a RoadAnnotation table that contains textual labels that describe the road. A Road object can be associated to 0…n RoadAnnotation objects.

These two classes are related through their primary identifiers.

Road.FeatId == RoadAnnotation.ParentId

Road features can be related n times to RoadAnnotation objects through a combination of matching primary identifiers and the RoadAnnotation SequenceId. The full primary key on RoadAnnotation is therefore a combination of the ParentId and SequenceId. The SequenceId column is used to order the text elements associated to Road. Any sortable type is valid for this column in the table, although integers would be the obvious choice.

The RoadAnnotation table contains a set of properties that are in form (not name) mandated by the OGC specification. These properties, taken together, represent a complete Annotation Text Element. Each Text Element is defined by its Location or spatial geometry, a textual display Value, a textual description of its display model Attributes, and the geographic Leader Line that is used to place the Text Value in relation to its owner or neighboring features.

The optional “Text” properties defined on the Road table are also mandated by the OGC Specification. Implementing applications may optionally provide a means of capturing the overall Text Envelope, a Default Text Value and a set of Default Text Attributes to be used to describe all instances of Annotation Text associated to the parent feature. The Default values are used if no values (NULL) are specified for a individual instance of an Annotation object. The Text Default Value may be a text string or a query expression. Text Default Attributes are typically serialized XML documents that describe how to symbolize text entities and their leader lines.

In the example above, I show these properties defined on the parent Road table, however, they could in fact be located in any schema:table in the data store and their location and property names described using metadata.

Starting from the Road Table described above, let’s construct a simple set of attribute data to represent a Road and several Annotation Text Elements. NOTE: Geometry and Envelope information are not described below.

Road Features

FeatIdNameWidthDefaultTextValue
100Main St.25
200First Ave.20
300Second Ave.20Expr(“Road.Name”)

RoadAnnotation Text Elements

ParentIdSequenceIdTextValue
1001“Main St.”
1002“Main St.”
2001“First Avenue”
2002“First Avenue”
2003“First Avenue”
3001
3002
Physical Schema to FDO Logical Schema

From the above Physical Schema, a Logical Schema will be generated that exposes two classes: Feature Class “Road” and Annotation Text Element Class “RoadAnnotation”. The road table columns will be exposed on the Road Feature Class as Properties. Class Road will also contain a reference to an Annotation property, a new FDO property definition type defined as FdoAnnotationPropertyDefinition. The Annotation property will in turn reference a new FDO class type FdoAnnotationTextElementClass that defines the instance of the RoadAnnotation class.

Here are the new definitions (simplified property view) of the new FdoAnnotationTextElement and FdoAnnotationPropertyDefintion FDO API classes. The full descriptions of these new classes are available in subsequent sections and will specify the Set and Get methods for each class. Each property defined in the two classes described below map to a OGC Annotation construct as outlined in the

class FdoAnnotationTextElementClass : public FdoClassDefinition
{
public:
    FdoDataPropertyDefinition* SequenceProperty;
    FdoDataPropertyDefinition* ParentIdentityProperty;
    FdoDataPropertyDefinition* TextValueProperty;
    FdoDataPropertyDefinition* TextAttributesProperty;
    FdoGeometricPropertyDefinition* GeometryProperty;
    FdoGeometricPropertyDefinition* LeaderLineProperty;
};
class FdoAnnotationPropertyDefinition : public FdoPropertyDefinition
{
public:
    FdoDataPropertyDefinition* FeatureIdentityProperty;
    FdoDataPropertyDefinition* DefaultTextValueProperty;
    FdoDataPropertyDefinition* DefaultTextAttributesProperty;
    FdoGeometricPropertyDefinition* TextEnvelopeProperty;
    FdoAnnotationTextElementClass* TextElementClass;
};

Here are the how these new classes and their respective definitions would map to the Road example specified above. Both Road and RoadAnnotation are exposed as classes. Road is associated to RoadAnnotation through an AnnotationPropertyDefinition named ‘Annotation’. The AnnotationPropertyDefinition points to the TextElementClass RoadAnnotation.

PropertyValue
AnnotationPropertyDefintion.TextElementClass@RoadAnnotation
AnnotationPropertyDefintion.FeatureIdentityPropertyRoad.FeatId
AnnotationPropertyDefintion.TextEnvelopePropertyRoad.TextEnvelope
AnnotationPropertyDefintion.DefaultTextValuePropertyRoad.TextDefaultValue
AnnotationPropertyDefintion.DefaultTextAttributesPropertyRoad.TextDefaultAttributes
AnnotationTextElementClass.SequencePropertyRoadAnnotation.SequenceId
AnnotationTextElementClass.ParentIdentityPropertyRoadAnnotation.ParentId
AnnotationTextElementClass.GeometryPropertyRoadAnnotation.Location
AnnotationTextElementClass.LeaderLinePropertyRoadAnnotation.LeaderLine
AnnotationTextElementClass.TextValuePropertyRoadAnnotation.TextValue
AnnotationTextElementClass.TextAttributesPropertyRoadAnnotation.TextAttributes

Through such an organization of Annotation properties into FdoAnnotationPropertyDefinition and FdoAnnotationTextElementClass types, multiple Annotation definitions can then be created and added to a single feature class definition, each named uniquely and pointing to a distinct TextElement class.

Enhanced FDO Class and Property Types

In order for the AnnotationTextElement class type to be recognizable when reading an FDO schema, the FDO API Class Type enumeration will be extended to include an enumeration value for type AnnotationTextElementClass.

enum FdoClassType
{
    FdoClassType_Class,
    FdoClassType_FeatureClass,
    ...
    ...
    FdoClassType_AnnotationTextElementClass
};

This enumerated value will be returned by the implementation of

FdoClassType FdoAnnotationTextElementClass::GetClassType();

In order for the AnnotationPropertyDefinition type to be recognizable when reading an FDO schema, the FDO API Property Type enumeration will be extended to include an enumeration value for type AnnotationPropertyDefinition.

enum FdoPropertyType
{
    FdoPropertyType_DataProperty,
    FdoPropertyType_ObjectProperty,
    FdoPropertyType_GeometricProperty,
    FdoPropertyType_AssociationProperty,
    FdoPropertyType_RasterProperty,
    FdoPropertyType_AnnotationProperty
};

This enumerated value will be returned by the implementation of

FdoPropertyType FdoAnnotationPropertyDefinition::GetPropertyType();
FDO Logical Schema to Physical Schema

Using the same FDO classes and physical schema elements introduced in the above sections, here is an FDO code example on how an ApplySchema Command would be executed to create a physical schema from an FDO logical schema.

// Create the schema
FdoFeatureSchemaP schema = FdoFeatureSchema::Create(L"Default", L"");
FdoClassCollectionP classes = schema->GetClasses();

// Create the RoadAnnotation TextElements Class
FdoAnnotationTextElementClassP txtElementClassDef = 
    FdoAnnotationTextElementClass::Create(L"RoadAnnotation", L"");
FdoPropertyDefinitionCollectionP txtElementProps = 
    txtElementClassDef->GetProperties();
FdoDataPropertyDefinitionCollectionP txtElementIdProps = 
    txtElementClassDef->GetIdentityProperties();;

// Create a ParentId property to hold the parent ID that owns the text element
FdoDataPropertyDefinitionP dataProp = 
    FdoDataPropertyDefinition::Create(L"ParentId", L"");
dataProp->SetDataType(FdoDataType_Int32);
dataProp->SetNullable(false);
dataProp->SetReadOnly(false);
dataProp->SetIsAutoGenerated(false);

// The ParentId property is a class ID property
txtElementProps->Add(dataProp);
txtElementIdProps->Add(dataProp);

// Explicitly set the ParentId property
txtElementClassDef->SetParentIdentityProperty(dataProp);

// Create a ParentId property so that Text Elements can be ordered
dataProp = FdoDataPropertyDefinition::Create(L"SequenceId", L"");
dataProp->SetDataType(FdoDataType_Int32);
dataProp->SetNullable(false);
dataProp->SetReadOnly(false);
dataProp->SetIsAutoGenerated(false);

// The SequenceId property is a class ID property
txtElementProps->Add(dataProp);
txtElementIdProps->Add(dataProp);

// Explicitly set the SequenceId property
txtElementClassDef->SetSequenceProperty(dataProp);

// Create a string data property that will hold the Text Element Value
dataProp = FdoDataPropertyDefinition::Create(L"TextValue", L"");
dataProp->SetDataType(FdoDataType_String);
props->Add(dataProp);

// Explicitly set the Text Element Value property
txtElementClassDef->SetTextValueProperty(geoProp);

// Create a string data property that will hold the Text Element Attributes
dataProp = FdoDataPropertyDefinition::Create(L"TextAttributes", L"");
dataProp->SetDataType(FdoDataType_String);
props->Add(dataProp);

// Explicitly set the Text Element Attributes property
txtElementClassDef->SetTextAttributesProperty(geoProp);

// Create a Geometry Location property for the Text Element
FdoGeometricPropertyDefinitionP geoProp = 
FdoGeometricPropertyDefinition::Create(L"Location", L"");
geoProp->SetSpatialContextAssociation(L"EPSG:4326");
geoProp->SetGeometryTypes((int)(FdoGeometryType_Point)); // Point
props->Add(geoProp);

// Explicitly set the Geometry Location property
txtElementClassDef->SetGeometryProperty(geoProp);

// Create a Geometry LeaderLine property for the Text Element
geoProp = FdoGeometricPropertyDefinition::Create(L"LeaderLine", L"");
geoProp->SetSpatialContextAssociation(L"EPSG:4326");
geoProp->SetGeometryTypes((int)(FdoGeometryType_MultiCurveString)); 
props->Add(geoProp);

// Explicitly set the Geometry LeaderLine property
txtElementClassDef->SetLeaderLineProperty(geoProp);

// Add the class to the schema
classes->Add(txtElementClassDef);

// Create the Read class
FdoFeatureClassP classDef = FdoFeatureClass::Create(L"Road", L"");
FdoPropertyDefinitionCollectionP props = classDef->GetProperties();
FdoDataPropertyDefinitionCollectionP idProps = classDef->GetIdentityProperties();;

// Create an Annotation property to allow reference to the TextElements 
FdoAnnotationPropertyDefinitionP annotationProp = 
    FdoAnnotationPropertyDefinition::Create(L"Annotation", L"");
props->Add(annotationProp);

// Create a Road Identity property
dataProp = FdoDataPropertyDefinition::Create(L"FeatId", L"");
dataProp->SetDataType(FdoDataType_Int32);
dataProp->SetNullable(false);
dataProp->SetReadOnly(false);
dataProp->SetIsAutoGenerated(true);

// The FeatId property is an ID property
props->Add(dataProp);
idProps->Add(dataProp);

// Set the annotation identity property
annotationProp->SetIdentityProperty(dataProp);

// Create a Name property
dataProp = FdoDataPropertyDefinition::Create(L"Name", L"");
dataProp->SetDataType(FdoDataType_String);
props->Add(dataProp);

// Create a Width property
dataProp = FdoDataPropertyDefinition::Create(L"Width", L"");
dataProp->SetDataType(FdoDataType_Double);
props->Add(dataProp);

// Create a Geometry to contain the Road location
geoProp = FdoGeometricPropertyDefinition::Create(L"Location", L"");
geoProp->SetSpatialContextAssociation(L"EPSG:4326");
geoProp->SetGeometryTypes((int)(FdoGeometryType_CurveString)); // CurveString
props->Add(geoProp);

// Set the geometry property for the class
classDef->SetGeometryProperty(geoProp);

// Create a Geometry Envelope to contain the TextElements extents
geoProp = FdoGeometricPropertyDefinition::Create(L"TextEnvelope", L"");
geoProp->SetSpatialContextAssociation(L"EPSG:4326");
geoProp->SetGeometryTypes((int)(FdoGeometryType_CurveString)); // CurveString
props->Add(geoProp);

// Set the annotation envelope property
annotationProp->SetTextEnvelopeProperty(geoProp);

// Create a string data property that will hold the default TextElement Value
dataProp = FdoDataPropertyDefinition::Create(L"TextDefaultValue", L"");
dataProp->SetDataType(FdoDataType_String);
props->Add(dataProp);

// Explicitly set the Text Element Value property
annotationProp->SetDefaultTextValueProperty(dataProp);

// Create a string data property that will hold the default TextElement Attributes
dataProp = FdoDataPropertyDefinition::Create(L"TextDefaultAttributes", L"");
dataProp->SetDataType(FdoDataType_String);
props->Add(dataProp);

// Explicitly set the Text Element Attributes property
annotationProp->SetDefaultTextAttributesProperty(dataProp);

// Add the class to the schema
classes->Add(classDef);

// Execute ApplySchema to create the schema
FdoIApplySchemaP applyschema = 
    (FdoIApplySchema*)(connection->CreateCommand(FdoCommandType_ApplySchema));
applyschema->SetIgnoreStates(true);
applyschema->SetFeatureSchema(schema);
applyschema->Execute();

Selecting Annotation Text Objects Through FDO

Annotation Text instances owned by FDO features will be queryable and selectable through a new FDO Interface FdoIAnnotation. The FdoIAnnotation type will be considered a primary data type that can be accessed when reading FDO features, in the same manner that Raster, Association and Geometry are currently exposed. This will allow complex Annotation objects to be associated to logical features such as roads, pipes, etc. The FdoIAnnotation Interface allows clients that interact with and maintain Annotation text to do so through a single interface. Whereas the data that completely defines the set of Text Elements may be spread across several logical classes, accessing the Annotation will be managed through a more linear mechanism that allows users to manage data with worrying where that data is stored.

class FdoIAnnotation : public FdoIDisposable
{
public:
    FdoIEnvelope* TextEnvelope;
    FdoString* DefaultBaseMapScale;
    FdoExpression* DefaultTextValue;
    FdoString* DefaultTextAttributesAsXml;
    FdoAnnotationTextElementCollection* TextElements; 
};

In this simplified view of FdoIAnnotation, we see how the Annotation’s text envelope, map scale, default values, and text elements are all available through a single interface.

From FdoIAnnotation, users are able to retrieve the collection of text attributes associated to the annotation. This is possible by accessing the TextElements property and iterating over the returned FdoAnnotationTextElement Collection. Each object in the collection represents a piece of individual Annotation text.

class FdoAnnotationTextElement : public FdoIDisposable
{
public:
    FdoByteArray*  Location;
    FdoByteArray*  LeaderLine;
    FdoExpression* TextValue;
    FdoString*     TextAttributesAsXml;
};

In order to access the above example data through the FDO logical model The FDO API’s FdoFeatureReader class will be extended to allow Annotation properties to be queried by name and by index, in the same manner as Geometry and Raster properties are today queried.

class FdoIFeatureReader: public FdoIReader
{
public:
…
…
    FdoIAnnotation* GetAnnotation(FdoString* propertyName);
    FdoIAnnotation* GetAnnotation(FdoInt32 index);
};
Querying Features with Annotation Properties

Using the above Road/RoadAnnotation Example, here is an example of how Annotation properties would be queried from an FDO data store.

// Create a select command to retrieve Road features and its associated Annotations
FdoISelectP selectCmd = (FdoISelect*)conn->CreateCommand(FdoCommandType_Select); 
selectCmd->SetFeatureClassName(L"Road");

// Add the class properties to the selection set, including the Annotation property
FdoIdentifierCollectionP props =  selectCmd->GetPropertyNames();
props->Add(FdoIdentifierP(FdoIdentifier::Create(L"FeatId")));
props->Add(FdoIdentifierP(FdoIdentifier::Create(L"Geometry")));
props->Add(FdoIdentifierP(FdoIdentifier::Create(L"Name")));
props->Add(FdoIdentifierP(FdoIdentifier::Create(L"Width")));
props->Add(FdoIdentifierP(FdoIdentifier::Create(L"Annotation")));

// The selection can be arbitrarily filtered against
FdoFilterP filter = FdoFilter::Parse(L"FeatId > 100");
selectCmd->SetFilter(filter);

// Execute the command and get a feature reader that points to the retrieved records
FdoIFeatureReaderP reader = selectCmd->Execute();
while (reader->ReadNext())
{
    // Get the Annotation property by name
    FdoPtr<FdoIAnnotation> annotation = reader->GetAnnotation(L"Annotation");

    // The annotation will have an envelope and default properties, some
    // or all of which may be NULL. Envelope is a Geometry ByteArray. The
    // Default Text will be an expression that can be evaluated as any
    // database value
    FdoByteArrayP envelope = annotation->GetEnvelope();
    FdoExpressionP defaultText = annotation->GetDefaultTextValue();
    FdoStringP defaultTextAttributes = annotation->GetDefaultTextAttibutesAsXml();
    const char* charArray = (const char*)textAttributes;
    
    // The TextAttributes would be an XML string that needs to be streamed into memory
    // and then Read into the XML API class FdoTextElementAttributes
    FdoIoMemoryStreamP stream = FdoIoMemoryStream::Create();
    stream->Write( (FdoByte*) charArray, strlen(charArray) );
    stream->Reset();

    // Create the XML API class that allows programatic access to the XML properties
    // and read the XML stream into the corresponding classes.
    FdoTextElementAttributesP defaultAttributes = FdoTextElementAttributes::Create();
    defaultAttributes->ReadXml(stream);

    // Each Annotation has 0...n Text Elements that are the actual text values
    FdoAnnotationTextElementCollectionP textElements = annotation->GetTextElements();
    for (FdoInt32 i=0; i<textElements->GetCount(); i++)
    {
        // Get the nth Text Element and read its values
        FdoAnnotationTextElementP textElement = textElements->GetItem(i);
        FdoExpressionP textValue = textElement->GetTextValue();
        FdoByteArrayP location = textElement->GetLocation();
        FdoByteArrayP leader = textElement->GetLeaderLine();

        // As seen above, the XML text will need to be parsed into its API clases
        FdoStringP textAttributes = textElement->GetTextAttributesAsXml();
        if (textAttributes != L"")
        {
            const char* charArrayA = (const char*)textAttributes;
            FdoIoMemoryStreamP streamA = FdoIoMemoryStream::Create();
            streamA->Write( (FdoByte*) charArrayA, strlen(charArrayA) );
            streamA->Reset();

            FdoTextElementAttributesP attributes = FdoTextElementAttributes::Create();
            attributes->ReadXml(streamA);
        }
    }
}

Inserting and Updating Features with Annotation Properties

Annotation Text associated to FDO features will be insertable and updatable through a extended set of derived FDO interfaces that follow the existing PropertyValue pattern used to specify data values for the FdoIInsert and FdoIUpadte comands. The newly defined Annotation interfaces will be derived from FdoExpression and FdoValueExpression and allow the Annotation properties to be set as Property Values and be parsed as expressions.

The first step required to support an insertable Annotation is to derive a new FdoAnnotationValue class from FdoValueExpression. Instances of FdoAnnotationValue will be set as the Value object on FdoPropertyValue. Users of AnnotationValue will have the ability to specify the Annotation Envelope and set of TextElementValues attached to the Annotation.

class FdoAnnotationValue : public FdoValueExpression
{
public:
    FdoGeometryValue* Envelope;
    FdoStringValue* DefaultTextValue;
    FdoStringValue* DefaultTextAttributesValue;
    FdoAnnotationTextElementValueCollection* TextElementValues; 

public:
    bool IsNull();
    void SetNullValue();
    void Process(FdoIExpressionProcessor* p);
    FdoString* ToString();
    FdoExpressionItemType GetExpressionType();
};

While the above class allows users to specify high level Annotation values, they will still need a secondary Expression interface to specify the order list of TextElementValues attached to the Annotation. Through this interface, users will be able to specify the Annotation Text location, leader line, text value, and attributes.

class FdoAnnotationTextElementValue : public FdoExpression
{
public:
    FdoGeometryValue* Location;
    FdoGeometryValue* LeaderLine;
    FdoStringValue* TextValue;
    FdoStringValue* TextAttributesValue;

public:
    void Process(FdoIExpressionProcessor* p);
    FdoString* ToString();
    FdoExpressionItemType GetExpressionType();
};
Inserting Features with Annotation Properties

Using the above Road/RoadAnnotation Example, here is an example of how Annotation properties would be inserted into an FDO data store as a part of a feature.

// Create an Insert command to create a Road
FdoPtr<FdoIInsert> insCmd = (FdoIInsert*)(conn->CreateCommand(FdoCommandType_Insert));
insCmd->SetFeatureClassName(L"Road");
FdoPtr<FdoPropertyValueCollection> propVals = insCmd->GetPropertyValues();

// Specify Road object's Geometry as a line string
FdoPtr<FdoDirectPositionCollection> objPoints = FdoDirectPositionCollection::Create();
FdoPtr<FdoIDirectPosition> pt1 = gf->CreatePositionXY(pt_A.x, pt_A.y); 
FdoPtr<FdoIDirectPosition> pt2 = gf->CreatePositionXY(pt_C.x, pt_B.y);
FdoPtr<FdoIDirectPosition> pt3 = gf->CreatePositionXY(pt_C.x, pt_C.y);
objPoints->Add(pt1);
objPoints->Add(pt2);
objPoints->Add(pt3);
FdoPtr<FdoILineStringSegment> lineSeg = gf->CreateLineStringSegment(objPoints);
FdoPtr<FdoByteArray> fgf = gf->GetFgf(lineSeg);
FdoPtr<FdoGeometryValue> gv = FdoGeometryValue::Create(fgf);
FdoPtr<FdoPropertyValue> propGeom = FdoPropertyValue::Create(L"Geometry", gv);
propVals->Add(propGeom);


// Specify Road object's Name
FdoPtr<FdoStringValue> strValue = FdoStringValue::Create(L"Main St.");
FdoPtr<FdoPropertyValue> propName = FdoPropertyValue::Create(L"Name", strValue);
propVals->Add(propName);

// Specify Road object's Width
FdoPtr<FdoInt32Value> width = FdoInt64Value::Create(20);
FdoPtr<FdoPropertyValue> propWidth = FdoPropertyValue::Create(L"Width", width);
propVals->Add(propWidth);

// Create a Text Annotation Location as a point in space
double* ordsXY = new double[2];
ordsXY[0] = pt_D.x; ordsXY[1] = pt_D.y;
FdoPtr<FdoIGeometry> pnt = gf->CreatePoint(FdoDimensionality_XY, ordsXY);
FdoPtr<FdoByteArray> fgf2 = gf->GetFgf(pnt);
FdoPtr<FdoGeometryValue> gv2 = FdoGeometryValue::Create(fgf2);

// Create a Text Annotation Leader Line as a 2 segment line
FdoPtr<FdoDirectPositionCollection> leaderPoints = FdoDirectPositionCollection::Create();
FdoPtr<FdoIDirectPosition> pt4 = gf->CreatePositionXY(pt_E.x, pt_E.y); 
FdoPtr<FdoIDirectPosition> pt5 = gf->CreatePositionXY(pt_F.x, pt_F.y);
FdoPtr<FdoIDirectPosition> pt6 = gf->CreatePositionXY(pt_G.x, pt_G.y);
leaderPoints->Add(pt4);
leaderPoints->Add(pt5);
leaderPoints->Add(pt6);
FdoPtr<FdoILineStringSegment> lineSeg2 = gf->CreateLineStringSegment(leaderPoints);
FdoPtr<FdoByteArray> fgf3 = gf->GetFgf(lineSeg2);
FdoPtr<FdoGeometryValue> gv3 = FdoGeometryValue::Create(fgf3);

// Define the Annotation Text Envelope as a simple bounding box
FdoPtr<FdoIEnvelope> envl = gf->CreateEnvelopeXY(pt_H.x, pt_H.y, pt_J.x, pt_J.y);
FdoPtr<FdoByteArray> fgf4 = gf->GetFgf(envl);
FdoPtr<FdoGeometryValue> gv4 = FdoGeometryValue::Create(fgf4);

// Specify the Annotation Text as an expression. Value determined at runtime
FdoPtr<FdoStringValue> textStrValue = FdoStringValue::Create(L"Road.Name");

// Specify the Annotation Text as an expression (NULL)
FdoPtr<FdoStringValue> textAttribValue = FdoStringValue::Create(L"");
textAttribValue->SetNull();

// Create the Text Element Values (only one here) associated to the annotation 
FdoPtr<FdoAnnotationTextElementValue> eValue = FdoAnnotationTextElementValue::Create();
eValue->SetLocation(gv2);
eValue->SetLeaderLine(gv3);
eValue->SetTextValue(textStrValue);
eValue->SetTextAttributesValue(textAttribValue);

// Create the Annotation Value and set the Envelope and text elements
FdoPtr<FdoAnnotationValue> annValue = FdoAnnotationValue::Create();
annValue->SetEnvelope(gv4);
FdoAnnotationTextElementValueCollectionP textElements = annValue->GetTextElementValues();
textElements->Add(eValue);
FdoPtr<FdoPropertyValue> propAnn = FdoPropertyValue::Create(L"Annotation", annValue);
propVals->Add(propAnn);

// Execute the insert
FdoPtr<FdoIFeatureReader> rdr = insCmd->Execute();
Updating Features with Annotation Properties

Using the above Road/RoadAnnotation Example, here is an example of how Annotation properties would be updated in an FDO data store as a part of a feature edit.

// Create an Update command to create a Road
FdoPtr<FdoIUpdate> cmd = (FdoIUpdate*)(conn->CreateCommand(FdoCommandType_Insert));
cmd->SetFeatureClassName(L"Road");
FdoPtr<FdoPropertyValueCollection> propVals = cmd->GetPropertyValues();

// Specify the Filter
FdoPtr<FdoFilter> filter = FdoFilter::Parse(L"FeatId=100");
cmd->SetFilter(filter);

// Create a Text Annotation Location as a point in space
double*	ordsXY = new double[2];
ordsXY[0] = pt_D.x; ordsXY[1] = pt_D.y;
FdoPtr<FdoIGeometry> pnt = gf->CreatePoint(FdoDimensionality_XY, ordsXY);
FdoPtr<FdoByteArray> fgf2 = gf->GetFgf(pnt);
FdoPtr<FdoGeometryValue> gv2 = FdoGeometryValue::Create(fgf2);

// Create a Text Annotation Leader Line as a 2 segment line
FdoPtr<FdoDirectPositionCollection> ldrPts = FdoDirectPositionCollection::Create();
FdoPtr<FdoIDirectPosition> pt4 = gf->CreatePositionXY(pt_E.x, pt_E.y); 
FdoPtr<FdoIDirectPosition> pt5 = gf->CreatePositionXY(pt_F.x, pt_F.y);
FdoPtr<FdoIDirectPosition> pt6 = gf->CreatePositionXY(pt_G.x, pt_G.y);
ldrPts->Add(pt4);
ldrPts->Add(pt5);
ldrPts->Add(pt6);
FdoPtr<FdoILineStringSegment> lineSeg2 = gf->CreateLineStringSegment(ldrPts);
FdoPtr<FdoByteArray> fgf3 = gf->GetFgf(lineSeg2);
FdoPtr<FdoGeometryValue> gv3 = FdoGeometryValue::Create(fgf3);

// Define the Annotation Text Envelope as a simple bounding box
FdoPtr<FdoIEnvelope> envl = gf->CreateEnvelopeXY(pt_H.x, pt_H.y, pt_J.x, pt_J.y);
FdoPtr<FdoByteArray> fgf4 = gf->GetFgf(envl);
FdoPtr<FdoGeometryValue> gv4 = FdoGeometryValue::Create(fgf4);

// Specify the Annotation Text as an expression. Value determined at runtime
FdoPtr<FdoStringValue> textStrValue = FdoStringValue::Create(L"Main St.");

// Specify the Annotation Text as an expression (NULL)
FdoStringP textAttributes = GetTextAttributesAsXMLDocument();
FdoPtr<FdoStringValue> textAttribValue = FdoStringValue::Create(textAttributes);

// Create the Text Element Values (only one here) associated to the annotation 
FdoAnnotationTextElementValueP txtElemVal = FdoAnnotationTextElementValue::Create();
txtElemVal->SetLocation(gv2);
txtElemVal->SetLeaderLine(gv3);
txtElemVal->SetTextValue(textStrValue);
txtElemVal->SetTextAttributesValue(textAttribValue);

// Create the Annotation Value and set the Envelope and text elements
FdoPtr<FdoAnnotationValue> annotationValue = FdoAnnotationValue::Create();
annotationValue->SetEnvelope(gv4);
FdoAnnotationTextElementValueCollectionP txtElems = annValue->GetTextElementValues();
textElements->Add(textElementValue);
FdoPtr<FdoPropertyValue> propAnn = FdoPropertyValue::Create(L"Annotation", annValue);
propVals->Add(propAnn);

// Execute the update
FdoPtr<FdoITransaction> tr = conn->BeginTransaction();
FdoInt32 rez = cmd->Execute();
tr->Commit();

Filtering on Features with Annotation Properties

TBD…

Q: Can you filter on Annotation values? Join? Computed Values? Do we need to define a textual representation of an Annotation property and subsequently update the FDO filter parser to recognize the new constructs?

Accessing Annotation Text Element Stylization

Each Annotation object will contain references to its Text Elements exposed through an associated collection of FdoAnnotationTextElement objects. Text Attributes will be supported for individual Text Entities using XML descriptive text that will be supported through a set of XML serializable objects that allow all of the attributes to be programmatically accessed.

As mandated by the OGC Simple Feature Access Specification, each Text Element associated to an Annotation will allow attributes to be specified for Style and Layout. Style attributes will include properties for Font, Fill, Stroke and Decoration. Layout attributes will include properties for Alignment, Justification and Spacing. In the FDO API, these properties will be exposed on two new classes FdoTextElementStyle and FdoTextElementLayout.

class FdoTextElementStyle 
{
public:
    FdoString* FontFamily;
    double FontSize;
    FdoFontWeightType FontWeight;
    FdoFontStyleType FontStyle;
    FdoTextDecorationType TextDecoration;
    FdoString* FillColor;
    double FillOpacity;
    FdoString* StrokeColor;
    double StrokeWidth;
    double StrokOpacity;
};
class FdoTextElementLayout 
{
public:
    FdoHorizontalAlignmentType HorizontalAlignment;
    FdoVerticalAlignmentType VerticalAlignment;
    FdoMultilineJustificationType MultilineJustification;
    double MultilineSpacing;
};

These two sets of properties shall be exposed through another new Interface FdoTextElemnetAttributes. This interface will allow both sets of properties to be grouped together yet still allow each group to be accessed separately. Instances of TextElementAttributes will be associated to the FDO Annotation as a whole through the "TextDefaultAttributes" property, and to each FDO Text Element through its "TextAttributes" property.

class FdoTextElementAttributes
{
public:
    FdoTextElementStyle* TextStyle;
    FdoTextElementLayout* TextLayout;
};
Processing Text Element Attributes

Using the select example preciously documented to query Annotations, we can continue to flush out the on and show how the de-serialized XML string elements can be accessed using the classes described above.

// Since OGC allows text elements to inherit their style
// from previously defined elements, we will need to save a 
// "parent" style information as we work down the element array
FdoTextElementStyleP parentTextStyle;
FdoTextElementLayoutP parentTextLayout;

// Each Annotation has 0...n Text Elements that are the actual text values
FdoAnnotationTextElementCollectionP textElements = annotation->GetTextElements();
for (FdoInt32 i=0; i<textElements->GetCount(); i++)
{
    // Get the n’th Text Element and read its style values
    FdoAnnotationTextElementP textElement = textElements->GetItem(i);

    // As seen above, the XML text will need to be parsed into its API clases
    FdoStringP textAttributes = textElement->GetTextAttributesAsXml();

    // Convert the FdoString to a char array and stream it into memory
    const char* charArrayA = (const char*)textAttributes;
    FdoIoMemoryStreamP streamA = FdoIoMemoryStream::Create();
    streamA->Write( (FdoByte*) charArrayA, strlen(charArrayA) );
    streamA->Reset();

    // Create the extended style object (initially empty) and read the style
    // attributes into it from the XML stream.
    FdoTextElementAttributesP attributes = FdoTextElementAttributes::Create();
    attributes->ReadXml(streamA);

    // Extract the text style info. If defined for this element process and display it.
    // NOTE: The OGC specification allow for elements higher in the display
    // list to dictate style if the element lower in the array has no style 
    // information specified. Therefore, save the parent and use it later in the 
    // array iteration if needed. This applies for the next 3 types as well
    FdoTextElementStyleP textStyle = attributes->GetTextStyle();
    if (textStyle) 
    {
        ProcessTextStyle(textStyle);
        parentTextStyle = textStyle;
    }
    else if (parentTextStyle)
        ProcessTextStyle(parentTextStyle);
       
    // Extract the layout style. If defined for this element process it for display
    FdoTextElementLayoutP textLayout = attributes->GetTextLayout();
    if (textLayout)
    {
        ProcessLayoutStyle(textLayout);
        parentTextLayout = textLayout;
    }
    else if (parentTextLayout)
        ProcessLayoutStyle(parentTextLayout);
}

API Overview

Enumerations

ClassType (Updated)

The FdoClassType enumeration lists all of the concrete class types defined in the Schema package.

enum FdoClassType
{
    FdoClassType_Class,
    FdoClassType_FeatureClass,
    FdoClassType_NetworkClass,
    FdoClassType_NetworkLayerClass,
    FdoClassType_NetworkNodeClass,
    FdoClassType_NetworkLinkClass,
    FdoClassType_AnnotationTextElemenetClass
};
PropertyType (Updated)

The FdoPropertyType enumeration lists the possible types that a Property can be.

enum FdoPropertyType
{
    FdoPropertyType_DataProperty,
    FdoPropertyType_ObjectProperty,
    FdoPropertyType_GeometricProperty,
    FdoPropertyType_AssociationProperty,
    FdoPropertyType_RasterProperty
    FdoPropertyType_AnnotationProperty
};
ExpressionItemType (Updated)

The FdoExpressionType enumeration defines the expression types available. This enumeration is used in the capabilities metadata.

enum FdoExpressionItemType
{
   FdoExpressionItemType_Identifier,
   FdoExpressionItemType_ComputedIdentifier,
   FdoExpressionItemType_SubSelectExpression,
   FdoExpressionItemType_Parameter,
   FdoExpressionItemType_Function,
   FdoExpressionItemType_BinaryExpression,
   FdoExpressionItemType_UnaryExpression,
   FdoExpressionItemType_DataValue,
   FdoExpressionItemType_GeometryValue
   FdoExpressionItemType_AnnotationValue
   FdoExpressionItemType_AnnotationTextElementValue
};

Annotation Types

TextElementStyle

The FdoTextElementStyle class represents the text style attributes associated to a text element.

class FdoTextElementStyle : 
    public FdoIDisposable, 
    public virtual FdoXmlSaxHandler
{
public:
    /// \brief
    /// Gets the font family.
    /// 
    /// \remarks
    /// There is no guarantee that the glyphs exist on the client system. 
    /// These names can be delimited by a semi-colon and
    /// indicate an ordered list of names to use.
    ///
    /// \return
    /// Returns the fontfamily. 
    /// 
    FdoString* GetFontFamily() const;

    /// \brief
    /// Sets the font family.
    /// 
    /// \remarks
    /// There is no guarantee that the glyphs exist on the client system. 
    /// These names can be delimited by a semi-colon and
    /// indicate an ordered list of names to use.
    ///
    /// \param font Family
    /// Input the fontfamily. Required to be non-empty string.
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetFontFamily(FdoString* fontFamily);

    /// \brief
    /// Gets the size of the text based on the sum of the ascender,
    /// descender and internal leading in points. 
    ///
    /// \return
    /// Returns the element font size
    /// 
    double GetFontSize() const;

    /// \brief
    /// Sets the size of the text based on the sum of the ascender,
    /// descender and internal leading in points. 
    ///
    /// \param fontSize
    /// Input the element font size.
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetFontSize(double fontSize);

    /// \brief
    /// Gets the weight of the font
    ///
    /// \remarks
    /// Allows for Normal, Bold, or 100, 200, 300, 400, 500, 600, 700,
    /// 800 or 900. Normal is the same as 200. Bold is the same as
    /// 400.
    /// 
    /// \return
    /// Returns the elements font size. 
    /// 
    FdoFontWeightType GetFontWeight() const;

    /// \brief
    /// Sets the weight of the font
    ///
    /// \remarks
    /// Allows for Normal, Bold, or 100, 200, 300, 400, 500, 600, 700,
    /// 800 or 900. Normal is the same as 200. Bold is the same as
    /// 400.
    /// 
    /// \param type
    /// Input the element's font size. The default is normal.
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetFontWeight(FdoFontWeightType type);

    /// \brief
    /// Gets the style of the font	
    ///
    /// \remarks
    /// Normal, Italic or Oblique. Oblique is optional. It is
    /// meant to the opposite angle of italic, slanted left instead 
    /// of the Italic right. As this has little actual support, the
    /// recommendation is that clients just use italic.
    /// 
    /// \return
    /// Returns the element's font style.
    /// 
    FdoFontStyleType GetFontStyle() const;

    /// \brief
    /// Sets the style of the fontt
    ///
    /// \remarks
    /// Normal, Italic or Oblique. Oblique is optional. It is
    /// meant to the opposite angle of italic, slanted left instead 
    /// of the Italic right. As this has little actual support, the
    /// recommendation is that clients just use italic.
    /// 
    /// \param type
    /// Input the element's font style. 
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetFontStyle(FdoFontStyleType type);

    /// \brief
    /// Gets the text decoration
    ///
    /// \remarks
    /// None, underline, line-through and over-line. Underline is drawn
    /// at the baseline, over-line at the baseline + ascent, line-through
    /// at baseline + (.5 x ascent). 
    /// 
    /// \return
    /// Returns the element's text decoration value. 
    /// 
    FdoTextDecorationType GetTextDecoration() const;

    /// \brief
    /// Sets the text decoration
    ///
    /// \remarks
    /// None, underline, line-through and over-line. Underline is drawn
    /// at the baseline, over-line at the baseline + ascent, line-through
    /// at baseline + (.5 x ascent). 
    /// 
    /// \param value
    /// Returns the element's text decoration value. The default is normal.
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetTextDecoration(FdoTextDecorationType value);

    /// \brief
    /// Gets the fill color
    ///
    /// \remarks
    /// This specifies the color of the interior of the glyphs. Colors can
    /// be specified in the following manner:
    /// 1. Well known SVG font names such as black, blue, red.     
    /// 2. RGB values specified using function syntax
    /// 3. A literal hex value which would be the same as the previous RGB example.
    /// 
    /// \return
    /// Returns the element's text fill color value. 
    /// 
    FdoString* GetFillColor() const;

    /// \brief
    /// Sets the fill color
    ///
    /// \remarks
    /// This specifies the color of the interior of the glyphs. Colors can
    /// be specified in the following manner:
    /// 
    /// 1. Well known SVG font names such as black, blue, red.
    /// 2. RGB values specified using function syntax
    /// 3. A literal hex value which would be the same as the previous RGB example.
    /// 
    /// \param fillColor
    /// Input the element's text fill color value. The default is "black".
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetFillColor(FdoString* fillColor);

    /// \brief
    /// Gets the fill opacity
    ///
    /// \remarks
    /// A percentage that specifies the opacity or translucency of the
    /// fill. A 0 is fully transparent and 1 is fully opaque.
    /// 
    /// \return
    /// Returns the element's fill opacity. 
    /// 
    double GetFillOpacity() const;

    /// \brief
    /// Sets the fill opacity
    ///
    /// \remarks
    /// A percentage that specifies the opacity or translucency of the
    /// fill. A 0 is fully transparent and 1 is fully opaque.
    /// 
    /// \param fillOpacity
    /// Input the element's fill opacity. 
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetFillOpacity(double fillOpacity);

    /// \brief
    /// Gets the stroke color
    ///
    /// \remarks
    /// This specifies the color of the outline of the glyphs. Stroke
    /// allows the same color values as Fill. It is our proposal that we
    /// define, contrary to SVG, that the stroke be drawn before the fill,
    /// which creates a very nice shadow background effect around
    /// the text.
    /// 
    /// \return
    /// Returns the element's stroke color as a string. 
    /// 
    FdoString* GetStrokeColor() const;

    /// \brief
    /// Sets the stroke color
    ///
    /// \remarks
    /// This specifies the color of the outline of the glyphs. Stroke
    /// allows the same color values as Fill. It is our proposal that we
    /// define, contrary to SVG, that the stroke be drawn before the fill,
    /// which creates a very nice shadow background effect around
    /// the text.
    /// 
    /// \param strokeColor
    /// Returns the element's stroke color as a string. 
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetStrokeColor(FdoString* strokeColor);

    /// \brief
    /// Gets the stroke width
    ///
    /// \return
    /// Returns the element's stroke width in points. 
    /// 
    double GetStrokeWidth() const;

    /// \brief
    /// Sets the stroke width
    ///
    /// \param stroke
    /// Input the element's stroke width in points. 
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetStrokeWidth(double stroke);

    /// \brief
    /// Gets the stroke opacity
    ///
    /// \remarks
    /// A percentage that specifies the opacity or translucency of the
    /// stroke. A 0 is fully transparent and 1 is fully opaque.
    ///
    /// \return
    /// Returns the element's stroke opacity. 
    /// 
    double GetStrokOpacity() const;

    /// \brief
    /// Sets the stroke opacity
    ///
    /// \remarks
    /// A percentage that specifies the opacity or translucency of the
    /// stroke. A 0 is fully transparent and 1 is fully opaque.
    ///
    /// \param stroke
    /// Input the element's stroke opacity. The default is 1.
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetStrokeOpacity(double stroke);
};
TextElementLayout

The FdoTextElementLayout class represents the text layout attributes associated to a text element.

class FdoTextElementLayout : 
    public FdoIDisposable, 
    public virtual FdoXmlSaxHandler
{
public:
    /// \brief
    /// Gets the horizontal alignment
    ///
    /// \remarks
    /// 3 allowable values which are: "start", "center", "end". 
    /// The meaning of these attributes is such that the appropriate
    /// part of the text is placed at the point or starting point of 
    /// the geometry. For example, start means that the first 
    /// characters of the text is placed there. Note that this means 
    /// the text is positioned to the right of the geometry. Optional 
    /// defaults to "start"
    /// 
    /// \return
    /// Returns the element's horizontal alignment setting.
    /// 
    FdoHorizontalAlignmentType GetHorizontalAlignment() const;

    /// \brief
    /// Sets the horizontal alignment
    ///
    /// \remarks
    /// 3 allowable values which are: "start", "center", "end". 
    /// The meaning of these attributes is such that the appropriate
    /// part of the text is placed at the point or starting point of 
    /// the geometry. For example, start means that the first 
    /// characters of the text is placed there. Note that this means 
    /// the text is positioned to the right of the geometry. Optional 
    /// defaults to "start"
    /// 
    /// \param value
    /// Input the element's horizontal alignment setting. The default
    /// is normal.
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetHorizontalAlignment(FdoHorizontalAlignmentType value);

    /// \brief
    /// Gets the vertical alignment
    ///
    /// \remarks
    /// 4 allowable values which are: "top", "center", "baseline" 
    /// and "bottom". The meaning is similar to that of horizontal
    /// alignment. For example, “top” means that the topmost part 
    /// of the text glyph is placed at the geometry start location.
    /// Optional defaults to "top".
    /// 
    /// \return
    /// Returns the element's vertical alignment setting. 
    /// 
    FdoVerticalAlignmentType GetVerticalAlignment() const;

    /// \brief
    /// Sets the vertical alignment
    ///
    /// \remarks
    /// 4 allowable values which are: "top", "center", "baseline" 
    /// and "bottom". The meaning is similar to that of horizontal
    /// alignment. For example, “top” means that the topmost part 
    /// of the text glyph is placed at the geometry start location.
    /// Optional defaults to "top".
    /// 
    /// \param value
    /// Input the element's vertical alignment setting. 
    /// The default is normal.
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetVerticalAlignment(FdoVerticalAlignmentType value);

    /// \brief
    /// Gets the multiline justification
    ///
    /// \remarks
    /// 3 allowable values. These are: left, center, and right, 
    /// The meaning of these attributes is such that each text line is
    /// appropriately justified in relation to each other. Optional as
    /// it is not needed in single line text. Defaults to "left"
    /// 
    /// \return
    /// Returns the element's multiline justification. 
    /// 
    FdoMultilineJustificationType GetMultilineJustification() const;

    /// \brief
    /// Sets the multiline justification
    ///
    /// \remarks
    /// 3 allowable values. These are: left, center, and right, 
    /// The meaning of these attributes is such that each text line is
    /// appropriately justified in relation to each other. Optional as
    /// it is not needed in single line text. Defaults to "left"
    /// 
    /// \param value
    /// Input the element's multiline justification value. 
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetMultilineJustification(FdoMultilineJustificationType value);

    /// \brief
    /// Gets the multiline spacing
    ///
    /// \remarks
    /// A value in points determining the space between lines of text as
    /// measured from the bottom of one line to the top of the next.
    /// Optional as it is not needed in single line text. Defaults to 0 
    /// which puts each line immediately below the previous one
    /// 
    /// \return
    /// Returns the multiline spacing. 
    /// 
    double GetMultilineSpacing() const;

    /// \brief
    /// Sets the multiline spacing
    ///
    /// \remarks
    /// A value in points determining the space between lines of text as
    /// measured from the bottom of one line to the top of the next.
    /// Optional as it is not needed in single line text. Defaults to 0 
    /// which puts each line immediately below the previous one
    /// 
    /// \param spacing
    /// Input the element's multiline spacing. 
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetMultilineSpacing(double spacing);
};
TextElementAttributes

The FdoTextElementAttributes class defines the style and layout properties for the Annotation TextElement type.

class FdoTextElementAttributes : 
    public FdoIDisposable,
    public FdoXmlDeserializable,
    public FdoXmlSerializable
{
public:
    /// \brief
    /// Gets the text style attributes.
    ///
    /// \remarks
    /// Other information associated to the annotation text is
    /// the various style information, such as the size of the text 
    /// (usually in units appropriate to the display, such as pixels
    /// or points), the font used, characteristics of the font.
    /// 
    /// \return
    /// Returns the element's text style attributes
    /// 
    virtual FdoTextElementStyle* GetTextStyle() const;

    /// \brief
    /// Gets the layout style attribute.
    ///
    /// \remarks
    /// Other information associated to the annotation text is
    /// the various layout information, such as the vertical and
    /// horizontal alignment, and multiline justification and
    /// spacing
    /// 
    /// \return
    /// Returns the element's layout style attributes
    /// 
    virtual FdoTextElementLayout* GetTextLayout() const;
};
AnnotationTextElement

The FdoIAnnotationTextElement interface is a Annotation TextElement type.

class FdoAnnotationTextElement : public FdoIDisposable
{
public:
    /// \brief
    /// Gets the text value.
    /// 
    /// \return
    /// Returns the text element's string value as an Expression
    /// 
    FdoExpression* GetTextValue() const;

    /// \brief
    /// Sets the text value.
    /// 
    /// \param value 
    /// Input the element's text string value as an Expression.
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetTextValue(FdoExpression* value);

    /// \brief
    /// Gets the element's geometry location.
    ///
    /// \return
    /// Returns the element's geometry.
    /// 
    FdoByteArray* GetLocation() const;

    /// \brief
    /// Sets the element's geometry location.
    ///
    /// \param name 
    /// Input the element's geometry location
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetLocation(FdoByteArray* location);

    /// \brief
    /// Gets the element's leader line geometry
    ///
    /// \remarks
    /// A second geometry that may be required in order to visually  
    /// connect the placed text and the location geometry, especially  
    /// where the location geometry is crowded in an area with other 
    /// close-by features. This other geometry is referred to here 
    /// as a leader line, and is a displayable curve of no geographic 
    /// significance. 
    /// 
    /// Optional – if null, there is no leader line.
    /// 
    /// \return
    /// Returns the leader line geometry
    /// 
    FdoByteArray* GetLeaderLine() const;

    /// \brief
    /// Sets the leader line geometry.
    ///
    /// \remarks
    /// A second geometry that may be required in order to visually  
    /// connect the placed text and the location geometry, especially  
    /// where the location geometry is crowded in an area with other 
    /// close-by features. This other geometry is referred to here 
    /// as a leader line, and is a displayable curve of no geographic 
    /// significance. 
    /// 
    /// Optional – if null, there is no leader line.
    /// 
    /// \param name 
    /// Input the leader line geometry
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetLeaderLine(FdoByteArray* leaderLine);

    /// \brief
    /// Gets the attribute information associated with this text element
    /// and all subsequent text elements in the ordered text element 
    /// collection.
    ///
    /// \remarks
    /// Each element has its own text attributes, but they are
    /// not used independently. The first element will set the  
    /// attributes for all following elements. Subsequent element's 
    /// text attributes are only specified when a change is required.  
    /// This behavior just extends the metadata text attributes  
    /// to each element of the text collection.
    ///
    /// \return
    /// Returns the text element's text attributes as an OGC XML 
    /// definition
    /// 
    FdoString* GetTextAttributesAsXml() const;

    /// \brief
    /// Sets the attribute information associated with this text element
    /// and all subsequent text elements in the ordered text element 
    /// collection.
    ///
    /// \remarks
    /// Each element has its own text attributes, but they are
    /// not used independently. The first element will set the  
    /// attributes for all following elements. Subsequent element's 
    /// text attributes are only specified when a change is required.  
    /// This behavior just extends the metadata text attributes  
    /// to each element of the text collection.
    ///
    /// \param xml 
    /// Input the text attributes as OGC compliant XML definition.
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetTextAttributesAsXml(FdoString* xml);
};
AnnotationTextElementCollection

The FdoAnnotationTextElementCollection class is a collection of TextElement objects.

class FdoAnnotationTextElementCollection : 
      public FdoCollection<FdoAnnotationTextElement, FdoException>
{
public:
    /// \brief
    /// Creates an instance of FdoAnnotationTextElementCollection 
    /// with no contained elements.
    /// 
    /// \return
    /// Returns an empty collection
    /// 
    static FdoAnnotationTextElementCollection* Create();
};

AnnotationTextElementClass

The FdoAnnotationTextElementClass class derives from FdoClassDefinition and is used to allow Annotation Text Element definitions and their mandated OGC properties to be defined and described so that clients can maintain relationships between parent features and a set of text attributes that are spatially placed in relation to the parent feature.

An annotation consists of an ordered list of independently placed text elements, possibly corresponding to individual lines of text in a multiline text, and an envelope that approximates an outer limit of the text elements when placed. Each element has its own text attributes, but they are not used independently. The first element will set the attributes for all following elements. Subsequent element's text attributes are only specified when a change is required. This behavior just extends that of the metadata text attributes to each element of the text collection.

A text element consists of a text string and information about its placement. The most important piece of information is the geometry to which the text is to refer, here referred to as the location geometry. A second geometry may be required to visually connect the placed text and the location geometry, especially where the location geometry is crowded in an area with other close-by features. This other geometry is referred to here as a leader line, and is a displayable curve of no geographic significance. The other information associated to the annotation text is the various style information, such as the size of the text (usually in units appropriate to the display, such as pixels or points), the font used, characteristics of the font.

class FdoAnnotationTextElementClass : public FdoClassDefinition
{
public:
    /// \brief
    /// Gets the property which defines the unique identity of the parent  
    /// feature of the annotation text elements. This property will act 
    /// as a foreign key to the identity id contained in the parent 
    /// feature class
    ///
    /// \return
    /// Returns the property that will contain the parent feature 
    /// identity value.
    /// 
    FdoDataPropertyDefinition* GetParentIdentityProperty() const;

    /// \brief
    /// Sets the property which defines the unique identity of the parent  
    /// feature of the annotation text elements. This property will act 
    /// as a foreign key to the identity id contained in the parent 
    /// feature class
    ///
    /// \param prop 
    /// Input the property that will contain the parent feature 
    /// identity value.
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetParentIdentityProperty(FdoDataPropertyDefinition* prop);

    /// \brief
    /// Gets the property which defines the sequence in which Text
    /// Elements are ordered for display. This property must be of 
    /// type integer.
    ///
    /// \return
    /// Returns the property that will contain the sequence number.
    /// 
    FdoDataPropertyDefinition* GetSequenceProperty() const;

    /// \brief
    /// Sets the property which defines the sequence in which Text
    /// Elements are ordered for display. This property must be of 
    /// type integer.
    ///
    /// \param prop 
    /// Input the property that will contain the sequence number.
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetSequenceProperty(FdoDataPropertyDefinition* prop);

    /// \brief
    /// Gets the property where the annotation text value is stored.
    ///
    /// \return
    /// Returns the property that contains the annotation text value
    /// 
    FdoDataPropertyDefinition* GetTextValueProperty() const;

    /// \brief
    /// Sets the property where the annotation text value is stored.
    ///
    /// \param value 
    /// Input the property that contains the text value
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetTextValueProperty(FdoDataPropertyDefinition* value);

    /// \brief
    /// Gets the property where the annotation text attributes are stored.
    ///
    /// \return
    /// Returns the property that contains the annotation text attributes
    /// 
    FdoDataPropertyDefinition* GetTextAttributesProperty() const;

    /// \brief
    /// Sets the property where the annotation text attributes are stored.
    ///
    /// \param value 
    /// Input the property that contains the text attributes
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetTextAttributesProperty(FdoDataPropertyDefinition* value);

    /// \brief
    /// Gets the property where the geometry location of the annotation text 
    /// element is stored.
    ///
    /// \return
    /// Returns the geometry property that will contain the annotation 
    /// text element location
    /// 
    FdoGeometricPropertyDefinition* GetGeometryProperty();

    /// \brief
    /// Sets the property where the geometry location of the text 
    /// element is stored.
    ///
    /// \param value 
    /// Input the geometry property where the annotation 
    /// text element location will be stored
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetGeometryProperty(FdoGeometricPropertyDefinition* value);

    /// \brief
    /// Gets the property where the geometry of the text 
    /// element leader line is stored.
    ///
    /// \return
    /// Returns the geometry property that will contain the annotation 
    /// text element leader line
    /// 
    FdoGeometricPropertyDefinition* GetLeaderLineProperty();

    /// \brief
    /// Sets the property where the geometry of the text 
    /// element leader line is stored.
    ///
    /// \param value 
    /// Input the geometry property where the annotation 
    /// text element leader line will be stored
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetLeaderLineProperty(FdoGeometricPropertyDefinition* value);
};
AnnotationPropertyDefinition

The FdoAnnotationPropertyDefinition class is an FDO Annotation property type.

An annotation consists of an ordered list of independently placed text elements, possibly corresponding to individual lines of text in a multiline text, and an envelope that approximates an outer limit of the text elements when placed. Each element has its own text attributes, but they are not used independently. The first element will set the attributes for all following elements. Subsequent element's text attributes are only specified when a change is required. This behavior just extends that of the metadata text attributes to each element of the text collection.

If indexing is used, the envelope or minimum bounding box of the text is a handy piece of information that should be available. If unavailable, the envelope can be calculated from the processes of placing the text. Since this is often cumbersome, precalculating the envelope and storing it is often the most efficient manner to use this information.

class FdoAnnotationPropertyDefinition : public FdoPropertyDefinition
{
public:
    /// \brief
    /// Gets the property which defines the unique identity of the parent  
    /// feature of the annotation text elements. This property will act 
    /// as a foreign key to the parent id contained in the Annotation 
    /// TextElement Class
    ///
    /// \return
    /// Returns the property that will contain the annotation 
    /// parent identity value.
    /// 
    FdoDataPropertyDefinition* GetIdentityProperty() const;

    /// \brief
    /// Sets the property which defines the unique identity of the parent  
    /// feature of the annotation text elements. This property will act 
    /// as a foreign key to the parent id contained in the Annotation 
    /// TextElement Class
    ///
    /// \param prop 
    /// Input the property that will contain the annotation 
    /// parent identity value.
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetIdentityProperty(FdoDataPropertyDefinition* prop);

    /// \brief
    /// Gets the geometry property, defined on this properties feature
    /// class owner, that contains the envelope geometry describing the 
    /// total area of the collection of associated annotation text elements.
    ///
    /// \return
    /// Returns the property that will contain the Annotation 
    /// envelope geometry
    /// 
    FdoGeometricPropertyDefinition* GetTextEnvelopeProperty();

    /// \brief
    /// Sets the geometry property, defined on this properties feature
    /// class owner, that contains the envelope geometry describing the 
    /// total area of the collection of associated annotation text elements.
    ///
    /// \param value 
    /// Input the property that will contain the Annotation 
    /// envelope geometry
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetTextEnvelopeProperty(FdoGeometricPropertyDefinition* value);

    /// \brief
    /// Gets the property where the default annotation text value is stored.
    /// This value will be used if the Annotation Text Element has no (NULL)
    /// value set.
    ///
    /// \return
    /// Returns the property that contains the default text value
    /// 
    FdoDataPropertyDefinition* GetDefaultTextValueProperty() const;

    /// \brief
    /// Sets the property where the default annotation text value is stored.
    /// This value will be used if the Annotation Text Element has no (NULL)
    /// value set.
    ///
    /// \param value 
    /// Input the property that contains the default text value
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetDefaultTextValueProperty(FdoDataPropertyDefinition* value);

    /// \brief
    /// Gets the property where the default annotation text attributes are
    /// stored. This value will be used if the Annotation Text Element has 
    /// no (NULL) attributes set.
    ///
    /// \return
    /// Returns the property that contains the default text attributes
    /// 
    FdoDataPropertyDefinition* GetDefaultTextAttributesProperty() const;

    /// \brief
    /// Sets the property where the default annotation text attributes
    /// are stored. This value will be used if the Annotation Text Element has
    /// no (NULL) attributes set.
    ///
    /// \param value 
    /// Input the property that contains the default attributes value
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetDefaultTextAttributesProperty(FdoDataPropertyDefinition* value);

    /// \brief
    /// Gets the Annotation class definition where the text element instances
    /// will be stored
    ///
    /// \return
    /// Returns the Annotation class definition
    /// 
    FdoAnnotationTextElementClass* GetTextElementClass() const;

    /// \brief
    /// Sets the Annotation class definition where the text element instances 
    /// will be stored
    ///
    /// \param annotationClass 
    /// Input the Annotation class definition
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetTextElementClass(FdoAnnotationTextElementClass* annotationClass);
};
IAnnotation

The FdoIAnnotation interface represents a instance of an Annotation and its associated Text Elements as exposed by an FDO Feature Reader.

An annotation text consists of an ordered list of independently placed text elements, possibly corresponding to individual lines of text in a multiline text, and an envelope that approximates an outer limit of the text elements when placed. Each element has its own text attributes, but they are not used independently. The first element will set the attributes for all following elements. Subsequent element's text attributes are only specified when a change is required. This behavior just extends that of the metadata text attributes to each element of the text collection.

class FdoIAnnotation : public FdoIDisposable
{
public:
    /// \brief
    /// Gets the envelope or minimum bounding box of the annotation
    /// text elements
    ///
    /// \remarks
    /// If unavailable, the envelope can be calculated from the  
    /// processes of placing the text. Since this is often 
    /// cumbersome, precalculating, setting the envelope and storing
    /// it is often the most efficient manner to use this information.
    /// 
    /// \return
    /// Returns the envelope of the text elements
    /// 
    virtual FdoIEnvelope* GetTextEnvelope() const = 0;

    /// \brief
    /// Sets the envelope or minimum bounding box of the annotation
    /// text elements.
    ///
    /// \remarks
    /// The envelope can be calculated from the processes of 
    /// placing the text. However, calculating and setting the envelope  
    /// when creating annotation text is often the most efficient 
    /// manner to deal with annotation text objects.
    /// 
    /// \param envelope 
    /// Input the envelope of all the text elements associated to this
    /// Annotation text
    /// 
    /// \return
    /// Returns nothing
    /// 
    virtual void SetTextEnvelope(FdoIEnvelope* envelope) = 0;

    /// \brief
    /// Gets the default base map scale for which the text will be displayed.
    ///
    /// \return
    /// Returns the base map scale as a string
    /// 
    virtual FdoString* GetDefaultBaseMapScale() const = 0;

    /// \brief
    /// Sets the default base map scale for which the text will be displayed.
    ///
    /// \param scale 
    /// Input the base map scale as a string
    /// 
    /// \return
    /// Returns nothing
    /// 
    virtual void SetDefaultBaseMapScale(FdoString* scale) = 0;

    /// \brief
    /// Gets the default text value for elements contained by the Annotation.
    ///
    /// \remarks
    /// Allows the actual text of a text element to come from data outside the 
    /// text element Value property.
    ///
    /// Any valid data store expression resulting in a string is acceptable. 
    /// The expression is evaluated for each text element. If this field is null, the
    /// individual text element may have their own embedded text or nothing shall 
    /// be displayed. Any embedded text shall override this expression value.
    ///
    /// \return
    /// Returns the default text element value as an expression
    /// 
    virtual FdoExpression* GetDefaultTextValue() const = 0;

    /// \brief
    /// Sets the default text value for elements contained by the Annotation.
    ///
    /// \remarks
    /// Allows the actual text of a text element to come from data outside the 
    /// text element Value property.
    ///
    /// Any valid data store expression resulting in a string is acceptable. 
    /// The expression is evaluated for each text element. If this field is null, the
    /// individual text element may have their own embedded text or nothing shall 
    /// be displayed. Any embedded text shall override this expression value.
    ///
    /// \param expression 
    /// Input the default text element value as an expression
    /// 
    /// \return
    /// Returns nothing
    /// 
    virtual void SetDefaultTextValue(FdoExpression* expression) = 0;

    /// \brief
    /// Gets the default attribute information associated with the 
    /// text elements attached to this Annotation.
    ///
    /// \remarks
    /// As many text attributes may be common across text elements, 
    /// common ones may be stored once and allow for individual 
    /// text element overrides.
    ///
    /// The Text Style, Layout and Leader Line Style described by the 
    /// text element style may be stored as a default on the Annotation
    /// as well on the individual text element objects. Any values in the 
    /// individual elements shall override the Annotation values. The 
    /// resulting attributes are an overlay of the Annotation attributes 
    /// and individual text element attribute values.
    ///
    /// \return
    /// Returns the default text attributes as an OGC XML definition
    /// 
    virtual FdoString* GetDefaultTextAttributesAsXml() const;

    /// \brief
    /// Sets the default attribute information associated with the 
    /// text elements attached to this Annotation.
    ///
    /// \remarks
    /// As many text attributes may be common across text elements, 
    /// common ones may be stored once and allow for individual 
    /// text element overrides.
    ///
    /// The Text Style, Layout and Leader Line Style described by the 
    /// text element style may be stored as a default on the Annotation
    /// as well on the individual text element objects. Any values in the 
    /// individual elements shall override the Annotation values. The 
    /// resulting attributes are an overlay of the Annotation attributes 
    /// and individual text element attribute values.
    ///
    /// \param xml 
    /// Input the default text attributes as an OGC XML definition.
    /// 
    /// \return
    /// Returns nothing
    /// 
    virtual void SetDefaultTextAttributesAsXml(FdoString* xml);

    /// \brief
    /// Gets the collection of text elements that define the annotation.
    /// 
    /// \return
    /// Returns the collection of text elements
    /// 
    virtual FdoAnnotationTextElementCollection* GetTextElements() const = 0; 
};
IFeatureReader

The FdoIFeatureReader interface provides a forward-only, read-only iterator for reading feature data. A reference to an FdoIFeatureReader is returned from the Select and SelectAndLock commands. Because the initial position of the FdoIFeatureReader is prior to the first item, you must call ReadNext to begin accessing any data.

class FdoIFeatureReader: public FdoIReader
{
public:
…
…

    /// \brief
    /// Gets the Annotation object of the specified property.
    /// Because no conversion is performed, the property must be
    /// of Annotation type; otherwise, an exception is thrown.
    /// 
    /// \param propertyName 
    /// Input the property name.
    /// 
    /// \return
    /// Returns the Annotation object.
    /// 
    virtual FdoIAnnotation* GetAnnotation(FdoString* propertyName) = 0;

    /// \brief
    /// Gets the Annotation object of the property at the specified index.
    /// Because no conversion is performed, the property must be
    /// of Annotation type; otherwise, an exception is thrown.
    /// 
    /// \param index 
    /// Input the index of the property.
    /// 
    /// \return
    /// Returns the Annotation object.
    /// 
    virtual FdoIAnnotation* GetAnnotation(FdoInt32 index) = 0;
 };
AnnotationTextElementValue

The FdoAnnotationTextElementValue class derives from FdoExpression and represents an Annotation TextElement value embedded in an Annotation. AnnotationTextElementValue allows Annotation objects to be passed to FDO Insert and update commands though the AnnotationValue base interface.

class FdoAnnotationTextElementValue : public FdoExpression
{
public:
    /// \brief
    /// Gets the Location specified as a GeometryValue. 
    /// 
    /// \return
    /// Returns the Location as a GeometryValue 
    /// 
    FdoGeometryValue* GetLocation();

    /// \brief
    /// Sets the Location using a GeometryValue.
    /// 
    /// \param value 
    /// Input the Location GeometryValue
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetLocation(FdoGeometryValue* value);

    /// \brief
    /// Gets the Leader Line specified as a GeometryValue. 
    /// 
    /// \return
    /// Returns the Location as a GeometryValue 
    /// 
    FdoGeometryValue* GetLeaderLine();

    /// \brief
    /// Sets the Leader Line using a GeometryValue.
    /// 
    /// \param value 
    /// Input the Leader Line GeometryValue
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetLeaderLine(FdoGeometryValue* value);

    /// \brief
    /// Gets the Text specified as a StringValue. 
    /// 
    /// \return
    /// Returns the Text as a StringValue 
    /// 
    FdoStringValue* GetTextValue();

    /// \brief
    /// Sets the Text specified as a StringValue. 
    /// 
    /// \param value 
    /// Input the Text as a StringValue
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetTextValue(FdoStringValue* value);

    /// \brief
    /// Gets the Text Attributes specified as a StringValue. 
    /// 
    /// \return
    /// Returns the Text Attributes as a StringValue 
    /// 
    FdoStringValue* GetTextAttributesValue();

    /// \brief
    /// Sets the Text Attributes using a StringValue.
    /// 
    /// \param value 
    /// Input the Text Attributes as a StringValue
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetTextAttributesValue(FdoStringValue* value);

    /// \brief
    /// Overrides FdoExpression. Process to pass the FdoAnnotationValue to the
    /// appropriate expression processor operation.
    /// 
    /// \param p 
    /// Input the expression processor interface
    /// 
    /// \return
    /// Returns nothing
    /// 
    void Process(FdoIExpressionProcessor* p);

    /// \brief
    /// Returns the well-defined text representation of this expression.
    /// 
    /// \return
    /// Returns the well-defined text string
    /// 
    FdoString* ToString();

    /// \brief
    /// Returns the type of the expression as geometry value
    /// 
    /// \return
    /// Returns FdoExpressionItemType
    /// 
    FdoExpressionItemType GetExpressionType();
};
AnnotationValue

The FdoAnnotationValue class derives from FdoValueExpression and represents an Annotation value. AnnotationValue allows Annotation objects to be passed to FDO Insert and update commands though the PropertyValue base interface.

class FdoAnnotationValue : public FdoValueExpression
{
public:
    /// \brief
    /// Returns true if the AnnotationValue represents a null value.
    /// 
    /// \return
    /// Returns true if the Annotation Value contains a NULL value
    /// 
    bool IsNull();

    /// \brief
    /// Sets the AnnotationValue to a null value.
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetNullValue();

    /// \brief
    /// Gets the Annotation envelope as a geometry value. The geometry is 
    /// expected to be encoded in Autodesk Well-Known Binary format.
    /// 
    /// \return
    /// Returns the envelope as a GeometryValue
    /// 
    FdoGeometryValue* GetEnvelope();

    /// \brief
    /// Gets the Text specified as a StringValue. 
    /// 
    /// \return
    /// Returns the Text as a StringValue 
    /// 
    FdoStringValue* GetDefaultTextValue();

    /// \brief
    /// Sets the Text specified as a StringValue. 
    /// 
    /// \param value 
    /// Input the Text as a StringValue
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetDefaultTextValue(FdoStringValue* value);

    /// \brief
    /// Gets the Text Attributes specified as a StringValue. 
    /// 
    /// \return
    /// Returns the Text Attributes as a StringValue 
    /// 
    FdoStringValue* GetDefaultTextAttributesValue();

    /// \brief
    /// Sets the Text Attributes using a StringValue.
    /// 
    /// \param value 
    /// Input the Text Attributes as a StringValue
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetDefaultTextAttributesValue(FdoStringValue* value);

    /// \brief
    /// Sets the Annotation envelope as a geometry value. The geometry is 
    /// expected to beencoded in Autodesk Well-Known Binary format.
    /// 
    /// \param value 
    /// Input the envelope as a geometry value
    /// 
    /// \return
    /// Returns nothing
    /// 
    void SetEnvelope(FdoGeometryValue* value);

    /// \brief
    /// Gets the collection of text element values that define the annotation.
    /// 
    /// \return
    /// Returns the collection of text element values
    /// 
    FdoAnnotationTextElementValueCollection* GetTextElementValues() const; 

    /// \brief
    /// Overrides FdoExpression. Process to pass the AnnotationValue to the
    /// appropriate expression processor operation.
    /// 
    /// \param p 
    /// Input the expression processor interface
    /// 
    /// \return
    /// Returns nothing
    /// 
    void Process(FdoIExpressionProcessor* p);

    /// \brief
    /// Returns the well-defined text representation of this expression.
    /// 
    /// \return
    /// Returns the well-defined text string
    /// 
    FdoString* ToString();

    /// \brief
    /// Returns the type of the expression as geometry value
    /// 
    /// \return
    /// Returns ExpressionItemType_Annotation
    /// 
    FdoExpressionItemType GetExpressionType();
};

Appendix A: AnnotationText XSD Style Definitions

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
      targetNamespace="http://fdo.osgeo.org/annotation"
      xmlns="http://fdo.osgeo.org/annotation"
      xmlns:xs="http://www.w3.org/2001/XMLSchema"
      elementFormDefault="qualified"
      attributeFormDefault="unqualified">
  <xs:simpleType name="fontWeight">
    <xs:restriction base="xs:string">
      <xs:enumeration value="Normal"/>
      <xs:enumeration value="Bold"/>
      <xs:enumeration value="100"/>
      <xs:enumeration value="200"/>
      <xs:enumeration value="300"/>
      <xs:enumeration value="400"/>
      <xs:enumeration value="500"/>
      <xs:enumeration value="600"/>
      <xs:enumeration value="700"/>
      <xs:enumeration value="800"/>
      <xs:enumeration value="900"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="fontStyle">
    <xs:restriction base="xs:string">
      <xs:enumeration value="Normal"/>
      <xs:enumeration value="Italics"/>
      <xs:enumeration value="Oblique"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="textDecoration">
    <xs:restriction base="xs:string">
      <xs:enumeration value="None"/>
      <xs:enumeration value="Underline"/>
      <xs:enumeration value="LineThrough"/>
      <xs:enumeration value="Overline"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="spacing">
    <xs:union>
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:enumeration value="Normal"/>
        </xs:restriction>
      </xs:simpleType>
      <xs:simpleType>
        <xs:restriction base="xs:float"/>
      </xs:simpleType>
    </xs:union>
  </xs:simpleType>
  <xs:simpleType name="colorType">
    <xs:union>
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:pattern value="(rgb\(N,N,N\))"/>
        </xs:restriction>
      </xs:simpleType>
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:enumeration value="none"/>
          <xs:enumeration value="aliceblue"/>
          <xs:enumeration value="antiquewhite"/>
          <xs:enumeration value="aqua"/>
          <xs:enumeration value="aquamarine"/>
          <xs:enumeration value="azure"/>
          <xs:enumeration value="beige"/>
          <xs:enumeration value="bisque"/>
          <xs:enumeration value="black"/>
          <xs:enumeration value="blanchedalmond"/>
          <xs:enumeration value="blue"/>
          <xs:enumeration value="blueviolet"/>
          <xs:enumeration value="brown"/>
          <xs:enumeration value="burlywood"/>
          <xs:enumeration value="cadetblue"/>
          <xs:enumeration value="chartreuse"/>
          <xs:enumeration value="chocolate"/>
          <xs:enumeration value="coral"/>
          <xs:enumeration value="cornflowerblue"/>
          <xs:enumeration value="cornsilk"/>
          <xs:enumeration value="crimson"/>
          <xs:enumeration value="cyan"/>
          <xs:enumeration value="darkblue"/>
          <xs:enumeration value="darkcyan"/>
          <xs:enumeration value="darkgoldenrod"/>
          <xs:enumeration value="darkgray"/>
          <xs:enumeration value="darkgreen"/>
          <xs:enumeration value="darkgrey"/>
          <xs:enumeration value="darkkhaki"/>
          <xs:enumeration value="darkmagenta"/>
          <xs:enumeration value="darkolivegreen"/>
          <xs:enumeration value="darkorange"/>
          <xs:enumeration value="darkorchid"/>
          <xs:enumeration value="darkred"/>
          <xs:enumeration value="darksalmon"/>
          <xs:enumeration value="darkseagreen"/>
          <xs:enumeration value="darkslateblue"/>
          <xs:enumeration value="darkslategray"/>
          <xs:enumeration value="darkslategrey"/>
          <xs:enumeration value="darkturquoise"/>
          <xs:enumeration value="darkviolet"/>
          <xs:enumeration value="deeppink"/>
          <xs:enumeration value="deepskyblue"/>
          <xs:enumeration value="dimgray"/>
          <xs:enumeration value="dimgrey"/>
          <xs:enumeration value="dodgerblue"/>
          <xs:enumeration value="firebrick"/>
          <xs:enumeration value="floralwhite"/>
          <xs:enumeration value="forestgreen"/>
          <xs:enumeration value="fuchsia"/>
          <xs:enumeration value="gainsboro"/>
          <xs:enumeration value="ghostwhite"/>
          <xs:enumeration value="gold"/>
          <xs:enumeration value="goldenrod"/>
          <xs:enumeration value="gray"/>
          <xs:enumeration value="grey"/>
          <xs:enumeration value="green"/>
          <xs:enumeration value="greenyellow"/>
          <xs:enumeration value="honeydew"/>
          <xs:enumeration value="hotpink"/>
          <xs:enumeration value="indianred"/>
          <xs:enumeration value="indigo"/>
          <xs:enumeration value="ivory"/>
          <xs:enumeration value="khaki"/>
          <xs:enumeration value="lavender"/>
          <xs:enumeration value="lavenderblush"/>
          <xs:enumeration value="lawngreen"/>
          <xs:enumeration value="lemonchiffon"/>
          <xs:enumeration value="lightblue"/>
          <xs:enumeration value="lightcoral"/>
          <xs:enumeration value="lightcyan"/>
          <xs:enumeration value="lightgoldenrodyellow"/>
          <xs:enumeration value="lightgray"/>
          <xs:enumeration value="lightgreen"/>
          <xs:enumeration value="lightgrey"/>
          <xs:enumeration value="lightpink"/>
          <xs:enumeration value="lightsalmon"/>
          <xs:enumeration value="lightseagreen"/>
          <xs:enumeration value="lightskyblue"/>
          <xs:enumeration value="lightslategray"/>
          <xs:enumeration value="lightslategrey"/>
          <xs:enumeration value="lightsteelblue"/>
          <xs:enumeration value="lightyellow"/>
          <xs:enumeration value="lime"/>
          <xs:enumeration value="limegreen"/>
          <xs:enumeration value="linen"/>
          <xs:enumeration value="magenta"/>
          <xs:enumeration value="maroon"/>
          <xs:enumeration value="mediumaquamarine"/>
          <xs:enumeration value="mediumblue"/>
          <xs:enumeration value="mediumorchid"/>
          <xs:enumeration value="mediumpurple"/>
          <xs:enumeration value="mediumseagreen"/>
          <xs:enumeration value="mediumslateblue"/>
          <xs:enumeration value="mediumspringgreen"/>
          <xs:enumeration value="mediumturquoise"/>
          <xs:enumeration value="mediumvioletred"/>
          <xs:enumeration value="midnightblue"/>
          <xs:enumeration value="mintcream"/>
          <xs:enumeration value="mistyrose"/>
          <xs:enumeration value="moccasin"/>
          <xs:enumeration value="navajowhite"/>
          <xs:enumeration value="navy"/>
          <xs:enumeration value="oldlace"/>
          <xs:enumeration value="olive"/>
          <xs:enumeration value="olivedrab"/>
          <xs:enumeration value="orange"/>
          <xs:enumeration value="orangered"/>
          <xs:enumeration value="orchid"/>
          <xs:enumeration value="palegoldenrod"/>
          <xs:enumeration value="palegreen"/>
          <xs:enumeration value="paleturquoise"/>
          <xs:enumeration value="palevioletred"/>
          <xs:enumeration value="papayawhip"/>
          <xs:enumeration value="peachpuff"/>
          <xs:enumeration value="peru"/>
          <xs:enumeration value="pink"/>
          <xs:enumeration value="plum"/>
          <xs:enumeration value="powderblue"/>
          <xs:enumeration value="purple"/>
          <xs:enumeration value="red"/>
          <xs:enumeration value="rosybrown"/>
          <xs:enumeration value="royalblue"/>
          <xs:enumeration value="saddlebrown"/>
          <xs:enumeration value="salmon"/>
          <xs:enumeration value="sandybrown"/>
          <xs:enumeration value="seagreen"/>
          <xs:enumeration value="seashell"/>
          <xs:enumeration value="sienna"/>
          <xs:enumeration value="silver"/>
          <xs:enumeration value="skyblue"/>
          <xs:enumeration value="slateblue"/>
          <xs:enumeration value="slategray"/>
          <xs:enumeration value="slategrey"/>
          <xs:enumeration value="snow"/>
          <xs:enumeration value="springgreen"/>
          <xs:enumeration value="steelblue"/>
          <xs:enumeration value="tan"/>
          <xs:enumeration value="teal"/>
          <xs:enumeration value="thistle"/>
          <xs:enumeration value="tomato"/>
          <xs:enumeration value="turquoise"/>
          <xs:enumeration value="violet"/>
          <xs:enumeration value="wheat"/>
          <xs:enumeration value="white"/>
          <xs:enumeration value="whitesmoke"/>
          <xs:enumeration value="yellow"/>
          <xs:enumeration value="yellowgreen"/>
        </xs:restriction>
      </xs:simpleType>
    </xs:union>
  </xs:simpleType>
  <xs:simpleType name="opacity">
    <xs:restriction base="xs:float">
      <xs:minInclusive value="0.0"/>
      <xs:maxInclusive value="1.0"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="horizontalAlignment">
    <xs:restriction base="xs:string">
      <xs:enumeration value="start"/>
      <xs:enumeration value="center"/>
      <xs:enumeration value="end"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="verticalAlignment">
    <xs:restriction base="xs:string">
      <xs:enumeration value="top"/>
      <xs:enumeration value="center"/>
      <xs:enumeration value="baseline"/>
      <xs:enumeration value="bottom"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:simpleType name="multilineJustification">
    <xs:restriction base="xs:string">
      <xs:enumeration value="left"/>
      <xs:enumeration value="center"/>
      <xs:enumeration value="right"/>
    </xs:restriction>
  </xs:simpleType>
  <xs:element name="textStyle">
    <xs:annotation>
      <xs:documentation>Text font style attribute</xs:documentation>
    </xs:annotation>
    <xs:complexType>
      <xs:attribute name="font-family" type="xs:string" use="required"/>
      <xs:attribute name="font-size" type="xs:float" use="required"/>
      <xs:attribute name="font-weight" type="fontWeight" use="optional" default="Normal"/>
      <xs:attribute name="font-style" type="fontStyle" use="optional" default="Normal"/>
      <xs:attribute name="text-decoration" type="textDecoration" use="optional" default="None"/>
      <xs:attribute name="letter-spacing" type="spacing" use="optional" default="Normal"/>
      <xs:attribute name="word-spacing" type="spacing" use="optional" default="Normal"/>
      <xs:attribute name="fill" type="colorType" use="optional" default="black"/>
      <xs:attribute name="fill-opacity" type="opacity" use="optional" default="1.0"/>
      <xs:attribute name="stroke" type="colorType" use="optional" default="black"/>
      <xs:attribute name="stroke-width" type="xs:float" use="optional" default="1.0"/>
      <xs:attribute name="stroke-opacity" type="opacity" use="optional" default="1.0"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="textLayout">
    <xs:annotation>
      <xs:documentation>Text alignment and justification </xs:documentation>
    </xs:annotation>
    <xs:complexType>
      <xs:attribute name="horizontalAlignment" type="horizontalAlignment" 
                    use="optional" default="start"/>
      <xs:attribute name="verticalAlignment" type="verticalAlignment" 
                    use="optional" default="top" />
      <xs:attribute name="multilineJustification" type="multilineJustification" 
                    use="optional" default="left"/>
      <xs:attribute name="multilineSpacing" type="xs:float" use="optional" default="0.0"/>
    </xs:complexType>
  </xs:element>
  <xs:complexType name="textAttributesType">
    <xs:annotation>
      <xs:documentation>OGC Annotation Style Definiton</xs:documentation>
    </xs:annotation>
    <xs:sequence>
      <xs:element ref="textStyle" minOccurs="0" maxOccurs="1"/>
      <xs:element ref="textLayout" minOccurs="0" maxOccurs="1"/>
    </xs:sequence>
  </xs:complexType>
  <xs:element name="textAttributes" type="textAttributesType"/>
</xs:schema>

Implications

TBD

Test Plan

TBD

Funding/Resources

TBD

Last modified 13 years ago Last modified on Apr 13, 2011, 10:14:52 AM

Attachments (2)

Download all attachments as: .zip

Note: See TracWiki for help on using the wiki.