ArcObjects Library Reference  

TranslateTree

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