Mozilla Location Service-8

上次搞清楚了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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值