public GroupData() { SatelliteName = "Unknown"; RegionName = "Unknown"; SatelliteLongitude = 0f; FrameTime = DateTime.Now; Visible = new OrganizerData(); Infrared = new OrganizerData(); WaterVapour = new OrganizerData(); OtherData = new Dictionary <string, OrganizerData>(); IsFalseColorProcessed = false; IsVisibleProcessed = false; IsInfraredProcessed = false; IsWaterVapourProcessed = false; IsProcessed = false; Failed = false; RetryCount = 0; CropImage = false; Created = LLTools.Timestamp(); ColumnOffset = -1; LineOffset = -1; ColumnScalingFactor = 0f; LineScalingFactor = 0f; Code = DateTime.UtcNow.ToString(); HasNavigationData = false; }
private void GenerateImageOverlay(ref Bitmap bmp, GroupData gd, OrganizerData od) { var columnOffset = od.ColumnOffset != -1 ? od.ColumnOffset : gd.FallBackColumnOffset; var lineOffset = od.LineOffset != -1 ? od.LineOffset : gd.FallBackLineOffset; var columnScalingFactor = od.ColumnScalingFactor != 0 ? od.ColumnScalingFactor : gd.FallBackColumnScalingFactor; var lineScalingFactor = od.LineScalingFactor != 0 ? od.LineScalingFactor : gd.FallBackLineScalingFactor; if (gd.HasNavigationData) { var gc = new GeoConverter(gd.SatelliteLongitude, columnOffset, lineOffset, columnScalingFactor, lineScalingFactor, true, od.Columns); if (mapDrawer != null && GenerateMapOverlays) { mapDrawer.DrawMap(ref bmp, gc, MapOverlayPenColor, MapOverlayPenThickness, gd.CropImage); } if (GenerateLatLonOverlays) { ImageTools.DrawLatLonLines(ref bmp, gc, LatLonOverlayPenColor, LatLonOverlayPenThickness, gd.CropImage); } if (EnableReproject) { var reprojBmp = ImageTools.ReprojectLinear(bmp, gc, gd.CropImage); bmp.Dispose(); bmp = reprojBmp; } if (GenerateLabels) { ImageTools.ImageLabel(ref bmp, gd, od, gc, GenerateLatLonLabel); } } else if (GenerateLabels) { ImageTools.ImageLabel(ref bmp, gd, od, null, false); } }
private void GenerateImageOverlay(ref Bitmap bmp, GroupData gd, OrganizerData od) { if (gd.HasNavigationData) { var gc = new GeoConverter(gd.SatelliteLongitude, gd.ColumnOffset, gd.LineOffset, gd.ColumnScalingFactor, gd.LineScalingFactor, true, od.Columns); if (mapDrawer != null && GenerateMapOverlays) { mapDrawer.DrawMap(ref bmp, gc, MapOverlayPenColor, MapOverlayPenThickness, gd.CropImage); } if (GenerateLatLonOverlays) { ImageTools.DrawLatLonLines(ref bmp, gc, LatLonOverlayPenColor, LatLonOverlayPenThickness, gd.CropImage); } if (GenerateLabels) { ImageTools.ImageLabel(ref bmp, gd, od, gc, GenerateLatLonLabel); } } else if (GenerateLabels) { ImageTools.ImageLabel(ref bmp, gd, od, null, false); } }
public void Update() { try { List <string> files = Directory.GetFiles(folder).Where(f => f.EndsWith(".lrit")).ToList(); foreach (string file in files) { if (alreadyProcessed.Contains(file)) { continue; } try { var header = FileParser.GetHeaderFromFile(file); var anciliary = header.AncillaryHeader != null ? header.AncillaryHeader.Values : null; var satellite = "Unknown"; var region = "Unknown"; var satLon = 0f; var datetime = header.TimestampHeader.DateTime; // Defaults to capture time var channel = 99; var segmentId = header.SegmentIdentificationHeader != null ? header.SegmentIdentificationHeader.Sequence : 0; var imageKey = header.SegmentIdentificationHeader != null ? header.SegmentIdentificationHeader.ImageID : -1; if (header.Product.ID == (int)NOAAProductID.HIMAWARI8_ABI) { channel = header.SubProduct.ID; satellite = "HIMAWARI8"; region = "Full Disk"; } var rgx = new Regex(@".*\((.*)\)", RegexOptions.IgnoreCase); var regMatch = rgx.Match(header.ImageNavigationHeader.ProjectionName); satLon = float.Parse(regMatch.Groups[1].Captures[0].Value, CultureInfo.InvariantCulture); if (anciliary != null) { if (anciliary.ContainsKey("Satellite")) { satellite = anciliary["Satellite"]; } if (anciliary.ContainsKey("Region")) { region = anciliary["Region"]; } if (anciliary.ContainsKey("Channel")) { channel = int.Parse(anciliary["Channel"]); } if (anciliary.ContainsKey("Time of frame start")) { var dtstring = anciliary["Time of frame start"]; // 2017/055/05:45:18 // or // 2017-03-27T15:45:38.2Z if (dtstring[4] == '/') { var year = dtstring.Substring(0, 4); var dayOfYear = dtstring.Substring(5, 3); var hours = dtstring.Substring(9, 2); var minutes = dtstring.Substring(12, 2); var seconds = dtstring.Substring(15, 2); //Console.WriteLine("Year: {0}\nDay Of Year: {1}\nHours: {2}\nMinutes: {3}\nSeconds: {4}", year, dayOfYear, hours, minutes, seconds); datetime = new DateTime(int.Parse(year), 1, 1, int.Parse(hours), int.Parse(minutes), int.Parse(seconds)); datetime = datetime.AddDays(int.Parse(dayOfYear)); } else { datetime = DateTime.Parse(dtstring, null, DateTimeStyles.RoundtripKind); } } else { UIConsole.Debug("No Frame Time of Start found! Using capture time."); } } var cropSection = region.ToLower().Contains("full disk") || header.IsFullDisk; int timestamp = 0; if (datetime.Year < 2005 && file.Contains("OR_ABI")) { // Timestamp bug on G16 imageKey = header.SegmentIdentificationHeader != null ? header.SegmentIdentificationHeader.ImageID : (int)Math.Floor((datetime - UnixEpoch).TotalSeconds); timestamp = (int)Math.Floor((datetime - UnixEpoch).TotalSeconds); } else if (datetime.Year < 2005 && file.Contains("IMG_DK")) { // Himawari-8 relay BUG //IMG_DK01VIS_201704161550 string bfile = Path.GetFileName(file); string hdt = bfile.Substring(12, 12); var year = hdt.Substring(0, 4); var month = hdt.Substring(4, 2); var day = hdt.Substring(6, 2); var hour = hdt.Substring(8, 2); var minute = hdt.Substring(10, 2); datetime = new DateTime(int.Parse(year), int.Parse(month), int.Parse(day), int.Parse(hour), int.Parse(minute), 0); imageKey = timestamp = (int)Math.Floor((datetime - UnixEpoch).TotalSeconds); } else { imageKey = timestamp = (int)Math.Floor((datetime - UnixEpoch).TotalSeconds); } if (!groupData.ContainsKey(imageKey)) { groupData[imageKey] = new GroupData(); } var grp = groupData[imageKey]; grp.SatelliteName = satellite; grp.RegionName = region; grp.FrameTime = datetime; if (segmentId == 0) { grp.CropImage = cropSection; grp.SatelliteLongitude = satLon; if ( header.ImageNavigationHeader != null && header.ImageNavigationHeader.ColumnScalingFactor != 0 && header.ImageNavigationHeader.LineScalingFactor != 0 ) { grp.HasNavigationData = true; grp.ColumnScalingFactor = header.ImageNavigationHeader.ColumnScalingFactor; grp.LineScalingFactor = header.ImageNavigationHeader.LineScalingFactor; grp.ColumnOffset = grp.ColumnOffset == -1 ? header.ImageNavigationHeader.ColumnOffset : grp.ColumnOffset; grp.LineOffset = grp.LineOffset == -1 ? header.ImageNavigationHeader.LineOffset : grp.LineOffset; } } grp.Code = header.SegmentIdentificationHeader != null ? header.SegmentIdentificationHeader.ImageID + "_" + header.SubProduct.Name : header.Product.Name + "_" + header.SubProduct.Name; var od = new OrganizerData(); string z; switch (channel) { case 1: // Visible od = grp.Visible; break; case 2: // Visible for G16 if (satellite == "G16") { od = grp.Visible; } else { string p = $"{timestamp%1000}-{((NOAAProductID)header.Product.ID).ToString()}-{header.SubProduct.Name}"; if (!grp.OtherData.ContainsKey(p)) { grp.OtherData.Add(p, new OrganizerData()); } od = grp.OtherData[p]; } break; case 3: // Water Vapour od = satellite == "HIMAWARI8" ? grp.Infrared : grp.WaterVapour; break; case 4: // Infrared od = grp.Infrared; break; case 7: if (satellite == "HIMAWARI8") { od = grp.WaterVapour; break; } z = $"{timestamp%1000}-{((NOAAProductID)header.Product.ID).ToString()}-{header.SubProduct.Name}"; if (!grp.OtherData.ContainsKey(z)) { grp.OtherData.Add(z, new OrganizerData()); } od = grp.OtherData[z]; break; case 8: if (satellite == "G16") { od = grp.WaterVapour; break; } z = $"{timestamp%1000}-{((NOAAProductID)header.Product.ID).ToString()}-{header.SubProduct.Name}"; if (!grp.OtherData.ContainsKey(z)) { grp.OtherData.Add(z, new OrganizerData()); } od = grp.OtherData[z]; break; case 13: // Infrared for G16 if (satellite == "G16") { od = grp.Infrared; break; } z = $"{timestamp%1000}-{((NOAAProductID)header.Product.ID).ToString()}-{header.SubProduct.Name}"; if (!grp.OtherData.ContainsKey(z)) { grp.OtherData.Add(z, new OrganizerData()); } od = grp.OtherData[z]; break; default: z = $"{timestamp%1000}-{((NOAAProductID)header.Product.ID).ToString()}-{header.SubProduct.Name}"; if (!grp.OtherData.ContainsKey(z)) { grp.OtherData.Add(z, new OrganizerData()); } od = grp.OtherData[z]; break; } od.Code = grp.Code; od.Timestamp = timestamp; od.Segments[segmentId] = file; od.FirstSegment = Math.Min(od.FirstSegment, segmentId); od.FileHeader = header; if (od.Columns == -1) { od.Columns = header.ImageStructureHeader.Columns; od.Lines = header.ImageStructureHeader.Lines; od.PixelAspect = header.ImageNavigationHeader.ColumnScalingFactor / (float)header.ImageNavigationHeader.LineScalingFactor; od.ColumnOffset = header.ImageNavigationHeader.ColumnOffset; od.MaxSegments = header.SegmentIdentificationHeader != null ? header.SegmentIdentificationHeader.MaxSegments : 1; } else { od.Lines += header.ImageStructureHeader.Lines; } alreadyProcessed.Add(file); } catch (Exception e) { UIConsole.Error($"Error reading file {Path.GetFileName(file)}: {e}"); alreadyProcessed.Add(file); } } } catch (Exception e) { UIConsole.Error($"Error checking folders: {e}"); } }
public static void ImageLabel(ref Bitmap inbmp, GroupData gd, OrganizerData od, GeoConverter gc, bool genLatLonLabel) { var usedFontSize = FONT_SIZES [0]; if (inbmp.Width >= 4000) { usedFontSize = FONT_SIZES [3]; } else if (inbmp.Width >= 2000) { usedFontSize = FONT_SIZES [2]; } else if (inbmp.Width >= 1000) { usedFontSize = FONT_SIZES [1]; } var bgBrush = new SolidBrush(Color.Black); var font = new Font("Arial", usedFontSize); var fontBrush = new SolidBrush(Color.White); var upperText = $"{gd.SatelliteName} ({gd.SatelliteLongitude}) - {gd.RegionName}"; var usedLabelSize = PADDING * 2; using (var g = Graphics.FromImage(inbmp)) { usedLabelSize += (int)Math.Round(g.MeasureString(upperText, font).Height); } var bmp = new Bitmap(inbmp.Width, inbmp.Height + ((genLatLonLabel && gc != null) ? usedLabelSize * 3 : usedLabelSize * 2), inbmp.PixelFormat); var sf = new StringFormat { LineAlignment = StringAlignment.Center, Alignment = StringAlignment.Center }; if (od.FileHeader != null && od.FileHeader.SubProduct.Name != "None") { upperText = upperText + " - " + od.FileHeader.SubProduct.Name; } var dt = LLTools.UnixTimeStampToDateTime(od.Timestamp); var lowerText = $"{dt.ToShortDateString ()} {dt.ToLongTimeString()} UTC - {OSPLABEL}"; using (var g = Graphics.FromImage(bmp)) { g.CompositingQuality = CompositingQuality.HighQuality; g.FillRectangle(bgBrush, 0, 0, bmp.Width, bmp.Height); g.DrawImage(inbmp, 0, usedLabelSize, inbmp.Width, inbmp.Height); // Upper Label // var textSize = g.MeasureString (upperText, font); var rect = new RectangleF(PADDING, 0, bmp.Width - PADDING * 2, usedLabelSize); g.DrawString(upperText, font, fontBrush, rect, sf); // Lower Label with Lat/Lon if (genLatLonLabel && gc != null) { var latlon = gc.xy2latlon(inbmp.Width / 2, inbmp.Height / 2); var lat = latlon.Item1.ToString("##.000000", CultureInfo.InvariantCulture); var lon = latlon.Item2.ToString("##.000000", CultureInfo.InvariantCulture); var latLonText = $"Center Coord: ({lat}; {lon})"; lowerText += $"\r\n{latLonText}"; // textSize = g.MeasureString (lowerText, font); rect = new RectangleF(PADDING, usedLabelSize + inbmp.Height, bmp.Width - PADDING * 2, usedLabelSize * 2); g.DrawString(lowerText, font, fontBrush, rect, sf); } else // Lower Label without Lat/Lon // textSize = g.MeasureString (lowerText, font); { rect = new RectangleF(PADDING, usedLabelSize + inbmp.Height, bmp.Width - PADDING * 2, usedLabelSize); g.DrawString(lowerText, font, fontBrush, rect, sf); } } inbmp.Dispose(); inbmp = bmp; }
/// <summary> /// Generates the full image represented on OrganizedData /// </summary> /// <returns>The full image</returns> /// <param name="data">The Organizer Data</param> public static Bitmap GenerateFullImage(OrganizerData data, bool crop = false) { var bmp = new Bitmap(data.Columns, data.Lines, PixelFormat.Format8bppIndexed); var pal = bmp.Palette; // Standard grayscale palette for (var i = 0; i <= 255; i++) { pal.Entries[i] = Color.FromArgb(i, i, i); } bmp.Palette = pal; var lineOffset = 0; var pdata = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed); // Dump files to bitmap for (var i = 0; i < data.Segments.Count; i++) { var filename = data.Segments[data.FirstSegment + i]; var header = FileParser.GetHeaderFromFile(filename); var width = header.ImageStructureHeader.Columns; var height = header.ImageStructureHeader.Lines; var bytesToRead = (width * height); var buffer = new byte[bytesToRead]; // Read data var file = File.OpenRead(filename); file.Seek(header.PrimaryHeader.HeaderLength, SeekOrigin.Begin); file.Read(buffer, 0, bytesToRead); file.Close(); // Write data to image if (pdata.Stride == width) { Marshal.Copy(buffer, 0, IntPtr.Add(pdata.Scan0, lineOffset * pdata.Stride), buffer.Length); lineOffset += height; } else { // So our stride is bigger than our width (alignment issues). So let's copy line by line. for (var z = 0; z < height; z++) { Marshal.Copy(buffer, width * z, IntPtr.Add(pdata.Scan0, lineOffset * pdata.Stride), width); lineOffset += 1; } } } bmp.UnlockBits(pdata); // Crop if (crop && data.ColumnOffset > 0) { var sc = (int)data.ColumnOffset; var hw = (int)Math.Min(data.Columns - sc, sc); var cl = (int)data.ColumnOffset - hw; var cf = cl + 2 * hw; bmp = bmp.Crop(cl, 0, cf - cl, bmp.Height, true); } // Resize to match pixel aspect var newHeight = (int)Math.Round(bmp.Height * data.PixelAspect); bmp = ResizeImage(bmp, bmp.Width, newHeight, true); return(bmp); }