diff --git a/README.es-419.md b/README.es-419.md new file mode 100644 index 00000000..3ce5aace --- /dev/null +++ b/README.es-419.md @@ -0,0 +1,386 @@ +# MapConductor Android SDK + +- [English Doc](./README.md) +- [Japanese Doc](./README.ja.md) + +**Una sola API de mapas para Android que funciona con múltiples proveedores de mapas.** + +MapConductor Android SDK es una librería de mapas de código abierto para Android que te permite trabajar con múltiples SDKs de mapas a través de una API única y consistente basada en Jetpack Compose. + +En lugar de escribir código de mapas distinto para Google Maps, Mapbox, HERE Maps, ArcGIS y MapLibre, MapConductor ofrece abstracciones compartidas para mapas, estado de cámara, marcadores, formas, superposiciones y funciones avanzadas de mapas. + +Escribe tu interfaz de mapa una sola vez. +Elige el proveedor de mapas que mejor se adapte a tu producto. + +--- + +## ¿Por qué MapConductor? + +El desarrollo de mapas para móviles suele quedar fuertemente acoplado a un SDK de mapas específico. Cada proveedor tiene su propio diseño de API, modelo de ciclo de vida, comportamiento de renderizado y conjunto de funciones. Esto dificulta cambiar de proveedor, dar soporte a varios backends de mapas o mantener limpio el código relacionado con mapas en una aplicación moderna con Compose. + +MapConductor resuelve esto proporcionando una capa común sobre los principales SDKs de mapas para Android. + +Con MapConductor puedes: + +* Usar una API orientada a Jetpack Compose para la interfaz de mapas +* Cambiar entre los proveedores de mapas compatibles con menos trabajo de reescritura +* Compartir la misma lógica de marcadores, círculos, polilíneas, polígonos y superposiciones +* Construir funciones de mapas independientes del proveedor, como mapas de calor y agrupamiento de marcadores +* Mantener tu código de aplicación enfocado en el comportamiento del mapa, no en las diferencias específicas de cada SDK + +![](./images/es-419-comic-why-map-conductor.jpg) + +--- + +## Proveedores de mapas compatibles + +MapConductor actualmente es compatible con los siguientes proveedores de mapas para Android: + +| Proveedor | Módulo | +| ---------------- | --------------------------------- | +| Google Maps | `com.mapconductor:for-googlemaps` | +| Mapbox | `com.mapconductor:for-mapbox` | +| HERE Maps | `com.mapconductor:for-here` | +| ArcGIS Maps SDK | `com.mapconductor:for-arcgis` | +| MapLibre | `com.mapconductor:for-maplibre` | + +Puedes elegir un proveedor para tu app, o estructurar tu código de modo que el proveedor pueda cambiarse más adelante. + +--- + +## Funciones principales + +MapConductor ofrece una API unificada para las funciones comunes de interfaz de mapas y geoespaciales: + +* Componentes de vista de mapa para múltiples proveedores +* Estado de cámara y posición de cámara +* Marcadores +* Iconos de marcador personalizados +* Burbujas de información escritas con Jetpack Compose +* Círculos con radio en metros +* Polilíneas +* Polígonos +* Imágenes de superficie (ground images) +* Capas de teselas ráster (raster tile layers) +* Mapas de calor +* Agrupamiento de marcadores +* Capas GeoJSON +* Tipos de geometría compartidos como `GeoPoint` +* Gestión de estado reactiva para objetos de mapa + +El objetivo no es solo envolver el SDK de cada proveedor, sino también ofrecer un comportamiento consistente, en la medida de lo posible, entre los distintos motores de mapas. + +--- + +## Instalación + +Agrega los repositorios de Maven Central y Google a tu proyecto de Android si aún no están configurados. + +```kotlin +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + } +} +``` + +Luego agrega las dependencias de MapConductor. + +```kotlin +dependencies { + implementation(platform("com.mapconductor:mapconductor-bom:")) + + implementation("com.mapconductor:core") + + // Elige uno o más módulos de proveedor de mapas + implementation("com.mapconductor:for-googlemaps") + // implementation("com.mapconductor:for-mapbox") + // implementation("com.mapconductor:for-here") + // implementation("com.mapconductor:for-arcgis") + // implementation("com.mapconductor:for-maplibre") + + // Módulos de funciones opcionales + implementation("com.mapconductor:icons") + implementation("com.mapconductor:heatmap") + implementation("com.mapconductor:marker-clustering") + implementation("com.mapconductor:geojson-layer") +} +``` + +Cada proveedor de mapas puede requerir su propia clave de API, token de acceso, configuración de Gradle o configuración en el manifiesto de Android. + +Por favor revisa la guía de configuración del proveedor que estés usando. +- [Configuración de Google Maps Android API](https://docs-android.mapconductor.com/setup/google-maps/) +- [Configuración de MapBox](https://docs-android.mapconductor.com/setup/mapbox/) +- [Configuración de HERE](https://docs-android.mapconductor.com/setup/here-maps/) +- [Configuración de ArcGIS](https://docs-android.mapconductor.com/setup/arcgis/) +- [Configuración de MapLibre](https://docs-android.mapconductor.com/setup/maplibre/) + +--- + +## Ejemplo básico + +El siguiente ejemplo muestra un mapa simple con Compose que incluye un marcador y un círculo. + +```kotlin +@Composable +fun SimpleMapScreen(modifier: Modifier) { + val mapState = rememberMapLibreMapViewState( + cameraPosition = MapCameraPosition( + position = GeoPoint(35.6762, 139.6503), + zoom = 15.0, + ), + mapDesign = MapLibreDesign.OpenMapTiles, + ) + + MapLibreMapView( + modifier = modifier, + state = mapState, + ) { + Marker( + state = MarkerState( + position = GeoPoint(35.6762, 139.6503), + ) + ) + + Circle( + state = CircleState( + center = GeoPoint(35.6762, 139.6503), + radiusMeters = 500.0, + fillColor = Color.Green.copy(alpha = 0.5f), + strokeColor = Color.Blue, + strokeWidth = 3.dp, + ) + ) + } +} +``` + +Este ejemplo usa MapLibre Maps, pero los objetos del mapa están escritos usando conceptos de MapConductor. La misma lógica de superposiciones se puede adaptar a otros proveedores compatibles. + +![](./images/simple-map-screen.png) + +--- + +## Cambiar de proveedor de mapas + +Una de las ideas principales detrás de MapConductor es que tus superposiciones de mapa no deberían tener que reescribirse cuando cambias de proveedor de mapas. + +Por ejemplo: + +- MapLibre + + ```kotlin + val initCameraPosition = MapCameraPosition(...) + + val mapLibreMapState = rememberMapLibreMapViewState( + cameraPosition = initCameraPosition, + mapDesign = mapDesign = MapLibreDesign.OpenMapTiles, + ) + + MapLibreMapView(state = mapLibreMapState) { + MapContent() + } + ``` + +-
+ Google Maps (Toca para abrir) + + ```kotlin + val initCameraPosition = MapCameraPosition(...) + + val googleMapState = rememberGoogleMapViewState( + cameraPosition = initCameraPosition, + mapDesign = GoogleMapDesign.Normal, + ) + + GoogleMapView(state = googleMapState) { + MapContent() + } + ``` +
+ +-
+ Mapbox (Toca para abrir) + + ```kotlin + val initCameraPosition = MapCameraPosition(...) + + val mapboxMapState = rememberMapboxMapViewState( + cameraPosition = initCameraPosition, + mapDesign = MapboxMapDesign.Standard, + ) + + MapboxMapView(state = mapboxMapState) { + MapContent() + } + ``` +
+ +-
+ HERE (Toca para abrir) + + ```kotlin + val initCameraPosition = MapCameraPosition(...) + + val hereMapState = rememberHereMapViewState( + cameraPosition = initCameraPosition, + mapDesign = HereMapDesign.NormalDay, + ) + + HereMapView(state = hereMapState) { + MapContent() + } + ``` +
+ +-
+ ArcGIS 2D (Toca para abrir) + + ```kotlin + val initCameraPosition = MapCameraPosition(...) + + val arcgisMapState = rememberArcGISMapViewState( + cameraPosition = initCameraPosition, + mapDesign = ArcGISDesign.Streets, + ) + + ArcGISMapView2D(state = arcgisMapState) { + MapContent() + } + ``` +
+ +-
+ ArcGIS 3D (Toca para abrir) + + ```kotlin + val initCameraPosition = MapCameraPosition(...) + + val arcgisMapState = rememberArcGISMapViewState( + cameraPosition = initCameraPosition, + mapDesign = ArcGISDesign.Streets, + ) + + ArcGISMapView(state = arcgisMapState) { + MapContent() + } + ``` +
+ +Tu contenido de mapa reutilizable puede incluir marcadores, círculos, polilíneas, polígonos, mapas de calor, agrupaciones u otros componentes de MapConductor. + +```kotlin +@Composable +fun MapContent() { + Marker( + state = rememberMarkerState( + position = GeoPoint(35.6762, 139.6503), + ) + ) + + Polyline( + state = rememberPolylineState( + points = listOf( + GeoPoint(35.6762, 139.6503), + GeoPoint(35.6895, 139.6917), + ) + ) + ) +} +``` + +Aún se requiere una configuración específica por proveedor, pero la interfaz de mapas a nivel de aplicación puede ser mucho más portable. + +--- + +## Resumen de módulos + +| Módulo | Artefacto | Descripción | +| ----------------- | ------------------------------------ | --------------------------------------------------------------------- | +| BOM | `com.mapconductor:mapconductor-bom` | Alinea las versiones de los módulos de MapConductor | +| Core | `com.mapconductor:core` | Abstracciones principales, tipos de geometría, estado de cámara y de superposiciones | +| Google Maps | `com.mapconductor:for-googlemaps` | Implementación del proveedor Google Maps | +| Mapbox | `com.mapconductor:for-mapbox` | Implementación del proveedor Mapbox | +| HERE Maps | `com.mapconductor:for-here` | Implementación del proveedor HERE Maps | +| ArcGIS | `com.mapconductor:for-arcgis` | Implementación del proveedor ArcGIS | +| MapLibre | `com.mapconductor:for-maplibre` | Implementación del proveedor MapLibre | +| Icons | `com.mapconductor:icons` | Iconos de marcador basados en Compose y utilidades de burbujas de información | +| Heatmap | `com.mapconductor:heatmap` | Superposición de mapa de calor independiente del proveedor | +| Marker Clustering | `com.mapconductor:marker-clustering` | Soporte de agrupamiento de marcadores | +| GeoJSON Layer | `com.mapconductor:geojson-layer` | Soporte de capas GeoJSON | + +--- + +## Estado de las funciones + +| Función | Google Maps | Mapbox | HERE Maps | ArcGIS | MapLibre | +| ------------------ | ----------: | ------: | --------: | ------: | -------: | +| Map | ✅ | ✅ | ✅ | ✅ | ✅ | +| Marker | ✅ | ✅ | ✅ | ✅ | ✅ | +| Circle | ✅ | ✅ | ✅ | ✅ | ✅ | +| Polyline | ✅ | ✅ | ✅ | ✅ | ✅ | +| Polygon | ✅ | ✅ | ✅ | ✅ | ✅ | +| Ground Image | ✅ | ✅ | ✅ | ✅ | ✅ | +| Heatmap | ✅ | ✅ | ✅ | ✅ | ✅ | +| Marker Clustering | ✅ | ✅ | ✅ | ✅ | ✅ | +| Raster Tile Layer | ✅ | ✅ | ✅ | ✅ | ✅ | +| Vector Tile Layer | Planned | Planned | Planned | Planned | Planned | + +MapConductor está en desarrollo activo. Consulta la documentación y las notas de la versión para conocer el comportamiento y las limitaciones más recientes de cada proveedor. + +--- + +## ¿Para quién es esto? + +MapConductor te resulta útil si estás: + +* Construyendo una app de Android con Jetpack Compose y mapas +* Evaluando múltiples proveedores de mapas +* Planeando una posible migración de un SDK de mapas a otro +* Manteniendo funciones de mapas para distintos requisitos de clientes o regiones +* Construyendo componentes de interfaz de mapas reutilizables +* Buscando una capa de abstracción de código abierto para mapas móviles + +Es especialmente útil cuando quieres que tu código de aplicación describa qué debe aparecer en el mapa, en lugar de cómo espera cada SDK de proveedor que se implemente esa función. + +--- + +## Documentación + +La documentación está disponible en: + +```text +https://docs-android.mapconductor.com/ +``` + +La documentación incluye: + +* Guías de introducción +* Configuración específica por proveedor +* Componentes de vista de mapa +* Gestión de estado +* Manejo de eventos +* Clases principales de geometría +* Iconos de marcador +* Mapas de calor +* Agrupamiento de marcadores +* Capas GeoJSON + +--- + +## Estado del proyecto + +MapConductor Android SDK ya está publicado y se encuentra en desarrollo activo. + +El proyecto busca hacer que el desarrollo de mapas sea más flexible, portable y amigable con Compose en los principales proveedores de mapas para Android. Algunas funciones avanzadas pueden seguir siendo experimentales o presentar diferencias específicas por proveedor. + +Los comentarios, reportes de errores y contribuciones son bienvenidos. + +--- + +## Licencia + +MapConductor Android SDK se publica bajo la Licencia Apache 2.0. diff --git a/README.ja.md b/README.ja.md new file mode 100644 index 00000000..cb6ea3b1 --- /dev/null +++ b/README.ja.md @@ -0,0 +1,386 @@ +# MapConductor Android SDK + +- [English Doc](./README.ja.md) +- [Spanish Doc](./README.es-419.md) + +**複数のマッププロバイダーに対応する、ひとつのAndroidマップAPI。** + +MapConductor Android SDKは、Jetpack Composeベースの単一で一貫したAPIを通じて複数のマップSDKを扱えるようにする、オープンソースのAndroid向けマッピングライブラリです。 + +Google Maps、Mapbox、HERE Maps、ArcGIS、MapLibreごとに異なるマップコードを書く代わりに、MapConductorはマップ、カメラの状態、マーカー、図形、オーバーレイ、高度なマップ機能のための共通の抽象化を提供します。 + +マップUIは一度だけ書きます。 +プロダクトに合ったマッププロバイダーを選びましょう。 + +--- + +## なぜMapConductorなのか? + +モバイルのマップ開発は、特定のマップSDKに強く依存してしまうことがよくあります。各プロバイダーは独自のAPI設計、ライフサイクルモデル、レンダリングの挙動、機能セットを持っています。これにより、プロバイダーの切り替えや複数のマップバックエンドのサポート、最新のCompose アプリケーションにおけるマップ関連コードのクリーンな維持が難しくなります。 + +MapConductorは、主要なAndroidマップSDKの上に共通レイヤーを提供することでこれを解決します。 + +MapConductorを使うと、以下のことができます: + +* マップUIにComposeファーストのAPIを使う +* 少ない書き換え作業でサポートされているマッププロバイダーを切り替える +* マーカー、円、ポリライン、ポリゴン、オーバーレイのロジックを共有する +* プロバイダーに依存しないヒートマップやマーカークラスタリングなどのマップ機能を構築する +* アプリケーションコードをSDK固有の差異ではなくマップの挙動に集中させる + +![](./images/japanese-comic-why-map-conductor.jpg) + +--- + +## サポートされているマッププロバイダー + +MapConductorは現在、以下のAndroidマッププロバイダーをサポートしています: + +| プロバイダー | モジュール | +| ----------------- | --------------------------------- | +| Google Maps | `com.mapconductor:for-googlemaps` | +| Mapbox | `com.mapconductor:for-mapbox` | +| HERE Maps | `com.mapconductor:for-here` | +| ArcGIS Maps SDK | `com.mapconductor:for-arcgis` | +| MapLibre | `com.mapconductor:for-maplibre` | + +アプリ用に1つのプロバイダーを選んでもよいですし、後でプロバイダーを変更できるようにコードを構成することもできます。 + +--- + +## コア機能 + +MapConductorは、一般的なマップUIおよび地理空間機能に対して統一されたAPIを提供します: + +* 複数プロバイダー向けのマップビューコンポーネント +* カメラの状態とカメラ位置 +* マーカー +* カスタムマーカーアイコン +* Jetpack Composeで書かれた情報バブル +* メートル単位の半径を持つ円 +* ポリライン +* ポリゴン +* グラウンドイメージ +* ラスタータイルレイヤー +* ヒートマップ +* マーカークラスタリング +* GeoJSONレイヤー +* `GeoPoint`などの共有ジオメトリ型 +* マップオブジェクトのためのリアクティブな状態管理 + +目的は各プロバイダーSDKをラップするだけでなく、可能な限り異なるマップエンジン間で一貫した動作を提供することです。 + +--- + +## インストール + +まだ設定していない場合は、AndroidプロジェクトにMaven CentralとGoogleのリポジトリを追加してください。 + +```kotlin +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + } +} +``` + +次にMapConductorの依存関係を追加します。 + +```kotlin +dependencies { + implementation(platform("com.mapconductor:mapconductor-bom:")) + + implementation("com.mapconductor:core") + + // 1つ以上のマッププロバイダーモジュールを選択 + implementation("com.mapconductor:for-googlemaps") + // implementation("com.mapconductor:for-mapbox") + // implementation("com.mapconductor:for-here") + // implementation("com.mapconductor:for-arcgis") + // implementation("com.mapconductor:for-maplibre") + + // オプションの機能モジュール + implementation("com.mapconductor:icons") + implementation("com.mapconductor:heatmap") + implementation("com.mapconductor:marker-clustering") + implementation("com.mapconductor:geojson-layer") +} +``` + +各マッププロバイダーは、それぞれ独自のAPIキー、アクセストークン、Gradleの設定、またはAndroidマニフェストの設定が必要な場合があります。 + +使用するプロバイダーのセットアップガイドを確認してください。 +- [Google Maps Android APIのセットアップ](https://docs-android.mapconductor.com/setup/google-maps/) +- [MapBoxのセットアップ](https://docs-android.mapconductor.com/setup/mapbox/) +- [HEREのセットアップ](https://docs-android.mapconductor.com/setup/here-maps/) +- [ArcGISのセットアップ](https://docs-android.mapconductor.com/setup/arcgis/) +- [MapLibreのセットアップ](https://docs-android.mapconductor.com/setup/maplibre/) + +--- + +## 基本的な例 + +以下の例は、マーカーと円を含むシンプルなComposeマップを示しています。 + +```kotlin +@Composable +fun SimpleMapScreen(modifier: Modifier) { + val mapState = rememberMapLibreMapViewState( + cameraPosition = MapCameraPosition( + position = GeoPoint(35.6762, 139.6503), + zoom = 15.0, + ), + mapDesign = MapLibreDesign.OpenMapTiles, + ) + + MapLibreMapView( + modifier = modifier, + state = mapState, + ) { + Marker( + state = MarkerState( + position = GeoPoint(35.6762, 139.6503), + ) + ) + + Circle( + state = CircleState( + center = GeoPoint(35.6762, 139.6503), + radiusMeters = 500.0, + fillColor = Color.Green.copy(alpha = 0.5f), + strokeColor = Color.Blue, + strokeWidth = 3.dp, + ) + ) + } +} +``` + +この例ではMapLibre Mapsを使用していますが、マップオブジェクトはMapConductorの概念を使って書かれています。同じオーバーレイのロジックを他のサポートされているプロバイダーに適用できます。 + +![](./images/simple-map-screen.png) + +--- + +## マッププロバイダーの切り替え + +MapConductorの主な考え方の1つは、マッププロバイダーを変更してもマップオーバーレイを書き直す必要がないということです。 + +例: + +- MapLibre + + ```kotlin + val initCameraPosition = MapCameraPosition(...) + + val mapLibreMapState = rememberMapLibreMapViewState( + cameraPosition = initCameraPosition, + mapDesign = mapDesign = MapLibreDesign.OpenMapTiles, + ) + + MapLibreMapView(state = mapLibreMapState) { + MapContent() + } + ``` + +-
+ Google Maps (タップして開く) + + ```kotlin + val initCameraPosition = MapCameraPosition(...) + + val googleMapState = rememberGoogleMapViewState( + cameraPosition = initCameraPosition, + mapDesign = GoogleMapDesign.Normal, + ) + + GoogleMapView(state = googleMapState) { + MapContent() + } + ``` +
+ +-
+ Mapbox (タップして開く) + + ```kotlin + val initCameraPosition = MapCameraPosition(...) + + val mapboxMapState = rememberMapboxMapViewState( + cameraPosition = initCameraPosition, + mapDesign = MapboxMapDesign.Standard, + ) + + MapboxMapView(state = mapboxMapState) { + MapContent() + } + ``` +
+ +-
+ HERE (タップして開く) + + ```kotlin + val initCameraPosition = MapCameraPosition(...) + + val hereMapState = rememberHereMapViewState( + cameraPosition = initCameraPosition, + mapDesign = HereMapDesign.NormalDay, + ) + + HereMapView(state = hereMapState) { + MapContent() + } + ``` +
+ +-
+ ArcGIS 2D (タップして開く) + + ```kotlin + val initCameraPosition = MapCameraPosition(...) + + val arcgisMapState = rememberArcGISMapViewState( + cameraPosition = initCameraPosition, + mapDesign = ArcGISDesign.Streets, + ) + + ArcGISMapView2D(state = arcgisMapState) { + MapContent() + } + ``` +
+ +-
+ ArcGIS 3D (タップして開く) + + ```kotlin + val initCameraPosition = MapCameraPosition(...) + + val arcgisMapState = rememberArcGISMapViewState( + cameraPosition = initCameraPosition, + mapDesign = ArcGISDesign.Streets, + ) + + ArcGISMapView(state = arcgisMapState) { + MapContent() + } + ``` +
+ +再利用可能なマップコンテンツには、マーカー、円、ポリライン、ポリゴン、ヒートマップ、クラスター、その他のMapConductorコンポーネントを含めることができます。 + +```kotlin +@Composable +fun MapContent() { + Marker( + state = rememberMarkerState( + position = GeoPoint(35.6762, 139.6503), + ) + ) + + Polyline( + state = rememberPolylineState( + points = listOf( + GeoPoint(35.6762, 139.6503), + GeoPoint(35.6895, 139.6917), + ) + ) + ) +} +``` + +プロバイダー固有のセットアップは依然として必要ですが、アプリケーションレベルのマップUIはより高いポータビリティを維持できます。 + +--- + +## モジュール概要 + +| モジュール | アーティファクト | 説明 | +| ----------------- | ------------------------------------ | ------------------------------------------------------------------- | +| BOM | `com.mapconductor:mapconductor-bom` | MapConductorモジュールのバージョンを揃える | +| Core | `com.mapconductor:core` | コアの抽象化、ジオメトリ型、カメラの状態、オーバーレイの状態 | +| Google Maps | `com.mapconductor:for-googlemaps` | Google Mapsプロバイダー実装 | +| Mapbox | `com.mapconductor:for-mapbox` | Mapboxプロバイダー実装 | +| HERE Maps | `com.mapconductor:for-here` | HERE Mapsプロバイダー実装 | +| ArcGIS | `com.mapconductor:for-arcgis` | ArcGISプロバイダー実装 | +| MapLibre | `com.mapconductor:for-maplibre` | MapLibreプロバイダー実装 | +| Icons | `com.mapconductor:icons` | Composeベースのマーカーアイコンと情報バブルのユーティリティ | +| Heatmap | `com.mapconductor:heatmap` | プロバイダーに依存しないヒートマップオーバーレイ | +| Marker Clustering | `com.mapconductor:marker-clustering` | マーカークラスタリングのサポート | +| GeoJSON Layer | `com.mapconductor:geojson-layer` | GeoJSONレイヤーのサポート | + +--- + +## 機能対応状況 + +| 機能 | Google Maps | Mapbox | HERE Maps | ArcGIS | MapLibre | +| ----------------- | ----------: | ------: | --------: | ------: | -------: | +| Map | ✅ | ✅ | ✅ | ✅ | ✅ | +| Marker | ✅ | ✅ | ✅ | ✅ | ✅ | +| Circle | ✅ | ✅ | ✅ | ✅ | ✅ | +| Polyline | ✅ | ✅ | ✅ | ✅ | ✅ | +| Polygon | ✅ | ✅ | ✅ | ✅ | ✅ | +| Ground Image | ✅ | ✅ | ✅ | ✅ | ✅ | +| Heatmap | ✅ | ✅ | ✅ | ✅ | ✅ | +| Marker Clustering | ✅ | ✅ | ✅ | ✅ | ✅ | +| Raster Tile Layer | ✅ | ✅ | ✅ | ✅ | ✅ | +| Vector Tile Layer | Planned | Planned | Planned | Planned | Planned | + +MapConductorは活発に開発が進められています。最新のプロバイダー固有の挙動や制限事項については、ドキュメントとリリースノートを確認してください。 + +--- + +## こんな方に向いています + +MapConductorは、以下のような方に役立ちます: + +* Jetpack Composeとマップを使ったAndroidアプリを構築している +* 複数のマッププロバイダーを評価している +* あるマップSDKから別のものへの移行を計画している +* 異なる顧客や地域の要件にわたってマップ機能を保守している +* 再利用可能なマップUIコンポーネントを構築している +* モバイルマップ向けのオープンソースの抽象化レイヤーを探している + +各プロバイダーSDKがその機能をどのように実装することを期待しているかではなく、マップに何を表示すべきかをアプリケーションコードで記述したい場合に特に役立ちます。 + +--- + +## ドキュメント + +ドキュメントは以下で利用できます: + +```text +https://docs-android.mapconductor.com/ +``` + +ドキュメントには以下が含まれます: + +* スタートガイド +* プロバイダー固有のセットアップ +* マップビューコンポーネント +* 状態管理 +* イベントハンドリング +* コアジオメトリクラス +* マーカーアイコン +* ヒートマップ +* マーカークラスタリング +* GeoJSONレイヤー + +--- + +## プロジェクトの状況 + +MapConductor Android SDKはリリース済みで、活発に開発が進められています。 + +このプロジェクトは、主要なAndroidマッププロバイダーにわたって、マップ開発をより柔軟でポータブル、かつComposeフレンドリーにすることを目指しています。一部の高度な機能は実験的であったり、プロバイダー固有の差異がある場合があります。 + +フィードバック、Issue、コントリビューションを歓迎します。 + +--- + +## ライセンス + +MapConductor Android SDKはApache License 2.0のもとでリリースされています。 diff --git a/README.md b/README.md index f1d7cff9..b8f44ab0 100644 --- a/README.md +++ b/README.md @@ -1,116 +1,386 @@ # MapConductor Android SDK -A unified mapping library that provides a common API for multiple map providers including Google Maps, Mapbox, HERE, ArcGIS, and MapLibre. Write once, deploy across all major mapping platforms. - -## Features - -- **Multi-Provider Support**: Seamlessly switch between Google Maps, Mapbox, HERE, ArcGIS, and MapLibre with a single API -- **Unified Interface**: Common abstractions for markers, circles, polylines, polygons, ground overlays, heatmaps, and marker clustering -- **Reactive State**: Built on Kotlin StateFlow for reactive UI updates -- **Jetpack Compose**: Modern Android UI toolkit integration - -## Module Structure - -| Module | Artifact | Description | -|-----------------------------|--------------------------------------|--------------------------------------------------------------| -| `mapconductor-bom` | `com.mapconductor:mapconductor-bom` | Bill of Materials — aligns all module versions | -| `android-sdk-core` | `com.mapconductor:core` | Core abstractions, geometry types, overlay states | -| `android-for-googlemaps` | `com.mapconductor:for-googlemaps` | Google Maps implementation | -| `android-for-mapbox` | `com.mapconductor:for-mapbox` | Mapbox implementation | -| `android-for-here` | `com.mapconductor:for-here` | HERE Maps implementation | -| `android-for-arcgis` | `com.mapconductor:for-arcgis` | ArcGIS implementation | -| `android-for-maplibre` | `com.mapconductor:for-maplibre` | MapLibre implementation | -| `android-icons` | `com.mapconductor:icons` | Composable marker icons (CircleIcon, FlagIcon, info bubbles) | -| `android-heatmap` | `com.mapconductor:heatmap` | Map-provider-agnostic heatmap overlay | -| `android-marker-clustering` | `com.mapconductor:marker-clustering` | Automatic marker clustering across all providers | -| `android-geojson-layer` | `com.mapconductor:geojson-layer` | Geojson layer across all providers | - -## Quick Start - -### 1. Setup - -Clone the repository: -```bash -git clone https://github.com/MapConductor/android-sdk.git -``` +- [Japanese Doc](./README.ja.md) +- [Spanish Doc](./README.es-419.md) + +**One Android map API for multiple map providers.** + +MapConductor Android SDK is an open-source mapping library for Android that lets you work with multiple map SDKs through a single, consistent Jetpack Compose API. + +Instead of writing different map code for Google Maps, Mapbox, HERE Maps, ArcGIS, and MapLibre, MapConductor provides shared abstractions for maps, camera state, markers, shapes, overlays, and advanced map features. + +Write your map UI once. +Choose the map provider that fits your product. + +--- + +## Why MapConductor? + +Mobile map development often becomes tightly coupled to a specific map SDK. Each provider has its own API design, lifecycle model, rendering behavior, and feature set. This makes it hard to switch providers, support multiple map backends, or keep map-related code clean in a modern Compose application. + +MapConductor solves this by providing a common layer on top of major Android map SDKs. + +With MapConductor, you can: + +* Use a Jetpack Compose-first API for map UI +* Switch between supported map providers with less rewrite work +* Share the same marker, circle, polyline, polygon, and overlay logic +* Build provider-independent map features such as heatmaps and marker clustering +* Keep your application code focused on map behavior, not SDK-specific differences + +![](./images/english-comic-why-map-conductor.jpg) + +--- + +## Supported Map Providers + +MapConductor currently supports the following Android map providers: + +| Provider | Module | +| --------------- | --------------------------------- | +| Google Maps | `com.mapconductor:for-googlemaps` | +| Mapbox | `com.mapconductor:for-mapbox` | +| HERE Maps | `com.mapconductor:for-here` | +| ArcGIS Maps SDK | `com.mapconductor:for-arcgis` | +| MapLibre | `com.mapconductor:for-maplibre` | + +You can choose one provider for your app, or structure your code so that the provider can be changed later. + +--- + +## Core Features + +MapConductor provides a unified API for common map UI and geospatial features: + +* Map view components for multiple providers +* Camera state and camera position +* Markers +* Custom marker icons +* Info bubbles written with Jetpack Compose +* Circles with meter-based radius +* Polylines +* Polygons +* Ground images +* Raster tile layers +* Heatmaps +* Marker clustering +* GeoJSON layers +* Shared geometry types such as `GeoPoint` +* Reactive state management for map objects + +The goal is not only to wrap each provider SDK, but also to provide consistent behavior where possible across different map engines. + +--- -Add `secrets.properties` to the project root from https://github.com/MapConductor/map-sdk-credentials/ +## Installation -### 2. Add Dependencies +Add Maven Central and Google repositories to your Android project if they are not already configured. + +```kotlin +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + } +} +``` + +Then add MapConductor dependencies. ```kotlin dependencies { - implementation(platform("com.mapconductor:mapconductor-bom:$version")) + implementation(platform("com.mapconductor:mapconductor-bom:")) + implementation("com.mapconductor:core") - implementation("com.mapconductor:for-googlemaps") // or your chosen provider + + // Choose one or more map provider modules + implementation("com.mapconductor:for-googlemaps") + // implementation("com.mapconductor:for-mapbox") + // implementation("com.mapconductor:for-here") + // implementation("com.mapconductor:for-arcgis") + // implementation("com.mapconductor:for-maplibre") + + // Optional feature modules + implementation("com.mapconductor:icons") + implementation("com.mapconductor:heatmap") + implementation("com.mapconductor:marker-clustering") + implementation("com.mapconductor:geojson-layer") } ``` -### 3. Basic Usage +Each map provider may require its own API key, access token, Gradle setup, or Android manifest configuration. + +Please check the setup guide for the provider you are using. +- [Setup for Google Maps Android API](https://docs-android.mapconductor.com/setup/google-maps/) +- [Setup for MapBox](https://docs-android.mapconductor.com/setup/mapbox/) +- [Setup for HERE](https://docs-android.mapconductor.com/setup/here-maps/) +- [Setup for ArcGIS](https://docs-android.mapconductor.com/setup/arcgis/) +- [Setup for MapLibre](https://docs-android.mapconductor.com/setup/maplibre/) + +--- + +## Basic Example + +The following example shows a simple Compose map with a marker and a circle. ```kotlin -val mapState = rememberGoogleMapViewState( - initialCameraPosition = MapCameraPosition( - target = GeoPoint(35.6762, 139.6503), - zoom = 12.0, +@Composable +fun SimpleMapScreen(modifier: Modifier) { + val mapState = rememberMapLibreMapViewState( + cameraPosition = MapCameraPosition( + position = GeoPoint(35.6762, 139.6503), + zoom = 15.0, + ), + mapDesign = MapLibreDesign.OpenMapTiles, ) -) - -GoogleMapView( - modifier = Modifier.fillMaxSize(), - state = mapState, -) { - Marker(rememberMarkerState(position = GeoPoint(35.6762, 139.6503))) - Circle(rememberCircleState(center = GeoPoint(35.6762, 139.6503), radius = 500.0)) + + MapLibreMapView( + modifier = modifier, + state = mapState, + ) { + Marker( + state = MarkerState( + position = GeoPoint(35.6762, 139.6503), + ) + ) + + Circle( + state = CircleState( + center = GeoPoint(35.6762, 139.6503), + radiusMeters = 500.0, + fillColor = Color.Green.copy(alpha = 0.5f), + strokeColor = Color.Blue, + strokeWidth = 3.dp, + ) + ) + } } ``` -### 4. Switch Map Providers +This example uses MapLibre Maps, but the map objects are written using MapConductor concepts. The same overlay logic can be adapted to other supported providers. -Simply change the map view component — all overlays work unchanged: -```kotlin -// Google Maps -GoogleMapView(state = googleMapState) { /* overlays */ } +![](./images/simple-map-screen.png) -// Mapbox -MapboxMapView(state = mapboxState) { /* overlays */ } +--- -// HERE Maps -HereMapView(state = hereState) { /* overlays */ } +## Switching Map Providers -// ArcGIS -ArcGISMapView(state = arcgisState) { /* overlays */ } +One of the main ideas behind MapConductor is that your map overlays should not have to be rewritten when you change map providers. -// MapLibre -MapLibreMapView(state = maplibreState) { /* overlays */ } -``` +For example: + +- MapLibre + + ```kotlin + val initCameraPosition = MapCameraPosition(...) + + val mapLibreMapState = rememberMapLibreMapViewState( + cameraPosition = initCameraPosition, + mapDesign = mapDesign = MapLibreDesign.OpenMapTiles, + ) + + MapLibreMapView(state = mapLibreMapState) { + MapContent() + } + ``` + +-
+ Google Maps (Tap to open) + + ```kotlin + val initCameraPosition = MapCameraPosition(...) -## Development + val googleMapState = rememberGoogleMapViewState( + cameraPosition = initCameraPosition, + mapDesign = GoogleMapDesign.Normal, + ) -### Building -```bash -./gradlew build + GoogleMapView(state = googleMapState) { + MapContent() + } + ``` +
+ +-
+ Mapbox (Tap to open) + + ```kotlin + val initCameraPosition = MapCameraPosition(...) + + val mapboxMapState = rememberMapboxMapViewState( + cameraPosition = initCameraPosition, + mapDesign = MapboxMapDesign.Standard, + ) + + MapboxMapView(state = mapboxMapState) { + MapContent() + } + ``` +
+ +-
+ HERE (Tap to open) + + ```kotlin + val initCameraPosition = MapCameraPosition(...) + + val hereMapState = rememberHereMapViewState( + cameraPosition = initCameraPosition, + mapDesign = HereMapDesign.NormalDay, + ) + + HereMapView(state = hereMapState) { + MapContent() + } + ``` +
+ +-
+ ArcGIS 2D (Tap to open) + + ```kotlin + val initCameraPosition = MapCameraPosition(...) + + val arcgisMapState = rememberArcGISMapViewState( + cameraPosition = initCameraPosition, + mapDesign = ArcGISDesign.Streets, + ) + + ArcGISMapView2D(state = arcgisMapState) { + MapContent() + } + ``` +
+ +-
+ ArcGIS 3D (Tap to open) + + ```kotlin + val initCameraPosition = MapCameraPosition(...) + + val arcgisMapState = rememberArcGISMapViewState( + cameraPosition = initCameraPosition, + mapDesign = ArcGISDesign.Streets, + ) + + ArcGISMapView(state = arcgisMapState) { + MapContent() + } + ``` +
+ +Your reusable map content can contain markers, circles, polylines, polygons, heatmaps, clusters, or other MapConductor components. + +```kotlin +@Composable +fun MapContent() { + Marker( + state = rememberMarkerState( + position = GeoPoint(35.6762, 139.6503), + ) + ) + + Polyline( + state = rememberPolylineState( + points = listOf( + GeoPoint(35.6762, 139.6503), + GeoPoint(35.6895, 139.6917), + ) + ) + ) +} ``` -### Code Style -This project follows KtLint conventions: -```bash -./gradlew allLintChecks +Provider-specific setup is still required, but your application-level map UI can stay much more portable. + +--- + +## Module Overview + +| Module | Artifact | Description | +| ----------------- | ------------------------------------ | ------------------------------------------------------------------- | +| BOM | `com.mapconductor:mapconductor-bom` | Aligns MapConductor module versions | +| Core | `com.mapconductor:core` | Core abstractions, geometry types, camera state, and overlay states | +| Google Maps | `com.mapconductor:for-googlemaps` | Google Maps provider implementation | +| Mapbox | `com.mapconductor:for-mapbox` | Mapbox provider implementation | +| HERE Maps | `com.mapconductor:for-here` | HERE Maps provider implementation | +| ArcGIS | `com.mapconductor:for-arcgis` | ArcGIS provider implementation | +| MapLibre | `com.mapconductor:for-maplibre` | MapLibre provider implementation | +| Icons | `com.mapconductor:icons` | Compose-based marker icons and info bubble utilities | +| Heatmap | `com.mapconductor:heatmap` | Provider-independent heatmap overlay | +| Marker Clustering | `com.mapconductor:marker-clustering` | Marker clustering support | +| GeoJSON Layer | `com.mapconductor:geojson-layer` | GeoJSON layer support | + +--- + +## Feature Status + +| Feature | Google Maps | Mapbox | HERE Maps | ArcGIS | MapLibre | +| ----------------- | ----------: | ------: | --------: | ------: | -------: | +| Map | ✅ | ✅ | ✅ | ✅ | ✅ | +| Marker | ✅ | ✅ | ✅ | ✅ | ✅ | +| Circle | ✅ | ✅ | ✅ | ✅ | ✅ | +| Polyline | ✅ | ✅ | ✅ | ✅ | ✅ | +| Polygon | ✅ | ✅ | ✅ | ✅ | ✅ | +| Ground Image | ✅ | ✅ | ✅ | ✅ | ✅ | +| Heatmap | ✅ | ✅ | ✅ | ✅ | ✅ | +| Marker Clustering | ✅ | ✅ | ✅ | ✅ | ✅ | +| Raster Tile Layer | ✅ | ✅ | ✅ | ✅ | ✅ | +| Vector Tile Layer | Planned | Planned | Planned | Planned | Planned | + +MapConductor is actively developed. Please check the documentation and release notes for the latest provider-specific behavior and limitations. + +--- + +## Who Is This For? + +MapConductor is useful if you are: + +* Building an Android app with Jetpack Compose and maps +* Evaluating multiple map providers +* Planning a possible migration from one map SDK to another +* Maintaining map features across different customer or regional requirements +* Building reusable map UI components +* Looking for an open-source abstraction layer for mobile maps + +It is especially helpful when you want your application code to describe what should appear on the map, rather than how each provider SDK expects that feature to be implemented. + +--- + +## Documentation + +Documentation is available at: + +```text +https://docs-android.mapconductor.com/ ``` -## Feature Implementation Status +The documentation includes: + +* Getting started guides +* Provider-specific setup +* Map view components +* State management +* Event handling +* Core geometry classes +* Marker icons +* Heatmaps +* Marker clustering +* GeoJSON layers + +--- + +## Project Status + +MapConductor Android SDK is released and under active development. + +The project aims to make map development more flexible, portable, and Compose-friendly across major Android map providers. Some advanced features may still be experimental or may have provider-specific differences. + +Feedback, issues, and contributions are welcome. -| | Google Maps | Mapbox | HERE | ArcGIS | MapLibre | -|---------------------|-------------|----------|----------|----------|----------| -| Map | ☑ | ☑ | ☑ | ☑ | ☑ | -| Marker | ☑ | ☑ | ☑ | ☑ | ☑ | -| Circle | ☑ | ☑ | ☑ | ☑ | ☑ | -| Polyline | ☑ | ☑ | ☑ | ☑ | ☑ | -| Polygon | ☑ | ☑ | ☑ | ☑ | ☑ | -| GroundImage | ☑ | ☑ | ☑ | ☑ | ☑ | -| Heatmap | ☑ | ☑ | ☑ | ☑ | ☑ | -| Marker Clustering | ☑ | ☑ | ☑ | ☑ | ☑ | -| RasterTileLayer | ☑ | ☑ | ☑ | ☑ | ☑ | -| VectorTileLayer | ☐ | ☐ | ☐ | ☐ | ☐ | +--- +## License +MapConductor Android SDK is released under the Apache License 2.0. diff --git a/images/english-comic-why-map-conductor.jpg b/images/english-comic-why-map-conductor.jpg new file mode 100644 index 00000000..ab61ce23 Binary files /dev/null and b/images/english-comic-why-map-conductor.jpg differ diff --git a/images/es-419-comic-why-map-conductor.jpg b/images/es-419-comic-why-map-conductor.jpg new file mode 100644 index 00000000..558b3272 Binary files /dev/null and b/images/es-419-comic-why-map-conductor.jpg differ diff --git a/images/japanese-comic-why-map-conductor.jpg b/images/japanese-comic-why-map-conductor.jpg new file mode 100644 index 00000000..9f494905 Binary files /dev/null and b/images/japanese-comic-why-map-conductor.jpg differ diff --git a/images/simple-map-screen.png b/images/simple-map-screen.png new file mode 100644 index 00000000..3163ed17 Binary files /dev/null and b/images/simple-map-screen.png differ