예제 #1
0
        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);
            }
        }