예제 #1
0
            public bool LoadFile(string filename)
            {
                FileName = filename;

                log.InfoFormat("GeoTiff {0}", filename);

                using (Tiff tiff = Tiff.Open(filename, "r"))
                {
                    width  = tiff.GetField(TiffTag.IMAGEWIDTH)[0].ToInt();
                    height = tiff.GetField(TiffTag.IMAGELENGTH)[0].ToInt();
                    bits   = tiff.GetField(TiffTag.BITSPERSAMPLE)[0].ToInt();
                    //https://www.awaresystems.be/imaging/tiff/tifftags/sampleformat.html
                    type = tiff.GetField(TiffTag.SAMPLEFORMAT)[0].ToInt();

                    modelscale = tiff.GetField(TiffTag.GEOTIFF_MODELPIXELSCALETAG);
                    tiepoint   = tiff.GetField(TiffTag.GEOTIFF_MODELTIEPOINTTAG);

                    var GeoKeyDirectoryTag = tiff.GetField((TiffTag)34735);

                    var KeyDirectoryVersion = BitConverter.ToUInt16(GeoKeyDirectoryTag[1].ToByteArray(), 0);
                    var KeyRevision         = BitConverter.ToUInt16(GeoKeyDirectoryTag[1].ToByteArray(), 2);
                    var MinorRevision       = BitConverter.ToUInt16(GeoKeyDirectoryTag[1].ToByteArray(), 4);
                    var NumberOfKeys        = BitConverter.ToUInt16(GeoKeyDirectoryTag[1].ToByteArray(), 6);

                    ProjectedCSTypeGeoKey = 0;

                    for (int i = 8; i < 8 + NumberOfKeys * 8; i += 8)
                    {
                        var KeyID           = BitConverter.ToUInt16(GeoKeyDirectoryTag[1].ToByteArray(), i);
                        var TIFFTagLocation = BitConverter.ToUInt16(GeoKeyDirectoryTag[1].ToByteArray(), i + 2);
                        var Count           = BitConverter.ToUInt16(GeoKeyDirectoryTag[1].ToByteArray(), i + 4);
                        var Value_Offset    = BitConverter.ToUInt16(GeoKeyDirectoryTag[1].ToByteArray(), i + 6);

                        log.InfoFormat("GeoKeyDirectoryTag ID={0} TagLoc={1} Count={2} Value/offset={3}", (GKID)KeyID, TIFFTagLocation,
                                       Count, Value_Offset);

                        if (KeyID == (int)GKID.ProjectedCSTypeGeoKey)
                        {
                            ProjectedCSTypeGeoKey = Value_Offset;
                        }

                        if (KeyID == (int)GKID.GTRasterTypeGeoKey)
                        {
                            GTRasterTypeGeoKey = Value_Offset;
                        }

                        if (TIFFTagLocation != 0)
                        {
                            if (TIFFTagLocation == 34737)
                            {
                                var value = tiff.GetField((TiffTag)TIFFTagLocation)[1].ToByteArray().Skip(Value_Offset)
                                            .Take(Count);
                                log.InfoFormat("GeoKeyDirectoryTag ID={0} Value={1}", (GKID)KeyID,
                                               Encoding.ASCII.GetString(value.ToArray()));
                            }
                            if (TIFFTagLocation == 34736)
                            {
                                /*
                                 * var value = tiff.GetField((TiffTag)TIFFTagLocation)[1].ToByteArray().Skip(Value_Offset*8)
                                 *  .Take(Count*8);
                                 * log.InfoFormat("GeoKeyDirectoryTag ID={0} Value={1}", (GKID) KeyID, value);
                                 */
                            }

                            if (KeyID == (int)GKID.PCSCitationGeoKey)
                            {
                                var value = tiff.GetField((TiffTag)TIFFTagLocation)[1].ToByteArray().Skip(Value_Offset)
                                            .Take(Count);
                                PCSCitationGeoKey = Encoding.ASCII.GetString(value.ToArray());
                            }
                        }
                    }

                    GeoAsciiParamsTag = tiff.GetField((TiffTag)34737);
                    if (GeoAsciiParamsTag != null && GeoAsciiParamsTag.Length == 2)
                    {
                        log.InfoFormat("GeoAsciiParamsTag {0}", GeoAsciiParamsTag[1]);
                    }

                    i = BitConverter.ToDouble(tiepoint[1].ToByteArray(), 0);
                    j = BitConverter.ToDouble(tiepoint[1].ToByteArray(), 0 + 8);
                    k = BitConverter.ToDouble(tiepoint[1].ToByteArray(), 0 + 16);
                    x = BitConverter.ToDouble(tiepoint[1].ToByteArray(), 0 + 24);
                    y = BitConverter.ToDouble(tiepoint[1].ToByteArray(), 0 + 32);
                    z = BitConverter.ToDouble(tiepoint[1].ToByteArray(), 0 + 40);

                    log.InfoFormat("Tie Point ({0},{1},{2}) --> ({3},{4},{5})", i, j, k, x, y, z);

                    xscale = BitConverter.ToDouble(modelscale[1].ToByteArray(), 0);
                    yscale = BitConverter.ToDouble(modelscale[1].ToByteArray(), 0 + 8);
                    zscale = BitConverter.ToDouble(modelscale[1].ToByteArray(), 0 + 16);

                    log.InfoFormat("Scale ({0},{1},{2})", xscale, yscale, zscale);

                    if (!String.IsNullOrEmpty(PCSCitationGeoKey))
                    {
                        //var source = new CoordinateSystemFactory();
                        //var coords = source.CreateFromWkt(PCSCitationGeoKey);
                        //var converter = new CoordinateTransformationFactory().CreateFromCoordinateSystems(coords,GeocentricCoordinateSystem.WGS84);
                    }

                    // wgs84 utm
                    if (ProjectedCSTypeGeoKey >= 32601 && ProjectedCSTypeGeoKey <= 32760)
                    {
                        if (ProjectedCSTypeGeoKey > 32700)
                        {
                            UTMZone = (ProjectedCSTypeGeoKey - 32700) * -1;
                            var pnt  = PointLatLngAlt.FromUTM(UTMZone, x, y);
                            var pnt2 = PointLatLngAlt.FromUTM(UTMZone, x + width * xscale,
                                                              y + height * yscale);
                            var pnt3 = PointLatLngAlt.FromUTM(UTMZone, x + width * xscale, y);
                            var pnt4 = PointLatLngAlt.FromUTM(UTMZone, x, y + height * yscale);

                            ymin = Math.Min(Math.Min(Math.Min(pnt.Lat, pnt2.Lat), pnt3.Lat), pnt4.Lat);
                            xmin = Math.Min(Math.Min(Math.Min(pnt.Lng, pnt2.Lng), pnt3.Lng), pnt4.Lng);
                            ymax = Math.Max(Math.Max(Math.Max(pnt.Lat, pnt2.Lat), pnt3.Lat), pnt4.Lat);
                            xmax = Math.Max(Math.Max(Math.Max(pnt.Lng, pnt2.Lng), pnt3.Lng), pnt4.Lng);
                        }

                        if (ProjectedCSTypeGeoKey < 32700)
                        {
                            UTMZone = ProjectedCSTypeGeoKey - 32600;
                            var pnt  = PointLatLngAlt.FromUTM(UTMZone, x, y);
                            var pnt2 = PointLatLngAlt.FromUTM(UTMZone, x + width * xscale,
                                                              y - height * yscale);
                            var pnt3 = PointLatLngAlt.FromUTM(UTMZone, x + width * xscale, y);
                            var pnt4 = PointLatLngAlt.FromUTM(UTMZone, x, y - height * yscale);

                            ymin = Math.Min(Math.Min(Math.Min(pnt.Lat, pnt2.Lat), pnt3.Lat), pnt4.Lat);
                            xmin = Math.Min(Math.Min(Math.Min(pnt.Lng, pnt2.Lng), pnt3.Lng), pnt4.Lng);
                            ymax = Math.Max(Math.Max(Math.Max(pnt.Lat, pnt2.Lat), pnt3.Lat), pnt4.Lat);
                            xmax = Math.Max(Math.Max(Math.Max(pnt.Lng, pnt2.Lng), pnt3.Lng), pnt4.Lng);
                        }
                    }
                    // etrs89 utm
                    if (ProjectedCSTypeGeoKey >= 3038 && ProjectedCSTypeGeoKey <= 3051)
                    {
                        UTMZone = ProjectedCSTypeGeoKey - 3012;
                        // 3038 - 26
                        var pnt  = PointLatLngAlt.FromUTM(UTMZone, x, y);
                        var pnt2 = PointLatLngAlt.FromUTM(UTMZone, x + width * xscale,
                                                          y - height * yscale);
                        var pnt3 = PointLatLngAlt.FromUTM(UTMZone, x + width * xscale, y);
                        var pnt4 = PointLatLngAlt.FromUTM(UTMZone, x, y - height * yscale);

                        ymin = Math.Min(Math.Min(Math.Min(pnt.Lat, pnt2.Lat), pnt3.Lat), pnt4.Lat);
                        xmin = Math.Min(Math.Min(Math.Min(pnt.Lng, pnt2.Lng), pnt3.Lng), pnt4.Lng);
                        ymax = Math.Max(Math.Max(Math.Max(pnt.Lat, pnt2.Lat), pnt3.Lat), pnt4.Lat);
                        xmax = Math.Max(Math.Max(Math.Max(pnt.Lng, pnt2.Lng), pnt3.Lng), pnt4.Lng);
                    }

                    if (ProjectedCSTypeGeoKey >= 25828 && ProjectedCSTypeGeoKey <= 25838)
                    {
                        UTMZone = ProjectedCSTypeGeoKey - 25800;
                        // 3038 - 26
                        var pnt  = PointLatLngAlt.FromUTM(UTMZone, x, y);
                        var pnt2 = PointLatLngAlt.FromUTM(UTMZone, x + width * xscale,
                                                          y - height * yscale);
                        var pnt3 = PointLatLngAlt.FromUTM(UTMZone, x + width * xscale, y);
                        var pnt4 = PointLatLngAlt.FromUTM(UTMZone, x, y - height * yscale);

                        ymin = Math.Min(Math.Min(Math.Min(pnt.Lat, pnt2.Lat), pnt3.Lat), pnt4.Lat);
                        xmin = Math.Min(Math.Min(Math.Min(pnt.Lng, pnt2.Lng), pnt3.Lng), pnt4.Lng);
                        ymax = Math.Max(Math.Max(Math.Max(pnt.Lat, pnt2.Lat), pnt3.Lat), pnt4.Lat);
                        xmax = Math.Max(Math.Max(Math.Max(pnt.Lng, pnt2.Lng), pnt3.Lng), pnt4.Lng);
                    }

                    Area = new RectLatLng(ymax, xmin, xmax - xmin, ymax - ymin);

                    /// gda94
                    if (ProjectedCSTypeGeoKey >= 28348 && ProjectedCSTypeGeoKey <= 28358)
                    {
                        UTMZone = (ProjectedCSTypeGeoKey - 28300) * -1;
                        var pnt  = PointLatLngAlt.FromUTM(UTMZone, x, y);
                        var pnt2 = PointLatLngAlt.FromUTM(UTMZone, x + width * xscale,
                                                          y - height * yscale);
                        var pnt3 = PointLatLngAlt.FromUTM(UTMZone, x + width * xscale, y);
                        var pnt4 = PointLatLngAlt.FromUTM(UTMZone, x, y - height * yscale);

                        ymin = Math.Min(Math.Min(Math.Min(pnt.Lat, pnt2.Lat), pnt3.Lat), pnt4.Lat);
                        xmin = Math.Min(Math.Min(Math.Min(pnt.Lng, pnt2.Lng), pnt3.Lng), pnt4.Lng);
                        ymax = Math.Max(Math.Max(Math.Max(pnt.Lat, pnt2.Lat), pnt3.Lat), pnt4.Lat);
                        xmax = Math.Max(Math.Max(Math.Max(pnt.Lng, pnt2.Lng), pnt3.Lng), pnt4.Lng);

                        Area = new RectLatLng(ymax, xmin, xmax - xmin, ymax - ymin);
                    }

                    // geo lat/lng
                    if (ProjectedCSTypeGeoKey == 0 || ProjectedCSTypeGeoKey == 4326)
                    {
                        var pnt  = new PointLatLngAlt(y, x);
                        var pnt2 = new PointLatLngAlt(y + height * yscale, x + width * xscale);
                        var pnt3 = new PointLatLngAlt(y, x + width * xscale);
                        var pnt4 = new PointLatLngAlt(y + height * yscale, x);

                        ymin = Math.Min(Math.Min(Math.Min(pnt.Lat, pnt2.Lat), pnt3.Lat), pnt4.Lat);
                        xmin = Math.Min(Math.Min(Math.Min(pnt.Lng, pnt2.Lng), pnt3.Lng), pnt4.Lng);
                        ymax = Math.Max(Math.Max(Math.Max(pnt.Lat, pnt2.Lat), pnt3.Lat), pnt4.Lat);
                        xmax = Math.Max(Math.Max(Math.Max(pnt.Lng, pnt2.Lng), pnt3.Lng), pnt4.Lng);

                        Area = new RectLatLng(y, x, width * xscale, height * yscale);
                    }

                    log.InfoFormat("Coverage {0}", Area.ToString());

                    if (GTRasterTypeGeoKey == 1)
                    {
                        // starts from top left so x + y -
                        x += xscale / 2.0;
                        y -= yscale / 2.0;
                    }

                    log.InfoFormat("Start Point ({0},{1},{2}) --> ({3},{4},{5})", i, j, k, x, y, z);

                    lock (index)
                        GeoTiff.index.Add(this);

                    /*
                     *
                     * short numberOfDirectories = tiff.NumberOfDirectories();
                     * for (short d = 0; d < numberOfDirectories; ++d)
                     * {
                     * tiff.SetDirectory((short)d);
                     *
                     * for (ushort t = ushort.MinValue; t < ushort.MaxValue; ++t)
                     * {
                     *  TiffTag tag = (TiffTag)t;
                     *  FieldValue[] value = tiff.GetField(tag);
                     *  if (value != null)
                     *  {
                     *      for (int j2 = 0; j2 < value.Length; j2++)
                     *      {
                     *          Console.WriteLine("{0} : {1} : {2}", tag.ToString(), value[j2].Value.GetType().ToString(), value[j2].ToString());
                     *      }
                     *  }
                     * }
                     * }
                     */
                }

                return(true);
            }
예제 #2
0
            public bool LoadFile(string filename)
            {
                FileName = filename;

                log.InfoFormat("GeoTiff {0}", filename);

                using (Tiff tiff = Tiff.Open(filename, "r"))
                {
                    width  = tiff.GetField(TiffTag.IMAGEWIDTH)[0].ToInt();
                    height = tiff.GetField(TiffTag.IMAGELENGTH)[0].ToInt();
                    bits   = tiff.GetField(TiffTag.BITSPERSAMPLE)[0].ToInt();
                    //https://www.awaresystems.be/imaging/tiff/tifftags/sampleformat.html
                    type = tiff.GetField(TiffTag.SAMPLEFORMAT)[0].ToInt();

                    modelscale = tiff.GetField(TiffTag.GEOTIFF_MODELPIXELSCALETAG);
                    tiepoint   = tiff.GetField(TiffTag.GEOTIFF_MODELTIEPOINTTAG);

                    for (int i = 0; i < tiff.GetTagListCount(); i += 1)
                    {
                        var tagno = tiff.GetTagListEntry(i);
                        var tag   = (TiffTag)tagno;
                        var info  = tiff.GetField((TiffTag)tagno);

                        log.InfoFormat("tiff ID={0} ? {1} len={2}", tag, (GKID)tagno, info.Length);
                    }

                    var GeoKeyDirectoryTag = tiff.GetField((TiffTag)34735);

                    var KeyDirectoryVersion = BitConverter.ToUInt16(GeoKeyDirectoryTag[1].ToByteArray(), 0);
                    var KeyRevision         = BitConverter.ToUInt16(GeoKeyDirectoryTag[1].ToByteArray(), 2);
                    var MinorRevision       = BitConverter.ToUInt16(GeoKeyDirectoryTag[1].ToByteArray(), 4);
                    var NumberOfKeys        = BitConverter.ToUInt16(GeoKeyDirectoryTag[1].ToByteArray(), 6);

                    ProjectedCSTypeGeoKey = 0;

                    for (int i = 8; i < 8 + NumberOfKeys * 8; i += 8)
                    {
                        var KeyID           = BitConverter.ToUInt16(GeoKeyDirectoryTag[1].ToByteArray(), i);
                        var TIFFTagLocation = BitConverter.ToUInt16(GeoKeyDirectoryTag[1].ToByteArray(), i + 2);
                        var Count           = BitConverter.ToUInt16(GeoKeyDirectoryTag[1].ToByteArray(), i + 4);
                        var Value_Offset    = BitConverter.ToUInt16(GeoKeyDirectoryTag[1].ToByteArray(), i + 6);

                        log.InfoFormat("GeoKeyDirectoryTag ID={0} TagLoc={1} Count={2} Value/offset={3}", (GKID)KeyID, TIFFTagLocation,
                                       Count, Value_Offset);

                        // save it
                        if (TIFFTagLocation == 0)
                        {
                            GeoKeys[(GKID)KeyID] = Value_Offset;
                        }
                        else if (TIFFTagLocation == 34737)
                        {
                            GeoKeys[(GKID)KeyID] = Encoding.ASCII.GetString(tiff.GetField((TiffTag)TIFFTagLocation)[1].ToByteArray().Skip(Value_Offset).Take(Count).ToArray());
                        }
                        else if (TIFFTagLocation == 34736)
                        {
                            GeoKeys[(GKID)KeyID] = BitConverter.ToDouble(tiff.GetField((TiffTag)TIFFTagLocation)[1].ToByteArray().Skip(Value_Offset * 8).Take(Count * 8).ToArray(), 0);
                        }
                        else
                        {
                            GeoKeys[(GKID)KeyID] = Value_Offset;
                        }


                        if (KeyID == (int)GKID.ProjectedCSTypeGeoKey)
                        {
                            ProjectedCSTypeGeoKey = Value_Offset;
                        }

                        if (KeyID == (int)GKID.GTRasterTypeGeoKey)
                        {
                            GTRasterTypeGeoKey = Value_Offset;
                        }

                        if (KeyID == (int)GKID.ProjCoordTransGeoKey)
                        {
                            ProjCoordTransGeoKey = Value_Offset;
                        }

                        if (TIFFTagLocation != 0)
                        {
                            if (TIFFTagLocation == 34737) //ascii
                            {
                                var value = tiff.GetField((TiffTag)TIFFTagLocation)[1].ToByteArray().Skip(Value_Offset)
                                            .Take(Count);
                                log.InfoFormat("GeoKeyDirectoryTag ID={0} Value={1}", (GKID)KeyID,
                                               Encoding.ASCII.GetString(value.ToArray()));
                            }
                            if (TIFFTagLocation == 34736) // double
                            {
                                var value = tiff.GetField((TiffTag)TIFFTagLocation)[1].ToByteArray().Skip(Value_Offset * 8).Take(Count * 8);
                                log.InfoFormat("GeoKeyDirectoryTag ID={0} Value={1}", (GKID)KeyID, BitConverter.ToDouble(value.ToArray(), 0));
                            }

                            if (KeyID == (int)GKID.PCSCitationGeoKey)
                            {
                                var value = tiff.GetField((TiffTag)TIFFTagLocation)[1].ToByteArray().Skip(Value_Offset).Take(Count);
                                PCSCitationGeoKey = Encoding.ASCII.GetString(value.ToArray());
                                log.InfoFormat("GeoKeyDirectoryTag ID={0} Value={1}", (GKID)KeyID, Encoding.ASCII.GetString(value.ToArray()));
                            }
                        }
                    }

                    GeoAsciiParamsTag = tiff.GetField((TiffTag)34737);
                    if (GeoAsciiParamsTag != null && GeoAsciiParamsTag.Length == 2)
                    {
                        log.InfoFormat("GeoAsciiParamsTag 34737 {0}", GeoAsciiParamsTag[1]);
                    }

                    i = BitConverter.ToDouble(tiepoint[1].ToByteArray(), 0);
                    j = BitConverter.ToDouble(tiepoint[1].ToByteArray(), 0 + 8);
                    k = BitConverter.ToDouble(tiepoint[1].ToByteArray(), 0 + 16);
                    x = BitConverter.ToDouble(tiepoint[1].ToByteArray(), 0 + 24);
                    y = BitConverter.ToDouble(tiepoint[1].ToByteArray(), 0 + 32);
                    z = BitConverter.ToDouble(tiepoint[1].ToByteArray(), 0 + 40);

                    log.InfoFormat("Tie Point ({0},{1},{2}) --> ({3},{4},{5})", i, j, k, x, y, z);

                    xscale = BitConverter.ToDouble(modelscale[1].ToByteArray(), 0);
                    yscale = BitConverter.ToDouble(modelscale[1].ToByteArray(), 0 + 8);
                    zscale = BitConverter.ToDouble(modelscale[1].ToByteArray(), 0 + 16);

                    log.InfoFormat("Scale ({0},{1},{2})", xscale, yscale, zscale);

                    if (GTRasterTypeGeoKey == 1)
                    {
                        // starts from top left so x + y -
                        x += xscale / 2.0;
                        y -= yscale / 2.0;
                    }

                    if (ProjectedCSTypeGeoKey == 32767 && ProjCoordTransGeoKey == 15)
                    { // user-defined
                        ProjectionInfo pStart   = ProjectionInfo.FromProj4String($"+proj=stere +lat_ts={GeoKeys[GKID.ProjOriginLatGeoKey].ToString()} +lat_0=90 +lon_0={GeoKeys[GKID.ProjStraightVertPoleLongGeoKey].ToString()} +x_0=0 +y_0=0 +ellps={GeoKeys[GKID.GeogCitationGeoKey].ToString().Replace(" ", "").Replace("|", "")} +datum={GeoKeys[GKID.GeogCitationGeoKey].ToString().Replace(" ", "").Replace("|", "")} +units=m +no_defs ");
                        ProjectionInfo pESRIEnd = KnownCoordinateSystems.Geographic.World.WGS1984;

                        srcProjection = pStart;

                        double[] xyarray = { x,                  y,
                                             x + width * xscale, y - height * yscale,
                                             x + width * xscale, y,
                                             x,                  y - height * yscale };
                        Reproject.ReprojectPoints(xyarray, null, pStart, pESRIEnd, 0, xyarray.Length / 2);

                        ymin = Math.Min(Math.Min(Math.Min(xyarray[1], xyarray[3]), xyarray[5]), xyarray[7]);
                        xmin = Math.Min(Math.Min(Math.Min(xyarray[0], xyarray[2]), xyarray[4]), xyarray[6]);
                        ymax = Math.Max(Math.Max(Math.Max(xyarray[1], xyarray[3]), xyarray[5]), xyarray[7]);
                        xmax = Math.Max(Math.Max(Math.Max(xyarray[0], xyarray[2]), xyarray[4]), xyarray[6]);
                    }
                    else if (ProjectedCSTypeGeoKey != 32767 && ProjectedCSTypeGeoKey != 0)
                    {
                        try
                        {
                            srcProjection = ProjectionInfo.FromEpsgCode(ProjectedCSTypeGeoKey);

                            ProjectionInfo pESRIEnd = KnownCoordinateSystems.Geographic.World.WGS1984;

                            double[] xyarray = { x,                  y,
                                                 x + width * xscale, y - height * yscale,
                                                 x + width * xscale, y,
                                                 x,                  y - height * yscale };
                            Reproject.ReprojectPoints(xyarray, null, srcProjection, pESRIEnd, 0, xyarray.Length / 2);

                            ymin = Math.Min(Math.Min(Math.Min(xyarray[1], xyarray[3]), xyarray[5]), xyarray[7]);
                            xmin = Math.Min(Math.Min(Math.Min(xyarray[0], xyarray[2]), xyarray[4]), xyarray[6]);
                            ymax = Math.Max(Math.Max(Math.Max(xyarray[1], xyarray[3]), xyarray[5]), xyarray[7]);
                            xmax = Math.Max(Math.Max(Math.Max(xyarray[0], xyarray[2]), xyarray[4]), xyarray[6]);
                        }
                        catch (Exception ex) { log.Error(ex); srcProjection = null; }
                    }
                    else
                    {
                        try
                        {
                            srcProjection = ProjectionInfo.FromEsriString(GeoKeys[GKID.PCSCitationGeoKey].ToString());

                            ProjectionInfo pESRIEnd = KnownCoordinateSystems.Geographic.World.WGS1984;

                            double[] xyarray = { x,                  y,
                                                 x + width * xscale, y - height * yscale,
                                                 x + width * xscale, y,
                                                 x,                  y - height * yscale };
                            Reproject.ReprojectPoints(xyarray, null, srcProjection, pESRIEnd, 0, xyarray.Length / 2);

                            ymin = Math.Min(Math.Min(Math.Min(xyarray[1], xyarray[3]), xyarray[5]), xyarray[7]);
                            xmin = Math.Min(Math.Min(Math.Min(xyarray[0], xyarray[2]), xyarray[4]), xyarray[6]);
                            ymax = Math.Max(Math.Max(Math.Max(xyarray[1], xyarray[3]), xyarray[5]), xyarray[7]);
                            xmax = Math.Max(Math.Max(Math.Max(xyarray[0], xyarray[2]), xyarray[4]), xyarray[6]);
                        }
                        catch (Exception ex) { log.Error(ex); srcProjection = null; }
                    }

                    if (srcProjection != null)
                    {
                    }
                    else
                    // wgs84 utm
                    if (ProjectedCSTypeGeoKey >= 32601 && ProjectedCSTypeGeoKey <= 32760)
                    {
                        if (ProjectedCSTypeGeoKey > 32700)
                        {
                            UTMZone       = (ProjectedCSTypeGeoKey - 32700) * -1;
                            srcProjection = ProjectionInfo.FromProj4String($"+proj=utm +zone={UTMZone} +ellps=WGS84 +datum=WGS84 +units=m +no_defs ");
                            //tl
                            var pnt = PointLatLngAlt.FromUTM(UTMZone, x, y);
                            //br
                            var pnt2 = PointLatLngAlt.FromUTM(UTMZone, x + width * xscale,
                                                              y - height * yscale);
                            //tr
                            var pnt3 = PointLatLngAlt.FromUTM(UTMZone, x + width * xscale, y);
                            //bl
                            var pnt4 = PointLatLngAlt.FromUTM(UTMZone, x, y - height * yscale);

                            ymin = Math.Min(Math.Min(Math.Min(pnt.Lat, pnt2.Lat), pnt3.Lat), pnt4.Lat);
                            xmin = Math.Min(Math.Min(Math.Min(pnt.Lng, pnt2.Lng), pnt3.Lng), pnt4.Lng);
                            ymax = Math.Max(Math.Max(Math.Max(pnt.Lat, pnt2.Lat), pnt3.Lat), pnt4.Lat);
                            xmax = Math.Max(Math.Max(Math.Max(pnt.Lng, pnt2.Lng), pnt3.Lng), pnt4.Lng);
                        }

                        if (ProjectedCSTypeGeoKey < 32700)
                        {
                            UTMZone       = ProjectedCSTypeGeoKey - 32600;
                            srcProjection = ProjectionInfo.FromProj4String($"+proj=utm +zone={UTMZone} +ellps=WGS84 +datum=WGS84 +units=m +no_defs ");
                            var pnt  = PointLatLngAlt.FromUTM(UTMZone, x, y);
                            var pnt2 = PointLatLngAlt.FromUTM(UTMZone, x + width * xscale,
                                                              y - height * yscale);
                            var pnt3 = PointLatLngAlt.FromUTM(UTMZone, x + width * xscale, y);
                            var pnt4 = PointLatLngAlt.FromUTM(UTMZone, x, y - height * yscale);

                            ymin = Math.Min(Math.Min(Math.Min(pnt.Lat, pnt2.Lat), pnt3.Lat), pnt4.Lat);
                            xmin = Math.Min(Math.Min(Math.Min(pnt.Lng, pnt2.Lng), pnt3.Lng), pnt4.Lng);
                            ymax = Math.Max(Math.Max(Math.Max(pnt.Lat, pnt2.Lat), pnt3.Lat), pnt4.Lat);
                            xmax = Math.Max(Math.Max(Math.Max(pnt.Lng, pnt2.Lng), pnt3.Lng), pnt4.Lng);
                        }
                    }
                    else
                    // etrs89 utm
                    if (ProjectedCSTypeGeoKey >= 3038 && ProjectedCSTypeGeoKey <= 3051)
                    {
                        UTMZone       = ProjectedCSTypeGeoKey - 3012;
                        srcProjection = ProjectionInfo.FromProj4String($"+proj=utm +zone={UTMZone} +ellps=GRS80 +units=m +no_defs ");
                        // 3038 - 26
                        var pnt  = PointLatLngAlt.FromUTM(UTMZone, x, y);
                        var pnt2 = PointLatLngAlt.FromUTM(UTMZone, x + width * xscale,
                                                          y - height * yscale);
                        var pnt3 = PointLatLngAlt.FromUTM(UTMZone, x + width * xscale, y);
                        var pnt4 = PointLatLngAlt.FromUTM(UTMZone, x, y - height * yscale);

                        ymin = Math.Min(Math.Min(Math.Min(pnt.Lat, pnt2.Lat), pnt3.Lat), pnt4.Lat);
                        xmin = Math.Min(Math.Min(Math.Min(pnt.Lng, pnt2.Lng), pnt3.Lng), pnt4.Lng);
                        ymax = Math.Max(Math.Max(Math.Max(pnt.Lat, pnt2.Lat), pnt3.Lat), pnt4.Lat);
                        xmax = Math.Max(Math.Max(Math.Max(pnt.Lng, pnt2.Lng), pnt3.Lng), pnt4.Lng);
                    }
                    else

                    if (ProjectedCSTypeGeoKey >= 25828 && ProjectedCSTypeGeoKey <= 25838)
                    {
                        UTMZone = ProjectedCSTypeGeoKey - 25800;
                        // 3038 - 26
                        var pnt  = PointLatLngAlt.FromUTM(UTMZone, x, y);
                        var pnt2 = PointLatLngAlt.FromUTM(UTMZone, x + width * xscale,
                                                          y - height * yscale);
                        var pnt3 = PointLatLngAlt.FromUTM(UTMZone, x + width * xscale, y);
                        var pnt4 = PointLatLngAlt.FromUTM(UTMZone, x, y - height * yscale);

                        ymin = Math.Min(Math.Min(Math.Min(pnt.Lat, pnt2.Lat), pnt3.Lat), pnt4.Lat);
                        xmin = Math.Min(Math.Min(Math.Min(pnt.Lng, pnt2.Lng), pnt3.Lng), pnt4.Lng);
                        ymax = Math.Max(Math.Max(Math.Max(pnt.Lat, pnt2.Lat), pnt3.Lat), pnt4.Lat);
                        xmax = Math.Max(Math.Max(Math.Max(pnt.Lng, pnt2.Lng), pnt3.Lng), pnt4.Lng);
                    }
                    else
                    /// gda94
                    if (ProjectedCSTypeGeoKey >= 28348 && ProjectedCSTypeGeoKey <= 28358)
                    {
                        UTMZone = (ProjectedCSTypeGeoKey - 28300) * -1;
                        var pnt  = PointLatLngAlt.FromUTM(UTMZone, x, y);
                        var pnt2 = PointLatLngAlt.FromUTM(UTMZone, x + width * xscale,
                                                          y - height * yscale);
                        var pnt3 = PointLatLngAlt.FromUTM(UTMZone, x + width * xscale, y);
                        var pnt4 = PointLatLngAlt.FromUTM(UTMZone, x, y - height * yscale);

                        ymin = Math.Min(Math.Min(Math.Min(pnt.Lat, pnt2.Lat), pnt3.Lat), pnt4.Lat);
                        xmin = Math.Min(Math.Min(Math.Min(pnt.Lng, pnt2.Lng), pnt3.Lng), pnt4.Lng);
                        ymax = Math.Max(Math.Max(Math.Max(pnt.Lat, pnt2.Lat), pnt3.Lat), pnt4.Lat);
                        xmax = Math.Max(Math.Max(Math.Max(pnt.Lng, pnt2.Lng), pnt3.Lng), pnt4.Lng);
                    }
                    else

                    // geo lat/lng
                    if (ProjectedCSTypeGeoKey == 0 || ProjectedCSTypeGeoKey == 4326)
                    {
                        var pnt  = new PointLatLngAlt(y, x);
                        var pnt2 = new PointLatLngAlt(y - height * yscale, x + width * xscale);
                        var pnt3 = new PointLatLngAlt(y, x + width * xscale);
                        var pnt4 = new PointLatLngAlt(y - height * yscale, x);

                        ymin = Math.Min(Math.Min(Math.Min(pnt.Lat, pnt2.Lat), pnt3.Lat), pnt4.Lat);
                        xmin = Math.Min(Math.Min(Math.Min(pnt.Lng, pnt2.Lng), pnt3.Lng), pnt4.Lng);
                        ymax = Math.Max(Math.Max(Math.Max(pnt.Lat, pnt2.Lat), pnt3.Lat), pnt4.Lat);
                        xmax = Math.Max(Math.Max(Math.Max(pnt.Lng, pnt2.Lng), pnt3.Lng), pnt4.Lng);
                    }

                    Area = new RectLatLng(ymax, xmin, xmax - xmin, ymax - ymin);

                    log.InfoFormat("Coverage {0}", Area.ToString());


                    log.InfoFormat("Start Point ({0},{1},{2}) --> ({3},{4},{5})", i, j, k, x, y, z);

                    lock (index)
                        GeoTiff.index.Add(this);

                    /*
                     *
                     * short numberOfDirectories = tiff.NumberOfDirectories();
                     * for (short d = 0; d < numberOfDirectories; ++d)
                     * {
                     * tiff.SetDirectory((short)d);
                     *
                     * for (ushort t = ushort.MinValue; t < ushort.MaxValue; ++t)
                     * {
                     *  TiffTag tag = (TiffTag)t;
                     *  FieldValue[] value = tiff.GetField(tag);
                     *  if (value != null)
                     *  {
                     *      for (int j2 = 0; j2 < value.Length; j2++)
                     *      {
                     *          Console.WriteLine("{0} : {1} : {2}", tag.ToString(), value[j2].Value.GetType().ToString(), value[j2].ToString());
                     *      }
                     *  }
                     * }
                     * }
                     */
                }

                return(true);
            }