2-2位置服务-用户位置在地图上的显示

Mapbox 地图 SDK for Android 的位置组件使您的应用能够观察、响应和显示用户的位置。

在您能够在地图上显示用户的位置之前,用户必须授权您的应用访问他们的位置。有关更多细节,请参见前面的权限处理部分。

位置组件

为了在地图上可视化用户的位置,您应该启用位置组件。有多种方法可以启用位置:

  1. 在您的 MapView XML 组件中直接使用属性 mapbox_locationComponentEnabled:

    <com.mapbox.maps.MapView
      android:id="@+id/mapView"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      app:mapbox_locationComponentEnabled="true"
      app:mapbox_locationComponentPuckBearing="heading" />
    
  2. 通过调用位置组件的 enabled 方法进行编程:

    // Android View
    // Jetpack Compose
    setContentView(mapView)
    with(mapView) {
        location.locationPuck = createDefault2DPuck(withBearing = true)
        location.enabled = true
        location.puckBearing = PuckBearing.COURSE
        location.puckBearingEnabled = true
        viewport.transitionTo(
            targetState = viewport.makeFollowPuckViewportState(),
            transition = viewport.makeImmediateViewportTransition()
        )
    }
    

位置组件利用 Maps SDK 中的两个专用图层来显示 2D 设备位置图标(使用图层 ID LOCATION_INDICATOR_LAYER)或 3D 模型(使用图层 ID MODEL_LAYER)。这些图层显示在地图内部,而不是作为 Android 视图覆盖在地图上。Mapbox 地图样式中的图层使您能够精确控制如何在地图上显示设备的位置。

默认情况下,Android 的 Maps SDK 提供一个带有蓝点和白圈的二维位置图标。

示例

显示用户在地图上的位置

使用默认位置图标在地图上显示用户的位置。

图标样式选项

有几种选项可以自定义位置图标的外观。您可以在 LocationComponentSettings 中查看完整列表。

您可以直接使用 LocationComponentPlugin 更改设置。例如,默认情况下脉冲效果是禁用的,但您可以通过将 true 传递给 pulsingEnabled 属性来启用该效果。

// Android View
class LocationComponentActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val mapView = MapView(this)
        setContentView(mapView)
        with(mapView) {
            location.enabled = true
            location.pulsingEnabled = true
        }
    }
}
使用自定义图像

您还可以通过使用自定义图像 Drawable 来进一步自定义图标,以在地图上显示用户的位置。您可以通过 XML 属性或通过 LocationPuck 类以编程方式设置自定义位置图标样式。

以下是使用样式 XML 属性自定义位置图标外观的示例:

<com.mapbox.maps.MapView
    android:id="@+id/mapView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:mapbox_locationComponentEnabled="true"
    app:mapbox_locationComponentLocationPuck="location_puck_2_d"
    app:mapbox_locationComponentLocationPuckLocationPuck2DTopImage="@drawable/custom_user_icon"
    app:mapbox_locationComponentLocationPuckLocationPuck2DBearingImage="@drawable/custom_user_arrow"
    app:mapbox_locationComponentLocationPuckLocationPuck2DShadowImage="@drawable/custom_user_puck_icon"
    tools:context=".examples.LocationComponentActivity" />

以下是使用 LocationPuck 类以编程方式自定义位置图标外观的示例。创建一个 LocationPuck2DLocationPuck3D 对象,并通过 LocationComponentPlugin#locationPuck 方法设置它。以下示例还根据地图的缩放级别使用 scaleExpression 指定图标的大小。

// Android View
mapView.location.locationPuck = LocationPuck2D(
    topImage = ImageHolder.from(R.drawable.mapbox_user_icon), // ImageHolder 也接受 Bitmap
    bearingImage = ImageHolder.from(R.drawable.mapbox_user_bearing_icon),
    shadowImage = ImageHolder.from(R.drawable.mapbox_user_stroke_icon),
    scaleExpression = interpolate {
        linear()
        zoom()
        stop {
            literal(0.0)
            literal(0.6)
        }
        stop {
            literal(20.0)
            literal(1.0)
        }
    }.toJson()
)

您可以使用 createDefault2DPuck 函数恢复默认的二维图标。

设置图标朝向源

用户位置可以使用设备的朝向或设备的航向进行追踪。此选项在 LocationComponentSettings 中。

// 示例
mapView.location.puckBearing = PuckBearing.HEADING
mapView.location.puckBearing = PuckBearing.COURSE
位置跟踪

要使相机跟随位置图标,您可以使用 ViewportPlugin,它在 mapView.viewport 可用。

ViewportPlugin 主要用于在地图上跟踪对象,但也可以通过自定义状态和过渡进行扩展。

视口状态

ViewportState 根据实现特定的规则生成相机更新(例如:跟踪动态位置数据源或显示预定义区域的静态概览)。

SDK 提供了两种 ViewportState 实现,均可以从 ViewportPlugin 实例化:

  • viewport.makeFollowPuckViewportState(options):此状态将地图相机与位置图标同步。
  • viewport.makeOverviewViewportState(options):此状态使相机显示用户提供的几何形状。

除了使用这些内置实现,您还可以创建自己的实现并与 ViewportPlugin 一起使用。

视口过渡

ViewportTransition 定义如何过渡到目标 ViewportState

SDK 还提供了两种 ViewportTransition 实现,均可以从 ViewportPlugin 实例化:

  • viewport.makeDefaultViewportTransition(options):默认视口过渡使用动画将相机移动到目标状态。
  • viewport.makeImmediateViewportTransition():立即视口过渡会将相机一次性移动到目标状态而不使用动画。

除了使用这些内置实现,您还可以创建自己的实现并与 ViewportPlugin 一起使用。

示例
// Android View
val viewportPlugin = mapView.viewport
// 过渡到 followPuckViewportState,使用默认过渡
val followPuckViewportState: FollowPuckViewportState = viewportPlugin.makeFollowPuckViewportState(
    FollowPuckViewportStateOptions.Builder()
        .bearing(FollowPuckViewportStateBearing.Constant(0.0))
        .padding(EdgeInsets(200.0 * resources.displayMetrics.density, 0.0, 0.0, 0.0))
        .build()
)
viewportPlugin.transitionTo(followPuckViewportState) { success ->
    // 过渡完成,带有指示过渡是否成功的标志
}

// Android View
// 过渡到 overviewViewportState,使用立即过渡
val overviewViewportState: OverviewViewportState = viewportPlugin.makeOverviewViewportState(
    OverviewViewportStateOptions.Builder()
        .geometry(routePoints)
        .padding(EdgeInsets(100.0, 100.0, 100.0, 100.0))
        .build()
)
val immediateTransition = viewportPlugin.makeImmediateViewportTransition()
viewportPlugin.transitionTo(overviewViewportState, immediateTransition) { success ->
    // 过渡完成,带有指示过渡是否成功的标志
}
位置提供者

LocationProvider 是 Mapbox Maps SDK 的一个接口,用于向 LocationComponentPlugin 提供位置更新。您可以通过调用 getLocationProvider() 访问位置组件中使用的当前位置提供者。

您可以注册自己的 LocationConsumer 来处理与地图上渲染位置图标相同的位置。如果您需要访问设备的原始位置,请参见“访问设备位置”。

使用 Google 的融合位置提供者

Maps SDK 还预先编译了对 Google 的融合位置提供者的支持。如果您的目标设备支持 Google Play 服务,请将 Google Play 位置服务依赖项添加到您的项目中,Maps SDK 将自动在您的应用中使用 Google 的融合位置提供者:

implementation("com.google.android.gms:play-services-location:21.0.1")
使用自定义位置提供者

您还可以提供自己的 LocationProvider 以与 LocationComponentPlugin 一起使用。使用 setLocationProvider(locationProvider: LocationProvider) API 来替换默认实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值