(資料科學學習手札143)為geopandas新增gdb檔案寫出功能

2022-09-20 18:02:31

本文範例程式碼已上傳至我的Github倉庫https://github.com/CNFeffery/DataScienceStudyNotes

1 簡介

  大家好我是費老師,很多讀者朋友跟隨著我先前寫作的基於geopandas的空間資料分析系列教學文章(快捷存取地址:https://www.cnblogs.com/feffery/tag/geopandas/),掌握了有關geopandas的諸多實用方法,從而更方便地在Python中處理分析GIS資料。其中在檔案IO篇中給大家介紹過針對ESRI GeoDataBase格式的檔案(也就是大家簡稱的gdb檔案),可以在指定圖層名layer引數後進行讀取,但無法進行gdb檔案的寫出操作。

  實際上geopandas是具有寫出向量資料到gdb檔案的能力的,只是需要額外設定一些軟體庫,今天的文章中,我就來帶大家學習如何簡單快捷地給geopandas補充gdb檔案寫出功能。

2 為geopandas補充gdb檔案寫出功能

2.1 為gdal新增FileGDB外掛

  在geopandas0.11版本之後,針對向量檔案的讀寫有預設的'fiona'和可選的'pyogrio'兩種引擎,請注意,本文的方案僅適用於預設的'fiona'引擎。

  而fiona底層依賴的則是著名的柵格向量資料轉換框架gdal,因此我們要給geopandas新增gdb寫出功能,本質上是需要給gdal新增相關功能。

  搞清楚問題的關鍵後,下面我們開始操作,這裡為了方便演示測試,我們利用conda新建一個geopandas虛擬環境,順便把jupyterlab也裝上,全部命令如下,直接全部貼上到終端執行即可:

conda create -n geopandas-write-gdb-test python=3.8 -c https://mirrors.sjtug.sjtu.edu.cn/anaconda/pkgs/main -y
conda activate geopandas-write-gdb-test
conda install geopandas -c https://mirrors.sjtug.sjtu.edu.cn/anaconda/cloud/conda-forge -y
pip install jupyterlab -i https://pypi.tuna.tsinghua.edu.cn/simple

  全部執行完之後,我們可以先檢視預設情況下fiona有哪些已有的讀寫驅動:

import fiona

fiona.supported_drivers

  可以看到其中列出的'OpenFileGDB'就是gdal中預設自帶的針對gdb檔案的驅動,其對應的值為'r'說明它只能針對gdb檔案進行讀取,我們要想寫出gdb檔案,需要額外設定新增Esri官方開發的FileGDB驅動。

  第一步,我們需要去下載FileGDB驅動檔案,Esri官方Github倉庫:https://github.com/Esri/file-geodatabase-api,按照https://www.lfd.uci.edu/~gohlke/pythonlibs/#gdal上有關gdal使用FileGDB外掛的額外說明,我選擇下載FileGDB的版本為https://github.com/Esri/file-geodatabase-api/blob/master/FileGDB_API_1.5.1/FileGDB_API_1_5_1-VS2015.zip(我在百度雲盤分享了一份備份,連結:https://pan.baidu.com/s/1f1ytxPjjjJWLwpbpDwY8Qg
提取碼:r2rf)。

  下載到本地解壓後,因為我是64位元windows系統,所以從bin64目錄下複製FileGDBAPI.dll檔案,貼上到我們前面利用conda新建的虛擬環境根目錄下的Library\bin裡。

  這個目錄找起來很簡單,因為所有用conda建立的虛擬環境,預設都位於你的conda安裝根目錄的envs目錄下,我的conda安裝根目錄在C:\Conda,因此我需要貼上前面檔案的目標目錄為C:\Conda\envs\geopandas-write-gdb-test\Library\bin

  第二步,我們還需要下載ogr_FileGDB.dll這個檔案,我是通過OSGeo4W下載的,有些麻煩,為了方便廣大讀者朋友使用,我在百度雲盤分享了一個備份(連結:https://pan.baidu.com/s/1VEtN6JAReFsDhnWl_8v6Eg
提取碼:w2s7),大家將其下載下來放置於前面FileGDBAPI.dll同級目錄下的gdalplugins目錄中即可:

  第三步,完成了這些操作後,我們就已經搞定了,這時回到fiona中再次檢視支援的驅動,可以看到多了FileGDB,且值為'raw',這代表我們已經擁有了寫出gdb檔案的能力:

2.2 在geopandas中測試寫出gdb檔案

  至此我們就可以進行gdb檔案的寫出了,只需要在to_file()中指定driver='FileGDB',並設定好對應的圖層名layer引數即可:

import geopandas as gpd
from shapely.geometry import Point, LineString, Polygon

demo_point_layer = gpd.GeoDataFrame(
    {
        '資料欄位測試': ['點要素測試資料欄位測試'],
        'geometry': [Point(0, 0)]
    },
    crs='EPSG:4326'
)
demo_linestring_layer = gpd.GeoDataFrame(
    {
        '資料欄位測試': ['線要素測試資料欄位測試'],
        'geometry': [LineString([(0, 0), (1, 1)])]
    },
    crs='EPSG:4326'
)
demo_polygon_layer = gpd.GeoDataFrame(
    {
        '資料欄位測試': ['面要素測試資料欄位測試'],
        'geometry': [Polygon([(0, 0), (1, 1), (1, 0)])]
    },
    crs='EPSG:4326'
)

# 寫出到範例gdb檔案中
demo_point_layer.to_file('./demo.gdb', layer='點圖層測試', driver='FileGDB')
demo_linestring_layer.to_file('./demo.gdb', layer='線圖層測試', driver='FileGDB')
demo_polygon_layer.to_file('./demo.gdb', layer='面圖層測試', driver='FileGDB')

  檢視目標gdb檔案的所有圖層名:

  讀入檢視向量,在讀入時建議不設定driver引數,因為預設的OpenFileGDB驅動讀取gdb檔案要更快:

  其中線要素與面要素讀進來不知為何變成了多部件要素型別,這其實不影響在geopandas中進行分析使用,但如果實在介意,可以直接基於數值唯一的某個欄位進行dissolve()操作即可恢復原樣:

  以上操作適用於windows系統,至於linux系統,且容我日後研究出來後再分享給大家