显示模式与视角
本指南:控制地图相机位置、缩放、2D/3D、地图全览、跟车模式与自动缩放。
功能介绍
CameraController 负责控制地图相机的位置、朝向、缩放、2D/3D 渲染模式,以及 跟车模式 与 自动缩放(Auto-Zoom)。典型场景包括浏览地图、路线全览和导航跟车。
初始化时可通过 MapViewInitConfig.autoZoomLevel 设置自动缩放视野;运行时可通过 setEnableAutoZoom 和 enableFollowVehicleMode(..., useAutoZoom) 控制是否启用自动缩放。工作机制与产品行为见 Auto Zoom。
获取入口:
| val camera = mapView.getCameraController() ?: return
|
核心接口一览
| 分类 |
接口 / 属性 |
说明 |
| 区域适配 |
showRegion(region) / showRegion(region, marginRect) / showRegion(region, pixelMargins) / showRegion(region, percentageMargins) |
将相机移动至能完整显示指定区域 |
| 区域适配 |
showRegionForRoutes(regionForRoutesInfo) |
适配一条或多条路线到指定屏幕矩形 |
| 区域适配 |
showRegionForModelInstance(regionForModelInstance) |
适配 Shape.Collection 模型实例 |
| 位姿控制 |
position |
读写相机位置、姿态、缩放与过渡时间 |
| 缩放控制 |
zoomLevelRange |
限定允许的缩放范围 |
| 渲染模式 |
renderMode |
当前 2D / 3D 渲染模式 |
| 跟车模式 |
enableFollowVehicleMode(mode, useAutoZoom) |
开启跟车 |
| 跟车模式 |
disableFollowVehicle() |
关闭跟车 |
| 跟车模式 |
vehicleFollowMode |
当前跟车模式(null 表示未跟车) |
| 自动缩放 |
setEnableAutoZoom(enableAutozoom) |
全局开关自动缩放 |
| 坐标转换 |
worldToViewport(location) |
经纬度 → 屏幕坐标 |
| 坐标转换 |
viewportToWorld(point) |
屏幕坐标 → 经纬度 |
| 事件监听 |
MapView.setOnCurrentRenderModeChangedListener / setOnTargetRenderModeChangedListener |
监听 2D/3D 切换 |
接口详细说明
1. showRegion — 显示指定经纬度区域
showRegion 提供 4 个重载,用于将相机调整到刚好能包含指定 Camera.Region(经纬度包围盒)的位置。其中重载二直接传入视口上的目标矩形;重载三、四通过像素或百分比边距换算为矩形后再适配,便于避让 HMI 面板。
重载一:无边距
| fun showRegion(region: Camera.Region?)
|
| 参数 |
类型 |
说明 |
region |
Camera.Region? |
经纬度包围盒(含 northLatitude / southLatitude / eastLongitude / westLongitude);为 null 时不生效 |
重载二:Rect 指定视口矩形
| fun showRegion(region: Camera.Region?, marginRect: Rect)
|
| 参数 |
类型 |
说明 |
region |
Camera.Region? |
经纬度包围盒 |
marginRect |
android.graphics.Rect |
地图 surface 上的目标矩形(像素)。相机会平移、缩放,使 region 完整落在该矩形内;含义与 RegionForRoutesInfo.rect 一致 |
与边距重载的区别:marginRect 使用标准 Rect(left, top, right, bottom) 表示一块矩形区域(须满足 right > left、bottom > top),不是“左/上/右/下四条内边距”。需要按像素或百分比从四边留白时,请用 Margins.Pixels / Margins.Percentages(实现里会先换算成 Rect 再调用引擎)。marginRect.isEmpty 时本次调用会被忽略。与 CameraController、MapEngineViewDelegate 说明一致:经纬度区域将显示在该矩形内(inside the view rect)。
重载三:像素边距
| fun showRegion(region: Camera.Region?, pixelMargins: Margins.Pixels)
|
| 参数 |
类型 |
说明 |
region |
Camera.Region? |
经纬度包围盒 |
pixelMargins |
Margins.Pixels |
像素边距;lrPixels 左右,tbPixels 上下 |
重载四:百分比边距
| fun showRegion(region: Camera.Region?, percentageMargins: Margins.Percentages)
|
| 参数 |
类型 |
说明 |
region |
Camera.Region? |
经纬度包围盒 |
percentageMargins |
Margins.Percentages |
百分比边距;lrPercentage / tbPercentage 取值 0.0 ~ 1.0 |
构造 Camera.Region:
| val region = Camera.Region().apply {
extend(37.405, -121.978) // 经纬度点 1
extend(37.412, -121.962) // 经纬度点 2
// 多次 extend 后即可自动算出包围盒
}
if (region.valid()) camera.showRegion(region)
|
示例代码(四个重载对照):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | import android.graphics.Rect
import com.telenav.map.api.Margins
// 1) 无边距:整幅地图 surface 作为目标区域
camera.showRegion(region)
// 2) Rect:在地图 surface 上指定一块目标矩形(left, top, right, bottom)
val w = mapView.width
val h = mapView.height
val targetRect = Rect(w / 2 - 300, h / 2 - 300, w - 300, h - 300)
camera.showRegion(region, targetRect)
// 3) 像素边距:对称留白(lr = 左右各留、tb = 上下各留,由 SDK 换算为 Rect)
camera.showRegion(region, Margins.Pixels(32.0, 64.0))
// 4) 百分比边距:相对当前视图尺寸(例如左右、上下各 0.20)
camera.showRegion(region, Margins.Percentages(0.20, 0.20))
|
更多 showRegion 场景示例
以下片段只突出相机调用;业务里通常在「路线全览 / 看 POI 范围」前关闭跟车并视情况关闭 Auto-Zoom,且应在 region != null 且 region.valid() 为真时再调用。
由路线 ID 列表得到包围盒并适配(无边距)
| val routeIds: List<String> = // 已添加到 mapView 的路线 id
val region = mapView.routesController().region(routeIds)
mapView.cameraController()?.showRegion(region)
|
路线包围盒 + 百分比边距(导航全览等场景常用)
| val region = mapView.routesController().region(routeIds)
mapView.cameraController()
?.showRegion(region, Margins.Percentages(0.20, 0.20))
|
为顶部面板留出固定高度:用 Rect 把有效地图区设为「去掉顶栏后的矩形」
| val w = mapView.width
val h = mapView.height
val topBarPx = 200
if (w > 0 && h > topBarPx) {
mapView.cameraController()?.showRegion(region, Rect(0, topBarPx, w, h))
}
|
根据多个经纬度点构造 Camera.Region 再带像素边距适配
| val region = Camera.Region().apply {
// points 可为 List<LatLon> 等含 latitude/longitude 的点集合
points.forEach { extend(it.latitude, it.longitude) }
}
if (region.valid()) {
mapView.cameraController()?.showRegion(region, Margins.Pixels(48.0, 80.0))
}
|
2. showRegionForRoutes — 适配路线区域
将一条或多条路线在指定屏幕矩形内进行 Pan + Zoom 适配(不旋转)。常用于"路线全览"场景。
效果示意:

| fun showRegionForRoutes(
regionForRoutesInfo: RegionForRoutesInfo
)
|
| 参数 |
类型 |
说明 |
regionForRoutesInfo |
RegionForRoutesInfo |
路线适配参数集合,详见下表 |
RegionForRoutesInfo 字段:
| 字段 |
类型 |
默认 |
说明 |
routes |
List<String> |
— |
需要纳入视野的路线 ID 列表 |
rect |
android.graphics.Rect |
— |
屏幕目标矩形:left = x,top = y,width() = 宽度,height() = 高度 |
gridAligned |
Boolean |
false |
true:以 2D 北朝上方式适配(矩形严格对齐);false:保持当前相机姿态,矩形覆盖区域的外接圆 |
showFullRouteOverview |
Boolean |
false |
true:包含已驶过的路线段;false:仅显示剩余部分 |
includeCVP |
Boolean |
false |
true:强制将 CVP 纳入视野 |
nearestLegMode |
Boolean |
false |
true:仅显示到第一个 waypoint 的路段 |
annotations |
List<Annotation>? |
null |
需一同纳入视野的额外 Annotation |
注意:该方法不考虑 skew,调用前需将 LayoutController 的 horizontalOffset 与 verticalOffset 置为 0。
示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | import android.graphics.Rect
val regionInfo = RegionForRoutesInfo(
routes = listOf(routeId),
rect = Rect(0, 0, mapView.width, mapView.height),
gridAligned = false,
showFullRouteOverview = true,
includeCVP = true,
nearestLegMode = false,
annotations = null
)
// 重要:先归零 layout offset
mapView.getLayoutController()?.apply {
setHorizontalOffset(0f)
setVerticalOffset(0f)
}
val ok = camera.showRegionForRoutes(regionInfo)
|
更多 showRegionForRoutes 示例
多条路线同一视口内全览
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | val ids = listOf(primaryRouteId, alternateRouteId)
val info = RegionForRoutesInfo(
routes = ids,
rect = Rect(0, 0, mapView.width, mapView.height),
gridAligned = false,
showFullRouteOverview = true,
includeCVP = false,
nearestLegMode = false,
annotations = null
)
mapView.getLayoutController()?.apply {
setHorizontalOffset(0f)
setVerticalOffset(0f)
}
camera.showRegionForRoutes(info)
|
只在地图下半区域做路线全览(rect 与 showRegion 的 Rect 语义相同)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | val w = mapView.width
val h = mapView.height
val info = RegionForRoutesInfo(
routes = listOf(routeId),
rect = Rect(0, h / 4, w, h),
gridAligned = true,
showFullRouteOverview = false,
includeCVP = true,
nearestLegMode = false,
annotations = null
)
mapView.getLayoutController()?.apply {
setHorizontalOffset(0f)
setVerticalOffset(0f)
}
camera.showRegionForRoutes(info)
|
与 Annotation 一并纳入视野
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | val info = RegionForRoutesInfo(
routes = listOf(routeId),
rect = Rect(0, 0, mapView.width, mapView.height),
gridAligned = false,
showFullRouteOverview = true,
includeCVP = true,
nearestLegMode = false,
annotations = listOf(poiAnnotation, incidentAnnotation)
)
mapView.getLayoutController()?.apply {
setHorizontalOffset(0f)
setVerticalOffset(0f)
}
camera.showRegionForRoutes(info)
|
将某个 Shape.Collection 模型实例适配到指定屏幕矩形内。
| fun showRegionForModelInstance(
regionForModelInstance: RegionForModelInstance
)
|
| 参数 |
类型 |
说明 |
regionForModelInstance |
RegionForModelInstance |
模型实例适配参数 |
RegionForModelInstance 字段:
| 字段 |
类型 |
说明 |
id |
ShapesController.Id |
由 ShapesController.add(...) 返回的形状集合唯一 ID |
rect |
android.graphics.Rect |
屏幕目标矩形 |
gridAligned |
Boolean |
同 RegionForRoutesInfo.gridAligned |
示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | import android.graphics.Rect
val shapesController = mapView.getShapesController() ?: return
val shapeId: ShapesController.Id = shapesController.add(shapeCollection)
val info = RegionForModelInstance(
id = shapeId,
rect = Rect(0, 0, mapView.width, mapView.height),
gridAligned = true
)
// 与 showRegionForRoutes 相同:当前实现不考虑 skew,建议先归零 layout offset
mapView.getLayoutController()?.apply {
setHorizontalOffset(0f)
setVerticalOffset(0f)
}
camera.showRegionForModelInstance(info)
|
在指定屏幕矩形内看高亮多边形(gridAligned = false 时按外接圆适配,见 API 说明)
1
2
3
4
5
6
7
8
9
10
11
12 | val w = mapView.width
val h = mapView.height
val info = RegionForModelInstance(
id = shapeId,
rect = Rect(w / 4, h / 4, w * 3 / 4, h * 3 / 4),
gridAligned = false
)
mapView.getLayoutController()?.apply {
setHorizontalOffset(0f)
setVerticalOffset(0f)
}
mapView.cameraController()?.showRegionForModelInstance(info)
|
北朝上 2D 下严格按模型轴对齐包围盒适配(gridAligned = true)
| val info = RegionForModelInstance(
id = shapeId,
rect = Rect(0, 0, mapView.width, mapView.height),
gridAligned = true
)
mapView.getLayoutController()?.apply {
setHorizontalOffset(0f)
setVerticalOffset(0f)
}
mapView.cameraController()?.showRegionForModelInstance(info)
|
4. position — 相机位姿(读写)
通过 Camera.Position 一次性读取或设置相机的位置、姿态、缩放与过渡动画。
| 接口属性 |
类型 |
说明 |
position(get) |
Camera.Position |
读取当前相机位置 |
position(set) |
Camera.Position |
写入目标相机位置(不需要的字段保持 null 即可) |
Camera.Position.Builder 字段:
| 方法 |
参数类型 |
取值 |
说明 |
setLocation(location) |
Location? |
— |
相机中心位置(经纬度) |
setBearing(bearing) |
Float |
0f ~ 360f |
方位角,0° 正北,180° 正南,逆时针增大 |
setTilt(tilt) |
Float |
0f ~ 60f |
倾角,0° 为完全俯视(2D 视角) |
setZoomLevel(zoomLevel) |
Float |
0f ~ 17f |
缩放级别,0 为最低(大陆级),17 为最高(街道级) |
setZoomTransitionTime(transitionTime) |
Float |
秒 |
缩放过渡动画时间 |
示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13 | // 平滑飞向某个位置
val target = Location("").apply {
latitude = 37.7749
longitude = -122.4194
}
camera.position = Camera.Position.Builder()
.setLocation(target)
.setZoomLevel(14f)
.setBearing(0f)
.setTilt(0f)
.setZoomTransitionTime(0.6f)
.build()
|
5. renderMode — 2D / 3D 渲染模式
| 接口属性 |
类型 |
说明 |
renderMode(get) |
Camera.RenderMode |
读取当前渲染模式 |
renderMode(set) |
Camera.RenderMode |
设置目标渲染模式 |
Camera.RenderMode 枚举:
| 值 |
说明 |
M2D |
二维模式 |
M3D |
三维模式(默认 tilt ≈ -39°) |
示例代码:
| // 切到 3D
camera.renderMode = Camera.RenderMode.M3D
// 切回 2D
camera.renderMode = Camera.RenderMode.M2D
|
6. zoomLevelRange — 限定缩放范围
| 接口属性 |
类型 |
说明 |
zoomLevelRange |
android.util.Range<Float> |
允许的缩放上下限,外部手势缩放与代码设置都将被夹紧到此范围内 |
示例代码:
| camera.zoomLevelRange = Range(0f, 18f)
|
7. enableFollowVehicleMode — 启用跟车模式
| fun enableFollowVehicleMode(
mode: Camera.FollowVehicleMode,
useAutoZoom: Boolean
)
|
| 参数 |
类型 |
说明 |
mode |
Camera.FollowVehicleMode |
跟车朝向模式:HeadingUp(车头朝上)/ NorthUp(北朝上)/ Static(不调整朝向/tilt) |
useAutoZoom |
Boolean |
跟车过程中是否自动调整缩放;在 M3D 下会同时调整 tilt 突出关键路口 |
示例代码:
| // 导航中:车头朝上 + Auto-Zoom
camera.enableFollowVehicleMode(
Camera.FollowVehicleMode.HeadingUp,
useAutoZoom = true
)
// 路线全览时:北朝上、关闭自动缩放
camera.enableFollowVehicleMode(
Camera.FollowVehicleMode.NorthUp,
useAutoZoom = false
)
|
8. disableFollowVehicle — 关闭跟车
| 接口方法 |
说明 |
disableFollowVehicle() |
退出跟车模式,相机不再跟随 CVP 移动;调用后 vehicleFollowMode 变为 null |
示例代码:
| camera.disableFollowVehicle()
|
9. setEnableAutoZoom — 全局开关自动缩放
| fun setEnableAutoZoom(
enableAutozoom: Boolean
)
|
| 参数 |
类型 |
说明 |
enableAutozoom |
Boolean |
true 启用自动缩放;false 关闭。不改变跟车模式本身 |
示例代码:
| camera.setEnableAutoZoom(true)
|
10. vehicleFollowMode — 读取当前跟车模式
| 接口属性 |
类型 |
说明 |
vehicleFollowMode |
Camera.FollowVehicleMode? |
当前跟车模式;为 null 表示未启用跟车 |
示例代码:
| val isFollowing = camera.vehicleFollowMode != null
when (camera.vehicleFollowMode) {
Camera.FollowVehicleMode.HeadingUp -> { /* 车头朝上 */ }
Camera.FollowVehicleMode.NorthUp -> { /* 北朝上 */ }
Camera.FollowVehicleMode.Static -> { /* 静态跟车 */ }
null -> { /* 未跟车 */ }
}
|
11. worldToViewport — 经纬度 → 屏幕坐标
| fun worldToViewport(
location: android.location.Location
)
|
| 参数 |
类型 |
说明 |
location |
android.location.Location |
要转换的地理位置(含经纬度) |
示例代码:
| val loc = Location("").apply {
latitude = 37.7749
longitude = -122.4194
}
val screen: PointF? = camera.worldToViewport(loc)
screen?.let { drawOverlayAt(it.x, it.y) }
|
12. viewportToWorld — 屏幕坐标 → 经纬度
| fun viewportToWorld(
point: android.graphics.PointF
)
|
| 参数 |
类型 |
说明 |
point |
android.graphics.PointF |
MapView 上的屏幕坐标(像素) |
示例代码:
| mapView.setOnTouchListener { _, ev ->
if (ev.action == MotionEvent.ACTION_UP) {
val world = camera.viewportToWorld(PointF(ev.x, ev.y))
world?.let { onMapTapped(it.latitude, it.longitude) }
}
false
}
|
13. 渲染模式监听
通过 MapView 注册监听 2D/3D 模式切换:
| 接口 |
回调 |
参数类型 |
说明 |
CurrentRenderModeChangeListener |
onCurrentRenderingModeChanged(currentRenderMode) |
Camera.RenderMode |
当前渲染模式 已经 切换完成 |
TargetRenderModeChangeListener |
onTargetRenderingModeChanged(targetRenderMode) |
Camera.RenderMode |
渲染模式 即将 切换的目标值 |
示例代码:
| mapView.setOnCurrentRenderModeChangedListener { current ->
Log.d(TAG, "render mode changed to $current")
}
mapView.setOnTargetRenderModeChangedListener { target ->
Log.d(TAG, "render mode is changing to $target")
}
|
14. AutoZoomLevel(初始化期)
在 MapViewInitConfig 或 ClusterMapViewParams 中通过 autoZoomLevel 设置默认自动缩放视野:
| 枚举值 |
说明 |
DEFAULT |
默认视野 |
MEDIUM |
中等视野 |
FAR |
较远视野 |
VERY_FAR |
很远视野 |
MAXIMUM |
最大视野 |
值越大,自动缩放展示的范围越广。
示例代码:
| val config = MapViewInitConfig(
context = context,
listener = readyListener,
autoZoomLevel = AutoZoomLevel.FAR
)
mapView.initialize(config)
|
AutoZoomController 由引擎内部驱动,不在 MapView 上直接暴露;集成方通过 autoZoomLevel 与 CameraController.setEnableAutoZoom 控制即可。
注意事项
- 所有
CameraController 接口必须在 onReady 之后调用。
- 跟车模式下若
renderMode 为 M3D,且 useAutoZoom = true,自动缩放可能同时调整 tilt。
showRegionForRoutes / showRegionForModelInstance 当前不考虑 skew,调用前需将 LayoutController 的 horizontal / vertical offset 置为 0。
worldToViewport 在目标点不在可视区域时可能返回 null,调用方需做空值处理。
showAutoZoomDebugInfo 等调试 API 非对外集成接口,请勿依赖。
相关指南