@mapsindoors/react-native-maps-indoors-google-maps
v2.9.0
Published
React Native MapsIndoors component with google
Downloads
843
Readme
react-native-maps-indoors-google-maps
Documentation
Visit our reference document site to get an overview of what the MapsIndoors SDK offers.
Changelog
[2.9.0] - 2026-09-17
Added
Offline base map tiles support [Mapbox]
- The offline base-map tile API added to the Mapbox package -
MapsIndoors.setBaseMapTilesEnabled(enabled, apiKey),MapsIndoors.synchronizeBaseMapTiles(onProgress?, apiKeys?)andMapsIndoors.isBaseMapCachingSupported()- so the same code runs against either map provider. The Google Maps SDK exposes no per-region offline tile API, soisBaseMapCachingSupported()resolvesfalseandsynchronizeBaseMapTilesrejects withMPError.baseMapCachingNotSupportedrather than silently doing nothing
Improved DirectionsRenderer
MPDirectionsRenderer.setOptions(options)andgetOptions(), which style a rendered route from a singleMPDirectionsRendererOptionsobject - line color, opacity, weight andMPStrokeStyle, the background halo, the animated overlay and itsMPRouteAnimationType, a repeatingMPRouteStampTypestamp with itsMPRouteArrowStyle,MPRouteMarkerDisplayRulestyling for the route's start and end markers, per connectorMPLegBoundaryIconsand the camera's fit-bounds max zoom. The 3D elevation options are accepted but ignored, Google Maps keeps the route flat. Each option resolves on its own - the value set here, then the solution level default from the CMS, then the SDK's built-in default - so options left out are inherited rather than reset. This supersedessetPolylineColorsandsetAnimatedPolyline, which are now deprecatedMPDirectionsRenderer.finishGuidance(usagePercentage?), which signals that guidance on the current route has finished, optionally supplying how much of the route was travelled
Enhanced Language support
resolveLanguageTag(tag, availableLanguages)andnormalizeLanguageTag(tag), for turning a device locale into the exact language tag a solution publishes before callingMapsIndoors.setLanguage.resolveLanguageTag('zh-Hant-TW', solution.availableLanguages)returns'zh-Hant'MPSolution.resolveLanguage(language), the same lookup against that solution's own languages
Changed
- Updated the MapsIndoors Android SDK to 4.22.0 and the iOS SDK to 4.20.0, the releases that carry the base-map tile cache
MPSolution.hasLanguagenow matches language tags the way the native SDKs do, instead of requiring an exact string. Casing is ignored, the ICU underscore form is accepted (zh_Hans), legacy region-only Chinese tags resolve to their script (zh-CNmatcheszh-Hans,zh-TWmatcheszh-Hant), and a more specific tag falls back to a less specific one (en-USmatchesen). It stays deliberately strict about ambiguity: barezhdoes not match a solution that publishes onlyzh-Hansandzh-Hant, because there is no way to tell which script is wantedMapsIndoors.setLanguagedocuments what its returned boolean means on each platform. On Android it isfalsefor a language the solution does not have, and also while the SDK is still loading or synchronizing - in which case the change is queued rather than lost. On iOS it reports only that the tag was accepted, with no check against the solution. Read the language back withgetLanguageto confirm a change took effectMapsIndoors.setLanguageresolvesfalsefor an empty language tag without calling into the native SDK, matching Android's own precondition. iOS would otherwise accept it and store an empty language
Fixed
- The iOS geometry helpers never decoded the polygon they were given, because
JSONDecoderis not polymorphic and the SDK's internalmp_polygonaccessors are nil on a freshly decoded value.MPPolygon.containstherefore always answeredfalse,getAreaalways0, anddistanceToClosestEdgeresolvedundefineddespite being typedPromise<number>. The concrete geometry type is now decoded from the GeoJSONtypediscriminator, as on Android, so multi-polygon geometry works by construction - Serialising SDK models to the bridge on Android walked native memory by reflection.
MPLocationholds anMPIconwhose layer holds anandroid.graphics.Bitmap, and the buffer behind a Bitmap carries aCleanerthat is linked to every other live Cleaner in the process - so the work grew with whatever the host app had allocated, not with the map data. This only showed up on physical devices with a real app around them MapsIndoors.setLanguagealways resolvednullon iOS, despite being typedPromise<boolean>. It now resolves the native SDK's real result, as it already did on AndroidMapsIndoors.getAvailableLanguagesandgetDefaultLanguagerejected with an unparseable error on iOS when called before the solution had loaded, so theMPErrornever reached the caller. Both now reject with anMPError, as they already did on AndroidMapsIndoors.getDefaultLanguageresolvednullon Android when no solution was loaded, despite being typedPromise<string>. It now rejects with anMPError, matching iOSMapsIndoors.getSolutionresolvednullon Android whenever no solution was loaded - including the moment right after a language change, which reloads the solution. Callers either crashed inJSON.parseor got a solution whoseavailableLanguageswasundefined, sohasLanguageansweredfalsefor every tag. It now rejects with anMPError, matching iOSMapsIndoors.getLocationsdiscarded a native rejection instead of propagating it, then failed inJSON.parsewith "Unexpected character: u". The real error now reaches the callerMPError.parsethrew aSyntaxErrorwhen a rejection did not carry the native SDK's JSON payload - a bridge-level or JavaScript error - replacing the real message with "JSON Parse error: Unexpected character". It now wraps such a message as an unknown error and keeps the text
2.8.0 - 2026-08-17
Changed
- Breaking: raised the minimum iOS deployment target to 16.0 (from 15.6), as required by the
MapsIndoors iOS SDK. Update your Podfile, and
expo-build-properties'deploymentTargetif you use Expo - see iOS - Breaking: raised the minimum supported React Native version to 0.75.0
- Updated MapsIndoors Android SDK to 4.18.6
- Updated MapsIndoors iOS SDK to 4.19.1
Fixed
- The map turning black after navigating away from and back to the map screen when using
react-native-screens' native stack - The map continuing to render in the background while the app was backgrounded, which wasted battery
onLowMemory()not being forwarded to the underlying Google MapsMapView
2.7.0
- Updated MapsIndoors Android SDK to 4.18.3
- Updated MapsIndoors iOS SDK to 4.17.2
- Added React Native New Architecture support (TurboModules / Fabric interop layer)
- Added
setPolylineColorstoMPDirectionsRendererto allow customizing the foreground and background color of the displayed route
Getting started
$ npm install @mapsindoors/react-native-maps-indoors-google-maps
iOS
The MapsIndoors SDK requires iOS 16.0, so make sure that your podfile is configured for iOS 16.0.
Add use_frameworks! to your Podfile target.
platform :ios, '16.0'
target 'MyApp' do
use_frameworks!
...
endProviding API key
- Navigate to
iOS/MyApp/AppDelegate.m. - Import
#import "GoogleMaps/GoogleMaps.h"on the class. - Add this code as the first line inside the application function:
[GMSServices provideAPIKey:@"YOUR GOOGLE MAPS API KEY HERE"];
Adding MapsIndoors script specific to Google Maps, to Podfile
Note from version 2.1.1 this is no longer necessary, and should be removed from the podfile if upgrading to 2.1.1
After this you should navigate into the iOS folder of your react native project and add this script to the applications Podfile: MapsIndoors podfile Post install
Android
Android Gooogle Maps Setup
To get the underlying Google Map to function, you need to perform the following steps:
- Navigate to
android/app/src/main/res/value. - Create a file in this folder called
google_maps_api_key.xml. - Copy and paste the below code snippet and replace
YOUR_KEY_HEREwith your Google Maps API key. - Add the key to your application metadata in the manifest, located at
android/app/src/main/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="google_maps_key">YOUR_KEY_HERE</string>
</resources><application>
...
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="@string/google_maps_key" />
...
</application>MapsIndoors Gradle Setup
The plugin Gradle project has trouble resolving the MapsIndoors dependency, so to ensure that it is resolved correctly, do the following:
- Navigate to the app's project level
build.gradle. - add
maven { url 'https://maven.mapsindoors.com/' }toallprojects/repositoriesaftermavenCentral()
allprojects {
repositories {
google()
mavenCentral()
maven { url 'https://maven.mapsindoors.com/' }
}
}Expo
This library implements native modules and can't be used with ExpoGO, a development build is required Development Builds.
To build and run correctly, the native ios linkage is required to be set as dynamic
(useFrameworks: "dynamic"). Project configuration can be done with the expo module
expo-build-properties.
This library includes an expo plugin to support native integration. To enable it, you need to add the configuration in your expo configuration.
// app.json
{
"expo": {
// ... your configuration
"plugins": [
[
"expo-build-properties",
{
"ios": {
"deploymentTarget": "16.0",
"useFrameworks": "dynamic"
}
}
],
[
"@mapsindoors/react-native-maps-indoors-google-maps/app.plugin.js",
{
"apiKeyAndroid": "GMAPS_ANDROID_API_KEY",
"apiKeyIOS": "GMAPS_IOS_API_KEY"
}
]
]
}
}Usage
Showing your map
This snippet shows you how to set up MapsIndoors in a React Native application.
import MapsIndoors, { MapControl, MapView } from 'react-native-maps-indoors';
...
//Function to initialize mapsindoors and mapcontrol. To load a solution and show data onto the map.
const loadMapsIndoors = () => {
//Load solution data with your api key
MapsIndoors.load('API_KEY').then(async () => {
//Create the MapControl. Which will be using the MapView of the component.
const mc = await MapControl.create(new MPMapConfig({useDefaultMapsIndoorsStyle: true}), NativeEventEmitter);
//Get a venue and move the camera to it.
let venue: MPVenue = (await MapsIndoors.getVenues()).getAll()[0];
mapControl.goTo(venue);
}
}
...
render() {
return (
<MapView
style={{
width: Dimensions.get('window').width,
height: Dimensions.get('window').height,
}}
/>
);
}
...Showing a route
const showRoute = async () => {
let point = new MPPoint(57.0580431, 9.9505475);
let point2 = new MPPoint(57.0581638, 9.9507732, 10);
var directionsService = await MPDirectionsService.create();
//Optional query parameters for the route.
directionsService.setIsDeparture(true);
directionsService.setTime(Date.now());
directionsService.setTravelMode('bicycling');
var route = await directionsService.getRoute(point, point2);
directionsRenderer = new MPDirectionsRenderer(NativeEventEmitter);
directionsRenderer.setRoute(route);
};Searching locations
This code snippet shows a function called searchForParking that takes a single argument of type MPPoint. The function uses MapsIndoors to search for locations matching the query string "parking" near the point specified, and uses the filter to only get the first 10 matches.
It mathces in the locations' descriptions, names, and external IDs to the query string. Once the search is complete, it is possible to update/get information from the locations (not specified in the code snippet).
const searchForParking = async (point: MPPoint) => {
let query = MPQuery.create({query: "parking",
near: point,
queryProperties: [MPLocationPropertyNames.description, MPLocationPropertyNames.name, MPLocationPropertyNames.externalId]});
let filter = MPFilter.create({take: 10});
let parkingLotsNearPoint = await MapsIndoors.getLocationsAsync(query, filter);
}Changing the look with DisplayRules
This code snippet shows three ways to manipulate display rules in the MapsIndoors SDK.
The hideLocationsByDefault method hides all markers that are not explicitly visible by setting the main display rule to not visible.
The showLocationsByDefault method ensures all markers are shown by setting the main display rule to visible.
The changeTypePolygonColor(String type, String color) method changes the fill color for all polygons belonging to a specific type. It gets the display rule for the specified type using getDisplayRuleByName, and sets the fill color using setPolygonFillColor.
These methods can all be used to customize the display of markers and polygons on the map.
// This method changes the main display rule to hide all markers,
// This will cause all locations/types that are not explicitly visible to be hidden.
const hideLocationsByDefault = async () => {
let mainDisplayRule = await MapsIndoors.getMainDisplayRule();
mainDisplayRule?.setVisible(false);
}
// This method changes the main display rule to show all markers,
// This will cause all locations/types that are not explicitly visible to be shown.
const showLocationsByDefault = async () => {
let mainDisplayRule = await MapsIndoors.getMainDisplayRule();
mainDisplayRule?.setVisible(true);
}
// This method changes the fill color for all polygons belonging to a specific [type]
// the color MUST be a valid hex color string.
const changeTypePolygonColor = async (type: string, color: string) => {
let typeDisplayRule = await MapsIndoors.getDisplayRuleByName(type);
typeDisplayRule?.setPolygonFillColor(color);
}