I’m working on a project where I need to add information to a map and I need more than just a pin drop. I originally wanted to overlay an informational map on top of the built in MapView so that I could use the GPS to show where I was within the informational overlay. All of this is fairly well documented/demoed at WWDC 2010, including sample code (TileMap) but I wanted to document the path I took and expand on some of the issues I ran into. Ultimately, it did not work because you need an informational map that is highly detailed and drawn to scale, which I did not have available to me.
As I said, what I wanted to do was overlay an informational map on top of the existing Google Map. After watching the WWDC video, Session 127 – Customizing Maps with Overlays, I decided the best course of action was to use the TileMap sample application provided with the video. The presenter, James Howard, said the easiest way to get started is to create your map tiles and drop them into the sample app. Sounds easy enough but there are a few steps you need to do to get to that point.
Let’s say our goal is to add an amusement park map on top of our Google Map.
- You need a high resolution image of your overlay.
- You need to convert this to a VRT and add coordinates to the file
- Then you create your tiles
- You need to add these tiles to the project and create a folder reference for them.
1. You need a high resolution image of your overlay.
At first I was working with a low resolution gif, bad idea. The best thing you can work with is a high resolution tiff file. I eventually found a PDF containing the informational overlay I wanted to work with and saved it as a TIFF file at 300ppi. I’m not sure if this is overkill but it looked pretty good and I could go down to a decent zoom level.
2. You need to convert this to a VRT and add coordinates to the file
You need some tools, gdal – Geospatial Data Abstraction Library, to do this and the presentation mentions you can just use mac ports. You can find information on doing this here: http://gdal.darwinports.com/
Now you’ll need some GPS coordinates that map pixels to coordinates on your map. I used Photoshop to get the pixel locations by picking out some landmarks and then found them on Google Earth to get the GPS coordinates. I imagine the more points you have, the more accurate your overlay will be but you need at least 4. I’m just going to do a few points. You can also add your image as an overlay in Google Earth and get your points that way (Add Menu->Image Overlay).
- (x,y)=Lat, Long
- (0,0)= 41.486375, -82.699724
- (3255,0)= 41.494846, -82.687452
- (3255,4686)= 41.481369, -82.670725
- (0, 4686)=41.472848, -82.683005
Now to create the VRT and add the coordinates to the file, you’ll use gdal_translate. The tricky thing with this is that the longitude comes first in the command. So to create this file for the coordinates above, I used the command:
gdal_translate -of VRT -a_srs EPSG:4326 -gcp 0 0 -82.693573 41.493081 -gcp 3255 0 -82.676874 41.493081 -gcp 3255 4686 -82.676874 41.474665 -gcp 0 4686 -82.693573 41.474665 CedarPoint.tiff CedarPoint.vrt
You can check the file by downloading a utility called MapTiler. Launch MapTiler and choose “Google Maps compatible”:
Add your newly created VRT file and click continue. Then click “Preview the map reference with this SRS”:
You should see a red bounding box over the area that your overlay covers. If this is correct, then proceed, otherwise go back and check your coordinates and your gdal_translate command. When I was specifying the latitude first, I would end up with a box somewhere over Antartica and it took me a while to figure out what was wrong.
3. Then you create your tiles
Now you’ll use a python script called gdal2tiles.py to generate tiles from your VRT file. I had a hard time actually finding gdal2tiles.py. It didn’t come with the mac ports install of GDAL so I downloaded the source code (don’t freak out, you just need a file from the zip, you don’t have to do any compiling). You can get the gdal source from: http://trac.osgeo.org/gdal/wiki/DownloadSource I got the file: gdal173.zip. Unzip this file and find gdal2tiles.py in the folder swig/python/scripts/
Copy gdal2tiles.py to the same directory containing your .VRT and run the following in a terminal window:
python gdal2tiles.py -p mercator CedarPoint.vrt
This command will generate a subdirectory with the name of your VRT. Rename this subdirectory “Tiles”. Inside this sub directory is a series of numbered folders, these are your tiles (and the only folders we are interested in).
4. You need to add these tiles to the project and create a folder reference for them.
Open the TileMap project form the WWDC files. You’ll need to update the project to use the latest SDK (Project Menu->Edit Project->Base SDK=Latest).
Now Build the project just to make sure it builds.
Open the Resources container and delete the “Tiles” group:
Now add the Tile folders you just created (the numbered ones) to the project in a “Tiles” folder. When you do this, you need to select “Create Folder References for any added folders”
This will create blue colored folders in your Resources file. The reason I had you select “Create Folder Reference” is that it will create a folder in the Resources directory on the device and the TileMap project needs this folder to exist.
Now just build and run.
What you’ll most likely find is that your map does not use the proper scale and is warped in some manner. At least that’s what I saw when I tried to do this. The example from WWDC used USGS maps which are probably the most accurate you are going to get. All is not to be lost though, you can create a custom map overlay using polygons to mark out your important areas. And that will carry us to the next session on creating your own polygon overlays…To be continued…