@kerala-startup-mission/react-native-indoor-map
v0.1.0
Published
Indoor map screen for React Native: the venue JSON from the indoor editor, drawn with MapLibre, with iBeacon and GPS positioning.
Maintainers
Readme
@kerala-startup-mission/react-native-indoor-map
The indoor map as a React Native screen. Give it the address of the data folder the indoor editor saves (indoor/data/: every building, the outdoor walkways between them, and the floor plan images) and it shows the tilted floor plans, search From/To across all buildings, the way with its steps (from one building, outside and into another), walking with the map following, and where the visitor is: from the venue's iBeacons, or GPS where no beacon is heard. Beacons also tell the floor.
import { IndoorMap } from '@kerala-startup-mission/react-native-indoor-map'
export default () => <IndoorMap dataUrl="https://your-site/data/" />The built indoor site serves its data folder at /data/, and so does npm run dev in indoor/; any static host of the folder's contents works too. The screen reads site.json, then building/<id>.json for each building it lists, and the images from plans/.
No Expo needed. React Native 0.86 or newer (New Architecture), iPhone and Android.
Add it to an app
Install it and MapLibre:
npm install @kerala-startup-mission/react-native-indoor-map @maplibre/maplibre-react-native@^11.5iPhone: in
ios/Podfile, insidepost_install do |installer| … end, add MapLibre's line:$MLRN.post_install(installer)In
Info.plist, say why the app wants location (beacons and the compass need it):<key>NSLocationWhenInUseUsageDescription</key> <string>Shows where you are on the indoor map.</string>Then
cd ios && bundle exec pod install.Android: nothing to add. The package's manifest brings Bluetooth scanning and precise location; the screen asks for them when the visitor picks "Your location".
Host the data folder (see above) and pass its address as
dataUrl. A plainhttp://address needs the platform's permission for cleartext traffic, except for localhost on iPhone.
Props
| Prop | |
|---|---|
| dataUrl | Where the data folder is served, such as https://your-site/data/. A query on it (a dev tunnel's ?key=) goes along with every file. The map is loaded again whenever the app comes back to the front. The last map loaded is kept on the phone: the screen starts from it at once, and without the network. |
| from, to | Slugs of places to start with. |
| onArrive(place), onPlaceSelect(place, side) | Callbacks. |
| safeArea | { top, bottom } taken by the status bar and home indicator (from react-native-safe-area-context, if the app uses it). |
| beaconOptions | { P, n }: see calibration. |
| fake | Desk test: with From = Your location, a tap on the map sets where you are. |
| debug | Lists the beacons heard and their signal. |
| basemap | Street map around the building, once its two real-world points are set in the editor. true uses OpenFreeMap's street map (free, no key, fine for a published app); or pass another MapLibre style URL, whose glyphs include Noto Sans Bold. Without internet the venue shows on its own. |
Beacons
Flash beacon/beacon.ino onto each ESP32-C3; it prints its UUID, major and minor on the serial monitor. Bought iBeacons work too, with whatever ids they came with. List every beacon on the editor's beacon list (/?edit&beacons): paste the boards' serial lines or the rows of a seller's sheet, and each beacon gets a number to write on it. Then in the editor pick Beacon (B), tap where each one is mounted and type just that number. The screen listens for every UUID on the list and tells beacons apart by UUID, major and minor.
Calibrate on site with debug:
- Stand 1 m from a beacon for 10 s and note its dBm: that is
P(default −59; the firmware sends at +9 dBm, so expect nearer −50). - Walk a corridor between beacons. If the dot lags behind you toward the beacon you left, raise
n(default 2.5; 2 open halls, 3–4 through walls). - iPhone: Precise Location must be on for the app. Android: location must be switched on, or Bluetooth scans return nothing.
The position is the weighted centre of the strongest four beacons on the floor; a beacon unheard for 4 s drops out; the floor changes only after another floor's beacons lead clearly for 3 s. If beacons go quiet, the last beacon position is kept for 10 s, then GPS takes over.
Heading
The dot carries an arrow toward where the phone points (compass), and the compass button turns the map with you. Both need the plan placed on the earth: the editor's Real-world position points.
Develop
npm testchecks the camera maths, beacon positioning, and thatsrc/corestill matchesindoor/src(npm run sync-corecopies it again).example/is a bare React Native app:npm install,cd ios && bundle exec pod install, thennpx react-native run-iosorrun-android. It reads the map fromnpm run devinindoor/on this computer, as the iOS Simulator and the Android emulator reach it. It installs the package from the folder above (file:..), so Metro must watch that folder and resolve its imports from the app; seeexample/metro.config.jsandexample/react-native.config.js. An app installing from npm needs neither.- Publish:
npm version patch(orminor; the podspec follows package.json), thennpm publish, which runsnpm testfirst. - On an iPhone, tap the strip at the top of the example and paste the link
npm run dev:phoneprints inindoor/, or a published site's/data/address.
