コンテンツにスキップ

Polyline

ポリラインは、複数の地理的ポイントを接続する線分のシーケンスです。ルート、パス、境界、または地図上の線形フィーチャーに一般的に使用されます。

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

@Composable
fun Polyline(
points: List<GeoPoint>,
id: String? = null,
strokeColor: Color = Color.Black,
strokeWidth: Dp = 1.dp,
geodesic: Boolean = false,
extra: Serializable? = null
)
  • points: 線分を定義する地理座標のリスト(List<GeoPoint>
  • id: ポリラインのオプションの一意識別子(String?
  • strokeColor: 線の色(デフォルト: Color.Black
  • strokeWidth: 線の幅(デフォルト: 1.dp
  • geodesic: 測地線(地球の曲率に沿う)を描画するかどうか(デフォルト: false
  • extra: ポリラインに付加する追加データ(Serializable?
@Composable
fun BasicPolylineExample(modifier: Modifier = Modifier) {
val center = GeoPointImpl.fromLatLong(53.566853, 9.988269)
// 地図の作成
val camera =
MapCameraPositionImpl(
position = center,
zoom = 14.0,
)
val mapViewState =
rememberMapboxMapViewState(
cameraPosition = camera,
)
val routePoints = listOf(
GeoPointImpl.fromLatLong(53.561011,9.989448),
GeoPointImpl.fromLatLong(53.563203,9.985800),
GeoPointImpl.fromLatLong(53.564579,9.983525),
GeoPointImpl.fromLatLong(53.566873,9.980822),
GeoPointImpl.fromLatLong(53.567943,9.982152),
GeoPointImpl.fromLatLong(53.570186,9.984813),
GeoPointImpl.fromLatLong(53.572683,9.986143),
GeoPointImpl.fromLatLong(53.572658,9.988675),
GeoPointImpl.fromLatLong(53.572709,9.990392)
)
// MapView を GoogleMapView、HereMapView などのマップ地図SDKに置き換えてください
MapboxMapView(
state = mapViewState,
modifier = modifier,
) {
Polyline(
points = routePoints,
strokeColor = Color.Blue,
strokeWidth = 9.dp
)
}
}

実行結果

ウェイポイントマーカー付きのインタラクティブな Polyline

Section titled “ウェイポイントマーカー付きのインタラクティブな Polyline”
@Composable
fun InteractivePolylineExample() {
val center = GeoPointImpl.fromLatLong(53.566853, 9.988269)
// 地図の作成
val camera =
MapCameraPositionImpl(
position = center,
zoom = 14.0,
)
val mapViewState =
rememberMapboxMapViewState(
cameraPosition = camera,
)
var waypoints by remember {
mutableStateOf(
listOf(
GeoPointImpl.fromLatLong(53.561011, 9.989448),
GeoPointImpl.fromLatLong(53.563203, 9.985800),
GeoPointImpl.fromLatLong(53.564579, 9.983525),
GeoPointImpl.fromLatLong(53.566873, 9.980822),
GeoPointImpl.fromLatLong(53.567943, 9.982152),
GeoPointImpl.fromLatLong(53.570186, 9.984813),
GeoPointImpl.fromLatLong(53.572683, 9.986143),
GeoPointImpl.fromLatLong(53.572658, 9.988675),
GeoPointImpl.fromLatLong(53.572709, 9.990392)
)
)
}
val polylineState = PolylineState(
points = waypoints,
strokeColor = Color.Blue,
strokeWidth = 4.dp,
geodesic = true
)
val waypointMarkers = waypoints.mapIndexed { index, point ->
MarkerState(
id = "marker-${index}",
position = point,
icon = DefaultIcon(
label = "${index + 1}",
scale = 0.7f,
),
draggable = true,
extra = index
)
}
MapboxMapView(
state = mapViewState,
onMarkerDrag = { markerState ->
val markerIndex = markerState.extra as Int
markerIndex?.let { index ->
waypoints = waypoints.toMutableList().apply {
if (index < size) {
set(index, markerState.position as GeoPointImpl)
}
}
}
}
) {
// ポリラインを描画
Polyline(polylineState)
// ウェイポイントマーカーを描画
waypointMarkers.forEach { marker ->
Marker(marker)
}
}
}
@Composable
fun DynamicPolylineExample() {
val center = GeoPointImpl.fromLatLong(53.566853, 9.988269)
// 地図の作成
val camera =
MapCameraPositionImpl(
position = center,
zoom = 14.0,
)
val mapViewState =
rememberMapLibreMapViewState(
cameraPosition = camera,
)
var points by remember { mutableStateOf<List<GeoPoint>>(emptyList()) }
var isDrawing by remember { mutableStateOf(false) }
Column(modifier = modifier) {
Row {
Button(
onClick = { isDrawing = !isDrawing }
) {
Text(if (isDrawing) "Stop Drawing" else "Start Drawing")
}
Button(
onClick = { points = emptyList() }
) {
Text("Clear")
}
}
// MapView を GoogleMapView、MapboxMapView などのマップ地図SDKに置き換えてください
MapLibreMapView(
state = mapViewState,
onMapClick = { geoPoint ->
if (isDrawing) {
points = points + geoPoint
}
}
) {
if (points.isNotEmpty()) {
Polyline(
points = points,
strokeColor = Color.Red,
strokeWidth = 3.dp
)
// 各ポイントにマーカーを追加
points.forEachIndexed { index, point ->
Marker(
position = point,
icon = DefaultIcon(
fillColor = if (index == 0) Color.Green
else if (index == points.size - 1) Color.Red
else Color.Blue,
label = "${index + 1}",
scale = 0.8f
)
)
}
}
}
}
}
@Composable
fun GeodesicPolylineExample(modifier: Modifier = Modifier) {
val center = GeoPointImpl.fromLatLong(36.0, -160.0)
val camera = MapCameraPositionImpl(
position = center,
zoom = 4.0,
)
val mapViewState = rememberMapboxMapViewState(
cameraPosition = camera,
)
var markers by remember {
mutableStateOf<List<MarkerState>>(emptyList())
}
// MapView を GoogleMapView、MapboxMapView などのマップ地図SDKに置き換えてください
MapboxMapView(
state = mapViewState,
modifier = modifier,
onPolylineClick = { polylineEvent ->
markers = markers + MarkerState(
icon = DefaultIcon(
fillColor = polylineEvent.state.strokeColor,
),
position = polylineEvent.clicked,
)
}
) {
val longDistancePoints = listOf(
GeoPointImpl.fromLatLong(35.548852, 139.784086), // 羽田空港
GeoPointImpl.fromLatLong(37.615223, -122.389979) // サンフランシスコ空港
)
// 標準線(地図投影上で直線)
Polyline(
id = "straight-line",
points = longDistancePoints,
strokeColor = Color.Red,
strokeWidth = 3.dp,
geodesic = false,
extra = "Straight line"
)
// 測地線(地球の曲率に沿う)
Polyline(
id = "geodesic-line",
points = longDistancePoints,
strokeColor = Color.Blue,
strokeWidth = 3.dp,
geodesic = true,
extra = "Geodesic line"
)
markers.forEach { markerState ->
Marker(markerState)
}
}
}

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

// MapView を GoogleMapView、MapboxMapView などのマップ地図SDKに置き換えてください
MapView(
state = mapViewState,
onPolylineClick = { polylineEvent ->
val polyline = polylineEvent.state
val clickPoint = polylineEvent.clicked
println("Polyline clicked:")
println(" Points count: ${polyline.points.size}")
println(" Click location: ${clickPoint}")
println(" Extra data: ${polyline.extra}")
}
) {
Polyline(
points = routePoints,
strokeColor = Color.Blue,
strokeWidth = 4.dp,
extra = "Interactive route"
)
}
// 細い線
Polyline(
points = points,
strokeWidth = 1.dp
)
// 中程度の線
Polyline(
points = points,
strokeWidth = 3.dp
)
// 太い線
Polyline(
points = points,
strokeWidth = 8.dp
)
// ソリッドカラー
Polyline(points = points, strokeColor = Color.Red)
Polyline(points = points, strokeColor = Color.Blue)
Polyline(points = points, strokeColor = Color.Green)
// 半透明
Polyline(points = points, strokeColor = Color.Red.copy(alpha = 0.7f))
// カスタムカラー
Polyline(
points = points,
strokeColor = Color(0xFF4CAF50) // マテリアルグリーン
)
  1. ポイント密度: 詳細とパフォーマンスのバランスを取る - ポイントが多すぎるとレンダリングが遅くなる可能性があります
  2. 測地線: 長距離ルートには測地線を使用して正確なパスを表示してください
  3. 視覚的階層: 異なる色と幅を使用して、さまざまな種類のルートを区別してください
  4. インタラクティブなフィードバック: ポリラインがクリック可能な場合は、視覚的なフィードバックを提供してください
  5. パフォーマンス: 特定のズームレベルで複雑なポリラインの簡略化されたジオメトリの使用を検討してください
  6. 色のコントラスト: ポリラインの色が地図の背景に対して目立つことを確認してください
  7. ルートの方向: ルートに沿って方向を示すために矢印やマーカーを追加することを検討してください
  8. 状態管理: ポリラインデータを効率的に保存し、必要に応じてリアクティブに更新してください