2

我想将地理点和相关数据存储在浏览器的 IndexedDB 中,并能够在给定纬度/经度位置的情况下定位 X 个最近点。数据集可能包含数千个点,因此效率是一个考虑因素。是否有任何现有的解决方案可用于此类查询?如何建立索引以便可以找到靠近给定地理点的点?

4

1 回答 1

2

对于查询两个变量,IndexedDB 有两个选项,手动合并和使用复合索引。

对于手动合并,您只需要索引 lat 和 long。然后您将对键光标进行键范围查询。交集就是结果。结果是主键。使用结果主键,您可以获得完整的记录。

var r = 10; // require distance
lat_range = IDBKeyRange.bound(query_lat - r, query_lat + r);
long_range = IDBKeyRange.bound(query_long - r, query_long + r);

obj_store = db.objectStore('geopoint');
lat_key_cursor = obj_store.index('lat').openKeyCursor(lat_range);
long_key_cursor = obj_store.index('long').openKeyCursor(long_range);

// get primary keys from cursors, sort and find intersection as results 
var cursor = obj_store.openCursor(results.shift());
cursor.onsuccess = function(e) {
  console.log(e.target.result);
  if (results.length > 0) {
    cursor.continue(results.shift());
  }
}

通过将索引 keyPath 指定为数组 ['lat', 'long'],可以将 Lat 和 long 索引为数组复合索引。然后您将查询 'lat' 的范围查询。有效密钥的结果是“长”。在给定范围内过滤“长”并查询完整记录。

var compound_index = obj_store.index('lat, long');
var range = IDBKeyRange.bound([query_lat - r], [query_lat + r]);
var cursor = compound_index.openKeyCursor(range);
cursor.onsuccess = function(e) {
  var key = e.target.result.key();
  var lat = key[0];
  var long = key[1];
  if (long > query_long - r && long < query_long + r) {
     // we get result
     var req = obj_store.get(e.target.result.primaryKey());
     req.onsuccess = function(e2) {
        console.log(e2.target.result);
     }
  }
}   
于 2012-12-24T02:08:17.947 回答