【问题标题】:Storing Polygons in localStorage在 localStorage 中存储多边形
【发布时间】:2015-09-14 16:28:03
【问题描述】:

当用户放大我的地图时,我发送当前边界框以从数据库中获取多边形并将它们设置在 localStorage 中。它们以 JSON 格式传输,因此类似于 [{"polygons":{"features":[{"geometry":{"coordinates":[...]](当然还有实际坐标)。

bounds = getBounds();
$.ajax({
    url: '/getPolygons',
    type: 'POST',
    data: JSON.stringify(bounds),
    contentType: 'application/json; charset=utf-8',
    dataType: 'json',
    success: function (data) {
        polyArray = JSON.parse(localStorage.getItem('polygons')) || [];
        polygons = data;
        polyArray.push(polygons);
        localStorage.setItem('polygons', JSON.stringify(polyArray));
    }
});

当用户进一步探索(平移、缩放)地图时,多边形会继续添加到相同的 localStorage 键中。我的问题是,既然这些多边形位于 localStorage 中,我该如何加载它们?我想减少发送到数据库的请求数量。如果某些多边形已经加载到地图上,我不想再次从数据库中请求这些多边形。

我可以从 localStorage 设置和获取多边形,但我遇到的问题是逻辑问题,如下所示。这是完整的功能。

google.maps.event.addListener(map, 'idle', function () {
    if (localStorage.getItem('polygons')) {
        var data = JSON.parse(localStorage.getItem('polygons'));
        map.data.addGeoJson(data['polygons']);
    } else {
        bounds = getBounds();
        $.ajax({
            url: '/getPolygons',
            type: 'POST',
            data: JSON.stringify(bounds),
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',
            success: function (data) {
                addPolygons(data);
                polyArray = JSON.parse(localStorage.getItem('polygons')) || [];
                polygons = data;
                polyArray.push(polygons);
                localStorage.setItem('polygons', JSON.stringify(polyArray));
            }
        });
    }
});

这是上面使用的addPolygons 函数:

function addPolygons(json) {
    data = json;

    if (typeof polygons !== 'undefined') {
        map.data.forEach(function(feature) {
            map.data.remove(feature);
        });
    }

    polygons = map.data.addGeoJson(data['polygons']);   
}

边界框定义如下:

function getBounds() {
    var boundsNE = map.getBounds().getNorthEast();
    var boundsSW = map.getBounds().getSouthWest();
    var ne = [ boundsNE.lng(), boundsNE.lat() ];
    var nw = [ boundsSW.lng(), boundsNE.lat() ];
    var sw = [ boundsSW.lng(), boundsSW.lat() ];
    var se = [ boundsNE.lng(), boundsSW.lat() ];
    var ne = [ boundsNE.lng(), boundsNE.lat() ];
    var boundsArray = [ ne, nw, sw, se, ne ];
    return boundsArray;
}

编辑:它使用map.data.addGeoJson(data['polygons']); 工作(请参阅我已设置的 IF 语句中的第 3 行)。但是现在当我开始平移地图时,我没有看到从数据库请求新的多边形(地图上不存在的多边形)。

Edit v2:我正在尝试的一件事是跟踪地图中心的变化。如果地图中心改变了 X 个值,则请求新的多边形。如果我能得到这个工作,希望能更新答案。

Edit v3:这是polyArray 在第二次获取后的样子。初始提取为空。 [Object] 0: Object polygons: Object features: Array[209] type: "FeatureCollection" __proto__: Object __proto__: Object 1: Object polygons: Object features: Array[205] type: "FeatureCollection" __proto__: Object __proto__: Object length: 2 __proto__: Array[0]

【问题讨论】:

  • 按照此问题的(现已删除)以前版本中的要求:请提供一个 Minimal, Complete, Tested and Readable example,以证明您正在尝试解决的问题。从 localStorage(以我自己的 JSON 格式)存储和检索多边形(显示在地图上)似乎没有任何问题。
  • 嗨@geocodezip——是的,现在我还可以存储和检索多边形,但仅限于初始视口。当边界改变时,localStorage 中不存在的新多边形不会被数据库请求。我试图通过 JSFiddle 提供一个示例。我现在无法访问开发服务器。
  • 我怀疑您需要更聪明地了解如何将新多边形合并到您的polyArray 中。第二次获取后 polyArray 是什么样的?
  • 最初是空的 ([])。在第二次获取之后,它是一个对象。我在上面的问题中添加了console.log 结果。因此,数组中的特征数量会根据进入视口的内容而变化。
  • 但是你只想更新特征数组,你有一个特征集合数组。您可能可以使其以这种方式工作,但我认为它不适用于您当前的代码。您是否正在做任何检查以防止重复的多边形?

标签: javascript html google-maps google-maps-api-3


【解决方案1】:

将此google.maps.event.addListener(map, 'idle', function () 改为bounds_changed 函数。基于谷歌documentation的建议:

地图 API 会独立触发后面的这些事件,getBounds() 可能 在视口具有权威性之前不要报告有用的结果 改变了。如果您希望在此类事件之后 getBounds(),请务必 改为收听 bounds_changed 事件。

“后者”事件是指zoom_changedcenter_changed,这可能不是最有效的方法。

EDITED SNIPPET(超时一秒):

var timeout;
google.maps.event.addListener(map, 'bounds_changed', function() {
    window.clearTimeout(timeout);
    timeout = window.setTimeout(function() {
      if (localStorage.getItem('polygons')) {
        ...
      } else {
        bounds = getBounds();
        ...
      }
    });
  },
  1000);

【讨论】:

  • 但是当您平移地图时,bounds_changed 事件会继续触发。这意味着我的getBounds() 函数(见上文)将继续发送边界框坐标,直到平移停止。这会减慢地图速度。
  • 您必须为此设置超时。我会更新我的答案。
  • 理想情况下,由于bounds_changed 的这种挫折,您以前的逻辑更好,但考虑到您的特定用例,我认为这可能是一种有效的解决方法。
猜你喜欢
  • 2012-06-23
  • 2014-02-14
  • 1970-01-01
  • 2022-07-08
  • 1970-01-01
  • 2013-06-03
  • 2013-09-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多