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