@nativescript-community/ui-mapbox 6.2.9 → 6.2.13
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 +36 -0
- package/README.md +199 -99
- package/{mapbox.common.d.ts → common.d.ts} +20 -3
- package/{mapbox.common.js → common.js} +18 -1
- package/{filter/filter-parser.android.d.ts → expression/expression-parser.android.d.ts} +1 -1
- package/{filter/filter-parser.android.js → expression/expression-parser.android.js} +2 -2
- package/expression/expression-parser.d.ts +4 -0
- package/{filter/filter-parser.ios.d.ts → expression/expression-parser.ios.d.ts} +1 -1
- package/{filter/filter-parser.ios.js → expression/expression-parser.ios.js} +2 -2
- package/{mapbox.android.d.ts → index.android.d.ts} +5 -14
- package/{mapbox.android.js → index.android.js} +142 -66
- package/index.d.ts +98 -6
- package/{mapbox.ios.d.ts → index.ios.d.ts} +3 -30
- package/{mapbox.ios.js → index.ios.js} +1300 -1250
- package/layers/layer-factory.android.d.ts +14 -1
- package/layers/layer-factory.android.js +33 -2
- package/layers/layer-factory.d.ts +15 -1
- package/layers/layer-factory.ios.d.ts +14 -1
- package/layers/layer-factory.ios.js +42 -2
- package/layers/parser/property-parser.android.d.ts +1 -0
- package/layers/parser/property-parser.android.js +25 -0
- package/layers/parser/property-parser.d.ts +4 -0
- package/layers/parser/property-parser.ios.d.ts +1 -0
- package/layers/parser/property-parser.ios.js +21 -0
- package/package.json +55 -49
- package/platforms/android/include.gradle +4 -1
- package/platforms/android/ui_mapbox.aar +0 -0
- package/platforms/ios/Podfile +2 -2
- package/typings/Mapbox.ios.d.ts +2 -0
- package/LICENSE +0 -21
|
@@ -1,10 +1,416 @@
|
|
|
1
|
-
import { Color, File, ImageSource, Trace, knownFolders, path } from '@nativescript/core';
|
|
2
|
-
import { CLog, CLogTypes, MapStyle, MapboxCommon,
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { Color, File, Http, ImageSource, Trace, Utils, knownFolders, path } from '@nativescript/core';
|
|
2
|
+
import { CLog, CLogTypes, MapStyle, MapboxCommon, MapboxViewBase, telemetryProperty } from './common';
|
|
3
|
+
import { Layer, LayerFactory } from './layers/layer-factory';
|
|
4
|
+
import { ExpressionParser } from './expression/expression-parser';
|
|
5
|
+
var MGLMapViewDelegateImpl = /** @class */ (function (_super) {
|
|
6
|
+
__extends(MGLMapViewDelegateImpl, _super);
|
|
7
|
+
function MGLMapViewDelegateImpl() {
|
|
8
|
+
return _super !== null && _super.apply(this, arguments) || this;
|
|
9
|
+
}
|
|
10
|
+
MGLMapViewDelegateImpl.new = function () {
|
|
11
|
+
return _super.new.call(this);
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* initialize with the mapReady callback
|
|
15
|
+
*/
|
|
16
|
+
MGLMapViewDelegateImpl.prototype.initWithCallback = function (mapLoadedCallback) {
|
|
17
|
+
if (Trace.isEnabled()) {
|
|
18
|
+
CLog(CLogTypes.info, 'MGLMapViewDelegateImpl::initWithCallback()');
|
|
19
|
+
}
|
|
20
|
+
this.mapLoadedCallback = mapLoadedCallback;
|
|
21
|
+
return this;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* set a reference to the mapboxAPI instance
|
|
25
|
+
*/
|
|
26
|
+
MGLMapViewDelegateImpl.prototype.setMapboxApi = function (api) {
|
|
27
|
+
this.mapboxApi = api;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* set the user location click listener callback
|
|
31
|
+
*/
|
|
32
|
+
MGLMapViewDelegateImpl.prototype.setUserLocationClickListener = function (callback) {
|
|
33
|
+
this.userLocationClickListener = callback;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* set the user location click listener callback
|
|
37
|
+
*/
|
|
38
|
+
MGLMapViewDelegateImpl.prototype.setUserLocationChangedistener = function (callback) {
|
|
39
|
+
this.userLocationChangedListener = callback;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* set user location marker modes
|
|
43
|
+
*/
|
|
44
|
+
MGLMapViewDelegateImpl.prototype.changeUserLocationRenderMode = function (userLocationRenderMode) {
|
|
45
|
+
this.userLocationAnnotationView.changeUserLocationRenderMode(userLocationRenderMode);
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* set the camera changd listener callback
|
|
49
|
+
*/
|
|
50
|
+
MGLMapViewDelegateImpl.prototype.setCameraChangedListener = function (callback) {
|
|
51
|
+
this.cameraChangedListener = callback;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* set the camera idled listener callback
|
|
55
|
+
*/
|
|
56
|
+
MGLMapViewDelegateImpl.prototype.setCameraIdledListener = function (callback) {
|
|
57
|
+
this.cameraIdledListener = callback;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* set style loaded callback.
|
|
61
|
+
*
|
|
62
|
+
* set an optional callback to be invoked when a style set with
|
|
63
|
+
* setMapStyle() is finished loading
|
|
64
|
+
*
|
|
65
|
+
* @param {function} callback function with loaded style as parameter.
|
|
66
|
+
*
|
|
67
|
+
* @see Mapbox:setMapStyle()
|
|
68
|
+
*/
|
|
69
|
+
MGLMapViewDelegateImpl.prototype.setStyleLoadedCallback = function (callback) {
|
|
70
|
+
this.styleLoadedCallback = callback;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* map ready callback
|
|
74
|
+
*/
|
|
75
|
+
MGLMapViewDelegateImpl.prototype.mapViewDidFinishLoadingMap = function (mapView) {
|
|
76
|
+
if (Trace.isEnabled()) {
|
|
77
|
+
CLog(CLogTypes.info, 'MGLMapViewDelegateImpl:mapViewDidFinishLoadingMap(): top');
|
|
78
|
+
}
|
|
79
|
+
if (this.mapLoadedCallback !== undefined) {
|
|
80
|
+
this.mapLoadedCallback(mapView);
|
|
81
|
+
// this should be fired only once, but it's also fired when the style changes, so just remove the callback
|
|
82
|
+
this.mapLoadedCallback = undefined;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
MGLMapViewDelegateImpl.prototype.mapViewDidFinishRenderingMapFullyRendered = function (mapView, fullyRendered) {
|
|
86
|
+
if (Trace.isEnabled()) {
|
|
87
|
+
CLog(CLogTypes.info, 'MGLMapViewDelegateImpl:mapViewDidFinishRenderingMapFullyRendered(): rendered is:', fullyRendered);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Callback when the style has been loaded.
|
|
92
|
+
*
|
|
93
|
+
* Based on my testing, it looks like this callback is invoked multiple times.
|
|
94
|
+
*
|
|
95
|
+
* @see Mapbox:setMapStyle()
|
|
96
|
+
*
|
|
97
|
+
* @link https://mapbox.github.io/mapbox-gl-native/macos/0.3.0/Protocols/MGLMapViewDelegate.html#/c:objc(pl)MGLMapViewDelegate(im)mapView:didFinishLoadingStyle:
|
|
98
|
+
*/
|
|
99
|
+
MGLMapViewDelegateImpl.prototype.mapViewDidFinishLoadingStyle = function (mapView, style) {
|
|
100
|
+
if (Trace.isEnabled()) {
|
|
101
|
+
CLog(CLogTypes.info, 'MGLMapViewDelegateImpl:mapViewDidFinishLoadingStyle(): callback called.');
|
|
102
|
+
}
|
|
103
|
+
if (this.styleLoadedCallback !== undefined) {
|
|
104
|
+
this.styleLoadedCallback(mapView, style);
|
|
105
|
+
// to avoid multiple calls. This is only invoked from setMapStyle().
|
|
106
|
+
this.styleLoadedCallback = undefined;
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* disable the default user location callout
|
|
111
|
+
*
|
|
112
|
+
* This took forever to find. The default iOS click handler for the user location
|
|
113
|
+
* marker is about useless. It just displays "You Are Here". The examples do not
|
|
114
|
+
* show how to disable it.
|
|
115
|
+
*/
|
|
116
|
+
MGLMapViewDelegateImpl.prototype.mapViewAnnotationCanShowCallout = function (mapView, annotation) {
|
|
117
|
+
if (annotation.isKindOfClass(MGLUserLocation.class())) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
MGLMapViewDelegateImpl.prototype.mapViewDidFailLoadingMapWithError = function (mapView, error) {
|
|
125
|
+
if (Trace.isEnabled()) {
|
|
126
|
+
CLog(CLogTypes.info, 'mapViewDidFailLoadingMapWithError: ' + error);
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
MGLMapViewDelegateImpl.prototype.mapViewDidChangeUserTrackingModeAnimated = function (mapView, mode, animated) {
|
|
130
|
+
if (Trace.isEnabled()) {
|
|
131
|
+
CLog(CLogTypes.info, 'mapViewDidChangeUserTrackingModeAnimated: ' + mode);
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* fired when the marker icon is about to be rendered - return null for the default icon
|
|
136
|
+
*/
|
|
137
|
+
MGLMapViewDelegateImpl.prototype.mapViewImageForAnnotation = function (mapView, annotation) {
|
|
138
|
+
var cachedMarker = this.getTappedMarkerDetails(annotation);
|
|
139
|
+
if (cachedMarker) {
|
|
140
|
+
if (cachedMarker.reuseIdentifier) {
|
|
141
|
+
var reusedImage = mapView.dequeueReusableAnnotationImageWithIdentifier(cachedMarker.reuseIdentifier);
|
|
142
|
+
if (reusedImage) {
|
|
143
|
+
return reusedImage;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// TODO try adding .rotatesToMatchCamera = true;
|
|
147
|
+
// .. for instance in the mapViewDidDeselectAnnotationView / mapViewDidSelectAnnotationView / mapViewViewForAnnotation delegate
|
|
148
|
+
if (cachedMarker.icon) {
|
|
149
|
+
if (cachedMarker.icon.startsWith('res://')) {
|
|
150
|
+
var resourceName = cachedMarker.icon.substring('res://'.length);
|
|
151
|
+
var imageSource = ImageSource.fromResourceSync(resourceName);
|
|
152
|
+
if (imageSource === null) {
|
|
153
|
+
console.log("Unable to locate ".concat(resourceName));
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
cachedMarker.reuseIdentifier = cachedMarker.icon;
|
|
157
|
+
return MGLAnnotationImage.annotationImageWithImageReuseIdentifier(imageSource.ios, cachedMarker.reuseIdentifier);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
else if (cachedMarker.icon.startsWith('http')) {
|
|
161
|
+
if (cachedMarker.iconDownloaded !== null) {
|
|
162
|
+
cachedMarker.reuseIdentifier = cachedMarker.icon;
|
|
163
|
+
return MGLAnnotationImage.annotationImageWithImageReuseIdentifier(cachedMarker.iconDownloaded, cachedMarker.reuseIdentifier);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
if (Trace.isEnabled()) {
|
|
168
|
+
CLog(CLogTypes.info, 'Please use res://resourceName, http(s)://imageUrl or iconPath to use a local path');
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
else if (cachedMarker.iconPath) {
|
|
173
|
+
var appPath = knownFolders.currentApp().path;
|
|
174
|
+
var iconFullPath = appPath + '/' + cachedMarker.iconPath.replace('~/', '');
|
|
175
|
+
if (File.exists(iconFullPath)) {
|
|
176
|
+
var image = ImageSource.fromFileSync(iconFullPath).ios;
|
|
177
|
+
// perhaps add resize options for nice retina rendering (although you can now use the 'icon' param instead)
|
|
178
|
+
cachedMarker.reuseIdentifier = cachedMarker.iconPath;
|
|
179
|
+
return MGLAnnotationImage.annotationImageWithImageReuseIdentifier(image, cachedMarker.reuseIdentifier);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return null;
|
|
184
|
+
};
|
|
185
|
+
/**
|
|
186
|
+
* fired when one of the callout's accessoryviews is tapped (not currently used)
|
|
187
|
+
*/
|
|
188
|
+
MGLMapViewDelegateImpl.prototype.mapViewAnnotationCalloutAccessoryControlTapped = function (mapView, annotation, control) { };
|
|
189
|
+
/**
|
|
190
|
+
* fired when a marker is tapped
|
|
191
|
+
*/
|
|
192
|
+
MGLMapViewDelegateImpl.prototype.mapViewDidSelectAnnotation = function (mapView, annotation) {
|
|
193
|
+
if (Trace.isEnabled()) {
|
|
194
|
+
CLog(CLogTypes.info, 'MGLMapViewDelegateImpl::mapViewDidSelectAnntation()');
|
|
195
|
+
}
|
|
196
|
+
if (annotation.isKindOfClass(MGLUserLocation.class())) {
|
|
197
|
+
if (Trace.isEnabled()) {
|
|
198
|
+
CLog(CLogTypes.info, 'MGLMapViewDelegateImpl::mapViewDidSelectAnnotation(): tapped the user location button');
|
|
199
|
+
}
|
|
200
|
+
if (typeof this.userLocationClickListener != 'undefined') {
|
|
201
|
+
this.userLocationClickListener(annotation);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
mapView.deselectAnnotationAnimated(annotation, false);
|
|
205
|
+
}
|
|
206
|
+
var cachedMarker = this.getTappedMarkerDetails(annotation);
|
|
207
|
+
if (cachedMarker && cachedMarker.onTap) {
|
|
208
|
+
cachedMarker.onTap(cachedMarker);
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
/**
|
|
212
|
+
* fired when a callout is tapped
|
|
213
|
+
*/
|
|
214
|
+
MGLMapViewDelegateImpl.prototype.mapViewTapOnCalloutForAnnotation = function (mapView, annotation) {
|
|
215
|
+
var cachedMarker = this.getTappedMarkerDetails(annotation);
|
|
216
|
+
if (cachedMarker && cachedMarker.onCalloutTap) {
|
|
217
|
+
cachedMarker.onCalloutTap(cachedMarker);
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
MGLMapViewDelegateImpl.prototype.getTappedMarkerDetails = function (tapped) {
|
|
221
|
+
for (var m in _markers) {
|
|
222
|
+
var cached = _markers[m];
|
|
223
|
+
// don't compare lat/lng types as they're not the same (same for (sub)title, they may be null vs undefined)
|
|
224
|
+
if (
|
|
225
|
+
// eslint-disable-next-line eqeqeq
|
|
226
|
+
cached.lat == tapped.coordinate.latitude &&
|
|
227
|
+
// eslint-disable-next-line eqeqeq
|
|
228
|
+
cached.lng == tapped.coordinate.longitude &&
|
|
229
|
+
// eslint-disable-next-line eqeqeq
|
|
230
|
+
cached.title == tapped.title &&
|
|
231
|
+
// eslint-disable-next-line eqeqeq
|
|
232
|
+
cached.subtitle == tapped.subtitle) {
|
|
233
|
+
return cached;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
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
|
+
MGLMapViewDelegateImpl.prototype.mapViewRegionIsChangingWithReason = function (mapView, reason) {
|
|
251
|
+
if (Trace.isEnabled()) {
|
|
252
|
+
CLog(CLogTypes.info, 'MGLMapViewDelegateImpl::mapViewRegionIsChanging()');
|
|
253
|
+
}
|
|
254
|
+
if (this.cameraChangedListener) {
|
|
255
|
+
this.cameraChangedListener(reason);
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
MGLMapViewDelegateImpl.prototype.mapViewRegionDidChangeWithReasonAnimated = function (mapView, reason, animated) {
|
|
259
|
+
if (Trace.isEnabled()) {
|
|
260
|
+
CLog(CLogTypes.info, 'MGLMapViewDelegateImpl::mapViewRegionDidChangeAnimated()');
|
|
261
|
+
}
|
|
262
|
+
if (this.cameraChangedListener) {
|
|
263
|
+
this.cameraChangedListener(reason, animated);
|
|
264
|
+
}
|
|
265
|
+
if (this.cameraIdledListener) {
|
|
266
|
+
this.cameraIdledListener();
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
MGLMapViewDelegateImpl.prototype.mapViewDidUpdateUserLocation = function (mapView, userLocation) {
|
|
270
|
+
if (Trace.isEnabled()) {
|
|
271
|
+
CLog(CLogTypes.info, 'MGLMapViewDelegateImpl::mapViewDidUpdateUserLocation()');
|
|
272
|
+
}
|
|
273
|
+
if (this.userLocationChangedListener) {
|
|
274
|
+
this.userLocationChangedListener(_getLocation(userLocation));
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
MGLMapViewDelegateImpl.ObjCProtocols = [MGLMapViewDelegate];
|
|
278
|
+
return MGLMapViewDelegateImpl;
|
|
279
|
+
}(NSObject));
|
|
280
|
+
var MapTapHandlerImpl = /** @class */ (function (_super) {
|
|
281
|
+
__extends(MapTapHandlerImpl, _super);
|
|
282
|
+
function MapTapHandlerImpl() {
|
|
283
|
+
return _super !== null && _super.apply(this, arguments) || this;
|
|
284
|
+
}
|
|
285
|
+
MapTapHandlerImpl.initWithOwnerAndListenerForMap = function (owner, listener, mapView) {
|
|
286
|
+
var handler = MapTapHandlerImpl.new();
|
|
287
|
+
handler._owner = owner;
|
|
288
|
+
handler._listener = listener;
|
|
289
|
+
handler._mapView = mapView;
|
|
290
|
+
return handler;
|
|
291
|
+
};
|
|
292
|
+
MapTapHandlerImpl.prototype.tap = function (recognizer) {
|
|
293
|
+
var tapPoint = recognizer.locationInView(this._mapView);
|
|
294
|
+
var tapCoordinate = this._mapView.convertPointToCoordinateFromView(tapPoint, this._mapView);
|
|
295
|
+
this._listener({
|
|
296
|
+
lat: tapCoordinate.latitude,
|
|
297
|
+
lng: tapCoordinate.longitude
|
|
298
|
+
});
|
|
299
|
+
};
|
|
300
|
+
MapTapHandlerImpl.ObjCExposedMethods = {
|
|
301
|
+
tap: { returns: interop.types.void, params: [interop.types.id] }
|
|
302
|
+
};
|
|
303
|
+
return MapTapHandlerImpl;
|
|
304
|
+
}(NSObject));
|
|
305
|
+
var MapLongPressHandlerImpl = /** @class */ (function (_super) {
|
|
306
|
+
__extends(MapLongPressHandlerImpl, _super);
|
|
307
|
+
function MapLongPressHandlerImpl() {
|
|
308
|
+
return _super !== null && _super.apply(this, arguments) || this;
|
|
309
|
+
}
|
|
310
|
+
MapLongPressHandlerImpl.initWithOwnerAndListenerForMap = function (owner, listener, mapView) {
|
|
311
|
+
var handler = MapLongPressHandlerImpl.new();
|
|
312
|
+
handler._owner = owner;
|
|
313
|
+
handler._listener = listener;
|
|
314
|
+
handler._mapView = mapView;
|
|
315
|
+
return handler;
|
|
316
|
+
};
|
|
317
|
+
MapLongPressHandlerImpl.prototype.longPress = function (recognizer) {
|
|
318
|
+
var longPressPoint = recognizer.locationInView(this._mapView);
|
|
319
|
+
var longPressCoordinate = this._mapView.convertPointToCoordinateFromView(longPressPoint, this._mapView);
|
|
320
|
+
this._listener({
|
|
321
|
+
lat: longPressCoordinate.latitude,
|
|
322
|
+
lng: longPressCoordinate.longitude
|
|
323
|
+
});
|
|
324
|
+
};
|
|
325
|
+
MapLongPressHandlerImpl.ObjCExposedMethods = {
|
|
326
|
+
longPress: { returns: interop.types.void, params: [interop.types.id] }
|
|
327
|
+
};
|
|
328
|
+
return MapLongPressHandlerImpl;
|
|
329
|
+
}(NSObject));
|
|
330
|
+
var MapPanHandlerImpl = /** @class */ (function (_super) {
|
|
331
|
+
__extends(MapPanHandlerImpl, _super);
|
|
332
|
+
function MapPanHandlerImpl() {
|
|
333
|
+
return _super !== null && _super.apply(this, arguments) || this;
|
|
334
|
+
}
|
|
335
|
+
MapPanHandlerImpl.initWithOwnerAndListenerForMap = function (owner, listener, panState, mapView) {
|
|
336
|
+
var handler = MapPanHandlerImpl.new();
|
|
337
|
+
handler._owner = owner;
|
|
338
|
+
handler._listener = new Map([[panState, listener]]);
|
|
339
|
+
handler._mapView = mapView;
|
|
340
|
+
return handler;
|
|
341
|
+
};
|
|
342
|
+
MapPanHandlerImpl.prototype.addListener = function (panState, listener) {
|
|
343
|
+
this._listener.set(panState, listener);
|
|
344
|
+
};
|
|
345
|
+
MapPanHandlerImpl.prototype.pan = function (recognizer) {
|
|
346
|
+
var panCoordinate = this.getCoordinates(recognizer);
|
|
347
|
+
if (Trace.isEnabled()) {
|
|
348
|
+
CLog(CLogTypes.info, 'MapPanHandlerImpl::pan(): top with state:', recognizer.state);
|
|
349
|
+
}
|
|
350
|
+
if (recognizer.state === UIGestureRecognizerState.Changed) {
|
|
351
|
+
this.notifyListener(recognizer.state, panCoordinate.latitude, panCoordinate.longitude);
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
MapPanHandlerImpl.prototype.panEnd = function (recognizer) {
|
|
355
|
+
var panCoordinate = this.getCoordinates(recognizer);
|
|
356
|
+
if (Trace.isEnabled()) {
|
|
357
|
+
CLog(CLogTypes.info, 'MapPanHandlerImpl::panEnd(): top with state:', recognizer.state);
|
|
358
|
+
}
|
|
359
|
+
if (recognizer.state === UIGestureRecognizerState.Ended) {
|
|
360
|
+
this.notifyListener(recognizer.state, panCoordinate.latitude, panCoordinate.longitude);
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
MapPanHandlerImpl.prototype.panBegin = function (recognizer) {
|
|
364
|
+
var panCoordinate = this.getCoordinates(recognizer);
|
|
365
|
+
if (Trace.isEnabled()) {
|
|
366
|
+
CLog(CLogTypes.info, 'MapPanHandlerImpl::panBegin(): top with state:', recognizer.state);
|
|
367
|
+
}
|
|
368
|
+
if (recognizer.state === UIGestureRecognizerState.Began) {
|
|
369
|
+
this.notifyListener(recognizer.state, panCoordinate.latitude, panCoordinate.longitude);
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
MapPanHandlerImpl.prototype.getCoordinates = function (recognizer) {
|
|
373
|
+
var panPoint = recognizer.locationInView(this._mapView);
|
|
374
|
+
return this._mapView.convertPointToCoordinateFromView(panPoint, this._mapView);
|
|
375
|
+
};
|
|
376
|
+
MapPanHandlerImpl.prototype.notifyListener = function (panState, latitude, longitude) {
|
|
377
|
+
if (this._listener.has(panState)) {
|
|
378
|
+
this._listener.get(panState)({ lat: latitude, lng: longitude });
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
MapPanHandlerImpl.ObjCExposedMethods = {
|
|
382
|
+
pan: { returns: interop.types.void, params: [interop.types.id] },
|
|
383
|
+
panEnd: { returns: interop.types.void, params: [interop.types.id] },
|
|
384
|
+
panBegin: { returns: interop.types.void, params: [interop.types.id] }
|
|
385
|
+
};
|
|
386
|
+
return MapPanHandlerImpl;
|
|
387
|
+
}(NSObject));
|
|
388
|
+
var MapSwipeHandlerImpl = /** @class */ (function (_super) {
|
|
389
|
+
__extends(MapSwipeHandlerImpl, _super);
|
|
390
|
+
function MapSwipeHandlerImpl() {
|
|
391
|
+
return _super !== null && _super.apply(this, arguments) || this;
|
|
392
|
+
}
|
|
393
|
+
MapSwipeHandlerImpl.initWithOwnerAndListenerForMap = function (owner, listener, mapView) {
|
|
394
|
+
var handler = MapSwipeHandlerImpl.new();
|
|
395
|
+
handler._owner = owner;
|
|
396
|
+
handler._listener = listener;
|
|
397
|
+
handler._mapView = mapView;
|
|
398
|
+
return handler;
|
|
399
|
+
};
|
|
400
|
+
MapSwipeHandlerImpl.prototype.swipe = function (recognizer) {
|
|
401
|
+
var swipePoint = recognizer.locationInView(this._mapView);
|
|
402
|
+
var swipeCoordinate = this._mapView.convertPointToCoordinateFromView(swipePoint, this._mapView);
|
|
403
|
+
this._listener({
|
|
404
|
+
lat: swipeCoordinate.latitude,
|
|
405
|
+
lng: swipeCoordinate.longitude
|
|
406
|
+
});
|
|
407
|
+
};
|
|
408
|
+
MapSwipeHandlerImpl.ObjCExposedMethods = {
|
|
409
|
+
swipe: { returns: interop.types.void, params: [interop.types.id] }
|
|
410
|
+
};
|
|
411
|
+
return MapSwipeHandlerImpl;
|
|
412
|
+
}(NSObject));
|
|
413
|
+
export * from './common';
|
|
8
414
|
let _markers = [];
|
|
9
415
|
const _markerIconDownloadCache = [];
|
|
10
416
|
const _setMapboxMapOptions = (mapView, settings) => {
|
|
@@ -219,6 +625,28 @@ export class MapboxView extends MapboxViewBase {
|
|
|
219
625
|
ios: this.nativeMapView
|
|
220
626
|
});
|
|
221
627
|
}, this.nativeMapView);
|
|
628
|
+
this.mapbox.setOnMoveEndListener((data) => {
|
|
629
|
+
if (Trace.isEnabled()) {
|
|
630
|
+
CLog(CLogTypes.info, 'initMap(): onMoveEnd listener');
|
|
631
|
+
}
|
|
632
|
+
this.notify({
|
|
633
|
+
eventName: MapboxViewBase.moveEndEvent,
|
|
634
|
+
object: this,
|
|
635
|
+
map: this,
|
|
636
|
+
ios: this.nativeMapView
|
|
637
|
+
});
|
|
638
|
+
}, this.nativeMapView);
|
|
639
|
+
this.mapbox.setOnScrollListener((data) => {
|
|
640
|
+
if (Trace.isEnabled()) {
|
|
641
|
+
CLog(CLogTypes.info, 'initMap(): onScroll listener');
|
|
642
|
+
}
|
|
643
|
+
this.notify({
|
|
644
|
+
eventName: MapboxViewBase.scrollEvent,
|
|
645
|
+
object: this,
|
|
646
|
+
map: this,
|
|
647
|
+
ios: this.nativeMapView
|
|
648
|
+
});
|
|
649
|
+
}, this.nativeMapView);
|
|
222
650
|
};
|
|
223
651
|
setTimeout(drawMap, this.settings.delay ? this.settings.delay : 0);
|
|
224
652
|
}
|
|
@@ -233,9 +661,6 @@ export class MapboxView extends MapboxViewBase {
|
|
|
233
661
|
NSUserDefaults.standardUserDefaults.setBoolForKey(false, 'MGLMapboxMetricsEnabled');
|
|
234
662
|
}
|
|
235
663
|
}
|
|
236
|
-
"use strict";
|
|
237
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
238
|
-
exports.CustomUserLocationAnnotationView = void 0;
|
|
239
664
|
var CustomUserLocationAnnotationView = /** @class */ (function (_super) {
|
|
240
665
|
__extends(CustomUserLocationAnnotationView, _super);
|
|
241
666
|
function CustomUserLocationAnnotationView() {
|
|
@@ -444,7 +869,6 @@ var CustomUserLocationAnnotationView = /** @class */ (function (_super) {
|
|
|
444
869
|
};
|
|
445
870
|
return CustomUserLocationAnnotationView;
|
|
446
871
|
}(MGLUserLocationAnnotationView));
|
|
447
|
-
exports.CustomUserLocationAnnotationView = CustomUserLocationAnnotationView;
|
|
448
872
|
export class Mapbox extends MapboxCommon {
|
|
449
873
|
constructor() {
|
|
450
874
|
super(...arguments);
|
|
@@ -825,403 +1249,41 @@ export class Mapbox extends MapboxCommon {
|
|
|
825
1249
|
const level = options.level;
|
|
826
1250
|
if (level >= 0 && level <= 20) {
|
|
827
1251
|
theMap.setZoomLevelAnimated(level, animated);
|
|
828
|
-
resolve();
|
|
829
|
-
}
|
|
830
|
-
else {
|
|
831
|
-
reject('invalid ZoomLevel, use any double value from 0 to 20 (like 8.3)');
|
|
832
|
-
}
|
|
833
|
-
}
|
|
834
|
-
catch (ex) {
|
|
835
|
-
if (Trace.isEnabled()) {
|
|
836
|
-
CLog(CLogTypes.info, 'Error in mapbox.setZoomLevel: ' + ex);
|
|
837
|
-
}
|
|
838
|
-
reject(ex);
|
|
839
|
-
}
|
|
840
|
-
});
|
|
841
|
-
}
|
|
842
|
-
getZoomLevel(nativeMap) {
|
|
843
|
-
return new Promise((resolve, reject) => {
|
|
844
|
-
try {
|
|
845
|
-
const theMap = nativeMap || this._mapboxViewInstance;
|
|
846
|
-
resolve(theMap.zoomLevel);
|
|
847
|
-
}
|
|
848
|
-
catch (ex) {
|
|
849
|
-
if (Trace.isEnabled()) {
|
|
850
|
-
CLog(CLogTypes.info, 'Error in mapbox.getZoomLevel: ' + ex);
|
|
851
|
-
}
|
|
852
|
-
reject(ex);
|
|
853
|
-
}
|
|
854
|
-
});
|
|
855
|
-
}
|
|
856
|
-
setTilt(options, nativeMap) {
|
|
857
|
-
return new Promise((resolve, reject) => {
|
|
858
|
-
try {
|
|
859
|
-
const theMap = nativeMap || this._mapboxViewInstance;
|
|
860
|
-
const cam = theMap.camera;
|
|
861
|
-
cam.pitch = options.tilt;
|
|
862
|
-
const durationMs = options.duration ? options.duration : 5000;
|
|
863
|
-
theMap.setCameraWithDurationAnimationTimingFunction(cam, durationMs / 1000, CAMediaTimingFunction.functionWithName(kCAMediaTimingFunctionEaseInEaseOut));
|
|
864
|
-
setTimeout(() => {
|
|
865
|
-
resolve();
|
|
866
|
-
}, durationMs);
|
|
867
|
-
}
|
|
868
|
-
catch (ex) {
|
|
869
|
-
if (Trace.isEnabled()) {
|
|
870
|
-
CLog(CLogTypes.info, 'Error in mapbox.setTilt: ' + ex);
|
|
871
|
-
}
|
|
872
|
-
reject(ex);
|
|
873
|
-
}
|
|
874
|
-
});
|
|
875
|
-
}
|
|
876
|
-
getTilt(nativeMap) {
|
|
877
|
-
return new Promise((resolve, reject) => {
|
|
878
|
-
try {
|
|
879
|
-
const theMap = nativeMap || this._mapboxViewInstance;
|
|
880
|
-
resolve(theMap.camera.pitch);
|
|
881
|
-
}
|
|
882
|
-
catch (ex) {
|
|
883
|
-
if (Trace.isEnabled()) {
|
|
884
|
-
CLog(CLogTypes.info, 'Error in mapbox.getTilt: ' + ex);
|
|
885
|
-
}
|
|
886
|
-
reject(ex);
|
|
887
|
-
}
|
|
888
|
-
});
|
|
889
|
-
}
|
|
890
|
-
getUserLocation(nativeMap) {
|
|
891
|
-
return new Promise((resolve, reject) => {
|
|
892
|
-
try {
|
|
893
|
-
const theMap = nativeMap || this._mapboxViewInstance;
|
|
894
|
-
const loc = theMap.userLocation;
|
|
895
|
-
if (loc === null) {
|
|
896
|
-
reject('Location not available');
|
|
897
|
-
}
|
|
898
|
-
else {
|
|
899
|
-
resolve(_getLocation(loc));
|
|
900
|
-
}
|
|
901
|
-
}
|
|
902
|
-
catch (ex) {
|
|
903
|
-
if (Trace.isEnabled()) {
|
|
904
|
-
CLog(CLogTypes.info, 'Error in mapbox.getUserLocation: ' + ex);
|
|
905
|
-
}
|
|
906
|
-
reject(ex);
|
|
907
|
-
}
|
|
908
|
-
});
|
|
909
|
-
}
|
|
910
|
-
_stringToCameraMode(mode) {
|
|
911
|
-
switch (mode) {
|
|
912
|
-
case 'NONE':
|
|
913
|
-
return 0;
|
|
914
|
-
case 'NONE_COMPASS':
|
|
915
|
-
if (Trace.isEnabled()) {
|
|
916
|
-
CLog(CLogTypes.info, '_stringToCameraMode(): NONE_COMPASS unsupported on iOS');
|
|
917
|
-
}
|
|
918
|
-
return 0;
|
|
919
|
-
case 'NONE_GPS':
|
|
920
|
-
if (Trace.isEnabled()) {
|
|
921
|
-
CLog(CLogTypes.info, '_stringToCameraMode(): NONE_GPS unsupported on iOS');
|
|
922
|
-
}
|
|
923
|
-
return 0;
|
|
924
|
-
case 'TRACKING':
|
|
925
|
-
return 1;
|
|
926
|
-
case 'TRACK_COMPASS':
|
|
927
|
-
return 2;
|
|
928
|
-
case 'TRACKING_GPS':
|
|
929
|
-
return 1;
|
|
930
|
-
case 'TRACK_GPS_NORTH':
|
|
931
|
-
return 3;
|
|
932
|
-
}
|
|
933
|
-
}
|
|
934
|
-
_stringToRenderMode(mode) {
|
|
935
|
-
let renderMode;
|
|
936
|
-
switch (mode) {
|
|
937
|
-
case 'NORMAL':
|
|
938
|
-
return 'NORMAL';
|
|
939
|
-
case 'COMPASS':
|
|
940
|
-
return 'COMPASS';
|
|
941
|
-
case 'GPS':
|
|
942
|
-
return 'GPS';
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
showUserLocationMarker(options, nativeMap) {
|
|
946
|
-
return new Promise((resolve, reject) => {
|
|
947
|
-
try {
|
|
948
|
-
const theMap = nativeMap || this._mapboxViewInstance;
|
|
949
|
-
theMap.showsUserLocation = true;
|
|
950
|
-
theMap.userTrackingMode = this._stringToCameraMode(options.cameraMode);
|
|
951
|
-
theMap.showsUserHeadingIndicator = true;
|
|
952
|
-
this.userLocationRenderMode = this._stringToRenderMode(options.renderMode);
|
|
953
|
-
const delegate = theMap.delegate;
|
|
954
|
-
delegate.changeUserLocationRenderMode(this.userLocationRenderMode);
|
|
955
|
-
if (typeof options.clickListener != 'undefined') {
|
|
956
|
-
delegate.setUserLocationClickListener(options.clickListener);
|
|
957
|
-
}
|
|
958
|
-
resolve();
|
|
959
|
-
}
|
|
960
|
-
catch (ex) {
|
|
961
|
-
if (Trace.isEnabled()) {
|
|
962
|
-
CLog(CLogTypes.info, 'Error in mapbox.getUserLocation: ' + ex);
|
|
963
|
-
}
|
|
964
|
-
reject(ex);
|
|
965
|
-
}
|
|
966
|
-
});
|
|
967
|
-
}
|
|
968
|
-
hideUserLocationMarker(nativeMap) {
|
|
969
|
-
return new Promise((resolve, reject) => {
|
|
970
|
-
try {
|
|
971
|
-
resolve();
|
|
972
|
-
}
|
|
973
|
-
catch (ex) {
|
|
974
|
-
if (Trace.isEnabled()) {
|
|
975
|
-
CLog(CLogTypes.info, 'Error in mapbox.getUserLocation: ' + ex);
|
|
976
|
-
}
|
|
977
|
-
reject(ex);
|
|
978
|
-
}
|
|
979
|
-
});
|
|
980
|
-
}
|
|
981
|
-
changeUserLocationMarkerMode(renderModeString, cameraModeString, nativeMap) {
|
|
982
|
-
return new Promise((resolve, reject) => {
|
|
983
|
-
try {
|
|
984
|
-
const theMap = nativeMap || this._mapboxViewInstance;
|
|
985
|
-
if (Trace.isEnabled()) {
|
|
986
|
-
CLog(CLogTypes.info, "Mapbox::changeUserLocationMarkerMode(): changing renderMode to '" + renderModeString + "' cameraMode '" + cameraModeString + "'");
|
|
987
|
-
}
|
|
988
|
-
theMap.userTrackingMode = this._stringToCameraMode(cameraModeString);
|
|
989
|
-
const delegate = theMap.delegate;
|
|
990
|
-
const renderMode = this._stringToRenderMode(renderModeString);
|
|
991
|
-
delegate.changeUserLocationRenderMode(renderMode);
|
|
992
|
-
}
|
|
993
|
-
catch (ex) {
|
|
994
|
-
if (Trace.isEnabled()) {
|
|
995
|
-
CLog(CLogTypes.info, 'Error in mapbox.showUserLocationMarker: ' + ex);
|
|
996
|
-
}
|
|
997
|
-
reject(ex);
|
|
998
|
-
}
|
|
999
|
-
});
|
|
1000
|
-
}
|
|
1001
|
-
forceUserLocationUpdate(location, nativeMap) { }
|
|
1002
|
-
queryRenderedFeatures(options, nativeMap) {
|
|
1003
|
-
return new Promise((resolve, reject) => {
|
|
1004
|
-
try {
|
|
1005
|
-
const theMap = nativeMap || this._mapboxViewInstance;
|
|
1006
|
-
if (options.point === undefined) {
|
|
1007
|
-
reject("Please set the 'point' parameter");
|
|
1008
|
-
return;
|
|
1009
|
-
}
|
|
1010
|
-
if (!options) {
|
|
1011
|
-
options = {};
|
|
1012
|
-
}
|
|
1013
|
-
const { x, y } = theMap.convertCoordinateToPointToView({ latitude: options.point.lat, longitude: options.point.lng }, theMap);
|
|
1014
|
-
const queryLayerIds = options.layers ? NSSet.setWithArray(iOSNativeHelper.collections.jsArrayToNSArray(options.layers)) : null;
|
|
1015
|
-
const queryFilter = options.filter ? FilterParser.parseJson(options.filter) : null;
|
|
1016
|
-
const features = theMap.visibleFeaturesAtPointInStyleLayersWithIdentifiersPredicate({ x, y }, queryLayerIds, queryFilter);
|
|
1017
|
-
const result = [];
|
|
1018
|
-
for (let i = 0; i < features.count; i++) {
|
|
1019
|
-
const feature = features.objectAtIndex(i);
|
|
1020
|
-
const featureJson = NSJSONSerialization.dataWithJSONObjectOptionsError(feature.geoJSONDictionary(), 0);
|
|
1021
|
-
result.push(JSON.parse(NSString.alloc().initWithDataEncoding(featureJson, NSUTF8StringEncoding)));
|
|
1022
|
-
}
|
|
1023
|
-
resolve(result);
|
|
1024
|
-
}
|
|
1025
|
-
catch (ex) {
|
|
1026
|
-
if (Trace.isEnabled()) {
|
|
1027
|
-
CLog(CLogTypes.info, 'Error in mapbox.queryRenderedFeatures: ' + ex);
|
|
1028
|
-
}
|
|
1029
|
-
reject(ex);
|
|
1030
|
-
}
|
|
1031
|
-
});
|
|
1032
|
-
}
|
|
1033
|
-
querySourceFeatures(sourceId, options, nativeMap) {
|
|
1034
|
-
return new Promise((resolve, reject) => {
|
|
1035
|
-
try {
|
|
1036
|
-
const theMap = nativeMap || this._mapboxViewInstance;
|
|
1037
|
-
if (!options) {
|
|
1038
|
-
options = {};
|
|
1039
|
-
}
|
|
1040
|
-
const source = theMap.style.sourceWithIdentifier(sourceId);
|
|
1041
|
-
if (!source) {
|
|
1042
|
-
throw new Error(`Source with id "${sourceId}" not found.`);
|
|
1043
|
-
}
|
|
1044
|
-
let features;
|
|
1045
|
-
const queryFilter = options.filter ? FilterParser.parseJson(options.filter) : null;
|
|
1046
|
-
if (source instanceof MGLShapeSource) {
|
|
1047
|
-
features = source.featuresMatchingPredicate(queryFilter);
|
|
1048
|
-
}
|
|
1049
|
-
else if (source instanceof MGLVectorTileSource) {
|
|
1050
|
-
if (!options.sourceLayer) {
|
|
1051
|
-
throw new Error('The option "sourceLayer" is required for vector sources.');
|
|
1052
|
-
}
|
|
1053
|
-
const sourceLayerIds = options.sourceLayer ? NSSet.setWithArray(iOSNativeHelper.collections.jsArrayToNSArray([options.sourceLayer])) : null;
|
|
1054
|
-
features = source.featuresInSourceLayersWithIdentifiersPredicate(sourceLayerIds, queryFilter);
|
|
1252
|
+
resolve();
|
|
1055
1253
|
}
|
|
1056
1254
|
else {
|
|
1057
|
-
|
|
1058
|
-
}
|
|
1059
|
-
const result = [];
|
|
1060
|
-
for (let i = 0; i < features.count; i++) {
|
|
1061
|
-
const feature = features.objectAtIndex(i);
|
|
1062
|
-
const featureJson = NSJSONSerialization.dataWithJSONObjectOptionsError(feature.geoJSONDictionary(), 0);
|
|
1063
|
-
result.push(JSON.parse(NSString.alloc().initWithDataEncoding(featureJson, NSUTF8StringEncoding)));
|
|
1255
|
+
reject('invalid ZoomLevel, use any double value from 0 to 20 (like 8.3)');
|
|
1064
1256
|
}
|
|
1065
|
-
resolve(result);
|
|
1066
1257
|
}
|
|
1067
1258
|
catch (ex) {
|
|
1068
1259
|
if (Trace.isEnabled()) {
|
|
1069
|
-
CLog(CLogTypes.info, 'Error in mapbox.
|
|
1260
|
+
CLog(CLogTypes.info, 'Error in mapbox.setZoomLevel: ' + ex);
|
|
1070
1261
|
}
|
|
1071
1262
|
reject(ex);
|
|
1072
1263
|
}
|
|
1073
1264
|
});
|
|
1074
1265
|
}
|
|
1075
|
-
|
|
1266
|
+
getZoomLevel(nativeMap) {
|
|
1076
1267
|
return new Promise((resolve, reject) => {
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
reject("Please set the 'points' parameter");
|
|
1081
|
-
return;
|
|
1082
|
-
}
|
|
1083
|
-
const coordinateArray = [];
|
|
1084
|
-
points.forEach((point) => coordinateArray.push([point.lng, point.lat]));
|
|
1085
|
-
const polygonID = `polygon_${options.id || new Date().getTime()}`;
|
|
1086
|
-
if (theMap.style.sourceWithIdentifier(polygonID)) {
|
|
1087
|
-
reject("Remove the polygon with this id first with 'removePolygons': " + polygonID);
|
|
1088
|
-
return;
|
|
1268
|
+
try {
|
|
1269
|
+
const theMap = nativeMap || this._mapboxViewInstance;
|
|
1270
|
+
resolve(theMap.zoomLevel);
|
|
1089
1271
|
}
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
{
|
|
1094
|
-
"id": ${JSON.stringify(polygonID)},
|
|
1095
|
-
"type": "Feature",
|
|
1096
|
-
"properties": {
|
|
1097
|
-
},
|
|
1098
|
-
"geometry": {
|
|
1099
|
-
"type": "Polygon",
|
|
1100
|
-
"coordinates": [${JSON.stringify(coordinateArray)}]
|
|
1101
|
-
}
|
|
1272
|
+
catch (ex) {
|
|
1273
|
+
if (Trace.isEnabled()) {
|
|
1274
|
+
CLog(CLogTypes.info, 'Error in mapbox.getZoomLevel: ' + ex);
|
|
1102
1275
|
}
|
|
1103
|
-
|
|
1104
|
-
}`;
|
|
1105
|
-
const geoDataStr = NSString.stringWithString(geoJSON);
|
|
1106
|
-
const geoData = geoDataStr.dataUsingEncoding(NSUTF8StringEncoding);
|
|
1107
|
-
const geoDataBase64Enc = geoData.base64EncodedStringWithOptions(0);
|
|
1108
|
-
const geo = NSData.alloc().initWithBase64EncodedStringOptions(geoDataBase64Enc, null);
|
|
1109
|
-
const shape = MGLShape.shapeWithDataEncodingError(geo, NSUTF8StringEncoding);
|
|
1110
|
-
const source = MGLShapeSource.alloc().initWithIdentifierShapeOptions(polygonID, shape, null);
|
|
1111
|
-
theMap.style.addSource(source);
|
|
1112
|
-
if (options.strokeColor || options.strokeWidth || options.strokeOpacity) {
|
|
1113
|
-
const strokeLayer = MGLLineStyleLayer.alloc().initWithIdentifierSource(polygonID + '_stroke', source);
|
|
1114
|
-
strokeLayer.lineColor = NSExpression.expressionForConstantValue(!options.strokeColor ? UIColor.blackColor : options.strokeColor instanceof Color ? options.strokeColor.ios : new Color(options.strokeColor).ios);
|
|
1115
|
-
strokeLayer.lineWidth = NSExpression.expressionForConstantValue(options.strokeWidth || 5);
|
|
1116
|
-
strokeLayer.lineOpacity = NSExpression.expressionForConstantValue(options.strokeOpacity === undefined ? 1 : options.strokeOpacity);
|
|
1117
|
-
theMap.style.addLayer(strokeLayer);
|
|
1118
|
-
}
|
|
1119
|
-
const layer = MGLFillStyleLayer.alloc().initWithIdentifierSource(polygonID, source);
|
|
1120
|
-
layer.fillColor = NSExpression.expressionForConstantValue(!options.fillColor ? UIColor.blackColor : options.fillColor instanceof Color ? options.fillColor.ios : new Color(options.fillColor).ios);
|
|
1121
|
-
layer.fillOpacity = NSExpression.expressionForConstantValue(options.fillOpacity === undefined ? 1 : options.fillOpacity);
|
|
1122
|
-
theMap.style.addLayer(layer);
|
|
1123
|
-
resolve();
|
|
1124
|
-
});
|
|
1125
|
-
}
|
|
1126
|
-
addPolyline(options, nativeMap) {
|
|
1127
|
-
return new Promise((resolve, reject) => {
|
|
1128
|
-
const theMap = nativeMap || this._mapboxViewInstance;
|
|
1129
|
-
const points = options.points;
|
|
1130
|
-
if (points === undefined) {
|
|
1131
|
-
reject("Please set the 'points' parameter");
|
|
1132
|
-
return;
|
|
1133
|
-
}
|
|
1134
|
-
const coordinateArray = [];
|
|
1135
|
-
points.forEach((point) => coordinateArray.push([point.lng, point.lat]));
|
|
1136
|
-
const polylineID = 'polyline_' + (options.id || new Date().getTime());
|
|
1137
|
-
if (theMap.style.sourceWithIdentifier(polylineID)) {
|
|
1138
|
-
reject("Remove the polyline with this id first with 'removePolylines': " + polylineID);
|
|
1139
|
-
return;
|
|
1276
|
+
reject(ex);
|
|
1140
1277
|
}
|
|
1141
|
-
const geoJSON = `{"type": "FeatureCollection", "features": [{"type": "Feature","properties": {},"geometry": {"type": "LineString", "coordinates": ${JSON.stringify(coordinateArray)}}}]}`;
|
|
1142
|
-
const geoDataStr = NSString.stringWithString(geoJSON);
|
|
1143
|
-
const geoData = geoDataStr.dataUsingEncoding(NSUTF8StringEncoding);
|
|
1144
|
-
const geoDataBase64Enc = geoData.base64EncodedStringWithOptions(0);
|
|
1145
|
-
const geo = NSData.alloc().initWithBase64EncodedStringOptions(geoDataBase64Enc, null);
|
|
1146
|
-
const shape = MGLShape.shapeWithDataEncodingError(geo, NSUTF8StringEncoding);
|
|
1147
|
-
const source = MGLShapeSource.alloc().initWithIdentifierShapeOptions(polylineID, shape, null);
|
|
1148
|
-
theMap.style.addSource(source);
|
|
1149
|
-
const layer = MGLLineStyleLayer.alloc().initWithIdentifierSource(polylineID, source);
|
|
1150
|
-
layer.lineColor = NSExpression.expressionForConstantValue(!options.color ? UIColor.blackColor : options.color instanceof Color ? options.color.ios : new Color(options.color).ios);
|
|
1151
|
-
layer.lineWidth = NSExpression.expressionForConstantValue(options.width || 5);
|
|
1152
|
-
layer.lineOpacity = NSExpression.expressionForConstantValue(options.opacity === undefined ? 1 : options.opacity);
|
|
1153
|
-
theMap.style.addLayer(layer);
|
|
1154
|
-
resolve();
|
|
1155
1278
|
});
|
|
1156
1279
|
}
|
|
1157
|
-
|
|
1158
|
-
let layer = theMap.style.layerWithIdentifier(id);
|
|
1159
|
-
if (layer !== null) {
|
|
1160
|
-
theMap.style.removeLayer(layer);
|
|
1161
|
-
}
|
|
1162
|
-
layer = theMap.style.layerWithIdentifier(id + '_stroke');
|
|
1163
|
-
if (layer !== null) {
|
|
1164
|
-
theMap.style.removeLayer(layer);
|
|
1165
|
-
}
|
|
1166
|
-
const source = theMap.style.sourceWithIdentifier(id);
|
|
1167
|
-
if (source !== null) {
|
|
1168
|
-
theMap.style.removeSource(source);
|
|
1169
|
-
}
|
|
1170
|
-
}
|
|
1171
|
-
removePolys(polyType, ids, nativeMap) {
|
|
1172
|
-
return new Promise((resolve) => {
|
|
1173
|
-
const theMap = nativeMap || this._mapboxViewInstance;
|
|
1174
|
-
ids.forEach((id) => this.removePolyById(theMap, polyType + id));
|
|
1175
|
-
resolve();
|
|
1176
|
-
});
|
|
1177
|
-
}
|
|
1178
|
-
removePolygons(ids, nativeMap) {
|
|
1179
|
-
return this.removePolys('polygon_', ids, nativeMap);
|
|
1180
|
-
}
|
|
1181
|
-
removePolylines(ids, nativeMap) {
|
|
1182
|
-
return this.removePolys('polyline_', ids, nativeMap);
|
|
1183
|
-
}
|
|
1184
|
-
animateCamera(options, nativeMap) {
|
|
1280
|
+
setTilt(options, nativeMap) {
|
|
1185
1281
|
return new Promise((resolve, reject) => {
|
|
1186
1282
|
try {
|
|
1187
1283
|
const theMap = nativeMap || this._mapboxViewInstance;
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
const insets = {
|
|
1192
|
-
top: padding,
|
|
1193
|
-
left: padding,
|
|
1194
|
-
bottom: padding,
|
|
1195
|
-
right: padding
|
|
1196
|
-
};
|
|
1197
|
-
const bounds = {
|
|
1198
|
-
sw: CLLocationCoordinate2DMake(options.bounds.south, options.bounds.west),
|
|
1199
|
-
ne: CLLocationCoordinate2DMake(options.bounds.north, options.bounds.east)
|
|
1200
|
-
};
|
|
1201
|
-
cam = theMap.cameraThatFitsCoordinateBoundsEdgePadding(bounds, insets);
|
|
1202
|
-
}
|
|
1203
|
-
else {
|
|
1204
|
-
const target = options.target;
|
|
1205
|
-
if (target === undefined) {
|
|
1206
|
-
reject("Please set the 'target' parameter");
|
|
1207
|
-
return;
|
|
1208
|
-
}
|
|
1209
|
-
cam = theMap.camera;
|
|
1210
|
-
cam.centerCoordinate = CLLocationCoordinate2DMake(target.lat, target.lng);
|
|
1211
|
-
}
|
|
1212
|
-
if (options.altitude) {
|
|
1213
|
-
cam.altitude = options.altitude;
|
|
1214
|
-
}
|
|
1215
|
-
if (options.bearing) {
|
|
1216
|
-
cam.heading = options.bearing;
|
|
1217
|
-
}
|
|
1218
|
-
if (options.tilt) {
|
|
1219
|
-
cam.pitch = options.tilt;
|
|
1220
|
-
}
|
|
1221
|
-
if (options.zoomLevel && options.target) {
|
|
1222
|
-
cam.altitude = MGLAltitudeForZoomLevel(options.zoomLevel, cam.pitch, options.target.lat, theMap.frame.size);
|
|
1223
|
-
}
|
|
1224
|
-
const durationMs = options.duration ? options.duration : 10000;
|
|
1284
|
+
const cam = theMap.camera;
|
|
1285
|
+
cam.pitch = options.tilt;
|
|
1286
|
+
const durationMs = options.duration ? options.duration : 5000;
|
|
1225
1287
|
theMap.setCameraWithDurationAnimationTimingFunction(cam, durationMs / 1000, CAMediaTimingFunction.functionWithName(kCAMediaTimingFunctionEaseInEaseOut));
|
|
1226
1288
|
setTimeout(() => {
|
|
1227
1289
|
resolve();
|
|
@@ -1229,336 +1291,375 @@ export class Mapbox extends MapboxCommon {
|
|
|
1229
1291
|
}
|
|
1230
1292
|
catch (ex) {
|
|
1231
1293
|
if (Trace.isEnabled()) {
|
|
1232
|
-
CLog(CLogTypes.info, 'Error in mapbox.
|
|
1294
|
+
CLog(CLogTypes.info, 'Error in mapbox.setTilt: ' + ex);
|
|
1233
1295
|
}
|
|
1234
1296
|
reject(ex);
|
|
1235
1297
|
}
|
|
1236
1298
|
});
|
|
1237
1299
|
}
|
|
1238
|
-
|
|
1300
|
+
getTilt(nativeMap) {
|
|
1239
1301
|
return new Promise((resolve, reject) => {
|
|
1240
1302
|
try {
|
|
1241
1303
|
const theMap = nativeMap || this._mapboxViewInstance;
|
|
1242
|
-
|
|
1243
|
-
reject('No map has been loaded');
|
|
1244
|
-
return;
|
|
1245
|
-
}
|
|
1246
|
-
theMap['mapTapHandler'] = MapTapHandlerImpl.initWithOwnerAndListenerForMap(new WeakRef(this), listener, theMap);
|
|
1247
|
-
const tapGestureRecognizer = UITapGestureRecognizer.alloc().initWithTargetAction(theMap['mapTapHandler'], 'tap');
|
|
1248
|
-
for (let i = 0; i < theMap.gestureRecognizers.count; i++) {
|
|
1249
|
-
const recognizer = theMap.gestureRecognizers.objectAtIndex(i);
|
|
1250
|
-
if (recognizer instanceof UITapGestureRecognizer) {
|
|
1251
|
-
tapGestureRecognizer.requireGestureRecognizerToFail(recognizer);
|
|
1252
|
-
}
|
|
1253
|
-
}
|
|
1254
|
-
theMap.addGestureRecognizer(tapGestureRecognizer);
|
|
1255
|
-
resolve();
|
|
1304
|
+
resolve(theMap.camera.pitch);
|
|
1256
1305
|
}
|
|
1257
1306
|
catch (ex) {
|
|
1258
1307
|
if (Trace.isEnabled()) {
|
|
1259
|
-
CLog(CLogTypes.info, 'Error in mapbox.
|
|
1308
|
+
CLog(CLogTypes.info, 'Error in mapbox.getTilt: ' + ex);
|
|
1260
1309
|
}
|
|
1261
1310
|
reject(ex);
|
|
1262
1311
|
}
|
|
1263
1312
|
});
|
|
1264
1313
|
}
|
|
1265
|
-
|
|
1314
|
+
getUserLocation(nativeMap) {
|
|
1266
1315
|
return new Promise((resolve, reject) => {
|
|
1267
1316
|
try {
|
|
1268
1317
|
const theMap = nativeMap || this._mapboxViewInstance;
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1318
|
+
const loc = theMap.userLocation;
|
|
1319
|
+
if (loc === null) {
|
|
1320
|
+
reject('Location not available');
|
|
1272
1321
|
}
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
for (let i = 0; i < theMap.gestureRecognizers.count; i++) {
|
|
1276
|
-
const recognizer = theMap.gestureRecognizers.objectAtIndex(i);
|
|
1277
|
-
if (recognizer instanceof UILongPressGestureRecognizer) {
|
|
1278
|
-
longPressGestureRecognizer.requireGestureRecognizerToFail(recognizer);
|
|
1279
|
-
}
|
|
1322
|
+
else {
|
|
1323
|
+
resolve(_getLocation(loc));
|
|
1280
1324
|
}
|
|
1281
|
-
theMap.addGestureRecognizer(longPressGestureRecognizer);
|
|
1282
|
-
resolve();
|
|
1283
1325
|
}
|
|
1284
1326
|
catch (ex) {
|
|
1285
1327
|
if (Trace.isEnabled()) {
|
|
1286
|
-
CLog(CLogTypes.info, 'Error in mapbox.
|
|
1328
|
+
CLog(CLogTypes.info, 'Error in mapbox.getUserLocation: ' + ex);
|
|
1287
1329
|
}
|
|
1288
1330
|
reject(ex);
|
|
1289
1331
|
}
|
|
1290
1332
|
});
|
|
1291
1333
|
}
|
|
1292
|
-
|
|
1334
|
+
_stringToCameraMode(mode) {
|
|
1335
|
+
switch (mode) {
|
|
1336
|
+
case 'NONE':
|
|
1337
|
+
return 0;
|
|
1338
|
+
case 'NONE_COMPASS':
|
|
1339
|
+
if (Trace.isEnabled()) {
|
|
1340
|
+
CLog(CLogTypes.info, '_stringToCameraMode(): NONE_COMPASS unsupported on iOS');
|
|
1341
|
+
}
|
|
1342
|
+
return 0;
|
|
1343
|
+
case 'NONE_GPS':
|
|
1344
|
+
if (Trace.isEnabled()) {
|
|
1345
|
+
CLog(CLogTypes.info, '_stringToCameraMode(): NONE_GPS unsupported on iOS');
|
|
1346
|
+
}
|
|
1347
|
+
return 0;
|
|
1348
|
+
case 'TRACKING':
|
|
1349
|
+
return 1;
|
|
1350
|
+
case 'TRACKING_COMPASS':
|
|
1351
|
+
return 2;
|
|
1352
|
+
case 'TRACKING_GPS':
|
|
1353
|
+
return 1;
|
|
1354
|
+
case 'TRACKING_GPS_NORTH':
|
|
1355
|
+
return 3;
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1358
|
+
_stringToRenderMode(mode) {
|
|
1359
|
+
let renderMode;
|
|
1360
|
+
switch (mode) {
|
|
1361
|
+
case 'NORMAL':
|
|
1362
|
+
return 'NORMAL';
|
|
1363
|
+
case 'COMPASS':
|
|
1364
|
+
return 'COMPASS';
|
|
1365
|
+
case 'GPS':
|
|
1366
|
+
return 'GPS';
|
|
1367
|
+
}
|
|
1368
|
+
}
|
|
1369
|
+
showUserLocationMarker(options, nativeMap) {
|
|
1293
1370
|
return new Promise((resolve, reject) => {
|
|
1294
1371
|
try {
|
|
1295
1372
|
const theMap = nativeMap || this._mapboxViewInstance;
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
recognizer.addTargetAction(theMap['mapPanHandler'], 'pan');
|
|
1305
|
-
break;
|
|
1306
|
-
}
|
|
1373
|
+
theMap.showsUserLocation = true;
|
|
1374
|
+
theMap.userTrackingMode = this._stringToCameraMode(options.cameraMode);
|
|
1375
|
+
theMap.showsUserHeadingIndicator = true;
|
|
1376
|
+
this.userLocationRenderMode = this._stringToRenderMode(options.renderMode);
|
|
1377
|
+
const delegate = theMap.delegate;
|
|
1378
|
+
delegate.changeUserLocationRenderMode(this.userLocationRenderMode);
|
|
1379
|
+
if (typeof options.clickListener != 'undefined') {
|
|
1380
|
+
delegate.setUserLocationClickListener(options.clickListener);
|
|
1307
1381
|
}
|
|
1308
1382
|
resolve();
|
|
1309
1383
|
}
|
|
1310
1384
|
catch (ex) {
|
|
1311
1385
|
if (Trace.isEnabled()) {
|
|
1312
|
-
CLog(CLogTypes.info, 'Error in mapbox.
|
|
1386
|
+
CLog(CLogTypes.info, 'Error in mapbox.getUserLocation: ' + ex);
|
|
1313
1387
|
}
|
|
1314
1388
|
reject(ex);
|
|
1315
1389
|
}
|
|
1316
1390
|
});
|
|
1317
1391
|
}
|
|
1318
|
-
|
|
1392
|
+
hideUserLocationMarker(nativeMap) {
|
|
1319
1393
|
return new Promise((resolve, reject) => {
|
|
1320
1394
|
try {
|
|
1321
|
-
const theMap = nativeMap || this._mapboxViewInstance;
|
|
1322
|
-
if (!theMap) {
|
|
1323
|
-
reject('No map has been loaded');
|
|
1324
|
-
return;
|
|
1325
|
-
}
|
|
1326
|
-
theMap['mapOnMoveBeginHandler'] = MapPanHandlerImpl.initWithOwnerAndListenerForMap(new WeakRef(this), listener, theMap);
|
|
1327
|
-
theMap['mapOnMoveBeginHandler'].setOnMoveBegin();
|
|
1328
|
-
for (let i = 0; i < theMap.gestureRecognizers.count; i++) {
|
|
1329
|
-
const recognizer = theMap.gestureRecognizers.objectAtIndex(i);
|
|
1330
|
-
if (recognizer instanceof UIPanGestureRecognizer) {
|
|
1331
|
-
recognizer.addTargetAction(theMap['mapOnMoveBeginHandler'], 'pan');
|
|
1332
|
-
break;
|
|
1333
|
-
}
|
|
1334
|
-
}
|
|
1335
1395
|
resolve();
|
|
1336
1396
|
}
|
|
1337
1397
|
catch (ex) {
|
|
1338
1398
|
if (Trace.isEnabled()) {
|
|
1339
|
-
CLog(CLogTypes.info, 'Error in mapbox.
|
|
1399
|
+
CLog(CLogTypes.info, 'Error in mapbox.getUserLocation: ' + ex);
|
|
1340
1400
|
}
|
|
1341
1401
|
reject(ex);
|
|
1342
1402
|
}
|
|
1343
1403
|
});
|
|
1344
1404
|
}
|
|
1345
|
-
|
|
1346
|
-
return Promise.reject("'setOnFlingListener' is not supported on iOS");
|
|
1347
|
-
}
|
|
1348
|
-
async setOnCameraMoveListener(listener, nativeMap) {
|
|
1349
|
-
const theMap = nativeMap || this._mapboxViewInstance;
|
|
1350
|
-
if (theMap) {
|
|
1351
|
-
theMap.delegate.setCameraChangedListener(listener);
|
|
1352
|
-
}
|
|
1353
|
-
else {
|
|
1354
|
-
return Promise.reject('No map has been loaded');
|
|
1355
|
-
}
|
|
1356
|
-
}
|
|
1357
|
-
setOnCameraMoveCancelListener(listener, nativeMap) {
|
|
1358
|
-
return Promise.reject("'setOnCameraMoveCancelListener' not currently supported on iOS");
|
|
1359
|
-
}
|
|
1360
|
-
async setOnCameraIdleListener(listener, nativeMap) {
|
|
1361
|
-
const theMap = nativeMap || this._mapboxViewInstance;
|
|
1362
|
-
if (theMap) {
|
|
1363
|
-
theMap.delegate.setCameraIdledListener(listener);
|
|
1364
|
-
}
|
|
1365
|
-
else {
|
|
1366
|
-
return Promise.reject('No map has been loaded');
|
|
1367
|
-
}
|
|
1368
|
-
}
|
|
1369
|
-
getViewport(nativeMap) {
|
|
1405
|
+
changeUserLocationMarkerMode(renderModeString, cameraModeString, nativeMap) {
|
|
1370
1406
|
return new Promise((resolve, reject) => {
|
|
1371
1407
|
try {
|
|
1372
1408
|
const theMap = nativeMap || this._mapboxViewInstance;
|
|
1373
|
-
if (
|
|
1374
|
-
|
|
1375
|
-
return;
|
|
1409
|
+
if (Trace.isEnabled()) {
|
|
1410
|
+
CLog(CLogTypes.info, "Mapbox::changeUserLocationMarkerMode(): changing renderMode to '" + renderModeString + "' cameraMode '" + cameraModeString + "'");
|
|
1376
1411
|
}
|
|
1377
|
-
|
|
1378
|
-
const
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
south: visibleBounds.sw.latitude,
|
|
1382
|
-
west: visibleBounds.sw.longitude
|
|
1383
|
-
};
|
|
1384
|
-
resolve({
|
|
1385
|
-
bounds,
|
|
1386
|
-
zoomLevel: theMap.zoomLevel
|
|
1387
|
-
});
|
|
1412
|
+
theMap.userTrackingMode = this._stringToCameraMode(cameraModeString);
|
|
1413
|
+
const delegate = theMap.delegate;
|
|
1414
|
+
const renderMode = this._stringToRenderMode(renderModeString);
|
|
1415
|
+
delegate.changeUserLocationRenderMode(renderMode);
|
|
1388
1416
|
}
|
|
1389
1417
|
catch (ex) {
|
|
1390
1418
|
if (Trace.isEnabled()) {
|
|
1391
|
-
CLog(CLogTypes.info, 'Error in mapbox.
|
|
1419
|
+
CLog(CLogTypes.info, 'Error in mapbox.showUserLocationMarker: ' + ex);
|
|
1392
1420
|
}
|
|
1393
1421
|
reject(ex);
|
|
1394
1422
|
}
|
|
1395
1423
|
});
|
|
1396
1424
|
}
|
|
1397
|
-
|
|
1425
|
+
forceUserLocationUpdate(location, nativeMap) { }
|
|
1426
|
+
queryRenderedFeatures(options, nativeMap) {
|
|
1398
1427
|
return new Promise((resolve, reject) => {
|
|
1399
1428
|
try {
|
|
1400
1429
|
const theMap = nativeMap || this._mapboxViewInstance;
|
|
1401
|
-
if (
|
|
1402
|
-
reject(
|
|
1430
|
+
if (options.point === undefined) {
|
|
1431
|
+
reject("Please set the 'point' parameter");
|
|
1403
1432
|
return;
|
|
1404
1433
|
}
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
};
|
|
1409
|
-
const
|
|
1410
|
-
const
|
|
1411
|
-
theMap.
|
|
1412
|
-
|
|
1434
|
+
if (!options) {
|
|
1435
|
+
options = {};
|
|
1436
|
+
}
|
|
1437
|
+
const { x, y } = theMap.convertCoordinateToPointToView({ latitude: options.point.lat, longitude: options.point.lng }, theMap);
|
|
1438
|
+
const queryLayerIds = options.layers ? NSSet.setWithArray(Utils.ios.collections.jsArrayToNSArray(options.layers)) : null;
|
|
1439
|
+
const queryFilter = options.filter ? ExpressionParser.parseJson(options.filter) : null;
|
|
1440
|
+
const features = theMap.visibleFeaturesAtPointInStyleLayersWithIdentifiersPredicate({ x, y }, queryLayerIds, queryFilter);
|
|
1441
|
+
const result = [];
|
|
1442
|
+
for (let i = 0; i < features.count; i++) {
|
|
1443
|
+
const feature = features.objectAtIndex(i);
|
|
1444
|
+
const featureJson = NSJSONSerialization.dataWithJSONObjectOptionsError(feature.geoJSONDictionary(), 0);
|
|
1445
|
+
result.push(JSON.parse(NSString.alloc().initWithDataEncoding(featureJson, NSUTF8StringEncoding)));
|
|
1446
|
+
}
|
|
1447
|
+
resolve(result);
|
|
1413
1448
|
}
|
|
1414
1449
|
catch (ex) {
|
|
1415
1450
|
if (Trace.isEnabled()) {
|
|
1416
|
-
CLog(CLogTypes.info, 'Error in mapbox.
|
|
1451
|
+
CLog(CLogTypes.info, 'Error in mapbox.queryRenderedFeatures: ' + ex);
|
|
1417
1452
|
}
|
|
1418
1453
|
reject(ex);
|
|
1419
1454
|
}
|
|
1420
1455
|
});
|
|
1421
1456
|
}
|
|
1422
|
-
|
|
1457
|
+
querySourceFeatures(sourceId, options, nativeMap) {
|
|
1423
1458
|
return new Promise((resolve, reject) => {
|
|
1424
1459
|
try {
|
|
1425
|
-
const
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
const bounds = {
|
|
1429
|
-
sw: swCoordinate,
|
|
1430
|
-
ne: neCoordinate
|
|
1431
|
-
};
|
|
1432
|
-
const region = MGLTilePyramidOfflineRegion.alloc().initWithStyleURLBoundsFromZoomLevelToZoomLevel(styleURL, bounds, options.minZoom, options.maxZoom);
|
|
1433
|
-
if (options.accessToken) {
|
|
1434
|
-
MGLAccountManager.accessToken = options.accessToken;
|
|
1460
|
+
const theMap = nativeMap || this._mapboxViewInstance;
|
|
1461
|
+
if (!options) {
|
|
1462
|
+
options = {};
|
|
1435
1463
|
}
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
const offlinePackProgress = offlinePack.progress;
|
|
1440
|
-
const userInfo = NSKeyedUnarchiver.unarchiveObjectWithData(offlinePack.context);
|
|
1441
|
-
const complete = offlinePackProgress.countOfResourcesCompleted === offlinePackProgress.countOfResourcesExpected;
|
|
1442
|
-
options.onProgress({
|
|
1443
|
-
name: userInfo.objectForKey('name'),
|
|
1444
|
-
completed: offlinePackProgress.countOfResourcesCompleted,
|
|
1445
|
-
expected: offlinePackProgress.countOfResourcesExpected,
|
|
1446
|
-
percentage: Math.round((offlinePackProgress.countOfResourcesCompleted / offlinePackProgress.countOfResourcesExpected) * 10000) / 100,
|
|
1447
|
-
complete
|
|
1448
|
-
});
|
|
1449
|
-
if (complete) {
|
|
1450
|
-
resolve();
|
|
1451
|
-
}
|
|
1452
|
-
});
|
|
1464
|
+
const source = theMap.style.sourceWithIdentifier(sourceId);
|
|
1465
|
+
if (!source) {
|
|
1466
|
+
throw new Error(`Source with id "${sourceId}" not found.`);
|
|
1453
1467
|
}
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
});
|
|
1463
|
-
_addObserver(MGLOfflinePackMaximumMapboxTilesReachedNotification, (notification) => {
|
|
1464
|
-
const offlinePack = notification.object;
|
|
1465
|
-
const userInfo = NSKeyedUnarchiver.unarchiveObjectWithData(offlinePack.context);
|
|
1466
|
-
const maximumCount = notification.userInfo[MGLOfflinePackUserInfoKeyMaximumCount];
|
|
1467
|
-
console.log(`Offline region '${userInfo.objectForKey('name')}' reached the tile limit of ${maximumCount}`);
|
|
1468
|
-
});
|
|
1469
|
-
const userInfo = { name: options.name };
|
|
1470
|
-
const context = NSKeyedArchiver.archivedDataWithRootObject(userInfo);
|
|
1471
|
-
MGLOfflineStorage.sharedOfflineStorage.addPackForRegionWithContextCompletionHandler(region, context, (pack, error) => {
|
|
1472
|
-
if (error) {
|
|
1473
|
-
reject(error.localizedFailureReason);
|
|
1474
|
-
}
|
|
1475
|
-
else {
|
|
1476
|
-
pack.resume();
|
|
1468
|
+
let features;
|
|
1469
|
+
const queryFilter = options.filter ? ExpressionParser.parseJson(options.filter) : null;
|
|
1470
|
+
if (source instanceof MGLShapeSource) {
|
|
1471
|
+
features = source.featuresMatchingPredicate(queryFilter);
|
|
1472
|
+
}
|
|
1473
|
+
else if (source instanceof MGLVectorTileSource) {
|
|
1474
|
+
if (!options.sourceLayer) {
|
|
1475
|
+
throw new Error('The option "sourceLayer" is required for vector sources.');
|
|
1477
1476
|
}
|
|
1478
|
-
|
|
1477
|
+
const sourceLayerIds = options.sourceLayer ? NSSet.setWithArray(Utils.ios.collections.jsArrayToNSArray([options.sourceLayer])) : null;
|
|
1478
|
+
features = source.featuresInSourceLayersWithIdentifiersPredicate(sourceLayerIds, queryFilter);
|
|
1479
|
+
}
|
|
1480
|
+
else {
|
|
1481
|
+
throw new Error('Only sources from type "vector" or "geojson" are supported.');
|
|
1482
|
+
}
|
|
1483
|
+
const result = [];
|
|
1484
|
+
for (let i = 0; i < features.count; i++) {
|
|
1485
|
+
const feature = features.objectAtIndex(i);
|
|
1486
|
+
const featureJson = NSJSONSerialization.dataWithJSONObjectOptionsError(feature.geoJSONDictionary(), 0);
|
|
1487
|
+
result.push(JSON.parse(NSString.alloc().initWithDataEncoding(featureJson, NSUTF8StringEncoding)));
|
|
1488
|
+
}
|
|
1489
|
+
resolve(result);
|
|
1479
1490
|
}
|
|
1480
1491
|
catch (ex) {
|
|
1481
1492
|
if (Trace.isEnabled()) {
|
|
1482
|
-
CLog(CLogTypes.info, 'Error in mapbox.
|
|
1493
|
+
CLog(CLogTypes.info, 'Error in mapbox.querySourceFeatures: ' + ex);
|
|
1483
1494
|
}
|
|
1484
1495
|
reject(ex);
|
|
1485
1496
|
}
|
|
1486
1497
|
});
|
|
1487
1498
|
}
|
|
1488
|
-
|
|
1499
|
+
addPolygon(options, nativeMap) {
|
|
1489
1500
|
return new Promise((resolve, reject) => {
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1501
|
+
const theMap = nativeMap || this._mapboxViewInstance;
|
|
1502
|
+
const points = options.points;
|
|
1503
|
+
if (points === undefined) {
|
|
1504
|
+
reject("Please set the 'points' parameter");
|
|
1505
|
+
return;
|
|
1506
|
+
}
|
|
1507
|
+
const coordinateArray = [];
|
|
1508
|
+
points.forEach((point) => coordinateArray.push([point.lng, point.lat]));
|
|
1509
|
+
const polygonID = `polygon_${options.id || new Date().getTime()}`;
|
|
1510
|
+
if (theMap.style.sourceWithIdentifier(polygonID)) {
|
|
1511
|
+
reject("Remove the polygon with this id first with 'removePolygons': " + polygonID);
|
|
1512
|
+
return;
|
|
1513
|
+
}
|
|
1514
|
+
const geoJSON = `{
|
|
1515
|
+
"type": "FeatureCollection",
|
|
1516
|
+
"features": [
|
|
1517
|
+
{
|
|
1518
|
+
"id": ${JSON.stringify(polygonID)},
|
|
1519
|
+
"type": "Feature",
|
|
1520
|
+
"properties": {
|
|
1521
|
+
},
|
|
1522
|
+
"geometry": {
|
|
1523
|
+
"type": "Polygon",
|
|
1524
|
+
"coordinates": [${JSON.stringify(coordinateArray)}]
|
|
1525
|
+
}
|
|
1513
1526
|
}
|
|
1514
|
-
|
|
1527
|
+
]
|
|
1528
|
+
}`;
|
|
1529
|
+
const geoDataStr = NSString.stringWithString(geoJSON);
|
|
1530
|
+
const geoData = geoDataStr.dataUsingEncoding(NSUTF8StringEncoding);
|
|
1531
|
+
const geoDataBase64Enc = geoData.base64EncodedStringWithOptions(0);
|
|
1532
|
+
const geo = NSData.alloc().initWithBase64EncodedStringOptions(geoDataBase64Enc, null);
|
|
1533
|
+
const shape = MGLShape.shapeWithDataEncodingError(geo, NSUTF8StringEncoding);
|
|
1534
|
+
const source = MGLShapeSource.alloc().initWithIdentifierShapeOptions(polygonID, shape, null);
|
|
1535
|
+
theMap.style.addSource(source);
|
|
1536
|
+
if (options.strokeColor || options.strokeWidth || options.strokeOpacity) {
|
|
1537
|
+
const strokeLayer = MGLLineStyleLayer.alloc().initWithIdentifierSource(polygonID + '_stroke', source);
|
|
1538
|
+
strokeLayer.lineColor = NSExpression.expressionForConstantValue(!options.strokeColor ? UIColor.blackColor : options.strokeColor instanceof Color ? options.strokeColor.ios : new Color(options.strokeColor).ios);
|
|
1539
|
+
strokeLayer.lineWidth = NSExpression.expressionForConstantValue(options.strokeWidth || 5);
|
|
1540
|
+
strokeLayer.lineOpacity = NSExpression.expressionForConstantValue(options.strokeOpacity === undefined ? 1 : options.strokeOpacity);
|
|
1541
|
+
theMap.style.addLayer(strokeLayer);
|
|
1542
|
+
}
|
|
1543
|
+
const layer = MGLFillStyleLayer.alloc().initWithIdentifierSource(polygonID, source);
|
|
1544
|
+
layer.fillColor = NSExpression.expressionForConstantValue(!options.fillColor ? UIColor.blackColor : options.fillColor instanceof Color ? options.fillColor.ios : new Color(options.fillColor).ios);
|
|
1545
|
+
layer.fillOpacity = NSExpression.expressionForConstantValue(options.fillOpacity === undefined ? 1 : options.fillOpacity);
|
|
1546
|
+
theMap.style.addLayer(layer);
|
|
1547
|
+
resolve();
|
|
1548
|
+
});
|
|
1549
|
+
}
|
|
1550
|
+
addPolyline(options, nativeMap) {
|
|
1551
|
+
return new Promise((resolve, reject) => {
|
|
1552
|
+
const theMap = nativeMap || this._mapboxViewInstance;
|
|
1553
|
+
const points = options.points;
|
|
1554
|
+
if (points === undefined) {
|
|
1555
|
+
reject("Please set the 'points' parameter");
|
|
1556
|
+
return;
|
|
1515
1557
|
}
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
reject(
|
|
1558
|
+
const coordinateArray = [];
|
|
1559
|
+
points.forEach((point) => coordinateArray.push([point.lng, point.lat]));
|
|
1560
|
+
const polylineID = 'polyline_' + (options.id || new Date().getTime());
|
|
1561
|
+
if (theMap.style.sourceWithIdentifier(polylineID)) {
|
|
1562
|
+
reject("Remove the polyline with this id first with 'removePolylines': " + polylineID);
|
|
1563
|
+
return;
|
|
1521
1564
|
}
|
|
1565
|
+
const geoJSON = `{"type": "FeatureCollection", "features": [{"type": "Feature","properties": {},"geometry": {"type": "LineString", "coordinates": ${JSON.stringify(coordinateArray)}}}]}`;
|
|
1566
|
+
const geoDataStr = NSString.stringWithString(geoJSON);
|
|
1567
|
+
const geoData = geoDataStr.dataUsingEncoding(NSUTF8StringEncoding);
|
|
1568
|
+
const geoDataBase64Enc = geoData.base64EncodedStringWithOptions(0);
|
|
1569
|
+
const geo = NSData.alloc().initWithBase64EncodedStringOptions(geoDataBase64Enc, null);
|
|
1570
|
+
const shape = MGLShape.shapeWithDataEncodingError(geo, NSUTF8StringEncoding);
|
|
1571
|
+
const source = MGLShapeSource.alloc().initWithIdentifierShapeOptions(polylineID, shape, null);
|
|
1572
|
+
theMap.style.addSource(source);
|
|
1573
|
+
const layer = MGLLineStyleLayer.alloc().initWithIdentifierSource(polylineID, source);
|
|
1574
|
+
layer.lineColor = NSExpression.expressionForConstantValue(!options.color ? UIColor.blackColor : options.color instanceof Color ? options.color.ios : new Color(options.color).ios);
|
|
1575
|
+
layer.lineWidth = NSExpression.expressionForConstantValue(options.width || 5);
|
|
1576
|
+
layer.lineOpacity = NSExpression.expressionForConstantValue(options.opacity === undefined ? 1 : options.opacity);
|
|
1577
|
+
theMap.style.addLayer(layer);
|
|
1578
|
+
resolve();
|
|
1522
1579
|
});
|
|
1523
1580
|
}
|
|
1524
|
-
|
|
1581
|
+
removePolyById(theMap, id) {
|
|
1582
|
+
let layer = theMap.style.layerWithIdentifier(id);
|
|
1583
|
+
if (layer !== null) {
|
|
1584
|
+
theMap.style.removeLayer(layer);
|
|
1585
|
+
}
|
|
1586
|
+
layer = theMap.style.layerWithIdentifier(id + '_stroke');
|
|
1587
|
+
if (layer !== null) {
|
|
1588
|
+
theMap.style.removeLayer(layer);
|
|
1589
|
+
}
|
|
1590
|
+
const source = theMap.style.sourceWithIdentifier(id);
|
|
1591
|
+
if (source !== null) {
|
|
1592
|
+
theMap.style.removeSource(source);
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
removePolys(polyType, ids, nativeMap) {
|
|
1596
|
+
return new Promise((resolve) => {
|
|
1597
|
+
const theMap = nativeMap || this._mapboxViewInstance;
|
|
1598
|
+
ids.forEach((id) => this.removePolyById(theMap, polyType + id));
|
|
1599
|
+
resolve();
|
|
1600
|
+
});
|
|
1601
|
+
}
|
|
1602
|
+
removePolygons(ids, nativeMap) {
|
|
1603
|
+
return this.removePolys('polygon_', ids, nativeMap);
|
|
1604
|
+
}
|
|
1605
|
+
removePolylines(ids, nativeMap) {
|
|
1606
|
+
return this.removePolys('polyline_', ids, nativeMap);
|
|
1607
|
+
}
|
|
1608
|
+
animateCamera(options, nativeMap) {
|
|
1525
1609
|
return new Promise((resolve, reject) => {
|
|
1526
1610
|
try {
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1611
|
+
const theMap = nativeMap || this._mapboxViewInstance;
|
|
1612
|
+
let cam;
|
|
1613
|
+
if (options.bounds) {
|
|
1614
|
+
const padding = options.padding || 0;
|
|
1615
|
+
const insets = {
|
|
1616
|
+
top: padding,
|
|
1617
|
+
left: padding,
|
|
1618
|
+
bottom: padding,
|
|
1619
|
+
right: padding
|
|
1620
|
+
};
|
|
1621
|
+
const bounds = {
|
|
1622
|
+
sw: CLLocationCoordinate2DMake(options.bounds.south, options.bounds.west),
|
|
1623
|
+
ne: CLLocationCoordinate2DMake(options.bounds.north, options.bounds.east)
|
|
1624
|
+
};
|
|
1625
|
+
cam = theMap.cameraThatFitsCoordinateBoundsEdgePadding(bounds, insets);
|
|
1530
1626
|
}
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
const name = userInfo.objectForKey('name');
|
|
1537
|
-
if (name === options.name) {
|
|
1538
|
-
found = true;
|
|
1539
|
-
MGLOfflineStorage.sharedOfflineStorage.removePackWithCompletionHandler(pack, (error) => {
|
|
1540
|
-
if (error) {
|
|
1541
|
-
reject(error.localizedFailureReason);
|
|
1542
|
-
}
|
|
1543
|
-
else {
|
|
1544
|
-
resolve();
|
|
1545
|
-
}
|
|
1546
|
-
});
|
|
1627
|
+
else {
|
|
1628
|
+
const target = options.target;
|
|
1629
|
+
if (target === undefined) {
|
|
1630
|
+
reject("Please set the 'target' parameter");
|
|
1631
|
+
return;
|
|
1547
1632
|
}
|
|
1633
|
+
cam = theMap.camera;
|
|
1634
|
+
cam.centerCoordinate = CLLocationCoordinate2DMake(target.lat, target.lng);
|
|
1548
1635
|
}
|
|
1549
|
-
if (
|
|
1550
|
-
|
|
1636
|
+
if (options.altitude) {
|
|
1637
|
+
cam.altitude = options.altitude;
|
|
1638
|
+
}
|
|
1639
|
+
if (options.bearing) {
|
|
1640
|
+
cam.heading = options.bearing;
|
|
1641
|
+
}
|
|
1642
|
+
if (options.tilt) {
|
|
1643
|
+
cam.pitch = options.tilt;
|
|
1551
1644
|
}
|
|
1645
|
+
if (options.zoomLevel && options.target) {
|
|
1646
|
+
cam.altitude = MGLAltitudeForZoomLevel(options.zoomLevel, cam.pitch, options.target.lat, theMap.frame.size);
|
|
1647
|
+
}
|
|
1648
|
+
const durationMs = options.duration ? options.duration : 10000;
|
|
1649
|
+
theMap.setCameraWithDurationAnimationTimingFunction(cam, durationMs / 1000, CAMediaTimingFunction.functionWithName(kCAMediaTimingFunctionEaseInEaseOut));
|
|
1650
|
+
setTimeout(() => {
|
|
1651
|
+
resolve();
|
|
1652
|
+
}, durationMs);
|
|
1552
1653
|
}
|
|
1553
1654
|
catch (ex) {
|
|
1554
1655
|
if (Trace.isEnabled()) {
|
|
1555
|
-
CLog(CLogTypes.info, 'Error in mapbox.
|
|
1656
|
+
CLog(CLogTypes.info, 'Error in mapbox.animateCamera: ' + ex);
|
|
1556
1657
|
}
|
|
1557
1658
|
reject(ex);
|
|
1558
1659
|
}
|
|
1559
1660
|
});
|
|
1560
1661
|
}
|
|
1561
|
-
|
|
1662
|
+
setOnMapClickListener(listener, nativeMap) {
|
|
1562
1663
|
return new Promise((resolve, reject) => {
|
|
1563
1664
|
try {
|
|
1564
1665
|
const theMap = nativeMap || this._mapboxViewInstance;
|
|
@@ -1566,17 +1667,26 @@ export class Mapbox extends MapboxCommon {
|
|
|
1566
1667
|
reject('No map has been loaded');
|
|
1567
1668
|
return;
|
|
1568
1669
|
}
|
|
1670
|
+
theMap['mapTapHandler'] = MapTapHandlerImpl.initWithOwnerAndListenerForMap(new WeakRef(this), listener, theMap);
|
|
1671
|
+
const tapGestureRecognizer = UITapGestureRecognizer.alloc().initWithTargetAction(theMap['mapTapHandler'], 'tap');
|
|
1672
|
+
for (let i = 0; i < theMap.gestureRecognizers.count; i++) {
|
|
1673
|
+
const recognizer = theMap.gestureRecognizers.objectAtIndex(i);
|
|
1674
|
+
if (recognizer instanceof UITapGestureRecognizer) {
|
|
1675
|
+
tapGestureRecognizer.requireGestureRecognizerToFail(recognizer);
|
|
1676
|
+
}
|
|
1677
|
+
}
|
|
1678
|
+
theMap.addGestureRecognizer(tapGestureRecognizer);
|
|
1569
1679
|
resolve();
|
|
1570
1680
|
}
|
|
1571
1681
|
catch (ex) {
|
|
1572
1682
|
if (Trace.isEnabled()) {
|
|
1573
|
-
CLog(CLogTypes.info, 'Error in mapbox.
|
|
1683
|
+
CLog(CLogTypes.info, 'Error in mapbox.setOnMapClickListener: ' + ex);
|
|
1574
1684
|
}
|
|
1575
1685
|
reject(ex);
|
|
1576
1686
|
}
|
|
1577
1687
|
});
|
|
1578
1688
|
}
|
|
1579
|
-
|
|
1689
|
+
setOnMapLongClickListener(listener, nativeMap) {
|
|
1580
1690
|
return new Promise((resolve, reject) => {
|
|
1581
1691
|
try {
|
|
1582
1692
|
const theMap = nativeMap || this._mapboxViewInstance;
|
|
@@ -1584,159 +1694,88 @@ export class Mapbox extends MapboxCommon {
|
|
|
1584
1694
|
reject('No map has been loaded');
|
|
1585
1695
|
return;
|
|
1586
1696
|
}
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
const content = NSString.stringWithString(JSON.stringify(options.data));
|
|
1595
|
-
const nsData = content.dataUsingEncoding(NSUTF8StringEncoding);
|
|
1596
|
-
const geoJsonShape = MGLShape.shapeWithDataEncodingError(nsData, NSUTF8StringEncoding);
|
|
1597
|
-
source.shape = geoJsonShape;
|
|
1598
|
-
break;
|
|
1599
|
-
default:
|
|
1600
|
-
reject('Invalid source type: ' + options['type']);
|
|
1601
|
-
return;
|
|
1697
|
+
theMap['mapLongPressHandler'] = MapLongPressHandlerImpl.initWithOwnerAndListenerForMap(new WeakRef(this), listener, theMap);
|
|
1698
|
+
const longPressGestureRecognizer = UILongPressGestureRecognizer.alloc().initWithTargetAction(theMap['mapLongPressHandler'], 'longPress');
|
|
1699
|
+
for (let i = 0; i < theMap.gestureRecognizers.count; i++) {
|
|
1700
|
+
const recognizer = theMap.gestureRecognizers.objectAtIndex(i);
|
|
1701
|
+
if (recognizer instanceof UILongPressGestureRecognizer) {
|
|
1702
|
+
longPressGestureRecognizer.requireGestureRecognizerToFail(recognizer);
|
|
1703
|
+
}
|
|
1602
1704
|
}
|
|
1705
|
+
theMap.addGestureRecognizer(longPressGestureRecognizer);
|
|
1706
|
+
resolve();
|
|
1603
1707
|
}
|
|
1604
1708
|
catch (ex) {
|
|
1605
1709
|
if (Trace.isEnabled()) {
|
|
1606
|
-
CLog(CLogTypes.info, 'Error in mapbox.
|
|
1710
|
+
CLog(CLogTypes.info, 'Error in mapbox.setOnMapClickListener: ' + ex);
|
|
1607
1711
|
}
|
|
1608
1712
|
reject(ex);
|
|
1609
1713
|
}
|
|
1610
1714
|
});
|
|
1611
1715
|
}
|
|
1612
|
-
|
|
1716
|
+
setOnScrollListener(listener, nativeMap) {
|
|
1613
1717
|
return new Promise((resolve, reject) => {
|
|
1614
1718
|
try {
|
|
1615
1719
|
const theMap = nativeMap || this._mapboxViewInstance;
|
|
1616
|
-
let source;
|
|
1617
1720
|
if (!theMap) {
|
|
1618
1721
|
reject('No map has been loaded');
|
|
1619
1722
|
return;
|
|
1620
1723
|
}
|
|
1621
|
-
if (theMap
|
|
1622
|
-
|
|
1623
|
-
return;
|
|
1724
|
+
if (theMap['mapPanHandler'] === undefined) {
|
|
1725
|
+
theMap['mapPanHandler'] = MapPanHandlerImpl.initWithOwnerAndListenerForMap(new WeakRef(this), listener, 2, theMap);
|
|
1624
1726
|
}
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
if (options.minzoom !== undefined) {
|
|
1633
|
-
sourceOptions[MGLTileSourceOptionMinimumZoomLevel] = options.minzoom;
|
|
1634
|
-
}
|
|
1635
|
-
if (options.maxzoom !== undefined) {
|
|
1636
|
-
sourceOptions[MGLTileSourceOptionMaximumZoomLevel] = options.maxzoom;
|
|
1637
|
-
}
|
|
1638
|
-
if (options.scheme) {
|
|
1639
|
-
switch (options.scheme) {
|
|
1640
|
-
case 'xyz':
|
|
1641
|
-
sourceOptions[MGLTileSourceOptionTileCoordinateSystem] = 0;
|
|
1642
|
-
break;
|
|
1643
|
-
case 'tms':
|
|
1644
|
-
sourceOptions[MGLTileSourceOptionTileCoordinateSystem] = 1;
|
|
1645
|
-
break;
|
|
1646
|
-
default:
|
|
1647
|
-
throw new Error('Unknown raster tile scheme.');
|
|
1648
|
-
}
|
|
1649
|
-
}
|
|
1650
|
-
if (options.bounds) {
|
|
1651
|
-
sourceOptions[MGLTileSourceOptionCoordinateBounds] = NSValue.valueWithMGLCoordinateBounds({
|
|
1652
|
-
sw: CLLocationCoordinate2DMake(options.bounds[1], options.bounds[0]),
|
|
1653
|
-
ne: CLLocationCoordinate2DMake(options.bounds[3], options.bounds[2])
|
|
1654
|
-
});
|
|
1655
|
-
}
|
|
1656
|
-
source = MGLVectorTileSource.alloc().initWithIdentifierTileURLTemplatesOptions(id, options.tiles, sourceOptions);
|
|
1657
|
-
}
|
|
1658
|
-
break;
|
|
1659
|
-
}
|
|
1660
|
-
case 'geojson':
|
|
1661
|
-
if (theMap.style.sourceWithIdentifier(id)) {
|
|
1662
|
-
reject("Remove the layer with this id first with 'removeLayer': " + id);
|
|
1663
|
-
return;
|
|
1664
|
-
}
|
|
1665
|
-
let geoJsonShape;
|
|
1666
|
-
if (options.data) {
|
|
1667
|
-
const content = NSString.stringWithString(JSON.stringify(options.data));
|
|
1668
|
-
const nsData = content.dataUsingEncoding(NSUTF8StringEncoding);
|
|
1669
|
-
geoJsonShape = MGLShape.shapeWithDataEncodingError(nsData, NSUTF8StringEncoding);
|
|
1670
|
-
}
|
|
1671
|
-
const sourceOptions = {};
|
|
1672
|
-
if (options.minzoom !== undefined) {
|
|
1673
|
-
sourceOptions[MGLShapeSourceOptionMinimumZoomLevel] = options.minzoom;
|
|
1674
|
-
}
|
|
1675
|
-
if (options.maxzoom !== undefined) {
|
|
1676
|
-
sourceOptions[MGLShapeSourceOptionMaximumZoomLevel] = options.maxzoom;
|
|
1677
|
-
}
|
|
1678
|
-
if (options.cluster) {
|
|
1679
|
-
sourceOptions[MGLShapeSourceOptionClustered] = true;
|
|
1680
|
-
sourceOptions[MGLShapeSourceOptionClusterRadius] = options.cluster.radius || 40;
|
|
1681
|
-
sourceOptions[MGLShapeSourceOptionMaximumZoomLevelForClustering] = options.cluster.maxZoom || 13;
|
|
1682
|
-
}
|
|
1683
|
-
source = MGLShapeSource.alloc().initWithIdentifierShapeOptions(id, geoJsonShape, sourceOptions);
|
|
1684
|
-
break;
|
|
1685
|
-
case 'raster': {
|
|
1686
|
-
const sourceOptions = {
|
|
1687
|
-
[MGLTileSourceOptionTileSize]: options.tileSize || 256
|
|
1688
|
-
};
|
|
1689
|
-
if (options.minzoom !== undefined) {
|
|
1690
|
-
sourceOptions[MGLTileSourceOptionMinimumZoomLevel] = options.minzoom;
|
|
1691
|
-
}
|
|
1692
|
-
if (options.maxzoom !== undefined) {
|
|
1693
|
-
sourceOptions[MGLTileSourceOptionMaximumZoomLevel] = options.maxzoom;
|
|
1694
|
-
}
|
|
1695
|
-
if (options.scheme) {
|
|
1696
|
-
switch (options.scheme || 'xyz') {
|
|
1697
|
-
case 'xyz':
|
|
1698
|
-
sourceOptions[MGLTileSourceOptionTileCoordinateSystem] = 0;
|
|
1699
|
-
break;
|
|
1700
|
-
case 'tms':
|
|
1701
|
-
sourceOptions[MGLTileSourceOptionTileCoordinateSystem] = 1;
|
|
1702
|
-
break;
|
|
1703
|
-
default:
|
|
1704
|
-
throw new Error('Unknown raster tile scheme.');
|
|
1705
|
-
}
|
|
1706
|
-
}
|
|
1707
|
-
if (options.bounds) {
|
|
1708
|
-
sourceOptions[MGLTileSourceOptionCoordinateBounds] = NSValue.valueWithMGLCoordinateBounds({
|
|
1709
|
-
sw: CLLocationCoordinate2DMake(options.bounds[1], options.bounds[0]),
|
|
1710
|
-
ne: CLLocationCoordinate2DMake(options.bounds[3], options.bounds[2])
|
|
1711
|
-
});
|
|
1712
|
-
}
|
|
1713
|
-
source = MGLRasterTileSource.alloc().initWithIdentifierTileURLTemplatesOptions(id, options.tiles, sourceOptions);
|
|
1727
|
+
else {
|
|
1728
|
+
theMap['mapPanHandler'].addListener(2, listener);
|
|
1729
|
+
}
|
|
1730
|
+
for (let i = 0; i < theMap.gestureRecognizers.count; i++) {
|
|
1731
|
+
const recognizer = theMap.gestureRecognizers.objectAtIndex(i);
|
|
1732
|
+
if (recognizer instanceof UIPanGestureRecognizer) {
|
|
1733
|
+
recognizer.addTargetAction(theMap['mapPanHandler'], 'pan');
|
|
1714
1734
|
break;
|
|
1715
1735
|
}
|
|
1716
|
-
default:
|
|
1717
|
-
reject('Invalid source type: ' + options['type']);
|
|
1718
|
-
return;
|
|
1719
1736
|
}
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1737
|
+
resolve();
|
|
1738
|
+
}
|
|
1739
|
+
catch (ex) {
|
|
1740
|
+
if (Trace.isEnabled()) {
|
|
1741
|
+
CLog(CLogTypes.info, 'Error in mapbox.setOnScrollListener: ' + ex);
|
|
1742
|
+
}
|
|
1743
|
+
reject(ex);
|
|
1744
|
+
}
|
|
1745
|
+
});
|
|
1746
|
+
}
|
|
1747
|
+
setOnMoveBeginListener(listener, nativeMap) {
|
|
1748
|
+
return new Promise((resolve, reject) => {
|
|
1749
|
+
try {
|
|
1750
|
+
const theMap = nativeMap || this._mapboxViewInstance;
|
|
1751
|
+
if (!theMap) {
|
|
1752
|
+
reject('No map has been loaded');
|
|
1726
1753
|
return;
|
|
1727
1754
|
}
|
|
1728
|
-
theMap
|
|
1755
|
+
if (theMap['mapPanHandler'] === undefined) {
|
|
1756
|
+
theMap['mapPanHandler'] = MapPanHandlerImpl.initWithOwnerAndListenerForMap(new WeakRef(this), listener, 1, theMap);
|
|
1757
|
+
}
|
|
1758
|
+
else {
|
|
1759
|
+
theMap['mapPanHandler'].addListener(1, listener);
|
|
1760
|
+
}
|
|
1761
|
+
for (let i = 0; i < theMap.gestureRecognizers.count; i++) {
|
|
1762
|
+
const recognizer = theMap.gestureRecognizers.objectAtIndex(i);
|
|
1763
|
+
if (recognizer instanceof UIPanGestureRecognizer) {
|
|
1764
|
+
recognizer.addTargetAction(theMap['mapPanHandler'], 'panBegin');
|
|
1765
|
+
break;
|
|
1766
|
+
}
|
|
1767
|
+
}
|
|
1729
1768
|
resolve();
|
|
1730
1769
|
}
|
|
1731
1770
|
catch (ex) {
|
|
1732
1771
|
if (Trace.isEnabled()) {
|
|
1733
|
-
CLog(CLogTypes.info, 'Error in mapbox.
|
|
1772
|
+
CLog(CLogTypes.info, 'Error in mapbox.setOnMoveBeginListener: ' + ex);
|
|
1734
1773
|
}
|
|
1735
1774
|
reject(ex);
|
|
1736
1775
|
}
|
|
1737
1776
|
});
|
|
1738
1777
|
}
|
|
1739
|
-
|
|
1778
|
+
setOnMoveEndListener(listener, nativeMap) {
|
|
1740
1779
|
return new Promise((resolve, reject) => {
|
|
1741
1780
|
try {
|
|
1742
1781
|
const theMap = nativeMap || this._mapboxViewInstance;
|
|
@@ -1744,109 +1783,246 @@ export class Mapbox extends MapboxCommon {
|
|
|
1744
1783
|
reject('No map has been loaded');
|
|
1745
1784
|
return;
|
|
1746
1785
|
}
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1786
|
+
if (theMap['mapPanHandler'] === undefined) {
|
|
1787
|
+
theMap['mapPanHandler'] = MapPanHandlerImpl.initWithOwnerAndListenerForMap(new WeakRef(this), listener, 3, theMap);
|
|
1788
|
+
}
|
|
1789
|
+
else {
|
|
1790
|
+
theMap['mapPanHandler'].addListener(3, listener);
|
|
1791
|
+
}
|
|
1792
|
+
for (let i = 0; i < theMap.gestureRecognizers.count; i++) {
|
|
1793
|
+
const recognizer = theMap.gestureRecognizers.objectAtIndex(i);
|
|
1794
|
+
if (recognizer instanceof UIPanGestureRecognizer) {
|
|
1795
|
+
recognizer.addTargetAction(theMap['mapPanHandler'], 'panEnd');
|
|
1796
|
+
break;
|
|
1797
|
+
}
|
|
1751
1798
|
}
|
|
1752
|
-
theMap.style.removeSource(source);
|
|
1753
1799
|
resolve();
|
|
1754
1800
|
}
|
|
1755
1801
|
catch (ex) {
|
|
1756
1802
|
if (Trace.isEnabled()) {
|
|
1757
|
-
CLog(CLogTypes.info, 'Error in mapbox.
|
|
1803
|
+
CLog(CLogTypes.info, 'Error in mapbox.setOnMoveEndListener: ' + ex);
|
|
1758
1804
|
}
|
|
1759
1805
|
reject(ex);
|
|
1760
1806
|
}
|
|
1761
1807
|
});
|
|
1762
1808
|
}
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1809
|
+
setOnFlingListener(listener, nativeMap) {
|
|
1810
|
+
return Promise.reject("'setOnFlingListener' is not supported on iOS");
|
|
1811
|
+
}
|
|
1812
|
+
async setOnCameraMoveListener(listener, nativeMap) {
|
|
1813
|
+
const theMap = nativeMap || this._mapboxViewInstance;
|
|
1814
|
+
if (theMap) {
|
|
1815
|
+
theMap.delegate.setCameraChangedListener(listener);
|
|
1769
1816
|
}
|
|
1770
1817
|
else {
|
|
1771
|
-
|
|
1772
|
-
}
|
|
1773
|
-
const layer = await LayerFactory.createLayer(style, source);
|
|
1774
|
-
if (belowLayerId) {
|
|
1775
|
-
const belowlayer = theMap.style.layerWithIdentifier(belowLayerId);
|
|
1776
|
-
if (belowlayer) {
|
|
1777
|
-
theMap.style.insertLayerBelowLayer(layer.getNativeInstance(), belowlayer);
|
|
1778
|
-
return;
|
|
1779
|
-
}
|
|
1818
|
+
return Promise.reject('No map has been loaded');
|
|
1780
1819
|
}
|
|
1781
|
-
theMap.style.addLayer(layer.getNativeInstance());
|
|
1782
1820
|
}
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
CLog(CLogTypes.info, 'Mapbox:removeLayer(): got layer object: ', layer);
|
|
1791
|
-
}
|
|
1792
|
-
if (!layer) {
|
|
1793
|
-
throw new Error("Layer '" + id + "' not found when attempting to remove it.");
|
|
1821
|
+
setOnCameraMoveCancelListener(listener, nativeMap) {
|
|
1822
|
+
return Promise.reject("'setOnCameraMoveCancelListener' not currently supported on iOS");
|
|
1823
|
+
}
|
|
1824
|
+
async setOnCameraIdleListener(listener, nativeMap) {
|
|
1825
|
+
const theMap = nativeMap || this._mapboxViewInstance;
|
|
1826
|
+
if (theMap) {
|
|
1827
|
+
theMap.delegate.setCameraIdledListener(listener);
|
|
1794
1828
|
}
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
CLog(CLogTypes.info, 'Mapbox:removeLayer(): after removing layer ' + id);
|
|
1829
|
+
else {
|
|
1830
|
+
return Promise.reject('No map has been loaded');
|
|
1798
1831
|
}
|
|
1799
1832
|
}
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1833
|
+
getViewport(nativeMap) {
|
|
1834
|
+
return new Promise((resolve, reject) => {
|
|
1835
|
+
try {
|
|
1836
|
+
const theMap = nativeMap || this._mapboxViewInstance;
|
|
1837
|
+
if (!theMap) {
|
|
1838
|
+
reject('No map has been loaded');
|
|
1839
|
+
return;
|
|
1840
|
+
}
|
|
1841
|
+
const visibleBounds = theMap.visibleCoordinateBounds;
|
|
1842
|
+
const bounds = {
|
|
1843
|
+
north: visibleBounds.ne.latitude,
|
|
1844
|
+
east: visibleBounds.ne.longitude,
|
|
1845
|
+
south: visibleBounds.sw.latitude,
|
|
1846
|
+
west: visibleBounds.sw.longitude
|
|
1847
|
+
};
|
|
1848
|
+
resolve({
|
|
1849
|
+
bounds,
|
|
1850
|
+
zoomLevel: theMap.zoomLevel
|
|
1851
|
+
});
|
|
1852
|
+
}
|
|
1853
|
+
catch (ex) {
|
|
1854
|
+
if (Trace.isEnabled()) {
|
|
1855
|
+
CLog(CLogTypes.info, 'Error in mapbox.getViewport: ' + ex);
|
|
1856
|
+
}
|
|
1857
|
+
reject(ex);
|
|
1858
|
+
}
|
|
1859
|
+
});
|
|
1860
|
+
}
|
|
1861
|
+
setViewport(options, nativeMap) {
|
|
1862
|
+
return new Promise((resolve, reject) => {
|
|
1863
|
+
try {
|
|
1864
|
+
const theMap = nativeMap || this._mapboxViewInstance;
|
|
1865
|
+
if (!theMap) {
|
|
1866
|
+
reject('No map has been loaded');
|
|
1867
|
+
return;
|
|
1868
|
+
}
|
|
1869
|
+
const bounds = {
|
|
1870
|
+
sw: CLLocationCoordinate2DMake(options.bounds.south, options.bounds.west),
|
|
1871
|
+
ne: CLLocationCoordinate2DMake(options.bounds.north, options.bounds.east)
|
|
1872
|
+
};
|
|
1873
|
+
const animated = options.animated === undefined || options.animated;
|
|
1874
|
+
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 };
|
|
1875
|
+
theMap.setVisibleCoordinateBoundsEdgePaddingAnimated(bounds, padding, animated);
|
|
1876
|
+
resolve();
|
|
1877
|
+
}
|
|
1878
|
+
catch (ex) {
|
|
1879
|
+
if (Trace.isEnabled()) {
|
|
1880
|
+
CLog(CLogTypes.info, 'Error in mapbox.setViewport: ' + ex);
|
|
1881
|
+
}
|
|
1882
|
+
reject(ex);
|
|
1883
|
+
}
|
|
1884
|
+
});
|
|
1885
|
+
}
|
|
1886
|
+
downloadOfflineRegion(options) {
|
|
1887
|
+
return new Promise((resolve, reject) => {
|
|
1888
|
+
try {
|
|
1889
|
+
const styleURL = _getMapStyle(options.style);
|
|
1890
|
+
const swCoordinate = CLLocationCoordinate2DMake(options.bounds.south, options.bounds.west);
|
|
1891
|
+
const neCoordinate = CLLocationCoordinate2DMake(options.bounds.north, options.bounds.east);
|
|
1892
|
+
const bounds = {
|
|
1893
|
+
sw: swCoordinate,
|
|
1894
|
+
ne: neCoordinate
|
|
1895
|
+
};
|
|
1896
|
+
const region = MGLTilePyramidOfflineRegion.alloc().initWithStyleURLBoundsFromZoomLevelToZoomLevel(styleURL, bounds, options.minZoom, options.maxZoom);
|
|
1897
|
+
if (options.accessToken) {
|
|
1898
|
+
MGLAccountManager.accessToken = options.accessToken;
|
|
1899
|
+
}
|
|
1900
|
+
if (options.onProgress) {
|
|
1901
|
+
_addObserver(MGLOfflinePackProgressChangedNotification, (notification) => {
|
|
1902
|
+
const offlinePack = notification.object;
|
|
1903
|
+
const offlinePackProgress = offlinePack.progress;
|
|
1904
|
+
const userInfo = NSKeyedUnarchiver.unarchiveObjectWithData(offlinePack.context);
|
|
1905
|
+
const complete = offlinePackProgress.countOfResourcesCompleted === offlinePackProgress.countOfResourcesExpected;
|
|
1906
|
+
options.onProgress({
|
|
1907
|
+
name: userInfo.objectForKey('name'),
|
|
1908
|
+
completed: offlinePackProgress.countOfResourcesCompleted,
|
|
1909
|
+
expected: offlinePackProgress.countOfResourcesExpected,
|
|
1910
|
+
percentage: Math.round((offlinePackProgress.countOfResourcesCompleted / offlinePackProgress.countOfResourcesExpected) * 10000) / 100,
|
|
1911
|
+
complete
|
|
1912
|
+
});
|
|
1913
|
+
if (complete) {
|
|
1914
|
+
resolve();
|
|
1915
|
+
}
|
|
1916
|
+
});
|
|
1917
|
+
}
|
|
1918
|
+
_addObserver(MGLOfflinePackErrorNotification, (notification) => {
|
|
1919
|
+
const offlinePack = notification.object;
|
|
1920
|
+
const userInfo = NSKeyedUnarchiver.unarchiveObjectWithData(offlinePack.context);
|
|
1921
|
+
const error = notification.userInfo[MGLOfflinePackUserInfoKeyError];
|
|
1922
|
+
reject({
|
|
1923
|
+
name: userInfo.objectForKey('name'),
|
|
1924
|
+
error: 'Download error. ' + error
|
|
1925
|
+
});
|
|
1926
|
+
});
|
|
1927
|
+
_addObserver(MGLOfflinePackMaximumMapboxTilesReachedNotification, (notification) => {
|
|
1928
|
+
const offlinePack = notification.object;
|
|
1929
|
+
const userInfo = NSKeyedUnarchiver.unarchiveObjectWithData(offlinePack.context);
|
|
1930
|
+
const maximumCount = notification.userInfo[MGLOfflinePackUserInfoKeyMaximumCount];
|
|
1931
|
+
console.log(`Offline region '${userInfo.objectForKey('name')}' reached the tile limit of ${maximumCount}`);
|
|
1932
|
+
});
|
|
1933
|
+
const userInfo = { name: options.name };
|
|
1934
|
+
const context = NSKeyedArchiver.archivedDataWithRootObject(userInfo);
|
|
1935
|
+
MGLOfflineStorage.sharedOfflineStorage.addPackForRegionWithContextCompletionHandler(region, context, (pack, error) => {
|
|
1936
|
+
if (error) {
|
|
1937
|
+
reject(error.localizedFailureReason);
|
|
1938
|
+
}
|
|
1939
|
+
else {
|
|
1940
|
+
pack.resume();
|
|
1941
|
+
}
|
|
1942
|
+
});
|
|
1943
|
+
}
|
|
1944
|
+
catch (ex) {
|
|
1945
|
+
if (Trace.isEnabled()) {
|
|
1946
|
+
CLog(CLogTypes.info, 'Error in mapbox.downloadOfflineRegion: ' + ex);
|
|
1947
|
+
}
|
|
1948
|
+
reject(ex);
|
|
1949
|
+
}
|
|
1950
|
+
});
|
|
1951
|
+
}
|
|
1952
|
+
listOfflineRegions(options) {
|
|
1953
|
+
return new Promise((resolve, reject) => {
|
|
1954
|
+
try {
|
|
1955
|
+
const packs = MGLOfflineStorage.sharedOfflineStorage.packs;
|
|
1956
|
+
if (!packs) {
|
|
1957
|
+
reject('No packs found or Mapbox not ready yet');
|
|
1958
|
+
return;
|
|
1959
|
+
}
|
|
1960
|
+
const regions = [];
|
|
1961
|
+
for (let i = 0; i < packs.count; i++) {
|
|
1962
|
+
const pack = packs.objectAtIndex(i);
|
|
1963
|
+
const region = pack.region;
|
|
1964
|
+
const userInfo = NSKeyedUnarchiver.unarchiveObjectWithData(pack.context);
|
|
1965
|
+
regions.push({
|
|
1966
|
+
name: userInfo.objectForKey('name'),
|
|
1967
|
+
style: '' + region.styleURL,
|
|
1968
|
+
minZoom: region.minimumZoomLevel,
|
|
1969
|
+
maxZoom: region.maximumZoomLevel,
|
|
1970
|
+
bounds: {
|
|
1971
|
+
north: region.bounds.ne.latitude,
|
|
1972
|
+
east: region.bounds.ne.longitude,
|
|
1973
|
+
south: region.bounds.sw.latitude,
|
|
1974
|
+
west: region.bounds.sw.longitude
|
|
1975
|
+
}
|
|
1976
|
+
});
|
|
1977
|
+
}
|
|
1978
|
+
resolve(regions);
|
|
1979
|
+
}
|
|
1980
|
+
catch (ex) {
|
|
1981
|
+
if (Trace.isEnabled()) {
|
|
1982
|
+
CLog(CLogTypes.info, 'Error in mapbox.listOfflineRegions: ' + ex);
|
|
1983
|
+
}
|
|
1984
|
+
reject(ex);
|
|
1811
1985
|
}
|
|
1812
|
-
|
|
1813
|
-
const newCoord = CLLocationCoordinate2DMake(lnglat[1], lnglat[0]);
|
|
1814
|
-
const newCoordPointer = new interop.Reference(newCoord);
|
|
1815
|
-
lineFeature.appendCoordinatesCount(newCoordPointer, 1);
|
|
1816
|
-
lineSource.shape = lineFeature;
|
|
1817
|
-
}
|
|
1818
|
-
catch (error) {
|
|
1819
|
-
console.log(error);
|
|
1820
|
-
throw error;
|
|
1821
|
-
}
|
|
1822
|
-
}
|
|
1823
|
-
addGeoJsonClustered(options, nativeMapViewInstance) {
|
|
1824
|
-
throw new Error('Method not implemented.');
|
|
1986
|
+
});
|
|
1825
1987
|
}
|
|
1826
|
-
|
|
1988
|
+
deleteOfflineRegion(options) {
|
|
1827
1989
|
return new Promise((resolve, reject) => {
|
|
1828
1990
|
try {
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
reject('No map has been loaded');
|
|
1991
|
+
if (!options || (!options.id && !options.name)) {
|
|
1992
|
+
reject("Pass in the 'id' or 'name' param");
|
|
1832
1993
|
return;
|
|
1833
1994
|
}
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1995
|
+
const packs = MGLOfflineStorage.sharedOfflineStorage.packs;
|
|
1996
|
+
let found = false;
|
|
1997
|
+
for (let i = 0; i < packs.count; i++) {
|
|
1998
|
+
const pack = packs.objectAtIndex(i);
|
|
1999
|
+
const userInfo = NSKeyedUnarchiver.unarchiveObjectWithData(pack.context);
|
|
2000
|
+
const regionId = options.id ? userInfo.objectForKey('id') : userInfo.objectForKey('name');
|
|
2001
|
+
if (regionId === (options.id || options.name)) {
|
|
2002
|
+
found = true;
|
|
2003
|
+
MGLOfflineStorage.sharedOfflineStorage.removePackWithCompletionHandler(pack, (error) => {
|
|
2004
|
+
if (error) {
|
|
2005
|
+
reject(error.localizedFailureReason);
|
|
2006
|
+
}
|
|
2007
|
+
else {
|
|
2008
|
+
resolve();
|
|
2009
|
+
}
|
|
2010
|
+
});
|
|
2011
|
+
}
|
|
2012
|
+
}
|
|
2013
|
+
if (!found) {
|
|
2014
|
+
reject('Region not found');
|
|
1837
2015
|
}
|
|
1838
|
-
theMap.setUserTrackingModeAnimated(_getTrackingMode(options.mode), options.animated !== false);
|
|
1839
|
-
resolve();
|
|
1840
2016
|
}
|
|
1841
2017
|
catch (ex) {
|
|
1842
2018
|
if (Trace.isEnabled()) {
|
|
1843
|
-
CLog(CLogTypes.info, 'Error in mapbox.
|
|
2019
|
+
CLog(CLogTypes.info, 'Error in mapbox.deleteOfflineRegion: ' + ex);
|
|
1844
2020
|
}
|
|
1845
2021
|
reject(ex);
|
|
1846
2022
|
}
|
|
1847
2023
|
});
|
|
1848
2024
|
}
|
|
1849
|
-
|
|
2025
|
+
addExtrusion(options, nativeMap) {
|
|
1850
2026
|
return new Promise((resolve, reject) => {
|
|
1851
2027
|
try {
|
|
1852
2028
|
const theMap = nativeMap || this._mapboxViewInstance;
|
|
@@ -1854,18 +2030,17 @@ export class Mapbox extends MapboxCommon {
|
|
|
1854
2030
|
reject('No map has been loaded');
|
|
1855
2031
|
return;
|
|
1856
2032
|
}
|
|
1857
|
-
|
|
1858
|
-
resolve(new Layer(layer));
|
|
2033
|
+
resolve();
|
|
1859
2034
|
}
|
|
1860
2035
|
catch (ex) {
|
|
1861
2036
|
if (Trace.isEnabled()) {
|
|
1862
|
-
CLog(CLogTypes.info, 'Error in mapbox.
|
|
2037
|
+
CLog(CLogTypes.info, 'Error in mapbox.deleteOfflineRegion: ' + ex);
|
|
1863
2038
|
}
|
|
1864
2039
|
reject(ex);
|
|
1865
2040
|
}
|
|
1866
2041
|
});
|
|
1867
2042
|
}
|
|
1868
|
-
|
|
2043
|
+
updateSource(id, options, nativeMap) {
|
|
1869
2044
|
return new Promise((resolve, reject) => {
|
|
1870
2045
|
try {
|
|
1871
2046
|
const theMap = nativeMap || this._mapboxViewInstance;
|
|
@@ -1873,489 +2048,364 @@ export class Mapbox extends MapboxCommon {
|
|
|
1873
2048
|
reject('No map has been loaded');
|
|
1874
2049
|
return;
|
|
1875
2050
|
}
|
|
1876
|
-
const
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
}
|
|
1881
|
-
resolve(result);
|
|
1882
|
-
}
|
|
1883
|
-
catch (ex) {
|
|
1884
|
-
if (Trace.isEnabled()) {
|
|
1885
|
-
CLog(CLogTypes.info, 'Error in mapbox.getLayers: ' + ex);
|
|
2051
|
+
const source = theMap.style.sourceWithIdentifier(id);
|
|
2052
|
+
if (!source) {
|
|
2053
|
+
reject('Source does not exists: ' + id);
|
|
2054
|
+
return;
|
|
1886
2055
|
}
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
const _addObserver = (eventName, callback) => NSNotificationCenter.defaultCenter.addObserverForNameObjectQueueUsingBlock(eventName, null, NSOperationQueue.mainQueue, callback);
|
|
1898
|
-
function _downloadImage(marker) {
|
|
1899
|
-
return new Promise((resolve, reject) => {
|
|
1900
|
-
if (Trace.isEnabled()) {
|
|
1901
|
-
CLog(CLogTypes.info, '>> _downloadImage');
|
|
1902
|
-
}
|
|
1903
|
-
if (_markerIconDownloadCache[marker.icon]) {
|
|
1904
|
-
marker.iconDownloaded = _markerIconDownloadCache[marker.icon];
|
|
1905
|
-
if (Trace.isEnabled()) {
|
|
1906
|
-
CLog(CLogTypes.info, '>> marker.iconDownloaded: ' + marker.iconDownloaded);
|
|
1907
|
-
}
|
|
1908
|
-
resolve(marker);
|
|
1909
|
-
return;
|
|
1910
|
-
}
|
|
1911
|
-
getImage(marker.icon).then((output) => {
|
|
1912
|
-
marker.iconDownloaded = output.ios;
|
|
1913
|
-
_markerIconDownloadCache[marker.icon] = marker.iconDownloaded;
|
|
1914
|
-
resolve(marker);
|
|
1915
|
-
}, (ignoredError) => {
|
|
1916
|
-
console.log(`Download failed for ${marker.icon} with error: ${ignoredError}`);
|
|
1917
|
-
resolve(marker);
|
|
1918
|
-
});
|
|
1919
|
-
});
|
|
1920
|
-
}
|
|
1921
|
-
const _downloadMarkerImages = (markers) => {
|
|
1922
|
-
const iterations = [];
|
|
1923
|
-
const result = [];
|
|
1924
|
-
markers.forEach((marker) => {
|
|
1925
|
-
if (marker.icon && marker.icon.startsWith('http')) {
|
|
1926
|
-
const p = _downloadImage(marker).then((mark) => result.push(mark));
|
|
1927
|
-
iterations.push(p);
|
|
1928
|
-
}
|
|
1929
|
-
else {
|
|
1930
|
-
result.push(marker);
|
|
1931
|
-
}
|
|
1932
|
-
});
|
|
1933
|
-
return Promise.all(iterations).then(() => result);
|
|
1934
|
-
};
|
|
1935
|
-
var MGLMapViewDelegateImpl = /** @class */ (function (_super) {
|
|
1936
|
-
__extends(MGLMapViewDelegateImpl, _super);
|
|
1937
|
-
function MGLMapViewDelegateImpl() {
|
|
1938
|
-
return _super !== null && _super.apply(this, arguments) || this;
|
|
1939
|
-
}
|
|
1940
|
-
MGLMapViewDelegateImpl.new = function () {
|
|
1941
|
-
return _super.new.call(this);
|
|
1942
|
-
};
|
|
1943
|
-
/**
|
|
1944
|
-
* initialize with the mapReady callback
|
|
1945
|
-
*/
|
|
1946
|
-
MGLMapViewDelegateImpl.prototype.initWithCallback = function (mapLoadedCallback) {
|
|
1947
|
-
if (Trace.isEnabled()) {
|
|
1948
|
-
CLog(CLogTypes.info, 'MGLMapViewDelegateImpl::initWithCallback()');
|
|
1949
|
-
}
|
|
1950
|
-
this.mapLoadedCallback = mapLoadedCallback;
|
|
1951
|
-
return this;
|
|
1952
|
-
};
|
|
1953
|
-
/**
|
|
1954
|
-
* set a reference to the mapboxAPI instance
|
|
1955
|
-
*/
|
|
1956
|
-
MGLMapViewDelegateImpl.prototype.setMapboxApi = function (api) {
|
|
1957
|
-
this.mapboxApi = api;
|
|
1958
|
-
};
|
|
1959
|
-
/**
|
|
1960
|
-
* set the user location click listener callback
|
|
1961
|
-
*/
|
|
1962
|
-
MGLMapViewDelegateImpl.prototype.setUserLocationClickListener = function (callback) {
|
|
1963
|
-
this.userLocationClickListener = callback;
|
|
1964
|
-
};
|
|
1965
|
-
/**
|
|
1966
|
-
* set the user location click listener callback
|
|
1967
|
-
*/
|
|
1968
|
-
MGLMapViewDelegateImpl.prototype.setUserLocationChangedistener = function (callback) {
|
|
1969
|
-
this.userLocationChangedListener = callback;
|
|
1970
|
-
};
|
|
1971
|
-
/**
|
|
1972
|
-
* set user location marker modes
|
|
1973
|
-
*/
|
|
1974
|
-
MGLMapViewDelegateImpl.prototype.changeUserLocationRenderMode = function (userLocationRenderMode) {
|
|
1975
|
-
this.userLocationAnnotationView.changeUserLocationRenderMode(userLocationRenderMode);
|
|
1976
|
-
};
|
|
1977
|
-
/**
|
|
1978
|
-
* set the camera changd listener callback
|
|
1979
|
-
*/
|
|
1980
|
-
MGLMapViewDelegateImpl.prototype.setCameraChangedListener = function (callback) {
|
|
1981
|
-
this.cameraChangedListener = callback;
|
|
1982
|
-
};
|
|
1983
|
-
/**
|
|
1984
|
-
* set the camera idled listener callback
|
|
1985
|
-
*/
|
|
1986
|
-
MGLMapViewDelegateImpl.prototype.setCameraIdledListener = function (callback) {
|
|
1987
|
-
this.cameraIdledListener = callback;
|
|
1988
|
-
};
|
|
1989
|
-
/**
|
|
1990
|
-
* set style loaded callback.
|
|
1991
|
-
*
|
|
1992
|
-
* set an optional callback to be invoked when a style set with
|
|
1993
|
-
* setMapStyle() is finished loading
|
|
1994
|
-
*
|
|
1995
|
-
* @param {function} callback function with loaded style as parameter.
|
|
1996
|
-
*
|
|
1997
|
-
* @see Mapbox:setMapStyle()
|
|
1998
|
-
*/
|
|
1999
|
-
MGLMapViewDelegateImpl.prototype.setStyleLoadedCallback = function (callback) {
|
|
2000
|
-
this.styleLoadedCallback = callback;
|
|
2001
|
-
};
|
|
2002
|
-
/**
|
|
2003
|
-
* map ready callback
|
|
2004
|
-
*/
|
|
2005
|
-
MGLMapViewDelegateImpl.prototype.mapViewDidFinishLoadingMap = function (mapView) {
|
|
2006
|
-
if (Trace.isEnabled()) {
|
|
2007
|
-
CLog(CLogTypes.info, 'MGLMapViewDelegateImpl:mapViewDidFinishLoadingMap(): top');
|
|
2008
|
-
}
|
|
2009
|
-
if (this.mapLoadedCallback !== undefined) {
|
|
2010
|
-
this.mapLoadedCallback(mapView);
|
|
2011
|
-
// this should be fired only once, but it's also fired when the style changes, so just remove the callback
|
|
2012
|
-
this.mapLoadedCallback = undefined;
|
|
2013
|
-
}
|
|
2014
|
-
};
|
|
2015
|
-
MGLMapViewDelegateImpl.prototype.mapViewDidFinishRenderingMapFullyRendered = function (mapView, fullyRendered) {
|
|
2016
|
-
if (Trace.isEnabled()) {
|
|
2017
|
-
CLog(CLogTypes.info, 'MGLMapViewDelegateImpl:mapViewDidFinishRenderingMapFullyRendered(): rendered is:', fullyRendered);
|
|
2018
|
-
}
|
|
2019
|
-
};
|
|
2020
|
-
/**
|
|
2021
|
-
* Callback when the style has been loaded.
|
|
2022
|
-
*
|
|
2023
|
-
* Based on my testing, it looks like this callback is invoked multiple times.
|
|
2024
|
-
*
|
|
2025
|
-
* @see Mapbox:setMapStyle()
|
|
2026
|
-
*
|
|
2027
|
-
* @link https://mapbox.github.io/mapbox-gl-native/macos/0.3.0/Protocols/MGLMapViewDelegate.html#/c:objc(pl)MGLMapViewDelegate(im)mapView:didFinishLoadingStyle:
|
|
2028
|
-
*/
|
|
2029
|
-
MGLMapViewDelegateImpl.prototype.mapViewDidFinishLoadingStyle = function (mapView, style) {
|
|
2030
|
-
if (Trace.isEnabled()) {
|
|
2031
|
-
CLog(CLogTypes.info, 'MGLMapViewDelegateImpl:mapViewDidFinishLoadingStyle(): callback called.');
|
|
2032
|
-
}
|
|
2033
|
-
if (this.styleLoadedCallback !== undefined) {
|
|
2034
|
-
this.styleLoadedCallback(mapView, style);
|
|
2035
|
-
// to avoid multiple calls. This is only invoked from setMapStyle().
|
|
2036
|
-
this.styleLoadedCallback = undefined;
|
|
2037
|
-
}
|
|
2038
|
-
};
|
|
2039
|
-
/**
|
|
2040
|
-
* disable the default user location callout
|
|
2041
|
-
*
|
|
2042
|
-
* This took forever to find. The default iOS click handler for the user location
|
|
2043
|
-
* marker is about useless. It just displays "You Are Here". The examples do not
|
|
2044
|
-
* show how to disable it.
|
|
2045
|
-
*/
|
|
2046
|
-
MGLMapViewDelegateImpl.prototype.mapViewAnnotationCanShowCallout = function (mapView, annotation) {
|
|
2047
|
-
if (annotation.isKindOfClass(MGLUserLocation.class())) {
|
|
2048
|
-
return false;
|
|
2049
|
-
}
|
|
2050
|
-
else {
|
|
2051
|
-
return true;
|
|
2052
|
-
}
|
|
2053
|
-
};
|
|
2054
|
-
MGLMapViewDelegateImpl.prototype.mapViewDidFailLoadingMapWithError = function (mapView, error) {
|
|
2055
|
-
if (Trace.isEnabled()) {
|
|
2056
|
-
CLog(CLogTypes.info, 'mapViewDidFailLoadingMapWithError: ' + error);
|
|
2057
|
-
}
|
|
2058
|
-
};
|
|
2059
|
-
MGLMapViewDelegateImpl.prototype.mapViewDidChangeUserTrackingModeAnimated = function (mapView, mode, animated) {
|
|
2060
|
-
if (Trace.isEnabled()) {
|
|
2061
|
-
CLog(CLogTypes.info, 'mapViewDidChangeUserTrackingModeAnimated: ' + mode);
|
|
2062
|
-
}
|
|
2063
|
-
};
|
|
2064
|
-
/**
|
|
2065
|
-
* fired when the marker icon is about to be rendered - return null for the default icon
|
|
2066
|
-
*/
|
|
2067
|
-
MGLMapViewDelegateImpl.prototype.mapViewImageForAnnotation = function (mapView, annotation) {
|
|
2068
|
-
var cachedMarker = this.getTappedMarkerDetails(annotation);
|
|
2069
|
-
if (cachedMarker) {
|
|
2070
|
-
if (cachedMarker.reuseIdentifier) {
|
|
2071
|
-
var reusedImage = mapView.dequeueReusableAnnotationImageWithIdentifier(cachedMarker.reuseIdentifier);
|
|
2072
|
-
if (reusedImage) {
|
|
2073
|
-
return reusedImage;
|
|
2056
|
+
switch (options.type) {
|
|
2057
|
+
case 'geojson':
|
|
2058
|
+
const content = NSString.stringWithString(JSON.stringify(options.data));
|
|
2059
|
+
const nsData = content.dataUsingEncoding(NSUTF8StringEncoding);
|
|
2060
|
+
const geoJsonShape = MGLShape.shapeWithDataEncodingError(nsData, NSUTF8StringEncoding);
|
|
2061
|
+
source.shape = geoJsonShape;
|
|
2062
|
+
break;
|
|
2063
|
+
default:
|
|
2064
|
+
reject('Invalid source type: ' + options['type']);
|
|
2065
|
+
return;
|
|
2074
2066
|
}
|
|
2075
2067
|
}
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
if (cachedMarker.icon.startsWith('res://')) {
|
|
2080
|
-
var resourceName = cachedMarker.icon.substring('res://'.length);
|
|
2081
|
-
var imageSource = ImageSource.fromResourceSync(resourceName);
|
|
2082
|
-
if (imageSource === null) {
|
|
2083
|
-
console.log("Unable to locate " + resourceName);
|
|
2084
|
-
}
|
|
2085
|
-
else {
|
|
2086
|
-
cachedMarker.reuseIdentifier = cachedMarker.icon;
|
|
2087
|
-
return MGLAnnotationImage.annotationImageWithImageReuseIdentifier(imageSource.ios, cachedMarker.reuseIdentifier);
|
|
2088
|
-
}
|
|
2068
|
+
catch (ex) {
|
|
2069
|
+
if (Trace.isEnabled()) {
|
|
2070
|
+
CLog(CLogTypes.info, 'Error in mapbox.addSource: ' + ex);
|
|
2089
2071
|
}
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2072
|
+
reject(ex);
|
|
2073
|
+
}
|
|
2074
|
+
});
|
|
2075
|
+
}
|
|
2076
|
+
addSource(id, options, nativeMap) {
|
|
2077
|
+
return new Promise((resolve, reject) => {
|
|
2078
|
+
try {
|
|
2079
|
+
const theMap = nativeMap || this._mapboxViewInstance;
|
|
2080
|
+
let source;
|
|
2081
|
+
if (!theMap) {
|
|
2082
|
+
reject('No map has been loaded');
|
|
2083
|
+
return;
|
|
2084
|
+
}
|
|
2085
|
+
if (theMap.style.sourceWithIdentifier(id)) {
|
|
2086
|
+
reject('Source exists: ' + id);
|
|
2087
|
+
return;
|
|
2088
|
+
}
|
|
2089
|
+
switch (options.type) {
|
|
2090
|
+
case 'vector': {
|
|
2091
|
+
if (options.url) {
|
|
2092
|
+
source = MGLVectorTileSource.alloc().initWithIdentifierConfigurationURL(id, NSURL.URLWithString(options.url));
|
|
2093
|
+
}
|
|
2094
|
+
else {
|
|
2095
|
+
const sourceOptions = {};
|
|
2096
|
+
if (options.minzoom !== undefined) {
|
|
2097
|
+
sourceOptions[MGLTileSourceOptionMinimumZoomLevel] = options.minzoom;
|
|
2098
|
+
}
|
|
2099
|
+
if (options.maxzoom !== undefined) {
|
|
2100
|
+
sourceOptions[MGLTileSourceOptionMaximumZoomLevel] = options.maxzoom;
|
|
2101
|
+
}
|
|
2102
|
+
if (options.scheme) {
|
|
2103
|
+
switch (options.scheme) {
|
|
2104
|
+
case 'xyz':
|
|
2105
|
+
sourceOptions[MGLTileSourceOptionTileCoordinateSystem] = 0;
|
|
2106
|
+
break;
|
|
2107
|
+
case 'tms':
|
|
2108
|
+
sourceOptions[MGLTileSourceOptionTileCoordinateSystem] = 1;
|
|
2109
|
+
break;
|
|
2110
|
+
default:
|
|
2111
|
+
throw new Error('Unknown raster tile scheme.');
|
|
2112
|
+
}
|
|
2113
|
+
}
|
|
2114
|
+
if (options.bounds) {
|
|
2115
|
+
sourceOptions[MGLTileSourceOptionCoordinateBounds] = NSValue.valueWithMGLCoordinateBounds({
|
|
2116
|
+
sw: CLLocationCoordinate2DMake(options.bounds[1], options.bounds[0]),
|
|
2117
|
+
ne: CLLocationCoordinate2DMake(options.bounds[3], options.bounds[2])
|
|
2118
|
+
});
|
|
2119
|
+
}
|
|
2120
|
+
source = MGLVectorTileSource.alloc().initWithIdentifierTileURLTemplatesOptions(id, options.tiles, sourceOptions);
|
|
2121
|
+
}
|
|
2122
|
+
break;
|
|
2123
|
+
}
|
|
2124
|
+
case 'geojson':
|
|
2125
|
+
if (theMap.style.sourceWithIdentifier(id)) {
|
|
2126
|
+
reject("Remove the layer with this id first with 'removeLayer': " + id);
|
|
2127
|
+
return;
|
|
2128
|
+
}
|
|
2129
|
+
let geoJsonShape;
|
|
2130
|
+
if (options.data) {
|
|
2131
|
+
const content = NSString.stringWithString(JSON.stringify(options.data));
|
|
2132
|
+
const nsData = content.dataUsingEncoding(NSUTF8StringEncoding);
|
|
2133
|
+
geoJsonShape = MGLShape.shapeWithDataEncodingError(nsData, NSUTF8StringEncoding);
|
|
2134
|
+
}
|
|
2135
|
+
const sourceOptions = {};
|
|
2136
|
+
if (options.minzoom !== undefined) {
|
|
2137
|
+
sourceOptions[MGLShapeSourceOptionMinimumZoomLevel] = options.minzoom;
|
|
2138
|
+
}
|
|
2139
|
+
if (options.maxzoom !== undefined) {
|
|
2140
|
+
sourceOptions[MGLShapeSourceOptionMaximumZoomLevel] = options.maxzoom;
|
|
2141
|
+
}
|
|
2142
|
+
if (options.cluster) {
|
|
2143
|
+
sourceOptions[MGLShapeSourceOptionClustered] = true;
|
|
2144
|
+
sourceOptions[MGLShapeSourceOptionClusterRadius] = options.cluster.radius || 40;
|
|
2145
|
+
sourceOptions[MGLShapeSourceOptionMaximumZoomLevelForClustering] = options.cluster.maxZoom || 13;
|
|
2146
|
+
if (options.cluster.properties) {
|
|
2147
|
+
const clusterProperties = {};
|
|
2148
|
+
for (const property of Object.keys(options.cluster.properties)) {
|
|
2149
|
+
let [operator, operand] = options.cluster.properties[property];
|
|
2150
|
+
if (!Array.isArray(operator)) {
|
|
2151
|
+
operator = [operator];
|
|
2152
|
+
}
|
|
2153
|
+
const expressions = Utils.ios.collections.jsArrayToNSArray([ExpressionParser.parseJson(operator), ExpressionParser.parseJson(operand)]);
|
|
2154
|
+
clusterProperties[property] = expressions;
|
|
2155
|
+
}
|
|
2156
|
+
sourceOptions[MGLShapeSourceOptionClusterProperties] = clusterProperties;
|
|
2157
|
+
}
|
|
2158
|
+
}
|
|
2159
|
+
source = MGLShapeSource.alloc().initWithIdentifierShapeOptions(id, geoJsonShape, sourceOptions);
|
|
2160
|
+
break;
|
|
2161
|
+
case 'raster': {
|
|
2162
|
+
const sourceOptions = {
|
|
2163
|
+
[MGLTileSourceOptionTileSize]: options.tileSize || 256
|
|
2164
|
+
};
|
|
2165
|
+
if (options.minzoom !== undefined) {
|
|
2166
|
+
sourceOptions[MGLTileSourceOptionMinimumZoomLevel] = options.minzoom;
|
|
2167
|
+
}
|
|
2168
|
+
if (options.maxzoom !== undefined) {
|
|
2169
|
+
sourceOptions[MGLTileSourceOptionMaximumZoomLevel] = options.maxzoom;
|
|
2170
|
+
}
|
|
2171
|
+
if (options.scheme) {
|
|
2172
|
+
switch (options.scheme || 'xyz') {
|
|
2173
|
+
case 'xyz':
|
|
2174
|
+
sourceOptions[MGLTileSourceOptionTileCoordinateSystem] = 0;
|
|
2175
|
+
break;
|
|
2176
|
+
case 'tms':
|
|
2177
|
+
sourceOptions[MGLTileSourceOptionTileCoordinateSystem] = 1;
|
|
2178
|
+
break;
|
|
2179
|
+
default:
|
|
2180
|
+
throw new Error('Unknown raster tile scheme.');
|
|
2181
|
+
}
|
|
2182
|
+
}
|
|
2183
|
+
if (options.bounds) {
|
|
2184
|
+
sourceOptions[MGLTileSourceOptionCoordinateBounds] = NSValue.valueWithMGLCoordinateBounds({
|
|
2185
|
+
sw: CLLocationCoordinate2DMake(options.bounds[1], options.bounds[0]),
|
|
2186
|
+
ne: CLLocationCoordinate2DMake(options.bounds[3], options.bounds[2])
|
|
2187
|
+
});
|
|
2188
|
+
}
|
|
2189
|
+
source = MGLRasterTileSource.alloc().initWithIdentifierTileURLTemplatesOptions(id, options.tiles, sourceOptions);
|
|
2190
|
+
break;
|
|
2094
2191
|
}
|
|
2192
|
+
default:
|
|
2193
|
+
reject('Invalid source type: ' + options['type']);
|
|
2194
|
+
return;
|
|
2095
2195
|
}
|
|
2096
|
-
|
|
2196
|
+
if (!source) {
|
|
2197
|
+
const ex = 'No source to add';
|
|
2097
2198
|
if (Trace.isEnabled()) {
|
|
2098
|
-
CLog(CLogTypes.info, '
|
|
2199
|
+
CLog(CLogTypes.info, 'Error in mapbox.addSource: ' + ex);
|
|
2099
2200
|
}
|
|
2201
|
+
reject(ex);
|
|
2202
|
+
return;
|
|
2100
2203
|
}
|
|
2204
|
+
theMap.style.addSource(source);
|
|
2205
|
+
resolve();
|
|
2101
2206
|
}
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
if (File.exists(iconFullPath)) {
|
|
2106
|
-
var image = ImageSource.fromFileSync(iconFullPath).ios;
|
|
2107
|
-
// perhaps add resize options for nice retina rendering (although you can now use the 'icon' param instead)
|
|
2108
|
-
cachedMarker.reuseIdentifier = cachedMarker.iconPath;
|
|
2109
|
-
return MGLAnnotationImage.annotationImageWithImageReuseIdentifier(image, cachedMarker.reuseIdentifier);
|
|
2207
|
+
catch (ex) {
|
|
2208
|
+
if (Trace.isEnabled()) {
|
|
2209
|
+
CLog(CLogTypes.info, 'Error in mapbox.addSource: ' + ex);
|
|
2110
2210
|
}
|
|
2211
|
+
reject(ex);
|
|
2111
2212
|
}
|
|
2112
|
-
}
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2213
|
+
});
|
|
2214
|
+
}
|
|
2215
|
+
removeSource(id, nativeMap) {
|
|
2216
|
+
return new Promise((resolve, reject) => {
|
|
2217
|
+
try {
|
|
2218
|
+
const theMap = nativeMap || this._mapboxViewInstance;
|
|
2219
|
+
if (!theMap) {
|
|
2220
|
+
reject('No map has been loaded');
|
|
2221
|
+
return;
|
|
2222
|
+
}
|
|
2223
|
+
const source = theMap.style.sourceWithIdentifier(id);
|
|
2224
|
+
if (!source) {
|
|
2225
|
+
reject('Source does not exist');
|
|
2226
|
+
return;
|
|
2227
|
+
}
|
|
2228
|
+
theMap.style.removeSource(source);
|
|
2229
|
+
resolve();
|
|
2129
2230
|
}
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2231
|
+
catch (ex) {
|
|
2232
|
+
if (Trace.isEnabled()) {
|
|
2233
|
+
CLog(CLogTypes.info, 'Error in mapbox.removeSource: ' + ex);
|
|
2234
|
+
}
|
|
2235
|
+
reject(ex);
|
|
2133
2236
|
}
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2237
|
+
});
|
|
2238
|
+
}
|
|
2239
|
+
async addLayer(style, belowLayerId, nativeMapView) {
|
|
2240
|
+
const theMap = nativeMapView || this._mapboxViewInstance;
|
|
2241
|
+
let source = null;
|
|
2242
|
+
if (typeof style.source != 'string') {
|
|
2243
|
+
await this.addSource(style.id + '_source', style.source);
|
|
2244
|
+
source = theMap.style.sourceWithIdentifier(style.id + '_source');
|
|
2139
2245
|
}
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
* fired when a callout is tapped
|
|
2143
|
-
*/
|
|
2144
|
-
MGLMapViewDelegateImpl.prototype.mapViewTapOnCalloutForAnnotation = function (mapView, annotation) {
|
|
2145
|
-
var cachedMarker = this.getTappedMarkerDetails(annotation);
|
|
2146
|
-
if (cachedMarker && cachedMarker.onCalloutTap) {
|
|
2147
|
-
cachedMarker.onCalloutTap(cachedMarker);
|
|
2246
|
+
else {
|
|
2247
|
+
source = theMap.style.sourceWithIdentifier(style.source);
|
|
2148
2248
|
}
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
// eslint-disable-next-line eqeqeq
|
|
2156
|
-
cached.lat == tapped.coordinate.latitude &&
|
|
2157
|
-
// eslint-disable-next-line eqeqeq
|
|
2158
|
-
cached.lng == tapped.coordinate.longitude &&
|
|
2159
|
-
// eslint-disable-next-line eqeqeq
|
|
2160
|
-
cached.title == tapped.title &&
|
|
2161
|
-
// eslint-disable-next-line eqeqeq
|
|
2162
|
-
cached.subtitle == tapped.subtitle) {
|
|
2163
|
-
return cached;
|
|
2249
|
+
const layer = await LayerFactory.createLayer(style, source);
|
|
2250
|
+
if (belowLayerId) {
|
|
2251
|
+
const belowlayer = theMap.style.layerWithIdentifier(belowLayerId);
|
|
2252
|
+
if (belowlayer) {
|
|
2253
|
+
theMap.style.insertLayerBelowLayer(layer.getNativeInstance(), belowlayer);
|
|
2254
|
+
return;
|
|
2164
2255
|
}
|
|
2165
2256
|
}
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
CLog(CLogTypes.info, 'MGLMapViewDelegateImpl::mapViewViewForAnnotation() top');
|
|
2173
|
-
}
|
|
2174
|
-
if (annotation.isKindOfClass(MGLUserLocation.class())) {
|
|
2175
|
-
this.userLocationAnnotationView = CustomUserLocationAnnotationView.alloc().init();
|
|
2176
|
-
return this.userLocationAnnotationView;
|
|
2257
|
+
theMap.style.addLayer(layer.getNativeInstance());
|
|
2258
|
+
}
|
|
2259
|
+
async removeLayer(id, nativeMapViewInstance) {
|
|
2260
|
+
const theMap = nativeMapViewInstance || this._mapboxViewInstance;
|
|
2261
|
+
if (Trace.isEnabled()) {
|
|
2262
|
+
CLog(CLogTypes.info, "Mapbox::removeLayer(): attempting to remove layer '" + id + "'");
|
|
2177
2263
|
}
|
|
2178
|
-
|
|
2179
|
-
};
|
|
2180
|
-
MGLMapViewDelegateImpl.prototype.mapViewRegionIsChangingWithReason = function (mapView, reason) {
|
|
2264
|
+
const layer = theMap.style.layerWithIdentifier(id);
|
|
2181
2265
|
if (Trace.isEnabled()) {
|
|
2182
|
-
CLog(CLogTypes.info, '
|
|
2266
|
+
CLog(CLogTypes.info, 'Mapbox:removeLayer(): got layer object: ', layer);
|
|
2183
2267
|
}
|
|
2184
|
-
if (
|
|
2185
|
-
|
|
2268
|
+
if (!layer) {
|
|
2269
|
+
throw new Error("Layer '" + id + "' not found when attempting to remove it.");
|
|
2186
2270
|
}
|
|
2187
|
-
|
|
2188
|
-
MGLMapViewDelegateImpl.prototype.mapViewRegionDidChangeWithReasonAnimated = function (mapView, reason, animated) {
|
|
2271
|
+
theMap.style.removeLayer(layer);
|
|
2189
2272
|
if (Trace.isEnabled()) {
|
|
2190
|
-
CLog(CLogTypes.info, '
|
|
2191
|
-
}
|
|
2192
|
-
if (this.cameraChangedListener) {
|
|
2193
|
-
this.cameraChangedListener(reason, animated);
|
|
2273
|
+
CLog(CLogTypes.info, 'Mapbox:removeLayer(): after removing layer ' + id);
|
|
2194
2274
|
}
|
|
2195
|
-
|
|
2196
|
-
|
|
2275
|
+
}
|
|
2276
|
+
async addLinePoint(id, lnglat, sourceId, nativeMapView) {
|
|
2277
|
+
const theMap = nativeMapView || this._mapboxViewInstance;
|
|
2278
|
+
const sId = !!sourceId ? sourceId : id + '_source';
|
|
2279
|
+
const lineSource = theMap.style.sourceWithIdentifier(sId);
|
|
2280
|
+
if (!lineSource) {
|
|
2281
|
+
throw new Error(`no source found with id: ${sId}`);
|
|
2197
2282
|
}
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2283
|
+
try {
|
|
2284
|
+
const lineFeatures = lineSource.featuresMatchingPredicate(ExpressionParser.parseJson(['==', '$type', 'LineString']));
|
|
2285
|
+
if (lineFeatures.count === 0) {
|
|
2286
|
+
throw new Error('no line string feature found');
|
|
2287
|
+
}
|
|
2288
|
+
const lineFeature = lineFeatures.objectAtIndex(0);
|
|
2289
|
+
const newCoord = CLLocationCoordinate2DMake(lnglat[1], lnglat[0]);
|
|
2290
|
+
const newCoordPointer = new interop.Reference(newCoord);
|
|
2291
|
+
lineFeature.appendCoordinatesCount(newCoordPointer, 1);
|
|
2292
|
+
lineSource.shape = lineFeature;
|
|
2202
2293
|
}
|
|
2203
|
-
|
|
2204
|
-
|
|
2294
|
+
catch (error) {
|
|
2295
|
+
console.log(error);
|
|
2296
|
+
throw error;
|
|
2205
2297
|
}
|
|
2206
|
-
};
|
|
2207
|
-
MGLMapViewDelegateImpl.ObjCProtocols = [MGLMapViewDelegate];
|
|
2208
|
-
return MGLMapViewDelegateImpl;
|
|
2209
|
-
}(NSObject));
|
|
2210
|
-
var MapTapHandlerImpl = /** @class */ (function (_super) {
|
|
2211
|
-
__extends(MapTapHandlerImpl, _super);
|
|
2212
|
-
function MapTapHandlerImpl() {
|
|
2213
|
-
return _super !== null && _super.apply(this, arguments) || this;
|
|
2214
2298
|
}
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
handler._owner = owner;
|
|
2218
|
-
handler._listener = listener;
|
|
2219
|
-
handler._mapView = mapView;
|
|
2220
|
-
return handler;
|
|
2221
|
-
};
|
|
2222
|
-
MapTapHandlerImpl.prototype.tap = function (recognizer) {
|
|
2223
|
-
var tapPoint = recognizer.locationInView(this._mapView);
|
|
2224
|
-
var tapCoordinate = this._mapView.convertPointToCoordinateFromView(tapPoint, this._mapView);
|
|
2225
|
-
this._listener({
|
|
2226
|
-
lat: tapCoordinate.latitude,
|
|
2227
|
-
lng: tapCoordinate.longitude
|
|
2228
|
-
});
|
|
2229
|
-
};
|
|
2230
|
-
MapTapHandlerImpl.ObjCExposedMethods = {
|
|
2231
|
-
tap: { returns: interop.types.void, params: [interop.types.id] }
|
|
2232
|
-
};
|
|
2233
|
-
return MapTapHandlerImpl;
|
|
2234
|
-
}(NSObject));
|
|
2235
|
-
var MapLongPressHandlerImpl = /** @class */ (function (_super) {
|
|
2236
|
-
__extends(MapLongPressHandlerImpl, _super);
|
|
2237
|
-
function MapLongPressHandlerImpl() {
|
|
2238
|
-
return _super !== null && _super.apply(this, arguments) || this;
|
|
2299
|
+
addGeoJsonClustered(options, nativeMapViewInstance) {
|
|
2300
|
+
throw new Error('Method not implemented.');
|
|
2239
2301
|
}
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2302
|
+
trackUser(options, nativeMap) {
|
|
2303
|
+
return new Promise((resolve, reject) => {
|
|
2304
|
+
try {
|
|
2305
|
+
const theMap = nativeMap || this._mapboxViewInstance;
|
|
2306
|
+
if (!theMap) {
|
|
2307
|
+
reject('No map has been loaded');
|
|
2308
|
+
return;
|
|
2309
|
+
}
|
|
2310
|
+
if (!theMap.showsUserLocation) {
|
|
2311
|
+
reject('The map is not currently showing the user location');
|
|
2312
|
+
return;
|
|
2313
|
+
}
|
|
2314
|
+
theMap.setUserTrackingModeAnimated(_getTrackingMode(options.cameraMode), options.animated !== false);
|
|
2315
|
+
resolve();
|
|
2316
|
+
}
|
|
2317
|
+
catch (ex) {
|
|
2318
|
+
if (Trace.isEnabled()) {
|
|
2319
|
+
CLog(CLogTypes.info, 'Error in mapbox.trackUser: ' + ex);
|
|
2320
|
+
}
|
|
2321
|
+
reject(ex);
|
|
2322
|
+
}
|
|
2253
2323
|
});
|
|
2254
|
-
};
|
|
2255
|
-
MapLongPressHandlerImpl.ObjCExposedMethods = {
|
|
2256
|
-
longPress: { returns: interop.types.void, params: [interop.types.id] }
|
|
2257
|
-
};
|
|
2258
|
-
return MapLongPressHandlerImpl;
|
|
2259
|
-
}(NSObject));
|
|
2260
|
-
var MapPanHandlerImpl = /** @class */ (function (_super) {
|
|
2261
|
-
__extends(MapPanHandlerImpl, _super);
|
|
2262
|
-
function MapPanHandlerImpl() {
|
|
2263
|
-
return _super !== null && _super.apply(this, arguments) || this;
|
|
2264
2324
|
}
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
var panPoint = recognizer.locationInView(this._mapView);
|
|
2278
|
-
var panCoordinate = this._mapView.convertPointToCoordinateFromView(panPoint, this._mapView);
|
|
2279
|
-
if (Trace.isEnabled()) {
|
|
2280
|
-
CLog(CLogTypes.info, 'MapPanHandlerImpl::pan(): top with state:', recognizer.state);
|
|
2281
|
-
}
|
|
2282
|
-
// if this is the beginning of the pan simulate the Android onMoveBegin
|
|
2283
|
-
//
|
|
2284
|
-
// See the objc platform declarations in objc!UIKit.d.ts. It doesn't quite match the apple documention
|
|
2285
|
-
if (this.onMoveBegin) {
|
|
2286
|
-
if (recognizer.state === UIGestureRecognizerState.Began) {
|
|
2325
|
+
getLayer(name, nativeMap) {
|
|
2326
|
+
return new Promise((resolve, reject) => {
|
|
2327
|
+
try {
|
|
2328
|
+
const theMap = nativeMap || this._mapboxViewInstance;
|
|
2329
|
+
if (!theMap) {
|
|
2330
|
+
reject('No map has been loaded');
|
|
2331
|
+
return;
|
|
2332
|
+
}
|
|
2333
|
+
const layer = theMap.style.layerWithIdentifier(name);
|
|
2334
|
+
resolve(new Layer(layer));
|
|
2335
|
+
}
|
|
2336
|
+
catch (ex) {
|
|
2287
2337
|
if (Trace.isEnabled()) {
|
|
2288
|
-
CLog(CLogTypes.info, '
|
|
2338
|
+
CLog(CLogTypes.info, 'Error in mapbox.getLayer: ' + ex);
|
|
2289
2339
|
}
|
|
2290
|
-
|
|
2291
|
-
lat: panCoordinate.latitude,
|
|
2292
|
-
lng: panCoordinate.longitude
|
|
2293
|
-
});
|
|
2340
|
+
reject(ex);
|
|
2294
2341
|
}
|
|
2295
|
-
return;
|
|
2296
|
-
}
|
|
2297
|
-
this._listener({
|
|
2298
|
-
lat: panCoordinate.latitude,
|
|
2299
|
-
lng: panCoordinate.longitude
|
|
2300
2342
|
});
|
|
2301
|
-
};
|
|
2302
|
-
MapPanHandlerImpl.ObjCExposedMethods = {
|
|
2303
|
-
pan: { returns: interop.types.void, params: [interop.types.id] }
|
|
2304
|
-
};
|
|
2305
|
-
return MapPanHandlerImpl;
|
|
2306
|
-
}(NSObject));
|
|
2307
|
-
var MapSwipeHandlerImpl = /** @class */ (function (_super) {
|
|
2308
|
-
__extends(MapSwipeHandlerImpl, _super);
|
|
2309
|
-
function MapSwipeHandlerImpl() {
|
|
2310
|
-
return _super !== null && _super.apply(this, arguments) || this;
|
|
2311
2343
|
}
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2344
|
+
getLayers(nativeMap) {
|
|
2345
|
+
return new Promise((resolve, reject) => {
|
|
2346
|
+
try {
|
|
2347
|
+
const theMap = nativeMap || this._mapboxViewInstance;
|
|
2348
|
+
if (!theMap) {
|
|
2349
|
+
reject('No map has been loaded');
|
|
2350
|
+
return;
|
|
2351
|
+
}
|
|
2352
|
+
const layers = theMap.style.layers;
|
|
2353
|
+
const result = [];
|
|
2354
|
+
for (let i = 0; i < layers.count; i++) {
|
|
2355
|
+
result.push(new Layer(layers[i]));
|
|
2356
|
+
}
|
|
2357
|
+
resolve(result);
|
|
2358
|
+
}
|
|
2359
|
+
catch (ex) {
|
|
2360
|
+
if (Trace.isEnabled()) {
|
|
2361
|
+
CLog(CLogTypes.info, 'Error in mapbox.getLayers: ' + ex);
|
|
2362
|
+
}
|
|
2363
|
+
reject(ex);
|
|
2364
|
+
}
|
|
2325
2365
|
});
|
|
2326
|
-
};
|
|
2327
|
-
MapSwipeHandlerImpl.ObjCExposedMethods = {
|
|
2328
|
-
swipe: { returns: interop.types.void, params: [interop.types.id] }
|
|
2329
|
-
};
|
|
2330
|
-
return MapSwipeHandlerImpl;
|
|
2331
|
-
}(NSObject));
|
|
2332
|
-
export class Layer {
|
|
2333
|
-
constructor(instance) {
|
|
2334
|
-
this.instance = instance;
|
|
2335
|
-
this.id = instance.identifier;
|
|
2336
|
-
}
|
|
2337
|
-
visibility() {
|
|
2338
|
-
return this.instance.visible;
|
|
2339
|
-
}
|
|
2340
|
-
show() {
|
|
2341
|
-
this.instance.visible = true;
|
|
2342
2366
|
}
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
return this.instance;
|
|
2367
|
+
project(data) {
|
|
2368
|
+
const theMap = this._mapboxViewInstance;
|
|
2369
|
+
const { x, y } = theMap.convertCoordinateToPointToView({ latitude: data.lat, longitude: data.lng }, theMap);
|
|
2370
|
+
return { x, y };
|
|
2348
2371
|
}
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2372
|
+
}
|
|
2373
|
+
const _addObserver = (eventName, callback) => NSNotificationCenter.defaultCenter.addObserverForNameObjectQueueUsingBlock(eventName, null, NSOperationQueue.mainQueue, callback);
|
|
2374
|
+
function _downloadImage(marker) {
|
|
2375
|
+
return new Promise((resolve, reject) => {
|
|
2376
|
+
if (Trace.isEnabled()) {
|
|
2377
|
+
CLog(CLogTypes.info, '>> _downloadImage');
|
|
2352
2378
|
}
|
|
2353
|
-
|
|
2354
|
-
|
|
2379
|
+
if (_markerIconDownloadCache[marker.icon]) {
|
|
2380
|
+
marker.iconDownloaded = _markerIconDownloadCache[marker.icon];
|
|
2381
|
+
if (Trace.isEnabled()) {
|
|
2382
|
+
CLog(CLogTypes.info, '>> marker.iconDownloaded: ' + marker.iconDownloaded);
|
|
2383
|
+
}
|
|
2384
|
+
resolve(marker);
|
|
2385
|
+
return;
|
|
2355
2386
|
}
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2387
|
+
Http.getImage(marker.icon).then((output) => {
|
|
2388
|
+
marker.iconDownloaded = output.ios;
|
|
2389
|
+
_markerIconDownloadCache[marker.icon] = marker.iconDownloaded;
|
|
2390
|
+
resolve(marker);
|
|
2391
|
+
}, (ignoredError) => {
|
|
2392
|
+
console.log(`Download failed for ${marker.icon} with error: ${ignoredError}`);
|
|
2393
|
+
resolve(marker);
|
|
2394
|
+
});
|
|
2395
|
+
});
|
|
2360
2396
|
}
|
|
2361
|
-
|
|
2397
|
+
const _downloadMarkerImages = (markers) => {
|
|
2398
|
+
const iterations = [];
|
|
2399
|
+
const result = [];
|
|
2400
|
+
markers.forEach((marker) => {
|
|
2401
|
+
if (marker.icon && marker.icon.startsWith('http')) {
|
|
2402
|
+
const p = _downloadImage(marker).then((mark) => result.push(mark));
|
|
2403
|
+
iterations.push(p);
|
|
2404
|
+
}
|
|
2405
|
+
else {
|
|
2406
|
+
result.push(marker);
|
|
2407
|
+
}
|
|
2408
|
+
});
|
|
2409
|
+
return Promise.all(iterations).then(() => result);
|
|
2410
|
+
};
|
|
2411
|
+
//# sourceMappingURL=index.ios.js.map
|