> ## Content Index
> Fetch the complete content index at: https://blog.anthea.day/llms.txt
> Use this file to discover other available public pages before exploring further.

# 歡迎來到 GIS 的世界－Day 10：用 GDAL 讀取
- URL: https://blog.anthea.day/series-2022-ithome-10/
- Published: 2022-09-23T16:02:19.000Z
- Updated: 2026-11-06T19:02:02.000Z
- Author: Anthea / 芫荽
- Tags: #Migrated-1792241843742, #Import 2026-10-17 12:57, Coding, 2022 iThome 鐵人賽：歡迎來到 GIS 的世界

既然有了 DotSpatial 可以處理 Shapefile，為甚麼我還要學習另外兩種工具呢?

### 神秘的問題

使用 DotSpatial 沒多久之後我就遇到了一個神奇的問題：資料庫的內容一樣，讀取的數量也都一樣，但每個環境：local、STG、Prod 所生產出來的 Shapefile 中，Feature 數量都不一樣。 😢

由於一直研究不出一個原因，所以我選擇改用別的套件，也就是我們接下來要介紹的 GDAL。

.NET Framework 和 .NET Core 所安裝的 Nuget 套件不太相同：

#### .NET Framework

安裝完下列的套件之後，會自動長出兩個 Configuration 的檔案，只需要保留副檔名是 .cs 的檔案就好，並且加上專案的命名空間就可以開始使用了。

![](https://cdn-images-1.medium.com/max/800/1*xhB0SMwXQXrh16va7bMRiA.png)

#### .NET / .NET Core

如果使用 .NET 安裝上面兩個套件的話，應該在運行時會出現錯誤：

```
Unable to load DLL 'gdal_wrap' or one of its dependencies
```

因此 .NET 需要改成安裝 `Gdal.Core` 才有辦法正常運行。

![](https://cdn-images-1.medium.com/max/800/1*0dJarAAH5eOFyhdFIoTAfg.png)

### 讀取

GDAL 對於 Shapefile 的讀取方式比較完整。之前有提到所有的內容都會寫在 Feature 上，而 Feature 的集合就是一層 Layer，一個 Shapefile 可以擁有多個 Layer。

這裡所讀取的檔案是我另外用 QGIS 建立的，有需要的話可以從 [GitHub](https://github.com/anthea-wu/GdalCsharpSimpleSample/tree/master/gdal-smaple/files/simple?ref=blog.anthea.day) 上取得。

```
// 註冊 GDAL
Gdal.AllRegister();
Ogr.RegisterAll();
// 開啟 SHP 檔案（0 - 讀取、1 - 讀寫）
var source = Ogr.Open("test.shp", (int)EnumShapefileOpen.ReadOnly);
var layerCount = source.GetLayerCount();
for (var i = 0; i < layerCount; i++)
{
    // 讀取圖層 Layer 資訊
    var layer = source.GetLayerByIndex(i);
    var fieldCount = layer.GetLayerDefn().GetFieldCount();
    for (var j = 0; j < fieldCount; j++)
    {
        var field = layer.GetLayerDefn().GetFieldDefn(j);
        var fieldName = field.GetName();
        Console.WriteLine($"欄位{j + 1}. {fieldName}");
    }
    
    // 讀取要素 Feature
    Feature feature;
    while ((feature = layer.GetNextFeature()) != null)
    {
        var id = feature.GetFieldAsInteger(0);
        Console.WriteLine($"內容1. Id: {id}");
        
        var name = feature.GetFieldAsString(1);
        Console.WriteLine($"內容2. 土地名稱: {name}");
        
        var area = feature.GetFieldAsInteger64(2);
        Console.WriteLine($"內容3. 土地面積: {area}");
        
        // 轉換成 WKT 的值
        var geometry = feature.GetGeometryRef();
        geometry.ExportToWkt(out var wkt);
        Console.WriteLine($"- WKT: {wkt}");
    }
}
public enum EnumShapefileOpen
{
    ReadOnly
}
```

執行後的結果如下：

![](https://cdn-images-1.medium.com/max/800/0*Ks_WeKVr-idqM2Fy.png)

而原本的檔案內容是長這樣：

![](https://cdn-images-1.medium.com/max/800/0*3bzUe-3-jYvWEgeU.png)

可以觀察到中文的內容會變成亂碼，但明明欄位的名稱原本也是中文，卻可以好好地顯示。這件事情不是單純改變檔案編碼可以解決的事情，因為需要花一點篇幅解釋，所以會把這個問題的原因和解法放在下一篇。

#### Reference

- [【C#】C#中使用GDAL3（二）：Windows下读写Shape文件及超详细解决中文乱码问题](https://www.cnblogs.com/litou/p/15035790.html?ref=blog.anthea.day)