diff --git a/gpxinfo b/gpxinfo index 1fed4f9a..7a2db748 100755 --- a/gpxinfo +++ b/gpxinfo @@ -13,6 +13,7 @@ import gpxpy as mod_gpxpy gpx_files = mod_sys.argv[1:] + def format_time(time_s): if not time_s: return 'n/a' @@ -21,6 +22,7 @@ def format_time(time_s): return '%s:%s:%s' % (str(int(hours)).zfill(2), str(int(minutes % 60)).zfill(2), str(int(time_s % 60)).zfill(2)) + def print_gpx_part_info(gpx_part, indentation=' '): """ gpx_part may be a track or segment. @@ -58,6 +60,7 @@ def print_gpx_part_info(gpx_part, indentation=' '): print('') + def print_gpx_info(gpx): print('File: %s' % gpx_file) diff --git a/gpxpy/__init__.py b/gpxpy/__init__.py index 10880642..8130dd24 100644 --- a/gpxpy/__init__.py +++ b/gpxpy/__init__.py @@ -14,6 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. + def parse(xml_or_file, parser=None): """ Parse xml (string) or file object. This is just an wrapper for diff --git a/gpxpy/geo.py b/gpxpy/geo.py index 93f8c98d..40c19777 100644 --- a/gpxpy/geo.py +++ b/gpxpy/geo.py @@ -28,9 +28,11 @@ EARTH_RADIUS = 6371 * 1000 + def to_rad(x): return x / 180. * mod_math.pi + def haversine_distance(latitude_1, longitude_1, latitude_2, longitude_2): """ Haversine distance between two points, expressed in meters. @@ -49,6 +51,7 @@ def haversine_distance(latitude_1, longitude_1, latitude_2, longitude_2): return d + def length(locations=None, _3d=None): locations = locations or [] if not locations: @@ -69,16 +72,19 @@ def length(locations=None, _3d=None): length += d return length + def length_2d(locations=None): """ 2-dimensional length (meters) of locations (only latitude and longitude, no elevation). """ locations = locations or [] return length(locations, False) + def length_3d(locations=None): """ 3-dimensional length (meters) of locations (it uses latitude, longitude, and elevation). """ locations = locations or [] return length(locations, True) + def calculate_max_speed(speeds_and_distances): """ Compute average distance and standard deviation for distance. Extremes @@ -109,7 +115,7 @@ def calculate_max_speed(speeds_and_distances): # sort by speed: speeds = list(map(lambda speed_and_distance: speed_and_distance[0], filtered_speeds_and_distances)) - if not isinstance(speeds, list): # python3 + if not isinstance(speeds, list): # python3 speeds = list(speeds) if not speeds: return None @@ -122,6 +128,7 @@ def calculate_max_speed(speeds_and_distances): return speeds[index] + def calculate_uphill_downhill(elevations): if not elevations: return 0, 0 @@ -152,6 +159,7 @@ def __filter(n): return uphill, downhill + def distance(latitude_1, longitude_1, elevation_1, latitude_2, longitude_2, elevation_2, haversine=None): """ @@ -180,6 +188,7 @@ def distance(latitude_1, longitude_1, elevation_1, latitude_2, longitude_2, elev return mod_math.sqrt(distance_2d ** 2 + (elevation_1 - elevation_2) ** 2) + def elevation_angle(location1, location2, radians=False): """ Uphill/downhill angle between two locations. """ if location1.elevation is None or location2.elevation is None: @@ -198,6 +207,7 @@ def elevation_angle(location1, location2, radians=False): return 180 * angle / mod_math.pi + def distance_from_line(point, line_point_1, line_point_2): """ Distance of point from a line given with two points. """ assert point, point @@ -216,6 +226,7 @@ def distance_from_line(point, line_point_1, line_point_2): return 2. * mod_math.sqrt(abs(s * (s - a) * (s - b) * (s - c))) / a + def get_line_equation_coefficients(location1, location2): """ Get line equation coefficients for: @@ -231,6 +242,7 @@ def get_line_equation_coefficients(location1, location2): b = location1.latitude - location1.longitude * a return float(1), float(-a), float(-b) + def simplify_polyline(points, max_distance): """Does Ramer-Douglas-Peucker algorithm for simplification of polyline """ @@ -266,6 +278,7 @@ def simplify_polyline(points, max_distance): return (simplify_polyline(points[:tmp_max_distance_position + 2], max_distance) + simplify_polyline(points[tmp_max_distance_position + 1:], max_distance)[1:]) + class Location: """ Generic geographical location """ diff --git a/gpxpy/gpx.py b/gpxpy/gpx.py index 17dd87a4..7f5f96c5 100644 --- a/gpxpy/gpx.py +++ b/gpxpy/gpx.py @@ -20,14 +20,14 @@ import pdb -import logging as mod_logging -import math as mod_math -import collections as mod_collections -import copy as mod_copy -import datetime as mod_datetime +import logging as mod_logging +import math as mod_math +import collections as mod_collections +import copy as mod_copy +import datetime as mod_datetime from . import utils as mod_utils -from . import geo as mod_geo +from . import geo as mod_geo # GPX date format DATE_FORMAT = '%Y-%m-%dT%H:%M:%SZ' @@ -41,26 +41,27 @@ # When possible, the result of various methods are named tuples defined here: Bounds = mod_collections.namedtuple( - 'Bounds', - ('min_latitude', 'max_latitude', 'min_longitude', 'max_longitude')) + 'Bounds', + ('min_latitude', 'max_latitude', 'min_longitude', 'max_longitude')) TimeBounds = mod_collections.namedtuple( - 'TimeBounds', - ('start_time', 'end_time')) + 'TimeBounds', + ('start_time', 'end_time')) MovingData = mod_collections.namedtuple( - 'MovingData', - ('moving_time', 'stopped_time', 'moving_distance', 'stopped_distance', 'max_speed')) + 'MovingData', + ('moving_time', 'stopped_time', 'moving_distance', 'stopped_distance', 'max_speed')) UphillDownhill = mod_collections.namedtuple( - 'UphillDownhill', - ('uphill', 'downhill')) + 'UphillDownhill', + ('uphill', 'downhill')) MinimumMaximum = mod_collections.namedtuple( - 'MinimumMaximum', - ('minimum', 'maximum')) + 'MinimumMaximum', + ('minimum', 'maximum')) NearestLocationData = mod_collections.namedtuple( - 'NearestLocationData', - ('location', 'track_no', 'segment_no', 'point_no')) + 'NearestLocationData', + ('location', 'track_no', 'segment_no', 'point_no')) PointData = mod_collections.namedtuple( - 'PointData', - ('point', 'distance_from_start', 'track_no', 'segment_no', 'point_no')) + 'PointData', + ('point', 'distance_from_start', 'track_no', 'segment_no', 'point_no')) + class GPXException(Exception): """ @@ -69,6 +70,7 @@ class GPXException(Exception): """ pass + class GPXXMLSyntaxException(GPXException): """ Exception used when the the XML syntax is invalid. @@ -79,6 +81,7 @@ def __init__(self, message, original_exception): GPXException.__init__(self, message) self.__cause__ = original_exception + class GPXWaypoint(mod_geo.Location): time = None name = None @@ -95,9 +98,9 @@ class GPXWaypoint(mod_geo.Location): position_dilution = None def __init__(self, latitude, longitude, elevation=None, time=None, - name=None, description=None, symbol=None, type=None, - comment=None, horizontal_dilution=None, vertical_dilution=None, - position_dilution=None): + name=None, description=None, symbol=None, type=None, + comment=None, horizontal_dilution=None, vertical_dilution=None, + position_dilution=None): mod_geo.Location.__init__(self, latitude, longitude, elevation) self.time = time @@ -129,7 +132,7 @@ def to_xml(self, version=None): if self.type: content += mod_utils.to_xml('type', content=self.type, escape=True) - if version == '1.1': # TODO + if version == '1.1': # TODO content += mod_utils.to_xml('cmt', content=self.comment, escape=True) if self.horizontal_dilution: @@ -149,7 +152,8 @@ def get_max_dilution_of_precision(self): def __hash__(self): return mod_utils.hash_object(self, 'time', 'name', 'description', 'symbol', 'type', - 'comment', 'horizontal_dilution', 'vertical_dilution', 'position_dilution') + 'comment', 'horizontal_dilution', 'vertical_dilution', 'position_dilution') + class GPXRoute: def __init__(self, name=None, description=None, number=None): @@ -217,11 +221,12 @@ def to_xml(self, version=None): def __hash__(self): return mod_utils.hash_object(self, 'name', 'description', 'number', 'points') + class GPXRoutePoint(mod_geo.Location): def __init__(self, latitude, longitude, elevation=None, time=None, name=None, - description=None, symbol=None, type=None, comment=None, - horizontal_dilution=None, vertical_dilution=None, - position_dilution=None): + description=None, symbol=None, type=None, comment=None, + horizontal_dilution=None, vertical_dilution=None, + position_dilution=None): mod_geo.Location.__init__(self, latitude, longitude, elevation) @@ -232,9 +237,9 @@ def __init__(self, latitude, longitude, elevation=None, time=None, name=None, self.type = type self.comment = comment - self.horizontal_dilution = horizontal_dilution # Horizontal dilution of precision - self.vertical_dilution = vertical_dilution # Vertical dilution of precision - self.position_dilution = position_dilution # Position dilution of precision + self.horizontal_dilution = horizontal_dilution # Horizontal dilution of precision + self.vertical_dilution = vertical_dilution # Vertical dilution of precision + self.position_dilution = position_dilution # Position dilution of precision def __str__(self): return '[rtept{%s}:%s,%s@%s]' % (self.name, self.latitude, self.longitude, self.elevation) @@ -267,12 +272,13 @@ def to_xml(self, version=None): def __hash__(self): return mod_utils.hash_object(self, 'time', 'name', 'description', 'symbol', 'type', 'comment', - 'horizontal_dilution', 'vertical_dilution', 'position_dilution') + 'horizontal_dilution', 'vertical_dilution', 'position_dilution') + class GPXTrackPoint(mod_geo.Location): def __init__(self, latitude, longitude, elevation=None, time=None, symbol=None, comment=None, - horizontal_dilution=None, vertical_dilution=None, position_dilution=None, speed=None, - name=None): + horizontal_dilution=None, vertical_dilution=None, position_dilution=None, speed=None, + name=None): mod_geo.Location.__init__(self, latitude, longitude, elevation) self.time = time @@ -280,9 +286,9 @@ def __init__(self, latitude, longitude, elevation=None, time=None, symbol=None, self.comment = comment self.name = name - self.horizontal_dilution = horizontal_dilution # Horizontal dilution of precision - self.vertical_dilution = vertical_dilution # Vertical dilution of precision - self.position_dilution = position_dilution # Position dilution of precision + self.horizontal_dilution = horizontal_dilution # Horizontal dilution of precision + self.vertical_dilution = vertical_dilution # Vertical dilution of precision + self.position_dilution = position_dilution # Position dilution of precision self.speed = speed @@ -357,7 +363,8 @@ def __str__(self): def __hash__(self): return mod_utils.hash_object(self, 'latitude', 'longitude', 'elevation', 'time', 'symbol', 'comment', - 'horizontal_dilution', 'vertical_dilution', 'position_dilution', 'speed') + 'horizontal_dilution', 'vertical_dilution', 'position_dilution', 'speed') + class GPXTrack: def __init__(self, name=None, description=None, number=None): @@ -681,6 +688,7 @@ def clone(self): def __hash__(self): return mod_utils.hash_object(self, 'name', 'description', 'number', 'segments') + class GPXTrackSegment: def __init__(self, points=None): self.points = points if points else [] @@ -752,8 +760,8 @@ def get_points_no(self): def split(self, point_no): """ Splits this segment in two parts. Point #point_no remains in the first part. Returns a list with two GPXTrackSegments """ - part_1 = self.points[: point_no + 1] - part_2 = self.points[point_no + 1 :] + part_1 = self.points[:point_no + 1] + part_2 = self.points[point_no + 1:] return GPXTrackSegment(part_1), GPXTrackSegment(part_2) def join(self, track_segment): @@ -764,8 +772,8 @@ def remove_point(self, point_no): if point_no < 0 or point_no >= len(self.points): return - part_1 = self.points[: point_no] - part_2 = self.points[point_no + 1 :] + part_1 = self.points[:point_no] + part_2 = self.points[point_no + 1:] self.points = part_1 + part_2 @@ -813,7 +821,7 @@ def get_moving_data(self, stopped_speed_threshold=None): moving_distance += distance if distance and moving_time: - speeds_and_distances.append((distance / timedelta.seconds, distance, )) + speeds_and_distances.append((distance / timedelta.seconds, distance,)) max_speed = None if speeds_and_distances: @@ -891,7 +899,7 @@ def add_elevation(self, delta): return for track_point in self.points: - if track_point.elevation != None: + if track_point.elevation is not None: track_point.elevation += delta def add_missing_data(self, get_data_function, add_missing_function): @@ -908,14 +916,14 @@ def add_missing_data(self, get_data_function, add_missing_function): previous_point = None for track_point in self.points: data = get_data_function(track_point) - if data == None and previous_point: + if data is None and previous_point: if not start_point: start_point = previous_point interval.append(track_point) else: if interval: distances_ratios = self._get_interval_distances_ratios(interval, - start_point, track_point) + start_point, track_point) add_missing_function(interval, start_point, track_point, distances_ratios) start_point = None @@ -941,7 +949,7 @@ def _get_interval_distances_ratios(self, interval, start, end): assert len(interval) == len(distances) return list(map( - lambda distance : (distance / from_start_to_end) if from_start_to_end else 0, + lambda distance: (distance / from_start_to_end) if from_start_to_end else 0, distances)) def get_duration(self): @@ -976,7 +984,7 @@ def get_uphill_downhill(self): if not self.points: return UphillDownhill(0, 0) - elevations = list(map(lambda point:point.elevation, self.points)) + elevations = list(map(lambda point: point.elevation, self.points)) uphill, downhill = mod_geo.calculate_uphill_downhill(elevations) return UphillDownhill(uphill, downhill) @@ -987,8 +995,8 @@ def get_elevation_extremes(self): if not self.points: return MinimumMaximum(None, None) - elevations = map(lambda location:location.elevation, self.points) - elevations = filter(lambda elevation:elevation is not None, elevations) + elevations = map(lambda location: location.elevation, self.points) + elevations = filter(lambda elevation: elevation is not None, elevations) elevations = list(elevations) if len(elevations) == 0: @@ -1074,7 +1082,7 @@ def smooth(self, vertical=True, horizontal=False, remove_extremes=False): # compute the average distance between two points: distances = [] elevations_delta = [] - for i in range(len(self.points))[1 :]: + for i in range(len(self.points))[1:]: distances.append(self.points[i].distance_2d(self.points[i - 1])) elevation_1 = self.points[i].elevation elevation_2 = self.points[i - 1].elevation @@ -1089,18 +1097,18 @@ def smooth(self, vertical=True, horizontal=False, remove_extremes=False): # points -- then is a candidate for deletion: # TODO: Make this a method parameter remove_2d_extremes_threshold = 1.75 * avg_distance - remove_elevation_extremes_threshold = avg_elevation_delta * 5 # TODO: Param + remove_elevation_extremes_threshold = avg_elevation_delta * 5 # TODO: Param new_track_points = [self.points[0]] - for i in range(len(self.points))[1 : -1]: + for i in range(len(self.points))[1:-1]: new_point = None point_removed = False if vertical and elevations[i - 1] and elevations[i] and elevations[i + 1]: old_elevation = self.points[i].elevation new_elevation = SMOOTHING_RATIO[0] * elevations[i - 1] + \ - SMOOTHING_RATIO[1] * elevations[i] + \ - SMOOTHING_RATIO[2] * elevations[i + 1] + SMOOTHING_RATIO[1] * elevations[i] + \ + SMOOTHING_RATIO[2] * elevations[i + 1] if not remove_extremes: self.points[i].elevation = new_elevation @@ -1126,12 +1134,12 @@ def smooth(self, vertical=True, horizontal=False, remove_extremes=False): if horizontal: old_latitude = self.points[i].latitude new_latitude = SMOOTHING_RATIO[0] * latitudes[i - 1] + \ - SMOOTHING_RATIO[1] * latitudes[i] + \ - SMOOTHING_RATIO[2] * latitudes[i + 1] + SMOOTHING_RATIO[1] * latitudes[i] + \ + SMOOTHING_RATIO[2] * latitudes[i + 1] old_longitude = self.points[i].longitude new_longitude = SMOOTHING_RATIO[0] * longitudes[i - 1] + \ - SMOOTHING_RATIO[1] * longitudes[i] + \ - SMOOTHING_RATIO[2] * longitudes[i + 1] + SMOOTHING_RATIO[1] * longitudes[i] + \ + SMOOTHING_RATIO[2] * longitudes[i + 1] if not remove_extremes: self.points[i].latitude = new_latitude @@ -1210,6 +1218,7 @@ def __hash__(self): def clone(self): return mod_copy.deepcopy(self) + class GPX: def __init__(self, waypoints=None, routes=None, tracks=None): if waypoints: self.waypoints = waypoints @@ -1535,7 +1544,7 @@ def get_points_data(self, distance_2d=False): distance_from_start += distance - points.append(PointData(point, distance_from_start, track_no, segment_no, point_no )) + points.append(PointData(point, distance_from_start, track_no, segment_no, point_no)) previous_point = point @@ -1632,8 +1641,8 @@ def add_missing_elevations(self): def _add(interval, start, end, distances_ratios): assert start assert end - assert start.elevation != None - assert end.elevation != None + assert start.elevation is not None + assert end.elevation is not None assert interval assert len(interval) == len(distances_ratios) for i in range(len(interval)): @@ -1646,18 +1655,18 @@ def add_missing_times(self): def _add(interval, start, end, distances_ratios): assert start assert end - assert start.time != None - assert end.time != None + assert start.time is not None + assert end.time is not None assert interval assert len(interval) == len(distances_ratios) - seconds_between = float((end.time - start.time).seconds) + seconds_between = float((end.time - start.time).seconds) for i in range(len(interval)): point = interval[i] ratio = distances_ratios[i] point.time = start.time + mod_datetime.timedelta( - seconds=(seconds_between + ratio * seconds_between)) + seconds=(seconds_between + ratio * seconds_between)) print(point.time) self.add_missing_data(get_data_function=lambda point: point.time, @@ -1708,11 +1717,11 @@ def to_xml(self): content += track.to_xml(version) xml_attributes = { - 'version': '1.0', - 'creator': 'gpx.py -- https://github.com/tkrajina/gpxpy', - 'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance', - 'xmlns': 'http://www.topografix.com/GPX/1/0', - 'xsi:schemaLocation': 'http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd', + 'version': '1.0', + 'creator': 'gpx.py -- https://github.com/tkrajina/gpxpy', + 'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance', + 'xmlns': 'http://www.topografix.com/GPX/1/0', + 'xsi:schemaLocation': 'http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd', } if self.creator: xml_attributes['creator'] = self.creator diff --git a/gpxpy/parser.py b/gpxpy/parser.py index f5d69dc4..11a38c64 100644 --- a/gpxpy/parser.py +++ b/gpxpy/parser.py @@ -27,11 +27,12 @@ import lxml.etree as mod_etree except: mod_etree = None - pass # LXML not available + pass # LXML not available from . import gpx as mod_gpx from . import utils as mod_utils + class XMLParser: """ Used when lxml is not available. Uses standard minidom. @@ -85,6 +86,7 @@ def get_node_attribute(self, node, attribute): return node.attributes[attribute].nodeValue return None + class LXMLParser: """ Used when lxml is available. @@ -143,6 +145,7 @@ def get_node_data(self, node): def get_node_attribute(self, node, attribute): return node.attrib.get(attribute) + def parse_time(string): if not string: return None @@ -222,7 +225,7 @@ def __parse_dom(self): if node is None: raise mod_gpx.GPXException('Document must have a `gpx` root node.') if self.xml_parser.get_node_attribute(node, "creator"): - self.gpx.creator = self.xml_parser.get_node_attribute(node, "creator") + self.gpx.creator = self.xml_parser.get_node_attribute(node, "creator") for node in self.xml_parser.get_children(node): node_name = self.xml_parser.get_node_name(node) @@ -288,7 +291,7 @@ def _parse_waypoint(self, node): elevation_node = self.xml_parser.get_first_child(node, 'ele') elevation = mod_utils.to_number(self.xml_parser.get_node_data(elevation_node), - default = None, nan_value = None) + default=None, nan_value=None) time_node = self.xml_parser.get_first_child(node, 'time') time_str = self.xml_parser.get_node_data(time_node) @@ -319,9 +322,9 @@ def _parse_waypoint(self, node): pdop = mod_utils.to_number(self.xml_parser.get_node_data(pdop_node)) return mod_gpx.GPXWaypoint(latitude=lat, longitude=lon, elevation=elevation, - time=time, name=name, description=desc, symbol=sym, - type=type, comment=comment, horizontal_dilution=hdop, - vertical_dilution=vdop, position_dilution=pdop) + time=time, name=name, description=desc, symbol=sym, + type=type, comment=comment, horizontal_dilution=hdop, + vertical_dilution=vdop, position_dilution=pdop) def _parse_route(self, node): name_node = self.xml_parser.get_first_child(node, 'name') @@ -357,7 +360,7 @@ def _parse_route_point(self, node): elevation_node = self.xml_parser.get_first_child(node, 'ele') elevation = mod_utils.to_number(self.xml_parser.get_node_data(elevation_node), - default = None, nan_value = None) + default=None, nan_value=None) time_node = self.xml_parser.get_first_child(node, 'time') time_str = self.xml_parser.get_node_data(time_node) @@ -388,7 +391,7 @@ def _parse_route_point(self, node): pdop = mod_utils.to_number(self.xml_parser.get_node_data(pdop_node)) return mod_gpx.GPXRoutePoint(lat, lon, elevation, time, name, desc, sym, type, comment, - horizontal_dilution = hdop, vertical_dilution = vdop, position_dilution = pdop) + horizontal_dilution=hdop, vertical_dilution=vdop, position_dilution=pdop) def __parse_track(self, node): name_node = self.xml_parser.get_first_child(node, 'name') @@ -437,7 +440,7 @@ def __parse_track_point(self, node): elevation_node = self.xml_parser.get_first_child(node, 'ele') elevation = mod_utils.to_number(self.xml_parser.get_node_data(elevation_node), - default = None, nan_value = None) + default=None, nan_value=None) sym_node = self.xml_parser.get_first_child(node, 'sym') symbol = self.xml_parser.get_node_data(sym_node) @@ -461,9 +464,8 @@ def __parse_track_point(self, node): speed = mod_utils.to_number(self.xml_parser.get_node_data(speed_node)) return mod_gpx.GPXTrackPoint(latitude=latitude, longitude=longitude, elevation=elevation, time=time, - symbol=symbol, comment=comment, horizontal_dilution=hdop, vertical_dilution=vdop, - position_dilution=pdop, speed=speed, name=name) - + symbol=symbol, comment=comment, horizontal_dilution=hdop, vertical_dilution=vdop, + position_dilution=pdop, speed=speed, name=name) if __name__ == '__main__': diff --git a/gpxpy/utils.py b/gpxpy/utils.py index 408d6b52..cdd12ffd 100644 --- a/gpxpy/utils.py +++ b/gpxpy/utils.py @@ -20,6 +20,7 @@ PYTHON_VERSION = mod_sys.version.split(' ')[0] + def to_xml(tag, attributes=None, content=None, default=None, escape=False): attributes = attributes or {} result = '\n<%s' % tag @@ -43,6 +44,7 @@ def to_xml(tag, attributes=None, content=None, default=None, escape=False): return result + def is_numeric(object): try: float(object) @@ -52,6 +54,7 @@ def is_numeric(object): except ValueError: return False + def to_number(s, default=0, nan_value=None): try: result = float(s) @@ -64,9 +67,9 @@ def to_number(s, default=0, nan_value=None): pass return default - # Hash utilities: + def __hash(obj): result = 0 @@ -79,6 +82,7 @@ def __hash(obj): return hash(obj) + def hash_list_or_tuple(iteration): result = 17 @@ -87,6 +91,7 @@ def hash_list_or_tuple(iteration): return result + def hash_object(obj, *attributes): result = 19 @@ -95,6 +100,7 @@ def hash_object(obj, *attributes): return result + def make_str(s): """ Convert a str or unicode object into a str type. """ if PYTHON_VERSION[0] == '2': diff --git a/test.py b/test.py index a8180dba..7300201b 100644 --- a/test.py +++ b/test.py @@ -54,6 +54,7 @@ mod_logging.basicConfig(level=mod_logging.DEBUG, format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s') + def equals(object1, object2, ignore=None): """ Testing purposes only """ @@ -96,6 +97,7 @@ def equals(object1, object2, ignore=None): # TODO: Track segment speed in point test + class AbstractTests: """ Add tests here. @@ -167,20 +169,19 @@ def test_simple_parse_function_invalid_xml(self): def test_creator_field(self): gpx = self.parse('cerknicko-jezero.gpx') - self.assertEquals(gpx.creator,"GPSBabel - http://www.gpsbabel.org") - def test_no_creator_field(self): + self.assertEquals(gpx.creator, "GPSBabel - http://www.gpsbabel.org") + def test_no_creator_field(self): gpx = self.parse('cerknicko-jezero-no-creator.gpx') - self.assertEquals(gpx.creator,None) + self.assertEquals(gpx.creator, None) def test_to_xml_creator(self): gpx = self.parse('cerknicko-jezero.gpx') xml = gpx.to_xml() - self.assertTrue('creator="GPSBabel - http://www.gpsbabel.org"' in xml ) + self.assertTrue('creator="GPSBabel - http://www.gpsbabel.org"' in xml) gpx2 = self.reparse(gpx) - self.assertEquals(gpx2.creator,"GPSBabel - http://www.gpsbabel.org") - + self.assertEquals(gpx2.creator, "GPSBabel - http://www.gpsbabel.org") def test_waypoints_equality_after_reparse(self): gpx = self.parse('cerknicko-jezero.gpx') @@ -218,7 +219,7 @@ def test_get_duration(self): gpx.tracks[0].segments.append(mod_gpx.GPXTrackSegment()) gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=13, - time=mod_datetime.datetime(2013, 1, 1, 12, 30))) + time=mod_datetime.datetime(2013, 1, 1, 12, 30))) self.assertEqual(gpx.get_duration(), 0) gpx.tracks[0].segments.append(mod_gpx.GPXTrackSegment()) @@ -227,9 +228,9 @@ def test_get_duration(self): gpx.tracks[0].segments.append(mod_gpx.GPXTrackSegment()) gpx.tracks[0].segments[2].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=13, - time=mod_datetime.datetime(2013, 1, 1, 12, 30))) + time=mod_datetime.datetime(2013, 1, 1, 12, 30))) gpx.tracks[0].segments[2].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=13, - time=mod_datetime.datetime(2013, 1, 1, 12, 31))) + time=mod_datetime.datetime(2013, 1, 1, 12, 31))) self.assertEqual(gpx.get_duration(), 60) def test_remove_elevation(self): @@ -534,7 +535,7 @@ def test_remove_point_from_segment(self): self.assertTrue(len(segment.points) + 1 == len(original_segment.points)) def test_distance(self): - distance = mod_geo.distance(48.56806,21.43467, None, 48.599214,21.430878, None) + distance = mod_geo.distance(48.56806, 21.43467, None, 48.599214, 21.430878, None) print(distance) self.assertTrue(distance > 3450 and distance < 3500) @@ -593,7 +594,6 @@ def test_vertical_smooth_remove_extremes(self): print(points_before) print(points_after) - self.assertTrue(points_before - 1 == points_after) def test_horizontal_and_vertical_smooth_remove_extremes(self): @@ -786,8 +786,8 @@ def test_time_bounds(self): segment_1 = mod_gpx.GPXTrackSegment() segment_1.points.append(mod_gpx.GPXTrackPoint(latitude=-12, longitude=13)) - segment_1.points.append(mod_gpx.GPXTrackPoint(latitude=-100, longitude=-5, time=mod_datetime.datetime(2001, 1, 12) )) - segment_1.points.append(mod_gpx.GPXTrackPoint(latitude=100, longitude=-13 , time=mod_datetime.datetime(2003, 1, 12))) + segment_1.points.append(mod_gpx.GPXTrackPoint(latitude=-100, longitude=-5, time=mod_datetime.datetime(2001, 1, 12))) + segment_1.points.append(mod_gpx.GPXTrackPoint(latitude=100, longitude=-13, time=mod_datetime.datetime(2003, 1, 12))) track.segments.append(segment_1) segment_2 = mod_gpx.GPXTrackSegment() @@ -851,7 +851,7 @@ def test_name_comment_and_symbol(self): xml = gpx.to_xml() - self.assertTrue('aaa' in xml ) + self.assertTrue('aaa' in xml) gpx2 = self.reparse(gpx) @@ -900,7 +900,7 @@ def test_named_tuples_values_bounds(self): gpx = self.parse('korita-zbevnica.gpx') bounds = gpx.get_bounds() - min_lat, max_lat, min_lon, max_lon=gpx.get_bounds() + min_lat, max_lat, min_lon, max_lon = gpx.get_bounds() self.assertEqual(min_lat, bounds.min_latitude) self.assertEqual(min_lon, bounds.min_longitude) @@ -920,7 +920,7 @@ def test_named_tuples_values_moving_data(self): gpx = self.parse('korita-zbevnica.gpx') moving_data = gpx.get_moving_data() - moving_time, stopped_time, moving_distance, stopped_distance, max_speed=gpx.get_moving_data() + moving_time, stopped_time, moving_distance, stopped_distance, max_speed = gpx.get_moving_data() self.assertEqual(moving_time, moving_data.moving_time) self.assertEqual(stopped_time, moving_data.stopped_time) self.assertEqual(moving_distance, moving_data.moving_distance) @@ -950,7 +950,7 @@ def test_named_tuples_values_nearest_location_data(self): location.latitude *= 1.00001 location.longitude *= 0.99999 nearest_location_data = gpx.get_nearest_location(location) - found_location, track_no, segment_no, point_no=gpx.get_nearest_location(location) + found_location, track_no, segment_no, point_no = gpx.get_nearest_location(location) self.assertEqual(found_location, nearest_location_data.location) self.assertEqual(track_no, nearest_location_data.track_no) self.assertEqual(segment_no, nearest_location_data.segment_no) @@ -962,7 +962,7 @@ def test_named_tuples_values_point_data(self): points_datas = gpx.get_points_data() for point_data in points_datas: - point, distance_from_start, track_no, segment_no, point_no=point_data + point, distance_from_start, track_no, segment_no, point_no = point_data self.assertEqual(point, point_data.point) self.assertEqual(distance_from_start, point_data.distance_from_start) self.assertEqual(track_no, point_data.track_no) @@ -974,14 +974,14 @@ def test_track_points_data(self): points_data_2d = gpx.get_points_data(distance_2d=True) - point, distance_from_start, track_no, segment_no, point_no=points_data_2d[-1] + point, distance_from_start, track_no, segment_no, point_no = points_data_2d[-1] self.assertEqual(track_no, len(gpx.tracks) - 1) self.assertEqual(segment_no, len(gpx.tracks[-1].segments) - 1) self.assertEqual(point_no, len(gpx.tracks[-1].segments[-1].points) - 1) self.assertTrue(abs(distance_from_start - gpx.length_2d()) < 0.0001) points_data_3d = gpx.get_points_data(distance_2d=False) - point, distance_from_start, track_no, segment_no, point_no=points_data_3d[-1] + point, distance_from_start, track_no, segment_no, point_no = points_data_3d[-1] self.assertEqual(track_no, len(gpx.tracks) - 1) self.assertEqual(segment_no, len(gpx.tracks[-1].segments) - 1) self.assertEqual(point_no, len(gpx.tracks[-1].segments[-1].points) - 1) @@ -1249,17 +1249,17 @@ def test_add_missing_data_no_intervals(self): gpx.tracks[0].segments.append(mod_gpx.GPXTrackSegment()) gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=13, - elevation=10)) + elevation=10)) gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=14, - elevation=100)) + elevation=100)) gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=15, - elevation=20)) + elevation=20)) # Shouldn't be called because all points have elevation def _add_missing_function(interval, start_point, end_point, ratios): raise Error() - gpx.add_missing_data(get_data_function=lambda point:point.elevation, + gpx.add_missing_data(get_data_function=lambda point: point.elevation, add_missing_function=_add_missing_function) def test_add_missing_data_one_interval(self): @@ -1269,11 +1269,11 @@ def test_add_missing_data_one_interval(self): gpx.tracks[0].segments.append(mod_gpx.GPXTrackSegment()) gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=13, - elevation=10)) + elevation=10)) gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=14, - elevation=None)) + elevation=None)) gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=15, - elevation=20)) + elevation=20)) # Shouldn't be called because all points have elevation def _add_missing_function(interval, start_point, end_point, ratios): @@ -1286,7 +1286,7 @@ def _add_missing_function(interval, start_point, end_point, ratios): assert ratios interval[0].elevation = 314 - gpx.add_missing_data(get_data_function=lambda point:point.elevation, + gpx.add_missing_data(get_data_function=lambda point: point.elevation, add_missing_function=_add_missing_function) self.assertEquals(314, gpx.tracks[0].segments[0].points[1].elevation) @@ -1298,15 +1298,15 @@ def test_add_missing_data_one_interval_and_empty_points_on_start_and_end(self): gpx.tracks[0].segments.append(mod_gpx.GPXTrackSegment()) gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=13, - elevation=None)) + elevation=None)) gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=13, - elevation=10)) + elevation=10)) gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=14, - elevation=None)) + elevation=None)) gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=15, - elevation=20)) + elevation=20)) gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=12, longitude=13, - elevation=None)) + elevation=None)) # Shouldn't be called because all points have elevation def _add_missing_function(interval, start_point, end_point, ratios): @@ -1319,7 +1319,7 @@ def _add_missing_function(interval, start_point, end_point, ratios): assert ratios interval[0].elevation = 314 - gpx.add_missing_data(get_data_function=lambda point:point.elevation, + gpx.add_missing_data(get_data_function=lambda point: point.elevation, add_missing_function=_add_missing_function) # Points at start and end should not have elevation 314 because have @@ -1335,17 +1335,17 @@ def test_add_missing_elevations(self): gpx.tracks[0].segments.append(mod_gpx.GPXTrackSegment()) gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=13, longitude=12, - elevation=10)) + elevation=10)) gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=13.25, longitude=12, - elevation=None)) + elevation=None)) gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=13.5, longitude=12, - elevation=None)) + elevation=None)) gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=13.9, longitude=12, - elevation=None)) + elevation=None)) gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=14, longitude=12, - elevation=20)) + elevation=20)) gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=15, longitude=12, - elevation=None)) + elevation=None)) gpx.add_missing_elevations() @@ -1359,15 +1359,15 @@ def test_add_missing_times(self): gpx.tracks[0].segments.append(mod_gpx.GPXTrackSegment()) gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=13, longitude=12, - time=mod_datetime.datetime(2013, 1, 2, 12, 0))) + time=mod_datetime.datetime(2013, 1, 2, 12, 0))) gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=13.25, longitude=12, - time=None)) + time=None)) gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=13.5, longitude=12, - time=None)) + time=None)) gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=13.75, longitude=12, - time=None)) + time=None)) gpx.tracks[0].segments[0].points.append(mod_gpx.GPXTrackPoint(latitude=14, longitude=12, - time=mod_datetime.datetime(2013, 1, 2, 13, 0))) + time=mod_datetime.datetime(2013, 1, 2, 13, 0))) gpx.add_missing_times() @@ -1436,10 +1436,12 @@ def test_nan_elevation(self): self.assertTrue(gpx.routes[0].points[0].elevation == None) self.assertTrue(gpx.waypoints[0].elevation == None) + class LxmlTests(mod_unittest.TestCase, AbstractTests): def get_parser_type(self): return 'lxml' + class MinidomTests(LxmlTests, AbstractTests): def get_parser_type(self): return 'minidom'