GDAL\OGR讀取數據示例 C#版本


首先創建一個Windows窗體應用程序,然后拖幾個按鈕和文本框,如下圖所示。第一行用來顯示柵格數據的路徑,點擊瀏覽找到一個柵格文件,將路徑顯示在文本框中,然后點擊讀取,將圖像的基本信息顯示在最下方的富文本框中;第二行的類似,顯示的是矢量數據的信息。

1、添加GDALC#版本的引用,注意只添加后面是_csharp.dll的四個文件。如下圖所示。

2、添加瀏覽按鈕的事件,代碼如下:

        private void buttonRaster_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Title = "打開柵格文件";
            ofd.Filter = @"Erdas Imagine (*.img)|*.img|
GeoTiff (*.tif *.tiff)|*.tif *.tiff|
PCIDSK (*.pix)|*.pix|
EarthWatch/DigitalGlobe (*.til)|*.til|
HDF (*.hdf *.h5 *he5)|*.hdf *.h5 *he5|
NITF (*.ntf *.nsf)|*.ntf *.nsf|
Spot DIMAP (metadata.dim)|metadata.dim|
位圖文件 (*.bmp)|*.bmp|
Graphics Interchange Format (*.gif)|*.gif|
JPEG (*.jpg *.jpeg)|*.jpg *.jpeg|
Portable Network Graphics (*.png)|*.png|
Web Map Servers (*.xml)|*.xml|所有文件|*.*";

            ofd.ShowDialog();
            textBoxRaster.Text = ofd.FileName;
        }

        private void buttonVector_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Title = "打開矢量文件";
            ofd.Filter = @"ESRI Shapefile(*.shp)|*.shp|
MapInfo File(*.mid *.mif *.tab)|*.mid *.mif *tab|
Arc/Info .E00 (*.e00)|*.e00|
AutoCAD DXF(*.dxf)|*.dxf|
Comma Separated Value (.csv)|*.csv|
GML(*.gml)|*.gml|
KML(*.kml)|*.kml|
所有文件|*.*";

            ofd.ShowDialog();
            textBoxVector.Text = ofd.FileName;
        }

3、添加讀取柵格和矢量數據信息的代碼,分別存在GDALReadFile.cs和OGRReadFile.cs文件中。具體代碼見下面:

首先是GDALReadFile.cs

using OSGeo.GDAL;
using OSGeo.OSR;
using System;

namespace GDALTest
{
    /// <summary>
    /// 使用GDAL讀取柵格數據信息類
    /// </summary>
    public class GDALReadFile
    {
        public static string GetRasterInfo(string strFilePath)
        {
            string strInfomation = "";
            try
            {
                /* -------------------------------------------------------------------- */
                /*      Register driver(s).                                             */
                /* -------------------------------------------------------------------- */
                Gdal.AllRegister();

                /* -------------------------------------------------------------------- */
                /*      Open dataset.                                                   */
                /* -------------------------------------------------------------------- */
                Dataset ds = Gdal.Open(strFilePath, Access.GA_ReadOnly);

                if (ds == null)
                {
                    strInfomation = ("Can't open " + strFilePath);
                    return strInfomation;
                }

                strInfomation += ("Raster dataset parameters:\n");
                strInfomation += ("  Projection: " + ds.GetProjectionRef() + "\n");
                strInfomation += ("  RasterCount: " + ds.RasterCount.ToString() + "\n");
                strInfomation += ("  RasterSize (" + ds.RasterXSize.ToString() + "," + ds.RasterYSize.ToString() + ")" + "\n");

                /* -------------------------------------------------------------------- */
                /*      Get driver                                                      */
                /* -------------------------------------------------------------------- */
                Driver drv = ds.GetDriver();

                if (drv == null)
                {
                    strInfomation += ("Can't get driver.");
                    return strInfomation;
                }

                strInfomation += ("Using driver " + drv.LongName);

                /* -------------------------------------------------------------------- */
                /*      Get metadata                                                    */
                /* -------------------------------------------------------------------- */
                string[] metadata = ds.GetMetadata("");
                if (metadata.Length > 0)
                {
                    strInfomation += ("  Metadata:");
                    for (int iMeta = 0; iMeta < metadata.Length; iMeta++)
                    {
                        strInfomation += ("    " + iMeta.ToString() + ":  " + metadata[iMeta] + "\n");
                    }
                    strInfomation += ("\n");
                }

                /* -------------------------------------------------------------------- */
                /*      Report "IMAGE_STRUCTURE" metadata.                              */
                /* -------------------------------------------------------------------- */
                metadata = ds.GetMetadata("IMAGE_STRUCTURE");
                if (metadata.Length > 0)
                {
                    strInfomation += ("  Image Structure Metadata:" + "\n");
                    for (int iMeta = 0; iMeta < metadata.Length; iMeta++)
                    {
                        strInfomation += ("    " + iMeta.ToString() + ":  " + metadata[iMeta] + "\n");
                    }
                    strInfomation += ("\n");
                }

                /* -------------------------------------------------------------------- */
                /*      Report subdatasets.                                             */
                /* -------------------------------------------------------------------- */
                metadata = ds.GetMetadata("SUBDATASETS");
                if (metadata.Length > 0)
                {
                    strInfomation += ("  Subdatasets:\n");
                    for (int iMeta = 0; iMeta < metadata.Length; iMeta++)
                    {
                        strInfomation += ("    " + iMeta.ToString() + ":  " + metadata[iMeta] + "\n");
                    }
                    strInfomation += ("\n");
                }

                /* -------------------------------------------------------------------- */
                /*      Report geolocation.                                             */
                /* -------------------------------------------------------------------- */
                metadata = ds.GetMetadata("GEOLOCATION");
                if (metadata.Length > 0)
                {
                    strInfomation += ("  Geolocation:\n");
                    for (int iMeta = 0; iMeta < metadata.Length; iMeta++)
                    {
                        strInfomation += ("    " + iMeta.ToString() + ":  " + metadata[iMeta] + "\n");
                    }
                    strInfomation += ("\n");
                }

                /* -------------------------------------------------------------------- */
                /*      Report corners.                                                 */
                /* -------------------------------------------------------------------- */
                strInfomation += ("Corner Coordinates:\n");
                strInfomation += ("  Upper Left (" + GDALInfoGetPosition(ds, 0.0, 0.0) + ")" + "\n");
                strInfomation += ("  Lower Left (" + GDALInfoGetPosition(ds, 0.0, ds.RasterYSize) + ")" + "\n");
                strInfomation += ("  Upper Right (" + GDALInfoGetPosition(ds, ds.RasterXSize, 0.0) + ")" + "\n");
                strInfomation += ("  Lower Right (" + GDALInfoGetPosition(ds, ds.RasterXSize, ds.RasterYSize) + ")" + "\n");
                strInfomation += ("  Center (" + GDALInfoGetPosition(ds, ds.RasterXSize / 2, ds.RasterYSize / 2) + ")" + "\n");
                strInfomation += ("\n");

                /* -------------------------------------------------------------------- */
                /*      Report projection.                                              */
                /* -------------------------------------------------------------------- */
                string projection = ds.GetProjectionRef();
                if (projection != null)
                {
                    SpatialReference srs = new SpatialReference(null);
                    if (srs.ImportFromWkt(ref projection) == 0)
                    {
                        string wkt;
                        srs.ExportToPrettyWkt(out wkt, 0);
                        strInfomation += ("Coordinate System is:\n");
                        strInfomation += (wkt);
                    }
                    else
                    {
                        strInfomation += ("Coordinate System is:\n");
                        strInfomation += (projection);
                    }
                }

                /* -------------------------------------------------------------------- */
                /*      Report GCPs.                                                    */
                /* -------------------------------------------------------------------- */
                if (ds.GetGCPCount() > 0)
                {
                    strInfomation += ("GCP Projection: " + ds.GetGCPProjection() + "\n");
                    GCP[] GCPs = ds.GetGCPs();
                    for (int i = 0; i < ds.GetGCPCount(); i++)
                    {
                        strInfomation += ("GCP[" + i.ToString() + "]: Id=" + GCPs[i].Id + ", Info=" + GCPs[i].Info + "\n");
                        strInfomation += ("          (" + GCPs[i].GCPPixel.ToString() + "," + GCPs[i].GCPLine.ToString() + ") -> ("
                                    + GCPs[i].GCPX.ToString() + "," + GCPs[i].GCPY.ToString() + "," + GCPs[i].GCPZ.ToString() + ")" + "\n");
                        strInfomation += ("");
                    }
                    strInfomation += ("\n");

                    double[] transform = new double[6];
                    Gdal.GCPsToGeoTransform(GCPs, transform, 0);
                    strInfomation += ("GCP Equivalent geotransformation parameters: " + ds.GetGCPProjection() + "\n");
                    for (int i = 0; i < 6; i++)
                        strInfomation += ("t[" + i + "] = " + transform[i].ToString() + "\n");
                    strInfomation += ("\n");
                }

                /* -------------------------------------------------------------------- */
                /*      Get raster band                                                 */
                /* -------------------------------------------------------------------- */
                for (int iBand = 1; iBand <= ds.RasterCount; iBand++)
                {
                    Band band = ds.GetRasterBand(iBand);
                    strInfomation += ("Band " + iBand.ToString() + " :\n");
                    strInfomation += ("   DataType: " + Gdal.GetDataTypeName(band.DataType) + "\n");
                    strInfomation += ("   ColorInterpretation: " + Gdal.GetColorInterpretationName(band.GetRasterColorInterpretation()) + "\n");
                    ColorTable ct = band.GetRasterColorTable();
                    if (ct != null)
                        strInfomation += ("   Band has a color table with " + ct.GetCount().ToString() + " entries.\n");

                    strInfomation += ("   Description: " + band.GetDescription() + "\n");
                    strInfomation += ("   Size (" + band.XSize.ToString() + "," + band.YSize.ToString() + ")" + "\n");
                    int BlockXSize, BlockYSize;
                    band.GetBlockSize(out BlockXSize, out BlockYSize);
                    strInfomation += ("   BlockSize (" + BlockXSize.ToString() + "," + BlockYSize.ToString() + ")" + "\n");
                    double val;
                    int hasval;
                    band.GetMinimum(out val, out hasval);
                    if (hasval != 0) strInfomation += ("   Minimum: " + val.ToString());
                    band.GetMaximum(out val, out hasval);
                    if (hasval != 0) strInfomation += ("   Maximum: " + val.ToString());
                    band.GetNoDataValue(out val, out hasval);
                    if (hasval != 0) strInfomation += ("   NoDataValue: " + val.ToString());
                    band.GetOffset(out val, out hasval);
                    if (hasval != 0) strInfomation += ("   Offset: " + val.ToString());
                    band.GetScale(out val, out hasval);
                    if (hasval != 0) strInfomation += ("   Scale: " + val.ToString());

                    for (int iOver = 0; iOver < band.GetOverviewCount(); iOver++)
                    {
                        Band over = band.GetOverview(iOver);
                        strInfomation += ("      OverView " + iOver + " :" + "\n");
                        strInfomation += ("         DataType: " + over.DataType + "\n");
                        strInfomation += ("         Size (" + over.XSize + "," + over.YSize + ")" + "\n");
                        strInfomation += ("         PaletteInterp: " + over.GetRasterColorInterpretation().ToString() + "\n");
                    }
                }
            }
            catch (Exception e)
            {
                strInfomation += ("Application error: " + e.Message);
            }

            return strInfomation;
        }

        private static string GDALInfoGetPosition(Dataset ds, double x, double y)
        {
            double[] adfGeoTransform = new double[6];
            double dfGeoX, dfGeoY;
            ds.GetGeoTransform(adfGeoTransform);

            dfGeoX = adfGeoTransform[0] + adfGeoTransform[1] * x + adfGeoTransform[2] * y;
            dfGeoY = adfGeoTransform[3] + adfGeoTransform[4] * x + adfGeoTransform[5] * y;

            return dfGeoX.ToString() + ", " + dfGeoY.ToString();
        }
    }
}

接着是OGRReadFile.cs文件:

using OSGeo.OGR;
using OSGeo.OSR;
using System;

/// <summary>
/// 使用OGR讀取矢量數據信息類
/// </summary>
public class OGRReadFile
{
    public static string GetVectorInfo(string strFilePath)
    {
        string strInfomation = "";

        /* -------------------------------------------------------------------- */
        /*      Register format(s).                                             */
        /* -------------------------------------------------------------------- */
        Ogr.RegisterAll();

        /* -------------------------------------------------------------------- */
        /*      Open data source.                                               */
        /* -------------------------------------------------------------------- */
        DataSource ds = Ogr.Open(strFilePath, 0);
        if (ds == null)
        {
            strInfomation = ("Can't open " + strFilePath);
            return strInfomation;
        }

        /* -------------------------------------------------------------------- */
        /*      Get driver                                                      */
        /* -------------------------------------------------------------------- */
        Driver drv = ds.GetDriver();
        if (drv == null)
        {
            strInfomation = ("Can't get driver.");
            return strInfomation;
        }

        // TODO: drv.name is still unsafe with lazy initialization (Bug 1339)
        strInfomation += ("Using driver " + drv.name);

        /* -------------------------------------------------------------------- */
        /*      Iterating through the layers                                    */
        /* -------------------------------------------------------------------- */

        for (int iLayer = 0; iLayer < ds.GetLayerCount(); iLayer++)
        {
            Layer layer = ds.GetLayerByIndex(iLayer);

            if (layer == null)
            {
                strInfomation = ("FAILURE: Couldn't fetch advertised layer " + iLayer);
                return strInfomation;
            }

            strInfomation += ReportLayer(layer);
        }

        return strInfomation;
    }

    public static string ReportLayer(Layer layer)
    {
        string strInfomation = "";
        FeatureDefn def = layer.GetLayerDefn();
        strInfomation += ("Layer name: " + def.GetName());
        strInfomation += ("Feature Count: " + layer.GetFeatureCount(1).ToString());
        Envelope ext = new Envelope();
        layer.GetExtent(ext, 1);
        strInfomation += ("Extent: " + ext.MinX.ToString() + "," + ext.MaxX.ToString() + "," +
            ext.MinY.ToString() + "," + ext.MaxY.ToString());

        /* -------------------------------------------------------------------- */
        /*      Reading the spatial reference                                   */
        /* -------------------------------------------------------------------- */
        OSGeo.OSR.SpatialReference sr = layer.GetSpatialRef();
        string srs_wkt;
        if (sr != null)
        {
            sr.ExportToPrettyWkt(out srs_wkt, 1);
        }
        else
            srs_wkt = "(unknown)";


        strInfomation += ("Layer SRS WKT: " + srs_wkt);

        /* -------------------------------------------------------------------- */
        /*      Reading the fields                                              */
        /* -------------------------------------------------------------------- */
        strInfomation += ("Field definition:");
        for (int iAttr = 0; iAttr < def.GetFieldCount(); iAttr++)
        {
            FieldDefn fdef = def.GetFieldDefn(iAttr);

            strInfomation += (fdef.GetNameRef() + ": " +
                 fdef.GetFieldTypeName(fdef.GetFieldType()) + " (" +
                 fdef.GetWidth().ToString() + "." +
                 fdef.GetPrecision().ToString() + ")");
        }

        /* -------------------------------------------------------------------- */
        /*      Reading the shapes                                              */
        /* -------------------------------------------------------------------- */
        strInfomation += ("");
        Feature feat;
        while ((feat = layer.GetNextFeature()) != null)
        {
            strInfomation += ReportFeature(feat, def);
            feat.Dispose();
        }

        return strInfomation;
    }

    public static string ReportFeature(Feature feat, FeatureDefn def)
    {
        string strInfomation = "";
        strInfomation += ("Feature(" + def.GetName() + "): " + feat.GetFID().ToString());
        for (int iField = 0; iField < feat.GetFieldCount(); iField++)
        {
            FieldDefn fdef = def.GetFieldDefn(iField);

            strInfomation += (fdef.GetNameRef() + " (" +
                fdef.GetFieldTypeName(fdef.GetFieldType()) + ") = ");

            if (feat.IsFieldSet(iField))
            {
                if (fdef.GetFieldType() == FieldType.OFTStringList)
                {
                    string[] sList = feat.GetFieldAsStringList(iField);
                    foreach (string s in sList)
                    {
                        strInfomation += ("\"" + s + "\" ");
                    }
                    strInfomation += ("\n");
                }
                else if (fdef.GetFieldType() == FieldType.OFTIntegerList)
                {
                    int count;
                    int[] iList = feat.GetFieldAsIntegerList(iField, out count);
                    for (int i = 0; i < count; i++)
                    {
                        strInfomation += (iList[i] + " ");
                    }
                    strInfomation += ("\n");
                }
                else if (fdef.GetFieldType() == FieldType.OFTRealList)
                {
                    int count;
                    double[] iList = feat.GetFieldAsDoubleList(iField, out count);
                    for (int i = 0; i < count; i++)
                    {
                        strInfomation += (iList[i].ToString() + " ");
                    }
                    strInfomation += ("\n");
                }
                else
                    strInfomation += (feat.GetFieldAsString(iField));
            }
            else
                strInfomation += ("(null)");

        }

        if (feat.GetStyleString() != null)
            strInfomation += ("  Style = " + feat.GetStyleString());

        Geometry geom = feat.GetGeometryRef();
        if (geom != null)
        {
            strInfomation += ("  " + geom.GetGeometryName() +
                "(" + geom.GetGeometryType() + ")");
            Geometry sub_geom;
            for (int i = 0; i < geom.GetGeometryCount(); i++)
            {
                sub_geom = geom.GetGeometryRef(i);
                if (sub_geom != null)
                {
                    strInfomation += ("  subgeom" + i + ": " + sub_geom.GetGeometryName() +
                        "(" + sub_geom.GetGeometryType() + ")");
                }
            }
            Envelope env = new Envelope();
            geom.GetEnvelope(env);
            strInfomation += ("   ENVELOPE: " + env.MinX + "," + env.MaxX + "," +
                env.MinY + "," + env.MaxY);

            string geom_wkt;
            geom.ExportToWkt(out geom_wkt);
            strInfomation += ("  " + geom_wkt);
        }

        strInfomation += ("\n");
        return strInfomation;
    }
}
4、寫完讀取代碼,然后編寫讀取按鈕的響應事件,具體代碼如下:

private void buttonRasterRead_Click(object sender, EventArgs e)
{
    string strRasterPath = textBoxRaster.Text;
    if (strRasterPath == "")
    {
        MessageBox.Show("請先選擇文件路徑", "提示");
        return;
    }

    string strInfomation = GDALReadFile.GetRasterInfo(strRasterPath);
    richTextBoxInfo.Text = strInfomation;
}

private void buttonVectorRead_Click(object sender, EventArgs e)
{
    string strVectorPath = textBoxVector.Text;
    if (strVectorPath == "")
    {
        MessageBox.Show("請先選擇文件路徑", "提示");
        return;
    }

    string strInfomation = OGRReadFile.GetVectorInfo(strVectorPath);
    richTextBoxInfo.Text = strInfomation;
}

5、做完上面的步驟,你就可以編譯了,編譯很順利,直接編譯過去了(如果你不能編譯過去,請查看錯誤並修改)。然后點擊運行,選擇一個柵格數據,然后點擊讀取,期待將圖像信息寫入下面的富文本框中,結果很悲劇的發現,出現了一個異常。群里很多人都遇到過這個異常,這個異常就是“Application error: “OSGeo.GDAL.GdalPINVOKE”的類型初始值設定項引發異常。”,截圖如下:

下面就開始解決這個異常,按照下面的步驟進行解決:

首先:確定自己引用的GDAL庫是正常的,檢驗正常的一個很方便的就是雙擊GDAL庫中bin文件夾里面的exe,如果一閃而過,基本上就正常的。如果提示錯誤信息,比如,應用程序無法正常啟動啥的,就先安裝編譯GDAL庫的VS對應版本的C++分發庫(也叫C++運行庫,名字叫vcredist_x86.exe或者vcredist_x64.exe,注意還有SP1之分)。

第二:假設通過安裝這個運行庫,GDAL庫可以正常啟動了,接下來把GDAL庫的C#版本里面的dll全部拷貝到C#程序編譯的exe所在目錄,比如我的是在【F:\Work\GDALTest\bin\Debug】,然后再次啟動程序,看看還拋出異常不,如果不拋出異常,那么恭喜你,下面的不用看了(我的電腦到這步結束后就正常了);如果還是拋出異常,不要着急,按照下面的步驟繼續。

第三:通過上面的步驟還是不行的話,將整個工程的【配置管理器】中改成與GDAL庫的版本一致,這里的版本指的是操作系統是32位還是64位,如果GDAL是32位的,那么在配置管理器中創建一個x86的平台,然后編譯整個工程;如果GDAL版本是64位的,那么創建一個x64的平台進行編譯。(這個步驟一般是會出現在使用32位的GDAL庫在64位的系統上開發會用到)。

第四:如果你通過上面三個步驟還是沒有解決的話,那我也不知道了……

最后截個圖,看看輸出的圖像信息和矢量信息,初學者可以參考這個來讀取柵格數據和矢量數據。程序的代碼打包在我的CSDN資源里面,下載地址是:http://download.csdn.net/detail/liminlu0314/4653881

—————————————華麗的分割線 下面的修改於2012年10月17日—————————————

昨天忘記測試中文路徑,發現果然中文路徑不支持,具體說明參考下一篇博客。不想看的請在上面的打開數據的代碼下面加下面的一句代碼。至於原因查看下一篇博文。

[csharp] view plaincopyprint?

  1. OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM