Visit our reference document site to get an overview of what the MapsIndoors SDK offers.
MapsIndoors.setBaseMapTilesEnabled(enabled, apiKey),
MapsIndoors.synchronizeBaseMapTiles(onProgress?, apiKeys?) and
MapsIndoors.isBaseMapCachingSupported() - so the same code runs against either map provider.
The Google Maps SDK exposes no per-region offline tile API, so isBaseMapCachingSupported()
resolves false and synchronizeBaseMapTiles rejects with
MPError.baseMapCachingNotSupported rather than silently doing nothingMPDirectionsRenderer.setOptions(options) and getOptions(), which style a rendered route from a
single MPDirectionsRendererOptions object - line color, opacity, weight and MPStrokeStyle, the
background halo, the animated overlay and its MPRouteAnimationType, a repeating
MPRouteStampType stamp with its MPRouteArrowStyle, MPRouteMarkerDisplayRule styling for the
route's start and end markers, per connector MPLegBoundaryIcons and 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
supersedes setPolylineColors and setAnimatedPolyline, which are now deprecatedMPDirectionsRenderer.finishGuidance(usagePercentage?), which signals that guidance on the
current route has finished, optionally supplying how much of the route was travelledresolveLanguageTag(tag, availableLanguages) and normalizeLanguageTag(tag), for turning a
device locale into the exact language tag a solution publishes before calling
MapsIndoors.setLanguage. resolveLanguageTag('zh-Hant-TW', solution.availableLanguages)
returns 'zh-Hant'MPSolution.resolveLanguage(language), the same lookup against that solution's own languagesMPSolution.hasLanguage now 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-CN matches zh-Hans, zh-TW
matches zh-Hant), and a more specific tag falls back to a less specific one (en-US matches
en). It stays deliberately strict about ambiguity: bare zh does not match a solution that
publishes only zh-Hans and zh-Hant, because there is no way to tell which script is wantedMapsIndoors.setLanguage documents what its returned boolean means on each platform. On Android
it is false for 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 with
getLanguage to confirm a change took effectMapsIndoors.setLanguage resolves false for an empty language tag without calling into the
native SDK, matching Android's own precondition. iOS would otherwise accept it and store an
empty languageJSONDecoder is not polymorphic and the SDK's internal mp_polygon accessors are nil on a
freshly decoded value. MPPolygon.contains therefore always answered false, getArea always
0, and distanceToClosestEdge resolved undefined despite being typed Promise<number>. The
concrete geometry type is now decoded from the GeoJSON type discriminator, as on Android, so
multi-polygon geometry works by constructionMPLocation
holds an MPIcon whose layer holds an android.graphics.Bitmap, and the buffer behind a Bitmap
carries a Cleaner that 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 themMapsIndoors.setLanguage always resolved null on iOS, despite being typed Promise<boolean>.
It now resolves the native SDK's real result, as it already did on AndroidMapsIndoors.getAvailableLanguages and getDefaultLanguage rejected with an unparseable error
on iOS when called before the solution had loaded, so the MPError never reached the caller.
Both now reject with an MPError, as they already did on AndroidMapsIndoors.getDefaultLanguage resolved null on Android when no solution was loaded, despite
being typed Promise<string>. It now rejects with an MPError, matching iOSMapsIndoors.getSolution resolved null on Android whenever no solution was loaded - including
the moment right after a language change, which reloads the solution. Callers either crashed in
JSON.parse or got a solution whose availableLanguages was undefined, so hasLanguage
answered false for every tag. It now rejects with an MPError, matching iOSMapsIndoors.getLocations discarded a native rejection instead of propagating it, then failed
in JSON.parse with "Unexpected character: u". The real error now reaches the callerMPError.parse threw a SyntaxError when 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 textexpo-build-properties' deploymentTarget if you
use Expo - see iOSreact-native-screens' native stackonLowMemory() not being forwarded to the underlying Google Maps MapViewsetPolylineColors to MPDirectionsRenderer to allow customizing the foreground and background color of the displayed route$ npm install @mapsindoors/react-native-maps-indoors-google-maps
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!
...
end
iOS/MyApp/AppDelegate.m.#import "GoogleMaps/GoogleMaps.h" on the class.[GMSServices provideAPIKey:@"YOUR GOOGLE MAPS API KEY HERE"];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
To get the underlying Google Map to function, you need to perform the following steps:
android/app/src/main/res/value.google_maps_api_key.xml.YOUR_KEY_HERE with your Google Maps API key.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>
The plugin Gradle project has trouble resolving the MapsIndoors dependency, so to ensure that it is resolved correctly, do the following:
build.gradle.maven { url 'https://maven.mapsindoors.com/' } to allprojects/repositories after mavenCentral()
allprojects {
repositories {
google()
mavenCentral()
maven { url 'https://maven.mapsindoors.com/' }
}
}
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"
}
]
]
}
}
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,
}}
/>
);
}
...
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);
};
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);
}
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);
}
Generated using TypeDoc