Пример #1
0
    def get_track_distance(self, track):
        """Get distance of a section of track.
        """
        distance = 0 
        if not track:
            pass
        else:
            start_point = None
            for point in track:
                if not start_point: 
                    start_point = point
                    continue
                else:
                    distance += get_distance(start_point["longitude"], start_point["latitude"], 
                                             point["longitude"], point["latitude"])
                    start_point = point

        return distance
Пример #2
0
def block_test():
    db = DBConnection().db
    redis = MyRedis()

    #start_time = int(time.mktime(time.strptime("%s-%s-%s-%s-%s-%s"%(2014,8,26,0,0,0),"%Y-%m-%d-%H-%M-%S")))
    #end_time = int(time.mktime(time.strptime("%s-%s-%s-%s-%s-%s"%(2014,8,27,18,0,0),"%Y-%m-%d-%H-%M-%S")))
    #print time.localtime(start_time)
    #print time.localtime(end_time)

    tid = '3922400068'
    
        
    start_time = 1409222189 
    end_time = 1409223445
    track = db.query("SELECT id, latitude, longitude, clatitude,"
                     "       clongitude, timestamp, name, type, speed, degree, locate_error"
                     "  FROM T_LOCATION"
                     "  WHERE tid = %s"
                     "    AND category = 1"
                     "    AND NOT (latitude = 0 OR longitude = 0)"
                     "    AND (timestamp BETWEEN %s AND %s)"
                     "    AND type = 0"
                     "    GROUP BY timestamp"
                     "    ORDER BY timestamp",
                     tid, start_time, end_time)

    distance = 0
    start_point = None
    for point in track:
        if not start_point: 
            start_point = point
            continue
        else:
            distance += get_distance(start_point["longitude"], start_point["latitude"], 
                                     point["longitude"], point["latitude"])
            start_point = point

    print '---distance',  distance,  tid, start_time, end_time
Пример #3
0
        def _on_finish(db):
            self.db = db
            if cellid_flag == 1:
                # gps track and cellid track
                track = self.db.query("SELECT id, latitude, longitude, clatitude,"
                                      "       clongitude, timestamp, name,"
                                      "       type, speed, degree, locate_error"
                                      "  FROM T_LOCATION"
                                      "  WHERE tid = %s"
                                      "    AND NOT (latitude = 0 OR longitude = 0)"
                                      "    AND (timestamp BETWEEN %s AND %s)"
                                      "    GROUP BY timestamp"
                                      "    ORDER BY timestamp",
                                      self.current_user.tid, start_time, end_time)

            else:
                # cellid_flag is None or 0, only gps track
                track = self.db.query("SELECT id, latitude, longitude, clatitude,"
                                      "       clongitude, timestamp, name, "
                                      "       type, speed, degree, locate_error"
                                      "  FROM T_LOCATION"
                                      "  WHERE tid = %s"
                                      "    AND NOT (latitude = 0 OR longitude = 0)"
                                      "    AND (timestamp BETWEEN %s AND %s)"
                                      "    AND type = 0"
                                      "    GROUP BY timestamp"
                                      "    ORDER BY timestamp",
                                      self.current_user.tid, start_time, end_time)

            # check track point count
            if track and len(track) > 500 and network_type == 0:
                logging.info("[UWEB] The %s track points length is: %s, "
                             "  and the newtork type is too low, so return error.", 
                             tid, len(track))
                self.write_ret(ErrorCode.TRACK_POINTS_TOO_MUCH)
                self.finish()
                return

            # NOTE: if latlons are legal, but clatlons are illlegal, offset
            # them and update them in db.
            _start_time = time.time()
            track = get_locations_with_clatlon(track, self.db)
            _now_time = time.time()
            if _now_time - _start_time > 3:  # 3 seconds
                logging.info("[UWEB] Track offset used time: %s s, tid: %s, cid: %s",
                             _now_time - _start_time, self.current_user.tid, self.current_user.cid)

            # NOTE: filter point without valid clat and clon
            _track = []
            for t in track:
                if t['clongitude'] and ['clatitude']:
                    _track.append(t)
                else:
                    logging.info("[UWEB] Invalid point: %s, drop it, cid: %s",
                                 t, self.current_user.cid)
            track = _track

            # add idle_points
            # track1, track2, track3,...
            # when the distance between two points is larger than 10 meters and the interval is less than 5 minutes,
            # they are regarded as idle_points
            idle_lst = []
            idle_points = []
            for i, item_start in enumerate(track):
                is_idle = False
                if i in idle_lst:
                    continue
                for j in range(i + 1, len(track)):
                    item_end = track[j]
                    distance = get_distance(
                        item_start.clongitude, item_start.clatitude, item_end.clongitude, item_end.clatitude)
                    if distance >= UWEB.IDLE_DISTANCE:
                        break
                    else:
                        idle_time = item_end[
                            'timestamp'] - item_start['timestamp']
                        item_start['idle_time'] = idle_time
                        item_start['start_time'] = item_start['timestamp']
                        item_start['end_time'] = item_end['timestamp']
                        idle_lst.append(j)
                        is_idle = True
                if is_idle and item_start['idle_time'] > UWEB.IDLE_INTERVAL:
                    idle_points.append(item_start)

            # modify name & degere
            for item in track:
                item['degree'] = float(item['degree'])
                if item.name is None:
                    item['name'] = ''

            # organize and store the data to be downloaded
            m = hashlib.md5()
            m.update(self.request.body)
            hash_ = m.hexdigest()
            mem_key = self.KEY_TEMPLATE % (self.current_user.uid, hash_)

            res = []
            if idle_lst:
                point_begin = dict(label=u'起点',
                                   start_time=utc_to_date(
                                       track[0]['timestamp']),
                                   end_time='',
                                   name=track[0]['name'])
                point_idle = []
                for idle_point in idle_points:
                    idle_label = seconds_to_label(idle_point['idle_time'])
                    label = u'停留' + idle_label
                    point = dict(label=label,
                                 start_time=utc_to_date(
                                     idle_point['start_time']),
                                 end_time=utc_to_date(idle_point['end_time']),
                                 name=idle_point['name'])
                    point_idle.append(point)
                point_end = dict(label=u'终点',
                                 start_time=utc_to_date(
                                     track[-1]['timestamp']),
                                 end_time='',
                                 name=track[-1]['name'])
                res.append(point_begin)
                res.append(point_end)
                res.extend(point_idle)

                self.redis.setvalue(mem_key, res, time=UWEB.STATISTIC_INTERVAL)

            logging.info(
                "[UEB] Tid:%s track query, returned %s points.", self.current_user.tid, len(track))
            self.write_ret(status,
                           dict_=DotDict(track=track,
                                         idle_points=idle_points,
                                         hash_=hash_))
            self.finish()
Пример #4
0
    def handle_stop(self, pvt):
        """Handle the stop point.
        """
        flag = self.check_timestamp(int(pvt['gps_time']))
        if not flag: 
            return

        tid = pvt['dev_id']
        stop_key = get_stop_key(tid)
        stop = self.redis.getvalue(stop_key)

        distance_key = get_distance_key(tid)
        distance = self.redis.get(distance_key)
        if not distance:
            distance = 0

        last_pvt_key = get_last_pvt_key(tid) 
        last_pvt = self.redis.getvalue(last_pvt_key)
        if last_pvt:
            distance = float(distance) + lbmphelper.get_distance(int(last_pvt["lon"]), int(last_pvt["lat"]), 
                                     int(pvt["lon"]),
                                     int(pvt["lat"]))
            self.redis.setvalue(distance_key, distance, time=EVENTER.STOP_EXPIRY)

        if pvt['speed'] > LIMIT.SPEED_LIMIT: # is moving
            if stop: #NOTE: time_diff is too short, drop the point. 
                if pvt["gps_time"] - stop['start_time'] < 60: # 60 seconds 
                    _stop = self.db.get("SELECT distance FROM T_STOP WHERE lid =%s", stop['lid'])
                    if _stop: 
                        tmp_dis = _stop['distance'] 
                    else: 
                        tmp_dis = 0 
                    distance = float(distance) + tmp_dis

                    self.db.execute("DELETE FROM T_STOP WHERE lid = %s",
                                    stop['lid'])
                    self.redis.delete(stop_key)
                    self.redis.setvalue(distance_key, distance, time=EVENTER.STOP_EXPIRY)
                    logging.info("[EVENTER] Stop point is droped: %s", stop)
                else: # close a stop point
                    self.redis.delete(stop_key)
                    self.db.execute("UPDATE T_STOP SET end_time = %s WHERE lid = %s",
                                    pvt["gps_time"], stop['lid'])
                    logging.info("[EVENTER] Stop point is closed: %s", stop)
            else:
                pass
        else: # low speed, may stop
            if stop: 
                logging.info("[EVENTER] Stop point is updated: %s", stop)
                stop['end_time'] = pvt["gps_time"]
                self.redis.setvalue(stop_key, stop, time=EVENTER.STOP_EXPIRY)
                logging.info("[EVENTER] Stop point is updated: %s", stop)
            else: # create a new stop point
                pvt = lbmphelper.handle_location(pvt, self.redis, cellid=True, db=self.db)
                lid = insert_location(pvt, self.db, self.redis) 
                stop = dict(lid=lid, 
                            tid=tid, 
                            start_time=pvt["gps_time"], 
                            end_time=0, 
                            pre_lon=pvt["lon"], 
                            pre_lat=pvt["lat"], 
                            distance=distance)

                self.db.execute("INSERT INTO T_STOP(lid, tid, start_time, distance) VALUES(%s, %s, %s, %s)",
                                lid, tid, pvt["gps_time"], distance)
                self.redis.setvalue(stop_key, stop, time=EVENTER.STOP_EXPIRY)

                self.redis.delete(distance_key)

                logging.info("[EVENTER] Stop point is created: %s", stop)
Пример #5
0
    def handle_mileage(self, pvt):
        """Check the mileage.
        """
        flag = self.check_timestamp(int(pvt['gps_time']))
        if not flag: 
            return

        #NOTE: record the mileage
        tid = pvt['dev_id']
        mileage_key = get_mileage_key(tid)
        mileage = self.redis.getvalue(mileage_key)
        if not mileage:
            logging.info("[EVENTER] Tid: %s, init mileage. pvt: %s.",
                          tid, pvt)
            mileage = dict(lat=pvt.get('lat'),
                           lon=pvt.get('lon'),
                           dis=0,
                           gps_time=pvt['gps_time'])
            self.redis.setvalue(mileage_key, mileage)
        else:
            if pvt['gps_time'] < mileage['gps_time']:
                logging.info("[EVENTER] Tid: %s, gps_time: %s is less than mileage['gps_time']: %s, drop it. pvt: %s, mileage: %s", 
                             tid,
                             pvt['gps_time'],
                             mileage['gps_time'], 
                             pvt, 
                             mileage)
                pass
            else:
                dis = lbmphelper.get_distance(int(mileage["lon"]), int(mileage["lat"]),  int(pvt["lon"]) , int(pvt["lat"]))

                # for mileage notification
                dis_current = mileage['dis'] +  dis 
                self.db.execute("UPDATE T_TERMINAL_INFO" 
                                "  SET distance_current = %s"
                                "  WHERE tid = %s",
                                dis_current, tid)

                logging.info("[EVENTER] Tid: %s, distance: %s. pvt: %s.",
                              tid, dis_current, pvt)

                mileage = dict(lat=pvt.get('lat'),
                               lon=pvt.get('lon'),
                               dis=dis_current,
                               gps_time=pvt['gps_time'])
                self.redis.setvalue(mileage_key, mileage)

                # for mileage junior statistic
                current_day = time.localtime(pvt['gps_time']) 
                day_start_time, day_end_time = start_end_of_day(current_day.tm_year, current_day.tm_mon, current_day.tm_mday)

                mileage_log = self.db.get("SELECT * FROM T_MILEAGE_LOG"
                                          "  WHERE tid = %s"
                                          "  AND timestamp = %s",
                                          tid, day_end_time)
                if mileage_log:
                    dis_day = mileage_log['distance'] + dis
                else:
                    self.db.execute("INSERT INTO T_MILEAGE_LOG(tid, timestamp)"
                                    "  VALUES(%s, %s)",
                                    tid, day_end_time)
                    dis_day = dis

                self.db.execute("INSERT INTO T_MILEAGE_LOG(tid, distance, timestamp)"
                                "  VALUES(%s, %s, %s)"
                                "  ON DUPLICATE KEY"
                                "  UPDATE distance=values(distance)",
                                tid, dis_day, day_end_time)
                logging.info("[EVENTER] Tid: %s, dis_day: %s. pvt: %s.",
                              tid, dis_day, pvt)
Пример #6
0
    def check_region_event(self, ori_location, region): 
        """Check enter or out region 

        workflow:
        get old_region_status accordinding to region and tid
        get old_region_time accordinding to region and tid
        check region_status according distance, then keep region_status in redis
        if not old_region_status:
            skip
        if old_region_time and location's gps_time <= old_region_time:
            skip
        check region event according to region_status and old_region_staus
        if region event:
            keep region_status, region_time in redis
        """
        if not (ori_location and region): 
            logging.info("[EVENTER] query data is invalid, ori_location: %s, region: %s, no check", 
                         ori_location, region)
            return None
        if not (ori_location['cLat'] and ori_location['cLon']):
            logging.info("[EVENTER] location is invalid, ori_location: %s, no check", 
                         ori_location)
            return None

        # BIG NOTE: python grammar, shallow copy will change origen data.
        location = copy.deepcopy(dict(ori_location))
        location = DotDict(location)

        old_region_status_key = get_region_status_key(location['dev_id'], region.region_id)
        old_region_status = self.redis.getvalue(old_region_status_key)

        old_region_time_key = get_region_time_key(location['dev_id'], region.region_id)
        old_region_time = self.redis.getvalue(old_region_time_key)

        if region.region_shape == UWEB.REGION_SHAPE.CIRCLE:
            # get distance beteween now location and the centre of the region 
            distance = lbmphelper.get_distance(region.region_longitude,
                                               region.region_latitude,
                                               location.cLon, 
                                               location.cLat)
            
            if distance >= region.region_radius:
                region_status = EVENTER.CATEGORY.REGION_OUT
                rname = EVENTER.RNAME.REGION_OUT
            else:
                region_status = EVENTER.CATEGORY.REGION_ENTER
                rname = EVENTER.RNAME.REGION_ENTER
        elif region.region_shape == UWEB.REGION_SHAPE.POLYGON:
            polygon = {'name':'',
                       'points':[]}
            points = region.points 
            point_lst = points.split(':') 
            for point in point_lst: 
               latlon = point.split(',') 
               dct = {'lat':float(latlon[0])/3600000, 
                      'lon':float(latlon[1])/3600000} 
               polygon['points'].append(dct)

            polygon['name'] = region.region_name

            if PtInPolygon(location, polygon):
                region_status = EVENTER.CATEGORY.REGION_ENTER
                rname = EVENTER.RNAME.REGION_ENTER
            else:
                region_status = EVENTER.CATEGORY.REGION_OUT
                rname = EVENTER.RNAME.REGION_OUT
        else: #NOTE: here should never occur. 
            logging.error("[EVENTER] unknow region_shape: %s, region: %s, skip it", 
                         region.region_shape, region)

        if old_region_time:
            if int(location['gps_time']) <= int(old_region_time):
                logging.info("[EVENTER] current location's gps_time: %s is not bigger than old_region_time: %s, skip it", 
                             location['gps_time'], old_region_time)
                return location
        
        # keep region status 
        self.redis.setvalue(old_region_status_key, region_status)
        logging.info("rname:%s, old status:%s, current status:%s, tid:%s",
                     safe_unicode(region.region_name), old_region_status, region_status, location['dev_id'])    

        if not old_region_status:
            logging.info("[EVENTER] old_region_status: %s is invalid, skip it", 
                         old_region_status)
            # skip the first region event
            return location

        # check region event
        if region_status != old_region_status:
            self.redis.setvalue(old_region_status_key, region_status)
            self.redis.setvalue(old_region_time_key, location['gps_time'])
            # 2: complete the location
            location['category'] = region_status
            location['t'] = EVENTER.INFO_TYPE.REPORT #NOTE: t is need
            location['rName'] = rname
            location['region'] = region 
            location['region_id'] = region.region_id

        return location
Пример #7
0
    def check_single_event(self, ori_location, single): 
        """Check enter or out single 

        workflow:
        get old_single_status accordinding to single and tid
        get old_single_time accordinding to single and tid
        check single_status according distance, then keep single_status in redis
        if not old_single_status:
            skip
        if old_single_time and location's gps_time <= old_region_time:
            skip
        check single event according to single_status and old_single_staus
        if single event:
            keep single_status, single_time in redis
        """
        if not (ori_location and single): 
            logging.info("[EVENTER] query data is invalid, ori_location: %s, single: %s, do not check.", 
                         ori_location, single)
            return None
        if not (ori_location['cLat'] and ori_location['cLon']):
            logging.info("[EVENTER] location is invalid, ori_location: %s, do not check.", 
                         ori_location)
            return None

        # BIG NOTE: python grammar, shallow copy will change origen data.
        location = copy.deepcopy(dict(ori_location))
        location = DotDict(location)

        old_single_status_key = get_single_status_key(location['dev_id'], single.single_id)
        old_single_status = self.redis.getvalue(old_single_status_key)

        old_single_time_key = get_single_time_key(location['dev_id'], single.single_id)
        old_single_time = self.redis.getvalue(old_single_time_key)

        if single.single_shape == UWEB.SINGLE_SHAPE.CIRCLE:
            # get distance beteween now location and the centre of the region 
            distance = lbmphelper.get_distance(single.single_longitude,
                                               single.single_latitude,
                                               location.cLon, 
                                               location.cLat)
            
            if distance >= single.single_radius:
                single_status = EVENTER.CATEGORY.SINGLE_OUT
                rname = EVENTER.RNAME.SINGLE_OUT
            else:
                single_status = EVENTER.CATEGORY.SINGLE_ENTER
                rname = EVENTER.RNAME.SINGLE_ENTER
        elif single.single_shape == UWEB.SINGLE_SHAPE.POLYGON:
            polygon = {'name':'',
                       'points':[]}
            points = single.points 
            point_lst = points.split(':') 
            for point in point_lst: 
               latlon = point.split(',') 
               dct = {'lat':float(latlon[0])/3600000, 
                      'lon':float(latlon[1])/3600000} 
               polygon['points'].append(dct)

            polygon['name'] = single.single_name

            if PtInPolygon(location, polygon):
                single_status = EVENTER.CATEGORY.SINGLE_ENTER
                rname = EVENTER.RNAME.SINGLE_ENTER
            else:
                single_status = EVENTER.CATEGORY.SINGLE_OUT
                rname = EVENTER.RNAME.SINGLE_OUT
        else: #NOTE: here should never occur. 
            logging.error("[EVENTER] unknow single_shape: %s, single: %s, skip it", 
                         single.single_shape, single)

        #NOTE: skip the time
        if old_single_time:
            if int(location['gps_time']) <= int(old_single_time):
                logging.info("[EVENTER] current location's gps_time: %s is not bigger than old_single_time: %s, skip it", 
                             location['gps_time'], old_single_time)
                return location
        
        logging.info('old_single_status_key: %s, single_status: %s', old_single_status_key, single_status)

        # keep region status 
        self.redis.setvalue(old_single_status_key, single_status)
        logging.info("rname:%s, old status:%s, current status:%s, tid:%s",
                     safe_unicode(single.single_name), old_single_status, single_status, location['dev_id'])    

        if not old_single_status:
            logging.info("[EVENTER] old_single_status: %s is invalid, skip it", 
                         old_single_status)
            # skip the first region event
            return location

        # check single event
        if single_status != old_single_status:
            self.redis.setvalue(old_single_status_key, single_status)
            self.redis.setvalue(old_single_time_key, location['gps_time'])

            # 2: complete the location
            location['category'] = single_status
            location['t'] = EVENTER.INFO_TYPE.REPORT #NOTE: t is need
            location['rName'] = rname
            location['single'] = single 
            location['single_id'] = single.single_id

            # 3. keep it in db
            # out first, then enter
            if single_status == EVENTER.CATEGORY.SINGLE_ENTER:
                single_event = self.db.get("SELECT id as seid, tid, sid, start_time, end_time" 
                                           "  FROM T_SINGLE_EVENT"
                                           "  WHERE tid = %s "
                                           "  AND sid = %s"
                                           "  AND start_time !=0"
                                           "  AND end_time = 0 "
                                           "  ORDER BY id DESC LIMIT 1",
                                           location['dev_id'],
                                           location['single_id'])

                if not single_event:
                    pass
                else:
                    self.db.execute("UPDATE T_SINGLE_EVENT"
                                    "  SET end_time = %s"
                                    "  WHERE id = %s",
                                    location['gps_time'],
                                    single_event['seid'])
            elif single_status == EVENTER.CATEGORY.SINGLE_OUT:
                last_pvt_key = get_last_pvt_key(location['dev_id'])
                last_pvt = self.redis.getvalue(last_pvt_key)
                if last_pvt:
                    gps_time = last_pvt['gps_time']
                else:
                    gps_time = location['gps_time']
                self.db.execute("INSERT INTO T_SINGLE_EVENT(tid, sid, start_time)" 
                                "  VALUES(%s, %s, %s)",
                                location['dev_id'], 
                                location['single_id'],
                                gps_time)
                
        return location
Пример #8
0
    def handle_stop(self, tid, start_time, end_time):

        track = self.get_track(tid, start_time, end_time)
        print 'track', len(track)
        cnt = 0  

        for i, pvt in enumerate(track):

            #print 'i: %s, speed: %s, pvt: %s' % (i, pvt['speed'], pvt)
            stop_key = 'test_stop_redis:%s' % tid
            stop = self.redis.getvalue(stop_key)

            distance_key = 'test_distance_redis:%s' % tid
            distance = self.redis.get(distance_key) 

            if not distance:
                distance = 0

            last_pvt_key = 'test_last_pvt_redis:%s' % tid
            last_pvt = self.redis.getvalue(last_pvt_key)

            if last_pvt:
                tmp = get_distance(int(last_pvt["longitude"]), int(last_pvt["latitude"]), 
                                                          int(pvt["longitude"]), int(pvt["latitude"])) 


                print 'tmp: %s, distance: %s' % (tmp, distance) 
                distance = float(distance) + tmp 
                print 'last distance: %s' % (distance) 
                #print 'add distance', i, pvt['id'], tmp, distance
                self.redis.setvalue(distance_key, distance, time=EVENTER.STOP_EXPIRY)

            if pvt['speed'] > LIMIT.SPEED_LIMIT: # 5  is moving
                if stop: #NOTE: time_diff is too short, drop the point. 
                    if pvt["timestamp"] - stop['start_time'] < 60: # 60 seconds 
                        cnt += 1  
                        _stop = self.db.get("select distance from T_STOP where lid =%s", stop['lid'])
                        if _stop:
                            tmp_dis = _stop['distance']
                        else:
                            tmp_dis = 0 
                        print 'tmp_dis', tmp_dis
                        distance = float(distance) + tmp_dis 
                        print 'tmp_dis distance', distance 

                        self.db.execute("DELETE FROM T_STOP WHERE lid = %s",
                                        stop['lid'])
                        self.redis.delete(stop_key)
                        self.redis.setvalue(distance_key, distance, time=EVENTER.STOP_EXPIRY) 
                        logging.info("[EVENTER] Stop point is droped: %s", stop)
                    else: # close a stop point
                        cnt += 1  
                        self.redis.delete(stop_key)
                        self.db.execute("UPDATE T_STOP SET end_time = %s WHERE lid = %s",
                                        pvt["timestamp"], stop['lid'])
                        logging.info("[EVENTER] Stop point is closed: %s", stop)
                else:
                    pass
            else: # low speed, may stop
                if stop: 
                    stop['end_time'] = pvt["timestamp"]
                    self.redis.setvalue(stop_key, stop, time=EVENTER.STOP_EXPIRY)
                    logging.info("[EVENTER] Stop point is updated: %s", stop)
                else: # NOTE: start stop. #NOTE:  create a new stop point
                    cnt += 1  
                    lid=pvt['id']
                    stop = dict(lid=lid,
                                tid=tid, 
                                start_time=pvt["timestamp"], 
                                end_time=0, 
                                pre_lon=pvt["longitude"], 
                                pre_lat=pvt["latitude"], 
                                distance=distance)

                    self.db.execute("INSERT INTO T_STOP(lid, tid, start_time, distance) VALUES(%s, %s, %s, %s)",
                                    lid, tid, pvt["timestamp"], distance)
                    self.redis.setvalue(stop_key, stop, time=EVENTER.STOP_EXPIRY)

                    self.redis.delete(distance_key)

                    logging.info("[EVENTER] Stop point is created: %s", stop)
            
            last_pvt = pvt 
            self.redis.setvalue(last_pvt_key, last_pvt, time=EVENTER.STOP_EXPIRY)
            print '---------------------- cnt', cnt
Пример #9
0
        def _on_finish(db):
            self.db = db
            page_count = int(data.pagecnt)
            if statistic_mode == 'all': # all
                if page_count == -1:
                    count = len(tids)
                    d, m = divmod(count, page_size)
                    page_count = (d + 1) if m else d

                reports = []                
                for item, tid in enumerate(tids):
                    seq=item+1
                    dis_sum = Decimal()  

                    start_date = get_date_from_utc(start_time)
                    end_date = get_date_from_utc(end_time)
                    start_day = datetime.datetime.fromtimestamp(start_time)
                    end_day = datetime.datetime.fromtimestamp(end_time)
                    # get how many days the end_time and start_time cover
                    days = abs(end_day-start_day).days+1
                    for item in range(days):
                        distance = Decimal()
                        timestamp = start_time+1*60*60*24*(item)
                        date = get_date_from_utc(timestamp)
                        year, month, day = date.year, date.month, date.day
                        start_time_, end_time_ = start_end_of_day(year=year, month=month, day=day)
                 
                        points = self.db.query("SELECT longitude, latitude FROM T_LOCATION"
                                               "  WHERE tid = %s"
                                               "    AND (timestamp BETWEEN %s AND %s)"
                                               "    AND type = 0"
                                               "  ORDER BY timestamp asc",
                                               tid, start_time_+start_period_, start_time_+end_period_)
                        for i in range(len(points)-1):
                            if points[i].longitude and points[i].latitude and \
                               points[i+1].longitude and points[i+1].latitude:
                               dis = get_distance(points[i].longitude, points[i].latitude,
                                                         points[i+1].longitude, points[i+1].latitude) 
                               distance += Decimal(str(dis))
                        # meter --> km
                        distance = '%0.1f' % (distance/1000,)
                        dis_sum += Decimal(distance)

                    alias = QueryHelper.get_alias_by_tid(tid, self.redis, self.db)
                    dct = dict(seq=seq,
                               alias=alias,
                               distance=float(dis_sum))
                    reports.append(dct)

                # orgnize and store the data to be downloaded 
                m = hashlib.md5()
                m.update(self.request.body)
                hash_ = m.hexdigest()
                mem_key = self.KEY_TEMPLATE % (self.current_user.uid, hash_)
                
                self.redis.setvalue(mem_key, (statistic_mode, reports, 0), time=UWEB.STATISTIC_INTERVAL)

                reports= reports[(page_number * page_size):((page_number+1) * page_size)]
                self.write_ret(status,
                               dict_=DotDict(res=reports,
                                             pagecnt=page_count,
                                             hash_=hash_))
            else: # single
                tid = tids[0]
                delta = end_time - start_time # end_time must bigger than start_time
                d, m = divmod(delta, 60*60*24) 
                start_date = get_date_from_utc(start_time)
                end_date = get_date_from_utc(end_time)
                start_day = datetime.datetime.fromtimestamp(start_time)
                end_day = datetime.datetime.fromtimestamp(end_time)
                # get how many days the end_time and start_time cover
                days = abs(end_day-start_day).days+1
                #if days == 0: 
                #    if start_date.day  == end_date.day:   
                #        days = 1
                #    else: 
                #        days = 2
                #else: 
                #    days = days+1 if m else days
                #    if end_day.hour*60*60 + end_day.minute*60 + end_day.second <  start_day.hour*60*60 + start_day.minute*60 + start_day.second:                   
                #        days = days+1 
  
                res = []
                graphics = [] 
                counts = []
                dis_sum = Decimal() 
                current_time = int(time.time()) 

                sql_cmd = ("SELECT longitude, latitude FROM T_LOCATION"
                           "  WHERE tid = %s"
                           "    AND (timestamp BETWEEN %s AND %s)"
                           "    AND type = 0"
                           "  ORDER BY timestamp asc")

                #last_cmd = ("SELECT timestamp FROM T_LOCATION"
                #            "  WHERE tid = %s"
                #            "    AND (timestamp BETWEEN %s AND %s)"
                #            "    AND type = 0"
                #            "  ORDER BY timestamp desc limit 1")

                #next_cmd = ("SELECT timestamp FROM T_LOCATION"
                #            "  WHERE tid = %s"
                #            "    AND (timestamp BETWEEN %s AND %s)"
                #            "    AND type = 0"
                #            "  ORDER BY timestamp asc limit 1")
                 
                if days == 1: # start_time, end_time in the same day
                    timestamp = start_time
                    date = get_date_from_utc(timestamp)

                    re = {} 
                    re['alias'] = '-'.join([str(date.year),str(date.month),str(date.day)]) 
                    distance = Decimal() 

                    points = self.db.query(sql_cmd, tid, start_time+start_period_, start_time+end_period_)
                    for i in range(len(points)-1):
                        if points[i].longitude and points[i].latitude and \
                           points[i+1].longitude and points[i+1].latitude:
                            dis = get_distance(points[i].longitude, points[i].latitude,
                                               points[i+1].longitude, points[i+1].latitude) 
                            distance += Decimal(str(dis)) 
                    # meter --> km
                    distance = '%0.1f' % (distance/1000,)      
                        
                    graphics.append(float(distance))
                    dis_sum += Decimal(distance)

                    re['distance'] = distance 
                    re['seq'] = 1 
                    res.append(re)
                else: # start_time, end_time in different days
                    for item in range(days):
                        timestamp = start_time+1*60*60*24*(item)
                        date = get_date_from_utc(timestamp)
                        year, month, day = date.year, date.month, date.day
                        start_time_, end_time_ = start_end_of_day(year=year, month=month, day=day)
                        ## handle the first day and last day
                        #if item == 0: 
                        #    start_time_ = start_time
                        #if item == days: 
                        #    end_time_ = end_time
                        #last_point = self.db.get(last_cmd, tid, start_time_-60*60*24, start_time_,)
                        #next_point = self.db.get(next_cmd, tid, end_time_, end_time_+60*60*24)
                        #start_time_ = last_point['timestamp'] if last_point else start_time_
                        #end_time_ = next_point['timestamp'] if next_point else end_time_

                        re = {} 
                        re['alias'] = '-'.join([str(year),str(month),str(day)]) 
                        distance = Decimal() 
                        points = self.db.query(sql_cmd, tid, start_time_+start_period_, start_time_+end_period_)
                        for i in range(len(points)-1):
                            if points[i].longitude and points[i].latitude and \
                               points[i+1].longitude and points[i+1].latitude:
                                dis = get_distance(points[i].longitude, points[i].latitude,
                                                   points[i+1].longitude, points[i+1].latitude) 
                                distance += Decimal(str(dis)) 
                        # meter --> km
                        distance = '%0.1f' % (distance/1000,)      
                            
                        graphics.append(float(distance))
                        dis_sum += Decimal(distance)

                        re['distance'] = distance 
                        re['seq'] = item+1 
                        res.append(re)

                counts = [float(dis_sum),]

                if page_count == -1:
                    items_count = len(res) 
                    d, m = divmod(items_count, page_size) 
                    page_count = (d + 1) if m else d
    
                # store resutl in redis
                m = hashlib.md5()
                m.update(self.request.body)
                hash_ = m.hexdigest()
                mem_key = self.KEY_TEMPLATE % (self.current_user.uid, hash_)
                
                self.redis.setvalue(mem_key, (statistic_mode, res, counts,), time=UWEB.STATISTIC_INTERVAL)
    
                res= res[page_number*page_size:(page_number+1)*page_size]
                self.write_ret(status, 
                               dict_=dict(res=res, 
                                          counts=counts,
                                          graphics=graphics,
                                          pagecnt=page_count,
                                          hash_=hash_)) 
            self.finish()
Пример #10
0
    def post(self):
        """Provide statistics about terminal.
        """
        status = ErrorCode.SUCCESS
        try:
            data = DotDict(json_decode(self.request.body))
            logging.info("[UWEB] statistic request: %s, uid: %s, tid: %s", 
                         data, self.current_user.uid, self.current_user.tid)
        except Exception as e:
            status = ErrorCode.ILLEGAL_DATA_FORMAT
            self.write_ret(status)
            return

        try:
            page_size = UWEB.LIMIT.PAGE_SIZE_STATISTICS
            page_number = int(data.pagenum)
            page_count = int(data.pagecnt)
            tid = data.tid
           
            res = []
            graphics = []
            counts = []
            label = u''
           
            sql_cmd = ("SELECT longitude, latitude FROM T_LOCATION"
                       "  WHERE tid = %s"
                       "    AND (timestamp BETWEEN %s AND %s)"
                       "    AND type = 0"
                       "  ORDER BY timestamp asc")

            last_cmd = ("SELECT timestamp FROM T_LOCATION"
                        "  WHERE tid = %s"
                        "    AND (timestamp BETWEEN %s AND %s)"
                        "    AND type = 0"
                        "  ORDER BY timestamp desc limit 1")

            next_cmd = ("SELECT timestamp FROM T_LOCATION"
                        "  WHERE tid = %s"
                        "    AND (timestamp BETWEEN %s AND %s)"
                        "    AND type = 0"
                        "  ORDER BY timestamp asc limit 1")

            dis_sum = Decimal() 
            
            current_time = int(time.time()) 

            statistics_type = data.statistics_type
            if statistics_type == UWEB.STATISTICS_TYPE.YEAR:
                label = data.year + u'年' 
                start_time, end_time = start_end_of_year(year=data.year)
                for month in range(1,12+1):
                    start_time_, end_time_ = start_end_of_month(year=data.year, month=str(month))
                    if start_time_ > current_time:
                        break

                    re = {} 
                    re['name'] = str(month)
                    distance = Decimal() 
                    points = self.db.query(sql_cmd, tid, start_time_, end_time_)
                    for i in range(len(points)-1):
                        if points[i].longitude and points[i].latitude and \
                           points[i+1].longitude and points[i+1].latitude:
                            dis = get_distance(points[i].longitude, points[i].latitude,
                                               points[i+1].longitude, points[i+1].latitude) 
                            distance += Decimal(str(dis)) 
                    # meter --> km
                    distance = '%0.1f' % (distance/1000,)      
                    if float(distance) == 0:
                        distance = 0
                        
                    graphics.append(float(distance))
                    dis_sum += Decimal(distance)

                    re['mileage'] = distance 
                    res.append(re)

                counts = [float(dis_sum),]

            elif statistics_type == UWEB.STATISTICS_TYPE.MONTH:
                label = data.year + u'年' + data.month + u'月'
                start_time, end_time = start_end_of_month(year=data.year, month=data.month)
                days = days_of_month(year=data.year, month=data.month)

                distance = Decimal() 
                points_ = self.db.query(sql_cmd, tid, start_time, end_time)
                for i in range(len(points_)-1):
                    if points_[i].longitude and points_[i].latitude and \
                        points_[i+1].longitude and points_[i+1].latitude:
                        dis = get_distance(points_[i].longitude, points_[i].latitude, 
                            points_[i+1].longitude, points_[i+1].latitude)
                        dis=Decimal(str(dis))
                        distance += dis

                distance = '%0.1f' % (distance/1000,)
                dis_sum = distance

                for day in range(1,days+1):
                    start_time_, end_time_ = start_end_of_day(year=data.year, month=data.month, day=str(day))
                    if start_time_ > current_time:
                        break

                    last_point = self.db.get(last_cmd, tid, start_time_-60*60*24, start_time_,)
                    next_point = self.db.get(next_cmd, tid, end_time_, end_time_+60*60*24)
                    start_time_ = last_point['timestamp'] if last_point else start_time_
                    end_time_ = next_point['timestamp'] if next_point else end_time_

                    re = {} 
                    re['name'] = str(day)
                    distance = Decimal() 
                    points = self.db.query(sql_cmd, tid, start_time_, end_time_)
                    for i in range(len(points)-1):
                        if points[i].longitude and points[i].latitude and \
                           points[i+1].longitude and points[i+1].latitude:
                            dis = get_distance(points[i].longitude, points[i].latitude,
                                               points[i+1].longitude, points[i+1].latitude) 
                            distance += Decimal(str(dis)) 
                    # meter --> km
                    distance = '%0.1f' % (distance/1000,)      
                    if float(distance) == 0:
                        distance = 0

                    graphics.append(float(distance))
                        
                    re['mileage'] = distance 
                    res.append(re)

                counts = [float(dis_sum),]

            else:
                logging.error("[UWEB] Error statistics type: %s", statistics_type)
            
            
            if page_count == -1:
                items_count = len(res) 
                d, m = divmod(items_count, page_size) 
                page_count = (d + 1) if m else d

      
            # store resutl in redis
            m = hashlib.md5()
            m.update(self.request.body)
            hash_ = m.hexdigest()
            mem_key = self.KEY_TEMPLATE % (self.current_user.uid, hash_)
            
            self.redis.setvalue(mem_key, (res, counts, label, statistics_type), time=UWEB.STATISTIC_INTERVAL)

            res= res[page_number*page_size:(page_number+1)*page_size]

            self.write_ret(status, 
                           dict_=dict(res=res, 
                                      counts=counts,
                                      graphics=graphics,
                                      pagecnt=page_count,
                                      hash_=hash_)) 
        except Exception as e:
            logging.exception("[UWEB] uid:%s, tid:%s statistic failed. Exception: %s",
                              self.current_user.uid, self.current_user.tid, e.args)
            status = ErrorCode.SERVER_BUSY
            self.write_ret(status)