GeoJSON レイヤー
android-geojson-layer は、地図実装に依存せず GeoJSON データを表示するための独立モジュールです。
タイルベースのラスターレイヤーとして描画するため、Google Maps、Mapbox、MapLibre、ArcGIS、HERE など、任意の地図 SDK で使用できます。
インストール
dependencies { implementation(platform("com.mapconductor:mapconductor-bom:1.1.7")) implementation("com.mapconductor:core") implementation("com.mapconductor:geojson-layer")
// 使用する地図 SDK を選択 implementation("com.mapconductor:for-googlemaps")}基本的な使い方
GeoJSONFeature のリストを作成し、任意の MapView の content ブロック内で GeoJSONLayer に渡します。
val layerState = remember { GeoJSONLayerState() }val features = remember { listOf( GeoJSONFeature( geometry = GeoJSONGeometry.Point(longitude = 139.76, latitude = 35.68), properties = mapOf("name" to "東京駅"), ), GeoJSONFeature( geometry = GeoJSONGeometry.LineString( coordinates = listOf( LonLat(139.76, 35.68), LonLat(139.77, 35.69), ) ), ), GeoJSONFeature( geometry = GeoJSONGeometry.Polygon( rings = listOf( listOf( LonLat(139.75, 35.67), LonLat(139.77, 35.67), LonLat(139.77, 35.69), LonLat(139.75, 35.69), LonLat(139.75, 35.67), // 始点と終点を同じにする ) ) ), ), )}
MapView(...) { GeoJSONLayer( state = layerState, features = features, )}API リファレンス
GeoJSONLayer Composable
@Composablefun MapViewScope.GeoJSONLayer( state: GeoJSONLayerState = remember { GeoJSONLayerState() }, features: List<GeoJSONFeature> = emptyList(), tileSize: Int = 512, disableTileServerCache: Boolean = false, content: @Composable () -> Unit = {},)state: レイヤーの表示状態、スタイル、クリック処理を管理するGeoJSONLayerStateです。features: 静的または一括データとして描画するGeoJSONFeatureのリストです。tileSize: ラスターレイヤーのタイルサイズです。disableTileServerCache: タイルサーバー側のキャッシュを無効化するかどうかを指定します。content:GeoJSONFeatureStateなど、Compose の状態と連動するフィーチャを配置するブロックです。
GeoJSONLayerState
class GeoJSONLayerState( opacity: Float = 1.0f, strokeColor: Int = Color.argb(255, 30, 136, 229), // 青系 fillColor: Int = Color.argb(128, 30, 136, 229), // 半透明青系 strokeWidth: Float = 2f, pointRadius: Float = 8f, visible: Boolean = true, minZoom: Int = 0, maxZoom: Int = 22, val onClick: ((feature: GeoJSONFeature, position: GeoPoint) -> Unit)? = null,) { fun processClick(geoPoint: GeoPoint): Boolean}processClick(geoPoint) は、マップのクリックハンドラから呼び出してフィーチャのヒットテストを実行します。対象フィーチャが見つかると onClick を呼び出し、true を返します。
GeoJSONLayerState パラメータ
opacity: レイヤー全体の不透明度です。strokeColor: 線やポリゴン外周のデフォルト色です。fillColor: ポリゴン塗りつぶしのデフォルト色です。strokeWidth: 線幅のデフォルト値です。pointRadius: Point / MultiPoint の半径のデフォルト値です。visible: レイヤーを表示するかどうかを指定します。minZoom: レイヤーを表示する最小ズームレベルです。maxZoom: レイヤーを表示する最大ズームレベルです。onClick: ヒットテストでフィーチャが見つかったときに呼び出されるコールバックです。
GeoJSONFeature
data class GeoJSONFeature( val id: String? = null, val geometry: GeoJSONGeometry, val properties: Map<String, Any?> = emptyMap(), val strokeColor: Int? = null, // nullの場合は GeoJSONLayerState のデフォルトを使用 val fillColor: Int? = null, val strokeWidth: Float? = null, val pointRadius: Float? = null, val visible: Boolean = true,)GeoJSONFeature は静的データや一括ロードしたデータに適しています。大量データを描画する場合は、GeoJSONLayer の features パラメータに渡す方法が効率的です。
ジオメトリタイプ
sealed class GeoJSONGeometry { data class Point(val longitude: Double, val latitude: Double) data class MultiPoint(val points: List<Point>) data class LineString(val coordinates: List<LonLat>) data class MultiLineString(val lines: List<List<LonLat>>) data class Polygon(val rings: List<List<LonLat>>) // rings[0]=外周, rings[1..]=穴 data class MultiPolygon(val polygons: List<List<List<LonLat>>>) data class GeometryCollection(val geometries: List<GeoJSONGeometry>) object Empty}
data class LonLat(val longitude: Double, val latitude: Double)Polygon の rings[0] は外周、rings[1..] は穴として扱われます。座標指定には LonLat(longitude, latitude) を使用します。
大容量ファイルのパース
GeoJSONParser は、InputStream 全体を一括でパースする方法と、1フィーチャずつ処理するストリームパースを提供します。
object GeoJSONParser { // InputStream 全体をパースして List<GeoJSONFeature> を返す fun parseStream(inputStream: InputStream): List<GeoJSONFeature>
// 1フィーチャずつコールバック — 大容量ファイル(10MB+)向け fun streamParse(inputStream: InputStream, onFeature: (GeoJSONFeature) -> Unit)}// 大容量 GeoJSON ファイルのパースval features = GeoJSONParser.parseStream(assets.open("data.geojson"))
// 1フィーチャずつ処理(メモリ効率が良い)GeoJSONParser.streamParse(assets.open("large-data.geojson")) { feature -> // 1件ずつ処理}クリックイベント / ヒットテスト
GeoJSONLayerState.processClick() を MapView の onMapClick から呼び出すと、タップ位置にある GeoJSON フィーチャを検索できます。
val layerState = remember { GeoJSONLayerState( onClick = { feature, position -> println("フィーチャが見つかった場合: ${feature.properties["name"]}") } )}
MapView( onMapClick = { geoPoint -> // タップ位置のフィーチャを検索 val handled = layerState.processClick(geoPoint) if (!handled) { // GeoJSON フィーチャ以外のタップ処理 } }) { GeoJSONLayer(state = layerState, features = features)}リアクティブフィーチャ(GeoJSONFeatureState)
GeoJSONFeatureState は GeoJSONLayer の content ブロック内に配置する、Compose の状態更新に対応したフィーチャです。頻繁に変化する少数のフィーチャには便利ですが、大量データには features パラメータで GeoJSONFeature を渡す方法を推奨します。
val featureState = remember { GeoJSONFeatureState( geometry = GeoJSONGeometry.Point(longitude = 139.76, latitude = 35.68), properties = mapOf("name" to "動的ポイント"), )}
// 動的に変化するフィーチャ(Compose state)LaunchedEffect(userLocation) { featureState.geometry = GeoJSONGeometry.Point( longitude = userLocation.longitude, latitude = userLocation.latitude, )}
MapView(...) { GeoJSONLayer(state = layerState) { // content ブロック内に GeoJSONFeatureState を配置 GeoJSONFeatureCompose(state = featureState) }}スタイルカスタマイズ
レイヤー全体のデフォルトスタイルは GeoJSONLayerState で指定できます。個別の GeoJSONFeature に strokeColor や fillColor を設定した場合は、そのフィーチャ固有のスタイルが優先されます。
val layerState = remember { GeoJSONLayerState( strokeColor = Color.rgb(255, 87, 34), // オレンジ fillColor = Color.argb(100, 255, 87, 34), // 半透明オレンジ strokeWidth = 3f, pointRadius = 12f, opacity = 0.9f, )}