Dav*_*vid 9 android google-maps dynamic
我有一个谷歌地图的Android地图,可以根据用户的屏幕位置从服务器动态加载标记.因此,例如,如果用户移动地图,我只是向服务器发出请求,并且我正在发送屏幕边界,并且基于此我得到标记数据(id和corrdinates),稍后将其解析并创建为实际指针.问题是,当用户返回到同一区域(之前创建了哪些标记)时,我仍然提出相同的请求并获得相同的数据(但显然我不会让重新创建该标记,所以我只是在那里运行所有标记的循环在地图上并检查地图标记id是否相等服务器发送数据标记ID,如果它相等,我只是打破循环)
try {
Collection<MarkerItemData> mapMarkers = algorithm.getItems();
JSONObject jsonObject = new JSONObject(strings[0]);
JSONArray respondArray = jsonObject.getJSONArray("respond");
list = new ArrayList();
for (int i = 0; i < respondArray.length(); i++) {
JSONObject station = respondArray.getJSONObject(i);
int id = station.getInt("_id");
boolean skip = false;
for (final MarkerItemData m : mapMarkers) {
if (m.getId() == id) {
skip = true;
break;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是我不认为这种方法是最好的.我还有其他想法应该有效(至少我认为)
那么哪些想法最好?还有其他想法吗?(对不起我的英语不好)
将屏幕边界发送到服务器和屏幕上当前可见标记的 id-s 是您最好的选择。但仍然存在一些麻烦的问题。如何找到屏幕边界指定范围内包含的所有标记?如果新标记到达您的服务器或某些标记被删除怎么办?在这种情况下,你能提供一个可维护的结构吗?还是你会一一测试数据库中与标记相对应的每个点,看看它是否位于范围内?考虑到所有这些,您需要找到一种方法来优化存储和查询点,即点标记的纬度和经度对。您应该使用一种常见的空间索引方法来执行空间索引。
空间索引的方法有很多,根据用例,一种方法可能比另一种方法稍好。长话短说,由于您需要在这种情况下查询范围,因此您应该实现四叉树。四叉树被称为树形数据结构,其中每个内部节点恰好有四个子节点(西北、东北、西南、东南)。如果你对这个结构没有了解,我相信你一个小时就能明白它的基础知识,但从头开始详细解释会导致我损失太多时间。因此,我跳过有关四叉树的实现细节。有几个来源已经比我更好地解释了这种结构,并且您可以轻松找到开源库。
我只会为你的四叉树提供伪 Java 方法来查找屏幕边界范围内出现的所有点,不包括上一个屏幕中已经存在的点:
ArrayList<LatLng> queryRange(QuadLevel level, float[] screenBounds, ArrayList<LatLng> prevPoints) {
// Initialize a list to hold the found points
ArrayList<LatLng> pointsInRange = new ArrayList<>();
if (!quadtreeBounds.intersects(screenBounds))
return pointsInRange;
// Find the points that are in the current quad level
for (LatLng point : level.getPoints()) {
// If the current point is in screen bounds and it is not contained by prevPoints
if (point.isInRange(screenBounds)
&& !prevPoints.contains(point))
pointsInRange.add(point);
}
// If there are no children, return
if (level.hasNoChildren())
return pointsInRange;
// Else, continue to look up children
pointsInRange.addAll(queryRange(level.northwest, screenBounds, prevPoints));
pointsInRange.addAll(queryRange(level.northeast, screenBounds, prevPoints));
pointsInRange.addAll(queryRange(level.southwest, screenBounds, prevPoints));
pointsInRange.addAll(queryRange(level.southeast, screenBounds, prevPoints));
return pointsInRange;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
901 次 |
| 最近记录: |