Mozilla Location Service-8

来源:互联网 发布:淘宝袜子好评语100字 编辑:程序博客网 时间:2024/04/26 10:54

上次搞清楚了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里又经度和纬度两个字段,如果在这条记录里,这两个值不为空,岂不是可以直接靠一个当前基站信息就确定当前经纬度?

原始数据从哪里弄呢?如果用户连接到基站,也只能上传基站信息,不能上传经纬度(这是定位结果),那数据库里一直没有经纬度又如何做定位?

0 0
原创粉丝点击