I write solutions to the problems I can't find much about elsewhere on the Web, also some code/script snippets that are absolutely awesome and make my life easier. Will be glad if someone finds these posts interesting and helpful!

Tuesday, June 7, 2011

Offline tiled layer with ArcGIS for Android

On the official ArcGIS mobile blog they have described how to create an offline tiled layer for iOS, but not a word about Android (probably because it's still in beta, thing might change and it doesn't gain any publicity anyway). The idea was taken from this blog: if not for that, I would've not even attempted to look into this direction. So thank God for a custom hack!
My first attempt for offline tiles was to create a local tile server and in the ArcGISTiledMapServiceLayer as a URL supply something with localhost in it. It totally worked, but there were two issues that forced me to look for another solution. Number one was technical: as soon as the connection was down (e.g. Airplane mode turned on) the tiles would just stop to download (even though their physical location was on the same SD card the application was installed on!); the second issue was mental: just for knowing that the files stored locally had to take a trip to the moon before being rendered (let alone maintaining a whole process of a local map server), caused an allergy and made me invest some time into research.
So here we go with offline tiled layer. Easier than easy, with a very little code, but totally impossible to find out how to make it! At least at the current version of ArcGIS for Android all the interesting stuff regarding custom tiled layers is undocumented.
Here's the implementation of the custom tiled layer:
Here's a usage example:

Now about the filesystem. In the usage example I have set some values to the OfflineTiledLayer constructor and these represent the directory structure. First off, I didn't use the cache created by ArcGIS. I mentioned in the beginning of the post that earlier I had implemented a local map server, that's why the file paths reflect the ones used by the online map servers. For instance, the absolute path of the tile at zoom level 3/row 44/column 65 looks like /mnt/sdcard/services/RoadMapsWebMercator101010/MapServer/tile/3/44/65. I guess it's not hard at all to modify my class to use the HEX paths of the cache created by ArcGIS.
Finally, a couple words about the map server specification. That paramter index.html of the OfflineTiledLayer constructor represents this. Again, I named it index.html to support the local map server implemented earlier, but in fact it contains what an online map server outputs by clicking on the link "REST" on the bottom of the MapServer description page of the ArcGIS server (the address looks something like /MapServer?f=json&pretty=true). 

And that's totally it. Hope it helps!

4 comments:

  1. Hi,

    This is the only example I found on the web, however after I tried, I encountered following errors:

    ERROR/ArcGIS(2117): Failed to initialize the layer:null
    ERROR/ArcGIS(2117): java.lang.NullPointerException
    ERROR/ArcGIS(2117): at com.stee.android.agoffline.OfflineTiledLayer.initModel(OfflineTiledLayer.java:43)
    ERROR/ArcGIS(2117): at com.stee.android.agoffline.OfflineTiledLayer.initModel(OfflineTiledLayer.java:1)
    ERROR/ArcGIS(2117): at com.esri.android.map.LayerView.initLayer(Unknown Source)
    ERROR/ArcGIS(2117): at com.esri.android.map.MapView$1.a(Unknown Source)
    ERROR/ArcGIS(2117): at com.esri.android.map.MapView$1.call(Unknown Source)
    ERROR/ArcGIS(2117): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
    ERROR/ArcGIS(2117): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
    ERROR/ArcGIS(2117): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
    ERROR/ArcGIS(2117): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
    ERROR/ArcGIS(2117): at java.lang.Thread.run(Thread.java:1096)

    occurred at the line passing JSON file and my json file path: /sdcard/cachetest/cachetest/2.json


    Would much appreciate if you can help!

    ReplyDelete
  2. Ouch! Sorry it took me like 3 weeks to see your comment. Are you sure that the JSON file has the right look and is located in the right directory?
    I know it's a pain in the ass to debug a project with ArcGIS for Android, simply because the project gets so heavy (!!!) as soon as you add the jars to the classpath!

    ReplyDelete
  3. Hi Thanks for posting. ESRI release a new V2 version and I have trouble getting it to work with the newer Version. Especially with importing the neccesary classes Do you vave a newer version?

    Thank you
    Martin

    ReplyDelete
  4. Hello Elijah

    I went trough your example, and i couldn't found the Class com.esri.core.map.TiledLayerModel.
    In which SDK is this class included, or is it custom?

    Thanks in advance
    Matej

    ReplyDelete