Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Windows App SDK a WinUI 3 poskytují rozhraní API a ovládací prvky pro zobrazení map, zjišťování polohy uživatele a nastavení geofence. Pomocí těchto možností můžete vytvářet aplikace, které zobrazují interaktivní mapy s špendlíky, sledovat polohu uživatele a aktivovat akce, když uživatel vstoupí nebo opustí zeměpisnou oblast.
Tento článek představuje každou funkci a obsahuje kompletní příklad , který kombinuje MapControl, Geolocatora GeofenceMonitor v jedné pracovní aplikaci.
Zobrazení map pomocí MapControl
MapControl zobrazí interaktivní mapu využívající Azure Maps. Můžete přidat špendlíky, vrstvy a reagovat na interakce uživatelů, jako je posouvání, přiblížení a kliknutí.
MapControl vyžaduje účet Azure Maps. Informace o vytvoření účtu a získání tokenu služby najdete v tématu Správa účtu Azure Maps.
Podrobné pokyny k použití najdete v tématu MapControl.
<MapControl x:Name="myMap"
MapServiceToken="YOUR_AZURE_MAPS_TOKEN"
Height="400" />
Note
UWP MapControl a rozhraní API Windows.Services.Maps jsou zastaralé a v budoucích verzích Windows nemusí být k dispozici. Aplikace WinUI 3 by měly používat nový MapControl popsaný výše. Další informace najdete v tématu Zdroje informací o zastaralých funkcích.
Zjištění polohy uživatele
Rozhraní API Windows.Devices.Geolocation umožňují získat zeměpisnou polohu zařízení. Tato rozhraní API fungují v aplikacích pro UPW i Windows App SDK (WinUI 3). Máte tyto možnosti:
- Získejte jednorázovou pozici pomocí Geolocator.GetGeopositionAsync.
- Pomocí události Geolocator.PositionChangedmůžete sledovat změny pozice v průběhu času.
- Monitorování změn stavu návštěv pomocí GeovisitMonitor pro energeticky úsporné zjišťování polohy.
Podrobný průvodce najdete v tématu Získání polohy uživatele.
Nastavení geofences
Geofence definuje geografickou hranici. Aplikace obdrží oznámení, když uživatel vstoupí nebo ukončí hranici. Geografické zóny jsou užitečné pro připomenutí, upozornění nebo doručování obsahu na základě polohy.
Pokyny k vytváření a monitorování geofence najdete v tématu Nastavení geografické zóny.
Funkce určování polohy a ochrana osobních údajů
Všechna rozhraní API pro umístění vyžadují funkci umístění deklarovanou v manifestu balíčku vaší aplikace. Před přístupem k údajům o poloze musíte také za běhu aplikace zavolat Geolocator.RequestAccessAsync.
Windows uživatelům dává kontrolu nad tím, které aplikace mají přístup k jejich poloze prostřednictvím nastavení > Soukromí a umístění zabezpečení>. Vaše aplikace by měla počítat se situací, kdy uživatel nepovolí nebo zruší přístup k poloze.
Kompletní příklad
Následující příklad spojuje MapControl, Geolocatora GeofenceMonitor v jednom okně WinUI 3. Pokud není nakonfigurovaný žádný klíč služby Azure Maps, mapa se korektně přepne do omezeného režimu, zatímco geolokace a geofencing budou nadále fungovat.
Předpoklady
- Windows App SDK 2.2 nebo novější
- Klíč Azure Maps – potřebný k zobrazení dlaždic mapy. Bez platného klíče se MapControl vykreslí, ale zobrazí prázdnou mapu.
- Schopnost zařízení Poloha deklarovaná v
Package.appxmanifest:
<DeviceCapability Name="location" />
Před spuštěním aplikace nastavte klíč Azure Maps jako proměnnou prostředí:
$env:AZURE_MAPS_KEY = "your-key-here"
MainWindow.xaml
Vlevo je ovládací panel o šířce 300 pixelů s tlačítky a stavovým textem a vpravo MapControl. Když chybí klíč Azure Maps, zobrazí se překryv.
<?xml version="1.0" encoding="utf-8" ?>
<Window
x:Class="MapLocationDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Map Location Demo">
<Window.SystemBackdrop>
<MicaBackdrop />
</Window.SystemBackdrop>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TitleBar Title="Map Location Demo" />
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Margin="16" RowSpacing="12">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="Location Demo" FontSize="20" FontWeight="Bold"/>
<StackPanel Grid.Row="1" Spacing="8">
<Button x:Name="FindMeButton" Content="Find My Location"
Click="FindMeButton_Click" HorizontalAlignment="Stretch"/>
<Button x:Name="AddGeofenceButton" Content="Add Geofence Here"
Click="AddGeofenceButton_Click" HorizontalAlignment="Stretch"/>
</StackPanel>
<TextBlock x:Name="StatusText" Grid.Row="2"
Text="Click 'Find My Location' to begin." TextWrapping="Wrap"/>
<ListView x:Name="EventLog" Grid.Row="3" Header="Event Log"/>
</Grid>
<Grid Grid.Column="1">
<MapControl x:Name="MyMap" />
<StackPanel x:Name="MapKeyMissing" Visibility="Collapsed"
HorizontalAlignment="Center" VerticalAlignment="Center"
Spacing="8">
<FontIcon Glyph="" FontSize="48"
HorizontalAlignment="Center"
Foreground="{ThemeResource SystemFillColorCautionBrush}" />
<TextBlock Text="Azure Maps key not configured"
FontSize="18" FontWeight="SemiBold"
HorizontalAlignment="Center" />
<TextBlock x:Name="MapKeyHint" TextWrapping="Wrap" MaxWidth="400"
HorizontalAlignment="Center" TextAlignment="Center"
Foreground="{ThemeResource TextFillColorSecondaryBrush}" />
</StackPanel>
</Grid>
</Grid>
</Grid>
</Window>
MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Windows.Devices.Geolocation;
using Windows.Devices.Geolocation.Geofencing;
namespace MapLocationDemo;
public sealed partial class MainWindow : Window
{
private Geolocator? _geolocator;
private BasicGeoposition _lastPosition;
private bool _mapAvailable;
public MainWindow()
{
InitializeComponent();
_mapAvailable = TryConfigureMap();
GeofenceMonitor.Current.GeofenceStateChanged += OnGeofenceStateChanged;
}
// Read the Azure Maps key from an environment variable.
// If missing, collapse the map and show an informational overlay.
private bool TryConfigureMap()
{
var key = Environment.GetEnvironmentVariable("AZURE_MAPS_KEY");
if (string.IsNullOrWhiteSpace(key))
{
MyMap.Visibility = Visibility.Collapsed;
MapKeyMissing.Visibility = Visibility.Visible;
MapKeyHint.Text = "Set the AZURE_MAPS_KEY environment variable "
+ "and restart.\nGeolocation and geofencing still work "
+ "without the map.";
Log("Azure Maps key not found — map disabled");
return false;
}
MyMap.MapServiceToken = key;
return true;
}
private async void FindMeButton_Click(object sender, RoutedEventArgs e)
{
FindMeButton.IsEnabled = false;
StatusText.Text = "Requesting location access...";
var access = await Geolocator.RequestAccessAsync();
if (access != GeolocationAccessStatus.Allowed)
{
StatusText.Text =
"Location access denied. Check Settings > Privacy > Location.";
FindMeButton.IsEnabled = true;
return;
}
_geolocator = new Geolocator { DesiredAccuracyInMeters = 100 };
try
{
var pos = await _geolocator.GetGeopositionAsync();
var lat = pos.Coordinate.Point.Position.Latitude;
var lon = pos.Coordinate.Point.Position.Longitude;
_lastPosition = new BasicGeoposition
{
Latitude = lat, Longitude = lon
};
StatusText.Text =
$"Location: {lat:F5}, {lon:F5} ({pos.Coordinate.Accuracy:F0} m)";
Log($"Position: {lat:F5}, {lon:F5}");
if (_mapAvailable)
{
var pt = new Geopoint(_lastPosition);
MyMap.Center = pt;
MyMap.ZoomLevel = 15;
var layer = new MapElementsLayer();
layer.MapElements = new List<MapElement>
{
new MapIcon { Location = pt }
};
MyMap.Layers.Clear();
MyMap.Layers.Add(layer);
}
}
catch (Exception ex) { StatusText.Text = $"Error: {ex.Message}"; }
finally { FindMeButton.IsEnabled = true; }
}
private void AddGeofenceButton_Click(object sender, RoutedEventArgs e)
{
if (_lastPosition.Latitude == 0 && _lastPosition.Longitude == 0)
{
StatusText.Text = "Get your location first.";
return;
}
var fence = new Geofence("MyGeofence",
new Geocircle(_lastPosition, 200),
MonitoredGeofenceStates.Entered | MonitoredGeofenceStates.Exited,
false, TimeSpan.FromSeconds(5));
GeofenceMonitor.Current.Geofences.Add(fence);
StatusText.Text = $"Geofence added at "
+ $"{_lastPosition.Latitude:F5}, {_lastPosition.Longitude:F5}";
Log("Geofence registered");
}
private void OnGeofenceStateChanged(
GeofenceMonitor sender, object args)
{
var reports = sender.ReadReports();
DispatcherQueue.TryEnqueue(() =>
{
foreach (var r in reports)
{
var msg = r.NewState switch
{
GeofenceState.Entered => $"Entered: {r.Geofence.Id}",
GeofenceState.Exited => $"Exited: {r.Geofence.Id}",
GeofenceState.Removed => $"Removed: {r.Geofence.Id}",
_ => null
};
if (msg != null) { StatusText.Text = msg; Log(msg); }
}
});
}
private void Log(string msg) =>
EventLog.Items.Insert(0, $"[{DateTime.Now:HH:mm:ss}] {msg}");
}
Klíčové vzory
-
MapControlje integrovaný do Windows App SDK 1.6 a novější. NastavteMapServiceTokenna svůj klíč Azure Maps. -
TryConfigureMapzkontroluje proměnnouAZURE_MAPS_KEYprostředí při spuštění. Pokud je proměnná prázdná, mapa se skryje a překryvná vrstva vysvětlí, jak problém opravit – bez chybového ukončení a bez prázdné mapy. -
DeviceCapability Name="location"vPackage.appxmanifestje vyžadováno, jinakGeolocator.RequestAccessAsyncvrátíDenied. -
GeofenceMonitor.GeofenceStateChangedaktivuje vlákno na pozadí, takže se používáDispatcherQueue.TryEnqueuek aktualizaci uživatelského rozhraní.
Související články
Windows developer