GenerateGeodatabase job is failing while downloading offline map

5909
27
Jump to solution
01-11-2017 09:42 PM
VinayPrabhakar
New Contributor

Hi All,

Since we have updated our SDK to 100.0.0 we are unable to download offline Geodatabase map in our xamarin Application.

We are referring the sample code given at Create an offline map—ArcGIS Runtime SDK for .NET | ArcGIS for Developers 

Only thing we are not doing exactly as of the sample code is passing extent because,Below code throwing exception for us.

 Envelope extent = MyMapView.GetCurrentViewpoint(ViewpointType.BoundingGeometry).TargetGeometry as Envelope;
If I want to pass a generic extent which will cover all the map,What we need to pass in that case.
Before 100.0.0 we were  not passing any extent,In that case how everything was downloading smoothly?
If we are passing hard coded extent still no luck.
The Error I am getting is:
Job failed. Job error 22 User defined failure. Error while handling generate geodatabase job statu


0 Kudos
1 Solution

Accepted Solutions
ChadYoder1
Occasional Contributor II

Instead of using generateGdbJob.Start(), try using:

//Get the result
                var gdb = await gdbJob.GetResultAsync();

Where gdb is the Geodatabase object.  The error seems to hint it's something with the job.

Did you try calling the function I provided?

If that works, you could refactor for your needs.

View solution in original post

27 Replies
ChadYoder1
Occasional Contributor II

This code works for me in v. 100.  You'll have to change some of the things used in other classes, but hopefully it helps.

The map extent passed into this function is EsriMapView.VisibleArea.Extent.

/// <summary>
        /// Generates the offline gdb.
        /// </summary>
        /// <returns>The offline gdb.</returns>
        public static async Task<Geodatabase> GenerateOfflineGdbAsync(string mapName, Envelope mapExtent)
        {
            try {
                //Get the feature service and load it
                var url = await ConfigurationManager.GetSyncServiceUrlAsync ();

                //Create the task and get the default parameters
                var gdbSyncTask = await GeodatabaseSyncTask.CreateAsync (new Uri (url));
                var gdbParameters = await gdbSyncTask.CreateDefaultGenerateGeodatabaseParametersAsync(mapExtent);
                gdbParameters.AttachmentSyncDirection = AttachmentSyncDirection.Bidirectional;
                gdbParameters.ReturnAttachments = true;
                gdbParameters.SyncModel = SyncModel.Geodatabase;

                //Get the path and generate the geodatabase
                string gdbPath = Path.Combine (ConfigurationManager.AppDataDirectory, mapName);
                gdbPath = PathHelpers.CleanPath (gdbPath);
                if (!System.IO.Directory.Exists(gdbPath))
                    System.IO.Directory.CreateDirectory(gdbPath);
                gdbPath = Path.Combine(gdbPath , SettingsManager.GeodatabaseName);

                //Generate the Gdb and create the callback handler
                Job<Geodatabase> gdbJob = gdbSyncTask.GenerateGeodatabase (gdbParameters, gdbPath);
                gdbJob.JobChanged += (object sender, EventArgs evt) => {
#if WINDOWS_UWP
                    Debug.WriteLine("[GDB GENERATE STATUS MESSAGE] " + gdbJob.Status.ToString());
#else
                    Console.WriteLine("[GDB GENERATE STATUS MESSAGE] " + gdbJob.Status.ToString());
#endif
                };

                //Get the result
                var gdb = await gdbJob.GetResultAsync();

                //Check the result
                if (gdb == null) {
                    ToastHelpers.ShowError("Download Error", "Unable to download the selected feature data.\n\nError: " + gdbJob.Error.Message, 7);
                }
                else {
                    ToastHelpers.ShowSuccess("Map Data Download", "Successfully downloaded the map data for offline use.", 5);
                }
                return gdb;
            }
            catch (Exception ex) {
                ToastHelpers.ShowError("Error", ex.Message, 7);
                return null;
            }
        }

0 Kudos
VinayPrabhakar
New Contributor

Still same error.I am passing extent properly.

 public async Task<UtiliSyncMap> MakeMapAvailableOffline(UtiliSyncMap map, bool isManualSyc = false)
        {
            try
            {


                var maps = new Map(BasemapType.Streets, map.CenterYCoord, map.CenterXCoord, map.ZoomLevel);
                int currentLayerCount = 0;
                foreach (var mapService in map.MapServices)
                {
                    string mapServiceUrl = mapService.ServiceUrl.ToString().Substring(0, mapService.ServiceUrl.ToString().LastIndexOf("/"));
                    int layerAssociated = Convert.ToInt32((mapService.ServiceUrl.ToString().Substring(mapService.ServiceUrl.ToString().LastIndexOf('/') + 1)));
                    if (mapServiceUrl.Equals("https://services1.arcgis.com/BqQ60RORKMjmx3jf/arcgis/rest/services/SF_AGOL_TEST/FeatureServer") || mapServiceUrl.Equals("https://services6.arcgis.com/ExtdhXSbhHKK7FFW/arcgis/rest/services/SSMH_midvale/FeatureServer"))
                    {
                        currentLayerCount++;
                        int downloadedPercentage = getDownloadedPercentage(currentLayerCount, map.MapServices.Count);
                        Acr.UserDialogs.UserDialogs.Instance.HideLoading();
                        Acr.UserDialogs.UserDialogs.Instance.ShowLoading(string.Format("Downloading {0} of {1} Layers", currentLayerCount, map.MapServices));
                        continue;
                    }

                

                    string Username = Settings.Username;

                    string Password = Settings.Password;

                    //  var credential = await AuthenticationManager.Current.GenerateCredentialAsync(new Uri(url), Username, Password);
                    //-- commented by samrat 9th nov 3.58 pm
                    var credential = await AuthenticationManager.Current.GenerateCredentialAsync(new Uri(mapServiceUrl), "XXXX", "XXXXX");

                    //  var credential = await AuthenticationManager.Current.GenerateCredentialAsync(new Uri(url), Username, Password);

                    AuthenticationManager.Current.AddCredential(credential);
                    // var draftedForm = await formDefinitionService.GetAssociatedFormStatus(map.MapId, "SUBMITTED_DRAFT");

                    GenerateGeodatabaseParameters gdbParams = null;
                    try
                    {
                        currentLayerCount++;
                        //int urlCount = url.BaseURL.Length;


                        Acr.UserDialogs.UserDialogs.Instance.HideLoading();
                        int downloadedPercentage = getDownloadedPercentage(currentLayerCount, map.MapServices.Count);

                        Acr.UserDialogs.UserDialogs.Instance.ShowLoading(string.Format("Downloading {0} of {1} Layers", currentLayerCount, map.MapServices.Count));

                        Debug.WriteLine("Getting Service Info for " + mapService.ServiceUrl);


                     


                        if (!Directory.Exists("/storage/emulated/0/SmartMaps/OfflineMaps"))
                        {
                            System.IO.Directory.CreateDirectory("/storage/emulated/0/SmartMaps/OfflineMaps");
                        }

#if __UWP__
                        string gdbPath = Path.Combine(ApplicationData.Current.LocalFolder.Path, $"{mapService.MapServiceId}.geodatabase");
#else
                        //string gdbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), $"{map.MapId}-{i++}.geodatabase");
                        string gdbPath = Path.Combine("/storage/emulated/0/SmartMaps/OfflineMaps", $"{mapService.MapServiceId}.geodatabase");

#endif
                        if (!File.Exists(gdbPath) || isManualSyc)
                        {
                            // Envelope extent = MapView.GetCurrentViewpoint(ViewpointType.BoundingGeometry).TargetGeometry as Envelope;

                            //var gdbSyncTask = new GeodatabaseSyncTask(new Uri(mapServiceUrl));
                            //gdbParams = await gdbSyncTask.CreateDefaultGenerateGeodatabaseParametersAsync(extent);

                            //gdbParams.SyncModel = SyncModel.Layer;

                            //gdbParams.LayerOptions.Clear();


                            //gdbParams.LayerOptions.Add(new GenerateLayerOption(layerAssociated));
                            //Job <Geodatabase> gdbJob = gdbSyncTask.GenerateGeodatabase(gdbParams, gdbPath);

                            //Updated Downlaod code
                            // create a new GeodatabaseSyncTask to create a local version of feature service data
                            if(isManualSyc && File.Exists(gdbPath))
                            {
                                File.Delete(gdbPath);

                            }
                            var featureServiceUri = new Uri(mapServiceUrl);
                           // var featureServiceUri = new Uri("https://services1.arcgis.com/BqQ60RORKMjmx3jf/arcgis/rest/services/UtiliSync_Test/FeatureServer");
                            var gdbSyncTask = await GeodatabaseSyncTask.CreateAsync(featureServiceUri, credential);
                            // define an extent for the features to include
                            // Envelope extent = MyMapView.GetCurrentViewpoint(ViewpointType.BoundingGeometry).TargetGeometry as Envelope;
                            //Envelope extent = null;
                            // Envelope extent = new Viewpoint(new MapPoint(map.CenterXCoord, map.CenterYCoord, new SpatialReference(map.Wkid)), maps.InitialViewpoint.TargetScale).TargetGeometry.Extent ;

                            double XMin =Convert.ToDouble( Settings.XMin);
                            double YMin = Convert.ToDouble(Settings.YMin);
                            double XMax = Convert.ToDouble(Settings.XMax);
                            double YMax = Convert.ToDouble(Settings.YMax);
                            int wkid = Convert.ToInt32(Settings.SpatialReference);

                            Envelope extent = new Envelope(XMin, YMin, XMax, YMax, new SpatialReference(wkid));
                           // Envelope extent = new Envelope( map.CenterXCoord, map.CenterYCoord, map.CenterXCoord, map.CenterYCoord,new SpatialReference(map.Wkid));
                            
                            // get the default parameters for generating a geodatabase
                            var generateGdbParams = await gdbSyncTask.CreateDefaultGenerateGeodatabaseParametersAsync(extent);
                            // set the sync model to per layer
                            generateGdbParams.SyncModel = SyncModel.Layer;

                            generateGdbParams.SyncModel = SyncModel.Geodatabase;                         

                            // do not return attachments
                            generateGdbParams.ReturnAttachments = false;
                           
                            // create the generate geodatabase job, pass in the parameters and an output path for the local geodatabase
                            //File.Create(gdbPath);
                            var generateGdbJob = gdbSyncTask.GenerateGeodatabase(generateGdbParams, gdbPath);
                            // handle the JobChanged event to check the status of the job
                            generateGdbJob.JobChanged += OnGenerateGdbJobChanged;
                            // start the job and report the job ID
                            generateGdbJob.Start();
                            Debug.WriteLine("Submitted job #" + generateGdbJob.ServerJobId + " to create local geodatabase");
                          
                        }

                    }
                    catch (Exception ex)
                    {

                        Debug.WriteLine("Unable to download database for: " + mapService.ServiceUrl);
                        Debug.WriteLine(ex.ToString());
                        var cacheD = BlobCache.LocalMachine;

                        var allMapsD = await cacheD.GetObject<List<UtiliSyncMap>>("All Maps");

                        var cachedMapD = allMapsD.FirstOrDefault(x => x.MapId == map.MapId);

                        if (cachedMapD != null)
                        {
                            cachedMapD.LastSyncedDate = DateTime.Now;
                            cachedMapD.IsMapDownloaded = true;
                            // cachedMapD.SelectedMapColor = "Aqua";

                            Acr.UserDialogs.UserDialogs.Instance.HideLoading();

                            await cacheD.InsertObject("All Maps", allMapsD);
                        }

                  

        }

0 Kudos
ChadYoder1
Occasional Contributor II

Instead of using generateGdbJob.Start(), try using:

//Get the result
                var gdb = await gdbJob.GetResultAsync();

Where gdb is the Geodatabase object.  The error seems to hint it's something with the job.

Did you try calling the function I provided?

If that works, you could refactor for your needs.

VinayPrabhakar
New Contributor

tried with your suggestion.Now getting error like:

{Esri.ArcGISRuntime.Http.ArcGISWebException: Unable to create replica. Please check your parameters.

at Esri.ArcGISRuntime.Http.ArcGISHttpClientHandlerArcGISClientHandlerInternald__13.MoveNext () in :0

--- End of stack trace from previous location where exception was thrown ---

at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () in /Users/builder/data/lanes/3540/1cf254db/source/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143

at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) in /Users/builder/data/lanes/3540/1cf254db/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:187

at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) in /Users/builder/data/lanes/3540/1cf254db/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:156

at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) in /Users/builder/data/lanes/3540/1cf254db/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:128

at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[TResult].GetResult () in /Users/builder/data/lanes/3540/1cf254db/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:535

at System.Net.Http.HttpClient+c__async0.MoveNext () in /Users/builder/data/lanes/3540/1cf254db/source/mono/mcs/class/System.Net.Http/System.Net.Http/HttpClient.cs:276

--- End of stack trace from previous location where exception was thrown ---

at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () in /Users/builder/data/lanes/3540/1cf254db/source/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143

at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) in /Users/builder/data/lanes/3540/1cf254db/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:187

at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) in /Users/builder/data/lanes/3540/1cf254db/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:156

at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) in /Users/builder/data/lanes/3540/1cf254db/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:128

at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1+ConfiguredTaskAwaiter[TResult].GetResult () in /Users/builder/data/lanes/3540/1cf254db/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:535

at Esri.ArcGISRuntime.Internal.RequestRequiredHandler+d__14.MoveNext () in :0

--- End of stack trace from previous location where exception was thrown ---

at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () in /Users/builder/data/lanes/3540/1cf254db/source/mono/external/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143

at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) in /Users/builder/data/lanes/3540/1cf254db/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:187

at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) in /Users/builder/data/lanes/3540/1cf254db/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:156

at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) in /Users/builder/data/lanes/3540/1cf254db/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:128

at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult () in /Users/builder/data/lanes/3540/1cf254db/source/mono/external/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:357

at UtiliSyncTest.Services.EsriMapService+d__2.MoveNext () in D:\Xamarin\Source Code\Working copy\Backup\Vinay\2ndJan\UtiliSyncTest\UtiliSyncTest\Services\EsriMapService.cs:180 }

Thanks & Regards

Binay Prabhakar Yadav

Mobile: +91 8095648069

0 Kudos
ChadYoder1
Occasional Contributor II

When you run the test, are you using the Geodatabase sync model instead of the layer?  The code shows both, so just wondering what you are using.

Anything special in the service?

I'll try to wire it up in my code and see if it works.

0 Kudos
VinayPrabhakar
New Contributor

I am using layer.I have commneted the Geodatabase one.Still same issue.

Thanks & Regards

Binay Prabhakar Yadav

Mobile: +91 8095648069

0 Kudos
ChadYoder1
Occasional Contributor II

I did a quick test and was able to download the geodatabase.

Give the code I sent a try.

If you are using layer, give the geodatabase model a try.

0 Kudos
VinayPrabhakar
New Contributor

I think something may go wrong with extent.Any Idea how to pass extent.Your earlier mentioned way is returning null at my code.

Thanks & Regards

Binay Prabhakar Yadav

Mobile: +91 8095648069

0 Kudos
ChadYoder1
Occasional Contributor II

Has you map been activated before you try to get the VisibleArea.Extent?

For example, if you initially load a different page other than the map page, then this will give you null.  If you load the map page, then this will be set.

That is the only time I've seen it be null.  Hope this helps.

0 Kudos