@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.ios.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Color, File, Http, ImageSource, Trace, Utils, knownFolders, path } from '@nativescript/core';
|
|
2
|
-
import { CLog, CLogTypes, MapStyle, MapboxCommon, MapboxViewBase, telemetryProperty } from './common';
|
|
2
|
+
import { CLog, CLogTypes, MapStyle, MapboxCommon, MapboxTraceCategory, MapboxViewBase, telemetryProperty } from './common';
|
|
3
3
|
import { Layer, LayerFactory } from './layers/layer-factory';
|
|
4
4
|
import { ExpressionParser } from './expression/expression-parser';
|
|
5
5
|
var MGLMapViewDelegateImpl = /** @class */ (function (_super) {
|
|
@@ -42,7 +42,7 @@ var MGLMapViewDelegateImpl = /** @class */ (function (_super) {
|
|
|
42
42
|
* set user location marker modes
|
|
43
43
|
*/
|
|
44
44
|
MGLMapViewDelegateImpl.prototype.changeUserLocationRenderMode = function (userLocationRenderMode) {
|
|
45
|
-
|
|
45
|
+
// nothing to do here
|
|
46
46
|
};
|
|
47
47
|
/**
|
|
48
48
|
* set the camera changd listener callback
|
|
@@ -234,19 +234,6 @@ var MGLMapViewDelegateImpl = /** @class */ (function (_super) {
|
|
|
234
234
|
}
|
|
235
235
|
}
|
|
236
236
|
};
|
|
237
|
-
/**
|
|
238
|
-
* override the standard location marker
|
|
239
|
-
*/
|
|
240
|
-
MGLMapViewDelegateImpl.prototype.mapViewViewForAnnotation = function (mapView, annotation) {
|
|
241
|
-
if (Trace.isEnabled()) {
|
|
242
|
-
CLog(CLogTypes.info, 'MGLMapViewDelegateImpl::mapViewViewForAnnotation() top');
|
|
243
|
-
}
|
|
244
|
-
if (annotation.isKindOfClass(MGLUserLocation.class())) {
|
|
245
|
-
this.userLocationAnnotationView = CustomUserLocationAnnotationView.alloc().init();
|
|
246
|
-
return this.userLocationAnnotationView;
|
|
247
|
-
}
|
|
248
|
-
return null;
|
|
249
|
-
};
|
|
250
237
|
MGLMapViewDelegateImpl.prototype.mapViewRegionIsChangingWithReason = function (mapView, reason) {
|
|
251
238
|
if (Trace.isEnabled()) {
|
|
252
239
|
CLog(CLogTypes.info, 'MGLMapViewDelegateImpl::mapViewRegionIsChanging()');
|
|
@@ -410,6 +397,7 @@ var MapSwipeHandlerImpl = /** @class */ (function (_super) {
|
|
|
410
397
|
};
|
|
411
398
|
return MapSwipeHandlerImpl;
|
|
412
399
|
}(NSObject));
|
|
400
|
+
// Export the enums for devs not using TS
|
|
413
401
|
export * from './common';
|
|
414
402
|
let _markers = [];
|
|
415
403
|
const _markerIconDownloadCache = [];
|
|
@@ -429,7 +417,7 @@ const _setMapboxMapOptions = (mapView, settings) => {
|
|
|
429
417
|
mapView.setZoomLevelAnimated(settings.zoomLevel, false);
|
|
430
418
|
}
|
|
431
419
|
mapView.showsUserLocation = settings.showUserLocation;
|
|
432
|
-
mapView.autoresizingMask = 2 | 16
|
|
420
|
+
mapView.autoresizingMask = 2 /* UIViewAutoresizing.FlexibleWidth */ | 16 /* UIViewAutoresizing.FlexibleHeight */;
|
|
433
421
|
};
|
|
434
422
|
const _getMapStyle = (input) => {
|
|
435
423
|
if (input.startsWith('mapbox://styles') || input.startsWith('http://') || input.startsWith('https://')) {
|
|
@@ -481,24 +469,30 @@ export function setLogLevel(level) {
|
|
|
481
469
|
let loggingLevel;
|
|
482
470
|
switch (level) {
|
|
483
471
|
case 'none':
|
|
484
|
-
loggingLevel = 0
|
|
472
|
+
loggingLevel = 0 /* MGLLoggingLevel.None */;
|
|
485
473
|
break;
|
|
486
474
|
case 'info':
|
|
487
|
-
loggingLevel = 1
|
|
475
|
+
loggingLevel = 1 /* MGLLoggingLevel.Info */;
|
|
488
476
|
break;
|
|
489
477
|
case 'verbose':
|
|
490
478
|
case 'debug':
|
|
491
|
-
loggingLevel = 2
|
|
479
|
+
loggingLevel = 2 /* MGLLoggingLevel.Debug */;
|
|
492
480
|
break;
|
|
493
481
|
case 'error':
|
|
494
|
-
loggingLevel = 3
|
|
482
|
+
loggingLevel = 3 /* MGLLoggingLevel.Error */;
|
|
495
483
|
break;
|
|
496
484
|
case 'fault':
|
|
497
|
-
loggingLevel = 4
|
|
485
|
+
loggingLevel = 4 /* MGLLoggingLevel.Fault */;
|
|
498
486
|
break;
|
|
499
487
|
}
|
|
500
488
|
MGLLoggingConfiguration.sharedConfiguration.loggingLevel = loggingLevel;
|
|
501
489
|
}
|
|
490
|
+
/**
|
|
491
|
+
* Map View Class instantiated from XML
|
|
492
|
+
*
|
|
493
|
+
* This class is created by the NativeScript XML view parsing
|
|
494
|
+
* code.
|
|
495
|
+
*/
|
|
502
496
|
export class MapboxView extends MapboxViewBase {
|
|
503
497
|
constructor() {
|
|
504
498
|
super(...arguments);
|
|
@@ -506,8 +500,13 @@ export class MapboxView extends MapboxViewBase {
|
|
|
506
500
|
this.delegate = null;
|
|
507
501
|
this.settings = null;
|
|
508
502
|
this.initialized = false;
|
|
503
|
+
// see initMap. Count of how many times we've
|
|
504
|
+
// tried to init the map.
|
|
509
505
|
this.initCountHack = 50;
|
|
510
506
|
}
|
|
507
|
+
/**
|
|
508
|
+
* programmatically include settings
|
|
509
|
+
*/
|
|
511
510
|
setConfig(settings) {
|
|
512
511
|
if (Trace.isEnabled()) {
|
|
513
512
|
CLog(CLogTypes.info, 'setConfig(): settings:', settings);
|
|
@@ -524,6 +523,19 @@ export class MapboxView extends MapboxViewBase {
|
|
|
524
523
|
const v = super.createNativeView();
|
|
525
524
|
return v;
|
|
526
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
|
+
*/
|
|
527
539
|
onLoaded() {
|
|
528
540
|
super.onLoaded();
|
|
529
541
|
if (Trace.isEnabled()) {
|
|
@@ -541,6 +553,15 @@ export class MapboxView extends MapboxViewBase {
|
|
|
541
553
|
super.initNativeView();
|
|
542
554
|
this.nativeView.owner = this;
|
|
543
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
|
+
*/
|
|
544
565
|
async disposeNativeView() {
|
|
545
566
|
if (Trace.isEnabled()) {
|
|
546
567
|
CLog(CLogTypes.info, 'disposeNativeView(): top');
|
|
@@ -555,20 +576,39 @@ export class MapboxView extends MapboxViewBase {
|
|
|
555
576
|
CLog(CLogTypes.info, 'disposeNativeView(): bottom');
|
|
556
577
|
}
|
|
557
578
|
}
|
|
579
|
+
/**
|
|
580
|
+
* returns a reference to the class Mapbox API shim instance
|
|
581
|
+
*
|
|
582
|
+
* @see Mapbox
|
|
583
|
+
*/
|
|
558
584
|
getMapboxApi() {
|
|
559
585
|
return this.mapbox;
|
|
560
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
|
+
*/
|
|
561
594
|
initMap() {
|
|
562
595
|
if (Trace.isEnabled()) {
|
|
563
596
|
CLog(CLogTypes.info, 'initMap() top with settings:', this.settings);
|
|
564
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.
|
|
565
603
|
if (!this.settings && !this.config.accessToken) {
|
|
566
604
|
if (Trace.isEnabled()) {
|
|
567
605
|
CLog(CLogTypes.info, 'initMap() no access token. Race condition on XML property evaluation?');
|
|
568
606
|
}
|
|
607
|
+
// If the user didn't specify an accessToken we don't want to loop forever
|
|
569
608
|
if (this.initCountHack > 50) {
|
|
570
609
|
return;
|
|
571
610
|
}
|
|
611
|
+
// FIXME: super ugly.
|
|
572
612
|
setTimeout(() => {
|
|
573
613
|
this.initMap();
|
|
574
614
|
}, 50);
|
|
@@ -586,13 +626,18 @@ export class MapboxView extends MapboxViewBase {
|
|
|
586
626
|
if (Trace.isEnabled()) {
|
|
587
627
|
CLog(CLogTypes.info, 'initMap(): after new Mapbox()');
|
|
588
628
|
}
|
|
629
|
+
// called in a setTimeout call at the bottom.
|
|
589
630
|
const drawMap = () => {
|
|
590
631
|
MGLAccountManager.accessToken = this.settings.accessToken;
|
|
591
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.
|
|
592
635
|
this.nativeMapView.delegate = this.delegate = MGLMapViewDelegateImpl.new().initWithCallback(() => {
|
|
593
636
|
if (Trace.isEnabled()) {
|
|
594
637
|
CLog(CLogTypes.info, 'initMap(): MLMapViewDeleteImpl onMapReady callback');
|
|
595
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.
|
|
596
641
|
this.mapbox.setMapboxViewInstance(this.nativeMapView);
|
|
597
642
|
this.mapbox.initEventHandlerShim(this.settings, this.nativeMapView);
|
|
598
643
|
this.notify({
|
|
@@ -601,6 +646,7 @@ export class MapboxView extends MapboxViewBase {
|
|
|
601
646
|
map: this,
|
|
602
647
|
ios: this.nativeMapView
|
|
603
648
|
});
|
|
649
|
+
// no permission required, but to align with Android we fire the event anyway
|
|
604
650
|
this.notify({
|
|
605
651
|
eventName: MapboxViewBase.locationPermissionGrantedEvent,
|
|
606
652
|
object: this,
|
|
@@ -608,9 +654,14 @@ export class MapboxView extends MapboxViewBase {
|
|
|
608
654
|
ios: this.nativeMapView
|
|
609
655
|
});
|
|
610
656
|
});
|
|
657
|
+
// this.delegate.setStyleLoadedCallback((map, style)=>{
|
|
658
|
+
// this.delegate.setStyleLoadedCallback(null);
|
|
659
|
+
// });
|
|
611
660
|
_setMapboxMapOptions(this.nativeMapView, this.settings);
|
|
612
661
|
_markers = [];
|
|
613
662
|
this.nativeView.addSubview(this.nativeMapView);
|
|
663
|
+
// this.notify will notify an event listener specified
|
|
664
|
+
// in the XML, in this case (onMoveBegin)="..."
|
|
614
665
|
this.mapbox.setOnMoveBeginListener((data) => {
|
|
615
666
|
if (Trace.isEnabled()) {
|
|
616
667
|
CLog(CLogTypes.info, 'initMap(): onMoveBegin listener');
|
|
@@ -645,9 +696,10 @@ export class MapboxView extends MapboxViewBase {
|
|
|
645
696
|
});
|
|
646
697
|
}, this.nativeMapView);
|
|
647
698
|
};
|
|
699
|
+
// draw the map after a timeout
|
|
648
700
|
setTimeout(drawMap, this.settings.delay ? this.settings.delay : 0);
|
|
649
701
|
}
|
|
650
|
-
}
|
|
702
|
+
} // end of initMap()
|
|
651
703
|
onLayout(left, top, right, bottom) {
|
|
652
704
|
super.onLayout(left, top, right, bottom);
|
|
653
705
|
if (this.nativeMapView) {
|
|
@@ -658,228 +710,38 @@ export class MapboxView extends MapboxViewBase {
|
|
|
658
710
|
NSUserDefaults.standardUserDefaults.setBoolForKey(false, 'MGLMapboxMetricsEnabled');
|
|
659
711
|
}
|
|
660
712
|
}
|
|
661
|
-
var CustomUserLocationAnnotationView = /** @class */ (function (_super) {
|
|
662
|
-
__extends(CustomUserLocationAnnotationView, _super);
|
|
663
|
-
function CustomUserLocationAnnotationView() {
|
|
664
|
-
return _super !== null && _super.apply(this, arguments) || this;
|
|
665
|
-
}
|
|
666
|
-
/**
|
|
667
|
-
* init
|
|
668
|
-
*
|
|
669
|
-
* @link https://docs.nativescript.org/core-concepts/ios-runtime/HelloWorld
|
|
670
|
-
*/
|
|
671
|
-
CustomUserLocationAnnotationView.prototype.init = function () {
|
|
672
|
-
this.size = 48;
|
|
673
|
-
_super.prototype.initWithFrame.call(this, CGRectMake(0, 0, this.size, this.size));
|
|
674
|
-
this.renderModeChanged = true;
|
|
675
|
-
this.userLocationRenderMode = 'NORMAL';
|
|
676
|
-
return this;
|
|
677
|
-
};
|
|
678
|
-
/**
|
|
679
|
-
* update
|
|
680
|
-
*
|
|
681
|
-
* The note from the Objective-C sample indicates this method may be called quite
|
|
682
|
-
* often so it needs to be kept lightweight.
|
|
683
|
-
*/
|
|
684
|
-
CustomUserLocationAnnotationView.prototype.update = function () {
|
|
685
|
-
if (CLLocationCoordinate2DIsValid(this.userLocation.coordinate)) {
|
|
686
|
-
// if it's the first time here, setup the layers that make up the
|
|
687
|
-
// location marker.
|
|
688
|
-
if (!this.dot) {
|
|
689
|
-
this.drawNonTrackingLocationMarker();
|
|
690
|
-
}
|
|
691
|
-
if (this.userLocationRenderMode === 'GPS') {
|
|
692
|
-
this.updateHeading();
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
};
|
|
696
|
-
/**
|
|
697
|
-
* Draw the GPS tracking arrow.
|
|
698
|
-
*
|
|
699
|
-
* @link https://docs.nativescript.org/ns-framework-modules/color
|
|
700
|
-
*/
|
|
701
|
-
CustomUserLocationAnnotationView.prototype.drawTrackingLocationMarker = function () {
|
|
702
|
-
if (Trace.isEnabled()) {
|
|
703
|
-
CLog(CLogTypes.info, 'CustomerUserLocationAnnotatinView::drawTrackingLocationMarker()');
|
|
704
|
-
}
|
|
705
|
-
this.drawTrackingDot();
|
|
706
|
-
this.drawArrow();
|
|
707
|
-
}; // end of setupLayers()
|
|
708
|
-
/**
|
|
709
|
-
* draw the non-tracking marker
|
|
710
|
-
*/
|
|
711
|
-
CustomUserLocationAnnotationView.prototype.drawNonTrackingLocationMarker = function () {
|
|
712
|
-
if (Trace.isEnabled()) {
|
|
713
|
-
CLog(CLogTypes.info, 'CustomerUserLocationAnnotatinView::drawNonTrackingLocationMarker()');
|
|
714
|
-
}
|
|
715
|
-
this.drawNonTrackingDot();
|
|
716
|
-
if (this.arrow) {
|
|
717
|
-
this.arrow.removeFromSuperlayer();
|
|
718
|
-
this.arrow = null;
|
|
719
|
-
}
|
|
720
|
-
};
|
|
721
|
-
/**
|
|
722
|
-
* draw the tracking dot.
|
|
723
|
-
*/
|
|
724
|
-
CustomUserLocationAnnotationView.prototype.drawTrackingDot = function () {
|
|
725
|
-
this.size = 48;
|
|
726
|
-
// we need to adjust the size of the bounds of the marker. The Tracking marker
|
|
727
|
-
// is larger than the non tracking marker.
|
|
728
|
-
this.bounds = CGRectMake(0, 0, this.size, this.size);
|
|
729
|
-
var dot = CALayer.layer();
|
|
730
|
-
dot.frame = this.bounds;
|
|
731
|
-
// user corner radius to turn the layer into a circle
|
|
732
|
-
dot.cornerRadius = this.size / 2;
|
|
733
|
-
dot.backgroundColor = this.tintColor.CGColor;
|
|
734
|
-
dot.borderWidth = 4;
|
|
735
|
-
var whiteColor = new Color('#FFFFFF');
|
|
736
|
-
dot.borderColor = whiteColor.ios.CGColor;
|
|
737
|
-
if (!this.dot) {
|
|
738
|
-
this.layer.addSublayer(dot);
|
|
739
|
-
}
|
|
740
|
-
else {
|
|
741
|
-
this.layer.replaceSublayerWith(this.dot, dot);
|
|
742
|
-
}
|
|
743
|
-
// QUESTION: does GC catch this?
|
|
744
|
-
this.dot = dot;
|
|
745
|
-
};
|
|
746
|
-
/**
|
|
747
|
-
* draw the non-tracking dot.
|
|
748
|
-
*/
|
|
749
|
-
CustomUserLocationAnnotationView.prototype.drawNonTrackingDot = function () {
|
|
750
|
-
this.size = 24;
|
|
751
|
-
this.bounds = CGRectMake(0, 0, this.size, this.size);
|
|
752
|
-
var dot = CALayer.layer();
|
|
753
|
-
dot.frame = this.bounds;
|
|
754
|
-
// user corner radius to turn the layer into a circle
|
|
755
|
-
dot.cornerRadius = this.size / 2;
|
|
756
|
-
dot.backgroundColor = this.tintColor.CGColor;
|
|
757
|
-
dot.borderWidth = 1;
|
|
758
|
-
var whiteColor = new Color('#FFFFFF');
|
|
759
|
-
dot.borderColor = whiteColor.ios.CGColor;
|
|
760
|
-
if (!this.dot) {
|
|
761
|
-
this.layer.addSublayer(dot);
|
|
762
|
-
}
|
|
763
|
-
else {
|
|
764
|
-
this.layer.replaceSublayerWith(this.dot, dot);
|
|
765
|
-
}
|
|
766
|
-
// QUESTION: does GC catch this?
|
|
767
|
-
this.dot = dot;
|
|
768
|
-
};
|
|
769
|
-
/**
|
|
770
|
-
* draw an arrow
|
|
771
|
-
*/
|
|
772
|
-
CustomUserLocationAnnotationView.prototype.drawArrow = function () {
|
|
773
|
-
var arrow = CAShapeLayer.layer();
|
|
774
|
-
arrow.path = this.arrowPath();
|
|
775
|
-
arrow.frame = CGRectMake(0, 0, this.size / 2, this.size / 2);
|
|
776
|
-
arrow.position = CGPointMake(CGRectGetMidX(this.dot.frame), CGRectGetMidY(this.dot.frame));
|
|
777
|
-
arrow.fillColor = this.dot.borderColor;
|
|
778
|
-
if (!this.arrow) {
|
|
779
|
-
this.layer.addSublayer(arrow);
|
|
780
|
-
}
|
|
781
|
-
else {
|
|
782
|
-
this.layer.replaceSublayerWith(this.arrow, arrow);
|
|
783
|
-
}
|
|
784
|
-
// QUESTION: Does GC catch this?
|
|
785
|
-
this.arrow = arrow;
|
|
786
|
-
};
|
|
787
|
-
/**
|
|
788
|
-
* update arrow heading
|
|
789
|
-
*
|
|
790
|
-
* @link https://docs.nativescript.org/core-concepts/ios-runtime/types/C-Functions
|
|
791
|
-
*/
|
|
792
|
-
CustomUserLocationAnnotationView.prototype.updateHeading = function () {
|
|
793
|
-
// just to avoid a possible race condition where the arrow isnt' drawn yet
|
|
794
|
-
if (!this.arrow) {
|
|
795
|
-
return;
|
|
796
|
-
}
|
|
797
|
-
if (typeof this.userLocation == 'undefined') {
|
|
798
|
-
return;
|
|
799
|
-
}
|
|
800
|
-
if (typeof this.userLocation.heading == 'undefined' || this.userLocation.heading === null) {
|
|
801
|
-
return;
|
|
802
|
-
}
|
|
803
|
-
if (typeof this.userLocation.heading.trueHeading == 'undefined' || this.userLocation.heading.trueHeading === null) {
|
|
804
|
-
return;
|
|
805
|
-
}
|
|
806
|
-
if (this.userLocation.heading.trueHeading > 0) {
|
|
807
|
-
this.arrow.hidden = false;
|
|
808
|
-
// get the difference between the map's current direction and the
|
|
809
|
-
// user's heading, then convert it from degrees to radians
|
|
810
|
-
//
|
|
811
|
-
// The original Objective-C example uses the inline C function MGLRadiansFromDegrees but because
|
|
812
|
-
// it's declared as inline it is not available for NativeScript. See linked article above.
|
|
813
|
-
// let rotation : number = MGLRadiansFromDegrees( this.mapView.direction - this.userLocation.heading.trueHeading );
|
|
814
|
-
var degrees = this.mapView.direction - this.userLocation.heading.trueHeading;
|
|
815
|
-
// in radians
|
|
816
|
-
var rotation = (degrees * Math.PI) / 180;
|
|
817
|
-
rotation = -rotation;
|
|
818
|
-
// if the difference would be perceptible, rotate the arrow.
|
|
819
|
-
if (fabs(rotation) > 0.01) {
|
|
820
|
-
// Disable implicit animations of this rotation, which reduces lag between updates
|
|
821
|
-
CATransaction.begin();
|
|
822
|
-
CATransaction.setDisableActions(true);
|
|
823
|
-
this.arrow.setAffineTransform(CGAffineTransformRotate(CGAffineTransformIdentity, rotation));
|
|
824
|
-
CATransaction.commit();
|
|
825
|
-
}
|
|
826
|
-
}
|
|
827
|
-
else {
|
|
828
|
-
this.arrow.hidden = true;
|
|
829
|
-
}
|
|
830
|
-
};
|
|
831
|
-
/**
|
|
832
|
-
* Calculate the vector path for an arrow
|
|
833
|
-
*/
|
|
834
|
-
CustomUserLocationAnnotationView.prototype.arrowPath = function () {
|
|
835
|
-
var max = this.size / 2;
|
|
836
|
-
var pad = 3;
|
|
837
|
-
var top = CGPointMake(max * 0.5, 0);
|
|
838
|
-
var left = CGPointMake(0 + pad, max - pad);
|
|
839
|
-
var right = CGPointMake(max - pad, max - pad);
|
|
840
|
-
var center = CGPointMake(max * 0.5, max * 0.6);
|
|
841
|
-
var bezierPath = UIBezierPath.bezierPath();
|
|
842
|
-
bezierPath.moveToPoint(top);
|
|
843
|
-
bezierPath.addLineToPoint(left);
|
|
844
|
-
bezierPath.addLineToPoint(center);
|
|
845
|
-
bezierPath.addLineToPoint(right);
|
|
846
|
-
bezierPath.addLineToPoint(top);
|
|
847
|
-
bezierPath.closePath();
|
|
848
|
-
return bezierPath.CGPath;
|
|
849
|
-
};
|
|
850
|
-
/**
|
|
851
|
-
* change Render mode
|
|
852
|
-
*
|
|
853
|
-
* @param {string} renderMode
|
|
854
|
-
*/
|
|
855
|
-
CustomUserLocationAnnotationView.prototype.changeUserLocationRenderMode = function (renderMode) {
|
|
856
|
-
if (Trace.isEnabled()) {
|
|
857
|
-
CLog(CLogTypes.info, "CustomUserLocationAnnotatinView::changeUserLocationRenderMode(): changing mode to '" + renderMode + "'");
|
|
858
|
-
}
|
|
859
|
-
this.userLocationRenderMode = renderMode;
|
|
860
|
-
if (renderMode === 'GPS') {
|
|
861
|
-
this.drawTrackingLocationMarker();
|
|
862
|
-
}
|
|
863
|
-
else {
|
|
864
|
-
this.drawNonTrackingLocationMarker();
|
|
865
|
-
}
|
|
866
|
-
};
|
|
867
|
-
return CustomUserLocationAnnotationView;
|
|
868
|
-
}(MGLUserLocationAnnotationView));
|
|
869
713
|
export class Mapbox extends MapboxCommon {
|
|
870
714
|
constructor() {
|
|
715
|
+
// reference to the native mapbox API
|
|
871
716
|
super(...arguments);
|
|
872
717
|
this.eventCallbacks = {};
|
|
873
718
|
}
|
|
719
|
+
/**
|
|
720
|
+
* set the mapboxViewInstance
|
|
721
|
+
*
|
|
722
|
+
* @see MapboxView::initMap();
|
|
723
|
+
*/
|
|
874
724
|
setMapboxViewInstance(mapboxViewInstance) {
|
|
875
725
|
this._mapboxViewInstance = mapboxViewInstance;
|
|
876
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
|
+
*/
|
|
877
734
|
initEventHandlerShim(settings, mapboxNativeViewInstance) {
|
|
878
735
|
if (Trace.isEnabled()) {
|
|
879
736
|
CLog(CLogTypes.info, 'Mapbox:initEventHandlerShim(): top');
|
|
880
737
|
}
|
|
881
738
|
this.setOnMapClickListener((point) => this.checkForClickEvent(point), mapboxNativeViewInstance);
|
|
882
739
|
}
|
|
740
|
+
/**
|
|
741
|
+
* register a map event handler
|
|
742
|
+
*
|
|
743
|
+
* The NativeScript ContentView base class as on() and off() methods.
|
|
744
|
+
*/
|
|
883
745
|
onMapEvent(eventName, id, callback, nativeMapView) {
|
|
884
746
|
if (typeof this.eventCallbacks[eventName] == 'undefined') {
|
|
885
747
|
this.eventCallbacks[eventName] = [];
|
|
@@ -895,6 +757,9 @@ export class Mapbox extends MapboxCommon {
|
|
|
895
757
|
}
|
|
896
758
|
this.eventCallbacks[eventName] = this.eventCallbacks[eventName].filter((entry) => entry.id !== id);
|
|
897
759
|
}
|
|
760
|
+
/**
|
|
761
|
+
* If click events registered and a feature found for the event, then fire listener.
|
|
762
|
+
*/
|
|
898
763
|
checkForClickEvent(point, nativeMap) {
|
|
899
764
|
if (Trace.isEnabled()) {
|
|
900
765
|
CLog(CLogTypes.info, 'Mapbox:checkForClickEvent(): got click event with point:', point);
|
|
@@ -936,6 +801,7 @@ export class Mapbox extends MapboxCommon {
|
|
|
936
801
|
point.coordinate = CLLocationCoordinate2DMake(lat, lng);
|
|
937
802
|
point.title = marker.title;
|
|
938
803
|
point.subtitle = marker.subtitle;
|
|
804
|
+
// needs to be done before adding to the map, otherwise the delegate method 'mapViewImageForAnnotation' can't use it
|
|
939
805
|
_markers.push(marker);
|
|
940
806
|
theMap.addAnnotation(point);
|
|
941
807
|
if (marker.selected) {
|
|
@@ -971,6 +837,11 @@ export class Mapbox extends MapboxCommon {
|
|
|
971
837
|
});
|
|
972
838
|
});
|
|
973
839
|
}
|
|
840
|
+
/**
|
|
841
|
+
* create an display the map
|
|
842
|
+
*
|
|
843
|
+
* @todo FIXME: This method is not called. See MapboxView::initMap().
|
|
844
|
+
*/
|
|
974
845
|
show(options) {
|
|
975
846
|
if (Trace.isEnabled()) {
|
|
976
847
|
CLog(CLogTypes.info, 'show(): top with options:', options);
|
|
@@ -978,10 +849,14 @@ export class Mapbox extends MapboxCommon {
|
|
|
978
849
|
return new Promise((resolve, reject) => {
|
|
979
850
|
try {
|
|
980
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
|
|
981
855
|
if (settings.accessToken === undefined) {
|
|
982
856
|
reject("Please set the 'accessToken' parameter");
|
|
983
857
|
return;
|
|
984
858
|
}
|
|
859
|
+
// if already added, make sure it's removed first
|
|
985
860
|
if (this._mapboxViewInstance) {
|
|
986
861
|
this._mapboxViewInstance.removeFromSuperview();
|
|
987
862
|
}
|
|
@@ -996,6 +871,7 @@ export class Mapbox extends MapboxCommon {
|
|
|
996
871
|
});
|
|
997
872
|
_markers = [];
|
|
998
873
|
this._addMarkers(settings.markers);
|
|
874
|
+
// wrapping in a little timeout since the map area tends to flash black a bit initially
|
|
999
875
|
setTimeout(() => {
|
|
1000
876
|
view.addSubview(this._mapboxViewInstance);
|
|
1001
877
|
}, 500);
|
|
@@ -1054,6 +930,9 @@ export class Mapbox extends MapboxCommon {
|
|
|
1054
930
|
resolve();
|
|
1055
931
|
});
|
|
1056
932
|
}
|
|
933
|
+
// ----------------------------------------
|
|
934
|
+
// Life Cycle Hooks - Required on Android
|
|
935
|
+
// ----------------------------------------
|
|
1057
936
|
onStart(nativeMap) {
|
|
1058
937
|
return Promise.resolve();
|
|
1059
938
|
}
|
|
@@ -1072,10 +951,15 @@ export class Mapbox extends MapboxCommon {
|
|
|
1072
951
|
onDestroy(nativeMap) {
|
|
1073
952
|
return Promise.resolve();
|
|
1074
953
|
}
|
|
954
|
+
/**
|
|
955
|
+
* explicitly set a map style
|
|
956
|
+
*/
|
|
1075
957
|
setMapStyle(style, nativeMap) {
|
|
1076
958
|
return new Promise((resolve, reject) => {
|
|
1077
959
|
try {
|
|
1078
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
|
|
1079
963
|
const delegate = theMap.delegate;
|
|
1080
964
|
delegate.setStyleLoadedCallback((mapView) => {
|
|
1081
965
|
if (Trace.isEnabled()) {
|
|
@@ -1184,6 +1068,7 @@ export class Mapbox extends MapboxCommon {
|
|
|
1184
1068
|
markersToRemove.push(marker.ios);
|
|
1185
1069
|
}
|
|
1186
1070
|
});
|
|
1071
|
+
// remove markers from cache
|
|
1187
1072
|
if (ids) {
|
|
1188
1073
|
_markers = _markers.filter((marker) => ids.indexOf(marker.id) < 0);
|
|
1189
1074
|
}
|
|
@@ -1328,28 +1213,36 @@ export class Mapbox extends MapboxCommon {
|
|
|
1328
1213
|
}
|
|
1329
1214
|
});
|
|
1330
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
|
+
*/
|
|
1331
1223
|
_stringToCameraMode(mode) {
|
|
1332
1224
|
switch (mode) {
|
|
1333
|
-
case
|
|
1334
|
-
return 0
|
|
1335
|
-
case
|
|
1336
|
-
console.log(
|
|
1337
|
-
return 0
|
|
1338
|
-
case
|
|
1339
|
-
console.log(
|
|
1340
|
-
return 0
|
|
1341
|
-
case
|
|
1342
|
-
return 1
|
|
1343
|
-
case
|
|
1344
|
-
return 2
|
|
1345
|
-
case
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
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 */;
|
|
1349
1242
|
default:
|
|
1350
1243
|
console.log(`_stringToCameraMode: invalid cameraMode: ${mode}`);
|
|
1351
1244
|
}
|
|
1352
|
-
return 0
|
|
1245
|
+
return 0 /* MGLUserTrackingMode.None */;
|
|
1353
1246
|
}
|
|
1354
1247
|
_stringToRenderMode(mode) {
|
|
1355
1248
|
let renderMode;
|
|
@@ -1364,16 +1257,32 @@ export class Mapbox extends MapboxCommon {
|
|
|
1364
1257
|
}
|
|
1365
1258
|
_convertCameraMode(mode) {
|
|
1366
1259
|
switch (mode) {
|
|
1367
|
-
case 0
|
|
1368
|
-
return
|
|
1369
|
-
case 1
|
|
1370
|
-
return
|
|
1371
|
-
case 2
|
|
1372
|
-
return
|
|
1373
|
-
case 3
|
|
1374
|
-
return
|
|
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';
|
|
1375
1268
|
}
|
|
1376
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
|
+
*/
|
|
1377
1286
|
showUserLocationMarker(options, nativeMap) {
|
|
1378
1287
|
return new Promise((resolve, reject) => {
|
|
1379
1288
|
try {
|
|
@@ -1382,7 +1291,10 @@ export class Mapbox extends MapboxCommon {
|
|
|
1382
1291
|
theMap.userTrackingMode = this._stringToCameraMode(options.cameraMode);
|
|
1383
1292
|
theMap.showsUserHeadingIndicator = true;
|
|
1384
1293
|
this.userLocationRenderMode = this._stringToRenderMode(options.renderMode);
|
|
1294
|
+
// the "delegate" needs to know the modes
|
|
1385
1295
|
const delegate = theMap.delegate;
|
|
1296
|
+
// tell the delegate to tell the CustomerLocationAnnotationView to change the
|
|
1297
|
+
// appearance of the marker.
|
|
1386
1298
|
delegate.changeUserLocationRenderMode(this.userLocationRenderMode);
|
|
1387
1299
|
if (typeof options.clickListener != 'undefined') {
|
|
1388
1300
|
delegate.setUserLocationClickListener(options.clickListener);
|
|
@@ -1397,6 +1309,11 @@ export class Mapbox extends MapboxCommon {
|
|
|
1397
1309
|
}
|
|
1398
1310
|
});
|
|
1399
1311
|
}
|
|
1312
|
+
/**
|
|
1313
|
+
* hide the user location marker
|
|
1314
|
+
*
|
|
1315
|
+
* @todo unfinished
|
|
1316
|
+
*/
|
|
1400
1317
|
hideUserLocationMarker(nativeMap) {
|
|
1401
1318
|
return new Promise((resolve, reject) => {
|
|
1402
1319
|
try {
|
|
@@ -1410,6 +1327,15 @@ export class Mapbox extends MapboxCommon {
|
|
|
1410
1327
|
}
|
|
1411
1328
|
});
|
|
1412
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
|
+
*/
|
|
1413
1339
|
changeUserLocationMarkerMode(renderModeString, cameraModeString, nativeMap) {
|
|
1414
1340
|
return new Promise((resolve, reject) => {
|
|
1415
1341
|
try {
|
|
@@ -1430,6 +1356,9 @@ export class Mapbox extends MapboxCommon {
|
|
|
1430
1356
|
}
|
|
1431
1357
|
});
|
|
1432
1358
|
}
|
|
1359
|
+
/**
|
|
1360
|
+
* ignored on iOS
|
|
1361
|
+
*/
|
|
1433
1362
|
forceUserLocationUpdate(location, nativeMap) { }
|
|
1434
1363
|
queryRenderedFeatures(options, nativeMap) {
|
|
1435
1364
|
return new Promise((resolve, reject) => {
|
|
@@ -1504,6 +1433,9 @@ export class Mapbox extends MapboxCommon {
|
|
|
1504
1433
|
}
|
|
1505
1434
|
});
|
|
1506
1435
|
}
|
|
1436
|
+
/**
|
|
1437
|
+
* @deprecated
|
|
1438
|
+
*/
|
|
1507
1439
|
addPolygon(options, nativeMap) {
|
|
1508
1440
|
return new Promise((resolve, reject) => {
|
|
1509
1441
|
const theMap = nativeMap || this._mapboxViewInstance;
|
|
@@ -1566,6 +1498,7 @@ export class Mapbox extends MapboxCommon {
|
|
|
1566
1498
|
const coordinateArray = [];
|
|
1567
1499
|
points.forEach((point) => coordinateArray.push([point.lng, point.lat]));
|
|
1568
1500
|
const polylineID = 'polyline_' + (options.id || new Date().getTime());
|
|
1501
|
+
// this would otherwise crash the app
|
|
1569
1502
|
if (theMap.style.sourceWithIdentifier(polylineID)) {
|
|
1570
1503
|
reject("Remove the polyline with this id first with 'removePolylines': " + polylineID);
|
|
1571
1504
|
return;
|
|
@@ -1591,6 +1524,7 @@ export class Mapbox extends MapboxCommon {
|
|
|
1591
1524
|
if (layer !== null) {
|
|
1592
1525
|
theMap.style.removeLayer(layer);
|
|
1593
1526
|
}
|
|
1527
|
+
// polygons may have a 'stroke' layer
|
|
1594
1528
|
layer = theMap.style.layerWithIdentifier(id + '_stroke');
|
|
1595
1529
|
if (layer !== null) {
|
|
1596
1530
|
theMap.style.removeLayer(layer);
|
|
@@ -1620,6 +1554,7 @@ export class Mapbox extends MapboxCommon {
|
|
|
1620
1554
|
let cam;
|
|
1621
1555
|
if (options.bounds) {
|
|
1622
1556
|
const padding = options.padding || 0;
|
|
1557
|
+
// support defined padding
|
|
1623
1558
|
const insets = {
|
|
1624
1559
|
top: padding,
|
|
1625
1560
|
left: padding,
|
|
@@ -1667,6 +1602,10 @@ export class Mapbox extends MapboxCommon {
|
|
|
1667
1602
|
}
|
|
1668
1603
|
});
|
|
1669
1604
|
}
|
|
1605
|
+
/**
|
|
1606
|
+
* sets a map level click listener
|
|
1607
|
+
*
|
|
1608
|
+
*/
|
|
1670
1609
|
setOnMapClickListener(listener, nativeMap) {
|
|
1671
1610
|
return new Promise((resolve, reject) => {
|
|
1672
1611
|
try {
|
|
@@ -1680,7 +1619,8 @@ export class Mapbox extends MapboxCommon {
|
|
|
1680
1619
|
for (let i = 0; i < theMap.gestureRecognizers.count; i++) {
|
|
1681
1620
|
const recognizer = theMap.gestureRecognizers.objectAtIndex(i);
|
|
1682
1621
|
if (recognizer instanceof UITapGestureRecognizer) {
|
|
1683
|
-
|
|
1622
|
+
recognizer.addTargetAction(theMap['mapTapHandler'], 'tap');
|
|
1623
|
+
break;
|
|
1684
1624
|
}
|
|
1685
1625
|
}
|
|
1686
1626
|
theMap.addGestureRecognizer(tapGestureRecognizer);
|
|
@@ -1702,8 +1642,10 @@ export class Mapbox extends MapboxCommon {
|
|
|
1702
1642
|
reject('No map has been loaded');
|
|
1703
1643
|
return;
|
|
1704
1644
|
}
|
|
1645
|
+
// adding the longPress handler to the map oject so it's not GC'd
|
|
1705
1646
|
theMap['mapLongPressHandler'] = MapLongPressHandlerImpl.initWithOwnerAndListenerForMap(new WeakRef(this), listener, theMap);
|
|
1706
1647
|
const longPressGestureRecognizer = UILongPressGestureRecognizer.alloc().initWithTargetAction(theMap['mapLongPressHandler'], 'longPress');
|
|
1648
|
+
// cancel the default longPress handler
|
|
1707
1649
|
for (let i = 0; i < theMap.gestureRecognizers.count; i++) {
|
|
1708
1650
|
const recognizer = theMap.gestureRecognizers.objectAtIndex(i);
|
|
1709
1651
|
if (recognizer instanceof UILongPressGestureRecognizer) {
|
|
@@ -1729,12 +1671,14 @@ export class Mapbox extends MapboxCommon {
|
|
|
1729
1671
|
reject('No map has been loaded');
|
|
1730
1672
|
return;
|
|
1731
1673
|
}
|
|
1674
|
+
// adding the pan handler to the map oject so it's not GC'd
|
|
1732
1675
|
if (theMap['mapPanHandler'] === undefined) {
|
|
1733
|
-
theMap['mapPanHandler'] = MapPanHandlerImpl.initWithOwnerAndListenerForMap(new WeakRef(this), listener, 2
|
|
1676
|
+
theMap['mapPanHandler'] = MapPanHandlerImpl.initWithOwnerAndListenerForMap(new WeakRef(this), listener, 2 /* UIGestureRecognizerState.Changed */, theMap);
|
|
1734
1677
|
}
|
|
1735
1678
|
else {
|
|
1736
|
-
theMap['mapPanHandler'].addListener(2
|
|
1679
|
+
theMap['mapPanHandler'].addListener(2 /* UIGestureRecognizerState.Changed */, listener);
|
|
1737
1680
|
}
|
|
1681
|
+
// there's already a pan recognizer, so find it and attach a target action
|
|
1738
1682
|
for (let i = 0; i < theMap.gestureRecognizers.count; i++) {
|
|
1739
1683
|
const recognizer = theMap.gestureRecognizers.objectAtIndex(i);
|
|
1740
1684
|
if (recognizer instanceof UIPanGestureRecognizer) {
|
|
@@ -1752,6 +1696,12 @@ export class Mapbox extends MapboxCommon {
|
|
|
1752
1696
|
}
|
|
1753
1697
|
});
|
|
1754
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
|
+
*/
|
|
1755
1705
|
setOnMoveBeginListener(listener, nativeMap) {
|
|
1756
1706
|
return new Promise((resolve, reject) => {
|
|
1757
1707
|
try {
|
|
@@ -1760,12 +1710,14 @@ export class Mapbox extends MapboxCommon {
|
|
|
1760
1710
|
reject('No map has been loaded');
|
|
1761
1711
|
return;
|
|
1762
1712
|
}
|
|
1713
|
+
// adding the pan handler to the map oject so it's not GC'd
|
|
1763
1714
|
if (theMap['mapPanHandler'] === undefined) {
|
|
1764
|
-
theMap['mapPanHandler'] = MapPanHandlerImpl.initWithOwnerAndListenerForMap(new WeakRef(this), listener, 1
|
|
1715
|
+
theMap['mapPanHandler'] = MapPanHandlerImpl.initWithOwnerAndListenerForMap(new WeakRef(this), listener, 1 /* UIGestureRecognizerState.Began */, theMap);
|
|
1765
1716
|
}
|
|
1766
1717
|
else {
|
|
1767
|
-
theMap['mapPanHandler'].addListener(1
|
|
1718
|
+
theMap['mapPanHandler'].addListener(1 /* UIGestureRecognizerState.Began */, listener);
|
|
1768
1719
|
}
|
|
1720
|
+
// there's already a pan recognizer, so find it and attach a target action
|
|
1769
1721
|
for (let i = 0; i < theMap.gestureRecognizers.count; i++) {
|
|
1770
1722
|
const recognizer = theMap.gestureRecognizers.objectAtIndex(i);
|
|
1771
1723
|
if (recognizer instanceof UIPanGestureRecognizer) {
|
|
@@ -1792,11 +1744,12 @@ export class Mapbox extends MapboxCommon {
|
|
|
1792
1744
|
return;
|
|
1793
1745
|
}
|
|
1794
1746
|
if (theMap['mapPanHandler'] === undefined) {
|
|
1795
|
-
theMap['mapPanHandler'] = MapPanHandlerImpl.initWithOwnerAndListenerForMap(new WeakRef(this), listener, 3
|
|
1747
|
+
theMap['mapPanHandler'] = MapPanHandlerImpl.initWithOwnerAndListenerForMap(new WeakRef(this), listener, 3 /* UIGestureRecognizerState.Ended */, theMap);
|
|
1796
1748
|
}
|
|
1797
1749
|
else {
|
|
1798
|
-
theMap['mapPanHandler'].addListener(3
|
|
1750
|
+
theMap['mapPanHandler'].addListener(3 /* UIGestureRecognizerState.Ended */, listener);
|
|
1799
1751
|
}
|
|
1752
|
+
// there's already a pan recognizer, so find it and attach a target action
|
|
1800
1753
|
for (let i = 0; i < theMap.gestureRecognizers.count; i++) {
|
|
1801
1754
|
const recognizer = theMap.gestureRecognizers.objectAtIndex(i);
|
|
1802
1755
|
if (recognizer instanceof UIPanGestureRecognizer) {
|
|
@@ -1815,6 +1768,7 @@ export class Mapbox extends MapboxCommon {
|
|
|
1815
1768
|
});
|
|
1816
1769
|
}
|
|
1817
1770
|
setOnFlingListener(listener, nativeMap) {
|
|
1771
|
+
// there's no swipe event we can bind to
|
|
1818
1772
|
return Promise.reject("'setOnFlingListener' is not supported on iOS");
|
|
1819
1773
|
}
|
|
1820
1774
|
async setOnCameraMoveListener(listener, nativeMap) {
|
|
@@ -1879,6 +1833,7 @@ export class Mapbox extends MapboxCommon {
|
|
|
1879
1833
|
ne: CLLocationCoordinate2DMake(options.bounds.north, options.bounds.east)
|
|
1880
1834
|
};
|
|
1881
1835
|
const animated = options.animated === undefined || options.animated;
|
|
1836
|
+
// support defined padding
|
|
1882
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 };
|
|
1883
1838
|
theMap.setVisibleCoordinateBoundsEdgePaddingAnimated(bounds, padding, animated);
|
|
1884
1839
|
resolve();
|
|
@@ -1905,6 +1860,7 @@ export class Mapbox extends MapboxCommon {
|
|
|
1905
1860
|
if (options.accessToken) {
|
|
1906
1861
|
MGLAccountManager.accessToken = options.accessToken;
|
|
1907
1862
|
}
|
|
1863
|
+
// TODO there's more observers, see https://www.mapbox.com/ios-sdk/examples/offline-pack/
|
|
1908
1864
|
if (options.onProgress) {
|
|
1909
1865
|
_addObserver(MGLOfflinePackProgressChangedNotification, (notification) => {
|
|
1910
1866
|
const offlinePack = notification.object;
|
|
@@ -1938,13 +1894,17 @@ export class Mapbox extends MapboxCommon {
|
|
|
1938
1894
|
const maximumCount = notification.userInfo[MGLOfflinePackUserInfoKeyMaximumCount];
|
|
1939
1895
|
console.log(`Offline region '${userInfo.objectForKey('name')}' reached the tile limit of ${maximumCount}`);
|
|
1940
1896
|
});
|
|
1897
|
+
// Store some data for identification purposes alongside the downloaded resources.
|
|
1941
1898
|
const userInfo = { name: options.name };
|
|
1942
1899
|
const context = NSKeyedArchiver.archivedDataWithRootObject(userInfo);
|
|
1900
|
+
// Create and register an offline pack with the shared offline storage object.
|
|
1943
1901
|
MGLOfflineStorage.sharedOfflineStorage.addPackForRegionWithContextCompletionHandler(region, context, (pack, error) => {
|
|
1944
1902
|
if (error) {
|
|
1903
|
+
// The pack couldn’t be created for some reason.
|
|
1945
1904
|
reject(error.localizedFailureReason);
|
|
1946
1905
|
}
|
|
1947
1906
|
else {
|
|
1907
|
+
// Start downloading.
|
|
1948
1908
|
pack.resume();
|
|
1949
1909
|
}
|
|
1950
1910
|
});
|
|
@@ -2010,12 +1970,15 @@ export class Mapbox extends MapboxCommon {
|
|
|
2010
1970
|
found = true;
|
|
2011
1971
|
MGLOfflineStorage.sharedOfflineStorage.removePackWithCompletionHandler(pack, (error) => {
|
|
2012
1972
|
if (error) {
|
|
1973
|
+
// The pack couldn’t be deleted for some reason.
|
|
2013
1974
|
reject(error.localizedFailureReason);
|
|
2014
1975
|
}
|
|
2015
1976
|
else {
|
|
2016
1977
|
resolve();
|
|
1978
|
+
// don't return, see note below
|
|
2017
1979
|
}
|
|
2018
1980
|
});
|
|
1981
|
+
// don't break the loop as there may be multiple packs with the same name
|
|
2019
1982
|
}
|
|
2020
1983
|
}
|
|
2021
1984
|
if (!found) {
|
|
@@ -2048,6 +2011,10 @@ export class Mapbox extends MapboxCommon {
|
|
|
2048
2011
|
}
|
|
2049
2012
|
});
|
|
2050
2013
|
}
|
|
2014
|
+
/**
|
|
2015
|
+
* update a geojson source
|
|
2016
|
+
*
|
|
2017
|
+
*/
|
|
2051
2018
|
updateSource(id, options, nativeMap) {
|
|
2052
2019
|
return new Promise((resolve, reject) => {
|
|
2053
2020
|
try {
|
|
@@ -2082,6 +2049,14 @@ export class Mapbox extends MapboxCommon {
|
|
|
2082
2049
|
}
|
|
2083
2050
|
});
|
|
2084
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
|
+
*/
|
|
2085
2060
|
addSource(id, options, nativeMap) {
|
|
2086
2061
|
return new Promise((resolve, reject) => {
|
|
2087
2062
|
try {
|
|
@@ -2111,10 +2086,10 @@ export class Mapbox extends MapboxCommon {
|
|
|
2111
2086
|
if (options.scheme) {
|
|
2112
2087
|
switch (options.scheme) {
|
|
2113
2088
|
case 'xyz':
|
|
2114
|
-
sourceOptions[MGLTileSourceOptionTileCoordinateSystem] = 0
|
|
2089
|
+
sourceOptions[MGLTileSourceOptionTileCoordinateSystem] = 0 /* MGLTileCoordinateSystem.XYZ */;
|
|
2115
2090
|
break;
|
|
2116
2091
|
case 'tms':
|
|
2117
|
-
sourceOptions[MGLTileSourceOptionTileCoordinateSystem] = 1
|
|
2092
|
+
sourceOptions[MGLTileSourceOptionTileCoordinateSystem] = 1 /* MGLTileCoordinateSystem.TMS */;
|
|
2118
2093
|
break;
|
|
2119
2094
|
default:
|
|
2120
2095
|
throw new Error('Unknown raster tile scheme.');
|
|
@@ -2158,6 +2133,7 @@ export class Mapbox extends MapboxCommon {
|
|
|
2158
2133
|
if (options.cluster.properties) {
|
|
2159
2134
|
const clusterProperties = {};
|
|
2160
2135
|
for (const property of Object.keys(options.cluster.properties)) {
|
|
2136
|
+
// eslint-disable-next-line prefer-const
|
|
2161
2137
|
let [operator, operand] = options.cluster.properties[property];
|
|
2162
2138
|
if (!Array.isArray(operator)) {
|
|
2163
2139
|
operator = [operator];
|
|
@@ -2183,10 +2159,10 @@ export class Mapbox extends MapboxCommon {
|
|
|
2183
2159
|
if (options.scheme) {
|
|
2184
2160
|
switch (options.scheme || 'xyz') {
|
|
2185
2161
|
case 'xyz':
|
|
2186
|
-
sourceOptions[MGLTileSourceOptionTileCoordinateSystem] = 0
|
|
2162
|
+
sourceOptions[MGLTileSourceOptionTileCoordinateSystem] = 0 /* MGLTileCoordinateSystem.XYZ */;
|
|
2187
2163
|
break;
|
|
2188
2164
|
case 'tms':
|
|
2189
|
-
sourceOptions[MGLTileSourceOptionTileCoordinateSystem] = 1
|
|
2165
|
+
sourceOptions[MGLTileSourceOptionTileCoordinateSystem] = 1 /* MGLTileCoordinateSystem.TMS */;
|
|
2190
2166
|
break;
|
|
2191
2167
|
default:
|
|
2192
2168
|
throw new Error('Unknown raster tile scheme.');
|
|
@@ -2224,6 +2200,9 @@ export class Mapbox extends MapboxCommon {
|
|
|
2224
2200
|
}
|
|
2225
2201
|
});
|
|
2226
2202
|
}
|
|
2203
|
+
/**
|
|
2204
|
+
* remove source by id
|
|
2205
|
+
*/
|
|
2227
2206
|
removeSource(id, nativeMap) {
|
|
2228
2207
|
return new Promise((resolve, reject) => {
|
|
2229
2208
|
try {
|
|
@@ -2248,6 +2227,24 @@ export class Mapbox extends MapboxCommon {
|
|
|
2248
2227
|
}
|
|
2249
2228
|
});
|
|
2250
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
|
+
*/
|
|
2251
2248
|
async addLayer(style, belowLayerId, nativeMapView) {
|
|
2252
2249
|
const theMap = nativeMapView || this._mapboxViewInstance;
|
|
2253
2250
|
let source = null;
|
|
@@ -2268,6 +2265,13 @@ export class Mapbox extends MapboxCommon {
|
|
|
2268
2265
|
}
|
|
2269
2266
|
theMap.style.addLayer(layer.getNativeInstance());
|
|
2270
2267
|
}
|
|
2268
|
+
/**
|
|
2269
|
+
* remove layer by ID
|
|
2270
|
+
*
|
|
2271
|
+
* Removes a layer given a layer id
|
|
2272
|
+
*
|
|
2273
|
+
* @param {string} id
|
|
2274
|
+
*/
|
|
2271
2275
|
async removeLayer(id, nativeMapViewInstance) {
|
|
2272
2276
|
const theMap = nativeMapViewInstance || this._mapboxViewInstance;
|
|
2273
2277
|
if (Trace.isEnabled()) {
|
|
@@ -2285,6 +2289,21 @@ export class Mapbox extends MapboxCommon {
|
|
|
2285
2289
|
CLog(CLogTypes.info, 'Mapbox:removeLayer(): after removing layer ' + id);
|
|
2286
2290
|
}
|
|
2287
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
|
+
*/
|
|
2288
2307
|
async addLinePoint(id, lnglat, sourceId, nativeMapView) {
|
|
2289
2308
|
const theMap = nativeMapView || this._mapboxViewInstance;
|
|
2290
2309
|
const sId = !!sourceId ? sourceId : id + '_source';
|
|
@@ -2310,6 +2329,72 @@ export class Mapbox extends MapboxCommon {
|
|
|
2310
2329
|
}
|
|
2311
2330
|
addGeoJsonClustered(options, nativeMapViewInstance) {
|
|
2312
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
|
+
// });
|
|
2313
2398
|
}
|
|
2314
2399
|
trackUser(options, nativeMap) {
|
|
2315
2400
|
return new Promise((resolve, reject) => {
|
|
@@ -2343,7 +2428,7 @@ export class Mapbox extends MapboxCommon {
|
|
|
2343
2428
|
return;
|
|
2344
2429
|
}
|
|
2345
2430
|
const layer = theMap.style.layerWithIdentifier(name);
|
|
2346
|
-
resolve(new Layer(layer));
|
|
2431
|
+
resolve(layer ? new Layer(layer) : null);
|
|
2347
2432
|
}
|
|
2348
2433
|
catch (ex) {
|
|
2349
2434
|
if (Trace.isEnabled()) {
|
|
@@ -2394,9 +2479,9 @@ export class Mapbox extends MapboxCommon {
|
|
|
2394
2479
|
};
|
|
2395
2480
|
}
|
|
2396
2481
|
getUserLocationCameraMode(nativeMap) {
|
|
2397
|
-
|
|
2482
|
+
const theMap = nativeMap || this._mapboxViewInstance;
|
|
2398
2483
|
if (!theMap) {
|
|
2399
|
-
return
|
|
2484
|
+
return 'NONE';
|
|
2400
2485
|
}
|
|
2401
2486
|
return this._convertCameraMode(theMap.userTrackingMode);
|
|
2402
2487
|
}
|
|
@@ -2407,6 +2492,7 @@ function _downloadImage(marker) {
|
|
|
2407
2492
|
if (Trace.isEnabled()) {
|
|
2408
2493
|
CLog(CLogTypes.info, '>> _downloadImage');
|
|
2409
2494
|
}
|
|
2495
|
+
// to cache..
|
|
2410
2496
|
if (_markerIconDownloadCache[marker.icon]) {
|
|
2411
2497
|
marker.iconDownloaded = _markerIconDownloadCache[marker.icon];
|
|
2412
2498
|
if (Trace.isEnabled()) {
|
|
@@ -2415,6 +2501,7 @@ function _downloadImage(marker) {
|
|
|
2415
2501
|
resolve(marker);
|
|
2416
2502
|
return;
|
|
2417
2503
|
}
|
|
2504
|
+
// ..or not to cache
|
|
2418
2505
|
Http.getImage(marker.icon).then((output) => {
|
|
2419
2506
|
marker.iconDownloaded = output.ios;
|
|
2420
2507
|
_markerIconDownloadCache[marker.icon] = marker.iconDownloaded;
|