Mapkit。从服务器获取附近的位置并可能缓存它们(例如,供离线使用)

时间:2012-09-07 20:51:49

标签: ios caching mapkit

我正在开发iOS 5应用程序,我想与服务器通信,提供有关给定位置的附近位置的信息:放置位置和注释。我想使用MapKit用这些信息填充我的地图。

我没有找到关于以下问题的任何直接信息:

  1. MapKit是否具有开箱即用的切片功能(谷歌地图方式),如果没有,我还需要另外处理它吗?
  2. 从服务器检索地点信息(标记位置和注释)的最佳做法是什么?
  3. 是否可以缓存此信息,以便用户可以在离线模式下查看“他所在城市”的附近位置?
  4. 实际上问题2和问题3是相互关联的:它们都解决了不检索已多次在地图上的信息(位置+注释)的问题。

    希望我不会忽视这里显而易见的事情。

    谢谢!

    更新1 :(关于地方,而不是地图)更具体地说,我感兴趣的是,如何为包含我从服务器获取的地方的区域创建“手工制作”的逻辑磁贴,因此它们不需要自己重新获取当用户滚动地图时?我知道我可以自己深入实现这个功能。例如,我应该在获取或组织一些队列后立即使用Core Data立即写入刚刚获取到本地存储的位置吗?或者我怎么知道何时需要在服务器上执行有关特定区域的请求以及何时只获取设备上已有的本地数据?我只是想知道,有任何推荐的方法,最佳做法?希望我在这里写清楚。

    更新2:我想知道这里的最佳实践(链接,示例)不要从头开始创建所有这些(第2 + 3点)。是否有任何框架包含这个或好的教程?

2 个答案:

答案 0 :(得分:0)

@Stanislaw - 我们已经为我们的一个客户实现了您在名为PreventConnect的应用中描述的功能。客户端已经将一些数据存储在Google Fusion表中。我们通过添加另一个Google Fusion表来扩展现有解决方案,该表存储了多个地点的地理坐标。所有这些都说,回答你的问题......

1)地图部分本身是开箱即用的,瓷砖和什么不是,但你需要做一些编码来获得缩放范围,针脚,注释,以及像你期望的那样工作的东西他们工作。

2)我们发现Google Fusion解决方案非常有效。如果您不想使用Google Fusion,还有其他云数据库提供商,如StackMob,database.com和许多其他人。谷歌是免费的,他们有一个iOS SDK,可以很容易地与谷歌Fusion进行通信。

3)绝对!我们将大部分数据缓存在设备本地的Core Data存储中。这极大地提高了性能和响应能力。

答案 1 :(得分:0)

是时候为我的问题写一个可靠的答案了(我可以在一年前写出来,但不知怎的,我已经忘记了它。)


  

MapKit是否具有开箱即用的切片功能(谷歌地图方式),如果没有,我是否需要另外处理它?<​​/ p>

答案是肯定的:MapKit确实拥有它。这里的关键字是overlays (MKOverlay, MKOverlayView and others)。请参阅my another answer

另见:

WWDC 2010 Session: Customizing Maps with Overlays

Apple-WWDC10-TileMap


  

从服务器检索地点信息(标记位置和注释)的最佳做法是什么?

实际上从那以后我没有学到很多关于“最佳实践”的知识 - 不幸的是,没有人告诉我他们:(这就是为什么我会描述“我的实践”。

首先,有两种策略用地方填充MapKit地图:

第一个策略是关于按要求使用地点填充地图:想象您想要显示并查看附近的所有地点(例如,距当前用户位置不超过1公里) - 这种方法假设您只向服务器询问您感兴趣的盒子的位置。这意味着:“如果我在柏林(我希望柏林有200个地方),我为什么要从俄罗斯,日本取得这些地方,...(10000+个地方)“。

这种方法导致依赖于询问N1地址的“图块”功能:Google地图和Apple地图通常使用“图块”绘制,因此对于您的“柏林”部分地图,您依赖于绘制的相应“柏林”图块通过MKMapView - 您可以使用它们的尺寸,仅向服务器询问“柏林”框中的位置(请参阅我的链接答案和那里的演示应用程序)。

最初这是我使用的方法,我的实现工作得很好但后来我被推到使用第二种方法(见下文),因为出现了聚类问题。

第二个策略是一次获取所有地点(是的,所有10000以上)并使用核心数据来获取您感兴趣的地图的可见部分所需的位置

第二种方法意味着,在第一次运行期间,您向服务器发送一个请求以获取所有位置(我的应用程序中大约有2000个)。这里重要的是,您将要获取的字段仅限制为地图中真正需要的地理位置:idlatitudelongitude

这个'fetch-all'抓取对我的应用程序的第一个开始时间产生了重大影响(在“最老的”iPhone 4上,整个Fetch + Parse-JSON-into-Core-Data过程我接近700毫秒,并且广泛的基准测试向我显示< strong>它是核心数据,它的插入是一个瓶颈)但是你可以获得有关你设备上所在位置的所有重要地理信息。

请注意,无论您使用何种策略,都应该执行有效获取这些地理位置的过程

想象一下核心数据实体Place,它具有以下字段结构(preudo-Objective-C代码):

// Unique identificator
NSNumber *id,

// Geo info
NSNumber *latitude,
NSNumber *longitude,

// The rest "heavy" info  
NSString *name,
NSString *shortDescription,
NSString *detailedDescription, etc

有效地获取位置意味着您只询问您的地点记录来自服务器的地理数据,以尽可能快地完成此镜像的过程。

另见这个热门话题:Improve process of mirroring server database to a client database via JSON?

群集问题超出了这个问题的范围,但仍然非常相关,影响了整个过程中使用的整个算法 - 我将留下的唯一注意事项是所有当前存在的群集解决方案将要求您使用第二个策略 - 在遇到将在地图上组织您的位置的群集算法之前,您必须准备好所有位置 - 这意味着如果您决定使用群集,则必须使用策略#2。 / p>

有关群集的相关链接:

WWDC 2011 Session: Visualizing Information Geographically with MapKit

How To Efficiently Display Large Amounts of Data on iOS Maps

kingpin - 开源集群解决方案:高性能且易于使用。


  

是否可以缓存此信息,以便用户可以在离线模式下查看“他所在城市”的附近位置?

是的,两种策略都是这样做的:第一种策略会缓存您在地图上看到的地方 - 如果您观察到柏林的地图部分,您将柏林部分缓存...

使用第二种策略时:您将获得有关您的地点的所有重要地理信息,并且已准备好在离线模式下在地图上绘制(假设MapKit缓存了您在离线模式下浏览的地区的地图图像)。 / p>