internal async Task PerformAnalysis(MapPoint ptStartLoc, MapView mapView, ProgressorSource ps) { ps.Progressor.Message = "Running the analysis..."; ps.Progressor.Status = "Gathering and verifying parameter data"; string sReqUrl = Properties.Settings.Default.QryPointToState; string sReq = String.Format("{0}?returnGeometry=false&returnDistinctValues=false&geometry={1}&geometryType=esriGeometryPoint&f=json&outFields=*&spatialRel=esriSpatialRelIntersects", sReqUrl, ptStartLoc.ToJson()); // Find out what state the user clicked; or report an error if outside the U.S. HttpWebRequest req = (HttpWebRequest)WebRequest.Create(sReq); string sResp; try { using (StreamReader sread = new StreamReader(req.GetResponse().GetResponseStream())) sResp = sread.ReadToEnd(); } catch (Exception e) { ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show("Error mapping the chosen spot to a petroleum area district in the U.S.A.: " + e.Message); return; } dynamic respPADDState = JsonConvert.DeserializeObject(sResp); try { string sState = respPADDState.features[0].attributes.STATE.ToString(); // Find out what PADD zone the state is in SelectedPADDZone = PaddStateToZone[sState]; } catch (Exception e) { System.Diagnostics.Debug.WriteLine("Exception getting PADD for chosen spot: " + e.Message); ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show("Please choose a spot within the U.S.A."); return /*null*/; } // Find out the gallons/$1.00 in that PADD zone double nFuelCost = PADDZoneToFuelCost[SelectedPADDZone]; // Find out the miles per dollar each vehicle: (mi / gal) / (dollars / gal) // Map is in meters, so convert miles to meters Vehicle[] orderedVehicles = SelectedVehicles.OrderBy(vehicle => vehicle.Mpg).ToArray <Vehicle>(); IEnumerable <double> vehicleMetersPerDollar = orderedVehicles.Select(vehicle => (vehicle.MetersPerGallon) / nFuelCost); string sDistsParam = String.Join(" ", vehicleMetersPerDollar.ToArray()); MapPoint ptStartLocNoZ = await QueuedTask.Run(() => { MapPoint ptNoZ = MapPointBuilder.CreateMapPoint(ptStartLoc.X, ptStartLoc.Y, ptStartLoc.SpatialReference); return(ptNoZ); }); // No corresponding type for the needed GPFeatureRecordSetLayer parameter string sStartGeom = ptStartLocNoZ.ToJson(); string sStartLocParam = "{\"geometryType\":\"esriGeometryPoint\",\"features\":[{\"geometry\":" + sStartGeom + "}]}"; // Run the query ps.Progressor.Status = "Executing the analysis"; string sGPUrl = Properties.Settings.Default.GPFindSA; sGPUrl += String.Format("?Distances={0}&Start_Location={1}&f=json", sDistsParam, sStartLocParam); HttpWebRequest reqSA = (HttpWebRequest)WebRequest.Create(sGPUrl); HttpWebResponse wr; try { wr = (HttpWebResponse)reqSA.GetResponse(); if (wr.StatusCode != HttpStatusCode.OK) { ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show("Error running analysis: " + wr.StatusDescription); return; } } catch (WebException e) { ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show("Error running analysis: " + e.Message); return; } // Show the results ps.Progressor.Status = "Processing the results"; using (StreamReader sread = new StreamReader(wr.GetResponseStream())) sResp = sread.ReadToEnd(); JObject respAnalysis = JObject.Parse(sResp); JArray feats = respAnalysis["results"][0]["value"]["features"] as JArray; // Rectify results and order so that largest polygon can be added to the map first List <JToken> aryResFeats = RectifyResults(feats, orderedVehicles); int iSR = respAnalysis["results"][0]["value"]["spatialReference"]["wkid"].ToObject <Int32>(); SpatialReference sr = await QueuedTask.Run <SpatialReference>(() => { SpatialReference srTemp = SpatialReferenceBuilder.CreateSpatialReference(iSR); return(srTemp); }); /*lock (_lockResults)*/ Results.ClearResults(); // Iterate backwards to add larger polygons behind smaller ones for (int iVeh = orderedVehicles.Count() - 1; iVeh >= 0; iVeh--) { Result result = new Result(orderedVehicles[iVeh]); Polygon poly = null; IDisposable graphic = null; // Compute color for this result float multiplier = aryResFeats.Count > 1 ? ((float)iVeh) / ((float)(aryResFeats.Count - 1)) : 0; byte red = (byte)(255 - (255 * multiplier)); byte green = (byte)(255 * multiplier); Color color = Color.FromRgb(red, green, 0); result.Color = color.ToString(); result.PaddZone = SelectedPADDZone; result.DollarsPerGallon = nFuelCost; string sGeom = aryResFeats[iVeh]["geometry"].ToString(); poly = await QueuedTask.Run(() => { Polygon polyNoSR = PolygonBuilder.FromJson(sGeom); return(PolygonBuilder.CreatePolygon(polyNoSR, sr)); }); CIMStroke outline = SymbolFactory.ConstructStroke(ColorFactory.BlackRGB, 1.0, SimpleLineStyle.Solid); CIMPolygonSymbol symPoly = SymbolFactory.ConstructPolygonSymbol( ColorFactory.CreateRGBColor(color.R, color.G, color.B, RESULT_OPACITY_PCT), SimpleFillStyle.Solid, outline); CIMSymbolReference sym = symPoly.MakeSymbolReference(); CIMSymbolReference symDef = SymbolFactory.DefaultPolygonSymbol.MakeSymbolReference(); graphic = await QueuedTask.Run(() => { return(mapView.AddOverlay(poly, sym)); }); result.DriveServiceArea = poly; result.DriveServiceAreaGraphic = graphic; result.DriveDistM = aryResFeats[iVeh]["attributes"]["ToBreak"].Value <double>(); /*lock (_lockResults)*/ Results.Add(result); } }