AGSGenerateOfflineMapJob basemap Illegal state

940
4
05-23-2019 10:29 AM
WorthSparks
New Contributor III

I am using AGSGenerateOfflineMapJob to download a simple map package from a web map in ArcGIS Online. Sometimes it works but sometimes I get "Illegal state" on the basemap. In testing, it seems like making the boundary smaller helps. On my original test boundary (which was larger), I could consistently download the region successfully if the basemap was Streets but if the basemap was Topographic or Imagery it would come back saying that layer was in error with "Illegal state" as the message. I used Tile Package Estimator on the same region, which, because it is an envelope formed by the screen, should be larger. It returned the following for the three basemaps:

  • Streets: Levels 0 - 19 (10,128 tiles) (36.991MB)
  • Topographic: Levels 0 - 19 (10,128 tiles) (44.35MB)
  • Imagery: Levels 0 - 19 (10,128 tiles) (148.146MB)

I condensed what I'm doing down to this simple function (in Swift) for this post:

func testDownload(agsPortalItem: AGSPortalItem, boundaryPolygon: AGSPolygon, url: URL) {
    let offlineMapTask = AGSOfflineMapTask(portalItem: agsPortalItem)
    self.offlineMapTask = offlineMapTask
    offlineMapTask.defaultGenerateOfflineMapParameters(withAreaOfInterest: boundaryPolygon) { (parameters, error) in
        let generateOfflineMapJob = offlineMapTask.generateOfflineMapJob(with: parameters!, downloadDirectory: url)
        // skipping typical progress indicator setup
        generateOfflineMapJob.start(statusHandler: nil) { (result, error) in
            if let error = error {
                print(error.localizedDescription)
            } else if let layerErrors = result!.layerErrors as? [AGSLayer: Error], !layerErrors.isEmpty {
                let layerErrorMessages = layerErrors.map { "\($0.key.name): \($0.value.localizedDescription)" }
                print("layer errors: \(layerErrorMessages)")
            } else {
                print("Success")
            }
        }
    }
}
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

What am I doing wrong? Are there limits I need to avoid or override?

0 Kudos
4 Replies
WorthSparks
New Contributor III

OK, I just found the notes on the map services for the basemaps saying to use the alternate map services for exporting. I'm guessing this is what I was running into. So if I understand correctly, I need to make and use a separate tile cache if the user is going offline with a map that uses one of the Esri basemaps. Is there a documented lookup tool that cross-references from ArcGIS Online interactive map service to export-friendly map service? Or should I build my own?

0 Kudos
Nicholas-Furness
Esri Regular Contributor

Hi Worth Sparks,

For standard raster tiled basemaps, the OfflineMapTask will map those services appropriately (i.e. if your map uses Streets, the OfflineMapTask will use Streets for Export).

The standard basemaps don't even allow for export (scroll down and compare the Supported Operations here (Standard) and here (For Export)).

Those tile counts are well within the 150,000 maxExportTilesCount for Streets and Imagery (I haven't checked Topo). IMO it should just work.  Based off status.arcgis.com and the date of your post, perhaps you were just bumping into the problems ArcGIS Online was having that day…

Are you still having issues? Let me know. If so I can check with the ArcGIS Online team and see what they have to say.

Nick

P.S. When you're using Vector Tiles, the difference between the Standard and For Export versions is actually in the styles (fewer fonts for export). Both can be exported, so the OfflineMapTask does not map the services as it does for the raster basemaps.

0 Kudos
WorthSparks
New Contributor III

I just retried the code doing the same thing. The hosted map is using Topo as its basemap. I still get the error message on the layer, "World Topographic Map: Illegal state". If it helps, I ran the test today at 4:24pm eastern (Tuesday, 5/28/2019). I ran it again on the smaller boundary in the same map and it worked great.

Nicholas-Furness
Esri Regular Contributor

Hey Worth,

To help us narrow this down…

  1. Could you print the entire Error you get back (beyond just the localizedDescription). The additionalMessage might give us some more insight.
  2. Could you confirm that all the basemaps you're talking about above are raster? Or is "Streets" the vector tile basemap? What about Topographic? Remember the Topographic Vector with relief actually uses a raster hillshade for the relief. Ignoring the test web app, we wonder if you're OK with vector tiles (Streets) but hitting raster limits with the other two.
  3. You could set AGSRequestConfiguration.global().debugLogRequests and debugLogResponses to true and let me know what you get for the request that's sent out.
  4. You could try the AGSExportTileCacheTask.estimateTileCacheSizeJobWithParameters() and execute that job from your app to see if it matches the web app and gives sensible values in the EstimateTileCacheResult.

Feel free to DM me with info if you like.

Cheers,

Nick.

P.S. I also noticed that the TPK Estimator might be failing at its task (technically it's a TPK creator, but the web page has the wrong title )… For a (client-side-calculated) estimate of 7,580 tiles, the service actually came back with 16,093. I will have to look into that. As I mentioned, the estimator is oooooooooold, and it's quite possible that stuff has changed without me noticing and updating it.

0 Kudos