Python实现表格转shapefile方法

1. 需求分析

将带有坐标和参数的表格信息(.xls,.xlsx)转换成地图图层(.shapefile)。
封装好的exe文件下载地址:
https://download.csdn.net/download/ashtyukjhf/19589740

2. 依赖模块

2.1 表格读取

Python用于表格读取的模块很多,由于此项目功能要求简单,只需要读取表格中的文本内容即可,应当选择尽量轻量级的模块,这里选用xlrd进行表格的读取,需要注意版本为“1.2”。
安装时输入:

pip install xlrd==1.2

2.2 图层写入

图层的写入同样尽量选择轻量级的模块,这里选用pyshp,安装时输入:

pip install pyshp

但是引用时要输入

import shapefile

3 功能实现

3.1 图层生成类的封装

由于生成shapefile图层的步骤比较复杂,这里单独写成一个类,对其功能进行封装。

class ShapeFileWriter(object):

    def __init__(self,name:str,project=4326):
        self.name=name#自定义图名
        self.shp=shapefile.Writer(name+'.shp')
        self.proj(project)#自定义投影坐标系

    def __del__(self):
        self.shp.close()
        pass

    def addField(self,key:str,keytype:str,length:str,decimal:str or int='6'):
        if keytype=='F':
            self.shp.field(key,keytype,length,decimal=int(decimal))
        else:
            self.shp.field(key,keytype,length)
        

    def addPoint(self,x:float,y:float,values:list):
        self.shp.point(x, y)
        self.shp.record(*values)


    def proj(self,p=4326):
       
        wkt = 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]'

        
        f = open(self.name+'.prj', 'w') 
        f.write(wkt)#写入投影信息
        f.close()#关闭操作流

完整代码

# -*- coding: utf-8 -*-
import shapefile # 使用pyshp
import xlrd #版本为1.2
import os

class ShapeFileWriter(object):

    def __init__(self,name:str,project=4326):
        self.name=name
        self.shp=shapefile.Writer(name+'.shp')
        self.proj(project)

    def __del__(self):
        self.shp.close()
        pass

    def addField(self,key:str,keytype:str,length:str,decimal:str or int='6'):
        if keytype=='F':
            self.shp.field(key,keytype,length,decimal=int(decimal))
        else:
            self.shp.field(key,keytype,length)
        

    def addPoint(self,x:float,y:float,values:list):
        self.shp.point(x, y)
        self.shp.record(*values)


    def proj(self,p=4326):
       
        wkt = 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]'

        
        f = open(self.name+'.prj', 'w') 
        f.write(wkt)#写入投影信息
        f.close()#关闭操作流


class Transform():


    def __init__(self,name):
        try:
            os.makedirs(name)
        except :pass
        self.name = name
        self.shape=ShapeFileWriter(name+'/'+name)
        self.define()
        self.load()
        

    def define(self):

        with open('字段定义.txt', mode='r', encoding='utf-8') as f:
            a=f.readline().split('=')
            b=f.readline().split('=')
            self.x=int(a[1])
            self.y=int(b[1])
            #print(x,y)
            fileds=f.readlines()
            for filed in fileds:
                filed=filed.replace('\n','').split(',')
                self.shape.addField(*filed)
                #print(filed)

    def load(self):
        try:
            wb=xlrd.open_workbook(self.name+'.xlsx')
        except :
            try:
                wb=xlrd.open_workbook_xls(self.name+'.xls')
            except :pass
        
        #print(wb)
        table = wb.sheet_by_index(0)
        #print (table)
        for i in range(1,table.nrows):
            values= (table.row_values(i))
            try:
                x=float(values[self.x])
                y=float(values[self.y])
                self.shape.addPoint(x, y, values)
            except :pass
       
    pass
    





name=input("文件名:")
name = name.split('.')[0]
Transform(name)
input('转换完成')

使用说明

使用方法

首先准备好xlsx或xls格式的数据表,表头只能有一行。
根据数据表表头编写字段定义文件字段定义.txt并与程序放在同一个文件夹。
运行程序,输入待转换的数据表文件名。

字段定义格式

投影定义

第一行,为投影类型,可选参数如下:

3857:球面墨卡托投影,用于谷歌地图、Bing地图、ESRI地图等;
4326:WGS-84坐标系,用于GPS坐标;
4610:西安80系;
4214:北京54系;
4490:中国大地坐标系2000。
如参数不在以上之列,则自动设置投影系为WGS-84。

坐标字段

第二、三行,为经纬度字段的位置,位置对应表格A列为0,B列为1……,以此类推。

字段属性

第四行及以后,根据数据表的表头,按顺序定义每一列的字段属性,每一行对应表格中的一列。

每一行第一词为字段名,尽量简短;
第二词为字段类型,'C’为字符型,'N’为整数型,'F’为浮点型,‘D’为日期;
第三词为字段长度,建议不要小于10;
若字段类型为’F’,可添加第四词,表示精确到小数点后的位数,留空则默认为6位。

示例

PROJECT=4326
X=2
Y=3
ID,N,20
NAME,C,20
LNG,F,20
LAT,F,20
VALUE1,F,30
VALUE2,F,30

注意事项

  1. 本程序只能读取数据表的第一个sheet,数据表存在多个sheet时可能读取失败;
  2. 字段定义文件的编码应为“UTF-8”,如果出现编码错误,用记事本打开,然后选择另存为,更改编码为“UTF-8”并替换原文件;
  3. 数据表文件名中如有空格,斜杆和多余的点号,会影响文件的读取和保存。
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高堂明镜悲白发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值