python+gdal读取txt解析成WKT标准格式直接绘制ploygon
当我有这样一份txt数据的时候,我如何将这些坐标点转换生成polygon呢?能不能直接识别。
那么我怎么实现,识别成标准的格式呢,首先想到的是 开源GIS格式——WKT、WKB与GeoJSON
处理思考
首先,解析下txt前面的0代表的是每一个polygon的属性信息,需要写到属性表内;其次是每行txt数据后面的坐标值,也就是逗号分隔的,一个代表x坐标一个代表y坐标;
注:此处放的文本,小编只是为了说明,前期数据的格式,txt中的坐标值,小编应文本所有者要求有做过更改,大家在使用的时候,可以直接替换成自己的数据。
WKT(well-known text)
是一种文本标记语言,该格式由开放地理空间联盟OGC(Open GIS Consortium )制定,用于表示矢量几何对象、空间参照系统及空间参照系统之间的转换,在数据传输与数据库存储时,常用到它的二进制形式,即WKB(well-known binary)。
WKB(well-known binary)
是WKT的二进制表示形式,解决了WKT表达方式冗余的问题,便于传输和在数据库中存储相同的信息。
WKT与WKB在GIS中的重要作用在于,他们能利用文本简洁明了的表达矢量空间要素的几何信息,使得几何信息能以字段的形式存储于数据库中。
目前,PostGIS中无论是WKT还是WKB,所支持的矢量数据类型都是相同的7种,除去以上3种简单要素类型oint, MultiPoint、LineString, MultiLineString、Polygon, MultiPolygon外,还有如下4种复合类型:
• MULTIPOINT
• MULTILINESTRING
• MULTIPOLYGON
• GEOMETRYCOLLECTION
下面,我们看一下这几种类型的形式:
POINT(15 20)
点坐标指定时不带逗号。
四个点组织的LineString线数据:
· LINESTRING(0 0, 10 10, 20 25, 50 60)
请注意,线字符中每个点的坐标 是以逗号分隔开来的。
一个具有内环和外环的Polygon :
· POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))
具有三个Point值的MultiPoint多点:
· MULTIPOINT(0 0, 20 20, 60 60)
具有两个线的MultiLineString多线:
· MULTILINESTRING((10 10, 20 20), (15 15, 30 15))
多线具有两个MultiPolygon的多面值:
· MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0)),((5 5,7 5,7 7,5 7, 5 5)))
A GeometryCollection consisting of two Point values and one LineString:
· GEOMETRYCOLLECTION(POINT(10 10), POINT(30 30), LINESTRING(15 15, 20 20))
GeoJSON
一种JSON格式的Feature信息输出格式,它便于被JavaScript等脚本语言处理,OpenLayers等地理库便是采用GeoJSON格式。此外,TopoJSON等更精简的扩展格式。
在一篇博客https://blog.csdn.net/xcymorningsun/article/details/89848096中看到,对比的分析,比较直观,特放此处以便更直观的理解:
·
然后就可以考虑,把数据解析成标准的WKT文本格式,然后使用GDAL的 ogr.CreateGeometryFromWkt()直接生成对象。
话不多说直接上代码,注释写的比较清楚,大家可以直接拿过去调试即可。
try:
from osgeo import gdal
from osgeo import ogr
except ImportError:
import gdal
import ogr
# from osgeo import ogr
import os
file = open(r"D:\20200309\shujushouji\geopandas4\shptest\polygontest\WKTdata.txt",'r')
# content = file.read()
sourceInLine=file.readlines()
# count = len(open(r"D:\20200309\shujushouji\geopandas4\shp\test004.txt",'rU').readlines())
count1=len(sourceInLine)
# print count
print (count1)
str='POLYGON'
gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "NO")
# 为了使属性表字段支持中文,请添加下面这句
gdal.SetConfigOption("SHAPE_ENCODING", "gb2312")
strVectorFile = r"D:\20200309\shujushouji\geopandas4\shptest\polygontest\ss.shp"
# 注册所有的驱动
ogr.RegisterAll()
# 创建数据,这里以创建ESRI的shp文件为例
strDriverName = "ESRI Shapefile"
oDriver = ogr.GetDriverByName(strDriverName)
# if oDriver == None:
# print("%s 驱动不可用!\n", strDriverName)
# return
# 创建数据源
oDS = oDriver.CreateDataSource(strVectorFile)
# 创建图层,创建一个多边形图层,这里没有指定空间参考,如果需要的话,需要在这里进行指定
papszLCO = []
oLayer = oDS.CreateLayer("ss", None, ogr.wkbPolygon, papszLCO)
if oLayer == None:
print("图层创建失败!\n")
# 下面创建属性表
# 先创建一个叫FieldID的整型属性
# 创建表属性
oFieldName = ogr.FieldDefn("category", ogr.OFTString)
oFieldName.SetWidth(100)
oLayer.CreateField(oFieldName, 1)
# idfield0 = ogr.FieldDefn('id1',ogr.OFTInteger)
oDefn = oLayer.GetLayerDefn()
for i in sourceInLine:
str_list = list(i)
keyword0 = '(('
nPos0 = i.index(keyword0)
keyword1 = '))'
nPos1 = i.index(keyword1)
str_list.insert(nPos0, 'POLYGON')
str_2 = "".join(str_list)
str0 = str_2[0] ##读取txt每行数据的第一个字符,留待转换为fields的添加值
# print(str0)
str5all = str_2[5:] ##读取txt每行数据的POLYGON后面的所有字符串,留待转换为polygon使用
# print(str5all)
file = open(r"D:\20200309\shujushouji\geopandas4\shptest\polygontest\jiexihouWKTdata.txt",'a')
file.write(str5all)
# 创建矩形要素
oFeatureRectangle = ogr.Feature(oDefn)
# oFeatureRectangle.SetField(0, 12)
oFeatureRectangle.SetField(0, str0)
geomRectangle = ogr.CreateGeometryFromWkt(str5all)
oFeatureRectangle.SetGeometry(geomRectangle)
oLayer.CreateFeature(oFeatureRectangle)
oDS.Destroy()
print("数据集创建完成!\n")
最后生成polygon的shp数据,可以直接用arcmap或者Qgis直接打开即可。