/// <summary> /// Adds the specified geo-key to the directory. /// </summary> /// <param name="directory">The geo-key directory.</param> /// <param name="key">The key.</param> /// <param name="metadata">The geometry metadata.</param> /// <param name="tagName">The name of the tag.</param> private void AddGeoKey(GeoKeyDirectory directory, Int16 key, IDictionary <String, Object> metadata, String tagName) { if (metadata.ContainsKey(tagName)) { directory.Add(key, new Object[] { metadata[tagName] }); metadata.Remove(tagName); } }
/// <summary> /// Adds the specified geo-key to the metadata. /// </summary> /// <param name="directory">The geo-key directory.</param> /// <param name="geoKey">The geo-key.</param> /// <param name="metadata">The metadata.</param> /// <param name="metadataKey">The metadata key.</param> protected void AddMetadata(GeoKeyDirectory directory, Int16 geoKey, IDictionary <String, Object> metadata, String metadataKey) { if (directory == null || !metadata.ContainsKey(metadataKey)) { return; } metadata[metadataKey] = directory[geoKey]; }
/// <summary> /// Writes the geo-key directory into the Image File Directory. /// </summary> /// <param name="imageFileDirectory">The Image File Directory.</param> /// <param name="geoKeyDirectory">The geo-key directory.</param> private void WriteGeoKeyDirectory(TiffImageFileDirectory imageFileDirectory, GeoKeyDirectory geoKeyDirectory) { if (geoKeyDirectory.Count == 0) { return; } Object[] geoKeyDirectoryTag = new Object[(geoKeyDirectory.Count + 1) * 4]; List <Object> geoDoubleParamsTag = new List <Object>(); List <Object> geoAsciiParamsTag = new List <Object>(); // header data (version, revision, count) geoKeyDirectoryTag[0] = (Int16)1; geoKeyDirectoryTag[1] = (Int16)0; geoKeyDirectoryTag[2] = (Int16)0; geoKeyDirectoryTag[3] = (Int16)geoKeyDirectory.Count; // content Int32 byteIndex = 4; foreach (KeyValuePair <Int16, Object> geoData in geoKeyDirectory) { geoKeyDirectoryTag[byteIndex] = geoData.Key; geoKeyDirectoryTag[byteIndex + 1] = (UInt16)0; geoKeyDirectoryTag[byteIndex + 2] = (UInt16)1; if (geoData.Value is Int16) { geoKeyDirectoryTag[byteIndex + 3] = geoData.Value; } if (geoData.Value is Double) { geoDoubleParamsTag.Add(geoData.Value); } if (geoData.Value is String) { geoAsciiParamsTag.Add(geoData.Value); } byteIndex += 4; } imageFileDirectory.Add(TiffTag.GeoKeyDirectoryTag, geoKeyDirectoryTag); if (geoDoubleParamsTag.Count > 0) { imageFileDirectory.Add(TiffTag.GeoDoubleParamsTag, geoDoubleParamsTag.ToArray()); } if (geoAsciiParamsTag.Count > 0) { imageFileDirectory.Add(TiffTag.GeoAsciiParamsTag, geoAsciiParamsTag.ToArray()); } }
/// <summary> /// Computes the coordinate projection for the geo-key directory. /// </summary> /// <param name="geoKeyDirectory">The geo-key directory.</param> /// <param name="projection">The coordinate projection.</param> private void ComputeCoordinateProjection(GeoKeyDirectory geoKeyDirectory, CoordinateProjection projection) { if (projection.Code >= 10000 && projection.Code <= 19999) { geoKeyDirectory.Add(GeoKey.Projection, (Int16)projection.Code); return; } // user-defined projection geoKeyDirectory.Add(GeoKey.Projection, Int16.MaxValue); geoKeyDirectory.Add(GeoKey.ProjectionCoordinateTransformation, (Int16)projection.Method.Code); // TODO: process parameters }
/// <summary> /// Computes the projected coordinate reference system for the geo-key directory. /// </summary> /// <param name="geoKeyDirectory">The geo-key directory.</param> /// <param name="referenceSystem">The reference system.</param> private void ComputeProjectedCoordinateReferenceSystem(GeoKeyDirectory geoKeyDirectory, ProjectedCoordinateReferenceSystem referenceSystem) { geoKeyDirectory.Add(GeoKey.ModelType, (Int16)1); if (referenceSystem.Identifier != IdentifiedObject.UserDefinedIdentifier) { geoKeyDirectory.Add(GeoKey.ProjectedCoordinateReferenceSystemType, (Int16)referenceSystem.Code); // ProjectedCSTypeGeoKey return; } // user-defined reference system geoKeyDirectory.Add(GeoKey.ProjectedCoordinateReferenceSystemType, Int16.MaxValue); ComputeGeodeticCoordinateReferenceSystem(geoKeyDirectory, referenceSystem.Base); ComputeCoordinateProjection(geoKeyDirectory, referenceSystem.Projection); }
/// <summary> /// Computes the geokeys for the current raster. /// </summary> /// <exception cref="System.IO.InvalidDataException">Geo key data is in an invalid format.</exception> private void ComputeGeoKeys() { _currentGeoKeys = new GeoKeyDirectory(); // there are no geokeys in the file if (!_imageFileDirectories[_currentImageIndex].ContainsKey(TiffTag.GeoKeyDirectoryTag)) { return; } try { Object[] geokeyDirectory = _imageFileDirectories[_currentImageIndex][TiffTag.GeoKeyDirectoryTag]; _geoTiffFormatVersion = geokeyDirectory[0] + "." + geokeyDirectory[1] + "." + geokeyDirectory[2]; Int32 offset, count; for (Int16 i = 4; i < geokeyDirectory.Length; i += 4) { switch (Convert.ToInt32(geokeyDirectory[1 + i])) { case 0: _currentGeoKeys.Add(Convert.ToInt16(geokeyDirectory[i]), Convert.ToInt16(geokeyDirectory[3 + i])); break; case TiffTag.GeoDoubleParamsTag: offset = Convert.ToInt32(geokeyDirectory[3 + i]); Double doubleValue = Convert.ToDouble(_imageFileDirectories[_currentImageIndex][TiffTag.GeoDoubleParamsTag][offset]); _currentGeoKeys.Add(Convert.ToInt16(geokeyDirectory[i]), doubleValue); break; case TiffTag.GeoAsciiParamsTag: count = Convert.ToInt32(geokeyDirectory[2 + i]); offset = Convert.ToInt32(geokeyDirectory[3 + i]); // strings are concatenated to a single value using the | (pipe) character, so they are split, and the ending character is removed _currentGeoKeys.Add(Convert.ToInt16(geokeyDirectory[i]), Convert.ToString(_imageFileDirectories[_currentImageIndex][TiffTag.GeoAsciiParamsTag][0]).Substring(offset, count - 1)); break; } } } catch { throw new InvalidDataException("Geo key data is in an invalid format."); } }
/// <summary> /// Computes the Geodetic coordinate reference system for the geo-key directory. /// </summary> /// <param name="geoKeyDirectory">The geo-key directory.</param> /// <param name="referenceSystem">The reference system.</param> private void ComputeGeodeticCoordinateReferenceSystem(GeoKeyDirectory geoKeyDirectory, GeographicCoordinateReferenceSystem referenceSystem) { if (!geoKeyDirectory.ContainsKey(GeoKey.ModelType)) { geoKeyDirectory.Add(GeoKey.ModelType, (Int16)2); } if (referenceSystem.Identifier != IdentifiedObject.UserDefinedIdentifier) { geoKeyDirectory.Add(GeoKey.GeodeticCoordinateReferenceSystemType, (Int16)referenceSystem.Code); return; } // user-defined reference system geoKeyDirectory.Add(GeoKey.GeodeticCoordinateReferenceSystemType, Int16.MaxValue); // TODO: process user-defined reference system }
/// <summary> /// Computes the Image File Directory of a geometry. /// </summary> /// <param name="geometry">The geometry.</param> /// <param name="compression">The compression.</param> /// <param name="format">The sample format.</param> /// <param name="startPosition">The starting position of the raster content within the stream.</param> /// <param name="endPosition">The ending position of the raster content within the stream.</param> /// <returns>The computed Image File Directory.</returns> protected override TiffImageFileDirectory ComputeImageFileDirectory(ISpectralGeometry geometry, TiffCompression compression, TiffSampleFormat format) { TiffImageFileDirectory imageFileDirectory = base.ComputeImageFileDirectory(geometry, compression, format); CoordinateReferenceSystem referenceSystem = geometry.ReferenceSystem as CoordinateReferenceSystem; GeoKeyDirectory geoKeyDirectory = new GeoKeyDirectory(); AddGeoKey(geoKeyDirectory, GeoKey.Citation, geometry.Metadata, "GeoTIFF::GeoCitation"); AddGeoKey(geoKeyDirectory, GeoKey.GeodeticCoordinateReferenceSystemCitation, geometry.Metadata, "GeoTIFF::GeodeticCoordinateReferenceSystemCitation"); AddGeoKey(geoKeyDirectory, GeoKey.ProjectedCoordinateReferenceSystemCitation, geometry.Metadata, "GeoTIFF::ProjectedCoordinateReferenceSystemCitation"); if (geometry.Raster.Mapper != null) // if mapper is available { geoKeyDirectory.Add(GeoKey.RasterType, (Int16)((geometry.Raster.Mapper.Mode == RasterMapMode.ValueIsArea) ? 1 : 2)); imageFileDirectory.Add(TiffTag.ModelTiepointTag, new Object[] { 0.0, 0.0, 0.0, geometry.Raster.Mapper.Translation.X, geometry.Raster.Mapper.Translation.Y, 0.0 }); imageFileDirectory.Add(TiffTag.ModelPixelScaleTag, new Object[] { geometry.Raster.Mapper.ColumnSize, geometry.Raster.Mapper.RowSize, 1.0 }); } if (referenceSystem != null) // if reference system is available (and supported) { switch (referenceSystem.Type) { case ReferenceSystemType.Projected: ComputeProjectedCoordinateReferenceSystem(geoKeyDirectory, referenceSystem as ProjectedCoordinateReferenceSystem); break; case ReferenceSystemType.Geographic2D: case ReferenceSystemType.Geographic3D: ComputeGeodeticCoordinateReferenceSystem(geoKeyDirectory, referenceSystem as GeographicCoordinateReferenceSystem); break; default: // other reference systems are not supported return(imageFileDirectory); } } WriteGeoKeyDirectory(imageFileDirectory, geoKeyDirectory); if (geometry.Imaging != null) // add imaging data { imageFileDirectory.Add(57410, new Object[] { geometry.Imaging.Device.Name }); imageFileDirectory.Add(57411, new Object[] { geometry.Imaging.Time.ToString(CultureInfo.InvariantCulture.DateTimeFormat) }); imageFileDirectory.Add(57412, new Object[] { geometry.Imaging.DeviceLocation.Latitude.BaseValue, geometry.Imaging.DeviceLocation.Longitude.BaseValue, geometry.Imaging.DeviceLocation.Height.BaseValue }); imageFileDirectory.Add(57413, new Object[] { geometry.Imaging.IncidenceAngle, geometry.Imaging.ViewingAngle, geometry.Imaging.SunAzimuth, geometry.Imaging.SunElevation }); imageFileDirectory.Add(57417, geometry.Imaging.Bands.Select(band => band.PhysicalGain).Cast <Object>().ToArray()); imageFileDirectory.Add(57418, geometry.Imaging.Bands.Select(band => band.PhysicalBias).Cast <Object>().ToArray()); imageFileDirectory.Add(57419, geometry.Imaging.Bands.Select(band => band.SolarIrradiance).Cast <Object>().ToArray()); Object[] imageLocation = new Object[12]; for (Int32 coordinateIndex = 0; coordinateIndex < geometry.Imaging.ImageLocation.Count; coordinateIndex++) { imageLocation[3 * coordinateIndex] = geometry.Imaging.ImageLocation[coordinateIndex].Latitude.BaseValue; imageLocation[3 * coordinateIndex + 1] = geometry.Imaging.ImageLocation[coordinateIndex].Longitude.BaseValue; imageLocation[3 * coordinateIndex + 2] = geometry.Imaging.ImageLocation[coordinateIndex].Height.BaseValue; } imageFileDirectory.Add(57420, imageLocation); } return(imageFileDirectory); }