How to create a topology in the geodatabase


Summary
A topology is a collection of simple feature classes within the same feature dataset that participate in topological relationships with a set of rules that govern those relationships. Topologies can have multiple feature classes in the same topological role. A feature dataset can have multiple topologies, but a feature class can only belong to one topology and only simple feature classes can participate in a topology.
Prior to creating the topology, ensure that you have an exclusive schema lock on the feature dataset. Use the ISchemaLock interface to determine if other locks exist and to get an exclusive lock on the feature dataset.
This article shows a common workflow for creating topologies within the geodatabase.

In this topic


Creating a topology in the geodatabase

The topology object is not one that is created together with another object; topologies must be created using the ITopologyContainer.CreateTopology or ITopologyContainer2.CreateTopologyEx. Once the topology is created, the AddClass and AddRule methods are used to add classes and rules to the topology.

Each topology has one associated topology graph. The topology graph is a planar representation of the geometries in the feature classes participating in a geodatabase topology. If you need to access the topology graph directly to work with topology primitives such as edges and nodes.
When new features are created, edited, or deleted, the topology is responsible for creating or modifying a dirty area that will encompass the envelope of the feature. A dirty area is a special type of feature where the state of the topology is unknown. Features that are covered by dirty areas can still be edited and queried, but their topological relationships cannot be guaranteed to be correct. A dirty area must be validated to discover the topology of its underlying features and guarantee their correctness.

The following screen shot shows an example of how dirty areas and topology errors work in a topology:
 

Each topology has one inherent rule—esriTRTFeatureLargerThanClusterTolerance—to identify features that are less than the defined cluster tolerance for the topology.
 
Initial topology creation
Each method creates a topology with the specified name, cluster tolerance, maximum allowable number of generated errors, and for ArcSDE, the supplied configuration keyword is created. When a topology is initially created, it is empty with no participating feature classes or rules. The decision on when to use one method over the other is based on whether the feature classes that participate in the topology are z–aware. If they are not z–aware, the CreateTopology method should be used. Whereas, if the feature classes are z–aware, CreateTopologyEx method should be used as it allows the setting of a z–cluster tolerance, in addition to the x,y–cluster tolerance.
 
Careful consideration should be given to specifying the parameters when creating a topology. Once the topology is built, none of the parameters can be modified. To change properties, such as cluster tolerance, the topology must be deleted and rebuilt with the new parameters.
 
Topology name
You need to provide a name for the topology. The name of the topology (fully qualified name for ArcSDE geodatabases) must be unique within the geodatabase. You can use the IWorkspace2.NameExists property to ensure you select a unique name. If you only have one topology in your feature dataset, you can choose to give it a name that is based on the feature dataset, such as Parcels_Topo.
 
X,Y–cluster tolerance
In general, you will want to set the ClusterTolerance parameter to be equal to the
ITopologyContainer.DefaultClusterTolerance. In ArcGIS 9.2 geodatabases, this value is equal
to the tolerance of the feature dataset, which is generally 0.001 meters, or the equivalent
in the units of the spatial reference. Values that are smaller than the DefaultClusterTolerance or larger than the ITopologyContainer.MaximumClusterTolerance are not permitted.
 
Z–cluster tolerance
The z–tolerance is used to distinguish the z–height or elevation of vertices within the tolerance of one another. For example, two adjacent features of different heights can share a common edge between them; their x,y–vertices are located close together, not their z–value or height.
 
The value that you supply for your z–tolerance depends on the type of surface you're modeling with the z–aware feature classes. If you're modeling city buildings, two buildings can be adjacent to one another and appear to share a common edge in the x,y–domain. However, you may be concerned about maintaining the relative height of each building structure during the topology validation process. By setting the z–cluster tolerance to a value of 0, you can prevent z–values from clustering when you validate a topology. The default z–cluster tolerance for all topologies is 0 and can be obtained through the ITopologyContainer2.DefaultZClusterTolerance property.
 
The following illustration shows how the validation process behaves with a z–cluster tolerance of 0. The vertices of the left side of the red feature are coincident with the right edge of the blue feature. This results in two vertices being introduced to the blue feature during validation. Because the z–tolerance is 0, the two new vertices have z–values of 10, equaling the values of their neighboring vertices in the blue feature. See the following:
 
 
If you're modeling a surface, you can have datasets collected with different x,y and z–accuracies. In this case, you may want to set a z–cluster tolerance greater than 0 to allow clustering during the validation process. To avoid z–values collected with a high-level of accuracy clustering to z–values of less accuracy, you can assign each feature class a rank. Lower-ranked features' z–values cluster to the elevation of higher-ranked vertices if they fall within the cluster tolerance. Z–values of vertices belonging to feature classes of the same rank are averaged if they fall within the cluster tolerance.
 
The following illustration shows how the validation process behaves with a z–cluster tolerance greater than 0. The vertices of the left side of the red feature are coincident with vertices on the right edge of the blue feature. The vertices on the red feature have z–values of 20, while the vertices of the blue feature have z–values of 10. During validation, the z–values are clustered, since they lie within the z–cluster tolerance and result in the vertices having z–values of 15. See the following:
 
 
Maximum generated error count and configuration keywords
The maxGeneratedErrorCount parameter specifies the maximum number of errors validation generates before stopping. Setting a value of –1 indicates there is no limit to the number of errors that are generated. Generally, you will want to stick with the default value of –1 for your topology.
 
The configurationKeyword parameter allows the application to control the physical layout for this table in the underlying relational database management system (RDBMS); for example, in the case of an Oracle database, the configuration keyword controls the table space where the table is created, the initial and next extents, and other properties.
 
The configurationKeywords for an ArcSDE instance are set up by the ArcSDE data administrator. The list of available keywords supported by a workspace can be obtained using the IWorkspaceConfiguration interface. The configurationKeyword parameter is not mandatory when building a topology in an ArcSDE geodatabase. An empty string can be specified where the topology is built using the default configuration. For more information on configuration keywords, refer to the Desktop documentation on "An overview of configuration keywords and how they are used".
 
Prior to creating a topology, an exclusive schema lock should be obtained for the target feature dataset.  For more information on obtaining an exclusive lock, see the complete code example at the end of this article.
The following code examples show how to use the CreateTopology and CreateTopologyEx methods to create a topology:
[Java]
// featureDataset is an IFeatureDataset where the topology will be located
// specifyZClusterTolerance is a System.Boolean whether a ZClusterTolerance has been specified
// topologyName is a String with the topology's name
// Cast the feature dataset to the ITopologyContainer2 interface to create a new topology.
ITopologyContainer2 topologyContainer = (ITopologyContainer2)featureDataset;
ITopology topology = null;
if (specifyZClusterTolerance){
    topology = topologyContainer.createTopologyEx(topologyName,
        topologyContainer.getDefaultClusterTolerance(),
        topologyContainer.getDefaultZClusterTolerance(),  - 1, "");
}

else{
    topology = topologyContainer.createTopology(topologyName,
        topologyContainer.getDefaultClusterTolerance(),  - 1, "");
}
Add feature classes to a topology
The AddClass method is used to add a feature class to a topology with the specified weight and ranks. The weight must be an integer between 1 and 10. Although it is not used in ArcGIS, it must still be specified. The x,y–rank and z–rank must each be an integer between 1 and 63. Ranks higher than 51 result in errors when specified in either the New Topology wizard or Topology property page. Even if the feature class being added to the topology is not z–aware, it must have a z–rank specified. The x,y and z–ranks represent the accuracies of the feature class relative to other feature classes participating in the topology. Feature classes with a higher rank, such as 1 are more accurate than feature classes with a lower rank, such as 2. Ranks are a relative measure of accuracy; the difference between two features classes of ranks 1 and 2 is the same as two feature classes with ranks of 1 and 50. Multiple feature classes in a topology can have the same rank.
The EventNotificationOnValidate parameter indicates if an event is broadcast when the topology that the feature class participates in is validated. The EventNotificationOnValidate parameter can only be set if the topology is created programmatically. The ITopologyClassEvents interface provides access to the OnValidate event, which is fired each time a dirty area is validated in the topology where the class is participating. The event returns an IGeometry object corresponding to the area that was validated.
Complicated feature classes, such as annotation, dimension, geometric network, and feature classes already in a topology, cannot be added to a topology. Also, object classes or tables and versioned, uncomplicated feature classes cannot be added to a topology. 
After a populated feature class is added to a topology that has been validated—in whole or in part—the state of the topology changes and a dirty area corresponding to the extent of the feature class is created. If an unpopulated feature class is added to a topology, the topology's state does not change and no dirty area is created.
The following code sample shows how to add a feature class to a topology:
[Java]
// ITopology.addClass(IClass class, double weight, int xyRank, int zRnk, boolean EventNotificationOnValidate)
topology.addClass(featureClass, weight, xyRank, zRank, false);
Add rules to a topology
As mentioned previously, each topology is created with at least one default rule (that is, must be larger than cluster tolerance rule). You can choose to add additional rules to a topology. The ITopologyRuleContainer interface provides access for adding, removing, and returning topology rules from a topology. This interface also provides access to members that control the promotion and demotion of topology errors and exceptions.
Before adding a rule to a topology, use the CanAddRule property to determine if the rule is consistent and does not conflict with any existing topology rules. For example, topology rules of the same type cannot be specified at the class level and subtype level for the same feature class.
Using AddRule on a topology that has already been validated—in whole or in part—results in a dirty area created for the extent of the feature classes participating in the rule and a change to the state of the topology to esriTSUnanalyzed.
The following code example shows how to create a single feature class topology rule and add it to a topology: 
[Java]
//ruleType is an integer constant belonging to esriTopologyRuleType
static void addRuleToTopology(ITopology topology, int ruleType, String ruleName,
    IFeatureClass featureClass)throws Exception{
    // Create a new topology rule.
    ITopologyRule topologyRule = new TopologyRule();
    topologyRule.setTopologyRuleType(ruleType);
    topologyRule.setName(ruleName);
    topologyRule.setOriginClassID(featureClass.getFeatureClassID());
    topologyRule.setAllOriginSubtypes(true);
    // Cast the topology to the ITopologyRuleContainer interface and add the rule.
    ITopologyRuleContainer topologyRuleContainer = (ITopologyRuleContainer)topology;
    if (topologyRuleContainer.isCanAddRule(topologyRule)){
        topologyRuleContainer.addRule(topologyRule);
    }
    else{
        throw new Exception("Could not add specified rule to the topology.");
    }
}
The following code example demonstrates how to create a topology rule between two feature classes, specify it at the subtype level for the destination, and add it to the topology:
[Java]
static void addRuleToTopology(ITopology topology, int ruleType, String ruleName,
    IFeatureClass originClass, int originSubtype, IFeatureClass destinationClass,
    int destinationSubtype)throws Exception{
    // Create a new topology rule.
    ITopologyRule topologyRule = new TopologyRule();
    topologyRule.setTopologyRuleType(ruleType);
    topologyRule.setName(ruleName);
    topologyRule.setOriginClassID(originClass.getFeatureClassID());
    topologyRule.setAllOriginSubtypes(false);
    topologyRule.setOriginSubtype(originSubtype);
    topologyRule.setDestinationClassID(destinationClass.getFeatureClassID());
    topologyRule.setAllDestinationSubtypes(false);
    topologyRule.setDestinationSubtype(destinationSubtype);
    // Cast the topology to the ITopologyRuleContainer interface and add the rule.
    ITopologyRuleContainer topologyRuleContainer = (ITopologyRuleContainer)topology;
    if (topologyRuleContainer.isCanAddRule(topologyRule)){
        topologyRuleContainer.addRule(topologyRule);
    }
    else{
        throw new Exception("Could not add specified rule to the topology.");
    }
}
Validate the topology
Once the topology has been created with all the feature classes and rules, you can optionally choose to validate the topology. However, this is not required, since the entire topology is covered by a dirty area. Until the topology is validated, the topological relationships of the features cannot be guaranteed.
The following code example shows one way of running a validation on a topology:
[Java]
static void validateTopology(ITopology topology, IEnvelope envelope)throws Exception{
    // Get the dirty area within the provided envelope.
    IPolygon locationPolygon = new Polygon();
    ISegmentCollection segmentCollection = (ISegmentCollection)locationPolygon;
    segmentCollection.setRectangle(envelope);
    IPolygon polygon = topology.getDirtyArea(locationPolygon);
    // If a dirty area exists, validate the topology.
    if (!polygon.isEmpty()){
        // Define the area to validate and validate the topology.
        IEnvelope areaToValidate = polygon.getEnvelope();
        IEnvelope areaValidated = topology.validateTopology(areaToValidate);
    }
}

Complete Code Example

The following code example shows the previous examples being used sequentially to create a new topology:
[Java]
static void createTopology()throws Exception{
    // Open the workspace and the required datasets.
    IWorkspaceFactory workspaceFactory = new FileGDBWorkspaceFactory();
    IWorkspace workspace = workspaceFactory.openFromFile(
        "C:/arcgis/ArcTutor/BuildingaGeodatabase/Montgomery.gdb", 0);
    IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)workspace;
    IFeatureDataset featureDataset = featureWorkspace.openFeatureDataset("Landbase");
    IFeatureClass blocksFC = featureWorkspace.openFeatureClass("Blocks");
    IFeatureClass parcelsFC = featureWorkspace.openFeatureClass("Parcels");
    // Attempt to acquire an exclusive schema lock on the feature dataset.
    ISchemaLock schemaLock = (ISchemaLock)featureDataset;
    schemaLock.changeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock);
    // Create the topology.
    ITopologyContainer2 topologyContainer = (ITopologyContainer2)featureDataset;
    ITopology topology = topologyContainer.createTopology("Landbase_Topology",
        topologyContainer.getDefaultClusterTolerance(),  - 1, "");
    // Add feature classes and rules to the topology.
    topology.addClass(blocksFC, 5, 1, 1, false);
    topology.addClass(parcelsFC, 5, 1, 1, false);
    addRuleToTopology(topology, esriTopologyRuleType.esriTRTAreaNoOverlap, 
        "No Block Overlap", blocksFC);
    addRuleToTopology(topology, esriTopologyRuleType.esriTRTAreaCoveredByAreaClass, 
        "ResParcels Covered by ResBlocks", parcelsFC, 1, blocksFC, 1);
    // Get an envelope with the topology's extents and validate the topology.
    IGeoDataset geoDataset = (IGeoDataset)topology;
    IEnvelope envelope = geoDataset.getExtent();
    validateTopology(topology, envelope);
    schemaLock.changeSchemaLock(esriSchemaLock.esriSharedSchemaLock);
}


See Also:

How to check for topology error features in a geodatabase topology




Development licensingDeployment licensing
ArcGIS for Desktop StandardArcGIS for Desktop Standard
ArcGIS for Desktop AdvancedArcGIS for Desktop Advanced
Engine Developer KitEngine: Geodatabase Update