def __main1(self):
        track = self.__getNextTrack()

        while track:
            for segment in track:
                segment.calcSpeed()

                sql = """
                    SELECT traffic.upd_speed_segment(%(segmentId)s, %(speed)s, %(speed)s, %(source)s, %(did)s,
                                                   %(curTs)s, %(area)s);
                """

                self.baseDB.execute(sql, {
                    'segmentId': segment.id,
                    'speed': segment.speed,
                    'source': track.source,
                    'did': track.deviceId,
                    'curTs': cur_time.getTs(self.baseDB),
                    'area': self.area
                })

                logger.logByCond(self.isLog, 'Update speed (%d km/h) on segment with id %d' % (segment.speed, segment.id))

            self.baseDB.commit()

            if self.isExportTrafficJam:
                self.trafficJamBuffer.put(track)

            if self.isStatsCollection:
                self.statsBuffer.put(track)

            track = self.__getNextTrack()
    def __main2(self):
        track = self.__getNextTrack()

        while True:
            for segment in track:
                segment.calcSpeed()

                sql = """
                    INSERT INTO traffic.segment_speeds_tmp (segment, source, did, speed, ts)
                    VALUES (%(segmentId)s, %(source)s, %(did)s, %(speed)s, %(curTs)s)
                """

                self.baseDB.execute(sql, {
                    'segmentId': segment.id,
                    'speed': segment.speed,
                    'source': track.source,
                    'did': track.deviceId,
                    'curTs': cur_time.getTs(self.baseDB)
                })

                self.baseDB.commit()

                logger.logByCond(self.isLog, 'Add speed (%d km/h) to segment with id %d' % (segment.speed, segment.id))

            if self.isExportTrafficJam:
                self.trafficJamBuffer.put(track)

            if self.isStatsCollection:
                self.statsBuffer.put(track)

            track = self.__getNextTrack()
    def __exportTrack(self, track):
        if config.FILTER_CONTINUOUS_TRACK_ENABLED:
           track = makeContinuousTrack(self.baseDB, track)

        unexportedTrackParts = list(filter(lambda trackPart: not trackPart.hasExported, track.getTrackParts()))

        if track.isActive:
            unexportedTrackParts = unexportedTrackParts[:-1]

        for trackPart in unexportedTrackParts:
            self.__exportTrackPart(trackPart)

        logger.logByCond(self.isLog and len(unexportedTrackParts) > 0,
                           'was composed track from %s with id %s' % (track.source, track.deviceId))
    def __updateStorage(self):
        if self.deviceFlag and self.busFlag:
            sql = """
                SELECT id, udid, lon, lat, speed, bearing, created_at AS ts, 'device'
                FROM tracking.points WHERE created_at > %(prevTs)s AND created_at <= %(now)s AND speed IS NOT NULL AND bearing IS NOT NULL
                UNION
                SELECT id, udid, lon, lat, speed, bearing, ts, 'bus'
                FROM bus.points WHERE ts > %(prevTs)s AND ts <= %(now)s AND speed IS NOT NULL AND bearing IS NOT NULL
                ORDER BY ts ASC
            """

        elif self.deviceFlag:
            sql = """
                SELECT id, udid, lon, lat, speed, bearing, created_at AS ts, 'device'
                FROM tracking.points WHERE created_at > %(prevTs)s AND created_at <= %(now)s AND speed IS NOT NULL AND bearing IS NOT NULL
                ORDER BY ts ASC
            """

        elif self.busFlag:
            sql = """
                SELECT id, udid, lon, lat, speed, bearing, ts, 'bus'
                FROM bus.points WHERE ts > %(prevTs)s AND ts <= %(now)s AND speed IS NOT NULL AND bearing IS NOT NULL
                ORDER BY ts ASC
            """

        prevTs = cur_time.getTs(self.conn)

        time.sleep(0.5)

        while self.isAlive:
            nowTs = cur_time.getTs(self.conn)

            self.conn.execute(sql, {'prevTs': prevTs, 'now': nowTs})

            logger.logByCond(self.isLog, 'point storage was updated [current time - %s]' % nowTs)

            points = self.conn.fetchAll()

            for p in points:
                source = p[7]
                speed = float(p[4]) * 3.6 if source == 'device' else float(p[4])
                self.storage.append(Point(source, p[0], p[1], p[2], p[3], speed, p[5], p[6]))

            prevTs = nowTs

            time.sleep(config.POINT_STORAGE_UPDATE_TIMEOUT)
    def __bindPoint(self, point, iteration):
        logger.logByCond(self.isLog, '+ point №%s has been received' % iteration)

        # find track for point
        if self.tracks.contains(point.deviceId):
            track = self.tracks.getTrack(point.deviceId)

        else:
            track = Track(point.source, point.deviceId)
            track.setModificationTs(point.ts)
            self.tracks.addTrack(track)

        # filter points with non valid angle
        if (config.FILTER_INVALID_ANGLE_ENABLED):
            if self.__filterPointsWithInvalidAnge(point, track, iteration):
                return

        # try bind point to track
        if self.__pointToTrack(point, track, iteration):
            track.setModificationTs(point.ts)
            track.prevPointNotBind = False

        else:
            track.prevPointNotBind = True
    def __reset(sql, message):
        conn.execute(sql)
        conn.commit()

        logger.logByCond(isLog, message)
    def __pointToTrack(self, point, track, iteration):
        segments = getSegmentsByDist(self.mapsDB, point)

        if self.enableAllowedSegmentsFilter:
            segments = self.__allowedSegmentsFilter(point, segments)

        if len(segments) == 0:
            return False

        if config.FILTER_UNATTAINABLE_SEGMENTS_ENABLED and not track.isAmbiguity and track.getPointCount() > 0 and not track.prevPointNotBind:
            segments = filterSegments(self.baseDB, point, track.getLastPoint(), track.getLastSegment(), segments)

            if len(segments) == 0:
                return False

        if (len(segments) > 1 or track.isAmbiguity):
            if not track.isAmbiguity:
                track.setAmbiguity(True, self.isLogFull)

                for segment in segments:
                    v = Variant(segment, point)
                    track.vStorage.addVariant(v)
                    v.addDist(segment.dist)

                logger.logByCondFunc(self.isLogFull, log_variants, (track.vStorage.variants,), end='')

                return True

            elif track.isAmbiguity:
                track.vStorage.filter(segments, point)

                logger.logByCondFunc(self.isLogFull, log_variants, (track.vStorage.variants,), end='')

                if track.vStorage.getActiveCount() == 1:
                    if track.vStorage.selectMostProbable(0.3):
                        logger.logByCondFunc(self.isLogFull, log_selMostProbable, (track.vStorage.variants,))

                    track.importFromVStorage()
                    track.setAmbiguity(False)
                    return True

                elif track.vStorage.getActiveCount() > 1:
                    return True

                elif track.vStorage.getActiveCount() == 0:
                    if track.vStorage.selectMostProbable(0.1):
                        logger.logByCondFunc(self.isLogFull, log_selMostProbable, (track.vStorage.variants,))

                        track.importFromVStorage()

                    track.setAmbiguity(False)

                    return self.__pointToTrack(point, track, iteration)

        logger.logByCond(self.isLogFull, '  - add segment %s' % segments[0].id)

        point.selSegment(segments[0].id)

        track.addSegment(segments[0])
        track.addPoint(point)

        return True