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
Solved! Go to Solution.
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.
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;
}
}
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);
}
}
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.
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
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.
I am using layer.I have commneted the Geodatabase one.Still same issue.
Thanks & Regards
Binay Prabhakar Yadav
Mobile: +91 8095648069
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.
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
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.