JavaScript:维护边界的最佳方法(谷歌地图)?
我使用的是 Google 地图 v3 API。目前,我正在请求每次有人更改视口(通过缩放或移动地图)时获取新数据,并丢弃我拥有的旧数据。这很好用,但现在我想缓存数据,这样我就不需要每次视口更改时都获取数据。 Google Maps API 通过由纬度和经度组成的东北和西南坐标定义视口。它们存储在名为 LatLngBounds 的对象中。
我想出了两种方法:
- 存储用户访问的每个新视口的边界,检查新视口是否位于旧视口中,并仅获取新视口不在旧视口中的部分的新数据。旧视口。本质上,
- 将每个新视口划分为我们拥有的数据和需要获取的数据的矩形部分。存储每个矩形部分的边界。
如果有人能想到更好的方法来做到这一点,请随时提出新方法。
我的问题是,就更好的性能/内存使用和整体速度而言,哪一个会更好?它们都是相似的算法,所以这真的很重要吗?
此外,现在两种算法都依赖于根据旧视口划分新视口。划分新视口的算法是什么样的? (假设我实现了第二个算法)
var prevBounds = [ /* Array of previously seen bounds */ ];
var newViewport = map.getBounds(); // New Viewport to divide up
var sw = newViewport.getSouthWest();
var swlat = sw.lat();
var swlng = sw.lng();
var ne = newViewport.getNorthEast();
var nelat = ne.lat();
var nelng = ne.lng();
// newViewport.intersects(bounds)
// Returns true if this bounds shares any points with this bounds.
I am using the Google Maps v3 API. I currently am making a request to fetch new data each time a person changes the viewport (by either zooming or shifting the map) and am throwing away the old data I have. This works great, but now I want to cache the data so that I don't need to fetch the data each time the viewport changes. The Google Maps API defines a viewport by its Northeast and Southwest coordinate consisting of a latitude and a longitude. They are stored in objects called LatLngBounds.
I have come up with 2 ways I can do this:
- Store the bounds of each new viewport the user visits and check if the new viewport is in an old viewport and fetch new data only of the part of the new viewport that is not within an old viewport. Essentially,
- Divide each new viewport up into rectangular sections of data that we have and data that needs to be fetched. Store the bounds of each of the rectangular sections.
If anyone can think of a better way to do this, feel free to suggest new approaches.
My question is which one is going to be better in terms of better performance/memory usage and overall speed? They are both similar algorithms so does it really matter?
Also, right now both algorithms rely on dividing up the new viewport based on old viewports. What would the algorithm to divide new viewports look like? (Assume I implemented my 2nd algorithm)
var prevBounds = [ /* Array of previously seen bounds */ ];
var newViewport = map.getBounds(); // New Viewport to divide up
var sw = newViewport.getSouthWest();
var swlat = sw.lat();
var swlng = sw.lng();
var ne = newViewport.getNorthEast();
var nelat = ne.lat();
var nelng = ne.lng();
// newViewport.intersects(bounds)
// Returns true if this bounds shares any points with this bounds.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我可能会考虑或多或少地以 Google 提供地图图块的方式进行此操作 - 不是立即加载整个视口的数据,而是将整个地图划分为方形区域(尽管可能比 Google 的 256x256 图块更大的区域),确定哪些区域位于当前视口中,并加载这些区域的数据。当用户平移和缩放地图时,检查视口边界以查看新区域是否已进入框架,并根据需要加载它们。粗略的伪代码:(
请参阅 Google 对地图坐标的解释以及此示例了解如何实施
getAreas
。)这样做的吸引力在于,您要检索的区域要简单得多,并且可以很容易地检查您是否已经加载了给定区域的数据 - 每个区域都可以有一个简单的唯一密钥,可能是由 x/y/缩放坐标组成的字符串,并且在加载每个新区域时,您保存密钥(或者可能是密钥和数据 - 这取决于您是否从区域中删除旧数据)映射或只是将其留在那里)到某个缓存对象。然后,当视口移动到新区域时,您所要做的就是检查缓存中是否存在该键。
缺点是您可能经常在当前视口之外加载数据,并且您向服务器发送的请求可能比您建议的实现更多。如果您在不同的缩放级别提供不同的数据,则此方法可能效果最佳 - 否则您可能会在尝试选择在不同缩放下运行良好的单一大小的缓存区域时陷入困境。
I might consider doing this more or less exactly the way Google serves up map tiles - instead of loading data for the entire viewport at once, carve up the entire map into square areas (though probably bigger areas than Google's 256x256 tiles), determine which areas are in the current viewport, and load data for those areas. As the user pans and zooms the map, check the viewport bounds to see whether new areas have come into the frame, and load them as necessary. Rough pseudocode:
(See the Google explanation of map coordinates and this example for an idea of how to implement
getAreas
.)The appeal of this is that the areas you're retrieving are much simpler, and it becomes very easy to check whether you've already loaded data for a given area - each area can have a simple unique key, probably a string made out of the x/y/zoom coordinates, and as each new area is loaded you save the key (or maybe the key and the data - it depends on whether you're removing old data from the map or just leaving it there) to some cache object. Then all you have to do when the viewport moves to a new area is check for the existence of that key in your cache.
The downside is that you might often load data outside the current viewport, and you're probably sending more requests to the server than you would with the implementations you suggest. This method might work best if you're serving up different data at different zoom levels - otherwise you might be stuck trying to choose a single-size cache area that works well at different zooms.