GeoTIFF libtiff.net获取c#中的高程数据

时间:2017-05-09 08:14:10

标签: c# geotiff libtiff.net

我正在尝试使用libtiff.net从GeoTIFF文件中读取高程数据。 到目前为止,我大多只能使用libtiff.net网页上的示例从文件中读取元数据。

但是如何读取我不理解的高程数据......我尝试使用Tiff.ReadScanline()进行首次阅读,如here所述,但我所拥有的文件似乎存储方式不同(如果我理解的话,可能在瓷砖中存储)正确地)

这是元数据(据我所知)(tiff文件来自丹麦地形高程数据集):

  

Tiff c:\ Users *** \ DTM_1km_6170_500.tif,第0页设置了以下标签:

     

IMAGEWIDTH System.Int32:2500

     

IMAGELENGTH System.Int32:2500

     

BITSPERSAMPLE System.Int16:32

     

COMPRESSION BitMiracle.LibTiff.Classic.Compression:ADOBE_DEFLATE

     

PHOTOMETRIC BitMiracle.LibTiff.Classic.Photometric:MINISBLACK

     

STRIPOFFSETS System.UInt64 []:System.UInt64 []

     

SAMPLESPERPIXEL System.Int16:1

     

STRIPBYTECOUNTS System.UInt64 []:System.UInt64 []

     

PLANARCONFIG BitMiracle.LibTiff.Classic.PlanarConfig:CONTIG

     

PREDICTOR BitMiracle.LibTiff.Classic.Predictor:FLOATINGPOINT

     

TILEWIDTH System.Int32:256

     

TILELENGTH System.Int32:256

     

TILEOFFSETS System.UInt64 []:System.UInt64 []

     

TILEBYTECOUNTS System.UInt64 []:System.UInt64 []

     

SAMPLEFORMAT BitMiracle.LibTiff.Classic.SampleFormat:IEEEFP

     

DATATYPE System.Int16:3

     

GEOTIFF_MODELPIXELSCALETAG System.Int32:3 GEOTIFF_MODELPIXELSCALETAG   System.Byte []:Ù?Ù?

     

GEOTIFF_MODELTIEPOINTTAG System.Int32:6 GEOTIFF_MODELTIEPOINTTAG   System.Byte []:A ^ WA

     

34735 System.Int32:36 34735 System.Byte []:   ±±#°èd)#

     

34736 System.Int32:3 34736 System.Byte []:

     

34737 System.Int32:30 34737 System.Byte []:ETRS89 / UTM zone   32N | ETRS89 |

     

42113 System.Int32:6 42113 System.Byte []: - 999

到目前为止我写的代码如下:

namespace GeoTIFFReader
{
  public class GeoTIFF
  {
    private double[,] heightmap;
    private double dx;
    private double dy;
    private double startx;
    private double starty;


    public GeoTIFF(string fn)
    {
      using (Tiff tiff = Tiff.Open(fn, "r"))
      {
        if (tiff == null)
        {
          // Error - could not open
          return;
        }



        int width = tiff.GetField(TiffTag.IMAGEWIDTH)[0].ToInt();
        int height = tiff.GetField(TiffTag.IMAGELENGTH)[0].ToInt();
        heightmap = new double[width, height];
        FieldValue[] modelPixelScaleTag = tiff.GetField(TiffTag.GEOTIFF_MODELPIXELSCALETAG);
        FieldValue[] modelTiePointTag = tiff.GetField(TiffTag.GEOTIFF_MODELTIEPOINTTAG);

        byte[] modelPixelScale = modelPixelScaleTag[1].GetBytes();
        dx = BitConverter.ToDouble(modelPixelScale, 0);
        dy = BitConverter.ToDouble(modelPixelScale, 8) * -1;

        byte[] modelTransformation = modelTiePointTag[1].GetBytes();
        double originLon = BitConverter.ToDouble(modelTransformation, 24);
        double originLat = BitConverter.ToDouble(modelTransformation, 32);

        startx = originLon + dx / 2.0;
        starty = originLat + dy / 2.0;

        double curx = startx;
        double cury = starty;

        FieldValue[] bitsPerSampleTag = tiff.GetField(TiffTag.BITSPERSAMPLE);

        FieldValue[] tilewtag = tiff.GetField(TiffTag.TILEWIDTH);
        FieldValue[] tilehtag = tiff.GetField(TiffTag.TILELENGTH);
        int tilew = tilewtag[0].ToInt();
        int tileh = tilehtag[0].ToInt();

        var tile = new byte[tilew*tileh];

        //var scanline = new byte[tiff.ScanlineSize()]; Does not work... wrong format
        for (int il = 0; il < height; il++)
        {
          //tiff.ReadScanline(scanline, il); // Load il'th line of data 
          for (int ir = 0; ir < width; ir++)
          {

            // Here I would like to read each pixel data that contains elevation in gray-scale in f32 as far I as I understand from metadata

            //object value = scanline[ir];
            //heightmap[ir, il] = double.Parse(value.ToString());
          }
        }

        Console.WriteLine(heightmap.ToString());
      }

    }
  }
}

因此,如果有人知道如何提取这些数据,那将非常感激。

4 个答案:

答案 0 :(得分:1)

所以我偶然发现了一些暗示,让我找到了具体问题的答案..:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="PopUp" class="overlay">
  <div class="PopUp">
    <div class="timer" id="timer"><img src="http://i.imgur.com/87XaOWA.png">
      <p class="close-message" id="close-message"></p>
    </div>
    <a class="close" href="#">&#10005;</a>
    <div class="content" id="content">
      <div id="p1" class="p1" style="overflow: hidden; position: relative; width: 885px; height: 878px;">
        <!-- Begin page background -->
        <div id="pg1Overlay" style="width:100%; height:100%; position:absolute; z-index:1; background-color:rgba(0,0,0,0); -webkit-user-select: none;"></div>
        <div id="pg1" class="pg1" style="-webkit-user-select: none;"><img src="http://i.imgur.com/vcY42CW.png" id="pdf1" class="pdf1"></img>
        </div>
        <!-- End page background -->

        <!-- Begin text definitions (Positioned/styled in CSS) -->
        <div id="t1_1" class="t s1_1">Player Selection Criteria Evaluator Cue Card</div>
        <div id="t2_1" class="t s2_1">Skating – speed, quickness, technique</div>
        <div id="t3_1" class="t s3_1">♦</div>
        <div id="t4_1" class="t s4_1">Forward and Backward</div>
        <div id="t5_1" class="t s3_1">♦</div>
        <div id="t6_1" class="t s3_1">♦</div>
        <div id="t7_1" class="t s3_1">♦</div>
        <div id="t8_1" class="t s4_1">Turn both directions</div>
        <div id="t9_1" class="t s4_1">Stop both directions</div>
        <div id="ta_1" class="t s4_1">Are they in a good position for stability and strength</div>
        <div id="tb_1" class="t s2_1">Passing – technique, control, vision</div>
        <div id="tc_1" class="t s3_1">♦</div>
        <div id="td_1" class="t s3_1">♦</div>
        <div id="te_1" class="t s3_1">♦</div>
        <div id="tf_1" class="t s3_1">♦</div>
        <div id="tg_1" class="t s4_1">Forehand and Backhand</div>
        <div id="th_1" class="t s4_1">To moving and stationary target</div>
        <div id="ti_1" class="t s4_1">Vision – do they take a look and select best option</div>
        <div id="tj_1" class="t s4_1">Advanced – board passes, chips, saucer passes</div>
        <div id="tk_1" class="t s2_1">Puck Control – technique, open ice, confined space</div>
        <div id="tl_1" class="t s3_1">♦</div>
        <div id="tm_1" class="t s3_1">♦</div>
        <div id="tn_1" class="t s3_1">♦</div>
        <div id="to_1" class="t s3_1">♦</div>
        <div id="tp_1" class="t s4_1">Open carry with speed</div>
        <div id="tq_1" class="t s4_1">Execute dekes and fakes on the 1 on 1</div>
        <div id="tr_1" class="t s4_1">Can they handle the puck in traffic and tight space</div>
        <div id="ts_1" class="t s4_1">Ability to maintain control while being stick checked</div>
        <div id="tt_1" class="t s2_1">Shooting – technique, accuracy, velocity</div>
        <div id="tu_1" class="t s3_1">♦</div>
        <div id="tv_1" class="t s3_1">♦</div>
        <div id="tw_1" class="t s3_1">♦</div>
        <div id="tx_1" class="t s4_1">Velocity</div>
        <div id="ty_1" class="t s3_1">♦</div>
        <div id="tz_1" class="t s4_1">Accuracy</div>
        <div id="t10_1" class="t s3_1">♦</div>
        <div id="t11_1" class="t s4_1">Forehand and backhand</div>
        <div id="t12_1" class="t s4_1">Wrist shot, snap shot, slap shot</div>
        <div id="t13_1" class="t s4_1">Shot Selection – do they select the best shot for the opportunity?</div>
        <div id="t14_1" class="t s2_1">Game Understanding – Principles of Offence and Defence</div>
        <div id="t15_1" class="t s3_1">♦</div>
        <div id="t16_1" class="t s3_1">♦</div>
        <div id="t17_1" class="t s3_1">♦</div>
        <div id="t18_1" class="t s3_1">♦</div>
        <div id="t19_1" class="t s4_1">Player understands positional play</div>
        <div id="t1a_1" class="t s4_1">Player supports the puck on the defensive and offensive side of puck</div>
        <div id="t1b_1" class="t s4_1">Player communicates with teammates</div>
        <div id="t1c_1" class="t s4_1">Player has the ability to read and react.</div>
      </div>
    </div>
    <div id="Print" class="Print" align="center">
      <button onclick="printDiv()"><img src="http://i.imgur.com/HcXNoMC.png" /></button>
    </div>
  </div>
</div>

编辑2018-09-20: @Graviton - 对于很长的响应时间抱歉...但这里是我用的构造函数的完整类,它将文件名作为输入并填充 int tileSize = tiff.TileSize(); for (int iw = 0; iw < nWidth; iw += tilew) { for (int ih = 0; ih < nHeight; ih += tileh) { byte[] buffer = new byte[tileSize]; tiff.ReadTile(buffer, 0, iw, ih, 0, 0); for (int itw = 0; itw < tilew; itw++) { int iwhm = ih + itw; if (iwhm > nWidth - 1) { break; } for (int ith = 0; ith < tileh; ith++) { int iyhm = iw + ith; if (iyhm > nHeight - 1) { break; } heightMap[iwhm, iyhm] = BitConverter.ToSingle(buffer, (itw * tileh + ith) * 4); } } } } (但@Nazonokaizijin看起来更好更苗条):< / p>

heightMap

答案 1 :(得分:1)

它有一个对 LibTiff 进行补充的库(在 c# 中),可以在给定纬度/经度的情况下进行高程查询,可在 GeoTiffCOG 处获得:

function __autoload($class_name) {
        $class_name = strtolower($class_name);
        $path = LIB_PATH.DS."{$class_name}.php";
        if(file_exists($path)){
            require_once($path);
        }else{
            die("The file {$class_name}.php could not be found.");
        }
                


}

它还通过添加 URI 作为参数来支持云优化 GeoTiff (COG)。

答案 2 :(得分:0)

我认为问题是id = <?php echo $id; ?>; 。它不是将数据放在文件中,而是使用PREDICTOR预测器对数据差异进行LZW编码。这是Adobe专有的。我一直在寻找代码解密FLOATINGPOINT,我自己。我想this github link 可能有库代码,可以读取和解码它。

答案 3 :(得分:0)

您可以执行以下操作:

private void ReadTiff()
{
    Tiff tiff = Tiff.Open("myfile.tif", "r");
    if (tiff == null)
        return;

    //Get the image size
    int imageWidth = tiff.GetField(TiffTag.IMAGEWIDTH)[0].ToInt();
    int imageHeight = tiff.GetField(TiffTag.IMAGELENGTH)[0].ToInt();

    //Get the tile size
    int tileWidth = tiff.GetField(TiffTag.TILEWIDTH)[0].ToInt();
    int tileHeight = tiff.GetField(TiffTag.TILELENGTH)[0].ToInt();
    int tileSize = tiff.TileSize();

    //Pixel depth
    int depth = tileSize / (tileWidth * tileHeight);

    byte[] buffer = new byte[tileSize];

    for (int y = 0; y < imageHeight; y += tileHeight)
    {
        for (int x = 0; x < imageWidth; x += tileWidth)
        {
            //Read the value and store to the buffer
            tiff.ReadTile(buffer, 0, x, y, 0, 0);

            for (int kx = 0; kx < tileWidth; kx++)
            {
                for (int ky = 0; ky < tileHeight; ky++)
                {
                    //Calculate the index in the buffer
                    int startIndex = (kx + tileWidth * ky) * depth;
                    if (startIndex >= buffer.Length)
                        continue;

                    //Calculate pixel index
                    int pixelX = x + kx;
                    int pixelY = y + ky;
                    if (pixelX >= imageWidth || pixelY >= imageHeight)
                        continue;

                    //Get the value for the target pixel
                    double value = BitConverter.ToSingle(buffer, startIndex);
                }
            }
        }
    }

    tiff.Close();
}