## version-6.0 ### 3D Models # 3D Models > > !3D Model Mapper ## Adding 3D Models to a Map Adding 3D models to a map can be a great way to represent landmarks to help users find key locations. They could also be used to show the location of assets or represent furniture to provide a rich indoor layout. Mappedin SDK for React Native supports models in Graphics Library Transmission Format (GLTF) and GL Transmission Format Binary (GLB) format. Models with nested meshes are not supported and should not be used. > A complete example demonstrating 3D models can be found in the Mappedin React Native Github repo: models.tsx 3D Models can be added to the map using the MapViewControl.Models.add() method. The `add` method requires a Mappedin.Coordinate to place the model and a URL of the model file. Optionally, the model's interactivity, rotation, scale and more can also be set using the `options` parameter, which accepts a Mappedin.TAddModelOptions. Models can be updated by calling the MapViewControl.updateState() method. The following code samples demonstrate adding a 3D model to the map. ```tsx ``` ```ts mapView.Models.add(coordinate, 'https://yourDomain.com/models/yourModel.glb', { interactive: true, rotation: [0, 0, 90], scale: [10, 10, 10], }); ``` ## Mappedin 3D Model Library The Mappedin 3D Assets Library is a collection of 3D models that can be used to represent landmarks, assets, and furniture on a map. It is optimized for use with Mappedin SDKs. These models are used in the 3D Model Mapper tool, which allows you to place models on a map and customize their appearance. ### Installation The Mappedin 3D Assets Library is available as an npm package available at https://www.npmjs.com/package/@mappedin/3d-assets. It can be installed using the following commands: **NPM**: ```bash npm install @mappedin/3d-assets ``` **Yarn**: ```bash yarn add @mappedin/3d-assets ``` ### Usage This package provides two ways to use the 3D assets: 1. Self-hosted GLB files (Recommended). 2. Direct base64 model imports. #### Self-hosted GLB files (Recommended) The `/binary` directory contains GLB files that can be self hosted on your own server. This method is recommended as it provides: - 30% smaller download size - No runtime overhead - Better caching control ```ts // Example usage with self-hosted GLB const coordinate = mapView.createCoordinate(45, -75); mapView.Models.add(coordinate, 'https://your-domain.com/assets/model.glb'); ``` #### Direct Base64 Imports For convenience, models can be imported directly as base64 strings. This method is easier to set up but comes with a larger bundle size. ```ts // Import specific models (supports tree-shaking) import { bed, chair } from '@mappedin/3d-assets/inline'; // Or import individual models import plant from '@mappedin/3d-assets/inline/plant_1'; // Usage with MapView const coordinate = mapView.createCoordinate(45, -75); mapView.Models.add(coordinate, bed); ``` This package supports tree-shaking when using direct imports. Only models explicitly imported will be included in the final bundle. ```ts // Only the bed model will be included in the bundle import { bed } from '@mappedin/3d-assets/inline'; ``` ### Example The 3D Model Mapper can be used to place models from the Mappedin 3D Assets Library on a map. Once placed, the model's location details can be exported to a JSON file that can be used when adding models to a map in an app. The Using the 3D Model Export In Other Projects section contains an interactive example that demonstrates using the exported JSON file to add 3D models. ### Model List The Mappedin 3D Assets Library contains the following models. Each model's default blue color can be customized when adding it to the map. Bathtub Bed Bookshelf Box Cardboard Can Garbage Can Recycling Car Chair Computer Couch Couch Curved Couch Outward Curve Desk Desk Chair Dryer EV Charger Floor Lamp Fountain High Bench Hot Tub Kitchen Sink Kiosk Plant 1 Plant 2 Privacy Booth Refrigerator Round Table Self Checkout Shipping Container Shopping Shelves Stove Toilet Tree Pine Tree Pine Short Truck TV Vending Machine Washer Whiteboard Wood Stove ### Annotations # Annotations > > Map annotations add visual or textual elements to maps, providing extra information about specific locations or features. Map makers can choose from many annotations included in the Mappedin Editor to add to a map and access them using Mappedin SDK for React Native. Mappedin.Annotations are organized into the following groups. > Note that these are just a few examples of annotations, each group contains many more. | Annotation Group | Examples | | ----------------- | -------------------------------------------- | | Access Features | Keybox, roof access | | Building Sides | Alpha, bravo, charlie, delta | | Equipment Rooms | Boiler Room, Sprinkler control room | | Fire Ratings | Fire and smoke wall 1 hour, firewall 3 hours | | Fire Safety | Fire Blanket, Fire Hose Reel | | General Systems | Emergency Generator, Smoke Control Panel | | Hazards | Biohazard, Explosive | | Safety | Accessible Elevator, Eyewash Station | | Utility Shutoff | Gas Valve, Main Water Valve | | Ventilation | Chimney, Exhaust Fan | | Water Connections | Sprinkler FDC, Public Hydrant | | Water Systems | Fire Pump, Pressurized Water Tank | Incorporating annotations help provide a safer space for all. It allows users to easily locate key elements in the map. !Mappedin JS v6 Annotations The following code sample lists each Annotation.type in text form that exist on the Mappedin Demo Office Map. It reads the annotations from each floor and groups them by their Annotation.group. ```ts // Sort the floors alphabetically. const sortedFloors = mapData .getByType("floor") .sort((a, b) => (a.name > b.name ? 1 : b.name > a.name ? -1 : 0)); // Iterate through each floor and create a list of annotations. sortedFloors.forEach((floor) => { // Use the floor name as the heading. console.log("Floor Name: " + floor.name + " Annotations"); // Sort the annotation groups alphabetically. const sortedAnnotations = floor.annotations.sort((a, b) => a.group > b.group ? 1 : b.group > a.group ? -1 : 0 ); var annotationGroup = ""; // Iterate through each annotation and create a list of annotations. sortedAnnotations.forEach((annotation) => { // If the annotation group changes, log the new group name. if (annotationGroup != annotation.group) { annotationGroup = annotation.group; console.log("Annotation Group: " + annotation.group); } // Log each annotation. console.log("Annotation: " + annotation.type); }); }); ``` The output of the code sample will be similar to the following: ``` Floor Name: Level 1 Annotations Annotation Group: access-features Annotation: keybox Annotation: primary-entrance Annotation Group: equipment-rooms Annotation: electrical-transformer-room Annotation Group: fire-safety Annotation: fire-alarm-pull-station Annotation: fire-emergency-phone Annotation Group: general-systems Annotation: fire-alarm-annunciator-panel Annotation Group: safety Annotation: evacuation-chair Annotation Group: utility-shutoffs Annotation: gas-valve-general Annotation: main-water-valve Annotation Group: water-connections Annotation: fdc-general Floor Name: Level 2 Annotations Annotation: elevator-firefighter Annotation: fire-extinguisher ``` ### API Reference # API Reference ## Latest Version Mappedin SDK for React Native v6.0.0-alpha.12 ## Previous Versions ### Areas & Shapes # Areas & Shapes > > ## Areas An Mappedin.Area represents a logical region on the map. They do not represent a physical attribute like a wall or desk, but rather a region that can be used to trigger events, display information, or affect wayfinding. An area is made up of a polygon stored as a GeoJSON Mappedin.Feature, which can be accessed using Mappedin.Area.geoJSON. The Mappedin.Feature can be passed to other methods in Mappedin JS. Mappedin.Shapes.add() accepts an FeatureCollection and can be used to display one or more areas on the map. The code snippet below demonstrates how to use an `Area` to create a `Shape` and add it to the map. ```ts // Get the first area. const areas = mapData.getByType('area'); const areaGeoJSON = areas[0].geoJSON; // Create a FeatureCollection containing the Feature of the Area. const shapeFeatureCollection = { type: 'FeatureCollection', features: [ { type: areaGeoJSON.type, properties: areaGeoJSON.properties, geometry: areaGeoJSON.geometry, }, ], }; // Draw a shape of the area. mapView.Shapes.add(shapeFeatureCollection, { color: 'orange', altitude: 0.2, height: 0.1, opacity: 0.7, }); ``` Within the Mappedin Editor, it is possible to create an area and set it to be off limits for wayfinding. This means that the area will be excluded from the route calculation and directions will be rerouted around the area. This is useful for creating areas that are permanently off limits. The following image shows how a path has been routed around areas that are set to not be navigable. !Path routed around areas that are set to not be navigable At runtime, it is also possible to use an area as an exclusion zone for wayfinding. This is useful for creating areas that are temporarily off limits. Below is a code snippet that demonstrates how to use an `Area` to define a region that a wayfinding route should avoid at runtime. Refer to the Dynamic Routing section of the Wayfinding Guide for an interactive example that demonstrates clicking to set an exclusion zone. Mappedin.TDirectionZone is the type of the Mappedin.TGetDirectionsOptions.zones property that is passed to MapViewControl.getDirections, MapViewControl.getDirectionsMultiDestination() and MapViewControl.getDistance(). These zones can be used to affect the route calculation by excluding a polygon from the route. The following code snippet demonstrates how to use an `Area` to define a region that a wayfinding route should avoid. ```ts //Get all areas. const areas = mapData.getByType('area'); // Get the maintenance area. const maintenanceArea = areas.find((area: any) => area.name === 'Maintenance Area'); const maintenanceGeoJSON = maintenanceArea.geoJSON; // Create directions that route around the area. const origin = mapData.getByType('object').find(obj => obj.name === 'I3'); const destination = mapData.getByType('door').find(obj => obj.name === 'Outbound Shipments 1'); if (origin && destination && shapeFeatureCollection) { const zoneFeature = { type: maintenanceGeoJSON.type, properties: maintenanceGeoJSON.properties, geometry: maintenanceGeoJSON.geometry, }; let zones = []; zones.push({ geometry: zoneFeature as Feature, cost: Infinity, floor: mapView.currentFloor, }); const directions = mapView.getDirections(origin, destination, { zones }); if (directions) { await mapView.Paths.add(directions.coordinates, { color: 'cornflowerblue', }); } } ``` ## Shapes The Mappedin.Shapes class draws 3 dimensional shapes on top of a map. The shapes are created using GeoJSON geometry, which could be a Mappedin.Polygon, Mappedin.MultiPolygon (array of polygons) or a Mappedin.LineString. The following image shows a map with a shape drawn on top of it. !Map with a shape drawn on top of it > A complete example demonstrating shapes can be found in the Mappedin React Native Github repo: shapes.tsx Access the Shapes interface through MapViewControl using MapViewControl.Shapes. Shapes are added by calling Mappedin.Shapes.add() and removed individually by calling Mappedin.Shapes.remove() and passing in the Mappedin.Shape object to be removed. All shapes can be removed at once by calling Mappedin.Shapes.removeAll(). The following code example adds a shape after the map is first loaded. Clicking on the map removes a shape if one is present and if not, adds the shape back to the map. ```ts let shape: = mapView.Shapes.add(shapeGeometry as any, { color: "red", altitude: 0.2, height: 2, opacity: 0.7, }); mapView.on("click", async (event) => { if (shape) { mapView.Shapes.remove(shape); shape = undefined; } else { shape = mapView.Shapes.add(shapeGeometry as any, { color: "red", altitude: 0.2, height: 2, opacity: 0.7, }); } }); ``` Refer to the Security Camera Placement example in the Developer Showcase for a more advanced example that uses shapes to draw the field of view of security cameras. ### Blue Dot # Blue Dot > > The Blue Dot is a visual marker in mapping apps that shows a user's real-time location. It serves as a reference point, helping users identify their position and navigate efficiently. GPS, Wi-Fi, or other tracking technologies typically power the Blue Dot to ensure location accuracy. Mappedin SDK for React Native provides a simple way to add a Blue Dot to a map. !Blue Dot > A complete example demonstrating Blue Dot can be found in the Mappedin React Native Github repo: bluedot-multi-floor.tsx ## Enable & Disable Blue Dot With Mappedin SDK for React Native, an app can display a user's location by calling MapViewControl.BlueDot.enable(). This will display a prompt for the user to allow or deny sharing their location with the web page. If permission is given, a device's geolocation is displayed on the map as a Blue Dot. The `enable` method accepts a Mappedin.TBlueDotOptions object as a parameter, which can be used to change the color of the Blue Dot, accuracy shading and heading indicator. It also allows a developer to enable Blue Dot debug logging, set the size of the Blue Dot, indicate whether it should watch the browser's geolocation for updates and to set the timeout value used to set the Blue Dot to inactive after a period of no location updates. When no longer required, the Blue Dot can be disabled using MapViewControl.BlueDot.disable(). The following example demonstrates how to enable the Blue Dot, setting Mappedin.TBlueDotOptions parameters to customize the colors of the Blue Dot, set its timeout to 20 seconds and enable debug logging. ```ts mapView.BlueDot.enable({ color: 'tomato', debug: true, accuracyRing: { color: 'forestgreen', opacity: 0.1, }, heading: { color: 'aqua', opacity: 1, }, inactiveColor: 'wheat', timeout: 20000, }); ``` ## States The Blue Dot has a number of visual states that are used to convey information to the user. - When the Blue Dot position given to Mappedin JS has a high accuracy (accuracy value of 0), it is displayed as bright blue. !Blue Dot - A semi-transparent blue shadow is displayed underneath the Blue Dot to indicate accuracy range in meters. !Blue Dot Accuracy Range - A heading can be shown to indicate the direction the user is facing. !Blue Dot Heading - After the Mappedin.TBlueDotOptions.timeout has passed (default of 30 seconds), the Blue Dot is displayed as greyed. This indicates the user may have moved while no updates were received. !Blue Dot Timeout ## Follow Mode A user may pan the camera away and lose track of their Blue Dot position. An app may want to snap the camera to the user's location to reorient themselves. While this could be done using camera focus on, an app can also leverage Blue Dot's follow mode. Follow mode has multiple modes that are defined within Mappedin.TFollowMode, which are: - `position-only`: Camera position follows the Blue Dot's position. - `position-and-heading`: Camera position follows the Blue Dot's position. Camera bearing matches the Blue Dot's heading. - `position-and-path-direction`: Camera position follows the Blue Dot's position. Camera bearing is calculated based on the Navigation path. - `false`: Disables follow mode. ## Indoor Positioning Mappedin SDK for React Native can use the browser's Geolocation API for position updates and display a Blue Dot on the map based on the given location. For indoor environments, an indoor positioning system may be required to provide an accurate location because satellite based positioning is not available indoors and cellular based positioning may not be accurate enough for indoor navigation. Mappedin SDK for React Native can use the location provided from an indoor positioning system to display the Blue Dot. An example of an indoor positioning system is the Apple Maps Program, which provides a location service for indoor use. A Mappedin Map can be exported to IMDF format and imported into the Apple Maps Program. For more information refer to the Mappedin IMDF Export Page. For development purposes, indoor positions can be simulated using Chrome Developer Tools or by using pre-generated location data. The MapViewControl.BlueDot.update() method can be used to update the Blue Dot's position on the map. It accepts a Mappedin.TBlueDotPositionUpdate that can set the `latitude`, `longitude`, `accuracy` `heading` and `floorOrFloorId` of the Blue Dot. All parameters of `TBlueDotPositionUpdate` are required, however it is possible to set individual parameters to override one or more coming from the browser's geolocation API. To do so provide values for parameters the app wishes to override and use `device` as the value of those parameters that should not be overridden. For example an app may wish to use the browser's Device Orientation API to provide the heading of the Blue Dot and leave the latitude and longitude to be provided by the browser's geolocation API. The following JSON object represents a Mappedin.TBlueDotPositionUpdate that overrides `heading` and uses the browser's geolocation API for the remaining parameters. ```JSON { "accuracy": 'device', "floorOrFloorId": 'device', "latitude": 'device', "longitude": 'device', "heading": 90 } ``` ## Events Blue Dot fires events that can be used to respond to changes to its position, state and errors. The data structure of these events are defined in Mappedin.TBlueDotEvents. The following events are available: - `blue-dot-error`: Fired when an error occurs. - `blue-dot-follow-change`: Fired when the Blue Dot's follow mode changes. - `blue-dot-position-update`: Fired when Blue Dot's position is updated. - `blue-dot-state-change`: Fired when Blue Dot's state changes. ### Blue Dot Position Update The `blue-dot-position-update` event is fired when the Blue Dot's position is updated. It provides the coordinate, floor, accuracy and heading from the last position update. ```ts useEvent('blue-dot-position-update', (event: Mappedin.TBlueDotEvents) => { console.log('blue-dot-position-update', event.coordinate, event.floor, event.accuracy, event.heading); }); ``` ### Blue Dot State Change The `blue-dot-state-change` event is fired when Blue Dot state changes. It provides the new state of the Blue Dot and the action that caused the state change. Actions are defined in Mappedin.TBlueDotAction and states in Mappedin.TBlueDotState. The states pertain to how the Blue Dot is displayed on the map. Refer to the Blue Dot States section above for images of each state. ```ts useEvent('blue-dot-state-change', (event: Mappedin.TBlueDotEvents) => { console.warn('blue-dot-state-change', event.state, event.action); }); ``` ### Blue Dot Error The `blue-dot-error` event is fired when an error occurs. It provides the error as a GeolocationPositionError object. ```ts useEvent('blue-dot-error', (event: Mappedin.TBlueDotEvents) => { console.error('blue-dot-error', event); }); ``` ## Generating Test Location Data The Mappedin Blue Dot Location Generator can be used to generate location data for testing. To create test data, load a map in the generator app and choose a Start and End space. Click Generate to generate the data and observe the Blue Dot on the map using the generated data for its position. Press the Download button to download the location data in JSON format. The data can be customized by specifying the parameters below: - **Venue Settings**: Add in a key, secret and map ID to load a different map. - **Environment**: Whether to load the map from Mappedin's North American or European environment. By default, maps exist in the North American environment. - **Jitter**: The amount of random variation in the position data from the navigation path. - **Accuracy**: The accuracy used in the data. In a real world scenario this value represents how accurate the indoor positioning system believes the result to be and is used to draw the light blue shading around the Blue Dot. - **Distance Between Updates**: The physical distance between each position update. Lower values will result in smoother movement of the Blue Dot. - **Start Space**: The space to start the Blue Dot's movement. - **End Space**: The space to end the Blue Dot's movement. - **Time between updates**: The time between each position update can be used to control the speed of the Blue Dot's movements. - **Path Near Radius**: Controls the size of the path shown on the map. ### Blue Dot Location Generator ### Building & Floor Selection # Building & Floor Selection > > ## Floor Selection When mapping a building with multiple floors, each floor has its own unique map. These are represented by the Mappedin.Floor class, which are accessed using Mappedin.MapData.getByType('floor'). The currently displayed Floor can be accessed using MapViewControl.currentFloor. !Mappedin-Web-SDK-v6-Level-Selector ### Changing Floors When initialized, MapView displays the Mappedin.Floor with the elevation that's closest to 0. This can be overridden by setting Mappedin.TShow3DMapOptions.initialFloor to a Mappedin.Floor or Mappedin.Floor.id and using it in the MapViewProps. ```tsx ``` ```ts // Setting the initial floor to Floor.id 'm_123456789'. const mapView = await show3dMap( document.getElementById('mappedin-map') as HTMLDivElement, mapData, { initialFloor: 'm_123456789', } ); ``` The Mappedin.Floor displayed in a MapView can also be changed during runtime by calling MapViewControl.setFloor() and passing in a Mappedin.Floor or Mappedin.Floor.id. ```ts // Set the floor to Floor.id 'm_987654321'. mapView.setFloor(`m_987654321`); ``` ### Listening for Floor Changes The Mappedin event system provides the ability to listen for floor changes on a MapView. The code below listens for the `floor-change` event and logs the new floor name to the console. ```tsx useEvent("floor-change", (event) => { console.log( "Floor changed to:", event?.floor.name, "in FloorStack:", event?.floor.floorStack.name ); }); ``` ## Building Selection Mappedin Maps can contain one to many buildings with each building having one to many floors. Each building has its floors organized into a Mappedin.FloorStack object. When multiple buildings are present, there are multiple Mappedin.FloorStack objects, one for each building. A Mappedin. FloorStack contains one to many Mappedin.Floor objects, each representing the map of each level of the building. The Mappedin.FloorStack object is accessed by using MapData.getByType('floor-stack'). ```ts // Get the FloorStack object. const floorStacks = mapData.getByType('floor-stack'); ``` ### Camera # Camera > > Controlling the view of the map allows apps to create visually rich experiences using Mappedin SDK for React Native. This guide shows how to focus the map view on targets, move the camera and listen to camera events. !Mappedin JS v6 Camera > Note that the **MapViewControl** class implements the **Mappedin.Camera** interface and exposes it as **MapViewControl.Camera**. Use **MapViewControl.Camera** to utilize **Mappedin.Camera**'s methods. ## Focus the Camera on Targets Mappedin JS has built in functionality to focus the camera on one ore more targets using a single or array of Mappedin.IFocusable. When multiple targets are used, the SDK will ensure that all targets are visible. The following sample code acts on the click event to focus on the Mappedin.Space the user clicked on. Note that the Mappedin.Space must be set to interactive to allow it to be clickable. Refer to the Interactivity guide for more information on how to set a space to interactive. ```ts // Act on the click event to focus on the Space that was clicked. useEvent('click', async (event: Mappedin.TClickPayload;) => { // Focus on the space that was clicked. mapView.Camera.focusOn(event.spaces[0]); }); ``` ## Controlling the Camera To control the camera, set it with new pitch, bearing or zoom using MapViewControl.Camera.set(). It accepts a Mappedin.TCameraTarget object that contains bearing, center coordinate, pitch and zoom level. These parameters are all optional, allowing the camera to by moved by adjusting one or more of these values. ### TCameraTarget - **bearing:** Bearing for the camera target in degrees. - **center:** Center `Coordinate` for the camera target. - **pitch:** Pitch for the camera target in degrees. - **zoomLevel:** Zoom level for the camera target in mercator zoom levels. ```ts mapView.Camera.set({ bearing: 30, pitch: 80, zoomLevel: 19.5, center: e.coordinate, }); ``` ## Animation The camera can also be animated into position using the same transforms described in the Controlling the Camera section above. This is done using the MapViewControl.Camera.animateTo() method. Similar to MapViewControl.Camera.set(), the `animateTo` method accepts a Mappedin.TCameraTarget object, but it is optional. This allows the camera to changed by adjusting its `bearing`, `pitch` or `zoomLevel` without specifying a new target to move to. In addition, `animateTo` also accepts Mappedin.TCameraAnimationOptions that allow setting of the duration of the animation in milliseconds and setting the easing curve. The next code snippet acts on the click event to animate the camera to the click position. It uses easing `ease-in-out` over 4000 milliseconds. ```ts // Act on the click event to animate to a new camera position. useEvent('click', async (event: Mappedin.TClickPayload) => { mapView.Camera.animateTo( { bearing: 30, pitch: 80, zoomLevel: 18, center: event.coordinate, }, { duration: 4000, easing: 'ease-in-out' }, ); }); ``` The types of easing anmiations are defined in Mappedin.TEasingFunction. ### TEasingFunction - **Linear:** This function implies a constant rate of change. It means the animation proceeds at the same speed from start to end. There's no acceleration or deceleration, giving a very mechanical feel. - **Ease-in:** This function causes the animation to start slowly and then speed up as it progresses. Initially, there's gradual acceleration, and as the function moves forward, the rate of change increases. - **Ease-out:** Contrary to ease-in, ease-out makes the animation start quickly and then slow down towards the end. It begins with a faster rate of change and gradually decelerates. - **Ease-in-out:** This function combines both ease-in and ease-out. The animation starts slowly, speeds up in the middle, and then slows down again towards the end. It offers a balance of acceleration and deceleration. ## Resetting The Camera While there is no method in Mappedin SDK for React Native to reset the camera to its default position, this can be easily built into an app. To do so, store the camera position after the map is shown and then use those values to reposition the camera at a later time. The code sample below stores the initial camera position. When a user clicks on a location it first focuses on that space. The next click will return the camera to its original position. ```ts let focused: boolean = false; const defaultCameraPosition: TCameraTarget = { bearing: mapView.Camera.bearing, pitch: mapView.Camera.pitch, zoomLevel: mapView.Camera.zoomLevel, center: mapView.Camera.center, }; // Set each space to be interactive and its hover color to orange. mapData.getByType('space').forEach((space) => { mapView.updateState(space, { interactive: true, hoverColor: '#4248FF', }); }); // Act on the click event to focus on the Space that was clicked or reset the camera. useEvent('click', async (event: Mappedin.TClickPayload) => { if (focused) { // Reset the camera to its default position. mapView.Camera.set(defaultCameraPosition); focused = false; } else { // Focus on the space that was clicked. mapView.Camera.focusOn(event.spaces[0]); focused = true; } }); ``` ## Listening to Camera Events There are several camera events that can be acted on by setting a listener with useEvent('camera-change'). The camera-change event contains a Mappedin.CameraTransform object. Mappedin.CameraTransform provides the bearing, center coordinate, pitch and zoom level. ```ts // Log camera change events to the console. useEvent('camera-change', async (cam: Mappedin.CameraTransform) => { console.log( 'Bearing: ' + cam.bearing + ', Pitch: ' + cam.pitch + ', Zoom Level: ' + cam.zoomLevel + ', Center: Lat:' + cam.center.latitude, +', Lon:' + cam.center.longitude, ); }); ``` ### Connections # Connections > > Map connections are pathways in multi-floor and multi-building maps that enable vertical or horizontal movement between levels, spaces or buildings. They include stairs, elevators, and escalators, providing essential links for seamless navigation and spatial continuity across the map. The Mappedin.Connection includes details such as name, description, floors, coordinates and more. Mappedin.Connection contains an array of `coordinates`, with each `coordinate` representing the location of the connection on a specific floor. In the case of an elevator, each `coordinate` would have `latitude` and `longitude` values that are the same with different `floorIds`. Stairs may have `coordinates` with the same or different `latitude` and `longitude` values on each floor, depending on whether a building's stairs are vertically aligned. The following code snippet retrieves all connections from the map. ```ts const connections = mapData.getByType("connection"); ``` ### Enterprise Data # Enterprise Data > > > The Enterprise Data classes described in this guide are populated in Mappedin CMS, which requires an Enterprise Tier subscription. ## Enterprise Locations A Mappedin.EnterpriseLocation contains metadata about a location, such as its name, description, logo, phone number, social medial links, hours of operation and more. They can be accessed using the Mappedin.MapData.getByType() method as shown below. ```ts const allLocations = mapData.getByType('enterprise-location'); ``` Here is an example of the data contained within Mappedin.EnterpriseLocation. !enterprise-location-example-data ## Enterprise Categories A Mappedin.EnterpriseCategory groups one or more Mappedin.EnterpriseLocation. These allow similar locations to be sorted in a logical fashion. For example a mall may group locations into Food Court, Footwear and Women's Fashion. They can be accessed using the Mappedin.MapData.getByType() method as shown below. ```ts mapData.getByType('enterprise-category'); ``` Here is an example of the data contained within Mappedin.EnterpriseCategory. !enterprise-category-example-data Mappedin.EnterpriseCategory can contain one or more sub Mappedin.EnterpriseCategory that are accessed from its children accessor. Mappedin.EnterpriseCategory also contains a name, array of Mappedin.EnterpriseLocation and other metadata. ## Enterprise Venue The Mappedin.EnterpriseVenue class holds metadata about the map, which includes the map name, supported languages, default language, top locations and more. It can be accessed using the Mappedin.MapData.getByType() method as shown below. ```ts mapData.getByType('enterprise-venue'); ``` Here is an example of the data contained within Mappedin.EnterpriseVenue. !enterprise-venue-example-data ## Enterprise Search The Mappedin.Search functionality allows users to search for locations, categories, and other points of interest within the venue. Here are two ways to enable search: 1. Enable Search on map initialization (Recommended): ```tsx ``` 2. Enable Search via method: ```ts await mapData.Search.enable(); ``` ### Search Query Use Mappedin.Search.query to search for locations based on a string input: - Mappedin.EnterpriseLocation: Specific places such as stores, restaurants, or washrooms. - Mappedin.EnterpriseCategory: Groups of locations, such as "Food Court" or "Electronics." - Mappedin.Places: Any main objects that can be searched for such as Mappedin.Space, Mappedin.Door, Mappedin.PointOfInterest Search query returns a list of matching Mappedin.SearchResults based on the input string. Mappedin.SearchResults include information about the type of match, the score (relevance), and detailed metadata about the matching items. #### Example Search Query ```ts const results = await mapData.Search.query('Coffee Shop'); // Log the entire result object console.log(results); ``` #### Example Response ```ts { "places": [ { "type": "space", "match": { "coffee": ["description"], "shop": ["description"], "shopping": ["description"] }, "score": 19.5, "item": { "id": "s_ef330e70329183b4", "name": "Take Five Cafe", "type": "room", "floor": "f_8ca999c2cbcb6022", "center": { "latitude": 43.860466138841865, "longitude": -78.94643735347043, "floor": "f_8ca999c2cbcb6022" } } } ], "enterpriseLocations": [ { "type": "enterprise-location", "match": { "coffee": ["tags", "description"] }, "score": 24.3, "item": { "id": "el_094c671a5bc73fb7", "name": "Nespresso" } } ], "enterpriseCategories": [ { "type": "enterprise-category", "match": { "shop": ["locations.name"] }, "score": 9.4, "item": { "id": "ec_5cf9b7898619b951", "name": "Health & Beauty" } } ] } ``` #### Response Field Breakdown 1. Mappedin.Places: - `type`: Indicates the type of match (e.g., space). - `match`: Shows the fields that matched the query (e.g., description). - `score`: Relevance score of the match. - `item`: Includes id, name, type, floor, and center (coordinates). 2. Mappedin.EnterpriseLocation: - `type`: enterprise-location. - `match`: Indicates fields matched (e.g., tags, description). - `item`: Contains id, name, and additional metadata. 3. Mappedin.EnterpriseCategory: - `type`: enterprise-category. - `match`: Indicates query matches to category-related data. - `item`: Contains id and name. ### Search Suggestions Use Mappedin.Search.suggest to fetch real-time suggestions based on partial input. This is useful for creating an autocomplete feature for a search bar. #### Example Code ```ts // fetch suggestions for partial input "Coff" const suggestions = await mapData.Search.suggest('Coff'); // log the suggestions console.log(suggestions); // log suggestion names suggestions.forEach(suggestion => { console.log(`Suggestion: ${suggestion.suggestion}`); }); ``` #### Example Response Here's a sample response for the query 'Coff': ```ts [ { suggestion: 'coffee', terms: ['coffee'], score: 7.558366632976704, }, ]; ``` #### Response Field Breakdown 1. `suggestion`: The suggested term or phrase (e.g., "coffee"). 2. `terms`: An array of individual terms that make up the suggestion. 3. `score`: A numerical value representing the relevance of the suggestion. ## Events & Deals Events and deals created in Mappedin CMS can be retrieved using the @mappedin/events package. ### Installation To use the @mappedin/events package, you need to install it using npm or yarn. **Using npm** ```bash npm install @mappedin/events ``` **Using yarn** ```bash yarn add @mappedin/events ``` ### Usage The following example demonstrates how to load and display events on a map. ```tsx const { mapData } = useMap(); // Create an EventManager to load and read event data const em = new EventsManager(mapData); // Load all events await em.load(); // Create markers for all events with the event name at the location of the event return ( <> {em.events.map(event => ( ))} ); ``` ### Options The `EventsManager` constructor accepts an optional `options` parameter. The following options are available: ```ts /** * Options for the {@link EventsManager}. */ export type EventsManagerOptions = Partial<{ /** * The fields to fetch for each event. * * @default fields id, name, type, startDate, endDate, externalId, description, location, image, video */ fields: string[]; /** * Whether to include past or expired events. * * @default false */ includeExpired: boolean; }>; ``` ### Methods The `EventsManager` class provides the following methods: ```ts class EventsManager { /** * Whether load() has been called and successfully completed. */ get ready(): boolean; /** * All current and future events that have been loaded. Will be empty if load() has not been called. */ get events(): EventMetaData[]; /** * Load all the events for the map. */ async load(): void; /** * Get an event by ID. */ getById(id: string): EventMetaData | undefined; /** * Get an array of events attached to an EnterpriseLocation. */ getByLocationId(locationId: string): EventMetaData[]; /** * Clean up the EventsManager instance. */ destroy(): void; } ``` ### 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