summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabian Guerra <fabian.guerra@mapbox.com>2017-08-23 18:39:14 -0400
committerFabian Guerra <fabian.guerra@mapbox.com>2017-08-23 18:39:14 -0400
commit2b8affc3c76c19ea3f44cabf672c06e158e67b58 (patch)
tree83e7437c12d1d5b3df4b7e8107aeb033a0534fcb
parentf2c9f2bf3695fc30579a40978ebda9d87e4b4bcd (diff)
parentacb8199d326eda02102b2d409ebec510053fec1b (diff)
downloadqtlocation-mapboxgl-upstream/fabian-merge-v3.6.0-branch.tar.gz
Merge branch 'release-ios-v3.6.0-android-v5.1.0' into releaseupstream/fabian-merge-v3.6.0-branch
# Conflicts: # cmake/core-files.cmake # include/mbgl/renderer/renderer_backend.hpp # platform/android/CHANGELOG.md # platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java # platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/IconManager.java # platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java # platform/darwin/src/MGLStyle.mm # platform/ios/CHANGELOG.md # platform/ios/app/Info.plist # platform/ios/app/MBXViewController.m # platform/ios/ios.xcodeproj/project.pbxproj # platform/macos/CHANGELOG.md # src/mbgl/gl/attribute.cpp # src/mbgl/gl/attribute.hpp # src/mbgl/gl/context.hpp # src/mbgl/gl/types.hpp # src/mbgl/gl/value.cpp # src/mbgl/gl/value.hpp # src/mbgl/map/backend_scope.cpp # src/mbgl/programs/attributes.hpp # src/mbgl/programs/program.hpp # src/mbgl/programs/segment.cpp # src/mbgl/programs/segment.hpp # src/mbgl/programs/symbol_program.hpp # src/mbgl/programs/uniforms.hpp # src/mbgl/renderer/buckets/symbol_bucket.hpp # src/mbgl/renderer/painter.cpp # src/mbgl/renderer/painter.hpp # src/mbgl/renderer/painter_background.cpp # src/mbgl/renderer/painter_circle.cpp # src/mbgl/renderer/painter_clipping.cpp # src/mbgl/renderer/painter_debug.cpp # src/mbgl/renderer/painter_fill.cpp # src/mbgl/renderer/painter_fill_extrusion.cpp # src/mbgl/renderer/painter_line.cpp # src/mbgl/renderer/painter_raster.cpp # src/mbgl/renderer/painter_symbol.cpp # src/mbgl/shaders/line.cpp # src/mbgl/shaders/line_pattern.cpp # test/renderer/backend_scope.test.cpp
-rw-r--r--platform/android/MapboxGLAndroidSDK/gradle.properties2
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java471
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/IconManager.java52
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java202
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/values-fr/strings.xml15
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/resources/fabric/com.mapbox.mapboxsdk.mapbox-android-sdk.properties2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_check_box.xml9
-rw-r--r--platform/android/dependencies.gradle4
-rw-r--r--platform/darwin/docs/guides/Working with GeoJSON Data.md6
-rw-r--r--platform/darwin/resources/fr.lproj/Foundation.strings291
-rw-r--r--platform/darwin/src/MGLFeature.h14
-rw-r--r--platform/darwin/src/MGLFeature.mm49
-rw-r--r--platform/darwin/src/MGLPolygon.mm10
-rw-r--r--platform/darwin/src/MGLPolyline.h14
-rw-r--r--platform/darwin/src/MGLPolyline.mm10
-rw-r--r--platform/darwin/src/MGLSource.mm5
-rw-r--r--platform/darwin/src/MGLSource_Private.h2
-rw-r--r--platform/darwin/src/MGLStyle.h15
-rw-r--r--platform/darwin/src/MGLStyle.mm265
-rw-r--r--platform/darwin/src/MGLVectorSource+MGLAdditions.h (renamed from platform/macos/app/MGLVectorSource+MBXAdditions.h)2
-rw-r--r--platform/darwin/src/MGLVectorSource+MGLAdditions.m (renamed from platform/macos/app/MGLVectorSource+MBXAdditions.m)4
-rw-r--r--platform/darwin/test/MGLDocumentationExampleTests.swift12
-rw-r--r--platform/ios/CHANGELOG.md17
-rw-r--r--platform/ios/Mapbox-iOS-SDK-nightly-dynamic.podspec2
-rw-r--r--platform/ios/Mapbox-iOS-SDK-symbols.podspec2
-rw-r--r--platform/ios/Mapbox-iOS-SDK.podspec2
-rw-r--r--platform/ios/app/Assets.xcassets/settings.imageset/Contents.json15
-rw-r--r--platform/ios/app/Assets.xcassets/settings.imageset/settings.pdfbin0 -> 9177 bytes
-rw-r--r--platform/ios/app/Assets.xcassets/settings.imageset/settings.pngbin528 -> 0 bytes
-rw-r--r--platform/ios/app/Assets.xcassets/settings.imageset/settings@2x.pngbin1130 -> 0 bytes
-rw-r--r--platform/ios/app/Default-568h@2x.pngbin18594 -> 0 bytes
-rw-r--r--platform/ios/app/Info.plist11
-rw-r--r--platform/ios/app/LaunchScreen.storyboard14
-rw-r--r--platform/ios/app/MBXAppDelegate.m18
-rw-r--r--platform/ios/app/MBXViewController.m299
-rw-r--r--platform/ios/docs/doc-README.md2
-rw-r--r--platform/ios/docs/pod-README.md2
-rw-r--r--platform/ios/framework/Settings.bundle/hu.lproj/Root.strings3
-rw-r--r--platform/ios/ios.xcodeproj/project.pbxproj68
-rw-r--r--platform/ios/resources/fr.lproj/Localizable.strings18
-rwxr-xr-xplatform/ios/scripts/package.sh38
-rw-r--r--platform/ios/src/MGLFaux3DUserLocationAnnotationView.m7
-rw-r--r--platform/ios/src/MGLMapView.h42
-rw-r--r--platform/ios/src/MGLMapView.mm109
-rw-r--r--platform/macos/CHANGELOG.md7
-rw-r--r--platform/macos/app/MapDocument.m49
-rw-r--r--platform/macos/macos.xcodeproj/project.pbxproj16
-rw-r--r--platform/macos/sdk/fr.lproj/Localizable.strings14
48 files changed, 1493 insertions, 718 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/gradle.properties b/platform/android/MapboxGLAndroidSDK/gradle.properties
index ff6e2f61df..db0c9047e3 100644
--- a/platform/android/MapboxGLAndroidSDK/gradle.properties
+++ b/platform/android/MapboxGLAndroidSDK/gradle.properties
@@ -1,5 +1,5 @@
GROUP=com.mapbox.mapboxsdk
-VERSION_NAME=5.2.0-SNAPSHOT
+VERSION_NAME=5.1.4-SNAPSHOT
POM_DESCRIPTION=Mapbox GL Android SDK
POM_URL=https://github.com/mapbox/mapbox-gl-native
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java
index c09c926eb5..d15d5eddf8 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java
@@ -14,6 +14,7 @@ import com.mapbox.mapboxsdk.R;
import com.mapbox.mapboxsdk.annotations.Annotation;
import com.mapbox.mapboxsdk.annotations.BaseMarkerOptions;
import com.mapbox.mapboxsdk.annotations.BaseMarkerViewOptions;
+import com.mapbox.mapboxsdk.annotations.Icon;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerView;
import com.mapbox.mapboxsdk.annotations.MarkerViewManager;
@@ -44,11 +45,12 @@ class AnnotationManager {
private static final String LAYER_ID_SHAPE_ANNOTATIONS = "com.mapbox.annotations.shape.";
private static final long NO_ANNOTATION_ID = -1;
+ private final NativeMapView nativeMapView;
private final MapView mapView;
private final IconManager iconManager;
private final InfoWindowManager infoWindowManager = new InfoWindowManager();
private final MarkerViewManager markerViewManager;
- private final LongSparseArray<Annotation> annotationsArray;
+ private final LongSparseArray<Annotation> annotations = new LongSparseArray<>();
private final List<Marker> selectedMarkers = new ArrayList<>();
private final List<String> shapeAnnotationIds = new ArrayList<>();
@@ -57,22 +59,11 @@ class AnnotationManager {
private MapboxMap.OnPolygonClickListener onPolygonClickListener;
private MapboxMap.OnPolylineClickListener onPolylineClickListener;
- private Annotations annotations;
- private Markers markers;
- private Polygons polygons;
- private Polylines polylines;
-
- AnnotationManager(NativeMapView view, MapView mapView, LongSparseArray<Annotation> annotationsArray,
- MarkerViewManager markerViewManager, IconManager iconManager, Annotations annotations,
- Markers markers, Polygons polygons, Polylines polylines) {
+ AnnotationManager(NativeMapView view, MapView mapView, MarkerViewManager markerViewManager) {
+ this.nativeMapView = view;
this.mapView = mapView;
- this.annotationsArray = annotationsArray;
+ this.iconManager = new IconManager(nativeMapView);
this.markerViewManager = markerViewManager;
- this.iconManager = iconManager;
- this.annotations = annotations;
- this.markers = markers;
- this.polygons = polygons;
- this.polylines = polylines;
if (view != null) {
// null checking needed for unit tests
view.addOnMapChangedListener(markerViewManager);
@@ -97,15 +88,15 @@ class AnnotationManager {
//
Annotation getAnnotation(long id) {
- return annotations.obtainBy(id);
+ return annotations.get(id);
}
List<Annotation> getAnnotations() {
- return annotations.obtainAll();
- }
-
- void removeAnnotation(long id) {
- annotations.removeBy(id);
+ List<Annotation> annotations = new ArrayList<>();
+ for (int i = 0; i < this.annotations.size(); i++) {
+ annotations.add(this.annotations.get(this.annotations.keyAt(i)));
+ }
+ return annotations;
}
void removeAnnotation(@NonNull Annotation annotation) {
@@ -118,19 +109,30 @@ class AnnotationManager {
if (marker instanceof MarkerView) {
markerViewManager.removeMarkerView((MarkerView) marker);
- } else {
- // do icon cleanup
- iconManager.iconCleanup(marker.getIcon());
}
} else {
// instanceOf Polygon/Polyline
shapeAnnotationIds.remove(annotation.getId());
}
- annotations.removeBy(annotation);
+ long id = annotation.getId();
+ if (nativeMapView != null) {
+ nativeMapView.removeAnnotation(id);
+ }
+ annotations.remove(id);
+ }
+
+ void removeAnnotation(long id) {
+ if (nativeMapView != null) {
+ nativeMapView.removeAnnotation(id);
+ }
+ annotations.remove(id);
}
void removeAnnotations(@NonNull List<? extends Annotation> annotationList) {
- for (Annotation annotation : annotationList) {
+ int count = annotationList.size();
+ long[] ids = new long[count];
+ for (int i = 0; i < count; i++) {
+ Annotation annotation = annotationList.get(i);
if (annotation instanceof Marker) {
Marker marker = (Marker) annotation;
marker.hideInfoWindow();
@@ -140,39 +142,48 @@ class AnnotationManager {
if (marker instanceof MarkerView) {
markerViewManager.removeMarkerView((MarkerView) marker);
- } else {
- iconManager.iconCleanup(marker.getIcon());
}
} else {
// instanceOf Polygon/Polyline
shapeAnnotationIds.remove(annotation.getId());
}
+ ids[i] = annotationList.get(i).getId();
+ }
+
+ if (nativeMapView != null) {
+ nativeMapView.removeAnnotations(ids);
+ }
+
+ for (long id : ids) {
+ annotations.remove(id);
}
- annotations.removeBy(annotationList);
}
void removeAnnotations() {
Annotation annotation;
- int count = annotationsArray.size();
+ int count = annotations.size();
long[] ids = new long[count];
selectedMarkers.clear();
for (int i = 0; i < count; i++) {
- ids[i] = annotationsArray.keyAt(i);
- annotation = annotationsArray.get(ids[i]);
+ ids[i] = annotations.keyAt(i);
+ annotation = annotations.get(ids[i]);
if (annotation instanceof Marker) {
Marker marker = (Marker) annotation;
marker.hideInfoWindow();
if (marker instanceof MarkerView) {
markerViewManager.removeMarkerView((MarkerView) marker);
- } else {
- iconManager.iconCleanup(marker.getIcon());
}
} else {
// instanceOf Polygon/Polyline
shapeAnnotationIds.remove(annotation.getId());
}
}
- annotations.removeAll();
+
+ if (nativeMapView != null) {
+ nativeMapView.removeAnnotations(ids);
+ }
+
+ annotations.clear();
}
//
@@ -180,109 +191,134 @@ class AnnotationManager {
//
Marker addMarker(@NonNull BaseMarkerOptions markerOptions, @NonNull MapboxMap mapboxMap) {
- return markers.addBy(markerOptions, mapboxMap);
+ Marker marker = prepareMarker(markerOptions);
+ long id = nativeMapView != null ? nativeMapView.addMarker(marker) : 0;
+ marker.setMapboxMap(mapboxMap);
+ marker.setId(id);
+ annotations.put(id, marker);
+ return marker;
}
List<Marker> addMarkers(@NonNull List<? extends BaseMarkerOptions> markerOptionsList, @NonNull MapboxMap mapboxMap) {
- return markers.addBy(markerOptionsList, mapboxMap);
- }
+ int count = markerOptionsList.size();
+ List<Marker> markers = new ArrayList<>(count);
+ if (count > 0) {
+ BaseMarkerOptions markerOptions;
+ Marker marker;
+ for (int i = 0; i < count; i++) {
+ markerOptions = markerOptionsList.get(i);
+ marker = prepareMarker(markerOptions);
+ markers.add(marker);
+ }
- void updateMarker(@NonNull Marker updatedMarker, @NonNull MapboxMap mapboxMap) {
- if (!isAddedToMap(updatedMarker)) {
- logNonAdded(updatedMarker);
- return;
- }
- markers.update(updatedMarker, mapboxMap);
- }
+ if (markers.size() > 0) {
+ long[] ids;
+ if (nativeMapView != null) {
+ ids = nativeMapView.addMarkers(markers);
+ } else {
+ ids = new long[markers.size()];
+ }
- List<Marker> getMarkers() {
- return markers.obtainAll();
+ long id;
+ Marker m;
+ for (int i = 0; i < ids.length; i++) {
+ m = markers.get(i);
+ m.setMapboxMap(mapboxMap);
+ id = ids[i];
+ m.setId(id);
+ annotations.put(id, m);
+ }
+
+ }
+ }
+ return markers;
}
- @NonNull
- List<Marker> getMarkersInRect(@NonNull RectF rectangle) {
- return markers.obtainAllIn(rectangle);
+ private Marker prepareMarker(BaseMarkerOptions markerOptions) {
+ Marker marker = markerOptions.getMarker();
+ Icon icon = iconManager.loadIconForMarker(marker);
+ marker.setTopOffsetPixels(iconManager.getTopOffsetPixelsForIcon(icon));
+ return marker;
}
MarkerView addMarker(@NonNull BaseMarkerViewOptions markerOptions, @NonNull MapboxMap mapboxMap,
@Nullable MarkerViewManager.OnMarkerViewAddedListener onMarkerViewAddedListener) {
- return markers.addViewBy(markerOptions, mapboxMap, onMarkerViewAddedListener);
- }
+ final MarkerView marker = prepareViewMarker(markerOptions);
- List<MarkerView> addMarkerViews(@NonNull List<? extends BaseMarkerViewOptions> markerViewOptions,
- @NonNull MapboxMap mapboxMap) {
- return markers.addViewsBy(markerViewOptions, mapboxMap);
- }
-
- List<MarkerView> getMarkerViewsInRect(@NonNull RectF rectangle) {
- return markers.obtainViewsIn(rectangle);
- }
+ // add marker to map
+ marker.setMapboxMap(mapboxMap);
+ long id = nativeMapView.addMarker(marker);
+ marker.setId(id);
+ annotations.put(id, marker);
- void reloadMarkers() {
- markers.reload();
+ if (onMarkerViewAddedListener != null) {
+ markerViewManager.addOnMarkerViewAddedListener(marker, onMarkerViewAddedListener);
+ }
+ markerViewManager.setEnabled(true);
+ markerViewManager.setWaitingForRenderInvoke(true);
+ return marker;
}
- //
- // Polygons
- //
-
- Polygon addPolygon(@NonNull PolygonOptions polygonOptions, @NonNull MapboxMap mapboxMap) {
- Polygon polygon = polygons.addBy(polygonOptions, mapboxMap);
- shapeAnnotationIds.add(LAYER_ID_SHAPE_ANNOTATIONS + polygon.getId());
- return polygon;
+ List<MarkerView> addMarkerViews(@NonNull List<? extends BaseMarkerViewOptions> markerViewOptions,
+ @NonNull MapboxMap mapboxMap) {
+ List<MarkerView> markers = new ArrayList<>();
+ for (BaseMarkerViewOptions markerViewOption : markerViewOptions) {
+ // if last marker
+ if (markerViewOptions.indexOf(markerViewOption) == markerViewOptions.size() - 1) {
+ // get notified when render occurs to invalidate and draw MarkerViews
+ markerViewManager.setWaitingForRenderInvoke(true);
+ }
+ // add marker to map
+ MarkerView marker = prepareViewMarker(markerViewOption);
+ marker.setMapboxMap(mapboxMap);
+ long id = nativeMapView.addMarker(marker);
+ marker.setId(id);
+ annotations.put(id, marker);
+ markers.add(marker);
+ }
+ markerViewManager.setEnabled(true);
+ markerViewManager.update();
+ return markers;
}
- List<Polygon> addPolygons(@NonNull List<PolygonOptions> polygonOptionsList, @NonNull MapboxMap mapboxMap) {
- List<Polygon> polygonList = polygons.addBy(polygonOptionsList, mapboxMap);
- for (Polygon polygon : polygonList) {
- shapeAnnotationIds.add(LAYER_ID_SHAPE_ANNOTATIONS + polygon.getId());
- }
- return polygonList;
+ private MarkerView prepareViewMarker(BaseMarkerViewOptions markerViewOptions) {
+ MarkerView marker = markerViewOptions.getMarker();
+ iconManager.loadIconForMarkerView(marker);
+ return marker;
}
- void updatePolygon(Polygon polygon) {
- if (!isAddedToMap(polygon)) {
- logNonAdded(polygon);
+ void updateMarker(@NonNull Marker updatedMarker) {
+ if (!isAddedToMap(updatedMarker)) {
+ Timber.w("Attempting to update non-added Marker with value %s", updatedMarker);
return;
}
- polygons.update(polygon);
+ ensureIconLoaded(updatedMarker);
+ nativeMapView.updateMarker(updatedMarker);
+ annotations.setValueAt(annotations.indexOfKey(updatedMarker.getId()), updatedMarker);
}
- List<Polygon> getPolygons() {
- return polygons.obtainAll();
- }
-
- //
- // Polylines
- //
-
- Polyline addPolyline(@NonNull PolylineOptions polylineOptions, @NonNull MapboxMap mapboxMap) {
- Polyline polyline = polylines.addBy(polylineOptions, mapboxMap);
- shapeAnnotationIds.add(LAYER_ID_SHAPE_ANNOTATIONS + polyline.getId());
- return polyline;
+ private boolean isAddedToMap(Annotation annotation) {
+ return annotation != null && annotation.getId() != -1 && annotations.indexOfKey(annotation.getId()) > -1;
}
- List<Polyline> addPolylines(@NonNull List<PolylineOptions> polylineOptionsList, @NonNull MapboxMap mapboxMap) {
- List<Polyline> polylineList = polylines.addBy(polylineOptionsList, mapboxMap);
- for (Polyline polyline : polylineList) {
- shapeAnnotationIds.add(LAYER_ID_SHAPE_ANNOTATIONS + polyline.getId());
+ private void ensureIconLoaded(Marker marker) {
+ if (!(marker instanceof MarkerView)) {
+ iconManager.ensureIconLoaded(marker, mapboxMap);
}
- return polylineList;
}
- void updatePolyline(Polyline polyline) {
- if (!isAddedToMap(polyline)) {
- logNonAdded(polyline);
- return;
+ List<Marker> getMarkers() {
+ List<Marker> markers = new ArrayList<>();
+ Annotation annotation;
+ for (int i = 0; i < annotations.size(); i++) {
+ annotation = annotations.get(annotations.keyAt(i));
+ if (annotation instanceof Marker) {
+ markers.add((Marker) annotation);
+ }
}
- polylines.update(polyline);
+ return markers;
}
- List<Polyline> getPolylines() {
- return polylines.obtainAll();
- }
-
- // TODO Refactor from here still in progress
void setOnMarkerClickListener(@Nullable MapboxMap.OnMarkerClickListener listener) {
onMarkerClickListener = listener;
}
@@ -357,6 +393,205 @@ class AnnotationManager {
return selectedMarkers;
}
+ @NonNull
+ List<Marker> getMarkersInRect(@NonNull RectF rectangle) {
+ // convert Rectangle to be density dependent
+ float pixelRatio = nativeMapView.getPixelRatio();
+ RectF rect = new RectF(rectangle.left / pixelRatio,
+ rectangle.top / pixelRatio,
+ rectangle.right / pixelRatio,
+ rectangle.bottom / pixelRatio);
+
+ long[] ids = nativeMapView.queryPointAnnotations(rect);
+
+ List<Long> idsList = new ArrayList<>(ids.length);
+ for (long id : ids) {
+ idsList.add(id);
+ }
+
+ List<Marker> annotations = new ArrayList<>(ids.length);
+ List<Annotation> annotationList = getAnnotations();
+ int count = annotationList.size();
+ for (int i = 0; i < count; i++) {
+ Annotation annotation = annotationList.get(i);
+ if (annotation instanceof com.mapbox.mapboxsdk.annotations.Marker && idsList.contains(annotation.getId())) {
+ annotations.add((com.mapbox.mapboxsdk.annotations.Marker) annotation);
+ }
+ }
+
+ return new ArrayList<>(annotations);
+ }
+
+ List<MarkerView> getMarkerViewsInRect(@NonNull RectF rectangle) {
+ float pixelRatio = nativeMapView.getPixelRatio();
+ RectF rect = new RectF(rectangle.left / pixelRatio,
+ rectangle.top / pixelRatio,
+ rectangle.right / pixelRatio,
+ rectangle.bottom / pixelRatio);
+
+ long[] ids = nativeMapView.queryPointAnnotations(rect);
+
+ List<Long> idsList = new ArrayList<>(ids.length);
+ for (long id : ids) {
+ idsList.add(id);
+ }
+
+ List<MarkerView> annotations = new ArrayList<>(ids.length);
+ List<Annotation> annotationList = getAnnotations();
+ int count = annotationList.size();
+ for (int i = 0; i < count; i++) {
+ Annotation annotation = annotationList.get(i);
+ if (annotation instanceof MarkerView && idsList.contains(annotation.getId())) {
+ annotations.add((MarkerView) annotation);
+ }
+ }
+
+ return new ArrayList<>(annotations);
+ }
+
+ //
+ // Polygons
+ //
+
+ Polygon addPolygon(@NonNull PolygonOptions polygonOptions, @NonNull MapboxMap mapboxMap) {
+ Polygon polygon = polygonOptions.getPolygon();
+ if (!polygon.getPoints().isEmpty()) {
+ long id = nativeMapView != null ? nativeMapView.addPolygon(polygon) : 0;
+ polygon.setId(id);
+ polygon.setMapboxMap(mapboxMap);
+ shapeAnnotationIds.add(LAYER_ID_SHAPE_ANNOTATIONS + id);
+ annotations.put(id, polygon);
+ }
+ return polygon;
+ }
+
+ List<Polygon> addPolygons(@NonNull List<PolygonOptions> polygonOptionsList, @NonNull MapboxMap mapboxMap) {
+ int count = polygonOptionsList.size();
+
+ Polygon polygon;
+ List<Polygon> polygons = new ArrayList<>(count);
+ if (count > 0) {
+ for (PolygonOptions polygonOptions : polygonOptionsList) {
+ polygon = polygonOptions.getPolygon();
+ if (!polygon.getPoints().isEmpty()) {
+ polygons.add(polygon);
+ }
+ }
+
+ long[] ids;
+ if (nativeMapView != null) {
+ ids = nativeMapView.addPolygons(polygons);
+ } else {
+ ids = new long[polygons.size()];
+ }
+
+ long id;
+ for (int i = 0; i < ids.length; i++) {
+ polygon = polygons.get(i);
+ polygon.setMapboxMap(mapboxMap);
+ id = ids[i];
+ polygon.setId(id);
+ shapeAnnotationIds.add(LAYER_ID_SHAPE_ANNOTATIONS + id);
+ annotations.put(id, polygon);
+ }
+ }
+ return polygons;
+ }
+
+ void updatePolygon(@NonNull Polygon polygon) {
+ if (!isAddedToMap(polygon)) {
+ Timber.w("Attempting to update non-added Polygon with value %s", polygon);
+ return;
+ }
+
+ nativeMapView.updatePolygon(polygon);
+ annotations.setValueAt(annotations.indexOfKey(polygon.getId()), polygon);
+ }
+
+ List<Polygon> getPolygons() {
+ List<Polygon> polygons = new ArrayList<>();
+ Annotation annotation;
+ for (int i = 0; i < annotations.size(); i++) {
+ annotation = annotations.get(annotations.keyAt(i));
+ if (annotation instanceof Polygon) {
+ polygons.add((Polygon) annotation);
+ }
+ }
+ return polygons;
+ }
+
+ //
+ // Polylines
+ //
+
+ Polyline addPolyline(@NonNull PolylineOptions polylineOptions, @NonNull MapboxMap mapboxMap) {
+ Polyline polyline = polylineOptions.getPolyline();
+ if (!polyline.getPoints().isEmpty()) {
+ long id = nativeMapView != null ? nativeMapView.addPolyline(polyline) : 0;
+ polyline.setMapboxMap(mapboxMap);
+ polyline.setId(id);
+ shapeAnnotationIds.add(LAYER_ID_SHAPE_ANNOTATIONS + id);
+ annotations.put(id, polyline);
+ }
+ return polyline;
+ }
+
+ List<Polyline> addPolylines(@NonNull List<PolylineOptions> polylineOptionsList, @NonNull MapboxMap mapboxMap) {
+ int count = polylineOptionsList.size();
+ Polyline polyline;
+ List<Polyline> polylines = new ArrayList<>(count);
+
+ if (count > 0) {
+ for (PolylineOptions options : polylineOptionsList) {
+ polyline = options.getPolyline();
+ if (!polyline.getPoints().isEmpty()) {
+ polylines.add(polyline);
+ }
+ }
+
+ long[] ids;
+ if (nativeMapView != null) {
+ ids = nativeMapView.addPolylines(polylines);
+ } else {
+ ids = new long[polylines.size()];
+ }
+
+ long id;
+ Polyline p;
+ for (int i = 0; i < ids.length; i++) {
+ p = polylines.get(i);
+ p.setMapboxMap(mapboxMap);
+ id = ids[i];
+ p.setId(id);
+ shapeAnnotationIds.add(LAYER_ID_SHAPE_ANNOTATIONS + id);
+ annotations.put(id, p);
+ }
+ }
+ return polylines;
+ }
+
+ void updatePolyline(@NonNull Polyline polyline) {
+ if (!isAddedToMap(polyline)) {
+ Timber.w("Attempting to update non-added Polyline with value %s", polyline);
+ return;
+ }
+
+ nativeMapView.updatePolyline(polyline);
+ annotations.setValueAt(annotations.indexOfKey(polyline.getId()), polyline);
+ }
+
+ List<Polyline> getPolylines() {
+ List<Polyline> polylines = new ArrayList<>();
+ Annotation annotation;
+ for (int i = 0; i < annotations.size(); i++) {
+ annotation = annotations.get(annotations.keyAt(i));
+ if (annotation instanceof Polyline) {
+ polylines.add((Polyline) annotation);
+ }
+ }
+ return polylines;
+ }
+
InfoWindowManager getInfoWindowManager() {
return infoWindowManager;
}
@@ -366,9 +601,9 @@ class AnnotationManager {
}
void adjustTopOffsetPixels(MapboxMap mapboxMap) {
- int count = annotationsArray.size();
+ int count = annotations.size();
for (int i = 0; i < count; i++) {
- Annotation annotation = annotationsArray.get(i);
+ Annotation annotation = annotations.get(i);
if (annotation instanceof Marker) {
Marker marker = (Marker) annotation;
marker.setTopOffsetPixels(
@@ -384,12 +619,18 @@ class AnnotationManager {
}
}
- private boolean isAddedToMap(Annotation annotation) {
- return annotation != null && annotation.getId() != -1 && annotationsArray.indexOfKey(annotation.getId()) > -1;
- }
-
- private void logNonAdded(Annotation annotation) {
- Timber.w("Attempting to update non-added %s with value %s", annotation.getClass().getCanonicalName(), annotation);
+ void reloadMarkers() {
+ iconManager.reloadIcons();
+ int count = annotations.size();
+ for (int i = 0; i < count; i++) {
+ Annotation annotation = annotations.get(i);
+ if (annotation instanceof Marker) {
+ Marker marker = (Marker) annotation;
+ nativeMapView.removeAnnotation(annotation.getId());
+ long newId = nativeMapView.addMarker(marker);
+ marker.setId(newId);
+ }
+ }
}
//
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/IconManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/IconManager.java
index affbf48267..18eecfd9c3 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/IconManager.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/IconManager.java
@@ -1,17 +1,16 @@
package com.mapbox.mapboxsdk.maps;
import android.graphics.Bitmap;
-import android.os.Build;
import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.annotations.Icon;
import com.mapbox.mapboxsdk.annotations.IconFactory;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerView;
+import com.mapbox.mapboxsdk.exceptions.IconBitmapChangedException;
-import java.util.HashMap;
+import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
/**
* Responsible for managing icons added to the Map.
@@ -26,14 +25,15 @@ import java.util.Map;
*/
class IconManager {
- private final Map<Icon, Integer> iconMap = new HashMap<>();
-
private NativeMapView nativeMapView;
+ private List<Icon> icons;
+
private int highestIconWidth;
private int highestIconHeight;
IconManager(NativeMapView nativeMapView) {
this.nativeMapView = nativeMapView;
+ this.icons = new ArrayList<>();
// load transparent icon for MarkerView to trace actual markers, see #6352
loadIcon(IconFactory.recreate(IconFactory.ICON_MARKERVIEW_ID, IconFactory.ICON_MARKERVIEW_BITMAP));
}
@@ -83,13 +83,13 @@ class IconManager {
}
private void addIcon(Icon icon, boolean addIconToMap) {
- if (!iconMap.keySet().contains(icon)) {
- iconMap.put(icon, 1);
+ if (!icons.contains(icon)) {
+ icons.add(icon);
if (addIconToMap) {
loadIcon(icon);
}
} else {
- iconMap.put(icon, iconMap.get(icon) + 1);
+ validateIconChanged(icon);
}
}
@@ -121,11 +121,18 @@ class IconManager {
}
void reloadIcons() {
- for (Icon icon : iconMap.keySet()) {
+ for (Icon icon : icons) {
loadIcon(icon);
}
}
+ private void validateIconChanged(Icon icon) {
+ Icon oldIcon = icons.get(icons.indexOf(icon));
+ if (!oldIcon.getBitmap().sameAs(icon.getBitmap())) {
+ throw new IconBitmapChangedException();
+ }
+ }
+
void ensureIconLoaded(Marker marker, MapboxMap mapboxMap) {
Icon icon = marker.getIcon();
if (icon == null) {
@@ -142,31 +149,4 @@ class IconManager {
marker.setTopOffsetPixels(getTopOffsetPixelsForIcon(icon));
}
}
-
- public void iconCleanup(Icon icon) {
- int refCounter = iconMap.get(icon) - 1;
- if (refCounter == 0) {
- remove(icon);
- } else {
- updateIconRefCounter(icon, refCounter);
- }
- }
-
- private void remove(Icon icon) {
- nativeMapView.removeAnnotationIcon(icon.getId());
- iconMap.remove(icon);
- if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- recycleBitmap(icon.getBitmap());
- }
- }
-
- private void updateIconRefCounter(Icon icon, int refCounter) {
- iconMap.put(icon, refCounter);
- }
-
- private void recycleBitmap(Bitmap bitmap) {
- if (!bitmap.isRecycled()) {
- bitmap.recycle();
- }
- }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java
index 0d1d0e03b5..e074d938fd 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java
@@ -59,7 +59,6 @@ import timber.log.Timber;
* Note: Similar to a View object, a MapboxMap should only be read and modified from the main thread.
* </p>
*/
-@UiThread
public final class MapboxMap {
private final NativeMapView nativeMapView;
@@ -100,7 +99,6 @@ public final class MapboxMap {
setDebugActive(options.getDebugActive());
setApiBaseUrl(options);
setStyleUrl(options);
- setPrefetchesTiles(options);
}
/**
@@ -211,6 +209,7 @@ public final class MapboxMap {
*
* @return Duration in milliseconds
*/
+ @UiThread
public long getTransitionDuration() {
return nativeMapView.getTransitionDuration();
}
@@ -220,6 +219,7 @@ public final class MapboxMap {
*
* @param durationMs Duration in milliseconds
*/
+ @UiThread
public void setTransitionDuration(long durationMs) {
nativeMapView.setTransitionDuration(durationMs);
}
@@ -232,6 +232,7 @@ public final class MapboxMap {
*
* @return Delay in milliseconds
*/
+ @UiThread
public long getTransitionDelay() {
return nativeMapView.getTransitionDelay();
}
@@ -241,44 +242,17 @@ public final class MapboxMap {
*
* @param delayMs Delay in milliseconds
*/
+ @UiThread
public void setTransitionDelay(long delayMs) {
nativeMapView.setTransitionDelay(delayMs);
}
/**
- * Sets tile pre-fetching from MapboxOptions.
- *
- * @param options the options object
- */
- private void setPrefetchesTiles(@NonNull MapboxMapOptions options) {
- setPrefetchesTiles(options.getPrefetchesTiles());
- }
-
- /**
- * Enable or disable tile pre-fetching. Pre-fetching makes sure that a low-resolution
- * tile is rendered as soon as possible at the expense of a little bandwidth.
- *
- * @param enable true to enable
- */
- public void setPrefetchesTiles(boolean enable) {
- nativeMapView.setPrefetchesTiles(enable);
- }
-
- /**
- * Check whether tile pre-fetching is enabled or not.
- *
- * @return true if enabled
- * @see MapboxMap#setPrefetchesTiles(boolean)
- */
- public boolean getPrefetchesTiles() {
- return nativeMapView.getPrefetchesTiles();
- }
-
- /**
* Retrieve all the layers in the style
*
* @return all the layers in the current style
*/
+ @UiThread
public List<Layer> getLayers() {
return nativeMapView.getLayers();
}
@@ -290,6 +264,7 @@ public final class MapboxMap {
* @return the layer, if present in the style
*/
@Nullable
+ @UiThread
public Layer getLayer(@NonNull String layerId) {
return nativeMapView.getLayer(layerId);
}
@@ -302,12 +277,13 @@ public final class MapboxMap {
* @return the casted Layer, null if another type
*/
@Nullable
+ @UiThread
public <T extends Layer> T getLayerAs(@NonNull String layerId) {
try {
// noinspection unchecked
return (T) nativeMapView.getLayer(layerId);
} catch (ClassCastException exception) {
- Timber.e(exception, "Layer: %s is a different type: ", layerId);
+ Timber.e(String.format("Layer: %s is a different type: %s", layerId, exception));
return null;
}
}
@@ -317,6 +293,7 @@ public final class MapboxMap {
*
* @param layer the layer to add
*/
+ @UiThread
public void addLayer(@NonNull Layer layer) {
nativeMapView.addLayer(layer);
}
@@ -327,6 +304,7 @@ public final class MapboxMap {
* @param layer the layer to add
* @param below the layer id to add this layer before
*/
+ @UiThread
public void addLayerBelow(@NonNull Layer layer, @NonNull String below) {
nativeMapView.addLayerBelow(layer, below);
}
@@ -337,6 +315,7 @@ public final class MapboxMap {
* @param layer the layer to add
* @param above the layer id to add this layer above
*/
+ @UiThread
public void addLayerAbove(@NonNull Layer layer, @NonNull String above) {
nativeMapView.addLayerAbove(layer, above);
}
@@ -348,6 +327,7 @@ public final class MapboxMap {
* @param layer the layer to add
* @param index the index to insert the layer at
*/
+ @UiThread
public void addLayerAt(@NonNull Layer layer, @IntRange(from = 0) int index) {
nativeMapView.addLayerAt(layer, index);
}
@@ -358,6 +338,7 @@ public final class MapboxMap {
* @param layerId the layer to remove
* @return the removed layer or null if not found
*/
+ @UiThread
@Nullable
public Layer removeLayer(@NonNull String layerId) {
return nativeMapView.removeLayer(layerId);
@@ -369,6 +350,7 @@ public final class MapboxMap {
* @param layer the layer to remove
* @return the layer
*/
+ @UiThread
@Nullable
public Layer removeLayer(@NonNull Layer layer) {
return nativeMapView.removeLayer(layer);
@@ -380,6 +362,7 @@ public final class MapboxMap {
* @param index the layer index
* @return the removed layer or null if not found
*/
+ @UiThread
@Nullable
public Layer removeLayerAt(@IntRange(from = 0) int index) {
return nativeMapView.removeLayerAt(index);
@@ -390,6 +373,7 @@ public final class MapboxMap {
*
* @return all the sources in the current style
*/
+ @UiThread
public List<Source> getSources() {
return nativeMapView.getSources();
}
@@ -401,6 +385,7 @@ public final class MapboxMap {
* @return the source if present in the current style
*/
@Nullable
+ @UiThread
public Source getSource(@NonNull String sourceId) {
return nativeMapView.getSource(sourceId);
}
@@ -413,12 +398,13 @@ public final class MapboxMap {
* @return the casted Source, null if another type
*/
@Nullable
+ @UiThread
public <T extends Source> T getSourceAs(@NonNull String sourceId) {
try {
// noinspection unchecked
return (T) nativeMapView.getSource(sourceId);
} catch (ClassCastException exception) {
- Timber.e(exception, "Source: %s is a different type: ", sourceId);
+ Timber.e(String.format("Source: %s is a different type: %s", sourceId, exception));
return null;
}
}
@@ -428,6 +414,7 @@ public final class MapboxMap {
*
* @param source the source to add
*/
+ @UiThread
public void addSource(@NonNull Source source) {
nativeMapView.addSource(source);
}
@@ -438,6 +425,7 @@ public final class MapboxMap {
* @param sourceId the source to remove
* @return the source handle or null if the source was not present
*/
+ @UiThread
@Nullable
public Source removeSource(@NonNull String sourceId) {
return nativeMapView.removeSource(sourceId);
@@ -449,6 +437,7 @@ public final class MapboxMap {
* @param source the source to remove
* @return the source
*/
+ @UiThread
@Nullable
public Source removeSource(@NonNull Source source) {
return nativeMapView.removeSource(source);
@@ -460,6 +449,7 @@ public final class MapboxMap {
* @param name the name of the image
* @param image the pre-multiplied Bitmap
*/
+ @UiThread
public void addImage(@NonNull String name, @NonNull Bitmap image) {
nativeMapView.addImage(name, image);
}
@@ -469,14 +459,11 @@ public final class MapboxMap {
*
* @param name the name of the image to remove
*/
+ @UiThread
public void removeImage(String name) {
nativeMapView.removeImage(name);
}
- public Bitmap getImage(@NonNull String name) {
- return nativeMapView.getImage(name);
- }
-
//
// MinZoom
//
@@ -488,6 +475,7 @@ public final class MapboxMap {
*
* @param minZoom The new minimum zoom level.
*/
+ @UiThread
public void setMinZoomPreference(
@FloatRange(from = MapboxConstants.MINIMUM_ZOOM, to = MapboxConstants.MAXIMUM_ZOOM) double minZoom) {
transform.setMinZoom(minZoom);
@@ -495,11 +483,12 @@ public final class MapboxMap {
/**
* <p>
- * Gets the minimum zoom level the map can be displayed at.
+ * Gets the maximum zoom level the map can be displayed at.
* </p>
*
* @return The minimum zoom level.
*/
+ @UiThread
public double getMinZoomLevel() {
return transform.getMinZoom();
}
@@ -512,11 +501,10 @@ public final class MapboxMap {
* <p>
* Sets the maximum zoom level the map can be displayed at.
* </p>
- * <p>
- * The default maximum zoomn level is 22. The upper bound for this value is 25.5.
- * </p>
+ *
* @param maxZoom The new maximum zoom level.
*/
+ @UiThread
public void setMaxZoomPreference(@FloatRange(from = MapboxConstants.MINIMUM_ZOOM,
to = MapboxConstants.MAXIMUM_ZOOM) double maxZoom) {
transform.setMaxZoom(maxZoom);
@@ -529,6 +517,7 @@ public final class MapboxMap {
*
* @return The maximum zoom level.
*/
+ @UiThread
public double getMaxZoomLevel() {
return transform.getMaxZoom();
}
@@ -554,10 +543,7 @@ public final class MapboxMap {
* Gets the tracking interface settings for the map.
*
* @return the TrackingSettings asssociated with this map
- * @deprecated use location layer plugin from
- * https://github.com/mapbox/mapbox-plugins-android/tree/master/plugins/locationlayer instead.
*/
- @Deprecated
public TrackingSettings getTrackingSettings() {
return trackingSettings;
}
@@ -570,10 +556,7 @@ public final class MapboxMap {
* Gets the settings of the user location for the map.
*
* @return the MyLocationViewSettings associated with this map
- * @deprecated use location layer plugin from
- * https://github.com/mapbox/mapbox-plugins-android/tree/master/plugins/locationlayer instead.
*/
- @Deprecated
public MyLocationViewSettings getMyLocationViewSettings() {
return myLocationViewSettings;
}
@@ -649,6 +632,7 @@ public final class MapboxMap {
*
* @param update The change that should be applied to the camera.
*/
+ @UiThread
public final void moveCamera(CameraUpdate update) {
moveCamera(update, null);
}
@@ -661,6 +645,7 @@ public final class MapboxMap {
* @param update The change that should be applied to the camera
* @param callback the callback to be invoked when an animation finishes or is canceled
*/
+ @UiThread
public final void moveCamera(final CameraUpdate update, final MapboxMap.CancelableCallback callback) {
new Handler().post(new Runnable() {
@Override
@@ -681,6 +666,7 @@ public final class MapboxMap {
* @param update The change that should be applied to the camera.
* @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates.
*/
+ @UiThread
public final void easeCamera(CameraUpdate update) {
easeCamera(update, MapboxConstants.ANIMATION_DURATION);
}
@@ -695,6 +681,7 @@ public final class MapboxMap {
* positive, otherwise an IllegalArgumentException will be thrown.
* @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates.
*/
+ @UiThread
public final void easeCamera(CameraUpdate update, int durationMs) {
easeCamera(update, durationMs, null);
}
@@ -718,6 +705,7 @@ public final class MapboxMap {
* Do not update or ease the camera from within onCancel().
* @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates.
*/
+ @UiThread
public final void easeCamera(CameraUpdate update, int durationMs, final MapboxMap.CancelableCallback callback) {
easeCamera(update, durationMs, true, callback);
}
@@ -736,6 +724,7 @@ public final class MapboxMap {
* positive, otherwise an IllegalArgumentException will be thrown.
* @param easingInterpolator True for easing interpolator, false for linear.
*/
+ @UiThread
public final void easeCamera(CameraUpdate update, int durationMs, boolean easingInterpolator) {
easeCamera(update, durationMs, easingInterpolator, null);
}
@@ -761,6 +750,7 @@ public final class MapboxMap {
* by a later camera movement or a user gesture, onCancel() will be called.
* Do not update or ease the camera from within onCancel().
*/
+ @UiThread
public final void easeCamera(final CameraUpdate update, final int durationMs, final boolean easingInterpolator,
final MapboxMap.CancelableCallback callback) {
easeCamera(update, durationMs, easingInterpolator, callback, false);
@@ -788,6 +778,7 @@ public final class MapboxMap {
* Do not update or ease the camera from within onCancel().
* @param isDismissable true will allow animated camera changes dismiss a tracking mode.
*/
+ @UiThread
public final void easeCamera(final CameraUpdate update, final int durationMs, final boolean easingInterpolator,
final MapboxMap.CancelableCallback callback, final boolean isDismissable) {
new Handler().post(new Runnable() {
@@ -807,6 +798,7 @@ public final class MapboxMap {
* @param update The change that should be applied to the camera.
* @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates.
*/
+ @UiThread
public final void animateCamera(CameraUpdate update) {
animateCamera(update, MapboxConstants.ANIMATION_DURATION, null);
}
@@ -823,6 +815,7 @@ public final class MapboxMap {
* called. Do not update or animate the camera from within onCancel().
* @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates.
*/
+ @UiThread
public final void animateCamera(CameraUpdate update, MapboxMap.CancelableCallback callback) {
animateCamera(update, MapboxConstants.ANIMATION_DURATION, callback);
}
@@ -838,6 +831,7 @@ public final class MapboxMap {
* positive, otherwise an IllegalArgumentException will be thrown.
* @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates.
*/
+ @UiThread
public final void animateCamera(CameraUpdate update, int durationMs) {
animateCamera(update, durationMs, null);
}
@@ -860,6 +854,7 @@ public final class MapboxMap {
* isn't required, leave it as null.
* @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates.
*/
+ @UiThread
public final void animateCamera(final CameraUpdate update, final int durationMs,
final MapboxMap.CancelableCallback callback) {
new Handler().post(new Runnable() {
@@ -930,6 +925,7 @@ public final class MapboxMap {
*
* @return If true, map debug information is currently shown.
*/
+ @UiThread
public boolean isDebugActive() {
return nativeMapView.getDebug();
}
@@ -942,6 +938,7 @@ public final class MapboxMap {
*
* @param debugActive If true, map debug information is shown.
*/
+ @UiThread
public void setDebugActive(boolean debugActive) {
nativeMapView.setDebug(debugActive);
}
@@ -955,6 +952,7 @@ public final class MapboxMap {
*
* @see #isDebugActive()
*/
+ @UiThread
public void cycleDebugOptions() {
nativeMapView.cycleDebugOptions();
}
@@ -1004,6 +1002,7 @@ public final class MapboxMap {
* @param url The URL of the map style
* @see Style
*/
+ @UiThread
public void setStyleUrl(@NonNull String url) {
setStyleUrl(url, null);
}
@@ -1036,6 +1035,7 @@ public final class MapboxMap {
* @param callback The callback that is invoked when the style has loaded.
* @see Style
*/
+ @UiThread
public void setStyleUrl(@NonNull final String url, @Nullable final OnStyleLoadedListener callback) {
if (callback != null) {
nativeMapView.addOnMapChangedListener(new MapView.OnMapChangedListener() {
@@ -1067,6 +1067,7 @@ public final class MapboxMap {
* @param style The bundled style.
* @see Style
*/
+ @UiThread
public void setStyle(@Style.StyleUrl String style) {
setStyleUrl(style);
}
@@ -1083,6 +1084,7 @@ public final class MapboxMap {
* @param callback The callback to be invoked when the style has finished loading
* @see Style
*/
+ @UiThread
public void setStyle(@Style.StyleUrl String style, @Nullable OnStyleLoadedListener callback) {
setStyleUrl(style, callback);
}
@@ -1100,36 +1102,16 @@ public final class MapboxMap {
}
/**
- * Returns the map style url currently displayed in the map view.
+ * Returns the map style currently displayed in the map view.
*
* @return The URL of the map style
*/
+ @UiThread
@Nullable
public String getStyleUrl() {
return nativeMapView.getStyleUrl();
}
- /**
- * Loads a new map style from a json string.
- * <p>
- * If the style fails to load or an invalid style URL is set, the map view will become blank.
- * An error message will be logged in the Android logcat and {@link MapView#DID_FAIL_LOADING_MAP} event will be
- * sent.
- * </p>
- */
- public void setStyleJson(@NonNull String styleJson) {
- nativeMapView.setStyleJson(styleJson);
- }
-
- /**
- * Returns the map style json currently displayed in the map view.
- *
- * @return The json of the map style
- */
- public String getStyleJson() {
- return nativeMapView.getStyleJson();
- }
-
//
// Annotations
//
@@ -1144,6 +1126,7 @@ public final class MapboxMap {
* @param markerOptions A marker options object that defines how to render the marker
* @return The {@code Marker} that was added to the map
*/
+ @UiThread
@NonNull
public Marker addMarker(@NonNull MarkerOptions markerOptions) {
return annotationManager.addMarker(markerOptions, this);
@@ -1159,6 +1142,7 @@ public final class MapboxMap {
* @param markerOptions A marker options object that defines how to render the marker
* @return The {@code Marker} that was added to the map
*/
+ @UiThread
@NonNull
public Marker addMarker(@NonNull BaseMarkerOptions markerOptions) {
return annotationManager.addMarker(markerOptions, this);
@@ -1174,6 +1158,7 @@ public final class MapboxMap {
* @param markerOptions A marker options object that defines how to render the marker
* @return The {@code Marker} that was added to the map
*/
+ @UiThread
@NonNull
public MarkerView addMarker(@NonNull BaseMarkerViewOptions markerOptions) {
return annotationManager.addMarker(markerOptions, this, null);
@@ -1190,6 +1175,7 @@ public final class MapboxMap {
* @param onMarkerViewAddedListener Callback invoked when the View has been added to the map
* @return The {@code Marker} that was added to the map
*/
+ @UiThread
@NonNull
public MarkerView addMarker(@NonNull BaseMarkerViewOptions markerOptions,
final MarkerViewManager.OnMarkerViewAddedListener onMarkerViewAddedListener) {
@@ -1206,6 +1192,7 @@ public final class MapboxMap {
* @param markerViewOptions A list of markerView options objects that defines how to render the markers
* @return A list of the {@code MarkerView}s that were added to the map
*/
+ @UiThread
@NonNull
public List<MarkerView> addMarkerViews(@NonNull List<? extends
BaseMarkerViewOptions> markerViewOptions) {
@@ -1218,6 +1205,7 @@ public final class MapboxMap {
* @param rect the rectangular area on the map to query for markerViews
* @return A list of the markerViews that were found in the rectangle
*/
+ @UiThread
@NonNull
public List<MarkerView> getMarkerViewsInRect(@NonNull RectF rect) {
return annotationManager.getMarkerViewsInRect(rect);
@@ -1233,6 +1221,7 @@ public final class MapboxMap {
* @param markerOptionsList A list of marker options objects that defines how to render the markers
* @return A list of the {@code Marker}s that were added to the map
*/
+ @UiThread
@NonNull
public List<Marker> addMarkers(@NonNull List<? extends
BaseMarkerOptions> markerOptionsList) {
@@ -1246,8 +1235,9 @@ public final class MapboxMap {
*
* @param updatedMarker An updated marker object
*/
+ @UiThread
public void updateMarker(@NonNull Marker updatedMarker) {
- annotationManager.updateMarker(updatedMarker, this);
+ annotationManager.updateMarker(updatedMarker);
}
/**
@@ -1256,6 +1246,7 @@ public final class MapboxMap {
* @param polylineOptions A polyline options object that defines how to render the polyline
* @return The {@code Polyine} that was added to the map
*/
+ @UiThread
@NonNull
public Polyline addPolyline(@NonNull PolylineOptions polylineOptions) {
return annotationManager.addPolyline(polylineOptions, this);
@@ -1267,6 +1258,7 @@ public final class MapboxMap {
* @param polylineOptionsList A list of polyline options objects that defines how to render the polylines.
* @return A list of the {@code Polyline}s that were added to the map.
*/
+ @UiThread
@NonNull
public List<Polyline> addPolylines(@NonNull List<PolylineOptions> polylineOptionsList) {
return annotationManager.addPolylines(polylineOptionsList, this);
@@ -1277,6 +1269,7 @@ public final class MapboxMap {
*
* @param polyline An updated polyline object.
*/
+ @UiThread
public void updatePolyline(Polyline polyline) {
annotationManager.updatePolyline(polyline);
}
@@ -1287,6 +1280,7 @@ public final class MapboxMap {
* @param polygonOptions A polygon options object that defines how to render the polygon.
* @return The {@code Polygon} that was added to the map.
*/
+ @UiThread
@NonNull
public Polygon addPolygon(@NonNull PolygonOptions polygonOptions) {
return annotationManager.addPolygon(polygonOptions, this);
@@ -1298,6 +1292,7 @@ public final class MapboxMap {
* @param polygonOptionsList A list of polygon options objects that defines how to render the polygons
* @return A list of the {@code Polygon}s that were added to the map
*/
+ @UiThread
@NonNull
public List<Polygon> addPolygons(@NonNull List<PolygonOptions> polygonOptionsList) {
return annotationManager.addPolygons(polygonOptionsList, this);
@@ -1308,6 +1303,7 @@ public final class MapboxMap {
*
* @param polygon An updated polygon object
*/
+ @UiThread
public void updatePolygon(Polygon polygon) {
annotationManager.updatePolygon(polygon);
}
@@ -1320,6 +1316,7 @@ public final class MapboxMap {
*
* @param marker Marker to remove
*/
+ @UiThread
public void removeMarker(@NonNull Marker marker) {
annotationManager.removeAnnotation(marker);
}
@@ -1332,6 +1329,7 @@ public final class MapboxMap {
*
* @param polyline Polyline to remove
*/
+ @UiThread
public void removePolyline(@NonNull Polyline polyline) {
annotationManager.removeAnnotation(polyline);
}
@@ -1344,6 +1342,7 @@ public final class MapboxMap {
*
* @param polygon Polygon to remove
*/
+ @UiThread
public void removePolygon(@NonNull Polygon polygon) {
annotationManager.removeAnnotation(polygon);
}
@@ -1353,6 +1352,7 @@ public final class MapboxMap {
*
* @param annotation The annotation object to remove.
*/
+ @UiThread
public void removeAnnotation(@NonNull Annotation annotation) {
annotationManager.removeAnnotation(annotation);
}
@@ -1362,6 +1362,7 @@ public final class MapboxMap {
*
* @param id The identifier associated to the annotation to be removed
*/
+ @UiThread
public void removeAnnotation(long id) {
annotationManager.removeAnnotation(id);
}
@@ -1371,6 +1372,7 @@ public final class MapboxMap {
*
* @param annotationList A list of annotation objects to remove.
*/
+ @UiThread
public void removeAnnotations(@NonNull List<? extends Annotation> annotationList) {
annotationManager.removeAnnotations(annotationList);
}
@@ -1378,6 +1380,7 @@ public final class MapboxMap {
/**
* Removes all annotations from the map.
*/
+ @UiThread
public void removeAnnotations() {
annotationManager.removeAnnotations();
}
@@ -1385,6 +1388,7 @@ public final class MapboxMap {
/**
* Removes all markers, polylines, polygons, overlays, etc from the map.
*/
+ @UiThread
public void clear() {
annotationManager.removeAnnotations();
}
@@ -1450,6 +1454,7 @@ public final class MapboxMap {
* @param listener The callback that's invoked when the user clicks on a marker.
* To unset the callback, use null.
*/
+ @UiThread
public void setOnMarkerClickListener(@Nullable OnMarkerClickListener listener) {
annotationManager.setOnMarkerClickListener(listener);
}
@@ -1460,6 +1465,7 @@ public final class MapboxMap {
* @param listener The callback that's invoked when the user clicks on a polygon.
* To unset the callback, use null.
*/
+ @UiThread
public void setOnPolygonClickListener(@Nullable OnPolygonClickListener listener) {
annotationManager.setOnPolygonClickListener(listener);
}
@@ -1470,6 +1476,7 @@ public final class MapboxMap {
* @param listener The callback that's invoked when the user clicks on a polyline.
* To unset the callback, use null.
*/
+ @UiThread
public void setOnPolylineClickListener(@Nullable OnPolylineClickListener listener) {
annotationManager.setOnPolylineClickListener(listener);
}
@@ -1484,6 +1491,7 @@ public final class MapboxMap {
*
* @param marker The marker to select.
*/
+ @UiThread
public void selectMarker(@NonNull Marker marker) {
if (marker == null) {
Timber.w("marker was null, so just returning");
@@ -1495,6 +1503,7 @@ public final class MapboxMap {
/**
* Deselects any currently selected marker. All markers will have it's info window closed.
*/
+ @UiThread
public void deselectMarkers() {
annotationManager.deselectMarkers();
}
@@ -1504,6 +1513,7 @@ public final class MapboxMap {
*
* @param marker the marker to deselect
*/
+ @UiThread
public void deselectMarker(@NonNull Marker marker) {
annotationManager.deselectMarker(marker);
}
@@ -1513,6 +1523,7 @@ public final class MapboxMap {
*
* @return The currently selected marker.
*/
+ @UiThread
public List<Marker> getSelectedMarkers() {
return annotationManager.getSelectedMarkers();
}
@@ -1540,6 +1551,7 @@ public final class MapboxMap {
* @param infoWindowAdapter The callback to be invoked when an info window will be shown.
* To unset the callback, use null.
*/
+ @UiThread
public void setInfoWindowAdapter(@Nullable InfoWindowAdapter infoWindowAdapter) {
annotationManager.getInfoWindowManager().setInfoWindowAdapter(infoWindowAdapter);
}
@@ -1549,6 +1561,7 @@ public final class MapboxMap {
*
* @return The callback to be invoked when an info window will be shown.
*/
+ @UiThread
@Nullable
public InfoWindowAdapter getInfoWindowAdapter() {
return annotationManager.getInfoWindowManager().getInfoWindowAdapter();
@@ -1559,6 +1572,7 @@ public final class MapboxMap {
*
* @param allow If true, map allows concurrent multiple infowindows to be shown.
*/
+ @UiThread
public void setAllowConcurrentMultipleOpenInfoWindows(boolean allow) {
annotationManager.getInfoWindowManager().setAllowConcurrentMultipleOpenInfoWindows(allow);
}
@@ -1568,6 +1582,7 @@ public final class MapboxMap {
*
* @return If true, map allows concurrent multiple infowindows to be shown.
*/
+ @UiThread
public boolean isAllowConcurrentMultipleOpenInfoWindows() {
return annotationManager.getInfoWindowManager().isAllowConcurrentMultipleOpenInfoWindows();
}
@@ -1661,6 +1676,7 @@ public final class MapboxMap {
* @param listener The callback that's invoked on every camera change position.
* To unset the callback, use null.
*/
+ @UiThread
@Deprecated
public void setOnCameraChangeListener(@Nullable OnCameraChangeListener listener) {
transform.setOnCameraChangeListener(listener);
@@ -1671,6 +1687,7 @@ public final class MapboxMap {
*
* @param listener the listener to notify
*/
+ @UiThread
public void setOnCameraIdleListener(@Nullable OnCameraIdleListener listener) {
cameraChangeDispatcher.setOnCameraIdleListener(listener);
}
@@ -1680,6 +1697,7 @@ public final class MapboxMap {
*
* @param listener the listener to notify
*/
+ @UiThread
public void setOnCameraMoveCancelListener(@Nullable OnCameraMoveCanceledListener listener) {
cameraChangeDispatcher.setOnCameraMoveCanceledListener(listener);
}
@@ -1689,6 +1707,7 @@ public final class MapboxMap {
*
* @param listener the listener to notify
*/
+ @UiThread
public void setOnCameraMoveStartedListener(@Nullable OnCameraMoveStartedListener listener) {
cameraChangeDispatcher.setOnCameraMoveStartedListener(listener);
}
@@ -1698,6 +1717,7 @@ public final class MapboxMap {
*
* @param listener the listener to notify
*/
+ @UiThread
public void setOnCameraMoveListener(@Nullable OnCameraMoveListener listener) {
cameraChangeDispatcher.setOnCameraMoveListener(listener);
}
@@ -1708,6 +1728,7 @@ public final class MapboxMap {
* @param listener The callback that's invoked on every frame rendered to the map view.
* To unset the callback, use null.
*/
+ @UiThread
public void setOnFpsChangedListener(@Nullable OnFpsChangedListener listener) {
onFpsChangedListener = listener;
}
@@ -1723,6 +1744,7 @@ public final class MapboxMap {
* @param listener The callback that's invoked when the map is scrolled.
* To unset the callback, use null.
*/
+ @UiThread
public void setOnScrollListener(@Nullable OnScrollListener listener) {
onRegisterTouchListener.onRegisterScrollListener(listener);
}
@@ -1733,6 +1755,7 @@ public final class MapboxMap {
* @param listener The callback that's invoked when the map is flinged.
* To unset the callback, use null.
*/
+ @UiThread
public void setOnFlingListener(@Nullable OnFlingListener listener) {
onRegisterTouchListener.onRegisterFlingListener(listener);
}
@@ -1743,6 +1766,7 @@ public final class MapboxMap {
* @param listener The callback that's invoked when the user clicks on the map view.
* To unset the callback, use null.
*/
+ @UiThread
public void setOnMapClickListener(@Nullable OnMapClickListener listener) {
onRegisterTouchListener.onRegisterMapClickListener(listener);
}
@@ -1753,6 +1777,7 @@ public final class MapboxMap {
* @param listener The callback that's invoked when the user long clicks on the map view.
* To unset the callback, use null.
*/
+ @UiThread
public void setOnMapLongClickListener(@Nullable OnMapLongClickListener listener) {
onRegisterTouchListener.onRegisterMapLongClickListener(listener);
}
@@ -1763,6 +1788,7 @@ public final class MapboxMap {
* @param listener The callback that's invoked when the user clicks on an info window.
* To unset the callback, use null.
*/
+ @UiThread
public void setOnInfoWindowClickListener(@Nullable OnInfoWindowClickListener listener) {
annotationManager.getInfoWindowManager().setOnInfoWindowClickListener(listener);
}
@@ -1772,6 +1798,7 @@ public final class MapboxMap {
*
* @return Current active InfoWindow Click Listener
*/
+ @UiThread
public OnInfoWindowClickListener getOnInfoWindowClickListener() {
return annotationManager.getInfoWindowManager().getOnInfoWindowClickListener();
}
@@ -1782,6 +1809,7 @@ public final class MapboxMap {
* @param listener The callback that's invoked when a marker's info window is long pressed. To unset the callback,
* use null.
*/
+ @UiThread
public void setOnInfoWindowLongClickListener(@Nullable OnInfoWindowLongClickListener
listener) {
annotationManager.getInfoWindowManager().setOnInfoWindowLongClickListener(listener);
@@ -1810,6 +1838,7 @@ public final class MapboxMap {
*
* @return Current active InfoWindow Close Listener
*/
+ @UiThread
public OnInfoWindowCloseListener getOnInfoWindowCloseListener() {
return annotationManager.getInfoWindowManager().getOnInfoWindowCloseListener();
}
@@ -1822,10 +1851,8 @@ public final class MapboxMap {
* Returns the status of the my-location layer.
*
* @return True if the my-location layer is enabled, false otherwise.
- * @deprecated use location layer plugin from
- * https://github.com/mapbox/mapbox-plugins-android/tree/master/plugins/locationlayer instead.
*/
- @Deprecated
+ @UiThread
public boolean isMyLocationEnabled() {
return trackingSettings.isMyLocationEnabled();
}
@@ -1840,10 +1867,8 @@ public final class MapboxMap {
* android.Manifest.permission#ACCESS_COARSE_LOCATION or android.Manifest.permission#ACCESS_FINE_LOCATION.
*
* @param enabled True to enable; false to disable.
- * @deprecated use location layer plugin from
- * https://github.com/mapbox/mapbox-plugins-android/tree/master/plugins/locationlayer instead.
*/
- @Deprecated
+ @UiThread
public void setMyLocationEnabled(boolean enabled) {
trackingSettings.setMyLocationEnabled(enabled);
}
@@ -1852,11 +1877,9 @@ public final class MapboxMap {
* Returns the currently displayed user location, or null if there is no location data available.
*
* @return The currently displayed user location.
- * @deprecated use location layer plugin from
- * https://github.com/mapbox/mapbox-plugins-android/tree/master/plugins/locationlayer instead.
*/
+ @UiThread
@Nullable
- @Deprecated
public Location getMyLocation() {
return trackingSettings.getMyLocation();
}
@@ -1867,10 +1890,8 @@ public final class MapboxMap {
*
* @param listener The callback that's invoked when the user clicks on a marker.
* To unset the callback, use null.
- * @deprecated use location layer plugin from
- * https://github.com/mapbox/mapbox-plugins-android/tree/master/plugins/locationlayer instead.
*/
- @Deprecated
+ @UiThread
public void setOnMyLocationChangeListener(@Nullable MapboxMap.OnMyLocationChangeListener
listener) {
trackingSettings.setOnMyLocationChangeListener(listener);
@@ -1880,10 +1901,8 @@ public final class MapboxMap {
* Replaces the location source of the my-location layer.
*
* @param locationSource A {@link LocationEngine} location source to use in the my-location layer.
- * @deprecated use location layer plugin from
- * https://github.com/mapbox/mapbox-plugins-android/tree/master/plugins/locationlayer instead.
*/
- @Deprecated
+ @UiThread
public void setLocationSource(@Nullable LocationEngine locationSource) {
trackingSettings.setLocationSource(locationSource);
}
@@ -1893,10 +1912,8 @@ public final class MapboxMap {
*
* @param listener The callback that's invoked when the location tracking mode changes.
* To unset the callback, use null.
- * @deprecated use location layer plugin from
- * https://github.com/mapbox/mapbox-plugins-android/tree/master/plugins/locationlayer instead.
*/
- @Deprecated
+ @UiThread
public void setOnMyLocationTrackingModeChangeListener(
@Nullable MapboxMap.OnMyLocationTrackingModeChangeListener listener) {
trackingSettings.setOnMyLocationTrackingModeChangeListener(listener);
@@ -1907,10 +1924,8 @@ public final class MapboxMap {
*
* @param listener The callback that's invoked when the bearing tracking mode changes.
* To unset the callback, use null.
- * @deprecated use location layer plugin from
- * https://github.com/mapbox/mapbox-plugins-android/tree/master/plugins/locationlayer instead.
*/
- @Deprecated
+ @UiThread
public void setOnMyBearingTrackingModeChangeListener(@Nullable OnMyBearingTrackingModeChangeListener listener) {
trackingSettings.setOnMyBearingTrackingModeChangeListener(listener);
}
@@ -1924,6 +1939,7 @@ public final class MapboxMap {
*
* @param callback Callback method invoked when the snapshot is taken.
*/
+ @UiThread
public void snapshot(@NonNull SnapshotReadyCallback callback) {
nativeMapView.addSnapshotCallback(callback);
}
@@ -1935,6 +1951,7 @@ public final class MapboxMap {
* @param layerIds optionally - only query these layers
* @return the list of feature
*/
+ @UiThread
@NonNull
public List<Feature> queryRenderedFeatures(@NonNull PointF coordinates, @Nullable String...
layerIds) {
@@ -1949,6 +1966,7 @@ public final class MapboxMap {
* @param layerIds optionally - only query these layers
* @return the list of feature
*/
+ @UiThread
@NonNull
public List<Feature> queryRenderedFeatures(@NonNull PointF coordinates,
@Nullable Filter.Statement filter,
@@ -1963,6 +1981,7 @@ public final class MapboxMap {
* @param layerIds optionally - only query these layers
* @return the list of feature
*/
+ @UiThread
@NonNull
public List<Feature> queryRenderedFeatures(@NonNull RectF coordinates,
@Nullable String... layerIds) {
@@ -1977,6 +1996,7 @@ public final class MapboxMap {
* @param layerIds optionally - only query these layers
* @return the list of feature
*/
+ @UiThread
@NonNull
public List<Feature> queryRenderedFeatures(@NonNull RectF coordinates,
@Nullable Filter.Statement filter,
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/values-fr/strings.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/values-fr/strings.xml
new file mode 100644
index 0000000000..48d90c3324
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/values-fr/strings.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="mapbox_compassContentDescription">Boussole. Activer pour rétablir l\'orientation de la carte vers le nord.</string>
+ <string name="mapbox_attributionsIconContentDescription">Icone d\'attribution. Activer pour montrer le dialogue d\'attribution.</string>
+ <string name="mapbox_myLocationViewContentDescription">Vue de géolocalisation. Ceci affiche votre localisation sur la carte.</string>
+ <string name="mapbox_mapActionDescription">Affichage d\'une carte créée avec Mapbox. Faites la glisser en traînant deux doigts. Zoomez ou dézoomez en écartant ou rapprochant deux doigts.</string>
+ <string name="mapbox_attributionsDialogTitle">SDK Mapbox pour Android</string>
+ <string name="mapbox_attributionTelemetryTitle">Faire de meilleures cartes Mapbox</string>
+ <string name="mapbox_attributionTelemetryMessage">Vous aidez à améliorer les cartes OpenStreetMap et Mapbox en contribuant des données d\'utilisation anonymes.</string>
+ <string name="mapbox_attributionTelemetryPositive">D\'accord</string>
+ <string name="mapbox_attributionTelemetryNegative">Pas d\'accord</string>
+ <string name="mapbox_attributionTelemetryNeutral">Plus d\'informations</string>
+ <string name="mapbox_offline_error_region_definition_invalid">Le cadre OfflineRegionDefinition pour définir la région de navigation ne tient pas dans les limites du monde : %s</string>
+
+ </resources>
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/resources/fabric/com.mapbox.mapboxsdk.mapbox-android-sdk.properties b/platform/android/MapboxGLAndroidSDK/src/main/resources/fabric/com.mapbox.mapboxsdk.mapbox-android-sdk.properties
index 029d25e046..81e0e5d7a8 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/resources/fabric/com.mapbox.mapboxsdk.mapbox-android-sdk.properties
+++ b/platform/android/MapboxGLAndroidSDK/src/main/resources/fabric/com.mapbox.mapboxsdk.mapbox-android-sdk.properties
@@ -1,3 +1,3 @@
fabric-identifier=com.mapbox.mapboxsdk.mapbox-android-sdk
-fabric-version=5.1.0
+fabric-version=5.1.3
fabric-build-type=binary
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_check_box.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_check_box.xml
new file mode 100644
index 0000000000..cf8bfa24b5
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable/ic_check_box.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M19,5v14H5V5h14m0,-2H5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2V5c0,-1.1 -0.9,-2 -2,-2z"/>
+</vector>
diff --git a/platform/android/dependencies.gradle b/platform/android/dependencies.gradle
index b938767b3d..4585e0cb1f 100644
--- a/platform/android/dependencies.gradle
+++ b/platform/android/dependencies.gradle
@@ -4,8 +4,8 @@ ext {
compileSdkVersion = 25
buildToolsVersion = "25.0.2"
- versionCode = 11
- versionName = "5.0.0"
+ versionCode = 12
+ versionName = "5.1.4"
mapboxServicesVersion = "2.2.1"
supportLibVersion = "25.3.1"
diff --git a/platform/darwin/docs/guides/Working with GeoJSON Data.md b/platform/darwin/docs/guides/Working with GeoJSON Data.md
index 57aaa3855d..f3b3dc0918 100644
--- a/platform/darwin/docs/guides/Working with GeoJSON Data.md
+++ b/platform/darwin/docs/guides/Working with GeoJSON Data.md
@@ -81,8 +81,10 @@ Linear ring | `MGLPolygon.coordinates`, `MGLPolygon.interiorPolygons`
A `Feature` object in GeoJSON corresponds to an instance of an `MGLShape`
subclass conforming to the `MGLFeature` protocol. There is a distinct
`MGLFeature`-conforming class for each type of geometry that a GeoJSON feature
-can contain. This allows features to be used as shapes where convenient. For
-example, some features can be added to a map view as annotations.
+can contain. This allows features to be used as raw shapes where convenient. For
+example, some features can be added to a map view as annotations. Note that
+identifiers and attributes will not be available for feature querying when a
+feature is used as an annotation.
In contrast to the GeoJSON standard, it is possible for `MGLShape` subclasses
other than `MGLPointAnnotation` to straddle the antimeridian.
diff --git a/platform/darwin/resources/fr.lproj/Foundation.strings b/platform/darwin/resources/fr.lproj/Foundation.strings
new file mode 100644
index 0000000000..d2f6c1f6df
--- /dev/null
+++ b/platform/darwin/resources/fr.lproj/Foundation.strings
@@ -0,0 +1,291 @@
+/* Clock position format, long: {hours} o’clock */
+"CLOCK_FMT_LONG" = "%@ heures";
+
+/* Clock position format, medium: {hours} o’clock */
+"CLOCK_FMT_MEDIUM" = "%@ heures";
+
+/* Clock position format, short: {hours}:00 */
+"CLOCK_FMT_SHORT" = "%@h 00";
+
+/* East, long */
+"COMPASS_E_LONG" = "est";
+
+/* East, short */
+"COMPASS_E_SHORT" = "E";
+
+/* East by north, long */
+"COMPASS_EbN_LONG" = "est par nord";
+
+/* East by north, short */
+"COMPASS_EbN_SHORT" = "EpN";
+
+/* East by south, long */
+"COMPASS_EbS_LONG" = "est par sud";
+
+/* East by south, short */
+"COMPASS_EbS_SHORT" = "EpS";
+
+/* East-northeast, long */
+"COMPASS_ENE_LONG" = "est-nord-est";
+
+/* East-northeast, short */
+"COMPASS_ENE_SHORT" = "ENE";
+
+/* East-southeast, long */
+"COMPASS_ESE_LONG" = "est-sud-est";
+
+/* East-southeast, short */
+"COMPASS_ESE_SHORT" = "ESE";
+
+/* North, long */
+"COMPASS_N_LONG" = "nord";
+
+/* North, short */
+"COMPASS_N_SHORT" = "N";
+
+/* North by east, long */
+"COMPASS_NbE_LONG" = "nord par est";
+
+/* North by east, short */
+"COMPASS_NbE_SHORT" = "NpE";
+
+/* North by west, long */
+"COMPASS_NbW_LONG" = "nord par ouest";
+
+/* North by west, short */
+"COMPASS_NbW_SHORT" = "NpO";
+
+/* Northeast, long */
+"COMPASS_NE_LONG" = "nord-est";
+
+/* Northeast, short */
+"COMPASS_NE_SHORT" = "NE";
+
+/* Northeast by east, long */
+"COMPASS_NEbE_LONG" = "nord-est par est";
+
+/* Northeast by east, short */
+"COMPASS_NEbE_SHORT" = "NEpE";
+
+/* Northeast by north, long */
+"COMPASS_NEbN_LONG" = "nord-est par nord";
+
+/* Northeast by north, short */
+"COMPASS_NEbN_SHORT" = "NEpN";
+
+/* North-northeast, long */
+"COMPASS_NNE_LONG" = "nord-nord-est";
+
+/* North-northeast, short */
+"COMPASS_NNE_SHORT" = "NNE";
+
+/* North-northwest, long */
+"COMPASS_NNW_LONG" = "nord-nord-ouest";
+
+/* North-northwest, short */
+"COMPASS_NNW_SHORT" = "NNO";
+
+/* Northwest, long */
+"COMPASS_NW_LONG" = "nord-ouest";
+
+/* Northwest, short */
+"COMPASS_NW_SHORT" = "NO";
+
+/* Northwest by north, long */
+"COMPASS_NWbN_LONG" = "nord-ouest par nord";
+
+/* Northwest by north, short */
+"COMPASS_NWbN_SHORT" = "NOpN";
+
+/* Northwest by west, long */
+"COMPASS_NWbW_LONG" = "nord-ouest par ouest";
+
+/* Northwest by west, short */
+"COMPASS_NWbW_SHORT" = "NOpO";
+
+/* South, long */
+"COMPASS_S_LONG" = "sud";
+
+/* South, short */
+"COMPASS_S_SHORT" = "S";
+
+/* South by east, long */
+"COMPASS_SbE_LONG" = "sud par est";
+
+/* South by east, short */
+"COMPASS_SbE_SHORT" = "SpE";
+
+/* South by west, long */
+"COMPASS_SbW_LONG" = "sud par ouest";
+
+/* South by west, short */
+"COMPASS_SbW_SHORT" = "SpO";
+
+/* Southeast, long */
+"COMPASS_SE_LONG" = "sud-est";
+
+/* Southeast, short */
+"COMPASS_SE_SHORT" = "SE";
+
+/* Southeast by east, long */
+"COMPASS_SEbE_LONG" = "sud-est par est";
+
+/* Southeast by east, short */
+"COMPASS_SEbE_SHORT" = "SEpE";
+
+/* Southeast by south, long */
+"COMPASS_SEbS_LONG" = "sud-est par sud";
+
+/* Southeast by south, short */
+"COMPASS_SEbS_SHORT" = "SEpS";
+
+/* South-southeast, long */
+"COMPASS_SSE_LONG" = "sud-sud-est";
+
+/* South-southeast, short */
+"COMPASS_SSE_SHORT" = "SSE";
+
+/* South-southwest, long */
+"COMPASS_SSW_LONG" = "sud-sud-ouest";
+
+/* South-southwest, short */
+"COMPASS_SSW_SHORT" = "SSO";
+
+/* Southwest, long */
+"COMPASS_SW_LONG" = "sud-ouest";
+
+/* Southwest, short */
+"COMPASS_SW_SHORT" = "SO";
+
+/* Southwest by south, long */
+"COMPASS_SWbS_LONG" = "sud-ouest par sud";
+
+/* Southwest by south, short */
+"COMPASS_SWbS_SHORT" = "SOpS";
+
+/* Southwest by west, long */
+"COMPASS_SWbW_LONG" = "sud-ouest par ouest";
+
+/* Southwest by west, short */
+"COMPASS_SWbW_SHORT" = "SOpO";
+
+/* West, long */
+"COMPASS_W_LONG" = "ouest";
+
+/* West, short */
+"COMPASS_W_SHORT" = "O";
+
+/* West by north, long */
+"COMPASS_WbN_LONG" = "ouest par nord";
+
+/* West by north, short */
+"COMPASS_WbN_SHORT" = "OpN";
+
+/* West by south, long */
+"COMPASS_WbS_LONG" = "ouest par sud";
+
+/* West by south, short */
+"COMPASS_WbS_SHORT" = "OpS";
+
+/* West-northwest, long */
+"COMPASS_WNW_LONG" = "ouest-nord-ouest";
+
+/* West-northwest, short */
+"COMPASS_WNW_SHORT" = "ONO";
+
+/* West-southwest, long */
+"COMPASS_WSW_LONG" = "ouest-sud-ouest";
+
+/* West-southwest, short */
+"COMPASS_WSW_SHORT" = "OSO";
+
+/* Degrees format, long */
+"COORD_DEG_LONG" = "%d degré(s)";
+
+/* Degrees format, medium: {degrees} */
+"COORD_DEG_MEDIUM" = "%d°";
+
+/* Degrees format, short: {degrees} */
+"COORD_DEG_SHORT" = "%d°";
+
+/* Coordinate format, long: {degrees}{minutes} */
+"COORD_DM_LONG" = "%1$@ et %2$@";
+
+/* Coordinate format, medium: {degrees}{minutes} */
+"COORD_DM_MEDIUM" = "%1$@%2$@";
+
+/* Coordinate format, short: {degrees}{minutes} */
+"COORD_DM_SHORT" = "%1$@%2$@";
+
+/* Coordinate format, long: {degrees}{minutes}{seconds} */
+"COORD_DMS_LONG" = "%1$@, %2$@ et %3$@";
+
+/* Coordinate format, medium: {degrees}{minutes}{seconds} */
+"COORD_DMS_MEDIUM" = "%1$@%2$@%3$@";
+
+/* Coordinate format, short: {degrees}{minutes}{seconds} */
+"COORD_DMS_SHORT" = "%1$@%2$@%3$@";
+
+/* East longitude format, long: {longitude} */
+"COORD_E_LONG" = "%@ est";
+
+/* East longitude format, medium: {longitude} */
+"COORD_E_MEDIUM" = "%@ est";
+
+/* East longitude format, short: {longitude} */
+"COORD_E_SHORT" = "%@E";
+
+/* Coordinate pair format, long: {latitude}, {longitude} */
+"COORD_FMT_LONG" = "%1$@, %2$@";
+
+/* Coordinate pair format, medium: {latitude}, {longitude} */
+"COORD_FMT_MEDIUM" = "%1$@, %2$@";
+
+/* Coordinate pair format, short: {latitude}, {longitude} */
+"COORD_FMT_SHORT" = "%1$@, %2$@";
+
+/* Minutes format, long */
+"COORD_MIN_LONG" = "%d minute(s)";
+
+/* Minutes format, medium: {minutes} */
+"COORD_MIN_MEDIUM" = "%d′";
+
+/* Minutes format, short: {minutes} */
+"COORD_MIN_SHORT" = "%d′";
+
+/* North latitude format, long: {latitude} */
+"COORD_N_LONG" = "%@ nord";
+
+/* North latitude format, medium: {latitude} */
+"COORD_N_MEDIUM" = "%@ nord";
+
+/* North latitude format, short: {latitude} */
+"COORD_N_SHORT" = "%@N";
+
+/* South latitude format, long: {latitude} */
+"COORD_S_LONG" = "%@ sud";
+
+/* South latitude format, medium: {latitude} */
+"COORD_S_MEDIUM" = "%@ sud";
+
+/* South latitude format, short: {latitude} */
+"COORD_S_SHORT" = "%@S";
+
+/* Seconds format, long */
+"COORD_SEC_LONG" = "%d seconde(s)";
+
+/* Seconds format, medium: {seconds} */
+"COORD_SEC_MEDIUM" = "%d″";
+
+/* Seconds format, short: {seconds} */
+"COORD_SEC_SHORT" = "%d″";
+
+/* West longitude format, long: {longitude} */
+"COORD_W_LONG" = "%@ ouest";
+
+/* West longitude format, medium: {longitude} */
+"COORD_W_MEDIUM" = "%@ ouest";
+
+/* West longitude format, short: {longitude} */
+"COORD_W_SHORT" = "%@O";
+
diff --git a/platform/darwin/src/MGLFeature.h b/platform/darwin/src/MGLFeature.h
index 491c89b608..a13821cf96 100644
--- a/platform/darwin/src/MGLFeature.h
+++ b/platform/darwin/src/MGLFeature.h
@@ -18,15 +18,23 @@ NS_ASSUME_NONNULL_BEGIN
You can add custom data to display on the map by creating feature objects and
adding them to an `MGLShapeSource` using the
`-[MGLShapeSource initWithIdentifier:shape:options:]` method or
- `MGLShapeSource.shape` property. Similarly, you can add `MGLPointFeature`,
- `MGLPolylineFeature`, and `MGLPolygonFeature` objects to the map as annotations
- using `-[MGLMapView addAnnotations:]` and related methods.
+ `MGLShapeSource.shape` property.
In addition to adding data to the map, you can also extract data from the map:
`-[MGLMapView visibleFeaturesAtPoint:]` and related methods return feature
objects that correspond to features in the source. This enables you to inspect
the properties of features in vector tiles loaded by `MGLVectorSource` objects.
You also reuse these feature objects as overlay annotations.
+
+ While it is possible to add `MGLFeature`-conforming objects to the map as
+ annotations using `-[MGLMapView addAnnotations:]` and related methods, doing so
+ has trade-offs:
+
+ - Features added as annotations will not have `identifier` or `attributes`
+ properties when used with feature querying.
+
+ - Features added as annotations become interactive. Taps and selection can be
+ handled in `-[MGLMapViewDelegate mapView:didSelectAnnotation:]`.
*/
@protocol MGLFeature <MGLAnnotation>
diff --git a/platform/darwin/src/MGLFeature.mm b/platform/darwin/src/MGLFeature.mm
index e169ee19bb..84f1a1ff25 100644
--- a/platform/darwin/src/MGLFeature.mm
+++ b/platform/darwin/src/MGLFeature.mm
@@ -42,6 +42,15 @@ MGL_DEFINE_FEATURE_IS_EQUAL();
return mbglFeature({[self geometryObject]}, identifier, self.attributes);
}
+- (NSString *)description
+{
+ return [NSString stringWithFormat:@"<%@: %p; identifier = %@, coordinate = %f, %f, attributes = %@>",
+ NSStringFromClass([self class]), (void *)self,
+ self.identifier ? [NSString stringWithFormat:@"\"%@\"", self.identifier] : self.identifier,
+ self.coordinate.latitude, self.coordinate.longitude,
+ self.attributes.count ? self.attributes : @"none"];
+}
+
@end
@interface MGLPolylineFeature ()
@@ -68,6 +77,16 @@ MGL_DEFINE_FEATURE_IS_EQUAL();
return mbglFeature({[self geometryObject]}, identifier, self.attributes);
}
+- (NSString *)description
+{
+ return [NSString stringWithFormat:@"<%@: %p; identifier = %@, count = %lu, bounds = %@, attributes = %@>",
+ NSStringFromClass([self class]), (void *)self,
+ self.identifier ? [NSString stringWithFormat:@"\"%@\"", self.identifier] : self.identifier,
+ (unsigned long)[self pointCount],
+ MGLStringFromCoordinateBounds(self.overlayBounds),
+ self.attributes.count ? self.attributes : @"none"];
+}
+
@end
@interface MGLPolygonFeature ()
@@ -94,6 +113,16 @@ MGL_DEFINE_FEATURE_IS_EQUAL();
return mbglFeature({[self geometryObject]}, identifier, self.attributes);
}
+- (NSString *)description
+{
+ return [NSString stringWithFormat:@"<%@: %p; identifier = %@, count = %lu, bounds = %@, attributes = %@>",
+ NSStringFromClass([self class]), (void *)self,
+ self.identifier ? [NSString stringWithFormat:@"\"%@\"", self.identifier] : self.identifier,
+ (unsigned long)[self pointCount],
+ MGLStringFromCoordinateBounds(self.overlayBounds),
+ self.attributes.count ? self.attributes : @"none"];
+}
+
@end
@interface MGLPointCollectionFeature ()
@@ -146,6 +175,16 @@ MGL_DEFINE_FEATURE_IS_EQUAL();
return mbglFeature({[self geometryObject]}, identifier, self.attributes);
}
+- (NSString *)description
+{
+ return [NSString stringWithFormat:@"<%@: %p; identifier = %@, count = %lu, bounds = %@, attributes = %@>",
+ NSStringFromClass([self class]), (void *)self,
+ self.identifier ? [NSString stringWithFormat:@"\"%@\"", self.identifier] : self.identifier,
+ (unsigned long)self.polylines.count,
+ MGLStringFromCoordinateBounds(self.overlayBounds),
+ self.attributes.count ? self.attributes : @"none"];
+}
+
@end
@interface MGLMultiPolygonFeature ()
@@ -172,6 +211,16 @@ MGL_DEFINE_FEATURE_IS_EQUAL();
return mbglFeature({[self geometryObject]}, identifier, self.attributes);
}
+- (NSString *)description
+{
+ return [NSString stringWithFormat:@"<%@: %p; identifier = %@, count = %lu, bounds = %@, attributes = %@>",
+ NSStringFromClass([self class]), (void *)self,
+ self.identifier ? [NSString stringWithFormat:@"\"%@\"", self.identifier] : self.identifier,
+ (unsigned long)self.polygons.count,
+ MGLStringFromCoordinateBounds(self.overlayBounds),
+ self.attributes.count ? self.attributes : @"none"];
+}
+
@end
@interface MGLShapeCollectionFeature ()
diff --git a/platform/darwin/src/MGLPolygon.mm b/platform/darwin/src/MGLPolygon.mm
index d966ff13ce..e7843224e9 100644
--- a/platform/darwin/src/MGLPolygon.mm
+++ b/platform/darwin/src/MGLPolygon.mm
@@ -200,4 +200,14 @@
@"coordinates": coordinates};
}
+- (NSString *)description
+{
+ return [NSString stringWithFormat:@"<%@: %p; title = %@, subtitle: = %@, count = %lu; bounds = %@>",
+ NSStringFromClass([self class]), (void *)self,
+ self.title ? [NSString stringWithFormat:@"\"%@\"", self.title] : self.title,
+ self.subtitle ? [NSString stringWithFormat:@"\"%@\"", self.subtitle] : self.subtitle,
+ (unsigned long)self.polygons.count,
+ MGLStringFromCoordinateBounds(self.overlayBounds)];
+}
+
@end
diff --git a/platform/darwin/src/MGLPolyline.h b/platform/darwin/src/MGLPolyline.h
index b3db0fd39f..e46baa91cc 100644
--- a/platform/darwin/src/MGLPolyline.h
+++ b/platform/darwin/src/MGLPolyline.h
@@ -33,8 +33,18 @@ NS_ASSUME_NONNULL_BEGIN
`MGLPolygon` object. To group multiple polylines together in one shape, use an
`MGLMultiPolyline` or `MGLShapeCollection` object.
- To make the polyline straddle the antimeridian, specify some longitudes less
- than −180 degrees or greater than 180 degrees.
+ To make the polyline go across the antimeridian or international date line,
+ specify some longitudes less than −180 degrees or greater than 180 degrees.
+ For example, a polyline that stretches from Tokyo to San Francisco would have
+ coordinates of (35.68476, -220.24257) and (37.78428, -122.41310).
+
+ ```swift
+ let coordinates = [
+ CLLocationCoordinate2D(latitude: 35.68476, longitude: -220.24257),
+ CLLocationCoordinate2D(latitude: 37.78428, longitude: -122.41310)
+ ]
+ let polyline = MGLPolyline(coordinates: coordinates, count: UInt(coordinates.count))
+ ```
A polyline is known as a
<a href="https://tools.ietf.org/html/rfc7946#section-3.1.4">LineString</a>
diff --git a/platform/darwin/src/MGLPolyline.mm b/platform/darwin/src/MGLPolyline.mm
index fd75dc2795..0e371a4dda 100644
--- a/platform/darwin/src/MGLPolyline.mm
+++ b/platform/darwin/src/MGLPolyline.mm
@@ -201,4 +201,14 @@
@"coordinates": coordinates};
}
+- (NSString *)description
+{
+ return [NSString stringWithFormat:@"<%@: %p; title = %@, subtitle: = %@, count = %lu; bounds = %@>",
+ NSStringFromClass([self class]), (void *)self,
+ self.title ? [NSString stringWithFormat:@"\"%@\"", self.title] : self.title,
+ self.subtitle ? [NSString stringWithFormat:@"\"%@\"", self.subtitle] : self.subtitle,
+ (unsigned long)self.polylines.count,
+ MGLStringFromCoordinateBounds(self.overlayBounds)];
+}
+
@end
diff --git a/platform/darwin/src/MGLSource.mm b/platform/darwin/src/MGLSource.mm
index ee012f4d66..dde55967d7 100644
--- a/platform/darwin/src/MGLSource.mm
+++ b/platform/darwin/src/MGLSource.mm
@@ -27,17 +27,18 @@
return self;
}
-- (instancetype)initWithRawSource:(mbgl::style::Source *)rawSource {
+- (instancetype)initWithRawSource:(mbgl::style::Source *)rawSource mapView:(MGLMapView *)mapView {
NSString *identifier = @(rawSource->getID().c_str());
if (self = [self initWithIdentifier:identifier]) {
_rawSource = rawSource;
_rawSource->peer = SourceWrapper { self };
+ _mapView = mapView;
}
return self;
}
- (instancetype)initWithPendingSource:(std::unique_ptr<mbgl::style::Source>)pendingSource {
- if (self = [self initWithRawSource:pendingSource.get()]) {
+ if (self = [self initWithRawSource:pendingSource.get() mapView:nil]) {
_pendingSource = std::move(pendingSource);
}
return self;
diff --git a/platform/darwin/src/MGLSource_Private.h b/platform/darwin/src/MGLSource_Private.h
index ba78973279..d83ca3335a 100644
--- a/platform/darwin/src/MGLSource_Private.h
+++ b/platform/darwin/src/MGLSource_Private.h
@@ -26,7 +26,7 @@ struct SourceWrapper {
Initializes and returns a source with a raw pointer to the backing store,
associated with a style.
*/
-- (instancetype)initWithRawSource:(mbgl::style::Source *)rawSource;
+- (instancetype)initWithRawSource:(mbgl::style::Source *)rawSource mapView:(nullable MGLMapView *)mapView;
/**
Initializes and returns a source with an owning pointer to the backing store,
diff --git a/platform/darwin/src/MGLStyle.h b/platform/darwin/src/MGLStyle.h
index 6fb4a6cc6b..98be70be9c 100644
--- a/platform/darwin/src/MGLStyle.h
+++ b/platform/darwin/src/MGLStyle.h
@@ -557,6 +557,21 @@ MGL_EXPORT
*/
@property (nonatomic, strong) MGLLight *light;
+#pragma mark Localizing Map Content
+
+/**
+ A Boolean value that determines whether the style attempts to localize labels in
+ the style into the system’s preferred language.
+
+ When this property is enabled, the style automatically modifies the text property
+ of any symbol style layer whose source is the
+ <a href="https://www.mapbox.com/vector-tiles/mapbox-streets-v7/#overview">Mapbox
+ Streets source</a>. On iOS, the user can set the system’s preferred language in
+ Settings, General Settings, Language & Region. On macOS, the user can set the
+ system’s preferred language in the Language & Region pane of System Preferences.
+ */
+@property (nonatomic) BOOL localizesLabels;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLStyle.mm b/platform/darwin/src/MGLStyle.mm
index 2365641f02..d8aa014341 100644
--- a/platform/darwin/src/MGLStyle.mm
+++ b/platform/darwin/src/MGLStyle.mm
@@ -2,7 +2,6 @@
#import "MGLMapView_Private.h"
#import "MGLStyleLayer.h"
-#import "MGLStyleLayer_Private.h"
#import "MGLFillStyleLayer.h"
#import "MGLFillExtrusionStyleLayer.h"
#import "MGLLineStyleLayer.h"
@@ -12,20 +11,24 @@
#import "MGLBackgroundStyleLayer.h"
#import "MGLOpenGLStyleLayer.h"
-#import "MGLSource.h"
+#import "MGLStyle_Private.h"
+#import "MGLStyleLayer_Private.h"
#import "MGLSource_Private.h"
#import "MGLLight_Private.h"
+
+#import "NSDate+MGLAdditions.h"
+
+#import "MGLSource.h"
#import "MGLTileSource_Private.h"
#import "MGLVectorSource.h"
+#import "MGLVectorSource+MGLAdditions.h"
#import "MGLRasterSource.h"
#import "MGLShapeSource.h"
-#import "MGLImageSource.h"
#import "MGLAttributionInfo_Private.h"
#include <mbgl/map/map.hpp>
#include <mbgl/util/default_styles.hpp>
-#include <mbgl/style/style.hpp>
#include <mbgl/style/image.hpp>
#include <mbgl/style/light.hpp>
#include <mbgl/style/layers/fill_layer.hpp>
@@ -39,9 +42,6 @@
#include <mbgl/style/sources/geojson_source.hpp>
#include <mbgl/style/sources/vector_source.hpp>
#include <mbgl/style/sources/raster_source.hpp>
-#include <mbgl/style/sources/image_source.hpp>
-
-#import "NSDate+MGLAdditions.h"
#if TARGET_OS_IPHONE
#import "UIImage+MGLAdditions.h"
@@ -49,12 +49,34 @@
#import "NSImage+MGLAdditions.h"
#endif
+/**
+ Model class for localization changes.
+ */
+@interface MGLTextLanguage: NSObject
+@property (strong, nonatomic) NSString *originalTextField;
+@property (strong, nonatomic) NSString *updatedTextField;
+
+- (instancetype)initWithTextLanguage:(NSString *)originalTextField updatedTextField:(NSString *)updatedTextField;
+
+@end
+
+@implementation MGLTextLanguage
+- (instancetype)initWithTextLanguage:(NSString *)originalTextField updatedTextField:(NSString *)updatedTextField
+{
+ if (self = [super init]) {
+ _originalTextField = originalTextField;
+ _updatedTextField = updatedTextField;
+ }
+ return self;
+}
+@end
+
@interface MGLStyle()
-@property (nonatomic, readonly, weak) MGLMapView *mapView;
-@property (nonatomic, readonly) mbgl::style::Style *rawStyle;
+@property (nonatomic, readwrite, weak) MGLMapView *mapView;
@property (readonly, copy, nullable) NSURL *URL;
@property (nonatomic, readwrite, strong) NS_MUTABLE_DICTIONARY_OF(NSString *, MGLOpenGLStyleLayer *) *openGLLayers;
+@property (nonatomic) NS_MUTABLE_DICTIONARY_OF(NSString *, NS_DICTIONARY_OF(NSObject *, MGLTextLanguage *) *) *localizedLayersByIdentifier;
@end
@@ -114,28 +136,28 @@ static NSURL *MGLStyleURL_emerald;
#pragma mark -
-- (instancetype)initWithRawStyle:(mbgl::style::Style *)rawStyle mapView:(MGLMapView *)mapView {
+- (instancetype)initWithMapView:(MGLMapView *)mapView {
if (self = [super init]) {
_mapView = mapView;
- _rawStyle = rawStyle;
_openGLLayers = [NSMutableDictionary dictionary];
+ _localizedLayersByIdentifier = [NSMutableDictionary dictionary];
}
return self;
}
- (NSURL *)URL {
- return [NSURL URLWithString:@(self.rawStyle->getURL().c_str())];
+ return [NSURL URLWithString:@(self.mapView.mbglMap->getStyleURL().c_str())];
}
- (NSString *)name {
- std::string name = self.rawStyle->getName();
+ std::string name = self.mapView.mbglMap->getStyleName();
return name.empty() ? nil : @(name.c_str());
}
#pragma mark Sources
- (NS_SET_OF(__kindof MGLSource *) *)sources {
- auto rawSources = self.rawStyle->getSources();
+ auto rawSources = self.mapView.mbglMap->getSources();
NS_MUTABLE_SET_OF(__kindof MGLSource *) *sources = [NSMutableSet setWithCapacity:rawSources.size()];
for (auto rawSource = rawSources.begin(); rawSource != rawSources.end(); ++rawSource) {
MGLSource *source = [self sourceFromMBGLSource:*rawSource];
@@ -154,7 +176,8 @@ static NSURL *MGLStyleURL_emerald;
}
- (NSUInteger)countOfSources {
- return self.rawStyle->getSources().size();
+ auto rawSources = self.mapView.mbglMap->getSources();
+ return rawSources.size();
}
- (MGLSource *)memberOfSources:(MGLSource *)object {
@@ -163,7 +186,8 @@ static NSURL *MGLStyleURL_emerald;
- (MGLSource *)sourceWithIdentifier:(NSString *)identifier
{
- auto rawSource = self.rawStyle->getSource(identifier.UTF8String);
+ auto rawSource = self.mapView.mbglMap->getSource(identifier.UTF8String);
+
return rawSource ? [self sourceFromMBGLSource:rawSource] : nil;
}
@@ -175,15 +199,13 @@ static NSURL *MGLStyleURL_emerald;
// TODO: Fill in options specific to the respective source classes
// https://github.com/mapbox/mapbox-gl-native/issues/6584
if (auto vectorSource = rawSource->as<mbgl::style::VectorSource>()) {
- return [[MGLVectorSource alloc] initWithRawSource:vectorSource];
+ return [[MGLVectorSource alloc] initWithRawSource:vectorSource mapView:self.mapView];
} else if (auto geoJSONSource = rawSource->as<mbgl::style::GeoJSONSource>()) {
- return [[MGLShapeSource alloc] initWithRawSource:geoJSONSource];
+ return [[MGLShapeSource alloc] initWithRawSource:geoJSONSource mapView:self.mapView];
} else if (auto rasterSource = rawSource->as<mbgl::style::RasterSource>()) {
- return [[MGLRasterSource alloc] initWithRawSource:rasterSource];
- } else if (auto imageSource = rawSource->as<mbgl::style::ImageSource>()) {
- return [[MGLImageSource alloc] initWithRawSource:imageSource];
+ return [[MGLRasterSource alloc] initWithRawSource:rasterSource mapView:self.mapView];
} else {
- return [[MGLSource alloc] initWithRawSource:rawSource];
+ return [[MGLSource alloc] initWithRawSource:rawSource mapView:self.mapView];
}
}
@@ -197,7 +219,7 @@ static NSURL *MGLStyleURL_emerald;
}
try {
- [source addToStyle:self];
+ [source addToMapView:self.mapView];
} catch (std::runtime_error & err) {
[NSException raise:@"MGLRedundantSourceIdentifierException" format:@"%s", err.what()];
}
@@ -211,14 +233,14 @@ static NSURL *MGLStyleURL_emerald;
@"Make sure the source was created as a member of a concrete subclass of MGLSource.",
source];
}
- [source removeFromStyle:self];
+ [source removeFromMapView:self.mapView];
}
- (nullable NS_ARRAY_OF(MGLAttributionInfo *) *)attributionInfosWithFontSize:(CGFloat)fontSize linkColor:(nullable MGLColor *)linkColor {
// It’d be incredibly convenient to use -sources here, but this operation
// depends on the sources being sorted in ascending order by creation, as
// with the std::vector used in mbgl.
- auto rawSources = self.rawStyle->getSources();
+ auto rawSources = self.mapView.mbglMap->getSources();
NSMutableArray *infos = [NSMutableArray arrayWithCapacity:rawSources.size()];
for (auto rawSource = rawSources.begin(); rawSource != rawSources.end(); ++rawSource) {
MGLTileSource *source = (MGLTileSource *)[self sourceFromMBGLSource:*rawSource];
@@ -236,7 +258,7 @@ static NSURL *MGLStyleURL_emerald;
- (NS_ARRAY_OF(__kindof MGLStyleLayer *) *)layers
{
- auto layers = self.rawStyle->getLayers();
+ auto layers = self.mapView.mbglMap->getLayers();
NS_MUTABLE_ARRAY_OF(__kindof MGLStyleLayer *) *styleLayers = [NSMutableArray arrayWithCapacity:layers.size()];
for (auto layer : layers) {
MGLStyleLayer *styleLayer = [self layerFromMBGLLayer:layer];
@@ -256,12 +278,12 @@ static NSURL *MGLStyleURL_emerald;
- (NSUInteger)countOfLayers
{
- return self.rawStyle->getLayers().size();
+ return self.mapView.mbglMap->getLayers().size();
}
- (MGLStyleLayer *)objectInLayersAtIndex:(NSUInteger)index
{
- auto layers = self.rawStyle->getLayers();
+ auto layers = self.mapView.mbglMap->getLayers();
if (index >= layers.size()) {
[NSException raise:NSRangeException
format:@"No style layer at index %lu.", (unsigned long)index];
@@ -273,7 +295,7 @@ static NSURL *MGLStyleURL_emerald;
- (void)getLayers:(MGLStyleLayer **)buffer range:(NSRange)inRange
{
- auto layers = self.rawStyle->getLayers();
+ auto layers = self.mapView.mbglMap->getLayers();
if (NSMaxRange(inRange) > layers.size()) {
[NSException raise:NSRangeException
format:@"Style layer range %@ is out of bounds.", NSStringFromRange(inRange)];
@@ -293,21 +315,21 @@ static NSURL *MGLStyleURL_emerald;
@"Make sure the style layer was created as a member of a concrete subclass of MGLStyleLayer.",
styleLayer];
}
- auto layers = self.rawStyle->getLayers();
+ auto layers = self.mapView.mbglMap->getLayers();
if (index > layers.size()) {
[NSException raise:NSRangeException
format:@"Cannot insert style layer at out-of-bounds index %lu.", (unsigned long)index];
} else if (index == 0) {
try {
MGLStyleLayer *sibling = layers.size() ? [self layerFromMBGLLayer:layers.at(0)] : nil;
- [styleLayer addToStyle:self belowLayer:sibling];
+ [styleLayer addToMapView:self.mapView belowLayer:sibling];
} catch (const std::runtime_error & err) {
[NSException raise:@"MGLRedundantLayerIdentifierException" format:@"%s", err.what()];
}
} else {
try {
MGLStyleLayer *sibling = [self layerFromMBGLLayer:layers.at(index)];
- [styleLayer addToStyle:self belowLayer:sibling];
+ [styleLayer addToMapView:self.mapView belowLayer:sibling];
} catch (std::runtime_error & err) {
[NSException raise:@"MGLRedundantLayerIdentifierException" format:@"%s", err.what()];
}
@@ -316,14 +338,14 @@ static NSURL *MGLStyleURL_emerald;
- (void)removeObjectFromLayersAtIndex:(NSUInteger)index
{
- auto layers = self.rawStyle->getLayers();
+ auto layers = self.mapView.mbglMap->getLayers();
if (index >= layers.size()) {
[NSException raise:NSRangeException
format:@"Cannot remove style layer at out-of-bounds index %lu.", (unsigned long)index];
}
auto layer = layers.at(index);
MGLStyleLayer *styleLayer = [self layerFromMBGLLayer:layer];
- [styleLayer removeFromStyle:self];
+ [styleLayer removeFromMapView:self.mapView];
}
- (MGLStyleLayer *)layerFromMBGLLayer:(mbgl::style::Layer *)rawLayer
@@ -358,7 +380,7 @@ static NSURL *MGLStyleURL_emerald;
- (MGLStyleLayer *)layerWithIdentifier:(NSString *)identifier
{
- auto mbglLayer = self.rawStyle->getLayer(identifier.UTF8String);
+ auto mbglLayer = self.mapView.mbglMap->getLayer(identifier.UTF8String);
return mbglLayer ? [self layerFromMBGLLayer:mbglLayer] : nil;
}
@@ -371,7 +393,7 @@ static NSURL *MGLStyleURL_emerald;
layer];
}
[self willChangeValueForKey:@"layers"];
- [layer removeFromStyle:self];
+ [layer removeFromMapView:self.mapView];
[self didChangeValueForKey:@"layers"];
}
@@ -385,7 +407,7 @@ static NSURL *MGLStyleURL_emerald;
}
[self willChangeValueForKey:@"layers"];
try {
- [layer addToStyle:self belowLayer:nil];
+ [layer addToMapView:self.mapView belowLayer:nil];
} catch (std::runtime_error & err) {
[NSException raise:@"MGLRedundantLayerIdentifierException" format:@"%s", err.what()];
}
@@ -414,7 +436,7 @@ static NSURL *MGLStyleURL_emerald;
}
[self willChangeValueForKey:@"layers"];
try {
- [layer addToStyle:self belowLayer:sibling];
+ [layer addToMapView:self.mapView belowLayer:sibling];
} catch (std::runtime_error & err) {
[NSException raise:@"MGLRedundantLayerIdentifierException" format:@"%s", err.what()];
}
@@ -437,7 +459,7 @@ static NSURL *MGLStyleURL_emerald;
sibling];
}
- auto layers = self.rawStyle->getLayers();
+ auto layers = self.mapView.mbglMap->getLayers();
std::string siblingIdentifier = sibling.identifier.UTF8String;
NSUInteger index = 0;
for (auto layer : layers) {
@@ -456,14 +478,14 @@ static NSURL *MGLStyleURL_emerald;
sibling];
} else if (index + 1 == layers.size()) {
try {
- [layer addToStyle:self belowLayer:nil];
+ [layer addToMapView:self.mapView belowLayer:nil];
} catch (std::runtime_error & err) {
[NSException raise:@"MGLRedundantLayerIdentifierException" format:@"%s", err.what()];
}
} else {
MGLStyleLayer *sibling = [self layerFromMBGLLayer:layers.at(index + 1)];
try {
- [layer addToStyle:self belowLayer:sibling];
+ [layer addToMapView:self.mapView belowLayer:sibling];
} catch (std::runtime_error & err) {
[NSException raise:@"MGLRedundantLayerIdentifierException" format:@"%s", err.what()];
}
@@ -475,32 +497,60 @@ static NSURL *MGLStyleURL_emerald;
- (NS_ARRAY_OF(NSString *) *)styleClasses
{
- return @[];
+ const std::vector<std::string> &appliedClasses = self.mapView.mbglMap->getClasses();
+
+ NSMutableArray *returnArray = [NSMutableArray arrayWithCapacity:appliedClasses.size()];
+
+ for (auto appliedClass : appliedClasses) {
+ [returnArray addObject:@(appliedClass.c_str())];
+ }
+
+ return returnArray;
}
- (void)setStyleClasses:(NS_ARRAY_OF(NSString *) *)appliedClasses
{
+ [self setStyleClasses:appliedClasses transitionDuration:0];
}
- (void)setStyleClasses:(NS_ARRAY_OF(NSString *) *)appliedClasses transitionDuration:(NSTimeInterval)transitionDuration
{
+ std::vector<std::string> newAppliedClasses;
+
+ for (NSString *appliedClass in appliedClasses)
+ {
+ newAppliedClasses.push_back([appliedClass UTF8String]);
+ }
+
+ mbgl::style::TransitionOptions transition { { MGLDurationFromTimeInterval(transitionDuration) } };
+ self.mapView.mbglMap->setTransitionOptions(transition);
+ self.mapView.mbglMap->setClasses(newAppliedClasses);
}
- (NSUInteger)countOfStyleClasses {
- return 0;
+ const auto &classes = self.mapView.mbglMap->getClasses();
+ return classes.size();
}
- (BOOL)hasStyleClass:(NSString *)styleClass
{
- return NO;
+ return styleClass && self.mapView.mbglMap->hasClass([styleClass UTF8String]);
}
- (void)addStyleClass:(NSString *)styleClass
{
+ if (styleClass)
+ {
+ self.mapView.mbglMap->addClass([styleClass UTF8String]);
+ }
}
- (void)removeStyleClass:(NSString *)styleClass
{
+ if (styleClass)
+ {
+ self.mapView.mbglMap->removeClass([styleClass UTF8String]);
+ }
}
#pragma mark Style images
@@ -516,7 +566,7 @@ static NSURL *MGLStyleURL_emerald;
format:@"Cannot assign image %@ to a nil name.", image];
}
- self.rawStyle->addImage([image mgl_styleImageWithIdentifier:name]);
+ self.mapView.mbglMap->addImage([name UTF8String], image.mgl_styleImage);
}
- (void)removeImageForName:(NSString *)name
@@ -526,7 +576,7 @@ static NSURL *MGLStyleURL_emerald;
format:@"Cannot remove image with nil name."];
}
- self.rawStyle->removeImage([name UTF8String]);
+ self.mapView.mbglMap->removeImage([name UTF8String]);
}
- (MGLImage *)imageForName:(NSString *)name
@@ -536,7 +586,7 @@ static NSURL *MGLStyleURL_emerald;
format:@"Cannot get image with nil name."];
}
- auto styleImage = self.rawStyle->getImage([name UTF8String]);
+ auto styleImage = self.mapView.mbglMap->getImage([name UTF8String]);
return styleImage ? [[MGLImage alloc] initWithMGLStyleImage:styleImage] : nil;
}
@@ -544,17 +594,17 @@ static NSURL *MGLStyleURL_emerald;
- (void)setTransition:(MGLTransition)transition
{
- auto transitionOptions = self.rawStyle->getTransitionOptions();
+ auto transitionOptions = self.mapView.mbglMap->getTransitionOptions();
transitionOptions.duration = MGLDurationFromTimeInterval(transition.duration);
transitionOptions.delay = MGLDurationFromTimeInterval(transition.delay);
- self.rawStyle->setTransitionOptions(transitionOptions);
+ self.mapView.mbglMap->setTransitionOptions(transitionOptions);
}
- (MGLTransition)transition
{
MGLTransition transition;
- const mbgl::style::TransitionOptions transitionOptions = self.rawStyle->getTransitionOptions();
+ const mbgl::style::TransitionOptions transitionOptions = self.mapView.mbglMap->getTransitionOptions();
transition.delay = MGLTimeIntervalFromDuration(transitionOptions.delay.value_or(mbgl::Duration::zero()));
transition.duration = MGLTimeIntervalFromDuration(transitionOptions.duration.value_or(mbgl::Duration::zero()));
@@ -567,12 +617,12 @@ static NSURL *MGLStyleURL_emerald;
- (void)setLight:(MGLLight *)light
{
std::unique_ptr<mbgl::style::Light> mbglLight = std::make_unique<mbgl::style::Light>([light mbglLight]);
- self.rawStyle->setLight(std::move(mbglLight));
+ self.mapView.mbglMap->setLight(std::move(mbglLight));
}
- (MGLLight *)light
{
- auto mbglLight = self.rawStyle->getLight();
+ auto mbglLight = self.mapView.mbglMap->getLight();
MGLLight *light = [[MGLLight alloc] initWithMBGLLight:mbglLight];
return light;
}
@@ -585,4 +635,115 @@ static NSURL *MGLStyleURL_emerald;
self.URL ? [NSString stringWithFormat:@"\"%@\"", self.URL] : self.URL];
}
+#pragma mark Style language preferences
+
+- (void)setLocalizesLabels:(BOOL)localizesLabels
+{
+ if (_localizesLabels != localizesLabels) {
+ _localizesLabels = localizesLabels;
+ } else {
+ return;
+ }
+
+ if (_localizesLabels) {
+ NSString *preferredLanguage = [MGLVectorSource preferredMapboxStreetsLanguage];
+ NSMutableDictionary *localizedKeysByKeyBySourceIdentifier = [NSMutableDictionary dictionary];
+ for (MGLSymbolStyleLayer *layer in self.layers) {
+ if (![layer isKindOfClass:[MGLSymbolStyleLayer class]]) {
+ continue;
+ }
+
+ MGLVectorSource *source = (MGLVectorSource *)[self sourceWithIdentifier:layer.sourceIdentifier];
+ if (![source isKindOfClass:[MGLVectorSource class]] || !source.mapboxStreets) {
+ continue;
+ }
+
+ NSDictionary *localizedKeysByKey = localizedKeysByKeyBySourceIdentifier[layer.sourceIdentifier];
+ if (!localizedKeysByKey) {
+ localizedKeysByKey = localizedKeysByKeyBySourceIdentifier[layer.sourceIdentifier] = [source localizedKeysByKeyForPreferredLanguage:preferredLanguage];
+ }
+
+ NSString *(^stringByLocalizingString)(NSString *) = ^ NSString * (NSString *string) {
+ NSMutableString *localizedString = string.mutableCopy;
+ [localizedKeysByKey enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull localizedKey, BOOL * _Nonnull stop) {
+ NSAssert([key isKindOfClass:[NSString class]], @"key is not a string");
+ NSAssert([localizedKey isKindOfClass:[NSString class]], @"localizedKey is not a string");
+ [localizedString replaceOccurrencesOfString:[NSString stringWithFormat:@"{%@}", key]
+ withString:[NSString stringWithFormat:@"{%@}", localizedKey]
+ options:0
+ range:NSMakeRange(0, localizedString.length)];
+ }];
+ return localizedString;
+ };
+
+ if ([layer.text isKindOfClass:[MGLConstantStyleValue class]]) {
+ NSString *textField = [(MGLConstantStyleValue<NSString *> *)layer.text rawValue];
+ NSString *localizingString = stringByLocalizingString(textField);
+ if (![textField isEqualToString:localizingString]) {
+ MGLTextLanguage *textLanguage = [[MGLTextLanguage alloc] initWithTextLanguage:textField
+ updatedTextField:localizingString];
+ [self.localizedLayersByIdentifier setObject:@{ textField : textLanguage } forKey:layer.identifier];
+ layer.text = [MGLStyleValue<NSString *> valueWithRawValue:localizingString];
+ }
+ }
+ else if ([layer.text isKindOfClass:[MGLCameraStyleFunction class]]) {
+ MGLCameraStyleFunction *function = (MGLCameraStyleFunction<NSString *> *)layer.text;
+ NSMutableDictionary *stops = function.stops.mutableCopy;
+ NSMutableDictionary *cameraStops = [NSMutableDictionary dictionary];
+ [stops enumerateKeysAndObjectsUsingBlock:^(NSNumber *zoomLevel, MGLConstantStyleValue<NSString *> *stop, BOOL *done) {
+ NSString *textField = stop.rawValue;
+ NSString *localizingString = stringByLocalizingString(textField);
+ if (![textField isEqualToString:localizingString]) {
+ MGLTextLanguage *textLanguage = [[MGLTextLanguage alloc] initWithTextLanguage:textField
+ updatedTextField:localizingString];
+ [cameraStops setObject:textLanguage forKey:zoomLevel];
+ stops[zoomLevel] = [MGLStyleValue<NSString *> valueWithRawValue:localizingString];
+ }
+
+ }];
+ if (cameraStops.count > 0) {
+ [self.localizedLayersByIdentifier setObject:cameraStops forKey:layer.identifier];
+ }
+ function.stops = stops;
+ layer.text = function;
+ }
+ }
+ } else {
+
+ [self.localizedLayersByIdentifier enumerateKeysAndObjectsUsingBlock:^(NSString *identifier, NSDictionary<NSObject *, MGLTextLanguage *> *textFields, BOOL *done) {
+ MGLSymbolStyleLayer *layer = (MGLSymbolStyleLayer *)[self.mapView.style layerWithIdentifier:identifier];
+
+ if ([layer.text isKindOfClass:[MGLConstantStyleValue class]]) {
+ NSString *textField = [(MGLConstantStyleValue<NSString *> *)layer.text rawValue];
+ [textFields enumerateKeysAndObjectsUsingBlock:^(NSObject *originalLanguage, MGLTextLanguage *textLanguage, BOOL *done) {
+ if ([textLanguage.updatedTextField isEqualToString:textField]) {
+ layer.text = [MGLStyleValue<NSString *> valueWithRawValue:textLanguage.originalTextField];
+ }
+ }];
+
+ }
+ else if ([layer.text isKindOfClass:[MGLCameraStyleFunction class]]) {
+ MGLCameraStyleFunction *function = (MGLCameraStyleFunction<NSString *> *)layer.text;
+ NSMutableDictionary *stops = function.stops.mutableCopy;
+ [textFields enumerateKeysAndObjectsUsingBlock:^(NSObject *zoomKey, MGLTextLanguage *textLanguage, BOOL *done) {
+ if ([zoomKey isKindOfClass:[NSNumber class]]) {
+ NSNumber *zoomLevel = (NSNumber*)zoomKey;
+ MGLConstantStyleValue<NSString *> *stop = [stops objectForKey:zoomLevel];
+ NSString *textField = stop.rawValue;
+ if ([textLanguage.updatedTextField isEqualToString:textField]) {
+ stops[zoomLevel] = [MGLStyleValue<NSString *> valueWithRawValue:textLanguage.originalTextField];
+ }
+ }
+ }];
+
+ function.stops = stops;
+ layer.text = function;
+ }
+
+ }];
+
+ self.localizedLayersByIdentifier = [NSMutableDictionary dictionary];
+ }
+}
+
@end
diff --git a/platform/macos/app/MGLVectorSource+MBXAdditions.h b/platform/darwin/src/MGLVectorSource+MGLAdditions.h
index 1e25ee5a60..43b0aba747 100644
--- a/platform/macos/app/MGLVectorSource+MBXAdditions.h
+++ b/platform/darwin/src/MGLVectorSource+MGLAdditions.h
@@ -2,7 +2,7 @@
NS_ASSUME_NONNULL_BEGIN
-@interface MGLVectorSource (MBXAdditions)
+@interface MGLVectorSource (MGLAdditions)
+ (NSString *)preferredMapboxStreetsLanguage;
diff --git a/platform/macos/app/MGLVectorSource+MBXAdditions.m b/platform/darwin/src/MGLVectorSource+MGLAdditions.m
index 323bc74366..a305388117 100644
--- a/platform/macos/app/MGLVectorSource+MBXAdditions.m
+++ b/platform/darwin/src/MGLVectorSource+MGLAdditions.m
@@ -1,6 +1,6 @@
-#import "MGLVectorSource+MBXAdditions.h"
+#import "MGLVectorSource+MGLAdditions.h"
-@implementation MGLVectorSource (MBXAdditions)
+@implementation MGLVectorSource (MGLAdditions)
+ (NS_SET_OF(NSString *) *)mapboxStreetsLanguages {
// https://www.mapbox.com/vector-tiles/mapbox-streets-v7/#overview
diff --git a/platform/darwin/test/MGLDocumentationExampleTests.swift b/platform/darwin/test/MGLDocumentationExampleTests.swift
index ae72b35d82..42c656f203 100644
--- a/platform/darwin/test/MGLDocumentationExampleTests.swift
+++ b/platform/darwin/test/MGLDocumentationExampleTests.swift
@@ -103,6 +103,18 @@ class MGLDocumentationExampleTests: XCTestCase, MGLMapViewDelegate {
XCTAssertNotNil(mapView.style?.source(withIdentifier: "pois"))
}
+
+ func testMGLPolyline() {
+ //#-example-code
+ let coordinates = [
+ CLLocationCoordinate2D(latitude: 35.68476, longitude: -220.24257),
+ CLLocationCoordinate2D(latitude: 37.78428, longitude: -122.41310)
+ ]
+ let polyline = MGLPolyline(coordinates: coordinates, count: UInt(coordinates.count))
+ //#-end-example-code
+
+ XCTAssertNotNil(polyline)
+ }
func testMGLImageSource() {
//#-example-code
diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md
index 9d6259d313..5c74dcf223 100644
--- a/platform/ios/CHANGELOG.md
+++ b/platform/ios/CHANGELOG.md
@@ -14,7 +14,22 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
* Increased the default maximum zoom level from 20 to 22. ([#9835](https://github.com/mapbox/mapbox-gl-native/pull/9835))
-## 3.6.0
+## 3.6.2
+
+* Added an `MGLStyle.localizesLabels` property, off by default, that localizes any Mapbox Streets–sourced symbol layer into the user’s preferred language. ([#9582](https://github.com/mapbox/mapbox-gl-native/pull/9582))
+* Added an additional camera method to MGLMapView that accepts an edge padding parameter. ([#9651](https://github.com/mapbox/mapbox-gl-native/pull/9651))
+* Fixed an issue with the scaling of the user location annotation’s horizontal accuracy indicator. ([#9721](https://github.com/mapbox/mapbox-gl-native/pull/9721))
+* Fixed an issue that caused `-[MGLShapeSource featuresMatchingPredicate:]` and `-[MGLVectorSource featuresInSourceLayersWithIdentifiers:predicate:]` to always return an empty array. ([#9784](https://github.com/mapbox/mapbox-gl-native/pull/9784))
+
+## 3.6.1 - July 28, 2017
+
+* Reduced the size of the dynamic framework by optimizing symbol visibility. ([#7604](https://github.com/mapbox/mapbox-gl-native/pull/7604))
+* Fixed an issue where the attribution button would have its custom tint color reset when the map view received a tint color change notification, such as when an alert controller was presented. ([#9598](https://github.com/mapbox/mapbox-gl-native/pull/9598))
+* Improved the behavior of zoom gestures when the map reaches the minimum zoom limit. ([#9626](https://github.com/mapbox/mapbox-gl-native/pull/9626))
+* Fixed an issue where tilt gesture was triggered with two fingers aligned vertically and panning down. ([#9571](https://github.com/mapbox/mapbox-gl-native/pull/9571))
+* Bitcode symbol maps (.bcsymbolmap files) are now included with the dynamic framework. ([#9613](https://github.com/mapbox/mapbox-gl-native/pull/9613))
+
+## 3.6.0 - June 29, 2017
### Packaging
diff --git a/platform/ios/Mapbox-iOS-SDK-nightly-dynamic.podspec b/platform/ios/Mapbox-iOS-SDK-nightly-dynamic.podspec
index c7b14ead3b..b5f9af2e61 100644
--- a/platform/ios/Mapbox-iOS-SDK-nightly-dynamic.podspec
+++ b/platform/ios/Mapbox-iOS-SDK-nightly-dynamic.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |m|
- version = '3.6.0-alpha.1'
+ version = '3.6.2'
m.name = 'Mapbox-iOS-SDK-nightly-dynamic'
m.version = "#{version}-nightly"
diff --git a/platform/ios/Mapbox-iOS-SDK-symbols.podspec b/platform/ios/Mapbox-iOS-SDK-symbols.podspec
index d2a686f1fb..0fcd335071 100644
--- a/platform/ios/Mapbox-iOS-SDK-symbols.podspec
+++ b/platform/ios/Mapbox-iOS-SDK-symbols.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |m|
- version = '3.6.0'
+ version = '3.6.2'
m.name = 'Mapbox-iOS-SDK-symbols'
m.version = "#{version}-symbols"
diff --git a/platform/ios/Mapbox-iOS-SDK.podspec b/platform/ios/Mapbox-iOS-SDK.podspec
index 55e8791b4c..0224048ff5 100644
--- a/platform/ios/Mapbox-iOS-SDK.podspec
+++ b/platform/ios/Mapbox-iOS-SDK.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |m|
- version = '3.6.0'
+ version = '3.6.2'
m.name = 'Mapbox-iOS-SDK'
m.version = version
diff --git a/platform/ios/app/Assets.xcassets/settings.imageset/Contents.json b/platform/ios/app/Assets.xcassets/settings.imageset/Contents.json
index 1eeddba9b9..228b81a818 100644
--- a/platform/ios/app/Assets.xcassets/settings.imageset/Contents.json
+++ b/platform/ios/app/Assets.xcassets/settings.imageset/Contents.json
@@ -2,24 +2,11 @@
"images" : [
{
"idiom" : "universal",
- "filename" : "settings.png",
- "scale" : "1x"
- },
- {
- "idiom" : "universal",
- "filename" : "settings@2x.png",
- "scale" : "2x"
- },
- {
- "idiom" : "universal",
- "scale" : "3x"
+ "filename" : "settings.pdf"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
- },
- "properties" : {
- "template-rendering-intent" : "template"
}
} \ No newline at end of file
diff --git a/platform/ios/app/Assets.xcassets/settings.imageset/settings.pdf b/platform/ios/app/Assets.xcassets/settings.imageset/settings.pdf
new file mode 100644
index 0000000000..46aa7443f0
--- /dev/null
+++ b/platform/ios/app/Assets.xcassets/settings.imageset/settings.pdf
Binary files differ
diff --git a/platform/ios/app/Assets.xcassets/settings.imageset/settings.png b/platform/ios/app/Assets.xcassets/settings.imageset/settings.png
deleted file mode 100644
index 5d7643eef5..0000000000
--- a/platform/ios/app/Assets.xcassets/settings.imageset/settings.png
+++ /dev/null
Binary files differ
diff --git a/platform/ios/app/Assets.xcassets/settings.imageset/settings@2x.png b/platform/ios/app/Assets.xcassets/settings.imageset/settings@2x.png
deleted file mode 100644
index 2bb9f0ebad..0000000000
--- a/platform/ios/app/Assets.xcassets/settings.imageset/settings@2x.png
+++ /dev/null
Binary files differ
diff --git a/platform/ios/app/Default-568h@2x.png b/platform/ios/app/Default-568h@2x.png
deleted file mode 100644
index 0891b7aabf..0000000000
--- a/platform/ios/app/Default-568h@2x.png
+++ /dev/null
Binary files differ
diff --git a/platform/ios/app/Info.plist b/platform/ios/app/Info.plist
index d5b6825422..167e66fa09 100644
--- a/platform/ios/app/Info.plist
+++ b/platform/ios/app/Info.plist
@@ -51,5 +51,16 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
+ <key>UIApplicationShortcutItems</key>
+ <array>
+ <dict>
+ <key>UIApplicationShortcutItemTitle</key>
+ <string>Settings</string>
+ <key>UIApplicationShortcutItemType</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER).settings</string>
+ <key>UIApplicationShortcutItemIconFile</key>
+ <string>settings</string>
+ </dict>
+ </array>
</dict>
</plist>
diff --git a/platform/ios/app/LaunchScreen.storyboard b/platform/ios/app/LaunchScreen.storyboard
index 323bd43177..299e186886 100644
--- a/platform/ios/app/LaunchScreen.storyboard
+++ b/platform/ios/app/LaunchScreen.storyboard
@@ -1,8 +1,12 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10116" systemVersion="15E65" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
+ <device id="retina4_7" orientation="portrait">
+ <adaptation id="fullscreen"/>
+ </device>
<dependencies>
<deployment identifier="iOS"/>
- <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
@@ -14,9 +18,9 @@
<viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
- <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
- <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+ <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
diff --git a/platform/ios/app/MBXAppDelegate.m b/platform/ios/app/MBXAppDelegate.m
index c2834bfa7f..1934f4912b 100644
--- a/platform/ios/app/MBXAppDelegate.m
+++ b/platform/ios/app/MBXAppDelegate.m
@@ -26,4 +26,22 @@ NSString * const MBXMapboxAccessTokenDefaultsKey = @"MBXMapboxAccessToken";
return YES;
}
+#pragma mark - Quick actions
+
+- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler {
+ completionHandler([self handleShortcut:shortcutItem]);
+}
+
+- (BOOL)handleShortcut:(UIApplicationShortcutItem *)shortcut {
+ if ([[shortcut.type componentsSeparatedByString:@"."].lastObject isEqual:@"settings"]) {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
+ });
+
+ return YES;
+ }
+
+ return NO;
+}
+
@end
diff --git a/platform/ios/app/MBXViewController.m b/platform/ios/app/MBXViewController.m
index 29c5c65012..992b7d587a 100644
--- a/platform/ios/app/MBXViewController.m
+++ b/platform/ios/app/MBXViewController.m
@@ -34,7 +34,6 @@ typedef NS_ENUM(NSInteger, MBXSettingsCoreRenderingRows) {
MBXSettingsCoreRenderingTimestamps,
MBXSettingsCoreRenderingCollisionBoxes,
MBXSettingsCoreRenderingOverdrawVisualization,
- MBXSettingsCoreRenderingToggleTwoMaps,
};
typedef NS_ENUM(NSInteger, MBXSettingsAnnotationsRows) {
@@ -48,12 +47,12 @@ typedef NS_ENUM(NSInteger, MBXSettingsAnnotationsRows) {
MBXSettingsAnnotationsTestShapes,
MBXSettingsAnnotationsCustomCallout,
MBXSettingsAnnotationsQueryAnnotations,
+ MBXSettingsAnnotationsCustomUserDot,
MBXSettingsAnnotationsRemoveAnnotations,
};
typedef NS_ENUM(NSInteger, MBXSettingsRuntimeStylingRows) {
- MBXSettingsRuntimeStylingBuildingExtrusions = 0,
- MBXSettingsRuntimeStylingWater,
+ MBXSettingsRuntimeStylingWater = 0,
MBXSettingsRuntimeStylingRoads,
MBXSettingsRuntimeStylingRaster,
MBXSettingsRuntimeStylingShape,
@@ -72,8 +71,6 @@ typedef NS_ENUM(NSInteger, MBXSettingsRuntimeStylingRows) {
MBXSettingsRuntimeStylingUpdateShapeSourceFeatures,
MBXSettingsRuntimeStylingVectorSource,
MBXSettingsRuntimeStylingRasterSource,
- MBXSettingsRuntimeStylingImageSource,
- MBXSettingsRuntimeStylingCountryLabels,
MBXSettingsRuntimeStylingRouteLine,
MBXSettingsRuntimeStylingDDSPolygon,
};
@@ -81,9 +78,10 @@ typedef NS_ENUM(NSInteger, MBXSettingsRuntimeStylingRows) {
typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
MBXSettingsMiscellaneousShowReuseQueueStats = 0,
MBXSettingsMiscellaneousWorldTour,
- MBXSettingsMiscellaneousCustomUserDot,
MBXSettingsMiscellaneousShowZoomLevel,
MBXSettingsMiscellaneousScrollView,
+ MBXSettingsMiscellaneousToggleTwoMaps,
+ MBXSettingsMiscellaneousCountryLabels,
MBXSettingsMiscellaneousPrintLogFile,
MBXSettingsMiscellaneousDeleteLogFile,
};
@@ -305,8 +303,6 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
(debugMask & MGLMapDebugCollisionBoxesMask ? @"Hide" :@"Show")],
[NSString stringWithFormat:@"%@ Overdraw Visualization",
(debugMask & MGLMapDebugOverdrawVisualizationMask ? @"Hide" :@"Show")],
- [NSString stringWithFormat:@"%@ Second Map",
- ([self.view viewWithTag:2] == nil ? @"Show" : @"Hide")],
]];
break;
case MBXSettingsAnnotations:
@@ -321,12 +317,12 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
@"Add Test Shapes",
@"Add Point With Custom Callout",
@"Query Annotations",
+ [NSString stringWithFormat:@"%@ Custom User Dot", (_customUserLocationAnnnotationEnabled ? @"Disable" : @"Enable")],
@"Remove Annotations",
]];
break;
case MBXSettingsRuntimeStyling:
[settingsTitles addObjectsFromArray:@[
- @"Add Building Extrusions",
@"Style Water With Function",
@"Style Roads With Function",
@"Add Raster & Apply Function",
@@ -346,8 +342,6 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
@"Update Shape Source: Features",
@"Style Vector Source",
@"Style Raster Source",
- @"Style Image Source",
- [NSString stringWithFormat:@"Label Countries in %@", (_usingLocaleBasedCountryLabels ? @"Local Language" : [[NSLocale currentLocale] displayNameForKey:NSLocaleIdentifier value:[self bestLanguageForUser]])],
@"Add Route Line",
@"Dynamically Style Polygon",
]];
@@ -356,9 +350,10 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
[settingsTitles addObjectsFromArray:@[
[NSString stringWithFormat:@"%@ Reuse Queue Stats", (_reuseQueueStatsEnabled ? @"Hide" :@"Show")],
@"Start World Tour",
- [NSString stringWithFormat:@"%@ Custom User Dot", (_customUserLocationAnnnotationEnabled ? @"Disable" : @"Enable")],
[NSString stringWithFormat:@"%@ Zoom Level", (_showZoomLevelEnabled ? @"Hide" :@"Show")],
@"Embedded Map View",
+ [NSString stringWithFormat:@"%@ Second Map", ([self.view viewWithTag:2] == nil ? @"Show" : @"Hide")],
+ [NSString stringWithFormat:@"Show Labels in %@", (_usingLocaleBasedCountryLabels ? @"Default Language" : [[NSLocale currentLocale] displayNameForKey:NSLocaleIdentifier value:[self bestLanguageForUser]])],
]];
if (self.debugLoggingEnabled)
@@ -403,81 +398,6 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
case MBXSettingsCoreRenderingOverdrawVisualization:
self.mapView.debugMask ^= MGLMapDebugOverdrawVisualizationMask;
break;
- case MBXSettingsCoreRenderingToggleTwoMaps:
- if ([self.view viewWithTag:2] == nil) {
- MGLMapView *secondMapView = [[MGLMapView alloc] initWithFrame:
- CGRectMake(0, self.view.bounds.size.height / 2,
- self.view.bounds.size.width, self.view.bounds.size.height / 2)];
- secondMapView.translatesAutoresizingMaskIntoConstraints = false;
- secondMapView.tag = 2;
- for (NSLayoutConstraint *constraint in self.view.constraints)
- {
- if ((constraint.firstItem == self.mapView && constraint.firstAttribute == NSLayoutAttributeBottom) ||
- (constraint.secondItem == self.mapView && constraint.secondAttribute == NSLayoutAttributeBottom))
- {
- [self.view removeConstraint:constraint];
- break;
- }
- }
- [self.view addSubview:secondMapView];
- [self.view addConstraints:@[
- [NSLayoutConstraint constraintWithItem:self.mapView
- attribute:NSLayoutAttributeBottom
- relatedBy:NSLayoutRelationEqual
- toItem:self.view
- attribute:NSLayoutAttributeCenterY
- multiplier:1
- constant:0],
- [NSLayoutConstraint constraintWithItem:secondMapView
- attribute:NSLayoutAttributeCenterX
- relatedBy:NSLayoutRelationEqual
- toItem:self.view
- attribute:NSLayoutAttributeCenterX
- multiplier:1
- constant:0],
- [NSLayoutConstraint constraintWithItem:secondMapView
- attribute:NSLayoutAttributeWidth
- relatedBy:NSLayoutRelationEqual
- toItem:self.view
- attribute:NSLayoutAttributeWidth
- multiplier:1
- constant:0],
- [NSLayoutConstraint constraintWithItem:secondMapView
- attribute:NSLayoutAttributeTop
- relatedBy:NSLayoutRelationEqual
- toItem:self.view
- attribute:NSLayoutAttributeCenterY
- multiplier:1
- constant:0],
- [NSLayoutConstraint constraintWithItem:secondMapView
- attribute:NSLayoutAttributeBottom
- relatedBy:NSLayoutRelationEqual
- toItem:self.bottomLayoutGuide
- attribute:NSLayoutAttributeTop
- multiplier:1
- constant:0],
- ]];
- } else {
- NSMutableArray *constraintsToRemove = [NSMutableArray array];
- MGLMapView *secondMapView = (MGLMapView *)[self.view viewWithTag:2];
- for (NSLayoutConstraint *constraint in self.view.constraints)
- {
- if (constraint.firstItem == secondMapView || constraint.secondItem == secondMapView)
- {
- [constraintsToRemove addObject:constraint];
- }
- }
- [self.view removeConstraints:constraintsToRemove];
- [secondMapView removeFromSuperview];
- [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.mapView
- attribute:NSLayoutAttributeBottom
- relatedBy:NSLayoutRelationEqual
- toItem:self.bottomLayoutGuide
- attribute:NSLayoutAttributeTop
- multiplier:1
- constant:0]];
- }
- break;
default:
NSAssert(NO, @"All core rendering setting rows should be implemented");
break;
@@ -516,6 +436,9 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
case MBXSettingsAnnotationsQueryAnnotations:
[self testQueryPointAnnotations];
break;
+ case MBXSettingsAnnotationsCustomUserDot:
+ [self toggleCustomUserDot];
+ break;
case MBXSettingsAnnotationsRemoveAnnotations:
[self.mapView removeAnnotations:self.mapView.annotations];
break;
@@ -527,9 +450,6 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
case MBXSettingsRuntimeStyling:
switch (indexPath.row)
{
- case MBXSettingsRuntimeStylingBuildingExtrusions:
- [self styleBuildingExtrusions];
- break;
case MBXSettingsRuntimeStylingWater:
[self styleWaterLayer];
break;
@@ -587,12 +507,6 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
case MBXSettingsRuntimeStylingRasterSource:
[self styleRasterSource];
break;
- case MBXSettingsRuntimeStylingImageSource:
- [self styleImageSource];
- break;
- case MBXSettingsRuntimeStylingCountryLabels:
- [self styleCountryLabelsLanguage];
- break;
case MBXSettingsRuntimeStylingRouteLine:
[self styleRouteLine];
break;
@@ -607,12 +521,12 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
case MBXSettingsMiscellaneous:
switch (indexPath.row)
{
+ case MBXSettingsMiscellaneousCountryLabels:
+ [self styleCountryLabelsLanguage];
+ break;
case MBXSettingsMiscellaneousWorldTour:
[self startWorldTour];
break;
- case MBXSettingsMiscellaneousCustomUserDot:
- [self toggleCustomUserDot];
- break;
case MBXSettingsMiscellaneousPrintLogFile:
[self printTelemetryLogFile];
break;
@@ -640,6 +554,81 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
[self.navigationController pushViewController:embeddedMapViewController animated:YES];
break;
}
+ case MBXSettingsMiscellaneousToggleTwoMaps:
+ if ([self.view viewWithTag:2] == nil) {
+ MGLMapView *secondMapView = [[MGLMapView alloc] initWithFrame:
+ CGRectMake(0, self.view.bounds.size.height / 2,
+ self.view.bounds.size.width, self.view.bounds.size.height / 2)];
+ secondMapView.translatesAutoresizingMaskIntoConstraints = false;
+ secondMapView.tag = 2;
+ for (NSLayoutConstraint *constraint in self.view.constraints)
+ {
+ if ((constraint.firstItem == self.mapView && constraint.firstAttribute == NSLayoutAttributeBottom) ||
+ (constraint.secondItem == self.mapView && constraint.secondAttribute == NSLayoutAttributeBottom))
+ {
+ [self.view removeConstraint:constraint];
+ break;
+ }
+ }
+ [self.view addSubview:secondMapView];
+ [self.view addConstraints:@[
+ [NSLayoutConstraint constraintWithItem:self.mapView
+ attribute:NSLayoutAttributeBottom
+ relatedBy:NSLayoutRelationEqual
+ toItem:self.view
+ attribute:NSLayoutAttributeCenterY
+ multiplier:1
+ constant:0],
+ [NSLayoutConstraint constraintWithItem:secondMapView
+ attribute:NSLayoutAttributeCenterX
+ relatedBy:NSLayoutRelationEqual
+ toItem:self.view
+ attribute:NSLayoutAttributeCenterX
+ multiplier:1
+ constant:0],
+ [NSLayoutConstraint constraintWithItem:secondMapView
+ attribute:NSLayoutAttributeWidth
+ relatedBy:NSLayoutRelationEqual
+ toItem:self.view
+ attribute:NSLayoutAttributeWidth
+ multiplier:1
+ constant:0],
+ [NSLayoutConstraint constraintWithItem:secondMapView
+ attribute:NSLayoutAttributeTop
+ relatedBy:NSLayoutRelationEqual
+ toItem:self.view
+ attribute:NSLayoutAttributeCenterY
+ multiplier:1
+ constant:0],
+ [NSLayoutConstraint constraintWithItem:secondMapView
+ attribute:NSLayoutAttributeBottom
+ relatedBy:NSLayoutRelationEqual
+ toItem:self.bottomLayoutGuide
+ attribute:NSLayoutAttributeTop
+ multiplier:1
+ constant:0],
+ ]];
+ } else {
+ NSMutableArray *constraintsToRemove = [NSMutableArray array];
+ MGLMapView *secondMapView = (MGLMapView *)[self.view viewWithTag:2];
+ for (NSLayoutConstraint *constraint in self.view.constraints)
+ {
+ if (constraint.firstItem == secondMapView || constraint.secondItem == secondMapView)
+ {
+ [constraintsToRemove addObject:constraint];
+ }
+ }
+ [self.view removeConstraints:constraintsToRemove];
+ [secondMapView removeFromSuperview];
+ [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.mapView
+ attribute:NSLayoutAttributeBottom
+ relatedBy:NSLayoutRelationEqual
+ toItem:self.bottomLayoutGuide
+ attribute:NSLayoutAttributeTop
+ multiplier:1
+ constant:0]];
+ }
+ break;
default:
NSAssert(NO, @"All miscellaneous setting rows should be implemented");
break;
@@ -870,38 +859,6 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
[self.mapView showAnnotations:annotations animated:YES];
}
-- (void)styleBuildingExtrusions
-{
- MGLSource* source = [self.mapView.style sourceWithIdentifier:@"composite"];
- if (source) {
-
- MGLFillExtrusionStyleLayer* layer = [[MGLFillExtrusionStyleLayer alloc] initWithIdentifier:@"extrudedBuildings" source:source];
- layer.sourceLayerIdentifier = @"building";
- layer.predicate = [NSPredicate predicateWithFormat:@"extrude == 'true' AND height > 0"];
- layer.fillExtrusionBase = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"min_height" options:nil];
- layer.fillExtrusionHeight = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"height" options:nil];
-
- // Set the fill color to that of the existing building footprint layer, if it exists.
- MGLFillStyleLayer* buildingLayer = (MGLFillStyleLayer*)[self.mapView.style layerWithIdentifier:@"building"];
- if (buildingLayer) {
- if (buildingLayer.fillColor) {
- layer.fillExtrusionColor = buildingLayer.fillColor;
- } else {
- layer.fillExtrusionColor = [MGLStyleValue valueWithRawValue:[UIColor whiteColor]];
- }
-
- layer.fillExtrusionOpacity = [MGLStyleValue<NSNumber *> valueWithRawValue:@0.75];
- }
-
- MGLStyleLayer* labelLayer = [self.mapView.style layerWithIdentifier:@"waterway-label"];
- if (labelLayer) {
- [self.mapView.style insertLayer:layer belowLayer:labelLayer];
- } else {
- [self.mapView.style addLayer:layer];
- }
- }
-}
-
- (void)styleWaterLayer
{
MGLFillStyleLayer *waterLayer = (MGLFillStyleLayer *)[self.mapView.style layerWithIdentifier:@"water"];
@@ -1303,8 +1260,8 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
- (void)styleRasterSource
{
- NSArray *tileURLTemplates = @[@"https://stamen-tiles.a.ssl.fastly.net/terrain-background/{z}/{x}/{y}.jpg"];
- MGLRasterSource *rasterSource = [[MGLRasterSource alloc] initWithIdentifier:@"style-raster-source-id" tileURLTemplates:tileURLTemplates options:@{
+ NSString *tileURL = [NSString stringWithFormat:@"https://stamen-tiles.a.ssl.fastly.net/terrain-background/{z}/{x}/{y}%@.jpg", UIScreen.mainScreen.nativeScale > 1 ? @"@2x" : @""];
+ MGLRasterSource *rasterSource = [[MGLRasterSource alloc] initWithIdentifier:@"style-raster-source-id" tileURLTemplates:@[tileURL] options:@{
MGLTileSourceOptionTileSize: @256,
}];
[self.mapView.style addSource:rasterSource];
@@ -1313,47 +1270,10 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
[self.mapView.style addLayer:rasterLayer];
}
-- (void)styleImageSource
-{
- MGLCoordinateQuad coordinateQuad = {
- { 46.437, -80.425 },
- { 37.936, -80.425 },
- { 37.936, -71.516 },
- { 46.437, -71.516 } };
-
- MGLImageSource *imageSource = [[MGLImageSource alloc] initWithIdentifier:@"style-image-source-id" coordinateQuad:coordinateQuad URL:[NSURL URLWithString:@"https://www.mapbox.com/mapbox-gl-js/assets/radar0.gif"]];
-
- [self.mapView.style addSource:imageSource];
-
- MGLRasterStyleLayer *rasterLayer = [[MGLRasterStyleLayer alloc] initWithIdentifier:@"style-raster-image-layer-id" source:imageSource];
- [self.mapView.style addLayer:rasterLayer];
-
- [NSTimer scheduledTimerWithTimeInterval:1.0
- target:self
- selector:@selector(updateAnimatedImageSource:)
- userInfo:imageSource
- repeats:YES];
-}
-
-
-- (void)updateAnimatedImageSource:(NSTimer *)timer {
- static int radarSuffix = 0;
- MGLImageSource *imageSource = (MGLImageSource *)timer.userInfo;
- NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"https://www.mapbox.com/mapbox-gl-js/assets/radar%d.gif", radarSuffix++]];
- [imageSource setValue:url forKey:@"URL"];
- if (radarSuffix > 3) {
- radarSuffix = 0;
- }
-}
-
-(void)styleCountryLabelsLanguage
{
- NSArray<NSString *> *labelLayers = @[
- @"country-label-lg",
- @"country-label-md",
- @"country-label-sm",
- ];
- [self styleLabelLanguageForLayersNamed:labelLayers];
+ _usingLocaleBasedCountryLabels = !_usingLocaleBasedCountryLabels;
+ self.mapView.style.localizesLabels = _usingLocaleBasedCountryLabels;
}
- (void)styleRouteLine
@@ -1436,39 +1356,6 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
[self.mapView.style addLayer:fillStyleLayer];
}
-- (void)styleLabelLanguageForLayersNamed:(NSArray<NSString *> *)layers
-{
- _usingLocaleBasedCountryLabels = !_usingLocaleBasedCountryLabels;
- NSString *bestLanguageForUser = [NSString stringWithFormat:@"{name_%@}", [self bestLanguageForUser]];
- NSString *language = _usingLocaleBasedCountryLabels ? bestLanguageForUser : @"{name}";
-
- for (NSString *layerName in layers) {
- MGLSymbolStyleLayer *layer = (MGLSymbolStyleLayer *)[self.mapView.style layerWithIdentifier:layerName];
-
- if ([layer isKindOfClass:[MGLSymbolStyleLayer class]]) {
- if ([layer.text isKindOfClass:[MGLConstantStyleValue class]]) {
- MGLConstantStyleValue *label = (MGLConstantStyleValue<NSString *> *)layer.text;
- if ([label.rawValue hasPrefix:@"{name"]) {
- layer.text = [MGLStyleValue valueWithRawValue:language];
- }
- }
- else if ([layer.text isKindOfClass:[MGLCameraStyleFunction class]]) {
- MGLCameraStyleFunction *function = (MGLCameraStyleFunction<NSString *> *)layer.text;
- NSMutableDictionary *stops = function.stops.mutableCopy;
- [stops enumerateKeysAndObjectsUsingBlock:^(NSNumber *zoomLevel, MGLConstantStyleValue<NSString *> *stop, BOOL *done) {
- if ([stop.rawValue hasPrefix:@"{name"]) {
- stops[zoomLevel] = [MGLStyleValue<NSString *> valueWithRawValue:language];
- }
- }];
- function.stops = stops;
- layer.text = function;
- }
- } else {
- NSLog(@"%@ is not a symbol style layer", layerName);
- }
- }
-}
-
- (NSString *)bestLanguageForUser
{
// https://www.mapbox.com/vector-tiles/mapbox-streets-v7/#overview
@@ -1686,7 +1573,7 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
[sender setAccessibilityValue:nextAccessibilityValue];
}
-#pragma mark - Map Delegate
+#pragma mark - MGLMapViewDelegate
- (MGLAnnotationView *)mapView:(MGLMapView *)mapView viewForAnnotation:(id<MGLAnnotation>)annotation
{
diff --git a/platform/ios/docs/doc-README.md b/platform/ios/docs/doc-README.md
index 6c2693cbbf..ebad32e04c 100644
--- a/platform/ios/docs/doc-README.md
+++ b/platform/ios/docs/doc-README.md
@@ -6,4 +6,4 @@ The Mapbox iOS SDK is an open-source framework for embedding interactive map vie
For setup information, check out the [Mapbox iOS SDK homepage](https://www.mapbox.com/ios-sdk/). For detailed usage instructions, read “[First steps with the Mapbox iOS SDK](https://www.mapbox.com/help/first-steps-ios-sdk/)” and consult the [online examples](https://www.mapbox.com/ios-sdk/examples/). A [full changelog](https://github.com/mapbox/mapbox-gl-native/blob/master/platform/ios/CHANGELOG.md) is also available.
-If you have any questions, please [contact our support team](https://www.mapbox.com/contact/). We welcome your [bug reports and feature requests](https://github.com/mapbox/mapbox-gl-native/issues/).
+If you have any questions, please see [our help page](https://www.mapbox.com/help/). We welcome your [bug reports, feature requests, and contributions](https://github.com/mapbox/mapbox-gl-native/issues/).
diff --git a/platform/ios/docs/pod-README.md b/platform/ios/docs/pod-README.md
index 0a7edc5a41..2e5a78841c 100644
--- a/platform/ios/docs/pod-README.md
+++ b/platform/ios/docs/pod-README.md
@@ -96,4 +96,4 @@ class ViewController: UIViewController {
Full API documentation is included in this package, within the `documentation` folder. For more details, read “[First steps with the Mapbox iOS SDK](https://www.mapbox.com/help/first-steps-ios-sdk/)” and consult the [online examples](https://www.mapbox.com/ios-sdk/examples/).
-If you have any questions, please [contact our support team](https://www.mapbox.com/contact/). We welcome your [bug reports and feature requests](https://github.com/mapbox/mapbox-gl-native/issues/).
+If you have any questions, please see [our help page](https://www.mapbox.com/help/). We welcome your [bug reports, feature requests, and contributions](https://github.com/mapbox/mapbox-gl-native/issues/).
diff --git a/platform/ios/framework/Settings.bundle/hu.lproj/Root.strings b/platform/ios/framework/Settings.bundle/hu.lproj/Root.strings
new file mode 100644
index 0000000000..3d761f2b97
--- /dev/null
+++ b/platform/ios/framework/Settings.bundle/hu.lproj/Root.strings
@@ -0,0 +1,3 @@
+"TELEMETRY_GROUP_TITLE" = "Adatvédelmi beállítások";
+"TELEMETRY_SWITCH_TITLE" = "Mapbox Telemetria";
+"TELEMETRY_GROUP_FOOTER" = "Ez a beállítás megengedi az alkalmazásnak, hogy névtelen helyzeti és használati adatokat osszon meg a Mapbox-szal.";
diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj
index f83aa50509..76b35be2de 100644
--- a/platform/ios/ios.xcodeproj/project.pbxproj
+++ b/platform/ios/ios.xcodeproj/project.pbxproj
@@ -7,11 +7,6 @@
objects = {
/* Begin PBXBuildFile section */
- 071BBAFF1EE7613E001FB02A /* MGLImageSource.mm in Sources */ = {isa = PBXBuildFile; fileRef = 071BBAFD1EE75CD4001FB02A /* MGLImageSource.mm */; };
- 071BBB001EE7613F001FB02A /* MGLImageSource.mm in Sources */ = {isa = PBXBuildFile; fileRef = 071BBAFD1EE75CD4001FB02A /* MGLImageSource.mm */; };
- 071BBB031EE76146001FB02A /* MGLImageSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 071BBAFC1EE75CD4001FB02A /* MGLImageSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 071BBB041EE76147001FB02A /* MGLImageSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 071BBAFC1EE75CD4001FB02A /* MGLImageSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 071BBB071EE77631001FB02A /* MGLImageSourceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 071BBB051EE7761A001FB02A /* MGLImageSourceTests.m */; };
1753ED421E53CE6F00A9FD90 /* MGLConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = 1753ED411E53CE6F00A9FD90 /* MGLConversion.h */; };
1753ED431E53CE6F00A9FD90 /* MGLConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = 1753ED411E53CE6F00A9FD90 /* MGLConversion.h */; };
1F06668A1EC64F8E001C16D7 /* MGLLight.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F0666881EC64F8E001C16D7 /* MGLLight.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -22,6 +17,10 @@
1F7454971ECD450D00021D39 /* MGLLight_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F7454941ECD450D00021D39 /* MGLLight_Private.h */; };
1F7454A91ED08AB400021D39 /* MGLLightTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F7454A61ED08AB400021D39 /* MGLLightTest.mm */; };
1F95931D1E6DE2E900D5B294 /* MGLNSDateAdditionsTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F95931C1E6DE2E900D5B294 /* MGLNSDateAdditionsTests.mm */; };
+ 1FB7DAAF1F2A4DBD00410606 /* MGLVectorSource+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FDD9D6D1F26936400252B09 /* MGLVectorSource+MGLAdditions.h */; };
+ 1FB7DAB01F2A4DC200410606 /* MGLVectorSource+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FDD9D6D1F26936400252B09 /* MGLVectorSource+MGLAdditions.h */; };
+ 1FB7DAB11F2A4DC800410606 /* MGLVectorSource+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FDD9D6E1F26936400252B09 /* MGLVectorSource+MGLAdditions.m */; };
+ 1FB7DAB21F2A4DC900410606 /* MGLVectorSource+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FDD9D6E1F26936400252B09 /* MGLVectorSource+MGLAdditions.m */; };
30E578171DAA85520050F07E /* UIImage+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 30E578111DAA7D690050F07E /* UIImage+MGLAdditions.h */; };
30E578181DAA85520050F07E /* UIImage+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 30E578111DAA7D690050F07E /* UIImage+MGLAdditions.h */; };
30E578191DAA855E0050F07E /* UIImage+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 30E578121DAA7D690050F07E /* UIImage+MGLAdditions.mm */; };
@@ -192,8 +191,6 @@
40F887711D7A1E59008ECB67 /* MGLShapeSource_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 40F8876F1D7A1DB8008ECB67 /* MGLShapeSource_Private.h */; };
40FDA76B1CCAAA6800442548 /* MBXAnnotationView.m in Sources */ = {isa = PBXBuildFile; fileRef = 40FDA76A1CCAAA6800442548 /* MBXAnnotationView.m */; };
5549A0381EF1D86B00073113 /* libmbgl-core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5549A0371EF1D86B00073113 /* libmbgl-core.a */; };
- 5549A0391EF2877100073113 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 554180411D2E97DE00012372 /* OpenGLES.framework */; };
- 5549A03A1EF2877500073113 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 554180411D2E97DE00012372 /* OpenGLES.framework */; };
556660CA1E1BF3A900E2C41B /* MGLFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = 556660C91E1BF3A900E2C41B /* MGLFoundation.h */; settings = {ATTRIBUTES = (Public, ); }; };
556660D81E1D085500E2C41B /* MGLVersionNumber.m in Sources */ = {isa = PBXBuildFile; fileRef = 556660D71E1D085500E2C41B /* MGLVersionNumber.m */; };
556660DB1E1D8E8D00E2C41B /* MGLFoundation.h in Headers */ = {isa = PBXBuildFile; fileRef = 556660C91E1BF3A900E2C41B /* MGLFoundation.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -213,7 +210,6 @@
7E016D861D9E890300A29A21 /* MGLPolygon+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E016D831D9E890300A29A21 /* MGLPolygon+MGLAdditions.m */; };
7E016D871D9E890300A29A21 /* MGLPolygon+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E016D831D9E890300A29A21 /* MGLPolygon+MGLAdditions.m */; };
920A3E5D1E6F995200C16EFC /* MGLSourceQueryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 920A3E5C1E6F995200C16EFC /* MGLSourceQueryTests.m */; };
- 92F2C3ED1F0E3C3A00268EC0 /* MGLRendererFrontend.h in Headers */ = {isa = PBXBuildFile; fileRef = 92F2C3EC1F0E3C3A00268EC0 /* MGLRendererFrontend.h */; };
960D0C361ECF5AAF008E151F /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 960D0C351ECF5AAF008E151F /* Images.xcassets */; };
960D0C371ECF5AAF008E151F /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 960D0C351ECF5AAF008E151F /* Images.xcassets */; };
9620BB381E69FE1700705A1D /* MGLSDKUpdateChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = 9620BB361E69FE1700705A1D /* MGLSDKUpdateChecker.h */; };
@@ -237,7 +233,6 @@
DA1DC9971CB6E046006E619F /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DA1DC9961CB6E046006E619F /* main.m */; };
DA1DC9991CB6E054006E619F /* MBXAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DA1DC9981CB6E054006E619F /* MBXAppDelegate.m */; };
DA1DC99B1CB6E064006E619F /* MBXViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DA1DC99A1CB6E064006E619F /* MBXViewController.m */; };
- DA1DC99D1CB6E076006E619F /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA1DC99C1CB6E076006E619F /* Default-568h@2x.png */; };
DA1DC99F1CB6E088006E619F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DA1DC99E1CB6E088006E619F /* Assets.xcassets */; };
DA1F8F3D1EBD287B00367E42 /* MGLDocumentationGuideTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA1F8F3C1EBD287B00367E42 /* MGLDocumentationGuideTests.swift */; };
DA2207BF1DC0805F0002F84D /* MGLStyleValueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2207BE1DC0805F0002F84D /* MGLStyleValueTests.swift */; };
@@ -549,15 +544,14 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
- 071BBAFC1EE75CD4001FB02A /* MGLImageSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLImageSource.h; sourceTree = "<group>"; };
- 071BBAFD1EE75CD4001FB02A /* MGLImageSource.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLImageSource.mm; sourceTree = "<group>"; };
- 071BBB051EE7761A001FB02A /* MGLImageSourceTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MGLImageSourceTests.m; path = ../../darwin/test/MGLImageSourceTests.m; sourceTree = "<group>"; };
1753ED411E53CE6F00A9FD90 /* MGLConversion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLConversion.h; sourceTree = "<group>"; };
1F0666881EC64F8E001C16D7 /* MGLLight.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLLight.h; sourceTree = "<group>"; };
1F0666891EC64F8E001C16D7 /* MGLLight.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLLight.mm; sourceTree = "<group>"; };
1F7454941ECD450D00021D39 /* MGLLight_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLLight_Private.h; sourceTree = "<group>"; };
1F7454A61ED08AB400021D39 /* MGLLightTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLLightTest.mm; path = ../../darwin/test/MGLLightTest.mm; sourceTree = "<group>"; };
1F95931C1E6DE2E900D5B294 /* MGLNSDateAdditionsTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLNSDateAdditionsTests.mm; path = ../../darwin/test/MGLNSDateAdditionsTests.mm; sourceTree = "<group>"; };
+ 1FDD9D6D1F26936400252B09 /* MGLVectorSource+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MGLVectorSource+MGLAdditions.h"; sourceTree = "<group>"; };
+ 1FDD9D6E1F26936400252B09 /* MGLVectorSource+MGLAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MGLVectorSource+MGLAdditions.m"; sourceTree = "<group>"; };
20DABE861DF78148007AC5FF /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Foundation.strings"; sourceTree = "<group>"; };
20DABE881DF78148007AC5FF /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = "<group>"; };
20DABE8A1DF78149007AC5FF /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Root.strings"; sourceTree = "<group>"; };
@@ -684,7 +678,6 @@
7E016D821D9E890300A29A21 /* MGLPolygon+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MGLPolygon+MGLAdditions.h"; sourceTree = "<group>"; };
7E016D831D9E890300A29A21 /* MGLPolygon+MGLAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MGLPolygon+MGLAdditions.m"; sourceTree = "<group>"; };
920A3E5C1E6F995200C16EFC /* MGLSourceQueryTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MGLSourceQueryTests.m; path = ../../darwin/test/MGLSourceQueryTests.m; sourceTree = "<group>"; };
- 92F2C3EC1F0E3C3A00268EC0 /* MGLRendererFrontend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLRendererFrontend.h; sourceTree = "<group>"; };
960D0C351ECF5AAF008E151F /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
9620BB361E69FE1700705A1D /* MGLSDKUpdateChecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLSDKUpdateChecker.h; sourceTree = "<group>"; };
9620BB371E69FE1700705A1D /* MGLSDKUpdateChecker.mm */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; path = MGLSDKUpdateChecker.mm; sourceTree = "<group>"; };
@@ -724,7 +717,6 @@
DA1DC9961CB6E046006E619F /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
DA1DC9981CB6E054006E619F /* MBXAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBXAppDelegate.m; sourceTree = "<group>"; };
DA1DC99A1CB6E064006E619F /* MBXViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBXViewController.m; sourceTree = "<group>"; };
- DA1DC99C1CB6E076006E619F /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = "<group>"; };
DA1DC99E1CB6E088006E619F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
DA1F8F3C1EBD287B00367E42 /* MGLDocumentationGuideTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MGLDocumentationGuideTests.swift; path = ../../darwin/test/MGLDocumentationGuideTests.swift; sourceTree = "<group>"; };
DA2207BE1DC0805F0002F84D /* MGLStyleValueTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MGLStyleValueTests.swift; path = ../../darwin/test/MGLStyleValueTests.swift; sourceTree = "<group>"; };
@@ -915,6 +907,7 @@
DABCABBF1CB80717000A7C39 /* locations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = locations.cpp; sourceTree = "<group>"; };
DABCABC01CB80717000A7C39 /* locations.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = locations.hpp; sourceTree = "<group>"; };
DAC49C621CD07D74009E1AA3 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
+ DACCD9C81F1F473700BB09A1 /* hu */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/Root.strings; sourceTree = "<group>"; };
DAD165691CF41981001FF4B9 /* MGLFeature.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLFeature.h; sourceTree = "<group>"; };
DAD1656A1CF41981001FF4B9 /* MGLFeature_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLFeature_Private.h; sourceTree = "<group>"; };
DAD1656B1CF41981001FF4B9 /* MGLFeature.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLFeature.mm; sourceTree = "<group>"; };
@@ -952,7 +945,6 @@
buildActionMask = 2147483647;
files = (
DA8847D91CBAF91600AB86E3 /* Mapbox.framework in Frameworks */,
- 5549A0391EF2877100073113 /* OpenGLES.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -987,7 +979,6 @@
buildActionMask = 2147483647;
files = (
DAA4E4081CBB6C9500178DFB /* Mapbox.framework in Frameworks */,
- 5549A03A1EF2877500073113 /* OpenGLES.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -997,8 +988,6 @@
35136D491D4277EA00C20EFD /* Sources */ = {
isa = PBXGroup;
children = (
- 071BBAFC1EE75CD4001FB02A /* MGLImageSource.h */,
- 071BBAFD1EE75CD4001FB02A /* MGLImageSource.mm */,
3566C76A1D4A8DFA008152BC /* MGLRasterSource.h */,
DAF0D80F1DFE0EA000B28378 /* MGLRasterSource_Private.h */,
3566C76B1D4A8DFA008152BC /* MGLRasterSource.mm */,
@@ -1156,7 +1145,6 @@
40CFA64E1D78754A008103BD /* Sources */ = {
isa = PBXGroup;
children = (
- 071BBB051EE7761A001FB02A /* MGLImageSourceTests.m */,
40CFA6501D787579008103BD /* MGLShapeSourceTests.mm */,
920A3E5C1E6F995200C16EFC /* MGLSourceQueryTests.m */,
4085AF081D933DEA00F11B22 /* MGLTileSetTests.mm */,
@@ -1164,6 +1152,20 @@
name = Sources;
sourceTree = "<group>";
};
+ 9604FC341F313A5E003EEA02 /* Fixtures */ = {
+ isa = PBXGroup;
+ children = (
+ 353BAEF51D646370009A8DA9 /* amsterdam.geojson */,
+ DA1DC96C1CB6C6CE006E619F /* points.geojson */,
+ DA1DC96D1CB6C6CE006E619F /* polyline.geojson */,
+ DA1DC96F1CB6C6CE006E619F /* threestates.geojson */,
+ DD4823721D94AE6C00EB71B7 /* fill_filter_style.json */,
+ DD4823731D94AE6C00EB71B7 /* line_filter_style.json */,
+ DD4823741D94AE6C00EB71B7 /* numeric_filter_style.json */,
+ );
+ name = Fixtures;
+ sourceTree = "<group>";
+ };
DA1DC9411CB6C1C2006E619F = {
isa = PBXGroup;
children = (
@@ -1212,16 +1214,9 @@
DA821D051CCC6D59007508D4 /* Main.storyboard */,
DA821D041CCC6D59007508D4 /* LaunchScreen.storyboard */,
DA1DC99E1CB6E088006E619F /* Assets.xcassets */,
- DA1DC96C1CB6C6CE006E619F /* points.geojson */,
- DA1DC96D1CB6C6CE006E619F /* polyline.geojson */,
- DA1DC96F1CB6C6CE006E619F /* threestates.geojson */,
- 353BAEF51D646370009A8DA9 /* amsterdam.geojson */,
- DD4823721D94AE6C00EB71B7 /* fill_filter_style.json */,
- DD4823731D94AE6C00EB71B7 /* line_filter_style.json */,
- DD4823741D94AE6C00EB71B7 /* numeric_filter_style.json */,
DA1DC95E1CB6C1C2006E619F /* Info.plist */,
- DA1DC99C1CB6E076006E619F /* Default-568h@2x.png */,
96E027251E57C76E004B8E66 /* Localizable.strings */,
+ 9604FC341F313A5E003EEA02 /* Fixtures */,
DA1DC94D1CB6C1C2006E619F /* Supporting Files */,
);
name = "Demo App";
@@ -1337,7 +1332,6 @@
DA8848031CBAFA6200AB86E3 /* MGLMapCamera.mm */,
DD0902A41DB18F1B00C5BDCE /* MGLNetworkConfiguration.h */,
DD0902A21DB18DE700C5BDCE /* MGLNetworkConfiguration.m */,
- 92F2C3EC1F0E3C3A00268EC0 /* MGLRendererFrontend.h */,
DA8847EC1CBAFA5100AB86E3 /* MGLStyle.h */,
35E0CFE51D3E501500188327 /* MGLStyle_Private.h */,
DA88480F1CBAFA6200AB86E3 /* MGLStyle.mm */,
@@ -1554,6 +1548,8 @@
DAD165831CF4CFED001FF4B9 /* Categories */ = {
isa = PBXGroup;
children = (
+ 1FDD9D6D1F26936400252B09 /* MGLVectorSource+MGLAdditions.h */,
+ 1FDD9D6E1F26936400252B09 /* MGLVectorSource+MGLAdditions.m */,
7E016D821D9E890300A29A21 /* MGLPolygon+MGLAdditions.h */,
7E016D831D9E890300A29A21 /* MGLPolygon+MGLAdditions.m */,
7E016D7C1D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.h */,
@@ -1659,6 +1655,7 @@
350098DC1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.h in Headers */,
DA8848231CBAFA6200AB86E3 /* MGLOfflineStorage_Private.h in Headers */,
404326891D5B9B27007111BD /* MGLAnnotationContainerView_Private.h in Headers */,
+ 1FB7DAAF1F2A4DBD00410606 /* MGLVectorSource+MGLAdditions.h in Headers */,
DA88483B1CBAFB8500AB86E3 /* MGLCalloutView.h in Headers */,
35E0CFE61D3E501500188327 /* MGLStyle_Private.h in Headers */,
3510FFF01D6D9D8C00F413B2 /* NSExpression+MGLAdditions.h in Headers */,
@@ -1692,9 +1689,7 @@
35D3A1E61E9BE7EB002B38EE /* MGLScaleBar.h in Headers */,
DA8848311CBAFA6200AB86E3 /* NSString+MGLAdditions.h in Headers */,
353933F81D3FB79F003F57D7 /* MGLLineStyleLayer.h in Headers */,
- 92F2C3ED1F0E3C3A00268EC0 /* MGLRendererFrontend.h in Headers */,
DAAF722D1DA903C700312FA4 /* MGLStyleValue_Private.h in Headers */,
- 071BBB031EE76146001FB02A /* MGLImageSource.h in Headers */,
DA8847F41CBAFA5100AB86E3 /* MGLOfflinePack.h in Headers */,
DA88482E1CBAFA6200AB86E3 /* NSException+MGLAdditions.h in Headers */,
DA8848551CBAFB9800AB86E3 /* MGLLocationManager.h in Headers */,
@@ -1778,7 +1773,6 @@
3566C7671D4A77BA008152BC /* MGLShapeSource.h in Headers */,
DA35A29F1CC9E94C00E826B2 /* MGLCoordinateFormatter.h in Headers */,
404C26E31D89B877000AA13D /* MGLTileSource.h in Headers */,
- 071BBB041EE76147001FB02A /* MGLImageSource.h in Headers */,
DABFB8611CBE99E500D62B32 /* MGLMultiPoint.h in Headers */,
3510FFF11D6D9D8C00F413B2 /* NSExpression+MGLAdditions.h in Headers */,
35D3A1E71E9BE7EC002B38EE /* MGLScaleBar.h in Headers */,
@@ -1793,7 +1787,6 @@
DABFB8621CBE99E500D62B32 /* MGLOfflinePack.h in Headers */,
DAD1656D1CF41981001FF4B9 /* MGLFeature.h in Headers */,
DA17BE311CC4BDAA00402C41 /* MGLMapView_Private.h in Headers */,
- 92F2C3EE1F0E3DC600268EC0 /* MGLRendererFrontend.h in Headers */,
DABFB86C1CBE99E500D62B32 /* MGLTypes.h in Headers */,
DABFB8691CBE99E500D62B32 /* MGLShape.h in Headers */,
9620BB391E69FE1700705A1D /* MGLSDKUpdateChecker.h in Headers */,
@@ -1840,6 +1833,7 @@
35136D4D1D4277FC00C20EFD /* MGLSource.h in Headers */,
DA35A2BC1CCA9A6900E826B2 /* MGLClockDirectionFormatter.h in Headers */,
35D13AC41D3D19DD00AFB4E0 /* MGLFillStyleLayer.h in Headers */,
+ 1FB7DAB01F2A4DC200410606 /* MGLVectorSource+MGLAdditions.h in Headers */,
DABFB86E1CBE9A0F00D62B32 /* MGLCalloutView.h in Headers */,
1F7454971ECD450D00021D39 /* MGLLight_Private.h in Headers */,
DABFB8601CBE99E500D62B32 /* MGLMapCamera.h in Headers */,
@@ -1990,6 +1984,7 @@
TargetAttributes = {
DA1DC9491CB6C1C2006E619F = {
CreatedOnToolsVersion = 7.3;
+ DevelopmentTeam = GJZR2MEM28;
LastSwiftMigration = 0820;
};
DA25D5B81CCD9EDE00607828 = {
@@ -2066,7 +2061,6 @@
353BAEF61D646370009A8DA9 /* amsterdam.geojson in Resources */,
DA1DC9711CB6C6CE006E619F /* polyline.geojson in Resources */,
DD4823761D94AE6C00EB71B7 /* line_filter_style.json in Resources */,
- DA1DC99D1CB6E076006E619F /* Default-568h@2x.png in Resources */,
DA821D071CCC6D59007508D4 /* Main.storyboard in Resources */,
DA1DC9731CB6C6CE006E619F /* threestates.geojson in Resources */,
DA821D061CCC6D59007508D4 /* LaunchScreen.storyboard in Resources */,
@@ -2175,7 +2169,6 @@
35D9DDE21DA25EEC00DAAD69 /* MGLCodingTests.m in Sources */,
DA1F8F3D1EBD287B00367E42 /* MGLDocumentationGuideTests.swift in Sources */,
3598544D1E1D38AA00B29F84 /* MGLDistanceFormatterTests.m in Sources */,
- 071BBB071EE77631001FB02A /* MGLImageSourceTests.m in Sources */,
DA2DBBCE1D51E80400D38FF9 /* MGLStyleLayerTests.m in Sources */,
DA35A2C61CCA9F8300E826B2 /* MGLCompassDirectionFormatterTests.m in Sources */,
DAE7DEC21E245455007505A6 /* MGLNSStringAdditionsTests.m in Sources */,
@@ -2218,6 +2211,7 @@
9620BB3A1E69FE1700705A1D /* MGLSDKUpdateChecker.mm in Sources */,
354B83981D2E873E005D9406 /* MGLUserLocationAnnotationView.m in Sources */,
DA88485D1CBAFB9800AB86E3 /* MGLFaux3DUserLocationAnnotationView.m in Sources */,
+ 1FB7DAB11F2A4DC800410606 /* MGLVectorSource+MGLAdditions.m in Sources */,
DAD165701CF41981001FF4B9 /* MGLFeature.mm in Sources */,
30E578191DAA855E0050F07E /* UIImage+MGLAdditions.mm in Sources */,
40EDA1C11CFE0E0500D9EA68 /* MGLAnnotationContainerView.m in Sources */,
@@ -2252,7 +2246,6 @@
DD0902A91DB1929D00C5BDCE /* MGLNetworkConfiguration.m in Sources */,
35D13AB91D3D15E300AFB4E0 /* MGLStyleLayer.mm in Sources */,
DA35A2CB1CCAAAD200E826B2 /* NSValue+MGLAdditions.m in Sources */,
- 071BBB001EE7613F001FB02A /* MGLImageSource.mm in Sources */,
DA8848321CBAFA6200AB86E3 /* NSString+MGLAdditions.m in Sources */,
408AA8581DAEDA1E00022900 /* NSDictionary+MGLAdditions.mm in Sources */,
DA35A2A11CC9E95F00E826B2 /* MGLCoordinateFormatter.m in Sources */,
@@ -2301,6 +2294,7 @@
9620BB3B1E69FE1700705A1D /* MGLSDKUpdateChecker.mm in Sources */,
DAA4E4221CBB730400178DFB /* MGLPointAnnotation.mm in Sources */,
DAED38661D62D0FC00D7640F /* NSURL+MGLAdditions.m in Sources */,
+ 1FB7DAB21F2A4DC900410606 /* MGLVectorSource+MGLAdditions.m in Sources */,
DAD165711CF41981001FF4B9 /* MGLFeature.mm in Sources */,
30E5781A1DAA855E0050F07E /* UIImage+MGLAdditions.mm in Sources */,
40EDA1C21CFE0E0500D9EA68 /* MGLAnnotationContainerView.m in Sources */,
@@ -2334,7 +2328,6 @@
DD0902AA1DB1929D00C5BDCE /* MGLNetworkConfiguration.m in Sources */,
DA35A2B41CCA141D00E826B2 /* MGLCompassDirectionFormatter.m in Sources */,
35D13ABA1D3D15E300AFB4E0 /* MGLStyleLayer.mm in Sources */,
- 071BBAFF1EE7613E001FB02A /* MGLImageSource.mm in Sources */,
DA35A2CC1CCAAAD200E826B2 /* NSValue+MGLAdditions.m in Sources */,
408AA8591DAEDA1E00022900 /* NSDictionary+MGLAdditions.mm in Sources */,
DAA4E4281CBB730400178DFB /* MGLTypes.m in Sources */,
@@ -2464,6 +2457,7 @@
DA618B1E1E688A3700CB7F44 /* ca */,
DA618B2C1E68933600CB7F44 /* fi */,
DAE8CCAE1E6E8C76009B5CB0 /* nl */,
+ DACCD9C81F1F473700BB09A1 /* hu */,
);
name = Root.strings;
sourceTree = "<group>";
@@ -2657,7 +2651,6 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = "$(SRCROOT)/app/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
@@ -2671,7 +2664,6 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = "$(SRCROOT)/app/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
diff --git a/platform/ios/resources/fr.lproj/Localizable.strings b/platform/ios/resources/fr.lproj/Localizable.strings
index 075042c695..7fc85568c7 100644
--- a/platform/ios/resources/fr.lproj/Localizable.strings
+++ b/platform/ios/resources/fr.lproj/Localizable.strings
@@ -10,6 +10,9 @@
/* No comment provided by engineer. */
"CANCEL" = "Annuler";
+/* Accessibility hint for closing the selected annotation’s callout view and returning to the map */
+"CLOSE_CALLOUT_A11Y_HINT" = "Retour à la carte";
+
/* Accessibility hint */
"COMPASS_A11Y_HINT" = "Tourne la carte vers le nord";
@@ -31,6 +34,12 @@
/* Accessibility label */
"INFO_A11Y_LABEL" = "À propos de cette carte";
+/* User-friendly error description */
+"LOAD_MAP_FAILED_DESC" = "La carte n’a pas pu être chargée car une erreur inconnue est survenue.";
+
+/* User-friendly error description */
+"LOAD_STYLE_FAILED_DESC" = "La carte n’a pas pu être chargée car le style ne peut pas être chargé.";
+
/* Accessibility label */
"LOGO_A11Y_LABEL" = "Mapbox";
@@ -40,9 +49,18 @@
/* Map accessibility value */
"MAP_A11Y_VALUE" = "Zoom %1$dx\n%2$ld annotation(s) visible(s)";
+/* User-friendly error description */
+"PARSE_STYLE_FAILED_DESC" = "La carte n’a pas pu être chargée car le style est corrompu.";
+
/* Action sheet title */
"SDK_NAME" = "Mapbox iOS SDK";
+/* Developer-only SDK update notification; {latest version, in format x.x.x} */
+"SDK_UPDATE_AVAILABLE" = "La version %@ du SDK Mapbox pour iOS est maintenant disponible :";
+
+/* User-friendly error description */
+"STYLE_NOT_FOUND_DESC" = "La carte n’a pas pu être chargée car le style n’a pas été trouvé ou est incompatible.";
+
/* Telemetry prompt message */
"TELEMETRY_DISABLED_MSG" = "Vous pouvez contribuer à OpenStreetMap et Mapbox en partageant des données d’utilisation anonymes.";
diff --git a/platform/ios/scripts/package.sh b/platform/ios/scripts/package.sh
index e4403c4652..a5e2f87e20 100755
--- a/platform/ios/scripts/package.sh
+++ b/platform/ios/scripts/package.sh
@@ -21,33 +21,17 @@ elif [[ ${FORMAT} == "dynamic" ]]; then
BUILD_STATIC=false
fi
-SELF_CONTAINED=${SELF_CONTAINED:-}
-STATIC_BUNDLE_DIR=
-if [[ ${SELF_CONTAINED} ]]; then
- STATIC_BUNDLE_DIR="${OUTPUT}/static/${NAME}.framework"
-else
- STATIC_BUNDLE_DIR="${OUTPUT}/static"
-fi
-
-STATIC_SETTINGS_DIR=
-if [[ ${SELF_CONTAINED} ]]; then
- STATIC_SETTINGS_DIR="${OUTPUT}/static/${NAME}.framework"
-else
- STATIC_SETTINGS_DIR="${OUTPUT}"
-fi
-
SDK=iphonesimulator
if [[ ${BUILD_FOR_DEVICE} == true ]]; then
SDK=iphoneos
fi
IOS_SDK_VERSION=`xcrun --sdk ${SDK} --show-sdk-version`
-echo "Configuring ${FORMAT:-dynamic and static} ${BUILDTYPE} framework for ${SDK}; symbols: ${SYMBOLS}; self-contained static framework: ${SELF_CONTAINED:-NO}"
-
function step { >&2 echo -e "\033[1m\033[36m* $@\033[0m"; }
function finish { >&2 echo -en "\033[0m"; }
trap finish EXIT
+step "Configuring ${FORMAT:-dynamic and static} ${BUILDTYPE} framework for ${SDK}; symbols: ${SYMBOLS}"
rm -rf ${OUTPUT}
if [[ ${BUILD_STATIC} == true ]]; then
@@ -69,7 +53,7 @@ PROJ_VERSION=$(git rev-list --count HEAD)
SEM_VERSION=$( git describe --tags --match=ios-v*.*.* --abbrev=0 | sed 's/^ios-v//' )
SHORT_VERSION=${SEM_VERSION%-*}
-step "Building targets (build ${PROJ_VERSION}, version ${SEM_VERSION})…"
+step "Building targets (build ${PROJ_VERSION}, version ${SEM_VERSION})"
SCHEME='dynamic'
if [[ ${BUILD_DYNAMIC} == true && ${BUILD_STATIC} == true ]]; then
@@ -78,6 +62,7 @@ elif [[ ${BUILD_STATIC} == true ]]; then
SCHEME='static'
fi
+step "Building for iOS Simulator using scheme ${SCHEME}"
xcodebuild \
CURRENT_PROJECT_VERSION=${PROJ_VERSION} \
CURRENT_SHORT_VERSION=${SHORT_VERSION} \
@@ -92,6 +77,7 @@ xcodebuild \
-jobs ${JOBS} | xcpretty
if [[ ${BUILD_FOR_DEVICE} == true ]]; then
+ step "Building for iOS devices using scheme ${SCHEME}"
xcodebuild \
CURRENT_PROJECT_VERSION=${PROJ_VERSION} \
CURRENT_SHORT_VERSION=${SHORT_VERSION} \
@@ -119,7 +105,7 @@ if [[ ${BUILD_FOR_DEVICE} == true ]]; then
${LIBS[@]/#/${PRODUCTS}/${BUILDTYPE}-iphonesimulator/lib} \
`cmake -LA -N ${DERIVED_DATA} | grep MASON_PACKAGE_icu_LIBRARIES | cut -d= -f2`
- cp -rv ${PRODUCTS}/${BUILDTYPE}-iphoneos/${NAME}.bundle ${STATIC_BUNDLE_DIR}
+ cp -rv ${PRODUCTS}/${BUILDTYPE}-iphoneos/${NAME}.bundle ${OUTPUT}/static
fi
if [[ ${BUILD_DYNAMIC} == true ]]; then
@@ -149,7 +135,7 @@ if [[ ${BUILD_FOR_DEVICE} == true ]]; then
-create -output ${OUTPUT}/dynamic/${NAME}.framework/${NAME} | echo
fi
- cp -rv ${PRODUCTS}/${BUILDTYPE}-iphoneos/Settings.bundle ${STATIC_SETTINGS_DIR}
+ cp -rv ${PRODUCTS}/${BUILDTYPE}-iphoneos/Settings.bundle ${OUTPUT}
else
if [[ ${BUILD_STATIC} == true ]]; then
step "Assembling static library for iOS Simulator…"
@@ -159,7 +145,7 @@ else
${LIBS[@]/#/${PRODUCTS}/${BUILDTYPE}-iphonesimulator/lib} \
`cmake -LA -N ${DERIVED_DATA} | grep MASON_PACKAGE_icu_LIBRARIES | cut -d= -f2`
- cp -rv ${PRODUCTS}/${BUILDTYPE}-iphonesimulator/${NAME}.bundle ${STATIC_BUNDLE_DIR}
+ cp -rv ${PRODUCTS}/${BUILDTYPE}-iphonesimulator/${NAME}.bundle ${OUTPUT}/static
fi
if [[ ${BUILD_DYNAMIC} == true ]]; then
@@ -174,7 +160,7 @@ else
fi
fi
- cp -rv ${PRODUCTS}/${BUILDTYPE}-iphonesimulator/Settings.bundle ${STATIC_SETTINGS_DIR}
+ cp -rv ${PRODUCTS}/${BUILDTYPE}-iphonesimulator/Settings.bundle ${OUTPUT}
fi
if [[ ${SYMBOLS} = NO ]]; then
@@ -244,13 +230,17 @@ if [[ ${BUILD_STATIC} == true ]]; then
fi
step "Copying library resources…"
-cp -pv LICENSE.md ${STATIC_SETTINGS_DIR}
+cp -pv LICENSE.md ${OUTPUT}
if [[ ${BUILD_STATIC} == true ]]; then
- cp -pv "${STATIC_BUNDLE_DIR}/${NAME}.bundle/Info.plist" "${OUTPUT}/static/${NAME}.framework/Info.plist"
+ cp -pv "${OUTPUT}/static/${NAME}.bundle/Info.plist" "${OUTPUT}/static/${NAME}.framework/Info.plist"
plutil -replace CFBundlePackageType -string FMWK "${OUTPUT}/static/${NAME}.framework/Info.plist"
mkdir "${OUTPUT}/static/${NAME}.framework/Modules"
cp -pv platform/ios/framework/modulemap "${OUTPUT}/static/${NAME}.framework/Modules/module.modulemap"
fi
+if [[ ${BUILD_DYNAMIC} == true && ${BUILD_FOR_DEVICE} == true ]]; then
+ step "Copying bitcode symbol maps…"
+ find "${PRODUCTS}/${BUILDTYPE}-iphoneos" -name '*.bcsymbolmap' -type f -exec cp -pv {} "${OUTPUT}/dynamic/" \;
+fi
sed -n -e '/^## /,$p' platform/ios/CHANGELOG.md > "${OUTPUT}/CHANGELOG.md"
rm -rf /tmp/mbgl
diff --git a/platform/ios/src/MGLFaux3DUserLocationAnnotationView.m b/platform/ios/src/MGLFaux3DUserLocationAnnotationView.m
index 6db9c0db10..5f67f24f4e 100644
--- a/platform/ios/src/MGLFaux3DUserLocationAnnotationView.m
+++ b/platform/ios/src/MGLFaux3DUserLocationAnnotationView.m
@@ -460,11 +460,8 @@ const CGFloat MGLUserLocationAnnotationArrowSize = MGLUserLocationAnnotationPuck
- (CGFloat)calculateAccuracyRingSize
{
- CGFloat latitudeRadians = MGLRadiansFromDegrees(self.userLocation.coordinate.latitude);
- CGFloat metersPerPoint = [self.mapView metersPerPointAtLatitude:self.userLocation.coordinate.latitude];
- CGFloat pixelRadius = self.userLocation.location.horizontalAccuracy / cos(latitudeRadians) / metersPerPoint;
-
- return pixelRadius * 2.0;
+ // diameter in screen points
+ return self.userLocation.location.horizontalAccuracy / [self.mapView metersPerPointAtLatitude:self.userLocation.coordinate.latitude] * 2.0;
}
- (UIImage *)headingIndicatorTintedGradientImage
diff --git a/platform/ios/src/MGLMapView.h b/platform/ios/src/MGLMapView.h
index 64d2e53d21..023ed1b437 100644
--- a/platform/ios/src/MGLMapView.h
+++ b/platform/ios/src/MGLMapView.h
@@ -778,6 +778,23 @@ MGL_EXPORT IB_DESIGNABLE
- (void)setCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration animationTimingFunction:(nullable CAMediaTimingFunction *)function completionHandler:(nullable void (^)(void))completion;
/**
+ Moves the viewpoint to a different location with respect to the map with an
+ optional transition duration and timing function.
+
+ @param camera The new viewpoint.
+ @param duration The amount of time, measured in seconds, that the transition
+ animation should take. Specify `0` to jump to the new viewpoint
+ instantaneously.
+ @param function A timing function used for the animation. Set this parameter to
+ `nil` for a transition that matches most system animations. If the duration
+ is `0`, this parameter is ignored.
+ @param edgePadding The minimum padding (in screen points) that would be visible
+ around the returned camera object if it were set as the receiver’s camera.
+ @param completion The block to execute after the animation finishes.
+ */
+- (void)setCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration animationTimingFunction:(nullable CAMediaTimingFunction *)function edgePadding:(UIEdgeInsets)edgePadding completionHandler:(nullable void (^)(void))completion;
+
+/**
Moves the viewpoint to a different location using a transition animation that
evokes powered flight and a default duration based on the length of the flight
path.
@@ -987,16 +1004,6 @@ MGL_EXPORT IB_DESIGNABLE
@property (nonatomic, readonly, nullable) NS_ARRAY_OF(id <MGLAnnotation>) *annotations;
/**
- The complete list of annotations associated with the receiver that are
- currently visible.
-
- The objects in this array must adopt the `MGLAnnotation` protocol. If no
- annotations are associated with the map view or if no annotations associated
- with the map view are currently visible, the value of this property is `nil`.
- */
-@property (nonatomic, readonly, nullable) NS_ARRAY_OF(id <MGLAnnotation>) *visibleAnnotations;
-
-/**
Adds an annotation to the map view.
@note `MGLMultiPolyline`, `MGLMultiPolygon`, `MGLShapeCollection`, and
@@ -1091,6 +1098,16 @@ MGL_EXPORT IB_DESIGNABLE
- (nullable __kindof MGLAnnotationView *)dequeueReusableAnnotationViewWithIdentifier:(NSString *)identifier;
/**
+ The complete list of annotations associated with the receiver that are
+ currently visible.
+
+ The objects in this array must adopt the `MGLAnnotation` protocol. If no
+ annotations are associated with the map view or if no annotations associated
+ with the map view are currently visible, the value of this property is `nil`.
+ */
+@property (nonatomic, readonly, nullable) NS_ARRAY_OF(id <MGLAnnotation>) *visibleAnnotations;
+
+/**
Returns the list of annotations associated with the receiver that intersect with
the given rectangle.
@@ -1259,6 +1276,11 @@ MGL_EXPORT IB_DESIGNABLE
`-[MGLVectorSource featuresInSourceLayersWithIdentifiers:predicate:]` and
`-[MGLShapeSource featuresMatchingPredicate:]` methods on the relevant sources.
+ The returned features may also include features corresponding to annotations.
+ These features are not object-equal to the `MGLAnnotation` objects that were
+ originally added to the map. To query the map for annotations, use
+ `visibleAnnotations` or `-[MGLMapView visibleAnnotationsInRect:]`.
+
@note Layer identifiers are not guaranteed to exist across styles or different
versions of the same style. Applications that use this API must first set
the style URL to an explicitly versioned style using a convenience method
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm
index 9c3d1d415f..d9d03ea478 100644
--- a/platform/ios/src/MGLMapView.mm
+++ b/platform/ios/src/MGLMapView.mm
@@ -1116,8 +1116,10 @@ public:
- (void)updateTintColorForView:(UIView *)view
{
- // stop at recursing container & annotation views (#8522)
- if ([view isEqual:self.annotationContainerView]) return;
+ // Don't update:
+ // - annotation views
+ // - attribution button (handled automatically)
+ if ([view isEqual:self.annotationContainerView] || [view isEqual:self.attributionButton]) return;
if ([view respondsToSelector:@selector(setTintColor:)]) view.tintColor = self.tintColor;
@@ -1250,8 +1252,6 @@ public:
{
if ( ! self.isZoomEnabled) return;
- if (_mbglMap->getZoom() <= _mbglMap->getMinZoom() && pinch.scale < 1) return;
-
_mbglMap->cancelTransitions();
CGPoint centerPoint = [self anchorPointForGesture:pinch];
@@ -1267,17 +1267,17 @@ public:
}
else if (pinch.state == UIGestureRecognizerStateChanged)
{
+ // Zoom limiting happens at the core level.
CGFloat newScale = self.scale * pinch.scale;
- double zoom = log2(newScale);
- if (zoom < _mbglMap->getMinZoom()) return;
-
+ double newZoom = log2(newScale);
+
// Calculates the final camera zoom, has no effect within current map camera.
- MGLMapCamera *toCamera = [self cameraByZoomingToZoomLevel:zoom aroundAnchorPoint:centerPoint];
+ MGLMapCamera *toCamera = [self cameraByZoomingToZoomLevel:newZoom aroundAnchorPoint:centerPoint];
if (![self.delegate respondsToSelector:@selector(mapView:shouldChangeFromCamera:toCamera:)] ||
[self.delegate mapView:self shouldChangeFromCamera:oldCamera toCamera:toCamera])
{
- _mbglMap->setZoom(zoom, mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y });
+ _mbglMap->setZoom(newZoom, mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y });
// The gesture recognizer only reports the gesture’s current center
// point, so use the previous center point to anchor the transition.
// If the number of touches has changed, the remembered center point is
@@ -1625,9 +1625,9 @@ public:
{
CGFloat distance = [quickZoom locationInView:quickZoom.view].y - self.quickZoomStart;
- CGFloat newZoom = log2f(self.scale) + (distance / 75);
+ CGFloat newZoom = MAX(log2f(self.scale) + (distance / 75), _mbglMap->getMinZoom());
- if (newZoom < _mbglMap->getMinZoom()) return;
+ if (_mbglMap->getZoom() == newZoom) return;
CGPoint centerPoint = [self anchorPointForGesture:quickZoom];
@@ -1760,39 +1760,6 @@ public:
return [gesture locationInView:gesture.view];
}
-- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
-{
- if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]])
- {
- UIPanGestureRecognizer *panGesture = (UIPanGestureRecognizer *)gestureRecognizer;
-
- if (panGesture.minimumNumberOfTouches == 2)
- {
- CGPoint velocity = [panGesture velocityInView:panGesture.view];
- double gestureAngle = MGLDegreesFromRadians(atan(velocity.y / velocity.x));
- double horizontalToleranceDegrees = 20.0;
-
- // cancel if gesture angle is not 90º±20º (more or less vertical)
- if ( ! (fabs((fabs(gestureAngle) - 90.0)) < horizontalToleranceDegrees))
- {
- return NO;
- }
- }
- }
- else if (gestureRecognizer == _singleTapGestureRecognizer)
- {
- // Gesture will be recognized if it could deselect an annotation
- if(!self.selectedAnnotation)
- {
- id<MGLAnnotation>annotation = [self annotationForGestureRecognizer:(UITapGestureRecognizer*)gestureRecognizer persistingResults:NO];
- if(!annotation) {
- return NO;
- }
- }
- }
- return YES;
-}
-
- (void)handleCalloutAccessoryTapGesture:(UITapGestureRecognizer *)tap
{
if ([self.delegate respondsToSelector:@selector(mapView:annotation:calloutAccessoryControlTapped:)])
@@ -1836,12 +1803,60 @@ public:
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, calloutView);
}
+- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
+{
+ if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]])
+ {
+ UIPanGestureRecognizer *panGesture = (UIPanGestureRecognizer *)gestureRecognizer;
+
+ if (panGesture.minimumNumberOfTouches == 2)
+ {
+ CGPoint west = [panGesture locationOfTouch:0 inView:panGesture.view];
+ CGPoint east = [panGesture locationOfTouch:1 inView:panGesture.view];
+
+ if (west.x > east.x) {
+ CGPoint swap = west;
+ west = east;
+ east = swap;
+ }
+
+ CLLocationDegrees horizontalToleranceDegrees = 60.0;
+ if ([self angleBetweenPoints:west east:east] > horizontalToleranceDegrees) {
+ return NO;
+ }
+
+ }
+ }
+ else if (gestureRecognizer == _singleTapGestureRecognizer)
+ {
+ // Gesture will be recognized if it could deselect an annotation
+ if(!self.selectedAnnotation)
+ {
+ id<MGLAnnotation>annotation = [self annotationForGestureRecognizer:(UITapGestureRecognizer*)gestureRecognizer persistingResults:NO];
+ if(!annotation) {
+ return NO;
+ }
+ }
+ }
+ return YES;
+}
+
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
NSArray *validSimultaneousGestures = @[ self.pan, self.pinch, self.rotate ];
return ([validSimultaneousGestures containsObject:gestureRecognizer] && [validSimultaneousGestures containsObject:otherGestureRecognizer]);
}
+
+- (CLLocationDegrees)angleBetweenPoints:(CGPoint)west east:(CGPoint)east
+{
+ CGFloat slope = (west.y - east.y) / (west.x - east.x);
+
+ CGFloat angle = atan(fabs(slope));
+ CLLocationDegrees degrees = MGLDegreesFromRadians(angle);
+
+ return degrees;
+}
- (void)trackGestureEvent:(NSString *)gestureID forRecognizer:(UIGestureRecognizer *)recognizer
{
@@ -2743,6 +2758,10 @@ public:
- (void)setCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration animationTimingFunction:(nullable CAMediaTimingFunction *)function completionHandler:(nullable void (^)(void))completion
{
+ [self setCamera:camera withDuration:duration animationTimingFunction:function edgePadding:self.contentInset completionHandler:completion];
+}
+
+- (void)setCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration animationTimingFunction:(nullable CAMediaTimingFunction *)function edgePadding:(UIEdgeInsets)edgePadding completionHandler:(nullable void (^)(void))completion {
mbgl::AnimationOptions animationOptions;
if (duration > 0)
{
@@ -2771,7 +2790,7 @@ public:
[self willChangeValueForKey:@"camera"];
_mbglMap->cancelTransitions();
- mbgl::CameraOptions cameraOptions = [self cameraOptionsObjectForAnimatingToCamera:camera edgePadding:self.contentInset];
+ mbgl::CameraOptions cameraOptions = [self cameraOptionsObjectForAnimatingToCamera:camera edgePadding:edgePadding];
_mbglMap->easeTo(cameraOptions, animationOptions);
[self didChangeValueForKey:@"camera"];
}
diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md
index 1f05281d32..8707c0aad7 100644
--- a/platform/macos/CHANGELOG.md
+++ b/platform/macos/CHANGELOG.md
@@ -12,6 +12,13 @@
* Increased the default maximum zoom level from 20 to 22. ([#9835](https://github.com/mapbox/mapbox-gl-native/pull/9835))
+## 0.5.1
+
+This version of the Mapbox macOS SDK corresponds to version 3.6.2 of the Mapbox iOS SDK.
+
+* Added an `MGLStyle.localizesLabels` property, off by default, that localizes any Mapbox Streets–sourced symbol layer into the user’s preferred language. ([#9582](https://github.com/mapbox/mapbox-gl-native/pull/9582))
+* Fixed an issue that caused `-[MGLShapeSource featuresMatchingPredicate:]` and `-[MGLVectorSource featuresInSourceLayersWithIdentifiers:predicate:]` to always return an empty array. ([#9784](https://github.com/mapbox/mapbox-gl-native/pull/9784))
+
## 0.5.0
This version of the Mapbox macOS SDK corresponds to version 3.6.0 of the Mapbox iOS SDK.
diff --git a/platform/macos/app/MapDocument.m b/platform/macos/app/MapDocument.m
index 94bf18dea1..d6855d3ff2 100644
--- a/platform/macos/app/MapDocument.m
+++ b/platform/macos/app/MapDocument.m
@@ -5,7 +5,7 @@
#import "DroppedPinAnnotation.h"
#import "MGLStyle+MBXAdditions.h"
-#import "MGLVectorSource+MBXAdditions.h"
+#import "MGLVectorSource+MGLAdditions.h"
#import <Mapbox/Mapbox.h>
@@ -344,52 +344,7 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio
}
- (void)updateLabels {
- MGLStyle *style = self.mapView.style;
- NSString *preferredLanguage = _isLocalizingLabels ? [MGLVectorSource preferredMapboxStreetsLanguage] : nil;
- NSMutableDictionary *localizedKeysByKeyBySourceIdentifier = [NSMutableDictionary dictionary];
- for (MGLSymbolStyleLayer *layer in style.layers) {
- if (![layer isKindOfClass:[MGLSymbolStyleLayer class]]) {
- continue;
- }
-
- MGLVectorSource *source = (MGLVectorSource *)[style sourceWithIdentifier:layer.sourceIdentifier];
- if (![source isKindOfClass:[MGLVectorSource class]] || !source.mapboxStreets) {
- continue;
- }
-
- NSDictionary *localizedKeysByKey = localizedKeysByKeyBySourceIdentifier[layer.sourceIdentifier];
- if (!localizedKeysByKey) {
- localizedKeysByKey = localizedKeysByKeyBySourceIdentifier[layer.sourceIdentifier] = [source localizedKeysByKeyForPreferredLanguage:preferredLanguage];
- }
-
- NSString *(^stringByLocalizingString)(NSString *) = ^ NSString * (NSString *string) {
- NSMutableString *localizedString = string.mutableCopy;
- [localizedKeysByKey enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull localizedKey, BOOL * _Nonnull stop) {
- NSAssert([key isKindOfClass:[NSString class]], @"key is not a string");
- NSAssert([localizedKey isKindOfClass:[NSString class]], @"localizedKey is not a string");
- [localizedString replaceOccurrencesOfString:[NSString stringWithFormat:@"{%@}", key]
- withString:[NSString stringWithFormat:@"{%@}", localizedKey]
- options:0
- range:NSMakeRange(0, localizedString.length)];
- }];
- return localizedString;
- };
-
- if ([layer.text isKindOfClass:[MGLConstantStyleValue class]]) {
- NSString *textField = [(MGLConstantStyleValue<NSString *> *)layer.text rawValue];
- layer.text = [MGLStyleValue<NSString *> valueWithRawValue:stringByLocalizingString(textField)];
- }
- else if ([layer.text isKindOfClass:[MGLCameraStyleFunction class]]) {
- MGLCameraStyleFunction *function = (MGLCameraStyleFunction<NSString *> *)layer.text;
- NSMutableDictionary *stops = function.stops.mutableCopy;
- [stops enumerateKeysAndObjectsUsingBlock:^(NSNumber *zoomLevel, MGLConstantStyleValue<NSString *> *stop, BOOL *done) {
- NSString *textField = stop.rawValue;
- stops[zoomLevel] = [MGLStyleValue<NSString *> valueWithRawValue:stringByLocalizingString(textField)];
- }];
- function.stops = stops;
- layer.text = function;
- }
- }
+ self.mapView.style.localizesLabels = _isLocalizingLabels;
}
- (void)applyPendingState {
diff --git a/platform/macos/macos.xcodeproj/project.pbxproj b/platform/macos/macos.xcodeproj/project.pbxproj
index 5b4cadbc7c..34b08c0035 100644
--- a/platform/macos/macos.xcodeproj/project.pbxproj
+++ b/platform/macos/macos.xcodeproj/project.pbxproj
@@ -16,6 +16,8 @@
1F7454A51ECFB00300021D39 /* MGLLight.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F7454A21ECFB00300021D39 /* MGLLight.mm */; };
1F7454AB1ED1DDBD00021D39 /* MGLLightTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F7454AA1ED1DDBD00021D39 /* MGLLightTest.mm */; };
1F95931B1E6DE2B600D5B294 /* MGLNSDateAdditionsTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F95931A1E6DE2B600D5B294 /* MGLNSDateAdditionsTests.mm */; };
+ 1FCDF1421F2A4F3600A46694 /* MGLVectorSource+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FCDF1401F2A4F3600A46694 /* MGLVectorSource+MGLAdditions.h */; };
+ 1FCDF1431F2A4F3600A46694 /* MGLVectorSource+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FCDF1411F2A4F3600A46694 /* MGLVectorSource+MGLAdditions.m */; };
30E5781B1DAA857E0050F07E /* NSImage+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 30E578141DAA7D920050F07E /* NSImage+MGLAdditions.h */; };
3508EC641D749D39009B0EE4 /* NSExpression+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 3508EC621D749D39009B0EE4 /* NSExpression+MGLAdditions.h */; };
3508EC651D749D39009B0EE4 /* NSExpression+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3508EC631D749D39009B0EE4 /* NSExpression+MGLAdditions.mm */; };
@@ -237,7 +239,6 @@
DAEDC4371D606291000224FF /* MGLAttributionButtonTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DAEDC4361D606291000224FF /* MGLAttributionButtonTests.m */; };
DAF0D80E1DFE0E5D00B28378 /* MGLPointCollection_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DAF0D80D1DFE0E5D00B28378 /* MGLPointCollection_Private.h */; };
DAF0D8161DFE6B1800B28378 /* MGLAttributionInfo_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DAF0D8151DFE6B1800B28378 /* MGLAttributionInfo_Private.h */; };
- DAF0D81C1DFF567C00B28378 /* MGLVectorSource+MBXAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = DAF0D81B1DFF567C00B28378 /* MGLVectorSource+MBXAdditions.m */; };
DD0902B21DB1AC6400C5BDCE /* MGLNetworkConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = DD0902AF1DB1AC6400C5BDCE /* MGLNetworkConfiguration.m */; };
DD0902B31DB1AC6400C5BDCE /* MGLNetworkConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = DD0902B01DB1AC6400C5BDCE /* MGLNetworkConfiguration.h */; };
DD58A4C91D822C6700E1F038 /* MGLExpressionTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = DD58A4C71D822C6200E1F038 /* MGLExpressionTests.mm */; };
@@ -284,6 +285,8 @@
1F7454A21ECFB00300021D39 /* MGLLight.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLLight.mm; sourceTree = "<group>"; };
1F7454AA1ED1DDBD00021D39 /* MGLLightTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLLightTest.mm; sourceTree = "<group>"; };
1F95931A1E6DE2B600D5B294 /* MGLNSDateAdditionsTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLNSDateAdditionsTests.mm; path = ../../darwin/test/MGLNSDateAdditionsTests.mm; sourceTree = "<group>"; };
+ 1FCDF1401F2A4F3600A46694 /* MGLVectorSource+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MGLVectorSource+MGLAdditions.h"; sourceTree = "<group>"; };
+ 1FCDF1411F2A4F3600A46694 /* MGLVectorSource+MGLAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MGLVectorSource+MGLAdditions.m"; sourceTree = "<group>"; };
30E578141DAA7D920050F07E /* NSImage+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSImage+MGLAdditions.h"; path = "src/NSImage+MGLAdditions.h"; sourceTree = SOURCE_ROOT; };
3508EC621D749D39009B0EE4 /* NSExpression+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSExpression+MGLAdditions.h"; sourceTree = "<group>"; };
3508EC631D749D39009B0EE4 /* NSExpression+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSExpression+MGLAdditions.mm"; sourceTree = "<group>"; };
@@ -483,6 +486,7 @@
DACC22121CF3D3E200D220D9 /* MGLFeature.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLFeature.h; sourceTree = "<group>"; };
DACC22131CF3D3E200D220D9 /* MGLFeature.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLFeature.mm; sourceTree = "<group>"; };
DACC22171CF3D4F700D220D9 /* MGLFeature_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLFeature_Private.h; sourceTree = "<group>"; };
+ DACCD9C71F1F443B00BB09A1 /* fr */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Foundation.strings; sourceTree = "<group>"; };
DAD165721CF4CD7A001FF4B9 /* MGLShapeCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLShapeCollection.h; sourceTree = "<group>"; };
DAD165731CF4CD7A001FF4B9 /* MGLShapeCollection.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLShapeCollection.mm; sourceTree = "<group>"; };
DAE6C2E11CC304F900DB3429 /* Credits.rtf */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.rtf; path = Credits.rtf; sourceTree = "<group>"; };
@@ -575,8 +579,6 @@
DAEDC4361D606291000224FF /* MGLAttributionButtonTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLAttributionButtonTests.m; sourceTree = "<group>"; };
DAF0D80D1DFE0E5D00B28378 /* MGLPointCollection_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLPointCollection_Private.h; sourceTree = "<group>"; };
DAF0D8151DFE6B1800B28378 /* MGLAttributionInfo_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLAttributionInfo_Private.h; sourceTree = "<group>"; };
- DAF0D81A1DFF567C00B28378 /* MGLVectorSource+MBXAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MGLVectorSource+MBXAdditions.h"; sourceTree = "<group>"; };
- DAF0D81B1DFF567C00B28378 /* MGLVectorSource+MBXAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MGLVectorSource+MBXAdditions.m"; sourceTree = "<group>"; };
DAFBD0D51E3FA969000CD6BF /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/Localizable.strings"; sourceTree = "<group>"; };
DAFBD0D61E3FA983000CD6BF /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/Foundation.strings"; sourceTree = "<group>"; };
DD0902AF1DB1AC6400C5BDCE /* MGLNetworkConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLNetworkConfiguration.m; sourceTree = "<group>"; };
@@ -749,8 +751,6 @@
DA839E9E1CC2E3400062CAFB /* MapDocument.xib */,
DACB0C371E18DFFD005DDBEA /* MGLStyle+MBXAdditions.h */,
DACB0C381E18DFFD005DDBEA /* MGLStyle+MBXAdditions.m */,
- DAF0D81A1DFF567C00B28378 /* MGLVectorSource+MBXAdditions.h */,
- DAF0D81B1DFF567C00B28378 /* MGLVectorSource+MBXAdditions.m */,
DAE6C2E91CC3050F00DB3429 /* OfflinePackNameValueTransformer.h */,
DAE6C2EA1CC3050F00DB3429 /* OfflinePackNameValueTransformer.m */,
DAA48EFB1D6A4731006A7E36 /* StyleLayerIconTransformer.h */,
@@ -930,6 +930,8 @@
DAD1657F1CF4CF50001FF4B9 /* Categories */ = {
isa = PBXGroup;
children = (
+ 1FCDF1401F2A4F3600A46694 /* MGLVectorSource+MGLAdditions.h */,
+ 1FCDF1411F2A4F3600A46694 /* MGLVectorSource+MGLAdditions.m */,
408AA8601DAEED3300022900 /* MGLPolygon+MGLAdditions.h */,
408AA85C1DAEED3300022900 /* MGLPolygon+MGLAdditions.m */,
408AA8611DAEED3300022900 /* MGLPolyline+MGLAdditions.h */,
@@ -1166,6 +1168,7 @@
DAE6C3601CC31E0400DB3429 /* MGLOfflineRegion.h in Headers */,
DAE6C3681CC31E0400DB3429 /* MGLTilePyramidOfflineRegion.h in Headers */,
DA35A2CF1CCAAED300E826B2 /* NSValue+MGLAdditions.h in Headers */,
+ 1FCDF1421F2A4F3600A46694 /* MGLVectorSource+MGLAdditions.h in Headers */,
DAE6C3A61CC31E9400DB3429 /* MGLMapViewDelegate.h in Headers */,
DAE6C38B1CC31E2A00DB3429 /* MGLOfflinePack_Private.h in Headers */,
558DE7A61E56161C00C7916D /* MGLFoundation_Private.h in Headers */,
@@ -1391,7 +1394,6 @@
DACB0C391E18DFFD005DDBEA /* MGLStyle+MBXAdditions.m in Sources */,
DA839E9A1CC2E3400062CAFB /* main.m in Sources */,
DA839E971CC2E3400062CAFB /* AppDelegate.m in Sources */,
- DAF0D81C1DFF567C00B28378 /* MGLVectorSource+MBXAdditions.m in Sources */,
DAE6C2F01CC3050F00DB3429 /* OfflinePackNameValueTransformer.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -1408,6 +1410,7 @@
40B77E461DB11BCD003DA2FE /* NSArray+MGLAdditions.mm in Sources */,
DAE6C38C1CC31E2A00DB3429 /* MGLOfflinePack.mm in Sources */,
35D65C5B1D65AD5500722C23 /* NSDate+MGLAdditions.mm in Sources */,
+ 1FCDF1431F2A4F3600A46694 /* MGLVectorSource+MGLAdditions.m in Sources */,
DD0902B21DB1AC6400C5BDCE /* MGLNetworkConfiguration.m in Sources */,
1F7454A51ECFB00300021D39 /* MGLLight.mm in Sources */,
DAE6C3B11CC31EF300DB3429 /* MGLAnnotationImage.m in Sources */,
@@ -1614,6 +1617,7 @@
DA618B171E68876C00CB7F44 /* ca */,
DA618B231E6891ED00CB7F44 /* lt */,
DAE9E0F21EB7BF39001E8E8B /* es */,
+ DACCD9C71F1F443B00BB09A1 /* fr */,
);
name = Foundation.strings;
sourceTree = "<group>";
diff --git a/platform/macos/sdk/fr.lproj/Localizable.strings b/platform/macos/sdk/fr.lproj/Localizable.strings
index 34e085ef2b..9d73f23d05 100644
--- a/platform/macos/sdk/fr.lproj/Localizable.strings
+++ b/platform/macos/sdk/fr.lproj/Localizable.strings
@@ -1,6 +1,18 @@
-/* Accessibility title */
+/* User-friendly error description */
+"LOAD_MAP_FAILED_DESC" = "La carte n’a pas pu être chargée car une erreur inconnue est survenue.";
+
+/* User-friendly error description */
+"LOAD_STYLE_FAILED_DESC" = "La carte n’a pas pu être chargée car le style ne peut pas être chargé.";
+
+/* Accessibility title */
"MAP_A11Y_TITLE" = "Mapbox";
+/* User-friendly error description */
+"PARSE_STYLE_FAILED_DESC" = "La carte n’a pas pu être chargée car le style est corrompu.";
+
+/* User-friendly error description */
+"STYLE_NOT_FOUND_DESC" = "La carte n’a pas pu être chargée car le style n’a pas été trouvé ou est incompatible.";
+
/* Label of Zoom In button */
"ZOOM_IN_LABEL" = "+";