MapKit Overlays – Session 1: Overlay Map

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.

  1. You need a high resolution image of your overlay.
  2. You need to convert this to a VRT and add coordinates to the file
  3. Then you create your tiles
  4. 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”:
MapTiler

Add your newly created VRT file and click continue. Then click “Preview the map reference with this SRS”:
MapTiler-2

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.

Cedar Point Overlay

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). Cedar Point Tile Files

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:
TileMap Project Files

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”
Create Folder References

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…


Iphone map overlayIphone Map Overlay zoomed in

21 Responses to “MapKit Overlays – Session 1: Overlay Map”

  1. Peter
    December 30, 2010 at 4:04 pm #

    Great stuff, and Im going to try this in near future.

    Maybe just one simple question:
    You have an “fixed or static” overlay. What about dynamic overlay?
    Lets say an overlay which shows current day/night zone.

    This is always (on each hour) different?

    Do you think that this overlay could be drawn on iPhone?

    Best regards, peter

    • Shawn Grimes
      December 31, 2010 at 12:42 am #

      Interesting thought Peter. I don’t think the overlay in this tutorial will work for a dynamic overlay because you would have to pull the images for each zoom level. I think what would work better in your requested scenario is a polygon line overlay that you dynamically draw. I’m going to cover this in a future post.

      • Alec M
        March 7, 2011 at 4:37 pm #

        Well, one could create images for all zoom levels when parsing received data and then programmatically add these images as resources.
        Theoretically, all image manipulation procedures can be compiled for iPhone and run there to generate dynamic images.
        Or the images have to be statically linked during compilation?

        What I’m trying to do is to display a weather information overlay on the map. Something like this: http://www.grib.us/Portals/0/screenshot1.jpg

        At first I wanted to go the “draw the lines and put symbols” as Polylines. But now an approach of rendering all symbols and curves onto an image and then overlaying that image looks more flexible.

  2. Peter
    February 8, 2011 at 2:14 pm #

    Great!

  3. Alec M
    March 7, 2011 at 1:01 pm #

    Great article, thanks!

    Looking forward to the second part. My particular interest is how to place custom markers and draw curves on a map.

  4. lookez
    March 14, 2011 at 8:12 pm #

    I tried installing GDAL complete 1.8 but with no success… It says it’s installed but I can’t get it to work. It simply says “-bash: gdal_translate: command not found”

    • Shawn Grimes
      March 14, 2011 at 10:22 pm #

      Look and see if this folder exists:
      /Library/Frameworks/GDAL.framework/Versions/1.7/unix/bin/

      If it does, you need to add that path to your $path variable so the terminal knows where to look for the binaries.

      • ViggoV
        May 12, 2011 at 6:32 am #

        Since i’m probably not the first nor last to have some difficulty here, let me explain how:

        1. Find /Library/Frameworks/GDAL.frameworks/Versions and note the latest version (1.8 in my case)
        2. Open terminal and write sudo vi /etc/paths (this will open an editor within the terminal) and write your password
        3. Press “i” to start insert-mode and navigate to the end of the last line, then press enter
        4. Add the path /Library/Frameworks/GDAL.framework/Versions/Latest version/Programs
        5. Input :w to write the changes to the file and then :q to quit the editor

        You should now be able to access gdal_translate and the other included commands from any directory…

  5. lookez
    March 15, 2011 at 3:23 pm #

    The information i’m getting from google earth is 1st corner, 2nd corner. Do you know what this corresponds to in the image?

  6. Henry
    April 27, 2011 at 8:15 pm #

    For this line:
    -a_srs EPSG:4326
    What do I replace it with? my image is located in the desktop.
    I looked at the documentation but I am having a hard time understanding.

    Sorry I’m new to coding.

  7. Eugene Pavlyuk
    April 28, 2011 at 5:50 am #

    hey, guy. you are awesome. great article. you have helped me very much. thanks

  8. ViggoV
    May 12, 2011 at 6:22 am #

    Hi there..
    Thanks for the guide, it’s awesome… Except:
    Whether I use the MapTiler OR gdal2python.py (Which seem to produce the exact same result) the sample map keeps showing up when i run the code. I have deleted the Tiles folder and added my own, as described, and i have cleaned the target. I don’t understand why it keeps ignoring the new tiles..

    Any help will be appreciated!

    -Viggo

    • ViggoV
      May 12, 2011 at 6:53 am #

      Whoop.. Finally found out you have to delete the App from the device/simulator if you have run it before you modify it.. Solved!

      • sadaf
        June 22, 2011 at 9:14 am #

        can you please explain the steps in details to delete it i m also having the same problem

  9. l_h2o_l
    May 24, 2011 at 5:02 pm #

    Hi!,

    I’m having this error:


    python gdal2tiles.py -p mercator myMap.vrt
    Traceback (most recent call last):
    File "gdal2tiles.py", line 44, in
    import gdal
    ImportError: No module named gdal

    Any suggestions?

    thx!

    • Shawn Grimes
      May 24, 2011 at 6:39 pm #

      Did you try what ViggoV outlined above? It looks like it can’t find the gdal module

      Since i’m probably not the first nor last to have some difficulty here, let me explain how:

      1. Find /Library/Frameworks/GDAL.frameworks/Versions and note the latest version (1.8 in my case)
      2. Open terminal and write sudo vi /etc/paths (this will open an editor within the terminal) and write your password
      3. Press “i” to start insert-mode and navigate to the end of the last line, then press enter
      4. Add the path /Library/Frameworks/GDAL.framework/Versions/Latest version/Programs
      5. Input :w to write the changes to the file and then :q to quit the editor

      You should now be able to access gdal_translate and the other included commands from any directory…

  10. John D Pope
    June 11, 2011 at 9:36 am #

    Nice article and I like this site layout.

    If you have problems where the maps are rendering upside down…..
    between step 1 and 2 ) you may need to run gdal_translate and set the bounds for the tif file.
    From the obscure posts I’ve read, there’s a bug and you need to flip this value.

    Upper Left ( 0.0, 0.0)
    Lower Left ( 0.0, 4452.0)
    Upper Right ( 5722.0, 0.0)
    Lower Right ( 5722.0, 4452.0)

    the the Latitudes must be negative for southern hemisphere
    ie. -33.84115615981285 -> 33.84115615981285
    otherwise maps are upside down.
    Do this
    gdal_translate input.tif output.tif -of GTiff -a_ullr 33.84115615981285 151.23820066452026 33.84657400170756 151.24597907066345

    Not this
    gdal_translate input.tif output.tif -of GTiff -a_ullr -33.84115615981285 151.23820066452026 -33.84657400170756 151.24597907066345

    • paul
      June 25, 2011 at 10:55 am #

      Hy,

      Coul you please provide the code for this applcation.I am new in this field and I am interested in overlaying images over the MKMapView .

      Regards,
      Paul.

  11. Paul
    June 23, 2011 at 9:20 am #

    Hy,

    Could somebody send my also the xCode Project of the OverlayView
    I have to do a project were this could be helpful.
    Regards,
    Paul M

  12. Thomas
    August 21, 2011 at 12:19 pm #

    I thought I’d add that if you use .jpg tiles the TileMap code won’t recognize them, you can use .png or edit TileOverlay.m

Leave a Reply