def split_segments_by_length(gpx_segments_list: List[GPXTrackSegment], *, max_length_m: int = 100) \ -> List[GPXTrackSegment]: """ Split GPX track segments until all are shorter than max_length_m :param: gpx_segments_list: List of GPX track segments to be processed :param: max_length_m: Maximum length of track segment above which the segment should be split :return: List of GPX track segments that are all shorter than max_length_m """ gpx_split_segments_list = [] buffer = collections.deque(gpx_segments_list) while len(buffer) > 0: segment = buffer.popleft() if segment.length_2d() < max_length_m: gpx_split_segments_list.append(segment) else: buffer.append(GPXTrackSegment(segment.points[:len(segment.points)//2])) buffer.append(GPXTrackSegment(segment.points[len(segment.points)//2:])) return gpx_split_segments_list
def observations_to_gpx( observations: List[JsonResponse], output_file: str = "observations.gpx", track: bool = True ): """Convert a list of observations to a set of GPX waypoints or a GPX track Args: observations: JSON observations output_file: File path to write to track: Create an ordered GXP track; otherwise, create unordered GPX waypoints """ gpx = GPX() logger.info(f"Converting {len(observations)} to GPX points") points = [observation_to_gpx_point(obs, track=track) for obs in observations] if track: gpx_track = GPXTrack() gpx.tracks.append(gpx_track) gpx_segment = GPXTrackSegment() gpx_track.segments.append(gpx_segment) gpx_segment.points = points else: gpx.waypoints = points # Save to file logger.info(f"Writing GPX data to {output_file}") with open(output_file, "w") as f: f.write(gpx.to_xml())
def optimize_segment(seg): """ RDP algorithm """ result = GPXTrackSegment() arr = np.array(list(map(lambda p: [p.latitude, p.longitude], seg.points))) mask = rdp(arr, algo="iter", return_mask=True, epsilon=EPSILON) parr = np.array(list(seg.points)) result.points = list(parr[mask]) return result
def setUp(self): self.short_segment_as_array = np.array([[1., 0., 3]]) self.short_segment = GPXTrackSegment( [gpx_point_from_array(self.short_segment_as_array[0])]) self.long_segment_as_array = np.random.normal(size=(25, 3)) self.long_segment = GPXTrackSegment([ gpx_point_from_array(point_data) for point_data in self.long_segment_as_array ])
def test_segment_short_1(self): input = [GPXTrackSegment(self.segment_1.points[0:3])] smoothen_coordinates(input) expected_result = [GPXTrackSegment([self.expected_1.points[0]])] self.assertEqual(len(input), 1) self.assertEqual(len(input[0].points), 1) np.testing.assert_array_almost_equal( gpx_point_to_array(input[0].points[0]), gpx_point_to_array(expected_result[0].points[0]))
def setUp(self): self.segment_1 = GPXTrackSegment([ GPXTrackPoint(longitude=.1, latitude=1, elevation=10), GPXTrackPoint(longitude=.2, latitude=2, elevation=20), GPXTrackPoint(longitude=.3, latitude=3, elevation=30), GPXTrackPoint(longitude=.5, latitude=-1, elevation=0) ]) self.expected_1 = GPXTrackSegment([ GPXTrackPoint(longitude=.2, latitude=2, elevation=20), GPXTrackPoint(longitude=1. / 3, latitude=4. / 3, elevation=50. / 3) ])
def main(gps_log, lawnmower_log): with open(gps_log) as fp: gpx = GPX() #Fill in the Waypoints and what the lawnmower saw with open(lawnmower_log) as fpi: # Create track for lawnmower gpx_track = GPXTrack(name="Lawmower GPS Log") gpx.tracks.append(gpx_track) # Create segment in GPX track: gpx_segment = GPXTrackSegment() gpx_track.segments.append(gpx_segment) for l in fpi: m = re.match(lawnmower_wpt_fmt, l) if m: point_num = int(m.group(2)) lat = float(m.group(3)) lon = float(m.group(4)) gpx.waypoints.append(GPXWaypoint(lat,lon,description="P%d" % point_num, type="Lawnmower")) m = re.match(lawnmower_gps_fmt, l) if m: ctime = parse_time(m.group(1)) lat = float(m.group(2)) lon = float(m.group(3)) gpx_segment.points.append(GPXTrackPoint(lat,lon,time=ctime)) # Create track of raw GPS log: gpx_track = GPXTrack(name="GPS Log") gpx.tracks.append(gpx_track) # Create segment in GPX track: gpx_segment = GPXTrackSegment() gpx_track.segments.append(gpx_segment) for l in fp: m = re.match(gps_fmt, l) if m: ctime = parse_time(m.group(1)) lat = float(m.group(2)) lon = float(m.group(3)) #'time' since last DGPS fix is group 4 hdop = float(m.group(5)) fix_quality = int(m.group(6)) num_satellites = int(m.group(7)) gpx_segment.points.append(GPXTrackPoint(lat,lon,horizontal_dilution=hdop,time=ctime)) with open("lawnmower_log.gpx", "w") as fpo: print(gpx.to_xml(), file=fpo)
def main(naza_log): with open(naza_log) as fp: gpx = GPX() # Create track of raw GPS log: gpx_track = GPXTrack(name="GPS Log") gpx.tracks.append(gpx_track) # Create segment in GPX track: gpx_segment = GPXTrackSegment() gpx_track.segments.append(gpx_segment) for l in fp: row = l.split(",") ctime = datetime.strptime(row[0], time_fmt) lat, lon, alt = float(row[1]), float(row[2]), float(row[3]) speed, cog, calheading = float(row[4]), float(row[5]), float( row[6]) hdop, vdop = float(row[7]), float(row[8]) fixtype, numsat = int(row[9]), int(row[10]) gpx_segment.points.append( GPXTrackPoint(lat, lon, alt, horizontal_dilution=hdop, vertical_dilution=vdop, speed=speed, name=str(calheading), time=ctime)) with open("naza_log.gpx", "w") as fpo: print(gpx.to_xml(), file=fpo)
def _gpx_for_logs(self, logs): g = GPX() track = GPXTrack() track.source = 'pizero-gpslog %s' % VERSION g.tracks.append(track) seg = GPXTrackSegment() track.segments.append(seg) for item in logs: try: tpv = item['tpv'][0] sky = item['sky'][0] p = GPXTrackPoint(latitude=tpv['lat'], longitude=tpv['lon'], elevation=tpv['alt'], time=TIME_TYPE.from_string(tpv['time']), speed=tpv['speed'], horizontal_dilution=sky.get('hdop', None), vertical_dilution=sky.get('vdop', None), position_dilution=sky.get('pdop', None)) if tpv['mode'] == 2: p.type_of_gpx_fix = '2d' elif tpv['mode'] == 3: p.type_of_gpx_fix = '3d' if 'satellites' in sky: p.satellites = len(sky['satellites']) seg.points.append(p) except Exception: sys.stderr.write('Exception loading line %d:\n' % item['lineno']) raise return g
def filter_segments_spt(segments, max_dist_error, max_speed_error): new_segments = [] for segment in segments: points = util.remove_duplicates(segment.points) new_segments.append( GPXTrackSegment(util.spt(points, max_dist_error, max_speed_error))) return new_segments
def main(gps_log): with open(gps_log) as fp: gpx = GPX() # Create track of raw GPS log: gpx_track = GPXTrack(name="GPS Log") gpx.tracks.append(gpx_track) # Create segment in GPX track: gpx_segment = GPXTrackSegment() gpx_track.segments.append(gpx_segment) for l in fp: m = re.match(gps_fmt, l) if m: ctime = parse_time(m.group(1)) lat = float(m.group(2)) lon = float(m.group(3)) #speed = float(m.group(4)) bearing = m.group(5) #alt = float(m.group(6)) speed = 0 alt = 0 gpx_segment.points.append(GPXTrackPoint(lat,lon,time=ctime, speed=speed, elevation=alt, name=bearing)) with open("gps_log.gpx", "w") as fpo: print(gpx.to_xml(), file=fpo)
def to_gpx(observations: AnyObservations, filename: str = None, track: bool = True) -> str: """Convert a list of observations to a set of GPX waypoints or a GPX track Example: >>> from pyinaturalist import get_observations >>> from pyinaturalist_convert import to_gpx >>> >>> results = get_observations( ... project_id=36883, # ID of the 'Sugarloaf Ridge State Park' project ... created_d1='2020-01-01', # Get observations from January 2020... ... created_d2='2020-09-30', # ...through September 2020 ... geo=True, # Only get observations with coordinates ... geoprivacy='open', # Only get observations with public coordinates ... page='all', # Paginate through all response pages ... ) >>> to_gpx(results, '~/tracks/observations-36883.gpx') Args: observations: JSON observations filename: Optional file path to write to track: Create an ordered GPX track; otherwise, create unordered GPX waypoints Returns: GPX XML as a string """ gpx = GPX() points = [ to_gpx_point(obs, track=track) for obs in to_dict_list(observations) ] if track: gpx_track = GPXTrack() gpx.tracks.append(gpx_track) gpx_segment = GPXTrackSegment() gpx_track.segments.append(gpx_segment) gpx_segment.points = points else: gpx.waypoints = points gpx_xml = gpx.to_xml() if filename: write(gpx_xml, filename) return gpx_xml
def setUp(self): self.segment_1 = GPXTrackSegment([ GPXTrackPoint(longitude=.1, latitude=1, elevation=10), GPXTrackPoint(longitude=.2, latitude=2, elevation=20), GPXTrackPoint(longitude=.3, latitude=3, elevation=30) ]) self.expected_path_1 = \ np.array([[0., 0., 0.], [1.0049875621, 0., 10], [2.00997512422, 0., 20], [0., 0., 0.]])
def bearing_splitter(points_set, degree_threshold, min_length): segments = [] segment = GPXTrackSegment() previous_bearing = None idx = 0 while idx < len(points_set) - 1: current_bearing = util.compass_bearing(points_set[idx], points_set[idx + 1]) if previous_bearing is not None: diff_bearing = abs(previous_bearing - current_bearing) if diff_bearing > 180: diff_bearing = abs(diff_bearing - 360) if diff_bearing > degree_threshold: segment.points.append(points_set[idx]) if segment.length_2d() > min_length: segments.append(segment) previous_bearing = None segment = GPXTrackSegment() # Not increase index. Next iteration must restart from this point else: segment.points.append(points_set[idx]) previous_bearing = current_bearing idx += 1 else: segment.points.append(points_set[idx]) previous_bearing = current_bearing idx += 1 segment.points.append(points_set[idx]) # append last point if segment.length_2d() > min_length: segments.append(segment) return segments
def split_by_distance(seg, max_distance=DISTANCE_THRESHOLD): """ Split segment if distance between two points exceeds max_distance """ result = [] last_split = 0 for i in range(len(seg.points) - 1): s = seg.points[i] f = seg.points[i + 1] if get_distance(s, f) > max_distance: result.append(seg.points[last_split:i + 1]) last_split = i + 1 if i == len(seg.points) - 5: result.append(seg.points[last_split:i + 1]) return list( map(lambda points: GPXTrackSegment(points=points), filter(lambda p: len(p) > 2, result)))
def test_latitude_calculation(self): gpxpy_instance = GPX() gpxpy_instance.tracks.append(GPXTrack()) gpxpy_instance.tracks[0].segments.append(GPXTrackSegment()) points = gpxpy_instance.tracks[0].segments[0].points longitude_distance_km = 111.31949079327357 self.assertEqual(lon2kilometers(lon_count=1), longitude_distance_km) self.assertEqual(kilometers2lon_count(longitude_distance_km), 1) for lon_count in range(10): distance_km = lon2kilometers(lon_count) self.assert_equal_rounded(distance_km, longitude_distance_km * lon_count) self.assert_equal_rounded(kilometers2lon_count(distance_km), lon_count, decimal_places=0)
def gpxdump(pts): gpx = GPX() # Create track gpx_track = GPXTrack(name="Lawnmower pattern") gpx.tracks.append(gpx_track) # Create segment in GPX track: gpx_segment = GPXTrackSegment() gpx_track.segments.append(gpx_segment) for pt in pts: gpx_segment.points.append(GPXTrackPoint(pt.lat, pt.lon)) with open("lawnmower.gpx", "w") as fpo: print(gpx.to_xml(), file=fpo)
def filter_segments(gpx_segments_list: List[GPXTrackSegment], min_distance_m: float = 5) \ -> List[GPXTrackSegment]: """ Filter points from GPX track segments that are too close to each other :param: gpx_segments_list: List of GPX track segments to be processed :param: min_distance_m: Minimum distance between consecutive track points after filtering :return: List of GPX track segments that are all shorter than max_length_m """ gpx_filtered_segments_list = [] for segment in gpx_segments_list: points = [segment.points[0]] last_kept = segment.points[0] for point in segment.points[1:]: if GPXTrackSegment([last_kept, point]).length_2d() > min_distance_m: points.append(point) last_kept = point gpx_filtered_segments_list.append(GPXTrackSegment(points)) return gpx_filtered_segments_list
def gpxdump(pts): gpx = GPX() # Create track gpx_track = GPXTrack(name="Spiral pattern") gpx.tracks.append(gpx_track) # Create segment in GPX track: gpx_segment = GPXTrackSegment() gpx_track.segments.append(gpx_segment) for pt in pts: gpx_segment.points.append( GPXTrackPoint(pt.lat, pt.lon, elevation=pt.alt)) with open("spiral.gpx", "w") as fpo: print(gpx.to_xml(), file=fpo)
def test_create_work_as_expected(self, gpxpy_mock): # Given some fake GPX data pnt1 = GPXTrackPoint(latitude=1, longitude=1, time=datetime(2016, 1, 1)) pnt2 = GPXTrackPoint(latitude=2, longitude=2, time=datetime(2016, 1, 2)) segment = GPXTrackSegment(points=[pnt1, pnt2]) track = GPXTrack() track.segments = [segment] gpx = GPX() gpx.tracks = [track] # Given a mock gpxpy that returns the fake data gpxpy_mock.parse.return_value = gpx trackpoint_mock = Mock() up_file = Mock() up_file.read.return_value.decode.return_value = sentinel.gpx_raw # When creating trackpoints tps = create_trackpoints(sentinel.track, up_file, trackpoint_mock) # Then the correct stuff happens assert len(tps) == 2 trackpoint_mock.assert_any_call(lat=1, lon=1, sog=0, timepoint=datetime(2016, 1, 1, tzinfo=pytz.UTC), track=sentinel.track) trackpoint_mock.assert_any_call(lat=2, lon=2, sog=1.819738796736955, timepoint=datetime(2016, 1, 2, tzinfo=pytz.UTC), track=sentinel.track) gpxpy_mock.parse.assert_called_once_with(sentinel.gpx_raw) up_file.read.assert_called_once_with() up_file.read.return_value.decode.assert_called_once_with('utf-8')
def __init__(self, segment: GPXTrackSegment, num_points_path: int = 25) -> None: """ Construct GpxSegmentStats object. :param: segment: GPX track segment :param: num_points_path: Maximal length of points in path features """ self.name = getattr(segment, 'name', 'NotAvailable') self.length2d = segment.length_2d() self.length3d = segment.length_3d() self.duration = float(segment.get_duration()) \ if segment.get_duration() is not None else float(-1) self.moving_time = segment.get_moving_data().moving_time self.stopped_time = segment.get_moving_data().stopped_time self.total_uphill = segment.get_uphill_downhill().uphill self.total_downhill = segment.get_uphill_downhill().downhill self.path = convert_path_to_feature(segment, num_points_path)
def generate_gpx_track(track_length_km, point_count, pace_min, start_longitude=0, start_date=datetime(2018, 5, 30, 10, 00)): distance_km = track_length_km / point_count print("km between points:", distance_km) longitude_diff = kilometers2lon_count(distance_km) print("longitude diff:", longitude_diff) time_delta = timedelta(minutes=(pace_min * distance_km)) print("time delta:", time_delta) gpxpy_instance = GPX() gpxpy_instance.tracks.append(GPXTrack()) gpxpy_instance.tracks[0].segments.append(GPXTrackSegment()) points = gpxpy_instance.tracks[0].segments[0].points points.append( GPXTrackPoint(latitude=0, longitude=start_longitude, elevation=0, time=start_date)) print("Start point:", points[-1]) td = 0 current_longitude = start_longitude current_datetime = start_date for point_no in range(point_count): current_longitude += longitude_diff current_datetime += time_delta points.append( GPXTrackPoint(latitude=0, longitude=current_longitude, elevation=0, time=current_datetime)) print("point %i: %s" % (point_no + 1, points[-1])) print("\ttime diff:", points[-1].time_difference(points[-2])) print("\tdistance 2d:", points[-1].distance_2d(points[-2])) print("\tdistance 3d:", points[-1].distance_3d(points[-2])) td += points[-1].distance_3d(points[-2]) print("\t", td) return gpxpy_instance
def add_points(self, points) ->None: """Adds points to last segment in the last track. If no track is allocated yet and points is not an empty list, allocates a track. Args: points (list(GPXTrackPoint): The points to be added """ if points: if self.__gpx.tracks: # make sure the same points are not added twice assert points != self.__gpx.tracks[-1].segments[-1].points[-len(points):] self._load_full() if not self.__gpx.tracks: self.__gpx.tracks.append(GPXTrack()) self.__gpx.tracks[0].segments.append(GPXTrackSegment()) self.__gpx.tracks[-1].segments[-1].points.extend(points) self.dirty = 'gpx'
def _gpx_for_logs(self): g = GPX() track = GPXTrack() track.source = 'pizero-gpslog gmc-500' g.tracks.append(track) seg = GPXTrackSegment() track.segments.append(seg) prev_alt = 0.0 for idx, item in enumerate(self.lines): try: tpv = item['tpv'][0] sky = item['sky'][0] alt = tpv.get( 'alt', item['gst'][0].get('alt', prev_alt) ) prev_alt = alt p = GPXTrackPoint( latitude=tpv['lat'], longitude=tpv['lon'], elevation=alt, time=TIME_TYPE.from_string(tpv['time']), speed=tpv['speed'], horizontal_dilution=sky.get('hdop', None), vertical_dilution=sky.get('vdop', None), position_dilution=sky.get('pdop', None) ) if tpv['mode'] == 2: p.type_of_gpx_fix = '2d' elif tpv['mode'] == 3: p.type_of_gpx_fix = '3d' if 'satellites' in sky: p.satellites = len(sky['satellites']) cpm = item.get('_extra_data', {}).get('data', {}).get('cpm', 0) seg.points.append(p) except Exception: logger.error( 'Error loading line %d: %s', idx, item ) raise return g
def test_segment_empty(self): smoothen_coordinates([GPXTrackSegment()])
def save_to_gpx(nav_df: pd.DataFrame, fileOutPN, gpx_obj_namef=None, waypoint_symbf=None, cfg_proc=None, gpx=None): # """ Save navigation from dataframe to *.gpx file. track or waypoints. Generate waypoints names and selects symbols from cfg['out']['gpx_symbols'] based on current row in nav_df :param nav_df: DataFrame with fields: if waypoint_symbf: itbl, ... :param fileOutPN: *.gpx file full name without extension. Set None to not write (useful if need only gpx) :param gpx_obj_namef: str or fun(waypoint number). If None then we set it to fileOutPN.stem :param waypoint_symbf: str or fun(nav_df record = row). If None saves track :param cfg_proc: 'simplify_tracks_error_m' 'dt_per_file' 'b_missed_coord_to_zeros' period_segments or period_tracks: to split track by this in one file :param gpx: gpx object to update. If None (default) then will be created here, updated and saved :return: None """ if nav_df.empty: l.warning('no data') return if gpx_obj_namef is None: gpx_obj_namef = Path(fileOutPN).stem if cfg_proc is None: cfg_proc = {'dt_per_file': None} elif not 'dt_per_file' in cfg_proc: cfg_proc['dt_per_file'] = None if gpx is None: gpx = GPX() if waypoint_symbf: # , fun_symbol= 'Waypoint', fun_name= str if isinstance(waypoint_symbf, str): s = waypoint_symbf waypoint_symbf = lambda x: s b_useDepEcho = 'DepEcho' in nav_df.columns and any(nav_df['DepEcho']) w_names = set() # w_name = None # same perpose for not all conditions but faster # nav_dft= nav_df.reset_index().set_index('itbl', drop=False, append=True) #, inplace=True # for t in range(nav_dft.itbl.min(), nav_dft.itbl.max()+1): #.ptp() = - for t, nav_dft in nav_df.groupby(['itbl']): # .reset_index() for i, r in enumerate(nav_dft.itertuples()): # .loc[t] name=None str_time_short = '{:%d %H:%M}'.format(r.Index.to_pydatetime()) timeUTC = r.Index.tz_convert(None).to_pydatetime() str_time_long = '{:%d.%m.%y %H:%M:%S}'.format(timeUTC) name = gpx_obj_namef if isinstance(gpx_obj_namef, str) else gpx_obj_namef(i, r, t) # remove duplicates by add letter name_test_dup = name i_dup = 0 while name_test_dup in w_names: # name== w_name or : name_test_dup = name + chr(97 + i_dup) # chr(97) = 'a' i_dup += 1 else: name = name_test_dup w_names.add(name) gpx_waypoint = GPXWaypoint( latitude=r.Lat, longitude=r.Lon, time=timeUTC, description=str_time_long, comment=str_time_short, name=name, symbol=waypoint_symbf(r), elevation=-r.DepEcho if b_useDepEcho and np.isfinite( r.DepEcho) else None) # , description=, type=, comment= # if not i_dup: # w_name = name # to check duplicates on next cycle gpx.waypoints.append(gpx_waypoint) if isinstance(gpx_obj_namef, str): gpx.description = gpx_obj_namef if fileOutPN: gpx.author_email = '*****@*****.**' write_file(fileOutPN, gpx.to_xml()) else: # tracks # loc= np.zeros_like(nav_df.index, dtype= int) # Lat= np.zeros_like(nav_df.index, dtype= np.float64) # Lon= np.zeros_like(nav_df.index, dtype= np.float64) # T= np.zeros_like(nav_df.index, dtype= pd.Timedelta) b_have_depth = ('DepEcho' in nav_df.columns) #b_have_speed = ('Speed' in nav_df.columns) period_split = cfg_proc.get('period_segments') or cfg_proc.get('period_tracks') if period_split: period_split = pd_period_to_timedelta(period_split) t_intervals_start = pd.date_range( start=nav_df.index[0].normalize(), end=max(nav_df.index[-1], nav_df.index[-1].normalize() + period_split), freq=period_split)[1:] # make last t_interval_start >= all_data[-1] #format_time = else: t_intervals_start = nav_df.index[-1:] # series with 1 last value t_interval_end = nav_df.index[0] n_intervals_without_data = 0 part = 0 nav_df = nav_df.tz_convert('utc', copy=False) Tprev = nav_df.index[0].to_pydatetime() Tcur = Tprev if not cfg_proc.get('period_tracks'): gpx_track = gpx_track_create(gpx, gpx_obj_namef) for t_interval_start in t_intervals_start: t_interval = slice(t_interval_end, t_interval_start) # from previous last # USEtime = [[t_interval_end.isoformat(), t_interval_start.isoformat()]] nav_df_cur = nav_df.truncate(t_interval_end, t_interval_start, copy=True) t_interval_end = t_interval_start # load_interval if not len(nav_df_cur): print('empty interval') n_intervals_without_data += 1 if n_intervals_without_data > 30: print('30 intervals without data => think it is the end') break continue gpx_segment = GPXTrackSegment() if cfg_proc.get('period_tracks'): fmt = '%y-%m-%d' if t_interval_start.second==0 and t_interval_start.hour==0 else '%y-%m-%d %H:%M' track_name = f'{gpx_obj_namef} {t_interval_start:{fmt}}' gpx_track = gpx_track_create(gpx, track_name) gpx_track[track_name].segments.append(gpx_segment) else: gpx_track[gpx_obj_namef].segments.append(gpx_segment) for i, r in enumerate(nav_df_cur.itertuples()): Tcur = r.Index.to_pydatetime() gpx_point = GPXTrackPoint( latitude=r.Lat, longitude=r.Lon, elevation=r.DepEcho if b_have_depth and not np.isnan(r.DepEcho) else None, time=Tcur) # , speed= speed_b, comment= Comment gpx_segment.points.append(gpx_point) # if i==1: # gpx.description= gpx_obj_namef # gpx.author_email= '*****@*****.**' # gpxxml= gpx.to_xml() # tree = ET.parse(gpxxml) # root = tree.getroot() if cfg_proc.get('simplify_tracks_error_m'): try: gpx_segment.points = gpxpy_simplify_polyline(gpx_segment.points, cfg_proc['simplify_tracks_error_m']) except RecursionError as e: recursion_limit = sys.getrecursionlimit() l.error('Check time in data! Why increasing old recursion limit (%s) is needed? Trying: x10...', recursion_limit) try: sys.setrecursionlimit(recursion_limit * 10) gpx_segment.points = gpxpy_simplify_polyline(gpx_segment.points, cfg_proc['simplify_tracks_error_m']) l.warning('now track simplified successfuly') except Exception as e: l.exception('not succes. skip simplifying tracks', recursion_limit) if cfg_proc['dt_per_file'] and Tcur - Tprev > cfg_proc['dt_per_file']: # save to next file part += 1 if fileOutPN: gpx_proc_and_save(gpx, gpx_obj_namef, cfg_proc, f'{fileOutPN}part{part}') gpx_track = gpx_track_create(gpx, gpx_obj_namef) Tprev = Tcur if fileOutPN: gpx_proc_and_save(gpx, gpx_obj_namef, cfg_proc, fileOutPN) return gpx
from gpxpy.gpx import GPX, GPXTrack, GPXTrackSegment, GPXTrackPoint from pandas import read_csv, to_datetime basename = '2018-06-07' df = read_csv('{0}.csv'.format(basename)) df['timestamp']= to_datetime(df.time) gpx_obj = GPX() gpx_track = GPXTrack() gpx_obj.tracks.append(gpx_track) gpx_segment = GPXTrackSegment() gpx_track.segments.append(gpx_segment) gpx_segment.points.extend( ( GPXTrackPoint( time=row.timestamp, latitude=row.latitude, longitude=row.longitude ) for row in df.itertuples() ) ) with open('{0}.gpx'.format(basename), 'w') as gpx_file: gpx_file.write(gpx_obj.to_xml())
def main(gps_log, waypoints_log): with open(gps_log) as fp: gpx = GPX() #Fill in the Waypoints and what the lawnmower saw with open(waypoints_log) as fpi: # Create track for lawnmower gpx_track = GPXTrack(name="Waypoints GPS Log") gpx.tracks.append(gpx_track) # Create segment in GPX track: gpx_segment = GPXTrackSegment() gpx_track.segments.append(gpx_segment) waypoints = [] for l in fpi: m = re.match(waypts_wpt_fmt, l) if m: waypoints.append((m.group(2), m.group(3))) m = re.match(waypts_gps_fmt, l) if m: ctime = parse_time(m.group(1)) lat = float(m.group(2)) lon = float(m.group(3)) gpx_segment.points.append( GPXTrackPoint(lat, lon, time=ctime)) waypoints = f7(waypoints) for i in range(len(waypoints)): lat, lon = float(waypoints[i][0]), float(waypoints[i][1]) gpx.waypoints.append( GPXWaypoint(lat, lon, description="P%d" % (i + 1), type="Waypoints")) # Create track of raw GPS log: gpx_track = GPXTrack(name="GPS Log") gpx.tracks.append(gpx_track) # Create segment in GPX track: gpx_segment = GPXTrackSegment() gpx_track.segments.append(gpx_segment) for l in fp: m = re.match(gps_fmt, l) if m: ctime = parse_time(m.group(1)) lat = float(m.group(2)) lon = float(m.group(3)) #'time' since last DGPS fix is group 4 hdop = float(m.group(5)) fix_quality = int(m.group(6)) num_satellites = int(m.group(7)) gpx_segment.points.append( GPXTrackPoint(lat, lon, horizontal_dilution=hdop, time=ctime)) with open("waypoints_log.gpx", "w") as fpo: print(gpx.to_xml(), file=fpo)
def main(wpt_log): with open(wpt_log) as fp: gpx = GPX() name, ext = os.path.splitext(wpt_log) # Create track for the waypoints gpx_track = GPXTrack(name="Waypoints log") gpx.tracks.append(gpx_track) # Create segment in GPX track: gpx_segment = GPXTrackSegment() gpx_track.segments.append(gpx_segment) #An empty detected object det = {} for l in fp: m = re.match(gen_fmt, l) if m: if m.group(2).startswith("Waypoint"): m2 = re.match(wpt_fmt,m.group(3)) if m2: lat = float(m2.group(1)) lon = float(m2.group(2)) alt = float(m2.group(3)) if m2.group(4): roi_lat = float(m2.group(4)) roi_lon = float(m2.group(5)) roi_alt = float(m2.group(6)) #TODO ??? wpt = GPXWaypoint(lat, lon, alt, description="W" + m.group(2)[9:], type="Waypoint") gpx.waypoints.append(wpt) elif m.group(2) == "At": m2 = re.match(gps_fmt, m.group(3)) if m2: ctime = parse_time(m.group(1)) lat = float(m2.group(1)) lon = float(m2.group(2)) alt = float(m2.group(3)) try: hdg = m2.group(4) except ValueError: hdg = None gpx_segment.points.append(GPXTrackPoint(lat,lon,alt,time=ctime,comment=hdg)) elif m.group(2).startswith("Detected"): id = m.group(3)[3:] det = {"ID" : id} elif m.group(2) == "Location": m2 = re.match(gps_fmt, m.group(3)) if m2: det["time"] = parse_time(m.group(1)) det["lat"] = float(m2.group(1)) det["lon"] = float(m2.group(2)) det["alt"] = float(m2.group(3)) try: det["hdg"] = m2.group(4) except ValueError: det["hdg"] = None elif m.group(2) == "Image": n = os.path.basename(m.group(3)) det["img"] = "pics/" + n poi = GPXWaypoint(det["lat"], det["lon"], det["alt"], time=det["time"], comment=det["hdg"], symbol=det["img"], description="POI" + det["ID"], type="Point of interest") gpx.waypoints.append(poi) print(gpx.to_xml())
def test_segment_empty(self): with self.assertRaises(AssertionError): convert_path_to_feature(GPXTrackSegment(), 1)