def splitAR(track, pt1, pt2=None, radius=10, nb_min_pts=10, verbose=True): if pt2 is None: pt2 = pt1 tracks = TrackCollection() subtrack = Track() k = -1 while k < len(track) - 1: k = k + 1 if (min(track[k].position.distance2DTo(pt1), track[k].position.distance2DTo(pt2)) < radius): if len(subtrack) > nb_min_pts: tracks.addTrack(subtrack) if verbose: print( "Add sub-track: ", subtrack[0].timestamp, subtrack[-1].timestamp, "[" + str(len(tracks)) + "]", ) subtrack = Track() subtrack.addObs(track[k].copy()) if len(subtrack) > nb_min_pts: tracks.addTrack(subtrack) if verbose: print( "Add sub-track: ", subtrack[0].timestamp, subtrack[-1].timestamp, "[" + str(len(tracks)) + "]", ) return tracks
def example3(): Stochastics.seed(1) # Reading network from text data file network = NetworkReader.readFromFile( 'tracklib/data/network/network_ecrin_extrait.csv', 'TEST2') # Cartographic Conversion network.toGeoCoords(2154) # Get distance between pairs of nodes tracks = TrackCollection() for i in range(10): node1 = network.getRandomNode() node2 = network.getRandomNode() track = network.shortest_path(node1, node2) if not track is None: tracks.addTrack(track) print(node1, node2, track.size(), track.length()) # Export KmlWriter.writeToKml(network, path='network.kml', c1=[1, 1, 1, 1]) # white network KmlWriter.writeToKml(tracks, path='tracks.kml', c1=[1, 0, 0, 1]) # red paths
def splitReturnTripFast(track, side_effect=0.1, sampling=1): """Split track when there is a return trip to keep only the first part. Second version with Fast Fourier Transform""" track = track.copy() track.toENUCoords(track.getFirstObs().position) track_test = track.copy() track_test.resample((track_test.length() / track_test.size()) / sampling, ALGO_LINEAR, MODE_SPATIAL) H = np.fft.fft(track_test.getY()) G = np.fft.fft(track_test.getY()[::-1]) temp = np.flip(np.abs(np.fft.ifft(H * np.conj(G)))) id = np.argmax(temp[int(side_effect * len(temp)):int((1 - side_effect) * len(temp))]) pt = track_test[id].position dmin = 1e300 argmin = 0 for i in range(track.size()): d = track[i].position.distance2DTo(pt) if d < dmin: dmin = d argmin = i first_part = track.extract(0, argmin - 1) second_part = track.extract(argmin, track.size() - 1) TRACKS = TrackCollection() TRACKS.addTrack(first_part) TRACKS.addTrack(second_part) return TRACKS
def splitReturnTripExhaustive(track): """Split track when there is a return trip to keep only the first part""" min_val = 1e300 argmin = 0 AVG = Operator.Operator.AVERAGER for return_point in progressbar.progressbar(range(1, track.size() - 1)): T1 = track.extract(0, return_point) T2 = track.extract(return_point, track.size() - 1) avg = (T1 - T2).operate(AVG, "diff") + (T2 - T1).operate(AVG, "diff") if avg < min_val: min_val = avg argmin = return_point first_part = track.extract(0, argmin - 1) second_part = track.extract(argmin, track.size() - 1) TRACKS = TrackCollection() TRACKS.addTrack(first_part) TRACKS.addTrack(second_part) return TRACKS
def getAllEdgeGeoms(self) -> TrackCollection: """Return a TrackCollection of all edges :return: All edges of :class:`Network` """ tracks = TrackCollection() for id in self.__idx_edges: tracks.addTrack(self.EDGES[id].geom) return tracks
def select(self, tracks): """TODO""" if self.type == TYPE_SELECT: output = TrackCollection() for track in tracks: if self.contains(track): output.addTrack(track) return output if self.type == TYPE_CUT_AND_SELECT: return tracks
def writeToGpx(tracks, path, af=False): """ Transforms track into Gpx string # path: file to write gpx (gpx returned in standard output if empty) af: AF exported in gpx file """ f = open(path, "w") # Time output management fmt_save = GPSTime.getPrintFormat() GPSTime.setPrintFormat("4Y-2M-2DT2h:2m:2s") if isinstance(tracks, Track): collection = TrackCollection() collection.addTrack(tracks) tracks = collection f.write('<?xml version="1.0" encoding="UTF-8"?>\n') f.write("<gpx>\n") f.write( "<author>File generated by Tracklib: https://github.com/umrlastig/tracklib</author>\n" ) for i in range(len(tracks)): track = tracks.getTrack(i) f.write(" <trk>\n") f.write(" <trkseg>\n") for i in range(len(track)): x = "{:3.8f}".format(track[i].position.getX()) y = "{:3.8f}".format(track[i].position.getY()) z = "{:3.8f}".format(track[i].position.getZ()) f.write(' <trkpt lat="' + y + '" lon="' + x + '">\n') f.write(" <ele>" + z + "</ele>\n") f.write(" <time>" + str(track[i].timestamp) + track[i].timestamp.printZone() + "</time>\n") if af: f.write(" <extensions>\n") for af_name in track.getListAnalyticalFeatures(): f.write(" <" + af_name + ">") f.write(str(track.getObsAnalyticalFeature(af_name, i))) f.write("</" + af_name + ">\n") f.write(" </extensions>\n") f.write(" </trkpt>\n") f.write(" </trkseg>\n") f.write(" </trk>\n") f.write("</gpx>\n") f.close() GPSTime.setPrintFormat(fmt_save)
def readFromGpx(path, srid="GEO"): """ Reads (multiple) tracks in .gpx file """ tracks = TrackCollection() format_old = GPSTime.getReadFormat() GPSTime.setReadFormat("4Y-2M-2D 2h:2m:2s") doc = minidom.parse(path) trks = doc.getElementsByTagName("trk") for trk in trks: trace = t.Track() trkpts = trk.getElementsByTagName("trkpt") for trkpt in trkpts: lon = float(trkpt.attributes["lon"].value) lat = float(trkpt.attributes["lat"].value) hgt = utils.NAN eles = trkpt.getElementsByTagName("ele") if eles.length > 0: hgt = float(eles[0].firstChild.data) time = "" times = trkpt.getElementsByTagName("time") if times.length > 0: time = GPSTime(times[0].firstChild.data) else: time = GPSTime() point = Obs(utils.makeCoords(lon, lat, hgt, srid), time) trace.addObs(point) tracks.addTrack(trace) # pourquoi ? # --> pour remettre le format comme il etait avant la lectre :) GPSTime.setReadFormat(format_old) collection = TrackCollection(tracks) return collection
def noise(self, track, N=1, mode='linear', force=False): """TODO""" if N == 1: return noise(track, self.amplitudes, self.kernels, self.distribution, mode=mode, force=force) else: collection = TrackCollection() for i in range(N): collection.addTrack( noise(track, self.amplitudes, self.kernels, self.distribution, mode=mode, force=force)) return collection
def split(track, source) -> TrackCollection: """Splits track according to : - af name (considered as a marker) if `source` is a string - list of index if `source` is a list :return: No track if no segmentation, otherwise a TrackCollection object """ NEW_TRACES = TrackCollection() # -------------------------------------------- # Split from analytical feature name # -------------------------------------------- if isinstance(source, str): count = 0 # Initialisation du compteur des étapes begin = 0 # indice du premier point de l'étape for i in range(track.size()): if track.getObsAnalyticalFeature(source, i) == 1: # Nouvelle trajectoire # L'identifiant de la trace subdivisée est obtenue par concaténation # de l'identifiant de la trace initiale et du compteur new_id = str(track.uid) + "." + str(count) # La liste de points correspondant à l'intervalle de subdivision est créée new_traj = track.extract(begin, i) new_traj.setUid(new_id) NEW_TRACES.addTrack(new_traj) count += 1 begin = i + 1 # Si tous les points sont dans la même classe, la liste d'étapes reste vide # sinon, on clôt la derniere étape et on l'ajoute à la liste if begin != 0: new_id = str(track.uid) + "." + str(count) new_traj = track.extract(begin, track.size() - 1) new_traj.setUid(new_id) NEW_TRACES.addTrack(new_traj) # -------------------------------------------- # Split from list of indices # -------------------------------------------- if isinstance(source, list): for i in range(len(source) - 1): NEW_TRACES.addTrack(track.extract(source[i], source[i + 1])) return NEW_TRACES