GroundImageState(画像オーバーレイ状態)
GroundImageState は、地図上のグラウンドイメージオーバーレイの構成と動作を管理します。地理的境界、画像リソース、不透明度設定のためのリアクティブなプロパティを提供します。
コンストラクタ
Section titled “コンストラクタ”GroundImageState( bounds: GeoRectBounds, image: Drawable, opacity: Float = 1.0f, id: String? = null, extra: Serializable? = null)基本プロパティ
Section titled “基本プロパティ”id: String: 一意の識別子(指定されていない場合は自動生成)bounds: GeoRectBounds: 画像配置のための地理的矩形境界image: Drawable: 表示する描画可能画像opacity: Float: 透明度レベル(0.0 = 透明、1.0 = 不透明)extra: Serializable?: グラウンドイメージに付加される追加データ
fun fingerPrint(): GroundImageFingerPrint // 変更検知fun asFlow(): Flow<GroundImageFingerPrint> // リアクティブ更新基本的なグラウンドイメージ
Section titled “基本的なグラウンドイメージ”@Composablefun BasicGroundImageExample() { val context = LocalContext.current val drawable = AppCompatResources.getDrawable(context, R.drawable.overlay_image)
val groundImageState = drawable?.let { GroundImageState( bounds = GeoRectBounds( southwest = GeoPointImpl.fromLatLong(37.7649, -122.4294), northeast = GeoPointImpl.fromLatLong(37.7849, -122.4094) ), image = it, opacity = 0.7f, extra = "Base overlay" ) }
// MapViewは、GoogleMapView、MapboxMapViewなど、選択した地図SDKーに置き換えてくださいMapView(state = mapViewState) { groundImageState?.let { state -> GroundImage(state) } }}インタラクティブなグラウンドイメージ
Section titled “インタラクティブなグラウンドイメージ”@Composablefun InteractiveGroundImageExample() { var groundImageState by remember { mutableStateOf<GroundImageState?>(null) } var opacity by remember { mutableStateOf(0.7f) }
val context = LocalContext.current
LaunchedEffect(opacity) { val drawable = AppCompatResources.getDrawable(context, R.drawable.map_overlay) drawable?.let { groundImageState = GroundImageState( bounds = GeoRectBounds( southwest = GeoPointImpl.fromLatLong(37.7649, -122.4294), northeast = GeoPointImpl.fromLatLong(37.7849, -122.4094) ), image = it, opacity = opacity, extra = "Interactive overlay" ) } }
Column { Slider( value = opacity, onValueChange = { opacity = it }, valueRange = 0f..1f, modifier = Modifier.padding(16.dp) ) Text("Opacity: ${(opacity * 100).toInt()}%")
// MapViewは、GoogleMapView、MapboxMapViewなど、選択した地図SDKーに置き換えてくださいMapView( state = mapViewState, onGroundImageClick = { event -> println("Ground image clicked at: ${event.clicked}") } ) { groundImageState?.let { state -> GroundImage(state) } } }}複数のオーバーレイ
Section titled “複数のオーバーレイ”@Composablefun MultiLayerGroundImageExample() { val context = LocalContext.current
val overlayStates = remember { listOf( Triple(R.drawable.base_layer, 0.3f, "Base satellite"), Triple(R.drawable.weather_layer, 0.6f, "Weather data"), Triple(R.drawable.traffic_layer, 0.8f, "Traffic info") ).mapNotNull { (resId, opacity, description) -> AppCompatResources.getDrawable(context, resId)?.let { drawable -> GroundImageState( bounds = GeoRectBounds( southwest = GeoPointImpl.fromLatLong(37.7649, -122.4294), northeast = GeoPointImpl.fromLatLong(37.7849, -122.4094) ), image = drawable, opacity = opacity, extra = description ) } } }
// MapViewは、GoogleMapView、MapboxMapViewなど、選択した地図SDKーに置き換えてくださいMapView(state = mapViewState) { overlayStates.forEach { state -> GroundImage(state) } }}@Composablefun DynamicBoundsExample() { var southwest by remember { mutableStateOf(GeoPointImpl.fromLatLong(37.7649, -122.4294)) } var northeast by remember { mutableStateOf(GeoPointImpl.fromLatLong(37.7849, -122.4094)) }
val context = LocalContext.current val drawable = AppCompatResources.getDrawable(context, R.drawable.floor_plan)
val groundImageState = drawable?.let { GroundImageState( bounds = GeoRectBounds(southwest = southwest, northeast = northeast), image = it, opacity = 0.8f, extra = "Floor plan" ) }
// MapViewは、GoogleMapView、MapboxMapViewなど、選択した地図SDKーに置き換えてくださいMapView( state = mapViewState, onMarkerDrag = { markerState -> when (markerState.extra) { "SW" -> southwest = markerState.position "NE" -> northeast = markerState.position } } ) { groundImageState?.let { state -> GroundImage(state) }
// 角のマーカー Marker( position = southwest, icon = DefaultIcon(fillColor = Color.Green, label = "SW"), draggable = true, extra = "SW" )
Marker( position = northeast, icon = DefaultIcon(fillColor = Color.Red, label = "NE"), draggable = true, extra = "NE" ) }}アニメーション付きオーバーレイ
Section titled “アニメーション付きオーバーレイ”@Composablefun AnimatedGroundImageExample() { var isAnimating by remember { mutableStateOf(false) } var opacity by remember { mutableStateOf(0.5f) }
LaunchedEffect(isAnimating) { if (isAnimating) { while (isAnimating) { delay(100) opacity = (sin(System.currentTimeMillis() / 1000.0).toFloat() + 1f) / 2f } } }
val context = LocalContext.current val drawable = AppCompatResources.getDrawable(context, R.drawable.animated_overlay)
val groundImageState = drawable?.let { GroundImageState( bounds = GeoRectBounds( southwest = GeoPointImpl.fromLatLong(37.7649, -122.4294), northeast = GeoPointImpl.fromLatLong(37.7849, -122.4094) ), image = it, opacity = opacity, extra = "Animated overlay" ) }
Column { Button(onClick = { isAnimating = !isAnimating }) { Text(if (isAnimating) "Stop" else "Animate") }
// MapViewは、GoogleMapView、MapboxMapViewなど、選択した地図SDKーに置き換えてくださいMapView(state = mapViewState) { groundImageState?.let { state -> GroundImage(state) } } }}イベント処理
Section titled “イベント処理”グラウンドイメージイベントは状態とクリック位置の両方を提供します:
data class GroundImageEvent( val state: GroundImageState, val clicked: GeoPointImpl?)
typealias OnGroundImageEventHandler = (GroundImageEvent) -> Unit画像リソース管理
Section titled “画像リソース管理”異なるソースからの読み込み
Section titled “異なるソースからの読み込み”// リソースからval drawable = AppCompatResources.getDrawable(context, R.drawable.overlay)
// アセットからval inputStream = context.assets.open("overlays/map.png")val drawable = Drawable.createFromStream(inputStream, null)
// ネットワークから(画像読み込みライブラリを使用)// Coil、Glide、Picassoなどのライブラリをネットワーク画像に使用してくださいベストプラクティス
Section titled “ベストプラクティス”- 画像サイズ: パフォーマンスのために画像解像度を最適化してください
- 境界の精度: 正確な地理的配置を確保してください
- 不透明度: 視認性のために適切な透明度を使用してください
- リソース管理: 描画可能リソースをキャッシュして再利用してください
- レイヤー順序: 複数のオーバーレイの描画順序を考慮してください
- パフォーマンス: 同時グラウンドイメージの数を制限してください
- エラー処理: 画像の読み込みに失敗した場合を処理してください