About the Utility wizard for basic schematic datasets configuration Sample
[C#]
GenerateSchematicTemplate.cs
// Copyright 2010 ESRI
//
// All rights reserved under the copyright laws of the United States
// and applicable international laws, treaties, and conventions.
//
// You may freely redistribute and use this sample code, with or
// without modification, provided you include the original copyright
// notice and use restrictions.
//
// See the use restrictions at <your ArcGIS install location>/DeveloperKit10.0/userestrictions.txt.
// namespace SchematicCreateBasicSettingsAddIn
using System;
using System.Collections.Generic;
using System.Collections;
using System.Collections.Specialized;
using System.Text;
using System.IO;
using ESRI.ArcGIS.Schematic;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.ArcCatalogUI;
using ESRI.ArcGIS.ArcCatalog;
using ESRI.ArcGIS.Catalog;
using ESRI.ArcGIS.CatalogUI;
using ESRI.ArcGIS.ArcMap;
using ESRI.ArcGIS.ArcMapUI;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.NetworkAnalysis;
using System.Windows.Forms;
using ESRI.ArcGIS.esriSystem;
namespace SchematicCreateBasicSettingsAddIn
{
public class GenerateSchematicTemplate : ESRI.ArcGIS.Desktop.AddIns.Button
{
#region Variables
public frmDatasetTemplateName formNames;
ESRI.ArcGIS.Geodatabase.IWorkspace m_pWS;
String m_sfn;
ESRI.ArcGIS.Schematic.ISchematicBuilder m_pB;
ESRI.ArcGIS.Schematic.ISchematicDataset m_pSDS;
ESRI.ArcGIS.Schematic.ISchematicStandardBuilder m_pSB;
ESRI.ArcGIS.Schematic.ISchematicDiagramClass m_pSDT;
ESRI.ArcGIS.Schematic.ISchematicDatasetImport m_pSDI;
NameEvents templateInfo;
public frmSelectItemsToReduce formReduce;
private bool blnCancel;
public frmAdvanced formAdvanced;
private string strLayers;
private string strNodeLayers;
NameValueCollection m_myCol = new NameValueCollection();
private IGxObject m_SelectedObject = null;
#endregion Attributes
public GenerateSchematicTemplate()
{
}
private IEnumLayer GetLayers()
{
//now get the map document to parse out the feature classes
GxDialog pGxDialog = new GxDialogClass();
IEnumGxObject pEnumGxObject;
bool pResult;
pGxDialog.ObjectFilter = new GxFilterMapsClass();
pGxDialog.Title = "Select a map document";
try
{
pResult = pGxDialog.DoModalOpen(0, out pEnumGxObject);
//check to see if the user canceled the dialog
if (pResult == false) return null;
IGxObject pGxObject = pEnumGxObject.Next();
IMapReader pMapReader = new MapReaderClass();
pMapReader.Open(pGxObject.FullName.ToString());
IMap pMap = pMapReader.get_Map(0);
ESRI.ArcGIS.esriSystem.UID pUID = new ESRI.ArcGIS.esriSystem.UIDClass();
pUID.Value = "{40A9E885-5533-11D0-98BE-00805F7CED21}"; //feature layer
IEnumLayer pLayers = pMap.get_Layers(pUID, true);
return pLayers;
}
catch
{
//error getting layers
return null;
}
}
private Dictionary<string, IFeatureClass> ProcessFCs(IEnumFeatureClass fcComplexEdge, IEnumFeatureClass fcComplexNode, IEnumFeatureClass fcSimpleEdge, IEnumFeatureClass fcSimpleNode)
{
Dictionary<string, IFeatureClass> pDictionary = new Dictionary<string, IFeatureClass>();
//handle complex edge
IFeatureClass fc = fcComplexEdge.Next();
if (fc != null)
{
do
{
try
{
pDictionary.Add(fc.AliasName, fc);
}
catch
{
//do nothing
}
fc = fcComplexEdge.Next();
} while (fc != null);
}
//handle complex node
fc = fcComplexNode.Next();
if (fc != null)
{
do
{
try
{
pDictionary.Add(fc.AliasName, fc);
}
catch
{
//do nothing
}
fc = fcComplexNode.Next();
} while (fc != null);
}
//handle simple edge
fc = fcSimpleEdge.Next();
if (fc != null)
{
do
{
try
{
pDictionary.Add(fc.AliasName, fc);
}
catch
{
//do nothing
}
fc = fcSimpleEdge.Next();
} while (fc != null);
}
//handle simple node
fc = fcSimpleNode.Next();
if (fc != null)
{
do
{
try
{
pDictionary.Add(fc.AliasName, fc);
}
catch
{
//do nothing
}
fc = fcSimpleNode.Next();
} while (fc != null);
}
return pDictionary;
}
private string CreateSchLayers(IEnumLayer pLayers)
{
if (pLayers == null) return "";
ILayer pLayer = pLayers.Next();
IFeatureLayer featureLayer;
IFeatureClass featureClass;
string pStrLayerNames = "";
IDataset pDataset;
System.Windows.Forms.Cursor.Current = Cursors.WaitCursor;
System.Windows.Forms.Cursor.Show();
m_pSDS.DesignMode = true;
m_pSDI = (ESRI.ArcGIS.Schematic.ISchematicDatasetImport)m_pSDS;
Dictionary<string, IFeatureClass> myDictionary = new Dictionary<string, IFeatureClass>();
IGeometricNetwork gn = null;
do
{
featureLayer = (IFeatureLayer)pLayer;
featureClass = featureLayer.FeatureClass;
pDataset = (IDataset)featureClass;
if (featureClass.FeatureType == esriFeatureType.esriFTSimpleJunction || featureClass.FeatureType == esriFeatureType.esriFTSimpleEdge || featureClass.FeatureType == esriFeatureType.esriFTComplexEdge || featureClass.FeatureType == esriFeatureType.esriFTComplexJunction)
{
//The FeatureType property of feature classes that implement this interface will be esriFTSimpleJunction, esriDTSimpleEdge, esriFTComplexJunction, or esriFTComplexEdge.
INetworkClass networkClass = (INetworkClass)featureLayer.FeatureClass;
if (networkClass.GeometricNetwork != null)
{
//we have a network class
if ((gn == null) || (gn != networkClass.GeometricNetwork))
{
//need to process all the classes
Dictionary<string, IFeatureClass> localDictionary = new Dictionary<string, IFeatureClass>();
gn = networkClass.GeometricNetwork;
IEnumFeatureClass fcComplexEdge = networkClass.GeometricNetwork.get_ClassesByType(esriFeatureType.esriFTComplexEdge);
IEnumFeatureClass fcComplexNode = networkClass.GeometricNetwork.get_ClassesByType(esriFeatureType.esriFTComplexJunction);
IEnumFeatureClass fcSimpleEdge = networkClass.GeometricNetwork.get_ClassesByType(esriFeatureType.esriFTSimpleEdge);
IEnumFeatureClass fcSimpleNode = networkClass.GeometricNetwork.get_ClassesByType(esriFeatureType.esriFTSimpleJunction);
localDictionary = ProcessFCs(fcComplexEdge, fcComplexNode, fcSimpleEdge, fcSimpleNode);
if (myDictionary.Count == 0) //just copy it
{
myDictionary = localDictionary;
}
else //merge
{
Dictionary<string, IFeatureClass>.KeyCollection keyColl = localDictionary.Keys;
foreach (string s in keyColl)
{
IFeatureClass fc;
bool bln = localDictionary.TryGetValue(s, out fc);
myDictionary.Add(s, fc);
}
}
}
//Build up the string that will go to the select items to reduce form
pStrLayerNames += pDataset.Name.ToString();
pStrLayerNames += ";";
//Build up the string for just the node feature classes
if (featureClass.FeatureType == esriFeatureType.esriFTSimpleJunction || featureClass.FeatureType == esriFeatureType.esriFTComplexJunction)
{
strNodeLayers += pDataset.Name.ToString();
strNodeLayers += ";";
}
//create the fields collections to be used by the frmAdvanced form
IFields pFields = featureClass.Fields;
if (pFields.FieldCount > 0)
{
for (int i = 0; i < pFields.FieldCount; i++)
{
//don't mess with objectid or shape or GlobalID
if ((pFields.get_Field(i).Name.ToString() != "OBJECTID") && (pFields.get_Field(i).Name.ToString() != "SHAPE") && (pFields.get_Field(i).Name.ToString() != "GlobalID") && (pFields.get_Field(i).Name.ToString() != featureClass.OIDFieldName.ToString()) && (pFields.get_Field(i).Name.ToString() != featureClass.ShapeFieldName.ToString()))
{
m_myCol.Add(pDataset.Name.ToString(), pFields.get_Field(i).Name.ToString());
}
}
}
//remove the layer from the list of dictionary classes
if (myDictionary.ContainsKey(featureClass.AliasName))
{
myDictionary.Remove(featureClass.AliasName);
}
m_pSDI.ImportFeatureLayer(featureLayer, m_pSDT, true, true, true);
}
}
pLayer = pLayers.Next();
} while (pLayer != null);
//handle any feature classes that were not in the map
if (myDictionary.Count > 0)
{
Dictionary<string, IFeatureClass>.KeyCollection keyColl = myDictionary.Keys;
foreach (string s in keyColl)
{
IFeatureClass fc;
bool bln = myDictionary.TryGetValue(s, out fc);
IObjectClass o = (IObjectClass)fc;
pDataset = (IDataset)fc;
pStrLayerNames += pDataset.Name.ToString();
pStrLayerNames += ";";
//Build up the string for just the node feature classes
if (fc.FeatureType == esriFeatureType.esriFTSimpleJunction || featureClass.FeatureType == esriFeatureType.esriFTComplexJunction)
{
strNodeLayers += pDataset.Name.ToString();
strNodeLayers += ";";
}
//create the fields collections to be used by the frmAdvanced form
IFields pFields = fc.Fields;
if (pFields.FieldCount > 0)
{
for (int i = 0; i < pFields.FieldCount; i++)
{
//don't mess with objectid or shape or GlobalID
if ((pFields.get_Field(i).Name.ToString() != "OBJECTID") && (pFields.get_Field(i).Name.ToString() != "SHAPE") && (pFields.get_Field(i).Name.ToString() != "GlobalID") && (pFields.get_Field(i).Name.ToString() != fc.OIDFieldName.ToString()) && (pFields.get_Field(i).Name.ToString() != fc.ShapeFieldName.ToString()))
{
m_myCol.Add(pDataset.Name.ToString(), pFields.get_Field(i).Name.ToString());
}
}
}
if ((fc.FeatureType == esriFeatureType.esriFTComplexJunction) || (fc.FeatureType == esriFeatureType.esriFTSimpleJunction))
{
//node
m_pSDI.ImportObjectClass(o, m_pSDT, true, esriSchematicElementType.esriSchematicNodeType);
}
else
{
//link
m_pSDI.ImportObjectClass(o, m_pSDT, true, esriSchematicElementType.esriSchematicLinkType);
}
}
}
m_pSDS.Save(ESRI.ArcGIS.esriSystem.esriArcGISVersion.esriArcGISVersionCurrent, true);
m_pSDS.DesignMode = false;
return pStrLayerNames;
}
protected override void OnClick()
{
blnCancel = false;
formNames = new frmDatasetTemplateName();
formNames.cancelFormEvent += new EventHandler(formNames_cancelFormEvent);
formNames.nextFormEvent += new EventHandler<NameEvents>(formNames_nextFormEvent);
m_SelectedObject = ArcCatalog.ThisApplication.SelectedObject;
if ((m_SelectedObject.Category == "Schematic Dataset")
|| (m_SelectedObject.Category.ToLower().Contains("database")))
{
if (m_SelectedObject.Category.ToLower().Contains("database"))
{
//get dataset and template names, then create the objects
formNames.blnNewDataset = true;
}
else
{
//dataset, just get template names, then create objects
formNames.blnNewDataset = false;
}
//show the first form of the wizard
if (formNames.ShowDialog() == DialogResult.Cancel)
{
formNames = null;
return;
}
}
else
{
//we are not on a database or a schematic dataset
blnCancel = true;
}
if (blnCancel == true)
{
System.Windows.Forms.MessageBox.Show("The name of the dataset or template already exists. Please try again with valid names.");
}
if (blnCancel != true) //only true if the user cancels the first form formNames_cancelFormEvent
{
System.Windows.Forms.Cursor.Current = Cursors.WaitCursor;
IEnumLayer pEnumLayer = GetLayers();
if (pEnumLayer == null)
{
//should only happen if the user clicks cancel on the gxdialog
blnCancel = true;
}
else
{
strLayers = CreateSchLayers(pEnumLayer);
if (strLayers.Length > 0) //make sure we get something back
{
//find out if we need to create node reduction rules
formReduce = new frmSelectItemsToReduce();
formReduce.doneFormEvent += new EventHandler<ReduceEvents>(formReduce_doneFormEvent);
formReduce.cancelFormEvent += new EventHandler(formReduce_cancelFormEvent);
formReduce.itemList = strNodeLayers;
System.Windows.Forms.Cursor.Current = Cursors.Default;
formReduce.ShowDialog();
}
else
{
//this can happen if the map document didn't have any
//layers corresponding to a geometric network
blnCancel = true;
}
}
System.Windows.Forms.Cursor.Current = Cursors.Default;
}
if (blnCancel != true) //could have cancelled on either frmDatasetTemplateName or frmSelectItemsToReduce
{
//Advanced Form
formAdvanced = new frmAdvanced();
formAdvanced.doneFormEvent += new EventHandler<AdvancedEvents>(formAdvanced_doneFormEvent);
formAdvanced.strLayers = this.strLayers;
formAdvanced.strNodeLayers = this.strNodeLayers;
formAdvanced.m_myCol = this.m_myCol;
formAdvanced.ShowDialog();
}
ArcCatalog.ThisApplication.Refresh(m_sfn);
try
{
ArcCatalog.ThisApplication.Location = m_SelectedObject.FullName.ToString();
}
catch { }
cleanUp();
}
void formReduce_cancelFormEvent(object sender, EventArgs e)
{
blnCancel = true;
formReduce.Close();
}
void formAdvanced_doneFormEvent(object sender, AdvancedEvents e)
{
m_pSDS.DesignMode = true;
formAdvanced.Cursor = System.Windows.Forms.Cursors.WaitCursor;
//process the algorithm if there is one
if (e.AlgorithmName != "")
{
ISchematicAlgoSmartTree a = new SchematicAlgoSmartTreeClass();
if (e.AlgorithmParams.Count > 0)
{
Dictionary<string, string>.KeyCollection keys = e.AlgorithmParams.Keys;
string strValue = "";
foreach (string s in keys)
{
if (s == "Direction")
{
e.AlgorithmParams.TryGetValue(s, out strValue);
if (strValue == "Top to Bottom")
{
a.Direction = esriSchematicAlgoDirection.esriSchematicAlgoTopDown;
}
else if (strValue == "Bottom to Top")
{
a.Direction = esriSchematicAlgoDirection.esriSchematicAlgoBottomUp;
}
else if (strValue == "Left to Right")
{
a.Direction = esriSchematicAlgoDirection.esriSchematicAlgoLeftRight;
}
else
{
a.Direction = esriSchematicAlgoDirection.esriSchematicAlgoRightLeft;
}
}
}
if (e.RootClass != "")
{
ISchematicElementClassContainer pECC = (ISchematicElementClassContainer)m_pSDS;
ISchematicElementClass pEC = pECC.GetSchematicElementClass(e.RootClass);
ESRI.ArcGIS.esriSystem.UID u = new ESRI.ArcGIS.esriSystem.UID();
u.Value = "{3AD9D8B8-0A1D-4F32-ABB5-54B848A46F85}";
ISchematicAttributeConstant pAttrConst = (ISchematicAttributeConstant)pEC.CreateSchematicAttribute("RootFlag", u);
ISchematicAttributeManagement pAttrMgmt = (ISchematicAttributeManagement)pAttrConst;
pAttrMgmt.StorageMode = esriSchematicAttributeStorageMode.esriSchematicAttributeFieldStorage;
pAttrConst.ConstantValue = "-1";
}
}
m_pSDT.SchematicAlgorithm = (ISchematicAlgorithm)a;
}
//check to see if we need to add associated fields
if (e.FieldsToCreate != null)
{
if (e.FieldsToCreate.Count > 0)
{
ISchematicElementClassContainer pECC = (ISchematicElementClassContainer)m_pSDS;
//create the associated field attributes
string[] keys = e.FieldsToCreate.AllKeys;
foreach (string s in keys)
{
//get the feature class
ISchematicElementClass pEC = pECC.GetSchematicElementClass(s);
if (pEC != null)
{
string strName = "";
string[] values = e.FieldsToCreate.GetValues(s);
foreach (string v in values)
{
//create the field
ESRI.ArcGIS.esriSystem.UID u = new ESRI.ArcGIS.esriSystem.UID();
u.Value = "{7DE3A19D-32D0-41CD-B896-37CA3AFBD88A}";
IClass pClass = (IClass)pEC;
//only handle names that don't already exist in the schematic tables
if (pClass.FindField(v) == -1)
{
strName = v.ToString();
ISchematicAttributeAssociatedField pFieldAttr = (ISchematicAttributeAssociatedField)pEC.CreateSchematicAttribute(strName, u);
pFieldAttr.AssociatedFieldName = v;
ISchematicAttributeManagement pAttrMgmt = (ISchematicAttributeManagement)pFieldAttr;
pAttrMgmt.StorageMode = esriSchematicAttributeStorageMode.esriSchematicAttributeFieldStorage;
}
}
}
}
}
}
m_pSDS.Save(ESRI.ArcGIS.esriSystem.esriArcGISVersion.esriArcGISVersionCurrent, true);
m_pSDS.DesignMode = false;
formAdvanced.Cursor = System.Windows.Forms.Cursors.Default;
formAdvanced.Close();
}
private Boolean CreateTemplate(NameEvents templateInfo)
{
//need to get everything first
IGxDatabase pDatabase = null;
ISchematicDiagramClassContainer pDiagramClassContainer = null;
if (m_SelectedObject.Category == "Schematic Dataset")
{
pDatabase = (IGxDatabase)m_SelectedObject.Parent;
}
else //on the database already
{
pDatabase = (IGxDatabase)m_SelectedObject;
}
m_pWS = pDatabase.Workspace;
ESRI.ArcGIS.Schematic.ISchematicWorkspaceFactory pSWF = new SchematicWorkspaceFactory();
ESRI.ArcGIS.Schematic.ISchematicWorkspace pSW = pSWF.Open(m_pWS);
m_pSDS = pSW.get_SchematicDatasetByName(templateInfo.DatasetName);
//check to see if the template name already exists
pDiagramClassContainer = (ISchematicDiagramClassContainer)m_pSDS;
m_pSDT = pDiagramClassContainer.GetSchematicDiagramClass(templateInfo.TemplateName.ToString());
if (m_pSDT != null) return false;
//create the schematic template
m_pSDT = m_pSDS.CreateSchematicDiagramClass(templateInfo.TemplateName);
if ((templateInfo.AutoCreate == true) || (templateInfo.UseVertices == true))
{
m_pB = (ESRI.ArcGIS.Schematic.ISchematicBuilder)m_pSDT;
m_pSB = (ESRI.ArcGIS.Schematic.ISchematicStandardBuilder)m_pSDT.SchematicBuilder;
m_pSB.InitializeLinksVertices = templateInfo.UseVertices;
m_pSB.AutoCreateElementClasses = templateInfo.AutoCreate;
}
m_pSDS.Save(ESRI.ArcGIS.esriSystem.esriArcGISVersion.esriArcGISVersion10, false);
return true;
}
private Boolean CreateDataset(NameEvents templateInfo)
{
try
{
IGxDatabase pDatabase = (IGxDatabase)m_SelectedObject;
m_pWS = pDatabase.Workspace;
ESRI.ArcGIS.Schematic.ISchematicWorkspaceFactory pSWF = new SchematicWorkspaceFactory();
ESRI.ArcGIS.Schematic.ISchematicWorkspace pSW = pSWF.Open(m_pWS);
//check to see if this dataset name is already used
m_pSDS = pSW.get_SchematicDatasetByName(templateInfo.DatasetName.ToString());
if (m_pSDS != null) return false;
m_pSDS = pSW.CreateSchematicDataset(templateInfo.DatasetName, "");
return true;
}
catch
{
//nothing
return false;
}
}
void formNames_cancelFormEvent(object sender, EventArgs e)
{
//user is canceling the wizard
formNames.Close();
formNames = null;
blnCancel = true;
}
void formReduce_doneFormEvent(object sender, ReduceEvents e)
{
//user click the done button on the reduce form
ISchematicBuilderRule pIsbr;
ISchematicBuilderRuleContainer pIsbrc = (ISchematicBuilderRuleContainer)m_pSDT;
ISchematicBuilderRuleContainerEdit pIsbrce = (ISchematicBuilderRuleContainerEdit)pIsbrc;
formReduce.Cursor = System.Windows.Forms.Cursors.WaitCursor;
string[] selectedItems = e.SelectedObjects;
m_pSDS.DesignMode = true;
foreach (string s in selectedItems)
{
//setup rule properties
ISchematicNodeReductionRuleByPriority pRule = new SchematicNodeReductionRuleByPriorityClass();
pRule.NodeDegreeConstraint = true;
pRule.ReduceNodeDegree0 = true;
pRule.ReduceNodeDegree2 = true;
pRule.ReduceNodeDegree1 = false;
pRule.ReduceNodeDegreeSup3 = false;
//set the name and class to reduce
ISchematicNodeReductionRule pNR = (ISchematicNodeReductionRule)pRule;
pNR.Description = "Remove " + s.ToString();
pNR.NodeClassName = s.ToString();
//add it to the template
pIsbr = pIsbrce.AddSchematicBuilderRule();
pIsbr.SchematicRule = (ISchematicRule)pRule;
}
//save and close
m_pSDS.Save(ESRI.ArcGIS.esriSystem.esriArcGISVersion.esriArcGISVersion10, false);
m_pSDS.DesignMode = false;
formReduce.Cursor = System.Windows.Forms.Cursors.Default;
formReduce.Close();
}
void formNames_nextFormEvent(object sender, NameEvents e)
{
Boolean blnCheck = false;
//check if we need to create a new dataset
templateInfo = new NameEvents(e.NewDataset, e.DatasetName, e.TemplateName, e.UseVertices);
formNames.Cursor = System.Windows.Forms.Cursors.WaitCursor;
if (templateInfo.NewDataset == true)
{
blnCheck = CreateDataset(templateInfo);
if (blnCheck == false)
{
//name already exists
blnCancel = true;
}
else
{
blnCheck = CreateTemplate(templateInfo);
if (blnCheck == false)
{
//name already exists
blnCancel = true;
}
}
}
else //just create a new template
{
blnCheck = CreateTemplate(templateInfo);
if (blnCheck == false)
{
//name already exists
blnCancel = true;
}
}
formNames.Cursor = System.Windows.Forms.Cursors.Default;
formNames.Close();
}
protected override void OnUpdate()
{
Enabled = ArcCatalog.Application != null;
if ((ArcCatalog.ThisApplication.SelectedObject.Category == "File Geodatabase")
|| (ArcCatalog.ThisApplication.SelectedObject.Category == "Personal Geodatabase")
|| (ArcCatalog.ThisApplication.SelectedObject.Category == "Schematic Dataset")
|| (ArcCatalog.ThisApplication.SelectedObject.Category == "Spatial Database Connection"))
{
Enabled = true;
}
else
{
Enabled = false;
}
}
void cleanUp()
{
//m_pWSF = null;
m_pWS = null;
m_pSDT = null;
m_pSDS = null;
m_pSB = null;
m_pB = null;
m_SelectedObject = null;
templateInfo = null;
m_pSDI = null;
formNames = null;
formReduce = null;
m_sfn = "";
blnCancel = false;
strLayers = "";
strNodeLayers = "";
}
}
}
[Visual Basic .NET]
GenerateSchematicTemplate.vb
' Copyright 2010 ESRI
'
' All rights reserved under the copyright laws of the United States
' and applicable international laws, treaties, and conventions.
'
' You may freely redistribute and use this sample code, with or
' without modification, provided you include the original copyright
' notice and use restrictions.
'
' See the use restrictions at <your ArcGIS install location>/DeveloperKit10.0/userestrictions.txt.
'Namespace SchematicCreateBasicSettingsAddIn
Imports System.Collections.Generic
Imports System.Collections
Imports System.Collections.Specialized
Imports System.Text
Imports System.IO
Imports ESRI.ArcGIS.Schematic
Imports ESRI.ArcGIS.Geodatabase
Imports ESRI.ArcGIS.ArcCatalog
Imports ESRI.ArcGIS.Catalog
Imports ESRI.ArcGIS.CatalogUI
Imports ESRI.ArcGIS.Carto
Imports System.Windows.Forms
Public Class GenerateSchematicTemplate
Inherits ESRI.ArcGIS.Desktop.AddIns.Button
#Region "Variables"
Public formNames As frmDatasetTemplateName
Private m_pWS As ESRI.ArcGIS.Geodatabase.IWorkspace
Private m_sfn As String
Private m_pB As ESRI.ArcGIS.Schematic.ISchematicBuilder
Private m_pSDS As ESRI.ArcGIS.Schematic.ISchematicDataset
Private m_pSB As ESRI.ArcGIS.Schematic.ISchematicStandardBuilder
Private m_pSDT As ESRI.ArcGIS.Schematic.ISchematicDiagramClass
Private m_pSDI As ESRI.ArcGIS.Schematic.ISchematicDatasetImport
Private templateInfo As NameEvents
Public formReduce As frmSelectItemsToReduce
Private blnCancel As Boolean
Public formAdvanced As frmAdvanced
Private strLayers As String
Private strNodeLayers As String
Private m_myCol As New NameValueCollection()
Private m_SelectedObject As IGxObject = Nothing
#End Region
Public Sub New()
End Sub
Private Function GetLayers() As IEnumLayer
'now get the map document to parse out the feature classes
Dim pGxDialog As GxDialog = New GxDialogClass()
Dim pEnumGxObject As IEnumGxObject = Nothing
Dim pResult As Boolean
pGxDialog.ObjectFilter = New GxFilterMapsClass()
pGxDialog.Title = "Select a map document"
Try
pResult = pGxDialog.DoModalOpen(0, pEnumGxObject)
'check to see if the user canceled the dialog
If pResult = False Then
Return Nothing
End If
Dim pGxObject As IGxObject = pEnumGxObject.Next()
Dim pMapReader As IMapReader = New MapReaderClass()
pMapReader.Open(pGxObject.FullName.ToString())
Dim pMap As IMap = pMapReader.Map(0)
Dim pUID As ESRI.ArcGIS.esriSystem.UID = New ESRI.ArcGIS.esriSystem.UIDClass()
pUID.Value = "{40A9E885-5533-11D0-98BE-00805F7CED21}"
'feature layer
Dim pLayers As IEnumLayer = pMap.Layers(pUID, True)
Return pLayers
Catch
'error getting layers
Return Nothing
End Try
End Function
Private Function ProcessFCs(ByVal fcComplexEdge As IEnumFeatureClass, ByVal fcComplexNode As IEnumFeatureClass, ByVal fcSimpleEdge As IEnumFeatureClass, ByVal fcSimpleNode As IEnumFeatureClass) As Dictionary(Of String, IFeatureClass)
Dim pDictionary As New Dictionary(Of String, IFeatureClass)()
'handle complex edge
Dim fc As IFeatureClass = fcComplexEdge.Next()
If fc IsNot Nothing Then
Do
Try
pDictionary.Add(fc.AliasName, fc)
'do nothing
Catch
End Try
fc = fcComplexEdge.Next()
Loop While fc IsNot Nothing
End If
'handle complex node
fc = fcComplexNode.Next()
If fc IsNot Nothing Then
Do
Try
pDictionary.Add(fc.AliasName, fc)
'do nothing
Catch
End Try
fc = fcComplexNode.Next()
Loop While fc IsNot Nothing
End If
'handle simple edge
fc = fcSimpleEdge.Next()
If fc IsNot Nothing Then
Do
Try
pDictionary.Add(fc.AliasName, fc)
'do nothing
Catch
End Try
fc = fcSimpleEdge.Next()
Loop While fc IsNot Nothing
End If
'handle simple node
fc = fcSimpleNode.Next()
If fc IsNot Nothing Then
Do
Try
pDictionary.Add(fc.AliasName, fc)
'do nothing
Catch
End Try
fc = fcSimpleNode.Next()
Loop While fc IsNot Nothing
End If
Return pDictionary
End Function
Private Function CreateSchLayers(ByVal pLayers As IEnumLayer) As String
If pLayers Is Nothing Then
Return ""
End If
pLayers.Reset()
Dim pLayer As ILayer = pLayers.Next()
Dim featureLayer As IFeatureLayer
Dim featureClass As IFeatureClass
Dim pStrLayerNames As String = ""
Dim pDataset As IDataset
System.Windows.Forms.Cursor.Current = Cursors.WaitCursor
System.Windows.Forms.Cursor.Show()
m_pSDS.DesignMode = True
m_pSDI = DirectCast(m_pSDS, ESRI.ArcGIS.Schematic.ISchematicDatasetImport)
Dim myDictionary As New Dictionary(Of String, IFeatureClass)()
Dim gn As IGeometricNetwork = Nothing
Do
featureLayer = DirectCast(pLayer, IFeatureLayer)
featureClass = featureLayer.FeatureClass
pDataset = DirectCast(featureClass, IDataset)
If featureClass.FeatureType = esriFeatureType.esriFTSimpleJunction OrElse featureClass.FeatureType = esriFeatureType.esriFTSimpleEdge OrElse featureClass.FeatureType = esriFeatureType.esriFTComplexEdge OrElse featureClass.FeatureType = esriFeatureType.esriFTComplexJunction Then
'The FeatureType property of feature classes that implement this interface will be esriFTSimpleJunction, esriDTSimpleEdge, esriFTComplexJunction, or esriFTComplexEdge.
Dim networkClass As INetworkClass = DirectCast(featureLayer.FeatureClass, INetworkClass)
If networkClass.GeometricNetwork IsNot Nothing Then
'we have a network class
If (gn Is Nothing) OrElse (gn IsNot networkClass.GeometricNetwork) Then
'need to process all the classes
Dim localDictionary As New Dictionary(Of String, IFeatureClass)()
gn = networkClass.GeometricNetwork
Dim fcComplexEdge As IEnumFeatureClass = networkClass.GeometricNetwork.ClassesByType(esriFeatureType.esriFTComplexEdge)
Dim fcComplexNode As IEnumFeatureClass = networkClass.GeometricNetwork.ClassesByType(esriFeatureType.esriFTComplexJunction)
Dim fcSimpleEdge As IEnumFeatureClass = networkClass.GeometricNetwork.ClassesByType(esriFeatureType.esriFTSimpleEdge)
Dim fcSimpleNode As IEnumFeatureClass = networkClass.GeometricNetwork.ClassesByType(esriFeatureType.esriFTSimpleJunction)
localDictionary = ProcessFCs(fcComplexEdge, fcComplexNode, fcSimpleEdge, fcSimpleNode)
If myDictionary.Count = 0 Then
'just copy it
myDictionary = localDictionary
Else
'merge
Dim keyColl As Dictionary(Of String, IFeatureClass).KeyCollection = localDictionary.Keys
For Each s As String In keyColl
Dim fc As IFeatureClass = Nothing
Dim bln As Boolean = localDictionary.TryGetValue(s, fc)
myDictionary.Add(s, fc)
Next
End If
End If
'Build up the string that will go to the select items to reduce form
pStrLayerNames += pDataset.Name.ToString()
pStrLayerNames += ";"
'Build up the string for just the node feature classes
If featureClass.FeatureType = esriFeatureType.esriFTSimpleJunction Or featureClass.FeatureType = esriFeatureType.esriFTComplexJunction Then
strNodeLayers += pDataset.Name.ToString()
strNodeLayers += ";"
End If
'create the fields collections to be used by the frmAdvanced form
Dim pFields As IFields = featureClass.Fields
If pFields.FieldCount > 0 Then
For i As Integer = 0 To pFields.FieldCount - 1
'don't mess with objectid or shape or GlobalID
Dim name As String = pFields.Field(i).Name.ToString()
If (name <> "OBJECTID") AndAlso (name <> "SHAPE") AndAlso (name <> "GlobalID") AndAlso (name <> featureClass.OIDFieldName.ToString()) AndAlso (name <> featureClass.ShapeFieldName.ToString()) Then
m_myCol.Add(pDataset.Name.ToString(), pFields.Field(i).Name.ToString())
End If
Next
End If
'remove the layer from the list of dictionary classes
If myDictionary.ContainsKey(featureClass.AliasName) Then
myDictionary.Remove(featureClass.AliasName)
End If
m_pSDI.ImportFeatureLayer(featureLayer, m_pSDT, True, True, True)
End If
End If
pLayer = pLayers.Next()
Loop While pLayer IsNot Nothing
'handle any feature classes that were not in the map
If myDictionary.Count > 0 Then
Dim keyColl As Dictionary(Of String, IFeatureClass).KeyCollection = myDictionary.Keys
For Each s As String In keyColl
Dim fc As IFeatureClass = Nothing
Dim bln As Boolean = myDictionary.TryGetValue(s, fc)
Dim o As IObjectClass = DirectCast(fc, IObjectClass)
pDataset = DirectCast(fc, IDataset)
pStrLayerNames += pDataset.Name.ToString()
pStrLayerNames += ";"
'Build up the string for just the node feature classes
If featureClass.FeatureType = esriFeatureType.esriFTSimpleJunction Or featureClass.FeatureType = esriFeatureType.esriFTComplexJunction Then
strNodeLayers += pDataset.Name.ToString()
strNodeLayers += ";"
End If
'create the fields collections to be used by the frmAdvanced form
Dim pFields As IFields = fc.Fields
If pFields.FieldCount > 0 Then
For i As Integer = 0 To pFields.FieldCount - 1
'don't mess with objectid or shape or GlobalID
Dim name As String = pFields.Field(i).Name.ToString()
If (name <> "OBJECTID") AndAlso (name <> "SHAPE") AndAlso (name <> "GlobalID") AndAlso (name <> fc.OIDFieldName.ToString()) AndAlso (name <> fc.ShapeFieldName.ToString()) Then
m_myCol.Add(pDataset.Name.ToString(), pFields.Field(i).Name.ToString())
End If
Next
End If
If (fc.FeatureType = esriFeatureType.esriFTComplexJunction) OrElse (fc.FeatureType = esriFeatureType.esriFTSimpleJunction) Then
'node
m_pSDI.ImportObjectClass(o, m_pSDT, True, esriSchematicElementType.esriSchematicNodeType)
Else
'link
m_pSDI.ImportObjectClass(o, m_pSDT, True, esriSchematicElementType.esriSchematicLinkType)
End If
Next
End If
m_pSDS.Save(ESRI.ArcGIS.esriSystem.esriArcGISVersion.esriArcGISVersionCurrent, True)
m_pSDS.DesignMode = False
Return pStrLayerNames
End Function
Protected Overrides Sub OnClick()
blnCancel = False
formNames = New frmDatasetTemplateName()
AddHandler formNames.cancelFormEvent, AddressOf formNames_cancelFormEvent
AddHandler formNames.nextFormEvent, AddressOf formNames_nextFormEvent
m_SelectedObject = ArcCatalog.ThisApplication.SelectedObject
If (m_SelectedObject.Category = "Schematic Dataset") OrElse (m_SelectedObject.Category.ToLower().Contains("database")) Then
If m_SelectedObject.Category.ToLower().Contains("database") Then
'get dataset and template names, then create the objects
formNames.blnNewDataset = True
Else
'dataset, just get template names, then create objects
formNames.blnNewDataset = False
End If
'show the first form of the wizard
If formNames.ShowDialog() = DialogResult.Cancel Then
formNames = Nothing
Return
End If
Else
'we are not on a database or a schematic dataset
blnCancel = True
End If
If blnCancel = True Then
System.Windows.Forms.MessageBox.Show("The name of the dataset or template already exists. Please try again with valid names.")
End If
If blnCancel <> True Then
'only true if the user cancels the first form formNames_cancelFormEvent
System.Windows.Forms.Cursor.Current = Cursors.WaitCursor
strLayers = CreateSchLayers(GetLayers())
If strLayers.Length > 0 Then
'make sure we get something back
'find out if we need to create node reduction rules
formReduce = New frmSelectItemsToReduce()
AddHandler formReduce.doneFormEvent, AddressOf formReduce_doneFormEvent
AddHandler formReduce.cancelFormEvent, AddressOf formReduce_cancelFormEvent
formReduce.itemList = strNodeLayers
System.Windows.Forms.Cursor.Current = Cursors.Default
formReduce.ShowDialog()
Else
'this can happen if the map document didn't have any
'layers corresponding to a geometric network
blnCancel = True
End If
System.Windows.Forms.Cursor.Current = Cursors.Default
End If
If blnCancel <> True Then
'could have cancelled on either frmDatasetTemplateName or frmSelectItemsToReduce
'Advanced Form
formAdvanced = New frmAdvanced()
AddHandler formAdvanced.doneFormEvent, AddressOf formAdvanced_doneFormEvent
formAdvanced.strLayers = Me.strLayers
formAdvanced.strNodeLayers = Me.strNodeLayers
formAdvanced.m_myCol = Me.m_myCol
formAdvanced.ShowDialog()
End If
Try
ArcCatalog.ThisApplication.Refresh(m_sfn)
ArcCatalog.ThisApplication.Location = m_SelectedObject.FullName.ToString()
Catch
End Try
cleanUp()
End Sub
Private Sub formReduce_cancelFormEvent(ByVal sender As Object, ByVal e As EventArgs)
blnCancel = True
formReduce.Close()
End Sub
Private Sub formAdvanced_doneFormEvent(ByVal sender As Object, ByVal e As AdvancedEvents)
m_pSDS.DesignMode = True
formAdvanced.Cursor = System.Windows.Forms.Cursors.WaitCursor
'process the algorithm if there is one
If e.AlgorithmName <> "" Then
Dim a As ISchematicAlgoSmartTree = New SchematicAlgoSmartTreeClass()
If e.AlgorithmParams.Count > 0 Then
Dim keys As Dictionary(Of String, String).KeyCollection = e.AlgorithmParams.Keys
Dim strValue As String = ""
For Each s As String In keys
If s = "Direction" Then
e.AlgorithmParams.TryGetValue(s, strValue)
If strValue = "Top to Bottom" Then
a.Direction = esriSchematicAlgoDirection.esriSchematicAlgoTopDown
ElseIf strValue = "Bottom to Top" Then
a.Direction = esriSchematicAlgoDirection.esriSchematicAlgoBottomUp
ElseIf strValue = "Left to Right" Then
a.Direction = esriSchematicAlgoDirection.esriSchematicAlgoLeftRight
Else
a.Direction = esriSchematicAlgoDirection.esriSchematicAlgoRightLeft
End If
End If
Next
If e.RootClass <> "" Then
Dim pECC As ISchematicElementClassContainer = DirectCast(m_pSDS, ISchematicElementClassContainer)
Dim pEC As ISchematicElementClass = pECC.GetSchematicElementClass(e.RootClass)
Dim u As New ESRI.ArcGIS.esriSystem.UID()
u.Value = "{3AD9D8B8-0A1D-4F32-ABB5-54B848A46F85}"
Dim pAttrConst As ISchematicAttributeConstant = DirectCast(pEC.CreateSchematicAttribute("RootFlag", u), ISchematicAttributeConstant)
Dim pAttrMgmt As ISchematicAttributeManagement = DirectCast(pAttrConst, ISchematicAttributeManagement)
pAttrMgmt.StorageMode = esriSchematicAttributeStorageMode.esriSchematicAttributeFieldStorage
pAttrConst.ConstantValue = "-1"
End If
End If
m_pSDT.SchematicAlgorithm = DirectCast(a, ISchematicAlgorithm)
End If
'check to see if we need to add associated fields
If e.FieldsToCreate IsNot Nothing Then
If e.FieldsToCreate.Count > 0 Then
Dim pECC As ISchematicElementClassContainer = DirectCast(m_pSDS, ISchematicElementClassContainer)
'create the associated field attributes
Dim keys As String() = e.FieldsToCreate.AllKeys
For Each s As String In keys
'get the feature class
Dim pEC As ISchematicElementClass = pECC.GetSchematicElementClass(s)
If pEC IsNot Nothing Then
Dim strName As String = ""
Dim values As String() = e.FieldsToCreate.GetValues(s)
For Each v As String In values
'create the field
Dim u As New ESRI.ArcGIS.esriSystem.UID()
u.Value = "{7DE3A19D-32D0-41CD-B896-37CA3AFBD88A}"
Dim pClass As IClass = DirectCast(pEC, IClass)
If pClass.FindField(v) <> -1 Then
'name exists
strName = "RF" & v.ToString()
Else
strName = v.ToString()
End If
Dim pFieldAttr As ISchematicAttributeAssociatedField = DirectCast(pEC.CreateSchematicAttribute(strName, u), ISchematicAttributeAssociatedField)
pFieldAttr.AssociatedFieldName = v
Dim pAttrMgmt As ISchematicAttributeManagement = DirectCast(pFieldAttr, ISchematicAttributeManagement)
pAttrMgmt.StorageMode = esriSchematicAttributeStorageMode.esriSchematicAttributeFieldStorage
Next
End If
Next
End If
End If
m_pSDS.Save(ESRI.ArcGIS.esriSystem.esriArcGISVersion.esriArcGISVersionCurrent, True)
m_pSDS.DesignMode = False
formAdvanced.Cursor = System.Windows.Forms.Cursors.Default
formAdvanced.Close()
End Sub
Private Function CreateTemplate(ByVal templateInfo As NameEvents) As Boolean
'need to get everything first
Dim pDatabase As IGxDatabase = Nothing
If m_SelectedObject.Category = "Schematic Dataset" Then
pDatabase = DirectCast(m_SelectedObject.Parent, IGxDatabase)
Else
'on the database already
pDatabase = DirectCast(m_SelectedObject, IGxDatabase)
End If
m_pWS = pDatabase.Workspace
Dim pSWF As ESRI.ArcGIS.Schematic.ISchematicWorkspaceFactory = New SchematicWorkspaceFactory()
Dim pSW As ESRI.ArcGIS.Schematic.ISchematicWorkspace = pSWF.Open(m_pWS)
m_pSDS = pSW.SchematicDatasetByName(templateInfo.DatasetName)
Dim pDCContainer As ISchematicDiagramClassContainer = m_pSDS
m_pSDT = pDCContainer.GetSchematicDiagramClass(templateInfo.TemplateName.ToString())
If m_pSDT IsNot Nothing Then
'name already exists
Return False
End If
'create the schematic template
m_pSDT = m_pSDS.CreateSchematicDiagramClass(templateInfo.TemplateName)
If (templateInfo.UseVertices = True) Then
m_pB = DirectCast(m_pSDT, ESRI.ArcGIS.Schematic.ISchematicBuilder)
m_pSB = DirectCast(m_pSDT.SchematicBuilder, ESRI.ArcGIS.Schematic.ISchematicStandardBuilder)
m_pSB.InitializeLinksVertices = templateInfo.UseVertices
End If
m_pSDS.Save(ESRI.ArcGIS.esriSystem.esriArcGISVersion.esriArcGISVersion10, False)
Return True
End Function
Private Function CreateDataset(ByVal templateInfo As NameEvents) As Boolean
Try
Dim pDatabase As IGxDatabase = DirectCast(m_SelectedObject, IGxDatabase)
m_pWS = pDatabase.Workspace
Dim pSWF As ESRI.ArcGIS.Schematic.ISchematicWorkspaceFactory = New SchematicWorkspaceFactory()
Dim pSW As ESRI.ArcGIS.Schematic.ISchematicWorkspace = pSWF.Open(m_pWS)
m_pSDS = pSW.SchematicDatasetByName(templateInfo.DatasetName.ToString())
If m_pSDS IsNot Nothing Then
'name exists
Return False
End If
m_pSDS = pSW.CreateSchematicDataset(templateInfo.DatasetName, "")
Return True
Catch 'ex As Exception
Return False
End Try
End Function
Private Sub formNames_cancelFormEvent(ByVal sender As Object, ByVal e As EventArgs)
'user is canceling the wizard
formNames.Close()
formNames = Nothing
blnCancel = True
End Sub
Private Sub formReduce_doneFormEvent(ByVal sender As Object, ByVal e As ReduceEvents)
'user click the done button on the reduce form
Dim pIsbr As ISchematicBuilderRule
Dim pIsbrc As ISchematicBuilderRuleContainer = DirectCast(m_pSDT, ISchematicBuilderRuleContainer)
Dim pIsbrce As ISchematicBuilderRuleContainerEdit = DirectCast(pIsbrc, ISchematicBuilderRuleContainerEdit)
formReduce.Cursor = System.Windows.Forms.Cursors.WaitCursor
Dim selectedItems As String() = e.SelectedObjects
m_pSDS.DesignMode = True
For Each s As String In selectedItems
'setup rule properties
Dim pRule As ISchematicNodeReductionRuleByPriority = New SchematicNodeReductionRuleByPriorityClass()
pRule.NodeDegreeConstraint = True
pRule.ReduceNodeDegree0 = True
pRule.ReduceNodeDegree2 = True
pRule.ReduceNodeDegree1 = False
pRule.ReduceNodeDegreeSup3 = False
'set the name and class to reduce
Dim pNR As ISchematicNodeReductionRule = DirectCast(pRule, ISchematicNodeReductionRule)
pNR.Description = "Remove " & s.ToString()
pNR.NodeClassName = s.ToString()
'add it to the template
pIsbr = pIsbrce.AddSchematicBuilderRule()
pIsbr.SchematicRule = DirectCast(pRule, ISchematicRule)
Next
'save and close
m_pSDS.Save(ESRI.ArcGIS.esriSystem.esriArcGISVersion.esriArcGISVersion10, False)
m_pSDS.DesignMode = False
formReduce.Cursor = System.Windows.Forms.Cursors.Default
formReduce.Close()
End Sub
Private Sub formNames_nextFormEvent(ByVal sender As Object, ByVal e As NameEvents)
Dim blnCheck As Boolean = False
'check if we need to create a new dataset
templateInfo = New NameEvents(e.NewDataset, e.DatasetName, e.TemplateName, e.UseVertices)
formNames.Cursor = System.Windows.Forms.Cursors.WaitCursor
If templateInfo.NewDataset = True Then
blnCheck = CreateDataset(templateInfo)
If blnCheck = False Then
'name exists
blnCancel = True
End If
blnCheck = CreateTemplate(templateInfo)
If blnCheck = False Then
'name exists
blnCancel = True
End If
Else
'just create a new template
blnCheck = CreateTemplate(templateInfo)
If blnCheck = False Then
'name exists
blnCancel = True
End If
End If
formNames.Cursor = System.Windows.Forms.Cursors.Default
formNames.Close()
End Sub
Protected Overrides Sub OnUpdate()
'Enabled = ArcCatalog.Application IsNot Nothing
Enabled = ArcCatalog.Application IsNot Nothing
'If (ArcCatalog.ThisApplication.SelectedObject.Category = "File Geodatabase") OrElse (ArcCatalog.ThisApplication.SelectedObject.Category = "Personal Geodatabase") OrElse (ArcCatalog.ThisApplication.SelectedObject.Category = "Schematic Dataset") OrElse (ArcCatalog.ThisApplication.SelectedObject.Category = "Spatial Database Connection") Then
If (ArcCatalog.ThisApplication.SelectedObject.Category = "File Geodatabase") OrElse (ArcCatalog.ThisApplication.SelectedObject.Category = "Personal Geodatabase") OrElse (ArcCatalog.ThisApplication.SelectedObject.Category = "Schematic Dataset") OrElse (ArcCatalog.ThisApplication.SelectedObject.Category = "Spatial Database Connection") Then
Enabled = True
Else
Enabled = False
End If
End Sub
Private Sub cleanUp()
m_pWS = Nothing
m_pSDT = Nothing
m_pSDS = Nothing
m_pSB = Nothing
m_pB = Nothing
m_SelectedObject = Nothing
templateInfo = Nothing
m_pSDI = Nothing
formNames = Nothing
formReduce = Nothing
m_sfn = ""
blnCancel = False
strNodeLayers = ""
strLayers = ""
End Sub
End Class