美文网首页
OsmAnd 数据流使用分析

OsmAnd 数据流使用分析

作者: 温温开水 | 来源:发表于2019-04-26 21:32 被阅读0次

    选择目的地--》搜索页数据

    由功能可以很清晰地推测出入口函数在 addTextChangedListener

    //QuickSearchDialogFragment.java
            searchEditText.addTextChangedListener({runSearch();})
    

    上述代码为简写,可看到search方法为 runSearch();

    runCoreSearchInternal() --> SearchUICore.search() --> searchInternal()

    searchInternal中执行了 search 的操作 ,代码如下

    void searchInternal(final SearchPhrase phrase, SearchResultMatcher matcher) {
            preparePhrase(phrase);
            ArrayList<SearchCoreAPI> lst = new ArrayList<>(apis);
            Collections.sort(lst, new Comparator<SearchCoreAPI>() {
                @Override
                public int compare(SearchCoreAPI o1, SearchCoreAPI o2) {
                    return Algorithms.compare(o1.getSearchPriority(phrase),
                            o2.getSearchPriority(phrase));
                }
            });
            for (SearchCoreAPI api : lst) {
                if (matcher.isCancelled()) {
                    break;
                }
                if (!api.isSearchAvailable(phrase) || api.getSearchPriority(phrase) == -1) {
                    continue;
                }
                try {
                //具体 search 入口
                    api.search(phrase, matcher);
                    matcher.apiSearchFinished(api, phrase);
                } catch (Throwable e) {
                    e.printStackTrace();
                    LOG.error(e.getMessage(), e);
                }
            }
        }
    

    关于 search 的操作在 SearchCoreAPI 子类中实现,打断点可看到 lst 有很多个
    以搜索朝阳公园为例,最后操作在 SearchAmenityByNameAPI.search
    search 主要是构造 req ,然后执行 r.searchPoiByName(req); --> BinaryMapIndexReader.searchPoiByName --> BinaryMapPoiReaderAdapter.searchPoiByName

    protected void searchPoiByName(PoiRegion region, SearchRequest<Amenity> req) throws IOException {
            TIntLongHashMap offsets = new TIntLongHashMap();
            String query = normalizeSearchPoiByNameQuery(req.nameQuery);
            CollatorStringMatcher matcher = new CollatorStringMatcher(query,
                    StringMatcherMode.CHECK_STARTS_FROM_SPACE);
            long time = System.currentTimeMillis();
            int indexOffset = codedIS.getTotalBytesRead();
            while (true) {
                if (req.isCancelled()) {
                    return;
                }
                int t = codedIS.readTag();
                int tag = WireFormat.getTagFieldNumber(t);
                switch (tag) {
                case 0:
                    return;
                case OsmandOdb.OsmAndPoiIndex.NAMEINDEX_FIELD_NUMBER:
                    int length = readInt();
                    int oldLimit = codedIS.pushLimit(length);
                    // here offsets are sorted by distance
                    offsets = readPoiNameIndex(matcher.getCollator(), query, req);
                    codedIS.popLimit(oldLimit);
                    break;
                case OsmandOdb.OsmAndPoiIndex.POIDATA_FIELD_NUMBER:
                    // also offsets can be randomly skipped by limit
                    Integer[] offKeys = new Integer[offsets.size()];
                    if (offsets.size() > 0) {
                        int[] keys = offsets.keys();
                        for (int i = 0; i < keys.length; i++) {
                            offKeys[i] = keys[i];
                        }
                        final TIntLongHashMap foffsets = offsets;
                        Arrays.sort(offKeys, new Comparator<Integer>() {
                            @Override
                            public int compare(Integer object1, Integer object2) {
                                return Double.compare(foffsets.get(object1), foffsets.get(object2));
                            }
                        });
                        int p = BUCKET_SEARCH_BY_NAME * 3;
                        if (p < offKeys.length) {
                            for (int i = p + BUCKET_SEARCH_BY_NAME; ; i += BUCKET_SEARCH_BY_NAME) {
                                if (i > offKeys.length) {
                                    Arrays.sort(offKeys, p, offKeys.length);
                                    break;
                                } else {
                                    Arrays.sort(offKeys, p, i);
                                }
                                p = i;
                            }
                        }
                    }
    
    
                    LOG.info("Searched poi structure in " + (System.currentTimeMillis() - time) +
                            "ms. Found " + offKeys.length + " subtrees");
                    for (int j = 0; j < offKeys.length; j++) {
                        codedIS.seek(offKeys[j] + indexOffset);
                        int len = readInt();
                        int oldLim = codedIS.pushLimit(len);
                        readPoiData(matcher, req, region);
                        codedIS.popLimit(oldLim);
                        if (req.isCancelled() || req.limitExceeded()) {
                            return;
                        }
                    }
                    LOG.info("Whole poi by name search is done in " + (System.currentTimeMillis() - time) +
                            "ms. Found " + req.getSearchResults().size());
                    codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
                    return;
                default:
                    skipUnknownField(t);
                    break;
                }
            }
        }
    

    这个方法为 searchByName 的核心方法,会执行 readPoiData --> readPoiPoint 来获取数据

    2.OsmAnd 数据源

    OsmAnd 在使用前需要先下载一个 .obf后缀的数据包,该数据包为 OsmAnd 的自定义地图数据包,OsmAnd app 内的大部分数据均来自于该数据包

    .obf is saved in the OBF format and stores map data, which may include the placement of roads, buildings, natural objects, and walking, hiking, and biking paths. OBF files enable OsmAnd to render, route, and search maps when offline.
    
    

    3. 数据流总结图

    数据流--end.png

    相关文章

      网友评论

          本文标题:OsmAnd 数据流使用分析

          本文链接:https://www.haomeiwen.com/subject/skkcnqtx.html