@nativescript-community/ui-mapbox 6.2.15 → 6.2.20
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.md +13 -93
- package/README.md +72 -12
- package/blueprint.md +922 -0
- package/common.d.ts +199 -0
- package/common.js +44 -4
- package/expression/expression-parser.ios.js +1 -1
- package/geo.utils.d.ts +13 -0
- package/geo.utils.js +14 -1
- package/index.android.d.ts +332 -1
- package/index.android.js +452 -21
- package/index.ios.d.ts +179 -0
- package/index.ios.js +356 -269
- package/layers/layer-factory.android.js +2 -1
- package/layers/layer-factory.ios.js +4 -1
- package/layers/parser/property-parser.android.js +1 -0
- package/layers/parser/property-parser.ios.js +3 -3
- package/package.json +3 -3
- package/platforms/android/ui_mapbox.aar +0 -0
package/index.android.js
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Android Implementation
|
|
3
|
+
*
|
|
4
|
+
* @todo FIXME: The gcFix() implementation currently assumes only one map visible at a time.
|
|
5
|
+
*/
|
|
1
6
|
import { request } from '@nativescript-community/perms';
|
|
2
|
-
import { AndroidApplication, Application, Color, File, Http, ImageSource, Trace, Utils, knownFolders, path } from '@nativescript/core';
|
|
7
|
+
import { AndroidApplication, Application, Color, File, Http, Image, ImageSource, Trace, Utils, knownFolders, path } from '@nativescript/core';
|
|
3
8
|
import { ExpressionParser } from './expression/expression-parser';
|
|
4
9
|
import { Layer, LayerFactory } from './layers/layer-factory';
|
|
5
|
-
import { CLog, CLogTypes, MapStyle, MapboxCommon, MapboxViewBase, telemetryProperty } from './common';
|
|
10
|
+
import { CLog, CLogTypes, MapStyle, MapboxCommon, MapboxTraceCategory, MapboxViewBase, telemetryProperty } from './common';
|
|
11
|
+
// Export the enums for devs not using TS
|
|
6
12
|
export * from './common';
|
|
7
13
|
function _getLocation(loc) {
|
|
8
14
|
if (loc === null) {
|
|
@@ -41,17 +47,39 @@ export function setLogLevel(level) {
|
|
|
41
47
|
}
|
|
42
48
|
Logger.setVerbosity(loggingLevel);
|
|
43
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* A map view created in XML.
|
|
52
|
+
*
|
|
53
|
+
* This is the class that is created when the Mapbox XML tag
|
|
54
|
+
* is encountered while parsing a view.
|
|
55
|
+
*
|
|
56
|
+
* Angular components need to register the Mapbox tag as follows:
|
|
57
|
+
*
|
|
58
|
+
* import { registerElement } from "nativescript-angular/element-registry";
|
|
59
|
+
* registerElement( "Mapbox", () => require("nativescript-mapbox").MapboxView);
|
|
60
|
+
*
|
|
61
|
+
* The registerElement call is what binds the XML tag to the class that creates it.
|
|
62
|
+
*
|
|
63
|
+
* @see MapboxViewBase
|
|
64
|
+
*/
|
|
44
65
|
export class MapboxView extends MapboxViewBase {
|
|
45
66
|
constructor() {
|
|
46
67
|
super();
|
|
47
68
|
this.settings = null;
|
|
69
|
+
// whether or not the view has already been initialized.
|
|
70
|
+
// see initNativeView()
|
|
48
71
|
this.initialized = false;
|
|
49
72
|
if (Trace.isEnabled()) {
|
|
50
73
|
CLog(CLogTypes.info, 'constructor(): building new MapboxView object.');
|
|
51
74
|
}
|
|
52
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* programmatically include settings
|
|
78
|
+
*/
|
|
53
79
|
setConfig(settings) {
|
|
80
|
+
// zoom level is not applied unless center is set
|
|
54
81
|
if (settings.zoomLevel && !settings.center) {
|
|
82
|
+
// Eiffel tower, Paris
|
|
55
83
|
settings.center = {
|
|
56
84
|
lat: 48.858093,
|
|
57
85
|
lng: 2.294694
|
|
@@ -62,9 +90,36 @@ export class MapboxView extends MapboxViewBase {
|
|
|
62
90
|
getNativeMapView() {
|
|
63
91
|
return this.nativeMapView;
|
|
64
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Return the Mapbox() API Shim instance
|
|
95
|
+
*
|
|
96
|
+
* This returns a reference to the Mapbox API shim class instance.
|
|
97
|
+
* See class Mapbox below.
|
|
98
|
+
*
|
|
99
|
+
* @see Mapbox
|
|
100
|
+
*/
|
|
65
101
|
getMapboxApi() {
|
|
66
102
|
return this.mapbox;
|
|
67
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Creates the native view.
|
|
106
|
+
*
|
|
107
|
+
* This method is supposed to create the native view. NativeScript caches
|
|
108
|
+
* and re-uses views to save on memory and increase performance. Unfortunately,
|
|
109
|
+
* the inner details of exactly how this is done is challenging to tease apart.
|
|
110
|
+
*
|
|
111
|
+
* The problem is that in order to create the Mapbox view we need the access token from
|
|
112
|
+
* the XML, but in the case of a pure NativeScript app with property binding
|
|
113
|
+
* (see the demo), the properties don't seem to be available until the page is loaded.
|
|
114
|
+
*
|
|
115
|
+
* As a workaround, I wait until the page is loaded to configure the map. See initNativeView.
|
|
116
|
+
*
|
|
117
|
+
* It seems to me there should be a better way.
|
|
118
|
+
*
|
|
119
|
+
* @link https://docs.nativescript.org/core-concepts/properties#views-lifecycle-and-recycling
|
|
120
|
+
*
|
|
121
|
+
* @todo check this.
|
|
122
|
+
*/
|
|
68
123
|
createNativeView() {
|
|
69
124
|
if (Trace.isEnabled()) {
|
|
70
125
|
CLog(CLogTypes.info, 'createNativeView(): top');
|
|
@@ -90,28 +145,56 @@ export class MapboxView extends MapboxViewBase {
|
|
|
90
145
|
CLog(CLogTypes.info, 'initNativeView(): top');
|
|
91
146
|
}
|
|
92
147
|
this.nativeView.owner = this;
|
|
148
|
+
// Application.android.on(AndroidApplication.activityStartedEvent, this.onStart, this);
|
|
93
149
|
Application.android.on(AndroidApplication.activityPausedEvent, this.onPause, this);
|
|
94
150
|
Application.android.on(AndroidApplication.activityResumedEvent, this.onResume, this);
|
|
151
|
+
// Application.android.on(AndroidApplication.activityStartedEvent, this.onStop, this);
|
|
95
152
|
super.initNativeView();
|
|
96
153
|
}
|
|
154
|
+
/**
|
|
155
|
+
* when the view is destroyed.
|
|
156
|
+
*
|
|
157
|
+
* This is called by the framework when the view is actually destroyed.
|
|
158
|
+
* NativeScript, by design, tries to cache native views because
|
|
159
|
+
* creating native views is expensive.
|
|
160
|
+
*
|
|
161
|
+
* @link https://docs.nativescript.org/plugins/ui-plugin-custom
|
|
162
|
+
*/
|
|
97
163
|
disposeNativeView() {
|
|
98
164
|
if (Trace.isEnabled()) {
|
|
99
165
|
CLog(CLogTypes.info, 'disposeNativeView(): top');
|
|
100
166
|
}
|
|
101
167
|
this.nativeView.owner = null;
|
|
168
|
+
// Application.android.off(AndroidApplication.activityStartedEvent, this.onStart, this);
|
|
102
169
|
Application.android.off(AndroidApplication.activityPausedEvent, this.onPause, this);
|
|
103
170
|
Application.android.off(AndroidApplication.activityResumedEvent, this.onResume, this);
|
|
171
|
+
// Application.android.off(AndroidApplication.activityStartedEvent, this.onStop, this);
|
|
104
172
|
if (this.mapbox) {
|
|
105
173
|
this.mapbox.destroy();
|
|
106
174
|
}
|
|
107
175
|
super.disposeNativeView();
|
|
108
176
|
}
|
|
177
|
+
/**
|
|
178
|
+
* initialize the map
|
|
179
|
+
*
|
|
180
|
+
* This method creates a new mapbox API instance and, through the show() method of the Mapbox API,
|
|
181
|
+
* creates a Mapbox native map view.
|
|
182
|
+
*
|
|
183
|
+
* @see show()
|
|
184
|
+
*
|
|
185
|
+
* @link https://docs.nativescript.org/core-concepts/events
|
|
186
|
+
*
|
|
187
|
+
* @todo FIXME: this.nativeMapView is unused and never actually set to anything.
|
|
188
|
+
*/
|
|
109
189
|
initMap() {
|
|
110
190
|
if (Trace.isEnabled()) {
|
|
111
191
|
CLog(CLogTypes.info, "MapboxView:initMap(): top - accessToken is '" + this.config.accessToken + "'", this.config);
|
|
112
192
|
}
|
|
113
193
|
if (!this.nativeMapView && ((this.config && this.config.accessToken) || (this.settings && this.settings.accessToken))) {
|
|
114
194
|
this.mapbox = new Mapbox(this);
|
|
195
|
+
// the NativeScript contentview class extends from Observable to provide the notify method
|
|
196
|
+
// which is the glue that joins this code with whatever callbacks are set in the Mapbox XML
|
|
197
|
+
// tag describing the map.
|
|
115
198
|
const options = {
|
|
116
199
|
context: this._context,
|
|
117
200
|
parentView: this.nativeView,
|
|
@@ -223,6 +306,16 @@ export class MapboxView extends MapboxViewBase {
|
|
|
223
306
|
}
|
|
224
307
|
}
|
|
225
308
|
}
|
|
309
|
+
/**
|
|
310
|
+
* A NativeScript shim for the Mapbox API.
|
|
311
|
+
*
|
|
312
|
+
* This implements a Typescript shim over the Native Mapbox GL Android API.
|
|
313
|
+
*
|
|
314
|
+
* It is created in one of two ways:
|
|
315
|
+
*
|
|
316
|
+
* - directly via let mapbox = new Mapbox(); mapbox.show( ... )
|
|
317
|
+
* - via the Mapbox XML tag in which case a MapboxView object is created which hosts a reference to this class. (See MapboxView::getMapboxAPI())
|
|
318
|
+
*/
|
|
226
319
|
export class Mapbox extends MapboxCommon {
|
|
227
320
|
constructor(view) {
|
|
228
321
|
super(view);
|
|
@@ -233,7 +326,9 @@ export class Mapbox extends MapboxCommon {
|
|
|
233
326
|
this._markers = [];
|
|
234
327
|
this._polylines = [];
|
|
235
328
|
this._polygons = [];
|
|
329
|
+
// list of polylines
|
|
236
330
|
this.lines = [];
|
|
331
|
+
// registered callbacks.
|
|
237
332
|
this.eventCallbacks = {};
|
|
238
333
|
this._markerIconDownloadCache = [];
|
|
239
334
|
this.iconCache = {};
|
|
@@ -245,7 +340,29 @@ export class Mapbox extends MapboxCommon {
|
|
|
245
340
|
CLog(CLogTypes.info, 'constructor(): end of Mapbox constructor.');
|
|
246
341
|
}
|
|
247
342
|
}
|
|
343
|
+
/**
|
|
344
|
+
* not used
|
|
345
|
+
*/
|
|
248
346
|
setMapboxViewInstance(mapboxViewInstance) { }
|
|
347
|
+
/**
|
|
348
|
+
* show the map programmatically.
|
|
349
|
+
*
|
|
350
|
+
* This method is used to programmatically display a map. It is also called
|
|
351
|
+
* by the MapboxView::init() method which initializes the map when the Mapbox
|
|
352
|
+
* XML tags is encountered
|
|
353
|
+
*
|
|
354
|
+
* options may additionally include:
|
|
355
|
+
*
|
|
356
|
+
* - context
|
|
357
|
+
* - parentView
|
|
358
|
+
* - onLocationPermissionGranted
|
|
359
|
+
* - onLocationPermissionDenied
|
|
360
|
+
* - onMapReady
|
|
361
|
+
*
|
|
362
|
+
* @see MapboxView::init()
|
|
363
|
+
*
|
|
364
|
+
* @todo FIXME: the timeout delay before showing the map works around some race condition. The source error needs to be figured out.
|
|
365
|
+
*/
|
|
249
366
|
show(options) {
|
|
250
367
|
return new Promise((resolve, reject) => {
|
|
251
368
|
try {
|
|
@@ -254,10 +371,14 @@ export class Mapbox extends MapboxCommon {
|
|
|
254
371
|
if (Trace.isEnabled()) {
|
|
255
372
|
CLog(CLogTypes.info, 'show()');
|
|
256
373
|
}
|
|
374
|
+
// if no accessToken was set the app may crash.
|
|
375
|
+
//
|
|
376
|
+
// FIXME: Even if using a local server add some string.
|
|
257
377
|
if (settings.accessToken === undefined) {
|
|
258
378
|
reject('mapbox_accesstoken_missing');
|
|
259
379
|
return;
|
|
260
380
|
}
|
|
381
|
+
// if already added, make sure it's removed first
|
|
261
382
|
if (this._mapboxViewInstance) {
|
|
262
383
|
if (Trace.isEnabled()) {
|
|
263
384
|
CLog(CLogTypes.info, 'show(): view already created. Removing it.');
|
|
@@ -275,10 +396,20 @@ export class Mapbox extends MapboxCommon {
|
|
|
275
396
|
if (settings.context) {
|
|
276
397
|
context = settings.context;
|
|
277
398
|
}
|
|
399
|
+
// Per the Mapbox Android Native samples:
|
|
400
|
+
//
|
|
401
|
+
// "Mapbox access token is configured here. This needs to be called either in your application
|
|
402
|
+
// object or in the same activity which contains the mapview."
|
|
278
403
|
com.mapbox.mapboxsdk.Mapbox.getInstance(context, this._accessToken);
|
|
279
404
|
const mapboxMapOptions = this._getMapboxMapOptions(settings);
|
|
405
|
+
// unlike the Mapbox Android Native samples, we are not laying the map out
|
|
406
|
+
// using the Android XML layout features. Instead, we are creating the map
|
|
407
|
+
// programmatically.
|
|
280
408
|
this._mapboxViewInstance = new com.mapbox.mapboxsdk.maps.MapView(context, mapboxMapOptions);
|
|
409
|
+
// required per the Mapbox Android API.
|
|
281
410
|
this._mapboxViewInstance.onCreate(null);
|
|
411
|
+
// define some listeners to inform in case the map does not
|
|
412
|
+
// load.
|
|
282
413
|
if (Trace.isEnabled()) {
|
|
283
414
|
this.onDidFailLoadingMapListener = new com.mapbox.mapboxsdk.maps.MapView.OnDidFailLoadingMapListener({
|
|
284
415
|
onDidFailLoadingMap: (error) => CLog(CLogTypes.error, 'Mapbox::show(): failed to load map:', error)
|
|
@@ -297,16 +428,21 @@ export class Mapbox extends MapboxCommon {
|
|
|
297
428
|
if (Trace.isEnabled()) {
|
|
298
429
|
CLog(CLogTypes.info, 'show(): onMapReady() with instance:', this._mapboxMapInstance);
|
|
299
430
|
}
|
|
431
|
+
// Android SDK 7.0.0 and on requires that the style be set separately after the map
|
|
432
|
+
// is initialized. We do not consider the map ready until the style has successfully
|
|
433
|
+
// loaded.
|
|
300
434
|
this.setMapStyle(settings.style).then((style) => {
|
|
301
435
|
if (Trace.isEnabled()) {
|
|
302
436
|
CLog(CLogTypes.info, 'show(): style loaded.');
|
|
303
437
|
}
|
|
438
|
+
// initialize the event handlers now that we have a constructed view.
|
|
304
439
|
this.initEventHandlerShim(settings, this._mapboxViewInstance);
|
|
305
440
|
this._addMarkers(settings.markers, this._mapboxViewInstance);
|
|
306
441
|
if (settings.showUserLocation) {
|
|
307
442
|
this.requestFineLocationPermission()
|
|
308
443
|
.then(() => {
|
|
309
444
|
this.showUserLocationMarker(settings.locationComponentOptions);
|
|
445
|
+
// if we have a callback defined, call it.
|
|
310
446
|
if (settings.onLocationPermissionGranted) {
|
|
311
447
|
settings.onLocationPermissionGranted(this._mapboxMapInstance);
|
|
312
448
|
}
|
|
@@ -317,6 +453,7 @@ export class Mapbox extends MapboxCommon {
|
|
|
317
453
|
}
|
|
318
454
|
});
|
|
319
455
|
}
|
|
456
|
+
// if we have an onMapReady callback fire it.
|
|
320
457
|
if (settings.onMapReady) {
|
|
321
458
|
settings.onMapReady(this._mapboxMapInstance);
|
|
322
459
|
}
|
|
@@ -330,6 +467,8 @@ export class Mapbox extends MapboxCommon {
|
|
|
330
467
|
if (Trace.isEnabled()) {
|
|
331
468
|
CLog(CLogTypes.info, 'show(): after getMapAsync()');
|
|
332
469
|
}
|
|
470
|
+
// we either have been given a view to add the map to or we
|
|
471
|
+
// add it to the top making it full screen.
|
|
333
472
|
if (settings.parentView) {
|
|
334
473
|
if (Trace.isEnabled()) {
|
|
335
474
|
CLog(CLogTypes.info, 'show(): adding map to passed in view');
|
|
@@ -340,6 +479,7 @@ export class Mapbox extends MapboxCommon {
|
|
|
340
479
|
if (Trace.isEnabled()) {
|
|
341
480
|
CLog(CLogTypes.info, 'show(): adding map to passed in container');
|
|
342
481
|
}
|
|
482
|
+
// Application.android.currentContext has been removed.
|
|
343
483
|
context = Application.android.foregroundActivity;
|
|
344
484
|
if (!context) {
|
|
345
485
|
context = Application.android.startActivity;
|
|
@@ -358,6 +498,7 @@ export class Mapbox extends MapboxCommon {
|
|
|
358
498
|
CLog(CLogTypes.info, 'show(): showIt() bottom');
|
|
359
499
|
}
|
|
360
500
|
};
|
|
501
|
+
// FIXME: There is some initialization error. A short delay works around this.
|
|
361
502
|
setTimeout(showIt, settings.delay ? settings.delay : 200);
|
|
362
503
|
}
|
|
363
504
|
catch (ex) {
|
|
@@ -368,6 +509,9 @@ export class Mapbox extends MapboxCommon {
|
|
|
368
509
|
}
|
|
369
510
|
});
|
|
370
511
|
}
|
|
512
|
+
/**
|
|
513
|
+
* hide the map
|
|
514
|
+
*/
|
|
371
515
|
hide() {
|
|
372
516
|
return new Promise((resolve, reject) => {
|
|
373
517
|
try {
|
|
@@ -406,6 +550,11 @@ export class Mapbox extends MapboxCommon {
|
|
|
406
550
|
}
|
|
407
551
|
});
|
|
408
552
|
}
|
|
553
|
+
/**
|
|
554
|
+
* destroy the map programmatically
|
|
555
|
+
*
|
|
556
|
+
* Destroy the map instance.
|
|
557
|
+
*/
|
|
409
558
|
destroy(nativeMap) {
|
|
410
559
|
return new Promise(async (resolve, reject) => {
|
|
411
560
|
this.clearEventListeners();
|
|
@@ -425,6 +574,10 @@ export class Mapbox extends MapboxCommon {
|
|
|
425
574
|
this.symbolManager.onDestroy();
|
|
426
575
|
this.symbolManager = null;
|
|
427
576
|
}
|
|
577
|
+
// if we have a location marker we need to disable it before destroying the map
|
|
578
|
+
//
|
|
579
|
+
// This is here to prevent a crash. The user code should disable/re-enable the
|
|
580
|
+
// location marker.
|
|
428
581
|
if (this._locationComponent) {
|
|
429
582
|
if (Trace.isEnabled()) {
|
|
430
583
|
CLog(CLogTypes.info, 'destroy(): Location marker not disabled before destroy() called.');
|
|
@@ -442,6 +595,7 @@ export class Mapbox extends MapboxCommon {
|
|
|
442
595
|
this._mapboxViewInstance.onPause();
|
|
443
596
|
this._mapboxViewInstance.onStop();
|
|
444
597
|
this._mapboxViewInstance.destroyDrawingCache();
|
|
598
|
+
// let the API know that we're programmatically destroying the map.
|
|
445
599
|
this._mapboxViewInstance.onDestroy();
|
|
446
600
|
this._mapboxViewInstance = null;
|
|
447
601
|
this._mapboxMapInstance = null;
|
|
@@ -449,6 +603,14 @@ export class Mapbox extends MapboxCommon {
|
|
|
449
603
|
resolve();
|
|
450
604
|
});
|
|
451
605
|
}
|
|
606
|
+
/**
|
|
607
|
+
* Clear Event Listeners
|
|
608
|
+
*
|
|
609
|
+
* Explicitly clear all registered event listeners. It's not clear to me whether or not this
|
|
610
|
+
* is strictly necessary as I imagine these should all get cleaned up when the map is destroyed
|
|
611
|
+
* but given the complication of NativeScript's garbage collection scheme it seems like a good
|
|
612
|
+
* idea to remove these handlers explicitly.
|
|
613
|
+
*/
|
|
452
614
|
clearEventListeners() {
|
|
453
615
|
if (this.onDidFailLoadingMapListener) {
|
|
454
616
|
this._mapboxViewInstance.removeOnDidFailLoadingMapListener(this.onDidFailLoadingMapListener);
|
|
@@ -515,6 +677,9 @@ export class Mapbox extends MapboxCommon {
|
|
|
515
677
|
this.onLocationClickListener = null;
|
|
516
678
|
}
|
|
517
679
|
}
|
|
680
|
+
// ------------------------------------------------
|
|
681
|
+
// Life Cycle Hooks
|
|
682
|
+
// ------------------------------------------------
|
|
518
683
|
async onStart(nativeMap) {
|
|
519
684
|
if (Trace.isEnabled()) {
|
|
520
685
|
CLog(CLogTypes.info, 'onStart()');
|
|
@@ -551,6 +716,14 @@ export class Mapbox extends MapboxCommon {
|
|
|
551
716
|
}
|
|
552
717
|
this._mapboxViewInstance.onDestroy();
|
|
553
718
|
}
|
|
719
|
+
/**
|
|
720
|
+
* event handler shim
|
|
721
|
+
*
|
|
722
|
+
* Initialize our event handler shim so that we can intercept events here.
|
|
723
|
+
*
|
|
724
|
+
* @param { any } settings
|
|
725
|
+
* @param { MapboxView } mapboxView
|
|
726
|
+
*/
|
|
554
727
|
initEventHandlerShim(settings, mapboxNativeViewInstance) {
|
|
555
728
|
if (Trace.isEnabled()) {
|
|
556
729
|
CLog(CLogTypes.info, 'Mapbox:initEventHandlerShim(): top');
|
|
@@ -581,6 +754,22 @@ export class Mapbox extends MapboxCommon {
|
|
|
581
754
|
}
|
|
582
755
|
}, mapboxNativeViewInstance);
|
|
583
756
|
}
|
|
757
|
+
/**
|
|
758
|
+
* register on click handlers.
|
|
759
|
+
*
|
|
760
|
+
* The native mapbox API does not, apparently, support click handlers
|
|
761
|
+
* on circles, but it does for markers and polylines. WTF?
|
|
762
|
+
*
|
|
763
|
+
* Here we attempt to replicate the mapbox-gl-js behaviour of being
|
|
764
|
+
* able to assign an onClick handler to a layer by it's layer id.
|
|
765
|
+
*
|
|
766
|
+
* @param {string} event - the event to subscribe to. i.e. 'click'.
|
|
767
|
+
* @param {string} id - the id of the layer
|
|
768
|
+
* @param {function} callback - the callback to invoke when the layer is clicked on.
|
|
769
|
+
* @param {object] nativeMapView - reference to the native Map view.
|
|
770
|
+
*
|
|
771
|
+
* @link https://github.com/mapbox/mapbox-android-demo/issues/540
|
|
772
|
+
*/
|
|
584
773
|
onMapEvent(eventName, id, callback, nativeMapView) {
|
|
585
774
|
if (typeof this.eventCallbacks[eventName] == 'undefined') {
|
|
586
775
|
this.eventCallbacks[eventName] = [];
|
|
@@ -590,12 +779,21 @@ export class Mapbox extends MapboxCommon {
|
|
|
590
779
|
callback
|
|
591
780
|
});
|
|
592
781
|
}
|
|
782
|
+
/**
|
|
783
|
+
* remove an event handler for a layer
|
|
784
|
+
*
|
|
785
|
+
* This will remove all event handlers (that we manage here) for
|
|
786
|
+
* the given layer id and event.
|
|
787
|
+
*/
|
|
593
788
|
offMapEvent(eventName, id, nativeMapView) {
|
|
594
789
|
if (typeof this.eventCallbacks[eventName] == 'undefined') {
|
|
595
790
|
return;
|
|
596
791
|
}
|
|
597
792
|
this.eventCallbacks[eventName] = this.eventCallbacks[eventName].filter((entry) => entry.id !== id);
|
|
598
793
|
}
|
|
794
|
+
/**
|
|
795
|
+
* If click events registered and a feature found for the event, then fire listener.
|
|
796
|
+
*/
|
|
599
797
|
checkForClickEvent(point, nativeMap) {
|
|
600
798
|
if (Trace.isEnabled()) {
|
|
601
799
|
CLog(CLogTypes.info, 'Mapbox:checkForClickEvent(): got click event with point:', JSON.stringify(point));
|
|
@@ -611,6 +809,12 @@ export class Mapbox extends MapboxCommon {
|
|
|
611
809
|
this.view && this.view.notify({ eventName: 'mapClick', object: this.view, point });
|
|
612
810
|
return false;
|
|
613
811
|
}
|
|
812
|
+
/**
|
|
813
|
+
* handles a line click event
|
|
814
|
+
*
|
|
815
|
+
* Given a click on a line overlay, find the id of the underlying line layer
|
|
816
|
+
* an invoke any registered callbacks.
|
|
817
|
+
*/
|
|
614
818
|
handleLineClickEvent(clickOverlay) {
|
|
615
819
|
const lineEntry = this.lines.find((entry) => {
|
|
616
820
|
if (Trace.isEnabled()) {
|
|
@@ -633,7 +837,7 @@ export class Mapbox extends MapboxCommon {
|
|
|
633
837
|
}
|
|
634
838
|
return entry.callback(lineEntry);
|
|
635
839
|
}
|
|
636
|
-
}
|
|
840
|
+
} // end of for loop over events.
|
|
637
841
|
return false;
|
|
638
842
|
}
|
|
639
843
|
hasFineLocationPermission() {
|
|
@@ -649,9 +853,30 @@ export class Mapbox extends MapboxCommon {
|
|
|
649
853
|
}
|
|
650
854
|
});
|
|
651
855
|
}
|
|
856
|
+
/**
|
|
857
|
+
* Request fine locaion permission
|
|
858
|
+
*
|
|
859
|
+
* @link https://docs.mapbox.com/android/core/overview/#permissionsmanager
|
|
860
|
+
*/
|
|
652
861
|
async requestFineLocationPermission() {
|
|
653
862
|
return request('location');
|
|
654
863
|
}
|
|
864
|
+
/**
|
|
865
|
+
* set the map style
|
|
866
|
+
*
|
|
867
|
+
* The 7.X version of the SDK uses a builder class for forming
|
|
868
|
+
* URLs.
|
|
869
|
+
*
|
|
870
|
+
* NOTE: The style must be explicitly set using this method in the onMapReady() handler.
|
|
871
|
+
*
|
|
872
|
+
* @param {string | MapStyle } style - a style following the Mapbox style specification or a URL to a style.
|
|
873
|
+
* @param {any} nativeMapViewInstance - native map view (com.mapbox.mapboxsdk.maps.MapView)
|
|
874
|
+
*
|
|
875
|
+
* @see MapboxViewCommonBase:setMapStyle()
|
|
876
|
+
*
|
|
877
|
+
* @link https://docs.mapbox.com/android/api/map-sdk/7.1.2/com/mapbox/mapboxsdk/maps/Style.Builder.html
|
|
878
|
+
* @link https://docs.mapbox.com/android/api/map-sdk/7.1.2/com/mapbox/mapboxsdk/maps/MapboxMap.html#setStyle-java.lang.String-com.mapbox.mapboxsdk.maps.Style.OnStyleLoaded-
|
|
879
|
+
*/
|
|
655
880
|
setMapStyle(style, nativeMapViewInstance) {
|
|
656
881
|
return new Promise((resolve, reject) => {
|
|
657
882
|
try {
|
|
@@ -659,15 +884,31 @@ export class Mapbox extends MapboxCommon {
|
|
|
659
884
|
if (Trace.isEnabled()) {
|
|
660
885
|
CLog(CLogTypes.info, 'setMapStyle(): with style:', style);
|
|
661
886
|
}
|
|
887
|
+
// callback for when the style is successfully loaded.
|
|
662
888
|
this.onDidFinishLoadingStyleListener = new com.mapbox.mapboxsdk.maps.MapView.OnDidFinishLoadingStyleListener({
|
|
663
889
|
onDidFinishLoadingStyle: () => {
|
|
664
890
|
if (Trace.isEnabled()) {
|
|
665
891
|
CLog(CLogTypes.info, 'Mapbox:setMapStyle(): style loaded');
|
|
666
892
|
}
|
|
893
|
+
// FIXME: now that the map is initialized and the style is loaded we can
|
|
894
|
+
// create the annotation managers that allow us to (hopefully) reliably
|
|
895
|
+
// receive events on lines
|
|
667
896
|
const nMapbox = this._mapboxMapInstance;
|
|
668
897
|
const nMapView = this._mapboxViewInstance;
|
|
669
898
|
const nStyle = nMapbox.getStyle();
|
|
670
899
|
this.lineManager = new com.mapbox.mapboxsdk.plugins.annotation.LineManager(nMapView, nMapbox, nStyle);
|
|
900
|
+
// this.symbolManager = new com.mapbox.mapboxsdk.plugins.annotation.SymbolManager(nMapView, nMapbox, nStyle);
|
|
901
|
+
// this.symbolManager.addClickListener(
|
|
902
|
+
// new com.mapbox.mapboxsdk.plugins.annotation.OnSymbolClickListener({
|
|
903
|
+
// onAnnotationClick: (marker: com.mapbox.mapboxsdk.plugins.annotation.Symbol) => {
|
|
904
|
+
// const cachedMarker = this._getClickedMarkerDetails(marker);
|
|
905
|
+
// if (cachedMarker && cachedMarker.onTap) {
|
|
906
|
+
// cachedMarker.onTap(cachedMarker);
|
|
907
|
+
// }
|
|
908
|
+
// return false;
|
|
909
|
+
// },
|
|
910
|
+
// })
|
|
911
|
+
// );
|
|
671
912
|
this.onAnnotationClickListener = new com.mapbox.mapboxsdk.plugins.annotation.OnAnnotationClickListener({
|
|
672
913
|
onAnnotationClick: (line) => {
|
|
673
914
|
if (Trace.isEnabled()) {
|
|
@@ -682,6 +923,7 @@ export class Mapbox extends MapboxCommon {
|
|
|
682
923
|
}
|
|
683
924
|
});
|
|
684
925
|
this._mapboxViewInstance.addOnDidFinishLoadingStyleListener(this.onDidFinishLoadingStyleListener);
|
|
926
|
+
// callback if loading the style fails.
|
|
685
927
|
this.onDidFailLoadingMapListener = new com.mapbox.mapboxsdk.maps.MapView.OnDidFailLoadingMapListener({
|
|
686
928
|
onDidFailLoadingMap: (error) => {
|
|
687
929
|
if (Trace.isEnabled()) {
|
|
@@ -789,6 +1031,11 @@ export class Mapbox extends MapboxCommon {
|
|
|
789
1031
|
throw ex;
|
|
790
1032
|
}
|
|
791
1033
|
}
|
|
1034
|
+
/**
|
|
1035
|
+
*
|
|
1036
|
+
* @deprecated
|
|
1037
|
+
* @link https://github.com/mapbox/mapbox-plugins-android/tree/master/plugin-annotation
|
|
1038
|
+
*/
|
|
792
1039
|
_addMarkers(markers, nativeMap) {
|
|
793
1040
|
if (!markers) {
|
|
794
1041
|
if (Trace.isEnabled()) {
|
|
@@ -833,6 +1080,7 @@ export class Mapbox extends MapboxCommon {
|
|
|
833
1080
|
this.iconFactory = com.mapbox.mapboxsdk.annotations.IconFactory.getInstance(Application.android.context);
|
|
834
1081
|
}
|
|
835
1082
|
const iconFactory = this.iconFactory;
|
|
1083
|
+
// if any markers need to be downloaded from the web they need to be available synchronously, so fetch them first before looping
|
|
836
1084
|
this._downloadMarkerImages(markers).then((updatedMarkers) => {
|
|
837
1085
|
for (const m in updatedMarkers) {
|
|
838
1086
|
const marker = updatedMarkers[m];
|
|
@@ -842,14 +1090,15 @@ export class Mapbox extends MapboxCommon {
|
|
|
842
1090
|
markerOptions.setSnippet(marker.subtitle);
|
|
843
1091
|
markerOptions.setPosition(new com.mapbox.mapboxsdk.geometry.LatLng(parseFloat(marker.lat), parseFloat(marker.lng)));
|
|
844
1092
|
if (marker.icon) {
|
|
1093
|
+
// for markers from url see UrlMarker in https://github.com/mapbox/mapbox-gl-native/issues/5370
|
|
845
1094
|
if (marker.icon.startsWith('res://')) {
|
|
846
|
-
let cached = this.iconCache[marker.
|
|
1095
|
+
let cached = this.iconCache[marker.icon];
|
|
847
1096
|
if (!cached) {
|
|
848
1097
|
const resourcename = marker.icon.substring(6);
|
|
849
1098
|
const res = Utils.ad.getApplicationContext().getResources();
|
|
850
1099
|
const identifier = res.getIdentifier(resourcename, 'drawable', Utils.ad.getApplication().getPackageName());
|
|
851
1100
|
if (identifier !== 0) {
|
|
852
|
-
cached = this.iconCache[marker.
|
|
1101
|
+
cached = this.iconCache[marker.icon] = iconFactory.fromResource(identifier);
|
|
853
1102
|
}
|
|
854
1103
|
}
|
|
855
1104
|
if (cached) {
|
|
@@ -874,7 +1123,9 @@ export class Mapbox extends MapboxCommon {
|
|
|
874
1123
|
let cached = this.iconCache[marker.iconPath];
|
|
875
1124
|
if (!cached) {
|
|
876
1125
|
const iconFullPath = path.join(knownFolders.currentApp().path, marker.iconPath.replace('~/', ''));
|
|
1126
|
+
// if the file doesn't exist the app will crash, so checking it
|
|
877
1127
|
if (File.exists(iconFullPath)) {
|
|
1128
|
+
// could set width, height, retina, see https://github.com/Telerik-Verified-Plugins/Mapbox/pull/42/files?diff=unified&short_path=1c65267, but that's what the marker.icon param is for..
|
|
878
1129
|
cached = this.iconCache[marker.iconPath] = iconFactory.fromPath(iconFullPath);
|
|
879
1130
|
}
|
|
880
1131
|
}
|
|
@@ -921,6 +1172,10 @@ export class Mapbox extends MapboxCommon {
|
|
|
921
1172
|
}
|
|
922
1173
|
});
|
|
923
1174
|
}
|
|
1175
|
+
/**
|
|
1176
|
+
*
|
|
1177
|
+
* @deprecated
|
|
1178
|
+
*/
|
|
924
1179
|
_removeMarkers(ids, nativeMap) {
|
|
925
1180
|
if (!this._mapboxMapInstance) {
|
|
926
1181
|
return;
|
|
@@ -933,6 +1188,7 @@ export class Mapbox extends MapboxCommon {
|
|
|
933
1188
|
}
|
|
934
1189
|
}
|
|
935
1190
|
}
|
|
1191
|
+
// remove markers from cache
|
|
936
1192
|
if (ids) {
|
|
937
1193
|
this._markers = this._markers.filter((marker) => ids.indexOf(marker.id) === -1);
|
|
938
1194
|
}
|
|
@@ -1053,6 +1309,11 @@ export class Mapbox extends MapboxCommon {
|
|
|
1053
1309
|
}
|
|
1054
1310
|
});
|
|
1055
1311
|
}
|
|
1312
|
+
/**
|
|
1313
|
+
* get users current location
|
|
1314
|
+
*
|
|
1315
|
+
* @link https://docs.mapbox.com/android/api/map-sdk/9.0.0/com/mapbox/mapboxsdk/location/LocationComponent.html#getLastKnownLocation--
|
|
1316
|
+
*/
|
|
1056
1317
|
getUserLocation() {
|
|
1057
1318
|
return new Promise((resolve, reject) => {
|
|
1058
1319
|
try {
|
|
@@ -1072,6 +1333,9 @@ export class Mapbox extends MapboxCommon {
|
|
|
1072
1333
|
}
|
|
1073
1334
|
});
|
|
1074
1335
|
}
|
|
1336
|
+
/**
|
|
1337
|
+
* @link https://www.mapbox.com/android-docs/api/mapbox-java/libjava-geojson/3.4.1/com/mapbox/geojson/Feature.html
|
|
1338
|
+
*/
|
|
1075
1339
|
queryRenderedFeatures(options) {
|
|
1076
1340
|
return new Promise((resolve, reject) => {
|
|
1077
1341
|
try {
|
|
@@ -1145,6 +1409,10 @@ export class Mapbox extends MapboxCommon {
|
|
|
1145
1409
|
}
|
|
1146
1410
|
});
|
|
1147
1411
|
}
|
|
1412
|
+
/**
|
|
1413
|
+
*
|
|
1414
|
+
* @deprecated
|
|
1415
|
+
*/
|
|
1148
1416
|
addPolygon(options, nativeMap) {
|
|
1149
1417
|
return new Promise((resolve, reject) => {
|
|
1150
1418
|
try {
|
|
@@ -1160,6 +1428,7 @@ export class Mapbox extends MapboxCommon {
|
|
|
1160
1428
|
}
|
|
1161
1429
|
polygonOptions.fillColor(Mapbox.getAndroidColor(options.fillColor));
|
|
1162
1430
|
polygonOptions.alpha(options.fillOpacity === undefined ? 1 : options.fillOpacity);
|
|
1431
|
+
// Note that the stroke is barely visible, see https://github.com/mapbox/mapbox-gl-native/issues/5676
|
|
1163
1432
|
if (options.strokeColor) {
|
|
1164
1433
|
polygonOptions.strokeColor(Mapbox.getAndroidColor(options.strokeColor));
|
|
1165
1434
|
}
|
|
@@ -1177,6 +1446,10 @@ export class Mapbox extends MapboxCommon {
|
|
|
1177
1446
|
}
|
|
1178
1447
|
});
|
|
1179
1448
|
}
|
|
1449
|
+
/**
|
|
1450
|
+
*
|
|
1451
|
+
* @deprecated
|
|
1452
|
+
*/
|
|
1180
1453
|
addPolyline(options, nativeMap) {
|
|
1181
1454
|
return new Promise((resolve, reject) => {
|
|
1182
1455
|
try {
|
|
@@ -1186,7 +1459,7 @@ export class Mapbox extends MapboxCommon {
|
|
|
1186
1459
|
return;
|
|
1187
1460
|
}
|
|
1188
1461
|
const polylineOptions = new com.mapbox.mapboxsdk.annotations.PolylineOptions();
|
|
1189
|
-
polylineOptions.width(options.width || 5);
|
|
1462
|
+
polylineOptions.width(options.width || 5); // default 5
|
|
1190
1463
|
polylineOptions.color(Mapbox.getAndroidColor(options.color));
|
|
1191
1464
|
polylineOptions.alpha(options.opacity === undefined ? 1 : options.opacity);
|
|
1192
1465
|
for (const p in points) {
|
|
@@ -1287,6 +1560,14 @@ export class Mapbox extends MapboxCommon {
|
|
|
1287
1560
|
}
|
|
1288
1561
|
});
|
|
1289
1562
|
}
|
|
1563
|
+
/**
|
|
1564
|
+
* set an on map click listener.
|
|
1565
|
+
*
|
|
1566
|
+
* The new Mapbox Native SDK allows for multiple listeners on an event and follows the standard
|
|
1567
|
+
* pattern of returning 'true' when a handler has handled the event and others shouldn't.
|
|
1568
|
+
*
|
|
1569
|
+
* Not returning a boolean from the listener function will cause a crash.
|
|
1570
|
+
*/
|
|
1290
1571
|
setOnMapClickListener(listener, nativeMap) {
|
|
1291
1572
|
return new Promise((resolve, reject) => {
|
|
1292
1573
|
try {
|
|
@@ -1351,15 +1632,15 @@ export class Mapbox extends MapboxCommon {
|
|
|
1351
1632
|
CLog(CLogTypes.info, 'setOnMoveBeginListener():');
|
|
1352
1633
|
}
|
|
1353
1634
|
this.onMoveListener = new com.mapbox.mapboxsdk.maps.MapboxMap.OnMoveListener({
|
|
1354
|
-
onMoveBegin: (detector) => {
|
|
1635
|
+
onMoveBegin: (detector /* MoveGestureDetector */) => {
|
|
1355
1636
|
const coordinate = this._mapboxMapInstance.getCameraPosition().target;
|
|
1356
1637
|
return listener({
|
|
1357
1638
|
lat: coordinate.getLatitude(),
|
|
1358
1639
|
lng: coordinate.getLongitude()
|
|
1359
1640
|
});
|
|
1360
1641
|
},
|
|
1361
|
-
onMove: (detector) => { },
|
|
1362
|
-
onMoveEnd: (detector) => { }
|
|
1642
|
+
onMove: (detector /* MoveGestureDetector */) => { },
|
|
1643
|
+
onMoveEnd: (detector /* MoveGestureDetector */) => { }
|
|
1363
1644
|
});
|
|
1364
1645
|
this._mapboxMapInstance.addOnMoveListener(this.onMoveListener);
|
|
1365
1646
|
resolve();
|
|
@@ -1383,9 +1664,9 @@ export class Mapbox extends MapboxCommon {
|
|
|
1383
1664
|
CLog(CLogTypes.info, 'setOnMoveEndListener():');
|
|
1384
1665
|
}
|
|
1385
1666
|
this.onMoveListener = new com.mapbox.mapboxsdk.maps.MapboxMap.OnMoveListener({
|
|
1386
|
-
onMoveBegin: (detector) => { },
|
|
1387
|
-
onMove: (detector) => { },
|
|
1388
|
-
onMoveEnd: (detector) => {
|
|
1667
|
+
onMoveBegin: (detector /* MoveGestureDetector */) => { },
|
|
1668
|
+
onMove: (detector /* MoveGestureDetector */) => { },
|
|
1669
|
+
onMoveEnd: (detector /* MoveGestureDetector */) => {
|
|
1389
1670
|
const coordinate = this._mapboxMapInstance.getCameraPosition().target;
|
|
1390
1671
|
return listener({
|
|
1391
1672
|
lat: coordinate.getLatitude(),
|
|
@@ -1414,16 +1695,17 @@ export class Mapbox extends MapboxCommon {
|
|
|
1414
1695
|
if (Trace.isEnabled()) {
|
|
1415
1696
|
CLog(CLogTypes.info, 'setOnScrollListener():');
|
|
1416
1697
|
}
|
|
1698
|
+
// the 'onMove' event seems like the one closest to the iOS implementation
|
|
1417
1699
|
this.onScrollListener = new com.mapbox.mapboxsdk.maps.MapboxMap.OnMoveListener({
|
|
1418
|
-
onMoveBegin: (detector) => { },
|
|
1419
|
-
onMove: (detector) => {
|
|
1700
|
+
onMoveBegin: (detector /* MoveGestureDetector */) => { },
|
|
1701
|
+
onMove: (detector /* MoveGestureDetector */) => {
|
|
1420
1702
|
const coordinate = this._mapboxMapInstance.getCameraPosition().target;
|
|
1421
1703
|
return listener({
|
|
1422
1704
|
lat: coordinate.getLatitude(),
|
|
1423
1705
|
lng: coordinate.getLongitude()
|
|
1424
1706
|
});
|
|
1425
1707
|
},
|
|
1426
|
-
onMoveEnd: (detector) => { }
|
|
1708
|
+
onMoveEnd: (detector /* MoveGestureDetector */) => { }
|
|
1427
1709
|
});
|
|
1428
1710
|
this._mapboxMapInstance.addOnMoveListener(this.onScrollListener);
|
|
1429
1711
|
resolve();
|
|
@@ -1586,7 +1868,10 @@ export class Mapbox extends MapboxCommon {
|
|
|
1586
1868
|
.build();
|
|
1587
1869
|
const retinaFactor = Utils.layout.getDisplayDensity();
|
|
1588
1870
|
const offlineRegionDefinition = new com.mapbox.mapboxsdk.offline.OfflineTilePyramidRegionDefinition(styleURL, bounds, options.minZoom, options.maxZoom, retinaFactor);
|
|
1589
|
-
const info =
|
|
1871
|
+
const info = {
|
|
1872
|
+
name: options.name,
|
|
1873
|
+
...options.metadata
|
|
1874
|
+
};
|
|
1590
1875
|
const infoStr = new java.lang.String(JSON.stringify(info));
|
|
1591
1876
|
const encodedMetadata = infoStr.getBytes();
|
|
1592
1877
|
if (!this._accessToken && !options.accessToken) {
|
|
@@ -1602,9 +1887,14 @@ export class Mapbox extends MapboxCommon {
|
|
|
1602
1887
|
reject(error);
|
|
1603
1888
|
},
|
|
1604
1889
|
onCreate: (offlineRegion) => {
|
|
1890
|
+
// if (options.onCreate) {
|
|
1891
|
+
// options.onCreate(offlineRegion);
|
|
1892
|
+
// }
|
|
1605
1893
|
offlineRegion.setDownloadState(com.mapbox.mapboxsdk.offline.OfflineRegion.STATE_ACTIVE);
|
|
1894
|
+
// Monitor the download progress using setObserver
|
|
1606
1895
|
offlineRegion.setObserver(new com.mapbox.mapboxsdk.offline.OfflineRegion.OfflineRegionObserver({
|
|
1607
1896
|
onStatusChanged: (status) => {
|
|
1897
|
+
// Calculate the download percentage and update the progress bar
|
|
1608
1898
|
const percentage = status.getRequiredResourceCount() >= 0 ? (100.0 * status.getCompletedResourceCount()) / status.getRequiredResourceCount() : 0.0;
|
|
1609
1899
|
if (options.onProgress) {
|
|
1610
1900
|
options.onProgress({
|
|
@@ -1613,6 +1903,7 @@ export class Mapbox extends MapboxCommon {
|
|
|
1613
1903
|
completed: status.getCompletedResourceCount(),
|
|
1614
1904
|
expected: status.getRequiredResourceCount(),
|
|
1615
1905
|
percentage: Math.round(percentage * 100) / 100,
|
|
1906
|
+
// downloading: status.getDownloadState() == com.mapbox.mapboxsdk.offline.OfflineRegion.STATE_ACTIVE,
|
|
1616
1907
|
complete: status.isComplete()
|
|
1617
1908
|
});
|
|
1618
1909
|
}
|
|
@@ -1720,8 +2011,10 @@ export class Mapbox extends MapboxCommon {
|
|
|
1720
2011
|
},
|
|
1721
2012
|
onDelete: () => {
|
|
1722
2013
|
resolve();
|
|
2014
|
+
// don't return, see note below
|
|
1723
2015
|
}
|
|
1724
2016
|
}));
|
|
2017
|
+
// don't break the loop as there may be multiple packs with the same name
|
|
1725
2018
|
}
|
|
1726
2019
|
}
|
|
1727
2020
|
}
|
|
@@ -1748,6 +2041,7 @@ export class Mapbox extends MapboxCommon {
|
|
|
1748
2041
|
addExtrusion(options, nativeMap) {
|
|
1749
2042
|
return new Promise((resolve, reject) => {
|
|
1750
2043
|
try {
|
|
2044
|
+
// Create fill extrusion layer
|
|
1751
2045
|
const fillExtrusionLayer = new com.mapbox.mapboxsdk.style.layers.FillExtrusionLayer('3d-buildings', 'composite');
|
|
1752
2046
|
fillExtrusionLayer.setSourceLayer('building');
|
|
1753
2047
|
fillExtrusionLayer.setFilter(com.mapbox.mapboxsdk.style.expressions.Expression.eq(com.mapbox.mapboxsdk.style.expressions.Expression.get('extrude'), 'true'));
|
|
@@ -1757,6 +2051,7 @@ export class Mapbox extends MapboxCommon {
|
|
|
1757
2051
|
props[1] = com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionHeight(com.mapbox.mapboxsdk.style.expressions.Expression.get('height'));
|
|
1758
2052
|
props[2] = com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionBase(com.mapbox.mapboxsdk.style.expressions.Expression.get('min_height'));
|
|
1759
2053
|
props[3] = com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillExtrusionOpacity(com.mapbox.mapboxsdk.style.expressions.Expression.literal(0.6));
|
|
2054
|
+
// Set data-driven styling properties
|
|
1760
2055
|
fillExtrusionLayer.setProperties(props);
|
|
1761
2056
|
this._mapboxMapInstance.getStyle().addLayer(fillExtrusionLayer);
|
|
1762
2057
|
resolve();
|
|
@@ -1769,6 +2064,10 @@ export class Mapbox extends MapboxCommon {
|
|
|
1769
2064
|
}
|
|
1770
2065
|
});
|
|
1771
2066
|
}
|
|
2067
|
+
/**
|
|
2068
|
+
* update a geojson source
|
|
2069
|
+
*
|
|
2070
|
+
*/
|
|
1772
2071
|
updateSource(id, options, nativeMap) {
|
|
1773
2072
|
return new Promise((resolve, reject) => {
|
|
1774
2073
|
try {
|
|
@@ -1801,6 +2100,14 @@ export class Mapbox extends MapboxCommon {
|
|
|
1801
2100
|
}
|
|
1802
2101
|
});
|
|
1803
2102
|
}
|
|
2103
|
+
/**
|
|
2104
|
+
* add a geojson or vector source
|
|
2105
|
+
*
|
|
2106
|
+
* Add a source that can then be referenced in the style specification
|
|
2107
|
+
* passed to addLayer().
|
|
2108
|
+
*
|
|
2109
|
+
* @link https://docs.mapbox.com/mapbox-gl-js/api/#map#addsource
|
|
2110
|
+
*/
|
|
1804
2111
|
addSource(id, options, nativeMap) {
|
|
1805
2112
|
return new Promise((resolve, reject) => {
|
|
1806
2113
|
try {
|
|
@@ -1879,6 +2186,7 @@ export class Mapbox extends MapboxCommon {
|
|
|
1879
2186
|
break;
|
|
1880
2187
|
}
|
|
1881
2188
|
case 'raster':
|
|
2189
|
+
// use Array.create because a marshal error throws on TileSet if options.tiles directly passed.
|
|
1882
2190
|
const tiles = Array.create(java.lang.String, options.tiles.length);
|
|
1883
2191
|
options.tiles.forEach((val, i) => (tiles[i] = val));
|
|
1884
2192
|
const tileSet = new com.mapbox.mapboxsdk.style.sources.TileSet('2.0.0', tiles);
|
|
@@ -1919,6 +2227,9 @@ export class Mapbox extends MapboxCommon {
|
|
|
1919
2227
|
}
|
|
1920
2228
|
});
|
|
1921
2229
|
}
|
|
2230
|
+
/**
|
|
2231
|
+
* remove source by id
|
|
2232
|
+
*/
|
|
1922
2233
|
removeSource(id, nativeMap) {
|
|
1923
2234
|
return new Promise((resolve, reject) => {
|
|
1924
2235
|
try {
|
|
@@ -1941,6 +2252,24 @@ export class Mapbox extends MapboxCommon {
|
|
|
1941
2252
|
}
|
|
1942
2253
|
});
|
|
1943
2254
|
}
|
|
2255
|
+
/**
|
|
2256
|
+
* a rough analogue to the mapbox-gl-js addLayer() method
|
|
2257
|
+
*
|
|
2258
|
+
* It would be nice if this {N} API matched the mapbox-gl-js API which
|
|
2259
|
+
* would make it much easier to share mapping applications between the web
|
|
2260
|
+
* and {N} apps.
|
|
2261
|
+
*
|
|
2262
|
+
* This method accepts a Mapbox-GL-JS style specification JSON object with some
|
|
2263
|
+
* limitations:
|
|
2264
|
+
*
|
|
2265
|
+
* - the source: must be a GeoJSON object, vector source definition, or an id of a source added via addSource()
|
|
2266
|
+
* - only a subset of paint properties are available.
|
|
2267
|
+
*
|
|
2268
|
+
* @param {object} style - a style following the Mapbox style specification.
|
|
2269
|
+
* @param {any} nativeMapView - native map view (com.mapbox.mapboxsdk.maps.MapView)
|
|
2270
|
+
*
|
|
2271
|
+
* @link https://docs.mapbox.com/mapbox-gl-js/style-spec/#layers
|
|
2272
|
+
*/
|
|
1944
2273
|
async addLayer(style, belowLayerId, nativeMap) {
|
|
1945
2274
|
const theMap = nativeMap || this._mapboxMapInstance;
|
|
1946
2275
|
if (!theMap) {
|
|
@@ -1961,6 +2290,13 @@ export class Mapbox extends MapboxCommon {
|
|
|
1961
2290
|
}
|
|
1962
2291
|
this._mapboxMapInstance.getStyle().addLayer(layer.getNativeInstance());
|
|
1963
2292
|
}
|
|
2293
|
+
/**
|
|
2294
|
+
* remove layer by ID
|
|
2295
|
+
*
|
|
2296
|
+
* Removes a layer given a layer id
|
|
2297
|
+
*
|
|
2298
|
+
* @param {string} id
|
|
2299
|
+
*/
|
|
1964
2300
|
async removeLayer(id, nativeMap) {
|
|
1965
2301
|
const theMap = nativeMap || this._mapboxMapInstance;
|
|
1966
2302
|
theMap.getStyle().removeLayer(id);
|
|
@@ -1968,6 +2304,19 @@ export class Mapbox extends MapboxCommon {
|
|
|
1968
2304
|
CLog(CLogTypes.info, 'Mapbox:removeLayer(): after removing layer');
|
|
1969
2305
|
}
|
|
1970
2306
|
}
|
|
2307
|
+
/**
|
|
2308
|
+
* @deprecated
|
|
2309
|
+
* Add a point to a line
|
|
2310
|
+
*
|
|
2311
|
+
* This method appends a point to a line and is useful for drawing a users track.
|
|
2312
|
+
*
|
|
2313
|
+
* @param {id} id - id of line to add a point to.
|
|
2314
|
+
* @param {array} lnglat - [lng,lat] to append to the line.
|
|
2315
|
+
*
|
|
2316
|
+
* @link https://github.com/mapbox/mapbox-gl-native/issues/13983
|
|
2317
|
+
* @link https://docs.mapbox.com/android/api/mapbox-java/libjava-geojson/3.0.1/com/mapbox/geojson/Feature.html#Feature--
|
|
2318
|
+
* @link https://docs.oracle.com/javase/8/docs/api/java/util/List.html
|
|
2319
|
+
*/
|
|
1971
2320
|
async addLinePoint(id, lnglat, sourceId, nativeMapView) {
|
|
1972
2321
|
try {
|
|
1973
2322
|
const sId = !!sourceId ? sourceId : id + '_source';
|
|
@@ -1999,6 +2348,7 @@ export class Mapbox extends MapboxCommon {
|
|
|
1999
2348
|
const layers = [];
|
|
2000
2349
|
if (options.clusters) {
|
|
2001
2350
|
for (let i = 0; i < options.clusters.length; i++) {
|
|
2351
|
+
// TODO also allow Color object
|
|
2002
2352
|
layers.push([options.clusters[i].points, new Color(options.clusters[i].color).android]);
|
|
2003
2353
|
}
|
|
2004
2354
|
}
|
|
@@ -2014,10 +2364,12 @@ export class Mapbox extends MapboxCommon {
|
|
|
2014
2364
|
com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleBlur(new java.lang.Float(0.2))
|
|
2015
2365
|
]);
|
|
2016
2366
|
unclustered.setFilter(com.mapbox.mapboxsdk.style.expressions.Expression.neq(com.mapbox.mapboxsdk.style.expressions.Expression.get('cluster'), true));
|
|
2017
|
-
this._mapboxMapInstance.getStyle().addLayer(unclustered);
|
|
2367
|
+
this._mapboxMapInstance.getStyle().addLayer(unclustered); // , "building");
|
|
2018
2368
|
for (let i = 0; i < layers.length; i++) {
|
|
2369
|
+
// Add some nice circles
|
|
2019
2370
|
const circles = new com.mapbox.mapboxsdk.style.layers.CircleLayer('cluster-' + i, options.name);
|
|
2020
2371
|
circles.setProperties([
|
|
2372
|
+
// com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconImage("icon")
|
|
2021
2373
|
com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleColor(layers[i][1]),
|
|
2022
2374
|
com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleRadius(new java.lang.Float(22.0)),
|
|
2023
2375
|
com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleBlur(new java.lang.Float(0.2))
|
|
@@ -2032,8 +2384,9 @@ export class Mapbox extends MapboxCommon {
|
|
|
2032
2384
|
com.mapbox.mapboxsdk.style.expressions.Expression.lt(pointCount, com.mapbox.mapboxsdk.style.expressions.Expression.literal(java.lang.Integer.valueOf(layers[i - 1][0])))
|
|
2033
2385
|
]));
|
|
2034
2386
|
}
|
|
2035
|
-
this._mapboxMapInstance.getStyle().addLayer(circles);
|
|
2387
|
+
this._mapboxMapInstance.getStyle().addLayer(circles); // , "building");
|
|
2036
2388
|
}
|
|
2389
|
+
// Add the count labels (note that this doesn't show.. #sad)
|
|
2037
2390
|
const count = new com.mapbox.mapboxsdk.style.layers.SymbolLayer('count', options.name);
|
|
2038
2391
|
count.setProperties([
|
|
2039
2392
|
com.mapbox.mapboxsdk.style.layers.PropertyFactory.textField(com.mapbox.mapboxsdk.style.expressions.Expression.get('point_count')),
|
|
@@ -2051,6 +2404,9 @@ export class Mapbox extends MapboxCommon {
|
|
|
2051
2404
|
}
|
|
2052
2405
|
});
|
|
2053
2406
|
}
|
|
2407
|
+
/**
|
|
2408
|
+
* constantly center the map on the users location.
|
|
2409
|
+
*/
|
|
2054
2410
|
trackUser(options, nativeMap) {
|
|
2055
2411
|
if (Trace.isEnabled()) {
|
|
2056
2412
|
CLog(CLogTypes.info, 'trackUser(): top');
|
|
@@ -2100,6 +2456,7 @@ export class Mapbox extends MapboxCommon {
|
|
|
2100
2456
|
CLog(CLogTypes.info, '_getMapStyle(): top with input:', input);
|
|
2101
2457
|
}
|
|
2102
2458
|
const Style = com.mapbox.mapboxsdk.maps.Style;
|
|
2459
|
+
// allow for a style URL to be passed
|
|
2103
2460
|
if (input.startsWith('mapbox://styles') || input.startsWith('http://') || input.startsWith('https://')) {
|
|
2104
2461
|
return input;
|
|
2105
2462
|
}
|
|
@@ -2128,9 +2485,17 @@ export class Mapbox extends MapboxCommon {
|
|
|
2128
2485
|
return Style.TRAFFIC_NIGHT;
|
|
2129
2486
|
}
|
|
2130
2487
|
else {
|
|
2488
|
+
// default
|
|
2131
2489
|
return Style.MAPBOX_STREETS;
|
|
2132
2490
|
}
|
|
2133
2491
|
}
|
|
2492
|
+
/**
|
|
2493
|
+
* Mapbox Map Options
|
|
2494
|
+
*
|
|
2495
|
+
* @link https://github.com/mapbox/mapbox-gl-native/wiki/Android-6.x-to-7.x-migration-guide
|
|
2496
|
+
* @link https://github.com/mapbox/mapbox-gl-native/blob/master/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java
|
|
2497
|
+
* @link https://docs.mapbox.com/android/api/map-sdk/7.1.2/com/mapbox/mapboxsdk/maps/MapboxMapOptions.html
|
|
2498
|
+
*/
|
|
2134
2499
|
_getMapboxMapOptions(settings) {
|
|
2135
2500
|
const mapboxMapOptions = new com.mapbox.mapboxsdk.maps.MapboxMapOptions()
|
|
2136
2501
|
.compassEnabled(!settings.hideCompass)
|
|
@@ -2140,7 +2505,9 @@ export class Mapbox extends MapboxCommon {
|
|
|
2140
2505
|
.zoomGesturesEnabled(!settings.disableZoom)
|
|
2141
2506
|
.attributionEnabled(!settings.hideAttribution)
|
|
2142
2507
|
.logoEnabled(!settings.hideLogo);
|
|
2508
|
+
// zoomlevel is not applied unless center is set
|
|
2143
2509
|
if (settings.zoomLevel && !settings.center) {
|
|
2510
|
+
// Eiffel tower, Paris
|
|
2144
2511
|
settings.center = {
|
|
2145
2512
|
lat: 48.858093,
|
|
2146
2513
|
lng: 2.294694
|
|
@@ -2154,6 +2521,11 @@ export class Mapbox extends MapboxCommon {
|
|
|
2154
2521
|
}
|
|
2155
2522
|
return mapboxMapOptions;
|
|
2156
2523
|
}
|
|
2524
|
+
/**
|
|
2525
|
+
* convert string to camera mode constant.
|
|
2526
|
+
*
|
|
2527
|
+
* @link https://docs.mapbox.com/android/api/map-sdk/8.1.0/com/mapbox/mapboxsdk/location/modes/CameraMode.html
|
|
2528
|
+
*/
|
|
2157
2529
|
_stringToCameraMode(mode) {
|
|
2158
2530
|
const modeRef = com.mapbox.mapboxsdk.location.modes.CameraMode;
|
|
2159
2531
|
switch (mode) {
|
|
@@ -2173,6 +2545,9 @@ export class Mapbox extends MapboxCommon {
|
|
|
2173
2545
|
return modeRef.TRACKING_GPS_NORTH;
|
|
2174
2546
|
}
|
|
2175
2547
|
}
|
|
2548
|
+
/**
|
|
2549
|
+
* convert string to render mode
|
|
2550
|
+
*/
|
|
2176
2551
|
_stringToRenderMode(mode) {
|
|
2177
2552
|
let renderMode;
|
|
2178
2553
|
switch (mode) {
|
|
@@ -2209,7 +2584,7 @@ export class Mapbox extends MapboxCommon {
|
|
|
2209
2584
|
return "NONE";
|
|
2210
2585
|
}
|
|
2211
2586
|
_fineLocationPermissionGranted() {
|
|
2212
|
-
let hasPermission = android.os.Build.VERSION.SDK_INT < 23;
|
|
2587
|
+
let hasPermission = android.os.Build.VERSION.SDK_INT < 23; // Android M. (6.0)
|
|
2213
2588
|
if (!hasPermission) {
|
|
2214
2589
|
hasPermission = com.mapbox.android.core.permissions.PermissionsManager.areLocationPermissionsGranted(Application.android.context);
|
|
2215
2590
|
}
|
|
@@ -2232,6 +2607,33 @@ export class Mapbox extends MapboxCommon {
|
|
|
2232
2607
|
const jsonObj = new org.json.JSONObject(jsonStr);
|
|
2233
2608
|
return JSON.parse(jsonObj.toString());
|
|
2234
2609
|
}
|
|
2610
|
+
/**
|
|
2611
|
+
* show a user location marker
|
|
2612
|
+
*
|
|
2613
|
+
* This method must not be called before location permissions have been granted.
|
|
2614
|
+
*
|
|
2615
|
+
* Supported options are:
|
|
2616
|
+
*
|
|
2617
|
+
* - foregroundTintColor
|
|
2618
|
+
* - foregroundStaleTintColor
|
|
2619
|
+
* - backgroundTintColor
|
|
2620
|
+
* - bearingTintColor
|
|
2621
|
+
* - elevation
|
|
2622
|
+
* - accuracyColor
|
|
2623
|
+
* - accuracyAlpha
|
|
2624
|
+
* - useDefaultLocationEngine
|
|
2625
|
+
* - renderMode
|
|
2626
|
+
* - cameraMode
|
|
2627
|
+
* - clickListener
|
|
2628
|
+
* - cameraTrackingChangeListener
|
|
2629
|
+
*
|
|
2630
|
+
* @param {object} options
|
|
2631
|
+
*
|
|
2632
|
+
* @link https://github.com/mapbox/mapbox-android-demo/blob/master/MapboxAndroidDemo/src/main/java/com/mapbox/mapboxandroiddemo/examples/location/LocationComponentOptionsActivity.java
|
|
2633
|
+
* @link https://developer.android.com/reference/android/graphics/Color
|
|
2634
|
+
*
|
|
2635
|
+
* @todo at least with simulated data, the location is only updated once hence adding support for forceLocation method.
|
|
2636
|
+
*/
|
|
2235
2637
|
showUserLocationMarker(options, nativeMap) {
|
|
2236
2638
|
return new Promise((resolve, reject) => {
|
|
2237
2639
|
try {
|
|
@@ -2321,6 +2723,11 @@ export class Mapbox extends MapboxCommon {
|
|
|
2321
2723
|
}
|
|
2322
2724
|
});
|
|
2323
2725
|
}
|
|
2726
|
+
/**
|
|
2727
|
+
* hide (destroy) the user location marker
|
|
2728
|
+
*
|
|
2729
|
+
* This method destroys the user location marker.
|
|
2730
|
+
*/
|
|
2324
2731
|
hideUserLocationMarker(nativeMap) {
|
|
2325
2732
|
return new Promise((resolve, reject) => {
|
|
2326
2733
|
try {
|
|
@@ -2349,6 +2756,15 @@ export class Mapbox extends MapboxCommon {
|
|
|
2349
2756
|
}
|
|
2350
2757
|
});
|
|
2351
2758
|
}
|
|
2759
|
+
/**
|
|
2760
|
+
* Change the mode of the user location marker
|
|
2761
|
+
*
|
|
2762
|
+
* Used to change the camera tracking and render modes of an existing
|
|
2763
|
+
* marker.
|
|
2764
|
+
*
|
|
2765
|
+
* The marker must be configured using showUserLocationMarker before this method
|
|
2766
|
+
* can called.
|
|
2767
|
+
*/
|
|
2352
2768
|
changeUserLocationMarkerMode(renderModeString, cameraModeString, nativeMap) {
|
|
2353
2769
|
return new Promise((resolve, reject) => {
|
|
2354
2770
|
try {
|
|
@@ -2387,6 +2803,13 @@ export class Mapbox extends MapboxCommon {
|
|
|
2387
2803
|
}
|
|
2388
2804
|
});
|
|
2389
2805
|
}
|
|
2806
|
+
/**
|
|
2807
|
+
* force updating of user location
|
|
2808
|
+
*
|
|
2809
|
+
* This method forces the user location marker, if displayed, to move to a new location
|
|
2810
|
+
*
|
|
2811
|
+
* @todo figure out why the user location marker is not updating.
|
|
2812
|
+
*/
|
|
2390
2813
|
forceUserLocationUpdate(location, nativeMap) {
|
|
2391
2814
|
return new Promise((resolve, reject) => {
|
|
2392
2815
|
try {
|
|
@@ -2397,6 +2820,7 @@ export class Mapbox extends MapboxCommon {
|
|
|
2397
2820
|
reject('No location component has been loaded');
|
|
2398
2821
|
return;
|
|
2399
2822
|
}
|
|
2823
|
+
// the location object needs to be converted into an android location
|
|
2400
2824
|
const nativeLocation = new android.location.Location('background');
|
|
2401
2825
|
nativeLocation.setLatitude(location.latitude);
|
|
2402
2826
|
nativeLocation.setLongitude(location.longitude);
|
|
@@ -2467,9 +2891,14 @@ export class Mapbox extends MapboxCommon {
|
|
|
2467
2891
|
_getClickedMarkerDetails(clicked) {
|
|
2468
2892
|
for (const m in this._markers) {
|
|
2469
2893
|
const cached = this._markers[m];
|
|
2470
|
-
if (
|
|
2894
|
+
if (
|
|
2895
|
+
// eslint-disable-next-line eqeqeq
|
|
2896
|
+
cached.lat == clicked.getPosition().getLatitude() &&
|
|
2897
|
+
// eslint-disable-next-line eqeqeq
|
|
2471
2898
|
cached.lng == clicked.getPosition().getLongitude() &&
|
|
2472
|
-
|
|
2899
|
+
// eslint-disable-next-line eqeqeq
|
|
2900
|
+
cached.title == clicked.getTitle() && // == because of null vs undefined
|
|
2901
|
+
// eslint-disable-next-line eqeqeq
|
|
2473
2902
|
cached.subtitle == clicked.getSnippet()) {
|
|
2474
2903
|
return cached;
|
|
2475
2904
|
}
|
|
@@ -2477,11 +2906,13 @@ export class Mapbox extends MapboxCommon {
|
|
|
2477
2906
|
}
|
|
2478
2907
|
_downloadImage(marker) {
|
|
2479
2908
|
return new Promise((resolve, reject) => {
|
|
2909
|
+
// to cache..
|
|
2480
2910
|
if (this._markerIconDownloadCache[marker.icon]) {
|
|
2481
2911
|
marker.iconDownloaded = this._markerIconDownloadCache[marker.icon];
|
|
2482
2912
|
resolve(marker);
|
|
2483
2913
|
return;
|
|
2484
2914
|
}
|
|
2915
|
+
// ..or not to cache
|
|
2485
2916
|
Http.getImage(marker.icon).then((output) => {
|
|
2486
2917
|
marker.iconDownloaded = output.android;
|
|
2487
2918
|
this._markerIconDownloadCache[marker.icon] = marker.iconDownloaded;
|