コンテンツにスキップ

Circle

円は、カスタマイズ可能な半径、ストローク、塗りつぶしプロパティを持つ円形のオーバーレイで、地図上に描画できます。エリア、範囲、またはゾーンを表現するのに便利です。

円の数が少ない場合、オプションを直接指定すると簡単に扱えます。 id を指定すると、不要な Recomposition を抑えることができます。

@Composable
fun Circle(
center: GeoPoint,
radiusMeters: Double,
geodesic: Boolean = false,
strokeColor: Color = Color.Red,
strokeWidth: Dp = 2.dp,
fillColor: Color = Color.White.copy(alpha = 0.5f),
extra: Serializable? = null,
id: String? = null
)
  • center: 円の地理的中心点(GeoPoint
  • radiusMeters: 半径(メートル単位、Double
  • geodesic: 測地線(地球の曲率に沿う)を描画するかどうか(デフォルト: false
  • strokeColor: 円の境界線の色(デフォルト: Color.Red
  • strokeWidth: 境界線の幅(デフォルト: 2.dp
  • fillColor: 円の内部の塗りつぶし色(デフォルト: 半透明の白)
  • extra: 円に付加する追加データ(Serializable?
  • id: 円の一意識別子(String?
// MapView を GoogleMapView、MapboxMapView などのマップ地図SDKに置き換えてください
MapView(state = mapViewState) {
// ソリッドな赤い円
Circle(
center = GeoPointImpl.fromLatLong(37.7749, -122.4194),
radiusMeters = 500.0,
strokeColor = Color.Red,
strokeWidth = 3.dp,
fillColor = Color.Red.copy(alpha = 0.2f),
extra = "Red zone"
)
// 太い境界線の青い円
Circle(
center = GeoPointImpl.fromLatLong(37.7849, -122.4194),
radiusMeters = 750.0,
strokeColor = Color.Blue,
strokeWidth = 5.dp,
fillColor = Color.Transparent,
extra = "Blue boundary"
)
// パターン付きの緑の円
Circle(
center = GeoPointImpl.fromLatLong(37.7649, -122.4194),
radiusMeters = 300.0,
strokeColor = Color.Green,
strokeWidth = 2.dp,
fillColor = Color.Green.copy(alpha = 0.4f),
extra = "Green area"
)
}

マーカーを使ったインタラクティブな Circle

Section titled “マーカーを使ったインタラクティブな Circle”

ドラッグ可能なマーカーを使ったインタラクティブな円の作成方法を示します。

@Composable
fun InteractiveCircleExample() {
val circleCenter = GeoPointImpl.fromLatLong(21.382314, -157.933097)
// calculatePositionAtDistance は MapConductor が提供するユーティリティ関数
// circleCenter から 1000m 離れて、時計回りに 180 度回転した位置を計算
val edgeMarkerPosition = calculatePositionAtDistance(
center = circleCenter,
distanceMeters = 1000.0,
bearingDegrees = 180.0,
)
// 円のエッジに設置するマーカー
val edgeMarkerState = MarkerState(
id = "edge_marker",
position = edgeMarkerPosition,
icon =
DefaultIcon(
fillColor = Color.Green,
strokeColor = Color.White,
label = "Drag me",
),
draggable = true,
)
// CircleState の作成
val circleState = remember {
CircleState(
id = "circle",
center = circleCenter,
radiusMeters = 1000.0,
)
}
// 円の半径を更新することで、Recomposition により円を再描画
// このときに circleState.id を指定していないと、新しい円が作成されてしまう
val onMarkerMove: OnMarkerEventHandler = { markerState ->
circleState.radiusMeters = computeDistanceBetween(circleCenter, markerState.position)
}
LaunchedEffect(Unit) {
onMarkerMove(edgeMarkerState)
}
// 地図の作成
val camera = MapCameraPositionImpl(
position = circleCenter,
zoom = 13.0,
)
val mapViewState = rememberMapLibreMapViewState(
cameraPosition = camera,
)
MapLibreMapView(
modifier = modifier,
state = mapViewState,
onMarkerDragStart = onMarkerMove,
onMarkerDrag = onMarkerMove,
onMarkerDragEnd = onMarkerMove,
) {
// Circle
Circle(circleState)
// Center marker (not draggable)
Marker(
position = circleCenter,
)
// Edge marker (draggable)
Marker(edgeMarkerState)
}
}
@Composable
fun DynamicCircleExample() {
var circleRadius by remember { mutableStateOf(500.0) }
var circleColor by remember { mutableStateOf(Color.Blue) }
Column {
// コントロール
Slider(
value = circleRadius.toFloat(),
onValueChange = { circleRadius = it.toDouble() },
valueRange = 100f..2000f,
modifier = Modifier.padding(16.dp)
)
Row {
Button(onClick = { circleColor = Color.Red }) {
Text("Red")
}
Button(onClick = { circleColor = Color.Blue }) {
Text("Blue")
}
Button(onClick = { circleColor = Color.Green }) {
Text("Green")
}
}
// 動的な円を持つマップ
// MapView を GoogleMapView、MapboxMapView などのマップ地図SDKに置き換えてください
MapView(state = mapViewState) {
Circle(
id = "circle",
center = GeoPointImpl.fromLatLong(37.7749, -122.4194),
radiusMeters = circleRadius,
strokeColor = circleColor,
fillColor = circleColor.copy(alpha = 0.3f)
)
// 中心マーカー
Marker(
id = "center-marker",
position = GeoPointImpl.fromLatLong(37.7749, -122.4194),
icon = DefaultIcon(
fillColor = circleColor,
label = "${circleRadius.toInt()}m"
)
)
}
}
}

Circle のインタラクションは、マップ地図SDKコンポーネントで処理されます:

// MapView を GoogleMapView、MapboxMapView などのマップ地図SDKに置き換えてください
MapView(
state = mapViewState,
onCircleClick = { circleEvent ->
val circle = circleEvent.state
val clickPoint = circleEvent.clicked
println("Circle clicked:")
println(" Center: ${circle.center}")
println(" Radius: ${circle.radiusMeters}m")
println(" Click point: ${clickPoint}")
println(" Extra data: ${circle.extra}")
}
) {
Circle(
center = GeoPointImpl.fromLatLong(37.7749, -122.4194),
radiusMeters = 1000.0,
clickable = true,
extra = "Clickable circle"
)
}
// 細い境界線
Circle(
center = center,
radiusMeters = 500.0,
strokeColor = Color.Black,
strokeWidth = 1.dp
)
// 太い境界線
Circle(
center = center,
radiusMeters = 500.0,
strokeColor = Color.Black,
strokeWidth = 5.dp
)
// 境界線なし
Circle(
center = center,
radiusMeters = 500.0,
strokeColor = Color.Transparent,
strokeWidth = 0.dp
)
// ソリッドな塗りつぶし
Circle(
center = center,
radiusMeters = 500.0,
fillColor = Color.Red
)
// 半透明の塗りつぶし
Circle(
center = center,
radiusMeters = 500.0,
fillColor = Color.Red.copy(alpha = 0.5f)
)
// 塗りつぶしなし
Circle(
center = center,
radiusMeters = 500.0,
fillColor = Color.Transparent
)

id プロパティは円に一意の識別子を提供し、効率的な追跡と管理を可能にします:

// 一意の ID を持つ円の作成
val circles = listOf(
Circle(
center = GeoPointImpl.fromLatLong(37.7749, -122.4194),
radiusMeters = 1000.0,
strokeColor = Color.Red,
fillColor = Color.Red.copy(alpha = 0.3f),
id = "zone-a"
),
Circle(
center = GeoPointImpl.fromLatLong(37.7849, -122.4094),
radiusMeters = 1500.0,
strokeColor = Color.Blue,
fillColor = Color.Blue.copy(alpha = 0.3f),
id = "zone-b"
)
)
// イベント処理での ID の使用
MapView(
state = mapViewState,
onCircleClick = { circleEvent ->
when (circleEvent.state.id) {
"zone-a" -> handleZoneA()
"zone-b" -> handleZoneB()
else -> handleUnknownZone()
}
}
) {
circles.forEach { circle -> Circle(circle) }
}