Python使用gdal/ogr包以及pandas包批量將帶經緯度信息的站點csv文件轉爲點shape文件

近日,接到一個博士師兄的要求,希望我寫一個Python程序,將其2006-2099年各年份的帶經緯度的站點模擬數據.csv文件轉爲點shape文件(.shp)。網上有利用arcpy轉的,也有利用shapely包轉的,但是,作爲開源GIS/RS愛好者,gdal/ogr包作爲開源GIS官方(osgeo)社區維護的包,很多較爲底層的操作都能實現,當然,是最好的選擇。不過,由於操作較爲底層也相對較爲繁瑣一些。當然,我們希望儘可能用一個Python包儘可能做更多的事情,如無必要,儘量減少引入依賴的第三方包,以減少後面程序維護的麻煩。

這裏是使用gdal/ogr和pandas(以及Python自帶的包:os,glob包)實現的將csv文件帶經緯度信息的站點csv文件轉爲點shape文件。(csv文件有個字段:站點id(字符串類型),緯度(浮點型),經度(浮點型),站點預測值(浮點型), 注意各字段的精度就行)

.csv文件所在(輸入)路徑:
在這裏插入圖片描述
源代碼如下:

# 導入相關庫
import os
from osgeo import ogr
import pandas as pd
from osgeo import osr
import glob

# 啓動異常報錯提示
ogr.UseExceptions()

# .shp文件保存路徑
shp_path = r'F:\多種模式平均後降尺度\Site149RCP降尺度數據Shp_2006-2099\rcp85\平均氣溫tas'
# 輸入的csv文件路徑
csv_path = r'F:\多種模式平均後降尺度\Site149RCP降尺度數據CSV_2006-2099\rcp85\平均氣溫tas'

for csv_filename in glob.glob(os.path.join(csv_path,'*.csv')):

    # 讀入csv文件信息,設置點幾何的字段屬性
    csv_df = pd.read_csv(csv_filename)

    # 利用.csv文件創建一個點shp文件
    
    # 獲取驅動
    driver = ogr.GetDriverByName('ESRI Shapefile')
    
    # 創建數據源
    shp_filename = os.path.basename(csv_filename)[:-4] + '.shp'
    # 檢查數據源是否已存在
    if os.path.exists(os.path.join(shp_path, shp_filename)):
        driver.DeleteDataSource(os.path.join(shp_path, shp_filename))    
    ds = driver.CreateDataSource(os.path.join(shp_path, shp_filename))
    
    # 圖層名
    layer_name = os.path.basename(csv_filename)[:-4]
    
    # 定義座標系對象
    sr = osr.SpatialReference()
    # 使用WGS84地理座標系
    sr.ImportFromEPSG(4326)
    
    # 創建點圖層, 並設置座標系
    out_lyr = ds.CreateLayer(layer_name, srs = sr, geom_type=ogr.wkbPoint)
    
    # 創建圖層定義
    # 利用csv文件中有四個字段創建4個屬性字段
    # station字段
    station_fld = ogr.FieldDefn('station', ogr.OFTString)
    station_fld.SetWidth(6)
    out_lyr.CreateField(station_fld)
    # Latitude字段
    lat_fld = ogr.FieldDefn('latitude', ogr.OFTReal)
    lat_fld.SetWidth(9)
    lat_fld.SetPrecision(5)
    out_lyr.CreateField(lat_fld)
    # Longitude字段
    lon_fld = ogr.FieldDefn('longitude', ogr.OFTReal)
    lon_fld.SetWidth(9)
    lon_fld.SetPrecision(5)
    out_lyr.CreateField(lon_fld)
    
    # # pr字段
    # pr_fld = ogr.FieldDefn('pr', ogr.OFTReal)
    # pr_fld.SetWidth(5)
    # pr_fld.SetPrecision(2)
    # out_lyr.CreateField(pr_fld)

    # tas字段
    tas_fld = ogr.FieldDefn('tas', ogr.OFTReal)
    tas_fld.SetWidth(6)
    tas_fld.SetPrecision(2)
    out_lyr.CreateField(tas_fld)
    # 從layer中讀取相應的feature類型,並創建feature
    featureDefn = out_lyr.GetLayerDefn()
    feature = ogr.Feature(featureDefn)
    
    # 設定幾何形狀
    point = ogr.Geometry(ogr.wkbPoint)
    
    # 讀入csv文件信息,設置點幾何的字段屬性
    for i in range(len(csv_df)):
        
        # 設置屬性值部分
        # 站點Id
        feature.SetField('station', str(csv_df.iloc[i, 0]))
        # 緯度
        feature.SetField('latitude', float(csv_df.iloc[i, 1]))
        # 經度
        feature.SetField('longitude', float(csv_df.iloc[i, 2]))
        # # pr值
        # feature.SetField('pr', float(csv_df.iloc[i, 3]))
        # tas值
        feature.SetField('tas', float(csv_df.iloc[i, 3]))
        
        # 設置幾何信息部分
        # 利用經緯度創建點, X爲經度, Y爲緯度
        point.AddPoint(float(csv_df.iloc[i, 2]), float(csv_df.iloc[i, 1]))
        feature.SetGeometry(point)
        
        # 將feature寫入layer
        out_lyr.CreateFeature(feature)
    
    # 從內存中清除 ds,將數據寫入磁盤中
    ds.Destroy()

程序運行後效果:
.shp文件輸出路徑:
在這裏插入圖片描述
QGIS打開.shp文件檢查效果:
在這裏插入圖片描述
打開屬性表和.csv文件對比:在這裏插入圖片描述
正確無誤,perfect!

從寫代碼到測試代碼再到運行代碼,花了近3小時,不過,好在解決了,記錄一下,以便後面可以參考一下,最近記憶力不太行,寫代碼都要翻下書本、手冊了!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章