def test_positions_on_track(self): gpx = mod_gpx.GPX() track = mod_gpx.GPXTrack() gpx.tracks.append(track) segment = mod_gpx.GPXTrackSegment() track.segments.append(segment) location_to_find_on_track = None for i in range(1000): latitude = 45 + i * 0.001 longitude = 45 + i * 0.001 elevation = 100 + i * 2 point = mod_gpx.GPXTrackPoint(latitude=latitude, longitude=longitude, elevation=elevation) segment.points.append(point) if i == 500: location_to_find_on_track = mod_gpx.GPXWaypoint( latitude=latitude, longitude=longitude) result = gpx.get_nearest_locations(location_to_find_on_track) self.assertTrue(len(result) == 1)
def to_gpx(self): wp = gpx.GPXWaypoint(latitude=self.coordinates[0], longitude=self.coordinates[1], elevation=self.height, name=self.id, description=u'хр. ' + self.ridge) return wp
def getMP_GPX(self, mp_URL_email): pos = 0 gpxinstance = gpx.GPX() mp_todos = self.getToDos(mp_URL_email, pos) #requery the API if we've reached 200 and there's still something returned while (len(mp_todos['toDos']) > 0): if (pos > 0): #requery the API to get next 200 batch mp_todos = self.getToDos(mp_URL_email, pos) #get routes returns an array of integer route ids, make a string to pass to MP route_ids = ','.join(str(todo) for todo in mp_todos['toDos']) if len(route_ids) > 0: mp_routes = self.getRoutes(mp_URL_email, route_ids) for route in mp_routes['routes']: pos += 1 gpxinstance.waypoints.append( gpx.GPXWaypoint(Decimal(str(route['latitude'])), Decimal(str(route['longitude'])), name=route['name'] + ' - ' + route['rating'], description=route['url'])) return gpxinstance.to_xml()
def getMP_GPX_location(self, lat, lng, maxDistance, minDiff, maxDiff): gpxinstance = gpx.GPX() mp_routes = self.getRoutesForLatLong(lat, lng, maxDistance, minDiff, maxDiff) for route in mp_routes['routes']: gpxinstance.waypoints.append( gpx.GPXWaypoint(Decimal(str(route['latitude'])), Decimal(str(route['longitude'])), name=route['name'] + ' - ' + route['rating'], description=route['url'])) return gpxinstance.to_xml()
def export(self): if self.rows: # create a new gpx file gpx_data = gpx.GPX() # exclude rows with no centroid data (polylines at present) to_gpx = (rw for rw in self.rows if rw.centroid_x is not None) # add the centroids into the file for pt in to_gpx: gpx_data.waypoints.append( gpx.GPXWaypoint(name=pt.location, longitude=pt.centroid_x, latitude=pt.centroid_y)) return gpx_data.to_xml() else: return ''
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.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 = GPX.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 = GPX.GPXTrackSegment() if cfg_proc.get('period_tracks'): track_name = f'{gpx_obj_namef}{t_interval_start:%y-%m-%d %H:%M}' 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 = GPX.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
mp_profile = getMP_API(profile_url) print('Getting MP ToDo List for', mp_profile['name']) todos_url = getMP_URL(mp_URL_base, 'get-to-dos', mp_URL_email, mp_private_key) mp_todos = getMP_API(todos_url) #get routes returns an array of integer route Ids, make a string to pass to MP route_ids = ','.join(str(todo) for todo in mp_todos['toDos']) if len(route_ids) > 0: #return routes routes_url = getMP_URL(mp_URL_base, 'get-routes', mp_URL_email, mp_private_key) routes_url = str.format("{0}&routeIds={1}", routes_url, route_ids) mp_routes = json_str = getMP_API(routes_url) gpxinstance = gpx.GPX() for route in mp_routes['routes']: gpxinstance.waypoints.append( gpx.GPXWaypoint(Decimal(str(route['latitude'])), Decimal(str(route['longitude'])), name=route['name'] + ' - ' + route['rating'], description=route['url'])) #write to file fo = open(r"todos.gpx", "w+") fo.write(gpxinstance.to_xml()) print('Success: Created GPX File: todos.gpx')