Как прочитать файл GeoTIFF из C#
Я приобрел Цифровые Карты Высот (Карта Высоты Земли) некоторой области. Моей целью было создать реалистичные ландшафты.
Поколение местности не проблема. Я практиковал это, используя VC# & XNA Framework.
Проблема в том, что эти файлы карт высот находятся в формате GeoTIFF, который я не знаю, как читать. Также у меня нет предыдущего опыта чтения каких-либо графических файлов, чтобы я мог что-то экспериментировать, используя в Интернете небольшие подсказки о чтении файлов GeoTIFF. До сих пор я был неудачным.
- У меня есть файлы geoTIFF размером 3601 x 3601.
- Каждый файл имеет две версии, десятичные и числовые файлы.
- Каждый файл содержит данные о каждой секунде долготы и широты гео-координат, а также карту высот, т.е. Lon, Lat, высота от уровня моря
Как читать эти файлы:)
Файлы, которые у меня есть, взяты из ASTER G-DEM Version-2 ССЫЛКА НА ОФИЦИАЛЬНОЕ ОПИСАНИЕ, согласно им GeoTIFF довольно стандартен, потому что некоторые визуализаторы GeoTIFF, которые я загружал, показывают мне правильные данные.
Я собираюсь использовать C#. Буду признателен, если мы поговорим в отношении этого языка.
РЕДАКТИРОВАТЬ
хорошо, у меня есть либтиф, и это то, что я сделал,
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- битные со знаком "
3 ответа
Есть несколько SDK, которые можно использовать из C# для чтения файлов GeoTIFF:
- http://www.bluemarblegeo.com/global-mapper/developer/developer.php (коммерческий)
- http://bitmiracle.com/libtiff/ (бесплатно)
- http://trac.osgeo.org/gdal/wiki/GdalOgrInCsharp (бесплатно?)
ОБНОВИТЬ:
Спецификация для GeoTIFF может быть найдена здесь - мне кажется, что GeoTIFF могут содержать разные "подтипы" информации, которые, в свою очередь, должны интерпретироваться соответствующим образом...
Вот парень, который сделал это без GDAL: http://build-failed.blogspot.com.au/2014/12/processing-geotiff-files-in-net-without.html
GDAL доступен в NuGet.
Если GeoTIFF содержит плитки, вам нужен другой подход. Вот как читать GeoTiff, который содержит 32-битные числа с плавающей запятой и данные о высоте:
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.)
}
}