利用Python實(shí)現(xiàn)Shp格式向GeoJSON的轉(zhuǎn)換方法
一、簡介
Shp格式是GIS中非常重要的數(shù)據(jù)格式,主要在Arcgis中使用,但在進(jìn)行很多基于網(wǎng)頁的空間數(shù)據(jù)可視化時,通常只接受GeoJSON格式的數(shù)據(jù),眾所周知JSON(JavaScript Object Nonation)是利用鍵值對+嵌套來表示數(shù)據(jù)的一種格式,以其輕量、易解析的優(yōu)點(diǎn),被廣泛使用與各種領(lǐng)域,而GeoJSON就是指在一套規(guī)定的語法規(guī)則下用JSON格式存儲矢量數(shù)據(jù),本文就將針對GeoJSON的語法規(guī)則,以及如何利用Python完成Shp格式到GeoJSON格式的轉(zhuǎn)換進(jìn)行介紹。
二、Shp轉(zhuǎn)GeoJSON
2.1 GeoJSON格式說明
GeoJSON本質(zhì)依舊是JSON,其基本格式如下:
{ "type": "FeatureCollection", "features": [] }
一個完整的GeoJSON文件最外層為一個字典,把整個GeoJSON文件看做自頂向下的樹狀結(jié)構(gòu)的話,其根目錄包含鍵值對 "type":"FeaturesCollection" ,以及存放所有要素的鍵值對 "features":[] ,所有矢量要素都存放在這個列表中,每個要素都是一個字典,下面我們來認(rèn)識一下各種矢量要素在GeoJSON中的規(guī)范格式:
點(diǎn)要素(Point):
對于單個點(diǎn)要素,其格式如下:
{"type":"Feature", "properties":{value1,value2}, "geometry":{ "type":"Point", "coordinates":[經(jīng)度,緯度] } }
其中properties對應(yīng)的值為這個要素對應(yīng)的屬性表中按順序存放的值,geometry對應(yīng)的值中type指明了要素類型,coordinates傳入一個包含兩個元素的列表,第一個元素代表經(jīng)度,第二個元素代表緯度。
多點(diǎn)要素(MultiPoint):
多點(diǎn)要素是點(diǎn)要素的特殊情況,其geometry下的type屬性傳入"MultiPoint",其coordinates屬性傳入的是一個二維列表,其最內(nèi)層列表定義了每個點(diǎn)的經(jīng)緯度,如下:
{"type":"Feature", "properties":{value1,value2}, "geometry":{ "type":"MultiPoint", "coordinates":[[經(jīng)度1,緯度1], [經(jīng)度2,緯度2] ] } }
線要素(LineString):
線要素記錄的是一條線上所有折點(diǎn)的經(jīng)緯度信息,只需要按順序連接這些折點(diǎn)就可以還原一條線的形態(tài),在GeoJSON中線要素與多點(diǎn)要素在coordinates屬性上格式相同,區(qū)別在于geometry屬性需要傳入"LineString",如下:
{"type":"Feature", "properties":{value1,value2}, "geometry":{ "type":"LineString", "coordinates":[[經(jīng)度1,緯度1], [經(jīng)度2,緯度2], [經(jīng)度3,緯度3], [經(jīng)度4,,緯度4]] } }
多線要素(MultiLineString):
多線要素是多個線要素的組合,因此其coordinates傳入三維列表,來組合多條線,對應(yīng)的geometry下type屬性為"MultiLineString",如下:
{"type":"Feature", "properties":{value1,value2}, "geometry":{ "type":"MultiLineString", "coordinates": [ [ [經(jīng)度1,緯度1], [經(jīng)度2,緯度2], [經(jīng)度3,緯度3], [經(jīng)度4,緯度4] ], [ [經(jīng)度5,緯度5], [經(jīng)度6,緯度6] ] ] } }
多邊形要素(Polygon):
多邊形要素記錄了構(gòu)成一個多邊形所有邊緣折點(diǎn)的經(jīng)緯度信息,其coordinates屬性傳入"Polygon",其geometry下type屬性格式為三維列表,其第三層列表中嵌套的所有列表記錄的經(jīng)緯度按順序連接即構(gòu)成了一個多邊形,但需要注意的是,多邊形頭尾折點(diǎn)的經(jīng)緯度需要相同,才能構(gòu)成一個閉合的多邊形,如下:
{"type":"Feature", "properties":{value1,value2}, "geometry":{ "type":"Polygon", "coordinates":[ [ [經(jīng)度1,緯度1], [經(jīng)度2,緯度2], [經(jīng)度3,緯度3], [經(jīng)度4,緯度4], [經(jīng)度1,緯度1] ] ] } }
多多邊形要素(MultiPolygon):
多多邊形的格式為四維列表,其geometry下type屬性傳入"MultiPloygon",由于多多邊形要素中存在幾種特殊情況,下面我們在geojson.io中進(jìn)行對應(yīng)GeoJSON數(shù)據(jù)的可視化以便于理解:
互不重疊的兩個多邊形:
下面是互不重疊的兩個多邊形的示例:
對應(yīng)的GeoJSON數(shù)據(jù)如下:
{ "type": "Feature", "properties": {}, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [102.74414062499999,36.217687122250574], [102.7001953125,35.585851593232356], [104.8590087890625,35.496456056584165], [104.96337890625,36.24427318493909], [102.74414062499999,36.217687122250574] ] ], [ [ [102.6397705078125,35.074964853989556], [103.0352783203125,34.23905366851639], [105.00732421875,34.24813554589752], [105.3973388671875,35.77771427205079], [104.556884765625,35.05698043137265], [102.711181640625,35.16931803601131], [102.6397705078125,35.074964853989556] ] ] ] } }
可以看到在多個多邊形不重疊時,直接將兩個多邊形要素對應(yīng)的三維列表存放在最外層列表下即可。
互有重疊的兩個多邊形:
互有重疊的多個多邊形要素格式同多個不重疊的多邊形,效果如下:
對應(yīng)的GeoJSON數(shù)據(jù)如下:
{ "type": "Feature", "properties": {}, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [101.6455078125,27.68352808378776], [114.78515624999999,27.68352808378776], [114.78515624999999, 35.209721645221386], [101.6455078125,35.209721645221386], [101.6455078125,27.68352808378776] ] ], [ [ [104.2822265625,30.107117887092357], [108.896484375,30.107117887092357], [108.896484375,33.76088200086917], [104.2822265625,33.76088200086917], [104.2822265625,30.107117887092357] ] ] ] } }
有孔的多邊形:
有孔的多邊形在類別上也是歸類到MultiPolygon,下面是一個示例:
對應(yīng)的GeoJSON數(shù)據(jù)如下,可以看出其與多個重疊的多邊形的區(qū)別在于多邊形矢量信息嵌套在第二層列表中:
{ "type": "Feature", "properties": {}, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [101.6455078125,27.68352808378776], [114.78515624999999,27.68352808378776], [114.78515624999999,35.209721645221386], [101.6455078125,35.209721645221386], [101.6455078125,27.68352808378776] ], [ [104.2822265625,30.107117887092357], [108.896484375,30.107117887092357], [108.896484375,33.76088200086917], [104.2822265625,33.76088200086917], [104.2822265625,30.107117887092357] ] ] ] } }
2.2 將Shp格式轉(zhuǎn)換為GeoJSON
在2.1中我們較為詳細(xì)的了解到矢量數(shù)據(jù)在GeoJSON數(shù)據(jù)中具體的表現(xiàn)形式,通過下面的自編函數(shù),以Shp文件名稱(去除文件拓展名)、Shp文件編碼、GeoJSON文件編碼為輸入?yún)?shù):
def Shp2JSON(filename,shp_encoding='utf-8',json_encoding='utf-8'): ''' 這個函數(shù)用于將shp文件轉(zhuǎn)換為GeoJSON文件 :param filename: shp文件對應(yīng)的文件名(去除文件拓展名) :return: ''' '''創(chuàng)建shp IO連接''' reader = shapefile.Reader(filename,encoding=shp_encoding) '''提取所有field部分內(nèi)容''' fields = reader.fields[1:] '''提取所有field的名稱''' field_names = [field[0] for field in fields] '''初始化要素列表''' buffer = [] for sr in tqdm(reader.shapeRecords()): '''提取每一個矢量對象對應(yīng)的屬性值''' record = sr.record '''屬性轉(zhuǎn)換為列表''' record = [r.decode('gb2312','ignore') if isinstance(r, bytes) else r for r in record] '''對齊屬性與對應(yīng)數(shù)值的鍵值對''' atr = dict(zip(field_names, record)) '''獲取當(dāng)前矢量對象的類型及矢量信息''' geom = sr.shape.__geo_interface__ '''向要素列表追加新對象''' buffer.append(dict(type="Feature", geometry=geom, properties=atr)) '''寫出GeoJSON文件''' geojson = codecs.open(filename + "-geo.json","w", encoding=json_encoding) geojson.write(json.dumps({"type":"FeatureCollection", "features":buffer}) + '\n') geojson.close() print('轉(zhuǎn)換成功!')
下面我們通過一個示例來展示實(shí)際轉(zhuǎn)換效果,使用到的Shp數(shù)據(jù)為中國省份數(shù)據(jù),在arcgis中效果如下:
import shapefile import json import codecs def Shp2JSON(filename,shp_encoding='utf-8',json_encoding='utf-8'): ''' 這個函數(shù)用于將shp文件轉(zhuǎn)換為GeoJSON文件 :param filename: shp文件對應(yīng)的文件名(去除文件拓展名) :return: ''' '''創(chuàng)建shp IO連接''' reader = shapefile.Reader(filename,encoding=shp_encoding) '''提取所有field部分內(nèi)容''' fields = reader.fields[1:] '''提取所有field的名稱''' field_names = [field[0] for field in fields] '''初始化要素列表''' buffer = [] for sr in tqdm(reader.shapeRecords()): '''提取每一個矢量對象對應(yīng)的屬性值''' record = sr.record '''屬性轉(zhuǎn)換為列表''' record = [r.decode('gb2312','ignore') if isinstance(r, bytes) else r for r in record] '''對齊屬性與對應(yīng)數(shù)值的鍵值對''' atr = dict(zip(field_names, record)) '''獲取當(dāng)前矢量對象的類型及矢量信息''' geom = sr.shape.__geo_interface__ '''向要素列表追加新對象''' buffer.append(dict(type="Feature", geometry=geom, properties=atr)) '''寫出GeoJSON文件''' geojson = codecs.open(filename + "-geo.json","w", encoding=json_encoding) geojson.write(json.dumps({"type":"FeatureCollection", "features":buffer}) + '\n') geojson.close() print('轉(zhuǎn)換成功!') if __name__ == '__main__': import os os.chdir(r'C:\Users\hp\Desktop\飛線圖素材') Shp2JSON(filename='bou2_4p.shp', shp_encoding='gbk', json_encoding='utf-8')
運(yùn)行之后同一目錄下出現(xiàn)對應(yīng)的json文件:
導(dǎo)入到Kepler.gl中進(jìn)行可視化:
from keplergl import KeplerGl import json with open('bou2_4p.shp-geo.json') as b: data = json.load(b) map1 = KeplerGl(height=700,data={'layer1':data});map1
總結(jié)
以上所述是小編給大家介紹的利用Python實(shí)現(xiàn)Shp格式向GeoJSON的轉(zhuǎn)換方法 ,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
如果你覺得本文對你有幫助,歡迎轉(zhuǎn)載,煩請注明出處,謝謝!
- Python字符串str和json格式相互轉(zhuǎn)換
- 把JSON數(shù)據(jù)格式轉(zhuǎn)換為Python的類對象方法詳解(兩種方法)
- python3 json數(shù)據(jù)格式的轉(zhuǎn)換(dumps/loads的使用、dict to str/str to dict、json字符串/字典的相互轉(zhuǎn)換)
- Python中xml和json格式相互轉(zhuǎn)換操作示例
- Python基于pandas實(shí)現(xiàn)json格式轉(zhuǎn)換成dataframe的方法
- 利用python將json數(shù)據(jù)轉(zhuǎn)換為csv格式的方法
- Python如何將LabelMe生成的JSON格式轉(zhuǎn)換成YOLOv8支持的TXT格式
相關(guān)文章
python中時間轉(zhuǎn)換datetime和pd.to_datetime詳析
這篇文章主要給大家介紹了關(guān)于python中時間轉(zhuǎn)換datetime和pd.to_datetime的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用python具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08python opencv實(shí)現(xiàn)旋轉(zhuǎn)矩形框裁減功能
這篇文章主要為大家詳細(xì)介紹了python opencv實(shí)現(xiàn)旋轉(zhuǎn)矩形框裁減功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-07-07spark dataframe 將一列展開,把該列所有值都變成新列的方法
今天小編就為大家分享一篇spark dataframe 將一列展開,把該列所有值都變成新列的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-01-01Python實(shí)現(xiàn)曲線的肘部點(diǎn)檢測詳解
肘部法則是經(jīng)常使用的法則。很多時候,可以憑人工經(jīng)驗(yàn)去找最優(yōu)拐點(diǎn),但有時需要自動尋找拐點(diǎn)。本文為大家介紹了Python實(shí)現(xiàn)曲線的肘部點(diǎn)檢測的方法,希望對大家有所幫助2023-02-02python numpy數(shù)組復(fù)制使用實(shí)例解析
這篇文章主要介紹了python numpy數(shù)組復(fù)制使用實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-01-01