Skip to content

Commit bfece10

Browse files
authored
fix OfflineBasemapByReference: replace deprecated web map and add local basemap selection dialog (#1724)
1 parent 1909c8f commit bfece10

File tree

9 files changed

+549
-218
lines changed

9 files changed

+549
-218
lines changed

src/MAUI/Maui.Samples/Samples/Map/OfflineBasemapByReference/OfflineBasemapByReference.xaml

Lines changed: 104 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,131 @@
1-
<ContentPage x:Class="ArcGIS.Samples.OfflineBasemapByReference.OfflineBasemapByReference"
2-
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
3-
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
4-
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui">
1+
<ContentPage
2+
x:Class="ArcGIS.Samples.OfflineBasemapByReference.OfflineBasemapByReference"
3+
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
4+
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
5+
xmlns:esriUI="clr-namespace:Esri.ArcGISRuntime.Maui;assembly=Esri.ArcGISRuntime.Maui">
56
<Grid Style="{DynamicResource EsriSampleContainer}">
67
<esriUI:MapView x:Name="MyMapView" Style="{DynamicResource EsriSampleGeoView}" />
8+
79
<Border Style="{DynamicResource EsriSampleControlPanel}">
8-
<Button x:Name="TakeMapOfflineButton"
9-
Clicked="TakeMapOfflineButton_Click"
10-
Text="Take map offline"
11-
VerticalOptions="Start" />
10+
<Button
11+
x:Name="TakeMapOfflineButton"
12+
Clicked="TakeMapOfflineButton_Click"
13+
Text="Take map offline">
14+
<Button.Triggers>
15+
<DataTrigger
16+
x:DataType="Grid"
17+
Binding="{Binding Source={x:Reference LoadingIndicator}, Path=IsVisible}"
18+
TargetType="Button"
19+
Value="True">
20+
<Setter Property="IsEnabled" Value="False" />
21+
</DataTrigger>
22+
<DataTrigger
23+
x:DataType="Grid"
24+
Binding="{Binding Source={x:Reference BusyIndicator}, Path=IsVisible}"
25+
TargetType="Button"
26+
Value="True">
27+
<Setter Property="IsEnabled" Value="False" />
28+
</DataTrigger>
29+
<DataTrigger
30+
x:DataType="Grid"
31+
Binding="{Binding Source={x:Reference BasemapChoicePanel}, Path=IsVisible}"
32+
TargetType="Button"
33+
Value="True">
34+
<Setter Property="IsEnabled" Value="False" />
35+
</DataTrigger>
36+
</Button.Triggers>
37+
</Button>
1238
</Border>
13-
<Grid x:Name="BusyIndicator"
14-
Grid.RowSpan="2"
15-
Grid.ColumnSpan="2"
16-
BackgroundColor="#807f7f7f"
17-
IsVisible="False">
39+
40+
<!-- Basemap Choice Dialog -->
41+
<Grid
42+
x:Name="BasemapChoicePanel"
43+
Grid.RowSpan="2"
44+
Grid.ColumnSpan="2"
45+
BackgroundColor="#80000000"
46+
IsVisible="False">
47+
<Border
48+
Padding="20"
49+
BackgroundColor="White"
50+
HorizontalOptions="Center"
51+
VerticalOptions="Center">
52+
<VerticalStackLayout Spacing="15" WidthRequest="280">
53+
<Label
54+
x:Name="BasemapChoiceMessage"
55+
FontSize="14"
56+
HorizontalTextAlignment="Center" />
57+
<Button Clicked="UseLocalBasemapButton_Click" Text="Use Local Basemap" />
58+
<Button Clicked="DownloadBasemapButton_Click" Text="Download Basemap" />
59+
<Button Clicked="CancelBasemapChoiceButton_Click" Text="Cancel" />
60+
</VerticalStackLayout>
61+
</Border>
62+
</Grid>
63+
64+
<Grid
65+
x:Name="BusyIndicator"
66+
Grid.RowSpan="2"
67+
Grid.ColumnSpan="2"
68+
BackgroundColor="#807f7f7f"
69+
IsVisible="False">
1870
<Grid HorizontalOptions="Center" VerticalOptions="Center">
1971
<Grid.RowDefinitions>
2072
<RowDefinition Height="auto" />
2173
<RowDefinition Height="auto" />
2274
<RowDefinition Height="auto" />
2375
</Grid.RowDefinitions>
24-
<Label Margin="10"
25-
FontSize="18"
26-
HorizontalOptions="Center"
27-
TextColor="White"
28-
VerticalOptions="Center">
76+
<Label
77+
Margin="10"
78+
FontSize="18"
79+
HorizontalOptions="Center"
80+
TextColor="White"
81+
VerticalOptions="Center">
2982
<Label.FormattedText>
3083
<FormattedString>
3184
<Span Text="Generating offline map... " />
3285
<Span x:Name="Percentage" Text="" />
3386
</FormattedString>
3487
</Label.FormattedText>
3588
</Label>
36-
<ProgressBar x:Name="MapProgressBar"
37-
Grid.Row="1"
38-
Margin="0,0,0,10"
39-
HeightRequest="10"
40-
HorizontalOptions="Center"
41-
IsEnabled="True"
42-
VerticalOptions="Center"
43-
WidthRequest="100" />
44-
<Button Grid.Row="2"
45-
Clicked="CancelJobButton_Click"
46-
HorizontalOptions="Center"
47-
Text="Cancel"
48-
WidthRequest="100" />
89+
<ProgressBar
90+
x:Name="MapProgressBar"
91+
Grid.Row="1"
92+
Margin="0,0,0,10"
93+
HeightRequest="10"
94+
HorizontalOptions="Center"
95+
IsEnabled="True"
96+
VerticalOptions="Center"
97+
WidthRequest="100" />
98+
<Button
99+
Grid.Row="2"
100+
Clicked="CancelJobButton_Click"
101+
HorizontalOptions="Center"
102+
Text="Cancel"
103+
WidthRequest="100" />
49104
</Grid>
50105
</Grid>
51-
<Grid x:Name="LoadingIndicator"
52-
Grid.RowSpan="2"
53-
Grid.ColumnSpan="2"
54-
BackgroundColor="#807f7f7f"
55-
IsVisible="True">
106+
<Grid
107+
x:Name="LoadingIndicator"
108+
Grid.RowSpan="2"
109+
Grid.ColumnSpan="2"
110+
BackgroundColor="#807f7f7f"
111+
IsVisible="True">
56112
<Grid HorizontalOptions="Center" VerticalOptions="Center">
57113
<Grid.RowDefinitions>
58114
<RowDefinition Height="auto" />
59115
<RowDefinition Height="auto" />
60116
</Grid.RowDefinitions>
61-
<Label Margin="10"
62-
FontSize="18"
63-
Text="Loading online map..."
64-
TextColor="White" />
65-
<ProgressBar Grid.Row="1"
66-
HeightRequest="10"
67-
HorizontalOptions="Center"
68-
IsEnabled="True"
69-
VerticalOptions="Center"
70-
WidthRequest="100" />
117+
<Label
118+
Margin="10"
119+
FontSize="18"
120+
Text="Loading online map..."
121+
TextColor="White" />
122+
<ProgressBar
123+
Grid.Row="1"
124+
HeightRequest="10"
125+
HorizontalOptions="Center"
126+
IsEnabled="True"
127+
VerticalOptions="Center"
128+
WidthRequest="100" />
71129
</Grid>
72130
</Grid>
73131
</Grid>

src/MAUI/Maui.Samples/Samples/Map/OfflineBasemapByReference/OfflineBasemapByReference.xaml.cs

Lines changed: 79 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -30,55 +30,103 @@ namespace ArcGIS.Samples.OfflineBasemapByReference
3030
description: "Use the `OfflineMapTask` to take a web map offline, but instead of downloading an online basemap, use one which is already on the device.",
3131
instructions: "1. Use the button to start taking the map offline.",
3232
tags: new[] { "basemap", "download", "local", "offline", "save", "web map" })]
33-
[ArcGIS.Samples.Shared.Attributes.OfflineData("628e8e3521cf45e9a28a12fe10c02c4d")]
33+
[ArcGIS.Samples.Shared.Attributes.OfflineData("85282f2aaa2844d8935cdb8722e22a93")]
3434
public partial class OfflineBasemapByReference : ContentPage
3535
{
36-
// The job to generate an offline map.
37-
private GenerateOfflineMapJob _generateOfflineMapJob;
36+
// The ID for a web map item hosted on ArcGIS Online (water network map of Naperville IL).
37+
private const string WebMapId = "acc027394bc84c2fb04d1ed317aac674";
38+
39+
// The ID for the offline basemap tile package hosted on ArcGIS Online.
40+
private const string BasemapDataId = "85282f2aaa2844d8935cdb8722e22a93";
41+
42+
// The filename of the local basemap tile package.
43+
private const string BasemapFilename = "naperville_imagery.tpkx";
3844

3945
// The extent of the data to take offline.
4046
private readonly Envelope _areaOfInterest = new Envelope(-88.1541, 41.7690, -88.1471, 41.7720, SpatialReferences.Wgs84);
4147

42-
// The ID for a web map item hosted on the server (water network map of Naperville IL).
43-
private const string WebMapId = "acc027394bc84c2fb04d1ed317aac674";
48+
// The job to generate an offline map.
49+
private GenerateOfflineMapJob _generateOfflineMapJob;
50+
51+
// Task completion source for basemap choice dialog.
52+
private TaskCompletionSource<string> _basemapChoiceCompletion;
4453

4554
public OfflineBasemapByReference()
4655
{
4756
InitializeComponent();
4857
_ = Initialize();
4958
}
5059

51-
private async Task ConfigureOfflineJobForBasemap(GenerateOfflineMapParameters parameters)
60+
private async Task<bool> ConfigureOfflineJobForBasemap(GenerateOfflineMapParameters parameters)
5261
{
53-
// Don't give the user a choice if there is no basemap specified.
54-
if (String.IsNullOrWhiteSpace(parameters.ReferenceBasemapFilename))
62+
// Get the path to the basemap directory.
63+
string basemapBasePath = DataManager.GetDataFolder(BasemapDataId);
64+
65+
// Set the reference basemap filename if not already configured.
66+
if (string.IsNullOrWhiteSpace(parameters.ReferenceBasemapFilename))
5567
{
56-
return;
68+
parameters.ReferenceBasemapFilename = BasemapFilename;
5769
}
5870

59-
// Get the path to the basemap directory.
60-
string basemapBasePath = DataManager.GetDataFolder("85282f2aaa2844d8935cdb8722e22a93");
61-
62-
// Get the full path to the basemap by combining the name specified in the web map (ReferenceBasemapFilename)
63-
// with the offline basemap directory.
71+
// Get the full path to the basemap.
6472
string basemapFullPath = Path.Combine(basemapBasePath, parameters.ReferenceBasemapFilename);
6573

6674
// If the offline basemap doesn't exist, proceed without it.
6775
if (!File.Exists(basemapFullPath))
6876
{
69-
return;
77+
return true;
7078
}
7179

72-
// Wait for the user to choose whether to use the offline basemap.
73-
bool useBasemap = await Application.Current.Windows[0].Page.DisplayAlert("Basemap choice", "Use the offline basemap?", "Yes", "No");
80+
// Show the dialog and wait for user choice.
81+
string choice = await ShowBasemapChoiceDialog(parameters.ReferenceBasemapFilename);
7482

75-
if (useBasemap)
83+
switch (choice)
7684
{
77-
// Configure the offline basemap if the user said yes.
78-
parameters.ReferenceBasemapDirectory = basemapBasePath;
85+
case "UseLocal":
86+
parameters.ReferenceBasemapDirectory = basemapBasePath;
87+
return true;
88+
89+
case "Download":
90+
return true;
91+
92+
default:
93+
return false;
7994
}
8095
}
8196

97+
private async Task<string> ShowBasemapChoiceDialog(string basemapFilename)
98+
{
99+
// Update the message with the basemap filename.
100+
BasemapChoiceMessage.Text = $"This web map references a local basemap '{basemapFilename}'.\n\nYou can use the basemap already on disk or download the basemap again.";
101+
102+
BasemapChoicePanel.IsVisible = true;
103+
104+
// Show the dialog and wait for user choice.
105+
_basemapChoiceCompletion = new TaskCompletionSource<string>();
106+
107+
string choice = await _basemapChoiceCompletion.Task;
108+
109+
// Hide dialog.
110+
BasemapChoicePanel.IsVisible = false;
111+
112+
return choice;
113+
}
114+
115+
private void UseLocalBasemapButton_Click(object sender, EventArgs e)
116+
{
117+
_basemapChoiceCompletion?.TrySetResult("UseLocal");
118+
}
119+
120+
private void DownloadBasemapButton_Click(object sender, EventArgs e)
121+
{
122+
_basemapChoiceCompletion?.TrySetResult("Download");
123+
}
124+
125+
private void CancelBasemapChoiceButton_Click(object sender, EventArgs e)
126+
{
127+
_basemapChoiceCompletion?.TrySetResult("Cancel");
128+
}
129+
82130
// Note: all code below (except call to ConfigureOfflineJobForBasemap) is identical to code in the Generate offline map sample.
83131

84132
#region Generate offline map
@@ -160,17 +208,23 @@ private async void TakeMapOfflineButton_Click(object sender, EventArgs e)
160208

161209
try
162210
{
163-
// Show the progress indicator while the job is running.
164-
BusyIndicator.IsVisible = true;
165-
166211
// Create an offline map task with the current (online) map.
167212
OfflineMapTask takeMapOfflineTask = await OfflineMapTask.CreateAsync(MyMapView.Map);
168213

169214
// Create the default parameters for the task, pass in the area of interest.
170215
GenerateOfflineMapParameters parameters = await takeMapOfflineTask.CreateDefaultGenerateOfflineMapParametersAsync(_areaOfInterest);
171216

172217
// Configure basemap settings for the job.
173-
await ConfigureOfflineJobForBasemap(parameters);
218+
bool proceed = await ConfigureOfflineJobForBasemap(parameters);
219+
220+
// Exit if user cancelled.
221+
if (!proceed)
222+
{
223+
return;
224+
}
225+
226+
// Show the progress indicator while the job is running.
227+
BusyIndicator.IsVisible = true;
174228

175229
// Create the job with the parameters and output location.
176230
_generateOfflineMapJob = takeMapOfflineTask.GenerateOfflineMap(parameters, packagePath);
@@ -212,7 +266,7 @@ private async void TakeMapOfflineButton_Click(object sender, EventArgs e)
212266
// Enable map interaction so the user can explore the offline data.
213267
MyMapView.InteractionOptions.IsEnabled = true;
214268

215-
// Hide the "Take map offline" button.
269+
// Disable the button since map is now offline.
216270
TakeMapOfflineButton.IsEnabled = false;
217271

218272
// Show a message that the map is offline.
0 Bytes
Loading
0 Bytes
Loading

0 commit comments

Comments
 (0)