/// <summary> /// Reads the imaging information stored in the metafile stream. /// </summary> /// <returns>The imaging data.</returns> protected override RasterImaging ReadImagingInternal() { ReadContent(); // read the device data ImagingDevice device = ReadDeviceInternal(); // time DateTime imagingDateTime = DateTime.Parse(_metadata["DATE_ACQUIRED"] + " " + _metadata["SCENE_CENTER_TIME"], CultureInfo.InvariantCulture.DateTimeFormat, DateTimeStyles.AssumeUniversal); // view Double incidenceAngle = Double.NaN; Double viewingAngle = _metadata.ContainsKey("ROLL_ANGLE") ? Double.Parse(_metadata["ROLL_ANGLE"], NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat) : Double.NaN; // only Landsat 8 contains the roll angle property Double sunAzimuth = Double.Parse(_metadata["SUN_AZIMUTH"], NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat); Double sunElevation = Double.Parse(_metadata["SUN_ELEVATION"], NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat); // image location GeoCoordinate[] imageLocation = new GeoCoordinate[] { new GeoCoordinate(Double.Parse(_metadata["CORNER_UL_LAT_PRODUCT"], NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat), Double.Parse(_metadata["CORNER_UL_LON_PRODUCT"], NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat)), new GeoCoordinate(Double.Parse(_metadata["CORNER_UR_LAT_PRODUCT"], NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat), Double.Parse(_metadata["CORNER_UR_LON_PRODUCT"], NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat)), new GeoCoordinate(Double.Parse(_metadata["CORNER_LL_LAT_PRODUCT"], NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat), Double.Parse(_metadata["CORNER_LL_LON_PRODUCT"], NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat)), new GeoCoordinate(Double.Parse(_metadata["CORNER_LR_LAT_PRODUCT"], NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat), Double.Parse(_metadata["CORNER_LR_LON_PRODUCT"], NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat)) }; // band parameters List <RasterImagingBand> bandData = new List <RasterImagingBand>(); Int32 numberOfBands = 0; Double[] solarIrradiance = null; switch (device.MissionNumber) { case 7: numberOfBands = 8; // solar irradiance is constant for Landsat 7, see: http://landsathandbook.gsfc.nasa.gov/pdfs/Landsat_Calibration_Summary_RSE.pdf solarIrradiance = new Double[] { 1997, 1812, 1533, 1039, 230.8, Double.NaN, 84.9, 1362 }; break; case 8: numberOfBands = 11; // solar irradiance is not provided for Landsat 8, see: http://landsat.usgs.gov/ESUN.php solarIrradiance = Enumerable.Repeat(Double.NaN, 11).ToArray(); break; } for (Int32 bandNumber = 1; bandNumber <= numberOfBands; bandNumber++) { String indexString = bandNumber.ToString(); if (device.MissionNumber == 7 && bandNumber == 6) // Landsat 7 band 6 has high gain and low gain modes { indexString += "_VCID_1"; } Double maximumRadiance = Double.Parse(_metadata["RADIANCE_MAXIMUM_BAND_" + indexString], NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat); Double minimumRadiance = Double.Parse(_metadata["RADIANCE_MINIMUM_BAND_" + indexString], NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat); Double qCalMax = Double.Parse(_metadata["QUANTIZE_CAL_MAX_BAND_" + indexString], NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat); Double qCalMin = Double.Parse(_metadata["QUANTIZE_CAL_MIN_BAND_" + indexString], NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat); Double physicalGain = (maximumRadiance - minimumRadiance) / (qCalMax - qCalMin); Double physicalBias = minimumRadiance; // match the device band data ImagingDeviceBand deviceBand = null; if (device != null) { deviceBand = device.Bands.FirstOrDefault(band => band.Description.Contains("BAND " + bandNumber)); } if (deviceBand != null) { bandData.Add(new RasterImagingBand(deviceBand.Description, physicalGain, physicalBias, solarIrradiance[bandNumber - 1], deviceBand.SpectralDomain, deviceBand.SpectralRange)); } else // if no match is found { bandData.Add(new RasterImagingBand("BAND " + bandNumber, physicalGain, physicalBias, solarIrradiance[bandNumber - 1], SpectralDomain.Undefined, null)); } } RasterImaging imaging = new RasterImaging(device, imagingDateTime, GeoCoordinate.Undefined, imageLocation, incidenceAngle, viewingAngle, sunAzimuth, sunElevation, bandData); foreach (String key in _metadata.Keys) { if (_imagingPropertyKeys.Contains(key)) { imaging[key] = _metadata[key]; } } return(imaging); }
/// <summary> /// Creates a metafile reader for the specified metafile path and device. /// </summary> /// <param name="device">The imaging device.</param> /// <param name="path">The path of the metafile.</param> /// <returns>The valid metafile reader for the path if any; otherwise, <c>null</c>.</returns> /// <exception cref="System.ArgumentNullException"> /// The path is null. /// or /// The device is null. /// </exception> /// <exception cref="System.ArgumentException"> /// The path is empty. /// or /// The path is invalid. /// or /// The path is a zero-length string, contains only white space, or contains one or more invalid characters. /// or /// The path, file name, or both exceed the system-defined maximum length. /// </exception> /// <exception cref="System.UnauthorizedAccessException"> /// The file on path is hidden. /// or /// The file on path is read-only. /// or /// The caller does not have the required permission for the path. /// </exception> /// <exception cref="System.NotSupportedException">The specified device is not supported.</exception> /// <exception cref="System.IO.FileNotFoundException">The metafile does not exist.</exception> public static GeoTiffMetafileReader CreateReader(ImagingDevice device, String path) { return(CreateReader(device, new Uri(path, UriKind.RelativeOrAbsolute))); }