summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin R. Miller <incanus@codesorcery.net>2016-10-18 14:33:25 -0700
committerJustin R. Miller <incanus@codesorcery.net>2016-10-18 14:33:25 -0700
commitcc75209ce4553212f3442692b1123e4c6fd85ff2 (patch)
treee99dc62c90be3458b61766e9db529ddc627cecc5
parentb0c6eb309e76cf06a8fdef1316abbe07bb0f2f74 (diff)
parent0ccc7f51ba1d3377b93b4dddc3a4a03d0fda2260 (diff)
downloadqtlocation-mapboxgl-cc75209ce4553212f3442692b1123e4c6fd85ff2.tar.gz
Merge remote-tracking branch 'origin/master' into smooth-camera
-rw-r--r--Makefile4
-rw-r--r--README.md28
-rw-r--r--cmake/core-files.cmake79
-rw-r--r--cmake/shaders.cmake16
-rw-r--r--cmake/test-files.cmake1
-rw-r--r--include/mbgl/gl/gl.hpp6
-rw-r--r--package.json5
-rw-r--r--platform/android/.gitignore1
-rw-r--r--platform/android/MapboxGLAndroidSDK/proguard-rules.pro7
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/TwoFingerGestureDetector.java4
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapboxAccountManager.java21
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BaseMarkerViewOptions.java6
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/IconFactory.java3
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerView.java53
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java37
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java45
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java45
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java63
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java28
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java14
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java129
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/net/ConnectivityReceiver.java8
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Filter.java8
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEventManager.java7
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/AnimatorUtils.java12
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapview_preview.jpgbin0 -> 166053 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapview_preview.pngbin1088139 -> 0 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/build.gradle6
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/gradle.properties2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/proguard-rules.pro4
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml13
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapboxApplication.java12
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/DynamicMarkerChangeActivity.java2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewActivity.java79
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/MultiMapActivity.java15
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/OfflineActivity.java9
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTintActivity.java11
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_dynamic_marker.xml7
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_manual_zoom.xml5
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_multi_map.xml72
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/MarkerViewTest.java102
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/camera/CameraPositionTest.java8
-rw-r--r--platform/android/MapboxGLAndroidSDKWearTestApp/build.gradle56
-rw-r--r--platform/android/MapboxGLAndroidSDKWearTestApp/proguard-rules.pro17
-rw-r--r--platform/android/MapboxGLAndroidSDKWearTestApp/src/main/AndroidManifest.xml47
-rw-r--r--platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/MapboxApplication.java28
-rw-r--r--platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/activity/FeatureOverviewActivity.java47
-rw-r--r--platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/activity/SimpleMapViewActivity.java60
-rw-r--r--platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/adapter/FeatureAdapter.java78
-rw-r--r--platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/model/Feature.java30
-rw-r--r--platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/utils/OffsettingHelper.java40
-rw-r--r--platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/layout/activity_feature_overview.xml17
-rw-r--r--platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/layout/activity_simple_mapview.xml22
-rw-r--r--platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/layout/item_curved_layout.xml19
-rw-r--r--platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/mipmap-hdpi/ic_launcher.pngbin0 -> 19772 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/mipmap-mdpi/ic_launcher.pngbin0 -> 11003 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/mipmap-xhdpi/ic_launcher.pngbin0 -> 30669 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/mipmap-xxhdpi/ic_launcher.pngbin0 -> 58564 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/values/colors.xml31
-rw-r--r--platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/values/strings.xml6
-rw-r--r--platform/android/bitrise.yml2
-rw-r--r--platform/android/scripts/generate-style-code.js2
-rw-r--r--platform/android/scripts/generate-test-code.js2
-rw-r--r--platform/android/scripts/release.py243
-rw-r--r--platform/android/settings.gradle1
-rwxr-xr-xplatform/android/src/jni.cpp32
-rw-r--r--platform/android/src/style/android_conversion.hpp4
-rw-r--r--platform/android/src/style/value.cpp41
-rw-r--r--platform/android/src/style/value.hpp6
-rw-r--r--platform/darwin/scripts/generate-style-code.js151
-rw-r--r--platform/darwin/src/MGLBackgroundStyleLayer.h25
-rw-r--r--platform/darwin/src/MGLBackgroundStyleLayer.mm55
-rw-r--r--platform/darwin/src/MGLBaseStyleLayer.h35
-rw-r--r--platform/darwin/src/MGLBaseStyleLayer.mm77
-rw-r--r--platform/darwin/src/MGLCircleStyleLayer.h66
-rw-r--r--platform/darwin/src/MGLCircleStyleLayer.mm102
-rw-r--r--platform/darwin/src/MGLFeature.h16
-rw-r--r--platform/darwin/src/MGLFeature.mm96
-rw-r--r--platform/darwin/src/MGLFeature_Private.h25
-rw-r--r--platform/darwin/src/MGLFillStyleLayer.h56
-rw-r--r--platform/darwin/src/MGLFillStyleLayer.mm102
-rw-r--r--platform/darwin/src/MGLForegroundStyleLayer.h48
-rw-r--r--platform/darwin/src/MGLForegroundStyleLayer.m13
-rw-r--r--platform/darwin/src/MGLGeoJSONSource.h103
-rw-r--r--platform/darwin/src/MGLGeoJSONSource.mm40
-rw-r--r--platform/darwin/src/MGLLineStyleLayer.h106
-rw-r--r--platform/darwin/src/MGLLineStyleLayer.mm172
-rw-r--r--platform/darwin/src/MGLMultiPoint.h21
-rw-r--r--platform/darwin/src/MGLMultiPoint.mm28
-rw-r--r--platform/darwin/src/MGLMultiPoint_Private.h1
-rw-r--r--platform/darwin/src/MGLNetworkConfiguration.h11
-rw-r--r--platform/darwin/src/MGLNetworkConfiguration.m43
-rw-r--r--platform/darwin/src/MGLOfflineStorage.mm16
-rw-r--r--platform/darwin/src/MGLPointAnnotation.mm (renamed from platform/darwin/src/MGLPointAnnotation.m)18
-rw-r--r--platform/darwin/src/MGLPolygon+MGLAdditions.h7
-rw-r--r--platform/darwin/src/MGLPolygon+MGLAdditions.m27
-rw-r--r--platform/darwin/src/MGLPolygon.h2
-rw-r--r--platform/darwin/src/MGLPolygon.mm39
-rw-r--r--platform/darwin/src/MGLPolyline+MGLAdditions.h7
-rw-r--r--platform/darwin/src/MGLPolyline+MGLAdditions.m14
-rw-r--r--platform/darwin/src/MGLPolyline.h3
-rw-r--r--platform/darwin/src/MGLPolyline.mm39
-rw-r--r--platform/darwin/src/MGLRasterSource.h72
-rw-r--r--platform/darwin/src/MGLRasterSource.mm12
-rw-r--r--platform/darwin/src/MGLRasterStyleLayer.h37
-rw-r--r--platform/darwin/src/MGLRasterStyleLayer.mm87
-rw-r--r--platform/darwin/src/MGLRuntimeStylingTests.m.ejs11
-rw-r--r--platform/darwin/src/MGLShape.mm (renamed from platform/darwin/src/MGLShape.m)0
-rw-r--r--platform/darwin/src/MGLShapeCollection.m14
-rw-r--r--platform/darwin/src/MGLShape_Private.h17
-rw-r--r--platform/darwin/src/MGLSource.h25
-rw-r--r--platform/darwin/src/MGLSource.mm17
-rw-r--r--platform/darwin/src/MGLStyle.h111
-rw-r--r--platform/darwin/src/MGLStyle.mm186
-rw-r--r--platform/darwin/src/MGLStyleAttribute.h25
-rw-r--r--platform/darwin/src/MGLStyleAttribute.mm112
-rw-r--r--platform/darwin/src/MGLStyleAttributeFunction.h17
-rw-r--r--platform/darwin/src/MGLStyleAttributeFunction.mm247
-rw-r--r--platform/darwin/src/MGLStyleAttributeFunction_Private.h73
-rw-r--r--platform/darwin/src/MGLStyleAttributeValue.h5
-rw-r--r--platform/darwin/src/MGLStyleAttributeValue_Private.h24
-rw-r--r--platform/darwin/src/MGLStyleLayer.h67
-rw-r--r--platform/darwin/src/MGLStyleLayer.h.ejs50
-rw-r--r--platform/darwin/src/MGLStyleLayer.mm50
-rw-r--r--platform/darwin/src/MGLStyleLayer.mm.ejs64
-rw-r--r--platform/darwin/src/MGLStyleLayer_Private.h25
-rw-r--r--platform/darwin/src/MGLStyleValue.h176
-rw-r--r--platform/darwin/src/MGLStyleValue.mm88
-rw-r--r--platform/darwin/src/MGLStyleValue_Private.h156
-rw-r--r--platform/darwin/src/MGLSymbolStyleLayer.h350
-rw-r--r--platform/darwin/src/MGLSymbolStyleLayer.mm512
-rw-r--r--platform/darwin/src/MGLTileSet.h12
-rw-r--r--platform/darwin/src/MGLTypes.h8
-rw-r--r--platform/darwin/src/MGLVectorSource.h53
-rw-r--r--platform/darwin/src/MGLVectorSource.mm12
-rw-r--r--platform/darwin/src/MGLVectorStyleLayer.h127
-rw-r--r--platform/darwin/src/MGLVectorStyleLayer.m16
-rw-r--r--platform/darwin/src/NSArray+MGLAdditions.h9
-rw-r--r--platform/darwin/src/NSArray+MGLAdditions.mm26
-rw-r--r--platform/darwin/src/NSArray+MGLStyleAttributeAdditions.h7
-rw-r--r--platform/darwin/src/NSArray+MGLStyleAttributeAdditions.mm36
-rw-r--r--platform/darwin/src/NSArray+MGLStyleAttributeAdditions_Private.h9
-rw-r--r--platform/darwin/src/NSColor+MGLStyleAttributeAdditions.h7
-rw-r--r--platform/darwin/src/NSColor+MGLStyleAttributeAdditions.m5
-rw-r--r--platform/darwin/src/NSColor+MGLStyleAttributeAdditions_Private.h9
-rw-r--r--platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm7
-rw-r--r--platform/darwin/src/NSDictionary+MGLAdditions.h13
-rw-r--r--platform/darwin/src/NSDictionary+MGLAdditions.mm24
-rw-r--r--platform/darwin/src/NSExpression+MGLAdditions.h2
-rw-r--r--platform/darwin/src/NSExpression+MGLAdditions.mm26
-rw-r--r--platform/darwin/src/NSNumber+MGLStyleAttributeAdditions.h7
-rw-r--r--platform/darwin/src/NSNumber+MGLStyleAttributeAdditions.mm22
-rw-r--r--platform/darwin/src/NSNumber+MGLStyleAttributeAdditions_Private.h13
-rw-r--r--platform/darwin/src/NSString+MGLStyleAttributeAdditions.h7
-rw-r--r--platform/darwin/src/NSString+MGLStyleAttributeAdditions.mm17
-rw-r--r--platform/darwin/src/NSString+MGLStyleAttributeAdditions_Private.h11
-rw-r--r--platform/darwin/src/NSValue+MGLStyleAttributeAdditions.h10
-rw-r--r--platform/darwin/src/NSValue+MGLStyleAttributeAdditions.mm19
-rw-r--r--platform/darwin/src/NSValue+MGLStyleAttributeAdditions_Private.h15
-rw-r--r--platform/darwin/src/UIColor+MGLStyleAttributeAdditions_Private.h9
-rw-r--r--platform/darwin/src/run_loop.cpp2
-rw-r--r--platform/darwin/test/MGLBackgroundStyleLayerTests.m9
-rw-r--r--platform/darwin/test/MGLCircleStyleLayerTests.m25
-rw-r--r--platform/darwin/test/MGLFeatureTests.mm165
-rw-r--r--platform/darwin/test/MGLFillStyleLayerTests.m16
-rw-r--r--platform/darwin/test/MGLFilterTests.mm16
-rw-r--r--platform/darwin/test/MGLLineStyleLayerTests.m34
-rw-r--r--platform/darwin/test/MGLRasterStyleLayerTests.m7
-rw-r--r--platform/darwin/test/MGLRuntimeStylingHelper.h38
-rw-r--r--platform/darwin/test/MGLRuntimeStylingHelper.m120
-rw-r--r--platform/darwin/test/MGLSymbolStyleLayerTests.m97
-rw-r--r--platform/default/mbgl/storage/offline_database.cpp57
-rw-r--r--platform/default/mbgl/storage/offline_database.hpp4
-rw-r--r--platform/default/mbgl/storage/offline_download.cpp25
-rw-r--r--platform/ios/CHANGELOG.md3
-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/MBXViewController.m131
-rw-r--r--platform/ios/ios.xcodeproj/project.pbxproj292
-rw-r--r--platform/ios/jazzy.yml5
-rwxr-xr-xplatform/ios/scripts/deploy-packages.sh98
-rwxr-xr-xplatform/ios/scripts/publish.sh9
-rw-r--r--platform/ios/src/MGLMapView.mm421
-rw-r--r--platform/ios/src/MGLMapViewDelegate.h35
-rw-r--r--platform/ios/src/MGLMapboxEvents.m2
-rw-r--r--platform/ios/src/Mapbox.h11
-rw-r--r--platform/ios/src/UIColor+MGLAdditions.h6
-rw-r--r--platform/ios/src/UIColor+MGLAdditions.mm11
-rw-r--r--platform/ios/src/UIColor+MGLStyleAttributeAdditions.h7
-rw-r--r--platform/ios/src/UIColor+MGLStyleAttributeAdditions.mm14
-rw-r--r--platform/ios/src/UIImage+MGLAdditions.h9
-rw-r--r--platform/ios/src/UIImage+MGLAdditions.mm27
-rw-r--r--platform/ios/test/MGLGeoJSONSourceTests.mm264
-rw-r--r--platform/ios/test/MGLNSDataAdditionsTests.m4
m---------platform/ios/vendor/SMCalloutView0
-rw-r--r--platform/macos/CHANGELOG.md39
-rw-r--r--platform/macos/app/MapDocument.m28
-rw-r--r--platform/macos/bitrise.yml26
-rw-r--r--platform/macos/jazzy.yml5
-rw-r--r--platform/macos/macos.xcodeproj/project.pbxproj227
-rw-r--r--platform/macos/macos.xcodeproj/xcshareddata/xcschemes/CI.xcscheme28
-rw-r--r--platform/macos/src/MGLMapView.mm336
-rw-r--r--platform/macos/src/MGLMapViewDelegate.h35
-rw-r--r--platform/macos/src/Mapbox.h11
-rw-r--r--platform/macos/src/NSColor+MGLAdditions.h6
-rw-r--r--platform/macos/src/NSColor+MGLAdditions.mm8
-rw-r--r--platform/macos/src/NSImage+MGLAdditions.h9
-rw-r--r--platform/macos/src/NSImage+MGLAdditions.mm22
-rw-r--r--platform/node/src/node_map.cpp42
-rw-r--r--platform/node/src/node_map.hpp2
-rw-r--r--platform/node/test/js/map.test.js2
-rw-r--r--platform/qt/bitrise-qt5.yml12
-rw-r--r--src/mbgl/annotation/annotation_manager.cpp1
-rw-r--r--src/mbgl/geometry/buffer.hpp115
-rw-r--r--src/mbgl/geometry/circle_buffer.cpp15
-rw-r--r--src/mbgl/geometry/circle_buffer.hpp24
-rw-r--r--src/mbgl/geometry/collision_box_buffer.cpp27
-rw-r--r--src/mbgl/geometry/collision_box_buffer.hpp20
-rw-r--r--src/mbgl/geometry/debug_font_buffer.cpp44
-rw-r--r--src/mbgl/geometry/debug_font_buffer.hpp14
-rw-r--r--src/mbgl/geometry/elements_buffer.cpp18
-rw-r--r--src/mbgl/geometry/elements_buffer.hpp46
-rw-r--r--src/mbgl/geometry/feature_index.cpp20
-rw-r--r--src/mbgl/geometry/feature_index.hpp8
-rw-r--r--src/mbgl/geometry/fill_buffer.cpp15
-rw-r--r--src/mbgl/geometry/fill_buffer.hpp18
-rw-r--r--src/mbgl/geometry/icon_buffer.cpp35
-rw-r--r--src/mbgl/geometry/icon_buffer.hpp17
-rw-r--r--src/mbgl/geometry/line_buffer.cpp37
-rw-r--r--src/mbgl/geometry/line_buffer.hpp37
-rw-r--r--src/mbgl/geometry/static_vertex_buffer.cpp24
-rw-r--r--src/mbgl/geometry/static_vertex_buffer.hpp30
-rw-r--r--src/mbgl/geometry/text_buffer.cpp36
-rw-r--r--src/mbgl/geometry/text_buffer.hpp20
-rw-r--r--src/mbgl/geometry/vao.hpp79
-rw-r--r--src/mbgl/gl/attribute.hpp50
-rw-r--r--src/mbgl/gl/context.cpp30
-rw-r--r--src/mbgl/gl/context.hpp31
-rw-r--r--src/mbgl/gl/index_buffer.hpp41
-rw-r--r--src/mbgl/gl/shader.cpp (renamed from src/mbgl/shader/shader.cpp)21
-rw-r--r--src/mbgl/gl/shader.hpp45
-rw-r--r--src/mbgl/gl/types.hpp21
-rw-r--r--src/mbgl/gl/uniform.cpp (renamed from src/mbgl/shader/uniform.cpp)6
-rw-r--r--src/mbgl/gl/uniform.hpp (renamed from src/mbgl/shader/uniform.hpp)8
-rw-r--r--src/mbgl/gl/vao.cpp (renamed from src/mbgl/geometry/vao.cpp)21
-rw-r--r--src/mbgl/gl/vao.hpp78
-rw-r--r--src/mbgl/gl/vertex_buffer.hpp17
-rw-r--r--src/mbgl/layout/symbol_layout.cpp111
-rw-r--r--src/mbgl/layout/symbol_layout.hpp2
-rw-r--r--src/mbgl/map/map.cpp11
-rw-r--r--src/mbgl/renderer/circle_bucket.cpp52
-rw-r--r--src/mbgl/renderer/circle_bucket.hpp20
-rw-r--r--src/mbgl/renderer/debug_bucket.cpp95
-rw-r--r--src/mbgl/renderer/debug_bucket.hpp21
-rw-r--r--src/mbgl/renderer/element_group.hpp28
-rw-r--r--src/mbgl/renderer/fill_bucket.cpp106
-rw-r--r--src/mbgl/renderer/fill_bucket.hpp37
-rw-r--r--src/mbgl/renderer/line_bucket.cpp218
-rw-r--r--src/mbgl/renderer/line_bucket.hpp33
-rw-r--r--src/mbgl/renderer/painter.cpp28
-rw-r--r--src/mbgl/renderer/painter.hpp47
-rw-r--r--src/mbgl/renderer/painter_background.cpp10
-rw-r--r--src/mbgl/renderer/painter_circle.cpp2
-rw-r--r--src/mbgl/renderer/painter_clipping.cpp6
-rw-r--r--src/mbgl/renderer/painter_debug.cpp10
-rw-r--r--src/mbgl/renderer/painter_fill.cpp8
-rw-r--r--src/mbgl/renderer/painter_line.cpp4
-rw-r--r--src/mbgl/renderer/painter_raster.cpp2
-rw-r--r--src/mbgl/renderer/painter_symbol.cpp14
-rw-r--r--src/mbgl/renderer/raster_bucket.cpp8
-rw-r--r--src/mbgl/renderer/raster_bucket.hpp12
-rw-r--r--src/mbgl/renderer/symbol_bucket.cpp61
-rw-r--r--src/mbgl/renderer/symbol_bucket.hpp49
-rw-r--r--src/mbgl/shader/circle_shader.cpp7
-rw-r--r--src/mbgl/shader/circle_shader.hpp29
-rw-r--r--src/mbgl/shader/circle_vertex.cpp7
-rw-r--r--src/mbgl/shader/circle_vertex.hpp39
-rw-r--r--src/mbgl/shader/collision_box_shader.cpp25
-rw-r--r--src/mbgl/shader/collision_box_shader.hpp23
-rw-r--r--src/mbgl/shader/collision_box_vertex.cpp7
-rw-r--r--src/mbgl/shader/collision_box_vertex.hpp43
-rw-r--r--src/mbgl/shader/fill_outline_pattern_shader.cpp15
-rw-r--r--src/mbgl/shader/fill_outline_pattern_shader.hpp37
-rw-r--r--src/mbgl/shader/fill_outline_shader.cpp15
-rw-r--r--src/mbgl/shader/fill_outline_shader.hpp26
-rw-r--r--src/mbgl/shader/fill_pattern_shader.cpp15
-rw-r--r--src/mbgl/shader/fill_pattern_shader.hpp36
-rw-r--r--src/mbgl/shader/fill_shader.cpp15
-rw-r--r--src/mbgl/shader/fill_shader.hpp25
-rw-r--r--src/mbgl/shader/fill_vertex.cpp7
-rw-r--r--src/mbgl/shader/fill_vertex.hpp30
-rw-r--r--src/mbgl/shader/icon_shader.cpp31
-rw-r--r--src/mbgl/shader/icon_shader.hpp24
-rw-r--r--src/mbgl/shader/line_pattern_shader.cpp15
-rw-r--r--src/mbgl/shader/line_pattern_shader.hpp41
-rw-r--r--src/mbgl/shader/line_sdf_shader.cpp15
-rw-r--r--src/mbgl/shader/line_sdf_shader.hpp42
-rw-r--r--src/mbgl/shader/line_shader.cpp10
-rw-r--r--src/mbgl/shader/line_shader.hpp38
-rw-r--r--src/mbgl/shader/line_vertex.cpp7
-rw-r--r--src/mbgl/shader/line_vertex.hpp72
-rw-r--r--src/mbgl/shader/linepattern_shader.cpp23
-rw-r--r--src/mbgl/shader/linepattern_shader.hpp35
-rw-r--r--src/mbgl/shader/linesdf_shader.cpp23
-rw-r--r--src/mbgl/shader/linesdf_shader.hpp36
-rw-r--r--src/mbgl/shader/outline_shader.cpp20
-rw-r--r--src/mbgl/shader/outline_shader.hpp21
-rw-r--r--src/mbgl/shader/outlinepattern_shader.cpp20
-rw-r--r--src/mbgl/shader/outlinepattern_shader.hpp32
-rw-r--r--src/mbgl/shader/pattern_shader.cpp20
-rw-r--r--src/mbgl/shader/pattern_shader.hpp31
-rw-r--r--src/mbgl/shader/plain_shader.cpp20
-rw-r--r--src/mbgl/shader/plain_shader.hpp20
-rw-r--r--src/mbgl/shader/raster_shader.cpp12
-rw-r--r--src/mbgl/shader/raster_shader.hpp42
-rw-r--r--src/mbgl/shader/raster_vertex.cpp7
-rw-r--r--src/mbgl/shader/raster_vertex.hpp39
-rw-r--r--src/mbgl/shader/sdf_shader.cpp31
-rw-r--r--src/mbgl/shader/sdf_shader.hpp32
-rw-r--r--src/mbgl/shader/shader.hpp53
-rw-r--r--src/mbgl/shader/shaders.hpp72
-rw-r--r--src/mbgl/shader/symbol_icon_shader.cpp15
-rw-r--r--src/mbgl/shader/symbol_icon_shader.hpp32
-rw-r--r--src/mbgl/shader/symbol_sdf_shader.cpp15
-rw-r--r--src/mbgl/shader/symbol_sdf_shader.hpp40
-rw-r--r--src/mbgl/shader/symbol_vertex.cpp9
-rw-r--r--src/mbgl/shader/symbol_vertex.hpp54
-rw-r--r--src/mbgl/style/layer_impl.hpp2
-rw-r--r--src/mbgl/style/layers/circle_layer_impl.cpp4
-rw-r--r--src/mbgl/style/layers/circle_layer_impl.hpp2
-rw-r--r--src/mbgl/style/layers/fill_layer_impl.cpp4
-rw-r--r--src/mbgl/style/layers/fill_layer_impl.hpp2
-rw-r--r--src/mbgl/style/layers/line_layer_impl.cpp4
-rw-r--r--src/mbgl/style/layers/line_layer_impl.hpp2
-rw-r--r--src/mbgl/style/source_impl.cpp51
-rw-r--r--src/mbgl/text/collision_tile.cpp46
-rw-r--r--src/mbgl/text/collision_tile.hpp10
-rw-r--r--src/mbgl/tile/geometry_tile.cpp2
-rw-r--r--src/mbgl/tile/tile.cpp1
-rw-r--r--src/mbgl/tile/tile.hpp1
-rw-r--r--src/mbgl/util/intersection_tests.cpp49
-rw-r--r--src/mbgl/util/intersection_tests.hpp6
-rw-r--r--src/mbgl/util/tile_coordinate.hpp25
-rw-r--r--test/api/annotations.test.cpp67
-rw-r--r--test/gl/object.test.cpp7
-rw-r--r--test/map/map.test.cpp16
-rw-r--r--test/storage/offline_database.test.cpp53
-rw-r--r--test/tile/raster_tile.test.cpp2
-rw-r--r--test/tile/tile_coordinate.test.cpp92
-rw-r--r--test/tile/vector_tile.test.cpp2
351 files changed, 7992 insertions, 5320 deletions
diff --git a/Makefile b/Makefile
index cb623b775d..1415d4f070 100644
--- a/Makefile
+++ b/Makefile
@@ -265,6 +265,10 @@ ifabric: $(IOS_PROJ_PATH)
FORMAT=static BUILD_DEVICE=$(BUILD_DEVICE) SYMBOLS=NO SELF_CONTAINED=YES \
./platform/ios/scripts/package.sh
+.PHONY: ideploy
+ideploy:
+ caffeinate -i ./platform/ios/scripts/deploy-packages.sh
+
.PHONY: idocument
idocument:
OUTPUT=$(OUTPUT) ./platform/ios/scripts/document.sh
diff --git a/README.md b/README.md
index b4beb9752a..94a534a12f 100644
--- a/README.md
+++ b/README.md
@@ -6,20 +6,22 @@ A library for embedding interactive, customizable vector maps into native applic
This repository hosts the cross-platform Mapbox GL Native library, plus convenient SDKs for several platforms. The cross-platform library comes with a [GLFW](https://github.com/glfw/glfw)-based demo application for Ubuntu Linux and macOS. The SDKs target the usual languages on their respective platforms:
-SDK | Languages | Build status
-----|-----------|-------------
-[Mapbox GL Native](INSTALL.md) | C++14 | [![Travis](https://travis-ci.org/mapbox/mapbox-gl-native.svg?branch=master)](https://travis-ci.org/mapbox/mapbox-gl-native/builds) [![Coverage Status](https://coveralls.io/repos/github/mapbox/mapbox-gl-native/badge.svg?branch=master)](https://coveralls.io/github/mapbox/mapbox-gl-native?branch=master)
-[Mapbox Android SDK](platform/android/) | Java | [![Bitrise](https://www.bitrise.io/app/79cdcbdc42de4303.svg?token=_InPF8bII6W7J6kFr-L8QQ&branch=master)](https://www.bitrise.io/app/79cdcbdc42de4303)
-[Mapbox iOS SDK](platform/ios/) | Objective-C or Swift | [![Bitrise](https://www.bitrise.io/app/7514e4cf3da2cc57.svg?token=OwqZE5rSBR9MVWNr_lf4sA&branch=master)](https://www.bitrise.io/app/7514e4cf3da2cc57)
-[Mapbox macOS SDK](platform/macos/) | Objective-C, Swift, or AppleScript | [![Bitrise](https://www.bitrise.io/app/155ef7da24b38dcd.svg?token=4KSOw_gd6WxTnvGE2rMttg&branch=master)](https://www.bitrise.io/app/155ef7da24b38dcd)
-[node-mapbox-gl-native](platform/node/) | Node.js | [![Linux](https://travis-ci.org/mapbox/mapbox-gl-native.svg?branch=master)](https://travis-ci.org/mapbox/mapbox-gl-native/builds) [![macOS](https://www.bitrise.io/app/55e3a9bf71202106.svg?token=5qf5ZUcKVN3LDnHhW7rO0w)](https://www.bitrise.io/app/55e3a9bf71202106)
-[Mapbox Qt SDK](platform/qt) | C++03 | [![Travis](https://travis-ci.org/mapbox/mapbox-gl-native.svg?branch=master)](https://travis-ci.org/mapbox/mapbox-gl-native/builds) [![Bitrise](https://www.bitrise.io/app/96cfbc97e0245c22.svg?token=GxsqIOGPXhn0F23sSVSsYA&branch=master)](https://www.bitrise.io/app/96cfbc97e0245c22)
+| SDK | Languages | Build status |
+| --------------------------------------- | ---------------------------------- | ---------------------------------------- |
+| [Mapbox GL Native](INSTALL.md) | C++14 | [![Travis](https://travis-ci.org/mapbox/mapbox-gl-native.svg?branch=master)](https://travis-ci.org/mapbox/mapbox-gl-native/builds) [![Coverage Status](https://coveralls.io/repos/github/mapbox/mapbox-gl-native/badge.svg?branch=master)](https://coveralls.io/github/mapbox/mapbox-gl-native?branch=master) |
+| [Mapbox Android SDK](platform/android/) | Java | [![Bitrise](https://www.bitrise.io/app/79cdcbdc42de4303.svg?token=_InPF8bII6W7J6kFr-L8QQ&branch=master)](https://www.bitrise.io/app/79cdcbdc42de4303) |
+| [Mapbox iOS SDK](platform/ios/) | Objective-C or Swift | [![Bitrise](https://www.bitrise.io/app/7514e4cf3da2cc57.svg?token=OwqZE5rSBR9MVWNr_lf4sA&branch=master)](https://www.bitrise.io/app/7514e4cf3da2cc57) |
+| [Mapbox macOS SDK](platform/macos/) | Objective-C, Swift, or AppleScript | [![Bitrise](https://www.bitrise.io/app/155ef7da24b38dcd.svg?token=4KSOw_gd6WxTnvGE2rMttg&branch=master)](https://www.bitrise.io/app/155ef7da24b38dcd) |
+| [node-mapbox-gl-native](platform/node/) | Node.js | [![Linux](https://travis-ci.org/mapbox/mapbox-gl-native.svg?branch=master)](https://travis-ci.org/mapbox/mapbox-gl-native/builds) [![macOS](https://www.bitrise.io/app/55e3a9bf71202106.svg?token=5qf5ZUcKVN3LDnHhW7rO0w)](https://www.bitrise.io/app/55e3a9bf71202106) |
+| [Mapbox Qt SDK](platform/qt) | C++03 | [![Travis](https://travis-ci.org/mapbox/mapbox-gl-native.svg?branch=master)](https://travis-ci.org/mapbox/mapbox-gl-native/builds) [![Bitrise](https://www.bitrise.io/app/96cfbc97e0245c22.svg?token=GxsqIOGPXhn0F23sSVSsYA&branch=master)](https://www.bitrise.io/app/96cfbc97e0245c22) |
-Additional Mapbox GL Native–based libraries are developed outside of this repository:
+Additional Mapbox GL Native–based libraries for **hybrid applications** are developed outside of this repository:
-* [React Native Mapbox GL](https://github.com/mapbox/react-native-mapbox-gl) for React Native applications on iOS and Android
-* Telerik’s [Mapbox plugin](http://plugins.telerik.com/cordova/plugin/mapbox) for Apache Cordova Hybrid applications
-* Telerik’s [Mapbox plugin](http://plugins.telerik.com/nativescript/plugin/mapbox) for NativeScript Hybrid applications
-* Xamarin's [Mapbox component](https://components.xamarin.com/view/mapboxsdk) for Xamarin Hybrid applications
+| Toolkit | Android | iOS | Developer |
+| ---------------------------------------- | --------|-----|------------ |
+| [React Native](https://github.com/mapbox/react-native-mapbox-gl/) ([npm](https://www.npmjs.com/package/react-native-mapbox-gl)) | :white_check_mark: | :white_check_mark: | |
+| [Apache Cordova](http://plugins.telerik.com/cordova/plugin/mapbox/) ([npm](https://www.npmjs.com/package/cordova-plugin-mapbox)) | :white_check_mark: | :white_check_mark: | Telerik |
+| [NativeScript](http://plugins.telerik.com/nativescript/plugin/mapbox/) ([npm](https://www.npmjs.com/package/nativescript-mapbox/)) | :white_check_mark: | :white_check_mark: | Telerik |
+| [Xamarin](https://components.xamarin.com/view/mapboxsdk/) | :white_check_mark: | :white_check_mark: | Xamarin |
If your platform or hybrid application framework isn’t listed here, consider embedding [Mapbox GL JS](https://github.com/mapbox/mapbox-gl-js) using the standard Web capabilities on your platform.
diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake
index 32410927ad..8940899c16 100644
--- a/cmake/core-files.cmake
+++ b/cmake/core-files.cmake
@@ -48,35 +48,15 @@ set(MBGL_CORE_FILES
# geometry
src/mbgl/geometry/anchor.hpp
src/mbgl/geometry/binpack.hpp
- src/mbgl/geometry/buffer.hpp
- src/mbgl/geometry/circle_buffer.cpp
- src/mbgl/geometry/circle_buffer.hpp
- src/mbgl/geometry/collision_box_buffer.cpp
- src/mbgl/geometry/collision_box_buffer.hpp
- src/mbgl/geometry/debug_font_buffer.cpp
- src/mbgl/geometry/debug_font_buffer.hpp
src/mbgl/geometry/debug_font_data.hpp
- src/mbgl/geometry/elements_buffer.cpp
- src/mbgl/geometry/elements_buffer.hpp
src/mbgl/geometry/feature_index.cpp
src/mbgl/geometry/feature_index.hpp
- src/mbgl/geometry/fill_buffer.cpp
- src/mbgl/geometry/fill_buffer.hpp
- src/mbgl/geometry/icon_buffer.cpp
- src/mbgl/geometry/icon_buffer.hpp
src/mbgl/geometry/line_atlas.cpp
src/mbgl/geometry/line_atlas.hpp
- src/mbgl/geometry/line_buffer.cpp
- src/mbgl/geometry/line_buffer.hpp
- src/mbgl/geometry/static_vertex_buffer.cpp
- src/mbgl/geometry/static_vertex_buffer.hpp
- src/mbgl/geometry/text_buffer.cpp
- src/mbgl/geometry/text_buffer.hpp
- src/mbgl/geometry/vao.cpp
- src/mbgl/geometry/vao.hpp
# gl
include/mbgl/gl/gl.hpp
+ src/mbgl/gl/attribute.hpp
src/mbgl/gl/context.cpp
src/mbgl/gl/context.hpp
src/mbgl/gl/debugging.cpp
@@ -84,15 +64,23 @@ set(MBGL_CORE_FILES
src/mbgl/gl/extension.cpp
src/mbgl/gl/extension.hpp
src/mbgl/gl/gl.cpp
+ src/mbgl/gl/index_buffer.hpp
src/mbgl/gl/object.cpp
src/mbgl/gl/object.hpp
+ src/mbgl/gl/shader.cpp
+ src/mbgl/gl/shader.hpp
src/mbgl/gl/state.hpp
src/mbgl/gl/texture.hpp
src/mbgl/gl/types.hpp
+ src/mbgl/gl/uniform.cpp
+ src/mbgl/gl/uniform.hpp
src/mbgl/gl/value.cpp
src/mbgl/gl/value.hpp
+ src/mbgl/gl/vao.cpp
+ src/mbgl/gl/vao.hpp
src/mbgl/gl/vertex_array.cpp
src/mbgl/gl/vertex_array.hpp
+ src/mbgl/gl/vertex_buffer.hpp
# layout
src/mbgl/layout/clip_lines.cpp
@@ -154,6 +142,7 @@ set(MBGL_CORE_FILES
src/mbgl/renderer/circle_bucket.hpp
src/mbgl/renderer/debug_bucket.cpp
src/mbgl/renderer/debug_bucket.hpp
+ src/mbgl/renderer/element_group.hpp
src/mbgl/renderer/fill_bucket.cpp
src/mbgl/renderer/fill_bucket.hpp
src/mbgl/renderer/frame_history.cpp
@@ -183,33 +172,41 @@ set(MBGL_CORE_FILES
# shader
src/mbgl/shader/circle_shader.cpp
src/mbgl/shader/circle_shader.hpp
+ src/mbgl/shader/circle_vertex.cpp
+ src/mbgl/shader/circle_vertex.hpp
src/mbgl/shader/collision_box_shader.cpp
src/mbgl/shader/collision_box_shader.hpp
- src/mbgl/shader/icon_shader.cpp
- src/mbgl/shader/icon_shader.hpp
+ src/mbgl/shader/collision_box_vertex.cpp
+ src/mbgl/shader/collision_box_vertex.hpp
+ src/mbgl/shader/fill_outline_pattern_shader.cpp
+ src/mbgl/shader/fill_outline_pattern_shader.hpp
+ src/mbgl/shader/fill_outline_shader.cpp
+ src/mbgl/shader/fill_outline_shader.hpp
+ src/mbgl/shader/fill_pattern_shader.cpp
+ src/mbgl/shader/fill_pattern_shader.hpp
+ src/mbgl/shader/fill_shader.cpp
+ src/mbgl/shader/fill_shader.hpp
+ src/mbgl/shader/fill_vertex.cpp
+ src/mbgl/shader/fill_vertex.hpp
+ src/mbgl/shader/line_pattern_shader.cpp
+ src/mbgl/shader/line_pattern_shader.hpp
+ src/mbgl/shader/line_sdf_shader.cpp
+ src/mbgl/shader/line_sdf_shader.hpp
src/mbgl/shader/line_shader.cpp
src/mbgl/shader/line_shader.hpp
- src/mbgl/shader/linepattern_shader.cpp
- src/mbgl/shader/linepattern_shader.hpp
- src/mbgl/shader/linesdf_shader.cpp
- src/mbgl/shader/linesdf_shader.hpp
- src/mbgl/shader/outline_shader.cpp
- src/mbgl/shader/outline_shader.hpp
- src/mbgl/shader/outlinepattern_shader.cpp
- src/mbgl/shader/outlinepattern_shader.hpp
- src/mbgl/shader/pattern_shader.cpp
- src/mbgl/shader/pattern_shader.hpp
- src/mbgl/shader/plain_shader.cpp
- src/mbgl/shader/plain_shader.hpp
+ src/mbgl/shader/line_vertex.cpp
+ src/mbgl/shader/line_vertex.hpp
src/mbgl/shader/raster_shader.cpp
src/mbgl/shader/raster_shader.hpp
- src/mbgl/shader/sdf_shader.cpp
- src/mbgl/shader/sdf_shader.hpp
- src/mbgl/shader/shader.cpp
- src/mbgl/shader/shader.hpp
+ src/mbgl/shader/raster_vertex.cpp
+ src/mbgl/shader/raster_vertex.hpp
src/mbgl/shader/shaders.hpp
- src/mbgl/shader/uniform.cpp
- src/mbgl/shader/uniform.hpp
+ src/mbgl/shader/symbol_icon_shader.cpp
+ src/mbgl/shader/symbol_icon_shader.hpp
+ src/mbgl/shader/symbol_sdf_shader.cpp
+ src/mbgl/shader/symbol_sdf_shader.hpp
+ src/mbgl/shader/symbol_vertex.cpp
+ src/mbgl/shader/symbol_vertex.hpp
# sprite
include/mbgl/sprite/sprite_image.hpp
diff --git a/cmake/shaders.cmake b/cmake/shaders.cmake
index 5495f5b281..bebf476bbf 100644
--- a/cmake/shaders.cmake
+++ b/cmake/shaders.cmake
@@ -15,15 +15,15 @@ function(add_shader VAR name)
endfunction()
add_shader(MBGL_SHADER_FILES circle)
-add_shader(MBGL_SHADER_FILES collisionbox)
+add_shader(MBGL_SHADER_FILES collision_box)
add_shader(MBGL_SHADER_FILES debug)
add_shader(MBGL_SHADER_FILES fill)
-add_shader(MBGL_SHADER_FILES icon)
+add_shader(MBGL_SHADER_FILES fill_outline)
+add_shader(MBGL_SHADER_FILES fill_outline_pattern)
+add_shader(MBGL_SHADER_FILES fill_pattern)
add_shader(MBGL_SHADER_FILES line)
-add_shader(MBGL_SHADER_FILES linepattern)
-add_shader(MBGL_SHADER_FILES linesdfpattern)
-add_shader(MBGL_SHADER_FILES outline)
-add_shader(MBGL_SHADER_FILES outlinepattern)
-add_shader(MBGL_SHADER_FILES pattern)
+add_shader(MBGL_SHADER_FILES line_pattern)
+add_shader(MBGL_SHADER_FILES line_sdf)
add_shader(MBGL_SHADER_FILES raster)
-add_shader(MBGL_SHADER_FILES sdf)
+add_shader(MBGL_SHADER_FILES symbol_icon)
+add_shader(MBGL_SHADER_FILES symbol_sdf)
diff --git a/cmake/test-files.cmake b/cmake/test-files.cmake
index 814936d786..2ade1ba537 100644
--- a/cmake/test-files.cmake
+++ b/cmake/test-files.cmake
@@ -91,6 +91,7 @@ set(MBGL_TEST_FILES
test/tile/raster_tile.test.cpp
test/tile/tile_id.test.cpp
test/tile/vector_tile.test.cpp
+ test/tile/tile_coordinate.test.cpp
# util
test/util/async_task.test.cpp
diff --git a/include/mbgl/gl/gl.hpp b/include/mbgl/gl/gl.hpp
index a499d731d6..b3c2d83a5e 100644
--- a/include/mbgl/gl/gl.hpp
+++ b/include/mbgl/gl/gl.hpp
@@ -1,6 +1,7 @@
#pragma once
#include <stdexcept>
+#include <limits>
#if __APPLE__
#include "TargetConditionals.h"
@@ -36,12 +37,11 @@ struct Error : std::runtime_error {
void checkError(const char *cmd, const char *file, int line);
-} // namespace gl
-} // namespace mbgl
-
#ifndef NDEBUG
#define MBGL_CHECK_ERROR(cmd) ([&]() { struct __MBGL_C_E { ~__MBGL_C_E() { ::mbgl::gl::checkError(#cmd, __FILE__, __LINE__); } } __MBGL_C_E; return cmd; }())
#else
#define MBGL_CHECK_ERROR(cmd) (cmd)
#endif
+} // namespace gl
+} // namespace mbgl
diff --git a/package.json b/package.json
index 0c27cbe95d..61936e2fe7 100644
--- a/package.json
+++ b/package.json
@@ -20,9 +20,10 @@
"csscolorparser": "^1.0.2",
"ejs": "^2.4.1",
"express": "^4.11.1",
- "mapbox-gl-shaders": "mapbox/mapbox-gl-shaders#de2ab007455aa2587c552694c68583f94c9f2747",
+ "lodash": "^4.16.4",
+ "mapbox-gl-shaders": "mapbox/mapbox-gl-shaders#98a56d538b11fb331aa67a6d632d6ecd6821b007",
"mapbox-gl-style-spec": "mapbox/mapbox-gl-style-spec#7f62a4fc9f21e619824d68abbc4b03cbc1685572",
- "mapbox-gl-test-suite": "mapbox/mapbox-gl-test-suite#694f0d0728f229d64d1639dc5ee7aff7f4b8ca41",
+ "mapbox-gl-test-suite": "mapbox/mapbox-gl-test-suite#6df3b27868cc00432197e3fc9c166fdba7067913",
"mkdirp": "^0.5.1",
"node-cmake": "^1.2.1",
"request": "^2.72.0",
diff --git a/platform/android/.gitignore b/platform/android/.gitignore
index 5ede06a831..b0e8cceb45 100644
--- a/platform/android/.gitignore
+++ b/platform/android/.gitignore
@@ -21,6 +21,7 @@ local.properties
# Token file
MapboxGLAndroidSDKTestApp/src/main/res/values/developer-config.xml
+MapboxGLAndroidSDKWearTestApp/src/main/res/values/developer-config.xml
# Twitter Fabric / Crashlytics
fabric.properties
diff --git a/platform/android/MapboxGLAndroidSDK/proguard-rules.pro b/platform/android/MapboxGLAndroidSDK/proguard-rules.pro
index ddd7730ac4..96f7bb95f3 100644
--- a/platform/android/MapboxGLAndroidSDK/proguard-rules.pro
+++ b/platform/android/MapboxGLAndroidSDK/proguard-rules.pro
@@ -1,7 +1,7 @@
# By default, the flags in this file are appended to flags specified
# in ../sdk/tools/proguard/proguard-android.txt,
# contents of this file will be appended into proguard-android.txt
--keepattributes Signature, *Annotation*
+-keepattributes Signature, *Annotation*, EnclosingMethod
# Square okio, ignoring warnings,
# see https://github.com/square/okio/issues/60
@@ -10,7 +10,7 @@
# Gesture package
-keep class almeros.android.multitouch.gesturedetectors.** { *; }
-# Package: annotations
+# Package annotations
-keep class com.mapbox.mapboxsdk.annotations.** { *; }
# Package camera
@@ -25,6 +25,9 @@
# Package maps
-keep class com.mapbox.mapboxsdk.maps.** { *; }
+# Package net
+-keep class com.mapbox.mapboxsdk.net.** { *; }
+
# Package offline
-keep class com.mapbox.mapboxsdk.offline.** { *; }
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/TwoFingerGestureDetector.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/TwoFingerGestureDetector.java
index 91e5ef13c8..6be0b46d5b 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/TwoFingerGestureDetector.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/TwoFingerGestureDetector.java
@@ -133,7 +133,7 @@ public abstract class TwoFingerGestureDetector extends BaseGestureDetector {
* @return Raw x value or 0
*/
protected static float getRawX(MotionEvent event, int pointerIndex) {
- float offset = event.getX() - event.getRawX();
+ float offset = event.getRawX() - event.getX();
if (pointerIndex < event.getPointerCount()) {
return event.getX(pointerIndex) + offset;
}
@@ -149,7 +149,7 @@ public abstract class TwoFingerGestureDetector extends BaseGestureDetector {
* @return Raw y value or 0
*/
protected static float getRawY(MotionEvent event, int pointerIndex) {
- float offset = event.getY() - event.getRawY();
+ float offset = event.getRawY() - event.getY();
if (pointerIndex < event.getPointerCount()) {
return event.getY(pointerIndex) + offset;
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapboxAccountManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapboxAccountManager.java
index 0d192d302d..b33d01a105 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapboxAccountManager.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapboxAccountManager.java
@@ -18,6 +18,8 @@ public class MapboxAccountManager {
private final String accessToken;
private final Context applicationContext;
+ private Boolean connected = null;
+
/**
* MapboxAccountManager should NOT be instantiated directly.
* Use @see MapboxAccountManager#getInstance() instead.
@@ -90,12 +92,29 @@ public class MapboxAccountManager {
}
/**
+ * Manually sets the connectivity state of the app. This is useful for apps that control their
+ * own connectivity state and want to bypass any checks to the ConnectivityManager.
+ *
+ * @param connected flag to determine the connectivity state, true for connected, false for
+ * disconnected, null for ConnectivityManager to determine.
+ */
+ public void setConnected(Boolean connected) {
+ // Connectivity state overridden by app
+ this.connected = connected;
+ }
+
+ /**
* Determines whether we have an Internet connection available. Please do not rely on this
* method in your apps, this method is used internally by the SDK.
*
* @return true if there is an Internet connection, false otherwise
*/
- public boolean isConnected() {
+ public Boolean isConnected() {
+ if (connected != null) {
+ // Connectivity state overridden by app
+ return connected;
+ }
+
ConnectivityManager cm = (ConnectivityManager) applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return (activeNetwork != null && activeNetwork.isConnected());
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BaseMarkerViewOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BaseMarkerViewOptions.java
index a5c6397b6f..d4eb390ab2 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BaseMarkerViewOptions.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BaseMarkerViewOptions.java
@@ -126,6 +126,12 @@ public abstract class BaseMarkerViewOptions<U extends MarkerView, T extends Base
*/
public T rotation(float rotation) {
this.rotation = rotation;
+ while (this.rotation > 360) {
+ this.rotation -= 360;
+ }
+ while (this.rotation < 0) {
+ this.rotation += 360;
+ }
return getThis();
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/IconFactory.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/IconFactory.java
index 93c6deddc9..56c1b643a1 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/IconFactory.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/IconFactory.java
@@ -24,11 +24,14 @@ import java.io.InputStream;
/**
* Factory for creating {@link Icon} objects.
+ *
* @see Icon
*/
public final class IconFactory {
private static final String ICON_ID_PREFIX = "com.mapbox.icons.icon_";
+ public static final Bitmap ICON_MARKERVIEW_BITMAP = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8);
+ public static final String ICON_MARKERVIEW_ID = ICON_ID_PREFIX + "marker_view";
private Context mContext;
private static IconFactory sInstance;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerView.java
index b94b24025a..b41eebff09 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerView.java
@@ -1,18 +1,11 @@
package com.mapbox.mapboxsdk.annotations;
-import android.animation.AnimatorSet;
-import android.graphics.Bitmap;
-import android.graphics.PointF;
import android.support.annotation.FloatRange;
-import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
-import android.view.View;
-import android.view.animation.AnimationUtils;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapboxMap;
-import com.mapbox.mapboxsdk.utils.AnimatorUtils;
/**
* MarkerView is an annotation that shows an View at a geographical location.
@@ -231,7 +224,10 @@ public class MarkerView extends Marker {
}
/**
- * Set the rotation value of the MarkerView.
+ * Set the rotation value of the MarkerView in degrees.
+ * <p>
+ * Input will be limited to 0 - 360 degrees
+ * </p>
* <p>
* This will result in animating the rotation of the MarkerView using an rotation animator
* from current value to the provided parameter value.
@@ -240,9 +236,26 @@ public class MarkerView extends Marker {
* @param rotation the rotation value to animate to
*/
public void setRotation(float rotation) {
- this.rotation = rotation;
+ // limit to 0 - 360 degrees
+ float newRotation = rotation;
+ while (newRotation > 360) {
+ newRotation -= 360;
+ }
+ while (newRotation < 0) {
+ newRotation += 360;
+ }
+
+ // calculate new direction
+ float diff = newRotation - this.rotation;
+ if (diff > 180.0f) {
+ diff -= 360.0f;
+ } else if (diff < -180.0f) {
+ diff += 360.f;
+ }
+
+ this.rotation = newRotation;
if (markerViewManager != null) {
- markerViewManager.animateRotation(this, rotation);
+ markerViewManager.animateRotationBy(this, diff);
}
}
@@ -288,10 +301,10 @@ public class MarkerView extends Marker {
@Override
public void setIcon(@Nullable Icon icon) {
if (icon != null) {
- markerViewIcon = IconFactory.recreate("icon", icon.getBitmap());
+ markerViewIcon = IconFactory.recreate(IconFactory.ICON_MARKERVIEW_ID, icon.getBitmap());
}
- Bitmap bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
- Icon transparentIcon = IconFactory.recreate("markerViewSettings", bitmap);
+ Icon transparentIcon = IconFactory.recreate(IconFactory.ICON_MARKERVIEW_ID,
+ IconFactory.ICON_MARKERVIEW_BITMAP);
if (markerViewManager != null) {
markerViewManager.updateIcon(this);
}
@@ -332,19 +345,23 @@ public class MarkerView extends Marker {
* <p>
* This method is used to instantiate the MarkerView and provide an instance of {@link com.mapbox.mapboxsdk.maps.MapboxMap.MarkerViewAdapter}
* </p>
+ * <p>
+ * This method is used to notify that a MarkerView is no longer active by setting a null value.
+ * </p>
*
* @param mapboxMap the MapboxMap instances
*/
@Override
public void setMapboxMap(MapboxMap mapboxMap) {
super.setMapboxMap(mapboxMap);
+ if(mapboxMap!=null) {
+ if (isFlat()) {
+ // initial tilt value if MapboxMap is started with a tilt attribute
+ tiltValue = (float) mapboxMap.getCameraPosition().tilt;
+ }
- if(isFlat()) {
- // initial tilt value if MapboxMap is started with a tilt attribute
- tiltValue = (float) mapboxMap.getCameraPosition().tilt;
+ markerViewManager = mapboxMap.getMarkerViewManager();
}
-
- markerViewManager = mapboxMap.getMarkerViewManager();
}
/**
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java
index 4742c9b66c..ded3130715 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java
@@ -15,7 +15,6 @@ import com.mapbox.mapboxsdk.R;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
-import com.mapbox.mapboxsdk.maps.Projection;
import com.mapbox.mapboxsdk.utils.AnimatorUtils;
import java.util.ArrayList;
@@ -72,6 +71,19 @@ public class MarkerViewManager {
}
/**
+ * Animate a MarkerView with a given rotation.
+ *
+ * @param marker the MarkerView to rotate by
+ * @param rotation the rotation by value
+ */
+ public void animateRotationBy(@NonNull MarkerView marker, float rotation) {
+ View convertView = markerViewMap.get(marker);
+ if (convertView != null) {
+ AnimatorUtils.rotateBy(convertView, rotation);
+ }
+ }
+
+ /**
* Animate a MarkerView to a given alpha value.
* <p>
* The {@link MarkerView} will be transformed from its current alpha value to the given value.
@@ -305,6 +317,7 @@ public class MarkerViewManager {
}
}
}
+ marker.setMapboxMap(null);
markerViewMap.remove(marker);
}
@@ -378,14 +391,15 @@ public class MarkerViewManager {
// remove old markers
Iterator<MarkerView> iterator = markerViewMap.keySet().iterator();
while (iterator.hasNext()) {
- MarkerView m = iterator.next();
- if (!markers.contains(m)) {
+ MarkerView marker = iterator.next();
+ if (!markers.contains(marker)) {
// remove marker
- convertView = markerViewMap.get(m);
+ convertView = markerViewMap.get(marker);
for (MapboxMap.MarkerViewAdapter adapter : markerViewAdapters) {
- if (adapter.getMarkerClass().equals(m.getClass())) {
- adapter.prepareViewForReuse(m, convertView);
+ if (adapter.getMarkerClass().equals(marker.getClass())) {
+ adapter.prepareViewForReuse(marker, convertView);
adapter.releaseView(convertView);
+ marker.setMapboxMap(null);
iterator.remove();
}
}
@@ -397,20 +411,14 @@ public class MarkerViewManager {
if (!markerViewMap.containsKey(marker)) {
for (final MapboxMap.MarkerViewAdapter adapter : markerViewAdapters) {
if (adapter.getMarkerClass().equals(marker.getClass())) {
+
+ // Inflate View
convertView = (View) adapter.getViewReusePool().acquire();
final View adaptedView = adapter.getView(marker, convertView, mapView);
if (adaptedView != null) {
-
- // tilt
adaptedView.setRotationX(marker.getTilt());
-
- // rotation
adaptedView.setRotation(marker.getRotation());
-
- // alpha
adaptedView.setAlpha(marker.getAlpha());
-
- // visible
adaptedView.setVisibility(View.GONE);
if (mapboxMap.getSelectedMarkers().contains(marker)) {
@@ -436,6 +444,7 @@ public class MarkerViewManager {
}
});
+ marker.setMapboxMap(mapboxMap);
markerViewMap.put(marker, adaptedView);
if (convertView == null) {
adaptedView.setVisibility(View.GONE);
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java
index 4253ff23d7..3888abc041 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java
@@ -158,7 +158,7 @@ public final class CameraPosition implements Parcelable {
double lat = typedArray.getFloat(R.styleable.MapView_center_latitude, 0.0f);
double lng = typedArray.getFloat(R.styleable.MapView_center_longitude, 0.0f);
this.target = new LatLng(lat, lng);
- this.tilt = Math.toRadians(typedArray.getFloat(R.styleable.MapView_tilt, 0.0f));
+ this.tilt = typedArray.getFloat(R.styleable.MapView_tilt, 0.0f);
this.zoom = typedArray.getFloat(R.styleable.MapView_zoom, 0.0f);
}
}
@@ -171,10 +171,10 @@ public final class CameraPosition implements Parcelable {
public Builder(CameraUpdateFactory.CameraPositionUpdate update) {
super();
if (update != null) {
- this.bearing = update.getBearing();
- this.target = update.getTarget();
- this.tilt = update.getTilt();
- this.zoom = update.getZoom();
+ bearing = update.getBearing();
+ target = update.getTarget();
+ tilt = update.getTilt();
+ zoom = update.getZoom();
}
}
@@ -192,16 +192,19 @@ public final class CameraPosition implements Parcelable {
/**
* Create Builder from an existing array of doubles.
+ * <p>
+ * These values conform to map.ccp representation of a camera position.
+ * </p>
*
- * @param values Values containing target, bearing, tilt and zoom
+ * @param nativeCameraValues Values containing target, bearing, tilt and zoom
*/
- public Builder(double[] values) {
+ public Builder(double[] nativeCameraValues) {
super();
- if (values != null && values.length == 5) {
- this.target = new LatLng(values[0], values[1]);
- this.bearing = Math.toDegrees(values[2]);
- this.tilt = Math.toRadians(values[3]);
- this.zoom = (float) values[4];
+ if (nativeCameraValues != null && nativeCameraValues.length == 5) {
+ target(new LatLng(nativeCameraValues[0], nativeCameraValues[1]));
+ bearing(nativeCameraValues[2]);
+ tilt(nativeCameraValues[3]);
+ zoom((float) nativeCameraValues[4]);
}
}
@@ -212,7 +215,16 @@ public final class CameraPosition implements Parcelable {
* @return Builder
*/
public Builder bearing(double bearing) {
- this.bearing = bearing;
+ double direction = bearing;
+
+ while (direction >= 360) {
+ direction -= 360;
+ }
+ while (direction < 0) {
+ direction += 360;
+ }
+
+ this.bearing = direction;
return this;
}
@@ -237,13 +249,16 @@ public final class CameraPosition implements Parcelable {
}
/**
- * Set the tilt
+ * Set the tilt in degrees
+ * <p>
+ * value is clamped to 0 and 60.
+ * <p/>
*
* @param tilt Tilt value
* @return Builder
*/
public Builder tilt(double tilt) {
- this.tilt = (float) Math.toRadians(MathUtils.clamp(tilt, MapboxConstants.MINIMUM_TILT, MapboxConstants.MAXIMUM_TILT));
+ this.tilt = (float) MathUtils.clamp(tilt, MapboxConstants.MINIMUM_TILT, MapboxConstants.MAXIMUM_TILT);
return this;
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java
index 73e67270ae..db05486bc2 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java
@@ -185,7 +185,7 @@ public final class CameraUpdateFactory {
CameraPosition previousPosition = mapboxMap.getCameraPosition();
if (target == null) {
return new CameraPosition.Builder()
- .tilt(Math.toDegrees(tilt))
+ .tilt(tilt)
.zoom(zoom)
.bearing(bearing)
.target(previousPosition.target)
@@ -200,16 +200,16 @@ public final class CameraUpdateFactory {
private LatLngBounds bounds;
private RectF padding;
- public CameraBoundsUpdate(LatLngBounds bounds, RectF padding) {
+ CameraBoundsUpdate(LatLngBounds bounds, RectF padding) {
this.bounds = bounds;
this.padding = padding;
}
- public CameraBoundsUpdate(LatLngBounds bounds, int[] padding) {
+ CameraBoundsUpdate(LatLngBounds bounds, int[] padding) {
this(bounds, new RectF(padding[0], padding[1], padding[2], padding[3]));
}
- public CameraBoundsUpdate(LatLngBounds bounds, int paddingLeft, int paddingTop, int paddingRight, int paddingBottom) {
+ CameraBoundsUpdate(LatLngBounds bounds, int paddingLeft, int paddingTop, int paddingRight, int paddingBottom) {
this(bounds, new int[]{paddingLeft, paddingTop, paddingRight, paddingBottom});
}
@@ -283,7 +283,7 @@ public final class CameraUpdateFactory {
private float x;
private float y;
- public CameraMoveUpdate(float x, float y) {
+ CameraMoveUpdate(float x, float y) {
this.x = x;
this.y = y;
}
@@ -302,21 +302,12 @@ public final class CameraUpdateFactory {
LatLng latLng = projection.fromScreenLocation(targetPoint);
CameraPosition previousPosition = mapboxMap.getCameraPosition();
- if (latLng != null) {
- return new CameraPosition.Builder()
- .target(latLng)
- .zoom(previousPosition.zoom)
- .tilt(previousPosition.tilt)
- .bearing(previousPosition.bearing)
- .build();
- } else {
- return new CameraPosition.Builder()
- .tilt(Math.toDegrees(previousPosition.tilt))
- .zoom(previousPosition.zoom)
- .bearing(previousPosition.bearing)
- .target(previousPosition.target)
- .build();
- }
+ return new CameraPosition.Builder()
+ .target(latLng != null ? latLng : previousPosition.target)
+ .zoom(previousPosition.zoom)
+ .tilt(previousPosition.tilt)
+ .bearing(previousPosition.bearing)
+ .build();
}
}
@@ -324,14 +315,14 @@ public final class CameraUpdateFactory {
@IntDef({ZOOM_IN, ZOOM_OUT, ZOOM_BY, ZOOM_TO, ZOOM_TO_POINT})
@Retention(RetentionPolicy.SOURCE)
- public @interface Type {
+ @interface Type {
}
- public static final int ZOOM_IN = 0;
- public static final int ZOOM_OUT = 1;
- public static final int ZOOM_BY = 2;
- public static final int ZOOM_TO = 3;
- public static final int ZOOM_TO_POINT = 4;
+ static final int ZOOM_IN = 0;
+ static final int ZOOM_OUT = 1;
+ static final int ZOOM_BY = 2;
+ static final int ZOOM_TO = 3;
+ static final int ZOOM_TO_POINT = 4;
@Type
private final int type;
@@ -373,7 +364,7 @@ public final class CameraUpdateFactory {
return y;
}
- public double transformZoom(double currentZoom) {
+ double transformZoom(double currentZoom) {
switch (getType()) {
case CameraUpdateFactory.ZoomUpdate.ZOOM_IN:
currentZoom++;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java
index c6259e6e9f..3d0e1e7636 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java
@@ -132,6 +132,8 @@ public class MapView extends FrameLayout {
private MyLocationView myLocationView;
private LocationListener myLocationListener;
+ private Projection projection;
+
private CopyOnWriteArrayList<OnMapChangedListener> onMapChangedListener;
private ZoomButtonsController zoomButtonsController;
private ConnectivityReceiver connectivityReceiver;
@@ -196,6 +198,8 @@ public class MapView extends FrameLayout {
onMapReadyCallbackList = new ArrayList<>();
onMapChangedListener = new CopyOnWriteArrayList<>();
mapboxMap = new MapboxMap(this);
+ projection = mapboxMap.getProjection();
+
icons = new ArrayList<>();
View view = LayoutInflater.from(context).inflate(R.layout.mapview_internal, this);
setWillNotDraw(false);
@@ -212,6 +216,9 @@ public class MapView extends FrameLayout {
nativeMapView = new NativeMapView(this);
+ // load transparent icon for MarkerView to trace actual markers, see #6352
+ loadIcon(IconFactory.recreate(IconFactory.ICON_MARKERVIEW_ID, IconFactory.ICON_MARKERVIEW_BITMAP));
+
// Ensure this view is interactable
setClickable(true);
setLongClickable(true);
@@ -219,7 +226,6 @@ public class MapView extends FrameLayout {
setFocusableInTouchMode(true);
requestFocus();
-
// Touch gesture detectors
gestureDetector = new GestureDetectorCompat(context, new GestureListener());
gestureDetector.setIsLongpressEnabled(true);
@@ -289,10 +295,10 @@ public class MapView extends FrameLayout {
// MyLocationView
MyLocationViewSettings myLocationViewSettings = mapboxMap.getMyLocationViewSettings();
myLocationViewSettings.setForegroundDrawable(
- options.getMyLocationForegroundDrawable(), options.getMyLocationForegroundBearingDrawable());
+ options.getMyLocationForegroundDrawable(), options.getMyLocationForegroundBearingDrawable());
myLocationViewSettings.setForegroundTintColor(options.getMyLocationForegroundTintColor());
myLocationViewSettings.setBackgroundDrawable(
- options.getMyLocationBackgroundDrawable(), options.getMyLocationBackgroundPadding());
+ options.getMyLocationBackgroundDrawable(), options.getMyLocationBackgroundPadding());
myLocationViewSettings.setBackgroundTintColor(options.getMyLocationBackgroundTintColor());
myLocationViewSettings.setAccuracyAlpha(options.getMyLocationAccuracyAlpha());
myLocationViewSettings.setAccuracyTintColor(options.getMyLocationAccuracyTintColor());
@@ -353,7 +359,7 @@ public class MapView extends FrameLayout {
int attributionTintColor = options.getAttributionTintColor();
uiSettings.setAttributionTintColor(attributionTintColor != -1
- ? attributionTintColor : ColorUtils.getPrimaryColor(getContext()));
+ ? attributionTintColor : ColorUtils.getPrimaryColor(getContext()));
}
//
@@ -408,9 +414,9 @@ public class MapView extends FrameLayout {
uiSettings.setCompassEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_COMPASS_ENABLED));
uiSettings.setCompassGravity(savedInstanceState.getInt(MapboxConstants.STATE_COMPASS_GRAVITY));
uiSettings.setCompassMargins(savedInstanceState.getInt(MapboxConstants.STATE_COMPASS_MARGIN_LEFT),
- savedInstanceState.getInt(MapboxConstants.STATE_COMPASS_MARGIN_TOP),
- savedInstanceState.getInt(MapboxConstants.STATE_COMPASS_MARGIN_RIGHT),
- savedInstanceState.getInt(MapboxConstants.STATE_COMPASS_MARGIN_BOTTOM));
+ savedInstanceState.getInt(MapboxConstants.STATE_COMPASS_MARGIN_TOP),
+ savedInstanceState.getInt(MapboxConstants.STATE_COMPASS_MARGIN_RIGHT),
+ savedInstanceState.getInt(MapboxConstants.STATE_COMPASS_MARGIN_BOTTOM));
// Logo
uiSettings.setLogoEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_LOGO_ENABLED));
@@ -441,7 +447,7 @@ public class MapView extends FrameLayout {
TrackingSettings trackingSettings = mapboxMap.getTrackingSettings();
//noinspection ResourceType
trackingSettings.setMyLocationTrackingMode(
- savedInstanceState.getInt(MapboxConstants.STATE_MY_LOCATION_TRACKING_MODE, MyLocationTracking.TRACKING_NONE));
+ savedInstanceState.getInt(MapboxConstants.STATE_MY_LOCATION_TRACKING_MODE, MyLocationTracking.TRACKING_NONE));
//noinspection ResourceType
trackingSettings.setMyBearingTrackingMode(
savedInstanceState.getInt(MapboxConstants.STATE_MY_BEARING_TRACKING_MODE, MyBearingTracking.NONE));
@@ -469,6 +475,8 @@ public class MapView extends FrameLayout {
reloadIcons();
reloadMarkers();
adjustTopOffsetPixels();
+
+ // Notify listeners the map is ready
if (onMapReadyCallbackList.size() > 0) {
Iterator<OnMapReadyCallback> iterator = onMapReadyCallbackList.iterator();
while (iterator.hasNext()) {
@@ -476,8 +484,11 @@ public class MapView extends FrameLayout {
callback.onMapReady(mapboxMap);
iterator.remove();
}
- mapboxMap.getMarkerViewManager().scheduleViewMarkerInvalidation();
}
+
+ // invalidate camera to update overlain views with correct tilt value
+ invalidateCameraPosition();
+
} else if (change == REGION_IS_CHANGING || change == REGION_DID_CHANGE || change == DID_FINISH_LOADING_MAP) {
mapboxMap.getMarkerViewManager().scheduleViewMarkerInvalidation();
@@ -658,6 +669,7 @@ public class MapView extends FrameLayout {
}
void setTilt(Double pitch) {
+ mapboxMap.getMarkerViewManager().setTilt(pitch.floatValue());
myLocationView.setTilt(pitch);
nativeMapView.setPitch(pitch, 0);
}
@@ -969,21 +981,24 @@ public class MapView extends FrameLayout {
// Projection
//
- LatLng fromScreenLocation(@NonNull PointF point) {
+ /*
+ * Internal use only, use Projection#fromScreenLocation instead
+ */
+ LatLng fromNativeScreenLocation(@NonNull PointF point) {
if (destroyed) {
return new LatLng();
}
- point.set(point.x / screenDensity, point.y / screenDensity);
return nativeMapView.latLngForPixel(point);
}
- PointF toScreenLocation(@NonNull LatLng location) {
+ /*
+ * Internal use only, use Projection#toScreenLocation instead.
+ */
+ PointF toNativeScreenLocation(@NonNull LatLng location) {
if (destroyed || location == null) {
return new PointF();
}
- PointF pointF = nativeMapView.pixelForLatLng(location);
- pointF.set(pointF.x * screenDensity, pointF.y * screenDensity);
- return pointF;
+ return nativeMapView.pixelForLatLng(location);
}
//
@@ -1283,6 +1298,12 @@ public class MapView extends FrameLayout {
public void invalidateContentPadding() {
setContentPadding(contentPaddingLeft, contentPaddingTop, contentPaddingRight, contentPaddingBottom);
+
+ if (!mapboxMap.getTrackingSettings().isLocationTrackingDisabled()) {
+ setFocalPoint(new PointF(myLocationView.getCenterX(), myLocationView.getCenterY()));
+ } else {
+ setFocalPoint(null);
+ }
}
double getMetersPerPixelAtLatitude(@FloatRange(from = -180, to = 180) double latitude) {
@@ -1527,6 +1548,7 @@ public class MapView extends FrameLayout {
}
CameraPosition position = new CameraPosition.Builder(nativeMapView.getCameraValues()).build();
myLocationView.setCameraPosition(position);
+ mapboxMap.getMarkerViewManager().setTilt((float) position.tilt);
return position;
}
@@ -1625,7 +1647,7 @@ public class MapView extends FrameLayout {
* @param yCoordinate Original y screen cooridnate at start of gesture
*/
private void trackGestureEvent(@NonNull String gestureId, @NonNull float xCoordinate, @NonNull float yCoordinate) {
- LatLng tapLatLng = fromScreenLocation(new PointF(xCoordinate, yCoordinate));
+ LatLng tapLatLng = projection.fromScreenLocation(new PointF(xCoordinate, yCoordinate));
// NaN and Infinite checks to prevent JSON errors at send to server time
if (Double.isNaN(tapLatLng.getLatitude()) || Double.isNaN(tapLatLng.getLongitude())) {
@@ -1657,7 +1679,7 @@ public class MapView extends FrameLayout {
* @param yCoordinate Orginal y screen coordinate at end of drag
*/
private void trackGestureDragEndEvent(@NonNull float xCoordinate, @NonNull float yCoordinate) {
- LatLng tapLatLng = fromScreenLocation(new PointF(xCoordinate, yCoordinate));
+ LatLng tapLatLng = projection.fromScreenLocation(new PointF(xCoordinate, yCoordinate));
// NaN and Infinite checks to prevent JSON errors at send to server time
if (Double.isNaN(tapLatLng.getLatitude()) || Double.isNaN(tapLatLng.getLongitude())) {
@@ -1728,7 +1750,7 @@ public class MapView extends FrameLayout {
if (twoTap && isTap && !inProgress) {
if (focalPoint != null) {
- zoom(false, focalPoint.x / screenDensity, focalPoint.y / screenDensity);
+ zoom(false, focalPoint.x, focalPoint.y);
} else {
PointF focalPoint = TwoFingerGestureDetector.determineFocalPoint(event);
zoom(false, focalPoint.x, focalPoint.y);
@@ -1874,7 +1896,7 @@ public class MapView extends FrameLayout {
// notify app of map click
MapboxMap.OnMapClickListener listener = mapboxMap.getOnMapClickListener();
if (listener != null) {
- LatLng point = fromScreenLocation(tapPoint);
+ LatLng point = projection.fromScreenLocation(tapPoint);
listener.onMapClick(point);
}
}
@@ -1888,7 +1910,7 @@ public class MapView extends FrameLayout {
public void onLongPress(MotionEvent motionEvent) {
MapboxMap.OnMapLongClickListener listener = mapboxMap.getOnMapLongClickListener();
if (listener != null && !quickZoom) {
- LatLng point = fromScreenLocation(new PointF(motionEvent.getX(), motionEvent.getY()));
+ LatLng point = projection.fromScreenLocation(new PointF(motionEvent.getX(), motionEvent.getY()));
listener.onMapLongClick(point);
}
}
@@ -2490,6 +2512,7 @@ public class MapView extends FrameLayout {
if (mapboxMap.getUiSettings().isZoomControlsEnabled()) {
zoomButtonsController.setVisible(false);
}
+ return true;
default:
// We are not interested in this event
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 a3368b4c78..3ab9900a1a 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
@@ -389,15 +389,16 @@ public class MapboxMap {
*/
@UiThread
public final void moveCamera(CameraUpdate update, MapboxMap.CancelableCallback callback) {
- // dismiss tracking, moving camera is equal to a gesture
-
cameraPosition = update.getCameraPosition(this);
mapView.resetTrackingModesIfRequired(cameraPosition);
mapView.jumpTo(cameraPosition.bearing, cameraPosition.target, cameraPosition.tilt, cameraPosition.zoom);
if (callback != null) {
callback.onFinish();
}
- invalidateCameraPosition();
+
+ if (onCameraChangeListener != null) {
+ onCameraChangeListener.onCameraChange(this.cameraPosition);
+ }
}
/**
@@ -560,8 +561,6 @@ public class MapboxMap {
*/
@UiThread
public final void animateCamera(CameraUpdate update, int durationMs, final MapboxMap.CancelableCallback callback) {
- // dismiss tracking, moving camera is equal to a gesture
-
cameraPosition = update.getCameraPosition(this);
mapView.resetTrackingModesIfRequired(cameraPosition);
mapView.flyTo(cameraPosition.bearing, cameraPosition.target, getDurationNano(durationMs), cameraPosition.tilt,
@@ -602,15 +601,17 @@ public class MapboxMap {
* Invalidates the current camera position by reconstructing it from mbgl
*/
private void invalidateCameraPosition() {
- invalidCameraPosition = false;
+ if(invalidCameraPosition) {
+ invalidCameraPosition = false;
- CameraPosition cameraPosition = mapView.invalidateCameraPosition();
- if (cameraPosition != null) {
- this.cameraPosition = cameraPosition;
- }
+ CameraPosition cameraPosition = mapView.invalidateCameraPosition();
+ if (cameraPosition != null) {
+ this.cameraPosition = cameraPosition;
+ }
- if (onCameraChangeListener != null) {
- onCameraChangeListener.onCameraChange(this.cameraPosition);
+ if (onCameraChangeListener != null) {
+ onCameraChangeListener.onCameraChange(this.cameraPosition);
+ }
}
}
@@ -785,7 +786,6 @@ public class MapboxMap {
//
void setTilt(double tilt) {
- markerViewManager.setTilt((float) tilt);
mapView.setTilt(tilt);
}
@@ -2037,7 +2037,7 @@ public class MapboxMap {
* @return the View that is adapted to the contents of MarkerView
*/
@Nullable
- public abstract View getView(@NonNull U marker, @NonNull View convertView, @NonNull ViewGroup parent);
+ public abstract View getView(@NonNull U marker, @Nullable View convertView, @NonNull ViewGroup parent);
/**
* Called when an MarkerView is removed from the MapView or the View object is going to be reused.
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java
index 17d4a7c657..e06ed38433 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java
@@ -15,10 +15,15 @@ import com.mapbox.mapboxsdk.geometry.VisibleRegion;
*/
public class Projection {
- private MapView mapView;
+ private final MapView mapView;
+ private final float screenDensity;
+ private final PointF screenLocationPoint;
Projection(@NonNull MapView mapView) {
this.mapView = mapView;
+ this.screenLocationPoint = new PointF();
+ this.screenDensity = mapView.getContext() != null ? /* return default if unit test */
+ mapView.getContext().getResources().getDisplayMetrics().density : 1.0f;
}
/**
@@ -45,7 +50,8 @@ public class Projection {
* the given screen point does not intersect the ground plane.
*/
public LatLng fromScreenLocation(PointF point) {
- return mapView.fromScreenLocation(point);
+ screenLocationPoint.set(point.x / screenDensity, point.y / screenDensity);
+ return mapView.fromNativeScreenLocation(screenLocationPoint);
}
/**
@@ -84,7 +90,9 @@ public class Projection {
* @return A Point representing the screen location in screen pixels.
*/
public PointF toScreenLocation(LatLng location) {
- return mapView.toScreenLocation(location);
+ PointF pointF = mapView.toNativeScreenLocation(location);
+ pointF.set(pointF.x * screenDensity, pointF.y * screenDensity);
+ return pointF;
}
/**
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java
index 14e45d7391..45e0c4903e 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java
@@ -36,7 +36,6 @@ import com.mapbox.mapboxsdk.location.LocationListener;
import com.mapbox.mapboxsdk.location.LocationServices;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.Projection;
-import com.mapbox.mapboxsdk.utils.MathUtils;
import java.lang.ref.WeakReference;
@@ -47,16 +46,18 @@ public class MyLocationView extends View {
private MyLocationBehavior myLocationBehavior;
private MapboxMap mapboxMap;
+
private Projection projection;
- private int[] contentPadding = new int[4];
+ private float[] projectedCoordinate = new float[2];
+ private float projectedX;
+ private float projectedY;
+
+ private float contentPaddingX;
+ private float contentPaddingY;
- private Location location;
private LatLng latLng;
- private LatLng interpolatedLocation;
- private LatLng previousLocation;
+ private Location location;
private long locationUpdateTimestamp;
-
- private float gpsDirection;
private float previousDirection;
private float accuracy;
@@ -78,9 +79,6 @@ public class MyLocationView extends View {
private Drawable foregroundBearingDrawable;
private Drawable backgroundDrawable;
- private int foregroundTintColor;
- private int backgroundTintColor;
-
private Rect foregroundBounds;
private Rect backgroundBounds;
@@ -175,7 +173,6 @@ public class MyLocationView extends View {
public final void setForegroundDrawableTint(@ColorInt int color) {
if (color != Color.TRANSPARENT) {
- foregroundTintColor = color;
if (foregroundDrawable != null) {
foregroundDrawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
}
@@ -205,7 +202,6 @@ public class MyLocationView extends View {
public final void setShadowDrawableTint(@ColorInt int color) {
if (color != Color.TRANSPARENT) {
- backgroundTintColor = color;
if (backgroundDrawable == null) {
return;
}
@@ -258,33 +254,36 @@ public class MyLocationView extends View {
}
final PointF pointF = screenLocation;
-
float metersPerPixel = (float) projection.getMetersPerPixelAtLatitude(location.getLatitude());
float accuracyPixels = (Float) accuracyAnimator.getAnimatedValue() / metersPerPixel / 2;
float maxRadius = getWidth() / 2;
accuracyPixels = accuracyPixels <= maxRadius ? accuracyPixels : maxRadius;
- // put matrix in origin
+ // reset
matrix.reset();
+ projectedCoordinate[0] = 0;
+ projectedCoordinate[1] = 0;
- // apply tilt to camera
+ // put camera in position
camera.save();
- camera.rotate(tilt, 0, bearing);
-
- // map camera matrix on our matrix
+ camera.rotate(tilt, 0, 0);
camera.getMatrix(matrix);
- //
if (myBearingTrackingMode != MyBearingTracking.NONE && directionAnimator != null) {
matrix.preRotate((Float) directionAnimator.getAnimatedValue());
}
- // put matrix at location of MyLocationView
- matrix.postTranslate(pointF.x, pointF.y);
+ matrix.preTranslate(0, contentPaddingY);
+ matrix.postTranslate(pointF.x, pointF.y - contentPaddingY);
// concat our matrix on canvas
canvas.concat(matrix);
+ // calculate focal point
+ matrix.mapPoints(projectedCoordinate);
+ projectedX = pointF.x - projectedCoordinate[0];
+ projectedY = pointF.y - projectedCoordinate[1];
+
// restore orientation from camera
camera.restore();
@@ -308,6 +307,9 @@ public class MyLocationView extends View {
public void setTilt(@FloatRange(from = 0, to = 60.0f) double tilt) {
this.tilt = (float) tilt;
+ if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW) {
+ mapboxMap.getUiSettings().setFocalPoint(new PointF(getCenterX(), getCenterY()));
+ }
}
public void setBearing(double bearing) {
@@ -315,7 +317,7 @@ public class MyLocationView extends View {
}
public void setCameraPosition(CameraPosition position) {
- setTilt(MathUtils.clamp(Math.toDegrees(position.tilt), 0.0, 60.0));
+ setTilt(position.tilt);
setBearing(position.bearing);
}
@@ -448,27 +450,29 @@ public class MyLocationView extends View {
compassListener.onPause();
if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW) {
// always face north
- gpsDirection = bearing;
- setCompass(gpsDirection);
+ setCompass(0);
}
}
invalidate();
- update();
}
public void setMyLocationTrackingMode(@MyLocationTracking.Mode int myLocationTrackingMode) {
-
MyLocationBehaviorFactory factory = new MyLocationBehaviorFactory();
myLocationBehavior = factory.getBehavioralModel(myLocationTrackingMode);
- if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW && location != null) {
- // center map directly if we have a location fix
+ if (location != null) {
+ if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW) {
+ // center map directly
+ mapboxMap.easeCamera(CameraUpdateFactory.newLatLng(new LatLng(location)), 0, false /*linear interpolator*/, false /*do not disable tracking*/, null);
+ } else {
+ // do not use interpolated location from tracking mode
+ latLng = null;
+ }
myLocationBehavior.updateLatLng(location);
- mapboxMap.easeCamera(CameraUpdateFactory.newLatLng(new LatLng(location)), 0, false /*linear interpolator*/, false /*do not disable tracking*/, null);
}
+
this.myLocationTrackingMode = myLocationTrackingMode;
invalidate();
- update();
}
private void setCompass(float bearing) {
@@ -495,22 +499,23 @@ public class MyLocationView extends View {
}
public float getCenterX() {
- return (getX() + contentPadding[0] - contentPadding[2] + getMeasuredWidth()) / 2;
+ return (getX() + getMeasuredWidth()) / 2 + contentPaddingX - projectedX;
}
public float getCenterY() {
- return (getY() + contentPadding[1] - contentPadding[3] + getMeasuredHeight()) / 2;
+ return (getY() + getMeasuredHeight()) / 2 + contentPaddingY - projectedY;
}
public void setContentPadding(int[] padding) {
- contentPadding = padding;
+ contentPaddingX = (padding[0] - padding[2]) / 2;
+ contentPaddingY = (padding[1] - padding[3]) / 2;
}
private static class GpsLocationListener implements LocationListener {
private WeakReference<MyLocationView> userLocationView;
- public GpsLocationListener(MyLocationView myLocationView) {
+ GpsLocationListener(MyLocationView myLocationView) {
userLocationView = new WeakReference<>(myLocationView);
}
@@ -541,7 +546,7 @@ public class MyLocationView extends View {
// Compass data
private long compassUpdateNextTimestamp = 0;
- public CompassListener(Context context) {
+ CompassListener(Context context) {
sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
rotationVectorSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
}
@@ -623,7 +628,7 @@ public class MyLocationView extends View {
private class MyLocationBehaviorFactory {
- public MyLocationBehavior getBehavioralModel(@MyLocationTracking.Mode int mode) {
+ MyLocationBehavior getBehavioralModel(@MyLocationTracking.Mode int mode) {
if (mode == MyLocationTracking.TRACKING_NONE) {
return new MyLocationShowBehavior();
} else {
@@ -634,16 +639,18 @@ public class MyLocationView extends View {
private abstract class MyLocationBehavior {
- abstract void updateLatLng(@NonNull Location location);
+ void updateLatLng(@NonNull Location newLocation) {
+ location = newLocation;
+ }
- public void updateLatLng(double lat, double lon) {
+ void updateLatLng(double lat, double lon) {
if (latLng != null) {
latLng.setLatitude(lat);
latLng.setLongitude(lon);
}
}
- protected void updateAccuracy(@NonNull Location location) {
+ void updateAccuracy(@NonNull Location location) {
if (accuracyAnimator != null && accuracyAnimator.isRunning()) {
// use current accuracy as a starting point
accuracy = (Float) accuracyAnimator.getAnimatedValue();
@@ -663,6 +670,7 @@ public class MyLocationView extends View {
@Override
void updateLatLng(@NonNull Location location) {
+ super.updateLatLng(location);
if (latLng == null) {
// first location fix
latLng = new LatLng(location);
@@ -670,46 +678,41 @@ public class MyLocationView extends View {
}
// updateLatLng timestamp
- long previousUpdateTimeStamp = locationUpdateTimestamp;
+ float previousUpdateTimeStamp = locationUpdateTimestamp;
locationUpdateTimestamp = SystemClock.elapsedRealtime();
// calculate animation duration
- long locationUpdateDuration;
+ float animationDuration;
if (previousUpdateTimeStamp == 0) {
- locationUpdateDuration = 0;
+ animationDuration = 0;
} else {
- locationUpdateDuration = locationUpdateTimestamp - previousUpdateTimeStamp;
+ animationDuration = (locationUpdateTimestamp - previousUpdateTimeStamp) * 1.1f /*make animation slightly longer*/;
}
// calculate interpolated location
- previousLocation = latLng;
latLng = new LatLng(location);
- interpolatedLocation = new LatLng((latLng.getLatitude() + previousLocation.getLatitude()) / 2, (latLng.getLongitude() + previousLocation.getLongitude()) / 2);
-
- // build new camera
- CameraPosition.Builder builder = new CameraPosition.Builder().target(interpolatedLocation);
+ CameraPosition.Builder builder = new CameraPosition.Builder().target(latLng);
// add direction
if (myBearingTrackingMode == MyBearingTracking.GPS) {
if (location.hasBearing()) {
builder.bearing(location.getBearing());
}
- gpsDirection = location.getBearing();
- setCompass(gpsDirection);
+ setCompass(0);
}
// accuracy
updateAccuracy(location);
// ease to new camera position with a linear interpolator
- mapboxMap.easeCamera(CameraUpdateFactory.newCameraPosition(builder.build()), (int) locationUpdateDuration, false /*linear interpolator*/, false /*do not disable tracking*/, null);
+ mapboxMap.easeCamera(CameraUpdateFactory.newCameraPosition(builder.build()), (int) animationDuration, false /*linear interpolator*/, false /*do not disable tracking*/, null);
}
@Override
void invalidate() {
int[] mapPadding = mapboxMap.getPadding();
- float x = (getWidth() + mapPadding[0] - mapPadding[2]) / 2 + (contentPadding[0] - contentPadding[2]) / 2;
- float y = (getHeight() - mapPadding[3] + mapPadding[1]) / 2 + (contentPadding[1] - contentPadding[3]) / 2;
+ float x = (getWidth() + mapPadding[0] - mapPadding[2]) / 2 + contentPaddingX;
+ float y = (getHeight() - mapPadding[3] + mapPadding[1]) / 2 + contentPaddingY;
screenLocation = new PointF(x, y);
MyLocationView.this.invalidate();
}
@@ -719,6 +722,7 @@ public class MyLocationView extends View {
@Override
void updateLatLng(@NonNull final Location location) {
+ super.updateLatLng(location);
if (latLng == null) {
// first location update
latLng = new LatLng(location);
@@ -726,13 +730,11 @@ public class MyLocationView extends View {
}
// update LatLng location
- previousLocation = latLng;
- latLng = new LatLng(location);
+ LatLng newLocation = new LatLng(location);
// update LatLng direction
if (myBearingTrackingMode == MyBearingTracking.GPS && location.hasBearing()) {
- gpsDirection = location.getBearing();
- setCompass(gpsDirection);
+ setCompass(location.getBearing() + bearing);
}
// update LatLng accuracy
@@ -741,10 +743,7 @@ public class MyLocationView extends View {
// calculate updateLatLng time + add some extra offset to improve animation
long previousUpdateTimeStamp = locationUpdateTimestamp;
locationUpdateTimestamp = SystemClock.elapsedRealtime();
- long locationUpdateDuration = (long) ((locationUpdateTimestamp - previousUpdateTimeStamp) * 1.3);
-
- // calculate interpolated entity
- interpolatedLocation = new LatLng((latLng.getLatitude() + previousLocation.getLatitude()) / 2, (latLng.getLongitude() + previousLocation.getLongitude()) / 2);
+ long locationUpdateDuration = (long) ((locationUpdateTimestamp - previousUpdateTimeStamp) * 1.2f);
// animate changes
if (locationChangeAnimator != null) {
@@ -753,14 +752,12 @@ public class MyLocationView extends View {
}
locationChangeAnimator = ValueAnimator.ofFloat(0.0f, 1.0f);
- locationChangeAnimator.setDuration((long) (locationUpdateDuration * 1.2));
+ locationChangeAnimator.setDuration(locationUpdateDuration);
locationChangeAnimator.addUpdateListener(new MarkerCoordinateAnimatorListener(this,
- previousLocation, interpolatedLocation
+ latLng, newLocation
));
locationChangeAnimator.start();
-
- // use interpolated location as current location
- latLng = interpolatedLocation;
+ latLng = newLocation;
}
@Override
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/net/ConnectivityReceiver.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/net/ConnectivityReceiver.java
index 823f463030..85695ec6c9 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/net/ConnectivityReceiver.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/net/ConnectivityReceiver.java
@@ -9,6 +9,8 @@ import android.net.NetworkInfo;
import android.support.annotation.NonNull;
import android.util.Log;
+import com.mapbox.mapboxsdk.MapboxAccountManager;
+
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -80,6 +82,12 @@ public class ConnectivityReceiver extends BroadcastReceiver {
* @return true if connected
*/
public boolean isConnected(Context context) {
+ Boolean connected = MapboxAccountManager.getInstance().isConnected();
+ if (connected != null) {
+ // Connectivity state overridden by app
+ return connected;
+ }
+
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return (activeNetwork != null && activeNetwork.isConnected());
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Filter.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Filter.java
index 4d9791b125..6f881e4960 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Filter.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Filter.java
@@ -31,7 +31,7 @@ public class Filter {
/**
* Represents a {@link Filter} statement. Can be unary (eg `has()`, etc) or take any number of values.
*/
- public static class SimpleStatement extends Statement {
+ private static class SimpleStatement extends Statement {
private final String key;
private final Object[] values;
@@ -40,7 +40,7 @@ public class Filter {
* @param key the property key
* @param values the values to operate on, if any
*/
- public SimpleStatement(String operator, String key, Object... values) {
+ SimpleStatement(String operator, String key, Object... values) {
super(operator);
this.key = key;
this.values = values;
@@ -63,14 +63,14 @@ public class Filter {
/**
* Represents a collection of {@link Statement}s with an operator that describes their relationship
*/
- public static class CompoundStatement extends Statement {
+ private static class CompoundStatement extends Statement {
private final Statement[] statements;
/**
* @param operator the relationship operator
* @param statements the statements to compound
*/
- public CompoundStatement(String operator, Statement... statements) {
+ CompoundStatement(String operator, Statement... statements) {
super(operator);
this.statements = statements;
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEventManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEventManager.java
index 67eb51fd8f..7d22292601 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEventManager.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEventManager.java
@@ -634,6 +634,8 @@ public class MapboxEventManager {
return null;
}
+ Response response = null;
+
try {
// Send data
// =========
@@ -742,13 +744,16 @@ public class MapboxEventManager {
.header("User-Agent", userAgent)
.post(body)
.build();
- Response response = client.newCall(request).execute();
+ response = client.newCall(request).execute();
Log.d(TAG, "response code = " + response.code() + " for events " + events.size());
} catch (Exception e) {
Log.e(TAG, "FlushTheEventsTask borked: " + e);
e.printStackTrace();
} finally {
+ if (response != null && response.body() != null) {
+ response.body().close();
+ }
// Reset Events
// ============
events.removeAllElements();
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/AnimatorUtils.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/AnimatorUtils.java
index 495393c258..ab3b841043 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/AnimatorUtils.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/AnimatorUtils.java
@@ -7,6 +7,7 @@ import android.animation.ObjectAnimator;
import android.support.annotation.AnimatorRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.view.View;
public class AnimatorUtils {
@@ -61,6 +62,17 @@ public class AnimatorUtils {
rotateAnimator.start();
}
+ public static void rotateBy(@NonNull final View view, float rotationBy) {
+ view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ view.animate().rotationBy(rotationBy).setInterpolator(new FastOutSlowInInterpolator()).setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ view.setLayerType(View.LAYER_TYPE_NONE, null);
+ }
+ });
+ }
+
public static void alpha(@NonNull final View convertView, float alpha, @Nullable final OnAnimationEndListener listener) {
convertView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
ObjectAnimator rotateAnimator = ObjectAnimator.ofFloat(convertView, View.ALPHA, convertView.getAlpha(), alpha);
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapview_preview.jpg b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapview_preview.jpg
new file mode 100644
index 0000000000..3a21fc08bc
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapview_preview.jpg
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapview_preview.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapview_preview.png
deleted file mode 100644
index 39d8a0c64a..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapview_preview.png
+++ /dev/null
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/build.gradle b/platform/android/MapboxGLAndroidSDKTestApp/build.gradle
index f247b41b24..859740e212 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/build.gradle
+++ b/platform/android/MapboxGLAndroidSDKTestApp/build.gradle
@@ -88,9 +88,9 @@ dependencies {
compile "com.android.support:recyclerview-v7:${supportLibVersion}"
// Leak Canary
- androidTestCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta2'
- debugCompile 'com.squareup.leakcanary:leakcanary-android:1.4-beta2'
- releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta2'
+ debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5'
+ releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
+ testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
// Mapbox Android Services
compile('com.mapbox.mapboxsdk:mapbox-android-services:1.3.0@aar') {
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/gradle.properties b/platform/android/MapboxGLAndroidSDKTestApp/gradle.properties
new file mode 100644
index 0000000000..ef89e27366
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/gradle.properties
@@ -0,0 +1,2 @@
+# allows gradle to use more memory
+org.gradle.jvmargs=-Xmx2048M
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/proguard-rules.pro b/platform/android/MapboxGLAndroidSDKTestApp/proguard-rules.pro
index fbeca9f23b..49c6038041 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/proguard-rules.pro
+++ b/platform/android/MapboxGLAndroidSDKTestApp/proguard-rules.pro
@@ -1,7 +1,5 @@
# Mapbox ProGuard configuration is handled in the SDK
--keep class android.support.** { *; }
--dontwarn com.squareup.**
--dontwarn com.retrofit.**
+-dontwarn android.support.**
-dontwarn java.lang.**
-dontwarn org.codehaus.**
-keep class com.google.**
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
index 834f872e89..164625d3fb 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
@@ -123,6 +123,14 @@
android:value="@string/category_fragment" />
</activity>
<activity
+ android:name=".activity.fragment.MultiMapActivity"
+ android:description="@string/description_multimap"
+ android:label="@string/activity_multimap">
+ <meta-data
+ android:name="@string/category"
+ android:value="@string/category_fragment" />
+ </activity>
+ <activity
android:name=".activity.camera.ManualZoomActivity"
android:description="@string/description_camera_zoom"
android:label="@string/activity_camera_zoom">
@@ -356,7 +364,6 @@
android:name="@string/category"
android:value="@string/category_style" />
</activity>
-
<activity
android:name=".activity.imagegenerator.PrintActivity"
android:description="@string/description_print"
@@ -416,7 +423,6 @@
android:value="@string/category_annotation" />
</activity>
-
<!-- For Unit tests -->
<activity android:name=".activity.style.RuntimeStyleTestActivity" />
<activity android:name=".activity.style.RuntimeStyleTimingTestActivity" />
@@ -435,7 +441,6 @@
<!-- android:value="true" /> -->
<service android:name="com.mapbox.mapboxsdk.telemetry.TelemetryService" />
-
</application>
-</manifest>
+</manifest> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapboxApplication.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapboxApplication.java
index 16329f5d44..5b4c730cfb 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapboxApplication.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapboxApplication.java
@@ -11,12 +11,18 @@ public class MapboxApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
- MapboxAccountManager.start(getApplicationContext(), getString(R.string.mapbox_access_token));
+
+ if (LeakCanary.isInAnalyzerProcess(this)) {
+ // This process is dedicated to LeakCanary for heap analysis.
+ // You should not init your app in this process.
+ return;
+ }
LeakCanary.install(this);
+
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
- .detectNetwork() // or .detectAll() for all detectable problems
+ .detectNetwork()
.penaltyLog()
.build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
@@ -24,5 +30,7 @@ public class MapboxApplication extends Application {
.penaltyLog()
.penaltyDeath()
.build());
+
+ MapboxAccountManager.start(getApplicationContext(), getString(R.string.mapbox_access_token));
}
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/DynamicMarkerChangeActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/DynamicMarkerChangeActivity.java
index 7842542ef1..3c3399168a 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/DynamicMarkerChangeActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/DynamicMarkerChangeActivity.java
@@ -54,8 +54,6 @@ public class DynamicMarkerChangeActivity extends AppCompatActivity {
@Override
public void onMapReady(@NonNull MapboxMap mapboxMap) {
DynamicMarkerChangeActivity.this.mapboxMap = mapboxMap;
- mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(51.506675, -0.128699), 10));
-
// Create marker
MarkerOptions markerOptions = new MarkerOptions()
.position(LAT_LNG_CHELSEA)
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewActivity.java
index ccce727130..fe20b75a8d 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewActivity.java
@@ -41,24 +41,30 @@ import java.util.Random;
public class MarkerViewActivity extends AppCompatActivity {
+ private static final LatLng[] LAT_LNGS = new LatLng[]{
+ new LatLng(38.897424, -77.036508),
+ new LatLng(38.909698, -77.029642),
+ new LatLng(38.907227, -77.036530),
+ new LatLng(38.905607, -77.031916),
+ new LatLng(38.889441, -77.050134),
+ new LatLng(38.888000, -77.050000) //Slight overlap to show re-ordering on selection
+ };
+
private MapboxMap mapboxMap;
private MapView mapView;
+ // MarkerView location updates
private MarkerView movingMarkerOne;
private MarkerView movingMarkerTwo;
private Random randomAnimator = new Random();
private Handler locationUpdateHandler = new Handler();
private Runnable moveMarkerRunnable = new MoveMarkerRunnable();
- private int rotation = 0;
- private static final LatLng[] LAT_LNGS = new LatLng[]{
- new LatLng(38.897424, -77.036508),
- new LatLng(38.909698, -77.029642),
- new LatLng(38.907227, -77.036530),
- new LatLng(38.905607, -77.031916),
- new LatLng(38.889441, -77.050134),
- new LatLng(38.888000, -77.050000) //Slight overlap to show re-ordering on selection
- };
+ // MarkerView rotate updates
+ private MarkerView rotateMarker;
+ private Handler rotateUpdateHandler = new Handler();
+ private Runnable rotateMarkerRunnable = new RotateMarkerRunnable();
+ private int rotation = 360;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -111,10 +117,13 @@ public class MarkerViewActivity extends AppCompatActivity {
.position(new LatLng(38.902580, -77.050102))
);
- MarkerViewActivity.this.mapboxMap.addMarker(new TextMarkerViewOptions()
+ rotateMarker = MarkerViewActivity.this.mapboxMap.addMarker(new TextMarkerViewOptions()
.text("A")
+ .rotation(rotation = 270)
.position(new LatLng(38.889876, -77.008849))
);
+ loopMarkerRotate();
+
MarkerViewActivity.this.mapboxMap.addMarker(new TextMarkerViewOptions()
.text("B")
@@ -137,7 +146,7 @@ public class MarkerViewActivity extends AppCompatActivity {
public void onMapChanged(@MapView.MapChange int change) {
if (change == MapView.REGION_IS_CHANGING || change == MapView.REGION_DID_CHANGE) {
if (!markerViewManager.getMarkerViewAdapters().isEmpty() && viewCountView != null) {
- viewCountView.setText("ViewCache size " + (mapView.getChildCount() - 5));
+ viewCountView.setText("ViewCache size " + mapView.getMarkerViewContainer().getChildCount());
}
}
}
@@ -167,6 +176,10 @@ public class MarkerViewActivity extends AppCompatActivity {
});
}
+ private void loopMarkerRotate() {
+ rotateUpdateHandler.postDelayed(rotateMarkerRunnable, 800);
+ }
+
@Override
protected void onStart() {
super.onStart();
@@ -181,29 +194,52 @@ public class MarkerViewActivity extends AppCompatActivity {
protected void onStop() {
super.onStop();
locationUpdateHandler.removeCallbacks(moveMarkerRunnable);
+ rotateUpdateHandler.removeCallbacks(rotateMarkerRunnable);
}
+ /**
+ * Updates the position of a Marker
+ */
private class MoveMarkerRunnable implements Runnable {
@Override
public void run() {
int i = randomAnimator.nextInt(9);
if (randomAnimator.nextInt() % 2 == 0) {
movingMarkerOne.setPosition(CarLocation.CAR_0_LNGS[i]);
- movingMarkerOne.setRotation(rotation = rotation + 45);
} else {
movingMarkerTwo.setPosition(CarLocation.CAR_1_LNGS[i]);
- movingMarkerTwo.setRotation(rotation = rotation + 90);
}
loopMarkerMove();
}
}
+ /**
+ * Updates the rotation of a Marker
+ */
+ private class RotateMarkerRunnable implements Runnable {
+
+ private final static int ROTATION_INCREASE_VALUE = 9;
+
+ @Override
+ public void run() {
+ rotation -= ROTATION_INCREASE_VALUE;
+ if (rotation >= 0) {
+ rotation += 360;
+ }
+ rotateMarker.setRotation(rotation);
+ loopMarkerRotate();
+ }
+ }
+
+ /**
+ * Adapts a MarkerView to display an abbreviated name in a TextView and a flag in an ImageView.
+ */
private static class CountryAdapter extends MapboxMap.MarkerViewAdapter<CountryMarkerView> {
private LayoutInflater inflater;
private MapboxMap mapboxMap;
- public CountryAdapter(@NonNull Context context, @NonNull MapboxMap mapboxMap) {
+ CountryAdapter(@NonNull Context context, @NonNull MapboxMap mapboxMap) {
super(context);
this.inflater = LayoutInflater.from(context);
this.mapboxMap = mapboxMap;
@@ -229,7 +265,7 @@ public class MarkerViewActivity extends AppCompatActivity {
@Override
public boolean onSelect(
- @NonNull final CountryMarkerView marker, @NonNull final View convertView, boolean reselectionForViewReuse) {
+ @NonNull final CountryMarkerView marker, @NonNull final View convertView, boolean reselectionForViewReuse) {
convertView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
ObjectAnimator rotateAnimator = ObjectAnimator.ofFloat(convertView, View.ROTATION, 0, 360);
rotateAnimator.setDuration(reselectionForViewReuse ? 0 : 350);
@@ -268,13 +304,15 @@ public class MarkerViewActivity extends AppCompatActivity {
}
}
-
+ /**
+ * Adapts a MarkerView to display text in a TextView.
+ */
private static class TextAdapter extends MapboxMap.MarkerViewAdapter<TextMarkerView> {
private LayoutInflater inflater;
private MapboxMap mapboxMap;
- public TextAdapter(@NonNull Context context, @NonNull MapboxMap mapboxMap) {
+ TextAdapter(@NonNull Context context, @NonNull MapboxMap mapboxMap) {
super(context);
this.inflater = LayoutInflater.from(context);
this.mapboxMap = mapboxMap;
@@ -298,7 +336,7 @@ public class MarkerViewActivity extends AppCompatActivity {
@Override
public boolean onSelect(
- @NonNull final TextMarkerView marker, @NonNull final View convertView, boolean reselectionForViewReuse) {
+ @NonNull final TextMarkerView marker, @NonNull final View convertView, boolean reselectionForViewReuse) {
animateGrow(marker, convertView, 0);
// false indicates that we are calling selectMarker after our animation ourselves
@@ -409,7 +447,7 @@ public class MarkerViewActivity extends AppCompatActivity {
private static class CarLocation {
- public static LatLng[] CAR_0_LNGS = new LatLng[]{
+ static LatLng[] CAR_0_LNGS = new LatLng[]{
new LatLng(38.92334425495122, -77.0533673443786),
new LatLng(38.9234737236897, -77.05389484528261),
new LatLng(38.9257094658146, -76.98819752280579),
@@ -421,7 +459,7 @@ public class MarkerViewActivity extends AppCompatActivity {
new LatLng(38.862930274733635, -76.99647808241964)
};
- public static LatLng[] CAR_1_LNGS = new LatLng[]{
+ static LatLng[] CAR_1_LNGS = new LatLng[]{
new LatLng(38.94237975070426, -76.98324549005675),
new LatLng(38.941520236084486, -76.98234257804742),
new LatLng(38.85972219720714, -76.98955808483929),
@@ -432,6 +470,5 @@ public class MarkerViewActivity extends AppCompatActivity {
new LatLng(38.882869724926245, -77.02992539231113),
new LatLng(38.9371988177896, -76.97786740676564)
};
-
}
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/MultiMapActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/MultiMapActivity.java
new file mode 100644
index 0000000000..526f9ae107
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/MultiMapActivity.java
@@ -0,0 +1,15 @@
+package com.mapbox.mapboxsdk.testapp.activity.fragment;
+
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+
+import com.mapbox.mapboxsdk.testapp.R;
+
+public class MultiMapActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_multi_map);
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/OfflineActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/OfflineActivity.java
index d3c66a22ad..e9dd9dc5f4 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/OfflineActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/OfflineActivity.java
@@ -13,8 +13,10 @@ import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;
+import com.mapbox.mapboxsdk.MapboxAccountManager;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
+import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
@@ -73,6 +75,13 @@ public class OfflineActivity extends AppCompatActivity
actionBar.setDisplayShowHomeEnabled(true);
}
+ // You can use MapboxAccountManager.setConnected(Boolean) to manually set the connectivity
+ // state of your app. This will override any checks performed via the ConnectivityManager.
+ //MapboxAccountManager.getInstance().setConnected(false);
+ Boolean connected = MapboxAccountManager.getInstance().isConnected();
+ Log.d(LOG_TAG, String.format(MapboxConstants.MAPBOX_LOCALE,
+ "MapboxAccountManager is connected: %b", connected));
+
// Set up map
mapView = (MapView) findViewById(R.id.mapView);
mapView.setStyleUrl(Style.MAPBOX_STREETS);
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTintActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTintActivity.java
index 937994ccd9..929c2f0b75 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTintActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTintActivity.java
@@ -18,12 +18,14 @@ import android.view.MenuItem;
import android.view.View;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
+import com.mapbox.mapboxsdk.constants.MyLocationTracking;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.location.LocationListener;
import com.mapbox.mapboxsdk.location.LocationServices;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
+import com.mapbox.mapboxsdk.maps.TrackingSettings;
import com.mapbox.mapboxsdk.maps.widgets.MyLocationViewSettings;
import com.mapbox.mapboxsdk.testapp.R;
@@ -55,9 +57,18 @@ public class MyLocationTintActivity extends AppCompatActivity implements Locatio
@Override
public void onMapReady(MapboxMap map) {
mapboxMap = map;
+
+ // enable location updates
toggleGps(!mapboxMap.isMyLocationEnabled());
+ // add some padding
final MyLocationViewSettings myLocationViewSettings = mapboxMap.getMyLocationViewSettings();
+ myLocationViewSettings.setPadding(0, 500, 0, 0);
+
+ // enable tracking
+ TrackingSettings settings = mapboxMap.getTrackingSettings();
+ settings.setDismissLocationTrackingOnGesture(false);
+ settings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW);
// handle default button clicks
ViewUtils.attachClickListener(
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_dynamic_marker.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_dynamic_marker.xml
index 6d9a15af89..1b1dca5327 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_dynamic_marker.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_dynamic_marker.xml
@@ -25,7 +25,12 @@
<com.mapbox.mapboxsdk.maps.MapView
android:id="@id/mapView"
android:layout_width="match_parent"
- android:layout_height="match_parent" />
+ android:layout_height="match_parent"
+ app:center_latitude="51.506675"
+ app:center_longitude="-0.128699"
+ app:direction="90"
+ app:tilt="40"
+ app:zoom="10" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_manual_zoom.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_manual_zoom.xml
index 746b8ffb11..c1f09a36d0 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_manual_zoom.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_manual_zoom.xml
@@ -2,6 +2,7 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
@@ -13,6 +14,10 @@
<com.mapbox.mapboxsdk.maps.MapView
android:id="@id/mapView"
+ app:center_latitude="50.871062"
+ app:center_longitude="1.583210"
+ app:direction="220"
+ app:zoom="10"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/toolbar" />
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_multi_map.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_multi_map.xml
new file mode 100644
index 0000000000..f8046a8821
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_multi_map.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:mapbox="http://schemas.android.com/tools"
+ android:id="@+id/map_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout
+ android:id="@+id/map_container1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="0.5"
+ android:orientation="horizontal">
+
+ <!-- DC -->
+ <fragment
+ android:id="@+id/map1"
+ class="com.mapbox.mapboxsdk.maps.SupportMapFragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="0.5"
+ mapbox:center_latitude="38.913187"
+ mapbox:center_longitude="-77.032546"
+ mapbox:style_url="mapbox://styles/mapbox/streets-v9"
+ mapbox:zoom="12" />
+
+ <!-- SF -->
+ <fragment
+ android:id="@+id/map2"
+ class="com.mapbox.mapboxsdk.maps.SupportMapFragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="0.5"
+ mapbox:center_latitude="37.775732"
+ mapbox:center_longitude="-122.413985"
+ mapbox:style_url="mapbox://styles/mapbox/outdoors-v9"
+ mapbox:zoom="13" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/map_container2"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="0.5"
+ android:orientation="horizontal">
+
+ <!-- Bangalore -->
+ <fragment
+ android:id="@+id/map3"
+ class="com.mapbox.mapboxsdk.maps.SupportMapFragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="0.5"
+ mapbox:center_latitude="12.97913"
+ mapbox:center_longitude="77.59188"
+ mapbox:style_url="mapbox://styles/mapbox/light-v9"
+ mapbox:zoom="14" />
+
+ <!-- Ayacucho -->
+ <fragment
+ android:id="@+id/map4"
+ class="com.mapbox.mapboxsdk.maps.SupportMapFragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="0.5"
+ mapbox:center_latitude="-13.155980"
+ mapbox:center_longitude="-74.217134"
+ mapbox:style_url="mapbox://styles/mapbox/dark-v9"
+ mapbox:zoom="15" />
+ </LinearLayout>
+</LinearLayout> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
index 83160feb5b..855e9a0bef 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
@@ -9,6 +9,7 @@
<!-- Fragment -->
<string name="activity_map_fragment_suport">Support Map Fragment</string>
<string name="activity_map_fragment">Map Fragment</string>
+ <string name="activity_multimap">Multiple Maps on Screen</string>
<!-- Annotations -->
<string name="activity_add_bulk_markers">Add Markers In Bulk</string>
@@ -79,6 +80,7 @@
<string name="description_cameraposition">CameraPosition capabilities</string>
<string name="description_map_fragment">Showcase MapFragment</string>
<string name="description_map_fragment_support">Showcase SupportMapFragment</string>
+ <string name="description_multimap">Activity with multiple maps on screen</string>
<string name="description_press_for_marker">Add marker to map on long press</string>
<string name="description_camera_zoom">Different types of zoom methods</string>
<string name="description_minmax_zoom">Configure a max and min zoomlevel</string>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/MarkerViewTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/MarkerViewTest.java
index e6c30f4aac..6cef1898bd 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/MarkerViewTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/MarkerViewTest.java
@@ -4,18 +4,36 @@ import android.os.Parcelable;
import com.mapbox.mapboxsdk.exceptions.InvalidMarkerPositionException;
import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.utils.MockParcel;
+import org.junit.Before;
import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
public class MarkerViewTest {
+ @Mock
+ MapboxMap mapboxMap;
+
+ @Mock
+ MarkerViewManager markerViewManager;
+
+ @Before
+ public void beforeTest() {
+ MockitoAnnotations.initMocks(this);
+ }
+
@Test
public void testSanity() {
MarkerViewOptions markerOptions = new MarkerViewOptions();
@@ -29,7 +47,7 @@ public class MarkerViewTest {
}
@Test(expected = InvalidMarkerPositionException.class)
- public void testInvalidMarker(){
+ public void testInvalidMarker() {
new MarkerViewOptions().getMarker();
}
@@ -111,6 +129,88 @@ public class MarkerViewTest {
}
@Test
+ public void testRotationAboveMax() {
+ MarkerViewOptions markerOptions = new MarkerViewOptions().rotation(390).position(new LatLng());
+ MarkerView marker = markerOptions.getMarker();
+ assertEquals(marker.getRotation(), 30, 0);
+ }
+
+ @Test
+ public void testRotationBelowMin() {
+ MarkerViewOptions markerOptions = new MarkerViewOptions().rotation(-10).position(new LatLng());
+ MarkerView marker = markerOptions.getMarker();
+ assertEquals(marker.getRotation(), 350, 0);
+ }
+
+ @Test
+ public void testRotationUpdatePositive() {
+ float startRotation = 45;
+ float endRotation = 180;
+ float animationValue = 135;
+
+ // allow calls to our mock
+ when(mapboxMap.getMarkerViewManager()).thenReturn(markerViewManager);
+
+ MarkerViewOptions markerOptions = new MarkerViewOptions().position(new LatLng()).rotation(startRotation);
+ MarkerView marker = markerOptions.getMarker();
+ marker.setMapboxMap(mapboxMap);
+
+ marker.setRotation(endRotation);
+ verify(markerViewManager, times(1)).animateRotationBy(marker, animationValue);
+ }
+
+ @Test
+ public void testRotationUpdateNegative() {
+ float startRotation = 10;
+ float endRotation = 270;
+ float animationValue = -100;
+
+ // allow calls to our mock
+ when(mapboxMap.getMarkerViewManager()).thenReturn(markerViewManager);
+
+ MarkerViewOptions markerOptions = new MarkerViewOptions().position(new LatLng()).rotation(startRotation);
+ MarkerView marker = markerOptions.getMarker();
+ marker.setMapboxMap(mapboxMap);
+
+ marker.setRotation(endRotation);
+ verify(markerViewManager, times(1)).animateRotationBy(marker, animationValue);
+ }
+
+ @Test
+ public void testRotationUpdateMax() {
+ float startRotation = 359;
+ float endRotation = 0;
+ float animationValue = 1;
+
+ // allow calls to our mock
+ when(mapboxMap.getMarkerViewManager()).thenReturn(markerViewManager);
+
+ MarkerViewOptions markerOptions = new MarkerViewOptions().position(new LatLng()).rotation(startRotation);
+ MarkerView marker = markerOptions.getMarker();
+ marker.setMapboxMap(mapboxMap);
+
+ marker.setRotation(endRotation);
+ verify(markerViewManager, times(1)).animateRotationBy(marker, animationValue);
+ }
+
+ @Test
+ public void testRotationUpdateMin() {
+ float startRotation = 0;
+ float endRotation = 359;
+ float animationValue = -1;
+
+ // allow calls to our mock
+ when(mapboxMap.getMarkerViewManager()).thenReturn(markerViewManager);
+
+ MarkerViewOptions markerOptions = new MarkerViewOptions().position(new LatLng()).rotation(startRotation);
+ MarkerView marker = markerOptions.getMarker();
+ marker.setMapboxMap(mapboxMap);
+
+ marker.setRotation(endRotation);
+ verify(markerViewManager, times(1)).animateRotationBy(marker, animationValue);
+ }
+
+ @Test
public void testVisible() {
boolean visible = false;
MarkerViewOptions markerOptions = new MarkerViewOptions().visible(visible).position(new LatLng());
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/camera/CameraPositionTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/camera/CameraPositionTest.java
index c3ae63a692..bce020255e 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/camera/CameraPositionTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/camera/CameraPositionTest.java
@@ -4,9 +4,7 @@ import android.content.res.TypedArray;
import android.os.Parcelable;
import com.mapbox.mapboxsdk.R;
-import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.geometry.LatLng;
-import com.mapbox.mapboxsdk.utils.MathUtils;
import com.mapbox.mapboxsdk.utils.MockParcel;
import org.junit.Test;
@@ -58,7 +56,7 @@ public class CameraPositionTest {
CameraPosition cameraPosition = new CameraPosition.Builder(typedArray).build();
assertEquals("bearing should match", bearing, cameraPosition.bearing, DELTA);
assertEquals("latlng should match", new LatLng(latitude, longitude), cameraPosition.target);
- assertEquals("tilt should match", Math.toRadians(tilt), cameraPosition.tilt, DELTA);
+ assertEquals("tilt should match", tilt, cameraPosition.tilt, DELTA);
assertEquals("zoom should match", zoom, cameraPosition.zoom, DELTA);
}
@@ -72,9 +70,9 @@ public class CameraPositionTest {
double[] cameraVars = new double[]{latitude, longitude, bearing, tilt, zoom};
CameraPosition cameraPosition = new CameraPosition.Builder(cameraVars).build();
- assertEquals("bearing should match", Math.toDegrees(bearing), cameraPosition.bearing, DELTA);
+ assertEquals("bearing should match", bearing, cameraPosition.bearing, DELTA);
assertEquals("latlng should match", new LatLng(latitude, longitude), cameraPosition.target);
- assertEquals("tilt should match", Math.toRadians(tilt), cameraPosition.tilt, DELTA);
+ assertEquals("tilt should match", tilt, cameraPosition.tilt, DELTA);
assertEquals("zoom should match", zoom, cameraPosition.zoom, DELTA);
}
diff --git a/platform/android/MapboxGLAndroidSDKWearTestApp/build.gradle b/platform/android/MapboxGLAndroidSDKWearTestApp/build.gradle
new file mode 100644
index 0000000000..6fbab3a32c
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKWearTestApp/build.gradle
@@ -0,0 +1,56 @@
+apply plugin: 'com.android.application'
+
+task accessToken {
+ def tokenFile = new File("MapboxGLAndroidSDKWearTestApp/src/main/res/values/developer-config.xml")
+ if (!tokenFile.exists()) {
+ String tokenFileContents = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
+ "<resources>\n" +
+ " <string name=\"mapbox_access_token\">" + "$System.env.MAPBOX_ACCESS_TOKEN" + "</string>\n" +
+ "</resources>"
+
+ if (tokenFileContents == null) {
+ throw new InvalidUserDataException("You must set the MAPBOX_ACCESS_TOKEN environment variable.")
+ }
+ tokenFile.write(tokenFileContents)
+ }
+}
+
+gradle.projectsEvaluated {
+ preBuild.dependsOn('accessToken')
+}
+
+android {
+ compileSdkVersion 24
+ buildToolsVersion "24.0.2"
+
+ defaultConfig {
+ applicationId "com.mapbox.mapboxsdk.testapp"
+ minSdkVersion 21
+ targetSdkVersion 24
+ versionCode 1
+ versionName "1.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile(project(':MapboxGLAndroidSDK')) {
+ transitive = true
+ }
+
+ // Leak Canary
+ androidTestCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta2'
+ debugCompile 'com.squareup.leakcanary:leakcanary-android:1.4-beta2'
+ releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta2'
+
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile 'com.google.android.support:wearable:2.0.0-alpha3'
+ provided 'com.google.android.wearable:wearable:2.0.0-alpha3'
+}
+
+apply from: '../checkstyle.gradle' \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKWearTestApp/proguard-rules.pro b/platform/android/MapboxGLAndroidSDKWearTestApp/proguard-rules.pro
new file mode 100644
index 0000000000..362685b172
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKWearTestApp/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/cameron/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/AndroidManifest.xml b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..22c44f9721
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/AndroidManifest.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.mapbox.weartestapp">
+
+ <uses-feature android:name="android.hardware.type.watch"/>
+
+ <uses-permission android:name="android.permission.WAKE_LOCK"/>
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+ <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+ <application
+ android:name=".MapboxApplication"
+ android:allowBackup="true"
+ android:icon="@mipmap/ic_launcher"
+ android:label="@string/app_name"
+ android:supportsRtl="true"
+ android:theme="@android:style/Theme.DeviceDefault">
+ <uses-library
+ android:name="com.google.android.wearable"
+ android:required="false"/>
+
+ <activity
+ android:name="com.mapbox.weartestapp.activity.FeatureOverviewActivity"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
+
+ <activity
+ android:name=".activity.SimpleMapViewActivity"
+ android:label="@string/activity_simple_mapview_title">
+ <meta-data
+ android:name="android.support.PARENT_ACTIVITY"
+ android:value=".activity.FeatureOverviewActivity"/>
+ </activity>
+
+ <service android:name="com.mapbox.mapboxsdk.telemetry.TelemetryService"/>
+
+ </application>
+
+</manifest> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/MapboxApplication.java b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/MapboxApplication.java
new file mode 100644
index 0000000000..390c7370cb
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/MapboxApplication.java
@@ -0,0 +1,28 @@
+package com.mapbox.weartestapp;
+
+import android.app.Application;
+import android.os.StrictMode;
+
+import com.mapbox.mapboxsdk.MapboxAccountManager;
+import com.squareup.leakcanary.LeakCanary;
+
+public class MapboxApplication extends Application {
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ MapboxAccountManager.start(getApplicationContext(), getString(R.string.mapbox_access_token));
+ LeakCanary.install(this);
+ StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
+ .detectDiskReads()
+ .detectDiskWrites()
+ .detectNetwork() // or .detectAll() for all detectable problems
+ .penaltyLog()
+ .build());
+ StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
+ .detectLeakedSqlLiteObjects()
+ .penaltyLog()
+ .penaltyDeath()
+ .build());
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/activity/FeatureOverviewActivity.java b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/activity/FeatureOverviewActivity.java
new file mode 100644
index 0000000000..7f2caa4d67
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/activity/FeatureOverviewActivity.java
@@ -0,0 +1,47 @@
+package com.mapbox.weartestapp.activity;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.wearable.activity.WearableActivity;
+import android.support.wearable.view.WearableRecyclerView;
+
+import com.mapbox.weartestapp.R;
+import com.mapbox.weartestapp.adapter.FeatureAdapter;
+import com.mapbox.weartestapp.model.Feature;
+import com.mapbox.weartestapp.utils.OffsettingHelper;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FeatureOverviewActivity extends WearableActivity implements FeatureAdapter.ItemSelectedListener {
+
+ private static final String TAG = "MainActivity";
+ private WearableRecyclerView wearableRecyclerView;
+ private List<Feature> exampleItemModels;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_feature_overview);
+
+ wearableRecyclerView = (WearableRecyclerView) findViewById(R.id.recycler_launcher_view);
+ wearableRecyclerView.setHasFixedSize(true);
+
+ OffsettingHelper offsettingHelper = new OffsettingHelper();
+
+ wearableRecyclerView.setOffsettingHelper(offsettingHelper);
+
+ exampleItemModels = new ArrayList<>();
+ exampleItemModels.add(new Feature(R.string.activity_simple_mapview_title, new Intent(FeatureOverviewActivity.this, SimpleMapViewActivity.class)));
+
+ FeatureAdapter exampleAdapter = new FeatureAdapter(FeatureOverviewActivity.this, exampleItemModels);
+ wearableRecyclerView.setAdapter(exampleAdapter);
+
+ exampleAdapter.setListener(this);
+ }
+
+ @Override
+ public void onItemSelected(int position) {
+ startActivity(exampleItemModels.get(position).getActivity());
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/activity/SimpleMapViewActivity.java b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/activity/SimpleMapViewActivity.java
new file mode 100644
index 0000000000..d6f3ccd410
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/activity/SimpleMapViewActivity.java
@@ -0,0 +1,60 @@
+package com.mapbox.weartestapp.activity;
+
+import android.os.Bundle;
+import android.support.wearable.activity.WearableActivity;
+
+import com.mapbox.mapboxsdk.maps.MapView;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
+import com.mapbox.weartestapp.R;
+
+public class SimpleMapViewActivity extends WearableActivity {
+
+ private MapView mapView;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_simple_mapview);
+
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(MapboxMap mapboxMap) {
+
+ // Customize map with markers, polylines, etc.
+ }
+ });
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/adapter/FeatureAdapter.java b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/adapter/FeatureAdapter.java
new file mode 100644
index 0000000000..7539a84d6e
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/adapter/FeatureAdapter.java
@@ -0,0 +1,78 @@
+package com.mapbox.weartestapp.adapter;
+
+import android.content.Context;
+import android.support.v7.widget.RecyclerView;
+import android.support.wearable.view.WearableRecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import com.mapbox.weartestapp.R;
+import com.mapbox.weartestapp.model.Feature;
+
+import java.util.List;
+
+public class FeatureAdapter extends WearableRecyclerView.Adapter<FeatureAdapter.ViewHolder> {
+
+ private List<Feature> data;
+ private Context context;
+ private ItemSelectedListener itemSelectedListener;
+
+ public FeatureAdapter(Context context, List<Feature> data) {
+ this.context = context;
+ this.data = data;
+ }
+
+ static class ViewHolder extends RecyclerView.ViewHolder {
+
+ private TextView textView;
+
+ ViewHolder(View view) {
+ super(view);
+ textView = (TextView) view.findViewById(R.id.text_item);
+ }
+
+ void bind(final int position, final ItemSelectedListener listener) {
+
+ itemView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ if (listener != null) {
+ listener.onItemSelected(position);
+ }
+ }
+ });
+ }
+ }
+
+ public void setListener(ItemSelectedListener itemSelectedListener) {
+ this.itemSelectedListener = itemSelectedListener;
+ }
+
+ @Override
+ public FeatureAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ return new ViewHolder(LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.item_curved_layout, parent, false));
+ }
+
+ @Override
+ public void onBindViewHolder(FeatureAdapter.ViewHolder holder, final int position) {
+ if (data != null && !data.isEmpty()) {
+ holder.textView.setText(data.get(position).getTitle());
+ holder.bind(position, itemSelectedListener);
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ if (data != null && !data.isEmpty()) {
+ return data.size();
+ }
+ return 0;
+ }
+
+ public interface ItemSelectedListener {
+ void onItemSelected(int position);
+ }
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/model/Feature.java b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/model/Feature.java
new file mode 100644
index 0000000000..65954ec27e
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/model/Feature.java
@@ -0,0 +1,30 @@
+package com.mapbox.weartestapp.model;
+
+import android.content.Intent;
+
+public class Feature {
+
+ public int title;
+ public Intent activity;
+
+ public int getTitle() {
+ return title;
+ }
+
+ public void setTitle(int title) {
+ this.title = title;
+ }
+
+ public Intent getActivity() {
+ return activity;
+ }
+
+ public void setActivity(Intent activity) {
+ this.activity = activity;
+ }
+
+ public Feature(int title, Intent activity) {
+ this.title = title;
+ this.activity = activity;
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/utils/OffsettingHelper.java b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/utils/OffsettingHelper.java
new file mode 100644
index 0000000000..5b5d512c45
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/utils/OffsettingHelper.java
@@ -0,0 +1,40 @@
+package com.mapbox.weartestapp.utils;
+
+import android.support.wearable.view.DefaultOffsettingHelper;
+import android.support.wearable.view.WearableRecyclerView;
+import android.view.View;
+
+public class OffsettingHelper extends DefaultOffsettingHelper {
+
+ /**
+ * How much should we scale the icon at most.
+ */
+ private static final float MAX_ICON_PROGRESS = 0.65f;
+
+ private float progressToCenter;
+
+ public OffsettingHelper() {
+ }
+
+ @Override
+ public void updateChild(View child, WearableRecyclerView parent) {
+ super.updateChild(child, parent);
+
+ // Figure out % progress from top to bottom
+ float centerOffset = ((float) child.getHeight() / 2.0f) / (float) parent.getHeight();
+ float yRelativeToCenterOffset = (child.getY() / parent.getHeight()) + centerOffset;
+
+ // Normalize for center
+ progressToCenter = Math.abs(0.5f - yRelativeToCenterOffset);
+ // Adjust to the maximum scale
+ progressToCenter = Math.min(progressToCenter, MAX_ICON_PROGRESS);
+
+ child.setScaleX(1 - progressToCenter);
+ child.setScaleY(1 - progressToCenter);
+ }
+
+ @Override
+ protected void adjustAnchorOffsetXY(View child, float[] anchorOffsetXY) {
+ anchorOffsetXY[0] = child.getHeight() / 2.0f;
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/layout/activity_feature_overview.xml b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/layout/activity_feature_overview.xml
new file mode 100644
index 0000000000..07cfcd3c51
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/layout/activity_feature_overview.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<android.support.wearable.view.BoxInsetLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context=".activity.FeatureOverviewActivity"
+ tools:deviceIds="wear">
+
+ <android.support.wearable.view.WearableRecyclerView
+ android:id="@+id/recycler_launcher_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scrollbars="vertical" />
+
+</android.support.wearable.view.BoxInsetLayout> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/layout/activity_simple_mapview.xml b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/layout/activity_simple_mapview.xml
new file mode 100644
index 0000000000..2c1e5fe2eb
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/layout/activity_simple_mapview.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:mapbox="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context=".activity.SimpleMapViewActivity"
+ tools:deviceIds="wear">
+
+ <com.mapbox.mapboxsdk.maps.MapView
+ android:id="@+id/mapView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ mapbox:center_latitude="40.73581"
+ mapbox:center_longitude="-73.99155"
+ mapbox:style_url="mapbox://styles/mapbox/streets-v9"
+ mapbox:zoom="11"
+ mapbox:zoom_controls_enabled="false"/>
+
+</FrameLayout> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/layout/item_curved_layout.xml b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/layout/item_curved_layout.xml
new file mode 100644
index 0000000000..e3a9b476a1
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/layout/item_curved_layout.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/layout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="10dp"
+ android:clickable="true"
+ android:orientation="horizontal">
+
+ <TextView
+ android:id="@+id/text_item"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:textColor="@color/mapboxWhite"
+ android:textSize="14sp"/>
+
+</LinearLayout> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/mipmap-hdpi/ic_launcher.png b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000000..ac2ea61c73
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/mipmap-mdpi/ic_launcher.png b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000000..99eed7146c
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/mipmap-xhdpi/ic_launcher.png b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000000..9b084daf91
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/mipmap-xxhdpi/ic_launcher.png b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000000..6fa714b47d
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/values/colors.xml b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/values/colors.xml
new file mode 100644
index 0000000000..1c40e40e1a
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/values/colors.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <!-- Mapbox colors -->
+ <color name="colorPrimary">@color/mapboxBlue</color>
+ <color name="colorPrimaryDark">@color/mapboxBlueDark</color>
+ <color name="colorAccent">@color/mapboxRed</color>
+
+ <color name="materialGrey">#F5F5F5</color>
+ <color name="materialDarkGrey">#DFDFDF</color>
+
+ <color name="mapboxWhite">#ffffff</color>
+ <color name="mapboxCyan">#3BB2D0</color>
+ <color name="mapboxGreen">#56B881</color>
+ <color name="mapboxBlue">#3887BE</color>
+ <color name="mapboxBlueDark">#1F6EA5</color>
+ <color name="mapboxPurple">#8A8ACB</color>
+ <color name="mapboxPurpleDark">#7171b2</color>
+ <color name="mapboxPurpleLight">#A4A4E5</color>
+
+ <color name="mapboxDenim">#50667F</color>
+ <color name="mapboxTeal">#41AFA5</color>
+ <color name="mapboxOrange">#F9886C</color>
+ <color name="mapboxRed">#E55E5E</color>
+ <color name="mapboxPink">#ED6498</color>
+ <color name="mapboxYellow">#f1f075</color>
+ <color name="mapboxMustard">#FBB03B</color>
+ <color name="mapboxNavy">#28353D</color>
+ <color name="mapboxNavyDark">#222B30</color>
+
+</resources> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/values/strings.xml b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/values/strings.xml
new file mode 100644
index 0000000000..e6a10ad308
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/values/strings.xml
@@ -0,0 +1,6 @@
+<resources>
+ <string name="app_name">MapboxGLAndroidSDKWearTestApp</string>
+
+ <!-- Feature Titles -->
+ <string name="activity_simple_mapview_title">A simple map view</string>
+</resources>
diff --git a/platform/android/bitrise.yml b/platform/android/bitrise.yml
index d477846917..5fe160214b 100644
--- a/platform/android/bitrise.yml
+++ b/platform/android/bitrise.yml
@@ -51,7 +51,7 @@ workflows:
sudo apt-get update && sudo apt-get install google-cloud-sdk
gcloud auth activate-service-account --key-file secret.json --project android-gl-native
gcloud beta test android devices list
- gcloud beta test android run --type instrumentation --app platform/android/MapboxGLAndroidSDKTestApp/build/outputs/apk/MapboxGLAndroidSDKTestApp-debug.apk --test platform/android/MapboxGLAndroidSDKTestApp/build/outputs/apk/MapboxGLAndroidSDKTestApp-debug-androidTest-unaligned.apk --device-ids shamu --os-version-ids 22 --locales en --orientations portrait --timeout 15m
+ gcloud beta test android run --type instrumentation --app platform/android/MapboxGLAndroidSDKTestApp/build/outputs/apk/MapboxGLAndroidSDKTestApp-debug.apk --test platform/android/MapboxGLAndroidSDKTestApp/build/outputs/apk/MapboxGLAndroidSDKTestApp-debug-androidTest-unaligned.apk --device-ids shamu --os-version-ids 22 --locales en --orientations portrait --timeout 15m --test-targets "class com.mapbox.mapboxsdk.camera.RotateTest"
- script:
title: Download test results
is_always_run: true
diff --git a/platform/android/scripts/generate-style-code.js b/platform/android/scripts/generate-style-code.js
index 690ecc3b3c..ca2d2e6778 100644
--- a/platform/android/scripts/generate-style-code.js
+++ b/platform/android/scripts/generate-style-code.js
@@ -265,7 +265,7 @@ fs.writeFileSync(
);
//De-duplicate enum properties before processing jni property templates
-const enumPropertiesDeDup = _(enumProperties).uniq(global.propertyNativeType).value();
+const enumPropertiesDeDup = _(enumProperties).uniqBy(global.propertyNativeType).value();
// JNI Enum property conversion templates
const enumPropertyHppTypeStringValueTemplate = ejs.compile(fs.readFileSync('platform/android/src/style/conversion/types_string_values.hpp.ejs', 'utf8'), {strict: true});
diff --git a/platform/android/scripts/generate-test-code.js b/platform/android/scripts/generate-test-code.js
index 780ec59957..5ec1d0b3bf 100644
--- a/platform/android/scripts/generate-test-code.js
+++ b/platform/android/scripts/generate-test-code.js
@@ -14,7 +14,7 @@ global.camelize = function (str) {
}
-const excludeActivities = ["UpdateMetadataActivity","CarDrivingActivity","MyLocationTrackingModeActivity","MyLocationToggleActivity","MyLocationTintActivity","MyLocationDrawableActivity","DoubleMapActivity", "LocationPickerActivity","GeoJsonClusteringActivity","RuntimeStyleTestActivity", "AnimatedMarkerActivity", "ViewPagerActivity","MapFragmentActivity","SupportMapFragmentActivity","SnapshotActivity","NavigationDrawerActivity", "QueryRenderedFeaturesBoxHighlightActivity"];
+const excludeActivities = ["UpdateMetadataActivity","CarDrivingActivity","MyLocationTrackingModeActivity","MyLocationToggleActivity","MyLocationTintActivity","MyLocationDrawableActivity","DoubleMapActivity", "LocationPickerActivity","GeoJsonClusteringActivity","RuntimeStyleTestActivity", "AnimatedMarkerActivity", "ViewPagerActivity","MapFragmentActivity","SupportMapFragmentActivity","SnapshotActivity","NavigationDrawerActivity", "QueryRenderedFeaturesBoxHighlightActivity", "MultiMapActivity"];
const appBasePath = 'platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity';
const testBasePath = 'platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/activity/gen';
const subPackages = fs.readdirSync(appBasePath);
diff --git a/platform/android/scripts/release.py b/platform/android/scripts/release.py
new file mode 100644
index 0000000000..bc485aa706
--- /dev/null
+++ b/platform/android/scripts/release.py
@@ -0,0 +1,243 @@
+'''
+Utility to schedule SDK builds in Bitrise.
+
+Examples:
+
+- Publish a snapshot from master (release.py uses the current branch)
+
+ $ git branch
+ * master
+ 1234-fix-crash
+ $ python release.py --stage snapshot
+
+- Publish a snapshot from a feature branch (same as before, just switch branchs with git):
+
+ $ git branch
+ master
+ * 1234-fix-crash
+ $ python release.py --stage snapshot
+
+- Publish a beta from a pre-release branch:
+
+ $ git branch
+ master
+ * release-android-420-beta1
+ $ python release.py --stage beta --version 4.2.0-beta.1
+
+- Publish a beta from a release branch:
+
+ $ git branch
+ master
+ * release-android-420
+ $ python release.py --stage final --version 4.2.0
+
+TODO:
+
+- Add a flag to wait until the release has been built (Bitrise) and published (Maven).
+
+'''
+
+import click
+import json
+import os
+import requests
+import subprocess
+
+# Three stages, from less stable to more stable
+ALLOWED_STAGES = ['snapshot', 'beta', 'final']
+
+# Get the version from GRADLE_PROPERTIES_PATH below
+CURRENT_VERSION_TAG = 'current'
+
+# You can find the API token in https://www.bitrise.io/app/79cdcbdc42de4303#/code -> API token
+BITRISE_API_TOKEN_ENV_VAR = 'BITRISE_API_TOKEN'
+
+# In the future we might want to consider alpha, or rc.
+ALLOWED_PRE_RELEASE = ['beta']
+
+# We get the default version from here
+MAPBOX_GL_ANDROID_SDK_PATH = '../MapboxGLAndroidSDK'
+GRADLE_PROPERTIES_PATH = '%s/gradle.properties' % MAPBOX_GL_ANDROID_SDK_PATH
+GRADLE_TOKEN = 'VERSION_NAME='
+FABRIC_PROPERTIES_PATH = '%s/src/main/resources/fabric/com.mapbox.mapboxsdk.mapbox-android-sdk.properties' % MAPBOX_GL_ANDROID_SDK_PATH
+FABRIC_TOKEN = 'fabric-version='
+
+# Bitrise
+URL_BITRISE = 'https://www.bitrise.io/app/79cdcbdc42de4303/build/start.json'
+
+# We support three parameters: stage, branch, and version
+@click.command()
+@click.option('--stage', default=ALLOWED_STAGES[0], type=click.Choice(ALLOWED_STAGES), prompt='Set stage', help='The release stage.')
+@click.option('--version', default=CURRENT_VERSION_TAG, prompt='Set version', help='The version you want to publish. E.g: 4.2.0-SNAPSHOT, 4.2.0-beta.1, or 4.2.0. If you set the version to "%s", the script will default to the current SNAPSHOT version.' % CURRENT_VERSION_TAG)
+def release(stage, version):
+ # Validate params
+ final_stage = validate_stage(stage=stage)
+ final_branch = validate_branch(stage=final_stage)
+ final_version = validate_version(stage=final_stage, branch=final_branch, version=version)
+
+ # Get user confirmation
+ click.echo('\n===== Build information =====')
+ click.echo('- Stage: %s' % final_stage)
+ click.echo('- Branch: %s' % final_branch)
+ click.echo('- Version: %s' % final_version)
+ click.confirm('\nDoes it look right?', abort=True)
+
+ # Proceed
+ if (final_stage == 'snapshot'):
+ publish_snapshot(branch=final_branch, version=final_version)
+ elif (final_stage == 'beta'):
+ publish_beta(branch=final_branch, version=final_version)
+ elif (final_stage == 'final'):
+ publish_final(branch=final_branch, version=final_version)
+
+def validate_stage(stage):
+ if stage not in ALLOWED_STAGES:
+ abort_with_message('Invalid stage: %s' % stage)
+ return stage
+
+def validate_branch(stage):
+ branch = git_get_current_branch()
+ if not branch:
+ abort_with_message('The current folder is not a git repository.')
+ if branch == 'master' and stage != 'snapshot':
+ abort_with_message('You need to swtich to a release branch for a beta or a final release.')
+ return branch
+
+def validate_version(stage, branch, version):
+ if stage == 'snapshot' and branch == 'master' and version != CURRENT_VERSION_TAG:
+ abort_with_message('You cannot specify a custom version if you are building a snapshot from master.')
+
+ if not version or version == CURRENT_VERSION_TAG:
+ version = get_current_version(file_path=GRADLE_PROPERTIES_PATH, file_var=GRADLE_TOKEN)
+
+ if stage == 'snapshot':
+ if not 'SNAPSHOT' in version:
+ abort_with_message('Version should contain the word SNAPSHOT: %s' % version)
+ elif stage == 'beta':
+ if not ALLOWED_PRE_RELEASE[0] in version:
+ abort_with_message('Version should contain the word %s: %s' % (ALLOWED_PRE_RELEASE[0], version))
+ elif stage == 'final':
+ if not version or 'SNAPSHOT' in version or ALLOWED_PRE_RELEASE[0] in version:
+ abort_with_message('Version cannot be empty, or contain the words SNAPSHOT or %s: %s' % (ALLOWED_PRE_RELEASE[0], version))
+
+ return version
+
+def publish_snapshot(branch, version):
+ click.echo('Publishing snapshot for branch: %s (version: %s).' % (branch, version))
+ if branch != 'master':
+ dirty_gradle = update_current_version(file_path=GRADLE_PROPERTIES_PATH, file_var=GRADLE_TOKEN, version=version)
+ if dirty_gradle:
+ git_add(path=GRADLE_PROPERTIES_PATH)
+ git_commit_and_push(branch=branch, version=version)
+ do_bitrise_request(build_params={'branch': branch, 'workflow_id': 'scheduled'})
+
+def publish_beta(branch, version):
+ click.echo('Publishing beta from branch: %s (version: %s).' % (branch, version))
+ dirty_gradle = update_current_version(file_path=GRADLE_PROPERTIES_PATH, file_var=GRADLE_TOKEN, version=version)
+ if dirty_gradle:
+ git_add(path=GRADLE_PROPERTIES_PATH)
+ git_commit_and_push(branch=branch, version=version)
+ do_bitrise_request(build_params={'branch': branch, 'workflow_id': 'scheduled'})
+
+def publish_final(branch, version):
+ click.echo('Publishing final release from branch: %s (version: %s).' % (branch, version))
+ dirty_gradle = update_current_version(file_path=GRADLE_PROPERTIES_PATH, file_var=GRADLE_TOKEN, version=version)
+ if dirty_gradle:
+ git_add(path=GRADLE_PROPERTIES_PATH)
+ dirty_fabric = update_current_version(file_path=FABRIC_PROPERTIES_PATH, file_var=FABRIC_TOKEN, version=version)
+ if dirty_fabric:
+ git_add(path=FABRIC_PROPERTIES_PATH)
+ if dirty_gradle or dirty_fabric:
+ git_commit_and_push(branch=branch, version=version)
+ do_bitrise_request(build_params={'branch': branch, 'workflow_id': 'scheduled'})
+
+#
+# Utils
+#
+
+def abort_with_message(message):
+ click.echo(message)
+ click.get_current_context().abort()
+
+def execute_call(command):
+ click.echo('Executing: %s' % command)
+ result = subprocess.call(command.split(' '))
+ if result != 0:
+ abort_with_message('Command failed: %s' % command)
+
+#
+# Bitrise
+#
+
+def get_bitrise_api_token():
+ bitrise_api_token = os.environ.get(BITRISE_API_TOKEN_ENV_VAR)
+ if not bitrise_api_token:
+ abort_with_message('You need to set the BITRISE_API_TOKEN environment variable.')
+ click.echo('Found Bitrise API token.')
+ return bitrise_api_token
+
+def do_bitrise_request(build_params):
+ data = {
+ 'hook_info': {'type': 'bitrise', 'api_token': get_bitrise_api_token()},
+ 'build_params' : build_params}
+ click.echo('Bitrise request data: %s' % json.dumps(data))
+ click.confirm('\nDo you want to start a build?', abort=True)
+
+ r = requests.post(URL_BITRISE, data=json.dumps(data))
+ click.echo('- Bitrise response code: %s' % r.status_code)
+ click.echo('- Bitrise response content: %s' % r.text)
+
+#
+# Git
+#
+
+def git_get_current_branch():
+ return subprocess.check_output('git symbolic-ref --short HEAD'.split(' ')).strip()
+
+def git_add(path):
+ execute_call(command='git add %s' % path)
+
+def git_commit_and_push(branch, version):
+ message = '[android] [auto] Update properties to version %s in preparation for build.' % version
+ commands = [
+ 'git commit -m "%s"' % message,
+ 'git push -u origin %s' % branch]
+ for command in commands:
+ execute_call(command=command)
+
+#
+# Read and update properties files
+#
+
+def get_current_version(file_path, file_var):
+ click.echo('Getting current version from %s.' % file_path)
+ with open(file_path, 'r') as f:
+ for line in f:
+ if line.startswith(file_var):
+ version_name = line[len(file_var):].strip()
+ click.echo('Current version is %s.' % version_name)
+ return version_name
+ return None
+
+def update_current_version(file_path, file_var, version):
+ dirty = False
+ click.echo('Updating file to version %s: %s.' % (version, file_path))
+ with open(file_path, 'r') as f:
+ file_lines = f.readlines()
+ for line_number in range(len(file_lines)):
+ if file_lines[line_number].startswith(file_var):
+ content_old = file_lines[line_number]
+ content_new = '%s%s\n' % (file_var, version)
+ if (content_old != content_new):
+ click.echo('%s -> %s' % (content_old.strip(), content_new.strip()))
+ file_lines[line_number] = content_new
+ dirty = True
+ if dirty:
+ with open(file_path, 'w') as f:
+ f.writelines(file_lines)
+ else:
+ click.echo('File already has the right version.')
+ return dirty
+
+if __name__ == '__main__':
+ release()
diff --git a/platform/android/settings.gradle b/platform/android/settings.gradle
index 71a8f1a9ad..9be29f4bd4 100644
--- a/platform/android/settings.gradle
+++ b/platform/android/settings.gradle
@@ -1,2 +1,3 @@
include ':MapboxGLAndroidSDK'
include ':MapboxGLAndroidSDKTestApp'
+include ':MapboxGLAndroidSDKWearTestApp'
diff --git a/platform/android/src/jni.cpp b/platform/android/src/jni.cpp
index bea615f615..19981c0ea7 100755
--- a/platform/android/src/jni.cpp
+++ b/platform/android/src/jni.cpp
@@ -244,13 +244,12 @@ jni::jobject* std_vector_string_to_jobject(JNIEnv *env, std::vector<std::string>
return jlist;
}
-jni::jarray<jlong>* std_vector_uint_to_jobject(JNIEnv *env, std::vector<uint32_t> vector) {
+jni::jarray<jlong>* std_vector_uint_to_jobject(JNIEnv *env, const std::vector<uint32_t>& vector) {
jni::jarray<jlong>& jarray = jni::NewArray<jlong>(*env, vector.size());
std::vector<jlong> v;
- for (const uint32_t& id : vector) {
- v.push_back(id);
- }
+ v.reserve(vector.size());
+ std::move(vector.begin(), vector.end(), std::back_inserter(v));
jni::SetArrayRegion(*env, jarray, 0, v);
@@ -513,7 +512,7 @@ jdoubleArray nativeGetCameraValues(JNIEnv *env, jni::jobject* obj, jlong nativeM
jdouble buf[5];
buf[0] = latLng.latitude;
buf[1] = latLng.longitude;
- buf[2] = nativeMapView->getMap().getBearing();
+ buf[2] = -(nativeMapView->getMap().getBearing()-360);
buf[3] = nativeMapView->getMap().getPitch();
buf[4] = nativeMapView->getMap().getZoom();
env->SetDoubleArrayRegion(output, start, leng, buf);
@@ -684,7 +683,7 @@ jni::jarray<jlong>* nativeAddMarkers(JNIEnv *env, jni::jobject* obj, jlong nativ
NullCheck(*env, jarray);
std::size_t len = jni::GetArrayLength(*env, *jarray);
- std::vector<mbgl::AnnotationID> ids;
+ mbgl::AnnotationIDs ids;
ids.reserve(len);
for (std::size_t i = 0; i < len; i++) {
@@ -755,7 +754,7 @@ jni::jarray<jlong>* nativeAddPolylines(JNIEnv *env, jni::jobject* obj, jlong nat
NullCheck(*env, jarray);
std::size_t len = jni::GetArrayLength(*env, *jarray);
- std::vector<mbgl::AnnotationID> ids;
+ mbgl::AnnotationIDs ids;
ids.reserve(len);
for (std::size_t i = 0; i < len; i++) {
@@ -782,7 +781,7 @@ jni::jarray<jlong>* nativeAddPolygons(JNIEnv *env, jni::jobject* obj, jlong nati
NullCheck(*env, jarray);
std::size_t len = jni::GetArrayLength(*env, *jarray);
- std::vector<mbgl::AnnotationID> ids;
+ mbgl::AnnotationIDs ids;
ids.reserve(len);
for (std::size_t i = 0; i < len; i++) {
@@ -860,10 +859,9 @@ jni::jarray<jlong>* nativeQueryPointAnnotations(JNIEnv *env, jni::jobject* obj,
};
// Assume only points for now
- std::vector<uint32_t> annotations = nativeMapView->getMap().queryPointAnnotations(
- box);
+ mbgl::AnnotationIDs ids = nativeMapView->getMap().queryPointAnnotations(box);
- return std_vector_uint_to_jobject(env, annotations);
+ return std_vector_uint_to_jobject(env, ids);
}
void nativeAddAnnotationIcon(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr,
@@ -1059,12 +1057,12 @@ void nativeJumpTo(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdoubl
mbgl::CameraOptions options;
if (angle != -1) {
- options.angle = angle;
+ options.angle = angle * M_PI / 180;
}
options.center = mbgl::LatLng(latitude, longitude);
options.padding = nativeMapView->getInsets();
if (pitch != -1) {
- options.pitch = pitch;
+ options.pitch = pitch * M_PI / 180;
}
if (zoom != -1) {
options.zoom = zoom;
@@ -1079,12 +1077,12 @@ void nativeEaseTo(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdoubl
mbgl::CameraOptions cameraOptions;
if (angle != -1) {
- cameraOptions.angle = angle;
+ cameraOptions.angle = angle * M_PI / 180;
}
cameraOptions.center = mbgl::LatLng(latitude, longitude);
cameraOptions.padding = nativeMapView->getInsets();
if (pitch != -1) {
- cameraOptions.pitch = pitch;
+ cameraOptions.pitch = pitch * M_PI / 180;
}
if (zoom != -1) {
cameraOptions.zoom = zoom;
@@ -1112,12 +1110,12 @@ void nativeFlyTo(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble
mbgl::CameraOptions cameraOptions;
if (angle != -1) {
- cameraOptions.angle = angle;
+ cameraOptions.angle = angle * M_PI / 180 ;
}
cameraOptions.center = mbgl::LatLng(latitude, longitude);
cameraOptions.padding = nativeMapView->getInsets();
if (pitch != -1) {
- cameraOptions.pitch = pitch;
+ cameraOptions.pitch = pitch * M_PI / 180;
}
if (zoom != -1) {
cameraOptions.zoom = zoom;
diff --git a/platform/android/src/style/android_conversion.hpp b/platform/android/src/style/android_conversion.hpp
index 46ee768348..cea7ce6d2a 100644
--- a/platform/android/src/style/android_conversion.hpp
+++ b/platform/android/src/style/android_conversion.hpp
@@ -75,7 +75,9 @@ inline optional<std::string> toString(const mbgl::android::Value& value) {
}
inline optional<Value> toValue(const mbgl::android::Value& value) {
- if (value.isBool()) {
+ if (value.isNull()) {
+ return {};
+ } else if (value.isBool()) {
return { value.toBool() };
} else if (value.isString()) {
return { value.toString() };
diff --git a/platform/android/src/style/value.cpp b/platform/android/src/style/value.cpp
index daad3e998d..c8aad1682b 100644
--- a/platform/android/src/style/value.cpp
+++ b/platform/android/src/style/value.cpp
@@ -5,61 +5,76 @@
namespace mbgl {
namespace android {
+ class ObjectDeleter {
+ public:
+ ObjectDeleter() = default;
+ ObjectDeleter(JNIEnv& e) : env(e) {}
+
+ void operator()(jni::jobject* p) const {
+ if (p) {
+ jni::DeleteLocalRef(env, p);
+ }
+ }
+
+ private:
+ JNIEnv& env;
+ };
+
//Instance
- Value::Value(jni::JNIEnv& env, jni::jobject* _value) : jenv(env), value(_value) {}
+ Value::Value(jni::JNIEnv& env, jni::jobject* _value) : jenv(env), value(_value, ObjectDeleter(env)) {}
- Value::~Value() {}
+ Value::~Value() = default;
bool Value::isNull() const {
return value == nullptr;
}
bool Value::isArray() const {
- return jni::IsInstanceOf(jenv, value, *java::ObjectArray::jclass);
+ return jni::IsInstanceOf(jenv, value.get(), *java::ObjectArray::jclass);
}
bool Value::isObject() const {
- return jni::IsInstanceOf(jenv, value, *java::Map::jclass);;
+ return jni::IsInstanceOf(jenv, value.get(), *java::Map::jclass);;
}
bool Value::isString() const {
- return jni::IsInstanceOf(jenv, value, *java::String::jclass);
+ return jni::IsInstanceOf(jenv, value.get(), *java::String::jclass);
}
bool Value::isBool() const {
- return jni::IsInstanceOf(jenv, value, *java::Boolean::jclass);
+ return jni::IsInstanceOf(jenv, value.get(), *java::Boolean::jclass);
}
bool Value::isNumber() const {
- return jni::IsInstanceOf(jenv, value, *java::Number::jclass);
+ return jni::IsInstanceOf(jenv, value.get(), *java::Number::jclass);
}
std::string Value::toString() const {
- jni::jstring* string = reinterpret_cast<jni::jstring*>(value);
+ jni::jstring* string = reinterpret_cast<jni::jstring*>(value.get());
return jni::Make<std::string>(jenv, jni::String(string));
}
float Value::toNumber() const {
- return jni::CallMethod<jni::jfloat>(jenv, value, *java::Number::floatValueMethodId);
+ return jni::CallMethod<jni::jfloat>(jenv, value.get(), *java::Number::floatValueMethodId);
}
bool Value::toBool() const {
- return jni::CallMethod<jni::jboolean>(jenv, value, *java::Boolean::booleanValueMethodId);
+ return jni::CallMethod<jni::jboolean>(jenv, value.get(), *java::Boolean::booleanValueMethodId);
}
Value Value::get(const char* key) const {
- jni::jobject* member = jni::CallMethod<jni::jobject*>(jenv, value, *java::Map::getMethodId, jni::Make<jni::String>(jenv, std::string(key)).Get());
+ jni::jobject* member = jni::CallMethod<jni::jobject*>(jenv, value.get(), *java::Map::getMethodId, jni::Make<jni::String>(jenv, std::string(key)).Get());
return Value(jenv, member);
}
int Value::getLength() const {
- auto array = (jni::jarray<jni::jobject>*) value;
+ auto array = (jni::jarray<jni::jobject>*) value.get();
return jni::GetArrayLength(jenv, *array);
}
Value Value::get(const int index ) const {
- auto array = (jni::jarray<jni::jobject>*) value;
+ auto array = (jni::jarray<jni::jobject>*) value.get();
return Value(jenv, jni::GetObjectArrayElement(jenv, *array, index));
}
}
diff --git a/platform/android/src/style/value.hpp b/platform/android/src/style/value.hpp
index 2f0b1d9706..461fc1a033 100644
--- a/platform/android/src/style/value.hpp
+++ b/platform/android/src/style/value.hpp
@@ -7,7 +7,7 @@
namespace mbgl {
namespace android {
-class Value {
+class Value {
public:
Value(jni::JNIEnv&, jni::jobject*);
@@ -27,8 +27,10 @@ public:
int getLength() const;
Value get(const int index ) const;
+private:
+
jni::JNIEnv& jenv;
- jni::jobject* value;
+ std::shared_ptr<jni::jobject> value;
};
}
diff --git a/platform/darwin/scripts/generate-style-code.js b/platform/darwin/scripts/generate-style-code.js
index a801145dec..4bcfe54d32 100644
--- a/platform/darwin/scripts/generate-style-code.js
+++ b/platform/darwin/scripts/generate-style-code.js
@@ -25,7 +25,7 @@ global.objCName = function (property) {
}
global.objCType = function (layerType, propertyName) {
- return `${prefix}${camelize(layerType)}${suffix}${camelize(propertyName)}`;
+ return `${prefix}${camelize(propertyName)}`;
}
global.arrayType = function (property) {
@@ -44,7 +44,8 @@ global.testGetterImplementation = function (property, layerType, isFunction) {
if (isFunction) {
return `XCTAssertEqualObjects(gLayer.${objCName(property)}, ${value});`;
}
- return `XCTAssert([(NSValue *)gLayer.${objCName(property)} isEqualToValue:${value}], @"%@ is not equal to %@", gLayer.${objCName(property)}, ${value});`;
+ return `XCTAssert([gLayer.${objCName(property)} isKindOfClass:[MGLStyleConstantValue class]]);
+ XCTAssertEqualObjects(gLayer.${objCName(property)}, ${value});`;
}
return `XCTAssertEqualObjects(gLayer.${objCName(property)}, ${value});`;
}
@@ -129,7 +130,7 @@ global.propertyReqs = function (property, layoutPropertiesByName, type) {
return '`' + camelizeWithLeadingLowercase(req['!']) + '` is set to `nil`';
} else {
let name = Object.keys(req)[0];
- return '`' + camelizeWithLeadingLowercase(name) + '` is set to ' + describeValue(req[name], layoutPropertiesByName[name], type);
+ return '`' + camelizeWithLeadingLowercase(name) + '` is set to an `MGLStyleValue` object containing ' + describeValue(req[name], layoutPropertiesByName[name], type);
}
}).join(', and ') + '. Otherwise, it is ignored.';
};
@@ -204,117 +205,93 @@ global.describeValue = function (value, property, layerType) {
};
global.propertyDefault = function (property, layerType) {
- return describeValue(property.default, property, layerType);
+ return 'an `MGLStyleValue` object containing ' + describeValue(property.default, property, layerType);
};
-global.propertyType = function (property, _private) {
- return _private ? `id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>` : `id <MGLStyleAttributeValue>`;
-};
-
-global.initLayerIdentifierOnly = function (layerType) {
- return `_layer = new mbgl::style::${camelize(layerType)}Layer(layerIdentifier.UTF8String);`
-}
-
-global.initLayer = function (layerType) {
- if (layerType == "background") {
- return `_layer = new mbgl::style::${camelize(layerType)}Layer(layerIdentifier.UTF8String);`
- } else {
- return `_layer = new mbgl::style::${camelize(layerType)}Layer(layerIdentifier.UTF8String, source.sourceIdentifier.UTF8String);`
- }
-}
-
-global.initLayerWithSourceLayer = function(layerType) {
- return `_layer = new mbgl::style::${camelize(layerType)}Layer(layerIdentifier.UTF8String, source.sourceIdentifier.UTF8String);`
-}
-
-global.setSourceLayer = function() {
- return `_layer->setSourceLayer(sourceLayer.UTF8String);`
-}
-
-global.setterImplementation = function(property, layerType) {
- let implementation = '';
+global.propertyType = function (property) {
switch (property.type) {
case 'boolean':
- implementation = `self.layer->set${camelize(property.name)}(${objCName(property)}.mbgl_boolPropertyValue);`;
- break;
+ return 'NSNumber *';
case 'number':
- implementation = `self.layer->set${camelize(property.name)}(${objCName(property)}.mbgl_floatPropertyValue);`;
- break;
+ return 'NSNumber *';
case 'string':
- implementation = `self.layer->set${camelize(property.name)}(${objCName(property)}.mbgl_stringPropertyValue);`;
- break;
+ return 'NSString *';
case 'enum':
- let objCType = global.objCType(layerType, property.name);
- implementation = `MGLSetEnumProperty(${objCName(property)}, ${camelize(property.name)}, ${mbglType(property)}, ${objCType});`;
- break;
+ return 'NSValue *';
case 'color':
- implementation = `self.layer->set${camelize(property.name)}(${objCName(property)}.mbgl_colorPropertyValue);`;
- break;
+ return 'MGLColor *';
case 'array':
- implementation = arraySetterImplementation(property);
- break;
- default: throw new Error(`unknown type for ${property.name}`)
- }
- return implementation;
-}
-
-global.mbglType = function(property) {
- let mbglType = camelize(property.name) + 'Type';
- if (/-translate-anchor$/.test(property.name)) {
- mbglType = 'TranslateAnchorType';
- }
- if (/-(rotation|pitch)-alignment$/.test(property.name)) {
- mbglType = 'AlignmentType';
+ switch (arrayType(property)) {
+ case 'dasharray':
+ return 'NSArray<NSNumber *> *';
+ case 'font':
+ return 'NSArray<NSString *> *';
+ case 'padding':
+ return 'NSValue *';
+ case 'offset':
+ case 'translate':
+ return 'NSValue *';
+ default:
+ throw new Error(`unknown array type for ${property.name}`);
+ }
+ default:
+ throw new Error(`unknown type for ${property.name}`);
}
- return mbglType;
-}
-
-global.arraySetterImplementation = function(property) {
- return `self.layer->set${camelize(property.name)}(${objCName(property)}.mbgl_${convertedType(property)}PropertyValue);`;
-}
+};
-global.styleAttributeFactory = function (property, layerType) {
+global.valueTransformerArguments = function (property) {
+ let objCType = propertyType(property);
switch (property.type) {
case 'boolean':
- return 'mbgl_boolWithPropertyValueBool';
+ return ['bool', objCType];
case 'number':
- return 'mbgl_numberWithPropertyValueNumber';
+ return ['float', objCType];
case 'string':
- return 'mbgl_stringWithPropertyValueString';
+ return ['std::string', objCType];
case 'enum':
- throw new Error('Use MGLGetEnumProperty() for enums.');
+ return [`mbgl::style::${mbglType(property)}`, objCType];
case 'color':
- return 'mbgl_colorWithPropertyValueColor';
+ return ['mbgl::Color', objCType];
case 'array':
- return `mbgl_${convertedType(property)}WithPropertyValue${camelize(convertedType(property))}`;
+ switch (arrayType(property)) {
+ case 'dasharray':
+ return ['std::vector<float>', objCType, 'float'];
+ case 'font':
+ return ['std::vector<std::string>', objCType, 'std::string'];
+ case 'padding':
+ return ['std::array<float, 4>', objCType];
+ case 'offset':
+ case 'translate':
+ return ['std::array<float, 2>', objCType];
+ default:
+ throw new Error(`unknown array type for ${property.name}`);
+ }
default:
throw new Error(`unknown type for ${property.name}`);
}
};
-global.getterImplementation = function(property, layerType) {
- if (property.type === 'enum') {
- let objCType = global.objCType(layerType, property.name);
- return `MGLGetEnumProperty(${camelize(property.name)}, ${mbglType(property)}, ${objCType});`;
+global.initLayer = function (layerType) {
+ if (layerType == "background") {
+ return `_layer = new mbgl::style::${camelize(layerType)}Layer(identifier.UTF8String);`
+ } else {
+ return `_layer = new mbgl::style::${camelize(layerType)}Layer(identifier.UTF8String, source.identifier.UTF8String);`
}
- let rawValue = `self.layer->get${camelize(property.name)}() ?: self.layer->getDefault${camelize(property.name)}()`;
- return `return [MGLStyleAttribute ${styleAttributeFactory(property, layerType)}:${rawValue}];`;
}
-global.convertedType = function(property) {
- switch (arrayType(property)) {
- case 'dasharray':
- return 'numberArray';
- case 'font':
- return 'stringArray';
- case 'padding':
- return 'padding';
- case 'offset':
- case 'translate':
- return 'offset';
- default:
- throw new Error(`unknown array type for ${property.name}`);
+global.setSourceLayer = function() {
+ return `_layer->setSourceLayer(sourceLayer.UTF8String);`
+}
+
+global.mbglType = function(property) {
+ let mbglType = camelize(property.name) + 'Type';
+ if (/-translate-anchor$/.test(property.name)) {
+ mbglType = 'TranslateAnchorType';
}
+ if (/-(rotation|pitch)-alignment$/.test(property.name)) {
+ mbglType = 'AlignmentType';
+ }
+ return mbglType;
}
const layerH = ejs.compile(fs.readFileSync('platform/darwin/src/MGLStyleLayer.h.ejs', 'utf8'), { strict: true });
diff --git a/platform/darwin/src/MGLBackgroundStyleLayer.h b/platform/darwin/src/MGLBackgroundStyleLayer.h
index 386b68feda..1c167fc91c 100644
--- a/platform/darwin/src/MGLBackgroundStyleLayer.h
+++ b/platform/darwin/src/MGLBackgroundStyleLayer.h
@@ -1,8 +1,8 @@
// This file is generated.
// Edit platform/darwin/scripts/generate-style-code.js, then run `make style-code-darwin`.
-#import "MGLStyleAttributeValue.h"
-#import "MGLBaseStyleLayer.h"
+#import "MGLStyleValue.h"
+#import "MGLStyleLayer.h"
NS_ASSUME_NONNULL_BEGIN
@@ -12,12 +12,9 @@ NS_ASSUME_NONNULL_BEGIN
`style` and obtain the background layer using the `-[MGLStyle layerWithIdentifier:]`
method and passing `background` for the identifier.
*/
-@interface MGLBackgroundStyleLayer : MGLBaseStyleLayer <MGLStyleLayer>
-
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier;
-
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier source:(MGLSource *)source;
+@interface MGLBackgroundStyleLayer : MGLStyleLayer
+- (instancetype)initWithIdentifier:(NSString *)identifier NS_DESIGNATED_INITIALIZER;
#pragma mark - Accessing the Paint Attributes
@@ -25,33 +22,33 @@ NS_ASSUME_NONNULL_BEGIN
/**
The color with which the background will be drawn.
- The default value of this property is `UIColor.blackColor`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing `UIColor.blackColor`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `backgroundPattern` is set to `nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> backgroundColor;
+@property (nonatomic, null_resettable) MGLStyleValue<MGLColor *> *backgroundColor;
#else
/**
The color with which the background will be drawn.
- The default value of this property is `NSColor.blackColor`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing `NSColor.blackColor`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `backgroundPattern` is set to `nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> backgroundColor;
+@property (nonatomic, null_resettable) MGLStyleValue<MGLColor *> *backgroundColor;
#endif
/**
Name of image in sprite to use for drawing an image background. For seamless patterns, image width and height must be a factor of two (2, 4, 8, ..., 512).
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> backgroundPattern;
+@property (nonatomic, null_resettable) MGLStyleValue<NSString *> *backgroundPattern;
/**
The opacity at which the background will be drawn.
- The default value of this property is an `NSNumber` object containing the float `1`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `1`. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> backgroundOpacity;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *backgroundOpacity;
@end
diff --git a/platform/darwin/src/MGLBackgroundStyleLayer.mm b/platform/darwin/src/MGLBackgroundStyleLayer.mm
index f15bc4ceed..33a105e5d5 100644
--- a/platform/darwin/src/MGLBackgroundStyleLayer.mm
+++ b/platform/darwin/src/MGLBackgroundStyleLayer.mm
@@ -4,7 +4,7 @@
#import "MGLSource.h"
#import "NSPredicate+MGLAdditions.h"
#import "MGLStyleLayer_Private.h"
-#import "MGLStyleAttributeValue.h"
+#import "MGLStyleValue_Private.h"
#import "MGLBackgroundStyleLayer.h"
#include <mbgl/style/layers/background_layer.hpp>
@@ -12,60 +12,49 @@
@interface MGLBackgroundStyleLayer ()
@property (nonatomic) mbgl::style::BackgroundLayer *layer;
-@property (nonatomic, readwrite) NSString *layerIdentifier;
-@property (nonatomic, readwrite) NSString *sourceIdentifier;
-@property (nonatomic, readwrite) NSString *sourceLayerIdentifier;
@end
@implementation MGLBackgroundStyleLayer
-@synthesize mapView;
-
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier
+- (instancetype)initWithIdentifier:(NSString *)identifier
{
- if (self = [super init]) {
- _layerIdentifier = layerIdentifier;
- _layer = new mbgl::style::BackgroundLayer(layerIdentifier.UTF8String);
+ if (self = [super initWithIdentifier:identifier]) {
+ _layer = new mbgl::style::BackgroundLayer(identifier.UTF8String);
}
return self;
}
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier source:(MGLSource *)source
-{
- if (self = [super init]) {
- _layerIdentifier = layerIdentifier;
- _sourceIdentifier = source.sourceIdentifier;
- _layer = new mbgl::style::BackgroundLayer(layerIdentifier.UTF8String);
- }
- return self;
-}
-
-
#pragma mark - Accessing the Paint Attributes
-- (void)setBackgroundColor:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)backgroundColor {
- self.layer->setBackgroundColor(backgroundColor.mbgl_colorPropertyValue);
+- (void)setBackgroundColor:(MGLStyleValue<MGLColor *> *)backgroundColor {
+ auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue(backgroundColor);
+ self.layer->setBackgroundColor(mbglValue);
}
-- (id <MGLStyleAttributeValue>)backgroundColor {
- return [MGLStyleAttribute mbgl_colorWithPropertyValueColor:self.layer->getBackgroundColor() ?: self.layer->getDefaultBackgroundColor()];
+- (MGLStyleValue<MGLColor *> *)backgroundColor {
+ auto propertyValue = self.layer->getBackgroundColor() ?: self.layer->getDefaultBackgroundColor();
+ return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(propertyValue);
}
-- (void)setBackgroundPattern:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)backgroundPattern {
- self.layer->setBackgroundPattern(backgroundPattern.mbgl_stringPropertyValue);
+- (void)setBackgroundPattern:(MGLStyleValue<NSString *> *)backgroundPattern {
+ auto mbglValue = MGLStyleValueTransformer<std::string, NSString *>().toPropertyValue(backgroundPattern);
+ self.layer->setBackgroundPattern(mbglValue);
}
-- (id <MGLStyleAttributeValue>)backgroundPattern {
- return [MGLStyleAttribute mbgl_stringWithPropertyValueString:self.layer->getBackgroundPattern() ?: self.layer->getDefaultBackgroundPattern()];
+- (MGLStyleValue<NSString *> *)backgroundPattern {
+ auto propertyValue = self.layer->getBackgroundPattern() ?: self.layer->getDefaultBackgroundPattern();
+ return MGLStyleValueTransformer<std::string, NSString *>().toStyleValue(propertyValue);
}
-- (void)setBackgroundOpacity:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)backgroundOpacity {
- self.layer->setBackgroundOpacity(backgroundOpacity.mbgl_floatPropertyValue);
+- (void)setBackgroundOpacity:(MGLStyleValue<NSNumber *> *)backgroundOpacity {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(backgroundOpacity);
+ self.layer->setBackgroundOpacity(mbglValue);
}
-- (id <MGLStyleAttributeValue>)backgroundOpacity {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getBackgroundOpacity() ?: self.layer->getDefaultBackgroundOpacity()];
+- (MGLStyleValue<NSNumber *> *)backgroundOpacity {
+ auto propertyValue = self.layer->getBackgroundOpacity() ?: self.layer->getDefaultBackgroundOpacity();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
@end
diff --git a/platform/darwin/src/MGLBaseStyleLayer.h b/platform/darwin/src/MGLBaseStyleLayer.h
deleted file mode 100644
index fee7707c64..0000000000
--- a/platform/darwin/src/MGLBaseStyleLayer.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#import <Foundation/Foundation.h>
-
-#import "MGLTypes.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-/**
- The base style layer class from which all other style layer classes
- inherit. Style layers allow runtime customization of all map styling
- properties.
-
- You should use the concrete subclasses of `MGLBaseStyleLayer` (which
- conform to `MGLStyleLayer`) to style fill, line, symbol, and other layer
- types.
- */
-@interface MGLBaseStyleLayer : NSObject
-
-/**
- Whether this layer is displayed. A value of `NO` hides the layer.
- */
-@property (nonatomic, assign, getter=isVisible) BOOL visible;
-
-/**
- The maximum zoom level at which the layer gets parsed and appears.
- */
-@property (nonatomic, assign) float maximumZoomLevel;
-
-/**
- The minimum zoom level at which the layer gets parsed and appears.
- */
-@property (nonatomic, assign) float minimumZoomLevel;
-
-@end
-
-NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLBaseStyleLayer.mm b/platform/darwin/src/MGLBaseStyleLayer.mm
deleted file mode 100644
index 8aaabcc8a8..0000000000
--- a/platform/darwin/src/MGLBaseStyleLayer.mm
+++ /dev/null
@@ -1,77 +0,0 @@
-#import "MGLBaseStyleLayer.h"
-
-#import "MGLStyleLayer_Private.h"
-#import "MGLMapView_Private.h"
-
-#include <mbgl/style/layer.hpp>
-
-@interface MGLBaseStyleLayer() <MGLStyleLayer_Private>
-@end
-
-@implementation MGLBaseStyleLayer
-
-@synthesize layerIdentifier;
-@synthesize mapView;
-@synthesize layer;
-@synthesize sourceIdentifier;
-@synthesize sourceLayerIdentifier;
-
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier
-{
- [[NSException exceptionWithName:@"MGLAbstractClassException"
- reason:@"MGLBaseStyleLayer is an abstract class"
- userInfo:nil] raise];
- return nil;
-}
-
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier sourceIdentifier:(NSString *)sourceIdentifier
-{
- [[NSException exceptionWithName:@"MGLAbstractClassException"
- reason:@"MGLBaseStyleLayer is an abstract class"
- userInfo:nil] raise];
- return nil;
-}
-
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier sourceIdentifier:(NSString *)sourceIdentifier sourceLayer:(NSString *)sourceLayer
-{
- [[NSException exceptionWithName:@"MGLAbstractClassException"
- reason:@"MGLBaseStyleLayer is an abstract class"
- userInfo:nil] raise];
- return nil;
-}
-
-- (void)setVisible:(BOOL)visible
-{
- mbgl::style::VisibilityType v = visible
- ? mbgl::style::VisibilityType::Visible
- : mbgl::style::VisibilityType::None;
- self.layer->setVisibility(v);
-}
-
-- (BOOL)isVisible
-{
- mbgl::style::VisibilityType v = self.layer->getVisibility();
- return (v == mbgl::style::VisibilityType::Visible);
-}
-
-- (void)setMaximumZoomLevel:(float)maximumZoomLevel
-{
- self.layer->setMaxZoom(maximumZoomLevel);
-}
-
-- (float)maximumZoomLevel
-{
- return self.layer->getMaxZoom();
-}
-
-- (void)setMinimumZoomLevel:(float)minimumZoomLevel
-{
- self.layer->setMinZoom(minimumZoomLevel);
-}
-
-- (float)minimumZoomLevel
-{
- return self.layer->getMinZoom();
-}
-
-@end
diff --git a/platform/darwin/src/MGLCircleStyleLayer.h b/platform/darwin/src/MGLCircleStyleLayer.h
index 9e620eeeec..6006250cdf 100644
--- a/platform/darwin/src/MGLCircleStyleLayer.h
+++ b/platform/darwin/src/MGLCircleStyleLayer.h
@@ -1,37 +1,41 @@
// This file is generated.
// Edit platform/darwin/scripts/generate-style-code.js, then run `make style-code-darwin`.
-#import "MGLStyleAttributeValue.h"
-#import "MGLBaseStyleLayer.h"
+#import "MGLStyleValue.h"
+#import "MGLVectorStyleLayer.h"
NS_ASSUME_NONNULL_BEGIN
/**
Controls the translation reference point.
+
+ Values of this type are used in the `circleTranslateAnchor` property of `MGLCircleStyleLayer`.
*/
-typedef NS_ENUM(NSUInteger, MGLCircleStyleLayerCircleTranslateAnchor) {
+typedef NS_ENUM(NSUInteger, MGLCircleTranslateAnchor) {
/**
The circle is translated relative to the map.
*/
- MGLCircleStyleLayerCircleTranslateAnchorMap,
+ MGLCircleTranslateAnchorMap,
/**
The circle is translated relative to the viewport.
*/
- MGLCircleStyleLayerCircleTranslateAnchorViewport,
+ MGLCircleTranslateAnchorViewport,
};
/**
Controls the scaling behavior of the circle when the map is pitched.
+
+ Values of this type are used in the `circlePitchScale` property of `MGLCircleStyleLayer`.
*/
-typedef NS_ENUM(NSUInteger, MGLCircleStyleLayerCirclePitchScale) {
+typedef NS_ENUM(NSUInteger, MGLCirclePitchScale) {
/**
Circles are scaled according to their apparent distance to the camera.
*/
- MGLCircleStyleLayerCirclePitchScaleMap,
+ MGLCirclePitchScaleMap,
/**
Circles are not scaled.
*/
- MGLCircleStyleLayerCirclePitchScaleViewport,
+ MGLCirclePitchScaleViewport,
};
/**
@@ -40,19 +44,7 @@ typedef NS_ENUM(NSUInteger, MGLCircleStyleLayerCirclePitchScale) {
`MGLMapView` for its `style` and obtain existing layers using the
`-[MGLStyle layerWithIdentifier:]` method.
*/
-@interface MGLCircleStyleLayer : MGLBaseStyleLayer <MGLStyleLayer>
-
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier source:(MGLSource *)source;
-
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier source:(MGLSource *)source sourceLayer:(NSString *)sourceLayer;
-
-/**
- A predicate that corresponds to the layer's <a href='https://www.mapbox.com/mapbox-gl-style-spec/#types-filter'>filter</a>.
-
- The predicate's left expression must be a string that identifies a feature
- property, or one of the special keys.
- */
-@property (nonatomic, nullable) NSPredicate *predicate;
+@interface MGLCircleStyleLayer : MGLVectorStyleLayer
#pragma mark - Accessing the Paint Attributes
@@ -61,64 +53,64 @@ typedef NS_ENUM(NSUInteger, MGLCircleStyleLayerCirclePitchScale) {
This property is measured in points.
- The default value of this property is an `NSNumber` object containing the float `5`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `5`. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> circleRadius;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *circleRadius;
#if TARGET_OS_IPHONE
/**
The fill color of the circle.
- The default value of this property is `UIColor.blackColor`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing `UIColor.blackColor`. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> circleColor;
+@property (nonatomic, null_resettable) MGLStyleValue<MGLColor *> *circleColor;
#else
/**
The fill color of the circle.
- The default value of this property is `NSColor.blackColor`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing `NSColor.blackColor`. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> circleColor;
+@property (nonatomic, null_resettable) MGLStyleValue<MGLColor *> *circleColor;
#endif
/**
Amount to blur the circle. 1 blurs the circle such that only the centerpoint is full opacity.
- The default value of this property is an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> circleBlur;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *circleBlur;
/**
The opacity at which the circle will be drawn.
- The default value of this property is an `NSNumber` object containing the float `1`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `1`. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> circleOpacity;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *circleOpacity;
/**
The geometry's offset. Values are [x, y] where negatives indicate left and up, respectively.
This property is measured in points.
- The default value of this property is an `NSValue` object containing a `CGVector` struct set to 0 points from the left and 0 points from the top. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing a `CGVector` struct set to 0 points from the left and 0 points from the top. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> circleTranslate;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *circleTranslate;
/**
Controls the translation reference point.
- The default value of this property is an `NSValue` object containing `MGLCircleStyleLayerCircleTranslateAnchorMap`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLCircleTranslateAnchorMap`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `circleTranslate` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> circleTranslateAnchor;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *circleTranslateAnchor;
/**
Controls the scaling behavior of the circle when the map is pitched.
- The default value of this property is an `NSValue` object containing `MGLCircleStyleLayerCirclePitchScaleMap`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLCirclePitchScaleMap`. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> circlePitchScale;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *circlePitchScale;
@end
diff --git a/platform/darwin/src/MGLCircleStyleLayer.mm b/platform/darwin/src/MGLCircleStyleLayer.mm
index 1db7ef875e..8fe97a0537 100644
--- a/platform/darwin/src/MGLCircleStyleLayer.mm
+++ b/platform/darwin/src/MGLCircleStyleLayer.mm
@@ -4,7 +4,7 @@
#import "MGLSource.h"
#import "NSPredicate+MGLAdditions.h"
#import "MGLStyleLayer_Private.h"
-#import "MGLStyleAttributeValue.h"
+#import "MGLStyleValue_Private.h"
#import "MGLCircleStyleLayer.h"
#include <mbgl/style/layers/circle_layer.hpp>
@@ -12,36 +12,28 @@
@interface MGLCircleStyleLayer ()
@property (nonatomic) mbgl::style::CircleLayer *layer;
-@property (nonatomic, readwrite) NSString *layerIdentifier;
-@property (nonatomic, readwrite) NSString *sourceIdentifier;
-@property (nonatomic, readwrite) NSString *sourceLayerIdentifier;
@end
@implementation MGLCircleStyleLayer
-@synthesize mapView;
-
-
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier source:(MGLSource *)source
+- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source
{
- if (self = [super init]) {
- _layerIdentifier = layerIdentifier;
- _sourceIdentifier = source.sourceIdentifier;
- _layer = new mbgl::style::CircleLayer(layerIdentifier.UTF8String, source.sourceIdentifier.UTF8String);
+ if (self = [super initWithIdentifier:identifier source:source]) {
+ _layer = new mbgl::style::CircleLayer(identifier.UTF8String, source.identifier.UTF8String);
}
return self;
}
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier source:(MGLSource *)source sourceLayer:(NSString *)sourceLayer
+- (NSString *)sourceLayerIdentifier
{
- if (self = [super init]) {
- _layerIdentifier = layerIdentifier;
- _sourceIdentifier = source.sourceIdentifier;
- _layer = new mbgl::style::CircleLayer(layerIdentifier.UTF8String, source.sourceIdentifier.UTF8String);
- _layer->setSourceLayer(sourceLayer.UTF8String);
- }
- return self;
+ auto layerID = self.layer->getSourceLayer();
+ return layerID.empty() ? nil : @(layerID.c_str());
+}
+
+- (void)setSourceLayerIdentifier:(NSString *)sourceLayerIdentifier
+{
+ self.layer->setSourceLayer(sourceLayerIdentifier.UTF8String ?: "");
}
- (void)setPredicate:(NSPredicate *)predicate
@@ -56,60 +48,74 @@
#pragma mark - Accessing the Paint Attributes
-- (void)setCircleRadius:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)circleRadius {
- self.layer->setCircleRadius(circleRadius.mbgl_floatPropertyValue);
+- (void)setCircleRadius:(MGLStyleValue<NSNumber *> *)circleRadius {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(circleRadius);
+ self.layer->setCircleRadius(mbglValue);
}
-- (id <MGLStyleAttributeValue>)circleRadius {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getCircleRadius() ?: self.layer->getDefaultCircleRadius()];
+- (MGLStyleValue<NSNumber *> *)circleRadius {
+ auto propertyValue = self.layer->getCircleRadius() ?: self.layer->getDefaultCircleRadius();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setCircleColor:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)circleColor {
- self.layer->setCircleColor(circleColor.mbgl_colorPropertyValue);
+- (void)setCircleColor:(MGLStyleValue<MGLColor *> *)circleColor {
+ auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue(circleColor);
+ self.layer->setCircleColor(mbglValue);
}
-- (id <MGLStyleAttributeValue>)circleColor {
- return [MGLStyleAttribute mbgl_colorWithPropertyValueColor:self.layer->getCircleColor() ?: self.layer->getDefaultCircleColor()];
+- (MGLStyleValue<MGLColor *> *)circleColor {
+ auto propertyValue = self.layer->getCircleColor() ?: self.layer->getDefaultCircleColor();
+ return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(propertyValue);
}
-- (void)setCircleBlur:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)circleBlur {
- self.layer->setCircleBlur(circleBlur.mbgl_floatPropertyValue);
+- (void)setCircleBlur:(MGLStyleValue<NSNumber *> *)circleBlur {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(circleBlur);
+ self.layer->setCircleBlur(mbglValue);
}
-- (id <MGLStyleAttributeValue>)circleBlur {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getCircleBlur() ?: self.layer->getDefaultCircleBlur()];
+- (MGLStyleValue<NSNumber *> *)circleBlur {
+ auto propertyValue = self.layer->getCircleBlur() ?: self.layer->getDefaultCircleBlur();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setCircleOpacity:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)circleOpacity {
- self.layer->setCircleOpacity(circleOpacity.mbgl_floatPropertyValue);
+- (void)setCircleOpacity:(MGLStyleValue<NSNumber *> *)circleOpacity {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(circleOpacity);
+ self.layer->setCircleOpacity(mbglValue);
}
-- (id <MGLStyleAttributeValue>)circleOpacity {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getCircleOpacity() ?: self.layer->getDefaultCircleOpacity()];
+- (MGLStyleValue<NSNumber *> *)circleOpacity {
+ auto propertyValue = self.layer->getCircleOpacity() ?: self.layer->getDefaultCircleOpacity();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setCircleTranslate:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)circleTranslate {
- self.layer->setCircleTranslate(circleTranslate.mbgl_offsetPropertyValue);
+- (void)setCircleTranslate:(MGLStyleValue<NSValue *> *)circleTranslate {
+ auto mbglValue = MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toPropertyValue(circleTranslate);
+ self.layer->setCircleTranslate(mbglValue);
}
-- (id <MGLStyleAttributeValue>)circleTranslate {
- return [MGLStyleAttribute mbgl_offsetWithPropertyValueOffset:self.layer->getCircleTranslate() ?: self.layer->getDefaultCircleTranslate()];
+- (MGLStyleValue<NSValue *> *)circleTranslate {
+ auto propertyValue = self.layer->getCircleTranslate() ?: self.layer->getDefaultCircleTranslate();
+ return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toStyleValue(propertyValue);
}
-- (void)setCircleTranslateAnchor:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)circleTranslateAnchor {
- MGLSetEnumProperty(circleTranslateAnchor, CircleTranslateAnchor, TranslateAnchorType, MGLCircleStyleLayerCircleTranslateAnchor);
+- (void)setCircleTranslateAnchor:(MGLStyleValue<NSValue *> *)circleTranslateAnchor {
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *>().toPropertyValue(circleTranslateAnchor);
+ self.layer->setCircleTranslateAnchor(mbglValue);
}
-- (id <MGLStyleAttributeValue>)circleTranslateAnchor {
- MGLGetEnumProperty(CircleTranslateAnchor, TranslateAnchorType, MGLCircleStyleLayerCircleTranslateAnchor);
+- (MGLStyleValue<NSValue *> *)circleTranslateAnchor {
+ auto propertyValue = self.layer->getCircleTranslateAnchor() ?: self.layer->getDefaultCircleTranslateAnchor();
+ return MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *>().toStyleValue(propertyValue);
}
-- (void)setCirclePitchScale:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)circlePitchScale {
- MGLSetEnumProperty(circlePitchScale, CirclePitchScale, CirclePitchScaleType, MGLCircleStyleLayerCirclePitchScale);
+- (void)setCirclePitchScale:(MGLStyleValue<NSValue *> *)circlePitchScale {
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::CirclePitchScaleType, NSValue *>().toPropertyValue(circlePitchScale);
+ self.layer->setCirclePitchScale(mbglValue);
}
-- (id <MGLStyleAttributeValue>)circlePitchScale {
- MGLGetEnumProperty(CirclePitchScale, CirclePitchScaleType, MGLCircleStyleLayerCirclePitchScale);
+- (MGLStyleValue<NSValue *> *)circlePitchScale {
+ auto propertyValue = self.layer->getCirclePitchScale() ?: self.layer->getDefaultCirclePitchScale();
+ return MGLStyleValueTransformer<mbgl::style::CirclePitchScaleType, NSValue *>().toStyleValue(propertyValue);
}
@end
diff --git a/platform/darwin/src/MGLFeature.h b/platform/darwin/src/MGLFeature.h
index aec4223b12..239a338f67 100644
--- a/platform/darwin/src/MGLFeature.h
+++ b/platform/darwin/src/MGLFeature.h
@@ -91,6 +91,17 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (nullable id)attributeForKey:(NSString *)key;
+/**
+ Returns a dictionary that can be serialized as a GeoJSON Feature representation
+ of an instance of an `MGLFeature` subclass.
+
+ The dictionary includes a `geometry` key corresponding to the receiver’s
+ underlying geometry data, a `properties` key corresponding to the receiver’s
+ `attributes` property, and an `id` key corresponding to the receiver’s
+ `identifier` property.
+ */
+- (NS_DICTIONARY_OF(NSString *, id) *)geoJSONDictionary;
+
@end
/**
@@ -140,6 +151,11 @@ NS_ASSUME_NONNULL_BEGIN
<a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources">tile source</a>.
*/
@interface MGLShapeCollectionFeature : MGLShapeCollection <MGLFeature>
+
+@property (nonatomic, copy, readonly) NS_ARRAY_OF(MGLShape<MGLFeature> *) *shapes;
+
++ (instancetype)shapeCollectionWithShapes:(NS_ARRAY_OF(MGLShape<MGLFeature> *) *)shapes;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLFeature.mm b/platform/darwin/src/MGLFeature.mm
index 6d4f76a71d..84dcc4f0bb 100644
--- a/platform/darwin/src/MGLFeature.mm
+++ b/platform/darwin/src/MGLFeature.mm
@@ -5,16 +5,16 @@
#import "MGLPolygon.h"
#import "MGLValueEvaluator.h"
+#import "MGLShape_Private.h"
#import "MGLMultiPoint_Private.h"
+#import "MGLPolyline+MGLAdditions.h"
+#import "MGLPolygon+MGLAdditions.h"
+#import "NSDictionary+MGLAdditions.h"
-#import <mbgl/util/geometry.hpp>
-
-@protocol MGLFeaturePrivate <MGLFeature>
-
-@property (nonatomic, copy, nullable, readwrite) id identifier;
-@property (nonatomic, copy, readwrite) NS_DICTIONARY_OF(NSString *, id) *attributes;
+#import "NSExpression+MGLAdditions.h"
-@end
+#import <mbgl/util/geometry.hpp>
+#import <mapbox/geometry/feature.hpp>
@interface MGLPointFeature () <MGLFeaturePrivate>
@end
@@ -28,6 +28,14 @@
return self.attributes[key];
}
+- (NSDictionary *)geoJSONDictionary {
+ return NSDictionaryFeatureForGeometry([super geoJSONDictionary], self.attributes, self.identifier);
+}
+
+- (mbgl::Feature)mbglFeature {
+ return mbglFeature([self featureObject], identifier, self.attributes);
+}
+
@end
@interface MGLPolylineFeature () <MGLFeaturePrivate>
@@ -42,6 +50,14 @@
return self.attributes[key];
}
+- (NSDictionary *)geoJSONDictionary {
+ return NSDictionaryFeatureForGeometry([super geoJSONDictionary], self.attributes, self.identifier);
+}
+
+- (mbgl::Feature)mbglFeature {
+ return mbglFeature([self featureObject], identifier, self.attributes);
+}
+
@end
@interface MGLPolygonFeature () <MGLFeaturePrivate>
@@ -56,6 +72,14 @@
return self.attributes[key];
}
+- (NSDictionary *)geoJSONDictionary {
+ return NSDictionaryFeatureForGeometry([super geoJSONDictionary], self.attributes, self.identifier);
+}
+
+- (mbgl::Feature)mbglFeature {
+ return mbglFeature([self featureObject], identifier, self.attributes);
+}
+
@end
@interface MGLMultiPointFeature () <MGLFeaturePrivate>
@@ -70,6 +94,14 @@
return self.attributes[key];
}
+- (NSDictionary *)geoJSONDictionary {
+ return NSDictionaryFeatureForGeometry([super geoJSONDictionary], self.attributes, self.identifier);
+}
+
+- (mbgl::Feature)mbglFeature {
+ return mbglFeature([self featureObject], identifier, self.attributes);
+}
+
@end
@interface MGLMultiPolylineFeature () <MGLFeaturePrivate>
@@ -84,6 +116,14 @@
return self.attributes[key];
}
+- (NSDictionary *)geoJSONDictionary {
+ return NSDictionaryFeatureForGeometry([super geoJSONDictionary], self.attributes, self.identifier);
+}
+
+- (mbgl::Feature)mbglFeature {
+ return mbglFeature([self featureObject], identifier, self.attributes);
+}
+
@end
@interface MGLMultiPolygonFeature () <MGLFeaturePrivate>
@@ -98,6 +138,14 @@
return self.attributes[key];
}
+- (NSDictionary *)geoJSONDictionary {
+ return NSDictionaryFeatureForGeometry([super geoJSONDictionary], self.attributes, self.identifier);
+}
+
+- (mbgl::Feature)mbglFeature {
+ return mbglFeature([self featureObject], identifier, self.attributes);
+}
+
@end
@interface MGLShapeCollectionFeature () <MGLFeaturePrivate>
@@ -108,13 +156,27 @@
@synthesize identifier;
@synthesize attributes;
+@dynamic shapes;
+
++ (instancetype)shapeCollectionWithShapes:(NSArray *)shapes {
+ return [super shapeCollectionWithShapes:shapes];
+}
+
- (id)attributeForKey:(NSString *)key {
return self.attributes[key];
}
-@end
+- (NSDictionary *)geoJSONDictionary {
+ return NSDictionaryFeatureForGeometry([super geoJSONDictionary], self.attributes, self.identifier);
+}
+- (mbgl::Feature)mbglFeature {
+ [NSException raise:@"Method unavailable" format:@"%s is not available on %@.", __PRETTY_FUNCTION__, [self class]];
+ mbgl::Polygon<double> geometry;
+ return mbgl::Feature{geometry};
+}
+@end
/**
Transforms an `mbgl::geometry::geometry` type into an instance of the
@@ -224,3 +286,21 @@ NS_ARRAY_OF(MGLShape <MGLFeature> *) *MGLFeaturesFromMBGLFeatures(const std::vec
}
return shapes;
}
+
+mbgl::Feature mbglFeature(mbgl::Feature feature, id identifier, NSDictionary *attributes)
+{
+ if (identifier) {
+ NSExpression *identifierExpression = [NSExpression expressionForConstantValue:identifier];
+ feature.id = [identifierExpression mgl_featureIdentifier];
+ }
+ feature.properties = [attributes mgl_propertyMap];
+ return feature;
+}
+
+NS_DICTIONARY_OF(NSString *, id) *NSDictionaryFeatureForGeometry(NSDictionary *geometry, NSDictionary *attributes, id identifier) {
+ NSMutableDictionary *feature = [@{@"type": @"Feature",
+ @"properties": (attributes) ?: [NSNull null],
+ @"geometry": geometry} mutableCopy];
+ feature[@"id"] = identifier;
+ return [feature copy];
+}
diff --git a/platform/darwin/src/MGLFeature_Private.h b/platform/darwin/src/MGLFeature_Private.h
index fbc7f88559..5fb82bde5b 100644
--- a/platform/darwin/src/MGLFeature_Private.h
+++ b/platform/darwin/src/MGLFeature_Private.h
@@ -4,8 +4,33 @@
#import <mbgl/util/geo.hpp>
#import <mbgl/util/feature.hpp>
+NS_ASSUME_NONNULL_BEGIN
+
/**
Returns an array of `MGLFeature` objects converted from the given vector of
vector tile features.
*/
NS_ARRAY_OF(MGLShape <MGLFeature> *) *MGLFeaturesFromMBGLFeatures(const std::vector<mbgl::Feature> &features);
+
+/**
+ Takes an `mbgl::Feature` object, an identifer, and attributes dictionary and
+ returns the feature object with converted `mbgl::FeatureIdentifier` and
+ `mbgl::PropertyMap` properties.
+ */
+mbgl::Feature mbglFeature(mbgl::Feature feature, id identifier, NSDictionary *attributes);
+
+/**
+ Returns an `NSDictionary` representation of an `MGLFeature`.
+ */
+NS_DICTIONARY_OF(NSString *, id) *NSDictionaryFeatureForGeometry(NSDictionary *geometry, NSDictionary *attributes, id identifier);
+
+@protocol MGLFeaturePrivate <MGLFeature>
+
+@property (nonatomic, copy, nullable, readwrite) id identifier;
+@property (nonatomic, copy, readwrite) NS_DICTIONARY_OF(NSString *, id) *attributes;
+
+- (mbgl::Feature)mbglFeature;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLFillStyleLayer.h b/platform/darwin/src/MGLFillStyleLayer.h
index 9adfd7c432..712bfea998 100644
--- a/platform/darwin/src/MGLFillStyleLayer.h
+++ b/platform/darwin/src/MGLFillStyleLayer.h
@@ -1,23 +1,25 @@
// This file is generated.
// Edit platform/darwin/scripts/generate-style-code.js, then run `make style-code-darwin`.
-#import "MGLStyleAttributeValue.h"
-#import "MGLBaseStyleLayer.h"
+#import "MGLStyleValue.h"
+#import "MGLVectorStyleLayer.h"
NS_ASSUME_NONNULL_BEGIN
/**
Controls the translation reference point.
+
+ Values of this type are used in the `fillTranslateAnchor` property of `MGLFillStyleLayer`.
*/
-typedef NS_ENUM(NSUInteger, MGLFillStyleLayerFillTranslateAnchor) {
+typedef NS_ENUM(NSUInteger, MGLFillTranslateAnchor) {
/**
The fill is translated relative to the map.
*/
- MGLFillStyleLayerFillTranslateAnchorMap,
+ MGLFillTranslateAnchorMap,
/**
The fill is translated relative to the viewport.
*/
- MGLFillStyleLayerFillTranslateAnchorViewport,
+ MGLFillTranslateAnchorViewport,
};
/**
@@ -26,85 +28,73 @@ typedef NS_ENUM(NSUInteger, MGLFillStyleLayerFillTranslateAnchor) {
`MGLMapView` for its `style` and obtain existing layers using the
`-[MGLStyle layerWithIdentifier:]` method.
*/
-@interface MGLFillStyleLayer : MGLBaseStyleLayer <MGLStyleLayer>
-
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier source:(MGLSource *)source;
-
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier source:(MGLSource *)source sourceLayer:(NSString *)sourceLayer;
-
-/**
- A predicate that corresponds to the layer's <a href='https://www.mapbox.com/mapbox-gl-style-spec/#types-filter'>filter</a>.
-
- The predicate's left expression must be a string that identifies a feature
- property, or one of the special keys.
- */
-@property (nonatomic, nullable) NSPredicate *predicate;
+@interface MGLFillStyleLayer : MGLVectorStyleLayer
#pragma mark - Accessing the Paint Attributes
/**
Whether or not the fill should be antialiased.
- The default value of this property is an `NSNumber` object containing `YES`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing `YES`. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> fillAntialias;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *fillAntialias;
/**
The opacity of the entire fill layer. In contrast to the `fillColor`, this value will also affect the 1pt stroke around the fill, if the stroke is used.
- The default value of this property is an `NSNumber` object containing the float `1`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `1`. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> fillOpacity;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *fillOpacity;
#if TARGET_OS_IPHONE
/**
The color of the filled part of this layer. This color can be specified as `rgba` with an alpha component and the color's opacity will not affect the opacity of the 1pt stroke, if it is used.
- The default value of this property is `UIColor.blackColor`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing `UIColor.blackColor`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `fillPattern` is set to `nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> fillColor;
+@property (nonatomic, null_resettable) MGLStyleValue<MGLColor *> *fillColor;
#else
/**
The color of the filled part of this layer. This color can be specified as `rgba` with an alpha component and the color's opacity will not affect the opacity of the 1pt stroke, if it is used.
- The default value of this property is `NSColor.blackColor`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing `NSColor.blackColor`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `fillPattern` is set to `nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> fillColor;
+@property (nonatomic, null_resettable) MGLStyleValue<MGLColor *> *fillColor;
#endif
/**
The outline color of the fill. Matches the value of `fillColor` if unspecified.
- This property is only applied to the style if `fillPattern` is set to `nil`, and `fillAntialias` is set to an `NSNumber` object containing `YES`. Otherwise, it is ignored.
+ This property is only applied to the style if `fillPattern` is set to `nil`, and `fillAntialias` is set to an `MGLStyleValue` object containing an `NSNumber` object containing `YES`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> fillOutlineColor;
+@property (nonatomic, null_resettable) MGLStyleValue<MGLColor *> *fillOutlineColor;
/**
The geometry's offset. Values are [x, y] where negatives indicate left and up, respectively.
This property is measured in points.
- The default value of this property is an `NSValue` object containing a `CGVector` struct set to 0 points from the left and 0 points from the top. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing a `CGVector` struct set to 0 points from the left and 0 points from the top. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> fillTranslate;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *fillTranslate;
/**
Controls the translation reference point.
- The default value of this property is an `NSValue` object containing `MGLFillStyleLayerFillTranslateAnchorMap`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLFillTranslateAnchorMap`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `fillTranslate` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> fillTranslateAnchor;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *fillTranslateAnchor;
/**
Name of image in sprite to use for drawing image fills. For seamless patterns, image width and height must be a factor of two (2, 4, 8, ..., 512).
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> fillPattern;
+@property (nonatomic, null_resettable) MGLStyleValue<NSString *> *fillPattern;
@end
diff --git a/platform/darwin/src/MGLFillStyleLayer.mm b/platform/darwin/src/MGLFillStyleLayer.mm
index d36375b126..e16e3b2652 100644
--- a/platform/darwin/src/MGLFillStyleLayer.mm
+++ b/platform/darwin/src/MGLFillStyleLayer.mm
@@ -4,7 +4,7 @@
#import "MGLSource.h"
#import "NSPredicate+MGLAdditions.h"
#import "MGLStyleLayer_Private.h"
-#import "MGLStyleAttributeValue.h"
+#import "MGLStyleValue_Private.h"
#import "MGLFillStyleLayer.h"
#include <mbgl/style/layers/fill_layer.hpp>
@@ -12,36 +12,28 @@
@interface MGLFillStyleLayer ()
@property (nonatomic) mbgl::style::FillLayer *layer;
-@property (nonatomic, readwrite) NSString *layerIdentifier;
-@property (nonatomic, readwrite) NSString *sourceIdentifier;
-@property (nonatomic, readwrite) NSString *sourceLayerIdentifier;
@end
@implementation MGLFillStyleLayer
-@synthesize mapView;
-
-
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier source:(MGLSource *)source
+- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source
{
- if (self = [super init]) {
- _layerIdentifier = layerIdentifier;
- _sourceIdentifier = source.sourceIdentifier;
- _layer = new mbgl::style::FillLayer(layerIdentifier.UTF8String, source.sourceIdentifier.UTF8String);
+ if (self = [super initWithIdentifier:identifier source:source]) {
+ _layer = new mbgl::style::FillLayer(identifier.UTF8String, source.identifier.UTF8String);
}
return self;
}
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier source:(MGLSource *)source sourceLayer:(NSString *)sourceLayer
+- (NSString *)sourceLayerIdentifier
{
- if (self = [super init]) {
- _layerIdentifier = layerIdentifier;
- _sourceIdentifier = source.sourceIdentifier;
- _layer = new mbgl::style::FillLayer(layerIdentifier.UTF8String, source.sourceIdentifier.UTF8String);
- _layer->setSourceLayer(sourceLayer.UTF8String);
- }
- return self;
+ auto layerID = self.layer->getSourceLayer();
+ return layerID.empty() ? nil : @(layerID.c_str());
+}
+
+- (void)setSourceLayerIdentifier:(NSString *)sourceLayerIdentifier
+{
+ self.layer->setSourceLayer(sourceLayerIdentifier.UTF8String ?: "");
}
- (void)setPredicate:(NSPredicate *)predicate
@@ -56,60 +48,74 @@
#pragma mark - Accessing the Paint Attributes
-- (void)setFillAntialias:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)fillAntialias {
- self.layer->setFillAntialias(fillAntialias.mbgl_boolPropertyValue);
+- (void)setFillAntialias:(MGLStyleValue<NSNumber *> *)fillAntialias {
+ auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue(fillAntialias);
+ self.layer->setFillAntialias(mbglValue);
}
-- (id <MGLStyleAttributeValue>)fillAntialias {
- return [MGLStyleAttribute mbgl_boolWithPropertyValueBool:self.layer->getFillAntialias() ?: self.layer->getDefaultFillAntialias()];
+- (MGLStyleValue<NSNumber *> *)fillAntialias {
+ auto propertyValue = self.layer->getFillAntialias() ?: self.layer->getDefaultFillAntialias();
+ return MGLStyleValueTransformer<bool, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setFillOpacity:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)fillOpacity {
- self.layer->setFillOpacity(fillOpacity.mbgl_floatPropertyValue);
+- (void)setFillOpacity:(MGLStyleValue<NSNumber *> *)fillOpacity {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(fillOpacity);
+ self.layer->setFillOpacity(mbglValue);
}
-- (id <MGLStyleAttributeValue>)fillOpacity {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getFillOpacity() ?: self.layer->getDefaultFillOpacity()];
+- (MGLStyleValue<NSNumber *> *)fillOpacity {
+ auto propertyValue = self.layer->getFillOpacity() ?: self.layer->getDefaultFillOpacity();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setFillColor:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)fillColor {
- self.layer->setFillColor(fillColor.mbgl_colorPropertyValue);
+- (void)setFillColor:(MGLStyleValue<MGLColor *> *)fillColor {
+ auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue(fillColor);
+ self.layer->setFillColor(mbglValue);
}
-- (id <MGLStyleAttributeValue>)fillColor {
- return [MGLStyleAttribute mbgl_colorWithPropertyValueColor:self.layer->getFillColor() ?: self.layer->getDefaultFillColor()];
+- (MGLStyleValue<MGLColor *> *)fillColor {
+ auto propertyValue = self.layer->getFillColor() ?: self.layer->getDefaultFillColor();
+ return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(propertyValue);
}
-- (void)setFillOutlineColor:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)fillOutlineColor {
- self.layer->setFillOutlineColor(fillOutlineColor.mbgl_colorPropertyValue);
+- (void)setFillOutlineColor:(MGLStyleValue<MGLColor *> *)fillOutlineColor {
+ auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue(fillOutlineColor);
+ self.layer->setFillOutlineColor(mbglValue);
}
-- (id <MGLStyleAttributeValue>)fillOutlineColor {
- return [MGLStyleAttribute mbgl_colorWithPropertyValueColor:self.layer->getFillOutlineColor() ?: self.layer->getDefaultFillOutlineColor()];
+- (MGLStyleValue<MGLColor *> *)fillOutlineColor {
+ auto propertyValue = self.layer->getFillOutlineColor() ?: self.layer->getDefaultFillOutlineColor();
+ return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(propertyValue);
}
-- (void)setFillTranslate:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)fillTranslate {
- self.layer->setFillTranslate(fillTranslate.mbgl_offsetPropertyValue);
+- (void)setFillTranslate:(MGLStyleValue<NSValue *> *)fillTranslate {
+ auto mbglValue = MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toPropertyValue(fillTranslate);
+ self.layer->setFillTranslate(mbglValue);
}
-- (id <MGLStyleAttributeValue>)fillTranslate {
- return [MGLStyleAttribute mbgl_offsetWithPropertyValueOffset:self.layer->getFillTranslate() ?: self.layer->getDefaultFillTranslate()];
+- (MGLStyleValue<NSValue *> *)fillTranslate {
+ auto propertyValue = self.layer->getFillTranslate() ?: self.layer->getDefaultFillTranslate();
+ return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toStyleValue(propertyValue);
}
-- (void)setFillTranslateAnchor:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)fillTranslateAnchor {
- MGLSetEnumProperty(fillTranslateAnchor, FillTranslateAnchor, TranslateAnchorType, MGLFillStyleLayerFillTranslateAnchor);
+- (void)setFillTranslateAnchor:(MGLStyleValue<NSValue *> *)fillTranslateAnchor {
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *>().toPropertyValue(fillTranslateAnchor);
+ self.layer->setFillTranslateAnchor(mbglValue);
}
-- (id <MGLStyleAttributeValue>)fillTranslateAnchor {
- MGLGetEnumProperty(FillTranslateAnchor, TranslateAnchorType, MGLFillStyleLayerFillTranslateAnchor);
+- (MGLStyleValue<NSValue *> *)fillTranslateAnchor {
+ auto propertyValue = self.layer->getFillTranslateAnchor() ?: self.layer->getDefaultFillTranslateAnchor();
+ return MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *>().toStyleValue(propertyValue);
}
-- (void)setFillPattern:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)fillPattern {
- self.layer->setFillPattern(fillPattern.mbgl_stringPropertyValue);
+- (void)setFillPattern:(MGLStyleValue<NSString *> *)fillPattern {
+ auto mbglValue = MGLStyleValueTransformer<std::string, NSString *>().toPropertyValue(fillPattern);
+ self.layer->setFillPattern(mbglValue);
}
-- (id <MGLStyleAttributeValue>)fillPattern {
- return [MGLStyleAttribute mbgl_stringWithPropertyValueString:self.layer->getFillPattern() ?: self.layer->getDefaultFillPattern()];
+- (MGLStyleValue<NSString *> *)fillPattern {
+ auto propertyValue = self.layer->getFillPattern() ?: self.layer->getDefaultFillPattern();
+ return MGLStyleValueTransformer<std::string, NSString *>().toStyleValue(propertyValue);
}
@end
diff --git a/platform/darwin/src/MGLForegroundStyleLayer.h b/platform/darwin/src/MGLForegroundStyleLayer.h
new file mode 100644
index 0000000000..642dde4992
--- /dev/null
+++ b/platform/darwin/src/MGLForegroundStyleLayer.h
@@ -0,0 +1,48 @@
+#import <Foundation/Foundation.h>
+
+#import "MGLStyleLayer.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@class MGLSource;
+
+/**
+ `MGLForegroundStyleLayer` is an abstract superclass for style layers whose
+ content is defined by an `MGLSource` object.
+
+ Do not create instances of this class directly, and do not create your own
+ subclasses of this class. Instead, create instances of `MGLRasterStyleLayer`
+ and the concrete subclasses of `MGLVectorStyleLayer`.
+ */
+@interface MGLForegroundStyleLayer : MGLStyleLayer
+
+#pragma mark Initializing a Style Layer
+
+- (instancetype)init __attribute__((unavailable("Use -initWithIdentifier:source: instead.")));
+- (instancetype)initWithIdentifier:(NSString *)identifier __attribute__((unavailable("Use -initWithIdentifier:source: instead.")));
+
+/**
+ Returns a foreground style layer initialized with an identifier and source.
+
+ After initializing and configuring the style layer, add it to a map view’s
+ style using the `-[MGLStyle addLayer:]` or
+ `-[MGLStyle insertLayer:belowLayer:]` method.
+
+ @param identifier A string that uniquely identifies the source in the style to
+ which it is added.
+ @param source The source from which to obtain the data to style. If the source
+ has not yet been added to the current style, the behavior is undefined.
+ @return An initialized foreground style layer.
+ */
+- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source NS_DESIGNATED_INITIALIZER;
+
+#pragma mark Specifying a Style Layer’s Content
+
+/**
+ Identifier of the source from which the receiver obtains the data to style.
+ */
+@property (nonatomic, readonly, nullable) NSString *sourceIdentifier;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLForegroundStyleLayer.m b/platform/darwin/src/MGLForegroundStyleLayer.m
new file mode 100644
index 0000000000..e3af963313
--- /dev/null
+++ b/platform/darwin/src/MGLForegroundStyleLayer.m
@@ -0,0 +1,13 @@
+#import "MGLForegroundStyleLayer.h"
+#import "MGLSource.h"
+
+@implementation MGLForegroundStyleLayer
+
+- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source {
+ if (self = [super initWithIdentifier:identifier]) {
+ _sourceIdentifier = source.identifier;
+ }
+ return self;
+}
+
+@end
diff --git a/platform/darwin/src/MGLGeoJSONSource.h b/platform/darwin/src/MGLGeoJSONSource.h
index da772108f1..9eeb1e1188 100644
--- a/platform/darwin/src/MGLGeoJSONSource.h
+++ b/platform/darwin/src/MGLGeoJSONSource.h
@@ -50,7 +50,6 @@ extern NSString * const MGLGeoJSONBufferOption;
*/
extern NSString * const MGLGeoJSONToleranceOption;
-
/**
A GeoJSON source.
@@ -59,77 +58,81 @@ extern NSString * const MGLGeoJSONToleranceOption;
*/
@interface MGLGeoJSONSource : MGLSource
-/**
- The contents of the source.
-
- If the receiver was initialized using `-initWithSourceIdentifier:URL:`, this
- property is set to `nil`. This property is unavailable until the receiver is
- passed into `-[MGLStyle addSource]`.
- */
-@property (nonatomic, readonly, nullable) NS_ARRAY_OF(id <MGLFeature>) *features;
+#pragma mark Initializing a Source
/**
- A GeoJSON representation of the contents of the source.
-
- Use the `features` property instead to get an object representation of the
- contents. Alternatively, use NSJSONSerialization with the value of this
- property to transform it into Foundation types.
+ Returns a GeoJSON source initialized with an identifier, GeoJSON data, and a
+ dictionary of options for the source according to the
+ <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson">style
+ specification</a>.
- If the receiver was initialized using `-initWithSourceIdentifier:URL:`, this
- property is set to `nil`. This property is unavailable until the receiver is
- passed into `-[MGLStyle addSource]`.
+ @param identifier A string that uniquely identifies the source.
+ @param geoJSONData An `NSData` object representing GeoJSON source code.
+ @param options An `NSDictionary` of options for this source.
+ @return An initialized GeoJSON source.
*/
-@property (nonatomic, readonly, nullable, copy) NSData *geoJSONData;
+- (instancetype)initWithIdentifier:(NSString *)identifier geoJSONData:(NSData *)data options:(nullable NS_DICTIONARY_OF(NSString *, id) *)options NS_DESIGNATED_INITIALIZER;
/**
- The URL to the GeoJSON document that specifies the contents of the source.
+ Returns a GeoJSON source with an identifier, URL, and dictionary of options for
+ the source according to the
+ <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson">style
+ specification</a>.
- If the receiver was initialized using `-initWithSourceIdentifier:geoJSONData:`,
- this property is set to `nil`.
+ @param identifier A string that uniquely identifies the source.
+ @param URL An HTTP(S) URL, absolute file URL, or local file URL relative to the
+ current application’s resource bundle.
+ @param options An `NSDictionary` of options for this source.
+ @return An initialized GeoJSON source.
*/
-@property (nonatomic, readonly, nullable) NSURL *URL;
+- (instancetype)initWithIdentifier:(NSString *)identifier URL:(NSURL *)url options:(nullable NS_DICTIONARY_OF(NSString *, id) *)options NS_DESIGNATED_INITIALIZER;
/**
- Initializes a source with the given identifier and GeoJSON data.
+ Returns a GeoJSON source with an identifier, features dictionary, and dictionary
+ of options for the source according to the
+ <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson">style
+ specification</a>.
- @param sourceIdentifier A string that uniquely identifies the source.
- @param geoJSONData An NSData object representing GeoJSON source code.
+ @param identifier A string that uniquely identifies the source.
+ @param features An array of features that conform to the `MGLFeature` protocol.
+ @param options An `NSDictionary` of options for this source.
+ @return An initialized GeoJSON source.
*/
-- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier geoJSONData:(NSData *)data NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithIdentifier:(NSString *)identifier features:(NSArray<id<MGLFeature>> *)features options:(nullable NS_DICTIONARY_OF(NSString *,id) *)options NS_DESIGNATED_INITIALIZER;
+
+#pragma mark Accessing a Source’s Content
/**
- Initializes a source with the given identifier, GeoJSON data, and a dictionary
- of options for the source as specified by the
- <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson">the
- style specification</a>.
-
- @param sourceIdentifier A string that uniquely identifies the source.
- @param geoJSONData An NSData object representing GeoJSON source code.
- @param options An NSDictionary of attributes for this source.
+ The contents of the source.
+
+ If the receiver was initialized using `-initWithIdentifier:URL:options:`, this property
+ is set to `nil`. This property is unavailable until the receiver is passed into
+ `-[MGLStyle addSource]`.
*/
-- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier geoJSONData:(NSData *)data options:(NS_DICTIONARY_OF(NSString *, id) *)options NS_DESIGNATED_INITIALIZER;
+@property (nonatomic, readonly, nullable) NS_ARRAY_OF(id <MGLFeature>) *features;
/**
- Initializes a source with the given identifier and URL.
+ A GeoJSON representation of the contents of the source.
- @param sourceIdentifier A string that uniquely identifies the source.
- @param URL An HTTP(S) URL, absolute file URL, or local file URL relative to the
- current application’s resource bundle.
+ Use the `features` property instead to get an object representation of the
+ contents. Alternatively, use NSJSONSerialization with the value of this
+ property to transform it into Foundation types.
+
+ If the receiver was initialized using `-initWithIdentifier:URL:options` or
+ `-initWithIdentifier:features:options`, this property is set to `nil`.
+ This property is unavailable until the receiver is passed
+ into `-[MGLStyle addSource]`.
*/
-- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier URL:(NSURL *)url NS_DESIGNATED_INITIALIZER;
+@property (nonatomic, readonly, nullable, copy) NSData *geoJSONData;
/**
- Initializes a source with the given identifier, a URL, and a dictionary of
- options for the source as specified by the
- <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-geojson">the
- style specification</a>.
-
- @param sourceIdentifier A string that uniquely identifies the source.
- @param URL An HTTP(S) URL, absolute file URL, or local file URL relative to the
- current application’s resource bundle.
- @param options An NSDictionary of attributes for this source.
+ The URL to the GeoJSON document that specifies the contents of the source.
+
+ If the receiver was initialized using `-initWithIdentifier:geoJSONData:options`, this
+ property is set to `nil`.
*/
-- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier URL:(NSURL *)url options:(NS_DICTIONARY_OF(NSString *, id) *)options NS_DESIGNATED_INITIALIZER;
+@property (nonatomic, readonly, nullable) NSURL *URL;
+
@end
diff --git a/platform/darwin/src/MGLGeoJSONSource.mm b/platform/darwin/src/MGLGeoJSONSource.mm
index 652644be47..27f2eb8bda 100644
--- a/platform/darwin/src/MGLGeoJSONSource.mm
+++ b/platform/darwin/src/MGLGeoJSONSource.mm
@@ -22,18 +22,9 @@ NSString * const MGLGeoJSONToleranceOption = @"MGLGeoJSONOptionsClusterTolerance
@implementation MGLGeoJSONSource
-- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier geoJSONData:(NSData *)data
+- (instancetype)initWithIdentifier:(NSString *)identifier geoJSONData:(NSData *)data options:(NS_DICTIONARY_OF(NSString *, id) *)options
{
- if (self = [super initWithSourceIdentifier:sourceIdentifier])
- {
- _geoJSONData = data;
- }
- return self;
-}
-
-- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier geoJSONData:(NSData *)data options:(NS_DICTIONARY_OF(NSString *, id) *)options
-{
- if (self = [super initWithSourceIdentifier:sourceIdentifier])
+ if (self = [super initWithIdentifier:identifier])
{
_geoJSONData = data;
_options = options;
@@ -41,22 +32,22 @@ NSString * const MGLGeoJSONToleranceOption = @"MGLGeoJSONOptionsClusterTolerance
return self;
}
-- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier URL:(NSURL *)url
+- (instancetype)initWithIdentifier:(NSString *)identifier URL:(NSURL *)url options:(NS_DICTIONARY_OF(NSString *, id) *)options
{
- if (self = [super initWithSourceIdentifier:sourceIdentifier])
+ if (self = [super initWithIdentifier:identifier])
{
_URL = url;
+ _options = options;
}
return self;
}
-- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier URL:(NSURL *)url options:(NS_DICTIONARY_OF(NSString *, id) *)options
-{
- if (self = [super initWithSourceIdentifier:sourceIdentifier])
- {
- _URL = url;
+- (instancetype)initWithIdentifier:(NSString *)identifier features:(NSArray<id<MGLFeature>> *)features options:(NS_DICTIONARY_OF(NSString *,id) *)options {
+ if (self = [super initWithIdentifier:identifier]) {
+ _features = features;
_options = options;
}
+
return self;
}
@@ -113,16 +104,25 @@ NSString * const MGLGeoJSONToleranceOption = @"MGLGeoJSONOptionsClusterTolerance
- (std::unique_ptr<mbgl::style::Source>)mbglSource
{
- auto source = std::make_unique<mbgl::style::GeoJSONSource>(self.sourceIdentifier.UTF8String, [self geoJSONOptions]);
+ auto source = std::make_unique<mbgl::style::GeoJSONSource>(self.identifier.UTF8String, self.geoJSONOptions);
if (self.URL) {
NSURL *url = self.URL.mgl_URLByStandardizingScheme;
source->setURL(url.absoluteString.UTF8String);
- } else {
+ } else if (self.geoJSONData) {
NSString *string = [[NSString alloc] initWithData:self.geoJSONData encoding:NSUTF8StringEncoding];
const auto geojson = mapbox::geojson::parse(string.UTF8String).get<mapbox::geojson::feature_collection>();
source->setGeoJSON(geojson);
_features = MGLFeaturesFromMBGLFeatures(geojson);
+ } else {
+ mbgl::FeatureCollection featureCollection;
+ featureCollection.reserve(self.features.count);
+ for (id <MGLFeaturePrivate> feature in self.features) {
+ featureCollection.push_back([feature mbglFeature]);
+ }
+ const auto geojson = mbgl::GeoJSON{featureCollection};
+ source->setGeoJSON(geojson);
+ _features = MGLFeaturesFromMBGLFeatures(featureCollection);
}
return std::move(source);
diff --git a/platform/darwin/src/MGLLineStyleLayer.h b/platform/darwin/src/MGLLineStyleLayer.h
index d0a341d024..663e927718 100644
--- a/platform/darwin/src/MGLLineStyleLayer.h
+++ b/platform/darwin/src/MGLLineStyleLayer.h
@@ -1,59 +1,65 @@
// This file is generated.
// Edit platform/darwin/scripts/generate-style-code.js, then run `make style-code-darwin`.
-#import "MGLStyleAttributeValue.h"
-#import "MGLBaseStyleLayer.h"
+#import "MGLStyleValue.h"
+#import "MGLVectorStyleLayer.h"
NS_ASSUME_NONNULL_BEGIN
/**
The display of line endings.
+
+ Values of this type are used in the `lineCap` property of `MGLLineStyleLayer`.
*/
-typedef NS_ENUM(NSUInteger, MGLLineStyleLayerLineCap) {
+typedef NS_ENUM(NSUInteger, MGLLineCap) {
/**
A cap with a squared-off end which is drawn to the exact endpoint of the line.
*/
- MGLLineStyleLayerLineCapButt,
+ MGLLineCapButt,
/**
A cap with a rounded end which is drawn beyond the endpoint of the line at a radius of one-half of the line's width and centered on the endpoint of the line.
*/
- MGLLineStyleLayerLineCapRound,
+ MGLLineCapRound,
/**
A cap with a squared-off end which is drawn beyond the endpoint of the line at a distance of one-half of the line's width.
*/
- MGLLineStyleLayerLineCapSquare,
+ MGLLineCapSquare,
};
/**
The display of lines when joining.
+
+ Values of this type are used in the `lineJoin` property of `MGLLineStyleLayer`.
*/
-typedef NS_ENUM(NSUInteger, MGLLineStyleLayerLineJoin) {
+typedef NS_ENUM(NSUInteger, MGLLineJoin) {
/**
A join with a squared-off end which is drawn beyond the endpoint of the line at a distance of one-half of the line's width.
*/
- MGLLineStyleLayerLineJoinBevel,
+ MGLLineJoinBevel,
/**
A join with a rounded end which is drawn beyond the endpoint of the line at a radius of one-half of the line's width and centered on the endpoint of the line.
*/
- MGLLineStyleLayerLineJoinRound,
+ MGLLineJoinRound,
/**
A join with a sharp, angled corner which is drawn with the outer sides beyond the endpoint of the path until they meet.
*/
- MGLLineStyleLayerLineJoinMiter,
+ MGLLineJoinMiter,
};
/**
Controls the translation reference point.
+
+ Values of this type are used in the `lineTranslateAnchor` property of `MGLLineStyleLayer`.
*/
-typedef NS_ENUM(NSUInteger, MGLLineStyleLayerLineTranslateAnchor) {
+typedef NS_ENUM(NSUInteger, MGLLineTranslateAnchor) {
/**
The line is translated relative to the map.
*/
- MGLLineStyleLayerLineTranslateAnchorMap,
+ MGLLineTranslateAnchorMap,
/**
The line is translated relative to the viewport.
*/
- MGLLineStyleLayerLineTranslateAnchorViewport,
+ MGLLineTranslateAnchorViewport,
};
/**
@@ -62,81 +68,69 @@ typedef NS_ENUM(NSUInteger, MGLLineStyleLayerLineTranslateAnchor) {
`MGLMapView` for its `style` and obtain existing layers using the
`-[MGLStyle layerWithIdentifier:]` method.
*/
-@interface MGLLineStyleLayer : MGLBaseStyleLayer <MGLStyleLayer>
-
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier source:(MGLSource *)source;
-
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier source:(MGLSource *)source sourceLayer:(NSString *)sourceLayer;
-
-/**
- A predicate that corresponds to the layer's <a href='https://www.mapbox.com/mapbox-gl-style-spec/#types-filter'>filter</a>.
-
- The predicate's left expression must be a string that identifies a feature
- property, or one of the special keys.
- */
-@property (nonatomic, nullable) NSPredicate *predicate;
+@interface MGLLineStyleLayer : MGLVectorStyleLayer
#pragma mark - Accessing the Layout Attributes
/**
The display of line endings.
- The default value of this property is an `NSValue` object containing `MGLLineStyleLayerLineCapButt`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLLineCapButt`. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> lineCap;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *lineCap;
/**
The display of lines when joining.
- The default value of this property is an `NSValue` object containing `MGLLineStyleLayerLineJoinMiter`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLLineJoinMiter`. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> lineJoin;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *lineJoin;
/**
Used to automatically convert miter joins to bevel joins for sharp angles.
- The default value of this property is an `NSNumber` object containing the float `2`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `2`. Set this property to `nil` to reset it to the default value.
- This property is only applied to the style if `lineJoin` is set to an `NSValue` object containing `MGLLineStyleLayerLineJoinMiter`. Otherwise, it is ignored.
+ This property is only applied to the style if `lineJoin` is set to an `MGLStyleValue` object containing an `NSValue` object containing `MGLLineJoinMiter`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> lineMiterLimit;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *lineMiterLimit;
/**
Used to automatically convert round joins to miter joins for shallow angles.
- The default value of this property is an `NSNumber` object containing the float `1.05`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `1.05`. Set this property to `nil` to reset it to the default value.
- This property is only applied to the style if `lineJoin` is set to an `NSValue` object containing `MGLLineStyleLayerLineJoinRound`. Otherwise, it is ignored.
+ This property is only applied to the style if `lineJoin` is set to an `MGLStyleValue` object containing an `NSValue` object containing `MGLLineJoinRound`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> lineRoundLimit;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *lineRoundLimit;
#pragma mark - Accessing the Paint Attributes
/**
The opacity at which the line will be drawn.
- The default value of this property is an `NSNumber` object containing the float `1`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `1`. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> lineOpacity;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *lineOpacity;
#if TARGET_OS_IPHONE
/**
The color with which the line will be drawn.
- The default value of this property is `UIColor.blackColor`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing `UIColor.blackColor`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `linePattern` is set to `nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> lineColor;
+@property (nonatomic, null_resettable) MGLStyleValue<MGLColor *> *lineColor;
#else
/**
The color with which the line will be drawn.
- The default value of this property is `NSColor.blackColor`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing `NSColor.blackColor`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `linePattern` is set to `nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> lineColor;
+@property (nonatomic, null_resettable) MGLStyleValue<MGLColor *> *lineColor;
#endif
/**
@@ -144,54 +138,54 @@ typedef NS_ENUM(NSUInteger, MGLLineStyleLayerLineTranslateAnchor) {
This property is measured in points.
- The default value of this property is an `NSValue` object containing a `CGVector` struct set to 0 points from the left and 0 points from the top. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing a `CGVector` struct set to 0 points from the left and 0 points from the top. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> lineTranslate;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *lineTranslate;
/**
Controls the translation reference point.
- The default value of this property is an `NSValue` object containing `MGLLineStyleLayerLineTranslateAnchorMap`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLLineTranslateAnchorMap`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `lineTranslate` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> lineTranslateAnchor;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *lineTranslateAnchor;
/**
Stroke thickness.
This property is measured in points.
- The default value of this property is an `NSNumber` object containing the float `1`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `1`. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> lineWidth;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *lineWidth;
/**
Draws a line casing outside of a line's actual path. Value indicates the width of the inner gap.
This property is measured in points.
- The default value of this property is an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> lineGapWidth;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *lineGapWidth;
/**
The line's offset. For linear features, a positive value offsets the line to the right, relative to the direction of the line, and a negative value to the left. For polygon features, a positive value results in an inset, and a negative value results in an outset.
This property is measured in points.
- The default value of this property is an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> lineOffset;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *lineOffset;
/**
Blur applied to the line, in points.
This property is measured in points.
- The default value of this property is an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> lineBlur;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *lineBlur;
/**
Specifies the lengths of the alternating dashes and gaps that form the dash pattern. The lengths are later scaled by the line width. To convert a dash length to points, multiply the length by the current line width.
@@ -200,12 +194,12 @@ typedef NS_ENUM(NSUInteger, MGLLineStyleLayerLineTranslateAnchor) {
This property is only applied to the style if `linePattern` is set to `nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> lineDasharray;
+@property (nonatomic, null_resettable) MGLStyleValue<NSArray<NSNumber *> *> *lineDasharray;
/**
Name of image in sprite to use for drawing image lines. For seamless patterns, image width must be a factor of two (2, 4, 8, ..., 512).
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> linePattern;
+@property (nonatomic, null_resettable) MGLStyleValue<NSString *> *linePattern;
@end
diff --git a/platform/darwin/src/MGLLineStyleLayer.mm b/platform/darwin/src/MGLLineStyleLayer.mm
index b35d3921f5..57724a0600 100644
--- a/platform/darwin/src/MGLLineStyleLayer.mm
+++ b/platform/darwin/src/MGLLineStyleLayer.mm
@@ -4,7 +4,7 @@
#import "MGLSource.h"
#import "NSPredicate+MGLAdditions.h"
#import "MGLStyleLayer_Private.h"
-#import "MGLStyleAttributeValue.h"
+#import "MGLStyleValue_Private.h"
#import "MGLLineStyleLayer.h"
#include <mbgl/style/layers/line_layer.hpp>
@@ -12,36 +12,28 @@
@interface MGLLineStyleLayer ()
@property (nonatomic) mbgl::style::LineLayer *layer;
-@property (nonatomic, readwrite) NSString *layerIdentifier;
-@property (nonatomic, readwrite) NSString *sourceIdentifier;
-@property (nonatomic, readwrite) NSString *sourceLayerIdentifier;
@end
@implementation MGLLineStyleLayer
-@synthesize mapView;
-
-
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier source:(MGLSource *)source
+- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source
{
- if (self = [super init]) {
- _layerIdentifier = layerIdentifier;
- _sourceIdentifier = source.sourceIdentifier;
- _layer = new mbgl::style::LineLayer(layerIdentifier.UTF8String, source.sourceIdentifier.UTF8String);
+ if (self = [super initWithIdentifier:identifier source:source]) {
+ _layer = new mbgl::style::LineLayer(identifier.UTF8String, source.identifier.UTF8String);
}
return self;
}
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier source:(MGLSource *)source sourceLayer:(NSString *)sourceLayer
+- (NSString *)sourceLayerIdentifier
{
- if (self = [super init]) {
- _layerIdentifier = layerIdentifier;
- _sourceIdentifier = source.sourceIdentifier;
- _layer = new mbgl::style::LineLayer(layerIdentifier.UTF8String, source.sourceIdentifier.UTF8String);
- _layer->setSourceLayer(sourceLayer.UTF8String);
- }
- return self;
+ auto layerID = self.layer->getSourceLayer();
+ return layerID.empty() ? nil : @(layerID.c_str());
+}
+
+- (void)setSourceLayerIdentifier:(NSString *)sourceLayerIdentifier
+{
+ self.layer->setSourceLayer(sourceLayerIdentifier.UTF8String ?: "");
}
- (void)setPredicate:(NSPredicate *)predicate
@@ -56,118 +48,146 @@
#pragma mark - Accessing the Layout Attributes
-- (void)setLineCap:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)lineCap {
- MGLSetEnumProperty(lineCap, LineCap, LineCapType, MGLLineStyleLayerLineCap);
+- (void)setLineCap:(MGLStyleValue<NSValue *> *)lineCap {
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::LineCapType, NSValue *>().toPropertyValue(lineCap);
+ self.layer->setLineCap(mbglValue);
}
-- (id <MGLStyleAttributeValue>)lineCap {
- MGLGetEnumProperty(LineCap, LineCapType, MGLLineStyleLayerLineCap);
+- (MGLStyleValue<NSValue *> *)lineCap {
+ auto propertyValue = self.layer->getLineCap() ?: self.layer->getDefaultLineCap();
+ return MGLStyleValueTransformer<mbgl::style::LineCapType, NSValue *>().toStyleValue(propertyValue);
}
-- (void)setLineJoin:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)lineJoin {
- MGLSetEnumProperty(lineJoin, LineJoin, LineJoinType, MGLLineStyleLayerLineJoin);
+- (void)setLineJoin:(MGLStyleValue<NSValue *> *)lineJoin {
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::LineJoinType, NSValue *>().toPropertyValue(lineJoin);
+ self.layer->setLineJoin(mbglValue);
}
-- (id <MGLStyleAttributeValue>)lineJoin {
- MGLGetEnumProperty(LineJoin, LineJoinType, MGLLineStyleLayerLineJoin);
+- (MGLStyleValue<NSValue *> *)lineJoin {
+ auto propertyValue = self.layer->getLineJoin() ?: self.layer->getDefaultLineJoin();
+ return MGLStyleValueTransformer<mbgl::style::LineJoinType, NSValue *>().toStyleValue(propertyValue);
}
-- (void)setLineMiterLimit:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)lineMiterLimit {
- self.layer->setLineMiterLimit(lineMiterLimit.mbgl_floatPropertyValue);
+- (void)setLineMiterLimit:(MGLStyleValue<NSNumber *> *)lineMiterLimit {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(lineMiterLimit);
+ self.layer->setLineMiterLimit(mbglValue);
}
-- (id <MGLStyleAttributeValue>)lineMiterLimit {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getLineMiterLimit() ?: self.layer->getDefaultLineMiterLimit()];
+- (MGLStyleValue<NSNumber *> *)lineMiterLimit {
+ auto propertyValue = self.layer->getLineMiterLimit() ?: self.layer->getDefaultLineMiterLimit();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setLineRoundLimit:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)lineRoundLimit {
- self.layer->setLineRoundLimit(lineRoundLimit.mbgl_floatPropertyValue);
+- (void)setLineRoundLimit:(MGLStyleValue<NSNumber *> *)lineRoundLimit {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(lineRoundLimit);
+ self.layer->setLineRoundLimit(mbglValue);
}
-- (id <MGLStyleAttributeValue>)lineRoundLimit {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getLineRoundLimit() ?: self.layer->getDefaultLineRoundLimit()];
+- (MGLStyleValue<NSNumber *> *)lineRoundLimit {
+ auto propertyValue = self.layer->getLineRoundLimit() ?: self.layer->getDefaultLineRoundLimit();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
#pragma mark - Accessing the Paint Attributes
-- (void)setLineOpacity:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)lineOpacity {
- self.layer->setLineOpacity(lineOpacity.mbgl_floatPropertyValue);
+- (void)setLineOpacity:(MGLStyleValue<NSNumber *> *)lineOpacity {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(lineOpacity);
+ self.layer->setLineOpacity(mbglValue);
}
-- (id <MGLStyleAttributeValue>)lineOpacity {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getLineOpacity() ?: self.layer->getDefaultLineOpacity()];
+- (MGLStyleValue<NSNumber *> *)lineOpacity {
+ auto propertyValue = self.layer->getLineOpacity() ?: self.layer->getDefaultLineOpacity();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setLineColor:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)lineColor {
- self.layer->setLineColor(lineColor.mbgl_colorPropertyValue);
+- (void)setLineColor:(MGLStyleValue<MGLColor *> *)lineColor {
+ auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue(lineColor);
+ self.layer->setLineColor(mbglValue);
}
-- (id <MGLStyleAttributeValue>)lineColor {
- return [MGLStyleAttribute mbgl_colorWithPropertyValueColor:self.layer->getLineColor() ?: self.layer->getDefaultLineColor()];
+- (MGLStyleValue<MGLColor *> *)lineColor {
+ auto propertyValue = self.layer->getLineColor() ?: self.layer->getDefaultLineColor();
+ return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(propertyValue);
}
-- (void)setLineTranslate:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)lineTranslate {
- self.layer->setLineTranslate(lineTranslate.mbgl_offsetPropertyValue);
+- (void)setLineTranslate:(MGLStyleValue<NSValue *> *)lineTranslate {
+ auto mbglValue = MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toPropertyValue(lineTranslate);
+ self.layer->setLineTranslate(mbglValue);
}
-- (id <MGLStyleAttributeValue>)lineTranslate {
- return [MGLStyleAttribute mbgl_offsetWithPropertyValueOffset:self.layer->getLineTranslate() ?: self.layer->getDefaultLineTranslate()];
+- (MGLStyleValue<NSValue *> *)lineTranslate {
+ auto propertyValue = self.layer->getLineTranslate() ?: self.layer->getDefaultLineTranslate();
+ return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toStyleValue(propertyValue);
}
-- (void)setLineTranslateAnchor:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)lineTranslateAnchor {
- MGLSetEnumProperty(lineTranslateAnchor, LineTranslateAnchor, TranslateAnchorType, MGLLineStyleLayerLineTranslateAnchor);
+- (void)setLineTranslateAnchor:(MGLStyleValue<NSValue *> *)lineTranslateAnchor {
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *>().toPropertyValue(lineTranslateAnchor);
+ self.layer->setLineTranslateAnchor(mbglValue);
}
-- (id <MGLStyleAttributeValue>)lineTranslateAnchor {
- MGLGetEnumProperty(LineTranslateAnchor, TranslateAnchorType, MGLLineStyleLayerLineTranslateAnchor);
+- (MGLStyleValue<NSValue *> *)lineTranslateAnchor {
+ auto propertyValue = self.layer->getLineTranslateAnchor() ?: self.layer->getDefaultLineTranslateAnchor();
+ return MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *>().toStyleValue(propertyValue);
}
-- (void)setLineWidth:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)lineWidth {
- self.layer->setLineWidth(lineWidth.mbgl_floatPropertyValue);
+- (void)setLineWidth:(MGLStyleValue<NSNumber *> *)lineWidth {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(lineWidth);
+ self.layer->setLineWidth(mbglValue);
}
-- (id <MGLStyleAttributeValue>)lineWidth {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getLineWidth() ?: self.layer->getDefaultLineWidth()];
+- (MGLStyleValue<NSNumber *> *)lineWidth {
+ auto propertyValue = self.layer->getLineWidth() ?: self.layer->getDefaultLineWidth();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setLineGapWidth:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)lineGapWidth {
- self.layer->setLineGapWidth(lineGapWidth.mbgl_floatPropertyValue);
+- (void)setLineGapWidth:(MGLStyleValue<NSNumber *> *)lineGapWidth {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(lineGapWidth);
+ self.layer->setLineGapWidth(mbglValue);
}
-- (id <MGLStyleAttributeValue>)lineGapWidth {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getLineGapWidth() ?: self.layer->getDefaultLineGapWidth()];
+- (MGLStyleValue<NSNumber *> *)lineGapWidth {
+ auto propertyValue = self.layer->getLineGapWidth() ?: self.layer->getDefaultLineGapWidth();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setLineOffset:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)lineOffset {
- self.layer->setLineOffset(lineOffset.mbgl_floatPropertyValue);
+- (void)setLineOffset:(MGLStyleValue<NSNumber *> *)lineOffset {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(lineOffset);
+ self.layer->setLineOffset(mbglValue);
}
-- (id <MGLStyleAttributeValue>)lineOffset {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getLineOffset() ?: self.layer->getDefaultLineOffset()];
+- (MGLStyleValue<NSNumber *> *)lineOffset {
+ auto propertyValue = self.layer->getLineOffset() ?: self.layer->getDefaultLineOffset();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setLineBlur:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)lineBlur {
- self.layer->setLineBlur(lineBlur.mbgl_floatPropertyValue);
+- (void)setLineBlur:(MGLStyleValue<NSNumber *> *)lineBlur {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(lineBlur);
+ self.layer->setLineBlur(mbglValue);
}
-- (id <MGLStyleAttributeValue>)lineBlur {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getLineBlur() ?: self.layer->getDefaultLineBlur()];
+- (MGLStyleValue<NSNumber *> *)lineBlur {
+ auto propertyValue = self.layer->getLineBlur() ?: self.layer->getDefaultLineBlur();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setLineDasharray:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)lineDasharray {
- self.layer->setLineDasharray(lineDasharray.mbgl_numberArrayPropertyValue);
+- (void)setLineDasharray:(MGLStyleValue<NSArray<NSNumber *> *> *)lineDasharray {
+ auto mbglValue = MGLStyleValueTransformer<std::vector<float>, NSArray<NSNumber *> *, float>().toPropertyValue(lineDasharray);
+ self.layer->setLineDasharray(mbglValue);
}
-- (id <MGLStyleAttributeValue>)lineDasharray {
- return [MGLStyleAttribute mbgl_numberArrayWithPropertyValueNumberArray:self.layer->getLineDasharray() ?: self.layer->getDefaultLineDasharray()];
+- (MGLStyleValue<NSArray<NSNumber *> *> *)lineDasharray {
+ auto propertyValue = self.layer->getLineDasharray() ?: self.layer->getDefaultLineDasharray();
+ return MGLStyleValueTransformer<std::vector<float>, NSArray<NSNumber *> *, float>().toStyleValue(propertyValue);
}
-- (void)setLinePattern:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)linePattern {
- self.layer->setLinePattern(linePattern.mbgl_stringPropertyValue);
+- (void)setLinePattern:(MGLStyleValue<NSString *> *)linePattern {
+ auto mbglValue = MGLStyleValueTransformer<std::string, NSString *>().toPropertyValue(linePattern);
+ self.layer->setLinePattern(mbglValue);
}
-- (id <MGLStyleAttributeValue>)linePattern {
- return [MGLStyleAttribute mbgl_stringWithPropertyValueString:self.layer->getLinePattern() ?: self.layer->getDefaultLinePattern()];
+- (MGLStyleValue<NSString *> *)linePattern {
+ auto propertyValue = self.layer->getLinePattern() ?: self.layer->getDefaultLinePattern();
+ return MGLStyleValueTransformer<std::string, NSString *>().toStyleValue(propertyValue);
}
@end
diff --git a/platform/darwin/src/MGLMultiPoint.h b/platform/darwin/src/MGLMultiPoint.h
index 69c7295842..b936205ab2 100644
--- a/platform/darwin/src/MGLMultiPoint.h
+++ b/platform/darwin/src/MGLMultiPoint.h
@@ -6,16 +6,25 @@
NS_ASSUME_NONNULL_BEGIN
/**
- The `MGLMultiPoint` class is an abstract superclass used to define shapes
- composed of multiple points. You should not create instances of this class
- directly. Instead, you should create instances of the `MGLPolyline` or
- `MGLPolygon` classes. However, you can use the method and properties of this
- class to access information about the specific points associated with the line
- or polygon.
+ The `MGLMultiPoint` class is used to define shapes composed of multiple points.
+ This class is also the superclass of `MGLPolyline` and `MGLPolygon`. The
+ methods and properties of this class can be used to access information about
+ the specific points associated with a line or polygon.
*/
@interface MGLMultiPoint : MGLShape
/**
+ Creates and returns an `MGLMultiPoint` object from the specified set of
+ coordinates.
+
+ @param coords The array of coordinates defining the shape. The data in this
+ array is copied to the new object.
+ @param count The number of items in the `coords` array.
+ @return A new multipoint object.
+ */
++ (instancetype)multiPointWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count NS_SWIFT_NAME(multiPoint(coordinates:count:));
+
+/**
The array of coordinates associated with the shape.
This C array is a pointer to a structure inside the multipoint object,
diff --git a/platform/darwin/src/MGLMultiPoint.mm b/platform/darwin/src/MGLMultiPoint.mm
index 17a61ed081..0090c5e35f 100644
--- a/platform/darwin/src/MGLMultiPoint.mm
+++ b/platform/darwin/src/MGLMultiPoint.mm
@@ -18,6 +18,11 @@ mbgl::Color MGLColorObjectFromCGColorRef(CGColorRef cgColor)
MGLCoordinateBounds _bounds;
}
++ (instancetype)multiPointWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count
+{
+ return [[self alloc] initWithCoordinates:coords count:count];
+}
+
- (instancetype)initWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count
{
self = [super init];
@@ -141,6 +146,29 @@ mbgl::Color MGLColorObjectFromCGColorRef(CGColorRef cgColor)
return mbgl::SymbolAnnotation({mbgl::Point<double>()});
}
+- (mbgl::Feature)featureObject
+{
+ mbgl::MultiPoint<double> multiPoint;
+ multiPoint.reserve(self.pointCount);
+ for (NSInteger i = 0; i< self.pointCount; i++)
+ {
+ multiPoint.push_back(mbgl::Point<double>(self.coordinates[i].longitude, self.coordinates[i].latitude));
+ }
+ return mbgl::Feature {multiPoint};
+}
+
+- (NSDictionary *)geoJSONDictionary
+{
+ NSMutableArray *coordinates = [[NSMutableArray alloc] initWithCapacity:self.pointCount];
+ for (NSUInteger index = 0; index < self.pointCount; index++) {
+ CLLocationCoordinate2D coordinate = self.coordinates[index];
+ [coordinates addObject:@[@(coordinate.longitude), @(coordinate.latitude)]];
+ }
+
+ return @{@"type": @"MultiPoint",
+ @"coordinates": coordinates};
+}
+
- (NSString *)description
{
return [NSString stringWithFormat:@"<%@: %p; count = %lu; bounds = %@>",
diff --git a/platform/darwin/src/MGLMultiPoint_Private.h b/platform/darwin/src/MGLMultiPoint_Private.h
index dc39172723..7bc3cae58a 100644
--- a/platform/darwin/src/MGLMultiPoint_Private.h
+++ b/platform/darwin/src/MGLMultiPoint_Private.h
@@ -3,6 +3,7 @@
#import "MGLGeometry.h"
#import <mbgl/annotation/annotation.hpp>
+#import <mbgl/util/feature.hpp>
#import <vector>
#import <CoreGraphics/CoreGraphics.h>
diff --git a/platform/darwin/src/MGLNetworkConfiguration.h b/platform/darwin/src/MGLNetworkConfiguration.h
new file mode 100644
index 0000000000..4e22fa294c
--- /dev/null
+++ b/platform/darwin/src/MGLNetworkConfiguration.h
@@ -0,0 +1,11 @@
+#import <Foundation/Foundation.h>
+
+@interface MGLNetworkConfiguration : NSObject
+
+/// Returns the shared instance of the `MGLNetworkConfiguration` class.
++ (instancetype)sharedManager;
+
+/// The current API base URL.
+@property (atomic) NSURL *apiBaseURL;
+
+@end
diff --git a/platform/darwin/src/MGLNetworkConfiguration.m b/platform/darwin/src/MGLNetworkConfiguration.m
new file mode 100644
index 0000000000..d661d9090e
--- /dev/null
+++ b/platform/darwin/src/MGLNetworkConfiguration.m
@@ -0,0 +1,43 @@
+#import "MGLNetworkConfiguration.h"
+#import "NSProcessInfo+MGLAdditions.h"
+
+@implementation MGLNetworkConfiguration
+
++ (void)load {
+ // Read the initial configuration from Info.plist.
+ NSString *apiBaseURL = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"MGLMapboxAPIBaseURL"];
+ if (apiBaseURL.length) {
+ [self setAPIBaseURL:[NSURL URLWithString:apiBaseURL]];
+ }
+}
+
++ (instancetype)sharedManager {
+ if (NSProcessInfo.processInfo.mgl_isInterfaceBuilderDesignablesAgent) {
+ return nil;
+ }
+ static dispatch_once_t onceToken;
+ static MGLNetworkConfiguration *_sharedManager;
+ void (^setupBlock)() = ^{
+ dispatch_once(&onceToken, ^{
+ _sharedManager = [[self alloc] init];
+ });
+ };
+ if (![[NSThread currentThread] isMainThread]) {
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ setupBlock();
+ });
+ } else {
+ setupBlock();
+ }
+ return _sharedManager;
+}
+
++ (void)setAPIBaseURL:(NSURL *)apiBaseURL {
+ [MGLNetworkConfiguration sharedManager].apiBaseURL = apiBaseURL;
+}
+
++ (NSURL *)apiBaseURL {
+ return [MGLNetworkConfiguration sharedManager].apiBaseURL;
+}
+
+@end
diff --git a/platform/darwin/src/MGLOfflineStorage.mm b/platform/darwin/src/MGLOfflineStorage.mm
index f279235ca0..5f284b76a1 100644
--- a/platform/darwin/src/MGLOfflineStorage.mm
+++ b/platform/darwin/src/MGLOfflineStorage.mm
@@ -2,6 +2,7 @@
#import "MGLAccountManager_Private.h"
#import "MGLGeometry_Private.h"
+#import "MGLNetworkConfiguration.h"
#import "MGLOfflinePack_Private.h"
#import "MGLOfflineRegion_Private.h"
#import "MGLTilePyramidOfflineRegion.h"
@@ -127,6 +128,13 @@ NSString * const MGLOfflinePackMaximumCountUserInfoKey = @"MaximumCount";
_mbglFileSource = new mbgl::DefaultFileSource(cachePath.UTF8String, [NSBundle mainBundle].resourceURL.path.UTF8String);
+ // Observe for changes to the API base URL (and find out the current one).
+ [[MGLNetworkConfiguration sharedManager] addObserver:self
+ forKeyPath:@"apiBaseURL"
+ options:(NSKeyValueObservingOptionInitial |
+ NSKeyValueObservingOptionNew)
+ context:NULL];
+
// Observe for changes to the global access token (and find out the current one).
[[MGLAccountManager sharedManager] addObserver:self
forKeyPath:@"accessToken"
@@ -147,6 +155,7 @@ NSString * const MGLOfflinePackMaximumCountUserInfoKey = @"MaximumCount";
}
- (void)dealloc {
+ [[MGLNetworkConfiguration sharedManager] removeObserver:self forKeyPath:@"apiBaseURL"];
[[MGLAccountManager sharedManager] removeObserver:self forKeyPath:@"accessToken"];
for (MGLOfflinePack *pack in self.packs) {
@@ -164,6 +173,13 @@ NSString * const MGLOfflinePackMaximumCountUserInfoKey = @"MaximumCount";
if (![accessToken isKindOfClass:[NSNull class]]) {
self.mbglFileSource->setAccessToken(accessToken.UTF8String);
}
+ } else if ([keyPath isEqualToString:@"apiBaseURL"] && object == [MGLNetworkConfiguration sharedManager]) {
+ NSURL *apiBaseURL = change[NSKeyValueChangeNewKey];
+ if ([apiBaseURL isKindOfClass:[NSNull class]]) {
+ self.mbglFileSource->setAPIBaseURL(mbgl::util::API_BASE_URL);
+ } else {
+ self.mbglFileSource->setAPIBaseURL(apiBaseURL.absoluteString.UTF8String);
+ }
} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
diff --git a/platform/darwin/src/MGLPointAnnotation.m b/platform/darwin/src/MGLPointAnnotation.mm
index 9495a2c6f8..ce8e4a2355 100644
--- a/platform/darwin/src/MGLPointAnnotation.m
+++ b/platform/darwin/src/MGLPointAnnotation.mm
@@ -1,5 +1,10 @@
#import "MGLPointAnnotation.h"
+#import "MGLShape_Private.h"
+
+#import <mbgl/util/geometry.hpp>
+
+
@implementation MGLPointAnnotation
@synthesize coordinate;
@@ -13,4 +18,17 @@
coordinate.latitude, coordinate.longitude];
}
+- (NSDictionary *)geoJSONDictionary
+{
+ return @{@"type": @"Point",
+ @"coordinates": @[@(self.coordinate.longitude), @(self.coordinate.latitude)]};
+}
+
+- (mbgl::Feature)featureObject
+{
+ mbgl::Point<double> point = { self.coordinate.longitude, self.coordinate.latitude };
+ return mbgl::Feature {point};
+}
+
@end
+
diff --git a/platform/darwin/src/MGLPolygon+MGLAdditions.h b/platform/darwin/src/MGLPolygon+MGLAdditions.h
new file mode 100644
index 0000000000..f409fb96ca
--- /dev/null
+++ b/platform/darwin/src/MGLPolygon+MGLAdditions.h
@@ -0,0 +1,7 @@
+#import <Mapbox/Mapbox.h>
+
+@interface MGLPolygon (MGLAdditions)
+
+- (NS_ARRAY_OF(id) *)mgl_coordinates;
+
+@end
diff --git a/platform/darwin/src/MGLPolygon+MGLAdditions.m b/platform/darwin/src/MGLPolygon+MGLAdditions.m
new file mode 100644
index 0000000000..def4687016
--- /dev/null
+++ b/platform/darwin/src/MGLPolygon+MGLAdditions.m
@@ -0,0 +1,27 @@
+#import "MGLPolygon+MGLAdditions.h"
+
+@implementation MGLPolygon (MGLAdditions)
+
+- (NS_ARRAY_OF(id) *)mgl_coordinates {
+ NSMutableArray *coordinates = [NSMutableArray array];
+
+ NSMutableArray *exteriorRing = [NSMutableArray array];
+ for (NSUInteger index = 0; index < self.pointCount; index++) {
+ CLLocationCoordinate2D coordinate = self.coordinates[index];
+ [exteriorRing addObject:@[@(coordinate.longitude), @(coordinate.latitude)]];
+ }
+ [coordinates addObject:exteriorRing];
+
+ for (MGLPolygon *interiorPolygon in self.interiorPolygons) {
+ NSMutableArray *interiorRing = [NSMutableArray array];
+ for (int index = 0; index < interiorPolygon.pointCount; index++) {
+ CLLocationCoordinate2D coordinate = interiorPolygon.coordinates[index];
+ [interiorRing addObject:@[@(coordinate.longitude), @(coordinate.latitude)]];
+ }
+ [coordinates addObject:interiorRing];
+ }
+
+ return [coordinates copy];
+}
+
+@end
diff --git a/platform/darwin/src/MGLPolygon.h b/platform/darwin/src/MGLPolygon.h
index 3d5b36abb6..6d53356ba4 100644
--- a/platform/darwin/src/MGLPolygon.h
+++ b/platform/darwin/src/MGLPolygon.h
@@ -36,7 +36,7 @@ NS_ASSUME_NONNULL_BEGIN
@param count The number of items in the `coords` array.
@return A new polygon object.
*/
-+ (instancetype)polygonWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count;
++ (instancetype)polygonWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count NS_SWIFT_NAME(polygon(coordinates:count:));
/**
Creates and returns an `MGLPolygon` object from the specified set of
diff --git a/platform/darwin/src/MGLPolygon.mm b/platform/darwin/src/MGLPolygon.mm
index b8f02b6406..eae2cfe75a 100644
--- a/platform/darwin/src/MGLPolygon.mm
+++ b/platform/darwin/src/MGLPolygon.mm
@@ -3,6 +3,8 @@
#import "MGLMultiPoint_Private.h"
#import "MGLGeometry_Private.h"
+#import "MGLPolygon+MGLAdditions.h"
+
@implementation MGLPolygon
@dynamic overlayBounds;
@@ -36,6 +38,15 @@
return result;
}
+- (mbgl::Feature)featureObject {
+ mbgl::Polygon<double> geometry;
+ geometry.push_back(self.ring);
+ for (MGLPolygon *polygon in self.interiorPolygons) {
+ geometry.push_back(polygon.ring);
+ }
+ return mbgl::Feature{geometry};
+}
+
- (mbgl::Annotation)annotationObjectWithDelegate:(id <MGLMultiPointDelegate>)delegate {
mbgl::Polygon<double> geometry;
geometry.push_back(self.ring);
@@ -51,6 +62,11 @@
return annotation;
}
+- (NSDictionary *)geoJSONDictionary {
+ return @{@"type": @"Polygon",
+ @"coordinates": self.mgl_coordinates};
+}
+
@end
@interface MGLMultiPolygon ()
@@ -87,4 +103,27 @@
return MGLLatLngBoundsFromCoordinateBounds(_overlayBounds).intersects(MGLLatLngBoundsFromCoordinateBounds(overlayBounds));
}
+- (mbgl::Feature)featureObject {
+ mbgl::MultiPolygon<double> multiPolygon;
+ multiPolygon.reserve(self.polygons.count);
+ for (MGLPolygon *polygon in self.polygons) {
+ mbgl::Polygon<double> geometry;
+ geometry.push_back(polygon.ring);
+ for (MGLPolygon *interiorPolygon in polygon.interiorPolygons) {
+ geometry.push_back(interiorPolygon.ring);
+ }
+ multiPolygon.push_back(geometry);
+ }
+ return mbgl::Feature {multiPolygon};
+}
+
+- (NSDictionary *)geoJSONDictionary {
+ NSMutableArray *coordinates = [[NSMutableArray alloc] initWithCapacity:self.polygons.count];
+ for (MGLPolygonFeature *feature in self.polygons) {
+ [coordinates addObject: feature.mgl_coordinates];
+ }
+ return @{@"type": @"MultiPolygon",
+ @"coordinates": coordinates};
+}
+
@end
diff --git a/platform/darwin/src/MGLPolyline+MGLAdditions.h b/platform/darwin/src/MGLPolyline+MGLAdditions.h
new file mode 100644
index 0000000000..4cdbbf17f9
--- /dev/null
+++ b/platform/darwin/src/MGLPolyline+MGLAdditions.h
@@ -0,0 +1,7 @@
+#import <Mapbox/Mapbox.h>
+
+@interface MGLPolyline (MGLAdditions)
+
+- (NS_ARRAY_OF(id) *)mgl_coordinates;
+
+@end
diff --git a/platform/darwin/src/MGLPolyline+MGLAdditions.m b/platform/darwin/src/MGLPolyline+MGLAdditions.m
new file mode 100644
index 0000000000..d1db2c58a0
--- /dev/null
+++ b/platform/darwin/src/MGLPolyline+MGLAdditions.m
@@ -0,0 +1,14 @@
+#import "MGLPolyline+MGLAdditions.h"
+
+@implementation MGLPolyline (MGLAdditions)
+
+- (NS_ARRAY_OF(id) *)mgl_coordinates {
+ NSMutableArray *coordinates = [[NSMutableArray alloc] initWithCapacity:self.pointCount];
+ for (NSUInteger index = 0; index < self.pointCount; index++) {
+ CLLocationCoordinate2D coordinate = self.coordinates[index];
+ [coordinates addObject:@[@(coordinate.longitude), @(coordinate.latitude)]];
+ }
+ return [coordinates copy];
+}
+
+@end
diff --git a/platform/darwin/src/MGLPolyline.h b/platform/darwin/src/MGLPolyline.h
index 78d9649751..6642afef7e 100644
--- a/platform/darwin/src/MGLPolyline.h
+++ b/platform/darwin/src/MGLPolyline.h
@@ -25,8 +25,7 @@ NS_ASSUME_NONNULL_BEGIN
@param count The number of items in the `coords` array.
@return A new polyline object.
*/
-+ (instancetype)polylineWithCoordinates:(CLLocationCoordinate2D *)coords
- count:(NSUInteger)count;
++ (instancetype)polylineWithCoordinates:(CLLocationCoordinate2D *)coords count:(NSUInteger)count NS_SWIFT_NAME(polyline(coordinates:count:));
@end
diff --git a/platform/darwin/src/MGLPolyline.mm b/platform/darwin/src/MGLPolyline.mm
index b81147a3ba..dd2fccf53d 100644
--- a/platform/darwin/src/MGLPolyline.mm
+++ b/platform/darwin/src/MGLPolyline.mm
@@ -3,6 +3,8 @@
#import "MGLMultiPoint_Private.h"
#import "MGLGeometry_Private.h"
+#import "MGLPolyline+MGLAdditions.h"
+
@implementation MGLPolyline
@dynamic overlayBounds;
@@ -13,17 +15,21 @@
return [[self alloc] initWithCoordinates:coords count:count];
}
-- (mbgl::Annotation)annotationObjectWithDelegate:(id <MGLMultiPointDelegate>)delegate {
+- (mbgl::LineString<double>)lineString {
NSUInteger count = self.pointCount;
CLLocationCoordinate2D *coordinates = self.coordinates;
-
+
mbgl::LineString<double> geometry;
geometry.reserve(self.pointCount);
for (NSUInteger i = 0; i < count; i++) {
geometry.push_back(mbgl::Point<double>(coordinates[i].longitude, coordinates[i].latitude));
}
+
+ return geometry;
+}
- mbgl::LineAnnotation annotation { geometry };
+- (mbgl::Annotation)annotationObjectWithDelegate:(id <MGLMultiPointDelegate>)delegate {
+ mbgl::LineAnnotation annotation { [self lineString] };
annotation.opacity = { static_cast<float>([delegate alphaForShapeAnnotation:self]) };
annotation.color = { [delegate strokeColorForShapeAnnotation:self] };
annotation.width = { static_cast<float>([delegate lineWidthForPolylineAnnotation:self]) };
@@ -31,6 +37,15 @@
return annotation;
}
+- (mbgl::Feature)featureObject {
+ return mbgl::Feature {[self lineString]};
+}
+
+- (NSDictionary *)geoJSONDictionary {
+ return @{@"type": @"LineString",
+ @"coordinates": self.mgl_coordinates};
+}
+
@end
@interface MGLMultiPolyline ()
@@ -67,4 +82,22 @@
return MGLLatLngBoundsFromCoordinateBounds(_overlayBounds).intersects(MGLLatLngBoundsFromCoordinateBounds(overlayBounds));
}
+- (mbgl::Feature)featureObject {
+ mbgl::MultiLineString<double> multiLineString;
+ multiLineString.reserve(self.polylines.count);
+ for (MGLPolyline *polyline in self.polylines) {
+ multiLineString.push_back([polyline lineString]);
+ }
+ return mbgl::Feature {multiLineString};
+}
+
+- (NSDictionary *)geoJSONDictionary {
+ NSMutableArray *coordinates = [NSMutableArray array];
+ for (MGLPolylineFeature *feature in self.polylines) {
+ [coordinates addObject: feature.mgl_coordinates];
+ }
+ return @{@"type": @"MultiLineString",
+ @"coordinates": coordinates};
+}
+
@end
diff --git a/platform/darwin/src/MGLRasterSource.h b/platform/darwin/src/MGLRasterSource.h
index bf561df8da..78f5af8a6a 100644
--- a/platform/darwin/src/MGLRasterSource.h
+++ b/platform/darwin/src/MGLRasterSource.h
@@ -15,9 +15,49 @@ NS_ASSUME_NONNULL_BEGIN
*/
@interface MGLRasterSource : MGLSource
+#pragma mark Initializing a Source
+
+/**
+ Returns a raster source initialized with an identifier, TileJSON configuration
+ URL, and tile size.
+
+ After initializing and configuring the source, add it to a map view’s style
+ using the `-[MGLStyle addSource:]` method.
+
+ @param identifier A string that uniquely identifies the source in the style to
+ which it is added.
+ @param url A URL to a TileJSON configuration file describing the source’s
+ contents and other metadata.
+ @param tileSize The height and width (measured in points) at which to display
+ each tile in this source when the map’s zoom level is an integer.
+ @return An initialized raster source.
+ */
+- (instancetype)initWithIdentifier:(NSString *)identifier URL:(NSURL *)url tileSize:(CGFloat)tileSize NS_DESIGNATED_INITIALIZER;
+
+/**
+ Returns a raster source initialized with the given identifier, tile size, and
+ tile set.
+
+ After initializing and configuring the source, add it to a map view’s style
+ using the `-[MGLStyle addSource:]` method.
+
+ @param identifier A string that uniquely identifies the source in the style to
+ which it is added.
+ @param tileSet A tile set describing the source’s contents and other metadata.
+ @param tileSize The height and width (measured in points) at which to display
+ each tile in this source when the map’s zoom level is an integer.
+ @return An initialized raster source.
+ */
+- (instancetype)initWithIdentifier:(NSString *)identifier tileSet:(MGLTileSet *)tileSet tileSize:(CGFloat)tileSize NS_DESIGNATED_INITIALIZER;
+
+#pragma mark Accessing a Source’s Content
+
/**
- A URL to a TileJSON resource. Supported protocols are `http:`, `https:`, and
- `mapbox://<mapid>`.
+ A URL to a TileJSON configuration file describing the source’s contents and
+ other metadata.
+
+ The URL may be a full HTTP or HTTPS URL or a Mapbox URL indicating the tile
+ set’s map ID (`mapbox://<mapid>`).
@see <a href="https://www.mapbox.com/help/an-open-platform/#tilejson">The
TileJSON specification.</a>
@@ -25,8 +65,12 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readonly, copy) NSURL *URL;
/**
- The minimum visual size to display tiles for this source. Units in pixels.
- Defaults to `512` on each tile side.
+ The height and width (measured in points) at which to display each tile in this
+ source when the map’s zoom level is an integer.
+
+ A tile may be scaled up or down when the zoom level is between two integers.
+
+ The default value of this property is 512 points.
*/
@property (nonatomic, readonly, assign) NSUInteger tileSize;
@@ -40,26 +84,6 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (nonatomic, readonly, nullable) MGLTileSet *tileSet;
-/**
- Initializes a source with the given identifier, TileJSON configuration
- URL, and tile size.
-
- @param sourceIdentifier A string that uniquely identifies the source.
- @param url A URL to a TileJSON resource.
- @param tileSize The minimum visual size to display tiles for the source.
- */
-- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier URL:(NSURL *)url tileSize:(CGFloat)tileSize;
-
-/**
- Initializes a source with the given identifier, tile size, and tile
- URL template set.
-
- @param sourceIdentifier A string that uniquely identifies the source.
- @param tileSet A tile set describing where to download tiles.
- @param tileSize The minimum visual size to display tiles for the source.
- */
-- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier tileSet:(MGLTileSet *)tileSet tileSize:(CGFloat)tileSize;
-
@end
NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLRasterSource.mm b/platform/darwin/src/MGLRasterSource.mm
index 3d8a11101e..41b9a5b043 100644
--- a/platform/darwin/src/MGLRasterSource.mm
+++ b/platform/darwin/src/MGLRasterSource.mm
@@ -8,18 +8,18 @@
@implementation MGLRasterSource
-- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier URL:(NSURL *)url tileSize:(CGFloat)tileSize
+- (instancetype)initWithIdentifier:(NSString *)identifier URL:(NSURL *)url tileSize:(CGFloat)tileSize
{
- if (self = [super initWithSourceIdentifier:sourceIdentifier]) {
+ if (self = [super initWithIdentifier:identifier]) {
_URL = url;
_tileSize = tileSize;
}
return self;
}
-- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier tileSet:(MGLTileSet *)tileSet tileSize:(CGFloat)tileSize;
+- (instancetype)initWithIdentifier:(NSString *)identifier tileSet:(MGLTileSet *)tileSet tileSize:(CGFloat)tileSize;
{
- if (self = [super initWithSourceIdentifier:sourceIdentifier])
+ if (self = [super initWithIdentifier:identifier])
{
_tileSet = tileSet;
_tileSize = tileSize;
@@ -33,13 +33,13 @@
if (self.URL)
{
- source = std::make_unique<mbgl::style::RasterSource>(self.sourceIdentifier.UTF8String,
+ source = std::make_unique<mbgl::style::RasterSource>(self.identifier.UTF8String,
self.URL.mgl_URLByStandardizingScheme.absoluteString.UTF8String,
uint16_t(self.tileSize));
}
else
{
- source = std::make_unique<mbgl::style::RasterSource>(self.sourceIdentifier.UTF8String,
+ source = std::make_unique<mbgl::style::RasterSource>(self.identifier.UTF8String,
self.tileSet.mbglTileset,
uint16_t(self.tileSize));
diff --git a/platform/darwin/src/MGLRasterStyleLayer.h b/platform/darwin/src/MGLRasterStyleLayer.h
index 7fdfb04c99..afae85001e 100644
--- a/platform/darwin/src/MGLRasterStyleLayer.h
+++ b/platform/darwin/src/MGLRasterStyleLayer.h
@@ -1,8 +1,8 @@
// This file is generated.
// Edit platform/darwin/scripts/generate-style-code.js, then run `make style-code-darwin`.
-#import "MGLStyleAttributeValue.h"
-#import "MGLBaseStyleLayer.h"
+#import "MGLStyleValue.h"
+#import "MGLForegroundStyleLayer.h"
NS_ASSUME_NONNULL_BEGIN
@@ -12,65 +12,62 @@ NS_ASSUME_NONNULL_BEGIN
`MGLMapView` for its `style` and obtain existing layers using the
`-[MGLStyle layerWithIdentifier:]` method.
*/
-@interface MGLRasterStyleLayer : MGLBaseStyleLayer <MGLStyleLayer>
-
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier source:(MGLSource *)source;
-
+@interface MGLRasterStyleLayer : MGLForegroundStyleLayer
#pragma mark - Accessing the Paint Attributes
/**
The opacity at which the image will be drawn.
- The default value of this property is an `NSNumber` object containing the float `1`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `1`. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> rasterOpacity;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *rasterOpacity;
/**
Rotates hues around the color wheel.
This property is measured in degrees.
- The default value of this property is an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> rasterHueRotate;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *rasterHueRotate;
/**
Increase or reduce the brightness of the image. The value is the minimum brightness.
- The default value of this property is an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> rasterBrightnessMin;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *rasterBrightnessMin;
/**
Increase or reduce the brightness of the image. The value is the maximum brightness.
- The default value of this property is an `NSNumber` object containing the float `1`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `1`. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> rasterBrightnessMax;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *rasterBrightnessMax;
/**
Increase or reduce the saturation of the image.
- The default value of this property is an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> rasterSaturation;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *rasterSaturation;
/**
Increase or reduce the contrast of the image.
- The default value of this property is an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> rasterContrast;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *rasterContrast;
/**
Fade duration when a new tile is added.
This property is measured in milliseconds.
- The default value of this property is an `NSNumber` object containing the float `300`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `300`. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> rasterFadeDuration;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *rasterFadeDuration;
@end
diff --git a/platform/darwin/src/MGLRasterStyleLayer.mm b/platform/darwin/src/MGLRasterStyleLayer.mm
index 74cffc2ed2..f616e89518 100644
--- a/platform/darwin/src/MGLRasterStyleLayer.mm
+++ b/platform/darwin/src/MGLRasterStyleLayer.mm
@@ -4,7 +4,7 @@
#import "MGLSource.h"
#import "NSPredicate+MGLAdditions.h"
#import "MGLStyleLayer_Private.h"
-#import "MGLStyleAttributeValue.h"
+#import "MGLStyleValue_Private.h"
#import "MGLRasterStyleLayer.h"
#include <mbgl/style/layers/raster_layer.hpp>
@@ -12,84 +12,89 @@
@interface MGLRasterStyleLayer ()
@property (nonatomic) mbgl::style::RasterLayer *layer;
-@property (nonatomic, readwrite) NSString *layerIdentifier;
-@property (nonatomic, readwrite) NSString *sourceIdentifier;
-@property (nonatomic, readwrite) NSString *sourceLayerIdentifier;
@end
@implementation MGLRasterStyleLayer
-@synthesize mapView;
-
-
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier source:(MGLSource *)source
+- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source
{
- if (self = [super init]) {
- _layerIdentifier = layerIdentifier;
- _sourceIdentifier = source.sourceIdentifier;
- _layer = new mbgl::style::RasterLayer(layerIdentifier.UTF8String, source.sourceIdentifier.UTF8String);
+ if (self = [super initWithIdentifier:identifier source:source]) {
+ _layer = new mbgl::style::RasterLayer(identifier.UTF8String, source.identifier.UTF8String);
}
return self;
}
-
#pragma mark - Accessing the Paint Attributes
-- (void)setRasterOpacity:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)rasterOpacity {
- self.layer->setRasterOpacity(rasterOpacity.mbgl_floatPropertyValue);
+- (void)setRasterOpacity:(MGLStyleValue<NSNumber *> *)rasterOpacity {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(rasterOpacity);
+ self.layer->setRasterOpacity(mbglValue);
}
-- (id <MGLStyleAttributeValue>)rasterOpacity {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getRasterOpacity() ?: self.layer->getDefaultRasterOpacity()];
+- (MGLStyleValue<NSNumber *> *)rasterOpacity {
+ auto propertyValue = self.layer->getRasterOpacity() ?: self.layer->getDefaultRasterOpacity();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setRasterHueRotate:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)rasterHueRotate {
- self.layer->setRasterHueRotate(rasterHueRotate.mbgl_floatPropertyValue);
+- (void)setRasterHueRotate:(MGLStyleValue<NSNumber *> *)rasterHueRotate {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(rasterHueRotate);
+ self.layer->setRasterHueRotate(mbglValue);
}
-- (id <MGLStyleAttributeValue>)rasterHueRotate {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getRasterHueRotate() ?: self.layer->getDefaultRasterHueRotate()];
+- (MGLStyleValue<NSNumber *> *)rasterHueRotate {
+ auto propertyValue = self.layer->getRasterHueRotate() ?: self.layer->getDefaultRasterHueRotate();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setRasterBrightnessMin:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)rasterBrightnessMin {
- self.layer->setRasterBrightnessMin(rasterBrightnessMin.mbgl_floatPropertyValue);
+- (void)setRasterBrightnessMin:(MGLStyleValue<NSNumber *> *)rasterBrightnessMin {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(rasterBrightnessMin);
+ self.layer->setRasterBrightnessMin(mbglValue);
}
-- (id <MGLStyleAttributeValue>)rasterBrightnessMin {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getRasterBrightnessMin() ?: self.layer->getDefaultRasterBrightnessMin()];
+- (MGLStyleValue<NSNumber *> *)rasterBrightnessMin {
+ auto propertyValue = self.layer->getRasterBrightnessMin() ?: self.layer->getDefaultRasterBrightnessMin();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setRasterBrightnessMax:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)rasterBrightnessMax {
- self.layer->setRasterBrightnessMax(rasterBrightnessMax.mbgl_floatPropertyValue);
+- (void)setRasterBrightnessMax:(MGLStyleValue<NSNumber *> *)rasterBrightnessMax {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(rasterBrightnessMax);
+ self.layer->setRasterBrightnessMax(mbglValue);
}
-- (id <MGLStyleAttributeValue>)rasterBrightnessMax {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getRasterBrightnessMax() ?: self.layer->getDefaultRasterBrightnessMax()];
+- (MGLStyleValue<NSNumber *> *)rasterBrightnessMax {
+ auto propertyValue = self.layer->getRasterBrightnessMax() ?: self.layer->getDefaultRasterBrightnessMax();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setRasterSaturation:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)rasterSaturation {
- self.layer->setRasterSaturation(rasterSaturation.mbgl_floatPropertyValue);
+- (void)setRasterSaturation:(MGLStyleValue<NSNumber *> *)rasterSaturation {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(rasterSaturation);
+ self.layer->setRasterSaturation(mbglValue);
}
-- (id <MGLStyleAttributeValue>)rasterSaturation {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getRasterSaturation() ?: self.layer->getDefaultRasterSaturation()];
+- (MGLStyleValue<NSNumber *> *)rasterSaturation {
+ auto propertyValue = self.layer->getRasterSaturation() ?: self.layer->getDefaultRasterSaturation();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setRasterContrast:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)rasterContrast {
- self.layer->setRasterContrast(rasterContrast.mbgl_floatPropertyValue);
+- (void)setRasterContrast:(MGLStyleValue<NSNumber *> *)rasterContrast {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(rasterContrast);
+ self.layer->setRasterContrast(mbglValue);
}
-- (id <MGLStyleAttributeValue>)rasterContrast {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getRasterContrast() ?: self.layer->getDefaultRasterContrast()];
+- (MGLStyleValue<NSNumber *> *)rasterContrast {
+ auto propertyValue = self.layer->getRasterContrast() ?: self.layer->getDefaultRasterContrast();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setRasterFadeDuration:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)rasterFadeDuration {
- self.layer->setRasterFadeDuration(rasterFadeDuration.mbgl_floatPropertyValue);
+- (void)setRasterFadeDuration:(MGLStyleValue<NSNumber *> *)rasterFadeDuration {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(rasterFadeDuration);
+ self.layer->setRasterFadeDuration(mbglValue);
}
-- (id <MGLStyleAttributeValue>)rasterFadeDuration {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getRasterFadeDuration() ?: self.layer->getDefaultRasterFadeDuration()];
+- (MGLStyleValue<NSNumber *> *)rasterFadeDuration {
+ auto propertyValue = self.layer->getRasterFadeDuration() ?: self.layer->getDefaultRasterFadeDuration();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
@end
diff --git a/platform/darwin/src/MGLRuntimeStylingTests.m.ejs b/platform/darwin/src/MGLRuntimeStylingTests.m.ejs
index 0d0317cb65..720ee4547e 100644
--- a/platform/darwin/src/MGLRuntimeStylingTests.m.ejs
+++ b/platform/darwin/src/MGLRuntimeStylingTests.m.ejs
@@ -14,11 +14,15 @@
@implementation MGL<%- camelize(type) %>LayerTests
- (void)test<%- camelize(type) %>Layer {
+<% if (type === 'background') { -%>
+ MGL<%- camelize(type) %>StyleLayer *layer = [[MGL<%- camelize(type) %>StyleLayer alloc] initWithIdentifier:@"layerID"];
+<% } else { -%>
NSString *filePath = [[NSBundle bundleForClass:self.class] pathForResource:@"amsterdam" ofType:@"geojson"];
NSURL *url = [NSURL fileURLWithPath:filePath];
- MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithSourceIdentifier:@"sourceID" URL:url];
-MGL<%- camelize(type) %>StyleLayer *layer = [[MGL<%- camelize(type) %>StyleLayer alloc] initWithLayerIdentifier:@"layerID" source:source];
+ MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"sourceID" URL:url options:nil];
[self.mapView.style addSource:source];
+ MGL<%- camelize(type) %>StyleLayer *layer = [[MGL<%- camelize(type) %>StyleLayer alloc] initWithIdentifier:@"layerID" source:source];
+<% } -%>
[self.mapView.style addLayer:layer];
<% for (const property of layoutProperties) { -%>
@@ -28,7 +32,8 @@ MGL<%- camelize(type) %>StyleLayer *layer = [[MGL<%- camelize(type) %>StyleLayer
<%- testImplementation(property, type) %>
<% } -%>
- MGL<%- camelize(type) %>StyleLayer *gLayer = [self.mapView.style layerWithIdentifier:@"layerID"];
+ MGL<%- camelize(type) %>StyleLayer *gLayer = (MGL<%- camelize(type) %>StyleLayer *)[self.mapView.style layerWithIdentifier:@"layerID"];
+ XCTAssertTrue([gLayer isKindOfClass:[MGL<%- camelize(type) %>StyleLayer class]]);
<% for (const property of layoutProperties) { -%>
<%- testGetterImplementation(property, type) %>
<% } -%>
diff --git a/platform/darwin/src/MGLShape.m b/platform/darwin/src/MGLShape.mm
index e3d92c38c8..e3d92c38c8 100644
--- a/platform/darwin/src/MGLShape.m
+++ b/platform/darwin/src/MGLShape.mm
diff --git a/platform/darwin/src/MGLShapeCollection.m b/platform/darwin/src/MGLShapeCollection.m
index 5d42b5a51c..0f011bfd20 100644
--- a/platform/darwin/src/MGLShapeCollection.m
+++ b/platform/darwin/src/MGLShapeCollection.m
@@ -18,4 +18,18 @@
return _shapes.firstObject.coordinate;
}
+- (NSDictionary *)geoJSONDictionary {
+ return @{@"type": @"GeometryCollection",
+ @"geometries": [self geometryCollection]};
+}
+
+- (NSArray *)geometryCollection {
+ NSMutableArray *geometries = [[NSMutableArray alloc] initWithCapacity:self.shapes.count];
+ for (id shape in self.shapes) {
+ NSDictionary *geometry = [shape geoJSONDictionary];
+ [geometries addObject:geometry];
+ }
+ return [geometries copy];
+}
+
@end
diff --git a/platform/darwin/src/MGLShape_Private.h b/platform/darwin/src/MGLShape_Private.h
new file mode 100644
index 0000000000..a8ee12c207
--- /dev/null
+++ b/platform/darwin/src/MGLShape_Private.h
@@ -0,0 +1,17 @@
+#import "MGLShape.h"
+
+#import <mbgl/util/feature.hpp>
+
+@interface MGLShape (Private)
+
+/**
+ Returns an `mbgl::Feature` representation of the `MGLShape`.
+ */
+- (mbgl::Feature)featureObject;
+
+/**
+ Returns a dictionary with the GeoJSON geometry member object.
+ */
+- (NSDictionary *)geoJSONDictionary;
+
+@end
diff --git a/platform/darwin/src/MGLSource.h b/platform/darwin/src/MGLSource.h
index bb8f990828..ec3733bf08 100644
--- a/platform/darwin/src/MGLSource.h
+++ b/platform/darwin/src/MGLSource.h
@@ -2,24 +2,33 @@
/**
A source supplies data to be shown on the map. Sources don't contain styling
- details like color or width. Use subclasses of `MGLBaseStyleLayer` to give
- visual representation to sources.
+ details like color or width. Use subclasses of `MGLStyleLayer` to give visual
+ representation to sources.
You should use the concrete subclasses of `MGLSource` to create vector,
raster, GeoJSON, and other source types.
*/
@interface MGLSource : NSObject
+#pragma mark Initializing a Source
+
/**
- A string that uniquely identifies the source.
+ Returns a source initialized with an identifier.
+
+ After initializing and configuring the source, add it to a map view’s style
+ using the `-[MGLStyle addSource:]` method.
+
+ @param identifier A string that uniquely identifies the source in the style to
+ which it is added.
+ @return An initialized source.
*/
-@property (nonatomic, copy) NSString *sourceIdentifier;
+- (instancetype)initWithIdentifier:(NSString *)identifier;
-/**
- Initializes a source with the given identifier.
+#pragma mark Identifying a Source
- @param sourceIdentifier A string that uniquely identifies the source.
+/**
+ A string that uniquely identifies the source in the style to which it is added.
*/
-- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier;
+@property (nonatomic, copy) NSString *identifier;
@end
diff --git a/platform/darwin/src/MGLSource.mm b/platform/darwin/src/MGLSource.mm
index cdf003cb00..85bbc06342 100644
--- a/platform/darwin/src/MGLSource.mm
+++ b/platform/darwin/src/MGLSource.mm
@@ -1,18 +1,27 @@
-#import "MGLSource.h"
+#import "MGLSource_Private.h"
#include <mbgl/style/source.hpp>
+@interface MGLSource ()
+
+@property (nonatomic) mbgl::style::Source *source;
+
+@end
+
@implementation MGLSource
-- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier {
+- (instancetype)initWithIdentifier:(NSString *)identifier {
if (self = [super init]) {
- _sourceIdentifier = sourceIdentifier;
+ _identifier = identifier;
}
return self;
}
- (std::unique_ptr<mbgl::style::Source>)mbglSource {
- [NSException raise:@"Subclasses must override this method" format:@""];
+ [NSException raise:@"MGLAbstractClassException" format:
+ @"The source %@ cannot be added to the style. "
+ @"Make sure the source was created as a member of a concrete subclass of MGLSource.",
+ NSStringFromClass(self)];
return nil;
}
diff --git a/platform/darwin/src/MGLStyle.h b/platform/darwin/src/MGLStyle.h
index d4972a3d31..7f01c230c5 100644
--- a/platform/darwin/src/MGLStyle.h
+++ b/platform/darwin/src/MGLStyle.h
@@ -12,14 +12,14 @@ NS_ASSUME_NONNULL_BEGIN
A version number identifying the default version of the suite of default styles
provided by Mapbox. This version number may be passed into one of the
“StyleURLWithVersion” class methods of MGLStyle.
-
+
The value of this constant generally corresponds to the latest released version
as of the date on which this SDK was published. You can use this constant to
ascertain the style used by `MGLMapView` and `MGLTilePyramidOfflineRegion` when
no style URL is specified. Consult the
<a href="https://www.mapbox.com/api-documentation/#styles">Mapbox Styles API documentation</a>
for the most up-to-date style versioning information.
-
+
@warning The value of this constant may change in a future release of the SDK.
If you use any feature that depends on a specific aspect of a default style
– for instance, the minimum zoom level that includes roads – you may use the
@@ -30,8 +30,8 @@ NS_ASSUME_NONNULL_BEGIN
static const NSInteger MGLStyleDefaultVersion = 9;
/**
- The proxy object for the current map style for customization purposes and a
- set of convenience methods for creating style URLs of default styles provided
+ The proxy object for the current map style for customization purposes and a
+ set of convenience methods for creating style URLs of default styles provided
by Mapbox.
<a href="https://www.mapbox.com/maps/">Learn more about Mapbox default styles</a>.
*/
@@ -42,9 +42,9 @@ static const NSInteger MGLStyleDefaultVersion = 9;
/**
Returns the URL to version 8 of the
<a href="https://www.mapbox.com/maps/streets/">Mapbox Streets</a> style.
-
+
Streets is a general-purpose style with detailed road and transit networks.
-
+
`MGLMapView` and `MGLTilePyramidOfflineRegion` use Mapbox Streets when no style
is specified explicitly.
*/
@@ -53,12 +53,12 @@ static const NSInteger MGLStyleDefaultVersion = 9;
/**
Returns the URL to the given version of the
<a href="https://www.mapbox.com/maps/streets/">Mapbox Streets</a> style.
-
+
Streets is a general-purpose style with detailed road and transit networks.
-
+
`MGLMapView` and `MGLTilePyramidOfflineRegion` use Mapbox Streets when no style
is specified explicitly.
-
+
@param version The style’s latest released version. As of publication, the
current version is `9`.
*/
@@ -67,7 +67,7 @@ static const NSInteger MGLStyleDefaultVersion = 9;
/**
Returns the URL to version 8 of the
<a href="https://www.mapbox.com/blog/emerald-gl/">Mapbox Emerald</a> style.
-
+
Emerald is a tactile style with subtle textures and dramatic hillshading.
*/
+ (NSURL *)emeraldStyleURL __attribute__((deprecated("Create an NSURL object with the string “mapbox://styles/mapbox/emerald-v8”.")));
@@ -75,9 +75,9 @@ static const NSInteger MGLStyleDefaultVersion = 9;
/**
Returns the URL to the given version of the
<a href="https://www.mapbox.com/maps/outdoors/">Mapbox Outdoors</a> style.
-
+
Outdoors is a general-purpose style tailored to outdoor activities.
-
+
@param version The style’s latest released version. As of publication, the
current version is `9`.
*/
@@ -86,7 +86,7 @@ static const NSInteger MGLStyleDefaultVersion = 9;
/**
Returns the URL to version 8 of the
<a href="https://www.mapbox.com/maps/light-dark/">Mapbox Light</a> style.
-
+
Light is a subtle, light-colored backdrop for data visualizations.
*/
+ (NSURL *)lightStyleURL __attribute__((deprecated("Use -lightStyleURLWithVersion:.")));
@@ -94,9 +94,9 @@ static const NSInteger MGLStyleDefaultVersion = 9;
/**
Returns the URL to the given version of the
<a href="https://www.mapbox.com/maps/light-dark/">Mapbox Light</a> style.
-
+
Light is a subtle, light-colored backdrop for data visualizations.
-
+
@param version The style’s latest released version. As of publication, the
current version is `9`.
*/
@@ -105,7 +105,7 @@ static const NSInteger MGLStyleDefaultVersion = 9;
/**
Returns the URL to version 8 of the
<a href="https://www.mapbox.com/maps/light-dark/">Mapbox Dark</a> style.
-
+
Dark is a subtle, dark-colored backdrop for data visualizations.
*/
+ (NSURL *)darkStyleURL __attribute__((deprecated("Use -darkStyleURLWithVersion:.")));
@@ -113,9 +113,9 @@ static const NSInteger MGLStyleDefaultVersion = 9;
/**
Returns the URL to the given version of the
<a href="https://www.mapbox.com/maps/light-dark/">Mapbox Dark</a> style.
-
+
Dark is a subtle, dark-colored backdrop for data visualizations.
-
+
@param version The style’s latest released version. As of publication, the
current version is `9`.
*/
@@ -124,7 +124,7 @@ static const NSInteger MGLStyleDefaultVersion = 9;
/**
Returns the URL to version 8 of the
<a href="https://www.mapbox.com/maps/satellite/">Mapbox Satellite</a> style.
-
+
Satellite is high-resolution satellite and aerial imagery.
*/
+ (NSURL *)satelliteStyleURL __attribute__((deprecated("Use -satelliteStyleURLWithVersion:.")));
@@ -132,9 +132,9 @@ static const NSInteger MGLStyleDefaultVersion = 9;
/**
Returns the URL to the given version of the
<a href="https://www.mapbox.com/maps/satellite/">Mapbox Satellite</a> style.
-
+
Satellite is high-resolution satellite and aerial imagery.
-
+
@param version The style’s latest released version. As of publication, the
current version is `9`.
*/
@@ -144,7 +144,7 @@ static const NSInteger MGLStyleDefaultVersion = 9;
Returns the URL to version 8 of the
<a href="https://www.mapbox.com/maps/satellite/">Mapbox Satellite Streets</a>
style.
-
+
Satellite Streets combines the high-resolution satellite and aerial imagery of
Mapbox Satellite with unobtrusive labels and translucent roads from Mapbox
Streets.
@@ -155,11 +155,11 @@ static const NSInteger MGLStyleDefaultVersion = 9;
Returns the URL to the given version of the
<a href="https://www.mapbox.com/maps/satellite/">Mapbox Satellite Streets</a>
style.
-
+
Satellite Streets combines the high-resolution satellite and aerial imagery of
Mapbox Satellite with unobtrusive labels and translucent roads from Mapbox
Streets.
-
+
@param version The style’s latest released version. As of publication, the
current version is `9`.
*/
@@ -167,7 +167,7 @@ static const NSInteger MGLStyleDefaultVersion = 9;
/**
The name of the style.
-
+
You can customize the style’s name in Mapbox Studio.
*/
@property (readonly, copy, nullable) NSString *name;
@@ -177,54 +177,55 @@ static const NSInteger MGLStyleDefaultVersion = 9;
/**
Returns a layer that conforms to `MGLStyleLayer` if any layer with the given
identifier was found.
-
- @return layer A layer instance of the corresponding type.
+
+ @return An instance of a concrete subclass of `MGLStyleLayer` associated with
+ the given identifier.
*/
-- (nullable id <MGLStyleLayer>)layerWithIdentifier:(NSString *)identifier;
+- (nullable MGLStyleLayer *)layerWithIdentifier:(NSString *)identifier;
/**
Returns a source if any source with the given identifier was found.
-
- @return source An instance of an `MGLSource` subclass.
+
+ @return An instance of a concrete subclass of `MGLSource` associated with the
+ given identifier.
*/
- (nullable MGLSource *)sourceWithIdentifier:(NSString *)identifier;
/**
Adds a new layer on top of existing layers.
-
- @param styleLayer The layer object to add to the map view. This object
- must conform to the `MGLStyleLayer` protocol.
+
+ @param layer The layer object to add to the map view. This object must be an
+ instance of a concrete subclass of `MGLStyleLayer`.
*/
-- (void)addLayer:(id <MGLStyleLayer>)styleLayer;
+- (void)addLayer:(MGLStyleLayer *)layer;
/**
Inserts a new layer below another layer.
-
- @param styleLayer Layer to be inserted.
+
+ @param layer Layer to be inserted.
@param belowLayer A layer that's already on the map view.
*/
-- (void)insertLayer:(id <MGLStyleLayer>)styleLayer
- belowLayer:(id <MGLStyleLayer>)belowLayer;
+- (void)insertLayer:(MGLStyleLayer *)layer belowLayer:(MGLStyleLayer *)otherLayer;
/**
Removes a layer from the map view.
-
- @param styleLayer The layer object to remove from the map view. This object
+
+ @param layer The layer object to remove from the map view. This object
must conform to the `MGLStyleLayer` protocol.
*/
-- (void)removeLayer:(id <MGLStyleLayer>)styleLayer;
+- (void)removeLayer:(MGLStyleLayer *)layer;
/**
Adds a new source to the map view.
-
+
@param source The source to add to the map view.
*/
- (void)addSource:(MGLSource *)source;
/**
Removes a source from the map view.
-
+
@param source The source to remove.
*/
- (void)removeSource:(MGLSource *)source;
@@ -237,7 +238,7 @@ static const NSInteger MGLStyleDefaultVersion = 9;
/**
Returns a Boolean value indicating whether the style class with the given
identifier is currently active.
-
+
@param styleClass The style class to query for.
@return Whether the style class is currently active.
*/
@@ -245,18 +246,36 @@ static const NSInteger MGLStyleDefaultVersion = 9;
/**
Activates the style class with the given identifier.
-
+
@param styleClass The style class to activate.
*/
- (void)addStyleClass:(NSString *)styleClass;
/**
Deactivates the style class with the given identifier.
-
+
@param styleClass The style class to deactivate.
*/
- (void)removeStyleClass:(NSString *)styleClass;
+/**
+Adds or overrides an image used by the style’s layers.
+
+To use an image in a style layer, give it a unique name using this method,
+then set the `iconImage` property of an `MGLSymbolStyleLayer` object to that name.
+
+ @param image The image for the name.
+ @param name The name of the image to set to the style.
+ */
+- (void)setImage:(MGLImage *)image forName:(NSString *)name;
+
+/**
+ Removes a name and its associated image from the style.
+
+ @param name The name of the image to remove.
+ */
+- (void)removeImageForName:(NSString *)name;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLStyle.mm b/platform/darwin/src/MGLStyle.mm
index 79d7d7e0f6..f9f2e03d40 100644
--- a/platform/darwin/src/MGLStyle.mm
+++ b/platform/darwin/src/MGLStyle.mm
@@ -21,6 +21,7 @@
#import "MGLGeoJSONSource.h"
#include <mbgl/util/default_styles.hpp>
+#include <mbgl/sprite/sprite_image.hpp>
#include <mbgl/style/layers/fill_layer.hpp>
#include <mbgl/style/layers/line_layer.hpp>
#include <mbgl/style/layers/symbol_layer.hpp>
@@ -32,8 +33,15 @@
#include <mbgl/style/sources/raster_source.hpp>
#include <mbgl/mbgl.hpp>
+#if TARGET_OS_IPHONE
+ #import "UIImage+MGLAdditions.h"
+#else
+ #import "NSImage+MGLAdditions.h"
+#endif
+
@interface MGLStyle()
@property (nonatomic, weak) MGLMapView *mapView;
+@property (readonly, copy, nullable) NSURL *URL;
@end
@implementation MGLStyle
@@ -92,107 +100,129 @@ static NSURL *MGLStyleURL_emerald;
return @(self.mapView.mbglMap->getStyleName().c_str());
}
-- (id <MGLStyleLayer>)layerWithIdentifier:(NSString *)identifier
+- (NSURL *)URL {
+ return [NSURL URLWithString:@(self.mapView.mbglMap->getStyleURL().c_str())];
+}
+
+- (MGLStyleLayer *)layerWithIdentifier:(NSString *)identifier
{
- auto layer = self.mapView.mbglMap->getLayer(identifier.UTF8String);
+ auto mbglLayer = self.mapView.mbglMap->getLayer(identifier.UTF8String);
+ if (!mbglLayer) {
+ return nil;
+ }
+
+ MGLStyleLayer *styleLayer;
+ if (auto fillLayer = mbglLayer->as<mbgl::style::FillLayer>()) {
+ MGLSource *source = [self sourceWithIdentifier:@(fillLayer->getSourceID().c_str())];
+ styleLayer = [[MGLFillStyleLayer alloc] initWithIdentifier:identifier source:source];
+ } else if (auto lineLayer = mbglLayer->as<mbgl::style::LineLayer>()) {
+ MGLSource *source = [self sourceWithIdentifier:@(lineLayer->getSourceID().c_str())];
+ styleLayer = [[MGLLineStyleLayer alloc] initWithIdentifier:identifier source:source];
+ } else if (auto symbolLayer = mbglLayer->as<mbgl::style::SymbolLayer>()) {
+ MGLSource *source = [self sourceWithIdentifier:@(symbolLayer->getSourceID().c_str())];
+ styleLayer = [[MGLSymbolStyleLayer alloc] initWithIdentifier:identifier source:source];
+ } else if (auto rasterLayer = mbglLayer->as<mbgl::style::RasterLayer>()) {
+ MGLSource *source = [self sourceWithIdentifier:@(rasterLayer->getSourceID().c_str())];
+ styleLayer = [[MGLRasterStyleLayer alloc] initWithIdentifier:identifier source:source];
+ } else if (auto circleLayer = mbglLayer->as<mbgl::style::CircleLayer>()) {
+ MGLSource *source = [self sourceWithIdentifier:@(circleLayer->getSourceID().c_str())];
+ styleLayer = [[MGLCircleStyleLayer alloc] initWithIdentifier:identifier source:source];
+ } else if (mbglLayer->as<mbgl::style::BackgroundLayer>()) {
+ styleLayer = [[MGLBackgroundStyleLayer alloc] initWithIdentifier:identifier];
+ } else {
+ NSAssert(NO, @"Unrecognized layer type");
+ return nil;
+ }
+
+ styleLayer.layer = mbglLayer;
- if (!layer) return nil;
-
- Class clazz = [self classFromLayer:layer];
-
- id <MGLStyleLayer, MGLStyleLayer_Private> styleLayer = [[clazz alloc] init];
- styleLayer.layerIdentifier = identifier;
- styleLayer.layer = layer;
- styleLayer.mapView = self.mapView;
-
return styleLayer;
}
- (MGLSource *)sourceWithIdentifier:(NSString *)identifier
{
- auto s = self.mapView.mbglMap->getSource(identifier.UTF8String);
+ auto mbglSource = self.mapView.mbglMap->getSource(identifier.UTF8String);
+ if (!mbglSource) {
+ return nil;
+ }
+
+ // TODO: Fill in options specific to the respective source classes
+ // https://github.com/mapbox/mapbox-gl-native/issues/6584
+ MGLSource *source;
+ if (mbglSource->is<mbgl::style::VectorSource>()) {
+ source = [[MGLVectorSource alloc] initWithIdentifier:identifier];
+ } else if (mbglSource->is<mbgl::style::GeoJSONSource>()) {
+ source = [[MGLGeoJSONSource alloc] initWithIdentifier:identifier];
+ } else if (mbglSource->is<mbgl::style::RasterSource>()) {
+ source = [[MGLRasterSource alloc] initWithIdentifier:identifier];
+ } else {
+ NSAssert(NO, @"Unrecognized source type");
+ return nil;
+ }
+
+ source.source = mbglSource;
- if (!s) return nil;
-
- Class clazz = [self classFromSource:s];
-
- MGLSource *source = [[clazz alloc] init];
- source.sourceIdentifier = identifier;
- source.source = s;
-
return source;
}
-- (Class)classFromSource:(mbgl::style::Source *)source
+- (void)removeLayer:(MGLStyleLayer *)layer
{
- if (source->is<mbgl::style::VectorSource>()) {
- return MGLVectorSource.class;
- } else if (source->is<mbgl::style::GeoJSONSource>()) {
- return MGLGeoJSONSource.class;
- } else if (source->is<mbgl::style::RasterSource>()) {
- return MGLRasterSource.class;
- }
-
- [NSException raise:@"Source type not handled" format:@""];
- return Nil;
-}
-
-- (Class)classFromLayer:(mbgl::style::Layer *)layer
-{
- if (layer->is<mbgl::style::FillLayer>()) {
- return MGLFillStyleLayer.class;
- } else if (layer->is<mbgl::style::LineLayer>()) {
- return MGLLineStyleLayer.class;
- } else if (layer->is<mbgl::style::SymbolLayer>()) {
- return MGLSymbolStyleLayer.class;
- } else if (layer->is<mbgl::style::RasterLayer>()) {
- return MGLRasterStyleLayer.class;
- } else if (layer->is<mbgl::style::CircleLayer>()) {
- return MGLCircleStyleLayer.class;
- } else if (layer->is<mbgl::style::BackgroundLayer>()) {
- return MGLBackgroundStyleLayer.class;
- }
- [NSException raise:@"Layer type not handled" format:@""];
- return Nil;
+ self.mapView.mbglMap->removeLayer(layer.identifier.UTF8String);
}
-- (void)removeLayer:(id <MGLStyleLayer_Private>)styleLayer
+- (void)addLayer:(MGLStyleLayer *)layer
{
- self.mapView.mbglMap->removeLayer(styleLayer.layer->getID());
-}
+ if (!layer.layer) {
+ [NSException raise:NSInvalidArgumentException format:
+ @"The style layer %@ cannot be added to the style. "
+ @"Make sure the style layer was created as a member of a concrete subclass of MGLStyleLayer.",
+ NSStringFromClass(self)];
+ }
-- (void)addLayer:(id <MGLStyleLayer, MGLStyleLayer_Private>)styleLayer
-{
- self.mapView.mbglMap->addLayer(std::unique_ptr<mbgl::style::Layer>(styleLayer.layer));
+ self.mapView.mbglMap->addLayer(std::unique_ptr<mbgl::style::Layer>(layer.layer));
}
-- (void)insertLayer:(id <MGLStyleLayer, MGLStyleLayer_Private>)styleLayer
- belowLayer:(id <MGLStyleLayer, MGLStyleLayer_Private>)belowLayer
+- (void)insertLayer:(MGLStyleLayer *)layer belowLayer:(MGLStyleLayer *)otherLayer
{
- const mbgl::optional<std::string> belowLayerId{[belowLayer layerIdentifier].UTF8String};
- self.mapView.mbglMap->addLayer(std::unique_ptr<mbgl::style::Layer>(styleLayer.layer), belowLayerId);
+ if (!layer.layer) {
+ [NSException raise:NSInvalidArgumentException
+ format:
+ @"The style layer %@ cannot be added to the style. "
+ @"Make sure the style layer was created as a member of a concrete subclass of MGLStyleLayer.",
+ NSStringFromClass(layer)];
+ }
+ if (!otherLayer.layer) {
+ [NSException raise:NSInvalidArgumentException
+ format:
+ @"A style layer cannot be placed before %@ in the style. "
+ @"Make sure the style layer was created as a member of a concrete subclass of MGLStyleLayer.",
+ NSStringFromClass(otherLayer)];
+ }
+
+ const mbgl::optional<std::string> belowLayerId{otherLayer.identifier.UTF8String};
+ self.mapView.mbglMap->addLayer(std::unique_ptr<mbgl::style::Layer>(layer.layer), belowLayerId);
}
- (void)addSource:(MGLSource *)source
{
- self.mapView.mbglMap->addSource([source mbglSource]);
+ self.mapView.mbglMap->addSource(source.mbglSource);
}
- (void)removeSource:(MGLSource *)source
{
- self.mapView.mbglMap->removeSource(source.sourceIdentifier.UTF8String);
+ self.mapView.mbglMap->removeSource(source.identifier.UTF8String);
}
- (NS_ARRAY_OF(NSString *) *)styleClasses
{
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;
}
@@ -204,12 +234,12 @@ static NSURL *MGLStyleURL_emerald;
- (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 { { MGLDurationInSeconds(transitionDuration) } };
self.mapView.mbglMap->setTransitionOptions(transition);
self.mapView.mbglMap->setClasses(newAppliedClasses);
@@ -236,5 +266,27 @@ static NSURL *MGLStyleURL_emerald;
}
}
+- (void)setImage:(MGLImage *)image forName:(NSString *)name
+{
+ NSAssert(image, @"image is null");
+ NSAssert(name, @"name is null");
+
+ self.mapView.mbglMap->addImage([name UTF8String], image.mgl_spriteImage);
+}
+
+- (void)removeImageForName:(NSString *)name
+{
+ NSAssert(name, @"name is null");
+
+ self.mapView.mbglMap->removeImage([name UTF8String]);
+}
+
+- (NSString *)description
+{
+ return [NSString stringWithFormat:@"<%@: %p; name = %@, URL = %@>",
+ NSStringFromClass([self class]), (void *)self,
+ self.name ? [NSString stringWithFormat:@"\"%@\"", self.name] : self.name,
+ self.URL ? [NSString stringWithFormat:@"\"%@\"", self.URL] : self.URL];
+}
@end
diff --git a/platform/darwin/src/MGLStyleAttribute.h b/platform/darwin/src/MGLStyleAttribute.h
deleted file mode 100644
index 564f44ad00..0000000000
--- a/platform/darwin/src/MGLStyleAttribute.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#import <Foundation/Foundation.h>
-
-#import "MGLStyleAttributeValue.h"
-#import "MGLStyleLayer_Private.h"
-#import "MGLStyleAttributeValue_Private.h"
-
-@interface MGLStyleAttribute : NSObject <MGLStyleAttributeValue>
-
-+ (id <MGLStyleAttributeValue>)mbgl_colorWithPropertyValueColor:(mbgl::style::PropertyValue<mbgl::Color>)property;
-
-+ (id <MGLStyleAttributeValue>)mbgl_numberWithPropertyValueNumber:(mbgl::style::PropertyValue<float>)property;
-
-+ (id <MGLStyleAttributeValue>)mbgl_boolWithPropertyValueBool:(mbgl::style::PropertyValue<bool>)property;
-
-+ (id <MGLStyleAttributeValue>)mbgl_stringWithPropertyValueString:(mbgl::style::PropertyValue<std::string>)property;
-
-+ (id <MGLStyleAttributeValue>)mbgl_offsetWithPropertyValueOffset:(mbgl::style::PropertyValue<std::array<float, 2>>)property;
-
-+ (id <MGLStyleAttributeValue>)mbgl_paddingWithPropertyValuePadding:(mbgl::style::PropertyValue<std::array<float, 4>>)property;
-
-+ (id <MGLStyleAttributeValue>)mbgl_stringArrayWithPropertyValueStringArray:(mbgl::style::PropertyValue<std::vector<std::string>>)property;
-
-+ (id <MGLStyleAttributeValue>)mbgl_numberArrayWithPropertyValueNumberArray:(mbgl::style::PropertyValue<std::vector<float>>)property;
-
-@end
diff --git a/platform/darwin/src/MGLStyleAttribute.mm b/platform/darwin/src/MGLStyleAttribute.mm
deleted file mode 100644
index 9e3c22914b..0000000000
--- a/platform/darwin/src/MGLStyleAttribute.mm
+++ /dev/null
@@ -1,112 +0,0 @@
-#import "MGLStyleAttribute.h"
-
-#import "MGLStyleAttributeValue_Private.h"
-#import "MGLStyleAttributeFunction_Private.h"
-#import "NSValue+MGLStyleAttributeAdditions_Private.h"
-
-@interface MGLStyleAttribute()
-@end
-
-@implementation MGLStyleAttribute
-
-+ (id<MGLStyleAttributeValue>)mbgl_colorWithPropertyValueColor:(mbgl::style::PropertyValue<mbgl::Color>)property
-{
- if (property.isConstant()) {
- return [MGLColor mbgl_colorWithColor:property.asConstant()];
- } else if (property.isFunction()) {
- return [MGLStyleAttributeFunction functionWithColorPropertyValue:property.asFunction()];
- } else {
- return nil;
- }
-}
-
-+ (id <MGLStyleAttributeValue>)mbgl_numberWithPropertyValueNumber:(mbgl::style::PropertyValue<float>)property
-{
- if (property.isConstant()) {
- return @(property.asConstant());
- } else if (property.isFunction()) {
- return [MGLStyleAttributeFunction functionWithNumberPropertyValue:property.asFunction()];
- } else {
- return nil;
- }
-}
-
-+ (id<MGLStyleAttributeValue>)mbgl_boolWithPropertyValueBool:(mbgl::style::PropertyValue<bool>)property
-{
- if (property.isConstant()) {
- return @(property.asConstant());
- } else if (property.isFunction()) {
- return [MGLStyleAttributeFunction functionWithBoolPropertyValue:property.asFunction()];
- } else {
- return nil;
- }
-}
-
-+ (id<MGLStyleAttributeValue>)mbgl_stringWithPropertyValueString:(mbgl::style::PropertyValue<std::string>)property
-{
- if (property.isConstant()) {
- return @(property.asConstant().c_str());
- } else if (property.isFunction()) {
- return [MGLStyleAttributeFunction functionWithStringPropertyValue:property.asFunction()];
- } else {
- return nil;
- }
-}
-
-+ (id<MGLStyleAttributeValue>)mbgl_offsetWithPropertyValueOffset:(mbgl::style::PropertyValue<std::array<float, 2> >)property
-{
- if (property.isConstant()) {
- auto offset = property.asConstant();
- return [NSValue mgl_valueWithOffsetArray:offset];
- } else if (property.isFunction()) {
- return [MGLStyleAttributeFunction functionWithOffsetPropertyValue:property.asFunction()];
- } else {
- return nil;
- }
-}
-
-+ (id<MGLStyleAttributeValue>)mbgl_paddingWithPropertyValuePadding:(mbgl::style::PropertyValue<std::array<float, 4> >)property
-{
- if (property.isConstant()) {
- auto padding = property.asConstant();
- return [NSValue mgl_valueWithPaddingArray:padding];
- } else if (property.isFunction()) {
- return [MGLStyleAttributeFunction functionWithPaddingPropertyValue:property.asFunction()];
- } else {
- return nil;
- }
-}
-
-+ (id<MGLStyleAttributeValue>)mbgl_stringArrayWithPropertyValueStringArray:(mbgl::style::PropertyValue<std::vector<std::string> >)property
-{
- if (property.isConstant()) {
- auto strings = property.asConstant();
- NSMutableArray *convertedStrings = [[NSMutableArray alloc] initWithCapacity:strings.size()];
- for (auto string : strings) {
- [convertedStrings addObject:@(string.c_str())];
- }
- return convertedStrings;
- } else if (property.isFunction()) {
- return [MGLStyleAttributeFunction functionWithStringArrayPropertyValue:property.asFunction()];
- } else {
- return nil;
- }
-}
-
-+ (id<MGLStyleAttributeValue>)mbgl_numberArrayWithPropertyValueNumberArray:(mbgl::style::PropertyValue<std::vector<float> >)property
-{
- if (property.isConstant()) {
- auto numbers = property.asConstant();
- NSMutableArray *convertedNumbers = [NSMutableArray arrayWithCapacity:numbers.size()];
- for (auto number : numbers) {
- [convertedNumbers addObject:@(number)];
- }
- return convertedNumbers;
- } else if (property.isFunction()) {
- return [MGLStyleAttributeFunction functionWithNumberArrayPropertyValue:property.asFunction()];
- } else {
- return nil;
- }
-}
-
-@end
diff --git a/platform/darwin/src/MGLStyleAttributeFunction.h b/platform/darwin/src/MGLStyleAttributeFunction.h
deleted file mode 100644
index e636c1addd..0000000000
--- a/platform/darwin/src/MGLStyleAttributeFunction.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#import <Foundation/Foundation.h>
-
-#import "MGLTypes.h"
-#import "MGLStyleAttributeValue.h"
-
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface MGLStyleAttributeFunction : NSObject <MGLStyleAttributeValue>
-
-@property (nonatomic, copy) NS_DICTIONARY_OF(NSNumber *, id) *stops;
-
-@property (nonatomic, copy, nullable) NSNumber *base;
-
-@end
-
-NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLStyleAttributeFunction.mm b/platform/darwin/src/MGLStyleAttributeFunction.mm
deleted file mode 100644
index 7eec5c2369..0000000000
--- a/platform/darwin/src/MGLStyleAttributeFunction.mm
+++ /dev/null
@@ -1,247 +0,0 @@
-#import "MGLStyleAttributeFunction.h"
-
-#import "MGLStyleLayer_Private.h"
-#import "MGLStyleAttributeValue_Private.h"
-#import "MGLStyleAttributeFunction_Private.h"
-
-@interface MGLStyleAttributeFunction() <MGLStyleAttributeValue_Private>
-@end
-
-@implementation MGLStyleAttributeFunction
-
-- (instancetype)init
-{
- if (self = [super init]) {
- _base = @1;
- }
- return self;
-}
-
-- (BOOL)isFunction
-{
- return YES;
-}
-
-- (mbgl::style::PropertyValue<mbgl::Color>)mbgl_colorPropertyValue
-{
- __block std::vector<std::pair<float, mbgl::Color>> stops;
- [self.stops enumerateKeysAndObjectsUsingBlock:^(NSNumber * _Nonnull zoomKey, MGLColor * _Nonnull color, BOOL * _Nonnull stop) {
- NSAssert([color isKindOfClass:[MGLColor class]], @"Stops should be colors");
- stops.emplace_back(zoomKey.floatValue, color.mbgl_color);
- }];
- return mbgl::style::Function<mbgl::Color>({{stops}}, _base.floatValue);
-}
-
-- (mbgl::style::PropertyValue<float>)mbgl_floatPropertyValue
-{
- __block std::vector<std::pair<float, float>> stops;
- [self.stops enumerateKeysAndObjectsUsingBlock:^(NSNumber * _Nonnull zoomKey, NSNumber * _Nonnull number, BOOL * _Nonnull stop) {
- NSAssert([number isKindOfClass:[NSNumber class]], @"Stops should be NSNumbers");
- stops.emplace_back(zoomKey.floatValue, number.floatValue);
- }];
- return mbgl::style::Function<float>({{stops}}, _base.floatValue);
-}
-
-- (mbgl::style::PropertyValue<bool>)mbgl_boolPropertyValue
-{
- __block std::vector<std::pair<float, bool>> stops;
- [self.stops enumerateKeysAndObjectsUsingBlock:^(NSNumber * _Nonnull zoomKey, NSNumber * _Nonnull number, BOOL * _Nonnull stop) {
- NSAssert([number isKindOfClass:[NSNumber class]], @"Stops should be NSNumbers");
- stops.emplace_back(zoomKey.floatValue, number.boolValue);
- }];
- return mbgl::style::Function<bool>({{stops}}, _base.floatValue);
-}
-
-- (mbgl::style::PropertyValue<std::string>)mbgl_stringPropertyValue
-{
- __block std::vector<std::pair<float, std::string>> stops;
- [self.stops enumerateKeysAndObjectsUsingBlock:^(NSNumber * _Nonnull zoomKey, NSString * _Nonnull string, BOOL * _Nonnull stop) {
- NSAssert([string isKindOfClass:[NSString class]], @"Stops should be strings");
- stops.emplace_back(zoomKey.floatValue, string.UTF8String);
- }];
- return mbgl::style::Function<std::string>({{stops}}, _base.floatValue);
-}
-
-- (mbgl::style::PropertyValue<std::vector<std::string> >)mbgl_stringArrayPropertyValue
-{
- __block std::vector<std::pair<float, std::vector<std::string>>> stops;
- [self.stops enumerateKeysAndObjectsUsingBlock:^(NSNumber * _Nonnull zoomKey, NSArray * _Nonnull strings, BOOL * _Nonnull stop) {
- NSAssert([strings isKindOfClass:[NSArray class]], @"Stops should be NSArray");
- std::vector<std::string>convertedStrings;
- for (NSString *string in strings) {
- convertedStrings.emplace_back(string.UTF8String);
- }
- stops.emplace_back(zoomKey.floatValue, convertedStrings);
- }];
- return mbgl::style::Function<std::vector<std::string>>({{stops}}, _base.floatValue);
-}
-
-- (mbgl::style::PropertyValue<std::vector<float> >)mbgl_numberArrayPropertyValue
-{
- __block std::vector<std::pair<float, std::vector<float>>> stops;
- [self.stops enumerateKeysAndObjectsUsingBlock:^(NSNumber * _Nonnull zoomKey, NSArray * _Nonnull numbers, BOOL * _Nonnull stop) {
- NSAssert([numbers isKindOfClass:[NSArray class]], @"Stops should be NSArray");
- std::vector<float>convertedNumbers;
- for (NSNumber *number in numbers) {
- convertedNumbers.emplace_back(number.floatValue);
- }
- stops.emplace_back(zoomKey.floatValue, convertedNumbers);
- }];
- return mbgl::style::Function<std::vector<float>>({{stops}}, _base.floatValue);
-}
-
-- (mbgl::style::PropertyValue<std::array<float, 4> >)mbgl_paddingPropertyValue
-{
- __block std::vector<std::pair<float, std::array<float, 4>>> stops;
- [self.stops enumerateKeysAndObjectsUsingBlock:^(NSNumber * _Nonnull zoomKey, NSValue * _Nonnull padding, BOOL * _Nonnull stop) {
- NSAssert([padding isKindOfClass:[NSValue class]], @"Stops should be NSValue");
- stops.emplace_back(zoomKey.floatValue, padding.mgl_paddingArrayValue);
- }];
- return mbgl::style::Function<std::array<float, 4>>({{stops}}, _base.floatValue);
-}
-
-- (mbgl::style::PropertyValue<std::array<float, 2> >)mbgl_offsetPropertyValue
-{
- __block std::vector<std::pair<float, std::array<float, 2>>> stops;
- [self.stops enumerateKeysAndObjectsUsingBlock:^(NSNumber * _Nonnull zoomKey, NSValue * _Nonnull offset, BOOL * _Nonnull stop) {
- NSAssert([offset isKindOfClass:[NSValue class]], @"Stops should be NSValue");
- stops.emplace_back(zoomKey.floatValue, offset.mgl_offsetArrayValue);
- }];
- return mbgl::style::Function<std::array<float, 2>>({{stops}}, _base.floatValue);
-}
-
-+ (instancetype)functionWithColorPropertyValue:(mbgl::style::Function<mbgl::Color>)property
-{
- MGLStyleAttributeFunction *function = [[MGLStyleAttributeFunction alloc] init];
- auto stops = property.getStops();
- NSMutableDictionary *convertedStops = [NSMutableDictionary dictionaryWithCapacity:stops.size()];
- for (auto stop : stops) {
- convertedStops[@(stop.first)] = [MGLColor mbgl_colorWithColor:stop.second];
- }
- function.base = @(property.getBase());
- function.stops = convertedStops;
- return function;
-}
-
-+ (instancetype)functionWithNumberPropertyValue:(mbgl::style::Function<float>)property
-{
- MGLStyleAttributeFunction *function = [[MGLStyleAttributeFunction alloc] init];
- auto stops = property.getStops();
- NSMutableDictionary *convertedStops = [NSMutableDictionary dictionaryWithCapacity:stops.size()];
- for (auto stop : stops) {
- convertedStops[@(stop.first)] = @(stop.second);
- }
- function.base = @(property.getBase());
- function.stops = convertedStops;
- return function;
-}
-
-+ (instancetype)functionWithBoolPropertyValue:(mbgl::style::Function<bool>)property
-{
- MGLStyleAttributeFunction *function = [[MGLStyleAttributeFunction alloc] init];
- auto stops = property.getStops();
- NSMutableDictionary *convertedStops = [NSMutableDictionary dictionaryWithCapacity:stops.size()];
- for (auto stop : stops) {
- convertedStops[@(stop.first)] = @(stop.second);
- }
- function.base = @(property.getBase());
- function.stops = convertedStops;
- return function;
-}
-
-+ (instancetype)functionWithStringPropertyValue:(mbgl::style::Function<std::string>)property
-{
- MGLStyleAttributeFunction *function = [[MGLStyleAttributeFunction alloc] init];
- auto stops = property.getStops();
- NSMutableDictionary *convertedStops = [NSMutableDictionary dictionaryWithCapacity:stops.size()];
- for (auto stop : stops) {
- convertedStops[@(stop.first)] = @(stop.second.c_str());
- }
- function.base = @(property.getBase());
- function.stops = convertedStops;
- return function;
-}
-
-+ (instancetype)functionWithOffsetPropertyValue:(mbgl::style::Function<std::array<float, 2> >)property
-{
- MGLStyleAttributeFunction *function = [[MGLStyleAttributeFunction alloc] init];
- auto stops = property.getStops();
- NSMutableDictionary *convertedStops = [NSMutableDictionary dictionaryWithCapacity:stops.size()];
- for (auto stop : stops) {
- convertedStops[@(stop.first)] = [NSValue mgl_valueWithOffsetArray:stop.second];
- }
- function.base = @(property.getBase());
- function.stops = convertedStops;
- return function;
-}
-
-+ (instancetype)functionWithPaddingPropertyValue:(mbgl::style::Function<std::array<float, 4> >)property
-{
- MGLStyleAttributeFunction *function = [[MGLStyleAttributeFunction alloc] init];
- auto stops = property.getStops();
- NSMutableDictionary *convertedStops = [NSMutableDictionary dictionaryWithCapacity:stops.size()];
- for (auto stop : stops) {
- convertedStops[@(stop.first)] = [NSValue mgl_valueWithPaddingArray:stop.second];
- }
- function.base = @(property.getBase());
- function.stops = convertedStops;
- return function;
-}
-
-+ (instancetype)functionWithStringArrayPropertyValue:(mbgl::style::Function<std::vector<std::string> >)property
-{
- MGLStyleAttributeFunction *function = [[MGLStyleAttributeFunction alloc] init];
- auto stops = property.getStops();
- NSMutableDictionary *convertedStops = [NSMutableDictionary dictionaryWithCapacity:stops.size()];
- for (auto stop : stops) {
- auto strings = stop.second;
- NSMutableArray *convertedStrings = [NSMutableArray arrayWithCapacity:strings.size()];
- for (auto const& string: strings) {
- [convertedStrings addObject:@(string.c_str())];
- }
- convertedStops[@(stop.first)] = convertedStrings;
- }
- function.base = @(property.getBase());
- function.stops = convertedStops;
- return function;
-}
-
-+ (instancetype)functionWithNumberArrayPropertyValue:(mbgl::style::Function<std::vector<float> >)property
-{
- MGLStyleAttributeFunction *function = [[MGLStyleAttributeFunction alloc] init];
- auto stops = property.getStops();
- NSMutableDictionary *convertedStops = [NSMutableDictionary dictionaryWithCapacity:stops.size()];
- for (auto stop : stops) {
- auto numbers = stop.second;
- NSMutableArray *convertedNumbers = [NSMutableArray arrayWithCapacity:numbers.size()];
- for (auto const& number: numbers) {
- [convertedNumbers addObject:@(number)];
- }
- convertedStops[@(stop.first)] = convertedNumbers;
- }
- function.base = @(property.getBase());
- function.stops = convertedStops;
- return function;
-}
-
-- (NSString *)description
-{
- return [NSString stringWithFormat:@"<%@: %p, base = %@; stops = %@>",
- NSStringFromClass([self class]), (void *)self,
- self.base,
- self.stops];
-}
-
-- (BOOL)isEqual:(MGLStyleAttributeFunction *)other
-{
- return ([other isKindOfClass:[self class]]
- && (other.base == self.base || [other.base isEqualToNumber:self.base])
- && [other.stops isEqualToDictionary:self.stops]);
-}
-
-- (NSUInteger)hash
-{
- return self.base.hash + self.stops.hash;
-}
-
-@end
diff --git a/platform/darwin/src/MGLStyleAttributeFunction_Private.h b/platform/darwin/src/MGLStyleAttributeFunction_Private.h
deleted file mode 100644
index 92dec0d4a2..0000000000
--- a/platform/darwin/src/MGLStyleAttributeFunction_Private.h
+++ /dev/null
@@ -1,73 +0,0 @@
-#import "MGLStyleAttributeFunction.h"
-
-#include <mbgl/util/color.hpp>
-#include <mbgl/style/function.hpp>
-#include <mbgl/style/property_value.hpp>
-
-#define MGLSetEnumProperty(name, Name, MBGLType, ObjCType) \
- if (name.isFunction) { \
- NSAssert([name isKindOfClass:[MGLStyleAttributeFunction class]], @"" #name @" should be a function"); \
- \
- __block std::vector<std::pair<float, mbgl::style::MBGLType>> stops; \
- [[(MGLStyleAttributeFunction *)name stops] enumerateKeysAndObjectsUsingBlock:^(NSNumber * _Nonnull key, NSValue * _Nonnull obj, BOOL * _Nonnull stop) { \
- NSAssert([obj isKindOfClass:[NSValue class]], @"Stops in " #name @" should be NSValues"); \
- ObjCType value; \
- [obj getValue:&value]; \
- stops.emplace_back(key.floatValue, static_cast<mbgl::style::MBGLType>(value)); \
- }]; \
- auto function = mbgl::style::Function<mbgl::style::MBGLType> { \
- stops, \
- [(MGLStyleAttributeFunction *)name base].floatValue, \
- }; \
- self.layer->set##Name(function); \
- } else if (name) { \
- NSAssert([name isKindOfClass:[NSValue class]], @"" #name @"should be an NSValue"); \
- ObjCType value; \
- [(NSValue *)name getValue:&value]; \
- self.layer->set##Name({ static_cast<mbgl::style::MBGLType>(value) }); \
- } else { \
- self.layer->set##Name({}); \
- }
-
-#define MGLGetEnumProperty(Name, MBGLType, ObjCType) \
- const char *type = @encode(ObjCType); \
- mbgl::style::PropertyValue<mbgl::style::MBGLType> property = self.layer->get##Name() ?: self.layer->getDefault##Name(); \
- if (property.isConstant()) { \
- ObjCType value = static_cast<ObjCType>(property.asConstant()); \
- return [NSValue value:&value withObjCType:type]; \
- } else if (property.isFunction()) { \
- MGLStyleAttributeFunction *function = [[MGLStyleAttributeFunction alloc] init]; \
- auto stops = property.asFunction().getStops(); \
- NSMutableDictionary *convertedStops = [NSMutableDictionary dictionaryWithCapacity:stops.size()]; \
- for (auto stop : stops) { \
- ObjCType value = static_cast<ObjCType>(stop.second); \
- convertedStops[@(stop.first)] = [NSValue value:&value withObjCType:type]; \
- } \
- function.base = @(property.asFunction().getBase()); \
- function.stops = convertedStops; \
- return function; \
- } else { \
- return nil; \
- }
-
-@interface MGLStyleAttributeFunction(Private)
-
-+ (instancetype)functionWithColorPropertyValue:(mbgl::style::Function<mbgl::Color>)property;
-
-+ (instancetype)functionWithNumberPropertyValue:(mbgl::style::Function<float>)property;
-
-+ (instancetype)functionWithBoolPropertyValue:(mbgl::style::Function<bool>)property;
-
-+ (instancetype)functionWithStringPropertyValue:(mbgl::style::Function<std::string>)property;
-
-+ (instancetype)functionWithOffsetPropertyValue:(mbgl::style::Function<std::array<float, 2>>)property;
-
-+ (instancetype)functionWithPaddingPropertyValue:(mbgl::style::Function<std::array<float, 4>>)property;
-
-+ (instancetype)functionWithStringArrayPropertyValue:(mbgl::style::Function<std::vector<std::string>>)property;
-
-+ (instancetype)functionWithNumberArrayPropertyValue:(mbgl::style::Function<std::vector<float>>)property;
-
-+ (instancetype)functionWithEnumProperyValue:(mbgl::style::Function<bool>)property type:(const char *)type;
-
-@end;
diff --git a/platform/darwin/src/MGLStyleAttributeValue.h b/platform/darwin/src/MGLStyleAttributeValue.h
deleted file mode 100644
index cd33923889..0000000000
--- a/platform/darwin/src/MGLStyleAttributeValue.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#import <Foundation/Foundation.h>
-
-@protocol MGLStyleAttributeValue <NSObject>
-@optional
-@end \ No newline at end of file
diff --git a/platform/darwin/src/MGLStyleAttributeValue_Private.h b/platform/darwin/src/MGLStyleAttributeValue_Private.h
deleted file mode 100644
index 4b8fd1cc01..0000000000
--- a/platform/darwin/src/MGLStyleAttributeValue_Private.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#import <Foundation/Foundation.h>
-
-#import "MGLStyleAttributeFunction_Private.h"
-
-#include <array>
-
-@protocol MGLStyleAttributeValue_Private <NSObject>
-- (BOOL)isFunction;
-@optional
-
-// Convert darwin types to mbgl types
-- (mbgl::style::PropertyValue<mbgl::Color>)mbgl_colorPropertyValue;
-- (mbgl::style::PropertyValue<float>)mbgl_floatPropertyValue;
-- (mbgl::style::PropertyValue<bool>)mbgl_boolPropertyValue;
-- (mbgl::style::PropertyValue<std::string>)mbgl_stringPropertyValue;
-- (mbgl::style::PropertyValue<std::array<float, 2>>)mbgl_offsetPropertyValue;
-- (mbgl::style::PropertyValue<std::array<float, 4>>)mbgl_paddingPropertyValue;
-- (mbgl::style::PropertyValue<std::vector<std::string> >)mbgl_stringArrayPropertyValue;
-- (mbgl::style::PropertyValue<std::vector<float> >)mbgl_numberArrayPropertyValue;
-
-// Convert mbgl types to darwin types
-- (id <MGLStyleAttributeValue>)mbgl_colorPropertyValueWith:(mbgl::style::PropertyValue<mbgl::Color>)color;
-
-@end
diff --git a/platform/darwin/src/MGLStyleLayer.h b/platform/darwin/src/MGLStyleLayer.h
index d4ed525a3f..4032be9297 100644
--- a/platform/darwin/src/MGLStyleLayer.h
+++ b/platform/darwin/src/MGLStyleLayer.h
@@ -1,12 +1,67 @@
#import <Foundation/Foundation.h>
-@class MGLMapView;
+#import "MGLTypes.h"
-@protocol MGLStyleLayer <NSObject>
+NS_ASSUME_NONNULL_BEGIN
-@property (nonatomic, weak) MGLMapView *mapView;
-@property (nonatomic, copy, readonly) NSString *layerIdentifier;
-@property (nonatomic, readonly) NSString *sourceIdentifier;
-@property (nonatomic, readonly) NSString *sourceLayerIdentifier;
+/**
+ `MGLStyleLayer` is an abstract base class for style layers. A style layer
+ manages the layout and appearance of content at a specific z-index in a style.
+ An `MGLStyle` object consists of one or more `MGLStyleLayer` objects.
+
+ Each style layer defined by the style JSON file is represented at runtime by an
+ `MGLStyleLayer` object, which you can use to refine the map’s appearance. You
+ can also add and remove style layers dynamically.
+
+ Do not create instances of this class directly, and do not create your own
+ subclasses of this class. Instead, create instances of
+ `MGLBackgroundStyleLayer` and the concrete subclasses of
+ `MGLForegroundStyleLayer`.
+ */
+@interface MGLStyleLayer : NSObject
+
+#pragma mark Initializing a Style Layer
+
+- (instancetype)init __attribute__((unavailable("Use -initWithIdentifier: instead.")));
+
+/**
+ Returns a style layer object initialized with the given identifier.
+
+ After initializing and configuring the style layer, add it to a map view’s
+ style using the `-[MGLStyle addLayer:]` or
+ `-[MGLStyle insertLayer:belowLayer:]` method.
+
+ @param identifier A string that uniquely identifies the layer in the style to
+ which it is added.
+ @return An initialized style layer.
+ */
+- (instancetype)initWithIdentifier:(NSString *)identifier;
+
+#pragma mark Identifying a Style Layer
+
+/**
+ A string that uniquely identifies the style layer in the style to which it is
+ added.
+ */
+@property (nonatomic, copy, readonly) NSString *identifier;
+
+#pragma mark Configuring a Style Layer’s Visibility
+
+/**
+ Whether this layer is displayed. A value of `NO` hides the layer.
+ */
+@property (nonatomic, assign, getter=isVisible) BOOL visible;
+
+/**
+ The maximum zoom level at which the layer gets parsed and appears.
+ */
+@property (nonatomic, assign) float maximumZoomLevel;
+
+/**
+ The minimum zoom level at which the layer gets parsed and appears.
+ */
+@property (nonatomic, assign) float minimumZoomLevel;
@end
+
+NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLStyleLayer.h.ejs b/platform/darwin/src/MGLStyleLayer.h.ejs
index 40b750e73c..b97d070b90 100644
--- a/platform/darwin/src/MGLStyleLayer.h.ejs
+++ b/platform/darwin/src/MGLStyleLayer.h.ejs
@@ -8,8 +8,12 @@
// This file is generated.
// Edit platform/darwin/scripts/generate-style-code.js, then run `make style-code-darwin`.
-#import "MGLStyleAttributeValue.h"
-#import "MGLBaseStyleLayer.h"
+#import "MGLStyleValue.h"
+#import "MGL<%-
+(type === 'background' ? '' :
+ (type === 'raster' ? 'Foreground' :
+ 'Vector'))
+%>StyleLayer.h"
NS_ASSUME_NONNULL_BEGIN
@@ -17,13 +21,15 @@ NS_ASSUME_NONNULL_BEGIN
<% if (property.type == "enum") { -%>
/**
<%- propertyDoc(property.name, property, type) %>
+
+ Values of this type are used in the `<%- camelizeWithLeadingLowercase(property.name) %>` property of `MGL<%- camelize(type) %>StyleLayer`.
*/
-typedef NS_ENUM(NSUInteger, MGL<%- camelize(type) %>StyleLayer<%- camelize(property.name) %>) {
+typedef NS_ENUM(NSUInteger, MGL<%- camelize(property.name) %>) {
<% for (const value in property.values) { -%>
/**
<%- propertyDoc(property.name, property.values[value], type) %>
*/
- MGL<%- camelize(type) %>StyleLayer<%- camelize(property.name) %><%- camelize(value) %>,
+ MGL<%- camelize(property.name) %><%- camelize(value) %>,
<% } -%>
};
@@ -33,13 +39,15 @@ typedef NS_ENUM(NSUInteger, MGL<%- camelize(type) %>StyleLayer<%- camelize(prope
<% if (property.type == "enum") { -%>
/**
<%- propertyDoc(property.name, property, type) %>
+
+ Values of this type are used in the `<%- camelizeWithLeadingLowercase(property.name) %>` property of `MGL<%- camelize(type) %>StyleLayer`.
*/
-typedef NS_ENUM(NSUInteger, MGL<%- camelize(type) %>StyleLayer<%- camelize(property.name) %>) {
+typedef NS_ENUM(NSUInteger, MGL<%- camelize(property.name) %>) {
<% for (const value in property.values) { -%>
/**
<%- propertyDoc(property.name, property.values[value], type) %>
*/
- MGL<%- camelize(type) %>StyleLayer<%- camelize(property.name) %><%- camelize(value) %>,
+ MGL<%- camelize(property.name) %><%- camelize(value) %>,
<% } -%>
};
@@ -60,28 +68,16 @@ typedef NS_ENUM(NSUInteger, MGL<%- camelize(type) %>StyleLayer<%- camelize(prope
`-[MGLStyle layerWithIdentifier:]` method.
*/
<% } -%>
-@interface MGL<%- camelize(type) %>StyleLayer : MGLBaseStyleLayer <MGLStyleLayer>
-<% if (type == 'background') { -%>
-
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier;
-<% } -%>
-
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier source:(MGLSource *)source;
+@interface MGL<%- camelize(type) %>StyleLayer : MGL<%-
+(type === 'background' ? '' :
+ (type === 'raster' ? 'Foreground' :
+ 'Vector'))
+%>StyleLayer
+<% if (type === 'background') { -%>
-<% if (type !== 'background' && type !== 'raster') { -%>
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier source:(MGLSource *)source sourceLayer:(NSString *)sourceLayer;
+- (instancetype)initWithIdentifier:(NSString *)identifier NS_DESIGNATED_INITIALIZER;
<% } -%>
-<% if (type !== 'background' && type !== 'raster') { -%>
-/**
- A predicate that corresponds to the layer's <a href='https://www.mapbox.com/mapbox-gl-style-spec/#types-filter'>filter</a>.
-
- The predicate's left expression must be a string that identifies a feature
- property, or one of the special keys.
- */
-@property (nonatomic, nullable) NSPredicate *predicate;
-
-<% } -%>
<% if (layoutProperties.length) { -%>
#pragma mark - Accessing the Layout Attributes
@@ -96,7 +92,7 @@ typedef NS_ENUM(NSUInteger, MGL<%- camelize(type) %>StyleLayer<%- camelize(prope
<%- propertyReqs(property, layoutPropertiesByName, type) %>
<% } -%>
*/
-@property (nonatomic<% if (!property.required) { %>, null_resettable<% } %>) <%- propertyType(property, false, type) %> <%- camelizeWithLeadingLowercase(property.name) %>;
+@property (nonatomic<% if (!property.required) { %>, null_resettable<% } %>) MGLStyleValue<<%- propertyType(property, true) %>> *<%- camelizeWithLeadingLowercase(property.name) %>;
<% } -%>
<% } -%>
@@ -114,7 +110,7 @@ typedef NS_ENUM(NSUInteger, MGL<%- camelize(type) %>StyleLayer<%- camelize(prope
<%- propertyReqs(property, paintPropertiesByName, type) %>
<% } -%>
*/
-@property (nonatomic<% if (!property.required) { %>, null_resettable<% } %>) <%- propertyType(property, false, type) %> <%- camelizeWithLeadingLowercase(property.name) %>;
+@property (nonatomic<% if (!property.required) { %>, null_resettable<% } %>) MGLStyleValue<<%- propertyType(property, true) %>> *<%- camelizeWithLeadingLowercase(property.name) %>;
<% } -%>
<% } -%>
diff --git a/platform/darwin/src/MGLStyleLayer.mm b/platform/darwin/src/MGLStyleLayer.mm
index 43d98d62dc..a2bb1fc2cf 100644
--- a/platform/darwin/src/MGLStyleLayer.mm
+++ b/platform/darwin/src/MGLStyleLayer.mm
@@ -1,4 +1,50 @@
-#import "MGLStyleLayer.h"
-
#import "MGLStyleLayer_Private.h"
#import "MGLMapView_Private.h"
+
+#include <mbgl/style/layer.hpp>
+
+@implementation MGLStyleLayer
+
+- (instancetype)initWithIdentifier:(NSString *)identifier
+{
+ if (self = [super init]) {
+ _identifier = identifier;
+ }
+ return self;
+}
+
+- (void)setVisible:(BOOL)visible
+{
+ mbgl::style::VisibilityType v = visible
+ ? mbgl::style::VisibilityType::Visible
+ : mbgl::style::VisibilityType::None;
+ self.layer->setVisibility(v);
+}
+
+- (BOOL)isVisible
+{
+ mbgl::style::VisibilityType v = self.layer->getVisibility();
+ return (v == mbgl::style::VisibilityType::Visible);
+}
+
+- (void)setMaximumZoomLevel:(float)maximumZoomLevel
+{
+ self.layer->setMaxZoom(maximumZoomLevel);
+}
+
+- (float)maximumZoomLevel
+{
+ return self.layer->getMaxZoom();
+}
+
+- (void)setMinimumZoomLevel:(float)minimumZoomLevel
+{
+ self.layer->setMinZoom(minimumZoomLevel);
+}
+
+- (float)minimumZoomLevel
+{
+ return self.layer->getMinZoom();
+}
+
+@end
diff --git a/platform/darwin/src/MGLStyleLayer.mm.ejs b/platform/darwin/src/MGLStyleLayer.mm.ejs
index 233117fa91..3678e9ec52 100644
--- a/platform/darwin/src/MGLStyleLayer.mm.ejs
+++ b/platform/darwin/src/MGLStyleLayer.mm.ejs
@@ -9,7 +9,7 @@
#import "MGLSource.h"
#import "NSPredicate+MGLAdditions.h"
#import "MGLStyleLayer_Private.h"
-#import "MGLStyleAttributeValue.h"
+#import "MGLStyleValue_Private.h"
#import "MGL<%- camelize(type) %>StyleLayer.h"
#include <mbgl/style/layers/<%- type %>_layer.hpp>
@@ -17,51 +17,41 @@
@interface MGL<%- camelize(type) %>StyleLayer ()
@property (nonatomic) mbgl::style::<%- camelize(type) %>Layer *layer;
-@property (nonatomic, readwrite) NSString *layerIdentifier;
-@property (nonatomic, readwrite) NSString *sourceIdentifier;
-@property (nonatomic, readwrite) NSString *sourceLayerIdentifier;
@end
@implementation MGL<%- camelize(type) %>StyleLayer
-@synthesize mapView;
-
<% if (type == 'background') { -%>
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier
+- (instancetype)initWithIdentifier:(NSString *)identifier
{
- if (self = [super init]) {
- _layerIdentifier = layerIdentifier;
- <%- initLayerIdentifierOnly(type) %>
+ if (self = [super initWithIdentifier:identifier]) {
+ _layer = new mbgl::style::<%- camelize(type) %>Layer(identifier.UTF8String);
}
return self;
}
-<% } -%>
-
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier source:(MGLSource *)source
+<% } else { -%>
+- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source
{
- if (self = [super init]) {
- _layerIdentifier = layerIdentifier;
- _sourceIdentifier = source.sourceIdentifier;
- <%- initLayer(type) %>
+ if (self = [super initWithIdentifier:identifier source:source]) {
+ _layer = new mbgl::style::<%- camelize(type) %>Layer(identifier.UTF8String, source.identifier.UTF8String);
}
return self;
}
+<% } -%>
<% if (type !== 'background' && type !== 'raster') { -%>
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier source:(MGLSource *)source sourceLayer:(NSString *)sourceLayer
+- (NSString *)sourceLayerIdentifier
{
- if (self = [super init]) {
- _layerIdentifier = layerIdentifier;
- _sourceIdentifier = source.sourceIdentifier;
- <%- initLayerWithSourceLayer(type) %>
- <%- setSourceLayer() %>
- }
- return self;
+ auto layerID = self.layer->getSourceLayer();
+ return layerID.empty() ? nil : @(layerID.c_str());
+}
+
+- (void)setSourceLayerIdentifier:(NSString *)sourceLayerIdentifier
+{
+ self.layer->setSourceLayer(sourceLayerIdentifier.UTF8String ?: "");
}
-<% } -%>
-<% if (type !== 'background' && type !== 'raster') { -%>
- (void)setPredicate:(NSPredicate *)predicate
{
self.layer->setFilter(predicate.mgl_filter);
@@ -77,12 +67,14 @@
#pragma mark - Accessing the Layout Attributes
<% for (const property of layoutProperties) { -%>
-- (void)set<%- camelize(property.name) %>:(<%- propertyType(property, true, type) %>)<%- objCName(property) %> {
- <%- setterImplementation(property, type) %>
+- (void)set<%- camelize(property.name) %>:(MGLStyleValue<<%- propertyType(property, true) %>> *)<%- objCName(property) %> {
+ auto mbglValue = MGLStyleValueTransformer<<%- valueTransformerArguments(property).join(', ') %>>().toPropertyValue(<%- objCName(property) %>);
+ self.layer->set<%- camelize(property.name) %>(mbglValue);
}
-- (<%- propertyType(property, false, type) %>)<%- objCName(property) %> {
- <%- getterImplementation(property, type) %>
+- (MGLStyleValue<<%- propertyType(property, true) %>> *)<%- objCName(property) %> {
+ auto propertyValue = self.layer->get<%- camelize(property.name) %>() ?: self.layer->getDefault<%- camelize(property.name) %>();
+ return MGLStyleValueTransformer<<%- valueTransformerArguments(property).join(', ') %>>().toStyleValue(propertyValue);
}
<% } -%>
@@ -91,12 +83,14 @@
#pragma mark - Accessing the Paint Attributes
<% for (const property of paintProperties) { -%>
-- (void)set<%- camelize(property.name) %>:(<%- propertyType(property, true, type) %>)<%- objCName(property) %> {
- <%- setterImplementation(property, type) %>
+- (void)set<%- camelize(property.name) %>:(MGLStyleValue<<%- propertyType(property, true) %>> *)<%- objCName(property) %> {
+ auto mbglValue = MGLStyleValueTransformer<<%- valueTransformerArguments(property).join(', ') %>>().toPropertyValue(<%- objCName(property) %>);
+ self.layer->set<%- camelize(property.name) %>(mbglValue);
}
-- (<%- propertyType(property, false, type) %>)<%- objCName(property) %> {
- <%- getterImplementation(property, type) %>
+- (MGLStyleValue<<%- propertyType(property, true) %>> *)<%- objCName(property) %> {
+ auto propertyValue = self.layer->get<%- camelize(property.name) %>() ?: self.layer->getDefault<%- camelize(property.name) %>();
+ return MGLStyleValueTransformer<<%- valueTransformerArguments(property).join(', ') %>>().toStyleValue(propertyValue);
}
<% } -%>
diff --git a/platform/darwin/src/MGLStyleLayer_Private.h b/platform/darwin/src/MGLStyleLayer_Private.h
index bc3d87bcb7..5fa01856ea 100644
--- a/platform/darwin/src/MGLStyleLayer_Private.h
+++ b/platform/darwin/src/MGLStyleLayer_Private.h
@@ -1,30 +1,13 @@
#import <Foundation/Foundation.h>
-#include <mbgl/style/layer.hpp>
#import "MGLStyleLayer.h"
-#import "MGLStyleAttribute.h"
-
-#import "NSNumber+MGLStyleAttributeAdditions_Private.h"
-#import "NSArray+MGLStyleAttributeAdditions_Private.h"
-#import "NSString+MGLStyleAttributeAdditions_Private.h"
-#import "NSValue+MGLStyleAttributeAdditions_Private.h"
-#import "MGLStyleAttributeFunction_Private.h"
-#import "MGLStyleAttributeValue_Private.h"
+#import "MGLStyleValue_Private.h"
-#if TARGET_OS_IPHONE
- #import "UIColor+MGLAdditions.h"
- #import "UIColor+MGLStyleAttributeAdditions_Private.h"
-#else
- #import "NSColor+MGLAdditions.h"
- #import "NSColor+MGLStyleAttributeAdditions_Private.h"
-#endif
-
-@class MGLMapView;
+#include <mbgl/style/layer.hpp>
-@protocol MGLStyleLayer_Private <MGLStyleLayer>
+@interface MGLStyleLayer (Private)
-@property (nonatomic, weak) MGLMapView *mapView;
-@property (nonatomic, readwrite, copy) NSString *layerIdentifier;
+@property (nonatomic, readwrite, copy) NSString *identifier;
@property (nonatomic) mbgl::style::Layer *layer;
@end
diff --git a/platform/darwin/src/MGLStyleValue.h b/platform/darwin/src/MGLStyleValue.h
new file mode 100644
index 0000000000..eb0eaf5340
--- /dev/null
+++ b/platform/darwin/src/MGLStyleValue.h
@@ -0,0 +1,176 @@
+#import <Foundation/Foundation.h>
+#import <CoreGraphics/CoreGraphics.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ An `MGLStyleValue` object is a generic container for a style attribute value.
+ The layout and paint attribute properties of `MGLStyleLayer` can be set to
+ `MGLStyleValue` objects.
+
+ The `MGLStyleValue` class itself represents a class cluster. Under the hood, a
+ particular `MGLStyleValue` object may be either an `MGLStyleConstantValue` to
+ represent a constant value or an `MGLStyleFunction` to represent a value
+ function. Do not initialize an `MGLStyleValue` object directly; instead, use
+ one of the class factory methods to create an `MGLStyleValue` object.
+
+ The `MGLStyleValue` class takes a generic parameter `T` that indicates the
+ Foundation class being wrapped by this class. Common values for `T` include:
+
+ <ul>
+ <li>`NSNumber` (for Boolean values, floating-point numbers, and enumerations)</li>
+ <li>`NSValue` (for `CGVector`, `NSEdgeInset`, and `UIEdgeInset`s)</li>
+ <li>`NSString`</li>
+ <li>`NSColor` or `UIColor`</li>
+ <li>`NSArray`</li>
+ </ul>
+ */
+@interface MGLStyleValue<T> : NSObject
+
+#pragma mark Creating a Style Value
+
+/**
+ Creates and returns an `MGLStyleConstantValue` object containing a raw value.
+
+ @param rawValue The constant value contained by the object.
+ @return An `MGLStyleConstantValue` object containing `rawValue`, which is
+ treated as a constant value.
+ */
++ (instancetype)valueWithRawValue:(T)rawValue;
+
+/**
+ Creates and returns an `MGLStyleFunction` object representing a linear zoom
+ level function with any number of stops.
+
+ @param stops A dictionary associating zoom levels with style values.
+ @return An `MGLStyleFunction` object with the given stops.
+ */
++ (instancetype)valueWithStops:(NSDictionary<NSNumber *, MGLStyleValue<T> *> *)stops;
+
+/**
+ Creates and returns an `MGLStyleFunction` object representing a zoom level
+ function with an exponential base and any number of stops.
+
+ @param base The exponential base of the interpolation curve.
+ @param stops A dictionary associating zoom levels with style values.
+ @return An `MGLStyleFunction` object with the given base and stops.
+ */
++ (instancetype)valueWithBase:(CGFloat)base stops:(NSDictionary<NSNumber *, MGLStyleValue<T> *> *)stops;
+
+@end
+
+/**
+ An `MGLStyleConstantValue` object is a generic container for a style attribute
+ value that remains constant as the zoom level changes. The layout and paint
+ attribute properties of `MGLStyleLayer` objects can be set to
+ `MGLStyleConstantValue` objects.
+
+ The `MGLStyleConstantValue` class takes a generic parameter `T` that indicates
+ the Foundation class being wrapped by this class.
+ */
+@interface MGLStyleConstantValue<T> : MGLStyleValue
+
+#pragma mark Creating a Style Constant Value
+
+/**
+ Creates and returns an `MGLStyleConstantValue` object containing a raw value.
+
+ @param rawValue The constant value contained by the object.
+ @return An `MGLStyleConstantValue` object containing `rawValue`, which is
+ treated as a constant value.
+ */
++ (instancetype)valueWithRawValue:(T)rawValue;
+
+#pragma mark Initializing a Style Constant Value
+
+- (instancetype)init NS_UNAVAILABLE;
+
+/**
+ Returns an `MGLStyleConstantValue` object containing a raw value.
+
+ @param rawValue The value contained by the receiver.
+ @return An `MGLStyleConstantValue` object containing `rawValue`.
+ */
+- (instancetype)initWithRawValue:(T)rawValue NS_DESIGNATED_INITIALIZER;
+
+#pragma mark Accessing the Underlying Value
+
+/**
+ The raw value contained by the receiver.
+ */
+@property (nonatomic) T rawValue;
+
+@end
+
+/**
+ An `MGLStyleFunction` is a value function defining a style value that changes
+ as the zoom level changes. The layout and paint attribute properties of an
+ `MGLStyleLayer` object can be set to `MGLStyleFunction` objects. Use a zoom
+ level function to create the illusion of depth and control data density.
+
+ The `MGLStyleFunction` class takes a generic parameter `T` that indicates the
+ Foundation class being wrapped by this class.
+ */
+@interface MGLStyleFunction<T> : MGLStyleValue
+
+#pragma mark Creating a Style Function
+
+/**
+ Creates and returns an `MGLStyleFunction` object representing a linear zoom
+ level function with any number of stops.
+
+ @param stops A dictionary associating zoom levels with style values.
+ @return An `MGLStyleFunction` object with the given stops.
+ */
++ (instancetype)functionWithStops:(NSDictionary<NSNumber *, MGLStyleValue<T> *> *)stops;
+
+/**
+ Creates and returns an `MGLStyleFunction` object representing a zoom level
+ function with an exponential base and any number of stops.
+
+ @param base The exponential base of the interpolation curve.
+ @param stops A dictionary associating zoom levels with style values.
+ @return An `MGLStyleFunction` object with the given base and stops.
+ */
++ (instancetype)functionWithBase:(CGFloat)base stops:(NSDictionary<NSNumber *, MGLStyleValue<T> *> *)stops;
+
+#pragma mark Initializing a Style Function
+
+/**
+ Returns an `MGLStyleFunction` object representing a zoom level function with an
+ exponential base and any number of stops.
+
+ @param base The exponential base of the interpolation curve.
+ @param stops A dictionary associating zoom levels with style values.
+ @return An `MGLStyleFunction` object with the given base and stops.
+ */
+- (instancetype)initWithBase:(CGFloat)base stops:(NSDictionary<NSNumber *, MGLStyleValue<T> *> *)stops NS_DESIGNATED_INITIALIZER;
+
+#pragma mark Accessing the Parameters of a Function
+
+/**
+ The exponential base of the function’s interpolation curve.
+
+ The exponential base controls the rate at which the function’s output values
+ increase. A value of 1 causes the function to increase linearly by zoom level.
+ A higher exponential base causes the function’s output values to vary
+ exponentially, increasing more rapidly towards the high end of the function’s
+ range. The default value of this property is 1, for a linear curve.
+ */
+@property (nonatomic) CGFloat base;
+
+/**
+ A dictionary associating zoom levels with style values.
+
+ Each of the function’s stops is represented by one key-value pair in the
+ dictionary. Each key in the dictionary is an `NSNumber` object containing a
+ floating-point zoom level. Each value in the dictionary is an `MGLStyleValue`
+ object containing the value of the style attribute when the map is at the
+ associated zoom level. An `MGLStyleFunction` object may not be used recursively
+ as a stop value.
+ */
+@property (nonatomic, copy) NSDictionary<NSNumber *, MGLStyleValue<T> *> *stops;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLStyleValue.mm b/platform/darwin/src/MGLStyleValue.mm
new file mode 100644
index 0000000000..43b51d6788
--- /dev/null
+++ b/platform/darwin/src/MGLStyleValue.mm
@@ -0,0 +1,88 @@
+#import "MGLStyleValue_Private.h"
+
+@implementation MGLStyleValue
+
++ (instancetype)valueWithRawValue:(id)rawValue {
+ return [MGLStyleConstantValue valueWithRawValue:rawValue];
+}
+
++ (instancetype)valueWithBase:(CGFloat)base stops:(NSDictionary *)stops {
+ return [MGLStyleFunction functionWithBase:base stops:stops];
+}
+
++ (instancetype)valueWithStops:(NSDictionary *)stops {
+ return [MGLStyleFunction functionWithStops:stops];
+}
+
+@end
+
+@implementation MGLStyleConstantValue
+
++ (instancetype)valueWithRawValue:(id)rawValue {
+ return [[self alloc] initWithRawValue:rawValue];
+}
+
+- (instancetype)initWithRawValue:(id)rawValue {
+ if (self = [super init]) {
+ _rawValue = rawValue;
+ }
+ return self;
+}
+
+- (NSString *)description {
+ return [self.rawValue description];
+}
+
+- (NSString *)debugDescription {
+ return [self.rawValue debugDescription];
+}
+
+- (BOOL)isEqual:(MGLStyleConstantValue *)other {
+ return [other isKindOfClass:[self class]] && [other.rawValue isEqual:self.rawValue];
+}
+
+- (NSUInteger)hash {
+ return [self.rawValue hash];
+}
+
+@end
+
+@implementation MGLStyleFunction
+
++ (instancetype)functionWithBase:(CGFloat)base stops:(NSDictionary *)stops {
+ return [[self alloc] initWithBase:base stops:stops];
+}
+
++ (instancetype)functionWithStops:(NSDictionary *)stops {
+ return [[self alloc] initWithBase:1 stops:stops];
+}
+
+- (instancetype)init {
+ return [self initWithBase:1 stops:@{}];
+}
+
+- (instancetype)initWithBase:(CGFloat)base stops:(NSDictionary *)stops {
+ if (self = [super init]) {
+ _base = base;
+ _stops = stops;
+ }
+ return self;
+}
+
+- (NSString *)description {
+ return [NSString stringWithFormat:@"<%@: %p, base = %f; stops = %@>",
+ NSStringFromClass([self class]), (void *)self,
+ self.base,
+ self.stops];
+}
+
+- (BOOL)isEqual:(MGLStyleFunction *)other {
+ return ([other isKindOfClass:[self class]] && other.base == self.base
+ && [other.stops isEqualToDictionary:self.stops]);
+}
+
+- (NSUInteger)hash {
+ return self.base + self.stops.hash;
+}
+
+@end
diff --git a/platform/darwin/src/MGLStyleValue_Private.h b/platform/darwin/src/MGLStyleValue_Private.h
new file mode 100644
index 0000000000..fdad07aafa
--- /dev/null
+++ b/platform/darwin/src/MGLStyleValue_Private.h
@@ -0,0 +1,156 @@
+#import <Foundation/Foundation.h>
+
+#import "MGLStyleValue.h"
+
+#import "NSValue+MGLStyleAttributeAdditions.h"
+#import "MGLTypes.h"
+
+#if TARGET_OS_IPHONE
+ #import "UIColor+MGLAdditions.h"
+#else
+ #import "NSColor+MGLAdditions.h"
+#endif
+
+#include <array>
+
+template <typename MBGLType, typename ObjCType, typename MBGLElement = MBGLType>
+class MGLStyleValueTransformer {
+public:
+
+ MGLStyleValue<ObjCType> *toStyleValue(const mbgl::style::PropertyValue<MBGLType> &mbglValue) {
+ if (mbglValue.isConstant()) {
+ return toStyleConstantValue(mbglValue.asConstant());
+ } else if (mbglValue.isFunction()) {
+ return toStyleFunction(mbglValue.asFunction());
+ } else {
+ return nil;
+ }
+ }
+
+ mbgl::style::PropertyValue<MBGLType> toPropertyValue(MGLStyleValue<ObjCType> *value) {
+ if ([value isKindOfClass:[MGLStyleConstantValue class]]) {
+ MBGLType mbglValue;
+ getMBGLValue([(MGLStyleConstantValue<ObjCType> *)value rawValue], mbglValue);
+ return mbglValue;
+ } else if ([value isKindOfClass:[MGLStyleFunction class]]) {
+ MGLStyleFunction<ObjCType> *function = (MGLStyleFunction<ObjCType> *)value;
+ __block std::vector<std::pair<float, MBGLType>> mbglStops;
+ [function.stops enumerateKeysAndObjectsUsingBlock:^(NSNumber * _Nonnull zoomKey, MGLStyleValue<ObjCType> * _Nonnull stopValue, BOOL * _Nonnull stop) {
+ NSCAssert([stopValue isKindOfClass:[MGLStyleValue class]], @"Stops should be MGLStyleValues");
+ auto mbglStopValue = toPropertyValue(stopValue);
+ NSCAssert(mbglStopValue.isConstant(), @"Stops must be constant");
+ mbglStops.emplace_back(zoomKey.floatValue, mbglStopValue.asConstant());
+ }];
+ return mbgl::style::Function<MBGLType>({{mbglStops}}, function.base);
+ } else if (value) {
+ [NSException raise:@"MGLAbstractClassException" format:
+ @"The style value %@ cannot be applied to the style. "
+ @"Make sure the style value was created as a member of a concrete subclass of MGLStyleValue.",
+ NSStringFromClass([value class])];
+ return {};
+ } else {
+ return {};
+ }
+ }
+
+private:
+
+ MGLStyleConstantValue<ObjCType> *toStyleConstantValue(const MBGLType mbglValue) {
+ auto rawValue = toMGLRawStyleValue(mbglValue);
+ return [MGLStyleConstantValue<ObjCType> valueWithRawValue:rawValue];
+ }
+
+ MGLStyleFunction<ObjCType> *toStyleFunction(const mbgl::style::Function<MBGLType> &mbglFunction) {
+ const auto &mbglStops = mbglFunction.getStops();
+ NSMutableDictionary *stops = [NSMutableDictionary dictionaryWithCapacity:mbglStops.size()];
+ for (const auto &mbglStop : mbglStops) {
+ auto rawValue = toMGLRawStyleValue(mbglStop.second);
+ stops[@(mbglStop.first)] = [MGLStyleValue valueWithRawValue:rawValue];
+ }
+ return [MGLStyleFunction<ObjCType> functionWithBase:mbglFunction.getBase() stops:stops];
+ }
+
+ NSNumber *toMGLRawStyleValue(const bool mbglStopValue) {
+ return @(mbglStopValue);
+ }
+
+ NSNumber *toMGLRawStyleValue(const float mbglStopValue) {
+ return @(mbglStopValue);
+ }
+
+ NSString *toMGLRawStyleValue(const std::string &mbglStopValue) {
+ return @(mbglStopValue.c_str());
+ }
+
+ // Offsets
+ NSValue *toMGLRawStyleValue(const std::array<float, 2> &mbglStopValue) {
+ return [NSValue mgl_valueWithOffsetArray:mbglStopValue];
+ }
+
+ // Padding
+ NSValue *toMGLRawStyleValue(const std::array<float, 4> &mbglStopValue) {
+ return [NSValue mgl_valueWithPaddingArray:mbglStopValue];
+ }
+
+ // Enumerations
+ template <typename MBGLEnum = MBGLType, class = typename std::enable_if<std::is_enum<MBGLEnum>::value>::type>
+ ObjCType toMGLRawStyleValue(const MBGLType &mbglStopValue) {
+ NSUInteger rawValue = static_cast<NSUInteger>(mbglStopValue);
+ return [NSValue value:&rawValue withObjCType:@encode(NSUInteger)];
+ }
+
+ MGLColor *toMGLRawStyleValue(const mbgl::Color mbglStopValue) {
+ return [MGLColor mgl_colorWithColor:mbglStopValue];
+ }
+
+ ObjCType toMGLRawStyleValue(const std::vector<MBGLElement> &mbglStopValue) {
+ NSMutableArray *array = [NSMutableArray arrayWithCapacity:mbglStopValue.size()];
+ for (const auto &mbglElement: mbglStopValue) {
+ [array addObject:toMGLRawStyleValue(mbglElement)];
+ }
+ return array;
+ }
+
+private:
+
+ void getMBGLValue(NSNumber *rawValue, bool &mbglValue) {
+ mbglValue = !!rawValue.boolValue;
+ }
+
+ void getMBGLValue(NSNumber *rawValue, float &mbglValue) {
+ mbglValue = rawValue.floatValue;
+ }
+
+ void getMBGLValue(NSString *rawValue, std::string &mbglValue) {
+ mbglValue = rawValue.UTF8String;
+ }
+
+ // Offsets
+ void getMBGLValue(NSValue *rawValue, std::array<float, 2> &mbglValue) {
+ mbglValue = rawValue.mgl_offsetArrayValue;
+ }
+
+ // Padding
+ void getMBGLValue(NSValue *rawValue, std::array<float, 4> &mbglValue) {
+ mbglValue = rawValue.mgl_paddingArrayValue;
+ }
+
+ // Enumerations
+ template <typename MBGLEnum = MBGLType, class = typename std::enable_if<std::is_enum<MBGLEnum>::value>::type>
+ void getMBGLValue(ObjCType rawValue, MBGLType &mbglValue) {
+ [rawValue getValue:&mbglValue];
+ }
+
+ void getMBGLValue(MGLColor *rawValue, mbgl::Color &mbglValue) {
+ mbglValue = rawValue.mgl_color;
+ }
+
+ void getMBGLValue(ObjCType rawValue, std::vector<MBGLElement> &mbglValue) {
+ mbglValue.reserve(rawValue.count);
+ for (id obj in rawValue) {
+ MBGLElement mbglElement;
+ getMBGLValue(obj, mbglElement);
+ mbglValue.push_back(mbglElement);
+ }
+ }
+};
diff --git a/platform/darwin/src/MGLSymbolStyleLayer.h b/platform/darwin/src/MGLSymbolStyleLayer.h
index b805ee18da..3fcecedca3 100644
--- a/platform/darwin/src/MGLSymbolStyleLayer.h
+++ b/platform/darwin/src/MGLSymbolStyleLayer.h
@@ -1,205 +1,225 @@
// This file is generated.
// Edit platform/darwin/scripts/generate-style-code.js, then run `make style-code-darwin`.
-#import "MGLStyleAttributeValue.h"
-#import "MGLBaseStyleLayer.h"
+#import "MGLStyleValue.h"
+#import "MGLVectorStyleLayer.h"
NS_ASSUME_NONNULL_BEGIN
/**
Label placement relative to its geometry.
+
+ Values of this type are used in the `symbolPlacement` property of `MGLSymbolStyleLayer`.
*/
-typedef NS_ENUM(NSUInteger, MGLSymbolStyleLayerSymbolPlacement) {
+typedef NS_ENUM(NSUInteger, MGLSymbolPlacement) {
/**
The label is placed at the point where the geometry is located.
*/
- MGLSymbolStyleLayerSymbolPlacementPoint,
+ MGLSymbolPlacementPoint,
/**
The label is placed along the line of the geometry. Can only be used on `LineString` and `Polygon` geometries.
*/
- MGLSymbolStyleLayerSymbolPlacementLine,
+ MGLSymbolPlacementLine,
};
/**
In combination with `symbolPlacement`, determines the rotation behavior of icons.
+
+ Values of this type are used in the `iconRotationAlignment` property of `MGLSymbolStyleLayer`.
*/
-typedef NS_ENUM(NSUInteger, MGLSymbolStyleLayerIconRotationAlignment) {
+typedef NS_ENUM(NSUInteger, MGLIconRotationAlignment) {
/**
- When `symbolPlacement` is set to `MGLSymbolStyleLayerSymbolPlacementPoint`, aligns icons east-west. When `symbolPlacement` is set to `MGLSymbolStyleLayerSymbolPlacementLine`, aligns icon x-axes with the line.
+ When `symbolPlacement` is set to `MGLSymbolPlacementPoint`, aligns icons east-west. When `symbolPlacement` is set to `MGLSymbolPlacementLine`, aligns icon x-axes with the line.
*/
- MGLSymbolStyleLayerIconRotationAlignmentMap,
+ MGLIconRotationAlignmentMap,
/**
Produces icons whose x-axes are aligned with the x-axis of the viewport, regardless of the value of `symbolPlacement`.
*/
- MGLSymbolStyleLayerIconRotationAlignmentViewport,
+ MGLIconRotationAlignmentViewport,
/**
- When `symbolPlacement` is set to `MGLSymbolStyleLayerSymbolPlacementPoint`, this is equivalent to `MGLSymbolStyleLayerIconRotationAlignmentViewport`. When `symbolPlacement` is set to `MGLSymbolStyleLayerSymbolPlacementLine`, this is equivalent to `MGLSymbolStyleLayerIconRotationAlignmentMap`.
+ When `symbolPlacement` is set to `MGLSymbolPlacementPoint`, this is equivalent to `MGLIconRotationAlignmentViewport`. When `symbolPlacement` is set to `MGLSymbolPlacementLine`, this is equivalent to `MGLIconRotationAlignmentMap`.
*/
- MGLSymbolStyleLayerIconRotationAlignmentAuto,
+ MGLIconRotationAlignmentAuto,
};
/**
Scales the icon to fit around the associated text.
+
+ Values of this type are used in the `iconTextFit` property of `MGLSymbolStyleLayer`.
*/
-typedef NS_ENUM(NSUInteger, MGLSymbolStyleLayerIconTextFit) {
+typedef NS_ENUM(NSUInteger, MGLIconTextFit) {
/**
The icon is displayed at its intrinsic aspect ratio.
*/
- MGLSymbolStyleLayerIconTextFitNone,
+ MGLIconTextFitNone,
/**
The icon is scaled in the x-dimension to fit the width of the text.
*/
- MGLSymbolStyleLayerIconTextFitWidth,
+ MGLIconTextFitWidth,
/**
The icon is scaled in the y-dimension to fit the height of the text.
*/
- MGLSymbolStyleLayerIconTextFitHeight,
+ MGLIconTextFitHeight,
/**
The icon is scaled in both x- and y-dimensions.
*/
- MGLSymbolStyleLayerIconTextFitBoth,
+ MGLIconTextFitBoth,
};
/**
Orientation of text when map is pitched.
+
+ Values of this type are used in the `textPitchAlignment` property of `MGLSymbolStyleLayer`.
*/
-typedef NS_ENUM(NSUInteger, MGLSymbolStyleLayerTextPitchAlignment) {
+typedef NS_ENUM(NSUInteger, MGLTextPitchAlignment) {
/**
The text is aligned to the plane of the map.
*/
- MGLSymbolStyleLayerTextPitchAlignmentMap,
+ MGLTextPitchAlignmentMap,
/**
The text is aligned to the plane of the viewport.
*/
- MGLSymbolStyleLayerTextPitchAlignmentViewport,
+ MGLTextPitchAlignmentViewport,
/**
Automatically matches the value of `textRotationAlignment`.
*/
- MGLSymbolStyleLayerTextPitchAlignmentAuto,
+ MGLTextPitchAlignmentAuto,
};
/**
In combination with `symbolPlacement`, determines the rotation behavior of the individual glyphs forming the text.
+
+ Values of this type are used in the `textRotationAlignment` property of `MGLSymbolStyleLayer`.
*/
-typedef NS_ENUM(NSUInteger, MGLSymbolStyleLayerTextRotationAlignment) {
+typedef NS_ENUM(NSUInteger, MGLTextRotationAlignment) {
/**
- When `symbolPlacement` is set to `MGLSymbolStyleLayerSymbolPlacementPoint`, aligns text east-west. When `symbolPlacement` is set to `MGLSymbolStyleLayerSymbolPlacementLine`, aligns text x-axes with the line.
+ When `symbolPlacement` is set to `MGLSymbolPlacementPoint`, aligns text east-west. When `symbolPlacement` is set to `MGLSymbolPlacementLine`, aligns text x-axes with the line.
*/
- MGLSymbolStyleLayerTextRotationAlignmentMap,
+ MGLTextRotationAlignmentMap,
/**
Produces glyphs whose x-axes are aligned with the x-axis of the viewport, regardless of the value of `symbolPlacement`.
*/
- MGLSymbolStyleLayerTextRotationAlignmentViewport,
+ MGLTextRotationAlignmentViewport,
/**
- When `symbolPlacement` is set to `MGLSymbolStyleLayerSymbolPlacementPoint`, this is equivalent to `MGLSymbolStyleLayerTextRotationAlignmentViewport`. When `symbolPlacement` is set to `MGLSymbolStyleLayerSymbolPlacementLine`, this is equivalent to `MGLSymbolStyleLayerTextRotationAlignmentMap`.
+ When `symbolPlacement` is set to `MGLSymbolPlacementPoint`, this is equivalent to `MGLTextRotationAlignmentViewport`. When `symbolPlacement` is set to `MGLSymbolPlacementLine`, this is equivalent to `MGLTextRotationAlignmentMap`.
*/
- MGLSymbolStyleLayerTextRotationAlignmentAuto,
+ MGLTextRotationAlignmentAuto,
};
/**
Text justification options.
+
+ Values of this type are used in the `textJustify` property of `MGLSymbolStyleLayer`.
*/
-typedef NS_ENUM(NSUInteger, MGLSymbolStyleLayerTextJustify) {
+typedef NS_ENUM(NSUInteger, MGLTextJustify) {
/**
The text is aligned to the left.
*/
- MGLSymbolStyleLayerTextJustifyLeft,
+ MGLTextJustifyLeft,
/**
The text is centered.
*/
- MGLSymbolStyleLayerTextJustifyCenter,
+ MGLTextJustifyCenter,
/**
The text is aligned to the right.
*/
- MGLSymbolStyleLayerTextJustifyRight,
+ MGLTextJustifyRight,
};
/**
Part of the text placed closest to the anchor.
+
+ Values of this type are used in the `textAnchor` property of `MGLSymbolStyleLayer`.
*/
-typedef NS_ENUM(NSUInteger, MGLSymbolStyleLayerTextAnchor) {
+typedef NS_ENUM(NSUInteger, MGLTextAnchor) {
/**
The center of the text is placed closest to the anchor.
*/
- MGLSymbolStyleLayerTextAnchorCenter,
+ MGLTextAnchorCenter,
/**
The left side of the text is placed closest to the anchor.
*/
- MGLSymbolStyleLayerTextAnchorLeft,
+ MGLTextAnchorLeft,
/**
The right side of the text is placed closest to the anchor.
*/
- MGLSymbolStyleLayerTextAnchorRight,
+ MGLTextAnchorRight,
/**
The top of the text is placed closest to the anchor.
*/
- MGLSymbolStyleLayerTextAnchorTop,
+ MGLTextAnchorTop,
/**
The bottom of the text is placed closest to the anchor.
*/
- MGLSymbolStyleLayerTextAnchorBottom,
+ MGLTextAnchorBottom,
/**
The top left corner of the text is placed closest to the anchor.
*/
- MGLSymbolStyleLayerTextAnchorTopLeft,
+ MGLTextAnchorTopLeft,
/**
The top right corner of the text is placed closest to the anchor.
*/
- MGLSymbolStyleLayerTextAnchorTopRight,
+ MGLTextAnchorTopRight,
/**
The bottom left corner of the text is placed closest to the anchor.
*/
- MGLSymbolStyleLayerTextAnchorBottomLeft,
+ MGLTextAnchorBottomLeft,
/**
The bottom right corner of the text is placed closest to the anchor.
*/
- MGLSymbolStyleLayerTextAnchorBottomRight,
+ MGLTextAnchorBottomRight,
};
/**
Specifies how to capitalize text, similar to the CSS `text-transform` property.
+
+ Values of this type are used in the `textTransform` property of `MGLSymbolStyleLayer`.
*/
-typedef NS_ENUM(NSUInteger, MGLSymbolStyleLayerTextTransform) {
+typedef NS_ENUM(NSUInteger, MGLTextTransform) {
/**
The text is not altered.
*/
- MGLSymbolStyleLayerTextTransformNone,
+ MGLTextTransformNone,
/**
Forces all letters to be displayed in uppercase.
*/
- MGLSymbolStyleLayerTextTransformUppercase,
+ MGLTextTransformUppercase,
/**
Forces all letters to be displayed in lowercase.
*/
- MGLSymbolStyleLayerTextTransformLowercase,
+ MGLTextTransformLowercase,
};
/**
Controls the translation reference point.
+
+ Values of this type are used in the `iconTranslateAnchor` property of `MGLSymbolStyleLayer`.
*/
-typedef NS_ENUM(NSUInteger, MGLSymbolStyleLayerIconTranslateAnchor) {
+typedef NS_ENUM(NSUInteger, MGLIconTranslateAnchor) {
/**
Icons are translated relative to the map.
*/
- MGLSymbolStyleLayerIconTranslateAnchorMap,
+ MGLIconTranslateAnchorMap,
/**
Icons are translated relative to the viewport.
*/
- MGLSymbolStyleLayerIconTranslateAnchorViewport,
+ MGLIconTranslateAnchorViewport,
};
/**
Controls the translation reference point.
+
+ Values of this type are used in the `textTranslateAnchor` property of `MGLSymbolStyleLayer`.
*/
-typedef NS_ENUM(NSUInteger, MGLSymbolStyleLayerTextTranslateAnchor) {
+typedef NS_ENUM(NSUInteger, MGLTextTranslateAnchor) {
/**
The text is translated relative to the map.
*/
- MGLSymbolStyleLayerTextTranslateAnchorMap,
+ MGLTextTranslateAnchorMap,
/**
The text is translated relative to the viewport.
*/
- MGLSymbolStyleLayerTextTranslateAnchorViewport,
+ MGLTextTranslateAnchorViewport,
};
/**
@@ -208,391 +228,379 @@ typedef NS_ENUM(NSUInteger, MGLSymbolStyleLayerTextTranslateAnchor) {
`MGLMapView` for its `style` and obtain existing layers using the
`-[MGLStyle layerWithIdentifier:]` method.
*/
-@interface MGLSymbolStyleLayer : MGLBaseStyleLayer <MGLStyleLayer>
-
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier source:(MGLSource *)source;
-
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier source:(MGLSource *)source sourceLayer:(NSString *)sourceLayer;
-
-/**
- A predicate that corresponds to the layer's <a href='https://www.mapbox.com/mapbox-gl-style-spec/#types-filter'>filter</a>.
-
- The predicate's left expression must be a string that identifies a feature
- property, or one of the special keys.
- */
-@property (nonatomic, nullable) NSPredicate *predicate;
+@interface MGLSymbolStyleLayer : MGLVectorStyleLayer
#pragma mark - Accessing the Layout Attributes
/**
Label placement relative to its geometry.
- The default value of this property is an `NSValue` object containing `MGLSymbolStyleLayerSymbolPlacementPoint`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLSymbolPlacementPoint`. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> symbolPlacement;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *symbolPlacement;
/**
Distance between two symbol anchors.
This property is measured in points.
- The default value of this property is an `NSNumber` object containing the float `250`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `250`. Set this property to `nil` to reset it to the default value.
- This property is only applied to the style if `symbolPlacement` is set to an `NSValue` object containing `MGLSymbolStyleLayerSymbolPlacementLine`. Otherwise, it is ignored.
+ This property is only applied to the style if `symbolPlacement` is set to an `MGLStyleValue` object containing an `NSValue` object containing `MGLSymbolPlacementLine`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> symbolSpacing;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *symbolSpacing;
/**
If true, the symbols will not cross tile edges to avoid mutual collisions. Recommended in layers that don't have enough padding in the vector tile to prevent collisions, or if it is a point symbol layer placed after a line symbol layer.
- The default value of this property is an `NSNumber` object containing `NO`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing `NO`. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> symbolAvoidEdges;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *symbolAvoidEdges;
/**
If true, the icon will be visible even if it collides with other previously drawn symbols.
- The default value of this property is an `NSNumber` object containing `NO`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing `NO`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `iconImage` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> iconAllowOverlap;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *iconAllowOverlap;
/**
If true, other symbols can be visible even if they collide with the icon.
- The default value of this property is an `NSNumber` object containing `NO`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing `NO`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `iconImage` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> iconIgnorePlacement;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *iconIgnorePlacement;
/**
If true, text will display without their corresponding icons when the icon collides with other symbols and the text does not.
- The default value of this property is an `NSNumber` object containing `NO`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing `NO`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `iconImage` is non-`nil`, and `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> iconOptional;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *iconOptional;
/**
In combination with `symbolPlacement`, determines the rotation behavior of icons.
- The default value of this property is an `NSValue` object containing `MGLSymbolStyleLayerIconRotationAlignmentAuto`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLIconRotationAlignmentAuto`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `iconImage` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> iconRotationAlignment;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *iconRotationAlignment;
/**
Scale factor for icon. 1 is original size, 3 triples the size.
- The default value of this property is an `NSNumber` object containing the float `1`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `1`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `iconImage` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> iconSize;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *iconSize;
/**
Scales the icon to fit around the associated text.
- The default value of this property is an `NSValue` object containing `MGLSymbolStyleLayerIconTextFitNone`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLIconTextFitNone`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `iconImage` is non-`nil`, and `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> iconTextFit;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *iconTextFit;
/**
Size of the additional area added to dimensions determined by `iconTextFit`, in clockwise order: top, right, bottom, left.
This property is measured in points.
- The default value of this property is an `NSValue` object containing `NSEdgeInsetsZero` or `UIEdgeInsetsZero`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `NSEdgeInsetsZero` or `UIEdgeInsetsZero`. Set this property to `nil` to reset it to the default value.
- This property is only applied to the style if `iconImage` is non-`nil`, and `textField` is non-`nil`, and `iconTextFit` is set to an `NSValue` object containing `MGLSymbolStyleLayerIconTextFitBoth`, `MGLSymbolStyleLayerIconTextFitWidth`, or `MGLSymbolStyleLayerIconTextFitHeight`. Otherwise, it is ignored.
+ This property is only applied to the style if `iconImage` is non-`nil`, and `textField` is non-`nil`, and `iconTextFit` is set to an `MGLStyleValue` object containing an `NSValue` object containing `MGLIconTextFitBoth`, `MGLIconTextFitWidth`, or `MGLIconTextFitHeight`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> iconTextFitPadding;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *iconTextFitPadding;
/**
A string with {tokens} replaced, referencing the data property to pull from.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> iconImage;
+@property (nonatomic, null_resettable) MGLStyleValue<NSString *> *iconImage;
/**
Rotates the icon clockwise.
This property is measured in degrees.
- The default value of this property is an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `iconImage` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> iconRotate;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *iconRotate;
/**
Size of the additional area around the icon bounding box used for detecting symbol collisions.
This property is measured in points.
- The default value of this property is an `NSNumber` object containing the float `2`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `2`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `iconImage` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> iconPadding;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *iconPadding;
/**
If true, the icon may be flipped to prevent it from being rendered upside-down.
- The default value of this property is an `NSNumber` object containing `NO`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing `NO`. Set this property to `nil` to reset it to the default value.
- This property is only applied to the style if `iconImage` is non-`nil`, and `iconRotationAlignment` is set to an `NSValue` object containing `MGLSymbolStyleLayerIconRotationAlignmentMap`, and `symbolPlacement` is set to an `NSValue` object containing `MGLSymbolStyleLayerSymbolPlacementLine`. Otherwise, it is ignored.
+ This property is only applied to the style if `iconImage` is non-`nil`, and `iconRotationAlignment` is set to an `MGLStyleValue` object containing an `NSValue` object containing `MGLIconRotationAlignmentMap`, and `symbolPlacement` is set to an `MGLStyleValue` object containing an `NSValue` object containing `MGLSymbolPlacementLine`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> iconKeepUpright;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *iconKeepUpright;
/**
Offset distance of icon from its anchor. Positive values indicate right and down, while negative values indicate left and up.
- The default value of this property is an `NSValue` object containing a `CGVector` struct set to 0 from the left and 0 from the top. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing a `CGVector` struct set to 0 from the left and 0 from the top. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `iconImage` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> iconOffset;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *iconOffset;
/**
Orientation of text when map is pitched.
- The default value of this property is an `NSValue` object containing `MGLSymbolStyleLayerTextPitchAlignmentAuto`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLTextPitchAlignmentAuto`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> textPitchAlignment;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *textPitchAlignment;
/**
In combination with `symbolPlacement`, determines the rotation behavior of the individual glyphs forming the text.
- The default value of this property is an `NSValue` object containing `MGLSymbolStyleLayerTextRotationAlignmentAuto`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLTextRotationAlignmentAuto`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> textRotationAlignment;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *textRotationAlignment;
/**
Value to use for a text label. Feature properties are specified using tokens like {field_name}.
- The default value of this property is the string ``. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing the string ``. Set this property to `nil` to reset it to the default value.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> textField;
+@property (nonatomic, null_resettable) MGLStyleValue<NSString *> *textField;
/**
Font stack to use for displaying text.
- The default value of this property is the array `Open Sans Regular`, `Arial Unicode MS Regular`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing the array `Open Sans Regular`, `Arial Unicode MS Regular`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> textFont;
+@property (nonatomic, null_resettable) MGLStyleValue<NSArray<NSString *> *> *textFont;
/**
Font size.
This property is measured in points.
- The default value of this property is an `NSNumber` object containing the float `16`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `16`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> textSize;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textSize;
/**
The maximum line width for text wrapping.
This property is measured in ems.
- The default value of this property is an `NSNumber` object containing the float `10`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `10`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> textMaxWidth;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textMaxWidth;
/**
Text leading value for multi-line text.
This property is measured in ems.
- The default value of this property is an `NSNumber` object containing the float `1.2`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `1.2`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> textLineHeight;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textLineHeight;
/**
Text tracking amount.
This property is measured in ems.
- The default value of this property is an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> textLetterSpacing;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textLetterSpacing;
/**
Text justification options.
- The default value of this property is an `NSValue` object containing `MGLSymbolStyleLayerTextJustifyCenter`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLTextJustifyCenter`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> textJustify;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *textJustify;
/**
Part of the text placed closest to the anchor.
- The default value of this property is an `NSValue` object containing `MGLSymbolStyleLayerTextAnchorCenter`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLTextAnchorCenter`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> textAnchor;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *textAnchor;
/**
Maximum angle change between adjacent characters.
This property is measured in degrees.
- The default value of this property is an `NSNumber` object containing the float `45`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `45`. Set this property to `nil` to reset it to the default value.
- This property is only applied to the style if `textField` is non-`nil`, and `symbolPlacement` is set to an `NSValue` object containing `MGLSymbolStyleLayerSymbolPlacementLine`. Otherwise, it is ignored.
+ This property is only applied to the style if `textField` is non-`nil`, and `symbolPlacement` is set to an `MGLStyleValue` object containing an `NSValue` object containing `MGLSymbolPlacementLine`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> textMaxAngle;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textMaxAngle;
/**
Rotates the text clockwise.
This property is measured in degrees.
- The default value of this property is an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> textRotate;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textRotate;
/**
Size of the additional area around the text bounding box used for detecting symbol collisions.
This property is measured in points.
- The default value of this property is an `NSNumber` object containing the float `2`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `2`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> textPadding;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textPadding;
/**
If true, the text may be flipped vertically to prevent it from being rendered upside-down.
- The default value of this property is an `NSNumber` object containing `YES`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing `YES`. Set this property to `nil` to reset it to the default value.
- This property is only applied to the style if `textField` is non-`nil`, and `textRotationAlignment` is set to an `NSValue` object containing `MGLSymbolStyleLayerTextRotationAlignmentMap`, and `symbolPlacement` is set to an `NSValue` object containing `MGLSymbolStyleLayerSymbolPlacementLine`. Otherwise, it is ignored.
+ This property is only applied to the style if `textField` is non-`nil`, and `textRotationAlignment` is set to an `MGLStyleValue` object containing an `NSValue` object containing `MGLTextRotationAlignmentMap`, and `symbolPlacement` is set to an `MGLStyleValue` object containing an `NSValue` object containing `MGLSymbolPlacementLine`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> textKeepUpright;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textKeepUpright;
/**
Specifies how to capitalize text, similar to the CSS `text-transform` property.
- The default value of this property is an `NSValue` object containing `MGLSymbolStyleLayerTextTransformNone`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLTextTransformNone`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> textTransform;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *textTransform;
/**
Offset distance of text from its anchor. Positive values indicate right and down, while negative values indicate left and up.
This property is measured in ems.
- The default value of this property is an `NSValue` object containing a `CGVector` struct set to 0 ems from the left and 0 ems from the top. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing a `CGVector` struct set to 0 ems from the left and 0 ems from the top. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> textOffset;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *textOffset;
/**
If true, the text will be visible even if it collides with other previously drawn symbols.
- The default value of this property is an `NSNumber` object containing `NO`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing `NO`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> textAllowOverlap;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textAllowOverlap;
/**
If true, other symbols can be visible even if they collide with the text.
- The default value of this property is an `NSNumber` object containing `NO`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing `NO`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> textIgnorePlacement;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textIgnorePlacement;
/**
If true, icons will display without their corresponding text when the text collides with other symbols and the icon does not.
- The default value of this property is an `NSNumber` object containing `NO`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing `NO`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`, and `iconImage` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> textOptional;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textOptional;
#pragma mark - Accessing the Paint Attributes
/**
The opacity at which the icon will be drawn.
- The default value of this property is an `NSNumber` object containing the float `1`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `1`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `iconImage` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> iconOpacity;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *iconOpacity;
#if TARGET_OS_IPHONE
/**
The color of the icon. This can only be used with sdf icons.
- The default value of this property is `UIColor.blackColor`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing `UIColor.blackColor`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `iconImage` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> iconColor;
+@property (nonatomic, null_resettable) MGLStyleValue<MGLColor *> *iconColor;
#else
/**
The color of the icon. This can only be used with sdf icons.
- The default value of this property is `NSColor.blackColor`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing `NSColor.blackColor`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `iconImage` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> iconColor;
+@property (nonatomic, null_resettable) MGLStyleValue<MGLColor *> *iconColor;
#endif
#if TARGET_OS_IPHONE
/**
The color of the icon's halo. Icon halos can only be used with SDF icons.
- The default value of this property is `UIColor.clearColor`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing `UIColor.clearColor`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `iconImage` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> iconHaloColor;
+@property (nonatomic, null_resettable) MGLStyleValue<MGLColor *> *iconHaloColor;
#else
/**
The color of the icon's halo. Icon halos can only be used with SDF icons.
- The default value of this property is `NSColor.clearColor`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing `NSColor.clearColor`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `iconImage` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> iconHaloColor;
+@property (nonatomic, null_resettable) MGLStyleValue<MGLColor *> *iconHaloColor;
#endif
/**
@@ -600,90 +608,90 @@ typedef NS_ENUM(NSUInteger, MGLSymbolStyleLayerTextTranslateAnchor) {
This property is measured in points.
- The default value of this property is an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `iconImage` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> iconHaloWidth;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *iconHaloWidth;
/**
Fade out the halo towards the outside.
This property is measured in points.
- The default value of this property is an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `iconImage` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> iconHaloBlur;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *iconHaloBlur;
/**
Distance that the icon's anchor is moved from its original placement. Positive values indicate right and down, while negative values indicate left and up.
This property is measured in points.
- The default value of this property is an `NSValue` object containing a `CGVector` struct set to 0 points from the left and 0 points from the top. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing a `CGVector` struct set to 0 points from the left and 0 points from the top. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `iconImage` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> iconTranslate;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *iconTranslate;
/**
Controls the translation reference point.
- The default value of this property is an `NSValue` object containing `MGLSymbolStyleLayerIconTranslateAnchorMap`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLIconTranslateAnchorMap`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `iconImage` is non-`nil`, and `iconTranslate` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> iconTranslateAnchor;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *iconTranslateAnchor;
/**
The opacity at which the text will be drawn.
- The default value of this property is an `NSNumber` object containing the float `1`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `1`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> textOpacity;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textOpacity;
#if TARGET_OS_IPHONE
/**
The color with which the text will be drawn.
- The default value of this property is `UIColor.blackColor`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing `UIColor.blackColor`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> textColor;
+@property (nonatomic, null_resettable) MGLStyleValue<MGLColor *> *textColor;
#else
/**
The color with which the text will be drawn.
- The default value of this property is `NSColor.blackColor`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing `NSColor.blackColor`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> textColor;
+@property (nonatomic, null_resettable) MGLStyleValue<MGLColor *> *textColor;
#endif
#if TARGET_OS_IPHONE
/**
The color of the text's halo, which helps it stand out from backgrounds.
- The default value of this property is `UIColor.clearColor`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing `UIColor.clearColor`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> textHaloColor;
+@property (nonatomic, null_resettable) MGLStyleValue<MGLColor *> *textHaloColor;
#else
/**
The color of the text's halo, which helps it stand out from backgrounds.
- The default value of this property is `NSColor.clearColor`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing `NSColor.clearColor`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> textHaloColor;
+@property (nonatomic, null_resettable) MGLStyleValue<MGLColor *> *textHaloColor;
#endif
/**
@@ -691,42 +699,42 @@ typedef NS_ENUM(NSUInteger, MGLSymbolStyleLayerTextTranslateAnchor) {
This property is measured in points.
- The default value of this property is an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> textHaloWidth;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textHaloWidth;
/**
The halo's fadeout distance towards the outside.
This property is measured in points.
- The default value of this property is an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSNumber` object containing the float `0`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> textHaloBlur;
+@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *textHaloBlur;
/**
Distance that the text's anchor is moved from its original placement. Positive values indicate right and down, while negative values indicate left and up.
This property is measured in points.
- The default value of this property is an `NSValue` object containing a `CGVector` struct set to 0 points from the left and 0 points from the top. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing a `CGVector` struct set to 0 points from the left and 0 points from the top. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> textTranslate;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *textTranslate;
/**
Controls the translation reference point.
- The default value of this property is an `NSValue` object containing `MGLSymbolStyleLayerTextTranslateAnchorMap`. Set this property to `nil` to reset it to the default value.
+ The default value of this property is an `MGLStyleValue` object containing an `NSValue` object containing `MGLTextTranslateAnchorMap`. Set this property to `nil` to reset it to the default value.
This property is only applied to the style if `textField` is non-`nil`, and `textTranslate` is non-`nil`. Otherwise, it is ignored.
*/
-@property (nonatomic, null_resettable) id <MGLStyleAttributeValue> textTranslateAnchor;
+@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *textTranslateAnchor;
@end
diff --git a/platform/darwin/src/MGLSymbolStyleLayer.mm b/platform/darwin/src/MGLSymbolStyleLayer.mm
index 4d9b20fbcb..a4c56fe297 100644
--- a/platform/darwin/src/MGLSymbolStyleLayer.mm
+++ b/platform/darwin/src/MGLSymbolStyleLayer.mm
@@ -4,7 +4,7 @@
#import "MGLSource.h"
#import "NSPredicate+MGLAdditions.h"
#import "MGLStyleLayer_Private.h"
-#import "MGLStyleAttributeValue.h"
+#import "MGLStyleValue_Private.h"
#import "MGLSymbolStyleLayer.h"
#include <mbgl/style/layers/symbol_layer.hpp>
@@ -12,36 +12,28 @@
@interface MGLSymbolStyleLayer ()
@property (nonatomic) mbgl::style::SymbolLayer *layer;
-@property (nonatomic, readwrite) NSString *layerIdentifier;
-@property (nonatomic, readwrite) NSString *sourceIdentifier;
-@property (nonatomic, readwrite) NSString *sourceLayerIdentifier;
@end
@implementation MGLSymbolStyleLayer
-@synthesize mapView;
-
-
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier source:(MGLSource *)source
+- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source
{
- if (self = [super init]) {
- _layerIdentifier = layerIdentifier;
- _sourceIdentifier = source.sourceIdentifier;
- _layer = new mbgl::style::SymbolLayer(layerIdentifier.UTF8String, source.sourceIdentifier.UTF8String);
+ if (self = [super initWithIdentifier:identifier source:source]) {
+ _layer = new mbgl::style::SymbolLayer(identifier.UTF8String, source.identifier.UTF8String);
}
return self;
}
-- (instancetype)initWithLayerIdentifier:(NSString *)layerIdentifier source:(MGLSource *)source sourceLayer:(NSString *)sourceLayer
+- (NSString *)sourceLayerIdentifier
{
- if (self = [super init]) {
- _layerIdentifier = layerIdentifier;
- _sourceIdentifier = source.sourceIdentifier;
- _layer = new mbgl::style::SymbolLayer(layerIdentifier.UTF8String, source.sourceIdentifier.UTF8String);
- _layer->setSourceLayer(sourceLayer.UTF8String);
- }
- return self;
+ auto layerID = self.layer->getSourceLayer();
+ return layerID.empty() ? nil : @(layerID.c_str());
+}
+
+- (void)setSourceLayerIdentifier:(NSString *)sourceLayerIdentifier
+{
+ self.layer->setSourceLayer(sourceLayerIdentifier.UTF8String ?: "");
}
- (void)setPredicate:(NSPredicate *)predicate
@@ -56,390 +48,486 @@
#pragma mark - Accessing the Layout Attributes
-- (void)setSymbolPlacement:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)symbolPlacement {
- MGLSetEnumProperty(symbolPlacement, SymbolPlacement, SymbolPlacementType, MGLSymbolStyleLayerSymbolPlacement);
+- (void)setSymbolPlacement:(MGLStyleValue<NSValue *> *)symbolPlacement {
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::SymbolPlacementType, NSValue *>().toPropertyValue(symbolPlacement);
+ self.layer->setSymbolPlacement(mbglValue);
}
-- (id <MGLStyleAttributeValue>)symbolPlacement {
- MGLGetEnumProperty(SymbolPlacement, SymbolPlacementType, MGLSymbolStyleLayerSymbolPlacement);
+- (MGLStyleValue<NSValue *> *)symbolPlacement {
+ auto propertyValue = self.layer->getSymbolPlacement() ?: self.layer->getDefaultSymbolPlacement();
+ return MGLStyleValueTransformer<mbgl::style::SymbolPlacementType, NSValue *>().toStyleValue(propertyValue);
}
-- (void)setSymbolSpacing:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)symbolSpacing {
- self.layer->setSymbolSpacing(symbolSpacing.mbgl_floatPropertyValue);
+- (void)setSymbolSpacing:(MGLStyleValue<NSNumber *> *)symbolSpacing {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(symbolSpacing);
+ self.layer->setSymbolSpacing(mbglValue);
}
-- (id <MGLStyleAttributeValue>)symbolSpacing {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getSymbolSpacing() ?: self.layer->getDefaultSymbolSpacing()];
+- (MGLStyleValue<NSNumber *> *)symbolSpacing {
+ auto propertyValue = self.layer->getSymbolSpacing() ?: self.layer->getDefaultSymbolSpacing();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setSymbolAvoidEdges:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)symbolAvoidEdges {
- self.layer->setSymbolAvoidEdges(symbolAvoidEdges.mbgl_boolPropertyValue);
+- (void)setSymbolAvoidEdges:(MGLStyleValue<NSNumber *> *)symbolAvoidEdges {
+ auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue(symbolAvoidEdges);
+ self.layer->setSymbolAvoidEdges(mbglValue);
}
-- (id <MGLStyleAttributeValue>)symbolAvoidEdges {
- return [MGLStyleAttribute mbgl_boolWithPropertyValueBool:self.layer->getSymbolAvoidEdges() ?: self.layer->getDefaultSymbolAvoidEdges()];
+- (MGLStyleValue<NSNumber *> *)symbolAvoidEdges {
+ auto propertyValue = self.layer->getSymbolAvoidEdges() ?: self.layer->getDefaultSymbolAvoidEdges();
+ return MGLStyleValueTransformer<bool, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setIconAllowOverlap:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)iconAllowOverlap {
- self.layer->setIconAllowOverlap(iconAllowOverlap.mbgl_boolPropertyValue);
+- (void)setIconAllowOverlap:(MGLStyleValue<NSNumber *> *)iconAllowOverlap {
+ auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue(iconAllowOverlap);
+ self.layer->setIconAllowOverlap(mbglValue);
}
-- (id <MGLStyleAttributeValue>)iconAllowOverlap {
- return [MGLStyleAttribute mbgl_boolWithPropertyValueBool:self.layer->getIconAllowOverlap() ?: self.layer->getDefaultIconAllowOverlap()];
+- (MGLStyleValue<NSNumber *> *)iconAllowOverlap {
+ auto propertyValue = self.layer->getIconAllowOverlap() ?: self.layer->getDefaultIconAllowOverlap();
+ return MGLStyleValueTransformer<bool, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setIconIgnorePlacement:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)iconIgnorePlacement {
- self.layer->setIconIgnorePlacement(iconIgnorePlacement.mbgl_boolPropertyValue);
+- (void)setIconIgnorePlacement:(MGLStyleValue<NSNumber *> *)iconIgnorePlacement {
+ auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue(iconIgnorePlacement);
+ self.layer->setIconIgnorePlacement(mbglValue);
}
-- (id <MGLStyleAttributeValue>)iconIgnorePlacement {
- return [MGLStyleAttribute mbgl_boolWithPropertyValueBool:self.layer->getIconIgnorePlacement() ?: self.layer->getDefaultIconIgnorePlacement()];
+- (MGLStyleValue<NSNumber *> *)iconIgnorePlacement {
+ auto propertyValue = self.layer->getIconIgnorePlacement() ?: self.layer->getDefaultIconIgnorePlacement();
+ return MGLStyleValueTransformer<bool, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setIconOptional:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)iconOptional {
- self.layer->setIconOptional(iconOptional.mbgl_boolPropertyValue);
+- (void)setIconOptional:(MGLStyleValue<NSNumber *> *)iconOptional {
+ auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue(iconOptional);
+ self.layer->setIconOptional(mbglValue);
}
-- (id <MGLStyleAttributeValue>)iconOptional {
- return [MGLStyleAttribute mbgl_boolWithPropertyValueBool:self.layer->getIconOptional() ?: self.layer->getDefaultIconOptional()];
+- (MGLStyleValue<NSNumber *> *)iconOptional {
+ auto propertyValue = self.layer->getIconOptional() ?: self.layer->getDefaultIconOptional();
+ return MGLStyleValueTransformer<bool, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setIconRotationAlignment:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)iconRotationAlignment {
- MGLSetEnumProperty(iconRotationAlignment, IconRotationAlignment, AlignmentType, MGLSymbolStyleLayerIconRotationAlignment);
+- (void)setIconRotationAlignment:(MGLStyleValue<NSValue *> *)iconRotationAlignment {
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *>().toPropertyValue(iconRotationAlignment);
+ self.layer->setIconRotationAlignment(mbglValue);
}
-- (id <MGLStyleAttributeValue>)iconRotationAlignment {
- MGLGetEnumProperty(IconRotationAlignment, AlignmentType, MGLSymbolStyleLayerIconRotationAlignment);
+- (MGLStyleValue<NSValue *> *)iconRotationAlignment {
+ auto propertyValue = self.layer->getIconRotationAlignment() ?: self.layer->getDefaultIconRotationAlignment();
+ return MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *>().toStyleValue(propertyValue);
}
-- (void)setIconSize:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)iconSize {
- self.layer->setIconSize(iconSize.mbgl_floatPropertyValue);
+- (void)setIconSize:(MGLStyleValue<NSNumber *> *)iconSize {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(iconSize);
+ self.layer->setIconSize(mbglValue);
}
-- (id <MGLStyleAttributeValue>)iconSize {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getIconSize() ?: self.layer->getDefaultIconSize()];
+- (MGLStyleValue<NSNumber *> *)iconSize {
+ auto propertyValue = self.layer->getIconSize() ?: self.layer->getDefaultIconSize();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setIconTextFit:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)iconTextFit {
- MGLSetEnumProperty(iconTextFit, IconTextFit, IconTextFitType, MGLSymbolStyleLayerIconTextFit);
+- (void)setIconTextFit:(MGLStyleValue<NSValue *> *)iconTextFit {
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::IconTextFitType, NSValue *>().toPropertyValue(iconTextFit);
+ self.layer->setIconTextFit(mbglValue);
}
-- (id <MGLStyleAttributeValue>)iconTextFit {
- MGLGetEnumProperty(IconTextFit, IconTextFitType, MGLSymbolStyleLayerIconTextFit);
+- (MGLStyleValue<NSValue *> *)iconTextFit {
+ auto propertyValue = self.layer->getIconTextFit() ?: self.layer->getDefaultIconTextFit();
+ return MGLStyleValueTransformer<mbgl::style::IconTextFitType, NSValue *>().toStyleValue(propertyValue);
}
-- (void)setIconTextFitPadding:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)iconTextFitPadding {
- self.layer->setIconTextFitPadding(iconTextFitPadding.mbgl_paddingPropertyValue);
+- (void)setIconTextFitPadding:(MGLStyleValue<NSValue *> *)iconTextFitPadding {
+ auto mbglValue = MGLStyleValueTransformer<std::array<float, 4>, NSValue *>().toPropertyValue(iconTextFitPadding);
+ self.layer->setIconTextFitPadding(mbglValue);
}
-- (id <MGLStyleAttributeValue>)iconTextFitPadding {
- return [MGLStyleAttribute mbgl_paddingWithPropertyValuePadding:self.layer->getIconTextFitPadding() ?: self.layer->getDefaultIconTextFitPadding()];
+- (MGLStyleValue<NSValue *> *)iconTextFitPadding {
+ auto propertyValue = self.layer->getIconTextFitPadding() ?: self.layer->getDefaultIconTextFitPadding();
+ return MGLStyleValueTransformer<std::array<float, 4>, NSValue *>().toStyleValue(propertyValue);
}
-- (void)setIconImage:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)iconImage {
- self.layer->setIconImage(iconImage.mbgl_stringPropertyValue);
+- (void)setIconImage:(MGLStyleValue<NSString *> *)iconImage {
+ auto mbglValue = MGLStyleValueTransformer<std::string, NSString *>().toPropertyValue(iconImage);
+ self.layer->setIconImage(mbglValue);
}
-- (id <MGLStyleAttributeValue>)iconImage {
- return [MGLStyleAttribute mbgl_stringWithPropertyValueString:self.layer->getIconImage() ?: self.layer->getDefaultIconImage()];
+- (MGLStyleValue<NSString *> *)iconImage {
+ auto propertyValue = self.layer->getIconImage() ?: self.layer->getDefaultIconImage();
+ return MGLStyleValueTransformer<std::string, NSString *>().toStyleValue(propertyValue);
}
-- (void)setIconRotate:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)iconRotate {
- self.layer->setIconRotate(iconRotate.mbgl_floatPropertyValue);
+- (void)setIconRotate:(MGLStyleValue<NSNumber *> *)iconRotate {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(iconRotate);
+ self.layer->setIconRotate(mbglValue);
}
-- (id <MGLStyleAttributeValue>)iconRotate {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getIconRotate() ?: self.layer->getDefaultIconRotate()];
+- (MGLStyleValue<NSNumber *> *)iconRotate {
+ auto propertyValue = self.layer->getIconRotate() ?: self.layer->getDefaultIconRotate();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setIconPadding:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)iconPadding {
- self.layer->setIconPadding(iconPadding.mbgl_floatPropertyValue);
+- (void)setIconPadding:(MGLStyleValue<NSNumber *> *)iconPadding {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(iconPadding);
+ self.layer->setIconPadding(mbglValue);
}
-- (id <MGLStyleAttributeValue>)iconPadding {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getIconPadding() ?: self.layer->getDefaultIconPadding()];
+- (MGLStyleValue<NSNumber *> *)iconPadding {
+ auto propertyValue = self.layer->getIconPadding() ?: self.layer->getDefaultIconPadding();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setIconKeepUpright:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)iconKeepUpright {
- self.layer->setIconKeepUpright(iconKeepUpright.mbgl_boolPropertyValue);
+- (void)setIconKeepUpright:(MGLStyleValue<NSNumber *> *)iconKeepUpright {
+ auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue(iconKeepUpright);
+ self.layer->setIconKeepUpright(mbglValue);
}
-- (id <MGLStyleAttributeValue>)iconKeepUpright {
- return [MGLStyleAttribute mbgl_boolWithPropertyValueBool:self.layer->getIconKeepUpright() ?: self.layer->getDefaultIconKeepUpright()];
+- (MGLStyleValue<NSNumber *> *)iconKeepUpright {
+ auto propertyValue = self.layer->getIconKeepUpright() ?: self.layer->getDefaultIconKeepUpright();
+ return MGLStyleValueTransformer<bool, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setIconOffset:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)iconOffset {
- self.layer->setIconOffset(iconOffset.mbgl_offsetPropertyValue);
+- (void)setIconOffset:(MGLStyleValue<NSValue *> *)iconOffset {
+ auto mbglValue = MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toPropertyValue(iconOffset);
+ self.layer->setIconOffset(mbglValue);
}
-- (id <MGLStyleAttributeValue>)iconOffset {
- return [MGLStyleAttribute mbgl_offsetWithPropertyValueOffset:self.layer->getIconOffset() ?: self.layer->getDefaultIconOffset()];
+- (MGLStyleValue<NSValue *> *)iconOffset {
+ auto propertyValue = self.layer->getIconOffset() ?: self.layer->getDefaultIconOffset();
+ return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toStyleValue(propertyValue);
}
-- (void)setTextPitchAlignment:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)textPitchAlignment {
- MGLSetEnumProperty(textPitchAlignment, TextPitchAlignment, AlignmentType, MGLSymbolStyleLayerTextPitchAlignment);
+- (void)setTextPitchAlignment:(MGLStyleValue<NSValue *> *)textPitchAlignment {
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *>().toPropertyValue(textPitchAlignment);
+ self.layer->setTextPitchAlignment(mbglValue);
}
-- (id <MGLStyleAttributeValue>)textPitchAlignment {
- MGLGetEnumProperty(TextPitchAlignment, AlignmentType, MGLSymbolStyleLayerTextPitchAlignment);
+- (MGLStyleValue<NSValue *> *)textPitchAlignment {
+ auto propertyValue = self.layer->getTextPitchAlignment() ?: self.layer->getDefaultTextPitchAlignment();
+ return MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *>().toStyleValue(propertyValue);
}
-- (void)setTextRotationAlignment:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)textRotationAlignment {
- MGLSetEnumProperty(textRotationAlignment, TextRotationAlignment, AlignmentType, MGLSymbolStyleLayerTextRotationAlignment);
+- (void)setTextRotationAlignment:(MGLStyleValue<NSValue *> *)textRotationAlignment {
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *>().toPropertyValue(textRotationAlignment);
+ self.layer->setTextRotationAlignment(mbglValue);
}
-- (id <MGLStyleAttributeValue>)textRotationAlignment {
- MGLGetEnumProperty(TextRotationAlignment, AlignmentType, MGLSymbolStyleLayerTextRotationAlignment);
+- (MGLStyleValue<NSValue *> *)textRotationAlignment {
+ auto propertyValue = self.layer->getTextRotationAlignment() ?: self.layer->getDefaultTextRotationAlignment();
+ return MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *>().toStyleValue(propertyValue);
}
-- (void)setTextField:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)textField {
- self.layer->setTextField(textField.mbgl_stringPropertyValue);
+- (void)setTextField:(MGLStyleValue<NSString *> *)textField {
+ auto mbglValue = MGLStyleValueTransformer<std::string, NSString *>().toPropertyValue(textField);
+ self.layer->setTextField(mbglValue);
}
-- (id <MGLStyleAttributeValue>)textField {
- return [MGLStyleAttribute mbgl_stringWithPropertyValueString:self.layer->getTextField() ?: self.layer->getDefaultTextField()];
+- (MGLStyleValue<NSString *> *)textField {
+ auto propertyValue = self.layer->getTextField() ?: self.layer->getDefaultTextField();
+ return MGLStyleValueTransformer<std::string, NSString *>().toStyleValue(propertyValue);
}
-- (void)setTextFont:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)textFont {
- self.layer->setTextFont(textFont.mbgl_stringArrayPropertyValue);
+- (void)setTextFont:(MGLStyleValue<NSArray<NSString *> *> *)textFont {
+ auto mbglValue = MGLStyleValueTransformer<std::vector<std::string>, NSArray<NSString *> *, std::string>().toPropertyValue(textFont);
+ self.layer->setTextFont(mbglValue);
}
-- (id <MGLStyleAttributeValue>)textFont {
- return [MGLStyleAttribute mbgl_stringArrayWithPropertyValueStringArray:self.layer->getTextFont() ?: self.layer->getDefaultTextFont()];
+- (MGLStyleValue<NSArray<NSString *> *> *)textFont {
+ auto propertyValue = self.layer->getTextFont() ?: self.layer->getDefaultTextFont();
+ return MGLStyleValueTransformer<std::vector<std::string>, NSArray<NSString *> *, std::string>().toStyleValue(propertyValue);
}
-- (void)setTextSize:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)textSize {
- self.layer->setTextSize(textSize.mbgl_floatPropertyValue);
+- (void)setTextSize:(MGLStyleValue<NSNumber *> *)textSize {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(textSize);
+ self.layer->setTextSize(mbglValue);
}
-- (id <MGLStyleAttributeValue>)textSize {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getTextSize() ?: self.layer->getDefaultTextSize()];
+- (MGLStyleValue<NSNumber *> *)textSize {
+ auto propertyValue = self.layer->getTextSize() ?: self.layer->getDefaultTextSize();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setTextMaxWidth:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)textMaxWidth {
- self.layer->setTextMaxWidth(textMaxWidth.mbgl_floatPropertyValue);
+- (void)setTextMaxWidth:(MGLStyleValue<NSNumber *> *)textMaxWidth {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(textMaxWidth);
+ self.layer->setTextMaxWidth(mbglValue);
}
-- (id <MGLStyleAttributeValue>)textMaxWidth {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getTextMaxWidth() ?: self.layer->getDefaultTextMaxWidth()];
+- (MGLStyleValue<NSNumber *> *)textMaxWidth {
+ auto propertyValue = self.layer->getTextMaxWidth() ?: self.layer->getDefaultTextMaxWidth();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setTextLineHeight:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)textLineHeight {
- self.layer->setTextLineHeight(textLineHeight.mbgl_floatPropertyValue);
+- (void)setTextLineHeight:(MGLStyleValue<NSNumber *> *)textLineHeight {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(textLineHeight);
+ self.layer->setTextLineHeight(mbglValue);
}
-- (id <MGLStyleAttributeValue>)textLineHeight {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getTextLineHeight() ?: self.layer->getDefaultTextLineHeight()];
+- (MGLStyleValue<NSNumber *> *)textLineHeight {
+ auto propertyValue = self.layer->getTextLineHeight() ?: self.layer->getDefaultTextLineHeight();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setTextLetterSpacing:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)textLetterSpacing {
- self.layer->setTextLetterSpacing(textLetterSpacing.mbgl_floatPropertyValue);
+- (void)setTextLetterSpacing:(MGLStyleValue<NSNumber *> *)textLetterSpacing {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(textLetterSpacing);
+ self.layer->setTextLetterSpacing(mbglValue);
}
-- (id <MGLStyleAttributeValue>)textLetterSpacing {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getTextLetterSpacing() ?: self.layer->getDefaultTextLetterSpacing()];
+- (MGLStyleValue<NSNumber *> *)textLetterSpacing {
+ auto propertyValue = self.layer->getTextLetterSpacing() ?: self.layer->getDefaultTextLetterSpacing();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setTextJustify:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)textJustify {
- MGLSetEnumProperty(textJustify, TextJustify, TextJustifyType, MGLSymbolStyleLayerTextJustify);
+- (void)setTextJustify:(MGLStyleValue<NSValue *> *)textJustify {
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::TextJustifyType, NSValue *>().toPropertyValue(textJustify);
+ self.layer->setTextJustify(mbglValue);
}
-- (id <MGLStyleAttributeValue>)textJustify {
- MGLGetEnumProperty(TextJustify, TextJustifyType, MGLSymbolStyleLayerTextJustify);
+- (MGLStyleValue<NSValue *> *)textJustify {
+ auto propertyValue = self.layer->getTextJustify() ?: self.layer->getDefaultTextJustify();
+ return MGLStyleValueTransformer<mbgl::style::TextJustifyType, NSValue *>().toStyleValue(propertyValue);
}
-- (void)setTextAnchor:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)textAnchor {
- MGLSetEnumProperty(textAnchor, TextAnchor, TextAnchorType, MGLSymbolStyleLayerTextAnchor);
+- (void)setTextAnchor:(MGLStyleValue<NSValue *> *)textAnchor {
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::TextAnchorType, NSValue *>().toPropertyValue(textAnchor);
+ self.layer->setTextAnchor(mbglValue);
}
-- (id <MGLStyleAttributeValue>)textAnchor {
- MGLGetEnumProperty(TextAnchor, TextAnchorType, MGLSymbolStyleLayerTextAnchor);
+- (MGLStyleValue<NSValue *> *)textAnchor {
+ auto propertyValue = self.layer->getTextAnchor() ?: self.layer->getDefaultTextAnchor();
+ return MGLStyleValueTransformer<mbgl::style::TextAnchorType, NSValue *>().toStyleValue(propertyValue);
}
-- (void)setTextMaxAngle:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)textMaxAngle {
- self.layer->setTextMaxAngle(textMaxAngle.mbgl_floatPropertyValue);
+- (void)setTextMaxAngle:(MGLStyleValue<NSNumber *> *)textMaxAngle {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(textMaxAngle);
+ self.layer->setTextMaxAngle(mbglValue);
}
-- (id <MGLStyleAttributeValue>)textMaxAngle {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getTextMaxAngle() ?: self.layer->getDefaultTextMaxAngle()];
+- (MGLStyleValue<NSNumber *> *)textMaxAngle {
+ auto propertyValue = self.layer->getTextMaxAngle() ?: self.layer->getDefaultTextMaxAngle();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setTextRotate:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)textRotate {
- self.layer->setTextRotate(textRotate.mbgl_floatPropertyValue);
+- (void)setTextRotate:(MGLStyleValue<NSNumber *> *)textRotate {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(textRotate);
+ self.layer->setTextRotate(mbglValue);
}
-- (id <MGLStyleAttributeValue>)textRotate {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getTextRotate() ?: self.layer->getDefaultTextRotate()];
+- (MGLStyleValue<NSNumber *> *)textRotate {
+ auto propertyValue = self.layer->getTextRotate() ?: self.layer->getDefaultTextRotate();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setTextPadding:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)textPadding {
- self.layer->setTextPadding(textPadding.mbgl_floatPropertyValue);
+- (void)setTextPadding:(MGLStyleValue<NSNumber *> *)textPadding {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(textPadding);
+ self.layer->setTextPadding(mbglValue);
}
-- (id <MGLStyleAttributeValue>)textPadding {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getTextPadding() ?: self.layer->getDefaultTextPadding()];
+- (MGLStyleValue<NSNumber *> *)textPadding {
+ auto propertyValue = self.layer->getTextPadding() ?: self.layer->getDefaultTextPadding();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setTextKeepUpright:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)textKeepUpright {
- self.layer->setTextKeepUpright(textKeepUpright.mbgl_boolPropertyValue);
+- (void)setTextKeepUpright:(MGLStyleValue<NSNumber *> *)textKeepUpright {
+ auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue(textKeepUpright);
+ self.layer->setTextKeepUpright(mbglValue);
}
-- (id <MGLStyleAttributeValue>)textKeepUpright {
- return [MGLStyleAttribute mbgl_boolWithPropertyValueBool:self.layer->getTextKeepUpright() ?: self.layer->getDefaultTextKeepUpright()];
+- (MGLStyleValue<NSNumber *> *)textKeepUpright {
+ auto propertyValue = self.layer->getTextKeepUpright() ?: self.layer->getDefaultTextKeepUpright();
+ return MGLStyleValueTransformer<bool, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setTextTransform:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)textTransform {
- MGLSetEnumProperty(textTransform, TextTransform, TextTransformType, MGLSymbolStyleLayerTextTransform);
+- (void)setTextTransform:(MGLStyleValue<NSValue *> *)textTransform {
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::TextTransformType, NSValue *>().toPropertyValue(textTransform);
+ self.layer->setTextTransform(mbglValue);
}
-- (id <MGLStyleAttributeValue>)textTransform {
- MGLGetEnumProperty(TextTransform, TextTransformType, MGLSymbolStyleLayerTextTransform);
+- (MGLStyleValue<NSValue *> *)textTransform {
+ auto propertyValue = self.layer->getTextTransform() ?: self.layer->getDefaultTextTransform();
+ return MGLStyleValueTransformer<mbgl::style::TextTransformType, NSValue *>().toStyleValue(propertyValue);
}
-- (void)setTextOffset:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)textOffset {
- self.layer->setTextOffset(textOffset.mbgl_offsetPropertyValue);
+- (void)setTextOffset:(MGLStyleValue<NSValue *> *)textOffset {
+ auto mbglValue = MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toPropertyValue(textOffset);
+ self.layer->setTextOffset(mbglValue);
}
-- (id <MGLStyleAttributeValue>)textOffset {
- return [MGLStyleAttribute mbgl_offsetWithPropertyValueOffset:self.layer->getTextOffset() ?: self.layer->getDefaultTextOffset()];
+- (MGLStyleValue<NSValue *> *)textOffset {
+ auto propertyValue = self.layer->getTextOffset() ?: self.layer->getDefaultTextOffset();
+ return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toStyleValue(propertyValue);
}
-- (void)setTextAllowOverlap:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)textAllowOverlap {
- self.layer->setTextAllowOverlap(textAllowOverlap.mbgl_boolPropertyValue);
+- (void)setTextAllowOverlap:(MGLStyleValue<NSNumber *> *)textAllowOverlap {
+ auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue(textAllowOverlap);
+ self.layer->setTextAllowOverlap(mbglValue);
}
-- (id <MGLStyleAttributeValue>)textAllowOverlap {
- return [MGLStyleAttribute mbgl_boolWithPropertyValueBool:self.layer->getTextAllowOverlap() ?: self.layer->getDefaultTextAllowOverlap()];
+- (MGLStyleValue<NSNumber *> *)textAllowOverlap {
+ auto propertyValue = self.layer->getTextAllowOverlap() ?: self.layer->getDefaultTextAllowOverlap();
+ return MGLStyleValueTransformer<bool, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setTextIgnorePlacement:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)textIgnorePlacement {
- self.layer->setTextIgnorePlacement(textIgnorePlacement.mbgl_boolPropertyValue);
+- (void)setTextIgnorePlacement:(MGLStyleValue<NSNumber *> *)textIgnorePlacement {
+ auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue(textIgnorePlacement);
+ self.layer->setTextIgnorePlacement(mbglValue);
}
-- (id <MGLStyleAttributeValue>)textIgnorePlacement {
- return [MGLStyleAttribute mbgl_boolWithPropertyValueBool:self.layer->getTextIgnorePlacement() ?: self.layer->getDefaultTextIgnorePlacement()];
+- (MGLStyleValue<NSNumber *> *)textIgnorePlacement {
+ auto propertyValue = self.layer->getTextIgnorePlacement() ?: self.layer->getDefaultTextIgnorePlacement();
+ return MGLStyleValueTransformer<bool, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setTextOptional:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)textOptional {
- self.layer->setTextOptional(textOptional.mbgl_boolPropertyValue);
+- (void)setTextOptional:(MGLStyleValue<NSNumber *> *)textOptional {
+ auto mbglValue = MGLStyleValueTransformer<bool, NSNumber *>().toPropertyValue(textOptional);
+ self.layer->setTextOptional(mbglValue);
}
-- (id <MGLStyleAttributeValue>)textOptional {
- return [MGLStyleAttribute mbgl_boolWithPropertyValueBool:self.layer->getTextOptional() ?: self.layer->getDefaultTextOptional()];
+- (MGLStyleValue<NSNumber *> *)textOptional {
+ auto propertyValue = self.layer->getTextOptional() ?: self.layer->getDefaultTextOptional();
+ return MGLStyleValueTransformer<bool, NSNumber *>().toStyleValue(propertyValue);
}
#pragma mark - Accessing the Paint Attributes
-- (void)setIconOpacity:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)iconOpacity {
- self.layer->setIconOpacity(iconOpacity.mbgl_floatPropertyValue);
+- (void)setIconOpacity:(MGLStyleValue<NSNumber *> *)iconOpacity {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(iconOpacity);
+ self.layer->setIconOpacity(mbglValue);
}
-- (id <MGLStyleAttributeValue>)iconOpacity {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getIconOpacity() ?: self.layer->getDefaultIconOpacity()];
+- (MGLStyleValue<NSNumber *> *)iconOpacity {
+ auto propertyValue = self.layer->getIconOpacity() ?: self.layer->getDefaultIconOpacity();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setIconColor:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)iconColor {
- self.layer->setIconColor(iconColor.mbgl_colorPropertyValue);
+- (void)setIconColor:(MGLStyleValue<MGLColor *> *)iconColor {
+ auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue(iconColor);
+ self.layer->setIconColor(mbglValue);
}
-- (id <MGLStyleAttributeValue>)iconColor {
- return [MGLStyleAttribute mbgl_colorWithPropertyValueColor:self.layer->getIconColor() ?: self.layer->getDefaultIconColor()];
+- (MGLStyleValue<MGLColor *> *)iconColor {
+ auto propertyValue = self.layer->getIconColor() ?: self.layer->getDefaultIconColor();
+ return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(propertyValue);
}
-- (void)setIconHaloColor:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)iconHaloColor {
- self.layer->setIconHaloColor(iconHaloColor.mbgl_colorPropertyValue);
+- (void)setIconHaloColor:(MGLStyleValue<MGLColor *> *)iconHaloColor {
+ auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue(iconHaloColor);
+ self.layer->setIconHaloColor(mbglValue);
}
-- (id <MGLStyleAttributeValue>)iconHaloColor {
- return [MGLStyleAttribute mbgl_colorWithPropertyValueColor:self.layer->getIconHaloColor() ?: self.layer->getDefaultIconHaloColor()];
+- (MGLStyleValue<MGLColor *> *)iconHaloColor {
+ auto propertyValue = self.layer->getIconHaloColor() ?: self.layer->getDefaultIconHaloColor();
+ return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(propertyValue);
}
-- (void)setIconHaloWidth:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)iconHaloWidth {
- self.layer->setIconHaloWidth(iconHaloWidth.mbgl_floatPropertyValue);
+- (void)setIconHaloWidth:(MGLStyleValue<NSNumber *> *)iconHaloWidth {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(iconHaloWidth);
+ self.layer->setIconHaloWidth(mbglValue);
}
-- (id <MGLStyleAttributeValue>)iconHaloWidth {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getIconHaloWidth() ?: self.layer->getDefaultIconHaloWidth()];
+- (MGLStyleValue<NSNumber *> *)iconHaloWidth {
+ auto propertyValue = self.layer->getIconHaloWidth() ?: self.layer->getDefaultIconHaloWidth();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setIconHaloBlur:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)iconHaloBlur {
- self.layer->setIconHaloBlur(iconHaloBlur.mbgl_floatPropertyValue);
+- (void)setIconHaloBlur:(MGLStyleValue<NSNumber *> *)iconHaloBlur {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(iconHaloBlur);
+ self.layer->setIconHaloBlur(mbglValue);
}
-- (id <MGLStyleAttributeValue>)iconHaloBlur {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getIconHaloBlur() ?: self.layer->getDefaultIconHaloBlur()];
+- (MGLStyleValue<NSNumber *> *)iconHaloBlur {
+ auto propertyValue = self.layer->getIconHaloBlur() ?: self.layer->getDefaultIconHaloBlur();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setIconTranslate:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)iconTranslate {
- self.layer->setIconTranslate(iconTranslate.mbgl_offsetPropertyValue);
+- (void)setIconTranslate:(MGLStyleValue<NSValue *> *)iconTranslate {
+ auto mbglValue = MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toPropertyValue(iconTranslate);
+ self.layer->setIconTranslate(mbglValue);
}
-- (id <MGLStyleAttributeValue>)iconTranslate {
- return [MGLStyleAttribute mbgl_offsetWithPropertyValueOffset:self.layer->getIconTranslate() ?: self.layer->getDefaultIconTranslate()];
+- (MGLStyleValue<NSValue *> *)iconTranslate {
+ auto propertyValue = self.layer->getIconTranslate() ?: self.layer->getDefaultIconTranslate();
+ return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toStyleValue(propertyValue);
}
-- (void)setIconTranslateAnchor:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)iconTranslateAnchor {
- MGLSetEnumProperty(iconTranslateAnchor, IconTranslateAnchor, TranslateAnchorType, MGLSymbolStyleLayerIconTranslateAnchor);
+- (void)setIconTranslateAnchor:(MGLStyleValue<NSValue *> *)iconTranslateAnchor {
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *>().toPropertyValue(iconTranslateAnchor);
+ self.layer->setIconTranslateAnchor(mbglValue);
}
-- (id <MGLStyleAttributeValue>)iconTranslateAnchor {
- MGLGetEnumProperty(IconTranslateAnchor, TranslateAnchorType, MGLSymbolStyleLayerIconTranslateAnchor);
+- (MGLStyleValue<NSValue *> *)iconTranslateAnchor {
+ auto propertyValue = self.layer->getIconTranslateAnchor() ?: self.layer->getDefaultIconTranslateAnchor();
+ return MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *>().toStyleValue(propertyValue);
}
-- (void)setTextOpacity:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)textOpacity {
- self.layer->setTextOpacity(textOpacity.mbgl_floatPropertyValue);
+- (void)setTextOpacity:(MGLStyleValue<NSNumber *> *)textOpacity {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(textOpacity);
+ self.layer->setTextOpacity(mbglValue);
}
-- (id <MGLStyleAttributeValue>)textOpacity {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getTextOpacity() ?: self.layer->getDefaultTextOpacity()];
+- (MGLStyleValue<NSNumber *> *)textOpacity {
+ auto propertyValue = self.layer->getTextOpacity() ?: self.layer->getDefaultTextOpacity();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setTextColor:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)textColor {
- self.layer->setTextColor(textColor.mbgl_colorPropertyValue);
+- (void)setTextColor:(MGLStyleValue<MGLColor *> *)textColor {
+ auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue(textColor);
+ self.layer->setTextColor(mbglValue);
}
-- (id <MGLStyleAttributeValue>)textColor {
- return [MGLStyleAttribute mbgl_colorWithPropertyValueColor:self.layer->getTextColor() ?: self.layer->getDefaultTextColor()];
+- (MGLStyleValue<MGLColor *> *)textColor {
+ auto propertyValue = self.layer->getTextColor() ?: self.layer->getDefaultTextColor();
+ return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(propertyValue);
}
-- (void)setTextHaloColor:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)textHaloColor {
- self.layer->setTextHaloColor(textHaloColor.mbgl_colorPropertyValue);
+- (void)setTextHaloColor:(MGLStyleValue<MGLColor *> *)textHaloColor {
+ auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue(textHaloColor);
+ self.layer->setTextHaloColor(mbglValue);
}
-- (id <MGLStyleAttributeValue>)textHaloColor {
- return [MGLStyleAttribute mbgl_colorWithPropertyValueColor:self.layer->getTextHaloColor() ?: self.layer->getDefaultTextHaloColor()];
+- (MGLStyleValue<MGLColor *> *)textHaloColor {
+ auto propertyValue = self.layer->getTextHaloColor() ?: self.layer->getDefaultTextHaloColor();
+ return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(propertyValue);
}
-- (void)setTextHaloWidth:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)textHaloWidth {
- self.layer->setTextHaloWidth(textHaloWidth.mbgl_floatPropertyValue);
+- (void)setTextHaloWidth:(MGLStyleValue<NSNumber *> *)textHaloWidth {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(textHaloWidth);
+ self.layer->setTextHaloWidth(mbglValue);
}
-- (id <MGLStyleAttributeValue>)textHaloWidth {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getTextHaloWidth() ?: self.layer->getDefaultTextHaloWidth()];
+- (MGLStyleValue<NSNumber *> *)textHaloWidth {
+ auto propertyValue = self.layer->getTextHaloWidth() ?: self.layer->getDefaultTextHaloWidth();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setTextHaloBlur:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)textHaloBlur {
- self.layer->setTextHaloBlur(textHaloBlur.mbgl_floatPropertyValue);
+- (void)setTextHaloBlur:(MGLStyleValue<NSNumber *> *)textHaloBlur {
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(textHaloBlur);
+ self.layer->setTextHaloBlur(mbglValue);
}
-- (id <MGLStyleAttributeValue>)textHaloBlur {
- return [MGLStyleAttribute mbgl_numberWithPropertyValueNumber:self.layer->getTextHaloBlur() ?: self.layer->getDefaultTextHaloBlur()];
+- (MGLStyleValue<NSNumber *> *)textHaloBlur {
+ auto propertyValue = self.layer->getTextHaloBlur() ?: self.layer->getDefaultTextHaloBlur();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
-- (void)setTextTranslate:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)textTranslate {
- self.layer->setTextTranslate(textTranslate.mbgl_offsetPropertyValue);
+- (void)setTextTranslate:(MGLStyleValue<NSValue *> *)textTranslate {
+ auto mbglValue = MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toPropertyValue(textTranslate);
+ self.layer->setTextTranslate(mbglValue);
}
-- (id <MGLStyleAttributeValue>)textTranslate {
- return [MGLStyleAttribute mbgl_offsetWithPropertyValueOffset:self.layer->getTextTranslate() ?: self.layer->getDefaultTextTranslate()];
+- (MGLStyleValue<NSValue *> *)textTranslate {
+ auto propertyValue = self.layer->getTextTranslate() ?: self.layer->getDefaultTextTranslate();
+ return MGLStyleValueTransformer<std::array<float, 2>, NSValue *>().toStyleValue(propertyValue);
}
-- (void)setTextTranslateAnchor:(id <MGLStyleAttributeValue, MGLStyleAttributeValue_Private>)textTranslateAnchor {
- MGLSetEnumProperty(textTranslateAnchor, TextTranslateAnchor, TranslateAnchorType, MGLSymbolStyleLayerTextTranslateAnchor);
+- (void)setTextTranslateAnchor:(MGLStyleValue<NSValue *> *)textTranslateAnchor {
+ auto mbglValue = MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *>().toPropertyValue(textTranslateAnchor);
+ self.layer->setTextTranslateAnchor(mbglValue);
}
-- (id <MGLStyleAttributeValue>)textTranslateAnchor {
- MGLGetEnumProperty(TextTranslateAnchor, TranslateAnchorType, MGLSymbolStyleLayerTextTranslateAnchor);
+- (MGLStyleValue<NSValue *> *)textTranslateAnchor {
+ auto propertyValue = self.layer->getTextTranslateAnchor() ?: self.layer->getDefaultTextTranslateAnchor();
+ return MGLStyleValueTransformer<mbgl::style::TranslateAnchorType, NSValue *>().toStyleValue(propertyValue);
}
@end
diff --git a/platform/darwin/src/MGLTileSet.h b/platform/darwin/src/MGLTileSet.h
index 5ae899d833..08a34338b1 100644
--- a/platform/darwin/src/MGLTileSet.h
+++ b/platform/darwin/src/MGLTileSet.h
@@ -39,8 +39,8 @@ typedef NS_ENUM(NSUInteger, MGLTileSetScheme) {
@property (nonatomic, nullable) NSNumber *maximumZoomLevel;
/**
- An `NSString` object that contains an attribution to be displayed when the map is
- shown to a user. The default value is nil.
+ An `NSString` object that contains an attribution to be displayed when the map
+ is shown to a user. The default value is `nil`.
*/
@property (nonatomic, copy, nullable) NSString *attribution;
@@ -55,7 +55,7 @@ typedef NS_ENUM(NSUInteger, MGLTileSetScheme) {
Initializes and returns a new tile set object.
@param tileURLTemplates An `NSArray` of `NSString` objects that represent the
- tile templates.
+ tile templates.
@return The initialized tile set object.
*/
- (instancetype)initWithTileURLTemplates:(NS_ARRAY_OF(NSString *) *)tileURLTemplates;
@@ -64,11 +64,11 @@ typedef NS_ENUM(NSUInteger, MGLTileSetScheme) {
Initializes and returns a new tile set object.
@param tileURLTemplates An `NSArray` of `NSString` objects that represent the
- tile templates.
+ tile templates.
@param minimumZoomLevel An `NSUInteger`; specifies the minimum zoom level at
- which to display tiles.
+ which to display tiles.
@param maximumZoomLevel An `NSUInteger`; specifies the maximum zoom level at
- which to display tiles.
+ which to display tiles.
@return The initialized tile set object.
*/
- (instancetype)initWithTileURLTemplates:(NS_ARRAY_OF(NSString *) *)tileURLTemplates minimumZoomLevel:(NSUInteger)minimumZoomLevel maximumZoomLevel:(NSUInteger)maximumZoomLevel;
diff --git a/platform/darwin/src/MGLTypes.h b/platform/darwin/src/MGLTypes.h
index 6a323153fb..a3ea587add 100644
--- a/platform/darwin/src/MGLTypes.h
+++ b/platform/darwin/src/MGLTypes.h
@@ -3,6 +3,14 @@
#pragma once
#if TARGET_OS_IPHONE
+@class UIImage;
+#define MGLImage UIImage
+#else
+@class NSImage;
+#define MGLImage NSImage
+#endif
+
+#if TARGET_OS_IPHONE
@class UIColor;
#define MGLColor UIColor
#else
diff --git a/platform/darwin/src/MGLVectorSource.h b/platform/darwin/src/MGLVectorSource.h
index 2106a5cf42..6cfab09489 100644
--- a/platform/darwin/src/MGLVectorSource.h
+++ b/platform/darwin/src/MGLVectorSource.h
@@ -13,27 +13,56 @@ NS_ASSUME_NONNULL_BEGIN
*/
@interface MGLVectorSource : MGLSource
-@property (nonatomic, readonly, copy) NSURL *URL;
-@property (nonatomic, readonly, nullable) MGLTileSet *tileSet;
+#pragma mark Initializing a Source
/**
- Initializes and returns a vector source from a remote URL.
+ Returns a vector source initialized with an identifier and TileJSON URL.
- @param sourceIdentifier The source identifier.
- @param URL A remote URL holding the vector source data.
+ After initializing and configuring the source, add it to a map view’s style
+ using the `-[MGLStyle addSource:]` method.
- @return An `MGLVectorSource`.
+ @param identifier A string that uniquely identifies the source in the style to
+ which it is added.
+ @param url A URL to a TileJSON configuration file describing the source’s
+ contents and other metadata.
+ @return An initialized vector source.
*/
-- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier URL:(NSURL *)url;
+- (instancetype)initWithIdentifier:(NSString *)identifier URL:(NSURL *)url NS_DESIGNATED_INITIALIZER;
/**
- Initializes a source with the given identifier, tile size, and tile
- URL template set.
+ Returns a vector source initialized an identifier and tile set.
- @param sourceIdentifier A string that uniquely identifies the source.
- @param tileSet A tile set describing where to download tiles.
+ After initializing and configuring the source, add it to a map view’s style
+ using the `-[MGLStyle addSource:]` method.
+
+ @param identifier A string that uniquely identifies the source in the style to
+ which it is added.
+ @param tileSet A tile set describing the source’s contents and other metadata.
+ @return An initialized vector source.
*/
-- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier tileSet:(MGLTileSet *)tileSet;
+- (instancetype)initWithIdentifier:(NSString *)identifier tileSet:(MGLTileSet *)tileSet NS_DESIGNATED_INITIALIZER;
+
+#pragma mark Accessing a Source’s Content
+
+/**
+ A URL to a TileJSON configuration file describing the source’s contents and
+ other metadata.
+
+ The URL may be a full HTTP or HTTPS URL or a Mapbox URL indicating the tile
+ set’s map ID (`mapbox://<mapid>`).
+
+ If the receiver was initialized using `-initWithIdentifier:tileSet:`, this
+ property is set to `nil`.
+ */
+@property (nonatomic, readonly, copy) NSURL *URL;
+
+/**
+ A tile set describing the source’s contents and other metadata.
+
+ If the receiver was initialized using `-initWithIdentifier:URL:`, this property
+ is set to `nil`.
+ */
+@property (nonatomic, readonly, nullable) MGLTileSet *tileSet;
@end
diff --git a/platform/darwin/src/MGLVectorSource.mm b/platform/darwin/src/MGLVectorSource.mm
index 2ab9627ef5..3597812359 100644
--- a/platform/darwin/src/MGLVectorSource.mm
+++ b/platform/darwin/src/MGLVectorSource.mm
@@ -10,18 +10,18 @@
static NSString *MGLVectorSourceType = @"vector";
-- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier URL:(NSURL *)url
+- (instancetype)initWithIdentifier:(NSString *)identifier URL:(NSURL *)url
{
- if (self = [super initWithSourceIdentifier:sourceIdentifier])
+ if (self = [super initWithIdentifier:identifier])
{
_URL = url;
}
return self;
}
-- (instancetype)initWithSourceIdentifier:(NSString *)sourceIdentifier tileSet:(MGLTileSet *)tileSet
+- (instancetype)initWithIdentifier:(NSString *)identifier tileSet:(MGLTileSet *)tileSet
{
- if (self = [super initWithSourceIdentifier:sourceIdentifier])
+ if (self = [super initWithIdentifier:identifier])
{
_tileSet = tileSet;
}
@@ -34,12 +34,12 @@ static NSString *MGLVectorSourceType = @"vector";
if (self.URL)
{
- source = std::make_unique<mbgl::style::VectorSource>(self.sourceIdentifier.UTF8String,
+ source = std::make_unique<mbgl::style::VectorSource>(self.identifier.UTF8String,
self.URL.mgl_URLByStandardizingScheme.absoluteString.UTF8String);
}
else
{
- source = std::make_unique<mbgl::style::VectorSource>(self.sourceIdentifier.UTF8String,
+ source = std::make_unique<mbgl::style::VectorSource>(self.identifier.UTF8String,
self.tileSet.mbglTileset);
}
diff --git a/platform/darwin/src/MGLVectorStyleLayer.h b/platform/darwin/src/MGLVectorStyleLayer.h
new file mode 100644
index 0000000000..13bb9e79a9
--- /dev/null
+++ b/platform/darwin/src/MGLVectorStyleLayer.h
@@ -0,0 +1,127 @@
+#import <Foundation/Foundation.h>
+
+#import "MGLForegroundStyleLayer.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ `MGLVectorStyleLayer` is an abstract superclass for style layers whose content
+ is defined by an `MGLGeoJSONSource` or `MGLVectorSource` object.
+
+ Do not create instances of this class directly, and do not create your own
+ subclasses of this class. Instead, create instances of the following concrete
+ subclasses: `MGLCircleStyleLayer`, `MGLFillStyleLayer`, `MGLLineStyleLayer`,
+ and `MGLSymbolStyleLayer`.
+ */
+@interface MGLVectorStyleLayer : MGLForegroundStyleLayer
+
+#pragma mark Refining a Style Layer’s Content
+
+/**
+ Identifier of the layer within the source identified by the `sourceIdentifier`
+ property from which the receiver obtains the data to style.
+ */
+@property (nonatomic, nullable) NSString *sourceLayerIdentifier;
+
+/**
+ The style layer’s predicate.
+
+ Use the style layer’s predicate to include only the features in the source
+ layer that satisfy a condition that you define. If the style layer initially
+ comes from the style, its predicate corresponds to the
+ <a href="https://www.mapbox.com/mapbox-gl-style-spec/#layer-filter">`filter`</a>
+ property in the style JSON.
+
+ The following comparison operators are supported.
+
+ <ul>
+ <li><code>NSEqualToPredicateOperatorType</code> (<code>=</code>, <code>==</code>)</li>
+ <li><code>NSGreaterThanOrEqualToPredicateOperatorType</code> (<code>>=</code>, <code>=></code>)</li>
+ <li><code>NSLessThanOrEqualToPredicateOperatorType</code> (<code><=</code>, <code>=<</code>)</li>
+ <li><code>NSGreaterThanPredicateOperatorType</code> (<code>></code>)</li>
+ <li><code>NSLessThanPredicateOperatorType</code> (<code><</code>)</li>
+ <li><code>NSNotEqualToPredicateOperatorType</code> (<code>!=</code>, <code><></code>)</li>
+ <li><code>NSBetweenPredicateOperatorType</code> (<code>BETWEEN</code>)</li>
+ </ul>
+
+ The following compound operators are supported:
+
+ <ul>
+ <li><code>NSAndPredicateType</code> (<code>AND</code>, <code>&&</code>)</li>
+ <li><code>NSOrPredicateType</code> (<code>OR</code>, <code>||</code>)</li>
+ <li><code>NSNotPredicateType</code> (<code>NOT</code>, <code>!</code>)</li>
+ </ul>
+
+ The following aggregate operator is supported:
+
+ <ul>
+ <li><code>NSInPredicateOperatorType</code> (<code>IN</code>)</li>
+ </ul>
+
+ To test whether a feature has or lacks a specific attribute, compare the attribute to `NULL` or `NIL`. Predicates created using the `+[NSPredicate predicateWithValue:]` method are also supported. String operators and custom operators are not supported.
+
+ For details about the predicate format string syntax, consult the “Predicate
+ Format String Syntax” chapter of the “Predicate Programming Guide” in Apple
+ developer documentation.
+
+ The predicate's left-hand expression must be a string that identifies a feature
+ attribute or, alternatively, one of the following special attributes:
+
+ <table>
+ <thead>
+ <tr><th>Attribute</th><th>Meaning</th></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><code>$id</code></td>
+ <td>
+ A value that uniquely identifies the feature in the containing source.
+ For details on the types of values that may be associated with this key,
+ consult the documentation for the <code>MGLFeature</code> protocol’s
+ <code>identifier</code> property.
+ </td>
+ </tr>
+ <tr>
+ <td><code>$type</code></td>
+ <td>
+ The type of geometry represented by the feature. A feature’s type is
+ guaranteed to be one of the following strings:
+ <ul>
+ <li>
+ <code>Point</code> for point features, corresponding to the
+ <code>MGLPointAnnotation</code> class
+ </li>
+ <li>
+ <code>LineString</code> for polyline features, corresponding to
+ the <code>MGLPolyline</code> class
+ </li>
+ <li>
+ <code>Polygon</code> for polygon features, corresponding to the
+ <code>MGLPolygon</code> class
+ </li>
+ </ul>
+ </td>
+ </tr>
+ <tr>
+ <td><code>point_count</code></td>
+ <td>The number of point features in a given cluster.</td>
+ </tr>
+ </tbody>
+ </table>
+
+ The predicate’s right-hand expression must be an `NSString` (to match strings)
+ or `NSNumber` (to match numbers, including Boolean values) or an array of
+ `NSString`s or `NSNumber`s, depending on the operator and the type of values
+ expected for the attribute being tested. For floating-point values, use
+ `-[NSNumber numberWithDouble:]` instead of `-[NSNumber numberWithFloat:]`
+ to avoid precision issues.
+
+ Automatic type casting is not performed. Therefore, a feature only matches this
+ predicate if its value for the attribute in question is of the same type as the
+ value specified in the predicate.
+ */
+@property (nonatomic, nullable) NSPredicate *predicate;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLVectorStyleLayer.m b/platform/darwin/src/MGLVectorStyleLayer.m
new file mode 100644
index 0000000000..174256cbdd
--- /dev/null
+++ b/platform/darwin/src/MGLVectorStyleLayer.m
@@ -0,0 +1,16 @@
+#import "MGLVectorStyleLayer.h"
+
+@implementation MGLVectorStyleLayer
+
+- (void)setPredicate:(NSPredicate *)predicate {
+ [NSException raise:@"MGLAbstractClassException"
+ format:@"MGLVectorLayer is an abstract class"];
+}
+
+- (NSPredicate *)predicate {
+ [NSException raise:@"MGLAbstractClassException"
+ format:@"MGLVectorLayer is an abstract class"];
+ return nil;
+}
+
+@end
diff --git a/platform/darwin/src/NSArray+MGLAdditions.h b/platform/darwin/src/NSArray+MGLAdditions.h
new file mode 100644
index 0000000000..6871f15486
--- /dev/null
+++ b/platform/darwin/src/NSArray+MGLAdditions.h
@@ -0,0 +1,9 @@
+#import <Foundation/Foundation.h>
+
+#import <mbgl/util/feature.hpp>
+
+@interface NSArray (MGLAdditions)
+
+- (std::vector<mbgl::Value>)mgl_vector;
+
+@end
diff --git a/platform/darwin/src/NSArray+MGLAdditions.mm b/platform/darwin/src/NSArray+MGLAdditions.mm
new file mode 100644
index 0000000000..976eda704f
--- /dev/null
+++ b/platform/darwin/src/NSArray+MGLAdditions.mm
@@ -0,0 +1,26 @@
+#import "NSArray+MGLAdditions.h"
+
+#import "NSDictionary+MGLAdditions.h"
+#import "NSExpression+MGLAdditions.mm"
+
+@implementation NSArray (MGLAdditions)
+
+- (std::vector<mbgl::Value>)mgl_vector {
+ std::vector<mbgl::Value> vector;
+ vector.reserve(self.count);
+ for (id value in self) {
+ if ([value isKindOfClass:[NSArray class]]) {
+ std::vector<mbgl::Value> innerVector = [value mgl_vector];
+ vector.push_back(innerVector);
+ } else if ([value isKindOfClass:[NSDictionary class]]) {
+ mbgl::PropertyMap propertyMap = [value mgl_propertyMap];
+ vector.push_back(propertyMap);
+ } else {
+ NSExpression *expression = [NSExpression expressionForConstantValue:value];
+ vector.push_back([expression mgl_filterValue]);
+ }
+ }
+ return vector;
+}
+
+@end
diff --git a/platform/darwin/src/NSArray+MGLStyleAttributeAdditions.h b/platform/darwin/src/NSArray+MGLStyleAttributeAdditions.h
deleted file mode 100644
index fa5193acf0..0000000000
--- a/platform/darwin/src/NSArray+MGLStyleAttributeAdditions.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#import <Foundation/Foundation.h>
-
-#import "MGLStyleAttributeValue.h"
-
-@interface NSArray (MGLStyleAttributeAdditions) <MGLStyleAttributeValue>
-
-@end
diff --git a/platform/darwin/src/NSArray+MGLStyleAttributeAdditions.mm b/platform/darwin/src/NSArray+MGLStyleAttributeAdditions.mm
deleted file mode 100644
index fb60cf0f72..0000000000
--- a/platform/darwin/src/NSArray+MGLStyleAttributeAdditions.mm
+++ /dev/null
@@ -1,36 +0,0 @@
-#import "NSArray+MGLStyleAttributeAdditions.h"
-
-#import "NSArray+MGLStyleAttributeAdditions_Private.h"
-#import "MGLStyleAttributeValue_Private.h"
-
-#include <array>
-
-@interface NSArray(Private) <MGLStyleAttributeValue_Private>
-@end
-
-@implementation NSArray (MGLStyleAttributeAdditions)
-
-- (mbgl::style::PropertyValue<std::vector<std::string> >)mbgl_stringArrayPropertyValue
-{
- std::vector<std::string>fonts;
-
- for (NSString *font in self) {
- fonts.emplace_back(font.UTF8String);
- }
-
- return {{fonts}};
-}
-
-- (mbgl::style::PropertyValue<std::vector<float> >)mbgl_numberArrayPropertyValue
-{
- std::vector<float>values;
-
- for (NSNumber *n in self) {
- values.emplace_back(n.floatValue);
- }
-
- return {{values}};
-}
-
-
-@end
diff --git a/platform/darwin/src/NSArray+MGLStyleAttributeAdditions_Private.h b/platform/darwin/src/NSArray+MGLStyleAttributeAdditions_Private.h
deleted file mode 100644
index 1be02c01d2..0000000000
--- a/platform/darwin/src/NSArray+MGLStyleAttributeAdditions_Private.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#import <Foundation/Foundation.h>
-
-#import "MGLStyleAttributeValue.h"
-
-#include <mbgl/style/property_value.hpp>
-
-@interface NSArray (MGLStyleAttributeAdditions_Private) <MGLStyleAttributeValue>
-
-@end
diff --git a/platform/darwin/src/NSColor+MGLStyleAttributeAdditions.h b/platform/darwin/src/NSColor+MGLStyleAttributeAdditions.h
deleted file mode 100644
index 5a4f7af006..0000000000
--- a/platform/darwin/src/NSColor+MGLStyleAttributeAdditions.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#import <Cocoa/Cocoa.h>
-
-#import "MGLStyleAttributeValue.h"
-
-@interface NSColor (MGLStyleAttributeAdditions) <MGLStyleAttributeValue>
-
-@end
diff --git a/platform/darwin/src/NSColor+MGLStyleAttributeAdditions.m b/platform/darwin/src/NSColor+MGLStyleAttributeAdditions.m
deleted file mode 100644
index ac330343c8..0000000000
--- a/platform/darwin/src/NSColor+MGLStyleAttributeAdditions.m
+++ /dev/null
@@ -1,5 +0,0 @@
-#import "NSColor+MGLStyleAttributeAdditions.h"
-
-@implementation NSColor (MGLStyleAttributeAdditions)
-
-@end
diff --git a/platform/darwin/src/NSColor+MGLStyleAttributeAdditions_Private.h b/platform/darwin/src/NSColor+MGLStyleAttributeAdditions_Private.h
deleted file mode 100644
index 9a714cbd83..0000000000
--- a/platform/darwin/src/NSColor+MGLStyleAttributeAdditions_Private.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#import <Foundation/Foundation.h>
-
-#import "MGLStyleAttributeValue.h"
-
-#include <mbgl/style/property_value.hpp>
-
-@interface NSColor (MGLStyleAttributeAdditions_Private) <MGLStyleAttributeValue>
-
-@end
diff --git a/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm b/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm
index 19c264aa40..aa0e456bb1 100644
--- a/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm
+++ b/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm
@@ -68,12 +68,6 @@
filter.values = self.rightExpression.mgl_filterValues;
return filter;
}
- case NSContainsPredicateOperatorType: {
- auto filter = mbgl::style::InFilter();
- filter.key = [self.rightExpression.constantValue UTF8String];
- filter.values = self.leftExpression.mgl_filterValues;
- return filter;
- }
case NSBetweenPredicateOperatorType: {
auto filter = mbgl::style::AllFilter();
auto gteFilter = mbgl::style::GreaterThanEqualsFilter();
@@ -91,6 +85,7 @@
case NSBeginsWithPredicateOperatorType:
case NSEndsWithPredicateOperatorType:
case NSCustomSelectorPredicateOperatorType:
+ case NSContainsPredicateOperatorType:
[NSException raise:@"Unsupported operator type"
format:@"NSPredicateOperatorType:%lu is not supported.", (unsigned long)self.predicateOperatorType];
}
diff --git a/platform/darwin/src/NSDictionary+MGLAdditions.h b/platform/darwin/src/NSDictionary+MGLAdditions.h
new file mode 100644
index 0000000000..556f21992b
--- /dev/null
+++ b/platform/darwin/src/NSDictionary+MGLAdditions.h
@@ -0,0 +1,13 @@
+#import <Foundation/Foundation.h>
+
+#import <mbgl/util/feature.hpp>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface NSDictionary (MGLAdditions)
+
+- (mbgl::PropertyMap)mgl_propertyMap;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/NSDictionary+MGLAdditions.mm b/platform/darwin/src/NSDictionary+MGLAdditions.mm
new file mode 100644
index 0000000000..1023e91a48
--- /dev/null
+++ b/platform/darwin/src/NSDictionary+MGLAdditions.mm
@@ -0,0 +1,24 @@
+#import "NSDictionary+MGLAdditions.h"
+
+#import "NSExpression+MGLAdditions.mm"
+#import "NSArray+MGLAdditions.h"
+
+@implementation NSDictionary (MGLAdditions)
+
+- (mbgl::PropertyMap)mgl_propertyMap {
+ mbgl::PropertyMap propertyMap;
+ for (NSString *key in self.allKeys) {
+ if ([self[key] isKindOfClass:[NSDictionary class]]) {
+ propertyMap[[key UTF8String]] = [self[key] mgl_propertyMap];
+ } else if ([self[key] isKindOfClass:[NSArray class]]) {
+ NSArray *array = self[key];
+ propertyMap[[key UTF8String]] = [array mgl_vector];
+ } else {
+ NSExpression *expression = [NSExpression expressionForConstantValue:self[key]];
+ propertyMap[[key UTF8String]] = [expression mgl_filterValue];
+ }
+ }
+ return propertyMap;
+}
+
+@end
diff --git a/platform/darwin/src/NSExpression+MGLAdditions.h b/platform/darwin/src/NSExpression+MGLAdditions.h
index 4e8c5ee071..6d0fff5760 100644
--- a/platform/darwin/src/NSExpression+MGLAdditions.h
+++ b/platform/darwin/src/NSExpression+MGLAdditions.h
@@ -5,7 +5,7 @@
@interface NSExpression (MGLAdditions)
- (mbgl::Value)mgl_filterValue;
-
- (std::vector<mbgl::Value>)mgl_filterValues;
+- (mbgl::FeatureIdentifier)mgl_featureIdentifier;
@end
diff --git a/platform/darwin/src/NSExpression+MGLAdditions.mm b/platform/darwin/src/NSExpression+MGLAdditions.mm
index 52a0b9bd88..392a6d7f5b 100644
--- a/platform/darwin/src/NSExpression+MGLAdditions.mm
+++ b/platform/darwin/src/NSExpression+MGLAdditions.mm
@@ -61,4 +61,30 @@
return { };
}
+- (mbgl::FeatureIdentifier)mgl_featureIdentifier
+{
+ id value = self.constantValue;
+ mbgl::Value mbglValue = [self mgl_filterValue];
+
+ if ([value isKindOfClass:NSString.class]) {
+ return mbglValue.get<std::string>();
+ } else if ([value isKindOfClass:NSNumber.class]) {
+ NSNumber *number = (NSNumber *)value;
+ if ((strcmp([number objCType], @encode(char)) == 0) ||
+ (strcmp([number objCType], @encode(BOOL)) == 0)) {
+ return mbglValue.get<bool>();
+ } else if ( strcmp([number objCType], @encode(double)) == 0 ||
+ strcmp([number objCType], @encode(float)) == 0) {
+ return mbglValue.get<double>();
+ } else if ([number compare:@(0)] == NSOrderedDescending ||
+ [number compare:@(0)] == NSOrderedSame) {
+ return mbglValue.get<uint64_t>();
+ } else if ([number compare:@(0)] == NSOrderedAscending) {
+ return mbglValue.get<int64_t>();
+ }
+ }
+
+ return {};
+}
+
@end
diff --git a/platform/darwin/src/NSNumber+MGLStyleAttributeAdditions.h b/platform/darwin/src/NSNumber+MGLStyleAttributeAdditions.h
deleted file mode 100644
index 162b5e94f5..0000000000
--- a/platform/darwin/src/NSNumber+MGLStyleAttributeAdditions.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#import <Foundation/Foundation.h>
-
-#import "MGLStyleAttributeValue.h"
-
-@interface NSNumber (MGLStyleAttributeAdditions) <MGLStyleAttributeValue>
-
-@end
diff --git a/platform/darwin/src/NSNumber+MGLStyleAttributeAdditions.mm b/platform/darwin/src/NSNumber+MGLStyleAttributeAdditions.mm
deleted file mode 100644
index 163105d2fa..0000000000
--- a/platform/darwin/src/NSNumber+MGLStyleAttributeAdditions.mm
+++ /dev/null
@@ -1,22 +0,0 @@
-#import "NSNumber+MGLStyleAttributeAdditions.h"
-
-#include <mbgl/style/property_value.hpp>
-
-@implementation NSNumber (MGLStyleAttributeAdditions)
-
-- (NSNumber *)numberValue
-{
- return self;
-}
-
-- (mbgl::style::PropertyValue<bool>)mbgl_boolPropertyValue
-{
- return mbgl::style::PropertyValue<bool> { !!self.boolValue };
-}
-
-- (mbgl::style::PropertyValue<float>)mbgl_floatPropertyValue
-{
- return mbgl::style::PropertyValue<float> { self.floatValue };
-}
-
-@end
diff --git a/platform/darwin/src/NSNumber+MGLStyleAttributeAdditions_Private.h b/platform/darwin/src/NSNumber+MGLStyleAttributeAdditions_Private.h
deleted file mode 100644
index 73e40bb3ad..0000000000
--- a/platform/darwin/src/NSNumber+MGLStyleAttributeAdditions_Private.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#import <Foundation/Foundation.h>
-
-#import "MGLStyleAttributeValue.h"
-
-#include <mbgl/style/property_value.hpp>
-
-@interface NSNumber (MGLStyleAttributeAdditions_Private) <MGLStyleAttributeValue>
-
-- (mbgl::style::PropertyValue<bool>)mbgl_booleanPropertyValue;
-
-- (mbgl::style::PropertyValue<float>)mbgl_numberPropertyValue;
-
-@end
diff --git a/platform/darwin/src/NSString+MGLStyleAttributeAdditions.h b/platform/darwin/src/NSString+MGLStyleAttributeAdditions.h
deleted file mode 100644
index 2126335922..0000000000
--- a/platform/darwin/src/NSString+MGLStyleAttributeAdditions.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#import <Foundation/Foundation.h>
-
-#import "MGLStyleAttributeValue.h"
-
-@interface NSString (MGLStyleAttributeAdditions) <MGLStyleAttributeValue>
-
-@end
diff --git a/platform/darwin/src/NSString+MGLStyleAttributeAdditions.mm b/platform/darwin/src/NSString+MGLStyleAttributeAdditions.mm
deleted file mode 100644
index ff88f5501a..0000000000
--- a/platform/darwin/src/NSString+MGLStyleAttributeAdditions.mm
+++ /dev/null
@@ -1,17 +0,0 @@
-#import "NSString+MGLStyleAttributeAdditions.h"
-
-#import "NSString+MGLStyleAttributeAdditions_Private.h"
-
-@implementation NSString (MGLStyleAttributeAdditions)
-
-- (BOOL)isFunction
-{
- return NO;
-}
-
-- (mbgl::style::PropertyValue<std::string>)mbgl_stringPropertyValue
-{
- return mbgl::style::PropertyValue<std::string> {{ self.UTF8String }};
-}
-
-@end
diff --git a/platform/darwin/src/NSString+MGLStyleAttributeAdditions_Private.h b/platform/darwin/src/NSString+MGLStyleAttributeAdditions_Private.h
deleted file mode 100644
index 8e401e2996..0000000000
--- a/platform/darwin/src/NSString+MGLStyleAttributeAdditions_Private.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#import <Foundation/Foundation.h>
-
-#import "MGLStyleAttributeValue.h"
-
-#include <mbgl/style/property_value.hpp>
-
-@interface NSString (MGLStyleAttributeAdditions_Private) <MGLStyleAttributeValue>
-
-- (mbgl::style::PropertyValue<std::string>)mbgl_stringPropertyValue;
-
-@end
diff --git a/platform/darwin/src/NSValue+MGLStyleAttributeAdditions.h b/platform/darwin/src/NSValue+MGLStyleAttributeAdditions.h
index 0ee0c78f87..60c1ee4075 100644
--- a/platform/darwin/src/NSValue+MGLStyleAttributeAdditions.h
+++ b/platform/darwin/src/NSValue+MGLStyleAttributeAdditions.h
@@ -1,7 +1,13 @@
#import <Foundation/Foundation.h>
-#import "MGLStyleAttributeValue.h"
+#include <array>
-@interface NSValue (MGLStyleAttributeValue) <MGLStyleAttributeValue>
+@interface NSValue (MGLStyleAttributeAdditions)
+
++ (instancetype)mgl_valueWithOffsetArray:(std::array<float, 2>)offsetArray;
++ (instancetype)mgl_valueWithPaddingArray:(std::array<float, 4>)paddingArray;
+
+- (std::array<float, 2>)mgl_offsetArrayValue;
+- (std::array<float, 4>)mgl_paddingArrayValue;
@end
diff --git a/platform/darwin/src/NSValue+MGLStyleAttributeAdditions.mm b/platform/darwin/src/NSValue+MGLStyleAttributeAdditions.mm
index 83266e7db5..59afe559d7 100644
--- a/platform/darwin/src/NSValue+MGLStyleAttributeAdditions.mm
+++ b/platform/darwin/src/NSValue+MGLStyleAttributeAdditions.mm
@@ -1,9 +1,5 @@
#import "NSValue+MGLStyleAttributeAdditions.h"
-#import "NSValue+MGLStyleAttributeAdditions_Private.h"
-
-#include <array>
-
#if TARGET_OS_IPHONE
#import <UIKit/UIKit.h>
#define MGLEdgeInsets UIEdgeInsets
@@ -32,16 +28,6 @@
return [NSValue value:&insets withObjCType:@encode(MGLEdgeInsets)];
}
-- (BOOL)isFunction
-{
- return NO;
-}
-
-- (mbgl::style::PropertyValue<std::array<float, 2>>)mbgl_offsetPropertyValue
-{
- return { self.mgl_offsetArrayValue };
-}
-
- (std::array<float, 2>)mgl_offsetArrayValue
{
NSAssert(strcmp(self.objCType, @encode(CGVector)) == 0, @"Value does not represent a CGVector");
@@ -53,11 +39,6 @@
};
}
-- (mbgl::style::PropertyValue<std::array<float, 4>>)mbgl_paddingPropertyValue
-{
- return { self.mgl_paddingArrayValue };
-}
-
- (std::array<float, 4>)mgl_paddingArrayValue
{
NSAssert(strcmp(self.objCType, @encode(MGLEdgeInsets)) == 0, @"Value does not represent an NSEdgeInsets/UIEdgeInsets");
diff --git a/platform/darwin/src/NSValue+MGLStyleAttributeAdditions_Private.h b/platform/darwin/src/NSValue+MGLStyleAttributeAdditions_Private.h
deleted file mode 100644
index 28a9b10908..0000000000
--- a/platform/darwin/src/NSValue+MGLStyleAttributeAdditions_Private.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#import <Foundation/Foundation.h>
-
-#import "MGLStyleAttributeValue.h"
-
-#include <mbgl/style/property_value.hpp>
-
-@interface NSValue (MGLStyleAttributeAdditions_Private) <MGLStyleAttributeValue>
-
-+ (instancetype)mgl_valueWithOffsetArray:(std::array<float, 2>)offsetArray;
-+ (instancetype)mgl_valueWithPaddingArray:(std::array<float, 4>)paddingArray;
-
-- (std::array<float, 2>)mgl_offsetArrayValue;
-- (std::array<float, 4>)mgl_paddingArrayValue;
-
-@end
diff --git a/platform/darwin/src/UIColor+MGLStyleAttributeAdditions_Private.h b/platform/darwin/src/UIColor+MGLStyleAttributeAdditions_Private.h
deleted file mode 100644
index ef886dca5d..0000000000
--- a/platform/darwin/src/UIColor+MGLStyleAttributeAdditions_Private.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#import <UIKit/UIKit.h>
-
-#import "MGLStyleAttributeValue.h"
-
-#include <mbgl/style/property_value.hpp>
-
-@interface UIColor (MGLStyleAttributeAdditions_Private) <MGLStyleAttributeValue>
-
-@end
diff --git a/platform/darwin/src/run_loop.cpp b/platform/darwin/src/run_loop.cpp
index 6e9a1c50b0..63bd8d2f53 100644
--- a/platform/darwin/src/run_loop.cpp
+++ b/platform/darwin/src/run_loop.cpp
@@ -8,7 +8,6 @@ namespace mbgl {
namespace util {
static ThreadLocal<RunLoop>& current = *new ThreadLocal<RunLoop>;
-static RunLoop mainRunLoop;
class RunLoop::Impl {
public:
@@ -22,6 +21,7 @@ RunLoop* RunLoop::Get() {
RunLoop::RunLoop(Type)
: impl(std::make_unique<Impl>()) {
+ assert(!current.get());
current.set(this);
impl->async = std::make_unique<AsyncTask>(std::bind(&RunLoop::process, this));
}
diff --git a/platform/darwin/test/MGLBackgroundStyleLayerTests.m b/platform/darwin/test/MGLBackgroundStyleLayerTests.m
index f4fdae61a4..2681b773ae 100644
--- a/platform/darwin/test/MGLBackgroundStyleLayerTests.m
+++ b/platform/darwin/test/MGLBackgroundStyleLayerTests.m
@@ -9,18 +9,15 @@
@implementation MGLBackgroundLayerTests
- (void)testBackgroundLayer {
- NSString *filePath = [[NSBundle bundleForClass:self.class] pathForResource:@"amsterdam" ofType:@"geojson"];
- NSURL *url = [NSURL fileURLWithPath:filePath];
- MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithSourceIdentifier:@"sourceID" URL:url];
-MGLBackgroundStyleLayer *layer = [[MGLBackgroundStyleLayer alloc] initWithLayerIdentifier:@"layerID" source:source];
- [self.mapView.style addSource:source];
+ MGLBackgroundStyleLayer *layer = [[MGLBackgroundStyleLayer alloc] initWithIdentifier:@"layerID"];
[self.mapView.style addLayer:layer];
layer.backgroundColor = [MGLRuntimeStylingHelper testColor];
layer.backgroundPattern = [MGLRuntimeStylingHelper testString];
layer.backgroundOpacity = [MGLRuntimeStylingHelper testNumber];
- MGLBackgroundStyleLayer *gLayer = [self.mapView.style layerWithIdentifier:@"layerID"];
+ MGLBackgroundStyleLayer *gLayer = (MGLBackgroundStyleLayer *)[self.mapView.style layerWithIdentifier:@"layerID"];
+ XCTAssertTrue([gLayer isKindOfClass:[MGLBackgroundStyleLayer class]]);
XCTAssertEqualObjects(gLayer.backgroundColor, [MGLRuntimeStylingHelper testColor]);
XCTAssertEqualObjects(gLayer.backgroundPattern, [MGLRuntimeStylingHelper testString]);
XCTAssertEqualObjects(gLayer.backgroundOpacity, [MGLRuntimeStylingHelper testNumber]);
diff --git a/platform/darwin/test/MGLCircleStyleLayerTests.m b/platform/darwin/test/MGLCircleStyleLayerTests.m
index 0e70c3f836..54ba8be6c1 100644
--- a/platform/darwin/test/MGLCircleStyleLayerTests.m
+++ b/platform/darwin/test/MGLCircleStyleLayerTests.m
@@ -11,9 +11,9 @@
- (void)testCircleLayer {
NSString *filePath = [[NSBundle bundleForClass:self.class] pathForResource:@"amsterdam" ofType:@"geojson"];
NSURL *url = [NSURL fileURLWithPath:filePath];
- MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithSourceIdentifier:@"sourceID" URL:url];
-MGLCircleStyleLayer *layer = [[MGLCircleStyleLayer alloc] initWithLayerIdentifier:@"layerID" source:source];
+ MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"sourceID" URL:url options:nil];
[self.mapView.style addSource:source];
+ MGLCircleStyleLayer *layer = [[MGLCircleStyleLayer alloc] initWithIdentifier:@"layerID" source:source];
[self.mapView.style addLayer:layer];
layer.circleRadius = [MGLRuntimeStylingHelper testNumber];
@@ -21,33 +21,36 @@ MGLCircleStyleLayer *layer = [[MGLCircleStyleLayer alloc] initWithLayerIdentifie
layer.circleBlur = [MGLRuntimeStylingHelper testNumber];
layer.circleOpacity = [MGLRuntimeStylingHelper testNumber];
layer.circleTranslate = [MGLRuntimeStylingHelper testOffset];
- layer.circleTranslateAnchor = [MGLRuntimeStylingHelper testEnum:MGLCircleStyleLayerCircleTranslateAnchorViewport type:@encode(MGLCircleStyleLayerCircleTranslateAnchor)];
- layer.circlePitchScale = [MGLRuntimeStylingHelper testEnum:MGLCircleStyleLayerCirclePitchScaleViewport type:@encode(MGLCircleStyleLayerCirclePitchScale)];
+ layer.circleTranslateAnchor = [MGLRuntimeStylingHelper testEnum:MGLCircleTranslateAnchorViewport type:@encode(MGLCircleTranslateAnchor)];
+ layer.circlePitchScale = [MGLRuntimeStylingHelper testEnum:MGLCirclePitchScaleViewport type:@encode(MGLCirclePitchScale)];
- MGLCircleStyleLayer *gLayer = [self.mapView.style layerWithIdentifier:@"layerID"];
+ MGLCircleStyleLayer *gLayer = (MGLCircleStyleLayer *)[self.mapView.style layerWithIdentifier:@"layerID"];
+ XCTAssertTrue([gLayer isKindOfClass:[MGLCircleStyleLayer class]]);
XCTAssertEqualObjects(gLayer.circleRadius, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.circleColor, [MGLRuntimeStylingHelper testColor]);
XCTAssertEqualObjects(gLayer.circleBlur, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.circleOpacity, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.circleTranslate, [MGLRuntimeStylingHelper testOffset]);
- XCTAssert([(NSValue *)gLayer.circleTranslateAnchor isEqualToValue:[MGLRuntimeStylingHelper testEnum:MGLCircleStyleLayerCircleTranslateAnchorViewport type:@encode(MGLCircleStyleLayerCircleTranslateAnchor)]], @"%@ is not equal to %@", gLayer.circleTranslateAnchor, [MGLRuntimeStylingHelper testEnum:MGLCircleStyleLayerCircleTranslateAnchorViewport type:@encode(MGLCircleStyleLayerCircleTranslateAnchor)]);
- XCTAssert([(NSValue *)gLayer.circlePitchScale isEqualToValue:[MGLRuntimeStylingHelper testEnum:MGLCircleStyleLayerCirclePitchScaleViewport type:@encode(MGLCircleStyleLayerCirclePitchScale)]], @"%@ is not equal to %@", gLayer.circlePitchScale, [MGLRuntimeStylingHelper testEnum:MGLCircleStyleLayerCirclePitchScaleViewport type:@encode(MGLCircleStyleLayerCirclePitchScale)]);
+ XCTAssert([gLayer.circleTranslateAnchor isKindOfClass:[MGLStyleConstantValue class]]);
+ XCTAssertEqualObjects(gLayer.circleTranslateAnchor, [MGLRuntimeStylingHelper testEnum:MGLCircleTranslateAnchorViewport type:@encode(MGLCircleTranslateAnchor)]);
+ XCTAssert([gLayer.circlePitchScale isKindOfClass:[MGLStyleConstantValue class]]);
+ XCTAssertEqualObjects(gLayer.circlePitchScale, [MGLRuntimeStylingHelper testEnum:MGLCirclePitchScaleViewport type:@encode(MGLCirclePitchScale)]);
layer.circleRadius = [MGLRuntimeStylingHelper testNumberFunction];
layer.circleColor = [MGLRuntimeStylingHelper testColorFunction];
layer.circleBlur = [MGLRuntimeStylingHelper testNumberFunction];
layer.circleOpacity = [MGLRuntimeStylingHelper testNumberFunction];
layer.circleTranslate = [MGLRuntimeStylingHelper testOffsetFunction];
- layer.circleTranslateAnchor = [MGLRuntimeStylingHelper testEnumFunction:MGLCircleStyleLayerCircleTranslateAnchorViewport type:@encode(MGLCircleStyleLayerCircleTranslateAnchor)];
- layer.circlePitchScale = [MGLRuntimeStylingHelper testEnumFunction:MGLCircleStyleLayerCirclePitchScaleViewport type:@encode(MGLCircleStyleLayerCirclePitchScale)];
+ layer.circleTranslateAnchor = [MGLRuntimeStylingHelper testEnumFunction:MGLCircleTranslateAnchorViewport type:@encode(MGLCircleTranslateAnchor)];
+ layer.circlePitchScale = [MGLRuntimeStylingHelper testEnumFunction:MGLCirclePitchScaleViewport type:@encode(MGLCirclePitchScale)];
XCTAssertEqualObjects(gLayer.circleRadius, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.circleColor, [MGLRuntimeStylingHelper testColorFunction]);
XCTAssertEqualObjects(gLayer.circleBlur, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.circleOpacity, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.circleTranslate, [MGLRuntimeStylingHelper testOffsetFunction]);
- XCTAssertEqualObjects(gLayer.circleTranslateAnchor, [MGLRuntimeStylingHelper testEnumFunction:MGLCircleStyleLayerCircleTranslateAnchorViewport type:@encode(MGLCircleStyleLayerCircleTranslateAnchor)]);
- XCTAssertEqualObjects(gLayer.circlePitchScale, [MGLRuntimeStylingHelper testEnumFunction:MGLCircleStyleLayerCirclePitchScaleViewport type:@encode(MGLCircleStyleLayerCirclePitchScale)]);
+ XCTAssertEqualObjects(gLayer.circleTranslateAnchor, [MGLRuntimeStylingHelper testEnumFunction:MGLCircleTranslateAnchorViewport type:@encode(MGLCircleTranslateAnchor)]);
+ XCTAssertEqualObjects(gLayer.circlePitchScale, [MGLRuntimeStylingHelper testEnumFunction:MGLCirclePitchScaleViewport type:@encode(MGLCirclePitchScale)]);
}
@end
diff --git a/platform/darwin/test/MGLFeatureTests.mm b/platform/darwin/test/MGLFeatureTests.mm
index 1b1722f172..18c3fd16c2 100644
--- a/platform/darwin/test/MGLFeatureTests.mm
+++ b/platform/darwin/test/MGLFeatureTests.mm
@@ -158,4 +158,169 @@
XCTAssertEqual(string, shape.attributes[@"string"]);
}
+- (void)testPointFeatureGeoJSONDictionary {
+ MGLPointFeature<MGLFeaturePrivate> *pointFeature = (MGLPointFeature<MGLFeaturePrivate> *)[[MGLPointFeature alloc] init];
+ CLLocationCoordinate2D coordinate = { 10, 10 };
+ pointFeature.coordinate = coordinate;
+
+ // A GeoJSON feature
+ // when there are no identifier or properties
+ NSDictionary *geoJSONFeature = [pointFeature geoJSONDictionary];
+
+ // it has the correct type
+ XCTAssertEqualObjects(geoJSONFeature[@"type"], @"Feature");
+ // it has the correct geometry
+ NSDictionary *expectedGeometry = @{@"type": @"Point",
+ @"coordinates": @[@(coordinate.longitude), @(coordinate.latitude)]};
+ XCTAssertEqualObjects(geoJSONFeature[@"geometry"], expectedGeometry);
+ // it has no "id" key (or value)
+ XCTAssertNil(geoJSONFeature[@"id"]);
+ // it has a null representation of the properties object
+ XCTAssertEqualObjects(geoJSONFeature[@"properties"], [NSNull null]);
+
+ // when there is a string identifier
+ pointFeature.identifier = @"string-id";
+
+ // it has the identifier in the result
+ geoJSONFeature = [pointFeature geoJSONDictionary];
+ XCTAssertEqualObjects(geoJSONFeature[@"id"], pointFeature.identifier);
+
+ // when there are properties
+ pointFeature.attributes = @{@"name": @"name-value"};
+
+ // it has the properties value in the result
+ geoJSONFeature = [pointFeature geoJSONDictionary];
+ XCTAssertEqualObjects(geoJSONFeature[@"properties"], pointFeature.attributes);
+}
+
+- (void)testPolylineFeatureGeoJSONDictionary {
+ CLLocationCoordinate2D coord1 = { 0, 0 };
+ CLLocationCoordinate2D coord2 = { 10, 10 };
+ CLLocationCoordinate2D coords[] = { coord1, coord2 };
+ MGLPolylineFeature *polyLineFeature = [MGLPolylineFeature polylineWithCoordinates:coords count:2];
+
+ // A GeoJSON feature
+ NSDictionary *geoJSONFeature = [polyLineFeature geoJSONDictionary];
+
+ // it has the correct geometry
+ NSDictionary *expectedGeometry = @{@"type": @"LineString",
+ @"coordinates": @[@[@(coord1.longitude), @(coord1.latitude)],
+ @[@(coord2.longitude), @(coord2.latitude)]]};
+ XCTAssertEqualObjects(geoJSONFeature[@"geometry"], expectedGeometry);
+}
+
+- (void)testPolygonFeatureGeoJSONDictionary {
+ CLLocationCoordinate2D coord1 = { 0, 0 };
+ CLLocationCoordinate2D coord2 = { 10, 10 };
+ CLLocationCoordinate2D coord3 = { 0, 0 };
+ CLLocationCoordinate2D coords[] = { coord1, coord2, coord3 };
+ MGLPolygonFeature *polygonFeature = [MGLPolygonFeature polygonWithCoordinates:coords count:3];
+
+ // A GeoJSON feature
+ NSDictionary *geoJSONFeature = [polygonFeature geoJSONDictionary];
+
+ // it has the correct geometry
+ NSDictionary *expectedGeometry = @{@"type": @"Polygon",
+ @"coordinates": @[@[@[@(coord1.longitude), @(coord1.latitude)],
+ @[@(coord2.longitude), @(coord2.latitude)],
+ @[@(coord3.longitude), @(coord3.latitude)]]]};
+ XCTAssertEqualObjects(geoJSONFeature[@"geometry"], expectedGeometry);
+}
+
+- (void)testMultiPointFeatureGeoJSONDictionary {
+ CLLocationCoordinate2D coord1 = { 0, 0 };
+ CLLocationCoordinate2D coord2 = { 10, 10 };
+ CLLocationCoordinate2D coord3 = { 0, 0 };
+ CLLocationCoordinate2D coords[] = { coord1, coord2, coord3 };
+ MGLMultiPointFeature *multiPointFeature = [MGLMultiPointFeature multiPointWithCoordinates:coords count:3];
+
+ // A GeoJSON feature
+ NSDictionary *geoJSONFeature = [multiPointFeature geoJSONDictionary];
+
+ // it has the correct geometry
+ NSDictionary *expectedGeometry = @{@"type": @"MultiPoint",
+ @"coordinates": @[@[@(coord1.longitude), @(coord1.latitude)],
+ @[@(coord2.longitude), @(coord2.latitude)],
+ @[@(coord3.longitude), @(coord3.latitude)]]};
+ XCTAssertEqualObjects(geoJSONFeature[@"geometry"], expectedGeometry);
+}
+
+- (void)testMultiPolylineFeatureGeoJSONDictionary {
+ CLLocationCoordinate2D coord1 = { 0, 0 };
+ CLLocationCoordinate2D coord2 = { 10, 10 };
+ CLLocationCoordinate2D coord3 = { 0, 0 };
+ CLLocationCoordinate2D coords[] = { coord1, coord2, coord3 };
+
+ MGLPolyline *polyLine1 = [MGLPolyline polylineWithCoordinates:coords count:3];
+ MGLPolyline *polyLine2 = [MGLPolyline polylineWithCoordinates:coords count:3];
+
+ MGLMultiPolylineFeature *multiPolylineFeature = [MGLMultiPolylineFeature multiPolylineWithPolylines:@[polyLine1, polyLine2]];
+
+ // A GeoJSON feature
+ NSDictionary *geoJSONFeature = [multiPolylineFeature geoJSONDictionary];
+
+ // it has the correct geometry
+ NSDictionary *expectedGeometry = @{@"type": @"MultiLineString",
+ @"coordinates": @[@[@[@(coord1.longitude), @(coord1.latitude)],
+ @[@(coord2.longitude), @(coord2.latitude)],
+ @[@(coord3.longitude), @(coord3.latitude)]],
+ @[@[@(coord1.longitude), @(coord1.latitude)],
+ @[@(coord2.longitude), @(coord2.latitude)],
+ @[@(coord3.longitude), @(coord3.latitude)]]]};
+ XCTAssertEqualObjects(geoJSONFeature[@"geometry"], expectedGeometry);
+}
+
+- (void)testMultiPolygonFeatureGeoJSONDictionary {
+ CLLocationCoordinate2D coord1 = { 0, 0 };
+ CLLocationCoordinate2D coord2 = { 10, 10 };
+ CLLocationCoordinate2D coord3 = { 0, 0 };
+ CLLocationCoordinate2D coords[] = { coord1, coord2, coord3 };
+
+ MGLPolygon *polygon1 = [MGLPolygon polygonWithCoordinates:coords count:3];
+ MGLPolygon *polygon2 = [MGLPolygon polygonWithCoordinates:coords count:3];
+
+ MGLMultiPolygonFeature *multiPolylineFeature = [MGLMultiPolygonFeature multiPolygonWithPolygons:@[polygon1, polygon2]];
+
+ // A GeoJSON feature
+ NSDictionary *geoJSONFeature = [multiPolylineFeature geoJSONDictionary];
+
+ // it has the correct geometry
+ NSDictionary *expectedGeometry = @{@"type": @"MultiPolygon",
+ @"coordinates": @[
+ @[@[@[@(coord1.longitude), @(coord1.latitude)],
+ @[@(coord2.longitude), @(coord2.latitude)],
+ @[@(coord3.longitude), @(coord3.latitude)]]],
+ @[@[@[@(coord1.longitude), @(coord1.latitude)],
+ @[@(coord2.longitude), @(coord2.latitude)],
+ @[@(coord3.longitude), @(coord3.latitude)]]]]};
+ XCTAssertEqualObjects(geoJSONFeature[@"geometry"], expectedGeometry);
+}
+
+- (void)testShapeCollectionFeatureGeoJSONDictionary {
+ MGLPointAnnotation *pointFeature = [[MGLPointAnnotation alloc] init];
+ CLLocationCoordinate2D pointCoordinate = { 10, 10 };
+ pointFeature.coordinate = pointCoordinate;
+
+ CLLocationCoordinate2D coord1 = { 0, 0 };
+ CLLocationCoordinate2D coord2 = { 10, 10 };
+ CLLocationCoordinate2D coords[] = { coord1, coord2 };
+ MGLPolyline *polyline = [MGLPolyline polylineWithCoordinates:coords count:2];
+
+ MGLShapeCollectionFeature *shapeCollectionFeature = [MGLShapeCollectionFeature shapeCollectionWithShapes:@[pointFeature,
+ polyline]];
+ // A GeoJSON feature
+ NSDictionary *geoJSONFeature = [shapeCollectionFeature geoJSONDictionary];
+
+ // it has the correct geometry
+ NSDictionary *expectedGeometry = @{@"type": @"GeometryCollection",
+ @"geometries": @[
+ @{@"type": @"Point",
+ @"coordinates": @[@(pointCoordinate.longitude), @(pointCoordinate.latitude)]},
+ @{@"type": @"LineString",
+ @"coordinates": @[@[@(coord1.longitude), @(coord1.latitude)],
+ @[@(coord2.longitude), @(coord2.latitude)]]}
+ ]};
+ XCTAssertEqualObjects(geoJSONFeature[@"geometry"], expectedGeometry);
+}
+
@end
diff --git a/platform/darwin/test/MGLFillStyleLayerTests.m b/platform/darwin/test/MGLFillStyleLayerTests.m
index 7994d76517..7b31207902 100644
--- a/platform/darwin/test/MGLFillStyleLayerTests.m
+++ b/platform/darwin/test/MGLFillStyleLayerTests.m
@@ -11,9 +11,9 @@
- (void)testFillLayer {
NSString *filePath = [[NSBundle bundleForClass:self.class] pathForResource:@"amsterdam" ofType:@"geojson"];
NSURL *url = [NSURL fileURLWithPath:filePath];
- MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithSourceIdentifier:@"sourceID" URL:url];
-MGLFillStyleLayer *layer = [[MGLFillStyleLayer alloc] initWithLayerIdentifier:@"layerID" source:source];
+ MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"sourceID" URL:url options:nil];
[self.mapView.style addSource:source];
+ MGLFillStyleLayer *layer = [[MGLFillStyleLayer alloc] initWithIdentifier:@"layerID" source:source];
[self.mapView.style addLayer:layer];
layer.fillAntialias = [MGLRuntimeStylingHelper testBool];
@@ -21,16 +21,18 @@ MGLFillStyleLayer *layer = [[MGLFillStyleLayer alloc] initWithLayerIdentifier:@"
layer.fillColor = [MGLRuntimeStylingHelper testColor];
layer.fillOutlineColor = [MGLRuntimeStylingHelper testColor];
layer.fillTranslate = [MGLRuntimeStylingHelper testOffset];
- layer.fillTranslateAnchor = [MGLRuntimeStylingHelper testEnum:MGLFillStyleLayerFillTranslateAnchorViewport type:@encode(MGLFillStyleLayerFillTranslateAnchor)];
+ layer.fillTranslateAnchor = [MGLRuntimeStylingHelper testEnum:MGLFillTranslateAnchorViewport type:@encode(MGLFillTranslateAnchor)];
layer.fillPattern = [MGLRuntimeStylingHelper testString];
- MGLFillStyleLayer *gLayer = [self.mapView.style layerWithIdentifier:@"layerID"];
+ MGLFillStyleLayer *gLayer = (MGLFillStyleLayer *)[self.mapView.style layerWithIdentifier:@"layerID"];
+ XCTAssertTrue([gLayer isKindOfClass:[MGLFillStyleLayer class]]);
XCTAssertEqualObjects(gLayer.fillAntialias, [MGLRuntimeStylingHelper testBool]);
XCTAssertEqualObjects(gLayer.fillOpacity, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.fillColor, [MGLRuntimeStylingHelper testColor]);
XCTAssertEqualObjects(gLayer.fillOutlineColor, [MGLRuntimeStylingHelper testColor]);
XCTAssertEqualObjects(gLayer.fillTranslate, [MGLRuntimeStylingHelper testOffset]);
- XCTAssert([(NSValue *)gLayer.fillTranslateAnchor isEqualToValue:[MGLRuntimeStylingHelper testEnum:MGLFillStyleLayerFillTranslateAnchorViewport type:@encode(MGLFillStyleLayerFillTranslateAnchor)]], @"%@ is not equal to %@", gLayer.fillTranslateAnchor, [MGLRuntimeStylingHelper testEnum:MGLFillStyleLayerFillTranslateAnchorViewport type:@encode(MGLFillStyleLayerFillTranslateAnchor)]);
+ XCTAssert([gLayer.fillTranslateAnchor isKindOfClass:[MGLStyleConstantValue class]]);
+ XCTAssertEqualObjects(gLayer.fillTranslateAnchor, [MGLRuntimeStylingHelper testEnum:MGLFillTranslateAnchorViewport type:@encode(MGLFillTranslateAnchor)]);
XCTAssertEqualObjects(gLayer.fillPattern, [MGLRuntimeStylingHelper testString]);
layer.fillAntialias = [MGLRuntimeStylingHelper testBoolFunction];
@@ -38,7 +40,7 @@ MGLFillStyleLayer *layer = [[MGLFillStyleLayer alloc] initWithLayerIdentifier:@"
layer.fillColor = [MGLRuntimeStylingHelper testColorFunction];
layer.fillOutlineColor = [MGLRuntimeStylingHelper testColorFunction];
layer.fillTranslate = [MGLRuntimeStylingHelper testOffsetFunction];
- layer.fillTranslateAnchor = [MGLRuntimeStylingHelper testEnumFunction:MGLFillStyleLayerFillTranslateAnchorViewport type:@encode(MGLFillStyleLayerFillTranslateAnchor)];
+ layer.fillTranslateAnchor = [MGLRuntimeStylingHelper testEnumFunction:MGLFillTranslateAnchorViewport type:@encode(MGLFillTranslateAnchor)];
layer.fillPattern = [MGLRuntimeStylingHelper testStringFunction];
XCTAssertEqualObjects(gLayer.fillAntialias, [MGLRuntimeStylingHelper testBoolFunction]);
@@ -46,7 +48,7 @@ MGLFillStyleLayer *layer = [[MGLFillStyleLayer alloc] initWithLayerIdentifier:@"
XCTAssertEqualObjects(gLayer.fillColor, [MGLRuntimeStylingHelper testColorFunction]);
XCTAssertEqualObjects(gLayer.fillOutlineColor, [MGLRuntimeStylingHelper testColorFunction]);
XCTAssertEqualObjects(gLayer.fillTranslate, [MGLRuntimeStylingHelper testOffsetFunction]);
- XCTAssertEqualObjects(gLayer.fillTranslateAnchor, [MGLRuntimeStylingHelper testEnumFunction:MGLFillStyleLayerFillTranslateAnchorViewport type:@encode(MGLFillStyleLayerFillTranslateAnchor)]);
+ XCTAssertEqualObjects(gLayer.fillTranslateAnchor, [MGLRuntimeStylingHelper testEnumFunction:MGLFillTranslateAnchorViewport type:@encode(MGLFillTranslateAnchor)]);
XCTAssertEqualObjects(gLayer.fillPattern, [MGLRuntimeStylingHelper testStringFunction]);
}
diff --git a/platform/darwin/test/MGLFilterTests.mm b/platform/darwin/test/MGLFilterTests.mm
index 6fbe5f0157..2bb188575b 100644
--- a/platform/darwin/test/MGLFilterTests.mm
+++ b/platform/darwin/test/MGLFilterTests.mm
@@ -18,9 +18,9 @@
NSString *filePath = [[NSBundle bundleForClass:self.class] pathForResource:@"amsterdam" ofType:@"geojson"];
NSURL *url = [NSURL fileURLWithPath:filePath];
NSData *geoJSONData = [NSData dataWithContentsOfURL:url];
- source = [[MGLGeoJSONSource alloc] initWithSourceIdentifier:@"test-source" geoJSONData:geoJSONData];
+ source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"test-source" geoJSONData:geoJSONData options:nil];
[self.mapView.style addSource:source];
- layer = [[MGLLineStyleLayer alloc] initWithLayerIdentifier:@"test-layer" source:source];
+ layer = [[MGLLineStyleLayer alloc] initWithIdentifier:@"test-layer" source:source];
}
- (void)tearDown
@@ -74,18 +74,6 @@
[self.mapView.style addLayer:layer];
}
-- (void)testContainsPredicate
-{
- // core does not have a "contains" filter but we can achieve the equivalent by creating an `mbgl::style::InFilter`
- // and searching the value for the key
- NSPredicate *expectedPredicate = [NSPredicate predicateWithFormat:@"park IN %@", @[@"park", @"neighbourhood"]];
- NSPredicate *containsPredicate = [NSPredicate predicateWithFormat:@"%@ CONTAINS %@", @[@"park", @"neighbourhood"], @"park"];
-
- layer.predicate = containsPredicate;
- XCTAssertEqualObjects(layer.predicate, expectedPredicate);
- [self.mapView.style addLayer:layer];
-}
-
- (void)testBetweenPredicate
{
// core does not have a "between" filter but we can achieve the equivalent by creating a set of greater than or equal / less than or equal
diff --git a/platform/darwin/test/MGLLineStyleLayerTests.m b/platform/darwin/test/MGLLineStyleLayerTests.m
index ff607f2e2b..801bc12ff8 100644
--- a/platform/darwin/test/MGLLineStyleLayerTests.m
+++ b/platform/darwin/test/MGLLineStyleLayerTests.m
@@ -11,19 +11,19 @@
- (void)testLineLayer {
NSString *filePath = [[NSBundle bundleForClass:self.class] pathForResource:@"amsterdam" ofType:@"geojson"];
NSURL *url = [NSURL fileURLWithPath:filePath];
- MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithSourceIdentifier:@"sourceID" URL:url];
-MGLLineStyleLayer *layer = [[MGLLineStyleLayer alloc] initWithLayerIdentifier:@"layerID" source:source];
+ MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"sourceID" URL:url options:nil];
[self.mapView.style addSource:source];
+ MGLLineStyleLayer *layer = [[MGLLineStyleLayer alloc] initWithIdentifier:@"layerID" source:source];
[self.mapView.style addLayer:layer];
- layer.lineCap = [MGLRuntimeStylingHelper testEnum:MGLLineStyleLayerLineCapSquare type:@encode(MGLLineStyleLayerLineCap)];
- layer.lineJoin = [MGLRuntimeStylingHelper testEnum:MGLLineStyleLayerLineJoinMiter type:@encode(MGLLineStyleLayerLineJoin)];
+ layer.lineCap = [MGLRuntimeStylingHelper testEnum:MGLLineCapSquare type:@encode(MGLLineCap)];
+ layer.lineJoin = [MGLRuntimeStylingHelper testEnum:MGLLineJoinMiter type:@encode(MGLLineJoin)];
layer.lineMiterLimit = [MGLRuntimeStylingHelper testNumber];
layer.lineRoundLimit = [MGLRuntimeStylingHelper testNumber];
layer.lineOpacity = [MGLRuntimeStylingHelper testNumber];
layer.lineColor = [MGLRuntimeStylingHelper testColor];
layer.lineTranslate = [MGLRuntimeStylingHelper testOffset];
- layer.lineTranslateAnchor = [MGLRuntimeStylingHelper testEnum:MGLLineStyleLayerLineTranslateAnchorViewport type:@encode(MGLLineStyleLayerLineTranslateAnchor)];
+ layer.lineTranslateAnchor = [MGLRuntimeStylingHelper testEnum:MGLLineTranslateAnchorViewport type:@encode(MGLLineTranslateAnchor)];
layer.lineWidth = [MGLRuntimeStylingHelper testNumber];
layer.lineGapWidth = [MGLRuntimeStylingHelper testNumber];
layer.lineOffset = [MGLRuntimeStylingHelper testNumber];
@@ -31,15 +31,19 @@ MGLLineStyleLayer *layer = [[MGLLineStyleLayer alloc] initWithLayerIdentifier:@"
layer.lineDasharray = [MGLRuntimeStylingHelper testDashArray];
layer.linePattern = [MGLRuntimeStylingHelper testString];
- MGLLineStyleLayer *gLayer = [self.mapView.style layerWithIdentifier:@"layerID"];
- XCTAssert([(NSValue *)gLayer.lineCap isEqualToValue:[MGLRuntimeStylingHelper testEnum:MGLLineStyleLayerLineCapSquare type:@encode(MGLLineStyleLayerLineCap)]], @"%@ is not equal to %@", gLayer.lineCap, [MGLRuntimeStylingHelper testEnum:MGLLineStyleLayerLineCapSquare type:@encode(MGLLineStyleLayerLineCap)]);
- XCTAssert([(NSValue *)gLayer.lineJoin isEqualToValue:[MGLRuntimeStylingHelper testEnum:MGLLineStyleLayerLineJoinMiter type:@encode(MGLLineStyleLayerLineJoin)]], @"%@ is not equal to %@", gLayer.lineJoin, [MGLRuntimeStylingHelper testEnum:MGLLineStyleLayerLineJoinMiter type:@encode(MGLLineStyleLayerLineJoin)]);
+ MGLLineStyleLayer *gLayer = (MGLLineStyleLayer *)[self.mapView.style layerWithIdentifier:@"layerID"];
+ XCTAssertTrue([gLayer isKindOfClass:[MGLLineStyleLayer class]]);
+ XCTAssert([gLayer.lineCap isKindOfClass:[MGLStyleConstantValue class]]);
+ XCTAssertEqualObjects(gLayer.lineCap, [MGLRuntimeStylingHelper testEnum:MGLLineCapSquare type:@encode(MGLLineCap)]);
+ XCTAssert([gLayer.lineJoin isKindOfClass:[MGLStyleConstantValue class]]);
+ XCTAssertEqualObjects(gLayer.lineJoin, [MGLRuntimeStylingHelper testEnum:MGLLineJoinMiter type:@encode(MGLLineJoin)]);
XCTAssertEqualObjects(gLayer.lineMiterLimit, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.lineRoundLimit, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.lineOpacity, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.lineColor, [MGLRuntimeStylingHelper testColor]);
XCTAssertEqualObjects(gLayer.lineTranslate, [MGLRuntimeStylingHelper testOffset]);
- XCTAssert([(NSValue *)gLayer.lineTranslateAnchor isEqualToValue:[MGLRuntimeStylingHelper testEnum:MGLLineStyleLayerLineTranslateAnchorViewport type:@encode(MGLLineStyleLayerLineTranslateAnchor)]], @"%@ is not equal to %@", gLayer.lineTranslateAnchor, [MGLRuntimeStylingHelper testEnum:MGLLineStyleLayerLineTranslateAnchorViewport type:@encode(MGLLineStyleLayerLineTranslateAnchor)]);
+ XCTAssert([gLayer.lineTranslateAnchor isKindOfClass:[MGLStyleConstantValue class]]);
+ XCTAssertEqualObjects(gLayer.lineTranslateAnchor, [MGLRuntimeStylingHelper testEnum:MGLLineTranslateAnchorViewport type:@encode(MGLLineTranslateAnchor)]);
XCTAssertEqualObjects(gLayer.lineWidth, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.lineGapWidth, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.lineOffset, [MGLRuntimeStylingHelper testNumber]);
@@ -47,14 +51,14 @@ MGLLineStyleLayer *layer = [[MGLLineStyleLayer alloc] initWithLayerIdentifier:@"
XCTAssertEqualObjects(gLayer.lineDasharray, [MGLRuntimeStylingHelper testDashArray]);
XCTAssertEqualObjects(gLayer.linePattern, [MGLRuntimeStylingHelper testString]);
- layer.lineCap = [MGLRuntimeStylingHelper testEnumFunction:MGLLineStyleLayerLineCapSquare type:@encode(MGLLineStyleLayerLineCap)];
- layer.lineJoin = [MGLRuntimeStylingHelper testEnumFunction:MGLLineStyleLayerLineJoinMiter type:@encode(MGLLineStyleLayerLineJoin)];
+ layer.lineCap = [MGLRuntimeStylingHelper testEnumFunction:MGLLineCapSquare type:@encode(MGLLineCap)];
+ layer.lineJoin = [MGLRuntimeStylingHelper testEnumFunction:MGLLineJoinMiter type:@encode(MGLLineJoin)];
layer.lineMiterLimit = [MGLRuntimeStylingHelper testNumberFunction];
layer.lineRoundLimit = [MGLRuntimeStylingHelper testNumberFunction];
layer.lineOpacity = [MGLRuntimeStylingHelper testNumberFunction];
layer.lineColor = [MGLRuntimeStylingHelper testColorFunction];
layer.lineTranslate = [MGLRuntimeStylingHelper testOffsetFunction];
- layer.lineTranslateAnchor = [MGLRuntimeStylingHelper testEnumFunction:MGLLineStyleLayerLineTranslateAnchorViewport type:@encode(MGLLineStyleLayerLineTranslateAnchor)];
+ layer.lineTranslateAnchor = [MGLRuntimeStylingHelper testEnumFunction:MGLLineTranslateAnchorViewport type:@encode(MGLLineTranslateAnchor)];
layer.lineWidth = [MGLRuntimeStylingHelper testNumberFunction];
layer.lineGapWidth = [MGLRuntimeStylingHelper testNumberFunction];
layer.lineOffset = [MGLRuntimeStylingHelper testNumberFunction];
@@ -62,14 +66,14 @@ MGLLineStyleLayer *layer = [[MGLLineStyleLayer alloc] initWithLayerIdentifier:@"
layer.lineDasharray = [MGLRuntimeStylingHelper testDashArrayFunction];
layer.linePattern = [MGLRuntimeStylingHelper testStringFunction];
- XCTAssertEqualObjects(gLayer.lineCap, [MGLRuntimeStylingHelper testEnumFunction:MGLLineStyleLayerLineCapSquare type:@encode(MGLLineStyleLayerLineCap)]);
- XCTAssertEqualObjects(gLayer.lineJoin, [MGLRuntimeStylingHelper testEnumFunction:MGLLineStyleLayerLineJoinMiter type:@encode(MGLLineStyleLayerLineJoin)]);
+ XCTAssertEqualObjects(gLayer.lineCap, [MGLRuntimeStylingHelper testEnumFunction:MGLLineCapSquare type:@encode(MGLLineCap)]);
+ XCTAssertEqualObjects(gLayer.lineJoin, [MGLRuntimeStylingHelper testEnumFunction:MGLLineJoinMiter type:@encode(MGLLineJoin)]);
XCTAssertEqualObjects(gLayer.lineMiterLimit, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.lineRoundLimit, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.lineOpacity, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.lineColor, [MGLRuntimeStylingHelper testColorFunction]);
XCTAssertEqualObjects(gLayer.lineTranslate, [MGLRuntimeStylingHelper testOffsetFunction]);
- XCTAssertEqualObjects(gLayer.lineTranslateAnchor, [MGLRuntimeStylingHelper testEnumFunction:MGLLineStyleLayerLineTranslateAnchorViewport type:@encode(MGLLineStyleLayerLineTranslateAnchor)]);
+ XCTAssertEqualObjects(gLayer.lineTranslateAnchor, [MGLRuntimeStylingHelper testEnumFunction:MGLLineTranslateAnchorViewport type:@encode(MGLLineTranslateAnchor)]);
XCTAssertEqualObjects(gLayer.lineWidth, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.lineGapWidth, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.lineOffset, [MGLRuntimeStylingHelper testNumberFunction]);
diff --git a/platform/darwin/test/MGLRasterStyleLayerTests.m b/platform/darwin/test/MGLRasterStyleLayerTests.m
index 7158c9aef2..f68f6d3283 100644
--- a/platform/darwin/test/MGLRasterStyleLayerTests.m
+++ b/platform/darwin/test/MGLRasterStyleLayerTests.m
@@ -11,9 +11,9 @@
- (void)testRasterLayer {
NSString *filePath = [[NSBundle bundleForClass:self.class] pathForResource:@"amsterdam" ofType:@"geojson"];
NSURL *url = [NSURL fileURLWithPath:filePath];
- MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithSourceIdentifier:@"sourceID" URL:url];
-MGLRasterStyleLayer *layer = [[MGLRasterStyleLayer alloc] initWithLayerIdentifier:@"layerID" source:source];
+ MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"sourceID" URL:url options:nil];
[self.mapView.style addSource:source];
+ MGLRasterStyleLayer *layer = [[MGLRasterStyleLayer alloc] initWithIdentifier:@"layerID" source:source];
[self.mapView.style addLayer:layer];
layer.rasterOpacity = [MGLRuntimeStylingHelper testNumber];
@@ -24,7 +24,8 @@ MGLRasterStyleLayer *layer = [[MGLRasterStyleLayer alloc] initWithLayerIdentifie
layer.rasterContrast = [MGLRuntimeStylingHelper testNumber];
layer.rasterFadeDuration = [MGLRuntimeStylingHelper testNumber];
- MGLRasterStyleLayer *gLayer = [self.mapView.style layerWithIdentifier:@"layerID"];
+ MGLRasterStyleLayer *gLayer = (MGLRasterStyleLayer *)[self.mapView.style layerWithIdentifier:@"layerID"];
+ XCTAssertTrue([gLayer isKindOfClass:[MGLRasterStyleLayer class]]);
XCTAssertEqualObjects(gLayer.rasterOpacity, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.rasterHueRotate, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.rasterBrightnessMin, [MGLRuntimeStylingHelper testNumber]);
diff --git a/platform/darwin/test/MGLRuntimeStylingHelper.h b/platform/darwin/test/MGLRuntimeStylingHelper.h
index 6626d13901..8857dba9c5 100644
--- a/platform/darwin/test/MGLRuntimeStylingHelper.h
+++ b/platform/darwin/test/MGLRuntimeStylingHelper.h
@@ -1,35 +1,35 @@
#import <Foundation/Foundation.h>
#import "MGLTypes.h"
-#import "MGLStyleAttributeFunction.h"
+#import "MGLStyleValue.h"
@interface MGLRuntimeStylingHelper : NSObject
-+ (NSArray *)testPadding;
-+ (MGLStyleAttributeFunction *)testPaddingFunction;
++ (MGLStyleConstantValue<NSValue *> *)testPadding;
++ (MGLStyleFunction<NSValue *> *)testPaddingFunction;
-+ (NSArray *)testOffset;
-+ (MGLStyleAttributeFunction *)testOffsetFunction;
++ (MGLStyleConstantValue<NSValue *> *)testOffset;
++ (MGLStyleFunction<NSValue *> *)testOffsetFunction;
-+ (NSArray *)testFont;
-+ (MGLStyleAttributeFunction *)testFontFunction;
++ (MGLStyleConstantValue<NSArray<NSString *> *> *)testFont;
++ (MGLStyleFunction<NSArray<NSString *> *> *)testFontFunction;
-+ (NSArray *)testDashArray;
-+ (MGLStyleAttributeFunction *)testDashArrayFunction;
++ (MGLStyleConstantValue<NSArray<NSNumber *> *> *)testDashArray;
++ (MGLStyleFunction<NSArray<NSNumber *> *> *)testDashArrayFunction;
-+ (NSNumber *)testNumber;
-+ (MGLStyleAttributeFunction *)testNumberFunction;
++ (MGLStyleConstantValue<NSNumber *> *)testNumber;
++ (MGLStyleFunction<NSNumber *> *)testNumberFunction;
-+ (NSNumber *)testBool;
-+ (MGLStyleAttributeFunction *)testBoolFunction;
++ (MGLStyleConstantValue<NSNumber *> *)testBool;
++ (MGLStyleFunction<NSNumber *> *)testBoolFunction;
-+ (NSString *)testString;
-+ (MGLStyleAttributeFunction *)testStringFunction;
++ (MGLStyleConstantValue<NSString *> *)testString;
++ (MGLStyleFunction<NSString *> *)testStringFunction;
-+ (MGLColor *)testColor;
-+ (MGLStyleAttributeFunction *)testColorFunction;
++ (MGLStyleConstantValue<MGLColor *> *)testColor;
++ (MGLStyleFunction<MGLColor *> *)testColorFunction;
-+ (NSValue *)testEnum:(NSUInteger)value type:(const char *)type;
-+ (MGLStyleAttributeFunction *)testEnumFunction:(NSUInteger)value type:(const char *)type;
++ (MGLStyleConstantValue<NSValue *> *)testEnum:(NSUInteger)value type:(const char *)type;
++ (MGLStyleFunction<NSValue *> *)testEnumFunction:(NSUInteger)value type:(const char *)type;
@end
diff --git a/platform/darwin/test/MGLRuntimeStylingHelper.m b/platform/darwin/test/MGLRuntimeStylingHelper.m
index 29e80086ec..955c664f2c 100644
--- a/platform/darwin/test/MGLRuntimeStylingHelper.m
+++ b/platform/darwin/test/MGLRuntimeStylingHelper.m
@@ -10,7 +10,7 @@
@implementation MGLRuntimeStylingHelper
-+ (NSValue *)testPadding
++ (MGLStyleConstantValue<NSValue *> *)testPadding
{
MGLEdgeInsets insets = {
.top = 1,
@@ -18,129 +18,105 @@
.bottom = 1,
.right = 1,
};
- return [NSValue value:&insets withObjCType:@encode(MGLEdgeInsets)];
+ return [MGLStyleConstantValue<NSValue *> valueWithRawValue:[NSValue value:&insets withObjCType:@encode(MGLEdgeInsets)]];
}
-+ (MGLStyleAttributeFunction *)testPaddingFunction
++ (MGLStyleFunction<NSValue *> *)testPaddingFunction
{
- MGLStyleAttributeFunction *function = [[MGLStyleAttributeFunction alloc] init];
- function.stops = @{
- @(18): self.testPadding,
- };
- return function;
+ return [MGLStyleFunction<NSValue *> functionWithStops:@{@(18): self.testPadding}];
}
-+ (NSValue *)testOffset
++ (MGLStyleConstantValue<NSValue *> *)testOffset
{
CGVector vector = CGVectorMake(1, 1);
- return [NSValue value:&vector withObjCType:@encode(CGVector)];
+ return [MGLStyleConstantValue<NSValue *> valueWithRawValue:[NSValue value:&vector withObjCType:@encode(CGVector)]];
}
-+ (MGLStyleAttributeFunction *)testOffsetFunction
++ (MGLStyleFunction<NSValue *> *)testOffsetFunction
{
- MGLStyleAttributeFunction *function = [[MGLStyleAttributeFunction alloc] init];
- function.stops = @{
- @(18): self.testOffset,
- };
- return function;
+ return [MGLStyleFunction<NSValue *> valueWithStops:@{ @(18): self.testOffset }];
}
-+ (NSArray *)testFont
++ (MGLStyleConstantValue<NSArray<NSString *> *> *)testFont
{
- return @[@"Open Sans Regular", @"Arial Unicode MS Regular"];
+ return [MGLStyleConstantValue<NSArray<NSString *> *> valueWithRawValue:@[@"Open Sans Regular", @"Arial Unicode MS Regular"]];
}
-+ (MGLStyleAttributeFunction *)testFontFunction
++ (MGLStyleFunction<NSArray<NSString *> *> *)testFontFunction
{
- MGLStyleAttributeFunction *function = [[MGLStyleAttributeFunction alloc] init];
- function.stops = @{
- @(18): self.testFont,
- };
- return function;
+ return [MGLStyleFunction<NSArray<NSString *> *> valueWithStops:@{ @18: self.testFont }];
}
-+ (NSArray *)testDashArray
++ (MGLStyleConstantValue<NSArray<NSNumber *> *> *)testDashArray
{
- return @[@1, @2];
+ return [MGLStyleConstantValue<NSArray<NSNumber *> *> valueWithRawValue:@[@1, @2]];
}
-+ (MGLStyleAttributeFunction *)testDashArrayFunction
++ (MGLStyleFunction<NSArray<NSNumber *> *> *)testDashArrayFunction
{
- MGLStyleAttributeFunction *function = [[MGLStyleAttributeFunction alloc] init];
- function.stops = @{
- @(18): self.testDashArray,
- };
- return function;
+ return [MGLStyleFunction<NSArray<NSNumber *> *> valueWithStops:@{
+ @18: self.testDashArray,
+ }];
}
-+ (NSNumber *)testNumber
++ (MGLStyleConstantValue<NSNumber *> *)testNumber
{
- return @1;
+ return [MGLStyleConstantValue<NSNumber *> valueWithRawValue:@1];
}
-+ (MGLStyleAttributeFunction *)testNumberFunction
++ (MGLStyleFunction<NSNumber *> *)testNumberFunction
{
- MGLStyleAttributeFunction *function = [[MGLStyleAttributeFunction alloc] init];
- function.stops = @{
- @(18): self.testNumber,
- };
- return function;
+ return [MGLStyleFunction<NSNumber *> valueWithStops:@{
+ @18: self.testNumber,
+ }];
}
-+ (NSNumber *)testBool
++ (MGLStyleConstantValue<NSNumber *> *)testBool
{
- return @YES;
+ return [MGLStyleConstantValue<NSNumber *> valueWithRawValue:@YES];
}
-+ (MGLStyleAttributeFunction *)testBoolFunction
++ (MGLStyleFunction<NSNumber *> *)testBoolFunction
{
- MGLStyleAttributeFunction *function = [[MGLStyleAttributeFunction alloc] init];
- function.stops = @{
- @(18): self.testBool,
- };
- return function;
+ return [MGLStyleFunction<NSNumber *> valueWithStops:@{
+ @18: self.testBool,
+ }];
}
-+ (NSString *)testString
++ (MGLStyleConstantValue<NSString *> *)testString
{
- return @"test";
+ return [MGLStyleConstantValue<NSString *> valueWithRawValue:@"test"];
}
-+ (MGLStyleAttributeFunction *)testStringFunction
++ (MGLStyleFunction<NSString *> *)testStringFunction
{
- MGLStyleAttributeFunction *function = [[MGLStyleAttributeFunction alloc] init];
- function.stops = @{
- @(18): self.testString,
- };
- return function;
+ return [MGLStyleFunction<NSString *> valueWithStops:@{
+ @18: self.testString,
+ }];
}
-+ (MGLColor *)testColor
++ (MGLStyleConstantValue<MGLColor *> *)testColor
{
- return [MGLColor redColor];
+ return [MGLStyleConstantValue<MGLColor *> valueWithRawValue:[MGLColor redColor]];
}
-+ (MGLStyleAttributeFunction *)testColorFunction
++ (MGLStyleFunction<MGLColor *> *)testColorFunction
{
- MGLStyleAttributeFunction *function = [[MGLStyleAttributeFunction alloc] init];
- function.stops = @{
- @(18): self.testColor,
- };
- return function;
+ return [MGLStyleFunction<MGLColor *> valueWithStops:@{
+ @18: self.testColor,
+ }];
}
-+ (NSValue *)testEnum:(NSUInteger)value type:(const char *)type
++ (MGLStyleConstantValue<NSValue *> *)testEnum:(NSUInteger)value type:(const char *)type
{
- return [NSValue value:&value withObjCType:type];
+ return [MGLStyleConstantValue<NSValue *> valueWithRawValue:[NSValue value:&value withObjCType:type]];
}
-+ (MGLStyleAttributeFunction *)testEnumFunction:(NSUInteger)value type:(const char *)type
++ (MGLStyleFunction<NSValue *> *)testEnumFunction:(NSUInteger)value type:(const char *)type
{
- MGLStyleAttributeFunction *function = [[MGLStyleAttributeFunction alloc] init];
- function.stops = @{
- @(18): [self testEnum:value type:type],
- };
- return function;
+ return [MGLStyleFunction<NSValue *> valueWithStops:@{
+ @18: [self testEnum:value type:type],
+ }];
}
@end
diff --git a/platform/darwin/test/MGLSymbolStyleLayerTests.m b/platform/darwin/test/MGLSymbolStyleLayerTests.m
index 096a49b571..f60ae7c2a8 100644
--- a/platform/darwin/test/MGLSymbolStyleLayerTests.m
+++ b/platform/darwin/test/MGLSymbolStyleLayerTests.m
@@ -11,41 +11,41 @@
- (void)testSymbolLayer {
NSString *filePath = [[NSBundle bundleForClass:self.class] pathForResource:@"amsterdam" ofType:@"geojson"];
NSURL *url = [NSURL fileURLWithPath:filePath];
- MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithSourceIdentifier:@"sourceID" URL:url];
-MGLSymbolStyleLayer *layer = [[MGLSymbolStyleLayer alloc] initWithLayerIdentifier:@"layerID" source:source];
+ MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"sourceID" URL:url options:nil];
[self.mapView.style addSource:source];
+ MGLSymbolStyleLayer *layer = [[MGLSymbolStyleLayer alloc] initWithIdentifier:@"layerID" source:source];
[self.mapView.style addLayer:layer];
- layer.symbolPlacement = [MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerSymbolPlacementLine type:@encode(MGLSymbolStyleLayerSymbolPlacement)];
+ layer.symbolPlacement = [MGLRuntimeStylingHelper testEnum:MGLSymbolPlacementLine type:@encode(MGLSymbolPlacement)];
layer.symbolSpacing = [MGLRuntimeStylingHelper testNumber];
layer.symbolAvoidEdges = [MGLRuntimeStylingHelper testBool];
layer.iconAllowOverlap = [MGLRuntimeStylingHelper testBool];
layer.iconIgnorePlacement = [MGLRuntimeStylingHelper testBool];
layer.iconOptional = [MGLRuntimeStylingHelper testBool];
- layer.iconRotationAlignment = [MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerIconRotationAlignmentAuto type:@encode(MGLSymbolStyleLayerIconRotationAlignment)];
+ layer.iconRotationAlignment = [MGLRuntimeStylingHelper testEnum:MGLIconRotationAlignmentAuto type:@encode(MGLIconRotationAlignment)];
layer.iconSize = [MGLRuntimeStylingHelper testNumber];
- layer.iconTextFit = [MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerIconTextFitBoth type:@encode(MGLSymbolStyleLayerIconTextFit)];
+ layer.iconTextFit = [MGLRuntimeStylingHelper testEnum:MGLIconTextFitBoth type:@encode(MGLIconTextFit)];
layer.iconTextFitPadding = [MGLRuntimeStylingHelper testPadding];
layer.iconImage = [MGLRuntimeStylingHelper testString];
layer.iconRotate = [MGLRuntimeStylingHelper testNumber];
layer.iconPadding = [MGLRuntimeStylingHelper testNumber];
layer.iconKeepUpright = [MGLRuntimeStylingHelper testBool];
layer.iconOffset = [MGLRuntimeStylingHelper testOffset];
- layer.textPitchAlignment = [MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerTextPitchAlignmentAuto type:@encode(MGLSymbolStyleLayerTextPitchAlignment)];
- layer.textRotationAlignment = [MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerTextRotationAlignmentAuto type:@encode(MGLSymbolStyleLayerTextRotationAlignment)];
+ layer.textPitchAlignment = [MGLRuntimeStylingHelper testEnum:MGLTextPitchAlignmentAuto type:@encode(MGLTextPitchAlignment)];
+ layer.textRotationAlignment = [MGLRuntimeStylingHelper testEnum:MGLTextRotationAlignmentAuto type:@encode(MGLTextRotationAlignment)];
layer.textField = [MGLRuntimeStylingHelper testString];
layer.textFont = [MGLRuntimeStylingHelper testFont];
layer.textSize = [MGLRuntimeStylingHelper testNumber];
layer.textMaxWidth = [MGLRuntimeStylingHelper testNumber];
layer.textLineHeight = [MGLRuntimeStylingHelper testNumber];
layer.textLetterSpacing = [MGLRuntimeStylingHelper testNumber];
- layer.textJustify = [MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerTextJustifyRight type:@encode(MGLSymbolStyleLayerTextJustify)];
- layer.textAnchor = [MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerTextAnchorBottomRight type:@encode(MGLSymbolStyleLayerTextAnchor)];
+ layer.textJustify = [MGLRuntimeStylingHelper testEnum:MGLTextJustifyRight type:@encode(MGLTextJustify)];
+ layer.textAnchor = [MGLRuntimeStylingHelper testEnum:MGLTextAnchorBottomRight type:@encode(MGLTextAnchor)];
layer.textMaxAngle = [MGLRuntimeStylingHelper testNumber];
layer.textRotate = [MGLRuntimeStylingHelper testNumber];
layer.textPadding = [MGLRuntimeStylingHelper testNumber];
layer.textKeepUpright = [MGLRuntimeStylingHelper testBool];
- layer.textTransform = [MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerTextTransformLowercase type:@encode(MGLSymbolStyleLayerTextTransform)];
+ layer.textTransform = [MGLRuntimeStylingHelper testEnum:MGLTextTransformLowercase type:@encode(MGLTextTransform)];
layer.textOffset = [MGLRuntimeStylingHelper testOffset];
layer.textAllowOverlap = [MGLRuntimeStylingHelper testBool];
layer.textIgnorePlacement = [MGLRuntimeStylingHelper testBool];
@@ -56,46 +56,55 @@ MGLSymbolStyleLayer *layer = [[MGLSymbolStyleLayer alloc] initWithLayerIdentifie
layer.iconHaloWidth = [MGLRuntimeStylingHelper testNumber];
layer.iconHaloBlur = [MGLRuntimeStylingHelper testNumber];
layer.iconTranslate = [MGLRuntimeStylingHelper testOffset];
- layer.iconTranslateAnchor = [MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerIconTranslateAnchorViewport type:@encode(MGLSymbolStyleLayerIconTranslateAnchor)];
+ layer.iconTranslateAnchor = [MGLRuntimeStylingHelper testEnum:MGLIconTranslateAnchorViewport type:@encode(MGLIconTranslateAnchor)];
layer.textOpacity = [MGLRuntimeStylingHelper testNumber];
layer.textColor = [MGLRuntimeStylingHelper testColor];
layer.textHaloColor = [MGLRuntimeStylingHelper testColor];
layer.textHaloWidth = [MGLRuntimeStylingHelper testNumber];
layer.textHaloBlur = [MGLRuntimeStylingHelper testNumber];
layer.textTranslate = [MGLRuntimeStylingHelper testOffset];
- layer.textTranslateAnchor = [MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerTextTranslateAnchorViewport type:@encode(MGLSymbolStyleLayerTextTranslateAnchor)];
+ layer.textTranslateAnchor = [MGLRuntimeStylingHelper testEnum:MGLTextTranslateAnchorViewport type:@encode(MGLTextTranslateAnchor)];
- MGLSymbolStyleLayer *gLayer = [self.mapView.style layerWithIdentifier:@"layerID"];
- XCTAssert([(NSValue *)gLayer.symbolPlacement isEqualToValue:[MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerSymbolPlacementLine type:@encode(MGLSymbolStyleLayerSymbolPlacement)]], @"%@ is not equal to %@", gLayer.symbolPlacement, [MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerSymbolPlacementLine type:@encode(MGLSymbolStyleLayerSymbolPlacement)]);
+ MGLSymbolStyleLayer *gLayer = (MGLSymbolStyleLayer *)[self.mapView.style layerWithIdentifier:@"layerID"];
+ XCTAssertTrue([gLayer isKindOfClass:[MGLSymbolStyleLayer class]]);
+ XCTAssert([gLayer.symbolPlacement isKindOfClass:[MGLStyleConstantValue class]]);
+ XCTAssertEqualObjects(gLayer.symbolPlacement, [MGLRuntimeStylingHelper testEnum:MGLSymbolPlacementLine type:@encode(MGLSymbolPlacement)]);
XCTAssertEqualObjects(gLayer.symbolSpacing, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.symbolAvoidEdges, [MGLRuntimeStylingHelper testBool]);
XCTAssertEqualObjects(gLayer.iconAllowOverlap, [MGLRuntimeStylingHelper testBool]);
XCTAssertEqualObjects(gLayer.iconIgnorePlacement, [MGLRuntimeStylingHelper testBool]);
XCTAssertEqualObjects(gLayer.iconOptional, [MGLRuntimeStylingHelper testBool]);
- XCTAssert([(NSValue *)gLayer.iconRotationAlignment isEqualToValue:[MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerIconRotationAlignmentAuto type:@encode(MGLSymbolStyleLayerIconRotationAlignment)]], @"%@ is not equal to %@", gLayer.iconRotationAlignment, [MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerIconRotationAlignmentAuto type:@encode(MGLSymbolStyleLayerIconRotationAlignment)]);
+ XCTAssert([gLayer.iconRotationAlignment isKindOfClass:[MGLStyleConstantValue class]]);
+ XCTAssertEqualObjects(gLayer.iconRotationAlignment, [MGLRuntimeStylingHelper testEnum:MGLIconRotationAlignmentAuto type:@encode(MGLIconRotationAlignment)]);
XCTAssertEqualObjects(gLayer.iconSize, [MGLRuntimeStylingHelper testNumber]);
- XCTAssert([(NSValue *)gLayer.iconTextFit isEqualToValue:[MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerIconTextFitBoth type:@encode(MGLSymbolStyleLayerIconTextFit)]], @"%@ is not equal to %@", gLayer.iconTextFit, [MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerIconTextFitBoth type:@encode(MGLSymbolStyleLayerIconTextFit)]);
+ XCTAssert([gLayer.iconTextFit isKindOfClass:[MGLStyleConstantValue class]]);
+ XCTAssertEqualObjects(gLayer.iconTextFit, [MGLRuntimeStylingHelper testEnum:MGLIconTextFitBoth type:@encode(MGLIconTextFit)]);
XCTAssertEqualObjects(gLayer.iconTextFitPadding, [MGLRuntimeStylingHelper testPadding]);
XCTAssertEqualObjects(gLayer.iconImage, [MGLRuntimeStylingHelper testString]);
XCTAssertEqualObjects(gLayer.iconRotate, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.iconPadding, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.iconKeepUpright, [MGLRuntimeStylingHelper testBool]);
XCTAssertEqualObjects(gLayer.iconOffset, [MGLRuntimeStylingHelper testOffset]);
- XCTAssert([(NSValue *)gLayer.textPitchAlignment isEqualToValue:[MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerTextPitchAlignmentAuto type:@encode(MGLSymbolStyleLayerTextPitchAlignment)]], @"%@ is not equal to %@", gLayer.textPitchAlignment, [MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerTextPitchAlignmentAuto type:@encode(MGLSymbolStyleLayerTextPitchAlignment)]);
- XCTAssert([(NSValue *)gLayer.textRotationAlignment isEqualToValue:[MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerTextRotationAlignmentAuto type:@encode(MGLSymbolStyleLayerTextRotationAlignment)]], @"%@ is not equal to %@", gLayer.textRotationAlignment, [MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerTextRotationAlignmentAuto type:@encode(MGLSymbolStyleLayerTextRotationAlignment)]);
+ XCTAssert([gLayer.textPitchAlignment isKindOfClass:[MGLStyleConstantValue class]]);
+ XCTAssertEqualObjects(gLayer.textPitchAlignment, [MGLRuntimeStylingHelper testEnum:MGLTextPitchAlignmentAuto type:@encode(MGLTextPitchAlignment)]);
+ XCTAssert([gLayer.textRotationAlignment isKindOfClass:[MGLStyleConstantValue class]]);
+ XCTAssertEqualObjects(gLayer.textRotationAlignment, [MGLRuntimeStylingHelper testEnum:MGLTextRotationAlignmentAuto type:@encode(MGLTextRotationAlignment)]);
XCTAssertEqualObjects(gLayer.textField, [MGLRuntimeStylingHelper testString]);
XCTAssertEqualObjects(gLayer.textFont, [MGLRuntimeStylingHelper testFont]);
XCTAssertEqualObjects(gLayer.textSize, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.textMaxWidth, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.textLineHeight, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.textLetterSpacing, [MGLRuntimeStylingHelper testNumber]);
- XCTAssert([(NSValue *)gLayer.textJustify isEqualToValue:[MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerTextJustifyRight type:@encode(MGLSymbolStyleLayerTextJustify)]], @"%@ is not equal to %@", gLayer.textJustify, [MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerTextJustifyRight type:@encode(MGLSymbolStyleLayerTextJustify)]);
- XCTAssert([(NSValue *)gLayer.textAnchor isEqualToValue:[MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerTextAnchorBottomRight type:@encode(MGLSymbolStyleLayerTextAnchor)]], @"%@ is not equal to %@", gLayer.textAnchor, [MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerTextAnchorBottomRight type:@encode(MGLSymbolStyleLayerTextAnchor)]);
+ XCTAssert([gLayer.textJustify isKindOfClass:[MGLStyleConstantValue class]]);
+ XCTAssertEqualObjects(gLayer.textJustify, [MGLRuntimeStylingHelper testEnum:MGLTextJustifyRight type:@encode(MGLTextJustify)]);
+ XCTAssert([gLayer.textAnchor isKindOfClass:[MGLStyleConstantValue class]]);
+ XCTAssertEqualObjects(gLayer.textAnchor, [MGLRuntimeStylingHelper testEnum:MGLTextAnchorBottomRight type:@encode(MGLTextAnchor)]);
XCTAssertEqualObjects(gLayer.textMaxAngle, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.textRotate, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.textPadding, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.textKeepUpright, [MGLRuntimeStylingHelper testBool]);
- XCTAssert([(NSValue *)gLayer.textTransform isEqualToValue:[MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerTextTransformLowercase type:@encode(MGLSymbolStyleLayerTextTransform)]], @"%@ is not equal to %@", gLayer.textTransform, [MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerTextTransformLowercase type:@encode(MGLSymbolStyleLayerTextTransform)]);
+ XCTAssert([gLayer.textTransform isKindOfClass:[MGLStyleConstantValue class]]);
+ XCTAssertEqualObjects(gLayer.textTransform, [MGLRuntimeStylingHelper testEnum:MGLTextTransformLowercase type:@encode(MGLTextTransform)]);
XCTAssertEqualObjects(gLayer.textOffset, [MGLRuntimeStylingHelper testOffset]);
XCTAssertEqualObjects(gLayer.textAllowOverlap, [MGLRuntimeStylingHelper testBool]);
XCTAssertEqualObjects(gLayer.textIgnorePlacement, [MGLRuntimeStylingHelper testBool]);
@@ -106,45 +115,47 @@ MGLSymbolStyleLayer *layer = [[MGLSymbolStyleLayer alloc] initWithLayerIdentifie
XCTAssertEqualObjects(gLayer.iconHaloWidth, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.iconHaloBlur, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.iconTranslate, [MGLRuntimeStylingHelper testOffset]);
- XCTAssert([(NSValue *)gLayer.iconTranslateAnchor isEqualToValue:[MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerIconTranslateAnchorViewport type:@encode(MGLSymbolStyleLayerIconTranslateAnchor)]], @"%@ is not equal to %@", gLayer.iconTranslateAnchor, [MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerIconTranslateAnchorViewport type:@encode(MGLSymbolStyleLayerIconTranslateAnchor)]);
+ XCTAssert([gLayer.iconTranslateAnchor isKindOfClass:[MGLStyleConstantValue class]]);
+ XCTAssertEqualObjects(gLayer.iconTranslateAnchor, [MGLRuntimeStylingHelper testEnum:MGLIconTranslateAnchorViewport type:@encode(MGLIconTranslateAnchor)]);
XCTAssertEqualObjects(gLayer.textOpacity, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.textColor, [MGLRuntimeStylingHelper testColor]);
XCTAssertEqualObjects(gLayer.textHaloColor, [MGLRuntimeStylingHelper testColor]);
XCTAssertEqualObjects(gLayer.textHaloWidth, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.textHaloBlur, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.textTranslate, [MGLRuntimeStylingHelper testOffset]);
- XCTAssert([(NSValue *)gLayer.textTranslateAnchor isEqualToValue:[MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerTextTranslateAnchorViewport type:@encode(MGLSymbolStyleLayerTextTranslateAnchor)]], @"%@ is not equal to %@", gLayer.textTranslateAnchor, [MGLRuntimeStylingHelper testEnum:MGLSymbolStyleLayerTextTranslateAnchorViewport type:@encode(MGLSymbolStyleLayerTextTranslateAnchor)]);
+ XCTAssert([gLayer.textTranslateAnchor isKindOfClass:[MGLStyleConstantValue class]]);
+ XCTAssertEqualObjects(gLayer.textTranslateAnchor, [MGLRuntimeStylingHelper testEnum:MGLTextTranslateAnchorViewport type:@encode(MGLTextTranslateAnchor)]);
- layer.symbolPlacement = [MGLRuntimeStylingHelper testEnumFunction:MGLSymbolStyleLayerSymbolPlacementLine type:@encode(MGLSymbolStyleLayerSymbolPlacement)];
+ layer.symbolPlacement = [MGLRuntimeStylingHelper testEnumFunction:MGLSymbolPlacementLine type:@encode(MGLSymbolPlacement)];
layer.symbolSpacing = [MGLRuntimeStylingHelper testNumberFunction];
layer.symbolAvoidEdges = [MGLRuntimeStylingHelper testBoolFunction];
layer.iconAllowOverlap = [MGLRuntimeStylingHelper testBoolFunction];
layer.iconIgnorePlacement = [MGLRuntimeStylingHelper testBoolFunction];
layer.iconOptional = [MGLRuntimeStylingHelper testBoolFunction];
- layer.iconRotationAlignment = [MGLRuntimeStylingHelper testEnumFunction:MGLSymbolStyleLayerIconRotationAlignmentAuto type:@encode(MGLSymbolStyleLayerIconRotationAlignment)];
+ layer.iconRotationAlignment = [MGLRuntimeStylingHelper testEnumFunction:MGLIconRotationAlignmentAuto type:@encode(MGLIconRotationAlignment)];
layer.iconSize = [MGLRuntimeStylingHelper testNumberFunction];
- layer.iconTextFit = [MGLRuntimeStylingHelper testEnumFunction:MGLSymbolStyleLayerIconTextFitBoth type:@encode(MGLSymbolStyleLayerIconTextFit)];
+ layer.iconTextFit = [MGLRuntimeStylingHelper testEnumFunction:MGLIconTextFitBoth type:@encode(MGLIconTextFit)];
layer.iconTextFitPadding = [MGLRuntimeStylingHelper testPaddingFunction];
layer.iconImage = [MGLRuntimeStylingHelper testStringFunction];
layer.iconRotate = [MGLRuntimeStylingHelper testNumberFunction];
layer.iconPadding = [MGLRuntimeStylingHelper testNumberFunction];
layer.iconKeepUpright = [MGLRuntimeStylingHelper testBoolFunction];
layer.iconOffset = [MGLRuntimeStylingHelper testOffsetFunction];
- layer.textPitchAlignment = [MGLRuntimeStylingHelper testEnumFunction:MGLSymbolStyleLayerTextPitchAlignmentAuto type:@encode(MGLSymbolStyleLayerTextPitchAlignment)];
- layer.textRotationAlignment = [MGLRuntimeStylingHelper testEnumFunction:MGLSymbolStyleLayerTextRotationAlignmentAuto type:@encode(MGLSymbolStyleLayerTextRotationAlignment)];
+ layer.textPitchAlignment = [MGLRuntimeStylingHelper testEnumFunction:MGLTextPitchAlignmentAuto type:@encode(MGLTextPitchAlignment)];
+ layer.textRotationAlignment = [MGLRuntimeStylingHelper testEnumFunction:MGLTextRotationAlignmentAuto type:@encode(MGLTextRotationAlignment)];
layer.textField = [MGLRuntimeStylingHelper testStringFunction];
layer.textFont = [MGLRuntimeStylingHelper testFontFunction];
layer.textSize = [MGLRuntimeStylingHelper testNumberFunction];
layer.textMaxWidth = [MGLRuntimeStylingHelper testNumberFunction];
layer.textLineHeight = [MGLRuntimeStylingHelper testNumberFunction];
layer.textLetterSpacing = [MGLRuntimeStylingHelper testNumberFunction];
- layer.textJustify = [MGLRuntimeStylingHelper testEnumFunction:MGLSymbolStyleLayerTextJustifyRight type:@encode(MGLSymbolStyleLayerTextJustify)];
- layer.textAnchor = [MGLRuntimeStylingHelper testEnumFunction:MGLSymbolStyleLayerTextAnchorBottomRight type:@encode(MGLSymbolStyleLayerTextAnchor)];
+ layer.textJustify = [MGLRuntimeStylingHelper testEnumFunction:MGLTextJustifyRight type:@encode(MGLTextJustify)];
+ layer.textAnchor = [MGLRuntimeStylingHelper testEnumFunction:MGLTextAnchorBottomRight type:@encode(MGLTextAnchor)];
layer.textMaxAngle = [MGLRuntimeStylingHelper testNumberFunction];
layer.textRotate = [MGLRuntimeStylingHelper testNumberFunction];
layer.textPadding = [MGLRuntimeStylingHelper testNumberFunction];
layer.textKeepUpright = [MGLRuntimeStylingHelper testBoolFunction];
- layer.textTransform = [MGLRuntimeStylingHelper testEnumFunction:MGLSymbolStyleLayerTextTransformLowercase type:@encode(MGLSymbolStyleLayerTextTransform)];
+ layer.textTransform = [MGLRuntimeStylingHelper testEnumFunction:MGLTextTransformLowercase type:@encode(MGLTextTransform)];
layer.textOffset = [MGLRuntimeStylingHelper testOffsetFunction];
layer.textAllowOverlap = [MGLRuntimeStylingHelper testBoolFunction];
layer.textIgnorePlacement = [MGLRuntimeStylingHelper testBoolFunction];
@@ -155,45 +166,45 @@ MGLSymbolStyleLayer *layer = [[MGLSymbolStyleLayer alloc] initWithLayerIdentifie
layer.iconHaloWidth = [MGLRuntimeStylingHelper testNumberFunction];
layer.iconHaloBlur = [MGLRuntimeStylingHelper testNumberFunction];
layer.iconTranslate = [MGLRuntimeStylingHelper testOffsetFunction];
- layer.iconTranslateAnchor = [MGLRuntimeStylingHelper testEnumFunction:MGLSymbolStyleLayerIconTranslateAnchorViewport type:@encode(MGLSymbolStyleLayerIconTranslateAnchor)];
+ layer.iconTranslateAnchor = [MGLRuntimeStylingHelper testEnumFunction:MGLIconTranslateAnchorViewport type:@encode(MGLIconTranslateAnchor)];
layer.textOpacity = [MGLRuntimeStylingHelper testNumberFunction];
layer.textColor = [MGLRuntimeStylingHelper testColorFunction];
layer.textHaloColor = [MGLRuntimeStylingHelper testColorFunction];
layer.textHaloWidth = [MGLRuntimeStylingHelper testNumberFunction];
layer.textHaloBlur = [MGLRuntimeStylingHelper testNumberFunction];
layer.textTranslate = [MGLRuntimeStylingHelper testOffsetFunction];
- layer.textTranslateAnchor = [MGLRuntimeStylingHelper testEnumFunction:MGLSymbolStyleLayerTextTranslateAnchorViewport type:@encode(MGLSymbolStyleLayerTextTranslateAnchor)];
+ layer.textTranslateAnchor = [MGLRuntimeStylingHelper testEnumFunction:MGLTextTranslateAnchorViewport type:@encode(MGLTextTranslateAnchor)];
- XCTAssertEqualObjects(gLayer.symbolPlacement, [MGLRuntimeStylingHelper testEnumFunction:MGLSymbolStyleLayerSymbolPlacementLine type:@encode(MGLSymbolStyleLayerSymbolPlacement)]);
+ XCTAssertEqualObjects(gLayer.symbolPlacement, [MGLRuntimeStylingHelper testEnumFunction:MGLSymbolPlacementLine type:@encode(MGLSymbolPlacement)]);
XCTAssertEqualObjects(gLayer.symbolSpacing, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.symbolAvoidEdges, [MGLRuntimeStylingHelper testBoolFunction]);
XCTAssertEqualObjects(gLayer.iconAllowOverlap, [MGLRuntimeStylingHelper testBoolFunction]);
XCTAssertEqualObjects(gLayer.iconIgnorePlacement, [MGLRuntimeStylingHelper testBoolFunction]);
XCTAssertEqualObjects(gLayer.iconOptional, [MGLRuntimeStylingHelper testBoolFunction]);
- XCTAssertEqualObjects(gLayer.iconRotationAlignment, [MGLRuntimeStylingHelper testEnumFunction:MGLSymbolStyleLayerIconRotationAlignmentAuto type:@encode(MGLSymbolStyleLayerIconRotationAlignment)]);
+ XCTAssertEqualObjects(gLayer.iconRotationAlignment, [MGLRuntimeStylingHelper testEnumFunction:MGLIconRotationAlignmentAuto type:@encode(MGLIconRotationAlignment)]);
XCTAssertEqualObjects(gLayer.iconSize, [MGLRuntimeStylingHelper testNumberFunction]);
- XCTAssertEqualObjects(gLayer.iconTextFit, [MGLRuntimeStylingHelper testEnumFunction:MGLSymbolStyleLayerIconTextFitBoth type:@encode(MGLSymbolStyleLayerIconTextFit)]);
+ XCTAssertEqualObjects(gLayer.iconTextFit, [MGLRuntimeStylingHelper testEnumFunction:MGLIconTextFitBoth type:@encode(MGLIconTextFit)]);
XCTAssertEqualObjects(gLayer.iconTextFitPadding, [MGLRuntimeStylingHelper testPaddingFunction]);
XCTAssertEqualObjects(gLayer.iconImage, [MGLRuntimeStylingHelper testStringFunction]);
XCTAssertEqualObjects(gLayer.iconRotate, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.iconPadding, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.iconKeepUpright, [MGLRuntimeStylingHelper testBoolFunction]);
XCTAssertEqualObjects(gLayer.iconOffset, [MGLRuntimeStylingHelper testOffsetFunction]);
- XCTAssertEqualObjects(gLayer.textPitchAlignment, [MGLRuntimeStylingHelper testEnumFunction:MGLSymbolStyleLayerTextPitchAlignmentAuto type:@encode(MGLSymbolStyleLayerTextPitchAlignment)]);
- XCTAssertEqualObjects(gLayer.textRotationAlignment, [MGLRuntimeStylingHelper testEnumFunction:MGLSymbolStyleLayerTextRotationAlignmentAuto type:@encode(MGLSymbolStyleLayerTextRotationAlignment)]);
+ XCTAssertEqualObjects(gLayer.textPitchAlignment, [MGLRuntimeStylingHelper testEnumFunction:MGLTextPitchAlignmentAuto type:@encode(MGLTextPitchAlignment)]);
+ XCTAssertEqualObjects(gLayer.textRotationAlignment, [MGLRuntimeStylingHelper testEnumFunction:MGLTextRotationAlignmentAuto type:@encode(MGLTextRotationAlignment)]);
XCTAssertEqualObjects(gLayer.textField, [MGLRuntimeStylingHelper testStringFunction]);
XCTAssertEqualObjects(gLayer.textFont, [MGLRuntimeStylingHelper testFontFunction]);
XCTAssertEqualObjects(gLayer.textSize, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.textMaxWidth, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.textLineHeight, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.textLetterSpacing, [MGLRuntimeStylingHelper testNumberFunction]);
- XCTAssertEqualObjects(gLayer.textJustify, [MGLRuntimeStylingHelper testEnumFunction:MGLSymbolStyleLayerTextJustifyRight type:@encode(MGLSymbolStyleLayerTextJustify)]);
- XCTAssertEqualObjects(gLayer.textAnchor, [MGLRuntimeStylingHelper testEnumFunction:MGLSymbolStyleLayerTextAnchorBottomRight type:@encode(MGLSymbolStyleLayerTextAnchor)]);
+ XCTAssertEqualObjects(gLayer.textJustify, [MGLRuntimeStylingHelper testEnumFunction:MGLTextJustifyRight type:@encode(MGLTextJustify)]);
+ XCTAssertEqualObjects(gLayer.textAnchor, [MGLRuntimeStylingHelper testEnumFunction:MGLTextAnchorBottomRight type:@encode(MGLTextAnchor)]);
XCTAssertEqualObjects(gLayer.textMaxAngle, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.textRotate, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.textPadding, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.textKeepUpright, [MGLRuntimeStylingHelper testBoolFunction]);
- XCTAssertEqualObjects(gLayer.textTransform, [MGLRuntimeStylingHelper testEnumFunction:MGLSymbolStyleLayerTextTransformLowercase type:@encode(MGLSymbolStyleLayerTextTransform)]);
+ XCTAssertEqualObjects(gLayer.textTransform, [MGLRuntimeStylingHelper testEnumFunction:MGLTextTransformLowercase type:@encode(MGLTextTransform)]);
XCTAssertEqualObjects(gLayer.textOffset, [MGLRuntimeStylingHelper testOffsetFunction]);
XCTAssertEqualObjects(gLayer.textAllowOverlap, [MGLRuntimeStylingHelper testBoolFunction]);
XCTAssertEqualObjects(gLayer.textIgnorePlacement, [MGLRuntimeStylingHelper testBoolFunction]);
@@ -204,14 +215,14 @@ MGLSymbolStyleLayer *layer = [[MGLSymbolStyleLayer alloc] initWithLayerIdentifie
XCTAssertEqualObjects(gLayer.iconHaloWidth, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.iconHaloBlur, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.iconTranslate, [MGLRuntimeStylingHelper testOffsetFunction]);
- XCTAssertEqualObjects(gLayer.iconTranslateAnchor, [MGLRuntimeStylingHelper testEnumFunction:MGLSymbolStyleLayerIconTranslateAnchorViewport type:@encode(MGLSymbolStyleLayerIconTranslateAnchor)]);
+ XCTAssertEqualObjects(gLayer.iconTranslateAnchor, [MGLRuntimeStylingHelper testEnumFunction:MGLIconTranslateAnchorViewport type:@encode(MGLIconTranslateAnchor)]);
XCTAssertEqualObjects(gLayer.textOpacity, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.textColor, [MGLRuntimeStylingHelper testColorFunction]);
XCTAssertEqualObjects(gLayer.textHaloColor, [MGLRuntimeStylingHelper testColorFunction]);
XCTAssertEqualObjects(gLayer.textHaloWidth, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.textHaloBlur, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.textTranslate, [MGLRuntimeStylingHelper testOffsetFunction]);
- XCTAssertEqualObjects(gLayer.textTranslateAnchor, [MGLRuntimeStylingHelper testEnumFunction:MGLSymbolStyleLayerTextTranslateAnchorViewport type:@encode(MGLSymbolStyleLayerTextTranslateAnchor)]);
+ XCTAssertEqualObjects(gLayer.textTranslateAnchor, [MGLRuntimeStylingHelper testEnumFunction:MGLTextTranslateAnchorViewport type:@encode(MGLTextTranslateAnchor)]);
}
@end
diff --git a/platform/default/mbgl/storage/offline_database.cpp b/platform/default/mbgl/storage/offline_database.cpp
index b2ed16db56..4bcc9ad711 100644
--- a/platform/default/mbgl/storage/offline_database.cpp
+++ b/platform/default/mbgl/storage/offline_database.cpp
@@ -151,6 +151,15 @@ optional<std::pair<Response, uint64_t>> OfflineDatabase::getInternal(const Resou
}
}
+optional<int64_t> OfflineDatabase::hasInternal(const Resource& resource) {
+ if (resource.kind == Resource::Kind::Tile) {
+ assert(resource.tileData);
+ return hasTile(*resource.tileData);
+ } else {
+ return hasResource(resource);
+ }
+}
+
std::pair<bool, uint64_t> OfflineDatabase::put(const Resource& resource, const Response& response) {
return putInternal(resource, response, true);
}
@@ -236,6 +245,19 @@ optional<std::pair<Response, uint64_t>> OfflineDatabase::getResource(const Resou
return std::make_pair(response, size);
}
+optional<int64_t> OfflineDatabase::hasResource(const Resource& resource) {
+ // clang-format off
+ Statement stmt = getStatement("SELECT length(data) FROM resources WHERE url = ?");
+ // clang-format on
+
+ stmt->bind(1, resource.url);
+ if (!stmt->run()) {
+ return {};
+ }
+
+ return stmt->get<optional<int64_t>>(0);
+}
+
bool OfflineDatabase::putResource(const Resource& resource,
const Response& response,
const std::string& data,
@@ -386,6 +408,31 @@ optional<std::pair<Response, uint64_t>> OfflineDatabase::getTile(const Resource:
return std::make_pair(response, size);
}
+optional<int64_t> OfflineDatabase::hasTile(const Resource::TileData& tile) {
+ // clang-format off
+ Statement stmt = getStatement(
+ "SELECT length(data) "
+ "FROM tiles "
+ "WHERE url_template = ?1 "
+ " AND pixel_ratio = ?2 "
+ " AND x = ?3 "
+ " AND y = ?4 "
+ " AND z = ?5 ");
+ // clang-format on
+
+ stmt->bind(1, tile.urlTemplate);
+ stmt->bind(2, tile.pixelRatio);
+ stmt->bind(3, tile.x);
+ stmt->bind(4, tile.y);
+ stmt->bind(5, tile.z);
+
+ if (!stmt->run()) {
+ return {};
+ }
+
+ return stmt->get<optional<int64_t>>(0);
+}
+
bool OfflineDatabase::putTile(const Resource::TileData& tile,
const Response& response,
const std::string& data,
@@ -562,6 +609,16 @@ optional<std::pair<Response, uint64_t>> OfflineDatabase::getRegionResource(int64
return response;
}
+optional<int64_t> OfflineDatabase::hasRegionResource(int64_t regionID, const Resource& resource) {
+ auto response = hasInternal(resource);
+
+ if (response) {
+ markUsed(regionID, resource);
+ }
+
+ return response;
+}
+
uint64_t OfflineDatabase::putRegionResource(int64_t regionID, const Resource& resource, const Response& response) {
uint64_t size = putInternal(resource, response, false).second;
bool previouslyUnused = markUsed(regionID, resource);
diff --git a/platform/default/mbgl/storage/offline_database.hpp b/platform/default/mbgl/storage/offline_database.hpp
index 011817fbee..875677f7cf 100644
--- a/platform/default/mbgl/storage/offline_database.hpp
+++ b/platform/default/mbgl/storage/offline_database.hpp
@@ -46,6 +46,7 @@ public:
// Return value is (response, stored size)
optional<std::pair<Response, uint64_t>> getRegionResource(int64_t regionID, const Resource&);
+ optional<int64_t> hasRegionResource(int64_t regionID, const Resource&);
uint64_t putRegionResource(int64_t regionID, const Resource&, const Response&);
OfflineRegionDefinition getRegionDefinition(int64_t regionID);
@@ -80,14 +81,17 @@ private:
Statement getStatement(const char *);
optional<std::pair<Response, uint64_t>> getTile(const Resource::TileData&);
+ optional<int64_t> hasTile(const Resource::TileData&);
bool putTile(const Resource::TileData&, const Response&,
const std::string&, bool compressed);
optional<std::pair<Response, uint64_t>> getResource(const Resource&);
+ optional<int64_t> hasResource(const Resource&);
bool putResource(const Resource&, const Response&,
const std::string&, bool compressed);
optional<std::pair<Response, uint64_t>> getInternal(const Resource&);
+ optional<int64_t> hasInternal(const Resource&);
std::pair<bool, uint64_t> putInternal(const Resource&, const Response&, bool evict);
// Return value is true iff the resource was previously unused by any other regions.
diff --git a/platform/default/mbgl/storage/offline_download.cpp b/platform/default/mbgl/storage/offline_download.cpp
index 293166b807..9e2e11c86f 100644
--- a/platform/default/mbgl/storage/offline_download.cpp
+++ b/platform/default/mbgl/storage/offline_download.cpp
@@ -252,19 +252,26 @@ void OfflineDownload::ensureResource(const Resource& resource,
auto workRequestsIt = requests.insert(requests.begin(), nullptr);
*workRequestsIt = util::RunLoop::Get()->invokeCancellable([=]() {
requests.erase(workRequestsIt);
-
- optional<std::pair<Response, uint64_t>> offlineResponse =
- offlineDatabase.getRegionResource(id, resource);
- if (offlineResponse) {
- if (callback) {
- callback(offlineResponse->first);
+
+ auto getResourceSizeInDatabase = [&] () -> optional<int64_t> {
+ if (!callback) {
+ return offlineDatabase.hasRegionResource(id, resource);
}
-
+ optional<std::pair<Response, uint64_t>> response = offlineDatabase.getRegionResource(id, resource);
+ if (!response) {
+ return {};
+ }
+ callback(response->first);
+ return response->second;
+ };
+
+ optional<int64_t> offlineResponse = getResourceSizeInDatabase();
+ if (offlineResponse) {
status.completedResourceCount++;
- status.completedResourceSize += offlineResponse->second;
+ status.completedResourceSize += *offlineResponse;
if (resource.kind == Resource::Kind::Tile) {
status.completedTileCount += 1;
- status.completedTileSize += offlineResponse->second;
+ status.completedTileSize += *offlineResponse;
}
observer->statusChanged(status);
diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md
index 07f0a3c89d..4d8ca723c2 100644
--- a/platform/ios/CHANGELOG.md
+++ b/platform/ios/CHANGELOG.md
@@ -25,10 +25,12 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
* The `circle-pitch-scale` property is now supported in stylesheets, allowing circle features in a tilted base map to scale or remain the same size as the viewing distance changes. ([#5576](https://github.com/mapbox/mapbox-gl-native/pull/5576))
* The `identifier` property of an MGLFeature may now be either a number or string. ([#5514](https://github.com/mapbox/mapbox-gl-native/pull/5514))
* If MGLMapView is unable to obtain or parse a style, it now calls its delegate’s `-mapViewDidFailLoadingMap:withError:` method. ([#6145](https://github.com/mapbox/mapbox-gl-native/pull/6145))
+* Added the `-[MGLMapViewDelegate mapView:didFinishLoadingStyle:]` delegate method, which offers the earliest opportunity to modify the layout or appearance of the current style before the map view is displayed to the user. ([#6636](https://github.com/mapbox/mapbox-gl-native/pull/6636))
* Fixed crashes that could occur when loading a malformed stylesheet. ([#5736](https://github.com/mapbox/mapbox-gl-native/pull/5736))
* Fixed an issue causing stepwise zoom functions to be misinterpreted. ([#6328](https://github.com/mapbox/mapbox-gl-native/pull/6328))
* A source’s tiles are no longer rendered when the map is outside the source’s supported zoom levels. ([#6345](https://github.com/mapbox/mapbox-gl-native/pull/6345))
* Improved style parsing performance. ([#6170](https://github.com/mapbox/mapbox-gl-native/pull/6170))
+* Improved feature querying performance. ([#6514](https://github.com/mapbox/mapbox-gl-native/pull/6514))
### User location
@@ -50,6 +52,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
* Improved the precision of annotations at zoom levels greater than 18. ([#5517](https://github.com/mapbox/mapbox-gl-native/pull/5517))
* Fixed an issue that could reset user-added transformations on annotation views. ([#6166](https://github.com/mapbox/mapbox-gl-native/pull/6166))
* Fixed an issue that caused an annotation view to disappear if it isn’t created using the annotation view reuse queue. ([#6485](https://github.com/mapbox/mapbox-gl-native/pull/6485))
+* Deprecated `-[MGLMapViewDelegate mapView:alphaForShapeAnnotation:]` in favor of specifying an alpha component via `-[MGLMapViewDelegate mapView:strokeColorForShapeAnnotation:]` or `-[MGLMapViewDelegate mapView:fillColorForPolygonAnnotation:]`. ([#6706](https://github.com/mapbox/mapbox-gl-native/pull/6706))
### Networking and offline maps
diff --git a/platform/ios/Mapbox-iOS-SDK-symbols.podspec b/platform/ios/Mapbox-iOS-SDK-symbols.podspec
index e971990520..bbc0425088 100644
--- a/platform/ios/Mapbox-iOS-SDK-symbols.podspec
+++ b/platform/ios/Mapbox-iOS-SDK-symbols.podspec
@@ -1,7 +1,7 @@
Pod::Spec.new do |m|
m.name = 'Mapbox-iOS-SDK'
- m.version = '3.4.0-alpha.5-symbols'
+ m.version = '3.4.0-beta.1-symbols'
m.summary = 'Open source vector map solution for iOS with full styling capabilities.'
m.description = 'Open source, OpenGL-based vector map solution for iOS with full styling capabilities and Cocoa Touch APIs.'
diff --git a/platform/ios/Mapbox-iOS-SDK.podspec b/platform/ios/Mapbox-iOS-SDK.podspec
index 99144d2c70..77ada60fa4 100644
--- a/platform/ios/Mapbox-iOS-SDK.podspec
+++ b/platform/ios/Mapbox-iOS-SDK.podspec
@@ -1,7 +1,7 @@
Pod::Spec.new do |m|
m.name = 'Mapbox-iOS-SDK'
- m.version = '3.4.0-alpha.5'
+ m.version = '3.4.0-beta.1'
m.summary = 'Open source vector map solution for iOS with full styling capabilities.'
m.description = 'Open source, OpenGL-based vector map solution for iOS with full styling capabilities and Cocoa Touch APIs.'
diff --git a/platform/ios/app/MBXViewController.m b/platform/ios/app/MBXViewController.m
index 9102469574..2b4193d0a0 100644
--- a/platform/ios/app/MBXViewController.m
+++ b/platform/ios/app/MBXViewController.m
@@ -62,6 +62,7 @@ typedef NS_ENUM(NSInteger, MBXSettingsRuntimeStylingRows) {
MBXSettingsRuntimeStylingFilteredFill,
MBXSettingsRuntimeStylingFilteredLines,
MBXSettingsRuntimeStylingNumericFilteredFill,
+ MBXSettingsRuntimeStylingStyleQuery,
};
typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
@@ -473,6 +474,7 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
@"Style Fill With Filter",
@"Style Lines With Filter",
@"Style Fill With Numeric Filter",
+ @"Style Query For GeoJSON",
]];
break;
case MBXSettingsMiscellaneous:
@@ -598,6 +600,9 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
case MBXSettingsRuntimeStylingNumericFilteredFill:
[self styleNumericFilteredFills];
break;
+ case MBXSettingsRuntimeStylingStyleQuery:
+ [self styleQuery];
+ break;
default:
NSAssert(NO, @"All runtime styling setting rows should be implemented");
break;
@@ -807,33 +812,36 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
- (void)styleWaterLayer
{
MGLFillStyleLayer *waterLayer = (MGLFillStyleLayer *)[self.mapView.style layerWithIdentifier:@"water"];
- MGLStyleAttributeFunction *waterColorFunction = [[MGLStyleAttributeFunction alloc] init];
- waterColorFunction.stops = @{@6.0f: [UIColor yellowColor],
- @8.0f: [UIColor blueColor],
- @10.0f: [UIColor redColor],
- @12.0f: [UIColor greenColor],
- @14.0f: [UIColor blueColor]};
+ MGLStyleValue *waterColorFunction = [MGLStyleValue<UIColor *> valueWithStops:@{
+ @6.0f: [MGLStyleValue<UIColor *> valueWithRawValue:[UIColor yellowColor]],
+ @8.0f: [MGLStyleValue<UIColor *> valueWithRawValue:[UIColor blueColor]],
+ @10.0f: [MGLStyleValue<UIColor *> valueWithRawValue:[UIColor redColor]],
+ @12.0f: [MGLStyleValue<UIColor *> valueWithRawValue:[UIColor greenColor]],
+ @14.0f: [MGLStyleValue<UIColor *> valueWithRawValue:[UIColor blueColor]],
+ }];
waterLayer.fillColor = waterColorFunction;
- MGLStyleAttributeFunction *fillAntialias = [[MGLStyleAttributeFunction alloc] init];
- fillAntialias.stops = @{@11: @YES,
- @12: @NO,
- @13: @YES,
- @14: @NO,
- @15: @YES};
+ MGLStyleValue *fillAntialias = [MGLStyleValue<NSNumber *> valueWithStops:@{
+ @11: [MGLStyleValue<NSNumber *> valueWithRawValue:@YES],
+ @12: [MGLStyleValue<NSNumber *> valueWithRawValue:@NO],
+ @13: [MGLStyleValue<NSNumber *> valueWithRawValue:@YES],
+ @14: [MGLStyleValue<NSNumber *> valueWithRawValue:@NO],
+ @15: [MGLStyleValue<NSNumber *> valueWithRawValue:@YES],
+ }];
waterLayer.fillAntialias = fillAntialias;
}
- (void)styleRoadLayer
{
MGLLineStyleLayer *roadLayer = (MGLLineStyleLayer *)[self.mapView.style layerWithIdentifier:@"road-primary"];
- roadLayer.lineColor = [UIColor blackColor];
- MGLStyleAttributeFunction *lineWidthFunction = [[MGLStyleAttributeFunction alloc] init];
+ roadLayer.lineColor = [MGLStyleValue<UIColor *> valueWithRawValue:[UIColor blackColor]];
+ MGLStyleValue *lineWidthFunction = [MGLStyleValue<NSNumber *> valueWithStops:@{}];
- MGLStyleAttributeFunction *roadLineColor = [[MGLStyleAttributeFunction alloc] init];
- roadLineColor.stops = @{@10: [UIColor purpleColor],
- @13: [UIColor yellowColor],
- @16: [UIColor cyanColor]};
+ MGLStyleValue *roadLineColor = [MGLStyleValue<UIColor *> valueWithStops:@{
+ @10: [MGLStyleValue<UIColor *> valueWithRawValue:[UIColor purpleColor]],
+ @13: [MGLStyleValue<UIColor *> valueWithRawValue:[UIColor yellowColor]],
+ @16: [MGLStyleValue<UIColor *> valueWithRawValue:[UIColor cyanColor]],
+ }];
roadLayer.lineColor = roadLineColor;
roadLayer.lineWidth = lineWidthFunction;
roadLayer.lineGapWidth = lineWidthFunction;
@@ -846,13 +854,14 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
- (void)styleRasterLayer
{
NSURL *rasterURL = [NSURL URLWithString:@"mapbox://mapbox.satellite"];
- MGLRasterSource *rasterSource = [[MGLRasterSource alloc] initWithSourceIdentifier:@"my-raster-source" URL:rasterURL tileSize:512];
+ MGLRasterSource *rasterSource = [[MGLRasterSource alloc] initWithIdentifier:@"my-raster-source" URL:rasterURL tileSize:512];
[self.mapView.style addSource:rasterSource];
- MGLRasterStyleLayer *rasterLayer = [[MGLRasterStyleLayer alloc] initWithLayerIdentifier:@"my-raster-layer" source:rasterSource];
- MGLStyleAttributeFunction *opacityFunction = [[MGLStyleAttributeFunction alloc] init];
- opacityFunction.stops = @{@20.0f: @1.0f,
- @5.0f: @0.0f};
+ MGLRasterStyleLayer *rasterLayer = [[MGLRasterStyleLayer alloc] initWithIdentifier:@"my-raster-layer" source:rasterSource];
+ MGLStyleValue *opacityFunction = [MGLStyleValue<NSNumber *> valueWithStops:@{
+ @20.0f: [MGLStyleValue<NSNumber *> valueWithRawValue:@1.0f],
+ @5.0f: [MGLStyleValue<NSNumber *> valueWithRawValue:@0.0f],
+ }];
rasterLayer.rasterOpacity = opacityFunction;
[self.mapView.style addLayer:rasterLayer];
}
@@ -861,30 +870,30 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
{
NSString *filePath = [[NSBundle bundleForClass:self.class] pathForResource:@"amsterdam" ofType:@"geojson"];
NSURL *geoJSONURL = [NSURL fileURLWithPath:filePath];
- MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithSourceIdentifier:@"ams" URL:geoJSONURL];
+ MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"ams" URL:geoJSONURL options:nil];
[self.mapView.style addSource:source];
- MGLFillStyleLayer *fillLayer = [[MGLFillStyleLayer alloc] initWithLayerIdentifier:@"test" source:source];
- fillLayer.fillColor = [UIColor purpleColor];
+ MGLFillStyleLayer *fillLayer = [[MGLFillStyleLayer alloc] initWithIdentifier:@"test" source:source];
+ fillLayer.fillColor = [MGLStyleValue<UIColor *> valueWithRawValue:[UIColor purpleColor]];
[self.mapView.style addLayer:fillLayer];
}
- (void)styleSymbolLayer
{
MGLSymbolStyleLayer *stateLayer = (MGLSymbolStyleLayer *)[self.mapView.style layerWithIdentifier:@"state-label-lg"];
- stateLayer.textColor = [UIColor redColor];
+ stateLayer.textColor = [MGLStyleValue<UIColor *> valueWithRawValue:[UIColor redColor]];
}
- (void)styleBuildingLayer
{
MGLFillStyleLayer *buildingLayer = (MGLFillStyleLayer *)[self.mapView.style layerWithIdentifier:@"building"];
- buildingLayer.fillColor = [UIColor blackColor];
+ buildingLayer.fillColor = [MGLStyleValue<UIColor *> valueWithRawValue:[UIColor blackColor]];
}
- (void)styleFerryLayer
{
MGLLineStyleLayer *ferryLineLayer = (MGLLineStyleLayer *)[self.mapView.style layerWithIdentifier:@"ferry"];
- ferryLineLayer.lineColor = [UIColor redColor];
+ ferryLineLayer.lineColor = [MGLStyleValue<UIColor *> valueWithRawValue:[UIColor redColor]];
}
- (void)removeParkLayer
@@ -908,8 +917,8 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
statesLayer.predicate = [NSPredicate predicateWithFormat:@"name == 'Texas'"];
// paint properties
- statesLayer.fillColor = [UIColor redColor];
- statesLayer.fillOpacity = @(0.25);
+ statesLayer.fillColor = [MGLStyleValue<UIColor *> valueWithRawValue:[UIColor redColor]];
+ statesLayer.fillOpacity = [MGLStyleValue<NSNumber *> valueWithRawValue:@0.25];
});
}
@@ -928,9 +937,9 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
countiesLayer.predicate = [NSPredicate predicateWithFormat:@"NAME10 == 'Washington'"];
// paint properties
- countiesLayer.lineColor = [UIColor redColor];
- countiesLayer.lineOpacity = @(0.75);
- countiesLayer.lineWidth = @(5);
+ countiesLayer.lineColor = [MGLStyleValue<UIColor *> valueWithRawValue:[UIColor redColor]];
+ countiesLayer.lineOpacity = [MGLStyleValue<NSNumber *> valueWithRawValue:@0.75];
+ countiesLayer.lineWidth = [MGLStyleValue<NSNumber *> valueWithRawValue:@5];
});
}
@@ -949,8 +958,42 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
regionsLayer.predicate = [NSPredicate predicateWithFormat:@"HRRNUM >= %@ AND HRRNUM < 300", @(200)];
// paint properties
- regionsLayer.fillColor = [UIColor blueColor];
- regionsLayer.fillOpacity = @(0.5);
+ regionsLayer.fillColor = [MGLStyleValue<UIColor *> valueWithRawValue:[UIColor blueColor]];
+ regionsLayer.fillOpacity = [MGLStyleValue<NSNumber *> valueWithRawValue:@0.5];
+ });
+}
+
+
+- (void)styleQuery
+{
+ CGRect queryRect = CGRectInset(self.mapView.bounds, 100, 200);
+ NSArray *features = [self.mapView visibleFeaturesInRect:queryRect];
+
+ NSString *querySourceID = @"query-source-id";
+ NSString *queryLayerID = @"query-layer-id";
+
+ // RTE if you don't remove the layer first
+ // RTE if you pass a nill layer to remove layer
+ MGLStyleLayer *layer = [self.mapView.style layerWithIdentifier:queryLayerID];
+ if (layer) {
+ [self.mapView.style removeLayer:layer];
+ }
+
+ // RTE if you pass a nill source to remove source
+ MGLSource *source = [self.mapView.style sourceWithIdentifier:querySourceID];
+ if (source) {
+ [self.mapView.style removeSource:source];
+ }
+
+
+ dispatch_async(dispatch_get_main_queue(), ^{
+ MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:querySourceID features:features options:nil];
+ [self.mapView.style addSource:source];
+
+ MGLFillStyleLayer *fillLayer = [[MGLFillStyleLayer alloc] initWithIdentifier:queryLayerID source:source];
+ fillLayer.fillColor = [MGLStyleConstantValue<UIColor *> valueWithRawValue:[UIColor blueColor]];
+ fillLayer.fillOpacity = [MGLStyleConstantValue<NSNumber *> valueWithRawValue:@0.5];
+ [self.mapView.style addLayer:fillLayer];
});
}
@@ -1397,18 +1440,11 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
return YES;
}
-- (CGFloat)mapView:(__unused MGLMapView *)mapView alphaForShapeAnnotation:(MGLShape *)annotation
-{
- if ([annotation isKindOfClass:[ProgressPolyline class]]) return 0.75;
- if ([annotation isKindOfClass:[MGLPolygon class]]) return 0.5;
- return 0.5;
-}
-
- (UIColor *)mapView:(__unused MGLMapView *)mapView strokeColorForShapeAnnotation:(MGLShape *)annotation
{
- if ([annotation isKindOfClass:[ProgressPolyline class]]) return [UIColor redColor];
- if ([annotation isKindOfClass:[MGLPolyline class]]) return [UIColor darkGrayColor];
- return [UIColor blackColor];
+ if ([annotation isKindOfClass:[ProgressPolyline class]]) return [[UIColor redColor] colorWithAlphaComponent:0.75];
+ if ([annotation isKindOfClass:[MGLPolyline class]]) return [[UIColor darkGrayColor] colorWithAlphaComponent:0.5];
+ return [[UIColor blackColor] colorWithAlphaComponent:0.5];
}
- (CGFloat)mapView:(MGLMapView *)mapView lineWidthForPolylineAnnotation:(MGLPolyline *)annotation
@@ -1418,7 +1454,8 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
- (UIColor *)mapView:(__unused MGLMapView *)mapView fillColorForPolygonAnnotation:(__unused MGLPolygon *)annotation
{
- return (annotation.pointCount > 3 ? [UIColor greenColor] : [UIColor redColor]);
+ UIColor *color = annotation.pointCount > 3 ? [UIColor greenColor] : [UIColor redColor];
+ return [color colorWithAlphaComponent:0.5];
}
- (void)mapView:(__unused MGLMapView *)mapView didChangeUserTrackingMode:(MGLUserTrackingMode)mode animated:(__unused BOOL)animated
diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj
index d7887bdf03..6cc6a91cd5 100644
--- a/platform/ios/ios.xcodeproj/project.pbxproj
+++ b/platform/ios/ios.xcodeproj/project.pbxproj
@@ -7,34 +7,16 @@
objects = {
/* Begin PBXBuildFile section */
- 350098AF1D47E6F4004B2AF0 /* UIColor+MGLStyleAttributeAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 350098AD1D47E6F4004B2AF0 /* UIColor+MGLStyleAttributeAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 350098B01D47E6F4004B2AF0 /* UIColor+MGLStyleAttributeAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 350098AD1D47E6F4004B2AF0 /* UIColor+MGLStyleAttributeAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 350098B11D47E6F4004B2AF0 /* UIColor+MGLStyleAttributeAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 350098AE1D47E6F4004B2AF0 /* UIColor+MGLStyleAttributeAdditions.mm */; };
- 350098B21D47E6F4004B2AF0 /* UIColor+MGLStyleAttributeAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 350098AE1D47E6F4004B2AF0 /* UIColor+MGLStyleAttributeAdditions.mm */; };
+ 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 */; };
+ 30E5781A1DAA855E0050F07E /* UIImage+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 30E578121DAA7D690050F07E /* UIImage+MGLAdditions.mm */; };
350098BB1D480108004B2AF0 /* MGLVectorSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 350098B91D480108004B2AF0 /* MGLVectorSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
350098BC1D480108004B2AF0 /* MGLVectorSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 350098B91D480108004B2AF0 /* MGLVectorSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
350098BD1D480108004B2AF0 /* MGLVectorSource.mm in Sources */ = {isa = PBXBuildFile; fileRef = 350098BA1D480108004B2AF0 /* MGLVectorSource.mm */; };
350098BE1D480108004B2AF0 /* MGLVectorSource.mm in Sources */ = {isa = PBXBuildFile; fileRef = 350098BA1D480108004B2AF0 /* MGLVectorSource.mm */; };
- 350098C11D48149E004B2AF0 /* NSNumber+MGLStyleAttributeAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 350098BF1D48149E004B2AF0 /* NSNumber+MGLStyleAttributeAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 350098C21D48149E004B2AF0 /* NSNumber+MGLStyleAttributeAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 350098BF1D48149E004B2AF0 /* NSNumber+MGLStyleAttributeAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 350098C31D48149E004B2AF0 /* NSNumber+MGLStyleAttributeAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 350098C01D48149E004B2AF0 /* NSNumber+MGLStyleAttributeAdditions.mm */; };
- 350098C41D48149E004B2AF0 /* NSNumber+MGLStyleAttributeAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 350098C01D48149E004B2AF0 /* NSNumber+MGLStyleAttributeAdditions.mm */; };
- 350098C61D48288B004B2AF0 /* NSNumber+MGLStyleAttributeAdditions_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 350098C51D48288B004B2AF0 /* NSNumber+MGLStyleAttributeAdditions_Private.h */; };
- 350098C71D48288B004B2AF0 /* NSNumber+MGLStyleAttributeAdditions_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 350098C51D48288B004B2AF0 /* NSNumber+MGLStyleAttributeAdditions_Private.h */; };
- 350098CA1D482D9C004B2AF0 /* NSArray+MGLStyleAttributeAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 350098C81D482D9C004B2AF0 /* NSArray+MGLStyleAttributeAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 350098CB1D482D9C004B2AF0 /* NSArray+MGLStyleAttributeAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 350098C81D482D9C004B2AF0 /* NSArray+MGLStyleAttributeAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 350098CC1D482D9C004B2AF0 /* NSArray+MGLStyleAttributeAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 350098C91D482D9C004B2AF0 /* NSArray+MGLStyleAttributeAdditions.mm */; };
- 350098CD1D482D9C004B2AF0 /* NSArray+MGLStyleAttributeAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 350098C91D482D9C004B2AF0 /* NSArray+MGLStyleAttributeAdditions.mm */; };
- 350098CF1D482E10004B2AF0 /* NSArray+MGLStyleAttributeAdditions_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 350098CE1D482E10004B2AF0 /* NSArray+MGLStyleAttributeAdditions_Private.h */; };
- 350098D01D482E10004B2AF0 /* NSArray+MGLStyleAttributeAdditions_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 350098CE1D482E10004B2AF0 /* NSArray+MGLStyleAttributeAdditions_Private.h */; };
- 350098D31D4830A6004B2AF0 /* NSString+MGLStyleAttributeAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 350098D11D4830A6004B2AF0 /* NSString+MGLStyleAttributeAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 350098D41D4830A6004B2AF0 /* NSString+MGLStyleAttributeAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 350098D11D4830A6004B2AF0 /* NSString+MGLStyleAttributeAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 350098D51D4830A6004B2AF0 /* NSString+MGLStyleAttributeAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 350098D21D4830A6004B2AF0 /* NSString+MGLStyleAttributeAdditions.mm */; };
- 350098D61D4830A6004B2AF0 /* NSString+MGLStyleAttributeAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 350098D21D4830A6004B2AF0 /* NSString+MGLStyleAttributeAdditions.mm */; };
- 350098D81D4830D5004B2AF0 /* NSString+MGLStyleAttributeAdditions_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 350098D71D4830D5004B2AF0 /* NSString+MGLStyleAttributeAdditions_Private.h */; };
- 350098D91D4830D5004B2AF0 /* NSString+MGLStyleAttributeAdditions_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 350098D71D4830D5004B2AF0 /* NSString+MGLStyleAttributeAdditions_Private.h */; };
- 350098DC1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 350098DA1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 350098DD1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 350098DA1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 350098DC1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 350098DA1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.h */; };
+ 350098DD1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 350098DA1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.h */; };
350098DE1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 350098DB1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.mm */; };
350098DF1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 350098DB1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.mm */; };
3510FFEA1D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 3510FFE81D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.h */; };
@@ -66,14 +48,10 @@
35305D481D22AA680007D005 /* NSData+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 35305D471D22AA450007D005 /* NSData+MGLAdditions.mm */; };
35305D491D22AA680007D005 /* NSData+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 35305D471D22AA450007D005 /* NSData+MGLAdditions.mm */; };
35305D4A1D22AA6A0007D005 /* NSData+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 35305D461D22AA450007D005 /* NSData+MGLAdditions.h */; };
- 3534C7921D4BC95400D874A4 /* MGLStyleAttributeFunction_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 3534C7911D4BC95400D874A4 /* MGLStyleAttributeFunction_Private.h */; };
- 3534C7931D4BC95400D874A4 /* MGLStyleAttributeFunction_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 3534C7911D4BC95400D874A4 /* MGLStyleAttributeFunction_Private.h */; };
- 3534C7951D4BD1D400D874A4 /* MGLStyleAttributeValue_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 3534C7941D4BD1D400D874A4 /* MGLStyleAttributeValue_Private.h */; };
- 3534C7961D4BD1D400D874A4 /* MGLStyleAttributeValue_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 3534C7941D4BD1D400D874A4 /* MGLStyleAttributeValue_Private.h */; };
- 3538AA1D1D542239008EC33D /* MGLBaseStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 3538AA1B1D542239008EC33D /* MGLBaseStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 3538AA1E1D542239008EC33D /* MGLBaseStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 3538AA1B1D542239008EC33D /* MGLBaseStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 3538AA1F1D542239008EC33D /* MGLBaseStyleLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3538AA1C1D542239008EC33D /* MGLBaseStyleLayer.mm */; };
- 3538AA201D542239008EC33D /* MGLBaseStyleLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3538AA1C1D542239008EC33D /* MGLBaseStyleLayer.mm */; };
+ 3538AA1D1D542239008EC33D /* MGLForegroundStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 3538AA1B1D542239008EC33D /* MGLForegroundStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 3538AA1E1D542239008EC33D /* MGLForegroundStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 3538AA1B1D542239008EC33D /* MGLForegroundStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 3538AA1F1D542239008EC33D /* MGLForegroundStyleLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 3538AA1C1D542239008EC33D /* MGLForegroundStyleLayer.m */; };
+ 3538AA201D542239008EC33D /* MGLForegroundStyleLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 3538AA1C1D542239008EC33D /* MGLForegroundStyleLayer.m */; };
353933F21D3FB753003F57D7 /* MGLCircleStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 353933F11D3FB753003F57D7 /* MGLCircleStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
353933F31D3FB753003F57D7 /* MGLCircleStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 353933F11D3FB753003F57D7 /* MGLCircleStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
353933F51D3FB785003F57D7 /* MGLBackgroundStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 353933F41D3FB785003F57D7 /* MGLBackgroundStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -96,14 +74,8 @@
354B83981D2E873E005D9406 /* MGLUserLocationAnnotationView.m in Sources */ = {isa = PBXBuildFile; fileRef = 354B83951D2E873E005D9406 /* MGLUserLocationAnnotationView.m */; };
354B83991D2E873E005D9406 /* MGLUserLocationAnnotationView.m in Sources */ = {isa = PBXBuildFile; fileRef = 354B83951D2E873E005D9406 /* MGLUserLocationAnnotationView.m */; };
354B839C1D2E9B48005D9406 /* MBXUserLocationAnnotationView.m in Sources */ = {isa = PBXBuildFile; fileRef = 354B839B1D2E9B48005D9406 /* MBXUserLocationAnnotationView.m */; };
- 354D42DC1D4919F900F400A1 /* NSValue+MGLStyleAttributeAdditions_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 354D42DB1D4919F900F400A1 /* NSValue+MGLStyleAttributeAdditions_Private.h */; };
- 354D42DD1D4919F900F400A1 /* NSValue+MGLStyleAttributeAdditions_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 354D42DB1D4919F900F400A1 /* NSValue+MGLStyleAttributeAdditions_Private.h */; };
- 35599DEB1D46F14E0048254D /* MGLStyleAttributeFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 35599DE91D46F14E0048254D /* MGLStyleAttributeFunction.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 35599DEC1D46F14E0048254D /* MGLStyleAttributeFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 35599DE91D46F14E0048254D /* MGLStyleAttributeFunction.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 35599DED1D46F14E0048254D /* MGLStyleAttributeFunction.mm in Sources */ = {isa = PBXBuildFile; fileRef = 35599DEA1D46F14E0048254D /* MGLStyleAttributeFunction.mm */; };
- 35599DEE1D46F14E0048254D /* MGLStyleAttributeFunction.mm in Sources */ = {isa = PBXBuildFile; fileRef = 35599DEA1D46F14E0048254D /* MGLStyleAttributeFunction.mm */; };
- 35599DF01D46F3A60048254D /* MGLStyleAttributeValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 35599DEF1D46F3A60048254D /* MGLStyleAttributeValue.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 35599DF11D46F3A60048254D /* MGLStyleAttributeValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 35599DEF1D46F3A60048254D /* MGLStyleAttributeValue.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 35599DED1D46F14E0048254D /* MGLStyleValue.mm in Sources */ = {isa = PBXBuildFile; fileRef = 35599DEA1D46F14E0048254D /* MGLStyleValue.mm */; };
+ 35599DEE1D46F14E0048254D /* MGLStyleValue.mm in Sources */ = {isa = PBXBuildFile; fileRef = 35599DEA1D46F14E0048254D /* MGLStyleValue.mm */; };
3566C7661D4A77BA008152BC /* MGLGeoJSONSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 3566C7641D4A77BA008152BC /* MGLGeoJSONSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
3566C7671D4A77BA008152BC /* MGLGeoJSONSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 3566C7641D4A77BA008152BC /* MGLGeoJSONSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
3566C7681D4A77BA008152BC /* MGLGeoJSONSource.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3566C7651D4A77BA008152BC /* MGLGeoJSONSource.mm */; };
@@ -121,12 +93,6 @@
357579891D502B06000B822E /* MGLCircleStyleLayerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 357579881D502B06000B822E /* MGLCircleStyleLayerTests.m */; };
3575798B1D502B0C000B822E /* MGLBackgroundStyleLayerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3575798A1D502B0C000B822E /* MGLBackgroundStyleLayerTests.m */; };
3575798E1D502EC7000B822E /* MGLRuntimeStylingHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 3575798D1D502EC7000B822E /* MGLRuntimeStylingHelper.m */; };
- 3593E5211D529C29006D9365 /* MGLStyleAttribute.h in Headers */ = {isa = PBXBuildFile; fileRef = 3593E51F1D529C29006D9365 /* MGLStyleAttribute.h */; };
- 3593E5221D529C29006D9365 /* MGLStyleAttribute.h in Headers */ = {isa = PBXBuildFile; fileRef = 3593E51F1D529C29006D9365 /* MGLStyleAttribute.h */; };
- 3593E5231D529C29006D9365 /* MGLStyleAttribute.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3593E5201D529C29006D9365 /* MGLStyleAttribute.mm */; };
- 3593E5241D529C29006D9365 /* MGLStyleAttribute.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3593E5201D529C29006D9365 /* MGLStyleAttribute.mm */; };
- 3593E5261D529EDC006D9365 /* UIColor+MGLStyleAttributeAdditions_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 3593E5251D529EDC006D9365 /* UIColor+MGLStyleAttributeAdditions_Private.h */; };
- 3593E5271D529EDC006D9365 /* UIColor+MGLStyleAttributeAdditions_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 3593E5251D529EDC006D9365 /* UIColor+MGLStyleAttributeAdditions_Private.h */; };
359F57461D2FDDA6005217F1 /* MGLUserLocationAnnotationView_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 359F57451D2FDBD5005217F1 /* MGLUserLocationAnnotationView_Private.h */; };
35B82BF81D6C5F8400B1B721 /* NSPredicate+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 35B82BF61D6C5F8400B1B721 /* NSPredicate+MGLAdditions.h */; };
35B82BF91D6C5F8400B1B721 /* NSPredicate+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 35B82BF61D6C5F8400B1B721 /* NSPredicate+MGLAdditions.h */; };
@@ -153,6 +119,9 @@
35E79F201D41266300957B9E /* MGLStyleLayer_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 35E79F1F1D41266300957B9E /* MGLStyleLayer_Private.h */; };
35E79F211D41266300957B9E /* MGLStyleLayer_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 35E79F1F1D41266300957B9E /* MGLStyleLayer_Private.h */; };
36F1153D1D46080700878E1A /* libmbgl-core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 36F1153B1D46080700878E1A /* libmbgl-core.a */; };
+ 400533011DB0862B0069F638 /* NSArray+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 400532FF1DB0862B0069F638 /* NSArray+MGLAdditions.h */; };
+ 400533021DB0862B0069F638 /* NSArray+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 400533001DB0862B0069F638 /* NSArray+MGLAdditions.mm */; };
+ 400533031DB086490069F638 /* NSArray+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 400533001DB0862B0069F638 /* NSArray+MGLAdditions.mm */; };
4018B1C71CDC287F00F666AF /* MGLAnnotationView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4018B1C41CDC277F00F666AF /* MGLAnnotationView.mm */; };
4018B1C81CDC287F00F666AF /* MGLAnnotationView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4018B1C41CDC277F00F666AF /* MGLAnnotationView.mm */; };
4018B1C91CDC288A00F666AF /* MGLAnnotationView_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 4018B1C31CDC277F00F666AF /* MGLAnnotationView_Private.h */; };
@@ -166,6 +135,10 @@
404C26E71D89C55D000AA13D /* MGLTileSet_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 404C26E61D89C515000AA13D /* MGLTileSet_Private.h */; };
404C26E81D89C55D000AA13D /* MGLTileSet_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 404C26E61D89C515000AA13D /* MGLTileSet_Private.h */; };
4085AF091D933DEA00F11B22 /* MGLTileSetTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4085AF081D933DEA00F11B22 /* MGLTileSetTests.mm */; };
+ 408AA8571DAEDA1700022900 /* NSDictionary+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 408AA8551DAEDA0800022900 /* NSDictionary+MGLAdditions.h */; };
+ 408AA8581DAEDA1E00022900 /* NSDictionary+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 408AA8561DAEDA0800022900 /* NSDictionary+MGLAdditions.mm */; };
+ 408AA8591DAEDA1E00022900 /* NSDictionary+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 408AA8561DAEDA0800022900 /* NSDictionary+MGLAdditions.mm */; };
+ 40CF6DBB1DAC3C6600A4D18B /* MGLShape_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 40CF6DBA1DAC3C1800A4D18B /* MGLShape_Private.h */; };
40CFA6511D7875BB008103BD /* MGLGeoJSONSourceTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 40CFA6501D787579008103BD /* MGLGeoJSONSourceTests.mm */; };
40EDA1C01CFE0E0200D9EA68 /* MGLAnnotationContainerView.h in Headers */ = {isa = PBXBuildFile; fileRef = 40EDA1BD1CFE0D4A00D9EA68 /* MGLAnnotationContainerView.h */; };
40EDA1C11CFE0E0500D9EA68 /* MGLAnnotationContainerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 40EDA1BE1CFE0D4A00D9EA68 /* MGLAnnotationContainerView.m */; };
@@ -175,6 +148,14 @@
40FDA76B1CCAAA6800442548 /* MBXAnnotationView.m in Sources */ = {isa = PBXBuildFile; fileRef = 40FDA76A1CCAAA6800442548 /* MBXAnnotationView.m */; };
554180421D2E97DE00012372 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 554180411D2E97DE00012372 /* OpenGLES.framework */; };
55D8C9961D0F18CE00F42F10 /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 55D8C9951D0F18CE00F42F10 /* libsqlite3.tbd */; };
+ 7E016D7E1D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E016D7C1D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.h */; };
+ 7E016D7F1D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E016D7C1D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.h */; };
+ 7E016D801D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E016D7D1D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.m */; };
+ 7E016D811D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E016D7D1D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.m */; };
+ 7E016D841D9E890300A29A21 /* MGLPolygon+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E016D821D9E890300A29A21 /* MGLPolygon+MGLAdditions.h */; };
+ 7E016D851D9E890300A29A21 /* MGLPolygon+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E016D821D9E890300A29A21 /* MGLPolygon+MGLAdditions.h */; };
+ 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 */; };
DA0CD5901CF56F6A00A5F5A5 /* MGLFeatureTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA0CD58F1CF56F6A00A5F5A5 /* MGLFeatureTests.mm */; };
DA17BE301CC4BAC300402C41 /* MGLMapView_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DA17BE2F1CC4BAC300402C41 /* MGLMapView_Private.h */; };
DA17BE311CC4BDAA00402C41 /* MGLMapView_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DA17BE2F1CC4BAC300402C41 /* MGLMapView_Private.h */; };
@@ -219,6 +200,10 @@
DA35A2CA1CCAAAD200E826B2 /* NSValue+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = DA35A2C71CCAAAD200E826B2 /* NSValue+MGLAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
DA35A2CB1CCAAAD200E826B2 /* NSValue+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = DA35A2C81CCAAAD200E826B2 /* NSValue+MGLAdditions.m */; };
DA35A2CC1CCAAAD200E826B2 /* NSValue+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = DA35A2C81CCAAAD200E826B2 /* NSValue+MGLAdditions.m */; };
+ DA6408DB1DA4E7D300908C90 /* MGLVectorStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = DA6408D91DA4E7D300908C90 /* MGLVectorStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ DA6408DC1DA4E7D300908C90 /* MGLVectorStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = DA6408D91DA4E7D300908C90 /* MGLVectorStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ DA6408DD1DA4E7D300908C90 /* MGLVectorStyleLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = DA6408DA1DA4E7D300908C90 /* MGLVectorStyleLayer.m */; };
+ DA6408DE1DA4E7D300908C90 /* MGLVectorStyleLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = DA6408DA1DA4E7D300908C90 /* MGLVectorStyleLayer.m */; };
DA737EE11D056A4E005BDA16 /* MGLMapViewDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = DA737EE01D056A4E005BDA16 /* MGLMapViewDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
DA737EE21D056A4E005BDA16 /* MGLMapViewDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = DA737EE01D056A4E005BDA16 /* MGLMapViewDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
DA821D061CCC6D59007508D4 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DA821D041CCC6D59007508D4 /* LaunchScreen.storyboard */; };
@@ -252,10 +237,10 @@
DA8848221CBAFA6200AB86E3 /* MGLOfflineRegion_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8848081CBAFA6200AB86E3 /* MGLOfflineRegion_Private.h */; };
DA8848231CBAFA6200AB86E3 /* MGLOfflineStorage_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8848091CBAFA6200AB86E3 /* MGLOfflineStorage_Private.h */; };
DA8848241CBAFA6200AB86E3 /* MGLOfflineStorage.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA88480A1CBAFA6200AB86E3 /* MGLOfflineStorage.mm */; };
- DA8848251CBAFA6200AB86E3 /* MGLPointAnnotation.m in Sources */ = {isa = PBXBuildFile; fileRef = DA88480B1CBAFA6200AB86E3 /* MGLPointAnnotation.m */; };
+ DA8848251CBAFA6200AB86E3 /* MGLPointAnnotation.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA88480B1CBAFA6200AB86E3 /* MGLPointAnnotation.mm */; };
DA8848261CBAFA6200AB86E3 /* MGLPolygon.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA88480C1CBAFA6200AB86E3 /* MGLPolygon.mm */; };
DA8848271CBAFA6200AB86E3 /* MGLPolyline.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA88480D1CBAFA6200AB86E3 /* MGLPolyline.mm */; };
- DA8848281CBAFA6200AB86E3 /* MGLShape.m in Sources */ = {isa = PBXBuildFile; fileRef = DA88480E1CBAFA6200AB86E3 /* MGLShape.m */; };
+ DA8848281CBAFA6200AB86E3 /* MGLShape.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA88480E1CBAFA6200AB86E3 /* MGLShape.mm */; };
DA8848291CBAFA6200AB86E3 /* MGLStyle.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA88480F1CBAFA6200AB86E3 /* MGLStyle.mm */; };
DA88482A1CBAFA6200AB86E3 /* MGLTilePyramidOfflineRegion.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA8848101CBAFA6200AB86E3 /* MGLTilePyramidOfflineRegion.mm */; };
DA88482B1CBAFA6200AB86E3 /* MGLTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = DA8848111CBAFA6200AB86E3 /* MGLTypes.m */; };
@@ -340,10 +325,10 @@
DAA4E41F1CBB730400178DFB /* MGLMultiPoint.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA8848051CBAFA6200AB86E3 /* MGLMultiPoint.mm */; };
DAA4E4201CBB730400178DFB /* MGLOfflinePack.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA8848071CBAFA6200AB86E3 /* MGLOfflinePack.mm */; };
DAA4E4211CBB730400178DFB /* MGLOfflineStorage.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA88480A1CBAFA6200AB86E3 /* MGLOfflineStorage.mm */; };
- DAA4E4221CBB730400178DFB /* MGLPointAnnotation.m in Sources */ = {isa = PBXBuildFile; fileRef = DA88480B1CBAFA6200AB86E3 /* MGLPointAnnotation.m */; };
+ DAA4E4221CBB730400178DFB /* MGLPointAnnotation.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA88480B1CBAFA6200AB86E3 /* MGLPointAnnotation.mm */; };
DAA4E4231CBB730400178DFB /* MGLPolygon.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA88480C1CBAFA6200AB86E3 /* MGLPolygon.mm */; };
DAA4E4241CBB730400178DFB /* MGLPolyline.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA88480D1CBAFA6200AB86E3 /* MGLPolyline.mm */; };
- DAA4E4251CBB730400178DFB /* MGLShape.m in Sources */ = {isa = PBXBuildFile; fileRef = DA88480E1CBAFA6200AB86E3 /* MGLShape.m */; };
+ DAA4E4251CBB730400178DFB /* MGLShape.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA88480E1CBAFA6200AB86E3 /* MGLShape.mm */; };
DAA4E4261CBB730400178DFB /* MGLStyle.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA88480F1CBAFA6200AB86E3 /* MGLStyle.mm */; };
DAA4E4271CBB730400178DFB /* MGLTilePyramidOfflineRegion.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA8848101CBAFA6200AB86E3 /* MGLTilePyramidOfflineRegion.mm */; };
DAA4E4281CBB730400178DFB /* MGLTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = DA8848111CBAFA6200AB86E3 /* MGLTypes.m */; };
@@ -360,6 +345,10 @@
DAA4E4341CBB730400178DFB /* MGLFaux3DUserLocationAnnotationView.m in Sources */ = {isa = PBXBuildFile; fileRef = DA88484E1CBAFB9800AB86E3 /* MGLFaux3DUserLocationAnnotationView.m */; };
DAA4E4351CBB730400178DFB /* SMCalloutView.m in Sources */ = {isa = PBXBuildFile; fileRef = DA88488A1CBB037E00AB86E3 /* SMCalloutView.m */; };
DAABF73D1CBC59BB005B1825 /* libmbgl-core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAABF73B1CBC59BB005B1825 /* libmbgl-core.a */; };
+ DAAF722B1DA903C700312FA4 /* MGLStyleValue.h in Headers */ = {isa = PBXBuildFile; fileRef = DAAF72291DA903C700312FA4 /* MGLStyleValue.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ DAAF722C1DA903C700312FA4 /* MGLStyleValue.h in Headers */ = {isa = PBXBuildFile; fileRef = DAAF72291DA903C700312FA4 /* MGLStyleValue.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ DAAF722D1DA903C700312FA4 /* MGLStyleValue_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DAAF722A1DA903C700312FA4 /* MGLStyleValue_Private.h */; };
+ DAAF722E1DA903C700312FA4 /* MGLStyleValue_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DAAF722A1DA903C700312FA4 /* MGLStyleValue_Private.h */; };
DABCABAC1CB80692000A7C39 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DABCABAB1CB80692000A7C39 /* main.m */; };
DABCABAF1CB80692000A7C39 /* MBXBenchAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DABCABAE1CB80692000A7C39 /* MBXBenchAppDelegate.m */; };
DABCABB21CB80692000A7C39 /* MBXBenchViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = DABCABB11CB80692000A7C39 /* MBXBenchViewController.mm */; };
@@ -411,6 +400,9 @@
DD01C66A1DA6DC0D00ABCAC7 /* left.jpg in Resources */ = {isa = PBXBuildFile; fileRef = DD01C6631DA6DC0D00ABCAC7 /* left.jpg */; };
DD01C66B1DA6DC0D00ABCAC7 /* right.jpg in Resources */ = {isa = PBXBuildFile; fileRef = DD01C6641DA6DC0D00ABCAC7 /* right.jpg */; };
DD01C66C1DA6DC0D00ABCAC7 /* top.jpg in Resources */ = {isa = PBXBuildFile; fileRef = DD01C6651DA6DC0D00ABCAC7 /* top.jpg */; };
+ DD0902A91DB1929D00C5BDCE /* MGLNetworkConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = DD0902A21DB18DE700C5BDCE /* MGLNetworkConfiguration.m */; };
+ DD0902AA1DB1929D00C5BDCE /* MGLNetworkConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = DD0902A21DB18DE700C5BDCE /* MGLNetworkConfiguration.m */; };
+ DD0902AB1DB192A800C5BDCE /* MGLNetworkConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = DD0902A41DB18F1B00C5BDCE /* MGLNetworkConfiguration.h */; };
DD4823751D94AE6C00EB71B7 /* fill_filter_style.json in Resources */ = {isa = PBXBuildFile; fileRef = DD4823721D94AE6C00EB71B7 /* fill_filter_style.json */; };
DD4823761D94AE6C00EB71B7 /* line_filter_style.json in Resources */ = {isa = PBXBuildFile; fileRef = DD4823731D94AE6C00EB71B7 /* line_filter_style.json */; };
DD4823771D94AE6C00EB71B7 /* numeric_filter_style.json in Resources */ = {isa = PBXBuildFile; fileRef = DD4823741D94AE6C00EB71B7 /* numeric_filter_style.json */; };
@@ -497,19 +489,10 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
- 350098AD1D47E6F4004B2AF0 /* UIColor+MGLStyleAttributeAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIColor+MGLStyleAttributeAdditions.h"; path = "src/UIColor+MGLStyleAttributeAdditions.h"; sourceTree = SOURCE_ROOT; };
- 350098AE1D47E6F4004B2AF0 /* UIColor+MGLStyleAttributeAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "UIColor+MGLStyleAttributeAdditions.mm"; path = "src/UIColor+MGLStyleAttributeAdditions.mm"; sourceTree = SOURCE_ROOT; };
+ 30E578111DAA7D690050F07E /* UIImage+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIImage+MGLAdditions.h"; path = "src/UIImage+MGLAdditions.h"; sourceTree = SOURCE_ROOT; };
+ 30E578121DAA7D690050F07E /* UIImage+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = "UIImage+MGLAdditions.mm"; path = "src/UIImage+MGLAdditions.mm"; sourceTree = SOURCE_ROOT; };
350098B91D480108004B2AF0 /* MGLVectorSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLVectorSource.h; sourceTree = "<group>"; };
350098BA1D480108004B2AF0 /* MGLVectorSource.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLVectorSource.mm; sourceTree = "<group>"; };
- 350098BF1D48149E004B2AF0 /* NSNumber+MGLStyleAttributeAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSNumber+MGLStyleAttributeAdditions.h"; sourceTree = "<group>"; };
- 350098C01D48149E004B2AF0 /* NSNumber+MGLStyleAttributeAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSNumber+MGLStyleAttributeAdditions.mm"; sourceTree = "<group>"; };
- 350098C51D48288B004B2AF0 /* NSNumber+MGLStyleAttributeAdditions_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSNumber+MGLStyleAttributeAdditions_Private.h"; sourceTree = "<group>"; };
- 350098C81D482D9C004B2AF0 /* NSArray+MGLStyleAttributeAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+MGLStyleAttributeAdditions.h"; sourceTree = "<group>"; };
- 350098C91D482D9C004B2AF0 /* NSArray+MGLStyleAttributeAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSArray+MGLStyleAttributeAdditions.mm"; sourceTree = "<group>"; };
- 350098CE1D482E10004B2AF0 /* NSArray+MGLStyleAttributeAdditions_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+MGLStyleAttributeAdditions_Private.h"; sourceTree = "<group>"; };
- 350098D11D4830A6004B2AF0 /* NSString+MGLStyleAttributeAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+MGLStyleAttributeAdditions.h"; sourceTree = "<group>"; };
- 350098D21D4830A6004B2AF0 /* NSString+MGLStyleAttributeAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSString+MGLStyleAttributeAdditions.mm"; sourceTree = "<group>"; };
- 350098D71D4830D5004B2AF0 /* NSString+MGLStyleAttributeAdditions_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+MGLStyleAttributeAdditions_Private.h"; sourceTree = "<group>"; };
350098DA1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSValue+MGLStyleAttributeAdditions.h"; sourceTree = "<group>"; };
350098DB1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSValue+MGLStyleAttributeAdditions.mm"; sourceTree = "<group>"; };
3510FFE81D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSComparisonPredicate+MGLAdditions.h"; sourceTree = "<group>"; };
@@ -527,10 +510,8 @@
35136D4B1D4277FC00C20EFD /* MGLSource.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLSource.mm; sourceTree = "<group>"; };
35305D461D22AA450007D005 /* NSData+MGLAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSData+MGLAdditions.h"; sourceTree = "<group>"; };
35305D471D22AA450007D005 /* NSData+MGLAdditions.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSData+MGLAdditions.mm"; sourceTree = "<group>"; };
- 3534C7911D4BC95400D874A4 /* MGLStyleAttributeFunction_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleAttributeFunction_Private.h; sourceTree = "<group>"; };
- 3534C7941D4BD1D400D874A4 /* MGLStyleAttributeValue_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleAttributeValue_Private.h; sourceTree = "<group>"; };
- 3538AA1B1D542239008EC33D /* MGLBaseStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLBaseStyleLayer.h; sourceTree = "<group>"; };
- 3538AA1C1D542239008EC33D /* MGLBaseStyleLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLBaseStyleLayer.mm; sourceTree = "<group>"; };
+ 3538AA1B1D542239008EC33D /* MGLForegroundStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLForegroundStyleLayer.h; sourceTree = "<group>"; };
+ 3538AA1C1D542239008EC33D /* MGLForegroundStyleLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLForegroundStyleLayer.m; sourceTree = "<group>"; };
353933F11D3FB753003F57D7 /* MGLCircleStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLCircleStyleLayer.h; sourceTree = "<group>"; };
353933F41D3FB785003F57D7 /* MGLBackgroundStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLBackgroundStyleLayer.h; sourceTree = "<group>"; };
353933F71D3FB79F003F57D7 /* MGLLineStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLLineStyleLayer.h; sourceTree = "<group>"; };
@@ -544,10 +525,7 @@
354B83951D2E873E005D9406 /* MGLUserLocationAnnotationView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLUserLocationAnnotationView.m; sourceTree = "<group>"; };
354B839A1D2E9B48005D9406 /* MBXUserLocationAnnotationView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBXUserLocationAnnotationView.h; sourceTree = "<group>"; };
354B839B1D2E9B48005D9406 /* MBXUserLocationAnnotationView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBXUserLocationAnnotationView.m; sourceTree = "<group>"; };
- 354D42DB1D4919F900F400A1 /* NSValue+MGLStyleAttributeAdditions_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSValue+MGLStyleAttributeAdditions_Private.h"; sourceTree = "<group>"; };
- 35599DE91D46F14E0048254D /* MGLStyleAttributeFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleAttributeFunction.h; sourceTree = "<group>"; };
- 35599DEA1D46F14E0048254D /* MGLStyleAttributeFunction.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLStyleAttributeFunction.mm; sourceTree = "<group>"; };
- 35599DEF1D46F3A60048254D /* MGLStyleAttributeValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleAttributeValue.h; sourceTree = "<group>"; };
+ 35599DEA1D46F14E0048254D /* MGLStyleValue.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLStyleValue.mm; sourceTree = "<group>"; };
3566C7641D4A77BA008152BC /* MGLGeoJSONSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLGeoJSONSource.h; sourceTree = "<group>"; };
3566C7651D4A77BA008152BC /* MGLGeoJSONSource.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLGeoJSONSource.mm; sourceTree = "<group>"; };
3566C76A1D4A8DFA008152BC /* MGLRasterSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLRasterSource.h; sourceTree = "<group>"; };
@@ -561,9 +539,6 @@
3575798A1D502B0C000B822E /* MGLBackgroundStyleLayerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MGLBackgroundStyleLayerTests.m; path = ../../darwin/test/MGLBackgroundStyleLayerTests.m; sourceTree = "<group>"; };
3575798C1D502EC7000B822E /* MGLRuntimeStylingHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MGLRuntimeStylingHelper.h; path = ../../darwin/test/MGLRuntimeStylingHelper.h; sourceTree = "<group>"; };
3575798D1D502EC7000B822E /* MGLRuntimeStylingHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MGLRuntimeStylingHelper.m; path = ../../darwin/test/MGLRuntimeStylingHelper.m; sourceTree = "<group>"; };
- 3593E51F1D529C29006D9365 /* MGLStyleAttribute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleAttribute.h; sourceTree = "<group>"; };
- 3593E5201D529C29006D9365 /* MGLStyleAttribute.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLStyleAttribute.mm; sourceTree = "<group>"; };
- 3593E5251D529EDC006D9365 /* UIColor+MGLStyleAttributeAdditions_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIColor+MGLStyleAttributeAdditions_Private.h"; sourceTree = "<group>"; };
359F57451D2FDBD5005217F1 /* MGLUserLocationAnnotationView_Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLUserLocationAnnotationView_Private.h; sourceTree = "<group>"; };
35B82BF61D6C5F8400B1B721 /* NSPredicate+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSPredicate+MGLAdditions.h"; sourceTree = "<group>"; };
35B82BF71D6C5F8400B1B721 /* NSPredicate+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSPredicate+MGLAdditions.mm"; sourceTree = "<group>"; };
@@ -580,6 +555,8 @@
35E79F1F1D41266300957B9E /* MGLStyleLayer_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleLayer_Private.h; sourceTree = "<group>"; };
36F1153B1D46080700878E1A /* libmbgl-core.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libmbgl-core.a"; path = "build/Debug-iphoneos/libmbgl-core.a"; sourceTree = "<group>"; };
36F1153C1D46080700878E1A /* libmbgl-platform-ios.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libmbgl-platform-ios.a"; path = "build/Debug-iphoneos/libmbgl-platform-ios.a"; sourceTree = "<group>"; };
+ 400532FF1DB0862B0069F638 /* NSArray+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+MGLAdditions.h"; sourceTree = "<group>"; };
+ 400533001DB0862B0069F638 /* NSArray+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSArray+MGLAdditions.mm"; sourceTree = "<group>"; };
4018B1C31CDC277F00F666AF /* MGLAnnotationView_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLAnnotationView_Private.h; sourceTree = "<group>"; };
4018B1C41CDC277F00F666AF /* MGLAnnotationView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLAnnotationView.mm; sourceTree = "<group>"; };
4018B1C51CDC277F00F666AF /* MGLAnnotationView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLAnnotationView.h; sourceTree = "<group>"; };
@@ -589,6 +566,9 @@
404C26E11D89B877000AA13D /* MGLTileSet.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLTileSet.mm; sourceTree = "<group>"; };
404C26E61D89C515000AA13D /* MGLTileSet_Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLTileSet_Private.h; sourceTree = "<group>"; };
4085AF081D933DEA00F11B22 /* MGLTileSetTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLTileSetTests.mm; sourceTree = "<group>"; };
+ 408AA8551DAEDA0800022900 /* NSDictionary+MGLAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+MGLAdditions.h"; sourceTree = "<group>"; };
+ 408AA8561DAEDA0800022900 /* NSDictionary+MGLAdditions.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSDictionary+MGLAdditions.mm"; sourceTree = "<group>"; };
+ 40CF6DBA1DAC3C1800A4D18B /* MGLShape_Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLShape_Private.h; sourceTree = "<group>"; };
40CFA6501D787579008103BD /* MGLGeoJSONSourceTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLGeoJSONSourceTests.mm; sourceTree = "<group>"; };
40EDA1BD1CFE0D4A00D9EA68 /* MGLAnnotationContainerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLAnnotationContainerView.h; sourceTree = "<group>"; };
40EDA1BE1CFE0D4A00D9EA68 /* MGLAnnotationContainerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLAnnotationContainerView.m; sourceTree = "<group>"; };
@@ -598,6 +578,10 @@
554180411D2E97DE00012372 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
55D8C9941D0F133500F42F10 /* config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = config.xcconfig; path = ../../build/ios/config.xcconfig; sourceTree = "<group>"; };
55D8C9951D0F18CE00F42F10 /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; };
+ 7E016D7C1D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MGLPolyline+MGLAdditions.h"; sourceTree = "<group>"; };
+ 7E016D7D1D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MGLPolyline+MGLAdditions.m"; sourceTree = "<group>"; };
+ 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>"; };
DA0CD58F1CF56F6A00A5F5A5 /* MGLFeatureTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLFeatureTests.mm; path = ../../darwin/test/MGLFeatureTests.mm; sourceTree = "<group>"; };
DA17BE2F1CC4BAC300402C41 /* MGLMapView_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLMapView_Private.h; sourceTree = "<group>"; };
DA1DC94A1CB6C1C2006E619F /* Mapbox GL.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Mapbox GL.app"; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -642,6 +626,8 @@
DA35A2C81CCAAAD200E826B2 /* NSValue+MGLAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSValue+MGLAdditions.m"; sourceTree = "<group>"; };
DA35A2D11CCAB25200E826B2 /* jazzy.yml */ = {isa = PBXFileReference; lastKnownFileType = text; path = jazzy.yml; sourceTree = "<group>"; };
DA4A26961CB6E795000B7809 /* Mapbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Mapbox.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ DA6408D91DA4E7D300908C90 /* MGLVectorStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLVectorStyleLayer.h; sourceTree = "<group>"; };
+ DA6408DA1DA4E7D300908C90 /* MGLVectorStyleLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLVectorStyleLayer.m; sourceTree = "<group>"; };
DA737EE01D056A4E005BDA16 /* MGLMapViewDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLMapViewDelegate.h; sourceTree = "<group>"; };
DA821D041CCC6D59007508D4 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; };
DA821D051CCC6D59007508D4 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = "<group>"; };
@@ -675,10 +661,10 @@
DA8848081CBAFA6200AB86E3 /* MGLOfflineRegion_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLOfflineRegion_Private.h; sourceTree = "<group>"; };
DA8848091CBAFA6200AB86E3 /* MGLOfflineStorage_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLOfflineStorage_Private.h; sourceTree = "<group>"; };
DA88480A1CBAFA6200AB86E3 /* MGLOfflineStorage.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLOfflineStorage.mm; sourceTree = "<group>"; };
- DA88480B1CBAFA6200AB86E3 /* MGLPointAnnotation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLPointAnnotation.m; sourceTree = "<group>"; };
+ DA88480B1CBAFA6200AB86E3 /* MGLPointAnnotation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLPointAnnotation.mm; sourceTree = "<group>"; };
DA88480C1CBAFA6200AB86E3 /* MGLPolygon.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLPolygon.mm; sourceTree = "<group>"; };
DA88480D1CBAFA6200AB86E3 /* MGLPolyline.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLPolyline.mm; sourceTree = "<group>"; };
- DA88480E1CBAFA6200AB86E3 /* MGLShape.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLShape.m; sourceTree = "<group>"; };
+ DA88480E1CBAFA6200AB86E3 /* MGLShape.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLShape.mm; sourceTree = "<group>"; };
DA88480F1CBAFA6200AB86E3 /* MGLStyle.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLStyle.mm; sourceTree = "<group>"; };
DA8848101CBAFA6200AB86E3 /* MGLTilePyramidOfflineRegion.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLTilePyramidOfflineRegion.mm; sourceTree = "<group>"; };
DA8848111CBAFA6200AB86E3 /* MGLTypes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLTypes.m; sourceTree = "<group>"; };
@@ -749,6 +735,8 @@
DAA4E4061CBB5CBF00178DFB /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
DAA4E4131CBB71D400178DFB /* libMapbox.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libMapbox.a; sourceTree = BUILT_PRODUCTS_DIR; };
DAABF73B1CBC59BB005B1825 /* libmbgl-core.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libmbgl-core.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+ DAAF72291DA903C700312FA4 /* MGLStyleValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleValue.h; sourceTree = "<group>"; };
+ DAAF722A1DA903C700312FA4 /* MGLStyleValue_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleValue_Private.h; sourceTree = "<group>"; };
DABCABA81CB80692000A7C39 /* Bench GL.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Bench GL.app"; sourceTree = BUILT_PRODUCTS_DIR; };
DABCABAB1CB80692000A7C39 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
DABCABAD1CB80692000A7C39 /* MBXBenchAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MBXBenchAppDelegate.h; sourceTree = "<group>"; };
@@ -775,6 +763,8 @@
DD01C6631DA6DC0D00ABCAC7 /* left.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = left.jpg; sourceTree = "<group>"; };
DD01C6641DA6DC0D00ABCAC7 /* right.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = right.jpg; sourceTree = "<group>"; };
DD01C6651DA6DC0D00ABCAC7 /* top.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = top.jpg; sourceTree = "<group>"; };
+ DD0902A21DB18DE700C5BDCE /* MGLNetworkConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLNetworkConfiguration.m; sourceTree = "<group>"; };
+ DD0902A41DB18F1B00C5BDCE /* MGLNetworkConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLNetworkConfiguration.h; sourceTree = "<group>"; };
DD4823721D94AE6C00EB71B7 /* fill_filter_style.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = fill_filter_style.json; sourceTree = "<group>"; };
DD4823731D94AE6C00EB71B7 /* line_filter_style.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = line_filter_style.json; sourceTree = "<group>"; };
DD4823741D94AE6C00EB71B7 /* numeric_filter_style.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = numeric_filter_style.json; sourceTree = "<group>"; };
@@ -859,6 +849,8 @@
35136D3B1D42272500C20EFD /* MGLCircleStyleLayer.mm */,
35D13AC11D3D19DD00AFB4E0 /* MGLFillStyleLayer.h */,
35D13AC21D3D19DD00AFB4E0 /* MGLFillStyleLayer.mm */,
+ 3538AA1B1D542239008EC33D /* MGLForegroundStyleLayer.h */,
+ 3538AA1C1D542239008EC33D /* MGLForegroundStyleLayer.m */,
353933F71D3FB79F003F57D7 /* MGLLineStyleLayer.h */,
35136D3E1D42273000C20EFD /* MGLLineStyleLayer.mm */,
353933FA1D3FB7C0003F57D7 /* MGLRasterStyleLayer.h */,
@@ -868,8 +860,8 @@
35D13AB61D3D15E300AFB4E0 /* MGLStyleLayer.mm */,
353933FD1D3FB7DD003F57D7 /* MGLSymbolStyleLayer.h */,
35136D441D42275100C20EFD /* MGLSymbolStyleLayer.mm */,
- 3538AA1B1D542239008EC33D /* MGLBaseStyleLayer.h */,
- 3538AA1C1D542239008EC33D /* MGLBaseStyleLayer.mm */,
+ DA6408D91DA4E7D300908C90 /* MGLVectorStyleLayer.h */,
+ DA6408DA1DA4E7D300908C90 /* MGLVectorStyleLayer.m */,
);
name = Layers;
sourceTree = "<group>";
@@ -880,13 +872,9 @@
35599DB81D46AD7F0048254D /* Categories */,
353933F01D3FB6BA003F57D7 /* Layers */,
35136D491D4277EA00C20EFD /* Sources */,
- 35599DE91D46F14E0048254D /* MGLStyleAttributeFunction.h */,
- 3534C7911D4BC95400D874A4 /* MGLStyleAttributeFunction_Private.h */,
- 35599DEA1D46F14E0048254D /* MGLStyleAttributeFunction.mm */,
- 35599DEF1D46F3A60048254D /* MGLStyleAttributeValue.h */,
- 3534C7941D4BD1D400D874A4 /* MGLStyleAttributeValue_Private.h */,
- 3593E51F1D529C29006D9365 /* MGLStyleAttribute.h */,
- 3593E5201D529C29006D9365 /* MGLStyleAttribute.mm */,
+ DAAF72291DA903C700312FA4 /* MGLStyleValue.h */,
+ DAAF722A1DA903C700312FA4 /* MGLStyleValue_Private.h */,
+ 35599DEA1D46F14E0048254D /* MGLStyleValue.mm */,
);
name = Styling;
sourceTree = "<group>";
@@ -894,20 +882,7 @@
35599DB81D46AD7F0048254D /* Categories */ = {
isa = PBXGroup;
children = (
- 350098AD1D47E6F4004B2AF0 /* UIColor+MGLStyleAttributeAdditions.h */,
- 3593E5251D529EDC006D9365 /* UIColor+MGLStyleAttributeAdditions_Private.h */,
- 350098AE1D47E6F4004B2AF0 /* UIColor+MGLStyleAttributeAdditions.mm */,
- 350098BF1D48149E004B2AF0 /* NSNumber+MGLStyleAttributeAdditions.h */,
- 350098C51D48288B004B2AF0 /* NSNumber+MGLStyleAttributeAdditions_Private.h */,
- 350098C01D48149E004B2AF0 /* NSNumber+MGLStyleAttributeAdditions.mm */,
- 350098C81D482D9C004B2AF0 /* NSArray+MGLStyleAttributeAdditions.h */,
- 350098CE1D482E10004B2AF0 /* NSArray+MGLStyleAttributeAdditions_Private.h */,
- 350098C91D482D9C004B2AF0 /* NSArray+MGLStyleAttributeAdditions.mm */,
- 350098D11D4830A6004B2AF0 /* NSString+MGLStyleAttributeAdditions.h */,
- 350098D71D4830D5004B2AF0 /* NSString+MGLStyleAttributeAdditions_Private.h */,
- 350098D21D4830A6004B2AF0 /* NSString+MGLStyleAttributeAdditions.mm */,
350098DA1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.h */,
- 354D42DB1D4919F900F400A1 /* NSValue+MGLStyleAttributeAdditions_Private.h */,
350098DB1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.mm */,
);
name = Categories;
@@ -945,6 +920,8 @@
children = (
35CE61801D4165D9004F2359 /* UIColor+MGLAdditions.h */,
35CE61811D4165D9004F2359 /* UIColor+MGLAdditions.mm */,
+ 30E578111DAA7D690050F07E /* UIImage+MGLAdditions.h */,
+ 30E578121DAA7D690050F07E /* UIImage+MGLAdditions.mm */,
);
name = Categories;
sourceTree = "<group>";
@@ -1113,6 +1090,8 @@
DA8847DF1CBAFA5100AB86E3 /* MGLAccountManager.h */,
DA8847FF1CBAFA6200AB86E3 /* MGLAccountManager_Private.h */,
DA8848001CBAFA6200AB86E3 /* MGLAccountManager.m */,
+ DD0902A41DB18F1B00C5BDCE /* MGLNetworkConfiguration.h */,
+ DD0902A21DB18DE700C5BDCE /* MGLNetworkConfiguration.m */,
DA8847E21CBAFA5100AB86E3 /* MGLMapCamera.h */,
DA8848031CBAFA6200AB86E3 /* MGLMapCamera.mm */,
DA8847EC1CBAFA5100AB86E3 /* MGLStyle.h */,
@@ -1298,13 +1277,14 @@
DA8848051CBAFA6200AB86E3 /* MGLMultiPoint.mm */,
DA8847E71CBAFA5100AB86E3 /* MGLOverlay.h */,
DA8847E81CBAFA5100AB86E3 /* MGLPointAnnotation.h */,
- DA88480B1CBAFA6200AB86E3 /* MGLPointAnnotation.m */,
+ DA88480B1CBAFA6200AB86E3 /* MGLPointAnnotation.mm */,
DA8847E91CBAFA5100AB86E3 /* MGLPolygon.h */,
DA88480C1CBAFA6200AB86E3 /* MGLPolygon.mm */,
DA8847EA1CBAFA5100AB86E3 /* MGLPolyline.h */,
DA88480D1CBAFA6200AB86E3 /* MGLPolyline.mm */,
DA8847EB1CBAFA5100AB86E3 /* MGLShape.h */,
- DA88480E1CBAFA6200AB86E3 /* MGLShape.m */,
+ 40CF6DBA1DAC3C1800A4D18B /* MGLShape_Private.h */,
+ DA88480E1CBAFA6200AB86E3 /* MGLShape.mm */,
DAD165761CF4CDFF001FF4B9 /* MGLShapeCollection.h */,
DAD165771CF4CDFF001FF4B9 /* MGLShapeCollection.m */,
);
@@ -1331,13 +1311,29 @@
DAD165831CF4CFED001FF4B9 /* Categories */ = {
isa = PBXGroup;
children = (
- 353AFA121D65AB17005A69F4 /* NSDate+MGLAdditions.h */,
- 353AFA131D65AB17005A69F4 /* NSDate+MGLAdditions.mm */,
+ 7E016D821D9E890300A29A21 /* MGLPolygon+MGLAdditions.h */,
+ 7E016D831D9E890300A29A21 /* MGLPolygon+MGLAdditions.m */,
+ 7E016D7C1D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.h */,
+ 7E016D7D1D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.m */,
+ 400532FF1DB0862B0069F638 /* NSArray+MGLAdditions.h */,
+ 400533001DB0862B0069F638 /* NSArray+MGLAdditions.mm */,
DA8848121CBAFA6200AB86E3 /* NSBundle+MGLAdditions.h */,
DA8848131CBAFA6200AB86E3 /* NSBundle+MGLAdditions.m */,
+ 3510FFE81D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.h */,
+ 3510FFE91D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.mm */,
+ 3510FFF71D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.h */,
+ 3510FFF81D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.mm */,
35305D461D22AA450007D005 /* NSData+MGLAdditions.h */,
35305D471D22AA450007D005 /* NSData+MGLAdditions.mm */,
+ 353AFA121D65AB17005A69F4 /* NSDate+MGLAdditions.h */,
+ 353AFA131D65AB17005A69F4 /* NSDate+MGLAdditions.mm */,
+ 408AA8551DAEDA0800022900 /* NSDictionary+MGLAdditions.h */,
+ 408AA8561DAEDA0800022900 /* NSDictionary+MGLAdditions.mm */,
DA8848141CBAFA6200AB86E3 /* NSException+MGLAdditions.h */,
+ 3510FFEE1D6D9D8C00F413B2 /* NSExpression+MGLAdditions.h */,
+ 3510FFEF1D6D9D8C00F413B2 /* NSExpression+MGLAdditions.mm */,
+ 35B82BF61D6C5F8400B1B721 /* NSPredicate+MGLAdditions.h */,
+ 35B82BF71D6C5F8400B1B721 /* NSPredicate+MGLAdditions.mm */,
DA8848151CBAFA6200AB86E3 /* NSProcessInfo+MGLAdditions.h */,
DA8848161CBAFA6200AB86E3 /* NSProcessInfo+MGLAdditions.m */,
DA8848171CBAFA6200AB86E3 /* NSString+MGLAdditions.h */,
@@ -1346,14 +1342,6 @@
DAED38621D62D0FC00D7640F /* NSURL+MGLAdditions.m */,
DA35A2C71CCAAAD200E826B2 /* NSValue+MGLAdditions.h */,
DA35A2C81CCAAAD200E826B2 /* NSValue+MGLAdditions.m */,
- 35B82BF61D6C5F8400B1B721 /* NSPredicate+MGLAdditions.h */,
- 35B82BF71D6C5F8400B1B721 /* NSPredicate+MGLAdditions.mm */,
- 3510FFE81D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.h */,
- 3510FFE91D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.mm */,
- 3510FFEE1D6D9D8C00F413B2 /* NSExpression+MGLAdditions.h */,
- 3510FFEF1D6D9D8C00F413B2 /* NSExpression+MGLAdditions.mm */,
- 3510FFF71D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.h */,
- 3510FFF81D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.mm */,
);
name = Categories;
sourceTree = "<group>";
@@ -1427,13 +1415,11 @@
DA8848201CBAFA6200AB86E3 /* MGLOfflinePack_Private.h in Headers */,
DA8847FA1CBAFA5100AB86E3 /* MGLPolyline.h in Headers */,
3566C7711D4A9198008152BC /* MGLSource_Private.h in Headers */,
- 3593E5211D529C29006D9365 /* MGLStyleAttribute.h in Headers */,
- 35599DEB1D46F14E0048254D /* MGLStyleAttributeFunction.h in Headers */,
4018B1C91CDC288A00F666AF /* MGLAnnotationView_Private.h in Headers */,
35E1A4D81D74336F007AA97F /* MGLValueEvaluator.h in Headers */,
DA88482C1CBAFA6200AB86E3 /* NSBundle+MGLAdditions.h in Headers */,
+ 7E016D7E1D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.h in Headers */,
35D13AB71D3D15E300AFB4E0 /* MGLStyleLayer.h in Headers */,
- 354D42DC1D4919F900F400A1 /* NSValue+MGLStyleAttributeAdditions_Private.h in Headers */,
DA88488E1CBB047F00AB86E3 /* reachability.h in Headers */,
40F887701D7A1E58008ECB67 /* MGLGeoJSONSource_Private.h in Headers */,
350098DC1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.h in Headers */,
@@ -1443,8 +1429,6 @@
35E0CFE61D3E501500188327 /* MGLStyle_Private.h in Headers */,
3510FFF01D6D9D8C00F413B2 /* NSExpression+MGLAdditions.h in Headers */,
353AFA141D65AB17005A69F4 /* NSDate+MGLAdditions.h in Headers */,
- 3593E5261D529EDC006D9365 /* UIColor+MGLStyleAttributeAdditions_Private.h in Headers */,
- 35599DF01D46F3A60048254D /* MGLStyleAttributeValue.h in Headers */,
DA8848531CBAFB9800AB86E3 /* MGLCompactCalloutView.h in Headers */,
DA8847FB1CBAFA5100AB86E3 /* MGLShape.h in Headers */,
353933F51D3FB785003F57D7 /* MGLBackgroundStyleLayer.h in Headers */,
@@ -1453,23 +1437,27 @@
DA8847FC1CBAFA5100AB86E3 /* MGLStyle.h in Headers */,
354B83961D2E873E005D9406 /* MGLUserLocationAnnotationView.h in Headers */,
DA8847F01CBAFA5100AB86E3 /* MGLAnnotation.h in Headers */,
+ 7E016D841D9E890300A29A21 /* MGLPolygon+MGLAdditions.h in Headers */,
+ 400533011DB0862B0069F638 /* NSArray+MGLAdditions.h in Headers */,
DA88483E1CBAFB8500AB86E3 /* MGLMapView+MGLCustomStyleLayerAdditions.h in Headers */,
+ 40CF6DBB1DAC3C6600A4D18B /* MGLShape_Private.h in Headers */,
4018B1CA1CDC288E00F666AF /* MGLAnnotationView.h in Headers */,
- 350098C61D48288B004B2AF0 /* NSNumber+MGLStyleAttributeAdditions_Private.h in Headers */,
35E79F201D41266300957B9E /* MGLStyleLayer_Private.h in Headers */,
353933FB1D3FB7C0003F57D7 /* MGLRasterStyleLayer.h in Headers */,
DA8847EF1CBAFA5100AB86E3 /* MGLAccountManager.h in Headers */,
DA8848511CBAFB9800AB86E3 /* MGLAPIClient.h in Headers */,
DA35A2C91CCAAAD200E826B2 /* NSValue+MGLAdditions.h in Headers */,
- 350098CF1D482E10004B2AF0 /* NSArray+MGLStyleAttributeAdditions_Private.h in Headers */,
3510FFEA1D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.h in Headers */,
+ DA6408DB1DA4E7D300908C90 /* MGLVectorStyleLayer.h in Headers */,
+ DD0902AB1DB192A800C5BDCE /* MGLNetworkConfiguration.h in Headers */,
DA8848571CBAFB9800AB86E3 /* MGLMapboxEvents.h in Headers */,
DA8848311CBAFA6200AB86E3 /* NSString+MGLAdditions.h in Headers */,
353933F81D3FB79F003F57D7 /* MGLLineStyleLayer.h in Headers */,
+ DAAF722D1DA903C700312FA4 /* MGLStyleValue_Private.h in Headers */,
DA8847F41CBAFA5100AB86E3 /* MGLOfflinePack.h in Headers */,
DA88482E1CBAFA6200AB86E3 /* NSException+MGLAdditions.h in Headers */,
DA8848551CBAFB9800AB86E3 /* MGLLocationManager.h in Headers */,
- 350098C11D48149E004B2AF0 /* NSNumber+MGLStyleAttributeAdditions.h in Headers */,
+ 408AA8571DAEDA1700022900 /* NSDictionary+MGLAdditions.h in Headers */,
DA88483F1CBAFB8500AB86E3 /* MGLUserLocation.h in Headers */,
DA88483D1CBAFB8500AB86E3 /* MGLMapView+IBAdditions.h in Headers */,
DA17BE301CC4BAC300402C41 /* MGLMapView_Private.h in Headers */,
@@ -1480,9 +1468,9 @@
35CE61821D4165D9004F2359 /* UIColor+MGLAdditions.h in Headers */,
35B82BF81D6C5F8400B1B721 /* NSPredicate+MGLAdditions.h in Headers */,
DA35A29E1CC9E94C00E826B2 /* MGLCoordinateFormatter.h in Headers */,
+ DAAF722B1DA903C700312FA4 /* MGLStyleValue.h in Headers */,
DA8847F71CBAFA5100AB86E3 /* MGLOverlay.h in Headers */,
DA35A2B11CCA141D00E826B2 /* MGLCompassDirectionFormatter.h in Headers */,
- 350098D31D4830A6004B2AF0 /* NSString+MGLStyleAttributeAdditions.h in Headers */,
DA88488B1CBB037E00AB86E3 /* SMCalloutView.h in Headers */,
DA8847FE1CBAFA5100AB86E3 /* MGLTypes.h in Headers */,
DA8847F11CBAFA5100AB86E3 /* MGLGeometry.h in Headers */,
@@ -1493,23 +1481,20 @@
DA8847F81CBAFA5100AB86E3 /* MGLPointAnnotation.h in Headers */,
353933F21D3FB753003F57D7 /* MGLCircleStyleLayer.h in Headers */,
DA8847F31CBAFA5100AB86E3 /* MGLMultiPoint.h in Headers */,
+ 30E578171DAA85520050F07E /* UIImage+MGLAdditions.h in Headers */,
DAD1656C1CF41981001FF4B9 /* MGLFeature.h in Headers */,
40EDA1C01CFE0E0200D9EA68 /* MGLAnnotationContainerView.h in Headers */,
DA88484F1CBAFB9800AB86E3 /* MGLAnnotationImage_Private.h in Headers */,
- 3534C7921D4BC95400D874A4 /* MGLStyleAttributeFunction_Private.h in Headers */,
DA8847F21CBAFA5100AB86E3 /* MGLMapCamera.h in Headers */,
- 3538AA1D1D542239008EC33D /* MGLBaseStyleLayer.h in Headers */,
+ 3538AA1D1D542239008EC33D /* MGLForegroundStyleLayer.h in Headers */,
DA8847F51CBAFA5100AB86E3 /* MGLOfflineRegion.h in Headers */,
DA737EE11D056A4E005BDA16 /* MGLMapViewDelegate.h in Headers */,
DA8848851CBB033F00AB86E3 /* FABKitProtocol.h in Headers */,
DA88481B1CBAFA6200AB86E3 /* MGLGeometry_Private.h in Headers */,
- 350098CA1D482D9C004B2AF0 /* NSArray+MGLStyleAttributeAdditions.h in Headers */,
- 350098AF1D47E6F4004B2AF0 /* UIColor+MGLStyleAttributeAdditions.h in Headers */,
3510FFF91D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.h in Headers */,
404C26E71D89C55D000AA13D /* MGLTileSet_Private.h in Headers */,
DA88485C1CBAFB9800AB86E3 /* MGLFaux3DUserLocationAnnotationView.h in Headers */,
DA8848871CBB033F00AB86E3 /* Fabric.h in Headers */,
- 350098D81D4830D5004B2AF0 /* NSString+MGLStyleAttributeAdditions_Private.h in Headers */,
35305D4A1D22AA6A0007D005 /* NSData+MGLAdditions.h in Headers */,
359F57461D2FDDA6005217F1 /* MGLUserLocationAnnotationView_Private.h in Headers */,
404C26E21D89B877000AA13D /* MGLTileSet.h in Headers */,
@@ -1518,7 +1503,6 @@
DA88482F1CBAFA6200AB86E3 /* NSProcessInfo+MGLAdditions.h in Headers */,
DA8848601CBAFC2E00AB86E3 /* Mapbox.h in Headers */,
350098BB1D480108004B2AF0 /* MGLVectorSource.h in Headers */,
- 3534C7951D4BD1D400D874A4 /* MGLStyleAttributeValue_Private.h in Headers */,
DA8847F61CBAFA5100AB86E3 /* MGLOfflineStorage.h in Headers */,
DAD1656E1CF41981001FF4B9 /* MGLFeature_Private.h in Headers */,
DA88483C1CBAFB8500AB86E3 /* MGLMapView.h in Headers */,
@@ -1535,12 +1519,9 @@
353933FC1D3FB7C0003F57D7 /* MGLRasterStyleLayer.h in Headers */,
3566C76D1D4A8DFA008152BC /* MGLRasterSource.h in Headers */,
DAED38641D62D0FC00D7640F /* NSURL+MGLAdditions.h in Headers */,
- 35599DEC1D46F14E0048254D /* MGLStyleAttributeFunction.h in Headers */,
DABFB85E1CBE99E500D62B32 /* MGLAnnotation.h in Headers */,
- 350098D01D482E10004B2AF0 /* NSArray+MGLStyleAttributeAdditions_Private.h in Headers */,
DABFB8641CBE99E500D62B32 /* MGLOfflineStorage.h in Headers */,
DAD165791CF4CDFF001FF4B9 /* MGLShapeCollection.h in Headers */,
- 350098D41D4830A6004B2AF0 /* NSString+MGLStyleAttributeAdditions.h in Headers */,
3566C7671D4A77BA008152BC /* MGLGeoJSONSource.h in Headers */,
DA35A29F1CC9E94C00E826B2 /* MGLCoordinateFormatter.h in Headers */,
DABFB8711CBE9A0F00D62B32 /* MGLMapView+MGLCustomStyleLayerAdditions.h in Headers */,
@@ -1552,37 +1533,32 @@
DABFB8721CBE9A0F00D62B32 /* MGLUserLocation.h in Headers */,
3566C7721D4A9198008152BC /* MGLSource_Private.h in Headers */,
353933FF1D3FB7DD003F57D7 /* MGLSymbolStyleLayer.h in Headers */,
+ DAAF722E1DA903C700312FA4 /* MGLStyleValue_Private.h in Headers */,
DABFB8661CBE99E500D62B32 /* MGLPointAnnotation.h in Headers */,
- 35599DF11D46F3A60048254D /* MGLStyleAttributeValue.h in Headers */,
DABFB8621CBE99E500D62B32 /* MGLOfflinePack.h in Headers */,
DAD1656D1CF41981001FF4B9 /* MGLFeature.h in Headers */,
DA17BE311CC4BDAA00402C41 /* MGLMapView_Private.h in Headers */,
DABFB86C1CBE99E500D62B32 /* MGLTypes.h in Headers */,
- 350098C21D48149E004B2AF0 /* NSNumber+MGLStyleAttributeAdditions.h in Headers */,
DABFB8691CBE99E500D62B32 /* MGLShape.h in Headers */,
- 350098CB1D482D9C004B2AF0 /* NSArray+MGLStyleAttributeAdditions.h in Headers */,
3510FFEB1D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.h in Headers */,
35E1A4D91D74336F007AA97F /* MGLValueEvaluator.h in Headers */,
+ 7E016D7F1D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.h in Headers */,
DABFB8701CBE9A0F00D62B32 /* MGLMapView+IBAdditions.h in Headers */,
353AFA151D65AB17005A69F4 /* NSDate+MGLAdditions.h in Headers */,
- 350098D91D4830D5004B2AF0 /* NSString+MGLStyleAttributeAdditions_Private.h in Headers */,
3510FFFA1D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.h in Headers */,
35CE61831D4165D9004F2359 /* UIColor+MGLAdditions.h in Headers */,
- 350098B01D47E6F4004B2AF0 /* UIColor+MGLStyleAttributeAdditions.h in Headers */,
DABFB8671CBE99E500D62B32 /* MGLPolygon.h in Headers */,
- 350098C71D48288B004B2AF0 /* NSNumber+MGLStyleAttributeAdditions_Private.h in Headers */,
404C26E81D89C55D000AA13D /* MGLTileSet_Private.h in Headers */,
- 3593E5221D529C29006D9365 /* MGLStyleAttribute.h in Headers */,
+ DAAF722C1DA903C700312FA4 /* MGLStyleValue.h in Headers */,
DABFB8651CBE99E500D62B32 /* MGLOverlay.h in Headers */,
35E79F211D41266300957B9E /* MGLStyleLayer_Private.h in Headers */,
350098DD1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.h in Headers */,
- 3534C7961D4BD1D400D874A4 /* MGLStyleAttributeValue_Private.h in Headers */,
DABFB8681CBE99E500D62B32 /* MGLPolyline.h in Headers */,
- 3534C7931D4BC95400D874A4 /* MGLStyleAttributeFunction_Private.h in Headers */,
DABFB86F1CBE9A0F00D62B32 /* MGLMapView.h in Headers */,
+ DA6408DC1DA4E7D300908C90 /* MGLVectorStyleLayer.h in Headers */,
353933F31D3FB753003F57D7 /* MGLCircleStyleLayer.h in Headers */,
- 3593E5271D529EDC006D9365 /* UIColor+MGLStyleAttributeAdditions_Private.h in Headers */,
- 3538AA1E1D542239008EC33D /* MGLBaseStyleLayer.h in Headers */,
+ 3538AA1E1D542239008EC33D /* MGLForegroundStyleLayer.h in Headers */,
+ 30E578181DAA85520050F07E /* UIImage+MGLAdditions.h in Headers */,
40F887711D7A1E59008ECB67 /* MGLGeoJSONSource_Private.h in Headers */,
DABFB8631CBE99E500D62B32 /* MGLOfflineRegion.h in Headers */,
DA35A2B21CCA141D00E826B2 /* MGLCompassDirectionFormatter.h in Headers */,
@@ -1591,7 +1567,7 @@
DABFB86B1CBE99E500D62B32 /* MGLTilePyramidOfflineRegion.h in Headers */,
4018B1CB1CDC288E00F666AF /* MGLAnnotationView.h in Headers */,
DABFB85F1CBE99E500D62B32 /* MGLGeometry.h in Headers */,
- 354D42DD1D4919F900F400A1 /* NSValue+MGLStyleAttributeAdditions_Private.h in Headers */,
+ 7E016D851D9E890300A29A21 /* MGLPolygon+MGLAdditions.h in Headers */,
353933F61D3FB785003F57D7 /* MGLBackgroundStyleLayer.h in Headers */,
DABFB85D1CBE99E500D62B32 /* MGLAccountManager.h in Headers */,
353933F91D3FB79F003F57D7 /* MGLLineStyleLayer.h in Headers */,
@@ -1948,22 +1924,22 @@
files = (
35136D391D42271A00C20EFD /* MGLBackgroundStyleLayer.mm in Sources */,
3510FFEC1D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.mm in Sources */,
- 350098D51D4830A6004B2AF0 /* NSString+MGLStyleAttributeAdditions.mm in Sources */,
- 3593E5231D529C29006D9365 /* MGLStyleAttribute.mm in Sources */,
- 350098B11D47E6F4004B2AF0 /* UIColor+MGLStyleAttributeAdditions.mm in Sources */,
+ 7E016D801D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.m in Sources */,
DAED38651D62D0FC00D7640F /* NSURL+MGLAdditions.m in Sources */,
354B83981D2E873E005D9406 /* MGLUserLocationAnnotationView.m in Sources */,
DA88485D1CBAFB9800AB86E3 /* MGLFaux3DUserLocationAnnotationView.m in Sources */,
DAD165701CF41981001FF4B9 /* MGLFeature.mm in Sources */,
- 350098C31D48149E004B2AF0 /* NSNumber+MGLStyleAttributeAdditions.mm in Sources */,
+ 30E578191DAA855E0050F07E /* UIImage+MGLAdditions.mm in Sources */,
40EDA1C11CFE0E0500D9EA68 /* MGLAnnotationContainerView.m in Sources */,
DA8848541CBAFB9800AB86E3 /* MGLCompactCalloutView.m in Sources */,
- DA8848251CBAFA6200AB86E3 /* MGLPointAnnotation.m in Sources */,
+ DA8848251CBAFA6200AB86E3 /* MGLPointAnnotation.mm in Sources */,
35136D3C1D42272500C20EFD /* MGLCircleStyleLayer.mm in Sources */,
350098DE1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.mm in Sources */,
+ DA6408DD1DA4E7D300908C90 /* MGLVectorStyleLayer.m in Sources */,
3566C7681D4A77BA008152BC /* MGLGeoJSONSource.mm in Sources */,
+ 400533021DB0862B0069F638 /* NSArray+MGLAdditions.mm in Sources */,
35136D421D42274500C20EFD /* MGLRasterStyleLayer.mm in Sources */,
- 3538AA1F1D542239008EC33D /* MGLBaseStyleLayer.mm in Sources */,
+ 3538AA1F1D542239008EC33D /* MGLForegroundStyleLayer.m in Sources */,
DA88482D1CBAFA6200AB86E3 /* NSBundle+MGLAdditions.m in Sources */,
DA88485B1CBAFB9800AB86E3 /* MGLUserLocation.m in Sources */,
350098BD1D480108004B2AF0 /* MGLVectorSource.mm in Sources */,
@@ -1972,17 +1948,18 @@
35136D4E1D4277FC00C20EFD /* MGLSource.mm in Sources */,
DA35A2B81CCA9A5D00E826B2 /* MGLClockDirectionFormatter.m in Sources */,
DAD1657A1CF4CDFF001FF4B9 /* MGLShapeCollection.m in Sources */,
- 350098CC1D482D9C004B2AF0 /* NSArray+MGLStyleAttributeAdditions.mm in Sources */,
35136D451D42275100C20EFD /* MGLSymbolStyleLayer.mm in Sources */,
- 35599DED1D46F14E0048254D /* MGLStyleAttributeFunction.mm in Sources */,
+ 35599DED1D46F14E0048254D /* MGLStyleValue.mm in Sources */,
DA8848211CBAFA6200AB86E3 /* MGLOfflinePack.mm in Sources */,
DA8848591CBAFB9800AB86E3 /* MGLMapView.mm in Sources */,
DA8848501CBAFB9800AB86E3 /* MGLAnnotationImage.m in Sources */,
- DA8848281CBAFA6200AB86E3 /* MGLShape.m in Sources */,
+ DA8848281CBAFA6200AB86E3 /* MGLShape.mm in Sources */,
DA35A2B31CCA141D00E826B2 /* MGLCompassDirectionFormatter.m in Sources */,
+ DD0902A91DB1929D00C5BDCE /* MGLNetworkConfiguration.m in Sources */,
35D13AB91D3D15E300AFB4E0 /* MGLStyleLayer.mm in Sources */,
DA35A2CB1CCAAAD200E826B2 /* NSValue+MGLAdditions.m in Sources */,
DA8848321CBAFA6200AB86E3 /* NSString+MGLAdditions.m in Sources */,
+ 408AA8581DAEDA1E00022900 /* NSDictionary+MGLAdditions.mm in Sources */,
DA35A2A11CC9E95F00E826B2 /* MGLCoordinateFormatter.m in Sources */,
35305D481D22AA680007D005 /* NSData+MGLAdditions.mm in Sources */,
DA8848291CBAFA6200AB86E3 /* MGLStyle.mm in Sources */,
@@ -1995,6 +1972,7 @@
DA88481D1CBAFA6200AB86E3 /* MGLMapCamera.mm in Sources */,
DA8848261CBAFA6200AB86E3 /* MGLPolygon.mm in Sources */,
35B82BFA1D6C5F8400B1B721 /* NSPredicate+MGLAdditions.mm in Sources */,
+ 7E016D861D9E890300A29A21 /* MGLPolygon+MGLAdditions.m in Sources */,
DA8848521CBAFB9800AB86E3 /* MGLAPIClient.m in Sources */,
DA8848301CBAFA6200AB86E3 /* NSProcessInfo+MGLAdditions.m in Sources */,
353AFA161D65AB17005A69F4 /* NSDate+MGLAdditions.mm in Sources */,
@@ -2017,22 +1995,22 @@
files = (
35136D3A1D42271A00C20EFD /* MGLBackgroundStyleLayer.mm in Sources */,
3510FFED1D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.mm in Sources */,
- 350098D61D4830A6004B2AF0 /* NSString+MGLStyleAttributeAdditions.mm in Sources */,
+ 7E016D811D9E86BE00A29A21 /* MGLPolyline+MGLAdditions.m in Sources */,
354B83991D2E873E005D9406 /* MGLUserLocationAnnotationView.m in Sources */,
- DAA4E4221CBB730400178DFB /* MGLPointAnnotation.m in Sources */,
- 3593E5241D529C29006D9365 /* MGLStyleAttribute.mm in Sources */,
- 350098B21D47E6F4004B2AF0 /* UIColor+MGLStyleAttributeAdditions.mm in Sources */,
+ DAA4E4221CBB730400178DFB /* MGLPointAnnotation.mm in Sources */,
DAED38661D62D0FC00D7640F /* NSURL+MGLAdditions.m in Sources */,
DAD165711CF41981001FF4B9 /* MGLFeature.mm in Sources */,
- 350098C41D48149E004B2AF0 /* NSNumber+MGLStyleAttributeAdditions.mm in Sources */,
+ 30E5781A1DAA855E0050F07E /* UIImage+MGLAdditions.mm in Sources */,
40EDA1C21CFE0E0500D9EA68 /* MGLAnnotationContainerView.m in Sources */,
DAA4E4291CBB730400178DFB /* NSBundle+MGLAdditions.m in Sources */,
DAA4E42E1CBB730400178DFB /* MGLAPIClient.m in Sources */,
35136D3D1D42272500C20EFD /* MGLCircleStyleLayer.mm in Sources */,
350098DF1D484E60004B2AF0 /* NSValue+MGLStyleAttributeAdditions.mm in Sources */,
+ DA6408DE1DA4E7D300908C90 /* MGLVectorStyleLayer.m in Sources */,
3566C7691D4A77BA008152BC /* MGLGeoJSONSource.mm in Sources */,
+ 400533031DB086490069F638 /* NSArray+MGLAdditions.mm in Sources */,
35136D431D42274500C20EFD /* MGLRasterStyleLayer.mm in Sources */,
- 3538AA201D542239008EC33D /* MGLBaseStyleLayer.mm in Sources */,
+ 3538AA201D542239008EC33D /* MGLForegroundStyleLayer.m in Sources */,
DAA4E4201CBB730400178DFB /* MGLOfflinePack.mm in Sources */,
DAA4E4331CBB730400178DFB /* MGLUserLocation.m in Sources */,
350098BE1D480108004B2AF0 /* MGLVectorSource.mm in Sources */,
@@ -2041,17 +2019,18 @@
35136D4F1D4277FC00C20EFD /* MGLSource.mm in Sources */,
DA35A2B91CCA9A5D00E826B2 /* MGLClockDirectionFormatter.m in Sources */,
DAD1657B1CF4CDFF001FF4B9 /* MGLShapeCollection.m in Sources */,
- 350098CD1D482D9C004B2AF0 /* NSArray+MGLStyleAttributeAdditions.mm in Sources */,
- DAA4E4251CBB730400178DFB /* MGLShape.m in Sources */,
+ DAA4E4251CBB730400178DFB /* MGLShape.mm in Sources */,
35136D461D42275100C20EFD /* MGLSymbolStyleLayer.mm in Sources */,
- 35599DEE1D46F14E0048254D /* MGLStyleAttributeFunction.mm in Sources */,
+ 35599DEE1D46F14E0048254D /* MGLStyleValue.mm in Sources */,
DAA4E42B1CBB730400178DFB /* NSString+MGLAdditions.m in Sources */,
DAA4E4261CBB730400178DFB /* MGLStyle.mm in Sources */,
DAA4E41D1CBB730400178DFB /* MGLGeometry.mm in Sources */,
DAA4E41F1CBB730400178DFB /* MGLMultiPoint.mm in Sources */,
+ DD0902AA1DB1929D00C5BDCE /* MGLNetworkConfiguration.m in Sources */,
DA35A2B41CCA141D00E826B2 /* MGLCompassDirectionFormatter.m in Sources */,
35D13ABA1D3D15E300AFB4E0 /* MGLStyleLayer.mm in Sources */,
DA35A2CC1CCAAAD200E826B2 /* NSValue+MGLAdditions.m in Sources */,
+ 408AA8591DAEDA1E00022900 /* NSDictionary+MGLAdditions.mm in Sources */,
DAA4E4281CBB730400178DFB /* MGLTypes.m in Sources */,
DA35A2A21CC9E95F00E826B2 /* MGLCoordinateFormatter.m in Sources */,
35305D491D22AA680007D005 /* NSData+MGLAdditions.mm in Sources */,
@@ -2064,6 +2043,7 @@
4018B1C81CDC287F00F666AF /* MGLAnnotationView.mm in Sources */,
DAA4E4341CBB730400178DFB /* MGLFaux3DUserLocationAnnotationView.m in Sources */,
35B82BFB1D6C5F8400B1B721 /* NSPredicate+MGLAdditions.mm in Sources */,
+ 7E016D871D9E890300A29A21 /* MGLPolygon+MGLAdditions.m in Sources */,
DAA4E4311CBB730400178DFB /* MGLMapboxEvents.m in Sources */,
DAA4E4231CBB730400178DFB /* MGLPolygon.mm in Sources */,
353AFA171D65AB17005A69F4 /* NSDate+MGLAdditions.mm in Sources */,
diff --git a/platform/ios/jazzy.yml b/platform/ios/jazzy.yml
index b2b3d3878e..c41dddc899 100644
--- a/platform/ios/jazzy.yml
+++ b/platform/ios/jazzy.yml
@@ -53,14 +53,15 @@ custom_categories:
- MGLShapeCollectionFeature
- name: Style Layers
children:
- - MGLStyleLayer
- - MGLBaseStyleLayer
- MGLBackgroundStyleLayer
- MGLCircleStyleLayer
- MGLFillStyleLayer
+ - MGLForegroundStyleLayer
- MGLLineStyleLayer
- MGLRasterStyleLayer
+ - MGLStyleLayer
- MGLSymbolStyleLayer
+ - MGLVectorStyleLayer
- name: Data Sources
children:
- MGLSource
diff --git a/platform/ios/scripts/deploy-packages.sh b/platform/ios/scripts/deploy-packages.sh
index 42bce89cf3..51b90a545f 100755
--- a/platform/ios/scripts/deploy-packages.sh
+++ b/platform/ios/scripts/deploy-packages.sh
@@ -4,32 +4,29 @@ set -e
set -o pipefail
set -u
-usage() {
-cat <<EOF
-# Usage: sh $0 version target_directory [argument]
-
-# version: The semver version plus optional alpha beta distinction (i.e. {major.minor.patch}{-alpha.N})
-# target_directory: The directory where build output should be placed
-
-# argument:
-# -g: Upload to github
+# dynamic environment variables:
+# VERSION_TAG={determined automatically}: Version tag in format ios-vX.X.X-pre.X
+# GITHUB_RELEASE=true: Upload to github
+# BINARY_DIRECTORY=build/ios/deploy: Directory in which to save test packages
# environment variables and dependencies:
# - You must run "mbx auth ..." before running
# - Set GITHUB_TOKEN to a GitHub API access token in your environment to use GITHUB_RELEASE
# - "wget" is required for downloading the zip files from s3
-# - The "github-release" gem is required to use GITHUB_RELEASE
-EOF
-}
+# - The "github-release" command is required to use GITHUB_RELEASE
+
+function step { >&2 echo -e "\033[1m\033[36m* $@\033[0m"; }
+function finish { >&2 echo -en "\033[0m"; }
+trap finish EXIT
buildPackageStyle() {
local package=$1 style=""
if [[ ${#} -eq 2 ]]; then
style="$2"
fi
- echo "make ${package} ${style}"
+ step "Building: make ${package} ${style}"
make ${package}
- echo "publish ${package} with ${style}"
+ step "Publishing ${package} with ${style}"
local file_name=""
if [ -z ${style} ]
then
@@ -39,43 +36,78 @@ buildPackageStyle() {
./platform/ios/scripts/publish.sh "${PUBLISH_VERSION}" ${style}
file_name=mapbox-ios-sdk-${PUBLISH_VERSION}-${style}.zip
fi
- echo "Downloading ${file_name} from s3... to ${BINARY_DIRECTORY}"
- wget -P ${BINARY_DIRECTORY} http://mapbox.s3.amazonaws.com/mapbox-gl-native/ios/builds/${file_name}
+ step "Downloading ${file_name} from s3 to ${BINARY_DIRECTORY}"
+ wget -O ${BINARY_DIRECTORY}/${file_name} http://mapbox.s3.amazonaws.com/mapbox-gl-native/ios/builds/${file_name}
if [[ "${GITHUB_RELEASE}" == true ]]; then
- echo "publish ${file_name} to GitHub"
- github-release --verbose upload --tag "ios-v${PUBLISH_VERSION}" --name ${file_name} --file "${BINARY_DIRECTORY}/${file_name}"
+ step "Uploading ${file_name} to GitHub"
+ github-release upload \
+ --tag "ios-v${PUBLISH_VERSION}" \
+ --name ${file_name} \
+ --file "${BINARY_DIRECTORY}/${file_name}"
fi
}
-if [ ${#} -eq 0 -o ${#} -gt 3 ]; then
- usage
- exit 1
-fi
-
export TRAVIS_REPO_SLUG=mapbox-gl-native
-export PUBLISH_VERSION=$1
export GITHUB_USER=mapbox
export GITHUB_REPO=mapbox-gl-native
export BUILDTYPE=Release
-BINARY_DIRECTORY=$2
+VERSION_TAG=${VERSION_TAG:-''}
+PUBLISH_VERSION=
+BINARY_DIRECTORY=${BINARY_DIRECTORY:-build/ios/deploy}
+GITHUB_RELEASE=${GITHUB_RELEASE:-true}
PUBLISH_PRE_FLAG=''
-GITHUB_RELEASE=false
-echo "Deploying version ${PUBLISH_VERSION}..."
+rm -rf ${BINARY_DIRECTORY}
+mkdir -p ${BINARY_DIRECTORY}
+
+if [[ ${GITHUB_RELEASE} = "true" ]]; then
+ GITHUB_RELEASE=true # Assign bool, not just a string
+
+ if [[ -z `which github-release` ]]; then
+ step "Installing github-release…"
+ brew install github-release
+ if [ -z `which github-release` ]; then
+ echo "Unable to install github-release. See: https://github.com/aktau/github-release"
+ exit 1
+ fi
+ fi
+fi
-if [[ ${#} -eq 3 && $3 == "-g" ]]; then
- GITHUB_RELEASE=true
+if [[ -z ${VERSION_TAG} ]]; then
+ step "Determining version number from most recent relevant git tag…"
+ VERSION_TAG=$( git describe --tags --match=ios-v*.*.* --abbrev=0 )
+ echo "Found tag: ${VERSION_TAG}"
fi
-
+
+if [[ $( echo ${VERSION_TAG} | grep --invert-match ios-v ) ]]; then
+ echo "Error: ${VERSION_TAG} is not a valid iOS version tag"
+ echo "VERSION_TAG should be in format: ios-vX.X.X-pre.X"
+ exit 1
+fi
+
+if [[ $( wget --spider -O- https://api.github.com/repos/${GITHUB_USER}/${GITHUB_REPO}/releases/tags/${VERSION_TAG} 2>&1 | grep -c "404 Not Found" ) == 0 ]]; then
+ echo "Error: ${VERSION_TAG} has already been published on GitHub"
+ echo "See: https://github.com/${GITHUB_USER}/${GITHUB_REPO}/releases/tag/${VERSION_TAG}"
+ exit 1
+fi
+
+PUBLISH_VERSION=$( echo ${VERSION_TAG} | sed 's/^ios-v//' )
+git checkout ${VERSION_TAG}
+
+step "Deploying version ${PUBLISH_VERSION}…"
+
make clean && make distclean
if [[ "${GITHUB_RELEASE}" == true ]]; then
- echo "Create GitHub release..."
+ step "Create GitHub release…"
if [[ $( echo ${PUBLISH_VERSION} | awk '/[0-9]-/' ) ]]; then
PUBLISH_PRE_FLAG='--pre-release'
fi
- github-release --verbose release --tag "ios-v${PUBLISH_VERSION}" --name "ios-v${PUBLISH_VERSION}" --draft ${PUBLISH_PRE_FLAG}
+ github-release release \
+ --tag "ios-v${PUBLISH_VERSION}" \
+ --name "ios-v${PUBLISH_VERSION}" \
+ --draft ${PUBLISH_PRE_FLAG}
fi
buildPackageStyle "ipackage" "symbols"
@@ -83,3 +115,5 @@ buildPackageStyle "ipackage-strip"
buildPackageStyle "iframework" "symbols-dynamic"
buildPackageStyle "iframework SYMBOLS=NO" "dynamic"
buildPackageStyle "ifabric" "fabric"
+
+step "Finished deploying ${PUBLISH_VERSION}"
diff --git a/platform/ios/scripts/publish.sh b/platform/ios/scripts/publish.sh
index bdfbc94314..e080ee825c 100755
--- a/platform/ios/scripts/publish.sh
+++ b/platform/ios/scripts/publish.sh
@@ -4,6 +4,10 @@ set -e
set -o pipefail
set -u
+function step { >&2 echo -e "\033[1m\033[36m* $@\033[0m"; }
+function finish { >&2 echo -en "\033[0m"; }
+trap finish EXIT
+
#
# iOS release tag format is `vX.Y.Z`; `X.Y.Z` gets passed in
# In the case of symbolicated builds, we also append the `-symbols`.
@@ -21,11 +25,14 @@ fi
#
cd build/ios/pkg
ZIP=mapbox-ios-sdk-${PUBLISH_VERSION}${PUBLISH_STYLE}.zip
+step "Compressing ${ZIP}…"
rm -f ../${ZIP}
zip -r ../${ZIP} *
+
#
# upload
#
+step "Uploading ${ZIP} to s3…"
REPO_NAME=$(basename $TRAVIS_REPO_SLUG)
-aws s3 cp ../${ZIP} s3://mapbox/$REPO_NAME/ios/builds/ --acl public-read > /dev/null
+aws s3 cp ../${ZIP} s3://mapbox/$REPO_NAME/ios/builds/ --acl public-read
echo http://mapbox.s3.amazonaws.com/$REPO_NAME/ios/builds/${ZIP}
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm
index 9067efc033..88f4d8a970 100644
--- a/platform/ios/src/MGLMapView.mm
+++ b/platform/ios/src/MGLMapView.mm
@@ -24,6 +24,7 @@
#include <mbgl/util/projection.hpp>
#include <mbgl/util/default_styles.hpp>
#include <mbgl/util/chrono.hpp>
+#import <mbgl/util/run_loop.hpp>
#import "Mapbox.h"
#import "MGLFeature_Private.h"
@@ -37,6 +38,7 @@
#import "NSProcessInfo+MGLAdditions.h"
#import "NSException+MGLAdditions.h"
#import "NSURL+MGLAdditions.h"
+#import "UIImage+MGLAdditions.h"
#import "MGLFaux3DUserLocationAnnotationView.h"
#import "MGLUserLocationAnnotationView.h"
@@ -126,6 +128,11 @@ enum { MGLAnnotationTagNotFound = UINT32_MAX };
/// the annotation itself.
typedef std::map<MGLAnnotationTag, MGLAnnotationContext> MGLAnnotationContextMap;
+/// Initializes the run loop shim that lives on the main thread.
+void MGLinitializeRunLoop() {
+ static mbgl::util::RunLoop mainRunLoop;
+}
+
mbgl::util::UnitBezier MGLUnitBezierForMediaTimingFunction(CAMediaTimingFunction *function)
{
if ( ! function)
@@ -251,16 +258,16 @@ public:
{
mbgl::Map *_mbglMap;
MBGLView *_mbglView;
-
+
BOOL _opaque;
NS_MUTABLE_ARRAY_OF(NSURL *) *_bundledStyleURLs;
-
+
MGLAnnotationContextMap _annotationContextsByAnnotationTag;
/// Tag of the selected annotation. If the user location annotation is selected, this ivar is set to `MGLAnnotationTagNotFound`.
MGLAnnotationTag _selectedAnnotationTag;
NS_MUTABLE_DICTIONARY_OF(NSString *, NS_MUTABLE_ARRAY_OF(MGLAnnotationView *) *) *_annotationViewReuseQueueByIdentifier;
-
+
BOOL _userLocationAnnotationIsSelected;
/// Size of the rectangle formed by unioning the maximum slop area around every annotation image and annotation image view.
CGSize _unionedAnnotationRepresentationSize;
@@ -277,18 +284,18 @@ public:
CADisplayLink *_displayLink;
BOOL _needsDisplayRefresh;
-
+
NSUInteger _changeDelimiterSuppressionDepth;
-
+
/// Center coordinate of the pinch gesture on the previous iteration of the gesture.
CLLocationCoordinate2D _previousPinchCenterCoordinate;
NSUInteger _previousPinchNumberOfTouches;
-
+
BOOL _delegateHasAlphasForShapeAnnotations;
BOOL _delegateHasStrokeColorsForShapeAnnotations;
BOOL _delegateHasFillColorsForShapeAnnotations;
BOOL _delegateHasLineWidthsForShapeAnnotations;
-
+
MGLCompassDirectionFormatter *_accessibilityCompassFormatter;
}
@@ -357,6 +364,8 @@ public:
- (void)commonInit
{
+ MGLinitializeRunLoop();
+
_isTargetingInterfaceBuilder = NSProcessInfo.processInfo.mgl_isInterfaceBuilderDesignablesAgent;
_opaque = YES;
@@ -373,14 +382,14 @@ public:
self.accessibilityTraits = UIAccessibilityTraitAllowsDirectInteraction | UIAccessibilityTraitAdjustable;
_accessibilityCompassFormatter = [[MGLCompassDirectionFormatter alloc] init];
_accessibilityCompassFormatter.unitStyle = NSFormattingUnitStyleLong;
-
+
self.backgroundColor = [UIColor clearColor];
self.clipsToBounds = YES;
// setup mbgl view
const float scaleFactor = [UIScreen instancesRespondToSelector:@selector(nativeScale)] ? [[UIScreen mainScreen] nativeScale] : [[UIScreen mainScreen] scale];
_mbglView = new MBGLView(self, scaleFactor);
-
+
// Delete the pre-offline ambient cache at ~/Library/Caches/cache.db.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *fileCachePath = [paths.firstObject stringByAppendingPathComponent:@"cache.db"];
@@ -408,7 +417,7 @@ public:
_isWaitingForRedundantReachableNotification = YES;
}
[reachability startNotifier];
-
+
// Set up annotation management and selection state.
_annotationImagesByIdentifier = [NSMutableDictionary dictionary];
_annotationContextsByAnnotationTag = {};
@@ -573,7 +582,7 @@ public:
UIImage *scaleImage = [MGLMapView resourceImageNamed:@"Compass.png"];
UIGraphicsBeginImageContextWithOptions(scaleImage.size, NO, [UIScreen mainScreen].scale);
[scaleImage drawInRect:{ CGPointZero, scaleImage.size }];
-
+
CGFloat northSize = 9;
UIFont *northFont;
if ([UIFont respondsToSelector:@selector(systemFontOfSize:weight:)])
@@ -592,7 +601,7 @@ public:
scaleImage.size.height * 0.45,
north.size.width, north.size.height);
[north drawInRect:stringRect];
-
+
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
@@ -619,14 +628,14 @@ public:
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[_attributionButton removeObserver:self forKeyPath:@"hidden"];
-
+
// Removing the annotations unregisters any outstanding KVO observers.
NSArray *annotations = self.annotations;
if (annotations)
{
[self removeAnnotations:annotations];
}
-
+
[self validateDisplayLink];
if (_mbglMap)
@@ -657,7 +666,7 @@ public:
if (_delegate == delegate) return;
_delegate = delegate;
-
+
_delegateHasAlphasForShapeAnnotations = [_delegate respondsToSelector:@selector(mapView:alphaForShapeAnnotation:)];
_delegateHasStrokeColorsForShapeAnnotations = [_delegate respondsToSelector:@selector(mapView:strokeColorForShapeAnnotation:)];
_delegateHasFillColorsForShapeAnnotations = [_delegate respondsToSelector:@selector(mapView:fillColorForPolygonAnnotation:)];
@@ -695,7 +704,7 @@ public:
{
return;
}
-
+
CGFloat zoomFactor = self.maximumZoomLevel - self.minimumZoomLevel + 1;
CGFloat cpuFactor = [NSProcessInfo processInfo].processorCount;
CGFloat memoryFactor = (CGFloat)[NSProcessInfo processInfo].physicalMemory / 1000 / 1000 / 1000;
@@ -787,7 +796,7 @@ public:
//
[constraintParentView removeConstraints:self.logoViewConstraints];
[self.logoViewConstraints removeAllObjects];
-
+
[self.logoViewConstraints addObject:
[NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeBottom
@@ -811,7 +820,7 @@ public:
//
[constraintParentView removeConstraints:self.attributionButtonConstraints];
[self.attributionButtonConstraints removeAllObjects];
-
+
[self.attributionButtonConstraints addObject:
[NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeBottom
@@ -859,7 +868,7 @@ public:
- (void)layoutSubviews
{
[super layoutSubviews];
-
+
[self adjustContentInset];
if ( ! _isTargetingInterfaceBuilder)
@@ -877,7 +886,7 @@ public:
[self updateHeadingForDeviceOrientation];
[self updateCompass];
}
-
+
[self updateUserLocationAnnotationView];
}
@@ -899,12 +908,12 @@ public:
// This map view is an immediate child of a view controller’s content view.
viewController = (UIViewController *)self.superview.nextResponder;
}
-
+
if ( ! viewController.automaticallyAdjustsScrollViewInsets)
{
return;
}
-
+
UIEdgeInsets contentInset = UIEdgeInsetsZero;
CGPoint topPoint = CGPointMake(0, viewController.topLayoutGuide.length);
contentInset.top = [self convertPoint:topPoint fromView:viewController.view].y;
@@ -931,14 +940,14 @@ public:
{
return;
}
-
+
// After adjusting the content inset, move the center coordinate from the
// old frame of reference to the new one represented by the newly set
// content inset.
CLLocationCoordinate2D oldCenter = self.centerCoordinate;
-
+
_contentInset = contentInset;
-
+
if (self.userTrackingMode == MGLUserTrackingModeNone)
{
// Don’t call -setCenterCoordinate:, which resets the user tracking mode.
@@ -948,7 +957,7 @@ public:
{
[self didUpdateLocationWithUserTrackingAnimated:animated];
}
-
+
// Compass, logo and attribution button constraints needs to be updated.
[self setNeedsUpdateConstraints];
}
@@ -1008,7 +1017,7 @@ public:
{
_mbglMap->setConstrainMode(mbgl::ConstrainMode::HeightOnly);
}
-
+
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateFromDisplayLink)];
_displayLink.frameInterval = MGLTargetFrameInterval;
[_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
@@ -1045,7 +1054,7 @@ public:
[self validateLocationServices];
[MGLMapboxEvents flush];
-
+
_displayLink.paused = YES;
if ( ! self.glSnapshotView)
@@ -1086,11 +1095,11 @@ public:
[self.glSnapshotView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
[self.glView bindDrawable];
-
+
_displayLink.paused = NO;
[self validateLocationServices];
-
+
[MGLMapboxEvents pushEvent:MGLEventTypeMapLoad withAttributes:@{}];
}
}
@@ -1171,7 +1180,7 @@ public:
[self trackGestureEvent:MGLEventGesturePanStart forRecognizer:pan];
self.userTrackingMode = MGLUserTrackingModeNone;
-
+
[self notifyGestureDidBegin];
}
else if (pan.state == UIGestureRecognizerStateChanged)
@@ -1220,7 +1229,7 @@ public:
if (_mbglMap->getZoom() <= _mbglMap->getMinZoom() && pinch.scale < 1) return;
_mbglMap->cancelTransitions();
-
+
CGPoint centerPoint = [self anchorPointForGesture:pinch];
if (pinch.state == UIGestureRecognizerStateBegan)
@@ -1228,7 +1237,7 @@ public:
[self trackGestureEvent:MGLEventGesturePinchStart forRecognizer:pinch];
self.scale = _mbglMap->getScale();
-
+
[self notifyGestureDidBegin];
}
else if (pinch.state == UIGestureRecognizerStateChanged)
@@ -1236,9 +1245,9 @@ public:
CGFloat newScale = self.scale * pinch.scale;
if (log2(newScale) < _mbglMap->getMinZoom()) return;
-
+
_mbglMap->setScale(newScale, 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
@@ -1292,7 +1301,7 @@ public:
[self unrotateIfNeededForGesture];
}
-
+
_previousPinchCenterCoordinate = [self convertPoint:centerPoint toCoordinateFromView:self];
_previousPinchNumberOfTouches = pinch.numberOfTouches;
}
@@ -1302,7 +1311,7 @@ public:
if ( ! self.isRotateEnabled) return;
_mbglMap->cancelTransitions();
-
+
CGPoint centerPoint = [self anchorPointForGesture:rotate];
if (rotate.state == UIGestureRecognizerStateBegan)
@@ -1315,7 +1324,7 @@ public:
{
self.userTrackingMode = MGLUserTrackingModeFollow;
}
-
+
[self notifyGestureDidBegin];
}
else if (rotate.state == UIGestureRecognizerStateChanged)
@@ -1329,7 +1338,7 @@ public:
newDegrees = fminf(newDegrees, 30);
newDegrees = fmaxf(newDegrees, -30);
}
-
+
_mbglMap->setBearing(newDegrees, mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y });
[self notifyMapChange:mbgl::MapChangeRegionIsChanging];
@@ -1370,7 +1379,7 @@ public:
return;
}
[self trackGestureEvent:MGLEventGestureSingleTap forRecognizer:singleTap];
-
+
if (self.mapViewProxyAccessibilityElement.accessibilityElementIsFocused)
{
id nextElement;
@@ -1425,7 +1434,7 @@ public:
}
}
}
-
+
MGLAnnotationTag hitAnnotationTag = [self annotationTagAtPoint:tapPoint persistingResults:YES];
if (hitAnnotationTag != MGLAnnotationTagNotFound)
{
@@ -1506,7 +1515,7 @@ public:
self.scale = _mbglMap->getScale();
self.quickZoomStart = [quickZoom locationInView:quickZoom.view].y;
-
+
[self notifyGestureDidBegin];
}
else if (quickZoom.state == UIGestureRecognizerStateChanged)
@@ -1516,7 +1525,7 @@ public:
CGFloat newZoom = log2f(self.scale) + (distance / 75);
if (newZoom < _mbglMap->getMinZoom()) return;
-
+
CGPoint centerPoint = [self anchorPointForGesture:quickZoom];
_mbglMap->scaleBy(powf(2, newZoom) / _mbglMap->getScale(),
@@ -1549,7 +1558,7 @@ public:
CGFloat slowdown = 20.0;
CGFloat pitchNew = currentPitch - (gestureDistance / slowdown);
-
+
CGPoint centerPoint = [self anchorPointForGesture:twoFingerDrag];
_mbglMap->setPitch(pitchNew, mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y });
@@ -1574,7 +1583,7 @@ public:
{
return self.contentCenter;
}
-
+
return [gesture locationInView:gesture.view];
}
@@ -1682,7 +1691,7 @@ public:
nil];
}
-
+
[self.attributionSheet showFromRect:self.attributionButton.frame inView:self animated:YES];
}
@@ -1783,7 +1792,7 @@ public:
// Redundantly move the associated annotation view outside the scope of the animation-less transaction block in -updateAnnotationViews.
annotationContext.annotationView.center = [self convertCoordinate:annotationContext.annotation.coordinate toPointToView:self];
}
-
+
MGLAnnotationImage *annotationImage = [self imageOfAnnotationWithTag:annotationTag];
NSString *symbolName = annotationImage.styleIconIdentifier;
@@ -1960,14 +1969,14 @@ public:
- (UIBezierPath *)accessibilityPath
{
UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.accessibilityFrame];
-
+
// Exclude any visible annotation callout view.
if (self.calloutViewForSelectedAnnotation)
{
UIBezierPath *calloutViewPath = [UIBezierPath bezierPathWithRect:self.calloutViewForSelectedAnnotation.frame];
[path appendPath:calloutViewPath];
}
-
+
return path;
}
@@ -2008,7 +2017,7 @@ public:
return nil;
}
std::vector<MGLAnnotationTag> visibleAnnotations = [self annotationTagsInRect:self.bounds];
-
+
// Ornaments
if (index == 0)
{
@@ -2026,7 +2035,7 @@ public:
{
return self.attributionButton;
}
-
+
std::sort(visibleAnnotations.begin(), visibleAnnotations.end());
CGPoint centerPoint = self.contentCenter;
if (self.userTrackingMode != MGLUserTrackingModeNone)
@@ -2043,7 +2052,7 @@ public:
coordinateB.longitude - currentCoordinate.longitude);
return deltaA < deltaB;
});
-
+
NSUInteger annotationIndex = MGLAnnotationTagNotFound;
if (index >= 0 && (NSUInteger)(index - 2) < visibleAnnotations.size())
{
@@ -2054,20 +2063,20 @@ public:
NSAssert(_annotationContextsByAnnotationTag.count(annotationTag), @"Missing annotation for tag %u.", annotationTag);
MGLAnnotationContext &annotationContext = _annotationContextsByAnnotationTag.at(annotationTag);
id <MGLAnnotation> annotation = annotationContext.annotation;
-
+
// Let the annotation view serve as its own accessibility element.
MGLAnnotationView *annotationView = annotationContext.annotationView;
if (annotationView && annotationView.superview)
{
return annotationView;
}
-
+
// Lazily create an accessibility element for the found annotation.
if ( ! annotationContext.accessibilityElement)
{
annotationContext.accessibilityElement = [[MGLAnnotationAccessibilityElement alloc] initWithAccessibilityContainer:self tag:annotationTag];
}
-
+
// Update the accessibility element.
MGLAnnotationImage *annotationImage = [self imageOfAnnotationWithTag:annotationTag];
CGRect annotationFrame = [self frameOfImage:annotationImage.image centeredAtCoordinate:annotation.coordinate];
@@ -2079,7 +2088,7 @@ public:
CGRect screenRect = UIAccessibilityConvertFrameToScreenCoordinates(annotationFrame, self);
annotationContext.accessibilityElement.accessibilityFrame = screenRect;
annotationContext.accessibilityElement.accessibilityHint = NSLocalizedStringWithDefaultValue(@"ANNOTATION_A11Y_HINT", nil, nil, @"Shows more info", @"Accessibility hint");
-
+
if ([annotation respondsToSelector:@selector(title)])
{
annotationContext.accessibilityElement.accessibilityLabel = annotation.title;
@@ -2088,7 +2097,7 @@ public:
{
annotationContext.accessibilityElement.accessibilityValue = annotation.subtitle;
}
-
+
return annotationContext.accessibilityElement;
}
@@ -2107,9 +2116,9 @@ public:
{
return 1;
}
-
+
std::vector<MGLAnnotationTag> visibleAnnotations = [self annotationTagsInRect:self.bounds];
-
+
MGLAnnotationTag tag = MGLAnnotationTagNotFound;
if ([element isKindOfClass:[MGLAnnotationView class]])
{
@@ -2128,7 +2137,7 @@ public:
{
return NSNotFound;
}
-
+
std::sort(visibleAnnotations.begin(), visibleAnnotations.end());
auto foundElement = std::find(visibleAnnotations.begin(), visibleAnnotations.end(), tag);
if (foundElement == visibleAnnotations.end())
@@ -2168,7 +2177,7 @@ public:
}
_mbglMap->scaleBy(scaleFactor, mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y });
[self unrotateIfNeededForGesture];
-
+
UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, self.accessibilityValue);
}
@@ -2218,7 +2227,7 @@ public:
- (void)_setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate edgePadding:(UIEdgeInsets)insets zoomLevel:(double)zoomLevel direction:(CLLocationDirection)direction duration:(NSTimeInterval)duration animationTimingFunction:(nullable CAMediaTimingFunction *)function completionHandler:(nullable void (^)(void))completion
{
_mbglMap->cancelTransitions();
-
+
mbgl::CameraOptions cameraOptions;
cameraOptions.center = MGLLatLngFromLocationCoordinate2D(centerCoordinate);
cameraOptions.padding = MGLEdgeInsetsFromNSEdgeInsets(insets);
@@ -2227,7 +2236,7 @@ public:
{
cameraOptions.angle = MGLRadiansFromDegrees(-direction);
}
-
+
mbgl::AnimationOptions animationOptions;
if (duration)
{
@@ -2267,9 +2276,9 @@ public:
{
if (zoomLevel == self.zoomLevel) return;
_mbglMap->cancelTransitions();
-
+
CGFloat duration = animated ? MGLAnimationDuration : 0;
-
+
_mbglMap->setZoom(zoomLevel,
MGLEdgeInsetsFromNSEdgeInsets(self.contentInset),
MGLDurationInSeconds(duration));
@@ -2364,7 +2373,7 @@ public:
- (void)_setVisibleCoordinates:(CLLocationCoordinate2D *)coordinates count:(NSUInteger)count edgePadding:(UIEdgeInsets)insets direction:(CLLocationDirection)direction duration:(NSTimeInterval)duration animationTimingFunction:(nullable CAMediaTimingFunction *)function completionHandler:(nullable void (^)(void))completion
{
_mbglMap->cancelTransitions();
-
+
[self willChangeValueForKey:@"visibleCoordinateBounds"];
mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(insets);
padding += MGLEdgeInsetsFromNSEdgeInsets(self.contentInset);
@@ -2374,13 +2383,13 @@ public:
{
latLngs.push_back({coordinates[i].latitude, coordinates[i].longitude});
}
-
+
mbgl::CameraOptions cameraOptions = _mbglMap->cameraForLatLngs(latLngs, padding);
if (direction >= 0)
{
cameraOptions.angle = MGLRadiansFromDegrees(-direction);
}
-
+
mbgl::AnimationOptions animationOptions;
if (duration > 0)
{
@@ -2417,7 +2426,7 @@ public:
{
self.userTrackingMode = MGLUserTrackingModeFollow;
}
-
+
[self _setDirection:direction animated:animated];
}
@@ -2427,7 +2436,7 @@ public:
_mbglMap->cancelTransitions();
CGFloat duration = animated ? MGLAnimationDuration : 0;
-
+
if (self.userTrackingMode == MGLUserTrackingModeNone)
{
_mbglMap->setBearing(direction,
@@ -2502,7 +2511,7 @@ public:
});
};
}
-
+
[self willChangeValueForKey:@"camera"];
_mbglMap->easeTo(cameraOptions, animationOptions);
[self didChangeValueForKey:@"camera"];
@@ -2521,7 +2530,7 @@ public:
- (void)flyToCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration peakAltitude:(CLLocationDistance)peakAltitude completionHandler:(nullable void (^)(void))completion
{
self.userTrackingMode = MGLUserTrackingModeNone;
-
+
[self _flyToCamera:camera edgePadding:self.contentInset withDuration:duration peakAltitude:peakAltitude completionHandler:completion];
}
@@ -2554,7 +2563,7 @@ public:
});
};
}
-
+
[self willChangeValueForKey:@"camera"];
_mbglMap->flyTo(cameraOptions, animationOptions);
[self didChangeValueForKey:@"camera"];
@@ -2658,7 +2667,7 @@ public:
bounds.extend([self convertPoint:{ CGRectGetMaxX(rect), CGRectGetMinY(rect) } toLatLngFromView:view]);
bounds.extend([self convertPoint:{ CGRectGetMaxX(rect), CGRectGetMaxY(rect) } toLatLngFromView:view]);
bounds.extend([self convertPoint:{ CGRectGetMinX(rect), CGRectGetMaxY(rect) } toLatLngFromView:view]);
-
+
// The world is wrapping if a point just outside the bounds is also within
// the rect.
mbgl::LatLng outsideLatLng;
@@ -2676,14 +2685,14 @@ public:
bounds.east() + 1,
};
}
-
+
// If the world is wrapping, extend the bounds to cover all longitudes.
if (CGRectContainsPoint(rect, [self convertLatLng:outsideLatLng toPointToView:view]))
{
bounds.extend(mbgl::LatLng(bounds.south(), -180));
bounds.extend(mbgl::LatLng(bounds.south(), 180));
}
-
+
return bounds;
}
@@ -2769,7 +2778,7 @@ public:
{
return nil;
}
-
+
// Map all the annotation tags to the annotations themselves.
std::vector<id <MGLAnnotation>> annotations;
std::transform(_annotationContextsByAnnotationTag.begin(),
@@ -2779,11 +2788,11 @@ public:
{
return pair.second.annotation;
});
-
+
annotations.erase(std::remove_if(annotations.begin(), annotations.end(),
[](const id <MGLAnnotation> annotation) { return annotation == nullptr; }),
annotations.end());
-
+
return [NSArray arrayWithObjects:&annotations[0] count:annotations.size()];
}
@@ -2794,7 +2803,7 @@ public:
{
return nil;
}
-
+
MGLAnnotationContext &annotationContext = _annotationContextsByAnnotationTag[tag];
return annotationContext.annotation;
}
@@ -2806,7 +2815,7 @@ public:
{
return MGLAnnotationTagNotFound;
}
-
+
for (auto &pair : _annotationContextsByAnnotationTag)
{
if (pair.second.annotation == annotation)
@@ -2837,7 +2846,7 @@ public:
BOOL delegateImplementsViewForAnnotation = [self.delegate respondsToSelector:@selector(mapView:viewForAnnotation:)];
BOOL delegateImplementsImageForPoint = [self.delegate respondsToSelector:@selector(mapView:imageForAnnotation:)];
-
+
NSMutableArray *newAnnotationViews = [[NSMutableArray alloc] initWithCapacity:annotations.count];
for (id <MGLAnnotation> annotation in annotations)
@@ -2852,7 +2861,7 @@ public:
{
continue;
}
-
+
// The polyline or polygon knows how to style itself (with the map view’s help).
MGLMultiPoint *multiPoint = (MGLMultiPoint *)annotation;
if (!multiPoint.pointCount) {
@@ -2873,7 +2882,7 @@ public:
MGLAnnotationView *annotationView;
NSString *symbolName;
NSValue *annotationValue = [NSValue valueWithNonretainedObject:annotation];
-
+
if (delegateImplementsViewForAnnotation)
{
annotationView = [self annotationViewForAnnotation:annotation];
@@ -2883,7 +2892,7 @@ public:
annotationView.annotation = annotation;
annotationView.center = [self convertCoordinate:annotation.coordinate toPointToView:self];
[newAnnotationViews addObject:annotationView];
-
+
MGLAnnotationImage *annotationImage = self.invisibleAnnotationImage;
symbolName = annotationImage.styleIconIdentifier;
annotationImagesForAnnotation[annotationValue] = annotationImage;
@@ -2893,10 +2902,10 @@ public:
}
}
}
-
+
if ( ! annotationView) {
MGLAnnotationImage *annotationImage;
-
+
if (delegateImplementsImageForPoint)
{
annotationImage = [self.delegate mapView:self imageForAnnotation:annotation];
@@ -2909,9 +2918,9 @@ public:
{
annotationImage = self.defaultAnnotationImage;
}
-
+
symbolName = annotationImage.styleIconIdentifier;
-
+
if ( ! symbolName)
{
symbolName = [MGLAnnotationSpritePrefix stringByAppendingString:annotationImage.reuseIdentifier];
@@ -2921,7 +2930,7 @@ public:
{
[self installAnnotationImage:annotationImage];
}
-
+
annotationImagesForAnnotation[annotationValue] = annotationImage;
}
@@ -2939,7 +2948,7 @@ public:
context.annotationView = annotationView;
context.viewReuseIdentifier = annotationView.reuseIdentifier;
}
-
+
_annotationContextsByAnnotationTag[annotationTag] = context;
if ([annotation isKindOfClass:[NSObject class]]) {
@@ -2950,21 +2959,21 @@ public:
}
[self updateAnnotationContainerViewWithAnnotationViews:newAnnotationViews];
-
+
[self didChangeValueForKey:@"annotations"];
-
+
if ([self.delegate respondsToSelector:@selector(mapView:didAddAnnotationViews:)])
{
[self.delegate mapView:self didAddAnnotationViews:newAnnotationViews];
}
-
+
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, nil);
}
- (void)updateAnnotationContainerViewWithAnnotationViews:(NS_ARRAY_OF(MGLAnnotationView *) *)annotationViews
{
if (annotationViews.count == 0) return;
-
+
MGLAnnotationContainerView *newAnnotationContainerView;
if (self.annotationContainerView)
{
@@ -3000,7 +3009,7 @@ public:
- (MGLAnnotationImage *)invisibleAnnotationImage
{
MGLAnnotationImage *annotationImage = [self dequeueReusableAnnotationImageWithIdentifier:MGLInvisibleStyleMarkerSymbolName];
-
+
if (!annotationImage)
{
UIGraphicsBeginImageContext(CGSizeMake(1, 1));
@@ -3010,27 +3019,27 @@ public:
reuseIdentifier:MGLInvisibleStyleMarkerSymbolName];
annotationImage.styleIconIdentifier = [MGLAnnotationSpritePrefix stringByAppendingString:annotationImage.reuseIdentifier];
}
-
+
return annotationImage;
}
- (MGLAnnotationView *)annotationViewForAnnotation:(id<MGLAnnotation>)annotation
{
MGLAnnotationView *annotationView = [self.delegate mapView:self viewForAnnotation:annotation];
-
+
if (annotationView)
{
annotationView.annotation = annotation;
annotationView.mapView = self;
CGRect bounds = UIEdgeInsetsInsetRect({ CGPointZero, annotationView.frame.size }, annotationView.alignmentRectInsets);
-
+
_largestAnnotationViewSize = CGSizeMake(MAX(_largestAnnotationViewSize.width, CGRectGetWidth(bounds)),
MAX(_largestAnnotationViewSize.height, CGRectGetHeight(bounds)));
-
+
_unionedAnnotationRepresentationSize = CGSizeMake(MAX(_unionedAnnotationRepresentationSize.width, _largestAnnotationViewSize.width),
MAX(_unionedAnnotationRepresentationSize.height, _largestAnnotationViewSize.height));
}
-
+
return annotationView;
}
@@ -3038,16 +3047,30 @@ public:
{
MGLAnnotationTag annotationTag = [self annotationTagForAnnotation:annotation];
if (annotationTag == MGLAnnotationTagNotFound) return nil;
-
+
MGLAnnotationContext &annotationContext = _annotationContextsByAnnotationTag.at(annotationTag);
return annotationContext.annotationView;
}
- (double)alphaForShapeAnnotation:(MGLShape *)annotation
{
+ // The explicit -mapView:alphaForShapeAnnotation: delegate method is deprecated
+ // but still used, if implemented. When not implemented, call the stroke or
+ // fill color delegate methods and pull the alpha from the returned color.
if (_delegateHasAlphasForShapeAnnotations)
{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self.delegate mapView:self alphaForShapeAnnotation:annotation];
+#pragma clang diagnostic pop
+ }
+ else if ([annotation isKindOfClass:[MGLPolygon class]])
+ {
+ return [self fillColorForPolygonAnnotation:(MGLPolygon *)annotation].a ?: 1.0;
+ }
+ else if ([annotation isKindOfClass:[MGLShape class]])
+ {
+ return [self strokeColorForShapeAnnotation:annotation].a ?: 1.0;
}
return 1.0;
}
@@ -3057,7 +3080,7 @@ public:
UIColor *color = (_delegateHasStrokeColorsForShapeAnnotations
? [self.delegate mapView:self strokeColorForShapeAnnotation:annotation]
: self.tintColor);
- return color.mbgl_color;
+ return color.mgl_color;
}
- (mbgl::Color)fillColorForPolygonAnnotation:(MGLPolygon *)annotation
@@ -3065,7 +3088,7 @@ public:
UIColor *color = (_delegateHasFillColorsForShapeAnnotations
? [self.delegate mapView:self fillColorForPolygonAnnotation:annotation]
: self.tintColor);
- return color.mbgl_color;
+ return color.mgl_color;
}
- (CGFloat)lineWidthForPolylineAnnotation:(MGLPolyline *)annotation
@@ -3082,29 +3105,11 @@ public:
NSString *iconIdentifier = annotationImage.styleIconIdentifier;
self.annotationImagesByIdentifier[annotationImage.reuseIdentifier] = annotationImage;
annotationImage.delegate = self;
-
- // retrieve pixels
- CGImageRef image = annotationImage.image.CGImage;
- size_t width = CGImageGetWidth(image);
- size_t height = CGImageGetHeight(image);
- CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
- mbgl::PremultipliedImage cPremultipliedImage(width, height);
- size_t bytesPerPixel = 4;
- size_t bytesPerRow = bytesPerPixel * width;
- size_t bitsPerComponent = 8;
- CGContextRef context = CGBitmapContextCreate(cPremultipliedImage.data.get(), width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast);
- CGContextDrawImage(context, CGRectMake(0, 0, width, height), image);
- CGContextRelease(context);
- CGColorSpaceRelease(colorSpace);
// add sprite
- auto cSpriteImage = std::make_shared<mbgl::SpriteImage>(
- std::move(cPremultipliedImage),
- float(annotationImage.image.scale));
+ std::shared_ptr<mbgl::SpriteImage> sprite(annotationImage.image.mgl_spriteImage);
+ _mbglMap->addAnnotationIcon(iconIdentifier.UTF8String, sprite);
- // sprite upload
- _mbglMap->addAnnotationIcon(iconIdentifier.UTF8String, cSpriteImage);
-
// Create a slop area with a “radius” equal in size to the annotation
// image’s alignment rect, allowing the eventual tap to be on any point
// within this image. Union this slop area with any existing slop areas.
@@ -3150,9 +3155,9 @@ public:
{
[self deselectAnnotation:annotation animated:NO];
}
-
+
_annotationContextsByAnnotationTag.erase(annotationTag);
-
+
if ([annotation isKindOfClass:[NSObject class]] && ![annotation isKindOfClass:[MGLMultiPoint class]])
{
[(NSObject *)annotation removeObserver:self forKeyPath:@"coordinate" context:(void *)(NSUInteger)annotationTag];
@@ -3214,7 +3219,7 @@ public:
MGLAnnotationView *reusableView = annotationViewReuseQueue.firstObject;
[reusableView prepareForReuse];
[annotationViewReuseQueue removeObject:reusableView];
-
+
return reusableView;
}
@@ -3241,14 +3246,14 @@ public:
queryRect = CGRectInset(queryRect, -MGLAnnotationImagePaddingForHitTest,
-MGLAnnotationImagePaddingForHitTest);
std::vector<MGLAnnotationTag> nearbyAnnotations = [self annotationTagsInRect:queryRect];
-
+
if (nearbyAnnotations.size())
{
// Assume that the user is fat-fingering an annotation.
CGRect hitRect = CGRectInset({ point, CGSizeZero },
-MGLAnnotationImagePaddingForHitTest,
-MGLAnnotationImagePaddingForHitTest);
-
+
// Filter out any annotation whose image or view is unselectable or for which
// hit testing fails.
auto end = std::remove_if(nearbyAnnotations.begin(), nearbyAnnotations.end(),
@@ -3256,10 +3261,10 @@ public:
{
id <MGLAnnotation> annotation = [self annotationWithTag:annotationTag];
NSAssert(annotation, @"Unknown annotation found nearby tap");
-
+
MGLAnnotationContext annotationContext = _annotationContextsByAnnotationTag[annotationTag];
CGRect annotationRect;
-
+
MGLAnnotationView *annotationView = annotationContext.annotationView;
if (annotationView)
{
@@ -3267,7 +3272,7 @@ public:
{
return true;
}
-
+
CGPoint calloutAnchorPoint = [self convertCoordinate:annotation.coordinate toPointToView:self];
CGRect frame = CGRectInset({ calloutAnchorPoint, CGSizeZero }, -CGRectGetWidth(annotationView.frame) / 2, -CGRectGetHeight(annotationView.frame) / 2);
annotationRect = UIEdgeInsetsInsetRect(frame, annotationView.alignmentRectInsets);
@@ -3279,28 +3284,28 @@ public:
{
return true;
}
-
+
MGLAnnotationImage *fallbackAnnotationImage = [self dequeueReusableAnnotationImageWithIdentifier:MGLDefaultStyleMarkerSymbolName];
UIImage *fallbackImage = fallbackAnnotationImage.image;
-
+
annotationRect = [self frameOfImage:annotationImage.image ?: fallbackImage centeredAtCoordinate:annotation.coordinate];
}
-
+
// Filter out the annotation if the fattened finger didn’t land
// within the image’s alignment rect.
return !!!CGRectIntersectsRect(annotationRect, hitRect);
});
-
+
nearbyAnnotations.resize(std::distance(nearbyAnnotations.begin(), end));
}
-
+
MGLAnnotationTag hitAnnotationTag = MGLAnnotationTagNotFound;
if (nearbyAnnotations.size())
{
// The annotation tags need to be stable in order to compare them with
// the remembered tags.
std::sort(nearbyAnnotations.begin(), nearbyAnnotations.end());
-
+
if (nearbyAnnotations == _annotationsNearbyLastTap)
{
// The first selection in the cycle should be the one nearest to the
@@ -3315,7 +3320,7 @@ public:
coordinateB.longitude - currentCoordinate.longitude);
return deltaA < deltaB;
});
-
+
// The last time we persisted a set of annotations, we had the same
// set of annotations as we do now. Cycle through them.
if (_selectedAnnotationTag == MGLAnnotationTagNotFound
@@ -3353,7 +3358,7 @@ public:
{
_annotationsNearbyLastTap = nearbyAnnotations;
}
-
+
// Choose the first nearby annotation.
if (nearbyAnnotations.size())
{
@@ -3361,7 +3366,7 @@ public:
}
}
}
-
+
return hitAnnotationTag;
}
@@ -3433,7 +3438,7 @@ public:
}
[self deselectAnnotation:self.selectedAnnotation animated:NO];
-
+
// Add the annotation to the map if it hasn’t been added yet.
MGLAnnotationTag annotationTag = [self annotationTagForAnnotation:annotation];
if (annotationTag == MGLAnnotationTagNotFound && annotation != self.userLocation)
@@ -3442,29 +3447,29 @@ public:
annotationTag = [self annotationTagForAnnotation:annotation];
if (annotationTag == MGLAnnotationTagNotFound) return;
}
-
+
// By default attempt to use the GL annotation image frame as the positioning rect.
CGRect positioningRect = [self positioningRectForCalloutForAnnotationWithTag:annotationTag];
-
+
MGLAnnotationView *annotationView = nil;
-
+
if (annotation != self.userLocation)
{
MGLAnnotationContext &annotationContext = _annotationContextsByAnnotationTag.at(annotationTag);
-
+
annotationView = annotationContext.annotationView;
-
+
if (annotationView && annotationView.enabled)
{
// Annotations represented by views use the view frame as the positioning rect.
positioningRect = annotationView.frame;
-
+
[annotationView.superview bringSubviewToFront:annotationView];
[annotationView setSelected:YES animated:animated];
}
}
-
+
// The client can request that any annotation be selected (even ones that are offscreen).
// The annotation can’t be selected if no part of it is hittable.
if ( ! CGRectIntersectsRect(positioningRect, self.bounds) && annotation != self.userLocation)
@@ -3494,7 +3499,7 @@ public:
if (_userLocationAnnotationIsSelected)
{
positioningRect = [self.userLocationAnnotationView.layer.presentationLayer frame];
-
+
CGRect implicitAnnotationFrame = [self.userLocationAnnotationView.layer.presentationLayer frame];
CGRect explicitAnnotationFrame = self.userLocationAnnotationView.frame;
_initialImplicitCalloutViewOffset = CGPointMake(CGRectGetMinX(explicitAnnotationFrame) - CGRectGetMinX(implicitAnnotationFrame),
@@ -3543,7 +3548,7 @@ public:
{
[self.delegate mapView:self didSelectAnnotation:annotation];
}
-
+
if (annotationView && [self.delegate respondsToSelector:@selector(mapView:didSelectAnnotationView:)])
{
[self.delegate mapView:self didSelectAnnotationView:annotationView];
@@ -3565,7 +3570,7 @@ public:
- (CGRect)positioningRectForCalloutForAnnotationWithTag:(MGLAnnotationTag)annotationTag
{
MGLAnnotationContext annotationContext = _annotationContextsByAnnotationTag[annotationTag];
-
+
id <MGLAnnotation> annotation = [self annotationWithTag:annotationTag];
if ( ! annotation)
{
@@ -3580,10 +3585,10 @@ public:
{
return CGRectZero;
}
-
+
CGRect positioningRect = [self frameOfImage:image centeredAtCoordinate:annotation.coordinate];
positioningRect.origin.x -= 0.5;
-
+
return CGRectInset(positioningRect, -MGLAnnotationImagePaddingForCallout,
-MGLAnnotationImagePaddingForCallout);
}
@@ -3605,10 +3610,10 @@ public:
{
return nil;
}
-
+
NSString *customSymbol = _annotationContextsByAnnotationTag.at(annotationTag).imageReuseIdentifier;
NSString *symbolName = customSymbol.length ? customSymbol : MGLDefaultStyleMarkerSymbolName;
-
+
return [self dequeueReusableAnnotationImageWithIdentifier:symbolName];
}
@@ -3620,11 +3625,11 @@ public:
{
// dismiss popup
[self.calloutViewForSelectedAnnotation dismissCalloutAnimated:animated];
-
+
// deselect annotation view
MGLAnnotationView *annotationView = nil;
MGLAnnotationTag annotationTag = [self annotationTagForAnnotation:annotation];
-
+
if (annotationTag != MGLAnnotationTagNotFound)
{
MGLAnnotationContext &annotationContext = _annotationContextsByAnnotationTag.at(annotationTag);
@@ -3641,7 +3646,7 @@ public:
{
[self.delegate mapView:self didDeselectAnnotation:annotation];
}
-
+
if (annotationView && [self.delegate respondsToSelector:@selector(mapView:didDeselectAnnotationView:)])
{
[self.delegate mapView:self didDeselectAnnotationView:annotationView];
@@ -3656,7 +3661,7 @@ public:
{
return;
}
-
+
// The user location callout view initially points to the user location
// annotation’s implicit (visual) frame, which is offset from the
// annotation’s explicit frame. Now the callout view needs to rendezvous
@@ -3720,19 +3725,19 @@ public:
NSString *iconIdentifier = annotationImage.styleIconIdentifier;
NSString *fallbackReuseIdentifier = MGLDefaultStyleMarkerSymbolName;
NSString *fallbackIconIdentifier = [MGLAnnotationSpritePrefix stringByAppendingString:fallbackReuseIdentifier];
-
+
// Remove the old icon from the style.
if ( ! [iconIdentifier isEqualToString:fallbackIconIdentifier]) {
_mbglMap->removeAnnotationIcon(iconIdentifier.UTF8String);
}
-
+
if (annotationImage.image)
{
// Add the new icon to the style.
NSString *updatedIconIdentifier = [MGLAnnotationSpritePrefix stringByAppendingString:annotationImage.reuseIdentifier];
annotationImage.styleIconIdentifier = updatedIconIdentifier;
[self installAnnotationImage:annotationImage];
-
+
if ([iconIdentifier isEqualToString:fallbackIconIdentifier])
{
// Update any annotations associated with the annotation image.
@@ -3747,7 +3752,7 @@ public:
{
[self installAnnotationImage:self.defaultAnnotationImage];
}
-
+
// Update any annotations associated with the annotation image.
[self applyIconIdentifier:fallbackIconIdentifier toAnnotationsWithImageReuseIdentifier:reuseIdentifier];
}
@@ -3826,11 +3831,11 @@ public:
{
[self.delegate mapViewWillStartLocatingUser:self];
}
-
+
self.userLocation = [[MGLUserLocation alloc] initWithMapView:self];
-
+
MGLUserLocationAnnotationView *userLocationAnnotationView;
-
+
if ([self.delegate respondsToSelector:@selector(mapView:viewForAnnotation:)])
{
userLocationAnnotationView = (MGLUserLocationAnnotationView *)[self.delegate mapView:self viewForAnnotation:self.userLocation];
@@ -3844,11 +3849,11 @@ public:
userLocationAnnotationView = nil;
}
}
-
+
self.userLocationAnnotationView = userLocationAnnotationView ?: [[MGLFaux3DUserLocationAnnotationView alloc] init];
self.userLocationAnnotationView.mapView = self;
self.userLocationAnnotationView.userLocation = self.userLocation;
-
+
self.userLocationAnnotationView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin |
UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin);
@@ -3926,7 +3931,7 @@ public:
case MGLUserTrackingModeNone:
{
self.userTrackingState = MGLUserTrackingStatePossible;
-
+
[self.locationManager stopUpdatingHeading];
// Immediately update the annotation view; other cases update inside
@@ -3957,7 +3962,7 @@ public:
{
self.userTrackingState = animated ? MGLUserTrackingStatePossible : MGLUserTrackingStateChanged;
}
-
+
self.showsUserLocation = YES;
if (self.zoomLevel < self.currentMinimumZoom)
@@ -4058,7 +4063,7 @@ public:
duration = MIN([newLocation.timestamp timeIntervalSinceDate:oldLocation.timestamp], MGLUserLocationAnimationDuration);
}
[self updateUserLocationAnnotationViewAnimatedWithDuration:duration];
-
+
if (self.userTrackingMode == MGLUserTrackingModeNone &&
self.userLocationAnnotationView.accessibilityElementIsFocused &&
[UIApplication sharedApplication].applicationState == UIApplicationStateActive)
@@ -4076,7 +4081,7 @@ public:
{
return;
}
-
+
// If the user location annotation is already where it’s supposed to be,
// don’t change the viewport.
CGPoint correctPoint = self.userLocationAnnotationViewCenter;
@@ -4086,7 +4091,7 @@ public:
{
return;
}
-
+
if (self.userTrackingMode == MGLUserTrackingModeFollowWithCourse
&& CLLocationCoordinate2DIsValid(self.targetCoordinate))
{
@@ -4127,7 +4132,7 @@ public:
- (void)didUpdateLocationSignificantlyAnimated:(BOOL)animated
{
self.userTrackingState = MGLUserTrackingStateBegan;
-
+
MGLMapCamera *camera = self.camera;
camera.centerCoordinate = self.userLocation.location.coordinate;
camera.heading = self.directionByFollowingWithCourse;
@@ -4138,7 +4143,7 @@ public:
camera.centerCoordinate.latitude,
self.frame.size);
}
-
+
__weak MGLMapView *weakSelf = self;
[self _flyToCamera:camera
edgePadding:self.edgePaddingForFollowing
@@ -4171,7 +4176,7 @@ public:
}
};
}
-
+
CLLocationCoordinate2D foci[] = {
self.userLocation.location.coordinate,
self.targetCoordinate,
@@ -4195,7 +4200,7 @@ public:
{
// Center on user location unless we're already centered there (or very close).
CGPoint correctPoint = self.userLocationAnnotationViewCenter;
-
+
// Shift the entire frame upward or downward to accommodate a shifted user
// location annotation view.
CGRect bounds = self.bounds;
@@ -4237,7 +4242,7 @@ public:
{
direction = self.userLocation.location.course;
}
-
+
if (direction >= 0)
{
if (self.userLocationVerticalAlignment == MGLAnnotationVerticalAlignmentTop)
@@ -4337,7 +4342,7 @@ public:
- (NS_ARRAY_OF(id <MGLFeature>) *)visibleFeaturesAtPoint:(CGPoint)point inStyleLayersWithIdentifiers:(NS_SET_OF(NSString *) *)styleLayerIdentifiers
{
mbgl::ScreenCoordinate screenCoordinate = { point.x, point.y };
-
+
mbgl::optional<std::vector<std::string>> optionalLayerIDs;
if (styleLayerIdentifiers)
{
@@ -4349,7 +4354,7 @@ public:
}];
optionalLayerIDs = layerIDs;
}
-
+
std::vector<mbgl::Feature> features = _mbglMap->queryRenderedFeatures(screenCoordinate, optionalLayerIDs);
return MGLFeaturesFromMBGLFeatures(features);
}
@@ -4363,7 +4368,7 @@ public:
{ CGRectGetMinX(rect), CGRectGetMinY(rect) },
{ CGRectGetMaxX(rect), CGRectGetMaxY(rect) },
};
-
+
mbgl::optional<std::vector<std::string>> optionalLayerIDs;
if (styleLayerIdentifiers) {
__block std::vector<std::string> layerIDs;
@@ -4373,7 +4378,7 @@ public:
}];
optionalLayerIDs = layerIDs;
}
-
+
std::vector<mbgl::Feature> features = _mbglMap->queryRenderedFeatures(screenBox, optionalLayerIDs);
return MGLFeaturesFromMBGLFeatures(features);
}
@@ -4404,7 +4409,7 @@ public:
&& state != UIGestureRecognizerStateChanged)
{
[self unrotateIfNeededAnimated:YES];
-
+
// Snap to north.
if ((self.direction < MGLToleranceForSnappingToNorth
|| self.direction > 360 - MGLToleranceForSnappingToNorth)
@@ -4558,6 +4563,14 @@ public:
}
break;
}
+ case mbgl::MapChangeDidFinishLoadingStyle:
+ {
+ if ([self.delegate respondsToSelector:@selector(mapView:didFinishLoadingStyle:)])
+ {
+ [self.delegate mapView:self didFinishLoadingStyle:self.style];
+ }
+ break;
+ }
}
}
@@ -4569,21 +4582,21 @@ public:
- (void)updateAnnotationViews
{
BOOL delegateImplementsViewForAnnotation = [self.delegate respondsToSelector:@selector(mapView:viewForAnnotation:)];
-
+
if (!delegateImplementsViewForAnnotation)
{
return;
}
-
+
[CATransaction begin];
[CATransaction setDisableActions:YES];
-
+
for (auto &pair : _annotationContextsByAnnotationTag)
{
CGRect viewPort = CGRectInset(self.bounds,
-_largestAnnotationViewSize.width / 2.0 - MGLAnnotationUpdateViewportOutset.width / 2.0,
-_largestAnnotationViewSize.height / 2.0 - MGLAnnotationUpdateViewportOutset.width);
-
+
MGLAnnotationContext &annotationContext = pair.second;
MGLAnnotationView *annotationView = annotationContext.annotationView;
@@ -4601,7 +4614,7 @@ public:
annotationView.mapView = self;
annotationView.center = [self convertCoordinate:annotationContext.annotation.coordinate toPointToView:self];
annotationContext.annotationView = annotationView;
-
+
if (!annotationView.superview) {
[self.annotationContainerView insertSubview:annotationView atIndex:0];
}
@@ -4612,7 +4625,7 @@ public:
continue;
}
}
-
+
bool annotationViewIsVisible = CGRectContainsRect(viewPort, annotationView.frame);
if (!annotationViewIsVisible && annotationContext.viewReuseIdentifier)
{
@@ -4623,18 +4636,18 @@ public:
annotationView.center = [self convertCoordinate:annotationContext.annotation.coordinate toPointToView:self];
}
}
-
+
[CATransaction commit];
}
- (void)enqueueAnnotationViewForAnnotationContext:(MGLAnnotationContext &)annotationContext
{
MGLAnnotationView *annotationView = annotationContext.annotationView;
-
+
if (!annotationView) return;
-
+
annotationView.annotation = nil;
-
+
if (annotationContext.viewReuseIdentifier)
{
NSMutableArray *annotationViewReuseQueue = [self annotationViewReuseQueueForIdentifier:annotationContext.viewReuseIdentifier];
@@ -4664,7 +4677,7 @@ public:
{
userPoint = [self convertCoordinate:self.userLocation.coordinate toPointToView:self];
}
-
+
if ( ! annotationView.superview)
{
[self.glView addSubview:annotationView];
@@ -4693,10 +4706,10 @@ public:
annotationView.center = userPoint;
} completion:NULL];
_userLocationAnimationCompletionDate = [NSDate dateWithTimeIntervalSinceNow:duration];
-
+
annotationView.hidden = NO;
[annotationView update];
-
+
if (_userLocationAnnotationIsSelected)
{
// Ensure the callout view still points to its annotation.
@@ -4715,7 +4728,7 @@ public:
// User has moved far enough outside of the viewport that showing it or
// its callout would be useless.
annotationView.hidden = YES;
-
+
if (_userLocationAnnotationIsSelected)
{
[self deselectAnnotation:self.selectedAnnotation animated:YES];
@@ -4733,7 +4746,7 @@ public:
contentFrame = self.contentFrame;
}
CGPoint center = CGPointMake(CGRectGetMidX(contentFrame), CGRectGetMidY(contentFrame));
-
+
// When tracking course, it’s more important to see the road ahead, so
// weight the user dot down towards the bottom.
switch (self.userLocationVerticalAlignment) {
@@ -4746,7 +4759,7 @@ public:
center.y = CGRectGetMaxY(contentFrame);
break;
}
-
+
return center;
}
@@ -4755,7 +4768,7 @@ public:
CLLocationDirection direction = self.direction;
CLLocationDirection plateDirection = mbgl::util::wrap(-direction, 0., 360.);
self.compassView.transform = CGAffineTransformMakeRotation(MGLRadiansFromDegrees(plateDirection));
-
+
self.compassView.isAccessibilityElement = direction > 0;
self.compassView.accessibilityValue = [_accessibilityCompassFormatter stringFromDirection:direction];
@@ -4795,7 +4808,7 @@ public:
[NSException raise:@"Resource not found" format:
@"The resource named “%@” could not be found in the Mapbox framework bundle.", imageName];
}
-
+
return [UIImage imageWithContentsOfFile:path];
}
@@ -4912,7 +4925,7 @@ public:
{
_annotationViewReuseQueueByIdentifier[identifier] = [NSMutableArray array];
}
-
+
return _annotationViewReuseQueueByIdentifier[identifier];
}
@@ -5114,7 +5127,7 @@ public:
MGLCustomStyleLayerDrawingHandler d,
MGLCustomStyleLayerCompletionHandler f)
: prepare(p), draw(d), finish(f) {}
-
+
MGLCustomStyleLayerPreparationHandler prepare;
MGLCustomStyleLayerDrawingHandler draw;
MGLCustomStyleLayerCompletionHandler finish;
diff --git a/platform/ios/src/MGLMapViewDelegate.h b/platform/ios/src/MGLMapViewDelegate.h
index ea9933f870..777af4ba63 100644
--- a/platform/ios/src/MGLMapViewDelegate.h
+++ b/platform/ios/src/MGLMapViewDelegate.h
@@ -126,6 +126,23 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (void)mapViewDidFinishRenderingFrame:(MGLMapView *)mapView fullyRendered:(BOOL)fullyRendered;
+/**
+ Tells the delegate that the map has just finished loading a style.
+
+ This method is called during the initialization of the map view and after any
+ subsequent loading of a new style. This method is called between the
+ `-mapViewWillStartRenderingMap:` and `-mapViewDidFinishRenderingMap:` delegate
+ methods. Changes to sources or layers of the current style do not cause this
+ method to be called.
+
+ This method is the earliest opportunity to modify the layout or appearance of
+ the current style before the map view is displayed to the user.
+
+ @param mapView The map view that has just loaded a style.
+ @param style The style that was loaded.
+ */
+- (void)mapView:(MGLMapView *)mapView didFinishLoadingStyle:(MGLStyle *)style;
+
#pragma mark Tracking User Location
/**
@@ -211,17 +228,7 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (nullable MGLAnnotationImage *)mapView:(MGLMapView *)mapView imageForAnnotation:(id <MGLAnnotation>)annotation;
-/**
- Returns the alpha value to use when rendering a shape annotation.
-
- A value of `0.0` results in a completely transparent shape. A value of `1.0`,
- the default, results in a completely opaque shape.
-
- @param mapView The map view rendering the shape annotation.
- @param annotation The annotation being rendered.
- @return An alpha value between `0` and `1.0`.
- */
-- (CGFloat)mapView:(MGLMapView *)mapView alphaForShapeAnnotation:(MGLShape *)annotation;
+- (CGFloat)mapView:(MGLMapView *)mapView alphaForShapeAnnotation:(MGLShape *)annotation __attribute__((deprecated("Use -mapView:strokeColorForShapeAnnotation: or -mapView:fillColorForPolygonAnnotation:.")));
/**
Returns the color to use when rendering the outline of a shape annotation.
@@ -229,6 +236,9 @@ NS_ASSUME_NONNULL_BEGIN
The default stroke color is the map view’s tint color. If a pattern color is
specified, the result is undefined.
+ Opacity may be set by specifying an alpha component. The default alpha value is
+ `1.0` and results in a completely opaque stroke.
+
@param mapView The map view rendering the shape annotation.
@param annotation The annotation being rendered.
@return A color to use for the shape outline.
@@ -241,6 +251,9 @@ NS_ASSUME_NONNULL_BEGIN
The default fill color is the map view’s tint color. If a pattern color is
specified, the result is undefined.
+ Opacity may be set by specifying an alpha component. The default alpha value is
+ `1.0` and results in a completely opaque shape.
+
@param mapView The map view rendering the polygon annotation.
@param annotation The annotation being rendered.
@return The polygon’s interior fill color.
diff --git a/platform/ios/src/MGLMapboxEvents.m b/platform/ios/src/MGLMapboxEvents.m
index 53b917f701..15b78b65ae 100644
--- a/platform/ios/src/MGLMapboxEvents.m
+++ b/platform/ios/src/MGLMapboxEvents.m
@@ -208,7 +208,7 @@ const NSTimeInterval MGLFlushInterval = 180;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(userDefaultsDidChange:) name:NSUserDefaultsDidChangeNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pauseOrResumeMetricsCollectionIfRequired) name:UIApplicationDidEnterBackgroundNotification object:nil];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pauseOrResumeMetricsCollectionIfRequired) name:UIApplicationWillEnterForegroundNotification object:nil];
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pauseOrResumeMetricsCollectionIfRequired) name:UIApplicationDidBecomeActiveNotification object:nil];
// Watch for Low Power Mode change events
if (&NSProcessInfoPowerStateDidChangeNotification != NULL) {
diff --git a/platform/ios/src/Mapbox.h b/platform/ios/src/Mapbox.h
index 535e00e01e..04892eb6a1 100644
--- a/platform/ios/src/Mapbox.h
+++ b/platform/ios/src/Mapbox.h
@@ -33,7 +33,8 @@ FOUNDATION_EXPORT const unsigned char MapboxVersionString[];
#import "MGLShapeCollection.h"
#import "MGLStyle.h"
#import "MGLStyleLayer.h"
-#import "MGLBaseStyleLayer.h"
+#import "MGLForegroundStyleLayer.h"
+#import "MGLVectorStyleLayer.h"
#import "MGLFillStyleLayer.h"
#import "MGLLineStyleLayer.h"
#import "MGLSymbolStyleLayer.h"
@@ -49,11 +50,5 @@ FOUNDATION_EXPORT const unsigned char MapboxVersionString[];
#import "MGLUserLocation.h"
#import "MGLUserLocationAnnotationView.h"
#import "NSValue+MGLAdditions.h"
-#import "MGLStyleAttributeValue.h"
-#import "MGLStyleAttributeFunction.h"
-#import "UIColor+MGLStyleAttributeAdditions.h"
-#import "NSNumber+MGLStyleAttributeAdditions.h"
-#import "NSValue+MGLStyleAttributeAdditions.h"
-#import "NSString+MGLStyleAttributeAdditions.h"
-#import "NSArray+MGLStyleAttributeAdditions.h"
+#import "MGLStyleValue.h"
#import "MGLTileSet.h"
diff --git a/platform/ios/src/UIColor+MGLAdditions.h b/platform/ios/src/UIColor+MGLAdditions.h
index 7cc291c657..ea415d9db9 100644
--- a/platform/ios/src/UIColor+MGLAdditions.h
+++ b/platform/ios/src/UIColor+MGLAdditions.h
@@ -5,10 +5,10 @@
@interface UIColor (MGLAdditions)
-- (mbgl::Color)mbgl_color;
+- (mbgl::Color)mgl_color;
-- (mbgl::style::PropertyValue<mbgl::Color>)mbgl_colorPropertyValue;
+- (mbgl::style::PropertyValue<mbgl::Color>)mgl_colorPropertyValue;
-+ (UIColor *)mbgl_colorWithColor:(mbgl::Color)color;
++ (UIColor *)mgl_colorWithColor:(mbgl::Color)color;
@end
diff --git a/platform/ios/src/UIColor+MGLAdditions.mm b/platform/ios/src/UIColor+MGLAdditions.mm
index 5a4b4b49f3..41c066c206 100644
--- a/platform/ios/src/UIColor+MGLAdditions.mm
+++ b/platform/ios/src/UIColor+MGLAdditions.mm
@@ -1,24 +1,21 @@
#import "UIColor+MGLAdditions.h"
-#import "MGLStyleAttributeValue.h"
-#import "MGLStyleAttributeValue_Private.h"
-
@implementation UIColor (MGLAdditions)
-- (mbgl::Color)mbgl_color
+- (mbgl::Color)mgl_color
{
CGFloat r, g, b, a;
[self getRed:&r green:&g blue:&b alpha:&a];
return { (float)r, (float)g, (float)b, (float)a };
}
-- (mbgl::style::PropertyValue<mbgl::Color>)mbgl_colorPropertyValue
+- (mbgl::style::PropertyValue<mbgl::Color>)mgl_colorPropertyValue
{
- mbgl::Color color = self.mbgl_color;
+ mbgl::Color color = self.mgl_color;
return {{ color.r, color.g, color.b, color.a }};
}
-+ (UIColor *)mbgl_colorWithColor:(mbgl::Color)color
++ (UIColor *)mgl_colorWithColor:(mbgl::Color)color
{
return [UIColor colorWithRed:color.r green:color.g blue:color.b alpha:color.a];
}
diff --git a/platform/ios/src/UIColor+MGLStyleAttributeAdditions.h b/platform/ios/src/UIColor+MGLStyleAttributeAdditions.h
deleted file mode 100644
index 3637ceab6c..0000000000
--- a/platform/ios/src/UIColor+MGLStyleAttributeAdditions.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#import <UIKit/UIKit.h>
-
-#import "MGLStyleAttributeValue.h"
-
-@interface UIColor (MGLStyleAttributeAdditions) <MGLStyleAttributeValue>
-
-@end
diff --git a/platform/ios/src/UIColor+MGLStyleAttributeAdditions.mm b/platform/ios/src/UIColor+MGLStyleAttributeAdditions.mm
deleted file mode 100644
index 5a9ac3afe9..0000000000
--- a/platform/ios/src/UIColor+MGLStyleAttributeAdditions.mm
+++ /dev/null
@@ -1,14 +0,0 @@
-#import "UIColor+MGLStyleAttributeAdditions.h"
-
-#import "MGLStyleAttributeValue.h"
-#import "MGLStyleAttributeValue_Private.h"
-#import "UIColor+MGLAdditions.h"
-
-@implementation UIColor (MGLStyleAttributeAdditions)
-
-- (BOOL)isFunction
-{
- return NO;
-}
-
-@end
diff --git a/platform/ios/src/UIImage+MGLAdditions.h b/platform/ios/src/UIImage+MGLAdditions.h
new file mode 100644
index 0000000000..411220c503
--- /dev/null
+++ b/platform/ios/src/UIImage+MGLAdditions.h
@@ -0,0 +1,9 @@
+#import <UIKit/UIKit.h>
+
+#include <mbgl/sprite/sprite_image.hpp>
+
+@interface UIImage (MGLAdditions)
+
+- (std::unique_ptr<mbgl::SpriteImage>)mgl_spriteImage;
+
+@end
diff --git a/platform/ios/src/UIImage+MGLAdditions.mm b/platform/ios/src/UIImage+MGLAdditions.mm
new file mode 100644
index 0000000000..8ec8f9e15f
--- /dev/null
+++ b/platform/ios/src/UIImage+MGLAdditions.mm
@@ -0,0 +1,27 @@
+#import "UIImage+MGLAdditions.h"
+
+@implementation UIImage (MGLAdditions)
+
+- (std::unique_ptr<mbgl::SpriteImage>)mgl_spriteImage
+{
+ CGImageRef cgImage = self.CGImage;
+ size_t width = CGImageGetWidth(cgImage);
+ size_t height = CGImageGetHeight(cgImage);
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+ mbgl::PremultipliedImage cPremultipliedImage(width, height);
+ size_t bytesPerPixel = 4;
+ size_t bytesPerRow = bytesPerPixel * width;
+ size_t bitsPerComponent = 8;
+
+ CGContextRef context = CGBitmapContextCreate(cPremultipliedImage.data.get(),
+ width, height, bitsPerComponent, bytesPerRow,
+ colorSpace, kCGImageAlphaPremultipliedLast);
+
+ CGContextDrawImage(context, CGRectMake(0, 0, width, height), cgImage);
+ CGContextRelease(context);
+ CGColorSpaceRelease(colorSpace);
+
+ return std::make_unique<mbgl::SpriteImage>(std::move(cPremultipliedImage), float(self.scale));
+}
+
+@end
diff --git a/platform/ios/test/MGLGeoJSONSourceTests.mm b/platform/ios/test/MGLGeoJSONSourceTests.mm
index 76353dc76b..40d8067985 100644
--- a/platform/ios/test/MGLGeoJSONSourceTests.mm
+++ b/platform/ios/test/MGLGeoJSONSourceTests.mm
@@ -1,11 +1,18 @@
#import <XCTest/XCTest.h>
#import <Mapbox/Mapbox.h>
+#import "MGLFeature_Private.h"
#import "MGLGeoJSONSource_Private.h"
+#import "MGLSource_Private.h"
#include <mbgl/style/sources/geojson_source.hpp>
@interface MGLGeoJSONSourceTests : XCTestCase
+@end
+
+@interface MGLPolygonFeature (Test)
+
+@property (nonatomic, copy, readwrite) NS_DICTIONARY_OF(NSString *, id) *attributes;
@end
@@ -20,7 +27,7 @@
MGLGeoJSONMaximumZoomLevelOption: @99,
MGLGeoJSONBufferOption: @1976,
MGLGeoJSONToleranceOption: @0.42};
- MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithSourceIdentifier:@"source-id" URL:url options:options];
+ MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"source-id" URL:url options:options];
auto mbglOptions = [source geoJSONOptions];
XCTAssertTrue(mbglOptions.cluster);
@@ -30,10 +37,261 @@
XCTAssertEqual(mbglOptions.buffer, 1976);
XCTAssertEqual(mbglOptions.tolerance, 0.42);
- // when the supplied option cluster value is not of the correct type
options = @{MGLGeoJSONClusterOption: @"number 1"};
- source = [[MGLGeoJSONSource alloc] initWithSourceIdentifier:@"source-id" URL:url options:options];
+ source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"source-id" URL:url options:options];
XCTAssertThrows([source geoJSONOptions]);
}
+- (void)testMGLGeoJSONSourceWithData {
+
+ NSString *geoJSON = @"{\"type\": \"FeatureCollection\",\"features\": [{\"type\": \"Feature\",\"properties\": {},\"geometry\": {\"type\": \"LineString\",\"coordinates\": [[-107.75390625,40.329795743702064],[-104.34814453125,37.64903402157866]]}}]}";
+
+ NSData *data = [geoJSON dataUsingEncoding:NSUTF8StringEncoding];
+ MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"source-id" geoJSONData:data options:nil];
+
+ [source mbglSource];
+
+ XCTAssertNotNil(source.features);
+ XCTAssertEqual(source.features.count, 1);
+ XCTAssertTrue([source.features.firstObject isMemberOfClass:[MGLPolylineFeature class]]);
+}
+
+- (void)testMGLGeoJSONSourceWithPolylineFeatures {
+ CLLocationCoordinate2D coordinates[] = { CLLocationCoordinate2DMake(0, 0), CLLocationCoordinate2DMake(10, 10)};
+ MGLPolylineFeature *polylineFeature = [MGLPolylineFeature polylineWithCoordinates:coordinates count:2];
+
+ MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"source-id" features:@[polylineFeature] options:nil];
+
+ std::unique_ptr<mbgl::style::Source> mbglSource = [source mbglSource];
+
+ XCTAssertNotNil(source.features);
+ XCTAssertEqual(source.features.count, 1);
+ XCTAssertTrue([source.features.firstObject isMemberOfClass:[MGLPolylineFeature class]]);
+}
+
+- (void)testMGLGeoJSONSourceWithPolygonFeatures {
+ CLLocationCoordinate2D coordinates[] = {
+ CLLocationCoordinate2DMake(100.0, 0.0),
+ CLLocationCoordinate2DMake(101.0, 0.0),
+ CLLocationCoordinate2DMake(101.0, 1.0),
+ CLLocationCoordinate2DMake(100.0, 1.0),
+ CLLocationCoordinate2DMake(100.0, 0.0)};
+
+ MGLPolygonFeature<MGLFeaturePrivate> *polygonFeature = (MGLPolygonFeature<MGLFeaturePrivate> *)[MGLPolygonFeature polygonWithCoordinates:coordinates count:5];
+ polygonFeature.identifier = @"feature-id";
+ NSString *stringAttribute = @"string";
+ NSNumber *boolAttribute = [NSNumber numberWithBool:YES];
+ NSNumber *doubleAttribute = [NSNumber numberWithDouble:1.23];
+ NSDictionary *nestedDictionaryValue = @{@"nested-key-1": @"nested-string-value"};
+ NSArray *arrayValue = @[@"string-value", @2];
+ NSDictionary *dictionaryValue = @{@"key-1": @"string-value",
+ @"key-2": @1,
+ @"key-3": nestedDictionaryValue,
+ @"key-4": arrayValue};
+ NSArray *arrayOfArrays = @[@[@1, @"string-value", @[@"jagged"]]];
+ NSArray *arrayOfDictionaries = @[@{@"key": @"value"}];
+
+ polygonFeature.attributes = @{@"name": stringAttribute,
+ @"bool": boolAttribute,
+ @"double": doubleAttribute,
+ @"dictionary-attribute": dictionaryValue,
+ @"array-attribute": arrayValue,
+ @"array-of-array-attribute": arrayOfArrays,
+ @"array-of-dictionary-attribute": arrayOfDictionaries};
+
+ MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"source-id" features:@[polygonFeature] options:nil];
+
+ std::unique_ptr<mbgl::style::Source> mbglSource = [source mbglSource];
+
+ XCTAssertNotNil(source.features);
+ XCTAssertEqual(source.features.count, 1);
+ MGLPolygonFeature *expectedPolygonFeature = (MGLPolygonFeature *)source.features.firstObject;
+ XCTAssertTrue([expectedPolygonFeature isMemberOfClass:[MGLPolygonFeature class]]);
+ XCTAssertEqualObjects(expectedPolygonFeature.identifier, polygonFeature.identifier);
+ XCTAssertEqualObjects(expectedPolygonFeature.attributes[@"name"], stringAttribute);
+ XCTAssertEqualObjects(expectedPolygonFeature.attributes[@"bool"], boolAttribute);
+ XCTAssertEqualObjects(expectedPolygonFeature.attributes[@"double"], doubleAttribute);
+ XCTAssertEqualObjects(expectedPolygonFeature.attributes[@"dictionary-attribute"], dictionaryValue);
+ XCTAssertEqualObjects(expectedPolygonFeature.attributes[@"array-attribute"], arrayValue);
+ XCTAssertEqualObjects(expectedPolygonFeature.attributes[@"array-of-array-attribute"], arrayOfArrays);
+ XCTAssertEqualObjects(expectedPolygonFeature.attributes[@"array-of-dictionary-attribute"], arrayOfDictionaries);
+}
+
+- (void)testMGLGeoJSONSourceWithPolygonFeaturesInculdingInteriorPolygons {
+ CLLocationCoordinate2D coordinates[] = {
+ CLLocationCoordinate2DMake(100.0, 0.0),
+ CLLocationCoordinate2DMake(101.0, 0.0),
+ CLLocationCoordinate2DMake(101.0, 1.0),
+ CLLocationCoordinate2DMake(100.0, 1.0),
+ CLLocationCoordinate2DMake(100.0, 0.0)};
+
+ CLLocationCoordinate2D interiorCoordinates[] = {
+ CLLocationCoordinate2DMake(100.2, 0.2),
+ CLLocationCoordinate2DMake(100.8, 0.2),
+ CLLocationCoordinate2DMake(100.8, 0.8),
+ CLLocationCoordinate2DMake(100.2, 0.8),
+ CLLocationCoordinate2DMake(100.2, 0.2)};
+
+ MGLPolygon *polygon = [MGLPolygon polygonWithCoordinates:interiorCoordinates count:5];
+
+ MGLPolygonFeature *polygonFeature = [MGLPolygonFeature polygonWithCoordinates:coordinates count:5 interiorPolygons:@[polygon]];
+
+ MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"source-id" features:@[polygonFeature] options:nil];
+
+ std::unique_ptr<mbgl::style::Source> mbglSource = [source mbglSource];
+
+ XCTAssertNotNil(source.features);
+ XCTAssertEqual(source.features.count, 1);
+ XCTAssertTrue([source.features.firstObject isMemberOfClass:[MGLPolygonFeature class]]);
+}
+
+
+- (void)testMGLGeoJSONSourceWithMultiPointFeaturesUsingPolylines {
+ CLLocationCoordinate2D coordinates[] = {
+ CLLocationCoordinate2DMake(100.0, 0.0),
+ CLLocationCoordinate2DMake(101.0, 0.0),
+ CLLocationCoordinate2DMake(101.0, 1.0),
+ CLLocationCoordinate2DMake(100.0, 1.0),
+ CLLocationCoordinate2DMake(100.0, 0.0)};
+
+ MGLMultiPointFeature *multiPointFeature = [MGLMultiPointFeature multiPointWithCoordinates:coordinates count:5];
+
+ MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"source-id" features:@[multiPointFeature] options:nil];
+
+ std::unique_ptr<mbgl::style::Source> mbglSource = [source mbglSource];
+
+ XCTAssertNotNil(source.features);
+ XCTAssertEqual(source.features.count, 1);
+ XCTAssertTrue([source.features.firstObject isMemberOfClass:[MGLMultiPointFeature class]]);
+}
+
+- (void)testMGLGeoJSONSourceWithMultiPointFeaturesUsingPolygons {
+ CLLocationCoordinate2D coordinates[] = {
+ CLLocationCoordinate2DMake(100.0, 0.0),
+ CLLocationCoordinate2DMake(101.0, 0.0),
+ CLLocationCoordinate2DMake(101.0, 1.0),
+ CLLocationCoordinate2DMake(100.0, 1.0),
+ CLLocationCoordinate2DMake(100.0, 0.0)};
+
+ CLLocationCoordinate2D interiorCoordinates[] = {
+ CLLocationCoordinate2DMake(100.2, 0.2),
+ CLLocationCoordinate2DMake(100.8, 0.2),
+ CLLocationCoordinate2DMake(100.8, 0.8),
+ CLLocationCoordinate2DMake(100.2, 0.8),
+ CLLocationCoordinate2DMake(100.2, 0.2)};
+
+ MGLPolygon *polygon = [MGLPolygon polygonWithCoordinates:interiorCoordinates count:5];
+
+ MGLMultiPointFeature *multiPointFeature = (MGLMultiPointFeature *)[MGLPolygonFeature polygonWithCoordinates:coordinates count:5 interiorPolygons:@[polygon]];
+
+ MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"source-id" features:@[multiPointFeature] options:nil];
+
+ std::unique_ptr<mbgl::style::Source> mbglSource = [source mbglSource];
+
+ XCTAssertNotNil(source.features);
+ XCTAssertEqual(source.features.count, 1);
+ XCTAssertTrue([source.features.firstObject isMemberOfClass:[MGLPolygonFeature class]]);
+}
+
+- (void)testMGLGeoJSONSourceWithMultiPolylineFeatures {
+ CLLocationCoordinate2D firstCoordinates[] = { CLLocationCoordinate2DMake(0, 0), CLLocationCoordinate2DMake(10, 10)};
+ MGLPolylineFeature *firstPolylineFeature = [MGLPolylineFeature polylineWithCoordinates:firstCoordinates count:2];
+ CLLocationCoordinate2D secondCoordinates[] = { CLLocationCoordinate2DMake(0, 0), CLLocationCoordinate2DMake(10, 10)};
+ MGLPolylineFeature *secondPolylineFeature = [MGLPolylineFeature polylineWithCoordinates:secondCoordinates count:2];
+ MGLMultiPolylineFeature *multiPolylineFeature = [MGLMultiPolylineFeature multiPolylineWithPolylines:@[firstPolylineFeature, secondPolylineFeature]];
+
+ MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"source-id" features:@[multiPolylineFeature] options:nil];
+
+ std::unique_ptr<mbgl::style::Source> mbglSource = [source mbglSource];
+
+ XCTAssertNotNil(source.features);
+ XCTAssertEqual(source.features.count, 1);
+ XCTAssertTrue([source.features.firstObject isMemberOfClass:[MGLMultiPolylineFeature class]]);
+}
+
+- (void)testMGLGeoJSONSourceWithMultiPolygonFeatures {
+ CLLocationCoordinate2D coordinates[] = {
+ CLLocationCoordinate2DMake(100.0, 0.0),
+ CLLocationCoordinate2DMake(101.0, 0.0),
+ CLLocationCoordinate2DMake(101.0, 1.0),
+ CLLocationCoordinate2DMake(100.0, 1.0),
+ CLLocationCoordinate2DMake(100.0, 0.0)};
+
+ CLLocationCoordinate2D interiorCoordinates[] = {
+ CLLocationCoordinate2DMake(100.2, 0.2),
+ CLLocationCoordinate2DMake(100.8, 0.2),
+ CLLocationCoordinate2DMake(100.8, 0.8),
+ CLLocationCoordinate2DMake(100.2, 0.8),
+ CLLocationCoordinate2DMake(100.2, 0.2)};
+
+ MGLPolygon *polygon = [MGLPolygon polygonWithCoordinates:interiorCoordinates count:5];
+
+ MGLPolygonFeature *firstPolygon = [MGLPolygonFeature polygonWithCoordinates:coordinates count:5 interiorPolygons:@[polygon]];
+ MGLPolygonFeature *secondPolygon = [MGLPolygonFeature polygonWithCoordinates:coordinates count:5 interiorPolygons:@[polygon]];
+
+ MGLMultiPolygonFeature *multiPolygonFeature = [MGLMultiPolygonFeature multiPolygonWithPolygons:@[firstPolygon, secondPolygon]];
+
+ MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"source-id" features:@[multiPolygonFeature] options:nil];
+
+ std::unique_ptr<mbgl::style::Source> mbglSource = [source mbglSource];
+
+ XCTAssertNotNil(source.features);
+ XCTAssertEqual(source.features.count, 1);
+ XCTAssertTrue([source.features.firstObject isMemberOfClass:[MGLMultiPolygonFeature class]]);
+
+}
+
+- (void)testMGLGeoJSONSourceWithPointFeature {
+ MGLPointFeature *pointFeature = [MGLPointFeature new];
+ pointFeature.coordinate = CLLocationCoordinate2DMake(100.2, 0.2);
+
+ MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"souce-id" features:@[pointFeature] options:nil];
+
+ std::unique_ptr<mbgl::style::Source> mbglSource = [source mbglSource];
+
+ XCTAssertNotNil(source.features);
+ XCTAssertEqual(source.features.count, 1);
+ XCTAssertTrue([source.features.firstObject isMemberOfClass:[MGLPointFeature class]]);
+}
+
+- (void)testMGLGeoJSONSourceWithShapeCollectionFeatures {
+ CLLocationCoordinate2D coordinates[] = {
+ CLLocationCoordinate2DMake(100.0, 0.0),
+ CLLocationCoordinate2DMake(101.0, 0.0),
+ CLLocationCoordinate2DMake(101.0, 1.0),
+ CLLocationCoordinate2DMake(100.0, 1.0),
+ CLLocationCoordinate2DMake(100.0, 0.0)};
+
+ CLLocationCoordinate2D interiorCoordinates[] = {
+ CLLocationCoordinate2DMake(100.2, 0.2),
+ CLLocationCoordinate2DMake(100.8, 0.2),
+ CLLocationCoordinate2DMake(100.8, 0.8),
+ CLLocationCoordinate2DMake(100.2, 0.8),
+ CLLocationCoordinate2DMake(100.2, 0.2)};
+
+ MGLPolygon *polygon = [MGLPolygon polygonWithCoordinates:interiorCoordinates count:5];
+
+ MGLPolygonFeature *polygonFeature = [MGLPolygonFeature polygonWithCoordinates:coordinates count:5 interiorPolygons:@[polygon]];
+
+ CLLocationCoordinate2D coordinates_2[] = { CLLocationCoordinate2DMake(0, 0), CLLocationCoordinate2DMake(10, 10)};
+ MGLPolylineFeature *polylineFeature = [MGLPolylineFeature polylineWithCoordinates:coordinates_2 count:2];
+
+ MGLMultiPolygonFeature *multiPolygonFeature = [MGLMultiPolygonFeature multiPolygonWithPolygons:@[polygonFeature, polygonFeature]];
+
+ MGLMultiPolylineFeature *multiPolylineFeature = [MGLMultiPolylineFeature multiPolylineWithPolylines:@[polylineFeature, polylineFeature]];
+
+ MGLMultiPointFeature *multiPointFeature = (MGLMultiPointFeature *)[MGLPolygonFeature polygonWithCoordinates:coordinates count:5 interiorPolygons:@[polygon]];
+
+ MGLPointFeature *pointFeature = [MGLPointFeature new];
+ pointFeature.coordinate = CLLocationCoordinate2DMake(100.2, 0.2);
+
+ MGLShapeCollectionFeature *shapeCollectionFeature = [MGLShapeCollectionFeature shapeCollectionWithShapes:@[polygonFeature, polylineFeature, multiPolygonFeature, multiPolylineFeature, multiPointFeature, pointFeature]];
+
+ MGLShapeCollectionFeature *shapeCollectionFeature_1 = [MGLShapeCollectionFeature shapeCollectionWithShapes:@[polygonFeature, polylineFeature, multiPolygonFeature, multiPolylineFeature, multiPointFeature, pointFeature, shapeCollectionFeature]];
+
+ MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"" features:@[shapeCollectionFeature_1] options:nil];
+
+ XCTAssertThrowsSpecificNamed([source mbglSource], NSException, @"Method unavailable");
+}
+
@end
diff --git a/platform/ios/test/MGLNSDataAdditionsTests.m b/platform/ios/test/MGLNSDataAdditionsTests.m
index 38f19a9703..b01db25812 100644
--- a/platform/ios/test/MGLNSDataAdditionsTests.m
+++ b/platform/ios/test/MGLNSDataAdditionsTests.m
@@ -7,10 +7,6 @@
@implementation MGLNSDataAdditionsTests
-- (void)setUp {
- [super setUp];
-}
-
- (void)testCompressDecompress
{
NSArray *originalArray = [self mockDataWithCount:180];
diff --git a/platform/ios/vendor/SMCalloutView b/platform/ios/vendor/SMCalloutView
-Subproject 2aede5d8d1577101bf18405246220e7a710df60
+Subproject d6ecaba377c9f963aef630faf86e3b8f8cdb88d
diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md
index e23d0199e9..5d58bafd79 100644
--- a/platform/macos/CHANGELOG.md
+++ b/platform/macos/CHANGELOG.md
@@ -2,32 +2,49 @@
## master
+### Packaging
+
* Fixed an issue causing code signing failures and bloating the framework. ([#5850](https://github.com/mapbox/mapbox-gl-native/pull/5850))
* Xcode 7.3 or higher is now required for using this SDK. ([#6059](https://github.com/mapbox/mapbox-gl-native/issues/6059))
-* A new runtime styling API allows you to adjust the style and content of the base map dynamically. All the options available in [Mapbox Studio](https://www.mapbox.com/studio/) are now exposed via MGLStyle and subclasses of MGLStyleLayer and MGLSource. ([#5727](https://github.com/mapbox/mapbox-gl-native/pull/5727))
* Fixed an issue with symbols not being properly stripped from the dynamic framework when built with `make xpackage SYMBOLS=NO`. ([#6531](https://github.com/mapbox/mapbox-gl-native/pull/6531))
-* Added `showAnnotations:animated:` and `showAnnotations:edgePadding:animated:`, which moves the map viewport to show the specified annotations. ([#5749](https://github.com/mapbox/mapbox-gl-native/pull/5749))
-* Fixed an issue where the map view’s center would always be calculated as if the view occupied the entire window. ([#6102](https://github.com/mapbox/mapbox-gl-native/pull/6102))
-* MGLPolyline annotations and the exterior coordinates of MGLPolygon annotations are now able to be mutated, part or all, and changes are displayed immediately. ([#6565](https://github.com/mapbox/mapbox-gl-native/pull/6565))
-* To make an MGLPolyline or MGLPolygon span the antimeridian, specify coordinates with longitudes greater than 180° or less than −180°. ([#6088](https://github.com/mapbox/mapbox-gl-native/pull/6088))
+
+### Styles and data
+
+* A new runtime styling API allows you to adjust the style and content of the base map dynamically. All the options available in [Mapbox Studio](https://www.mapbox.com/studio/) are now exposed via MGLStyle and subclasses of MGLStyleLayer and MGLSource. ([#5727](https://github.com/mapbox/mapbox-gl-native/pull/5727))
* MGLMapView’s `styleURL` property can now be set to an absolute file URL. ([#6026](https://github.com/mapbox/mapbox-gl-native/pull/6026))
* GeoJSON sources specified by the stylesheet at design time now support `cluster`, `clusterMaxZoom`, and `clusterRadius` attributes for clustering point features on the base map. ([#5724](https://github.com/mapbox/mapbox-gl-native/pull/5724))
* TileJSON manifests can now specify `"scheme": "tms"` to indicate the use of [TMS](https://en.wikipedia.org/wiki/Tile_Map_Service) coordinates. ([#2270](https://github.com/mapbox/mapbox-gl-native/pull/2270))
* Fixed rendering artifacts and missing glyphs that occurred after viewing a large number of CJK characters on the map. ([#5908](https://github.com/mapbox/mapbox-gl-native/pull/5908))
-* Improved the precision of annotations at zoom levels greater than 18. ([#5517](https://github.com/mapbox/mapbox-gl-native/pull/5517))
-* Fixed an issue preventing an MGLMapView from loading tiles while an offline pack is downloading. ([#6446](https://github.com/mapbox/mapbox-gl-native/pull/6446))
* Fixed an issue where the style zoom levels were not respected when deciding when to render a layer. ([#5811](https://github.com/mapbox/mapbox-gl-native/issues/5811))
-* Fixed an issue causing an MGLOfflinePack’s progress to continue to update after calling `-suspend`. ([#6186](https://github.com/mapbox/mapbox-gl-native/pull/6186))
-* Fixed an issue preventing cached annotation images from displaying while the device is offline. ([#6358](https://github.com/mapbox/mapbox-gl-native/pull/6358))
* If MGLMapView is unable to obtain or parse a style, it now calls its delegate’s `-mapViewDidFailLoadingMap:withError:` method. ([#6145](https://github.com/mapbox/mapbox-gl-native/pull/6145))
+* Added the `-[MGLMapViewDelegate mapView:didFinishLoadingStyle:]` delegate method, which offers the earliest opportunity to modify the layout or appearance of the current style before the map view is displayed to the user. ([#6636](https://github.com/mapbox/mapbox-gl-native/pull/6636))
* Fixed an issue causing stepwise zoom functions to be misinterpreted. ([#6328](https://github.com/mapbox/mapbox-gl-native/pull/6328))
* A source’s tiles are no longer rendered when the map is outside the source’s supported zoom levels. ([#6345](https://github.com/mapbox/mapbox-gl-native/pull/6345))
-* Fixed a crash that could occur when the device is disconnected while downloading an offline pack. ([#6293](https://github.com/mapbox/mapbox-gl-native/pull/6293))
* Fixed crashes that could occur when loading a malformed stylesheet. ([#5736](https://github.com/mapbox/mapbox-gl-native/pull/5736))
+* Improved style parsing performance. ([#6170](https://github.com/mapbox/mapbox-gl-native/pull/6170))
+* Improved feature querying performance. ([#6514](https://github.com/mapbox/mapbox-gl-native/pull/6514))
+
+### Annotations
+
+* Added `showAnnotations:animated:` and `showAnnotations:edgePadding:animated:`, which moves the map viewport to show the specified annotations. ([#5749](https://github.com/mapbox/mapbox-gl-native/pull/5749))
+* MGLPolyline annotations and the exterior coordinates of MGLPolygon annotations are now able to be mutated, part or all, and changes are displayed immediately. ([#6565](https://github.com/mapbox/mapbox-gl-native/pull/6565))
+* To make an MGLPolyline or MGLPolygon span the antimeridian, specify coordinates with longitudes greater than 180° or less than −180°. ([#6088](https://github.com/mapbox/mapbox-gl-native/pull/6088))
+* Improved the precision of annotations at zoom levels greater than 18. ([#5517](https://github.com/mapbox/mapbox-gl-native/pull/5517))
+* Deprecated `-[MGLMapViewDelegate mapView:alphaForShapeAnnotation:]` in favor of specifying an alpha component via `-[MGLMapViewDelegate mapView:strokeColorForShapeAnnotation:]` or `-[MGLMapViewDelegate mapView:fillColorForPolygonAnnotation:]`. ([#6706](https://github.com/mapbox/mapbox-gl-native/pull/6706))
+
+### Networking and offline maps
+
+* Fixed an issue preventing an MGLMapView from loading tiles while an offline pack is downloading. ([#6446](https://github.com/mapbox/mapbox-gl-native/pull/6446))
+* Fixed an issue causing an MGLOfflinePack’s progress to continue to update after calling `-suspend`. ([#6186](https://github.com/mapbox/mapbox-gl-native/pull/6186))
+* Fixed an issue preventing cached annotation images from displaying while the device is offline. ([#6358](https://github.com/mapbox/mapbox-gl-native/pull/6358))
+* Fixed a crash that could occur when the device is disconnected while downloading an offline pack. ([#6293](https://github.com/mapbox/mapbox-gl-native/pull/6293))
* Fixed a crash that occurred when encountering a rate-limit error in response to a network request. ([#6223](https://github.com/mapbox/mapbox-gl-native/pull/6223))
* Query parameters are no longer stripped from mapbox: URLs used as resource URLs. ([#6182](https://github.com/mapbox/mapbox-gl-native/pull/6182), [#6432](https://github.com/mapbox/mapbox-gl-native/pull/6432))
* Database errors are now logged to the console. ([#6291](https://github.com/mapbox/mapbox-gl-native/pull/6291))
-* Improved style parsing performance. ([#6170](https://github.com/mapbox/mapbox-gl-native/pull/6170))
+
+### Other changes
+
+* Fixed an issue where the map view’s center would always be calculated as if the view occupied the entire window. ([#6102](https://github.com/mapbox/mapbox-gl-native/pull/6102))
* Fixed a typo in the documentation for the MGLCompassDirectionFormatter class. ([#5879](https://github.com/mapbox/mapbox-gl-native/pull/5879))
## 0.2.1 - July 19, 2016
diff --git a/platform/macos/app/MapDocument.m b/platform/macos/app/MapDocument.m
index dfbf55a805..da8d56ee89 100644
--- a/platform/macos/app/MapDocument.m
+++ b/platform/macos/app/MapDocument.m
@@ -638,21 +638,20 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio
- (IBAction)manipulateStyle:(id)sender {
MGLFillStyleLayer *fillStyleLayer = (MGLFillStyleLayer *)[self.mapView.style layerWithIdentifier:@"water"];
- MGLStyleAttributeFunction *colorFunction = [[MGLStyleAttributeFunction alloc] init];
- colorFunction.stops = @{
- @0.0: [NSColor redColor],
- @10.0: [NSColor yellowColor],
- @20.0: [NSColor blackColor],
- };
+ MGLStyleValue *colorFunction = [MGLStyleValue<NSColor *> valueWithStops:@{
+ @0.0: [MGLStyleValue<NSColor *> valueWithRawValue:[NSColor redColor]],
+ @10.0: [MGLStyleValue<NSColor *> valueWithRawValue:[NSColor yellowColor]],
+ @20.0: [MGLStyleValue<NSColor *> valueWithRawValue:[NSColor blackColor]],
+ }];
fillStyleLayer.fillColor = colorFunction;
NSString *filePath = [[NSBundle bundleForClass:self.class] pathForResource:@"amsterdam" ofType:@"geojson"];
NSURL *geoJSONURL = [NSURL fileURLWithPath:filePath];
- MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithSourceIdentifier:@"ams" URL:geoJSONURL];
+ MGLGeoJSONSource *source = [[MGLGeoJSONSource alloc] initWithIdentifier:@"ams" URL:geoJSONURL options:nil];
[self.mapView.style addSource:source];
- MGLFillStyleLayer *fillLayer = [[MGLFillStyleLayer alloc] initWithLayerIdentifier:@"test" source:source];
- fillLayer.fillColor = [NSColor greenColor];
+ MGLFillStyleLayer *fillLayer = [[MGLFillStyleLayer alloc] initWithIdentifier:@"test" source:source];
+ fillLayer.fillColor = [MGLStyleValue<NSColor *> valueWithRawValue:[NSColor greenColor]];
fillLayer.predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"type", @"park"];
[self.mapView.style addLayer:fillLayer];
}
@@ -970,18 +969,19 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio
}
}
-- (CGFloat)mapView:(MGLMapView *)mapView alphaForShapeAnnotation:(MGLShape *)annotation {
- return ([annotation isKindOfClass:[ProgressPolyline class]] ? 0.75: 0.5);
-}
-
- (NSColor *)mapView:(MGLMapView *)mapView strokeColorForShapeAnnotation:(MGLShape *)annotation {
- return ([annotation isKindOfClass:[ProgressPolyline class]] ? [NSColor yellowColor] : [NSColor darkGrayColor]);
+ return ([annotation isKindOfClass:[ProgressPolyline class]] ? [[NSColor yellowColor] colorWithAlphaComponent:0.75] : [[NSColor darkGrayColor] colorWithAlphaComponent:0.5]);
}
- (CGFloat)mapView:(MGLMapView *)mapView lineWidthForPolylineAnnotation:(MGLPolyline *)annotation {
return ([annotation isKindOfClass:[ProgressPolyline class]] ? 6 : 8);
}
+- (NSColor *)mapView:(MGLMapView *)mapView fillColorForPolygonAnnotation:(MGLPolygon *)annotation {
+ NSColor *color = [[NSColor selectedMenuItemColor] colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
+ return [color colorWithAlphaComponent:0.8];
+}
+
@end
@interface ValidatedToolbarItem : NSToolbarItem
diff --git a/platform/macos/bitrise.yml b/platform/macos/bitrise.yml
index 6d51b4878e..340d72e27c 100644
--- a/platform/macos/bitrise.yml
+++ b/platform/macos/bitrise.yml
@@ -43,27 +43,7 @@ workflows:
make xproj
- is_debug: 'yes'
- script:
- title: Build Benchmark Tests
- run_if: '{{enveq "SKIPCI" "false"}}'
- inputs:
- - content: |-
- #!/bin/bash
- set -eu -o pipefail
- export BUILDTYPE=Debug
- make benchmark
- - is_debug: 'yes'
- - script:
- title: Run Core Tests
- run_if: '{{enveq "SKIPCI" "false"}}'
- inputs:
- - content: |-
- #!/bin/bash
- set -eu -o pipefail
- export BUILDTYPE=Debug
- make test
- - is_debug: 'yes'
- - script:
- title: Run SDK Unit Tests
+ title: Run Core and SDK Unit Tests
run_if: '{{enveq "SKIPCI" "false"}}'
inputs:
- content: |-
@@ -71,13 +51,15 @@ workflows:
set -eu -o pipefail
export BUILDTYPE=Debug
export XCPRETTY="| tee ${BITRISE_DEPLOY_DIR}/raw-xcodebuild-output.txt | xcpretty --color --report html --output ${BITRISE_DEPLOY_DIR}/xcode-test-results.html"
- make macos-test
+ make run-test
- is_debug: 'yes'
- deploy-to-bitrise-io:
title: Deploy to Bitrise.io
run_if: '{{enveq "SKIPCI" "false"}}'
inputs:
+ - deploy_path: "test/fixtures"
- notify_user_groups: none
+ - is_compress: 'true'
- slack:
title: Post to Slack
run_if: '{{enveq "SKIPCI" "false"}}'
diff --git a/platform/macos/jazzy.yml b/platform/macos/jazzy.yml
index 406154ec5e..6909e14385 100644
--- a/platform/macos/jazzy.yml
+++ b/platform/macos/jazzy.yml
@@ -47,14 +47,15 @@ custom_categories:
- MGLShapeCollectionFeature
- name: Style Layers
children:
- - MGLStyleLayer
- - MGLBaseStyleLayer
- MGLBackgroundStyleLayer
- MGLCircleStyleLayer
- MGLFillStyleLayer
+ - MGLForegroundStyleLayer
- MGLLineStyleLayer
- MGLRasterStyleLayer
+ - MGLStyleLayer
- MGLSymbolStyleLayer
+ - MGLVectorStyleLayer
- name: Data Sources
children:
- MGLSource
diff --git a/platform/macos/macos.xcodeproj/project.pbxproj b/platform/macos/macos.xcodeproj/project.pbxproj
index 1e22796f2e..2f78f9479e 100644
--- a/platform/macos/macos.xcodeproj/project.pbxproj
+++ b/platform/macos/macos.xcodeproj/project.pbxproj
@@ -7,11 +7,10 @@
objects = {
/* Begin PBXBuildFile section */
+ 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 */; };
- 352742781D4C220900A1ECE6 /* MGLStyleAttributeValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 352742771D4C220900A1ECE6 /* MGLStyleAttributeValue.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 3527427C1D4C238F00A1ECE6 /* NSColor+MGLStyleAttributeAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 3527427A1D4C238F00A1ECE6 /* NSColor+MGLStyleAttributeAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 3527427D1D4C238F00A1ECE6 /* NSColor+MGLStyleAttributeAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 3527427B1D4C238F00A1ECE6 /* NSColor+MGLStyleAttributeAdditions.m */; };
+ 352742781D4C220900A1ECE6 /* MGLStyleValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 352742771D4C220900A1ECE6 /* MGLStyleValue.h */; settings = {ATTRIBUTES = (Public, ); }; };
352742811D4C243B00A1ECE6 /* MGLSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 3527427F1D4C243B00A1ECE6 /* MGLSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
352742821D4C243B00A1ECE6 /* MGLSource.mm in Sources */ = {isa = PBXBuildFile; fileRef = 352742801D4C243B00A1ECE6 /* MGLSource.mm */; };
352742851D4C244700A1ECE6 /* MGLRasterSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 352742831D4C244700A1ECE6 /* MGLRasterSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -20,32 +19,37 @@
3527428A1D4C245800A1ECE6 /* MGLGeoJSONSource.mm in Sources */ = {isa = PBXBuildFile; fileRef = 352742881D4C245800A1ECE6 /* MGLGeoJSONSource.mm */; };
3527428D1D4C24AB00A1ECE6 /* MGLCircleStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 3527428B1D4C24AB00A1ECE6 /* MGLCircleStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
3527428E1D4C24AB00A1ECE6 /* MGLCircleStyleLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3527428C1D4C24AB00A1ECE6 /* MGLCircleStyleLayer.mm */; };
- 3527429F1D4C25BD00A1ECE6 /* MGLStyleAttributeFunction_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 3527429C1D4C25BD00A1ECE6 /* MGLStyleAttributeFunction_Private.h */; };
- 352742A01D4C25BD00A1ECE6 /* MGLStyleAttributeFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 3527429D1D4C25BD00A1ECE6 /* MGLStyleAttributeFunction.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 352742A11D4C25BD00A1ECE6 /* MGLStyleAttributeFunction.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3527429E1D4C25BD00A1ECE6 /* MGLStyleAttributeFunction.mm */; };
+ 352742A11D4C25BD00A1ECE6 /* MGLStyleValue.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3527429E1D4C25BD00A1ECE6 /* MGLStyleValue.mm */; };
3529039B1D6C63B80002C7DF /* NSPredicate+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 352903991D6C63B80002C7DF /* NSPredicate+MGLAdditions.h */; };
3529039C1D6C63B80002C7DF /* NSPredicate+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3529039A1D6C63B80002C7DF /* NSPredicate+MGLAdditions.mm */; };
3537CA741D3F93A600380318 /* MGLStyle_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 3537CA731D3F93A600380318 /* MGLStyle_Private.h */; };
- 3538AA231D542685008EC33D /* MGLBaseStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 3538AA211D542685008EC33D /* MGLBaseStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 3538AA241D542685008EC33D /* MGLBaseStyleLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3538AA221D542685008EC33D /* MGLBaseStyleLayer.mm */; };
+ 3538AA231D542685008EC33D /* MGLStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 3538AA211D542685008EC33D /* MGLStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 3538AA241D542685008EC33D /* MGLStyleLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3538AA221D542685008EC33D /* MGLStyleLayer.mm */; };
353BAEF81D6463B8009A8DA9 /* amsterdam.geojson in Resources */ = {isa = PBXBuildFile; fileRef = 358EB3AE1D61F0DB00E46D9C /* amsterdam.geojson */; };
355BA4ED1D41633E00CCC6D5 /* NSColor+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 355BA4EB1D41633E00CCC6D5 /* NSColor+MGLAdditions.h */; };
355BA4EE1D41633E00CCC6D5 /* NSColor+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 355BA4EC1D41633E00CCC6D5 /* NSColor+MGLAdditions.mm */; };
35602BFA1D3EA99F0050646F /* MGLFillStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 35602BF81D3EA99F0050646F /* MGLFillStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
35602BFB1D3EA99F0050646F /* MGLFillStyleLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 35602BF91D3EA99F0050646F /* MGLFillStyleLayer.mm */; };
35602BFF1D3EA9B40050646F /* MGLStyleLayer_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 35602BFC1D3EA9B40050646F /* MGLStyleLayer_Private.h */; };
- 35602C001D3EA9B40050646F /* MGLStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 35602BFD1D3EA9B40050646F /* MGLStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 35602C011D3EA9B40050646F /* MGLStyleLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 35602BFE1D3EA9B40050646F /* MGLStyleLayer.mm */; };
+ 35602C001D3EA9B40050646F /* MGLForegroundStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 35602BFD1D3EA9B40050646F /* MGLForegroundStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 35602C011D3EA9B40050646F /* MGLForegroundStyleLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 35602BFE1D3EA9B40050646F /* MGLForegroundStyleLayer.m */; };
35724FC41D630502002A4AB4 /* amsterdam.geojson in Resources */ = {isa = PBXBuildFile; fileRef = 358EB3AE1D61F0DB00E46D9C /* amsterdam.geojson */; };
- 3593E52A1D52A628006D9365 /* MGLStyleAttribute.h in Headers */ = {isa = PBXBuildFile; fileRef = 3593E5281D52A628006D9365 /* MGLStyleAttribute.h */; };
- 3593E52B1D52A628006D9365 /* MGLStyleAttribute.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3593E5291D52A628006D9365 /* MGLStyleAttribute.mm */; };
- 3593E52D1D52A680006D9365 /* NSColor+MGLStyleAttributeAdditions_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 3593E52C1D52A680006D9365 /* NSColor+MGLStyleAttributeAdditions_Private.h */; };
35C5D8471D6DD66D00E95907 /* NSComparisonPredicate+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 35C5D8431D6DD66D00E95907 /* NSComparisonPredicate+MGLAdditions.h */; };
35C5D8481D6DD66D00E95907 /* NSComparisonPredicate+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 35C5D8441D6DD66D00E95907 /* NSComparisonPredicate+MGLAdditions.mm */; };
35C5D8491D6DD66D00E95907 /* NSCompoundPredicate+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 35C5D8451D6DD66D00E95907 /* NSCompoundPredicate+MGLAdditions.h */; };
35C5D84A1D6DD66D00E95907 /* NSCompoundPredicate+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 35C5D8461D6DD66D00E95907 /* NSCompoundPredicate+MGLAdditions.mm */; };
35D65C5A1D65AD5500722C23 /* NSDate+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 35D65C581D65AD5500722C23 /* NSDate+MGLAdditions.h */; };
35D65C5B1D65AD5500722C23 /* NSDate+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 35D65C591D65AD5500722C23 /* NSDate+MGLAdditions.mm */; };
+ 408AA85B1DAEECFE00022900 /* MGLShape_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 408AA85A1DAEECF100022900 /* MGLShape_Private.h */; };
+ 408AA8651DAEEE3400022900 /* MGLPolygon+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 408AA8601DAEED3300022900 /* MGLPolygon+MGLAdditions.h */; };
+ 408AA8661DAEEE3600022900 /* MGLPolyline+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 408AA8611DAEED3300022900 /* MGLPolyline+MGLAdditions.h */; };
+ 408AA8671DAEEE3900022900 /* NSDictionary+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 408AA85F1DAEED3300022900 /* NSDictionary+MGLAdditions.h */; };
+ 408AA8681DAEEE5200022900 /* MGLPolygon+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 408AA85C1DAEED3300022900 /* MGLPolygon+MGLAdditions.m */; };
+ 408AA8691DAEEE5500022900 /* MGLPolyline+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 408AA85D1DAEED3300022900 /* MGLPolyline+MGLAdditions.m */; };
+ 408AA86A1DAEEE5D00022900 /* NSDictionary+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 408AA85E1DAEED3300022900 /* NSDictionary+MGLAdditions.mm */; };
+ 40ABDB561DB0022100372083 /* NSImage+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 405C03971DB0004E001AC280 /* NSImage+MGLAdditions.mm */; };
+ 40B77E451DB11BC9003DA2FE /* NSArray+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 40B77E431DB11BB0003DA2FE /* NSArray+MGLAdditions.h */; };
+ 40B77E461DB11BCD003DA2FE /* NSArray+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 40B77E421DB11BB0003DA2FE /* NSArray+MGLAdditions.mm */; };
52BECB0A1CC5A26F009CD791 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52BECB091CC5A26F009CD791 /* SystemConfiguration.framework */; };
5548BE781D09E718005DDE81 /* libmbgl-core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAE6C3451CC31D1200DB3429 /* libmbgl-core.a */; };
558F18221D0B13B100123F46 /* libmbgl-loop.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 558F18211D0B13B000123F46 /* libmbgl-loop.a */; };
@@ -63,7 +67,12 @@
DA35A2C21CCA9F4A00E826B2 /* MGLClockDirectionFormatterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DA35A2C11CCA9F4A00E826B2 /* MGLClockDirectionFormatterTests.m */; };
DA35A2CF1CCAAED300E826B2 /* NSValue+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = DA35A2CD1CCAAED300E826B2 /* NSValue+MGLAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
DA35A2D01CCAAED300E826B2 /* NSValue+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = DA35A2CE1CCAAED300E826B2 /* NSValue+MGLAdditions.m */; };
+ DA551B821DB496AC0009AFAF /* MGLTileSet.h in Headers */ = {isa = PBXBuildFile; fileRef = DA551B7F1DB496AC0009AFAF /* MGLTileSet.h */; };
+ DA551B831DB496AC0009AFAF /* MGLTileSet_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DA551B801DB496AC0009AFAF /* MGLTileSet_Private.h */; };
+ DA551B841DB496AC0009AFAF /* MGLTileSet.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA551B811DB496AC0009AFAF /* MGLTileSet.mm */; };
DA5589771D320C41006B7F64 /* wms.json in Resources */ = {isa = PBXBuildFile; fileRef = DA5589761D320C41006B7F64 /* wms.json */; };
+ DA6408D71DA4E5DA00908C90 /* MGLVectorStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = DA6408D51DA4E5DA00908C90 /* MGLVectorStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ DA6408D81DA4E5DA00908C90 /* MGLVectorStyleLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = DA6408D61DA4E5DA00908C90 /* MGLVectorStyleLayer.m */; };
DA839E971CC2E3400062CAFB /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DA839E961CC2E3400062CAFB /* AppDelegate.m */; };
DA839E9A1CC2E3400062CAFB /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DA839E991CC2E3400062CAFB /* main.m */; };
DA839E9D1CC2E3400062CAFB /* MapDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = DA839E9C1CC2E3400062CAFB /* MapDocument.m */; };
@@ -85,19 +94,9 @@
DA8F25971D51CAC70010E6B5 /* MGLVectorSource.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8F25951D51CAC70010E6B5 /* MGLVectorSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
DA8F25981D51CAC70010E6B5 /* MGLVectorSource.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA8F25961D51CAC70010E6B5 /* MGLVectorSource.mm */; };
DA8F259A1D51CAD00010E6B5 /* MGLSource_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8F25991D51CAD00010E6B5 /* MGLSource_Private.h */; };
- DA8F259C1D51CB000010E6B5 /* MGLStyleAttributeValue_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8F259B1D51CB000010E6B5 /* MGLStyleAttributeValue_Private.h */; };
- DA8F25A91D51CB270010E6B5 /* NSNumber+MGLStyleAttributeAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8F259D1D51CB270010E6B5 /* NSNumber+MGLStyleAttributeAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
- DA8F25AA1D51CB270010E6B5 /* NSNumber+MGLStyleAttributeAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA8F259E1D51CB270010E6B5 /* NSNumber+MGLStyleAttributeAdditions.mm */; };
- DA8F25AB1D51CB270010E6B5 /* NSNumber+MGLStyleAttributeAdditions_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8F259F1D51CB270010E6B5 /* NSNumber+MGLStyleAttributeAdditions_Private.h */; };
- DA8F25AC1D51CB270010E6B5 /* NSArray+MGLStyleAttributeAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8F25A01D51CB270010E6B5 /* NSArray+MGLStyleAttributeAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
- DA8F25AD1D51CB270010E6B5 /* NSArray+MGLStyleAttributeAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA8F25A11D51CB270010E6B5 /* NSArray+MGLStyleAttributeAdditions.mm */; };
- DA8F25AE1D51CB270010E6B5 /* NSArray+MGLStyleAttributeAdditions_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8F25A21D51CB270010E6B5 /* NSArray+MGLStyleAttributeAdditions_Private.h */; };
- DA8F25AF1D51CB270010E6B5 /* NSString+MGLStyleAttributeAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8F25A31D51CB270010E6B5 /* NSString+MGLStyleAttributeAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
- DA8F25B01D51CB270010E6B5 /* NSString+MGLStyleAttributeAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA8F25A41D51CB270010E6B5 /* NSString+MGLStyleAttributeAdditions.mm */; };
- DA8F25B11D51CB270010E6B5 /* NSString+MGLStyleAttributeAdditions_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8F25A51D51CB270010E6B5 /* NSString+MGLStyleAttributeAdditions_Private.h */; };
- DA8F25B21D51CB270010E6B5 /* NSValue+MGLStyleAttributeAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8F25A61D51CB270010E6B5 /* NSValue+MGLStyleAttributeAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ DA8F259C1D51CB000010E6B5 /* MGLStyleValue_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8F259B1D51CB000010E6B5 /* MGLStyleValue_Private.h */; };
+ DA8F25B21D51CB270010E6B5 /* NSValue+MGLStyleAttributeAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8F25A61D51CB270010E6B5 /* NSValue+MGLStyleAttributeAdditions.h */; };
DA8F25B31D51CB270010E6B5 /* NSValue+MGLStyleAttributeAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA8F25A71D51CB270010E6B5 /* NSValue+MGLStyleAttributeAdditions.mm */; };
- DA8F25B41D51CB270010E6B5 /* NSValue+MGLStyleAttributeAdditions_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8F25A81D51CB270010E6B5 /* NSValue+MGLStyleAttributeAdditions_Private.h */; };
DAC2ABC51CC6D343006D18C4 /* MGLAnnotationImage_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DAC2ABC41CC6D343006D18C4 /* MGLAnnotationImage_Private.h */; };
DACC22141CF3D3E200D220D9 /* MGLFeature.h in Headers */ = {isa = PBXBuildFile; fileRef = DACC22121CF3D3E200D220D9 /* MGLFeature.h */; settings = {ATTRIBUTES = (Public, ); }; };
DACC22151CF3D3E200D220D9 /* MGLFeature.mm in Sources */ = {isa = PBXBuildFile; fileRef = DACC22131CF3D3E200D220D9 /* MGLFeature.mm */; };
@@ -141,10 +140,10 @@
DAE6C38D1CC31E2A00DB3429 /* MGLOfflineRegion_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DAE6C3731CC31E2A00DB3429 /* MGLOfflineRegion_Private.h */; };
DAE6C38E1CC31E2A00DB3429 /* MGLOfflineStorage_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DAE6C3741CC31E2A00DB3429 /* MGLOfflineStorage_Private.h */; };
DAE6C38F1CC31E2A00DB3429 /* MGLOfflineStorage.mm in Sources */ = {isa = PBXBuildFile; fileRef = DAE6C3751CC31E2A00DB3429 /* MGLOfflineStorage.mm */; };
- DAE6C3901CC31E2A00DB3429 /* MGLPointAnnotation.m in Sources */ = {isa = PBXBuildFile; fileRef = DAE6C3761CC31E2A00DB3429 /* MGLPointAnnotation.m */; };
+ DAE6C3901CC31E2A00DB3429 /* MGLPointAnnotation.mm in Sources */ = {isa = PBXBuildFile; fileRef = DAE6C3761CC31E2A00DB3429 /* MGLPointAnnotation.mm */; };
DAE6C3911CC31E2A00DB3429 /* MGLPolygon.mm in Sources */ = {isa = PBXBuildFile; fileRef = DAE6C3771CC31E2A00DB3429 /* MGLPolygon.mm */; };
DAE6C3921CC31E2A00DB3429 /* MGLPolyline.mm in Sources */ = {isa = PBXBuildFile; fileRef = DAE6C3781CC31E2A00DB3429 /* MGLPolyline.mm */; };
- DAE6C3931CC31E2A00DB3429 /* MGLShape.m in Sources */ = {isa = PBXBuildFile; fileRef = DAE6C3791CC31E2A00DB3429 /* MGLShape.m */; };
+ DAE6C3931CC31E2A00DB3429 /* MGLShape.mm in Sources */ = {isa = PBXBuildFile; fileRef = DAE6C3791CC31E2A00DB3429 /* MGLShape.mm */; };
DAE6C3941CC31E2A00DB3429 /* MGLStyle.mm in Sources */ = {isa = PBXBuildFile; fileRef = DAE6C37A1CC31E2A00DB3429 /* MGLStyle.mm */; };
DAE6C3951CC31E2A00DB3429 /* MGLTilePyramidOfflineRegion.mm in Sources */ = {isa = PBXBuildFile; fileRef = DAE6C37B1CC31E2A00DB3429 /* MGLTilePyramidOfflineRegion.mm */; };
DAE6C3961CC31E2A00DB3429 /* MGLTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = DAE6C37C1CC31E2A00DB3429 /* MGLTypes.m */; };
@@ -180,6 +179,8 @@
DAE6C3D61CC34C9900DB3429 /* MGLStyleTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = DAE6C3CC1CC34BD800DB3429 /* MGLStyleTests.mm */; };
DAED385F1D62CED700D7640F /* NSURL+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = DAED385D1D62CED700D7640F /* NSURL+MGLAdditions.h */; };
DAED38601D62CED700D7640F /* NSURL+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = DAED385E1D62CED700D7640F /* NSURL+MGLAdditions.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 */; };
DD5D1EA91DA579A80064B213 /* polyline.geojson in Resources */ = {isa = PBXBuildFile; fileRef = DD5D1EA81DA579A80064B213 /* polyline.geojson */; };
/* End PBXBuildFile section */
@@ -216,11 +217,10 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
+ 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>"; };
- 352742771D4C220900A1ECE6 /* MGLStyleAttributeValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleAttributeValue.h; sourceTree = "<group>"; };
- 3527427A1D4C238F00A1ECE6 /* NSColor+MGLStyleAttributeAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSColor+MGLStyleAttributeAdditions.h"; sourceTree = "<group>"; };
- 3527427B1D4C238F00A1ECE6 /* NSColor+MGLStyleAttributeAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSColor+MGLStyleAttributeAdditions.m"; sourceTree = "<group>"; };
+ 352742771D4C220900A1ECE6 /* MGLStyleValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleValue.h; sourceTree = "<group>"; };
3527427F1D4C243B00A1ECE6 /* MGLSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLSource.h; sourceTree = "<group>"; };
352742801D4C243B00A1ECE6 /* MGLSource.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLSource.mm; sourceTree = "<group>"; };
352742831D4C244700A1ECE6 /* MGLRasterSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLRasterSource.h; sourceTree = "<group>"; };
@@ -229,25 +229,20 @@
352742881D4C245800A1ECE6 /* MGLGeoJSONSource.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLGeoJSONSource.mm; sourceTree = "<group>"; };
3527428B1D4C24AB00A1ECE6 /* MGLCircleStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLCircleStyleLayer.h; sourceTree = "<group>"; };
3527428C1D4C24AB00A1ECE6 /* MGLCircleStyleLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLCircleStyleLayer.mm; sourceTree = "<group>"; };
- 3527429C1D4C25BD00A1ECE6 /* MGLStyleAttributeFunction_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleAttributeFunction_Private.h; sourceTree = "<group>"; };
- 3527429D1D4C25BD00A1ECE6 /* MGLStyleAttributeFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleAttributeFunction.h; sourceTree = "<group>"; };
- 3527429E1D4C25BD00A1ECE6 /* MGLStyleAttributeFunction.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLStyleAttributeFunction.mm; sourceTree = "<group>"; };
+ 3527429E1D4C25BD00A1ECE6 /* MGLStyleValue.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLStyleValue.mm; sourceTree = "<group>"; };
352903991D6C63B80002C7DF /* NSPredicate+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSPredicate+MGLAdditions.h"; sourceTree = "<group>"; };
3529039A1D6C63B80002C7DF /* NSPredicate+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSPredicate+MGLAdditions.mm"; sourceTree = "<group>"; };
3537CA731D3F93A600380318 /* MGLStyle_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyle_Private.h; sourceTree = "<group>"; };
- 3538AA211D542685008EC33D /* MGLBaseStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLBaseStyleLayer.h; sourceTree = "<group>"; };
- 3538AA221D542685008EC33D /* MGLBaseStyleLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLBaseStyleLayer.mm; sourceTree = "<group>"; };
+ 3538AA211D542685008EC33D /* MGLStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleLayer.h; sourceTree = "<group>"; };
+ 3538AA221D542685008EC33D /* MGLStyleLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLStyleLayer.mm; sourceTree = "<group>"; };
355BA4EB1D41633E00CCC6D5 /* NSColor+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSColor+MGLAdditions.h"; sourceTree = "<group>"; };
355BA4EC1D41633E00CCC6D5 /* NSColor+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSColor+MGLAdditions.mm"; sourceTree = "<group>"; };
35602BF81D3EA99F0050646F /* MGLFillStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLFillStyleLayer.h; sourceTree = "<group>"; };
35602BF91D3EA99F0050646F /* MGLFillStyleLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLFillStyleLayer.mm; sourceTree = "<group>"; };
35602BFC1D3EA9B40050646F /* MGLStyleLayer_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleLayer_Private.h; sourceTree = "<group>"; };
- 35602BFD1D3EA9B40050646F /* MGLStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleLayer.h; sourceTree = "<group>"; };
- 35602BFE1D3EA9B40050646F /* MGLStyleLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLStyleLayer.mm; sourceTree = "<group>"; };
+ 35602BFD1D3EA9B40050646F /* MGLForegroundStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLForegroundStyleLayer.h; sourceTree = "<group>"; };
+ 35602BFE1D3EA9B40050646F /* MGLForegroundStyleLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLForegroundStyleLayer.m; sourceTree = "<group>"; };
358EB3AE1D61F0DB00E46D9C /* amsterdam.geojson */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = amsterdam.geojson; path = ../../darwin/test/amsterdam.geojson; sourceTree = "<group>"; };
- 3593E5281D52A628006D9365 /* MGLStyleAttribute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleAttribute.h; sourceTree = "<group>"; };
- 3593E5291D52A628006D9365 /* MGLStyleAttribute.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLStyleAttribute.mm; sourceTree = "<group>"; };
- 3593E52C1D52A680006D9365 /* NSColor+MGLStyleAttributeAdditions_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSColor+MGLStyleAttributeAdditions_Private.h"; sourceTree = "<group>"; };
35C5D8431D6DD66D00E95907 /* NSComparisonPredicate+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSComparisonPredicate+MGLAdditions.h"; sourceTree = "<group>"; };
35C5D8441D6DD66D00E95907 /* NSComparisonPredicate+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSComparisonPredicate+MGLAdditions.mm"; sourceTree = "<group>"; };
35C5D8451D6DD66D00E95907 /* NSCompoundPredicate+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSCompoundPredicate+MGLAdditions.h"; sourceTree = "<group>"; };
@@ -255,6 +250,17 @@
35C5D84B1D6DD75B00E95907 /* MGLFilterTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLFilterTests.mm; sourceTree = "<group>"; };
35D65C581D65AD5500722C23 /* NSDate+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDate+MGLAdditions.h"; sourceTree = "<group>"; };
35D65C591D65AD5500722C23 /* NSDate+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSDate+MGLAdditions.mm"; sourceTree = "<group>"; };
+ 405C03961DB0004E001AC280 /* NSImage+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSImage+MGLAdditions.h"; sourceTree = "<group>"; };
+ 405C03971DB0004E001AC280 /* NSImage+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSImage+MGLAdditions.mm"; sourceTree = "<group>"; };
+ 408AA85A1DAEECF100022900 /* MGLShape_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLShape_Private.h; sourceTree = "<group>"; };
+ 408AA85C1DAEED3300022900 /* MGLPolygon+MGLAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MGLPolygon+MGLAdditions.m"; sourceTree = "<group>"; };
+ 408AA85D1DAEED3300022900 /* MGLPolyline+MGLAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MGLPolyline+MGLAdditions.m"; sourceTree = "<group>"; };
+ 408AA85E1DAEED3300022900 /* NSDictionary+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSDictionary+MGLAdditions.mm"; sourceTree = "<group>"; };
+ 408AA85F1DAEED3300022900 /* NSDictionary+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+MGLAdditions.h"; sourceTree = "<group>"; };
+ 408AA8601DAEED3300022900 /* MGLPolygon+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MGLPolygon+MGLAdditions.h"; sourceTree = "<group>"; };
+ 408AA8611DAEED3300022900 /* MGLPolyline+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MGLPolyline+MGLAdditions.h"; sourceTree = "<group>"; };
+ 40B77E421DB11BB0003DA2FE /* NSArray+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSArray+MGLAdditions.mm"; sourceTree = "<group>"; };
+ 40B77E431DB11BB0003DA2FE /* NSArray+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+MGLAdditions.h"; sourceTree = "<group>"; };
52BECB091CC5A26F009CD791 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
5548BE791D0ACBB2005DDE81 /* libmbgl-loop-darwin.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libmbgl-loop-darwin.a"; path = "cmake/Debug/libmbgl-loop-darwin.a"; sourceTree = "<group>"; };
5548BE7B1D0ACBBD005DDE81 /* libmbgl-loop-darwin.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libmbgl-loop-darwin.a"; path = "cmake/Debug/libmbgl-loop-darwin.a"; sourceTree = "<group>"; };
@@ -276,7 +282,12 @@
DA35A2C11CCA9F4A00E826B2 /* MGLClockDirectionFormatterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MGLClockDirectionFormatterTests.m; path = ../../darwin/test/MGLClockDirectionFormatterTests.m; sourceTree = "<group>"; };
DA35A2CD1CCAAED300E826B2 /* NSValue+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSValue+MGLAdditions.h"; sourceTree = "<group>"; };
DA35A2CE1CCAAED300E826B2 /* NSValue+MGLAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSValue+MGLAdditions.m"; sourceTree = "<group>"; };
+ DA551B7F1DB496AC0009AFAF /* MGLTileSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLTileSet.h; sourceTree = "<group>"; };
+ DA551B801DB496AC0009AFAF /* MGLTileSet_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLTileSet_Private.h; sourceTree = "<group>"; };
+ DA551B811DB496AC0009AFAF /* MGLTileSet.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLTileSet.mm; sourceTree = "<group>"; };
DA5589761D320C41006B7F64 /* wms.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = wms.json; sourceTree = "<group>"; };
+ DA6408D51DA4E5DA00908C90 /* MGLVectorStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLVectorStyleLayer.h; sourceTree = "<group>"; };
+ DA6408D61DA4E5DA00908C90 /* MGLVectorStyleLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLVectorStyleLayer.m; sourceTree = "<group>"; };
DA839E921CC2E3400062CAFB /* Mapbox GL.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Mapbox GL.app"; sourceTree = BUILT_PRODUCTS_DIR; };
DA839E951CC2E3400062CAFB /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
DA839E961CC2E3400062CAFB /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
@@ -310,19 +321,9 @@
DA8F25951D51CAC70010E6B5 /* MGLVectorSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLVectorSource.h; sourceTree = "<group>"; };
DA8F25961D51CAC70010E6B5 /* MGLVectorSource.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLVectorSource.mm; sourceTree = "<group>"; };
DA8F25991D51CAD00010E6B5 /* MGLSource_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLSource_Private.h; sourceTree = "<group>"; };
- DA8F259B1D51CB000010E6B5 /* MGLStyleAttributeValue_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleAttributeValue_Private.h; sourceTree = "<group>"; };
- DA8F259D1D51CB270010E6B5 /* NSNumber+MGLStyleAttributeAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSNumber+MGLStyleAttributeAdditions.h"; sourceTree = "<group>"; };
- DA8F259E1D51CB270010E6B5 /* NSNumber+MGLStyleAttributeAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSNumber+MGLStyleAttributeAdditions.mm"; sourceTree = "<group>"; };
- DA8F259F1D51CB270010E6B5 /* NSNumber+MGLStyleAttributeAdditions_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSNumber+MGLStyleAttributeAdditions_Private.h"; sourceTree = "<group>"; };
- DA8F25A01D51CB270010E6B5 /* NSArray+MGLStyleAttributeAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+MGLStyleAttributeAdditions.h"; sourceTree = "<group>"; };
- DA8F25A11D51CB270010E6B5 /* NSArray+MGLStyleAttributeAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSArray+MGLStyleAttributeAdditions.mm"; sourceTree = "<group>"; };
- DA8F25A21D51CB270010E6B5 /* NSArray+MGLStyleAttributeAdditions_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+MGLStyleAttributeAdditions_Private.h"; sourceTree = "<group>"; };
- DA8F25A31D51CB270010E6B5 /* NSString+MGLStyleAttributeAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+MGLStyleAttributeAdditions.h"; sourceTree = "<group>"; };
- DA8F25A41D51CB270010E6B5 /* NSString+MGLStyleAttributeAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSString+MGLStyleAttributeAdditions.mm"; sourceTree = "<group>"; };
- DA8F25A51D51CB270010E6B5 /* NSString+MGLStyleAttributeAdditions_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+MGLStyleAttributeAdditions_Private.h"; sourceTree = "<group>"; };
+ DA8F259B1D51CB000010E6B5 /* MGLStyleValue_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLStyleValue_Private.h; sourceTree = "<group>"; };
DA8F25A61D51CB270010E6B5 /* NSValue+MGLStyleAttributeAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSValue+MGLStyleAttributeAdditions.h"; sourceTree = "<group>"; };
DA8F25A71D51CB270010E6B5 /* NSValue+MGLStyleAttributeAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSValue+MGLStyleAttributeAdditions.mm"; sourceTree = "<group>"; };
- DA8F25A81D51CB270010E6B5 /* NSValue+MGLStyleAttributeAdditions_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSValue+MGLStyleAttributeAdditions_Private.h"; sourceTree = "<group>"; };
DA8F25B51D51D2240010E6B5 /* MGLRuntimeStylingTests.m.ejs */ = {isa = PBXFileReference; lastKnownFileType = text; path = MGLRuntimeStylingTests.m.ejs; sourceTree = "<group>"; };
DA8F25B61D51D2240010E6B5 /* MGLStyleLayer.h.ejs */ = {isa = PBXFileReference; lastKnownFileType = text; path = MGLStyleLayer.h.ejs; sourceTree = "<group>"; };
DA8F25B71D51D2240010E6B5 /* MGLStyleLayer.mm.ejs */ = {isa = PBXFileReference; lastKnownFileType = text; path = MGLStyleLayer.mm.ejs; sourceTree = "<group>"; };
@@ -375,10 +376,10 @@
DAE6C3731CC31E2A00DB3429 /* MGLOfflineRegion_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLOfflineRegion_Private.h; sourceTree = "<group>"; };
DAE6C3741CC31E2A00DB3429 /* MGLOfflineStorage_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLOfflineStorage_Private.h; sourceTree = "<group>"; };
DAE6C3751CC31E2A00DB3429 /* MGLOfflineStorage.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLOfflineStorage.mm; sourceTree = "<group>"; };
- DAE6C3761CC31E2A00DB3429 /* MGLPointAnnotation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLPointAnnotation.m; sourceTree = "<group>"; };
+ DAE6C3761CC31E2A00DB3429 /* MGLPointAnnotation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLPointAnnotation.mm; sourceTree = "<group>"; };
DAE6C3771CC31E2A00DB3429 /* MGLPolygon.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLPolygon.mm; sourceTree = "<group>"; };
DAE6C3781CC31E2A00DB3429 /* MGLPolyline.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLPolyline.mm; sourceTree = "<group>"; };
- DAE6C3791CC31E2A00DB3429 /* MGLShape.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLShape.m; sourceTree = "<group>"; };
+ DAE6C3791CC31E2A00DB3429 /* MGLShape.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLShape.mm; sourceTree = "<group>"; };
DAE6C37A1CC31E2A00DB3429 /* MGLStyle.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLStyle.mm; sourceTree = "<group>"; };
DAE6C37B1CC31E2A00DB3429 /* MGLTilePyramidOfflineRegion.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLTilePyramidOfflineRegion.mm; sourceTree = "<group>"; };
DAE6C37C1CC31E2A00DB3429 /* MGLTypes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLTypes.m; sourceTree = "<group>"; };
@@ -414,6 +415,8 @@
DAE6C3CC1CC34BD800DB3429 /* MGLStyleTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLStyleTests.mm; path = ../../darwin/test/MGLStyleTests.mm; sourceTree = "<group>"; };
DAED385D1D62CED700D7640F /* NSURL+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURL+MGLAdditions.h"; sourceTree = "<group>"; };
DAED385E1D62CED700D7640F /* NSURL+MGLAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURL+MGLAdditions.m"; sourceTree = "<group>"; };
+ DD0902AF1DB1AC6400C5BDCE /* MGLNetworkConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLNetworkConfiguration.m; sourceTree = "<group>"; };
+ DD0902B01DB1AC6400C5BDCE /* MGLNetworkConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLNetworkConfiguration.h; sourceTree = "<group>"; };
DD58A4C71D822C6200E1F038 /* MGLExpressionTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLExpressionTests.mm; path = ../../darwin/test/MGLExpressionTests.mm; sourceTree = "<group>"; };
DD5D1EA81DA579A80064B213 /* polyline.geojson */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = polyline.geojson; sourceTree = "<group>"; };
/* End PBXFileReference section */
@@ -454,23 +457,25 @@
35136D471D42295400C20EFD /* Layers */ = {
isa = PBXGroup;
children = (
- 3538AA211D542685008EC33D /* MGLBaseStyleLayer.h */,
- 3538AA221D542685008EC33D /* MGLBaseStyleLayer.mm */,
DA8F25851D51C9E10010E6B5 /* MGLBackgroundStyleLayer.h */,
DA8F25861D51C9E10010E6B5 /* MGLBackgroundStyleLayer.mm */,
3527428B1D4C24AB00A1ECE6 /* MGLCircleStyleLayer.h */,
3527428C1D4C24AB00A1ECE6 /* MGLCircleStyleLayer.mm */,
35602BF81D3EA99F0050646F /* MGLFillStyleLayer.h */,
35602BF91D3EA99F0050646F /* MGLFillStyleLayer.mm */,
+ 35602BFD1D3EA9B40050646F /* MGLForegroundStyleLayer.h */,
+ 35602BFE1D3EA9B40050646F /* MGLForegroundStyleLayer.m */,
DA8F25891D51CA540010E6B5 /* MGLLineStyleLayer.h */,
DA8F258A1D51CA540010E6B5 /* MGLLineStyleLayer.mm */,
DA8F258D1D51CA600010E6B5 /* MGLRasterStyleLayer.h */,
DA8F258E1D51CA600010E6B5 /* MGLRasterStyleLayer.mm */,
- 35602BFD1D3EA9B40050646F /* MGLStyleLayer.h */,
+ 3538AA211D542685008EC33D /* MGLStyleLayer.h */,
35602BFC1D3EA9B40050646F /* MGLStyleLayer_Private.h */,
- 35602BFE1D3EA9B40050646F /* MGLStyleLayer.mm */,
+ 3538AA221D542685008EC33D /* MGLStyleLayer.mm */,
DA8F25911D51CA750010E6B5 /* MGLSymbolStyleLayer.h */,
DA8F25921D51CA750010E6B5 /* MGLSymbolStyleLayer.mm */,
+ DA6408D51DA4E5DA00908C90 /* MGLVectorStyleLayer.h */,
+ DA6408D61DA4E5DA00908C90 /* MGLVectorStyleLayer.m */,
);
name = Layers;
sourceTree = "<group>";
@@ -478,19 +483,6 @@
352742791D4C235C00A1ECE6 /* Categories */ = {
isa = PBXGroup;
children = (
- DA8F25A21D51CB270010E6B5 /* NSArray+MGLStyleAttributeAdditions_Private.h */,
- DA8F25A01D51CB270010E6B5 /* NSArray+MGLStyleAttributeAdditions.h */,
- DA8F25A11D51CB270010E6B5 /* NSArray+MGLStyleAttributeAdditions.mm */,
- 3593E52C1D52A680006D9365 /* NSColor+MGLStyleAttributeAdditions_Private.h */,
- 3527427A1D4C238F00A1ECE6 /* NSColor+MGLStyleAttributeAdditions.h */,
- 3527427B1D4C238F00A1ECE6 /* NSColor+MGLStyleAttributeAdditions.m */,
- DA8F259F1D51CB270010E6B5 /* NSNumber+MGLStyleAttributeAdditions_Private.h */,
- DA8F259D1D51CB270010E6B5 /* NSNumber+MGLStyleAttributeAdditions.h */,
- DA8F259E1D51CB270010E6B5 /* NSNumber+MGLStyleAttributeAdditions.mm */,
- DA8F25A51D51CB270010E6B5 /* NSString+MGLStyleAttributeAdditions_Private.h */,
- DA8F25A31D51CB270010E6B5 /* NSString+MGLStyleAttributeAdditions.h */,
- DA8F25A41D51CB270010E6B5 /* NSString+MGLStyleAttributeAdditions.mm */,
- DA8F25A81D51CB270010E6B5 /* NSValue+MGLStyleAttributeAdditions_Private.h */,
DA8F25A61D51CB270010E6B5 /* NSValue+MGLStyleAttributeAdditions.h */,
DA8F25A71D51CB270010E6B5 /* NSValue+MGLStyleAttributeAdditions.mm */,
);
@@ -509,6 +501,9 @@
352742881D4C245800A1ECE6 /* MGLGeoJSONSource.mm */,
352742831D4C244700A1ECE6 /* MGLRasterSource.h */,
352742841D4C244700A1ECE6 /* MGLRasterSource.mm */,
+ DA551B7F1DB496AC0009AFAF /* MGLTileSet.h */,
+ DA551B801DB496AC0009AFAF /* MGLTileSet_Private.h */,
+ DA551B811DB496AC0009AFAF /* MGLTileSet.mm */,
);
name = Sources;
sourceTree = "<group>";
@@ -519,13 +514,9 @@
352742791D4C235C00A1ECE6 /* Categories */,
35136D471D42295400C20EFD /* Layers */,
3527427E1D4C242B00A1ECE6 /* Sources */,
- 3527429D1D4C25BD00A1ECE6 /* MGLStyleAttributeFunction.h */,
- 3527429C1D4C25BD00A1ECE6 /* MGLStyleAttributeFunction_Private.h */,
- 3527429E1D4C25BD00A1ECE6 /* MGLStyleAttributeFunction.mm */,
- 3593E5281D52A628006D9365 /* MGLStyleAttribute.h */,
- 3593E5291D52A628006D9365 /* MGLStyleAttribute.mm */,
- 352742771D4C220900A1ECE6 /* MGLStyleAttributeValue.h */,
- DA8F259B1D51CB000010E6B5 /* MGLStyleAttributeValue_Private.h */,
+ 352742771D4C220900A1ECE6 /* MGLStyleValue.h */,
+ DA8F259B1D51CB000010E6B5 /* MGLStyleValue_Private.h */,
+ 3527429E1D4C25BD00A1ECE6 /* MGLStyleValue.mm */,
);
name = Styling;
sourceTree = "<group>";
@@ -649,6 +640,17 @@
path = ../../darwin/src;
sourceTree = "<group>";
};
+ DA90B12C1DB43B180073CF55 /* Categories */ = {
+ isa = PBXGroup;
+ children = (
+ 355BA4EB1D41633E00CCC6D5 /* NSColor+MGLAdditions.h */,
+ 355BA4EC1D41633E00CCC6D5 /* NSColor+MGLAdditions.mm */,
+ 405C03961DB0004E001AC280 /* NSImage+MGLAdditions.h */,
+ 405C03971DB0004E001AC280 /* NSImage+MGLAdditions.mm */,
+ );
+ name = Categories;
+ sourceTree = "<group>";
+ };
DAD1657C1CF4CE6B001FF4B9 /* Formatters */ = {
isa = PBXGroup;
children = (
@@ -677,13 +679,14 @@
DAE6C3701CC31E2A00DB3429 /* MGLMultiPoint.mm */,
DAE6C3521CC31E0400DB3429 /* MGLOverlay.h */,
DAE6C3531CC31E0400DB3429 /* MGLPointAnnotation.h */,
- DAE6C3761CC31E2A00DB3429 /* MGLPointAnnotation.m */,
+ DAE6C3761CC31E2A00DB3429 /* MGLPointAnnotation.mm */,
DAE6C3541CC31E0400DB3429 /* MGLPolygon.h */,
DAE6C3771CC31E2A00DB3429 /* MGLPolygon.mm */,
DAE6C3551CC31E0400DB3429 /* MGLPolyline.h */,
DAE6C3781CC31E2A00DB3429 /* MGLPolyline.mm */,
DAE6C3561CC31E0400DB3429 /* MGLShape.h */,
- DAE6C3791CC31E2A00DB3429 /* MGLShape.m */,
+ 408AA85A1DAEECF100022900 /* MGLShape_Private.h */,
+ DAE6C3791CC31E2A00DB3429 /* MGLShape.mm */,
DAD165721CF4CD7A001FF4B9 /* MGLShapeCollection.h */,
DAD165731CF4CD7A001FF4B9 /* MGLShapeCollection.m */,
);
@@ -710,6 +713,12 @@
DAD1657F1CF4CF50001FF4B9 /* Categories */ = {
isa = PBXGroup;
children = (
+ 408AA8601DAEED3300022900 /* MGLPolygon+MGLAdditions.h */,
+ 408AA85C1DAEED3300022900 /* MGLPolygon+MGLAdditions.m */,
+ 408AA8611DAEED3300022900 /* MGLPolyline+MGLAdditions.h */,
+ 408AA85D1DAEED3300022900 /* MGLPolyline+MGLAdditions.m */,
+ 40B77E431DB11BB0003DA2FE /* NSArray+MGLAdditions.h */,
+ 40B77E421DB11BB0003DA2FE /* NSArray+MGLAdditions.mm */,
DAE6C37D1CC31E2A00DB3429 /* NSBundle+MGLAdditions.h */,
DAE6C37E1CC31E2A00DB3429 /* NSBundle+MGLAdditions.m */,
35C5D8431D6DD66D00E95907 /* NSComparisonPredicate+MGLAdditions.h */,
@@ -718,6 +727,8 @@
35C5D8461D6DD66D00E95907 /* NSCompoundPredicate+MGLAdditions.mm */,
35D65C581D65AD5500722C23 /* NSDate+MGLAdditions.h */,
35D65C591D65AD5500722C23 /* NSDate+MGLAdditions.mm */,
+ 408AA85F1DAEED3300022900 /* NSDictionary+MGLAdditions.h */,
+ 408AA85E1DAEED3300022900 /* NSDictionary+MGLAdditions.mm */,
DAE6C37F1CC31E2A00DB3429 /* NSException+MGLAdditions.h */,
3508EC621D749D39009B0EE4 /* NSExpression+MGLAdditions.h */,
3508EC631D749D39009B0EE4 /* NSExpression+MGLAdditions.mm */,
@@ -796,6 +807,8 @@
DAE6C34A1CC31E0400DB3429 /* MGLAccountManager.h */,
DAE6C36A1CC31E2A00DB3429 /* MGLAccountManager_Private.h */,
DAE6C36B1CC31E2A00DB3429 /* MGLAccountManager.m */,
+ DD0902B01DB1AC6400C5BDCE /* MGLNetworkConfiguration.h */,
+ DD0902AF1DB1AC6400C5BDCE /* MGLNetworkConfiguration.m */,
DAE6C34D1CC31E0400DB3429 /* MGLMapCamera.h */,
DAE6C36E1CC31E2A00DB3429 /* MGLMapCamera.mm */,
DAE6C3571CC31E0400DB3429 /* MGLStyle.h */,
@@ -811,6 +824,7 @@
DAE6C39E1CC31E7C00DB3429 /* Kit */ = {
isa = PBXGroup;
children = (
+ DA90B12C1DB43B180073CF55 /* Categories */,
DAE6C39F1CC31E9400DB3429 /* MGLAnnotationImage.h */,
DAC2ABC41CC6D343006D18C4 /* MGLAnnotationImage_Private.h */,
DAE6C3A71CC31EF300DB3429 /* MGLAnnotationImage.m */,
@@ -826,8 +840,6 @@
DAE6C3A21CC31E9400DB3429 /* MGLMapViewDelegate.h */,
DAE6C3AF1CC31EF300DB3429 /* MGLOpenGLLayer.h */,
DAE6C3B01CC31EF300DB3429 /* MGLOpenGLLayer.mm */,
- 355BA4EB1D41633E00CCC6D5 /* NSColor+MGLAdditions.h */,
- 355BA4EC1D41633E00CCC6D5 /* NSColor+MGLAdditions.mm */,
);
name = Kit;
path = src;
@@ -848,30 +860,27 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
- 3593E52D1D52A680006D9365 /* NSColor+MGLStyleAttributeAdditions_Private.h in Headers */,
DA8F258F1D51CA600010E6B5 /* MGLRasterStyleLayer.h in Headers */,
3508EC641D749D39009B0EE4 /* NSExpression+MGLAdditions.h in Headers */,
DAE6C38D1CC31E2A00DB3429 /* MGLOfflineRegion_Private.h in Headers */,
- DA8F25AB1D51CB270010E6B5 /* NSNumber+MGLStyleAttributeAdditions_Private.h in Headers */,
- DA8F259C1D51CB000010E6B5 /* MGLStyleAttributeValue_Private.h in Headers */,
- DA8F25B41D51CB270010E6B5 /* NSValue+MGLStyleAttributeAdditions_Private.h in Headers */,
+ 408AA8651DAEEE3400022900 /* MGLPolygon+MGLAdditions.h in Headers */,
+ DA8F259C1D51CB000010E6B5 /* MGLStyleValue_Private.h in Headers */,
DAE6C35B1CC31E0400DB3429 /* MGLAnnotation.h in Headers */,
DAE6C3B61CC31EF300DB3429 /* MGLMapView_Private.h in Headers */,
3527428D1D4C24AB00A1ECE6 /* MGLCircleStyleLayer.h in Headers */,
DAE6C3B21CC31EF300DB3429 /* MGLAttributionButton.h in Headers */,
+ 40B77E451DB11BC9003DA2FE /* NSArray+MGLAdditions.h in Headers */,
35C5D8471D6DD66D00E95907 /* NSComparisonPredicate+MGLAdditions.h in Headers */,
DAE6C3A31CC31E9400DB3429 /* MGLAnnotationImage.h in Headers */,
DAE6C3A41CC31E9400DB3429 /* MGLMapView.h in Headers */,
- 352742A01D4C25BD00A1ECE6 /* MGLStyleAttributeFunction.h in Headers */,
355BA4ED1D41633E00CCC6D5 /* NSColor+MGLAdditions.h in Headers */,
DAE6C3611CC31E0400DB3429 /* MGLOfflineStorage.h in Headers */,
- 352742781D4C220900A1ECE6 /* MGLStyleAttributeValue.h in Headers */,
+ 352742781D4C220900A1ECE6 /* MGLStyleValue.h in Headers */,
DAE6C35E1CC31E0400DB3429 /* MGLMultiPoint.h in Headers */,
35602BFF1D3EA9B40050646F /* MGLStyleLayer_Private.h in Headers */,
DAE6C3971CC31E2A00DB3429 /* NSBundle+MGLAdditions.h in Headers */,
DAED385F1D62CED700D7640F /* NSURL+MGLAdditions.h in Headers */,
DAD165741CF4CD7A001FF4B9 /* MGLShapeCollection.h in Headers */,
- DA8F25AF1D51CB270010E6B5 /* NSString+MGLStyleAttributeAdditions.h in Headers */,
DAE6C3631CC31E0400DB3429 /* MGLPointAnnotation.h in Headers */,
DAC2ABC51CC6D343006D18C4 /* MGLAnnotationImage_Private.h in Headers */,
DAE6C35F1CC31E0400DB3429 /* MGLOfflinePack.h in Headers */,
@@ -881,41 +890,39 @@
DAE6C3861CC31E2A00DB3429 /* MGLGeometry_Private.h in Headers */,
DAE6C3841CC31E2A00DB3429 /* MGLAccountManager_Private.h in Headers */,
DAE6C3691CC31E0400DB3429 /* MGLTypes.h in Headers */,
- DA8F25AE1D51CB270010E6B5 /* NSArray+MGLStyleAttributeAdditions_Private.h in Headers */,
DAE6C3991CC31E2A00DB3429 /* NSException+MGLAdditions.h in Headers */,
DA8F25871D51C9E10010E6B5 /* MGLBackgroundStyleLayer.h in Headers */,
+ 30E5781B1DAA857E0050F07E /* NSImage+MGLAdditions.h in Headers */,
DAE6C3661CC31E0400DB3429 /* MGLShape.h in Headers */,
+ DA551B831DB496AC0009AFAF /* MGLTileSet_Private.h in Headers */,
352742811D4C243B00A1ECE6 /* MGLSource.h in Headers */,
DAE6C3C21CC31F4500DB3429 /* Mapbox.h in Headers */,
- 3527427C1D4C238F00A1ECE6 /* NSColor+MGLStyleAttributeAdditions.h in Headers */,
DAE6C3641CC31E0400DB3429 /* MGLPolygon.h in Headers */,
DA35A2BF1CCA9B1A00E826B2 /* MGLClockDirectionFormatter.h in Headers */,
35602BFA1D3EA99F0050646F /* MGLFillStyleLayer.h in Headers */,
DA35A2A41CC9EB1A00E826B2 /* MGLCoordinateFormatter.h in Headers */,
- DA8F25B11D51CB270010E6B5 /* NSString+MGLStyleAttributeAdditions_Private.h in Headers */,
- 3593E52A1D52A628006D9365 /* MGLStyleAttribute.h in Headers */,
35C5D8491D6DD66D00E95907 /* NSCompoundPredicate+MGLAdditions.h in Headers */,
+ DD0902B31DB1AC6400C5BDCE /* MGLNetworkConfiguration.h in Headers */,
DAE6C3621CC31E0400DB3429 /* MGLOverlay.h in Headers */,
DAE6C3651CC31E0400DB3429 /* MGLPolyline.h in Headers */,
DAE6C39A1CC31E2A00DB3429 /* NSProcessInfo+MGLAdditions.h in Headers */,
DA8F258B1D51CA540010E6B5 /* MGLLineStyleLayer.h in Headers */,
DA8F25B21D51CB270010E6B5 /* NSValue+MGLStyleAttributeAdditions.h in Headers */,
DAE6C38E1CC31E2A00DB3429 /* MGLOfflineStorage_Private.h in Headers */,
+ 408AA8661DAEEE3600022900 /* MGLPolyline+MGLAdditions.h in Headers */,
DAE6C3601CC31E0400DB3429 /* MGLOfflineRegion.h in Headers */,
DAE6C3681CC31E0400DB3429 /* MGLTilePyramidOfflineRegion.h in Headers */,
- DA8F25AC1D51CB270010E6B5 /* NSArray+MGLStyleAttributeAdditions.h in Headers */,
- 3527429F1D4C25BD00A1ECE6 /* MGLStyleAttributeFunction_Private.h in Headers */,
DA35A2CF1CCAAED300E826B2 /* NSValue+MGLAdditions.h in Headers */,
DAE6C3A61CC31E9400DB3429 /* MGLMapViewDelegate.h in Headers */,
DAE6C38B1CC31E2A00DB3429 /* MGLOfflinePack_Private.h in Headers */,
DACC22141CF3D3E200D220D9 /* MGLFeature.h in Headers */,
- 3538AA231D542685008EC33D /* MGLBaseStyleLayer.h in Headers */,
+ 3538AA231D542685008EC33D /* MGLStyleLayer.h in Headers */,
DAE6C35C1CC31E0400DB3429 /* MGLGeometry.h in Headers */,
DAE6C35A1CC31E0400DB3429 /* MGLAccountManager.h in Headers */,
- 35602C001D3EA9B40050646F /* MGLStyleLayer.h in Headers */,
+ DA551B821DB496AC0009AFAF /* MGLTileSet.h in Headers */,
+ 35602C001D3EA9B40050646F /* MGLForegroundStyleLayer.h in Headers */,
DAE6C35D1CC31E0400DB3429 /* MGLMapCamera.h in Headers */,
DAE6C3B41CC31EF300DB3429 /* MGLCompassCell.h in Headers */,
- DA8F25A91D51CB270010E6B5 /* NSNumber+MGLStyleAttributeAdditions.h in Headers */,
3537CA741D3F93A600380318 /* MGLStyle_Private.h in Headers */,
DA8F259A1D51CAD00010E6B5 /* MGLSource_Private.h in Headers */,
DA8F25931D51CA750010E6B5 /* MGLSymbolStyleLayer.h in Headers */,
@@ -925,8 +932,11 @@
DAE6C3A51CC31E9400DB3429 /* MGLMapView+IBAdditions.h in Headers */,
DA35A2AD1CCA091800E826B2 /* MGLCompassDirectionFormatter.h in Headers */,
352742851D4C244700A1ECE6 /* MGLRasterSource.h in Headers */,
+ 408AA85B1DAEECFE00022900 /* MGLShape_Private.h in Headers */,
DACC22181CF3D4F700D220D9 /* MGLFeature_Private.h in Headers */,
+ DA6408D71DA4E5DA00908C90 /* MGLVectorStyleLayer.h in Headers */,
352742891D4C245800A1ECE6 /* MGLGeoJSONSource.h in Headers */,
+ 408AA8671DAEEE3900022900 /* NSDictionary+MGLAdditions.h in Headers */,
DAE6C3671CC31E0400DB3429 /* MGLStyle.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -1109,30 +1119,33 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- DAE6C3901CC31E2A00DB3429 /* MGLPointAnnotation.m in Sources */,
+ 40ABDB561DB0022100372083 /* NSImage+MGLAdditions.mm in Sources */,
+ DAE6C3901CC31E2A00DB3429 /* MGLPointAnnotation.mm in Sources */,
DAE6C3981CC31E2A00DB3429 /* NSBundle+MGLAdditions.m in Sources */,
- DA8F25AA1D51CB270010E6B5 /* NSNumber+MGLStyleAttributeAdditions.mm in Sources */,
DAE6C3B71CC31EF300DB3429 /* MGLMapView.mm in Sources */,
+ 40B77E461DB11BCD003DA2FE /* NSArray+MGLAdditions.mm in Sources */,
DAE6C38C1CC31E2A00DB3429 /* MGLOfflinePack.mm in Sources */,
35D65C5B1D65AD5500722C23 /* NSDate+MGLAdditions.mm in Sources */,
+ DD0902B21DB1AC6400C5BDCE /* MGLNetworkConfiguration.m in Sources */,
DAE6C3B11CC31EF300DB3429 /* MGLAnnotationImage.m in Sources */,
3508EC651D749D39009B0EE4 /* NSExpression+MGLAdditions.mm in Sources */,
DACC22151CF3D3E200D220D9 /* MGLFeature.mm in Sources */,
355BA4EE1D41633E00CCC6D5 /* NSColor+MGLAdditions.mm in Sources */,
DAE6C3B31CC31EF300DB3429 /* MGLAttributionButton.m in Sources */,
35602BFB1D3EA99F0050646F /* MGLFillStyleLayer.mm in Sources */,
- DAE6C3931CC31E2A00DB3429 /* MGLShape.m in Sources */,
+ DAE6C3931CC31E2A00DB3429 /* MGLShape.mm in Sources */,
352742861D4C244700A1ECE6 /* MGLRasterSource.mm in Sources */,
DAE6C39D1CC31E2A00DB3429 /* NSString+MGLAdditions.m in Sources */,
DAE6C3941CC31E2A00DB3429 /* MGLStyle.mm in Sources */,
DAE6C3871CC31E2A00DB3429 /* MGLGeometry.mm in Sources */,
3527428E1D4C24AB00A1ECE6 /* MGLCircleStyleLayer.mm in Sources */,
- 35602C011D3EA9B40050646F /* MGLStyleLayer.mm in Sources */,
- 3527427D1D4C238F00A1ECE6 /* NSColor+MGLStyleAttributeAdditions.m in Sources */,
+ 35602C011D3EA9B40050646F /* MGLForegroundStyleLayer.m in Sources */,
+ 408AA86A1DAEEE5D00022900 /* NSDictionary+MGLAdditions.mm in Sources */,
DA8F25881D51C9E10010E6B5 /* MGLBackgroundStyleLayer.mm in Sources */,
+ DA551B841DB496AC0009AFAF /* MGLTileSet.mm in Sources */,
DAE6C3B81CC31EF300DB3429 /* MGLMapView+IBAdditions.mm in Sources */,
DA35A2D01CCAAED300E826B2 /* NSValue+MGLAdditions.m in Sources */,
- 3538AA241D542685008EC33D /* MGLBaseStyleLayer.mm in Sources */,
+ 3538AA241D542685008EC33D /* MGLStyleLayer.mm in Sources */,
DA35A2C01CCA9B1A00E826B2 /* MGLClockDirectionFormatter.m in Sources */,
DAE6C3BA1CC31EF300DB3429 /* MGLOpenGLLayer.mm in Sources */,
DAE6C38A1CC31E2A00DB3429 /* MGLMultiPoint.mm in Sources */,
@@ -1140,16 +1153,16 @@
DA35A2A61CC9EB2700E826B2 /* MGLCoordinateFormatter.m in Sources */,
352742821D4C243B00A1ECE6 /* MGLSource.mm in Sources */,
DAE6C3881CC31E2A00DB3429 /* MGLMapCamera.mm in Sources */,
+ DA6408D81DA4E5DA00908C90 /* MGLVectorStyleLayer.m in Sources */,
DA8F25B31D51CB270010E6B5 /* NSValue+MGLStyleAttributeAdditions.mm in Sources */,
DAE6C3911CC31E2A00DB3429 /* MGLPolygon.mm in Sources */,
DAE6C39B1CC31E2A00DB3429 /* NSProcessInfo+MGLAdditions.m in Sources */,
DAE6C38F1CC31E2A00DB3429 /* MGLOfflineStorage.mm in Sources */,
DAED38601D62CED700D7640F /* NSURL+MGLAdditions.m in Sources */,
35C5D84A1D6DD66D00E95907 /* NSCompoundPredicate+MGLAdditions.mm in Sources */,
+ 408AA8681DAEEE5200022900 /* MGLPolygon+MGLAdditions.m in Sources */,
DAE6C3951CC31E2A00DB3429 /* MGLTilePyramidOfflineRegion.mm in Sources */,
- 3593E52B1D52A628006D9365 /* MGLStyleAttribute.mm in Sources */,
DAE6C3851CC31E2A00DB3429 /* MGLAccountManager.m in Sources */,
- DA8F25B01D51CB270010E6B5 /* NSString+MGLStyleAttributeAdditions.mm in Sources */,
DAE6C3921CC31E2A00DB3429 /* MGLPolyline.mm in Sources */,
3527428A1D4C245800A1ECE6 /* MGLGeoJSONSource.mm in Sources */,
DAE6C3B51CC31EF300DB3429 /* MGLCompassCell.m in Sources */,
@@ -1158,11 +1171,11 @@
35C5D8481D6DD66D00E95907 /* NSComparisonPredicate+MGLAdditions.mm in Sources */,
DA35A2AE1CCA091800E826B2 /* MGLCompassDirectionFormatter.m in Sources */,
DA8F258C1D51CA540010E6B5 /* MGLLineStyleLayer.mm in Sources */,
- DA8F25AD1D51CB270010E6B5 /* NSArray+MGLStyleAttributeAdditions.mm in Sources */,
+ 408AA8691DAEEE5500022900 /* MGLPolyline+MGLAdditions.m in Sources */,
DA8F25941D51CA750010E6B5 /* MGLSymbolStyleLayer.mm in Sources */,
3529039C1D6C63B80002C7DF /* NSPredicate+MGLAdditions.mm in Sources */,
DA8F25981D51CAC70010E6B5 /* MGLVectorSource.mm in Sources */,
- 352742A11D4C25BD00A1ECE6 /* MGLStyleAttributeFunction.mm in Sources */,
+ 352742A11D4C25BD00A1ECE6 /* MGLStyleValue.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/platform/macos/macos.xcodeproj/xcshareddata/xcschemes/CI.xcscheme b/platform/macos/macos.xcodeproj/xcshareddata/xcschemes/CI.xcscheme
index 3cc2afa46c..eca3be86dc 100644
--- a/platform/macos/macos.xcodeproj/xcshareddata/xcschemes/CI.xcscheme
+++ b/platform/macos/macos.xcodeproj/xcshareddata/xcschemes/CI.xcscheme
@@ -48,6 +48,34 @@
ReferencedContainer = "container:macos.xcodeproj">
</BuildableReference>
</BuildActionEntry>
+ <BuildActionEntry
+ buildForTesting = "YES"
+ buildForRunning = "YES"
+ buildForProfiling = "YES"
+ buildForArchiving = "YES"
+ buildForAnalyzing = "YES">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "8E8A234D3E364CDFA2918983"
+ BuildableName = "mbgl-test"
+ BlueprintName = "mbgl-test"
+ ReferencedContainer = "container:../../build/macos/mbgl.xcodeproj">
+ </BuildableReference>
+ </BuildActionEntry>
+ <BuildActionEntry
+ buildForTesting = "NO"
+ buildForRunning = "NO"
+ buildForProfiling = "NO"
+ buildForArchiving = "NO"
+ buildForAnalyzing = "NO">
+ <BuildableReference
+ BuildableIdentifier = "primary"
+ BlueprintIdentifier = "11FCEF1E29744645907C1E4B"
+ BuildableName = "mbgl-benchmark"
+ BlueprintName = "mbgl-benchmark"
+ ReferencedContainer = "container:../../build/macos/mbgl.xcodeproj">
+ </BuildableReference>
+ </BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
diff --git a/platform/macos/src/MGLMapView.mm b/platform/macos/src/MGLMapView.mm
index 8fca7b86ff..a8f91a24e7 100644
--- a/platform/macos/src/MGLMapView.mm
+++ b/platform/macos/src/MGLMapView.mm
@@ -30,6 +30,7 @@
#import <mbgl/math/wrap.hpp>
#import <mbgl/util/constants.hpp>
#import <mbgl/util/chrono.hpp>
+#import <mbgl/util/run_loop.hpp>
#import <unordered_map>
#import <unordered_set>
@@ -41,6 +42,7 @@
#import "NSString+MGLAdditions.h"
#import "NSURL+MGLAdditions.h"
#import "NSColor+MGLAdditions.h"
+#import "NSImage+MGLAdditions.h"
#import <QuartzCore/QuartzCore.h>
@@ -112,6 +114,11 @@ NSImage *MGLDefaultMarkerImage() {
return [[NSImage alloc] initWithContentsOfFile:path];
}
+/// Initializes the run loop shim that lives on the main thread.
+void MGLinitializeRunLoop() {
+ static mbgl::util::RunLoop mainRunLoop;
+}
+
/// Converts a media timing function into a unit bezier object usable in mbgl.
mbgl::util::UnitBezier MGLUnitBezierForMediaTimingFunction(CAMediaTimingFunction *function) {
if (!function) {
@@ -151,7 +158,7 @@ public:
/// Cross-platform map view controller.
mbgl::Map *_mbglMap;
MGLMapViewImpl *_mbglView;
-
+
NSPanGestureRecognizer *_panGestureRecognizer;
NSMagnificationGestureRecognizer *_magnificationGestureRecognizer;
NSRotationGestureRecognizer *_rotationGestureRecognizer;
@@ -159,7 +166,7 @@ public:
CLLocationDirection _directionAtBeginningOfGesture;
CGFloat _pitchAtBeginningOfGesture;
BOOL _didHideCursorDuringGesture;
-
+
MGLAnnotationContextMap _annotationContextsByAnnotationTag;
MGLAnnotationTag _selectedAnnotationTag;
MGLAnnotationTag _lastSelectedAnnotationTag;
@@ -170,22 +177,22 @@ public:
BOOL _wantsToolTipRects;
/// True if any annotation images that have custom cursors have been installed.
BOOL _wantsCursorRects;
-
+
// Cached checks for delegate method implementations that may be called from
// MGLMultiPointDelegate methods.
-
+
BOOL _delegateHasAlphasForShapeAnnotations;
BOOL _delegateHasStrokeColorsForShapeAnnotations;
BOOL _delegateHasFillColorsForShapeAnnotations;
BOOL _delegateHasLineWidthsForShapeAnnotations;
-
+
/// True if the current process is the Interface Builder designable
/// renderer. When drawing the designable, the map is paused, so any call to
/// it may hang the process.
BOOL _isTargetingInterfaceBuilder;
CLLocationDegrees _pendingLatitude;
CLLocationDegrees _pendingLongitude;
-
+
/// True if the view is currently printing itself.
BOOL _isPrinting;
}
@@ -225,7 +232,7 @@ public:
- (void)awakeFromNib {
[super awakeFromNib];
-
+
self.styleURL = nil;
}
@@ -234,11 +241,13 @@ public:
}
- (void)commonInit {
+ MGLinitializeRunLoop();
+
_isTargetingInterfaceBuilder = NSProcessInfo.processInfo.mgl_isInterfaceBuilderDesignablesAgent;
-
+
// Set up cross-platform controllers and resources.
_mbglView = new MGLMapViewImpl(self, [NSScreen mainScreen].backingScaleFactor);
-
+
// Delete the pre-offline ambient cache at
// ~/Library/Caches/com.mapbox.sdk.ios/cache.db.
NSURL *cachesDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSCachesDirectory
@@ -250,36 +259,36 @@ public:
[NSBundle mgl_frameworkBundle].bundleIdentifier];
NSURL *legacyCacheURL = [cachesDirectoryURL URLByAppendingPathComponent:@"cache.db"];
[[NSFileManager defaultManager] removeItemAtURL:legacyCacheURL error:NULL];
-
+
mbgl::DefaultFileSource *mbglFileSource = [MGLOfflineStorage sharedOfflineStorage].mbglFileSource;
_mbglMap = new mbgl::Map(*_mbglView, *mbglFileSource, mbgl::MapMode::Continuous, mbgl::GLContextMode::Unique, mbgl::ConstrainMode::None, mbgl::ViewportMode::Default);
[self validateTileCacheSize];
-
+
// Install the OpenGL layer. Interface Builder’s synchronous drawing means
// we can’t display a map, so don’t even bother to have a map layer.
self.layer = _isTargetingInterfaceBuilder ? [CALayer layer] : [MGLOpenGLLayer layer];
-
+
// Notify map object when network reachability status changes.
MGLReachability *reachability = [MGLReachability reachabilityForInternetConnection];
reachability.reachableBlock = ^(MGLReachability *) {
mbgl::NetworkStatus::Reachable();
};
[reachability startNotifier];
-
+
// Install ornaments and gesture recognizers.
[self installZoomControls];
[self installCompass];
[self installLogoView];
[self installAttributionView];
[self installGestureRecognizers];
-
+
// Set up annotation management and selection state.
_annotationImagesByIdentifier = [NSMutableDictionary dictionary];
_annotationContextsByAnnotationTag = {};
_selectedAnnotationTag = MGLAnnotationTagNotFound;
_lastSelectedAnnotationTag = MGLAnnotationTagNotFound;
_annotationsNearbyLastClick = {};
-
+
// Jump to Null Island initially.
self.automaticallyAdjustsContentInsets = YES;
mbgl::CameraOptions options;
@@ -345,26 +354,26 @@ public:
- (void)installAttributionView {
_attributionView = [[NSView alloc] initWithFrame:NSZeroRect];
_attributionView.wantsLayer = YES;
-
+
// Make the background and foreground translucent to be unobtrusive.
_attributionView.layer.opacity = 0.6;
-
+
// Blur the background to prevent text underneath the view from running into
// the text in the view, rendering it illegible.
CIFilter *attributionBlurFilter = [CIFilter filterWithName:@"CIGaussianBlur"];
[attributionBlurFilter setDefaults];
-
+
// Brighten the background. This is similar to applying a translucent white
// background on the view, but the effect is a bit more subtle and works
// well with the blur above.
CIFilter *attributionColorFilter = [CIFilter filterWithName:@"CIColorControls"];
[attributionColorFilter setDefaults];
[attributionColorFilter setValue:@(0.1) forKey:kCIInputBrightnessKey];
-
+
// Apply the background effects and a standard button corner radius.
_attributionView.backgroundFilters = @[attributionColorFilter, attributionBlurFilter];
_attributionView.layer.cornerRadius = 4;
-
+
_attributionView.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_attributionView];
[self updateAttributionView];
@@ -376,27 +385,27 @@ public:
_zoomEnabled = YES;
_rotateEnabled = YES;
_pitchEnabled = YES;
-
+
_panGestureRecognizer = [[NSPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)];
_panGestureRecognizer.delaysKeyEvents = YES;
[self addGestureRecognizer:_panGestureRecognizer];
-
+
NSClickGestureRecognizer *clickGestureRecognizer = [[NSClickGestureRecognizer alloc] initWithTarget:self action:@selector(handleClickGesture:)];
clickGestureRecognizer.delaysPrimaryMouseButtonEvents = NO;
[self addGestureRecognizer:clickGestureRecognizer];
-
+
NSClickGestureRecognizer *rightClickGestureRecognizer = [[NSClickGestureRecognizer alloc] initWithTarget:self action:@selector(handleRightClickGesture:)];
rightClickGestureRecognizer.buttonMask = 0x2;
[self addGestureRecognizer:rightClickGestureRecognizer];
-
+
NSClickGestureRecognizer *doubleClickGestureRecognizer = [[NSClickGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleClickGesture:)];
doubleClickGestureRecognizer.numberOfClicksRequired = 2;
doubleClickGestureRecognizer.delaysPrimaryMouseButtonEvents = NO;
[self addGestureRecognizer:doubleClickGestureRecognizer];
-
+
_magnificationGestureRecognizer = [[NSMagnificationGestureRecognizer alloc] initWithTarget:self action:@selector(handleMagnificationGesture:)];
[self addGestureRecognizer:_magnificationGestureRecognizer];
-
+
_rotationGestureRecognizer = [[NSRotationGestureRecognizer alloc] initWithTarget:self action:@selector(handleRotationGesture:)];
[self addGestureRecognizer:_rotationGestureRecognizer];
}
@@ -405,7 +414,7 @@ public:
/// hard-coded to the standard Mapbox and OpenStreetMap attribution.
- (void)updateAttributionView {
self.attributionView.subviews = @[];
-
+
for (NSUInteger i = 0; i < sizeof(MGLAttributions) / sizeof(MGLAttributions[0]); i++) {
// For each attribution, add a borderless button that responds to clicks
// and feels like a hyperlink.
@@ -413,7 +422,7 @@ public:
NSButton *button = [[MGLAttributionButton alloc] initWithTitle:MGLAttributions[i].title URL:url];
button.controlSize = NSMiniControlSize;
button.translatesAutoresizingMaskIntoConstraints = NO;
-
+
// Set the new button flush with the buttom of the container and to the
// right of the previous button, with standard spacing. If there is no
// previous button, align to the container instead.
@@ -441,14 +450,14 @@ public:
- (void)dealloc {
[self.window removeObserver:self forKeyPath:@"contentLayoutRect"];
[self.window removeObserver:self forKeyPath:@"titlebarAppearsTransparent"];
-
+
// Close any annotation callout immediately.
[self.calloutForSelectedAnnotation close];
self.calloutForSelectedAnnotation = nil;
-
+
// Removing the annotations unregisters any outstanding KVO observers.
[self removeAnnotations:self.annotations];
-
+
if (_mbglMap) {
delete _mbglMap;
_mbglMap = nullptr;
@@ -510,14 +519,14 @@ public:
- (void)setDelegate:(id<MGLMapViewDelegate>)delegate {
_delegate = delegate;
-
+
// Cache checks for delegate method implementations that may be called in a
// hot loop, namely the annotation style methods.
_delegateHasAlphasForShapeAnnotations = [_delegate respondsToSelector:@selector(mapView:alphaForShapeAnnotation:)];
_delegateHasStrokeColorsForShapeAnnotations = [_delegate respondsToSelector:@selector(mapView:strokeColorForShapeAnnotation:)];
_delegateHasFillColorsForShapeAnnotations = [_delegate respondsToSelector:@selector(mapView:fillColorForPolygonAnnotation:)];
_delegateHasLineWidthsForShapeAnnotations = [_delegate respondsToSelector:@selector(mapView:lineWidthForPolylineAnnotation:)];
-
+
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
if ([self.delegate respondsToSelector:@selector(mapView:regionWillChangeAnimated:)]) {
@@ -549,7 +558,7 @@ public:
if (_isTargetingInterfaceBuilder) {
return;
}
-
+
// Default to Streets.
if (!styleURL) {
// An access token is required to load any default style, including
@@ -559,7 +568,7 @@ public:
}
styleURL = [MGLStyle streetsStyleURLWithVersion:MGLStyleDefaultVersion];
}
-
+
styleURL = styleURL.mgl_URLByStandardizingScheme;
_mbglMap->setStyleURL(styleURL.absoluteString.UTF8String);
}
@@ -577,7 +586,7 @@ public:
if (!self.dormant && !newWindow) {
self.dormant = YES;
}
-
+
[self.window removeObserver:self forKeyPath:@"contentLayoutRect"];
[self.window removeObserver:self forKeyPath:@"titlebarAppearsTransparent"];
}
@@ -587,11 +596,11 @@ public:
if (self.dormant && window) {
self.dormant = NO;
}
-
+
if (window && _mbglMap->getConstrainMode() == mbgl::ConstrainMode::None) {
_mbglMap->setConstrainMode(mbgl::ConstrainMode::HeightOnly);
}
-
+
[window addObserver:self
forKeyPath:@"contentLayoutRect"
options:NSKeyValueObservingOptionInitial
@@ -640,7 +649,7 @@ public:
attribute:NSLayoutAttributeTrailing
multiplier:1
constant:MGLOrnamentPadding]];
-
+
// Center the compass above the zoom controls, assuming that the compass is
// narrower than the zoom controls.
[self addConstraint:
@@ -659,7 +668,7 @@ public:
attribute:NSLayoutAttributeBottom
multiplier:1
constant:8]];
-
+
// Place the logo view in the lower-left corner of the view, accounting for
// the logo’s alignment rect.
[self addConstraint:
@@ -678,7 +687,7 @@ public:
attribute:NSLayoutAttributeLeading
multiplier:1
constant:MGLOrnamentPadding - _logoView.image.alignmentRect.origin.x]];
-
+
// Place the attribution view to the right of the logo view and size it to
// fit the buttons inside.
[self addConstraint:[NSLayoutConstraint constraintWithItem:_logoView
@@ -709,7 +718,7 @@ public:
attribute:NSLayoutAttributeTrailing
multiplier:1
constant:8]];
-
+
[super updateConstraints];
}
@@ -747,20 +756,20 @@ public:
if (!_mbglMap) {
return;
}
-
+
CGFloat zoomFactor = self.maximumZoomLevel - self.minimumZoomLevel + 1;
CGFloat cpuFactor = [NSProcessInfo processInfo].processorCount;
CGFloat memoryFactor = (CGFloat)[NSProcessInfo processInfo].physicalMemory / 1000 / 1000 / 1000;
CGFloat sizeFactor = (NSWidth(self.bounds) / mbgl::util::tileSize) * (NSHeight(self.bounds) / mbgl::util::tileSize);
-
+
NSUInteger cacheSize = zoomFactor * cpuFactor * memoryFactor * sizeFactor * 0.5;
-
+
_mbglMap->setSourceTileCacheSize(cacheSize);
}
- (void)invalidate {
MGLAssertIsMainThread();
-
+
[self.layer setNeedsDisplay];
}
@@ -769,7 +778,7 @@ public:
if (!_mbglMap) {
return;
}
-
+
switch (change) {
case mbgl::MapChangeRegionWillChange:
case mbgl::MapChangeRegionWillChangeAnimated:
@@ -786,7 +795,7 @@ public:
// while animating.
[self updateCompass];
[self updateAnnotationCallouts];
-
+
if ([self.delegate respondsToSelector:@selector(mapViewCameraIsChanging:)]) {
[self.delegate mapViewCameraIsChanging:self];
}
@@ -804,7 +813,7 @@ public:
[self updateCompass];
[self updateAnnotationCallouts];
[self updateAnnotationTrackingAreas];
-
+
if ([self.delegate respondsToSelector:@selector(mapView:cameraDidChangeAnimated:)]) {
BOOL animated = change == mbgl::MapChangeRegionDidChangeAnimated;
[self.delegate mapView:self cameraDidChangeAnimated:animated];
@@ -865,6 +874,14 @@ public:
}
break;
}
+ case mbgl::MapChangeDidFinishLoadingStyle:
+ {
+ if ([self.delegate respondsToSelector:@selector(mapView:didFinishLoadingStyle:)])
+ {
+ [self.delegate mapView:self didFinishLoadingStyle:self.style];
+ }
+ break;
+ }
}
}
@@ -878,7 +895,7 @@ public:
- (void)printWithImage:(NSImage *)image {
NSImageView *imageView = [[NSImageView alloc] initWithFrame:self.bounds];
imageView.image = image;
-
+
NSPrintOperation *op = [NSPrintOperation printOperationWithView:imageView];
[op runOperation];
}
@@ -1045,7 +1062,7 @@ public:
if ([self.camera isEqual:camera]) {
return;
}
-
+
mbgl::CameraOptions cameraOptions = [self cameraOptionsObjectForAnimatingToCamera:camera];
mbgl::AnimationOptions animationOptions;
if (duration > 0) {
@@ -1062,7 +1079,7 @@ public:
});
};
}
-
+
[self willChangeValueForKey:@"camera"];
_mbglMap->easeTo(cameraOptions, animationOptions);
[self didChangeValueForKey:@"camera"];
@@ -1081,7 +1098,7 @@ public:
if ([self.camera isEqual:camera]) {
return;
}
-
+
mbgl::CameraOptions cameraOptions = [self cameraOptionsObjectForAnimatingToCamera:camera];
mbgl::AnimationOptions animationOptions;
if (duration >= 0) {
@@ -1103,7 +1120,7 @@ public:
});
};
}
-
+
[self willChangeValueForKey:@"camera"];
_mbglMap->flyTo(cameraOptions, animationOptions);
[self didChangeValueForKey:@"camera"];
@@ -1145,7 +1162,7 @@ public:
- (void)setVisibleCoordinateBounds:(MGLCoordinateBounds)bounds edgePadding:(NSEdgeInsets)insets animated:(BOOL)animated {
_mbglMap->cancelTransitions();
-
+
mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(insets);
padding += MGLEdgeInsetsFromNSEdgeInsets(self.contentInsets);
mbgl::CameraOptions cameraOptions = _mbglMap->cameraForLatLngBounds(MGLLatLngBoundsFromCoordinateBounds(bounds), padding);
@@ -1153,7 +1170,7 @@ public:
if (animated) {
animationOptions.duration = MGLDurationInSeconds(MGLAnimationDuration);
}
-
+
[self willChangeValueForKey:@"visibleCoordinateBounds"];
animationOptions.transitionFinishFn = ^() {
[self didChangeValueForKey:@"visibleCoordinateBounds"];
@@ -1196,7 +1213,7 @@ public:
if (!_automaticallyAdjustsContentInsets) {
return;
}
-
+
NSEdgeInsets contentInsets = self.contentInsets;
if ((self.window.styleMask & NSFullSizeContentViewWindowMask)
&& !self.window.titlebarAppearsTransparent) {
@@ -1210,7 +1227,7 @@ public:
} else {
contentInsets = NSEdgeInsetsZero;
}
-
+
self.contentInsets = contentInsets;
}
@@ -1222,7 +1239,7 @@ public:
if (NSEdgeInsetsEqual(contentInsets, self.contentInsets)) {
return;
}
-
+
// After adjusting the content insets, move the center coordinate from the
// old frame of reference to the new one represented by the newly set
// content insets.
@@ -1243,12 +1260,12 @@ public:
NSPoint delta = [gestureRecognizer translationInView:self];
NSPoint endPoint = [gestureRecognizer locationInView:self];
NSPoint startPoint = NSMakePoint(endPoint.x - delta.x, endPoint.y - delta.y);
-
+
NSEventModifierFlags flags = [NSApp currentEvent].modifierFlags;
if (gestureRecognizer.state == NSGestureRecognizerStateBegan) {
[self.window invalidateCursorRectsForView:self];
_mbglMap->setGestureInProgress(true);
-
+
if (![self isPanningWithGesture]) {
// Hide the cursor except when panning.
CGDisplayHideCursor(kCGDirectMainDisplay);
@@ -1258,7 +1275,7 @@ public:
|| gestureRecognizer.state == NSGestureRecognizerStateCancelled) {
_mbglMap->setGestureInProgress(false);
[self.window invalidateCursorRectsForView:self];
-
+
if (_didHideCursorDuringGesture) {
_didHideCursorDuringGesture = NO;
// Move the cursor back to the start point and show it again, creating
@@ -1270,15 +1287,15 @@ public:
CGDisplayShowCursor(kCGDirectMainDisplay);
}
}
-
+
if (flags & NSShiftKeyMask) {
// Shift-drag to zoom.
if (!self.zoomEnabled) {
return;
}
-
+
_mbglMap->cancelTransitions();
-
+
if (gestureRecognizer.state == NSGestureRecognizerStateBegan) {
_scaleAtBeginningOfGesture = _mbglMap->getScale();
} else if (gestureRecognizer.state == NSGestureRecognizerStateChanged) {
@@ -1288,7 +1305,7 @@ public:
} else if (flags & NSAlternateKeyMask) {
// Option-drag to rotate and/or tilt.
_mbglMap->cancelTransitions();
-
+
if (gestureRecognizer.state == NSGestureRecognizerStateBegan) {
_directionAtBeginningOfGesture = self.direction;
_pitchAtBeginningOfGesture = _mbglMap->getPitch();
@@ -1307,7 +1324,7 @@ public:
} else if (self.scrollEnabled) {
// Otherwise, drag to pan.
_mbglMap->cancelTransitions();
-
+
if (gestureRecognizer.state == NSGestureRecognizerStateChanged) {
delta.y *= -1;
[self offsetCenterCoordinateBy:delta animated:NO];
@@ -1329,9 +1346,9 @@ public:
if (!self.zoomEnabled) {
return;
}
-
+
_mbglMap->cancelTransitions();
-
+
if (gestureRecognizer.state == NSGestureRecognizerStateBegan) {
_mbglMap->setGestureInProgress(true);
_scaleAtBeginningOfGesture = _mbglMap->getScale();
@@ -1357,7 +1374,7 @@ public:
|| [self subviewContainingGesture:gestureRecognizer]) {
return;
}
-
+
NSPoint gesturePoint = [gestureRecognizer locationInView:self];
MGLAnnotationTag hitAnnotationTag = [self annotationTagAtPoint:gesturePoint persistingResults:YES];
if (hitAnnotationTag != MGLAnnotationTagNotFound) {
@@ -1385,9 +1402,9 @@ public:
|| [self subviewContainingGesture:gestureRecognizer]) {
return;
}
-
+
_mbglMap->cancelTransitions();
-
+
NSPoint gesturePoint = [gestureRecognizer locationInView:self];
[self scaleBy:2 atPoint:gesturePoint animated:YES];
}
@@ -1396,9 +1413,9 @@ public:
if (!self.zoomEnabled) {
return;
}
-
+
_mbglMap->cancelTransitions();
-
+
// Tap with two fingers (“right-click”) to zoom out on mice but not trackpads.
NSPoint gesturePoint = [self convertPoint:event.locationInWindow fromView:nil];
[self scaleBy:0.5 atPoint:gesturePoint animated:YES];
@@ -1409,9 +1426,9 @@ public:
if (!self.rotateEnabled) {
return;
}
-
+
_mbglMap->cancelTransitions();
-
+
if (gestureRecognizer.state == NSGestureRecognizerStateBegan) {
_mbglMap->setGestureInProgress(true);
_directionAtBeginningOfGesture = self.direction;
@@ -1455,13 +1472,13 @@ public:
&& _rotationGestureRecognizer.state == NSGestureRecognizerStatePossible) {
// Scroll to pan.
_mbglMap->cancelTransitions();
-
+
CGFloat x = event.scrollingDeltaX;
CGFloat y = event.scrollingDeltaY;
if (x || y) {
[self offsetCenterCoordinateBy:NSMakePoint(x, y) animated:NO];
}
-
+
// Drift pan.
if (event.momentumPhase != NSEventPhaseNone) {
[self offsetCenterCoordinateBy:NSMakePoint(x, y) animated:NO];
@@ -1573,7 +1590,7 @@ public:
if (_annotationContextsByAnnotationTag.empty()) {
return nil;
}
-
+
// Map all the annotation tags to the annotations themselves.
std::vector<id <MGLAnnotation>> annotations;
std::transform(_annotationContextsByAnnotationTag.begin(),
@@ -1590,7 +1607,7 @@ public:
if (!_annotationContextsByAnnotationTag.count(tag)) {
return nil;
}
-
+
MGLAnnotationContext &annotationContext = _annotationContextsByAnnotationTag[tag];
return annotationContext.annotation;
}
@@ -1600,7 +1617,7 @@ public:
if (!annotation) {
return MGLAnnotationTagNotFound;
}
-
+
for (auto &pair : _annotationContextsByAnnotationTag) {
if (pair.second.annotation == annotation) {
return pair.first;
@@ -1619,21 +1636,21 @@ public:
if (!annotations) {
return;
}
-
+
[self willChangeValueForKey:@"annotations"];
-
+
BOOL delegateHasImagesForAnnotations = [self.delegate respondsToSelector:@selector(mapView:imageForAnnotation:)];
-
+
for (id <MGLAnnotation> annotation in annotations) {
NSAssert([annotation conformsToProtocol:@protocol(MGLAnnotation)], @"Annotation does not conform to MGLAnnotation");
-
+
if ([annotation isKindOfClass:[MGLMultiPoint class]]) {
// Actual multipoints aren’t supported as annotations.
if ([annotation isMemberOfClass:[MGLMultiPoint class]]
|| [annotation isMemberOfClass:[MGLMultiPointFeature class]]) {
continue;
}
-
+
// The multipoint knows how to style itself (with the map view’s help).
MGLMultiPoint *multiPoint = (MGLMultiPoint *)annotation;
if (!multiPoint.pointCount) {
@@ -1659,13 +1676,13 @@ public:
if (!annotationImage) {
annotationImage = self.defaultAnnotationImage;
}
-
+
NSString *symbolName = annotationImage.styleIconIdentifier;
if (!symbolName) {
symbolName = [MGLAnnotationSpritePrefix stringByAppendingString:annotationImage.reuseIdentifier];
annotationImage.styleIconIdentifier = symbolName;
}
-
+
if (!self.annotationImagesByIdentifier[annotationImage.reuseIdentifier]) {
self.annotationImagesByIdentifier[annotationImage.reuseIdentifier] = annotationImage;
[self installAnnotationImage:annotationImage];
@@ -1680,7 +1697,7 @@ public:
context.annotation = annotation;
context.imageReuseIdentifier = annotationImage.reuseIdentifier;
_annotationContextsByAnnotationTag[annotationTag] = context;
-
+
if ([annotation isKindOfClass:[NSObject class]]) {
NSAssert(![annotation isKindOfClass:[MGLMultiPoint class]], @"Point annotation should not be MGLMultiPoint.");
[(NSObject *)annotation addObserver:self forKeyPath:@"coordinate" options:0 context:(void *)(NSUInteger)annotationTag];
@@ -1694,7 +1711,7 @@ public:
}
[self didChangeValueForKey:@"annotations"];
-
+
[self updateAnnotationTrackingAreas];
}
@@ -1716,36 +1733,23 @@ public:
- (void)installAnnotationImage:(MGLAnnotationImage *)annotationImage {
NSString *iconIdentifier = annotationImage.styleIconIdentifier;
self.annotationImagesByIdentifier[annotationImage.reuseIdentifier] = annotationImage;
-
+
NSImage *image = annotationImage.image;
NSSize size = image.size;
if (size.width == 0 || size.height == 0 || !image.valid) {
// Can’t create an empty sprite. An image that hasn’t loaded is also useless.
return;
}
-
- // Create a bitmap image representation from the image, respecting backing
- // scale factor and any resizing done on the image at runtime.
- // http://www.cocoabuilder.com/archive/cocoa/82430-nsimage-getting-raw-bitmap-data.html#82431
- [image lockFocus];
- NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:{ NSZeroPoint, size }];
- [image unlockFocus];
-
- // Get the image’s raw pixel data as an RGBA buffer.
- std::string pixelString((const char *)rep.bitmapData, rep.pixelsWide * rep.pixelsHigh * 4 /* RGBA */);
-
- mbgl::PremultipliedImage cPremultipliedImage(rep.pixelsWide, rep.pixelsHigh);
- std::copy(rep.bitmapData, rep.bitmapData + cPremultipliedImage.size(), cPremultipliedImage.data.get());
- auto cSpriteImage = std::make_shared<mbgl::SpriteImage>(std::move(cPremultipliedImage),
- (float)(rep.pixelsWide / size.width));
- _mbglMap->addAnnotationIcon(iconIdentifier.UTF8String, cSpriteImage);
-
+
+ std::shared_ptr<mbgl::SpriteImage> sprite(annotationImage.image.mgl_spriteImage);
+ _mbglMap->addAnnotationIcon(iconIdentifier.UTF8String, sprite);
+
// Create a slop area with a “radius” equal to the annotation image’s entire
// size, allowing the eventual click to be on any point within this image.
// Union this slop area with any existing slop areas.
_unionedAnnotationImageSize = NSMakeSize(MAX(_unionedAnnotationImageSize.width, size.width),
MAX(_unionedAnnotationImageSize.height, size.height));
-
+
// Opt into potentially expensive cursor tracking areas.
if (annotationImage.cursor) {
_wantsCursorRects = YES;
@@ -1762,12 +1766,12 @@ public:
if (!annotations) {
return;
}
-
+
[self willChangeValueForKey:@"annotations"];
for (id <MGLAnnotation> annotation in annotations) {
NSAssert([annotation conformsToProtocol:@protocol(MGLAnnotation)], @"Annotation does not conform to MGLAnnotation");
-
+
MGLAnnotationTag annotationTag = [self annotationTagForAnnotation:annotation];
NSAssert(annotationTag != MGLAnnotationTagNotFound, @"No ID for annotation %@", annotation);
@@ -1777,9 +1781,9 @@ public:
if (annotationTag == _lastSelectedAnnotationTag) {
_lastSelectedAnnotationTag = MGLAnnotationTagNotFound;
}
-
+
_annotationContextsByAnnotationTag.erase(annotationTag);
-
+
if ([annotation isKindOfClass:[NSObject class]] &&
![annotation isKindOfClass:[MGLMultiPoint class]]) {
[(NSObject *)annotation removeObserver:self forKeyPath:@"coordinate" context:(void *)(NSUInteger)annotationTag];
@@ -1789,9 +1793,9 @@ public:
_mbglMap->removeAnnotation(annotationTag);
}
-
+
[self didChangeValueForKey:@"annotations"];
-
+
[self updateAnnotationTrackingAreas];
}
@@ -1805,11 +1809,11 @@ public:
/**
Returns the tag of the annotation at the given point in the view.
-
+
This is more involved than it sounds: if multiple point annotations overlap
near the point, this method cycles through them so that each of them is
accessible to the user at some point.
-
+
@param persist True to remember the cycleable set of annotations, so that a
different annotation is returned the next time this method is called
with the same point. Setting this parameter to false is useful for
@@ -1825,13 +1829,13 @@ public:
queryRect = NSInsetRect(queryRect, -MGLAnnotationImagePaddingForHitTest,
-MGLAnnotationImagePaddingForHitTest);
std::vector<MGLAnnotationTag> nearbyAnnotations = [self annotationTagsInRect:queryRect];
-
+
if (nearbyAnnotations.size()) {
// Assume that the user is fat-fingering an annotation.
NSRect hitRect = NSInsetRect({ point, NSZeroSize },
-MGLAnnotationImagePaddingForHitTest,
-MGLAnnotationImagePaddingForHitTest);
-
+
// Filter out any annotation whose image is unselectable or for which
// hit testing fails.
auto end = std::remove_if(nearbyAnnotations.begin(), nearbyAnnotations.end(), [&](const MGLAnnotationTag annotationTag) {
@@ -1840,12 +1844,12 @@ public:
if (!annotation) {
return true;
}
-
+
MGLAnnotationImage *annotationImage = [self imageOfAnnotationWithTag:annotationTag];
if (!annotationImage.selectable) {
return true;
}
-
+
// Filter out the annotation if the fattened finger didn’t land on a
// translucent or opaque pixel in the image.
NSRect annotationRect = [self frameOfImage:annotationImage.image
@@ -1855,13 +1859,13 @@ public:
});
nearbyAnnotations.resize(std::distance(nearbyAnnotations.begin(), end));
}
-
+
MGLAnnotationTag hitAnnotationTag = MGLAnnotationTagNotFound;
if (nearbyAnnotations.size()) {
// The annotation tags need to be stable in order to compare them with
// the remembered tags.
std::sort(nearbyAnnotations.begin(), nearbyAnnotations.end());
-
+
if (nearbyAnnotations == _annotationsNearbyLastClick) {
// The first selection in the cycle should be the one nearest to the
// click.
@@ -1875,7 +1879,7 @@ public:
coordinateB.longitude - currentCoordinate.longitude);
return distanceA < distanceB;
});
-
+
// The last time we persisted a set of annotations, we had the same
// set of annotations as we do now. Cycle through them.
if (_lastSelectedAnnotationTag == MGLAnnotationTagNotFound
@@ -1904,14 +1908,14 @@ public:
if (persist) {
_annotationsNearbyLastClick = nearbyAnnotations;
}
-
+
// Choose the first nearby annotation.
if (nearbyAnnotations.size()) {
hitAnnotationTag = nearbyAnnotations.front();
}
}
}
-
+
return hitAnnotationTag;
}
@@ -1950,13 +1954,13 @@ public:
if (!selectedAnnotations.count) {
return;
}
-
+
id <MGLAnnotation> firstAnnotation = selectedAnnotations[0];
NSAssert([firstAnnotation conformsToProtocol:@protocol(MGLAnnotation)], @"Annotation does not conform to MGLAnnotation");
if ([firstAnnotation isKindOfClass:[MGLMultiPoint class]]) {
return;
}
-
+
// Select the annotation if it’s visible.
if (MGLCoordinateInCoordinateBounds(firstAnnotation.coordinate, self.visibleCoordinateBounds)) {
[self selectAnnotation:firstAnnotation];
@@ -1969,29 +1973,29 @@ public:
if (!annotation || [annotation isKindOfClass:[MGLMultiPoint class]]) {
return;
}
-
+
id <MGLAnnotation> selectedAnnotation = self.selectedAnnotation;
if (annotation == selectedAnnotation) {
return;
}
-
+
// Deselect the annotation before reselecting it.
[self deselectAnnotation:selectedAnnotation];
-
+
// Add the annotation to the map if it hasn’t been added yet.
MGLAnnotationTag annotationTag = [self annotationTagForAnnotation:annotation];
if (annotationTag == MGLAnnotationTagNotFound) {
[self addAnnotation:annotation];
}
-
+
// The annotation can’t be selected if no part of it is hittable.
NSRect positioningRect = [self positioningRectForCalloutForAnnotationWithTag:annotationTag];
if (NSIsEmptyRect(NSIntersectionRect(positioningRect, self.bounds))) {
return;
}
-
+
self.selectedAnnotation = annotation;
-
+
// For the callout to be shown, the annotation must have a title, its
// callout must not already be shown, and the annotation must be able to
// show a callout according to the delegate.
@@ -2001,7 +2005,7 @@ public:
&& [self.delegate respondsToSelector:@selector(mapView:annotationCanShowCallout:)]
&& [self.delegate mapView:self annotationCanShowCallout:annotation]) {
NSPopover *callout = [self calloutForAnnotation:annotation];
-
+
// Hang the callout off the right edge of the annotation image’s
// alignment rect, or off the left edge in a right-to-left UI.
callout.delegate = self;
@@ -2049,7 +2053,7 @@ public:
- (NSPopover *)calloutForAnnotation:(id <MGLAnnotation>)annotation {
NSPopover *callout = [[NSPopover alloc] init];
callout.behavior = NSPopoverBehaviorTransient;
-
+
NSViewController *viewController;
if ([self.delegate respondsToSelector:@selector(mapView:calloutViewControllerForAnnotation:)]) {
NSViewController *viewControllerFromDelegate = [self.delegate mapView:self
@@ -2066,7 +2070,7 @@ public:
// annotation.
viewController.representedObject = annotation;
callout.contentViewController = viewController;
-
+
return callout;
}
@@ -2094,7 +2098,7 @@ public:
if (!image) {
return NSZeroRect;
}
-
+
NSRect positioningRect = [self frameOfImage:image centeredAtCoordinate:annotation.coordinate];
positioningRect = NSOffsetRect(image.alignmentRect, positioningRect.origin.x, positioningRect.origin.y);
return NSInsetRect(positioningRect, -MGLAnnotationImagePaddingForCallout,
@@ -2114,10 +2118,10 @@ public:
|| _annotationContextsByAnnotationTag.count(annotationTag) == 0) {
return nil;
}
-
+
NSString *customSymbol = _annotationContextsByAnnotationTag.at(annotationTag).imageReuseIdentifier;
NSString *symbolName = customSymbol.length ? customSymbol : MGLDefaultStyleMarkerSymbolName;
-
+
return [self dequeueReusableAnnotationImageWithIdentifier:symbolName];
}
@@ -2125,11 +2129,11 @@ public:
if (!annotation || self.selectedAnnotation != annotation) {
return;
}
-
+
// Close the callout popover gracefully.
NSPopover *callout = self.calloutForSelectedAnnotation;
[callout performClose:self];
-
+
self.selectedAnnotation = nil;
}
@@ -2159,8 +2163,18 @@ public:
#pragma mark MGLMultiPointDelegate methods
- (double)alphaForShapeAnnotation:(MGLShape *)annotation {
+ // The explicit -mapView:alphaForShapeAnnotation: delegate method is deprecated
+ // but still used, if implemented. When not implemented, call the stroke or
+ // fill color delegate methods and pull the alpha from the returned color.
if (_delegateHasAlphasForShapeAnnotations) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
return [self.delegate mapView:self alphaForShapeAnnotation:annotation];
+#pragma clang diagnostic pop
+ } else if ([annotation isKindOfClass:[MGLPolygon class]]) {
+ return [self fillColorForPolygonAnnotation:(MGLPolygon *)annotation].a ?: 1.0;
+ } else if ([annotation isKindOfClass:[MGLShape class]]) {
+ return [self strokeColorForShapeAnnotation:annotation].a ?: 1.0;
}
return 1.0;
}
@@ -2169,14 +2183,14 @@ public:
NSColor *color = (_delegateHasStrokeColorsForShapeAnnotations
? [self.delegate mapView:self strokeColorForShapeAnnotation:annotation]
: [NSColor selectedMenuItemColor]);
- return color.mbgl_color;
+ return color.mgl_color;
}
- (mbgl::Color)fillColorForPolygonAnnotation:(MGLPolygon *)annotation {
NSColor *color = (_delegateHasFillColorsForShapeAnnotations
? [self.delegate mapView:self fillColorForPolygonAnnotation:annotation]
: [NSColor selectedMenuItemColor]);
- return color.mbgl_color;
+ return color.mgl_color;
}
- (CGFloat)lineWidthForPolylineAnnotation:(MGLPolyline *)annotation {
@@ -2201,7 +2215,7 @@ public:
id <MGLAnnotation> annotation = self.calloutForSelectedAnnotation.contentViewController.representedObject;
self.calloutForSelectedAnnotation = nil;
self.selectedAnnotation = nil;
-
+
if ([self.delegate respondsToSelector:@selector(mapView:didDeselectAnnotation:)]) {
[self.delegate mapView:self didDeselectAnnotation:annotation];
}
@@ -2258,7 +2272,7 @@ public:
}
}
}
-
+
// Blow away any cursor tracking areas and rebuild them. That’s the
// potentially expensive part.
if (_wantsCursorRects) {
@@ -2279,13 +2293,13 @@ public:
[self addCursorRect:self.bounds cursor:[NSCursor closedHandCursor]];
return;
}
-
+
// The rest of this method can be expensive, so bail if no annotations have
// ever had custom cursors.
if (!_wantsCursorRects) {
return;
}
-
+
std::vector<MGLAnnotationTag> annotationTags = [self annotationTagsInRect:self.bounds];
for (MGLAnnotationTag annotationTag : annotationTags) {
id <MGLAnnotation> annotation = [self annotationWithTag:annotationTag];
@@ -2311,7 +2325,7 @@ public:
- (NS_ARRAY_OF(id <MGLFeature>) *)visibleFeaturesAtPoint:(NSPoint)point inStyleLayersWithIdentifiers:(NS_SET_OF(NSString *) *)styleLayerIdentifiers {
// Cocoa origin is at the lower-left corner.
mbgl::ScreenCoordinate screenCoordinate = { point.x, NSHeight(self.bounds) - point.y };
-
+
mbgl::optional<std::vector<std::string>> optionalLayerIDs;
if (styleLayerIdentifiers) {
__block std::vector<std::string> layerIDs;
@@ -2321,7 +2335,7 @@ public:
}];
optionalLayerIDs = layerIDs;
}
-
+
std::vector<mbgl::Feature> features = _mbglMap->queryRenderedFeatures(screenCoordinate, optionalLayerIDs);
return MGLFeaturesFromMBGLFeatures(features);
}
@@ -2336,7 +2350,7 @@ public:
{ NSMinX(rect), NSHeight(self.bounds) - NSMaxY(rect) },
{ NSMaxX(rect), NSHeight(self.bounds) - NSMinY(rect) },
};
-
+
mbgl::optional<std::vector<std::string>> optionalLayerIDs;
if (styleLayerIdentifiers) {
__block std::vector<std::string> layerIDs;
@@ -2346,7 +2360,7 @@ public:
}];
optionalLayerIDs = layerIDs;
}
-
+
std::vector<mbgl::Feature> features = _mbglMap->queryRenderedFeatures(screenBox, optionalLayerIDs);
return MGLFeaturesFromMBGLFeatures(features);
}
@@ -2355,7 +2369,7 @@ public:
- (void)prepareForInterfaceBuilder {
[super prepareForInterfaceBuilder];
-
+
// Color the background a glorious Mapbox teal.
self.layer.borderColor = [NSColor colorWithRed:59/255.
green:178/255.
@@ -2366,7 +2380,7 @@ public:
green:178/255.
blue:208/255.
alpha:0.6].CGColor;
-
+
// Place a playful marker right smack dab in the middle.
self.layer.contents = MGLDefaultMarkerImage();
self.layer.contentsGravity = kCAGravityCenter;
@@ -2425,7 +2439,7 @@ public:
bounds.extend([self convertPoint:{ NSMaxX(rect), NSMinY(rect) } toLatLngFromView:view]);
bounds.extend([self convertPoint:{ NSMaxX(rect), NSMaxY(rect) } toLatLngFromView:view]);
bounds.extend([self convertPoint:{ NSMinX(rect), NSMaxY(rect) } toLatLngFromView:view]);
-
+
// The world is wrapping if a point just outside the bounds is also within
// the rect.
mbgl::LatLng outsideLatLng;
@@ -2440,13 +2454,13 @@ public:
bounds.east() + 1,
};
}
-
+
// If the world is wrapping, extend the bounds to cover all longitudes.
if (NSPointInRect([self convertLatLng:outsideLatLng toPointToView:view], rect)) {
bounds.extend(mbgl::LatLng(bounds.south(), -180));
bounds.extend(mbgl::LatLng(bounds.south(), 180));
}
-
+
return bounds;
}
@@ -2554,7 +2568,7 @@ public:
mbgl::PremultipliedImage image { size[0], size[1] };
MBGL_CHECK_ERROR(glReadPixels(0, 0, size[0], size[1], GL_RGBA, GL_UNSIGNED_BYTE, image.data.get()));
-
+
const size_t stride = image.stride();
auto tmp = std::make_unique<uint8_t[]>(stride);
uint8_t *rgba = image.data.get();
@@ -2563,14 +2577,14 @@ public:
std::memcpy(rgba + i * stride, rgba + j * stride, stride);
std::memcpy(rgba + j * stride, tmp.get(), stride);
}
-
+
return image;
}
-
+
private:
/// Cocoa map view that this adapter bridges to.
__weak MGLMapView *nativeView = nullptr;
-
+
/// Backing scale factor of the view.
const float scaleFactor;
};
diff --git a/platform/macos/src/MGLMapViewDelegate.h b/platform/macos/src/MGLMapViewDelegate.h
index 8f4922d304..c5af93f8ad 100644
--- a/platform/macos/src/MGLMapViewDelegate.h
+++ b/platform/macos/src/MGLMapViewDelegate.h
@@ -125,6 +125,23 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (void)mapViewDidFinishRenderingFrame:(MGLMapView *)mapView fullyRendered:(BOOL)fullyRendered;
+/**
+ Tells the delegate that the map has just finished loading a style.
+
+ This method is called during the initialization of the map view and after any
+ subsequent loading of a new style. This method is called between the
+ `-mapViewWillStartRenderingMap:` and `-mapViewDidFinishRenderingMap:` delegate
+ methods. Changes to sources or layers of the current style do not cause this
+ method to be called.
+
+ This method is the earliest opportunity to modify the layout or appearance of
+ the current style before the map view is displayed to the user.
+
+ @param mapView The map view that has just loaded a style.
+ @param style The style that was loaded.
+ */
+- (void)mapView:(MGLMapView *)mapView didFinishLoadingStyle:(MGLStyle *)style;
+
#pragma mark Managing the Appearance of Annotations
/**
@@ -139,17 +156,7 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (nullable MGLAnnotationImage *)mapView:(MGLMapView *)mapView imageForAnnotation:(id <MGLAnnotation>)annotation;
-/**
- Returns the alpha value to use when rendering a shape annotation.
-
- A value of 0.0 results in a completely transparent shape. A value of 1.0, the
- default, results in a completely opaque shape.
-
- @param mapView The map view rendering the shape annotation.
- @param annotation The annotation being rendered.
- @return An alpha value between 0 and 1.0.
- */
-- (CGFloat)mapView:(MGLMapView *)mapView alphaForShapeAnnotation:(MGLShape *)annotation;
+- (CGFloat)mapView:(MGLMapView *)mapView alphaForShapeAnnotation:(MGLShape *)annotation __attribute__((deprecated("Use -mapView:strokeColorForShapeAnnotation: or -mapView:fillColorForPolygonAnnotation:.")));
/**
Returns the color to use when rendering the outline of a shape annotation.
@@ -157,6 +164,9 @@ NS_ASSUME_NONNULL_BEGIN
The default stroke color is the selected menu item color. If a pattern color is
specified, the result is undefined.
+ Opacity may be set by specifying an alpha component. The default alpha value is
+ `1.0` and results in a completely opaque stroke.
+
@param mapView The map view rendering the shape annotation.
@param annotation The annotation being rendered.
@return A color to use for the shape outline.
@@ -169,6 +179,9 @@ NS_ASSUME_NONNULL_BEGIN
The default fill color is the selected menu item color. If a pattern color is
specified, the result is undefined.
+ Opacity may be set by specifying an alpha component. The default alpha value is
+ `1.0` and results in a completely opaque shape.
+
@param mapView The map view rendering the polygon annotation.
@param annotation The annotation being rendered.
@return The polygon’s interior fill color.
diff --git a/platform/macos/src/Mapbox.h b/platform/macos/src/Mapbox.h
index 0217bca44a..67e3775100 100644
--- a/platform/macos/src/Mapbox.h
+++ b/platform/macos/src/Mapbox.h
@@ -30,7 +30,8 @@ FOUNDATION_EXPORT const unsigned char MapboxVersionString[];
#import "MGLShapeCollection.h"
#import "MGLStyle.h"
#import "MGLStyleLayer.h"
-#import "MGLBaseStyleLayer.h"
+#import "MGLForegroundStyleLayer.h"
+#import "MGLVectorStyleLayer.h"
#import "MGLFillStyleLayer.h"
#import "MGLLineStyleLayer.h"
#import "MGLSymbolStyleLayer.h"
@@ -44,10 +45,4 @@ FOUNDATION_EXPORT const unsigned char MapboxVersionString[];
#import "MGLTilePyramidOfflineRegion.h"
#import "MGLTypes.h"
#import "NSValue+MGLAdditions.h"
-#import "MGLStyleAttributeValue.h"
-#import "MGLStyleAttributeFunction.h"
-#import "NSColor+MGLStyleAttributeAdditions.h"
-#import "NSNumber+MGLStyleAttributeAdditions.h"
-#import "NSValue+MGLStyleAttributeAdditions.h"
-#import "NSString+MGLStyleAttributeAdditions.h"
-#import "NSArray+MGLStyleAttributeAdditions.h"
+#import "MGLStyleValue.h"
diff --git a/platform/macos/src/NSColor+MGLAdditions.h b/platform/macos/src/NSColor+MGLAdditions.h
index 2ba38f7d90..8dd8c1c17c 100644
--- a/platform/macos/src/NSColor+MGLAdditions.h
+++ b/platform/macos/src/NSColor+MGLAdditions.h
@@ -8,13 +8,13 @@
/**
Converts the color into an mbgl::Color in calibrated RGB space.
*/
-- (mbgl::Color)mbgl_color;
+- (mbgl::Color)mgl_color;
/**
Instantiates `NSColor` from an `mbgl::Color`
*/
-+ (NSColor *)mbgl_colorWithColor:(mbgl::Color)color;
++ (NSColor *)mgl_colorWithColor:(mbgl::Color)color;
-- (mbgl::style::PropertyValue<mbgl::Color>)mbgl_colorPropertyValue;
+- (mbgl::style::PropertyValue<mbgl::Color>)mgl_colorPropertyValue;
@end
diff --git a/platform/macos/src/NSColor+MGLAdditions.mm b/platform/macos/src/NSColor+MGLAdditions.mm
index a75dc488fd..e347fd1798 100644
--- a/platform/macos/src/NSColor+MGLAdditions.mm
+++ b/platform/macos/src/NSColor+MGLAdditions.mm
@@ -2,7 +2,7 @@
@implementation NSColor (MGLAdditions)
-- (mbgl::Color)mbgl_color
+- (mbgl::Color)mgl_color
{
CGFloat r, g, b, a;
@@ -11,14 +11,14 @@
return { (float)r, (float)g, (float)b, (float)a };
}
-+ (NSColor *)mbgl_colorWithColor:(mbgl::Color)color
++ (NSColor *)mgl_colorWithColor:(mbgl::Color)color
{
return [NSColor colorWithRed:color.r green:color.g blue:color.b alpha:color.a];
}
-- (mbgl::style::PropertyValue<mbgl::Color>)mbgl_colorPropertyValue
+- (mbgl::style::PropertyValue<mbgl::Color>)mgl_colorPropertyValue
{
- mbgl::Color color = self.mbgl_color;
+ mbgl::Color color = self.mgl_color;
return {{ color.r, color.g, color.b, color.a }};
}
diff --git a/platform/macos/src/NSImage+MGLAdditions.h b/platform/macos/src/NSImage+MGLAdditions.h
new file mode 100644
index 0000000000..a2144e96a2
--- /dev/null
+++ b/platform/macos/src/NSImage+MGLAdditions.h
@@ -0,0 +1,9 @@
+#import <Cocoa/Cocoa.h>
+
+#include <mbgl/sprite/sprite_image.hpp>
+
+@interface NSImage (MGLAdditions)
+
+- (std::unique_ptr<mbgl::SpriteImage>)mgl_spriteImage;
+
+@end
diff --git a/platform/macos/src/NSImage+MGLAdditions.mm b/platform/macos/src/NSImage+MGLAdditions.mm
new file mode 100644
index 0000000000..7d02271bb3
--- /dev/null
+++ b/platform/macos/src/NSImage+MGLAdditions.mm
@@ -0,0 +1,22 @@
+#import "NSImage+MGLAdditions.h"
+
+@implementation NSImage (MGLAdditions)
+
+- (std::unique_ptr<mbgl::SpriteImage>)mgl_spriteImage {
+ // Create a bitmap image representation from the image, respecting backing
+ // scale factor and any resizing done on the image at runtime.
+ // http://www.cocoabuilder.com/archive/cocoa/82430-nsimage-getting-raw-bitmap-data.html#82431
+ [self lockFocus];
+ NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:{ NSZeroPoint, self.size }];
+ [self unlockFocus];
+
+ // Get the image’s raw pixel data as an RGBA buffer.
+ std::string pixelString((const char *)rep.bitmapData, rep.pixelsWide * rep.pixelsHigh * 4 /* RGBA */);
+
+ mbgl::PremultipliedImage cPremultipliedImage(rep.pixelsWide, rep.pixelsHigh);
+ std::copy(rep.bitmapData, rep.bitmapData + cPremultipliedImage.size(), cPremultipliedImage.data.get());
+ return std::make_unique<mbgl::SpriteImage>(std::move(cPremultipliedImage),
+ (float)(rep.pixelsWide / self.size.width));
+}
+
+@end
diff --git a/platform/node/src/node_map.cpp b/platform/node/src/node_map.cpp
index 1fc9e987c7..4d4be5be66 100644
--- a/platform/node/src/node_map.cpp
+++ b/platform/node/src/node_map.cpp
@@ -61,6 +61,8 @@ void NodeMap::Init(v8::Local<v8::Object> target) {
Nan::SetPrototypeMethod(tpl, "setLayoutProperty", SetLayoutProperty);
Nan::SetPrototypeMethod(tpl, "setPaintProperty", SetPaintProperty);
Nan::SetPrototypeMethod(tpl, "setFilter", SetFilter);
+ Nan::SetPrototypeMethod(tpl, "setCenter", SetCenter);
+ Nan::SetPrototypeMethod(tpl, "setBearing", SetBearing);
Nan::SetPrototypeMethod(tpl, "dumpDebugLogs", DumpDebugLogs);
Nan::SetPrototypeMethod(tpl, "queryRenderedFeatures", QueryRenderedFeatures);
@@ -674,6 +676,46 @@ void NodeMap::SetFilter(const Nan::FunctionCallbackInfo<v8::Value>& info) {
layer->accept(SetFilterVisitor { filter });
}
+void NodeMap::SetCenter(const Nan::FunctionCallbackInfo<v8::Value>& info) {
+ auto nodeMap = Nan::ObjectWrap::Unwrap<NodeMap>(info.Holder());
+ if (!nodeMap->map) return Nan::ThrowError(releasedMessage());
+
+ if (info.Length() <= 0 || !info[0]->IsArray()) {
+ return Nan::ThrowTypeError("First argument must be an array");
+ }
+
+ auto center = info[0].As<v8::Array>();
+ double latitude = 0;
+ double longitude = 0;
+ if (center->Length() > 0) { longitude = Nan::Get(center, 0).ToLocalChecked()->NumberValue(); }
+ if (center->Length() > 1) { latitude = Nan::Get(center, 1).ToLocalChecked()->NumberValue(); }
+
+ try {
+ nodeMap->map->setLatLng(mbgl::LatLng { latitude, longitude });
+ } catch (const std::exception &ex) {
+ return Nan::ThrowError(ex.what());
+ }
+
+ info.GetReturnValue().SetUndefined();
+}
+
+void NodeMap::SetBearing(const Nan::FunctionCallbackInfo<v8::Value>& info) {
+ auto nodeMap = Nan::ObjectWrap::Unwrap<NodeMap>(info.Holder());
+ if (!nodeMap->map) return Nan::ThrowError(releasedMessage());
+
+ if (info.Length() <= 0 || !info[0]->IsNumber()) {
+ return Nan::ThrowTypeError("First argument must be a number");
+ }
+
+ try {
+ nodeMap->map->setBearing(info[0]->NumberValue());
+ } catch (const std::exception &ex) {
+ return Nan::ThrowError(ex.what());
+ }
+
+ info.GetReturnValue().SetUndefined();
+}
+
void NodeMap::DumpDebugLogs(const Nan::FunctionCallbackInfo<v8::Value>& info) {
auto nodeMap = Nan::ObjectWrap::Unwrap<NodeMap>(info.Holder());
if (!nodeMap->map) return Nan::ThrowError(releasedMessage());
diff --git a/platform/node/src/node_map.hpp b/platform/node/src/node_map.hpp
index 5f6176ba75..c0b025c369 100644
--- a/platform/node/src/node_map.hpp
+++ b/platform/node/src/node_map.hpp
@@ -37,6 +37,8 @@ public:
static void SetLayoutProperty(const Nan::FunctionCallbackInfo<v8::Value>&);
static void SetPaintProperty(const Nan::FunctionCallbackInfo<v8::Value>&);
static void SetFilter(const Nan::FunctionCallbackInfo<v8::Value>&);
+ static void SetCenter(const Nan::FunctionCallbackInfo<v8::Value>&);
+ static void SetBearing(const Nan::FunctionCallbackInfo<v8::Value>&);
static void DumpDebugLogs(const Nan::FunctionCallbackInfo<v8::Value>&);
static void QueryRenderedFeatures(const Nan::FunctionCallbackInfo<v8::Value>&);
diff --git a/platform/node/test/js/map.test.js b/platform/node/test/js/map.test.js
index 9300cac4e1..7321572637 100644
--- a/platform/node/test/js/map.test.js
+++ b/platform/node/test/js/map.test.js
@@ -114,6 +114,8 @@ test('Map', function(t) {
'setLayoutProperty',
'setPaintProperty',
'setFilter',
+ 'setCenter',
+ 'setBearing',
'dumpDebugLogs',
'queryRenderedFeatures'
]);
diff --git a/platform/qt/bitrise-qt5.yml b/platform/qt/bitrise-qt5.yml
index 4122012327..e0627f03e5 100644
--- a/platform/qt/bitrise-qt5.yml
+++ b/platform/qt/bitrise-qt5.yml
@@ -34,13 +34,21 @@ workflows:
brew install qt5
brew link qt5 --force
brew linkapps qt5
- ln -s /usr/local/Cellar/qt5/5.6.1-1/mkspecs /usr/local/mkspecs
- ln -s /usr/local/Cellar/qt5/5.6.1-1/plugins /usr/local/plugins
+ export HOMEBREW_QT5_VERSION=$(brew list --versions qt5 | rev | cut -d' ' -f1 | rev)
+ ln -s /usr/local/Cellar/qt5/$HOMEBREW_QT5_VERSION/mkspecs /usr/local/mkspecs
+ ln -s /usr/local/Cellar/qt5/$HOMEBREW_QT5_VERSION/plugins /usr/local/plugins
export BUILDTYPE=Debug
make qt-app
make qt-qml-app
make run-qt-test
- is_debug: 'yes'
+ - deploy-to-bitrise-io:
+ title: Deploy to Bitrise.io
+ run_if: '{{enveq "SKIPCI" "false"}}'
+ inputs:
+ - deploy_path: "test/fixtures"
+ - notify_user_groups: none
+ - is_compress: 'true'
- slack:
title: Post to Slack
run_if: '{{enveq "SKIPCI" "false"}}'
diff --git a/src/mbgl/annotation/annotation_manager.cpp b/src/mbgl/annotation/annotation_manager.cpp
index 63adf9de2a..dbd5f1f433 100644
--- a/src/mbgl/annotation/annotation_manager.cpp
+++ b/src/mbgl/annotation/annotation_manager.cpp
@@ -185,6 +185,7 @@ void AnnotationManager::updateStyle(Style& style) {
layer->setSourceLayer(PointLayerID);
layer->setIconImage({"{sprite}"});
layer->setIconAllowOverlap(true);
+ layer->setIconIgnorePlacement(true);
layer->impl->spriteAtlas = &spriteAtlas;
diff --git a/src/mbgl/geometry/buffer.hpp b/src/mbgl/geometry/buffer.hpp
deleted file mode 100644
index 2d010e39ac..0000000000
--- a/src/mbgl/geometry/buffer.hpp
+++ /dev/null
@@ -1,115 +0,0 @@
-#pragma once
-
-#include <mbgl/gl/context.hpp>
-#include <mbgl/platform/log.hpp>
-#include <mbgl/util/noncopyable.hpp>
-#include <mbgl/util/optional.hpp>
-
-#include <memory>
-#include <cstdlib>
-#include <cassert>
-#include <stdexcept>
-
-namespace mbgl {
-
-template <uint32_t item_size,
- gl::BufferType target = gl::BufferType::Vertex,
- uint32_t defaultLength = 8192,
- bool retainAfterUpload = false>
-class Buffer : private util::noncopyable {
- static_assert(target == gl::BufferType::Vertex || target == gl::BufferType::Element,
- "target must be one of gl::BufferType::Vertex or gl::BufferType::Element");
-
-public:
- ~Buffer() {
- cleanup();
- }
-
- // Returns the number of elements in this buffer. This is not the number of
- // bytes, but rather the number of coordinates with associated information.
- uint32_t index() const {
- return pos / itemSize;
- }
-
- bool empty() const {
- return pos == 0;
- }
-
- // Transfers this buffer to the GPU and binds the buffer to the GL context.
- void bind(gl::Context& context) {
- const bool initialized { buffer };
- if (!initialized) {
- buffer = context.createBuffer();
- }
-
- if (target == gl::BufferType::Vertex) {
- context.vertexBuffer = *buffer;
- } else {
- context.elementBuffer = *buffer;
- }
-
- if (!initialized) {
- if (array == nullptr) {
- Log::Debug(Event::OpenGL, "Buffer doesn't contain elements");
- pos = 0;
- }
- context.uploadBuffer(target, pos, array);
- if (!retainAfterUpload) {
- cleanup();
- }
- }
- }
-
- void cleanup() {
- if (array) {
- free(array);
- array = nullptr;
- }
- }
-
- gl::BufferID getID() const {
- return buffer ? *buffer : 0;
- }
-
- // Uploads the buffer to the GPU to be available when we need it.
- void upload(gl::Context& context) {
- if (!buffer) {
- bind(context);
- }
- }
-
-protected:
- // increase the buffer size by at least /required/ bytes.
- void *addElement() {
- if (buffer) {
- throw std::runtime_error("Can't add elements after buffer was bound to GPU");
- }
- if (length < pos + itemSize) {
- while (length < pos + itemSize) length += defaultLength;
- array = realloc(array, length);
- if (array == nullptr) {
- throw std::runtime_error("Buffer reallocation failed");
- }
- }
- pos += itemSize;
- return reinterpret_cast<char *>(array) + (pos - itemSize);
- }
-
-public:
- static constexpr const uint32_t itemSize = item_size;
-
-private:
- // CPU buffer
- void* array = nullptr;
-
- // Byte position where we are writing.
- uint32_t pos = 0;
-
- // Number of bytes that are valid in this buffer.
- uint32_t length = 0;
-
- // GL buffer object handle.
- mbgl::optional<gl::UniqueBuffer> buffer;
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/circle_buffer.cpp b/src/mbgl/geometry/circle_buffer.cpp
deleted file mode 100644
index cc31fb83bf..0000000000
--- a/src/mbgl/geometry/circle_buffer.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#include <mbgl/geometry/circle_buffer.hpp>
-
-#include <mbgl/gl/gl.hpp>
-
-#include <climits>
-
-namespace mbgl {
-
-void CircleVertexBuffer::add(vertex_type x, vertex_type y, float ex, float ey) {
- vertex_type *vertices = static_cast<vertex_type *>(addElement());
- vertices[0] = (x * 2) + ((ex + 1) / 2);
- vertices[1] = (y * 2) + ((ey + 1) / 2);
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/circle_buffer.hpp b/src/mbgl/geometry/circle_buffer.hpp
deleted file mode 100644
index 2b188c4003..0000000000
--- a/src/mbgl/geometry/circle_buffer.hpp
+++ /dev/null
@@ -1,24 +0,0 @@
-#pragma once
-
-#include <mbgl/geometry/buffer.hpp>
-
-namespace mbgl {
-
-class CircleVertexBuffer : public Buffer<
- 4 // 2 bytes per short * 4 of them.
-> {
-public:
- typedef int16_t vertex_type;
-
- /*
- * Add a vertex to this buffer
- *
- * @param {number} x vertex position
- * @param {number} y vertex position
- * @param {number} ex extrude normal
- * @param {number} ey extrude normal
- */
- void add(vertex_type x, vertex_type y, float ex, float ey);
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/collision_box_buffer.cpp b/src/mbgl/geometry/collision_box_buffer.cpp
deleted file mode 100644
index ae58cf7bca..0000000000
--- a/src/mbgl/geometry/collision_box_buffer.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-#include <mbgl/geometry/collision_box_buffer.hpp>
-#include <mbgl/gl/gl.hpp>
-#include <mbgl/util/math.hpp>
-
-#include <cmath>
-
-namespace mbgl {
-
-uint32_t CollisionBoxVertexBuffer::add(int16_t x, int16_t y, float ox, float oy, float maxzoom, float placementZoom) {
- const uint32_t idx = index();
- void *data = addElement();
-
- int16_t *shorts = static_cast<int16_t *>(data);
- shorts[0] /* pos */ = x;
- shorts[1] /* pos */ = y;
- shorts[2] /* offset */ = ::round(ox); // use 1/64 pixels for placement
- shorts[3] /* offset */ = ::round(oy);
-
- uint8_t *ubytes = static_cast<uint8_t *>(data);
- // a_data
- ubytes[8] = maxzoom * 10;
- ubytes[9] = placementZoom * 10;
-
- return idx;
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/collision_box_buffer.hpp b/src/mbgl/geometry/collision_box_buffer.hpp
deleted file mode 100644
index 5360ac3f4c..0000000000
--- a/src/mbgl/geometry/collision_box_buffer.hpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#pragma once
-
-#include <mbgl/geometry/buffer.hpp>
-#include <array>
-
-namespace mbgl {
-
-class CollisionBoxVertexBuffer : public Buffer <
- 12,
- gl::BufferType::Vertex,
- 32768
-> {
-public:
- typedef int16_t vertex_type;
-
- uint32_t add(int16_t x, int16_t y, float ex, float ey, float maxzoom, float placementZoom);
-};
-
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/debug_font_buffer.cpp b/src/mbgl/geometry/debug_font_buffer.cpp
deleted file mode 100644
index f64ce8816b..0000000000
--- a/src/mbgl/geometry/debug_font_buffer.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-#include <mbgl/geometry/debug_font_buffer.hpp>
-#include <mbgl/geometry/debug_font_data.hpp>
-
-#include <mbgl/gl/gl.hpp>
-#include <cmath>
-#include <cstring>
-
-namespace mbgl {
-
-void DebugFontBuffer::addText(const char *text, double left, double baseline, double scale) {
- uint16_t *coords = nullptr;
-
- const size_t len = strlen(text);
- for (size_t i = 0; i < len; ++i) {
- if (text[i] < 32 || (unsigned char)(text[i]) >= 127) {
- continue;
- }
-
- const glyph& glyph = simplex[text[i] - 32];
-
- int16_t prev_x = -1, prev_y = -1, prev = false;
- for (int32_t j = 0; j < glyph.length; j += 2) {
- if (glyph.data[j] == -1 && glyph.data[j + 1] == -1) {
- prev = false;
- } else {
- int16_t x = ::round(left + glyph.data[j] * scale);
- int16_t y = ::round(baseline - glyph.data[j + 1] * scale);
- if (prev) {
- coords = static_cast<uint16_t *>(addElement());
- coords[0] = prev_x;
- coords[1] = prev_y;
-
- coords = static_cast<uint16_t *>(addElement());
- coords[0] = x;
- coords[1] = y;
- }
- prev_x = x; prev_y = y; prev = true;
- }
- }
- left += glyph.width * scale;
- }
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/debug_font_buffer.hpp b/src/mbgl/geometry/debug_font_buffer.hpp
deleted file mode 100644
index f2debe97a4..0000000000
--- a/src/mbgl/geometry/debug_font_buffer.hpp
+++ /dev/null
@@ -1,14 +0,0 @@
-#pragma once
-
-#include <mbgl/geometry/buffer.hpp>
-
-namespace mbgl {
-
-class DebugFontBuffer : public Buffer<
- 4 // 2 bytes per coordinate, 2 coordinates
-> {
-public:
- void addText(const char *text, double left, double baseline, double scale = 1);
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/elements_buffer.cpp b/src/mbgl/geometry/elements_buffer.cpp
deleted file mode 100644
index b7d8cb2015..0000000000
--- a/src/mbgl/geometry/elements_buffer.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#include <mbgl/geometry/elements_buffer.hpp>
-
-namespace mbgl {
-
-void TriangleElementsBuffer::add(element_type a, element_type b, element_type c) {
- element_type *elements = static_cast<element_type *>(addElement());
- elements[0] = a;
- elements[1] = b;
- elements[2] = c;
-}
-
-void LineElementsBuffer::add(element_type a, element_type b) {
- element_type *elements = static_cast<element_type *>(addElement());
- elements[0] = a;
- elements[1] = b;
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/elements_buffer.hpp b/src/mbgl/geometry/elements_buffer.hpp
deleted file mode 100644
index f995229c9d..0000000000
--- a/src/mbgl/geometry/elements_buffer.hpp
+++ /dev/null
@@ -1,46 +0,0 @@
-#pragma once
-
-#include <mbgl/geometry/buffer.hpp>
-#include <mbgl/geometry/vao.hpp>
-
-#include <mbgl/util/noncopyable.hpp>
-
-#include <array>
-
-namespace mbgl {
-
-template <uint8_t count>
-struct ElementGroup : public util::noncopyable {
- std::array<VertexArrayObject, count> array;
- uint32_t vertex_length;
- uint32_t elements_length;
-
- ElementGroup(uint32_t vertex_length_ = 0, uint32_t elements_length_ = 0)
- : vertex_length(vertex_length_)
- , elements_length(elements_length_)
- {
- }
-};
-
-class TriangleElementsBuffer : public Buffer<
- 6, // bytes per triangle (3 * unsigned short == 6 bytes)
- gl::BufferType::Element
-> {
-public:
- typedef uint16_t element_type;
-
- void add(element_type a, element_type b, element_type c);
-};
-
-
-class LineElementsBuffer : public Buffer<
- 4, // bytes per triangle (2 * unsigned short == 6 bytes)
- gl::BufferType::Element
-> {
-public:
- typedef uint16_t element_type;
-
- void add(element_type a, element_type b);
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/feature_index.cpp b/src/mbgl/geometry/feature_index.cpp
index 62db3b478d..b37bdb5ecc 100644
--- a/src/mbgl/geometry/feature_index.cpp
+++ b/src/mbgl/geometry/feature_index.cpp
@@ -52,7 +52,7 @@ static bool topDownSymbols(const IndexedSubfeature& a, const IndexedSubfeature&
void FeatureIndex::query(
std::unordered_map<std::string, std::vector<Feature>>& result,
- const GeometryCollection& queryGeometry,
+ const GeometryCoordinates& queryGeometry,
const float bearing,
const double tileSize,
const double scale,
@@ -83,7 +83,7 @@ void FeatureIndex::query(
return;
}
- std::vector<IndexedSubfeature> symbolFeatures = collisionTile->queryRenderedSymbols(box, scale);
+ std::vector<IndexedSubfeature> symbolFeatures = collisionTile->queryRenderedSymbols(queryGeometry, scale);
std::sort(symbolFeatures.begin(), symbolFeatures.end(), topDownSymbols);
for (const auto& symbolFeature : symbolFeatures) {
addFeature(result, symbolFeature, queryGeometry, filterLayerIDs, geometryTileData, tileID, style, bearing, pixelsToTileUnits);
@@ -93,7 +93,7 @@ void FeatureIndex::query(
void FeatureIndex::addFeature(
std::unordered_map<std::string, std::vector<Feature>>& result,
const IndexedSubfeature& indexedFeature,
- const GeometryCollection& queryGeometry,
+ const GeometryCoordinates& queryGeometry,
const optional<std::vector<std::string>>& filterLayerIDs,
const GeometryTileData& geometryTileData,
const CanonicalTileID& tileID,
@@ -128,8 +128,8 @@ void FeatureIndex::addFeature(
}
}
-optional<GeometryCollection> FeatureIndex::translateQueryGeometry(
- const GeometryCollection& queryGeometry,
+optional<GeometryCoordinates> FeatureIndex::translateQueryGeometry(
+ const GeometryCoordinates& queryGeometry,
const std::array<float, 2>& translate,
const style::TranslateAnchorType anchorType,
const float bearing,
@@ -143,13 +143,9 @@ optional<GeometryCollection> FeatureIndex::translateQueryGeometry(
translateVec = util::rotate(translateVec, -bearing);
}
- GeometryCollection translated;
- for (const auto& ring : queryGeometry) {
- translated.emplace_back();
- auto& translatedRing = translated.back();
- for (const auto& p : ring) {
- translatedRing.push_back(p - translateVec);
- }
+ GeometryCoordinates translated;
+ for (const auto& p : queryGeometry) {
+ translated.push_back(p - translateVec);
}
return translated;
}
diff --git a/src/mbgl/geometry/feature_index.hpp b/src/mbgl/geometry/feature_index.hpp
index 0fddcb4700..021770c78d 100644
--- a/src/mbgl/geometry/feature_index.hpp
+++ b/src/mbgl/geometry/feature_index.hpp
@@ -35,7 +35,7 @@ public:
void query(
std::unordered_map<std::string, std::vector<Feature>>& result,
- const GeometryCollection& queryGeometry,
+ const GeometryCoordinates& queryGeometry,
const float bearing,
const double tileSize,
const double scale,
@@ -44,8 +44,8 @@ public:
const CanonicalTileID&,
const style::Style&) const;
- static optional<GeometryCollection> translateQueryGeometry(
- const GeometryCollection& queryGeometry,
+ static optional<GeometryCoordinates> translateQueryGeometry(
+ const GeometryCoordinates& queryGeometry,
const std::array<float, 2>& translate,
const style::TranslateAnchorType,
const float bearing,
@@ -59,7 +59,7 @@ private:
void addFeature(
std::unordered_map<std::string, std::vector<Feature>>& result,
const IndexedSubfeature&,
- const GeometryCollection& queryGeometry,
+ const GeometryCoordinates& queryGeometry,
const optional<std::vector<std::string>>& filterLayerIDs,
const GeometryTileData&,
const CanonicalTileID&,
diff --git a/src/mbgl/geometry/fill_buffer.cpp b/src/mbgl/geometry/fill_buffer.cpp
deleted file mode 100644
index 6cb07ea66a..0000000000
--- a/src/mbgl/geometry/fill_buffer.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#include <mbgl/geometry/fill_buffer.hpp>
-
-#include <mbgl/gl/gl.hpp>
-
-#include <climits>
-
-namespace mbgl {
-
-void FillVertexBuffer::add(vertex_type x, vertex_type y) {
- vertex_type *vertices = static_cast<vertex_type *>(addElement());
- vertices[0] = x;
- vertices[1] = y;
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/fill_buffer.hpp b/src/mbgl/geometry/fill_buffer.hpp
deleted file mode 100644
index a180d9c5a2..0000000000
--- a/src/mbgl/geometry/fill_buffer.hpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma once
-
-#include <mbgl/geometry/buffer.hpp>
-#include <vector>
-#include <cstdint>
-
-namespace mbgl {
-
-class FillVertexBuffer : public Buffer<
- 4 // bytes per coordinates (2 * unsigned short == 4 bytes)
-> {
-public:
- typedef int16_t vertex_type;
-
- void add(vertex_type x, vertex_type y);
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/icon_buffer.cpp b/src/mbgl/geometry/icon_buffer.cpp
deleted file mode 100644
index 745003a548..0000000000
--- a/src/mbgl/geometry/icon_buffer.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-#include <mbgl/geometry/icon_buffer.hpp>
-#include <mbgl/gl/gl.hpp>
-#include <mbgl/util/math.hpp>
-
-#include <cmath>
-
-namespace mbgl {
-
-uint32_t IconVertexBuffer::add(int16_t x, int16_t y, float ox, float oy, int16_t tx, int16_t ty, float minzoom, float maxzoom, float labelminzoom, uint8_t labelangle) {
- const uint32_t idx = index();
- void *data = addElement();
-
- int16_t *shorts = static_cast<int16_t *>(data);
- shorts[0] /* pos */ = x;
- shorts[1] /* pos */ = y;
- shorts[2] /* offset */ = ::round(ox * 64); // use 1/64 pixels for placement
- shorts[3] /* offset */ = ::round(oy * 64);
-
- uint16_t *ushorts = static_cast<uint16_t *>(data);
- // a_texture_pos
- ushorts[4] /* tex */ = tx / 4;
- ushorts[5] /* tex */ = ty / 4;
-
- uint8_t *ubytes = static_cast<uint8_t *>(data);
- // a_data
- ubytes[12] /* labelminzoom */ = labelminzoom * 10;
- ubytes[13] /* labelangle */ = labelangle;
-
- ubytes[14] /* minzoom */ = minzoom * 10; // 1/10 zoom levels: z16 == 160.
- ubytes[15] /* maxzoom */ = ::fmin(maxzoom, 25) * 10; // 1/10 zoom levels: z16 == 160.
-
- return idx;
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/icon_buffer.hpp b/src/mbgl/geometry/icon_buffer.hpp
deleted file mode 100644
index 81e17df495..0000000000
--- a/src/mbgl/geometry/icon_buffer.hpp
+++ /dev/null
@@ -1,17 +0,0 @@
-#pragma once
-
-#include <mbgl/geometry/buffer.hpp>
-
-#include <array>
-
-namespace mbgl {
-
- class IconVertexBuffer : public Buffer<
- 16
- > {
- public:
- uint32_t add(int16_t x, int16_t y, float ox, float oy, int16_t tx, int16_t ty, float minzoom, float maxzoom, float labelminzoom, uint8_t labelangle);
-
- };
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/line_buffer.cpp b/src/mbgl/geometry/line_buffer.cpp
deleted file mode 100644
index 0eabf8e1e9..0000000000
--- a/src/mbgl/geometry/line_buffer.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-#include <mbgl/geometry/line_buffer.hpp>
-
-#include <cmath>
-
-namespace mbgl {
-
-uint32_t LineVertexBuffer::add(vertex_type x, vertex_type y, float ex, float ey, bool tx, bool ty, int8_t dir, int32_t linesofar) {
- uint32_t idx = index();
- void *data = addElement();
-
- int16_t *coords = static_cast<int16_t *>(data);
- coords[0] = (x * 2) | tx;
- coords[1] = (y * 2) | ty;
-
- uint8_t *ubytes = static_cast<uint8_t *>(data);
- // add 128 to store an byte in an unsigned byte
- ubytes[4] = ::round(extrudeScale * ex) + 128;
- ubytes[5] = ::round(extrudeScale * ey) + 128;
-
- // Encode the -1/0/1 direction value into the first two bits of .z of a_data.
- // Combine it with the lower 6 bits of `linesofar` (shifted by 2 bites to make
- // room for the direction value). The upper 8 bits of `linesofar` are placed in
- // the `w` component. `linesofar` is scaled down by `LINE_DISTANCE_SCALE` so that
- // we can store longer distances while sacrificing precision.
-
- // Encode the -1/0/1 direction value into .zw coordinates of a_data, which is normally covered
- // by linesofar, so we need to merge them.
- // The z component's first bit, as well as the sign bit is reserved for the direction,
- // so we need to shift the linesofar.
-
- ubytes[6] = ((dir == 0 ? 0 : (dir < 0 ? -1 : 1 )) + 1) | ((linesofar & 0x3F) << 2);
- ubytes[7] = linesofar >> 6;
-
- return idx;
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/line_buffer.hpp b/src/mbgl/geometry/line_buffer.hpp
deleted file mode 100644
index bfa9a55021..0000000000
--- a/src/mbgl/geometry/line_buffer.hpp
+++ /dev/null
@@ -1,37 +0,0 @@
-#pragma once
-
-#include <mbgl/geometry/buffer.hpp>
-
-namespace mbgl {
-
-class LineVertexBuffer : public Buffer<
- 8 // 2 coordinates per vertex + 1 linesofar + 1 extrude coord pair == 4 (== 8 bytes)
-> {
-public:
- typedef int16_t vertex_type;
-
- /*
- * Scale the extrusion vector so that the normal length is this value.
- * Contains the "texture" normals (-1..1). This is distinct from the extrude
- * normals for line joins, because the x-value remains 0 for the texture
- * normal array, while the extrude normal actually moves the vertex to create
- * the acute/bevelled line join.
- */
- static const int8_t extrudeScale = 63;
-
- /*
- * Add a vertex to this buffer
- *
- * @param {number} x vertex position
- * @param {number} y vertex position
- * @param {number} ex extrude normal
- * @param {number} ey extrude normal
- * @param {number} tx texture normal
- * @param {number} ty texture normal
- * @param {number} dir direction of the line cap (-1/0/1)
- */
- uint32_t add(vertex_type x, vertex_type y, float ex, float ey, bool tx, bool ty, int8_t dir, int32_t linesofar = 0);
-};
-
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/static_vertex_buffer.cpp b/src/mbgl/geometry/static_vertex_buffer.cpp
deleted file mode 100644
index c66b194748..0000000000
--- a/src/mbgl/geometry/static_vertex_buffer.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-#include <mbgl/geometry/static_vertex_buffer.hpp>
-#include <mbgl/gl/gl.hpp>
-
-namespace mbgl {
-
-StaticVertexBuffer::StaticVertexBuffer(std::initializer_list<std::array<VertexType, 2>> init) {
- for (const auto& vertex : init) {
- VertexType* vertices = static_cast<VertexType*>(addElement());
- vertices[0] = std::get<0>(vertex);
- vertices[1] = std::get<1>(vertex);
- }
-}
-
-StaticRasterVertexBuffer::StaticRasterVertexBuffer(std::initializer_list<std::array<VertexType, 4>> init) {
- for (const auto& vertex : init) {
- VertexType* vertices = static_cast<VertexType*>(addElement());
- vertices[0] = std::get<0>(vertex);
- vertices[1] = std::get<1>(vertex);
- vertices[2] = std::get<2>(vertex);
- vertices[3] = std::get<3>(vertex);
- }
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/static_vertex_buffer.hpp b/src/mbgl/geometry/static_vertex_buffer.hpp
deleted file mode 100644
index edf3b966fd..0000000000
--- a/src/mbgl/geometry/static_vertex_buffer.hpp
+++ /dev/null
@@ -1,30 +0,0 @@
-#pragma once
-
-#include <mbgl/geometry/buffer.hpp>
-
-#include <array>
-#include <cstdint>
-
-namespace mbgl {
-
-class StaticVertexBuffer : public Buffer<
- 4, // bytes per vertex (2 * signed short == 4 bytes)
- gl::BufferType::Vertex,
- 32 // default length
-> {
-public:
- using VertexType = int16_t;
- StaticVertexBuffer(std::initializer_list<std::array<VertexType, 2>>);
-};
-
-class StaticRasterVertexBuffer : public Buffer<
- 8, // bytes per vertex (4 * signed short == 8 bytes)
- gl::BufferType::Vertex,
- 32 // default length
-> {
-public:
- using VertexType = int16_t;
- StaticRasterVertexBuffer(std::initializer_list<std::array<VertexType, 4>>);
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/text_buffer.cpp b/src/mbgl/geometry/text_buffer.cpp
deleted file mode 100644
index 8fed7a71d1..0000000000
--- a/src/mbgl/geometry/text_buffer.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-#include <mbgl/geometry/text_buffer.hpp>
-#include <mbgl/gl/gl.hpp>
-#include <mbgl/util/math.hpp>
-
-#include <cmath>
-
-namespace mbgl {
-
-uint32_t TextVertexBuffer::add(int16_t x, int16_t y, float ox, float oy, uint16_t tx, uint16_t ty, float minzoom, float maxzoom, float labelminzoom, uint8_t labelangle) {
- const uint32_t idx = index();
- void *data = addElement();
-
- int16_t *shorts = static_cast<int16_t *>(data);
- shorts[0] /* pos */ = x;
- shorts[1] /* pos */ = y;
- shorts[2] /* offset */ = ::round(ox * 64); // use 1/64 pixels for placement
- shorts[3] /* offset */ = ::round(oy * 64);
-
- uint16_t *ushorts = static_cast<uint16_t *>(data);
- // a_texture_pos
- ushorts[4] /* tex */ = tx / 4;
- ushorts[5] /* tex */ = ty / 4;
-
- uint8_t *ubytes = static_cast<uint8_t *>(data);
- // a_data
- ubytes[12] /* labelminzoom */ = labelminzoom * 10;
- ubytes[13] /* labelangle */ = labelangle;
-
- ubytes[14] /* minzoom */ = minzoom * 10; // 1/10 zoom levels: z16 == 160.
- ubytes[15] /* maxzoom */ = ::fmin(maxzoom, 25) * 10; // 1/10 zoom levels: z16 == 160.
-
- return idx;
-}
-
-} // namespace mbgl
-
diff --git a/src/mbgl/geometry/text_buffer.hpp b/src/mbgl/geometry/text_buffer.hpp
deleted file mode 100644
index 4b46a38770..0000000000
--- a/src/mbgl/geometry/text_buffer.hpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#pragma once
-
-#include <mbgl/geometry/buffer.hpp>
-#include <array>
-
-namespace mbgl {
-
-class TextVertexBuffer : public Buffer <
- 16,
- gl::BufferType::Vertex,
- 32768
-> {
-public:
- typedef int16_t vertex_type;
-
- uint32_t add(int16_t x, int16_t y, float ox, float oy, uint16_t tx, uint16_t ty, float minzoom, float maxzoom, float labelminzoom, uint8_t labelangle);
-};
-
-
-} // namespace mbgl
diff --git a/src/mbgl/geometry/vao.hpp b/src/mbgl/geometry/vao.hpp
deleted file mode 100644
index 65abab1e4e..0000000000
--- a/src/mbgl/geometry/vao.hpp
+++ /dev/null
@@ -1,79 +0,0 @@
-#pragma once
-
-#include <mbgl/shader/shader.hpp>
-#include <mbgl/gl/context.hpp>
-#include <mbgl/util/noncopyable.hpp>
-#include <mbgl/util/optional.hpp>
-
-#include <stdexcept>
-
-namespace mbgl {
-
-class VertexArrayObject : public util::noncopyable {
-public:
- VertexArrayObject();
- ~VertexArrayObject();
-
- template <typename VertexBuffer>
- void bind(Shader& shader,
- VertexBuffer& vertexBuffer,
- int8_t* offset,
- gl::Context& context) {
- bindVertexArrayObject(context);
- if (bound_shader == 0) {
- vertexBuffer.bind(context);
- shader.bind(offset);
- if (vertexArray) {
- storeBinding(shader, vertexBuffer.getID(), 0, offset);
- }
- } else {
- verifyBinding(shader, vertexBuffer.getID(), 0, offset);
- }
- }
-
- template <typename VertexBuffer, typename ElementsBuffer>
- void bind(Shader& shader,
- VertexBuffer& vertexBuffer,
- ElementsBuffer& elementsBuffer,
- int8_t* offset,
- gl::Context& context) {
- bindVertexArrayObject(context);
- if (bound_shader == 0) {
- vertexBuffer.bind(context);
- elementsBuffer.bind(context);
- shader.bind(offset);
- if (vertexArray) {
- storeBinding(shader, vertexBuffer.getID(), elementsBuffer.getID(), offset);
- }
- } else {
- verifyBinding(shader, vertexBuffer.getID(), elementsBuffer.getID(), offset);
- }
- }
-
- gl::VertexArrayID getID() const {
- return *vertexArray;
- }
-
-private:
- void bindVertexArrayObject(gl::Context&);
- void storeBinding(Shader& shader,
- gl::BufferID vertexBuffer,
- gl::BufferID elementsBuffer,
- int8_t* offset);
- void verifyBinding(Shader& shader,
- gl::BufferID vertexBuffer,
- gl::BufferID elementsBuffer,
- int8_t* offset);
-
- mbgl::optional<gl::UniqueVertexArray> vertexArray;
-
- // For debug reasons, we're storing the bind information so that we can
- // detect errors and report
- gl::ProgramID bound_shader = 0;
- const char* bound_shader_name = "";
- gl::BufferID bound_vertex_buffer = 0;
- gl::BufferID bound_elements_buffer = 0;
- int8_t *bound_offset = nullptr;
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/gl/attribute.hpp b/src/mbgl/gl/attribute.hpp
new file mode 100644
index 0000000000..8bc474e967
--- /dev/null
+++ b/src/mbgl/gl/attribute.hpp
@@ -0,0 +1,50 @@
+#pragma once
+
+#include <mbgl/gl/types.hpp>
+#include <mbgl/gl/shader.hpp>
+
+#include <cstddef>
+#include <limits>
+#include <vector>
+
+namespace mbgl {
+namespace gl {
+
+template <typename T, std::size_t N>
+class Attribute {
+public:
+ Attribute(const char* name, const Shader& shader)
+ : location(shader.getAttributeLocation(name)) {}
+
+ AttributeLocation location;
+};
+
+class AttributeBinding {
+public:
+ template <class Vertex, class T, std::size_t N, std::size_t O>
+ AttributeBinding(const T (Vertex::*)[N], const Attribute<T, N>& attribute, std::integral_constant<std::size_t, O>)
+ : location(attribute.location),
+ type(DataTypeOf<T>::value),
+ count(N),
+ offset(O) {
+ static_assert(std::is_standard_layout<Vertex>::value, "vertex type must use standard layout");
+ static_assert(O % 4 == 0, "vertex attribute must be optimally aligned");
+ static_assert(1 <= N && N <= 4, "count must be 1, 2, 3, or 4");
+ static_assert(sizeof(Vertex) <= std::numeric_limits<int32_t>::max(), "vertex type is too big");
+ }
+
+ AttributeLocation location;
+ DataType type;
+ uint8_t count;
+ std::size_t offset;
+};
+
+#define MBGL_MAKE_ATTRIBUTE_BINDING(Vertex, shader, name) \
+ ::mbgl::gl::AttributeBinding(&Vertex::name, \
+ shader.name, \
+ std::integral_constant<std::size_t, offsetof(Vertex, name)>())
+
+template <class Shader, class Vertex> struct AttributeBindings;
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp
index ded7936feb..2a04fcc18e 100644
--- a/src/mbgl/gl/context.cpp
+++ b/src/mbgl/gl/context.cpp
@@ -91,10 +91,32 @@ UniqueShader Context::createFragmentShader() {
return UniqueShader{ MBGL_CHECK_ERROR(glCreateShader(GL_FRAGMENT_SHADER)), { this } };
}
-UniqueBuffer Context::createBuffer() {
+UniqueBuffer Context::createVertexBuffer(const void* data, std::size_t size) {
BufferID id = 0;
MBGL_CHECK_ERROR(glGenBuffers(1, &id));
- return UniqueBuffer{ std::move(id), { this } };
+ UniqueBuffer result { std::move(id), { this } };
+ vertexBuffer = result;
+ MBGL_CHECK_ERROR(glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW));
+ return result;
+}
+
+UniqueBuffer Context::createIndexBuffer(const void* data, std::size_t size) {
+ BufferID id = 0;
+ MBGL_CHECK_ERROR(glGenBuffers(1, &id));
+ UniqueBuffer result { std::move(id), { this } };
+ elementBuffer = result;
+ MBGL_CHECK_ERROR(glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, GL_STATIC_DRAW));
+ return result;
+}
+
+void Context::bindAttribute(const AttributeBinding& binding, std::size_t stride, const int8_t* offset) {
+ MBGL_CHECK_ERROR(glEnableVertexAttribArray(binding.location));
+ MBGL_CHECK_ERROR(glVertexAttribPointer(binding.location,
+ binding.count,
+ static_cast<GLenum>(binding.type),
+ false,
+ static_cast<GLsizei>(stride),
+ offset + binding.offset));
}
UniqueTexture Context::createTexture() {
@@ -120,10 +142,6 @@ UniqueFramebuffer Context::createFramebuffer() {
return UniqueFramebuffer{ std::move(id), { this } };
}
-void Context::uploadBuffer(BufferType type, size_t size, void* data) {
- MBGL_CHECK_ERROR(glBufferData(static_cast<GLenum>(type), size, data, GL_STATIC_DRAW));
-}
-
UniqueTexture
Context::createTexture(uint16_t width, uint16_t height, const void* data, TextureUnit unit) {
auto obj = createTexture();
diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp
index 0ec846033a..6a5d44793a 100644
--- a/src/mbgl/gl/context.hpp
+++ b/src/mbgl/gl/context.hpp
@@ -4,6 +4,9 @@
#include <mbgl/gl/state.hpp>
#include <mbgl/gl/value.hpp>
#include <mbgl/gl/texture.hpp>
+#include <mbgl/gl/vertex_buffer.hpp>
+#include <mbgl/gl/index_buffer.hpp>
+#include <mbgl/gl/attribute.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <memory>
@@ -22,12 +25,24 @@ public:
UniqueProgram createProgram();
UniqueShader createVertexShader();
UniqueShader createFragmentShader();
- UniqueBuffer createBuffer();
UniqueTexture createTexture();
UniqueVertexArray createVertexArray();
UniqueFramebuffer createFramebuffer();
- void uploadBuffer(BufferType, size_t, void*);
+ template <class V>
+ VertexBuffer<V> createVertexBuffer(std::vector<V>&& v) {
+ return VertexBuffer<V> {
+ v.size(),
+ createVertexBuffer(v.data(), v.size() * sizeof(V))
+ };
+ }
+
+ template <class P>
+ IndexBuffer<P> createIndexBuffer(std::vector<P>&& v) {
+ return IndexBuffer<P> {
+ createIndexBuffer(v.data(), v.size() * sizeof(P))
+ };
+ }
// Create a texture from an image with data.
template <typename Image>
@@ -46,6 +61,14 @@ public:
TextureFilter = TextureFilter::Nearest,
TextureMipMap = TextureMipMap::No);
+ template <class Shader, class Vertex>
+ void bindAttributes(const Shader& shader, const VertexBuffer<Vertex>&, const int8_t* offset) {
+ static_assert(std::is_same<typename Shader::VertexType, Vertex>::value, "vertex type mismatch");
+ for (const auto& binding : AttributeBindings<Shader, Vertex>()(shader)) {
+ bindAttribute(binding, sizeof(Vertex), offset);
+ }
+ }
+
// Actually remove the objects we marked as abandoned with the above methods.
// Only call this while the OpenGL context is exclusive to this thread.
void performCleanup();
@@ -98,9 +121,11 @@ public:
State<value::BindVertexArray> vertexArrayObject;
private:
+ UniqueBuffer createVertexBuffer(const void* data, std::size_t size);
+ UniqueBuffer createIndexBuffer(const void* data, std::size_t size);
UniqueTexture createTexture(uint16_t width, uint16_t height, const void* data, TextureUnit);
+ void bindAttribute(const AttributeBinding&, std::size_t stride, const int8_t* offset);
-private:
friend detail::ProgramDeleter;
friend detail::ShaderDeleter;
friend detail::BufferDeleter;
diff --git a/src/mbgl/gl/index_buffer.hpp b/src/mbgl/gl/index_buffer.hpp
new file mode 100644
index 0000000000..f38d7fd4f5
--- /dev/null
+++ b/src/mbgl/gl/index_buffer.hpp
@@ -0,0 +1,41 @@
+#pragma once
+
+#include <mbgl/gl/object.hpp>
+
+namespace mbgl {
+namespace gl {
+
+class Line {
+public:
+ Line(uint16_t a_, uint16_t b_)
+ : a(a_), b(b_) {}
+
+ uint16_t a;
+ uint16_t b;
+
+ static constexpr std::size_t IndexCount = 2;
+};
+
+class Triangle {
+public:
+ Triangle(uint16_t a_, uint16_t b_, uint16_t c_)
+ : a(a_), b(b_), c(c_) {}
+
+ uint16_t a;
+ uint16_t b;
+ uint16_t c;
+
+ static constexpr std::size_t IndexCount = 3;
+};
+
+template <class Primitive>
+class IndexBuffer {
+public:
+ static_assert(std::is_same<Primitive, Line>::value || std::is_same<Primitive, Triangle>::value,
+ "primitive must be Line or Triangle");
+ static constexpr std::size_t primitiveSize = sizeof(Primitive);
+ UniqueBuffer buffer;
+};
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/shader/shader.cpp b/src/mbgl/gl/shader.cpp
index 1198300cec..d8ee734567 100644
--- a/src/mbgl/shader/shader.cpp
+++ b/src/mbgl/gl/shader.cpp
@@ -1,4 +1,4 @@
-#include <mbgl/shader/shader.hpp>
+#include <mbgl/gl/shader.hpp>
#include <mbgl/gl/gl.hpp>
#include <mbgl/gl/context.hpp>
#include <mbgl/util/stopwatch.hpp>
@@ -15,11 +15,12 @@
#include <cassert>
namespace mbgl {
+namespace gl {
Shader::Shader(const char* name_,
const char* vertexSource,
const char* fragmentSource,
- gl::Context& context,
+ Context& context,
Defines defines)
: name(name_),
program(context.createProgram()),
@@ -47,13 +48,6 @@ Shader::Shader(const char* name_,
MBGL_CHECK_ERROR(glAttachShader(program.get(), vertexShader.get()));
MBGL_CHECK_ERROR(glAttachShader(program.get(), fragmentShader.get()));
- // Bind attribute variables
- MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_pos, "a_pos"));
- MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_extrude, "a_extrude"));
- MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_offset, "a_offset"));
- MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_data, "a_data"));
- MBGL_CHECK_ERROR(glBindAttribLocation(program.get(), a_texture_pos, "a_texture_pos"));
-
// Link program
GLint status;
MBGL_CHECK_ERROR(glLinkProgram(program.get()));
@@ -71,7 +65,7 @@ Shader::Shader(const char* name_,
}
}
-bool Shader::compileShader(gl::UniqueShader& shader, const GLchar *source) {
+bool Shader::compileShader(UniqueShader& shader, const GLchar *source) {
GLint status = 0;
const GLsizei lengths = static_cast<GLsizei>(std::strlen(source));
@@ -107,8 +101,13 @@ Shader::~Shader() {
}
}
-gl::UniformLocation Shader::getUniformLocation(const char* uniform) const {
+UniformLocation Shader::getUniformLocation(const char* uniform) const {
return MBGL_CHECK_ERROR(glGetUniformLocation(program.get(), uniform));
}
+AttributeLocation Shader::getAttributeLocation(const char* attribute) const {
+ return MBGL_CHECK_ERROR(glGetAttribLocation(program.get(), attribute));
+}
+
+} // namespace gl
} // namespace mbgl
diff --git a/src/mbgl/gl/shader.hpp b/src/mbgl/gl/shader.hpp
new file mode 100644
index 0000000000..f88bd4f867
--- /dev/null
+++ b/src/mbgl/gl/shader.hpp
@@ -0,0 +1,45 @@
+#pragma once
+
+#include <mbgl/gl/types.hpp>
+#include <mbgl/gl/object.hpp>
+#include <mbgl/util/noncopyable.hpp>
+
+namespace mbgl {
+namespace gl {
+
+class Context;
+
+class Shader : private util::noncopyable {
+public:
+ ~Shader();
+ const char* name;
+
+ ProgramID getID() const {
+ return program.get();
+ }
+
+ AttributeLocation getAttributeLocation(const char* uniform) const;
+ UniformLocation getUniformLocation(const char* uniform) const;
+
+ enum Defines : bool {
+ None = false,
+ Overdraw = true,
+ };
+
+protected:
+ Shader(const char* name_,
+ const char* vertex,
+ const char* fragment,
+ Context&,
+ Defines defines = Defines::None);
+
+private:
+ bool compileShader(UniqueShader&, const char *source);
+
+ UniqueProgram program;
+ UniqueShader vertexShader;
+ UniqueShader fragmentShader;
+};
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/gl/types.hpp b/src/mbgl/gl/types.hpp
index e9d14e4807..f24674457a 100644
--- a/src/mbgl/gl/types.hpp
+++ b/src/mbgl/gl/types.hpp
@@ -1,6 +1,7 @@
#pragma once
#include <cstdint>
+#include <type_traits>
namespace mbgl {
namespace gl {
@@ -22,6 +23,26 @@ using DepthValue = double;
using StencilValue = int32_t;
using StencilMaskValue = uint32_t;
+enum class DataType : uint32_t {
+ Byte = 0x1400,
+ UnsignedByte = 0x1401,
+ Short = 0x1402,
+ UnsignedShort = 0x1403,
+ Integer = 0x1404,
+ UnsignedInteger = 0x1405,
+ Float = 0x1406
+};
+
+template <typename T> struct DataTypeOf;
+
+template <> struct DataTypeOf<int8_t> : std::integral_constant<DataType, DataType::Byte> {};
+template <> struct DataTypeOf<uint8_t> : std::integral_constant<DataType, DataType::UnsignedByte> {};
+template <> struct DataTypeOf<int16_t> : std::integral_constant<DataType, DataType::Short> {};
+template <> struct DataTypeOf<uint16_t> : std::integral_constant<DataType, DataType::UnsignedShort> {};
+template <> struct DataTypeOf<int32_t> : std::integral_constant<DataType, DataType::Integer> {};
+template <> struct DataTypeOf<uint32_t> : std::integral_constant<DataType, DataType::UnsignedInteger> {};
+template <> struct DataTypeOf<float> : std::integral_constant<DataType, DataType::Float> {};
+
enum class BufferType : uint32_t {
Vertex = 0x8892,
Element = 0x8893
diff --git a/src/mbgl/shader/uniform.cpp b/src/mbgl/gl/uniform.cpp
index bd4c13eee1..07a27963d9 100644
--- a/src/mbgl/shader/uniform.cpp
+++ b/src/mbgl/gl/uniform.cpp
@@ -1,8 +1,9 @@
-#include <mbgl/shader/uniform.hpp>
-#include <mbgl/util/color.hpp>
+#include <mbgl/gl/uniform.hpp>
#include <mbgl/gl/gl.hpp>
+#include <mbgl/util/color.hpp>
namespace mbgl {
+namespace gl {
template <>
void Uniform<float>::bind(const float& t) {
@@ -52,4 +53,5 @@ void UniformMatrix<4>::bind(const std::array<float, 16>& t) {
// Add more as needed.
+} // namespace gl
} // namespace mbgl
diff --git a/src/mbgl/shader/uniform.hpp b/src/mbgl/gl/uniform.hpp
index 5df6942ff6..5af781043d 100644
--- a/src/mbgl/shader/uniform.hpp
+++ b/src/mbgl/gl/uniform.hpp
@@ -1,10 +1,11 @@
#pragma once
-#include <mbgl/shader/shader.hpp>
+#include <mbgl/gl/shader.hpp>
#include <array>
namespace mbgl {
+namespace gl {
template <typename T>
class Uniform {
@@ -24,7 +25,7 @@ private:
void bind(const T&);
T current;
- gl::UniformLocation location;
+ UniformLocation location;
};
template <size_t C, size_t R = C>
@@ -53,7 +54,8 @@ private:
void bind(const T&);
T current;
- gl::UniformLocation location;
+ UniformLocation location;
};
+} // namespace gl
} // namespace mbgl
diff --git a/src/mbgl/geometry/vao.cpp b/src/mbgl/gl/vao.cpp
index 2c5e1677ff..b235b0e63b 100644
--- a/src/mbgl/geometry/vao.cpp
+++ b/src/mbgl/gl/vao.cpp
@@ -1,18 +1,14 @@
-#include <mbgl/geometry/vao.hpp>
+#include <mbgl/gl/vao.hpp>
#include <mbgl/gl/vertex_array.hpp>
#include <mbgl/platform/log.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/gl/gl.hpp>
namespace mbgl {
+namespace gl {
-VertexArrayObject::VertexArrayObject() {
-}
-
-VertexArrayObject::~VertexArrayObject() = default;
-
-void VertexArrayObject::bindVertexArrayObject(gl::Context& context) {
- if (!gl::GenVertexArrays || !gl::BindVertexArray) {
+void VertexArrayObject::bindVertexArrayObject(Context& context) {
+ if (!GenVertexArrays || !BindVertexArray) {
static bool reported = false;
if (!reported) {
Log::Warning(Event::OpenGL, "Not using Vertex Array Objects");
@@ -31,8 +27,8 @@ void VertexArrayObject::bindVertexArrayObject(gl::Context& context) {
}
void VertexArrayObject::verifyBinding(Shader& shader,
- gl::BufferID vertexBuffer,
- gl::BufferID elementsBuffer,
+ BufferID vertexBuffer,
+ BufferID elementsBuffer,
int8_t* offset) {
if (bound_shader != shader.getID()) {
throw std::runtime_error(std::string("trying to rebind VAO to another shader from " +
@@ -48,8 +44,8 @@ void VertexArrayObject::verifyBinding(Shader& shader,
}
void VertexArrayObject::storeBinding(Shader& shader,
- gl::BufferID vertexBuffer,
- gl::BufferID elementsBuffer,
+ BufferID vertexBuffer,
+ BufferID elementsBuffer,
int8_t* offset) {
bound_shader = shader.getID();
bound_shader_name = shader.name;
@@ -58,4 +54,5 @@ void VertexArrayObject::storeBinding(Shader& shader,
bound_elements_buffer = elementsBuffer;
}
+} // namespace gl
} // namespace mbgl
diff --git a/src/mbgl/gl/vao.hpp b/src/mbgl/gl/vao.hpp
new file mode 100644
index 0000000000..826c028d32
--- /dev/null
+++ b/src/mbgl/gl/vao.hpp
@@ -0,0 +1,78 @@
+#pragma once
+
+#include <mbgl/gl/shader.hpp>
+#include <mbgl/gl/context.hpp>
+#include <mbgl/gl/vertex_buffer.hpp>
+#include <mbgl/util/optional.hpp>
+
+#include <stdexcept>
+
+namespace mbgl {
+namespace gl {
+
+class VertexArrayObject {
+public:
+ template <typename Shader, typename T>
+ void bind(Shader& shader,
+ const VertexBuffer<T>& vertexBuffer,
+ int8_t* offset,
+ Context& context) {
+ bindVertexArrayObject(context);
+ if (bound_shader == 0) {
+ context.vertexBuffer = vertexBuffer.buffer;
+ context.bindAttributes(shader, vertexBuffer, offset);
+ if (vertexArray) {
+ storeBinding(shader, vertexBuffer.buffer, 0, offset);
+ }
+ } else {
+ verifyBinding(shader, vertexBuffer.buffer, 0, offset);
+ }
+ }
+
+ template <typename Shader, typename T, typename P>
+ void bind(Shader& shader,
+ const VertexBuffer<T>& vertexBuffer,
+ const IndexBuffer<P>& indexBuffer,
+ int8_t* offset,
+ Context& context) {
+ bindVertexArrayObject(context);
+ if (bound_shader == 0) {
+ context.vertexBuffer = vertexBuffer.buffer;
+ context.elementBuffer = indexBuffer.buffer;
+ context.bindAttributes(shader, vertexBuffer, offset);
+ if (vertexArray) {
+ storeBinding(shader, vertexBuffer.buffer, indexBuffer.buffer, offset);
+ }
+ } else {
+ verifyBinding(shader, vertexBuffer.buffer, indexBuffer.buffer, offset);
+ }
+ }
+
+ VertexArrayID getID() const {
+ return *vertexArray;
+ }
+
+private:
+ void bindVertexArrayObject(Context&);
+ void storeBinding(Shader& shader,
+ BufferID vertexBuffer,
+ BufferID elementsBuffer,
+ int8_t* offset);
+ void verifyBinding(Shader& shader,
+ BufferID vertexBuffer,
+ BufferID elementsBuffer,
+ int8_t* offset);
+
+ optional<UniqueVertexArray> vertexArray;
+
+ // For debug reasons, we're storing the bind information so that we can
+ // detect errors and report
+ ProgramID bound_shader = 0;
+ const char* bound_shader_name = "";
+ BufferID bound_vertex_buffer = 0;
+ BufferID bound_elements_buffer = 0;
+ int8_t *bound_offset = nullptr;
+};
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/gl/vertex_buffer.hpp b/src/mbgl/gl/vertex_buffer.hpp
new file mode 100644
index 0000000000..c77a9a4213
--- /dev/null
+++ b/src/mbgl/gl/vertex_buffer.hpp
@@ -0,0 +1,17 @@
+#pragma once
+
+#include <mbgl/gl/object.hpp>
+
+namespace mbgl {
+namespace gl {
+
+template <class Vertex>
+class VertexBuffer {
+public:
+ static constexpr std::size_t vertexSize = sizeof(Vertex);
+ std::size_t vertexCount;
+ UniqueBuffer buffer;
+};
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp
index fdd66095fe..07ba2bf4a3 100644
--- a/src/mbgl/layout/symbol_layout.cpp
+++ b/src/mbgl/layout/symbol_layout.cpp
@@ -8,12 +8,14 @@
#include <mbgl/text/get_anchors.hpp>
#include <mbgl/text/glyph_atlas.hpp>
#include <mbgl/text/collision_tile.hpp>
+#include <mbgl/util/constants.hpp>
#include <mbgl/util/utf.hpp>
#include <mbgl/util/token.hpp>
#include <mbgl/util/math.hpp>
#include <mbgl/util/std.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/string.hpp>
+#include <mbgl/math/clamp.hpp>
#include <mbgl/math/minmax.hpp>
#include <mbgl/platform/platform.hpp>
#include <mbgl/platform/log.hpp>
@@ -53,8 +55,8 @@ SymbolLayout::SymbolLayout(std::string bucketName_,
auto layerName = layer.getName();
// Determine and load glyph ranges
- const size_t featureCount = static_cast<size_t>(layer.featureCount());
- for (size_t i = 0; i < featureCount; i++) {
+ const size_t featureCount = layer.featureCount();
+ for (size_t i = 0; i < featureCount; ++i) {
auto feature = layer.getFeature(i);
if (!filter(feature->getType(), feature->getID(), [&] (const auto& key) { return feature->getValue(key); }))
continue;
@@ -391,7 +393,7 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile)
if (hasText) {
collisionTile.insertFeature(symbolInstance.textCollisionFeature, glyphScale, layout.textIgnorePlacement);
if (glyphScale < collisionTile.maxScale) {
- addSymbols<SymbolBucket::TextBuffer, SymbolBucket::TextElementGroup>(
+ addSymbols(
bucket->text, symbolInstance.glyphQuads, glyphScale,
layout.textKeepUpright, textPlacement, collisionTile.config.angle);
}
@@ -400,7 +402,7 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile)
if (hasIcon) {
collisionTile.insertFeature(symbolInstance.iconCollisionFeature, iconScale, layout.iconIgnorePlacement);
if (iconScale < collisionTile.maxScale) {
- addSymbols<SymbolBucket::IconBuffer, SymbolBucket::IconElementGroup>(
+ addSymbols(
bucket->icon, symbolInstance.iconQuads, iconScale,
layout.iconKeepUpright, iconPlacement, collisionTile.config.angle);
}
@@ -414,7 +416,7 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile)
return bucket;
}
-template <typename Buffer, typename GroupType>
+template <typename Buffer>
void SymbolLayout::addSymbols(Buffer &buffer, const SymbolQuads &symbols, float scale, const bool keepUpright, const style::SymbolPlacementType placement, const float placementAngle) {
const float placementZoom = ::fmax(std::log(scale) / std::log(2) + zoom, 0);
@@ -449,53 +451,58 @@ void SymbolLayout::addSymbols(Buffer &buffer, const SymbolQuads &symbols, float
const int glyph_vertex_length = 4;
- if (buffer.groups.empty() || (buffer.groups.back()->vertex_length + glyph_vertex_length > 65535)) {
+ if (buffer.groups.empty() || buffer.groups.back().vertexLength + glyph_vertex_length > 65535) {
// Move to a new group because the old one can't hold the geometry.
- buffer.groups.emplace_back(std::make_unique<GroupType>());
+ buffer.groups.emplace_back();
}
// We're generating triangle fans, so we always start with the first
// coordinate in this polygon.
- assert(buffer.groups.back());
- auto &triangleGroup = *buffer.groups.back();
- size_t triangleIndex = triangleGroup.vertex_length;
+ auto& group = buffer.groups.back();
+ size_t index = group.vertexLength;
// Encode angle of glyph
uint8_t glyphAngle = std::round((symbol.glyphAngle / (M_PI * 2)) * 256);
// coordinates (2 triangles)
- buffer.vertices.add(anchorPoint.x, anchorPoint.y, tl.x, tl.y, tex.x, tex.y, minZoom,
+ buffer.vertices.emplace_back(anchorPoint.x, anchorPoint.y, tl.x, tl.y, tex.x, tex.y, minZoom,
maxZoom, placementZoom, glyphAngle);
- buffer.vertices.add(anchorPoint.x, anchorPoint.y, tr.x, tr.y, tex.x + tex.w, tex.y,
+ buffer.vertices.emplace_back(anchorPoint.x, anchorPoint.y, tr.x, tr.y, tex.x + tex.w, tex.y,
minZoom, maxZoom, placementZoom, glyphAngle);
- buffer.vertices.add(anchorPoint.x, anchorPoint.y, bl.x, bl.y, tex.x, tex.y + tex.h,
+ buffer.vertices.emplace_back(anchorPoint.x, anchorPoint.y, bl.x, bl.y, tex.x, tex.y + tex.h,
minZoom, maxZoom, placementZoom, glyphAngle);
- buffer.vertices.add(anchorPoint.x, anchorPoint.y, br.x, br.y, tex.x + tex.w, tex.y + tex.h,
+ buffer.vertices.emplace_back(anchorPoint.x, anchorPoint.y, br.x, br.y, tex.x + tex.w, tex.y + tex.h,
minZoom, maxZoom, placementZoom, glyphAngle);
// add the two triangles, referencing the four coordinates we just inserted.
- buffer.triangles.add(triangleIndex + 0, triangleIndex + 1, triangleIndex + 2);
- buffer.triangles.add(triangleIndex + 1, triangleIndex + 2, triangleIndex + 3);
-
- triangleGroup.vertex_length += glyph_vertex_length;
- triangleGroup.elements_length += 2;
+ buffer.triangles.emplace_back(static_cast<uint16_t>(index + 0),
+ static_cast<uint16_t>(index + 1),
+ static_cast<uint16_t>(index + 2));
+ buffer.triangles.emplace_back(static_cast<uint16_t>(index + 1),
+ static_cast<uint16_t>(index + 2),
+ static_cast<uint16_t>(index + 3));
+
+ group.vertexLength += glyph_vertex_length;
+ group.indexLength += 2;
}
}
void SymbolLayout::addToDebugBuffers(CollisionTile& collisionTile, SymbolBucket& bucket) {
+ if (!hasSymbolInstances()) {
+ return;
+ }
+
const float yStretch = collisionTile.yStretch;
- const float angle = collisionTile.config.angle;
- float angle_sin = std::sin(-angle);
- float angle_cos = std::cos(-angle);
- std::array<float, 4> matrix = {{angle_cos, -angle_sin, angle_sin, angle_cos}};
- for (const SymbolInstance &symbolInstance : symbolInstances) {
- for (int i = 0; i < 2; i++) {
- auto& feature = i == 0 ?
- symbolInstance.textCollisionFeature :
- symbolInstance.iconCollisionFeature;
+ auto& collisionBox = bucket.collisionBox;
+ if (collisionBox.groups.empty()) {
+ // Move to a new group because the old one can't hold the geometry.
+ collisionBox.groups.emplace_back();
+ }
+ for (const SymbolInstance &symbolInstance : symbolInstances) {
+ auto populateCollisionBox = [&](const auto& feature) {
for (const CollisionBox &box : feature.boxes) {
auto& anchor = box.anchor;
@@ -503,33 +510,29 @@ void SymbolLayout::addToDebugBuffers(CollisionTile& collisionTile, SymbolBucket&
Point<float> tr{box.x2, box.y1 * yStretch};
Point<float> bl{box.x1, box.y2 * yStretch};
Point<float> br{box.x2, box.y2 * yStretch};
- tl = util::matrixMultiply(matrix, tl);
- tr = util::matrixMultiply(matrix, tr);
- bl = util::matrixMultiply(matrix, bl);
- br = util::matrixMultiply(matrix, br);
-
- const float maxZoom = util::max(0.0f, util::min(25.0f, static_cast<float>(zoom + log(box.maxScale) / log(2))));
- const float placementZoom= util::max(0.0f, util::min(25.0f, static_cast<float>(zoom + log(box.placementScale) / log(2))));
-
- auto& collisionBox = bucket.collisionBox;
- if (collisionBox.groups.empty()) {
- // Move to a new group because the old one can't hold the geometry.
- collisionBox.groups.emplace_back(std::make_unique<SymbolBucket::CollisionBoxElementGroup>());
- }
-
- collisionBox.vertices.add(anchor.x, anchor.y, tl.x, tl.y, maxZoom, placementZoom);
- collisionBox.vertices.add(anchor.x, anchor.y, tr.x, tr.y, maxZoom, placementZoom);
- collisionBox.vertices.add(anchor.x, anchor.y, tr.x, tr.y, maxZoom, placementZoom);
- collisionBox.vertices.add(anchor.x, anchor.y, br.x, br.y, maxZoom, placementZoom);
- collisionBox.vertices.add(anchor.x, anchor.y, br.x, br.y, maxZoom, placementZoom);
- collisionBox.vertices.add(anchor.x, anchor.y, bl.x, bl.y, maxZoom, placementZoom);
- collisionBox.vertices.add(anchor.x, anchor.y, bl.x, bl.y, maxZoom, placementZoom);
- collisionBox.vertices.add(anchor.x, anchor.y, tl.x, tl.y, maxZoom, placementZoom);
-
- auto &group= *collisionBox.groups.back();
- group.vertex_length += 8;
+ tl = util::matrixMultiply(collisionTile.reverseRotationMatrix, tl);
+ tr = util::matrixMultiply(collisionTile.reverseRotationMatrix, tr);
+ bl = util::matrixMultiply(collisionTile.reverseRotationMatrix, bl);
+ br = util::matrixMultiply(collisionTile.reverseRotationMatrix, br);
+
+ const float maxZoom = util::clamp(zoom + log(box.maxScale) / log(2), util::MIN_ZOOM, util::MAX_ZOOM);
+ const float placementZoom = util::clamp(zoom + log(box.placementScale) / log(2), util::MIN_ZOOM, util::MAX_ZOOM);
+
+ collisionBox.vertices.emplace_back(anchor.x, anchor.y, tl.x, tl.y, maxZoom, placementZoom);
+ collisionBox.vertices.emplace_back(anchor.x, anchor.y, tr.x, tr.y, maxZoom, placementZoom);
+ collisionBox.vertices.emplace_back(anchor.x, anchor.y, tr.x, tr.y, maxZoom, placementZoom);
+ collisionBox.vertices.emplace_back(anchor.x, anchor.y, br.x, br.y, maxZoom, placementZoom);
+ collisionBox.vertices.emplace_back(anchor.x, anchor.y, br.x, br.y, maxZoom, placementZoom);
+ collisionBox.vertices.emplace_back(anchor.x, anchor.y, bl.x, bl.y, maxZoom, placementZoom);
+ collisionBox.vertices.emplace_back(anchor.x, anchor.y, bl.x, bl.y, maxZoom, placementZoom);
+ collisionBox.vertices.emplace_back(anchor.x, anchor.y, tl.x, tl.y, maxZoom, placementZoom);
+
+ auto& group = collisionBox.groups.back();
+ group.vertexLength += 8;
}
- }
+ };
+ populateCollisionBox(symbolInstance.textCollisionFeature);
+ populateCollisionBox(symbolInstance.iconCollisionFeature);
}
}
diff --git a/src/mbgl/layout/symbol_layout.hpp b/src/mbgl/layout/symbol_layout.hpp
index c4e6455794..54acf84aaf 100644
--- a/src/mbgl/layout/symbol_layout.hpp
+++ b/src/mbgl/layout/symbol_layout.hpp
@@ -70,7 +70,7 @@ private:
void addToDebugBuffers(CollisionTile&, SymbolBucket&);
// Adds placed items to the buffer.
- template <typename Buffer, typename GroupType>
+ template <typename Buffer>
void addSymbols(Buffer&, const SymbolQuads&, float scale,
const bool keepUpright, const style::SymbolPlacementType, const float placementAngle);
diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp
index e04f7f3900..bf2462e2ab 100644
--- a/src/mbgl/map/map.cpp
+++ b/src/mbgl/map/map.cpp
@@ -22,6 +22,7 @@
#include <mbgl/util/mapbox.hpp>
#include <mbgl/util/tile_coordinate.hpp>
#include <mbgl/actor/thread_pool.hpp>
+#include <mbgl/platform/log.hpp>
namespace mbgl {
@@ -421,7 +422,7 @@ void Map::moveBy(const ScreenCoordinate& point, const Duration& duration) {
}
void Map::setLatLng(const LatLng& latLng, const Duration& duration) {
- setLatLng(latLng, ScreenCoordinate {}, duration);
+ setLatLng(latLng, optional<ScreenCoordinate> {}, duration);
}
void Map::setLatLng(const LatLng& latLng, optional<EdgeInsets> padding, const Duration& duration) {
@@ -749,13 +750,15 @@ std::vector<Feature> Map::queryRenderedFeatures(const ScreenBox& box, const opti
AnnotationIDs Map::queryPointAnnotations(const ScreenBox& box) {
auto features = queryRenderedFeatures(box, {{ AnnotationManager::PointLayerID }});
- AnnotationIDs ids;
- ids.reserve(features.size());
+ std::set<AnnotationID> set;
for (auto &feature : features) {
assert(feature.id);
assert(*feature.id <= std::numeric_limits<AnnotationID>::max());
- ids.push_back(static_cast<AnnotationID>(feature.id->get<uint64_t>()));
+ set.insert(static_cast<AnnotationID>(feature.id->get<uint64_t>()));
}
+ AnnotationIDs ids;
+ ids.reserve(set.size());
+ std::move(set.begin(), set.end(), std::back_inserter(ids));
return ids;
}
diff --git a/src/mbgl/renderer/circle_bucket.cpp b/src/mbgl/renderer/circle_bucket.cpp
index 7b10fafc93..f12139d004 100644
--- a/src/mbgl/renderer/circle_bucket.cpp
+++ b/src/mbgl/renderer/circle_bucket.cpp
@@ -18,8 +18,8 @@ CircleBucket::~CircleBucket() {
}
void CircleBucket::upload(gl::Context& context) {
- vertexBuffer_.upload(context);
- elementsBuffer_.upload(context);
+ vertexBuffer = context.createVertexBuffer(std::move(vertices));
+ indexBuffer = context.createIndexBuffer(std::move(triangles));
uploaded = true;
}
@@ -31,7 +31,7 @@ void CircleBucket::render(Painter& painter,
}
bool CircleBucket::hasData() const {
- return !triangleGroups_.empty();
+ return !groups.empty();
}
bool CircleBucket::needsClipping() const {
@@ -59,45 +59,47 @@ void CircleBucket::addGeometry(const GeometryCollection& geometryCollection) {
// │ 1 2 │
// └─────────┘
//
- vertexBuffer_.add(x, y, -1, -1); // 1
- vertexBuffer_.add(x, y, 1, -1); // 2
- vertexBuffer_.add(x, y, 1, 1); // 3
- vertexBuffer_.add(x, y, -1, 1); // 4
+ vertices.emplace_back(x, y, -1, -1); // 1
+ vertices.emplace_back(x, y, 1, -1); // 2
+ vertices.emplace_back(x, y, 1, 1); // 3
+ vertices.emplace_back(x, y, -1, 1); // 4
- if (!triangleGroups_.size() || (triangleGroups_.back()->vertex_length + 4 > 65535)) {
+ if (!groups.size() || groups.back().vertexLength + 4 > 65535) {
// Move to a new group because the old one can't hold the geometry.
- triangleGroups_.emplace_back(std::make_unique<TriangleGroup>());
+ groups.emplace_back();
}
- TriangleGroup& group = *triangleGroups_.back();
- auto index = group.vertex_length;
+ auto& group = groups.back();
+ uint16_t index = group.vertexLength;
// 1, 2, 3
// 1, 4, 3
- elementsBuffer_.add(index, index + 1, index + 2);
- elementsBuffer_.add(index, index + 3, index + 2);
-
- group.vertex_length += 4;
- group.elements_length += 2;
+ triangles.emplace_back(index,
+ static_cast<uint16_t>(index + 1),
+ static_cast<uint16_t>(index + 2));
+ triangles.emplace_back(index,
+ static_cast<uint16_t>(index + 3),
+ static_cast<uint16_t>(index + 2));
+
+ group.vertexLength += 4;
+ group.indexLength += 2;
}
}
}
-void CircleBucket::drawCircles(CircleShader& shader, gl::Context& context) {
+void CircleBucket::drawCircles(CircleShader& shader, gl::Context& context, PaintMode paintMode) {
GLbyte* vertexIndex = BUFFER_OFFSET(0);
GLbyte* elementsIndex = BUFFER_OFFSET(0);
- for (auto& group : triangleGroups_) {
- assert(group);
-
- if (!group->elements_length) continue;
+ for (auto& group : groups) {
+ if (!group.indexLength) continue;
- group->array[0].bind(shader, vertexBuffer_, elementsBuffer_, vertexIndex, context);
+ group.getVAO(shader, paintMode).bind(shader, *vertexBuffer, *indexBuffer, vertexIndex, context);
- MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT, elementsIndex));
+ MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(group.indexLength * 3), GL_UNSIGNED_SHORT, elementsIndex));
- vertexIndex += group->vertex_length * vertexBuffer_.itemSize;
- elementsIndex += group->elements_length * elementsBuffer_.itemSize;
+ vertexIndex += group.vertexLength * vertexBuffer->vertexSize;
+ elementsIndex += group.indexLength * indexBuffer->primitiveSize;
}
}
diff --git a/src/mbgl/renderer/circle_bucket.hpp b/src/mbgl/renderer/circle_bucket.hpp
index 9e9357d77f..2f3faccdec 100644
--- a/src/mbgl/renderer/circle_bucket.hpp
+++ b/src/mbgl/renderer/circle_bucket.hpp
@@ -1,19 +1,18 @@
#pragma once
#include <mbgl/renderer/bucket.hpp>
+#include <mbgl/renderer/element_group.hpp>
#include <mbgl/map/mode.hpp>
#include <mbgl/tile/geometry_tile_data.hpp>
-#include <mbgl/geometry/elements_buffer.hpp>
-#include <mbgl/geometry/circle_buffer.hpp>
+#include <mbgl/gl/vertex_buffer.hpp>
+#include <mbgl/gl/index_buffer.hpp>
+#include <mbgl/shader/circle_vertex.hpp>
namespace mbgl {
-class CircleVertexBuffer;
class CircleShader;
class CircleBucket : public Bucket {
- using TriangleGroup = ElementGroup<3>;
-
public:
CircleBucket(const MapMode);
~CircleBucket() override;
@@ -25,13 +24,16 @@ public:
bool needsClipping() const override;
void addGeometry(const GeometryCollection&);
- void drawCircles(CircleShader&, gl::Context&);
+ void drawCircles(CircleShader&, gl::Context&, PaintMode);
private:
- CircleVertexBuffer vertexBuffer_;
- TriangleElementsBuffer elementsBuffer_;
+ std::vector<CircleVertex> vertices;
+ std::vector<gl::Triangle> triangles;
+
+ std::vector<ElementGroup<CircleShader>> groups;
- std::vector<std::unique_ptr<TriangleGroup>> triangleGroups_;
+ optional<gl::VertexBuffer<CircleVertex>> vertexBuffer;
+ optional<gl::IndexBuffer<gl::Triangle>> indexBuffer;
const MapMode mode;
};
diff --git a/src/mbgl/renderer/debug_bucket.cpp b/src/mbgl/renderer/debug_bucket.cpp
index 249924abb7..c47ae434be 100644
--- a/src/mbgl/renderer/debug_bucket.cpp
+++ b/src/mbgl/renderer/debug_bucket.cpp
@@ -1,54 +1,101 @@
#include <mbgl/renderer/debug_bucket.hpp>
#include <mbgl/renderer/painter.hpp>
-#include <mbgl/shader/plain_shader.hpp>
+#include <mbgl/shader/fill_shader.hpp>
+#include <mbgl/shader/fill_vertex.hpp>
+#include <mbgl/geometry/debug_font_data.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/gl/gl.hpp>
-#include <cassert>
+#include <cmath>
#include <string>
+#include <vector>
namespace mbgl {
-DebugBucket::DebugBucket(const OverscaledTileID& id,
- const bool renderable_,
- const bool complete_,
- optional<Timestamp> modified_,
- optional<Timestamp> expires_,
- MapDebugOptions debugMode_)
- : renderable(renderable_),
- complete(complete_),
- modified(std::move(modified_)),
- expires(std::move(expires_)),
- debugMode(debugMode_) {
+std::vector<FillVertex> buildTextVertices(const OverscaledTileID& id,
+ const bool renderable,
+ const bool complete,
+ optional<Timestamp> modified,
+ optional<Timestamp> expires,
+ MapDebugOptions debugMode) {
+ std::vector<FillVertex> textPoints;
+
+ auto addText = [&] (const std::string& text, double left, double baseline, double scale) {
+ for (uint8_t c : text) {
+ if (c < 32 || c >= 127)
+ continue;
+
+ optional<Point<int16_t>> prev;
+
+ const glyph& glyph = simplex[c - 32];
+ for (int32_t j = 0; j < glyph.length; j += 2) {
+ if (glyph.data[j] == -1 && glyph.data[j + 1] == -1) {
+ prev = {};
+ } else {
+ Point<int16_t> p {
+ int16_t(::round(left + glyph.data[j] * scale)),
+ int16_t(::round(baseline - glyph.data[j + 1] * scale))
+ };
+
+ if (prev) {
+ textPoints.emplace_back(prev->x, prev->y);
+ textPoints.emplace_back(p.x, p.y);
+ }
+
+ prev = p;
+ }
+ }
+
+ left += glyph.width * scale;
+ }
+ };
+
double baseline = 200;
if (debugMode & MapDebugOptions::ParseStatus) {
const std::string text = util::toString(id) + " - " +
(complete ? "complete" : renderable ? "renderable" : "pending");
- fontBuffer.addText(text.c_str(), 50, baseline, 5);
+ addText(text, 50, baseline, 5);
baseline += 200;
}
if (debugMode & MapDebugOptions::Timestamps && modified && expires) {
const std::string modifiedText = "modified: " + util::iso8601(*modified);
- fontBuffer.addText(modifiedText.c_str(), 50, baseline, 5);
+ addText(modifiedText, 50, baseline, 5);
const std::string expiresText = "expires: " + util::iso8601(*expires);
- fontBuffer.addText(expiresText.c_str(), 50, baseline + 200, 5);
+ addText(expiresText, 50, baseline + 200, 5);
}
+
+ return textPoints;
+}
+
+DebugBucket::DebugBucket(const OverscaledTileID& id,
+ const bool renderable_,
+ const bool complete_,
+ optional<Timestamp> modified_,
+ optional<Timestamp> expires_,
+ MapDebugOptions debugMode_,
+ gl::Context& context)
+ : renderable(renderable_),
+ complete(complete_),
+ modified(std::move(modified_)),
+ expires(std::move(expires_)),
+ debugMode(debugMode_),
+ vertexBuffer(context.createVertexBuffer(buildTextVertices(id, renderable_, complete_, modified_, expires_, debugMode_))) {
}
-void DebugBucket::drawLines(PlainShader& shader, gl::Context& context) {
- if (!fontBuffer.empty()) {
- array.bind(shader, fontBuffer, BUFFER_OFFSET_0, context);
- MBGL_CHECK_ERROR(glDrawArrays(GL_LINES, 0, (GLsizei)(fontBuffer.index())));
+void DebugBucket::drawLines(FillShader& shader, gl::Context& context) {
+ if (vertexBuffer.vertexCount != 0) {
+ array.bind(shader, vertexBuffer, BUFFER_OFFSET_0, context);
+ MBGL_CHECK_ERROR(glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(vertexBuffer.vertexCount)));
}
}
-void DebugBucket::drawPoints(PlainShader& shader, gl::Context& context) {
- if (!fontBuffer.empty()) {
- array.bind(shader, fontBuffer, BUFFER_OFFSET_0, context);
- MBGL_CHECK_ERROR(glDrawArrays(GL_POINTS, 0, (GLsizei)(fontBuffer.index())));
+void DebugBucket::drawPoints(FillShader& shader, gl::Context& context) {
+ if (vertexBuffer.vertexCount != 0) {
+ array.bind(shader, vertexBuffer, BUFFER_OFFSET_0, context);
+ MBGL_CHECK_ERROR(glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(vertexBuffer.vertexCount)));
}
}
diff --git a/src/mbgl/renderer/debug_bucket.hpp b/src/mbgl/renderer/debug_bucket.hpp
index 51315967da..89087f0010 100644
--- a/src/mbgl/renderer/debug_bucket.hpp
+++ b/src/mbgl/renderer/debug_bucket.hpp
@@ -1,14 +1,18 @@
#pragma once
#include <mbgl/map/mode.hpp>
-#include <mbgl/geometry/debug_font_buffer.hpp>
-#include <mbgl/geometry/vao.hpp>
#include <mbgl/util/chrono.hpp>
+#include <mbgl/util/geometry.hpp>
+#include <mbgl/util/optional.hpp>
+#include <mbgl/util/noncopyable.hpp>
+#include <mbgl/gl/vertex_buffer.hpp>
+#include <mbgl/gl/vao.hpp>
+#include <mbgl/shader/fill_vertex.hpp>
namespace mbgl {
class OverscaledTileID;
-class PlainShader;
+class FillShader;
namespace gl {
class Context;
@@ -21,10 +25,11 @@ public:
bool complete,
optional<Timestamp> modified,
optional<Timestamp> expires,
- MapDebugOptions);
+ MapDebugOptions,
+ gl::Context&);
- void drawLines(PlainShader&, gl::Context&);
- void drawPoints(PlainShader&, gl::Context&);
+ void drawLines(FillShader&, gl::Context&);
+ void drawPoints(FillShader&, gl::Context&);
const bool renderable;
const bool complete;
@@ -33,8 +38,8 @@ public:
const MapDebugOptions debugMode;
private:
- DebugFontBuffer fontBuffer;
- VertexArrayObject array;
+ gl::VertexBuffer<FillVertex> vertexBuffer;
+ gl::VertexArrayObject array;
};
} // namespace mbgl
diff --git a/src/mbgl/renderer/element_group.hpp b/src/mbgl/renderer/element_group.hpp
new file mode 100644
index 0000000000..59b5c3068d
--- /dev/null
+++ b/src/mbgl/renderer/element_group.hpp
@@ -0,0 +1,28 @@
+#pragma once
+
+#include <mbgl/gl/vao.hpp>
+#include <mbgl/renderer/render_pass.hpp>
+
+namespace mbgl {
+
+template <class... Shaders>
+struct ElementGroup {
+ template <class Shader>
+ struct VAOs {
+ gl::VertexArrayObject normalVAO;
+ gl::VertexArrayObject overdrawVAO;
+ };
+
+ std::tuple<VAOs<Shaders>...> vaos;
+
+ template <class Shader>
+ gl::VertexArrayObject& getVAO(const Shader&, PaintMode paintMode) {
+ auto& vao = std::get<VAOs<Shader>>(vaos);
+ return paintMode == PaintMode::Overdraw ? vao.overdrawVAO : vao.normalVAO;
+ }
+
+ std::size_t vertexLength = 0;
+ std::size_t indexLength = 0;
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/renderer/fill_bucket.cpp b/src/mbgl/renderer/fill_bucket.cpp
index d07fe5c725..cd4277cabc 100644
--- a/src/mbgl/renderer/fill_bucket.cpp
+++ b/src/mbgl/renderer/fill_bucket.cpp
@@ -1,10 +1,10 @@
#include <mbgl/renderer/fill_bucket.hpp>
#include <mbgl/style/layers/fill_layer.hpp>
#include <mbgl/renderer/painter.hpp>
-#include <mbgl/shader/plain_shader.hpp>
-#include <mbgl/shader/pattern_shader.hpp>
-#include <mbgl/shader/outline_shader.hpp>
-#include <mbgl/shader/outlinepattern_shader.hpp>
+#include <mbgl/shader/fill_shader.hpp>
+#include <mbgl/shader/fill_pattern_shader.hpp>
+#include <mbgl/shader/fill_outline_shader.hpp>
+#include <mbgl/shader/fill_outline_pattern_shader.hpp>
#include <mbgl/gl/gl.hpp>
#include <mbgl/platform/log.hpp>
@@ -54,22 +54,24 @@ void FillBucket::addGeometry(const GeometryCollection& geometry) {
if (nVertices == 0)
continue;
- if (lineGroups.empty() || lineGroups.back()->vertex_length + nVertices > 65535)
- lineGroups.emplace_back(std::make_unique<LineGroup>());
+ if (lineGroups.empty() || lineGroups.back().vertexLength + nVertices > 65535)
+ lineGroups.emplace_back();
- LineGroup& lineGroup = *lineGroups.back();
- GLsizei lineIndex = lineGroup.vertex_length;
+ auto& lineGroup = lineGroups.back();
+ uint16_t lineIndex = lineGroup.vertexLength;
- vertexBuffer.add(ring[0].x, ring[0].y);
- lineElementsBuffer.add(lineIndex + nVertices - 1, lineIndex);
+ vertices.emplace_back(ring[0].x, ring[0].y);
+ lines.emplace_back(static_cast<uint16_t>(lineIndex + nVertices - 1),
+ static_cast<uint16_t>(lineIndex));
for (uint32_t i = 1; i < nVertices; i++) {
- vertexBuffer.add(ring[i].x, ring[i].y);
- lineElementsBuffer.add(lineIndex + i - 1, lineIndex + i);
+ vertices.emplace_back(ring[i].x, ring[i].y);
+ lines.emplace_back(static_cast<uint16_t>(lineIndex + i - 1),
+ static_cast<uint16_t>(lineIndex + i));
}
- lineGroup.vertex_length += nVertices;
- lineGroup.elements_length += nVertices;
+ lineGroup.vertexLength += nVertices;
+ lineGroup.indexLength += nVertices;
}
std::vector<uint32_t> indices = mapbox::earcut(polygon);
@@ -77,28 +79,28 @@ void FillBucket::addGeometry(const GeometryCollection& geometry) {
std::size_t nIndicies = indices.size();
assert(nIndicies % 3 == 0);
- if (triangleGroups.empty() || triangleGroups.back()->vertex_length + totalVertices > 65535) {
- triangleGroups.emplace_back(std::make_unique<TriangleGroup>());
+ if (triangleGroups.empty() || triangleGroups.back().vertexLength + totalVertices > 65535) {
+ triangleGroups.emplace_back();
}
- TriangleGroup& triangleGroup = *triangleGroups.back();
- GLsizei triangleIndex = triangleGroup.vertex_length;
+ auto& triangleGroup = triangleGroups.back();
+ uint16_t triangleIndex = triangleGroup.vertexLength;
for (uint32_t i = 0; i < nIndicies; i += 3) {
- triangleElementsBuffer.add(triangleIndex + indices[i],
- triangleIndex + indices[i + 1],
- triangleIndex + indices[i + 2]);
+ triangles.emplace_back(static_cast<uint16_t>(triangleIndex + indices[i]),
+ static_cast<uint16_t>(triangleIndex + indices[i + 1]),
+ static_cast<uint16_t>(triangleIndex + indices[i + 2]));
}
- triangleGroup.vertex_length += totalVertices;
- triangleGroup.elements_length += nIndicies / 3;
+ triangleGroup.vertexLength += totalVertices;
+ triangleGroup.indexLength += nIndicies / 3;
}
}
void FillBucket::upload(gl::Context& context) {
- vertexBuffer.upload(context);
- triangleElementsBuffer.upload(context);
- lineElementsBuffer.upload(context);
+ vertexBuffer = context.createVertexBuffer(std::move(vertices));
+ lineIndexBuffer = context.createIndexBuffer(std::move(lines));
+ triangleIndexBuffer = context.createIndexBuffer(std::move(triangles));
// From now on, we're going to render during the opaque and translucent pass.
uploaded = true;
@@ -119,67 +121,63 @@ bool FillBucket::needsClipping() const {
return true;
}
-void FillBucket::drawElements(PlainShader& shader,
+void FillBucket::drawElements(FillShader& shader,
gl::Context& context,
PaintMode paintMode) {
GLbyte* vertex_index = BUFFER_OFFSET(0);
GLbyte* elements_index = BUFFER_OFFSET(0);
for (auto& group : triangleGroups) {
- assert(group);
- group->array[paintMode == PaintMode::Overdraw ? 1 : 0].bind(
- shader, vertexBuffer, triangleElementsBuffer, vertex_index, context);
- MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT,
+ group.getVAO(shader, paintMode).bind(
+ shader, *vertexBuffer, *triangleIndexBuffer, vertex_index, context);
+ MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(group.indexLength * 3), GL_UNSIGNED_SHORT,
elements_index));
- vertex_index += group->vertex_length * vertexBuffer.itemSize;
- elements_index += group->elements_length * triangleElementsBuffer.itemSize;
+ vertex_index += group.vertexLength * vertexBuffer->vertexSize;
+ elements_index += group.indexLength * triangleIndexBuffer->primitiveSize;
}
}
-void FillBucket::drawElements(PatternShader& shader,
+void FillBucket::drawElements(FillPatternShader& shader,
gl::Context& context,
PaintMode paintMode) {
GLbyte* vertex_index = BUFFER_OFFSET(0);
GLbyte* elements_index = BUFFER_OFFSET(0);
for (auto& group : triangleGroups) {
- assert(group);
- group->array[paintMode == PaintMode::Overdraw ? 3 : 2].bind(
- shader, vertexBuffer, triangleElementsBuffer, vertex_index, context);
- MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT,
+ group.getVAO(shader, paintMode).bind(
+ shader, *vertexBuffer, *triangleIndexBuffer, vertex_index, context);
+ MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(group.indexLength * 3), GL_UNSIGNED_SHORT,
elements_index));
- vertex_index += group->vertex_length * vertexBuffer.itemSize;
- elements_index += group->elements_length * triangleElementsBuffer.itemSize;
+ vertex_index += group.vertexLength * vertexBuffer->vertexSize;
+ elements_index += group.indexLength * triangleIndexBuffer->primitiveSize;
}
}
-void FillBucket::drawVertices(OutlineShader& shader,
+void FillBucket::drawVertices(FillOutlineShader& shader,
gl::Context& context,
PaintMode paintMode) {
GLbyte* vertex_index = BUFFER_OFFSET(0);
GLbyte* elements_index = BUFFER_OFFSET(0);
for (auto& group : lineGroups) {
- assert(group);
- group->array[paintMode == PaintMode::Overdraw ? 1 : 0].bind(
- shader, vertexBuffer, lineElementsBuffer, vertex_index, context);
- MBGL_CHECK_ERROR(glDrawElements(GL_LINES, group->elements_length * 2, GL_UNSIGNED_SHORT,
+ group.getVAO(shader, paintMode).bind(
+ shader, *vertexBuffer, *lineIndexBuffer, vertex_index, context);
+ MBGL_CHECK_ERROR(glDrawElements(GL_LINES, static_cast<GLsizei>(group.indexLength * 2), GL_UNSIGNED_SHORT,
elements_index));
- vertex_index += group->vertex_length * vertexBuffer.itemSize;
- elements_index += group->elements_length * lineElementsBuffer.itemSize;
+ vertex_index += group.vertexLength * vertexBuffer->vertexSize;
+ elements_index += group.indexLength * lineIndexBuffer->primitiveSize;
}
}
-void FillBucket::drawVertices(OutlinePatternShader& shader,
+void FillBucket::drawVertices(FillOutlinePatternShader& shader,
gl::Context& context,
PaintMode paintMode) {
GLbyte* vertex_index = BUFFER_OFFSET(0);
GLbyte* elements_index = BUFFER_OFFSET(0);
for (auto& group : lineGroups) {
- assert(group);
- group->array[paintMode == PaintMode::Overdraw ? 3 : 2].bind(
- shader, vertexBuffer, lineElementsBuffer, vertex_index, context);
- MBGL_CHECK_ERROR(glDrawElements(GL_LINES, group->elements_length * 2, GL_UNSIGNED_SHORT,
+ group.getVAO(shader, paintMode).bind(
+ shader, *vertexBuffer, *lineIndexBuffer, vertex_index, context);
+ MBGL_CHECK_ERROR(glDrawElements(GL_LINES, static_cast<GLsizei>(group.indexLength * 2), GL_UNSIGNED_SHORT,
elements_index));
- vertex_index += group->vertex_length * vertexBuffer.itemSize;
- elements_index += group->elements_length * lineElementsBuffer.itemSize;
+ vertex_index += group.vertexLength * vertexBuffer->vertexSize;
+ elements_index += group.indexLength * lineIndexBuffer->primitiveSize;
}
}
diff --git a/src/mbgl/renderer/fill_bucket.hpp b/src/mbgl/renderer/fill_bucket.hpp
index 2e6d390bfe..34cd886687 100644
--- a/src/mbgl/renderer/fill_bucket.hpp
+++ b/src/mbgl/renderer/fill_bucket.hpp
@@ -1,19 +1,21 @@
#pragma once
#include <mbgl/renderer/bucket.hpp>
+#include <mbgl/renderer/element_group.hpp>
#include <mbgl/tile/geometry_tile_data.hpp>
-#include <mbgl/geometry/elements_buffer.hpp>
-#include <mbgl/geometry/fill_buffer.hpp>
+#include <mbgl/gl/vertex_buffer.hpp>
+#include <mbgl/gl/index_buffer.hpp>
+#include <mbgl/shader/fill_vertex.hpp>
#include <vector>
#include <memory>
namespace mbgl {
-class OutlinePatternShader;
-class PlainShader;
-class PatternShader;
-class OutlineShader;
+class FillShader;
+class FillPatternShader;
+class FillOutlineShader;
+class FillOutlinePatternShader;
class FillBucket : public Bucket {
public:
@@ -27,21 +29,22 @@ public:
void addGeometry(const GeometryCollection&);
- void drawElements(PlainShader&, gl::Context&, PaintMode);
- void drawElements(PatternShader&, gl::Context&, PaintMode);
- void drawVertices(OutlineShader&, gl::Context&, PaintMode);
- void drawVertices(OutlinePatternShader&, gl::Context&, PaintMode);
+ void drawElements(FillShader&, gl::Context&, PaintMode);
+ void drawElements(FillPatternShader&, gl::Context&, PaintMode);
+ void drawVertices(FillOutlineShader&, gl::Context&, PaintMode);
+ void drawVertices(FillOutlinePatternShader&, gl::Context&, PaintMode);
private:
- FillVertexBuffer vertexBuffer;
- TriangleElementsBuffer triangleElementsBuffer;
- LineElementsBuffer lineElementsBuffer;
+ std::vector<FillVertex> vertices;
+ std::vector<gl::Line> lines;
+ std::vector<gl::Triangle> triangles;
- typedef ElementGroup<4> TriangleGroup;
- typedef ElementGroup<4> LineGroup;
+ std::vector<ElementGroup<FillOutlineShader, FillOutlinePatternShader>> lineGroups;
+ std::vector<ElementGroup<FillShader, FillPatternShader>> triangleGroups;
- std::vector<std::unique_ptr<TriangleGroup>> triangleGroups;
- std::vector<std::unique_ptr<LineGroup>> lineGroups;
+ optional<gl::VertexBuffer<FillVertex>> vertexBuffer;
+ optional<gl::IndexBuffer<gl::Line>> lineIndexBuffer;
+ optional<gl::IndexBuffer<gl::Triangle>> triangleIndexBuffer;
};
} // namespace mbgl
diff --git a/src/mbgl/renderer/line_bucket.cpp b/src/mbgl/renderer/line_bucket.cpp
index 17a92ad3d8..7a5309bafc 100644
--- a/src/mbgl/renderer/line_bucket.cpp
+++ b/src/mbgl/renderer/line_bucket.cpp
@@ -1,10 +1,9 @@
#include <mbgl/renderer/line_bucket.hpp>
#include <mbgl/style/layers/line_layer.hpp>
-#include <mbgl/geometry/elements_buffer.hpp>
#include <mbgl/renderer/painter.hpp>
#include <mbgl/shader/line_shader.hpp>
-#include <mbgl/shader/linesdf_shader.hpp>
-#include <mbgl/shader/linepattern_shader.hpp>
+#include <mbgl/shader/line_sdf_shader.hpp>
+#include <mbgl/shader/line_pattern_shader.hpp>
#include <mbgl/util/math.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/gl/gl.hpp>
@@ -54,11 +53,11 @@ const float LINE_DISTANCE_SCALE = 1.0 / 2.0;
// The maximum line distance, in tile units, that fits in the buffer.
const float MAX_LINE_DISTANCE = std::pow(2, LINE_DISTANCE_BUFFER_BITS) / LINE_DISTANCE_SCALE;
-void LineBucket::addGeometry(const GeometryCoordinates& vertices) {
- const GLsizei len = [&vertices] {
- GLsizei l = static_cast<GLsizei>(vertices.size());
+void LineBucket::addGeometry(const GeometryCoordinates& coordinates) {
+ const GLsizei len = [&coordinates] {
+ GLsizei l = static_cast<GLsizei>(coordinates.size());
// If the line has duplicate vertices at the end, adjust length to remove them.
- while (l > 2 && vertices[l - 1] == vertices[l - 2]) {
+ while (l > 2 && coordinates[l - 1] == coordinates[l - 2]) {
l--;
}
return l;
@@ -73,9 +72,9 @@ void LineBucket::addGeometry(const GeometryCoordinates& vertices) {
const double sharpCornerOffset = SHARP_CORNER_OFFSET * (float(util::EXTENT) / (util::tileSize * overscaling));
- const GeometryCoordinate firstVertex = vertices.front();
- const GeometryCoordinate lastVertex = vertices[len - 1];
- const bool closed = firstVertex == lastVertex;
+ const GeometryCoordinate firstCoordinate = coordinates.front();
+ const GeometryCoordinate lastCoordinate = coordinates[len - 1];
+ const bool closed = firstCoordinate == lastCoordinate;
if (len == 2 && closed) {
// fprintf(stderr, "a line may not have coincident points\n");
@@ -87,9 +86,9 @@ void LineBucket::addGeometry(const GeometryCoordinates& vertices) {
double distance = 0;
bool startOfLine = true;
- optional<GeometryCoordinate> currentVertex;
- optional<GeometryCoordinate> prevVertex;
- optional<GeometryCoordinate> nextVertex;
+ optional<GeometryCoordinate> currentCoordinate;
+ optional<GeometryCoordinate> prevCoordinate;
+ optional<GeometryCoordinate> nextCoordinate;
optional<Point<double>> prevNormal;
optional<Point<double>> nextNormal;
@@ -97,43 +96,43 @@ void LineBucket::addGeometry(const GeometryCoordinates& vertices) {
e1 = e2 = e3 = -1;
if (closed) {
- currentVertex = vertices[len - 2];
- nextNormal = util::perp(util::unit(convertPoint<double>(firstVertex - *currentVertex)));
+ currentCoordinate = coordinates[len - 2];
+ nextNormal = util::perp(util::unit(convertPoint<double>(firstCoordinate - *currentCoordinate)));
}
- const int32_t startVertex = vertexBuffer.index();
+ const std::size_t startVertex = vertices.size();
std::vector<TriangleElement> triangleStore;
for (GLsizei i = 0; i < len; ++i) {
if (closed && i == len - 1) {
// if the line is closed, we treat the last vertex like the first
- nextVertex = vertices[1];
+ nextCoordinate = coordinates[1];
} else if (i + 1 < len) {
// just the next vertex
- nextVertex = vertices[i + 1];
+ nextCoordinate = coordinates[i + 1];
} else {
// there is no next vertex
- nextVertex = {};
+ nextCoordinate = {};
}
// if two consecutive vertices exist, skip the current one
- if (nextVertex && vertices[i] == *nextVertex) {
+ if (nextCoordinate && coordinates[i] == *nextCoordinate) {
continue;
}
if (nextNormal) {
prevNormal = *nextNormal;
}
- if (currentVertex) {
- prevVertex = *currentVertex;
+ if (currentCoordinate) {
+ prevCoordinate = *currentCoordinate;
}
- currentVertex = vertices[i];
+ currentCoordinate = coordinates[i];
// Calculate the normal towards the next vertex in this line. In case
// there is no next vertex, pretend that the line is continuing straight,
// meaning that we are just using the previous normal.
- nextNormal = nextVertex ? util::perp(util::unit(convertPoint<double>(*nextVertex - *currentVertex)))
+ nextNormal = nextCoordinate ? util::perp(util::unit(convertPoint<double>(*nextCoordinate - *currentCoordinate)))
: prevNormal;
// If we still don't have a previous normal, this is the beginning of a
@@ -162,22 +161,22 @@ void LineBucket::addGeometry(const GeometryCoordinates& vertices) {
const double cosHalfAngle = joinNormal.x * nextNormal->x + joinNormal.y * nextNormal->y;
const double miterLength = cosHalfAngle != 0 ? 1 / cosHalfAngle: 1;
- const bool isSharpCorner = cosHalfAngle < COS_HALF_SHARP_CORNER && prevVertex && nextVertex;
+ const bool isSharpCorner = cosHalfAngle < COS_HALF_SHARP_CORNER && prevCoordinate && nextCoordinate;
if (isSharpCorner && i > 0) {
- const double prevSegmentLength = util::dist<double>(*currentVertex, *prevVertex);
+ const double prevSegmentLength = util::dist<double>(*currentCoordinate, *prevCoordinate);
if (prevSegmentLength > 2.0 * sharpCornerOffset) {
- GeometryCoordinate newPrevVertex = *currentVertex - convertPoint<int16_t>(util::round(convertPoint<double>(*currentVertex - *prevVertex) * (sharpCornerOffset / prevSegmentLength)));
- distance += util::dist<double>(newPrevVertex, *prevVertex);
+ GeometryCoordinate newPrevVertex = *currentCoordinate - convertPoint<int16_t>(util::round(convertPoint<double>(*currentCoordinate - *prevCoordinate) * (sharpCornerOffset / prevSegmentLength)));
+ distance += util::dist<double>(newPrevVertex, *prevCoordinate);
addCurrentVertex(newPrevVertex, distance, *prevNormal, 0, 0, false, startVertex, triangleStore);
- prevVertex = newPrevVertex;
+ prevCoordinate = newPrevVertex;
}
}
// The join if a middle vertex, otherwise the cap
- const bool middleVertex = prevVertex && nextVertex;
+ const bool middleVertex = prevCoordinate && nextCoordinate;
LineJoinType currentJoin = layout.lineJoin;
- const LineCapType currentCap = nextVertex ? beginCap : endCap;
+ const LineCapType currentCap = nextCoordinate ? beginCap : endCap;
if (middleVertex) {
if (currentJoin == LineJoinType::Round) {
@@ -208,12 +207,12 @@ void LineBucket::addGeometry(const GeometryCoordinates& vertices) {
}
// Calculate how far along the line the currentVertex is
- if (prevVertex)
- distance += util::dist<double>(*currentVertex, *prevVertex);
+ if (prevCoordinate)
+ distance += util::dist<double>(*currentCoordinate, *prevCoordinate);
if (middleVertex && currentJoin == LineJoinType::Miter) {
joinNormal = joinNormal * miterLength;
- addCurrentVertex(*currentVertex, distance, joinNormal, 0, 0, false, startVertex,
+ addCurrentVertex(*currentCoordinate, distance, joinNormal, 0, 0, false, startVertex,
triangleStore);
} else if (middleVertex && currentJoin == LineJoinType::FlipBevel) {
@@ -229,10 +228,10 @@ void LineBucket::addGeometry(const GeometryCoordinates& vertices) {
joinNormal = util::perp(joinNormal) * bevelLength * direction;
}
- addCurrentVertex(*currentVertex, distance, joinNormal, 0, 0, false, startVertex,
+ addCurrentVertex(*currentCoordinate, distance, joinNormal, 0, 0, false, startVertex,
triangleStore);
- addCurrentVertex(*currentVertex, distance, joinNormal * -1.0, 0, 0, false, startVertex,
+ addCurrentVertex(*currentCoordinate, distance, joinNormal * -1.0, 0, 0, false, startVertex,
triangleStore);
} else if (middleVertex && (currentJoin == LineJoinType::Bevel || currentJoin == LineJoinType::FakeRound)) {
const bool lineTurnsLeft = (prevNormal->x * nextNormal->y - prevNormal->y * nextNormal->x) > 0;
@@ -250,7 +249,7 @@ void LineBucket::addGeometry(const GeometryCoordinates& vertices) {
// Close previous segement with bevel
if (!startOfLine) {
- addCurrentVertex(*currentVertex, distance, *prevNormal, offsetA, offsetB, false,
+ addCurrentVertex(*currentCoordinate, distance, *prevNormal, offsetA, offsetB, false,
startVertex, triangleStore);
}
@@ -266,40 +265,40 @@ void LineBucket::addGeometry(const GeometryCoordinates& vertices) {
for (int m = 0; m < n; m++) {
auto approxFractionalJoinNormal = util::unit(*nextNormal * ((m + 1.0) / (n + 1.0)) + *prevNormal);
- addPieSliceVertex(*currentVertex, distance, approxFractionalJoinNormal, lineTurnsLeft, startVertex, triangleStore);
+ addPieSliceVertex(*currentCoordinate, distance, approxFractionalJoinNormal, lineTurnsLeft, startVertex, triangleStore);
}
- addPieSliceVertex(*currentVertex, distance, joinNormal, lineTurnsLeft, startVertex, triangleStore);
+ addPieSliceVertex(*currentCoordinate, distance, joinNormal, lineTurnsLeft, startVertex, triangleStore);
for (int k = n - 1; k >= 0; k--) {
auto approxFractionalJoinNormal = util::unit(*prevNormal * ((k + 1.0) / (n + 1.0)) + *nextNormal);
- addPieSliceVertex(*currentVertex, distance, approxFractionalJoinNormal, lineTurnsLeft, startVertex, triangleStore);
+ addPieSliceVertex(*currentCoordinate, distance, approxFractionalJoinNormal, lineTurnsLeft, startVertex, triangleStore);
}
}
// Start next segment
- if (nextVertex) {
- addCurrentVertex(*currentVertex, distance, *nextNormal, -offsetA, -offsetB,
+ if (nextCoordinate) {
+ addCurrentVertex(*currentCoordinate, distance, *nextNormal, -offsetA, -offsetB,
false, startVertex, triangleStore);
}
} else if (!middleVertex && currentCap == LineCapType::Butt) {
if (!startOfLine) {
// Close previous segment with a butt
- addCurrentVertex(*currentVertex, distance, *prevNormal, 0, 0, false,
+ addCurrentVertex(*currentCoordinate, distance, *prevNormal, 0, 0, false,
startVertex, triangleStore);
}
// Start next segment with a butt
- if (nextVertex) {
- addCurrentVertex(*currentVertex, distance, *nextNormal, 0, 0, false,
+ if (nextCoordinate) {
+ addCurrentVertex(*currentCoordinate, distance, *nextNormal, 0, 0, false,
startVertex, triangleStore);
}
} else if (!middleVertex && currentCap == LineCapType::Square) {
if (!startOfLine) {
// Close previous segment with a square cap
- addCurrentVertex(*currentVertex, distance, *prevNormal, 1, 1, false,
+ addCurrentVertex(*currentCoordinate, distance, *prevNormal, 1, 1, false,
startVertex, triangleStore);
// The segment is done. Unset vertices to disconnect segments.
@@ -307,19 +306,19 @@ void LineBucket::addGeometry(const GeometryCoordinates& vertices) {
}
// Start next segment
- if (nextVertex) {
- addCurrentVertex(*currentVertex, distance, *nextNormal, -1, -1, false,
+ if (nextCoordinate) {
+ addCurrentVertex(*currentCoordinate, distance, *nextNormal, -1, -1, false,
startVertex, triangleStore);
}
} else if (middleVertex ? currentJoin == LineJoinType::Round : currentCap == LineCapType::Round) {
if (!startOfLine) {
// Close previous segment with a butt
- addCurrentVertex(*currentVertex, distance, *prevNormal, 0, 0, false,
+ addCurrentVertex(*currentCoordinate, distance, *prevNormal, 0, 0, false,
startVertex, triangleStore);
// Add round cap or linejoin at end of segment
- addCurrentVertex(*currentVertex, distance, *prevNormal, 1, 1, true, startVertex,
+ addCurrentVertex(*currentCoordinate, distance, *prevNormal, 1, 1, true, startVertex,
triangleStore);
// The segment is done. Unset vertices to disconnect segments.
@@ -327,67 +326,65 @@ void LineBucket::addGeometry(const GeometryCoordinates& vertices) {
}
// Start next segment with a butt
- if (nextVertex) {
+ if (nextCoordinate) {
// Add round cap before first segment
- addCurrentVertex(*currentVertex, distance, *nextNormal, -1, -1, true,
+ addCurrentVertex(*currentCoordinate, distance, *nextNormal, -1, -1, true,
startVertex, triangleStore);
- addCurrentVertex(*currentVertex, distance, *nextNormal, 0, 0, false,
+ addCurrentVertex(*currentCoordinate, distance, *nextNormal, 0, 0, false,
startVertex, triangleStore);
}
}
if (isSharpCorner && i < len - 1) {
- const double nextSegmentLength = util::dist<double>(*currentVertex, *nextVertex);
+ const double nextSegmentLength = util::dist<double>(*currentCoordinate, *nextCoordinate);
if (nextSegmentLength > 2 * sharpCornerOffset) {
- GeometryCoordinate newCurrentVertex = *currentVertex + convertPoint<int16_t>(util::round(convertPoint<double>(*nextVertex - *currentVertex) * (sharpCornerOffset / nextSegmentLength)));
- distance += util::dist<double>(newCurrentVertex, *currentVertex);
+ GeometryCoordinate newCurrentVertex = *currentCoordinate + convertPoint<int16_t>(util::round(convertPoint<double>(*nextCoordinate - *currentCoordinate) * (sharpCornerOffset / nextSegmentLength)));
+ distance += util::dist<double>(newCurrentVertex, *currentCoordinate);
addCurrentVertex(newCurrentVertex, distance, *nextNormal, 0, 0, false, startVertex, triangleStore);
- currentVertex = newCurrentVertex;
+ currentCoordinate = newCurrentVertex;
}
}
startOfLine = false;
}
- const GLsizei endVertex = vertexBuffer.index();
- const GLsizei vertexCount = endVertex - startVertex;
+ const std::size_t endVertex = vertices.size();
+ const std::size_t vertexCount = endVertex - startVertex;
- // Store the triangle/line groups.
- {
- if (triangleGroups.empty() || (triangleGroups.back()->vertex_length + vertexCount > 65535)) {
- // Move to a new group because the old one can't hold the geometry.
- triangleGroups.emplace_back(std::make_unique<TriangleGroup>());
- }
+ if (groups.empty() || groups.back().vertexLength + vertexCount > 65535) {
+ // Move to a new group because the old one can't hold the geometry.
+ groups.emplace_back();
+ }
- assert(triangleGroups.back());
- auto& group = *triangleGroups.back();
- for (const auto& triangle : triangleStore) {
- triangleElementsBuffer.add(group.vertex_length + triangle.a,
- group.vertex_length + triangle.b,
- group.vertex_length + triangle.c);
- }
+ auto& group = groups.back();
+ uint16_t index = group.vertexLength;
- group.vertex_length += vertexCount;
- group.elements_length += triangleStore.size();
+ for (const auto& triangle : triangleStore) {
+ triangles.emplace_back(static_cast<uint16_t>(index + triangle.a),
+ static_cast<uint16_t>(index + triangle.b),
+ static_cast<uint16_t>(index + triangle.c));
}
+
+ group.vertexLength += vertexCount;
+ group.indexLength += triangleStore.size();
}
-void LineBucket::addCurrentVertex(const GeometryCoordinate& currentVertex,
+void LineBucket::addCurrentVertex(const GeometryCoordinate& currentCoordinate,
double &distance,
const Point<double>& normal,
double endLeft,
double endRight,
bool round,
- int32_t startVertex,
+ std::size_t startVertex,
std::vector<TriangleElement>& triangleStore) {
int8_t tx = round ? 1 : 0;
Point<double> extrude = normal;
if (endLeft)
extrude = extrude - (util::perp(normal) * endLeft);
- e3 = vertexBuffer.add(currentVertex.x, currentVertex.y, extrude.x, extrude.y, tx, 0, endLeft, distance * LINE_DISTANCE_SCALE)
- - startVertex;
+ vertices.emplace_back(currentCoordinate.x, currentCoordinate.y, extrude.x, extrude.y, tx, 0, endLeft, distance * LINE_DISTANCE_SCALE);
+ e3 = vertices.size() - 1 - startVertex;
if (e1 >= 0 && e2 >= 0) {
triangleStore.emplace_back(e1, e2, e3);
}
@@ -397,8 +394,8 @@ void LineBucket::addCurrentVertex(const GeometryCoordinate& currentVertex,
extrude = normal * -1.0;
if (endRight)
extrude = extrude - (util::perp(normal) * endRight);
- e3 = vertexBuffer.add(currentVertex.x, currentVertex.y, extrude.x, extrude.y, tx, 1, -endRight, distance * LINE_DISTANCE_SCALE)
- - startVertex;
+ vertices.emplace_back(currentCoordinate.x, currentCoordinate.y, extrude.x, extrude.y, tx, 1, -endRight, distance * LINE_DISTANCE_SCALE);
+ e3 = vertices.size() - 1 - startVertex;
if (e1 >= 0 && e2 >= 0) {
triangleStore.emplace_back(e1, e2, e3);
}
@@ -411,7 +408,7 @@ void LineBucket::addCurrentVertex(const GeometryCoordinate& currentVertex,
// to `linesofar`.
if (distance > MAX_LINE_DISTANCE / 2.0f) {
distance = 0;
- addCurrentVertex(currentVertex, distance, normal, endLeft, endRight, round, startVertex, triangleStore);
+ addCurrentVertex(currentCoordinate, distance, normal, endLeft, endRight, round, startVertex, triangleStore);
}
}
@@ -419,13 +416,13 @@ void LineBucket::addPieSliceVertex(const GeometryCoordinate& currentVertex,
double distance,
const Point<double>& extrude,
bool lineTurnsLeft,
- int32_t startVertex,
+ std::size_t startVertex,
std::vector<TriangleElement>& triangleStore) {
int8_t ty = lineTurnsLeft;
Point<double> flippedExtrude = extrude * (lineTurnsLeft ? -1.0 : 1.0);
- e3 = vertexBuffer.add(currentVertex.x, currentVertex.y, flippedExtrude.x, flippedExtrude.y, 0, ty, 0, distance * LINE_DISTANCE_SCALE)
- - startVertex;
+ vertices.emplace_back(currentVertex.x, currentVertex.y, flippedExtrude.x, flippedExtrude.y, 0, ty, 0, distance * LINE_DISTANCE_SCALE);
+ e3 = vertices.size() - 1 - startVertex;
if (e1 >= 0 && e2 >= 0) {
triangleStore.emplace_back(e1, e2, e3);
}
@@ -438,8 +435,8 @@ void LineBucket::addPieSliceVertex(const GeometryCoordinate& currentVertex,
}
void LineBucket::upload(gl::Context& context) {
- vertexBuffer.upload(context);
- triangleElementsBuffer.upload(context);
+ vertexBuffer = context.createVertexBuffer(std::move(vertices));
+ indexBuffer = context.createIndexBuffer(std::move(triangles));
// From now on, we're only going to render during the translucent pass.
uploaded = true;
@@ -453,7 +450,7 @@ void LineBucket::render(Painter& painter,
}
bool LineBucket::hasData() const {
- return !triangleGroups.empty();
+ return !groups.empty();
}
bool LineBucket::needsClipping() const {
@@ -465,17 +462,16 @@ void LineBucket::drawLines(LineShader& shader,
PaintMode paintMode) {
GLbyte* vertex_index = BUFFER_OFFSET(0);
GLbyte* elements_index = BUFFER_OFFSET(0);
- for (auto& group : triangleGroups) {
- assert(group);
- if (!group->elements_length) {
+ for (auto& group : groups) {
+ if (!group.indexLength) {
continue;
}
- group->array[paintMode == PaintMode::Overdraw ? 1 : 0].bind(
- shader, vertexBuffer, triangleElementsBuffer, vertex_index, context);
- MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT,
+ group.getVAO(shader, paintMode).bind(
+ shader, *vertexBuffer, *indexBuffer, vertex_index, context);
+ MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(group.indexLength * 3), GL_UNSIGNED_SHORT,
elements_index));
- vertex_index += group->vertex_length * vertexBuffer.itemSize;
- elements_index += group->elements_length * triangleElementsBuffer.itemSize;
+ vertex_index += group.vertexLength * vertexBuffer->vertexSize;
+ elements_index += group.indexLength * indexBuffer->primitiveSize;
}
}
@@ -484,36 +480,34 @@ void LineBucket::drawLineSDF(LineSDFShader& shader,
PaintMode paintMode) {
GLbyte* vertex_index = BUFFER_OFFSET(0);
GLbyte* elements_index = BUFFER_OFFSET(0);
- for (auto& group : triangleGroups) {
- assert(group);
- if (!group->elements_length) {
+ for (auto& group : groups) {
+ if (!group.indexLength) {
continue;
}
- group->array[paintMode == PaintMode::Overdraw ? 3 : 2].bind(
- shader, vertexBuffer, triangleElementsBuffer, vertex_index, context);
- MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT,
+ group.getVAO(shader, paintMode).bind(
+ shader, *vertexBuffer, *indexBuffer, vertex_index, context);
+ MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(group.indexLength * 3), GL_UNSIGNED_SHORT,
elements_index));
- vertex_index += group->vertex_length * vertexBuffer.itemSize;
- elements_index += group->elements_length * triangleElementsBuffer.itemSize;
+ vertex_index += group.vertexLength * vertexBuffer->vertexSize;
+ elements_index += group.indexLength * indexBuffer->primitiveSize;
}
}
-void LineBucket::drawLinePatterns(LinepatternShader& shader,
+void LineBucket::drawLinePatterns(LinePatternShader& shader,
gl::Context& context,
PaintMode paintMode) {
GLbyte* vertex_index = BUFFER_OFFSET(0);
GLbyte* elements_index = BUFFER_OFFSET(0);
- for (auto& group : triangleGroups) {
- assert(group);
- if (!group->elements_length) {
+ for (auto& group : groups) {
+ if (!group.indexLength) {
continue;
}
- group->array[paintMode == PaintMode::Overdraw ? 5 : 4].bind(
- shader, vertexBuffer, triangleElementsBuffer, vertex_index, context);
- MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT,
+ group.getVAO(shader, paintMode).bind(
+ shader, *vertexBuffer, *indexBuffer, vertex_index, context);
+ MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(group.indexLength * 3), GL_UNSIGNED_SHORT,
elements_index));
- vertex_index += group->vertex_length * vertexBuffer.itemSize;
- elements_index += group->elements_length * triangleElementsBuffer.itemSize;
+ vertex_index += group.vertexLength * vertexBuffer->vertexSize;
+ elements_index += group.indexLength * indexBuffer->primitiveSize;
}
}
diff --git a/src/mbgl/renderer/line_bucket.hpp b/src/mbgl/renderer/line_bucket.hpp
index 5ddaca8ae8..14af710877 100644
--- a/src/mbgl/renderer/line_bucket.hpp
+++ b/src/mbgl/renderer/line_bucket.hpp
@@ -1,24 +1,22 @@
#pragma once
#include <mbgl/renderer/bucket.hpp>
+#include <mbgl/renderer/element_group.hpp>
#include <mbgl/tile/geometry_tile_data.hpp>
-#include <mbgl/geometry/vao.hpp>
-#include <mbgl/geometry/elements_buffer.hpp>
-#include <mbgl/geometry/line_buffer.hpp>
+#include <mbgl/gl/vertex_buffer.hpp>
+#include <mbgl/gl/index_buffer.hpp>
+#include <mbgl/shader/line_vertex.hpp>
#include <mbgl/style/layers/line_layer_properties.hpp>
#include <vector>
namespace mbgl {
-class LineVertexBuffer;
-class TriangleElementsBuffer;
class LineShader;
class LineSDFShader;
-class LinepatternShader;
+class LinePatternShader;
class LineBucket : public Bucket {
- using TriangleGroup = ElementGroup<6>;
public:
LineBucket(uint32_t overscaling);
@@ -34,7 +32,7 @@ public:
void drawLines(LineShader&, gl::Context&, PaintMode);
void drawLineSDF(LineSDFShader&, gl::Context&, PaintMode);
- void drawLinePatterns(LinepatternShader&, gl::Context&, PaintMode);
+ void drawLinePatterns(LinePatternShader&, gl::Context&, PaintMode);
private:
struct TriangleElement {
@@ -43,23 +41,26 @@ private:
};
void addCurrentVertex(const GeometryCoordinate& currentVertex, double& distance,
const Point<double>& normal, double endLeft, double endRight, bool round,
- int32_t startVertex, std::vector<LineBucket::TriangleElement>& triangleStore);
+ std::size_t startVertex, std::vector<LineBucket::TriangleElement>& triangleStore);
void addPieSliceVertex(const GeometryCoordinate& currentVertex, double distance,
- const Point<double>& extrude, bool lineTurnsLeft, int32_t startVertex,
+ const Point<double>& extrude, bool lineTurnsLeft, std::size_t startVertex,
std::vector<TriangleElement>& triangleStore);
public:
style::LineLayoutProperties layout;
private:
- LineVertexBuffer vertexBuffer;
- TriangleElementsBuffer triangleElementsBuffer;
+ std::vector<LineVertex> vertices;
+ std::vector<gl::Triangle> triangles;
- int32_t e1;
- int32_t e2;
- int32_t e3;
+ std::vector<ElementGroup<LineShader, LineSDFShader, LinePatternShader>> groups;
- std::vector<std::unique_ptr<TriangleGroup>> triangleGroups;
+ optional<gl::VertexBuffer<LineVertex>> vertexBuffer;
+ optional<gl::IndexBuffer<gl::Triangle>> indexBuffer;
+
+ std::ptrdiff_t e1;
+ std::ptrdiff_t e2;
+ std::ptrdiff_t e3;
const uint32_t overscaling;
};
diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp
index 4c624a0d7a..ad0e75cd92 100644
--- a/src/mbgl/renderer/painter.cpp
+++ b/src/mbgl/renderer/painter.cpp
@@ -39,14 +39,35 @@ namespace mbgl {
using namespace style;
Painter::Painter(const TransformState& state_)
- : state(state_) {
+ : state(state_),
+ tileTriangleVertexBuffer(context.createVertexBuffer(std::vector<FillVertex> {{
+ { 0, 0 },
+ { util::EXTENT, 0 },
+ { 0, util::EXTENT },
+ { util::EXTENT, 0 },
+ { 0, util::EXTENT },
+ { util::EXTENT, util::EXTENT }
+ }})),
+ tileLineStripVertexBuffer(context.createVertexBuffer(std::vector<FillVertex> {{
+ { 0, 0 },
+ { util::EXTENT, 0 },
+ { util::EXTENT, util::EXTENT },
+ { 0, util::EXTENT },
+ { 0, 0 }
+ }})),
+ rasterVertexBuffer(context.createVertexBuffer(std::vector<RasterVertex> {{
+ { 0, 0, 0, 0 },
+ { util::EXTENT, 0, 32767, 0 },
+ { 0, util::EXTENT, 0, 32767 },
+ { util::EXTENT, util::EXTENT, 32767, 32767 }
+ }})) {
#ifndef NDEBUG
gl::debugging::enable();
#endif
shaders = std::make_unique<Shaders>(context);
#ifndef NDEBUG
- overdrawShaders = std::make_unique<Shaders>(context, Shader::Overdraw);
+ overdrawShaders = std::make_unique<Shaders>(context, gl::Shader::Overdraw);
#endif
// Reset GL values
@@ -109,9 +130,6 @@ void Painter::render(const Style& style, const FrameData& frame_, SpriteAtlas& a
{
MBGL_DEBUG_GROUP("upload");
- tileStencilBuffer.upload(context);
- rasterBoundsBuffer.upload(context);
- tileBorderBuffer.upload(context);
spriteAtlas->upload(context, 0);
lineAtlas->upload(context, 0);
glyphAtlas->upload(context, 0);
diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp
index 2159881ffd..28aa5aab44 100644
--- a/src/mbgl/renderer/painter.hpp
+++ b/src/mbgl/renderer/painter.hpp
@@ -8,10 +8,10 @@
#include <mbgl/renderer/render_item.hpp>
#include <mbgl/renderer/bucket.hpp>
-#include <mbgl/geometry/vao.hpp>
-#include <mbgl/geometry/static_vertex_buffer.hpp>
-
+#include <mbgl/gl/vao.hpp>
#include <mbgl/gl/context.hpp>
+#include <mbgl/shader/fill_vertex.hpp>
+#include <mbgl/shader/raster_vertex.hpp>
#include <mbgl/style/style.hpp>
@@ -41,7 +41,7 @@ class SymbolBucket;
class RasterBucket;
class Shaders;
-class SDFShader;
+class SymbolSDFShader;
class PaintParameters;
struct ClipID;
@@ -121,8 +121,8 @@ private:
const RenderTile&,
float scaleDivisor,
std::array<float, 2> texsize,
- SDFShader& sdfShader,
- void (SymbolBucket::*drawSDF)(SDFShader&, gl::Context&, PaintMode),
+ SymbolSDFShader& sdfShader,
+ void (SymbolBucket::*drawSDF)(SymbolSDFShader&, gl::Context&, PaintMode),
// Layout
style::AlignmentType rotationAlignment,
@@ -188,36 +188,11 @@ private:
std::unique_ptr<Shaders> overdrawShaders;
#endif
- // Set up the stencil quad we're using to generate the stencil mask.
- StaticVertexBuffer tileStencilBuffer {
- // top left triangle
- {{ 0, 0 }},
- {{ util::EXTENT, 0 }},
- {{ 0, util::EXTENT }},
-
- // bottom right triangle
- {{ util::EXTENT, 0 }},
- {{ 0, util::EXTENT }},
- {{ util::EXTENT, util::EXTENT }},
- };
-
- StaticRasterVertexBuffer rasterBoundsBuffer {
- {{ 0, 0, 0, 0 }},
- {{ util::EXTENT, 0, 32767, 0 }},
- {{ 0, util::EXTENT, 0, 32767 }},
- {{ util::EXTENT, util::EXTENT, 32767, 32767 }},
- };
-
- // Set up the tile boundary lines we're using to draw the tile outlines.
- StaticVertexBuffer tileBorderBuffer {
- {{ 0, 0 }},
- {{ util::EXTENT, 0 }},
- {{ util::EXTENT, util::EXTENT }},
- {{ 0, util::EXTENT }},
- {{ 0, 0 }},
- };
-
- VertexArrayObject tileBorderArray;
+ gl::VertexBuffer<FillVertex> tileTriangleVertexBuffer;
+ gl::VertexBuffer<FillVertex> tileLineStripVertexBuffer;
+ gl::VertexBuffer<RasterVertex> rasterVertexBuffer;
+
+ gl::VertexArrayObject tileBorderArray;
};
} // namespace mbgl
diff --git a/src/mbgl/renderer/painter_background.cpp b/src/mbgl/renderer/painter_background.cpp
index af92f17c97..61ec76d1d8 100644
--- a/src/mbgl/renderer/painter_background.cpp
+++ b/src/mbgl/renderer/painter_background.cpp
@@ -22,8 +22,8 @@ void Painter::renderBackground(PaintParameters& parameters, const BackgroundLaye
optional<SpriteAtlasPosition> imagePosA;
optional<SpriteAtlasPosition> imagePosB;
- auto& patternShader = parameters.shaders.pattern;
- auto& plainShader = parameters.shaders.plain;
+ auto& patternShader = parameters.shaders.fillPattern;
+ auto& plainShader = parameters.shaders.fill;
auto& arrayBackgroundPattern = parameters.shaders.backgroundPatternArray;
auto& arrayBackground = parameters.shaders.backgroundArray;
@@ -46,14 +46,14 @@ void Painter::renderBackground(PaintParameters& parameters, const BackgroundLaye
patternShader.u_opacity = properties.backgroundOpacity;
spriteAtlas->bind(true, context, 0);
- arrayBackgroundPattern.bind(patternShader, tileStencilBuffer, BUFFER_OFFSET(0), context);
+ arrayBackgroundPattern.bind(patternShader, tileTriangleVertexBuffer, BUFFER_OFFSET(0), context);
} else {
context.program = plainShader.getID();
plainShader.u_color = properties.backgroundColor;
plainShader.u_opacity = properties.backgroundOpacity;
- arrayBackground.bind(plainShader, tileStencilBuffer, BUFFER_OFFSET(0), context);
+ arrayBackground.bind(plainShader, tileTriangleVertexBuffer, BUFFER_OFFSET(0), context);
}
context.stencilTest = false;
@@ -84,7 +84,7 @@ void Painter::renderBackground(PaintParameters& parameters, const BackgroundLaye
plainShader.u_matrix = vertexMatrix;
}
- MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)tileStencilBuffer.index()));
+ MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, static_cast<GLsizei>(tileTriangleVertexBuffer.vertexCount)));
}
}
diff --git a/src/mbgl/renderer/painter_circle.cpp b/src/mbgl/renderer/painter_circle.cpp
index 327011d03e..462ed59ebf 100644
--- a/src/mbgl/renderer/painter_circle.cpp
+++ b/src/mbgl/renderer/painter_circle.cpp
@@ -51,7 +51,7 @@ void Painter::renderCircle(PaintParameters& parameters,
circleShader.u_blur = properties.circleBlur;
circleShader.u_opacity = properties.circleOpacity;
- bucket.drawCircles(circleShader, context);
+ bucket.drawCircles(circleShader, context, paintMode());
}
} // namespace mbgl
diff --git a/src/mbgl/renderer/painter_clipping.cpp b/src/mbgl/renderer/painter_clipping.cpp
index 03402a2695..68f580c280 100644
--- a/src/mbgl/renderer/painter_clipping.cpp
+++ b/src/mbgl/renderer/painter_clipping.cpp
@@ -14,7 +14,7 @@ namespace mbgl {
void Painter::drawClippingMasks(PaintParameters& parameters, const std::map<UnwrappedTileID, ClipID>& stencils) {
MBGL_DEBUG_GROUP("clipping masks");
- auto& plainShader = parameters.shaders.plain;
+ auto& plainShader = parameters.shaders.fill;
auto& arrayCoveringPlain = parameters.shaders.coveringPlainArray;
mat4 matrix;
@@ -29,7 +29,7 @@ void Painter::drawClippingMasks(PaintParameters& parameters, const std::map<Unwr
context.colorMask = { false, false, false, false };
context.stencilMask = mask;
- arrayCoveringPlain.bind(plainShader, tileStencilBuffer, BUFFER_OFFSET_0, context);
+ arrayCoveringPlain.bind(plainShader, tileTriangleVertexBuffer, BUFFER_OFFSET_0, context);
for (const auto& stencil : stencils) {
const auto& id = stencil.first;
@@ -42,7 +42,7 @@ void Painter::drawClippingMasks(PaintParameters& parameters, const std::map<Unwr
const GLint ref = (GLint)(clip.reference.to_ulong());
context.stencilFunc = { gl::StencilTestFunction::Always, ref, mask };
- MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index()));
+ MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(tileTriangleVertexBuffer.vertexCount)));
}
}
diff --git a/src/mbgl/renderer/painter_debug.cpp b/src/mbgl/renderer/painter_debug.cpp
index f19b77462a..23a2a8e571 100644
--- a/src/mbgl/renderer/painter_debug.cpp
+++ b/src/mbgl/renderer/painter_debug.cpp
@@ -35,10 +35,10 @@ void Painter::renderDebugText(Tile& tile, const mat4 &matrix) {
tile.debugBucket->debugMode != frame.debugOptions) {
tile.debugBucket = std::make_unique<DebugBucket>(
tile.id, tile.isRenderable(), tile.isComplete(), tile.modified,
- tile.expires, frame.debugOptions);
+ tile.expires, frame.debugOptions, context);
}
- auto& plainShader = shaders->plain;
+ auto& plainShader = shaders->fill;
context.program = plainShader.getID();
plainShader.u_matrix = matrix;
plainShader.u_opacity = 1.0f;
@@ -74,16 +74,16 @@ void Painter::renderDebugFrame(const mat4 &matrix) {
gl::StencilTestOperation::Replace };
context.stencilTest = true;
- auto& plainShader = shaders->plain;
+ auto& plainShader = shaders->fill;
context.program = plainShader.getID();
plainShader.u_matrix = matrix;
plainShader.u_opacity = 1.0f;
// draw tile outline
- tileBorderArray.bind(plainShader, tileBorderBuffer, BUFFER_OFFSET_0, context);
+ tileBorderArray.bind(plainShader, tileLineStripVertexBuffer, BUFFER_OFFSET_0, context);
plainShader.u_color = { 1.0f, 0.0f, 0.0f, 1.0f };
context.lineWidth = 4.0f * frame.pixelRatio;
- MBGL_CHECK_ERROR(glDrawArrays(GL_LINE_STRIP, 0, (GLsizei)tileBorderBuffer.index()));
+ MBGL_CHECK_ERROR(glDrawArrays(GL_LINE_STRIP, 0, static_cast<GLsizei>(tileLineStripVertexBuffer.vertexCount)));
}
#ifndef NDEBUG
diff --git a/src/mbgl/renderer/painter_fill.cpp b/src/mbgl/renderer/painter_fill.cpp
index 6d6ae4df61..50ead900f6 100644
--- a/src/mbgl/renderer/painter_fill.cpp
+++ b/src/mbgl/renderer/painter_fill.cpp
@@ -43,10 +43,10 @@ void Painter::renderFill(PaintParameters& parameters,
context.depthMask = true;
context.lineWidth = 2.0f; // This is always fixed and does not depend on the pixelRatio!
- auto& outlineShader = parameters.shaders.outline;
- auto& patternShader = parameters.shaders.pattern;
- auto& outlinePatternShader = parameters.shaders.outlinePattern;
- auto& plainShader = parameters.shaders.plain;
+ auto& outlineShader = parameters.shaders.fillOutline;
+ auto& patternShader = parameters.shaders.fillPattern;
+ auto& outlinePatternShader = parameters.shaders.fillOutlinePattern;
+ auto& plainShader = parameters.shaders.fill;
// Because we're drawing top-to-bottom, and we update the stencil mask
// befrom, we have to draw the outline first (!)
diff --git a/src/mbgl/renderer/painter_line.cpp b/src/mbgl/renderer/painter_line.cpp
index ee749746b9..85a5786353 100644
--- a/src/mbgl/renderer/painter_line.cpp
+++ b/src/mbgl/renderer/painter_line.cpp
@@ -57,8 +57,8 @@ void Painter::renderLine(PaintParameters& parameters,
setDepthSublayer(0);
- auto& linesdfShader = parameters.shaders.linesdf;
- auto& linepatternShader = parameters.shaders.linepattern;
+ auto& linesdfShader = parameters.shaders.lineSDF;
+ auto& linepatternShader = parameters.shaders.linePattern;
auto& lineShader = parameters.shaders.line;
if (!properties.lineDasharray.value.from.empty()) {
diff --git a/src/mbgl/renderer/painter_raster.cpp b/src/mbgl/renderer/painter_raster.cpp
index 8a05456927..8b39c8adf8 100644
--- a/src/mbgl/renderer/painter_raster.cpp
+++ b/src/mbgl/renderer/painter_raster.cpp
@@ -47,7 +47,7 @@ void Painter::renderRaster(PaintParameters& parameters,
context.depthMask = false;
setDepthSublayer(0);
- bucket.drawRaster(rasterShader, rasterBoundsBuffer, rasterVAO, context);
+ bucket.drawRaster(rasterShader, rasterVertexBuffer, rasterVAO, context);
}
}
diff --git a/src/mbgl/renderer/painter_symbol.cpp b/src/mbgl/renderer/painter_symbol.cpp
index a91329d003..2ed6facad8 100644
--- a/src/mbgl/renderer/painter_symbol.cpp
+++ b/src/mbgl/renderer/painter_symbol.cpp
@@ -19,8 +19,8 @@ void Painter::renderSDF(SymbolBucket& bucket,
const RenderTile& tile,
float sdfFontSize,
std::array<float, 2> texsize,
- SDFShader& sdfShader,
- void (SymbolBucket::*drawSDF)(SDFShader&, gl::Context&, PaintMode),
+ SymbolSDFShader& sdfShader,
+ void (SymbolBucket::*drawSDF)(SymbolSDFShader&, gl::Context&, PaintMode),
// Layout
AlignmentType rotationAlignment,
@@ -168,7 +168,7 @@ void Painter::renderSymbol(PaintParameters& parameters,
tile,
1.0f,
{{ float(activeSpriteAtlas->getWidth()) / 4.0f, float(activeSpriteAtlas->getHeight()) / 4.0f }},
- parameters.shaders.sdfIcon,
+ parameters.shaders.symbolIconSDF,
&SymbolBucket::drawIcons,
layout.iconRotationAlignment,
// icon-pitch-alignment is not yet implemented
@@ -200,7 +200,7 @@ void Painter::renderSymbol(PaintParameters& parameters,
}};
}
- auto& iconShader = parameters.shaders.icon;
+ auto& iconShader = parameters.shaders.symbolIcon;
context.program = iconShader.getID();
iconShader.u_matrix = vtxMatrix;
@@ -235,7 +235,7 @@ void Painter::renderSymbol(PaintParameters& parameters,
tile,
24.0f,
{{ float(glyphAtlas->width) / 4, float(glyphAtlas->height) / 4 }},
- parameters.shaders.sdfGlyph,
+ parameters.shaders.symbolGlyph,
&SymbolBucket::drawGlyphs,
layout.textRotationAlignment,
layout.textPitchAlignment,
@@ -251,9 +251,7 @@ void Painter::renderSymbol(PaintParameters& parameters,
}
if (bucket.hasCollisionBoxData()) {
- context.stencilOp = { gl::StencilTestOperation::Keep, gl::StencilTestOperation::Keep,
- gl::StencilTestOperation::Replace };
- context.stencilTest = true;
+ context.stencilTest = false;
auto& collisionBoxShader = shaders->collisionBox;
context.program = collisionBoxShader.getID();
diff --git a/src/mbgl/renderer/raster_bucket.cpp b/src/mbgl/renderer/raster_bucket.cpp
index 3edbe3e042..80d6dfe8dd 100644
--- a/src/mbgl/renderer/raster_bucket.cpp
+++ b/src/mbgl/renderer/raster_bucket.cpp
@@ -3,7 +3,7 @@
#include <mbgl/shader/raster_shader.hpp>
#include <mbgl/renderer/painter.hpp>
#include <mbgl/gl/gl.hpp>
-
+#include <mbgl/gl/context.hpp>
namespace mbgl {
@@ -26,14 +26,14 @@ void RasterBucket::render(Painter& painter,
}
void RasterBucket::drawRaster(RasterShader& shader,
- StaticRasterVertexBuffer& vertices,
- VertexArrayObject& array,
+ gl::VertexBuffer<RasterVertex>& vertices,
+ gl::VertexArrayObject& array,
gl::Context& context) {
assert(texture);
context.bindTexture(*texture, 0, gl::TextureFilter::Linear);
context.bindTexture(*texture, 1, gl::TextureFilter::Linear);
array.bind(shader, vertices, BUFFER_OFFSET_0, context);
- MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)vertices.index()));
+ MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, static_cast<GLsizei>(vertices.vertexCount)));
}
bool RasterBucket::hasData() const {
diff --git a/src/mbgl/renderer/raster_bucket.hpp b/src/mbgl/renderer/raster_bucket.hpp
index db8138b875..b0d3ca49c7 100644
--- a/src/mbgl/renderer/raster_bucket.hpp
+++ b/src/mbgl/renderer/raster_bucket.hpp
@@ -2,13 +2,19 @@
#include <mbgl/renderer/bucket.hpp>
#include <mbgl/util/image.hpp>
-#include <mbgl/gl/context.hpp>
+#include <mbgl/util/optional.hpp>
+#include <mbgl/gl/texture.hpp>
namespace mbgl {
class RasterShader;
-class StaticRasterVertexBuffer;
+class RasterVertex;
+
+namespace gl {
+class Context;
+template <class> class VertexBuffer;
class VertexArrayObject;
+} // namespace gl
class RasterBucket : public Bucket {
public:
@@ -19,7 +25,7 @@ public:
bool hasData() const override;
bool needsClipping() const override;
- void drawRaster(RasterShader&, StaticRasterVertexBuffer&, VertexArrayObject&, gl::Context&);
+ void drawRaster(RasterShader&, gl::VertexBuffer<RasterVertex>&, gl::VertexArrayObject&, gl::Context&);
private:
PremultipliedImage image;
diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp
index 3ef0686e4d..565c58c7ed 100644
--- a/src/mbgl/renderer/symbol_bucket.cpp
+++ b/src/mbgl/renderer/symbol_bucket.cpp
@@ -1,8 +1,8 @@
#include <mbgl/renderer/symbol_bucket.hpp>
#include <mbgl/renderer/painter.hpp>
#include <mbgl/style/layers/symbol_layer.hpp>
-#include <mbgl/shader/sdf_shader.hpp>
-#include <mbgl/shader/icon_shader.hpp>
+#include <mbgl/shader/symbol_sdf_shader.hpp>
+#include <mbgl/shader/symbol_icon_shader.hpp>
#include <mbgl/shader/collision_box_shader.hpp>
#include <mbgl/gl/gl.hpp>
@@ -22,12 +22,17 @@ SymbolBucket::SymbolBucket(const MapMode mode_,
void SymbolBucket::upload(gl::Context& context) {
if (hasTextData()) {
- text.vertices.upload(context);
- text.triangles.upload(context);
+ text.vertexBuffer = context.createVertexBuffer(std::move(text.vertices));
+ text.indexBuffer = context.createIndexBuffer(std::move(text.triangles));
}
+
if (hasIconData()) {
- icon.vertices.upload(context);
- icon.triangles.upload(context);
+ icon.vertexBuffer = context.createVertexBuffer(std::move(icon.vertices));
+ icon.indexBuffer = context.createIndexBuffer(std::move(icon.triangles));
+ }
+
+ if (hasCollisionBoxData()) {
+ collisionBox.vertexBuffer = context.createVertexBuffer(std::move(collisionBox.vertices));
}
uploaded = true;
@@ -61,51 +66,48 @@ bool SymbolBucket::needsClipping() const {
return mode == MapMode::Still;
}
-void SymbolBucket::drawGlyphs(SDFShader& shader,
+void SymbolBucket::drawGlyphs(SymbolSDFShader& shader,
gl::Context& context,
PaintMode paintMode) {
GLbyte* vertex_index = BUFFER_OFFSET_0;
GLbyte* elements_index = BUFFER_OFFSET_0;
for (auto& group : text.groups) {
- assert(group);
- group->array[paintMode == PaintMode::Overdraw ? 1 : 0].bind(
- shader, text.vertices, text.triangles, vertex_index, context);
- MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT,
+ group.getVAO(shader, paintMode).bind(
+ shader, *text.vertexBuffer, *text.indexBuffer, vertex_index, context);
+ MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(group.indexLength * 3), GL_UNSIGNED_SHORT,
elements_index));
- vertex_index += group->vertex_length * text.vertices.itemSize;
- elements_index += group->elements_length * text.triangles.itemSize;
+ vertex_index += group.vertexLength * text.vertexBuffer->vertexSize;
+ elements_index += group.indexLength * text.indexBuffer->primitiveSize;
}
}
-void SymbolBucket::drawIcons(SDFShader& shader,
+void SymbolBucket::drawIcons(SymbolSDFShader& shader,
gl::Context& context,
PaintMode paintMode) {
GLbyte* vertex_index = BUFFER_OFFSET_0;
GLbyte* elements_index = BUFFER_OFFSET_0;
for (auto& group : icon.groups) {
- assert(group);
- group->array[paintMode == PaintMode::Overdraw ? 1 : 0].bind(
- shader, icon.vertices, icon.triangles, vertex_index, context);
- MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT,
+ group.getVAO(shader, paintMode).bind(
+ shader, *icon.vertexBuffer, *icon.indexBuffer, vertex_index, context);
+ MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(group.indexLength * 3), GL_UNSIGNED_SHORT,
elements_index));
- vertex_index += group->vertex_length * icon.vertices.itemSize;
- elements_index += group->elements_length * icon.triangles.itemSize;
+ vertex_index += group.vertexLength * icon.vertexBuffer->vertexSize;
+ elements_index += group.indexLength * icon.indexBuffer->primitiveSize;
}
}
-void SymbolBucket::drawIcons(IconShader& shader,
+void SymbolBucket::drawIcons(SymbolIconShader& shader,
gl::Context& context,
PaintMode paintMode) {
GLbyte* vertex_index = BUFFER_OFFSET_0;
GLbyte* elements_index = BUFFER_OFFSET_0;
for (auto& group : icon.groups) {
- assert(group);
- group->array[paintMode == PaintMode::Overdraw ? 3 : 2].bind(
- shader, icon.vertices, icon.triangles, vertex_index, context);
- MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, group->elements_length * 3, GL_UNSIGNED_SHORT,
+ group.getVAO(shader, paintMode).bind(
+ shader, *icon.vertexBuffer, *icon.indexBuffer, vertex_index, context);
+ MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(group.indexLength * 3), GL_UNSIGNED_SHORT,
elements_index));
- vertex_index += group->vertex_length * icon.vertices.itemSize;
- elements_index += group->elements_length * icon.triangles.itemSize;
+ vertex_index += group.vertexLength * icon.vertexBuffer->vertexSize;
+ elements_index += group.indexLength * icon.indexBuffer->primitiveSize;
}
}
@@ -113,8 +115,9 @@ void SymbolBucket::drawCollisionBoxes(CollisionBoxShader& shader,
gl::Context& context) {
GLbyte* vertex_index = BUFFER_OFFSET_0;
for (auto& group : collisionBox.groups) {
- group->array[0].bind(shader, collisionBox.vertices, vertex_index, context);
- MBGL_CHECK_ERROR(glDrawArrays(GL_LINES, 0, group->vertex_length));
+ group.getVAO(shader, PaintMode::Regular).bind(
+ shader, *collisionBox.vertexBuffer, vertex_index, context);
+ MBGL_CHECK_ERROR(glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(group.vertexLength)));
}
}
diff --git a/src/mbgl/renderer/symbol_bucket.hpp b/src/mbgl/renderer/symbol_bucket.hpp
index 87c8250d55..e5180c31e2 100644
--- a/src/mbgl/renderer/symbol_bucket.hpp
+++ b/src/mbgl/renderer/symbol_bucket.hpp
@@ -1,11 +1,12 @@
#pragma once
#include <mbgl/renderer/bucket.hpp>
+#include <mbgl/renderer/element_group.hpp>
#include <mbgl/map/mode.hpp>
-#include <mbgl/geometry/elements_buffer.hpp>
-#include <mbgl/geometry/text_buffer.hpp>
-#include <mbgl/geometry/icon_buffer.hpp>
-#include <mbgl/geometry/collision_box_buffer.hpp>
+#include <mbgl/gl/vertex_buffer.hpp>
+#include <mbgl/gl/index_buffer.hpp>
+#include <mbgl/shader/symbol_vertex.hpp>
+#include <mbgl/shader/collision_box_vertex.hpp>
#include <mbgl/text/glyph_range.hpp>
#include <mbgl/style/layers/symbol_layer_properties.hpp>
@@ -14,8 +15,8 @@
namespace mbgl {
-class SDFShader;
-class IconShader;
+class SymbolSDFShader;
+class SymbolIconShader;
class CollisionBoxShader;
class SymbolBucket : public Bucket {
@@ -33,9 +34,9 @@ public:
bool hasCollisionBoxData() const;
bool needsClipping() const override;
- void drawGlyphs(SDFShader&, gl::Context&, PaintMode);
- void drawIcons(SDFShader&, gl::Context&, PaintMode);
- void drawIcons(IconShader&, gl::Context&, PaintMode);
+ void drawGlyphs(SymbolSDFShader&, gl::Context&, PaintMode);
+ void drawIcons(SymbolSDFShader&, gl::Context&, PaintMode);
+ void drawIcons(SymbolIconShader&, gl::Context&, PaintMode);
void drawCollisionBoxes(CollisionBoxShader&, gl::Context&);
const MapMode mode;
@@ -46,25 +47,31 @@ public:
private:
friend class SymbolLayout;
- typedef ElementGroup<2> TextElementGroup;
- typedef ElementGroup<4> IconElementGroup;
- typedef ElementGroup<1> CollisionBoxElementGroup;
-
struct TextBuffer {
- TextVertexBuffer vertices;
- TriangleElementsBuffer triangles;
- std::vector<std::unique_ptr<TextElementGroup>> groups;
+ std::vector<SymbolVertex> vertices;
+ std::vector<gl::Triangle> triangles;
+ std::vector<ElementGroup<SymbolSDFShader>> groups;
+
+ optional<gl::VertexBuffer<SymbolVertex>> vertexBuffer;
+ optional<gl::IndexBuffer<gl::Triangle>> indexBuffer;
} text;
struct IconBuffer {
- IconVertexBuffer vertices;
- TriangleElementsBuffer triangles;
- std::vector<std::unique_ptr<IconElementGroup>> groups;
+ std::vector<SymbolVertex> vertices;
+ std::vector<gl::Triangle> triangles;
+ std::vector<ElementGroup<SymbolSDFShader, SymbolIconShader>> groups;
+
+ optional<gl::VertexBuffer<SymbolVertex>> vertexBuffer;
+ optional<gl::IndexBuffer<gl::Triangle>> indexBuffer;
} icon;
struct CollisionBoxBuffer {
- CollisionBoxVertexBuffer vertices;
- std::vector<std::unique_ptr<CollisionBoxElementGroup>> groups;
+ std::vector<CollisionBoxVertex> vertices;
+ std::vector<gl::Line> lines;
+ std::vector<ElementGroup<CollisionBoxShader>> groups;
+
+ optional<gl::VertexBuffer<CollisionBoxVertex>> vertexBuffer;
+ optional<gl::IndexBuffer<gl::Line>> indexBuffer;
} collisionBox;
};
diff --git a/src/mbgl/shader/circle_shader.cpp b/src/mbgl/shader/circle_shader.cpp
index b3430d4450..9e294f8d76 100644
--- a/src/mbgl/shader/circle_shader.cpp
+++ b/src/mbgl/shader/circle_shader.cpp
@@ -1,7 +1,7 @@
#include <mbgl/shader/circle_shader.hpp>
#include <mbgl/shader/circle.vertex.hpp>
#include <mbgl/shader/circle.fragment.hpp>
-#include <mbgl/gl/gl.hpp>
+#include <mbgl/shader/circle_vertex.hpp>
namespace mbgl {
@@ -12,9 +12,4 @@ CircleShader::CircleShader(gl::Context& context, Defines defines)
context, defines) {
}
-void CircleShader::bind(int8_t* offset) {
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 4, offset));
-}
-
} // namespace mbgl
diff --git a/src/mbgl/shader/circle_shader.hpp b/src/mbgl/shader/circle_shader.hpp
index b87d856775..c2c4053ba4 100644
--- a/src/mbgl/shader/circle_shader.hpp
+++ b/src/mbgl/shader/circle_shader.hpp
@@ -1,25 +1,30 @@
#pragma once
-#include <mbgl/shader/shader.hpp>
-#include <mbgl/shader/uniform.hpp>
+#include <mbgl/gl/shader.hpp>
+#include <mbgl/gl/attribute.hpp>
+#include <mbgl/gl/uniform.hpp>
#include <mbgl/util/color.hpp>
namespace mbgl {
-class CircleShader : public Shader {
+class CircleVertex;
+
+class CircleShader : public gl::Shader {
public:
CircleShader(gl::Context&, Defines defines = None);
- void bind(int8_t* offset) final;
+ using VertexType = CircleVertex;
+
+ gl::Attribute<int16_t, 2> a_pos = {"a_pos", *this};
- UniformMatrix<4> u_matrix = {"u_matrix", *this};
- Uniform<std::array<float, 2>> u_extrude_scale = {"u_extrude_scale", *this};
- Uniform<float> u_devicepixelratio = {"u_devicepixelratio", *this};
- Uniform<Color> u_color = {"u_color", *this};
- Uniform<float> u_radius = {"u_radius", *this};
- Uniform<float> u_blur = {"u_blur", *this};
- Uniform<float> u_opacity = {"u_opacity", *this};
- Uniform<int32_t> u_scale_with_map = {"u_scale_with_map", *this};
+ gl::UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ gl::Uniform<std::array<float, 2>> u_extrude_scale = {"u_extrude_scale", *this};
+ gl::Uniform<float> u_devicepixelratio = {"u_devicepixelratio", *this};
+ gl::Uniform<Color> u_color = {"u_color", *this};
+ gl::Uniform<float> u_radius = {"u_radius", *this};
+ gl::Uniform<float> u_blur = {"u_blur", *this};
+ gl::Uniform<float> u_opacity = {"u_opacity", *this};
+ gl::Uniform<int32_t> u_scale_with_map = {"u_scale_with_map", *this};
};
} // namespace mbgl
diff --git a/src/mbgl/shader/circle_vertex.cpp b/src/mbgl/shader/circle_vertex.cpp
new file mode 100644
index 0000000000..8beb88e650
--- /dev/null
+++ b/src/mbgl/shader/circle_vertex.cpp
@@ -0,0 +1,7 @@
+#include <mbgl/shader/circle_vertex.hpp>
+
+namespace mbgl {
+
+static_assert(sizeof(CircleVertex) == 4, "expected CircleVertex size");
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/circle_vertex.hpp b/src/mbgl/shader/circle_vertex.hpp
new file mode 100644
index 0000000000..4fce49f137
--- /dev/null
+++ b/src/mbgl/shader/circle_vertex.hpp
@@ -0,0 +1,39 @@
+#pragma once
+
+#include <mbgl/gl/attribute.hpp>
+
+#include <array>
+#include <cstdint>
+
+namespace mbgl {
+
+class CircleVertex {
+public:
+ /*
+ * @param {number} x vertex position
+ * @param {number} y vertex position
+ * @param {number} ex extrude normal
+ * @param {number} ey extrude normal
+ */
+ CircleVertex(int16_t x, int16_t y, float ex, float ey)
+ : a_pos {
+ static_cast<int16_t>((x * 2) + ((ex + 1) / 2)),
+ static_cast<int16_t>((y * 2) + ((ey + 1) / 2))
+ } {}
+
+ const int16_t a_pos[2];
+};
+
+namespace gl {
+
+template <class Shader>
+struct AttributeBindings<Shader, CircleVertex> {
+ std::array<AttributeBinding, 1> operator()(const Shader& shader) {
+ return {{
+ MBGL_MAKE_ATTRIBUTE_BINDING(CircleVertex, shader, a_pos)
+ }};
+ };
+};
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/shader/collision_box_shader.cpp b/src/mbgl/shader/collision_box_shader.cpp
index c0a24f0f6f..d61c849cd1 100644
--- a/src/mbgl/shader/collision_box_shader.cpp
+++ b/src/mbgl/shader/collision_box_shader.cpp
@@ -1,28 +1,15 @@
#include <mbgl/shader/collision_box_shader.hpp>
-#include <mbgl/shader/collisionbox.vertex.hpp>
-#include <mbgl/shader/collisionbox.fragment.hpp>
-#include <mbgl/gl/gl.hpp>
+#include <mbgl/shader/collision_box.vertex.hpp>
+#include <mbgl/shader/collision_box.fragment.hpp>
+#include <mbgl/shader/collision_box_vertex.hpp>
namespace mbgl {
CollisionBoxShader::CollisionBoxShader(gl::Context& context)
- : Shader(shaders::collisionbox::name,
- shaders::collisionbox::vertex,
- shaders::collisionbox::fragment,
+ : Shader(shaders::collision_box::name,
+ shaders::collision_box::vertex,
+ shaders::collision_box::fragment,
context) {
}
-void CollisionBoxShader::bind(GLbyte *offset) {
- const GLint stride = 12;
-
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_SHORT, false, stride, offset + 0));
-
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_extrude));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_extrude, 2, GL_SHORT, false, stride, offset + 4));
-
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_data));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_data, 2, GL_UNSIGNED_BYTE, false, stride, offset + 8));
-}
-
} // namespace mbgl
diff --git a/src/mbgl/shader/collision_box_shader.hpp b/src/mbgl/shader/collision_box_shader.hpp
index 65c3ca0146..2f5c506168 100644
--- a/src/mbgl/shader/collision_box_shader.hpp
+++ b/src/mbgl/shader/collision_box_shader.hpp
@@ -1,20 +1,27 @@
#pragma once
-#include <mbgl/shader/shader.hpp>
-#include <mbgl/shader/uniform.hpp>
+#include <mbgl/gl/shader.hpp>
+#include <mbgl/gl/attribute.hpp>
+#include <mbgl/gl/uniform.hpp>
namespace mbgl {
-class CollisionBoxShader : public Shader {
+class CollisionBoxVertex;
+
+class CollisionBoxShader : public gl::Shader {
public:
CollisionBoxShader(gl::Context&);
- void bind(int8_t* offset) final;
+ using VertexType = CollisionBoxVertex;
+
+ gl::Attribute<int16_t, 2> a_pos = {"a_pos", *this};
+ gl::Attribute<int16_t, 2> a_extrude = {"a_extrude", *this};
+ gl::Attribute<uint8_t, 2> a_data = {"a_data", *this};
- UniformMatrix<4> u_matrix = {"u_matrix", *this};
- Uniform<float> u_scale = {"u_scale", *this};
- Uniform<float> u_zoom = {"u_zoom", *this};
- Uniform<float> u_maxzoom = {"u_maxzoom", *this};
+ gl::UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ gl::Uniform<float> u_scale = {"u_scale", *this};
+ gl::Uniform<float> u_zoom = {"u_zoom", *this};
+ gl::Uniform<float> u_maxzoom = {"u_maxzoom", *this};
};
} // namespace mbgl
diff --git a/src/mbgl/shader/collision_box_vertex.cpp b/src/mbgl/shader/collision_box_vertex.cpp
new file mode 100644
index 0000000000..397fbfe6a3
--- /dev/null
+++ b/src/mbgl/shader/collision_box_vertex.cpp
@@ -0,0 +1,7 @@
+#include <mbgl/shader/collision_box_vertex.hpp>
+
+namespace mbgl {
+
+static_assert(sizeof(CollisionBoxVertex) == 10, "expected CollisionBoxVertex size");
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/collision_box_vertex.hpp b/src/mbgl/shader/collision_box_vertex.hpp
new file mode 100644
index 0000000000..ba72b1c0ee
--- /dev/null
+++ b/src/mbgl/shader/collision_box_vertex.hpp
@@ -0,0 +1,43 @@
+#pragma once
+
+#include <mbgl/gl/attribute.hpp>
+
+#include <array>
+#include <cstdint>
+#include <cmath>
+
+namespace mbgl {
+
+class CollisionBoxVertex {
+public:
+ CollisionBoxVertex(int16_t x, int16_t y, float ox, float oy, float maxzoom, float placementZoom)
+ : a_pos { x, y },
+ a_extrude {
+ static_cast<int16_t>(::round(ox)),
+ static_cast<int16_t>(::round(oy))
+ },
+ a_data {
+ static_cast<uint8_t>(maxzoom * 10),
+ static_cast<uint8_t>(placementZoom * 10)
+ } {}
+
+ const int16_t a_pos[2];
+ const int16_t a_extrude[2];
+ const uint8_t a_data[2];
+};
+
+namespace gl {
+
+template <class Shader>
+struct AttributeBindings<Shader, CollisionBoxVertex> {
+ std::array<AttributeBinding, 3> operator()(const Shader& shader) {
+ return {{
+ MBGL_MAKE_ATTRIBUTE_BINDING(CollisionBoxVertex, shader, a_pos),
+ MBGL_MAKE_ATTRIBUTE_BINDING(CollisionBoxVertex, shader, a_extrude),
+ MBGL_MAKE_ATTRIBUTE_BINDING(CollisionBoxVertex, shader, a_data)
+ }};
+ };
+};
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/shader/fill_outline_pattern_shader.cpp b/src/mbgl/shader/fill_outline_pattern_shader.cpp
new file mode 100644
index 0000000000..b03921d384
--- /dev/null
+++ b/src/mbgl/shader/fill_outline_pattern_shader.cpp
@@ -0,0 +1,15 @@
+#include <mbgl/shader/fill_outline_pattern_shader.hpp>
+#include <mbgl/shader/fill_outline_pattern.vertex.hpp>
+#include <mbgl/shader/fill_outline_pattern.fragment.hpp>
+#include <mbgl/shader/fill_vertex.hpp>
+
+namespace mbgl {
+
+FillOutlinePatternShader::FillOutlinePatternShader(gl::Context& context, Defines defines)
+ : Shader(shaders::fill_outline_pattern::name,
+ shaders::fill_outline_pattern::vertex,
+ shaders::fill_outline_pattern::fragment,
+ context, defines) {
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/fill_outline_pattern_shader.hpp b/src/mbgl/shader/fill_outline_pattern_shader.hpp
new file mode 100644
index 0000000000..630e6a7ce8
--- /dev/null
+++ b/src/mbgl/shader/fill_outline_pattern_shader.hpp
@@ -0,0 +1,37 @@
+#pragma once
+
+#include <mbgl/gl/shader.hpp>
+#include <mbgl/gl/attribute.hpp>
+#include <mbgl/gl/uniform.hpp>
+
+namespace mbgl {
+
+class FillVertex;
+
+class FillOutlinePatternShader : public gl::Shader {
+public:
+ FillOutlinePatternShader(gl::Context&, Defines defines = None);
+
+ using VertexType = FillVertex;
+
+ gl::Attribute<int16_t, 2> a_pos = {"a_pos", *this};
+
+ gl::UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_tl_a = {"u_pattern_tl_a", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_br_a = {"u_pattern_br_a", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_tl_b = {"u_pattern_tl_b", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_br_b = {"u_pattern_br_b", *this};
+ gl::Uniform<float> u_opacity = {"u_opacity", *this};
+ gl::Uniform<float> u_mix = {"u_mix", *this};
+ gl::Uniform<float> u_scale_a = {"u_scale_a", *this};
+ gl::Uniform<float> u_scale_b = {"u_scale_b", *this};
+ gl::Uniform<float> u_tile_units_to_pixels = {"u_tile_units_to_pixels", *this};
+ gl::Uniform<int32_t> u_image = {"u_image", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_size_a = {"u_pattern_size_a", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_size_b = {"u_pattern_size_b", *this};
+ gl::Uniform<std::array<float, 2>> u_pixel_coord_upper = {"u_pixel_coord_upper", *this};
+ gl::Uniform<std::array<float, 2>> u_pixel_coord_lower = {"u_pixel_coord_lower", *this};
+ gl::Uniform<std::array<float, 2>> u_world = {"u_world", *this};
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/fill_outline_shader.cpp b/src/mbgl/shader/fill_outline_shader.cpp
new file mode 100644
index 0000000000..6e6d8c2239
--- /dev/null
+++ b/src/mbgl/shader/fill_outline_shader.cpp
@@ -0,0 +1,15 @@
+#include <mbgl/shader/fill_outline_shader.hpp>
+#include <mbgl/shader/fill_outline.vertex.hpp>
+#include <mbgl/shader/fill_outline.fragment.hpp>
+#include <mbgl/shader/fill_vertex.hpp>
+
+namespace mbgl {
+
+FillOutlineShader::FillOutlineShader(gl::Context& context, Defines defines)
+ : Shader(shaders::fill_outline::name,
+ shaders::fill_outline::vertex,
+ shaders::fill_outline::fragment,
+ context, defines) {
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/fill_outline_shader.hpp b/src/mbgl/shader/fill_outline_shader.hpp
new file mode 100644
index 0000000000..c20bc187d3
--- /dev/null
+++ b/src/mbgl/shader/fill_outline_shader.hpp
@@ -0,0 +1,26 @@
+#pragma once
+
+#include <mbgl/gl/shader.hpp>
+#include <mbgl/gl/attribute.hpp>
+#include <mbgl/gl/uniform.hpp>
+#include <mbgl/util/color.hpp>
+
+namespace mbgl {
+
+class FillVertex;
+
+class FillOutlineShader : public gl::Shader {
+public:
+ FillOutlineShader(gl::Context&, Defines defines = None);
+
+ using VertexType = FillVertex;
+
+ gl::Attribute<int16_t, 2> a_pos = {"a_pos", *this};
+
+ gl::UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ gl::Uniform<Color> u_outline_color = {"u_outline_color", *this};
+ gl::Uniform<float> u_opacity = {"u_opacity", *this};
+ gl::Uniform<std::array<float, 2>> u_world = {"u_world", *this};
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/fill_pattern_shader.cpp b/src/mbgl/shader/fill_pattern_shader.cpp
new file mode 100644
index 0000000000..60be6d79ad
--- /dev/null
+++ b/src/mbgl/shader/fill_pattern_shader.cpp
@@ -0,0 +1,15 @@
+#include <mbgl/shader/fill_pattern_shader.hpp>
+#include <mbgl/shader/fill_pattern.vertex.hpp>
+#include <mbgl/shader/fill_pattern.fragment.hpp>
+#include <mbgl/shader/fill_vertex.hpp>
+
+namespace mbgl {
+
+FillPatternShader::FillPatternShader(gl::Context& context, Defines defines)
+ : Shader(shaders::fill_pattern::name,
+ shaders::fill_pattern::vertex,
+ shaders::fill_pattern::fragment,
+ context, defines) {
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/fill_pattern_shader.hpp b/src/mbgl/shader/fill_pattern_shader.hpp
new file mode 100644
index 0000000000..36be538000
--- /dev/null
+++ b/src/mbgl/shader/fill_pattern_shader.hpp
@@ -0,0 +1,36 @@
+#pragma once
+
+#include <mbgl/gl/shader.hpp>
+#include <mbgl/gl/attribute.hpp>
+#include <mbgl/gl/uniform.hpp>
+
+namespace mbgl {
+
+class FillVertex;
+
+class FillPatternShader : public gl::Shader {
+public:
+ FillPatternShader(gl::Context&, Defines defines = None);
+
+ using VertexType = FillVertex;
+
+ gl::Attribute<int16_t, 2> a_pos = {"a_pos", *this};
+
+ gl::UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_tl_a = {"u_pattern_tl_a", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_br_a = {"u_pattern_br_a", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_tl_b = {"u_pattern_tl_b", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_br_b = {"u_pattern_br_b", *this};
+ gl::Uniform<float> u_opacity = {"u_opacity", *this};
+ gl::Uniform<float> u_mix = {"u_mix", *this};
+ gl::Uniform<float> u_scale_a = {"u_scale_a", *this};
+ gl::Uniform<float> u_scale_b = {"u_scale_b", *this};
+ gl::Uniform<float> u_tile_units_to_pixels = {"u_tile_units_to_pixels", *this};
+ gl::Uniform<int32_t> u_image = {"u_image", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_size_a = {"u_pattern_size_a", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_size_b = {"u_pattern_size_b", *this};
+ gl::Uniform<std::array<float, 2>> u_pixel_coord_upper = {"u_pixel_coord_upper", *this};
+ gl::Uniform<std::array<float, 2>> u_pixel_coord_lower = {"u_pixel_coord_lower", *this};
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/fill_shader.cpp b/src/mbgl/shader/fill_shader.cpp
new file mode 100644
index 0000000000..7026bb2f1c
--- /dev/null
+++ b/src/mbgl/shader/fill_shader.cpp
@@ -0,0 +1,15 @@
+#include <mbgl/shader/fill_shader.hpp>
+#include <mbgl/shader/fill.vertex.hpp>
+#include <mbgl/shader/fill.fragment.hpp>
+#include <mbgl/shader/fill_vertex.hpp>
+
+namespace mbgl {
+
+FillShader::FillShader(gl::Context& context, Defines defines)
+ : Shader(shaders::fill::name,
+ shaders::fill::vertex,
+ shaders::fill::fragment,
+ context, defines) {
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/fill_shader.hpp b/src/mbgl/shader/fill_shader.hpp
new file mode 100644
index 0000000000..1240b73aa2
--- /dev/null
+++ b/src/mbgl/shader/fill_shader.hpp
@@ -0,0 +1,25 @@
+#pragma once
+
+#include <mbgl/gl/shader.hpp>
+#include <mbgl/gl/attribute.hpp>
+#include <mbgl/gl/uniform.hpp>
+#include <mbgl/util/color.hpp>
+
+namespace mbgl {
+
+class FillVertex;
+
+class FillShader : public gl::Shader {
+public:
+ FillShader(gl::Context&, Defines defines = None);
+
+ using VertexType = FillVertex;
+
+ gl::Attribute<int16_t, 2> a_pos = {"a_pos", *this};
+
+ gl::UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ gl::Uniform<Color> u_color = {"u_color", *this};
+ gl::Uniform<float> u_opacity = {"u_opacity", *this};
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/fill_vertex.cpp b/src/mbgl/shader/fill_vertex.cpp
new file mode 100644
index 0000000000..c39a0b96b1
--- /dev/null
+++ b/src/mbgl/shader/fill_vertex.cpp
@@ -0,0 +1,7 @@
+#include <mbgl/shader/fill_vertex.hpp>
+
+namespace mbgl {
+
+static_assert(sizeof(FillVertex) == 4, "expected FillVertex size");
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/fill_vertex.hpp b/src/mbgl/shader/fill_vertex.hpp
new file mode 100644
index 0000000000..1b8130382a
--- /dev/null
+++ b/src/mbgl/shader/fill_vertex.hpp
@@ -0,0 +1,30 @@
+#pragma once
+
+#include <mbgl/gl/attribute.hpp>
+
+#include <array>
+#include <cstdint>
+
+namespace mbgl {
+
+class FillVertex {
+public:
+ FillVertex(int16_t x, int16_t y)
+ : a_pos { x, y } {}
+
+ const int16_t a_pos[2];
+};
+
+namespace gl {
+
+template <class Shader>
+struct AttributeBindings<Shader, FillVertex> {
+ std::array<AttributeBinding, 1> operator()(const Shader& shader) {
+ return {{
+ MBGL_MAKE_ATTRIBUTE_BINDING(FillVertex, shader, a_pos)
+ }};
+ };
+};
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/shader/icon_shader.cpp b/src/mbgl/shader/icon_shader.cpp
deleted file mode 100644
index d002e49a49..0000000000
--- a/src/mbgl/shader/icon_shader.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-#include <mbgl/shader/icon_shader.hpp>
-#include <mbgl/shader/icon.vertex.hpp>
-#include <mbgl/shader/icon.fragment.hpp>
-#include <mbgl/gl/gl.hpp>
-
-namespace mbgl {
-
-IconShader::IconShader(gl::Context& context, Defines defines)
- : Shader(shaders::icon::name,
- shaders::icon::vertex,
- shaders::icon::fragment,
- context, defines) {
-}
-
-void IconShader::bind(int8_t* offset) {
- const GLsizei stride = 16;
-
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_SHORT, false, stride, offset + 0));
-
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_offset));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_offset, 2, GL_SHORT, false, stride, offset + 4));
-
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_texture_pos));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_texture_pos, 2, GL_UNSIGNED_SHORT, false, stride, offset + 8));
-
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_data));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_data, 4, GL_UNSIGNED_BYTE, false, stride, offset + 12));
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/icon_shader.hpp b/src/mbgl/shader/icon_shader.hpp
deleted file mode 100644
index c4f24c91f7..0000000000
--- a/src/mbgl/shader/icon_shader.hpp
+++ /dev/null
@@ -1,24 +0,0 @@
-#pragma once
-
-#include <mbgl/shader/shader.hpp>
-#include <mbgl/shader/uniform.hpp>
-
-namespace mbgl {
-
-class IconShader : public Shader {
-public:
- IconShader(gl::Context&, Defines defines = None);
-
- void bind(int8_t* offset) final;
-
- UniformMatrix<4> u_matrix = {"u_matrix", *this};
- Uniform<std::array<float, 2>> u_extrude_scale = {"u_extrude_scale", *this};
- Uniform<float> u_zoom = {"u_zoom", *this};
- Uniform<float> u_opacity = {"u_opacity", *this};
- Uniform<std::array<float, 2>> u_texsize = {"u_texsize", *this};
- Uniform<int32_t> u_rotate_with_map = {"u_rotate_with_map", *this};
- Uniform<int32_t> u_texture = {"u_texture", *this};
- Uniform<int32_t> u_fadetexture = {"u_fadetexture", *this};
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/line_pattern_shader.cpp b/src/mbgl/shader/line_pattern_shader.cpp
new file mode 100644
index 0000000000..e6bc32a5c9
--- /dev/null
+++ b/src/mbgl/shader/line_pattern_shader.cpp
@@ -0,0 +1,15 @@
+#include <mbgl/shader/line_pattern_shader.hpp>
+#include <mbgl/shader/line_pattern.vertex.hpp>
+#include <mbgl/shader/line_pattern.fragment.hpp>
+#include <mbgl/shader/line_vertex.hpp>
+
+namespace mbgl {
+
+LinePatternShader::LinePatternShader(gl::Context& context, Defines defines)
+ : Shader(shaders::line_pattern::name,
+ shaders::line_pattern::vertex,
+ shaders::line_pattern::fragment,
+ context, defines) {
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/line_pattern_shader.hpp b/src/mbgl/shader/line_pattern_shader.hpp
new file mode 100644
index 0000000000..1bd6085c8b
--- /dev/null
+++ b/src/mbgl/shader/line_pattern_shader.hpp
@@ -0,0 +1,41 @@
+#pragma once
+
+#include <mbgl/gl/shader.hpp>
+#include <mbgl/gl/uniform.hpp>
+#include <mbgl/gl/attribute.hpp>
+
+namespace mbgl {
+
+class LineVertex;
+
+class LinePatternShader : public gl::Shader {
+public:
+ LinePatternShader(gl::Context&, Defines defines = None);
+
+ using VertexType = LineVertex;
+
+ gl::Attribute<int16_t, 2> a_pos = { "a_pos", *this };
+ gl::Attribute<uint8_t, 4> a_data = { "a_data", *this };
+
+ gl::UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ gl::Uniform<float> u_linewidth = {"u_linewidth", *this};
+ gl::Uniform<float> u_gapwidth = {"u_gapwidth", *this};
+ gl::Uniform<float> u_antialiasing = {"u_antialiasing", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_size_a = {"u_pattern_size_a", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_tl_a = {"u_pattern_tl_a", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_br_a = {"u_pattern_br_a", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_size_b = {"u_pattern_size_b", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_tl_b = {"u_pattern_tl_b", *this};
+ gl::Uniform<std::array<float, 2>> u_pattern_br_b = {"u_pattern_br_b", *this};
+ gl::Uniform<float> u_ratio = {"u_ratio", *this};
+ gl::Uniform<float> u_point = {"u_point", *this};
+ gl::Uniform<float> u_blur = {"u_blur", *this};
+ gl::Uniform<float> u_fade = {"u_fade", *this};
+ gl::Uniform<float> u_opacity = {"u_opacity", *this};
+ gl::Uniform<float> u_extra = {"u_extra", *this};
+ gl::Uniform<float> u_offset = {"u_offset", *this};
+ gl::Uniform<int32_t> u_image = {"u_image", *this};
+ gl::UniformMatrix<2> u_antialiasingmatrix = {"u_antialiasingmatrix", *this};
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/line_sdf_shader.cpp b/src/mbgl/shader/line_sdf_shader.cpp
new file mode 100644
index 0000000000..dd724365ea
--- /dev/null
+++ b/src/mbgl/shader/line_sdf_shader.cpp
@@ -0,0 +1,15 @@
+#include <mbgl/shader/line_sdf_shader.hpp>
+#include <mbgl/shader/line_sdf.vertex.hpp>
+#include <mbgl/shader/line_sdf.fragment.hpp>
+#include <mbgl/shader/line_vertex.hpp>
+
+namespace mbgl {
+
+LineSDFShader::LineSDFShader(gl::Context& context, Defines defines)
+ : Shader(shaders::line_sdf::name,
+ shaders::line_sdf::vertex,
+ shaders::line_sdf::fragment,
+ context, defines) {
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/line_sdf_shader.hpp b/src/mbgl/shader/line_sdf_shader.hpp
new file mode 100644
index 0000000000..d74e42e50f
--- /dev/null
+++ b/src/mbgl/shader/line_sdf_shader.hpp
@@ -0,0 +1,42 @@
+#pragma once
+
+#include <mbgl/gl/shader.hpp>
+#include <mbgl/gl/attribute.hpp>
+#include <mbgl/gl/uniform.hpp>
+#include <mbgl/util/color.hpp>
+
+namespace mbgl {
+
+class LineVertex;
+
+class LineSDFShader : public gl::Shader {
+public:
+ LineSDFShader(gl::Context&, Defines defines = None);
+
+ using VertexType = LineVertex;
+
+ gl::Attribute<int16_t, 2> a_pos = { "a_pos", *this };
+ gl::Attribute<uint8_t, 4> a_data = { "a_data", *this };
+
+ gl::UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ gl::Uniform<Color> u_color = {"u_color", *this};
+ gl::Uniform<float> u_opacity = {"u_opacity", *this};
+ gl::Uniform<float> u_linewidth = {"u_linewidth", *this};
+ gl::Uniform<float> u_gapwidth = {"u_gapwidth", *this};
+ gl::Uniform<float> u_antialiasing = {"u_antialiasing", *this};
+ gl::Uniform<float> u_ratio = {"u_ratio", *this};
+ gl::Uniform<float> u_blur = {"u_blur", *this};
+ gl::Uniform<std::array<float, 2>> u_patternscale_a = { "u_patternscale_a", *this};
+ gl::Uniform<float> u_tex_y_a = {"u_tex_y_a", *this};
+ gl::Uniform<std::array<float, 2>> u_patternscale_b = { "u_patternscale_b", *this};
+ gl::Uniform<float> u_tex_y_b = {"u_tex_y_b", *this};
+ gl::Uniform<int32_t> u_image = {"u_image", *this};
+ gl::Uniform<float> u_sdfgamma = {"u_sdfgamma", *this};
+ gl::Uniform<float> u_mix = {"u_mix", *this};
+ gl::Uniform<float> u_extra = {"u_extra", *this};
+ gl::Uniform<float> u_offset = {"u_offset", *this};
+ gl::UniformMatrix<2> u_antialiasingmatrix = {"u_antialiasingmatrix", *this};
+};
+
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/line_shader.cpp b/src/mbgl/shader/line_shader.cpp
index 684390815c..4e934cd60c 100644
--- a/src/mbgl/shader/line_shader.cpp
+++ b/src/mbgl/shader/line_shader.cpp
@@ -1,7 +1,7 @@
#include <mbgl/shader/line_shader.hpp>
#include <mbgl/shader/line.vertex.hpp>
#include <mbgl/shader/line.fragment.hpp>
-#include <mbgl/gl/gl.hpp>
+#include <mbgl/shader/line_vertex.hpp>
namespace mbgl {
@@ -12,12 +12,4 @@ LineShader::LineShader(gl::Context& context, Defines defines)
context, defines) {
}
-void LineShader::bind(int8_t* offset) {
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 8, offset + 0));
-
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_data));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_data, 4, GL_UNSIGNED_BYTE, false, 8, offset + 4));
-}
-
} // namespace mbgl
diff --git a/src/mbgl/shader/line_shader.hpp b/src/mbgl/shader/line_shader.hpp
index a6be32ebc3..79991e1883 100644
--- a/src/mbgl/shader/line_shader.hpp
+++ b/src/mbgl/shader/line_shader.hpp
@@ -1,28 +1,34 @@
#pragma once
-#include <mbgl/shader/shader.hpp>
-#include <mbgl/shader/uniform.hpp>
+#include <mbgl/gl/shader.hpp>
+#include <mbgl/gl/attribute.hpp>
+#include <mbgl/gl/uniform.hpp>
#include <mbgl/util/color.hpp>
namespace mbgl {
-class LineShader : public Shader {
+class LineVertex;
+
+class LineShader : public gl::Shader {
public:
LineShader(gl::Context&, Defines defines = None);
- void bind(int8_t* offset) final;
-
- UniformMatrix<4> u_matrix = {"u_matrix", *this};
- Uniform<Color> u_color = {"u_color", *this};
- Uniform<float> u_opacity = {"u_opacity", *this};
- Uniform<float> u_ratio = {"u_ratio", *this};
- Uniform<float> u_linewidth = {"u_linewidth", *this};
- Uniform<float> u_gapwidth = {"u_gapwidth", *this};
- Uniform<float> u_antialiasing = {"u_antialiasing", *this};
- Uniform<float> u_blur = {"u_blur", *this};
- Uniform<float> u_extra = {"u_extra", *this};
- Uniform<float> u_offset = {"u_offset", *this};
- UniformMatrix<2> u_antialiasingmatrix = {"u_antialiasingmatrix", *this};
+ using VertexType = LineVertex;
+
+ gl::Attribute<int16_t, 2> a_pos = { "a_pos", *this };
+ gl::Attribute<uint8_t, 4> a_data = { "a_data", *this };
+
+ gl::UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ gl::Uniform<Color> u_color = {"u_color", *this};
+ gl::Uniform<float> u_opacity = {"u_opacity", *this};
+ gl::Uniform<float> u_ratio = {"u_ratio", *this};
+ gl::Uniform<float> u_linewidth = {"u_linewidth", *this};
+ gl::Uniform<float> u_gapwidth = {"u_gapwidth", *this};
+ gl::Uniform<float> u_antialiasing = {"u_antialiasing", *this};
+ gl::Uniform<float> u_blur = {"u_blur", *this};
+ gl::Uniform<float> u_extra = {"u_extra", *this};
+ gl::Uniform<float> u_offset = {"u_offset", *this};
+ gl::UniformMatrix<2> u_antialiasingmatrix = {"u_antialiasingmatrix", *this};
};
diff --git a/src/mbgl/shader/line_vertex.cpp b/src/mbgl/shader/line_vertex.cpp
new file mode 100644
index 0000000000..ad466310d8
--- /dev/null
+++ b/src/mbgl/shader/line_vertex.cpp
@@ -0,0 +1,7 @@
+#include <mbgl/shader/line_vertex.hpp>
+
+namespace mbgl {
+
+static_assert(sizeof(LineVertex) == 8, "expected LineVertex size");
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/line_vertex.hpp b/src/mbgl/shader/line_vertex.hpp
new file mode 100644
index 0000000000..086100810e
--- /dev/null
+++ b/src/mbgl/shader/line_vertex.hpp
@@ -0,0 +1,72 @@
+#pragma once
+
+#include <mbgl/gl/attribute.hpp>
+
+#include <array>
+#include <cstdint>
+#include <cmath>
+
+namespace mbgl {
+
+class LineVertex {
+public:
+ /*
+ * @param {number} x vertex position
+ * @param {number} y vertex position
+ * @param {number} ex extrude normal
+ * @param {number} ey extrude normal
+ * @param {number} tx texture normal
+ * @param {number} ty texture normal
+ * @param {number} dir direction of the line cap (-1/0/1)
+ */
+ LineVertex(int16_t x, int16_t y, float ex, float ey, bool tx, bool ty, int8_t dir, int32_t linesofar = 0)
+ : a_pos {
+ static_cast<int16_t>((x * 2) | tx),
+ static_cast<int16_t>((y * 2) | ty)
+ },
+ a_data {
+ // add 128 to store an byte in an unsigned byte
+ static_cast<uint8_t>(::round(extrudeScale * ex) + 128),
+ static_cast<uint8_t>(::round(extrudeScale * ey) + 128),
+
+ // Encode the -1/0/1 direction value into the first two bits of .z of a_data.
+ // Combine it with the lower 6 bits of `linesofar` (shifted by 2 bites to make
+ // room for the direction value). The upper 8 bits of `linesofar` are placed in
+ // the `w` component. `linesofar` is scaled down by `LINE_DISTANCE_SCALE` so that
+ // we can store longer distances while sacrificing precision.
+
+ // Encode the -1/0/1 direction value into .zw coordinates of a_data, which is normally covered
+ // by linesofar, so we need to merge them.
+ // The z component's first bit, as well as the sign bit is reserved for the direction,
+ // so we need to shift the linesofar.
+ static_cast<uint8_t>(((dir == 0 ? 0 : (dir < 0 ? -1 : 1 )) + 1) | ((linesofar & 0x3F) << 2)),
+ static_cast<uint8_t>(linesofar >> 6)
+ } {}
+
+ const int16_t a_pos[2];
+ const uint8_t a_data[4];
+
+ /*
+ * Scale the extrusion vector so that the normal length is this value.
+ * Contains the "texture" normals (-1..1). This is distinct from the extrude
+ * normals for line joins, because the x-value remains 0 for the texture
+ * normal array, while the extrude normal actually moves the vertex to create
+ * the acute/bevelled line join.
+ */
+ static const int8_t extrudeScale = 63;
+};
+
+namespace gl {
+
+template <class Shader>
+struct AttributeBindings<Shader, LineVertex> {
+ std::array<AttributeBinding, 2> operator()(const Shader& shader) {
+ return {{
+ MBGL_MAKE_ATTRIBUTE_BINDING(LineVertex, shader, a_pos),
+ MBGL_MAKE_ATTRIBUTE_BINDING(LineVertex, shader, a_data)
+ }};
+ };
+};
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/shader/linepattern_shader.cpp b/src/mbgl/shader/linepattern_shader.cpp
deleted file mode 100644
index 8f755d4140..0000000000
--- a/src/mbgl/shader/linepattern_shader.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-#include <mbgl/shader/linepattern_shader.hpp>
-#include <mbgl/shader/linepattern.vertex.hpp>
-#include <mbgl/shader/linepattern.fragment.hpp>
-#include <mbgl/gl/gl.hpp>
-
-namespace mbgl {
-
-LinepatternShader::LinepatternShader(gl::Context& context, Defines defines)
- : Shader(shaders::linepattern::name,
- shaders::linepattern::vertex,
- shaders::linepattern::fragment,
- context, defines) {
-}
-
-void LinepatternShader::bind(int8_t* offset) {
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 8, offset + 0));
-
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_data));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_data, 4, GL_UNSIGNED_BYTE, false, 8, offset + 4));
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/linepattern_shader.hpp b/src/mbgl/shader/linepattern_shader.hpp
deleted file mode 100644
index 89f64d3e1f..0000000000
--- a/src/mbgl/shader/linepattern_shader.hpp
+++ /dev/null
@@ -1,35 +0,0 @@
-#pragma once
-
-#include <mbgl/shader/shader.hpp>
-#include <mbgl/shader/uniform.hpp>
-
-namespace mbgl {
-
-class LinepatternShader : public Shader {
-public:
- LinepatternShader(gl::Context&, Defines defines = None);
-
- void bind(int8_t* offset) final;
-
- UniformMatrix<4> u_matrix = {"u_matrix", *this};
- Uniform<float> u_linewidth = {"u_linewidth", *this};
- Uniform<float> u_gapwidth = {"u_gapwidth", *this};
- Uniform<float> u_antialiasing = {"u_antialiasing", *this};
- Uniform<std::array<float, 2>> u_pattern_size_a = {"u_pattern_size_a", *this};
- Uniform<std::array<float, 2>> u_pattern_tl_a = {"u_pattern_tl_a", *this};
- Uniform<std::array<float, 2>> u_pattern_br_a = {"u_pattern_br_a", *this};
- Uniform<std::array<float, 2>> u_pattern_size_b = {"u_pattern_size_b", *this};
- Uniform<std::array<float, 2>> u_pattern_tl_b = {"u_pattern_tl_b", *this};
- Uniform<std::array<float, 2>> u_pattern_br_b = {"u_pattern_br_b", *this};
- Uniform<float> u_ratio = {"u_ratio", *this};
- Uniform<float> u_point = {"u_point", *this};
- Uniform<float> u_blur = {"u_blur", *this};
- Uniform<float> u_fade = {"u_fade", *this};
- Uniform<float> u_opacity = {"u_opacity", *this};
- Uniform<float> u_extra = {"u_extra", *this};
- Uniform<float> u_offset = {"u_offset", *this};
- Uniform<int32_t> u_image = {"u_image", *this};
- UniformMatrix<2> u_antialiasingmatrix = {"u_antialiasingmatrix", *this};
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/linesdf_shader.cpp b/src/mbgl/shader/linesdf_shader.cpp
deleted file mode 100644
index 788239459f..0000000000
--- a/src/mbgl/shader/linesdf_shader.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-#include <mbgl/shader/linesdf_shader.hpp>
-#include <mbgl/shader/linesdfpattern.vertex.hpp>
-#include <mbgl/shader/linesdfpattern.fragment.hpp>
-#include <mbgl/gl/gl.hpp>
-
-namespace mbgl {
-
-LineSDFShader::LineSDFShader(gl::Context& context, Defines defines)
- : Shader(shaders::linesdfpattern::name,
- shaders::linesdfpattern::vertex,
- shaders::linesdfpattern::fragment,
- context, defines) {
-}
-
-void LineSDFShader::bind(int8_t* offset) {
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 8, offset + 0));
-
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_data));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_data, 4, GL_UNSIGNED_BYTE, false, 8, offset + 4));
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/linesdf_shader.hpp b/src/mbgl/shader/linesdf_shader.hpp
deleted file mode 100644
index 4c1fd89635..0000000000
--- a/src/mbgl/shader/linesdf_shader.hpp
+++ /dev/null
@@ -1,36 +0,0 @@
-#pragma once
-
-#include <mbgl/shader/shader.hpp>
-#include <mbgl/shader/uniform.hpp>
-#include <mbgl/util/color.hpp>
-
-namespace mbgl {
-
-class LineSDFShader : public Shader {
-public:
- LineSDFShader(gl::Context&, Defines defines = None);
-
- void bind(int8_t* offset) final;
-
- UniformMatrix<4> u_matrix = {"u_matrix", *this};
- Uniform<Color> u_color = {"u_color", *this};
- Uniform<float> u_opacity = {"u_opacity", *this};
- Uniform<float> u_linewidth = {"u_linewidth", *this};
- Uniform<float> u_gapwidth = {"u_gapwidth", *this};
- Uniform<float> u_antialiasing = {"u_antialiasing", *this};
- Uniform<float> u_ratio = {"u_ratio", *this};
- Uniform<float> u_blur = {"u_blur", *this};
- Uniform<std::array<float, 2>> u_patternscale_a = { "u_patternscale_a", *this};
- Uniform<float> u_tex_y_a = {"u_tex_y_a", *this};
- Uniform<std::array<float, 2>> u_patternscale_b = { "u_patternscale_b", *this};
- Uniform<float> u_tex_y_b = {"u_tex_y_b", *this};
- Uniform<int32_t> u_image = {"u_image", *this};
- Uniform<float> u_sdfgamma = {"u_sdfgamma", *this};
- Uniform<float> u_mix = {"u_mix", *this};
- Uniform<float> u_extra = {"u_extra", *this};
- Uniform<float> u_offset = {"u_offset", *this};
- UniformMatrix<2> u_antialiasingmatrix = {"u_antialiasingmatrix", *this};
-};
-
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/outline_shader.cpp b/src/mbgl/shader/outline_shader.cpp
deleted file mode 100644
index 94e981f4a6..0000000000
--- a/src/mbgl/shader/outline_shader.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#include <mbgl/shader/outline_shader.hpp>
-#include <mbgl/shader/outline.vertex.hpp>
-#include <mbgl/shader/outline.fragment.hpp>
-#include <mbgl/gl/gl.hpp>
-
-namespace mbgl {
-
-OutlineShader::OutlineShader(gl::Context& context, Defines defines)
- : Shader(shaders::outline::name,
- shaders::outline::vertex,
- shaders::outline::fragment,
- context, defines) {
-}
-
-void OutlineShader::bind(int8_t* offset) {
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset));
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/outline_shader.hpp b/src/mbgl/shader/outline_shader.hpp
deleted file mode 100644
index ccd8dc4303..0000000000
--- a/src/mbgl/shader/outline_shader.hpp
+++ /dev/null
@@ -1,21 +0,0 @@
-#pragma once
-
-#include <mbgl/shader/shader.hpp>
-#include <mbgl/shader/uniform.hpp>
-#include <mbgl/util/color.hpp>
-
-namespace mbgl {
-
-class OutlineShader : public Shader {
-public:
- OutlineShader(gl::Context&, Defines defines = None);
-
- void bind(int8_t* offset) final;
-
- UniformMatrix<4> u_matrix = {"u_matrix", *this};
- Uniform<Color> u_outline_color = {"u_outline_color", *this};
- Uniform<float> u_opacity = {"u_opacity", *this};
- Uniform<std::array<float, 2>> u_world = {"u_world", *this};
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/outlinepattern_shader.cpp b/src/mbgl/shader/outlinepattern_shader.cpp
deleted file mode 100644
index b33c2b2c1f..0000000000
--- a/src/mbgl/shader/outlinepattern_shader.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#include <mbgl/shader/outlinepattern_shader.hpp>
-#include <mbgl/shader/outlinepattern.vertex.hpp>
-#include <mbgl/shader/outlinepattern.fragment.hpp>
-#include <mbgl/gl/gl.hpp>
-
-namespace mbgl {
-
-OutlinePatternShader::OutlinePatternShader(gl::Context& context, Defines defines)
- : Shader(shaders::outlinepattern::name,
- shaders::outlinepattern::vertex,
- shaders::outlinepattern::fragment,
- context, defines) {
-}
-
-void OutlinePatternShader::bind(GLbyte *offset) {
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset));
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/outlinepattern_shader.hpp b/src/mbgl/shader/outlinepattern_shader.hpp
deleted file mode 100644
index 795d390f19..0000000000
--- a/src/mbgl/shader/outlinepattern_shader.hpp
+++ /dev/null
@@ -1,32 +0,0 @@
-#pragma once
-
-#include <mbgl/shader/shader.hpp>
-#include <mbgl/shader/uniform.hpp>
-
-namespace mbgl {
-
-class OutlinePatternShader : public Shader {
-public:
- OutlinePatternShader(gl::Context&, Defines defines = None);
-
- void bind(int8_t* offset) final;
-
- UniformMatrix<4> u_matrix = {"u_matrix", *this};
- Uniform<std::array<float, 2>> u_pattern_tl_a = {"u_pattern_tl_a", *this};
- Uniform<std::array<float, 2>> u_pattern_br_a = {"u_pattern_br_a", *this};
- Uniform<std::array<float, 2>> u_pattern_tl_b = {"u_pattern_tl_b", *this};
- Uniform<std::array<float, 2>> u_pattern_br_b = {"u_pattern_br_b", *this};
- Uniform<float> u_opacity = {"u_opacity", *this};
- Uniform<float> u_mix = {"u_mix", *this};
- Uniform<float> u_scale_a = {"u_scale_a", *this};
- Uniform<float> u_scale_b = {"u_scale_b", *this};
- Uniform<float> u_tile_units_to_pixels = {"u_tile_units_to_pixels", *this};
- Uniform<int32_t> u_image = {"u_image", *this};
- Uniform<std::array<float, 2>> u_pattern_size_a = {"u_pattern_size_a", *this};
- Uniform<std::array<float, 2>> u_pattern_size_b = {"u_pattern_size_b", *this};
- Uniform<std::array<float, 2>> u_pixel_coord_upper = {"u_pixel_coord_upper", *this};
- Uniform<std::array<float, 2>> u_pixel_coord_lower = {"u_pixel_coord_lower", *this};
- Uniform<std::array<float, 2>> u_world = {"u_world", *this};
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/pattern_shader.cpp b/src/mbgl/shader/pattern_shader.cpp
deleted file mode 100644
index dba12155f9..0000000000
--- a/src/mbgl/shader/pattern_shader.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#include <mbgl/shader/pattern_shader.hpp>
-#include <mbgl/shader/pattern.vertex.hpp>
-#include <mbgl/shader/pattern.fragment.hpp>
-#include <mbgl/gl/gl.hpp>
-
-namespace mbgl {
-
-PatternShader::PatternShader(gl::Context& context, Defines defines)
- : Shader(shaders::pattern::name,
- shaders::pattern::vertex,
- shaders::pattern::fragment,
- context, defines) {
-}
-
-void PatternShader::bind(GLbyte *offset) {
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset));
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/pattern_shader.hpp b/src/mbgl/shader/pattern_shader.hpp
deleted file mode 100644
index 6ba141a2cb..0000000000
--- a/src/mbgl/shader/pattern_shader.hpp
+++ /dev/null
@@ -1,31 +0,0 @@
-#pragma once
-
-#include <mbgl/shader/shader.hpp>
-#include <mbgl/shader/uniform.hpp>
-
-namespace mbgl {
-
-class PatternShader : public Shader {
-public:
- PatternShader(gl::Context&, Defines defines = None);
-
- void bind(int8_t* offset) final;
-
- UniformMatrix<4> u_matrix = {"u_matrix", *this};
- Uniform<std::array<float, 2>> u_pattern_tl_a = {"u_pattern_tl_a", *this};
- Uniform<std::array<float, 2>> u_pattern_br_a = {"u_pattern_br_a", *this};
- Uniform<std::array<float, 2>> u_pattern_tl_b = {"u_pattern_tl_b", *this};
- Uniform<std::array<float, 2>> u_pattern_br_b = {"u_pattern_br_b", *this};
- Uniform<float> u_opacity = {"u_opacity", *this};
- Uniform<float> u_mix = {"u_mix", *this};
- Uniform<float> u_scale_a = {"u_scale_a", *this};
- Uniform<float> u_scale_b = {"u_scale_b", *this};
- Uniform<float> u_tile_units_to_pixels = {"u_tile_units_to_pixels", *this};
- Uniform<int32_t> u_image = {"u_image", *this};
- Uniform<std::array<float, 2>> u_pattern_size_a = {"u_pattern_size_a", *this};
- Uniform<std::array<float, 2>> u_pattern_size_b = {"u_pattern_size_b", *this};
- Uniform<std::array<float, 2>> u_pixel_coord_upper = {"u_pixel_coord_upper", *this};
- Uniform<std::array<float, 2>> u_pixel_coord_lower = {"u_pixel_coord_lower", *this};
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/plain_shader.cpp b/src/mbgl/shader/plain_shader.cpp
deleted file mode 100644
index 8ea008c4ec..0000000000
--- a/src/mbgl/shader/plain_shader.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#include <mbgl/shader/plain_shader.hpp>
-#include <mbgl/shader/fill.vertex.hpp>
-#include <mbgl/shader/fill.fragment.hpp>
-#include <mbgl/gl/gl.hpp>
-
-namespace mbgl {
-
-PlainShader::PlainShader(gl::Context& context, Defines defines)
- : Shader(shaders::fill::name,
- shaders::fill::vertex,
- shaders::fill::fragment,
- context, defines) {
-}
-
-void PlainShader::bind(int8_t* offset) {
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_SHORT, false, 0, offset));
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/plain_shader.hpp b/src/mbgl/shader/plain_shader.hpp
deleted file mode 100644
index 2611a5a549..0000000000
--- a/src/mbgl/shader/plain_shader.hpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#pragma once
-
-#include <mbgl/shader/shader.hpp>
-#include <mbgl/shader/uniform.hpp>
-#include <mbgl/util/color.hpp>
-
-namespace mbgl {
-
-class PlainShader : public Shader {
-public:
- PlainShader(gl::Context&, Defines defines = None);
-
- void bind(int8_t* offset) final;
-
- UniformMatrix<4> u_matrix = {"u_matrix", *this};
- Uniform<Color> u_color = {"u_color", *this};
- Uniform<float> u_opacity = {"u_opacity", *this};
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/raster_shader.cpp b/src/mbgl/shader/raster_shader.cpp
index 8133b396c6..34b2bdf47b 100644
--- a/src/mbgl/shader/raster_shader.cpp
+++ b/src/mbgl/shader/raster_shader.cpp
@@ -1,7 +1,7 @@
#include <mbgl/shader/raster_shader.hpp>
#include <mbgl/shader/raster.vertex.hpp>
#include <mbgl/shader/raster.fragment.hpp>
-#include <mbgl/gl/gl.hpp>
+#include <mbgl/shader/raster_vertex.hpp>
namespace mbgl {
@@ -12,14 +12,4 @@ RasterShader::RasterShader(gl::Context& context, Defines defines)
context, defines) {
}
-void RasterShader::bind(int8_t* offset) {
- const GLint stride = 8;
-
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_SHORT, false, stride, offset));
-
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_texture_pos));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_texture_pos, 2, GL_SHORT, false, stride, offset + 4));
-}
-
} // namespace mbgl
diff --git a/src/mbgl/shader/raster_shader.hpp b/src/mbgl/shader/raster_shader.hpp
index e583b2337d..9633fd5fa0 100644
--- a/src/mbgl/shader/raster_shader.hpp
+++ b/src/mbgl/shader/raster_shader.hpp
@@ -1,29 +1,35 @@
#pragma once
-#include <mbgl/shader/shader.hpp>
-#include <mbgl/shader/uniform.hpp>
+#include <mbgl/gl/shader.hpp>
+#include <mbgl/gl/attribute.hpp>
+#include <mbgl/gl/uniform.hpp>
namespace mbgl {
-class RasterShader : public Shader {
+class RasterVertex;
+
+class RasterShader : public gl::Shader {
public:
RasterShader(gl::Context&, Defines defines = None);
- void bind(int8_t* offset) final;
-
- UniformMatrix<4> u_matrix = {"u_matrix", *this};
- Uniform<int32_t> u_image0 = {"u_image0", *this};
- Uniform<int32_t> u_image1 = {"u_image1", *this};
- Uniform<float> u_opacity0 = {"u_opacity0", *this};
- Uniform<float> u_opacity1 = {"u_opacity1", *this};
- Uniform<float> u_buffer_scale = {"u_buffer_scale", *this};
- Uniform<float> u_brightness_low = {"u_brightness_low", *this};
- Uniform<float> u_brightness_high = {"u_brightness_high", *this};
- Uniform<float> u_saturation_factor = {"u_saturation_factor", *this};
- Uniform<float> u_contrast_factor = {"u_contrast_factor", *this};
- Uniform<std::array<float, 3>> u_spin_weights = {"u_spin_weights", *this};
- Uniform<std::array<float, 2>> u_tl_parent = {"u_tl_parent", *this};
- Uniform<float> u_scale_parent = {"u_scale_parent", *this};
+ using VertexType = RasterVertex;
+
+ gl::Attribute<int16_t, 2> a_pos = { "a_pos", *this };
+ gl::Attribute<uint16_t, 2> a_texture_pos = { "a_texture_pos", *this };
+
+ gl::UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ gl::Uniform<int32_t> u_image0 = {"u_image0", *this};
+ gl::Uniform<int32_t> u_image1 = {"u_image1", *this};
+ gl::Uniform<float> u_opacity0 = {"u_opacity0", *this};
+ gl::Uniform<float> u_opacity1 = {"u_opacity1", *this};
+ gl::Uniform<float> u_buffer_scale = {"u_buffer_scale", *this};
+ gl::Uniform<float> u_brightness_low = {"u_brightness_low", *this};
+ gl::Uniform<float> u_brightness_high = {"u_brightness_high", *this};
+ gl::Uniform<float> u_saturation_factor = {"u_saturation_factor", *this};
+ gl::Uniform<float> u_contrast_factor = {"u_contrast_factor", *this};
+ gl::Uniform<std::array<float, 3>> u_spin_weights = {"u_spin_weights", *this};
+ gl::Uniform<std::array<float, 2>> u_tl_parent = {"u_tl_parent", *this};
+ gl::Uniform<float> u_scale_parent = {"u_scale_parent", *this};
};
} // namespace mbgl
diff --git a/src/mbgl/shader/raster_vertex.cpp b/src/mbgl/shader/raster_vertex.cpp
new file mode 100644
index 0000000000..fc9b1f11c2
--- /dev/null
+++ b/src/mbgl/shader/raster_vertex.cpp
@@ -0,0 +1,7 @@
+#include <mbgl/shader/raster_vertex.hpp>
+
+namespace mbgl {
+
+static_assert(sizeof(RasterVertex) == 8, "expected RasterVertex size");
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/raster_vertex.hpp b/src/mbgl/shader/raster_vertex.hpp
new file mode 100644
index 0000000000..70e08c609d
--- /dev/null
+++ b/src/mbgl/shader/raster_vertex.hpp
@@ -0,0 +1,39 @@
+#pragma once
+
+#include <mbgl/gl/attribute.hpp>
+
+#include <array>
+#include <cstdint>
+
+namespace mbgl {
+
+class RasterVertex {
+public:
+ RasterVertex(int16_t x, int16_t y, uint16_t tx, uint16_t ty)
+ : a_pos {
+ x,
+ y
+ },
+ a_texture_pos {
+ tx,
+ ty
+ } {}
+
+ const int16_t a_pos[2];
+ const uint16_t a_texture_pos[2];
+};
+
+namespace gl {
+
+template <class Shader>
+struct AttributeBindings<Shader, RasterVertex> {
+ std::array<AttributeBinding, 2> operator()(const Shader& shader) {
+ return {{
+ MBGL_MAKE_ATTRIBUTE_BINDING(RasterVertex, shader, a_pos),
+ MBGL_MAKE_ATTRIBUTE_BINDING(RasterVertex, shader, a_texture_pos)
+ }};
+ };
+};
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/shader/sdf_shader.cpp b/src/mbgl/shader/sdf_shader.cpp
deleted file mode 100644
index 3b4aa69535..0000000000
--- a/src/mbgl/shader/sdf_shader.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-#include <mbgl/shader/sdf_shader.hpp>
-#include <mbgl/shader/sdf.vertex.hpp>
-#include <mbgl/shader/sdf.fragment.hpp>
-#include <mbgl/gl/gl.hpp>
-
-namespace mbgl {
-
-SDFShader::SDFShader(gl::Context& context, Defines defines)
- : Shader(shaders::sdf::name,
- shaders::sdf::vertex,
- shaders::sdf::fragment,
- context, defines) {
-}
-
-void SDFShader::bind(int8_t* offset) {
- const int stride = 16;
-
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_pos));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_SHORT, false, stride, offset + 0));
-
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_offset));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_offset, 2, GL_SHORT, false, stride, offset + 4));
-
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_texture_pos));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_texture_pos, 2, GL_UNSIGNED_SHORT, false, stride, offset + 8));
-
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(a_data));
- MBGL_CHECK_ERROR(glVertexAttribPointer(a_data, 4, GL_UNSIGNED_BYTE, false, stride, offset + 12));
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/sdf_shader.hpp b/src/mbgl/shader/sdf_shader.hpp
deleted file mode 100644
index f7fde3e539..0000000000
--- a/src/mbgl/shader/sdf_shader.hpp
+++ /dev/null
@@ -1,32 +0,0 @@
-#pragma once
-
-#include <mbgl/shader/shader.hpp>
-#include <mbgl/shader/uniform.hpp>
-#include <mbgl/util/color.hpp>
-
-namespace mbgl {
-
-class SDFShader : public Shader {
-public:
- SDFShader(gl::Context&, Defines defines = None);
-
- UniformMatrix<4> u_matrix = {"u_matrix", *this};
- Uniform<std::array<float, 2>> u_extrude_scale = {"u_extrude_scale", *this};
- Uniform<Color> u_color = {"u_color", *this};
- Uniform<float> u_opacity = {"u_opacity", *this};
- Uniform<std::array<float, 2>> u_texsize = {"u_texsize", *this};
- Uniform<float> u_buffer = {"u_buffer", *this};
- Uniform<float> u_gamma = {"u_gamma", *this};
- Uniform<float> u_zoom = {"u_zoom", *this};
- Uniform<float> u_pitch = {"u_pitch", *this};
- Uniform<float> u_bearing = {"u_bearing", *this};
- Uniform<float> u_aspect_ratio = {"u_aspect_ratio", *this};
- Uniform<int32_t> u_rotate_with_map = {"u_rotate_with_map", *this};
- Uniform<int32_t> u_pitch_with_map = {"u_pitch_with_map", *this};
- Uniform<int32_t> u_texture = {"u_texture", *this};
- Uniform<int32_t> u_fadetexture = {"u_fadetexture", *this};
-
- void bind(int8_t* offset) final;
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/shader.hpp b/src/mbgl/shader/shader.hpp
deleted file mode 100644
index 91dd8ed518..0000000000
--- a/src/mbgl/shader/shader.hpp
+++ /dev/null
@@ -1,53 +0,0 @@
-#pragma once
-
-#include <mbgl/gl/types.hpp>
-#include <mbgl/gl/object.hpp>
-#include <mbgl/util/noncopyable.hpp>
-#include <mbgl/util/optional.hpp>
-
-namespace mbgl {
-
-namespace gl {
-class Context;
-} // namespace gl
-
-class Shader : private util::noncopyable {
-public:
- ~Shader();
- const char* name;
-
- gl::ProgramID getID() const {
- return program.get();
- }
-
- gl::UniformLocation getUniformLocation(const char* uniform) const;
-
- virtual void bind(int8_t *offset) = 0;
-
- enum Defines : bool {
- None = false,
- Overdraw = true,
- };
-
-protected:
- Shader(const char* name_,
- const char* vertex,
- const char* fragment,
- gl::Context&,
- Defines defines = Defines::None);
-
- static constexpr gl::AttributeLocation a_pos = 0;
- static constexpr gl::AttributeLocation a_extrude = 1;
- static constexpr gl::AttributeLocation a_offset = 2;
- static constexpr gl::AttributeLocation a_data = 3;
- static constexpr gl::AttributeLocation a_texture_pos = 4;
-
-private:
- bool compileShader(gl::UniqueShader&, const char *source);
-
- gl::UniqueProgram program;
- gl::UniqueShader vertexShader;
- gl::UniqueShader fragmentShader;
-};
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/shaders.hpp b/src/mbgl/shader/shaders.hpp
index cf80a00d97..937ee85f44 100644
--- a/src/mbgl/shader/shaders.hpp
+++ b/src/mbgl/shader/shaders.hpp
@@ -1,56 +1,58 @@
#pragma once
-#include <mbgl/shader/pattern_shader.hpp>
-#include <mbgl/shader/plain_shader.hpp>
-#include <mbgl/shader/outline_shader.hpp>
-#include <mbgl/shader/outlinepattern_shader.hpp>
+#include <mbgl/shader/circle_shader.hpp>
+#include <mbgl/shader/fill_shader.hpp>
+#include <mbgl/shader/fill_pattern_shader.hpp>
+#include <mbgl/shader/fill_outline_shader.hpp>
+#include <mbgl/shader/fill_outline_pattern_shader.hpp>
#include <mbgl/shader/line_shader.hpp>
-#include <mbgl/shader/linesdf_shader.hpp>
-#include <mbgl/shader/linepattern_shader.hpp>
-#include <mbgl/shader/icon_shader.hpp>
+#include <mbgl/shader/line_sdf_shader.hpp>
+#include <mbgl/shader/line_pattern_shader.hpp>
#include <mbgl/shader/raster_shader.hpp>
-#include <mbgl/shader/sdf_shader.hpp>
+#include <mbgl/shader/symbol_icon_shader.hpp>
+#include <mbgl/shader/symbol_sdf_shader.hpp>
+
#include <mbgl/shader/collision_box_shader.hpp>
-#include <mbgl/shader/circle_shader.hpp>
namespace mbgl {
class Shaders {
public:
- Shaders(gl::Context& context, Shader::Defines defines = Shader::None)
- : plain(context, defines),
- outline(context, defines),
- outlinePattern(context, defines),
+ Shaders(gl::Context& context, gl::Shader::Defines defines = gl::Shader::None)
+ : circle(context, defines),
+ fill(context, defines),
+ fillPattern(context, defines),
+ fillOutline(context, defines),
+ fillOutlinePattern(context, defines),
line(context, defines),
- linesdf(context, defines),
- linepattern(context, defines),
- pattern(context, defines),
- icon(context, defines),
+ lineSDF(context, defines),
+ linePattern(context, defines),
raster(context, defines),
- sdfGlyph(context, defines),
- sdfIcon(context, defines),
- collisionBox(context),
- circle(context, defines) {
+ symbolIcon(context, defines),
+ symbolIconSDF(context, defines),
+ symbolGlyph(context, defines),
+ collisionBox(context) {
}
- PlainShader plain;
- OutlineShader outline;
- OutlinePatternShader outlinePattern;
+ CircleShader circle;
+ FillShader fill;
+ FillPatternShader fillPattern;
+ FillOutlineShader fillOutline;
+ FillOutlinePatternShader fillOutlinePattern;
LineShader line;
- LineSDFShader linesdf;
- LinepatternShader linepattern;
- PatternShader pattern;
- IconShader icon;
+ LineSDFShader lineSDF;
+ LinePatternShader linePattern;
RasterShader raster;
- SDFShader sdfGlyph;
- SDFShader sdfIcon;
+ SymbolIconShader symbolIcon;
+ SymbolSDFShader symbolIconSDF;
+ SymbolSDFShader symbolGlyph;
+
CollisionBoxShader collisionBox;
- CircleShader circle;
- VertexArrayObject coveringPlainArray;
- VertexArrayObject coveringRasterArray;
- VertexArrayObject backgroundPatternArray;
- VertexArrayObject backgroundArray;
+ gl::VertexArrayObject coveringPlainArray;
+ gl::VertexArrayObject coveringRasterArray;
+ gl::VertexArrayObject backgroundPatternArray;
+ gl::VertexArrayObject backgroundArray;
};
} // namespace mbgl
diff --git a/src/mbgl/shader/symbol_icon_shader.cpp b/src/mbgl/shader/symbol_icon_shader.cpp
new file mode 100644
index 0000000000..2655a1c9b5
--- /dev/null
+++ b/src/mbgl/shader/symbol_icon_shader.cpp
@@ -0,0 +1,15 @@
+#include <mbgl/shader/symbol_icon_shader.hpp>
+#include <mbgl/shader/symbol_icon.vertex.hpp>
+#include <mbgl/shader/symbol_icon.fragment.hpp>
+#include <mbgl/shader/symbol_vertex.hpp>
+
+namespace mbgl {
+
+SymbolIconShader::SymbolIconShader(gl::Context& context, Defines defines)
+ : Shader(shaders::symbol_icon::name,
+ shaders::symbol_icon::vertex,
+ shaders::symbol_icon::fragment,
+ context, defines) {
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/symbol_icon_shader.hpp b/src/mbgl/shader/symbol_icon_shader.hpp
new file mode 100644
index 0000000000..5281beb60c
--- /dev/null
+++ b/src/mbgl/shader/symbol_icon_shader.hpp
@@ -0,0 +1,32 @@
+#pragma once
+
+#include <mbgl/gl/shader.hpp>
+#include <mbgl/gl/attribute.hpp>
+#include <mbgl/gl/uniform.hpp>
+
+namespace mbgl {
+
+class SymbolVertex;
+
+class SymbolIconShader : public gl::Shader {
+public:
+ SymbolIconShader(gl::Context&, Defines defines = None);
+
+ using VertexType = SymbolVertex;
+
+ gl::Attribute<int16_t, 2> a_pos = { "a_pos", *this };
+ gl::Attribute<int16_t, 2> a_offset = { "a_offset", *this };
+ gl::Attribute<uint16_t, 2> a_texture_pos = { "a_texture_pos", *this };
+ gl::Attribute<uint8_t, 4> a_data = { "a_data", *this };
+
+ gl::UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ gl::Uniform<std::array<float, 2>> u_extrude_scale = {"u_extrude_scale", *this};
+ gl::Uniform<float> u_zoom = {"u_zoom", *this};
+ gl::Uniform<float> u_opacity = {"u_opacity", *this};
+ gl::Uniform<std::array<float, 2>> u_texsize = {"u_texsize", *this};
+ gl::Uniform<int32_t> u_rotate_with_map = {"u_rotate_with_map", *this};
+ gl::Uniform<int32_t> u_texture = {"u_texture", *this};
+ gl::Uniform<int32_t> u_fadetexture = {"u_fadetexture", *this};
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/symbol_sdf_shader.cpp b/src/mbgl/shader/symbol_sdf_shader.cpp
new file mode 100644
index 0000000000..63c3bd5a4a
--- /dev/null
+++ b/src/mbgl/shader/symbol_sdf_shader.cpp
@@ -0,0 +1,15 @@
+#include <mbgl/shader/symbol_sdf_shader.hpp>
+#include <mbgl/shader/symbol_sdf.vertex.hpp>
+#include <mbgl/shader/symbol_sdf.fragment.hpp>
+#include <mbgl/shader/symbol_vertex.hpp>
+
+namespace mbgl {
+
+SymbolSDFShader::SymbolSDFShader(gl::Context& context, Defines defines)
+ : Shader(shaders::symbol_sdf::name,
+ shaders::symbol_sdf::vertex,
+ shaders::symbol_sdf::fragment,
+ context, defines) {
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/symbol_sdf_shader.hpp b/src/mbgl/shader/symbol_sdf_shader.hpp
new file mode 100644
index 0000000000..8d3b3df939
--- /dev/null
+++ b/src/mbgl/shader/symbol_sdf_shader.hpp
@@ -0,0 +1,40 @@
+#pragma once
+
+#include <mbgl/gl/shader.hpp>
+#include <mbgl/gl/attribute.hpp>
+#include <mbgl/gl/uniform.hpp>
+#include <mbgl/util/color.hpp>
+
+namespace mbgl {
+
+class SymbolVertex;
+
+class SymbolSDFShader : public gl::Shader {
+public:
+ SymbolSDFShader(gl::Context&, Defines defines = None);
+
+ using VertexType = SymbolVertex;
+
+ gl::Attribute<int16_t, 2> a_pos = { "a_pos", *this };
+ gl::Attribute<int16_t, 2> a_offset = { "a_offset", *this };
+ gl::Attribute<uint16_t, 2> a_texture_pos = { "a_texture_pos", *this };
+ gl::Attribute<uint8_t, 4> a_data = { "a_data", *this };
+
+ gl::UniformMatrix<4> u_matrix = {"u_matrix", *this};
+ gl::Uniform<std::array<float, 2>> u_extrude_scale = {"u_extrude_scale", *this};
+ gl::Uniform<Color> u_color = {"u_color", *this};
+ gl::Uniform<float> u_opacity = {"u_opacity", *this};
+ gl::Uniform<std::array<float, 2>> u_texsize = {"u_texsize", *this};
+ gl::Uniform<float> u_buffer = {"u_buffer", *this};
+ gl::Uniform<float> u_gamma = {"u_gamma", *this};
+ gl::Uniform<float> u_zoom = {"u_zoom", *this};
+ gl::Uniform<float> u_pitch = {"u_pitch", *this};
+ gl::Uniform<float> u_bearing = {"u_bearing", *this};
+ gl::Uniform<float> u_aspect_ratio = {"u_aspect_ratio", *this};
+ gl::Uniform<int32_t> u_rotate_with_map = {"u_rotate_with_map", *this};
+ gl::Uniform<int32_t> u_pitch_with_map = {"u_pitch_with_map", *this};
+ gl::Uniform<int32_t> u_texture = {"u_texture", *this};
+ gl::Uniform<int32_t> u_fadetexture = {"u_fadetexture", *this};
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/symbol_vertex.cpp b/src/mbgl/shader/symbol_vertex.cpp
new file mode 100644
index 0000000000..4075d749ea
--- /dev/null
+++ b/src/mbgl/shader/symbol_vertex.cpp
@@ -0,0 +1,9 @@
+#include <mbgl/shader/symbol_vertex.hpp>
+#include <mbgl/gl/shader.hpp>
+#include <mbgl/gl/gl.hpp>
+
+namespace mbgl {
+
+static_assert(sizeof(SymbolVertex) == 16, "expected SymbolVertex size");
+
+} // namespace mbgl
diff --git a/src/mbgl/shader/symbol_vertex.hpp b/src/mbgl/shader/symbol_vertex.hpp
new file mode 100644
index 0000000000..4eba86f946
--- /dev/null
+++ b/src/mbgl/shader/symbol_vertex.hpp
@@ -0,0 +1,54 @@
+#pragma once
+
+#include <mbgl/gl/attribute.hpp>
+
+#include <array>
+#include <cstdint>
+#include <cmath>
+
+namespace mbgl {
+
+class SymbolVertex {
+public:
+ SymbolVertex(int16_t x, int16_t y, float ox, float oy, uint16_t tx, uint16_t ty, float minzoom, float maxzoom, float labelminzoom, uint8_t labelangle)
+ : a_pos {
+ x,
+ y
+ },
+ a_offset {
+ static_cast<int16_t>(::round(ox * 64)), // use 1/64 pixels for placement
+ static_cast<int16_t>(::round(oy * 64))
+ },
+ a_texture_pos {
+ static_cast<uint16_t>(tx / 4),
+ static_cast<uint16_t>(ty / 4)
+ },
+ a_data {
+ static_cast<uint8_t>(labelminzoom * 10), // 1/10 zoom levels: z16 == 160
+ static_cast<uint8_t>(labelangle),
+ static_cast<uint8_t>(minzoom * 10),
+ static_cast<uint8_t>(::fmin(maxzoom, 25) * 10)
+ } {}
+
+ const int16_t a_pos[2];
+ const int16_t a_offset[2];
+ const uint16_t a_texture_pos[2];
+ const uint8_t a_data[4];
+};
+
+namespace gl {
+
+template <class Shader>
+struct AttributeBindings<Shader, SymbolVertex> {
+ std::array<AttributeBinding, 4> operator()(const Shader& shader) {
+ return {{
+ MBGL_MAKE_ATTRIBUTE_BINDING(SymbolVertex, shader, a_pos),
+ MBGL_MAKE_ATTRIBUTE_BINDING(SymbolVertex, shader, a_offset),
+ MBGL_MAKE_ATTRIBUTE_BINDING(SymbolVertex, shader, a_texture_pos),
+ MBGL_MAKE_ATTRIBUTE_BINDING(SymbolVertex, shader, a_data)
+ }};
+ };
+};
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/style/layer_impl.hpp b/src/mbgl/style/layer_impl.hpp
index 55b1ff058c..4bf2956a6d 100644
--- a/src/mbgl/style/layer_impl.hpp
+++ b/src/mbgl/style/layer_impl.hpp
@@ -69,7 +69,7 @@ public:
virtual float getQueryRadius() const { return 0; }
virtual bool queryIntersectsGeometry(
- const GeometryCollection&,
+ const GeometryCoordinates&,
const GeometryCollection&,
const float,
const float) const { return false; };
diff --git a/src/mbgl/style/layers/circle_layer_impl.cpp b/src/mbgl/style/layers/circle_layer_impl.cpp
index e08d9df146..33699b6665 100644
--- a/src/mbgl/style/layers/circle_layer_impl.cpp
+++ b/src/mbgl/style/layers/circle_layer_impl.cpp
@@ -40,7 +40,7 @@ float CircleLayer::Impl::getQueryRadius() const {
}
bool CircleLayer::Impl::queryIntersectsGeometry(
- const GeometryCollection& queryGeometry,
+ const GeometryCoordinates& queryGeometry,
const GeometryCollection& geometry,
const float bearing,
const float pixelsToTileUnits) const {
@@ -50,7 +50,7 @@ bool CircleLayer::Impl::queryIntersectsGeometry(
auto circleRadius = paint.circleRadius * pixelsToTileUnits;
- return util::multiPolygonIntersectsBufferedMultiPoint(
+ return util::polygonIntersectsBufferedMultiPoint(
translatedQueryGeometry.value_or(queryGeometry), geometry, circleRadius);
}
diff --git a/src/mbgl/style/layers/circle_layer_impl.hpp b/src/mbgl/style/layers/circle_layer_impl.hpp
index 555691b6b4..14baaf84e4 100644
--- a/src/mbgl/style/layers/circle_layer_impl.hpp
+++ b/src/mbgl/style/layers/circle_layer_impl.hpp
@@ -19,7 +19,7 @@ public:
float getQueryRadius() const override;
bool queryIntersectsGeometry(
- const GeometryCollection& queryGeometry,
+ const GeometryCoordinates& queryGeometry,
const GeometryCollection& geometry,
const float bearing,
const float pixelsToTileUnits) const override;
diff --git a/src/mbgl/style/layers/fill_layer_impl.cpp b/src/mbgl/style/layers/fill_layer_impl.cpp
index 2992312514..fc439f1cd1 100644
--- a/src/mbgl/style/layers/fill_layer_impl.cpp
+++ b/src/mbgl/style/layers/fill_layer_impl.cpp
@@ -49,7 +49,7 @@ float FillLayer::Impl::getQueryRadius() const {
}
bool FillLayer::Impl::queryIntersectsGeometry(
- const GeometryCollection& queryGeometry,
+ const GeometryCoordinates& queryGeometry,
const GeometryCollection& geometry,
const float bearing,
const float pixelsToTileUnits) const {
@@ -57,7 +57,7 @@ bool FillLayer::Impl::queryIntersectsGeometry(
auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry(
queryGeometry, paint.fillTranslate, paint.fillTranslateAnchor, bearing, pixelsToTileUnits);
- return util::multiPolygonIntersectsMultiPolygon(translatedQueryGeometry.value_or(queryGeometry), geometry);
+ return util::polygonIntersectsMultiPolygon(translatedQueryGeometry.value_or(queryGeometry), geometry);
}
} // namespace style
diff --git a/src/mbgl/style/layers/fill_layer_impl.hpp b/src/mbgl/style/layers/fill_layer_impl.hpp
index fc6578ecd1..54cfb80c86 100644
--- a/src/mbgl/style/layers/fill_layer_impl.hpp
+++ b/src/mbgl/style/layers/fill_layer_impl.hpp
@@ -19,7 +19,7 @@ public:
float getQueryRadius() const override;
bool queryIntersectsGeometry(
- const GeometryCollection& queryGeometry,
+ const GeometryCoordinates& queryGeometry,
const GeometryCollection& geometry,
const float bearing,
const float pixelsToTileUnits) const override;
diff --git a/src/mbgl/style/layers/line_layer_impl.cpp b/src/mbgl/style/layers/line_layer_impl.cpp
index 3cdd90b7fd..c116af5fc2 100644
--- a/src/mbgl/style/layers/line_layer_impl.cpp
+++ b/src/mbgl/style/layers/line_layer_impl.cpp
@@ -87,7 +87,7 @@ float LineLayer::Impl::getQueryRadius() const {
}
bool LineLayer::Impl::queryIntersectsGeometry(
- const GeometryCollection& queryGeometry,
+ const GeometryCoordinates& queryGeometry,
const GeometryCollection& geometry,
const float bearing,
const float pixelsToTileUnits) const {
@@ -98,7 +98,7 @@ bool LineLayer::Impl::queryIntersectsGeometry(
queryGeometry, paint.lineTranslate, paint.lineTranslateAnchor, bearing, pixelsToTileUnits);
auto offsetGeometry = offsetLine(geometry, paint.lineOffset * pixelsToTileUnits);
- return util::multiPolygonIntersectsBufferedMultiLine(
+ return util::polygonIntersectsBufferedMultiLine(
translatedQueryGeometry.value_or(queryGeometry),
offsetGeometry.value_or(geometry),
halfWidth);
diff --git a/src/mbgl/style/layers/line_layer_impl.hpp b/src/mbgl/style/layers/line_layer_impl.hpp
index e130bc01bc..c6b4be3bec 100644
--- a/src/mbgl/style/layers/line_layer_impl.hpp
+++ b/src/mbgl/style/layers/line_layer_impl.hpp
@@ -19,7 +19,7 @@ public:
float getQueryRadius() const override;
bool queryIntersectsGeometry(
- const GeometryCollection& queryGeometry,
+ const GeometryCoordinates& queryGeometry,
const GeometryCollection& geometry,
const float bearing,
const float pixelsToTileUnits) const override;
diff --git a/src/mbgl/style/source_impl.cpp b/src/mbgl/style/source_impl.cpp
index 58ae3d9f91..1fb6d59f0e 100644
--- a/src/mbgl/style/source_impl.cpp
+++ b/src/mbgl/style/source_impl.cpp
@@ -176,26 +176,13 @@ void Source::Impl::reloadTiles() {
cache.clear();
for (auto& pair : tiles) {
- auto tile = pair.second.get();
- tile->redoLayout();
+ pair.second->redoLayout();
}
}
-static Point<int16_t> coordinateToTilePoint(const UnwrappedTileID& tileID, const Point<double>& p) {
- auto zoomedCoord = TileCoordinate { p, 0 }.zoomTo(tileID.canonical.z);
- return {
- int16_t(util::clamp<int64_t>((zoomedCoord.p.x - tileID.canonical.x - tileID.wrap * std::pow(2, tileID.canonical.z)) * util::EXTENT,
- std::numeric_limits<int16_t>::min(),
- std::numeric_limits<int16_t>::max())),
- int16_t(util::clamp<int64_t>((zoomedCoord.p.y - tileID.canonical.y) * util::EXTENT,
- std::numeric_limits<int16_t>::min(),
- std::numeric_limits<int16_t>::max()))
- };
-}
-
std::unordered_map<std::string, std::vector<Feature>> Source::Impl::queryRenderedFeatures(const QueryParameters& parameters) const {
std::unordered_map<std::string, std::vector<Feature>> result;
- if (renderTiles.empty()) {
+ if (renderTiles.empty() || parameters.geometry.empty()) {
return result;
}
@@ -206,31 +193,30 @@ std::unordered_map<std::string, std::vector<Feature>> Source::Impl::queryRendere
parameters.transformState, 0, { p.x, parameters.transformState.getHeight() - p.y }).p);
}
- if (queryGeometry.empty()) {
- return result;
- }
-
mapbox::geometry::box<double> box = mapbox::geometry::envelope(queryGeometry);
for (const auto& tilePtr : renderTiles) {
- const RenderTile& tile = tilePtr.second;
-
- Point<int16_t> tileSpaceBoundsMin = coordinateToTilePoint(tile.id, box.min);
- Point<int16_t> tileSpaceBoundsMax = coordinateToTilePoint(tile.id, box.max);
+ const RenderTile& renderTile = tilePtr.second;
+ GeometryCoordinate tileSpaceBoundsMin = TileCoordinate::toGeometryCoordinate(renderTile.id, box.min);
+ if (tileSpaceBoundsMin.x >= util::EXTENT || tileSpaceBoundsMin.y >= util::EXTENT) {
+ continue;
+ }
- if (tileSpaceBoundsMin.x >= util::EXTENT || tileSpaceBoundsMin.y >= util::EXTENT ||
- tileSpaceBoundsMax.x < 0 || tileSpaceBoundsMax.y < 0) continue;
+ GeometryCoordinate tileSpaceBoundsMax = TileCoordinate::toGeometryCoordinate(renderTile.id, box.max);
+ if (tileSpaceBoundsMax.x < 0 || tileSpaceBoundsMax.y < 0) {
+ continue;
+ }
GeometryCoordinates tileSpaceQueryGeometry;
-
+ tileSpaceQueryGeometry.reserve(queryGeometry.size());
for (const auto& c : queryGeometry) {
- tileSpaceQueryGeometry.push_back(coordinateToTilePoint(tile.id, c));
+ tileSpaceQueryGeometry.push_back(TileCoordinate::toGeometryCoordinate(renderTile.id, c));
}
- tile.tile.queryRenderedFeatures(result,
- tileSpaceQueryGeometry,
- parameters.transformState,
- parameters.layerIDs);
+ renderTile.tile.queryRenderedFeatures(result,
+ tileSpaceQueryGeometry,
+ parameters.transformState,
+ parameters.layerIDs);
}
return result;
@@ -261,8 +247,7 @@ void Source::Impl::dumpDebugLogs() const {
Log::Info(Event::General, "Source::loaded: %d", loaded);
for (const auto& pair : tiles) {
- auto& tile = pair.second;
- tile->dumpDebugLogs();
+ pair.second->dumpDebugLogs();
}
}
diff --git a/src/mbgl/text/collision_tile.cpp b/src/mbgl/text/collision_tile.cpp
index 32a1a5474a..d6fc1a6ada 100644
--- a/src/mbgl/text/collision_tile.cpp
+++ b/src/mbgl/text/collision_tile.cpp
@@ -2,6 +2,10 @@
#include <mbgl/geometry/feature_index.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/math.hpp>
+#include <mbgl/math/minmax.hpp>
+
+#include <mapbox/geometry/envelope.hpp>
+#include <mapbox/geometry/multi_point.hpp>
#include <cmath>
@@ -20,7 +24,6 @@ CollisionTile::CollisionTile(PlacementConfig config_) : config(std::move(config_
// bottom
CollisionBox(Point<float>(0, util::EXTENT), -infinity, 0, infinity, 0, infinity),
}}) {
- tree.clear();
// Compute the transformation matrix.
const float angle_sin = std::sin(config.angle);
@@ -51,7 +54,7 @@ float CollisionTile::findPlacementScale(float minPlacementScale, const Point<flo
if (std::isnan(s1) || std::isnan(s2)) s1 = s2 = 1;
if (std::isnan(s3) || std::isnan(s4)) s3 = s4 = 1;
- float collisionFreeScale = ::fmin(::fmax(s1, s2), ::fmax(s3, s4));
+ float collisionFreeScale = util::min(util::max(s1, s2), util::max(s3, s4));
if (collisionFreeScale > blocking.maxScale) {
// After a box's maxScale the label has shrunk enough that the box is no longer needed to cover it,
@@ -104,10 +107,10 @@ float CollisionTile::placeFeature(const CollisionFeature& feature, const bool al
const Point<float> rbl = util::matrixMultiply(reverseRotationMatrix, bl);
const Point<float> rbr = util::matrixMultiply(reverseRotationMatrix, br);
CollisionBox rotatedBox(box.anchor,
- ::fmin(::fmin(rtl.x, rtr.x), ::fmin(rbl.x, rbr.x)),
- ::fmin(::fmin(rtl.y, rtr.y), ::fmin(rbl.y, rbr.y)),
- ::fmax(::fmax(rtl.x, rtr.x), ::fmax(rbl.x, rbr.x)),
- ::fmax(::fmax(rtl.y, rtr.y), ::fmax(rbl.y, rbr.y)),
+ util::min(rtl.x, rtr.x, rbl.x, rbr.x),
+ util::min(rtl.y, rtr.y, rbl.y, rbr.y),
+ util::max(rtl.x, rtr.x, rbl.x, rbr.x),
+ util::max(rtl.y, rtr.y, rbl.y, rbr.y),
box.maxScale);
for (auto& blocking : edges) {
@@ -153,34 +156,49 @@ Box CollisionTile::getTreeBox(const Point<float>& anchor, const CollisionBox& bo
};
}
-std::vector<IndexedSubfeature> CollisionTile::queryRenderedSymbols(const mapbox::geometry::box<int16_t>& box, const float scale) {
+std::vector<IndexedSubfeature> CollisionTile::queryRenderedSymbols(const GeometryCoordinates& queryGeometry, const float scale) {
std::vector<IndexedSubfeature> result;
+ if (queryGeometry.empty()) return result;
+
std::unordered_map<std::string, std::unordered_set<std::size_t>> sourceLayerFeatures;
- auto anchor = util::matrixMultiply(rotationMatrix, convertPoint<float>(box.min));
+ mapbox::geometry::multi_point<float> rotatedPoints {};
+ rotatedPoints.reserve(queryGeometry.size());
+ std::transform(queryGeometry.cbegin(), queryGeometry.cend(), std::back_inserter(rotatedPoints),
+ [&](const auto& c) { return util::matrixMultiply(rotationMatrix, convertPoint<float>(c)); });
+ const auto box = mapbox::geometry::envelope(rotatedPoints);
+
+ const auto& anchor = box.min;
CollisionBox queryBox(anchor, 0, 0, box.max.x - box.min.x, box.max.y - box.min.y, scale);
auto predicates = bgi::intersects(getTreeBox(anchor, queryBox));
- auto fn = [&] (const Tree& tree_) {
+ auto fn = [&] (const Tree& tree_, bool ignorePlacement) {
for (auto it = tree_.qbegin(predicates); it != tree_.qend(); ++it) {
const CollisionBox& blocking = std::get<1>(*it);
const IndexedSubfeature& indexedFeature = std::get<2>(*it);
auto& seenFeatures = sourceLayerFeatures[indexedFeature.sourceLayerName];
if (seenFeatures.find(indexedFeature.index) == seenFeatures.end()) {
- auto blockingAnchor = util::matrixMultiply(rotationMatrix, blocking.anchor);
- float minPlacementScale = findPlacementScale(minScale, anchor, queryBox, blockingAnchor, blocking);
- if (minPlacementScale >= scale) {
+ if (ignorePlacement) {
seenFeatures.insert(indexedFeature.index);
result.push_back(indexedFeature);
+ } else {
+ auto blockingAnchor = util::matrixMultiply(rotationMatrix, blocking.anchor);
+ float minPlacementScale = findPlacementScale(minScale, anchor, queryBox, blockingAnchor, blocking);
+ if (minPlacementScale >= scale) {
+ seenFeatures.insert(indexedFeature.index);
+ result.push_back(indexedFeature);
+ }
}
}
}
};
- fn(tree);
- fn(ignoredTree);
+ bool ignorePlacement = false;
+ fn(tree, ignorePlacement);
+ ignorePlacement = true;
+ fn(ignoredTree, ignorePlacement);
return result;
}
diff --git a/src/mbgl/text/collision_tile.hpp b/src/mbgl/text/collision_tile.hpp
index 7450fb1b86..dbc23b2a79 100644
--- a/src/mbgl/text/collision_tile.hpp
+++ b/src/mbgl/text/collision_tile.hpp
@@ -2,6 +2,7 @@
#include <mbgl/text/collision_feature.hpp>
#include <mbgl/text/placement_config.hpp>
+#include <mbgl/tile/geometry_tile_data.hpp>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
@@ -41,7 +42,7 @@ public:
float placeFeature(const CollisionFeature&, const bool allowOverlap, const bool avoidEdges);
void insertFeature(CollisionFeature&, const float minPlacementScale, const bool ignorePlacement);
- std::vector<IndexedSubfeature> queryRenderedSymbols(const mapbox::geometry::box<int16_t>&, const float scale);
+ std::vector<IndexedSubfeature> queryRenderedSymbols(const GeometryCoordinates&, const float scale);
const PlacementConfig config;
@@ -49,6 +50,10 @@ public:
const float maxScale = 2.0f;
float yStretch;
+ std::array<float, 4> rotationMatrix;
+ std::array<float, 4> reverseRotationMatrix;
+ std::array<CollisionBox, 4> edges;
+
private:
float findPlacementScale(float minPlacementScale,
const Point<float>& anchor, const CollisionBox& box,
@@ -57,9 +62,6 @@ private:
Tree tree;
Tree ignoredTree;
- std::array<float, 4> rotationMatrix;
- std::array<float, 4> reverseRotationMatrix;
- std::array<CollisionBox, 4> edges;
};
} // namespace mbgl
diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp
index 1f64b6b6c6..46e2b414fe 100644
--- a/src/mbgl/tile/geometry_tile.cpp
+++ b/src/mbgl/tile/geometry_tile.cpp
@@ -136,7 +136,7 @@ void GeometryTile::queryRenderedFeatures(
if (!featureIndex || !data) return;
featureIndex->query(result,
- { queryGeometry },
+ queryGeometry,
transformState.getAngle(),
util::tileSize * id.overscaleFactor(),
std::pow(2, transformState.getZoom() - id.overscaledZ),
diff --git a/src/mbgl/tile/tile.cpp b/src/mbgl/tile/tile.cpp
index ec0540b1ad..1375263107 100644
--- a/src/mbgl/tile/tile.cpp
+++ b/src/mbgl/tile/tile.cpp
@@ -2,6 +2,7 @@
#include <mbgl/tile/tile_observer.hpp>
#include <mbgl/renderer/debug_bucket.hpp>
#include <mbgl/util/string.hpp>
+#include <mbgl/platform/log.hpp>
namespace mbgl {
diff --git a/src/mbgl/tile/tile.hpp b/src/mbgl/tile/tile.hpp
index be03608994..949bc0e334 100644
--- a/src/mbgl/tile/tile.hpp
+++ b/src/mbgl/tile/tile.hpp
@@ -4,6 +4,7 @@
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/optional.hpp>
#include <mbgl/util/feature.hpp>
+#include <mbgl/util/tile_coordinate.hpp>
#include <mbgl/tile/tile_id.hpp>
#include <mbgl/renderer/bucket.hpp>
#include <mbgl/tile/geometry_tile_data.hpp>
diff --git a/src/mbgl/util/intersection_tests.cpp b/src/mbgl/util/intersection_tests.cpp
index 74b3bec388..a0feb8ec37 100644
--- a/src/mbgl/util/intersection_tests.cpp
+++ b/src/mbgl/util/intersection_tests.cpp
@@ -90,54 +90,47 @@ bool lineIntersectsBufferedLine(const GeometryCoordinates& lineA, const Geometry
return false;
}
-bool multiPolygonIntersectsBufferedMultiPoint(const GeometryCollection& multiPolygon, const GeometryCollection& rings, float radius) {
- for (auto& polygon : multiPolygon) {
- for (auto& ring : rings) {
- for (auto& point : ring) {
- if (polygonContainsPoint(polygon, point)) return true;
- if (pointIntersectsBufferedLine(point, polygon, radius)) return true;
- }
+bool polygonIntersectsBufferedMultiPoint(const GeometryCoordinates& polygon, const GeometryCollection& rings, float radius) {
+ for (auto& ring : rings) {
+ for (auto& point : ring) {
+ if (polygonContainsPoint(polygon, point)) return true;
+ if (pointIntersectsBufferedLine(point, polygon, radius)) return true;
}
}
return false;
}
-bool multiPolygonIntersectsBufferedMultiLine(const GeometryCollection& multiPolygon, const GeometryCollection& multiLine, float radius) {
+bool polygonIntersectsBufferedMultiLine(const GeometryCoordinates& polygon, const GeometryCollection& multiLine, float radius) {
for (auto& line : multiLine) {
- for (auto& polygon : multiPolygon) {
-
- if (polygon.size() >= 3) {
- for (auto& p : line) {
- if (polygonContainsPoint(polygon, p)) return true;
- }
+ if (polygon.size() >= 3) {
+ for (auto& p : line) {
+ if (polygonContainsPoint(polygon, p)) return true;
}
-
- if (lineIntersectsBufferedLine(polygon, line, radius)) return true;
}
+
+ if (lineIntersectsBufferedLine(polygon, line, radius)) return true;
}
return false;
}
-bool multiPolygonIntersectsMultiPolygon(const GeometryCollection& multiPolygonA, const GeometryCollection& multiPolygonB) {
- if (multiPolygonA.size() == 1 && multiPolygonA.at(0).size() == 1) {
- return multiPolygonContainsPoint(multiPolygonB, multiPolygonA.at(0).at(0));
+bool polygonIntersectsMultiPolygon(const GeometryCoordinates& polygon, const GeometryCollection& multiPolygon) {
+ if (polygon.size() == 1) {
+ return multiPolygonContainsPoint(multiPolygon, polygon.at(0));
}
- for (auto& ring : multiPolygonB) {
+ for (auto& ring : multiPolygon) {
for (auto& p : ring) {
- if (multiPolygonContainsPoint(multiPolygonA, p)) return true;
+ if (polygonContainsPoint(polygon, p)) return true;
}
}
- for (auto& polygon : multiPolygonA) {
- for (auto& p : polygon) {
- if (multiPolygonContainsPoint(multiPolygonB, p)) return true;
- }
+ for (auto& p : polygon) {
+ if (multiPolygonContainsPoint(multiPolygon, p)) return true;
+ }
- for (auto& polygonB : multiPolygonB) {
- if (lineIntersectsLine(polygon, polygonB)) return true;
- }
+ for (auto& polygonB : multiPolygon) {
+ if (lineIntersectsLine(polygon, polygonB)) return true;
}
return false;
diff --git a/src/mbgl/util/intersection_tests.hpp b/src/mbgl/util/intersection_tests.hpp
index be89d14ed6..6adb3b5fdf 100644
--- a/src/mbgl/util/intersection_tests.hpp
+++ b/src/mbgl/util/intersection_tests.hpp
@@ -5,9 +5,9 @@
namespace mbgl {
namespace util {
-bool multiPolygonIntersectsBufferedMultiPoint(const GeometryCollection&, const GeometryCollection&, float radius);
-bool multiPolygonIntersectsBufferedMultiLine(const GeometryCollection&, const GeometryCollection&, float radius);
-bool multiPolygonIntersectsMultiPolygon(const GeometryCollection&, const GeometryCollection&);
+bool polygonIntersectsBufferedMultiPoint(const GeometryCoordinates&, const GeometryCollection&, float radius);
+bool polygonIntersectsBufferedMultiLine(const GeometryCoordinates&, const GeometryCollection&, float radius);
+bool polygonIntersectsMultiPolygon(const GeometryCoordinates&, const GeometryCollection&);
} // namespace util
} // namespace mbgl
diff --git a/src/mbgl/util/tile_coordinate.hpp b/src/mbgl/util/tile_coordinate.hpp
index df240a50e0..194a62ecef 100644
--- a/src/mbgl/util/tile_coordinate.hpp
+++ b/src/mbgl/util/tile_coordinate.hpp
@@ -1,15 +1,20 @@
#pragma once
-#include <mbgl/util/geometry.hpp>
#include <mbgl/map/transform_state.hpp>
+#include <mbgl/math/clamp.hpp>
+#include <mbgl/tile/geometry_tile_data.hpp>
+#include <mbgl/tile/tile_id.hpp>
+#include <mbgl/util/geometry.hpp>
namespace mbgl {
+using TileCoordinatePoint = Point<double>;
+
// Has floating point x/y coordinates.
// Used for computing the tiles that need to be visible in the viewport.
class TileCoordinate {
public:
- Point<double> p;
+ TileCoordinatePoint p;
double z;
static TileCoordinate fromLatLng(const TransformState& state, double zoom, const LatLng& latLng) {
@@ -17,13 +22,25 @@ public:
return { state.project(latLng) * scale / double(util::tileSize), zoom };
}
- static TileCoordinate fromScreenCoordinate(const TransformState& state, double zoom, const ScreenCoordinate& point) {
- return fromLatLng(state, zoom, state.screenCoordinateToLatLng(point));
+ static TileCoordinate fromScreenCoordinate(const TransformState& state, double zoom, const ScreenCoordinate& screenCoordinate) {
+ return fromLatLng(state, zoom, state.screenCoordinateToLatLng(screenCoordinate));
}
TileCoordinate zoomTo(double zoom) const {
return { p * std::pow(2, zoom - z), zoom };
}
+
+ static GeometryCoordinate toGeometryCoordinate(const UnwrappedTileID& tileID, const TileCoordinatePoint& point) {
+ auto zoomed = TileCoordinate { point, 0 }.zoomTo(tileID.canonical.z);
+ return {
+ int16_t(util::clamp<int64_t>((zoomed.p.x - tileID.canonical.x - tileID.wrap * std::pow(2.0, tileID.canonical.z)) * util::EXTENT,
+ std::numeric_limits<int16_t>::min(),
+ std::numeric_limits<int16_t>::max())),
+ int16_t(util::clamp<int64_t>((zoomed.p.y - tileID.canonical.y) * util::EXTENT,
+ std::numeric_limits<int16_t>::min(),
+ std::numeric_limits<int16_t>::max()))
+ };
+ }
};
} // namespace mbgl
diff --git a/test/api/annotations.test.cpp b/test/api/annotations.test.cpp
index 5b9fe7502e..dc4b00170a 100644
--- a/test/api/annotations.test.cpp
+++ b/test/api/annotations.test.cpp
@@ -43,9 +43,19 @@ TEST(Annotations, SymbolAnnotation) {
test.map.addAnnotation(SymbolAnnotation { Point<double>(0, 0), "default_marker" });
test.checkRendering("point_annotation");
+ auto size = test.view.getSize();
+ auto screenBox = ScreenBox { {}, { double(size[0]), double(size[1]) } };
+ auto features = test.map.queryPointAnnotations(screenBox);
+ EXPECT_EQ(features.size(), 1u);
+
+ test.map.setZoom(test.map.getMaxZoom());
// FIXME: https://github.com/mapbox/mapbox-gl-native/issues/5419
//test.map.setZoom(test.map.getMaxZoom());
//test.checkRendering("point_annotation");
+ test::render(test.map);
+
+ features = test.map.queryPointAnnotations(screenBox);
+ EXPECT_EQ(features.size(), 1u);
}
TEST(Annotations, LineAnnotation) {
@@ -341,3 +351,60 @@ TEST(Annotations, QueryRenderedFeatures) {
EXPECT_TRUE(!!features2[0].id);
EXPECT_EQ(*features2[0].id, 1);
}
+
+TEST(Annotations, QueryFractionalZoomLevels) {
+ AnnotationTest test;
+
+ auto viewSize = test.view.getSize();
+ auto box = ScreenBox { {}, { double(viewSize[0]), double(viewSize[1]) } };
+
+ test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.addAnnotationIcon("default_marker", namedMarker("default_marker.png"));
+
+ std::vector<mbgl::AnnotationID> ids;
+ for (int longitude = 0; longitude < 10; ++longitude) {
+ for (int latitude = 0; latitude < 10; ++latitude) {
+ ids.push_back(test.map.addAnnotation(SymbolAnnotation { { double(latitude), double(longitude) }, "default_marker" }));
+ }
+ }
+
+ test.map.setLatLngZoom({ 5, 5 }, 0);
+ for (uint16_t zoomSteps = 0; zoomSteps <= 20; ++zoomSteps) {
+ test.map.setZoom(zoomSteps / 10.0);
+ test::render(test.map);
+ auto features = test.map.queryRenderedFeatures(box);
+ EXPECT_EQ(features.size(), ids.size());
+ }
+}
+
+TEST(Annotations, VisibleFeatures) {
+ AnnotationTest test;
+
+ auto viewSize = test.view.getSize();
+ auto box = ScreenBox { {}, { double(viewSize[0]), double(viewSize[1]) } };
+
+ test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.addAnnotationIcon("default_marker", namedMarker("default_marker.png"));
+ test.map.setZoom(3);
+
+ std::vector<mbgl::AnnotationID> ids;
+ for (int longitude = -5; longitude <= 5; ++longitude) {
+ for (int latitude = -5; latitude <= 5; ++latitude) {
+ ids.push_back(test.map.addAnnotation(SymbolAnnotation { { double(latitude), double(longitude) }, "default_marker" }));
+ }
+ }
+
+ // Change bearing *after* adding annotations cause them to be reordered,
+ // and some annotations become occluded by others.
+ test.map.setBearing(45);
+ test::render(test.map);
+
+ auto features = test.map.queryRenderedFeatures(box);
+ EXPECT_EQ(features.size(), ids.size());
+
+ test.map.setBearing(0);
+ test.map.setZoom(4);
+ test::render(test.map);
+ features = test.map.queryRenderedFeatures(box);
+ EXPECT_EQ(features.size(), ids.size());
+}
diff --git a/test/gl/object.test.cpp b/test/gl/object.test.cpp
index 0502bbc847..1a90cec83b 100644
--- a/test/gl/object.test.cpp
+++ b/test/gl/object.test.cpp
@@ -87,13 +87,6 @@ TEST(GLObject, Store) {
context.performCleanup();
EXPECT_TRUE(context.empty());
- mbgl::gl::UniqueBuffer buffer = context.createBuffer();
- EXPECT_NE(buffer.get(), 0u);
- buffer.reset();
- EXPECT_FALSE(context.empty());
- context.performCleanup();
- EXPECT_TRUE(context.empty());
-
mbgl::gl::UniqueTexture texture = context.createTexture();
EXPECT_NE(texture.get(), 0u);
texture.reset();
diff --git a/test/map/map.test.cpp b/test/map/map.test.cpp
index 12d4ff2bcd..5b66d9b753 100644
--- a/test/map/map.test.cpp
+++ b/test/map/map.test.cpp
@@ -26,6 +26,22 @@ struct MapTest {
StubFileSource fileSource;
};
+TEST(Map, LatLngBehavior) {
+ MapTest test;
+ Map map(test.view, test.fileSource, MapMode::Still);
+
+ map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
+
+ map.setLatLngZoom({ 1, 1 }, 0);
+ auto latLng1 = map.getLatLng();
+
+ map.setLatLng({ 1, 1 });
+ auto latLng2 = map.getLatLng();
+
+ ASSERT_DOUBLE_EQ(latLng1.latitude, latLng2.latitude);
+ ASSERT_DOUBLE_EQ(latLng1.longitude, latLng2.longitude);
+}
+
TEST(Map, Offline) {
MapTest test;
DefaultFileSource fileSource(":memory:", ".");
diff --git a/test/storage/offline_database.test.cpp b/test/storage/offline_database.test.cpp
index bcc9784b35..2e25835d80 100644
--- a/test/storage/offline_database.test.cpp
+++ b/test/storage/offline_database.test.cpp
@@ -496,6 +496,59 @@ TEST(OfflineDatabase, GetRegionCompletedStatus) {
EXPECT_EQ(tileSize, status3.completedTileSize);
}
+TEST(OfflineDatabase, HasRegionResource) {
+ using namespace mbgl;
+
+ OfflineDatabase db(":memory:", 1024 * 100);
+ OfflineRegionDefinition definition { "", LatLngBounds::world(), 0, INFINITY, 1.0 };
+ OfflineRegion region = db.createRegion(definition, OfflineRegionMetadata());
+
+ EXPECT_FALSE(bool(db.hasRegionResource(region.getID(), Resource::style("http://example.com/1"))));
+ EXPECT_FALSE(bool(db.hasRegionResource(region.getID(), Resource::style("http://example.com/20"))));
+
+ Response response;
+ response.data = randomString(1024);
+
+ for (uint32_t i = 1; i <= 100; i++) {
+ db.putRegionResource(region.getID(), Resource::style("http://example.com/"s + util::toString(i)), response);
+ }
+
+ EXPECT_TRUE(bool(db.hasRegionResource(region.getID(), Resource::style("http://example.com/1"))));
+ EXPECT_TRUE(bool(db.hasRegionResource(region.getID(), Resource::style("http://example.com/20"))));
+ EXPECT_EQ(1024, *(db.hasRegionResource(region.getID(), Resource::style("http://example.com/20"))));
+}
+
+TEST(OfflineDatabase, HasRegionResourceTile) {
+ using namespace mbgl;
+
+ OfflineDatabase db(":memory:", 1024 * 100);
+ OfflineRegionDefinition definition { "", LatLngBounds::world(), 0, INFINITY, 1.0 };
+ OfflineRegion region = db.createRegion(definition, OfflineRegionMetadata());
+
+ Resource resource { Resource::Tile, "http://example.com/" };
+ resource.tileData = Resource::TileData {
+ "http://example.com/",
+ 1,
+ 0,
+ 0,
+ 0
+ };
+ Response response;
+
+ response.data = std::make_shared<std::string>("first");
+
+ EXPECT_FALSE(bool(db.hasRegionResource(region.getID(), resource)));
+ db.putRegionResource(region.getID(), resource, response);
+ EXPECT_TRUE(bool(db.hasRegionResource(region.getID(), resource)));
+ EXPECT_EQ(5, *(db.hasRegionResource(region.getID(), resource)));
+
+ OfflineRegion anotherRegion = db.createRegion(definition, OfflineRegionMetadata());
+ EXPECT_LT(region.getID(), anotherRegion.getID());
+ EXPECT_TRUE(bool(db.hasRegionResource(anotherRegion.getID(), resource)));
+ EXPECT_EQ(5, *(db.hasRegionResource(anotherRegion.getID(), resource)));
+
+}
+
TEST(OfflineDatabase, OfflineMapboxTileCount) {
using namespace mbgl;
diff --git a/test/tile/raster_tile.test.cpp b/test/tile/raster_tile.test.cpp
index a5a7e65b35..4e9e907321 100644
--- a/test/tile/raster_tile.test.cpp
+++ b/test/tile/raster_tile.test.cpp
@@ -4,6 +4,7 @@
#include <mbgl/tile/tile_loader_impl.hpp>
#include <mbgl/actor/thread_pool.hpp>
+#include <mbgl/util/run_loop.hpp>
#include <mbgl/map/transform.hpp>
#include <mbgl/style/style.hpp>
#include <mbgl/style/update_parameters.hpp>
@@ -15,6 +16,7 @@ class RasterTileTest {
public:
FakeFileSource fileSource;
TransformState transformState;
+ util::RunLoop loop;
ThreadPool threadPool { 1 };
AnnotationManager annotationManager { 1.0 };
style::Style style { fileSource, 1.0 };
diff --git a/test/tile/tile_coordinate.test.cpp b/test/tile/tile_coordinate.test.cpp
new file mode 100644
index 0000000000..f2337c1e7f
--- /dev/null
+++ b/test/tile/tile_coordinate.test.cpp
@@ -0,0 +1,92 @@
+#include <mbgl/test/util.hpp>
+
+#include <mbgl/map/change.hpp>
+#include <mbgl/map/transform.hpp>
+#include <mbgl/map/transform_state.hpp>
+#include <mbgl/tile/tile.hpp>
+#include <mbgl/tile/tile_id.hpp>
+#include <mbgl/util/constants.hpp>
+#include <mbgl/util/geometry.hpp>
+#include <mbgl/util/tile_coordinate.hpp>
+
+
+using namespace mbgl;
+
+TEST(TileCoordinate, FromLatLng) {
+ size_t changeCount = 0;
+ std::vector<MapChange> changes = {
+ MapChangeRegionWillChange,
+ MapChangeRegionDidChange,
+ };
+ auto onMapChange = [&](MapChange change) {
+ ASSERT_EQ(change, changes[changeCount]);
+ ++changeCount;
+ };
+
+ Transform transform(onMapChange);
+
+ const double max = util::tileSize;
+ const std::array<uint16_t, 2> size { { uint16_t(max), uint16_t(max) } };
+ transform.resize(size);
+
+ // Center, top-left, bottom-left, bottom-right, top-right edges.
+ std::vector<std::pair<LatLng, ScreenCoordinate>> edges {
+ { {}, { max / 2.0, max / 2.0 } },
+ { { util::LATITUDE_MAX, -util::LONGITUDE_MAX }, { 0, max } },
+ { { -util::LATITUDE_MAX, -util::LONGITUDE_MAX }, { 0, 0 } },
+ { { -util::LATITUDE_MAX, util::LONGITUDE_MAX }, { max, 0 } },
+ { { util::LATITUDE_MAX, util::LONGITUDE_MAX }, { max, max } },
+ };
+
+ for (const auto& pair : edges) {
+ const auto& latLng = pair.first;
+ const auto& screenCoordinate = pair.second;
+ const auto base = TileCoordinate::fromLatLng(transform.getState(), 0, latLng);
+
+ // 16 is the maximum zoom level where we actually compute placements.
+ for (uint8_t integerZoom = 0; integerZoom <= 16; ++integerZoom) {
+ const double zoom = integerZoom;
+ const double maxTilesPerAxis = std::pow(2.0, zoom);
+ const Point<double> tilePoint = {
+ latLng.longitude == 0 ? 0.5 : latLng.longitude == -util::LONGITUDE_MAX ? 0 : 1.0,
+ latLng.latitude == 0 ? 0.5 : latLng.latitude == -util::LATITUDE_MAX ? 1.0 : 0,
+ };
+
+ const auto fromLatLng = TileCoordinate::fromLatLng(transform.getState(), zoom, latLng);
+ ASSERT_DOUBLE_EQ(fromLatLng.z, zoom);
+ ASSERT_DOUBLE_EQ(fromLatLng.p.x, tilePoint.x * maxTilesPerAxis);
+ ASSERT_NEAR(fromLatLng.p.y, tilePoint.y * maxTilesPerAxis, 1.0e-7);
+
+ const auto fromScreenCoordinate = TileCoordinate::fromScreenCoordinate(transform.getState(), zoom, screenCoordinate);
+ ASSERT_DOUBLE_EQ(fromScreenCoordinate.z, fromLatLng.z);
+ ASSERT_NEAR(fromScreenCoordinate.p.x, fromLatLng.p.x, 0.99);
+ ASSERT_NEAR(fromScreenCoordinate.p.y, fromLatLng.p.y, 0.99);
+
+ const auto zoomed = base.zoomTo(zoom);
+ ASSERT_DOUBLE_EQ(zoomed.z, zoom);
+ ASSERT_DOUBLE_EQ(zoomed.p.x, fromLatLng.p.x);
+ ASSERT_DOUBLE_EQ(zoomed.p.y, fromLatLng.p.y);
+ }
+ }
+}
+
+TEST(TileCoordinate, ToGeometryCoordinate) {
+ std::vector<Point<double>> edges {
+ { 0.5, 0.5 }, { 0, 0 }, { 1, 0 }, { 1, 1 }, { 0, 1 }
+ };
+
+ for (uint8_t zoom = 0; zoom <= 16; ++zoom) {
+ uint32_t maxTilesPerAxis = std::pow(2, zoom);
+ for (const auto& edge : edges) {
+ uint32_t tileX = edge.x == 0 ? 0 : edge.x == 1 ? maxTilesPerAxis - 1 : (maxTilesPerAxis / 2.0) - 1;
+ uint32_t tileY = edge.y == 0 ? 0 : edge.y == 1 ? maxTilesPerAxis - 1 : (maxTilesPerAxis / 2.0) - 1;
+ UnwrappedTileID unwrapped(0, CanonicalTileID { zoom, tileX, tileY });
+
+ auto tilePointX = ((edge.x * maxTilesPerAxis) - tileX) * util::EXTENT;
+ auto tilePointY = ((edge.y * maxTilesPerAxis) - tileY) * util::EXTENT;
+ GeometryCoordinate point = TileCoordinate::toGeometryCoordinate(unwrapped, edge);
+ ASSERT_DOUBLE_EQ(point.x, tilePointX);
+ ASSERT_DOUBLE_EQ(point.y, tilePointY);
+ }
+ }
+}
diff --git a/test/tile/vector_tile.test.cpp b/test/tile/vector_tile.test.cpp
index e22b88a61d..fa75e24480 100644
--- a/test/tile/vector_tile.test.cpp
+++ b/test/tile/vector_tile.test.cpp
@@ -4,6 +4,7 @@
#include <mbgl/tile/tile_loader_impl.hpp>
#include <mbgl/actor/thread_pool.hpp>
+#include <mbgl/util/run_loop.hpp>
#include <mbgl/map/transform.hpp>
#include <mbgl/style/style.hpp>
#include <mbgl/style/update_parameters.hpp>
@@ -15,6 +16,7 @@ class VectorTileTest {
public:
FakeFileSource fileSource;
TransformState transformState;
+ util::RunLoop loop;
ThreadPool threadPool { 1 };
AnnotationManager annotationManager { 1.0 };
style::Style style { fileSource, 1.0 };