python使用gdal对shp读取,新建和更新的实例


Posted in Python onMarch 10, 2020

昨天要处理一个shp文件,读取里面的信息,做个计算然后写到后面新建的field里面。先写个外面网上都能找到的新建和读取吧。

1.读取shp文件

#-*- coding: cp936 -*-
try:
   from osgeo import gdal
   from osgeo import ogr
exceptImportError:
   import gdal
   import ogr
 
defReadVectorFile():
   # 为了支持中文路径,请添加下面这句代码
   gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8","NO")
   # 为了使属性表字段支持中文,请添加下面这句
   gdal.SetConfigOption("SHAPE_ENCODING","")
 
   strVectorFile ="E:\\Datum\\GDALCsTest\\Debug\\beijing.shp"
 
   # 注册所有的驱动
   ogr.RegisterAll()
 
   #打开数据
   ds = ogr.Open(strVectorFile, 0)
   if ds == None:
     print("打开文件【%s】失败!", strVectorFile)
     return
 
   print("打开文件【%s】成功!", strVectorFile)
 
   # 获取该数据源中的图层个数,一般shp数据图层只有一个,如果是mdb、dxf等图层就会有多个
   iLayerCount = ds.GetLayerCount()
 
   # 获取第一个图层
   oLayer = ds.GetLayerByIndex(0)
   if oLayer == None:
     print("获取第%d个图层失败!\n", 0)
     return
 
   # 对图层进行初始化,如果对图层进行了过滤操作,执行这句后,之前的过滤全部清空
   oLayer.ResetReading()
 
   # 通过属性表的SQL语句对图层中的要素进行筛选,这部分详细参考SQL查询章节内容
   oLayer.SetAttributeFilter("\"NAME99\"LIKE \"北京市市辖区\"")
 
   # 通过指定的几何对象对图层中的要素进行筛选
   #oLayer.SetSpatialFilter()
 
   # 通过指定的四至范围对图层中的要素进行筛选
   #oLayer.SetSpatialFilterRect()
 
   # 获取图层中的属性表表头并输出
   print("属性表结构信息:")
   oDefn = oLayer.GetLayerDefn()
   iFieldCount = oDefn.GetFieldCount()
   for iAttr in range(iFieldCount):
     oField =oDefn.GetFieldDefn(iAttr)
     print( "%s: %s(%d.%d)" % ( \
          oField.GetNameRef(),\
          oField.GetFieldTypeName(oField.GetType() ), \
          oField.GetWidth(),\
          oField.GetPrecision()))
 
   # 输出图层中的要素个数
   print("要素个数 = %d", oLayer.GetFeatureCount(0))
 
   oFeature = oLayer.GetNextFeature()
   # 下面开始遍历图层中的要素
   while oFeature is not None:
     print("当前处理第%d个: \n属性值:", oFeature.GetFID())
     # 获取要素中的属性表内容
     for iField inrange(iFieldCount):
       oFieldDefn =oDefn.GetFieldDefn(iField)
       line = " %s (%s) = " % ( \
            oFieldDefn.GetNameRef(),\
            ogr.GetFieldTypeName(oFieldDefn.GetType()))
 
       ifoFeature.IsFieldSet( iField ):
          line = line+ "%s" % (oFeature.GetFieldAsString( iField ) )
       else:
          line = line+ "(null)"
 
       print(line)
  
     # 获取要素中的几何体
     oGeometry =oFeature.GetGeometryRef()
 
     # 为了演示,只输出一个要素信息
     break
 
   print("数据集关闭!")

2.新建shp文件

#-*- coding: cp936 -*-
try:
   from osgeo import gdal
   from osgeo import ogr
exceptImportError:
   import gdal
   import ogr
 
defWriteVectorFile():
   # 为了支持中文路径,请添加下面这句代码
   gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8","NO")
   # 为了使属性表字段支持中文,请添加下面这句
   gdal.SetConfigOption("SHAPE_ENCODING","")
 
   strVectorFile ="E:\\TestPolygon.shp"
 
   # 注册所有的驱动
   ogr.RegisterAll()
 
   # 创建数据,这里以创建ESRI的shp文件为例
   strDriverName = "ESRIShapefile"
   oDriver =ogr.GetDriverByName(strDriverName)
   if oDriver == None:
     print("%s 驱动不可用!\n", strDriverName)
     return
  
   # 创建数据源
   oDS =oDriver.CreateDataSource(strVectorFile)
   if oDS == None:
     print("创建文件【%s】失败!", strVectorFile)
     return
 
   # 创建图层,创建一个多边形图层,这里没有指定空间参考,如果需要的话,需要在这里进行指定
   papszLCO = []
   oLayer =oDS.CreateLayer("TestPolygon", None, ogr.wkbPolygon, papszLCO)
   if oLayer == None:
     print("图层创建失败!\n")
     return
 
   # 下面创建属性表
   # 先创建一个叫FieldID的整型属性
   oFieldID =ogr.FieldDefn("FieldID", ogr.OFTInteger)
   oLayer.CreateField(oFieldID, 1)
 
   # 再创建一个叫FeatureName的字符型属性,字符长度为50
   oFieldName =ogr.FieldDefn("FieldName", ogr.OFTString)
   oFieldName.SetWidth(100)
   oLayer.CreateField(oFieldName, 1)
 
   oDefn = oLayer.GetLayerDefn()
 
   # 创建三角形要素
   oFeatureTriangle = ogr.Feature(oDefn)
   oFeatureTriangle.SetField(0, 0)
   oFeatureTriangle.SetField(1, "三角形")
   geomTriangle =ogr.CreateGeometryFromWkt("POLYGON ((0 0,20 0,10 15,0 0))")
   oFeatureTriangle.SetGeometry(geomTriangle)
   oLayer.CreateFeature(oFeatureTriangle)
 
   # 创建矩形要素
   oFeatureRectangle = ogr.Feature(oDefn)
   oFeatureRectangle.SetField(0, 1)
   oFeatureRectangle.SetField(1, "矩形")
   geomRectangle =ogr.CreateGeometryFromWkt("POLYGON ((30 0,60 0,60 30,30 30,30 0))")
   oFeatureRectangle.SetGeometry(geomRectangle)
   oLayer.CreateFeature(oFeatureRectangle)
 
   # 创建五角形要素
   oFeaturePentagon = ogr.Feature(oDefn)
   oFeaturePentagon.SetField(0, 2)
   oFeaturePentagon.SetField(1, "五角形")
   geomPentagon =ogr.CreateGeometryFromWkt("POLYGON ((70 0,85 0,90 15,80 30,65 15,700))")
   oFeaturePentagon.SetGeometry(geomPentagon)
   oLayer.CreateFeature(oFeaturePentagon)
 
   oDS.Destroy()
   print("数据集创建完成!\n")

3.更新

其实更新无非就是获取到field然后设置新值就可以了

其实用SetField()方法就行

import os,sys
from osgeo import gdal
from osgeo import ogr
from osgeo import osr
import numpy
import transformer
# 为了支持中文路径,请添加下面这句代码
 
 
pathname = sys.argv[1]
choose = sys.argv[2]
gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "NO")
# 为了使属性表字段支持中文,请添加下面这句
gdal.SetConfigOption("SHAPE_ENCODING", "")
# 注册所有的驱动
ogr.RegisterAll()
# 数据格式的驱动
driver = ogr.GetDriverByName('ESRI Shapefile')
ds = driver.Open(pathname, update=1)
if ds is None:
 print 'Could not open %s'%pathname
 sys.exit(1)
# 获取第0个图层
layer0 = ds.GetLayerByIndex(0);
# 投影
spatialRef = layer0.GetSpatialRef();
# 输出图层中的要素个数
print '要素个数=%d'%(layer0.GetFeatureCount(0))
print '属性表结构信息'
defn = layer0.GetLayerDefn()
fieldindex = defn.GetFieldIndex('x')
xfield = defn.GetFieldDefn(fieldindex)
#新建field
fieldDefn = ogr.FieldDefn('newx', xfield.GetType())
fieldDefn.SetWidth(32)
fieldDefn.SetPrecision(6)
layer0.CreateField(fieldDefn,1)
fieldDefn = ogr.FieldDefn('newy', xfield.GetType())
fieldDefn.SetWidth(32)
fieldDefn.SetPrecision(6)
layer0.CreateField(fieldDefn,1)
feature = layer0.GetNextFeature()
# 下面开始遍历图层中的要素
while feature is not None:
 # 获取要素中的属性表内容
 x = feature.GetFieldAsDouble('x')
 y = feature.GetFieldAsDouble('y')
 newx, newy = transformer.begintrans(choose, x, y)
 feature.SetField('newx', newx)
 feature.SetField('newy', newy)
 layer0.SetFeature(feature)
 feature = layer0.GetNextFeature()
feature.Destroy()
ds.Destroy()

这里我其实想说最重要的是这个SetFeature(),就是你更新好了field的feature一定要重新set一下,不然是根本起不到任何改变的。新建的时候有createfeature,已经设置了,所以不需要set。

网上的教程都是新建和读取,都没有提到这个,结果自己蠢到试了好久都没有发现问题在哪,以为是什么数据类型与设置字段属性不匹配,一头雾水哈哈哈。

补充知识:python使用GDAL生成shp文件

GDAL是一个开源的地理工具包,其支持基本所有的地理操作,其有python、java、c等语言包,是地理信息C端开发不可越过的工具,鉴于python语言的简单性,这里使用python中GDAL包来进行shp文件的生成,这里本质是利用ogc地理标准的坐标字符串来生成shp。

第一步:安装GDAL环境,建议下载后,本地安装,注意与python版本号要对应,可参考网上教程。

第二部:代码分析

引入GDAL工具包

import osgeo.ogr as ogr
import osgeo.osr as osr

注册驱动,这里是ESRI Shapefile类型,并设置shp文件名称

driver = ogr.GetDriverByName("ESRI Shapefile")
data_source = driver.CreateDataSource("ceshi.shp")

注入投影信息,这里使用的4326,表示经纬度坐标,根据情况可以自行更改

srs = osr.SpatialReference()
srs.ImportFromEPSG(4326)

这里定义的是,生成的要素类型,包括点、线、面

#ogr.wkbPoint 点
#ogr.wkbLineString 线
#ogr.wkbMultiPolygon 面

这里的图层名称要与上面注册驱动的shp名称一致

layer = data_source.CreateLayer("ceshi", srs, ogr.wkbLineString)

这里设置要素的属性字段,其中设置了两个字段,分别是Name、data,其中ogr.OFTString表示字符串类型,其长度都是14字节,可自行设置宽度

python使用gdal对shp读取,新建和更新的实例

field_name = ogr.FieldDefn("Name", ogr.OFTString)
field_name.SetWidth(14)
layer.CreateField(field_name)
field_name = ogr.FieldDefn("data", ogr.OFTString)
field_name.SetWidth(14)
layer.CreateField(field_name)

在生成的字段名中插入要素值,即属性表中每行的值

feature = ogr.Feature(layer.GetLayerDefn())
feature.SetField("Name", "ceshi")
feature.SetField("data", "1.2")

核心部分,生成line数据

其中各要素格式如下:

POINT(6 10)
LINESTRING(3 4,10 50,20 25)
POLYGON((1 1,5 1,5 5,1 5,1 1),(2 2,2 3,3 3,3 2,2 2))
MULTIPOINT(3.5 5.6, 4.8 10.5)
MULTILINESTRING((3 4,10 50,20 25),(-5 -8,-10 -8,-15 -4))
MULTIPOLYGON(((1 1,5 1,5 5,1 5,1 1),(2 2,2 3,3 3,3 2,2 2)),((6 3,9 2,9 4,6 3)))
GEOMETRYCOLLECTION(POINT(4 6),LINESTRING(4 6,7 10))
POINT ZM (1 1 5 60)
POINT M (1 1 80)

需要注意的是,这里应该与上面定义的生成要素的类型保持一致,最后是清空缓存,这里多说一句,字符串语法与postgis等开源gis一致,都遵循ogc国际标准

wkt = 'LINESTRING(3 4,10 50,20 25)'
line = ogr.CreateGeometryFromWkt(wkt)
feature.SetGeometry(line)
layer.CreateFeature(feature)

feature = None
data_source = None

结果如下:

python使用gdal对shp读取,新建和更新的实例

用arcgis打开

python使用gdal对shp读取,新建和更新的实例

可以使用该方法,下载在线shp数据,只需要知道所需要素的geojson格式数据中坐标串即可。或者图像识别中获取的矢量边界赋予经纬度。

以上这篇python使用gdal对shp读取,新建和更新的实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python 远程统计文件代码分享
May 14 Python
Python中subprocess模块用法实例详解
May 20 Python
对于Python中RawString的理解介绍
Jul 07 Python
Python实现基本数据结构中队列的操作方法示例
Dec 04 Python
win10环境下配置vscode python开发环境的教程详解
Oct 16 Python
浅谈PyTorch的可重复性问题(如何使实验结果可复现)
Feb 20 Python
Python对象的属性访问过程详解
Mar 05 Python
使用scrapy ImagesPipeline爬取图片资源的示例代码
Sep 28 Python
Python获取指定网段正在使用的IP
Dec 14 Python
Pytorch1.5.1版本安装的方法步骤
Dec 31 Python
浅谈Python基础之列表那些事儿
May 11 Python
python 如何将两个实数矩阵合并为一个复数矩阵
May 19 Python
Python实现获取当前目录下文件名代码详解
Mar 10 #Python
python爬虫开发之使用python爬虫库requests,urllib与今日头条搜索功能爬取搜索内容实例
Mar 10 #Python
python+gdal+遥感图像拼接(mosaic)的实例
Mar 10 #Python
python获取栅格点和面值的实现
Mar 10 #Python
Python列表切片常用操作实例解析
Mar 10 #Python
Python numpy多维数组实现原理详解
Mar 10 #Python
python中使用you-get库批量在线下载bilibili视频的教程
Mar 10 #Python
You might like
ThinkPHP的模版中调用session数据的方法
2014/07/01 PHP
php无限分类使用concat如何实现
2015/11/05 PHP
PHP+Jquery与ajax相结合实现下拉淡出瀑布流效果【无需插件】
2016/05/06 PHP
微信公众号开发之获取位置信息php代码
2018/06/13 PHP
PHP赋值的内部是如何跑的详解
2019/01/13 PHP
Thinkphp5框架实现获取数据库数据到视图的方法
2019/08/14 PHP
两种WEB下的模态对话框 (asp.net或js的分别实现)
2009/12/02 Javascript
bgsound 背景音乐 的一些常用方法及特殊用法小结
2010/05/11 Javascript
js 有框架页面跳转(target)三种情况下的应用
2013/04/09 Javascript
不使用jquery实现js打字效果示例分享
2014/01/19 Javascript
js中的for如何实现foreach中的遍历
2014/05/31 Javascript
JQuery对ASP.NET MVC数据进行更新删除
2016/07/13 Javascript
JS实现的五级联动菜单效果完整实例
2017/02/23 Javascript
footer定位页面底部(代码分享)
2017/03/07 Javascript
使用vue的v-for生成table并给table加上序号的实例代码
2017/10/27 Javascript
解决vue页面DOM操作不生效的问题
2018/03/17 Javascript
浅析Vue 生命周期
2018/06/21 Javascript
解决ie11 SCRIPT5011:不能执行已释放Script的代码问题
2019/05/05 Javascript
[40:56]2018DOTA2亚洲邀请赛 3.31 小组赛 A组 Liquid vs TNC
2018/04/01 DOTA
pycharm 使用心得(一)安装和首次使用
2014/06/05 Python
浅谈python新手中常见的疑惑及解答
2016/06/14 Python
python实现发送邮件及附件功能
2021/03/02 Python
python使用Apriori算法进行关联性解析
2017/12/21 Python
Python之ReportLab绘制条形码和二维码的实例
2018/01/15 Python
安装Pycharm2019以及配置anconda教程的方法步骤
2019/11/11 Python
Python实现PS滤镜中的USM锐化效果
2020/12/04 Python
基于css3的属性transition制作菜单导航效果
2015/09/01 HTML / CSS
MAC Cosmetics巴西官方网站:M·A·C彩妆
2019/04/18 全球购物
管理信息系学生的自我评价
2014/01/11 职场文书
志愿者活动总结
2014/04/28 职场文书
普通党员自我剖析材料
2014/10/07 职场文书
婚礼新人答谢词
2015/01/04 职场文书
2015年事业单位工作总结
2015/04/27 职场文书
赵氏孤儿观后感
2015/06/09 职场文书
五年级作文之想象作文
2019/10/30 职场文书
Python中requests库的用法详解
2022/06/05 Python