Try Live
Add Docs
Rankings
Pricing
Enterprise
Docs
Install
Install
Docs
Pricing
Enterprise
More...
More...
Try Live
Rankings
Add Docs
Magic Lane Maps SDK for Android Documentation
https://github.com/magiclane/magiclane-maps-sdk-for-android-docs-context7
Admin
Documentation for Magic Lane Maps SDK for Android
Tokens:
1,159,019
Snippets:
8,621
Trust Score:
3.5
Update:
1 month ago
Context
Skills
Chat
Benchmark
76.9
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# Magic Lane Maps SDK for Android The Magic Lane Maps SDK for Android is a comprehensive mapping and navigation library that enables developers to integrate powerful location-based features into their Android applications. Built on OpenStreetMap data with global coverage, the SDK provides 3D terrain topography, turn-by-turn navigation with voice guidance, offline functionality, real-time traffic integration, and customizable map styles. The SDK is designed for high performance on resource-constrained devices while delivering a complete suite of mapping capabilities. The SDK's core functionality centers around the `GemSurfaceView` for map display, `SearchService` for location search, `RoutingService` for route calculation, and `NavigationService` for turn-by-turn guidance. It supports both online and offline modes, with downloadable maps, voices, and styles through the `ContentStore` API. The architecture follows a service-oriented pattern where each major capability (search, routing, navigation, content management) is encapsulated in dedicated service classes with callback-based asynchronous operations. --- ## SDK Initialization Initialize the Maps SDK with default settings in your Activity. The SDK handles OpenGL context creation, map data loading, and service initialization automatically. ```kotlin import android.os.Bundle import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import com.magiclane.sdk.core.GemSdk import com.magiclane.sdk.core.SdkSettings class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // Handle API token rejection SdkSettings.onApiTokenRejected = { Toast.makeText(this, "TOKEN REJECTED", Toast.LENGTH_LONG).show() } // Initialize SDK with defaults (returns false if initialization fails) if (!GemSdk.initSdkWithDefaults(this)) { finish() return } } override fun onDestroy() { super.onDestroy() GemSdk.release() } } ``` --- ## GemSurfaceView - Display a Map The `GemSurfaceView` is the primary component for displaying maps. It handles OpenGL rendering, touch interactions, and automatic SDK initialization. ```xml <!-- res/layout/activity_main.xml --> <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/main" android:layout_width="match_parent" android:layout_height="match_parent"> <com.magiclane.sdk.core.GemSurfaceView android:id="@+id/gem_surface" android:layout_width="match_parent" android:layout_height="match_parent" app:createDefaultMapView="true" app:autoReleaseOnDetachedFromWindow="true" /> </androidx.constraintlayout.widget.ConstraintLayout> ``` ```kotlin val gemSurfaceView = findViewById<GemSurfaceView>(R.id.gem_surface) // Configure callbacks for map initialization gemSurfaceView.onDefaultMapViewCreated = { mapView -> // Map is ready - configure initial view mapView.centerOnCoordinates( Coordinates(48.8566, 2.3522), // Paris zoomLevel = 50, animation = Animation(EAnimation.Linear, 1000) ) } gemSurfaceView.onSdkInitSucceeded = { Log.d("Map", "SDK initialized successfully") } ``` --- ## MapView - Center and Control the Map The `MapView` class provides methods for controlling map display, including centering, zooming, rotation, and perspective changes. ```kotlin val gemSurfaceView = findViewById<GemSurfaceView>(R.id.gem_surface) val mapView = gemSurfaceView.mapView // Center on coordinates with animation mapView?.centerOnCoordinates( Coordinates(52.5200, 13.4050), // Berlin zoomLevel = 60, animation = Animation(EAnimation.Linear, 2000) ) // Center on a geographic area val topLeft = Coordinates(44.93343, 25.09946) val bottomRight = Coordinates(44.93324, 25.09987) val area = RectangleGeographicArea(topLeft, bottomRight) mapView?.centerOnArea(area) // Get and set zoom level val currentZoom = mapView?.zoomLevel mapView?.setZoomLevel(70) // Change map perspective (2D/3D) mapView?.preferences?.setMapViewPerspective(EMapViewPerspective.ThreeDimensional) // Set view angle for 3D effect (90 = top-down, lower = tilted) mapView?.preferences?.setViewAngle(45) // Rotate the map (0-360 degrees, 0 = north-up) mapView?.preferences?.rotationAngle = 45.0 // Convert screen coordinates to WGS coordinates val screenPos = Xy(500, 300) val wgsCoords = mapView?.transformScreenToWgs(screenPos) // Convert WGS coordinates to screen position val coords = Coordinates(48.8566, 2.3522) val screenXY = mapView?.transformWgsToScreen(coords) ``` --- ## SearchService - Text and Location Search The `SearchService` provides comprehensive search functionality including text search, category-based search, and proximity search with customizable preferences. ```kotlin import com.magiclane.sdk.places.SearchService import com.magiclane.sdk.places.SearchPreferences import com.magiclane.sdk.core.Coordinates import com.magiclane.sdk.core.GemError // Configure search preferences val preferences = SearchPreferences().apply { maxMatches = 40 allowFuzzyResults = true searchMapPOIsEnabled = true searchAddressesEnabled = true thresholdDistance = 50000 // 50km radius } // Create search service with completion callback val searchService = SearchService( preferences = preferences, onCompleted = { results, errorCode, hint -> when (errorCode) { GemError.NoError -> { if (results.isEmpty()) { Log.d("Search", "No results found") } else { Log.d("Search", "Found ${results.size} results") results.forEach { landmark -> Log.d("Search", "Name: ${landmark.name}, Coords: ${landmark.coordinates}") } // Center map on first result mapView?.centerOnCoordinates(results.first().coordinates, zoomLevel = 60) } } GemError.Cancel -> Log.d("Search", "Search cancelled") GemError.NetworkTimeout -> Log.e("Search", "Network timeout") else -> Log.e("Search", "Error: ${GemError.getMessage(errorCode)}") } } ) // Perform text search with reference coordinates val referencePoint = Coordinates(48.8566, 2.3522) // Paris searchService.searchByFilter("Eiffel Tower", referencePoint) // Search by category (e.g., gas stations) searchService.searchByFilter( "Shell", referencePoint, arrayListOf(EGenericCategoriesIDs.GasStation) ) // Search nearby without text (proximity search) searchService.searchAroundPosition(referencePoint) // Search within a bounded area val searchArea = RectangleGeographicArea( Coordinates(48.9, 2.2), // topLeft Coordinates(48.8, 2.5) // bottomRight ) val areaSearchService = SearchService( preferences = preferences, locationHint = searchArea, onCompleted = { results, errorCode, hint -> /* handle results */ } ) areaSearchService.searchByFilter("restaurant", Coordinates(48.85, 2.35)) ``` --- ## RoutingService - Calculate Routes The `RoutingService` calculates routes between waypoints with customizable preferences including transport mode, route type, and traffic awareness. ```kotlin import com.magiclane.sdk.routesandnavigation.RoutingService import com.magiclane.sdk.routesandnavigation.RoutePreferences import com.magiclane.sdk.places.Landmark import com.magiclane.sdk.core.GemError // Define departure and destination val departureLandmark = Landmark().apply { coordinates = Coordinates(48.85682, 2.34375) // Paris } val destinationLandmark = Landmark().apply { coordinates = Coordinates(50.84644, 4.34587) // Brussels } // Configure route preferences val routePreferences = RoutePreferences().apply { buildTerrainProfile = true // Enable elevation data // avoidTolls = true // avoidHighways = true // transportMode = ERouteTransportMode.Car } // Create waypoints list val waypoints = arrayListOf(departureLandmark, destinationLandmark) // Create routing service with callbacks val routingService = RoutingService( preferences = routePreferences, onCompleted = { routes, errorCode, hint -> when (errorCode) { GemError.Success -> { Log.d("Routing", "Calculated ${routes.size} routes") routes.firstOrNull()?.let { route -> // Get time and distance info val timeDistance = route.getTimeDistance(activePart = false) val totalDistance = timeDistance?.totalDistance // meters val totalDuration = timeDistance?.totalTime // seconds Log.d("Routing", "Distance: ${totalDistance}m, Duration: ${totalDuration}s") // Get traffic events on route route.trafficEvents?.forEach { event -> Log.d("Traffic", "Event: ${event.description}") } // Get terrain profile if enabled route.terrainProfile?.let { profile -> Log.d("Terrain", "Min elevation: ${profile.minElevation}m") Log.d("Terrain", "Max elevation: ${profile.maxElevation}m") Log.d("Terrain", "Total climb: ${profile.totalUp}m") } // Display route on map mapView?.presentRoute(route) } } GemError.Cancel -> Log.d("Routing", "Route calculation cancelled") GemError.WaypointAccess -> Log.e("Routing", "Cannot access waypoint") else -> Log.e("Routing", "Error: $errorCode") } } ) // Calculate the route val result = routingService.calculateRoute(waypoints) // Cancel route calculation if needed // routingService.cancelRoute() ``` --- ## NavigationService - Turn-by-Turn Navigation The `NavigationService` provides real-time turn-by-turn navigation with instruction updates, voice guidance events, and route recalculation capabilities. ```kotlin import com.magiclane.sdk.routesandnavigation.NavigationService import com.magiclane.sdk.routesandnavigation.NavigationListener import com.magiclane.sdk.core.ProgressListener import com.magiclane.sdk.core.GemError val navigationService = NavigationService() // Create navigation listener for events val navigationListener = NavigationListener.create( onNavigationInstructionUpdated = { instruction -> // Called periodically (~1 second) with navigation updates val turnText = instruction.nextTurnInstruction val followRoad = instruction.followRoadInstruction val distanceToTurn = instruction.timeDistanceToNextTurn?.totalDistance Log.d("Nav", "Turn: $turnText, Distance: ${distanceToTurn}m") // Get turn image for UI val turnImage = instruction.turnDetails?.abstractGeometryImage?.asBitmap() }, onNavigationStarted = { Log.d("Nav", "Navigation started") }, onNavigationSound = { sound -> // Play TTS instruction // sound.play() }, onWaypointReached = { landmark -> Log.d("Nav", "Reached waypoint: ${landmark.name}") }, onDestinationReached = { landmark -> Log.d("Nav", "Destination reached: ${landmark.name}") }, onRouteUpdated = { route -> Log.d("Nav", "Route was recalculated") }, onBetterRouteDetected = { route, travelTime, delay, timeGain -> Log.d("Nav", "Better route found, saves ${timeGain}s") // Accept better route: navigationService.acceptBetterRoute() }, onNavigationError = { error -> when (error) { GemError.NoError -> Log.d("Nav", "Navigation completed") GemError.Cancel -> Log.d("Nav", "Navigation cancelled") else -> Log.e("Nav", "Navigation error: ${GemError.getMessage(error)}") } }, onNotifyStatusChange = { status -> // ENavigationStatus: Running, WaitingRoute, WaitingGPS, WaitingReturnToRoute Log.d("Nav", "Status: $status") } ) // Progress listener for operation tracking val progressListener = ProgressListener.create( onStarted = { Log.d("Nav", "Starting navigation...") }, onCompleted = { _, _ -> Log.d("Nav", "Operation completed") } ) // Start navigation on a computed route fun startNavigation(route: Route) { val error = navigationService.startNavigation( route, navigationListener, progressListener ) if (error == GemError.NoError) { // Set camera to follow position during navigation mapView?.followPosition() } } // Start simulation for testing (no GPS required) fun startSimulation(route: Route) { mapView?.presentRoute(route) navigationService.startSimulation( route, navigationListener, progressListener, speedMultiplier = 2.0f // 2x speed ) mapView?.followPosition() } // Stop navigation or simulation fun stopNavigation() { navigationService.cancelNavigation(navigationListener) } ``` --- ## ContentStore - Offline Maps and Content The `ContentStore` manages downloadable offline content including maps, voices, and styles for use without internet connectivity. ```kotlin import com.magiclane.sdk.content.ContentStore import com.magiclane.sdk.content.EContentType import com.magiclane.sdk.core.GemError val contentStore = ContentStore() // List available online maps val (errorCode, progressListener) = contentStore.asyncGetStoreContentList( EContentType.RoadMap, onStarted = { Log.d("Content", "Fetching content list...") }, onProgress = { progress -> Log.d("Content", "Progress: $progress%") }, onCompleted = { items, error, hint -> if (error == GemError.NoError) { items?.forEach { item -> Log.d("Content", "Map: ${item.name}, Size: ${item.totalSize} bytes") Log.d("Content", "Status: ${item.status}") } } else { Log.e("Content", "Failed: ${GemError.getMessage(error)}") } } ) // List locally downloaded content val localMaps = contentStore.getLocalContentList(EContentType.RoadMap) localMaps?.forEach { item -> Log.d("Content", "Local map: ${item.name}, Downloaded: ${item.isCompleted()}") } // Download a content item fun downloadMap(item: ContentStoreItem) { val error = item.asyncDownload( allowChargedNetworks = false, // Only download on WiFi onProgress = { progress -> Log.d("Download", "Progress: $progress%") }, onCompleted = { error, hint -> if (error == GemError.NoError) { Log.d("Download", "Download completed: ${item.name}") } else { Log.e("Download", "Download failed: ${GemError.getMessage(error)}") } } ) } // Pause and resume download fun pauseDownload(item: ContentStoreItem) { item.pauseDownload() } fun resumeDownload(item: ContentStoreItem) { item.asyncDownload( onCompleted = { error, _ -> /* handle completion */ } ) } // Delete downloaded content fun deleteMap(item: ContentStoreItem) { if (item.canDeleteContent()) { val error = item.deleteContent() if (error == GemError.NoError) { Log.d("Content", "Deleted: ${item.name}") } } } // Filter content by country val countries = arrayListOf("USA", "CAN") val (filterError, filterProgress) = contentStore.asyncGetStoreFilteredList( EContentType.RoadMap, countries, area = null, // Optional geographic filter onCompleted = { filteredItems, error, hint -> // Handle filtered results } ) ``` --- ## Landmarks and LandmarkStore Landmarks represent points of interest with rich metadata. LandmarkStores provide persistent storage and organization for landmarks. ```kotlin import com.magiclane.sdk.places.Landmark import com.magiclane.sdk.places.LandmarkStoreService import com.magiclane.sdk.places.ContactInfo import com.magiclane.sdk.core.EContactInfoFieldType // Create a landmark val landmark = Landmark("Coffee Shop", 48.8584, 2.2945) // Add contact info val contactInfo = ContactInfo() contactInfo.addField(EContactInfoFieldType.Phone, "+33123456789", "Main") contactInfo.addField(EContactInfoFieldType.Email, "contact@shop.com", "Business") landmark.contactInfo = contactInfo // Create a landmark store (persistent) val (store, errorCode) = LandmarkStoreService().createLandmarkStore("MyFavorites") // Add landmark to store store?.addLandmark(landmark) // Retrieve landmarks from store val landmarks = store?.getLandmarks() landmarks?.forEach { lm -> Log.d("Store", "Landmark: ${lm.name} at ${lm.coordinates}") } // Get predefined map landmark stores val storeService = LandmarkStoreService() val mapPoisStore = storeService.getLandmarkStoreById(storeService.mapPoisLandmarkStoreId) val mapAddressStore = storeService.getLandmarkStoreById(storeService.mapAddressLandmarkStoreId) // Browse large landmark stores efficiently val browseSession = store?.createLandmarkBrowseSession( LandmarkBrowseSessionSettings().apply { orderBy = ELandmarkOrder.Name descendingOrder = false nameFilter = "Coffee" } ) val count = browseSession?.landmarksCount val firstTen = browseSession?.getLandmarks(0, 10) // Update a landmark landmark.name = "Updated Coffee Shop" store?.updateLandmark(landmark) // Remove landmark store?.removeLandmark(landmark) // Remove entire store val storeId = store?.id ?: return store?.release() LandmarkStoreService().removeLandmarkStore(storeId) ``` --- ## Display Routes on Map Configure how routes are displayed on the map with customizable render settings including colors, width, and traffic visualization. ```kotlin import com.magiclane.sdk.routesandnavigation.RouteRenderSettings import com.magiclane.sdk.core.Rgba // Display a single route mapView?.presentRoute(route) // Display route with custom rendering val renderSettings = RouteRenderSettings().apply { innerColor = Rgba(0, 122, 255, 255) // Route line color outerColor = Rgba(0, 80, 180, 255) // Border color traveledInnerColor = Rgba(128, 128, 128, 255) // Traveled portion } mapView?.presentRoute(route, renderSettings) // Display multiple routes val routesList = arrayListOf(route1, route2) mapView?.presentRoutes(routesList) // Hide routes mapView?.hideRoutes() // Center map on route mapView?.centerOnRoute(route) // Get route segments and instructions route.segments?.forEachIndexed { segmentIndex, segment -> Log.d("Route", "Segment $segmentIndex:") segment.instructions?.forEach { instruction -> Log.d("Route", " Turn: ${instruction.turnInstruction}") Log.d("Route", " Follow: ${instruction.followRoadInstruction}") Log.d("Route", " Distance: ${instruction.timeDistanceToNextTurn?.totalDistance}m") // Check for special road conditions if (instruction.isTollRoad) Log.d("Route", " Toll road") if (instruction.isFerry) Log.d("Route", " Ferry crossing") } } ``` --- ## Position Service and Location Tracking The `PositionService` provides device location tracking with support for live GPS data or custom position sources. ```kotlin import com.magiclane.sdk.sensordatasource.PositionService import com.magiclane.sdk.sensordatasource.PositionListener // Enable live GPS data source PositionService.setLiveDataSource() // Get current position val currentPosition = PositionService.position Log.d("Position", "Lat: ${currentPosition?.coordinates?.latitude}") Log.d("Position", "Lon: ${currentPosition?.coordinates?.longitude}") // Listen for position updates val positionListener = PositionListener.create( onPositionUpdated = { position -> Log.d("Position", "Updated: ${position.coordinates}") } ) PositionService.addListener(positionListener) // Follow position on map mapView?.followPosition() // Customize follow position behavior val followPrefs = mapView?.preferences?.followPositionPreferences followPrefs?.apply { // Configure camera behavior during position following } // Stop following position mapView?.stopFollowingPosition() // Remove listener when done PositionService.removeListener(positionListener) ``` --- ## Alarms and Speed Warnings The `AlarmService` provides notifications for speed limits, landmarks, overlays, and geographic areas. ```kotlin import com.magiclane.sdk.routesandnavigation.AlarmService import com.magiclane.sdk.routesandnavigation.AlarmListener val alarmService = AlarmService() val alarmListener = AlarmListener.create( onSpeedLimit = { speedLimit, insideCity -> Log.d("Alarm", "Speed limit: ${speedLimit}km/h, City: $insideCity") }, onHighSpeed = { currentSpeed, speedLimit, insideCity -> Log.d("Alarm", "Speeding! Current: $currentSpeed, Limit: $speedLimit") }, onNormalSpeed = { insideCity -> Log.d("Alarm", "Speed normalized") }, onLandmarkAlert = { landmark, distance, direction -> Log.d("Alarm", "Approaching: ${landmark.name}, Distance: ${distance}m") } ) // Start alarm service alarmService.startAlarm(alarmListener) // Configure speed warning threshold (km/h over limit) alarmService.speedWarningThreshold = 10 // Stop alarm service alarmService.stopAlarm(alarmListener) ``` --- ## Gradle Configuration Add the Magic Lane Maven repository and SDK dependency to your project. ```kotlin // settings.gradle.kts dependencyResolutionManagement { repositories { google() mavenCentral() maven { url = uri("https://developer.magiclane.com/packages/android") } } } // app/build.gradle.kts dependencies { implementation("com.magiclane:maps-kotlin:1.8.5") } ``` ```xml <!-- AndroidManifest.xml --> <manifest> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <application> <!-- API Key configuration --> <meta-data android:name="com.magiclane.sdk.token" android:value="YOUR_API_KEY"/> </application> </manifest> ``` --- The Magic Lane Maps SDK for Android provides a complete solution for building navigation and mapping applications. The primary use cases include turn-by-turn navigation apps, fleet management systems, location-based services, and any application requiring offline mapping capabilities. The SDK's architecture allows for seamless integration with existing Android projects through standard Gradle dependencies, with minimal boilerplate code required to display maps and calculate routes. Integration patterns typically involve initializing the SDK in your Application or main Activity, adding a `GemSurfaceView` to your layout for map display, and using the service classes (`SearchService`, `RoutingService`, `NavigationService`, `ContentStore`) for specific functionality. All major operations are asynchronous with callback-based completion handlers, making them suitable for modern Android development practices. The SDK supports both online mode with real-time data and offline mode with pre-downloaded content, providing flexibility for applications that need to work in areas with limited connectivity.