shp文件与GeoJSON文件互转

shp文件

shp文件全称Shapefile文件,是美国环境系统研究所(ESRI)研制的GIS文件系统格式文件,是工业标准的矢量数据文件。

Shapefile将空间特征表中的非拓扑几何对象和属性信息存储在数据集中,特征表中的几何对象存为以坐标点集表示的图形文件—SHP文件,Shapefile文件并不含拓扑(Topological)数据结构。一个Shape文件包括三个文件:一个主文件(.shp),一个索引文件(.shx),和一个dBASE(*.dbf)表。

在大多数GISer的日常工作中,得益于ArcGIS Desktop的广泛使用,接触最多的矢量数据恐怕就是shp文件了。

GeoJSON文件

GeoJSON归根结底也是一种JSON,只不过它更适合记录和描述各式各样的地理数据结构。GeoJSON支持以下的实体类型:Point, LineString, Polygon, MultiPoint, MultiLineString, and MultiPolygon。此外,GeoJSON在 FeatureCollection 也包含了详细的属性信息。

需求背景

在我们实际的工作中,可能会涉及到GeoJSON和shp文件互转的情况,因为这两种文件格式都是非常流行的地理数据文件格式。

GeoJSON适合描述和传输地理数据,shp文件则适合用于分析和展示;

GeoJSON转shp

以下代码使用到了gdal依赖包,在Windows环境下如何配置gdal开发环境,大家可以看这篇文章GDAL,我暗恋你很久了!

在开始操作前,我们需要使用两个网站,分别是:

该网站是又高德开放平台提供,是高德数据可视化项目旗下的非盈利性的工具网站,该网站可以非常便利的下载我国省市县三级的GeoJSON数据。既可以下载为文件格式,也可以复制为文本格式。

相比于DataV,geojson.io网站的优势在于可以支持用户自主绘制图形,以获取目标区域的geojson。支持点、线、面、矩形来获取目标区域的geojson,并支持一定的交互操作。

你可以选择任何一个网站来获取一个geojson来进行我们的代码实战操作。这里我选择陕西省和内蒙古自治区的省界GeoJSON数据。

<pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" spellcheck="false" lang="java" cid="n34" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); --select-text-bg-color: #36284e; --select-text-font-color: #fff; font-size: 0.9rem; line-height: 1.71429em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(218, 218, 218); position: relative !important; margin-bottom: 3em; margin-left: 2em; padding-left: 0px; padding-right: 1ch; width: inherit; color: rgb(31, 9, 9); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"> package com.geovis.bin.utils.gis;

import org.gdal.gdal.gdal;
import org.gdal.ogr.DataSource;
import org.gdal.ogr.ogr;

import java.io.File;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

/**

  • @Author Wangb
  • @Date 2021/5/19 19:42.
    /
    public class GeojsonAndShpUtil {
    /
    *
  • Geojson 转 shape
  • @param sourcePath
  • @param destPath
    */
    public static void Geojson2Shape(String sourcePath, String destPath ) {

Calendar instance = Calendar.getInstance(TimeZone.getTimeZone("GMT+08:00"));
instance.setTime(new Date());
String name = new File(sourcePath).getName();
name = name.substring(0, name.lastIndexOf(".")) + ".shp";

destPath += File.separator + instance.get(Calendar.YEAR) + (instance.get(Calendar.MONTH) + 1) + instance.get(Calendar.DATE) + instance.get(Calendar.HOUR) + instance.get(Calendar.MINUTE) + instance.get(Calendar.SECOND) + File.separator + name;
File file1 = new File(destPath);
if (!file1.exists()) {
new File(file1.getParent()).mkdir();
}

// 注册所有的驱动
ogr.RegisterAll();
// 为了支持中文路径,请添加下面这句代码
gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
// 为了使属性表字段支持中文,请添加下面这句
gdal.SetConfigOption("SHAPE_ENCODING", "");
String strVectorFile = sourcePath;
//打开数据
DataSource ds = ogr.Open(strVectorFile, 0);
if (ds == null) {
System.out.println("打开文件失败!");
return;
}
System.out.println("打开文件成功!");
// GeoJSON shp转json的驱动
// 面的记录 ESRI Shapefile
// 线的记录 ESRI Shapefile
// 点的记录 ESRI Shapefile
String strDriverName = "ESRI Shapefile";
org.gdal.ogr.Driver dv = ogr.GetDriverByName(strDriverName);
if (dv == null) {
System.out.println("打开驱动失败!");
return;
}
System.out.println("打开驱动成功!");
dv.CopyDataSource(ds, destPath);
System.out.println("转换成功!");
ds.delete();
dv.delete();

}

public static void main(String[] args) {
Geojson2Shape("D:\data\陕西省.json", "D:\data");
Geojson2Shape("D:\data\内蒙古.json", "D:\data");
}

}
</pre>

使用上面的代码进行转换之后,就会在我们指定的D盘data文件夹下自动生成包含年月日时分秒的文件夹,该文件夹里就存放了我们转换后的shp文件。

image.png

现在我们把生成的shp文件拖入ArcGIS内看一看

image.png

我们看到陕西省和内蒙古自治区的边界贴合的很自然,右击选择Data Frame Properties,我们可以在Coordinate System里面看到当前shp文件的坐标系统是WGS84坐标系。

image.png

shp转GeoJSON

接下来我们把shp文件转为geoJSON试一下

<pre class="md-fences md-end-block md-fences-with-lineno ty-contain-cm modeLoaded" spellcheck="false" lang="java" cid="n48" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); --select-text-bg-color: #36284e; --select-text-font-color: #fff; font-size: 0.9rem; line-height: 1.71429em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(218, 218, 218); position: relative !important; margin-bottom: 3em; margin-left: 2em; padding-left: 0px; padding-right: 1ch; width: inherit; color: rgb(31, 9, 9); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"> package com.geovis.bin.utils.gis;

import org.gdal.gdal.gdal;
import org.gdal.ogr.DataSource;
import org.gdal.ogr.ogr;

import java.io.File;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

/**

  • @Author Wangb
  • @Date 2021/5/19 19:42.
    /
    public class GeojsonAndShpUtil {
    /
    *
  • shape 转 geojson
  • @param sourcePath
  • @param destPath
    */
    public static void Shape2Geojson(String sourcePath, String destPath ) {

Calendar instance = Calendar.getInstance(TimeZone.getTimeZone("GMT+08:00"));
instance.setTime(new Date());
String name = new File(sourcePath).getName();
name = name.substring(0, name.lastIndexOf(".")) + ".json";

destPath += File.separator + instance.get(Calendar.YEAR) + (instance.get(Calendar.MONTH) + 1) + instance.get(Calendar.DATE) + instance.get(Calendar.HOUR) + instance.get(Calendar.MINUTE) + instance.get(Calendar.SECOND) + File.separator + name;
File file1 = new File(destPath);
if (!file1.exists()) {
new File(file1.getParent()).mkdir();
}

// 注册所有的驱动
ogr.RegisterAll();
// 为了支持中文路径,请添加下面这句代码
gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
// 为了使属性表字段支持中文,请添加下面这句
gdal.SetConfigOption("SHAPE_ENCODING", "");
String strVectorFile = sourcePath;
//打开数据
DataSource ds = ogr.Open(strVectorFile, 0);
if (ds == null) {
System.out.println("打开文件失败!");
return;
}
System.out.println("打开文件成功!");
// GeoJSON shp转json的驱动
org.gdal.ogr.Driver dv = ogr.GetDriverByName("GeoJSON");
if (dv == null) {
System.out.println("打开驱动失败!");
return;
}
System.out.println("打开驱动成功!");
dv.CopyDataSource(ds, destPath);
System.out.println("转换成功!");
ds.delete();
dv.delete();
}

public static void main(String[] args) {
Shape2Geojson("D:\data\202111143545\内蒙古.shp","D:\data\test");
}

}
</pre>

转换结果如下:

image.png

现在我们再Vscode里面对照一下,我们最初下载的内蒙古.geojson和反向生成的是否一样。

image.png

通过仔细对比这个两个文件,我们发现我们生成的内蒙古.geojson文件和之前下载的是完全一样的,这种双向验证的方式在有些时候会非常有用。

好啦!今天的shp文件和GeoJSON文件的互转就是以上的内容,希望可以帮助到你~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,591评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,448评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,823评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,204评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,228评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,190评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,078评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,923评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,334评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,550评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,727评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,428评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,022评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,672评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,826评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,734评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,619评论 2 354

推荐阅读更多精彩内容