This sample demonstrates how to search for, return, and use basemaps from ArcGIS Online. The sample creates a Map control from a web map, then calls ArcGISPortalInfo.SearchBasemapGalleryAsync to return the first 20 basemaps in a gallery hosted by ArcGIS Online and binds the result to a ListBox. Note, ArcGIS Online and other portals can define a gallery of basemaps Each basemap is simply a web map with basemap layers. When creating a Map from a web map, the Document class provides an attached property IsBaseMapProperty to tag layers within a Map as basemap layers. Use the Document.GetIsBaseMap() method to check this attached property you can determine which layers are basemap layers. Click on the basemaps in the ListBox to replace the basemap layers in the current Map control with layers from the basemap clicked. To do this, first get the ArcGISPortalItem bound to the button clicked, then get the web map associated with it. Next return all the basemap layers from the chosen web map and add them to the existing Map. One nuance in this process is that when adding new layers, some layers in the basemap are "Reference Layers" which go on top of all other layers in the Map (e.g. label layers). Note, this sample includes an operational layer that contains United States federal land holdings. Switching basemaps enables a user to quickly visualize relationships between federal ownership, human infrastructure, and natural features.
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using ESRI.ArcGIS.Client.Portal;
using ESRI.ArcGIS.Client.WebMap;
namespace ArcGISWPFSDK
{
publicpartialclass BasemapSwitcher : UserControl
{
ESRI.ArcGIS.Client.Map _map;
public BasemapSwitcher()
{
InitializeComponent();
LoadWebMap();
LoadPortalBasemaps();
}
privatevoid LoadWebMap()
{
// Downloads a web map from ArcGIS Online that contains a basemap and operational layer (federal land holdings)
Document doc = new Document();
doc.GetMapCompleted += (s, e) =>
{
_map = e.Map;
Grid.SetColumn(_map, 1);
LayoutRoot.Children.Insert(0, _map);
};
doc.GetMapAsync("3679c136c2694d0b95bb5e6c3f2b480e");
}
privatevoid LoadPortalBasemaps()
{
// Initialize a portal to get the query to return web maps in the basemap gallery
ArcGISPortal portal = new ArcGISPortal();
portal.InitializeAsync("http://www.arcgis.com/sharing/rest", (s, e) =>
{
if (portal.ArcGISPortalInfo != null)
{
// Return the first 20 basemaps in the gallery
SearchParameters parameters = new SearchParameters() { Limit = 20 };
// Use the advertised query to search the basemap gallery and return web maps as portal items
portal.ArcGISPortalInfo.SearchBasemapGalleryAsync(parameters, (result, error) =>
{
if (error == null && result != null)
{
basemapList.ItemsSource = result.Results;
}
});
}
});
}
privatevoid BaseMapButton_Click(object sender, RoutedEventArgs e)
{
var item = (sender as Button).DataContext as ArcGISPortalItem;
ESRI.ArcGIS.Client.WebMap.WebMap.FromPortalItemAsync(item, (webmap, err) =>
{
var basemaps = webmap.BaseMap;
//Create a map instance from the webmap
Document doc = new Document()
{
BingToken = ""//Required if you want to load bing basemaps
};
doc.GetMapCompleted += (s, result) =>
{
// Remove basemap layers in current map controlforeach (var layer in _map.Layers.ToList())
if (Document.GetIsBaseMap(layer))
_map.Layers.Remove(layer);
// Get the basemap layers from the result map control from the call to GetMapAsyncvar newBaseLayers = result.Map.Layers.Where(layer => Document.GetIsBaseMap(layer)).ToList();
// To add the basemap layer retrieved in the previous line to the current map control, remove them from // the result map control
result.Map.Layers.Clear();
// Use an index to determine where to insert basemap reference layersint idx = 0;
foreach (var layer in newBaseLayers)
{
// If basemap contains a Bing tile layer and no Bing key is available, skip adding the basemap layer.if (layer is ESRI.ArcGIS.Client.Bing.TileLayer && string.IsNullOrEmpty(doc.BingToken))
{
MessageBox.Show("Bing key not available. Bing layer cannot be used as a basemap.");
break;
}
// Returns json definition for the layervar data = layer.GetValue(Document.WebMapDataProperty) as IDictionary<string, object>;
// Reference layers go on top of other layers (e.g. labels)if (data.ContainsKey("isReference"))
_map.Layers.Add(layer);
else
{
// Basemap layers go below all other layers
_map.Layers.Insert(idx++, layer);
}
}
};
doc.GetMapAsync(webmap);
});
}
}
}
Imports System.Collections.Generic
Imports System.Linq
Imports System.Windows
Imports System.Windows.Controls
Imports ESRI.ArcGIS.Client.Portal
Imports ESRI.ArcGIS.Client.WebMap
Imports ESRI.ArcGIS.Client
Namespace ArcGISWPFSDK
PartialPublicClass BasemapSwitcher
Inherits UserControl
Private _map As ESRI.ArcGIS.Client.Map
PublicSubNew()
InitializeComponent()
LoadWebMap()
LoadPortalBasemaps()
EndSubPrivateSub LoadWebMap()
' Downloads a web map from ArcGIS Online that contains a basemap and operational layer (federal land holdings)Dim doc AsNew Document()
AddHandler doc.GetMapCompleted,
Sub(s, e)
_map = e.Map
Grid.SetColumn(_map, 1)
LayoutRoot.Children.Insert(0, _map)
EndSub
doc.GetMapAsync("3679c136c2694d0b95bb5e6c3f2b480e")
EndSubPrivateSub LoadPortalBasemaps()
' Initialize a portal to get the query to return web maps in the basemap galleryDim portal AsNew ArcGISPortal()
portal.InitializeAsync("http://www.arcgis.com/sharing/rest",
Sub(s, e)
If portal.ArcGISPortalInfo IsNotNothingThen' Return the first 20 basemaps in the galleryDim parameters AsNew SearchParameters() With {.Limit = 20}
' Use the advertised query to search the basemap gallery and return web maps as portal items
portal.ArcGISPortalInfo.SearchBasemapGalleryAsync(parameters,
Sub(result, err)
If err IsNothingAndAlso result IsNotNothingThen
basemapList.ItemsSource = result.Results
EndIfEndSub)
EndIfEndSub)
EndSubPrivateSub BaseMapButton_Click(ByVal sender AsObject, ByVal e As RoutedEventArgs)
Dim item = TryCast((TryCast(sender, Button)).DataContext, ArcGISPortalItem)
'Create a map instance from the webmap' Remove basemap layers in current map control' Get the basemap layers from the result map control from the call to GetMapAsync' To add the basemap layer retrieved in the previous line to the current map control, remove them from ' the result map control' Use an index to determine where to insert basemap reference layers' If basemap contains a Bing tile layer and no Bing key is available, skip adding the basemap layer.' Returns json definition for the layer' Reference layers go on top of other layers (e.g. labels)' Basemap layers go below all other layers
WebMap.FromPortalItemAsync( _
item,
Sub(webmap, err)
Dim basemaps = webmap.BaseMap
'Create a map instance from the webmapDim doc AsNew Document() With
{.BingToken = ""} 'Required if you want to load bing basemapsAddHandler doc.GetMapCompleted,
Sub(s, result)
'Remove basemap layers in current map controlForEach layer As Layer In _map.Layers.ToList()
If Document.GetIsBaseMap(layer) Then
_map.Layers.Remove(layer)
EndIfNext layer
'Get the basemap layers from the result map control from the call to GetMapAsyncDim newBaseLayers = result.Map.Layers.Where(Function(layer) Document.GetIsBaseMap(layer)).ToList()
'To add the basemap layer retrieved in the previous line to the current map control, remove them from'the result map control
result.Map.Layers.Clear()
'Use an index to determine where to insert basemap reference layersDim idx AsInteger = 0
ForEach layer As Layer In newBaseLayers
'If basemap contains a Bing tile layer and no Bing key is available, skip adding the basemap layer.IfTypeOf layer Is ESRI.ArcGIS.Client.Bing.TileLayer AndAlsoString.IsNullOrEmpty(doc.BingToken) Then
MessageBox.Show("Bing key not available. Bing layer cannot be used as a basemap.")
ExitForEndIf'Returns json definition for the layerDim data = TryCast(layer.GetValue(Document.WebMapDataProperty), IDictionary(Of String, Object))
'Reference layers go on top of other layers (e.g. labels)If data.ContainsKey("isReference") Then
_map.Layers.Add(layer)
Else'Basemap layers go below all other layers
_map.Layers.Insert(idx, layer)
idx += 1
EndIfNext layer
EndSub
doc.GetMapAsync(webmap)
EndSub)
EndSubEndClassEndNamespace