大家好,欢迎来到IT知识分享网。
前言
第三方库准备
shp文件是什么?笔者就不多做解释。后面将使用python的一些第三方库
1、sqlalchemy
2、pyshp
3、geoalchemy2
4、geopandas
这四个是主要的库,具体怎么使用可以参考相关教程,当然还有其他库,后面在介绍。
数据库准备
shp文件一般包含空间数据,所以选用的数据库是PostgreSQL。具体操作不多说。
shp文件准备
打开阿里云数据可视化平台,DataV.GeoAtlas地理小工具系列 (aliyun.com)
比如选择成都市,如下图。
可以其中类型中选择下载,直接下载json文件,也可以通过对json API 发送请求,得到json数据。
代码如下。
import requests import json r=requests.get(url='https://geo.datav.aliyun.com/areas_v3/bound/geojson?code=_full') str_data=json.dumps(r.json(),ensure_ascii=False) with open('成都.json','w',encoding='utf-8') as f: f.write(str_data)
修改code参数,就可以得到其他地区的数据。
后面可以通过网站把json文件转shp文件,如下这个网站,JSON to SHP Converter Online – MyGeodata Cloud,当然也可以通过python把json转shp文件,很简单,代码如下。
import geopandas as gpd data = gpd.read_file('成都市.json') data.to_file('成都', driver='ESRI Shapefile', encoding='utf-8')
运行是成功的,如果有如下警告,可以忽略,不存在。
则会在当前目录下生成shp及相关的文件,如下图
通过arcmap打开shp文件,在通过arcmap修改一下属性,显示的结果如图。
打开属性表,可以看到数据,如下图所示。
正文
读取shp文件,有多种方法,可以通过peopandas,或者pyshp(shapefile)读取,因为要创建表,笔者使用pyshp来读取shp文件。
得到列
代码如下。
import shapefile file=shapefile.Reader('成都/成都.shp') fileds=file.fields for i in fileds: print(i) shapes=file.shape() print(shapes.shapeTypeName)
打印的数据如下。
('DeletionFlag', 'C', 1, 0) ['adcode', 'N', 18, 0] ['name', 'C', 80, 0] ['childrenNu', 'N', 18, 0] ['level', 'C', 80, 0] ['parent', 'C', 80, 0] ['subFeature', 'N', 18, 0] POLYGON
分析数据的意思
DeletionFlag没有用,可以删除,POLYGON,对应的空间数据是面,还有其他类型,如下图所示
具体含义可自行搜索。以[‘adcode’, ‘N’, 18, 0]为例
还有其他字段类型,如下所示。
| 字段索引 | 字段类型 |
|---|---|
| C | 字符,文字 |
| N | 数字,带或不带小数 |
| F | 浮动(与“N”相同) |
| L | 逻辑,表示布尔值True / False值 |
| D | 日期 |
| M | 备忘录,在GIS中没有意义,而是xbase规范的一部分 |
所以,可以总结出表的属性分别有
id(自己建立),geometry,adcode,name,childrenNu,level,parent,subFeature
和arcmap中看到的一致。
创建表
创建表可以自己使用sql语句,笔者直接使用已有的轮子,sqlalchemy,先对怎么创建表举个例子
示例——创建学生表
代码如下。
from sqlalchemy import create_engine,Integer,String,Column from sqlalchemy.orm import declarative_base # 构造基础类 Base = declarative_base() # 创建交互引擎 engine = create_engine('mysql+pymysql://username:password@localhost:3306/database') # 表的定义 class Student(Base): __tablename__ = 'student' id = Column(Integer(), primary_key=True, autoincrement=True, nullable=False, comment='学生id') name = Column(String(16), nullable=False, comment='学生姓名') # 执行创建 Base.metadata.create_all(engine)
需要安装pymysql库,如果是PostgreSQL,需要安装psycopg2库。
创建shp文件中的表
代码如下。
from geoalchemy2 import Geometry # Geometry 空间数据类型 from sqlalchemy.schema import CreateTable from sqlalchemy.orm import declarative_base from sqlalchemy import Table, Column, Integer, VARCHAR, create_engine, BigInteger, Numeric, DATE, Boolean from dataclasses import dataclass, fields import shapefile Base = declarative_base() @dataclass class Shp2Postgres: shp_path: str table_name: str = 'shp' pg_db: str = 'arcgis' engine: create_engine = create_engine(f'postgresql+psycopg2://username:password@localhost/{pg_db}') file: shapefile.Reader = None words: list = None shape_name: str = None """ :param shp_path: shp文件路径 :param table_name: 表名 :param pg_db: 数据库名 :param engine: 数据库引擎 :param file: shp文件 :param words: shp文件字段 :param shape_name: shp文件类型 :param ShpTable: shp文件对应的表 """ def __post_init__(self): self.file = shapefile.Reader(self.shp_path) self.words = self.file.fields[1:] self.shape_name = self.file.shapeTypeName class ShpTable(Base): __tablename__ = self.table_name id = Column(Integer(), primary_key=True, autoincrement=True, nullable=False, comment='id') geometry = Column(Geometry(geometry_type=self.shape_name, srid=4326), comment='空间信息') self.ShpTable = ShpTable self.add_column() def add_column(self): """ 添加字段 :return: """ for field in self.words: name = field[0] _type = field[1] length = field[2] decimal = field[3] match _type: case 'N': _type = BigInteger() case 'C': _type = VARCHAR(length) case 'F': _type = Numeric(length, decimal) case 'L': _type = Boolean() case 'D': _type = DATE() case 'M': _type = VARCHAR(255) case _: _type = VARCHAR(255) setattr(self.ShpTable, name, Column(_type, comment=name, name=name, quote=False)) def execute(self): """ 执行创建 :return: """ # 执行创建 Base.metadata.create_all(self.engine) # 打印创建表的sql语句 table = CreateTable(self.ShpTable.__table__).compile(self.engine) print(table)
运行以下
数据库中表如下
创建成功。
最后
下一篇接着写,怎么插入数数据。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/117547.html







