Program.cs
// Copyright 2012 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. // using System; using System.Windows.Forms; using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.Display; using ESRI.ArcGIS.esriSystem; using ESRI.ArcGIS.Geodatabase; using ESRI.ArcGIS.NetworkAnalyst; namespace RouteLayer { /// <summary> /// Main class that checks out the appropriate ArcGIS license and calls RouteClass.SolveRoute to perform the analysis /// </summary> class Program { private static LicenseInitializer m_AOLicenseInitializer; static void Main(string[] args) { if (!ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.Engine)) { if (!ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.Desktop)) { System.Console.WriteLine("This application could not load the correct version of ArcGIS."); return; } } m_AOLicenseInitializer = new LicenseInitializer(); //ESRI License Initializer generated code. if (!m_AOLicenseInitializer.InitializeApplication(new esriLicenseProductCode[] { esriLicenseProductCode.esriLicenseProductCodeBasic, esriLicenseProductCode.esriLicenseProductCodeStandard, esriLicenseProductCode.esriLicenseProductCodeAdvanced }, new esriLicenseExtensionCode[] { esriLicenseExtensionCode.esriLicenseExtensionCodeNetwork })) { System.Console.WriteLine(m_AOLicenseInitializer.LicenseMessage()); System.Console.WriteLine("This application could not initialize with the correct ArcGIS license and will shutdown."); m_AOLicenseInitializer.ShutdownApplication(); return; } RouteClass routeClass = new RouteClass(); routeClass.SolveRoute(); //ESRI License Initializer generated code. //Do not make any call to ArcObjects after ShutDownApplication() m_AOLicenseInitializer.ShutdownApplication(); } } /// <summary> /// The RouteClass class is the workhorse class that does the analysis and writes it to disk /// </summary> public class RouteClass { private const String FGDB_WORKSPACE = @"\..\..\..\..\..\Data\SanFrancisco\SanFrancisco.gdb"; private const String INPUT_STOPS_FC = "Stores"; private const String INPUT_NAME_FIELD = "Name"; private const String FEATURE_DATASET = "Transportation"; private const String NETWORK_DATASET = "Streets_ND"; /// <summary> /// Create the analysis layer, load the locations, solve the analysis, and write to disk /// </summary> public void SolveRoute() { // Open the feature workspace, input feature class, and network dataset // As Workspace Factories are Singleton objects, they must be instantiated with the Activator IWorkspaceFactory workspaceFactory = System.Activator.CreateInstance(System.Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory")) as IWorkspaceFactory; IFeatureWorkspace featureWorkspace = workspaceFactory.OpenFromFile(Application.StartupPath + FGDB_WORKSPACE, 0) as IFeatureWorkspace; IFeatureClass inputStopsFClass = featureWorkspace.OpenFeatureClass(INPUT_STOPS_FC); // Obtain the dataset container from the workspace ESRI.ArcGIS.Geodatabase.IFeatureDataset featureDataset = featureWorkspace.OpenFeatureDataset(FEATURE_DATASET); var featureDatasetExtensionContainer = featureDataset as ESRI.ArcGIS.Geodatabase.IFeatureDatasetExtensionContainer; ESRI.ArcGIS.Geodatabase.IFeatureDatasetExtension featureDatasetExtension = featureDatasetExtensionContainer.FindExtension(ESRI.ArcGIS.Geodatabase.esriDatasetType.esriDTNetworkDataset); var datasetContainer3 = featureDatasetExtension as ESRI.ArcGIS.Geodatabase.IDatasetContainer3; // Use the container to open the network dataset. ESRI.ArcGIS.Geodatabase.IDataset dataset = datasetContainer3.get_DatasetByName(ESRI.ArcGIS.Geodatabase.esriDatasetType.esriDTNetworkDataset, NETWORK_DATASET); INetworkDataset networkDataset = dataset as INetworkDataset; // Create the Route NALayer INALayer naLayer = CreateRouteAnalysisLayer("Route", networkDataset); INAContext naContext = naLayer.Context; INAClass stopsNAClass = naContext.NAClasses.get_ItemByName("Stops") as INAClass; IFeatureClass routesFC = naContext.NAClasses.get_ItemByName("Routes") as IFeatureClass; // Load the Stops INAClassFieldMap naClassFieldMap = new NAClassFieldMapClass(); naClassFieldMap.set_MappedField("Name", INPUT_NAME_FIELD); INAClassLoader naLoader = new NAClassLoaderClass(); naLoader.Locator = naContext.Locator; naLoader.NAClass = stopsNAClass; naLoader.FieldMap = naClassFieldMap; // Avoid loading network locations onto non-traversable portions of elements INALocator3 locator = naContext.Locator as INALocator3; locator.ExcludeRestrictedElements = true; locator.CacheRestrictedElements(naContext); int rowsInCursor = 0; int rowsLocated = 0; naLoader.Load(inputStopsFClass.Search(new QueryFilterClass(), false) as ICursor, new CancelTrackerClass(), ref rowsInCursor, ref rowsLocated); //Message all of the network analysis agents that the analysis context has changed ((INAContextEdit)naContext).ContextChanged(); //Solve INASolver naSolver = naContext.Solver; naSolver.Solve(naContext, new GPMessagesClass(), new CancelTrackerClass()); //Save the layer to disk SaveLayerToDisk(naLayer as ILayer, System.Environment.CurrentDirectory + @"\Route.lyr"); } /// <summary> /// Create a new network analysis layer and set some solver settings /// </summary> private INALayer CreateRouteAnalysisLayer(String layerName, INetworkDataset networkDataset) { INARouteSolver naRouteSolver = new NARouteSolverClass(); INASolverSettings naSolverSettings = naRouteSolver as INASolverSettings; INASolver naSolver = naRouteSolver as INASolver; //Get the NetworkDataset's Data Element IDatasetComponent datasetComponent = networkDataset as IDatasetComponent; IDENetworkDataset deNetworkDataset = datasetComponent.DataElement as IDENetworkDataset; //Create the NAContext and bind to it INAContext naContext; naContext = naSolver.CreateContext(deNetworkDataset, layerName); INAContextEdit naContextEdit = naContext as INAContextEdit; naContextEdit.Bind(networkDataset, new GPMessagesClass()); //Create the NALayer INALayer naLayer; naLayer = naSolver.CreateLayer(naContext); (naLayer as ILayer).Name = layerName; //Set properties on the route solver interface naRouteSolver.FindBestSequence = true; naRouteSolver.PreserveFirstStop = true; naRouteSolver.PreserveLastStop = false; naRouteSolver.UseTimeWindows = false; naRouteSolver.OutputLines = esriNAOutputLineType.esriNAOutputLineTrueShapeWithMeasure; //Set some properties on the general INASolverSettings interface IStringArray restrictions = naSolverSettings.RestrictionAttributeNames; restrictions.Add("Oneway"); naSolverSettings.RestrictionAttributeNames = restrictions; // Update the context based on the changes made to the solver settings naSolver.UpdateContext(naContext, deNetworkDataset, new GPMessagesClass()); //Return the layer return naLayer; } /// <summary> /// Write the NALayer out to disk as a layer file. /// </summary> private void SaveLayerToDisk(ILayer layer, String path) { try { Console.WriteLine("Writing layer file containing analysis to " + path); ILayerFile layerFile = new LayerFileClass(); layerFile.New(path); layerFile.ReplaceContents(layer as ILayer); layerFile.Save(); Console.WriteLine("Writing layer file successfully saved"); } catch (Exception err) { // Write out errors Console.WriteLine(err.Message); } } } }