上次搞清楚了geosubmit是怎么回事,这次再来看看geolocate.
开启服务,如何访问,文档里有介绍,这里就不罗嗦了。
直接来看view:
/ProgFile/ichnaea-for-liuqiao/ichnaea/lib/python2.7/site-packages/ichnaea-1.5-py2.7-linux-x86_64.egg/ichnaea/api/locate/views.py:
class LocateV1View(BasePositionView):
"""View class for v1/geolocate HTTP API."""
metric_path = 'v1.geolocate' #:
route = '/v1/geolocate' #:
schema = LOCATE_V1_SCHEMA #:
def prepare_response(self, result):
response = {
'location': {
'lat': result['lat'],#经度
'lng': result['lon'],#纬度
},
'accuracy': result['accuracy'],
}
if result['fallback']:
response['fallback'] = result['fallback']
return response
class BaseLocateView(BaseAPIView):
"""Common base class for all locate related views."""
#: :exc:`ichnaea.api.exceptions.LocationNotFound`
not_found = LocationNotFound
searcher = None #:
def locate(self, api_key):
print 'api/locate/views/locate()......'
request_data, errors = self.preprocess_request()
query = Query(
fallback=request_data.get('fallbacks'),
ip=self.request.client_addr,
blue=request_data.get('bluetoothBeacons'),
cell=request_data.get('cellTowers'),
wifi=request_data.get('wifiAccessPoints'),
api_key=api_key,
api_type=self.view_type,
session=self.request.db_ro_session,
http_session=self.request.registry.http_session,
geoip_db=self.request.registry.geoip_db,
stats_client=self.stats_client,
)
searcher = getattr(self.request.registry, self.searcher)
#重点:
return searcher.search(query)
def prepare_response(self, response_data): # pragma: no cover
return response_data
#最开始是调用这个方法
def view(self, api_key):
print 'locate/views view(self,api_key)........'
result = self.locate(api_key)
if not result:
raise self.prepare_exception(self.not_found())
return self.prepare_response(result)
#重点:return searcher.search(query)
/ProgFile/ichnaea-for-liuqiao/ichnaea/lib/python2.7/site-packages/ichnaea-1.5-py2.7-linux-x86_64.egg/ichnaea/api/locate/searcher.py:
def search(self, query):
"""
Provide a type specific query result or return None.
:param query: A query.
:type query: :class:`~ichnaea.api.locate.query.Query`
:returns: A result_type specific dict.
"""
print 'start to search.....'
query.emit_query_stats()
# pdb.set_trace()
重点:
result = self._search(query)
query.emit_result_stats(result)
if result is not None:
return self.format_result(result)
result=self._serach(query):
def _search(self, query):
print '_search start......'
results = self.result_list()
#: :class:`ichnaea.api.locate.result.ResultList`
for name, source in self.sources:
if source.should_search(query, results):
pdb.set_trace()
#重点:
tmp=source.search(query)
print 'tmp:', tmp,tmp.__module__
"""
RegionResultList: Region<region_code:FR, region_name:France, accuracy:570000.0, score:1.0,
fallback:None, source:DataSource.internal>, Region<region_code:YT, region_name:Mayotte,
accuracy:19000.0, score:1.0, fallback:None, source:DataSource.internal>
ichnaea.api.locate.result
"""
results.add(tmp)
return results.best()
tmp=source.search(query):
/ProgFile/ichnaea-for-liuqiao/ichnaea/lib/python2.7/site-packages/ichnaea-1.5-py2.7-linux-x86_64.egg/ichnaea/api/locate/internal.py:
def search(self, query):
results = self.result_list()
for should, search in (
# Search by most precise to least precise data type.
(self.should_search_blue, self.search_blue),
(self.should_search_wifi, self.search_wifi),
(self.should_search_cell, self.search_cell)):
if should(query, results):
# pdb.set_trace()
print search.__module__
#重点
tmp2=search(query)
print 'tmp2:', tmp2, tmp2.__module__
results.add(tmp2)
query.emit_source_stats(self.source, results)
return results
tmp2=search(query):
/ProgFile/ichnaea-for-liuqiao/ichnaea/lib/python2.7/site-packages/ichnaea-1.5-py2.7-linux-x86_64.egg/ichnaea/api/locate/cell.py
def search_cell(self, query):
results = self.result_list()
if query.cell:
cells = query_cells(
query, query.cell, self.cell_model, self.raven_client)
if cells:
for cluster in cluster_cells(cells, query.cell):
lat, lon, accuracy, score = aggregate_cell_position(
cluster, CELL_MIN_ACCURACY, CELL_MAX_ACCURACY)
results.add(self.result_type(
lat=lat, lon=lon, accuracy=accuracy, score=score))
if len(results):
return results
if query.cell_area:
areas = query_areas(
query, query.cell_area, self.area_model, self.raven_client)
if areas:
for cluster in cluster_areas(areas, query.cell_area):
lat, lon, accuracy, score = aggregate_cell_position(
cluster, CELLAREA_MIN_ACCURACY, CELLAREA_MAX_ACCURACY)
results.add(self.result_type(
lat=lat, lon=lon, accuracy=accuracy, score=score,
fallback='lacf'))
return results
调用了N层终于要到最核心的做查询的地方了:
def query_cells(query, lookups, model, raven_client):
# Given a location query and a list of lookup instances, query the
# database and return a list of model objects.
# print 'query_cells param lookups:', lookups
print 'query_cell.......'
for lookup in lookups:
print lookup.radioType
cellids = [lookup.cellid for lookup in lookups]
if not cellids: # pragma: no cover
return []
# load all fields used in score calculation and those we
# need for the position
# load_fields is a YuanZu ,cant revise and visited by offset, eg.load_fields[2] is radius
load_fields = ('lat', 'lon', 'radius', 'region', 'samples',
'created', 'modified', 'last_seen',
'block_last', 'block_count')
result = []
today = util.utcnow().date()
print 'today is:', today
try:
# pdb.set_trace()
shards = defaultdict(list)# list {}
for lookup in lookups:
shards[model.shard_model(lookup.radioType)].append(lookup.cellid)
# (<type 'list'>, {<class 'ichnaea.models.cell.CellShardWcdma'>: ['\x02\x00\xd0\x00\x01\x00\x02\x00\x12\xd6\x87']})
for shard, shard_cellids in shards.items():
rows = (
query.session.query(shard)
.filter(shard.cellid.in_(shard_cellids),
shard.lat.isnot(None),
shard.lon.isnot(None))
.options(load_only(*load_fields))
).all()
print 'rows are:', rows
result.extend([row for row in rows if not row.blocked(today)])
except Exception:
raven_client.captureException()
print 'result is:', result
return result
到这里,我发现用了sqlachemy, query.session.query(A).filter(B).options(C).all(D)
A:要查询的对象,对应一个mysql表;(ORM)
B:查询条件
C:附加选项
D:查到多条记录返回一个list
然后来找,这里到底在对哪张表做查询?
在pdb里面看看shard是个什么类,因为这个类定义的tablename属性就对应一张表
class CellShardWcdma(CellShard, _Model):
"""Shard for WCDMA cells."""
__tablename__ = 'cell_wcdma'
证明在对cell_wcdma表做查询
进入mysql客户端,发现cell_wcdma里一条数据也没有,难怪查不到了。
用 show create table cell_wcdma看看这张表都有哪些字段:
| cell_wcdma | CREATE TABLE `cell_wcdma` (
`max_lat` double DEFAULT NULL,
`min_lat` double DEFAULT NULL,
`max_lon` double DEFAULT NULL,
`min_lon` double DEFAULT NULL,
`lat` double DEFAULT NULL,
`lon` double DEFAULT NULL,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
`radius` int(10) unsigned DEFAULT NULL,
`region` varchar(2) DEFAULT NULL,
`samples` int(10) unsigned DEFAULT NULL,
`source` tinyint(4) DEFAULT NULL,
`weight` double DEFAULT NULL,
`last_seen` date DEFAULT NULL,
`block_first` date DEFAULT NULL,
`block_last` date DEFAULT NULL,
`block_count` tinyint(3) unsigned DEFAULT NULL,
`cellid` binary(11) NOT NULL,
`radio` tinyint(4) NOT NULL,
`mcc` smallint(6) NOT NULL,
`mnc` smallint(6) NOT NULL,
`lac` smallint(5) unsigned NOT NULL,
`cid` int(10) unsigned NOT NULL,
`psc` smallint(6) DEFAULT NULL,
PRIMARY KEY (`cellid`),
UNIQUE KEY `cell_wcdma_cellid_unique` (`radio`,`mcc`,`mnc`,`lac`,`cid`),
KEY `cell_wcdma_latlon_idx` (`lat`,`lon`),
KEY `cell_wcdma_modified_idx` (`modified`),
KEY `cell_wcdma_region_idx` (`region`),
KEY `cell_wcdma_created_idx` (`created`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
手动insert一条记录:
insert into cell_wcdma(cellid,radio,mcc,mnc,lac,cid) values(184640524,q,460,1,29448,184640524);
在测试还是无法定位,大部分程序没有运行直接返回异常了。
问题:
cell_cdma里又经度和纬度两个字段,如果在这条记录里,这两个值不为空,岂不是可以直接靠一个当前基站信息就确定当前经纬度?
原始数据从哪里弄呢?如果用户连接到基站,也只能上传基站信息,不能上传经纬度(这是定位结果),那数据库里一直没有经纬度又如何做定位?