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文件所在(输入)路径:
Python使用gdal/ogr包以及pandas包批量将带经纬度信息的站点csv文件转为点shape文件_第1张图片
源代码如下:

# 导入相关库
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文件输出路径:
Python使用gdal/ogr包以及pandas包批量将带经纬度信息的站点csv文件转为点shape文件_第2张图片
QGIS打开.shp文件检查效果:
Python使用gdal/ogr包以及pandas包批量将带经纬度信息的站点csv文件转为点shape文件_第3张图片
打开属性表和.csv文件对比:Python使用gdal/ogr包以及pandas包批量将带经纬度信息的站点csv文件转为点shape文件_第4张图片
正确无误,perfect!

从写代码到测试代码再到运行代码,花了近3小时,不过,好在解决了,记录一下,以便后面可以参考一下,最近记忆力不太行,写代码都要翻下书本、手册了!

你可能感兴趣的:(GIS,gdal/ogr,Python遥感开发)