Location Display
Download Samples RepositoryDescription
This sample demonstrates the location display using the MapView.LocationDisplay attribute to show your location on a map.The user may change Location Provider settings and view basic details about the current location.
Available for Desktop, Store, Phone
Sample Code
<UserControl x:Class="ArcGISRuntime.Samples.Desktop.LocationDisplay"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:esri="http://schemas.esri.com/arcgis/runtime/2013">
<Grid>
<esri:MapView x:Name="MyMapView" WrapAround="True">
<esri:Map>
<esri:ArcGISTiledMapServiceLayer
ServiceUri="http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer" />
</esri:Map>
</esri:MapView>
<Border Background="White" BorderBrush="Black" BorderThickness="1"
HorizontalAlignment="Left" VerticalAlignment="Top"
Margin="30" Padding="20">
<Border.Effect>
<DropShadowEffect/>
</Border.Effect>
<StackPanel>
<TextBlock Text="Location Display Settings" FontWeight="Bold" Margin="0,4"/>
<CheckBox Content="Enabled" IsChecked="{Binding ElementName=MyMapView, Path=LocationDisplay.IsEnabled}" Margin="0,0,0,5"/>
<TextBlock Text="Auto Pan Mode"/>
<ComboBox SelectedItem="{Binding LocationDisplay.AutoPanMode, ElementName=MyMapView}" Margin="0,2,0,5">
<esri:AutoPanMode>Off</esri:AutoPanMode>
<esri:AutoPanMode>Default</esri:AutoPanMode>
<esri:AutoPanMode>Navigation</esri:AutoPanMode>
</ComboBox>
<TextBlock Text="Location Provider" />
<ComboBox x:Name="providerSelector" SelectionChanged="providerSelector_SelectionChanged" Margin="0,2">
<ComboBoxItem IsSelected="True" Content="System Provider"/>
<ComboBoxItem Content="Random Simulator"/>
</ComboBox>
<Button x:Name="resetDisplay" Click="resetDisplay_Click" Margin="0,15,0,0" Height="22">
<TextBlock Text="Reset Map" Margin="3,0,0,0" Width="135" />
</Button>
</StackPanel>
</Border>
<Border Background="White" BorderBrush="Black" BorderThickness="1"
HorizontalAlignment="Right" VerticalAlignment="Top"
Margin="0,30,30,0" Padding="20" Height="130" Width="136">
<Border.Effect>
<DropShadowEffect/>
</Border.Effect>
</Border>
<Border Background="White" BorderBrush="Black" BorderThickness="1"
HorizontalAlignment="Right" VerticalAlignment="Top"
Margin="30" Padding="20">
<StackPanel >
<TextBlock Text="Current Location" FontWeight="Bold" Margin="0,4"/>
<StackPanel>
<TextBlock Text="{Binding ElementName=MyMapView, Path=LocationDisplay.CurrentLocation.Location.X, StringFormat='X: {0:0.000000}'}" />
<TextBlock Text="{Binding ElementName=MyMapView, Path=LocationDisplay.CurrentLocation.Location.Y, StringFormat='Y: {0:0.000000}'}" />
<TextBlock Text="{Binding ElementName=MyMapView, Path=LocationDisplay.CurrentLocation.Course, StringFormat='Course: {0:0.000}'}" />
<TextBlock Text="{Binding ElementName=MyMapView, Path=LocationDisplay.CurrentLocation.Speed, StringFormat='Speed: {0:0.000}'}" />
</StackPanel>
</StackPanel>
</Border>
</Grid>
</UserControl>
using Esri.ArcGISRuntime.Controls;
using Esri.ArcGISRuntime.Geometry;
using Esri.ArcGISRuntime.Location;
using System;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
namespace ArcGISRuntime.Samples.Desktop
{
/// <summary>
/// This sample demonstrates the location display using the MapView.LocationDisplay attribute to show your location on a map. The user may change Location Provider settings and view basic details about the current location.
/// </summary>
/// <title>Location Display</title>
/// <category>Mapping</category>
public partial class LocationDisplay : UserControl
{
/// <summary>Construct Location Display sample user control</summary>
public LocationDisplay()
{
InitializeComponent();
}
private void providerSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (providerSelector.SelectedIndex == 0)
MyMapView.LocationDisplay.LocationProvider = new SystemLocationProvider();
else
MyMapView.LocationDisplay.LocationProvider = new RandomProvider();
}
/// <summary>Reset the MapView by removing any map rotation and centering on the existing Location. </summary>
private async void resetDisplay_Click(object sender, RoutedEventArgs e)
{
try
{
// If the LocationDisplay is enabled and a Location currently exists, reset the map
// to zero rotation and center on the Location. Otherwise, set the MapView to center on 0,0.
if (MyMapView.LocationDisplay != null &&
MyMapView.LocationDisplay.IsEnabled &&
MyMapView.LocationDisplay.CurrentLocation != null &&
MyMapView.LocationDisplay.CurrentLocation.Location.Extent != null)
{
// Get the current AutoPanMode setting as it is automatically disabled when calling MyMapView.SetView().
var PanMode = MyMapView.LocationDisplay.AutoPanMode;
MyMapView.SetRotation(0);
await MyMapView.SetViewAsync(MyMapView.LocationDisplay.CurrentLocation.Location);
// Reset the AutoPanMode
MyMapView.LocationDisplay.AutoPanMode = PanMode;
}
else
{
var viewpoint = new Viewpoint(MyMapView.Map.Layers[0].FullExtent) { Rotation = 0.0 };
await MyMapView.SetViewAsync(viewpoint);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Sample Error");
}
}
}
/// <summary>Location provider that provides pseudo random location updates</summary>
public class RandomProvider : ILocationProvider
{
private static Random randomizer = new Random();
private DispatcherTimer timer;
LocationInfo oldPosition;
/// <summary>Construct random provider</summary>
public RandomProvider()
{
timer = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(1) };
timer.Tick += timer_Tick;
// Default start location
StartLatitude = 34.057104;
StartLongitude = -117.196816;
}
// Called when the position timer triggers, and calculates the next position based on current speed and heading,
// and adds a little randomization to current heading, speed, and accuracy.
private void timer_Tick(object sender, object e)
{
if (oldPosition == null)
{
oldPosition = new LocationInfo()
{
Location = new MapPoint(StartLongitude, StartLatitude, new SpatialReference(4326)),
Speed = 0,
Course = 0,
HorizontalAccuracy = 20,
};
}
var now = DateTime.Now;
TimeSpan timeParsed = timer.Interval;
double acceleration = randomizer.NextDouble() * 5 - 2.5;
double deltaSpeed = acceleration * timeParsed.TotalSeconds;
double newSpeed = Math.Max(0, deltaSpeed + oldPosition.Speed);
double deltaCourse = randomizer.NextDouble() * 30 - 15;
double newCourse = deltaCourse + oldPosition.Course;
while (newCourse < 0) newCourse += 360;
while (newCourse >= 360) newCourse -= 360;
double distanceTravelled = (newSpeed + oldPosition.Speed) * .5 * timeParsed.TotalSeconds;
double accuracy = Math.Min(500, Math.Max(20, oldPosition.HorizontalAccuracy + (randomizer.NextDouble() * 100 - 50)));
var pos = GetPointFromHeadingGeodesic(new Point(oldPosition.Location.X, oldPosition.Location.Y), distanceTravelled, newCourse - 180);
var newPosition = new LocationInfo()
{
Location = new MapPoint(pos.X, pos.Y, new SpatialReference(4326)),
Speed = newSpeed,
Course = newCourse,
HorizontalAccuracy = accuracy,
};
oldPosition = newPosition;
if (LocationChanged != null)
LocationChanged(this, oldPosition);
}
// Gets a point on the globe based on a location, a heading and a distance.
private static Point GetPointFromHeadingGeodesic(Point start, double distance, double heading)
{
double brng = (180 + heading) / 180 * Math.PI;
double lon1 = start.X / 180 * Math.PI;
double lat1 = start.Y / 180 * Math.PI;
double dR = distance / 6378137; //Angular distance in radians
double lat2 = Math.Asin(Math.Sin(lat1) * Math.Cos(dR) + Math.Cos(lat1) * Math.Sin(dR) * Math.Cos(brng));
double lon2 = lon1 + Math.Atan2(Math.Sin(brng) * Math.Sin(dR) * Math.Cos(lat1), Math.Cos(dR) - Math.Sin(lat1) * Math.Sin(lat2));
double lon = lon2 / Math.PI * 180;
double lat = lat2 / Math.PI * 180;
while (lon < -180) lon += 360;
while (lat < -90) lat += 180;
while (lon > 180) lon -= 360;
while (lat > 90) lat -= 180;
return new Point(lon, lat);
}
/// <summary>Starting Latitude</summary>
public double StartLatitude { get; set; }
/// <summary>Starting Longitude</summary>
public double StartLongitude { get; set; }
/// <summary>Starts the location provider</summary>
public Task StartAsync()
{
timer.Start();
return Task.FromResult<bool>(true);
}
/// <summary>Stops the location provider</summary>
public Task StopAsync()
{
timer.Stop();
return Task.FromResult<bool>(true);
}
/// <summary>LocationChanged event (from ILocationProvider)</summary>
public event EventHandler<LocationInfo> LocationChanged;
}
}