Пример #1
0
def _load_gpx_points(filename):
    gpx_file = open(filename, 'r')
    gpx = gpxpy.parse(gpx_file)

    if len(gpx.tracks) != 1:
        raise TrackParsingError("GPX track with multiple tracks!")
    if len(gpx.tracks[0].segments) != 1:
        raise TrackParsingError("GPX track with multiple segments!")

    speed_in_mps = True
    print('Parsing %s gpx track' % gpx.creator)
    if gpx.creator == 'Racebox':
        speed_in_mps = False

    gpx_track = gpx.tracks[0].segments[0].points

    points = []
    for point in gpx_track:
        if point.speed is None:
            speed = 0.0
        else:
            speed = point.speed if speed_in_mps else float(point.speed) / 3.6

        points.append(TrackPoint(
            time=point.time,
            lat=point.latitude,
            lon=point.longitude,
            altitude=point.elevation,
            speed=speed,
            bearing=None
        ))

    return points
Пример #2
0
def _load_racechrono_csv_points(filename):
    csv_file = open(filename, newline='')

    # Seeking position for track start
    # Racechrono has several lines of headers, then empty line and the rest of the lines are actual track
    # Seeking for it
    line = csv_file.readline()
    lines_skipped = 0
    if 'RaceChrono' not in line:
        raise TrackParsingError('First line should contain "RaceChrono"!')
    while line.strip() and lines_skipped < RACECHRONO_MAX_HEADER_LINES:
        line = csv_file.readline()
        lines_skipped += 1

    if lines_skipped == RACECHRONO_MAX_HEADER_LINES:
        raise TrackParsingError('Cannot parse racechrono header, check the file manually')

    print(str(csv_file.tell()))

    track = csv.DictReader(csv_file, delimiter=',')

    invalid_rows = 0
    points = []
    for row in track:
        try:
            time_seconds_float = float(row[RACECHRONO_TIME_FIELD])
            time_seconds = int(time_seconds_float)
            time_microseconds = int(time_seconds_float % 1 * 1000000)
            time = datetime.fromtimestamp(time_seconds).replace(microsecond=time_microseconds)
            points.append(TrackPoint(
                time=time,
                lat=float(row[RACECHRONO_LAT_FIELD_IOS]),
                lon=float(row[RACECHRONO_LON_FIELD_IOS]),
                altitude=float(row[RACECHRONO_ALT_FIELD]),
                speed=float(row[RACECHRONO_SPEED_FIELD]),
                bearing=float(row[RACECHRONO_BEARING_FIELD]),
            ))

        except KeyError:
            raise TrackParsingError("Found invalid row %d: %s" % (len(points) + 1, str(row)))
        except ValueError:
            invalid_rows += 1

    if invalid_rows > RACECHRONO_INVALID_ROWS_THRESHOLD:
        raise TrackParsingError("Too many invalid rows in racechrono track: %d" % invalid_rows)

    print('Load racechrono track %s with %d points' % (filename, len(points)))

    return points
Пример #3
0
def normalize_minute_starts(points):
    from gpstools.track.track import TrackPoint
    if len(points) > 0 and (points[0].time.second != 0 or points[0].time.microsecond > 0):
        new_time = points[0].time.replace(second=0, microsecond=0)
        start_point = TrackPoint(
            new_time,
            points[0].lat,
            points[0].lon,
            points[0].altitude,
            points[0].speed,
            points[0].bearing
        )
        points.insert(0, start_point)

    return points
Пример #4
0
def _assign_micros_for_points(points, first_group=None):
    """When group is first, it means that we have to count points as a last millis in second"""
    assert len(points) <= 10
    micros_idx = 0
    if first_group:
        micros_idx = 10 - len(points)

    restored_points = []
    for i in range(len(points)):
        point = points[i]
        restored_points.append(TrackPoint(
            time=point.time.replace(microsecond=micros_idx * 100000),
            lat=point.latitude,
            lon=point.longitude,
            altitude=point.altitude,
            speed=point.speed,
            bearing=point.bearing
        ))
        micros_idx += 1

    return restored_points
Пример #5
0
def _load_racelogic_csv_points(filename):
    csv_file = open(filename, newline='')

    # Seeking position for track start
    # Racelogic has 7 lines of headers, then empty line and the rest of the lines are actual track
    # Seeking for it
    line = csv_file.readline()
    lines_skipped = 1
    if '[File]' not in line:
        raise TrackParsingError('First line should contain "[File]"!')
    while lines_skipped < RACELOGIC_MAX_HEADER_LINES:
        csv_file.readline()
        lines_skipped += 1

    track = csv.DictReader(csv_file, delimiter=',')
    points = []

    for row in track:
        try:
            lat = string2geocoord(row[RACELOGIC_LAT_FIELD], Latitude, "d%°%M% %H").decimal_degree
            # For some reason we have invalid hemisphere in logs
            lon = -string2geocoord(row[RACELOGIC_LON_FIELD], Longitude, "d%°%M% %H").decimal_degree

            points.append(TrackPoint(
                time=dateutil.parser.parse(row[RACELOGIC_TIME_FIELD]),
                lat=lat,
                lon=lon,
                altitude=float(row[RACELOGIC_ALT_FIELD]),
                speed=float(row[RACELOGIC_SPEED_FIELD]) / 3.6,  # Converting from kph to m/s
                bearing=float(row[RACELOGIC_BEARING_FIELD])
            ))

        except (KeyError, ValueError):
            raise TrackParsingError("Found invalid row %d: %s" % (len(points) + 1, str(row)))

    print('Load racelogic track %s with %d points' % (filename, len(points)))

    return points
Пример #6
0
def normalize_by_neighbor_weights(points, neighbor_weights):
    from gpstools.track.track import TrackPoint
    new_points = []

    prev_point = points[0]
    for i, point in enumerate(points):
        next_point = points[i + 1] if i < len(points) - 1 else points[i]

        new_points.append(TrackPoint(
            time=point.time,
            lat=neighbor_weights[0] * prev_point.lat +
                     neighbor_weights[1] * point.lat + neighbor_weights[2] * next_point.lat,
            lon=neighbor_weights[0] * prev_point.lon +
                     neighbor_weights[1] * point.lon + neighbor_weights[2] * next_point.lon,
            altitude=neighbor_weights[0] * prev_point.altitude +
                     neighbor_weights[1] * point.altitude + neighbor_weights[2] * next_point.altitude,
            speed=point.speed,
            bearing=point.bearing
        ))

        prev_point = point

    return new_points
Пример #7
0
def _load_racebox_csv_points(filename):
    csv_file = open(filename, newline='')

    track = csv.DictReader(csv_file, delimiter=';')
    points = []

    for row in track:
        try:
            points.append(TrackPoint(
                time=dateutil.parser.parse(row[RACEBOX_TIME_FIELD]),
                lat=float(row[RACEBOX_LAT_FIELD]),
                lon=float(row[RACEBOX_LON_FIELD]),
                altitude=float(row[RACEBOX_ALT_FIELD]),
                speed=float(row[RACEBOX_SPEED_FIELD]) / 3.6,  # Converting from kph to m/s
                bearing=float(row[RACEBOX_BEARING_FIELD])
            ))

        except (KeyError, ValueError):
            raise TrackParsingError("Found invalid row %d: %s" % (len(points) + 1, str(row)))

    print('Load racebox track %s with %d points' % (filename, len(points)))

    return points