About the Implementing a schematic layout algorithm and its layout property page Sample
[C#]
TranslateTree.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.ADF.CATIDs;
using ESRI.ArcGIS.Schematic;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
namespace ApplicativeAlgorithms
{
[ClassInterface(ClassInterfaceType.None)]
[Guid(TranslateTree.GUID)]
[ProgId(TranslateTree.PROGID)]
public class TranslateTree : ISchematicAlgorithm, ITranslateTree
{
// private member data
public const string GUID = "A675D260-6AF0-438d-80AB-630B3F956D05";
private const string PROGID = "ApplicativeAlgorithms.TranslateTree";
// property names (for the algorithm property set)
private const string TranslationFactorXName = "Translation Factor X";
private const string TranslationFactorYName = "Translation Factor Y";
private string m_algoLabel = "Translate Tree C#";
private bool m_available;
private bool m_overridable;
private bool m_useRootNode;
private bool m_useEndNode;
private double m_paramX;
private double m_paramY;
private ISchematicDiagramClassName m_schematicDiagramClassName;
public TranslateTree()
{
m_paramX = 50.0;
m_paramY = 50.0;
m_available = true;// In this example, the algorithm is available by default
m_overridable = true; // user is allowed to edit the parameters
m_useRootNode = false; // don't need the user to define root nodes
m_useEndNode = false; // don't need the user to define an end node
m_schematicDiagramClassName = null;
}
~TranslateTree()
{
m_schematicDiagramClassName = null;
}
#region Component Category Registration
[ComRegisterFunction()]
public static void Reg(string regKey)
{
SchematicAlgorithms.Register(regKey);
}
[ComUnregisterFunction()]
public static void Unreg(string regKey)
{
SchematicAlgorithms.Unregister(regKey);
}
#endregion
#region Implements ITranslateTree
public double TranslationFactorX
{
get
{
return m_paramX;
}
set
{
m_paramX = value;
}
}
public double TranslationFactorY
{
get
{
return m_paramY;
}
set
{
m_paramY = value;
}
}
#endregion
///////////////////////////////////////////////////////////////////////////////////////
//
// ISchematicAlgorithm interface : Defines its properties and methods (mandatory)
//
#region Implements ISchematicAlgorithm
public bool get_Enabled(ISchematicLayer schematicLayer)
{
if (schematicLayer == null)
return false;
// an algorithm needs the diagram to be in editing mode in order to run
if (!schematicLayer.IsEditingSchematicDiagram())
return false;
IEnumSchematicFeature enumFeatures = schematicLayer.GetSchematicSelectedFeatures(true);
if (enumFeatures == null)
return false;
// Count the selected nodes
int iCount = 0;
ISchematicFeature feature;
enumFeatures.Reset();
feature = enumFeatures.Next();
while (feature != null && iCount < 2)
{
ISchematicInMemoryFeatureClass inMemoryFeatureClass;
// just want SchematicFeatureNode
inMemoryFeatureClass = (ISchematicInMemoryFeatureClass)feature.Class;
if (inMemoryFeatureClass.SchematicElementClass.SchematicElementType == esriSchematicElementType.esriSchematicNodeType)
iCount++;
feature = enumFeatures.Next();
}
if (iCount == 1)
return true; // just want one selected node
else
return false;
}
public bool Available
{
get
{
return m_available;
}
set
{
m_available = value;
}
}
public bool Overridable
{
get
{
return m_overridable;
}
set
{
m_overridable = value;
}
}
public ISchematicDiagramClassName SchematicDiagramClassName
{
get
{
return m_schematicDiagramClassName;
}
set
{
m_schematicDiagramClassName = value;
}
}
public string Label
{
get
{
return m_algoLabel;
}
set
{
m_algoLabel = value;
}
}
public bool UseRootNode
{
get
{
return m_useRootNode;
}
}
public bool UseEndNode
{
get
{
return m_useEndNode;
}
}
public IPropertySet PropertySet
{
get
{
// build the property set
IPropertySet propSet = new PropertySet();
if (propSet == null)
return null;
propSet.SetProperty(TranslationFactorXName, m_paramX);
propSet.SetProperty(TranslationFactorYName, m_paramY);
return propSet;
}
set
{
IPropertySet pPropertySet = value;
if (pPropertySet != null)
{
try
{
m_paramX = (double)pPropertySet.GetProperty(TranslationFactorXName);
m_paramY = (double)pPropertySet.GetProperty(TranslationFactorYName);
}
catch { }
}
}
}
public string AlgorithmCLSID
{
get
{
//return "{" + GUID + "}"; Working as well with GUID
return PROGID;
}
}
// The execute part of the algorithm
public void Execute(ISchematicLayer schematicLayer, ITrackCancel CancelTracker)
{
if (schematicLayer == null)
return;
// Before Execute part
ISchematicDiagram schematicDiagram;
schematicDiagram = schematicLayer.SchematicDiagram;
if (schematicDiagram == null)
return;
// get the diagram spatial reference for geometry transformation
IGeoDataset geoDataset = (IGeoDataset)schematicDiagram;
if (geoDataset == null)
return;
ISpatialReference spatialReference = geoDataset.SpatialReference;
ISchematicDiagramClass diagramClass;
diagramClass = schematicDiagram.SchematicDiagramClass;
if (diagramClass == null)
return;
ISchematicDataset schemDataset;
schemDataset = diagramClass.SchematicDataset;
if (schemDataset == null)
return;
ISchematicAlgorithmEventsTrigger algorithmEventsTrigger;
algorithmEventsTrigger = (ISchematicAlgorithmEventsTrigger)schemDataset;
if (algorithmEventsTrigger == null)
return;
ESRI.ArcGIS.Carto.ILayer layer = (ESRI.ArcGIS.Carto.ILayer)schematicLayer;
ISchematicAlgorithm algorithm = (ISchematicAlgorithm)this;
bool canExecute = true;
algorithmEventsTrigger.FireBeforeExecuteAlgorithm(layer, algorithm, ref canExecute);
if (!canExecute)
return; // cannot execute
// Get the selected Features
IEnumSchematicFeature enumFeatures = schematicLayer.GetSchematicSelectedFeatures(true);
if (enumFeatures == null)
return;
// Count the selected nodes
ISchematicInMemoryFeatureClass inMemoryFeatureClass;
ISchematicFeature selectedFeature = null;
int iCount = 0;
ISchematicFeature schemFeature;
enumFeatures.Reset();
schemFeature = enumFeatures.Next();
while (schemFeature != null && iCount < 2)
{
// just want SchematicFeatureNode
inMemoryFeatureClass = (ISchematicInMemoryFeatureClass)schemFeature.Class;
if (inMemoryFeatureClass.SchematicElementClass.SchematicElementType == esriSchematicElementType.esriSchematicNodeType)
{
selectedFeature = schemFeature;
iCount++;
}
schemFeature = enumFeatures.Next();
}
if (iCount != 1 || selectedFeature == null)
return; // must be only one
// Create a new SchematicAnalystFindConnected algorithm
ISchematicAnalystFindConnected analystFindConnected = null;
analystFindConnected = (ISchematicAnalystFindConnected)new SchematicAnalystFindConnected();
if (analystFindConnected == null)
return;
// Modifying parameters value for this SchematicAnalystFindConnected algorithm so that when it is launched the trace result appears a selection set{
analystFindConnected.SelectLink = true;
analystFindConnected.SelectNode = true;
analystFindConnected.UseFlow = false;
//pAnalystFindConnected.FlowDirection = 1;
// Execute the algorithm
analystFindConnected.Execute(schematicLayer, CancelTracker);
// Retrieving the trace result (if any)
IEnumSchematicFeature resultFeatures;
resultFeatures = analystFindConnected.TraceResult;
if (resultFeatures == null || resultFeatures.Count < 1)
return;
// Apply the translation to the result
ISchematicInMemoryDiagram inMemoryDiagram;
inMemoryDiagram = schematicLayer.SchematicInMemoryDiagram;
// Translating each traced elements according to the TranslationFactorX and TranslationFactorY parameters current values
ISchematicInMemoryFeature inMemoryFeature;
resultFeatures.Reset();
while ((inMemoryFeature = (ISchematicInMemoryFeature)resultFeatures.Next()) != null)
{
IGeometry geometry;
ITransform2D transform;
esriSchematicElementType elemType;
inMemoryFeatureClass = (ISchematicInMemoryFeatureClass)inMemoryFeature.Class;
elemType = inMemoryFeatureClass.SchematicElementClass.SchematicElementType;
if (elemType == esriSchematicElementType.esriSchematicLinkType || elemType == esriSchematicElementType.esriSchematicNodeType)
{
// get a copy of the feature geometry
// then process the cloned geometry rather than the feature geometry directly
// Thus the modifications are stored in the heap of the current operation
// meaning it can be undone then redo (undo/redo)
geometry = inMemoryFeature.ShapeCopy;
// Convert the geometry into the SpatialReference of diagram class
geometry.Project(spatialReference);
// Move the geometry
transform = (ITransform2D)geometry;
if (transform != null)
{
transform.Move(m_paramX, m_paramY);
// Convert the moved geometry into the spatial reference of storage
// and feed it back to the feature
IObjectClass table = inMemoryFeature.Class;
if (table == null)
continue;
IGeoDataset featureGeoDataset = (IGeoDataset)table;
if (featureGeoDataset == null)
continue;
ISpatialReference featureSpatialRef = featureGeoDataset.SpatialReference;
if (featureSpatialRef == null)
continue;
IGeometry movedGeometry = (IGeometry)transform;
movedGeometry.Project(featureSpatialRef);
inMemoryFeature.Shape = movedGeometry;
}
}
}
// After Execute part
algorithmEventsTrigger.FireAfterExecuteAlgorithm(layer, algorithm);
// update the diagram extent
schematicLayer.UpdateExtent();
}
#endregion
}
}
[Visual Basic .NET]
TranslateTree.vb
Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.Runtime.InteropServices
Imports ESRI.ArcGIS.esriSystem
Imports ESRI.ArcGIS.ADF.CATIDs
Imports ESRI.ArcGIS.Schematic
Imports ESRI.ArcGIS.Geodatabase
Imports ESRI.ArcGIS.Geometry
<ClassInterface(ClassInterfaceType.None)> _
<Guid(TranslateTree.GUID)> _
<ProgId(TranslateTree.PROGID)> _
Public Class TranslateTree
Implements ISchematicAlgorithm
Implements ITranslateTree
' private member data
Public Const GUID As String = "F80339F6-9E87-4a75-AF8E-1B44C76D7D96"
Public Const PROGID As String = "ApplicativeAlgorithms.TranslateTreeVB"
' property names (for the algorithm property set)
Private Const TranslationFactorXName As String = "Translation Factor X"
Private Const TranslationFactorYName As String = "Translation Factor Y"
Private m_algoLabel As String = "Translate Tree VBNet"
Private m_available As Boolean
Private m_overridable As Boolean
Private m_useRootNode As Boolean
Private m_useEndNode As Boolean
Private m_paramX As Double
Private m_paramY As Double
Private m_schematicDiagramClassName As ISchematicDiagramClassName
Public Sub New()
m_paramX = 50.0
m_paramY = 50.0
m_available = True ' In this example, the algorithm is available by default
m_overridable = True ' user is allowed to edit the parameters
m_useRootNode = False ' don't need the user to define root nodes
m_useEndNode = False ' don't need the user to define an end node
m_schematicDiagramClassName = Nothing
End Sub
Protected Overrides Sub Finalize()
m_schematicDiagramClassName = Nothing
End Sub
#Region "COM Registration Function(s)"
<ComRegisterFunction()> _
<ComVisibleAttribute(True)> _
Public Shared Sub Reg(ByVal sKey As String)
SchematicAlgorithms.Register(sKey)
End Sub
<ComUnregisterFunction()> _
<ComVisibleAttribute(True)> _
Public Shared Sub Unreg(ByVal sKey As String)
SchematicAlgorithms.Unregister(sKey)
End Sub
#End Region
#Region "Implements ITranslateTree"
Public Property TranslationFactorX() As Double Implements ITranslateTree.TranslationFactorX
Get
Return m_paramX
End Get
Set(ByVal value As Double)
m_paramX = value
End Set
End Property
Public Property TranslationFactorY() As Double Implements ITranslateTree.TranslationFactorY
Get
Return m_paramY
End Get
Set(ByVal value As Double)
m_paramY = value
End Set
End Property
#End Region
#Region "Implements ISchematicAlgorithm"
Public ReadOnly Property Enabled(Optional ByVal schematicLayer As ESRI.ArcGIS.Schematic.ISchematicLayer = Nothing) As Boolean Implements ESRI.ArcGIS.Schematic.ISchematicAlgorithm.Enabled
Get
Dim enumFeatures As IEnumSchematicFeature
Dim schemFeature As ISchematicFeature
Dim iCount As Integer = 0
If (schematicLayer Is Nothing) Then Return False
' an algorithm needs the diagram to be in editing mode in order to run
If (Not schematicLayer.IsEditingSchematicDiagram()) Then Return False
enumFeatures = schematicLayer.GetSchematicSelectedFeatures(True)
If (enumFeatures Is Nothing) Then Return False
' Count the selected nodes
enumFeatures.Reset()
schemFeature = enumFeatures.Next()
While (schemFeature IsNot Nothing And iCount < 2)
Dim inMemoryFeatureClass As ISchematicInMemoryFeatureClass = Nothing
inMemoryFeatureClass = TryCast(schemFeature.Class, ISchematicInMemoryFeatureClass)
If (inMemoryFeatureClass Is Nothing) Then
schemFeature = enumFeatures.Next()
Continue While
End If
If (inMemoryFeatureClass.SchematicElementClass.SchematicElementType = esriSchematicElementType.esriSchematicNodeType) Then
iCount += 1
End If
schemFeature = enumFeatures.Next()
End While
If (iCount = 1) Then
Return True ' just want one selected node
Else
Return False
End If
End Get
End Property
Public Property Available() As Boolean Implements ISchematicAlgorithm.Available
Get
Return m_available
End Get
Set(ByVal value As Boolean)
m_available = value
End Set
End Property
' enclose the name of the property by brackets since the word is reserved (in VBNet)
Public Property [Overridable]() As Boolean Implements ISchematicAlgorithm.Overridable
Get
Return m_overridable
End Get
Set(ByVal value As Boolean)
m_overridable = value
End Set
End Property
Public Property SchematicDiagramClassName() As ISchematicDiagramClassName Implements ISchematicAlgorithm.SchematicDiagramClassName
Get
Return m_schematicDiagramClassName
End Get
Set(ByVal value As ISchematicDiagramClassName)
m_schematicDiagramClassName = value
End Set
End Property
Public Property Label() As String Implements ISchematicAlgorithm.Label
Get
Return m_algoLabel
End Get
Set(ByVal value As String)
m_algoLabel = value
End Set
End Property
Public ReadOnly Property UseRootNode() As Boolean Implements ISchematicAlgorithm.UseRootNode
Get
Return m_useRootNode
End Get
End Property
Public ReadOnly Property UseEndNode() As Boolean Implements ISchematicAlgorithm.UseEndNode
Get
Return m_useEndNode
End Get
End Property
Public Property PropertySet() As IPropertySet Implements ISchematicAlgorithm.PropertySet
Get
' build the property set
Dim builtPropertySet As New ESRI.ArcGIS.esriSystem.PropertySet
If (builtPropertySet Is Nothing) Then
Return Nothing
End If
builtPropertySet.SetProperty(TranslationFactorXName, m_paramX)
builtPropertySet.SetProperty(TranslationFactorYName, m_paramY)
Return builtPropertySet
End Get
Set(ByVal value As IPropertySet)
Dim propSet As IPropertySet = value
Dim oneParameter As Object
If (propSet IsNot Nothing) Then
Try
oneParameter = propSet.GetProperty(TranslationFactorXName)
m_paramX = CDbl(oneParameter)
oneParameter = propSet.GetProperty(TranslationFactorYName)
m_paramY = CDbl(oneParameter)
Catch ex As Exception
End Try
End If
End Set
End Property
Public ReadOnly Property AlgorithmCLSID() As String Implements ISchematicAlgorithm.AlgorithmCLSID
Get
Return "{" & GUID & "}"
End Get
End Property
Public Sub Execute(Optional ByVal schematicLayer As ESRI.ArcGIS.Schematic.ISchematicLayer = Nothing, Optional ByVal cancelTracker As ESRI.ArcGIS.esriSystem.ITrackCancel = Nothing) Implements ESRI.ArcGIS.Schematic.ISchematicAlgorithm.Execute
If (schematicLayer Is Nothing) Then Return
'''''''''''''''''''''''''''''''''''''''''''
' Before Execute part
Dim schematicDiagram As ISchematicDiagram
schematicDiagram = schematicLayer.SchematicDiagram
If (schematicDiagram Is Nothing) Then Return
' get the diagram spatial reference for geometry transformation
Dim geoDataset As IGeoDataset = CType(schematicDiagram, IGeoDataset)
If (geoDataset Is Nothing) Then Return
Dim spatialReference As ISpatialReference = geoDataset.SpatialReference
Dim diagramClass As ISchematicDiagramClass
diagramClass = schematicDiagram.SchematicDiagramClass
If (diagramClass Is Nothing) Then Return
Dim schemDataset As ISchematicDataset
schemDataset = diagramClass.SchematicDataset
If (schemDataset Is Nothing) Then Return
Dim algorithmEventsTrigger As ISchematicAlgorithmEventsTrigger
algorithmEventsTrigger = CType(schemDataset, ISchematicAlgorithmEventsTrigger)
If (algorithmEventsTrigger Is Nothing) Then Return
Dim layer As ESRI.ArcGIS.Carto.ILayer = CType(schematicLayer, ESRI.ArcGIS.Carto.ILayer)
Dim algorithm As ISchematicAlgorithm = CType(Me, ISchematicAlgorithm)
Dim canExecute As Boolean
algorithmEventsTrigger.FireBeforeExecuteAlgorithm(layer, algorithm, canExecute)
If Not canExecute Then Return ' cannot execute
' Get the selected Features
Dim enumFeatures As IEnumSchematicFeature = schematicLayer.GetSchematicSelectedFeatures(True)
If (enumFeatures Is Nothing) Then Return
' Count the selected nodes
Dim inMemoryFeatureClass As ISchematicInMemoryFeatureClass
Dim selectedFeature As ISchematicFeature = Nothing
Dim iCount As Integer = 0
Dim schemFeature As ISchematicFeature
enumFeatures.Reset()
schemFeature = enumFeatures.Next()
While (schemFeature IsNot Nothing AndAlso iCount < 2)
' just want SchematicFeatureNode
inMemoryFeatureClass = CType(schemFeature.Class, ISchematicInMemoryFeatureClass)
If (inMemoryFeatureClass.SchematicElementClass.SchematicElementType = esriSchematicElementType.esriSchematicNodeType) Then
selectedFeature = schemFeature
iCount += 1
End If
schemFeature = enumFeatures.Next()
End While
If (iCount <> 1 OrElse selectedFeature Is Nothing) Then Return ' must be only one
' Create a new SchematicAnalystFindConnected algorithm
Dim analystFindConnected As ISchematicAnalystFindConnected = Nothing
analystFindConnected = CType(New SchematicAnalystFindConnected(), ISchematicAnalystFindConnected)
If (analystFindConnected Is Nothing) Then Return
' Modifying parameters value for this SchematicAnalystFindConnected algorithm so that when it is launched the trace result appears a selection set{
analystFindConnected.SelectLink = True
analystFindConnected.SelectNode = True
analystFindConnected.UseFlow = False
'pAnalystFindConnected.FlowDirection = 1
' Execute the algorithm
analystFindConnected.Execute(schematicLayer, cancelTracker)
' Retrieving the trace result (if any)
Dim resultFeatures As IEnumSchematicFeature
resultFeatures = analystFindConnected.TraceResult
If (resultFeatures Is Nothing OrElse resultFeatures.Count < 1) Then Return
' Apply the translation to the result
Dim inMemoryDiagram As ISchematicInMemoryDiagram
inMemoryDiagram = schematicLayer.SchematicInMemoryDiagram
' Translating each traced elements according to the TranslationFactorX and TranslationFactorY parameters current values
Dim inMemoryFeature As ISchematicInMemoryFeature
resultFeatures.Reset()
inMemoryFeature = CType(resultFeatures.Next(), ISchematicInMemoryFeature)
While (inMemoryFeature IsNot Nothing)
Dim geometry As IGeometry
Dim transform As ITransform2D
Dim elemType As esriSchematicElementType
inMemoryFeatureClass = CType(inMemoryFeature.Class, ISchematicInMemoryFeatureClass)
elemType = inMemoryFeatureClass.SchematicElementClass.SchematicElementType
If (elemType = esriSchematicElementType.esriSchematicLinkType OrElse elemType = esriSchematicElementType.esriSchematicNodeType) Then
' get a copy of the feature geometry
' then process the cloned geometry rather than the feature geometry directly
' Thus the modifications are stored in the heap of the current operation
' meaning it can be undone then redo (undo/redo)
geometry = inMemoryFeature.ShapeCopy
' Convert the geometry into the SpatialReference of diagram class
geometry.Project(spatialReference)
' Move the geometry
transform = CType(geometry, ITransform2D)
If (transform IsNot Nothing) Then
transform.Move(m_paramX, m_paramY)
' Convert the moved geometry into the spatial reference of storage
' and feed it back to the feature
Dim table As IObjectClass = inMemoryFeature.Class
If (table Is Nothing) Then Continue While
Dim featureGeoDataset As IGeoDataset = CType(table, IGeoDataset)
If (featureGeoDataset Is Nothing) Then Continue While
Dim featureSpatialRef As ISpatialReference = featureGeoDataset.SpatialReference
If (featureSpatialRef Is Nothing) Then Continue While
Dim movedGeometry As IGeometry = CType(transform, IGeometry)
movedGeometry.Project(featureSpatialRef)
inMemoryFeature.Shape = movedGeometry
End If
End If
inMemoryFeature = CType(resultFeatures.Next(), ISchematicInMemoryFeature)
End While
' After Execute part
algorithmEventsTrigger.FireAfterExecuteAlgorithm(layer, algorithm)
' update the diagram extent
schematicLayer.UpdateExtent()
End Sub
#End Region
End Class
'End Namespace