About the Network Analyst Engine application Sample
[C#]
frmMain.cs
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.SystemUI;
using ESRI.ArcGIS.NetworkAnalyst;
using ESRI.ArcGIS.Geodatabase;
// This is the main form of the application.
namespace NAEngine
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class frmMain : System.Windows.Forms.Form
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
private System.Windows.Forms.Splitter splitter1;
// Context menu objects for NAWindow's context menu
private System.Windows.Forms.ContextMenu contextMenu1;
private System.Windows.Forms.MenuItem miLoadLocations;
private System.Windows.Forms.MenuItem miClearLocations;
private System.Windows.Forms.MenuItem miAddItem;
// ArcGIS Controls on the form
private ESRI.ArcGIS.Controls.AxMapControl axMapControl1;
private ESRI.ArcGIS.Controls.AxLicenseControl axLicenseControl1;
private ESRI.ArcGIS.Controls.AxToolbarControl axToolbarControl1;
private ESRI.ArcGIS.Controls.AxTOCControl axTOCControl1;
// Listen for context menu on NAWindow
private IEngineNAWindowEventsEx_OnContextMenuEventHandler m_onContextMenu;
// Reference to Network Analyst Environment
private IEngineNetworkAnalystEnvironment m_naEnv;
// Reference to NAWindow. Need to hold on to reference for events to work.
private IEngineNAWindow m_naWindow;
// Menu for our commands on the TOC context menu
private IToolbarMenu m_menuLayer;
// incrementor for auto generated names
private static int autogenInt = 0;
public frmMain()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose(bool disposing)
{
ESRI.ArcGIS.ADF.COMSupport.AOUninitialize.Shutdown();
if (disposing)
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmMain));
this.axMapControl1 = new ESRI.ArcGIS.Controls.AxMapControl();
this.axLicenseControl1 = new ESRI.ArcGIS.Controls.AxLicenseControl();
this.axToolbarControl1 = new ESRI.ArcGIS.Controls.AxToolbarControl();
this.splitter1 = new System.Windows.Forms.Splitter();
this.axTOCControl1 = new ESRI.ArcGIS.Controls.AxTOCControl();
this.contextMenu1 = new System.Windows.Forms.ContextMenu();
this.miLoadLocations = new System.Windows.Forms.MenuItem();
this.miClearLocations = new System.Windows.Forms.MenuItem();
this.miAddItem = new System.Windows.Forms.MenuItem();
((System.ComponentModel.ISupportInitialize)(this.axMapControl1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.axLicenseControl1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.axToolbarControl1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.axTOCControl1)).BeginInit();
this.SuspendLayout();
//
// axMapControl1
//
this.axMapControl1.Dock = System.Windows.Forms.DockStyle.Fill;
this.axMapControl1.Location = new System.Drawing.Point(227, 28);
this.axMapControl1.Name = "axMapControl1";
this.axMapControl1.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("axMapControl1.OcxState")));
this.axMapControl1.Size = new System.Drawing.Size(645, 472);
this.axMapControl1.TabIndex = 2;
//
// axLicenseControl1
//
this.axLicenseControl1.Enabled = true;
this.axLicenseControl1.Location = new System.Drawing.Point(664, 0);
this.axLicenseControl1.Name = "axLicenseControl1";
this.axLicenseControl1.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("axLicenseControl1.OcxState")));
this.axLicenseControl1.Size = new System.Drawing.Size(32, 32);
this.axLicenseControl1.TabIndex = 1;
//
// axToolbarControl1
//
this.axToolbarControl1.Dock = System.Windows.Forms.DockStyle.Top;
this.axToolbarControl1.Location = new System.Drawing.Point(0, 0);
this.axToolbarControl1.Name = "axToolbarControl1";
this.axToolbarControl1.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("axToolbarControl1.OcxState")));
this.axToolbarControl1.Size = new System.Drawing.Size(872, 28);
this.axToolbarControl1.TabIndex = 0;
//
// splitter1
//
this.splitter1.Location = new System.Drawing.Point(224, 28);
this.splitter1.Name = "splitter1";
this.splitter1.Size = new System.Drawing.Size(3, 472);
this.splitter1.TabIndex = 4;
this.splitter1.TabStop = false;
//
// axTOCControl1
//
this.axTOCControl1.Dock = System.Windows.Forms.DockStyle.Left;
this.axTOCControl1.Location = new System.Drawing.Point(0, 28);
this.axTOCControl1.Name = "axTOCControl1";
this.axTOCControl1.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("axTOCControl1.OcxState")));
this.axTOCControl1.Size = new System.Drawing.Size(224, 472);
this.axTOCControl1.TabIndex = 1;
this.axTOCControl1.OnMouseDown += new ESRI.ArcGIS.Controls.ITOCControlEvents_Ax_OnMouseDownEventHandler(this.axTOCControl1_OnMouseDown);
//
// contextMenu1
//
this.contextMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.miLoadLocations,
this.miClearLocations});
//
// miLoadLocations
//
this.miLoadLocations.Index = 0;
this.miLoadLocations.Text = "Load Locations...";
this.miLoadLocations.Click += new System.EventHandler(this.miLoadLocations_Click);
//
// miClearLocations
//
this.miClearLocations.Index = 1;
this.miClearLocations.Text = "Clear Locations";
this.miClearLocations.Click += new System.EventHandler(this.miClearLocations_Click);
//
// miAddItem
//
this.miAddItem.Index = -1;
this.miAddItem.Text = "Add Item";
this.miAddItem.Click += new System.EventHandler(this.miAddItem_Click);
//
// frmMain
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(872, 500);
this.Controls.Add(this.axLicenseControl1);
this.Controls.Add(this.axMapControl1);
this.Controls.Add(this.splitter1);
this.Controls.Add(this.axTOCControl1);
this.Controls.Add(this.axToolbarControl1);
this.Name = "frmMain";
this.Text = "Network Analyst Engine Application";
this.Load += new System.EventHandler(this.frmMain_Load);
((System.ComponentModel.ISupportInitialize)(this.axMapControl1)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.axLicenseControl1)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.axToolbarControl1)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.axTOCControl1)).EndInit();
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
if (!ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.Engine))
{
if (!ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.Desktop))
{
if (ESRI.ArcGIS.RuntimeManager.ActiveRuntime.Version == "") // "" is less than 10
{
System.Windows.Forms.MessageBox.Show("Loading ArcGIS Version Failed");
return;
}
}
}
Application.Run(new frmMain());
}
private void frmMain_Load(object sender, System.EventArgs e)
{
// Add commands to the NALayer context menu
m_menuLayer = new ToolbarMenuClass();
int nItem = -1;
m_menuLayer.AddItem(new cmdLoadLocations(), -1, ++nItem, false, esriCommandStyles.esriCommandStyleTextOnly);
m_menuLayer.AddItem(new cmdRemoveLayer(), -1, ++nItem, false, esriCommandStyles.esriCommandStyleTextOnly);
m_menuLayer.AddItem(new cmdClearAnalysisLayer(), -1, ++nItem, true, esriCommandStyles.esriCommandStyleTextOnly);
m_menuLayer.AddItem(new cmdNALayerProperties(), -1, ++nItem, true, esriCommandStyles.esriCommandStyleTextOnly);
m_menuLayer.SetHook(axMapControl1);
// Add command for Network Analyst env properties to end of "Network Analyst" dropdown menu
nItem = -1;
for (int i = 0; i < axToolbarControl1.Count; ++i)
{
IToolbarItem item = axToolbarControl1.GetItem(i);
IToolbarMenu mnu = item.Menu;
if (mnu == null)
continue;
IMenuDef mnudef = mnu.GetMenuDef();
string name = mnudef.Name;
if (name == "ControlToolsNetworkAnalyst_SolverMenu")
{
nItem = i;
break;
}
}
if (nItem >= 0)
{
IToolbarItem item = axToolbarControl1.GetItem(nItem);
IToolbarMenu mnu = item.Menu;
if (mnu != null)
mnu.AddItem(new cmdNAProperties(), -1, mnu.Count, true, esriCommandStyles.esriCommandStyleTextOnly);
}
// Initialize naEnv variables
m_naEnv = new EngineNetworkAnalystEnvironmentClass();
m_naEnv.ZoomToResultAfterSolve = false;
m_naEnv.ShowAnalysisMessagesAfterSolve = (int)(esriEngineNAMessageType.esriEngineNAMessageTypeInformative | esriEngineNAMessageType.esriEngineNAMessageTypeWarning);
// Explicitly setup buddy control and initialize NA extension
// so we can get to NAWindow to listen to window events
// This is necessary the various controls are not yet setup and they
// need to be in order to get the NAWindow's events.
axToolbarControl1.SetBuddyControl(axMapControl1);
IExtension ext = m_naEnv as IExtension;
object obj = axToolbarControl1.Object;
ext.Startup(ref obj);
m_naWindow = m_naEnv.NAWindow;
m_onContextMenu = new IEngineNAWindowEventsEx_OnContextMenuEventHandler(OnContextMenu);
((IEngineNAWindowEventsEx_Event)m_naWindow).OnContextMenu += m_onContextMenu;
}
// Show the TOC context menu when an NALayer is right-clicked on
private void axTOCControl1_OnMouseDown(object sender, ESRI.ArcGIS.Controls.ITOCControlEvents_OnMouseDownEvent e)
{
if (e.button != 2) return;
esriTOCControlItem item = esriTOCControlItem.esriTOCControlItemNone;
IBasicMap map = null;
ILayer layer = null;
object other = null;
object index = null;
//Determine what kind of item has been clicked on
axTOCControl1.HitTest(e.x, e.y, ref item, ref map, ref layer, ref other, ref index);
// Only implemented a context menu for NALayers. Exit if the layer is anything else.
if ((layer as INALayer) == null)
return;
axTOCControl1.SelectItem(layer);
// Set the layer into the CustomProperty.
// This is used by the other commands to know what layer was right-clicked on
// in the table of contents.
axMapControl1.CustomProperty = layer;
//Popup the correct context menu and update the TOC when it's done.
if (item == esriTOCControlItem.esriTOCControlItemLayer)
{
m_menuLayer.PopupMenu(e.x, e.y, axTOCControl1.hWnd);
ITOCControl toc = axTOCControl1.Object as ITOCControl;
toc.Update();
}
}
public bool OnContextMenu(int x, int y)
{
System.Drawing.Point pt = this.PointToClient(System.Windows.Forms.Cursor.Position);
//Get the active category
IEngineNAWindowCategory2 activeCategory = m_naWindow.ActiveCategory as IEngineNAWindowCategory2;
if (activeCategory == null)
return false;
MenuItem separator = new MenuItem("-");
miLoadLocations.Enabled = false;
miClearLocations.Enabled = false;
// in order for the AddItem choice to appear in the context menu, the class
// should be an input class, and it should not be editable
INAClassDefinition pNAClassDefinition = activeCategory.NAClass.ClassDefinition;
if (pNAClassDefinition.IsInput)
{
miLoadLocations.Enabled = true;
miClearLocations.Enabled = true;
// canEditShape should be false for AddItem to Apply (default is false)
// if it's a StandaloneTable canEditShape is implicitly false (there's no shape to edit)
bool canEditShape = false;
IFields pFields = pNAClassDefinition.Fields;
int nField = -1;
nField = pFields.FindField("Shape");
if (nField >= 0)
{
int naFieldType = 0;
naFieldType = pNAClassDefinition.get_FieldType("Shape");
// determining whether or not the shape field can be edited consists of running a bitwise comparison
// on the FieldType of the shape field. See the online help for a list of the possible field types.
// For our case, we want to verify that the shape field is an input field. If it is an input field,
// then we do NOT want to display the Add Item menu option.
canEditShape = ((naFieldType & (int)esriNAFieldType.esriNAFieldTypeInput) == (int)esriNAFieldType.esriNAFieldTypeInput) ? true : false;
}
if (!canEditShape)
{
contextMenu1.MenuItems.Add(separator);
contextMenu1.MenuItems.Add(miAddItem);
}
}
contextMenu1.Show(this, pt);
// even if the miAddItem menu item has not been added, Remove() won't crash.
contextMenu1.MenuItems.Remove(separator);
contextMenu1.MenuItems.Remove(miAddItem);
return true;
}
private void miLoadLocations_Click(object sender, System.EventArgs e)
{
IMapControl3 mapControl = (IMapControl3)axMapControl1.Object;
// Show the Property Page form for Network Analyst
frmLoadLocations loadLocations = new frmLoadLocations();
if (loadLocations.ShowModal(mapControl, m_naEnv))
{
// notify that the context has changed because we have added locations to a NAClass within it
INAContextEdit contextEdit = m_naEnv.NAWindow.ActiveAnalysis.Context as INAContextEdit;
contextEdit.ContextChanged();
// If loaded locations, refresh the NAWindow and the Screen
INALayer naLayer = m_naWindow.ActiveAnalysis;
mapControl.Refresh(esriViewDrawPhase.esriViewGeography, naLayer, mapControl.Extent);
m_naWindow.UpdateContent(m_naWindow.ActiveCategory);
}
}
private void miClearLocations_Click(object sender, System.EventArgs e)
{
IMapControl3 mapControl = (IMapControl3)axMapControl1.Object;
IEngineNetworkAnalystHelper naHelper = m_naEnv as IEngineNetworkAnalystHelper;
IEngineNAWindow naWindow = m_naWindow;
INALayer naLayer = naWindow.ActiveAnalysis;
// we do not have to run ContextChanged() as with adding an item and loading locations,
// because that is done by the DeleteAllNetworkLocations method.
naHelper.DeleteAllNetworkLocations();
mapControl.Refresh(esriViewDrawPhase.esriViewGeography, naLayer, mapControl.Extent);
}
private void miAddItem_Click(object sender, System.EventArgs e)
{
// Developers Note:
// Once an item has been added, the user can double click on the item to edit the properties
// of the item. For the purposes of this sample, only the default values from the InitDefaultValues method
// and an auto generated Name value are populated initially for the new item.
IMapControl3 mapControl = (IMapControl3)axMapControl1.Object;
IEngineNAWindowCategory2 activeCategory = m_naWindow.ActiveCategory as IEngineNAWindowCategory2;
IDataLayer pDataLayer = activeCategory.DataLayer;
// In order to add an item, we need to create a new row in the class and populate it
// with the initial default values for that class.
ITable table = pDataLayer as ITable;
IRow row = table.CreateRow();
IRowSubtypes rowSubtypes = row as IRowSubtypes;
rowSubtypes.InitDefaultValues();
// we need to auto generate a display name for the newly added item.
// In some cases (depending on how the schema is set up) InitDefaultValues may result in a nonempty name string
// in these cases do not override the preexisting non-empty name string with our auto generated one.
IFeatureLayer ipFeatureLayer = activeCategory.Layer as IFeatureLayer;
IStandaloneTable ipStandaloneTable = pDataLayer as IStandaloneTable;
string name = "";
if (ipFeatureLayer != null)
name = ipFeatureLayer.DisplayField;
else if (ipStandaloneTable != null)
name = ipStandaloneTable.DisplayField;
//If the display field is an empty string or does not represent an actual field on the NAClass just skip the auto generation.
// (Some custom solvers may not have set the DisplayField for example).
// Note: The name we are auto generating does not have any spaces in it. This is to ensure that any classes
// that are space sensitive will be able to handle the name (ex Specialties).
string currentName = "";
int fieldIndex = row.Fields.FindField(name);
if (fieldIndex >= 0)
{
currentName = row.get_Value(fieldIndex) as string;
if (currentName.Length <= 0)
row.set_Value(fieldIndex, "Item" + ++autogenInt);
}
// A special case is OrderPairs NAClass because that effectively has a combined 2 field display field.
// You will have to hard code to look for that NAClassName and create a default name for
// both first order and second order field names so the name will display correctly
// (look for the NAClass Name and NOT the layer name).
INAClassDefinition naClassDef = activeCategory.NAClass.ClassDefinition;
if (naClassDef.Name == "OrderPairs")
{
fieldIndex = row.Fields.FindField("SecondOrderName");
if (fieldIndex >= 0)
{
string secondName = row.get_Value(fieldIndex) as string;
if (secondName.Length <= 0)
row.set_Value(fieldIndex, "Item" + ++autogenInt);
}
}
row.Store();
// notify that the context has changed because we have added an item to a NAClass within it
INAContextEdit contextEdit = m_naEnv.NAWindow.ActiveAnalysis.Context as INAContextEdit;
contextEdit.ContextChanged();
// refresh the NAWindow and the Screen
INALayer naLayer = m_naWindow.ActiveAnalysis;
mapControl.Refresh(esriViewDrawPhase.esriViewGeography, naLayer, mapControl.Extent);
m_naWindow.UpdateContent(m_naWindow.ActiveCategory);
}
}
}
[Visual Basic .NET]
frmMain.vb
Imports Microsoft.VisualBasic
Imports System
Imports System.Drawing
Imports System.Collections
Imports System.ComponentModel
Imports System.Windows.Forms
Imports System.Data
Imports ESRI.ArcGIS.Carto
Imports ESRI.ArcGIS.Controls
Imports ESRI.ArcGIS.esriSystem
Imports ESRI.ArcGIS.SystemUI
Imports ESRI.ArcGIS.NetworkAnalyst
Imports ESRI.ArcGIS.Geodatabase
' This is the main form of the application.
Namespace NAEngine
''' <summary>
''' Summary description for Form1.
''' </summary>
Public Class frmMain : Inherits System.Windows.Forms.Form
''' <summary>
''' Required designer variable.
''' </summary>
Private components As System.ComponentModel.Container = Nothing
Private splitter1 As System.Windows.Forms.Splitter
' Context menu objects for NAWindow's context menu
Private contextMenu1 As System.Windows.Forms.ContextMenu
Private WithEvents miLoadLocations As System.Windows.Forms.MenuItem
Private WithEvents miClearLocations As System.Windows.Forms.MenuItem
Private WithEvents miAddItem As System.Windows.Forms.MenuItem
' ArcGIS Controls on the form
Private axMapControl1 As ESRI.ArcGIS.Controls.AxMapControl
Private axLicenseControl1 As ESRI.ArcGIS.Controls.AxLicenseControl
Private axToolbarControl1 As ESRI.ArcGIS.Controls.AxToolbarControl
Private WithEvents axTOCControl1 As ESRI.ArcGIS.Controls.AxTOCControl
' Listen for context menu on NAWindow
Private m_onContextMenu As IEngineNAWindowEventsEx_OnContextMenuEventHandler
' Reference to Network Analyst Environment
Private m_naEnv As IEngineNetworkAnalystEnvironment
' Reference to NAWindow. Need to hold on to reference for events to work.
Private m_naWindow As IEngineNAWindow
' Menu for our commands on the TOC context menu
Private m_menuLayer As IToolbarMenu
' integer to use for auto generated names
Private autogenInt As Integer
Public Sub New()
'
' Required for Windows Form Designer support
'
InitializeComponent()
End Sub
''' <summary>
''' Clean up any resources being used.
''' </summary>
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
'Release COM objects
ESRI.ArcGIS.ADF.COMSupport.AOUninitialize.Shutdown()
If disposing Then
If Not components Is Nothing Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
#Region "Windows Form Designer generated code"
''' <summary>
''' Required method for Designer support - do not modify
''' the contents of this method with the code editor.
''' </summary>
Private Sub InitializeComponent()
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(frmMain))
Me.axMapControl1 = New ESRI.ArcGIS.Controls.AxMapControl
Me.axLicenseControl1 = New ESRI.ArcGIS.Controls.AxLicenseControl
Me.axToolbarControl1 = New ESRI.ArcGIS.Controls.AxToolbarControl
Me.splitter1 = New System.Windows.Forms.Splitter
Me.axTOCControl1 = New ESRI.ArcGIS.Controls.AxTOCControl
Me.contextMenu1 = New System.Windows.Forms.ContextMenu
Me.miLoadLocations = New System.Windows.Forms.MenuItem
Me.miClearLocations = New System.Windows.Forms.MenuItem
Me.miAddItem = New System.Windows.Forms.MenuItem
CType(Me.axMapControl1, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.axLicenseControl1, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.axToolbarControl1, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.axTOCControl1, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'axMapControl1
'
Me.axMapControl1.Dock = System.Windows.Forms.DockStyle.Fill
Me.axMapControl1.Location = New System.Drawing.Point(227, 28)
Me.axMapControl1.Name = "axMapControl1"
Me.axMapControl1.OcxState = CType(resources.GetObject("axMapControl1.OcxState"), System.Windows.Forms.AxHost.State)
Me.axMapControl1.Size = New System.Drawing.Size(645, 472)
Me.axMapControl1.TabIndex = 2
'
'axLicenseControl1
'
Me.axLicenseControl1.Enabled = True
Me.axLicenseControl1.Location = New System.Drawing.Point(664, 0)
Me.axLicenseControl1.Name = "axLicenseControl1"
Me.axLicenseControl1.OcxState = CType(resources.GetObject("axLicenseControl1.OcxState"), System.Windows.Forms.AxHost.State)
Me.axLicenseControl1.Size = New System.Drawing.Size(32, 32)
Me.axLicenseControl1.TabIndex = 1
'
'axToolbarControl1
'
Me.axToolbarControl1.Dock = System.Windows.Forms.DockStyle.Top
Me.axToolbarControl1.Location = New System.Drawing.Point(0, 0)
Me.axToolbarControl1.Name = "axToolbarControl1"
Me.axToolbarControl1.OcxState = CType(resources.GetObject("axToolbarControl1.OcxState"), System.Windows.Forms.AxHost.State)
Me.axToolbarControl1.Size = New System.Drawing.Size(872, 28)
Me.axToolbarControl1.TabIndex = 0
'
'splitter1
'
Me.splitter1.Location = New System.Drawing.Point(224, 28)
Me.splitter1.Name = "splitter1"
Me.splitter1.Size = New System.Drawing.Size(3, 472)
Me.splitter1.TabIndex = 4
Me.splitter1.TabStop = False
'
'axTOCControl1
'
Me.axTOCControl1.Dock = System.Windows.Forms.DockStyle.Left
Me.axTOCControl1.Location = New System.Drawing.Point(0, 28)
Me.axTOCControl1.Name = "axTOCControl1"
Me.axTOCControl1.OcxState = CType(resources.GetObject("axTOCControl1.OcxState"), System.Windows.Forms.AxHost.State)
Me.axTOCControl1.Size = New System.Drawing.Size(224, 472)
Me.axTOCControl1.TabIndex = 1
'
'contextMenu1
'
Me.contextMenu1.MenuItems.AddRange(New System.Windows.Forms.MenuItem() {Me.miLoadLocations, Me.miClearLocations})
'
'miLoadLocations
'
Me.miLoadLocations.Index = 0
Me.miLoadLocations.Text = "Load Locations..."
'
'miClearLocations
'
Me.miClearLocations.Index = 1
Me.miClearLocations.Text = "Clear Locations"
'
'miAddItem
'
Me.miAddItem.Index = -1
Me.miAddItem.Text = "Add Item"
'
'frmMain
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(872, 500)
Me.Controls.Add(Me.axLicenseControl1)
Me.Controls.Add(Me.axMapControl1)
Me.Controls.Add(Me.splitter1)
Me.Controls.Add(Me.axTOCControl1)
Me.Controls.Add(Me.axToolbarControl1)
Me.Name = "frmMain"
Me.Text = "Network Analyst Engine Application"
CType(Me.axMapControl1, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.axLicenseControl1, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.axToolbarControl1, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.axTOCControl1, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
End Sub
#End Region
''' <summary>
''' The main entry point for the application.
''' </summary>
<STAThread()> _
Shared Sub Main()
If (ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.Engine) Or _
ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.Desktop)) Then
Application.Run(New frmMain())
Else
If (ESRI.ArcGIS.RuntimeManager.ActiveRuntime.Version = "") Then ' "" is less than 10
System.Windows.Forms.MessageBox.Show("Loading ArcGIS Version Failed")
End If
End If
End Sub
Private Sub frmMain_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
' Add commands to the NALayer context menu
m_menuLayer = New ToolbarMenuClass()
Dim nItem As Integer = -1
m_menuLayer.AddItem(New LoadLocations(), -1, ++nItem, False, esriCommandStyles.esriCommandStyleTextOnly)
m_menuLayer.AddItem(New RemoveLayer(), -1, ++nItem, False, esriCommandStyles.esriCommandStyleTextOnly)
m_menuLayer.AddItem(New ClearAnalysisLayer(), -1, ++nItem, True, esriCommandStyles.esriCommandStyleTextOnly)
m_menuLayer.AddItem(New NALayerProperties(), -1, ++nItem, True, esriCommandStyles.esriCommandStyleTextOnly)
m_menuLayer.SetHook(axMapControl1)
For i As Integer = 0 To axToolbarControl1.Count - 1
Dim item As IToolbarItem = axToolbarControl1.GetItem(i)
Dim mnu As IToolbarMenu = item.Menu
If mnu Is Nothing Then
Continue For
End If
Dim mnudef As IMenuDef = mnu.GetMenuDef()
Dim name As String = mnudef.Name
If name = "ControlToolsNetworkAnalyst_SolverMenu" Then
nItem = i
Exit For
End If
Next
If nItem >= 0 Then
Dim item As IToolbarItem = axToolbarControl1.GetItem(nItem)
Dim mnu As IToolbarMenu = item.Menu
If mnu IsNot Nothing Then
mnu.AddItem(New NAProperties(), -1, mnu.Count, True, esriCommandStyles.esriCommandStyleTextOnly)
End If
End If
' Initialize naEnv variables
m_naEnv = New EngineNetworkAnalystEnvironmentClass()
m_naEnv.ZoomToResultAfterSolve = False
m_naEnv.ShowAnalysisMessagesAfterSolve = CInt(esriEngineNAMessageType.esriEngineNAMessageTypeInformative Or esriEngineNAMessageType.esriEngineNAMessageTypeWarning)
' Explicitly setup buddy control and initialize NA extension
' so we can get to NAWindow to listen to window events
' This is necessary the various controls are not yet setup and they
' need to be in order to get the NAWindow's events.
axToolbarControl1.SetBuddyControl(axMapControl1)
Dim ext As IExtension = TryCast(m_naEnv, IExtension)
Dim obj As Object = axToolbarControl1.Object
ext.Startup(obj)
m_naWindow = m_naEnv.NAWindow
m_onContextMenu = New IEngineNAWindowEventsEx_OnContextMenuEventHandler(AddressOf OnContextMenu)
AddHandler CType(m_naWindow, IEngineNAWindowEventsEx_Event).OnContextMenu, m_onContextMenu
End Sub
' Show the TOC context menu when an NALayer is right-clicked on
Private Sub axTOCControl1_OnMouseDown(ByVal sender As Object, ByVal e As ESRI.ArcGIS.Controls.ITOCControlEvents_OnMouseDownEvent) Handles axTOCControl1.OnMouseDown
If e.button <> 2 Then
Return
End If
Dim item As esriTOCControlItem = esriTOCControlItem.esriTOCControlItemNone
Dim map As IBasicMap = Nothing
Dim layer As ILayer = Nothing
Dim other As Object = Nothing
Dim index As Object = Nothing
'Determine what kind of item has been clicked on
axTOCControl1.HitTest(e.x, e.y, item, map, layer, other, index)
' Only implemented a context menu for NALayers. Exit if the layer is anything else.
If (TryCast(layer, INALayer)) Is Nothing Then
Return
End If
axTOCControl1.SelectItem(layer)
' Set the layer into the CustomProperty.
' This is used by the other commands to know what layer was right-clicked on
' in the table of contents.
axMapControl1.CustomProperty = layer
'Popup the correct context menu and update the TOC when it's done.
If item = esriTOCControlItem.esriTOCControlItemLayer Then
m_menuLayer.PopupMenu(e.x,e.y,axTOCControl1.hWnd)
Dim toc As ITOCControl = TryCast(axTOCControl1.Object, ITOCControl)
toc.Update()
End If
End Sub
Public Function OnContextMenu(ByVal x As Integer, ByVal y As Integer) As Boolean
Dim pt As System.Drawing.Point = Me.PointToClient(System.Windows.Forms.Cursor.Position)
' Get the active category
Dim activeCategory As IEngineNAWindowCategory2 = TryCast(m_naWindow.ActiveCategory, IEngineNAWindowCategory2)
If (activeCategory Is Nothing) Then
Return False
End If
Dim separator As MenuItem = New MenuItem("-")
miLoadLocations.Enabled = False
miClearLocations.Enabled = False
' in order for the AddItem choice to appear in the context menu, the class
' should be an input class, and it should not be editable
Dim pNAClassDefinition As INAClassDefinition = activeCategory.NAClass.ClassDefinition
If (pNAClassDefinition.IsInput) Then
miLoadLocations.Enabled = True
miClearLocations.Enabled = True
' canEditShape should be false for AddItem to Apply (default is false)
' if it's a StandaloneTable canEditShape is implicitly false (there's no shape to edit)
Dim canEditShape As Boolean = False
Dim pFields As IFields = pNAClassDefinition.Fields
Dim nfield As Integer = -1
nfield = pFields.FindField("Shape")
If (nfield >= 0) Then
Dim naFieldtype As Integer = 0
naFieldtype = pNAClassDefinition.FieldType("Shape")
' determining whether or not the shape field can be edited consists of running a bitwise comparison
' on the FieldType of the shape field. See the online help for a list of the possible field types.
' For our case, we want to verify that the shape field is an input field. If it is an input field,
' then we do NOT want to display the Add Item menu option.
Dim bitwiseAnd As Integer = (naFieldtype And esriNAFieldType.esriNAFieldTypeInput)
If (bitwiseAnd = esriNAFieldType.esriNAFieldTypeInput) Then
canEditShape = True
End If
End If
If (Not canEditShape) Then
contextMenu1.MenuItems.Add(separator)
contextMenu1.MenuItems.Add(miAddItem)
End If
End If
contextMenu1.Show(Me, pt)
' even if the miAddItem menu item has not been added, Remove() won't crash.
contextMenu1.MenuItems.Remove(separator)
contextMenu1.MenuItems.Remove(miAddItem)
Return True
End Function
Private Sub miLoadLocations_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles miLoadLocations.Click
Dim mapControl As IMapControl3 = CType(axMapControl1.Object, IMapControl3)
' Show the Property Page form for Network Analyst
Dim dlgLoadLocations As frmLoadLocations = New frmLoadLocations()
If dlgLoadLocations.ShowModal(mapControl, m_naEnv) Then
' If loaded locations, refresh the NAWindow and the Screen
Dim naLayer As INALayer = m_naWindow.ActiveAnalysis
' notify that the context has changed because we have added locations to a NAClass within it
Dim contextEdit As INAContextEdit = TryCast(m_naEnv.NAWindow.ActiveAnalysis.Context, INAContextEdit)
contextEdit.ContextChanged()
mapControl.Refresh(esriViewDrawPhase.esriViewGeography, naLayer, mapControl.Extent)
m_naWindow.UpdateContent(m_naWindow.ActiveCategory)
End If
End Sub
Private Sub miClearLocations_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles miClearLocations.Click
Dim mapControl As IMapControl3 = CType(axMapControl1.Object, IMapControl3)
Dim naHelper As IEngineNetworkAnalystHelper = TryCast(m_naEnv, IEngineNetworkAnalystHelper)
Dim naWindow As IEngineNAWindow = m_naWindow
Dim naLayer As INALayer = naWindow.ActiveAnalysis
' we do not have to run ContextChanged() as with adding an item and loading locations,
' because that is done by the DeleteAllNetworkLocations method.
naHelper.DeleteAllNetworkLocations()
mapControl.Refresh(esriViewDrawPhase.esriViewGeography, naLayer, mapControl.Extent)
End Sub
Private Sub miAddItem_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles miAddItem.Click
' Developers Note:
' Once an item has been added, the user can double click on the item to edit the properties
' of the item. For the purposes of this sample, only the default values from the InitDefaultValues method
' and an auto generated Name value are populated initially for the new item.
Dim mapControl As IMapControl3 = CType(axMapControl1.Object, IMapControl3)
Dim activeCategory As IEngineNAWindowCategory2 = CType(m_naWindow.ActiveCategory, IEngineNAWindowCategory2)
Dim pDataLayer As IDataLayer = activeCategory.DataLayer
' In order to add an item, we need to create a new row in the class and populate it
' with the initial default values for that class.
Dim table As ITable = CType(pDataLayer, ITable)
Dim row As IRow = table.CreateRow()
Dim rowSubtypes As IRowSubtypes = CType(row, IRowSubtypes)
rowSubtypes.InitDefaultValues()
' we need to auto generate a display name for the newly added item.
' In some cases (depending on how the schema is set up) InitDefaultValues may result in a nonempty name string
' in these cases do not override the preexisting non-empty name string with our auto generated one.
Dim ipFeatureLayer As IFeatureLayer = TryCast(activeCategory.Layer, IFeatureLayer)
Dim ipStandaloneTable As IStandaloneTable = TryCast(pDataLayer, IStandaloneTable)
Dim name As String = ""
If Not ipFeatureLayer Is Nothing Then
name = ipFeatureLayer.DisplayField
ElseIf Not ipStandaloneTable Is Nothing Then
name = ipStandaloneTable.DisplayField
End If
' If the display field is an empty string or does not represent an actual field on the NAClass just skip the auto generation.
' (Some custom solvers may not have set the DisplayField for example).
' Note: The name we are auto generating does not have any spaces in it. This is to ensure that that any classes
' that are space sensitive will be able to handle the name (ex Specialties).
Dim currentName As String = ""
Dim fieldIndex As Integer = row.Fields.FindField(name)
If (fieldIndex >= 0) Then
currentName = CType(row.Value(fieldIndex), String)
If (currentName.Length <= 0) Then
autogenInt += 1
row.Value(fieldIndex) = "Item" & autogenInt
End If
End If
' A special case is OrderPairs NAClass because that effectively has a combined 2 field display field.
' You will have to hard code to look for that NAClassName and create a default name for
' both first order and second order field names so the name will display correctly
' (look for the NAClass Name and NOT the layer name).
Dim naClassDef As INAClassDefinition = activeCategory.NAClass.ClassDefinition
If (naClassDef.Name = "OrderPairs") Then
fieldIndex = row.Fields.FindField("SecondOrderName")
If (fieldIndex >= 0) Then
Dim secondName As String = CType(row.Value(fieldIndex), String)
If (secondName.Length <= 0) Then
autogenInt += 1
row.Value(fieldIndex) = "Item" & autogenInt
End If
End If
End If
row.Store()
' notify that the context has changed because we have added an item to a NAClass within it
Dim contextEdit As INAContextEdit = CType(m_naEnv.NAWindow.ActiveAnalysis.Context, INAContextEdit)
contextEdit.ContextChanged()
' refresh the NAWindow and the Screen
Dim naLayer As INALayer = m_naWindow.ActiveAnalysis
mapControl.Refresh(esriViewDrawPhase.esriViewGeography, naLayer, mapControl.Extent)
m_naWindow.UpdateContent(m_naWindow.ActiveCategory)
End Sub
End Class
End Namespace