A very powerful feature of the geodatabase data model is the ability to assign custom behavior through the use of feature class extensions. This paper discusses how to integrate a custom renderer with a feature class extension so that the feature class is automatically rendered with user-defined symbolization when it is loaded into ArcMap, or previewed in ArcCatalog. Developed for the U.S. Army's Digital Topographic Support System (DTSS), the application allows users to specify the desired symbolization by changing properties of symbols in a Style file that is linked to the custom renderer.
The Digital Topographic Support System (DTSS) provides a wide variety of terrain analysis and mapping capabilities for the U.S. Army. The most recent DTSS fielding is NT-based and uses the ArcInfo 8.0.2 suite of software as the primary production and analysis tool. The new system uses a series of modeled geodatabases that conform to National Imagery and Mapping Agency (NIMA) data formats such as Vector Product Format (VPF) and Interim Terrain Data (ITD). Similarly, modeled geodatabases have been created for DTSS output products, including Mobility and Line-of-Sight Tactical Decision Aids (TDA). The result is a fully integrated system that allows users to import raw VPF or ITD datasets into modeled geodatabases, then to perform an analysis (such as a Line-of-Sight terrain profile), and finally to produce a map using an automated map production tool developed for the system.
With more than 300 feature classes contained within the standard modeled geodatabases developed for DTSS, it was clear that some sort of default symbolization would be needed. The benefits of default symbolization include a standard look for all DTSS products, and increased productivity whereby users are not required to symbolize large numbers of datasets each time they are loaded into ArcMap. Several options were explored as methods for providing default symbolization, including the use of layer files, matching symbols from a Style, and the use of feature class extensions.
Layer files could be used, but there would be several drawbacks to their implementation, including the large number of layer files that would need to be maintained and a several-step process required on the part of users. Matching symbols from a Style in the symbology dialog turned out to be impractical due to limitations inherent in ArcInfo 8.0.2 when using numeric fields for symbolization. In addition, this solution, like the use of layer files, would have required several steps by the user in order to achieve the desired results. The third option, using a feature class extension, proved to be the most desirable solution, as it provides for seamless user interaction and requires maintenance of a minimal number of supporting files. Another benefit is that the feature class extension is recognized by ArcCatalog, which allows default symbology to be applied when viewing data in ArcCatalog, just as it is in ArcMap (Figure 1).
Figure 1. ArcCatalog Preview
The feature class extension is a class extension object within the Desktop ArcInfo development framework known as ArcObjects that allows developers to implement optional interfaces in order to customize geodatabase behavior at the feature class level. The optional interface used to provide custom drawing behavior is the IFeatureClassDraw interface. When a feature class has a feature class extension defined, the feature class will check the extension before drawing to see if the IFeatureClassDraw interface is supported. It is through the IFeatureClassDraw interface that the feature class accesses custom renderer objects that define symbology and provide instructions for drawing the feature class. The renderer objects can be of the types provided by ArcObjects, such as class breaks or unique values renderers, which is the case with DTSS, or they can be custom objects created to provide specialized drawing for custom features or applications.
An integral part of the DTSS application has been the creation of a Style file for each DTSS product, such as imported VPF or ITD data, or the various TDAs. The Styles were created manually using ArcMap's Style Manager, and include symbology and labels used by the various renderers. In Figure 2 we see a schematic representation of how the Styles are integrated into the feature class extension, while Figure 3 shows a Mobility Analysis TDA for Fort Hood, Texas, that has been created from Vector Product Interim Terrain Data (VITD) using DTSS default symbology derived from the VITD Style.
Figure 2. DTSS Feature Class Extension
Figure 3. Fort Hood Mobility Analysis
Developed using Visual Basic, the code for the DTSS feature class extension consists of a class module which implements the IClassExtension and IFeatureClassDraw interfaces, and a base module that contains rendering routines for each of the supported DTSS products. The extension is a dynamically linked library (DLL) that has its Unique Identifier Object (UID) associated with each feature class for which default symbolization is applied. When such feature classes are initialized, the extension first detects the name of the feature dataset, which is used as a key to select the correct Style file for the feature class. Finally, the extension reads the symbols from the Style and the desired renderer is created. With this, the feature class is drawn in ArcMap or ArcCatalog with the desired symbolization.
There are several advantages of this implementation. One advantage is that by detecting the type of product being drawn (VITD, ITD, Mobility, etc.) and calling the appropriate routine, configuration management is simplified since it is possible to create custom symbolization for all DTSS products while using only one DLL. Another advantage is that by using Style files for the default symbols, the symbols are not hard-coded. This allows users to create default symbolization that meets specific user needs by using the Style Manager to modify the symbols in the Style (Figure 4). In any case, the user is not locked into the default symbols. Once the feature class has been loaded into ArcMap, the user has complete freedom to symbolize the data in any way, using standard ArcMap symbolization tools.
Figure 4. Style Manager
There are several limitations that also should be noted. With this implementation, the default symbolization is available only if the feature class extension is present and registered on the user's system. If the feature class extension is not present and registered, an error ocurrs and the feature class cannot be opened. To overcome this on non-DTSS systems, the geodatabase can be modified using Microsoft Access to delete the references to the feature class extension UID. Alternatively, a separate application has been developed that installs the files required for default symbolization, without installing the entire DTSS application.
Another limitation occurs when creating features in an empty DTSS template geodatabase that is provided to users for the purpose of creating their own datasets in NIMA format. In this case, new features are not symbolized since they were not present when the feature class was initialized. When performing this operation it is therefore best to set the symbolization to a single symbol, add the new features, save edits, then unload and reload the feature class. Upon reloading, the feature class extension will detect the new features and symbolize them appropriately. In this same way, if the user makes changes to the symbolization after loading data into ArcMap and then wishes to return to the default symbolization, it is necessary to unload and reload the feature class.
The IClassExtension interface is key to the creation of a feature class extension, in that it establishes the connection between the feature class and the custom behavior defined by optional interfaces, such as IFeatureClassDraw. The feature class extension is initialized through the Init method of IClassExtension, which passes a reference to the IClassHelper object. Through the class helper, the feature class can be obtained by referencing the Class property of IClassHelper.
The following sample code shows how IClassExtension_Init has been implemented in DTSS. Notice that a reference to the extension's object class is not maintained directly, but is only accessed via the class helper as necessary (See ExploringArcObjects, page 727, ArcInfo 8.1 Pre-release Documentation). For example, after accessing the feature class in order to get the feature dataset name, the IFeatureClass object (pFClass) is set to Nothing so that the reference is removed. Otherwise, problems have been experienced with geodatabases remaining locked, even after deleting all associated layers from ArcMap.
Implements IClassExtension
Private m_strDataType As String
Private m_pClassHelper As EsriCore.IClassHelper
Private Sub IClassExtension_Init(ByVal pClassHelper As IClassHelper, _
ByVal pExtensionProperties As IPropertySet)
Dim pFClass as IFeatureClass
Set m_pClassHelper = pClassHelper 'Instantiate class helper variable.
Set pFClass = pClassHelper.Class 'Get reference to feature class.
m_strDataType = pFClass.FeatureDataset.Name 'Get feature dataset name.
Set pFClass = Nothing
End Sub
It is through the IFeatureClassDraw interface that the default symbolization for DTSS products is implemented. Of the six available properties and methods for IFeatureClassDraw, three are used in the application. The DoesCustomDrawing method is set to “False” and the HasCustomRenderer method is set to “True”, while the CustomRenderer property is used to assign the appropriate renderer to the feature class.
The following sample code shows how the CustomRenderer property is implemented for VITD data. In this case, certain VITD feature classes use a simple renderer, while others use a unique value renderer. An instance of each is passed to the rendering routine, which then detects the appropriate renderer for the feature class and passes only that renderer back to the calling routine as a valid renderer. The CustomRenderer property for IFeatureClassDraw is then set to the valid renderer returned by the rendering routine. Notice that only an indirect reference to the feature class object class is passed to the rendering routine via the class helper, so as to avoid the previously mentioned problem of the geodatabase becoming inappropriately locked. Note also that the data type (VITD, ITD, etc.) is passed to the rendering routine so that the appropriate Style file can be referenced by the renderer.
Dim pSimpleRenderer As ISimpleRenderer
Dim pUVRenderer As IUniqueValueRenderer
Select Case m_strDataType
Case "VITD"
'Instantiate renderers.
Set pSimpleRenderer = New SimpleRenderer
Set pUVRenderer = New UniqueValueRenderer
'Pass only reference to object class to rendering routine,
'along with the renderers and data type.
Call RenderVITD(m_pClassHelper.Class, pSimpleRenderer, _
pUVRenderer, m_strDataType)
If Not pSimpleRenderer Is Nothing And pUVRenderer Is Nothing Then
'Simple renderer is returned.
IFeatureClassDraw_CustomRenderer = pSimpleRenderer
ElseIf Not pUVRenderer Is Nothing And pSimpleRenderer Is Nothing Then
'Unique value renderer is returned.
IFeatureClassDraw_CustomRenderer = pUVRenderer
End If
'Add additional cases for different data types such as ITD, FFD, Mobility, etc.
End Select
Set pSimpleRenderer = Nothing
Set pUVRenderer = Nothing
End Property
An integral part of the rendering application is the ability to read symbols from a Style file for use with the appropriate renderer. In order to do this, reference to the Style file must be added to the collection of available Styles in the Style Gallery, using the IStyleGallery and IStyleGalleryStorage interfaces. Once reference to the appropriate Style file is established, the IEnumStyleGalleryItem and IStyleGalleryItem interfaces are used to access the symbols in the Style file. After the renderer object has been created, reference to the Style file is removed from the Style Gallery so that multiple instances of the Style are not created.
The sample code that follows shows how use of the Style Gallery is implemented. In this simple case, the feature class in question is "network_Junctions", where all features are symbolized with a single symbol. For more complex feature classes, such as "Vegetation_Water_Area" highlighted in Figure 4, symbology can be based on unique values or class breaks. In such cases additional steps are needed to detect either the unique values or the range of values, and to apply them to the appropriate renderer. In addition, if domains are used, it is necessary to read values from the domain so that labeling can consist of domain values rather than actual values.
The first step is to instantiate pStyleGallStorage and pStyleGall. We then check for the feature class name, as that is used in the Style as the category name (See Figure 4.) Next, the class name (Fill Symbols, Marker Symbols, etc.) is set, based on the shape type of the feature class. We then look for the data type and select the appropriate Style file, which is then added to the Style Gallery Storage. The pEnumStyleGall is then set to the items in the Style Gallery that correspond to the class name and category name. Next, the items in pEnumStyleGall are looped through to find the one whose name matches the name specified; in this case “network junction.” The single symbol for the simple renderer is set, as is the label (network junction), and finally, the Style is removed from Style Gallery Storage.
Although not a part of the feature class extension itself, an important step in the DTSS implementation is the application of the feature class extension's UID to the feature classes for which default symbolization is provided. While this can be done manually by opening the geodatabase in Microsoft Access and adding the UID to the EXTCLSID field of the GDB_ObjectClasses table, the requirements of DTSS are such that an automated process is needed for this step when DTSS products are created. The ISchemaLock interface is the appropriate interface for this purpose. As described in the ArcObjects Developer Help provided with ArcInfo 8.0.2, ISchemaLock is used to establish an exclusive lock on a dataset when changing its schema, or when performing other operations that require exclusive access to a dataset. The following example of its implementation was used with the various DTSS products and is taken directly from the ArcObjects Developer Help for ISchemaLock.
Dim pWSF As IWorkspaceFactory
Set pWSF = New AccessWorkspaceFactory
Dim pWS As IWorkspace
Set pWS = pWSF.OpenFromFile("d:\\data\\testclsext2.mdb", 0)
' QI for IFeatureWorkspace
Dim pFeatWS As IFeatureWorkspace
Set pFeatWS = pWS
' open the object class whose class schema you want to modify
Dim pOc As IObjectClass
Dim pTab As ITable
Set pTab = pFeatWS.OpenFeatureClass("buildings")
Set pOc = pTab
' QI for the IClassSchemEdit interface
Dim pOcSchemaEdit As IClassSchemaEdit
Set pOcSchemaEdit = pOc
' set an exclusive lock on the class
Dim pSchLock As ISchemaLock
Set pSchLock = pOc
pSchLock.ChangeSchemaLock (EsriExclusiveSchemaLock)
' create the IUID object
Dim pCUID As IUID
Set pCUID = New UID
pCUID.Value = "\{484F435C-9A08-11D3-815A-0080C78E8371\"
' alter the class extension for the class
pOcSchemaEdit.AlterClassExtensionCLSID pCUID, Nothing
' release the exclusive lock
pSchLock.ChangeSchemaLock (EsriSharedSchemaLock)
We see from the above discussion that the feature class extension is a very useful tool for assigning custom behavior to geodatabase feature classes. In addition to the custom rendering provided in DTSS, other optional implementations for feature class extensions include a custom object inspector, extension of the validation rules that are assigned to a spatial or non-spatial table, and the reception of notification messages when a new related feature is created. For DTSS, the feature class extension is an efficient tool that provides a common look to products created by all users, regardless of where they are stationed, yet there is flexibility that allows for individual customization as needed. As such, it has become an integral part of all phases of data creation, analysis, and presentation within the Army's Digital Topographic Support System.
ExploringArcObjects, Beta Draft Version, Environmental Systems Research Institute, Inc., November 16, 2000, Redlands, California.
ArcObjects Developer Help, ArcInfo Version 8.0.2, Environmental Systems Research, Inc., February 2000, Redlands, California.