|
import xml.etree.ElementTree as etree |
|
import re |
|
import argparse |
|
|
|
def inplace_change(filename, old_string, new_string, verbose): |
|
with open(filename) as f: |
|
s = f.read() |
|
if (old_string not in s and verbose): |
|
print '"{old_string}" not found in {filename}.'.format(**locals()) |
|
return |
|
|
|
with open(filename, 'w') as f: |
|
if (verbose): |
|
print 'Changing "{old_string}" to "{new_string}" in {filename}'.format(**locals()) |
|
s = s.replace(old_string, new_string) |
|
f.write(s) |
|
|
|
|
|
def filter(max_hdop, filename, verbose): |
|
ns = {"kml": "http://www.opengis.net/kml/2.2"} |
|
|
|
outfile = filename.split(".")[0] + ".out." + filename.split(".")[1] |
|
tree = etree.parse(filename) |
|
root = tree.getroot() |
|
|
|
track1 = root.find("kml:Document/kml:Folder[@id='Tracks']/kml:Folder[@id='track 1']", ns) |
|
linestring = track1.find("kml:Placemark/kml:MultiGeometry/kml:LineString/kml:coordinates", ns) |
|
linestringtxt = linestring.text |
|
points = track1.find("kml:Folder[@id='track 1 points']", ns) |
|
placemarks = points.findall("kml:Placemark", ns) |
|
placemarks_count = len(placemarks) |
|
removal_counter = 0 |
|
|
|
if (verbose): |
|
print "Processing {} points".format(placemarks_count) |
|
|
|
for placemark in placemarks: |
|
description = placemark.find("kml:description", ns).text |
|
hdop = float(re.search("<i>HDOP:</i> ([\d.]+)", description).group(1)) |
|
if hdop >= max_hdop: |
|
coordinates = placemark.find("kml:Point/kml:coordinates", ns).text |
|
coordlen = len(re.findall(coordinates, linestringtxt)) |
|
if coordlen > 1: |
|
print "Could not process coordinates {} because they appear {} times. Please remove this point manually.".format(coordinates, coordlen) |
|
else: |
|
if (verbose): |
|
print "Removing {} (HDOP: {} > {})".format(coordinates, hdop, str(max_hdop)) |
|
linestringtxt = linestringtxt.replace(coordinates + " ", "") |
|
points.remove(placemark) |
|
removal_counter += 1 |
|
|
|
|
|
linestring.text = linestringtxt |
|
|
|
percent = 100 * float(removal_counter)/placemarks_count |
|
|
|
print "Removed {} points of {} ({:<0.2f}%)".format(removal_counter, placemarks_count, percent) |
|
|
|
print "Output file: {}".format(outfile) |
|
|
|
tree.write(outfile, encoding="utf-8", xml_declaration=True) |
|
|
|
inplace_change(outfile, "ns0:", "", verbose) |
|
|
|
def get_options(): |
|
parser = argparse.ArgumentParser(prog='HdopFilter by ClemRz', description='Filter a KML file based on HDOP') |
|
parser.add_argument('filename', help='The path to the KML file to filter') |
|
parser.add_argument('-d', '--hdop', dest='hdop', default='2', help='The threshold HDOP value') |
|
parser.add_argument('-v', '--verbose', dest='verbose', help='Enables verbose output', action='store_true') |
|
return parser.parse_args() |
|
|
|
def main(): |
|
options = get_options() |
|
filter(float(options.hdop), options.filename, options.verbose) |
|
|
|
if __name__ == '__main__': |
|
main() |