This post was contributed by Joe Chandler.
I would like to show how you can utilize the Topobase tracing API. For this example we will be using the Topobase Batch executable to actually run the trace, but this code can be incorporated into a client plug-in just as easily.
For ease of demonstration we will be randomly selecting a couple of features from an attribute feature class specified in the Data section of the Topobase Batch XML configuration file. The XML file contains the following contents:
<?xml version="1.0" encoding="utf-8" ?>
<Batch>
<Assembly
AssemblyName="TraceExample.dll"
Namespace="TraceExample"
ClassName="TraceExample"></Assembly>
<Connection
Username="WATER"
PassWord="WATER"
Datasource="ORCL"
tbsysUsername="TBSYS"
tbsysPassword="TBSYS"
tbsysDataSource="ORCL"></Connection>
<Data
TopologyName="WA"
TestFeatureGeometryClass="WA_POINT"
TestFeatureClass="WA_FITTING">
</Data>
</Batch>
The example will create a search template and associated stop condition programmatically and use these newly created objects for the trace. We will be using an existing Topology for the example which is also specified in the Topobase Batch XML configuration file. The following image represents where predefined search templates and conditions can be found in the administrator.
This example relies on the following Topobase assemblies:
- Topobase.Batch.dll
- Topobase.Data.dll
- Topobase.LogicalTopology.dll
- Topobase.Tracing.dll
The Run() method in this example gets things started by selecting features from the specified TestFeatureClass, which in this example is the WA_FITTING feature class. It then calls the Trace method with a start feature and an end feature. In this example the end feature will be used as a stop condition for a Reachability network trace type. The second call to the Trace method is passing null as the end feature which will let the tracing run without a trace stop condition.
public override void Run()
{
Topobase.Data.FeatureClass attributeFeatureClass =
_connection.FeatureClasses[_testFeatureClass];
if (attributeFeatureClass == null || !attributeFeatureClass.IsAttributeTable)
{
_logger.ErrorFormat("Invalid example feature class {0}. " +
"It must be a valid attribute feature class.", _testFeatureClass);
return;
}
Topobase.Data.FeatureList allFeatures = attributeFeatureClass.GetFeatures();
if (allFeatures.Count <= 2)
{
_logger.ErrorFormat("Not enough features in class {0} for the example to run.",
_testFeatureClass);
return;
}
//made it here - now lets do some example tracing
Trace(_topology, allFeatures[0], allFeatures[2]);
Trace(_topology, allFeatures[0], null);
}
The following section is the tracing code itself. Below are a few items to note about the API usage:
- The LogicalTracing instance that is created will use a specific tracing algorithm based on the tracing type specified in the NetworkSearchTemplate instance. Care should be taken when calling the LogicalTracing.Trace(…) method as not all tracing algorithms take start and end features. For example, with the Reachability algorithm, end features cannot be specified. If they are, an exception will be thrown.
- The features passed as start and end features should not be attribute features. This example is specifically demonstrating that the geometry feature instance must be retrieved and passed to the LogicalTracing.Trace(…) method if dealing with attribute feature classes.
- There is a convenience method that can be used to take the TracingResult and convert it into an IList
instance.
private void Trace(string topologyName, Topobase.Data.Feature startFeature,
Topobase.Data.Feature endFeature)
{
//setup the topology and the search template to be used
Topobase.Data.Doc.Topologies.LogicalTopology logicalTopology =
(Topobase.Data.Doc.Topologies.LogicalTopology)_connection.Topologies[topologyName];
Topobase.Data.Doc.Topologies.NetworkSearchTemplate theSearchTemplate =
CreateReachabilityTemplate(endFeature);
//we need to use the fid of the geometry class and not the attribute class
//This is done for both the start and the end features.
Topobase.Data.FeatureClass pointFeatureClass =
_connection.FeatureClasses[_geometryFeatureClass];
Topobase.Data.FeatureList startFeatures = pointFeatureClass.GetFeatures("FID_ATTR = "
+ startFeature.FID);
Topobase.Data.FeatureList endFeatures = null;
if (endFeature != null)
endFeatures = pointFeatureClass.GetFeatures("FID_ATTR = " + endFeature.FID);
//Create the tracer instance and perform the trace
Topobase.LogicalTopology.Tracing.LogicalTracing tracer =
new Topobase.LogicalTopology.Tracing.LogicalTracing(
logicalTopology, theSearchTemplate);
Topobase.Tracing.TracingResult ret = null;
bool b = tracer.Trace(startFeatures, null, out ret);
//get the results as features
//and possibly do something with the results here -
//maybe store them in a table for reporting OR
//store them in a table to be displayed by another system as a layer with FDO
IList tracerResultFeatures = tracer.ConvertTracingResult(ret);
_logger.Info("The total number of trace results: " + tracerResultFeatures.Count);
}
This last code snippet is showing how to create a NetworkSearchTemplate instance with a stop condition, if a valid end feature is specified. The following are a few items to note about the API usage:
- With the Reachability trace type end features cannot be passed as parameters to the trace method so a stop condition can be used to terminate the trace if desired.
- You can use the preconfigured tracing templates, but care should be taken when adding stop conditions to the template as they will be added in the database. If your code dynamically needs to add stop conditions this could potentially interfere with other tracing operations being performed if the conditions are not removed after the trace.
private Topobase.Data.Doc.Topologies.NetworkSearchTemplate CreateReachabilityTemplate(
Topobase.Data.Feature stopConditionFeature)
{
Topobase.Data.Doc.Topologies.NetworkSearchTemplate theSearchTemplate =
new Topobase.Data.Doc.Topologies.NetworkSearchTemplate();
theSearchTemplate.Name = "Trace Example Template";
theSearchTemplate.Type =
Topobase.Data.Doc.Topologies.NetworkSearchTemplate.TraceType.Reachability;
theSearchTemplate.Direction =
Topobase.Data.Doc.Topologies.NetworkSearchTemplate.TraceDirection.Both;
if (stopConditionFeature != null)
{
Topobase.Data.Doc.Topologies.NetworkSearchCondition myCondition =
new Topobase.Data.Doc.Topologies.NetworkSearchCondition();
myCondition.Active = true;
myCondition.IsCost = false;
myCondition.Name = "Trace Example - Generated";
myCondition.Type =
Topobase.Data.Doc.Topologies.NetworkSearchCondition.ConditionType.NodeCondition;
Topobase.Data.FeatureClass pointFeatureClass =
_connection.FeatureClasses[_geometryFeatureClass];
myCondition.SqlStatement = "case /* Point */ when &f_class_id = "
+ pointFeatureClass.ID + " then (select case when f_class_id_attr = "
+ stopConditionFeature.FeatureClass.ID;
myCondition.SqlStatement += " then (select 1 from "
+ stopConditionFeature.FeatureClass.Name + " where fid=wa_point.fid_attr and fid ="
+ stopConditionFeature.FID + ") else null end from "
+ pointFeatureClass.Name + " wa_point where fid=&fid) else null end";
if (_logger.IsDebugEnabled)
_logger.Debug(myCondition.SqlStatement);
Topobase.Data.Doc.Topologies.NetworkSearchTemplateCondition myTemplateCondition =
new Topobase.Data.Doc.Topologies.NetworkSearchTemplateCondition(myCondition);
theSearchTemplate.Conditions.Add(myTemplateCondition);
}
return theSearchTemplate;
}
The following image represents the trace results from within Topobase using a default tracing template with no stop conditions (7 results found):
The following are the results from the batch tracing demonstrating the use of the API. These results are taken from the Topobase Application.log.
With the stop condition: The total number of trace results: 4
Without the stop condition: The total number of trace results: 7
AUTODESK DOES NOT GUARANTEE THAT YOU WILL BE ABLE TO SUCCESSFULLY DOWNLOAD OR IMPLEMENT ANY SAMPLE CODE. SAMPLE CODE IS SUBJECT TO CHANGE WITHOUT NOTICE TO YOU.
AUTODESK PROVIDES SAMPLE CODE "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE. IN NO EVENT SHALL AUTODESK OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS
OF DATA, OR LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, THAT MAY OCCUR AS A RESULT OF IMPLEMENTING OR USING ANY SAMPLE CODE, EVEN IF AUTODESK OR ITS SUPPLIERS
HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
very informational... educative as well, i've been a very good follower of your blog... all am gonna say is good job!
Posted by: Acai Optimum | March 29, 2010 at 02:43 PM