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 create_test_activity(cls, count: int = 1, idx: int = 0, what: str = None, status: bool = False): """creates an :class:`~gpxity.Activity`. It starts off with **test.gpx** and appends a last track point, it also changes the time stamp of the last point. This is done using **count** and **idx**: The last point is set such that looking at the tracks, they all go in a different direction clockwise, with an angle in degrees of :literal:`360 * idx / count`. Args: count: See above. Using 1 as default if not given. idx: See above. Using 0 as default if not given. what: The wanted value for the activity. Default: if count == len(:attr:`Activity.legal_what <gpxity.Activity.legal_what>`), the default value will be legal_what[idx]. Otherwise a random value will be applied. status: Public? Returns: (~gpxity.Activity): A new activity not bound to a backend """ if BasicTest.all_backend_classes is None: BasicTest.all_backend_classes = BasicTest._find_backend_classes() gpx = cls._get_gpx_from_test_file('test') movement = gpxpy.geo.LocationDelta(distance=100000, angle=360 * idx / count) last_points = gpx.tracks[-1].segments[-1].points new_point = GPXTrackPoint(latitude=last_points[-1].latitude, longitude=last_points[-1].longitude + 0.001, time=last_points[-1].time + datetime.timedelta(hours=10, seconds=idx)) new_point.move(movement) gpx.tracks[-1].segments[-1].points.append(new_point) # now set all times such that they are in order with this activity and do not overlap # with other test activities duration = new_point.time - gpx.tracks[0].segments[0].points[ 0].time + datetime.timedelta(seconds=10) for point in gpx.walk(only_points=True): point.time += duration * idx result = Activity(gpx=gpx) result.title = 'Random GPX # {}'.format(idx) result.description = 'Description to {}'.format(gpx.name) if what: result.what = what elif count == len(Activity.legal_what): result.what = Activity.legal_what[idx] else: result.what = random.choice(Activity.legal_what) result.public = status return result
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 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(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 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 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 main(in_file, out_file, forbidden_regions): in_file = pathlib.Path(in_file) out_file = pathlib.Path(out_file) forbidden_regions_parsed = [] for (p_lat, p_long, radius) in forbidden_regions: forbidden_regions_parsed.append( (GPXTrackPoint(latitude=p_lat, longitude=p_long), radius)) clean_gpx(in_file, out_file, forbidden_regions=forbidden_regions_parsed)
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 _random_points(cls, count=100, root=None): """Get some random points. Distance between two points will never exceed 200m. Returns: A list with count points """ start_time = cls._random_datetime() if root is None: root = GPXTrackPoint(latitude=random.uniform(-90.0, 90.0), longitude=random.uniform(-180.0, 180.0), elevation=0, time=start_time) result = [root] angle = 50 for _ in range(1, count): angle = angle + random.uniform(-20, 20) delta = LocationDelta(distance=random.randrange(200), angle=angle) point = GPXTrackPoint(latitude=result[-1].latitude, longitude=result[-1].longitude) point.move(delta) point.elevation = _ point.time = start_time + datetime.timedelta(seconds=10 * _) result.append(point) return result
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 generate_segements_sim(config, session, Segments, Routes, segment_ids, route_ids, matrix): map_options = config['map_options'] ref_routes = np.unique(route_ids) ref_files = { i: session.query(Routes.path).filter(Routes.id == int(i)).first().path for i in ref_routes } if config['apply']['aggregation'].lower().strip() == 'mean': aggregation_func = np.mean elif config['apply']['aggregation'].lower().strip() == 'median': aggregation_func = np.median elif config['apply']['aggregation'].lower().startswith('trim_mean'): _, _, percentage = config['apply']['aggregation'].partition('::') aggregation_func = functools.partial(trim_mean, proportiontocut=float(percentage)) else: raise ValueError( f"{config['apply']['aggregation']} is not a valid aggregation function!" ) mean_dist = np.empty(len(ref_routes), dtype=float) for i, idx_i in enumerate(ref_routes): mask_i = route_ids == idx_i dist_ij = matrix[:, mask_i] min_dist = np.min(dist_ij, axis=1) mean_dist[i] = aggregation_func(min_dist) mean_dist[mean_dist < 0.006] = np.inf idx_min = np.argmin(mean_dist) path_most_sim = ref_files[ref_routes[idx_min]] route_entry = session.query(Routes).filter( Routes.path == path_most_sim).first() route_mask = route_ids == ref_routes[idx_min] matrix_sim = matrix[:, route_mask] segments = [] for idx in segment_ids[route_mask]: segment = session.query(Segments).filter( Segments.id == int(idx)).first() mm = geotiler.Map(extent=(segment.p_0_long, segment.p_0_lat, segment.p_1_long, segment.p_1_lat), zoom=map_options['zoom']) mm = geotiler.Map(center=mm.center, zoom=map_options['zoom'], size=(map_options['width'], map_options['width'])) segments.append({ 'point': GPXTrackPoint(latitude=mm.center[1], longitude=mm.center[0]), 'origin': route_entry.path }) return segments, matrix_sim, route_entry.gpx_file
def generate_img_sim_global(config, session, Segments, matrix, segment_ids, embedding_model, render_map): map_options = config['map_options'] idx = np.argmin(matrix, axis=1) min_values = np.min(matrix, axis=1) segment_idx = segment_ids[idx] segments = [] images = [] entries = [] batch_size = config.get('apply').get('batch_size', 16) for (idx, value) in zip(segment_idx, min_values): entry = session.query(Segments).filter(Segments.id == int(idx)).first() entry = row2dict(entry) mm = geotiler.Map(extent=(entry['p_0_long'], entry['p_0_lat'], entry['p_1_long'], entry['p_1_lat']), zoom=map_options['zoom']) mm = geotiler.Map(center=mm.center, zoom=map_options['zoom'], size=(map_options['width'], map_options['width'])) entry['point'] = GPXTrackPoint(latitude=mm.center[1], longitude=mm.center[0]) entry['image_raw'] = render_map(mm).convert('RGB') entry['image_encoded'] = tf.reshape( tf.convert_to_tensor(bytes2array(entry['image']), dtype=tf.float32), map_options['encoding_shape']) entry[ 'image_for_reconstruction'] = tf.keras.preprocessing.image.img_to_array( entry['image_raw']) / 255. entry['dist'] = value del entry['image'] entries.append(entry) images.append(entry['image_for_reconstruction']) if len(images) == batch_size: reconstructed_images, *_ = apply_model(embedding_model, images, batch_size, fill_up=False) for img_decoded, entry in zip(reconstructed_images, entries): entry['image_decoded'] = img_decoded.numpy() segments.append(entry) images, entries = [], [] if len(entries) > 0: reconstructed_images, *_ = apply_model(embedding_model, images, batch_size, fill_up=True) for img_decoded, entry in zip(reconstructed_images, entries): entry['image_decoded'] = img_decoded.numpy() segments.append(entry) return segments
def get_points_simplified(raw_points, max_distance=5, zoom=16, size=(512, 512)): if max_distance is not None: points = simplify_polyline(raw_points, max_distance=max_distance) else: points = raw_points df = df_from_points(points) f_lat, f_long = interp1d(df.distance_total, df.latitude), interp1d(df.distance_total, df.longitude) mm_zero = geotiler.Map(center=(points[0].longitude, points[0].latitude), zoom=zoom, size=size) p_0_long, p_0_lat, p_1_long, p_1_lat = mm_zero.extent distance = GPXTrackPoint(latitude=p_0_lat, longitude=p_1_long).distance_2d( GPXTrackPoint(latitude=p_1_lat, longitude=p_0_long)) steps = np.arange(df.distance_total.values[0], df.distance_total.values[-1], distance / (2. * 1.41421356237)) for d in steps: yield f_long(d), f_lat(d)
def __points(self, raw): """convert raw data back into list(GPXTrackPoint)""" values = raw.split() if len(values) % 4: self.return_error(401, 'Point elements not a multiple of 4') raise TypeError result = list() for idx in range(0, len(values), 4): point = GPXTrackPoint( latitude=float(values[idx]), longitude=float(values[idx+1]), elevation=float(values[idx+2]), time=datetime.datetime.utcfromtimestamp(float(values[idx+3]))) result.append(point) return result
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 some_random_points(cls, count=100): """ Returns: A list with count points """ result = list() start_time = cls._random_datetime() for _ in range(count): point = GPXTrackPoint(latitude=random.uniform(0.0, 90.0), longitude=random.uniform(0.0, 180.0), elevation=_, time=start_time + datetime.timedelta(seconds=10 * _)) result.append(point) return result
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 to_gpx_trackpoint(self): waypoint = GPXTrackPoint(self.gps_latitude(), self.gps_longitude()) waypoint.name = self.title() waypoint.description = self.description() waypoint.comment = self.description() waypoint.symbol = "wpt_46" if self.elevation() is not None: waypoint.elevation = self.elevation() return waypoint
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 __init__(self, places, gpxfiles): """See class docstring.""" self.places = places self.gpxfiles = gpxfiles self.locations = list() for place in places: _ = geocoder.get(place, provider='osm') if not _: raise Exception('Place not found: {}'.format(place)) self.locations.append(_[0]) logging.info('using locations:') for _ in self.locations: logging.info(' %s', _.address) self.distances = list() gpx_points = [ GPXTrackPoint(latitude=x.lat, longitude=x.lng) for x in self.locations ] for gpxfile in gpxfiles: self.distances.append((gpxfile, [ gpxfile.gpx.get_nearest_location(x).location.distance_2d(x) for x in gpx_points ])) self.distances.sort(key=lambda x: sum(x[1]))
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 create_test_track(cls, backend_class=None, count: int = 1, idx: int = 0, category: str = None, public: bool = False, start_time=None, end_time=None): """create a :class:`~gpxity.gpxfile.GpxFile`. It starts off with **test.gpx** and appends a last gpxfile point, it also changes the time stamp of the last point. This is done using **count** and **idx**: The last point is set such that looking at the gpxfiles, they all go in a different direction clockwise, with an angle in degrees of :literal:`360 * idx / count`. Args: backend_class: If given, use it as source for a random category count: See above. Using 1 as default if not given. idx: See above. Using 0 as default if not given. category: The wanted value for the gpxfile. Default: if count == len(:attr:`GpxFile.categories <gpxity.gpxfile.GpxFile.categories>`), the default value will be backend_class.supported_categories[idx]. Otherwise a random value from backend_class.supported_categories will be applied. public: should the gpxfiles be public or private? start_time: If given, assign it to the first point and adjust all following times end_time: explicit time for the last point. If None: See above. Returns: (~gpxity.gpxfile.GpxFile): A new gpxfile not bound to a backend """ # pylint: disable=too-many-locals result = cls._get_track_from_test_file('test') if start_time is not None: if not start_time.tzinfo: start_time = start_time.replace(tzinfo=datetime.timezone.utc) result.adjust_time(start_time - result.first_time) last_point = result.last_point() if end_time is None: end_time = last_point.time + datetime.timedelta(hours=10, seconds=idx) if not end_time.tzinfo: end_time = end_time.replace(tzinfo=datetime.timezone.utc) new_point = GPXTrackPoint(latitude=last_point.latitude, longitude=last_point.longitude + 0.001, time=end_time) _ = gpxpy.geo.LocationDelta(distance=1000, angle=360 * idx / count) new_point.move(_) result.add_points([new_point]) # now set all times such that they are in order with this gpxfile and do not overlap # with other test gpxfiles _ = result.first_time duration = new_point.time - _ + datetime.timedelta(seconds=10) for point in result.gpx.walk(only_points=True): point.time += duration * idx result.title = 'Random GPX # {}'.format(idx) result.description = 'Description to {}'.format(result.title) if backend_class is None: cat_source = GpxFile.categories else: cat_source = backend_class.supported_categories cat_source = [backend_class.decode_category(x) for x in cat_source] if category: result.category = category elif count == len(GpxFile.categories): result.category = cat_source[idx] else: result.category = random.choice(cat_source) result.public = public return result
def apply_model_to_file(config, gpx_file, ref_database, checkpoint): gpx_file = pathlib.Path(gpx_file) click.echo(f'Loading model from: {checkpoint}!') embedding_model = tf.keras.models.load_model(checkpoint) client = redis.Redis(**config['redis']) downloader = redis_downloader(client) render_map = functools.partial(geotiler.render_map, downloader=downloader) batch_size = config.get('apply').get('batch_size', 16) map_options = config['map_options'] map_options['size'] = (map_options['width'], map_options['height']) click.echo(f'Generating segment images for the test gpx: {gpx_file}...') try: gpx = gpxpy.parse(gpx_file.open()) except gpxpy.gpx.GPXXMLSyntaxException: click.echo(f'{gpx_file} is not a valid GPX file!') return segments = [] for track_idx, track in enumerate(gpx.tracks): for segment_idx, segment in enumerate(track.segments): images, entries = [], [] for img, info in generate_images_for_segment( segment=segment, size=map_options['size'], zoom=map_options['zoom'], max_distance=map_options['smoothing_dist'], render_map=render_map, show_route=map_options['show_route']): entry = { 'origin': gpx_file, 'track_idx': track_idx, 'segment_idx': segment_idx, 'image_raw': img } entry = {**entry, **info} mm = geotiler.Map(extent=(info['p_0_long'], info['p_0_lat'], info['p_1_long'], info['p_1_lat']), zoom=map_options['zoom']) entry['point'] = GPXTrackPoint(latitude=mm.center[1], longitude=mm.center[0]) img_embedding = tf.keras.preprocessing.image.img_to_array( img) / 255. images.append(img_embedding) entries.append(entry) if len(images) == batch_size: reconstructed_images, mu, log_var = apply_model( embedding_model, images, batch_size, fill_up=False) images = [ np.array((mu_i, log_var_i)) for mu_i, log_var_i in zip(log_var, mu) ] for i, (img_encoded, img_decoded, entry) in enumerate( zip(images, reconstructed_images, entries)): if i == 0: map_options['encoding_shape'] = img_encoded.shape entry['image_encoded'] = img_encoded entry['image_decoded'] = img_decoded.numpy() segments.append(entry) images, entries = [], [] if len(entries) > 0: reconstructed_images, mu, log_var = apply_model( embedding_model, images, batch_size, fill_up=False) images = [ np.array((mu_i, log_var_i)) for mu_i, log_var_i in zip(log_var, mu) ] for img_encoded, img_decoded, entry in zip( images, reconstructed_images, entries): entry['image_encoded'] = img_encoded entry['image_decoded'] = img_decoded.numpy() segments.append(entry) test_images = np.asarray([entry['image_encoded'] for entry in segments]) click.echo(f'Loading date from reference database: {ref_database}...') engine, Routes, Segments = get_engine_and_model(ref_database, train=False) Session = sessionmaker(bind=engine) session = Session() images = [] route_ids = [] segment_ids = [] for seg in session.query(Segments.image, Segments.origin, Segments.id): images.append( bytes2array(seg.image).reshape(map_options['encoding_shape'])) route_ids.append(seg.origin) segment_ids.append(seg.id) images = np.asarray(images) route_ids = np.asarray(route_ids) segment_ids = np.asarray(segment_ids) click.echo(f'Calculating Bhattacharyya distance...') def bhattacharyya_distance(vec_a, vec_b): mu_a, var_a = vec_a[:len(vec_a) // 2], np.exp(vec_a[len(vec_a) // 2:]) mu_b, var_b = vec_b[:len(vec_b) // 2], np.exp(vec_b[len(vec_b) // 2:]) result = 0.25 * np.log(0.25 * (var_a / var_b + var_b / var_a + 2)) + 0.25 * ( (mu_a - mu_b)**2 / (var_a + var_b)) return np.mean(result) test_images_reshaped = test_images.reshape( test_images.shape[0], test_images.shape[1] * test_images.shape[2]) images_reshaped = images.reshape(images.shape[0], images.shape[1] * images.shape[2]) matrix = cdist(test_images_reshaped, images_reshaped, metric=bhattacharyya_distance) click.echo( f'Determine best matching route via aggregation of segments with `{config["apply"]["aggregation"]}`...' ) segments_sim, matrix_sim, compressed_gpx_file = generate_segements_sim( config, session, Segments, Routes, segment_ids, route_ids, matrix) click.echo(f'Preparing images of similar segments...') segments_sim_global = generate_img_sim_global(config, session, Segments, matrix, segment_ids, embedding_model, render_map) fig_test = create_plotly_fig_with_line(config, gpx) fig_sim = create_plotly_fig_with_line( config, gpxpy.parse(decompress_gpx(compressed_gpx_file))) session.close() return fig_test, fig_sim, segments, segments_sim, segments_sim_global, matrix_sim
def mkpt(s: str): t = s.split(sep=' ', maxsplit=1) return GPXTrackPoint(float(t[0]), float(t[1]))
def chk_waypoints_insert_inplace(gp2: GPX, wpname: str, /, want_dist_m=WANT_DIST_M_DEFAULT): @dataclass class D(): vec: vec_t idx: int tra_idx: int def wf(pos: Pos, vec: vec_t): return D(vec, pos.idx, pos.tra_idx) chk_: list[D] = chk_waypoints(gp2, want_dist_m=want_dist_m, way_fact=wf) chk = sorted(chk_, key=lambda x: (x.tra_idx, x.idx,), reverse=True) for d in chk: tra = gp2.tracks[d.tra_idx] seg = tra_seg(tra) seg.points.insert(d.idx + 1, GPXTrackPoint(d.vec[0], d.vec[1], name=wpname)) def pnt_filter_closer_than(a: List[wpt_t], cmp: List[wpt_t], len_): return [x for x in a if not any([x.distance_2d(y) < len_ for y in cmp])] def csv_waypoints(p: Path, t='trasa', sym=SYM_CIRCLE): with open(p, encoding='UTF-8') as f: return [GPXWaypoint(latitude=float(r['latitude']), longitude=float(r['longitude']), name=r['name'], symbol=sym, type=t) for r in DictReader(f)] if __name__ == '__main__': assert mkpt('46.5017784 15.5537548').latitude == GPXTrackPoint(46.5017784, 15.5537548).latitude and \ mkpt('46.5017784 15.5537548').longitude == GPXTrackPoint(46.5017784, 15.5537548).longitude import sys print(sys.argv) ta = GPXTrackPoint(46.533183, 15.628635)
def to_gpx_trackpoint(self): gps = self.geocoder.convert(self.address) trackpoint = GPXTrackPoint(gps['lat'], gps['lng']) trackpoint.name = self.name return trackpoint
def csv_line_to_gpx(csv_line): attrs = csv_line.split(',') lat, lng = stateplane_to_latlon(float(attrs[1]), float(attrs[2])) trackpoint = GPXTrackPoint(lat, lng) trackpoint.name = 'Tree ' + str(floor(float(attrs[4]))) + '"' return trackpoint
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
def eform_pre(gp2: GPX, kwp: list[wpt_t], want_dist_m=WANT_DIST_M_DEFAULT): chk_waypoints_insert_inplace(gp2, 'dummy_breaker', want_dist_m=want_dist_m) for k in kwp: gpx_insert_lseg_closest_inplace( gp2, GPXTrackPoint(k.latitude, k.longitude, name='dummy_koca'))
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 setUp(self): self.point_as_array = np.array([1., 2., 3.]) self.point = GPXTrackPoint(longitude=1., latitude=2., elevation=3.) self.attributes_to_test = ['longitude', 'latitude', 'elevation']
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)