是时候为这个我的问题写一个可靠的答案了(我可以在一年前写下它,但不知何故我忘记了它)。
MapKit 是否具有开箱即用的图块功能(谷歌地图方式),如果没有,我是否需要额外处理它?
答案是肯定的:MapKit 确实有。这里的关键词是overlays (MKOverlay, MKOverlayView and others)
。请参阅我的另一个答案。
也可以看看:
WWDC 2010 会议:使用叠加自定义地图,
苹果-WWDC10-TileMap。
从服务器检索地点信息(标记位置和注释)的最佳实践是什么?
实际上,从那时起,我并没有学到很多关于“最佳实践”的知识——不幸的是,没有人告诉我它们:(——这就是我要描述“我的实践”的原因。
首先,使用地点填充 MapKit 地图有两种策略:
第一个策略是根据需求用地点填充地图:假设您想要显示并查看附近的所有地点(例如,距离当前用户位置不超过 1 公里) - 这种方法假设您只询问服务器的地点你感兴趣的盒子。它的意思是:“如果我在柏林(我希望柏林有 200 个地方),我为什么要从俄罗斯、日本……(10000 多个地方)获取这些地方” .
这种方法导致依赖于问题 N1 解决的“图块”功能:谷歌地图和苹果地图通常使用“图块”绘制,因此对于地图的“柏林”部分,您依赖于由 MKMapView 绘制的相应“柏林”图块 -您使用它们的尺寸,仅询问您的服务器“柏林”框中的位置(请参阅我的链接答案和那里的演示应用程序)。
最初这是我使用的方法,我的实现运行良好,但后来我被迫使用第二种方法(见下文),因为出现了集群问题。
第二种策略是一次获取所有地点(是的,所有这 10000 多个或更多)并使用 Core Data 获取您感兴趣的地图可见部分所需的地点。
第二种方法意味着,在第一次运行期间,您向服务器发送请求以获取所有位置(我的应用程序中有大约 2000 个)。这里重要的是,您将获取的字段限制为仅地图真正需要的地理字段:id
, latitude
, longitude
。
这种 'fetch-all' 获取对我的应用程序的首次启动时间有重大影响(在“最旧的”iPhone 4 上,整个Fetch + Parse-JSON-into-Core-Data
过程我有近 700 毫秒的时间,并且广泛的基准测试表明它是 Core Data 并且它的插入是瓶颈),但随后您就可以在设备上获得有关您所在位置的所有基本地理信息。
请注意,无论您使用什么策略,您都应该执行一个有效地获取这些地理点的过程:
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
有效地获取地点意味着您只要求您的地点记录来自服务器的地理数据,以尽可能快地进行此镜像过程。
另请参阅此热门话题:改进通过 JSON 将服务器数据库镜像到客户端数据库的过程?.
聚类问题超出了这个问题的范围,但仍然非常相关,并且会影响您用于整个过程的整个算法 - 我要在这里留下的唯一说明是,所有当前现有的聚类解决方案都需要您使用第二种策略 -您必须在使用将在地图上组织您的地点的聚类算法之前准备好所有地点 - 这意味着如果您决定使用聚类,则必须使用策略 #2。
聚类的相关链接:
WWDC 2011 会议:使用 MapKit 在地理上可视化信息,
如何在 iOS 地图上高效显示大量数据,
kingpin - 开源集群解决方案:高性能且易于使用。
是否可以缓存此信息,以便用户可以在离线模式下查看“他的城市”附近的地方?
是的,这两种策略都是这样做的:第一个策略缓存您在地图上看到的地方 - 如果您观察到柏林的地图部分,您将缓存柏林的部分......
使用第二种策略时:您将缓存有关您的地点的所有基本地理信息,并准备好在离线模式下绘制在地图上(假设 MapKit 缓存了您在离线模式下浏览的区域的地图图像)。