def get_appid(): #return config_common.WXAPP_ID if not config_common.WXAPP_ID: raise ApplicationException(errcode=ERROR_MISSING_WXAPP_ID, ) return config_common.WXAPP_ID
def get_appsecret(): if not config_common.WXAPP_SECRET: raise ApplicationException(errcode=ERROR_MISSING_WXAPP_SECRET, ) return config_common.WXAPP_SECRET
async def get_similar_trajectories2(self, mmsi: int, from_date: Optional[datetime] = None, to_date: Optional[datetime] = None, distance_in_km: float = 5) -> List[dict]: pipeline = [ { '$match': { 'mmsi': mmsi, 'timestamp': { '$gte': from_date, '$lt': to_date } } }, { '$sort': { 'timestamp': 1 } }, { '$group': { '_id': '$mmsi', 'locations': { '$push': '$location' } } }, { '$project': { '_id': 0, 'type': 'lineString', 'locations': { '$map': { 'input': '$locations', 'as': 'location', 'in': '$$location.coordinates' } } } }, ] vessel_trajectories = await self.db[self.dynamic_collection].aggregate(pipeline).to_list(length=None) if not len(vessel_trajectories): raise ApplicationException(404, "Trajectory Of this vessel was not found within this time limits") vessel_trajectory = vessel_trajectories[0] locations_count = len(vessel_trajectory['locations']) if not locations_count: raise ApplicationException(400, "Empty trajectory") polygon = polygon_from_line_string(vessel_trajectory['locations'], distance_in_km) # last = vessel_trajectory['locations'][-1] # first = vessel_trajectory['locations'][0] # return { # 'type': 'Feature', # 'geometry': { # 'type': 'Polygon', # 'coordinates': polygon # } # } f = from_date - timedelta(days = 10) t = to_date + timedelta(days = 10) pipeline = [ { '$match': { 'mmsi': {'$ne': mmsi}, 'timestamp': { '$gte': f, '$lt': t }, 'location': { '$geoWithin': { '$geometry': { 'type': "Polygon" , 'coordinates': polygon } } } } }, {'$sort': {'timestamp': 1}}, { '$group': { '_id': '$mmsi', 'locations': { '$push': '$location' }, 'start': {'$first': '$timestamp'}, 'end': {'$last': '$timestamp'} } }, { '$project': { '_id': 0, 'type': 'lineString', 'mmsi': '$_id', 'locations': { '$map': { 'input': '$locations', 'as': 'location', 'in': '$$location.coordinates' } }, 'start': 1, 'end': 1 } }, { '$match': { '$expr': { '$function': { 'body': """function(vessel, v){ ( function() { function DynamicTimeWarping ( ts1, ts2, distanceFunction ) { var ser1 = ts1; var ser2 = ts2; var distFunc = distanceFunction; var distance; var matrix; var path; var getDistance = function() { if ( distance !== undefined ) { return distance; } matrix = []; for ( var i = 0; i < ser1.length; i++ ) { matrix[ i ] = []; for ( var j = 0; j < ser2.length; j++ ) { var cost = Infinity; if ( i > 0 ) { cost = Math.min( cost, matrix[ i - 1 ][ j ] ); if ( j > 0 ) { cost = Math.min( cost, matrix[ i - 1 ][ j - 1 ] ); cost = Math.min( cost, matrix[ i ][ j - 1 ] ); } } else { if ( j > 0 ) { cost = Math.min( cost, matrix[ i ][ j - 1 ] ); } else { cost = 0; } } matrix[ i ][ j ] = cost + distFunc( ser1[ i ], ser2[ j ] ); } } return matrix[ ser1.length - 1 ][ ser2.length - 1 ]; }; this.getDistance = getDistance; var getPath = function() { if ( path !== undefined ) { return path; } if ( matrix === undefined ) { getDistance(); } var i = ser1.length - 1; var j = ser2.length - 1; path = [ [ i, j ] ]; while ( i > 0 || j > 0 ) { if ( i > 0 ) { if ( j > 0 ) { if ( matrix[ i - 1 ][ j ] < matrix[ i - 1 ][ j - 1 ] ) { if ( matrix[ i - 1 ][ j ] < matrix[ i ][ j - 1 ] ) { path.push( [ i - 1, j ] ); i--; } else { path.push( [ i, j - 1 ] ); j--; } } else { if ( matrix[ i - 1 ][ j - 1 ] < matrix[ i ][ j - 1 ] ) { path.push( [ i - 1, j - 1 ] ); i--; j--; } else { path.push( [ i, j - 1 ] ); j--; } } } else { path.push( [ i - 1, j ] ); i--; } } else { path.push( [ i, j - 1 ] ); j--; } } path = path.reverse(); return path; }; this.getPath = getPath; } var root = typeof self === "object" && self.self === self && self || typeof global === "object" && global.global === global && global || this; if ( typeof exports !== "undefined" && !exports.nodeType ) { if ( typeof module !== "undefined" && !module.nodeType && module.exports ) { exports = module.exports = DynamicTimeWarping; } exports.DynamicTimeWarping = DynamicTimeWarping; } else { root.DynamicTimeWarping = DynamicTimeWarping; } if ( typeof define === "function" && define.amd ) { define( "dynamic-time-warping", [], function() { return DynamicTimeWarping; } ); } }() ); var dtw = new DynamicTimeWarping(v, vessel, function(v_coord, vessel_coord){ var lat1 = v_coord[1] var lon1 = v_coord[0] var lat2 = vessel_coord[1] var lon2= vessel_coord[0] var R = 6371e3; // metres var φ1 = lat1 * Math.PI/180; // φ, λ in radians var φ2 = lat2 * Math.PI/180; var Δφ = (lat2-lat1) * Math.PI/180; var Δλ = (lon2-lon1) * Math.PI/180; var a = Math.sin(Δφ/2) * Math.sin(Δφ/2) + Math.cos(φ1) * Math.cos(φ2) * Math.sin(Δλ/2) * Math.sin(Δλ/2); var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); var d = R * c; // in metres return d }); var path = dtw.getPath() //return path.length > (0.7 * vessel.length) return ((dtw.getDistance() / path.length) < 2000) && (path.length > (0.7 * vessel.length)) && (path.length > (1.2 * vessel.length)); }""", 'args': [vessel_trajectory["locations"], '$locations'], 'lang': 'js' } } } }, { '$project': { # Convert to GeoJson '_id': 0, 'type': 'Feature', 'geometry': { 'type': 'LineString', 'coordinates': '$locations' }, 'properties': { 'mmsi': '$mmsi', 'start': '$start', 'end': '$end' }, } } ] return await self.db[self.dynamic_collection].aggregate(pipeline, hint="location_m", allowDiskUse=True).to_list(length=None)
def wapper(self, *args, **kwargs): _logger.debug('-----------user registing-----------') token = request.environ.get('HTTP_{}'.format( get_token_header_field().upper())) content_type = request.environ.get('CONTENT_TYPE') _logger.debug({'content_type': content_type, 'token': token}) if not content_type or not content_type.lower() == 'application/json': raise ApplicationException(errcode=ERROR_CONTENT_TYPE_NOT_JSON, ) if not token: raise ApplicationException(errcode=ERROR_REGISTER_MISSING_TOKEN, ) #params = request.form params = request.json _logger.debug(params) encryptedData_field_name = get_update_encryptedData_field_name() iv_field_name = get_update_iv_field_name() if not params.get(iv_field_name) or not params.get( encryptedData_field_name): raise ApplicationException( errcode=ERROR_REGISTER_MISSING_IV_OR_ENCRYPTED, ) iv = params.get(iv_field_name) encryptedData = params.get(encryptedData_field_name) result_token = decrypt_token(token) openid = result_token['openid'] try: user = User.objects.get(openid=openid) except: raise ApplicationException( errcode=ERROR_REGISTER_MISSING_IV_OR_ENCRYPTED, ) session_key = user.session_key #session_key = 'HKUOhvaNYvMxGCt2BpjfJg==' result_userinfo = decrypt(session_key=session_key, iv=iv, encrypted=encryptedData) user = User.objects(openid=user.openid).update_one( session_key=session_key, nickname=result_userinfo.get('nickName'), avatar=result_userinfo.get('avatarUrl'), gender=result_userinfo.get('gender'), city=result_userinfo.get('city'), province=result_userinfo.get('province'), country=result_userinfo.get('country'), language=result_userinfo.get('language'), mobile=result_userinfo.get('mobile'), last_login_ts=now_ts()) user = User.objects.get(openid=openid) self.wechat_user = user return func(self, *args, **kwargs)
async def knn(self, mmsi: str, when: datetime, max_distance: float = 1000, dt: int = 1, k: int=None): location_pipeline = [ { '$match': { 'mmsi': mmsi, 'timestamp': { '$gte': when - timedelta(seconds=30), '$lt': when + timedelta(seconds=30) } } }, {'$limit': 1}, { '$project': { "_id": 0, "location": 1 } } ] locations = await self.db[self.dynamic_collection].aggregate(location_pipeline).to_list(length=None) if not len(locations): raise ApplicationException(404, "No location for this mmsi in this location") location = locations[0]['location'] pipeline = [ { '$geoNear': { 'near': location, 'distanceField': 'dist.calculated', 'maxDistance': max_distance, 'query': { 'mmsi': {"$ne": mmsi}, # 'timestamp': when 'timestamp': { '$gte': when - timedelta(minutes=dt), '$lt': when + timedelta(minutes=dt) } }, 'includeLocs': 'dist.location', 'key': 'location', 'spherical': True } }, { '$sort': { 'mmsi': 1, 'dist.calculated': 1 } }, { '$group': { '_id': '$mmsi', 'locations': {'$first': '$dist'}, 'timestamp': {'$first': '$timestamp'} } }, { '$project': { '_id': 0, 'type': 'Feature', 'geometry': { 'type': 'Point', 'coordinates': '$locations.location.coordinates' }, 'properties': { 'mmsi': "$_id", 'timestamp': '$timestamp', 'minDist': '$locations.calculated' } } }] if k: pipeline += [ { '$sort': { 'properties.minDist': 1 } }, {'$limit': k}, ] return await self.db[self.dynamic_collection].aggregate(pipeline).to_list(length=None)
async def get_similar_trajectories(self, mmsi: int, from_date: Optional[datetime] = None, to_date: Optional[datetime] = None, distance_in_km: float = 5) -> List[dict]: pipeline = [ { '$match': { 'mmsi': mmsi, 'timestamp': { '$gte': from_date, '$lt': to_date } } }, { '$sort': { 'timestamp': 1 } }, { '$group': { '_id': '$mmsi', 'locations': { '$push': '$location' } } }, { '$project': { '_id': 0, 'type': 'lineString', 'locations': { '$map': { 'input': '$locations', 'as': 'location', 'in': '$$location.coordinates' } } } }, ] vessel_trajectories = await self.db.dynamic_data.aggregate(pipeline).to_list(length=None) if not len(vessel_trajectories): raise ApplicationException(404, "Trajectory Of this vessel was not found within this time limits") vessel_trajectory = vessel_trajectories[0] locations_count = len(vessel_trajectory['locations']) if not locations_count: raise ApplicationException(400, "Empty trajectory") polygon = polygon_from_line_string(vessel_trajectory['locations'], distance_in_km) last = vessel_trajectory['locations'][-1] first = vessel_trajectory['locations'][0] f = from_date - timedelta(days = 10) t = to_date + timedelta(days = 10) # return { # 'type': 'Feature', # 'geometry': { # 'type': 'Polygon', # 'coordinates': polygon # }, # 'properties': {} # } pipeline = [ { '$match': { 'mmsi': {'$ne': mmsi}, 'timestamp': { '$gte': f, '$lt': t }, 'location': { '$geoWithin': { '$geometry': { 'type': "Polygon" , 'coordinates': polygon } } } } }, {'$sort': {'timestamp': 1}}, { '$group': { '_id': "$mmsi", 'trajectories': { '$accumulator': { 'init': "function() { return [[]] }", 'accumulate': """function(state, location, timestamp) { var calc_dist = function(v_coord, vessel_coord){ var lat1 = v_coord[1] var lon1 = v_coord[0] var lat2 = vessel_coord[1] var lon2= vessel_coord[0] var R = 6371e3; // metres var φ1 = lat1 * Math.PI/180; // φ, λ in radians var φ2 = lat2 * Math.PI/180; var Δφ = (lat2-lat1) * Math.PI/180; var Δλ = (lon2-lon1) * Math.PI/180; var a = Math.sin(Δφ/2) * Math.sin(Δφ/2) + Math.cos(φ1) * Math.cos(φ2) * Math.sin(Δλ/2) * Math.sin(Δλ/2); var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); var d = R * c; // in metres return d } var l = state.slice(-1)[0] if(l.length == 0){ l.push({coordinates: location.coordinates, timestamp: timestamp}) } else { var llt = l.slice(-1)[0].timestamp var diff =(timestamp.getTime() - llt.getTime()) / 1000; diff /= 10; if(diff > 60) { state.push([{coordinates: location.coordinates, timestamp: timestamp}]) } else { llc = l.slice(-1)[0].coordinates var dist = calc_dist(location.coordinates, llc) if(dist > 10) { l.push({coordinates: location.coordinates, timestamp: timestamp}) } } } return state }""", 'accumulateArgs': ["$location", "$timestamp"], 'merge': "function(state1, state2) { return state1.concat(state2) }" } } } }, # { # '$project': { # '_id': 0, # 'mmsi': "$_id", # 'trajectories': { # '$filter': { # "input": "$trajectories", # "as": "trajectory", # "cond": {'$gt': [{'$size': "$$trajectory"}, int(locations_count * 0.8)]} # } # } # } # }, { '$project': { '_id': 0, 'mmsi': "$_id", 'trajectories': '$trajectories' } }, ] r = await self.db.dynamic_data.aggregate(pipeline, hint="location_m", allowDiskUse=True).to_list(length=None) result = [] def calc_dist(lon1, lat1, lon2, lat2, cutoff=500): """ Calculate the great circle distance between two points on the earth (specified in decimal degrees) """ # convert decimal degrees to radians lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2]) # haversine formula dlon = lon2 - lon1 dlat = lat2 - lat1 a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2 c = 2 * asin(sqrt(a)) r = 6371100 # Radius of earth in m d = c * r if d > cutoff: return None return True def transform(trajectory): traject = [ pair["coordinates"] for pair in trajectory ] en = False st = False for pair in traject: if st and en: break if not st: if calc_dist(pair[0], pair[1], first[0], first[1], 500): st = True if not en: if calc_dist(pair[0], pair[1], last[0], last[1], 500): en = True # en = calc_dist(traject[-1][0], traject[-1][1], last[0], last[1], 500) # st = calc_dist(traject[0][0], traject[0][1], first[0], first[1], 500) return st and en and traject for ship in r: coordinates = [ transform(trajectory) for trajectory in ship["trajectories"]] coordinates = [ t for t in coordinates if t] o = { 'type': 'Feature', 'geometry': { 'type': "MultiLineString", 'coordinates': coordinates }, 'properties': { 'mmsi': ship["mmsi"] } } if len(coordinates): result.append(o) return result
def wrapper(self, request, *args, **kwargs): _logger.debug(request.__dict__) _logger.debug('-----------user logining------------') content_type = request.environ.get('CONTENT_TYPE') if not content_type or not content_type.lower() == 'application/json': raise ApplicationException( errcode=ERROR_CONTENT_TYPE_NOT_JSON, ) code_field_name = get_login_code_field_name() #params = request.form #params = request.json # flask-wechat-utils #params = json.loads(request.body) # django params = request.data # rest framework _logger.debug(params) code = params.get(code_field_name) _logger.debug({'content_type':content_type,'code':code}) if not code: raise ApplicationException( errcode=ERROR_LOGIN_CODE_MISSING, ) result_login = get_session_key_from_weixin( appid=get_appid(), appsecret=get_appsecret(), js_code=params.get(code_field_name) ) #success if result_login.get('session_key') and result_login.get('openid'): try: user = User.objects.get(openid=result_login['openid']) except: user = None #create if not user: try: User.objects.create( session_key=result_login['session_key'], openid=result_login['openid'], last_login_ts=now_ts() ).save() except: raise ApplicationException( errcode=ERROR_LOGIN_MONGO_CREATE_FAIL, ) #update else: try: user.session_key=result_login.get('session_key') user.last_login_ts=now_ts() user.last_ping_ts=now_ts() user.save() except: raise ApplicationException( errcode=ERROR_LOGIN_MONGO_UPDATE_FAIL, ) user = User.objects.get(openid=result_login['openid']) userinfo = {} for key in get_token_fields_required(): value = getattr(user,key) userinfo[key] = value request.wechat_user_token = encrypt_token(userinfo) request.wechat_user = user # #fail # elif result_login.get('errcode') == 45011: # raise ApplicationException( # errcode=ERROR_LOGIN_CODE_FREQUENCY_LIMIT, # ) # elif result_login.get('errcode') == -1: # raise ApplicationException( # errcode=ERROR_LOGIN_CODE_WEIXIN_BUSY, # ) # elif result_login.get('errcode') == 40029: # raise ApplicationException( # errcode=ERROR_LOGIN_CODE_LOST_EFFECT, # ) else: _logger.debug(result_login) raise ApplicationException( errcode=ERROR_LOGIN_CODE_NO_WHY, ) return func(self, request, *args, **kwargs)
def get_token_salt(): if not isinstance(config_common.TOKEN_SALT, str): raise ApplicationException( errcode=ERROR_CONFIG_TOKEN_SALT_WRONG, ) return config_common.TOKEN_SALT
def get_update_iv_field_name(): if not isinstance(config_common.UPDATE_IV_FIELD_NAME, str): raise ApplicationException( errcode=ERROR_CONFIG_UPDATE_IV_FIELD_NAME_WRONG, ) return config_common.UPDATE_IV_FIELD_NAME
def get_update_encryptedData_field_name(): if not isinstance(config_common.UPDATE_ENCRYPTEDDATA_FIELD_NAME, str): raise ApplicationException( errcode=ERROR_CONFIG_UPDATE_ENCRYPTEDDATA_FIELD_NAME_WRONG, ) return config_common.UPDATE_ENCRYPTEDDATA_FIELD_NAME
def get_login_code_field_name(): if not isinstance(config_common.LOGIN_CODE_FIELD_NAME, str): raise ApplicationException( errcode=ERROR_CONFIG_LOGIN_CODE_FIELD_NAME_WRONG, ) return config_common.LOGIN_CODE_FIELD_NAME
def get_token_header_field(): if not isinstance(config_common.TOKEN_HEADER_FIELD, str): raise ApplicationException( errcode=ERROR_CONFIG_TOKEN_HEADER_FIELD_WRONG, ) return config_common.TOKEN_HEADER_FIELD
def get_token_fields_required(): if not isinstance(config_common.TOKEN_FIELDS_REQUIRED, list): raise ApplicationException( errcode=ERROR_CONFIG_TOKEN_FIELDS_REQUIRED_WRONG, ) return config_common.TOKEN_FIELDS_REQUIRED
def get_web_name(): if not isinstance(config_common.WEB_NAME, str): raise ApplicationException(errcode=ERROR_CONFIG_WEB_NAME_WRONG, ) return config_common.WEB_NAME
def wrapper(self, request, *args, **kwargs): _logger.debug('-----------user registing-----------') token = request.environ.get('HTTP_{}'.format(get_token_header_field().upper())) content_type = request.environ.get('CONTENT_TYPE') _logger.debug({'content_type':content_type,'token':token}) if not content_type or not content_type.lower() == 'application/json': raise ApplicationException( errcode=ERROR_CONTENT_TYPE_NOT_JSON, ) if not token: raise ApplicationException( errcode=ERROR_REGISTER_MISSING_TOKEN, ) #params = request.form #params = request.json # flask-wechat-utils params = request.data # rest framework _logger.debug(params) encryptedData_field_name = get_update_encryptedData_field_name() iv_field_name = get_update_iv_field_name() if not params.get(iv_field_name) or not params.get(encryptedData_field_name): raise ApplicationException( errcode=ERROR_REGISTER_MISSING_IV_OR_ENCRYPTED, ) iv = params.get(iv_field_name) encryptedData = params.get(encryptedData_field_name) result_token = decrypt_token(token) openid = result_token['openid'] try: user = User.objects.get(openid=openid) except: raise ApplicationException( errcode=ERROR_REGISTER_MISSING_IV_OR_ENCRYPTED, ) session_key = user.session_key #session_key = 'HKUOhvaNYvMxGCt2BpjfJg==' result_userinfo = decrypt( session_key = session_key, iv=iv, encrypted=encryptedData ) mobile = '' if result_userinfo.get('mobile') == None else result_userinfo.get('mobile') nickName = '' if result_userinfo.get('nickName') == None else result_userinfo.get('nickName') avatarUrl = '' if result_userinfo.get('avatarUrl') == None else result_userinfo.get('avatarUrl') gender = '' if result_userinfo.get('gender') == None else result_userinfo.get('gender') city = '' if result_userinfo.get('city') == None else result_userinfo.get('city') province = '' if result_userinfo.get('province') == None else result_userinfo.get('province') country = '' if result_userinfo.get('country') == None else result_userinfo.get('country') language = '' if result_userinfo.get('language') == None else result_userinfo.get('language') user.session_key=session_key user.nickname=nickName user.avatar=avatarUrl user.gender=gender user.city=city user.province=province user.country=country user.language=language user.mobile=mobile user.last_login_ts=now_ts() user.last_ping_ts=now_ts() user.save() user = User.objects.get(openid=openid) request.wechat_user = user return func(self, request, *args, **kwargs)
def get_token_secret_key(): if not isinstance(config_common.TOKEN_SECRET_KEY, str): raise ApplicationException( errcode=ERROR_CONFIG_TOKEN_SECRET_KEY_WRONG, ) return config_common.TOKEN_SECRET_KEY
def get_token_timeout_hours(): if not isinstance(config_common.TOKEN_TIMEOUT_HOURS, int): raise ApplicationException( errcode=ERROR_CONFIG_TOKEN_TIMEOUT_HOURS_WRONG, ) return config_common.TOKEN_TIMEOUT_HOURS