Ejemplo n.º 1
0
        public async Task<NexradScan> FetchNexradScanAsync(string site, string product, string filename)
        {
            // http://level3.allisonhouse.com/level3/f410ba3360389cc8401869160fc0a4cb/MPX/N0U/N0U_20140416_1641
            // // http://weather.noaa.gov/pub/SL.us008001/DF.of/DC.radar/DS.p19r0/SI.kmpx/
            // Normalize parameters
            site = site.ToLowerInvariant();
            product = product.ToLowerInvariant();
            
            var scan = new NexradScan();
            var key = String.Format("{0}/{1}/{2}", site, product, filename);
            
            // Check cache and return scan if one is found
            scan = cache.Get(key) as NexradScan;
            if (scan != null)
                return scan;
            
            // No cached scan found, go grab a new one and decode it
            var filelist = new List<string>();
            var nexradbase = "http://weather.noaa.gov/pub/SL.us008001/DF.of/DC.radar/DS.{0}/SI.{1}/{2}";

            switch (product)
            {
                case "n0r":
                    product = "p19r0";
                    break;
            }

            site = site.ToLowerInvariant();
            var endpoint = String.Format(nexradbase, product, site, filename);
            Stream response;

            using (var client = new HttpClient())
            {
                response = await client.GetStreamAsync(endpoint);
            }

            if (response != null)
            {
                using (var ms = new MemoryStream())
                {
                    response.CopyTo(ms);
                    scan = ParseNexrad(ms);
                }
            }

            // Add scan to cache
            policy.AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(1);
            cache.Add(key, scan, policy);

            return scan;
        }
Ejemplo n.º 2
0
        public static NexradScan ParseNexrad(MemoryStream stream)
        {
            var nexrad = new NexradScan();

            try
            {
                var headerData = new byte[30];
                byte[] descriptorData;
                var bytes = new byte[stream.Length];
                descriptorData = new byte[stream.Length - 30];
                var descriptor = new Descriptor();
                var symbology = new Symbology();

                // Header
                stream.Position = 0;
                stream.Read(headerData, 0, 30);
                var headerString = System.Text.Encoding.UTF8.GetString(headerData);
                headerString = headerString.Replace("\n", string.Empty).Replace("\r", " ").Replace("  ", " ");
                var headerStrings = headerString.Split(' ');
                var header = new Header { Code = headerStrings[0], Site = headerStrings[1], Date = headerStrings[2], FullProductCode = headerStrings[3] };
                header.BodyCode = ReadHalfWord(stream);
                header.BodyDate = ReadHalfWord(stream);
                header.BodyTime = ReadWord(stream);
                header.Length = ReadWord(stream);
                header.SourceId = ReadHalfWord(stream);
                header.DestinationId = ReadHalfWord(stream);
                header.BlockCount = ReadHalfWord(stream);

                // Descriptor
                descriptor.Divider = ReadHalfWord(stream);
                descriptor.Latitude = ReadWord(stream);
                descriptor.Longitude = ReadWord(stream);
                descriptor.Height = ReadHalfWord(stream);
                descriptor.Code = ReadHalfWord(stream);
                descriptor.Mode = ReadHalfWord(stream);
                descriptor.VolumeCoveragePattern = ReadHalfWord(stream);
                descriptor.SequenceNumber = ReadHalfWord(stream);
                descriptor.ScanNumber = ReadHalfWord(stream);
                descriptor.ScanDate = ReadHalfWord(stream);
                descriptor.ScanTime = ReadWord(stream);
                descriptor.GenerationDate = ReadHalfWord(stream);
                descriptor.GenerationTime = ReadWord(stream);
                descriptor.ProductSpecific1 = ReadHalfWord(stream);
                descriptor.ProductSpecific2 = ReadHalfWord(stream);
                descriptor.ElevationNumber = ReadHalfWord(stream);
                descriptor.ProductSpecific3 = ReadHalfWord(stream);
                descriptor.Threshold1 = ReadHalfWord(stream);
                descriptor.Threshold2 = ReadHalfWord(stream);
                descriptor.Threshold3 = ReadHalfWord(stream);
                descriptor.Threshold4 = ReadHalfWord(stream);
                descriptor.Threshold5 = ReadHalfWord(stream);
                descriptor.Threshold6 = ReadHalfWord(stream);
                descriptor.Threshold7 = ReadHalfWord(stream);
                descriptor.Threshold8 = ReadHalfWord(stream);
                descriptor.Threshold9 = ReadHalfWord(stream);
                descriptor.Threshold10 = ReadHalfWord(stream);
                descriptor.Threshold11 = ReadHalfWord(stream);
                descriptor.Threshold12 = ReadHalfWord(stream);
                descriptor.Threshold13 = ReadHalfWord(stream);
                descriptor.Threshold14 = ReadHalfWord(stream);
                descriptor.Threshold15 = ReadHalfWord(stream);
                descriptor.Threshold16 = ReadHalfWord(stream);
                descriptor.ProductSpecific4 = ReadHalfWord(stream);
                descriptor.ProductSpecific5 = ReadHalfWord(stream);
                descriptor.ProductSpecific6 = ReadHalfWord(stream);
                descriptor.ProductSpecific7 = ReadHalfWord(stream);
                descriptor.ProductSpecific8 = ReadHalfWord(stream);
                descriptor.ProductSpecific9 = ReadHalfWord(stream);
                descriptor.ProductSpecific10 = ReadHalfWord(stream);
                descriptor.Version = ReadByte(stream);
                descriptor.SpotBlank = ReadByte(stream);
                descriptor.SymbologyOffset = ReadWord(stream);
                descriptor.GraphicOffset = ReadWord(stream);
                descriptor.TabularOffset = ReadWord(stream);

                if (descriptor.SymbologyOffset != 0)
                {
                    symbology.Divider = ReadHalfWord(stream);
                    symbology.BlockId = ReadHalfWord(stream);
                    symbology.Length = ReadWord(stream);
                    symbology.Layers = ReadHalfWord(stream);
                    symbology.LayerDivider = ReadHalfWord(stream);
                    symbology.DataLength = ReadWord(stream);
                    symbology.PacketCode = ReadHalfWord(stream);
                    symbology.IndexFirstRangeBin = ReadHalfWord(stream);
                    symbology.RangeBinCount = ReadHalfWord(stream); // dataHeader[1]
                    symbology.SweepCenterI = ReadHalfWord(stream);  // dataHeader[2]
                    symbology.SweepCenterJ = ReadHalfWord(stream);  // dataHeader[3]
                    symbology.ScaleFactor = ReadHalfWord(stream);   // dataHeader[4]
                    symbology.RadialCount = ReadHalfWord(stream);   // dataHeader[5]
                    symbology.RadialData = new List<Radial>();

                    var radialCount = symbology.RadialCount;
                    for (var i = 0; i < radialCount; i++)
                    {
                        var radial = new Radial();
                        radial.ColorValues = new List<Int32>();
                        radial.RleCount = ReadHalfWord(stream);
                        radial.StartAngle = ReadHalfWord(stream) / 10D;
                        radial.AngleDelta = ReadHalfWord(stream) / 10D;

                        for (var j = 0; j < radial.RleCount * 2; j++)
                        {
                            var values = DecodeRLES(stream, descriptor);
                            radial.ColorValues.AddRange(values);
                        }

                        symbology.RadialData.Add(radial);
                    }
                }

                nexrad = new NexradScan { Header = header, Descriptor = descriptor, Symbology = symbology };
            }
            catch (Exception ex)
            {
                Console.WriteLine("Generic error while parsing Nexrad data", ex.ToString());
            }

            return nexrad;
        }