Skip to content

Commit

Permalink
Reading CoordinateSystemId and other GeoTiff attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
fabric-io-rodrigues committed May 4, 2022
1 parent 3d12846 commit efac2b5
Show file tree
Hide file tree
Showing 11 changed files with 423 additions and 30 deletions.
182 changes: 172 additions & 10 deletions GeoTiffCOG/GeoTiff.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class GeoTiff
string _tiffPath;
TraceTiffErrorHandler _traceLogHandler = new TraceTiffErrorHandler();
Dictionary<int, byte[]> tilesCache;
public FileMetadata metadata { get; private set; }
public Metadata metadata { get; private set; }

internal Tiff TiffFile
{
Expand Down Expand Up @@ -286,9 +286,10 @@ private GDALMetaData ParseXml(string xml)

return gdal;
}
private FileMetadata ParseMetaData(DEMFileDefinition format)

private Metadata ParseMetaData(DEMFileDefinition format)
{
FileMetadata _metadata = new FileMetadata(FilePath, format);
Metadata _metadata = new Metadata(FilePath, format);

_metadata.Height = TiffFile.GetField(TiffTag.IMAGELENGTH)[0].ToInt();
_metadata.Width = TiffFile.GetField(TiffTag.IMAGEWIDTH)[0].ToInt();
Expand Down Expand Up @@ -347,29 +348,190 @@ private FileMetadata ParseMetaData(DEMFileDefinition format)
_metadata.BitsPerSample = TiffFile.GetField(TiffTag.BITSPERSAMPLE)[0].ToInt();
var sampleFormat = TiffFile.GetField(TiffTag.SAMPLEFORMAT);
_metadata.SampleFormat = sampleFormat[0].Value.ToString();
_metadata.WorldUnits = "meter";

LoadGEOTiffTags(_metadata);

return _metadata;
}

private void LoadGEOTiffTags(Metadata _metadata)
{
//defaults
_metadata.Properties.CoordinateSystemId = 4326; // WGS 84
_metadata.Properties.ModelType = ModelType.Geographic;
_metadata.Properties.RasterType = RasterType.RasterPixelIsArea;
_metadata.Properties.AngularUnit = AngularUnits.Degree;

var geoKeys = TiffFile.GetField((TiffTag)GEOTIFF_TAGS.GEOTIFF_GEOKEYDIRECTORYTAG);
if (geoKeys != null)
{
var geoDoubleParams = TiffFile.GetField((TiffTag)GEOTIFF_TAGS.GEOTIFF_GEODOUBLEPARAMSTAG);
double[] doubleParams = null;
if (geoDoubleParams != null)
{
doubleParams = geoDoubleParams[1].ToDoubleArray();
}
var geoAsciiParams = TiffFile.GetField((TiffTag)GEOTIFF_TAGS.GEOTIFF_GEOASCIIPARAMSTAG);
if (geoAsciiParams != null) _metadata.Properties.GeotiffAsciiParams = geoAsciiParams[1].ToString().Trim('\0');

// Array of GeoTIFF GeoKeys values
var keys = geoKeys[1].ToUShortArray();
if (keys.Length > 4)
{
// Header={KeyDirectoryVersion, KeyRevision, MinorRevision, NumberOfKeys}
var keyDirectoryVersion = keys[0];
var keyRevision = keys[1];
var minorRevision = keys[2];
var numberOfKeys = keys[3];
for (var keyIndex = 4; keyIndex < keys.Length;)
{
switch (keys[keyIndex])
{
case (ushort)GeoTiffKey.GTModelTypeGeoKey:
{
_metadata.Properties.ModelType = (ModelType)keys[keyIndex + 3];
keyIndex += 4;
break;
}
case (ushort)GeoTiffKey.GTRasterTypeGeoKey:
{
_metadata.Properties.RasterType = (RasterType)keys[keyIndex + 3];
keyIndex += 4;
break;
}
case (ushort)GeoTiffKey.GTCitationGeoKey:
{
_metadata.Properties.GTCitationGeo = keys[keyIndex + 3];
keyIndex += 4;
break;
}
case (ushort)GeoTiffKey.GeographicTypeGeoKey:
{
_metadata.Properties.CoordinateSystemId = keys[keyIndex + 3]; //geographicType
keyIndex += 4;
break;
}
case (ushort)GeoTiffKey.GeogCitationGeoKey:
{
_metadata.Properties.GeogCitation = keys[keyIndex + 3];
keyIndex += 4;
break;
}
case (ushort)GeoTiffKey.GeogGeodeticDatumGeoKey:
{
// 6.3.2.2 Geodetic Datum Codes
_metadata.Properties.GeodeticDatum = keys[keyIndex + 3];
keyIndex += 4;
break;
}
case (ushort)GeoTiffKey.GeogPrimeMeridianGeoKey:
{
// 6.3.2.4 Prime Meridian Codes
_metadata.Properties.PrimeMeridian = keys[keyIndex + 3];
keyIndex += 4;
break;
}
case (ushort)GeoTiffKey.GeogAngularUnitsGeoKey:
{
_metadata.Properties.AngularUnit = (AngularUnits)keys[keyIndex + 3];
keyIndex += 4;
break;
}
case (ushort)GeoTiffKey.GeogAngularUnitSizeGeoKey:
{
keyIndex += 4;
break;
}
case (ushort)GeoTiffKey.GeogEllipsoidGeoKey:
{
// 6.3.2.3 Ellipsoid Codes
_metadata.Properties.Ellipsoid = keys[keyIndex + 3];
keyIndex += 4;
break;
}
case (ushort)GeoTiffKey.GeogSemiMajorAxisGeoKey:
{
if (doubleParams != null)
_metadata.Properties.SemiMajorAxis = doubleParams[keys[keyIndex + 3]];
keyIndex += 4;
break;
}
case (ushort)GeoTiffKey.GeogSemiMinorAxisGeoKey:
{
if (doubleParams != null)
_metadata.Properties.SemiMinorAxis = doubleParams[keys[keyIndex + 3]];
keyIndex += 4;
break;
}
case (ushort)GeoTiffKey.GeogInvFlatteningGeoKey:
{
if (doubleParams != null)
_metadata.Properties.InvFlattening = doubleParams[keys[keyIndex + 3]];
keyIndex += 4;
break;
}
case (ushort)GeoTiffKey.GeogAzimuthUnitsGeoKey:
{
_metadata.Properties.AngularUnit = (AngularUnits)keys[keyIndex + 3];
keyIndex += 4;
break;
}
case (ushort)GeoTiffKey.GeogPrimeMeridianLongGeoKey:
{
_metadata.Properties.PrimeMeridianLong = keys[keyIndex + 3];
keyIndex += 4;
break;
}
case (ushort)GeoTiffKey.ProjectedCSTypeGeoKey:
{
_metadata.Properties.CoordinateSystemId = keys[keyIndex + 3]; //projectedCSType
keyIndex += 4;
break;
}
case (ushort)GeoTiffKey.PCSCitationGeoKey:
{
keyIndex += 4;
break;
}
case (ushort)GeoTiffKey.ProjLinearUnitsGeoKey:
{
_metadata.Properties.LinearUnit = (LinearUnits)keys[keyIndex + 3];
keyIndex += 4;
break;
}
default:
{
// Just skipping all unprocessed keys
keyIndex += 4;
break;
}
}
}

}

}

// TIFF Tag GDAL_METADATA 42112
_metadata.Scale = 1;
var tag42112 = TiffFile.GetField((TiffTag)42112);
var tag42112 = TiffFile.GetField((TiffTag)GEOTIFF_TAGS.GEOTIFF_GDAL_METADATA);
if (tag42112 != null && tag42112.Length >= 1)
{
var xml = tag42112[1].ToString().Trim('\0');
var gd = ParseXml(xml);
_metadata.Properties.GdalMetadata = tag42112[1].ToString().Trim('\0');
var gd = ParseXml(_metadata.Properties.GdalMetadata);
_metadata.Offset = gd.Offset;
_metadata.Scale = gd.Scale;
}

// TIFF Tag GDAL_NODATA 42113
_metadata.NoDataValue = "-10000";
var tag42113 = TiffFile.GetField((TiffTag)42113);
var tag42113 = TiffFile.GetField((TiffTag)GEOTIFF_TAGS.GEOTIFF_GDAL_NODATA);
if (tag42113 != null && tag42113.Length >= 1)
{
_metadata.NoDataValue = tag42113[1].ToString().Trim('\0');
}

return _metadata;
}

public HeightMap GetHeightMapInBBox(BoundingBox bbox, float noDataValue = 0)
{
int yStart = 0;
Expand Down
9 changes: 8 additions & 1 deletion GeoTiffCOG/GeoTiffCOG.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,26 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Struture\AngularUnits.cs" />
<Compile Include="Struture\BoundingBox.cs" />
<Compile Include="Struture\DEMFileDefinition.cs" />
<Compile Include="Struture\DEMFileRegistrationMode.cs" />
<Compile Include="Struture\DEMFileType.cs" />
<Compile Include="Struture\FileMetaData.cs" />
<Compile Include="Struture\GEOTiffProperties.cs" />
<Compile Include="Struture\MetaData.cs" />
<Compile Include="Struture\GeoPoint.cs" />
<Compile Include="GeoTiff.cs" />
<Compile Include="Struture\GeoTiffKey.cs" />
<Compile Include="Struture\GEOTIFF_TAGS.cs" />
<Compile Include="Struture\HeightMap.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Struture\LinearUnits.cs" />
<Compile Include="Struture\MetaDataRaster.cs" />
<Compile Include="Struture\ModelType.cs" />
<Compile Include="Struture\RasterOutputType.cs" />
<Compile Include="Struture\RasterSampleFormat.cs" />
<Compile Include="RasterServices.cs" />
<Compile Include="Struture\RasterType.cs" />
<Compile Include="Struture\TraceTiffErrorHandler.cs" />
<Compile Include="TiffSteamCustom.cs" />
<Compile Include="Utils.cs" />
Expand Down
20 changes: 20 additions & 0 deletions GeoTiffCOG/Struture/AngularUnits.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GeoTiffCOG.Struture
{
public enum AngularUnits
{
Radian = 9101,
Degree = 9102,
ArcMinute = 9103,
ArcSecond = 9104,
Grad = 9105,
Gon = 9106,
DMS = 9107,
DMSHemisphere = 9108,
}
}
47 changes: 47 additions & 0 deletions GeoTiffCOG/Struture/GEOTIFF_TAGS.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GeoTiffCOG.Struture
{
enum GEOTIFF_TAGS
{
/// <summary>
/// This tag is defining exact affine transformations between raster and model space. Used in interchangeable GeoTIFF files.
/// </summary>
GEOTIFF_MODELPIXELSCALETAG = 33550,

/// <summary>
/// This tag stores raster->model tiepoint pairs. Used in interchangeable GeoTIFF files.
/// </summary>
GEOTIFF_MODELTIEPOINTTAG = 33922,

/// <summary>
/// This tag is optionally provided for defining exact affine transformations between raster and model space. Used in interchangeable GeoTIFF files.
/// </summary>
GEOTIFF_MODELTRANSFORMATIONTAG = 34264,

/// <summary>
/// This tag may be used to store the GeoKey Directory, which defines and references the "GeoKeys". Used in interchangeable GeoTIFF files.
/// </summary>
GEOTIFF_GEOKEYDIRECTORYTAG = 34735,

/// <summary>
/// This tag is used to store all of the DOUBLE valued GeoKeys, referenced by the GeoKeyDirectoryTag. Used in interchangeable GeoTIFF files.
/// </summary>
GEOTIFF_GEODOUBLEPARAMSTAG = 34736,

/// <summary>
/// This tag is used to store all of the ASCII valued GeoKeys, referenced by the GeoKeyDirectoryTag. Used in interchangeable GeoTIFF files.
/// </summary>
GEOTIFF_GEOASCIIPARAMSTAG = 34737,

// TIFF Tag GDAL_METADATA 42112
GEOTIFF_GDAL_METADATA = 42112,

// TIFF Tag GDAL_NODATA 42113
GEOTIFF_GDAL_NODATA = 42113
}
}
30 changes: 30 additions & 0 deletions GeoTiffCOG/Struture/GEOTiffProperties.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GeoTiffCOG.Struture
{
public class GEOTiffProperties
{
public ModelType ModelType { get; set; }
public RasterType RasterType { get; set; }
public ushort GTCitationGeo { get; set; }
public ushort GeogCitation { get; set; }
public ushort GeodeticDatum { get; set; }
public ushort PrimeMeridian { get; set; }
public AngularUnits AngularUnit { get; set; }
public ushort Ellipsoid { get; set; }
public double SemiMajorAxis { get; set; }
public double SemiMinorAxis { get; set; }
public double InvFlattening { get; set; }
public ushort PrimeMeridianLong { get; set; }
public LinearUnits LinearUnit { get; set; }
public ushort CoordinateSystemId { get; set; }
public string GdalMetadata { get; set; }
public string GeotiffAsciiParams { get; set; }


}
}
Loading

0 comments on commit efac2b5

Please sign in to comment.