2012-10-31 30 views
6

Muszę użyć gdal w projekcie C#. Rzeczą, którą muszę zrobić, to "przekonwertować" prostą bitmapę na GeoTiff. Czytałem dokumentację na stronie gdal, ale nie udało mi się jej sprawnie. W rzeczywistości moja bitmapy jest z powodzeniem eksportowane do GeoTIFF, ale jeśli mogę otworzyć GeoTiff z oprogramowaniem GIS (np QuantumGIS) GeoTiff jest odwrócony na osi y:Utwórz geotrofę z istniejącej bitmapy w języku C# z gdalem

enter image description here:

Zważywszy oryginalnej bitmapy wyglądać tak:

enter image description here

Oto co zrobiłem:

Pierwszy napisać pliku tymczasowego na dysku (czyli bitmapy), tworzę zbiór danych zawierający bitmap dzięki funkcji gdal (Gdal.Open (path)), i utworzyć nowy zestaw danych (z kierowcą GTiff) przy użyciu zestawu danych bitmapy, ustawić transformację geo i piszę GeoTiff do dysku:

String wktProj = null; 
    String tmpPath = @"C:\tmp.bmp"; 
    Bitmap tmpBitmap = bmp.Clone(new Rectangle(0, 0, bmp.Width, bmp.Height), pixFormat); 
    tmpBitmap.Save(tmpPath, ImageFormat.Bmp); 

    String[] options = null; 
    Gdal.AllRegister(); 
    OSGeo.GDAL.Driver srcDrv = Gdal.GetDriverByName("GTiff"); 
    Dataset srcDs = Gdal.Open(tmpPath, Access.GA_ReadOnly); 
    Dataset dstDs = srcDrv.CreateCopy(path, srcDs, 0, options, null, null); 

    //Set the map projection 
    Osr.GetWellKnownGeogCSAsWKT("WGS84", out wktProj); 
    dstDs.SetProjection(wktProj); 

    //Set the map georeferencing 
    double mapWidth = Math.Abs(latLongMap.listBounds.topRight.x - latLongMap.listBounds.bottomLeft.x); 
    double mapHeight = Math.Abs(latLongMap.listBounds.topRight.y - latLongMap.listBounds.bottomLeft.y); 
    double[] geoTransfo = new double[] { -5.14, mapWidth/bmp.Width, 0, 48.75, 0, mapHeight/bmp.Height }; 
    dstDs.SetGeoTransform(geoTransfo); 

    dstDs.FlushCache(); 
    dstDs.Dispose(); 
    srcDs.Dispose(); 
    srcDrv.Dispose(); 
    tmpBitmap.Dispose(); 

    File.Delete(tmpPath); 

Każdy pomysł na to, co robię źle?

Edycja Nie wiem, czy jest to ważne, ale bitmap pikseli to 8bppIndexed.

+0

Jakiej klasy używałeś do latLongMap? Dzięki. –

Odpowiedz

5

Aby rozwiązać ten problem I zastąpić ten wiersz:

double[] geoTransfo = new double[] { -5.14, mapWidth/bmp.Width, 0, 48.75, 0, mapHeight/bmp.Height }; 

Przez ten jeden:

double[] geoTransfo = new double[] { -5.14, mapWidth/bmp.Width, 0, 48.75, 0, (mapHeight/bmp.Height)*(-1) }; 

Wygląda rozmiar piksela (wysokość) musi być ujemny.

+2

Prawdopodobnie już dość oczywiste, ale współrzędne obrazu zaczynają się w lewym górnym rogu (rosnące wartości Y oznaczają kolejny wiersz danych pikseli), natomiast obraz geograficzny zaczyna się w lewym dolnym rogu. –

+0

@ErikVullings Masz całkowitą rację. Zapomniałem zaktualizować swoją odpowiedź tymi informacjami. Więc dziękuję za wskazanie tego;) – Ashbay