Int16 ImageWidth = 0; //pixels
Int16 ImageHeight = 0; //pixels
Double LEFT_LONG = 0; //map coords
Double TOP_LAT = 0; //map coords
Double dXScale = 0; //degs/pixel
Double dYScale = 0; //degs/pixel
Int16 GEOMODEL = 0;
Int16 GEORASTER = 0;
Int16 GeographicType = 0;
Int16 GeogAngularUnits = 0;
enum EXIFTags
{
PixelScale = 0x830e,
ModelTiePoint = 0x8482,
GeoTiffDirectory = 0x87AF,
ImageWidth = 0x0100,
ImageHeight = 0x0101,
BitsPerSample = 0x0102,
Compression = 0x0103,
Photometric = 0x0106,
Thresholding = 0x0107,
PlanarConfig = 0x011c
}
enum GEOVector
{
Version = 0x0001,
Model = 0x0400,
Raster = 0x0401,
Citation = 0x0402,
GeographicType = 0x0800,
GeogCitation = 0x0801,
GeogGeodeticDatum = 0x0802,
GeogPrimeMeridian = 0x0803,
GeogLinearUnits = 0x0804,
GeogLinearUnitSize = 0x0805,
GeogAngularUnits = 0x0806,
GeogAngularUnitSize = 0x0807,
GeogEllipsoid = 0x0808,
GeogSemiMajorAxis = 0x0809,
GeogSemiMinorAxis = 0x080A,
GeogInvFlattening = 0x080B,
GeogAzimuthUnits = 0x080C,
GeogPrimeMeridianLong = 0x080D,
ProjectedCSType = 0x0c00,
PCSCitation = 0x0c01,
Projection = 0x0c02,
ProjCoordTrans = 0x0c03,
ProjLinearUnits = 0x0c04,
ProjLinearUnitSize = 0x0c05,
ProjStdParallel1 = 0x0c06,
ProjStdParallel2 = 0x0c07,
ProjNatOriginLong = 0x0c08,
ProjNatOriginLat = 0x0c09,
ProjFalseEasting = 0x0c0A,
ProjFalseNorthing = 0x0c0B,
ProjFalseOriginLong = 0x0c0C,
ProjFalseOriginLat = 0x0c0D,
ProjFalseOriginEasting = 0x0c0E,
ProjFalseOriginNorthing = 0x0c0F,
ProjCenterLong = 0x0c10,
ProjCenterLat = 0x0c11,
ProjCenterEasting = 0x0c12,
ProjCenterNorthing = 0x0c13,
ProjScaleAtNatOrigin = 0x0c14,
ProjScaleAtCenter = 0x0c15,
ProjAzimuthAngle = 0x0c16,
ProjStraightVertPoleLong = 0x0c17,
ProjRectifiedGridAngle = 0x0c18,
VerticalCSType = 0x1000,
VerticalCitation = 0x1001,
VerticalDatum = 0x1002,
VerticalUnits = 0x1003
}
public Bitmap initGeoTiff()
{
Bitmap mainBmp = new Bitmap(@"F:\DEV2010\PROJECTS\netProjects\TestPanel\TestPanel\RingPiece.tif");
PropertyItem[] propItems = mainBmp.PropertyItems;
foreach (PropertyItem propItem in propItems)
{
switch (propItem.Id)
{
case (int)EXIFTags.ImageWidth:
if (propItem.Len != 2) throw new Exception("Oops this code is not smart enuf");
ImageWidth = BitConverter.ToInt16(propItem.Value,0);
break;
case (int)EXIFTags.ImageHeight:
if (propItem.Len != 2) throw new Exception("Oops this code is not smart enuf");
ImageHeight = BitConverter.ToInt16(propItem.Value,0);
break;
case (int)EXIFTags.ModelTiePoint:
{
//Wild guesses at what data actually is... but looks ok
byte[] b = propItem.Value;
Double d0 = BitConverter.ToDouble(b, 0);
Double d1 = BitConverter.ToDouble(b, sizeof(Double));
Double d2 = BitConverter.ToDouble(b, 2 * sizeof(Double));
LEFT_LONG = BitConverter.ToDouble(b, 3 * sizeof(Double));
TOP_LAT = BitConverter.ToDouble(b, 4 * sizeof(Double));
Double d5 = BitConverter.ToDouble(b, 5 * sizeof(Double));
}
break;
case (int)EXIFTags.PixelScale:
{
byte[] b = propItem.Value;
//Wild guesses at what data actually is... but looks ok
dXScale = BitConverter.ToDouble(b, 0);
dYScale = BitConverter.ToDouble(b, sizeof(Double));
Double dZ = BitConverter.ToDouble(b, 2 * sizeof(Double));
}
break;
case (int)EXIFTags.GeoTiffDirectory:
{
//Wild guesses at what data actually is...
int byteOffset = 0;
byte[] b = propItem.Value;
while (byteOffset < b.Length)
{
Int16 vector = BitConverter.ToInt16(b, byteOffset);
byteOffset += sizeof(Int16);
switch (vector)
{
case (int)GEOVector.Version:
Int16 bV1 = BitConverter.ToInt16(b, byteOffset);
byteOffset += sizeof(Int16);
Int16 bV2 = BitConverter.ToInt16(b, byteOffset);
byteOffset += sizeof(Int16);
Int16 bV3 = BitConverter.ToInt16(b, byteOffset);
byteOffset += sizeof(Int16);
string GeoVersion = "" + bV1 + "." + bV2 + "." + bV3;
break;
case (int)GEOVector.Model:
{
Int16 bSpacerUnknown = BitConverter.ToInt16(b, byteOffset);
byteOffset += sizeof(Int16);
Int16 bSpacer2Unknown = BitConverter.ToInt16(b, byteOffset);
byteOffset += sizeof(Int16);
GEOMODEL = BitConverter.ToInt16(b, byteOffset); // 1 = Projected,2 = Geographic,3 = Geocentric
byteOffset += sizeof(Int16);
}
break;
case (int)GEOVector.Raster:
{
Int16 bSpacerUnknown = BitConverter.ToInt16(b, byteOffset);
byteOffset += sizeof(Int16);
Int16 bSpacer2Unknown = BitConverter.ToInt16(b, byteOffset);
byteOffset += sizeof(Int16);
GEORASTER = BitConverter.ToInt16(b, byteOffset); // 1 = Pixel Is Area, 2 = Pixel Is Point
byteOffset += sizeof(Int16);
}
break;
case (int)GEOVector.GeographicType:
{
Int16 bSpacerUnknown = BitConverter.ToInt16(b, byteOffset);
byteOffset += sizeof(Int16);
Int16 bSpacer2Unknown = BitConverter.ToInt16(b, byteOffset);
byteOffset += sizeof(Int16);
GeographicType = BitConverter.ToInt16(b, byteOffset); // 4326 = WGS 84
byteOffset += sizeof(Int16);
}
break;
case (int)GEOVector.GeogAngularUnits:
{
Int16 bSpacerUnknown = BitConverter.ToInt16(b, byteOffset);
byteOffset += sizeof(Int16);
Int16 bSpacer2Unknown = BitConverter.ToInt16(b, byteOffset);
byteOffset += sizeof(Int16);
GeogAngularUnits = BitConverter.ToInt16(b, byteOffset); // 9102 = Angular Degree
byteOffset += sizeof(Int16);
}
break;
default:
Debug.WriteLine(" VECTOR Data that could be captured ");
Debug.WriteLine(String.Format("{0:X}", vector));
//Dummy Read
byteOffset += 3 * sizeof(Int16);
break;
}// end vector switch
}// end while vector
}
break;
default:
Debug.WriteLine(" Meta Data that could be captured ");
Debug.WriteLine(String.Format("{0:X}", propItem.Id));
Debug.WriteLine(propItem.Type);
Debug.WriteLine(propItem.Len);
Debug.WriteLine(propItem.Value);
break;
}
}//end meta
if (dXScale == 0) throw new Exception("Oops Image does not have properties");
//Output test mapping data...
Debug.WriteLine("LEFT COORD OF IMAGE " + LEFT_LONG);
Debug.WriteLine("RIGHT COORD OF IMAGE " + LongFromXPixel(ImageWidth));
Debug.WriteLine("TOP COORD OF IMAGE " + TOP_LAT);
Debug.WriteLine("BOTTOM COORD OF IMAGE " + LatFromYPixel(ImageHeight));
//Check from Long and Lat to actual Pixel pos
Debug.WriteLine("THE CENTER OF MY WORLD MAP IS " + PixelFromPntCoord(0.0, 0.0));
//Playing
Debug.WriteLine("Impossible Coord " + LongFromXPixel(-100));
return mainBmp;
}
//---
public Double LongFromXPixel(Int16 xPixel)
{
Double xLong = LEFT_LONG + (xPixel * dXScale);
return xLong;
}
//---
public Double LatFromYPixel(Int16 yPixel)
{
Double yLat = TOP_LAT - (yPixel * dYScale);
return yLat;
}
//---
public Int16 XPixelFromLong(Double xLong)
{
Double xPixel = (Double)(xLong - LEFT_LONG) / dXScale;
return (Int16)xPixel;
}
//---
public Int16 YPixelFromLat(Double yLat)
{
Double yPixel = (Double)(TOP_LAT - yLat) / dYScale;
return (Int16)yPixel;
}
//---
public Point PixelFromPntCoord(Double xLong, Double yLat)
{
Point pixelPoint = new Point(XPixelFromLong(xLong),YPixelFromLat(yLat));
return pixelPoint;
}