本文共 5489 字,大约阅读时间需要 18 分钟。
在现代GIS(地理信息系统)应用中,数据格式的选择往往是技术方案的关键环节。ArcGIS中的Shp格式虽然在处理矢量数据时具有优势,但在进行基于网页的空间数据可视化时,GeoJSON格式的应用却更加普遍。JSON(JavaScript Object Notation)作为一种轻量级、易于解析的数据格式,不仅在Web应用中表现优异,而且通过其结构化特性,为GIS数据的标准化存储和传输提供了新的可能性。而GeoJSON则是对这一趋势的进一步延伸,是一种在JSON格式基础上专门针对GIS矢量数据的规范化表达方式。本文将从GeoJSON的语法规则出发,结合Python编程实践,详细介绍如何将Shp格式转换为GeoJSON格式。
GeoJSON本质上仍然是JSON格式,但其结构具有特定的 GIS 应用需求。一个完整的 GeoJSON 文件结构如下:
{ "type": "FeatureCollection", "features": []} 从整体结构来看,GeoJSON 文件的最外层是一个字典,type字段指定了数据类型为FeatureCollection,而features字段则是一个空列表,用于存储所有矢量要素。每个要素都是一个字典,包含以下几个关键字段:
type:指定要素的类型,支持 Feature、MultiPoint、LineString、MultiLineString、Polygon 和 MultiPolygon 等。properties:存储矢量要素的属性信息,由键值对形式表示。geometry:描述矢量要素的几何信息,具体格式取决于要素类型。根据 GeoJSON 的规范,矢量要素的几何信息可以分为以下几种类型:
点要素的几何信息格式如下:
{ "type": "Feature", "properties": { "value1": "属性值1", "value2": "属性值2" }, "geometry": { "type": "Point", "coordinates": [经度, 纬度] }} coordinates:是一个包含两个元素的列表,分别表示经度和纬度。geometry.type:指定要素类型为 Point。多点要素的几何信息格式如下:
{ "type": "Feature", "properties": { "value1": "属性值1", "value2": "属性值2" }, "geometry": { "type": "MultiPoint", "coordinates": [ [经度1, 纬度1], [经度2, 纬度2] ] }} coordinates:是一个二维列表,表示多个点的经纬度信息。geometry.type:指定要素类型为 MultiPoint。线要素的几何信息格式如下:
{ "type": "Feature", "properties": { "value1": "属性值1", "value2": "属性值2" }, "geometry": { "type": "LineString", "coordinates": [ [经度1, 纬度1], [经度2, 纬度2], [经度3, 纬度3], [经度4, 纬度4] ] }} coordinates:是一个三维列表,表示线要素的折点经纬度信息。geometry.type:指定要素类型为 LineString。多线要素的几何信息格式如下:
{ "type": "Feature", "properties": { "value1": "属性值1", "value2": "属性值2" }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [经度1, 纬度1], [经度2, 纬度2], [经度3, 纬度3], [经度4, 纬度4] ], [ [经度5, 纬度5], [经度6, 纬度6] ] ]} coordinates:是一个四维列表,表示多条线的经纬度信息。geometry.type:指定要素类型为 MultiLineString。多边形要素的几何信息格式如下:
{ "type": "Feature", "properties": { "value1": "属性值1", "value2": "属性值2" }, "geometry": { "type": "Polygon", "coordinates": [ [ [经度1, 纬度1], [经度2, 纬度2], [经度3, 纬度3], [经度4, 纬度4], [经度1, 纬度1] ] ] }} coordinates:是一个四维列表,表示多边形的顶点经纬度信息。geometry.type:指定要素类型为 Polygon。coordinates 的最后一个点需要与第一个点重合,以形成闭合多边形。多多边形要素的几何信息格式如下:
{ "type": "Feature", "properties": {}, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [经度1, 纬度1], [经度2, 纬度2], [经度3, 纬度3], [经度4, 纬度4], [经度1, 纬度1] ], [ [经度5, 纬度5], [经度6, 纬度6], [经度7, 纬度7], [经度8, 纬度8], [经度5, 纬度5] ] ]} coordinates:是一个五维列表,表示多个多边形的顶点经纬度信息。geometry.type:指定要素类型为 MultiPolygon。基于以上 GeoJSON 格式,我们可以编写一个 Python 函数来实现 Shp 格式到 GeoJSON 格式的转换。以下是转换函数的实现代码:
import shapefileimport jsonimport codecsdef Shp2JSON(filename, shp_encoding='utf-8', json_encoding='utf-8'): '''将shp文件转换为GeoJSON文件''' reader = shapefile.Reader(filename, encoding=shp_encoding) fields = reader.fields[1:] # 读取所有字段 field_names = [field[0] for field in fields] # 获取字段名称列表 buffer = [] for sr in reader.shapeRecords(): record = sr.record # 如果是字节类型则使用gb2312编码转换为字符串 record = [r.decode('gb2312', 'ignore') if isinstance(r, bytes) else r for r in record] atr = dict(zip(field_names, record)) geom = sr.shape.__geo_interface__ buffer.append({ 'type': 'Feature', 'properties': atr, 'geometry': geom }) # 写出GeoJSON文件 geojson = codecs.open(filename + '-geo.json', 'w', encoding=json_encoding) geojson.write(json.dumps({ 'type': 'FeatureCollection', 'features': buffer }) + '\n') geojson.close() print('转换成功!') 输入参数:
filename:Shp 文件名称(不包含文件扩展名)。shp_encoding:Shp 文件的编码格式,默认为 'utf-8'。json_encoding:GeoJSON 文件的编码格式,默认为 'utf-8'。运行结果:
filename.geo.json。示例使用:
import osimport shapefileimport jsonimport codecsdef Shp2JSON(filename, shp_encoding='utf-8', json_encoding='utf-8'): '''将shp文件转换为GeoJSON文件''' reader = shapefile.Reader(filename, encoding=shp_encoding) fields = reader.fields[1:] field_names = [field[0] for field in fields] buffer = [] for sr in reader.shapeRecords(): record = sr.record # 如果是字节类型则使用gb2312编码转换为字符串 record = [r.decode('gb2312', 'ignore') if isinstance(r, bytes) else r for r in record] atr = dict(zip(field_names, record)) geom = sr.shape.__geo_interface__ buffer.append({ 'type': 'Feature', 'properties': atr, 'geometry': geom }) # 写出GeoJSON文件 geojson = codecs.open(filename + '-geo.json', 'w', encoding=json_encoding) geojson.write(json.dumps({ 'type': 'FeatureCollection', 'features': buffer }) + '\n') geojson.close() print('转换成功!')if __name__ == '__main__': os.chdir(r'C:\Users\hp\Desktop\飞线图素材') Shp2JSON(filename='bou2_4p.shp', shp_encoding='gbk', json_encoding='utf-8') 运行上述代码后,会在当前目录下生成 bou2_4p.shp-geo.json 文件。为了验证转换结果是否正确,可以使用在线 GeoJSON 解析工具(如 geojson.io)或 GIS 软件(如 QGIS)来查看转换后的数据是否与原始 Shp 文件一致。
此外,转换后的 GeoJSON 文件可直接导入到 WebGIS 平台(如 Kepler.gl)中进行可视化,实现空间数据的在线展示。
通过以上方法,我们可以将 ArcGIS 中的 Shp 格式数据转换为 GeoJSON 格式,充分发挥两种格式的优势。在实际应用中,可以根据具体需求选择适合的 GIS 数据格式,从而实现高效的空间数据处理与可视化。
转载地址:http://lvcuz.baihongyu.com/