コンテンツにスキップ

MapCameraPositionInterface(カメラ位置)

MapCameraPositionInterface は、カメラの視野位置、方向、および地図上の可視領域を表します。カメラがどこを見ているか、地図のどの程度が表示されるか、地図を表示する視点を定義します。

MapCameraPositionInterface インターフェース

Section titled “MapCameraPositionInterface インターフェース”
interface MapCameraPositionInterface {
val position: GeoPointInterface
val zoom: Double
val bearing: Double
val tilt: Double
val paddings: MapPaddingsInterface?
val visibleRegion: VisibleRegion?
}

メイン実装は不変のカメラ位置データを提供します:

data class MapCameraPosition(
override val position: GeoPoint,
override val zoom: Double = 0.0,
override val bearing: Double = 0.0,
override val tilt: Double = 0.0,
override val paddings: MapPaddingsInterface? = MapPaddings.Zeros,
override val visibleRegion: VisibleRegion? = null
) : MapCameraPositionInterface
  • position: GeoPointInterface: カメラの視野の地理的中心点
  • zoom: Double: ズームレベル(おおよそ Google Maps のスケールに従います)
  • bearing: Double: コンパスの方向(度数)(0 = 北、90 = 東)
  • tilt: Double: カメラの傾斜角度(度数)(0 = 真上から、90 = 水平)
  • paddings: MapPaddingsInterface?: 可視領域に影響するビューポートのパディング
  • visibleRegion: VisibleRegion?: (読み込み専用) 画面上で実際に表示される地理的境界
// 原点のデフォルトカメラ位置
val defaultPosition = MapCameraPosition.Default
// 基本的なカメラ位置
val sanFrancisco = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
zoom = 15
)
// 方位角と傾きを持つカメラ
val aerialView = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
zoom = 18,
bearing = 45, // Northeast direction
tilt = 60 // Angled view
)

MapConductor のズームレベルは、おおよそ Google Maps のスケールに従いますが、地図SDK間で若干異なる場合があります:

  • 0-2: 世界ビュー、大陸が表示される
  • 3-5: 国レベル
  • 6-9: 州/地域レベル
  • 10-12: 都市レベル
  • 13-15: 地区/近隣レベル
  • 16-18: ストリートレベル
  • 19-21: 建物レベル(高詳細)
// Different zoom levels for different use cases
val worldView = MapCameraPosition(
position = GeoPoint.fromLatLong(0, 0),
zoom = 2 // 大陸を表示
)
val cityView = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
zoom = 12 // 都市全体を表示
)
val streetView = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
zoom = 17 // 個別の通りを表示
)

方位角は中心点を中心に地図を回転させます:

// 北向き(デフォルト)
val northUp = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
bearing = 0
)
// 東向き
val eastUp = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
bearing = 90
)
// ルートの方位角に従う
val routeBearing = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
bearing = 135, // 南東
zoom = 18.0
)

傾きは 3D 表示角度を提供します:

// 真上からの眺め(デフォルト)
val topDown = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
tilt = 0
)
// 奥行きを出すための傾斜
val angled = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
tilt = 30,
zoom = 16
)
// ストリートレベルの最大傾斜
val streetLevel = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
tilt = 80,
bearing = 45,
zoom = 19
)

可視領域は、カメラ位置、ズームレベル、方位角、傾き、およびビューポートのパディングを考慮した後、画面上に表示される実際の地理的エリアを記述します。

data class VisibleRegion(
val bounds: GeoRectBounds, // 全体の境界矩形
val nearLeft: GeoPointInterface?, // 左下角(カメラに近い側)
val nearRight: GeoPointInterface?, // 右下角(カメラに近い側)
val farLeft: GeoPointInterface?, // 左上角(カメラから遠い側)
val farRight: GeoPointInterface? // 右上角(カメラから遠い側)
)
  • bounds: GeoRectBounds: 可視領域全体を包含する矩形の地理的境界。これは、すべての可視コンテンツを含む最小の境界矩形です。
  • nearLeft: GeoPointInterface?: 可視領域の左下角の地理的座標。「near」はカメラ位置に最も近い側を指します。
  • nearRight: GeoPointInterface?: 可視領域の右下角の地理的座標。
  • farLeft: GeoPointInterface?: 可視領域の左上角の地理的座標。「far」はカメラ位置から最も遠い側を指します。
  • farRight: GeoPointInterface?: 可視領域の右上角の地理的座標。
@Composable
fun VisibleRegionExample() {
val mapViewState = rememberMapboxMapViewState(
cameraPosition = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
zoom = 15.0
),
)
var visibleRegionInfo by remember { mutableStateOf<VisibleRegion?>(null) }
// MapView を GoogleMapView、MapboxMapView などの選択した地図SDKに置き換えてください
MapboxMapView(
state = mapViewState,
modifier = modifier,
onCameraMoveEnd = { cameraPosition ->
cameraPosition.visibleRegion?.let { visibleRegion ->
visibleRegionInfo = visibleRegion
}
},
) {
// 可視領域情報を表示
visibleRegionInfo?.let { region ->
// 境界をポリゴンとして表示
region.bounds.let { bounds ->
if (!bounds.isEmpty) {
val sw = bounds.southWest!!
val ne = bounds.northEast!!
Polygon(
points = listOf(
sw,
GeoPoint.fromLatLong(sw.latitude, ne.longitude),
ne,
GeoPoint.fromLatLong(ne.latitude, sw.longitude),
sw
),
strokeColor = Color.Blue,
strokeWidth = 2.dp,
fillColor = Color.Blue.copy(alpha = 0.1f)
)
}
}
}
}
}
@Composable
fun AnimatedCameraExample() {
val locations = listOf(
GeoPoint.fromLatLong(37.7749, -122.4194), // San Francisco
GeoPoint.fromLatLong(40.7128, -74.0060), // New York
GeoPoint.fromLatLong(51.5074, -0.1278) // London
)
val mapViewState = rememberHereMapViewState(
cameraPosition = MapCameraPosition(
position = locations[0],
zoom = 6.0
),
)
var currentIndex by remember { mutableStateOf(0) }
// 5秒ごとに次の位置にアニメーション
LaunchedEffect(Unit) {
while (true) {
delay(5000)
currentIndex = (currentIndex + 1) % locations.size
val targetPosition = MapCameraPosition(
position = locations[currentIndex],
zoom = 6.0,
bearing = 0.0,
tilt = 0.0
)
mapViewState.moveCameraTo(targetPosition, 1000)
}
}
// Replace MapView with your chosen map provider, such as GoogleMapView, MapboxMapView
HereMapView(
state = mapViewState,
modifier = modifier,
) {
// Add markers for each location
locations.forEachIndexed { index, location ->
Marker(
position = location,
icon = DefaultIcon(
fillColor = if (index == currentIndex) Color.Red else Color.Gray,
label = when (index) {
0 -> "SF"
1 -> "NYC"
2 -> "LON"
else -> "$index"
}
)
)
}
}
}

インタラクティブなカメラ制御

Section titled “インタラクティブなカメラ制御”
@Composable
fun CameraControlExample(modifier: Modifier = Modifier) {
val mapViewState = rememberMapLibreMapViewState(
mapDesign = MapLibreDesignType(
id = "debug-tiles",
styleJsonURL = "https://demotiles.maplibre.org/debug-tiles/style.json",
),
cameraPosition = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
zoom = 15.0
),
)
Column(
modifier = modifier,
) {
// Camera controls
Row {
Button(
onClick = {
val newZoom = mapViewState.cameraPosition.copy(
zoom = (mapViewState.cameraPosition.zoom + 1)
.coerceAtMost(21.0),
)
mapViewState.moveCameraTo(newZoom, 500)
}
) {
Text("Zoom In")
}
Button(
onClick = {
val newZoom = mapViewState.cameraPosition.copy(
zoom = (mapViewState.cameraPosition.zoom - 1)
.coerceAtMost(21.0),
)
mapViewState.moveCameraTo(newZoom, 500)
}
) {
Text("Zoom Out")
}
Button(
onClick = {
val newZoom = mapViewState.cameraPosition.copy(
bearing = (mapViewState.cameraPosition.bearing + 45) % 360,
)
mapViewState.moveCameraTo(newZoom, 500)
}
) {
Text("Rotate")
}
}
// Tilt slider
Slider(
value = mapViewState.cameraPosition.tilt.toFloat(),
onValueChange = { tilt ->
val newZoom = mapViewState.cameraPosition.copy(
tilt = tilt.toDouble(),
)
mapViewState.moveCameraTo(newZoom)
},
valueRange = 0f..80f
)
// MapView を GoogleMapView、MapboxMapView などの選択した地図SDKに置き換えてください
MapLibreMapView(
state = mapViewState,
) {
Marker(
position = mapViewState.cameraPosition.position,
icon = DefaultIcon(fillColor = Color.Red)
)
}
}
}