Skip to content

Commit ae661f9

Browse files
authored
Set Basemap Sample (#76)
* Applies common sample design * using developerBasemaps() * no message * Removed unnecessary function * adopted changes * adopted the changes * Made changes to the README
1 parent 94a19f3 commit ae661f9

File tree

4 files changed

+82
-65
lines changed

4 files changed

+82
-65
lines changed

lib/samples/set_basemap/README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Set basemap
2+
3+
Change a map's basemap. A basemap is beneath all layers on a map and is used to provide visual reference for the operational layers.
4+
5+
![Image of set basemap](set_basemap.png)
6+
7+
## Use case
8+
9+
Basemaps should be selected contextually. For example, in maritime applications, it would be more appropriate to use a basemap of the world's oceans as opposed to a basemap of the world's streets.
10+
11+
## How to use the sample
12+
13+
Use the drawer to select the active basemap from the list of available basemaps.
14+
15+
## How it works
16+
17+
1. Create an `ArcGISMap` object.
18+
2. Set the map to the `ArcGISMapViewController` object.
19+
3. Choose a new basemap type and set it on the map.
20+
21+
## Relevant API
22+
23+
* ArcGISMap
24+
* ArcGISMapViewController
25+
* Basemap
26+
27+
## Tags
28+
29+
basemap, map
Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,25 @@
11
{
22
"category": "Maps",
3-
"description": "Set a map's basemap. A basemap is beneath all layers on a map and is used to provide visual reference for the operational layers.",
3+
"description": "Change a map's basemap. A basemap is beneath all layers on a map and is used to provide visual reference for the operational layers.",
44
"ignore": false,
5-
"images": [],
6-
"keywords": [],
5+
"images": [
6+
"set_basemap.png"
7+
],
8+
"keywords": [
9+
"basemap",
10+
"map",
11+
"ArcGISMap",
12+
"ArcGISMapViewController",
13+
"Basemap"
14+
],
715
"redirect_from": [],
8-
"relevant_apis": [],
9-
"snippets": [],
10-
"title": "Set Basemap"
16+
"relevant_apis": [
17+
"ArcGISMap",
18+
"ArcGISMapViewController",
19+
"Basemap"
20+
],
21+
"snippets": [
22+
"set_basemap_sample.dart"
23+
],
24+
"title": "Set basemap"
1125
}
218 KB
Loading

lib/samples/set_basemap/set_basemap_sample.dart

Lines changed: 33 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ import 'dart:async';
1818

1919
import 'package:arcgis_maps/arcgis_maps.dart';
2020
import 'package:flutter/material.dart';
21-
import 'package:path_provider/path_provider.dart';
2221

23-
import '../../utils/sample_data.dart';
2422
import '../../utils/sample_state_support.dart';
2523

2624
class SetBasemapSample extends StatefulWidget {
@@ -32,42 +30,44 @@ class SetBasemapSample extends StatefulWidget {
3230

3331
class _SetBasemapSampleState extends State<SetBasemapSample>
3432
with SampleStateSupport {
35-
final GlobalKey<ScaffoldState> _scaffoldStateKey = GlobalKey();
36-
33+
// Create a key to access the scaffold state.
34+
final _scaffoldStateKey = GlobalKey<ScaffoldState>();
35+
// Create a controller for the map view and a map with a navigation basemap.
3736
final _mapViewController = ArcGISMapView.createController();
3837
final _arcGISMap = ArcGISMap.withBasemapStyle(BasemapStyle.arcGISNavigation);
38+
// Create a dictionary to store basemaps.
3939
final _basemaps = <Basemap, Image>{};
40-
final _defaultImage = Image.asset('assets/basemap_default.png');
41-
final _sanFranciscoViewpoint = Viewpoint.fromCenter(
42-
ArcGISPoint(x: -13630206, y: 4546929),
43-
scale: 100000,
44-
);
40+
// Create a default image.
41+
final _defaultImage = Image.asset('assets/basemap_default.png');
4542
late Future _loadBasemapsFuture;
4643

4744
@override
4845
void initState() {
4946
super.initState();
50-
51-
_arcGISMap.initialViewpoint = _sanFranciscoViewpoint;
52-
_mapViewController.arcGISMap = _arcGISMap;
47+
// Load basemaps when the app starts.
5348
_loadBasemapsFuture = loadBasemaps();
5449
}
5550

5651
@override
5752
Widget build(BuildContext context) {
5853
return Scaffold(
54+
// Create a scaffold with a key to access the scaffold state.
5955
key: _scaffoldStateKey,
56+
// Create an end drawer to display basemaps.
6057
endDrawer: Drawer(
61-
child: SafeArea(
58+
child: SafeArea(
59+
// Create a future builder to load basemaps.
6260
child: FutureBuilder(
6361
future: _loadBasemapsFuture,
6462
builder: (context, snapshot) {
6563
switch (snapshot.connectionState) {
6664
case ConnectionState.done:
65+
// Create a grid view to display basemaps.
6766
return GridView.count(
6867
crossAxisCount: 2,
6968
children: _basemaps.keys
7069
.map(
70+
// Create a list tile for each basemap.
7171
(basemap) => ListTile(
7272
title: Column(
7373
children: [
@@ -78,6 +78,7 @@ class _SetBasemapSampleState extends State<SetBasemapSample>
7878
),
7979
],
8080
),
81+
// Update the map with the selected basemap.
8182
onTap: () {
8283
updateMap(basemap);
8384
_scaffoldStateKey.currentState!.closeEndDrawer();
@@ -87,6 +88,7 @@ class _SetBasemapSampleState extends State<SetBasemapSample>
8788
.toList(),
8889
);
8990
default:
91+
// Display a loading message while loading basemaps.
9092
return const Center(
9193
child: Text('Loading basemaps...'),
9294
);
@@ -95,10 +97,13 @@ class _SetBasemapSampleState extends State<SetBasemapSample>
9597
),
9698
),
9799
),
100+
// Create a stack with the map view and a floating action button to open the end drawer.
98101
body: Stack(
99102
children: [
103+
// Create an ArcGIS map view with a controller.
100104
ArcGISMapView(
101105
controllerProvider: () => _mapViewController,
106+
onMapViewReady: onMapViewReady,
102107
),
103108
Positioned(
104109
bottom: 70,
@@ -115,66 +120,35 @@ class _SetBasemapSampleState extends State<SetBasemapSample>
115120
);
116121
}
117122

123+
void onMapViewReady() {
124+
// Set the map view controller's map to the ArcGIS map.
125+
_mapViewController.arcGISMap = _arcGISMap;
126+
}
127+
118128
void updateMap(Basemap basemap) {
119-
_arcGISMap.basemap = basemap;
120-
_mapViewController.setViewpointAnimated(_sanFranciscoViewpoint);
121-
_mapViewController.setViewpointRotation(angleDegrees: 0.0);
129+
// Update the map view with the selected basemap.
130+
_arcGISMap.basemap = basemap;
122131
}
123132

124133
Future loadBasemaps() async {
125-
// load basemaps from online items
126-
List<Basemap> basemaps = List.from([
127-
Basemap.withUri(Uri.parse(
128-
'https://runtime.maps.arcgis.com/home/item.html?id=9b39104916614f0899993934d2f1d375')), // newspaper - from different org
129-
Basemap.withUri(Uri.parse(
130-
'https://www.arcgis.com/home/item.html?id=358ec1e175ea41c3bf5c68f0da11ae2b')), // dark gray canvas
131-
Basemap.withUri(Uri.parse(
132-
'https://www.arcgis.com/home/item.html?id=979c6cc89af9449cbeb5342a439c6a76')), // light gray canvas
133-
Basemap.withUri(Uri.parse(
134-
'https://www.arcgis.com/home/item.html?id=fae788aa91e54244b161b59725dcbb2a')), // OSM
135-
Basemap.withUri(Uri.parse(
136-
'https://www.arcgis.com/home/item.html?id=28f49811a6974659988fd279de5ce39f')), // Imagery
137-
Basemap.withUri(Uri.parse(
138-
'https://www.arcgis.com/home/item.html?id=2e8a3ccdfd6d42a995b79812b3b0ebc6')), // Outdoor
139-
Basemap.withUri(Uri.parse(
140-
'https://www.arcgis.com/home/item.html?id=7e2b9be8a9c94e45b7f87857d8d168d6')), // Streets night
141-
Basemap.withStyle(BasemapStyle.arcGISNavigation), // No thumbnail
142-
]);
134+
// Create a portal to access online items.
135+
final portal = Portal.arcGISOnline();
136+
// Load basemaps from portal.
137+
final basemaps = await portal.developerBasemaps();
143138

144-
// load each basemap to access and display attribute data in the UI
145-
for (var basemap in basemaps) {
139+
// Load each basemap to access and display attribute data in the UI.
140+
for (final basemap in basemaps) {
146141
await basemap.load();
147142
if (basemap.item != null) {
148-
var thumbnail = basemap.item!.thumbnail;
143+
final thumbnail = basemap.item!.thumbnail;
149144
if (thumbnail != null) {
150145
await thumbnail.load();
151146
_basemaps[basemap] = Image.network(thumbnail.uri.toString());
152147
}
153148
} else {
149+
// If the basemap does not have a thumbnail, use the default image.
154150
_basemaps[basemap] = _defaultImage;
155151
}
156152
}
157-
158-
// load basemaps from local packages
159-
await loadTileCache();
160-
}
161-
162-
Future loadTileCache() async {
163-
await downloadSampleData(['e4a398afe9a945f3b0f4dca1e4faccb5']);
164-
const tilePackageName = 'SanFrancisco.tpkx';
165-
final appDir = await getApplicationDocumentsDirectory();
166-
final tpkxPath = '${appDir.absolute.path}/$tilePackageName';
167-
168-
final tileCache = TileCache.withFileUri(Uri.parse(tpkxPath));
169-
// wait for the tile cache to load to access and display thumbnail
170-
await tileCache.load();
171-
final tiledLayer = ArcGISTiledLayer.withTileCache(tileCache);
172-
final tiledLayerBasemap = Basemap.withBaseLayer(tiledLayer);
173-
if (tileCache.thumbnail != null) {
174-
_basemaps[tiledLayerBasemap] =
175-
Image.memory(tileCache.thumbnail!.getEncodedBuffer());
176-
} else {
177-
_basemaps[tiledLayerBasemap] = _defaultImage;
178-
}
179153
}
180154
}

0 commit comments

Comments
 (0)