1

概述

我有一个相当有趣的需求,我需要从服务(不是矢量切片服务)加载 geojson 数据,然后缓存该数据以供离线使用(使用 indexDB)。因此,当离线运行应用程序时,我需要将 indexDB 中的数据加载到地图中(使用 mapbox-gl)。可以离线缓存的数据量(在 indexDB 中)可能非常大,因此我不能只将所有数据放入内存并将其添加到地图中(在这种情况下,mapbox 将使用 geojson-vt 在内部为我们处理一切)。

我意识到,如果源是一个矢量切片服务,这会使事情变得更容易,但不幸的是,目前这不是一个选择。

尝试的解决方案

我相信解决这个问题的方法是在我将数据存储在 indexDB 中时对其进行索引。我的想法是,我会计算出每个“特征”的每个 UTM 网格值,这样当地图移动时,我可以简单地查询相应网格中的特征并将它们加载到 mapbox 中。

示例索引数据库“表”:

特征 ID | 属性 | utm_tiles ({z}_{x}_{y})
1 ... 14_0_0、13_1_1、13_1_2 等
2 ... 14_0_0、12_100_100、12_100_101 等
ETC...

有了上面的信息,我就可以查询 select * from index_db_features where utm_tiles in ('14_0_0', '14_0_1')

虽然这在理论上似乎可行,但我遇到的问题是找出给定功能涉及的所有图块。geojson -vt库似乎可以满足我的要求,只是它没有为您提供在其中找到功能的所有图块的实际列表 - 它执行相反的操作,您需要根据给定瓷砖。

有没有人有任何建议来找出给定功能所涉及的所有图块?或者对在 indexDB 中使用的 geojson 数据进行空间索引的更好建议?

4

1 回答 1

1

这是我目前对这个问题的解决方案:

  1. 将带有,字段的location对象添加到每个 geojson 功能的 (我正在使用功能的中心)。location.latlocation.lonproperties
  2. 在 IndexDB(我使用的是 dexie.js)中为location.lon和创建一个复合索引location.lng
  3. 查询 IndexDB 数据库以查找可见屏幕内的所有功能(或根据需要添加填充)

基本上:

// Create DB:
let db = new Dexie("features");
db.version(1).stores({
    pois: "properties.id,[properties.location.lat+properties.location.lon]"
});
// Adding:
db.table("pois").bulkPut(someGeojsonFeaturesArray);
// Getting:
function getFeatures(northEast, southWest): Promise<GeoJSON.Feature[]> {
        return db.table("pois")
            .where("[properties.location.lat+properties.location.lon]")
            .between([southWest.lat, southWest.lon], [northEast.lat, northEast.lon])
            .toArray();
    }

这可行且可扩展,但我认为平铺数据应该运行得更快。随时向这个 Github 问题添加您的评论: https ://github.com/IsraelHikingMap/Site/issues/1169

在此处查看实施: https ://github.com/IsraelHikingMap/Site/blob/e31e4e73107897c9e069f1426ca9d56f13cf7bff/IsraelHiking.Web/sources/application/services/database.service.ts#L30

于 2020-02-27T07:41:26.357 回答