@nativescript-community/ui-mapbox 6.2.19 → 6.2.21

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/index.ios.js CHANGED
@@ -397,6 +397,7 @@ var MapSwipeHandlerImpl = /** @class */ (function (_super) {
397
397
  };
398
398
  return MapSwipeHandlerImpl;
399
399
  }(NSObject));
400
+ // Export the enums for devs not using TS
400
401
  export * from './common';
401
402
  let _markers = [];
402
403
  const _markerIconDownloadCache = [];
@@ -416,7 +417,7 @@ const _setMapboxMapOptions = (mapView, settings) => {
416
417
  mapView.setZoomLevelAnimated(settings.zoomLevel, false);
417
418
  }
418
419
  mapView.showsUserLocation = settings.showUserLocation;
419
- mapView.autoresizingMask = 2 | 16;
420
+ mapView.autoresizingMask = 2 /* UIViewAutoresizing.FlexibleWidth */ | 16 /* UIViewAutoresizing.FlexibleHeight */;
420
421
  };
421
422
  const _getMapStyle = (input) => {
422
423
  if (input.startsWith('mapbox://styles') || input.startsWith('http://') || input.startsWith('https://')) {
@@ -468,24 +469,30 @@ export function setLogLevel(level) {
468
469
  let loggingLevel;
469
470
  switch (level) {
470
471
  case 'none':
471
- loggingLevel = 0;
472
+ loggingLevel = 0 /* MGLLoggingLevel.None */;
472
473
  break;
473
474
  case 'info':
474
- loggingLevel = 1;
475
+ loggingLevel = 1 /* MGLLoggingLevel.Info */;
475
476
  break;
476
477
  case 'verbose':
477
478
  case 'debug':
478
- loggingLevel = 2;
479
+ loggingLevel = 2 /* MGLLoggingLevel.Debug */;
479
480
  break;
480
481
  case 'error':
481
- loggingLevel = 3;
482
+ loggingLevel = 3 /* MGLLoggingLevel.Error */;
482
483
  break;
483
484
  case 'fault':
484
- loggingLevel = 4;
485
+ loggingLevel = 4 /* MGLLoggingLevel.Fault */;
485
486
  break;
486
487
  }
487
488
  MGLLoggingConfiguration.sharedConfiguration.loggingLevel = loggingLevel;
488
489
  }
490
+ /**
491
+ * Map View Class instantiated from XML
492
+ *
493
+ * This class is created by the NativeScript XML view parsing
494
+ * code.
495
+ */
489
496
  export class MapboxView extends MapboxViewBase {
490
497
  constructor() {
491
498
  super(...arguments);
@@ -493,8 +500,13 @@ export class MapboxView extends MapboxViewBase {
493
500
  this.delegate = null;
494
501
  this.settings = null;
495
502
  this.initialized = false;
503
+ // see initMap. Count of how many times we've
504
+ // tried to init the map.
496
505
  this.initCountHack = 50;
497
506
  }
507
+ /**
508
+ * programmatically include settings
509
+ */
498
510
  setConfig(settings) {
499
511
  if (Trace.isEnabled()) {
500
512
  CLog(CLogTypes.info, 'setConfig(): settings:', settings);
@@ -511,6 +523,19 @@ export class MapboxView extends MapboxViewBase {
511
523
  const v = super.createNativeView();
512
524
  return v;
513
525
  }
526
+ /**
527
+ * init the native view.
528
+ *
529
+ * FIXME: It appears that the order of events is different between iOS and Android.
530
+ * In the demo under Android, the main-page event handler is called first then the one
531
+ * in the plugin. Under iOS it's the reverse.
532
+ *
533
+ * The symptom is that any properties that reference a binding aren't available
534
+ * at the time this method is called. For example {{access_token}}.
535
+ *
536
+ * I'm sure there is something I do not understand about how this is supposed to work
537
+ * and that the handstands below are not necessary.
538
+ */
514
539
  onLoaded() {
515
540
  super.onLoaded();
516
541
  if (Trace.isEnabled()) {
@@ -528,6 +553,15 @@ export class MapboxView extends MapboxViewBase {
528
553
  super.initNativeView();
529
554
  this.nativeView.owner = this;
530
555
  }
556
+ /**
557
+ * when the view is destroyed.
558
+ *
559
+ * This is called by the framework when the view is destroyed (made not visible).
560
+ *
561
+ * However, it does not seem to be called when the page is unloaded.
562
+ *
563
+ * @link https://docs.nativescript.org/plugins/ui-plugin-custom
564
+ */
531
565
  async disposeNativeView() {
532
566
  if (Trace.isEnabled()) {
533
567
  CLog(CLogTypes.info, 'disposeNativeView(): top');
@@ -542,20 +576,39 @@ export class MapboxView extends MapboxViewBase {
542
576
  CLog(CLogTypes.info, 'disposeNativeView(): bottom');
543
577
  }
544
578
  }
579
+ /**
580
+ * returns a reference to the class Mapbox API shim instance
581
+ *
582
+ * @see Mapbox
583
+ */
545
584
  getMapboxApi() {
546
585
  return this.mapbox;
547
586
  }
587
+ /**
588
+ * initialize the map
589
+ *
590
+ * @see MGLMapViewDelegateImpl
591
+ *
592
+ * @todo FIXME: figure out why the accessToken property (which is using a binding in the demo XML) isn't set before we arrive here.
593
+ */
548
594
  initMap() {
549
595
  if (Trace.isEnabled()) {
550
596
  CLog(CLogTypes.info, 'initMap() top with settings:', this.settings);
551
597
  }
598
+ // FIXME: HACK: if we are arriving here because of an XML parse the property evaluations may not have
599
+ // happened yet. This needs to be redone, but for the moment we'll assume the accessToken is done
600
+ // via a property eval (since it really shouldn't be hard coded in XML).
601
+ //
602
+ // settings will only be set here if we are programmatically showing a map.
552
603
  if (!this.settings && !this.config.accessToken) {
553
604
  if (Trace.isEnabled()) {
554
605
  CLog(CLogTypes.info, 'initMap() no access token. Race condition on XML property evaluation?');
555
606
  }
607
+ // If the user didn't specify an accessToken we don't want to loop forever
556
608
  if (this.initCountHack > 50) {
557
609
  return;
558
610
  }
611
+ // FIXME: super ugly.
559
612
  setTimeout(() => {
560
613
  this.initMap();
561
614
  }, 50);
@@ -573,13 +626,18 @@ export class MapboxView extends MapboxViewBase {
573
626
  if (Trace.isEnabled()) {
574
627
  CLog(CLogTypes.info, 'initMap(): after new Mapbox()');
575
628
  }
629
+ // called in a setTimeout call at the bottom.
576
630
  const drawMap = () => {
577
631
  MGLAccountManager.accessToken = this.settings.accessToken;
578
632
  this.nativeMapView = MGLMapView.alloc().initWithFrameStyleURL(CGRectMake(0, 0, this.nativeView.frame.size.width, this.nativeView.frame.size.height), _getMapStyle(this.settings.style));
633
+ // this delegate class is defined later in this file and is where, in Obj-C land,
634
+ // callbacks are delivered and handled.
579
635
  this.nativeMapView.delegate = this.delegate = MGLMapViewDelegateImpl.new().initWithCallback(() => {
580
636
  if (Trace.isEnabled()) {
581
637
  CLog(CLogTypes.info, 'initMap(): MLMapViewDeleteImpl onMapReady callback');
582
638
  }
639
+ // FIXME: on the Android side the view is created in Mapbox::show(). On the iOS side it's created
640
+ // here in MapboxView, however the mapbox api still needs a reference to it.
583
641
  this.mapbox.setMapboxViewInstance(this.nativeMapView);
584
642
  this.mapbox.initEventHandlerShim(this.settings, this.nativeMapView);
585
643
  this.notify({
@@ -588,6 +646,7 @@ export class MapboxView extends MapboxViewBase {
588
646
  map: this,
589
647
  ios: this.nativeMapView
590
648
  });
649
+ // no permission required, but to align with Android we fire the event anyway
591
650
  this.notify({
592
651
  eventName: MapboxViewBase.locationPermissionGrantedEvent,
593
652
  object: this,
@@ -595,9 +654,14 @@ export class MapboxView extends MapboxViewBase {
595
654
  ios: this.nativeMapView
596
655
  });
597
656
  });
657
+ // this.delegate.setStyleLoadedCallback((map, style)=>{
658
+ // this.delegate.setStyleLoadedCallback(null);
659
+ // });
598
660
  _setMapboxMapOptions(this.nativeMapView, this.settings);
599
661
  _markers = [];
600
662
  this.nativeView.addSubview(this.nativeMapView);
663
+ // this.notify will notify an event listener specified
664
+ // in the XML, in this case (onMoveBegin)="..."
601
665
  this.mapbox.setOnMoveBeginListener((data) => {
602
666
  if (Trace.isEnabled()) {
603
667
  CLog(CLogTypes.info, 'initMap(): onMoveBegin listener');
@@ -632,9 +696,10 @@ export class MapboxView extends MapboxViewBase {
632
696
  });
633
697
  }, this.nativeMapView);
634
698
  };
699
+ // draw the map after a timeout
635
700
  setTimeout(drawMap, this.settings.delay ? this.settings.delay : 0);
636
701
  }
637
- }
702
+ } // end of initMap()
638
703
  onLayout(left, top, right, bottom) {
639
704
  super.onLayout(left, top, right, bottom);
640
705
  if (this.nativeMapView) {
@@ -647,18 +712,36 @@ export class MapboxView extends MapboxViewBase {
647
712
  }
648
713
  export class Mapbox extends MapboxCommon {
649
714
  constructor() {
715
+ // reference to the native mapbox API
650
716
  super(...arguments);
651
717
  this.eventCallbacks = {};
652
718
  }
719
+ /**
720
+ * set the mapboxViewInstance
721
+ *
722
+ * @see MapboxView::initMap();
723
+ */
653
724
  setMapboxViewInstance(mapboxViewInstance) {
654
725
  this._mapboxViewInstance = mapboxViewInstance;
655
726
  }
727
+ /**
728
+ * event handler shim
729
+ *
730
+ * Initialize our event handler shim so that we can intercept events here.
731
+ *
732
+ * @param { MapboxView } mapboxView
733
+ */
656
734
  initEventHandlerShim(settings, mapboxNativeViewInstance) {
657
735
  if (Trace.isEnabled()) {
658
736
  CLog(CLogTypes.info, 'Mapbox:initEventHandlerShim(): top');
659
737
  }
660
738
  this.setOnMapClickListener((point) => this.checkForClickEvent(point), mapboxNativeViewInstance);
661
739
  }
740
+ /**
741
+ * register a map event handler
742
+ *
743
+ * The NativeScript ContentView base class as on() and off() methods.
744
+ */
662
745
  onMapEvent(eventName, id, callback, nativeMapView) {
663
746
  if (typeof this.eventCallbacks[eventName] == 'undefined') {
664
747
  this.eventCallbacks[eventName] = [];
@@ -674,6 +757,9 @@ export class Mapbox extends MapboxCommon {
674
757
  }
675
758
  this.eventCallbacks[eventName] = this.eventCallbacks[eventName].filter((entry) => entry.id !== id);
676
759
  }
760
+ /**
761
+ * If click events registered and a feature found for the event, then fire listener.
762
+ */
677
763
  checkForClickEvent(point, nativeMap) {
678
764
  if (Trace.isEnabled()) {
679
765
  CLog(CLogTypes.info, 'Mapbox:checkForClickEvent(): got click event with point:', point);
@@ -715,6 +801,7 @@ export class Mapbox extends MapboxCommon {
715
801
  point.coordinate = CLLocationCoordinate2DMake(lat, lng);
716
802
  point.title = marker.title;
717
803
  point.subtitle = marker.subtitle;
804
+ // needs to be done before adding to the map, otherwise the delegate method 'mapViewImageForAnnotation' can't use it
718
805
  _markers.push(marker);
719
806
  theMap.addAnnotation(point);
720
807
  if (marker.selected) {
@@ -750,6 +837,11 @@ export class Mapbox extends MapboxCommon {
750
837
  });
751
838
  });
752
839
  }
840
+ /**
841
+ * create an display the map
842
+ *
843
+ * @todo FIXME: This method is not called. See MapboxView::initMap().
844
+ */
753
845
  show(options) {
754
846
  if (Trace.isEnabled()) {
755
847
  CLog(CLogTypes.info, 'show(): top with options:', options);
@@ -757,10 +849,14 @@ export class Mapbox extends MapboxCommon {
757
849
  return new Promise((resolve, reject) => {
758
850
  try {
759
851
  const settings = Mapbox.merge(options, Mapbox.defaults);
852
+ // let directions = MBDirections.alloc().initWithAccessToken(arg.accessToken);
853
+ // alert("directions: " + directions);
854
+ // if no accessToken was set the app may crash
760
855
  if (settings.accessToken === undefined) {
761
856
  reject("Please set the 'accessToken' parameter");
762
857
  return;
763
858
  }
859
+ // if already added, make sure it's removed first
764
860
  if (this._mapboxViewInstance) {
765
861
  this._mapboxViewInstance.removeFromSuperview();
766
862
  }
@@ -775,6 +871,7 @@ export class Mapbox extends MapboxCommon {
775
871
  });
776
872
  _markers = [];
777
873
  this._addMarkers(settings.markers);
874
+ // wrapping in a little timeout since the map area tends to flash black a bit initially
778
875
  setTimeout(() => {
779
876
  view.addSubview(this._mapboxViewInstance);
780
877
  }, 500);
@@ -833,6 +930,9 @@ export class Mapbox extends MapboxCommon {
833
930
  resolve();
834
931
  });
835
932
  }
933
+ // ----------------------------------------
934
+ // Life Cycle Hooks - Required on Android
935
+ // ----------------------------------------
836
936
  onStart(nativeMap) {
837
937
  return Promise.resolve();
838
938
  }
@@ -851,10 +951,15 @@ export class Mapbox extends MapboxCommon {
851
951
  onDestroy(nativeMap) {
852
952
  return Promise.resolve();
853
953
  }
954
+ /**
955
+ * explicitly set a map style
956
+ */
854
957
  setMapStyle(style, nativeMap) {
855
958
  return new Promise((resolve, reject) => {
856
959
  try {
857
960
  const theMap = nativeMap || this._mapboxViewInstance;
961
+ // the style takes some time to load so we have to set a callback
962
+ // to wait for the style to finish loading
858
963
  const delegate = theMap.delegate;
859
964
  delegate.setStyleLoadedCallback((mapView) => {
860
965
  if (Trace.isEnabled()) {
@@ -963,6 +1068,7 @@ export class Mapbox extends MapboxCommon {
963
1068
  markersToRemove.push(marker.ios);
964
1069
  }
965
1070
  });
1071
+ // remove markers from cache
966
1072
  if (ids) {
967
1073
  _markers = _markers.filter((marker) => ids.indexOf(marker.id) < 0);
968
1074
  }
@@ -1107,28 +1213,36 @@ export class Mapbox extends MapboxCommon {
1107
1213
  }
1108
1214
  });
1109
1215
  }
1216
+ /**
1217
+ * convert string to camera mode constant.
1218
+ *
1219
+ * Supported modes on iOS are different than on Android.
1220
+ *
1221
+ * @todo come up with a reasonable set of cross platform defaults.
1222
+ */
1110
1223
  _stringToCameraMode(mode) {
1111
1224
  switch (mode) {
1112
- case "NONE":
1113
- return 0;
1114
- case "NONE_COMPASS":
1115
- console.log("MapboxView::_stringToCameraMode(): NONE_COMPASS unsupported on iOS");
1116
- return 0;
1117
- case "NONE_GPS":
1118
- console.log("MapboxView::_stringToCameraMode(): NONE_GPS unsupported on iOS");
1119
- return 0;
1120
- case "TRACKING":
1121
- return 1;
1122
- case "TRACKING_COMPASS":
1123
- return 2;
1124
- case "TRACKING_GPS":
1125
- return 1;
1126
- case "TRACKING_GPS_NORTH":
1127
- return 3;
1225
+ case 'NONE':
1226
+ return 0 /* MGLUserTrackingMode.None */;
1227
+ case 'NONE_COMPASS':
1228
+ console.log('MapboxView::_stringToCameraMode(): NONE_COMPASS unsupported on iOS');
1229
+ return 0 /* MGLUserTrackingMode.None */;
1230
+ case 'NONE_GPS':
1231
+ console.log('MapboxView::_stringToCameraMode(): NONE_GPS unsupported on iOS');
1232
+ return 0 /* MGLUserTrackingMode.None */;
1233
+ case 'TRACKING':
1234
+ return 1 /* MGLUserTrackingMode.Follow */;
1235
+ case 'TRACKING_COMPASS':
1236
+ return 2 /* MGLUserTrackingMode.FollowWithHeading */;
1237
+ case 'TRACKING_GPS':
1238
+ // a reasonable approximation.
1239
+ return 1 /* MGLUserTrackingMode.Follow */;
1240
+ case 'TRACKING_GPS_NORTH':
1241
+ return 3 /* MGLUserTrackingMode.FollowWithCourse */;
1128
1242
  default:
1129
1243
  console.log(`_stringToCameraMode: invalid cameraMode: ${mode}`);
1130
1244
  }
1131
- return 0;
1245
+ return 0 /* MGLUserTrackingMode.None */;
1132
1246
  }
1133
1247
  _stringToRenderMode(mode) {
1134
1248
  let renderMode;
@@ -1143,16 +1257,32 @@ export class Mapbox extends MapboxCommon {
1143
1257
  }
1144
1258
  _convertCameraMode(mode) {
1145
1259
  switch (mode) {
1146
- case 0:
1147
- return "NONE";
1148
- case 1:
1149
- return "TRACKING";
1150
- case 2:
1151
- return "TRACKING_COMPASS";
1152
- case 3:
1153
- return "TRACKING_GPS_NORTH";
1260
+ case 0 /* MGLUserTrackingMode.None */:
1261
+ return 'NONE';
1262
+ case 1 /* MGLUserTrackingMode.Follow */:
1263
+ return 'TRACKING';
1264
+ case 2 /* MGLUserTrackingMode.FollowWithHeading */:
1265
+ return 'TRACKING_COMPASS';
1266
+ case 3 /* MGLUserTrackingMode.FollowWithCourse */:
1267
+ return 'TRACKING_GPS_NORTH';
1154
1268
  }
1155
1269
  }
1270
+ /**
1271
+ * show a user location marker
1272
+ *
1273
+ * This method must not be called before location permissions have been granted.
1274
+ *
1275
+ * Supported options under iOS are:
1276
+ *
1277
+ * - renderMode
1278
+ * - cameraMode
1279
+ * - clickListener
1280
+ *
1281
+ * Other options are ignored. Compare with the android version that supports a
1282
+ * different set of options.
1283
+ *
1284
+ * @param {object} options
1285
+ */
1156
1286
  showUserLocationMarker(options, nativeMap) {
1157
1287
  return new Promise((resolve, reject) => {
1158
1288
  try {
@@ -1161,7 +1291,10 @@ export class Mapbox extends MapboxCommon {
1161
1291
  theMap.userTrackingMode = this._stringToCameraMode(options.cameraMode);
1162
1292
  theMap.showsUserHeadingIndicator = true;
1163
1293
  this.userLocationRenderMode = this._stringToRenderMode(options.renderMode);
1294
+ // the "delegate" needs to know the modes
1164
1295
  const delegate = theMap.delegate;
1296
+ // tell the delegate to tell the CustomerLocationAnnotationView to change the
1297
+ // appearance of the marker.
1165
1298
  delegate.changeUserLocationRenderMode(this.userLocationRenderMode);
1166
1299
  if (typeof options.clickListener != 'undefined') {
1167
1300
  delegate.setUserLocationClickListener(options.clickListener);
@@ -1176,6 +1309,11 @@ export class Mapbox extends MapboxCommon {
1176
1309
  }
1177
1310
  });
1178
1311
  }
1312
+ /**
1313
+ * hide the user location marker
1314
+ *
1315
+ * @todo unfinished
1316
+ */
1179
1317
  hideUserLocationMarker(nativeMap) {
1180
1318
  return new Promise((resolve, reject) => {
1181
1319
  try {
@@ -1189,6 +1327,15 @@ export class Mapbox extends MapboxCommon {
1189
1327
  }
1190
1328
  });
1191
1329
  }
1330
+ /**
1331
+ * Change the mode of the user location marker
1332
+ *
1333
+ * Used to change the camera tracking and render modes of an existing
1334
+ * marker.
1335
+ *
1336
+ * The marker must be configured using showUserLocationMarker before this method
1337
+ * can called.
1338
+ */
1192
1339
  changeUserLocationMarkerMode(renderModeString, cameraModeString, nativeMap) {
1193
1340
  return new Promise((resolve, reject) => {
1194
1341
  try {
@@ -1209,6 +1356,9 @@ export class Mapbox extends MapboxCommon {
1209
1356
  }
1210
1357
  });
1211
1358
  }
1359
+ /**
1360
+ * ignored on iOS
1361
+ */
1212
1362
  forceUserLocationUpdate(location, nativeMap) { }
1213
1363
  queryRenderedFeatures(options, nativeMap) {
1214
1364
  return new Promise((resolve, reject) => {
@@ -1283,6 +1433,9 @@ export class Mapbox extends MapboxCommon {
1283
1433
  }
1284
1434
  });
1285
1435
  }
1436
+ /**
1437
+ * @deprecated
1438
+ */
1286
1439
  addPolygon(options, nativeMap) {
1287
1440
  return new Promise((resolve, reject) => {
1288
1441
  const theMap = nativeMap || this._mapboxViewInstance;
@@ -1345,6 +1498,7 @@ export class Mapbox extends MapboxCommon {
1345
1498
  const coordinateArray = [];
1346
1499
  points.forEach((point) => coordinateArray.push([point.lng, point.lat]));
1347
1500
  const polylineID = 'polyline_' + (options.id || new Date().getTime());
1501
+ // this would otherwise crash the app
1348
1502
  if (theMap.style.sourceWithIdentifier(polylineID)) {
1349
1503
  reject("Remove the polyline with this id first with 'removePolylines': " + polylineID);
1350
1504
  return;
@@ -1370,6 +1524,7 @@ export class Mapbox extends MapboxCommon {
1370
1524
  if (layer !== null) {
1371
1525
  theMap.style.removeLayer(layer);
1372
1526
  }
1527
+ // polygons may have a 'stroke' layer
1373
1528
  layer = theMap.style.layerWithIdentifier(id + '_stroke');
1374
1529
  if (layer !== null) {
1375
1530
  theMap.style.removeLayer(layer);
@@ -1399,6 +1554,7 @@ export class Mapbox extends MapboxCommon {
1399
1554
  let cam;
1400
1555
  if (options.bounds) {
1401
1556
  const padding = options.padding || 0;
1557
+ // support defined padding
1402
1558
  const insets = {
1403
1559
  top: padding,
1404
1560
  left: padding,
@@ -1446,6 +1602,10 @@ export class Mapbox extends MapboxCommon {
1446
1602
  }
1447
1603
  });
1448
1604
  }
1605
+ /**
1606
+ * sets a map level click listener
1607
+ *
1608
+ */
1449
1609
  setOnMapClickListener(listener, nativeMap) {
1450
1610
  return new Promise((resolve, reject) => {
1451
1611
  try {
@@ -1459,7 +1619,8 @@ export class Mapbox extends MapboxCommon {
1459
1619
  for (let i = 0; i < theMap.gestureRecognizers.count; i++) {
1460
1620
  const recognizer = theMap.gestureRecognizers.objectAtIndex(i);
1461
1621
  if (recognizer instanceof UITapGestureRecognizer) {
1462
- tapGestureRecognizer.requireGestureRecognizerToFail(recognizer);
1622
+ recognizer.addTargetAction(theMap['mapTapHandler'], 'tap');
1623
+ break;
1463
1624
  }
1464
1625
  }
1465
1626
  theMap.addGestureRecognizer(tapGestureRecognizer);
@@ -1481,8 +1642,10 @@ export class Mapbox extends MapboxCommon {
1481
1642
  reject('No map has been loaded');
1482
1643
  return;
1483
1644
  }
1645
+ // adding the longPress handler to the map oject so it's not GC'd
1484
1646
  theMap['mapLongPressHandler'] = MapLongPressHandlerImpl.initWithOwnerAndListenerForMap(new WeakRef(this), listener, theMap);
1485
1647
  const longPressGestureRecognizer = UILongPressGestureRecognizer.alloc().initWithTargetAction(theMap['mapLongPressHandler'], 'longPress');
1648
+ // cancel the default longPress handler
1486
1649
  for (let i = 0; i < theMap.gestureRecognizers.count; i++) {
1487
1650
  const recognizer = theMap.gestureRecognizers.objectAtIndex(i);
1488
1651
  if (recognizer instanceof UILongPressGestureRecognizer) {
@@ -1508,12 +1671,14 @@ export class Mapbox extends MapboxCommon {
1508
1671
  reject('No map has been loaded');
1509
1672
  return;
1510
1673
  }
1674
+ // adding the pan handler to the map oject so it's not GC'd
1511
1675
  if (theMap['mapPanHandler'] === undefined) {
1512
- theMap['mapPanHandler'] = MapPanHandlerImpl.initWithOwnerAndListenerForMap(new WeakRef(this), listener, 2, theMap);
1676
+ theMap['mapPanHandler'] = MapPanHandlerImpl.initWithOwnerAndListenerForMap(new WeakRef(this), listener, 2 /* UIGestureRecognizerState.Changed */, theMap);
1513
1677
  }
1514
1678
  else {
1515
- theMap['mapPanHandler'].addListener(2, listener);
1679
+ theMap['mapPanHandler'].addListener(2 /* UIGestureRecognizerState.Changed */, listener);
1516
1680
  }
1681
+ // there's already a pan recognizer, so find it and attach a target action
1517
1682
  for (let i = 0; i < theMap.gestureRecognizers.count; i++) {
1518
1683
  const recognizer = theMap.gestureRecognizers.objectAtIndex(i);
1519
1684
  if (recognizer instanceof UIPanGestureRecognizer) {
@@ -1531,6 +1696,12 @@ export class Mapbox extends MapboxCommon {
1531
1696
  }
1532
1697
  });
1533
1698
  }
1699
+ /**
1700
+ * simulates onMoveBegin single event callback
1701
+ *
1702
+ * This will call the listener provided once per pan akin to the way
1703
+ * onMoveBegin on the Android side works.
1704
+ */
1534
1705
  setOnMoveBeginListener(listener, nativeMap) {
1535
1706
  return new Promise((resolve, reject) => {
1536
1707
  try {
@@ -1539,12 +1710,14 @@ export class Mapbox extends MapboxCommon {
1539
1710
  reject('No map has been loaded');
1540
1711
  return;
1541
1712
  }
1713
+ // adding the pan handler to the map oject so it's not GC'd
1542
1714
  if (theMap['mapPanHandler'] === undefined) {
1543
- theMap['mapPanHandler'] = MapPanHandlerImpl.initWithOwnerAndListenerForMap(new WeakRef(this), listener, 1, theMap);
1715
+ theMap['mapPanHandler'] = MapPanHandlerImpl.initWithOwnerAndListenerForMap(new WeakRef(this), listener, 1 /* UIGestureRecognizerState.Began */, theMap);
1544
1716
  }
1545
1717
  else {
1546
- theMap['mapPanHandler'].addListener(1, listener);
1718
+ theMap['mapPanHandler'].addListener(1 /* UIGestureRecognizerState.Began */, listener);
1547
1719
  }
1720
+ // there's already a pan recognizer, so find it and attach a target action
1548
1721
  for (let i = 0; i < theMap.gestureRecognizers.count; i++) {
1549
1722
  const recognizer = theMap.gestureRecognizers.objectAtIndex(i);
1550
1723
  if (recognizer instanceof UIPanGestureRecognizer) {
@@ -1571,11 +1744,12 @@ export class Mapbox extends MapboxCommon {
1571
1744
  return;
1572
1745
  }
1573
1746
  if (theMap['mapPanHandler'] === undefined) {
1574
- theMap['mapPanHandler'] = MapPanHandlerImpl.initWithOwnerAndListenerForMap(new WeakRef(this), listener, 3, theMap);
1747
+ theMap['mapPanHandler'] = MapPanHandlerImpl.initWithOwnerAndListenerForMap(new WeakRef(this), listener, 3 /* UIGestureRecognizerState.Ended */, theMap);
1575
1748
  }
1576
1749
  else {
1577
- theMap['mapPanHandler'].addListener(3, listener);
1750
+ theMap['mapPanHandler'].addListener(3 /* UIGestureRecognizerState.Ended */, listener);
1578
1751
  }
1752
+ // there's already a pan recognizer, so find it and attach a target action
1579
1753
  for (let i = 0; i < theMap.gestureRecognizers.count; i++) {
1580
1754
  const recognizer = theMap.gestureRecognizers.objectAtIndex(i);
1581
1755
  if (recognizer instanceof UIPanGestureRecognizer) {
@@ -1594,6 +1768,7 @@ export class Mapbox extends MapboxCommon {
1594
1768
  });
1595
1769
  }
1596
1770
  setOnFlingListener(listener, nativeMap) {
1771
+ // there's no swipe event we can bind to
1597
1772
  return Promise.reject("'setOnFlingListener' is not supported on iOS");
1598
1773
  }
1599
1774
  async setOnCameraMoveListener(listener, nativeMap) {
@@ -1658,6 +1833,7 @@ export class Mapbox extends MapboxCommon {
1658
1833
  ne: CLLocationCoordinate2DMake(options.bounds.north, options.bounds.east)
1659
1834
  };
1660
1835
  const animated = options.animated === undefined || options.animated;
1836
+ // support defined padding
1661
1837
  const padding = options.padding !== undefined ? { top: options.padding, left: options.padding, bottom: options.padding, right: options.padding } : { top: 25, left: 25, bottom: 25, right: 25 };
1662
1838
  theMap.setVisibleCoordinateBoundsEdgePaddingAnimated(bounds, padding, animated);
1663
1839
  resolve();
@@ -1684,6 +1860,7 @@ export class Mapbox extends MapboxCommon {
1684
1860
  if (options.accessToken) {
1685
1861
  MGLAccountManager.accessToken = options.accessToken;
1686
1862
  }
1863
+ // TODO there's more observers, see https://www.mapbox.com/ios-sdk/examples/offline-pack/
1687
1864
  if (options.onProgress) {
1688
1865
  _addObserver(MGLOfflinePackProgressChangedNotification, (notification) => {
1689
1866
  const offlinePack = notification.object;
@@ -1717,13 +1894,17 @@ export class Mapbox extends MapboxCommon {
1717
1894
  const maximumCount = notification.userInfo[MGLOfflinePackUserInfoKeyMaximumCount];
1718
1895
  console.log(`Offline region '${userInfo.objectForKey('name')}' reached the tile limit of ${maximumCount}`);
1719
1896
  });
1897
+ // Store some data for identification purposes alongside the downloaded resources.
1720
1898
  const userInfo = { name: options.name };
1721
1899
  const context = NSKeyedArchiver.archivedDataWithRootObject(userInfo);
1900
+ // Create and register an offline pack with the shared offline storage object.
1722
1901
  MGLOfflineStorage.sharedOfflineStorage.addPackForRegionWithContextCompletionHandler(region, context, (pack, error) => {
1723
1902
  if (error) {
1903
+ // The pack couldn’t be created for some reason.
1724
1904
  reject(error.localizedFailureReason);
1725
1905
  }
1726
1906
  else {
1907
+ // Start downloading.
1727
1908
  pack.resume();
1728
1909
  }
1729
1910
  });
@@ -1789,12 +1970,15 @@ export class Mapbox extends MapboxCommon {
1789
1970
  found = true;
1790
1971
  MGLOfflineStorage.sharedOfflineStorage.removePackWithCompletionHandler(pack, (error) => {
1791
1972
  if (error) {
1973
+ // The pack couldn’t be deleted for some reason.
1792
1974
  reject(error.localizedFailureReason);
1793
1975
  }
1794
1976
  else {
1795
1977
  resolve();
1978
+ // don't return, see note below
1796
1979
  }
1797
1980
  });
1981
+ // don't break the loop as there may be multiple packs with the same name
1798
1982
  }
1799
1983
  }
1800
1984
  if (!found) {
@@ -1827,6 +2011,10 @@ export class Mapbox extends MapboxCommon {
1827
2011
  }
1828
2012
  });
1829
2013
  }
2014
+ /**
2015
+ * update a geojson source
2016
+ *
2017
+ */
1830
2018
  updateSource(id, options, nativeMap) {
1831
2019
  return new Promise((resolve, reject) => {
1832
2020
  try {
@@ -1861,6 +2049,14 @@ export class Mapbox extends MapboxCommon {
1861
2049
  }
1862
2050
  });
1863
2051
  }
2052
+ /**
2053
+ * add a vector or geojson source
2054
+ *
2055
+ * Add a source that can then be referenced in the style specification
2056
+ * passed to addLayer().
2057
+ *
2058
+ * @link https://docs.mapbox.com/mapbox-gl-js/api/#map#addsource
2059
+ */
1864
2060
  addSource(id, options, nativeMap) {
1865
2061
  return new Promise((resolve, reject) => {
1866
2062
  try {
@@ -1890,10 +2086,10 @@ export class Mapbox extends MapboxCommon {
1890
2086
  if (options.scheme) {
1891
2087
  switch (options.scheme) {
1892
2088
  case 'xyz':
1893
- sourceOptions[MGLTileSourceOptionTileCoordinateSystem] = 0;
2089
+ sourceOptions[MGLTileSourceOptionTileCoordinateSystem] = 0 /* MGLTileCoordinateSystem.XYZ */;
1894
2090
  break;
1895
2091
  case 'tms':
1896
- sourceOptions[MGLTileSourceOptionTileCoordinateSystem] = 1;
2092
+ sourceOptions[MGLTileSourceOptionTileCoordinateSystem] = 1 /* MGLTileCoordinateSystem.TMS */;
1897
2093
  break;
1898
2094
  default:
1899
2095
  throw new Error('Unknown raster tile scheme.');
@@ -1937,6 +2133,7 @@ export class Mapbox extends MapboxCommon {
1937
2133
  if (options.cluster.properties) {
1938
2134
  const clusterProperties = {};
1939
2135
  for (const property of Object.keys(options.cluster.properties)) {
2136
+ // eslint-disable-next-line prefer-const
1940
2137
  let [operator, operand] = options.cluster.properties[property];
1941
2138
  if (!Array.isArray(operator)) {
1942
2139
  operator = [operator];
@@ -1962,10 +2159,10 @@ export class Mapbox extends MapboxCommon {
1962
2159
  if (options.scheme) {
1963
2160
  switch (options.scheme || 'xyz') {
1964
2161
  case 'xyz':
1965
- sourceOptions[MGLTileSourceOptionTileCoordinateSystem] = 0;
2162
+ sourceOptions[MGLTileSourceOptionTileCoordinateSystem] = 0 /* MGLTileCoordinateSystem.XYZ */;
1966
2163
  break;
1967
2164
  case 'tms':
1968
- sourceOptions[MGLTileSourceOptionTileCoordinateSystem] = 1;
2165
+ sourceOptions[MGLTileSourceOptionTileCoordinateSystem] = 1 /* MGLTileCoordinateSystem.TMS */;
1969
2166
  break;
1970
2167
  default:
1971
2168
  throw new Error('Unknown raster tile scheme.');
@@ -2003,6 +2200,9 @@ export class Mapbox extends MapboxCommon {
2003
2200
  }
2004
2201
  });
2005
2202
  }
2203
+ /**
2204
+ * remove source by id
2205
+ */
2006
2206
  removeSource(id, nativeMap) {
2007
2207
  return new Promise((resolve, reject) => {
2008
2208
  try {
@@ -2027,6 +2227,24 @@ export class Mapbox extends MapboxCommon {
2027
2227
  }
2028
2228
  });
2029
2229
  }
2230
+ /**
2231
+ * a rough analogue to the mapbox-gl-js addLayer() method
2232
+ *
2233
+ * It would be nice if this {N} API matched the mapbox-gl-js API which
2234
+ * would make it much easier to share mapping applications between the web
2235
+ * and {N} apps.
2236
+ *
2237
+ * This method accepts a Mapbox-GL-JS style specification JSON object with some
2238
+ * limitations:
2239
+ *
2240
+ * - the source: must be a GeoJSON object.
2241
+ * - only a subset of paint properties are available.
2242
+ *
2243
+ * @param {object} style - a style following the Mapbox style specification.
2244
+ * @param {any} nativeMapView - native map view (com.mapbox.mapboxsdk.maps.MapView)
2245
+ *
2246
+ * @link https://docs.mapbox.com/mapbox-gl-js/style-spec/#layers
2247
+ */
2030
2248
  async addLayer(style, belowLayerId, nativeMapView) {
2031
2249
  const theMap = nativeMapView || this._mapboxViewInstance;
2032
2250
  let source = null;
@@ -2047,6 +2265,13 @@ export class Mapbox extends MapboxCommon {
2047
2265
  }
2048
2266
  theMap.style.addLayer(layer.getNativeInstance());
2049
2267
  }
2268
+ /**
2269
+ * remove layer by ID
2270
+ *
2271
+ * Removes a layer given a layer id
2272
+ *
2273
+ * @param {string} id
2274
+ */
2050
2275
  async removeLayer(id, nativeMapViewInstance) {
2051
2276
  const theMap = nativeMapViewInstance || this._mapboxViewInstance;
2052
2277
  if (Trace.isEnabled()) {
@@ -2064,6 +2289,21 @@ export class Mapbox extends MapboxCommon {
2064
2289
  CLog(CLogTypes.info, 'Mapbox:removeLayer(): after removing layer ' + id);
2065
2290
  }
2066
2291
  }
2292
+ /**
2293
+ * @deprecated
2294
+ * Add a point to a line
2295
+ *
2296
+ * This method appends a point to a line and is useful for drawing a users track.
2297
+ *
2298
+ * The process for adding a point to a line is different in the iOS sdk than in
2299
+ * the Android java sdk.
2300
+ *
2301
+ * @param {id} id - id of line to add a point to.
2302
+ * @param {array} lnglat - [lng,lat] to append to the line.
2303
+ *
2304
+ * @link https://github.com/mapbox/mapbox-gl-native/issues/13983
2305
+ * @link https://docs.mapbox.com/ios/maps/examples/runtime-animate-line/
2306
+ */
2067
2307
  async addLinePoint(id, lnglat, sourceId, nativeMapView) {
2068
2308
  const theMap = nativeMapView || this._mapboxViewInstance;
2069
2309
  const sId = !!sourceId ? sourceId : id + '_source';
@@ -2089,6 +2329,72 @@ export class Mapbox extends MapboxCommon {
2089
2329
  }
2090
2330
  addGeoJsonClustered(options, nativeMapViewInstance) {
2091
2331
  throw new Error('Method not implemented.');
2332
+ // return new Promise((resolve, reject) => {
2333
+ // const theMap: MGLMapView = nativeMapViewInstance || this._mapboxViewInstance;
2334
+ // try {
2335
+ // const source = MGLShapeSource.alloc().initWithIdentifierURLOptions(options.name, NSURL.URLWithString(options.data), null);
2336
+ // theMap.style.addSource(source);
2337
+ // const layers = [];
2338
+ // if (options.clusters) {
2339
+ // for (let i = 0; i < options.clusters.length; i++) {
2340
+ // // TODO also allow Color object
2341
+ // layers.push([options.clusters[i].points, new Color(options.clusters[i].color).ios]);
2342
+ // }
2343
+ // } else {
2344
+ // layers.push([150, new Color('red').ios]);
2345
+ // layers.push([20, new Color('green').ios]);
2346
+ // layers.push([0, new Color('blue').ios]);
2347
+ // }
2348
+ // const unclustered = MGLCircleStyleLayer.alloc().initWithIdentifierSource(options.name, source);
2349
+ // unclustered.circleColor = NSExpression.expressionWithFormatArgumentArray('%@', new Color('red').ios);
2350
+ // unclustered.circleRadius = NSExpression.expressionWithFormatArgumentArray('16', null);
2351
+ // unclustered.circleBlur = NSExpression.expressionWithFormatArgumentArray('0.2', null);
2352
+ // // unclustered.setFilter(com.mapbox.mapboxsdk.style.expressions.Expression.neq(com.mapbox.mapboxsdk.style.expressions.Expression.get('cluster'), true));
2353
+ // // theMap.style.addLayer(unclustered); // , "building");
2354
+ // for (let i = 0; i < layers.length; i++) {
2355
+ // // Add some nice circles
2356
+ // const circles = MGLCircleStyleLayer.alloc().initWithIdentifierSource(options.name, source);
2357
+ // const circles = new com.mapbox.mapboxsdk.style.layers.CircleLayer('cluster-' + i, options.name);
2358
+ // // circles.setProperties([
2359
+ // // // com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconImage("icon")
2360
+ // // com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleColor(layers[i][1]),
2361
+ // // com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleRadius(new java.lang.Float(22.0)),
2362
+ // // com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleBlur(new java.lang.Float(0.2)),
2363
+ // // ]);
2364
+ // // const pointCount = com.mapbox.mapboxsdk.style.expressions.Expression.toNumber(com.mapbox.mapboxsdk.style.expressions.Expression.get('point_count'));
2365
+ // // if (i === 0) {
2366
+ // // circles.setFilter(
2367
+ // // com.mapbox.mapboxsdk.style.expressions.Expression.gte(pointCount, com.mapbox.mapboxsdk.style.expressions.Expression.literal(java.lang.Integer.valueOf(layers[i][0])))
2368
+ // // );
2369
+ // // } else {
2370
+ // // circles.setFilter(
2371
+ // // com.mapbox.mapboxsdk.style.expressions.Expression.all([
2372
+ // // com.mapbox.mapboxsdk.style.expressions.Expression.gte(pointCount, com.mapbox.mapboxsdk.style.expressions.Expression.literal(java.lang.Integer.valueOf(layers[i][0]))),
2373
+ // // com.mapbox.mapboxsdk.style.expressions.Expression.lt(
2374
+ // // pointCount,
2375
+ // // com.mapbox.mapboxsdk.style.expressions.Expression.literal(java.lang.Integer.valueOf(layers[i - 1][0]))
2376
+ // // ),
2377
+ // // ])
2378
+ // // );
2379
+ // // }
2380
+ // // this._mapboxMapInstance.getStyle().addLayer(circles); // , "building");
2381
+ // }
2382
+ // // // Add the count labels (note that this doesn't show.. #sad)
2383
+ // // const count = new com.mapbox.mapboxsdk.style.layers.SymbolLayer('count', options.name);
2384
+ // // count.setProperties([
2385
+ // // com.mapbox.mapboxsdk.style.layers.PropertyFactory.textField(com.mapbox.mapboxsdk.style.expressions.Expression.get('point_count')),
2386
+ // // com.mapbox.mapboxsdk.style.layers.PropertyFactory.textSize(new java.lang.Float(12.0)),
2387
+ // // com.mapbox.mapboxsdk.style.layers.PropertyFactory.textColor(new Color('white').android),
2388
+ // // ]);
2389
+ // // this._mapboxMapInstance.getStyle().addLayer(count);
2390
+ // resolve();
2391
+ // } catch (ex) {
2392
+ // if (Trace.isEnabled()) {
2393
+ // CLog(CLogTypes.info, 'Error in mapbox.addGeoJsonClustered: ' + ex);
2394
+ // }
2395
+ // reject(ex);
2396
+ // }
2397
+ // });
2092
2398
  }
2093
2399
  trackUser(options, nativeMap) {
2094
2400
  return new Promise((resolve, reject) => {
@@ -2173,9 +2479,9 @@ export class Mapbox extends MapboxCommon {
2173
2479
  };
2174
2480
  }
2175
2481
  getUserLocationCameraMode(nativeMap) {
2176
- let theMap = nativeMap || this._mapboxViewInstance;
2482
+ const theMap = nativeMap || this._mapboxViewInstance;
2177
2483
  if (!theMap) {
2178
- return "NONE";
2484
+ return 'NONE';
2179
2485
  }
2180
2486
  return this._convertCameraMode(theMap.userTrackingMode);
2181
2487
  }
@@ -2186,6 +2492,7 @@ function _downloadImage(marker) {
2186
2492
  if (Trace.isEnabled()) {
2187
2493
  CLog(CLogTypes.info, '>> _downloadImage');
2188
2494
  }
2495
+ // to cache..
2189
2496
  if (_markerIconDownloadCache[marker.icon]) {
2190
2497
  marker.iconDownloaded = _markerIconDownloadCache[marker.icon];
2191
2498
  if (Trace.isEnabled()) {
@@ -2194,6 +2501,7 @@ function _downloadImage(marker) {
2194
2501
  resolve(marker);
2195
2502
  return;
2196
2503
  }
2504
+ // ..or not to cache
2197
2505
  Http.getImage(marker.icon).then((output) => {
2198
2506
  marker.iconDownloaded = output.ios;
2199
2507
  _markerIconDownloadCache[marker.icon] = marker.iconDownloaded;