示例#1
0
 public AddAnalog(
     RemoteName remoteName,
     PointName pointName,
     PointCoordinate pointCoordinate)
 {
     RemoteName      = remoteName;
     PointName       = pointName;
     PointCoordinate = pointCoordinate;
 }
 public UpdateAnalogCoordinate(
     RemoteName remoteName,
     PointName pointName,
     PointCoordinate newPointCoordinate)
 {
     RemoteName         = remoteName;
     PointName          = pointName;
     NewPointCoordinate = newPointCoordinate;
 }
示例#3
0
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            try
            {
                JObject jsonObj = JObject.Load(reader);

                ITypedCoordinateContainer typedCoorContainerResult = (ITypedCoordinateContainer)Activator.CreateInstance(objectType);


                if (jsonObj.HasValues)
                {
                    JProperty typeProp        = jsonObj.Property("type");
                    JProperty coordinatesProp = jsonObj.Property("coordinates");
                    if (typeProp != null && coordinatesProp != null)
                    {
                        string type      = typeProp.Value.ToString();
                        JArray coorArray = string.IsNullOrWhiteSpace(coordinatesProp.Value.ToString()) ? null : JArray.FromObject(coordinatesProp.Value);
                        if (coorArray != null)
                        {
                            ICoordinateCollection coorResult      = null;
                            ITypedCoordinate      typedCoorResult = null;

                            if (type == "Point")
                            {
                                //TJM: Assume simple array of coordinate pairs...
                                coorResult = GetPointFromJArray(coorArray, _isLegacyFormat);
                                //TJM: It's ok if the coorResult is null.
                                typedCoorResult = new PointCoordinate(coorResult);
                            }
                            else if (type == "LineString")
                            {
                                //TJM: Assume array of "Point".
                                coorResult      = GetLineStringFromJArray(coorArray, _isLegacyFormat);
                                typedCoorResult = new LineStringCoordinate(coorResult);
                            }
                            else if (type == "Polygon")
                            {
                                //TJM: Assume array of "LineString".
                                coorResult      = GetPolygonFromJArray(coorArray, _isLegacyFormat);
                                typedCoorResult = new PolygonCoordinate(coorResult);
                            }

                            typedCoorContainerResult.Coordinates = typedCoorResult;

                            return(typedCoorContainerResult);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                //TJM: Should we do anything here??
            }

            return(null);
        }
示例#4
0
        /// <summary>
        /// Default function for retrieving Total Flow data
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task <ITimeSeriesOutput> GetTotalFlowData(TotalFlowInput input)
        {
            //TODO: Extract the geometry percentage from following code and place in Utility class, for possible use by all controllers.

            // Steps:
            // 1 - determine geometry
            // type case ID: is equal to "huc", "commid", or "catchmentid"
            // type case ID action: send request to HMS-GIS /rest/catchment?source=SOURCE%type=TYPE%id=ID for geometry
            // type case geojson: is equal to "catchment", or "flowline"
            // type case geojson action: send request to HMS-GIS /rest/catchment/geojson/ (geojson in body) OR
            //                         : send request to HMS-GIS /rest/catchment/flowlines/ (flowline geojson in body)
            // type case points: is equal to "points"
            // type case points action: if request is one point - send request to EPA waters for watershed geometry, if request is two points
            // 2 - retrieve catchments-points table
            // 3 - collect all points catchment table (this resolves issue of possible duplicate calls on catchment edge)
            // 4 - retrieve data for all points in catchment table [Parallel]
            // 5 - iterate through catchments and assign data to appropriate catchment
            // 6 - aggregate the data for each catchment based upon how much area that cell has in the catchment [Parallel]
            // 7 - return aggregated data as a timeseries in the form of { datetime : [ catchment1, catchment2, catchment3, ... ]}
            // 8 - set metadata (request inputs, catchment data, aggregation data, output structure)
            // 9 - return output
            string error = "";

            Utilities.ErrorOutput err = new Utilities.ErrorOutput();
            GeometryResponse      geo = new GeometryResponse();

            string requestUrl = this.baseUrl + "/hms/rest/api/v2/hms/gis/percentage/";

            if (input.GeometryInputs != null)
            {
                if (input.GeometryInputs.ContainsKey("huc8") && input.GeometryInputs.ContainsKey("commid"))
                {
                    Dictionary <string, string> taskID;
                    string queryUrl = requestUrl + "?huc_8_num=" + input.GeometryInputs["huc8"] + "&com_id_num=" + input.GeometryInputs["commid"];
                    using (var httpClientHandler = new HttpClientHandler())
                    {
                        httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return(true); };
                        using (var client = new HttpClient(httpClientHandler))
                        {
                            taskID = JsonConvert.DeserializeObject <Dictionary <string, string> >(client.GetStringAsync(queryUrl).Result);
                        }
                        geo = this.RequestData(taskID["job_id"], out error);
                    }
                }
                else
                {
                    return(err.ReturnError("Input error - GeometryInputs provided is invalid."));
                }
            }
            else
            {
                switch (input.GeometryType.ToLower())
                {
                case "huc":
                    // use case 1
                    // use case 2
                    string hucID = input.GeometryInput;
                    using (var client = new HttpClient())
                    {
                        string queryUrl = baseUrl + "?huc_8_id=" + hucID;
                        client.Timeout = TimeSpan.FromMinutes(10);
                        geo            = JsonConvert.DeserializeObject <GeometryResponse>(client.GetStringAsync(queryUrl).Result);
                    }
                    //goto default;
                    break;

                case "commid":
                    // use case 3
                    //string commid = input.GeometryInput;
                    //using (var client = new HttpClient())
                    //{
                    //    string queryUrl = baseUrl + "?com_id=" + commid;
                    //    client.Timeout = TimeSpan.FromMinutes(10);
                    //    geo = JsonConvert.DeserializeObject<GeometryResponse>(client.GetStringAsync(queryUrl).Result);
                    //}
                    goto default;
                    break;

                case "catchmentid":
                    // use case 3
                    // string catchmentID = input.GeometryInput;
                    //using (var client = new HttpClient())
                    //{
                    //    geo = JsonConvert.DeserializeObject<GeometryResponse>(client.GetStringAsync(baseUrl + "/api/GridCell/catchmentid/" + catchmentID).Result);
                    //}
                    goto default;
                    break;

                case "catchment":
                    // use case 4
                    // Use POST call with geometry
                    goto default;
                    break;

                case "flowline":
                    // use case 5
                    // Use POST call with geometry
                    goto default;
                    break;

                case "points":
                    // use case 6
                    // use case 7
                    // GET call with points, hms-gis will get geometries
                    goto default;
                    break;

                case "test":
                    string testGeometry = "{\"geometry\":{\"9311911\": { \"points\": [ { \"cellArea\": 0.015624999999992895,  \"containedArea\": 4.178630503273804e-05,  \"longitude\": -71.43749999999996,  \"latitude\": 44.18749999999999,  \"percentArea\": 0.26743235220964506 },  { \"cellArea\": 0.015624999999996447,  \"containedArea\": 0.005083393397351494,  \"longitude\": -71.31249999999997,  \"latitude\": 44.18750000000001,  \"percentArea\": 32.53371774305696 },  { \"cellArea\": 0.015624999999996447,  \"containedArea\": 0.0002419268603100419,  \"longitude\": -71.31249999999997,  \"latitude\": 44.31249999999997,  \"percentArea\": 1.5483319059846201 } ] } },  \"metadata\": { \"execution time\": 86.99717831611633,  \"nldas source\": \"https://ldas.gsfc.nasa.gov/nldas/gis/NLDAS_Grid_Reference.zip\",  \"number of points\": 3,  \"request date\": \"Thu, 22 Mar 2018 11:46:44 GMT\",  \"shapefile source\": \"ftp://newftp.epa.gov/exposure/BasinsData/NHDPlus21/NHDPlus01060002.zip\" } }";
                    //string testGeometry = "{\"Geometry\": {\"02080107\": [{\"Latitude\": 37.437499999999972,\"Longitude\": -76.687499999999972,\"CellArea\": 0.0156250000000036,\"ContainedArea\": 0.00559514073505796,\"PercentArea\": 35.8089007043628},{\"Latitude\": 37.437499999999972,\"Longitude\": -76.5625,\"CellArea\": 0.0156250000000053,\"ContainedArea\": 0.0100796700330301,\"PercentArea\": 64.5098882113707},{\"Latitude\": 37.437499999999972,\"Longitude\": -76.437499999999972,\"CellArea\": 0.0156250000000142,\"ContainedArea\": 0.00780989236262298,\"PercentArea\": 49.9833111207416},{\"Latitude\": 37.437499999999972,\"Longitude\": -76.312499999999957,\"CellArea\": 0.0156250000000036,\"ContainedArea\": 0.0012605882348706,\"PercentArea\": 8.06776470316997}]},\"Metadata\": {}}";
                    geo = JsonConvert.DeserializeObject <GeometryResponse>(testGeometry);
                    break;

                default:
                    return(err.ReturnError("Input error - GeometryType provided is invalid. Provided value = " + input.GeometryType));
                }
            }
            // Check for any errors
            if (!String.IsNullOrWhiteSpace(error) || !geo.status.Equals("SUCCESS"))
            {
                return(err.ReturnError(error));
            }

            // Collect all unique points in Catchment
            List <GeometryPoint> points    = new List <GeometryPoint>();
            List <string>        pointsSTR = new List <string>();

            foreach (KeyValuePair <string, Catchment> k in geo.data.geometry)
            {
                foreach (Point cp in k.Value.points)
                {
                    GeometryPoint p = new GeometryPoint();
                    p.Latitude  = cp.latitude;
                    p.Longitude = cp.longitude;
                    if (!points.Contains(p))
                    {
                        points.Add(p);
                        pointsSTR.Add("[" + p.Latitude.ToString() + ", " + p.Longitude.ToString() + "]");
                    }
                }
            }

            ITimeSeriesInputFactory inputFactory  = new TimeSeriesInputFactory();
            List <string>           errorMessages = new List <string>();
            string errorMsg = "";
            // Initialize all surface and subsurface points
            Dictionary <string, SurfaceRunoff.SurfaceRunoff>   surfaceFlow    = new Dictionary <string, SurfaceRunoff.SurfaceRunoff>();
            Dictionary <string, SubSurfaceFlow.SubSurfaceFlow> subsurfaceFlow = new Dictionary <string, SubSurfaceFlow.SubSurfaceFlow>();

            foreach (GeometryPoint point in points)
            {
                string             key        = point.Latitude.ToString() + "," + point.Longitude.ToString();
                TimeSeriesGeometry tsGeometry = new TimeSeriesGeometry();
                tsGeometry.Point = new PointCoordinate()
                {
                    Latitude  = point.Latitude,
                    Longitude = point.Longitude
                };

                // Initialize surfaceFlow catchment point object
                errorMsg = "";
                TimeSeriesInput surfaceTempInput = new TimeSeriesInput();
                surfaceTempInput          = input;
                surfaceTempInput.Geometry = tsGeometry;
                SurfaceRunoff.SurfaceRunoff sFlow = new SurfaceRunoff.SurfaceRunoff();
                sFlow.Input = inputFactory.SetTimeSeriesInput(surfaceTempInput, new List <string>()
                {
                    "surfacerunoff"
                }, out errorMsg);
                surfaceFlow.Add(key, sFlow);
                errorMessages.Add(errorMsg);

                // Initialize subsurfaceFlow catchment point object
                errorMsg = "";
                TimeSeriesInput subSurfaceTempInput = new TimeSeriesInput();
                subSurfaceTempInput          = input;
                subSurfaceTempInput.Geometry = tsGeometry;
                SubSurfaceFlow.SubSurfaceFlow subFlow = new SubSurfaceFlow.SubSurfaceFlow();
                subFlow.Input = inputFactory.SetTimeSeriesInput(subSurfaceTempInput, new List <string>()
                {
                    "subsurfaceflow"
                }, out errorMsg);
                subsurfaceFlow.Add(key, subFlow);
                errorMessages.Add(errorMsg);
            }

            // TODO: merge parallelized calls to surfaceRunoff and subsurfaceFlow
            // Parallelized surfaceRunoff
            object        outputListLock = new object();
            List <string> surfaceError   = new List <string>();
            var           options        = new ParallelOptions {
                MaxDegreeOfParallelism = -1
            };

            Parallel.ForEach(surfaceFlow, options, (KeyValuePair <string, SurfaceRunoff.SurfaceRunoff> surF) =>
            {
                string errorM = "";
                surF.Value.GetData(out errorM);
                lock (outputListLock)
                {
                    surfaceError.Add(errorM);
                }
            });

            // Parallelized subsurfaceFlow
            List <string> subsurfaceError = new List <string>();

            Parallel.ForEach(subsurfaceFlow, options, (KeyValuePair <string, SubSurfaceFlow.SubSurfaceFlow> subF) =>
            {
                string errorM = "";
                subF.Value.GetData(out errorM);
                lock (outputListLock)
                {
                    subsurfaceError.Add(errorM);
                }
            });

            ITimeSeriesOutputFactory outputFactory = new TimeSeriesOutputFactory();
            ITimeSeriesOutput        output        = outputFactory.Initialize();

            // Aggregate catchments
            List <ITimeSeriesOutput> catchmentFlow = new List <ITimeSeriesOutput>();
            ITimeSeriesOutput        iOutput       = outputFactory.Initialize();
            var options2 = new ParallelOptions {
                MaxDegreeOfParallelism = 1
            };
            Dictionary <string, string> catchmentMeta = new Dictionary <string, string>();

            Parallel.ForEach(geo.data.geometry, options2, (KeyValuePair <string, Catchment> catchments) => {
                string catchmentID = catchments.Key;
                List <ITimeSeriesOutput> catchmentPoints = new List <ITimeSeriesOutput>();
                foreach (Point cp in catchments.Value.points)
                {
                    IPointCoordinate point = new PointCoordinate()
                    {
                        Latitude  = cp.latitude,
                        Longitude = cp.longitude
                    };
                    string key = point.Latitude.ToString() + "," + point.Longitude.ToString();
                    ITimeSeriesOutput output1 = Utilities.Merger.ModifyTimeSeries(surfaceFlow[key].Output, cp.percentArea / 100);
                    ITimeSeriesOutput output2 = Utilities.Merger.ModifyTimeSeries(subsurfaceFlow[key].Output, cp.percentArea / 100);

                    if (iOutput.Data.Count == 0)
                    {
                        iOutput = output1;
                        iOutput = Utilities.Merger.MergeTimeSeries(iOutput, output2);
                    }
                    else
                    {
                        iOutput = Utilities.Merger.MergeTimeSeries(iOutput, output1);
                        iOutput = Utilities.Merger.MergeTimeSeries(iOutput, output2);
                    }
                    catchmentPoints.Add(Utilities.Merger.AddTimeSeries(output1, output2, "TotalFlow"));
                }

                output.Data          = (Utilities.Merger.MergeTimeSeries(catchmentPoints).Data);
                int currentCatchment = catchmentMeta.Count + 1;
                catchmentMeta.Add("catchment_column_" + currentCatchment.ToString() + "_ID", catchments.Key);
            });
            // Testing
            // output.Data = iOutput.Data;

            output.DataSource = input.Source;
            output.Dataset    = "Total Flow";

            output.Metadata = surfaceFlow.First().Value.Output.Metadata;
            output.Metadata.Remove(input.Source + "_lat");
            output.Metadata.Remove(input.Source + "_lon");
            output.Metadata.Remove(input.Source + "_prod_name");
            output.Metadata.Remove(input.Source + "_param_short_name");
            output.Metadata.Remove(input.Source + "_param_name");
            output.Metadata[input.Source + "_points"] = string.Join(", ", pointsSTR);

            // Adding geometry metadata to output metadata
            foreach (KeyValuePair <string, string> kv in geo.data.metadata)
            {
                if (!output.Metadata.ContainsKey(kv.Key))
                {
                    output.Metadata.Add(kv.Key, kv.Value);
                }
            }

            // Cleaning up output metadata
            Dictionary <string, string> cleanedMetaData = new Dictionary <string, string>();

            foreach (KeyValuePair <string, string> kv in output.Metadata)
            {
                if (!kv.Key.Contains("column"))
                {
                    cleanedMetaData.Add(kv.Key, kv.Value);
                }
            }
            output.Metadata = cleanedMetaData;

            // Add catchments metadata to output metadata
            foreach (KeyValuePair <string, string> kv in catchmentMeta)
            {
                output.Metadata.Add(kv.Key, kv.Value);
            }

            return(output);
        }
示例#5
0
        /// <summary>
        /// Gets workflow data.
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task <ITimeSeriesOutput> GetWorkFlowData(WorkFlowCompareInput input)
        {
            string errorMsg = "";

            // Constructs default error output object containing error message.
            Utilities.ErrorOutput err = new Utilities.ErrorOutput();

            input.SourceList = new List <string>()
            {
                { "ncdc" },
                { "nldas" },
                { "gldas" },
                { "daymet" }
            };

            ITimeSeriesOutputFactory oFactory = new TimeSeriesOutputFactory();
            ITimeSeriesOutput        output   = oFactory.Initialize();

            output.DataSource = string.Join(" - ", input.SourceList.ToArray());

            if (input.Dataset.Contains("precipitation"))
            {
                input.SourceList = new List <string>()
                {
                    { "nldas" },
                    { "gldas" },
                    { "daymet" }
                };
                input.Source = "ncdc";
                // Validate precipitation sources.
                errorMsg = (!Enum.TryParse(input.Source, true, out PrecipSources pSource)) ? "ERROR: 'Source' was not found or is invalid." : "";
                if (errorMsg.Contains("ERROR"))
                {
                    return(err.ReturnError(errorMsg));
                }

                List <Precipitation.Precipitation> precipList = new List <Precipitation.Precipitation>();
                List <ITimeSeriesOutput>           outputList = new List <ITimeSeriesOutput>();

                // NCDC Call
                Precipitation.Precipitation ncdc = new Precipitation.Precipitation();
                // ITimeSeriesInputFactory object used to validate and initialize all variables of the input object.
                ITimeSeriesInputFactory nFactory = new TimeSeriesInputFactory();
                ITimeSeriesInput        nInput   = nFactory.SetTimeSeriesInput(input, new List <string>()
                {
                    "precipitation"
                }, out errorMsg);
                if (errorMsg.Contains("ERROR"))
                {
                    return(err.ReturnError(errorMsg));
                }

                // Set input to precip object.
                ncdc.Input = nInput;
                ncdc.Input.TemporalResolution = "daily";
                ncdc.Input.Geometry.GeometryMetadata["token"] = (ncdc.Input.Geometry.GeometryMetadata.ContainsKey("token")) ? ncdc.Input.Geometry.GeometryMetadata["token"] : "RUYNSTvfSvtosAoakBSpgxcHASBxazzP";
                ITimeSeriesOutput nResult = ncdc.GetData(out errorMsg);
                if (errorMsg.Contains("ERROR"))
                {
                    return(err.ReturnError(errorMsg));
                }
                output = nResult;

                // Construct Precipitation objects for Parallel execution in the preceeding Parallel.ForEach statement.
                foreach (string source in input.SourceList)
                {
                    // Precipitation object
                    Precipitation.Precipitation precip = new Precipitation.Precipitation();
                    PointCoordinate             point  = new PointCoordinate();
                    if (output.Metadata.ContainsKey("ncdc_latitude") && output.Metadata.ContainsKey("ncdc_longitude"))
                    {
                        point.Latitude       = Convert.ToDouble(output.Metadata["ncdc_latitude"]);
                        point.Longitude      = Convert.ToDouble(output.Metadata["ncdc_longitude"]);
                        input.Geometry.Point = point;
                    }
                    else
                    {
                        errorMsg = "ERROR: Coordinate information was not found or is invalid for the specified NCDC station.";
                    }
                    // ITimeSeriesInputFactory object used to validate and initialize all variables of the input object.
                    ITimeSeriesInputFactory iFactory = new TimeSeriesInputFactory();
                    input.Source = source;
                    ITimeSeriesInput sInput = iFactory.SetTimeSeriesInput(input, new List <string>()
                    {
                        "PRECIP"
                    }, out errorMsg);
                    if (errorMsg.Contains("ERROR"))
                    {
                        return(err.ReturnError(errorMsg));
                    }

                    // Set input to precip object.
                    precip.Input = sInput;
                    precip.Input.TemporalResolution = "daily";

                    precip.Input.DateTimeSpan.EndDate = precip.Input.DateTimeSpan.EndDate.AddDays(1);
                    if (!precip.Input.Geometry.GeometryMetadata.ContainsKey("leapYear"))
                    {
                        precip.Input.Geometry.GeometryMetadata.Add("leapYear", "correction");
                    }
                    precipList.Add(precip);
                }

                List <string> errorList      = new List <string>();
                object        outputListLock = new object();
                var           options        = new ParallelOptions {
                    MaxDegreeOfParallelism = -1
                };

                Parallel.ForEach(precipList, options, (Precipitation.Precipitation precip) =>
                {
                    // Gets the Precipitation data.
                    string errorM            = "";
                    ITimeSeriesOutput result = precip.GetData(out errorM);
                    lock (outputListLock)
                    {
                        errorList.Add(errorM);
                        outputList.Add(result);
                    }
                });

                if (errorList.FindIndex(errorStr => errorStr.Contains("ERROR")) != -1)
                {
                    return(err.ReturnError(string.Join(",", errorList.ToArray())));
                }


                foreach (ITimeSeriesOutput result in outputList)
                {
                    output = Utilities.Merger.MergeTimeSeries(output, result);
                }

                output.Metadata.Add("column_1", "date");
                output.Metadata.Add("column_2", "ncdc");
                output = Utilities.Statistics.GetStatistics(out errorMsg, output);

                return(output);
            }
            else if (input.Dataset.Contains("SurfaceRunoff"))
            {
                //TODO: Do runoff source iteration.
                return(err.ReturnError("ERROR. Workflow has not yet been implemented."));
            }
            else
            {
                return(err.ReturnError("ERROR: WorkFlow source not found or is invalid."));
            }
        }
示例#6
0
 static extern IntPtr MonitorFromPoint(PointCoordinate pt, MonitorOptions dwFlags);
示例#7
0
 static extern bool GetCursorPos(out PointCoordinate lpPoint);