如何从 C# 读取 GeoTIFF 文件

发布于 2025-01-03 02:38:47 字数 2083 浏览 1 评论 0原文

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

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

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

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

如何阅读这些文件:)

我拥有的文件来自 ASTER G-DEM Version-2 官方描述链接 根据他们的说法,GeoTIFF 非常标准,这是因为一些 GeoTIFF我下载的可视化工具向我显示了正确的数据。

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


EDI T

好吧,我得到了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 位”

I have acquired Digital Elevation Maps(Height Map of Earth) of some area. My aim was to create Realistic Terrains.

Terrain Generation is no problem. I have practiced that using VC# & XNA framework.

The problem is that those Height Map Files are in GeoTIFF format which i don't know how to read. Nor do i have previous experience with reading any image files so that i could experiment something using little tips-bits available on internet about reading GeoTIFF files. So far i have been unsuccessful.

  • The geoTIFF files I have are 3601 x 3601 files.
  • Each file has two version, a decimal & num valued files.
  • Each file has data of every second of longitude & latitude of
    Geo-Coords along with Height Map i.e Lon, Lat, height from sea level

How to read these file :)

The files I have are from ASTER G-DEM Version-2 LINK TO OFFICIAL DESCRIPTION according to them GeoTIFF is pretty standard which is because some GeoTIFF Visualizers I dwonloaded are showing me the correct data.

I am gonna be using C#. I would appreciate if we talk in relation to this language.


E D I T

okay i got the libtiff and this what i have done,

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());
  }
}

where i am displaying the message box, i am displaying the corresponding values, Am i doing it Right, i am asking this cuz this is my maiden experience with images & 8\16 bit problem. I think unlike the official tutorials of libtiff i should be using short instead of ushort because the images i am using are "GeoTIFF, signed 16 bits"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

酒几许 2025-01-10 02:38:47

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

更新:

可以找到 GeoTIFF 的规范此处 - 对我来说,GeoTIFF 似乎可以包含不同的信息“子类型”,而这些信息又需要适当地解释...

There are some SDKs out there usable from C# to read GeoTIFF files:

UPDATE:

The spec for GeoTIFF can be found here - to me it seems that GeoTIFFs can contain different "subtypes" of information which in turn need to be interpreted appropriately...

痕至 2025-01-10 02:38:47

如果 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.)
    }
  }

If the GeoTIFF contains tiles, you need a different approach. This is how to read a GeoTiff that contains 32bit floats with height data:

  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.)
    }
  }
℡Ms空城旧梦 2025-01-10 02:38:47

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

GDAL 可用于不过,NuGet。

Here's a guy that did it without GDAL: http://build-failed.blogspot.com.au/2014/12/processing-geotiff-files-in-net-without.html

GDAL is available in NuGet, though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文