我正在尝试构建一个将使用Open Street Maps中的开源 Map 的应用程序(尽管该概念应该适用于任何 Map 提供者) . 该应用程序将使用户能够在出发前沿路线指定多个航路点 .
因为我的手机没有数据计划(因为在乡下漫步很少能给你很好的连接),我希望能够在出发前为路标和/或路线预先加载相关的 Map 图块这样可以在没有数据连接的情况下继续使用 Map .
我最初的想法是从 Map 提供程序下载所需的切片并将它们存储在独立存储中 . 但是,使用 TileSource
类的Bing Maps控件实现依赖于返回可以从中下载切片的绝对URI,这显然不适用于存储在独立存储中的数据 .
这个问题已经被问到:Windows Phone 7 Map Control with custom layer in offline mode,但不知道是否从那以后任何人都解决了这个问题 .
6 回答
我已经看到这是通过在 Map 上放置自定义图层来完成的 . 然后将瓷砖从您喜欢的任何地方(IsolatedStorage,在线,其他一些?)加载到自定义图层中 .
对不起,我没有任何我可以分享的代码,目前正在展示这一点,但我目前正在做一些非常相似的事情 .
您是否已将图像上的构建操作设置为内容?
我使用OpenStreetMaps for Android构建了一个小型原型 . 我认为查看存储库可能会很有趣,因此找到类似于我的解决方案 . 我事先下载了 Map ,但也许您可以使用在线解决方案 . 这是回购:https://github.com/kikofernandez/OpenStreetMapExample以及它的外观视频:https://vimeo.com/40619538 .
我在Android中使用了这个原型OpenLayers,OpenStreetMaps,JavaScript和WebView . 我想给你更多详细信息,但它只是一个原型 .
解决方案
这个问题有点陈旧,但对于任何可以使用Qt的人来说都有一个解决方案 . 解决方案不仅限于Windows Phone平台,我已经完成了针对Android的操作,它也适用于我的桌面 .
在Qt中,您需要修补QtLocation使用的OSM插件 . 它简单,快捷,简单 .
怎么做?
快速实现可以修改
QGeoTiledMappingManagerEngineOsm
类,使其调用自己的QGeoTileFetcher
而不是QGeoTileFetcherOsm
. 可能有更好的方法来实现这一点,但至少它对我有用 .基本上,您创建一个从文件系统而不是网络读取切片的提取器 . 例如,您可以从在线资源构建文件系统数据库一次(见下文),并将其与您的应用程序一起部署以供其脱机使用 .
我从哪里获得瓷砖?
有关如何将磁贴添加到离线实现的信息,请访问:http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
以下是可以免费使用的两种瓷砖来源:
打开街道 Map 项目服务器
Mapquest打开Tiles服务器
照顾许可和使用条款 .
打开街道 Map
项目:wiki.openstreetmap.org/wiki/Main_Page
许可证:www.openstreetmap.org/copyright
使用条款:wiki.openstreetmap.org/wiki/Tile_usage_policy
服务器目前的名称类似于* .tile.openstreetmap.org
MapQuest-OSM Tiles
项目:developer.mapquest.com/web/products/open/map
许可证:opendatacommons.org/licenses/odbl/
使用条款:developer.mapquest.com/web/info/terms-of-use
服务器当前命名为otile * .mqcdn.com
(对不起奇怪的链接:我没有足够的声誉发布实际链接) .
如果您可以在本地存储数据(将其嵌入XAP中),则可以通过绝对URI引用它 . Chris Walshie谈论它here .
因此,例如,一旦您拥有应用程序的安装路径,就可以像这样引用资源:
如果您的应用程序在WP8上运行,则使用Windows Phone 8 SDK中的内置 Map 控件,因为这已经支持开箱即用的离线 Map . 如果定位WP7,可以让离线 Map 工作,但需要做很多工作 . 几年前我为客户创建了这个,我相信我需要花费3000多行代码 . 请注意,他们还希望有一个框架,用于添加各种来源的图块,例如下载和区域以及下载压缩文件 . 我设法让渲染工作的方式是画布到 Map 而不设置它的位置 . 这将默认使它成为 Map 的子项,但它不会移动 . 然后我使画布与 Map 的大小相同,并在调整 Map 大小时使用resize事件调整画布大小 . 然后我使用视图更改事件来触发渲染切片的方法 . 当此事件触发时,我首先使用此处的代码计算视图中的所有图块:http://msdn.microsoft.com/en-us/library/bb259689.aspx
然后我会从孤立的存储中拉出瓷砖并在画布上绘制它们 . 为了表现我跟踪我添加到画布的哪些瓷砖,这样如果瓷砖仍然在视图中,我只需更改它的位置,而不是从隔离存储重新加载它 . 我还删除了任何不再可见的图像 . 总体而言,这种方法很好但有一些小问题,例如缩放级别之间没有平滑过渡 . 如果你真的想要它可以让它工作,但需要更多的数学 . 此外,如果您放大到没有瓷砖的区域,您最终会得到一张空 Map . 您可以创建自定义 Map 模式,以防止用户进入您没有切片的区域 .