ArcGIS_NAServer_Routing_CSharp\Default.aspx.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. // using System; using System.Data; using System.Configuration; using System.Collections; using System.Collections.Specialized; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using ESRI.ArcGIS.ADF.ArcGISServer; using ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer; public partial class _Default : System.Web.UI.Page { // Member Variables private const string SERVER_NAME = "localhost"; private const string ROUTE_SERVICE_NAME = "SanFrancisco"; private const string LOCATOR_SERVICE_NAME = "SanFranciscoLocator"; protected void Page_Load(object sender, EventArgs e) { Page.Title = "Simple Routing Application"; } protected void btnGetDirections_Click(object sender, EventArgs e) { Solve(); } /// <summary> /// This function /// - sets the server and solver parameters /// - populates the stops NALocations /// - gets and displays the server results (map, directions) /// </summary> private void Solve() { try { // Get the NAServer using (NAServerProxy naServer = NAServerProxy.Create(SERVER_NAME, ROUTE_SERVICE_NAME, null)) { if (naServer == null) throw (new System.Exception("Could not find the web service.")); // Get the NAServerSolverParams string[] naLayers = naServer.GetNALayerNames(esriNAServerLayerType.esriNAServerRouteLayer); NAServerSolverParams solverParams = naServer.GetSolverParameters(naLayers[0]) as NAServerSolverParams; // Set the NAServerRouteParams NAServerRouteParams routeParams = solverParams as NAServerRouteParams; DateTime time; routeParams.UseStartTime = DateTime.TryParse(txtStartTime.Value, out time); if (routeParams.UseStartTime) routeParams.StartTime = time; routeParams.ReturnMap = false; routeParams.ReturnRouteGeometries = true; routeParams.ReturnStops = true; routeParams.ReturnDirections = chkShowDirections.Checked; routeParams.DirectionsTimeAttributeName = "Minutes"; routeParams.ImpedanceAttributeName = "Minutes"; // Set Output Spatial Reference MapFunctionality mapFunctionality = (MapFunctionality)Map1.GetFunctionality(0); routeParams.OutputSpatialReference = mapFunctionality.MapDescription.SpatialReference; // Geocode two addresses and create the stop network locations LoadLocations(solverParams); // Solve the Route NAServerSolverResults solverResults; solverResults = naServer.Solve(solverParams); // Display results OutputResults(solverResults); } } catch (Exception exception) { pnlDirectionSummary.Visible = false; lblDirections.Visible = false; lblTotalDistance.Visible = false; dataGridDirections.Visible = false; lblError.Text = "An error has occurred Mesage = " + exception.Message; } } /// <summary> /// This function shows how to populate stop locations using an array of PropertySets /// </summary> private void LoadLocations(NAServerSolverParams solverParams) { // Geocode Addresses PropertySet[] propSets = new PropertySet[2]; propSets[0] = GeocodeAddress(txtFromStreet.Value, txtFromCity.Value, txtFromState.Value, txtFromZip.Value); propSets[1] = GeocodeAddress(txtToStreet.Value, txtToCity.Value, txtToState.Value, txtToZip.Value); NAServerPropertySets StopsPropSets = new NAServerPropertySets(); StopsPropSets.PropertySets = propSets; NAServerRouteParams routeParams = solverParams as NAServerRouteParams; routeParams.Stops = StopsPropSets; } /// <summary> /// Geocode an address based on the street name, city, state, and zip code /// Throws and exception and returns null if the address was unmatched. /// </summary> private PropertySet GeocodeAddress(string streetAddress, string city, string state, string zipCode) { PropertySet propSet = null; try { using (GeocodeServerProxy gc = GeocodeServerProxy.Create(SERVER_NAME, LOCATOR_SERVICE_NAME, null)) { PropertySet addressProperties = new PropertySet(); Fields addressFields; Field field; PropertySetProperty[] propSetProperty = new PropertySetProperty[4]; addressFields = gc.GetAddressFields(); for (int i = 0; i < addressFields.FieldArray.GetLength(0); i++) { field = addressFields.FieldArray[i]; if (field.Name.Equals("STREET", StringComparison.OrdinalIgnoreCase)) propSetProperty[0] = CreatePropertySetProperty(field.AliasName, streetAddress) as PropertySetProperty; if (field.Name.Equals("CITY", StringComparison.OrdinalIgnoreCase)) propSetProperty[1] = CreatePropertySetProperty(field.AliasName, city) as PropertySetProperty; if (field.Name.Equals("STATE", StringComparison.OrdinalIgnoreCase)) propSetProperty[2] = CreatePropertySetProperty(field.AliasName, state) as PropertySetProperty; if (field.Name.Equals("ZIP", StringComparison.OrdinalIgnoreCase) || field.Name.Equals("ZONE", StringComparison.OrdinalIgnoreCase)) propSetProperty[3] = CreatePropertySetProperty(field.AliasName, zipCode) as PropertySetProperty; } addressProperties.PropertyArray = propSetProperty; // find the matching address propSet = gc.GeocodeAddress(addressProperties, null); } } catch (Exception exception) { lblError.Text = "An error has occurred Mesage = " + exception.Message; } // Throw and error if the geocoded address is "Unmatched" if ((propSet != null) && (propSet.PropertyArray[1].Value.ToString() == "U")) throw (new System.Exception("Could not geocode [" + streetAddress + "]")); // Overwrite the "matched" property with the "Name" of the street propSet.PropertyArray[1].Key = "Name"; propSet.PropertyArray[1].Value = streetAddress; return propSet; } /// <summary> /// CreatePropertySetProperty /// </summary> private PropertySetProperty CreatePropertySetProperty(string key, object value) { PropertySetProperty propSetProperty = new PropertySetProperty(); propSetProperty.Key = key; propSetProperty.Value = value; return propSetProperty; } /// <summary> /// Output Results map, Directions /// </summary> private void OutputResults(NAServerSolverResults solverResults) { string messagesSolverResults = ""; // Output Solve messages GPMessages gpMessages = solverResults.SolveMessages; GPMessage[] arrGPMessage = gpMessages.GPMessages1; if (arrGPMessage != null) { for (int i = 0; i < arrGPMessage.GetLength(0); i++) { GPMessage gpMessage = arrGPMessage[i]; messagesSolverResults += "\n" + gpMessage.MessageDesc; } } lblError.Text = messagesSolverResults; NAServerRouteResults RouteSolverResults = solverResults as NAServerRouteResults; // Display turn-by-turn directions if (chkShowDirections.Checked == true) OutputDirections(RouteSolverResults.Directions); else { // Or simply display the total impedance for the route lblTotalTime.Text = "Total Time: " + RouteSolverResults.TotalImpedances[0].ToString("F") + " mn"; lblTotalDistance.Visible = false; pnlDirectionSummary.Visible = true; lblDirections.Visible = false; dataGridDirections.Visible = false; } // Add graphics from route and stops GraphicElement[] graphicElements = new GraphicElement[RouteSolverResults.RouteGeometries.Length + RouteSolverResults.Stops.Records.Length]; AddRoutesToGraphicElements(RouteSolverResults.RouteGeometries, graphicElements); AddStopsToGraphicElements(RouteSolverResults.Stops, graphicElements); MapFunctionality mapFunctionality = (MapFunctionality)Map1.GetFunctionality(0); mapFunctionality.MapDescription.CustomGraphics = graphicElements; // Zoom to extent PolylineN polylineN = RouteSolverResults.RouteGeometries[0] as PolylineN; EnvelopeN envelopeN = polylineN.Extent as EnvelopeN; double width = envelopeN.XMax - envelopeN.XMin; double height = envelopeN.YMax - envelopeN.YMin; double fivePercent; if (width > height) fivePercent = width * .05; else fivePercent = height * .05; envelopeN.XMin = envelopeN.XMin - fivePercent; envelopeN.YMin = envelopeN.YMin - fivePercent; envelopeN.XMax = envelopeN.XMax + fivePercent; envelopeN.YMax = envelopeN.YMax + fivePercent; Map1.Extent = ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.Converter.ToAdfEnvelope(envelopeN); Map1.Refresh(); } // Add routes as blue lines public void AddRoutesToGraphicElements(Polyline[] polylines, GraphicElement[] graphicElements) { RgbColor rgb = new RgbColor(); rgb.Red = 0; rgb.Green = 0; rgb.Blue = 255; rgb.AlphaValue = 32; SimpleLineSymbol sls = new SimpleLineSymbol(); sls.Color = rgb; sls.Style = esriSimpleLineStyle.esriSLSSolid; sls.Width = 6; for (int i = 0; i < polylines.Length; i++) { LineElement le = new LineElement(); le.Line = polylines[i]; le.Symbol = sls; graphicElements[i] = le; } } // Add all stops as black circles public void AddStopsToGraphicElements(RecordSet stops, GraphicElement[] graphicElements) { Record[] stopRecords = stops.Records; int stopCount = stopRecords.Length; RgbColor rgb = new RgbColor(); rgb.Red = 0; rgb.Green = 0; rgb.Blue = 0; rgb.AlphaValue = 255; SimpleMarkerSymbol sms = new SimpleMarkerSymbol(); sms.Color = rgb; sms.Style = esriSimpleMarkerStyle.esriSMSCircle; sms.Size = 16; int iGraphicElement = graphicElements.Length - stopCount; for (int iStop = 0; iStop < stopCount; iGraphicElement++, iStop++) { MarkerElement me = new MarkerElement(); me.Point = stopRecords[iStop].Values[1] as PointN; me.Symbol = sms; graphicElements[iGraphicElement] = me; } } /// <summary> /// Output Directions if a dataGrid control /// </summary> private void OutputDirections(NAStreetDirections[] serverDirections) { if (serverDirections == null) return; // get Directions from the ith route NAStreetDirections directions; directions = serverDirections[0]; // get Summary (Total Distance and Time) NAStreetDirection direction = directions.Summary; string totallength = null, totaltime = null; string[] SummaryStrings = direction.Strings; for (int k = SummaryStrings.GetLowerBound(0); k < SummaryStrings.GetUpperBound(0); k++) { if (direction.StringTypes[k] == esriDirectionsStringType.esriDSTLength) totallength = SummaryStrings[k]; if (direction.StringTypes[k] == esriDirectionsStringType.esriDSTTime) totaltime = SummaryStrings[k]; } // Display the direction in a DataGrid DataSet dataSet = new DataSet("dataSet"); DataTable dataTable = new DataTable("Results"); dataSet.Tables.Add(dataTable); DataColumn dataColumn = null; dataColumn = new DataColumn("Step "); dataTable.Columns.Add(dataColumn); dataColumn = new DataColumn("Directions "); dataTable.Columns.Add(dataColumn); dataColumn = new DataColumn("Estimated Arrival Time "); dataTable.Columns.Add(dataColumn); // Then add a node for each step-by-step directions DataRow newDataRow; NAStreetDirection[] StreetDirections = directions.Directions; for (int directionIndex = StreetDirections.GetLowerBound(0); directionIndex <= StreetDirections.GetUpperBound(0); directionIndex++) { NAStreetDirection streetDirection = StreetDirections[directionIndex]; string[] StringStreetDirection = streetDirection.Strings; newDataRow = dataTable.NewRow(); newDataRow[0] = System.Convert.ToString(directionIndex + 1); for (int stringIndex = StringStreetDirection.GetLowerBound(0); stringIndex <= StringStreetDirection.GetUpperBound(0); stringIndex++) { if (streetDirection.StringTypes[stringIndex] == esriDirectionsStringType.esriDSTGeneral || streetDirection.StringTypes[stringIndex] == esriDirectionsStringType.esriDSTDepart || streetDirection.StringTypes[stringIndex] == esriDirectionsStringType.esriDSTArrive) newDataRow[1] = StringStreetDirection[stringIndex]; if (streetDirection.StringTypes[stringIndex] == esriDirectionsStringType.esriDSTEstimatedArrivalTime) newDataRow[2] = StringStreetDirection[stringIndex]; } dataTable.Rows.Add(newDataRow); } dataGridDirections.DataSource = dataSet; dataGridDirections.DataBind(); dataGridDirections.Visible = true; // Display Total Distance and Total Time lblTotalDistance.Text = "Total Distance: " + totallength; lblTotalTime.Text = "Total Time: " + totaltime; pnlDirectionSummary.Visible = true; lblDirections.Visible = true; lblTotalDistance.Visible = true; } }