Py3.8将存放经纬度的csv文件转为Shp文件(点要素和面要素)

写论文数据可视化需要用到shp文件,这里做个记录方便日后自己查看。
本文参考博主1博主2的代码改的(故不多解释,直接上数据和代码)。并附上PythonGIS相关的知识手册

1.数据路径和格式

在这里插入图片描述

下图中CSV文件里寸的是影像的名称和四角点以及中心点的经纬度坐标
在这里插入图片描述

2.源代码

下面给出了生成点要素和面要素的代码:

# 导入相关库
import os
from osgeo import ogr
import pandas as pd
from osgeo import osr
import glob

# 启动异常报错提示
ogr.UseExceptions()

# .shp文件保存路径
shp_path = r'F:\SHP'
# 输入的csv文件路径
csv_path = r'F:\SHP'

#点要素
def poin_shp():
    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] + '_point.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('Image', 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('Image', 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()

#面要素
def Polygon_shp():
    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] + '_Polygon.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.wkbPolygon)

        # 创建图层定义
        # 利用csv文件中有四个字段创建4个属性字段
        # Image字段
        station_fld = ogr.FieldDefn('Image', 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)

        # 读入csv文件信息,设置点几何的字段属性
        for i in range(len(csv_df)):
            # 设置属性值部分
            # 站点Id
            feature.SetField('Image', str(csv_df.iloc[i, 0]))
            # 纬度
            # feature.SetField('tl_lat', float(csv_df.iloc[i, 3]))
            # feature.SetField('tr_lat', float(csv_df.iloc[i, 5]))
            # feature.SetField('bl_lat', float(csv_df.iloc[i, 7]))
            # feature.SetField('br_lat', float(csv_df.iloc[i, 9]))
            # # 经度
            # feature.SetField('tl_lon', float(csv_df.iloc[i, 4]))
            # feature.SetField('tr_lon', float(csv_df.iloc[i, 6]))
            # feature.SetField('bl_lon', float(csv_df.iloc[i, 8]))
            # feature.SetField('br_lon', float(csv_df.iloc[i, 10]))

            # 设置几何信息部分
            # 利用经纬度创建点, X为经度, Y为纬度
            ring = ogr.Geometry(ogr.wkbLinearRing)
            ring.AddPoint(float(csv_df.iloc[i, 4]), float(csv_df.iloc[i, 3]))  #左上
            ring.AddPoint(float(csv_df.iloc[i, 6]), float(csv_df.iloc[i, 5]))   #右上
            ring.AddPoint(float(csv_df.iloc[i, 10]), float(csv_df.iloc[i, 9]))  # 右下
            ring.AddPoint(float(csv_df.iloc[i, 8]), float(csv_df.iloc[i, 7]))   #左下


            # 设定几何形状
            Polygon = ogr.Geometry(ogr.wkbPolygon)
            Polygon.AddGeometry(ring)

            # ds = ogr.Open(shp_path, True)
            # layer = ds.GetLayer(0)
            # feature = ogr.Feature(layer.GetLayerDefn())
            feature.SetGeometry(Polygon)


            # 将feature写入layer
            out_lyr.CreateFeature(feature)

        # 从内存中清除 ds,将数据写入磁盘中
        ds.Destroy()

if __name__ == "__main__":
     # poin_shp()  #点要素
     Polygon_shp()   #面要素

3.结果展示

转成功后便生成如下文档。
在这里插入图片描述
想要看到图形,用ArcMap打开即可。步骤为:ArcMap工具栏选择“文件”——"添加数据“——选择相应的”.SHP“文件即可。
在这里插入图片描述
这里就只展示图的一部分(点要素)。

在这里插入图片描述

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这是一个关于QGIS和Python编程的问题。我会尽力回答。 首先,需要安装QGIS软件,并确保已经安装了Python插件。然后,可以使用以下Python脚本实现批量将txt经纬度文件转换成shp文件: ```python import os from qgis.core import * import qgis.utils # 设置QGIS应用程序路径 QgsApplication.setPrefixPath("C:/Program Files/QGIS 3.10", True) qgs = QgsApplication([], False) qgs.initQgis() # 设置经纬度txt文件路径 input_folder = "C:/input_folder" # 设置输出shp文件路径 output_folder = "C:/output_folder" # 遍历输入文件夹中的所有txt文件 for file_name in os.listdir(input_folder): if file_name.endswith(".txt"): # 加载txt文件 uri = "file:///" + os.path.join(input_folder, file_name) + "?delimiter=," layer = QgsVectorLayer(uri, file_name[:-4], "delimitedtext") # 设置坐标系 crs = QgsCoordinateReferenceSystem(4326, QgsCoordinateReferenceSystem.EpsgCrsId) layer.setCrs(crs) # 保存为shp文件 output_file = os.path.join(output_folder, file_name[:-4] + ".shp") QgsVectorFileWriter.writeAsVectorFormat(layer, output_file, "UTF-8", crs, "ESRI Shapefile") print("Converted {} to {}".format(file_name, output_file)) # 退出QGIS应用程序 qgs.exitQgis() ``` 在这个脚本中,首先设置了QGIS应用程序的路径,并初始化了QGIS应用程序。然后,设置了输入文件夹和输出文件夹的路径,并遍历了输入文件夹中的所有txt文件。对于每个txt文件,首先使用QGIS的delimitedtext数据提供程序加载文件,并设置其坐标系为WGS 84。然后,使用QGIS的ESRI Shapefile格式将图层保存为shp文件。最后,退出QGIS应用程序。 希望这个脚本能够帮助到你。如果你有任何问题,请随时问我。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值