shp文件與GeoJSON文件互轉(zhuǎn)

shp文件

shp文件全稱Shapefile文件,是美國環(huán)境系統(tǒng)研究所(ESRI)研制的GIS文件系統(tǒng)格式文件廉丽,是工業(yè)標(biāo)準(zhǔn)的矢量數(shù)據(jù)文件倦微。

Shapefile將空間特征表中的非拓?fù)鋷缀螌ο蠛蛯傩孕畔⒋鎯υ跀?shù)據(jù)集中,特征表中的幾何對象存為以坐標(biāo)點(diǎn)集表示的圖形文件—SHP文件正压,Shapefile文件并不含拓?fù)洌═opological)數(shù)據(jù)結(jié)構(gòu)欣福。一個Shape文件包括三個文件:一個主文件(.shp),一個索引文件(.shx)焦履,和一個dBASE(*.dbf)表拓劝。

在大多數(shù)GISer的日常工作中,得益于ArcGIS Desktop的廣泛使用嘉裤,接觸最多的矢量數(shù)據(jù)恐怕就是shp文件了郑临。

GeoJSON文件

GeoJSON歸根結(jié)底也是一種JSON,只不過它更適合記錄和描述各式各樣的地理數(shù)據(jù)結(jié)構(gòu)屑宠。GeoJSON支持以下的實(shí)體類型:Point, LineString, Polygon, MultiPoint, MultiLineString, and MultiPolygon厢洞。此外,GeoJSON在 FeatureCollection 也包含了詳細(xì)的屬性信息。

需求背景

在我們實(shí)際的工作中躺翻,可能會涉及到GeoJSON和shp文件互轉(zhuǎn)的情況丧叽,因?yàn)檫@兩種文件格式都是非常流行的地理數(shù)據(jù)文件格式。

GeoJSON適合描述和傳輸?shù)乩頂?shù)據(jù)公你,shp文件則適合用于分析和展示蠢正;

GeoJSON轉(zhuǎn)shp

以下代碼使用到了gdal依賴包,在Windows環(huán)境下如何配置gdal開發(fā)環(huán)境省店,大家可以看這篇文章GDAL,我暗戀你很久了!

在開始操作前笨触,我們需要使用兩個網(wǎng)站懦傍,分別是:

該網(wǎng)站是又高德開放平臺提供,是高德數(shù)據(jù)可視化項(xiàng)目旗下的非盈利性的工具網(wǎng)站芦劣,該網(wǎng)站可以非常便利的下載我國省市縣三級的GeoJSON數(shù)據(jù)粗俱。既可以下載為文件格式,也可以復(fù)制為文本格式虚吟。

相比于DataV寸认,geojson.io網(wǎng)站的優(yōu)勢在于可以支持用戶自主繪制圖形,以獲取目標(biāo)區(qū)域的geojson串慰。支持點(diǎn)偏塞、線、面邦鲫、矩形來獲取目標(biāo)區(qū)域的geojson灸叼,并支持一定的交互操作。

你可以選擇任何一個網(wǎng)站來獲取一個geojson來進(jìn)行我們的代碼實(shí)戰(zhàn)操作庆捺。這里我選擇陜西省和內(nèi)蒙古自治區(qū)的省界GeoJSON數(shù)據(jù)古今。

<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 轉(zhuǎn) 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();
}

// 注冊所有的驅(qū)動
ogr.RegisterAll();
// 為了支持中文路徑,請?zhí)砑酉旅孢@句代碼
gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
// 為了使屬性表字段支持中文滔以,請?zhí)砑酉旅孢@句
gdal.SetConfigOption("SHAPE_ENCODING", "");
String strVectorFile = sourcePath;
//打開數(shù)據(jù)
DataSource ds = ogr.Open(strVectorFile, 0);
if (ds == null) {
System.out.println("打開文件失斪叫取!");
return;
}
System.out.println("打開文件成功你画!");
// GeoJSON shp轉(zhuǎn)json的驅(qū)動
// 面的記錄 ESRI Shapefile
// 線的記錄 ESRI Shapefile
// 點(diǎn)的記錄 ESRI Shapefile
String strDriverName = "ESRI Shapefile";
org.gdal.ogr.Driver dv = ogr.GetDriverByName(strDriverName);
if (dv == null) {
System.out.println("打開驅(qū)動失數值!");
return;
}
System.out.println("打開驅(qū)動成功撬即!");
dv.CopyDataSource(ds, destPath);
System.out.println("轉(zhuǎn)換成功立磁!");
ds.delete();
dv.delete();

}

public static void main(String[] args) {
Geojson2Shape("D:\data\陜西省.json", "D:\data");
Geojson2Shape("D:\data\內(nèi)蒙古.json", "D:\data");
}

}
</pre>

使用上面的代碼進(jìn)行轉(zhuǎn)換之后,就會在我們指定的D盤data文件夾下自動生成包含年月日時分秒的文件夾剥槐,該文件夾里就存放了我們轉(zhuǎn)換后的shp文件唱歧。

image.png

現(xiàn)在我們把生成的shp文件拖入ArcGIS內(nèi)看一看

image.png

我們看到陜西省和內(nèi)蒙古自治區(qū)的邊界貼合的很自然,右擊選擇Data Frame Properties,我們可以在Coordinate System里面看到當(dāng)前shp文件的坐標(biāo)系統(tǒng)是WGS84坐標(biāo)系。

image.png

shp轉(zhuǎn)GeoJSON

接下來我們把shp文件轉(zhuǎn)為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 轉(zhuǎn) 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();
}

// 注冊所有的驅(qū)動
ogr.RegisterAll();
// 為了支持中文路徑颅崩,請?zhí)砑酉旅孢@句代碼
gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
// 為了使屬性表字段支持中文几于,請?zhí)砑酉旅孢@句
gdal.SetConfigOption("SHAPE_ENCODING", "");
String strVectorFile = sourcePath;
//打開數(shù)據(jù)
DataSource ds = ogr.Open(strVectorFile, 0);
if (ds == null) {
System.out.println("打開文件失敗沿后!");
return;
}
System.out.println("打開文件成功沿彭!");
// GeoJSON shp轉(zhuǎn)json的驅(qū)動
org.gdal.ogr.Driver dv = ogr.GetDriverByName("GeoJSON");
if (dv == null) {
System.out.println("打開驅(qū)動失敗尖滚!");
return;
}
System.out.println("打開驅(qū)動成功喉刘!");
dv.CopyDataSource(ds, destPath);
System.out.println("轉(zhuǎn)換成功!");
ds.delete();
dv.delete();
}

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

}
</pre>

轉(zhuǎn)換結(jié)果如下:

image.png

現(xiàn)在我們再Vscode里面對照一下漆弄,我們最初下載的內(nèi)蒙古.geojson和反向生成的是否一樣睦裳。

image.png

通過仔細(xì)對比這個兩個文件,我們發(fā)現(xiàn)我們生成的內(nèi)蒙古.geojson文件和之前下載的是完全一樣的撼唾,這種雙向驗(yàn)證的方式在有些時候會非常有用廉邑。

好啦!今天的shp文件和GeoJSON文件的互轉(zhuǎn)就是以上的內(nèi)容倒谷,希望可以幫助到你~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蛛蒙,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子渤愁,更是在濱河造成了極大的恐慌牵祟,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件猴伶,死亡現(xiàn)場離奇詭異课舍,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)他挎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進(jìn)店門筝尾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人办桨,你說我怎么就攤上這事筹淫。” “怎么了呢撞?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵损姜,是天一觀的道長。 經(jīng)常有香客問我殊霞,道長摧阅,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任绷蹲,我火速辦了婚禮棒卷,結(jié)果婚禮上顾孽,老公的妹妹穿的比我還像新娘。我一直安慰自己比规,他們只是感情好若厚,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蜒什,像睡著了一般测秸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上灾常,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天霎冯,我揣著相機(jī)與錄音,去河邊找鬼钞瀑。 笑死肃晚,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的仔戈。 我是一名探鬼主播,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼拧廊,長吁一口氣:“原來是場噩夢啊……” “哼监徘!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起吧碾,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤凰盔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后倦春,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體户敬,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年睁本,在試婚紗的時候發(fā)現(xiàn)自己被綠了尿庐。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡呢堰,死狀恐怖抄瑟,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情枉疼,我是刑警寧澤皮假,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站骂维,受9級特大地震影響惹资,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜航闺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一褪测、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦汰扭、人聲如沸稠肘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽项阴。三九已至,卻和暖如春笆包,著一層夾襖步出監(jiān)牢的瞬間环揽,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工庵佣, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留歉胶,地道東北人。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓巴粪,卻偏偏與公主長得像通今,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子肛根,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內(nèi)容