Visualizzare punti di interesse su una mappa
Importante
Ritiro del servizio Bing Maps for Enterprise
I servizi MapControl della piattaforma UWP e mappa dello spazio dei nomi Windows.Services.Maps si basano su Bing Maps. Bing Maps for Enterprise è deprecato e verrà ritirato, a questo punto MapControl e i servizi non riceveranno più dati.
Per altre informazioni, vedere la documentazione del Centro per sviluppatori di Bing Maps e di Bing Maps.
Nota
MapControl e i servizi per le mappe richiedono una chiave di autenticazione delle mappe denominata MapServiceToken. Per altre informazioni su come ottenere e impostare una chiave di autenticazione delle mappe, vedere Richiedere una chiave di autenticazione per le mappe.
Si possono aggiungere punti di interesse a una mappa usando puntine, immagini, forme ed elementi dell'interfaccia utente XAML. Un punto di interesse (POI) è un punto specifico sulla mappa che rappresenta un elemento di interesse. Ad esempio, la posizione di un'azienda, una città o un amico.
Visualizzare puntine, immagini e forme sulla mappa aggiungendo oggetti MapIcon, MapBillboard, MapPolygon e oggetti MapPolyline a una raccolta MapElements di un oggetto MapElementsLayer. Aggiungere quindi l'oggetto layer all'insieme Layers di un controllo mappa.
Nota
Nelle versioni precedenti, questa guida ha illustrato come aggiungere elementi mappa all'insieme MapElements. Anche se è comunque possibile usare questo approccio, si perderanno alcuni dei vantaggi del nuovo modello di livello mappa. Per maggiori informazioni, vedere la sezione Uso dei livelli di questa guida.
Si può anche visualizzare elementi dell'interfaccia utente XAML, ad esempio Button, un HyperlinkButton, o un TextBlock sulla mappa aggiungendoli a MapItemsControl or as Children di MapControl.
Se si dispone di un numero elevato di elementi da posizionare sulla mappa, valutare la possibilità di sovrapporre immagini affiancate sulla mappa. Per visualizzare le strade sulla mappa, vedere Visualizzare itinerari e indicazioni stradali
Aggiungere una puntina
Visualizzare un'immagine di questo tipo di puntina, con testo facoltativo, sulla mappa usando la classe MapIcon. È possibile accettare l'immagine predefinita o fornire un'immagine personalizzata usando la proprietà Image. L'immagine seguente mostra l'immagine predefinita per MapIcon senza alcun valore specificato per la proprietà Title, con un titolo breve, un titolo lungo e un titolo molto lungo.
L'esempio seguente mostra una mappa della città di Seattle e aggiunge una MapIcon con l'immagine predefinita e un titolo facoltativo per indicare la posizione dello Space Needle. Centra anche la mappa sull'icona e lo zoom avanti. Per informazioni generali sull'uso del controllo mappa, vedere Visualizzare mappe con visualizzazioni 2D, 3D e Streetside.
public void AddSpaceNeedleIcon()
{
var MyLandmarks = new List<MapElement>();
BasicGeoposition snPosition = new BasicGeoposition { Latitude = 47.620, Longitude = -122.349 };
Geopoint snPoint = new Geopoint(snPosition);
var spaceNeedleIcon = new MapIcon
{
Location = snPoint,
NormalizedAnchorPoint = new Point(0.5, 1.0),
ZIndex = 0,
Title = "Space Needle"
};
MyLandmarks.Add(spaceNeedleIcon);
var LandmarksLayer = new MapElementsLayer
{
ZIndex = 1,
MapElements = MyLandmarks
};
myMap.Layers.Add(LandmarksLayer);
myMap.Center = snPoint;
myMap.ZoomLevel = 14;
}
In questo esempio viene visualizzato il punto di interesse seguente sulla mappa (immagine predefinita al centro).
Nella riga di codice seguente viene visualizzata la MapIcon con un'immagine personalizzata salvata nella cartella Assets del progetto. La proprietà Image della MapIcon attende un valore di tipo RandomAccessStreamReference. Questo tipo richiede una dichiarazione in uso per lo spazio dei nomi Windows.Storage.Streams.
Nota
Se si usa la stessa immagine per più icone della mappa, dichiarare RandomAccessStreamReference a livello di pagina o app per ottenere prestazioni ottimali.
MapIcon1.Image =
RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/customicon.png"));
Tenere presenti queste considerazioni quando si lavora con la classe MapIcon:
- La proprietà Image supporta una dimensione massima dell'immagine di 2048×2048 pixel.
- Per impostazione predefinita, l'immagine dell'icona della mappa non è garantita. Può essere nascosta quando nasconde altri elementi o etichette sulla mappa. Per mantenerlo visibile, impostare la proprietà CollisionBehaviorDesired dell'icona della mappa MapElementCollisionBehavior.RemainVisible.
- Non è garantito che venga visualizzato il Titolo facoltativo di MapIcon. Se il testo non viene visualizzato, eseguire lo zoom indietro riducendo il valore della proprietà ZoomLevel di MapControl.
- Quando si visualizza un'immagine MapIcon che punta a una posizione specifica sulla mappa, ad esempio una puntina o una freccia, è consigliabile impostare il valore della proprietà NormalizedAnchorPoint sulla posizione approssimativa del puntatore sull'immagine. Se si lascia il valore di NormalizedAnchorPoint sul valore predefinito di (0, 0), che rappresenta l'angolo superiore sinistro dell'immagine, le modifiche apportate a ZoomLevel della mappa potrebbero far sì che l'immagine punti a una posizione diversa.
- Se non si imposta in modo esplicito un oggetto Altitude e AltitudeReferenceSystem, la MapIcon verrà posizionato sulla superficie.
Aggiungere una puntina 3D
È possibile aggiungere oggetti tridimensionali a una mappa. Usare la classe MapModel3D per importare un oggetto 3D da un file 3D Manufacturing Format (3MF).
Questa immagine usa tazze di caffè 3D per contrassegnare le posizioni delle caffetterie in un quartiere.
Il codice seguente aggiunge una tazza di caffè alla mappa tramite l'importazione di un file 3MF. Per semplificare le operazioni, questo codice aggiunge l'immagine al centro della mappa, ma è probabile che il codice aggiunga l'immagine a una posizione specifica.
public async void Add3DMapModel()
{
var mugStreamReference = RandomAccessStreamReference.CreateFromUri
(new Uri("ms-appx:///Assets/mug.3mf"));
var myModel = await MapModel3D.CreateFrom3MFAsync(mugStreamReference,
MapModel3DShadingOption.Smooth);
myMap.Layers.Add(new MapElementsLayer
{
ZIndex = 1,
MapElements = new List<MapElement>
{
new MapElement3D
{
Location = myMap.Center,
Model = myModel,
},
},
});
}
Aggiunta di un'immagine
Visualizzare immagini di grandi dimensioni correlate a posizioni mappate, ad esempio un'immagine di un ristorante o di un punto di riferimento. Quando gli utenti eseguono lo zoom indietro, l'immagine si ridurrà proporzionalmente in modo da consentire all'utente di visualizzare un'area più grande della mappa. Questo è un po' diverso da una MapIcon che contrassegna una posizione specifica, è in genere di piccole dimensioni e rimane la stessa dimensione dello zoom avanti e indietro di una mappa.
Il codice seguente mostra la mapBillboard presentata nell'immagine precedente.
public void AddLandmarkPhoto()
{
// Create MapBillboard.
RandomAccessStreamReference mapBillboardStreamReference =
RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/billboard.jpg"));
var mapBillboard = new MapBillboard(myMap.ActualCamera)
{
Location = myMap.Center,
NormalizedAnchorPoint = new Point(0.5, 1.0),
Image = mapBillboardStreamReference
};
// Add MapBillboard to a layer on the map control.
var MyLandmarkPhotos = new List<MapElement>();
MyLandmarkPhotos.Add(mapBillboard);
var LandmarksPhotoLayer = new MapElementsLayer
{
ZIndex = 1,
MapElements = MyLandmarkPhotos
};
myMap.Layers.Add(LandmarksPhotoLayer);
}
Ci sono tre parti di questo codice da esaminare più da vicino: l'immagine, la fotocamera di riferimento e la proprietà NormalizedAnchorPoint.
Immagine
Questo esempio mostra un'immagine personalizzata salvata nella cartella Assets del progetto. La proprietà Image di MapBillboard attende un valore di tipo RandomAccessStreamReference. Questo tipo richiede una dichiarazione in uso per lo spazio dei nomi Windows.Storage.Streams.
Nota
Se si usa la stessa immagine per più icone della mappa, dichiarare RandomAccessStreamReference a livello di pagina o app per ottenere prestazioni ottimali.
Fotocamera di riferimento
Poiché un'immagine MapBillboard viene ridimensionata e ridotta man mano che lo ZoomLevel della mappa cambia, è importante definire dove in questo ZoomLevel l'immagine viene visualizzata su una scala 1x normale. Tale posizione è definita nella fotocamera di riferimento di MapBillboard e per impostarla si deve passare un oggetto MapCamera nel costruttore di MapBillboard.
È possibile definire la posizione desiderata in un Geopoint e quindi usare questo Geopoint per creare un oggetto MapCamera. In questo esempio, tuttavia, viene usato solo l'oggetto MapCamera restituito dalla proprietà ActualCamera del controllo mappa. Questa è la fotocamera interna della mappa. La posizione corrente della fotocamera diventa la posizione della fotocamera di riferimento; posizione in cui viene visualizzata l'immagine MapBillboard in scala 1x.
Se l'app offre agli utenti la possibilità di ingrandire la mappa, l'immagine diminuisce di dimensioni perché la fotocamera interna delle mappe aumenta in altitudine mentre l'immagine su scala 1x rimane fissa nella posizione della fotocamera di riferimento.
NormalizedAnchorPoint
NormalizedAnchorPoint è il punto dell'immagine ancorata alla proprietà Location di MapBillboard. Il punto 0,5,1 è il centro inferiore dell'immagine. Poiché abbiamo impostato la proprietà Location di MapBillboard sul centro del controllo della mappa, il centro inferiore dell'immagine verrà ancorato al centro del controllo mappe. Se si desidera che l'immagine venga visualizzata al centro direttamente su un punto, impostare NormalizedAnchorPoint a 0.5,0.5.
Aggiungere una forma
Visualizzare una forma a più punti sulla mappa usando la classe MapPolygon. L'esempio seguente, nell'esempio di mappa UWP, visualizza una casella rossa con bordo blu sulla mappa.
public void HighlightArea()
{
// Create MapPolygon.
double centerLatitude = myMap.Center.Position.Latitude;
double centerLongitude = myMap.Center.Position.Longitude;
var mapPolygon = new MapPolygon
{
Path = new Geopath(new List<BasicGeoposition> {
new BasicGeoposition() {Latitude=centerLatitude+0.0005, Longitude=centerLongitude-0.001 },
new BasicGeoposition() {Latitude=centerLatitude-0.0005, Longitude=centerLongitude-0.001 },
new BasicGeoposition() {Latitude=centerLatitude-0.0005, Longitude=centerLongitude+0.001 },
new BasicGeoposition() {Latitude=centerLatitude+0.0005, Longitude=centerLongitude+0.001 },
}),
ZIndex = 1,
FillColor = Colors.Red,
StrokeColor = Colors.Blue,
StrokeThickness = 3,
StrokeDashed = false,
};
// Add MapPolygon to a layer on the map control.
var MyHighlights = new List<MapElement>();
MyHighlights.Add(mapPolygon);
var HighlightsLayer = new MapElementsLayer
{
ZIndex = 1,
MapElements = MyHighlights
};
myMap.Layers.Add(HighlightsLayer);
}
Aggiungi a riga
Visualizzare una linea sulla mappa usando la classe MapPolyline. L'esempio seguente, tratto dall'esempio mappa UWP, visualizza una linea tratteggiata sulla mappa.
public void DrawLineOnMap()
{
// Create Polyline.
double centerLatitude = myMap.Center.Position.Latitude;
double centerLongitude = myMap.Center.Position.Longitude;
var mapPolyline = new MapPolyline
{
Path = new Geopath(new List<BasicGeoposition> {
new BasicGeoposition() {Latitude=centerLatitude-0.0005, Longitude=centerLongitude-0.001 },
new BasicGeoposition() {Latitude=centerLatitude+0.0005, Longitude=centerLongitude+0.001 },
}),
StrokeColor = Colors.Black,
StrokeThickness = 3,
StrokeDashed = true,
};
// Add Polyline to a layer on the map control.
var MyLines = new List<MapElement>();
MyLines.Add(mapPolyline);
var LinesLayer = new MapElementsLayer
{
ZIndex = 1,
MapElements = MyLines
};
myMap.Layers.Add(LinesLayer);
}
Aggiungere XAML
Visualizzare elementi dell'interfaccia utente personalizzati sulla mappa usando XAML. Posizionare XAML sulla mappa specificando la posizione e il punto di ancoraggio normalizzato del codice XAML.
- Impostare la posizione sulla mappa in cui viene posizionato il codice XAML chiamando SetLocation.
- Impostare la posizione relativa su XAML che corrisponde alla posizione specificata chiamando SetNormalizedAnchorPoint.
L'esempio seguente mostra una mappa della città di Seattle e aggiunge un controllo Border XAML per indicare la posizione di Space Needle. Centra anche la mappa sull'area e lo zoom avanti. Per informazioni generali sull'uso del controllo mappa, vedere Visualizzare mappe con visualizzazioni 2D, 3D e Streetside.
private void displayXAMLButton_Click(object sender, RoutedEventArgs e)
{
// Specify a known location.
BasicGeoposition snPosition = new BasicGeoposition { Latitude = 47.620, Longitude = -122.349 };
Geopoint snPoint = new Geopoint(snPosition);
// Create a XAML border.
Border border = new Border
{
Height = 100,
Width = 100,
BorderBrush = new SolidColorBrush(Windows.UI.Colors.Blue),
BorderThickness = new Thickness(5),
};
// Center the map over the POI.
MapControl1.Center = snPoint;
MapControl1.ZoomLevel = 14;
// Add XAML to the map.
MapControl1.Children.Add(border);
MapControl.SetLocation(border, snPoint);
MapControl.SetNormalizedAnchorPoint(border, new Point(0.5, 0.5));
}
In questo esempio viene visualizzato un bordo blu sulla mappa.
Gli esempi successivi illustrano come aggiungere elementi dell'interfaccia utente XAML direttamente nel markup XAML della pagina usando il data binding. Come per altri elementi XAML che visualizzano contenuto, Children è la proprietà di contenuto predefinita di MapControl e non deve essere specificata in modo esplicito nel markup XAML.
Questo esempio mostra come visualizzare due controlli XAML come elementi figlio impliciti di MapControl. Questi controlli vengono visualizzati sulla mappa in corrispondenza delle posizioni associate ai dati.
<maps:MapControl>
<TextBox Text="Seattle" maps:MapControl.Location="{x:Bind SeattleLocation}"/>
<TextBox Text="Bellevue" maps:MapControl.Location="{x:Bind BellevueLocation}"/>
</maps:MapControl>
Impostare questi percorsi usando le proprietà nel file code-behind.
public Geopoint SeattleLocation { get; set; }
public Geopoint BellevueLocation { get; set; }
Questo esempio mostra come visualizzare due controlli XAML contenuti in un oggetto MapItemsControl. Questi controlli vengono visualizzati sulla mappa in corrispondenza delle posizioni associate ai dati.
<maps:MapControl>
<maps:MapItemsControl>
<TextBox Text="Seattle" maps:MapControl.Location="{x:Bind SeattleLocation}"/>
<TextBox Text="Bellevue" maps:MapControl.Location="{x:Bind BellevueLocation}"/>
</maps:MapItemsControl>
</maps:MapControl>
In questo esempio viene visualizzata una raccolta di elementi XAML associati a un oggetto MapItemsControl.
<maps:MapControl x:Name="MapControl" MapTapped="MapTapped" MapDoubleTapped="MapTapped" MapHolding="MapTapped">
<maps:MapItemsControl ItemsSource="{x:Bind LandmarkOverlays}">
<maps:MapItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Background="Black" Tapped ="Overlay_Tapped">
<TextBlock maps:MapControl.Location="{Binding Location}" Text="{Binding Title}"
maps:MapControl.NormalizedAnchorPoint="0.5,0.5" FontSize="20" Margin="5"/>
</StackPanel>
</DataTemplate>
</maps:MapItemsControl.ItemTemplate>
</maps:MapItemsControl>
</maps:MapControl>
La ItemsSource
proprietà nell'esempio precedente è associata a una proprietà di tipo IList nel file code-behind.
public sealed partial class Scenario1 : Page
{
public IList LandmarkOverlays { get; set; }
public MyClassConstructor()
{
SetLandMarkLocations();
this.InitializeComponent();
}
private void SetLandMarkLocations()
{
LandmarkOverlays = new List<MapElement>();
var pikePlaceIcon = new MapIcon
{
Location = new Geopoint(new BasicGeoposition
{ Latitude = 47.610, Longitude = -122.342 }),
Title = "Pike Place Market"
};
LandmarkOverlays.Add(pikePlaceIcon);
var SeattleSpaceNeedleIcon = new MapIcon
{
Location = new Geopoint(new BasicGeoposition
{ Latitude = 47.6205, Longitude = -122.3493 }),
Title = "Seattle Space Needle"
};
LandmarkOverlays.Add(SeattleSpaceNeedleIcon);
}
}
Uso dei livelli
Gli esempi in questa guida aggiungono elementi a un insieme MapElementsLayer . Illustrano quindi come aggiungere tale raccolta alla proprietà Layers del controllo mappa. Nelle versioni precedenti, questa guida ha illustrato come aggiungere elementi mappa all'insieme MapElements come segue:
var pikePlaceIcon = new MapIcon
{
Location = new Geopoint(new BasicGeoposition
{ Latitude = 47.610, Longitude = -122.342 }),
NormalizedAnchorPoint = new Point(0.5, 1.0),
ZIndex = 0,
Title = "Pike Place Market"
};
myMap.MapElements.Add(pikePlaceIcon);
Anche se è comunque possibile usare questo approccio, si perderanno alcuni dei vantaggi del nuovo modello di livello mappa. Raggruppando gli elementi in livelli, è possibile modificare ogni livello in modo indipendente l'uno dall'altro. Ad esempio, ogni livello ha un proprio set di eventi in modo da poter rispondere a un evento su un livello specifico ed eseguire un'azione specifica per l'evento.
Inoltre, si può associare XAML direttamente a un MapLayer. Si tratta di un'operazione che non è possibile eseguire usando la raccolta MapElements.
Un modo per eseguire questa operazione consiste nell'usare una classe del modello di visualizzazione, un code-behind di una pagina XAML e una pagina XAML.
Visualizzare la classe del modello
public class LandmarksViewModel
{
public ObservableCollection<MapLayer> LandmarkLayer
{ get; } = new ObservableCollection<MapLayer>();
public LandmarksViewModel()
{
var MyElements = new List<MapElement>();
var pikePlaceIcon = new MapIcon
{
Location = new Geopoint(new BasicGeoposition
{ Latitude = 47.610, Longitude = -122.342 }),
Title = "Pike Place Market"
};
MyElements.Add(pikePlaceIcon);
var LandmarksLayer = new MapElementsLayer
{
ZIndex = 1,
MapElements = MyElements
};
LandmarkLayer.Add(LandmarksLayer);
}
Code-behind di una pagina XAML
Connettere la classe del modello di visualizzazione nella tabella code-behind.
public LandmarksViewModel ViewModel { get; set; }
public myMapPage()
{
this.InitializeComponent();
this.ViewModel = new LandmarksViewModel();
}
Pagina XAML
Nella pagina XAML, associarla alla proprietà nella classe del modello di visualizzazione che restituisce il livello.
<maps:MapControl
x:Name="myMap" TransitFeaturesVisible="False" Loaded="MyMap_Loaded" Grid.Row="2"
MapServiceToken="Your token" Layers="{x:Bind ViewModel.LandmarkLayer}"/>