离线地图瓦片缓存技术

26
我正在尝试构建一个应用程序,将使用Open Street Maps提供的开源地图(虽然这个概念适用于任何地图提供商)。该应用程序将允许用户在出发前指定沿路的多个航点。
因为我没有为我的手机购买数据计划(而且在乡村漫步很少会有良好的连接),我希望能够预先加载相关的地图瓦片以及/或路线,以便在没有数据连接的情况下继续使用地图。
我的初步想法是从地图提供商下载所需的瓦片并将它们存储在隔离存储中。然而,Bing Maps控件实现使用TileSource类,它依赖于返回一个绝对URI,以便可以从中下载瓦片,显然这无法与存储在隔离存储中的数据一起使用。
已经有人问过这个问题:Windows Phone 7离线模式下的自定义层地图控件,但是没有得到答案,我想知道是否有人解决了这个问题。
6个回答

2
我看到过使用自定义图层覆盖地图来实现此功能。然后从任何你喜欢的地方(IsolatedStorage,在线,其他地方?)加载瓦片到自定义图层中。
抱歉,我目前没有可以分享的演示代码,但我正在做非常相似的事情。

2
我使用OpenStreetMaps为Android构建了一个小型原型。我认为查看存储库可能很有趣,因此可以找到类似于我的解决方案。我之前下载了地图,但也许您可以使用在线解决方案。这是存储库:https://github.com/kikofernandez/OpenStreetMapExample,这是其外观视频:https://vimeo.com/40619538
我在Android中使用了OpenLayers、OpenStreetMaps、JavaScript和WebView来创建此原型。我想给您更多细节,但这只是一个原型。

注:存储库链接已失效。 - chamberlainpi
抱歉,我已更改了我的用户名。它在这里:https://github.com/kikofernandez/OpenStreetMapExample - Kiko Fernandez

0
如果您可以将数据存储在本地(嵌入XAP中),则可以通过绝对URI引用它。Chris Walshie在这里谈到了这个问题。
例如,一旦您获得了应用程序的安装路径,就可以像这样引用资源:
Uri toResource = new Uri("file:///Applications/Install/4FFA38B5-00AF-4760-A7EB-7C0C0BC1D31A/Install/EMBEDDED_RESOURCE", UriKind.Absolute);

我想说的是,您可以随时动态更新XAP。 - Den
嗯...看起来这似乎是一个可以使用相当简单的“TileSource”方法。然而,Chris的帖子并没有详细解释如何更新XAP。我能否下载图像文件,然后将它们推入XAP以供以后使用? - Derek Lakin
实际上,他在他的帖子末尾提到了这一点。 - Den
您可以将所有内容存储在隔离存储中,并通过绝对路径稍后访问。隔离存储位置:file:///Applications/Install/YOUR_APP_GUID/Data/ - Den
3
关于:"您可以将所有内容存储在隔离存储中,并通过绝对路径稍后访问。 隔离存储位置:file:///Applications/Install/YOUR_APP_GUID/Data" 。其他参考资料暗示路径应为@"file:///Applications/Data/YOUR_APP_GUID/Data/IsolatedStore/",但似乎也无法正常工作。是否有人真正使用此技术成功加载离线地图? - Jay Borseth
显示剩余4条评论

0

你把图片的“Build Action”设置为“Content”了吗?


0

一个解决方案

这个问题有点老了,但是对于会使用Qt的人来说,有一个解决方案。 这个解决方案不仅限于Windows Phone平台,我已经针对Android进行了测试,并且在我的桌面上也可以运行。

在Qt中,您需要修补QtLocation使用的OSM插件。这很简单、快速和容易。

如何做到这一点?

一个快速的实现方式是修改QGeoTiledMappingManagerEngineOsm类,使其调用您自己的QGeoTileFetcher而不是QGeoTileFetcherOsm。 可能有更好的方法来实现这一点,但至少对我来说它是有效的。

基本上,您需要创建一个从文件系统而不是网络读取瓦片的获取器。 您可以从在线资源(见下文)构建您的文件系统数据库,并将其部署到应用程序中以供离线使用。

我从哪里获取瓦片?

关于如何将瓦片传输到您的离线实现的信息,请参阅此处: http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames

这里有两个可以免费使用的瓦片源:

  • Open Street Maps 项目服务器
  • Mapquest Open Tiles 服务器

请注意许可证和使用条款。

Open Street Map

  • 项目:wiki.openstreetmap.org/wiki/Main_Page
  • 许可证:www.openstreetmap.org/copyright
  • 使用条款:wiki.openstreetmap.org/wiki/Tile_usage_policy
  • 服务器目前命名为*.tile.openstreetmap.org

MapQuest-OSM 瓦片

  • 项目:developer.mapquest.com/web/products/open/map
  • 许可证:opendatacommons.org/licenses/odbl/
  • 使用条款:developer.mapquest.com/web/info/terms-of-use
  • 服务器目前命名为otile*.mqcdn.com

(抱歉链接有点奇怪:我没有足够的声望来发布真正的链接)。


0

如果您的应用程序正在运行WP8,则请使用Windows Phone 8 SDK中内置的地图控件,因为它已经支持了离线地图。如果针对WP7,则可能需要大量工作才能使离线地图正常工作。几年前,我为一个客户创建了这个功能,我相信我花费了超过3000行代码来完成它。请注意,他们还希望有一个框架,可以从各种来源添加瓷砖,例如下载区域和下载压缩文件。我设法让渲染工作的方式是将canvas添加到地图中而不设置其位置。这将默认将其设置为地图的子级但不会移动。然后,我将canvas设置为与地图相同的大小,并使用resize事件调整canvas的大小(如果地图被调整大小)。然后,我使用视图更改事件来触发一种方法来渲染瓷砖。当此事件触发时,我首先使用此处找到的代码计算出所有视图中的瓷砖:http://msdn.microsoft.com/en-us/library/bb259689.aspx

然后,我会从隔离存储中提取图块并在画布上绘制它们。为了提高性能,我会跟踪将哪些图块添加到了画布上,这样如果该图块仍然在视图中,我就只需更改其位置,而不是重新从隔离存储中加载它。我还会删除任何不再处于视图中的图像。总体来说,这很好用,但存在一些小问题,例如在缩放级别之间没有平滑过渡。如果您真的想要这个效果,可以实现,但需要进行更多的数学计算。此外,如果您缩放到没有图块的区域,您最终会得到一个空地图。您可以创建自定义地图模式,以防止用户进入您没有图块的区域。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接