2-4位置服务示例

下面的代码给出了位置服务的代码示例(https://github.com/mapbox/mapbox-maps-android/blob/v11.7.1/app/src/main/java/com/mapbox/maps/testapp/examples/LocationComponentActivity.kt)

对代码进行一个详细的解析:

这段代码是一个 Android 应用程序的 Activity,主要用于展示如何使用 Mapbox 地图 SDK 显示用户的位置以及处理位置组件。下面逐句详细解释这段代码:

kotlin 复制代码
package com.mapbox.maps.testapp.examples
  • 指定该文件的包名为 com.mapbox.maps.testapp.examples,这是一个 Kotlin 文件,通常是用于组织代码。
kotlin 复制代码
import android.graphics.Color
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
  • 导入所需的 Android 类和 Mapbox 相关库。这些类将用于设置 UI 组件、处理事件和显示消息等。
kotlin 复制代码
import com.mapbox.maps.CameraOptions
import com.mapbox.maps.ImageHolder
import com.mapbox.maps.MapboxExperimental
import com.mapbox.maps.Style
import com.mapbox.maps.extension.style.expressions.dsl.generated.interpolate
import com.mapbox.maps.extension.style.layers.properties.generated.Anchor
import com.mapbox.maps.extension.style.layers.properties.generated.ProjectionName
import com.mapbox.maps.extension.style.light.generated.flatLight
import com.mapbox.maps.extension.style.light.setLight
import com.mapbox.maps.extension.style.projection.generated.getProjection
import com.mapbox.maps.extension.style.projection.generated.projection
import com.mapbox.maps.extension.style.projection.generated.setProjection
import com.mapbox.maps.plugin.LocationPuck2D
import com.mapbox.maps.plugin.LocationPuck3D
import com.mapbox.maps.plugin.PuckBearing
import com.mapbox.maps.plugin.gestures.gestures
import com.mapbox.maps.plugin.locationcomponent.DefaultLocationProvider
import com.mapbox.maps.plugin.locationcomponent.OnIndicatorPositionChangedListener
import com.mapbox.maps.plugin.locationcomponent.createDefault2DPuck
import com.mapbox.maps.plugin.locationcomponent.location
import com.mapbox.maps.testapp.R
import com.mapbox.maps.testapp.databinding.ActivityLocationComponentBinding
import com.mapbox.maps.testapp.utils.LocationPermissionHelper
import java.lang.ref.WeakReference
  • 导入 Mapbox SDK 的各个组件和扩展功能,包括样式、光照、投影、位置组件等。同时导入了数据绑定和权限处理工具。
kotlin 复制代码
@OptIn(MapboxExperimental::class)
  • 指示使用 Mapbox 的实验性功能。这通常用于在 SDK 中处于实验阶段的功能,以避免警告。
kotlin 复制代码
class LocationComponentActivity : AppCompatActivity() {
  • 定义 LocationComponentActivity 类,继承自 AppCompatActivity,表示这是一个 Activity。
kotlin 复制代码
private var lastStyleUri = Style.DARK
  • 声明一个变量 lastStyleUri,用于存储最后使用的地图样式 URI,默认为 Style.DARK
kotlin 复制代码
private lateinit var locationPermissionHelper: LocationPermissionHelper
  • 声明一个 LocationPermissionHelper 类型的变量 locationPermissionHelper,用于处理位置权限请求。
kotlin 复制代码
private val onIndicatorPositionChangedListener = OnIndicatorPositionChangedListener {
  • 创建一个 OnIndicatorPositionChangedListener 的匿名实现,用于响应位置指示器位置变化事件。
kotlin 复制代码
// Jump to the current indicator position
binding.mapView.mapboxMap.setCamera(CameraOptions.Builder().center(it).build())
  • 当位置指示器位置发生变化时,更新地图相机的位置以跟随指示器。
kotlin 复制代码
// Set the gestures plugin's focal point to the current indicator location.
binding.mapView.gestures.focalPoint = binding.mapView.mapboxMap.pixelForCoordinate(it)
  • 设置手势插件的焦点为当前位置,以便于地图手势交互。
kotlin 复制代码
private lateinit var binding: ActivityLocationComponentBinding
  • 声明一个 ActivityLocationComponentBinding 类型的变量 binding,用于绑定布局文件。
kotlin 复制代码
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
  • 重写 onCreate 方法,这是 Activity 创建时调用的方法。
kotlin 复制代码
binding = ActivityLocationComponentBinding.inflate(layoutInflater)
  • 使用数据绑定将布局文件 activity_location_component 绑定到 binding 变量。
kotlin 复制代码
setContentView(binding.root)
  • 将活动的内容视图设置为绑定的根视图。
kotlin 复制代码
locationPermissionHelper = LocationPermissionHelper(WeakReference(this))
  • 初始化 locationPermissionHelper,并传入 this 的弱引用,用于处理位置权限。
kotlin 复制代码
locationPermissionHelper.checkPermissions {
  • 调用 checkPermissions 方法检查位置权限。
kotlin 复制代码
binding.mapView.apply {
  • mapView 上进行操作,以下所有操作将在 mapView 内部进行。
kotlin 复制代码
mapboxMap.loadStyle(Style.STANDARD) {
  • 加载标准样式的地图。
kotlin 复制代码
it.setLight(
    flatLight {
  • 设置地图的光照效果,使用 flatLight 方法配置。
kotlin 复制代码
anchor(Anchor.MAP)
  • 设置光照的锚点为地图本身。
kotlin 复制代码
color(Color.YELLOW)
  • 设置光照的颜色为黄色。
kotlin 复制代码
position(
    radialCoordinate = 10.0,
    azimuthalAngle = 40.0,
    polarAngle = 50.0
)
  • 配置光照的位置,包括径向坐标、方位角和极角。
kotlin 复制代码
}
)
  • 关闭光照设置。
kotlin 复制代码
// Disable scroll gesture, since we are updating the camera position based on the indicator location.
gestures.scrollEnabled = false
  • 禁用地图的滚动手势,因为相机位置是根据指示器位置更新的。
kotlin 复制代码
gestures.addOnMapClickListener { point ->
  • 添加点击地图的监听器。
kotlin 复制代码
location.isLocatedAt(point) { isPuckLocatedAtPoint ->
  • 检查点击的点是否在位置指示器上。
kotlin 复制代码
if (isPuckLocatedAtPoint) {
    Toast.makeText(context, "Clicked on location puck", Toast.LENGTH_SHORT).show()
}
  • 如果点击了位置指示器,显示提示信息。
kotlin 复制代码
true
  • 返回 true 表示事件已处理。
kotlin 复制代码
}
  • 结束点击监听器。
kotlin 复制代码
gestures.addOnMapLongClickListener { point ->
  • 添加长按地图的监听器。
kotlin 复制代码
location.isLocatedAt(point) { isPuckLocatedAtPoint ->
  • 检查长按的点是否在位置指示器上。
kotlin 复制代码
if (isPuckLocatedAtPoint) {
    Toast.makeText(context, "Long-clicked on location puck", Toast.LENGTH_SHORT)
        .show()
}
  • 如果长按了位置指示器,显示提示信息。
kotlin 复制代码
true
  • 返回 true 表示事件已处理。
kotlin 复制代码
}
  • 结束长按监听器。
kotlin 复制代码
val locationProvider = location.getLocationProvider() as DefaultLocationProvider
  • 获取位置提供者,并将其转换为 DefaultLocationProvider 类型。
kotlin 复制代码
locationProvider.addOnCompassCalibrationListener {
    Toast.makeText(context, "Compass needs to be calibrated", Toast.LENGTH_LONG).show()
}
  • 添加指南针校准的监听器,若需要校准则显示提示信息。
kotlin 复制代码
}
  • 结束 mapView.apply 块。
kotlin 复制代码
}
  • 结束 checkPermissions 的 lambda。
kotlin 复制代码
override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.menu_location_component, menu)
    return true
}
  • 创建选项菜单,加载菜单布局。
kotlin 复制代码
override fun onOptionsItemSelected(item: MenuItem): Boolean {
    when (item.itemId) {
  • 处理菜单项的点击事件。
kotlin 复制代码
R.id.action_customise_location_puck_change -> {
    toggleCustomisedPuck()
    return true
}
  • 点击自定义位置指示器的菜单项时,调用 toggleCustomisedPuck() 方法。
kotlin 复制代码
R.id.action_map_style_change -> {
    toggleMapStyle()
    return true
}
  • 点击更改地图样式的菜单项时,调用 toggleMapStyle() 方法。
kotlin 复制代码
R.id.action_map_projection_change -> {
    toggleMapProjection()
    return true
}
  • 点击更改地图投影的菜单项时,调用 toggleMapProjection() 方法。
kotlin 复制代码
R.id.action_component_disable -> {
    binding.mapView.location.enabled = false
    return true
}
  • 点击禁用位置组件的菜单项时,禁用位置组件。
kotlin 复制代码
R.id.action_component_enabled -> {
    binding.mapView.location.enabled = true
    return true
}
  • 点击启用位置组件的菜单项时,启用位置组件。
kotlin 复制代码
R.id.action_show_bearing -> {
    binding.mapView.location.puckBearingEnabled = true
    if (binding.mapView.location.locationPuck is LocationPuck2D) {
        binding.mapView.location.locationPuck = createDefault2DPuck(withBearing

= true)
    }
    return true
}
  • 点击显示方位的菜单项时,启用方位显示。
kotlin 复制代码
R.id.action_hide_bearing -> {
    binding.mapView.location.puckBearingEnabled = false
    if (binding.mapView.location.locationPuck is LocationPuck2D) {
        binding.mapView.location.locationPuck = createDefault2DPuck(withBearing = false)
    }
    return true
}
  • 点击隐藏方位的菜单项时,禁用方位显示。
kotlin 复制代码
R.id.heading -> {
    binding.mapView.location.puckBearing = PuckBearing.HEADING
    item.isChecked = true
    return true
}
  • 点击"指向"菜单项时,将方位设置为指向。
kotlin 复制代码
R.id.course -> {
    binding.mapView.location.puckBearing = PuckBearing.COURSE
    item.isChecked = true
    return true
}
  • 点击"航向"菜单项时,将方位设置为航向。
kotlin 复制代码
R.id.location_no_animation -> {
    (binding.mapView.location.getLocationProvider() as DefaultLocationProvider).locationAnimatorOptions {
        duration = 0
    }
    item.isChecked = true
    return true
}
  • 点击不带动画的菜单项时,设置位置动画持续时间为0。
kotlin 复制代码
R.id.location_1s_animation -> {
    (binding.mapView.location.getLocationProvider() as DefaultLocationProvider).locationAnimatorOptions {
        duration = 1000
    }
    item.isChecked = true
    return true
}
  • 点击1秒动画的菜单项时,设置位置动画持续时间为1000毫秒。
kotlin 复制代码
R.id.location_300ms_animation -> {
    (binding.mapView.location.getLocationProvider() as DefaultLocationProvider).locationAnimatorOptions {
        duration = 300
    }
    item.isChecked = true
    return true
}
  • 点击300毫秒动画的菜单项时,设置位置动画持续时间为300毫秒。
kotlin 复制代码
R.id.action_accuracy_enabled -> {
    binding.mapView.location.showAccuracyRing = true
    item.isChecked = true
    return true
}
  • 点击启用准确度环的菜单项时,启用准确度显示。
kotlin 复制代码
R.id.action_accuracy_disable -> {
    binding.mapView.location.showAccuracyRing = false
    item.isChecked = true
    return true
}
  • 点击禁用准确度环的菜单项时,禁用准确度显示。
kotlin 复制代码
R.id.toggle_opacity -> {
    val location = binding.mapView.location
    location.locationPuck = location.locationPuck.run {
        when (this) {
            is LocationPuck3D -> copy(modelOpacity = if (modelOpacity == 1.0F) 0.5F else 1.0F)
            is LocationPuck2D -> copy(opacity = if (opacity == 1.0F) 0.5F else 1.0F)
        }
    }
    return true
}
  • 点击切换不透明度的菜单项时,切换位置指示器的不透明度。
kotlin 复制代码
R.id.move_to_bottom_slot -> {
    val location = binding.mapView.location
    location.slot = "bottom"
    return true
}
  • 点击移动到底部槽的菜单项时,将位置指示器移动到底部。
kotlin 复制代码
R.id.reset_slot -> {
    val location = binding.mapView.location
    location.slot = null
    return true
}
  • 点击重置槽的菜单项时,将位置指示器的槽设置为 null
kotlin 复制代码
else -> return super.onOptionsItemSelected(item)
  • 如果未处理的菜单项,则调用父类的 onOptionsItemSelected 方法。
kotlin 复制代码
private fun toggleCustomisedPuck() {
  • 定义一个私有方法 toggleCustomisedPuck,用于切换自定义位置指示器。
kotlin 复制代码
binding.mapView.location.let {
    when (it.locationPuck) {
  • 使用 let 扩展函数在 mapView.location 上执行操作。
kotlin 复制代码
is LocationPuck3D -> it.locationPuck = LocationPuck2D(
  • 如果当前位置指示器是 3D 类型,则将其切换为 2D 类型。
kotlin 复制代码
topImage = ImageHolder.from(com.mapbox.maps.plugin.locationcomponent.R.drawable.mapbox_user_icon),
bearingImage = ImageHolder.from(com.mapbox.maps.plugin.locationcomponent.R.drawable.mapbox_user_bearing_icon),
shadowImage = ImageHolder.from(com.mapbox.maps.plugin.locationcomponent.R.drawable.mapbox_user_stroke_icon),
scaleExpression = interpolate {
    linear()
    zoom()
    stop(0.0, 0.6)  // 第一个 stop,值为 0.0,对应输出值 0.6
    stop(20.0, 1.0) // 第二个 stop,值为 20.0,对应输出值 1.0
}.toJson()
  • 为 2D 位置指示器设置图标和缩放表达式。
kotlin 复制代码
is LocationPuck2D -> it.locationPuck = LocationPuck3D(
  • 如果当前位置指示器是 2D 类型,则将其切换为 3D 类型。
kotlin 复制代码
modelUri = "asset://sportcar.glb",
modelScale = listOf(10f, 10f, 10f),
modelTranslation = listOf(0.1f, 0.1f, 0.1f),
modelRotation = listOf(0.0f, 0.0f, 180.0f),
modelCastShadows = false,
modelReceiveShadows = false,
modelEmissiveStrength = 1.1f
  • 为 3D 位置指示器设置模型的 URI、缩放、平移、旋转、阴影设置等属性。
kotlin 复制代码
}
  • 结束 let 块。
kotlin 复制代码
private fun toggleMapStyle() {
  • 定义一个私有方法 toggleMapStyle,用于切换地图样式。
kotlin 复制代码
val styleUrl = if (lastStyleUri == Style.DARK) Style.LIGHT else Style.DARK
  • 检查当前样式,如果是黑暗模式,则切换到亮模式,反之亦然。
kotlin 复制代码
binding.mapView.mapboxMap.loadStyle(styleUrl) {
    lastStyleUri = styleUrl
}
  • 加载新的样式并更新 lastStyleUri
kotlin 复制代码
private fun toggleMapProjection() {
  • 定义一个私有方法 toggleMapProjection,用于切换地图投影。
kotlin 复制代码
binding.mapView.mapboxMap.getStyle { style ->
  • 获取当前地图样式。
kotlin 复制代码
style.setProjection(
    projection(
  • 设置新的投影。
kotlin 复制代码
when (style.getProjection()?.name) {
    ProjectionName.MERCATOR -> ProjectionName.GLOBE
    ProjectionName.GLOBE -> ProjectionName.MERCATOR
    else -> ProjectionName.GLOBE
}
  • 根据当前投影名称决定切换到哪种投影。
kotlin 复制代码
)
)
  • 结束投影设置。
kotlin 复制代码
override fun onRequestPermissionsResult(
    requestCode: Int,
    permissions: Array<String>,
    grantResults: IntArray
) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    locationPermissionHelper.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
  • 重写权限请求结果处理方法,将结果传递给 locationPermissionHelper
kotlin 复制代码
override fun onStart() {
    super.onStart()
    binding.mapView.location
      .addOnIndicatorPositionChangedListener(onIndicatorPositionChangedListener)
}
  • 在 Activity 启动时添加位置指示器位置变化的监听器。
kotlin 复制代码
override fun onStop() {
    super.onStop()
    binding.mapView.location
      .removeOnIndicatorPositionChangedListener(onIndicatorPositionChangedListener)
}
  • 在 Activity 停止时移除位置指示器位置变化的监听器。

整个代码段的主要功能是设置一个地图应用,显示用户位置并允许用户与地图进行交互,例如点击、长按和切换样式等功能。希望这个逐句解释能帮助你更好地理解代码的结构和功能!如果有任何具体部分需要进一步解释,请告诉我!

相关推荐
想取一个与众不同的名字好难3 分钟前
安卓TvView显示hdmi-in画面
android·tvview·hdmi-in
苏柘_level61 小时前
Android TV因未完成开机向导导致HOME按键失效的解决方案
android
就爱学编程2 小时前
重生之我在异世界学智力题(6)
android·java·数据库
9毫米的幻想3 小时前
【Linux系统】—— 权限的概念
android·linux·服务器·c语言·c++·学习
ROCKY_8173 小时前
Kotlin复习
android·开发语言·kotlin
江上清风山间明月4 小时前
Flutter编译Module was compiled with an incompatible version of Kotlin错误解决
android·flutter·kotlin·version·module·incompatible·compiled
小狗蛋ing4 小时前
Android通过okhttp下载文件(本文案例 下载mp4到本地,并更新到相册)
android·网络·okhttp·android下载文件
呆呆小雅5 小时前
C# 中的Task
android·数据库·c#
不是AI6 小时前
【安卓开发】【Android Studio】启动时报错“Unable to access Android SDK add-on list”
android·ide·android studio