Skip to content

GeoJSON Layer

android-geojson-layer is a standalone module for displaying GeoJSON data independently of any map implementation. Because it is rendered as a tile-based raster layer, it can be used with any map SDK, including Google Maps, Mapbox, MapLibre, ArcGIS, and HERE.

Installation

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")
}

Basic Usage

Create a list of GeoJSONFeature objects and pass it to GeoJSONLayer inside the content block of any MapView.

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 Reference

GeoJSONLayer Composable

@Composable
fun MapViewScope.GeoJSONLayer(
state: GeoJSONLayerState = remember { GeoJSONLayerState() },
features: List<GeoJSONFeature> = emptyList(),
tileSize: Int = 512,
disableTileServerCache: Boolean = false,
content: @Composable () -> Unit = {},
)
  • state: The GeoJSONLayerState that manages the layer’s display state, styles, and click handling.
  • features: A list of GeoJSONFeature objects to render as static or batch data.
  • tileSize: The tile size for the raster layer.
  • disableTileServerCache: Specifies whether to disable server-side tile caching.
  • content: A block for placing features that work with Compose state, such as GeoJSONFeatureState.

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) is called from the map click handler to run feature hit testing. When a target feature is found, it calls onClick and returns true.

GeoJSONLayerState Parameters

  • opacity: The opacity of the entire layer.
  • strokeColor: The default color for lines and polygon outlines.
  • fillColor: The default polygon fill color.
  • strokeWidth: The default stroke width.
  • pointRadius: The default radius for Point / MultiPoint.
  • visible: Specifies whether the layer is visible.
  • minZoom: The minimum zoom level at which the layer is displayed.
  • maxZoom: The maximum zoom level at which the layer is displayed.
  • onClick: A callback invoked when hit testing finds a feature.

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 is suitable for static data or batch-loaded data. When rendering large datasets, it is more efficient to pass data to the features parameter of GeoJSONLayer.

Geometry Types

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)

For Polygon, rings[0] is treated as the outer ring and rings[1..] as holes. Use LonLat(longitude, latitude) to specify coordinates.

Parsing Large Files

GeoJSONParser provides both a method for parsing an entire InputStream at once and streaming parsing that processes one feature at a time.

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件ずつ処理
}

Click Events / Hit Testing

Calling GeoJSONLayerState.processClick() from the onMapClick handler of MapView lets you find GeoJSON features at the tapped position.

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)
}

Reactive Features (GeoJSONFeatureState)

GeoJSONFeatureState is a feature placed inside the content block of GeoJSONLayer that supports Compose state updates. It is useful for a small number of frequently changing features, but for large datasets, passing GeoJSONFeature objects through the features parameter is recommended.

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)
}
}

Style Customization

Default styles for the entire layer can be specified with GeoJSONLayerState. If strokeColor or fillColor is set on an individual GeoJSONFeature, that feature-specific style takes precedence.

val layerState = remember {
GeoJSONLayerState(
strokeColor = Color.rgb(255, 87, 34), // オレンジ
fillColor = Color.argb(100, 255, 87, 34), // 半透明オレンジ
strokeWidth = 3f,
pointRadius = 12f,
opacity = 0.9f,
)
}