JohnWeston44

ExportTileCache Runtime v100.0

Discussion created by JohnWeston44 on Jan 27, 2017
Latest reply on Jan 27, 2017 by JNery-esristaff

Unfortunately, the latest SDK lacks examples on caching tiles from a service.  How do I use ExportTileCache on a service?

A complete example would be much appreciated.

 

This is the map I want to cache:

http://www.arcgis.com/home/item.html?id=226d23f076da478bba4589e7eae95952 

 

From what I've read and understood, these are the steps I followed to use ExportTileCache:

 

1. Register app online

2. Setup AuthenticationManager with Server Info (client id, client secret, oauth2 settings)

3. register ServerInfo

4. Setup export cache parameters

5. Call ExportTileCache on the service

 

Upon calling ExportTileCache on the service I get the error 'Token required'.  Shouldn't ExportTileCache initiate a challenge procedure from the service and in doing so get a token, all handled by the AuthenticationManager?

 

I am also unsure which URL should be used where.  I assume the first URL(SERVICE_OFFLINE_URL) specified here is the URL that I should pass as the ServerUri to ServerInfo, and the fully qualified basemap url(BASEMAP_OFFLINE_URL) passed to ExportTileCache.CreateAsync.  Am I correct?

private const string SERVICE_OFFLINE_URL = "https://tiledbasemaps.arcgis.com/arcgis/rest";
private const string OTHER_URL = "https://www.arcgis.com/sharing/rest";
private const string BASEMAP_OFFLINE_URL = "https://tiledbasemaps.arcgis.com/arcgis/rest/services/World_Imagery/MapServer";
private const string OAUTH2_URN = "urn:ietf:wg:oauth:2.0:oob";

 

private async void CreateTileCacheAsync()
{
    Envelope extent =
        new Envelope(
            new MapPoint(-25.6129589203346, 27.9394285297344, SpatialReferences.Wgs84),
            new MapPoint(-26.1950346130634, 29.2006589984844, SpatialReferences.Wgs84));

    Authentication.Initialize(CLIENT_ID, CLIENT_SECRET, SERVICE_OFFLINE_URL, OAUTH2_URN);
    var t = await ExportTileCacheTask.CreateAsync(new Uri(BASEMAP_OFFLINE_URL), creds);

    var cacheParams = await t.CreateDefaultExportTileCacheParametersAsync(extent, 8000, 2000);

    var outFolder = System.AppDomain.CurrentDomain.BaseDirectory;
    var job = t.ExportTileCache(cacheParams, outFolder + "asdf.tpk");
    var result = await job.GetResultAsync();

    Debug.WriteLine("Tile Cache created at " + result.Path);
    Debug.WriteLine("format: " + result.CacheStorageFormat);
}

 

 

Authentication code:

 

The ChallengeHandler and OAuthAuthorizeHandler are taken from the sample code in the runtime samples Security section.

    public static class Authentication
    {
        public static void Initialize(string clientId, string clientSecret, String serverUrl, String redirectUrl)
        {
            ClientId = clientId;
            ClientSecret = clientSecret;
            ServerUrl = serverUrl;
            RedirectUrl = redirectUrl;

            UpdateAuthenticationManager();
        }

        private static string ClientId { get; set; }
        private static string ClientSecret { get; set; }
        private static string ServerUrl { get; set; }
        private static string RedirectUrl { get; set; }

        private static void UpdateAuthenticationManager()
        {

            Esri.ArcGISRuntime.Security.ServerInfo serverInfo = new ServerInfo
            {
                ServerUri = new Uri(ServerUrl),
                OAuthClientInfo = new OAuthClientInfo
                {
                    ClientId = ClientId,
                    RedirectUri = new Uri(RedirectUrl)
                }
            };


            if (!string.IsNullOrEmpty(ClientSecret))
            {
                serverInfo.TokenAuthenticationType = TokenAuthenticationType.OAuthAuthorizationCode;
                serverInfo.OAuthClientInfo.ClientSecret = ClientSecret;
                serverInfo.TokenServiceUri = new Uri(TOKEN_SERVICE_URL);

            }
            else
            {
                serverInfo.TokenAuthenticationType = TokenAuthenticationType.OAuthImplicit;
            }

            AuthenticationManager.Current.RegisterServer(serverInfo);
            AuthenticationManager.Current.OAuthAuthorizeHandler = new OAuthAuthorize();
            AuthenticationManager.Current.ChallengeHandler = new ChallengeHandler(CreateCredentialAsync);
        }

// ...

 

        public static async Task<Credential> CreateCredentialAsync(CredentialRequestInfo info)
        {
            OAuthTokenCredential credential = null;

            try
            {
                // Create generate token options if necessary
                if (info.GenerateTokenOptions == null)
                    info.GenerateTokenOptions = new GenerateTokenOptions();

                // AuthenticationManager will handle challenging the user for credentials
                credential = await AuthenticationManager.Current.GenerateCredentialAsync(
                            info.ServiceUri,
                            info.GenerateTokenOptions)
                                as OAuthTokenCredential;
            }
            catch (Exception ex)
            {
                throw (ex);
            }

            return credential;
        }

Outcomes