Skip to content

Instantly share code, notes, and snippets.

@tbnorth
Last active June 23, 2017 16:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tbnorth/30c37ab45852eeafb378 to your computer and use it in GitHub Desktop.
Save tbnorth/30c37ab45852eeafb378 to your computer and use it in GitHub Desktop.
Convert KML MultiGeometries containing points to their first Point, for GPSBabel input.
"""
kml_multigeom_points.py - Convert KML MultiGeometries
containing points to their first Point, for GPSBabel input.
Also deletes descriptions which can crash GPSBabel.
Usage:
python kml_multigeom_points.py < orig.kml > new.kml
Terry Brown, Terry_N_Brown@yahoo.com, Mon Nov 23 09:51:01 2015
"""
import sys
from xml.etree import ElementTree as ET
KML = "http://www.opengis.net/kml/2.2"
NS = {'kml': KML}
def log(s):
sys.stderr.write("%s\n" % s)
def main():
ET.register_namespace('', KML)
dom = ET.parse(sys.stdin)
parent_map = {c:p for p in dom.iter() for c in p}
for description in dom.findall(".//kml:description", NS):
parent_map[description].remove(description)
multis = dom.findall(".//kml:MultiGeometry", NS)
for multi in multis:
points = multi.findall(".//kml:Point", NS)
name = parent_map[multi].find(".//kml:name", NS).text
if not points:
log("MultiGeometry without Point for '%s'" % name)
continue
if len(points) > 1:
log("MultiGeometry with multiple Points for '%s', "
"using first" % name)
else:
log("Found Point for '%s'" % name)
parent_map[multi].remove(multi)
parent_map[multi].append(points[0])
# this way works in Python 2.7 and 3.4
text = ET.tostring(dom.getroot())
sys.stdout.write(text.decode('utf-8'))
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment