If you are a C# developer and do GIS or mapping work, the ArcGIS Runtime for .NET will help you quickly start building WPF applications. In this tutorial, you will build a WPF application that displays a map of public transit routes in Atlanta.
Create C# GIS Project
If you have not already done so, get started by downloading and installing the latest Visual Studio Extension (.vsix) file for the .NET ArcGIS Runtime. This extension will add templates and the required NuGet packages for using the the GIS runtime in your .NET applications.
With the extension installed, create a new project using the template ArcGIS Runtime Application (WPF). Name the project AtlantaTransit.
The project will be templated with a MainWindow.xaml file and a MapViewModel.cs file. Once you have created the project, go ahead and Build it ( Ctrl+B ). This will automatically add the required NuGet package references to the project.
In MainWindow.xaml, you will see the esri:MapView
control has been bound to a property called Map
.
<esri:MapView Map="{Binding Map, Source={StaticResource MapViewModel}}" />
Map is the name of a public property in the MapViewModel class, which implements INotifyPropertyChanged
. For a reminder about data binding, review the tutorial about WPF data binding using INotifyPropertyChanged.
Within MapViewModel.cs, you will create a new async method to initialize your map. You will generate a private async void
method called InitializeMap()
. Be sure to call this method when your MapViewModel() is initialized. Beginning on Line 24, your code will look like the following:
public MapViewModel()
{
InitializeMap();
}
private async void InitializeMap()
{
}
In the InitializeMap() method, you will create a new map and load a feature service that represents transit routes operating in the Atlanta region. You should load these datapoints asynchronously so the UI does not hang while the large data set is loading. Finally, you will add this layer to the map, and zoom into the appropriate area.
private async void InitializeMap()
{
Map newMap = new Map(Basemap.CreateStreets());
FeatureLayer featureLayer = new FeatureLayer(new Uri("https://arcgis.atlantaregional.com/arcgis/rest/services/OpenData/FeatureServer/146"));
await featureLayer.LoadAsync();
newMap.OperationalLayers.Add(featureLayer);
newMap.InitialViewpoint = new Viewpoint(featureLayer.FullExtent);
Map = newMap;
}
On Line 31, you declared a temporary Map object using the World Street Map basemap. Line 32 creates a new layer whose source is the Atlanta public transit feature service. This layer is loaded asynchronously on Line 34. Line 36 adds the layer to the map, and Line 37 sets the map’s viewpoint to the extent of the features in the public transit feature layer.
Recall that the MapView control (from MainWindow.xaml) has a binding associated with the Map property of the MapViewModel class. Therefore, your application’s user interface will only update when this property called Map changes. This is what Line 39 does.
Be patient while your map of Atlanta area transit routes loads; this is a large data set! In the next tutorial, you will learn how to filter the data set to fetch only the desired data.
Following is how your complete MapViewModel.cs may look:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;
using Esri.ArcGISRuntime.Data;
using Esri.ArcGISRuntime.Geometry;
using Esri.ArcGISRuntime.Location;
using Esri.ArcGISRuntime.Mapping;
using Esri.ArcGISRuntime.Security;
using Esri.ArcGISRuntime.Symbology;
using Esri.ArcGISRuntime.Tasks;
using Esri.ArcGISRuntime.UI;
namespace AtlantaTransit
{
public class MapViewModel : INotifyPropertyChanged
{
public MapViewModel()
{
InitializeMap();
}
private async void InitializeMap()
{
Map newMap = new Map(Basemap.CreateStreets());
FeatureLayer featureLayer = new FeatureLayer(new Uri("https://arcgis.atlantaregional.com/arcgis/rest/services/OpenData/FeatureServer/146"));
await featureLayer.LoadAsync();
newMap.OperationalLayers.Add(featureLayer);
newMap.InitialViewpoint = new Viewpoint(featureLayer.FullExtent);
Map = newMap;
}
private Map _map = new Map(Basemap.CreateStreets());
public Map Map
{
get { return _map; }
set { _map = value; OnPropertyChanged(); }
}
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
Don't stop learning!
There is so much to discover about C#. That's why I am making my favorite tips and tricks available for free. Enter your email address below to become a better .NET developer.
Did you know?
Our beautiful, multi-column C# reference guides contain more than 150 tips and examples to make it even easier to write better code.
Get your cheat sheets