@situm/cordova 3.1.1 → 3.2.1
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/CHANGELOG_UNRELEASED.md +2 -4
- package/README.md +320 -170
- package/example/.browserslistrc +16 -0
- package/example/.editorconfig +16 -0
- package/example/.eslintrc.json +46 -0
- package/example/README.md +163 -0
- package/example/android/app/build.gradle +54 -0
- package/example/android/app/capacitor.build.gradle +27 -0
- package/example/android/app/proguard-rules.pro +21 -0
- package/example/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java +26 -0
- package/example/android/app/src/main/AndroidManifest.xml +42 -0
- package/example/android/app/src/main/java/com/situm/capacitor_example/MainActivity.java +5 -0
- package/example/android/app/src/main/res/drawable/ic_launcher_background.xml +170 -0
- package/example/android/app/src/main/res/drawable/splash.png +0 -0
- package/example/android/app/src/main/res/drawable-land-hdpi/splash.png +0 -0
- package/example/android/app/src/main/res/drawable-land-mdpi/splash.png +0 -0
- package/example/android/app/src/main/res/drawable-land-xhdpi/splash.png +0 -0
- package/example/android/app/src/main/res/drawable-land-xxhdpi/splash.png +0 -0
- package/example/android/app/src/main/res/drawable-land-xxxhdpi/splash.png +0 -0
- package/example/android/app/src/main/res/drawable-port-hdpi/splash.png +0 -0
- package/example/android/app/src/main/res/drawable-port-mdpi/splash.png +0 -0
- package/example/android/app/src/main/res/drawable-port-xhdpi/splash.png +0 -0
- package/example/android/app/src/main/res/drawable-port-xxhdpi/splash.png +0 -0
- package/example/android/app/src/main/res/drawable-port-xxxhdpi/splash.png +0 -0
- package/example/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +34 -0
- package/example/android/app/src/main/res/layout/activity_main.xml +12 -0
- package/example/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +5 -0
- package/example/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +5 -0
- package/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
- package/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png +0 -0
- package/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
- package/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
- package/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png +0 -0
- package/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
- package/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
- package/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png +0 -0
- package/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
- package/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png +0 -0
- package/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
- package/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png +0 -0
- package/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
- package/example/android/app/src/main/res/values/ic_launcher_background.xml +4 -0
- package/example/android/app/src/main/res/values/strings.xml +7 -0
- package/example/android/app/src/main/res/values/styles.xml +22 -0
- package/example/android/app/src/main/res/xml/file_paths.xml +5 -0
- package/example/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java +18 -0
- package/example/android/build.gradle +29 -0
- package/example/android/capacitor.settings.gradle +27 -0
- package/example/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/example/android/gradle/wrapper/gradle-wrapper.properties +6 -0
- package/example/android/gradle.properties +22 -0
- package/example/android/gradlew +244 -0
- package/example/android/gradlew.bat +92 -0
- package/example/android/settings.gradle +5 -0
- package/example/android/variables.gradle +16 -0
- package/example/angular.json +145 -0
- package/example/capacitor.config.json +1 -0
- package/example/capacitor.config.ts +12 -0
- package/example/docs/assets/sdk_preview.png +0 -0
- package/example/docs/assets/wyf_preview.png +0 -0
- package/example/ionic.config.json +7 -0
- package/example/ios/App/App/AppDelegate.swift +49 -0
- package/example/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png +0 -0
- package/example/ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json +14 -0
- package/example/ios/App/App/Assets.xcassets/Contents.json +6 -0
- package/example/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json +23 -0
- package/example/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png +0 -0
- package/example/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png +0 -0
- package/example/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png +0 -0
- package/example/ios/App/App/Base.lproj/LaunchScreen.storyboard +32 -0
- package/example/ios/App/App/Base.lproj/Main.storyboard +19 -0
- package/example/ios/App/App/Info.plist +55 -0
- package/example/ios/App/App.xcodeproj/project.pbxproj +408 -0
- package/example/ios/App/App.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- package/example/ios/App/App.xcworkspace/contents.xcworkspacedata +10 -0
- package/example/ios/App/App.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/example/ios/App/Podfile +32 -0
- package/example/karma.conf.js +44 -0
- package/example/package-lock.json +17234 -0
- package/example/package.json +73 -0
- package/example/src/app/app.component.html +3 -0
- package/example/src/app/app.component.scss +0 -0
- package/example/src/app/app.component.spec.ts +16 -0
- package/example/src/app/app.component.ts +12 -0
- package/example/src/app/app.routes.ts +8 -0
- package/example/src/app/sdk/sdk.page.html +109 -0
- package/example/src/app/sdk/sdk.page.scss +24 -0
- package/example/src/app/sdk/sdk.page.spec.ts +18 -0
- package/example/src/app/sdk/sdk.page.ts +440 -0
- package/example/src/app/tabs/tabs.page.html +13 -0
- package/example/src/app/tabs/tabs.page.scss +1 -0
- package/example/src/app/tabs/tabs.page.spec.ts +27 -0
- package/example/src/app/tabs/tabs.page.ts +19 -0
- package/example/src/app/tabs/tabs.routes.ts +31 -0
- package/example/src/app/utils/request.permissions.ts +68 -0
- package/example/src/app/wyf/wyf.page.html +22 -0
- package/example/src/app/wyf/wyf.page.scss +8 -0
- package/example/src/app/wyf/wyf.page.spec.ts +18 -0
- package/example/src/app/wyf/wyf.page.ts +47 -0
- package/example/src/assets/icon/favicon.png +0 -0
- package/example/src/assets/icon/situm-logo-whitebg.svg +67 -0
- package/example/src/assets/shapes.svg +1 -0
- package/example/src/constants.ts.example +6 -0
- package/example/src/environments/environment.prod.ts +3 -0
- package/example/src/environments/environment.ts +16 -0
- package/example/src/global.scss +26 -0
- package/example/src/index.html +26 -0
- package/example/src/main.ts +20 -0
- package/example/src/polyfills.ts +55 -0
- package/example/src/test.ts +14 -0
- package/example/src/theme/variables.scss +244 -0
- package/example/src/zone-flags.ts +6 -0
- package/example/tsconfig.app.json +15 -0
- package/example/tsconfig.json +30 -0
- package/example/tsconfig.spec.json +18 -0
- package/package.json +1 -1
- package/plugin.xml +1 -1
- package/src/android/app/build.gradle +1 -1
- package/src/android/situm.gradle +1 -1
- package/www/map-view-controller.js +1 -1
- package/www/map-view.js +3 -3
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
import { Component, NgZone } from '@angular/core';
|
|
2
|
+
import {
|
|
3
|
+
IonHeader,
|
|
4
|
+
IonToolbar,
|
|
5
|
+
IonTitle,
|
|
6
|
+
IonContent,
|
|
7
|
+
IonCard,
|
|
8
|
+
IonButton,
|
|
9
|
+
IonCardHeader,
|
|
10
|
+
IonCardContent,
|
|
11
|
+
IonCardTitle,
|
|
12
|
+
IonItem,
|
|
13
|
+
IonLabel,
|
|
14
|
+
IonList,
|
|
15
|
+
IonIcon,
|
|
16
|
+
IonTextarea,
|
|
17
|
+
IonRow,
|
|
18
|
+
IonPicker,
|
|
19
|
+
IonThumbnail,
|
|
20
|
+
NavController,
|
|
21
|
+
Platform,
|
|
22
|
+
} from '@ionic/angular/standalone';
|
|
23
|
+
import { NgFor, NgIf } from '@angular/common';
|
|
24
|
+
import { locate, cloudDownload, map } from 'ionicons/icons';
|
|
25
|
+
import { addIcons } from 'ionicons';
|
|
26
|
+
|
|
27
|
+
import { requestPermissions } from '../utils/request.permissions';
|
|
28
|
+
import * as Constants from '../../constants';
|
|
29
|
+
|
|
30
|
+
// Declare a cordova variable to avoid typescript errors
|
|
31
|
+
declare let cordova: any;
|
|
32
|
+
|
|
33
|
+
@Component({
|
|
34
|
+
selector: 'app-sdk',
|
|
35
|
+
templateUrl: 'sdk.page.html',
|
|
36
|
+
styleUrls: ['sdk.page.scss'],
|
|
37
|
+
standalone: true,
|
|
38
|
+
imports: [
|
|
39
|
+
IonHeader,
|
|
40
|
+
IonToolbar,
|
|
41
|
+
IonTitle,
|
|
42
|
+
IonThumbnail,
|
|
43
|
+
IonContent,
|
|
44
|
+
IonCard,
|
|
45
|
+
IonCardHeader,
|
|
46
|
+
IonCardTitle,
|
|
47
|
+
IonCardContent,
|
|
48
|
+
IonButton,
|
|
49
|
+
IonLabel,
|
|
50
|
+
IonItem,
|
|
51
|
+
IonList,
|
|
52
|
+
IonRow,
|
|
53
|
+
IonIcon,
|
|
54
|
+
IonTextarea,
|
|
55
|
+
IonPicker,
|
|
56
|
+
NgFor,
|
|
57
|
+
NgIf,
|
|
58
|
+
],
|
|
59
|
+
})
|
|
60
|
+
export class SDKPage {
|
|
61
|
+
buildings: Array<any> | undefined;
|
|
62
|
+
currentBuilding: any | undefined;
|
|
63
|
+
pois: any | undefined;
|
|
64
|
+
currentPoi: any | undefined;
|
|
65
|
+
|
|
66
|
+
constructor(
|
|
67
|
+
private ngZone: NgZone,
|
|
68
|
+
private navCtrl: NavController,
|
|
69
|
+
public platform: Platform
|
|
70
|
+
) {
|
|
71
|
+
addIcons({ locate, cloudDownload, map });
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
ionViewDidEnter() {
|
|
75
|
+
// First of all, authenticate yourself in our SDK to be able to start positioning, retrieve data, ...
|
|
76
|
+
// Make sure you are authenticated before calling any other method of our SDK.
|
|
77
|
+
cordova.plugins.Situm.setApiKey(Constants.API_USER, Constants.API_KEY);
|
|
78
|
+
|
|
79
|
+
// Use the remote configuration of your situm account.
|
|
80
|
+
// With this flag activated, you can modify your location request without any code changes.
|
|
81
|
+
// See all the parameters you can modify in https://dashboard.situm.com/settings.
|
|
82
|
+
cordova.plugins.Situm.setUseRemoteConfig(true);
|
|
83
|
+
|
|
84
|
+
// Wait until receive the MapViewController of our map and
|
|
85
|
+
// be able to send actions and receive events that occur inside it.
|
|
86
|
+
cordova.plugins.MapView.onLoad((controller: any) => {
|
|
87
|
+
// Once the MapView was loaded you can start managing our map by:
|
|
88
|
+
|
|
89
|
+
// 1. Sending actions like selecting or navigating to a poi in a building:
|
|
90
|
+
// controller.selectPoi('YOUR_POI_IDENTIFIER');
|
|
91
|
+
// controller.navigateToPoi('YOUR_POI_IDENTIFIER');
|
|
92
|
+
|
|
93
|
+
// 2. Listen to events that take place inside our map like a poi being selected or deselected:
|
|
94
|
+
controller.onPoiSelected((poiSelectedResult: any) => {
|
|
95
|
+
console.log('EXAMPLE> onPoiSelected -> ', poiSelectedResult);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
controller.onPoiDeselected((poiDeselectedResult: any) => {
|
|
99
|
+
console.log('EXAMPLE> onPoiDeselected -> ', poiDeselectedResult);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
this._executePendingAction();
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
this._retrieveSpecifiedBuilding(Constants.BUILDING_IDENTIFIER);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// ==============================================================================================
|
|
109
|
+
// = POSITIONING =
|
|
110
|
+
// ==============================================================================================
|
|
111
|
+
|
|
112
|
+
async startPositioning() {
|
|
113
|
+
if (this.positioning) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
this._setInfo('');
|
|
117
|
+
// You might want to know how we ask the all the permissions,
|
|
118
|
+
// so take a look at /src/app/utils/request.permission.ts
|
|
119
|
+
requestPermissions(
|
|
120
|
+
() => {
|
|
121
|
+
this.doStartPositioning();
|
|
122
|
+
},
|
|
123
|
+
(errorMessage: any) => {
|
|
124
|
+
this._setInfo(
|
|
125
|
+
'Something did happen while asking for permission: ' + errorMessage
|
|
126
|
+
);
|
|
127
|
+
},
|
|
128
|
+
this.platform
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
private doStartPositioning() {
|
|
133
|
+
// Start positioning in the building specified in the /src/constants.ts you created before:
|
|
134
|
+
cordova.plugins.Situm.startPositioning(
|
|
135
|
+
// In case you have multiple buildings that the user could visit,
|
|
136
|
+
// you might want to start positioning in all your buildings using global mode
|
|
137
|
+
// by specifying an empty identifier:
|
|
138
|
+
//
|
|
139
|
+
// buildingIdentifier: ''
|
|
140
|
+
[{ buildingIdentifier: Constants.BUILDING_IDENTIFIER }],
|
|
141
|
+
(res: any) => {
|
|
142
|
+
if (res && res.statusName) {
|
|
143
|
+
this._setStatus(res.statusName);
|
|
144
|
+
}
|
|
145
|
+
if (res && res.position) {
|
|
146
|
+
this._setStatus('POSITIONING');
|
|
147
|
+
this._setInfo(res);
|
|
148
|
+
}
|
|
149
|
+
this._setPositioning(true);
|
|
150
|
+
},
|
|
151
|
+
(err: any) => {
|
|
152
|
+
this._setPositioning(false);
|
|
153
|
+
this._setStatus('ERROR WHILE POSITIONING');
|
|
154
|
+
this._setInfo(err);
|
|
155
|
+
}
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
async stopPositioning() {
|
|
160
|
+
cordova.plugins.Situm.stopPositioning(
|
|
161
|
+
() => {
|
|
162
|
+
this._setPositioning(false);
|
|
163
|
+
this._setStatus('STOPPED');
|
|
164
|
+
this._setInfo('');
|
|
165
|
+
},
|
|
166
|
+
(err: any) => {
|
|
167
|
+
this._setStatus('ERROR');
|
|
168
|
+
this._setInfo(err);
|
|
169
|
+
}
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// ==============================================================================================
|
|
174
|
+
// = FETCH RESOURCES =
|
|
175
|
+
// ==============================================================================================
|
|
176
|
+
|
|
177
|
+
public fetchBuildingInfo() {
|
|
178
|
+
this._setStatus('FETCHING BUILDING INFO ...');
|
|
179
|
+
|
|
180
|
+
cordova.plugins.Situm.fetchBuildingInfo(
|
|
181
|
+
this.currentBuilding,
|
|
182
|
+
(res: any) => {
|
|
183
|
+
this._setStatus('LOADED BUILDING INFO');
|
|
184
|
+
this._setInfo(res);
|
|
185
|
+
},
|
|
186
|
+
(err: any) => {
|
|
187
|
+
this._setStatus('ERROR FETCHING BUILDING INFO');
|
|
188
|
+
this._setInfo(err);
|
|
189
|
+
}
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
public fetchPois() {
|
|
194
|
+
this._setStatus('FETCHING BUILDING INDOOR POIS ...');
|
|
195
|
+
|
|
196
|
+
cordova.plugins.Situm.fetchIndoorPOIsFromBuilding(
|
|
197
|
+
this.currentBuilding,
|
|
198
|
+
(res: any) => {
|
|
199
|
+
this.pois = res;
|
|
200
|
+
this._setStatus('LOADED BUILDING INDOOR POIS');
|
|
201
|
+
this._setInfo(res);
|
|
202
|
+
},
|
|
203
|
+
(err: any) => {
|
|
204
|
+
this._setStatus('ERROR FETCHING INDOOR POIS');
|
|
205
|
+
this._setInfo(err);
|
|
206
|
+
}
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
public fetchPoiCategories() {
|
|
211
|
+
this._setStatus('FETCHING POI CATEGORIES ...');
|
|
212
|
+
|
|
213
|
+
cordova.plugins.Situm.fetchPoiCategories(
|
|
214
|
+
(poiCategories: any) => {
|
|
215
|
+
this._setStatus('LOADED POI CATEGORIES');
|
|
216
|
+
this._setInfo(poiCategories);
|
|
217
|
+
},
|
|
218
|
+
(err: any) => {
|
|
219
|
+
this._setStatus('ERROR FETCHING POI CATEGORIES');
|
|
220
|
+
this._setInfo(err);
|
|
221
|
+
}
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
public fetchGeofences() {
|
|
226
|
+
this._setStatus('FETCHING BUILDING GEOFENCES ...');
|
|
227
|
+
|
|
228
|
+
cordova.plugins.Situm.fetchGeofencesFromBuilding(
|
|
229
|
+
this.currentBuilding,
|
|
230
|
+
(geofences: any) => {
|
|
231
|
+
this._setStatus('LOADED BUILDING GEOFENCES');
|
|
232
|
+
this._setInfo(geofences);
|
|
233
|
+
},
|
|
234
|
+
(err: any) => {
|
|
235
|
+
this._setStatus('ERROR FETCHING GEOFENCES');
|
|
236
|
+
console.error(err);
|
|
237
|
+
this._setInfo(err);
|
|
238
|
+
}
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
public invalidateCache() {
|
|
243
|
+
cordova.plugins.Situm.invalidateCache();
|
|
244
|
+
this._setInfo('The cache was invalidated.');
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// ==============================================================================================
|
|
248
|
+
// = CARTOGRAPHY =
|
|
249
|
+
// ==============================================================================================
|
|
250
|
+
|
|
251
|
+
public selectPoi() {
|
|
252
|
+
if (!this.currentPoi) {
|
|
253
|
+
this._setInfo('Select a POI before calling selectPoi() ');
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
this._checkMapViewerIsLoaded(() => {
|
|
258
|
+
cordova.plugins.MapViewController.selectPoi(this.currentPoi.identifier);
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
this._transitionToWYFTab();
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
public navigateToPoi() {
|
|
265
|
+
if (!this.currentPoi) {
|
|
266
|
+
this._setInfo('Select a POI before calling navigateToPoi() ');
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
this._checkMapViewerIsLoaded(() => {
|
|
271
|
+
// See https://developers.situm.com/sdk_documentation/cordova/jsdoc/latest/mapviewcontrollerimpl#navigateToPoi
|
|
272
|
+
cordova.plugins.MapViewController.navigateToPoi(
|
|
273
|
+
this.currentPoi.identifier,
|
|
274
|
+
'CHOOSE_SHORTEST' // 'CHOOSE_SHORTEST' | 'ONLY_ACCESSIBLE' | 'ONLY_NOT_ACCESSIBLE_FLOOR_CHANGES' | undefined
|
|
275
|
+
);
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
this._transitionToWYFTab();
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// ==============================================================================================
|
|
282
|
+
// = INTERNAL APP METHODS =
|
|
283
|
+
// ==============================================================================================
|
|
284
|
+
|
|
285
|
+
currentStatus: string = 'NOT STARTED';
|
|
286
|
+
positioning: boolean = false;
|
|
287
|
+
currentPositioningInfo: string = 'NOT STARTED';
|
|
288
|
+
|
|
289
|
+
private _setStatus(status: string) {
|
|
290
|
+
this.ngZone.run(() => {
|
|
291
|
+
this.currentStatus = status;
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
private _setInfo(jsonRes: string) {
|
|
296
|
+
// console.log(JSON.stringify(jsonRes, null, 2));
|
|
297
|
+
this.ngZone.run(() => {
|
|
298
|
+
this.currentPositioningInfo =
|
|
299
|
+
jsonRes == '' || jsonRes == undefined
|
|
300
|
+
? ''
|
|
301
|
+
: JSON.stringify(jsonRes, null, 2);
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
private _setPositioning(positioning: boolean) {
|
|
306
|
+
this.ngZone.run(() => {
|
|
307
|
+
this.positioning = positioning;
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
private _retrieveSpecifiedBuilding(buildingIdentifier: string) {
|
|
312
|
+
// We are initially fetching the building specified in Constants.BUILDING_IDENTIFIER
|
|
313
|
+
this._loadBuildings((buildings: any) => {
|
|
314
|
+
this.currentBuilding = buildings.find(
|
|
315
|
+
(b: any) => b.buildingIdentifier == buildingIdentifier
|
|
316
|
+
);
|
|
317
|
+
// And its POIs
|
|
318
|
+
this._loadPoisFrom(this.currentBuilding, (pois: any) => {
|
|
319
|
+
// Finally, we also populate the POI picker with the building's pois
|
|
320
|
+
this._populatePOIPicker(pois);
|
|
321
|
+
});
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
private _loadBuildings(successCb: Function) {
|
|
326
|
+
if (this.buildings) return;
|
|
327
|
+
console.log('EXAMPLE> fetching all buildings ...');
|
|
328
|
+
// Fetch all buildings:
|
|
329
|
+
cordova.plugins.Situm.fetchBuildings(
|
|
330
|
+
(res: any) => {
|
|
331
|
+
this.buildings = res;
|
|
332
|
+
console.log('EXAMPLE> buildings loaded');
|
|
333
|
+
console.info('EXAMPLE> data:\n', res);
|
|
334
|
+
successCb(this.buildings);
|
|
335
|
+
},
|
|
336
|
+
(err: any) => {
|
|
337
|
+
console.error(
|
|
338
|
+
'EXAMPLE> error while fetching all buildings, error:\n',
|
|
339
|
+
err
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
private _loadPoisFrom(b: any, successCb: Function) {
|
|
346
|
+
console.log(
|
|
347
|
+
`EXAMPLE> fetching indoor pois from ${b.buildingIdentifier} - ${b.name} ...`
|
|
348
|
+
);
|
|
349
|
+
// Fetch indoor pois from the building of Constants.BUILDING_IDENTIFIER:
|
|
350
|
+
cordova.plugins.Situm.fetchIndoorPOIsFromBuilding(
|
|
351
|
+
b,
|
|
352
|
+
(res: any) => {
|
|
353
|
+
this.pois = res;
|
|
354
|
+
console.log('EXAMPLE> indoor pois loaded');
|
|
355
|
+
console.info('EXAMPLE> data:\n', res);
|
|
356
|
+
successCb(this.pois);
|
|
357
|
+
},
|
|
358
|
+
(err: any) => {
|
|
359
|
+
console.error(
|
|
360
|
+
`EXAMPLE> error while fetching indoor pois, error:\n ${err}`
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// ion-picker
|
|
367
|
+
|
|
368
|
+
isPOIPickerVisible = true;
|
|
369
|
+
|
|
370
|
+
public pickerColumns = [
|
|
371
|
+
{
|
|
372
|
+
name: 'pois',
|
|
373
|
+
options: [
|
|
374
|
+
{
|
|
375
|
+
text: 'Do fetchPois() before selecting a POI',
|
|
376
|
+
value: 'empty',
|
|
377
|
+
},
|
|
378
|
+
],
|
|
379
|
+
},
|
|
380
|
+
];
|
|
381
|
+
|
|
382
|
+
public pickerButtons = [
|
|
383
|
+
{
|
|
384
|
+
text: 'Cancel',
|
|
385
|
+
role: 'cancel',
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
text: 'Confirm',
|
|
389
|
+
handler: (value: any) => {
|
|
390
|
+
console.log('EXAMPLE> poi-picker> currentPoi: ', value.pois.value);
|
|
391
|
+
this.ngZone.run(() => {
|
|
392
|
+
this.currentPoi = value.pois.value;
|
|
393
|
+
});
|
|
394
|
+
},
|
|
395
|
+
},
|
|
396
|
+
];
|
|
397
|
+
|
|
398
|
+
private _populatePOIPicker(pois: any) {
|
|
399
|
+
this.pickerColumns[0].options = [];
|
|
400
|
+
for (let poi of pois) {
|
|
401
|
+
this.pickerColumns[0].options.push({
|
|
402
|
+
text: poi.poiName,
|
|
403
|
+
value: poi,
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
this.pickerColumns[0].options.sort((a, b) => {
|
|
407
|
+
const textA = a.text.toLowerCase();
|
|
408
|
+
const textB = b.text.toLowerCase();
|
|
409
|
+
return textA.localeCompare(textB);
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// deeplinking extra code
|
|
414
|
+
|
|
415
|
+
_doAfterMapViewIsLoaded: Function | undefined = () => {};
|
|
416
|
+
|
|
417
|
+
private _checkMapViewerIsLoaded(cb: Function) {
|
|
418
|
+
if (this._doAfterMapViewIsLoaded != undefined) {
|
|
419
|
+
this._doAfterMapViewIsLoaded = () => {
|
|
420
|
+
cb();
|
|
421
|
+
};
|
|
422
|
+
} else {
|
|
423
|
+
cb();
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
private _executePendingAction() {
|
|
428
|
+
if (
|
|
429
|
+
this._doAfterMapViewIsLoaded != undefined &&
|
|
430
|
+
typeof this._doAfterMapViewIsLoaded === 'function'
|
|
431
|
+
) {
|
|
432
|
+
this._doAfterMapViewIsLoaded();
|
|
433
|
+
this._doAfterMapViewIsLoaded = undefined;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
private _transitionToWYFTab() {
|
|
438
|
+
this.navCtrl.navigateRoot('/tabs/wyf');
|
|
439
|
+
}
|
|
440
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<ion-tabs>
|
|
2
|
+
<ion-tab-bar slot="bottom">
|
|
3
|
+
<ion-tab-button tab="sdk" href="/tabs/sdk">
|
|
4
|
+
<ion-icon aria-hidden="true" name="compass-outline"></ion-icon>
|
|
5
|
+
<ion-label>SDK</ion-label>
|
|
6
|
+
</ion-tab-button>
|
|
7
|
+
|
|
8
|
+
<ion-tab-button tab="wyf" href="/tabs/wyf">
|
|
9
|
+
<ion-icon aria-hidden="true" name="map-outline"></ion-icon>
|
|
10
|
+
<ion-label>WYF</ion-label>
|
|
11
|
+
</ion-tab-button>
|
|
12
|
+
</ion-tab-bar>
|
|
13
|
+
</ion-tabs>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
2
|
+
import { RouterTestingModule } from '@angular/router/testing';
|
|
3
|
+
|
|
4
|
+
import { TabsPage } from './tabs.page';
|
|
5
|
+
|
|
6
|
+
describe('TabsPage', () => {
|
|
7
|
+
let component: TabsPage;
|
|
8
|
+
let fixture: ComponentFixture<TabsPage>;
|
|
9
|
+
|
|
10
|
+
beforeEach(async () => {
|
|
11
|
+
TestBed.overrideComponent(TabsPage, {
|
|
12
|
+
add: {
|
|
13
|
+
imports: [RouterTestingModule]
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
fixture = TestBed.createComponent(TabsPage);
|
|
20
|
+
component = fixture.componentInstance;
|
|
21
|
+
fixture.detectChanges();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('should create', () => {
|
|
25
|
+
expect(component).toBeTruthy();
|
|
26
|
+
});
|
|
27
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Component, EnvironmentInjector, inject } from '@angular/core';
|
|
2
|
+
import { IonTabs, IonTabBar, IonTabButton, IonIcon, IonLabel } from '@ionic/angular/standalone';
|
|
3
|
+
import { addIcons } from 'ionicons';
|
|
4
|
+
import { compassOutline, mapOutline, squareOutline } from 'ionicons/icons';
|
|
5
|
+
|
|
6
|
+
@Component({
|
|
7
|
+
selector: 'app-tabs',
|
|
8
|
+
templateUrl: 'tabs.page.html',
|
|
9
|
+
styleUrls: ['tabs.page.scss'],
|
|
10
|
+
standalone: true,
|
|
11
|
+
imports: [IonTabs, IonTabBar, IonTabButton, IonIcon, IonLabel],
|
|
12
|
+
})
|
|
13
|
+
export class TabsPage {
|
|
14
|
+
public environmentInjector = inject(EnvironmentInjector);
|
|
15
|
+
|
|
16
|
+
constructor() {
|
|
17
|
+
addIcons({ compassOutline, mapOutline, squareOutline });
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Routes } from '@angular/router';
|
|
2
|
+
import { TabsPage } from './tabs.page';
|
|
3
|
+
|
|
4
|
+
export const routes: Routes = [
|
|
5
|
+
{
|
|
6
|
+
path: 'tabs',
|
|
7
|
+
component: TabsPage,
|
|
8
|
+
children: [
|
|
9
|
+
{
|
|
10
|
+
path: 'sdk',
|
|
11
|
+
loadComponent: () =>
|
|
12
|
+
import('../sdk/sdk.page').then((m) => m.SDKPage),
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
path: 'wyf',
|
|
16
|
+
loadComponent: () =>
|
|
17
|
+
import('../wyf/wyf.page').then((m) => m.WYFPage),
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
path: '',
|
|
21
|
+
redirectTo: '/tabs/sdk',
|
|
22
|
+
pathMatch: 'full',
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
path: '',
|
|
28
|
+
redirectTo: '/tabs/sdk',
|
|
29
|
+
pathMatch: 'full',
|
|
30
|
+
},
|
|
31
|
+
];
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Platform } from '@ionic/angular/standalone';
|
|
2
|
+
|
|
3
|
+
declare let cordova: any;
|
|
4
|
+
|
|
5
|
+
export function requestPermissions(
|
|
6
|
+
successCb: Function,
|
|
7
|
+
errorCb: Function,
|
|
8
|
+
platform: Platform
|
|
9
|
+
) {
|
|
10
|
+
if (platform.is('android')) {
|
|
11
|
+
cordova.plugins.diagnostic.requestRuntimePermissions(
|
|
12
|
+
function (permissions: Map<string, string>) {
|
|
13
|
+
console.log('EXAMPLE> permissions statuses: ', permissions);
|
|
14
|
+
successCb();
|
|
15
|
+
},
|
|
16
|
+
function (error: any) {
|
|
17
|
+
errorCb(JSON.stringify(error));
|
|
18
|
+
},
|
|
19
|
+
[
|
|
20
|
+
// Android
|
|
21
|
+
// We ask this permission to obtain the GPS data of the user and paint it on our map.
|
|
22
|
+
cordova.plugins.diagnostic.permission.ACCESS_FINE_LOCATION,
|
|
23
|
+
// We ask this last 2 permissions to improve the accuracy of our SDK when locating the user.
|
|
24
|
+
cordova.plugins.diagnostic.permission.BLUETOOTH_CONNECT,
|
|
25
|
+
cordova.plugins.diagnostic.permission.BLUETOOTH_SCAN,
|
|
26
|
+
]
|
|
27
|
+
);
|
|
28
|
+
} else if (platform.is('ios')) {
|
|
29
|
+
cordova.plugins.diagnostic.getLocationAuthorizationStatus(
|
|
30
|
+
(status: string) => {
|
|
31
|
+
if (status == 'authorized') {
|
|
32
|
+
successCb();
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
() => {
|
|
37
|
+
// Do nothing
|
|
38
|
+
}
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
// iOS
|
|
42
|
+
// We just need to ask for the location permission.
|
|
43
|
+
cordova.plugins.diagnostic.requestLocationAuthorization(
|
|
44
|
+
function (status: string) {
|
|
45
|
+
switch (status) {
|
|
46
|
+
case cordova.plugins.diagnostic.permissionStatus.NOT_REQUESTED:
|
|
47
|
+
errorCb('Permission not requested');
|
|
48
|
+
break;
|
|
49
|
+
case cordova.plugins.diagnostic.permissionStatus.DENIED_ALWAYS:
|
|
50
|
+
errorCb('Permission denied');
|
|
51
|
+
break;
|
|
52
|
+
case cordova.plugins.diagnostic.permissionStatus.GRANTED:
|
|
53
|
+
console.log('Permission granted always');
|
|
54
|
+
successCb();
|
|
55
|
+
break;
|
|
56
|
+
case cordova.plugins.diagnostic.permissionStatus.GRANTED_WHEN_IN_USE:
|
|
57
|
+
console.log('Permission granted only when in use');
|
|
58
|
+
successCb();
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
function (error: any) {
|
|
63
|
+
errorCb(JSON.stringify(error));
|
|
64
|
+
},
|
|
65
|
+
cordova.plugins.diagnostic.locationAuthorizationMode.ALWAYS
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<ion-header [translucent]="true">
|
|
2
|
+
<ion-toolbar mode="md">
|
|
3
|
+
<ion-thumbnail slot="start">
|
|
4
|
+
<img src="../../assets/icon/situm-logo-whitebg.svg" />
|
|
5
|
+
</ion-thumbnail>
|
|
6
|
+
<ion-title slot="start"> Situm Capacitor Example </ion-title>
|
|
7
|
+
</ion-toolbar>
|
|
8
|
+
</ion-header>
|
|
9
|
+
|
|
10
|
+
<ion-content [fullscreen]="true">
|
|
11
|
+
<!-- Add this component to your body -->
|
|
12
|
+
<!-- Retreive your situm api-key here https://dashboard.situm.com/accounts/profile -->
|
|
13
|
+
<!-- Follow this guide (https://situm.com/docs/sdk-cartography/#building-identifier)
|
|
14
|
+
to find out the identifier of the building you want to display -->
|
|
15
|
+
<map-view
|
|
16
|
+
viewer-domain="https://map-viewer.situm.com"
|
|
17
|
+
situm-api-key="YOUR_SITUM_API_KEY"
|
|
18
|
+
building-identifier="YOUR_BUILDING_IDENTIFIER"
|
|
19
|
+
#mapView
|
|
20
|
+
/>
|
|
21
|
+
<!-- WARNING: We will be overwritting this attributes with the values in constants.ts -->
|
|
22
|
+
</ion-content>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
2
|
+
|
|
3
|
+
import { WYFPage } from './wyf.page';
|
|
4
|
+
|
|
5
|
+
describe('WYFPage', () => {
|
|
6
|
+
let component: WYFPage;
|
|
7
|
+
let fixture: ComponentFixture<WYFPage>;
|
|
8
|
+
|
|
9
|
+
beforeEach(async () => {
|
|
10
|
+
fixture = TestBed.createComponent(WYFPage);
|
|
11
|
+
component = fixture.componentInstance;
|
|
12
|
+
fixture.detectChanges();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('should create', () => {
|
|
16
|
+
expect(component).toBeTruthy();
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CUSTOM_ELEMENTS_SCHEMA,
|
|
3
|
+
Component,
|
|
4
|
+
ElementRef,
|
|
5
|
+
ViewChild,
|
|
6
|
+
} from '@angular/core';
|
|
7
|
+
import {
|
|
8
|
+
IonHeader,
|
|
9
|
+
IonToolbar,
|
|
10
|
+
IonTitle,
|
|
11
|
+
IonContent,
|
|
12
|
+
IonThumbnail,
|
|
13
|
+
} from '@ionic/angular/standalone';
|
|
14
|
+
|
|
15
|
+
import * as Constants from 'src/constants';
|
|
16
|
+
|
|
17
|
+
@Component({
|
|
18
|
+
selector: 'app-wyf',
|
|
19
|
+
templateUrl: 'wyf.page.html',
|
|
20
|
+
// Make sure you declare that you are using our custom HTMLElement with:
|
|
21
|
+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
22
|
+
styleUrls: ['wyf.page.scss'],
|
|
23
|
+
standalone: true,
|
|
24
|
+
imports: [IonHeader, IonToolbar, IonTitle, IonThumbnail, IonContent],
|
|
25
|
+
})
|
|
26
|
+
export class WYFPage {
|
|
27
|
+
@ViewChild('mapView') mapView: ElementRef | undefined;
|
|
28
|
+
|
|
29
|
+
// Internal code
|
|
30
|
+
// Set the credentials inside the HTMLElement with the values in constants.ts
|
|
31
|
+
ngAfterViewInit() {
|
|
32
|
+
this.mapView?.nativeElement.setAttribute(
|
|
33
|
+
'viewer-domain',
|
|
34
|
+
Constants.VIEWER_DOMAIN
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
this.mapView?.nativeElement.setAttribute(
|
|
38
|
+
'situm-api-key',
|
|
39
|
+
Constants.API_KEY
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
this.mapView?.nativeElement.setAttribute(
|
|
43
|
+
'building-identifier',
|
|
44
|
+
Constants.BUILDING_IDENTIFIER
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
}
|