private async void CanBeTakenOffline(OfflineMapTask task, GenerateOfflineMapParameters parameters) { OfflineMapCapabilities results = await task.GetOfflineMapCapabilitiesAsync(parameters); if (results.HasErrors) { // Handle possible errors with layers foreach (var layerCapability in results.LayerCapabilities) { if (!layerCapability.Value.SupportsOffline) { Debug.WriteLine(layerCapability.Key.Name + " cannot be taken offline. Error : " + layerCapability.Value.Error.Message); } } // Handle possible errors with tables foreach (var tableCapability in results.TableCapabilities) { if (!tableCapability.Value.SupportsOffline) { Debug.WriteLine(tableCapability.Key.TableName + " cannot be taken offline. Error : " + tableCapability.Value.Error.Message); } } } else { // All layers and tables can be taken offline! MessageBox.Show("All layers are good to go!"); Debug.WriteLine("All layers are good to go!"); } }
private async void TakeMapOfflineButton_Click(object sender, EventArgs e) { // Create a path for the output mobile map. string tempPath = $"{Path.GetTempPath()}"; string[] outputFolders = Directory.GetDirectories(tempPath, "NapervilleWaterNetwork*"); // Loop through the folder names and delete them. foreach (string dir in outputFolders) { try { // Delete the folder. Directory.Delete(dir, true); } catch (Exception) { // Ignore exceptions (files might be locked, for example). } } // Create a new folder for the output mobile map. _packagePath = Path.Combine(tempPath, @"NapervilleWaterNetwork"); int num = 1; while (Directory.Exists(_packagePath)) { _packagePath = Path.Combine(tempPath, @"NapervilleWaterNetwork" + num.ToString()); num++; } // Create the output directory. Directory.CreateDirectory(_packagePath); try { // Create an offline map task with the current (online) map. _takeMapOfflineTask = await OfflineMapTask.CreateAsync(_mapView.Map); // Create the default parameters for the task, pass in the area of interest. _parameters = await _takeMapOfflineTask.CreateDefaultGenerateOfflineMapParametersAsync(_areaOfInterest); // Get the overrides. _overrides = await _takeMapOfflineTask.CreateGenerateOfflineMapParameterOverridesAsync(_parameters); // Create the overrides UI. ParameterOverrideFragment overlayFragment = new ParameterOverrideFragment(_overrides, _mapView.Map); // Complete configuration when the dialog is closed. overlayFragment.FinishedConfiguring += ConfigurationContinuation; // Display the configuration window. overlayFragment.Show(FragmentManager, ""); } catch (Exception ex) { // Exception while taking the map offline. ShowStatusMessage(ex.Message); } }
private void ConfigureOfflineJobForBasemap(GenerateOfflineMapParameters parameters) { // Don't give the user a choice if there is no basemap specified. if (String.IsNullOrWhiteSpace(parameters.ReferenceBasemapFilename)) { return; } // Get the path to the basemap directory. string basemapBasePath = DataManager.GetDataFolder("85282f2aaa2844d8935cdb8722e22a93"); // Get the full path to the basemap by combining the name specified in the web map (ReferenceBasemapFilename) // with the offline basemap directory. string basemapFullPath = Path.Combine(basemapBasePath, parameters.ReferenceBasemapFilename); // If the offline basemap doesn't exist, proceed without it. if (!File.Exists(basemapFullPath)) { return; } // Get the user's choice. MessageBoxResult userChoice = MessageBox.Show("Use the offline basemap?", "Basemap choice", MessageBoxButton.YesNo); // If the user approves, use the offline basemap. if (userChoice == MessageBoxResult.Yes) { parameters.ReferenceBasemapDirectory = basemapBasePath; } }
private async Task ConfigureOfflineJobForBasemap(GenerateOfflineMapParameters parameters) { // Don't give the user a choice if there is no basemap specified. if (String.IsNullOrWhiteSpace(parameters.ReferenceBasemapFilename)) { return; } // Get the path to the basemap directory. string basemapBasePath = DataManager.GetDataFolder("628e8e3521cf45e9a28a12fe10c02c4d"); // Get the full path to the basemap by combining the name specified in the web map (ReferenceBasemapFilename) // with the offline basemap directory. string basemapFullPath = Path.Combine(basemapBasePath, parameters.ReferenceBasemapFilename); // If the offline basemap doesn't exist, proceed without it. if (!File.Exists(basemapFullPath)) { return; } // Create a dialog for getting the user's basemap choice. MessageDialog dialog = new MessageDialog("Use the offline basemap?", "Basemap choice"); // If the user selects OK, parameters.ReferenceBasemapDirectory will be set. dialog.Commands.Add(new UICommand("Yes", command => parameters.ReferenceBasemapDirectory = basemapBasePath)); // Do nothing otherwise. dialog.Commands.Add(new UICommand("No")); // Wait for the user to choose. await dialog.ShowAsync(); }
private async Task ConfigureOfflineJobForBasemap(GenerateOfflineMapParameters parameters) { // Don't give the user a choice if there is no basemap specified. if (String.IsNullOrWhiteSpace(parameters.ReferenceBasemapFilename)) { return; } // Get the path to the basemap directory. string basemapBasePath = DataManager.GetDataFolder("628e8e3521cf45e9a28a12fe10c02c4d"); // Get the full path to the basemap by combining the name specified in the web map (ReferenceBasemapFilename) // with the offline basemap directory. string basemapFullPath = Path.Combine(basemapBasePath, parameters.ReferenceBasemapFilename); // If the offline basemap doesn't exist, proceed without it. if (!File.Exists(basemapFullPath)) { return; } // Wait for the user to choose whether to use the offline basemap. bool useBasemap = await Application.Current.MainPage.DisplayAlert("Basemap choice", "Use the offline basemap?", "Yes", "No"); if (useBasemap) { // Configure the offline basemap if the user said yes. parameters.ReferenceBasemapDirectory = basemapBasePath; } }
private static async Task DownloadMapAsync(PortalItem portalItem) { Map onlineMap = new Map(portalItem); var takeMapOfflineTask = await OfflineMapTask.CreateAsync(onlineMap); // Create the job to generate an offline map, pass in the parameters and a path to //store the map package. var parameters = new GenerateOfflineMapParameters() { MaxScale = 5000, IncludeBasemap = true, }; var path = MapAreaManager.GetOfflineMapPath("reference_base_map", true); GenerateOfflineMapJob generateMapJob = takeMapOfflineTask.GenerateOfflineMap(parameters, path); // Generate the offline map and download it. GenerateOfflineMapResult offlineMapResult = await generateMapJob.GetResultAsync(); if (!offlineMapResult.HasErrors) { // Job completed successfully and all content was generated. Debug.WriteLine("Map " + offlineMapResult.MobileMapPackage.Item.Title + " was saved to " + offlineMapResult.MobileMapPackage.Path); } else { // Job is finished but one or more layers or tables had errors. if (offlineMapResult.LayerErrors.Count > 0) { // Show layer errors. foreach (var layerError in offlineMapResult.LayerErrors) { Debug.WriteLine("Error occurred when taking " + layerError.Key.Name + " offline. Error : " + layerError.Value.Message); } } if (offlineMapResult.TableErrors.Count > 0) { // Show table errors. foreach (var tableError in offlineMapResult.TableErrors) { Debug.WriteLine("Error occurred when taking " + tableError.Key.TableName + " offline. Error : " + tableError.Value.Message); } } } }
public async void generateOfflineMap() { OfflineMapTask task = await OfflineMapTask.CreateAsync(mapView.Map); Envelope initialLocation = new Envelope(375474, 120000, 422020, 152000, new SpatialReference(26985)); GenerateOfflineMapParameters parameters = await task.CreateDefaultGenerateOfflineMapParametersAsync(initialLocation); GenerateOfflineMapJob generateMapJob = task.GenerateOfflineMap(parameters, "C:\\RuntimeArcgis"); GenerateOfflineMapResult results = await generateMapJob.GetResultAsync(); }
private async void CreateOfflineMapTask() { AuthenticationManager.Current.ChallengeHandler = new Esri.ArcGISRuntime.Security.ChallengeHandler(CreateKnownCredentials); // Create task and set parameters OfflineMapTask task = await OfflineMapTask.CreateAsync(MyMapView.Map); GenerateOfflineMapParameters parameters = await GenerateGeodatabaseParameters(task, webmapItem); CanBeTakenOffline(task, parameters); GenerateOfflineMap(task, parameters); }
private async Task <GenerateOfflineMapParameters> GenerateGeodatabaseParameters(OfflineMapTask task, PortalItem webmapItem) { // Create default parameters //Envelope areaOfInterest = new Envelope(-12211308.778729, 4645116.003309, -12208257.879667, 4650542.535773, SpatialReferences.WebMercator); //GenerateOfflineMapParameters parameters = await task.CreateDefaultGenerateOfflineMapParametersAsync(areaOfInterest); GenerateOfflineMapParameters parameters = await task.CreateDefaultGenerateOfflineMapParametersAsync(MyMapView.Map.InitialViewpoint.TargetGeometry.Extent); // Update the parameters if needed // Limit maximum scale to 5000 but take all the scales above (use 0 as a MinScale) //parameters.MaxScale = 5000; // Set attachment options parameters.AttachmentSyncDirection = AttachmentSyncDirection.Upload; parameters.ReturnLayerAttachmentOption = ReturnLayerAttachmentOption.EditableLayers; parameters.IncludeBasemap = true; // Request the table schema only (existing features won’t be included) parameters.ReturnSchemaOnlyForEditableLayers = false; // Update the title to contain the region parameters.ItemInfo.Title = parameters.ItemInfo.Title + " (Central)"; // Override thumbnail with the new image based on the extent RuntimeImage thumbnail = await MyMapView.ExportImageAsync(); // Create new item info OfflineMapItemInfo itemInfo = new OfflineMapItemInfo(); // Create new thumbnail from the map RuntimeImage thumbnailImage = await MyMapView.ExportImageAsync(); // Set values to the itemInfo itemInfo.Thumbnail = thumbnailImage; itemInfo.Title = "Water network (Central)"; itemInfo.Snippet = webmapItem.Snippet; // Copy from the source map itemInfo.Description = webmapItem.Description; // Copy from the source map itemInfo.AccessInformation = webmapItem.AccessInformation; // Copy from the source map itemInfo.Tags.Add("Water network"); itemInfo.Tags.Add("Data validation"); // Set metadata to parameters parameters.ItemInfo = itemInfo; return(parameters); }
public async void init() { try { MobileMapPackage offlineMapPackage = await MobileMapPackage.OpenAsync("C:/TEMPCD"); // Get the map from the package and set it to the MapView var map = offlineMapPackage.Maps.First(); Map = map; } catch (Exception e) { ArcGISPortal portal = await ArcGISPortal.CreateAsync(); // Get a web map item using its ID. PortalItem webmapItem = await PortalItem.CreateAsync(portal, "a72f2553da664a41b5f00583f7780206"); // Create a map from the web map item. _map = new Map(webmapItem); Map = _map; // Create an OfflineMapTask from the map ... OfflineMapTask takeMapOfflineTask = await OfflineMapTask.CreateAsync(_map); // ... or a web map portal item. // Create the default parameters for the task, pass in the area of interest. GenerateOfflineMapParameters parameters = await takeMapOfflineTask.CreateDefaultGenerateOfflineMapParametersAsync(new Envelope(375474, 120000, 422020, 152000, new SpatialReference(26985))); // Create the job with the parameters and output location. var _generateOfflineMapJob = takeMapOfflineTask.GenerateOfflineMap(parameters, "C:/TEMPCD"); // Handle the progress changed event for the job. // _generateOfflineMapJob.ProgressChanged += OfflineMapJob_ProgressChanged; // Await the job to generate geodatabases, export tile packages, and create the mobile map package. GenerateOfflineMapResult results = await _generateOfflineMapJob.GetResultAsync(); Map = results.OfflineMap; } }
private async void GenerateOfflineMap(OfflineMapTask task, GenerateOfflineMapParameters parameters) { string pathToOutputPackage = @"C:\My Documents\Readiness\Trainings\Runtime 100.1\Demos\OfflineMap"; // Create a job and provide needed parameters GenerateOfflineMapJob job = task.GenerateOfflineMap(parameters, pathToOutputPackage); // Generate the offline map and download it GenerateOfflineMapResult results = await job.GetResultAsync(); if (!results.HasErrors) { // Job is finished and all content was generated Debug.WriteLine("Map " + results.MobileMapPackage.Item.Title + " saved to " + results.MobileMapPackage.Path); // Show offline map in a MapView MyMapView.Map = results.OfflineMap; } else { // Job is finished but some of the layers/tables had errors if (results.LayerErrors.Count > 0) { foreach (var layerError in results.LayerErrors) { Debug.WriteLine("Error occurred when taking " + layerError.Key.Name + " offline. Error : " + layerError.Value.Message); } } if (results.TableErrors.Count > 0) { foreach (var tableError in results.TableErrors) { Debug.WriteLine("Error occurred when taking " + tableError.Key.TableName + " offline. Error : " + tableError.Value.Message); } } } }
private void ConfigureOfflineJobForBasemap(GenerateOfflineMapParameters parameters, Action completionHandler) { // Don't give the user a choice if there is no basemap specified. if (String.IsNullOrWhiteSpace(parameters.ReferenceBasemapFilename)) { return; } // Get the path to the basemap directory. string basemapBasePath = DataManager.GetDataFolder("628e8e3521cf45e9a28a12fe10c02c4d"); // Get the full path to the basemap by combining the name specified in the web map (ReferenceBasemapFilename) // with the offline basemap directory. string basemapFullPath = Path.Combine(basemapBasePath, parameters.ReferenceBasemapFilename); // If the offline basemap doesn't exist, proceed without it. if (!File.Exists(basemapFullPath)) { return; } // Create the dialog for getting the user's choice. AlertDialog.Builder basemapAlert = new AlertDialog.Builder(this).SetMessage("Use the offline basemap?").SetTitle("Basemap choice"); // Add the 'yes' choice. When the user selects it, the basemap directory will be set and the job will continue. basemapAlert = basemapAlert.SetPositiveButton("Yes", (o, e) => { parameters.ReferenceBasemapDirectory = basemapBasePath; completionHandler.Invoke(); }); // Add the 'no' choice. When the user selects it, the job will continue using the online map. basemapAlert = basemapAlert.SetNegativeButton("No", (o, e) => completionHandler.Invoke()); // Show the dialog. basemapAlert.Show(); }
private void ConfigureOfflineJobForBasemap(GenerateOfflineMapParameters parameters, Action completionAction) { // Don't give the user a choice if there is no basemap specified. if (String.IsNullOrWhiteSpace(parameters.ReferenceBasemapFilename)) { return; } // Get the path to the basemap directory. string basemapBasePath = DataManager.GetDataFolder("628e8e3521cf45e9a28a12fe10c02c4d"); // Get the full path to the basemap by combining the name specified in the web map (ReferenceBasemapFilename) // with the offline basemap directory. string basemapFullPath = Path.Combine(basemapBasePath, parameters.ReferenceBasemapFilename); // If the offline basemap doesn't exist, proceed without it. if (!File.Exists(basemapFullPath)) { return; } UIAlertController basemapAlert = UIAlertController.Create("Basemap choice", "Use the offline basemap?", UIAlertControllerStyle.Alert); // Configure the directory and move on when the user says 'yes'. basemapAlert.AddAction(UIAlertAction.Create("Yes", UIAlertActionStyle.Default, uiAlertAction => { parameters.ReferenceBasemapDirectory = basemapBasePath; completionAction.Invoke(); })); // Do nothing and move on if the user says no. basemapAlert.AddAction(UIAlertAction.Create("No", UIAlertActionStyle.Cancel, action => completionAction.Invoke())); // Show the alert. PresentViewController(basemapAlert, true, null); }
private async void TakeMapOfflineButton_Click(object sender, EventArgs e) { // Create a path for the output mobile map. string tempPath = $"{Path.GetTempPath()}"; string[] outputFolders = Directory.GetDirectories(tempPath, "NapervilleWaterNetwork*"); // Loop through the folder names and delete them. foreach (string dir in outputFolders) { try { // Delete the folder. Directory.Delete(dir, true); } catch (Exception) { // Ignore exceptions (files might be locked, for example). } } // Create a new folder for the output mobile map. string packagePath = Path.Combine(tempPath, @"NapervilleWaterNetwork"); int num = 1; while (Directory.Exists(packagePath)) { packagePath = Path.Combine(tempPath, @"NapervilleWaterNetwork" + num.ToString()); num++; } // Create the output directory. Directory.CreateDirectory(packagePath); // Show the progress dialog while the job is running. _alertDialog.Show(); // Create an offline map task with the current (online) map. OfflineMapTask takeMapOfflineTask = await OfflineMapTask.CreateAsync(_mapView.Map); // Create the default parameters for the task, pass in the area of interest. GenerateOfflineMapParameters parameters = await takeMapOfflineTask.CreateDefaultGenerateOfflineMapParametersAsync(_areaOfInterest); // Configure basemap settings for the job. ConfigureOfflineJobForBasemap(parameters, async() => { try { // Create the job with the parameters and output location. _generateOfflineMapJob = takeMapOfflineTask.GenerateOfflineMap(parameters, packagePath); // Handle the progress changed event for the job. _generateOfflineMapJob.ProgressChanged += OfflineMapJob_ProgressChanged; // Await the job to generate geodatabases, export tile packages, and create the mobile map package. GenerateOfflineMapResult results = await _generateOfflineMapJob.GetResultAsync(); // Check for job failure (writing the output was denied, e.g.). if (_generateOfflineMapJob.Status != JobStatus.Succeeded) { // Report failure to the user. ShowStatusMessage("Failed to take the map offline."); } // Check for errors with individual layers. if (results.LayerErrors.Any()) { // Build a string to show all layer errors. StringBuilder errorBuilder = new StringBuilder(); foreach (KeyValuePair <Layer, Exception> layerError in results.LayerErrors) { errorBuilder.AppendLine($"{layerError.Key.Id} : {layerError.Value.Message}"); } // Show layer errors. ShowStatusMessage(errorBuilder.ToString()); } // Display the offline map. _mapView.Map = results.OfflineMap; // Apply the original viewpoint for the offline map. _mapView.SetViewpoint(new Viewpoint(_areaOfInterest)); // Enable map interaction so the user can explore the offline data. _mapView.InteractionOptions.IsEnabled = true; // Change the title and disable the "Take map offline" button. _takeMapOfflineButton.Text = "Map is offline"; _takeMapOfflineButton.Enabled = false; } catch (TaskCanceledException) { // Generate offline map task was canceled. ShowStatusMessage("Taking map offline was canceled"); } catch (Exception ex) { // Exception while taking the map offline. ShowStatusMessage(ex.Message); } finally { // Hide the loading overlay when the job is done. _alertDialog.Dismiss(); } }); }
private async void TakeMapOfflineButton_Click(object sender, EventArgs e) { // Make sure the user is logged in. /* * bool loggedIn = await EnsureLoggedInAsync(); * if (!loggedIn) * { * return; * } */ // Disable the button to prevent errors. _takeMapOfflineButton.Enabled = false; // Show the loading indicator. _loadingIndicator.StartAnimating(); // Create a path for the output mobile map. string tempPath = $"{Path.GetTempPath()}"; string[] outputFolders = Directory.GetDirectories(tempPath, "NapervilleWaterNetwork*"); // Loop through the folder names and delete them. foreach (string dir in outputFolders) { try { // Delete the folder. Directory.Delete(dir, true); } catch (Exception ex) { // Ignore exceptions (files might be locked, for example). Debug.WriteLine(ex); } } // Create a new folder for the output mobile map. string packagePath = Path.Combine(tempPath, @"NapervilleWaterNetwork"); int num = 1; while (Directory.Exists(packagePath)) { packagePath = Path.Combine(tempPath, @"NapervilleWaterNetwork" + num); num++; } // Create the output directory. Directory.CreateDirectory(packagePath); try { // Show the loading overlay while the job is running. _statusLabel.Text = "Taking map offline..."; // Create an offline map task with the current (online) map. OfflineMapTask takeMapOfflineTask = await OfflineMapTask.CreateAsync(_myMapView.Map); // Create the default parameters for the task, pass in the area of interest. GenerateOfflineMapParameters parameters = await takeMapOfflineTask.CreateDefaultGenerateOfflineMapParametersAsync(_areaOfInterest); // Generate parameter overrides for more in-depth control of the job. GenerateOfflineMapParameterOverrides overrides = await takeMapOfflineTask.CreateGenerateOfflineMapParameterOverridesAsync(parameters); // Show the configuration window. ShowConfigurationWindow(overrides); // Finish work once the user has configured the override. _overridesVC.FinishedConfiguring += async() => { // Hide the configuration UI. _overridesVC.DismissViewController(true, null); // Create the job with the parameters and output location. _generateOfflineMapJob = takeMapOfflineTask.GenerateOfflineMap(parameters, packagePath, overrides); // Handle the progress changed event for the job. _generateOfflineMapJob.ProgressChanged += OfflineMapJob_ProgressChanged; // Await the job to generate geodatabases, export tile packages, and create the mobile map package. GenerateOfflineMapResult results = await _generateOfflineMapJob.GetResultAsync(); // Check for job failure (writing the output was denied, e.g.). if (_generateOfflineMapJob.Status != JobStatus.Succeeded) { // Report failure to the user. UIAlertController messageAlert = UIAlertController.Create("Error", "Failed to take the map offline.", UIAlertControllerStyle.Alert); messageAlert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, null)); PresentViewController(messageAlert, true, null); } // Check for errors with individual layers. if (results.LayerErrors.Any()) { // Build a string to show all layer errors. System.Text.StringBuilder errorBuilder = new System.Text.StringBuilder(); foreach (KeyValuePair <Layer, Exception> layerError in results.LayerErrors) { errorBuilder.AppendLine($"{layerError.Key.Id} : {layerError.Value.Message}"); } // Show layer errors. UIAlertController messageAlert = UIAlertController.Create("Error", errorBuilder.ToString(), UIAlertControllerStyle.Alert); messageAlert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, null)); PresentViewController(messageAlert, true, null); } // Display the offline map. _myMapView.Map = results.OfflineMap; // Apply the original viewpoint for the offline map. _myMapView.SetViewpoint(new Viewpoint(_areaOfInterest)); // Enable map interaction so the user can explore the offline data. _myMapView.InteractionOptions.IsEnabled = true; // Change the title and disable the "Take map offline" button. _statusLabel.Text = "Map is offline"; _takeMapOfflineButton.Enabled = false; }; } catch (TaskCanceledException) { // Generate offline map task was canceled. UIAlertController messageAlert = UIAlertController.Create("Canceled", "Taking map offline was canceled", UIAlertControllerStyle.Alert); messageAlert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, null)); PresentViewController(messageAlert, true, null); } catch (Exception ex) { // Exception while taking the map offline. UIAlertController messageAlert = UIAlertController.Create("Error", ex.Message, UIAlertControllerStyle.Alert); messageAlert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, null)); PresentViewController(messageAlert, true, null); } finally { // Hide the loading overlay when the job is done. _loadingIndicator.StopAnimating(); } }
private async void TakeMapOfflineButton_Click(object sender, RoutedEventArgs e) { // Create a new folder for the output mobile map. string packagePath = Path.Combine(Environment.ExpandEnvironmentVariables("%TEMP%"), @"NapervilleWaterNetwork"); int num = 1; while (Directory.Exists(packagePath)) { packagePath = Path.Combine(Environment.ExpandEnvironmentVariables("%TEMP%"), @"NapervilleWaterNetwork" + num.ToString()); num++; } // Create the output directory. Directory.CreateDirectory(packagePath); try { // Show the progress indicator while the job is running. BusyIndicator.Visibility = Visibility.Visible; // Create an offline map task with the current (online) map. OfflineMapTask takeMapOfflineTask = await OfflineMapTask.CreateAsync(MyMapView.Map); // Create the default parameters for the task, pass in the area of interest. GenerateOfflineMapParameters parameters = await takeMapOfflineTask.CreateDefaultGenerateOfflineMapParametersAsync(_areaOfInterest); #region overrides // Generate parameter overrides for more in-depth control of the job. GenerateOfflineMapParameterOverrides overrides = await takeMapOfflineTask.CreateGenerateOfflineMapParameterOverridesAsync(parameters); // Configure the overrides using helper methods. ConfigureTileLayerOverrides(overrides); ConfigureLayerExclusion(overrides); CropWaterPipes(overrides); ApplyFeatureFilter(overrides); // Create the job with the parameters and output location. _generateOfflineMapJob = takeMapOfflineTask.GenerateOfflineMap(parameters, packagePath, overrides); #endregion overrides // Handle the progress changed event for the job. _generateOfflineMapJob.ProgressChanged += OfflineMapJob_ProgressChanged; // Await the job to generate geodatabases, export tile packages, and create the mobile map package. GenerateOfflineMapResult results = await _generateOfflineMapJob.GetResultAsync(); // Check for job failure (writing the output was denied, e.g.). if (_generateOfflineMapJob.Status != JobStatus.Succeeded) { MessageBox.Show("Generate offline map package failed.", "Job status"); BusyIndicator.Visibility = Visibility.Collapsed; } // Check for errors with individual layers. if (results.LayerErrors.Any()) { // Build a string to show all layer errors. System.Text.StringBuilder errorBuilder = new System.Text.StringBuilder(); foreach (KeyValuePair <Layer, Exception> layerError in results.LayerErrors) { errorBuilder.AppendLine(string.Format("{0} : {1}", layerError.Key.Id, layerError.Value.Message)); } // Show layer errors. string errorText = errorBuilder.ToString(); MessageBox.Show(errorText, "Layer errors"); } // Display the offline map. MyMapView.Map = results.OfflineMap; // Apply the original viewpoint for the offline map. MyMapView.SetViewpoint(new Viewpoint(_areaOfInterest)); // Enable map interaction so the user can explore the offline data. MyMapView.InteractionOptions.IsEnabled = true; // Hide the "Take map offline" button. takeOfflineArea.Visibility = Visibility.Collapsed; // Show a message that the map is offline. MessageArea.Visibility = Visibility.Visible; } catch (TaskCanceledException) { // Generate offline map task was canceled. MessageBox.Show("Taking map offline was canceled"); } catch (Exception ex) { // Exception while taking the map offline. MessageBox.Show(ex.Message, "Offline map error"); } finally { // Hide the activity indicator when the job is done. BusyIndicator.Visibility = Visibility.Collapsed; } }
private async void TakeMapOfflineButton_Click(object sender, EventArgs e) { // Clean up any previous outputs in the temp directory. string tempPath = $"{Path.GetTempPath()}"; string[] outputFolders = Directory.GetDirectories(tempPath, "NapervilleWaterNetwork*"); // Loop through the folder names and delete them. foreach (string dir in outputFolders) { try { // Delete the folder. Directory.Delete(dir, true); } catch (Exception) { // Ignore exceptions (files might be locked, for example). } } // Create a new folder for the output mobile map. string packagePath = Path.Combine(tempPath, @"NapervilleWaterNetwork"); int num = 1; while (Directory.Exists(packagePath)) { packagePath = Path.Combine(tempPath, @"NapervilleWaterNetwork" + num.ToString()); num++; } // Create the output directory. Directory.CreateDirectory(packagePath); try { // Show the progress indicator while the job is running. busyIndicator.IsVisible = true; // Create an offline map task with the current (online) map. OfflineMapTask takeMapOfflineTask = await OfflineMapTask.CreateAsync(MyMapView.Map); // Create the default parameters for the task, pass in the area of interest. GenerateOfflineMapParameters parameters = await takeMapOfflineTask.CreateDefaultGenerateOfflineMapParametersAsync(_areaOfInterest); // Create the job with the parameters and output location. _generateOfflineMapJob = takeMapOfflineTask.GenerateOfflineMap(parameters, packagePath); // Handle the progress changed event for the job. _generateOfflineMapJob.ProgressChanged += OfflineMapJob_ProgressChanged; // Await the job to generate geodatabases, export tile packages, and create the mobile map package. GenerateOfflineMapResult results = await _generateOfflineMapJob.GetResultAsync(); // Check for job failure (writing the output was denied, e.g.). if (_generateOfflineMapJob.Status != JobStatus.Succeeded) { await((Page)Parent).DisplayAlert("Alert", "Generate offline map package failed.", "OK"); busyIndicator.IsVisible = false; } // Check for errors with individual layers. if (results.LayerErrors.Any()) { // Build a string to show all layer errors. System.Text.StringBuilder errorBuilder = new System.Text.StringBuilder(); foreach (KeyValuePair <Layer, Exception> layerError in results.LayerErrors) { errorBuilder.AppendLine(string.Format("{0} : {1}", layerError.Key.Id, layerError.Value.Message)); } // Show layer errors. string errorText = errorBuilder.ToString(); await((Page)Parent).DisplayAlert("Alert", errorText, "OK"); } // Display the offline map. MyMapView.Map = results.OfflineMap; // Apply the original viewpoint for the offline map. MyMapView.SetViewpoint(new Viewpoint(_areaOfInterest)); // Enable map interaction so the user can explore the offline data. MyMapView.InteractionOptions.IsEnabled = true; // Hide the "Take map offline" button. takeOfflineArea.IsVisible = false; // Show a message that the map is offline. messageArea.IsVisible = true; } catch (TaskCanceledException) { // Generate offline map task was canceled. await((Page)Parent).DisplayAlert("Alert", "Taking map offline was canceled", "OK"); } catch (Exception ex) { // Exception while taking the map offline. await((Page)Parent).DisplayAlert("Alert", ex.Message, "OK"); } finally { // Hide the activity indicator when the job is done. busyIndicator.IsVisible = false; } }
private async void TakeMapOfflineButton_Click(object sender, EventArgs e) { // Make sure the user is logged in. /* * bool loggedIn = await EnsureLoggedInAsync(); * if (!loggedIn) * { * return; * } */ // Disable the button to prevent errors. _takeMapOfflineButton.Enabled = false; // Show the loading indicator. _loadingIndicator.StartAnimating(); // Create a path for the output mobile map. string tempPath = $"{Path.GetTempPath()}"; string[] outputFolders = Directory.GetDirectories(tempPath, "NapervilleWaterNetwork*"); // Loop through the folder names and delete them. foreach (string dir in outputFolders) { try { // Delete the folder. Directory.Delete(dir, true); } catch (Exception ex) { // Ignore exceptions (files might be locked, for example). Debug.WriteLine(ex); } } // Create a new folder for the output mobile map. _packagePath = Path.Combine(tempPath, @"NapervilleWaterNetwork"); int num = 1; while (Directory.Exists(_packagePath)) { _packagePath = Path.Combine(tempPath, @"NapervilleWaterNetwork" + num); num++; } // Create the output directory. Directory.CreateDirectory(_packagePath); try { // Show the loading overlay while the job is running. _statusLabel.Text = "Taking map offline..."; // Create an offline map task with the current (online) map. _takeMapOfflineTask = await OfflineMapTask.CreateAsync(_myMapView.Map); // Create the default parameters for the task, pass in the area of interest. _parameters = await _takeMapOfflineTask.CreateDefaultGenerateOfflineMapParametersAsync(_areaOfInterest); // Generate parameter overrides for more in-depth control of the job. _overrides = await _takeMapOfflineTask.CreateGenerateOfflineMapParameterOverridesAsync(_parameters); // Show the configuration window. ShowConfigurationWindow(_overrides); // Finish work once the user has configured the override. _overridesVC.FinishedConfiguring += ConfigurationContinuation; } catch (TaskCanceledException) { // Generate offline map task was canceled. UIAlertController messageAlert = UIAlertController.Create("Canceled", "Taking map offline was canceled", UIAlertControllerStyle.Alert); messageAlert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, null)); PresentViewController(messageAlert, true, null); } catch (Exception ex) { // Exception while taking the map offline. UIAlertController messageAlert = UIAlertController.Create("Error", ex.Message, UIAlertControllerStyle.Alert); messageAlert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, null)); PresentViewController(messageAlert, true, null); } finally { // Hide the loading overlay when the job is done. _loadingIndicator.StopAnimating(); } }
private async void GenerateOnDemand() { ArcGISPortal portal = await ArcGISPortal.CreateAsync(); // Get a web map item using its ID. PortalItem webmapItem = await PortalItem.CreateAsync(portal, "dba73588a56d476484b8d0fa1c480c9b"); // Create a map from the web map item. Map onlineMap = new Map(webmapItem); // Create an OfflineMapTask from the map ... OfflineMapTask takeMapOfflineTask = await OfflineMapTask.CreateAsync(onlineMap); // ... or a web map portal item. takeMapOfflineTask = await OfflineMapTask.CreateAsync(webmapItem); await onlineMap.LoadAsync(); // Create default parameters for the task. Envelope areaOfInterest = GetAreaOfInterest(); GenerateOfflineMapParameters parameters = await takeMapOfflineTask.CreateDefaultGenerateOfflineMapParametersAsync(areaOfInterest); // Limit the maximum scale to 5000 but take all the scales above (use default of 0 as the MinScale). parameters.MaxScale = 5000; // Set attachment options. parameters.AttachmentSyncDirection = AttachmentSyncDirection.Upload; parameters.ReturnLayerAttachmentOption = ReturnLayerAttachmentOption.EditableLayers; // Request the table schema only (existing features won’t be included). parameters.ReturnSchemaOnlyForEditableLayers = true; // Update the map title to contain the region. parameters.ItemInfo.Title = parameters.ItemInfo.Title + " (Central)"; // Override the thumbnail with a new image based on the extent. RuntimeImage thumbnail = await MyMapView.ExportImageAsync(); parameters.ItemInfo.Thumbnail = thumbnail; // Create the job to generate an offline map, pass in the parameters and a path to store the map package. GenerateOfflineMapJob generateMapJob = takeMapOfflineTask.GenerateOfflineMap(parameters, pathToOutputPackage); // Generate the offline map and download it. GenerateOfflineMapResult offlineMapResult = await generateMapJob.GetResultAsync(); if (!offlineMapResult.HasErrors) { // Job completed successfully and all content was generated. Debug.WriteLine("Map " + offlineMapResult.MobileMapPackage.Item.Title + " was saved to " + offlineMapResult.MobileMapPackage.Path); // Show the offline map in a MapView. MyMapView.Map = offlineMapResult.OfflineMap; } else { // Job is finished but one or more layers or tables had errors. if (offlineMapResult.LayerErrors.Count > 0) { // Show layer errors. foreach (var layerError in offlineMapResult.LayerErrors) { Debug.WriteLine("Error occurred when taking " + layerError.Key.Name + " offline. Error : " + layerError.Value.Message); } } if (offlineMapResult.TableErrors.Count > 0) { // Show table errors. foreach (var tableError in offlineMapResult.TableErrors) { Debug.WriteLine("Error occurred when taking " + tableError.Key.TableName + " offline. Error : " + tableError.Value.Message); } } } OfflineMapCapabilities results = await takeMapOfflineTask.GetOfflineMapCapabilitiesAsync(parameters); if (results.HasErrors) { // Handle possible errors with layers foreach (var layerCapability in results.LayerCapabilities) { if (!layerCapability.Value.SupportsOffline) { Debug.WriteLine(layerCapability.Key.Name + " cannot be taken offline. Error : " + layerCapability.Value.Error.Message); } } // Handle possible errors with tables foreach (var tableCapability in results.TableCapabilities) { if (!tableCapability.Value.SupportsOffline) { Debug.WriteLine(tableCapability.Key.TableName + " cannot be taken offline. Error : " + tableCapability.Value.Error.Message); } } } else { // All layers and tables can be taken offline! MessageBox.Show("All layers are good to go!"); } // Create a mobile map package from an unpacked map package folder. MobileMapPackage offlineMapPackage = await MobileMapPackage.OpenAsync(pathToOutputPackage); // Set the title from the package metadata to the UI // Get the map from the package and set it to the MapView var map = offlineMapPackage.Maps.First(); MyMapView.Map = map; }
private async void TakeMapOfflineButton_Click(object sender, EventArgs e) { // Create a path for the output mobile map. string tempPath = $"{Path.GetTempPath()}"; string[] outputFolders = Directory.GetDirectories(tempPath, "NapervilleWaterNetwork*"); // Loop through the folder names and delete them. foreach (string dir in outputFolders) { try { // Delete the folder. Directory.Delete(dir, true); } catch (Exception) { // Ignore exceptions (files might be locked, for example). } } // Create a new folder for the output mobile map. string packagePath = Path.Combine(tempPath, @"NapervilleWaterNetwork"); int num = 1; while (Directory.Exists(packagePath)) { packagePath = Path.Combine(tempPath, @"NapervilleWaterNetwork" + num.ToString()); num++; } // Create the output directory. Directory.CreateDirectory(packagePath); try { // Show the loading overlay while the job is running. CGRect bounds = View.Bounds; _loadingOverlay = new LoadingMapOverlay(bounds, true); _loadingOverlay.UpdateLabel("Taking map offine ..."); _loadingOverlay.OnCanceled += (s, evt) => { // The user canceled the job. _generateOfflineMapJob.Cancel(); }; this.ParentViewController.View.Add(_loadingOverlay); // Create an offline map task with the current (online) map. OfflineMapTask takeMapOfflineTask = await OfflineMapTask.CreateAsync(_myMapView.Map); // Create the default parameters for the task, pass in the area of interest. GenerateOfflineMapParameters parameters = await takeMapOfflineTask.CreateDefaultGenerateOfflineMapParametersAsync(_areaOfInterest); // Create the job with the parameters and output location. _generateOfflineMapJob = takeMapOfflineTask.GenerateOfflineMap(parameters, packagePath); // Handle the progress changed event for the job. _generateOfflineMapJob.ProgressChanged += OfflineMapJob_ProgressChanged; // Await the job to generate geodatabases, export tile packages, and create the mobile map package. GenerateOfflineMapResult results = await _generateOfflineMapJob.GetResultAsync(); // Check for job failure (writing the output was denied, e.g.). if (_generateOfflineMapJob.Status != JobStatus.Succeeded) { // Report failure to the user. UIAlertController messageAlert = UIAlertController.Create("Error", "Failed to take the map offline.", UIAlertControllerStyle.Alert); messageAlert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, null)); PresentViewController(messageAlert, true, null); } // Check for errors with individual layers. if (results.LayerErrors.Any()) { // Build a string to show all layer errors. System.Text.StringBuilder errorBuilder = new System.Text.StringBuilder(); foreach (KeyValuePair <Layer, Exception> layerError in results.LayerErrors) { errorBuilder.AppendLine(string.Format("{0} : {1}", layerError.Key.Id, layerError.Value.Message)); } // Show layer errors. UIAlertController messageAlert = UIAlertController.Create("Error", errorBuilder.ToString(), UIAlertControllerStyle.Alert); messageAlert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, null)); PresentViewController(messageAlert, true, null); } // Display the offline map. _myMapView.Map = results.OfflineMap; // Apply the original viewpoint for the offline map. _myMapView.SetViewpoint(new Viewpoint(_areaOfInterest)); // Enable map interaction so the user can explore the offline data. _myMapView.InteractionOptions.IsEnabled = true; // Change the title and disable the "Take map offline" button. _takeMapOfflineButton.SetTitle("Map is offline", UIControlState.Normal); _takeMapOfflineButton.Enabled = false; } catch (TaskCanceledException) { // Generate offline map task was canceled. UIAlertController messageAlert = UIAlertController.Create("Canceled", "Taking map offline was canceled", UIAlertControllerStyle.Alert); messageAlert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, null)); PresentViewController(messageAlert, true, null); } catch (Exception ex) { // Exception while taking the map offline. UIAlertController messageAlert = UIAlertController.Create("Error", ex.Message, UIAlertControllerStyle.Alert); messageAlert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, null)); PresentViewController(messageAlert, true, null); } finally { // Hide the loading overlay when the job is done. if (_loadingOverlay != null) { _loadingOverlay.Hide(); } } }