Xamarin.Forms 地图控件

Download Sample下载示例

Map 控件是用于显示和批注地图的跨平台视图。 它使用每个平台的本机地图控件,为用户提供快速熟悉的地图体验:

Screenshot of map control, on iOS and Android

Map 类定义以下用于控制地图外观和行为的属性:

  • IsShowingUser,类型为 bool,指示地图是否显示用户的当前位置。
  • ItemsSource,类型为 IEnumerable,指定要显示的 IEnumerable 项的集合。
  • ItemTemplate,类型为 DataTemplate,指定要应用于显示项集合中的每一项的 DataTemplate
  • ItemTemplateSelector,类型为 DataTemplateSelector,指定将用于在运行时为项选择 DataTemplateDataTemplateSelector
  • HasScrollEnabled,类型为 bool,确定是否允许地图滚动。
  • HasZoomEnabled,类型为 bool,确定是否允许地图缩放。
  • MapElements,类型为 IList<MapElement>,表示地图上的元素列表,如多边形和折线。
  • MapType,类型为 MapType,指示地图的显示样式。
  • MoveToLastRegionOnLayoutChange,类型为 bool,控制当布局发生变化时,显示的地图区域是否从其当前区域移动到其以前设置的区域。
  • Pins,类型为 IList<Pin>,表示地图上的图钉列表。
  • TrafficEnabled,类型为 bool,指示地图上是否覆盖流量数据。
  • VisibleRegion,类型为 MapSpan,返回地图当前显示的区域。

这些属性中除 MapElementsPinsVisibleRegion 外,其他均由 BindableProperty 对象提供支持,这意味着它们可以成为数据绑定的目标。

Map 类还定义点击地图时触发的 MapClicked 事件。 事件附带的 MapClickedEventArgs 对象包含一个名为 Position 的属性,类型为 Position。 触发此事件时,Position 属性将设置为点击的地图位置。 有关 Position 结构的信息,请参阅地图位置和距离

有关 ItemsSourceItemTemplateItemTemplateSelector 属性的信息,请参阅显示图钉集合

显示地图

可以通过将 Map 添加到布局或页面来显示它:

<ContentPage ...
             xmlns:maps="clr-namespace:Xamarin.Forms.Maps;assembly=Xamarin.Forms.Maps">
    <maps:Map x:Name="map" />
</ContentPage>

注意

引用 Xamarin.Forms.Maps 控件需要额外的 xmlns 命名空间定义。 在前面的示例中,Xamarin.Forms.Maps 命名空间通过 maps 关键字引用。

等效 C# 代码如下:

using Xamarin.Forms;
using Xamarin.Forms.Maps;

namespace WorkingWithMaps
{
    public class MapTypesPageCode : ContentPage
    {
        public MapTypesPageCode()
        {
            Map map = new Map();
            Content = map;
        }
    }
}

此示例调用默认 Map 构造函数,该构造函数在地图中以罗马为中心:

Screenshot of map control with default location, on iOS and Android

或者,可以将 MapSpan 参数传递给 Map 构造函数,以在加载地图时设置地图的中心点和缩放级别。 有关详细信息,请参阅在地图上显示特定位置

地图类型

可以将 Map.MapType 属性设置为 MapType 枚举成员,以定义地图的显示样式。 MapType 枚举定义以下成员:

  • Street 指定将显示街道地图。
  • Satellite 指定将显示包含卫星图像的地图。
  • Hybrid 指定将显示合并街道和卫星数据的地图。

默认情况下,如果未定义 MapType 属性,则 Map 将显示街道地图。 或者,可以将 MapType 属性设置为其中一个 MapType 枚举成员:

<maps:Map MapType="Satellite" />

等效 C# 代码如下:

Map map = new Map
{
    MapType = MapType.Satellite
};

以下屏幕截图显示了当 MapType 属性设置为 Street 时的 Map

Screenshot of map control with the street map type, on iOS and Android

以下屏幕截图显示了当 MapType 属性设置为 Satellite 时的 Map

Screenshot of map control with the satellite map type, on iOS and Android

以下屏幕截图显示了当 MapType 属性设置为 Hybrid 时的 Map

Screenshot of map control with the hybrid map type, on iOS and Android

在地图上显示特定位置

可以通过将 MapSpan 参数传递给 Map 构造函数来设置加载地图时要显示的地图区域:

<maps:Map>
    <x:Arguments>
        <maps:MapSpan>
            <x:Arguments>
                <maps:Position>
                    <x:Arguments>
                        <x:Double>36.9628066</x:Double>
                        <x:Double>-122.0194722</x:Double>
                    </x:Arguments>
                </maps:Position>
                <x:Double>0.01</x:Double>
                <x:Double>0.01</x:Double>
            </x:Arguments>
        </maps:MapSpan>
    </x:Arguments>
</maps:Map>

等效 C# 代码如下:

Position position = new Position(36.9628066, -122.0194722);
MapSpan mapSpan = new MapSpan(position, 0.01, 0.01);
Map map = new Map(mapSpan);

此示例创建一个 Map 对象,该对象显示由 MapSpan 对象指定的区域。 MapSpan 对象以 Position 对象表示的经纬度为中心,跨越范围为纬度 0.01 度,经度 0.01 度。 有关 Position 结构的信息,请参阅地图位置和距离。 有关在 XAML 中传递自变量的信息,请参阅在 XAML 中传递自变量

结果是,当显示地图时,它以特定位置为中心,并跨越特定数量的纬度和经度:

Screenshot of map control with specified location, on iOS and Android

创建 MapSpan 对象

有多种方法可用于创建 MapSpan 对象。 一种常见的方法是向 MapSpan 构造函数提供所需的参数。 它们是由 Position 对象表示的经纬度,以及表示 MapSpan 跨越的经纬度的 double 值。 有关 Position 结构的信息,请参阅地图位置和距离

或者,MapSpan 类中有三个方法可用于返回新的 MapSpan 对象:

  1. ClampLatitude 返回与方法的类实例相同 LongitudeDegreesMapSpan,以及由其 northsouth 参数定义的半径。
  2. FromCenterAndRadius 返回由其 PositionDistance 参数定义的 MapSpan
  3. WithZoom 返回一个 MapSpan,其中心点与方法的类实例相同,但具有乘以其 double 参数的半径。

有关 Distance 结构的信息,请参阅地图位置和距离

创建 MapSpan 后,可以访问以下属性来检索有关它的数据:

移动地图

可以调用 Map.MoveToRegion 方法来更改地图的位置和缩放级别。 此方法接受 MapSpan 参数,该参数定义要显示的地图区域及其缩放级别。

以下代码显示了在地图上移动所显示区域的示例:

MapSpan mapSpan = MapSpan.FromCenterAndRadius(position, Distance.FromKilometers(0.444));
map.MoveToRegion(mapSpan);

缩放地图

可以在不更改 Map 位置的情况下更改其缩放级别。 这可以通过地图 UI 完成,也可以通过调用包含 MapSpan 参数的 MoveToRegion 方法以编程方式完成,该参数将当前位置用作 Position 参数:

double zoomLevel = 0.5;
double latlongDegrees = 360 / (Math.Pow(2, zoomLevel));
if (map.VisibleRegion != null)
{
    map.MoveToRegion(new MapSpan(map.VisibleRegion.Center, latlongDegrees, latlongDegrees));
}

在此示例中,使用 MapSpan 参数调用 MoveToRegion 方法,该参数通过 Map.VisibleRegion 属性指定地图的当前位置,并将缩放级别指定为纬度数和经度数。 总体结果是地图的缩放级别已更改,但其位置未更改。 在地图上实现缩放的另一种方法是使用 MapSpan.WithZoom 方法控制缩放因子。

重要说明

缩放地图(无论通过地图 UI 还是以编程方式)都需要 Map.HasZoomEnabled 属性为 true。 要详细了解此属性,请参阅禁用缩放

自定义地图行为

可以通过设置 Map 的某些属性和处理 MapClicked 事件来自定义其行为。

注意

可以通过创建地图自定义呈现器来实现其他地图行为自定义。 有关详细信息,请参阅自定义 Xamarin.Forms 地图

显示交通情况数据

Map 类定义类型为 boolTrafficEnabled 属性。 默认情况下,此属性为 false,指示不会在地图上覆盖流量数据。 当此属性设置为 true 时,交通数据将叠加在地图上。 下面的示例显示了如何设置该属性:

<maps:Map TrafficEnabled="true" />

等效 C# 代码如下:

Map map = new Map
{
    TrafficEnabled = true
};

禁用滚动

Map 类定义类型为 boolHasScrollEnabled 属性。 默认情况下,此属性为 true,指示允许地图滚动。 当此属性设置为 false 时,地图将不会滚动。 下面的示例显示了如何设置该属性:

<maps:Map HasScrollEnabled="false" />

等效 C# 代码如下:

Map map = new Map
{
    HasScrollEnabled = false
};

禁用缩放

Map 类定义类型为 boolHasZoomEnabled 属性。 默认情况下,此属性为 true,指示可以在地图上执行缩放。 当此属性设置为 false 时,将无法缩放地图。 下面的示例显示了如何设置该属性:

<maps:Map HasZoomEnabled="false" />

等效 C# 代码如下:

Map map = new Map
{
    HasZoomEnabled = false
};

显示用户位置

Map 类定义类型为 boolIsShowingUser 属性。 默认情况下,此属性为 false,指示地图未显示用户的当前位置。 当此属性设置为 true 时,地图将显示用户的当前位置。 下面的示例显示了如何设置该属性:

<maps:Map IsShowingUser="true" />

等效 C# 代码如下:

Map map = new Map
{
    IsShowingUser = true
};

重要

在 iOS、Android 和通用 Windows 平台上,访问用户的位置需要事先向应用程序授予位置权限。 有关详细信息,请参阅平台配置

在布局更改时保持地图区域

Map 类定义类型为 boolMoveToLastRegionOnLayoutChange 属性。 默认情况下,此属性为 true,指示当发生布局更改(例如设备旋转)时,显示的地图区域将从其当前区域移动到其以前设置的区域。 如果此属性设置为 false,当布局发生更改时,显示的地图区域将保持居中。 下面的示例显示了如何设置该属性:

<maps:Map MoveToLastRegionOnLayoutChange="false" />

等效 C# 代码如下:

Map map = new Map
{
    MoveToLastRegionOnLayoutChange = false
};

地图单击数

Map 类定义在点击地图时触发的 MapClicked 事件。 事件附带的 MapClickedEventArgs 对象包含一个名为 Position 的属性,类型为 Position。 触发此事件时,Position 属性将设置为点击的地图位置。 有关 Position 结构的信息,请参阅地图位置和距离

以下代码示例显示 MapClicked 事件的事件处理程序:

void OnMapClicked(object sender, MapClickedEventArgs e)
{
    System.Diagnostics.Debug.WriteLine($"MapClick: {e.Position.Latitude}, {e.Position.Longitude}");
}

在此示例中,OnMapClicked 事件处理程序输出表示点击地图位置的纬度和经度。 事件处理程序可以注册到 MapClicked 事件,如下所示:

<maps:Map MapClicked="OnMapClicked" />

等效 C# 代码如下:

Map map = new Map();
map.MapClicked += OnMapClicked;