2012-10-04 2 views
0

문제가 있습니다. 나는 gdal_csharp.dll 라이브러리 (gdal_retile.py 스크립트 작업을 C#으로 다시 작성)를 사용하여 타일에 대한지도를 잘라 냈습니다. 하나의 경우를 제외하고는 모두 잘 작동합니다. nodata 값 (테두리에있는 타일)이있는 영역을 자르고 JPEG 개의 파일로 저장할 경우 nodata 영역은 검은 색 (및 나는 흰색이 필요합니다.) - 아래에 포함 된 예제 타일입니다. SetNoDataValue(/* what to write in here? */)을 설정하는 방법을 모르겠어요 Tile no1Tile no2검정색 대신 흰색 nodata 값

: 나는 tBand.SetNoDataValue(0);하지만 때로는 검은 not-nodata 값 (예 : 도시 이름, 도로 이름 등) 흰색 도트를 포함 ...

예 타일을 사용하려 ... 어쩌면이 문제를 해결할 다른 방법이 있을까요? 여기

내 방법입니다 :

private void CreatePyramidTile(MosaicInfo levelMosaicInfo, int offsetX, int offsetY, int width, int height, string tileName, DataSource ogrds) 
{ 
    double sx = levelMosaicInfo.ScaleX * _scaleFactor; 
    double sy = levelMosaicInfo.ScaleY * _scaleFactor; 

    AffineTransformDecorator dec = 
     new AffineTransformDecorator(new[] 
             { 
              levelMosaicInfo.Ulx + offsetX*sx, sx, 0, 
              levelMosaicInfo.Uly + offsetY*sy, 0, sy 
             }); 

    Dataset sFh = levelMosaicInfo.GetDataSet((int) Math.Round(dec.Ulx), 
              (int) Math.Round((dec.Uly + height*dec.ScaleY)), 
              (int) Math.Round((dec.Ulx + width*dec.ScaleX)), 
              (int) Math.Round(dec.Uly)); 

    if (sFh == null) 
    { 
     return; 
    } 

    if (ogrds != null) 
    { 
     var points = dec.PointsFor(width, height); 
     AddFeature(ogrds, tileName, points); 
    } 

    DataType bt; 
    if (_bandType == DataType.GDT_Unknown) 
    { 
     bt = levelMosaicInfo.BandType; 
    } 
    else 
    { 
     bt = _bandType; 
    } 

    double[] geotransform = { dec.Ulx, dec.ScaleX, 0, dec.Uly, 0, dec.ScaleY }; 
    int bands = levelMosaicInfo.Bands; 

    Dataset tFh; 
    if (_memDriver == null) 
    { 
     tFh = _driver.Create(tileName, width, height, bands, bt, _createOptions.ToArray()); 
    } 
    else 
    { 
     tFh = _memDriver.Create(tileName, width, height, bands, bt, _createOptions.ToArray()); 
    } 

    if (tFh == null) 
    { 
     throw new Exception("Creation failed, terminating gdal_tile."); 
    } 

    tFh.SetGeoTransform(geotransform); 
    tFh.SetProjection(levelMosaicInfo.Projection); 
// I think, the problem occurs in this loop; I tried to set nodata values 
    for (int band = 1; band < bands + 1; band++) 
    { 
     Band tBand = tFh.GetRasterBand(band); 

     if (levelMosaicInfo.Ct != null) 
     { 
      tBand.SetRasterColorTable(levelMosaicInfo.Ct); 
     } 
     tBand.SetRasterColorInterpretation(levelMosaicInfo.Ci[band - 1]); 
//    tBand.SetNoDataValue(0); 
    } 

    var res = Gdal.ReprojectImage(sFh, tFh, null, null, _resamplingMethod, 0, 0, null, null); 

    if (res != 0) 
    { 
     throw new Exception("Reprojection failed for " + tileName + ", error " + res + "."); 
    } 

    levelMosaicInfo.CloseDataSet(ref sFh); 

    if (_memDriver != null) 
    { 
     Dataset ttFh = _driver.CreateCopy(tileName, tFh, 0, _createOptions.ToArray(), null, null); 
     ttFh.Dispose(); 
    } 

    tFh.Dispose(); 
} 

[편집]
내가 루프 변경 ... 여전히 같은 문제가있다 :

for (int band = 1; band < bands + 1; band++) 
{ 
    Band tBand = tFh.GetRasterBand(band); 
    tBand.Fill(255, 0); 
    tBand.SetNoDataValue(255); 

    if (levelMosaicInfo.Ct != null) 
    { 
     tBand.SetRasterColorTable(levelMosaicInfo.Ct); 
    } 
    tBand.SetRasterColorInterpretation(levelMosaicInfo.Ci[band - 1]); 
} 

지금 내 문제가 나타날 수 있다고 생각을 내 전환 방법으로. 내가 얻은 데이터는 8-bit 형식입니다. 타일을 재 투영 한 후 검정색으로 90 % 채워집니다. 먼저 소스 데이터를 pct2rgb.py 스크립트 (C#으로 다시 작성)를 사용하여 24-bit으로 변환합니다.

public Dataset Convert8To24Bit() 
{ 
    Gdal.AllRegister(); 

    string[] argv = Gdal.GeneralCmdLineProcessor(_args, 0); 

    int i = 1; 
    while (i < argv.Count()) 
    { 
     string arg = argv.ElementAt(i); 
     switch (arg) 
     { 
      case "-of": 
       i++; 
       _format = argv[i]; 
       break; 
      case "-b": 
       i++; 
       _bandNumber = int.Parse(argv[i]); 
       break; 
      case "-rgba": 
       _outBands = 4; 
       break; 
      default: 
       if (string.IsNullOrEmpty(_srcFileName)) 
       { 
        _srcFileName = argv[i]; 
       } 
       else 
       { 
        Usage(); 
       } 
       break; 
     } 
     i++; 
    } 

    string tmpFileName = _srcFileName + ".bak"; 

    // open source file 
    Dataset srcDS = Gdal.Open(_srcFileName, Access.GA_ReadOnly); 
    if (srcDS == null) 
    { 
     throw new Exception("Unable to open " + _srcFileName + "."); 
    } 

    Band srcBand = srcDS.GetRasterBand(_bandNumber); 

    // ensure we recognise the driver 
    Driver dstDriver = Gdal.GetDriverByName(_format); 
    if (dstDriver == null) 
    { 
     throw new Exception("\"" + _format + "\" not registered."); 
    } 

    // build color table 
    int[][] lookup = new int[4][]; 
    lookup[0] = Enumerable.Range(0, 256).ToArray(); 
    lookup[1] = Enumerable.Range(0, 256).ToArray(); 
    lookup[2] = Enumerable.Range(0, 256).ToArray(); 
    lookup[3] = new int[256]; 

    for (i = 0; i < 256; i++) 
    { 
     lookup[3][i] = 255; 
    } 

    ColorTable ct = srcBand.GetRasterColorTable(); 

    if (ct != null) 
    { 
     for (i = 0; i < Math.Min(256, ct.GetCount()); i++) 
     { 
      ColorEntry entry = ct.GetColorEntry(i); 
      for (int j = 0; j < 4; j++) 
      { 
       switch (j) 
       { 
        case 0: 
         lookup[j][i] = entry.c1; 
         break; 
        case 1: 
         lookup[j][i] = entry.c2; 
         break; 
        case 2: 
         lookup[j][i] = entry.c3; 
         break; 
        case 3: 
         lookup[j][i] = entry.c4; 
         break; 
       } 
      } 
     } 
    } 
    else 
    { 
     return srcDS; 
    } 

    // create the working file 
    string tifFileName = string.Empty; 
    if (_format.Equals("GTiff", StringComparison.OrdinalIgnoreCase)) 
    { 
     tifFileName = tmpFileName; 
    } 
    else 
    { 
     tifFileName = Path.Combine(Directory.GetParent(tmpFileName).Name, "temp.gif"); 
    } 

//   Driver gTiffDriver = Gdal.GetDriverByName("GTiff"); 
    Driver gTiffDriver = Gdal.GetDriverByName("MEM"); 

    Dataset tifDS = gTiffDriver.Create(tifFileName, srcDS.RasterXSize, srcDS.RasterYSize, _outBands, DataType.GDT_Byte, 
             new string[] {}); 

    // we should copy projection information and so forth at this point 
    tifDS.SetProjection(srcDS.GetProjection()); 
    double[] geotransform = new double[6]; 
    srcDS.GetGeoTransform(geotransform); 
    tifDS.SetGeoTransform(geotransform); 

    if (srcDS.GetGCPCount() > 0) 
    { 
     tifDS.SetGCPs(srcDS.GetGCPs(), srcDS.GetGCPProjection()); 
    } 

    // do the processing one scanline at a time 
    for (int iY = 0; iY < srcDS.RasterYSize; iY++) 
    { 
     byte[] srcData = new byte[srcDS.RasterXSize*1]; 
     srcBand.ReadRaster(0, iY, srcDS.RasterXSize, 1, srcData, srcDS.RasterXSize, 1, 0, 0); 

     for (int iBand = 0; iBand < _outBands; iBand++) 
     { 
      int[] bandLookup = lookup[iBand]; 

      int[] dstData = new int[srcData.Count()]; 
      for (int index = 0; index < srcData.Count(); index++) 
      { 
       byte b = srcData[index]; 
       dstData[index] = bandLookup[b]; 
      } 

      tifDS.GetRasterBand(iBand + 1).WriteRaster(0, iY, srcDS.RasterXSize, 1, dstData, 
                 srcDS.RasterXSize, 1, 0, 0); 
     } 
    } 

//   if (tifFileName != _srcFileName) 
//   { 
//    tifDS = Gdal.Open(tifFileName, Access.GA_ReadOnly); 
//    dstDriver.CreateCopy(_srcFileName, tifDS, 0, new string[] { }, null, null);; 
//   } 

    srcDS.Dispose(); 

    return tifDS; 
} 

전체 클래스 :

여기 코드의 래스터를 들어 GdalRetile.csTiffConverter.cs

답변

0

좋아, 나는 이것을위한 해결책을 발견했다! 나는 결과물 타일의 배경 인 흰색에 내 TEMP 이미지를 간단히 채웠다. GetDataSet() 방법으로 만든

변경 : 위의

Dataset resultDS = _tempDriver.Create("TEMP", resultSizeX, resultSizeY, _bands, _bandType, new string[] { });

라인 변경 :

Dataset resultDS = _tempDriver.Create("TEMP", resultSizeX, resultSizeY, _bands, _bandType, new string[] { }); 
for (int i = 1; i < _bands + 1; i++) 
{ 
    Band band = resultDS.GetRasterBand(i); 
    band.Fill(255, 0); 
} 
2

, NODATA 항상 존중되지 않습니다. JPEG는 대부분의 소프트웨어에서 NoData 메타 데이터를 준수하지 않습니다. 따라서 NoData가 '0'이면 검은 색의 픽셀 값으로 해석 될 수 있습니다. 기본적으로 래스터는 0 또는 검정색으로 채워집니다. NoData가 무엇인지 다시 정의하면됩니다. 당신이 흰색되고 싶어하고 픽셀 형식이 바이트의 경우, 그것은 제안으로 255

을해야한다, 데이터 세트를 생성 후 데이터를로드하기 전에,이 시도 :

... 
    Band tBand = tFh.GetRasterBand(band); 
    tBand.Fill(255); // otherwise it is filled with 0 
    tBand.SetNoDataValue(255); // set metadata 
... 
+0

그것은 나를 위해 작동하지만, 내 편집을하시기 바랍니다 확인하지 않았다. 어쩌면 그게 문제 야 ... :( – Nickon