轨迹管理平台实现了轨迹服务的管理,定位设备的管理,以位置轨迹的监控。后台是由Python实现的,Web服务由tornado框架开发,平台端实现对服务和设备的管理,设备终端也是通过调用api来实现定位信息的上传的。
代码截图说明如下:
初始化数据库和Redis。这里minTimeout表示同一设备要求距离上次上传特定时间间隔后才允许下一次上传,避免请求迸发,起到限流的作用。maxTimeout表示距离现在多久没有收到上传数据时判断为设备离线。
初始化Redis。从数据库中读取数据用来初始化Redis。hash_locators表示设备ID列表。updateForbidden_locator_X表示为每一个设备限制上传间隔。keepOnline_locator_X表示初始化所有设备为在线。recentCoordinate_locator_X表示设置每一个设备的最新定位数据(对于每一个设备从数据库历史定位表中查找最近的定位数据)。
平台API路由映射如下:
对于用户,轨迹服务,定位设备的管理,后台都提供了增删改查接口,比如对于轨迹服务(fleed表示车队的意思)
对于设备终端的新增和删除都要同时在Redis中更新其信息。
定位数据上传时会自带时间戳,这里方便演示在收到数据时以系统时间为时间戳。收到数据时更新Redis中最新定位数据。
轨迹管理平台主要有实时位置和轨迹查询的功能。
实时位置接口根据服务ID从Redis中获取其所有定位设备的最新数据。
查询某时间范围内有轨迹数据的设备,显示在历史轨迹设备列表中。
轨迹查询接口根据设备ID,时间范围从数据库中获取其历史轨迹数据。在历史轨迹设备列表勾选某设备时从后台查询。
代码如下:
代码语言:python代码运行次数:0复制import tornado.web
import tornado.ioloop
import tornado.httpserver
from tornado.options import define,options
import redis
from gpsMonitor_Model import *
import redis
from datetime import datetime,timedelta
import os
import sqlite3
import json
from collections import namedtuple
define('port',default=8090,help='run on the given port',type=int)
Locator=namedtuple('Locator',['id','name','stops'])
LocatorCoordinate=namedtuple('LocatorCoordinate',['coordinate_x','coordinate_y','coordinate_time'])
class Application(tornado.web.Application):
def __init__(self):
handlers=[
(r'/',IndexHandler),
(r'/index',IndexHandler),
(r'/user',userHandler),
(r'/fleed',fleedHandler),
(r'/locator',locatorHandler),
(r'/coordinate',coordinateHandler),
(r'/fleed/fleedsByUser',fleedsByUserHandler),
(r'/locator/locatorsByFleed',locatorsByFleedHandler),
(r'/coordinate/coordinatesByLocator',coordinatesByLocatorHandler),
(r'/coordinate/coordinatesByLocatorAndTime',coordinatesByLocatorAndTimeHandler),
(r'/coordinate/coordinatesByTime',coordinatesByTimeHandler),
(r'/coordinate/coordinatesByTime2GroupByLocator',coordinatesByTime2GroupByLocatorHandler),
(r'/locator/locatorsWithCoordinateByFleed',locatorsWithCoordinateByFleedHandler)
]
settings=dict(
template_path=os.path.join(os.path.curdir,'templates'),
static_path=os.path.join(os.path.curdir,'static'),
cookie_secret='miaojiyao',
debug=True
)
tornado.web.Application.__init__(self,handlers,**settings)
class IndexHandler(tornado.web.RequestHandler):
def get(self):
self.render('trackMap.html')
class userHandler(tornado.web.RequestHandler):
def post(self):
user_id=self.get_argument('itemId')
user_name=self.get_argument('user_name')
user=User.get(user_id)
user.user_name=user_name
self.write('post:')
self.write(repr(user))
def get(self):
user_id=self.get_argument('itemId')
user=User.get(user_id)
self.write('get:')
self.write(repr(user))
def put(self):
user_name=self.get_argument('user_name')
user=User(user_name=user_name)
self.write('put:')
self.write(repr(user))
def delete(self):
user_id=self.get_argument('itemId')
user=User.get(user_id)
User.delete(user_id)
self.write('delete:')
self.write(repr(user))
class fleedHandler(tornado.web.RequestHandler):
def post(self):
user=User.get(34)
fleed_id=self.get_argument('itemId')
fleed_name=self.get_argument('fleed_name')
fleed=Fleed.get(fleed_id)
fleed.fleed_name=fleed_name
fleed.fleed_user=user
self.write('post:')
self.write(repr(fleed))
def get(self):
fleed_id=self.get_argument('itemId')
fleed=Fleed.get(fleed_id)
self.write('get:')
self.write(repr(fleed))
def put(self):
user=User.get(33)
fleed_name=self.get_argument('fleed_name')
fleed=Fleed(fleed_name=fleed_name,fleed_user=user)
self.write('put:')
self.write(repr(fleed))
def delete(self):
fleed_id=self.get_argument('itemId')
fleed=Fleed.get(fleed_id)
Fleed.delete(fleed_id)
self.write('delete:')
self.write(repr(fleed))
class fleedsByUserHandler(tornado.web.RequestHandler):
def get(self):
user_id=self.get_argument('fleed_user')
user=User.get(user_id)
fleeds=Fleed.select(Fleed.q.fleed_userID==user.id)
fleeds=map(lambda x: { 'fleed_name':x.fleed_name, 'fleed_id':x.id, 'fleed_userID':x.fleed_userID},fleeds)
#self.write('getFleedsByUser:')
self.write({'result':fleeds})
class locatorHandler(tornado.web.RequestHandler):
def post(self):
fleed=Fleed.get(self.get_argument('locator_fleed'))
locator_id=self.get_argument('itemId')
locator_name=self.get_argument('locator_name')
locator=Locator.get(locator_id)
locator.locator_name=locator_name
locator.locator_fleed=fleed
self.write('post:')
self.write(repr(locator))
def get(self):
locator_id=self.get_argument('itemId')
locator=Locator.get(locator_id)
self.write('get:')
self.write(repr(locator))
def put(self):
fleed=Fleed.get(self.get_argument('locator_fleed'))
locator_name=self.get_argument('locator_name')
locator=Locator(locator_name=locator_name,locator_fleed=fleed)
myRedis.hset('hash_locators',str(locator.id),str(locator.id))
myRedis.setex('updateForbidden_locator_' str(locator.id),str(locator.id),minTimeout)
myRedis.setex('keepOnline_locator_' str(locator.id),str(locator.id),maxTimeout)
locatorCoordinates= Coordinate.select(Coordinate.q.coordinate_locatorID==locator.id,orderBy=Coordinate.q.coordinate_time)
if locatorCoordinates.count()>0:
myRedis.set('recentCoordinate_locator_' str(locator.id),
'|'.join([str(locatorCoordinates[-1].coordinate_x),
str(locatorCoordinates[-1].coordinate_y),
datetime.strftime(locatorCoordinates[-1].coordinate_time,'%Y-%m-%d %H:%M:%S')]))
else:
myRedis.set('recentCoordinate_locator_' str(locator.id),
'|'.join([str(defaultCoordinate_x),
str(defaultCoordinate_y),
datetime.strftime(defaultCoordinate_time,'%Y-%m-%d %H:%M:%S')]))
self.write('put:')
self.write(repr(locator))
def delete(self):
locator_id=self.get_argument('itemId')
locator=Locator.get(locator_id)
Locator.delete(locator_id)
myRedis.hdel('hash_locators',str(locator.id))
myRedis.delete('updateForbidden_locator_' str(locator.id))
myRedis.delete('keepOnline_locator_' str(locator.id))
myRedis.delete('recentCoordinate_locator_' str(locator.id))
self.write('delete:')
self.write(repr(locator))
class locatorsByFleedHandler(tornado.web.RequestHandler):
def get(self):
fleed_id=self.get_argument('locator_fleed')
fleed=Fleed.get(fleed_id)
locators=Locator.select(Locator.q.locator_fleedID==fleed.id)
locators=map(lambda x: { 'locator_id':x.id, 'locator_name':x.locator_name, 'locator_fleedID':x.locator_fleedID},locators)
#self.write('getLocatorsByFleed:')
self.write({'result':locators})
class coordinatesByTime2GroupByLocatorHandler(tornado.web.RequestHandler):
def get(self):
fleed_id=self.get_argument('fleed_id')
startTime=self.get_argument('startTime')
endTime=self.get_argument('endTime')
startTime=datetime.strptime(startTime,'%Y-%m-%d %H:%M:%S')
endTime=datetime.strptime(endTime,'%Y-%m-%d %H:%M:%S')
con=sqlite3.connect('../../GPS_DB.db')
cursor=con.cursor()
locatorsByCoordinate=cursor.execute('select * from coordinate where coordinate_time>(?)
and coordinate_time<(?) group by coordinate_locator_id',(startTime,endTime))
locatorsByFleed=Locator.select(Locator.q.locator_fleed==int(fleed_id))
locator_ids=map(lambda x:x[4],locatorsByCoordinate)
locators=filter(lambda x:locator_ids.count(x.id)>0,locatorsByFleed)
locators=map(lambda x: { 'locator_id':x.id, 'locator_name':x.locator_name, 'locator_fleedID':x.locator_fleedID},locators)
cursor.close()
con.close()
#locators=map(lambda x: { 'locator_id':x['name'], 'locator_name':x['name'], 'locator_fleedID':fleed_id},lines[0:25])
self.write({'result':locators})
class locatorsWithCoordinateByFleedHandler(tornado.web.RequestHandler):
def get(self):
fleed_id=self.get_argument('locator_fleed')
fleed=Fleed.get(fleed_id)
locators=Locator.select(Locator.q.locator_fleedID==fleed.id)
locators=map(lambda x: { 'locator_id':x.id, 'locator_name':x.locator_name, 'locator_fleedID':x.locator_fleedID},locators)
#locators=map(lambda x: { 'locator_id':x['name'], 'locator_name':x['name'], 'locator_fleedID':fleed_id},lines)
for locator in locators:
locator['locator_status']='on' if myRedis.get('keepOnline_locator_' str(locator.get('locator_id'))) else 'off'
locator['locator_coordinate_x'],locator['locator_coordinate_y'],locator['locator_coordinate_time']=
myRedis.get('recentCoordinate_locator_' str(locator.get('locator_id'))).split('|')
#hashLocators=myRedis.hgetall('hash_locators')
#filter(lambda x:hashLocators.get(str(x.get('locator_id',-90))) ,locators)
#self.write('getLocatorsByFleed:')
self.write({'result':locators})
class coordinateHandler(tornado.web.RequestHandler):
def post(self):
locator_id=self.get_argument('coordinate_locator')
locator=Locator.get(locator_id)
coordinate_id=self.get_argument('itemId')
coordinate_x=self.get_argument('coordinate_x')
coordinate_y=self.get_argument('coordinate_y')
coordinate_x=float(coordinate_x.encode('utf-8'))
coordinate_y=float(coordinate_y.encode('utf-8'))
coordinate_time=datetime.strptime('2010-10-09 10:00:20','%Y-%m-%d %H:%M:%S')
coordinate=Coordinate.get(coordinate_id)
coordinate.coordinate_x=coordinate_x
coordinate.coordinate_y=coordinate_y
coordinate.coordinate_time=coordinate_time
coordinate.coordinate_locator=locator
self.write('post:')
self.write(repr(coordinate))
def get(self):
coordinate_id=self.get_argument('itemId')
coordinate=Coordinate.get(coordinate_id)
self.write('get:')
self.write(repr(coordinate))
def put(self):
locator_id=self.get_argument('coordinate_locator')
locator=Locator.get(locator_id)
coordinate_x=self.get_argument('coordinate_x')
coordinate_x=float(coordinate_x.encode('utf-8'))
coordinate_y=self.get_argument('coordinate_y')
coordinate_y=float(coordinate_y.encode('utf-8'))
#coordinate_time=self.get_argument('coordinate_time')
#coordinate_time=datetime.strptime(coordinate_time,'%Y-%m-%d %H:%M:%S')
coordinate_time=datetime.now()
if not myRedis.get('updateForbidden_locator_' str(locator.id)):
coordinate=Coordinate(coordinate_x=coordinate_x,coordinate_y=coordinate_y,coordinate_time=coordinate_time,coordinate_locator=locator)
self.write('put:')
myRedis.setex('updateForbidden_locator_' str(locator.id),str(locator.id),minTimeout)
myRedis.setex('keepOnline_locator_' str(locator.id),str(locator.id),maxTimeout)
myRedis.set('recentCoordinate_locator_' str(locator.id),
'|'.join([str(coordinate_x),
str(coordinate_y),
datetime.strftime(coordinate_time,'%Y-%m-%d %H:%M:%S')]))
self.write(repr(coordinate))
else:
self.write('not allow submit too often!')
def delete(self):
coordinate_id=self.get_argument('itemId')
coordinate=Coordinate.get(coordinate_id)
Coordinate.delete(coordinate_id)
self.write('delete:')
self.write(repr(coordinate))
class coordinatesByLocatorHandler(tornado.web.RequestHandler):
def get(self):
locator_id=self.get_argument('coordinate_locator')
locator=Locator.get(locator_id)
coordinates=Coordinate.select(Coordinate.q.coordinate_locatorID==locator.id)
coordinates=map(lambda x: { 'coordinate_x':x.coordinate_x, 'coordinate_y':x.coordinate_y, 'coordinate_time':datetime.strftime(x.coordinate_time,'%Y-%m-%d %H:%M:%S'),'coordinate_locatorID':x.coordinate_locatorID},coordinates)
#self.write('getCoordinatesByLocator:')
self.write({'result':coordinates})
class coordinatesByTimeHandler(tornado.web.RequestHandler):
def get(self):
coordinate_time_start=self.get_argument('coordinate_time_start',datetime.strftime(datetime.now()-timedelta(1),'%Y-%m-%d %H:%M:%S'))
coordinate_time_end=self.get_argument('coordinate_time_end',datetime.strftime(datetime.strptime(coordinate_time_start,'%Y-%m-%d %H:%M:%S') timedelta(1),'%Y-%m-%d %H:%M:%S'))
coordinate_time_start=datetime.strptime(coordinate_time_start,'%Y-%m-%d %H:%M:%S')
coordinate_time_end=datetime.strptime(coordinate_time_end,'%Y-%m-%d %H:%M:%S')
coordinates=Coordinate.select((Coordinate.q.coordinate_time>coordinate_time_start) & (Coordinate.q.coordinate_time<coordinate_time_end))
coordinates=map(lambda x: { 'coordinate_x':x.coordinate_x, 'coordinate_y':x.coordinate_y, 'coordinate_time':datetime.strftime(x.coordinate_time,'%Y-%m-%d %H:%M:%S'),'coordinate_locatorID':x.coordinate_locatorID},coordinates)
#self.write('getcoordinatesByTime:')
self.write({'result':coordinates})
class coordinatesByLocatorAndTimeHandler(tornado.web.RequestHandler):
def get(self):
locator_id=self.get_argument('coordinate_locator')
locator=Locator.get(locator_id)
coordinate_time_start=self.get_argument('coordinate_time_start',datetime.strftime(datetime.now()-timedelta(1),'%Y-%m-%d %H:%M:%S'))
coordinate_time_end=self.get_argument('coordinate_time_end',datetime.strftime(datetime.strptime(coordinate_time_start,'%Y-%m-%d %H:%M:%S') timedelta(1),'%Y-%m-%d %H:%M:%S'))
coordinate_time_start=datetime.strptime(coordinate_time_start,'%Y-%m-%d %H:%M:%S')
coordinate_time_end=datetime.strptime(coordinate_time_end,'%Y-%m-%d %H:%M:%S')
coordinates=Coordinate.select((Coordinate.q.coordinate_locatorID==locator.id) & (Coordinate.q.coordinate_time>coordinate_time_start) & (Coordinate.q.coordinate_time<coordinate_time_end))
coordinates=map(lambda x: { 'coordinate_x':x.coordinate_x, 'coordinate_y':x.coordinate_y, 'coordinate_time':datetime.strftime(x.coordinate_time,'%Y-%m-%d %H:%M:%S'),'coordinate_locatorID':x.coordinate_locatorID},coordinates)
#myLines=filter(lambda x:str(x['name'])==str(locator_id),lines)
#if len(myLines)==0:
#self.write({'result':[]})
#myLine=myLines[0]
#coordinates=map(lambda x: { 'coordinate_x':x['lat'], 'coordinate_y':x['lng'],
# 'coordinate_time':datetime.strftime(x['time'],'%Y-%m-%d %H:%M:%S'),
# 'coordinate_locatorID':locator_id},myLine['stops'])
#self.write('getcoordinatesByLocatorAndTime:')
self.write({'result':coordinates})
def initRedis():
locators=Locator.select()
#locators=map(lambda x: Locator(x['name'],x['name'],x['stops']),lines)
for locator in locators:
myRedis.hset('hash_locators',str(locator.id),str(locator.id))
myRedis.setex('updateForbidden_locator_' str(locator.id),str(locator.id),minTimeout)
myRedis.setex('keepOnline_locator_' str(locator.id),str(locator.id),maxTimeout)
locatorCoordinates= Coordinate.select(Coordinate.q.coordinate_locatorID==locator.id,
orderBy=Coordinate.q.coordinate_time)
#locatorCoordinates=map(lambda x:LocatorCoordinate(x['lat'],x['lng'],x['time']),locator.stops)
if locatorCoordinates.count()>0:
#if len(locatorCoordinates)>0:
myRedis.set('recentCoordinate_locator_' str(locator.id),
'|'.join([str(locatorCoordinates[0].coordinate_x),
str(locatorCoordinates[0].coordinate_y),
datetime.strftime(locatorCoordinates[0].coordinate_time,'%Y-%m-%d %H:%M:%S')]))
else:
myRedis.set('recentCoordinate_locator_' str(locator.id),
'|'.join([str(defaultCoordinate_x),
str(defaultCoordinate_y),
datetime.strftime(defaultCoordinate_time,'%Y-%m-%d %H:%M:%S')]))
#测试数据
def initTest():
f=open('./lines12.js','rb')
global lines
lines=json.load(f)[0:50]
f.close()
for line in lines:
for i in range(len(line['stops'])):
line['stops'][i]['time']=(defaultCoordinate_time-i*timedelta(0,defaultInterval))
if __name__=='__main__':
print 'start server'
myRedis=redis.Redis()
minTimeout=60
maxTimeout=60*5
defaultInterval=300
defaultCoordinate_x=34.730861
defaultCoordinate_y=113.6101392
defaultCoordinate_time=datetime.now()
#initTest()
initDatabase()
initRedis()
tornado.options.parse_command_line()
http_server=tornado.httpserver.HTTPServer(Application())
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()