/// <summary> /// Reads the imaging information stored in the metafile stream. /// </summary> /// <returns>The imaging data.</returns> protected override RasterImaging ReadImagingInternal() { // read the device data. ImagingDevice device = ReadDeviceData(); XElement sceneSourceElement = _document.Element("Dimap_Document").Element("Dataset_Sources").Element("Source_Information").Element("Scene_Source"); // time DateTime imagingTime = DateTime.Parse(sceneSourceElement.Element("IMAGING_DATE").Value + " " + sceneSourceElement.Element("IMAGING_TIME").Value, CultureInfo.InvariantCulture.DateTimeFormat, DateTimeStyles.AssumeUniversal); // view Double incidenceAngle = Double.Parse(sceneSourceElement.Element("INCIDENCE_ANGLE").Value, NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat); Double viewingAngle = Double.Parse(sceneSourceElement.Element("VIEWING_ANGLE").Value, NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat); Double sunAzimuth = Double.Parse(sceneSourceElement.Element("SUN_AZIMUTH").Value, NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat); Double sunElevation = Double.Parse(sceneSourceElement.Element("SUN_ELEVATION").Value, NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat); // device location XElement ephemeris = _document.Element("Dimap_Document").Element("Data_Strip").Element("Ephemeris"); Double altitude = Double.Parse(ephemeris.Element("SATELLITE_ALTITUDE").Value, NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat); Double latitude = Double.Parse(ephemeris.Element("NADIR_LAT").Value, NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat); Double longitude = Double.Parse(ephemeris.Element("NADIR_LON").Value, NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat); GeoCoordinate deviceLocation = new GeoCoordinate(Angle.FromDegree(latitude), Angle.FromDegree(longitude), Length.FromMetre(altitude)); // image location List <GeoCoordinate> imageLocation = new List <GeoCoordinate>(4); foreach (XElement vertexElement in _document.Element("Dimap_Document").Element("Dataset_Frame").Elements("Vertex")) { GeoCoordinate coordinate = new GeoCoordinate(Double.Parse(vertexElement.Element("FRAME_LAT").Value, NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat), Double.Parse(vertexElement.Element("FRAME_LON").Value, NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat)); imageLocation.Add(coordinate); } // band parameters List <RasterImagingBand> bandData = new List <RasterImagingBand>(); foreach (XElement bandElement in _document.Element("Dimap_Document").Element("Image_Interpretation").Elements("Spectral_Band_Info")) { String bandIndex = bandElement.Element("BAND_INDEX").Value; Double physicalGain = Double.Parse(bandElement.Element("PHYSICAL_GAIN").Value, NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat); Double physicalBias = Double.Parse(bandElement.Element("PHYSICAL_BIAS").Value, NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat); // read the solar irradiance XElement solarIrradianceElement = _document.Element("Dimap_Document").Element("Data_Strip").Element("Sensor_Calibration").Element("Solar_Irradiance").Elements("Band_Solar_Irradiance").FirstOrDefault(elements => elements.Element("BAND_INDEX").Value.Equals(bandIndex)); Double solarIrradiance = 0; if (solarIrradianceElement != null) { solarIrradiance = Double.Parse(solarIrradianceElement.Element("SOLAR_IRRADIANCE_VALUE").Value, NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat); } // match the device band data ImagingDeviceBand deviceBand = null; if (device != null) { deviceBand = device.Bands.FirstOrDefault(band => band.Description.Contains(bandElement.Element("BAND_DESCRIPTION").Value)); } if (deviceBand != null) { bandData.Add(new RasterImagingBand(deviceBand.Description, physicalGain, physicalBias, solarIrradiance, deviceBand.SpectralDomain, deviceBand.SpectralRange)); } else // if no match is found { bandData.Add(new RasterImagingBand(bandElement.Element("BAND_DESCRIPTION").Value, physicalGain, physicalBias, solarIrradiance, SpectralDomain.Undefined, null)); } } return(new RasterImaging(device, imagingTime, deviceLocation, imageLocation, incidenceAngle, viewingAngle, sunAzimuth, sunElevation, bandData)); }
/// <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); }