react-native-pointr 9.2.0 → 9.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/settings.json +21 -0
- package/API_REFERENCE.md +887 -0
- package/CHANGELOG.md +45 -0
- package/EXTENDING.md +419 -0
- package/README.md +221 -117
- package/WAYFINDING_EVENTS.md +243 -0
- package/android/build.gradle +4 -5
- package/android/src/main/java/com/pointr/PTRCoreExtensions.kt +126 -0
- package/android/src/main/java/com/pointr/PTRMapWidgetCommandType.kt +2 -1
- package/android/src/main/java/com/pointr/PTRMapWidgetManager.kt +78 -16
- package/android/src/main/java/com/pointr/PointrModule.kt +106 -3
- package/example/pointr_rn_demo/.bundle/config +2 -0
- package/example/pointr_rn_demo/.eslintrc.js +4 -0
- package/example/pointr_rn_demo/.prettierrc.js +5 -0
- package/example/pointr_rn_demo/.watchmanconfig +1 -0
- package/example/pointr_rn_demo/App.tsx +323 -0
- package/example/pointr_rn_demo/Gemfile +16 -0
- package/example/pointr_rn_demo/Gemfile.lock +111 -0
- package/example/pointr_rn_demo/README.md +188 -0
- package/example/pointr_rn_demo/__tests__/App.test.tsx +13 -0
- package/example/pointr_rn_demo/android/app/build.gradle +119 -0
- package/example/pointr_rn_demo/android/app/debug.keystore +0 -0
- package/example/pointr_rn_demo/android/app/proguard-rules.pro +10 -0
- package/example/pointr_rn_demo/android/app/src/main/AndroidManifest.xml +27 -0
- package/example/pointr_rn_demo/android/app/src/main/java/com/pointr_rn_demo/MainActivity.kt +22 -0
- package/example/pointr_rn_demo/android/app/src/main/java/com/pointr_rn_demo/MainApplication.kt +27 -0
- package/example/pointr_rn_demo/android/app/src/main/res/drawable/rn_edit_text_material.xml +37 -0
- package/example/pointr_rn_demo/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
- package/example/pointr_rn_demo/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
- package/example/pointr_rn_demo/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
- package/example/pointr_rn_demo/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
- package/example/pointr_rn_demo/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
- package/example/pointr_rn_demo/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
- package/example/pointr_rn_demo/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/example/pointr_rn_demo/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
- package/example/pointr_rn_demo/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/example/pointr_rn_demo/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
- package/example/pointr_rn_demo/android/app/src/main/res/values/strings.xml +3 -0
- package/example/pointr_rn_demo/android/app/src/main/res/values/styles.xml +9 -0
- package/example/pointr_rn_demo/android/build.gradle +34 -0
- package/example/pointr_rn_demo/android/gradle.properties +44 -0
- package/example/pointr_rn_demo/android/settings.gradle +6 -0
- package/example/pointr_rn_demo/app.json +4 -0
- package/example/pointr_rn_demo/babel.config.js +3 -0
- package/example/pointr_rn_demo/index.js +16 -0
- package/example/pointr_rn_demo/ios/.xcode.env +11 -0
- package/example/pointr_rn_demo/ios/Podfile +40 -0
- package/example/pointr_rn_demo/ios/pointr_rn_demo/AppDelegate.swift +48 -0
- package/example/pointr_rn_demo/ios/pointr_rn_demo/Images.xcassets/AppIcon.appiconset/Contents.json +53 -0
- package/example/pointr_rn_demo/ios/pointr_rn_demo/Images.xcassets/Contents.json +6 -0
- package/example/pointr_rn_demo/ios/pointr_rn_demo/Info.plist +63 -0
- package/example/pointr_rn_demo/ios/pointr_rn_demo/LaunchScreen.storyboard +47 -0
- package/example/pointr_rn_demo/ios/pointr_rn_demo/PrivacyInfo.xcprivacy +37 -0
- package/example/pointr_rn_demo/ios/pointr_rn_demo.xcodeproj/project.pbxproj +488 -0
- package/example/pointr_rn_demo/ios/pointr_rn_demo.xcodeproj/xcshareddata/xcschemes/pointr_rn_demo.xcscheme +88 -0
- package/example/pointr_rn_demo/ios/pointr_rn_demo.xcworkspace/contents.xcworkspacedata +10 -0
- package/example/pointr_rn_demo/jest.config.js +3 -0
- package/example/pointr_rn_demo/metro.config.js +22 -0
- package/example/pointr_rn_demo/package.json +47 -0
- package/example/pointr_rn_demo/prepare-demo-distribution.sh +103 -0
- package/example/pointr_rn_demo/tsconfig.json +5 -0
- package/ios/PTRMapWidgetContainerView.swift +56 -5
- package/ios/PTRMapWidgetManager-Bridging.m +7 -0
- package/ios/PTRMapWidgetManager.swift +28 -0
- package/ios/PTRNativeLibrary-Bridging.m +4 -0
- package/ios/PTRNativeLibrary.swift +208 -2
- package/package.json +16 -2
- package/prepare-distribution.sh +151 -0
- package/react-native-pointr.podspec +1 -1
- package/src/PTRCommand.ts +13 -0
- package/src/PTRMapWidgetUtils.ts +10 -1
- package/src/PTRPoiManager.ts +20 -0
- package/src/index.tsx +40 -1
- package/src/types/PTRGeometry.ts +70 -0
- package/src/types/PTRPoi.ts +49 -0
- package/src/types/PTRPosition.ts +22 -0
- package/src/types/PTRWayfindingEvent.ts +18 -0
package/API_REFERENCE.md
ADDED
|
@@ -0,0 +1,887 @@
|
|
|
1
|
+
# React Native Pointr - API Reference
|
|
2
|
+
|
|
3
|
+
> **Platform Compatibility:** This API reference is identical for both Android and iOS platforms. All methods, parameters, and behaviors are consistent across platforms.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
- [Native Module API](#native-module-api)
|
|
7
|
+
- [Map Widget Component](#map-widget-component)
|
|
8
|
+
- [Command Types](#command-types)
|
|
9
|
+
- [Utility Functions](#utility-functions)
|
|
10
|
+
- [Event Listeners](#event-listeners)
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Native Module API
|
|
15
|
+
|
|
16
|
+
### `PTRNativePointrLibrary`
|
|
17
|
+
|
|
18
|
+
The main native module for interacting with the Pointr SDK.
|
|
19
|
+
|
|
20
|
+
#### Methods
|
|
21
|
+
|
|
22
|
+
##### `initialize(clientId, licenseKey, baseUrl, logLevel)`
|
|
23
|
+
|
|
24
|
+
Initializes the Pointr SDK with credentials.
|
|
25
|
+
|
|
26
|
+
**Parameters:**
|
|
27
|
+
- `clientId` (string): Your Pointr client identifier
|
|
28
|
+
- `licenseKey` (string): Your Pointr license key
|
|
29
|
+
- `baseUrl` (string): The Pointr cloud base URL
|
|
30
|
+
- `logLevel` (number): Log level (0-4)
|
|
31
|
+
- `0`: Verbose
|
|
32
|
+
- `1`: Debug
|
|
33
|
+
- `2`: Info
|
|
34
|
+
- `3`: Warning
|
|
35
|
+
- `4`: Error
|
|
36
|
+
|
|
37
|
+
**Example:**
|
|
38
|
+
```typescript
|
|
39
|
+
import { NativeModules } from 'react-native';
|
|
40
|
+
|
|
41
|
+
NativeModules.PTRNativePointrLibrary.initialize(
|
|
42
|
+
"client-id",
|
|
43
|
+
"license-key",
|
|
44
|
+
"https://your-instance.pointr.cloud",
|
|
45
|
+
3
|
|
46
|
+
);
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
##### `start(callback)`
|
|
52
|
+
|
|
53
|
+
Starts the Pointr SDK.
|
|
54
|
+
|
|
55
|
+
**Parameters:**
|
|
56
|
+
- `callback` (function): Callback function that receives the Pointr state as a string
|
|
57
|
+
|
|
58
|
+
**Example:**
|
|
59
|
+
```typescript
|
|
60
|
+
NativeModules.PTRNativePointrLibrary.start((state: string) => {
|
|
61
|
+
console.log(`Pointr state: ${state}`);
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Possible States:**
|
|
66
|
+
- `"running"` - SDK is running successfully
|
|
67
|
+
- `"failed registration"` - Registration failed
|
|
68
|
+
- `"failed validation"` - Validation failed
|
|
69
|
+
- `"failed invalid deep link url"` - Invalid deep link URL
|
|
70
|
+
- `"failed no internet"` - No internet connection
|
|
71
|
+
- `"off"` - SDK is off
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
##### `stop()`
|
|
76
|
+
|
|
77
|
+
Stops the Pointr SDK.
|
|
78
|
+
|
|
79
|
+
**Example:**
|
|
80
|
+
```typescript
|
|
81
|
+
NativeModules.PTRNativePointrLibrary.stop();
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
##### `requestPermissions()`
|
|
87
|
+
|
|
88
|
+
Requests necessary permissions (location, bluetooth, etc.).
|
|
89
|
+
|
|
90
|
+
**Example:**
|
|
91
|
+
```typescript
|
|
92
|
+
NativeModules.PTRNativePointrLibrary.requestPermissions();
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
##### `shouldRequestPermissionsAtStartup(shouldRequest)`
|
|
98
|
+
|
|
99
|
+
Sets whether permissions should be requested automatically at startup.
|
|
100
|
+
|
|
101
|
+
**Parameters:**
|
|
102
|
+
- `shouldRequest` (boolean): True to request permissions automatically
|
|
103
|
+
|
|
104
|
+
**Example:**
|
|
105
|
+
```typescript
|
|
106
|
+
NativeModules.PTRNativePointrLibrary.shouldRequestPermissionsAtStartup(true);
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
##### `getCurrentLocation(callback)`
|
|
112
|
+
|
|
113
|
+
Gets the current calculated position.
|
|
114
|
+
|
|
115
|
+
**Parameters:**
|
|
116
|
+
- `callback` (function): Callback function that receives location data or null
|
|
117
|
+
|
|
118
|
+
**Example:**
|
|
119
|
+
```typescript
|
|
120
|
+
NativeModules.PTRNativePointrLibrary.getCurrentLocation((location) => {
|
|
121
|
+
if (location) {
|
|
122
|
+
console.log('Site:', location.siteExternalIdentifier);
|
|
123
|
+
console.log('Building:', location.buildingExternalIdentifier);
|
|
124
|
+
console.log('Level:', location.levelIndex);
|
|
125
|
+
console.log('Coordinates:', location.latitude, location.longitude);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**Location Object:**
|
|
131
|
+
- `siteInternalIdentifier` (string)
|
|
132
|
+
- `siteExternalIdentifier` (string)
|
|
133
|
+
- `buildingInternalIdentifier` (string)
|
|
134
|
+
- `buildingExternalIdentifier` (string)
|
|
135
|
+
- `levelIndex` (number)
|
|
136
|
+
- `latitude` (number)
|
|
137
|
+
- `longitude` (number)
|
|
138
|
+
- `accuracy` (number)
|
|
139
|
+
- `heading` (number) - Only present if heading accuracy is high
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
##### `isMyCarMarked(callback)`
|
|
144
|
+
|
|
145
|
+
Checks if a "My Car" location has been saved.
|
|
146
|
+
|
|
147
|
+
**Parameters:**
|
|
148
|
+
- `callback` (function): Callback with no arguments if marked, error message if not
|
|
149
|
+
|
|
150
|
+
**Example:**
|
|
151
|
+
```typescript
|
|
152
|
+
NativeModules.PTRNativePointrLibrary.isMyCarMarked((error) => {
|
|
153
|
+
if (!error) {
|
|
154
|
+
console.log('My car location is marked');
|
|
155
|
+
} else {
|
|
156
|
+
console.log('No saved location:', error);
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
##### `setPointrMapWidgetConfiguration(configJson)`
|
|
164
|
+
|
|
165
|
+
Sets the map widget configuration.
|
|
166
|
+
|
|
167
|
+
**Parameters:**
|
|
168
|
+
- `configJson` (string): JSON string with configuration options
|
|
169
|
+
|
|
170
|
+
**Example:**
|
|
171
|
+
```typescript
|
|
172
|
+
NativeModules.PTRNativePointrLibrary.setPointrMapWidgetConfiguration(
|
|
173
|
+
JSON.stringify({
|
|
174
|
+
isExitButtonEnabled: false,
|
|
175
|
+
isCompassEnabled: true,
|
|
176
|
+
isSearchBarEnabled: true,
|
|
177
|
+
isLevelSelectorEnabled: true,
|
|
178
|
+
isMyCarButtonEnabled: true
|
|
179
|
+
})
|
|
180
|
+
);
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**Configuration Options:**
|
|
184
|
+
- `isExitButtonEnabled` (boolean): Show/hide exit button
|
|
185
|
+
- `isCompassEnabled` (boolean): Show/hide compass
|
|
186
|
+
- `isSearchBarEnabled` (boolean): Show/hide search bar
|
|
187
|
+
- `isLevelSelectorEnabled` (boolean): Show/hide level selector
|
|
188
|
+
- `isMyCarButtonEnabled` (boolean): Show/hide my car button
|
|
189
|
+
- `isRouteFooterViewEnabled` (boolean): Show/hide route footer
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
##### `getPois(siteId)`
|
|
194
|
+
|
|
195
|
+
Retrieves all Points of Interest (POIs) for a specific site.
|
|
196
|
+
|
|
197
|
+
**Parameters:**
|
|
198
|
+
- `siteId` (string): Site external identifier
|
|
199
|
+
|
|
200
|
+
**Returns:** Promise<PTRPoi[]> - Array of POI objects
|
|
201
|
+
|
|
202
|
+
**Example:**
|
|
203
|
+
```typescript
|
|
204
|
+
import { getPois } from 'react-native-pointr';
|
|
205
|
+
|
|
206
|
+
try {
|
|
207
|
+
const pois = await getPois('site-external-id');
|
|
208
|
+
console.log(`Found ${pois.length} POIs`);
|
|
209
|
+
|
|
210
|
+
pois.forEach(poi => {
|
|
211
|
+
console.log(`${poi.name} (${poi.typeCode})`);
|
|
212
|
+
console.log(` Location: ${poi.position.lat}, ${poi.position.lon}`);
|
|
213
|
+
console.log(` Level: ${poi.position.lvl}`);
|
|
214
|
+
});
|
|
215
|
+
} catch (error) {
|
|
216
|
+
console.error('Failed to get POIs:', error);
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
**POI Object Structure:**
|
|
221
|
+
```typescript
|
|
222
|
+
interface PTRPoi {
|
|
223
|
+
identifier: string; // Internal ID
|
|
224
|
+
externalIdentifier: string; // External ID
|
|
225
|
+
name: string; // Display name
|
|
226
|
+
typeCode: string; // POI type code
|
|
227
|
+
position: PTRPosition; // Geographic position
|
|
228
|
+
geometry: PTRGeometry; // Shape data
|
|
229
|
+
attributes: PTRPoiAttributes; // Metadata
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
interface PTRPosition {
|
|
233
|
+
lat: number; // Latitude
|
|
234
|
+
lon: number; // Longitude
|
|
235
|
+
isValid: boolean; // Position validity
|
|
236
|
+
sid: string; // Site ID
|
|
237
|
+
bid: string; // Building ID
|
|
238
|
+
lvl: number; // Level index
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
interface PTRPoiAttributes {
|
|
242
|
+
logo?: string; // Logo URL
|
|
243
|
+
images?: string[]; // Image URLs
|
|
244
|
+
description?: string; // Description text
|
|
245
|
+
extra?: Record<string, any>; // Custom data
|
|
246
|
+
[key: string]: any; // Other attributes
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## Map Widget Component
|
|
253
|
+
|
|
254
|
+
### `PTRMapWidget`
|
|
255
|
+
|
|
256
|
+
A native UI component that displays the Pointr map.
|
|
257
|
+
|
|
258
|
+
**Props:**
|
|
259
|
+
- `style` (ViewStyle): Component styling
|
|
260
|
+
- `onMapWidgetDidEndLoading` (function): Callback when map finishes loading with a command
|
|
261
|
+
- `ref` (ref): Reference to the component for sending commands
|
|
262
|
+
|
|
263
|
+
**Example:**
|
|
264
|
+
```typescript
|
|
265
|
+
import { requireNativeComponent } from 'react-native';
|
|
266
|
+
|
|
267
|
+
interface PTRMapWidgetProps {
|
|
268
|
+
style?: any;
|
|
269
|
+
onMapWidgetDidEndLoading?: (event: NativeSyntheticEvent<any>) => void;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const PTRMapWidget = requireNativeComponent<PTRMapWidgetProps>('PTRMapWidget');
|
|
273
|
+
|
|
274
|
+
function MyComponent() {
|
|
275
|
+
const ref = useRef(null);
|
|
276
|
+
|
|
277
|
+
const handleLoadingComplete = (event) => {
|
|
278
|
+
const { command, siteExternalIdentifier, error } = event.nativeEvent;
|
|
279
|
+
console.log('Map loaded:', command, siteExternalIdentifier, error);
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
return (
|
|
283
|
+
<PTRMapWidget
|
|
284
|
+
ref={ref}
|
|
285
|
+
style={{ flex: 1 }}
|
|
286
|
+
onMapWidgetDidEndLoading={handleLoadingComplete}
|
|
287
|
+
/>
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
294
|
+
## Command Types
|
|
295
|
+
|
|
296
|
+
### `PTRCommandType`
|
|
297
|
+
|
|
298
|
+
Enum of supported command types.
|
|
299
|
+
|
|
300
|
+
```typescript
|
|
301
|
+
enum PTRCommandType {
|
|
302
|
+
SITE = "site",
|
|
303
|
+
BUILDING = "building",
|
|
304
|
+
LEVEL = "level",
|
|
305
|
+
POI = "poi",
|
|
306
|
+
PATH = "path",
|
|
307
|
+
STATIC_PATH = "staticPath",
|
|
308
|
+
MARK_MY_CAR_LEVEL = "markMyCarForLevel",
|
|
309
|
+
MARK_MY_CAR_SITE = "markMyCarForSite",
|
|
310
|
+
SHOW_MY_CAR_SITE = "showMyCarForSite",
|
|
311
|
+
START_AND_FOCUS = "startAndFocus"
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
### Command Classes
|
|
318
|
+
|
|
319
|
+
#### `PTRSiteCommand`
|
|
320
|
+
|
|
321
|
+
Shows a specific site on the map.
|
|
322
|
+
|
|
323
|
+
**Constructor:**
|
|
324
|
+
```typescript
|
|
325
|
+
new PTRSiteCommand(site: string)
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
**Parameters:**
|
|
329
|
+
- `site` (string): Site external identifier
|
|
330
|
+
|
|
331
|
+
**Example:**
|
|
332
|
+
```typescript
|
|
333
|
+
import { PTRSiteCommand } from 'react-native-pointr/src/PTRCommand';
|
|
334
|
+
import { showMapWidget } from 'react-native-pointr/src/PTRMapWidgetUtils';
|
|
335
|
+
|
|
336
|
+
const command = new PTRSiteCommand("site-external-id");
|
|
337
|
+
showMapWidget(reactTag, command);
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
---
|
|
341
|
+
|
|
342
|
+
#### `PTRBuildingCommand`
|
|
343
|
+
|
|
344
|
+
Shows a specific building within a site.
|
|
345
|
+
|
|
346
|
+
**Constructor:**
|
|
347
|
+
```typescript
|
|
348
|
+
new PTRBuildingCommand(site: string, building: string)
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
**Parameters:**
|
|
352
|
+
- `site` (string): Site external identifier
|
|
353
|
+
- `building` (string): Building external identifier
|
|
354
|
+
|
|
355
|
+
**Example:**
|
|
356
|
+
```typescript
|
|
357
|
+
const command = new PTRBuildingCommand("site-id", "building-id");
|
|
358
|
+
showMapWidget(reactTag, command);
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
#### `PTRLevelCommand`
|
|
364
|
+
|
|
365
|
+
Shows a specific level within a building.
|
|
366
|
+
|
|
367
|
+
**Constructor:**
|
|
368
|
+
```typescript
|
|
369
|
+
new PTRLevelCommand(site: string, building: string, level: number)
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
**Parameters:**
|
|
373
|
+
- `site` (string): Site external identifier
|
|
374
|
+
- `building` (string): Building external identifier
|
|
375
|
+
- `level` (number): Level index
|
|
376
|
+
|
|
377
|
+
**Example:**
|
|
378
|
+
```typescript
|
|
379
|
+
const command = new PTRLevelCommand("site-id", "building-id", 1);
|
|
380
|
+
showMapWidget(reactTag, command);
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
---
|
|
384
|
+
|
|
385
|
+
#### `PTRPoiCommand`
|
|
386
|
+
|
|
387
|
+
Shows and focuses on a specific POI (Point of Interest).
|
|
388
|
+
|
|
389
|
+
**Constructor:**
|
|
390
|
+
```typescript
|
|
391
|
+
new PTRPoiCommand(site: string, poi: string)
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
**Parameters:**
|
|
395
|
+
- `site` (string): Site external identifier
|
|
396
|
+
- `poi` (string): POI external identifier or name
|
|
397
|
+
|
|
398
|
+
**Example:**
|
|
399
|
+
```typescript
|
|
400
|
+
const command = new PTRPoiCommand("site-id", "Lobby");
|
|
401
|
+
showMapWidget(reactTag, command);
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
---
|
|
405
|
+
|
|
406
|
+
#### `PTRPathCommand`
|
|
407
|
+
|
|
408
|
+
Shows navigation path from current location to a POI.
|
|
409
|
+
|
|
410
|
+
**Constructor:**
|
|
411
|
+
```typescript
|
|
412
|
+
new PTRPathCommand(site: string, poi: string)
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
**Parameters:**
|
|
416
|
+
- `site` (string): Site external identifier
|
|
417
|
+
- `poi` (string): Destination POI external identifier
|
|
418
|
+
|
|
419
|
+
**Example:**
|
|
420
|
+
```typescript
|
|
421
|
+
const command = new PTRPathCommand("site-id", "Lobby");
|
|
422
|
+
showMapWidget(reactTag, command);
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
---
|
|
426
|
+
|
|
427
|
+
#### `PTRStaticPathCommand`
|
|
428
|
+
|
|
429
|
+
Shows a static path between two POIs.
|
|
430
|
+
|
|
431
|
+
**Constructor:**
|
|
432
|
+
```typescript
|
|
433
|
+
new PTRStaticPathCommand(site: string, fromPoi: string, toPoi: string)
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
**Parameters:**
|
|
437
|
+
- `site` (string): Site external identifier
|
|
438
|
+
- `fromPoi` (string): Starting POI external identifier
|
|
439
|
+
- `toPoi` (string): Destination POI external identifier
|
|
440
|
+
|
|
441
|
+
**Example:**
|
|
442
|
+
```typescript
|
|
443
|
+
const command = new PTRStaticPathCommand("site-id", "Lobby", "Cafeteria");
|
|
444
|
+
showMapWidget(reactTag, command);
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
---
|
|
448
|
+
|
|
449
|
+
#### `PTRMarkMyCarLevelCommand`
|
|
450
|
+
|
|
451
|
+
Marks "My Car" location on a specific level.
|
|
452
|
+
|
|
453
|
+
**Constructor:**
|
|
454
|
+
```typescript
|
|
455
|
+
new PTRMarkMyCarLevelCommand(
|
|
456
|
+
site: string,
|
|
457
|
+
building: string,
|
|
458
|
+
level: number,
|
|
459
|
+
shouldShowPopup?: boolean,
|
|
460
|
+
animationType?: number
|
|
461
|
+
)
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
**Parameters:**
|
|
465
|
+
- `site` (string): Site external identifier
|
|
466
|
+
- `building` (string): Building external identifier
|
|
467
|
+
- `level` (number): Level index
|
|
468
|
+
- `shouldShowPopup` (boolean): Show popup after marking (default: true)
|
|
469
|
+
- `animationType` (number): Animation type (default: 1)
|
|
470
|
+
- `0`: None
|
|
471
|
+
- `1`: Standard
|
|
472
|
+
- `2`: Fly over
|
|
473
|
+
|
|
474
|
+
**Example:**
|
|
475
|
+
```typescript
|
|
476
|
+
const command = new PTRMarkMyCarLevelCommand("site-id", "building-id", 1, true, 1);
|
|
477
|
+
showMapWidget(reactTag, command);
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
---
|
|
481
|
+
|
|
482
|
+
#### `PTRMarkMyCarSiteCommand`
|
|
483
|
+
|
|
484
|
+
Marks "My Car" location at the current position within a site.
|
|
485
|
+
|
|
486
|
+
**Constructor:**
|
|
487
|
+
```typescript
|
|
488
|
+
new PTRMarkMyCarSiteCommand(
|
|
489
|
+
site: string,
|
|
490
|
+
shouldShowPopup?: boolean,
|
|
491
|
+
animationType?: number
|
|
492
|
+
)
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
**Parameters:**
|
|
496
|
+
- `site` (string): Site external identifier
|
|
497
|
+
- `shouldShowPopup` (boolean): Show popup after marking (default: true)
|
|
498
|
+
- `animationType` (number): Animation type (default: 1)
|
|
499
|
+
|
|
500
|
+
**Example:**
|
|
501
|
+
```typescript
|
|
502
|
+
const command = new PTRMarkMyCarSiteCommand("site-id", true, 1);
|
|
503
|
+
showMapWidget(reactTag, command);
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
---
|
|
507
|
+
|
|
508
|
+
#### `PTRShowMyCarSiteCommand`
|
|
509
|
+
|
|
510
|
+
Shows the saved "My Car" location.
|
|
511
|
+
|
|
512
|
+
**Constructor:**
|
|
513
|
+
```typescript
|
|
514
|
+
new PTRShowMyCarSiteCommand(
|
|
515
|
+
site: string,
|
|
516
|
+
shouldShowPopup?: boolean,
|
|
517
|
+
animationType?: number
|
|
518
|
+
)
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
**Parameters:**
|
|
522
|
+
- `site` (string): Site external identifier
|
|
523
|
+
- `shouldShowPopup` (boolean): Show popup (default: true)
|
|
524
|
+
- `animationType` (number): Animation type (default: 1)
|
|
525
|
+
|
|
526
|
+
**Example:**
|
|
527
|
+
```typescript
|
|
528
|
+
const command = new PTRShowMyCarSiteCommand("site-id", true, 1);
|
|
529
|
+
showMapWidget(reactTag, command);
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
---
|
|
533
|
+
|
|
534
|
+
#### `PTRStartAndFocusCommand`
|
|
535
|
+
|
|
536
|
+
Initializes the SDK and focuses on a location in a single command.
|
|
537
|
+
|
|
538
|
+
**Constructor:**
|
|
539
|
+
```typescript
|
|
540
|
+
new PTRStartAndFocusCommand(
|
|
541
|
+
clientId: string,
|
|
542
|
+
licenseKey: string,
|
|
543
|
+
baseUrl: string,
|
|
544
|
+
logLevel: number,
|
|
545
|
+
command: PTRSiteCommand | PTRBuildingCommand | PTRLevelCommand | PTRPoiCommand
|
|
546
|
+
)
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
**Parameters:**
|
|
550
|
+
- `clientId` (string): Client identifier
|
|
551
|
+
- `licenseKey` (string): License key
|
|
552
|
+
- `baseUrl` (string): Base URL
|
|
553
|
+
- `logLevel` (number): Log level (0-4)
|
|
554
|
+
- `command` (PTRCommand): Focus command to execute after initialization
|
|
555
|
+
|
|
556
|
+
**Example:**
|
|
557
|
+
```typescript
|
|
558
|
+
const focusCommand = new PTRSiteCommand("site-id");
|
|
559
|
+
const command = new PTRStartAndFocusCommand(
|
|
560
|
+
"client-id",
|
|
561
|
+
"license-key",
|
|
562
|
+
"https://your-instance.pointr.cloud",
|
|
563
|
+
3,
|
|
564
|
+
focusCommand
|
|
565
|
+
);
|
|
566
|
+
showMapWidget(reactTag, command);
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
---
|
|
570
|
+
|
|
571
|
+
## Utility Functions
|
|
572
|
+
|
|
573
|
+
### `showMapWidget(reactTag, command)`
|
|
574
|
+
|
|
575
|
+
Sends a command to the map widget.
|
|
576
|
+
|
|
577
|
+
**Parameters:**
|
|
578
|
+
- `reactTag` (number): The native view tag obtained from `findNodeHandle()`
|
|
579
|
+
- `command` (PTRCommand | PTRStartAndFocusCommand): The command to execute
|
|
580
|
+
|
|
581
|
+
**Example:**
|
|
582
|
+
```typescript
|
|
583
|
+
import { findNodeHandle } from 'react-native';
|
|
584
|
+
import { showMapWidget } from 'react-native-pointr/src/PTRMapWidgetUtils';
|
|
585
|
+
import { PTRSiteCommand } from 'react-native-pointr/src/PTRCommand';
|
|
586
|
+
|
|
587
|
+
const showSite = () => {
|
|
588
|
+
const reactTag = findNodeHandle(mapWidgetRef.current);
|
|
589
|
+
if (reactTag) {
|
|
590
|
+
const command = new PTRSiteCommand("site-id");
|
|
591
|
+
showMapWidget(reactTag, command);
|
|
592
|
+
}
|
|
593
|
+
};
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
---
|
|
597
|
+
|
|
598
|
+
## Event Listeners
|
|
599
|
+
|
|
600
|
+
### Position Manager Events
|
|
601
|
+
|
|
602
|
+
Subscribe to position updates using the native event emitter.
|
|
603
|
+
|
|
604
|
+
**Events:**
|
|
605
|
+
- `OnPositionManagerCalculatedLocation`: Fired when a new position is calculated
|
|
606
|
+
- `OnBuildingClicked`: Fired when a building is tapped on the map
|
|
607
|
+
- `OnSiteClicked`: Fired when a site is tapped on the map
|
|
608
|
+
- `OnGeofenceEvent`: Fired when a geofence enter/exit event occurs
|
|
609
|
+
|
|
610
|
+
**Example:**
|
|
611
|
+
```typescript
|
|
612
|
+
import { NativeEventEmitter, NativeModules } from 'react-native';
|
|
613
|
+
|
|
614
|
+
const PTREventEmitter = NativeModules.PTRNativePointrLibrary;
|
|
615
|
+
const eventEmitter = new NativeEventEmitter(PTREventEmitter);
|
|
616
|
+
|
|
617
|
+
// Listen to position updates
|
|
618
|
+
const subscription = eventEmitter.addListener(
|
|
619
|
+
'OnPositionManagerCalculatedLocation',
|
|
620
|
+
(location) => {
|
|
621
|
+
console.log('New position:', location);
|
|
622
|
+
}
|
|
623
|
+
);
|
|
624
|
+
|
|
625
|
+
// Listen to building clicks
|
|
626
|
+
const buildingSubscription = eventEmitter.addListener(
|
|
627
|
+
'OnBuildingClicked',
|
|
628
|
+
(building) => {
|
|
629
|
+
console.log('Building clicked:', building);
|
|
630
|
+
}
|
|
631
|
+
);
|
|
632
|
+
|
|
633
|
+
// Listen to geofence events
|
|
634
|
+
const geofenceSubscription = eventEmitter.addListener(
|
|
635
|
+
'OnGeofenceEvent',
|
|
636
|
+
(geofenceEvent) => {
|
|
637
|
+
console.log('Geofence event:', geofenceEvent);
|
|
638
|
+
}
|
|
639
|
+
);
|
|
640
|
+
|
|
641
|
+
// Clean up
|
|
642
|
+
subscription.remove();
|
|
643
|
+
buildingSubscription.remove();
|
|
644
|
+
geofenceSubscription.remove();
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
---
|
|
648
|
+
|
|
649
|
+
### Geofence Events
|
|
650
|
+
|
|
651
|
+
The `OnGeofenceEvent` is fired when the user enters or exits a geofence area. This feature requires the Pointr SDK to be running and geofence listeners are automatically registered when calling `start()`.
|
|
652
|
+
|
|
653
|
+
**Event Structure:**
|
|
654
|
+
```typescript
|
|
655
|
+
{
|
|
656
|
+
eventType: 'enter' | 'exit', // Event type
|
|
657
|
+
timestamp?: number, // Unix timestamp in milliseconds (iOS only)
|
|
658
|
+
geofence: {
|
|
659
|
+
id: string, // Internal geofence ID
|
|
660
|
+
externalId: string, // External geofence ID
|
|
661
|
+
name: string, // Geofence name
|
|
662
|
+
geofenceType: 'beacon' | 'gps', // Type of geofence
|
|
663
|
+
position: {
|
|
664
|
+
latitude: number, // Geofence latitude
|
|
665
|
+
longitude: number // Geofence longitude
|
|
666
|
+
}
|
|
667
|
+
},
|
|
668
|
+
geofenceNotification?: { // Optional notification data
|
|
669
|
+
id: string,
|
|
670
|
+
message: string,
|
|
671
|
+
timestamp: number // Unix timestamp in milliseconds (Android)
|
|
672
|
+
// or milliseconds (iOS)
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
```
|
|
676
|
+
|
|
677
|
+
**Platform Differences:**
|
|
678
|
+
- iOS: Includes `timestamp` field at the root level with milliseconds since epoch
|
|
679
|
+
- Android: Timestamp only available in `geofenceNotification` object
|
|
680
|
+
- Both platforms support beacon and GPS geofence types
|
|
681
|
+
|
|
682
|
+
**Example:**
|
|
683
|
+
```typescript
|
|
684
|
+
import React, { useEffect } from 'react';
|
|
685
|
+
import { NativeEventEmitter, NativeModules } from 'react-native';
|
|
686
|
+
|
|
687
|
+
function GeofenceMonitor() {
|
|
688
|
+
useEffect(() => {
|
|
689
|
+
const eventEmitter = new NativeEventEmitter(
|
|
690
|
+
NativeModules.PTRNativePointrLibrary
|
|
691
|
+
);
|
|
692
|
+
|
|
693
|
+
const geofenceSubscription = eventEmitter.addListener(
|
|
694
|
+
'OnGeofenceEvent',
|
|
695
|
+
(geofenceEvent) => {
|
|
696
|
+
console.log(`Geofence ${geofenceEvent.eventType}: ${geofenceEvent.geofence.name}`);
|
|
697
|
+
console.log(`Type: ${geofenceEvent.geofence.geofenceType}`);
|
|
698
|
+
console.log(`Location: ${geofenceEvent.geofence.position.latitude}, ${geofenceEvent.geofence.position.longitude}`);
|
|
699
|
+
|
|
700
|
+
if (geofenceEvent.geofenceNotification) {
|
|
701
|
+
console.log(`Notification: ${geofenceEvent.geofenceNotification.message}`);
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
if (geofenceEvent.timestamp) {
|
|
705
|
+
console.log(`Timestamp: ${new Date(geofenceEvent.timestamp).toISOString()}`);
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
);
|
|
709
|
+
|
|
710
|
+
return () => {
|
|
711
|
+
geofenceSubscription.remove();
|
|
712
|
+
};
|
|
713
|
+
}, []);
|
|
714
|
+
|
|
715
|
+
return null;
|
|
716
|
+
}
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
---
|
|
720
|
+
|
|
721
|
+
### Map Widget Load Events
|
|
722
|
+
|
|
723
|
+
The `onMapWidgetDidEndLoading` prop receives events when commands complete.
|
|
724
|
+
|
|
725
|
+
**Event Object:**
|
|
726
|
+
```typescript
|
|
727
|
+
{
|
|
728
|
+
command: string, // Command type that was executed
|
|
729
|
+
siteExternalIdentifier?: string,
|
|
730
|
+
buildingExternalIdentifier?: string,
|
|
731
|
+
levelIndex?: number,
|
|
732
|
+
poiExternalIdentifier?: string,
|
|
733
|
+
error?: string // Error message if command failed
|
|
734
|
+
}
|
|
735
|
+
```
|
|
736
|
+
|
|
737
|
+
**Example:**
|
|
738
|
+
```typescript
|
|
739
|
+
const handleMapWidgetDidEndLoading = (event) => {
|
|
740
|
+
const { command, siteExternalIdentifier, error } = event.nativeEvent;
|
|
741
|
+
|
|
742
|
+
if (error) {
|
|
743
|
+
console.error(`Command ${command} failed:`, error);
|
|
744
|
+
} else {
|
|
745
|
+
console.log(`Command ${command} completed for site:`, siteExternalIdentifier);
|
|
746
|
+
}
|
|
747
|
+
};
|
|
748
|
+
|
|
749
|
+
<PTRMapWidget
|
|
750
|
+
ref={ref}
|
|
751
|
+
onMapWidgetDidEndLoading={handleMapWidgetDidEndLoading}
|
|
752
|
+
/>
|
|
753
|
+
```
|
|
754
|
+
|
|
755
|
+
---
|
|
756
|
+
|
|
757
|
+
## Complete Example
|
|
758
|
+
|
|
759
|
+
```typescript
|
|
760
|
+
import React, { useRef, useEffect } from 'react';
|
|
761
|
+
import {
|
|
762
|
+
requireNativeComponent,
|
|
763
|
+
findNodeHandle,
|
|
764
|
+
NativeModules,
|
|
765
|
+
NativeEventEmitter,
|
|
766
|
+
View
|
|
767
|
+
} from 'react-native';
|
|
768
|
+
import {
|
|
769
|
+
PTRSiteCommand,
|
|
770
|
+
showMapWidget,
|
|
771
|
+
getPois,
|
|
772
|
+
type PTRPoi
|
|
773
|
+
} from 'react-native-pointr';
|
|
774
|
+
|
|
775
|
+
const PTRMapWidget = requireNativeComponent('PTRMapWidget');
|
|
776
|
+
|
|
777
|
+
function PointrMapExample() {
|
|
778
|
+
const mapRef = useRef(null);
|
|
779
|
+
|
|
780
|
+
useEffect(() => {
|
|
781
|
+
// Initialize SDK
|
|
782
|
+
NativeModules.PTRNativePointrLibrary.initialize(
|
|
783
|
+
"client-id",
|
|
784
|
+
"license-key",
|
|
785
|
+
"https://your-instance.pointr.cloud",
|
|
786
|
+
3
|
|
787
|
+
);
|
|
788
|
+
|
|
789
|
+
// Start SDK
|
|
790
|
+
NativeModules.PTRNativePointrLibrary.start((state) => {
|
|
791
|
+
console.log('Pointr state:', state);
|
|
792
|
+
|
|
793
|
+
if (state === 'running') {
|
|
794
|
+
// Show site when SDK is running
|
|
795
|
+
const reactTag = findNodeHandle(mapRef.current);
|
|
796
|
+
if (reactTag) {
|
|
797
|
+
const command = new PTRSiteCommand("site-id");
|
|
798
|
+
showMapWidget(reactTag, command);
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
// Fetch POIs for the site
|
|
802
|
+
fetchPOIs();
|
|
803
|
+
}
|
|
804
|
+
});
|
|
805
|
+
|
|
806
|
+
// Listen to position updates
|
|
807
|
+
const eventEmitter = new NativeEventEmitter(
|
|
808
|
+
NativeModules.PTRNativePointrLibrary
|
|
809
|
+
);
|
|
810
|
+
const subscription = eventEmitter.addListener(
|
|
811
|
+
'OnPositionManagerCalculatedLocation',
|
|
812
|
+
(location) => {
|
|
813
|
+
console.log('Position update:', location);
|
|
814
|
+
}
|
|
815
|
+
);
|
|
816
|
+
|
|
817
|
+
// Listen to geofence events
|
|
818
|
+
const geofenceSubscription = eventEmitter.addListener(
|
|
819
|
+
'OnGeofenceEvent',
|
|
820
|
+
(event) => {
|
|
821
|
+
console.log(`Geofence ${event.eventType}: ${event.geofence.name}`);
|
|
822
|
+
}
|
|
823
|
+
);
|
|
824
|
+
|
|
825
|
+
return () => {
|
|
826
|
+
subscription.remove();
|
|
827
|
+
geofenceSubscription.remove();
|
|
828
|
+
NativeModules.PTRNativePointrLibrary.stop();
|
|
829
|
+
};
|
|
830
|
+
}, []);
|
|
831
|
+
|
|
832
|
+
const fetchPOIs = async () => {
|
|
833
|
+
try {
|
|
834
|
+
const pois: PTRPoi[] = await getPois('site-id');
|
|
835
|
+
console.log(`Found ${pois.length} POIs`);
|
|
836
|
+
pois.forEach(poi => {
|
|
837
|
+
console.log(`${poi.name} at level ${poi.position.lvl}`);
|
|
838
|
+
});
|
|
839
|
+
} catch (error) {
|
|
840
|
+
console.error('Failed to fetch POIs:', error);
|
|
841
|
+
}
|
|
842
|
+
};
|
|
843
|
+
|
|
844
|
+
const handleMapLoaded = (event) => {
|
|
845
|
+
const { command, error } = event.nativeEvent;
|
|
846
|
+
console.log('Map command completed:', command, error);
|
|
847
|
+
};
|
|
848
|
+
|
|
849
|
+
return (
|
|
850
|
+
<View style={{ flex: 1 }}>
|
|
851
|
+
<PTRMapWidget
|
|
852
|
+
ref={mapRef}
|
|
853
|
+
style={{ flex: 1 }}
|
|
854
|
+
onMapWidgetDidEndLoading={handleMapLoaded}
|
|
855
|
+
/>
|
|
856
|
+
</View>
|
|
857
|
+
);
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
export default PointrMapExample;
|
|
861
|
+
```
|
|
862
|
+
|
|
863
|
+
---
|
|
864
|
+
|
|
865
|
+
## Error Handling
|
|
866
|
+
|
|
867
|
+
### Common Errors
|
|
868
|
+
|
|
869
|
+
- **"Pointr is not initialized"**: Call `initialize()` before other methods
|
|
870
|
+
- **"Pointr is not running"**: Call `start()` and wait for "running" state
|
|
871
|
+
- **"Failed to find node handle for ref"**: Ensure ref is properly attached to component
|
|
872
|
+
- **"No saved location"**: User hasn't marked a "My Car" location yet
|
|
873
|
+
|
|
874
|
+
### Best Practices
|
|
875
|
+
|
|
876
|
+
1. Always check the Pointr state before executing commands
|
|
877
|
+
2. Handle errors in callbacks and event handlers
|
|
878
|
+
3. Clean up event listeners when component unmounts
|
|
879
|
+
4. Use `findNodeHandle()` to get the correct native view tag
|
|
880
|
+
5. Initialize SDK before rendering the map widget
|
|
881
|
+
6. Request permissions before starting SDK if needed
|
|
882
|
+
|
|
883
|
+
---
|
|
884
|
+
|
|
885
|
+
## License
|
|
886
|
+
|
|
887
|
+
See the LICENSE file in the package root.
|