Beispiel #1
0
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
Beispiel #2
0
    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
Beispiel #3
0
 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
Beispiel #4
0
    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)
Beispiel #5
0
 def test_create_index(self):
     
     GPSTime.setReadFormat("4Y-2M-2D 2h:2m:2s")
     
     track = Track()
     p1 = Obs(ENUCoords(550, 320), GPSTime.readTimestamp('2020-01-01 10:00:00'))
     track.addObs(p1)
     p2 = Obs(ENUCoords(610, 325), GPSTime.readTimestamp('2020-01-01 10:08:00'))
     track.addObs(p2)
     p3 = Obs(ENUCoords(610, 330), GPSTime.readTimestamp('2020-01-01 10:17:00'))
     track.addObs(p3)
     p4 = Obs(ENUCoords(650, 330), GPSTime.readTimestamp('2020-01-01 10:21:00'))
     track.addObs(p4)
     p5 = Obs(ENUCoords(675, 340), GPSTime.readTimestamp('2020-01-01 10:25:00'))
     track.addObs(p5)
     #track.plot()
     #track.plotAsMarkers()
     
     TRACES = []
     TRACES.append(track)
     collection = TrackCollection(TRACES)
     
     res = (25, 4)
     index = SpatialIndex(collection, res, 0.05, True)
     index.plot()
     
     
     # =====================================================================
     self.assertEqual(index.request(0, 0), [0])
     self.assertEqual(index.request(1, 0), [0])
     self.assertEqual(index.request(0, 1), [])
     self.assertEqual(index.request(1, 1), [0])
     self.assertEqual(index.request(2, 0), [])
     self.assertEqual(index.request(2, 1), [0])
Beispiel #6
0
def centralTrack(tracks: Union[TrackCollection, Iterable[Track]], mode: Literal["NN", "DTW", "FDTW"] = "NN", verbose: bool = True) -> Track:   
    """Computes central track of a track collection

    :param tracks: TrackCollection or list of tracks
    :param mode: "NN", "DTW" or "FDTW" for track pair matching (see the documentation
                  of :func:`differenceProfile` function for more infos on modes)
    :return: The central track
    """

    tracks = tracks.copy()

    if isinstance(tracks, list):
        tracks = TrackCollection(tracks)
    base = tracks.toENUCoordsIfNeeded()
    central = tracks[0].copy()

    for i in range(1, len(tracks)):
        diff = differenceProfile(tracks[0], tracks[i], mode=mode, verbose=verbose)

        for j in range(len(central)):
            dx = tracks[i][diff["pair", j]].position.getX()
            dy = tracks[i][diff["pair", j]].position.getY()
            dz = tracks[i][diff["pair", j]].position.getZ()
            central[j].position.translate(dx, dy, dz)

    for j in range(len(central)):
        central[j].position.scale(1.0 / len(tracks))

    if not base is None:
        central.toGeoCoords(base)

    return central
Beispiel #7
0
def mapOnNetwork(
    tracks, network, gps_noise=50, transition_cost=10, search_radius=50, debug=False
):
    """TODO"""
    if isinstance(tracks, Track):
        tracks = TrackCollection([tracks])
    for track in tracks:
        __mapOnNetwork(track, network, gps_noise, transition_cost, search_radius, debug)
Beispiel #8
0
    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
Beispiel #9
0
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
Beispiel #10
0
 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
Beispiel #11
0
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
Beispiel #12
0
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
Beispiel #13
0
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
Beispiel #14
0
 def test_create_index_collection2(self):
     
     GPSTime.setReadFormat("4Y-2M-2D 2h:2m:2s")
             
     track = Track()
     p1 = Obs(ENUCoords(0, 0), GPSTime.readTimestamp('2020-01-01 10:00:00'))
     track.addObs(p1)
     p2 = Obs(ENUCoords(3.1, 3), GPSTime.readTimestamp('2020-01-01 10:08:00'))
     track.addObs(p2)
     p3 = Obs(ENUCoords(3.1, 4.5), GPSTime.readTimestamp('2020-01-01 10:17:00'))
     track.addObs(p3)
     
     p4 = Obs(ENUCoords(4.5, 4.5), GPSTime.readTimestamp('2020-01-01 10:21:00'))
     track.addObs(p4)
     p5 = Obs(ENUCoords(6, 5.5), GPSTime.readTimestamp('2020-01-01 10:21:00'))
     track.addObs(p5)
     
     p6 = Obs(ENUCoords(7, 4.5), GPSTime.readTimestamp('2020-01-01 10:21:00'))
     track.addObs(p6)
     p7 = Obs(ENUCoords(11, 5.5), GPSTime.readTimestamp('2020-01-01 10:21:00'))
     track.addObs(p7)
     p8 = Obs(ENUCoords(13, 10), GPSTime.readTimestamp('2020-01-01 10:25:00'))
     track.addObs(p8)
             #track.plot()
             #track.plotAsMarkers()
             
     TRACES = []
     TRACES.append(track)
     collection = TrackCollection(TRACES)
             
     index = SpatialIndex(collection, (2, 2))
     index.plot()
     
     # =====================================================================
     # =====================================================================
     self.assertEqual(index.request(0, 0), [0])
     self.assertEqual(index.request(1, 0), [0])
     self.assertEqual(index.request(0, 1), [])
     self.assertEqual(index.request(1, 1), [0])
     self.assertEqual(index.request(2, 0), [])
     self.assertEqual(index.request(2, 1), [])
     self.assertEqual(index.request(1, 2), [0])
     self.assertEqual(index.request(2, 2), [0])
     self.assertEqual(index.request(3, 2), [0])
     self.assertEqual(index.request(3, 3), [])
     self.assertEqual(index.request(4, 2), [0])
     self.assertEqual(index.request(4, 3), [])
     self.assertEqual(index.request(4, 4), [])
     self.assertEqual(index.request(5, 2), [0])
     self.assertEqual(index.request(5, 3), [0])
     self.assertEqual(index.request(5, 4), [])
Beispiel #15
0
def example5():

    # -------------------------------------------------------
    # Trajectoire de reference IMU
    # -------------------------------------------------------
    path = "data/imu_opk_Vincennes1909121306.txt"
    ref = FileReader.readFromFile(path, "IMU_STEREOPOLIS")
    ref = ref < 435
    ref.incrementTime(0, 18)
    ref.translate(0, 0, 43.79)

    track = ref.copy()
    track2 = ref.copy()
    track2 = track2 // track

    track.toGeoCoords(2154)
    track.toECEFCoords()

    # Read the data file of the satellites
    satellites = "data/satellites_no_errors.txt"

    # Model 1:
    # --------
    # The state matrix Xk = (Xr, Yr, Zr)

    # Define the evolution model matrix
    # Stationery model
    A = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])

    # Define the covariance matrix of the states
    Q = np.array([[1e2, 0, 0], [0, 1e2, 0], [0, 0, 1e2]])

    # Define the measurement matrix
    def H(x, k, track):

        # Declare the number of satellites used
        NUMBER_OF_SATELLITES = 32
        NUMBER_OF_STATES = 1

        Hk = np.zeros((NUMBER_OF_SATELLITES, 1))

        for ind in range(0, NUMBER_OF_SATELLITES):

            recue = 0 + (track.getObsAnalyticalFeature("Xs" + str(ind + 1), k)
                         != 0)

            # Obtenir les positions des satellites rajouter à la trace
            Xsat = track.getObsAnalyticalFeature("Xs" + str(ind + 1), k)
            Ysat = track.getObsAnalyticalFeature("Ys" + str(ind + 1), k)
            Zsat = track.getObsAnalyticalFeature("Zs" + str(ind + 1), k)

            # Distance radiale
            Hk[ind][0] = recue * ((x[0, 0] - Xsat)**2 + (x[1, 0] - Ysat)**2 +
                                  (x[2, 0] - Zsat)**2)**0.5

        return Hk

    # Define the covariance matrix of the observation
    Rk = np.eye(32, 32)

    # Create 32 analytical variables
    for cnt in range(0, 32):
        track.createAnalyticalFeature("Xs" + str(cnt + 1), [0] * len(track))
        track.createAnalyticalFeature("Ys" + str(cnt + 1), [0] * len(track))
        track.createAnalyticalFeature("Zs" + str(cnt + 1), [0] * len(track))
        track.createAnalyticalFeature("pd" + str(cnt + 1), [0] * len(track))

    # Put the satellites coordinates as new analytics into the track
    ind = -1
    counter = 0
    with open(satellites) as fp:
        line = fp.readline()
        while (line):
            if line[0:5] == "12/09":
                ind += 1
                counter = counter + 1
                fp.readline()
                while True:
                    line = fp.readline()
                    if line[0] == "-":
                        break

                    # Handle the headers of each slot
                    tok = line.split()

                    # Set the values of the satellites at each time stamp
                    track.setObsAnalyticalFeature("Xs" + str(tok[0]), ind,
                                                  float(tok[1]))
                    track.setObsAnalyticalFeature("Ys" + str(tok[0]), ind,
                                                  float(tok[2]))
                    track.setObsAnalyticalFeature("Zs" + str(tok[0]), ind,
                                                  float(tok[3]))
                    track.setObsAnalyticalFeature("pd" + str(tok[0]), ind,
                                                  float(tok[4]))

            line = fp.readline()

    start = ECEFCoords(4201797.8382, 178416.3546, 4779221.8874)

    X0 = np.array([[start.getX()], [start.getY()], [start.getZ()]])
    P0 = 1e1 * np.eye(3, 3)

    UKF = Kalman(spreading=1)
    UKF.setTransition(A, Q)
    UKF.setObservation(H, Rk)
    UKF.setInitState(X0, P0)
    UKF.summary()

    H(X0, 0, track)
    obs = []
    for i in range(32):
        obs.append("pd" + str(i + 1))

    UKF.estimate(track, obs, mode=Dynamics.MODE_STATES_AS_3D_POSITIONS)

    track.toGeoCoords()
    KmlWriter.writeToKml(TrackCollection([ref, track]),
                         "test_no_multipath.kml")

    # ref.plot('g-')
    track.plot('r.')
    plt.show()

    time_stamps = track.getTimestamps()
    """
    # Get the error of the predictions
    for t in range(len(time_stamps)):
        for sat in range (32):
            pos_sat = ECEFCoords(track["Xs"+str(sat+1),t], track["Ys"+str(sat+1),t], track["Zs"+str(sat+1),t])

            # Create analytic error and compute it
            track.createAnalyticalFeature("error_"+str(sat+1), [0]*len(track))

            # An error of -999 represents an NLOS Satellite
            if track["pd"+str(sat+1), t] != 0:
                error = track["pd"+str(sat+1), t] - track[t].position.distanceTo(pos_sat)
            else:
                error = 0

            track.setObsAnalyticalFeature("error_"+str(sat+1), t, error)

    from PIL import Image
    
    for cnt in range(32):
        plt.plot(track["error_"+str(cnt+1)])
        plt.xlabel('Position')
        plt.ylabel('Error (m)')
        plt.title("Error of Pseudo-distance on satellite " + str(cnt+1))
        plt.savefig("Result\Error_IMU_Satellite_" + str(cnt+1))
        plt.clf()
    """

    KmlWriter.writeToKml(track, "test1.kml", type="POINT")

    track.toProjCoords(2154)

    # ----------------------------------------------
    # Calcul RMSE dans chaque direction
    # ----------------------------------------------
    track.createAnalyticalFeature("x2", track2.getX())
    track.createAnalyticalFeature("y2", track2.getY())
    track.createAnalyticalFeature("z2", track2.getZ())

    std_x = track["RMSE(x-x2)"][0]
    std_y = track["RMSE(y-y2)"][0]
    std_z = track["RMSE(z-z2)"][0]

    print("X std = " + '{:5.3f}'.format(std_x) + " m")
    print("Y std = " + '{:5.3f}'.format(std_y) + " m")
    print("Z std = " + '{:5.3f}'.format(std_z) + " m")
Beispiel #16
0
class SpatialIndex:
    """Definition of a spatial index"""

    def __init__(self, collection, resolution=None, margin=0.05, verbose=True):
        """Constructor of :class:`SaptialIndex` class

        TODO: update documentation

        Parameters
        ----------
        features : bbox() + iterable


            TrackCollection : on construit une grille
                dont l’emprise est calculée sur la fonction getBBox
                de TrackCollection et dans un deuxième temps on appelle
                addSegment([c1,c2], [i,j]) pour chaque segment [c1,c2]
                (localisé entre les points GPS i et i+1) de chaque trace j,
                de la collection.
            Network : on construit une grille (de taille 100 x 100) par défaut,
                  dont l’emprise est calculée sur celle du réseau, et on appelle
                  addSegment ([c1,c2], [i,j]) pour chaque segment [c1,c2]
                  (localisé entre les points GPS i et i+1) de chaque tronçon j,
                  du réseau.


        resolution : tuple (xsize, ysize)
            DESCRIPTION. The default is (100, 100).

        Returns
        -------
        None.

        """
        # Bbox only or collection
        if isinstance(collection, Bbox):
            bb = collection
        else:
            bb = collection.bbox()

        bb = bb.copy()
        bb.addMargin(margin)
        (self.xmin, self.xmax, self.ymin, self.ymax) = bb.asTuple()

        ax, ay = bb.getDimensions()

        if resolution is None:
            am = max(ax, ay)
            r = am / 100
            resolution = (int(ax / r), int(ay / r))
        else:
            r = resolution
            resolution = (int(ax / r[0]), int(ay / r[1]))

        self.collection = collection

        # Keeps track of registered features
        self.inventaire = set()

        # Nombre de dalles par cote
        self.csize = resolution[0]
        self.lsize = resolution[1]
        # print ('nb cellule', self.xsize * self.ysize)

        # Tableau de collections de features appartenant a chaque dalle.
        # Un feature peut appartenir a plusieurs dalles.
        self.grid = []
        for i in range(self.csize):
            self.grid.append([])
            for j in range(self.lsize):
                self.grid[i].append([])

        self.dX = ax / self.csize
        self.dY = ay / self.lsize

        # Calcul de la grille
        if isinstance(collection, tuple):
            self.collection = TrackCollection()
            return

        boucle = range(collection.size())
        if verbose:
            print(
                "Building ["
                + str(self.csize)
                + " x "
                + str(self.lsize)
                + "] spatial index..."
            )
            boucle = progressbar.progressbar(boucle)
        for num in boucle:
            feature = collection[num]
            # On récupere la trace
            if isinstance(feature, Track):
                self.addFeature(feature, num)
            # On récupère l'arc du reseau qui est une trace
            elif isinstance(feature, Edge):
                self.addFeature(feature.geom, num)

    def __str__(self):
        """TODO"""
        c = [(self.xmin + self.xmax) / 2.0, (self.ymin + self.ymax) / 2.0]
        output = "[" + str(self.csize) + " x " + str(self.lsize) + "] "
        output += "spatial index centered on [" + str(c[0]) + "; " + str(c[1]) + "]"
        return output

    def addFeature(self, track, num):
        """TODO"""
        coord1 = None
        for i in range(track.size()):
            obs = track.getObs(i)
            coord2 = obs.position
            if coord1 != None:
                p1 = self.__getCell(coord1)
                p2 = self.__getCell(coord2)
                if p1 is None or p2 is None:
                    continue
                self.__addSegment(p1, p2, num)
            coord1 = coord2

    def __addSegment(self, coord1, coord2, data):
        """TODO

        data de type: int, liste, tuple, dictionnaire
        ajoute les données data dans toutes les cellules de la grille
               traversée par le segment [coord1, coord2] avec
               coord1 : indices de la grille
        """
        CELLS = self.__cellsCrossSegment(coord1, coord2)
        if CELLS is None:
            return  # out of grid
        # print (CELLS, coord1, coord2)

        for cell in CELLS:
            i = cell[0]
            j = cell[1]
            if i > self.csize:
                print("error, depassement en x")
                exit()
            if j > self.lsize:
                print("error, depassement en y")
                exit()

            if data not in self.grid[i][j]:
                if (i, j, data) not in self.inventaire:
                    self.grid[i][j].append(data)
                    self.inventaire.add((i, j, data))

    def __addPoint(self, coord, data):
        """TODO"""
        pass

    # ------------------------------------------------------------
    # Normalized coordinates of coord: (x,) -> (i,j) with:   
    #   i = (x-xmin)/(xmax-xmin)*nb_cols
    #   j = (y-ymin)/(ymax-ymin)*nb_rows
    # Returns None if out of grid
    # ------------------------------------------------------------
    def __getCell(self, coord):
        """TODO"""

        if (coord.getX() < self.xmin) or (coord.getX() > self.xmax):
            overflow = "{:5.5f}".format(
                max(self.xmin - coord.getX(), coord.getX() - self.xmax)
            )
            print("Warning: x overflow " + str(coord) + "  OVERFLOW = " + str(overflow))
            return None
        if (coord.getY() < self.ymin) or (coord.getY() > self.ymax):
            overflow = "{:5.5f}".format(
                max(self.ymin - coord.getY(), coord.getY() - self.ymax)
            )
            print("Warning: y overflow " + str(coord) + "  OVERFLOW = " + str(overflow))
            return None

        idx = (float(coord.getX()) - self.xmin) / self.dX
        idy = (float(coord.getY()) - self.ymin) / self.dY

        return (idx, idy)

    # ------------------------------------------------------------
    # Plot spatial index and collection structure together in the
    # same reference frame (geographic reference frame)
    #   - base: plot support network or track collection if True
    # ------------------------------------------------------------
    def plot(self, base=True):
        """TODO"""

        fig = plt.figure()
        ax = fig.add_subplot(
            111, xlim=(self.xmin, self.xmax), ylim=(self.ymin, self.ymax)
        )

        for i in range(1, self.csize):
            xi = i * self.dX + self.xmin
            ax.plot([xi, xi], [self.ymin, self.ymax], "-", color="lightgray")
        for j in range(1, self.lsize):
            yj = j * self.dY + self.ymin
            ax.plot([self.xmin, self.xmax], [yj, yj], "-", color="lightgray")

        if base:
            self.collection.plot(append=ax)

        for i in range(self.csize):
            xi1 = i * self.dX + self.xmin
            xi2 = xi1 + self.dX
            for j in range(self.lsize):
                yj1 = j * self.dY + self.ymin
                yj2 = yj1 + self.dY
                if len(self.grid[i][j]) > 0:
                    polygon = plt.Polygon(
                        [[xi1, yj1], [xi2, yj1], [xi2, yj2], [xi1, yj2], [xi1, yj1]]
                    )
                    ax.add_patch(polygon)
                    polygon.set_facecolor("lightcyan")

    # ------------------------------------------------------------
    # Plot a specific cell (i,j)
    # ------------------------------------------------------------
    def highlight(self, i, j, sym="r-", size=0.5):
        """TODO"""
        x0 = self.xmin + i * self.dX
        x1 = x0 + self.dX
        y0 = self.ymin + j * self.dY
        y1 = y0 + self.dY
        X = [x0, x1, x1, x0, x0]
        Y = [y0, y0, y1, y1, y0]
        plt.plot(X, Y, sym, linewidth=size)

    # ------------------------------------------------------------
    # Request function to get data registered in spatial index
    # Inputs:
    # 	- request(i,j) returns data registered in cell (i,j)
    #   	- i: row index i of spatial index grid
    # 		- j: col index j of spatial index grid
    #   - request(coord) returns data registered in the cell
    #     containing GeoCoords or ENUCoors object coord
    #   - request(list) returns data registered in all cells
    #     crossed by a segment list=[coord1, coord2].
    # 	- request(track) returns data registered in all cells
    #     crossed by a track.
    # ------------------------------------------------------------
    def request(self, obj, j=None) -> list[Any]:   
        """Request function to get data registered in spatial index

        TODO

        """
        # print (type(obj))
        if isinstance(obj, int):
            """dans la cellule (i,j)"""
            i = obj
            return self.grid[i][j]

        if isinstance(obj, GeoCoords) or isinstance(obj, ENUCoords):
            """dans la cellule contenant le point coord"""
            coord = obj
            c = self.__getCell(coord)
            return self.request(math.floor(c[0]), math.floor(c[1]))

        if isinstance(obj, list):
            """dans les cellules traversées par le segment défini
            par des coordonnées géographiques"""
            [coord1, coord2] = obj
            p1 = self.__getCell(coord1)
            p2 = self.__getCell(coord2)

            # Les cellules traversées par le segment
            CELLS = self.__cellsCrossSegment(p1, p2)
            TAB = []
            for cell in CELLS:
                self.__addCellValuesInTAB(TAB, cell)
            return TAB

        if isinstance(obj, Track):
            """dans les cellules traversée par la track"""
            track = obj

            # récupération des cellules de la track
            TAB = []
            pos1 = None
            for i in range(track.size()):
                obs = track.getObs(i)
                pos2 = obs.position
                if pos1 != None:
                    coord1 = self.__getCell(pos1)
                    coord2 = self.__getCell(pos2)

                    CELLS = self.__cellsCrossSegment(coord1, coord2)
                    for cell in CELLS:
                        self.__addCellValuesInTAB(TAB, cell)
                pos1 = pos2

            return TAB

    # ------------------------------------------------------------
    # Neighborhood function to get all data registered in spatial
    # index and located in the vicinity of a given location.
    # ------------------------------------------------------------
    # - neighborhood(i,j,unit) returns all data (as a plain list)
    #   registered in a cell located at less than 'unit' distance
    #   from (i,j) cell.
    # - neighborhood(coord, unit) returns data (as a plain list)
    #   registered in a cells located at less than 'unit' distance
    #   from cell containing coord.
    # - neighborhood([c1, c2], unit) returns data (as a plain
    #   list) registered in a cells located at less than 'unit'
    #   distance from cells containing segment [c1, c2]
    # - neighborhood(track, unit) returns data (as a plain list)
    #   registered in a cells located at less than 'unit' distance
    #   from cells containing track
    # ------------------------------------------------------------
    # As default value, unit=0, meaning that only data located in
    # (i,j) cell are selected. If unit=-1, the minimal value is
    # selected in order to get at least 1 data in function output.
    # ------------------------------------------------------------
    # The number of cells inspected is given by:
    #    - (1+2*unit)^2 if unit >= 0
    #    - (1+2*(unit'+1))^2 if unit < 0, with unit' is the min
    #      value of unit such that output is not empty
    # ------------------------------------------------------------

    def neighborhood(self, obj, j=None, unit=0):
        """TODO

        retourne toutes les données (sous forme de liste simple) référencées
        dans la cellule (i,j).

        Si unit=-1, calcule la valeur minimale à donner à unit,
        pour que la liste ne soit pas vide*.
        """

        # --------------------------------------------------------
        # neighborhood(i,j,unit)
        # --------------------------------------------------------
        if isinstance(obj, int):
            i = obj
            if unit != -1:
                TAB = set()
                NC = self.__neighboringcells(i, j, unit, False)
                for cell in NC:
                    TAB.update(self.request(cell[0], cell[1]))
                return list(TAB)

            # -----------------------------------------
            # Case: unit < 0 -> search for unit value
            # -----------------------------------------
            u = 0
            TAB = set()
            found = False
            while u <= max(self.csize, self.lsize):
                NC = self.__neighboringcells(i, j, u, True)
                for cell in NC:
                    TAB.update(self.request(cell[0], cell[1]))
                if found:
                    break

                found = len(TAB) > 0
                u += 1

            return list(TAB)

        # --------------------------------------------------------
        # neighborhood(coord, unit)
        # --------------------------------------------------------
        if isinstance(obj, GeoCoords) or isinstance(obj, ENUCoords):
            coord = obj
            x = coord.getX()
            y = coord.getY()
            c = self.__getCell(ENUCoords(x, y))
            return self.neighborhood(math.floor(c[0]), math.floor(c[1]), unit)

        # --------------------------------------------------------
        # neighborhood([c1, c2], unit)
        # --------------------------------------------------------
        if isinstance(obj, list):
            """cellules voisines traversées par le segment coord"""
            [coord1, coord2] = obj
            p1 = self.__getCell(coord1)
            p2 = self.__getCell(coord2)

            if unit > -1:
                # Tableau à retourner
                TAB = []

                # Les cellules traversées par le segment
                CELLS = self.__cellsCrossSegment(p1, p2)
                for cell in CELLS:
                    NC = self.__neighboringcells(cell[0], cell[1], unit)
                    # print ('    ', cell, NC)
                    for cellu in NC:
                        self.__addCellValuesInTAB(TAB, cellu)

                return TAB

            u = 0
            while u <= max(self.csize, self.lsize):
                TAB = []
                CELLS = self.__cellsCrossSegment(p1, p2)
                for cell in CELLS:
                    NC = self.__neighboringcells(cell[0], cell[1], u)
                    # print (cell, NC)
                    for cellu in NC:
                        self.__addCellValuesInTAB(TAB, cellu)

                # print (TAB)
                if len(TAB) <= 0:
                    u += 1
                    continue

                # Plus une marge de sécurité
                CELLS = self.__cellsCrossSegment(p1, p2)
                for cell in CELLS:
                    NC = self.__neighboringcells(cell[0], cell[1], u + 1)
                    # print (cell, NC)
                    for cellu in NC:
                        self.__addCellValuesInTAB(TAB, cellu)
                # print (TAB)
                return TAB

        # --------------------------------------------------------
        # neighborhood(track, unit)
        # --------------------------------------------------------
        if isinstance(obj, Track):
            """cellules voisines traversées par Track"""

            track = obj

            TAB2 = []
            pos1 = None
            for i in range(track.size()):
                obs = track.getObs(i)
                pos2 = obs.position

                if pos1 != None:
                    CELLS = self.neighborhood([pos1, pos2], None, unit)
                    # print (CELLS, unit)
                    for cell in CELLS:
                        if cell not in TAB2:
                            TAB2.append(cell)
                pos1 = pos2

            return TAB2

    # ------------------------------------------------------------
    # Function to convert ground distance (metric system is
    # assumed to be orthonormal) into unit number
    # ------------------------------------------------------------
    def groundDistanceToUnits(self, distance):
        """TODO"""
        return math.floor(distance / max(self.dX, self.dY) + 1)

    # ------------------------------------------------------------
    # Returns all cells (i',j') in a vicinity unit of (i,j)
    # ------------------------------------------------------------
    # - incremental = True: gets all cells where distance is to
    #   central cell is exactly u units (Manhattan L1 discretized
    #   distance). Used for incremental search of neighbors.
    # - incremental = False: gets all cells where distance is less
    #   or equal than u units (Manhattan L1 discretized distance)
    # ------------------------------------------------------------
    def __neighboringcells(self, i, j, u=0, incremental=False):
        """TODO"""
        NC = []
        imin = max(i - u, 0)
        imax = min(i + u + 1, self.csize)
        jmin = max(j - u, 0)
        jmax = min(j + u + 1, self.lsize)
        for ii in range(imin, imax):
            for jj in range(jmin, jmax):
                if incremental:
                    if (ii != imin) and (ii != imax - 1):
                        if (jj != jmin) and (jj != jmax - 1):
                            continue
                NC.append((ii, jj))
        return NC

    # ------------------------------------------------------------
    # Add data registered in cell within TAB structure
    # ------------------------------------------------------------
    def __addCellValuesInTAB(self, TAB, cell):
        """TODO"""
        values = self.request(cell[0], cell[1])
        for d in values:
            if d not in TAB:
                TAB.append(d)

    # ------------------------------------------------------------
    # List of cells crossing segment [coord1, coord2] (in px)
    # ------------------------------------------------------------
    def __cellsCrossSegment(self, coord1, coord2):
        """TODO"""

        CELLS = []
        segment2 = [coord1[0], coord1[1], coord2[0], coord2[1]]

        xmin = min(math.floor(coord1[0]), math.floor(coord2[0]))
        xmax = max(math.floor(coord1[0]), math.floor(coord2[0]))

        ymin = min(math.floor(coord1[1]), math.floor(coord2[1]))
        ymax = max(math.floor(coord1[1]), math.floor(coord2[1]))

        for i in range(xmin, xmax + 1):
            for j in range(ymin, ymax + 1):

                # complètement inclus
                if (
                    i < coord1[0]
                    and coord1[0] < i + 1
                    and i < coord2[0]
                    and coord2[0] < i + 1
                    and j < coord1[1]
                    and coord1[1] < j + 1
                    and j < coord2[1]
                    and coord2[1] < j + 1
                ):
                    if (i, j) not in CELLS:
                        CELLS.append((i, j))
                    continue

                # traverse
                segment1 = [i, j, i + 1, j]
                if Geometry.isSegmentIntersects(segment1, segment2):
                    if (i, j) not in CELLS:
                        CELLS.append((i, j))
                    continue

                segment1 = [i, j, i, j + 1]
                if Geometry.isSegmentIntersects(segment1, segment2):
                    if (i, j) not in CELLS:
                        CELLS.append((i, j))
                    continue

                segment1 = [i, j + 1, i + 1, j + 1]
                if Geometry.isSegmentIntersects(segment1, segment2):
                    if (i, j) not in CELLS:
                        CELLS.append((i, j))
                    continue

                segment1 = [i + 1, j, i + 1, j + 1]
                if Geometry.isSegmentIntersects(segment1, segment2):
                    if (i, j) not in CELLS:
                        CELLS.append((i, j))
                    continue

        return CELLS

    def save(self, filename):
        """TODO"""
        outfile = open(filename, "wb")
        pickle.dump(self, outfile)
        outfile.close()

    def load(filename):
        """TODO"""
        infile = open(filename, "rb")
        index = pickle.load(infile)
        infile.close()
        return index
Beispiel #17
0
    def setUp(self):

        GPSTime.GPSTime.setReadFormat("4Y-2M-2D 2h:2m:2s")
        self.TRACES = []

        # ---------------------------------------------------------------------
        trace1 = Track.Track([], 1)
        c1 = Coords.ENUCoords(10, 10, 0)
        p1 = Obs.Obs(c1, GPSTime.GPSTime.readTimestamp("2018-01-01 10:00:00"))
        trace1.addObs(p1)

        c2 = Coords.ENUCoords(10, 110, 0)
        p2 = Obs.Obs(c2, GPSTime.GPSTime.readTimestamp("2018-01-01 10:00:12"))
        trace1.addObs(p2)

        c3 = Coords.ENUCoords(270, 110, 0)
        p3 = Obs.Obs(c3, GPSTime.GPSTime.readTimestamp("2018-01-01 10:00:40"))
        trace1.addObs(p3)

        c4 = Coords.ENUCoords(360, 210, 0)
        p4 = Obs.Obs(c4, GPSTime.GPSTime.readTimestamp("2018-01-01 10:01:50"))
        trace1.addObs(p4)

        self.TRACES.append(trace1)

        # ---------------------------------------------------------------------
        trace2 = Track.Track([], 2)
        c7 = Coords.ENUCoords(25, 10, 0)
        p7 = Obs.Obs(c7, GPSTime.GPSTime.readTimestamp("2018-01-01 10:00:15"))
        trace2.addObs(p7)

        c6 = Coords.ENUCoords(280, 90, 0)
        p6 = Obs.Obs(c6, GPSTime.GPSTime.readTimestamp("2018-01-01 10:00:45"))
        trace2.addObs(p6)

        c5 = Coords.ENUCoords(330, 20, 0)
        p5 = Obs.Obs(c5, GPSTime.GPSTime.readTimestamp("2018-01-01 10:01:55"))
        trace2.addObs(p5)

        self.TRACES.append(trace2)

        self.collection = TrackCollection(self.TRACES)

        #  Construction de la grille
        #self.grille = Grid.Grid(Xmin, Ymin, Xmax, Ymax, PixelSize)
        marge = 0.05
        self.grille = Grid.Grid(self.collection, (60, 60), marge)
        #self.grille.plot()
        #plt.show()

        self.assertEqual(self.grille.xmin, 10.0 - marge * (360 - 10))
        self.assertEqual(self.grille.xmax, 360.0 + marge * (360 - 10))
        self.assertEqual(self.grille.ymin, 10.0 - marge * (210 - 10))
        self.assertEqual(self.grille.ymax, 210.0 + marge * (210 - 10))

        self.assertEqual(self.grille.ncol,
                         int(((360 - 10) + marge * (360 - 10)) / 60))
        self.assertEqual(self.grille.nrow,
                         int(((210 - 10) + marge * (210 - 10)) / 60))

        self.assertEqual(self.grille.XPixelSize,
                         ((360 - 10) + 2 * marge *
                          (360 - 10)) / self.grille.ncol)
        self.assertEqual(self.grille.YPixelSize,
                         ((210 - 10) + 2 * marge *
                          (210 - 10)) / self.grille.nrow)
Beispiel #18
0
class TestGrille(TestCase):
    def setUp(self):

        GPSTime.GPSTime.setReadFormat("4Y-2M-2D 2h:2m:2s")
        self.TRACES = []

        # ---------------------------------------------------------------------
        trace1 = Track.Track([], 1)
        c1 = Coords.ENUCoords(10, 10, 0)
        p1 = Obs.Obs(c1, GPSTime.GPSTime.readTimestamp("2018-01-01 10:00:00"))
        trace1.addObs(p1)

        c2 = Coords.ENUCoords(10, 110, 0)
        p2 = Obs.Obs(c2, GPSTime.GPSTime.readTimestamp("2018-01-01 10:00:12"))
        trace1.addObs(p2)

        c3 = Coords.ENUCoords(270, 110, 0)
        p3 = Obs.Obs(c3, GPSTime.GPSTime.readTimestamp("2018-01-01 10:00:40"))
        trace1.addObs(p3)

        c4 = Coords.ENUCoords(360, 210, 0)
        p4 = Obs.Obs(c4, GPSTime.GPSTime.readTimestamp("2018-01-01 10:01:50"))
        trace1.addObs(p4)

        self.TRACES.append(trace1)

        # ---------------------------------------------------------------------
        trace2 = Track.Track([], 2)
        c7 = Coords.ENUCoords(25, 10, 0)
        p7 = Obs.Obs(c7, GPSTime.GPSTime.readTimestamp("2018-01-01 10:00:15"))
        trace2.addObs(p7)

        c6 = Coords.ENUCoords(280, 90, 0)
        p6 = Obs.Obs(c6, GPSTime.GPSTime.readTimestamp("2018-01-01 10:00:45"))
        trace2.addObs(p6)

        c5 = Coords.ENUCoords(330, 20, 0)
        p5 = Obs.Obs(c5, GPSTime.GPSTime.readTimestamp("2018-01-01 10:01:55"))
        trace2.addObs(p5)

        self.TRACES.append(trace2)

        self.collection = TrackCollection(self.TRACES)

        #  Construction de la grille
        #self.grille = Grid.Grid(Xmin, Ymin, Xmax, Ymax, PixelSize)
        marge = 0.05
        self.grille = Grid.Grid(self.collection, (60, 60), marge)
        #self.grille.plot()
        #plt.show()

        self.assertEqual(self.grille.xmin, 10.0 - marge * (360 - 10))
        self.assertEqual(self.grille.xmax, 360.0 + marge * (360 - 10))
        self.assertEqual(self.grille.ymin, 10.0 - marge * (210 - 10))
        self.assertEqual(self.grille.ymax, 210.0 + marge * (210 - 10))

        self.assertEqual(self.grille.ncol,
                         int(((360 - 10) + marge * (360 - 10)) / 60))
        self.assertEqual(self.grille.nrow,
                         int(((210 - 10) + marge * (210 - 10)) / 60))

        self.assertEqual(self.grille.XPixelSize,
                         ((360 - 10) + 2 * marge *
                          (360 - 10)) / self.grille.ncol)
        self.assertEqual(self.grille.YPixelSize,
                         ((210 - 10) + 2 * marge *
                          (210 - 10)) / self.grille.nrow)

    def test_summarize_af(self):

        self.collection.addAnalyticalFeature(Analytics.speed)

        af_algos = ['speed']  #, utils.stop_point]
        cell_operators = [Summarising.co_avg]  #, utils.sum]

        raster = Summarising.summarize(self.grille, af_algos, cell_operators)
        raster.plot(Analytics.speed, Summarising.co_avg)

        rasterBand = raster.getRasterBand(Analytics.speed, Summarising.co_avg)

        speedTrace1 = self.collection.getTrack(0).getAnalyticalFeature('speed')
        speedTrace2 = self.collection.getTrack(1).getAnalyticalFeature('speed')

        self.assertEqual(rasterBand[0][0], 0)
        self.assertEqual(rasterBand[1][0], speedTrace1[1])
        self.assertEqual(rasterBand[2][0],
                         (speedTrace1[0] + speedTrace2[0]) / 2)

        self.assertEqual(rasterBand[0][1], 0)
        self.assertEqual(rasterBand[1][1], 0)
        self.assertEqual(rasterBand[2][1], 0)
        self.assertEqual(rasterBand[0][2], 0)
        self.assertEqual(rasterBand[1][2], 0)
        self.assertEqual(rasterBand[2][2], 0)
        self.assertEqual(rasterBand[0][3], 0)
        self.assertEqual(rasterBand[1][3], 0)
        self.assertEqual(rasterBand[2][3], 0)

        self.assertEqual(rasterBand[0][4], 0)
        self.assertEqual(rasterBand[1][4],
                         (speedTrace1[2] + speedTrace2[1]) / 2)
        self.assertEqual(rasterBand[2][4], 0)

        self.assertEqual(rasterBand[0][5], speedTrace1[3])
        self.assertEqual(rasterBand[1][5], 0)
        self.assertEqual(rasterBand[2][5], speedTrace2[2])
Beispiel #19
0
    def __init__(self, collection, resolution=None, margin=0.05, verbose=True):
        """Constructor of :class:`SaptialIndex` class

        TODO: update documentation

        Parameters
        ----------
        features : bbox() + iterable


            TrackCollection : on construit une grille
                dont l’emprise est calculée sur la fonction getBBox
                de TrackCollection et dans un deuxième temps on appelle
                addSegment([c1,c2], [i,j]) pour chaque segment [c1,c2]
                (localisé entre les points GPS i et i+1) de chaque trace j,
                de la collection.
            Network : on construit une grille (de taille 100 x 100) par défaut,
                  dont l’emprise est calculée sur celle du réseau, et on appelle
                  addSegment ([c1,c2], [i,j]) pour chaque segment [c1,c2]
                  (localisé entre les points GPS i et i+1) de chaque tronçon j,
                  du réseau.


        resolution : tuple (xsize, ysize)
            DESCRIPTION. The default is (100, 100).

        Returns
        -------
        None.

        """
        # Bbox only or collection
        if isinstance(collection, Bbox):
            bb = collection
        else:
            bb = collection.bbox()

        bb = bb.copy()
        bb.addMargin(margin)
        (self.xmin, self.xmax, self.ymin, self.ymax) = bb.asTuple()

        ax, ay = bb.getDimensions()

        if resolution is None:
            am = max(ax, ay)
            r = am / 100
            resolution = (int(ax / r), int(ay / r))
        else:
            r = resolution
            resolution = (int(ax / r[0]), int(ay / r[1]))

        self.collection = collection

        # Keeps track of registered features
        self.inventaire = set()

        # Nombre de dalles par cote
        self.csize = resolution[0]
        self.lsize = resolution[1]
        # print ('nb cellule', self.xsize * self.ysize)

        # Tableau de collections de features appartenant a chaque dalle.
        # Un feature peut appartenir a plusieurs dalles.
        self.grid = []
        for i in range(self.csize):
            self.grid.append([])
            for j in range(self.lsize):
                self.grid[i].append([])

        self.dX = ax / self.csize
        self.dY = ay / self.lsize

        # Calcul de la grille
        if isinstance(collection, tuple):
            self.collection = TrackCollection()
            return

        boucle = range(collection.size())
        if verbose:
            print(
                "Building ["
                + str(self.csize)
                + " x "
                + str(self.lsize)
                + "] spatial index..."
            )
            boucle = progressbar.progressbar(boucle)
        for num in boucle:
            feature = collection[num]
            # On récupere la trace
            if isinstance(feature, Track):
                self.addFeature(feature, num)
            # On récupère l'arc du reseau qui est une trace
            elif isinstance(feature, Edge):
                self.addFeature(feature.geom, num)
Beispiel #20
0
    def test_create_index_collection1(self):
        
        GPSTime.setReadFormat("4Y-2M-2D 2h:2m:2s")
                
        track = Track()
        p1 = Obs(ENUCoords(0, 0), GPSTime.readTimestamp('2020-01-01 10:00:00'))
        track.addObs(p1)
        p2 = Obs(ENUCoords(2.5, 3), GPSTime.readTimestamp('2020-01-01 10:08:00'))
        track.addObs(p2)
        p3 = Obs(ENUCoords(2.5, 5), GPSTime.readTimestamp('2020-01-01 10:17:00'))
        track.addObs(p3)
        p4 = Obs(ENUCoords(7, 5), GPSTime.readTimestamp('2020-01-01 10:21:00'))
        track.addObs(p4)
        p5 = Obs(ENUCoords(10, 10), GPSTime.readTimestamp('2020-01-01 10:25:00'))
        track.addObs(p5)
                #track.plot()
                #track.plotAsMarkers()
                
        TRACES = []
        TRACES.append(track)
        collection = TrackCollection(TRACES)
                
        index = SpatialIndex(collection, (2, 2))
        index.plot()
        
        # =====================================================================
        # =====================================================================
        self.assertEqual(index.request(0, 0), [0])
        self.assertEqual(index.request(1, 0), [])
        self.assertEqual(index.request(0, 1), [0])
        self.assertEqual(index.request(1, 1), [0])
        self.assertEqual(index.request(2, 0), [])
        self.assertEqual(index.request(2, 1), [])
        self.assertEqual(index.request(1, 2), [0])
        self.assertEqual(index.request(2, 2), [0])
        self.assertEqual(index.request(3, 2), [0])
        self.assertEqual(index.request(3, 3), [0])
        self.assertEqual(index.request(4, 3), [0])
        self.assertEqual(index.request(4, 4), [0])
        
        
        # # =====================================================================
        self.assertEqual(index.request(ENUCoords(0, 0)), [0])
        self.assertEqual(index.request(ENUCoords(2.5, 3)), [0])
        self.assertEqual(index.request(ENUCoords(2.5, 5)), [0])
        self.assertEqual(index.request(ENUCoords(7, 5)), [0])
        self.assertEqual(index.request(ENUCoords(10, 10)), [0])
        self.assertEqual(index.request(ENUCoords(0.5, 2.5)), [0])
        self.assertEqual(index.request(ENUCoords(4.2, 5.8)), [0])

        
        # # =====================================================================
        self.assertEqual(index.request([ENUCoords(2.1, 0.5), ENUCoords(1.1, 1.1)]), [0])
        self.assertEqual(index.request([ENUCoords(2.1, 0.5), ENUCoords(7.1, 3.5)]), [])
        self.assertEqual(index.request([ENUCoords(5.8, 5.8), ENUCoords(2.1, 1.1)]), [0])
        
        
        # # =====================================================================
        self.assertEqual(index.request(track), [0])
 
        track2 = Track()
        p6 = Obs(ENUCoords(2.2, 0), GPSTime.readTimestamp('2020-01-01 10:00:00'))
        track2.addObs(p6)
        p7 = Obs(ENUCoords(2.2, 3.8), GPSTime.readTimestamp('2020-01-01 10:08:00'))
        track2.addObs(p7)
        p8 = Obs(ENUCoords(6.5, 3.8), GPSTime.readTimestamp('2020-01-01 10:08:00'))
        track2.addObs(p8)
        self.assertEqual(index.request(track2), [0])
        
        
        track3 = Track()
        p9 = Obs(ENUCoords(6.5, 3.8), GPSTime.readTimestamp('2020-01-01 10:00:00'))
        track3.addObs(p9)
        p10 = Obs(ENUCoords(6.5, 7), GPSTime.readTimestamp('2020-01-01 10:08:00'))
        track3.addObs(p10)
        p11 = Obs(ENUCoords(10, 7), GPSTime.readTimestamp('2020-01-01 10:08:00'))
        track3.addObs(p11)
        self.assertEqual(index.request(track3), [0])


        # # =====================================================================
        # # =====================================================================
        self.assertCountEqual(index.neighborhood(0, 4, 0), [])
        self.assertCountEqual(index.neighborhood(0, 4, 1), [])
        self.assertCountEqual(index.neighborhood(0, 4, 2), [0])
        self.assertCountEqual(index.neighborhood(0, 4, 3), [0])
    
        self.assertCountEqual(index.neighborhood(3, 0, 0), [])
        self.assertCountEqual(index.neighborhood(3, 0, 1), [])
        self.assertCountEqual(index.neighborhood(3, 0, 2), [0])
        self.assertCountEqual(index.neighborhood(3, 0, 3), [0])
    
        self.assertCountEqual(index.neighborhood(2, 2, 0), [0])
        self.assertCountEqual(index.neighborhood(2, 2, 1), [0])
        self.assertCountEqual(index.neighborhood(2, 2, 2), [0])
        #self.assertCountEqual(index.neighborhood(2, 2, 3), [0])
    
        # # UNIT = -1
        self.assertCountEqual(index.neighborhood(2, 1, -1), [0])
        self.assertCountEqual(index.neighborhood(2, 0, -1), [0])
        self.assertCountEqual(index.neighborhood(0, 1, -1), [0])
        self.assertCountEqual(index.neighborhood(1, 1, -1), [0])
        self.assertCountEqual(index.neighborhood(0, 4, -1), [0])
        self.assertCountEqual(index.neighborhood(3, 4, -1), [0])
        self.assertCountEqual(index.neighborhood(4, 4, -1), [0])
        self.assertCountEqual(index.neighborhood(2, 4, -1), [0])
        
        
        # # =====================================================================
        self.assertCountEqual(index.neighborhood(ENUCoords(0, 0.1)), [0])
        self.assertCountEqual(index.neighborhood(ENUCoords(2.5, 3)), [0])
        self.assertCountEqual(index.neighborhood(ENUCoords(2.5, 5)), [0])
        self.assertCountEqual(index.neighborhood(ENUCoords(7, 5)), [0])
        self.assertCountEqual(index.neighborhood(ENUCoords(10, 10)), [0])
        
        self.assertCountEqual(index.neighborhood(ENUCoords(6.5, 3.8), None, 0), [])
        self.assertCountEqual(index.neighborhood(ENUCoords(6.5, 3.8), None, 1), [0])
        self.assertCountEqual(index.neighborhood(ENUCoords(6.5, 3.8), None, 2), [0])
        self.assertCountEqual(index.neighborhood(ENUCoords(6.5, 3.8), None, 3), [0])

        self.assertCountEqual(index.neighborhood(ENUCoords(2.2, 3.8), None, 0), [0])
        self.assertCountEqual(index.neighborhood(ENUCoords(2.2, 3.8), None, 1), [0])
        self.assertCountEqual(index.neighborhood(ENUCoords(2.2, 3.8), None, 2), [0])
        self.assertCountEqual(index.neighborhood(ENUCoords(2.2, 3.8), None, 3), [0])
        
        self.assertCountEqual(index.neighborhood(ENUCoords(9.9, 7), None, 0), [0])
        self.assertCountEqual(index.neighborhood(ENUCoords(9.9, 7), None, 1), [0])
        self.assertCountEqual(index.neighborhood(ENUCoords(9.9, 7), None, 2), [0])
        self.assertCountEqual(index.neighborhood(ENUCoords(9.9, 7), None, 3), [0])
       
        #  # UNIT = -1
        self.assertCountEqual(index.neighborhood(ENUCoords(0, 0), None, -1), [0])
        self.assertCountEqual(index.neighborhood(ENUCoords(2.5, 3), None, -1), [0])
        self.assertCountEqual(index.neighborhood(ENUCoords(2.5, 5), None, -1), [0])
        self.assertCountEqual(index.neighborhood(ENUCoords(7, 5), None, -1), [0])
        self.assertCountEqual(index.neighborhood(ENUCoords(10, 10), None, -1), [0])
        
        self.assertCountEqual(index.neighborhood(ENUCoords(6.5, 3.8), None, -1), [0])
        self.assertCountEqual(index.neighborhood(ENUCoords(2.2, 3.8), None, -1), [0])
        self.assertCountEqual(index.neighborhood(ENUCoords(9.9, 7), None, -1), [0])
  
    
        # # =====================================================================
        self.assertEqual(index.neighborhood([ENUCoords(2.1, 0.5), ENUCoords(0.1, 2.1)], None, 0), [0])
        self.assertEqual(index.neighborhood([ENUCoords(2.1, 0.5), ENUCoords(0.1, 2.1)], None, 1), [0])
        self.assertEqual(index.neighborhood([ENUCoords(2.1, 0.5), ENUCoords(0.1, 2.1)], None, 2), [0])
        self.assertEqual(index.neighborhood([ENUCoords(2.1, 0.5), ENUCoords(0.1, 2.1)], None, -1), [0])

        self.assertEqual(index.neighborhood([ENUCoords(2.1, 0.5), ENUCoords(7.1, 3.5)]), [])
        self.assertEqual(index.neighborhood([ENUCoords(2.1, 0.5), ENUCoords(7.1, 3.5)], None, 2), [0])
        self.assertEqual(index.neighborhood([ENUCoords(2.1, 0.5), ENUCoords(7.1, 3.5)], None, -1), [0])
        
        self.assertEqual(index.neighborhood([ENUCoords(5.8, 5.8), ENUCoords(2.1, 1.1)]), [0])
        self.assertEqual(index.neighborhood([ENUCoords(5.8, 5.8), ENUCoords(2.1, 1.1)], None, 1), [0])
        self.assertEqual(index.neighborhood([ENUCoords(5.8, 5.8), ENUCoords(2.1, 1.1)], None, 2), [0])
        self.assertEqual(index.neighborhood([ENUCoords(5.8, 5.8), ENUCoords(2.1, 1.1)], None, -1), [0])
        
        
        # # =====================================================================
        self.assertEqual(index.neighborhood(track), [0])
        self.assertEqual(index.neighborhood(track, None, 1), [0])
        self.assertEqual(index.neighborhood(track, None, 3), [0])
        self.assertEqual(index.neighborhood(track, None, -1), [0])
 
        self.assertEqual(index.neighborhood(track2), [0])
        self.assertEqual(index.neighborhood(track2, None, 0), [0])
        self.assertEqual(index.neighborhood(track2, None, 1), [0])
        self.assertEqual(index.neighborhood(track2, None, 3), [0])
        self.assertEqual(index.neighborhood(track2, None, -1), [0])
        
        self.assertEqual(index.neighborhood(track3), [0])
        self.assertEqual(index.neighborhood(track3, None, 0), [0])
        self.assertEqual(index.neighborhood(track3, None, 1), [0])
        self.assertEqual(index.neighborhood(track3, None, 2), [0])
        self.assertEqual(index.neighborhood(track3, None, 3), [0])
        self.assertEqual(index.neighborhood(track3, None, -1), [0])
Beispiel #21
0
 def addTrackPair(self, track1, track2):
     """TODO"""
     self.addTrackCollection(TrackCollection([track1, track2]))