DataFrame与shp文件相互转换

因为习惯了使用pandas的DataFrame数据结构,同时pandas作为一个方便计算和表操作的数据结构具有十分显著的优势,甚至很多时候dataFrame可以作为excel在使用,而在用python操作gis的shp文件时很不顺畅,不太符合使用习惯,故写了一个DataFrame与arcgis地理文件相互转换的函数,这个处理起来可以节约大量的思考时间。

Shp转DataFrame:

1import arcpy 2import pandas as pd 3 4def Shp2dataframe(path): 5    '''将arcpy表单变为pandas表单输出''' 6    fields=arcpy.ListFields(path) 7    table=[] 8    fieldname=[field.name for field in fields] 9    #游标集合,用for 循环一次后没办法循环第二次!一个游标实例只能循环一次 10    data=arcpy.SearchCursor(path) 11    for row in data: 12        #Shape字段中的要数是一个几何类 13        r=[] 14        for field in fields: 15            r.append(row.getValue(field.name)) 16        table.append(r) 17    return pd.DataFrame(table,columns=fieldname) 18

DataFrame转Shp:

DataFrame转Shp采用了模板形式,通过模板建立字段文件,坐标系等可以更加快速构建字段。

1#将由ReadTable读取的pandas表转换为shp格式,template为模板 2def Dataframe2ShpTemplate(df,outpath,geoType,template): 3    ''' 4    Fuction: 5    make the table of pandas's DataFrame convert to the shp of esri 6    Input: 7    df -- pandas DataFrame from the shp converted 8    outpath -- the shp output path 9    geometryType -- the type of geomentey, eg:'POINT','POLYLINE','POLYGON','MULTIPOINT' 10    temple -- the temple, at most time it is used the DataFrame's shp 11    ''' 12    out_path = outpath.replace(outpath.split('/')[-1],'') 13    out_name = outpath.split('/')[-1] 14    geometry_type = geoType 15    #template为模板,可以将里面属性全部赋予新建的要素,包括字段、坐标系 16    feature_class = arcpy.CreateFeatureclass_management( 17        out_path, out_name, geometry_type, template) 18    #'*'表示插入所有字段,但如果不用模板容易产生位置不对等 19    #cursor = arcpy.da.InsertCursor(outpath,'*') 20    for row in df.index: 21        #Shape需要改为'SHAPE@'才可以写入 22        df['SHAPE@'] = df['Shape'] 23        cursor = arcpy.da.InsertCursor(outpath,[field for field in df.columns]) 24        cursor.insertRow([df[field][row] for field in df.columns]) 25    print 'Pandas to shp finish!' 26    del cursor

实例应用:

写一个根据gps公交点Txt构建shp数据代码,代码如下:

1def readDataFile(filetype,filename,savefile): 2    #用'gbk'编码读取,读取成统一编码的unicode 3    with codecs.open(filename,encoding='gbk') as datafile: 4         5        #以列表形式读取所有文件 6        pointData = datafile.readlines() 7        #第一行删除并返回为title 8        outputFileName = 'bus'+re.findall('[0-9]*[0-9]',filename)[0]+filetype 9        #检查是否导出文件重复 10        saveEnv = arcpy.Describe(savefile) 11        for child in saveEnv.children: 12            if child.name == outputFileName: 13                outputFileName = outputFileName + '_1' 14        print 'output path is %s'%(savefile+outputFileName) 15        #设置shp文件模板 16        template = u'./dealing/temple.gdb/%s'%filetype 17        linename = filename.strip('./dealing\\').decode('gbk').encode('utf-8') 18        if filetype == 'point': 19            df = pd.DataFrame(columns=Shp2dataframe(template).columns) 20            for num in xrange(len(pointData)): 21                row = pointData[num].strip('\r\n').split(' ') 22                 23                df.set_value(num,'name',row[0]) 24                df.set_value(num,'x',row[1]) 25                df.set_value(num,'y',row[2]) 26                df.set_value(num,'line',linename.strip('point.txt')) 27                 28                point = arcpy.PointGeometry(arcpy.Point(row[1],row[2])) 29                df.set_value(num,'Shape',point) 30                 31        elif filetype == 'line': 32            df = pd.DataFrame(columns=Shp2dataframe(template).columns) 33            pointList = [] 34            #构建线集合 35            for eachPoint in pointData: 36                coord = eachPoint.strip('\r\n').split(' ') 37                pointList.append(arcpy.Point(float(coord[0]),float(coord[1]))) 38            df.set_value(0,'name',linename.strip('line.txt')) 39            #组建线要素arcpy.Polyline(arcpy.Array(pointList)) 40            df.set_value(0,'Shape',arcpy.Polyline(arcpy.Array(pointList))) 41     42    Dataframe2ShpTemplate(df,savefile+outputFileName,'',template) 43    return df

-------sugar---------------------sugar--------------------sugar-------------------sugar----------------sugar----------

1#搜索目录下的所有带point.txt和line.txt的文件 2 3pointfiles = glob.glob('./dealing/*point.txt') 4polylinefiles = glob.glob('./dealing/*line.txt') 5 6for pf in pointfiles: 7    print pf 8    readDataFile('point',pf,u'dealing/广州市道路网.gdb/') 9 10for pl in polylinefiles: 11    print pl 12    df=readDataFile('line',pl,u'dealing/广州市道路网.gdb/') 13 14 15lineshp = arcpy.Describe(u'dealing/广州市道路网.gdb/') 16linelist = [] 17for child in lineshp.children: 18    if 'line' in child.name: 19        linelist.append(u'dealing/广州市道路网.gdb/'+child.name) 20arcpy.Merge_management(linelist,u'dealing/广州市道路网.gdb/0allLine')

Kanonpy

http://my.oschina.net/Kanonpy/admin/edit-blog?blog=425633

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

java将前端的json数组字符串转换为列表

记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang

Python数据分析实战(2)使用Pandas进行数据分析

一、Pandas的使用1.Pandas介绍Pandas的主要应用包括:数据读取数据集成透视表数据聚合与分组运算分段统计数据可视化Pandas的使用很灵活,最重要的两个数据类型是DataFrame和Series。对DataFrame最直观的理解是把它当成一个Excel表格文件,如下:索引是从0开始的,也