26

I'm trying to build an application that will use open source maps from Open Street Maps (though the concept should be applicable to any map provider). The application will enable the user to specify a number of waypoints along a route prior to departure.

Because I don't have a data plan for my cell phone (and because rambling in the countryside rarely gives you a good connection), I want to be able to pre-load the relevant map tiles for the waypoints and/or route before departure so that maps can continue to be used without a data connection.

My initial thoughts are to download the required tiles from the map provider and store them in isolated storage. However, the Bing Maps control implementation, which uses the TileSource class relies on returning an absolute URI that it can download the tile(s) from, which clearly won't work with data stored in isolated storage.

The question has already been asked: Windows Phone 7 Map Control with custom layer in offline mode, but wasn't answered and I'm wondering if since then anyone has cracked the problem.

Community
  • 1
  • 1
Derek Lakin
  • 16,179
  • 36
  • 51

6 Answers6

2

I built a small prototype using OpenStreetMaps for Android. I think it might be interesting to look at the repository and therefore, find a solution similar to mine. I did download the maps before hand, but maybe you can use an online solution for this. This is the repo: https://github.com/kikofernandez/OpenStreetMapExample and the video of how it could look like: https://vimeo.com/40619538.

I used for this prototype OpenLayers, OpenStreetMaps, JavaScript and a WebView in Android. I would like to give you further details but it was just a prototype.

Kiko Fernandez
  • 857
  • 10
  • 26
2

I've seen this done with a custom layer placed over the map. Tiles are then loaded from anywhere you like (IsolatedStorage, online, somehwere else?) into the custom layer.

Sorry, I don't have any code I can share which demonstrates this at the moment but am currently doing something very similar.

Matt Lacey
  • 65,560
  • 11
  • 91
  • 143
0

Have you set the Build Action on your image(s) to Content?

0

If your app is running on WP8 then use the built in maps control in the Windows Phone 8 SDK as this already supports offline maps out of the box. If targeting WP7 it is possible to get offline maps to work but takes a lot of work. I created this for a customer a few years ago and I believe that it took me a little over 3000 lines of code to do. Mind you they wanted to also have a framework for adding tiles from various sources such as downloading over and area and downloading zipped files. They way I managed to get the rendering to work was to a canvas to the map without setting it's position. This will be default make it a child of the map but it will not move. I then made the canvas the same size as the map and used the resize event to resize the canvas should the map be resized. I then used the view change event to trigger a method to render the tiles. When this event fired I first calculated all the tiles in view using the code found here: http://msdn.microsoft.com/en-us/library/bb259689.aspx

I then would pull the tiles from isolated storage and draw them on the canvas. For performance I keep track of which tiles I added to the canvas so that if the tile was still in view I simply changed it's position rather than reloading it from isolated storage. I also removed any images that were no longer in view. Overall this works fine but there were some minor issues such as not having the smooth transition between zoom levels. If you really wanted that it is possible to get that to work but requires a lot more math. Also, if you zoom into an area where there is no tiles you end up with an empty map. You can create a custom map mode to prevent the user from going into areas where you don't have tiles.

rbrundritt
  • 16,570
  • 2
  • 21
  • 46
0

A solution

The question is a bit old, but there's a solution for anyone who can use Qt. The solution is not limited to the Windows Phone platform, I've done it targetting Android, and it also works on my desktop.

In Qt, you'll want to patch the OSM Plugin used by QtLocation. It's simple, quick and easy.

How to do it ?

A quick implementation could modify the QGeoTiledMappingManagerEngineOsm class to make it call your own QGeoTileFetcher instead of QGeoTileFetcherOsm. There may be better ways to acheive this, but at least it works for me.

Basically, you make a fetcher that reads tiles from the filesystem instead of the network. You build your filesystem database once, from an online resource for instance (see below) and you deploy it with your application for its offline use.

Where do I get tiles from ?

Information how to get the tiles to your offline implementation is available here : http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames

Here are two sources for tiles that can be used for free :

  • Open Street Maps project servers
  • Mapquest Open Tiles servers

Take care of the licensing and terms of use.

Open Street Map

  • Project : wiki.openstreetmap.org/wiki/Main_Page
  • License : www.openstreetmap.org/copyright
  • Terms of use : wiki.openstreetmap.org/wiki/Tile_usage_policy
  • Servers are currently named like *.tile.openstreetmap.org

MapQuest-OSM Tiles

  • Project : developer.mapquest.com/web/products/open/map
  • License : opendatacommons.org/licenses/odbl/
  • Terms of use : developer.mapquest.com/web/info/terms-of-use
  • Servers are currently named like otile*.mqcdn.com

(Sorry for strange links : I haven't got enough reputation to post real links).

SR_
  • 874
  • 13
  • 31
0

If you can store the data locally (embed it in the XAP), you can reference it via an absolute URI. Chris Walshie talks about it here.

So, for example, once you have the installation path for the app, you can reference the resource like this:

Uri toResource = new Uri("file:///Applications/Install/4FFA38B5-00AF-4760-A7EB-7C0C0BC1D31A/Install/EMBEDDED_RESOURCE", UriKind.Absolute);
Den
  • 16,686
  • 4
  • 47
  • 87
  • Thanks for the suggestion Dennis, but given the global nature of the application and the volume of map data for even a small country, and the constantly changing nature of map data, I don't think it's practical to include the data in the XAP. – Derek Lakin Feb 22 '11 at 08:23
  • What I was saying is that you could dynamically update the XAP as you go. – Den Feb 22 '11 at 15:10
  • Hmmm .. that looks like it's an approach that could work with a fairly simple `TileSource`. However, Chris' post falls short of actually explaining how to update the XAP. Could I download image files and then push them into the XAP to be used later? – Derek Lakin Feb 24 '11 at 08:36
  • Actually he mentions that at the end of his post. – Den Feb 25 '11 at 07:38
  • I don't see anything that explicitly shows how to write back to the XAP. Presumably in the instance that Chris shows it's a case of using `XDocument.Save`. Do you know what I'd need to do to write images into the XAP at runtime? – Derek Lakin Mar 01 '11 at 11:44
  • You can store everything in the isolated storage and access it later on via an absolute path. IS location: file:///Applications/Install/YOUR_APP_GUID/Data/ – Den Mar 04 '11 at 06:45
  • Sure, but can I actually write to the XAP post deployment? – Derek Lakin Mar 10 '11 at 16:42
  • 3
    Regarding: "You can store everything in the isolated storage and access it later on via an absolute path. IS location: file:///Applications/Install/YOUR_APP_GUID/Data". Other references imply the path should be @"file:///Applications/Data/YOUR_APP_GUID/Data/IsolatedStore/" but this doesn't seem to work either. Has anyone actually gotten this technique to work with offline maps? – Jay Borseth Jul 03 '11 at 02:30
  • To try and help clarify. The XAP is the deployment format of the app. Think of it like an MSI on the PC. When installed on a phone it is unzipped into the phone's file system. Once deployed, "adding a item to the XAP" is the same as saving it to the install directory. – Matt Lacey Feb 14 '12 at 09:15