## version-6.0
### API Reference
# API Reference
## Latest Version
Mappedin SDK for React Native v6.0.0-alpha.12
## Previous Versions
### Getting Started
# Getting Started
>
>
Mappedin SDK for React Native enables integration of Mappedin's indoor mapping and navigation capabilities into React Native applications. This SDK provides a native wrapper around Mappedin's web-based mapping technology using a WebView for cross-platform compatibility. Mappedin SDK for React Native uses the `react-native-webview` package to display the map.
This getting started guide demonstrates how to start a project using Mappedin SDK for React Native. Following this guide results in a working demo with a map that you can interact with (zoom, pan, rotate etc).
## Requirements
Mappedin SDK for React Native v6 supports the following:
- React 16.8.0+
- React Native 0.60.0+
- React Native WebView 11.0.0+
- Expo 39+
> Mappedin SDK for React Native v6 is available as @mappedin/react-native-sdk@alpha in NPM.
> You can find the Mappedin React Native demo application on Github at https://github.com/mappedin/react-native
## Coding with AI
Mappedin SDK for React Native provides an llms-mappedin-react-native.txt file that can be used to help with coding when using Large Language Models (LLMs).
## MapView
The MapView component contains the DOM element of the 3D map and the context wrapper for control of the map. Components which reference the 3D map must be children of the `MapView` component to have access to the context.
```tsx
import React from "react";
import { View, StyleSheet } from "react-native";
import { MapView } from "@mappedin/react-native-sdk";
// See Demo API key Terms and Conditions
// Demo Key & Maps: https://developer.mappedin.com/docs/demo-keys-and-maps
const App = () => {
return (
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#f0f8ff",
},
});
export default App;
```
## useMap
The useMap hook returns an object containing an instance of MapViewControl and Mappedin.MapData. This hook can be used after the map has been loaded and rendered. `useMap` must be used in a child component of MapView. Use the MapViewControl instance to access the map's methods and properties.
```tsx
function MyCustomComponent() {
const { mapView, mapData } = useMap();
return mapData.getByType('space').map(space => {
return ;
});
}
```
## useEvent
The useEvent hook enables subscribing to interactive map events and triggering a callback when they occur.
For example, the following snippet subscribes to the `click` event and updates state using the click coordinate. `Label`s are rendered based on the updated state. The `click` event contains all the interactive elements that the click action passed through.
> See full JavaScript guides about Interactivity and the Camera for more information about events.
```tsx
function MyCustomComponent() {
const { mapView, mapData } = useMap();
const [labels, setLabels] = useState([]);
useEvent('click', event => {
setLabels(prevLabels => [
...prevLabels,
{ target: event.coordinate, text: 'Hello, World!' },
]);
});
return labels.map((label, idx) => );
}
```
Other useful events include `hover`, `camera-change`, and `floor-change`. Refer to the useEvent documentation for a complete list of events.
The `hover` event is very similar to the `click` event and will contain all the interactive elements that are underneath the mouse cursor.
```tsx
useEvent('hover', event => {
console.log('hover', event);
});
```
The `camera-change` event fires when the camera is adjusted. It contains the new `bearing`, `pitch`, `zoomLevel` and camera `center` coordinate.
```tsx
useEvent('camera-change', event => {
console.log('camera-change', event.bearing, event.pitch, event.zoomLevel, event.center);
});
```
The `floor-change` event fires whenever the building floor is changed. It contains the `floor` and the `reason` that the change occurred.
```tsx
useEvent('floor-change', event => {
console.log('floor-change', event.floor, event.reason);
});
```
## Local Development
For local development, start a project using Expo. Refer to the React Native Getting Started guide for setup details. Guides are written in TypeScript (JavaScript), as the SDK is written in Typescript and uses comprehensive types.
### 1. Create a Project
> Note that Mappedin SDK for React Native version 6 is currently in an alpha state. Therefore you must append @alpha when adding the Mappedin package. Failing to do so will add the current production release of version 5, which does not support maps in the Free, Plus, Advanced or Pro tiers.
Run these shell commands to set up a new project and install Mappedin SDK for React Native.
**Create a new Expo project**
The following command will create a new Expo project with a blank Typescripttemplate.
```bash
npx create-expo-app@latest my-mappedin-app --template blank-typescript
```
### 2. Install Mappedin SDK for React Native
Using NPM:
Change to the project directory and install the Mappedin SDK for React Native.
```bash
cd my-mappedin-app
npm install @mappedin/react-native-sdk@alpha
```
Using Yarn:
```bash
cd my-mappedin-app
yarn add @mappedin/react-native-sdk@alpha
```
**Install Peer Dependencies**
This package requires the following peer dependencies:
Using NPM:
```bash
npm install react react-native react-native-webview
```
Using Yarn:
```bash
yarn add react react-native react-native-webview
```
### 3. Update App.tsx
Modify & update the contents of `App.tsx` to match the following.
```tsx title=App.tsx
import React, { useEffect } from "react";
import { View, StyleSheet } from "react-native";
import { MapView, useMap } from "@mappedin/react-native-sdk";
const MapSetup = () => {
const { mapData, mapView } = useMap();
useEffect(() => {
if (mapData && mapView) {
console.log("Map is ready!");
async function initializeMap() {
// Label all spaces.
mapView.Labels.all();
}
initializeMap();
}
}, [mapData, mapView]);
return null;
};
// See Demo API key Terms and Conditions
// Demo Key & Maps: https://developer.mappedin.com/docs/demo-keys-and-maps
const App = () => {
return (
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#f0f8ff",
},
});
export default App;
```
## 4. Run the project
Run the project using the following command. When prompted, press `a` to run the project on Android or `i` to run the project on iOS.
The 3D rendered map can be zoomed, panned and rotated via mouse or fingers.
Using NPM:
```bash
npm run start
```
Using Yarn:
```bash
yarn start
```
An example of a React Native application that showcases many features of Mappedin SDK for React Native can be found in the Mappedin React Native Github Repository.
## Create a Key & Secret
## Authenticating with a Bearer Token
Mappedin SDK for React Native can also be authenticated with a short lived bearer token. This can be used to prevent exposing an API key and secret by generating a token on the server side. The server can securely store the API key and secret, allowing the client to use the token to authenticate with Mappedin SDK for React Native.
To do so, make a request to the API Key REST endpoint sending the API key and secret. The following TypeScript example shows how to do this using a fetch request. Additional examples can found in the API Key REST documentation.
```ts
async function getAccessToken(): Promise {
// See Trial API key Terms and Conditions
// https://developer.mappedin.com/docs/demo-keys-and-maps
const response = await fetch('https://app.mappedin.com/api/v1/api-key/token', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
key: 'YOUR_KEY',
secret: 'YOUR_SECRET',
}),
});
const data: TokenResponse = await response.json();
return data.access_token;
}
```
The API Key REST endpoint will return JSON that contains the bearer token.
```json
{
"access_token": "…",
"expires_in": 172800
}
```
The bearer token can then be used to authenticate with Mappedin JS as shown in the following example.
```tsx
```
## Optimizing User Interface Performance
To optimize performance and avoid unnecessary re-renders, it's important to use React's memoization techniques. Rendering a MapView can be resource-intensive, especially when dealing with complex maps that include many components. Ensure that components only re-render when necessary, and avoid patterns that trigger cascading re-renders in sub-components.
Avoid defining component properties inline—this can lead to new references on every render. Instead, define them as constants, memoized callbacks (useCallback), or memoized values (useMemo) when appropriate.
## Debug Mode
Use Debug Mode to get a closer look at how various map components behave and interact. Here's how to enable it:
### 1. Enable Debug Mode
To activate the debug interface, call the following function in your code:
```ts
mapView.enableDebug();
```
MapViewControl.enableDebug displays a panel on the right side of the map, revealing several tools and controls for direct interaction with the map's elements.
### 2. Navigating the Debug Panel
The debug panel provides access to a variety of controls:
**Geometry Controls**
- Adjust individual geometry settings, such as color, opacity, visibility. These controls make it easy to see how different elements respond to changes.
**Interactivity**
- Use toggles to turn interactivity on/off
- Change colors and hover effects to highlight specific areas
**Scene Controls**
- Manage the overall scene settings, such as scaling, positioning, and group management. Toggle the visibility of groups or containers within the scene
- Adjust padding, scale, and watermark positioning
- Markers & Labels — Add, remove, or edit markers and labels directly through the panel
**Camera Controls**
- Fine-tune camera settings, including zoom levels, pitch, and center position
- Set minimum and maximum zoom levels
- Adjust the focus to a specific area or level
!enable debug
### Images, Textures & Colors
# Images, Textures & Colors
>
>
!Images and Textures
Images, textures and colors can enhance the fidelity of an indoor map. They can be used to add custom branding, highlight important features, or provide additional information to users. Images can be placed on any Mappedin.IAnchorable target on the map and given a `verticalOffset` to control the height at which the image is displayed. Textures can be applied to the top or sides of a Mappedin.MapObject, Mappedin.Space, Mappedin.Door or Wall.
## Requirements & Considerations
JPEG and PNG images are supported for both images and textures. It's important to consider the size of all unique image files displayed on a map at one time. Using many unique images may cause instability on mobile devices with limited GPU memory. Mappedin JS will cache and reuse images that have the same URL, resulting in reduced memory usage. The following calculations illustrates how much memory is used for a given image:
**Formula:** `width * height * 4 bytes/pixel = memory used`
**512 x 512 Pixel Image:** `512px * 512px * 4 bytes/pixel = 1MB`
**4096 x 4096 Pixel Image:** `4096px * 4096px * 4 bytes/pixel = 64MB`
## Creating Images for Spaces
When creating images to be used as the floor of a space, it's important that the image dimensions match the space to avoid it leaking into adjacent spaces. An SVG export of the map can be useful to determine the correct dimensions. The following steps demonstrate how to create an image that matches a space's dimensions using Figma. Similar steps could be used in other image editing tools that support the SVG format.
1. Log into app.mappedin.com and select the map you want to create an image for.
2. Click on the **Download** button and choose `Download as SVG`.
3. Import the SVG into Figma (**File** > **Place Image**).
4. Select the geometry to create the image for by clicking near the center of it (not the edge).
5. Choose **File** > **Place** Image to place the image you want to use as the floor.
6. Click the geometry to fill.
7. Click **Export** (bottom right).
8. Choose format (PNG or JPEG), size and export.
The exported image should match the dimensions of the space.
## Images
The Mappedin.Images class is accessed through MapViewControl.Images and used to add and remove images to and from the map. Images can be placed on any Mappedin.IAnchorable target. TAddImageOptions is used to configure the image and specifies its width, height, rotation, vertical offset and whether the image is rotated to face the camera. The following example places an image on a Space named "Arena".
```ts
const IMAGE_URL = 'https://x6ccjn.csb.app/arena-floor.png';
const arenaFloor = mapData.getByType('space').find((space) => space.name === 'Arena');
// Configure the images size and rotation.
// Using an offset of 0.1 to place it just above the map's floor.
// Use pixelsToMeters to convert pixels to meters. This value will vary based on the map size.
const pixelsToMeters = 0.0617;
const controller: Mappedin.TAddImageOptions = {
width: 1014 * pixelsToMeters,
height: 448 * pixelsToMeters,
rotation: 121,
verticalOffset: 1,
flipImageToFaceCamera: false,
};
// Add the default image to the arena floor.
mapView.Images.add(arenaFloor, IMAGE_URL, controller);
```
## Textures & Colors
Walls, doors, floors and objects can be given textures or colors, which can be applied individually to the top or sides. The Mappedin.TGeometryState type is used to configure the texture and color, which is applied by calling MapViewControl.updateState.
When applying textures to walls it is important to set Mappedin.TShow3DMapOptions.shadingAndOutlines to false in the MapView's MapViewProps.options. This will prevent lines from being drawn between the top and side textures.
Be sure to review the Requirements & Considerations section before applying textures.
### Doors
The top and sides of a door can be given textures or colors. The example below demonstrates how to set the color of all interior and exterior doors. Doors can also be made visible on an individual basis by passing in a Mappedin.Door object to MapViewControl.updateState().
```ts
//Make interior doors visible, sides brown and top yellow.
mapView.updateState(Mappedin.DOORS.Interior, {
visible: true,
color: 'brown',
topColor: 'yellow',
opacity: 0.6,
});
//Make exterior doors visible, sides black and top blue.
mapView.updateState(Mappedin.DOORS.Exterior, {
visible: true,
color: 'black',
topColor: 'blue',
opacity: 0.6,
});
```
### Objects
Objects can be given textures or colors, which can be applied individually to the top and sides. The following example demonstrates how to set the texture of the side and color of the top of all objects.
```ts
mapData.getByType('object').forEach((object: Mappedin.MapObject) => {
mapView.updateState(object, {
texture: {
url: 'https://example.com/object-side-texture.png',
},
topColor: '#9DB2BF',
});
});
```
### Spaces
The floor of a space can be given a texture or color. When creating an image for the floor of a space, it's important that the image dimensions match the space to avoid it leaking into adjacent spaces. Refer to the Creating Images for Spaces section for more information. The following example demonstrates how to set the texture of the floor for all spaces.
```ts
mapData.getByType('space').forEach((space: Mappedin.Space) => {
mapView.updateState(space, {
topTexture: {
url: FLOOR,
},
});
});
```
### Walls
The exterior and interior walls of a building can be targeted with different textures and colors. The following example demonstrates how to set the texture of an exterior wall and the colors of interior walls. Note that both types of walls support textures and colors.
```ts
// Disable shadingAndOutlines to prevent lines from appearing between the top and side textures.
const mapView = await show3dMap(document.getElementById('mappedin-map') as HTMLDivElement, mapData, {
shadingAndOutlines: false,
});
mapView.updateState(Mappedin.WALLS.Exterior, {
texture: {
url: 'https://example.com/wall-side-texture.png',
},
topTexture: {
url: 'https://example.com/wall-top-texture.png',
},
});
mapView.updateState(Mappedin.WALLS.Interior, {
color: '#526D82',
topColor: '#27374D',
});
```
### Interactivity
# Interactivity
>
>
This guide explains how to enhance a map's interactivity by making components clickable. Interactivity can greatly improve the user experience and user engagement with a map.
!Mappedin JS v6 Interactivity
## Interactive Spaces
Spaces can be set to interactive to allow a user to click on them. When interactivity is enabled for a space, it enables a hover effect that highlights the space when the cursor is moved over the space.
The following code enables interactivity for all spaces:
```ts
// Set each space to be interactive.
mapData.getByType('space').forEach((space: Mappedin.Space) => {
mapView.updateState(space, {
interactive: true,
});
});
```
## Hover Interactivity
When interactivity is enabled for a space, it enables a hover effect that highlights the space when the cursor is moved over the space. The highlight color can also be customised to match the style of the map.
The following code sample enables interactivity for all spaces on the map and sets the hover color to red.
```ts
// Set each space to be interactive and its hover color to red.
mapData.getByType('space').forEach((space: Mappedin.Space) => {
mapView.updateState(space, {
interactive: true,
hoverColor: 'red',
});
});
```
## Interactive Labels
Labels added to the map can be set to interactive to allow users to click on them and have the click event captured by an app. The code sample below adds a label to each space with a name and sets the label's interactivity to true.
```tsx
// Get all spaces with names
const spaces = mapData.getByType('space').filter(space => space.name);
// Label all spaces with its space name and make them interactive.
return (
<>
{spaces.map(space => (