【问题标题】:How to read GeoTIFF file from C#如何从 C# 读取 GeoTIFF 文件
【发布时间】:2012-02-29 14:35:25
【问题描述】:

我已经获得了一些地区的数字高程图(地球高度图)。我的目标是创建逼真的地形。

地形生成没问题。我已经使用 VC# & XNA 框架进行了实践。

问题是那些高度图文件是 GeoTIFF 格式,我不知道如何阅读。我以前也没有阅读任何图像文件的经验,因此我可以使用互联网上关于阅读 GeoTIFF 文件的小技巧进行一些实验。到目前为止,我一直没有成功。

  • 我拥有的 geoTIFF 文件是 3601 x 3601 文件。
  • 每个文件都有两个版本,一个十进制和一个数字文件。
  • 每个文件都有每秒的经纬度数据 地理坐标以及高度图,即 Lon、Lat、距海平面的高度

如何阅读这些文件:)

我拥有的文件来自 ASTER G-DEM Version-2 LINK TO OFFICIAL DESCRIPTION 根据他们的说法,GeoTIFF 非常标准,因为我下载的一些 GeoTIFF 可视化工具向我显示了正确的数据。

我将使用 C#。如果我们谈论这种语言,我将不胜感激。


编辑

好的,我得到了 libtiff,这就是我所做的,

using (Tiff tiff = Tiff.Open(@"Test\N41E071_dem.tif", r))
{
  int width   = tiff.GetField(TiffTag.IMAGEWIDTH)[0].ToInt();
  int height  = tiff.GetField(TiffTag.IMAGELENGTH)[0].ToInt();
  double dpiX = tiff.GetField(TiffTag.XRESOLUTION)[0].ToDouble();
  double dpiY = tiff.GetField(TiffTag.YRESOLUTION)[0].ToDouble(); 

  byte[] scanline        = new byte[tiff.ScanlineSize()]; 
  ushort[] scanline16Bit = new ushort[tiff.ScanlineSize() / 2];

  for (int i = 0; i < height; i++)
  {
    tiff.ReadScanline(scanline, i); //Loading ith Line                        
    MultiplyScanLineAs16BitSamples(scanline, scanline16Bit, 16,i);
  }
}

private static void MultiplyScanLineAs16BitSamples(byte[] scanline, ushort[] temp, ushort factor,int row)
{
  if (scanline.Length % 2 != 0)
  {
    // each two bytes define one sample so there should be even number of bytes
    throw new ArgumentException();
  }
  
  Buffer.BlockCopy(scanline, 0,   temp, 0, scanline.Length);

  for (int i = 0; i < temp.Length; i++)
  {                
    temp[i] *= factor;
    MessageBox.Show("Row:"+row.ToString()+"Column:"+(i/2).ToString()+"Value:"+temp[i].ToString());
  }
}

我在哪里显示消息框,我正在显示相应的值,我做得对吗,我问这个因为这是我第一次处理图像和 8\16 位问题。我认为与 libtiff 的官方教程不同,我应该使用 short 而不是 ushort 因为我使用的图像是 “GeoTIFF,签名 16 位”

【问题讨论】:

  • 只是好奇......第一个结果谷歌搜索了一下:Reading GeoTiff using .NET你试过吗?你在寻找其他图书馆吗?
  • 我不知道那个是怎么跳过的,这次我确实使用了libtif,请再次阅读我的问题
  • @JuanMellado,现在这篇文章是谷歌使用搜索关键字“geotiff reading in C#”的第一个结果
  • 大声笑............

标签: c#-4.0 gis geotiff


【解决方案1】:

有一些 SDK 可用于从 C# 读取 GeoTIFF 文件:

更新:

可以在here 找到 GeoTIFF 的规范 - 在我看来,GeoTIFF 可以包含不同的信息“子类型”,而这些信息又需要被适当地解释......

【讨论】:

  • 感谢您的精彩参考,请阅读我编辑的问题。
  • 我现在可以正确显示图像,我需要确保我正确获取了这些值,并且不会在任何类型的隐式\显式位转换中更改它们。因为这很敏感,我将使用此方法生成地形,用于关键\敏感应用程序。
  • @JunaidSaeed 另一点:要真正确保您的代码正常工作,您至少需要将您的结果与其他读者的结果进行对比......
  • @JunaidSaeed 欢迎您 :-) 关于“short 与 ushort”:因为 libtiff 在内部处理大/小端的东西,唯一的区别是如果使用 MSB(最高有效位) -在您的情况下:是否有任何具有“负高度”(即低于 0)的样本?如果是这样,那么使用 short[] 是必要的 IMO
  • @JunaidSaeed 我不确定的是您在乘法中使用的 16 因子...
【解决方案2】:

这是一个没有 GDAL 的人:http://build-failed.blogspot.com.au/2014/12/processing-geotiff-files-in-net-without.html

GDAL 在 NuGet 中可用。

【讨论】:

    【解决方案3】:

    如果 GeoTIFF 包含图块,则需要不同的方法。这是读取包含 32 位浮点数和高度数据的 GeoTiff 的方法:

      int buffersize = 1000000;
      using (Tiff tiff = Tiff.Open(geotifffile, "r"))
      {
        int nooftiles = tiff.GetField(TiffTag.TILEBYTECOUNTS).Length;
        int width = tiff.GetField(TiffTag.TILEWIDTH)[0].ToInt();
        int height = tiff.GetField(TiffTag.TILELENGTH)[0].ToInt();
        byte[] buffer = new byte[buffersize];
    
        for (int i = 0; i < nooftiles; i++)
        {
          int size = tiff.ReadEncodedTile(i, buffer, 0, buffersize);
          float[,] data = new float[width, height];
          Buffer.BlockCopy(buffer, 0, data, 0, size); // Convert byte array to x,y array of floats (height data)
          // Do whatever you want with the height data (calculate hillshade images etc.)
        }
      }
    

    【讨论】:

      猜你喜欢
      • 2019-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-24
      相关资源
      最近更新 更多