Python解析和生成用於Google Earth的KML格式檔案,解決Python3匯入pyKML錯誤
0 格式介紹
Google Earth生成的檔案格式是KML/KMZ,這裡介紹如何解析和生成KML格式檔案,KMZ格式可以在Google Earth中另存為KML格式。
更詳細的瞭解KML可以檢視Google 官方教程。KML用於Google Earth和Google Map中顯示地理資料,使用包含巢狀的元素和屬性的結構(基於標記),符合 XML 標準。KML基本格式:
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Placemark>
<name>Simple placemark</name>
<description>Not a real place.</description>
<LineString>
<coordinates>
120.315681310226,39.95885231106518,0 120.3157179045997,39.9586874087592,0
</coordinates >
<coordinates>
120.3158141778864,39.95791322572761,0 120.3158808732796,39.95791590956513,0
</coordinates>
</LineString>
</Placemark>
</kml>
上述檔案的解釋:
- XML 標頭。
- KML 名稱空間宣告。
- 地標物件元素。
- 用作地標標籤的名稱。
- 地標的描述。
- 該地標有兩條路徑,以及描述路徑的經度、緯度和高度(可以省略)。
1 Python庫pyKML
pyKML用於生成、解析和驗證KML檔案。
1.1 安裝
Linux下使用conda:
$ conda install -c conda-forge pykml
使用pip:
$ pip install pykml
1.2 問題
1.2.1 parser模組
如果是Python 3.x,pyKML在匯入parser的時候會出現以下問題,沒有模組urllib2 。
In [1]: from pykml import parser
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
<ipython-input-1-386e0923aa06> in <module>()
----> 1 from pykml import parser
~/miniconda3/lib/python3.6/site-packages/pykml/parser.py in <module>()
6 import sys
7 import os
----> 8 import urllib2
ModuleNotFoundError: No module named 'urllib2'
原因是Python 2.x的urllib 和urllib2 模組在Python 3.x中被合併在了urlllib中。這裡使用url是為了驗證KML檔案的有效性。
開啟檔案~/miniconda3/lib/python3.6/site-packages/pykml/parser.py
替換第8行為from urllib.request import urlopen
。再次嘗試匯入,提示缺少庫檔案libiconv.so.2
。
In [2]: from pykml import parser
---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
<ipython-input-1-386e0923aa06> in <module>()
----> 1 from pykml import parser
~/miniconda3/lib/python3.6/site-packages/pykml/parser.py in <module>()
7 import os
8 from urllib.request import urlopen
----> 9 from lxml import etree, objectify
ImportError: libiconv.so.2: cannot open shared object file: No such file or directory
安裝庫$ conda install -c conda-forge libiconv
,匯入成功!或者嘗試按照lxml官方教程安裝lxml模組。
1.2.2 factory模組
factory.py模組的print語句改成python3.x風格,kml2pykml()方法最後一行改為:
print(write_python_script_for_kml_document(doc))
1.3 解析檔案
解析KML格式的字串:
In [1]: from pykml import parser
In [2]: kml_str = '<kml xmlns="http://www.opengis.net/kml/2.2">' \ # 定義kml格式的字元
....: '<Document>' \
....: '<Folder>' \
....: '<name>sample folder</name>' \
....: '</Folder>' \
....: '</Document>' \
....: '</kml>'
In [9]: root = parser.fromstring(kml_str)
In [10]: print(root.Document.Folder.name.text)
sample folder
解析格式介紹中的KML檔案,Placemark標籤下有兩條路徑,從檔案中獲取兩條路徑中所有點的座標:
In [11]: with open(KML_FILE, 'r') as f:
In [12]: kml = parser.parse(f).getroot()
In [13]: for each in kml.Placemark: # 遍歷所有的Placemark
In [14]: print(each.LineString.coordinates)
或者使用 findall( ) 查詢所有的Placemark1:
In [15]: placemarks = kml.findall('.//{http://www.opengis.net/kml/2.2}Placemark')
In [16]: for each in placemarks:
In [17]: print(each.LineString.coordinates)
1.4 生成和驗證
生成和驗證KML檔案可參考pyKML官方教程。