summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
m---------.mason0
-rw-r--r--.travis.yml161
-rw-r--r--CMakeLists.txt28
-rw-r--r--INSTALL.md2
-rw-r--r--Makefile122
-rw-r--r--benchmark/api/query.benchmark.cpp10
-rw-r--r--benchmark/src/mbgl/benchmark/util.cpp4
-rw-r--r--bin/render.cpp26
-rw-r--r--cloudformation/travis.template92
-rw-r--r--cmake/benchmark.cmake6
-rw-r--r--cmake/core-files.cmake123
-rw-r--r--cmake/glfw.cmake13
-rw-r--r--cmake/loop-darwin.cmake2
-rw-r--r--cmake/mbgl.cmake5
-rw-r--r--cmake/node.cmake5
-rw-r--r--cmake/offline.cmake6
-rw-r--r--cmake/render.cmake1
-rw-r--r--cmake/shaders.cmake12
-rw-r--r--cmake/test-files.cmake2
-rw-r--r--cmake/test.cmake7
-rw-r--r--include/mbgl/gl/implementation.hpp16
-rw-r--r--include/mbgl/map/map.hpp8
-rw-r--r--include/mbgl/math/log2.hpp27
-rw-r--r--include/mbgl/mbgl.hpp4
-rw-r--r--include/mbgl/platform/default/headless_display.hpp29
-rw-r--r--include/mbgl/sprite/sprite_image.hpp4
-rw-r--r--include/mbgl/style/conversion/function.hpp4
-rw-r--r--include/mbgl/style/conversion/make_property_setters.hpp13
-rw-r--r--include/mbgl/style/conversion/make_property_setters.hpp.ejs2
-rw-r--r--include/mbgl/style/function.hpp31
-rw-r--r--include/mbgl/style/layer.hpp4
-rw-r--r--include/mbgl/style/layers/circle_layer.hpp12
-rw-r--r--include/mbgl/style/layers/fill_extrusion_layer.hpp72
-rw-r--r--include/mbgl/style/property_value.hpp24
-rw-r--r--include/mbgl/style/transition_options.hpp14
-rw-r--r--include/mbgl/util/color.hpp20
-rw-r--r--include/mbgl/util/constants.hpp2
-rw-r--r--include/mbgl/util/event.hpp (renamed from include/mbgl/platform/event.hpp)0
-rw-r--r--include/mbgl/util/exception.hpp5
-rw-r--r--include/mbgl/util/image.hpp43
-rw-r--r--include/mbgl/util/logging.hpp (renamed from include/mbgl/platform/log.hpp)2
-rw-r--r--include/mbgl/util/platform.hpp (renamed from include/mbgl/platform/platform.hpp)0
-rw-r--r--include/mbgl/util/range.hpp2
-rw-r--r--include/mbgl/util/size.hpp32
-rw-r--r--package.json13
-rw-r--r--platform/android/.gitignore2
-rw-r--r--platform/android/CHANGELOG.md14
-rw-r--r--platform/android/MapboxGLAndroidSDK/build.gradle235
-rwxr-xr-xplatform/android/MapboxGLAndroidSDK/deploy.sh2
-rw-r--r--platform/android/MapboxGLAndroidSDK/gradle-checkstyle.gradle17
-rw-r--r--platform/android/MapboxGLAndroidSDK/gradle-javadoc.gradle21
-rw-r--r--platform/android/MapboxGLAndroidSDK/gradle-publish.gradle153
-rw-r--r--platform/android/MapboxGLAndroidSDK/gradle.properties8
-rw-r--r--platform/android/MapboxGLAndroidSDK/proguard-rules.pro48
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/BaseGestureDetector.java241
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/MoveGestureDetector.java260
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/RotateGestureDetector.java260
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/ShoveGestureDetector.java317
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/TwoFingerGestureDetector.java356
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java93
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapboxAccountManager.java131
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Annotation.java195
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BaseMarkerOptions.java128
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BaseMarkerViewOptions.java477
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Icon.java90
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/IconFactory.java311
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java501
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindowTipView.java94
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindowView.java52
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java392
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerOptions.java249
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerView.java767
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java1030
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewOptions.java217
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MultiPoint.java102
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Polygon.java90
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolygonOptions.java346
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Polyline.java90
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolylineOptions.java350
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java497
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdate.java2
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java711
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/GeoConstants.java50
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java254
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyBearingTracking.java51
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyLocationTracking.java36
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/Style.java98
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/ConversionException.java22
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/IconBitmapChangedException.java8
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/InvalidAccessTokenException.java20
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/InvalidLatLngBoundsException.java6
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/InvalidMarkerPositionException.java10
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/MapboxAccountManagerNotStartedException.java23
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/TelemetryServiceNotConfiguredException.java11
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/TooManyIconsException.java6
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ILatLng.java6
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/IProjectedMeters.java4
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java366
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngBounds.java556
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngSpan.java156
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ProjectedMeters.java189
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/VisibleRegion.java219
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java312
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationListener.java11
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationServices.java298
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java683
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CompassViewSettings.java21
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/FocalPointChangeListener.java8
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/IconManager.java158
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/InfoWindowManager.java94
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapFragment.java325
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java636
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapKeyListener.java265
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java3965
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapZoomButtonController.java59
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java3877
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java2138
-rwxr-xr-xplatform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java1181
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/OnMapReadyCallback.java17
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java191
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/SupportMapFragment.java344
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java498
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java300
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java1450
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/ViewSettings.java48
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/CompassView.java225
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java1228
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettings.java496
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/net/ConnectivityListener.java2
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/net/ConnectivityReceiver.java134
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/net/NativeConnectivityListener.java38
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java534
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java709
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionDefinition.java2
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionError.java83
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionStatus.java184
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineTilePyramidRegionDefinition.java80
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/BackgroundLayer.java171
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CannotAddLayerException.java12
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CircleLayer.java426
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CustomLayer.java35
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/FillLayer.java450
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Filter.java422
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Function.java210
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Layer.java126
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/LayoutProperty.java6
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/LineLayer.java588
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/NoSuchLayerException.java6
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PaintProperty.java6
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Property.java919
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java3778
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyValue.java77
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/RasterLayer.java299
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/SymbolLayer.java1436
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/layer.java.ejs10
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property.java.ejs2
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property_factory.java.ejs2
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CannotAddSourceException.java12
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonOptions.java122
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonSource.java318
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/NoSuchSourceException.java6
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/RasterSource.java118
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/Source.java94
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/TileSet.java575
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/VectorSource.java86
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/GzipRequestInterceptor.java70
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEvent.java209
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEventManager.java1328
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryLocationReceiver.java104
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryService.java267
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/AnimatorUtils.java160
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/ColorUtils.java183
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/MathUtils.java96
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res-public/values/public.xml132
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/color/mapbox_material_bg_selector.xml (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/color/material_bg_selector.xml)0
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/mapbox_compass_icon.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/compass.png)bin3787 -> 3787 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/mapbox_logo_icon.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/attribution_logo.png)bin3408 -> 3408 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/mapbox_marker_icon_default.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/default_marker.png)bin1520 -> 1520 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/mapbox_markerview_icon_default.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/default_markerview.png)bin1669 -> 1669 bytes
-rwxr-xr-xplatform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/mapbox_mylocation_icon_bearing.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/ic_mylocationview_bearing.png)bin1046 -> 1046 bytes
-rwxr-xr-xplatform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/mapbox_mylocation_icon_default.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/ic_mylocationview_normal.png)bin885 -> 885 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/mapbox_compass_icon.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/compass.png)bin2488 -> 2488 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/mapbox_logo_icon.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/attribution_logo.png)bin1958 -> 1958 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/mapbox_marker_icon_default.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/default_marker.png)bin1010 -> 1010 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/mapbox_markerview_icon_default.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/default_markerview.png)bin1115 -> 1115 bytes
-rwxr-xr-xplatform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/mapbox_mylocation_icon_bearing.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/ic_mylocationview_bearing.png)bin649 -> 649 bytes
-rwxr-xr-xplatform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/mapbox_mylocation_icon_default.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/ic_mylocationview_normal.png)bin555 -> 555 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable-v21/mapbox_default_bg_selector.xml (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-v21/bg_default_selector.xml)0
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/mapbox_compass_icon.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/compass.png)bin4775 -> 4775 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/mapbox_logo_icon.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/attribution_logo.png)bin4492 -> 4492 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/mapbox_marker_icon_default.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/default_marker.png)bin1995 -> 1995 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/mapbox_markerview_icon_default.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/default_markerview.png)bin2163 -> 2163 bytes
-rwxr-xr-xplatform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/mapbox_mylocation_icon_bearing.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/ic_mylocationview_bearing.png)bin1345 -> 1345 bytes
-rwxr-xr-xplatform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/mapbox_mylocation_icon_default.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/ic_mylocationview_normal.png)bin1096 -> 1096 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapbox_compass_icon.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/compass.png)bin7527 -> 7527 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapbox_logo_icon.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/attribution_logo.png)bin7059 -> 7059 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapbox_mapview_preview.jpg (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapview_preview.jpg)bin166053 -> 166053 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapbox_marker_icon_default.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/default_marker.png)bin2998 -> 2998 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapbox_markerview_icon_default.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/default_markerview.png)bin3163 -> 3163 bytes
-rwxr-xr-xplatform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapbox_mylocation_icon_bearing.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/ic_mylocationview_bearing.png)bin1902 -> 1902 bytes
-rwxr-xr-xplatform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapbox_mylocation_icon_default.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/ic_mylocationview_normal.png)bin1586 -> 1586 bytes
-rwxr-xr-xplatform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/mapbox_compass_icon.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/compass.png)bin18537 -> 18537 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/mapbox_infowindow_icon_bg.9.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/bg_infowindow_content.9.png)bin928 -> 928 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/mapbox_logo_icon.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/attribution_logo.png)bin9402 -> 9402 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/mapbox_marker_icon_default.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/default_marker.png)bin4006 -> 4006 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/mapbox_markerview_icon_default.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/default_markerview.png)bin4071 -> 4071 bytes
-rwxr-xr-xplatform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/mapbox_mylocation_icon_bearing.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/ic_mylocationview_bearing.png)bin3022 -> 3022 bytes
-rwxr-xr-xplatform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/mapbox_mylocation_icon_default.png (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/ic_mylocationview_normal.png)bin2456 -> 2456 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable/bg_default_selector.xml6
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable/ic_info_outline_24dp_selector.xml5
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable/ic_mylocationview_background.xml10
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable/mapbox_default_bg_selector.xml6
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable/mapbox_info_bg_selector.xml5
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable/mapbox_info_icon_default.xml (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable/ic_info_outline_24dp.xml)0
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable/mapbox_info_icon_selected.xml (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/drawable/ic_info_outline_24dp_selected.xml)0
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/drawable/mapbox_mylocation_bg_shape.xml10
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_attribution_list_item.xml (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/layout/attribution_list_item.xml)0
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_infowindow_content.xml (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/layout/infowindow_content.xml)16
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_infowindow_view.xml (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/layout/infowindow_view.xml)0
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_mapview_internal.xml (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapview_internal.xml)10
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_mapview_preview.xml (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapview_preview.xml)22
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_view_image_marker.xml (renamed from platform/android/MapboxGLAndroidSDK/src/main/res/layout/view_image_marker.xml)0
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/values/arrays.xml4
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/values/attrs.xml99
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/values/colors.xml8
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/values/dimens.xml20
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/values/integers.xml4
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/values/strings.xml38
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/values/styles.xml7
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/build.gradle110
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/gradle-checkstyle.gradle17
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/gradle-config.gradle22
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/gradle-device-farm.gradle43
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/gradle-make.gradle18
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/lint.xml34
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/proguard-rules.pro2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapViewUtils.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapboxMapTest.java826
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapboxMapUtils.java15
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/BaseActivityTest.java81
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/AddRemoveMarkerActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/BulkMarkerActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/DynamicMarkerChangeActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/MarkerViewActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/MarkerViewScaleActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/PolygonActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/PolylineActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/PressForMarkerActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/camera/CameraAnimationTypeActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/camera/CameraPositionActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/camera/LatLngBoundsActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/camera/ManualZoomActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/camera/MaxMinZoomActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/camera/ScrollByActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/customlayer/CustomLayerActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/directions/DirectionsActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/feature/QueryRenderedFeaturesBoxCountActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/feature/QueryRenderedFeaturesPropertiesActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/geocoding/GeocoderActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/imagegenerator/PrintActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/infowindow/DynamicInfoWindowAdapterActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/infowindow/InfoWindowActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/infowindow/InfoWindowAdapterActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/maplayout/DebugModeActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/maplayout/MapPaddingActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/maplayout/SurfaceViewMediaControlActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/maplayout/VideoViewActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/offline/OfflineActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/style/CircleLayerActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/style/CustomSpriteActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/style/RuntimeStyleActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/style/RuntimeStyleTimingTestActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/style/StyleFileActivityTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/MarkerTest.java142
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/MarkerViewTest.java147
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/PolygonTest.java105
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/PolylineTest.java100
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraAnimateTest.java253
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraEaseTest.java252
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraInternalApiTest.java169
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraMoveTest.java252
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/RotateActivityTest.java62
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/TiltActivityTest.java62
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/ZoomActivityTest.java71
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/feature/QueryRenderedFeaturesBoxCountTest.java61
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/feature/QueryRenderedFeaturesHighlightTest.java81
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/feature/QueryRenderedFeaturesPropertiesTest.java78
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/feature/QueryRenderedSymbolBoxCountTest.java62
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/AttributionTest.java156
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/CompassViewTest.java153
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/LogoTest.java84
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/MyLocationViewTest.java246
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BackgroundLayerStyleTest.java169
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BackgroundLayerTest.java169
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BaseStyleTest.java40
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerStyleTest.java433
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerTest.java524
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillLayerStyleTest.java474
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillLayerTest.java474
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerStyleTest.java735
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerTest.java735
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RasterLayerStyleTest.java389
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RasterLayerTest.java390
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleBackgroundLayerTest.java74
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleTests.java219
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleTimingTests.java43
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerStyleTest.java2331
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java2331
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/layer.junit.ejs23
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/DrawerUtils.java16
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/GestureUtils.java6
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/OnMapReadyIdlingResource.java78
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/ScreenshotUtil.java193
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/TestConstants.java18
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/ViewUtils.java15
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml44
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MapboxApplication.java62
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/FeatureOverviewActivity.java339
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/AddRemoveMarkerActivity.java264
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/AnimatedMarkerActivity.java412
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/BulkMarkerActivity.java439
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/DynamicMarkerChangeActivity.java212
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewActivity.java786
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewScaleActivity.java229
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewsInRectangleActivity.java133
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PolygonActivity.java288
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PolylineActivity.java363
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PressForMarkerActivity.java217
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/CameraAnimationTypeActivity.java335
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/CameraPositionActivity.java306
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/LatLngBoundsActivity.java211
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/ManualZoomActivity.java194
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/MaxMinZoomActivity.java140
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/ScrollByActivity.java220
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/customlayer/CustomLayerActivity.java255
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/directions/DirectionsActivity.java314
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/espresso/EspressoTestActivity.java80
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxCountActivity.java252
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxHighlightActivity.java236
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxSymbolCountActivity.java186
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesPropertiesActivity.java398
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/MapFragmentActivity.java106
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/MultiMapActivity.java10
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/SupportMapFragmentActivity.java109
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/ViewPagerActivity.java138
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/geocoding/GeocoderActivity.java300
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/imagegenerator/PrintActivity.java170
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/imagegenerator/SnapshotActivity.java180
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/infowindow/DynamicInfoWindowAdapterActivity.java255
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/infowindow/InfoWindowActivity.java336
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/infowindow/InfoWindowAdapterActivity.java238
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/DebugModeActivity.java214
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/DoubleMapActivity.java268
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/MapInDialogActivity.java187
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/MapPaddingActivity.java238
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/NavigationDrawerActivity.java384
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/SimpleMapActivity.java86
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/SurfaceViewMediaControlActivity.java151
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/VideoViewActivity.java102
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/navigation/CarDrivingActivity.java282
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/navigation/LocationPickerActivity.java737
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/OfflineActivity.java589
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/UpdateMetadataActivity.java264
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/CircleLayerActivity.java215
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/CustomSpriteActivity.java238
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/GeoJsonClusteringActivity.java265
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RealTimeGeoJsonActivity.java194
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleActivity.java913
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleTestActivity.java101
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleTimingTestActivity.java143
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/StyleFileActivity.java35
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/SymbolLayerActivity.java215
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationDrawableActivity.java270
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTintActivity.java374
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationToggleActivity.java253
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTrackingModeActivity.java576
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/adapter/FeatureAdapter.java66
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/adapter/FeatureSectionAdapter.java265
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/activity/Feature.java112
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CityStateMarker.java16
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CityStateMarkerOptions.java88
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CountryMarker.java26
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CountryMarkerOptions.java98
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CountryMarkerView.java26
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CountryMarkerViewOptions.java166
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/PulseMarkerView.java6
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/PulseMarkerViewOptions.java110
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/TextMarkerView.java16
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/TextMarkerViewOptions.java130
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/constants/AppConstant.java2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/customlayer/ExampleCustomLayer.java19
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/other/OfflineDownloadRegionDialog.java82
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/other/OfflineListRegionsDialog.java63
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/FontCache.java27
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/GeoParseUtil.java88
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/ItemClickSupport.java138
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/OfflineUtils.java43
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/TimingLogger.java211
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/ToolbarComposer.java58
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-hdpi/ic_launcher_round.pngbin0 -> 24697 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/ic_launcher_round.pngbin0 -> 14115 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xhdpi/ic_launcher_round.pngbin0 -> 37126 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxhdpi/ic_launcher_round.pngbin0 -> 66853 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxxhdpi/ic_launcher_round.pngbin0 -> 103015 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_add_sprite.xml8
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_animated_marker.xml8
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_camera_animation_types.xml6
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_camera_position.xml2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_camera_test.xml22
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_car_driving.xml8
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_circlelayer.xml8
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_directions.xml2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_dynamic_marker.xml12
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_geocoder.xml6
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow.xml8
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow_adapter.xml8
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow_adapter_dynamic.xml8
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_manual_zoom.xml8
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_map_simple.xml19
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_marker_bulk.xml8
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_marker_view.xml8
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_marker_view_in_rect.xml28
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_marker_view_scale.xml9
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_maxmin_zoom.xml8
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_my_location_dot_color.xml43
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_my_location_tracking.xml8
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_polyline.xml10
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_press_for_marker.xml14
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_query_features_box.xml6
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_query_features_point.xml12
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_scroll_by.xml8
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_style_file.xml8
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_surfaceview_mediacontrols.xml2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_symbollayer.xml22
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_video_view.xml12
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/fragment_dialog_map.xml12
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_custom_layer.xml9
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_symbol_layer.xml16
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/raw/test_points_utrecht.geojson49
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml13
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/AnnotationTest.java122
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/IconTest.java80
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/InfoWindowTest.java130
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/MarkerTest.java282
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/MarkerViewTest.java521
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/PolygonTest.java106
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/PolylineTest.java104
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/camera/CameraPositionTest.java211
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/constants/StyleVersionTest.java16
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngBoundsTest.java363
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngSpanTest.java88
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngTest.java356
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/ProjectedMetersTest.java88
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/VisibleRegionTest.java161
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapOptionsTest.java335
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapTest.java868
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/ProjectionTest.java26
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/TrackingSettingsTest.java95
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/UiSettingsTest.java611
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettingsTest.java145
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/style/layers/FilterTest.java170
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/style/layers/FunctionTest.java33
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/telemetry/HttpTransportTest.java15
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/utils/MockParcel.java399
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker1
-rwxr-xr-xplatform/android/MapboxGLAndroidSDKTestApp/update_icons.sh21
-rw-r--r--platform/android/MapboxGLAndroidSDKWearTestApp/build.gradle43
-rw-r--r--platform/android/MapboxGLAndroidSDKWearTestApp/gradle-checkstyle.gradle17
-rw-r--r--platform/android/MapboxGLAndroidSDKWearTestApp/gradle-config.gradle22
-rw-r--r--platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/MapboxApplication.java4
-rw-r--r--platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/activity/FeatureOverviewActivity.java4
-rw-r--r--platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/activity/SimpleMapViewActivity.java16
-rw-r--r--platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/layout/activity_simple_mapview.xml10
-rw-r--r--platform/android/bitrise.yml69
-rw-r--r--platform/android/build.gradle7
-rw-r--r--platform/android/checkstyle.gradle16
-rw-r--r--platform/android/checkstyle.xml32
-rw-r--r--platform/android/config.cmake286
-rw-r--r--platform/android/gradle/wrapper/gradle-wrapper.jarbin53324 -> 54227 bytes
-rw-r--r--platform/android/gradle/wrapper/gradle-wrapper.properties5
-rwxr-xr-xplatform/android/gradlew22
-rw-r--r--platform/android/gradlew.bat6
-rw-r--r--platform/android/scripts/generate-style-code.js42
-rw-r--r--platform/android/scripts/generate-test-code.js2
-rwxr-xr-xplatform/android/scripts/metrics.sh15
-rw-r--r--platform/android/src/connectivity_listener.cpp2
-rw-r--r--platform/android/src/example_custom_layer.cpp35
-rw-r--r--platform/android/src/geometry/conversion/feature.hpp2
-rw-r--r--platform/android/src/http_file_source.cpp2
-rwxr-xr-xplatform/android/src/jni.cpp104
-rw-r--r--platform/android/src/jni.hpp6
-rw-r--r--platform/android/src/logging_android.cpp (renamed from platform/android/src/log_android.cpp)2
-rw-r--r--platform/android/src/main.cpp9
-rwxr-xr-xplatform/android/src/native_map_view.cpp120
-rwxr-xr-xplatform/android/src/native_map_view.hpp6
-rw-r--r--platform/android/src/run_loop.cpp2
-rw-r--r--platform/android/src/style/android_conversion.hpp2
-rw-r--r--platform/android/src/style/conversion/geojson.hpp2
-rw-r--r--platform/android/src/style/conversion/types.hpp2
-rw-r--r--platform/android/src/style/conversion/types.hpp.ejs2
-rw-r--r--platform/android/src/style/conversion/types_string_values.hpp2
-rw-r--r--platform/android/src/style/conversion/types_string_values.hpp.ejs2
-rw-r--r--platform/android/src/style/layers/background_layer.cpp2
-rw-r--r--platform/android/src/style/layers/background_layer.hpp2
-rw-r--r--platform/android/src/style/layers/circle_layer.cpp25
-rw-r--r--platform/android/src/style/layers/circle_layer.hpp8
-rw-r--r--platform/android/src/style/layers/custom_layer.cpp2
-rw-r--r--platform/android/src/style/layers/fill_layer.cpp2
-rw-r--r--platform/android/src/style/layers/fill_layer.hpp2
-rw-r--r--platform/android/src/style/layers/layer.cpp27
-rw-r--r--platform/android/src/style/layers/layer.cpp.ejs4
-rw-r--r--platform/android/src/style/layers/layer.hpp18
-rw-r--r--platform/android/src/style/layers/layer.hpp.ejs4
-rw-r--r--platform/android/src/style/layers/line_layer.cpp2
-rw-r--r--platform/android/src/style/layers/line_layer.hpp2
-rw-r--r--platform/android/src/style/layers/raster_layer.cpp2
-rw-r--r--platform/android/src/style/layers/raster_layer.hpp2
-rw-r--r--platform/android/src/style/layers/symbol_layer.cpp2
-rw-r--r--platform/android/src/style/layers/symbol_layer.hpp2
-rw-r--r--platform/android/src/style/sources/source.cpp23
-rw-r--r--platform/android/src/style/sources/source.hpp16
-rw-r--r--platform/android/src/test/Main.java15
-rw-r--r--platform/android/src/test/main.jni.cpp76
-rw-r--r--platform/android/src/thread.cpp4
-rw-r--r--platform/android/tests/docs/ACTIVITY_SANITY_TEST.md2
-rw-r--r--platform/darwin/mbgl/storage/reachability.h (renamed from include/mbgl/platform/darwin/reachability.h)0
-rw-r--r--platform/darwin/mbgl/storage/reachability.m (renamed from platform/darwin/src/reachability.m)2
-rw-r--r--platform/darwin/resources/zh-Hans.lproj/Foundation.strings291
-rw-r--r--platform/darwin/scripts/generate-style-code.js21
-rw-r--r--platform/darwin/src/MGLCircleStyleLayer.h32
-rw-r--r--platform/darwin/src/MGLCircleStyleLayer.mm42
-rw-r--r--platform/darwin/src/MGLStyle.mm7
-rw-r--r--platform/darwin/src/MGLStyleLayer.mm.ejs2
-rw-r--r--platform/darwin/src/NSDate+MGLAdditions.h1
-rw-r--r--platform/darwin/src/NSExpression+MGLAdditions.mm2
-rw-r--r--platform/darwin/src/headless_backend_cgl.cpp64
-rw-r--r--platform/darwin/src/headless_backend_eagl.mm44
-rw-r--r--platform/darwin/src/headless_display_cgl.cpp52
-rw-r--r--platform/darwin/src/image.mm22
-rw-r--r--platform/darwin/src/logging_nslog.mm (renamed from platform/darwin/src/log_nslog.mm)2
-rw-r--r--platform/darwin/src/nsthread.mm2
-rw-r--r--platform/darwin/src/string_nsstring.mm2
-rw-r--r--platform/darwin/test/MGLCircleStyleLayerTests.m15
-rw-r--r--platform/darwin/test/MGLFeatureTests.mm2
-rw-r--r--platform/darwin/test/MGLStyleLayerTests.xib4
-rw-r--r--platform/darwin/test/MGLStyleTests.mm2
-rw-r--r--platform/default/bidi.cpp128
-rw-r--r--platform/default/default_file_source.cpp2
-rw-r--r--platform/default/headless_backend_glx.cpp67
-rw-r--r--platform/default/headless_backend_osmesa.cpp65
-rw-r--r--platform/default/http_file_source.cpp2
-rw-r--r--platform/default/image.cpp12
-rw-r--r--platform/default/jpeg_reader.cpp2
-rw-r--r--platform/default/logging_stderr.cpp (renamed from platform/default/log_stderr.cpp)2
-rw-r--r--platform/default/mbgl/gl/headless_backend.cpp (renamed from platform/default/headless_backend.cpp)28
-rw-r--r--platform/default/mbgl/gl/headless_backend.hpp (renamed from include/mbgl/platform/default/headless_backend.hpp)60
-rw-r--r--platform/default/mbgl/gl/headless_display.cpp15
-rw-r--r--platform/default/mbgl/gl/headless_display.hpp20
-rw-r--r--platform/default/mbgl/gl/offscreen_view.cpp30
-rw-r--r--platform/default/mbgl/gl/offscreen_view.hpp (renamed from include/mbgl/platform/default/offscreen_view.hpp)6
-rw-r--r--platform/default/mbgl/storage/offline_database.cpp2
-rw-r--r--platform/default/mbgl/storage/offline_download.cpp2
-rw-r--r--platform/default/mbgl/util/default_styles.cpp (renamed from src/mbgl/util/default_styles.cpp)0
-rw-r--r--platform/default/mbgl/util/default_styles.hpp (renamed from include/mbgl/util/default_styles.hpp)0
-rw-r--r--platform/default/mbgl/util/default_thread_pool.cpp (renamed from platform/default/thread_pool.cpp)2
-rw-r--r--platform/default/mbgl/util/default_thread_pool.hpp (renamed from include/mbgl/platform/default/thread_pool.hpp)0
-rw-r--r--platform/default/offscreen_view.cpp47
-rw-r--r--platform/default/online_file_source.cpp2
-rw-r--r--platform/default/png_reader.cpp4
-rw-r--r--platform/default/sqlite3.cpp2
-rw-r--r--platform/default/string_stdlib.cpp4
-rw-r--r--platform/default/thread.cpp4
-rw-r--r--platform/default/webp_reader.cpp6
-rw-r--r--platform/glfw/glfw_view.cpp (renamed from platform/default/glfw_view.cpp)32
-rw-r--r--platform/glfw/glfw_view.hpp (renamed from include/mbgl/platform/default/glfw_view.hpp)7
-rw-r--r--platform/glfw/main.cpp (renamed from bin/glfw.cpp)12
-rw-r--r--platform/glfw/settings_json.cpp (renamed from platform/default/settings_json.cpp)2
-rw-r--r--platform/glfw/settings_json.hpp (renamed from include/mbgl/platform/default/settings_json.hpp)0
-rw-r--r--platform/ios/CHANGELOG.md8
-rw-r--r--platform/ios/bitrise.yml31
-rw-r--r--platform/ios/config.cmake29
-rw-r--r--platform/ios/framework/Settings.bundle/zh-Hans.lproj/Root.strings3
-rw-r--r--platform/ios/ios.xcodeproj/project.pbxproj13
-rw-r--r--platform/ios/ios.xcodeproj/xcshareddata/xcschemes/CI.xcscheme2
-rw-r--r--platform/ios/ios.xcodeproj/xcshareddata/xcschemes/bench.xcscheme2
-rw-r--r--platform/ios/ios.xcodeproj/xcshareddata/xcschemes/dynamic+static.xcscheme2
-rw-r--r--platform/ios/ios.xcodeproj/xcshareddata/xcschemes/dynamic.xcscheme2
-rw-r--r--platform/ios/ios.xcodeproj/xcshareddata/xcschemes/iosapp.xcscheme2
-rw-r--r--platform/ios/ios.xcodeproj/xcshareddata/xcschemes/static.xcscheme2
-rw-r--r--platform/ios/resources/zh-Hans.lproj/Localizable.strings84
-rwxr-xr-xplatform/ios/scripts/metrics.sh20
-rw-r--r--platform/ios/src/MGLMapView.mm39
-rw-r--r--platform/ios/src/MGLMapView_Private.h2
-rw-r--r--platform/ios/src/MGLMapboxEvents.m2
-rw-r--r--platform/ios/src/UIImage+MGLAdditions.mm2
-rw-r--r--platform/ios/test/MGLSourceTests.m24
-rw-r--r--platform/ios/toolchain.cmake7
m---------platform/ios/uitest/KIF0
m---------platform/ios/uitest/OHHTTPStubs0
-rw-r--r--platform/linux/config.cmake77
-rwxr-xr-xplatform/linux/scripts/after_success.sh10
-rwxr-xr-xplatform/linux/scripts/metrics.sh12
-rw-r--r--platform/linux/src/headless_backend_egl.cpp103
-rw-r--r--platform/linux/src/headless_backend_glx.cpp87
-rw-r--r--platform/linux/src/headless_display_egl.cpp69
-rw-r--r--platform/linux/src/headless_display_glx.cpp (renamed from platform/default/headless_display.cpp)57
-rw-r--r--platform/macos/CHANGELOG.md6
-rw-r--r--platform/macos/bitrise.yml30
-rw-r--r--platform/macos/config.cmake42
-rw-r--r--platform/macos/macos.xcodeproj/project.pbxproj5
-rw-r--r--platform/macos/macos.xcodeproj/xcshareddata/xcschemes/CI.xcscheme2
-rw-r--r--platform/macos/macos.xcodeproj/xcshareddata/xcschemes/dynamic.xcscheme2
-rw-r--r--platform/macos/macos.xcodeproj/xcshareddata/xcschemes/macosapp.xcscheme2
-rw-r--r--platform/macos/scripts/executable.xcscheme8
-rw-r--r--platform/macos/scripts/library.xcscheme2
-rwxr-xr-xplatform/macos/scripts/metrics.sh7
-rw-r--r--platform/macos/scripts/node.xcscheme5
-rw-r--r--platform/macos/src/MGLMapView.mm46
-rw-r--r--platform/macos/src/MGLMapView_Private.h2
-rw-r--r--platform/macos/src/MGLOpenGLLayer.mm2
-rw-r--r--platform/macos/src/NSImage+MGLAdditions.mm4
-rw-r--r--platform/node/CHANGELOG.md14
-rw-r--r--platform/node/bitrise.yml3
-rwxr-xr-xplatform/node/scripts/after_script.sh19
-rwxr-xr-xplatform/node/scripts/after_success.sh13
-rw-r--r--platform/node/src/node_logging.cpp (renamed from platform/node/src/node_log.cpp)2
-rw-r--r--platform/node/src/node_logging.hpp (renamed from platform/node/src/node_log.hpp)2
-rw-r--r--platform/node/src/node_map.cpp81
-rw-r--r--platform/node/src/node_map.hpp6
-rw-r--r--platform/node/src/node_mapbox_gl_native.cpp2
-rw-r--r--platform/node/test/fixtures/zoom-center/expected.pngbin0 -> 882 bytes
-rw-r--r--platform/node/test/js/map.test.js44
-rw-r--r--platform/node/test/suite_implementation.js31
-rw-r--r--platform/qt/app/mapwindow.cpp183
-rw-r--r--platform/qt/app/mapwindow.hpp26
-rw-r--r--platform/qt/config.cmake25
-rw-r--r--platform/qt/include/qmapboxgl.hpp2
-rw-r--r--platform/qt/qmlapp/main.qml46
-rw-r--r--platform/qt/qt.cmake16
-rw-r--r--platform/qt/resources/common.qrc3
-rw-r--r--platform/qt/resources/source1.geojson (renamed from platform/qt/resources/source.geojson)0
-rw-r--r--platform/qt/resources/source2.geojson92
-rw-r--r--platform/qt/src/bidi.cpp56
-rw-r--r--platform/qt/src/http_file_source.cpp2
-rw-r--r--platform/qt/src/image.cpp4
-rw-r--r--platform/qt/src/qmapboxgl.cpp98
-rw-r--r--platform/qt/src/qmapboxgl_p.hpp7
-rw-r--r--platform/qt/src/qquickmapboxgl.cpp11
-rw-r--r--platform/qt/src/qquickmapboxglrenderer.cpp2
-rw-r--r--platform/qt/src/qt_conversion.hpp4
-rw-r--r--platform/qt/src/run_loop_impl.hpp2
-rw-r--r--platform/qt/src/string_stdlib.cpp2
-rw-r--r--platform/qt/test/headless_backend_qt.cpp37
-rwxr-xr-xscripts/build-shaders.js101
-rwxr-xr-xscripts/clang-tools.sh9
-rw-r--r--scripts/generate-style-code.js39
-rwxr-xr-xscripts/log_binary_size.sh42
-rwxr-xr-xscripts/publish_binary_size.sh75
-rw-r--r--scripts/style-code.js36
-rwxr-xr-xscripts/travis_setup.sh28
-rw-r--r--scripts/valgrind.sup86
-rw-r--r--src/mbgl/algorithm/generate_clip_ids_impl.hpp11
-rw-r--r--src/mbgl/annotation/annotation_manager.cpp4
-rw-r--r--src/mbgl/annotation/annotation_tile.hpp2
-rw-r--r--src/mbgl/geometry/line_atlas.cpp88
-rw-r--r--src/mbgl/geometry/line_atlas.hpp18
-rw-r--r--src/mbgl/gl/attribute.cpp29
-rw-r--r--src/mbgl/gl/attribute.hpp177
-rw-r--r--src/mbgl/gl/color_mode.cpp44
-rw-r--r--src/mbgl/gl/color_mode.hpp95
-rw-r--r--src/mbgl/gl/context.cpp404
-rw-r--r--src/mbgl/gl/context.hpp153
-rw-r--r--src/mbgl/gl/debugging.cpp4
-rw-r--r--src/mbgl/gl/depth_mode.cpp18
-rw-r--r--src/mbgl/gl/depth_mode.hpp36
-rw-r--r--src/mbgl/gl/draw_mode.hpp76
-rw-r--r--src/mbgl/gl/extension.cpp21
-rw-r--r--src/mbgl/gl/framebuffer.hpp5
-rw-r--r--src/mbgl/gl/index_buffer.hpp39
-rw-r--r--src/mbgl/gl/primitives.hpp22
-rw-r--r--src/mbgl/gl/program.hpp70
-rw-r--r--src/mbgl/gl/renderbuffer.hpp5
-rw-r--r--src/mbgl/gl/segment.hpp39
-rw-r--r--src/mbgl/gl/shader.cpp113
-rw-r--r--src/mbgl/gl/shader.hpp45
-rw-r--r--src/mbgl/gl/stencil_mode.cpp27
-rw-r--r--src/mbgl/gl/stencil_mode.hpp66
-rw-r--r--src/mbgl/gl/texture.hpp7
-rw-r--r--src/mbgl/gl/types.hpp97
-rw-r--r--src/mbgl/gl/uniform.cpp54
-rw-r--r--src/mbgl/gl/uniform.hpp94
-rw-r--r--src/mbgl/gl/value.cpp99
-rw-r--r--src/mbgl/gl/value.hpp125
-rw-r--r--src/mbgl/gl/vao.cpp58
-rw-r--r--src/mbgl/gl/vao.hpp78
-rw-r--r--src/mbgl/gl/vertex_buffer.hpp31
-rw-r--r--src/mbgl/layout/merge_lines.cpp4
-rw-r--r--src/mbgl/layout/symbol_feature.hpp3
-rw-r--r--src/mbgl/layout/symbol_instance.cpp2
-rw-r--r--src/mbgl/layout/symbol_instance.hpp7
-rw-r--r--src/mbgl/layout/symbol_layout.cpp332
-rw-r--r--src/mbgl/layout/symbol_layout.hpp16
-rw-r--r--src/mbgl/map/map.cpp72
-rw-r--r--src/mbgl/map/transform.cpp37
-rw-r--r--src/mbgl/map/transform.hpp2
-rw-r--r--src/mbgl/map/transform_state.cpp50
-rw-r--r--src/mbgl/map/transform_state.hpp6
-rw-r--r--src/mbgl/math/log2.cpp (renamed from src/mbgl/util/math.cpp)12
-rw-r--r--src/mbgl/programs/attributes.hpp23
-rw-r--r--src/mbgl/programs/circle_program.cpp7
-rw-r--r--src/mbgl/programs/circle_program.hpp59
-rw-r--r--src/mbgl/programs/collision_box_program.cpp7
-rw-r--r--src/mbgl/programs/collision_box_program.hpp56
-rw-r--r--src/mbgl/programs/debug_program.hpp27
-rw-r--r--src/mbgl/programs/fill_program.cpp47
-rw-r--r--src/mbgl/programs/fill_program.hpp123
-rw-r--r--src/mbgl/programs/line_program.cpp129
-rw-r--r--src/mbgl/programs/line_program.hpp178
-rw-r--r--src/mbgl/programs/program.hpp43
-rw-r--r--src/mbgl/programs/program_parameters.hpp16
-rw-r--r--src/mbgl/programs/programs.hpp50
-rw-r--r--src/mbgl/programs/raster_program.cpp7
-rw-r--r--src/mbgl/programs/raster_program.hpp68
-rw-r--r--src/mbgl/programs/symbol_program.cpp145
-rw-r--r--src/mbgl/programs/symbol_program.hpp136
-rw-r--r--src/mbgl/programs/uniforms.hpp33
-rw-r--r--src/mbgl/renderer/bucket.hpp5
-rw-r--r--src/mbgl/renderer/circle_bucket.cpp75
-rw-r--r--src/mbgl/renderer/circle_bucket.hpp20
-rw-r--r--src/mbgl/renderer/debug_bucket.cpp65
-rw-r--r--src/mbgl/renderer/debug_bucket.hpp14
-rw-r--r--src/mbgl/renderer/element_group.hpp28
-rw-r--r--src/mbgl/renderer/fill_bucket.cpp126
-rw-r--r--src/mbgl/renderer/fill_bucket.hpp35
-rw-r--r--src/mbgl/renderer/frame_history.cpp72
-rw-r--r--src/mbgl/renderer/frame_history.hpp18
-rw-r--r--src/mbgl/renderer/line_bucket.cpp118
-rw-r--r--src/mbgl/renderer/line_bucket.hpp33
-rw-r--r--src/mbgl/renderer/paint_parameters.hpp4
-rw-r--r--src/mbgl/renderer/painter.cpp193
-rw-r--r--src/mbgl/renderer/painter.hpp80
-rw-r--r--src/mbgl/renderer/painter_background.cpp112
-rw-r--r--src/mbgl/renderer/painter_circle.cpp78
-rw-r--r--src/mbgl/renderer/painter_clipping.cpp68
-rw-r--r--src/mbgl/renderer/painter_debug.cpp198
-rw-r--r--src/mbgl/renderer/painter_fill.cpp263
-rw-r--r--src/mbgl/renderer/painter_line.cpp192
-rw-r--r--src/mbgl/renderer/painter_raster.cpp92
-rw-r--r--src/mbgl/renderer/painter_symbol.cpp305
-rw-r--r--src/mbgl/renderer/raster_bucket.cpp18
-rw-r--r--src/mbgl/renderer/raster_bucket.hpp13
-rw-r--r--src/mbgl/renderer/render_tile.hpp1
-rw-r--r--src/mbgl/renderer/symbol_bucket.cpp76
-rw-r--r--src/mbgl/renderer/symbol_bucket.hpp48
-rw-r--r--src/mbgl/shader/circle_shader.cpp15
-rw-r--r--src/mbgl/shader/circle_shader.hpp30
-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.cpp15
-rw-r--r--src/mbgl/shader/collision_box_shader.hpp27
-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/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.cpp15
-rw-r--r--src/mbgl/shader/line_shader.hpp35
-rw-r--r--src/mbgl/shader/line_vertex.cpp7
-rw-r--r--src/mbgl/shader/line_vertex.hpp72
-rw-r--r--src/mbgl/shader/raster_shader.cpp15
-rw-r--r--src/mbgl/shader/raster_shader.hpp35
-rw-r--r--src/mbgl/shader/raster_vertex.cpp7
-rw-r--r--src/mbgl/shader/raster_vertex.hpp39
-rw-r--r--src/mbgl/shader/shaders.hpp58
-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/sprite/sprite_atlas.cpp139
-rw-r--r--src/mbgl/sprite/sprite_atlas.hpp39
-rw-r--r--src/mbgl/sprite/sprite_image.cpp2
-rw-r--r--src/mbgl/sprite/sprite_parser.cpp27
-rw-r--r--src/mbgl/sprite/sprite_parser.hpp8
-rw-r--r--src/mbgl/style/class_dictionary.hpp1
-rw-r--r--src/mbgl/style/cross_faded_property_evaluator.cpp53
-rw-r--r--src/mbgl/style/cross_faded_property_evaluator.hpp48
-rw-r--r--src/mbgl/style/function.cpp81
-rw-r--r--src/mbgl/style/layer_impl.hpp4
-rw-r--r--src/mbgl/style/layers/background_layer.cpp12
-rw-r--r--src/mbgl/style/layers/background_layer_impl.cpp8
-rw-r--r--src/mbgl/style/layers/background_layer_impl.hpp2
-rw-r--r--src/mbgl/style/layers/background_layer_properties.cpp16
-rw-r--r--src/mbgl/style/layers/background_layer_properties.hpp23
-rw-r--r--src/mbgl/style/layers/circle_layer.cpp73
-rw-r--r--src/mbgl/style/layers/circle_layer_impl.cpp16
-rw-r--r--src/mbgl/style/layers/circle_layer_impl.hpp2
-rw-r--r--src/mbgl/style/layers/circle_layer_properties.cpp24
-rw-r--r--src/mbgl/style/layers/circle_layer_properties.hpp66
-rw-r--r--src/mbgl/style/layers/custom_layer_impl.cpp6
-rw-r--r--src/mbgl/style/layers/custom_layer_impl.hpp2
-rw-r--r--src/mbgl/style/layers/fill_extrusion_layer.cpp171
-rw-r--r--src/mbgl/style/layers/fill_extrusion_layer_impl.cpp19
-rw-r--r--src/mbgl/style/layers/fill_extrusion_layer_impl.hpp24
-rw-r--r--src/mbgl/style/layers/fill_extrusion_layer_properties.cpp9
-rw-r--r--src/mbgl/style/layers/fill_extrusion_layer_properties.hpp51
-rw-r--r--src/mbgl/style/layers/fill_layer.cpp28
-rw-r--r--src/mbgl/style/layers/fill_layer_impl.cpp14
-rw-r--r--src/mbgl/style/layers/fill_layer_impl.hpp2
-rw-r--r--src/mbgl/style/layers/fill_layer_properties.cpp24
-rw-r--r--src/mbgl/style/layers/fill_layer_properties.hpp51
-rw-r--r--src/mbgl/style/layers/layer.cpp.ejs14
-rw-r--r--src/mbgl/style/layers/layer_properties.cpp.ejs26
-rw-r--r--src/mbgl/style/layers/layer_properties.hpp.ejs40
-rw-r--r--src/mbgl/style/layers/line_layer.cpp64
-rw-r--r--src/mbgl/style/layers/line_layer_impl.cpp30
-rw-r--r--src/mbgl/style/layers/line_layer_impl.hpp2
-rw-r--r--src/mbgl/style/layers/line_layer_properties.cpp37
-rw-r--r--src/mbgl/style/layers/line_layer_properties.hpp102
-rw-r--r--src/mbgl/style/layers/raster_layer.cpp28
-rw-r--r--src/mbgl/style/layers/raster_layer_impl.cpp8
-rw-r--r--src/mbgl/style/layers/raster_layer_impl.hpp2
-rw-r--r--src/mbgl/style/layers/raster_layer_properties.cpp24
-rw-r--r--src/mbgl/style/layers/raster_layer_properties.hpp51
-rw-r--r--src/mbgl/style/layers/symbol_layer.cpp260
-rw-r--r--src/mbgl/style/layers/symbol_layer_impl.cpp85
-rw-r--r--src/mbgl/style/layers/symbol_layer_impl.hpp35
-rw-r--r--src/mbgl/style/layers/symbol_layer_properties.cpp75
-rw-r--r--src/mbgl/style/layers/symbol_layer_properties.hpp306
-rw-r--r--src/mbgl/style/layout_property.hpp64
-rw-r--r--src/mbgl/style/paint_property.hpp224
-rw-r--r--src/mbgl/style/parser.cpp2
-rw-r--r--src/mbgl/style/property_evaluation_parameters.hpp (renamed from src/mbgl/style/calculation_parameters.hpp)6
-rw-r--r--src/mbgl/style/property_evaluator.cpp152
-rw-r--r--src/mbgl/style/property_evaluator.hpp46
-rw-r--r--src/mbgl/style/property_parsing.hpp2
-rw-r--r--src/mbgl/style/source_impl.cpp38
-rw-r--r--src/mbgl/style/source_impl.hpp3
-rw-r--r--src/mbgl/style/sources/geojson_source_impl.cpp2
-rw-r--r--src/mbgl/style/style.cpp73
-rw-r--r--src/mbgl/style/style.hpp8
-rw-r--r--src/mbgl/text/bidi.hpp46
-rw-r--r--src/mbgl/text/collision_tile.cpp1
-rw-r--r--src/mbgl/text/get_anchors.cpp1
-rw-r--r--src/mbgl/text/glyph.cpp2
-rw-r--r--src/mbgl/text/glyph.hpp20
-rw-r--r--src/mbgl/text/glyph_atlas.cpp92
-rw-r--r--src/mbgl/text/glyph_atlas.hpp13
-rw-r--r--src/mbgl/text/glyph_set.cpp254
-rw-r--r--src/mbgl/text/glyph_set.hpp33
-rw-r--r--src/mbgl/text/quads.cpp30
-rw-r--r--src/mbgl/text/quads.hpp9
-rw-r--r--src/mbgl/text/shaping.cpp8
-rw-r--r--src/mbgl/text/shaping.hpp11
-rw-r--r--src/mbgl/tile/geometry_tile.cpp6
-rw-r--r--src/mbgl/tile/geometry_tile_worker.cpp2
-rw-r--r--src/mbgl/tile/tile.cpp2
-rw-r--r--src/mbgl/tile/tile.hpp3
-rw-r--r--src/mbgl/util/event.cpp (renamed from src/mbgl/platform/event.cpp)2
-rw-r--r--src/mbgl/util/i18n.cpp355
-rw-r--r--src/mbgl/util/i18n.hpp24
-rw-r--r--src/mbgl/util/ignore.hpp23
-rw-r--r--src/mbgl/util/indexed_tuple.hpp47
-rw-r--r--src/mbgl/util/logging.cpp (renamed from src/mbgl/platform/log.cpp)2
-rw-r--r--src/mbgl/util/mapbox.cpp23
-rw-r--r--src/mbgl/util/math.hpp6
-rw-r--r--src/mbgl/util/offscreen_texture.cpp23
-rw-r--r--src/mbgl/util/offscreen_texture.hpp6
-rw-r--r--src/mbgl/util/premultiply.cpp10
-rw-r--r--src/mbgl/util/stopwatch.cpp2
-rw-r--r--src/mbgl/util/stopwatch.hpp2
-rw-r--r--src/mbgl/util/thread.hpp2
-rw-r--r--src/mbgl/util/tile_cover.cpp4
-rw-r--r--src/mbgl/util/url.cpp35
-rw-r--r--src/mbgl/util/url.hpp1
-rw-r--r--src/mbgl/util/utf.hpp15
-rw-r--r--test/actor/actor.test.cpp2
-rw-r--r--test/actor/actor_ref.test.cpp2
-rw-r--r--test/algorithm/generate_clip_ids.test.cpp1
-rw-r--r--test/api/annotations.test.cpp102
-rw-r--r--test/api/api_misuse.test.cpp19
-rw-r--r--test/api/custom_layer.test.cpp12
-rw-r--r--test/api/query.test.cpp10
-rw-r--r--test/api/render_missing.test.cpp12
-rw-r--r--test/api/repeated_render.test.cpp28
-rw-r--r--test/fixtures/annotations/assets.zipbin481374 -> 0 bytes
-rw-r--r--test/fixtures/annotations/debug_empty/expected.pngbin0 -> 1238 bytes
-rw-r--r--test/fixtures/annotations/debug_sparse/expected.pngbin0 -> 2933 bytes
-rw-r--r--test/fixtures/api/assets.zipbin167696 -> 0 bytes
-rw-r--r--test/fixtures/storage/assets.zipbin1243 -> 0 bytes
-rw-r--r--test/fixtures/style_parser/stop-zoom-value.info.json1
-rw-r--r--test/gl/bucket.test.cpp41
-rw-r--r--test/gl/object.test.cpp40
-rw-r--r--test/map/map.test.cpp153
-rw-r--r--test/map/transform.test.cpp65
-rw-r--r--test/sprite/sprite_atlas.test.cpp110
-rw-r--r--test/sprite/sprite_image.test.cpp18
-rw-r--r--test/sprite/sprite_parser.test.cpp129
-rw-r--r--test/src/mbgl/test/conversion_stubs.hpp2
-rw-r--r--test/src/mbgl/test/fixture_log_observer.hpp2
-rw-r--r--test/src/mbgl/test/util.cpp23
-rw-r--r--test/src/mbgl/test/util.hpp9
-rw-r--r--test/storage/asset_file_source.test.cpp4
-rw-r--r--test/storage/local_file_source.test.cpp2
-rw-r--r--test/storage/online_file_source.test.cpp10
-rw-r--r--test/style/conversion/geojson_options.test.cpp14
-rw-r--r--test/style/filter.test.cpp6
-rw-r--r--test/style/functions.test.cpp12
-rw-r--r--test/style/source.test.cpp6
-rw-r--r--test/text/glyph_atlas.test.cpp4
-rw-r--r--test/text/quads.test.cpp96
-rw-r--r--test/tile/raster_tile.test.cpp2
-rw-r--r--test/tile/tile_coordinate.test.cpp3
-rw-r--r--test/tile/vector_tile.test.cpp2
-rw-r--r--test/util/http_timeout.test.cpp2
-rw-r--r--test/util/image.test.cpp18
-rw-r--r--test/util/mapbox.test.cpp2
-rw-r--r--test/util/memory.test.cpp24
-rw-r--r--test/util/merge_lines.test.cpp54
-rw-r--r--test/util/offscreen_texture.test.cpp38
-rw-r--r--test/util/text_conversions.test.cpp2
-rw-r--r--test/util/tile_cover.test.cpp2
-rw-r--r--test/util/url.test.cpp25
936 files changed, 54518 insertions, 46349 deletions
diff --git a/.gitignore b/.gitignore
index ecd9b7ec57..873b80fae8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,3 +30,5 @@ xcuserdata
/platform/macos/macos.xcworkspace/xcshareddata/macos.xcscmblueprint
/platform/ios/ios.xcworkspace/xcshareddata/ios.xcscmblueprint
/documentation
+test/fixtures/api/assets.zip
+test/fixtures/storage/assets.zip
diff --git a/.mason b/.mason
-Subproject 4279f58787acba8286789f861cf7c3c4ce47d52
+Subproject a17d47e8158824449bc93b894639c78b4d33cb5
diff --git a/.travis.yml b/.travis.yml
index 57f6e10abc..d36352c570 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,27 +2,48 @@ git:
submodules: false
# Save common build configurations as shortcuts, so we can reference them later.
+addons:
+ apt:
+ sources:
+ - &common_sources [ 'ubuntu-toolchain-r-test', 'george-edison55-precise-backports' ]
+ packages:
+ - &common_packages [ 'libllvm3.8v4', 'cmake', 'cmake-data' ]
+ - &clang38_packages [ 'clang-3.8', 'libstdc++-5-dev', 'libstdc++6' ]
+ - &gcc5_packages [ 'gcc-5', 'g++-5' ]
+ - &egl_packages [ 'libgles2-mesa-dev', 'libgbm-dev' ]
+ - &glfw_packages [ 'libxrandr-dev', 'libxcursor-dev', 'libxinerama-dev' ]
+
addons_shortcuts:
- addons_clang35: &clang35
+ addons_clang38: &clang38
apt:
- sources: [ 'ubuntu-toolchain-r-test', 'george-edison55-precise-backports' ]
- packages: [ 'clang-3.5', 'libstdc++-4.9-dev', 'libstdc++6', 'libllvm3.8v4', 'cmake', 'cmake-data',
- 'libxrandr-dev', 'libxcursor-dev', 'libxinerama-dev' ]
+ sources: *common_sources
+ packages:
+ - *common_packages
+ - *clang38_packages
+ - *egl_packages
+ - *glfw_packages
addons_gcc5: &gcc5
apt:
- sources: [ 'ubuntu-toolchain-r-test', 'george-edison55-precise-backports' ]
- packages: [ 'g++-5', 'gcc-5', 'libllvm3.8v4', 'cmake', 'cmake-data',
- 'libxrandr-dev', 'libxcursor-dev', 'libxinerama-dev' ]
+ sources: *common_sources
+ packages:
+ - *common_packages
+ - *gcc5_packages
+ - *egl_packages
+ - *glfw_packages
addons_qt4: &qt4
apt:
- sources: [ 'ubuntu-toolchain-r-test', 'george-edison55-precise-backports' ]
- packages: [ 'g++-5', 'gcc-5', 'libjemalloc-dev', 'cmake', 'cmake-data',
- 'mesa-utils', 'qt4-default' ]
+ sources: *common_sources
+ packages:
+ - *common_packages
+ - *gcc5_packages
+ - [ 'libjemalloc-dev', 'mesa-utils', 'qt4-default' ]
addons_qt5: &qt5
apt:
- sources: [ 'ubuntu-toolchain-r-test', 'george-edison55-precise-backports' ]
- packages: [ 'g++-5', 'gcc-5', 'cmake', 'cmake-data',
- 'mesa-utils', 'libc6-dbg', 'qt5-default', 'libqt5opengl5-dev', 'qtdeclarative5-dev', 'qtpositioning5-dev', 'qtlocation5-dev' ]
+ sources: *common_sources
+ packages:
+ - *common_packages
+ - *gcc5_packages
+ - [ 'mesa-utils', 'libc6-dbg', 'qt5-default', 'libqt5opengl5-dev', 'qtdeclarative5-dev', 'qtpositioning5-dev', 'qtlocation5-dev' ]
env:
global:
@@ -38,9 +59,7 @@ env:
install:
- source ./scripts/travis_helper.sh
- source ./scripts/travis_setup.sh
-before_script:
- ccache --zero-stats
- - cmake --version
script:
- make linux
- make benchmark
@@ -49,101 +68,147 @@ script:
after_script:
- ccache --show-stats
- ./platform/linux/scripts/after_script.sh ${TRAVIS_JOB_NUMBER}
+after_success:
+ - ./platform/linux/scripts/after_success.sh
matrix:
include:
- # Clang 3.5 - Debug - Node
+ # LLVM 3.8.0 - clang-{format,tidy}
+ - os: linux
+ sudo: false
+ dist: trusty
+ language: cpp
+ env: _CXX=c++ _CC=cc
+ compiler: "check"
+ script:
+ - git fetch origin master:refs/remotes/origin/master
+ - make check
+
+ # OSMesa - Node - Clang 3.8 - Debug
- os: linux
sudo: required
dist: trusty
language: node
- compiler: "node4-clang35-debug"
- env: _CXX=clang++-3.5 _CC=clang-3.5 WITH_OSMESA=1
- addons: *clang35
+ compiler: "osmesa-node4-clang38-debug"
+ env: BUILDTYPE=Debug _CXX=clang++-3.8 _CC=clang-3.8 WITH_OSMESA=1
+ addons: *clang38
+ script:
+ - nvm install 4
+ - nvm use 4
+ - make node
+ - make test-node
+ after_script:
+ - ccache --show-stats
+ - ./platform/node/scripts/after_script.sh ${TRAVIS_JOB_NUMBER}
+
+ # EGL - Node - Clang 3.8 - Debug
+ - os: linux
+ sudo: required
+ dist: trusty
+ language: node
+ compiler: "egl-node4-clang38-debug"
+ env: BUILDTYPE=Debug _CXX=clang++-3.8 _CC=clang-3.8 WITH_EGL=1
+ addons: *clang38
+ before_script:
+ - mapbox_start_xvfb
+ script:
+ - nvm install 4
+ - nvm use 4
+ - make node
+ - make test-node
+ after_script:
+ - ccache --show-stats
+ - ./platform/node/scripts/after_script.sh ${TRAVIS_JOB_NUMBER}
+
+ # GLX - Node - Clang 3.8 - Release
+ - os: linux
+ sudo: required
+ dist: trusty
+ language: node
+ compiler: "glx-node4-clang38-release"
+ env: BUILDTYPE=Release _CXX=clang++-3.8 _CC=clang-3.8
+ addons: *clang38
before_script:
- export PACKAGE_JSON_VERSION=$(node -e "console.log(require('./package.json').version)")
- export PUBLISH=$([[ "${TRAVIS_TAG:-}" == "node-v${PACKAGE_JSON_VERSION}" ]] && echo true)
- - export BUILDTYPE=$([[ -n ${PUBLISH:-} ]] && echo "Release" || echo "Debug")
+ - mapbox_start_xvfb
script:
- nvm install 4
- nvm use 4
- make node
- - if [[ -z ${PUBLISH} ]]; then make test-node; fi
+ - make test-node
after_script:
- ccache --show-stats
- ./platform/node/scripts/after_script.sh ${TRAVIS_JOB_NUMBER}
+ after_success:
+ - ./platform/node/scripts/after_success.sh
- # GCC 5 - Debug - Coverage
+ # OSMesa - GCC 5 - Debug (Coverage)
# FIXME: https://github.com/mapbox/mapbox-gl-native/issues/6918
- os: linux
sudo: required
dist: trusty
language: cpp
- compiler: "glfw-gcc5-debug"
+ compiler: "osmesa-gcc5-debug"
env: BUILDTYPE=Debug _CXX=g++-5 _CC=gcc-5 WITH_COVERAGE=1 WITH_OSMESA=1
addons: *gcc5
after_script:
- ccache --show-stats
- ./platform/linux/scripts/coveralls.sh
- # GCC 5 - Release
+ # OSMesa - GCC 5 - Release
- os: linux
sudo: required
dist: trusty
language: cpp
- compiler: "glfw-gcc5-release"
+ compiler: "osmesa-gcc5-release"
env: BUILDTYPE=Release _CXX=g++-5 _CC=gcc-5 WITH_OSMESA=1
addons: *gcc5
- # Clang 3.5 - Debug
- - os: linux
- sudo: required
- dist: trusty
- language: cpp
- compiler: "glfw-clang35-debug"
- env: BUILDTYPE=Debug _CXX=clang++-3.5 _CC=clang-3.5 WITH_OSMESA=1
- addons: *clang35
-
- # Clang 3.5 - Release
+ # OSMesa - Clang 3.8 - Debug
- os: linux
sudo: required
dist: trusty
language: cpp
- compiler: "glfw-clang35-release"
- env: BUILDTYPE=Release _CXX=clang++-3.5 _CC=clang-3.5 WITH_OSMESA=1
- addons: *clang35
+ compiler: "osmesa-clang38-debug"
+ env: BUILDTYPE=Debug _CXX=clang++-3.8 _CC=clang-3.8 WITH_OSMESA=1
+ addons: *clang38
- # Clang 3.5 - tidy
+ # OSMesa - Clang 3.8 - Release
- os: linux
sudo: required
dist: trusty
language: cpp
- compiler: "check-clang35-release"
- env: BUILDTYPE=Release _CXX=clang++-3.5 _CC=clang-3.5 WITH_OSMESA=1
- addons: *clang35
- script:
- - git fetch origin master:refs/remotes/origin/master
+ compiler: "osmesa-clang38-release"
+ env: BUILDTYPE=Release _CXX=clang++-3.8 _CC=clang-3.8 WITH_OSMESA=1
+ addons: *clang38
- # Qt 4 - Release
+ # Qt 4 - GCC 5 - Release
- os: linux
sudo: required
dist: trusty
language: cpp
compiler: "qt4-gcc5-release"
- env: BUILDTYPE=Release _CXX=g++-5 _CC=gcc-5 RUN_XVFB=1 WITH_QT_4=1
+ env: BUILDTYPE=Release _CXX=g++-5 _CC=gcc-5 WITH_QT_4=1
addons: *qt4
+ before_script:
+ - mapbox_start_xvfb
+ - mapbox_export_mesa_library_path
script:
- make qt-app
- LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libjemalloc.so make run-qt-test-Memory.*:*.Load
- # Qt 5 - Release
+ # Qt 5 - GCC 5 - Release
- os: linux
sudo: required
dist: trusty
language: cpp
compiler: "qt5-gcc5-release"
- env: BUILDTYPE=Release _CXX=g++-5 _CC=gcc-5 RUN_XVFB=1
+ env: BUILDTYPE=Release _CXX=g++-5 _CC=gcc-5
addons: *qt5
+ before_script:
+ - mapbox_start_xvfb
+ - mapbox_export_mesa_library_path
script:
- make qt-app
- make qt-qml-app
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5e99f8031e..f0f3d80cb6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -15,27 +15,43 @@ include(.mason/mason.cmake)
option(WITH_CXX11ABI "Use cxx11abi mason packages" OFF)
option(WITH_COVERAGE "Enable coverage reports" OFF)
option(WITH_OSMESA "Use OSMesa headless backend" OFF)
+option(WITH_EGL "Use EGL backend" OFF)
+option(IS_CI_BUILD "Continuous integration build" OFF)
if(WITH_CXX11ABI)
set(MASON_CXXABI_SUFFIX -cxx11abi)
endif()
+if(WITH_OSMESA AND WITH_EGL)
+ message(FATAL_ERROR "WITH_OSMESA and WITH_EGL are mutually exclusive.")
+endif()
+
if(WITH_OSMESA)
- add_compile_options(-D__OSMESA__)
+ # Default mesa mason binary is OSMesa.
+ set(MASON_MESA_SUFFIX "")
+elseif(WITH_EGL)
+ add_definitions(-DMBGL_USE_GLES2=1)
+ set(MASON_MESA_SUFFIX "-egl")
+else()
+ set(MASON_MESA_SUFFIX "-glx")
+endif()
+
+if(IS_CI_BUILD)
+ add_compile_options(-DCI_BUILD=1)
endif()
-mason_use(geometry VERSION 0.8.0 HEADER_ONLY)
-mason_use(variant VERSION 1.1.0 HEADER_ONLY)
+mason_use(geometry VERSION 0.9.0 HEADER_ONLY)
+mason_use(variant VERSION 1.1.4 HEADER_ONLY)
mason_use(unique_resource VERSION dev HEADER_ONLY)
mason_use(rapidjson VERSION 1.1.0 HEADER_ONLY)
-mason_use(boost VERSION 1.60.0 HEADER_ONLY)
+mason_use(boost VERSION 1.62.0 HEADER_ONLY)
mason_use(geojsonvt VERSION 6.1.3 HEADER_ONLY)
mason_use(supercluster VERSION 0.2.0 HEADER_ONLY)
mason_use(kdbush VERSION 0.1.1 HEADER_ONLY)
mason_use(earcut VERSION 0.12.1 HEADER_ONLY)
mason_use(protozero VERSION 1.4.2 HEADER_ONLY)
mason_use(pixelmatch VERSION 0.10.0 HEADER_ONLY)
-mason_use(geojson VERSION 0.3.2 HEADER_ONLY)
+mason_use(geojson VERSION 0.4.0 HEADER_ONLY)
if(WITH_COVERAGE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage")
@@ -44,7 +60,7 @@ endif(WITH_COVERAGE)
set(CMAKE_CONFIGURATION_TYPES Debug Release)
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall -Wextra -Wshadow -Werror -Wno-variadic-macros -Wno-unknown-pragmas")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -ftemplate-depth=1024 -Wall -Wextra -Wshadow -Werror -Wno-variadic-macros -Wno-unknown-pragmas")
if(APPLE)
# -Wno-error=unused-command-line-argument is required due to https://llvm.org/bugs/show_bug.cgi?id=7798
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=unused-command-line-argument")
diff --git a/INSTALL.md b/INSTALL.md
index b7a383f1e6..0789f5e0af 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -28,7 +28,7 @@ targets.
- g++-5 or later
- [CMake](https://cmake.org/) 3.1 or later (for build only)
- [cURL](https://curl.haxx.se) (for build only)
- - [Node.js](https://nodejs.org/) (for build only)
+ - [Node.js](https://nodejs.org/) 4.2.1 or later (for build only)
- [`pkg-config`](https://wiki.freedesktop.org/www/Software/pkg-config/) (for build only)
Depending on your operating system and target, you'll need additional
diff --git a/Makefile b/Makefile
index 29acc367f4..40f8d18568 100644
--- a/Makefile
+++ b/Makefile
@@ -52,7 +52,7 @@ endif
.NOTPARALLEL: node_modules
node_modules: package.json
- npm update # Install dependencies but don't run our own install script.
+ npm install --ignore-scripts # Install dependencies but don't run our own install script.
BUILD_DEPS += .mason/mason
BUILD_DEPS += Makefile
@@ -273,8 +273,10 @@ ideploy:
idocument:
OUTPUT=$(OUTPUT) ./platform/ios/scripts/document.sh
-style-code-darwin:
+.PHONY: darwin-style-code
+darwin-style-code:
node platform/darwin/scripts/generate-style-code.js
+style-code: darwin-style-code
endif
#### Linux targets #####################################################
@@ -292,7 +294,9 @@ $(LINUX_BUILD): $(BUILD_DEPS)
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DWITH_CXX11ABI=$(shell scripts/check-cxx11abi.sh) \
-DWITH_COVERAGE=${WITH_COVERAGE} \
- -DWITH_OSMESA=${WITH_OSMESA})
+ -DIS_CI_BUILD=${CI} \
+ -DWITH_OSMESA=${WITH_OSMESA} \
+ -DWITH_EGL=${WITH_EGL})
.PHONY: linux
linux: glfw-app render offline
@@ -385,9 +389,11 @@ $(QT_BUILD): $(BUILD_DEPS)
-DMASON_PLATFORM=$(BUILD_PLATFORM) \
-DMASON_PLATFORM_VERSION=$(BUILD_PLATFORM_VERSION) \
-DWITH_QT_DECODERS=${WITH_QT_DECODERS} \
+ -DWITH_QT_I18N=${WITH_QT_I18N} \
-DWITH_QT_4=${WITH_QT_4} \
-DWITH_CXX11ABI=$(shell scripts/check-cxx11abi.sh) \
- -DWITH_COVERAGE=${WITH_COVERAGE})
+ -DWITH_COVERAGE=${WITH_COVERAGE} \
+ -DIS_CI_BUILD=${CI})
ifeq ($(HOST_PLATFORM), macos)
@@ -399,9 +405,11 @@ $(MACOS_QT_PROJ_PATH): $(BUILD_DEPS)
-DMASON_PLATFORM=$(BUILD_PLATFORM) \
-DMASON_PLATFORM_VERSION=$(BUILD_PLATFORM_VERSION) \
-DWITH_QT_DECODERS=${WITH_QT_DECODERS} \
+ -DWITH_QT_I18N=${WITH_QT_I18N} \
-DWITH_QT_4=${WITH_QT_4} \
-DWITH_CXX11ABI=$(shell scripts/check-cxx11abi.sh) \
- -DWITH_COVERAGE=${WITH_COVERAGE})
+ -DWITH_COVERAGE=${WITH_COVERAGE} \
+ -DIS_CI_BUILD=${CI})
@# Create Xcode schemes so that we can use xcodebuild from the command line. CMake doesn't
@# create these automatically.
@@ -461,20 +469,24 @@ test-node: node
#### Android targets ###########################################################
-ANDROID_ENV = platform/android/scripts/toolchain.sh
-ANDROID_ABIS = arm-v5 arm-v7 arm-v8 x86 x86-64 mips
+MBGL_ANDROID_ENV = platform/android/scripts/toolchain.sh
+MBGL_ANDROID_ABIS = arm-v5 arm-v7 arm-v8 x86 x86-64 mips
+MBGL_ANDROID_LOCAL_WORK_DIR = /data/local/tmp/core-tests
+MBGL_ANDROID_LIBDIR = lib$(if $(filter arm-v8 x86-64,$1),64)
+MBGL_ANDROID_DALVIKVM = dalvikvm$(if $(filter arm-v8 x86-64,$1),64,32)
-.PHONY: style-code-android
-style-code-android: $(BUILD_DEPS)
+.PHONY: android-style-code
+android-style-code:
node platform/android/scripts/generate-style-code.js
+style-code: android-style-code
define ANDROID_RULES
-build/android-$1/$(BUILDTYPE): style-code-android
+build/android-$1/$(BUILDTYPE): $(BUILD_DEPS)
mkdir -p build/android-$1/$(BUILDTYPE)
build/android-$1/$(BUILDTYPE)/toolchain.cmake: platform/android/scripts/toolchain.sh build/android-$1/$(BUILDTYPE)
- $(ANDROID_ENV) $1 > build/android-$1/$(BUILDTYPE)/toolchain.cmake
+ $(MBGL_ANDROID_ENV) $1 > build/android-$1/$(BUILDTYPE)/toolchain.cmake
build/android-$1/$(BUILDTYPE)/Makefile: build/android-$1/$(BUILDTYPE)/toolchain.cmake platform/android/config.cmake
cd build/android-$1/$(BUILDTYPE) && cmake ../../.. -G Ninja \
@@ -483,38 +495,100 @@ build/android-$1/$(BUILDTYPE)/Makefile: build/android-$1/$(BUILDTYPE)/toolchain.
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DMBGL_PLATFORM=android
+.PHONY: android-test-lib-$1
+android-test-lib-$1: build/android-$1/$(BUILDTYPE)/Makefile
+ $(NINJA) $(NINJA_ARGS) -j$(JOBS) -C build/android-$1/$(BUILDTYPE) mbgl-test
+
.PHONY: android-lib-$1
android-lib-$1: build/android-$1/$(BUILDTYPE)/Makefile
- $(NINJA) $(NINJA_ARGS) -j$(JOBS) -C build/android-$1/$(BUILDTYPE) all
+ $(NINJA) $(NINJA_ARGS) -j$(JOBS) -C build/android-$1/$(BUILDTYPE) mapbox-gl example-custom-layer
.PHONY: android-$1
android-$1: android-lib-$1
- cd platform/android && ./gradlew --parallel --max-workers=$(JOBS) assemble$(BUILDTYPE)
+ cd platform/android && ./gradlew --parallel --max-workers=$(JOBS) :MapboxGLAndroidSDKTestApp:assemble$(BUILDTYPE)
+
+run-android-core-test-$1: android-test-lib-$1
+ # Compile main sources and extract the classes (using the test app to get all transitive dependencies in one place)
+ cd platform/android && ./gradlew :MapboxGLAndroidSDKTestApp:assembleDebug
+ unzip -o platform/android/MapboxGLAndroidSDKTestApp/build/outputs/apk/MapboxGLAndroidSDKTestApp-debug.apk classes.dex -d build/android-$1/$(BUILDTYPE)
+
+ #Compile Test runner
+ find platform/android/src/test -name "*.java" > build/android-$1/$(BUILDTYPE)/java-sources.txt
+ javac -sourcepath platform/android/src/test -d build/android-$1/$(BUILDTYPE) -source 1.7 -target 1.7 @build/android-$1/$(BUILDTYPE)/java-sources.txt
+ #Combine and dex
+ cd build/android-$1/$(BUILDTYPE) && $(ANDROID_HOME)/build-tools/25.0.0/dx --dex --output=test.jar *.class classes.dex
+
+ #Ensure clean state on the device
+ adb shell "rm -Rf $(MBGL_ANDROID_LOCAL_WORK_DIR) && mkdir -p $(MBGL_ANDROID_LOCAL_WORK_DIR)/test"
+
+ # Generate zipped asset files
+ cd test/fixtures/api && zip -r assets.zip assets && cd -
+ cd test/fixtures/storage && zip -r assets.zip assets && cd -
+
+ #Push all needed files to the device
+ adb push build/android-$1/$(BUILDTYPE)/test.jar $(MBGL_ANDROID_LOCAL_WORK_DIR) > /dev/null 2>&1
+ adb push test/fixtures $(MBGL_ANDROID_LOCAL_WORK_DIR)/test > /dev/null 2>&1
+ adb push build/android-$1/$(BUILDTYPE)/stripped/libmapbox-gl.so $(MBGL_ANDROID_LOCAL_WORK_DIR) > /dev/null 2>&1
+ adb push build/android-$1/$(BUILDTYPE)/stripped/libmbgl-test.so $(MBGL_ANDROID_LOCAL_WORK_DIR) > /dev/null 2>&1
+
+ #Kick off the tests
+ adb shell "export LD_LIBRARY_PATH=/system/$(MBGL_ANDROID_LIBDIR):$(MBGL_ANDROID_LOCAL_WORK_DIR) && cd $(MBGL_ANDROID_LOCAL_WORK_DIR) && $(MBGL_ANDROID_DALVIKVM) -cp $(MBGL_ANDROID_LOCAL_WORK_DIR)/test.jar Main"
+
+ #Gather the results
+ adb shell "cd $(MBGL_ANDROID_LOCAL_WORK_DIR) && tar -cvzf results.tgz test/fixtures/* > /dev/null 2>&1"
+ adb pull $(MBGL_ANDROID_LOCAL_WORK_DIR)/results.tgz build/android-$1/$(BUILDTYPE)/ > /dev/null 2>&1
+
+.PHONY: run-android-$1
+run-android-$1: android-$1
+ cd platform/android && ./gradlew :MapboxGLAndroidSDKTestApp:installDebug && adb shell am start -n com.mapbox.mapboxsdk.testapp/.activity.FeatureOverviewActivity
apackage: android-lib-$1
endef
-$(foreach abi,$(ANDROID_ABIS),$(eval $(call ANDROID_RULES,$(abi))))
+$(foreach abi,$(MBGL_ANDROID_ABIS),$(eval $(call ANDROID_RULES,$(abi))))
.PHONY: android
android: android-arm-v7
-.PHONY: android-test
-android-test:
- cd platform/android && ./gradlew testDebugUnitTest --continue
+.PHONY: run-android
+run-android: run-android-arm-v7
+
+.PHONY: run-android-unit-test
+run-android-unit-test:
+ cd platform/android && ./gradlew :MapboxGLAndroidSDKTestApp:testDebugUnitTest --continue
+
+.PHONY: android-ui-test
+android-ui-test:
+ cd platform/android && ./gradlew :MapboxGLAndroidSDKTestApp:assembleDebug --continue && ./gradlew :MapboxGLAndroidSDKTestApp:assembleAndroidTest --continue
-.PHONY: android-test-apk
-android-test-apk:
- cd platform/android && ./gradlew assembleDebug --continue && ./gradlew assembleAndroidTest --continue
+.PHONY: run-android-ui-test
+run-android-ui-test:
+ cd platform/android && ./gradlew :MapboxGLAndroidSDKTestApp:connectedAndroidTest -i
+
+.PHONY: run-android-ui-test-aws
+run-android-ui-test-aws:
+ cd platform/android && ./gradlew devicefarmUpload
+
+.PHONY: run-android-ui-test-spoon
+run-android-ui-test-spoon:
+ cd platform/android && ./gradlew spoon
.PHONY: apackage
apackage:
- cd platform/android && ./gradlew --parallel-threads=$(JOBS) assemble$(BUILDTYPE)
+ cd platform/android && ./gradlew --parallel --max-workers=$(JOBS) assemble$(BUILDTYPE)
-.PHONY: android-generate-test
-android-generate-test:
+.PHONY: test-code-android
+test-code-android:
node platform/android/scripts/generate-test-code.js
+.PHONY: android-ndk-stack
+android-ndk-stack:
+ adb logcat | ndk-stack -sym build/android-arm-v7/Debug
+
+.PHONY: android-checkstyle
+android-checkstyle:
+ cd platform/android && ./gradlew checkstyle
+
#### Miscellaneous targets #####################################################
.PHONY: style-code
@@ -526,6 +600,8 @@ clean:
-rm -rf ./build \
./platform/android/MapboxGLAndroidSDK/build \
./platform/android/MapboxGLAndroidSDKTestApp/build \
+ ./platform/android/MapboxGLAndroidSDKWearTestApp/build \
+ ./platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen \
./platform/android/MapboxGLAndroidSDK/src/main/jniLibs \
./platform/android/MapboxGLAndroidSDKTestApp/src/main/jniLibs \
./platform/android/MapboxGLAndroidSDK/src/main/assets
diff --git a/benchmark/api/query.benchmark.cpp b/benchmark/api/query.benchmark.cpp
index 5a95cd7666..ba696876cd 100644
--- a/benchmark/api/query.benchmark.cpp
+++ b/benchmark/api/query.benchmark.cpp
@@ -2,9 +2,9 @@
#include <mbgl/benchmark/util.hpp>
#include <mbgl/map/map.hpp>
-#include <mbgl/platform/default/headless_backend.hpp>
-#include <mbgl/platform/default/offscreen_view.hpp>
-#include <mbgl/platform/default/thread_pool.hpp>
+#include <mbgl/gl/headless_backend.hpp>
+#include <mbgl/gl/offscreen_view.hpp>
+#include <mbgl/util/default_thread_pool.hpp>
#include <mbgl/sprite/sprite_image.hpp>
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/storage/network_status.hpp>
@@ -34,10 +34,10 @@ public:
util::RunLoop loop;
HeadlessBackend backend;
- OffscreenView view{ backend.getContext(), {{ 1000, 1000 }} };
+ OffscreenView view{ backend.getContext(), { 1000, 1000 } };
DefaultFileSource fileSource{ "benchmark/fixtures/api/cache.db", "." };
ThreadPool threadPool{ 4 };
- Map map{ backend, view.getSize(), 1, fileSource, threadPool, MapMode::Still };
+ Map map{ backend, view.size, 1, fileSource, threadPool, MapMode::Still };
ScreenBox box{{ 0, 0 }, { 1000, 1000 }};
};
diff --git a/benchmark/src/mbgl/benchmark/util.cpp b/benchmark/src/mbgl/benchmark/util.cpp
index 39c5f86883..87d68ea729 100644
--- a/benchmark/src/mbgl/benchmark/util.cpp
+++ b/benchmark/src/mbgl/benchmark/util.cpp
@@ -1,5 +1,5 @@
#include <mbgl/benchmark/util.hpp>
-#include <mbgl/platform/default/offscreen_view.hpp>
+#include <mbgl/gl/offscreen_view.hpp>
#include <mbgl/map/map.hpp>
#include <mbgl/map/view.hpp>
@@ -15,7 +15,7 @@ void render(Map& map, OffscreenView& view) {
result = view.readStillImage();
});
- while (!result.size()) {
+ while (!result.valid()) {
util::RunLoop::Get()->runOnce();
}
}
diff --git a/bin/render.cpp b/bin/render.cpp
index ad29d91993..d275b445d2 100644
--- a/bin/render.cpp
+++ b/bin/render.cpp
@@ -3,10 +3,11 @@
#include <mbgl/util/io.hpp>
#include <mbgl/util/run_loop.hpp>
-#include <mbgl/platform/default/headless_backend.hpp>
-#include <mbgl/platform/default/offscreen_view.hpp>
-#include <mbgl/platform/default/thread_pool.hpp>
+#include <mbgl/gl/headless_backend.hpp>
+#include <mbgl/gl/offscreen_view.hpp>
+#include <mbgl/util/default_thread_pool.hpp>
#include <mbgl/storage/default_file_source.hpp>
+#include <mbgl/util/url.hpp>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
@@ -27,8 +28,9 @@ int main(int argc, char *argv[]) {
double bearing = 0;
double pitch = 0;
- int width = 512;
- int height = 512;
+ uint32_t pixelRatio = 1;
+ uint32_t width = 512;
+ uint32_t height = 512;
static std::string output = "out.png";
std::string cache_file = "cache.sqlite";
std::string asset_root = ".";
@@ -46,6 +48,7 @@ int main(int argc, char *argv[]) {
("pitch,p", po::value(&pitch)->value_name("degrees")->default_value(pitch), "Pitch")
("width,w", po::value(&width)->value_name("pixels")->default_value(width), "Image width")
("height,h", po::value(&height)->value_name("pixels")->default_value(height), "Image height")
+ ("ratio,r", po::value(&pixelRatio)->value_name("number")->default_value(pixelRatio), "Image scale factor")
("class,c", po::value(&classes)->value_name("name"), "Class name")
("token,t", po::value(&token)->value_name("key")->default_value(token), "Mapbox access token")
("debug", po::bool_switch(&debug)->default_value(debug), "Debug mode")
@@ -63,8 +66,6 @@ int main(int argc, char *argv[]) {
exit(1);
}
- std::string style = mbgl::util::read_file(style_path);
-
using namespace mbgl;
util::RunLoop loop;
@@ -84,11 +85,16 @@ int main(int argc, char *argv[]) {
}
HeadlessBackend backend;
- OffscreenView view(backend.getContext(), {{ static_cast<uint16_t>(width), static_cast<uint16_t>(height) }});
+ OffscreenView view(backend.getContext(), { width * pixelRatio, height * pixelRatio });
ThreadPool threadPool(4);
- Map map(backend, view.getSize(), 1, fileSource, threadPool, MapMode::Still);
+ Map map(backend, mbgl::Size { width, height }, pixelRatio, fileSource, threadPool, MapMode::Still);
+
+ if (util::isURL(style_path)) {
+ map.setStyleURL(style_path);
+ } else {
+ map.setStyleJSON(mbgl::util::read_file(style_path));
+ }
- map.setStyleJSON(style);
map.setClasses(classes);
map.setLatLngZoom({ lat, lon }, zoom);
diff --git a/cloudformation/travis.template b/cloudformation/travis.template
index b65093907c..0d9e3c0dc8 100644
--- a/cloudformation/travis.template
+++ b/cloudformation/travis.template
@@ -8,42 +8,6 @@
"Properties": {
"Policies": [
{
- "PolicyName": "list-testing-old",
- "PolicyDocument": {
- "Statement": [
- {
- "Action": [
- "s3:ListBucket"
- ],
- "Effect": "Allow",
- "Resource": [
- "arn:aws:s3:::mapbox-gl-testing"
- ]
- }
- ]
- }
- },
- {
- "PolicyName": "build-testing-old",
- "PolicyDocument": {
- "Statement": [
- {
- "Action": [
- "s3:DeleteObject",
- "s3:GetObject",
- "s3:GetObjectAcl",
- "s3:PutObject",
- "s3:PutObjectAcl"
- ],
- "Effect": "Allow",
- "Resource": [
- "arn:aws:s3:::mapbox-gl-testing/*"
- ]
- }
- ]
- }
- },
- {
"PolicyName": "list-testing",
"PolicyDocument": {
"Statement": [
@@ -148,6 +112,24 @@
}
]
}
+ },
+ {
+ "PolicyName": "cloudwatch-metrics",
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
+ "cloudwatch:PutMetricData",
+ "cloudwatch:GetMetricData",
+ "cloudwatch:GetMetricStatistics"
+ ],
+ "Effect": "Allow",
+ "Resource": [
+ "*"
+ ]
+ }
+ ]
+ }
}
]
}
@@ -179,6 +161,44 @@
}
]
}
+ },
+ {
+ "PolicyName": "publish-metrics",
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
+ "s3:DeleteObject",
+ "s3:GetObject",
+ "s3:GetObjectAcl",
+ "s3:PutObject",
+ "s3:PutObjectAcl"
+ ],
+ "Effect": "Allow",
+ "Resource": [
+ "arn:aws:s3:::mapbox/mapbox-gl-native/metrics/*"
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "PolicyName": "cloudwatch-metrics",
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
+ "cloudwatch:PutMetricData",
+ "cloudwatch:GetMetricData",
+ "cloudwatch:GetMetricStatistics"
+ ],
+ "Effect": "Allow",
+ "Resource": [
+ "*"
+ ]
+ }
+ ]
+ }
}
]
}
diff --git a/cmake/benchmark.cmake b/cmake/benchmark.cmake
index 79da54459e..0752647a2d 100644
--- a/cmake/benchmark.cmake
+++ b/cmake/benchmark.cmake
@@ -14,12 +14,6 @@ target_include_directories(mbgl-benchmark
PRIVATE platform/default
)
-if(DEFINED ENV{CI})
- target_compile_definitions(mbgl-benchmark
- PRIVATE -DCI_BUILD=1
- )
-endif()
-
target_link_libraries(mbgl-benchmark
PRIVATE mbgl-core
)
diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake
index 4d5cddbc49..3255da66f2 100644
--- a/cmake/core-files.cmake
+++ b/cmake/core-files.cmake
@@ -54,12 +54,17 @@ set(MBGL_CORE_FILES
# gl
include/mbgl/gl/gl.hpp
- include/mbgl/gl/implementation.hpp
+ src/mbgl/gl/attribute.cpp
src/mbgl/gl/attribute.hpp
+ src/mbgl/gl/color_mode.cpp
+ src/mbgl/gl/color_mode.hpp
src/mbgl/gl/context.cpp
src/mbgl/gl/context.hpp
src/mbgl/gl/debugging.cpp
src/mbgl/gl/debugging.hpp
+ src/mbgl/gl/depth_mode.cpp
+ src/mbgl/gl/depth_mode.hpp
+ src/mbgl/gl/draw_mode.hpp
src/mbgl/gl/extension.cpp
src/mbgl/gl/extension.hpp
src/mbgl/gl/framebuffer.hpp
@@ -67,18 +72,19 @@ set(MBGL_CORE_FILES
src/mbgl/gl/index_buffer.hpp
src/mbgl/gl/object.cpp
src/mbgl/gl/object.hpp
+ src/mbgl/gl/primitives.hpp
+ src/mbgl/gl/program.hpp
src/mbgl/gl/renderbuffer.hpp
- src/mbgl/gl/shader.cpp
- src/mbgl/gl/shader.hpp
+ src/mbgl/gl/segment.hpp
src/mbgl/gl/state.hpp
+ src/mbgl/gl/stencil_mode.cpp
+ src/mbgl/gl/stencil_mode.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
@@ -112,33 +118,34 @@ set(MBGL_CORE_FILES
# math
include/mbgl/math/clamp.hpp
+ include/mbgl/math/log2.hpp
include/mbgl/math/minmax.hpp
include/mbgl/math/wrap.hpp
-
- # mbgl
- include/mbgl/mbgl.hpp
+ src/mbgl/math/log2.cpp
# parsedate
src/parsedate/parsedate.c
src/parsedate/parsedate.h
- # platform
- include/mbgl/platform/event.hpp
- include/mbgl/platform/log.hpp
- include/mbgl/platform/platform.hpp
- src/mbgl/platform/event.cpp
- src/mbgl/platform/log.cpp
-
- # platform/darwin
- include/mbgl/platform/darwin/reachability.h
-
- # platform/default
- include/mbgl/platform/default/glfw_view.hpp
- include/mbgl/platform/default/headless_backend.hpp
- include/mbgl/platform/default/headless_display.hpp
- include/mbgl/platform/default/offscreen_view.hpp
- include/mbgl/platform/default/settings_json.hpp
- include/mbgl/platform/default/thread_pool.hpp
+ # programs
+ src/mbgl/programs/attributes.hpp
+ src/mbgl/programs/circle_program.cpp
+ src/mbgl/programs/circle_program.hpp
+ src/mbgl/programs/collision_box_program.cpp
+ src/mbgl/programs/collision_box_program.hpp
+ src/mbgl/programs/debug_program.hpp
+ src/mbgl/programs/fill_program.cpp
+ src/mbgl/programs/fill_program.hpp
+ src/mbgl/programs/line_program.cpp
+ src/mbgl/programs/line_program.hpp
+ src/mbgl/programs/program.hpp
+ src/mbgl/programs/program_parameters.hpp
+ src/mbgl/programs/programs.hpp
+ src/mbgl/programs/raster_program.cpp
+ src/mbgl/programs/raster_program.hpp
+ src/mbgl/programs/symbol_program.cpp
+ src/mbgl/programs/symbol_program.hpp
+ src/mbgl/programs/uniforms.hpp
# renderer
src/mbgl/renderer/bucket.hpp
@@ -146,7 +153,6 @@ 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
@@ -173,45 +179,6 @@ set(MBGL_CORE_FILES
src/mbgl/renderer/symbol_bucket.cpp
src/mbgl/renderer/symbol_bucket.hpp
- # 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/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/line_vertex.cpp
- src/mbgl/shader/line_vertex.hpp
- src/mbgl/shader/raster_shader.cpp
- src/mbgl/shader/raster_shader.hpp
- src/mbgl/shader/raster_vertex.cpp
- src/mbgl/shader/raster_vertex.hpp
- src/mbgl/shader/shaders.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
src/mbgl/sprite/sprite_atlas.cpp
@@ -248,10 +215,12 @@ set(MBGL_CORE_FILES
include/mbgl/style/types.hpp
src/mbgl/style/bucket_parameters.cpp
src/mbgl/style/bucket_parameters.hpp
- src/mbgl/style/calculation_parameters.hpp
src/mbgl/style/cascade_parameters.hpp
src/mbgl/style/class_dictionary.cpp
src/mbgl/style/class_dictionary.hpp
+ src/mbgl/style/cross_faded_property_evaluator.cpp
+ src/mbgl/style/cross_faded_property_evaluator.hpp
+ src/mbgl/style/function.cpp
src/mbgl/style/layer.cpp
src/mbgl/style/layer_impl.cpp
src/mbgl/style/layer_impl.hpp
@@ -261,7 +230,7 @@ set(MBGL_CORE_FILES
src/mbgl/style/paint_property.hpp
src/mbgl/style/parser.cpp
src/mbgl/style/parser.hpp
- src/mbgl/style/property_evaluator.cpp
+ src/mbgl/style/property_evaluation_parameters.hpp
src/mbgl/style/property_evaluator.hpp
src/mbgl/style/property_parsing.cpp
src/mbgl/style/property_parsing.hpp
@@ -296,6 +265,7 @@ set(MBGL_CORE_FILES
include/mbgl/style/layers/background_layer.hpp
include/mbgl/style/layers/circle_layer.hpp
include/mbgl/style/layers/custom_layer.hpp
+ include/mbgl/style/layers/fill_extrusion_layer.hpp
include/mbgl/style/layers/fill_layer.hpp
include/mbgl/style/layers/line_layer.hpp
include/mbgl/style/layers/raster_layer.hpp
@@ -313,6 +283,11 @@ set(MBGL_CORE_FILES
src/mbgl/style/layers/custom_layer.cpp
src/mbgl/style/layers/custom_layer_impl.cpp
src/mbgl/style/layers/custom_layer_impl.hpp
+ src/mbgl/style/layers/fill_extrusion_layer.cpp
+ src/mbgl/style/layers/fill_extrusion_layer_impl.cpp
+ src/mbgl/style/layers/fill_extrusion_layer_impl.hpp
+ src/mbgl/style/layers/fill_extrusion_layer_properties.cpp
+ src/mbgl/style/layers/fill_extrusion_layer_properties.hpp
src/mbgl/style/layers/fill_layer.cpp
src/mbgl/style/layers/fill_layer_impl.cpp
src/mbgl/style/layers/fill_layer_impl.hpp
@@ -349,6 +324,7 @@ set(MBGL_CORE_FILES
src/mbgl/style/sources/vector_source_impl.hpp
# text
+ src/mbgl/text/bidi.hpp
src/mbgl/text/check_max_angle.cpp
src/mbgl/text/check_max_angle.hpp
src/mbgl/text/collision_feature.cpp
@@ -406,8 +382,8 @@ set(MBGL_CORE_FILES
include/mbgl/util/compression.hpp
include/mbgl/util/constants.hpp
include/mbgl/util/convert.hpp
- include/mbgl/util/default_styles.hpp
include/mbgl/util/enum.hpp
+ include/mbgl/util/event.hpp
include/mbgl/util/exception.hpp
include/mbgl/util/feature.hpp
include/mbgl/util/font_stack.hpp
@@ -415,11 +391,14 @@ set(MBGL_CORE_FILES
include/mbgl/util/geojson.hpp
include/mbgl/util/geometry.hpp
include/mbgl/util/image.hpp
+ include/mbgl/util/logging.hpp
include/mbgl/util/noncopyable.hpp
include/mbgl/util/optional.hpp
+ include/mbgl/util/platform.hpp
include/mbgl/util/projection.hpp
include/mbgl/util/range.hpp
include/mbgl/util/run_loop.hpp
+ include/mbgl/util/size.hpp
include/mbgl/util/string.hpp
include/mbgl/util/tileset.hpp
include/mbgl/util/timer.hpp
@@ -438,9 +417,9 @@ set(MBGL_CORE_FILES
src/mbgl/util/compression.cpp
src/mbgl/util/constants.cpp
src/mbgl/util/convert.cpp
- src/mbgl/util/default_styles.cpp
src/mbgl/util/dtoa.cpp
src/mbgl/util/dtoa.hpp
+ src/mbgl/util/event.cpp
src/mbgl/util/exclusive.hpp
src/mbgl/util/font_stack.cpp
src/mbgl/util/geo.cpp
@@ -451,11 +430,16 @@ set(MBGL_CORE_FILES
src/mbgl/util/http_header.hpp
src/mbgl/util/http_timeout.cpp
src/mbgl/util/http_timeout.hpp
+ src/mbgl/util/i18n.cpp
+ src/mbgl/util/i18n.hpp
+ src/mbgl/util/ignore.hpp
+ src/mbgl/util/indexed_tuple.hpp
src/mbgl/util/interpolate.hpp
src/mbgl/util/intersection_tests.cpp
src/mbgl/util/intersection_tests.hpp
src/mbgl/util/io.cpp
src/mbgl/util/io.hpp
+ src/mbgl/util/logging.cpp
src/mbgl/util/mapbox.cpp
src/mbgl/util/mapbox.hpp
src/mbgl/util/mat2.cpp
@@ -464,7 +448,6 @@ set(MBGL_CORE_FILES
src/mbgl/util/mat3.hpp
src/mbgl/util/mat4.cpp
src/mbgl/util/mat4.hpp
- src/mbgl/util/math.cpp
src/mbgl/util/math.hpp
src/mbgl/util/offscreen_texture.cpp
src/mbgl/util/offscreen_texture.hpp
diff --git a/cmake/glfw.cmake b/cmake/glfw.cmake
index 56a1335e08..d63bdbc1cf 100644
--- a/cmake/glfw.cmake
+++ b/cmake/glfw.cmake
@@ -1,12 +1,14 @@
add_executable(mbgl-glfw
- bin/glfw.cpp
+ platform/glfw/main.cpp
)
target_sources(mbgl-glfw
- PRIVATE include/mbgl/platform/default/glfw_view.hpp
- PRIVATE platform/default/glfw_view.cpp
- PRIVATE include/mbgl/platform/default/settings_json.hpp
- PRIVATE platform/default/settings_json.cpp
+ PRIVATE platform/glfw/glfw_view.hpp
+ PRIVATE platform/glfw/glfw_view.cpp
+ PRIVATE platform/glfw/settings_json.hpp
+ PRIVATE platform/glfw/settings_json.cpp
+ PRIVATE platform/default/mbgl/util/default_styles.hpp
+ PRIVATE platform/default/mbgl/util/default_styles.cpp
)
target_compile_options(mbgl-glfw
@@ -16,6 +18,7 @@ target_compile_options(mbgl-glfw
target_include_directories(mbgl-glfw
PRIVATE include
PRIVATE src # TODO: eliminate
+ PRIVATE platform/default
)
target_link_libraries(mbgl-glfw
diff --git a/cmake/loop-darwin.cmake b/cmake/loop-darwin.cmake
index 16bc62537c..7884c80a69 100644
--- a/cmake/loop-darwin.cmake
+++ b/cmake/loop-darwin.cmake
@@ -4,6 +4,8 @@ add_library(mbgl-loop STATIC
platform/darwin/src/timer.cpp
)
+set_xcode_property(mbgl-loop GCC_SYMBOLS_PRIVATE_EXTERN YES)
+
target_compile_options(mbgl-loop
PRIVATE -fPIC
PRIVATE -fvisibility-inlines-hidden
diff --git a/cmake/mbgl.cmake b/cmake/mbgl.cmake
index f20f49004c..b2b959e6c1 100644
--- a/cmake/mbgl.cmake
+++ b/cmake/mbgl.cmake
@@ -35,6 +35,11 @@ function(create_source_groups target)
endforeach()
endfunction()
+# This little macro lets you set any XCode specific property
+macro(set_xcode_property TARGET XCODE_PROPERTY XCODE_VALUE)
+ set_property(TARGET ${TARGET} PROPERTY XCODE_ATTRIBUTE_${XCODE_PROPERTY} ${XCODE_VALUE})
+endmacro (set_xcode_property)
+
function(_write_xcconfig_var target var)
get_property(result TARGET ${target} PROPERTY INTERFACE_${var} SET)
if (result)
diff --git a/cmake/node.cmake b/cmake/node.cmake
index 8dd95a9419..ea28e86106 100644
--- a/cmake/node.cmake
+++ b/cmake/node.cmake
@@ -3,8 +3,8 @@ add_nodejs_module(mbgl-node
)
target_sources(mbgl-node
- PRIVATE platform/node/src/node_log.hpp
- PRIVATE platform/node/src/node_log.cpp
+ PRIVATE platform/node/src/node_logging.hpp
+ PRIVATE platform/node/src/node_logging.cpp
PRIVATE platform/node/src/node_map.hpp
PRIVATE platform/node/src/node_map.cpp
PRIVATE platform/node/src/node_request.hpp
@@ -29,6 +29,7 @@ target_compile_options(mbgl-node
target_include_directories(mbgl-node
PRIVATE src # TODO: eliminate
+ PRIVATE platform/default
)
target_link_libraries(mbgl-node
diff --git a/cmake/offline.cmake b/cmake/offline.cmake
index 1dc67f7887..23824e6bdf 100644
--- a/cmake/offline.cmake
+++ b/cmake/offline.cmake
@@ -2,6 +2,11 @@ add_executable(mbgl-offline
bin/offline.cpp
)
+target_sources(mbgl-offline
+ PRIVATE platform/default/mbgl/util/default_styles.hpp
+ PRIVATE platform/default/mbgl/util/default_styles.cpp
+)
+
target_compile_options(mbgl-offline
PRIVATE -fvisibility-inlines-hidden
)
@@ -9,6 +14,7 @@ target_compile_options(mbgl-offline
target_include_directories(mbgl-offline
PRIVATE include
PRIVATE src # TODO: eliminate
+ PRIVATE platform/default
)
target_link_libraries(mbgl-offline
diff --git a/cmake/render.cmake b/cmake/render.cmake
index f1b09b3c47..395a106642 100644
--- a/cmake/render.cmake
+++ b/cmake/render.cmake
@@ -9,6 +9,7 @@ target_compile_options(mbgl-render
target_include_directories(mbgl-render
PRIVATE include
PRIVATE src # TODO: eliminate
+ PRIVATE platform/default
)
target_link_libraries(mbgl-render
diff --git a/cmake/shaders.cmake b/cmake/shaders.cmake
index bebf476bbf..833ebec862 100644
--- a/cmake/shaders.cmake
+++ b/cmake/shaders.cmake
@@ -1,17 +1,19 @@
function(add_shader VAR name)
set(shader_build_cmd ${NodeJS_EXECUTABLE} ${CMAKE_SOURCE_DIR}/scripts/build-shaders.js)
- set(shader_file_prefix ${CMAKE_SOURCE_DIR}/node_modules/mapbox-gl-shaders/src)
+ set(shader_file_prefix ${CMAKE_SOURCE_DIR}/node_modules/mapbox-gl/shaders)
set(shader_source_prefix ${MBGL_GENERATED}/include/mbgl/shader)
add_custom_command(
- OUTPUT ${shader_source_prefix}/${name}.vertex.hpp ${shader_source_prefix}/${name}.fragment.hpp
- COMMAND ${shader_build_cmd} ${shader_file_prefix}/${name}.vertex.glsl ${shader_source_prefix}/${name}.vertex.hpp
- COMMAND ${shader_build_cmd} ${shader_file_prefix}/${name}.fragment.glsl ${shader_source_prefix}/${name}.fragment.hpp
+ OUTPUT ${shader_source_prefix}/${name}.hpp
+ COMMAND ${shader_build_cmd} ${name} ${shader_file_prefix} ${shader_source_prefix}
+ DEPENDS ${CMAKE_SOURCE_DIR}/scripts/build-shaders.js
DEPENDS ${shader_file_prefix}/${name}.vertex.glsl
DEPENDS ${shader_file_prefix}/${name}.fragment.glsl
+ DEPENDS ${shader_file_prefix}/_prelude.vertex.glsl
+ DEPENDS ${shader_file_prefix}/_prelude.fragment.glsl
VERBATIM
)
- set(${VAR} ${${VAR}} ${shader_source_prefix}/${name}.vertex.hpp ${shader_source_prefix}/${name}.fragment.hpp PARENT_SCOPE)
+ set(${VAR} ${${VAR}} ${shader_source_prefix}/${name}.hpp PARENT_SCOPE)
endfunction()
add_shader(MBGL_SHADER_FILES circle)
diff --git a/cmake/test-files.cmake b/cmake/test-files.cmake
index 598e018224..7d8dc82756 100644
--- a/cmake/test-files.cmake
+++ b/cmake/test-files.cmake
@@ -23,6 +23,7 @@ set(MBGL_TEST_FILES
test/geometry/binpack.test.cpp
# gl
+ test/gl/bucket.test.cpp
test/gl/object.test.cpp
# include/mbgl
@@ -111,5 +112,6 @@ set(MBGL_TEST_FILES
test/util/tile_cover.test.cpp
test/util/timer.test.cpp
test/util/token.test.cpp
+ test/util/url.test.cpp
test/util/work_queue.test.cpp
)
diff --git a/cmake/test.cmake b/cmake/test.cmake
index c4d9dd9fad..fc7a22874c 100644
--- a/cmake/test.cmake
+++ b/cmake/test.cmake
@@ -14,14 +14,9 @@ target_include_directories(mbgl-test
PRIVATE test/include
PRIVATE test/src
PRIVATE platform/default
+ PRIVATE ${MBGL_GENERATED}/include
)
-if(DEFINED ENV{CI})
- target_compile_definitions(mbgl-test
- PRIVATE -DCI_BUILD=1
- )
-endif()
-
target_link_libraries(mbgl-test
PRIVATE mbgl-core
)
diff --git a/include/mbgl/gl/implementation.hpp b/include/mbgl/gl/implementation.hpp
deleted file mode 100644
index a0101085fa..0000000000
--- a/include/mbgl/gl/implementation.hpp
+++ /dev/null
@@ -1,16 +0,0 @@
-#pragma once
-
-#if defined(__QT__)
- #define MBGL_USE_QT 1
-#elif defined(__APPLE__)
- #include <TargetConditionals.h>
- #if TARGET_OS_IOS
- #define MBGL_USE_EAGL 1
- #else
- #define MBGL_USE_CGL 1
- #endif
-#elif defined(__OSMESA__)
- #define MBGL_USE_OSMESA 1
-#else
- #define MBGL_USE_GLX 1
-#endif
diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp
index 092cfbe291..c80420371d 100644
--- a/include/mbgl/map/map.hpp
+++ b/include/mbgl/map/map.hpp
@@ -6,6 +6,7 @@
#include <mbgl/util/geo.hpp>
#include <mbgl/util/feature.hpp>
#include <mbgl/util/noncopyable.hpp>
+#include <mbgl/util/size.hpp>
#include <mbgl/annotation/annotation.hpp>
#include <mbgl/style/transition_options.hpp>
@@ -33,7 +34,7 @@ class Layer;
class Map : private util::noncopyable {
public:
explicit Map(Backend&,
- std::array<uint16_t, 2> size,
+ Size size,
float pixelRatio,
FileSource&,
Scheduler&,
@@ -136,9 +137,8 @@ public:
ViewportMode getViewportMode() const;
// Size
- void setSize(const std::array<uint16_t, 2>&);
- uint16_t getWidth() const;
- uint16_t getHeight() const;
+ void setSize(Size);
+ Size getSize() const;
// Projection
double getMetersPerPixelAtLatitude(double lat, double zoom) const;
diff --git a/include/mbgl/math/log2.hpp b/include/mbgl/math/log2.hpp
new file mode 100644
index 0000000000..8a3bc7f1c0
--- /dev/null
+++ b/include/mbgl/math/log2.hpp
@@ -0,0 +1,27 @@
+#pragma once
+
+#include <cmath>
+#include <cstdint>
+#include <type_traits>
+
+namespace mbgl {
+namespace util {
+
+// Computes the log2(x) rounded up to the next integer.
+// (== number of bits required to store x)
+uint32_t ceil_log2(uint64_t x);
+
+template <typename T>
+typename std::enable_if_t<std::is_floating_point<T>::value, T> log2(T x)
+{
+// log2() is producing wrong results on ARMv5 binaries
+// running on ARMv7+ CPUs.
+#if defined(__ANDROID__)
+ return std::log(x) / M_LN2;
+#else
+ return std::log2(x);
+#endif
+}
+
+} // namespace util
+} // namespace mbgl
diff --git a/include/mbgl/mbgl.hpp b/include/mbgl/mbgl.hpp
deleted file mode 100644
index 5cfc9cb45f..0000000000
--- a/include/mbgl/mbgl.hpp
+++ /dev/null
@@ -1,4 +0,0 @@
-#pragma once
-
-#include "map/map.hpp"
-#include "map/view.hpp"
diff --git a/include/mbgl/platform/default/headless_display.hpp b/include/mbgl/platform/default/headless_display.hpp
deleted file mode 100644
index f43e61340f..0000000000
--- a/include/mbgl/platform/default/headless_display.hpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#pragma once
-
-#include <mbgl/gl/implementation.hpp>
-
-#if MBGL_USE_CGL
-#include <OpenGL/OpenGL.h>
-#elif MBGL_USE_GLX
-typedef struct _XDisplay Display;
-typedef struct __GLXFBConfigRec* GLXFBConfig;
-#endif
-
-namespace mbgl {
-
-class HeadlessDisplay {
-public:
- HeadlessDisplay();
- ~HeadlessDisplay();
-
-#if MBGL_USE_CGL
- CGLPixelFormatObj pixelFormat = nullptr;
-#endif
-
-#if MBGL_USE_GLX
- Display *xDisplay = nullptr;
- GLXFBConfig *fbConfigs = nullptr;
-#endif
-};
-
-} // namespace mbgl
diff --git a/include/mbgl/sprite/sprite_image.hpp b/include/mbgl/sprite/sprite_image.hpp
index 7900b90b66..05d9871bf9 100644
--- a/include/mbgl/sprite/sprite_image.hpp
+++ b/include/mbgl/sprite/sprite_image.hpp
@@ -22,8 +22,8 @@ public:
// Whether this image should be interpreted as a signed distance field icon.
const bool sdf;
- float getWidth() const { return image.width / pixelRatio; }
- float getHeight() const { return image.height / pixelRatio; }
+ float getWidth() const { return image.size.width / pixelRatio; }
+ float getHeight() const { return image.size.height / pixelRatio; }
};
} // namespace mbgl
diff --git a/include/mbgl/style/conversion/function.hpp b/include/mbgl/style/conversion/function.hpp
index f14b5089be..6a0b67618f 100644
--- a/include/mbgl/style/conversion/function.hpp
+++ b/include/mbgl/style/conversion/function.hpp
@@ -25,6 +25,10 @@ struct Converter<Function<T>> {
return Error { "function stops must be an array" };
}
+ if (arrayLength(*stopsValue) == 0) {
+ return Error { "function must have at least one stop" };
+ }
+
std::vector<std::pair<float, T>> stops;
for (std::size_t i = 0; i < arrayLength(*stopsValue); ++i) {
const auto& stopValue = arrayMember(*stopsValue, i);
diff --git a/include/mbgl/style/conversion/make_property_setters.hpp b/include/mbgl/style/conversion/make_property_setters.hpp
index a3ba5e5d5a..e30359937e 100644
--- a/include/mbgl/style/conversion/make_property_setters.hpp
+++ b/include/mbgl/style/conversion/make_property_setters.hpp
@@ -8,6 +8,7 @@
#include <mbgl/style/layers/line_layer.hpp>
#include <mbgl/style/layers/symbol_layer.hpp>
#include <mbgl/style/layers/circle_layer.hpp>
+#include <mbgl/style/layers/fill_extrusion_layer.hpp>
#include <mbgl/style/layers/raster_layer.hpp>
#include <mbgl/style/layers/background_layer.hpp>
@@ -67,6 +68,7 @@ auto makeLayoutPropertySetters() {
+
return result;
}
@@ -115,6 +117,17 @@ auto makePaintPropertySetters() {
result["circle-translate"] = makePropertySetter<V>(&CircleLayer::setCircleTranslate);
result["circle-translate-anchor"] = makePropertySetter<V>(&CircleLayer::setCircleTranslateAnchor);
result["circle-pitch-scale"] = makePropertySetter<V>(&CircleLayer::setCirclePitchScale);
+ result["circle-stroke-width"] = makePropertySetter<V>(&CircleLayer::setCircleStrokeWidth);
+ result["circle-stroke-color"] = makePropertySetter<V>(&CircleLayer::setCircleStrokeColor);
+ result["circle-stroke-opacity"] = makePropertySetter<V>(&CircleLayer::setCircleStrokeOpacity);
+
+ result["fill-extrusion-opacity"] = makePropertySetter<V>(&FillExtrusionLayer::setFillExtrusionOpacity);
+ result["fill-extrusion-color"] = makePropertySetter<V>(&FillExtrusionLayer::setFillExtrusionColor);
+ result["fill-extrusion-translate"] = makePropertySetter<V>(&FillExtrusionLayer::setFillExtrusionTranslate);
+ result["fill-extrusion-translate-anchor"] = makePropertySetter<V>(&FillExtrusionLayer::setFillExtrusionTranslateAnchor);
+ result["fill-extrusion-pattern"] = makePropertySetter<V>(&FillExtrusionLayer::setFillExtrusionPattern);
+ result["fill-extrusion-height"] = makePropertySetter<V>(&FillExtrusionLayer::setFillExtrusionHeight);
+ result["fill-extrusion-base"] = makePropertySetter<V>(&FillExtrusionLayer::setFillExtrusionBase);
result["raster-opacity"] = makePropertySetter<V>(&RasterLayer::setRasterOpacity);
result["raster-hue-rotate"] = makePropertySetter<V>(&RasterLayer::setRasterHueRotate);
diff --git a/include/mbgl/style/conversion/make_property_setters.hpp.ejs b/include/mbgl/style/conversion/make_property_setters.hpp.ejs
index 54e3958180..ed8f6e891c 100644
--- a/include/mbgl/style/conversion/make_property_setters.hpp.ejs
+++ b/include/mbgl/style/conversion/make_property_setters.hpp.ejs
@@ -5,7 +5,7 @@
#include <mbgl/style/conversion/property_setter.hpp>
<% for (const layer of locals.layers) { -%>
-#include <mbgl/style/layers/<%- layer.type %>_layer.hpp>
+#include <mbgl/style/layers/<%- layer.type.replace('-', '_') %>_layer.hpp>
<% } -%>
#include <unordered_map>
diff --git a/include/mbgl/style/function.hpp b/include/mbgl/style/function.hpp
index 97e880b280..b023229e4f 100644
--- a/include/mbgl/style/function.hpp
+++ b/include/mbgl/style/function.hpp
@@ -1,7 +1,8 @@
#pragma once
-#include <vector>
+#include <cassert>
#include <utility>
+#include <vector>
namespace mbgl {
namespace style {
@@ -12,28 +13,28 @@ public:
using Stop = std::pair<float, T>;
using Stops = std::vector<Stop>;
- explicit Function(Stops stops_, float base_)
- : base(base_), stops(std::move(stops_)) {}
+ Function(Stops stops_, float base_)
+ : base(base_), stops(std::move(stops_)) {
+ assert(stops.size() > 0);
+ }
float getBase() const { return base; }
const std::vector<std::pair<float, T>>& getStops() const { return stops; }
+ T evaluate(float z) const;
+
+ friend bool operator==(const Function& lhs, const Function& rhs) {
+ return lhs.base == rhs.base && lhs.stops == rhs.stops;
+ }
+
+ friend bool operator!=(const Function& lhs, const Function& rhs) {
+ return !(lhs == rhs);
+ }
+
private:
float base = 1;
std::vector<std::pair<float, T>> stops;
-
- template <class S> friend bool operator==(const Function<S>&, const Function<S>&);
};
-template <class T>
-bool operator==(const Function<T>& lhs, const Function<T>& rhs) {
- return lhs.base == rhs.base && lhs.stops == rhs.stops;
-}
-
-template <class T>
-bool operator!=(const Function<T>& lhs, const Function<T>& rhs) {
- return !(lhs == rhs);
-}
-
} // namespace style
} // namespace mbgl
diff --git a/include/mbgl/style/layer.hpp b/include/mbgl/style/layer.hpp
index 925629a349..dc02cb09b2 100644
--- a/include/mbgl/style/layer.hpp
+++ b/include/mbgl/style/layer.hpp
@@ -15,6 +15,7 @@ class SymbolLayer;
class RasterLayer;
class BackgroundLayer;
class CustomLayer;
+class FillExtrusionLayer;
/**
* The runtime representation of a [layer](https://www.mapbox.com/mapbox-gl-style-spec/#layers) from the Mapbox Style
@@ -42,6 +43,7 @@ protected:
Raster,
Background,
Custom,
+ FillExtrusion,
};
class Impl;
@@ -95,6 +97,8 @@ public:
return visitor(*as<BackgroundLayer>());
case Type::Custom:
return visitor(*as<CustomLayer>());
+ case Type::FillExtrusion:
+ return visitor(*as<FillExtrusionLayer>());
}
}
diff --git a/include/mbgl/style/layers/circle_layer.hpp b/include/mbgl/style/layers/circle_layer.hpp
index 587f0023e3..5562126c2f 100644
--- a/include/mbgl/style/layers/circle_layer.hpp
+++ b/include/mbgl/style/layers/circle_layer.hpp
@@ -54,6 +54,18 @@ public:
PropertyValue<CirclePitchScaleType> getCirclePitchScale(const optional<std::string>& klass = {}) const;
void setCirclePitchScale(PropertyValue<CirclePitchScaleType>, const optional<std::string>& klass = {});
+ static PropertyValue<float> getDefaultCircleStrokeWidth();
+ PropertyValue<float> getCircleStrokeWidth(const optional<std::string>& klass = {}) const;
+ void setCircleStrokeWidth(PropertyValue<float>, const optional<std::string>& klass = {});
+
+ static PropertyValue<Color> getDefaultCircleStrokeColor();
+ PropertyValue<Color> getCircleStrokeColor(const optional<std::string>& klass = {}) const;
+ void setCircleStrokeColor(PropertyValue<Color>, const optional<std::string>& klass = {});
+
+ static PropertyValue<float> getDefaultCircleStrokeOpacity();
+ PropertyValue<float> getCircleStrokeOpacity(const optional<std::string>& klass = {}) const;
+ void setCircleStrokeOpacity(PropertyValue<float>, const optional<std::string>& klass = {});
+
// Private implementation
class Impl;
diff --git a/include/mbgl/style/layers/fill_extrusion_layer.hpp b/include/mbgl/style/layers/fill_extrusion_layer.hpp
new file mode 100644
index 0000000000..08728af309
--- /dev/null
+++ b/include/mbgl/style/layers/fill_extrusion_layer.hpp
@@ -0,0 +1,72 @@
+// This file is generated. Do not edit.
+
+#pragma once
+
+#include <mbgl/style/layer.hpp>
+#include <mbgl/style/filter.hpp>
+#include <mbgl/style/property_value.hpp>
+
+#include <mbgl/util/color.hpp>
+
+namespace mbgl {
+namespace style {
+
+class FillExtrusionLayer : public Layer {
+public:
+ FillExtrusionLayer(const std::string& layerID, const std::string& sourceID);
+ ~FillExtrusionLayer() final;
+
+ // Source
+ const std::string& getSourceID() const;
+ const std::string& getSourceLayer() const;
+ void setSourceLayer(const std::string& sourceLayer);
+
+ void setFilter(const Filter&);
+ const Filter& getFilter() const;
+
+ // Paint properties
+
+ static PropertyValue<float> getDefaultFillExtrusionOpacity();
+ PropertyValue<float> getFillExtrusionOpacity(const optional<std::string>& klass = {}) const;
+ void setFillExtrusionOpacity(PropertyValue<float>, const optional<std::string>& klass = {});
+
+ static PropertyValue<Color> getDefaultFillExtrusionColor();
+ PropertyValue<Color> getFillExtrusionColor(const optional<std::string>& klass = {}) const;
+ void setFillExtrusionColor(PropertyValue<Color>, const optional<std::string>& klass = {});
+
+ static PropertyValue<std::array<float, 2>> getDefaultFillExtrusionTranslate();
+ PropertyValue<std::array<float, 2>> getFillExtrusionTranslate(const optional<std::string>& klass = {}) const;
+ void setFillExtrusionTranslate(PropertyValue<std::array<float, 2>>, const optional<std::string>& klass = {});
+
+ static PropertyValue<TranslateAnchorType> getDefaultFillExtrusionTranslateAnchor();
+ PropertyValue<TranslateAnchorType> getFillExtrusionTranslateAnchor(const optional<std::string>& klass = {}) const;
+ void setFillExtrusionTranslateAnchor(PropertyValue<TranslateAnchorType>, const optional<std::string>& klass = {});
+
+ static PropertyValue<std::string> getDefaultFillExtrusionPattern();
+ PropertyValue<std::string> getFillExtrusionPattern(const optional<std::string>& klass = {}) const;
+ void setFillExtrusionPattern(PropertyValue<std::string>, const optional<std::string>& klass = {});
+
+ static PropertyValue<float> getDefaultFillExtrusionHeight();
+ PropertyValue<float> getFillExtrusionHeight(const optional<std::string>& klass = {}) const;
+ void setFillExtrusionHeight(PropertyValue<float>, const optional<std::string>& klass = {});
+
+ static PropertyValue<float> getDefaultFillExtrusionBase();
+ PropertyValue<float> getFillExtrusionBase(const optional<std::string>& klass = {}) const;
+ void setFillExtrusionBase(PropertyValue<float>, const optional<std::string>& klass = {});
+
+ // Private implementation
+
+ class Impl;
+ Impl* const impl;
+
+ FillExtrusionLayer(const Impl&);
+ FillExtrusionLayer(const FillExtrusionLayer&) = delete;
+};
+
+template <>
+inline bool Layer::is<FillExtrusionLayer>() const {
+ return type == Type::FillExtrusion;
+}
+
+} // namespace style
+} // namespace mbgl
diff --git a/include/mbgl/style/property_value.hpp b/include/mbgl/style/property_value.hpp
index d7e160fdca..83c4b4cf1b 100644
--- a/include/mbgl/style/property_value.hpp
+++ b/include/mbgl/style/property_value.hpp
@@ -17,7 +17,13 @@ private:
using Value = variant<Undefined, T, Function<T>>;
Value value;
- template <class S> friend bool operator==(const PropertyValue<S>&, const PropertyValue<S>&);
+ friend bool operator==(const PropertyValue& lhs, const PropertyValue& rhs) {
+ return lhs.value == rhs.value;
+ }
+
+ friend bool operator!=(const PropertyValue& lhs, const PropertyValue& rhs) {
+ return !(lhs == rhs);
+ }
public:
PropertyValue() : value() {}
@@ -33,21 +39,11 @@ public:
explicit operator bool() const { return !isUndefined(); };
- template <typename Visitor>
- static auto visit(const PropertyValue<T>& value, Visitor&& visitor) {
- return Value::visit(value.value, visitor);
+ template <typename Evaluator>
+ auto evaluate(const Evaluator& evaluator) const {
+ return Value::visit(value, evaluator);
}
};
-template <class T>
-bool operator==(const PropertyValue<T>& lhs, const PropertyValue<T>& rhs) {
- return lhs.value == rhs.value;
-}
-
-template <class T>
-bool operator!=(const PropertyValue<T>& lhs, const PropertyValue<T>& rhs) {
- return !(lhs == rhs);
-}
-
} // namespace style
} // namespace mbgl
diff --git a/include/mbgl/style/transition_options.hpp b/include/mbgl/style/transition_options.hpp
index d7a6633f0c..e2a156e665 100644
--- a/include/mbgl/style/transition_options.hpp
+++ b/include/mbgl/style/transition_options.hpp
@@ -6,9 +6,21 @@
namespace mbgl {
namespace style {
-struct TransitionOptions {
+class TransitionOptions {
+public:
optional<Duration> duration = {};
optional<Duration> delay = {};
+
+ TransitionOptions reverseMerge(const TransitionOptions& defaults) const {
+ return {
+ duration ? duration : defaults.duration,
+ delay ? delay : defaults.delay
+ };
+ }
+
+ explicit operator bool() const {
+ return duration || delay;
+ }
};
} // namespace style
diff --git a/include/mbgl/util/color.hpp b/include/mbgl/util/color.hpp
index 4be380fde3..178d0dc758 100644
--- a/include/mbgl/util/color.hpp
+++ b/include/mbgl/util/color.hpp
@@ -2,6 +2,7 @@
#include <mbgl/util/optional.hpp>
+#include <cassert>
#include <string>
namespace mbgl {
@@ -9,6 +10,19 @@ namespace mbgl {
// Stores a premultiplied color, with all four channels ranging from 0..1
class Color {
public:
+ constexpr Color() = default;
+ constexpr Color(float r_, float g_, float b_, float a_)
+ : r(r_), g(g_), b(b_), a(a_) {
+ assert(r_ >= 0.0f);
+ assert(r_ <= 1.0f);
+ assert(g_ >= 0.0f);
+ assert(g_ <= 1.0f);
+ assert(b_ >= 0.0f);
+ assert(b_ <= 1.0f);
+ assert(a_ >= 0.0f);
+ assert(a_ <= 1.0f);
+ }
+
float r = 0.0f;
float g = 0.0f;
float b = 0.0f;
@@ -17,6 +31,10 @@ public:
static constexpr Color black() { return { 0.0f, 0.0f, 0.0f, 1.0f }; };
static constexpr Color white() { return { 1.0f, 1.0f, 1.0f, 1.0f }; };
+ static constexpr Color red() { return { 1.0f, 0.0f, 0.0f, 1.0f }; };
+ static constexpr Color green() { return { 0.0f, 1.0f, 0.0f, 1.0f }; };
+ static constexpr Color blue() { return { 0.0f, 0.0f, 1.0f, 1.0f }; };
+
static optional<Color> parse(const std::string&);
};
@@ -29,6 +47,8 @@ constexpr bool operator!=(const Color& colorA, const Color& colorB) {
}
constexpr Color operator*(const Color& color, float alpha) {
+ assert(alpha >= 0.0f);
+ assert(alpha <= 1.0f);
return {
color.r * alpha,
color.g * alpha,
diff --git a/include/mbgl/util/constants.hpp b/include/mbgl/util/constants.hpp
index e6e9f6e67d..85e19c2ff0 100644
--- a/include/mbgl/util/constants.hpp
+++ b/include/mbgl/util/constants.hpp
@@ -35,6 +35,8 @@ constexpr double DEGREES_MAX = 360;
constexpr double PITCH_MAX = M_PI / 3;
constexpr double MIN_ZOOM = 0.0;
constexpr double MAX_ZOOM = 25.5;
+constexpr float MIN_ZOOM_F = MIN_ZOOM;
+constexpr float MAX_ZOOM_F = MAX_ZOOM;
constexpr uint64_t DEFAULT_MAX_CACHE_SIZE = 50 * 1024 * 1024;
diff --git a/include/mbgl/platform/event.hpp b/include/mbgl/util/event.hpp
index 7ad3d914e8..7ad3d914e8 100644
--- a/include/mbgl/platform/event.hpp
+++ b/include/mbgl/util/event.hpp
diff --git a/include/mbgl/util/exception.hpp b/include/mbgl/util/exception.hpp
index 7c331636d4..46de8528c7 100644
--- a/include/mbgl/util/exception.hpp
+++ b/include/mbgl/util/exception.hpp
@@ -20,10 +20,5 @@ struct MisuseException : Exception {
MisuseException(const std::string &msg) : Exception(msg) {}
};
-struct ShaderException : Exception {
- ShaderException(const char *msg) : Exception(msg) {}
- ShaderException(const std::string &msg) : Exception(msg) {}
-};
-
} // namespace util
} // namespace mbgl
diff --git a/include/mbgl/util/image.hpp b/include/mbgl/util/image.hpp
index 795d1f9d1a..1d84d4824a 100644
--- a/include/mbgl/util/image.hpp
+++ b/include/mbgl/util/image.hpp
@@ -1,6 +1,7 @@
#pragma once
#include <mbgl/util/noncopyable.hpp>
+#include <mbgl/util/size.hpp>
#include <string>
#include <memory>
@@ -8,9 +9,10 @@
namespace mbgl {
-enum ImageAlphaMode {
+enum class ImageAlphaMode {
Unassociated,
- Premultiplied
+ Premultiplied,
+ Exclusive, // Alpha-channel only
};
template <ImageAlphaMode Mode>
@@ -18,44 +20,45 @@ class Image : private util::noncopyable {
public:
Image() = default;
- Image(uint16_t w, uint16_t h)
- : width(w),
- height(h),
- data(std::make_unique<uint8_t[]>(size())) {}
+ Image(Size size_)
+ : size(std::move(size_)),
+ data(std::make_unique<uint8_t[]>(bytes())) {}
- Image(uint16_t w, uint16_t h, std::unique_ptr<uint8_t[]> data_)
- : width(w),
- height(h),
+ Image(Size size_, std::unique_ptr<uint8_t[]> data_)
+ : size(std::move(size_)),
data(std::move(data_)) {}
Image(Image&& o)
- : width(o.width),
- height(o.height),
+ : size(o.size),
data(std::move(o.data)) {}
Image& operator=(Image&& o) {
- width = o.width;
- height = o.height;
+ size = o.size;
data = std::move(o.data);
return *this;
}
bool operator==(const Image& rhs) const {
- return width == rhs.width && height == rhs.height &&
- std::equal(data.get(), data.get() + size(), rhs.data.get(),
- rhs.data.get() + rhs.size());
+ return size == rhs.size &&
+ std::equal(data.get(), data.get() + bytes(), rhs.data.get(),
+ rhs.data.get() + rhs.bytes());
}
- size_t stride() const { return static_cast<size_t>(width) * 4; }
- size_t size() const { return static_cast<size_t>(width) * height * 4; }
+ bool valid() const {
+ return size && data.get() != nullptr;
+ }
+
+ size_t stride() const { return channels * size.width; }
+ size_t bytes() const { return stride() * size.height; }
- uint16_t width = 0;
- uint16_t height = 0;
+ Size size;
+ static constexpr size_t channels = Mode == ImageAlphaMode::Exclusive ? 1 : 4;
std::unique_ptr<uint8_t[]> data;
};
using UnassociatedImage = Image<ImageAlphaMode::Unassociated>;
using PremultipliedImage = Image<ImageAlphaMode::Premultiplied>;
+using AlphaImage = Image<ImageAlphaMode::Exclusive>;
// TODO: don't use std::string for binary data.
PremultipliedImage decodeImage(const std::string&);
diff --git a/include/mbgl/platform/log.hpp b/include/mbgl/util/logging.hpp
index d5bb1c2fcc..d072673e76 100644
--- a/include/mbgl/platform/log.hpp
+++ b/include/mbgl/util/logging.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include <mbgl/platform/event.hpp>
+#include <mbgl/util/event.hpp>
#include <mbgl/util/noncopyable.hpp>
diff --git a/include/mbgl/platform/platform.hpp b/include/mbgl/util/platform.hpp
index cc8327c470..cc8327c470 100644
--- a/include/mbgl/platform/platform.hpp
+++ b/include/mbgl/util/platform.hpp
diff --git a/include/mbgl/util/range.hpp b/include/mbgl/util/range.hpp
index 8da2dd45bb..f7fa92eb8b 100644
--- a/include/mbgl/util/range.hpp
+++ b/include/mbgl/util/range.hpp
@@ -5,7 +5,7 @@ namespace mbgl {
template <class T>
class Range {
public:
- Range(const T& min_, const T& max_)
+ constexpr Range(const T& min_, const T& max_)
: min(min_), max(max_) {}
T min;
diff --git a/include/mbgl/util/size.hpp b/include/mbgl/util/size.hpp
new file mode 100644
index 0000000000..1af85bcff5
--- /dev/null
+++ b/include/mbgl/util/size.hpp
@@ -0,0 +1,32 @@
+#pragma once
+
+#include <cstdint>
+#include <array>
+
+namespace mbgl {
+
+class Size {
+public:
+ constexpr Size() : width(0), height(0) {
+ }
+
+ constexpr Size(const uint32_t width_, const uint32_t height_) : width(width_), height(height_) {
+ }
+
+ constexpr explicit operator bool() const {
+ return width > 0 && height > 0;
+ }
+
+ uint32_t width;
+ uint32_t height;
+};
+
+constexpr inline bool operator==(const Size& a, const Size& b) {
+ return a.width == b.width && a.height == b.height;
+}
+
+constexpr inline bool operator!=(const Size& a, const Size& b) {
+ return !(a == b);
+}
+
+} // namespace mbgl
diff --git a/package.json b/package.json
index 7abe377a47..f99653d184 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "mapbox-gl-native",
- "version": "3.3.3",
+ "version": "3.4.2",
"description": "Renders map tiles with Mapbox GL",
"keywords": [
"mapbox",
@@ -13,7 +13,8 @@
},
"license": "BSD-2-Clause",
"dependencies": {
- "node-pre-gyp": "^0.6.28"
+ "node-pre-gyp": "^0.6.28",
+ "nan": "^2.4.0"
},
"devDependencies": {
"aws-sdk": "^2.3.5",
@@ -21,11 +22,13 @@
"ejs": "^2.4.1",
"express": "^4.11.1",
"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#af9ee275f19e81f839a2733e6906c3fac272620e",
+ "mapbox-gl": "mapbox/mapbox-gl-js#ab836206d415ca3a74257a3066d11a54ab2838cb",
+ "mapbox-gl-style-spec": "mapbox/mapbox-gl-style-spec#49e8b407bdbbe6f7c92dbcb56d3d51f425fc2653",
+ "mapbox-gl-test-suite": "mapbox/mapbox-gl-test-suite#e1ada02a706fd124fc3441fd3a2b3cda67960ff5",
"mkdirp": "^0.5.1",
"node-cmake": "^1.2.1",
+ "pixelmatch": "^4.0.2",
+ "pngjs": "^3.0.0",
"request": "^2.72.0",
"tape": "^4.5.1"
},
diff --git a/platform/android/.gitignore b/platform/android/.gitignore
index b0e8cceb45..81eeaad167 100644
--- a/platform/android/.gitignore
+++ b/platform/android/.gitignore
@@ -30,5 +30,5 @@ fabric.properties
captures/
# Generated test cases
-MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/activity/gen/
+MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/
diff --git a/platform/android/CHANGELOG.md b/platform/android/CHANGELOG.md
index 836e1da7ae..1f4acc43f3 100644
--- a/platform/android/CHANGELOG.md
+++ b/platform/android/CHANGELOG.md
@@ -2,6 +2,20 @@
Mapbox welcomes participation and contributions from everyone. If you'd like to do so please see the [`Contributing Guide`](https://github.com/mapbox/mapbox-gl-native/blob/master/CONTRIBUTING.md) first to get started.
+## 5.0.0 - TBA
+
+* Support for Android Nougat [#5910](5910-move-listener-logic-for-nougat) & [#6390](https://github.com/mapbox/mapbox-gl-native/pull/6390)
+
+## 4.2.0 - December 14, 2016
+
+Mapbox Android 4.2.0 contains all 4.2.0-beta.3 changes and adds:
+
+* Adds additional documentation to APIs
+* Resolved issue with marker views occasionally not showing up until a gesture was performed on map [#7239](https://github.com/mapbox/mapbox-gl-native/pull/7239)
+* Added horizontal accuracy to location events [#7237](https://github.com/mapbox/mapbox-gl-native/pull/7237)
+* Resolved issue with changing visibility of a layer [#7242](https://github.com/mapbox/mapbox-gl-native/pull/7242)
+* Proguard improvement and fixes
+
## 4.2.0-beta.3 - September 21, 2016
Mapbox Android 4.2.0-beta.3 contains all 4.2.0-beta.2 changes and adds:
diff --git a/platform/android/MapboxGLAndroidSDK/build.gradle b/platform/android/MapboxGLAndroidSDK/build.gradle
index 3386bd81aa..b17fa91d04 100644
--- a/platform/android/MapboxGLAndroidSDK/build.gradle
+++ b/platform/android/MapboxGLAndroidSDK/build.gradle
@@ -1,32 +1,16 @@
-apply plugin: 'android-sdk-manager'
apply plugin: 'com.android.library'
-apply plugin: 'checkstyle'
-apply plugin: 'maven'
-apply plugin: 'signing'
-
-allprojects {
- group project.GROUP
- version project.VERSION_NAME
-
- repositories {
- mavenCentral()
- }
-}
-
-repositories {
- mavenCentral()
-}
ext {
- supportLibVersion = '23.4.0'
+ supportLibVersion = '25.0.0'
}
dependencies {
compile "com.android.support:support-annotations:${supportLibVersion}"
compile "com.android.support:support-v4:${supportLibVersion}"
compile "com.android.support:design:${supportLibVersion}"
- compile 'com.squareup.okhttp3:okhttp:3.3.0'
+ compile 'com.squareup.okhttp3:okhttp:3.5.0'
compile 'com.mapzen.android:lost:1.1.1'
+ compile 'com.jakewharton.timber:timber:4.3.1'
// Mapbox Android Services
compile('com.mapbox.mapboxsdk:mapbox-java-services:1.3.1@jar') {
@@ -46,7 +30,13 @@ android {
buildConfigField "String", "GIT_REVISION_SHORT", String.format("\"%s\"", getGitRevision())
}
+ android {
+ // avoid naming conflicts, force usage of prefix
+ resourcePrefix 'mapbox_'
+ }
+
sourceSets {
+ // limit amount of exposed library resources
main.res.srcDirs += 'src/main/res-public'
}
@@ -70,94 +60,13 @@ android {
}
release {
- jniDebuggable false
+ // aar proguard configuration
consumerProguardFiles 'proguard-rules.pro'
+ jniDebuggable false
}
}
}
-configurations {
- all*.exclude group: 'commons-logging', module: 'commons-logging'
- all*.exclude group: 'commons-collections', module: 'commons-collections'
-}
-
-android.libraryVariants.all { variant ->
- def name = variant.name
- //noinspection GroovyAssignabilityCheck
- task "javadoc$name"(type: Javadoc) {
- description = "Generates javadoc for build $name"
- failOnError = false
- destinationDir = new File(destinationDir, variant.baseName)
- source = files(variant.javaCompile.source)
- classpath = files(variant.javaCompile.classpath.files) + files(android.bootClasspath)
- options.windowTitle("Mapbox Android SDK $VERSION_NAME Reference")
- options.docTitle("Mapbox Android SDK $VERSION_NAME")
- options.header("Mapbox Android SDK $VERSION_NAME Reference")
- options.bottom("&copy; 2015&ndash;2016 Mapbox. All rights reserved.")
- options.links("http://docs.oracle.com/javase/7/docs/api/")
- options.linksOffline("http://d.android.com/reference/", "$System.env.ANDROID_HOME/docs/reference")
- options.overview("src/main/java/overview.html")
- options.group("Mapbox Android SDK", "com.mapbox.*")
- options.group("Third Party Libraries", "com.almeros.*")
- exclude '**/R.java', '**/BuildConfig.java', 'com/almeros/**'
- }
-}
-
-/*
-task cleanJNIBuilds {
- def jniLibsDir = new File("MapboxGLAndroidSDK/src/main/jniLibs")
- delete jniLibsDir.absolutePath
-}
-*/
-
-android.libraryVariants.all { variant ->
- def name = variant.buildType.name
- def checkstyle = project.tasks.create "checkstyle${name.capitalize()}", Checkstyle
- checkstyle.dependsOn variant.javaCompile
- checkstyle.source variant.javaCompile.source
- checkstyle.classpath = project.fileTree(variant.javaCompile.destinationDir)
- checkstyle.exclude('**/BuildConfig.java')
- checkstyle.exclude('**/R.java')
- checkstyle.exclude('**/com/almeros/android/multitouch/**')
- project.tasks.getByName("check").dependsOn checkstyle
-}
-
-// From https://raw.github.com/mcxiaoke/gradle-mvn-push/master/jar.gradle
-android.libraryVariants.all { variant ->
- def jarTask = project.tasks.create(name: "jar${variant.name.capitalize()}", type: Jar) {
- from variant.javaCompile.destinationDir
- exclude "**/R.class"
- exclude "**/BuildConfig.class"
- }
- jarTask.dependsOn variant.javaCompile
- artifacts.add('archives', jarTask);
-}
-
-// From https://raw.github.com/mcxiaoke/gradle-mvn-push/master/gradle-mvn-push.gradle
-def isReleaseBuild() {
- return VERSION_NAME.contains("SNAPSHOT") == false
-}
-
-def getReleaseRepositoryUrl() {
- return hasProperty('RELEASE_REPOSITORY_URL') ? RELEASE_REPOSITORY_URL :
- "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
-}
-
-def getSnapshotRepositoryUrl() {
- return hasProperty('SNAPSHOT_REPOSITORY_URL') ? SNAPSHOT_REPOSITORY_URL :
- "https://oss.sonatype.org/content/repositories/snapshots/"
-}
-
-def getRepositoryUsername() {
- return hasProperty('USERNAME') ? USERNAME :
- (hasProperty('NEXUS_USERNAME') ? NEXUS_USERNAME : "")
-}
-
-def getRepositoryPassword() {
- return hasProperty('PASSWORD') ? PASSWORD :
- (hasProperty('NEXUS_PASSWORD') ? NEXUS_PASSWORD : "")
-}
-
def getGitRevision() {
def cmd = "git rev-parse --short HEAD"
def proc = cmd.execute()
@@ -165,121 +74,11 @@ def getGitRevision() {
return ref
}
-task apklib(type: Zip) {
- appendix = extension = 'apklib'
-
- from 'AndroidManifest.xml'
- into('res') {
- from 'res'
- }
- into('src') {
- from 'src'
- }
-}
-
-artifacts {
- archives apklib
-}
-
-afterEvaluate { project ->
- uploadArchives {
- repositories {
- mavenDeployer {
- beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
-
- pom.groupId = GROUP
- pom.artifactId = POM_ARTIFACT_ID
- pom.version = VERSION_NAME
-
- repository(url: getReleaseRepositoryUrl()) {
- authentication(userName: getRepositoryUsername(),
- password: getRepositoryPassword())
- }
- snapshotRepository(url: getSnapshotRepositoryUrl()) {
- authentication(userName: getRepositoryUsername(),
- password: getRepositoryPassword())
- }
-
-/*
- // Leaving out as artifact was incorrectly named when found
- addFilter('aar') { artifact, file ->
- artifact.name == archivesBaseName
- }
- addFilter('apklib') { artifact, file ->
- artifact.name == archivesBaseName + '-apklib'
- }
-*/
-
- pom.project {
- name POM_NAME
- packaging POM_PACKAGING
- description POM_DESCRIPTION
- url POM_URL
-
- scm {
- url POM_SCM_URL
- connection POM_SCM_CONNECTION
- developerConnection POM_SCM_DEV_CONNECTION
- }
-
- licenses {
- license {
- name POM_LICENCE_NAME
- url POM_LICENCE_URL
- distribution POM_LICENCE_DIST
- }
- }
-
- developers {
- developer {
- id POM_DEVELOPER_ID
- name POM_DEVELOPER_NAME
- }
- }
- }
- }
- }
- }
-
- signing {
- required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") }
- sign configurations.archives
- }
-
- task androidJavadocs(type: Javadoc) {
- source = android.sourceSets.main.java.sourceFiles
- classpath = files(android.bootClasspath)
- }
-
- task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
- classifier = 'javadoc'
- from androidJavadocs.destinationDir
- }
-
- task androidSourcesJar(type: Jar) {
- classifier = 'sources'
- from android.sourceSets.main.java.sourceFiles
- }
-
- artifacts {
- archives androidSourcesJar
- archives androidJavadocsJar
- }
-}
-
-
-task makeClean(type: Exec) {
- workingDir '../../'
- commandLine 'make', 'clean'
-}
-
-task makeAndroid(type: Exec) {
- workingDir '../../'
- commandLine 'make', 'android'
-}
-
-task makeAndroidAll(type: Exec) {
- workingDir '../../'
- commandLine 'make', 'apackage'
+configurations {
+ all*.exclude group: 'commons-logging', module: 'commons-logging'
+ all*.exclude group: 'commons-collections', module: 'commons-collections'
}
+apply from: 'gradle-javadoc.gradle'
+apply from: 'gradle-publish.gradle'
+apply from: 'gradle-checkstyle.gradle' \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/deploy.sh b/platform/android/MapboxGLAndroidSDK/deploy.sh
deleted file mode 100755
index c9392201e4..0000000000
--- a/platform/android/MapboxGLAndroidSDK/deploy.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/usr/bin/env bash
-../gradlew -b build.gradle clean assembleRelease uploadArchives
diff --git a/platform/android/MapboxGLAndroidSDK/gradle-checkstyle.gradle b/platform/android/MapboxGLAndroidSDK/gradle-checkstyle.gradle
new file mode 100644
index 0000000000..cdcc7f1e23
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/gradle-checkstyle.gradle
@@ -0,0 +1,17 @@
+apply plugin: 'checkstyle'
+
+checkstyle {
+ toolVersion = "7.1.1" // 7.3
+ configFile = "../checkstyle.xml" as File
+}
+
+task checkstyle(type: Checkstyle) {
+ description 'Checks if the code adheres to coding standards'
+ group 'verification'
+ configFile file("../checkstyle.xml")
+ source 'src'
+ include '**/*.java'
+ exclude '**/gen/**'
+ classpath = files()
+ ignoreFailures = false
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/gradle-javadoc.gradle b/platform/android/MapboxGLAndroidSDK/gradle-javadoc.gradle
new file mode 100644
index 0000000000..00d96365ec
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/gradle-javadoc.gradle
@@ -0,0 +1,21 @@
+android.libraryVariants.all { variant ->
+ def name = variant.name
+ //noinspection GroovyAssignabilityCheck
+ task "javadoc$name"(type: Javadoc) {
+ description = "Generates javadoc for build $name"
+ failOnError = false
+ destinationDir = new File(destinationDir, variant.baseName)
+ source = files(variant.javaCompile.source)
+ classpath = files(variant.javaCompile.classpath.files) + files(android.bootClasspath)
+ options.windowTitle("Mapbox Android SDK $VERSION_NAME Reference")
+ options.docTitle("Mapbox Android SDK $VERSION_NAME")
+ options.header("Mapbox Android SDK $VERSION_NAME Reference")
+ options.bottom("&copy; 2015&ndash;2016 Mapbox. All rights reserved.")
+ options.links("http://docs.oracle.com/javase/7/docs/api/")
+ options.linksOffline("http://d.android.com/reference/", "$System.env.ANDROID_HOME/docs/reference")
+ options.overview("src/main/java/overview.html")
+ options.group("Mapbox Android SDK", "com.mapbox.*")
+ options.group("Third Party Libraries", "com.almeros.*")
+ exclude '**/R.java', '**/BuildConfig.java', 'com/almeros/**'
+ }
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/gradle-publish.gradle b/platform/android/MapboxGLAndroidSDK/gradle-publish.gradle
new file mode 100644
index 0000000000..f017434fac
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/gradle-publish.gradle
@@ -0,0 +1,153 @@
+apply plugin: 'maven'
+apply plugin: 'signing'
+
+allprojects {
+ group project.GROUP
+ version project.VERSION_NAME
+
+ repositories {
+ mavenCentral()
+ }
+}
+
+repositories {
+ mavenCentral()
+}
+
+// From https://raw.github.com/mcxiaoke/gradle-mvn-push/master/jar.gradle
+android.libraryVariants.all { variant ->
+ def jarTask = project.tasks.create(name: "jar${variant.name.capitalize()}", type: Jar) {
+ from variant.javaCompile.destinationDir
+ exclude "**/R.class"
+ exclude "**/BuildConfig.class"
+ }
+ jarTask.dependsOn variant.javaCompile
+ artifacts.add('archives', jarTask);
+}
+
+// From https://raw.github.com/mcxiaoke/gradle-mvn-push/master/gradle-mvn-push.gradle
+def isReleaseBuild() {
+ return VERSION_NAME.contains("SNAPSHOT") == false
+}
+
+def getReleaseRepositoryUrl() {
+ return hasProperty('RELEASE_REPOSITORY_URL') ? RELEASE_REPOSITORY_URL :
+ "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
+}
+
+def getSnapshotRepositoryUrl() {
+ return hasProperty('SNAPSHOT_REPOSITORY_URL') ? SNAPSHOT_REPOSITORY_URL :
+ "https://oss.sonatype.org/content/repositories/snapshots/"
+}
+
+def getRepositoryUsername() {
+ return hasProperty('USERNAME') ? USERNAME :
+ (hasProperty('NEXUS_USERNAME') ? NEXUS_USERNAME : "")
+}
+
+def getRepositoryPassword() {
+ return hasProperty('PASSWORD') ? PASSWORD :
+ (hasProperty('NEXUS_PASSWORD') ? NEXUS_PASSWORD : "")
+}
+
+task apklib(type: Zip) {
+ appendix = extension = 'apklib'
+
+ from 'AndroidManifest.xml'
+ into('res') {
+ from 'res'
+ }
+ into('src') {
+ from 'src'
+ }
+}
+
+artifacts {
+ archives apklib
+}
+
+afterEvaluate { project ->
+ uploadArchives {
+ repositories {
+ mavenDeployer {
+ beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
+
+ pom.groupId = GROUP
+ pom.artifactId = POM_ARTIFACT_ID
+ pom.version = VERSION_NAME
+
+ repository(url: getReleaseRepositoryUrl()) {
+ authentication(userName: getRepositoryUsername(),
+ password: getRepositoryPassword())
+ }
+ snapshotRepository(url: getSnapshotRepositoryUrl()) {
+ authentication(userName: getRepositoryUsername(),
+ password: getRepositoryPassword())
+ }
+
+/*
+ // Leaving out as artifact was incorrectly named when found
+ addFilter('aar') { artifact, file ->
+ artifact.name == archivesBaseName
+ }
+ addFilter('apklib') { artifact, file ->
+ artifact.name == archivesBaseName + '-apklib'
+ }
+*/
+
+ pom.project {
+ name POM_NAME
+ packaging POM_PACKAGING
+ description POM_DESCRIPTION
+ url POM_URL
+
+ scm {
+ url POM_SCM_URL
+ connection POM_SCM_CONNECTION
+ developerConnection POM_SCM_DEV_CONNECTION
+ }
+
+ licenses {
+ license {
+ name POM_LICENCE_NAME
+ url POM_LICENCE_URL
+ distribution POM_LICENCE_DIST
+ }
+ }
+
+ developers {
+ developer {
+ id POM_DEVELOPER_ID
+ name POM_DEVELOPER_NAME
+ }
+ }
+ }
+ }
+ }
+ }
+
+ signing {
+ required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") }
+ sign configurations.archives
+ }
+
+ task androidJavadocs(type: Javadoc) {
+ source = android.sourceSets.main.java.sourceFiles
+ classpath = files(android.bootClasspath)
+ }
+
+ task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
+ classifier = 'javadoc'
+ from androidJavadocs.destinationDir
+ }
+
+ task androidSourcesJar(type: Jar) {
+ classifier = 'sources'
+ from android.sourceSets.main.java.sourceFiles
+ }
+
+ artifacts {
+ archives androidSourcesJar
+ archives androidJavadocsJar
+ }
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/gradle.properties b/platform/android/MapboxGLAndroidSDK/gradle.properties
index 6aab985298..b0fdcea7f7 100644
--- a/platform/android/MapboxGLAndroidSDK/gradle.properties
+++ b/platform/android/MapboxGLAndroidSDK/gradle.properties
@@ -1,5 +1,5 @@
GROUP=com.mapbox.mapboxsdk
-VERSION_NAME=4.2.0-SNAPSHOT
+VERSION_NAME=5.0.0-SNAPSHOT
POM_DESCRIPTION=Mapbox GL Android SDK
POM_URL=https://github.com/mapbox/mapbox-gl-native
@@ -13,9 +13,9 @@ POM_DEVELOPER_ID=mapbox
POM_DEVELOPER_NAME=Mapbox
ANDROID_MIN_SDK=15
-ANDROID_BUILD_TARGET_SDK_VERSION=23
-ANDROID_BUILD_TOOLS_VERSION=23.0.3
-ANDROID_BUILD_SDK_VERSION=23
+ANDROID_BUILD_TARGET_SDK_VERSION=25
+ANDROID_BUILD_TOOLS_VERSION=25.0.0
+ANDROID_BUILD_SDK_VERSION=25
POM_NAME=Mapbox Android SDK
POM_ARTIFACT_ID=mapbox-android-sdk
diff --git a/platform/android/MapboxGLAndroidSDK/proguard-rules.pro b/platform/android/MapboxGLAndroidSDK/proguard-rules.pro
index 96f7bb95f3..92ef05df68 100644
--- a/platform/android/MapboxGLAndroidSDK/proguard-rules.pro
+++ b/platform/android/MapboxGLAndroidSDK/proguard-rules.pro
@@ -5,6 +5,7 @@
# Square okio, ignoring warnings,
# see https://github.com/square/okio/issues/60
+-dontwarn okhttp3.**
-dontwarn okio.**
# Gesture package
@@ -38,7 +39,48 @@
# Package telemetry
-keep class com.mapbox.mapboxsdk.telemetry.** { *; }
-# Keep external project mapbox-java,
-# Needs to be removed after https://github.com/mapbox/mapbox-java/issues/178 is resolved
--keep class com.mapbox.services.** { *; }
+#
+# Mapbox-java Proguard rules
+# We include these rules since libjava is a Jar file not AAR
+#
+# Retrofit 2
+# Platform calls Class.forName on types which do not exist on Android to determine platform.
+-dontnote retrofit2.Platform
+# Platform used when running on RoboVM on iOS. Will not be used at runtime.
+-dontnote retrofit2.Platform$IOS$MainThreadExecutor
+# Platform used when running on Java 8 VMs. Will not be used at runtime.
+-dontwarn retrofit2.Platform$Java8
+# Retain generic type information for use by reflection by converters and adapters.
+-keepattributes Signature
+# Retain declared checked exceptions for use by a Proxy instance.
+-keepattributes Exceptions
+
+# For using GSON @Expose annotation
+-keepattributes *Annotation*
+# Gson specific classes
+-dontwarn sun.misc.**
+
+# Prevent proguard from stripping interface information from TypeAdapterFactory,
+# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
+-keep class * implements com.google.gson.TypeAdapterFactory
+-keep class * implements com.google.gson.JsonSerializer
+-keep class * implements com.google.gson.JsonDeserializer
+
+# MAS Data Models
+-keep class com.mapbox.services.commons.geojson.** { *; }
+-keep class com.mapbox.services.mapmatching.v4.models.** { *; }
+-keep class com.mapbox.services.distance.v1.models.** { *; }
+-keep class com.mapbox.services.directions.v4.models.** { *; }
+-keep class com.mapbox.services.directions.v5.models.** { *; }
+-keep class com.mapbox.services.geocoding.v5.models.** { *; }
+
+-dontwarn javax.annotation.**
+
+-keepclassmembers class rx.internal.util.unsafe.** {
+ long producerIndex;
+ long consumerIndex;
+}
+
+-keep class com.google.** { *; }
+-dontwarn com.google.** \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/BaseGestureDetector.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/BaseGestureDetector.java
index 622e8f759c..b7bcb925a1 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/BaseGestureDetector.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/BaseGestureDetector.java
@@ -6,19 +6,19 @@ import android.view.MotionEvent;
/**
* @author Almer Thie (code.almeros.com) Copyright (c) 2013, Almer Thie
* (code.almeros.com)
- *
+ * <p>
* All rights reserved.
- *
+ * <p>
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- *
+ * <p>
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- *
+ * <p>
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -33,129 +33,128 @@ import android.view.MotionEvent;
* POSSIBILITY OF SUCH DAMAGE.
*/
public abstract class BaseGestureDetector {
- protected final Context mContext;
- protected boolean mGestureInProgress;
-
- protected MotionEvent mPrevEvent;
- protected MotionEvent mCurrEvent;
-
- protected float mCurrPressure;
- protected float mPrevPressure;
- protected long mTimeDelta;
-
- /**
- * This value is the threshold ratio between the previous combined pressure
- * and the current combined pressure. When pressure decreases rapidly
- * between events the position values can often be imprecise, as it usually
- * indicates that the user is in the process of lifting a pointer off of the
- * device. This value was tuned experimentally.
- */
- protected static final float PRESSURE_THRESHOLD = 0.67f;
-
- public BaseGestureDetector(Context context) {
- mContext = context;
+ protected final Context context;
+ protected boolean gestureInProgress;
+
+ protected MotionEvent prevEvent;
+ protected MotionEvent currEvent;
+
+ protected float currPressure;
+ protected float prevPressure;
+ protected long timeDelta;
+
+ /**
+ * This value is the threshold ratio between the previous combined pressure
+ * and the current combined pressure. When pressure decreases rapidly
+ * between events the position values can often be imprecise, as it usually
+ * indicates that the user is in the process of lifting a pointer off of the
+ * device. This value was tuned experimentally.
+ */
+ protected static final float PRESSURE_THRESHOLD = 0.67f;
+
+ public BaseGestureDetector(Context context) {
+ this.context = context;
+ }
+
+ /**
+ * All gesture detectors need to be called through this method to be able to
+ * detect gestures. This method delegates work to handler methods
+ * (handleStartProgressEvent, handleInProgressEvent) implemented in
+ * extending classes.
+ *
+ * @param event MotionEvent
+ * @return {@code true} as handled
+ */
+ public boolean onTouchEvent(MotionEvent event) {
+ final int actionCode = event.getAction() & MotionEvent.ACTION_MASK;
+ if (!gestureInProgress) {
+ handleStartProgressEvent(actionCode, event);
+ } else {
+ handleInProgressEvent(actionCode, event);
}
-
- /**
- * All gesture detectors need to be called through this method to be able to
- * detect gestures. This method delegates work to handler methods
- * (handleStartProgressEvent, handleInProgressEvent) implemented in
- * extending classes.
- *
- * @param event MotionEvent
- * @return {@code true} as handled
- */
- public boolean onTouchEvent(MotionEvent event) {
- final int actionCode = event.getAction() & MotionEvent.ACTION_MASK;
- if (!mGestureInProgress) {
- handleStartProgressEvent(actionCode, event);
- } else {
- handleInProgressEvent(actionCode, event);
- }
- return true;
- }
-
- /**
- * Called when the current event occurred when NO gesture is in progress
- * yet. The handling in this implementation may set the gesture in progress
- * (via mGestureInProgress) or out of progress
- *
- * @param actionCode Action Code from MotionEvent
- * @param event MotionEvent
- */
- protected abstract void handleStartProgressEvent(int actionCode,
- MotionEvent event);
-
- /**
- * Called when the current event occurred when a gesture IS in progress. The
- * handling in this implementation may set the gesture out of progress (via
- * mGestureInProgress).
- *
- *
- * @param actionCode Action Code from MotionEvent
- * @param event MotionEvent
- */
- protected abstract void handleInProgressEvent(int actionCode,
- MotionEvent event);
-
- protected void updateStateByEvent(MotionEvent curr) {
- final MotionEvent prev = mPrevEvent;
-
- // Reset mCurrEvent
- if (mCurrEvent != null) {
- mCurrEvent.recycle();
- mCurrEvent = null;
- }
- mCurrEvent = MotionEvent.obtain(curr);
-
- // Delta time
- mTimeDelta = curr.getEventTime() - prev.getEventTime();
-
- // Pressure
- mCurrPressure = curr.getPressure(curr.getActionIndex());
- mPrevPressure = prev.getPressure(prev.getActionIndex());
+ return true;
+ }
+
+ /**
+ * Called when the current event occurred when NO gesture is in progress
+ * yet. The handling in this implementation may set the gesture in progress
+ * (via gestureInProgress) or out of progress
+ *
+ * @param actionCode Action Code from MotionEvent
+ * @param event MotionEvent
+ */
+ protected abstract void handleStartProgressEvent(int actionCode,
+ MotionEvent event);
+
+ /**
+ * Called when the current event occurred when a gesture IS in progress. The
+ * handling in this implementation may set the gesture out of progress (via
+ * gestureInProgress).
+ *
+ * @param actionCode Action Code from MotionEvent
+ * @param event MotionEvent
+ */
+ protected abstract void handleInProgressEvent(int actionCode,
+ MotionEvent event);
+
+ protected void updateStateByEvent(MotionEvent curr) {
+ final MotionEvent prev = prevEvent;
+
+ // Reset currEvent
+ if (currEvent != null) {
+ currEvent.recycle();
+ currEvent = null;
}
+ currEvent = MotionEvent.obtain(curr);
- protected void resetState() {
- if (mPrevEvent != null) {
- mPrevEvent.recycle();
- mPrevEvent = null;
- }
- if (mCurrEvent != null) {
- mCurrEvent.recycle();
- mCurrEvent = null;
- }
- mGestureInProgress = false;
- }
+ // Delta time
+ timeDelta = curr.getEventTime() - prev.getEventTime();
- /**
- * Returns {@code true} if a gesture is currently in progress.
- *
- * @return {@code true} if a gesture is currently in progress, {@code false}
- * otherwise.
- */
- public boolean isInProgress() {
- return mGestureInProgress;
- }
+ // Pressure
+ currPressure = curr.getPressure(curr.getActionIndex());
+ prevPressure = prev.getPressure(prev.getActionIndex());
+ }
- /**
- * Return the time difference in milliseconds between the previous accepted
- * GestureDetector event and the current GestureDetector event.
- *
- * @return Time difference since the last move event in milliseconds.
- */
- public long getTimeDelta() {
- return mTimeDelta;
+ protected void resetState() {
+ if (prevEvent != null) {
+ prevEvent.recycle();
+ prevEvent = null;
}
-
- /**
- * Return the event time of the current GestureDetector event being
- * processed.
- *
- * @return Current GestureDetector event time in milliseconds.
- */
- public long getEventTime() {
- return mCurrEvent.getEventTime();
+ if (currEvent != null) {
+ currEvent.recycle();
+ currEvent = null;
}
+ gestureInProgress = false;
+ }
+
+ /**
+ * Returns {@code true} if a gesture is currently in progress.
+ *
+ * @return {@code true} if a gesture is currently in progress, {@code false}
+ * otherwise.
+ */
+ public boolean isInProgress() {
+ return gestureInProgress;
+ }
+
+ /**
+ * Return the time difference in milliseconds between the previous accepted
+ * GestureDetector event and the current GestureDetector event.
+ *
+ * @return Time difference since the last move event in milliseconds.
+ */
+ public long getTimeDelta() {
+ return timeDelta;
+ }
+
+ /**
+ * Return the event time of the current GestureDetector event being
+ * processed.
+ *
+ * @return Current GestureDetector event time in milliseconds.
+ */
+ public long getEventTime() {
+ return currEvent.getEventTime();
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/MoveGestureDetector.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/MoveGestureDetector.java
index 2430f3f920..bc7dda6159 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/MoveGestureDetector.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/MoveGestureDetector.java
@@ -7,19 +7,19 @@ import android.view.MotionEvent;
/**
* @author Almer Thie (code.almeros.com) Copyright (c) 2013, Almer Thie
* (code.almeros.com)
- *
+ * <p>
* All rights reserved.
- *
+ * <p>
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- *
+ * <p>
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- *
+ * <p>
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -35,151 +35,151 @@ import android.view.MotionEvent;
*/
public class MoveGestureDetector extends BaseGestureDetector {
- /**
- * Listener which must be implemented which is used by MoveGestureDetector
- * to perform callbacks to any implementing class which is registered to a
- * MoveGestureDetector via the constructor.
- *
- * @see MoveGestureDetector.SimpleOnMoveGestureListener
- */
- public interface OnMoveGestureListener {
- public boolean onMove(MoveGestureDetector detector);
-
- public boolean onMoveBegin(MoveGestureDetector detector);
-
- public void onMoveEnd(MoveGestureDetector detector);
+ /**
+ * Listener which must be implemented which is used by MoveGestureDetector
+ * to perform callbacks to any implementing class which is registered to a
+ * MoveGestureDetector via the constructor.
+ *
+ * @see MoveGestureDetector.SimpleOnMoveGestureListener
+ */
+ public interface OnMoveGestureListener {
+ public boolean onMove(MoveGestureDetector detector);
+
+ public boolean onMoveBegin(MoveGestureDetector detector);
+
+ public void onMoveEnd(MoveGestureDetector detector);
+ }
+
+ /**
+ * Helper class which may be extended and where the methods may be
+ * implemented. This way it is not necessary to implement all methods of
+ * OnMoveGestureListener.
+ */
+ public static class SimpleOnMoveGestureListener implements
+ OnMoveGestureListener {
+ public boolean onMove(MoveGestureDetector detector) {
+ return false;
}
- /**
- * Helper class which may be extended and where the methods may be
- * implemented. This way it is not necessary to implement all methods of
- * OnMoveGestureListener.
- */
- public static class SimpleOnMoveGestureListener implements
- OnMoveGestureListener {
- public boolean onMove(MoveGestureDetector detector) {
- return false;
- }
-
- public boolean onMoveBegin(MoveGestureDetector detector) {
- return true;
- }
+ public boolean onMoveBegin(MoveGestureDetector detector) {
+ return true;
+ }
- public void onMoveEnd(MoveGestureDetector detector) {
- // Do nothing, overridden implementation may be used
- }
+ public void onMoveEnd(MoveGestureDetector detector) {
+ // Do nothing, overridden implementation may be used
}
+ }
- private static final PointF FOCUS_DELTA_ZERO = new PointF();
+ private static final PointF FOCUS_DELTA_ZERO = new PointF();
- private final OnMoveGestureListener mListener;
+ private final OnMoveGestureListener listener;
- private PointF mFocusExternal = new PointF();
- private PointF mFocusDeltaExternal = new PointF();
+ private PointF focusExternal = new PointF();
+ private PointF focusDeltaExternal = new PointF();
- public MoveGestureDetector(Context context, OnMoveGestureListener listener) {
- super(context);
- mListener = listener;
- }
+ public MoveGestureDetector(Context context, OnMoveGestureListener listener) {
+ super(context);
+ this.listener = listener;
+ }
- @Override
- protected void handleStartProgressEvent(int actionCode, MotionEvent event) {
- switch (actionCode) {
- case MotionEvent.ACTION_DOWN:
- resetState(); // In case we missed an UP/CANCEL event
+ @Override
+ protected void handleStartProgressEvent(int actionCode, MotionEvent event) {
+ switch (actionCode) {
+ case MotionEvent.ACTION_DOWN:
+ resetState(); // In case we missed an UP/CANCEL event
- mPrevEvent = MotionEvent.obtain(event);
- mTimeDelta = 0;
+ prevEvent = MotionEvent.obtain(event);
+ timeDelta = 0;
- updateStateByEvent(event);
- break;
+ updateStateByEvent(event);
+ break;
- case MotionEvent.ACTION_MOVE:
- mGestureInProgress = mListener.onMoveBegin(this);
- break;
- }
+ case MotionEvent.ACTION_MOVE:
+ gestureInProgress = listener.onMoveBegin(this);
+ break;
}
-
- @Override
- protected void handleInProgressEvent(int actionCode, MotionEvent event) {
- switch (actionCode) {
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- mListener.onMoveEnd(this);
- resetState();
- break;
-
- case MotionEvent.ACTION_MOVE:
- updateStateByEvent(event);
-
- // Only accept the event if our relative pressure is within
- // a certain limit. This can help filter shaky data as a
- // finger is lifted.
- if (mCurrPressure / mPrevPressure > PRESSURE_THRESHOLD) {
- final boolean updatePrevious = mListener.onMove(this);
- if (updatePrevious) {
- mPrevEvent.recycle();
- mPrevEvent = MotionEvent.obtain(event);
- }
- }
- break;
+ }
+
+ @Override
+ protected void handleInProgressEvent(int actionCode, MotionEvent event) {
+ switch (actionCode) {
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ listener.onMoveEnd(this);
+ resetState();
+ break;
+
+ case MotionEvent.ACTION_MOVE:
+ updateStateByEvent(event);
+
+ // Only accept the event if our relative pressure is within
+ // a certain limit. This can help filter shaky data as a
+ // finger is lifted.
+ if (currPressure / prevPressure > PRESSURE_THRESHOLD) {
+ final boolean updatePrevious = listener.onMove(this);
+ if (updatePrevious) {
+ prevEvent.recycle();
+ prevEvent = MotionEvent.obtain(event);
+ }
}
+ break;
}
-
- protected void updateStateByEvent(MotionEvent curr) {
- super.updateStateByEvent(curr);
-
- final MotionEvent prev = mPrevEvent;
-
- // Focus intenal
- PointF mCurrFocusInternal = determineFocalPoint(curr);
- PointF mPrevFocusInternal = determineFocalPoint(prev);
-
- // Focus external
- // - Prevent skipping of focus delta when a finger is added or removed
- boolean mSkipNextMoveEvent = prev.getPointerCount() != curr
- .getPointerCount();
- mFocusDeltaExternal = mSkipNextMoveEvent ? FOCUS_DELTA_ZERO
- : new PointF(mCurrFocusInternal.x - mPrevFocusInternal.x,
- mCurrFocusInternal.y - mPrevFocusInternal.y);
-
- // - Don't directly use mFocusInternal (or skipping will occur). Add
- // unskipped delta values to mFocusExternal instead.
- mFocusExternal.x += mFocusDeltaExternal.x;
- mFocusExternal.y += mFocusDeltaExternal.y;
+ }
+
+ protected void updateStateByEvent(MotionEvent curr) {
+ super.updateStateByEvent(curr);
+
+ final MotionEvent prev = prevEvent;
+
+ // Focus intenal
+ PointF currFocusInternal = determineFocalPoint(curr);
+ PointF prevFocusInternal = determineFocalPoint(prev);
+
+ // Focus external
+ // - Prevent skipping of focus delta when a finger is added or removed
+ boolean skipNextMoveEvent = prev.getPointerCount() != curr
+ .getPointerCount();
+ focusDeltaExternal = skipNextMoveEvent ? FOCUS_DELTA_ZERO
+ : new PointF(currFocusInternal.x - prevFocusInternal.x,
+ currFocusInternal.y - prevFocusInternal.y);
+
+ // - Don't directly use mFocusInternal (or skipping will occur). Add
+ // unskipped delta values to focusExternal instead.
+ focusExternal.x += focusDeltaExternal.x;
+ focusExternal.y += focusDeltaExternal.y;
+ }
+
+ /**
+ * Determine (multi)finger focal point (a.k.a. center point between all
+ * fingers)
+ *
+ * @param motionEvent a {@link MotionEvent} object.
+ * @return PointF focal point
+ */
+ private PointF determineFocalPoint(MotionEvent motionEvent) {
+ // Number of fingers on screen
+ final int pCount = motionEvent.getPointerCount();
+ float x = 0.0f;
+ float y = 0.0f;
+
+ for (int i = 0; i < pCount; i++) {
+ x += motionEvent.getX(i);
+ y += motionEvent.getY(i);
}
- /**
- * Determine (multi)finger focal point (a.k.a. center point between all
- * fingers)
- *
- * @param e
- * @return PointF focal point
- */
- private PointF determineFocalPoint(MotionEvent e) {
- // Number of fingers on screen
- final int pCount = e.getPointerCount();
- float x = 0.0f;
- float y = 0.0f;
-
- for (int i = 0; i < pCount; i++) {
- x += e.getX(i);
- y += e.getY(i);
- }
-
- return new PointF(x / pCount, y / pCount);
- }
+ return new PointF(x / pCount, y / pCount);
+ }
- public float getFocusX() {
- return mFocusExternal.x;
- }
+ public float getFocusX() {
+ return focusExternal.x;
+ }
- public float getFocusY() {
- return mFocusExternal.y;
- }
+ public float getFocusY() {
+ return focusExternal.y;
+ }
- public PointF getFocusDelta() {
- return mFocusDeltaExternal;
- }
+ public PointF getFocusDelta() {
+ return focusDeltaExternal;
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/RotateGestureDetector.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/RotateGestureDetector.java
index 124fe8509c..8c111a68df 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/RotateGestureDetector.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/RotateGestureDetector.java
@@ -6,19 +6,19 @@ import android.view.MotionEvent;
/**
* @author Almer Thie (code.almeros.com) Copyright (c) 2013, Almer Thie
* (code.almeros.com)
- *
+ * <p>
* All rights reserved.
- *
+ * <p>
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- *
+ * <p>
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- *
+ * <p>
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,147 +34,147 @@ import android.view.MotionEvent;
*/
public class RotateGestureDetector extends TwoFingerGestureDetector {
- /**
- * Listener which must be implemented which is used by RotateGestureDetector
- * to perform callbacks to any implementing class which is registered to a
- * RotateGestureDetector via the constructor.
- *
- * @see RotateGestureDetector.SimpleOnRotateGestureListener
- */
- public interface OnRotateGestureListener {
- public boolean onRotate(RotateGestureDetector detector);
-
- public boolean onRotateBegin(RotateGestureDetector detector);
+ /**
+ * Listener which must be implemented which is used by RotateGestureDetector
+ * to perform callbacks to any implementing class which is registered to a
+ * RotateGestureDetector via the constructor.
+ *
+ * @see RotateGestureDetector.SimpleOnRotateGestureListener
+ */
+ public interface OnRotateGestureListener {
+ public boolean onRotate(RotateGestureDetector detector);
+
+ public boolean onRotateBegin(RotateGestureDetector detector);
+
+ public void onRotateEnd(RotateGestureDetector detector);
+ }
+
+ /**
+ * Helper class which may be extended and where the methods may be
+ * implemented. This way it is not necessary to implement all methods of
+ * OnRotateGestureListener.
+ */
+ public static class SimpleOnRotateGestureListener implements
+ OnRotateGestureListener {
+ public boolean onRotate(RotateGestureDetector detector) {
+ return false;
+ }
- public void onRotateEnd(RotateGestureDetector detector);
+ public boolean onRotateBegin(RotateGestureDetector detector) {
+ return true;
}
- /**
- * Helper class which may be extended and where the methods may be
- * implemented. This way it is not necessary to implement all methods of
- * OnRotateGestureListener.
- */
- public static class SimpleOnRotateGestureListener implements
- OnRotateGestureListener {
- public boolean onRotate(RotateGestureDetector detector) {
- return false;
+ public void onRotateEnd(RotateGestureDetector detector) {
+ // Do nothing, overridden implementation may be used
+ }
+ }
+
+ private final OnRotateGestureListener listener;
+ private boolean sloppyGesture;
+
+ public RotateGestureDetector(Context context,
+ OnRotateGestureListener listener) {
+ super(context);
+ this.listener = listener;
+ }
+
+ @Override
+ protected void handleStartProgressEvent(int actionCode, MotionEvent event) {
+ switch (actionCode) {
+ case MotionEvent.ACTION_POINTER_DOWN:
+ // At least the second finger is on screen now
+
+ resetState(); // In case we missed an UP/CANCEL event
+ prevEvent = MotionEvent.obtain(event);
+ timeDelta = 0;
+
+ updateStateByEvent(event);
+
+ // See if we have a sloppy gesture
+ sloppyGesture = isSloppyGesture(event);
+ if (!sloppyGesture) {
+ // No, start gesture now
+ gestureInProgress = listener.onRotateBegin(this);
}
+ break;
- public boolean onRotateBegin(RotateGestureDetector detector) {
- return true;
+ case MotionEvent.ACTION_MOVE:
+ if (!sloppyGesture) {
+ break;
}
- public void onRotateEnd(RotateGestureDetector detector) {
- // Do nothing, overridden implementation may be used
+ // See if we still have a sloppy gesture
+ sloppyGesture = isSloppyGesture(event);
+ if (!sloppyGesture) {
+ // No, start normal gesture now
+ gestureInProgress = listener.onRotateBegin(this);
}
- }
- private final OnRotateGestureListener mListener;
- private boolean mSloppyGesture;
+ break;
- public RotateGestureDetector(Context context,
- OnRotateGestureListener listener) {
- super(context);
- mListener = listener;
- }
-
- @Override
- protected void handleStartProgressEvent(int actionCode, MotionEvent event) {
- switch (actionCode) {
- case MotionEvent.ACTION_POINTER_DOWN:
- // At least the second finger is on screen now
-
- resetState(); // In case we missed an UP/CANCEL event
- mPrevEvent = MotionEvent.obtain(event);
- mTimeDelta = 0;
-
- updateStateByEvent(event);
-
- // See if we have a sloppy gesture
- mSloppyGesture = isSloppyGesture(event);
- if (!mSloppyGesture) {
- // No, start gesture now
- mGestureInProgress = mListener.onRotateBegin(this);
- }
- break;
-
- case MotionEvent.ACTION_MOVE:
- if (!mSloppyGesture) {
- break;
- }
-
- // See if we still have a sloppy gesture
- mSloppyGesture = isSloppyGesture(event);
- if (!mSloppyGesture) {
- // No, start normal gesture now
- mGestureInProgress = mListener.onRotateBegin(this);
- }
-
- break;
-
- case MotionEvent.ACTION_POINTER_UP:
- if (!mSloppyGesture) {
- break;
- }
-
- break;
+ case MotionEvent.ACTION_POINTER_UP:
+ if (!sloppyGesture) {
+ break;
}
+
+ break;
}
+ }
- @Override
- protected void handleInProgressEvent(int actionCode, MotionEvent event) {
- switch (actionCode) {
- case MotionEvent.ACTION_POINTER_UP:
- // Gesture ended but
- updateStateByEvent(event);
-
- if (!mSloppyGesture) {
- mListener.onRotateEnd(this);
- }
-
- resetState();
- break;
-
- case MotionEvent.ACTION_CANCEL:
- if (!mSloppyGesture) {
- mListener.onRotateEnd(this);
- }
-
- resetState();
- break;
-
- case MotionEvent.ACTION_MOVE:
- updateStateByEvent(event);
-
- // Only accept the event if our relative pressure is within
- // a certain limit. This can help filter shaky data as a
- // finger is lifted.
- if (mCurrPressure / mPrevPressure > PRESSURE_THRESHOLD) {
- final boolean updatePrevious = mListener.onRotate(this);
- if (updatePrevious) {
- mPrevEvent.recycle();
- mPrevEvent = MotionEvent.obtain(event);
- }
- }
- break;
+ @Override
+ protected void handleInProgressEvent(int actionCode, MotionEvent event) {
+ switch (actionCode) {
+ case MotionEvent.ACTION_POINTER_UP:
+ // Gesture ended but
+ updateStateByEvent(event);
+
+ if (!sloppyGesture) {
+ listener.onRotateEnd(this);
}
- }
- @Override
- protected void resetState() {
- super.resetState();
- mSloppyGesture = false;
- }
+ resetState();
+ break;
- /**
- * Return the rotation difference from the previous rotate event to the
- * current event.
- *
- * @return The current rotation //difference in degrees.
- */
- public float getRotationDegreesDelta() {
- double diffRadians = Math.atan2(mPrevFingerDiffY, mPrevFingerDiffX)
- - Math.atan2(mCurrFingerDiffY, mCurrFingerDiffX);
- return (float) (diffRadians * 180.0 / Math.PI);
+ case MotionEvent.ACTION_CANCEL:
+ if (!sloppyGesture) {
+ listener.onRotateEnd(this);
+ }
+
+ resetState();
+ break;
+
+ case MotionEvent.ACTION_MOVE:
+ updateStateByEvent(event);
+
+ // Only accept the event if our relative pressure is within
+ // a certain limit. This can help filter shaky data as a
+ // finger is lifted.
+ if (currPressure / prevPressure > PRESSURE_THRESHOLD) {
+ final boolean updatePrevious = listener.onRotate(this);
+ if (updatePrevious) {
+ prevEvent.recycle();
+ prevEvent = MotionEvent.obtain(event);
+ }
+ }
+ break;
}
+ }
+
+ @Override
+ protected void resetState() {
+ super.resetState();
+ sloppyGesture = false;
+ }
+
+ /**
+ * Return the rotation difference from the previous rotate event to the
+ * current event.
+ *
+ * @return The current rotation //difference in degrees.
+ */
+ public float getRotationDegreesDelta() {
+ double diffRadians = Math.atan2(prevFingerDiffY, prevFingerDiffX)
+ - Math.atan2(currFingerDiffY, currFingerDiffX);
+ return (float) (diffRadians * 180.0 / Math.PI);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/ShoveGestureDetector.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/ShoveGestureDetector.java
index 254597105b..9396578e48 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/ShoveGestureDetector.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/almeros/android/multitouch/gesturedetectors/ShoveGestureDetector.java
@@ -5,21 +5,21 @@ import android.view.MotionEvent;
/**
* @author Robert Nordan (robert.nordan@norkart.no)
- *
+ * <p>
* Copyright (c) 2013, Norkart AS
- *
+ * <p>
* All rights reserved.
- *
+ * <p>
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- *
+ * <p>
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- *
+ * <p>
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -35,179 +35,180 @@ import android.view.MotionEvent;
*/
public class ShoveGestureDetector extends TwoFingerGestureDetector {
- /**
- * Listener which must be implemented which is used by ShoveGestureDetector
- * to perform callbacks to any implementing class which is registered to a
- * ShoveGestureDetector via the constructor.
- *
- * @see ShoveGestureDetector.SimpleOnShoveGestureListener
- */
- public interface OnShoveGestureListener {
- public boolean onShove(ShoveGestureDetector detector);
+ /**
+ * Listener which must be implemented which is used by ShoveGestureDetector
+ * to perform callbacks to any implementing class which is registered to a
+ * ShoveGestureDetector via the constructor.
+ *
+ * @see ShoveGestureDetector.SimpleOnShoveGestureListener
+ */
+ public interface OnShoveGestureListener {
+ public boolean onShove(ShoveGestureDetector detector);
+
+ public boolean onShoveBegin(ShoveGestureDetector detector);
+
+ public void onShoveEnd(ShoveGestureDetector detector);
+ }
+
+ /**
+ * Helper class which may be extended and where the methods may be
+ * implemented. This way it is not necessary to implement all methods of
+ * OnShoveGestureListener.
+ */
+ public static class SimpleOnShoveGestureListener implements
+ OnShoveGestureListener {
+ public boolean onShove(ShoveGestureDetector detector) {
+ return false;
+ }
- public boolean onShoveBegin(ShoveGestureDetector detector);
+ public boolean onShoveBegin(ShoveGestureDetector detector) {
+ return true;
+ }
- public void onShoveEnd(ShoveGestureDetector detector);
+ public void onShoveEnd(ShoveGestureDetector detector) {
+ // Do nothing, overridden implementation may be used
}
+ }
+
+ private float prevAverageY;
+ private float currAverageY;
+
+ private final OnShoveGestureListener listener;
+ private boolean sloppyGesture;
+
+ public ShoveGestureDetector(Context context, OnShoveGestureListener listener) {
+ super(context);
+ this.listener = listener;
+ }
- /**
- * Helper class which may be extended and where the methods may be
- * implemented. This way it is not necessary to implement all methods of
- * OnShoveGestureListener.
- */
- public static class SimpleOnShoveGestureListener implements
- OnShoveGestureListener {
- public boolean onShove(ShoveGestureDetector detector) {
- return false;
+ @Override
+ protected void handleStartProgressEvent(int actionCode, MotionEvent event) {
+ switch (actionCode) {
+ case MotionEvent.ACTION_POINTER_DOWN:
+ // At least the second finger is on screen now
+
+ resetState(); // In case we missed an UP/CANCEL event
+ prevEvent = MotionEvent.obtain(event);
+ timeDelta = 0;
+
+ updateStateByEvent(event);
+
+ // See if we have a sloppy gesture
+ sloppyGesture = isSloppyGesture(event);
+ if (!sloppyGesture) {
+ // No, start gesture now
+ gestureInProgress = listener.onShoveBegin(this);
}
+ break;
- public boolean onShoveBegin(ShoveGestureDetector detector) {
- return true;
+ case MotionEvent.ACTION_MOVE:
+ if (!sloppyGesture) {
+ break;
}
- public void onShoveEnd(ShoveGestureDetector detector) {
- // Do nothing, overridden implementation may be used
+ // See if we still have a sloppy gesture
+ sloppyGesture = isSloppyGesture(event);
+ if (!sloppyGesture) {
+ // No, start normal gesture now
+ gestureInProgress = listener.onShoveBegin(this);
}
- }
- private float mPrevAverageY;
- private float mCurrAverageY;
+ break;
- private final OnShoveGestureListener mListener;
- private boolean mSloppyGesture;
+ case MotionEvent.ACTION_POINTER_UP:
+ if (!sloppyGesture) {
+ break;
+ }
- public ShoveGestureDetector(Context context, OnShoveGestureListener listener) {
- super(context);
- mListener = listener;
+ break;
}
+ }
- @Override
- protected void handleStartProgressEvent(int actionCode, MotionEvent event) {
- switch (actionCode) {
- case MotionEvent.ACTION_POINTER_DOWN:
- // At least the second finger is on screen now
-
- resetState(); // In case we missed an UP/CANCEL event
- mPrevEvent = MotionEvent.obtain(event);
- mTimeDelta = 0;
-
- updateStateByEvent(event);
-
- // See if we have a sloppy gesture
- mSloppyGesture = isSloppyGesture(event);
- if (!mSloppyGesture) {
- // No, start gesture now
- mGestureInProgress = mListener.onShoveBegin(this);
- }
- break;
-
- case MotionEvent.ACTION_MOVE:
- if (!mSloppyGesture) {
- break;
- }
-
- // See if we still have a sloppy gesture
- mSloppyGesture = isSloppyGesture(event);
- if (!mSloppyGesture) {
- // No, start normal gesture now
- mGestureInProgress = mListener.onShoveBegin(this);
- }
-
- break;
-
- case MotionEvent.ACTION_POINTER_UP:
- if (!mSloppyGesture) {
- break;
- }
-
- break;
- }
- }
+ @Override
+ protected void handleInProgressEvent(int actionCode, MotionEvent event) {
+ switch (actionCode) {
+ case MotionEvent.ACTION_POINTER_UP:
+ // Gesture ended but
+ updateStateByEvent(event);
- @Override
- protected void handleInProgressEvent(int actionCode, MotionEvent event) {
- switch (actionCode) {
- case MotionEvent.ACTION_POINTER_UP:
- // Gesture ended but
- updateStateByEvent(event);
-
- if (!mSloppyGesture) {
- mListener.onShoveEnd(this);
- }
-
- resetState();
- break;
-
- case MotionEvent.ACTION_CANCEL:
- if (!mSloppyGesture) {
- mListener.onShoveEnd(this);
- }
-
- resetState();
- break;
-
- case MotionEvent.ACTION_MOVE:
- updateStateByEvent(event);
-
- // Only accept the event if our relative pressure is within
- // a certain limit. This can help filter shaky data as a
- // finger is lifted. Also check that shove is meaningful.
- if (mCurrPressure / mPrevPressure > PRESSURE_THRESHOLD
- && Math.abs(getShovePixelsDelta()) > 0.5f) {
- final boolean updatePrevious = mListener.onShove(this);
- if (updatePrevious) {
- mPrevEvent.recycle();
- mPrevEvent = MotionEvent.obtain(event);
- }
- }
- break;
+ if (!sloppyGesture) {
+ listener.onShoveEnd(this);
}
- }
-
- @Override
- protected void resetState() {
- super.resetState();
- mSloppyGesture = false;
- mPrevAverageY = 0.0f;
- mCurrAverageY = 0.0f;
- }
- @Override
- protected void updateStateByEvent(MotionEvent curr) {
- super.updateStateByEvent(curr);
+ resetState();
+ break;
- final MotionEvent prev = mPrevEvent;
- float py0 = prev.getY(0);
- float py1 = prev.getY(1);
- mPrevAverageY = (py0 + py1) / 2.0f;
+ case MotionEvent.ACTION_CANCEL:
+ if (!sloppyGesture) {
+ listener.onShoveEnd(this);
+ }
- float cy0 = curr.getY(0);
- float cy1 = curr.getY(1);
- mCurrAverageY = (cy0 + cy1) / 2.0f;
+ resetState();
+ break;
+
+ case MotionEvent.ACTION_MOVE:
+ updateStateByEvent(event);
+
+ // Only accept the event if our relative pressure is within
+ // a certain limit. This can help filter shaky data as a
+ // finger is lifted. Also check that shove is meaningful.
+ if (currPressure / prevPressure > PRESSURE_THRESHOLD
+ && Math.abs(getShovePixelsDelta()) > 0.5f) {
+ final boolean updatePrevious = listener.onShove(this);
+ if (updatePrevious) {
+ prevEvent.recycle();
+ prevEvent = MotionEvent.obtain(event);
+ }
+ }
+ break;
}
-
- @Override
- protected boolean isSloppyGesture(MotionEvent event) {
- boolean sloppy = super.isSloppyGesture(event);
- if (sloppy)
- return true;
-
- // If it's not traditionally sloppy, we check if the angle between
- // fingers
- // is acceptable.
- double angle = Math.abs(Math.atan2(mCurrFingerDiffY, mCurrFingerDiffX));
- // about 20 degrees, left or right
- return !((0.0f < angle && angle < 0.35f) || 2.79f < angle
- && angle < Math.PI);
+ }
+
+ @Override
+ protected void resetState() {
+ super.resetState();
+ sloppyGesture = false;
+ prevAverageY = 0.0f;
+ currAverageY = 0.0f;
+ }
+
+ @Override
+ protected void updateStateByEvent(MotionEvent curr) {
+ super.updateStateByEvent(curr);
+
+ final MotionEvent prev = prevEvent;
+ float py0 = prev.getY(0);
+ float py1 = prev.getY(1);
+ prevAverageY = (py0 + py1) / 2.0f;
+
+ float cy0 = curr.getY(0);
+ float cy1 = curr.getY(1);
+ currAverageY = (cy0 + cy1) / 2.0f;
+ }
+
+ @Override
+ protected boolean isSloppyGesture(MotionEvent event) {
+ boolean sloppy = super.isSloppyGesture(event);
+ if (sloppy) {
+ return true;
}
- /**
- * Return the distance in pixels from the previous shove event to the
- * current event.
- *
- * @return The current distance in pixels.
- */
- public float getShovePixelsDelta() {
- return mCurrAverageY - mPrevAverageY;
- }
+ // If it's not traditionally sloppy, we check if the angle between
+ // fingers
+ // is acceptable.
+ double angle = Math.abs(Math.atan2(currFingerDiffY, currFingerDiffX));
+ // about 20 degrees, left or right
+ return !((0.0f < angle && angle < 0.35f) || 2.79f < angle
+ && angle < Math.PI);
+ }
+
+ /**
+ * Return the distance in pixels from the previous shove event to the
+ * current event.
+ *
+ * @return The current distance in pixels.
+ */
+ public float getShovePixelsDelta() {
+ return currAverageY - prevAverageY;
+ }
}
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 6be0b46d5b..71fb9aa168 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
@@ -9,19 +9,19 @@ import android.view.ViewConfiguration;
/**
* @author Almer Thie (code.almeros.com) Copyright (c) 2013, Almer Thie
* (code.almeros.com)
- *
+ * <p>
* All rights reserved.
- *
+ * <p>
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- *
+ * <p>
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- *
+ * <p>
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -37,187 +37,189 @@ import android.view.ViewConfiguration;
*/
public abstract class TwoFingerGestureDetector extends BaseGestureDetector {
- private final float mEdgeSlop;
-
- protected float mPrevFingerDiffX;
- protected float mPrevFingerDiffY;
- protected float mCurrFingerDiffX;
- protected float mCurrFingerDiffY;
-
- private float mCurrLen;
- private float mPrevLen;
-
- private PointF mFocus;
-
- public TwoFingerGestureDetector(Context context) {
- super(context);
-
- ViewConfiguration config = ViewConfiguration.get(context);
- mEdgeSlop = config.getScaledEdgeSlop();
+ private final float edgeSlop;
+
+ protected float prevFingerDiffX;
+ protected float prevFingerDiffY;
+ protected float currFingerDiffX;
+ protected float currFingerDiffY;
+
+ private float currLen;
+ private float prevLen;
+
+ private PointF focus;
+
+ public TwoFingerGestureDetector(Context context) {
+ super(context);
+
+ ViewConfiguration config = ViewConfiguration.get(context);
+
+ // We divide edge slop by 2 to make rotation gesture happen more easily #6870
+ edgeSlop = config.getScaledEdgeSlop() / 2;
+ }
+
+ @Override
+ protected abstract void handleStartProgressEvent(int actionCode,
+ MotionEvent event);
+
+ @Override
+ protected abstract void handleInProgressEvent(int actionCode,
+ MotionEvent event);
+
+ protected void updateStateByEvent(MotionEvent curr) {
+ super.updateStateByEvent(curr);
+
+ final MotionEvent prev = prevEvent;
+
+ currLen = -1;
+ prevLen = -1;
+
+ // Previous
+ final float px0 = prev.getX(0);
+ final float py0 = prev.getY(0);
+ final float px1 = prev.getX(1);
+ final float py1 = prev.getY(1);
+ final float pvx = px1 - px0;
+ final float pvy = py1 - py0;
+ prevFingerDiffX = pvx;
+ prevFingerDiffY = pvy;
+
+ // Current
+ final float cx0 = curr.getX(0);
+ final float cy0 = curr.getY(0);
+ final float cx1 = curr.getX(1);
+ final float cy1 = curr.getY(1);
+ final float cvx = cx1 - cx0;
+ final float cvy = cy1 - cy0;
+ currFingerDiffX = cvx;
+ currFingerDiffY = cvy;
+ focus = determineFocalPoint(curr);
+ }
+
+ /**
+ * Return the current distance between the two pointers forming the gesture
+ * in progress.
+ *
+ * @return Distance between pointers in pixels.
+ */
+ public float getCurrentSpan() {
+ if (currLen == -1) {
+ final float cvx = currFingerDiffX;
+ final float cvy = currFingerDiffY;
+ currLen = (float) Math.sqrt(cvx * cvx + cvy * cvy);
}
-
- @Override
- protected abstract void handleStartProgressEvent(int actionCode,
- MotionEvent event);
-
- @Override
- protected abstract void handleInProgressEvent(int actionCode,
- MotionEvent event);
-
- protected void updateStateByEvent(MotionEvent curr) {
- super.updateStateByEvent(curr);
-
- final MotionEvent prev = mPrevEvent;
-
- mCurrLen = -1;
- mPrevLen = -1;
-
- // Previous
- final float px0 = prev.getX(0);
- final float py0 = prev.getY(0);
- final float px1 = prev.getX(1);
- final float py1 = prev.getY(1);
- final float pvx = px1 - px0;
- final float pvy = py1 - py0;
- mPrevFingerDiffX = pvx;
- mPrevFingerDiffY = pvy;
-
- // Current
- final float cx0 = curr.getX(0);
- final float cy0 = curr.getY(0);
- final float cx1 = curr.getX(1);
- final float cy1 = curr.getY(1);
- final float cvx = cx1 - cx0;
- final float cvy = cy1 - cy0;
- mCurrFingerDiffX = cvx;
- mCurrFingerDiffY = cvy;
- mFocus = determineFocalPoint(curr);
+ return currLen;
+ }
+
+ /**
+ * Return the previous distance between the two pointers forming the gesture
+ * in progress.
+ *
+ * @return Previous distance between pointers in pixels.
+ */
+ public float getPreviousSpan() {
+ if (prevLen == -1) {
+ final float pvx = prevFingerDiffX;
+ final float pvy = prevFingerDiffY;
+ prevLen = (float) Math.sqrt(pvx * pvx + pvy * pvy);
}
-
- /**
- * Return the current distance between the two pointers forming the gesture
- * in progress.
- *
- * @return Distance between pointers in pixels.
- */
- public float getCurrentSpan() {
- if (mCurrLen == -1) {
- final float cvx = mCurrFingerDiffX;
- final float cvy = mCurrFingerDiffY;
- mCurrLen = (float) Math.sqrt(cvx * cvx + cvy * cvy);
- }
- return mCurrLen;
+ return prevLen;
+ }
+
+ /**
+ * MotionEvent has no getRawX(int) method; simulate it pending future API
+ * approval.
+ *
+ * @param event Motion Event
+ * @param pointerIndex Pointer Index
+ * @return Raw x value or 0
+ */
+ protected static float getRawX(MotionEvent event, int pointerIndex) {
+ float offset = event.getRawX() - event.getX();
+ if (pointerIndex < event.getPointerCount()) {
+ return event.getX(pointerIndex) + offset;
}
-
- /**
- * Return the previous distance between the two pointers forming the gesture
- * in progress.
- *
- * @return Previous distance between pointers in pixels.
- */
- public float getPreviousSpan() {
- if (mPrevLen == -1) {
- final float pvx = mPrevFingerDiffX;
- final float pvy = mPrevFingerDiffY;
- mPrevLen = (float) Math.sqrt(pvx * pvx + pvy * pvy);
- }
- return mPrevLen;
+ return 0.0f;
+ }
+
+ /**
+ * MotionEvent has no getRawY(int) method; simulate it pending future API
+ * approval.
+ *
+ * @param event Motion Event
+ * @param pointerIndex Pointer Index
+ * @return Raw y value or 0
+ */
+ protected static float getRawY(MotionEvent event, int pointerIndex) {
+ float offset = event.getRawY() - event.getY();
+ if (pointerIndex < event.getPointerCount()) {
+ return event.getY(pointerIndex) + offset;
}
-
- /**
- * MotionEvent has no getRawX(int) method; simulate it pending future API
- * approval.
- *
- * @param event Motion Event
- * @param pointerIndex Pointer Index
- * @return Raw x value or 0
- */
- protected static float getRawX(MotionEvent event, int pointerIndex) {
- float offset = event.getRawX() - event.getX();
- if (pointerIndex < event.getPointerCount()) {
- return event.getX(pointerIndex) + offset;
- }
- return 0.0f;
+ return 0.0f;
+ }
+
+ /**
+ * Check if we have a sloppy gesture. Sloppy gestures can happen if the edge
+ * of the user's hand is touching the screen, for example.
+ *
+ * @param event Motion Event
+ * @return {@code true} if is sloppy gesture, {@code false} if not
+ */
+ protected boolean isSloppyGesture(MotionEvent event) {
+ // As orientation can change, query the metrics in touch down
+ DisplayMetrics metrics = context.getResources().getDisplayMetrics();
+ float rightSlopEdge = metrics.widthPixels - edgeSlop;
+ float bottomSlopEdge = metrics.heightPixels - edgeSlop;
+
+ final float edgeSlop = this.edgeSlop;
+
+ final float x0 = event.getRawX();
+ final float y0 = event.getRawY();
+ final float x1 = getRawX(event, 1);
+ final float y1 = getRawY(event, 1);
+
+ boolean p0sloppy = x0 < edgeSlop || y0 < edgeSlop || x0 > rightSlopEdge
+ || y0 > bottomSlopEdge;
+ boolean p1sloppy = x1 < edgeSlop || y1 < edgeSlop || x1 > rightSlopEdge
+ || y1 > bottomSlopEdge;
+
+ if (p0sloppy && p1sloppy) {
+ return true;
+ } else if (p0sloppy) {
+ return true;
+ } else if (p1sloppy) {
+ return true;
}
-
- /**
- * MotionEvent has no getRawY(int) method; simulate it pending future API
- * approval.
- *
- * @param event Motion Event
- * @param pointerIndex Pointer Index
- * @return Raw y value or 0
- */
- protected static float getRawY(MotionEvent event, int pointerIndex) {
- float offset = event.getRawY() - event.getY();
- if (pointerIndex < event.getPointerCount()) {
- return event.getY(pointerIndex) + offset;
- }
- return 0.0f;
+ return false;
+ }
+
+ /**
+ * Determine (multi)finger focal point (a.k.a. center point between all
+ * fingers)
+ *
+ * @param motionEvent Motion Event
+ * @return PointF focal point
+ */
+ public static PointF determineFocalPoint(MotionEvent motionEvent) {
+ // Number of fingers on screen
+ final int pCount = motionEvent.getPointerCount();
+ float x = 0.0f;
+ float y = 0.0f;
+
+ for (int i = 0; i < pCount; i++) {
+ x += motionEvent.getX(i);
+ y += motionEvent.getY(i);
}
- /**
- * Check if we have a sloppy gesture. Sloppy gestures can happen if the edge
- * of the user's hand is touching the screen, for example.
- *
- * @param event Motion Event
- * @return {@code true} if is sloppy gesture, {@code false} if not
- */
- protected boolean isSloppyGesture(MotionEvent event) {
- // As orientation can change, query the metrics in touch down
- DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
- float mRightSlopEdge = metrics.widthPixels - mEdgeSlop;
- float mBottomSlopEdge = metrics.heightPixels - mEdgeSlop;
-
- final float edgeSlop = mEdgeSlop;
-
- final float x0 = event.getRawX();
- final float y0 = event.getRawY();
- final float x1 = getRawX(event, 1);
- final float y1 = getRawY(event, 1);
-
- boolean p0sloppy = x0 < edgeSlop || y0 < edgeSlop || x0 > mRightSlopEdge
- || y0 > mBottomSlopEdge;
- boolean p1sloppy = x1 < edgeSlop || y1 < edgeSlop || x1 > mRightSlopEdge
- || y1 > mBottomSlopEdge;
-
- if (p0sloppy && p1sloppy) {
- return true;
- } else if (p0sloppy) {
- return true;
- } else if (p1sloppy) {
- return true;
- }
- return false;
- }
+ return new PointF(x / pCount, y / pCount);
+ }
- /**
- * Determine (multi)finger focal point (a.k.a. center point between all
- * fingers)
- *
- * @param e Motion Event
- * @return PointF focal point
- */
- public static PointF determineFocalPoint(MotionEvent e) {
- // Number of fingers on screen
- final int pCount = e.getPointerCount();
- float x = 0.0f;
- float y = 0.0f;
-
- for (int i = 0; i < pCount; i++) {
- x += e.getX(i);
- y += e.getY(i);
- }
-
- return new PointF(x / pCount, y / pCount);
- }
+ public float getFocusX() {
+ return focus.x;
+ }
- public float getFocusX() {
- return mFocus.x;
- }
-
- public float getFocusY() {
- return mFocus.y;
- }
+ public float getFocusY() {
+ return focus.y;
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java
new file mode 100644
index 0000000000..d9cf407677
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java
@@ -0,0 +1,93 @@
+package com.mapbox.mapboxsdk;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.support.annotation.NonNull;
+import android.text.TextUtils;
+
+import com.mapbox.mapboxsdk.constants.MapboxConstants;
+import com.mapbox.mapboxsdk.exceptions.InvalidAccessTokenException;
+import com.mapbox.mapboxsdk.net.ConnectivityReceiver;
+import com.mapbox.mapboxsdk.telemetry.MapboxEventManager;
+
+public final class Mapbox {
+
+ private static Mapbox INSTANCE;
+ private Context context;
+ private String accessToken;
+ private Boolean connected;
+
+ public static synchronized Mapbox getInstance(@NonNull Context context, @NonNull String accessToken) {
+ if (INSTANCE == null) {
+ Context appContext = context.getApplicationContext();
+ INSTANCE = new Mapbox(appContext, accessToken);
+ MapboxEventManager.getMapboxEventManager().initialize(appContext, accessToken);
+ ConnectivityReceiver.instance(appContext);
+ }
+ return INSTANCE;
+ }
+
+ private Mapbox(@NonNull Context context, @NonNull String accessToken) {
+ this.context = context;
+ this.accessToken = accessToken;
+ }
+
+ /**
+ * Access Token for this application.
+ *
+ * @return Mapbox Access Token
+ */
+ public static String getAccessToken() {
+ return INSTANCE.accessToken;
+ }
+
+ /**
+ * Application context
+ */
+ public static Context getApplicationContext() {
+ return INSTANCE.context;
+ }
+
+ /**
+ * Runtime validation of Access Token.
+ *
+ * @throws InvalidAccessTokenException the exception thrown
+ */
+ public static void validateAccessToken() throws InvalidAccessTokenException {
+ String accessToken = INSTANCE.accessToken;
+ if (TextUtils.isEmpty(accessToken) || (!accessToken.toLowerCase(MapboxConstants.MAPBOX_LOCALE).startsWith("pk.")
+ && !accessToken.toLowerCase(MapboxConstants.MAPBOX_LOCALE).startsWith("sk."))) {
+ throw new InvalidAccessTokenException();
+ }
+ }
+
+ /**
+ * 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 static void setConnected(Boolean connected) {
+ // Connectivity state overridden by app
+ INSTANCE.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 static Boolean isConnected() {
+ if (INSTANCE.connected != null) {
+ // Connectivity state overridden by app
+ return INSTANCE.connected;
+ }
+
+ ConnectivityManager cm = (ConnectivityManager) INSTANCE.context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
+ return (activeNetwork != null && activeNetwork.isConnected());
+ }
+} \ No newline at end of file
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
deleted file mode 100644
index b33d01a105..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapboxAccountManager.java
+++ /dev/null
@@ -1,131 +0,0 @@
-package com.mapbox.mapboxsdk;
-
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.text.TextUtils;
-
-import com.mapbox.mapboxsdk.constants.MapboxConstants;
-import com.mapbox.mapboxsdk.exceptions.InvalidAccessTokenException;
-import com.mapbox.mapboxsdk.exceptions.MapboxAccountManagerNotStartedException;
-import com.mapbox.mapboxsdk.net.ConnectivityReceiver;
-import com.mapbox.mapboxsdk.telemetry.MapboxEventManager;
-
-public class MapboxAccountManager {
-
- private static MapboxAccountManager mapboxAccountManager = null;
-
- private final String accessToken;
- private final Context applicationContext;
-
- private Boolean connected = null;
-
- /**
- * MapboxAccountManager should NOT be instantiated directly.
- * Use @see MapboxAccountManager#getInstance() instead.
- *
- * @param applicationContext Context used to get ApplicationContext
- * @param accessToken Mapbox Access Token
- */
- private MapboxAccountManager(Context applicationContext, String accessToken) {
- super();
- this.applicationContext = applicationContext.getApplicationContext();
- this.accessToken = accessToken;
- }
-
- /**
- * Primary entry point to Mapbox for implementing developers.
- * Must be configured in either Application.onCreate() or Launch Activity.onCreate()
- *
- * @param context Context used to get Application Context
- * @param accessToken Mapbox Access Token. You can get one on the Mapbox Web site.
- * @return MapboxAccountManager instance for app
- */
- public static MapboxAccountManager start(Context context, String accessToken) {
- if (mapboxAccountManager == null) {
- //Create a new account manager
- mapboxAccountManager = new MapboxAccountManager(context, accessToken);
-
- //Initialize the event manager
- MapboxEventManager.getMapboxEventManager().initialize(context, accessToken);
-
- //Register a receiver to listen for connectivity updates
- ConnectivityReceiver.instance(context);
- }
-
- return mapboxAccountManager;
- }
-
- /**
- * Internal Use Only
- * Get an instance of MapboxAccountManager configured with the app's Access Token
- *
- * @return MapboxAccountManager instance for app. May be NULL if not configured yet.
- */
- public static MapboxAccountManager getInstance() {
- if (mapboxAccountManager == null) {
- throw new MapboxAccountManagerNotStartedException();
- }
-
- return mapboxAccountManager;
- }
-
- /**
- * Access Token for this application.
- *
- * @return Mapbox Access Token
- */
- public String getAccessToken() {
- return accessToken;
- }
-
- /**
- * Runtime validation of Access Token.
- *
- * @param accessToken Access Token to check
- * @throws InvalidAccessTokenException the exception thrown
- */
- public static void validateAccessToken(String accessToken) throws InvalidAccessTokenException {
- if (TextUtils.isEmpty(accessToken) || (!accessToken.toLowerCase(MapboxConstants.MAPBOX_LOCALE).startsWith("pk.") && !accessToken.toLowerCase(MapboxConstants.MAPBOX_LOCALE).startsWith("sk."))) {
- throw new InvalidAccessTokenException();
- }
- }
-
- /**
- * 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() {
- 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());
- }
-
- /**
- * Not public API
- * @return the Application Context
- */
- public Context getApplicationContext() {
- return applicationContext;
- }
-
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Annotation.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Annotation.java
index d7df692e17..831c1db5a3 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Annotation.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Annotation.java
@@ -15,104 +15,127 @@ import com.mapbox.mapboxsdk.maps.MapboxMap;
*/
public abstract class Annotation implements Comparable<Annotation> {
- /**
- * <p>
- * The annotation id
- * </p>
- * Internal C++ id is stored as unsigned int.
- */
- private long id = -1; // -1 unless added to a MapView
- protected MapboxMap mapboxMap;
- protected MapView mapView;
+ /**
+ * <p>
+ * The annotation id
+ * </p>
+ * Internal C++ id is stored as unsigned int.
+ */
+ private long id = -1; // -1 unless added to a MapView
+ protected MapboxMap mapboxMap;
+ protected MapView mapView;
- protected Annotation() {
- }
+ protected Annotation() {
+ }
- /**
- * <p>
- * Gets the annotation's unique ID.
- * </p>
- * This ID is unique for a MapView instance and is suitable for associating your own extra
- * data with.
- *
- * @return the assigned id
- */
- public long getId() {
- return id;
- }
+ /**
+ * <p>
+ * Gets the annotation's unique ID.
+ * </p>
+ * This ID is unique for a MapView instance and is suitable for associating your own extra
+ * data with.
+ *
+ * @return the assigned id.
+ */
+ public long getId() {
+ return id;
+ }
- public void remove() {
- if (mapboxMap == null) {
- return;
- }
- mapboxMap.removeAnnotation(this);
+ /**
+ * Do not use this method, used internally by the SDK.
+ */
+ public void remove() {
+ if (mapboxMap == null) {
+ return;
}
+ mapboxMap.removeAnnotation(this);
+ }
- /**
- * Do not use this method. Used internally by the SDK.
- *
- * @param id the assigned id
- */
- public void setId(long id) {
- this.id = id;
- }
+ /**
+ * Do not use this method, used internally by the SDK.
+ *
+ * @param id the assigned id
+ */
+ public void setId(long id) {
+ this.id = id;
+ }
- /**
- * Do not use this method. Used internally by the SDK.
- *
- * @param mapboxMap the hosting mapbox map
- */
- public void setMapboxMap(MapboxMap mapboxMap) {
- this.mapboxMap = mapboxMap;
- }
+ /**
+ * Do not use this method, used internally by the SDK.
+ *
+ * @param mapboxMap the hosting mapbox map
+ */
+ public void setMapboxMap(MapboxMap mapboxMap) {
+ this.mapboxMap = mapboxMap;
+ }
- /**
- * Gets the hosting mapbox map.
- *
- * @return the MapboxMap
- */
- protected MapboxMap getMapboxMap() {
- return mapboxMap;
- }
+ /**
+ * Gets the hosting mapbox map.
+ *
+ * @return the MapboxMap
+ */
+ protected MapboxMap getMapboxMap() {
+ return mapboxMap;
+ }
- /**
- * Don not use this method. Used internally by the SDK.
- *
- * @param mapView the hosting map view
- */
- public void setMapView(MapView mapView) {
- this.mapView = mapView;
- }
+ /**
+ * Do not use this method, used internally by the SDK.
+ *
+ * @param mapView the hosting map view
+ */
+ public void setMapView(MapView mapView) {
+ this.mapView = mapView;
+ }
- /**
- * Gets the hosting map view.
- *
- * @return The MapView
- */
- protected MapView getMapView() {
- return mapView;
- }
+ /**
+ * Gets the hosting map view.
+ *
+ * @return The MapView
+ */
+ protected MapView getMapView() {
+ return mapView;
+ }
- @Override
- public int compareTo(@NonNull Annotation annotation) {
- if (id < annotation.getId()) {
- return 1;
- } else if (id > annotation.getId()) {
- return -1;
- }
- return 0;
+ @Override
+ public int compareTo(@NonNull Annotation annotation) {
+ if (id < annotation.getId()) {
+ return 1;
+ } else if (id > annotation.getId()) {
+ return -1;
}
+ return 0;
+ }
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || !(o instanceof Annotation)) return false;
- Annotation that = (Annotation) o;
- return id == that.getId();
+ /**
+ * Compares this {@link PolylineOptions} object with another {@link PolylineOptions} and
+ * determines if their color, alpha, width, and vertices match.
+ *
+ * @param object Another {@link PolylineOptions} to compare with this object.
+ * @return True if color, alpha, width, and vertices match this {@link PolylineOptions} object.
+ * Else, false.
+ */
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
}
-
- @Override
- public int hashCode() {
- return (int) (getId() ^ (getId() >>> 32));
+ if (object == null || !(object instanceof Annotation)) {
+ return false;
}
+ Annotation that = (Annotation) object;
+ return id == that.getId();
+ }
+
+ /**
+ * Gives an integer which can be used as the bucket number for storing elements of the set/map.
+ * This bucket number is the address of the element inside the set/map. There's no guarantee
+ * that this hash value will be consistent between different Java implementations, or even
+ * between different execution runs of the same program.
+ *
+ * @return integer value you can use for storing element.
+ */
+ @Override
+ public int hashCode() {
+ return (int) (getId() ^ (getId() >>> 32));
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BaseMarkerOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BaseMarkerOptions.java
index 3adeb52ea7..82868e2888 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BaseMarkerOptions.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BaseMarkerOptions.java
@@ -6,7 +6,7 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
/**
* Abstract builder class for composing custom Marker objects.
- *
+ * <p>
* Extending this class requires implementing Parceable interface.
*
* @param <U> Type of the marker to be composed
@@ -14,49 +14,107 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
*/
public abstract class BaseMarkerOptions<U extends Marker, T extends BaseMarkerOptions<U, T>> implements Parcelable {
- protected LatLng position;
- protected String snippet;
- protected String title;
- protected Icon icon;
+ protected LatLng position;
+ protected String snippet;
+ protected String title;
+ protected Icon icon;
- public T position(LatLng position) {
- this.position = position;
- return getThis();
- }
+ /**
+ * Set the geographical location of the Marker.
+ *
+ * @param position the location to position the {@link Marker}.
+ * @return the object for which the method was called.
+ */
+ public T position(LatLng position) {
+ this.position = position;
+ return getThis();
+ }
- public T snippet(String snippet) {
- this.snippet = snippet;
- return getThis();
- }
+ /**
+ * Set the snippet of the Marker.
+ *
+ * @param snippet the snippet of the {@link Marker}.
+ * @return the object for which the method was called.
+ */
+ public T snippet(String snippet) {
+ this.snippet = snippet;
+ return getThis();
+ }
- public T title(String title) {
- this.title = title;
- return getThis();
- }
+ /**
+ * Set the title of the Marker.
+ *
+ * @param title the title of the {@link Marker}.
+ * @return the object for which the method was called.
+ */
+ public T title(String title) {
+ this.title = title;
+ return getThis();
+ }
- public T icon(Icon icon) {
- this.icon = icon;
- return getThis();
- }
+ /**
+ * Set the icon of the Marker.
+ *
+ * @param icon the icon of the {@link Marker}.
+ * @return the object for which the method was called.
+ */
+ public T icon(Icon icon) {
+ this.icon = icon;
+ return getThis();
+ }
- public T setIcon(Icon icon) {
- return icon(icon);
- }
+ /**
+ * Set the icon of the Marker.
+ *
+ * @param icon the icon of the {@link Marker}.
+ * @return the object for which the method was called.
+ */
+ public T setIcon(Icon icon) {
+ return icon(icon);
+ }
- public T setPosition(LatLng position) {
- return position(position);
- }
+ /**
+ * Set the geographical location of the Marker.
+ *
+ * @param position the location to position the {@link Marker}.
+ * @return the object for which the method was called.
+ */
+ public T setPosition(LatLng position) {
+ return position(position);
+ }
- public T setSnippet(String snippet) {
- return snippet(snippet);
- }
+ /**
+ * Set the snippet of the Marker.
+ *
+ * @param snippet the snippet of the {@link Marker}.
+ * @return the object for which the method was called.
+ */
+ public T setSnippet(String snippet) {
+ return snippet(snippet);
+ }
- public T setTitle(String title) {
- return title(title);
- }
+ /**
+ * Set the title of the Marker.
+ *
+ * @param title the title of the {@link Marker}.
+ * @return the object for which the method was called.
+ */
+ public T setTitle(String title) {
+ return title(title);
+ }
- public abstract T getThis();
+ /**
+ * Get the instance of the object for which this method was called.
+ *
+ * @return the object for which the this method was called.
+ */
+ public abstract T getThis();
- public abstract U getMarker();
+ /**
+ * Get the Marker.
+ *
+ * @return the Marker created from this builder.
+ */
+ public abstract U getMarker();
}
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 d4eb390ab2..ddedf3debf 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
@@ -12,270 +12,271 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
* Extending this class requires implementing Parceable interface.
* </p>
*
- * @param <U> Type of the marker view to be composed
- * @param <T> Type of the builder to be used for composing
+ * @param <U> Type of the marker view to be composed.
+ * @param <T> Type of the builder to be used for composing.
*/
-public abstract class BaseMarkerViewOptions<U extends MarkerView, T extends BaseMarkerViewOptions<U, T>> implements Parcelable {
+public abstract class BaseMarkerViewOptions<U extends MarkerView, T extends BaseMarkerViewOptions<U, T>>
+ implements Parcelable {
- protected LatLng position;
- protected String snippet;
- protected String title;
- protected Icon icon;
- protected boolean flat;
- protected float anchorU = 0.5f;
- protected float anchorV = 1f;
- protected float infoWindowAnchorU = 0.5f;
- protected float infoWindowAnchorV = 0.0f;
- protected float rotation;
- protected boolean visible = true;
- protected boolean selected;
- protected float alpha = 1.0f;
+ protected LatLng position;
+ protected String snippet;
+ protected String title;
+ protected Icon icon;
+ protected boolean flat;
+ protected float anchorU = 0.5f;
+ protected float anchorV = 1f;
+ protected float infoWindowAnchorU = 0.5f;
+ protected float infoWindowAnchorV = 0.0f;
+ protected float rotation;
+ protected boolean visible = true;
+ protected boolean selected;
+ protected float alpha = 1.0f;
- /**
- * Default constructor
- */
- public BaseMarkerViewOptions() {
- }
+ /**
+ * Default constructor
+ */
+ public BaseMarkerViewOptions() {
+ }
- /**
- * Set the geographical location of the MarkerView.
- *
- * @param position the location to position the MarkerView
- * @return the object for which the method was called
- */
- public T position(@NonNull LatLng position) {
- this.position = position;
- return getThis();
- }
+ /**
+ * Set the geographical location of the MarkerView.
+ *
+ * @param position the location to position the {@link MarkerView}.
+ * @return the object for which the method was called.
+ */
+ public T position(@NonNull LatLng position) {
+ this.position = position;
+ return getThis();
+ }
- /**
- * Set the snippet of the MarkerView.
- *
- * @param snippet the snippet of the MarkerView
- * @return the object for which the method was called
- */
- public T snippet(String snippet) {
- this.snippet = snippet;
- return getThis();
- }
+ /**
+ * Set the snippet of the MarkerView.
+ *
+ * @param snippet the snippet of the {@link MarkerView}.
+ * @return the object for which the method was called.
+ */
+ public T snippet(String snippet) {
+ this.snippet = snippet;
+ return getThis();
+ }
- /**
- * Set the title of the MarkerView.
- *
- * @param title the title of the MarkerView
- * @return the object for which the method was called
- */
- public T title(String title) {
- this.title = title;
- return getThis();
- }
+ /**
+ * Set the title of the MarkerView.
+ *
+ * @param title the title of the {@link MarkerView}.
+ * @return the object for which the method was called.
+ */
+ public T title(String title) {
+ this.title = title;
+ return getThis();
+ }
- /**
- * Set the icon of the MarkerView.
- *
- * @param icon the icon of the MarkerView
- * @return the object for which the method was called
- */
- public T icon(Icon icon) {
- this.icon = icon;
- return getThis();
- }
+ /**
+ * Set the icon of the MarkerView.
+ *
+ * @param icon the icon of the {@link MarkerView}.
+ * @return the object for which the method was called.
+ */
+ public T icon(Icon icon) {
+ this.icon = icon;
+ return getThis();
+ }
- /**
- * Set the flat state of the MarkerView.
- *
- * @param flat the flat state of the MarkerView
- * @return the object for which the method was called
- */
- public T flat(boolean flat) {
- this.flat = flat;
- return getThis();
- }
+ /**
+ * Set the flat state of the MarkerView.
+ *
+ * @param flat the flat state of the {@link MarkerView}.
+ * @return the object for which the method was called.
+ */
+ public T flat(boolean flat) {
+ this.flat = flat;
+ return getThis();
+ }
- /**
- * Set the anchor of the MarkerView.
- *
- * @param u the u-value
- * @param v the v-value
- * @return the object for which the method was called
- */
- public T anchor(@FloatRange(from = 0.0, to = 1.0) float u, @FloatRange(from = 0.0, to = 1.0) float v) {
- this.anchorU = u;
- this.anchorV = v;
- return getThis();
- }
+ /**
+ * Set the anchor of the {@link MarkerView}.
+ *
+ * @param u the u-value.
+ * @param v the v-value.
+ * @return the object for which the method was called.
+ */
+ public T anchor(@FloatRange(from = 0.0, to = 1.0) float u, @FloatRange(from = 0.0, to = 1.0) float v) {
+ this.anchorU = u;
+ this.anchorV = v;
+ return getThis();
+ }
- /**
- * Set the InfoWindow anchor of the MarkerView.
- *
- * @param u the u-value
- * @param v the v-values
- * @return the object for which the method was called
- */
- public T infoWindowAnchor(@FloatRange(from = 0.0, to = 1.0) float u, @FloatRange(from = 0.0, to = 1.0) float v) {
- this.infoWindowAnchorU = u;
- this.infoWindowAnchorV = v;
- return getThis();
- }
+ /**
+ * Set the InfoWindow anchor of the {@link MarkerView}.
+ *
+ * @param u the u-value.
+ * @param v the v-values.
+ * @return the object for which the method was called.
+ */
+ public T infoWindowAnchor(@FloatRange(from = 0.0, to = 1.0) float u, @FloatRange(from = 0.0, to = 1.0) float v) {
+ this.infoWindowAnchorU = u;
+ this.infoWindowAnchorV = v;
+ return getThis();
+ }
- /**
- * Set the rotation of the MarkerView.
- *
- * @param rotation the rotation value
- * @return the object for which the method was called
- */
- public T rotation(float rotation) {
- this.rotation = rotation;
- while (this.rotation > 360) {
- this.rotation -= 360;
- }
- while (this.rotation < 0) {
- this.rotation += 360;
- }
- return getThis();
+ /**
+ * Set the rotation of the {@link MarkerView}.
+ *
+ * @param rotation the rotation value.
+ * @return the object for which the method was called.
+ */
+ public T rotation(float rotation) {
+ this.rotation = rotation;
+ while (this.rotation > 360) {
+ this.rotation -= 360;
}
-
- /**
- * Set the visibility state of the MarkerView.
- *
- * @param visible the visible state
- * @return the object for which the method was called
- */
- public T visible(boolean visible) {
- this.visible = visible;
- return getThis();
+ while (this.rotation < 0) {
+ this.rotation += 360;
}
+ return getThis();
+ }
- /**
- * Set the alpha of the MarkerView.
- *
- * @param alpha the alpha value
- * @return the object for which the method was called
- */
- public T alpha(float alpha) {
- this.alpha = alpha;
- return getThis();
- }
+ /**
+ * Set the visibility state of the {@link MarkerView}.
+ *
+ * @param visible the visible state.
+ * @return the object for which the method was called.
+ */
+ public T visible(boolean visible) {
+ this.visible = visible;
+ return getThis();
+ }
- /**
- * Get the geographical location of the MarkerView.
- *
- * @return the geographical location
- */
- public LatLng getPosition() {
- return position;
- }
+ /**
+ * Set the alpha of the {@link MarkerView}.
+ *
+ * @param alpha the alpha value.
+ * @return the object for which the method was called.
+ */
+ public T alpha(float alpha) {
+ this.alpha = alpha;
+ return getThis();
+ }
- /**
- * Get the snippet of the MarkerView.
- *
- * @return the snippet
- */
- public String getSnippet() {
- return snippet;
- }
+ /**
+ * Get the geographical location of the {@link MarkerView}.
+ *
+ * @return the geographical location.
+ */
+ public LatLng getPosition() {
+ return position;
+ }
- /**
- * Get the title of the MarkerView.
- *
- * @return the title
- */
- public String getTitle() {
- return title;
- }
+ /**
+ * Get the snippet of the {@link MarkerView}.
+ *
+ * @return the snippet.
+ */
+ public String getSnippet() {
+ return snippet;
+ }
- /**
- * Get the icon of the MarkerView.
- *
- * @return the icon
- */
- public Icon getIcon() {
- return icon;
- }
+ /**
+ * Get the title of the {@link MarkerView}.
+ *
+ * @return the title.
+ */
+ public String getTitle() {
+ return title;
+ }
- /**
- * Get the flat state of the MarkerView.
- *
- * @return the flat state
- */
- public boolean isFlat() {
- return flat;
- }
+ /**
+ * Get the icon of the {@link MarkerView}.
+ *
+ * @return the icon.
+ */
+ public Icon getIcon() {
+ return icon;
+ }
- /**
- * Get the u-value of the MarkerView anchor.
- *
- * @return the u-value
- */
- public float getAnchorU() {
- return anchorU;
- }
+ /**
+ * Get the flat state of the {@link MarkerView}.
+ *
+ * @return the flat state.
+ */
+ public boolean isFlat() {
+ return flat;
+ }
- /**
- * Get the v-value of the MarkerView anchor.
- *
- * @return the v-value
- */
- public float getAnchorV() {
- return anchorV;
- }
+ /**
+ * Get the u-value of the {@link MarkerView} anchor.
+ *
+ * @return the u-value.
+ */
+ public float getAnchorU() {
+ return anchorU;
+ }
- /**
- * Get the u-value of the MarkerView InfoWindow anchor.
- *
- * @return the u-value
- */
- public float getInfoWindowAnchorU() {
- return infoWindowAnchorU;
- }
+ /**
+ * Get the v-value of the {@link MarkerView} anchor.
+ *
+ * @return the v-value.
+ */
+ public float getAnchorV() {
+ return anchorV;
+ }
- /**
- * Get the v-value of the MarkerView InfoWindow anchor.
- *
- * @return the v-value
- */
- public float getInfoWindowAnchorV() {
- return infoWindowAnchorV;
- }
+ /**
+ * Get the u-value of the MarkerView InfoWindow anchor.
+ *
+ * @return the u-value.
+ */
+ public float getInfoWindowAnchorU() {
+ return infoWindowAnchorU;
+ }
- /**
- * Get the rotation of the MarkerView.
- *
- * @return the rotation value
- */
- public float getRotation() {
- return rotation;
- }
+ /**
+ * Get the v-value of the MarkerView InfoWindow anchor.
+ *
+ * @return the v-value.
+ */
+ public float getInfoWindowAnchorV() {
+ return infoWindowAnchorV;
+ }
- /**
- * Get the visibility state of the MarkerView.
- *
- * @return the visibility state
- */
- public boolean isVisible() {
- return visible;
- }
+ /**
+ * Get the rotation of the MarkerView.
+ *
+ * @return the rotation value.
+ */
+ public float getRotation() {
+ return rotation;
+ }
- /**
- * Get the alpha of the MarkerView.
- *
- * @return the alpha value
- */
- public float getAlpha() {
- return alpha;
- }
+ /**
+ * Get the visibility state of the MarkerView.
+ *
+ * @return the visibility state.
+ */
+ public boolean isVisible() {
+ return visible;
+ }
+
+ /**
+ * Get the alpha of the MarkerView.
+ *
+ * @return the alpha value.
+ */
+ public float getAlpha() {
+ return alpha;
+ }
- /**
- * Get the instance of the object for which this method was called.
- *
- * @return the object for which the this method was called
- */
- public abstract T getThis();
+ /**
+ * Get the instance of the object for which this method was called.
+ *
+ * @return the object for which the this method was called.
+ */
+ public abstract T getThis();
- /**
- * Get the MarkerView.
- *
- * @return the MarkerView created from this builder
- */
- public abstract U getMarker();
+ /**
+ * Get the MarkerView.
+ *
+ * @return the MarkerView created from this builder.
+ */
+ public abstract U getMarker();
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Icon.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Icon.java
index fceeb52713..b1a05ec436 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Icon.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Icon.java
@@ -10,43 +10,73 @@ import com.mapbox.mapboxsdk.maps.MapView;
* @see Marker
*/
public class Icon {
- private Bitmap mBitmap;
- private String mId;
+ private Bitmap mBitmap;
+ private String mId;
- Icon(String id, Bitmap bitmap) {
- mId = id;
- mBitmap = bitmap;
- }
-
- public String getId() {
- return mId;
- }
+ Icon(String id, Bitmap bitmap) {
+ mId = id;
+ mBitmap = bitmap;
+ }
- public Bitmap getBitmap() {
- return mBitmap;
- }
+ /**
+ * {@link String} identifier for this {@link Icon}.
+ *
+ * @return {@link String} identifier for this {@link Icon}.
+ */
+ public String getId() {
+ return mId;
+ }
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
+ /**
+ * Get the {@link Bitmap} being used for this {@link Icon}.
+ *
+ * @return The {@link Bitmap} being used for the {@link Icon}.
+ */
+ public Bitmap getBitmap() {
+ return mBitmap;
+ }
- Icon icon = (Icon) o;
+ /**
+ * Compares this {@link Icon} object with another {@link Icon} and determines if they match.
+ *
+ * @param object Another {@link Icon} to compare with this object.
+ * @return True if the {@link Icon} being passed in matches this {@link Icon} object. Else,
+ * false.
+ */
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (object == null || getClass() != object.getClass()) {
+ return false;
+ }
- if (!mBitmap.equals(icon.mBitmap)) return false;
- return mId.equals(icon.mId);
+ Icon icon = (Icon) object;
+ if (!mBitmap.equals(icon.mBitmap)) {
+ return false;
}
+ return mId.equals(icon.mId);
+ }
- @Override
- public int hashCode() {
- int result = 0;
- if (mBitmap != null) {
- result = mBitmap.hashCode();
- }
- if (mId != null) {
- result = 31 * result + mId.hashCode();
- }
- return result;
+ /**
+ * Gives an integer which can be used as the bucket number for storing elements of the set/map.
+ * This bucket number is the address of the element inside the set/map. There's no guarantee
+ * that this hash value will be consistent between different Java implementations, or even
+ * between different execution runs of the same program.
+ *
+ * @return integer value you can use for storing element.
+ */
+ @Override
+ public int hashCode() {
+ int result = 0;
+ if (mBitmap != null) {
+ result = mBitmap.hashCode();
+ }
+ if (mId != null) {
+ result = 31 * result + mId.hashCode();
}
+ return result;
+ }
}
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 56c1b643a1..052d5592e4 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
@@ -29,140 +29,207 @@ import java.io.InputStream;
*/
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;
- private Icon mDefaultMarker;
- private Icon mDefaultMarkerView;
- private BitmapFactory.Options mOptions;
-
- private int mNextId = 0;
-
- public static synchronized IconFactory getInstance(@NonNull Context context) {
- if (sInstance == null) {
- sInstance = new IconFactory(context.getApplicationContext());
- }
- return sInstance;
- }
+ 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 IconFactory(@NonNull Context context) {
- mContext = context;
- DisplayMetrics realMetrics = null;
- DisplayMetrics metrics = new DisplayMetrics();
- WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
- realMetrics = new DisplayMetrics();
- wm.getDefaultDisplay().getRealMetrics(realMetrics);
- }
- wm.getDefaultDisplay().getMetrics(metrics);
-
- mOptions = new BitmapFactory.Options();
- mOptions.inScaled = true;
- mOptions.inDensity = DisplayMetrics.DENSITY_DEFAULT;
- mOptions.inTargetDensity = metrics.densityDpi;
- if (realMetrics != null) {
- mOptions.inScreenDensity = realMetrics.densityDpi;
- }
- }
+ private Context mContext;
+ private static IconFactory sInstance;
+ private Icon mDefaultMarker;
+ private Icon mDefaultMarkerView;
+ private BitmapFactory.Options mOptions;
- public Icon fromBitmap(@NonNull Bitmap bitmap) {
- if (mNextId < 0) {
- throw new TooManyIconsException();
- }
- String id = ICON_ID_PREFIX + ++mNextId;
- return new Icon(id, bitmap);
- }
+ private int mNextId = 0;
- public Icon fromDrawable(@NonNull Drawable drawable) {
- int width = drawable.getIntrinsicWidth();
- int height = drawable.getIntrinsicHeight();
- return fromDrawable(drawable, width, height);
+ public static synchronized IconFactory getInstance(@NonNull Context context) {
+ if (sInstance == null) {
+ sInstance = new IconFactory(context.getApplicationContext());
}
-
- public Icon fromDrawable(@NonNull Drawable drawable, int width, int height) {
- if ((width < 0) || (height < 0)) {
- return null;
- }
-
- Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- Canvas canvas = new Canvas(bitmap);
- Rect temp = drawable.getBounds();
- Rect bounds = new Rect(0, 0, width, height);
- drawable.setBounds(bounds);
- drawable.draw(canvas);
- drawable.setBounds(temp);
- return fromBitmap(bitmap);
+ return sInstance;
+ }
+
+ private IconFactory(@NonNull Context context) {
+ mContext = context;
+ DisplayMetrics realMetrics = null;
+ DisplayMetrics metrics = new DisplayMetrics();
+ WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ realMetrics = new DisplayMetrics();
+ wm.getDefaultDisplay().getRealMetrics(realMetrics);
}
-
- public Icon fromResource(@DrawableRes int resourceId) {
- Drawable drawable = ContextCompat.getDrawable(mContext, resourceId);
- Bitmap bitmap;
- if (drawable instanceof BitmapDrawable) {
- BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
- bitmap = bitmapDrawable.getBitmap();
- } else {
- if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
- bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
- } else {
- bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
- }
-
- Canvas canvas = new Canvas(bitmap);
- drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
- drawable.draw(canvas);
- }
- return fromBitmap(bitmap);
+ wm.getDefaultDisplay().getMetrics(metrics);
+
+ mOptions = new BitmapFactory.Options();
+ mOptions.inScaled = true;
+ mOptions.inDensity = DisplayMetrics.DENSITY_DEFAULT;
+ mOptions.inTargetDensity = metrics.densityDpi;
+ if (realMetrics != null) {
+ mOptions.inScreenDensity = realMetrics.densityDpi;
}
-
- public Icon defaultMarker() {
- if (mDefaultMarker == null) {
- mDefaultMarker = fromResource(R.drawable.default_marker);
- }
- return mDefaultMarker;
+ }
+
+ /**
+ * Creates an {@link Icon} from a given Bitmap image.
+ *
+ * @param bitmap image used for creating the Icon.
+ * @return The {@link Icon} using the given Bitmap image.
+ */
+ public Icon fromBitmap(@NonNull Bitmap bitmap) {
+ if (mNextId < 0) {
+ throw new TooManyIconsException();
}
-
- public Icon defaultMarkerView() {
- if (mDefaultMarkerView == null) {
- mDefaultMarkerView = fromResource(R.drawable.default_markerview);
- }
- return mDefaultMarkerView;
+ String id = ICON_ID_PREFIX + ++mNextId;
+ return new Icon(id, bitmap);
+ }
+
+ /**
+ * Create an {@link Icon} from a given {@link Drawable}.
+ *
+ * @param drawable A {@link Drawable} object used for creating the {@link Icon}.
+ * @return {@link Icon} with the provided {@link Drawable}.
+ */
+ public Icon fromDrawable(@NonNull Drawable drawable) {
+ int width = drawable.getIntrinsicWidth();
+ int height = drawable.getIntrinsicHeight();
+ return fromDrawable(drawable, width, height);
+ }
+
+ /**
+ * Create an {@link Icon} from a given {@link Drawable}.
+ *
+ * @param drawable A {@link Drawable} object used for creating the {@link Icon}.
+ * @param width An integer greater then zero defining the {@link Icon} width.
+ * @param height An integer greater then zero defining the {@link Icon} height.
+ * @return {@link Icon} with the provided {@link Drawable}.
+ */
+ public Icon fromDrawable(@NonNull Drawable drawable, int width, int height) {
+ if ((width < 0) || (height < 0)) {
+ return null;
}
- private Icon fromInputStream(@NonNull InputStream is) {
- Bitmap bitmap = BitmapFactory.decodeStream(is, null, mOptions);
- return fromBitmap(bitmap);
+ Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(bitmap);
+ Rect temp = drawable.getBounds();
+ Rect bounds = new Rect(0, 0, width, height);
+ drawable.setBounds(bounds);
+ drawable.draw(canvas);
+ drawable.setBounds(temp);
+ return fromBitmap(bitmap);
+ }
+
+ /**
+ * Create an {@link Icon} using the resource ID of a Bitmap image.
+ *
+ * @param resourceId The resource ID of a Bitmap image.
+ * @return The {@link Icon} that was loaded from the asset or {@code null} if failed to load.
+ */
+ public Icon fromResource(@DrawableRes int resourceId) {
+ Drawable drawable = ContextCompat.getDrawable(mContext, resourceId);
+ Bitmap bitmap;
+ if (drawable instanceof BitmapDrawable) {
+ BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
+ bitmap = bitmapDrawable.getBitmap();
+ } else {
+ if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
+ bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
+ } else {
+ bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(),
+ Bitmap.Config.ARGB_8888);
+ }
+
+ Canvas canvas = new Canvas(bitmap);
+ drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
+ drawable.draw(canvas);
}
-
- public Icon fromAsset(@NonNull String assetName) {
- InputStream is;
- try {
- is = mContext.getAssets().open(assetName);
- } catch (IOException e) {
- return null;
- }
- return fromInputStream(is);
+ return fromBitmap(bitmap);
+ }
+
+ /**
+ * Provides an {@link Icon} using the default marker icon used for {@link Marker}.
+ *
+ * @return An {@link Icon} with the default {@link Marker} icon.
+ */
+ public Icon defaultMarker() {
+ if (mDefaultMarker == null) {
+ mDefaultMarker = fromResource(R.drawable.mapbox_marker_icon_default);
}
-
- public Icon fromPath(@NonNull String absolutePath) {
- Bitmap bitmap = BitmapFactory.decodeFile(absolutePath, mOptions);
- return fromBitmap(bitmap);
+ return mDefaultMarker;
+ }
+
+ /**
+ * Provides an {@link Icon} using the default marker icon used for {@link MarkerView}.
+ *
+ * @return An {@link Icon} with the default {@link MarkerView} icon.
+ */
+ public Icon defaultMarkerView() {
+ if (mDefaultMarkerView == null) {
+ mDefaultMarkerView = fromResource(R.drawable.mapbox_markerview_icon_default);
}
-
- public Icon fromFile(@NonNull String fileName) {
- FileInputStream is;
- try {
- is = mContext.openFileInput(fileName);
- } catch (FileNotFoundException e) {
- return null;
- }
- return fromInputStream(is);
+ return mDefaultMarkerView;
+ }
+
+ private Icon fromInputStream(@NonNull InputStream is) {
+ Bitmap bitmap = BitmapFactory.decodeStream(is, null, mOptions);
+ return fromBitmap(bitmap);
+ }
+
+ /**
+ * Creates an {@link Icon} using the name of a Bitmap image in the assets directory.
+ *
+ * @param assetName The name of a Bitmap image in the assets directory.
+ * @return The {@link Icon} that was loaded from the asset or {@code null} if failed to load.
+ */
+ public Icon fromAsset(@NonNull String assetName) {
+ InputStream is;
+ try {
+ is = mContext.getAssets().open(assetName);
+ } catch (IOException ioException) {
+ return null;
}
-
- public static Icon recreate(@NonNull String iconId, @NonNull Bitmap bitmap) {
- return new Icon(iconId, bitmap);
+ return fromInputStream(is);
+ }
+
+ /**
+ * Creates an {@link Icon} using the absolute file path of a Bitmap image.
+ *
+ * @param absolutePath The absolute path of the Bitmap image.
+ * @return The {@link Icon} that was loaded from the absolute path or {@code null} if failed to
+ * load.
+ */
+ public Icon fromPath(@NonNull String absolutePath) {
+ Bitmap bitmap = BitmapFactory.decodeFile(absolutePath, mOptions);
+ return fromBitmap(bitmap);
+ }
+
+ /**
+ * Create an {@link Icon} using the name of a Bitmap image file located in the internal storage.
+ * In particular, this calls {@link Context#openFileInput(String)}.
+ *
+ * @param fileName The name of the Bitmap image file.
+ * @return The {@link Icon} that was loaded from the asset or {@code null} if failed to load.
+ * @see <a href="https://developer.android.com/guide/topics/data/data-storage.html#filesInternal">
+ * Using the Internal Storage</a>
+ */
+ public Icon fromFile(@NonNull String fileName) {
+ FileInputStream is;
+ try {
+ is = mContext.openFileInput(fileName);
+ } catch (FileNotFoundException fileNotFoundException) {
+ return null;
}
+ return fromInputStream(is);
+ }
+
+ /**
+ * Create an {@link Icon} using a previously created icon identifier along with a provided
+ * Bitmap.
+ *
+ * @param iconId The {@link Icon} identifier you'd like to recreate.
+ * @param bitmap a Bitmap used to replace the current one.
+ * @return The {@link Icon} using the new Bitmap.
+ */
+ public static Icon recreate(@NonNull String iconId, @NonNull Bitmap bitmap) {
+ return new Icon(iconId, bitmap);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java
index 9af459e8a0..34d2c31139 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java
@@ -17,264 +17,285 @@ import com.mapbox.mapboxsdk.maps.MapboxMap;
import java.lang.ref.WeakReference;
/**
+ * {@code InfoWindow} is a tooltip shown when a {@link Marker} or {@link MarkerView} is tapped. Only
+ * one info window is displayed at a time. When the user clicks on a marker, the currently open info
+ * window will be closed and the new info window will be displayed. If the user clicks the same
+ * marker while its info window is currently open, the info window will be closed.
* <p>
- * InfoWindow is a tooltip shown when a {@link Marker} is tapped.
- * </p>
- * <p>
- * This is a UI element placed over a map at a specific geographic location.
+ * The info window is drawn oriented against the device's screen, centered above its associated
+ * marker by default. The info window anchoring can be adjusted using
+ * {@link MarkerView#setInfoWindowAnchor(float, float)} for {@link MarkerView}. The default info
+ * window contains the title in bold and snippet text below the title. While either the title and
+ * snippet are optional, at least one is required to open the info window.
* </p>
*/
public class InfoWindow {
- private WeakReference<Marker> mBoundMarker;
- private WeakReference<MapboxMap> mMapboxMap;
- protected WeakReference<View> mView;
-
- private float mMarkerHeightOffset;
- private float mMarkerWidthOffset;
- private float mViewWidthOffset;
- private PointF mCoordinates;
- private boolean mIsVisible;
-
- @LayoutRes
- private int mLayoutRes;
-
- InfoWindow(MapView mapView, int layoutResId, MapboxMap mapboxMap) {
- mLayoutRes = layoutResId;
- View view = LayoutInflater.from(mapView.getContext()).inflate(layoutResId, mapView, false);
- initialize(view, mapboxMap);
- }
+ private WeakReference<Marker> boundMarker;
+ private WeakReference<MapboxMap> mapboxMap;
+ protected WeakReference<View> view;
+
+ private float markerHeightOffset;
+ private float markerWidthOffset;
+ private float viewWidthOffset;
+ private PointF coordinates;
+ private boolean isVisible;
+
+ @LayoutRes
+ private int layoutRes;
+
+ InfoWindow(MapView mapView, int layoutResId, MapboxMap mapboxMap) {
+ layoutRes = layoutResId;
+ View view = LayoutInflater.from(mapView.getContext()).inflate(layoutResId, mapView, false);
+ initialize(view, mapboxMap);
+ }
+
+ InfoWindow(View view, MapboxMap mapboxMap) {
+ initialize(view, mapboxMap);
+ }
+
+ private void initialize(View view, MapboxMap mapboxMap) {
+ this.mapboxMap = new WeakReference<>(mapboxMap);
+ isVisible = false;
+ this.view = new WeakReference<>(view);
+
+ view.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ MapboxMap mapboxMap = InfoWindow.this.mapboxMap.get();
+ if (mapboxMap != null) {
+ MapboxMap.OnInfoWindowClickListener onInfoWindowClickListener = mapboxMap.getOnInfoWindowClickListener();
+ boolean handledDefaultClick = false;
+ if (onInfoWindowClickListener != null) {
+ handledDefaultClick = onInfoWindowClickListener.onInfoWindowClick(getBoundMarker());
+ }
+
+ if (!handledDefaultClick) {
+ // default behavior: close it when clicking on the tooltip:
+ close();
+ }
+ }
+ }
+ });
+
+ view.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ MapboxMap mapboxMap = InfoWindow.this.mapboxMap.get();
+ if (mapboxMap != null) {
+ MapboxMap.OnInfoWindowLongClickListener listener = mapboxMap.getOnInfoWindowLongClickListener();
+ if (listener != null) {
+ listener.onInfoWindowLongClick(getBoundMarker());
+ }
+ }
+ return true;
+ }
+ });
+ }
+
+
+ /**
+ * Open the info window at the specified position.
+ *
+ * @param boundMarker The marker on which is hooked the view.
+ * @param position to place the window on the map.
+ * @param offsetX The offset of the view to the position, in pixels. This allows to offset
+ * the view from the object position.
+ * @param offsetY The offset of the view to the position, in pixels. This allows to offset
+ * the view from the object position.
+ * @return this {@link InfoWindow}.
+ */
+ InfoWindow open(MapView mapView, Marker boundMarker, LatLng position, int offsetX, int offsetY) {
+ setBoundMarker(boundMarker);
+
+ MapView.LayoutParams lp = new MapView.LayoutParams(MapView.LayoutParams.WRAP_CONTENT,
+ MapView.LayoutParams.WRAP_CONTENT);
+
+ MapboxMap mapboxMap = this.mapboxMap.get();
+ View view = this.view.get();
+ if (view != null && mapboxMap != null) {
+ view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
+
+ // Calculate y-offset for update method
+ markerHeightOffset = -view.getMeasuredHeight() + offsetY;
+ markerWidthOffset = -offsetX;
+
+ // Calculate default Android x,y coordinate
+ coordinates = mapboxMap.getProjection().toScreenLocation(position);
+ float x = coordinates.x - (view.getMeasuredWidth() / 2) + offsetX;
+ float y = coordinates.y - view.getMeasuredHeight() + offsetY;
+
+ if (view instanceof InfoWindowView) {
+ // only apply repositioning/margin for InfoWindowView
+ Resources resources = mapView.getContext().getResources();
+
+ // get right/left popup window
+ float rightSideInfowWindow = x + view.getMeasuredWidth();
+ float leftSideInfoWindow = x;
+
+ // get right/left map view
+ final float mapRight = mapView.getRight();
+ final float mapLeft = mapView.getLeft();
+
+ float marginHorizontal = resources.getDimension(R.dimen.mapbox_infowindow_margin);
+ float tipViewOffset = resources.getDimension(R.dimen.mapbox_infowindow_tipview_width) / 2;
+ float tipViewMarginLeft = view.getMeasuredWidth() / 2 - tipViewOffset;
+
+ boolean outOfBoundsLeft = false;
+ boolean outOfBoundsRight = false;
+
+ // only optimise margins if view is inside current viewport
+ if (coordinates.x >= 0 && coordinates.x <= mapView.getWidth()
+ && coordinates.y >= 0 && coordinates.y <= mapView.getHeight()) {
+
+ // if out of bounds right
+ if (rightSideInfowWindow > mapRight) {
+ outOfBoundsRight = true;
+ x -= rightSideInfowWindow - mapRight;
+ tipViewMarginLeft += rightSideInfowWindow - mapRight + tipViewOffset;
+ rightSideInfowWindow = x + view.getMeasuredWidth();
+ }
+
+ // fit screen left
+ if (leftSideInfoWindow < mapLeft) {
+ outOfBoundsLeft = true;
+ x += mapLeft - leftSideInfoWindow;
+ tipViewMarginLeft -= mapLeft - leftSideInfoWindow + tipViewOffset;
+ leftSideInfoWindow = x;
+ }
+
+ // Add margin right
+ if (outOfBoundsRight && mapRight - rightSideInfowWindow < marginHorizontal) {
+ x -= marginHorizontal - (mapRight - rightSideInfowWindow);
+ tipViewMarginLeft += marginHorizontal - (mapRight - rightSideInfowWindow) - tipViewOffset;
+ leftSideInfoWindow = x;
+ }
+
+ // Add margin left
+ if (outOfBoundsLeft && leftSideInfoWindow - mapLeft < marginHorizontal) {
+ x += marginHorizontal - (leftSideInfoWindow - mapLeft);
+ tipViewMarginLeft -= (marginHorizontal - (leftSideInfoWindow - mapLeft)) - tipViewOffset;
+ }
+ }
- InfoWindow(View view, MapboxMap mapboxMap) {
- initialize(view, mapboxMap);
- }
+ // Adjust tipView
+ InfoWindowView infoWindowView = (InfoWindowView) view;
+ infoWindowView.setTipViewMarginLeft((int) tipViewMarginLeft);
+ }
- private void initialize(View view, MapboxMap mapboxMap) {
- mMapboxMap = new WeakReference<>(mapboxMap);
- mIsVisible = false;
- mView = new WeakReference<>(view);
-
- view.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- MapboxMap mapboxMap = mMapboxMap.get();
- if (mapboxMap != null) {
- MapboxMap.OnInfoWindowClickListener onInfoWindowClickListener = mapboxMap.getOnInfoWindowClickListener();
- boolean handledDefaultClick = false;
- if (onInfoWindowClickListener != null) {
- handledDefaultClick = onInfoWindowClickListener.onInfoWindowClick(getBoundMarker());
- }
-
- if (!handledDefaultClick) {
- // default behavior: close it when clicking on the tooltip:
- close();
- }
- }
- }
- });
-
- view.setOnLongClickListener(new View.OnLongClickListener() {
- @Override
- public boolean onLongClick(View v) {
- MapboxMap mapboxMap = mMapboxMap.get();
- if (mapboxMap != null) {
- MapboxMap.OnInfoWindowLongClickListener listener = mapboxMap.getOnInfoWindowLongClickListener();
- if (listener != null) {
- listener.onInfoWindowLongClick(getBoundMarker());
- }
- }
- return true;
- }
- });
- }
+ // set anchor popupwindowview
+ view.setX(x);
+ view.setY(y);
+ // Calculate x-offset for update method
+ viewWidthOffset = x - coordinates.x - offsetX;
- /**
- * open the window at the specified position.
- *
- * @param boundMarker the marker on which is hooked the view
- * @param position to place the window on the map
- * @param offsetX (&offsetY) the offset of the view to the position, in pixels.
- * This allows to offset the view from the object position.
- * @return this infowindow
- */
- InfoWindow open(MapView mapView, Marker boundMarker, LatLng position, int offsetX, int offsetY) {
- setBoundMarker(boundMarker);
-
- MapView.LayoutParams lp = new MapView.LayoutParams(MapView.LayoutParams.WRAP_CONTENT, MapView.LayoutParams.WRAP_CONTENT);
-
- MapboxMap mapboxMap = mMapboxMap.get();
- View view = mView.get();
- if (view != null && mapboxMap != null) {
- view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
-
- // Calculate y-offset for update method
- mMarkerHeightOffset = -view.getMeasuredHeight() + offsetY;
- mMarkerWidthOffset = -offsetX;
-
- // Calculate default Android x,y coordinate
- mCoordinates = mapboxMap.getProjection().toScreenLocation(position);
- float x = mCoordinates.x - (view.getMeasuredWidth() / 2) + offsetX;
- float y = mCoordinates.y - view.getMeasuredHeight() + offsetY;
-
- if (view instanceof InfoWindowView) {
- // only apply repositioning/margin for InfoWindowView
- Resources resources = mapView.getContext().getResources();
-
- // get right/left popup window
- float rightSideInfowWindow = x + view.getMeasuredWidth();
- float leftSideInfoWindow = x;
-
- // get right/left map view
- final float mapRight = mapView.getRight();
- final float mapLeft = mapView.getLeft();
-
- float marginHorizontal = resources.getDimension(R.dimen.infowindow_margin);
- float tipViewOffset = resources.getDimension(R.dimen.infowindow_tipview_width) / 2;
- float tipViewMarginLeft = view.getMeasuredWidth() / 2 - tipViewOffset;
-
- boolean outOfBoundsLeft = false;
- boolean outOfBoundsRight = false;
-
- // if out of bounds right
- if (rightSideInfowWindow > mapRight) {
- outOfBoundsRight = true;
- x -= rightSideInfowWindow - mapRight;
- tipViewMarginLeft += rightSideInfowWindow - mapRight + tipViewOffset;
- rightSideInfowWindow = x + view.getMeasuredWidth();
- }
-
- // fit screen left
- if (leftSideInfoWindow < mapLeft) {
- outOfBoundsLeft = true;
- x += mapLeft - leftSideInfoWindow;
- tipViewMarginLeft -= mapLeft - leftSideInfoWindow + tipViewOffset;
- leftSideInfoWindow = x;
- }
-
- // Add margin right
- if (outOfBoundsRight && mapRight - rightSideInfowWindow < marginHorizontal) {
- x -= marginHorizontal - (mapRight - rightSideInfowWindow);
- tipViewMarginLeft += marginHorizontal - (mapRight - rightSideInfowWindow) - tipViewOffset;
- leftSideInfoWindow = x;
- }
-
- // Add margin left
- if (outOfBoundsLeft && leftSideInfoWindow - mapLeft < marginHorizontal) {
- x += marginHorizontal - (leftSideInfoWindow - mapLeft);
- tipViewMarginLeft -= (marginHorizontal - (leftSideInfoWindow - mapLeft)) - tipViewOffset;
- }
-
- // Adjust tipView
- InfoWindowView infoWindowView = (InfoWindowView) view;
- infoWindowView.setTipViewMarginLeft((int) tipViewMarginLeft);
- }
-
- // set anchor popupwindowview
- view.setX(x);
- view.setY(y);
-
- // Calculate x-offset for update method
- mViewWidthOffset = x - mCoordinates.x - offsetX;
-
- close(); //if it was already opened
- mapView.addView(view, lp);
- mIsVisible = true;
- }
- return this;
+ close(); //if it was already opened
+ mapView.addView(view, lp);
+ isVisible = true;
}
-
- /**
- * Close this InfoWindow if it is visible, otherwise don't do anything.
- *
- * @return this info window
- */
- InfoWindow close() {
- MapboxMap mapboxMap = mMapboxMap.get();
- if (mIsVisible && mapboxMap != null) {
- mIsVisible = false;
- View view = mView.get();
- if (view != null && view.getParent() != null) {
- ((ViewGroup) view.getParent()).removeView(view);
- }
-
- Marker marker = getBoundMarker();
- MapboxMap.OnInfoWindowCloseListener listener = mapboxMap.getOnInfoWindowCloseListener();
- if (listener != null) {
- listener.onInfoWindowClose(marker);
- }
-
- setBoundMarker(null);
- }
- return this;
+ return this;
+ }
+
+ /**
+ * Close this {@link InfoWindow} if it is visible, otherwise calling this will do nothing.
+ *
+ * @return This {@link InfoWindow}
+ */
+ InfoWindow close() {
+ MapboxMap mapboxMap = this.mapboxMap.get();
+ if (isVisible && mapboxMap != null) {
+ isVisible = false;
+ View view = this.view.get();
+ if (view != null && view.getParent() != null) {
+ ((ViewGroup) view.getParent()).removeView(view);
+ }
+
+ Marker marker = getBoundMarker();
+ MapboxMap.OnInfoWindowCloseListener listener = mapboxMap.getOnInfoWindowCloseListener();
+ if (listener != null) {
+ listener.onInfoWindowClose(marker);
+ }
+
+ setBoundMarker(null);
}
-
- /**
- * Constructs the view that is displayed when the InfoWindow opens.
- * This retrieves data from overlayItem and shows it in the tooltip.
- *
- * @param overlayItem the tapped overlay item
- */
- void adaptDefaultMarker(Marker overlayItem, MapboxMap mapboxMap, MapView mapView) {
- View view = mView.get();
- if (view == null) {
- view = LayoutInflater.from(mapView.getContext()).inflate(mLayoutRes, mapView, false);
- initialize(view, mapboxMap);
- }
- mMapboxMap = new WeakReference<>(mapboxMap);
- String title = overlayItem.getTitle();
- TextView titleTextView = ((TextView) view.findViewById(R.id.infowindow_title));
- if (!TextUtils.isEmpty(title)) {
- titleTextView.setText(title);
- titleTextView.setVisibility(View.VISIBLE);
- } else {
- titleTextView.setVisibility(View.GONE);
- }
-
- String snippet = overlayItem.getSnippet();
- TextView snippetTextView = ((TextView) view.findViewById(R.id.infowindow_description));
- if (!TextUtils.isEmpty(snippet)) {
- snippetTextView.setText(snippet);
- snippetTextView.setVisibility(View.VISIBLE);
- } else {
- snippetTextView.setVisibility(View.GONE);
- }
+ return this;
+ }
+
+ /**
+ * Constructs the view that is displayed when the InfoWindow opens. This retrieves data from
+ * overlayItem and shows it in the tooltip.
+ *
+ * @param overlayItem the tapped overlay item
+ */
+ void adaptDefaultMarker(Marker overlayItem, MapboxMap mapboxMap, MapView mapView) {
+ View view = this.view.get();
+ if (view == null) {
+ view = LayoutInflater.from(mapView.getContext()).inflate(layoutRes, mapView, false);
+ initialize(view, mapboxMap);
}
-
- InfoWindow setBoundMarker(Marker boundMarker) {
- mBoundMarker = new WeakReference<>(boundMarker);
- return this;
+ this.mapboxMap = new WeakReference<>(mapboxMap);
+ String title = overlayItem.getTitle();
+ TextView titleTextView = ((TextView) view.findViewById(R.id.infowindow_title));
+ if (!TextUtils.isEmpty(title)) {
+ titleTextView.setText(title);
+ titleTextView.setVisibility(View.VISIBLE);
+ } else {
+ titleTextView.setVisibility(View.GONE);
}
- Marker getBoundMarker() {
- if (mBoundMarker == null) {
- return null;
- }
- return mBoundMarker.get();
+ String snippet = overlayItem.getSnippet();
+ TextView snippetTextView = ((TextView) view.findViewById(R.id.infowindow_description));
+ if (!TextUtils.isEmpty(snippet)) {
+ snippetTextView.setText(snippet);
+ snippetTextView.setVisibility(View.VISIBLE);
+ } else {
+ snippetTextView.setVisibility(View.GONE);
}
+ }
- public void update() {
- MapboxMap mapboxMap = mMapboxMap.get();
- Marker marker = mBoundMarker.get();
- View view = mView.get();
- if (mapboxMap != null && marker != null && view != null) {
- mCoordinates = mapboxMap.getProjection().toScreenLocation(marker.getPosition());
-
- if (view instanceof InfoWindowView) {
- view.setX(mCoordinates.x + mViewWidthOffset - mMarkerWidthOffset);
- } else {
- view.setX(mCoordinates.x - (view.getMeasuredWidth() / 2) - mMarkerWidthOffset);
- }
- view.setY(mCoordinates.y + mMarkerHeightOffset);
- }
- }
+ InfoWindow setBoundMarker(Marker boundMarker) {
+ this.boundMarker = new WeakReference<>(boundMarker);
+ return this;
+ }
- public View getView() {
- return mView != null ? mView.get() : null;
+ Marker getBoundMarker() {
+ if (boundMarker == null) {
+ return null;
}
-
- boolean isVisible() {
- return mIsVisible;
+ return boundMarker.get();
+ }
+
+ /**
+ * Will result in getting this {@link InfoWindow} and updating the view being displayed.
+ */
+ public void update() {
+ MapboxMap mapboxMap = this.mapboxMap.get();
+ Marker marker = boundMarker.get();
+ View view = this.view.get();
+ if (mapboxMap != null && marker != null && view != null) {
+ coordinates = mapboxMap.getProjection().toScreenLocation(marker.getPosition());
+
+ if (view instanceof InfoWindowView) {
+ view.setX(coordinates.x + viewWidthOffset - markerWidthOffset);
+ } else {
+ view.setX(coordinates.x - (view.getMeasuredWidth() / 2) - markerWidthOffset);
+ }
+ view.setY(coordinates.y + markerHeightOffset);
}
+ }
+
+ /**
+ * Retrieve this {@link InfoWindow}'s current view being used.
+ *
+ * @return This {@link InfoWindow}'s current View.
+ */
+ public View getView() {
+ return view != null ? view.get() : null;
+ }
+
+ boolean isVisible() {
+ return isVisible;
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindowTipView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindowTipView.java
index d2afafc59d..abcebfec83 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindowTipView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindowTipView.java
@@ -12,51 +12,51 @@ import com.mapbox.mapboxsdk.R;
final class InfoWindowTipView extends View {
- private Paint mPaint;
- private Path mPath;
- private int mLineWidth;
-
- public InfoWindowTipView(Context context, AttributeSet attrs) {
- super(context, attrs);
-
- mPath = new Path();
- mLineWidth = (int) context.getResources().getDimension(R.dimen.infowindow_line_width);
- mPaint = new Paint();
- mPaint.setColor(Color.WHITE);
- mPaint.setAntiAlias(true);
- mPaint.setStrokeWidth(0.0f);
- mPaint.setStyle(Paint.Style.FILL);
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- int height = getMeasuredHeight();
- int width = getMeasuredWidth();
-
- mPath.rewind();
-
- this.mPaint.setColor(Color.WHITE);
- this.mPaint.setAntiAlias(true);
- this.mPaint.setStrokeWidth(0.0f);
- this.mPaint.setStyle(Paint.Style.FILL);
-
- mPath.moveTo(0, 0);
- mPath.lineTo(width, 0);
- mPath.lineTo((width / 2), height);
- mPath.lineTo(0, 0);
- canvas.drawPath(mPath, this.mPaint);
-
- mPath.rewind();
-
- this.mPaint.setColor(Color.parseColor("#C2C2C2"));
- this.mPaint.setAntiAlias(true);
- this.mPaint.setStrokeWidth(mLineWidth);
- this.mPaint.setStyle(Paint.Style.STROKE);
-
- mPath.moveTo(0, 0);
- mPath.lineTo(width / 2, height);
- mPath.lineTo(width, 0);
- canvas.drawPath(mPath, this.mPaint);
- }
+ private Paint mPaint;
+ private Path mPath;
+ private int mLineWidth;
+
+ public InfoWindowTipView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ mPath = new Path();
+ mLineWidth = (int) context.getResources().getDimension(R.dimen.mapbox_infowindow_line_width);
+ mPaint = new Paint();
+ mPaint.setColor(Color.WHITE);
+ mPaint.setAntiAlias(true);
+ mPaint.setStrokeWidth(0.0f);
+ mPaint.setStyle(Paint.Style.FILL);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ int height = getMeasuredHeight();
+ int width = getMeasuredWidth();
+
+ mPath.rewind();
+
+ this.mPaint.setColor(Color.WHITE);
+ this.mPaint.setAntiAlias(true);
+ this.mPaint.setStrokeWidth(0.0f);
+ this.mPaint.setStyle(Paint.Style.FILL);
+
+ mPath.moveTo(0, 0);
+ mPath.lineTo(width, 0);
+ mPath.lineTo((width / 2), height);
+ mPath.lineTo(0, 0);
+ canvas.drawPath(mPath, this.mPaint);
+
+ mPath.rewind();
+
+ this.mPaint.setColor(Color.parseColor("#C2C2C2"));
+ this.mPaint.setAntiAlias(true);
+ this.mPaint.setStrokeWidth(mLineWidth);
+ this.mPaint.setStyle(Paint.Style.STROKE);
+
+ mPath.moveTo(0, 0);
+ mPath.lineTo(width / 2, height);
+ mPath.lineTo(width, 0);
+ canvas.drawPath(mPath, this.mPaint);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindowView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindowView.java
index 80dc5931a7..d1a59aae4e 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindowView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindowView.java
@@ -9,30 +9,30 @@ import com.mapbox.mapboxsdk.R;
class InfoWindowView extends RelativeLayout {
- private InfoWindowTipView mTipView;
-
- public InfoWindowView(Context context) {
- this(context, null);
- }
-
- public InfoWindowView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public InfoWindowView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- initialize(context);
- }
-
- private void initialize(Context context) {
- LayoutInflater.from(context).inflate(R.layout.infowindow_content, this);
- mTipView = (InfoWindowTipView) findViewById(R.id.infowindow_tipview);
- }
-
- void setTipViewMarginLeft(int marginLeft) {
- RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mTipView.getLayoutParams();
- layoutParams.leftMargin = marginLeft;
- // This is a bit of a hack but prevents an occasional gap between the InfoWindow
- layoutParams.topMargin = (int) getResources().getDimension(R.dimen.infowindow_offset);
- }
+ private InfoWindowTipView mTipView;
+
+ public InfoWindowView(Context context) {
+ this(context, null);
+ }
+
+ public InfoWindowView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public InfoWindowView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ initialize(context);
+ }
+
+ private void initialize(Context context) {
+ LayoutInflater.from(context).inflate(R.layout.mapbox_infowindow_content, this);
+ mTipView = (InfoWindowTipView) findViewById(R.id.infowindow_tipview);
+ }
+
+ void setTipViewMarginLeft(int marginLeft) {
+ RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mTipView.getLayoutParams();
+ layoutParams.leftMargin = marginLeft;
+ // This is a bit of a hack but prevents an occasional gap between the InfoWindow
+ layoutParams.topMargin = (int) getResources().getDimension(R.dimen.mapbox_infowindow_offset);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java
index e1f692a6f4..edf118205b 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java
@@ -10,206 +10,266 @@ import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
/**
- * Marker is an annotation that shows an icon image at a geographical location.
+ * Marker is an annotation that shows an icon image at a geographical location. The default marker
+ * uses a provided icon. This icon can be customized using {@link IconFactory} to generate an
+ * {@link Icon} using a provided image. Markers are added to the map by first giving a
+ * {@link LatLng} and using {@link MapboxMap#addMarker(MarkerOptions)}. The marker icon will be
+ * centered at this position so it is common to add padding to the icon image before usage.
* <p>
- * An {@link InfoWindow} can be shown when a Marker is pressed
+ * If more customization is needed, we offer {@link MarkerView} which places a {@link View} on top
+ * of the map at a geographical location.
+ * </p>
+ * <p>
+ * Markers are designed to be interactive. They receive click events by default, and are often used
+ * with event listeners to bring up info windows. An {@link InfoWindow} is displayed by default when
+ * either a title or snippet is provided.
* </p>
*/
public class Marker extends Annotation {
- private LatLng position;
- private String snippet;
- private Icon icon;
- private String title;
+ private LatLng position;
+ private String snippet;
+ private Icon icon;
+ private String title;
- private InfoWindow infoWindow;
- private boolean infoWindowShown;
+ private InfoWindow infoWindow;
+ private boolean infoWindowShown;
- private int topOffsetPixels;
- private int rightOffsetPixels;
+ private int topOffsetPixels;
+ private int rightOffsetPixels;
- /**
- * Constructor
- */
- Marker() {
- super();
- }
+ /**
+ * Constructor
+ */
+ Marker() {
+ super();
+ }
- public Marker(BaseMarkerOptions baseMarkerOptions) {
- position = baseMarkerOptions.position;
- snippet = baseMarkerOptions.snippet;
- icon = baseMarkerOptions.icon;
- title = baseMarkerOptions.title;
- }
+ /**
+ * Creates a instance of {@link Marker} using the builder of Marker.
+ *
+ * @param baseMarkerOptions The builder used to construct the Marker.
+ */
+ public Marker(BaseMarkerOptions baseMarkerOptions) {
+ position = baseMarkerOptions.position;
+ snippet = baseMarkerOptions.snippet;
+ icon = baseMarkerOptions.icon;
+ title = baseMarkerOptions.title;
+ }
- Marker(BaseMarkerViewOptions baseMarkerViewOptions) {
- position = baseMarkerViewOptions.position;
- snippet = baseMarkerViewOptions.snippet;
- icon = baseMarkerViewOptions.icon;
- title = baseMarkerViewOptions.title;
- }
+ Marker(BaseMarkerViewOptions baseMarkerViewOptions) {
+ position = baseMarkerViewOptions.position;
+ snippet = baseMarkerViewOptions.snippet;
+ icon = baseMarkerViewOptions.icon;
+ title = baseMarkerViewOptions.title;
+ }
- Marker(LatLng position, Icon icon, String title, String snippet) {
- this.position = position;
- this.icon = icon;
- this.title = title;
- this.snippet = snippet;
- }
+ Marker(LatLng position, Icon icon, String title, String snippet) {
+ this.position = position;
+ this.icon = icon;
+ this.title = title;
+ this.snippet = snippet;
+ }
- public LatLng getPosition() {
- return position;
- }
+ /**
+ * Returns the position of the marker.
+ *
+ * @return A {@link LatLng} object specifying the marker's current position.
+ */
+ public LatLng getPosition() {
+ return position;
+ }
- public String getSnippet() {
- return snippet;
- }
+ /**
+ * Gets the snippet of the marker.
+ *
+ * @return A string containing the marker's snippet.
+ */
+ public String getSnippet() {
+ return snippet;
+ }
- public String getTitle() {
- return title;
- }
+ /**
+ * Gets the snippet of the marker.
+ *
+ * @return A string containing the marker's snippet.
+ */
+ public String getTitle() {
+ return title;
+ }
- /**
- * Do not use this method. Used internally by the SDK.
- */
- public void hideInfoWindow() {
- if (infoWindow != null) {
- infoWindow.close();
- }
- infoWindowShown = false;
+ /**
+ * Do not use this method, used internally by the SDK.
+ */
+ public void hideInfoWindow() {
+ if (infoWindow != null) {
+ infoWindow.close();
}
+ infoWindowShown = false;
+ }
- /**
- * Do not use this method. Used internally by the SDK.
- *
- * @return true if the infoWindow is shown
- */
- public boolean isInfoWindowShown() {
- return infoWindowShown;
- }
+ /**
+ * Do not use this method, used internally by the SDK.
+ *
+ * @return true if the infoWindow is shown
+ */
+ public boolean isInfoWindowShown() {
+ return infoWindowShown;
+ }
- /**
- * Sets the position.
- *
- * @param position new position
- */
- public void setPosition(LatLng position) {
- this.position = position;
- MapboxMap map = getMapboxMap();
- if (map != null) {
- map.updateMarker(this);
- }
+ /**
+ * Sets the location of the marker.
+ *
+ * @param position A {@link LatLng} defining the marker position.
+ */
+ public void setPosition(LatLng position) {
+ this.position = position;
+ MapboxMap map = getMapboxMap();
+ if (map != null) {
+ map.updateMarker(this);
}
+ }
- public void setSnippet(String snippet) {
- this.snippet = snippet;
- refreshInfoWindowContent();
- }
+ /**
+ * Sets the snippet of the marker.
+ *
+ * @param snippet A String used in the marker info window. If {@code null}, the snippet is
+ * cleared.
+ */
+ public void setSnippet(String snippet) {
+ this.snippet = snippet;
+ refreshInfoWindowContent();
+ }
- /**
- * Sets the icon.
- *
- * @param icon The icon to be used as Marker image
- */
- public void setIcon(@Nullable Icon icon) {
- this.icon = icon;
- MapboxMap map = getMapboxMap();
- if (map != null) {
- map.updateMarker(this);
- }
+ /**
+ * Sets the icon of the marker.
+ *
+ * @param icon The {@link Icon} to be used as Marker image
+ */
+ public void setIcon(@Nullable Icon icon) {
+ this.icon = icon;
+ MapboxMap map = getMapboxMap();
+ if (map != null) {
+ map.updateMarker(this);
}
+ }
- public Icon getIcon() {
- return icon;
- }
+ /**
+ * Gets the {@link Icon} currently used for the marker. If no Icon was set for the marker, the
+ * default icon will be returned.
+ *
+ * @return The {@link Icon} the marker is using.
+ */
+ public Icon getIcon() {
+ return icon;
+ }
- public void setTitle(String title) {
- this.title = title;
- refreshInfoWindowContent();
- }
+ /**
+ * Sets the title of the marker.
+ *
+ * @param title A String used in the marker info window. If {@code null}, the title is
+ * cleared.
+ */
+ public void setTitle(String title) {
+ this.title = title;
+ refreshInfoWindowContent();
+ }
- @Nullable
- public InfoWindow getInfoWindow() {
- return infoWindow;
- }
+ /**
+ * Gets the {@link InfoWindow} the marker is using. If the marker hasn't had an info window
+ * defined, this will return {@code null}.
+ *
+ * @return The info window the marker is using.
+ */
+ @Nullable
+ public InfoWindow getInfoWindow() {
+ return infoWindow;
+ }
- /**
- * Update only for default Marker's InfoWindow content for Title and Snippet
- */
- private void refreshInfoWindowContent() {
- if (isInfoWindowShown() && mapView != null && mapboxMap != null && mapboxMap.getInfoWindowAdapter() == null) {
- InfoWindow infoWindow = getInfoWindow(mapView);
- if (mapView.getContext() != null) {
- infoWindow.adaptDefaultMarker(this, mapboxMap, mapView);
- }
- MapboxMap map = getMapboxMap();
- if (map != null) {
- map.updateMarker(this);
- }
- infoWindow.update();
- }
+ /**
+ * Update only for default Marker's InfoWindow content for Title and Snippet
+ */
+ private void refreshInfoWindowContent() {
+ if (isInfoWindowShown() && mapView != null && mapboxMap != null && mapboxMap.getInfoWindowAdapter() == null) {
+ InfoWindow infoWindow = getInfoWindow(mapView);
+ if (mapView.getContext() != null) {
+ infoWindow.adaptDefaultMarker(this, mapboxMap, mapView);
+ }
+ MapboxMap map = getMapboxMap();
+ if (map != null) {
+ map.updateMarker(this);
+ }
+ infoWindow.update();
}
+ }
- /**
- * Do not use this method. Used internally by the SDK.
- *
- * @param mapboxMap the hosting mapbox map
- * @param mapView the hosting map view
- * @return the info window that was shown
- */
- public InfoWindow showInfoWindow(@NonNull MapboxMap mapboxMap, @NonNull MapView mapView) {
- setMapboxMap(mapboxMap);
- setMapView(mapView);
- MapboxMap.InfoWindowAdapter infoWindowAdapter = getMapboxMap().getInfoWindowAdapter();
- if (infoWindowAdapter != null) {
- // end developer is using a custom InfoWindowAdapter
- View content = infoWindowAdapter.getInfoWindow(this);
- if (content != null) {
- infoWindow = new InfoWindow(content, mapboxMap);
- showInfoWindow(infoWindow, mapView);
- return infoWindow;
- }
- }
-
- InfoWindow infoWindow = getInfoWindow(mapView);
- if (mapView.getContext() != null) {
- infoWindow.adaptDefaultMarker(this, mapboxMap, mapView);
- }
- return showInfoWindow(infoWindow, mapView);
+ /**
+ * Do not use this method, used internally by the SDK. Use {@link MapboxMap#selectMarker(Marker)}
+ * if you want to programmatically display the markers info window.
+ *
+ * @param mapboxMap The hosting mapbox map.
+ * @param mapView The hosting map view.
+ * @return The info window that was shown.
+ */
+ public InfoWindow showInfoWindow(@NonNull MapboxMap mapboxMap, @NonNull MapView mapView) {
+ setMapboxMap(mapboxMap);
+ setMapView(mapView);
+ MapboxMap.InfoWindowAdapter infoWindowAdapter = getMapboxMap().getInfoWindowAdapter();
+ if (infoWindowAdapter != null) {
+ // end developer is using a custom InfoWindowAdapter
+ View content = infoWindowAdapter.getInfoWindow(this);
+ if (content != null) {
+ infoWindow = new InfoWindow(content, mapboxMap);
+ showInfoWindow(infoWindow, mapView);
+ return infoWindow;
+ }
}
- private InfoWindow showInfoWindow(InfoWindow iw, MapView mapView) {
- iw.open(mapView, this, getPosition(), rightOffsetPixels, topOffsetPixels);
- infoWindowShown = true;
- return iw;
+ InfoWindow infoWindow = getInfoWindow(mapView);
+ if (mapView.getContext() != null) {
+ infoWindow.adaptDefaultMarker(this, mapboxMap, mapView);
}
+ return showInfoWindow(infoWindow, mapView);
+ }
- private InfoWindow getInfoWindow(@NonNull MapView mapView) {
- if (infoWindow == null && mapView.getContext() != null) {
- infoWindow = new InfoWindow(mapView, R.layout.infowindow_view, getMapboxMap());
- }
- return infoWindow;
- }
+ private InfoWindow showInfoWindow(InfoWindow iw, MapView mapView) {
+ iw.open(mapView, this, getPosition(), rightOffsetPixels, topOffsetPixels);
+ infoWindowShown = true;
+ return iw;
+ }
- /**
- * Do not use this method. Used internally by the SDK.
- *
- * @param topOffsetPixels the top offset pixels.
- */
- public void setTopOffsetPixels(int topOffsetPixels) {
- this.topOffsetPixels = topOffsetPixels;
+ private InfoWindow getInfoWindow(@NonNull MapView mapView) {
+ if (infoWindow == null && mapView.getContext() != null) {
+ infoWindow = new InfoWindow(mapView, R.layout.mapbox_infowindow_view, getMapboxMap());
}
+ return infoWindow;
+ }
- /**
- * Do not use this method. Used internally by the SDK.
- *
- * @param rightOffsetPixels the right offset pixels.
- */
- public void setRightOffsetPixels(int rightOffsetPixels) {
- this.rightOffsetPixels = rightOffsetPixels;
- }
+ /**
+ * Do not use this method, used internally by the SDK.
+ *
+ * @param topOffsetPixels the top offset pixels.
+ */
+ public void setTopOffsetPixels(int topOffsetPixels) {
+ this.topOffsetPixels = topOffsetPixels;
+ }
- @Override
- public String toString() {
- return "Marker [position[" + getPosition() + "]]";
- }
+ /**
+ * Do not use this method, used internally by the SDK.
+ *
+ * @param rightOffsetPixels the right offset pixels.
+ */
+ public void setRightOffsetPixels(int rightOffsetPixels) {
+ this.rightOffsetPixels = rightOffsetPixels;
+ }
+
+ /**
+ * Returns a String with the marker position.
+ *
+ * @return A String with the marker position.
+ */
+ @Override
+ public String toString() {
+ return "Marker [position[" + getPosition() + "]]";
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerOptions.java
index 328ee1894c..49d4867801 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerOptions.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerOptions.java
@@ -7,14 +7,13 @@ import android.os.Parcelable;
import com.mapbox.mapboxsdk.exceptions.InvalidMarkerPositionException;
import com.mapbox.mapboxsdk.geometry.LatLng;
-
/**
* <p>
- * Builder for composing {@link com.mapbox.mapboxsdk.annotations.Marker} objects.
+ * Builder for composing {@link Marker} objects. See {@link Marker} for additional information.
* </p>
* <h3>Example</h3>
* <pre>
- * mMapView.addMarker(new MarkerOptions()
+ * mapView.addMarker(new MarkerOptions()
* .title("Intersection")
* .snippet("H St NW with 15th St NW")
* .position(new LatLng(38.9002073, -77.03364419)));
@@ -22,108 +21,168 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
*/
public final class MarkerOptions extends BaseMarkerOptions<Marker, MarkerOptions> implements Parcelable {
- public MarkerOptions() {
+ /**
+ * Defines options for a Marker.
+ */
+ public MarkerOptions() {
+ }
+
+ protected MarkerOptions(Parcel in) {
+ position((LatLng) in.readParcelable(LatLng.class.getClassLoader()));
+ snippet(in.readString());
+ title(in.readString());
+ if (in.readByte() != 0) {
+ // this means we have an icon
+ String iconId = in.readString();
+ Bitmap iconBitmap = in.readParcelable(Bitmap.class.getClassLoader());
+ Icon icon = new Icon(iconId, iconBitmap);
+ icon(icon);
}
-
- protected MarkerOptions(Parcel in) {
- position((LatLng) in.readParcelable(LatLng.class.getClassLoader()));
- snippet(in.readString());
- title(in.readString());
- if (in.readByte() != 0) {
- // this means we have an icon
- String iconId = in.readString();
- Bitmap iconBitmap = in.readParcelable(Bitmap.class.getClassLoader());
- Icon icon = new Icon(iconId, iconBitmap);
- icon(icon);
- }
+ }
+
+ @Override
+ public MarkerOptions getThis() {
+ return this;
+ }
+
+ /**
+ * Describe the kinds of special objects contained in this Parcelable's
+ * marshalled representation.
+ *
+ * @return integer 0.
+ */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * Flatten this object in to a Parcel.
+ *
+ * @param out The Parcel in which the object should be written.
+ * @param flags Additional flags about how the object should be written. May be 0 or
+ * {@link #PARCELABLE_WRITE_RETURN_VALUE}.
+ */
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeParcelable(getPosition(), flags);
+ out.writeString(getSnippet());
+ out.writeString(getTitle());
+ Icon icon = getIcon();
+ out.writeByte((byte) (icon != null ? 1 : 0));
+ if (icon != null) {
+ out.writeString(getIcon().getId());
+ out.writeParcelable(getIcon().getBitmap(), flags);
}
-
- @Override
- public MarkerOptions getThis() {
- return this;
- }
-
- @Override
- public int describeContents() {
- return 0;
+ }
+
+ /**
+ * Do not use this method. Used internally by the SDK.
+ *
+ * @return Marker The build marker
+ */
+ public Marker getMarker() {
+ if (position == null) {
+ throw new InvalidMarkerPositionException();
}
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeParcelable(getPosition(), flags);
- out.writeString(getSnippet());
- out.writeString(getTitle());
- Icon icon = getIcon();
- out.writeByte((byte) (icon != null ? 1 : 0));
- if (icon != null) {
- out.writeString(getIcon().getId());
- out.writeParcelable(getIcon().getBitmap(), flags);
- }
- }
-
- /**
- * Do not use this method. Used internally by the SDK.
- *
- * @return Marker The build marker
- */
- public Marker getMarker() {
- if (position == null) {
- throw new InvalidMarkerPositionException();
- }
-
- return new Marker(position, icon, title, snippet);
- }
+ return new Marker(position, icon, title, snippet);
+ }
+
+ /**
+ * Returns the position set for this {@link MarkerOptions} object.
+ *
+ * @return A {@link LatLng} object specifying the marker's current position.
+ */
+ public LatLng getPosition() {
+ return position;
+ }
+
+ /**
+ * Gets the snippet set for this {@link MarkerOptions} object.
+ *
+ * @return A string containing the marker's snippet.
+ */
+ public String getSnippet() {
+ return snippet;
+ }
+
+ /**
+ * Gets the title set for this {@link MarkerOptions} object.
+ *
+ * @return A string containing the marker's title.
+ */
+ public String getTitle() {
+ return title;
+ }
+
+ /**
+ * Gets the custom icon set for this {@link MarkerOptions} object.
+ *
+ * @return A {@link Icon} object that the marker is using. If the icon wasn't set, default icon
+ * will return.
+ */
+ public Icon getIcon() {
+ return icon;
+ }
+
+ public static final Parcelable.Creator<MarkerOptions> CREATOR =
+ new Parcelable.Creator<MarkerOptions>() {
+ public MarkerOptions createFromParcel(Parcel in) {
+ return new MarkerOptions(in);
+ }
+
+ public MarkerOptions[] newArray(int size) {
+ return new MarkerOptions[size];
+ }
+ };
- public LatLng getPosition() {
- return position;
+ /**
+ * Compares this {@link MarkerOptions} object with another {@link MarkerOptions} and
+ * determines if their properties match.
+ *
+ * @param o Another {@link MarkerOptions} to compare with this object.
+ * @return True if marker properties match this {@link MarkerOptions} object.
+ * Else, false.
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
}
-
- public String getSnippet() {
- return snippet;
+ if (o == null || getClass() != o.getClass()) {
+ return false;
}
- public String getTitle() {
- return title;
- }
+ MarkerOptions marker = (MarkerOptions) o;
- public Icon getIcon() {
- return icon;
+ if (getPosition() != null ? !getPosition().equals(marker.getPosition()) : marker.getPosition() != null) {
+ return false;
}
-
- public static final Parcelable.Creator<MarkerOptions> CREATOR
- = new Parcelable.Creator<MarkerOptions>() {
- public MarkerOptions createFromParcel(Parcel in) {
- return new MarkerOptions(in);
- }
-
- public MarkerOptions[] newArray(int size) {
- return new MarkerOptions[size];
- }
- };
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- MarkerOptions marker = (MarkerOptions) o;
-
- if (getPosition() != null ? !getPosition().equals(marker.getPosition()) : marker.getPosition() != null)
- return false;
- if (getSnippet() != null ? !getSnippet().equals(marker.getSnippet()) : marker.getSnippet() != null)
- return false;
- if (getIcon() != null ? !getIcon().equals(marker.getIcon()) : marker.getIcon() != null)
- return false;
- return !(getTitle() != null ? !getTitle().equals(marker.getTitle()) : marker.getTitle() != null);
+ if (getSnippet() != null ? !getSnippet().equals(marker.getSnippet()) : marker.getSnippet() != null) {
+ return false;
}
-
- @Override
- public int hashCode() {
- int result = 1;
- result = 31 * result + (getPosition() != null ? getPosition().hashCode() : 0);
- result = 31 * result + (getSnippet() != null ? getSnippet().hashCode() : 0);
- result = 31 * result + (getIcon() != null ? getIcon().hashCode() : 0);
- result = 31 * result + (getTitle() != null ? getTitle().hashCode() : 0);
- return result;
+ if (getIcon() != null ? !getIcon().equals(marker.getIcon()) : marker.getIcon() != null) {
+ return false;
}
+ return !(getTitle() != null ? !getTitle().equals(marker.getTitle()) : marker.getTitle() != null);
+ }
+
+ /**
+ * Gives an integer which can be used as the bucket number for storing elements of the set/map.
+ * This bucket number is the address of the element inside the set/map. There's no guarantee
+ * that this hash value will be consistent between different Java implementations, or even
+ * between different execution runs of the same program.
+ *
+ * @return integer value you can use for storing element.
+ */
+ @Override
+ public int hashCode() {
+ int result = 1;
+ result = 31 * result + (getPosition() != null ? getPosition().hashCode() : 0);
+ result = 31 * result + (getSnippet() != null ? getSnippet().hashCode() : 0);
+ result = 31 * result + (getIcon() != null ? getIcon().hashCode() : 0);
+ result = 31 * result + (getTitle() != null ? getTitle().hashCode() : 0);
+ return result;
+ }
}
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 175fd57da4..c1b643eb4c 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
@@ -8,389 +8,402 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapboxMap;
/**
- * MarkerView is an annotation that shows an View at a geographical location.
+ * MarkerView is an annotation that shows a {@link android.view.View} at a geographical location. The
+ * default marker uses a provided icon. This icon can be customized using {@link IconFactory} to
+ * generate an {@link Icon} using a provided image. MarkerViews are added to the map by first giving
+ * a {@link LatLng} and using {@link MapboxMap#addMarker(BaseMarkerViewOptions)}. The marker view icon
+ * by default is anchored at the center bottom.
* <p>
- * This class uses {@link com.mapbox.mapboxsdk.maps.MapboxMap.MarkerViewAdapter} to adapt a
+ * If many markers are needed to be displayed on the map at once we suggest using {@link Marker}
+ * instead. This class uses {@link com.mapbox.mapboxsdk.maps.MapboxMap.MarkerViewAdapter} to adapt a
* MarkerView model to an Android SDK {@link android.view.View} object.
* </p>
* <p>
- * An {@link InfoWindow} can be shown when a MarkerView is pressed
+ * MarkerViews are designed to be interactive. They receive click events by default, and are often
+ * used with event listeners to bring up info windows. An {@link InfoWindow} is displayed by default
+ * when either a title or snippet is provided.
* </p>
*/
public class MarkerView extends Marker {
- private MarkerViewManager markerViewManager;
-
- private float width;
- private float height;
-
- private float anchorU;
- private float anchorV;
-
- private float offsetX = MapboxConstants.UNMEASURED;
- private float offsetY = MapboxConstants.UNMEASURED;
-
- private float infoWindowAnchorU;
- private float infoWindowAnchorV;
-
- private boolean flat;
- private boolean visible = true;
-
- private float tiltValue;
- private float rotation;
- private float alpha = 1;
-
- private Icon markerViewIcon;
-
- private boolean selected;
-
-
- /**
- * Publicly hidden default constructor
- */
- MarkerView() {
- }
-
- /**
- * Creates a instance of MarkerView using the builder of MarkerView
- *
- * @param baseMarkerViewOptions the builder used to construct the MarkerView
- */
- public MarkerView(BaseMarkerViewOptions baseMarkerViewOptions) {
- super(baseMarkerViewOptions);
- this.alpha = baseMarkerViewOptions.getAlpha();
- this.anchorU = baseMarkerViewOptions.getAnchorU();
- this.anchorV = baseMarkerViewOptions.getAnchorV();
- this.infoWindowAnchorU = baseMarkerViewOptions.getInfoWindowAnchorU();
- this.infoWindowAnchorV = baseMarkerViewOptions.getInfoWindowAnchorV();
- this.flat = baseMarkerViewOptions.isFlat();
- this.rotation = baseMarkerViewOptions.getRotation();
- this.selected = baseMarkerViewOptions.selected;
- }
-
- float getWidth() {
- return width;
- }
-
- void setWidth(float width) {
- this.width = width;
- }
-
- float getHeight() {
- return height;
- }
-
- void setHeight(float height) {
- this.height = height;
- }
-
- /**
- * Specifies the anchor being set on a particular point point of the MarkerView.
- * <p>
- * The anchor point is specified in the continuous space [0.0, 1.0] x [0.0, 1.0], where (0, 0)
- * is the top-left corner of the image, and (1, 1) is the bottom-right corner.
- * </p>
- *
- * @param u u-coordinate of the anchor, as a ratio of the image width (in the range [0, 1])
- * @param v v-coordinate of the anchor, as a ratio of the image height (in the range [0, 1])
- */
- public void setAnchor(@FloatRange(from = 0.0, to = 1.0) float u, @FloatRange(from = 0.0, to = 1.0) float v) {
- this.anchorU = u;
- this.anchorV = v;
- setOffset(-1, -1);
- }
-
- /**
- * Get the horizontal distance, normalized to [0, 1], of the anchor from the left edge.
- *
- * @return the u-value of the anchor
- */
- public float getAnchorU() {
- return anchorU;
- }
-
- /**
- * Get the vertical distance, normalized to [0, 1], of the anchor from the top edge.
- *
- * @return the v-value of the anchor
- */
- public float getAnchorV() {
- return anchorV;
- }
-
- /**
- * Internal method to set the calculated offset.
- * <p>
- * These are calculated based on the View bounds and the provided anchor.
- * </p>
- *
- * @param x the x-value of the offset
- * @param y the y-value of the offset
- */
- void setOffset(float x, float y) {
- offsetX = x;
- offsetY = y;
- }
-
- /**
- * Internal method to get the horizontal calculated offset
- *
- * @return the calculated horizontal offset
- */
- float getOffsetX() {
- return offsetX;
- }
-
- /**
- * Internal method to get the vertical calculated offset
- *
- * @return the calculated vertical offset
- */
- float getOffsetY() {
- return offsetY;
- }
-
- /**
- * Specifies the anchor point of the info window on the View of the MarkerView.
- * <p>
- * This is specified in the same coordinate system as the anchor.
- * </p>
- * <p>
- * The default is the top middle of the View.
- * </p>
- *
- * @param u u-coordinate of the info window anchor, as a ratio of the image width (in the range [0, 1])
- * @param v v-coordinate of the info window anchor, as a ratio of the image height (in the range [0, 1])
- * @see #setAnchor(float, float) for more details.
- */
- public void setInfoWindowAnchor(@FloatRange(from = 0.0, to = 1.0) float u, @FloatRange(from = 0.0, to = 1.0) float v) {
- this.infoWindowAnchorU = u;
- this.infoWindowAnchorV = v;
- }
-
- /**
- * Get the horizontal distance, normalized to [0, 1], of the info window anchor from the left edge.
- *
- * @return the u value of the InfoWindow anchor.
- */
- public float getInfoWindowAnchorU() {
- return infoWindowAnchorU;
- }
-
- /**
- * Get the vertical distance, normalized to [0, 1], of the info window anchor from the top edge.
- *
- * @return the v value of the InfoWindow anchor.
- */
- public float getInfoWindowAnchorV() {
- return infoWindowAnchorV;
- }
-
- /**
- * Get the flat state of a MarkerView.
- *
- * @return true is the MarkerView is flat; false is the MarkerView is billboard
- */
- public boolean isFlat() {
- return flat;
- }
-
- /**
- * Sets whether this marker should be flat against the map true or a billboard facing the camera false.
- *
- * @param flat the flat state of the MarkerView
- */
- public void setFlat(boolean flat) {
- this.flat = flat;
- }
-
- /**
- * Internal method to get the current tilted value of a MarkerView.
- *
- * @return the tilted value
- */
- float getTilt() {
- return tiltValue;
- }
-
- /**
- * Internal method to set the current titled value of a MarkerView.
- *
- * @param tiltValue the tilted value to set
- */
- void setTilt(@FloatRange(from = 0.0, to = MapboxConstants.MAXIMUM_TILT) float tiltValue) {
- this.tiltValue = tiltValue;
- }
-
- /**
- * Set the visible state of a MarkerView.
- *
- * @param visible true will make the MarkerView visible, false will hide the MarkerViews
- */
- public void setVisible(boolean visible) {
- this.visible = visible;
- if (markerViewManager != null) {
- markerViewManager.animateVisible(this, visible);
- }
- }
-
- /**
- * Returns the visible state of the MarkerView.
- *
- * @return the visible state
- */
- public boolean isVisible() {
- return visible;
- }
-
- /**
- * 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.
- * </p>
- *
- * @param rotation the rotation value to animate to
- */
- public void setRotation(float 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.animateRotationBy(this, diff);
- }
- }
-
- /**
- * Get the rotation value of the MarkerView.
- *
- * @return the rotation value
- */
- public float getRotation() {
- return rotation;
- }
-
- /**
- * Get the alpha value of the MarkerView.
- *
- * @return the alpha value
- */
- public float getAlpha() {
- return alpha;
- }
-
- /**
- * Set the alpha value of the MarkerView.
- * <p>
- * This will result in animating the alpha of the MarkerView using an alpha animator
- * from current value to the provided parameter value.
- * </p>
- *
- * @param alpha the alpha value to animate to
- */
- public void setAlpha(@FloatRange(from = 0.0, to = 255.0) float alpha) {
- this.alpha = alpha;
- if (markerViewManager != null) {
- markerViewManager.animateAlpha(this, alpha);
- }
- }
-
- /**
- * Set the icon of the MarkerView.
- *
- * @param icon the icon to be used as Marker image
- */
- @Override
- public void setIcon(@Nullable Icon icon) {
- if (icon != null) {
- markerViewIcon = IconFactory.recreate(IconFactory.ICON_MARKERVIEW_ID, icon.getBitmap());
- }
- Icon transparentIcon = IconFactory.recreate(IconFactory.ICON_MARKERVIEW_ID,
- IconFactory.ICON_MARKERVIEW_BITMAP);
- if (markerViewManager != null) {
- markerViewManager.updateIcon(this);
- }
- super.setIcon(transparentIcon);
- }
-
- @Override
- public void setPosition(LatLng position) {
- super.setPosition(position);
- if (markerViewManager != null) {
- markerViewManager.update();
- }
- }
-
- public boolean isSelected() {
- return selected;
- }
-
- /**
- * For internal use only, use {@link MapboxMap#selectMarker(Marker)} instead.
- */
- void setSelected(boolean selected) {
- this.selected = selected;
- }
-
- /**
- * Get the icon of the MarkerView.
- *
- * @return the icon use as Marker image
- */
- @Override
- public Icon getIcon() {
- return markerViewIcon;
- }
-
- /**
- * Set the MapboxMap associated tot the MapView containing the MarkerView.
- * <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;
- }
-
- markerViewManager = mapboxMap.getMarkerViewManager();
- }
- }
-
- /**
- * Get the String representation of a MarkerView.
- *
- * @return the String representation
- */
- @Override
- public String toString() {
- return "MarkerView [position[" + getPosition() + "]]";
- }
+ private MarkerViewManager markerViewManager;
+
+ private float width;
+ private float height;
+
+ private float anchorU;
+ private float anchorV;
+
+ private float offsetX = MapboxConstants.UNMEASURED;
+ private float offsetY = MapboxConstants.UNMEASURED;
+
+ private float infoWindowAnchorU;
+ private float infoWindowAnchorV;
+
+ private boolean flat;
+ private boolean visible = true;
+
+ private float tiltValue;
+ private float rotation;
+ private float alpha = 1;
+
+ private Icon markerViewIcon;
+
+ private boolean selected;
+
+
+ /**
+ * Publicly hidden default constructor
+ */
+ MarkerView() {
+ }
+
+ /**
+ * Creates a instance of MarkerView using the builder of MarkerView
+ *
+ * @param baseMarkerViewOptions the builder used to construct the MarkerView
+ */
+ public MarkerView(BaseMarkerViewOptions baseMarkerViewOptions) {
+ super(baseMarkerViewOptions);
+ this.alpha = baseMarkerViewOptions.getAlpha();
+ this.anchorU = baseMarkerViewOptions.getAnchorU();
+ this.anchorV = baseMarkerViewOptions.getAnchorV();
+ this.infoWindowAnchorU = baseMarkerViewOptions.getInfoWindowAnchorU();
+ this.infoWindowAnchorV = baseMarkerViewOptions.getInfoWindowAnchorV();
+ this.flat = baseMarkerViewOptions.isFlat();
+ this.rotation = baseMarkerViewOptions.getRotation();
+ this.selected = baseMarkerViewOptions.selected;
+ }
+
+ float getWidth() {
+ return width;
+ }
+
+ void setWidth(float width) {
+ this.width = width;
+ }
+
+ float getHeight() {
+ return height;
+ }
+
+ void setHeight(float height) {
+ this.height = height;
+ }
+
+ /**
+ * Specifies the anchor being set on a particular point of the MarkerView.
+ * <p>
+ * The anchor point is specified in the continuous space [0.0, 1.0] x [0.0, 1.0], where (0, 0)
+ * is the top-left corner of the image, and (1, 1) is the bottom-right corner.
+ * </p>
+ *
+ * @param u u-coordinate of the anchor, as a ratio of the image width (in the range [0, 1]).
+ * @param v v-coordinate of the anchor, as a ratio of the image height (in the range [0, 1]).
+ */
+ public void setAnchor(@FloatRange(from = 0.0, to = 1.0) float u, @FloatRange(from = 0.0, to = 1.0) float v) {
+ this.anchorU = u;
+ this.anchorV = v;
+ setOffset(-1, -1);
+ }
+
+ /**
+ * Get the horizontal distance, normalized to [0, 1], of the anchor from the left edge.
+ *
+ * @return The u-value of the anchor.
+ */
+ public float getAnchorU() {
+ return anchorU;
+ }
+
+ /**
+ * Get the vertical distance, normalized to [0, 1], of the anchor from the top edge.
+ *
+ * @return the v-value of the anchor.
+ */
+ public float getAnchorV() {
+ return anchorV;
+ }
+
+ /**
+ * Internal method to set the calculated offset.
+ * <p>
+ * These are calculated based on the View bounds and the provided anchor.
+ * </p>
+ *
+ * @param x the x-value of the offset.
+ * @param y the y-value of the offset.
+ */
+ void setOffset(float x, float y) {
+ offsetX = x;
+ offsetY = y;
+ }
+
+ /**
+ * Internal method to get the horizontal calculated offset.
+ *
+ * @return the calculated horizontal offset.
+ */
+ float getOffsetX() {
+ return offsetX;
+ }
+
+ /**
+ * Internal method to get the vertical calculated offset.
+ *
+ * @return the calculated vertical offset.
+ */
+ float getOffsetY() {
+ return offsetY;
+ }
+
+ /**
+ * Specifies the anchor point of the info window on the View of the MarkerView.
+ * <p>
+ * The anchor point is specified in the continuous space [0.0, 1.0] x [0.0, 1.0], where (0, 0)
+ * is the top-left corner of the image, and (1, 1) is the bottom-right corner.
+ * </p>
+ * <p>
+ * The default is the top middle of the View.
+ * </p>
+ *
+ * @param u u-coordinate of the info window anchor, as a ratio of the image width (in the range [0, 1]).
+ * @param v v-coordinate of the info window anchor, as a ratio of the image height (in the range [0, 1]).
+ * @see #setAnchor(float, float) for more details.
+ */
+ public void setInfoWindowAnchor(@FloatRange(from = 0.0, to = 1.0) float u,
+ @FloatRange(from = 0.0, to = 1.0) float v) {
+ this.infoWindowAnchorU = u;
+ this.infoWindowAnchorV = v;
+ }
+
+ /**
+ * Get the horizontal distance, normalized to [0, 1], of the info window anchor from the left edge.
+ *
+ * @return the u value of the InfoWindow anchor.
+ */
+ public float getInfoWindowAnchorU() {
+ return infoWindowAnchorU;
+ }
+
+ /**
+ * Get the vertical distance, normalized to [0, 1], of the info window anchor from the top edge.
+ *
+ * @return the v value of the InfoWindow anchor.
+ */
+ public float getInfoWindowAnchorV() {
+ return infoWindowAnchorV;
+ }
+
+ /**
+ * Get the flat state of a MarkerView.
+ *
+ * @return true if the MarkerView is flat; false if the MarkerView is billboard.
+ */
+ public boolean isFlat() {
+ return flat;
+ }
+
+ /**
+ * Sets whether this MarkerView should be flat against the map (true) or a billboard facing the
+ * camera (false).
+ *
+ * @param flat the flat state of the MarkerView.
+ */
+ public void setFlat(boolean flat) {
+ this.flat = flat;
+ }
+
+ /**
+ * Internal method to get the current tilted value of a MarkerView.
+ *
+ * @return the tilted value.
+ */
+ float getTilt() {
+ return tiltValue;
+ }
+
+ /**
+ * Internal method to set the current titled value of a MarkerView.
+ *
+ * @param tiltValue the tilted value to set.
+ */
+ void setTilt(@FloatRange(from = 0.0, to = MapboxConstants.MAXIMUM_TILT) float tiltValue) {
+ this.tiltValue = tiltValue;
+ }
+
+ /**
+ * Set the visible state of a MarkerView.
+ *
+ * @param visible true will make the MarkerView visible, false will hide the MarkerView.
+ */
+ public void setVisible(boolean visible) {
+ this.visible = visible;
+ if (markerViewManager != null) {
+ markerViewManager.animateVisible(this, visible);
+ }
+ }
+
+ /**
+ * Returns the visible state of the MarkerView.
+ *
+ * @return the visible state.
+ */
+ public boolean isVisible() {
+ return visible;
+ }
+
+ /**
+ * 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.
+ * </p>
+ *
+ * @param rotation the rotation value to animate to.
+ */
+ public void setRotation(float rotation) {
+ // limit to 0 - 360 degrees
+ float newRotation = rotation;
+ while (newRotation > 360) {
+ newRotation -= 360;
+ }
+ while (newRotation < 0) {
+ newRotation += 360;
+ }
+
+ this.rotation = newRotation;
+ if (markerViewManager != null) {
+ markerViewManager.animateRotationBy(this, newRotation);
+ }
+ }
+
+ /**
+ * Get the rotation value of the MarkerView.
+ *
+ * @return the rotation value.
+ */
+ public float getRotation() {
+ return rotation;
+ }
+
+ /**
+ * Get the alpha value of the MarkerView.
+ *
+ * @return the alpha value.
+ */
+ public float getAlpha() {
+ return alpha;
+ }
+
+ /**
+ * Set the alpha value of the MarkerView.
+ * <p>
+ * This will result in animating the alpha of the MarkerView using an alpha animator
+ * from current value to the provided parameter value.
+ * </p>
+ *
+ * @param alpha the alpha value to animate to.
+ */
+ public void setAlpha(@FloatRange(from = 0.0, to = 255.0) float alpha) {
+ this.alpha = alpha;
+ if (markerViewManager != null) {
+ markerViewManager.animateAlpha(this, alpha);
+ }
+ }
+
+ /**
+ * Set the icon of the MarkerView.
+ *
+ * @param icon the {@link Icon} to be used as Marker image.
+ */
+ @Override
+ public void setIcon(@Nullable Icon icon) {
+ if (icon != null) {
+ markerViewIcon = IconFactory.recreate(IconFactory.ICON_MARKERVIEW_ID, icon.getBitmap());
+ }
+ Icon transparentIcon = IconFactory.recreate(IconFactory.ICON_MARKERVIEW_ID,
+ IconFactory.ICON_MARKERVIEW_BITMAP);
+ if (markerViewManager != null) {
+ markerViewManager.updateIcon(this);
+ }
+ super.setIcon(transparentIcon);
+ }
+
+ /**
+ * Sets the location of the marker.
+ *
+ * @param position A {@link LatLng} defining the marker position.
+ */
+ @Override
+ public void setPosition(LatLng position) {
+ super.setPosition(position);
+ if (markerViewManager != null) {
+ markerViewManager.update();
+ }
+ }
+
+ /**
+ * Determine if the {@link MarkerView} is selected or not.
+ *
+ * @return True if the MarkerView's selected, else false.
+ */
+ public boolean isSelected() {
+ return selected;
+ }
+
+ /**
+ * For internal use only, use {@link MapboxMap#selectMarker(Marker)} instead.
+ */
+ void setSelected(boolean selected) {
+ this.selected = selected;
+ }
+
+ /**
+ * Get the icon of the MarkerView.
+ *
+ * @return the icon use as Marker image.
+ */
+ @Override
+ public Icon getIcon() {
+ return markerViewIcon;
+ }
+
+ /**
+ * Set the MapboxMap associated tot the MapView containing the MarkerView.
+ * <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;
+ }
+
+ markerViewManager = mapboxMap.getMarkerViewManager();
+ }
+ }
+
+ /**
+ * Get the String representation of a MarkerView.
+ *
+ * @return the String representation.
+ */
+ @Override
+ public String toString() {
+ return "MarkerView [position[" + getPosition() + "]]";
+ }
}
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 cd333268a1..409b0bf195 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
@@ -6,6 +6,7 @@ import android.graphics.RectF;
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import android.support.v4.util.LongSparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -29,527 +30,616 @@ import java.util.Map;
* This class is responsible for managing a {@link MarkerView} item.
* </p>
*/
-public class MarkerViewManager {
-
- private Map<MarkerView, View> markerViewMap;
- private MapboxMap mapboxMap;
- private MapView mapView;
- private List<MapboxMap.MarkerViewAdapter> markerViewAdapters;
- private long viewMarkerBoundsUpdateTime;
- private MapboxMap.OnMarkerViewClickListener onMarkerViewClickListener;
- private ImageMarkerViewAdapter defaultMarkerViewAdapter;
-
- /**
- * Creates an instance of MarkerViewManager.
- *
- * @param mapboxMap the MapboxMap associated with the MarkerViewManager
- * @param mapView the MapView associated with the MarkerViewManager
- */
- public MarkerViewManager(@NonNull MapboxMap mapboxMap, @NonNull MapView mapView) {
- this.mapboxMap = mapboxMap;
- this.markerViewAdapters = new ArrayList<>();
- this.mapView = mapView;
- this.markerViewMap = new HashMap<>();
- this.defaultMarkerViewAdapter = new ImageMarkerViewAdapter(mapView.getContext());
- this.markerViewAdapters.add(defaultMarkerViewAdapter);
+public class MarkerViewManager implements MapView.OnMapChangedListener {
+
+ private final ViewGroup markerViewContainer;
+ private final Map<MarkerView, View> markerViewMap = new HashMap<>();
+ private final LongSparseArray<OnMarkerViewAddedListener> markerViewAddedListenerMap = new LongSparseArray<>();
+ private final List<MapboxMap.MarkerViewAdapter> markerViewAdapters = new ArrayList<>();
+
+ // TODO refactor MapboxMap out for Projection and Transform
+ // Requires removing MapboxMap from Annotations by using Peer model from #6912
+ private MapboxMap mapboxMap;
+
+ private boolean enabled;
+ private long updateTime;
+ private MapboxMap.OnMarkerViewClickListener onMarkerViewClickListener;
+ private boolean isWaitingForRenderInvoke;
+
+ /**
+ * Creates an instance of MarkerViewManager.
+ *
+ * @param container the ViewGroup associated with the MarkerViewManager
+ */
+ public MarkerViewManager(@NonNull ViewGroup container) {
+ this.markerViewContainer = container;
+ this.markerViewAdapters.add(new ImageMarkerViewAdapter(container.getContext()));
+ }
+
+ // TODO refactor MapboxMap out for Projection and Transform
+ // Requires removing MapboxMap from Annotations by using Peer model from #6912
+ public void bind(MapboxMap mapboxMap) {
+ this.mapboxMap = mapboxMap;
+ }
+
+ @Override
+ public void onMapChanged(@MapView.MapChange int change) {
+ if (isWaitingForRenderInvoke && change == MapView.DID_FINISH_RENDERING_FRAME_FULLY_RENDERED) {
+ isWaitingForRenderInvoke = false;
+ invalidateViewMarkersInVisibleRegion();
}
-
- /**
- * Animate a MarkerView to a given rotation.
- * <p>
- * The {@link MarkerView} will be rotated from its current rotation to the given rotation.
- * </p>
- *
- * @param marker the MarkerView to rotate
- * @param rotation the rotation value
- */
- public void animateRotation(@NonNull MarkerView marker, float rotation) {
- View convertView = markerViewMap.get(marker);
- if (convertView != null) {
- AnimatorUtils.rotate(convertView, rotation);
- }
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public void setWaitingForRenderInvoke(boolean waitingForRenderInvoke) {
+ isWaitingForRenderInvoke = waitingForRenderInvoke;
+ }
+
+ /**
+ * Animate a MarkerView to a given rotation.
+ * <p>
+ * The {@link MarkerView} will be rotated from its current rotation to the given rotation.
+ * </p>
+ *
+ * @param marker the MarkerView to rotate.
+ * @param rotation the rotation value.
+ */
+ public void animateRotation(@NonNull MarkerView marker, float rotation) {
+ View convertView = markerViewMap.get(marker);
+ if (convertView != null) {
+ AnimatorUtils.rotate(convertView, rotation);
}
-
- /**
- * 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 with a given rotation.
+ *
+ * @param marker the MarkerView to rotate by.
+ * @param rotation the rotation by value, limited to 0 - 360 degrees.
+ */
+ public void animateRotationBy(@NonNull MarkerView marker, float rotation) {
+ View convertView = markerViewMap.get(marker);
+ if (convertView != null) {
+ convertView.animate().cancel();
+ // calculate new direction
+ float diff = rotation - convertView.getRotation();
+ if (diff > 180.0f) {
+ diff -= 360.0f;
+ } else if (diff < -180.0f) {
+ diff += 360.f;
+ }
+ AnimatorUtils.rotateBy(convertView, diff);
}
-
- /**
- * Animate a MarkerView to a given alpha value.
- * <p>
- * The {@link MarkerView} will be transformed from its current alpha value to the given value.
- * </p>
- *
- * @param marker the MarkerView to change its alpha value
- * @param alpha the alpha value
- */
- public void animateAlpha(@NonNull MarkerView marker, float alpha) {
- View convertView = markerViewMap.get(marker);
- if (convertView != null) {
- AnimatorUtils.alpha(convertView, alpha);
- }
+ }
+
+ /**
+ * Animate a MarkerView to a given alpha value.
+ * <p>
+ * The {@link MarkerView} will be transformed from its current alpha value to the given value.
+ * </p>
+ *
+ * @param marker the MarkerView to change its alpha value.
+ * @param alpha the alpha value.
+ */
+ public void animateAlpha(@NonNull MarkerView marker, float alpha) {
+ View convertView = markerViewMap.get(marker);
+ if (convertView != null) {
+ AnimatorUtils.alpha(convertView, alpha);
}
-
- /**
- * Animate a MarkerVIew to be visible or invisible
- * <p>
- * The {@link MarkerView} will be made {@link View#VISIBLE} or {@link View#GONE}.
- * </p>
- *
- * @param marker the MarkerView to change its visibility
- * @param visible the flag indicating if MarkerView is visible
- */
- public void animateVisible(@NonNull MarkerView marker, boolean visible) {
- View convertView = markerViewMap.get(marker);
- if (convertView != null) {
- convertView.setVisibility(visible ? View.VISIBLE : View.GONE);
- }
+ }
+
+ /**
+ * Animate a MarkerVIew to be visible or invisible
+ * <p>
+ * The {@link MarkerView} will be made {@link View#VISIBLE} or {@link View#GONE}.
+ * </p>
+ *
+ * @param marker the MarkerView to change its visibility
+ * @param visible the flag indicating if MarkerView is visible
+ */
+ public void animateVisible(@NonNull MarkerView marker, boolean visible) {
+ View convertView = markerViewMap.get(marker);
+ if (convertView != null) {
+ convertView.setVisibility(visible ? View.VISIBLE : View.GONE);
}
-
- /**
- * Updates the position of MarkerViews currently found in the viewport.
- * <p>
- * The collection of {@link MarkerView} will be iterated and each item position will be updated.
- * If an item is View state is not visible and its related flag is set to visible,
- * The {@link MarkerView} will be animated to visible using alpha animation.
- * </p>
- */
- public void update() {
- for (final MarkerView marker : markerViewMap.keySet()) {
- final View convertView = markerViewMap.get(marker);
- if (convertView != null) {
- PointF point = mapboxMap.getProjection().toScreenLocation(marker.getPosition());
- if (marker.getOffsetX() == MapboxConstants.UNMEASURED) {
- // ensure view is measured first
- if (marker.getWidth() == 0) {
- convertView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
- if (convertView.getMeasuredWidth() != 0) {
- marker.setWidth(convertView.getMeasuredWidth());
- marker.setHeight(convertView.getMeasuredHeight());
- }
- }
- }
- if (marker.getWidth() != 0) {
- int x = (int) (marker.getAnchorU() * marker.getWidth());
- int y = (int) (marker.getAnchorV() * marker.getHeight());
- marker.setOffset(x, y);
- }
-
- convertView.setX(point.x - marker.getOffsetX());
- convertView.setY(point.y - marker.getOffsetY());
-
- // animate visibility
- if (marker.isVisible() && convertView.getVisibility() == View.GONE) {
- animateVisible(marker, true);
- }
+ }
+
+ /**
+ * Updates the position of MarkerViews currently found in the viewport.
+ * <p>
+ * The collection of {@link MarkerView} will be iterated and each item position will be updated.
+ * If an item is View state is not visible and its related flag is set to visible, the
+ * {@link MarkerView} will be animated to visible using alpha animation.
+ * </p>
+ */
+ public void update() {
+ for (final MarkerView marker : markerViewMap.keySet()) {
+ final View convertView = markerViewMap.get(marker);
+ if (convertView != null) {
+ PointF point = mapboxMap.getProjection().toScreenLocation(marker.getPosition());
+ if (marker.getOffsetX() == MapboxConstants.UNMEASURED) {
+ // ensure view is measured first
+ if (marker.getWidth() == 0) {
+ convertView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
+ if (convertView.getMeasuredWidth() != 0) {
+ marker.setWidth(convertView.getMeasuredWidth());
+ marker.setHeight(convertView.getMeasuredHeight());
}
+ }
+ }
+ if (marker.getWidth() != 0) {
+ int x = (int) (marker.getAnchorU() * marker.getWidth());
+ int y = (int) (marker.getAnchorV() * marker.getHeight());
+ marker.setOffset(x, y);
}
- }
- /**
- * Set tilt on every non flat MarkerView currently shown in the Viewport.
- *
- * @param tilt the tilt value
- */
- public void setTilt(float tilt) {
- View convertView;
- for (MarkerView markerView : markerViewMap.keySet()) {
- if (markerView.isFlat()) {
- convertView = markerViewMap.get(markerView);
- if (convertView != null) {
- markerView.setTilt(tilt);
- convertView.setRotationX(tilt);
- }
- }
+ convertView.setX(point.x - marker.getOffsetX());
+ convertView.setY(point.y - marker.getOffsetY());
+
+ // animate visibility
+ if (marker.isVisible() && convertView.getVisibility() == View.GONE) {
+ animateVisible(marker, true);
}
+ }
}
-
- /**
- * Update and invalidate the MarkerView icon.
- *
- * @param markerView the marker view to updates
- */
- public void updateIcon(@NonNull MarkerView markerView) {
- View convertView = markerViewMap.get(markerView);
- if (convertView != null && convertView instanceof ImageView) {
- ((ImageView) convertView).setImageBitmap(markerView.getIcon().getBitmap());
+ }
+
+ /**
+ * Set tilt on every non flat MarkerView currently shown in the Viewport.
+ *
+ * @param tilt the tilt value.
+ */
+ public void setTilt(float tilt) {
+ View convertView;
+ for (MarkerView markerView : markerViewMap.keySet()) {
+ if (markerView.isFlat()) {
+ convertView = markerViewMap.get(markerView);
+ if (convertView != null) {
+ markerView.setTilt(tilt);
+ convertView.setRotationX(tilt);
}
+ }
}
-
- /**
- * Animate a MarkerView to a deselected state.
- * <p>
- * The {@link com.mapbox.mapboxsdk.maps.MapboxMap.MarkerViewAdapter#onDeselect(MarkerView, View)} will be called to execute an animation.
- * </p>
- *
- * @param marker the MarkerView to deselect
- */
- public void deselect(@NonNull MarkerView marker) {
- deselect(marker, true);
+ }
+
+ /**
+ * Update and invalidate the MarkerView icon.
+ *
+ * @param markerView the marker view to updates.
+ */
+ public void updateIcon(@NonNull MarkerView markerView) {
+ View convertView = markerViewMap.get(markerView);
+ if (convertView != null && convertView instanceof ImageView) {
+ ((ImageView) convertView).setImageBitmap(markerView.getIcon().getBitmap());
}
-
- /**
- * Animate a MarkerView to a deselected state.
- * <p>
- * The {@link com.mapbox.mapboxsdk.maps.MapboxMap.MarkerViewAdapter#onDeselect(MarkerView, View)} will be called to execute an animation.
- * </p>
- *
- * @param marker the MarkerView to deselect
- * @param callbackToMap indicates if deselect marker must be called on MapboxMap
- */
- public void deselect(@NonNull MarkerView marker, boolean callbackToMap) {
- final View convertView = markerViewMap.get(marker);
- if (convertView != null) {
- for (MapboxMap.MarkerViewAdapter adapter : markerViewAdapters) {
- if (adapter.getMarkerClass().equals(marker.getClass())) {
- adapter.onDeselect(marker, convertView);
- }
- }
- if (callbackToMap) {
- mapboxMap.deselectMarker(marker);
- }
- marker.setSelected(false);
+ }
+
+ /**
+ * Animate a MarkerView to a deselected state.
+ * <p>
+ * The {@link com.mapbox.mapboxsdk.maps.MapboxMap.MarkerViewAdapter#onDeselect(MarkerView, View)}
+ * will be called to execute an animation.
+ * </p>
+ *
+ * @param marker the MarkerView to deselect.
+ */
+ public void deselect(@NonNull MarkerView marker) {
+ deselect(marker, true);
+ }
+
+ /**
+ * Animate a MarkerView to a deselected state.
+ * <p>
+ * The {@link com.mapbox.mapboxsdk.maps.MapboxMap.MarkerViewAdapter#onDeselect(MarkerView, View)}
+ * will be called to execute an animation.
+ * </p>
+ *
+ * @param marker the MarkerView to deselect.
+ * @param callbackToMap indicates if deselect marker must be called on MapboxMap.
+ */
+ public void deselect(@NonNull MarkerView marker, boolean callbackToMap) {
+ final View convertView = markerViewMap.get(marker);
+ if (convertView != null) {
+ for (MapboxMap.MarkerViewAdapter adapter : markerViewAdapters) {
+ if (adapter.getMarkerClass().equals(marker.getClass())) {
+ adapter.onDeselect(marker, convertView);
}
+ }
}
-
- /**
- * Animate a MarkerView to a selected state.
- *
- * @param marker the MarkerView object to select
- */
- public void select(@NonNull MarkerView marker) {
- select(marker, true);
+ if (callbackToMap) {
+ mapboxMap.deselectMarker(marker);
}
-
- /**
- * Animate a MarkerView to a selected state.
- *
- * @param marker the MarkerView object to select
- * @param callbackToMap indicates if select marker must be called on MapboxMap
- */
- public void select(@NonNull MarkerView marker, boolean callbackToMap) {
- final View convertView = markerViewMap.get(marker);
- for (MapboxMap.MarkerViewAdapter adapter : markerViewAdapters) {
- if (adapter.getMarkerClass().equals(marker.getClass())) {
- select(marker, convertView, adapter, callbackToMap);
- }
+ marker.setSelected(false);
+ }
+
+ /**
+ * Animate a MarkerView to a selected state.
+ *
+ * @param marker the MarkerView object to select.
+ */
+ public void select(@NonNull MarkerView marker) {
+ select(marker, true);
+ }
+
+ /**
+ * Animate a MarkerView to a selected state.
+ *
+ * @param marker the MarkerView object to select.
+ * @param callbackToMap indicates if select marker must be called on {@link MapboxMap}.
+ */
+ public void select(@NonNull MarkerView marker, boolean callbackToMap) {
+ final View convertView = markerViewMap.get(marker);
+ for (MapboxMap.MarkerViewAdapter adapter : markerViewAdapters) {
+ if (adapter.getMarkerClass().equals(marker.getClass())) {
+ select(marker, convertView, adapter, callbackToMap);
+ }
+ }
+ }
+
+ /**
+ * Animate a MarkerView to a selected state.
+ * <p>
+ * The {@link com.mapbox.mapboxsdk.maps.MapboxMap.MarkerViewAdapter#onSelect(MarkerView, View, boolean)}
+ * will be called to execute an animation.
+ * </p>
+ *
+ * @param marker the MarkerView object to select.
+ * @param convertView the View presentation of the MarkerView.
+ * @param adapter the adapter used to adapt the marker to the convertView.
+ */
+ public void select(@NonNull MarkerView marker, View convertView, MapboxMap.MarkerViewAdapter adapter) {
+ select(marker, convertView, adapter, true);
+ }
+
+
+ /**
+ * Animate a MarkerView to a selected state.
+ * <p>
+ * The {@link com.mapbox.mapboxsdk.maps.MapboxMap.MarkerViewAdapter#onSelect(MarkerView, View, boolean)}
+ * will be called to execute an animation.
+ * </p>
+ *
+ * @param marker the MarkerView object to select.
+ * @param convertView the View presentation of the MarkerView.
+ * @param adapter the adapter used to adapt the marker to the convertView.
+ * @param callbackToMap indicates if select marker must be called on MapboxMap.
+ */
+ public void select(@NonNull MarkerView marker, View convertView, MapboxMap.MarkerViewAdapter adapter,
+ boolean callbackToMap) {
+ if (convertView != null) {
+ if (adapter.onSelect(marker, convertView, false)) {
+ if (callbackToMap) {
+ mapboxMap.selectMarker(marker);
}
+ }
+ marker.setSelected(true);
+ convertView.bringToFront();
}
-
- /**
- * Animate a MarkerView to a selected state.
- * <p>
- * The {@link com.mapbox.mapboxsdk.maps.MapboxMap.MarkerViewAdapter#onSelect(MarkerView, View, boolean)} will be called to execute an animation.
- * </p>
- *
- * @param marker the MarkerView object to select
- * @param convertView the View presentation of the MarkerView
- * @param adapter the adapter used to adapt the marker to the convertView
- */
- public void select(@NonNull MarkerView marker, View convertView, MapboxMap.MarkerViewAdapter adapter) {
- select(marker, convertView, adapter, true);
+ }
+
+ /**
+ * Get view representation from a MarkerView. If marker is not found in current viewport,
+ * {@code null} is returned.
+ *
+ * @param marker the marker to get the view.
+ * @return the Android SDK View object.
+ */
+ @Nullable
+ public View getView(MarkerView marker) {
+ return markerViewMap.get(marker);
+ }
+
+ /**
+ * Get the view adapter for a marker.
+ *
+ * @param markerView the marker to get the view adapter.
+ * @return the MarkerView adapter.
+ */
+ @Nullable
+ public MapboxMap.MarkerViewAdapter getViewAdapter(MarkerView markerView) {
+ MapboxMap.MarkerViewAdapter adapter = null;
+ for (MapboxMap.MarkerViewAdapter a : markerViewAdapters) {
+ if (a.getMarkerClass().equals(markerView.getClass())) {
+ adapter = a;
+ }
}
-
-
- /**
- * Animate a MarkerView to a selected state.
- * <p>
- * The {@link com.mapbox.mapboxsdk.maps.MapboxMap.MarkerViewAdapter#onSelect(MarkerView, View, boolean)} will be called to execute an animation.
- * </p>
- *
- * @param marker the MarkerView object to select
- * @param convertView the View presentation of the MarkerView
- * @param adapter the adapter used to adapt the marker to the convertView
- * @param callbackToMap indicates if select marker must be called on MapboxMap
- */
- public void select(@NonNull MarkerView marker, View convertView, MapboxMap.MarkerViewAdapter adapter, boolean callbackToMap) {
- if (convertView != null) {
- if (adapter.onSelect(marker, convertView, false)) {
- if (callbackToMap) {
- mapboxMap.selectMarker(marker);
- }
- }
- marker.setSelected(true);
- convertView.bringToFront();
+ return adapter;
+ }
+
+ /**
+ * Remove a MarkerView from a map.
+ * <p>
+ * The {@link MarkerView} will be removed using an alpha animation and related {@link View}
+ * will be released to the android.support.v4.util.Pools.SimplePool from the related
+ * {@link com.mapbox.mapboxsdk.maps.MapboxMap.MarkerViewAdapter}. It's possible to remove
+ * the {@link MarkerView} from the underlying collection if needed.
+ * </p>
+ *
+ * @param marker the MarkerView to remove.
+ */
+ public void removeMarkerView(MarkerView marker) {
+ final View viewHolder = markerViewMap.get(marker);
+ if (viewHolder != null && marker != null) {
+ for (final MapboxMap.MarkerViewAdapter<?> adapter : markerViewAdapters) {
+ if (adapter.getMarkerClass().equals(marker.getClass())) {
+ if (adapter.prepareViewForReuse(marker, viewHolder)) {
+ // reset offset for reuse
+ marker.setOffset(MapboxConstants.UNMEASURED, MapboxConstants.UNMEASURED);
+ adapter.releaseView(viewHolder);
+ }
}
+ }
}
-
- /**
- * Get view representation from a MarkerView.
- * <p>
- * If marker is not found in current viewport, null is returned.
- * </p>
- *
- * @param marker the marker to get the view for
- * @return the android SDK View object
- */
- @Nullable
- public View getView(MarkerView marker) {
- return markerViewMap.get(marker);
+ marker.setMapboxMap(null);
+ markerViewMap.remove(marker);
+ }
+
+ /**
+ * Add a MarkerViewAdapter to the MarkerViewManager.
+ * <p>
+ * The provided MarkerViewAdapter must supply a generic subclass of MarkerView.
+ * </p>
+ *
+ * @param markerViewAdapter the MarkerViewAdapter to add.
+ */
+ public void addMarkerViewAdapter(MapboxMap.MarkerViewAdapter markerViewAdapter) {
+ if (markerViewAdapter.getMarkerClass().equals(MarkerView.class)) {
+ throw new RuntimeException("Providing a custom MarkerViewAdapter requires subclassing MarkerView");
}
- @Nullable
- public MapboxMap.MarkerViewAdapter getViewAdapter(MarkerView markerView) {
- MapboxMap.MarkerViewAdapter adapter = null;
- for (MapboxMap.MarkerViewAdapter a : markerViewAdapters) {
- if (a.getMarkerClass().equals(markerView.getClass())) {
- adapter = a;
- }
+ if (!markerViewAdapters.contains(markerViewAdapter)) {
+ markerViewAdapters.add(markerViewAdapter);
+ invalidateViewMarkersInVisibleRegion();
+ }
+ }
+
+ /**
+ * Get all MarkerViewAdapters associated with this MarkerViewManager.
+ *
+ * @return a List of MarkerViewAdapters.
+ */
+ public List<MapboxMap.MarkerViewAdapter> getMarkerViewAdapters() {
+ return markerViewAdapters;
+ }
+
+ /**
+ * Register a callback to be invoked when this view is clicked.
+ *
+ * @param listener the callback to be invoked.
+ */
+ public void setOnMarkerViewClickListener(@Nullable MapboxMap.OnMarkerViewClickListener listener) {
+ onMarkerViewClickListener = listener;
+ }
+
+ /**
+ * Schedule that ViewMarkers found in the viewport are invalidated.
+ * <p>
+ * This method is rate limited, and {@link #invalidateViewMarkersInVisibleRegion} will only be called
+ * once each 250 ms.
+ * </p>
+ */
+ public void scheduleViewMarkerInvalidation() {
+ if (enabled) {
+ long currentTime = SystemClock.elapsedRealtime();
+ if (currentTime < updateTime) {
+ return;
+ }
+ invalidateViewMarkersInVisibleRegion();
+ updateTime = currentTime + 250;
+ }
+ }
+
+ /**
+ * Invalidate the ViewMarkers found in the viewport.
+ * <p>
+ * This method will remove any markers that aren't in the viewport anymore and will add new
+ * ones for each found Marker in the changed viewport.
+ * </p>
+ */
+ public void invalidateViewMarkersInVisibleRegion() {
+ RectF mapViewRect = new RectF(0, 0, markerViewContainer.getWidth(), markerViewContainer.getHeight());
+ List<MarkerView> markers = mapboxMap.getMarkerViewsInRect(mapViewRect);
+ View convertView;
+
+ // remove old markers
+ Iterator<MarkerView> iterator = markerViewMap.keySet().iterator();
+ while (iterator.hasNext()) {
+ MarkerView marker = iterator.next();
+ if (!markers.contains(marker)) {
+ // remove marker
+ convertView = markerViewMap.get(marker);
+ for (MapboxMap.MarkerViewAdapter adapter : markerViewAdapters) {
+ if (adapter.getMarkerClass().equals(marker.getClass())) {
+ adapter.prepareViewForReuse(marker, convertView);
+ adapter.releaseView(convertView);
+ marker.setMapboxMap(null);
+ iterator.remove();
+ }
}
- return adapter;
+ }
}
- /**
- * Remove a MarkerView from a map.
- * <p>
- * The {@link MarkerView} will be removed using an alpha animation and related {@link View}
- * will be released to the android.support.v4.util.Pools.SimplePool from the related
- * {@link com.mapbox.mapboxsdk.maps.MapboxMap.MarkerViewAdapter}. It's possible to remove
- * the {@link MarkerView} from the underlying collection if needed.
- * </p>
- *
- * @param marker the MarkerView to remove
- */
- public void removeMarkerView(MarkerView marker) {
- final View viewHolder = markerViewMap.get(marker);
- if (viewHolder != null && marker != null) {
- for (final MapboxMap.MarkerViewAdapter<?> adapter : markerViewAdapters) {
- if (adapter.getMarkerClass().equals(marker.getClass())) {
- if (adapter.prepareViewForReuse(marker, viewHolder)) {
- // reset offset for reuse
- marker.setOffset(MapboxConstants.UNMEASURED, MapboxConstants.UNMEASURED);
- adapter.releaseView(viewHolder);
- }
+ // introduce new markers
+ for (final MarkerView marker : markers) {
+ 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, markerViewContainer);
+ if (adaptedView != null) {
+ adaptedView.setRotationX(marker.getTilt());
+ adaptedView.setRotation(marker.getRotation());
+ adaptedView.setAlpha(marker.getAlpha());
+ adaptedView.setVisibility(View.GONE);
+
+ if (mapboxMap.getSelectedMarkers().contains(marker)) {
+ // if a marker to be shown was selected
+ // replay that animation with duration 0
+ if (adapter.onSelect(marker, adaptedView, true)) {
+ mapboxMap.selectMarker(marker);
}
+ }
+
+ marker.setMapboxMap(mapboxMap);
+ markerViewMap.put(marker, adaptedView);
+ if (convertView == null) {
+ adaptedView.setVisibility(View.GONE);
+ markerViewContainer.addView(adaptedView);
+ }
}
- }
- marker.setMapboxMap(null);
- markerViewMap.remove(marker);
- }
-
- /**
- * Add a MarkerViewAdapter to the MarkerViewManager.
- * <p>
- * The provided MarkerViewAdapter must use supply a generic subclass of MarkerView.
- * </p>
- *
- * @param markerViewAdapter the MarkerViewAdapter to add
- */
- public void addMarkerViewAdapter(MapboxMap.MarkerViewAdapter markerViewAdapter) {
- if (markerViewAdapter.getMarkerClass().equals(MarkerView.class)) {
- throw new RuntimeException("Providing a custom MarkerViewAdapter requires subclassing MarkerView");
- }
- if (!markerViewAdapters.contains(markerViewAdapter)) {
- markerViewAdapters.add(markerViewAdapter);
- invalidateViewMarkersInVisibleRegion();
+ // notify listener is marker view is rendered
+ OnMarkerViewAddedListener onViewAddedListener = markerViewAddedListenerMap.get(marker.getId());
+ if (onViewAddedListener != null) {
+ onViewAddedListener.onViewAdded(marker);
+ markerViewAddedListenerMap.remove(marker.getId());
+ }
+ }
}
+ }
}
- /**
- * Get all MarkerViewAdapters associated with this MarkerViewManager.
- *
- * @return a List of MarkerViewAdapters
- */
- public List<MapboxMap.MarkerViewAdapter> getMarkerViewAdapters() {
- return markerViewAdapters;
+ // clear map, don't keep references to MarkerView listeners that are not found in the bounds of the map.
+ markerViewAddedListenerMap.clear();
+
+ // trigger update to make newly added ViewMarker visible,
+ // these would only be updated when the map is moved.
+ update();
+ }
+
+ /**
+ * When the provided {@link MarkerView} is clicked on by a user, we check if a custom click
+ * event has been created and if not, display a {@link InfoWindow}.
+ *
+ * @param markerView that the click event occurred.
+ */
+ public boolean onClickMarkerView(MarkerView markerView) {
+ boolean clickHandled = false;
+
+ MapboxMap.MarkerViewAdapter adapter = getViewAdapter(markerView);
+ View view = getView(markerView);
+ if (adapter == null || view == null) {
+ // not a valid state
+ return true;
}
- /**
- * Register a callback to be invoked when this view is clicked.
- *
- * @param listener the callback to be invoked
- */
- public void setOnMarkerViewClickListener(@Nullable MapboxMap.OnMarkerViewClickListener listener) {
- onMarkerViewClickListener = listener;
+ if (onMarkerViewClickListener != null) {
+ clickHandled = onMarkerViewClickListener.onMarkerClick(markerView, view, adapter);
}
- /**
- * Schedule that ViewMarkers found in the viewport are invalidated.
- * <p>
- * This method is rate limited, and {@link #invalidateViewMarkersInVisibleRegion} will only be called
- * once each 250 ms.
- * </p>
- */
- public void scheduleViewMarkerInvalidation() {
- if (!markerViewAdapters.isEmpty()) {
- long currentTime = SystemClock.elapsedRealtime();
- if (currentTime < viewMarkerBoundsUpdateTime) {
- return;
- }
- invalidateViewMarkersInVisibleRegion();
- viewMarkerBoundsUpdateTime = currentTime + 250;
- }
+ if (!clickHandled) {
+ ensureInfoWindowOffset(markerView);
+ select(markerView, view, adapter);
}
- /**
- * Invalidate the ViewMarkers found in the viewport.
- * <p>
- * This method will remove any markers that aren't in the viewport any more and will add new
- * ones for each found Marker in the changed viewport.
- * </p>
- */
- public void invalidateViewMarkersInVisibleRegion() {
- RectF mapViewRect = new RectF(0, 0, mapView.getWidth(), mapView.getHeight());
- List<MarkerView> markers = mapView.getMarkerViewsInRect(mapViewRect);
- View convertView;
-
- // remove old markers
- Iterator<MarkerView> iterator = markerViewMap.keySet().iterator();
- while (iterator.hasNext()) {
- MarkerView marker = iterator.next();
- if (!markers.contains(marker)) {
- // remove marker
- convertView = markerViewMap.get(marker);
- for (MapboxMap.MarkerViewAdapter adapter : markerViewAdapters) {
- if (adapter.getMarkerClass().equals(marker.getClass())) {
- adapter.prepareViewForReuse(marker, convertView);
- adapter.releaseView(convertView);
- marker.setMapboxMap(null);
- iterator.remove();
- }
- }
- }
+ return clickHandled;
+ }
+
+ /**
+ * Handles the {@link MarkerView}'s info window offset.
+ *
+ * @param marker that we are ensuring info window offset.
+ */
+ public void ensureInfoWindowOffset(MarkerView marker) {
+ View view = null;
+ if (markerViewMap.containsKey(marker)) {
+ view = markerViewMap.get(marker);
+ } else {
+ for (final MapboxMap.MarkerViewAdapter adapter : markerViewAdapters) {
+ if (adapter.getMarkerClass().equals(marker.getClass())) {
+ View convertView = (View) adapter.getViewReusePool().acquire();
+ view = adapter.getView(marker, convertView, markerViewContainer);
+ break;
}
+ }
+ }
- // introduce new markers
- for (final MarkerView marker : markers) {
- 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) {
- adaptedView.setRotationX(marker.getTilt());
- adaptedView.setRotation(marker.getRotation());
- adaptedView.setAlpha(marker.getAlpha());
- adaptedView.setVisibility(View.GONE);
-
- if (mapboxMap.getSelectedMarkers().contains(marker)) {
- // if a marker to be shown was selected
- // replay that animation with duration 0
- if (adapter.onSelect(marker, adaptedView, true)) {
- mapboxMap.selectMarker(marker);
- }
- }
-
- marker.setMapboxMap(mapboxMap);
- markerViewMap.put(marker, adaptedView);
- if (convertView == null) {
- adaptedView.setVisibility(View.GONE);
- mapView.getMarkerViewContainer().addView(adaptedView);
- }
- }
- }
- }
- }
+ if (view != null) {
+ if (marker.getWidth() == 0) {
+ if (view.getMeasuredWidth() == 0) {
+ //Ensure the marker's view is measured first
+ view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
}
- // trigger update to make newly added ViewMarker visible,
- // these would only be updated when the map is moved.
- update();
+ marker.setWidth(view.getMeasuredWidth());
+ marker.setHeight(view.getMeasuredHeight());
+ }
+
+ // update position on map
+ if (marker.getOffsetX() == MapboxConstants.UNMEASURED) {
+ int x = (int) (marker.getAnchorU() * marker.getWidth());
+ int y = (int) (marker.getAnchorV() * marker.getHeight());
+ marker.setOffset(x, y);
+ }
+
+ // InfoWindow offset
+ int infoWindowOffsetX = (int) ((view.getMeasuredWidth() * marker.getInfoWindowAnchorU()) - marker.getOffsetX());
+ int infoWindowOffsetY = (int) ((view.getMeasuredHeight() * marker.getInfoWindowAnchorV()) - marker.getOffsetY());
+ marker.setTopOffsetPixels(infoWindowOffsetY);
+ marker.setRightOffsetPixels(infoWindowOffsetX);
}
+ }
- public void onClickMarkerView(MarkerView markerView) {
- boolean clickHandled = false;
+ public ViewGroup getMarkerViewContainer() {
+ return markerViewContainer;
+ }
- MapboxMap.MarkerViewAdapter adapter = getViewAdapter(markerView);
- View view = getView(markerView);
- if (adapter == null || view == null) {
- // not a valid state
- return;
- }
+ public void addOnMarkerViewAddedListener(MarkerView markerView, OnMarkerViewAddedListener onMarkerViewAddedListener) {
+ markerViewAddedListenerMap.put(markerView.getId(), onMarkerViewAddedListener);
+ }
- if (onMarkerViewClickListener != null) {
- clickHandled = onMarkerViewClickListener.onMarkerClick(markerView, view, adapter);
- }
+ /**
+ * Default MarkerViewAdapter used for base class of {@link MarkerView} to adapt a MarkerView to
+ * an ImageView.
+ */
+ private static class ImageMarkerViewAdapter extends MapboxMap.MarkerViewAdapter<MarkerView> {
- if (!clickHandled) {
- ensureInfoWindowOffset(markerView);
- select(markerView, view, adapter);
- }
- }
-
- //TODO: This whole method is a stopgap for: https://github.com/mapbox/mapbox-gl-native/issues/5384
- public void ensureInfoWindowOffset(MarkerView marker) {
- View view = null;
- if (markerViewMap.containsKey(marker)) {
- view = markerViewMap.get(marker);
- } else {
- for (final MapboxMap.MarkerViewAdapter adapter : markerViewAdapters) {
- if (adapter.getMarkerClass().equals(marker.getClass())) {
- View convertView = (View) adapter.getViewReusePool().acquire();
- view = adapter.getView(marker, convertView, mapView);
- break;
- }
- }
- }
+ private LayoutInflater inflater;
- if (view != null) {
- if (marker.getWidth() == 0) {
- if(view.getMeasuredWidth()==0) {
- //Ensure the marker's view is measured first
- view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
- }
- marker.setWidth(view.getMeasuredWidth());
- marker.setHeight(view.getMeasuredHeight());
- }
+ ImageMarkerViewAdapter(Context context) {
+ super(context);
+ inflater = LayoutInflater.from(context);
+ }
- // update position on map
- if (marker.getOffsetX() == MapboxConstants.UNMEASURED) {
- int x = (int) (marker.getAnchorU() * marker.getWidth());
- int y = (int) (marker.getAnchorV() * marker.getHeight());
- marker.setOffset(x, y);
- }
+ @Nullable
+ @Override
+ public View getView(@NonNull MarkerView marker, @Nullable View convertView, @NonNull ViewGroup parent) {
+ ViewHolder viewHolder;
+ if (convertView == null) {
+ viewHolder = new ViewHolder();
+ convertView = inflater.inflate(R.layout.mapbox_view_image_marker, parent, false);
+ viewHolder.imageView = (ImageView) convertView.findViewById(R.id.image);
+ convertView.setTag(viewHolder);
+ } else {
+ viewHolder = (ViewHolder) convertView.getTag();
+ }
+ viewHolder.imageView.setImageBitmap(marker.getIcon().getBitmap());
+ return convertView;
+ }
- // InfoWindow offset
- int infoWindowOffsetX = (int) ((view.getMeasuredWidth() * marker.getInfoWindowAnchorU()) - marker.getOffsetX());
- int infoWindowOffsetY = (int) ((view.getMeasuredHeight() * marker.getInfoWindowAnchorV()) - marker.getOffsetY());
- marker.setTopOffsetPixels(infoWindowOffsetY);
- marker.setRightOffsetPixels(infoWindowOffsetX);
- }
+ private static class ViewHolder {
+ ImageView imageView;
}
+ }
+
+ /**
+ * Interface definition invoked when the View of a MarkerView has been added to the map.
+ * <p>
+ * {@link MapboxMap#addMarker(BaseMarkerOptions)}
+ * and only when the related MarkerView is found in the viewport of the map.
+ * </p>
+ */
+ public interface OnMarkerViewAddedListener {
/**
- * Default MarkerViewAdapter used for base class of MarkerView to adapt a MarkerView to an ImageView
+ * Invoked when the View of a MarkerView has been added to the Map.
+ *
+ * @param markerView The MarkerView the View was added for
*/
- public static class ImageMarkerViewAdapter extends MapboxMap.MarkerViewAdapter<MarkerView> {
-
- private LayoutInflater inflater;
-
- public ImageMarkerViewAdapter(Context context) {
- super(context);
- inflater = LayoutInflater.from(context);
- }
-
- @Nullable
- @Override
- public View getView(@NonNull MarkerView marker, @Nullable View convertView, @NonNull ViewGroup parent) {
- ViewHolder viewHolder;
- if (convertView == null) {
- viewHolder = new ViewHolder();
- convertView = inflater.inflate(R.layout.view_image_marker, parent, false);
- viewHolder.imageView = (ImageView) convertView.findViewById(R.id.image);
- convertView.setTag(viewHolder);
- } else {
- viewHolder = (ViewHolder) convertView.getTag();
- }
- viewHolder.imageView.setImageBitmap(marker.getIcon().getBitmap());
- return convertView;
- }
-
- private static class ViewHolder {
- ImageView imageView;
- }
- }
+ void onViewAdded(@NonNull MarkerView markerView);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewOptions.java
index 86ad873347..2d829537fc 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewOptions.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewOptions.java
@@ -10,108 +10,155 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
/**
* builder class for composing MarkerView objects.
* <p>
- * Do not extend this class directly but extend BaseMarkerViewOptions instead.
+ * Do not extend this class directly but extend {@link BaseMarkerViewOptions} instead.
* </p>
*/
public class MarkerViewOptions extends BaseMarkerViewOptions<MarkerView, MarkerViewOptions> {
- private MarkerView marker;
+ private MarkerView marker;
- public MarkerViewOptions() {
- marker = new MarkerView();
- }
+ /**
+ * Defines default options for a MarkerView. Extend {@link BaseMarkerViewOptions} if you need
+ * more customization.
+ */
+ public MarkerViewOptions() {
+ marker = new MarkerView();
+ }
- protected MarkerViewOptions(Parcel in) {
- marker = new MarkerView();
- position((LatLng) in.readParcelable(LatLng.class.getClassLoader()));
- snippet(in.readString());
- title(in.readString());
- flat(in.readByte() != 0);
- anchor(in.readFloat(), in.readFloat());
- infoWindowAnchor(in.readFloat(), in.readFloat());
- rotation(in.readFloat());
- visible(in.readByte() != 0);
- alpha(in.readFloat());
- if (in.readByte() != 0) {
- // this means we have an icon
- String iconId = in.readString();
- Bitmap iconBitmap = in.readParcelable(Bitmap.class.getClassLoader());
- Icon icon = new Icon(iconId, iconBitmap);
- icon(icon);
- }
+ protected MarkerViewOptions(Parcel in) {
+ marker = new MarkerView();
+ position((LatLng) in.readParcelable(LatLng.class.getClassLoader()));
+ snippet(in.readString());
+ title(in.readString());
+ flat(in.readByte() != 0);
+ anchor(in.readFloat(), in.readFloat());
+ infoWindowAnchor(in.readFloat(), in.readFloat());
+ rotation(in.readFloat());
+ visible(in.readByte() != 0);
+ alpha(in.readFloat());
+ if (in.readByte() != 0) {
+ // this means we have an icon
+ String iconId = in.readString();
+ Bitmap iconBitmap = in.readParcelable(Bitmap.class.getClassLoader());
+ Icon icon = new Icon(iconId, iconBitmap);
+ icon(icon);
}
+ }
- @Override
- public MarkerViewOptions getThis() {
- return this;
- }
+ /**
+ * Get the instance of the object for which this method was called.
+ *
+ * @return the object for which this method was called.
+ */
+ @Override
+ public MarkerViewOptions getThis() {
+ return this;
+ }
- @Override
- public int describeContents() {
- return 0;
- }
+ /**
+ * Describe the kinds of special objects contained in this Parcelable's
+ * marshalled representation.
+ *
+ * @return integer 0.
+ */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeParcelable(getPosition(), flags);
- out.writeString(getSnippet());
- out.writeString(getTitle());
- out.writeByte((byte) (isFlat() ? 1 : 0));
- out.writeFloat(getAnchorU());
- out.writeFloat(getAnchorV());
- out.writeFloat(getInfoWindowAnchorU());
- out.writeFloat(getInfoWindowAnchorV());
- out.writeFloat(getRotation());
- out.writeByte((byte) (isVisible() ? 1 : 0));
- out.writeFloat(alpha);
- Icon icon = getIcon();
- out.writeByte((byte) (icon != null ? 1 : 0));
- if (icon != null) {
- out.writeString(getIcon().getId());
- out.writeParcelable(getIcon().getBitmap(), flags);
- }
+ /**
+ * Flatten this object in to a Parcel.
+ *
+ * @param out The Parcel in which the object should be written.
+ * @param flags Additional flags about how the object should be written. May be 0 or
+ * {@link #PARCELABLE_WRITE_RETURN_VALUE}.
+ */
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeParcelable(getPosition(), flags);
+ out.writeString(getSnippet());
+ out.writeString(getTitle());
+ out.writeByte((byte) (isFlat() ? 1 : 0));
+ out.writeFloat(getAnchorU());
+ out.writeFloat(getAnchorV());
+ out.writeFloat(getInfoWindowAnchorU());
+ out.writeFloat(getInfoWindowAnchorV());
+ out.writeFloat(getRotation());
+ out.writeByte((byte) (isVisible() ? 1 : 0));
+ out.writeFloat(alpha);
+ Icon icon = getIcon();
+ out.writeByte((byte) (icon != null ? 1 : 0));
+ if (icon != null) {
+ out.writeString(getIcon().getId());
+ out.writeParcelable(getIcon().getBitmap(), flags);
}
+ }
- @Override
- public MarkerView getMarker() {
- if (position == null) {
- throw new InvalidMarkerPositionException();
- }
-
- marker.setPosition(position);
- marker.setSnippet(snippet);
- marker.setTitle(title);
- marker.setIcon(icon);
- marker.setFlat(flat);
- marker.setAnchor(anchorU, anchorV);
- marker.setInfoWindowAnchor(infoWindowAnchorU, infoWindowAnchorV);
- marker.setRotation(rotation);
- marker.setVisible(visible);
- marker.setAlpha(alpha);
- return marker;
+ /**
+ * Get the {@link MarkerView}.
+ *
+ * @return {@link MarkerView}.
+ */
+ @Override
+ public MarkerView getMarker() {
+ if (position == null) {
+ throw new InvalidMarkerPositionException();
}
- public static final Parcelable.Creator<MarkerViewOptions> CREATOR
- = new Parcelable.Creator<MarkerViewOptions>() {
- public MarkerViewOptions createFromParcel(Parcel in) {
- return new MarkerViewOptions(in);
- }
+ marker.setPosition(position);
+ marker.setSnippet(snippet);
+ marker.setTitle(title);
+ marker.setIcon(icon);
+ marker.setFlat(flat);
+ marker.setAnchor(anchorU, anchorV);
+ marker.setInfoWindowAnchor(infoWindowAnchorU, infoWindowAnchorV);
+ marker.setRotation(rotation);
+ marker.setVisible(visible);
+ marker.setAlpha(alpha);
+ return marker;
+ }
- public MarkerViewOptions[] newArray(int size) {
- return new MarkerViewOptions[size];
- }
+ public static final Parcelable.Creator<MarkerViewOptions> CREATOR =
+ new Parcelable.Creator<MarkerViewOptions>() {
+ public MarkerViewOptions createFromParcel(Parcel in) {
+ return new MarkerViewOptions(in);
+ }
+
+ public MarkerViewOptions[] newArray(int size) {
+ return new MarkerViewOptions[size];
+ }
};
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- MarkerViewOptions that = (MarkerViewOptions) o;
- return marker != null ? marker.equals(that.marker) : that.marker == null;
+ /**
+ * Compares this {@link MarkerViewOptions} object with another {@link MarkerViewOptions} and
+ * determines if they match.
+ *
+ * @param object Another {@link MarkerViewOptions} to compare with this object.
+ * @return True if the {@link MarkerViewOptions} being passed in matches this
+ * {@link PolylineOptions} object. Else, false.
+ */
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
}
-
- @Override
- public int hashCode() {
- return marker != null ? marker.hashCode() : 0;
+ if (object == null || getClass() != object.getClass()) {
+ return false;
}
+ MarkerViewOptions that = (MarkerViewOptions) object;
+ return marker != null ? marker.equals(that.marker) : that.marker == null;
+ }
+
+ /**
+ * Gives an integer which can be used as the bucket number for storing elements of the set/map.
+ * This bucket number is the address of the element inside the set/map. There's no guarantee
+ * that this hash value will be consistent between different Java implementations, or even
+ * between different execution runs of the same program.
+ *
+ * @return integer value you can use for storing element.
+ */
+ @Override
+ public int hashCode() {
+ return marker != null ? marker.hashCode() : 0;
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MultiPoint.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MultiPoint.java
index a76238fdcb..2bd3c82786 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MultiPoint.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MultiPoint.java
@@ -10,48 +10,62 @@ import java.util.List;
*/
public abstract class MultiPoint extends Annotation {
- private List<LatLng> points;
- private float alpha = 1.0f;
-
- protected MultiPoint() {
- super();
- points = new ArrayList<>();
- }
-
- /**
- * Returns a copy of the points.
- *
- * @return points - as a copy
- */
- public List<LatLng> getPoints() {
- return new ArrayList<>(points);
- }
-
- /**
- * Sets the points of this polyline. This method will take a copy
- * of the points, so further mutations to points will have no effect
- * on this polyline.
- *
- * @param points the points of the polyline
- */
- public void setPoints(List<LatLng> points) {
- this.points = new ArrayList<>(points);
- update();
- }
-
- public void addPoint(LatLng point) {
- points.add(point);
- update();
- }
-
- public float getAlpha() {
- return alpha;
- }
-
- public void setAlpha(float alpha) {
- this.alpha = alpha;
- update();
- }
-
- abstract void update();
+ private List<LatLng> points;
+ private float alpha = 1.0f;
+
+ protected MultiPoint() {
+ super();
+ points = new ArrayList<>();
+ }
+
+ /**
+ * Returns a copy of the points.
+ *
+ * @return A {@link List} of points.
+ */
+ public List<LatLng> getPoints() {
+ return new ArrayList<>(points);
+ }
+
+ /**
+ * Sets the points of this polyline. This method will take a copy of the points, so further
+ * mutations to points will have no effect on this polyline.
+ *
+ * @param points A {@link List} of {@link LatLng} points making up the polyline.
+ */
+ public void setPoints(List<LatLng> points) {
+ this.points = new ArrayList<>(points);
+ update();
+ }
+
+ /**
+ * Add a point to the polyline.
+ *
+ * @param point A {@link LatLng} point to be added.
+ */
+ public void addPoint(LatLng point) {
+ points.add(point);
+ update();
+ }
+
+ /**
+ * Value between 0 and 1 defining the polyline alpha.
+ *
+ * @return float value between 0 and 1.
+ */
+ public float getAlpha() {
+ return alpha;
+ }
+
+ /**
+ * Set this {@link MultiPoint}s alpha.
+ *
+ * @param alpha float value between 0 and 1.
+ */
+ public void setAlpha(float alpha) {
+ this.alpha = alpha;
+ update();
+ }
+
+ abstract void update();
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Polygon.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Polygon.java
index 78e3a99e96..7b9de86bc4 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Polygon.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Polygon.java
@@ -9,56 +9,56 @@ import com.mapbox.mapboxsdk.maps.MapboxMap;
*/
public final class Polygon extends MultiPoint {
- private int fillColor = Color.BLACK; // default fillColor is black
- private int strokeColor = Color.BLACK; // default strokeColor is black
+ private int fillColor = Color.BLACK; // default fillColor is black
+ private int strokeColor = Color.BLACK; // default strokeColor is black
- Polygon() {
- super();
- }
+ Polygon() {
+ super();
+ }
- /**
- * Get the color of the fill region of the polygon.
- *
- * @return the color of the fill
- */
- public int getFillColor() {
- return fillColor;
- }
+ /**
+ * Get the color of the fill region of the polygon.
+ *
+ * @return The color of the fill.
+ */
+ public int getFillColor() {
+ return fillColor;
+ }
- /**
- * Get the color fo the stroke of the polygon.
- *
- * @return the color of the stroke
- */
- public int getStrokeColor() {
- return strokeColor;
- }
+ /**
+ * Get the color fo the stroke of the polygon.
+ *
+ * @return The color of the stroke.
+ */
+ public int getStrokeColor() {
+ return strokeColor;
+ }
- /**
- * Sets the color of the fill region of the polygon.
- *
- * @param color - the color in ARGB format
- */
- public void setFillColor(int color) {
- fillColor = color;
- update();
- }
+ /**
+ * Sets the color of the fill region of the polygon.
+ *
+ * @param color The color in ARGB format.
+ */
+ public void setFillColor(int color) {
+ fillColor = color;
+ update();
+ }
- /**
- * Sets the color of the stroke of the polygon.
- *
- * @param color - the color in ARGB format
- */
- public void setStrokeColor(int color) {
- strokeColor = color;
- update();
- }
+ /**
+ * Sets the color of the stroke of the polygon.
+ *
+ * @param color The color in ARGB format.
+ */
+ public void setStrokeColor(int color) {
+ strokeColor = color;
+ update();
+ }
- @Override
- void update() {
- MapboxMap mapboxMap = getMapboxMap();
- if (mapboxMap != null) {
- mapboxMap.updatePolygon(this);
- }
+ @Override
+ void update() {
+ MapboxMap mapboxMap = getMapboxMap();
+ if (mapboxMap != null) {
+ mapboxMap.updatePolygon(this);
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolygonOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolygonOptions.java
index 30847807b9..22f1258fc7 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolygonOptions.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolygonOptions.java
@@ -14,138 +14,220 @@ import java.util.List;
*/
public final class PolygonOptions implements Parcelable {
- public static final Parcelable.Creator<PolygonOptions> CREATOR
- = new Parcelable.Creator<PolygonOptions>() {
- public PolygonOptions createFromParcel(Parcel in) {
- return new PolygonOptions(in);
- }
-
- public PolygonOptions[] newArray(int size) {
- return new PolygonOptions[size];
- }
+ public static final Parcelable.Creator<PolygonOptions> CREATOR =
+ new Parcelable.Creator<PolygonOptions>() {
+ public PolygonOptions createFromParcel(Parcel in) {
+ return new PolygonOptions(in);
+ }
+
+ public PolygonOptions[] newArray(int size) {
+ return new PolygonOptions[size];
+ }
};
- private PolygonOptions(Parcel in) {
- polygon = new Polygon();
- ArrayList<LatLng> pointsList = new ArrayList<>();
- in.readList(pointsList, LatLng.class.getClassLoader());
- addAll(pointsList);
- alpha(in.readFloat());
- fillColor(in.readInt());
- strokeColor(in.readInt());
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeList(getPoints());
- out.writeFloat(getAlpha());
- out.writeInt(getFillColor());
- out.writeInt(getStrokeColor());
- }
-
- private Polygon polygon;
-
- public PolygonOptions() {
- polygon = new Polygon();
- }
-
- public PolygonOptions add(LatLng point) {
- polygon.addPoint(point);
- return this;
- }
-
- public PolygonOptions add(LatLng... points) {
- for (LatLng point : points) {
- add(point);
- }
- return this;
- }
-
- public PolygonOptions addAll(Iterable<LatLng> points) {
- for (LatLng point : points) {
- add(point);
- }
- return this;
- }
-
- public PolygonOptions alpha(float alpha) {
- polygon.setAlpha(alpha);
- return this;
- }
-
- public float getAlpha() {
- return polygon.getAlpha();
- }
-
- /**
- * Sets the color of the polygon.
- *
- * @param color - the color in ARGB format
- * @return PolygonOptions - the options object
- */
- public PolygonOptions fillColor(int color) {
- polygon.setFillColor(color);
- return this;
- }
-
- public int getFillColor() {
- return polygon.getFillColor();
- }
-
- /**
- * Do not use this method. Used internally by the SDK.
- *
- * @return Polygon the Polygon to return
- */
- public Polygon getPolygon() {
- return polygon;
- }
-
- /**
- * Sets the color of the stroke of the polygon.
- *
- * @param color - the color in ARGB format
- * @return PolygonOptions - the options object
- */
- public PolygonOptions strokeColor(int color) {
- polygon.setStrokeColor(color);
- return this;
- }
-
- public int getStrokeColor() {
- return polygon.getStrokeColor();
- }
-
- public List<LatLng> getPoints() {
- // the getter gives us a copy, which is the safe thing to do...
- return polygon.getPoints();
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- PolygonOptions polygon = (PolygonOptions) o;
-
- if (Float.compare(polygon.getAlpha(), getAlpha()) != 0) return false;
- if (getFillColor() != polygon.getFillColor()) return false;
- if (getStrokeColor() != polygon.getStrokeColor()) return false;
- return !(getPoints() != null ? !getPoints().equals(polygon.getPoints()) : polygon.getPoints() != null);
- }
-
- @Override
- public int hashCode() {
- int result = 1;
- result = 31 * result + (getAlpha() != +0.0f ? Float.floatToIntBits(getAlpha()) : 0);
- result = 31 * result + getFillColor();
- result = 31 * result + getStrokeColor();
- result = 31 * result + (getPoints() != null ? getPoints().hashCode() : 0);
- return result;
- }
+ private PolygonOptions(Parcel in) {
+ polygon = new Polygon();
+ ArrayList<LatLng> pointsList = new ArrayList<>();
+ in.readList(pointsList, LatLng.class.getClassLoader());
+ addAll(pointsList);
+ alpha(in.readFloat());
+ fillColor(in.readInt());
+ strokeColor(in.readInt());
+ }
+
+ /**
+ * Describe the kinds of special objects contained in this Parcelable's
+ * marshalled representation.
+ *
+ * @return integer 0.
+ */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * Flatten this object in to a Parcel.
+ *
+ * @param out The Parcel in which the object should be written.
+ * @param flags Additional flags about how the object should be written. May be 0 or
+ * {@link #PARCELABLE_WRITE_RETURN_VALUE}.
+ */
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeList(getPoints());
+ out.writeFloat(getAlpha());
+ out.writeInt(getFillColor());
+ out.writeInt(getStrokeColor());
+ }
+
+ private Polygon polygon;
+
+ /**
+ * Defines options for a polygon.
+ */
+ public PolygonOptions() {
+ polygon = new Polygon();
+ }
+
+ /**
+ * Adds a vertex to the outline of the polygon being built.
+ *
+ * @param point {@link LatLng} point to be added to polygon geometry.
+ * @return This {@link PolygonOptions} object with the given point added to the outline.
+ */
+ public PolygonOptions add(LatLng point) {
+ polygon.addPoint(point);
+ return this;
+ }
+
+ /**
+ * Adds vertices to the outline of the polygon being built.
+ *
+ * @param points {@link LatLng} points to be added to polygon geometry.
+ * @return This {@link PolygonOptions} object with the given points added to the outline.
+ */
+ public PolygonOptions add(LatLng... points) {
+ for (LatLng point : points) {
+ add(point);
+ }
+ return this;
+ }
+
+ /**
+ * Adds vertices to the outline of the polygon being built.
+ *
+ * @param points {@link Iterable} list made up of {@link LatLng} points defining the polygon
+ * geometry
+ * @return This {@link PolygonOptions} object with the given points added to the outline.
+ */
+ public PolygonOptions addAll(Iterable<LatLng> points) {
+ for (LatLng point : points) {
+ add(point);
+ }
+ return this;
+ }
+
+ /**
+ * Set the alpha value of the polyline.
+ *
+ * @param alpha float value between 0 (not visible) and 1.
+ * @return This {@link PolygonOptions} object with the given polygon alpha value.
+ */
+ public PolygonOptions alpha(float alpha) {
+ polygon.setAlpha(alpha);
+ return this;
+ }
+
+ /**
+ * Gets the alpha set for this {@link PolygonOptions} object.
+ *
+ * @return float value between 0 and 1 defining the alpha.
+ */
+ public float getAlpha() {
+ return polygon.getAlpha();
+ }
+
+ /**
+ * Specifies the polygon's fill color, as 32-bit ARGB. The default color is black.
+ *
+ * @param color 32-bit ARGB color.
+ * @return This {@link PolylineOptions} object with a new color set.
+ */
+ public PolygonOptions fillColor(int color) {
+ polygon.setFillColor(color);
+ return this;
+ }
+
+ /**
+ * Gets the fill color set for this {@link PolygonOptions} object.
+ *
+ * @return The fill color of the polygon in ARGB format.
+ */
+ public int getFillColor() {
+ return polygon.getFillColor();
+ }
+
+ /**
+ * Do not use this method. Used internally by the SDK.
+ *
+ * @return Polygon the Polygon to return
+ */
+ public Polygon getPolygon() {
+ return polygon;
+ }
+
+ /**
+ * Specifies the polygon's stroke color, as 32-bit ARGB. The default color is black.
+ *
+ * @param color 32-bit ARGB color.
+ * @return This {@link PolygonOptions} object with a new stroke color set.
+ */
+ public PolygonOptions strokeColor(int color) {
+ polygon.setStrokeColor(color);
+ return this;
+ }
+
+ /**
+ * Gets the stroke color set for this {@link PolygonOptions} object.
+ *
+ * @return The stroke color of the polygon in ARGB format.
+ */
+ public int getStrokeColor() {
+ return polygon.getStrokeColor();
+ }
+
+ public List<LatLng> getPoints() {
+ // the getter gives us a copy, which is the safe thing to do...
+ return polygon.getPoints();
+ }
+
+ /**
+ * Compares this {@link PolygonOptions} object with another {@link PolygonOptions} and
+ * determines if their color, alpha, stroke color, and vertices match.
+ *
+ * @param o Another {@link PolygonOptions} to compare with this object.
+ * @return True if color, alpha, stroke color, and vertices match this {@link PolygonOptions}
+ * object. Else, false.
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ PolygonOptions polygon = (PolygonOptions) o;
+
+ if (Float.compare(polygon.getAlpha(), getAlpha()) != 0) {
+ return false;
+ }
+ if (getFillColor() != polygon.getFillColor()) {
+ return false;
+ }
+ if (getStrokeColor() != polygon.getStrokeColor()) {
+ return false;
+ }
+ return !(getPoints() != null ? !getPoints().equals(polygon.getPoints()) : polygon.getPoints() != null);
+ }
+
+ /**
+ * Gives an integer which can be used as the bucket number for storing elements of the set/map.
+ * This bucket number is the address of the element inside the set/map. There's no guarantee
+ * that this hash value will be consistent between different Java implementations, or even
+ * between different execution runs of the same program.
+ *
+ * @return integer value you can use for storing element.
+ */
+ @Override
+ public int hashCode() {
+ int result = 1;
+ result = 31 * result + (getAlpha() != +0.0f ? Float.floatToIntBits(getAlpha()) : 0);
+ result = 31 * result + getFillColor();
+ result = 31 * result + getStrokeColor();
+ result = 31 * result + (getPoints() != null ? getPoints().hashCode() : 0);
+ return result;
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Polyline.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Polyline.java
index 4bf3242d57..a430d11009 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Polyline.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Polyline.java
@@ -9,56 +9,56 @@ import com.mapbox.mapboxsdk.maps.MapboxMap;
*/
public final class Polyline extends MultiPoint {
- private int color = Color.BLACK; // default color is black
- private float width = 10; // As specified by Google API Docs (in pixels)
+ private int color = Color.BLACK; // default color is black
+ private float width = 10; // As specified by Google API Docs (in pixels)
- Polyline() {
- super();
- }
+ Polyline() {
+ super();
+ }
- /**
- * Returns the Polyline tint color.
- *
- * @return the tint color
- */
- public int getColor() {
- return color;
- }
+ /**
+ * Gets the color of this polyline.
+ *
+ * @return The color in ARGB format.
+ */
+ public int getColor() {
+ return color;
+ }
- /**
- * Returns the Polyline width.
- *
- * @return the width
- */
- public float getWidth() {
- return width;
- }
+ /**
+ * Gets the width of this polyline.
+ *
+ * @return The width in screen pixels.
+ */
+ public float getWidth() {
+ return width;
+ }
- /**
- * Sets the color of the polyline.
- *
- * @param color - the color in ARGB format
- */
- public void setColor(int color) {
- this.color = color;
- update();
- }
+ /**
+ * Sets the color of the polyline.
+ *
+ * @param color - the color in ARGB format
+ */
+ public void setColor(int color) {
+ this.color = color;
+ update();
+ }
- /**
- * Sets the width of the polyline.
- *
- * @param width in pixels
- */
- public void setWidth(float width) {
- this.width = width;
- update();
- }
+ /**
+ * Sets the width of the polyline.
+ *
+ * @param width in pixels
+ */
+ public void setWidth(float width) {
+ this.width = width;
+ update();
+ }
- @Override
- void update() {
- MapboxMap mapboxMap = getMapboxMap();
- if (mapboxMap != null) {
- mapboxMap.updatePolyline(this);
- }
+ @Override
+ void update() {
+ MapboxMap mapboxMap = getMapboxMap();
+ if (mapboxMap != null) {
+ mapboxMap.updatePolyline(this);
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolylineOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolylineOptions.java
index 1e625c10fc..ab22109a4e 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolylineOptions.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolylineOptions.java
@@ -14,137 +14,225 @@ import java.util.List;
public final class PolylineOptions implements Parcelable {
- public static final Parcelable.Creator<PolylineOptions> CREATOR
- = new Parcelable.Creator<PolylineOptions>() {
- public PolylineOptions createFromParcel(Parcel in) {
- return new PolylineOptions(in);
- }
-
- public PolylineOptions[] newArray(int size) {
- return new PolylineOptions[size];
- }
+ public static final Parcelable.Creator<PolylineOptions> CREATOR =
+ new Parcelable.Creator<PolylineOptions>() {
+ public PolylineOptions createFromParcel(Parcel in) {
+ return new PolylineOptions(in);
+ }
+
+ public PolylineOptions[] newArray(int size) {
+ return new PolylineOptions[size];
+ }
};
- private PolylineOptions(Parcel in) {
- polyline = new Polyline();
- ArrayList<LatLng> pointsList = new ArrayList<>();
- in.readList(pointsList, LatLng.class.getClassLoader());
- addAll(pointsList);
- alpha(in.readFloat());
- color(in.readInt());
- width(in.readFloat());
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeList(getPoints());
- out.writeFloat(getAlpha());
- out.writeInt(getColor());
- out.writeFloat(getWidth());
- }
-
- private Polyline polyline;
-
- public PolylineOptions() {
- polyline = new Polyline();
- }
-
- public PolylineOptions add(LatLng point) {
- polyline.addPoint(point);
- return this;
- }
-
- public PolylineOptions add(LatLng... points) {
- for (LatLng point : points) {
- add(point);
- }
- return this;
- }
-
- public PolylineOptions addAll(Iterable<LatLng> points) {
- for (LatLng point : points) {
- add(point);
- }
- return this;
- }
-
- public PolylineOptions alpha(float alpha) {
- polyline.setAlpha(alpha);
- return this;
- }
-
- public float getAlpha() {
- return polyline.getAlpha();
- }
-
- /**
- * Sets the color of the polyline.
- *
- * @param color - the color in ARGB format
- * @return PolyLineOptions The builder used to build a Polyline
- */
- public PolylineOptions color(int color) {
- polyline.setColor(color);
- return this;
- }
-
- public int getColor() {
- return polyline.getColor();
- }
-
- /**
- * Do not use this method. Used internally by the SDK.
- * @return PolyLine The polyline build by this class.
- */
- public Polyline getPolyline() {
- return polyline;
- }
-
- public float getWidth() {
- return polyline.getWidth();
- }
-
- /**
- * Sets the width of the polyline.
- *
- * @param width in pixels
- * @return a new PolylineOptions
- */
- public PolylineOptions width(float width) {
- polyline.setWidth(width);
- return this;
- }
-
- public List<LatLng> getPoints() {
- // the getter gives us a copy, which is the safe thing to do...
- return polyline.getPoints();
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- PolylineOptions polyline = (PolylineOptions) o;
-
- if (Float.compare(polyline.getAlpha(), getAlpha()) != 0) return false;
- if (getColor() != polyline.getColor()) return false;
- if (Float.compare(polyline.getWidth(), getWidth()) != 0) return false;
- return !(getPoints() != null ? !getPoints().equals(polyline.getPoints()) : polyline.getPoints() != null);
- }
-
- @Override
- public int hashCode() {
- int result = 1;
- result = 31 * result + (getAlpha() != +0.0f ? Float.floatToIntBits(getAlpha()) : 0);
- result = 31 * result + getColor();
- result = 31 * result + (getWidth() != +0.0f ? Float.floatToIntBits(getWidth()) : 0);
- result = 31 * result + (getPoints() != null ? getPoints().hashCode() : 0);
- return result;
- }
+ private PolylineOptions(Parcel in) {
+ polyline = new Polyline();
+ ArrayList<LatLng> pointsList = new ArrayList<>();
+ in.readList(pointsList, LatLng.class.getClassLoader());
+ addAll(pointsList);
+ alpha(in.readFloat());
+ color(in.readInt());
+ width(in.readFloat());
+ }
+
+ /**
+ * Describe the kinds of special objects contained in this Parcelable's
+ * marshalled representation.
+ *
+ * @return integer 0.
+ */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * Flatten this object in to a Parcel.
+ *
+ * @param out The Parcel in which the object should be written.
+ * @param flags Additional flags about how the object should be written. May be 0 or
+ * {@link #PARCELABLE_WRITE_RETURN_VALUE}.
+ */
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeList(getPoints());
+ out.writeFloat(getAlpha());
+ out.writeInt(getColor());
+ out.writeFloat(getWidth());
+ }
+
+ private Polyline polyline;
+
+ /**
+ * Defines options for a polyline.
+ */
+ public PolylineOptions() {
+ polyline = new Polyline();
+ }
+
+ /**
+ * Adds a vertex to the end of the polyline being built.
+ *
+ * @param point {@link LatLng} point to be added to polyline geometry.
+ * @return This {@link PolylineOptions} object with the given point on the end.
+ */
+ public PolylineOptions add(LatLng point) {
+ polyline.addPoint(point);
+ return this;
+ }
+
+ /**
+ * Adds vertices to the end of the polyline being built.
+ *
+ * @param points {@link LatLng} points defining the polyline geometry.
+ * @return This {@link PolylineOptions} object with the given point on the end.
+ */
+ public PolylineOptions add(LatLng... points) {
+ for (LatLng point : points) {
+ add(point);
+ }
+ return this;
+ }
+
+ /**
+ * Adds vertices to the end of the polyline being built.
+ *
+ * @param points {@link Iterable} list made up of {@link LatLng} points defining the polyline
+ * geometry
+ * @return This {@link PolylineOptions} object with the given points on the end.
+ */
+ public PolylineOptions addAll(Iterable<LatLng> points) {
+ for (LatLng point : points) {
+ add(point);
+ }
+ return this;
+ }
+
+ /**
+ * Set the alpha value of the polyline.
+ *
+ * @param alpha float value between 0 (not visible) and 1.
+ * @return This {@link PolylineOptions} object with the given polyline alpha value.
+ */
+ public PolylineOptions alpha(float alpha) {
+ polyline.setAlpha(alpha);
+ return this;
+ }
+
+ /**
+ * Gets the alpha set for this {@link PolylineOptions} object.
+ *
+ * @return float value between 0 and 1 defining the alpha.
+ */
+ public float getAlpha() {
+ return polyline.getAlpha();
+ }
+
+ /**
+ * Sets the color of the polyline as a 32-bit ARGB color. The default color is black.
+ *
+ * @param color 32-bit ARGB color.
+ * @return This {@link PolylineOptions} object with a new color set.
+ */
+ public PolylineOptions color(int color) {
+ polyline.setColor(color);
+ return this;
+ }
+
+ /**
+ * Gets the color set for this {@link PolylineOptions} object.
+ *
+ * @return The color of the polyline in ARGB format.
+ */
+ public int getColor() {
+ return polyline.getColor();
+ }
+
+ /**
+ * Do not use this method. Used internally by the SDK.
+ *
+ * @return PolyLine The polyline build by this class.
+ */
+ public Polyline getPolyline() {
+ return polyline;
+ }
+
+ /**
+ * Gets the width set for this {@link PolylineOptions} object.
+ *
+ * @return The width of the polyline in screen pixels.
+ */
+ public float getWidth() {
+ return polyline.getWidth();
+ }
+
+ /**
+ * Sets the width of the polyline in screen pixels. The default is 10.
+ *
+ * @param width float value defining width of polyline using unit pixels.
+ * @return This {@link PolylineOptions} object with a new width set.
+ */
+ public PolylineOptions width(float width) {
+ polyline.setWidth(width);
+ return this;
+ }
+
+ /**
+ * Gets the points set for this {@link PolylineOptions} object.
+ *
+ * @return a {@link List} of {@link LatLng}s specifying the vertices of the polyline.
+ */
+ public List<LatLng> getPoints() {
+ // the getter gives us a copy, which is the safe thing to do...
+ return polyline.getPoints();
+ }
+
+ /**
+ * Compares this {@link PolylineOptions} object with another {@link PolylineOptions} and
+ * determines if their color, alpha, width, and vertices match.
+ *
+ * @param o Another {@link PolylineOptions} to compare with this object.
+ * @return True if color, alpha, width, and vertices match this {@link PolylineOptions} object.
+ * Else, false.
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ PolylineOptions polyline = (PolylineOptions) o;
+
+ if (Float.compare(polyline.getAlpha(), getAlpha()) != 0) {
+ return false;
+ }
+ if (getColor() != polyline.getColor()) {
+ return false;
+ }
+ if (Float.compare(polyline.getWidth(), getWidth()) != 0) {
+ return false;
+ }
+ return !(getPoints() != null ? !getPoints().equals(polyline.getPoints()) : polyline.getPoints() != null);
+ }
+
+ /**
+ * Gives an integer which can be used as the bucket number for storing elements of the set/map.
+ * This bucket number is the address of the element inside the set/map. There's no guarantee
+ * that this hash value will be consistent between different Java implementations, or even
+ * between different execution runs of the same program.
+ *
+ * @return integer value you can use for storing element.
+ */
+ @Override
+ public int hashCode() {
+ int result = 1;
+ result = 31 * result + (getAlpha() != +0.0f ? Float.floatToIntBits(getAlpha()) : 0);
+ result = 31 * result + getColor();
+ result = 31 * result + (getWidth() != +0.0f ? Float.floatToIntBits(getWidth()) : 0);
+ result = 31 * result + (getPoints() != null ? getPoints().hashCode() : 0);
+ return result;
+ }
}
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 3888abc041..79045b68bb 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
@@ -9,268 +9,311 @@ import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.utils.MathUtils;
+import static com.mapbox.mapboxsdk.utils.MathUtils.convertNativeBearing;
+
/**
* Resembles the position, angle, zoom and tilt of the user's viewpoint.
*/
public final class CameraPosition implements Parcelable {
- public static final Parcelable.Creator<CameraPosition> CREATOR
- = new Parcelable.Creator<CameraPosition>() {
- public CameraPosition createFromParcel(Parcel in) {
- double bearing = in.readDouble();
- LatLng target = in.readParcelable(LatLng.class.getClassLoader());
- double tilt = in.readDouble();
- double zoom = in.readDouble();
- return new CameraPosition(target, zoom, tilt, bearing);
- }
-
- public CameraPosition[] newArray(int size) {
- return new CameraPosition[size];
- }
+ public static final CameraPosition DEFAULT = new CameraPosition(new LatLng(), 0, 0, 0);
+
+ public static final Parcelable.Creator<CameraPosition> CREATOR =
+ new Parcelable.Creator<CameraPosition>() {
+ public CameraPosition createFromParcel(Parcel in) {
+ double bearing = in.readDouble();
+ LatLng target = in.readParcelable(LatLng.class.getClassLoader());
+ double tilt = in.readDouble();
+ double zoom = in.readDouble();
+ return new CameraPosition(target, zoom, tilt, bearing);
+ }
+
+ public CameraPosition[] newArray(int size) {
+ return new CameraPosition[size];
+ }
};
+ /**
+ * Direction that the camera is pointing in, in degrees clockwise from north.
+ */
+ public final double bearing;
+
+ /**
+ * The location that the camera is pointing at.
+ */
+ public final LatLng target;
+
+ /**
+ * The angle, in degrees, of the camera angle from the nadir (directly facing the Earth).
+ * See tilt(float) for details of restrictions on the range of values.
+ */
+ public final double tilt;
+
+ /**
+ * Zoom level near the center of the screen. See zoom(float) for the definition of the camera's
+ * zoom level.
+ */
+ public final double zoom;
+
+ /**
+ * Constructs a CameraPosition.
+ *
+ * @param target The target location to align with the center of the screen.
+ * @param zoom Zoom level at target. See zoom(float) for details of restrictions.
+ * @param tilt The camera angle, in degrees, from the nadir (directly down). See tilt(float)
+ * for details of restrictions.
+ * @param bearing Direction that the camera is pointing in, in degrees clockwise from north.
+ * This value will be normalized to be within 0 degrees inclusive and 360 degrees
+ * exclusive.
+ * @throws NullPointerException if target is null
+ * @throws IllegalArgumentException if tilt is outside the range of 0 to 90 degrees inclusive.
+ */
+ CameraPosition(LatLng target, double zoom, double tilt, double bearing) {
+ this.target = target;
+ this.bearing = bearing;
+ this.tilt = tilt;
+ this.zoom = zoom;
+ }
+
+ /**
+ * Describe the kinds of special objects contained in this Parcelable's
+ * marshalled representation.
+ *
+ * @return integer 0.
+ */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * Flatten this object in to a Parcel.
+ *
+ * @param out The Parcel in which the object should be written.
+ * @param flags Additional flags about how the object should be written. May be 0 or
+ * {@link #PARCELABLE_WRITE_RETURN_VALUE}.
+ */
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeDouble(bearing);
+ out.writeParcelable(target, flags);
+ out.writeDouble(tilt);
+ out.writeDouble(zoom);
+ }
+
+ /**
+ * Returns a String with the camera target, zoom, bearing and tilt.
+ *
+ * @return A String with CameraPosition information.
+ */
+ @Override
+ public String toString() {
+ return "Target: " + target + ", Zoom:" + zoom + ", Bearing:" + bearing + ", Tilt:" + tilt;
+ }
+
+ /**
+ * Compares this {@link CameraPosition} object with another {@link CameraPosition} and
+ * determines if their target, zoom, tilt, and bearing match.
+ *
+ * @param o Another {@link CameraPosition} to compare with this object.
+ * @return True if target, zoom, tilt, and bearing match this {@link CameraPosition} object.
+ * Else, false.
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ CameraPosition cameraPosition = (CameraPosition) o;
+ if (target != null && !target.equals(cameraPosition.target)) {
+ return false;
+ } else if (zoom != cameraPosition.zoom) {
+ return false;
+ } else if (tilt != cameraPosition.tilt) {
+ return false;
+ } else if (bearing != cameraPosition.bearing) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Gives an integer which can be used as the bucket number for storing elements of the set/map.
+ * This bucket number is the address of the element inside the set/map. There's no guarantee
+ * that this hash value will be consistent between different Java implementations, or even
+ * between different execution runs of the same program.
+ *
+ * @return integer value you can use for storing element.
+ */
+ @Override
+ public int hashCode() {
+ int result = 1;
+ result = 31 * result + (target != null ? target.hashCode() : 0);
+ return result;
+ }
+
+ /**
+ * Builder for composing {@link CameraPosition} objects.
+ */
+ public static final class Builder {
+
+ private double bearing = -1;
+ private LatLng target = null;
+ private double tilt = -1;
+ private double zoom = -1;
+
/**
- * Direction that the camera is pointing in, in degrees clockwise from north.
+ * Creates an empty builder.
*/
- public final double bearing;
+ public Builder() {
+ super();
+ }
/**
- * The location that the camera is pointing at.
+ * Create Builder with an existing CameraPosition data.
+ *
+ * @param previous Existing CameraPosition values to use
*/
- public final LatLng target;
+ public Builder(CameraPosition previous) {
+ super();
+ if (previous != null) {
+ this.bearing = previous.bearing;
+ this.target = previous.target;
+ this.tilt = previous.tilt;
+ this.zoom = previous.zoom;
+ }
+ }
/**
- * The angle, in degrees, of the camera angle from the nadir (directly facing the Earth). See tilt(float) for details of restrictions on the range of values.
+ * Create Builder with an existing CameraPosition data.
+ *
+ * @param typedArray TypedArray containgin attribute values
*/
- public final double tilt;
+ public Builder(TypedArray typedArray) {
+ super();
+ if (typedArray != null) {
+ this.bearing = typedArray.getFloat(R.styleable.mapbox_MapView_mapbox_cameraBearing, 0.0f);
+ double lat = typedArray.getFloat(R.styleable.mapbox_MapView_mapbox_cameraTargetLat, 0.0f);
+ double lng = typedArray.getFloat(R.styleable.mapbox_MapView_mapbox_cameraTargetLng, 0.0f);
+ this.target = new LatLng(lat, lng);
+ this.tilt = typedArray.getFloat(R.styleable.mapbox_MapView_mapbox_cameraTilt, 0.0f);
+ this.zoom = typedArray.getFloat(R.styleable.mapbox_MapView_mapbox_cameraZoom, 0.0f);
+ }
+ }
/**
- * Zoom level near the center of the screen. See zoom(float) for the definition of the camera's zoom level.
+ * Create Builder from an existing CameraPositionUpdate update.
+ *
+ * @param update Update containing camera options
*/
- public final double zoom;
+ public Builder(CameraUpdateFactory.CameraPositionUpdate update) {
+ super();
+ if (update != null) {
+ bearing = update.getBearing();
+ target = update.getTarget();
+ tilt = update.getTilt();
+ zoom = update.getZoom();
+ }
+ }
/**
- * Constructs a CameraPosition.
+ * Create Builder from an existing CameraPositionUpdate update.
*
- * @param target The target location to align with the center of the screen.
- * @param zoom Zoom level at target. See zoom(float) for details of restrictions.
- * @param tilt The camera angle, in degrees, from the nadir (directly down). See tilt(float) for details of restrictions.
- * @param bearing Direction that the camera is pointing in, in degrees clockwise from north. This value will be normalized to be within 0 degrees inclusive and 360 degrees exclusive.
- * @throws NullPointerException if target is null
- * @throws IllegalArgumentException if tilt is outside the range of 0 to 90 degrees inclusive.
+ * @param update Update containing camera options
*/
- CameraPosition(LatLng target, double zoom, double tilt, double bearing) {
- this.target = target;
- this.bearing = bearing;
- this.tilt = tilt;
- this.zoom = zoom;
+ public Builder(CameraUpdateFactory.ZoomUpdate update) {
+ super();
+ if (update != null) {
+ this.zoom = update.getZoom();
+ }
}
- @Override
- public int describeContents() {
- return 0;
+ /**
+ * Create Builder from an existing array of doubles.
+ * <p>
+ * These values conform to map.ccp representation of a camera position.
+ * </p>
+ *
+ * @param nativeCameraValues Values containing target, bearing, tilt and zoom
+ */
+ public Builder(double[] nativeCameraValues) {
+ super();
+ if (nativeCameraValues != null && nativeCameraValues.length == 5) {
+ target(new LatLng(nativeCameraValues[0], nativeCameraValues[1]));
+ bearing(convertNativeBearing(nativeCameraValues[2]));
+ tilt(nativeCameraValues[3]);
+ zoom(nativeCameraValues[4]);
+ }
}
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeDouble(bearing);
- out.writeParcelable(target, flags);
- out.writeDouble(tilt);
- out.writeDouble(zoom);
+ /**
+ * Sets the direction that the camera is pointing in, in degrees clockwise from north.
+ *
+ * @param bearing Bearing
+ * @return Builder
+ */
+ public Builder bearing(double bearing) {
+ double direction = bearing;
+
+ while (direction >= 360) {
+ direction -= 360;
+ }
+ while (direction < 0) {
+ direction += 360;
+ }
+
+ this.bearing = direction;
+ return this;
}
- @Override
- public String toString() {
- return "Target: " + target + ", Zoom:" + zoom + ", Bearing:" + bearing + ", Tilt:" + tilt;
+ /**
+ * Builds a CameraPosition.
+ *
+ * @return CameraPosition
+ */
+ public CameraPosition build() {
+ return new CameraPosition(target, zoom, tilt, bearing);
}
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
-
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
-
- CameraPosition cameraPosition = (CameraPosition) o;
- if (target != null && !target.equals(cameraPosition.target)) {
- return false;
- } else if (zoom != cameraPosition.zoom) {
- return false;
- } else if (tilt != cameraPosition.tilt) {
- return false;
- } else if (bearing != cameraPosition.bearing) {
- return false;
- }
- return true;
+ /**
+ * Sets the location that the camera is pointing at.
+ *
+ * @param location Location
+ * @return Builder
+ */
+ public Builder target(LatLng location) {
+ this.target = location;
+ return this;
}
- @Override
- public int hashCode() {
- int result = 1;
- result = 31 * result + (target != null ? target.hashCode() : 0);
- return result;
+ /**
+ * 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 = MathUtils.clamp(tilt, MapboxConstants.MINIMUM_TILT, MapboxConstants.MAXIMUM_TILT);
+ return this;
}
/**
- * Builder for composing {@link CameraPosition} objects.
+ * Set the zoom
+ *
+ * @param zoom Zoom value
+ * @return Builder
*/
- public static final class Builder {
-
- private double bearing = -1;
- private LatLng target = null;
- private double tilt = -1;
- private double zoom = -1;
-
- /**
- * Creates an empty builder.
- */
- public Builder() {
- super();
- }
-
- /**
- * Create Builder with an existing CameraPosition data.
- *
- * @param previous Existing CameraPosition values to use
- */
- public Builder(CameraPosition previous) {
- super();
- if (previous != null) {
- this.bearing = previous.bearing;
- this.target = previous.target;
- this.tilt = previous.tilt;
- this.zoom = previous.zoom;
- }
- }
-
- /**
- * Create Builder with an existing CameraPosition data.
- *
- * @param typedArray TypedArray containgin attribute values
- */
- public Builder(TypedArray typedArray) {
- super();
- if (typedArray != null) {
- this.bearing = typedArray.getFloat(R.styleable.MapView_direction, 0.0f);
- 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 = typedArray.getFloat(R.styleable.MapView_tilt, 0.0f);
- this.zoom = typedArray.getFloat(R.styleable.MapView_zoom, 0.0f);
- }
- }
-
- /**
- * Create Builder from an existing CameraPositionUpdate update.
- *
- * @param update Update containing camera options
- */
- public Builder(CameraUpdateFactory.CameraPositionUpdate update) {
- super();
- if (update != null) {
- bearing = update.getBearing();
- target = update.getTarget();
- tilt = update.getTilt();
- zoom = update.getZoom();
- }
- }
-
- /**
- * Create Builder from an existing CameraPositionUpdate update.
- *
- * @param update Update containing camera options
- */
- public Builder(CameraUpdateFactory.ZoomUpdate update) {
- super();
- if (update != null) {
- this.zoom = update.getZoom();
- }
- }
-
- /**
- * Create Builder from an existing array of doubles.
- * <p>
- * These values conform to map.ccp representation of a camera position.
- * </p>
- *
- * @param nativeCameraValues Values containing target, bearing, tilt and zoom
- */
- public Builder(double[] nativeCameraValues) {
- super();
- if (nativeCameraValues != null && nativeCameraValues.length == 5) {
- target(new LatLng(nativeCameraValues[0], nativeCameraValues[1]));
- bearing(nativeCameraValues[2]);
- tilt(nativeCameraValues[3]);
- zoom((float) nativeCameraValues[4]);
- }
- }
-
- /**
- * Sets the direction that the camera is pointing in, in degrees clockwise from north.
- *
- * @param bearing Bearing
- * @return Builder
- */
- public Builder bearing(double bearing) {
- double direction = bearing;
-
- while (direction >= 360) {
- direction -= 360;
- }
- while (direction < 0) {
- direction += 360;
- }
-
- this.bearing = direction;
- return this;
- }
-
- /**
- * Builds a CameraPosition.
- *
- * @return CameraPosition
- */
- public CameraPosition build() {
- return new CameraPosition(target, zoom, tilt, bearing);
- }
-
- /**
- * Sets the location that the camera is pointing at.
- *
- * @param location Location
- * @return Builder
- */
- public Builder target(LatLng location) {
- this.target = location;
- return this;
- }
-
- /**
- * 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) MathUtils.clamp(tilt, MapboxConstants.MINIMUM_TILT, MapboxConstants.MAXIMUM_TILT);
- return this;
- }
-
- /**
- * Set the zoom
- *
- * @param zoom Zoom value
- * @return Builder
- */
- public Builder zoom(double zoom) {
- this.zoom = zoom;
- return this;
- }
+ public Builder zoom(double zoom) {
+ this.zoom = zoom;
+ return this;
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdate.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdate.java
index 94ee4912ce..7e0dbf08fb 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdate.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdate.java
@@ -9,6 +9,6 @@ import com.mapbox.mapboxsdk.maps.MapboxMap;
*/
public interface CameraUpdate {
- CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap);
+ CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap);
}
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 db05486bc2..aecc51530b 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
@@ -21,386 +21,397 @@ import java.lang.annotation.RetentionPolicy;
*/
public final class CameraUpdateFactory {
- /**
- * Returns a CameraUpdate that moves the camera to a specified CameraPosition.
- *
- * @param cameraPosition Camera Position to change to
- * @return CameraUpdate Final Camera Position
- */
- public static CameraUpdate newCameraPosition(@NonNull CameraPosition cameraPosition) {
- return new CameraPositionUpdate(cameraPosition.bearing, cameraPosition.target, cameraPosition.tilt, cameraPosition.zoom);
+ /**
+ * Returns a CameraUpdate that moves the camera to a specified CameraPosition.
+ *
+ * @param cameraPosition Camera Position to change to
+ * @return CameraUpdate Final Camera Position
+ */
+ public static CameraUpdate newCameraPosition(@NonNull CameraPosition cameraPosition) {
+ return new CameraPositionUpdate(cameraPosition.bearing, cameraPosition.target, cameraPosition.tilt,
+ cameraPosition.zoom);
+ }
+
+ /**
+ * Returns a CameraUpdate that moves the center of the screen to a latitude and longitude
+ * specified by a LatLng object. This centers the camera on the LatLng object.
+ *
+ * @param latLng Target location to change to
+ * @return CameraUpdate Final Camera Position
+ */
+ public static CameraUpdate newLatLng(@NonNull LatLng latLng) {
+ return new CameraPositionUpdate(-1, latLng, -1, -1);
+ }
+
+ /**
+ * Returns a {@link CameraUpdate} that transforms the camera such that the specified
+ * latitude/longitude bounds are centered on screen at the greatest possible zoom level.
+ * You can specify padding, in order to inset the bounding box from the map view's edges.
+ * The returned CameraUpdate has a bearing of 0 and a tilt of 0.
+ *
+ * @param bounds Bounds to match Camera position with
+ * @param padding Padding added to the bounds
+ * @return CameraUpdate Final Camera Position
+ */
+ public static CameraUpdate newLatLngBounds(@NonNull LatLngBounds bounds, int padding) {
+ return newLatLngBounds(bounds, padding, padding, padding, padding);
+ }
+
+ /**
+ * Returns a {@link CameraUpdate} that transforms the camera such that the specified
+ * latitude/longitude bounds are centered on screen at the greatest possible zoom level.
+ * You can specify padding, in order to inset the bounding box from the map view's edges.
+ * The returned CameraUpdate has a bearing of 0 and a tilt of 0.
+ *
+ * @param bounds Bounds to base the Camera position out of
+ * @param paddingLeft Padding left of the bounds
+ * @param paddingTop Padding top of the bounds
+ * @param paddingRight Padding right of the bounds
+ * @param paddingBottom Padding bottom of the bounds
+ * @return CameraUpdate Final Camera Position
+ */
+ public static CameraUpdate newLatLngBounds(@NonNull LatLngBounds bounds, int paddingLeft, int paddingTop,
+ int paddingRight, int paddingBottom) {
+ return new CameraBoundsUpdate(bounds, paddingLeft, paddingTop, paddingRight, paddingBottom);
+ }
+
+ /**
+ * Returns a CameraUpdate that moves the center of the screen to a latitude and longitude
+ * specified by a LatLng object, and moves to the given zoom level.
+ *
+ * @param latLng Target location to change to
+ * @param zoom Zoom level to change to
+ * @return CameraUpdate Final Camera Position
+ */
+ public static CameraUpdate newLatLngZoom(@NonNull LatLng latLng, double zoom) {
+ return new CameraPositionUpdate(-1, latLng, -1, zoom);
+ }
+
+ /**
+ * Returns a CameraUpdate that scrolls the camera over the map,
+ * shifting the center of view by the specified number of pixels in the x and y directions.
+ *
+ * @param xPixel Amount of pixels to scroll to in x direction
+ * @param yPixel Amount of pixels to scroll to in y direction
+ * @return CameraUpdate Final Camera Position
+ */
+ public static CameraUpdate scrollBy(float xPixel, float yPixel) {
+ return new CameraMoveUpdate(xPixel, yPixel);
+ }
+
+ /**
+ * Returns a CameraUpdate that shifts the zoom level of the current camera viewpoint.
+ *
+ * @param amount Amount of zoom level to change with
+ * @param focus Focus point of zoom
+ * @return CameraUpdate Final Camera Position
+ */
+ public static CameraUpdate zoomBy(double amount, Point focus) {
+ return new ZoomUpdate(amount, focus.x, focus.y);
+ }
+
+ /**
+ * Returns a CameraUpdate that shifts the zoom level of the current camera viewpoint.
+ *
+ * @param amount Amount of zoom level to change with
+ * @return CameraUpdate Final Camera Position
+ */
+ public static CameraUpdate zoomBy(double amount) {
+ return new ZoomUpdate(ZoomUpdate.ZOOM_BY, amount);
+ }
+
+ /**
+ * Returns a CameraUpdate that zooms in on the map by moving the viewpoint's height closer to
+ * the Earth's surface. The zoom increment is 1.0.
+ *
+ * @return CameraUpdate Final Camera Position
+ */
+ public static CameraUpdate zoomIn() {
+ return new ZoomUpdate(ZoomUpdate.ZOOM_IN);
+ }
+
+ /**
+ * Returns a CameraUpdate that zooms out on the map by moving the viewpoint's height farther
+ * away from the Earth's surface. The zoom increment is -1.0.
+ *
+ * @return CameraUpdate Final Camera Position
+ */
+ public static CameraUpdate zoomOut() {
+ return new ZoomUpdate(ZoomUpdate.ZOOM_OUT);
+ }
+
+ /**
+ * Returns a CameraUpdate that moves the camera viewpoint to a particular zoom level.
+ *
+ * @param zoom Zoom level to change to
+ * @return CameraUpdate Final Camera Position
+ */
+ public static CameraUpdate zoomTo(double zoom) {
+ return new ZoomUpdate(ZoomUpdate.ZOOM_TO, zoom);
+ }
+
+ //
+ // CameraUpdate types
+ //
+
+ static final class CameraPositionUpdate implements CameraUpdate {
+
+ private final double bearing;
+ private final LatLng target;
+ private final double tilt;
+ private final double zoom;
+
+ CameraPositionUpdate(double bearing, LatLng target, double tilt, double zoom) {
+ this.bearing = bearing;
+ this.target = target;
+ this.tilt = tilt;
+ this.zoom = zoom;
}
- /**
- * Returns a CameraUpdate that moves the center of the screen to a latitude and longitude
- * specified by a LatLng object. This centers the camera on the LatLng object.
- *
- * @param latLng Target location to change to
- * @return CameraUpdate Final Camera Position
- */
- public static CameraUpdate newLatLng(@NonNull LatLng latLng) {
- return new CameraPositionUpdate(-1, latLng, -1, -1);
+ public LatLng getTarget() {
+ return target;
}
- /**
- * Returns a CameraUpdate that transforms the camera such that the specified latitude/longitude
- * bounds are centered on screen at the greatest possible zoom level.
- * You can specify padding, in order to inset the bounding box from the map view's edges.
- * The returned CameraUpdate has a bearing of 0 and a tilt of 0.
- *
- * @param bounds Bounds to match Camera position with
- * @param padding Padding added to the bounds
- * @return CameraUpdate Final Camera Position
- */
- public static CameraUpdate newLatLngBounds(@NonNull LatLngBounds bounds, int padding) {
- return newLatLngBounds(bounds, padding, padding, padding, padding);
+ public double getBearing() {
+ return bearing;
}
- /**
- * Returns a CameraUpdate that transforms the camera such that the specified latitude/longitude
- * bounds are centered on screen at the greatest possible zoom level.
- * You can specify padding, in order to inset the bounding box from the map view's edges.
- * The returned CameraUpdate has a bearing of 0 and a tilt of 0.
- *
- * @param bounds Bounds to base the Camera position out of
- * @param paddingLeft Padding left of the bounds
- * @param paddingTop Padding top of the bounds
- * @param paddingRight Padding right of the bounds
- * @param paddingBottom Padding bottom of the bounds
- * @return CameraUpdate Final Camera Position
- */
- public static CameraUpdate newLatLngBounds(@NonNull LatLngBounds bounds, int paddingLeft, int paddingTop, int paddingRight, int paddingBottom) {
- return new CameraBoundsUpdate(bounds, paddingLeft, paddingTop, paddingRight, paddingBottom);
+ public double getTilt() {
+ return tilt;
}
- /**
- * Returns a CameraUpdate that moves the center of the screen to a latitude and longitude specified by a LatLng object,
- * and moves to the given zoom level.
- *
- * @param latLng Target location to change to
- * @param zoom Zoom level to change to
- * @return CameraUpdate Final Camera Position
- */
- public static CameraUpdate newLatLngZoom(@NonNull LatLng latLng, float zoom) {
- return new CameraPositionUpdate(-1, latLng, -1, zoom);
+ public double getZoom() {
+ return zoom;
}
- /**
- * Returns a CameraUpdate that scrolls the camera over the map,
- * shifting the center of view by the specified number of pixels in the x and y directions.
- *
- * @param xPixel Amount of pixels to scroll to in x direction
- * @param yPixel Amount of pixels to scroll to in y direction
- * @return CameraUpdate Final Camera Position
- */
- public static CameraUpdate scrollBy(float xPixel, float yPixel) {
- return new CameraMoveUpdate(xPixel, yPixel);
+ @Override
+ public CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap) {
+ CameraPosition previousPosition = mapboxMap.getCameraPosition();
+ if (target == null) {
+ return new CameraPosition.Builder(this)
+ .target(previousPosition.target)
+ .build();
+ }
+ return new CameraPosition.Builder(this).build();
}
+ }
- /**
- * Returns a CameraUpdate that shifts the zoom level of the current camera viewpoint.
- *
- * @param amount Amount of zoom level to change with
- * @param focus Focus point of zoom
- * @return CameraUpdate Final Camera Position
- */
- public static CameraUpdate zoomBy(float amount, Point focus) {
- return new ZoomUpdate(amount, focus.x, focus.y);
+ static final class CameraBoundsUpdate implements CameraUpdate {
+
+ private LatLngBounds bounds;
+ private RectF padding;
+
+ CameraBoundsUpdate(LatLngBounds bounds, RectF padding) {
+ this.bounds = bounds;
+ this.padding = padding;
}
- /**
- * Returns a CameraUpdate that shifts the zoom level of the current camera viewpoint.
- *
- * @param amount Amount of zoom level to change with
- * @return CameraUpdate Final Camera Position
- */
- public static CameraUpdate zoomBy(float amount) {
- return new ZoomUpdate(ZoomUpdate.ZOOM_BY, amount);
+ CameraBoundsUpdate(LatLngBounds bounds, int[] padding) {
+ this(bounds, new RectF(padding[0], padding[1], padding[2], padding[3]));
}
- /**
- * Returns a CameraUpdate that zooms in on the map by moving the viewpoint's height closer to the Earth's surface. The zoom increment is 1.0.
- *
- * @return CameraUpdate Final Camera Position
- */
- public static CameraUpdate zoomIn() {
- return new ZoomUpdate(ZoomUpdate.ZOOM_IN);
+ CameraBoundsUpdate(LatLngBounds bounds, int paddingLeft, int paddingTop, int paddingRight, int paddingBottom) {
+ this(bounds, new int[] {paddingLeft, paddingTop, paddingRight, paddingBottom});
}
- /**
- * Returns a CameraUpdate that zooms out on the map by moving the viewpoint's height farther away from the Earth's surface. The zoom increment is -1.0.
- *
- * @return CameraUpdate Final Camera Position
- */
- public static CameraUpdate zoomOut() {
- return new ZoomUpdate(ZoomUpdate.ZOOM_OUT);
+ public LatLngBounds getBounds() {
+ return bounds;
+ }
+
+ public RectF getPadding() {
+ return padding;
+ }
+
+ @Override
+ public CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap) {
+ // Get required objects
+ Projection projection = mapboxMap.getProjection();
+ UiSettings uiSettings = mapboxMap.getUiSettings();
+
+ // calculate correct padding
+ int[] mapPadding = mapboxMap.getPadding();
+ RectF latLngPadding = getPadding();
+ RectF padding = new RectF(latLngPadding.left + mapPadding[0],
+ latLngPadding.top + mapPadding[1],
+ latLngPadding.right + mapPadding[2],
+ latLngPadding.bottom + mapPadding[3]);
+
+ // Calculate the bounds of the possibly rotated shape with respect to the viewport
+ PointF nePixel = new PointF(-Float.MAX_VALUE, -Float.MAX_VALUE);
+ PointF swPixel = new PointF(Float.MAX_VALUE, Float.MAX_VALUE);
+ float viewportHeight = uiSettings.getHeight();
+ for (LatLng latLng : getBounds().toLatLngs()) {
+ PointF pixel = projection.toScreenLocation(latLng);
+ swPixel.x = Math.min(swPixel.x, pixel.x);
+ nePixel.x = Math.max(nePixel.x, pixel.x);
+ swPixel.y = Math.min(swPixel.y, viewportHeight - pixel.y);
+ nePixel.y = Math.max(nePixel.y, viewportHeight - pixel.y);
+ }
+
+ // Calculate width/height
+ float width = nePixel.x - swPixel.x;
+ float height = nePixel.y - swPixel.y;
+
+ double zoom = 0;
+ float minScale = 1;
+ // Calculate the zoom level
+ if (padding != null) {
+ float scaleX = (uiSettings.getWidth() - padding.left - padding.right) / width;
+ float scaleY = (uiSettings.getHeight() - padding.top - padding.bottom) / height;
+ minScale = scaleX < scaleY ? scaleX : scaleY;
+ zoom = calculateZoom(mapboxMap, minScale);
+ zoom = MathUtils.clamp(zoom, mapboxMap.getMinZoomLevel(), mapboxMap.getMaxZoomLevel());
+ }
+
+ // Calculate the center point
+ PointF paddedNEPixel = new PointF(nePixel.x + padding.right / minScale, nePixel.y + padding.top / minScale);
+ PointF paddedSWPixel = new PointF(swPixel.x - padding.left / minScale, swPixel.y - padding.bottom / minScale);
+ PointF centerPixel = new PointF((paddedNEPixel.x + paddedSWPixel.x) / 2, (paddedNEPixel.y + paddedSWPixel.y) / 2);
+ centerPixel.y = viewportHeight - centerPixel.y;
+ LatLng center = projection.fromScreenLocation(centerPixel);
+
+ return new CameraPosition.Builder()
+ .target(center)
+ .zoom(zoom)
+ .tilt(0)
+ .bearing(0)
+ .build();
}
/**
- * Returns a CameraUpdate that moves the camera viewpoint to a particular zoom level.
+ * Calculates a zoom level based on minimum scale and current scale from MapView
*
- * @param zoom Zoom level to change to
- * @return CameraUpdate Final Camera Position
+ * @param minScale The minimum scale to calculate the zoom level.
+ * @return zoom level that fits the MapView.
*/
- public static CameraUpdate zoomTo(float zoom) {
- return new ZoomUpdate(ZoomUpdate.ZOOM_TO, zoom);
+ public double calculateZoom(MapboxMap mapboxMap, float minScale) {
+ return Math.log(mapboxMap.getCameraPosition().zoom * minScale) / Math.log(2);
+ }
+ }
+
+ static final class CameraMoveUpdate implements CameraUpdate {
+
+ private float x;
+ private float y;
+
+ CameraMoveUpdate(float x, float y) {
+ this.x = x;
+ this.y = y;
+ }
+
+ @Override
+ public CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap) {
+ UiSettings uiSettings = mapboxMap.getUiSettings();
+ Projection projection = mapboxMap.getProjection();
+
+ // Calculate the new center point
+ float viewPortWidth = uiSettings.getWidth();
+ float viewPortHeight = uiSettings.getHeight();
+ PointF targetPoint = new PointF(viewPortWidth / 2 + x, viewPortHeight / 2 + y);
+
+ // Convert point to LatLng
+ LatLng latLng = projection.fromScreenLocation(targetPoint);
+
+ CameraPosition previousPosition = mapboxMap.getCameraPosition();
+ return new CameraPosition.Builder()
+ .target(latLng != null ? latLng : previousPosition.target)
+ .zoom(previousPosition.zoom)
+ .tilt(previousPosition.tilt)
+ .bearing(previousPosition.bearing)
+ .build();
+ }
+ }
+
+ static final class ZoomUpdate implements CameraUpdate {
+
+ @IntDef( {ZOOM_IN, ZOOM_OUT, ZOOM_BY, ZOOM_TO, ZOOM_TO_POINT})
+ @Retention(RetentionPolicy.SOURCE)
+ @interface Type {
+ }
+
+ 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;
+ private final double zoom;
+ private float x;
+ private float y;
+
+ ZoomUpdate(@Type int type) {
+ this.type = type;
+ this.zoom = 0;
+ }
+
+ ZoomUpdate(@Type int type, double zoom) {
+ this.type = type;
+ this.zoom = zoom;
+ }
+
+ ZoomUpdate(double zoom, float x, float y) {
+ this.type = ZOOM_TO_POINT;
+ this.zoom = zoom;
+ this.x = x;
+ this.y = y;
+ }
+
+ public double getZoom() {
+ return zoom;
+ }
+
+ @Type
+ public int getType() {
+ return type;
}
- //
- // CameraUpdate types
- //
-
- static final class CameraPositionUpdate implements CameraUpdate {
-
- private final double bearing;
- private final LatLng target;
- private final double tilt;
- private final double zoom;
-
- CameraPositionUpdate(double bearing, LatLng target, double tilt, double zoom) {
- this.bearing = bearing;
- this.target = target;
- this.tilt = tilt;
- this.zoom = zoom;
- }
-
- public LatLng getTarget() {
- return target;
- }
-
- public double getBearing() {
- return bearing;
- }
-
- public double getTilt() {
- return tilt;
- }
-
- public double getZoom() {
- return zoom;
- }
-
- @Override
- public CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap) {
- CameraPosition previousPosition = mapboxMap.getCameraPosition();
- if (target == null) {
- return new CameraPosition.Builder()
- .tilt(tilt)
- .zoom(zoom)
- .bearing(bearing)
- .target(previousPosition.target)
- .build();
- }
- return new CameraPosition.Builder(this).build();
- }
+ public float getX() {
+ return x;
}
- static final class CameraBoundsUpdate implements CameraUpdate {
-
- private LatLngBounds bounds;
- private RectF padding;
-
- CameraBoundsUpdate(LatLngBounds bounds, RectF padding) {
- this.bounds = bounds;
- this.padding = padding;
- }
-
- CameraBoundsUpdate(LatLngBounds bounds, int[] padding) {
- this(bounds, new RectF(padding[0], padding[1], padding[2], padding[3]));
- }
-
- CameraBoundsUpdate(LatLngBounds bounds, int paddingLeft, int paddingTop, int paddingRight, int paddingBottom) {
- this(bounds, new int[]{paddingLeft, paddingTop, paddingRight, paddingBottom});
- }
-
- public LatLngBounds getBounds() {
- return bounds;
- }
-
- public RectF getPadding() {
- return padding;
- }
-
- @Override
- public CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap) {
- // Get required objects
- Projection projection = mapboxMap.getProjection();
- UiSettings uiSettings = mapboxMap.getUiSettings();
-
- // calculate correct padding
- int[] mapPadding = mapboxMap.getPadding();
- RectF latLngPadding = getPadding();
- RectF padding = new RectF(latLngPadding.left + mapPadding[0],
- latLngPadding.top + mapPadding[1],
- latLngPadding.right + mapPadding[2],
- latLngPadding.bottom + mapPadding[3]);
-
- // Calculate the bounds of the possibly rotated shape with respect to the viewport
- PointF nePixel = new PointF(-Float.MAX_VALUE, -Float.MAX_VALUE);
- PointF swPixel = new PointF(Float.MAX_VALUE, Float.MAX_VALUE);
- float viewportHeight = uiSettings.getHeight();
- for (LatLng latLng : getBounds().toLatLngs()) {
- PointF pixel = projection.toScreenLocation(latLng);
- swPixel.x = Math.min(swPixel.x, pixel.x);
- nePixel.x = Math.max(nePixel.x, pixel.x);
- swPixel.y = Math.min(swPixel.y, viewportHeight - pixel.y);
- nePixel.y = Math.max(nePixel.y, viewportHeight - pixel.y);
- }
-
- // Calculate width/height
- float width = nePixel.x - swPixel.x;
- float height = nePixel.y - swPixel.y;
-
- double zoom = 0;
- float minScale = 1;
- // Calculate the zoom level
- if (padding != null) {
- float scaleX = (uiSettings.getWidth() - padding.left - padding.right) / width;
- float scaleY = (uiSettings.getHeight() - padding.top - padding.bottom) / height;
- minScale = scaleX < scaleY ? scaleX : scaleY;
- zoom = projection.calculateZoom(minScale);
- zoom = MathUtils.clamp(zoom, (float) mapboxMap.getMinZoom(), (float) mapboxMap.getMaxZoom());
- }
-
- // Calculate the center point
- PointF paddedNEPixel = new PointF(nePixel.x + padding.right / minScale, nePixel.y + padding.top / minScale);
- PointF paddedSWPixel = new PointF(swPixel.x - padding.left / minScale, swPixel.y - padding.bottom / minScale);
- PointF centerPixel = new PointF((paddedNEPixel.x + paddedSWPixel.x) / 2, (paddedNEPixel.y + paddedSWPixel.y) / 2);
- centerPixel.y = viewportHeight - centerPixel.y;
- LatLng center = projection.fromScreenLocation(centerPixel);
-
- return new CameraPosition.Builder()
- .target(center)
- .zoom((float) zoom)
- .tilt(0)
- .bearing(0)
- .build();
- }
+ public float getY() {
+ return y;
}
- static final class CameraMoveUpdate implements CameraUpdate {
-
- private float x;
- private float y;
-
- CameraMoveUpdate(float x, float y) {
- this.x = x;
- this.y = y;
- }
-
- @Override
- public CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap) {
- UiSettings uiSettings = mapboxMap.getUiSettings();
- Projection projection = mapboxMap.getProjection();
-
- // Calculate the new center point
- float viewPortWidth = uiSettings.getWidth();
- float viewPortHeight = uiSettings.getHeight();
- PointF targetPoint = new PointF(viewPortWidth / 2 + x, viewPortHeight / 2 + y);
-
- // Convert point to LatLng
- LatLng latLng = projection.fromScreenLocation(targetPoint);
-
- CameraPosition previousPosition = mapboxMap.getCameraPosition();
- return new CameraPosition.Builder()
- .target(latLng != null ? latLng : previousPosition.target)
- .zoom(previousPosition.zoom)
- .tilt(previousPosition.tilt)
- .bearing(previousPosition.bearing)
- .build();
- }
+ double transformZoom(double currentZoom) {
+ switch (getType()) {
+ case CameraUpdateFactory.ZoomUpdate.ZOOM_IN:
+ currentZoom++;
+ break;
+ case CameraUpdateFactory.ZoomUpdate.ZOOM_OUT:
+ currentZoom--;
+ if (currentZoom < 0) {
+ currentZoom = 0;
+ }
+ break;
+ case CameraUpdateFactory.ZoomUpdate.ZOOM_TO:
+ currentZoom = getZoom();
+ break;
+ case CameraUpdateFactory.ZoomUpdate.ZOOM_BY:
+ currentZoom = currentZoom + getZoom();
+ break;
+ case CameraUpdateFactory.ZoomUpdate.ZOOM_TO_POINT:
+ currentZoom = currentZoom + getZoom();
+ break;
+ }
+ return currentZoom;
}
- static final class ZoomUpdate implements CameraUpdate {
-
- @IntDef({ZOOM_IN, ZOOM_OUT, ZOOM_BY, ZOOM_TO, ZOOM_TO_POINT})
- @Retention(RetentionPolicy.SOURCE)
- @interface Type {
- }
-
- 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;
- private final double zoom;
- private float x;
- private float y;
-
- ZoomUpdate(@Type int type) {
- this.type = type;
- this.zoom = 0;
- }
-
- ZoomUpdate(@Type int type, float zoom) {
- this.type = type;
- this.zoom = zoom;
- }
-
- ZoomUpdate(float zoom, float x, float y) {
- this.type = ZOOM_TO_POINT;
- this.zoom = zoom;
- this.x = x;
- this.y = y;
- }
-
- public double getZoom() {
- return zoom;
- }
-
- @Type
- public int getType() {
- return type;
- }
-
- public float getX() {
- return x;
- }
-
- public float getY() {
- return y;
- }
-
- double transformZoom(double currentZoom) {
- switch (getType()) {
- case CameraUpdateFactory.ZoomUpdate.ZOOM_IN:
- currentZoom++;
- break;
- case CameraUpdateFactory.ZoomUpdate.ZOOM_OUT:
- currentZoom--;
- if (currentZoom < 0) {
- currentZoom = 0;
- }
- break;
- case CameraUpdateFactory.ZoomUpdate.ZOOM_TO:
- currentZoom = getZoom();
- break;
- case CameraUpdateFactory.ZoomUpdate.ZOOM_BY:
- currentZoom = currentZoom + getZoom();
- break;
- case CameraUpdateFactory.ZoomUpdate.ZOOM_TO_POINT:
- currentZoom = currentZoom + getZoom();
- break;
- }
- return currentZoom;
- }
-
- @Override
- public CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap) {
- CameraPosition cameraPosition = mapboxMap.getCameraPosition();
- if (getType() != CameraUpdateFactory.ZoomUpdate.ZOOM_TO_POINT) {
- return new CameraPosition.Builder(cameraPosition)
- .zoom(transformZoom(cameraPosition.zoom))
- .build();
- } else {
- return new CameraPosition.Builder(cameraPosition)
- .zoom(transformZoom(cameraPosition.zoom))
- .target(mapboxMap.getProjection().fromScreenLocation(new PointF(getX(), getY())))
- .build();
- }
- }
+ @Override
+ public CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap) {
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ if (getType() != CameraUpdateFactory.ZoomUpdate.ZOOM_TO_POINT) {
+ return new CameraPosition.Builder(cameraPosition)
+ .zoom(transformZoom(cameraPosition.zoom))
+ .build();
+ } else {
+ return new CameraPosition.Builder(cameraPosition)
+ .zoom(transformZoom(cameraPosition.zoom))
+ .target(mapboxMap.getProjection().fromScreenLocation(new PointF(getX(), getY())))
+ .build();
+ }
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/GeoConstants.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/GeoConstants.java
index ed6f77f419..009ae936d5 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/GeoConstants.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/GeoConstants.java
@@ -5,34 +5,34 @@ package com.mapbox.mapboxsdk.constants;
*/
public class GeoConstants {
- /**
- * The <a href='http://en.wikipedia.org/wiki/Earth_radius#Equatorial_radius'>equatorial radius</a>
- * value in meters
- */
- public static final int RADIUS_EARTH_METERS = 6378137;
+ /**
+ * The <a href='http://en.wikipedia.org/wiki/Earth_radius#Equatorial_radius'>equatorial radius</a>
+ * value in meters
+ */
+ public static final int RADIUS_EARTH_METERS = 6378137;
- /**
- * The minimum latitude on Earth. This is the minimum latitude representable
- * by Mapbox GL's Mercator projection, because the projection distorts latitude
- * near the poles towards infinity.
- */
- public static final double MIN_LATITUDE = -85.05112878;
+ /**
+ * The minimum latitude on Earth. This is the minimum latitude representable
+ * by Mapbox GL's Mercator projection, because the projection distorts latitude
+ * near the poles towards infinity.
+ */
+ public static final double MIN_LATITUDE = -85.05112878;
- /**
- * The maximum latitude on Earth. This is the maximum latitude representable
- * by Mapbox GL's Mercator projection, because the projection distorts latitude
- * near the poles towards infinity.
- */
- public static final double MAX_LATITUDE = 85.05112878;
+ /**
+ * The maximum latitude on Earth. This is the maximum latitude representable
+ * by Mapbox GL's Mercator projection, because the projection distorts latitude
+ * near the poles towards infinity.
+ */
+ public static final double MAX_LATITUDE = 85.05112878;
- /**
- * The minimum longitude on Earth
- */
- public static final double MIN_LONGITUDE = -180;
+ /**
+ * The minimum longitude on Earth
+ */
+ public static final double MIN_LONGITUDE = -180;
- /**
- * The maximum longitude on Earth
- */
- public static final double MAX_LONGITUDE = 180;
+ /**
+ * The maximum longitude on Earth
+ */
+ public static final double MAX_LONGITUDE = 180;
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java
index 10d5c55044..e2a5d40795 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java
@@ -1,6 +1,5 @@
package com.mapbox.mapboxsdk.constants;
-import android.content.Context;
import java.util.Locale;
/**
@@ -8,132 +7,129 @@ import java.util.Locale;
*/
public class MapboxConstants {
- /**
- * Default Locale for data processing (ex: String.toLowerCase(MAPBOX_LOCALE, "foo"))
- */
- public static final Locale MAPBOX_LOCALE = Locale.US;
-
- /**
- * Key used to store access token in AndroidManifest.xml
- * @deprecated As of release 4.1.0, replaced by {@link com.mapbox.mapboxsdk.MapboxAccountManager#start(Context, String)}
- */
- @Deprecated
- public static final String KEY_META_DATA_MANIFEST = "com.mapbox.AccessToken";
-
- /**
- * Key used to store staging data server url in AndroidManifest.xml
- */
- public static final String KEY_META_DATA_STAGING_SERVER = "com.mapbox.TestEventsServer";
-
- /**
- * Key used to store staging data server access token in AndroidManifest.xml
- */
- public static final String KEY_META_DATA_STAGING_ACCESS_TOKEN = "com.mapbox.TestEventsAccessToken";
-
- /**
- * Key used to switch storage to external in AndroidManifest.xml
- */
- public final static String KEY_META_DATA_SET_STORAGE_EXTERNAL = "com.mapbox.SetStorageExternal";
-
- /**
- * Default value for KEY_META_DATA_SET_STORAGE_EXTERNAL (default is internal storage)
- */
- public final static boolean DEFAULT_SET_STORAGE_EXTERNAL = false;
-
- /**
- * Unmeasured state
- */
- public final static float UNMEASURED = -1f;
-
- /**
- * Default animation time
- */
- public static final int ANIMATION_DURATION = 300;
-
- /**
- * Default short animation time
- */
- public static final int ANIMATION_DURATION_SHORT = 150;
-
- /**
- * The currently supported minimum zoom level.
- */
- public static final float MINIMUM_ZOOM = 0.0f;
-
- /**
- * The currently supported maximum zoom level.
- */
- public static final float MAXIMUM_ZOOM = 21.0f;
-
- /**
- * The currently supported maximum tilt value.
- */
- public static final double MAXIMUM_TILT = 60;
-
- /**
- * The currently supported minimum tilt value.
- */
- public static final double MINIMUM_TILT = 0;
-
- /**
- * The currently supported maximum direction
- */
- public static final double MAXIMUM_DIRECTION = 360;
-
- /**
- * The currently supported minimum direction
- */
- public static final double MINIMUM_DIRECTION = 0;
-
- /**
- * Fragment Argument Key for MapboxMapOptions
- */
- public static final String FRAG_ARG_MAPBOXMAPOPTIONS = "MapboxMapOptions";
-
- // Save instance state keys
- public static final String STATE_HAS_SAVED_STATE = "savedState";
- public static final String STATE_CAMERA_POSITION = "cameraPosition";
- public static final String STATE_ZOOM_ENABLED = "zoomEnabled";
- public static final String STATE_ZOOM_ENABLED_CHANGE = "zoomEnabledChange";
- public static final String STATE_SCROLL_ENABLED = "scrollEnabled";
- public static final String STATE_SCROLL_ENABLED_CHANGE = "scrollEnabledChange";
- public static final String STATE_ROTATE_ENABLED = "rotateEnabled";
- public static final String STATE_ROTATE_ENABLED_CHANGE = "rotateEnabledChange";
- public static final String STATE_TILT_ENABLED = "tiltEnabled";
- public static final String STATE_TILT_ENABLED_CHANGE = "tiltEnabledChange";
- public static final String STATE_ZOOM_CONTROLS_ENABLED = "zoomControlsEnabled";
- public static final String STATE_DEBUG_ACTIVE = "debugActive";
- public static final String STATE_STYLE_URL = "styleUrl";
- public static final String STATE_MY_LOCATION_ENABLED = "myLocationEnabled";
- public static final String STATE_MY_LOCATION_TRACKING_MODE = "myLocationTracking";
- public static final String STATE_MY_BEARING_TRACKING_MODE = "myBearingTracking";
- public static final String STATE_MY_LOCATION_TRACKING_DISMISS = "myLocationTrackingDismiss";
- public static final String STATE_MY_BEARING_TRACKING_DISMISS = "myBearingTrackingDismiss";
- public static final String STATE_COMPASS_ENABLED = "compassEnabled";
- public static final String STATE_COMPASS_GRAVITY = "compassGravity";
- public static final String STATE_COMPASS_MARGIN_LEFT = "compassMarginLeft";
- public static final String STATE_COMPASS_MARGIN_TOP = "compassMarginTop";
- public static final String STATE_COMPASS_MARGIN_RIGHT = "compassMarginRight";
- public static final String STATE_COMPASS_MARGIN_BOTTOM = "compassMarginBottom";
- public static final String STATE_COMPASS_FADE_WHEN_FACING_NORTH = "compassFade";
- public static final String STATE_LOGO_GRAVITY = "logoGravity";
- public static final String STATE_LOGO_MARGIN_LEFT = "logoMarginLeft";
- public static final String STATE_LOGO_MARGIN_TOP = "logoMarginTop";
- public static final String STATE_LOGO_MARGIN_RIGHT = "logoMarginRight";
- public static final String STATE_LOGO_MARGIN_BOTTOM = "logoMarginBottom";
- public static final String STATE_LOGO_ENABLED = "logoEnabled";
- public static final String STATE_ATTRIBUTION_GRAVITY = "attrGravity";
- public static final String STATE_ATTRIBUTION_MARGIN_LEFT = "attrMarginLeft";
- public static final String STATE_ATTRIBUTION_MARGIN_TOP = "attrMarginTop";
- public static final String STATE_ATTRIBUTION_MARGIN_RIGHT = "attrMarginRight";
- public static final String STATE_ATTRIBUTION_MARGIN_BOTTOM = "atrrMarginBottom";
- public static final String STATE_ATTRIBUTION_ENABLED = "atrrEnabled";
-
- public static final String TAG = "MapboxMap";
-
- public static final String MAPBOX_SHARED_PREFERENCES_FILE = "MapboxSharedPreferences";
- public static final String MAPBOX_SHARED_PREFERENCE_KEY_VENDORID = "mapboxVendorId";
- public static final String MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_ENABLED = "mapboxTelemetryEnabled";
- public static final String MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_STAGING_URL = "mapboxTelemetryStagingUrl";
- public static final String MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_STAGING_ACCESS_TOKEN = "mapboxTelemetryStagingAccessToken";
+ /**
+ * Default Locale for data processing (ex: String.toLowerCase(MAPBOX_LOCALE, "foo"))
+ */
+ public static final Locale MAPBOX_LOCALE = Locale.US;
+
+ /**
+ * Key used to store staging data server url in AndroidManifest.xml
+ */
+ public static final String KEY_META_DATA_STAGING_SERVER = "com.mapbox.TestEventsServer";
+
+ /**
+ * Key used to store staging data server access token in AndroidManifest.xml
+ */
+ public static final String KEY_META_DATA_STAGING_ACCESS_TOKEN = "com.mapbox.TestEventsAccessToken";
+
+ /**
+ * Key used to switch storage to external in AndroidManifest.xml
+ */
+ public static final String KEY_META_DATA_SET_STORAGE_EXTERNAL = "com.mapbox.SetStorageExternal";
+
+ /**
+ * Default value for KEY_META_DATA_SET_STORAGE_EXTERNAL (default is internal storage)
+ */
+ public static final boolean DEFAULT_SET_STORAGE_EXTERNAL = false;
+
+ /**
+ * Unmeasured state
+ */
+ public static final float UNMEASURED = -1f;
+
+ /**
+ * Default animation time
+ */
+ public static final int ANIMATION_DURATION = 300;
+
+ /**
+ * Default short animation time
+ */
+ public static final int ANIMATION_DURATION_SHORT = 150;
+
+ /**
+ * Animation time of a fling gesture
+ */
+ public static final long ANIMATION_DURATION_FLING = 350;
+
+ /**
+ * The currently supported minimum zoom level.
+ */
+ public static final float MINIMUM_ZOOM = 0.0f;
+
+ /**
+ * The currently supported maximum zoom level.
+ */
+ public static final float MAXIMUM_ZOOM = 20.0f;
+
+ /**
+ * The currently supported maximum tilt value.
+ */
+ public static final double MAXIMUM_TILT = 60;
+
+ /**
+ * The currently supported minimum tilt value.
+ */
+ public static final double MINIMUM_TILT = 0;
+
+ /**
+ * The currently supported maximum direction
+ */
+ public static final double MAXIMUM_DIRECTION = 360;
+
+ /**
+ * The currently supported minimum direction
+ */
+ public static final double MINIMUM_DIRECTION = 0;
+
+ /**
+ * Fragment Argument Key for MapboxMapOptions
+ */
+ public static final String FRAG_ARG_MAPBOXMAPOPTIONS = "MapboxMapOptions";
+
+ // Save instance state keys
+ public static final String STATE_HAS_SAVED_STATE = "savedState";
+ public static final String STATE_CAMERA_POSITION = "cameraPosition";
+ public static final String STATE_ZOOM_ENABLED = "zoomEnabled";
+ public static final String STATE_ZOOM_ENABLED_CHANGE = "zoomEnabledChange";
+ public static final String STATE_SCROLL_ENABLED = "scrollEnabled";
+ public static final String STATE_SCROLL_ENABLED_CHANGE = "scrollEnabledChange";
+ public static final String STATE_ROTATE_ENABLED = "rotateEnabled";
+ public static final String STATE_ROTATE_ENABLED_CHANGE = "rotateEnabledChange";
+ public static final String STATE_TILT_ENABLED = "tiltEnabled";
+ public static final String STATE_TILT_ENABLED_CHANGE = "tiltEnabledChange";
+ public static final String STATE_ZOOM_CONTROLS_ENABLED = "zoomControlsEnabled";
+ public static final String STATE_DEBUG_ACTIVE = "debugActive";
+ public static final String STATE_STYLE_URL = "styleUrl";
+ public static final String STATE_MY_LOCATION_ENABLED = "myLocationEnabled";
+ public static final String STATE_MY_LOCATION_TRACKING_MODE = "myLocationTracking";
+ public static final String STATE_MY_BEARING_TRACKING_MODE = "myBearingTracking";
+ public static final String STATE_MY_LOCATION_TRACKING_DISMISS = "myLocationTrackingDismiss";
+ public static final String STATE_MY_BEARING_TRACKING_DISMISS = "myBearingTrackingDismiss";
+ public static final String STATE_COMPASS_ENABLED = "compassEnabled";
+ public static final String STATE_COMPASS_GRAVITY = "compassGravity";
+ public static final String STATE_COMPASS_MARGIN_LEFT = "compassMarginLeft";
+ public static final String STATE_COMPASS_MARGIN_TOP = "compassMarginTop";
+ public static final String STATE_COMPASS_MARGIN_RIGHT = "compassMarginRight";
+ public static final String STATE_COMPASS_MARGIN_BOTTOM = "compassMarginBottom";
+ public static final String STATE_COMPASS_FADE_WHEN_FACING_NORTH = "compassFade";
+ public static final String STATE_LOGO_GRAVITY = "logoGravity";
+ public static final String STATE_LOGO_MARGIN_LEFT = "logoMarginLeft";
+ public static final String STATE_LOGO_MARGIN_TOP = "logoMarginTop";
+ public static final String STATE_LOGO_MARGIN_RIGHT = "logoMarginRight";
+ public static final String STATE_LOGO_MARGIN_BOTTOM = "logoMarginBottom";
+ public static final String STATE_LOGO_ENABLED = "logoEnabled";
+ public static final String STATE_ATTRIBUTION_GRAVITY = "attrGravity";
+ public static final String STATE_ATTRIBUTION_MARGIN_LEFT = "attrMarginLeft";
+ public static final String STATE_ATTRIBUTION_MARGIN_TOP = "attrMarginTop";
+ public static final String STATE_ATTRIBUTION_MARGIN_RIGHT = "attrMarginRight";
+ public static final String STATE_ATTRIBUTION_MARGIN_BOTTOM = "atrrMarginBottom";
+ public static final String STATE_ATTRIBUTION_ENABLED = "atrrEnabled";
+
+ public static final String MAPBOX_SHARED_PREFERENCES_FILE = "MapboxSharedPreferences";
+ public static final String MAPBOX_SHARED_PREFERENCE_KEY_VENDORID = "mapboxVendorId";
+ public static final String MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_ENABLED = "mapboxTelemetryEnabled";
+ public static final String MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_STAGING_URL = "mapboxTelemetryStagingUrl";
+ public static final String MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_STAGING_ACCESS_TOKEN =
+ "mapboxTelemetryStagingAccessToken";
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyBearingTracking.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyBearingTracking.java
index 929df2da77..cba2fb282c 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyBearingTracking.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyBearingTracking.java
@@ -2,7 +2,6 @@ package com.mapbox.mapboxsdk.constants;
import android.support.annotation.IntDef;
-import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.widgets.MyLocationView;
import java.lang.annotation.Retention;
@@ -11,34 +10,34 @@ import java.lang.annotation.RetentionPolicy;
/**
* MyBearingTracking exposes different types bearing tracking modes.
*
- * @see MapView#setMyBearingTrackingMode(int)
+ * @see com.mapbox.mapboxsdk.maps.TrackingSettings#setMyBearingTrackingMode(int)
* @see MyLocationView#setMyBearingTrackingMode(int)
*/
public class MyBearingTracking {
- /**
- * Indicates the parameter accepts one of the values from {@link MyBearingTracking}.
- */
- @IntDef({NONE, COMPASS, GPS, /**COMBINED**/})
- @Retention(RetentionPolicy.SOURCE)
- public @interface Mode {
- }
-
- /**
- * Bearing tracking is disabled
- */
- public static final int NONE = 0x00000000;
-
- /**
- * Tracking the bearing of the user based on sensor data
- */
- public static final int COMPASS = 0x00000004;
-
- /**
- * Tracking the bearing of the user based on GPS data
- */
- public static final int GPS = 0x00000008;
-
- //public static final int COMBINED = 0x00000012;
+ /**
+ * Indicates the parameter accepts one of the values from {@link MyBearingTracking}.
+ */
+ @IntDef( {NONE, COMPASS, GPS, /**COMBINED**/})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Mode {
+ }
+
+ /**
+ * Bearing tracking is disabled
+ */
+ public static final int NONE = 0x00000000;
+
+ /**
+ * Tracking the bearing of the user based on sensor data
+ */
+ public static final int COMPASS = 0x00000004;
+
+ /**
+ * Tracking the bearing of the user based on GPS data
+ */
+ public static final int GPS = 0x00000008;
+
+ //public static final int COMBINED = 0x00000012;
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyLocationTracking.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyLocationTracking.java
index b2a49c6454..d1eaac04de 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyLocationTracking.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyLocationTracking.java
@@ -11,27 +11,27 @@ import java.lang.annotation.RetentionPolicy;
/**
* MyLocationTracking exposes different types of locational tracking modes.
*
- * @see MapView#setMyLocationTrackingMode(int)
+ * @see com.mapbox.mapboxsdk.maps.TrackingSettings#setMyLocationTrackingMode(int)
* @see MyLocationView#setMyLocationTrackingMode(int)
*/
public class MyLocationTracking {
- /**
- * Indicates the parameter accepts one of the values from {@link MyLocationTracking}.
- */
- @IntDef({TRACKING_NONE, TRACKING_FOLLOW})
- @Retention(RetentionPolicy.SOURCE)
- public @interface Mode {
- }
-
- /**
- * Location tracking is disabled.
- */
- public static final int TRACKING_NONE = 0x00000000;
-
- /**
- * Tracking the location of the user, {@link MapView} will reposition to center of {@link MyLocationView}
- */
- public static final int TRACKING_FOLLOW = 0x00000004;
+ /**
+ * Indicates the parameter accepts one of the values from {@link MyLocationTracking}.
+ */
+ @IntDef( {TRACKING_NONE, TRACKING_FOLLOW})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Mode {
+ }
+
+ /**
+ * Location tracking is disabled.
+ */
+ public static final int TRACKING_NONE = 0x00000000;
+
+ /**
+ * Tracking the location of the user, {@link MapView} will reposition to center of {@link MyLocationView}
+ */
+ public static final int TRACKING_FOLLOW = 0x00000004;
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/Style.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/Style.java
index 51eb038052..574ef4afa6 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/Style.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/Style.java
@@ -18,61 +18,61 @@ import java.lang.annotation.RetentionPolicy;
public class Style {
- /**
- * Indicates the parameter accepts one of the values from {@link Style}. Using one of these
- * constants means your map style will always use the latest version and may change as we
- * improve the style
- */
- @StringDef({MAPBOX_STREETS, OUTDOORS, EMERALD, LIGHT, DARK, SATELLITE, SATELLITE_STREETS})
- @Retention(RetentionPolicy.SOURCE)
- public @interface StyleUrl {
- }
+ /**
+ * Indicates the parameter accepts one of the values from {@link Style}. Using one of these
+ * constants means your map style will always use the latest version and may change as we
+ * improve the style
+ */
+ @StringDef( {MAPBOX_STREETS, OUTDOORS, EMERALD, LIGHT, DARK, SATELLITE, SATELLITE_STREETS})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface StyleUrl {
+ }
- // IMPORTANT: If you change any of these you also need to edit them in strings.xml
+ // IMPORTANT: If you change any of these you also need to edit them in strings.xml
- /**
- * Mapbox Streets: A complete basemap, perfect for incorporating your own data. Using this
- * constant means your map style will always use the latest version and may change as we
- * improve the style.
- */
- public static final String MAPBOX_STREETS = "mapbox://styles/mapbox/streets-v9";
+ /**
+ * Mapbox Streets: A complete basemap, perfect for incorporating your own data. Using this
+ * constant means your map style will always use the latest version and may change as we
+ * improve the style.
+ */
+ public static final String MAPBOX_STREETS = "mapbox://styles/mapbox/streets-v9";
- /**
- * Outdoors: A general-purpose style tailored to outdoor activities. Using this constant means
- * your map style will always use the latest version and may change as we improve the style.
- */
- public static final String OUTDOORS = "mapbox://styles/mapbox/outdoors-v9";
+ /**
+ * Outdoors: A general-purpose style tailored to outdoor activities. Using this constant means
+ * your map style will always use the latest version and may change as we improve the style.
+ */
+ public static final String OUTDOORS = "mapbox://styles/mapbox/outdoors-v9";
- /**
- * Emerald: A versatile style, with emphasis on road networks and public transit.
- *
- * @deprecated this style has been deprecated and will be removed in future versions.
- */
- @Deprecated
- public static final String EMERALD = "mapbox://styles/mapbox/emerald-v8";
+ /**
+ * Emerald: A versatile style, with emphasis on road networks and public transit.
+ *
+ * @deprecated this style has been deprecated and will be removed in future versions.
+ */
+ @Deprecated
+ public static final String EMERALD = "mapbox://styles/mapbox/emerald-v8";
- /**
- * Light: Subtle light backdrop for data visualizations. Using this constant means your map
- * style will always use the latest version and may change as we improve the style.
- */
- public static final String LIGHT = "mapbox://styles/mapbox/light-v9";
+ /**
+ * Light: Subtle light backdrop for data visualizations. Using this constant means your map
+ * style will always use the latest version and may change as we improve the style.
+ */
+ public static final String LIGHT = "mapbox://styles/mapbox/light-v9";
- /**
- * Dark: Subtle dark backdrop for data visualizations. Using this constant means your map style
- * will always use the latest version and may change as we improve the style.
- */
- public static final String DARK = "mapbox://styles/mapbox/dark-v9";
+ /**
+ * Dark: Subtle dark backdrop for data visualizations. Using this constant means your map style
+ * will always use the latest version and may change as we improve the style.
+ */
+ public static final String DARK = "mapbox://styles/mapbox/dark-v9";
- /**
- * Satellite: A beautiful global satellite and aerial imagery layer. Using this constant means
- * your map style will always use the latest version and may change as we improve the style.
- */
- public static final String SATELLITE = "mapbox://styles/mapbox/satellite-v9";
+ /**
+ * Satellite: A beautiful global satellite and aerial imagery layer. Using this constant means
+ * your map style will always use the latest version and may change as we improve the style.
+ */
+ public static final String SATELLITE = "mapbox://styles/mapbox/satellite-v9";
- /**
- * Satellite Streets: Global satellite and aerial imagery with unobtrusive labels. Using this
- * constant means your map style will always use the latest version and may change as we
- * improve the style.
- */
- public static final String SATELLITE_STREETS = "mapbox://styles/mapbox/satellite-streets-v9";
+ /**
+ * Satellite Streets: Global satellite and aerial imagery with unobtrusive labels. Using this
+ * constant means your map style will always use the latest version and may change as we
+ * improve the style.
+ */
+ public static final String SATELLITE_STREETS = "mapbox://styles/mapbox/satellite-streets-v9";
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/ConversionException.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/ConversionException.java
index 87656db2a9..be2b586683 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/ConversionException.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/ConversionException.java
@@ -5,18 +5,18 @@ package com.mapbox.mapboxsdk.exceptions;
*/
public class ConversionException extends RuntimeException {
- public ConversionException() {
- }
+ public ConversionException() {
+ }
- public ConversionException(String detailMessage) {
- super(detailMessage);
- }
+ public ConversionException(String detailMessage) {
+ super(detailMessage);
+ }
- public ConversionException(String detailMessage, Throwable throwable) {
- super(detailMessage, throwable);
- }
+ public ConversionException(String detailMessage, Throwable throwable) {
+ super(detailMessage, throwable);
+ }
- public ConversionException(Throwable throwable) {
- super(throwable);
- }
+ public ConversionException(Throwable throwable) {
+ super(throwable);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/IconBitmapChangedException.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/IconBitmapChangedException.java
index 1be82d6178..7154049bd7 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/IconBitmapChangedException.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/IconBitmapChangedException.java
@@ -19,9 +19,9 @@ import com.mapbox.mapboxsdk.maps.MapView;
*/
public class IconBitmapChangedException extends RuntimeException {
- public IconBitmapChangedException() {
- super("The added Marker has an Icon with a bitmap that has been modified. An Icon cannot be modified" +
- "after it has been added to the map in a Marker.");
- }
+ public IconBitmapChangedException() {
+ super("The added Marker has an Icon with a bitmap that has been modified. An Icon cannot be modified"
+ + "after it has been added to the map in a Marker.");
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/InvalidAccessTokenException.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/InvalidAccessTokenException.java
index 77797ecb4f..95851fc1d2 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/InvalidAccessTokenException.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/InvalidAccessTokenException.java
@@ -1,22 +1,24 @@
package com.mapbox.mapboxsdk.exceptions;
+import android.content.Context;
import android.os.Bundle;
import com.mapbox.mapboxsdk.maps.MapView;
/**
- * A {@code InvalidAccessTokenException} is thrown by {@link com.mapbox.mapboxsdk.maps.MapboxMap} when there is either no access
- * token set before {@link MapView#onCreate(Bundle)} or an invalid access token is set in {@link MapView#setAccessToken(String)}
+ * A {@code InvalidAccessTokenException} is thrown by {@link com.mapbox.mapboxsdk.maps.MapboxMap}
+ * when there is either no access token set before {@link MapView#onCreate(Bundle)} or an invalid access token
+ * is set in {@link com.mapbox.mapboxsdk.Mapbox#getInstance(Context, String)}
*
* @see MapView#onCreate(Bundle)
- * @see MapView#setAccessToken(String)
+ * @see com.mapbox.mapboxsdk.Mapbox#getInstance(Context, String)
*/
public class InvalidAccessTokenException extends RuntimeException {
- public InvalidAccessTokenException() {
- super("\nUsing MapView requires setting a valid access token. Use setAccessToken on Mapview to provide one. " +
- "\nPlease see https://www.mapbox.com/help/create-api-access-token/ to learn how to create one." +
- "\nMore information in this guide https://www.mapbox.com/help/first-steps-android-sdk/#access-tokens.");
- }
-
+ public InvalidAccessTokenException() {
+ super("\nUsing MapView requires setting a valid access token. Use Mapbox.getInstance(Context context, "
+ + "String accessToken) to provide one. "
+ + "\nPlease see https://www.mapbox.com/help/create-api-access-token/ to learn how to create one."
+ + "\nMore information in this guide https://www.mapbox.com/help/first-steps-android-sdk/#access-tokens.");
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/InvalidLatLngBoundsException.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/InvalidLatLngBoundsException.java
index 92feaac64b..08a23a7373 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/InvalidLatLngBoundsException.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/InvalidLatLngBoundsException.java
@@ -6,7 +6,7 @@ package com.mapbox.mapboxsdk.exceptions;
*/
public class InvalidLatLngBoundsException extends RuntimeException {
- public InvalidLatLngBoundsException(int latLngsListSize) {
- super("Cannot create a LatLngBounds from " + latLngsListSize + " items");
- }
+ public InvalidLatLngBoundsException(int latLngsListSize) {
+ super("Cannot create a LatLngBounds from " + latLngsListSize + " items");
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/InvalidMarkerPositionException.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/InvalidMarkerPositionException.java
index 8dc98118b1..e5a647841f 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/InvalidMarkerPositionException.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/InvalidMarkerPositionException.java
@@ -2,9 +2,9 @@ package com.mapbox.mapboxsdk.exceptions;
public class InvalidMarkerPositionException extends RuntimeException {
- public InvalidMarkerPositionException() {
- super("Adding an invalid Marker to a Map. " +
- "Missing the required position field. " +
- "Provide a non null LatLng as position to the Marker.");
- }
+ public InvalidMarkerPositionException() {
+ super("Adding an invalid Marker to a Map. "
+ + "Missing the required position field. "
+ + "Provide a non null LatLng as position to the Marker.");
+ }
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/MapboxAccountManagerNotStartedException.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/MapboxAccountManagerNotStartedException.java
deleted file mode 100644
index 4954098f15..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/MapboxAccountManagerNotStartedException.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.mapbox.mapboxsdk.exceptions;
-
-
-import android.content.Context;
-import android.os.Bundle;
-
-import com.mapbox.mapboxsdk.MapboxAccountManager;
-import com.mapbox.mapboxsdk.maps.MapView;
-
-/**
- * A MapboxAccountManagerNotStartedException is thrown by {@link com.mapbox.mapboxsdk.maps.MapView}
- * when {@link MapboxAccountManager} is not started before {@link MapView#onCreate(Bundle)}.
- *
- * @see MapView#onCreate(Bundle)
- * @see MapboxAccountManager#start(Context, String)
- */
-public class MapboxAccountManagerNotStartedException extends RuntimeException {
-
- public MapboxAccountManagerNotStartedException() {
- super("\nMapboxAccountManager was not started correctly. Use MapboxAccountManager#start(Context, String) to initialise. " +
- "\nMore information in this guide https://www.mapbox.com/help/first-steps-android-sdk/#access-tokens.");
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/TelemetryServiceNotConfiguredException.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/TelemetryServiceNotConfiguredException.java
index ec2b0d792d..e2e114fa77 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/TelemetryServiceNotConfiguredException.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/TelemetryServiceNotConfiguredException.java
@@ -12,10 +12,11 @@ import com.mapbox.mapboxsdk.maps.MapView;
*/
public class TelemetryServiceNotConfiguredException extends RuntimeException {
- public TelemetryServiceNotConfiguredException() {
- super("\nTelemetryService is not configured in your applications AndroidManifest.xml. " +
- "\nPlease add \"com.mapbox.mapboxsdk.telemetry.TelemetryService\" service in your applications AndroidManifest.xml" +
- "\nFor an example visit http://goo.gl/cET0Jn. For more information visit https://www.mapbox.com/android-sdk/.");
- }
+ public TelemetryServiceNotConfiguredException() {
+ super("\nTelemetryService is not configured in your applications AndroidManifest.xml. "
+ + "\nPlease add \"com.mapbox.mapboxsdk.telemetry.TelemetryService\" service in your applications "
+ + "AndroidManifest.xml"
+ + "\nFor an example visit http://goo.gl/cET0Jn. For more information visit https://www.mapbox.com/android-sdk/.");
+ }
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/TooManyIconsException.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/TooManyIconsException.java
index 4dcdea112c..8923d822f2 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/TooManyIconsException.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/TooManyIconsException.java
@@ -14,8 +14,8 @@ import com.mapbox.mapboxsdk.annotations.IconFactory;
*/
public class TooManyIconsException extends RuntimeException {
- public TooManyIconsException() {
- super("Cannot create an Icon because there are already too many. Try reusing Icon objects whenever possible.");
- }
+ public TooManyIconsException() {
+ super("Cannot create an Icon because there are already too many. Try reusing Icon objects whenever possible.");
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ILatLng.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ILatLng.java
index afd22e5ddb..1af8e7cfc7 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ILatLng.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ILatLng.java
@@ -4,9 +4,9 @@ package com.mapbox.mapboxsdk.geometry;
* Describes a latitude, longitude point.
*/
public interface ILatLng {
- double getLatitude();
+ double getLatitude();
- double getLongitude();
+ double getLongitude();
- double getAltitude();
+ double getAltitude();
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/IProjectedMeters.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/IProjectedMeters.java
index 43fe25f8e5..694c935143 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/IProjectedMeters.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/IProjectedMeters.java
@@ -4,7 +4,7 @@ package com.mapbox.mapboxsdk.geometry;
* Describes a projection in Mercator meters.
*/
public interface IProjectedMeters {
- double getNorthing();
+ double getNorthing();
- double getEasting();
+ double getEasting();
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java
index 4449a7fe0d..b18b7e87b0 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java
@@ -21,183 +21,191 @@ import com.mapbox.mapboxsdk.utils.MathUtils;
*/
public class LatLng implements ILatLng, Parcelable {
- public static final Parcelable.Creator<LatLng> CREATOR = new Parcelable.Creator<LatLng>() {
- public LatLng createFromParcel(Parcel in) {
- return new LatLng(in);
- }
-
- public LatLng[] newArray(int size) {
- return new LatLng[size];
- }
- };
-
- private double latitude;
- private double longitude;
- private double altitude = 0.0;
-
- /**
- * Construct a new latitude, longitude point at (0, 0)
- */
- public LatLng() {
- this.latitude = 0.0;
- this.longitude = 0.0;
- }
-
- /**
- * Construct a new latitude, longitude point given float arguments
- * @param latitude Latitude in degrees
- * @param longitude Longitude in degrees
- */
- public LatLng(double latitude, double longitude) {
- this.latitude = latitude;
- this.longitude = longitude;
- }
-
- /**
- * Construct a new latitude, longitude, altitude point given float arguments
- * @param latitude Latitude in degrees
- * @param longitude Longitude in degress
- * @param altitude Altitude in meters
- */
- public LatLng(double latitude, double longitude, double altitude) {
- this.latitude = latitude;
- this.longitude = longitude;
- this.altitude = altitude;
- }
-
- /**
- * Transform a Location into a LatLng point
- * @param location Android Location
- */
- public LatLng(Location location) {
- this(location.getLatitude(), location.getLongitude(), location.getAltitude());
- }
-
- /**
- * Clone an existing latitude longitude point
- * @param aLatLng LatLng
- */
- public LatLng(LatLng aLatLng) {
- this.latitude = aLatLng.latitude;
- this.longitude = aLatLng.longitude;
- this.altitude = aLatLng.altitude;
- }
-
- protected LatLng(Parcel in) {
- latitude = in.readDouble();
- longitude = in.readDouble();
- altitude = in.readDouble();
- }
-
- public void setLatitude(double latitude) {
- this.latitude = latitude;
- }
-
- @Override
- public double getLatitude() {
- return latitude;
- }
-
- public void setLongitude(double longitude) {
- this.longitude = longitude;
- }
-
- @Override
- public double getLongitude() {
- return longitude;
- }
-
- public void setAltitude(double altitude) {
- this.altitude = altitude;
- }
-
- @Override
- public double getAltitude() {
- return altitude;
- }
-
- /**
- * Return a new LatLng object with a wrapped Longitude. This allows original data object
- * to remain unchanged.
- * @return New LatLng object with wrapped Longitude
- */
- public LatLng wrap(){
- LatLng wrappedVersion = new LatLng(this);
- double lon = wrappedVersion.getLongitude();
- if (lon < GeoConstants.MIN_LONGITUDE || lon > GeoConstants.MAX_LONGITUDE) {
- wrappedVersion.setLongitude(MathUtils.wrap(wrappedVersion.getLongitude(), GeoConstants.MIN_LONGITUDE, GeoConstants.MAX_LONGITUDE));
- }
- return wrappedVersion;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
-
- LatLng latLng = (LatLng) o;
-
- return Double.compare(latLng.altitude, altitude) == 0 && Double.compare(latLng.latitude, latitude) == 0 && Double.compare(latLng.longitude, longitude) == 0;
- }
-
- @Override
- public int hashCode() {
- int result;
- long temp;
- temp = Double.doubleToLongBits(latitude);
- result = (int) (temp ^ (temp >>> 32));
- temp = Double.doubleToLongBits(longitude);
- result = 31 * result + (int) (temp ^ (temp >>> 32));
- temp = Double.doubleToLongBits(altitude);
- result = 31 * result + (int) (temp ^ (temp >>> 32));
- return result;
- }
-
- @Override
- public String toString() {
- return "LatLng [latitude=" + latitude + ", longitude=" + longitude + ", altitude=" + altitude + "]";
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeDouble(latitude);
- out.writeDouble(longitude);
- out.writeDouble(altitude);
- }
-
- /**
- * Calculate distance between two points
- * @param other Other LatLng to compare to
- * @return distance in meters
- */
- public double distanceTo(LatLng other) {
- if(latitude == other.latitude && longitude == other.longitude){
- // return 0.0 to avoid a NaN
- return 0.0;
- }
-
- final double a1 = Math.toRadians(this.latitude);
- final double a2 = Math.toRadians(this.longitude);
- final double b1 = Math.toRadians(other.getLatitude());
- final double b2 = Math.toRadians(other.getLongitude());
-
- final double cosa1 = Math.cos(a1);
- final double cosb1 = Math.cos(b1);
-
- final double t1 = cosa1 * Math.cos(a2) * cosb1 * Math.cos(b2);
- final double t2 = cosa1 * Math.sin(a2) * cosb1 * Math.sin(b2);
- final double t3 = Math.sin(a1) * Math.sin(b1);
- final double tt = Math.acos(t1 + t2 + t3);
-
- return GeoConstants.RADIUS_EARTH_METERS * tt;
- }
+ public static final Parcelable.Creator<LatLng> CREATOR = new Parcelable.Creator<LatLng>() {
+ public LatLng createFromParcel(Parcel in) {
+ return new LatLng(in);
+ }
+
+ public LatLng[] newArray(int size) {
+ return new LatLng[size];
+ }
+ };
+
+ private double latitude;
+ private double longitude;
+ private double altitude = 0.0;
+
+ /**
+ * Construct a new latitude, longitude point at (0, 0)
+ */
+ public LatLng() {
+ this.latitude = 0.0;
+ this.longitude = 0.0;
+ }
+
+ /**
+ * Construct a new latitude, longitude point given float arguments
+ *
+ * @param latitude Latitude in degrees
+ * @param longitude Longitude in degrees
+ */
+ public LatLng(double latitude, double longitude) {
+ this.latitude = latitude;
+ this.longitude = longitude;
+ }
+
+ /**
+ * Construct a new latitude, longitude, altitude point given float arguments
+ *
+ * @param latitude Latitude in degrees
+ * @param longitude Longitude in degress
+ * @param altitude Altitude in meters
+ */
+ public LatLng(double latitude, double longitude, double altitude) {
+ this.latitude = latitude;
+ this.longitude = longitude;
+ this.altitude = altitude;
+ }
+
+ /**
+ * Transform a Location into a LatLng point
+ *
+ * @param location Android Location
+ */
+ public LatLng(Location location) {
+ this(location.getLatitude(), location.getLongitude(), location.getAltitude());
+ }
+
+ /**
+ * Clone an existing latitude longitude point
+ *
+ * @param aLatLng LatLng
+ */
+ public LatLng(LatLng aLatLng) {
+ this.latitude = aLatLng.latitude;
+ this.longitude = aLatLng.longitude;
+ this.altitude = aLatLng.altitude;
+ }
+
+ protected LatLng(Parcel in) {
+ latitude = in.readDouble();
+ longitude = in.readDouble();
+ altitude = in.readDouble();
+ }
+
+ public void setLatitude(double latitude) {
+ this.latitude = latitude;
+ }
+
+ @Override
+ public double getLatitude() {
+ return latitude;
+ }
+
+ public void setLongitude(double longitude) {
+ this.longitude = longitude;
+ }
+
+ @Override
+ public double getLongitude() {
+ return longitude;
+ }
+
+ public void setAltitude(double altitude) {
+ this.altitude = altitude;
+ }
+
+ @Override
+ public double getAltitude() {
+ return altitude;
+ }
+
+ /**
+ * Return a new LatLng object with a wrapped Longitude. This allows original data object
+ * to remain unchanged.
+ *
+ * @return New LatLng object with wrapped Longitude
+ */
+ public LatLng wrap() {
+ LatLng wrappedVersion = new LatLng(this);
+ double lon = wrappedVersion.getLongitude();
+ if (lon < GeoConstants.MIN_LONGITUDE || lon > GeoConstants.MAX_LONGITUDE) {
+ wrappedVersion.setLongitude(MathUtils.wrap(wrappedVersion.getLongitude(), GeoConstants.MIN_LONGITUDE,
+ GeoConstants.MAX_LONGITUDE));
+ }
+ return wrappedVersion;
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (object == null || getClass() != object.getClass()) {
+ return false;
+ }
+
+ LatLng latLng = (LatLng) object;
+
+ return Double.compare(latLng.altitude, altitude) == 0 && Double.compare(latLng.latitude, latitude) == 0
+ && Double.compare(latLng.longitude, longitude) == 0;
+ }
+
+ @Override
+ public int hashCode() {
+ int result;
+ long temp;
+ temp = Double.doubleToLongBits(latitude);
+ result = (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(longitude);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(altitude);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "LatLng [latitude=" + latitude + ", longitude=" + longitude + ", altitude=" + altitude + "]";
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeDouble(latitude);
+ out.writeDouble(longitude);
+ out.writeDouble(altitude);
+ }
+
+ /**
+ * Calculate distance between two points
+ *
+ * @param other Other LatLng to compare to
+ * @return distance in meters
+ */
+ public double distanceTo(LatLng other) {
+ if (latitude == other.latitude && longitude == other.longitude) {
+ // return 0.0 to avoid a NaN
+ return 0.0;
+ }
+
+ final double a1 = Math.toRadians(this.latitude);
+ final double a2 = Math.toRadians(this.longitude);
+ final double b1 = Math.toRadians(other.getLatitude());
+ final double b2 = Math.toRadians(other.getLongitude());
+
+ final double cosa1 = Math.cos(a1);
+ final double cosb1 = Math.cos(b1);
+
+ final double t1 = cosa1 * Math.cos(a2) * cosb1 * Math.cos(b2);
+ final double t2 = cosa1 * Math.sin(a2) * cosb1 * Math.sin(b2);
+ final double t3 = Math.sin(a1) * Math.sin(b1);
+ final double tt = Math.acos(t1 + t2 + t3);
+
+ return GeoConstants.RADIUS_EARTH_METERS * tt;
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngBounds.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngBounds.java
index 2fd28202af..3b92f0f0f5 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngBounds.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngBounds.java
@@ -14,292 +14,296 @@ import java.util.List;
*/
public class LatLngBounds implements Parcelable {
- private final double mLatNorth;
- private final double mLatSouth;
- private final double mLonEast;
- private final double mLonWest;
-
- /**
- * Construct a new LatLngBounds based on its corners, given in NESW
- * order.
- *
- * @param northLatitude Northern Latitude
- * @param eastLongitude Eastern Longitude
- * @param southLatitude Southern Latitude
- * @param westLongitude Western Longitude
- */
- LatLngBounds(final double northLatitude, final double eastLongitude, final double southLatitude, final double westLongitude) {
- this.mLatNorth = northLatitude;
- this.mLonEast = eastLongitude;
- this.mLatSouth = southLatitude;
- this.mLonWest = westLongitude;
+ private final double mLatNorth;
+ private final double mLatSouth;
+ private final double mLonEast;
+ private final double mLonWest;
+
+ /**
+ * Construct a new LatLngBounds based on its corners, given in NESW
+ * order.
+ *
+ * @param northLatitude Northern Latitude
+ * @param eastLongitude Eastern Longitude
+ * @param southLatitude Southern Latitude
+ * @param westLongitude Western Longitude
+ */
+ LatLngBounds(final double northLatitude, final double eastLongitude, final double southLatitude,
+ final double westLongitude) {
+ this.mLatNorth = northLatitude;
+ this.mLonEast = eastLongitude;
+ this.mLatSouth = southLatitude;
+ this.mLonWest = westLongitude;
+ }
+
+ /**
+ * Calculates the centerpoint of this LatLngBounds by simple interpolation and returns
+ * it as a point. This is a non-geodesic calculation which is not the geographic center.
+ *
+ * @return LatLng center of this LatLngBounds
+ */
+ public LatLng getCenter() {
+ return new LatLng((this.mLatNorth + this.mLatSouth) / 2,
+ (this.mLonEast + this.mLonWest) / 2);
+ }
+
+ public double getLatNorth() {
+ return this.mLatNorth;
+ }
+
+ public double getLatSouth() {
+ return this.mLatSouth;
+ }
+
+ public double getLonEast() {
+ return this.mLonEast;
+ }
+
+ public double getLonWest() {
+ return this.mLonWest;
+ }
+
+ /**
+ * Get the area spanned by this LatLngBounds
+ *
+ * @return LatLngSpan area
+ */
+ public LatLngSpan getSpan() {
+ return new LatLngSpan(getLatitudeSpan(), getLongitudeSpan());
+ }
+
+ /**
+ * Get the absolute distance, in degrees, between the north and
+ * south boundaries of this LatLngBounds
+ *
+ * @return Span distance
+ */
+ public double getLatitudeSpan() {
+ return Math.abs(this.mLatNorth - this.mLatSouth);
+ }
+
+ /**
+ * Get the absolute distance, in degrees, between the west and
+ * east boundaries of this LatLngBounds
+ *
+ * @return Span distance
+ */
+ public double getLongitudeSpan() {
+ return Math.abs(this.mLonEast - this.mLonWest);
+ }
+
+
+ /**
+ * Validate if LatLngBounds is empty, determined if absolute distance is
+ *
+ * @return boolean indicating if span is empty
+ */
+ public boolean isEmptySpan() {
+ return getLongitudeSpan() == 0.0 || getLatitudeSpan() == 0.0;
+ }
+
+ @Override
+ public String toString() {
+ return "N:" + this.mLatNorth + "; E:" + this.mLonEast + "; S:" + this.mLatSouth + "; W:" + this.mLonWest;
+ }
+
+ /**
+ * Constructs a LatLngBounds that contains all of a list of LatLng
+ * objects. Empty lists will yield invalid LatLngBounds.
+ *
+ * @param latLngs List of LatLng objects
+ * @return LatLngBounds
+ */
+ static LatLngBounds fromLatLngs(final List<? extends ILatLng> latLngs) {
+ double minLat = 90;
+ double minLon = 180;
+ double maxLat = -90;
+ double maxLon = -180;
+
+ for (final ILatLng gp : latLngs) {
+ final double latitude = gp.getLatitude();
+ final double longitude = gp.getLongitude();
+
+ minLat = Math.min(minLat, latitude);
+ minLon = Math.min(minLon, longitude);
+ maxLat = Math.max(maxLat, latitude);
+ maxLon = Math.max(maxLon, longitude);
}
- /**
- * Calculates the centerpoint of this LatLngBounds by simple interpolation and returns
- * it as a point. This is a non-geodesic calculation which is not the geographic center.
- *
- * @return LatLng center of this LatLngBounds
- */
- public LatLng getCenter() {
- return new LatLng((this.mLatNorth + this.mLatSouth) / 2,
- (this.mLonEast + this.mLonWest) / 2);
+ return new LatLngBounds(maxLat, maxLon, minLat, minLon);
+ }
+
+ public LatLng[] toLatLngs() {
+ return new LatLng[] {new LatLng(mLatNorth, mLonEast), new LatLng(mLatSouth, mLonWest)};
+ }
+
+ /**
+ * Determines whether this LatLngBounds matches another one via LatLng.
+ *
+ * @param o another object
+ * @return a boolean indicating whether the LatLngBounds are equal
+ */
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
}
-
- public double getLatNorth() {
- return this.mLatNorth;
- }
-
- public double getLatSouth() {
- return this.mLatSouth;
- }
-
- public double getLonEast() {
- return this.mLonEast;
- }
-
- public double getLonWest() {
- return this.mLonWest;
- }
-
- /**
- * Get the area spanned by this LatLngBounds
- *
- * @return LatLngSpan area
- */
- public LatLngSpan getSpan() {
- return new LatLngSpan(getLatitudeSpan(), getLongitudeSpan());
- }
-
- /**
- * Get the absolute distance, in degrees, between the north and
- * south boundaries of this LatLngBounds
- *
- * @return Span distance
- */
- public double getLatitudeSpan() {
- return Math.abs(this.mLatNorth - this.mLatSouth);
- }
-
- /**
- * Get the absolute distance, in degrees, between the west and
- * east boundaries of this LatLngBounds
- *
- * @return Span distance
- */
- public double getLongitudeSpan() {
- return Math.abs(this.mLonEast - this.mLonWest);
- }
-
-
- /**
- * Validate if LatLngBounds is empty, determined if absolute distance is
- *
- * @return boolean indicating if span is empty
- */
- public boolean isEmptySpan() {
- return getLongitudeSpan() == 0.0 || getLatitudeSpan() == 0.0;
- }
-
- @Override
- public String toString() {
- return "N:" + this.mLatNorth + "; E:" + this.mLonEast + "; S:" + this.mLatSouth + "; W:" + this.mLonWest;
+ if (o instanceof LatLngBounds) {
+ LatLngBounds other = (LatLngBounds) o;
+ return mLatNorth == other.getLatNorth()
+ && mLatSouth == other.getLatSouth()
+ && mLonEast == other.getLonEast()
+ && mLonWest == other.getLonWest();
}
-
- /**
- * Constructs a LatLngBounds that contains all of a list of LatLng
- * objects. Empty lists will yield invalid LatLngBounds.
- *
- * @param latLngs List of LatLng objects
- * @return LatLngBounds
- */
- static LatLngBounds fromLatLngs(final List<? extends ILatLng> latLngs) {
- double minLat = 90,
- minLon = 180,
- maxLat = -90,
- maxLon = -180;
-
- for (final ILatLng gp : latLngs) {
- final double latitude = gp.getLatitude();
- final double longitude = gp.getLongitude();
-
- minLat = Math.min(minLat, latitude);
- minLon = Math.min(minLon, longitude);
- maxLat = Math.max(maxLat, latitude);
- maxLon = Math.max(maxLon, longitude);
- }
-
- return new LatLngBounds(maxLat, maxLon, minLat, minLon);
- }
-
- public LatLng[] toLatLngs() {
- return new LatLng[]{new LatLng(mLatNorth, mLonEast), new LatLng(mLatSouth, mLonWest)};
- }
-
- /**
- * Determines whether this LatLngBounds matches another one via LatLng.
- *
- * @param o another object
- * @return a boolean indicating whether the LatLngBounds are equal
- */
- @Override
- public boolean equals(final Object o) {
- if (this == o) return true;
- if (o instanceof LatLngBounds) {
- LatLngBounds other = (LatLngBounds) o;
- return mLatNorth == other.getLatNorth()
- && mLatSouth == other.getLatSouth()
- && mLonEast == other.getLonEast()
- && mLonWest == other.getLonWest();
- }
- return false;
- }
-
- /**
- * Determines whether this LatLngBounds contains a point and the point
- * does not touch its boundary.
- *
- * @param latLng the point which may be contained
- * @return true, if the point is contained within the box.
- */
- public boolean contains(final ILatLng latLng) {
- final double latitude = latLng.getLatitude();
- final double longitude = latLng.getLongitude();
- return ((latitude < this.mLatNorth)
- && (latitude > this.mLatSouth))
- && ((longitude < this.mLonEast)
- && (longitude > this.mLonWest));
- }
-
- /**
- * Returns a new LatLngBounds that stretches to contain both this and another LatLngBounds.
- *
- * @param bounds LatLngBounds to add
- * @return LatLngBounds
- */
- public LatLngBounds union(LatLngBounds bounds) {
- return union(bounds.getLatNorth(), bounds.getLonEast(), bounds.getLatSouth(), bounds.getLonWest());
+ return false;
+ }
+
+ /**
+ * Determines whether this LatLngBounds contains a point and the point
+ * does not touch its boundary.
+ *
+ * @param latLng the point which may be contained
+ * @return true, if the point is contained within the box.
+ */
+ public boolean contains(final ILatLng latLng) {
+ final double latitude = latLng.getLatitude();
+ final double longitude = latLng.getLongitude();
+ return ((latitude < this.mLatNorth)
+ && (latitude > this.mLatSouth))
+ && ((longitude < this.mLonEast)
+ && (longitude > this.mLonWest));
+ }
+
+ /**
+ * Returns a new LatLngBounds that stretches to contain both this and another LatLngBounds.
+ *
+ * @param bounds LatLngBounds to add
+ * @return LatLngBounds
+ */
+ public LatLngBounds union(LatLngBounds bounds) {
+ return union(bounds.getLatNorth(), bounds.getLonEast(), bounds.getLatSouth(), bounds.getLonWest());
+ }
+
+ /**
+ * Returns a new LatLngBounds that stretches to include another LatLngBounds,
+ * given by corner points.
+ *
+ * @param lonNorth Northern Longitude
+ * @param latEast Eastern Latitude
+ * @param lonSouth Southern Longitude
+ * @param latWest Western Longitude
+ * @return BoundingBox
+ */
+ public LatLngBounds union(final double lonNorth, final double latEast, final double lonSouth, final double latWest) {
+ return new LatLngBounds((this.mLatNorth < lonNorth) ? lonNorth : this.mLatNorth,
+ (this.mLonEast < latEast) ? latEast : this.mLonEast,
+ (this.mLatSouth > lonSouth) ? lonSouth : this.mLatSouth,
+ (this.mLonWest > latWest) ? latWest : this.mLonWest);
+ }
+
+ /**
+ * Returns a new LatLngBounds that is the intersection of this with another box
+ *
+ * @param box LatLngBounds to intersect with
+ * @return LatLngBounds
+ */
+ public LatLngBounds intersect(LatLngBounds box) {
+ double minLatWest = Math.max(getLonWest(), box.getLonWest());
+ double maxLatEast = Math.min(getLonEast(), box.getLonEast());
+ if (maxLatEast > minLatWest) {
+ double minLonSouth = Math.max(getLatSouth(), box.getLatSouth());
+ double maxLonNorth = Math.min(getLatNorth(), box.getLatNorth());
+ if (maxLonNorth > minLonSouth) {
+ return new LatLngBounds(maxLonNorth, maxLatEast, minLonSouth, minLatWest);
+ }
}
-
- /**
- * Returns a new LatLngBounds that stretches to include another LatLngBounds,
- * given by corner points.
- *
- * @param lonNorth Northern Longitude
- * @param latEast Eastern Latitude
- * @param lonSouth Southern Longitude
- * @param latWest Western Longitude
- * @return BoundingBox
- */
- public LatLngBounds union(final double lonNorth, final double latEast, final double lonSouth, final double latWest) {
- return new LatLngBounds((this.mLatNorth < lonNorth) ? lonNorth : this.mLatNorth,
- (this.mLonEast < latEast) ? latEast : this.mLonEast,
- (this.mLatSouth > lonSouth) ? lonSouth : this.mLatSouth,
- (this.mLonWest > latWest) ? latWest : this.mLonWest);
- }
-
- /**
- * Returns a new LatLngBounds that is the intersection of this with another box
- *
- * @param box LatLngBounds to intersect with
- * @return LatLngBounds
- */
- public LatLngBounds intersect(LatLngBounds box) {
- double minLatWest = Math.max(getLonWest(), box.getLonWest());
- double maxLatEast = Math.min(getLonEast(), box.getLonEast());
- if (maxLatEast > minLatWest) {
- double minLonSouth = Math.max(getLatSouth(), box.getLatSouth());
- double maxLonNorth = Math.min(getLatNorth(), box.getLatNorth());
- if (maxLonNorth > minLonSouth) {
- return new LatLngBounds(maxLonNorth, maxLatEast, minLonSouth, minLatWest);
- }
- }
- return null;
- }
-
- /**
- * Returns a new LatLngBounds that is the intersection of this with another LatLngBounds
- *
- * @param northLatitude Northern Longitude
- * @param eastLongitude Eastern Latitude
- * @param southLatitude Southern Longitude
- * @param westLongitude Western Latitude
- * @return LatLngBounds
- */
- public LatLngBounds intersect(double northLatitude, double eastLongitude, double southLatitude, double westLongitude) {
- return intersect(new LatLngBounds(northLatitude, eastLongitude, southLatitude, westLongitude));
- }
-
- public static final Parcelable.Creator<LatLngBounds> CREATOR =
- new Parcelable.Creator<LatLngBounds>() {
- @Override
- public LatLngBounds createFromParcel(final Parcel in) {
- return readFromParcel(in);
- }
-
- @Override
- public LatLngBounds[] newArray(final int size) {
- return new LatLngBounds[size];
- }
- };
-
- @Override
- public int hashCode() {
- return (int) ((mLatNorth + 90)
- + ((mLatSouth + 90) * 1000)
- + ((mLonEast + 180) * 1000000)
- + ((mLonEast + 180) * 1000000000));
- }
-
- @Override
- public int describeContents() {
- return 0;
+ return null;
+ }
+
+ /**
+ * Returns a new LatLngBounds that is the intersection of this with another LatLngBounds
+ *
+ * @param northLatitude Northern Longitude
+ * @param eastLongitude Eastern Latitude
+ * @param southLatitude Southern Longitude
+ * @param westLongitude Western Latitude
+ * @return LatLngBounds
+ */
+ public LatLngBounds intersect(double northLatitude, double eastLongitude, double southLatitude,
+ double westLongitude) {
+ return intersect(new LatLngBounds(northLatitude, eastLongitude, southLatitude, westLongitude));
+ }
+
+ public static final Parcelable.Creator<LatLngBounds> CREATOR =
+ new Parcelable.Creator<LatLngBounds>() {
+ @Override
+ public LatLngBounds createFromParcel(final Parcel in) {
+ return readFromParcel(in);
+ }
+
+ @Override
+ public LatLngBounds[] newArray(final int size) {
+ return new LatLngBounds[size];
+ }
+ };
+
+ @Override
+ public int hashCode() {
+ return (int) ((mLatNorth + 90)
+ + ((mLatSouth + 90) * 1000)
+ + ((mLonEast + 180) * 1000000)
+ + ((mLonEast + 180) * 1000000000));
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(final Parcel out, final int arg1) {
+ out.writeDouble(this.mLatNorth);
+ out.writeDouble(this.mLonEast);
+ out.writeDouble(this.mLatSouth);
+ out.writeDouble(this.mLonWest);
+ }
+
+ private static LatLngBounds readFromParcel(final Parcel in) {
+ final double lonNorth = in.readDouble();
+ final double latEast = in.readDouble();
+ final double lonSouth = in.readDouble();
+ final double latWest = in.readDouble();
+ return new LatLngBounds(lonNorth, latEast, lonSouth, latWest);
+ }
+
+ /**
+ * Builder for composing LatLngBounds objects.
+ */
+ public static final class Builder {
+
+ private List<LatLng> mLatLngList;
+
+ public Builder() {
+ mLatLngList = new ArrayList<>();
}
- @Override
- public void writeToParcel(final Parcel out, final int arg1) {
- out.writeDouble(this.mLatNorth);
- out.writeDouble(this.mLonEast);
- out.writeDouble(this.mLatSouth);
- out.writeDouble(this.mLonWest);
+ public LatLngBounds build() {
+ if (mLatLngList.size() < 2) {
+ throw new InvalidLatLngBoundsException(mLatLngList.size());
+ }
+ return LatLngBounds.fromLatLngs(mLatLngList);
}
- private static LatLngBounds readFromParcel(final Parcel in) {
- final double lonNorth = in.readDouble();
- final double latEast = in.readDouble();
- final double lonSouth = in.readDouble();
- final double latWest = in.readDouble();
- return new LatLngBounds(lonNorth, latEast, lonSouth, latWest);
+ public Builder includes(List<LatLng> latLngs) {
+ for (LatLng point : latLngs) {
+ mLatLngList.add(point);
+ }
+ return this;
}
- /**
- * Builder for composing LatLngBounds objects.
- */
- public static final class Builder {
-
- private List<LatLng> mLatLngList;
-
- public Builder() {
- mLatLngList = new ArrayList<>();
- }
-
- public LatLngBounds build() {
- if (mLatLngList.size() < 2) {
- throw new InvalidLatLngBoundsException(mLatLngList.size());
- }
- return LatLngBounds.fromLatLngs(mLatLngList);
- }
-
- public Builder includes(List<LatLng> latLngs){
- for (LatLng point : latLngs) {
- mLatLngList.add(point);
- }
- return this;
- }
-
- public Builder include(@NonNull LatLng latLng) {
- mLatLngList.add(latLng);
- return this;
- }
+ public Builder include(@NonNull LatLng latLng) {
+ mLatLngList.add(latLng);
+ return this;
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngSpan.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngSpan.java
index 81e52666f6..dd7fef4d23 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngSpan.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngSpan.java
@@ -9,93 +9,95 @@ import android.support.annotation.NonNull;
*/
public class LatLngSpan implements Parcelable {
- private double mLatitudeSpan;
- private double mLongitudeSpan;
+ private double mLatitudeSpan;
+ private double mLongitudeSpan;
- private LatLngSpan(@NonNull Parcel in) {
- mLatitudeSpan = in.readDouble();
- mLongitudeSpan = in.readDouble();
- }
+ private LatLngSpan(@NonNull Parcel in) {
+ mLatitudeSpan = in.readDouble();
+ mLongitudeSpan = in.readDouble();
+ }
- /**
- * Creates a LatLgnSpan.
- *
- * @param latitudeSpan The span used for latitude.
- * @param longitudeSpan The span used for longitude.
- */
- public LatLngSpan(double latitudeSpan, double longitudeSpan) {
- mLatitudeSpan = latitudeSpan;
- mLongitudeSpan = longitudeSpan;
- }
+ /**
+ * Creates a LatLgnSpan.
+ *
+ * @param latitudeSpan The span used for latitude.
+ * @param longitudeSpan The span used for longitude.
+ */
+ public LatLngSpan(double latitudeSpan, double longitudeSpan) {
+ mLatitudeSpan = latitudeSpan;
+ mLongitudeSpan = longitudeSpan;
+ }
- /**
- * Returns the latitude span.
- *
- * @return The latitude span.
- */
- public double getLatitudeSpan() {
- return mLatitudeSpan;
- }
+ /**
+ * Returns the latitude span.
+ *
+ * @return The latitude span.
+ */
+ public double getLatitudeSpan() {
+ return mLatitudeSpan;
+ }
- /**
- * Sets the latitude span.
- *
- * @param latitudeSpan The latitude span to set.
- */
- public void setLatitudeSpan(double latitudeSpan) {
- mLatitudeSpan = latitudeSpan;
- }
+ /**
+ * Sets the latitude span.
+ *
+ * @param latitudeSpan The latitude span to set.
+ */
+ public void setLatitudeSpan(double latitudeSpan) {
+ mLatitudeSpan = latitudeSpan;
+ }
- /**
- * Returns to longitude span.
- *
- * @return The longitude span.
- */
- public double getLongitudeSpan() {
- return mLongitudeSpan;
- }
+ /**
+ * Returns to longitude span.
+ *
+ * @return The longitude span.
+ */
+ public double getLongitudeSpan() {
+ return mLongitudeSpan;
+ }
- /**
- * Sets the longitude span.
- *
- * @param longitudeSpan The longitude span to set.
- */
- public void setLongitudeSpan(double longitudeSpan) {
- mLongitudeSpan = longitudeSpan;
- }
+ /**
+ * Sets the longitude span.
+ *
+ * @param longitudeSpan The longitude span to set.
+ */
+ public void setLongitudeSpan(double longitudeSpan) {
+ mLongitudeSpan = longitudeSpan;
+ }
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o instanceof LatLngSpan) {
- LatLngSpan other = (LatLngSpan) o;
- return mLongitudeSpan == other.getLongitudeSpan()
- && mLatitudeSpan == other.getLatitudeSpan();
- }
- return false;
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o instanceof LatLngSpan) {
+ LatLngSpan other = (LatLngSpan) o;
+ return mLongitudeSpan == other.getLongitudeSpan()
+ && mLatitudeSpan == other.getLatitudeSpan();
}
+ return false;
+ }
- public static final Parcelable.Creator<LatLngSpan> CREATOR =
- new Parcelable.Creator<LatLngSpan>() {
- @Override
- public LatLngSpan createFromParcel(Parcel in) {
- return new LatLngSpan(in);
- }
+ public static final Parcelable.Creator<LatLngSpan> CREATOR =
+ new Parcelable.Creator<LatLngSpan>() {
+ @Override
+ public LatLngSpan createFromParcel(Parcel in) {
+ return new LatLngSpan(in);
+ }
- @Override
- public LatLngSpan[] newArray(int size) {
- return new LatLngSpan[size];
- }
- };
+ @Override
+ public LatLngSpan[] newArray(int size) {
+ return new LatLngSpan[size];
+ }
+ };
- @Override
- public int describeContents() {
- return 0;
- }
+ @Override
+ public int describeContents() {
+ return 0;
+ }
- @Override
- public void writeToParcel(Parcel out, int arg1) {
- out.writeDouble(mLatitudeSpan);
- out.writeDouble(mLongitudeSpan);
- }
+ @Override
+ public void writeToParcel(Parcel out, int arg1) {
+ out.writeDouble(mLatitudeSpan);
+ out.writeDouble(mLongitudeSpan);
+ }
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ProjectedMeters.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ProjectedMeters.java
index 1f1417b4b6..761d8f2a8b 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ProjectedMeters.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/ProjectedMeters.java
@@ -13,104 +13,105 @@ import android.os.Parcelable;
*/
public class ProjectedMeters implements IProjectedMeters, Parcelable {
- public static final Creator<ProjectedMeters> CREATOR = new Creator<ProjectedMeters>() {
- public ProjectedMeters createFromParcel(Parcel in) {
- return new ProjectedMeters(in);
- }
-
- public ProjectedMeters[] newArray(int size) {
- return new ProjectedMeters[size];
- }
- };
-
- private double northing;
- private double easting;
-
- /**
- * Creates a ProjectedMeters based on projected meters in north and east direction.
- *
- * @param northing the northing in meters
- * @param easting the easting in meters
- */
- public ProjectedMeters(double northing, double easting) {
- this.northing = northing;
- this.easting = easting;
+ public static final Creator<ProjectedMeters> CREATOR = new Creator<ProjectedMeters>() {
+ public ProjectedMeters createFromParcel(Parcel in) {
+ return new ProjectedMeters(in);
}
- /**
- * Creates a ProjecteMeters based on another set of projected meters.
- *
- * @param projectedMeters The projected meters to be based on.
- */
- public ProjectedMeters(ProjectedMeters projectedMeters) {
- this.northing = projectedMeters.northing;
- this.easting = projectedMeters.easting;
+ public ProjectedMeters[] newArray(int size) {
+ return new ProjectedMeters[size];
}
-
- private ProjectedMeters(Parcel in) {
- northing = in.readDouble();
- easting = in.readDouble();
- }
-
- /**
- * Get projected meters in north direction.
- *
- * @return Projected meters in north.
- */
- @Override
- public double getNorthing() {
- return northing;
- }
-
- /**
- * Get projected meters in east direction.
- *
- * @return Projected meters in east.
- */
- @Override
- public double getEasting() {
- return easting;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
-
- ProjectedMeters projectedMeters = (ProjectedMeters) o;
-
- return Double.compare(projectedMeters.easting, easting) == 0 && Double.compare(projectedMeters.northing, northing) == 0;
-
- }
-
- @Override
- public int hashCode() {
- int result;
- long temp;
- temp = Double.doubleToLongBits(easting);
- result = (int) (temp ^ (temp >>> 32));
- temp = Double.doubleToLongBits(northing);
- result = 31 * result + (int) (temp ^ (temp >>> 32));
- return result;
+ };
+
+ private double northing;
+ private double easting;
+
+ /**
+ * Creates a ProjectedMeters based on projected meters in north and east direction.
+ *
+ * @param northing the northing in meters
+ * @param easting the easting in meters
+ */
+ public ProjectedMeters(double northing, double easting) {
+ this.northing = northing;
+ this.easting = easting;
+ }
+
+ /**
+ * Creates a ProjecteMeters based on another set of projected meters.
+ *
+ * @param projectedMeters The projected meters to be based on.
+ */
+ public ProjectedMeters(ProjectedMeters projectedMeters) {
+ this.northing = projectedMeters.northing;
+ this.easting = projectedMeters.easting;
+ }
+
+ private ProjectedMeters(Parcel in) {
+ northing = in.readDouble();
+ easting = in.readDouble();
+ }
+
+ /**
+ * Get projected meters in north direction.
+ *
+ * @return Projected meters in north.
+ */
+ @Override
+ public double getNorthing() {
+ return northing;
+ }
+
+ /**
+ * Get projected meters in east direction.
+ *
+ * @return Projected meters in east.
+ */
+ @Override
+ public double getEasting() {
+ return easting;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
}
-
- @Override
- public String toString() {
- return "ProjectedMeters [northing=" + northing + ", easting=" + easting + "]";
- }
-
- @Override
- public int describeContents() {
- return 0;
+ if (o == null || getClass() != o.getClass()) {
+ return false;
}
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeDouble(northing);
- out.writeDouble(easting);
- }
+ ProjectedMeters projectedMeters = (ProjectedMeters) o;
+
+ return Double.compare(projectedMeters.easting, easting) == 0
+ && Double.compare(projectedMeters.northing, northing) == 0;
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result;
+ long temp;
+ temp = Double.doubleToLongBits(easting);
+ result = (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(northing);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "ProjectedMeters [northing=" + northing + ", easting=" + easting + "]";
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeDouble(northing);
+ out.writeDouble(easting);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/VisibleRegion.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/VisibleRegion.java
index de562c3632..45300f248c 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/VisibleRegion.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/VisibleRegion.java
@@ -12,118 +12,119 @@ import android.os.Parcelable;
*/
public class VisibleRegion implements Parcelable {
- /**
- * LatLng object that defines the far left corner of the camera.
- */
- public final LatLng farLeft;
-
- /**
- * LatLng object that defines the far right corner of the camera.
- */
- public final LatLng farRight;
-
- /**
- * LatLng object that defines the bottom left corner of the camera.
- */
- public final LatLng nearLeft;
-
- /**
- * LatLng object that defines the bottom right corner of the camera.
- */
- public final LatLng nearRight;
-
- /**
- * The smallest bounding box that includes the visible region defined in this class.
- */
- public final LatLngBounds latLngBounds;
-
- private VisibleRegion(Parcel in) {
- this.farLeft = in.readParcelable(LatLng.class.getClassLoader());
- this.farRight = in.readParcelable(LatLng.class.getClassLoader());
- this.nearLeft = in.readParcelable(LatLng.class.getClassLoader());
- this.nearRight = in.readParcelable(LatLng.class.getClassLoader());
- this.latLngBounds = in.readParcelable(LatLngBounds.class.getClassLoader());
+ /**
+ * LatLng object that defines the far left corner of the camera.
+ */
+ public final LatLng farLeft;
+
+ /**
+ * LatLng object that defines the far right corner of the camera.
+ */
+ public final LatLng farRight;
+
+ /**
+ * LatLng object that defines the bottom left corner of the camera.
+ */
+ public final LatLng nearLeft;
+
+ /**
+ * LatLng object that defines the bottom right corner of the camera.
+ */
+ public final LatLng nearRight;
+
+ /**
+ * The smallest bounding box that includes the visible region defined in this class.
+ */
+ public final LatLngBounds latLngBounds;
+
+ private VisibleRegion(Parcel in) {
+ this.farLeft = in.readParcelable(LatLng.class.getClassLoader());
+ this.farRight = in.readParcelable(LatLng.class.getClassLoader());
+ this.nearLeft = in.readParcelable(LatLng.class.getClassLoader());
+ this.nearRight = in.readParcelable(LatLng.class.getClassLoader());
+ this.latLngBounds = in.readParcelable(LatLngBounds.class.getClassLoader());
+ }
+
+ /**
+ * Creates a new VisibleRegion given the four corners of the camera.
+ *
+ * @param farLeft A LatLng object containing the latitude and longitude of the near left corner of the region.
+ * @param farRight A LatLng object containing the latitude and longitude of the near left corner of the region.
+ * @param nearLeft A LatLng object containing the latitude and longitude of the near left corner of the region.
+ * @param nearRight A LatLng object containing the latitude and longitude of the near left corner of the region.
+ * @param latLngBounds The smallest bounding box that includes the visible region defined in this class.
+ */
+ public VisibleRegion(LatLng farLeft, LatLng farRight, LatLng nearLeft, LatLng nearRight, LatLngBounds latLngBounds) {
+ this.farLeft = farLeft;
+ this.farRight = farRight;
+ this.nearLeft = nearLeft;
+ this.nearRight = nearRight;
+ this.latLngBounds = latLngBounds;
+ }
+
+ /**
+ * Compares this VisibleRegion to another object.
+ * If the other object is actually a pointer to this object,
+ * or if all four corners and the bounds of the two objects are the same,
+ * this method returns true. Otherwise, this method returns false.
+ *
+ * @param o The Object to compare with.
+ * @return true if both objects are the same object.
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof VisibleRegion)) {
+ return false;
}
-
- /**
- * Creates a new VisibleRegion given the four corners of the camera.
- *
- * @param farLeft A LatLng object containing the latitude and longitude of the near left corner of the region.
- * @param farRight A LatLng object containing the latitude and longitude of the near left corner of the region.
- * @param nearLeft A LatLng object containing the latitude and longitude of the near left corner of the region.
- * @param nearRight A LatLng object containing the latitude and longitude of the near left corner of the region.
- * @param latLngBounds The smallest bounding box that includes the visible region defined in this class.
- */
- public VisibleRegion(LatLng farLeft, LatLng farRight, LatLng nearLeft, LatLng nearRight, LatLngBounds latLngBounds) {
- this.farLeft = farLeft;
- this.farRight = farRight;
- this.nearLeft = nearLeft;
- this.nearRight = nearRight;
- this.latLngBounds = latLngBounds;
- }
-
- /**
- * Compares this VisibleRegion to another object.
- * If the other object is actually a pointer to this object,
- * or if all four corners and the bounds of the two objects are the same,
- * this method returns true. Otherwise, this method returns false.
- *
- * @param o The Object to compare with.
- * @return true if both objects are the same object.
- */
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof VisibleRegion)) {
- return false;
- }
- if (o == this) {
- return true;
- }
-
- VisibleRegion visibleRegion = (VisibleRegion) o;
- return farLeft.equals(visibleRegion.farLeft)
- && farRight.equals(visibleRegion.farRight)
- && nearLeft.equals(visibleRegion.nearLeft)
- && nearRight.equals(visibleRegion.nearRight)
- && latLngBounds.equals(visibleRegion.latLngBounds);
- }
-
- @Override
- public String toString() {
- return "[farLeft [" + farLeft + "], farRight [" + farRight + "], nearLeft [" + nearLeft + "], nearRight [" + nearRight + "], latLngBounds [" + latLngBounds + "]]";
- }
-
- @Override
- public int hashCode() {
- return ((farLeft.hashCode() + 90)
- + ((farRight.hashCode() + 90) * 1000)
- + ((nearLeft.hashCode() + 180) * 1000000)
- + ((nearRight.hashCode() + 180) * 1000000000));
- }
-
- @Override
- public int describeContents() {
- return 0;
+ if (o == this) {
+ return true;
}
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeParcelable(farLeft, flags);
- out.writeParcelable(farRight, flags);
- out.writeParcelable(nearLeft, flags);
- out.writeParcelable(nearRight, flags);
- out.writeParcelable(latLngBounds, flags);
- }
-
- public static final Parcelable.Creator<VisibleRegion> CREATOR
- = new Parcelable.Creator<VisibleRegion>() {
- public VisibleRegion createFromParcel(Parcel in) {
- return new VisibleRegion(in);
- }
-
- public VisibleRegion[] newArray(int size) {
- return new VisibleRegion[size];
- }
+ VisibleRegion visibleRegion = (VisibleRegion) o;
+ return farLeft.equals(visibleRegion.farLeft)
+ && farRight.equals(visibleRegion.farRight)
+ && nearLeft.equals(visibleRegion.nearLeft)
+ && nearRight.equals(visibleRegion.nearRight)
+ && latLngBounds.equals(visibleRegion.latLngBounds);
+ }
+
+ @Override
+ public String toString() {
+ return "[farLeft [" + farLeft + "], farRight [" + farRight + "], nearLeft [" + nearLeft + "], nearRight ["
+ + nearRight + "], latLngBounds [" + latLngBounds + "]]";
+ }
+
+ @Override
+ public int hashCode() {
+ return ((farLeft.hashCode() + 90)
+ + ((farRight.hashCode() + 90) * 1000)
+ + ((nearLeft.hashCode() + 180) * 1000000)
+ + ((nearRight.hashCode() + 180) * 1000000000));
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeParcelable(farLeft, flags);
+ out.writeParcelable(farRight, flags);
+ out.writeParcelable(nearLeft, flags);
+ out.writeParcelable(nearRight, flags);
+ out.writeParcelable(latLngBounds, flags);
+ }
+
+ public static final Parcelable.Creator<VisibleRegion> CREATOR =
+ new Parcelable.Creator<VisibleRegion>() {
+ public VisibleRegion createFromParcel(Parcel in) {
+ return new VisibleRegion(in);
+ }
+
+ public VisibleRegion[] newArray(int size) {
+ return new VisibleRegion[size];
+ }
};
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java
index 430b37adb8..2c6251638a 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java
@@ -5,10 +5,9 @@ import android.content.Context;
import android.content.pm.PackageInfo;
import android.os.Build;
import android.text.TextUtils;
-import android.util.Log;
import com.mapbox.mapboxsdk.BuildConfig;
-import com.mapbox.mapboxsdk.MapboxAccountManager;
+import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
import java.io.IOException;
@@ -28,176 +27,179 @@ import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.internal.Util;
+import timber.log.Timber;
class HTTPRequest implements Callback {
- private static OkHttpClient mClient = new OkHttpClient();
- private static final String LOG_TAG = HTTPRequest.class.getName();
- private String USER_AGENT_STRING = null;
-
- private static final int CONNECTION_ERROR = 0;
- private static final int TEMPORARY_ERROR = 1;
- private static final int PERMANENT_ERROR = 2;
-
- // Reentrancy is not needed, but "Lock" is an
- // abstract class.
- private ReentrantLock mLock = new ReentrantLock();
-
- private long mNativePtr = 0;
-
- private Call mCall;
- private Request mRequest;
-
- private native void nativeOnFailure(int type, String message);
-
- private native void nativeOnResponse(int code, String etag, String modified, String cacheControl, String expires, String retryAfter, String xRateLimitReset, byte[] body);
-
- private HTTPRequest(long nativePtr, String resourceUrl, String etag, String modified) {
- mNativePtr = nativePtr;
-
- try {
- // Don't try a request if we aren't connected
- if (!MapboxAccountManager.getInstance().isConnected()) {
- throw new NoRouteToHostException("No Internet connection available.");
- }
-
- HttpUrl httpUrl = HttpUrl.parse(resourceUrl);
- final String host = httpUrl.host().toLowerCase(MapboxConstants.MAPBOX_LOCALE);
- if (host.equals("mapbox.com") || host.endsWith(".mapbox.com") || host.equals("mapbox.cn") || host.endsWith(".mapbox.cn")) {
- if (httpUrl.querySize() == 0) {
- resourceUrl = resourceUrl + "?";
- } else {
- resourceUrl = resourceUrl + "&";
- }
- resourceUrl = resourceUrl + "events=true";
- }
-
- Request.Builder builder = new Request.Builder()
- .url(resourceUrl)
- .tag(resourceUrl.toLowerCase(MapboxConstants.MAPBOX_LOCALE))
- .addHeader("User-Agent", getUserAgent());
- if (etag.length() > 0) {
- builder = builder.addHeader("If-None-Match", etag);
- } else if (modified.length() > 0) {
- builder = builder.addHeader("If-Modified-Since", modified);
- }
- mRequest = builder.build();
- mCall = mClient.newCall(mRequest);
- mCall.enqueue(this);
- } catch (Exception e) {
- onFailure(e);
- }
- }
+ private static OkHttpClient mClient = new OkHttpClient();
+ private String USER_AGENT_STRING = null;
- public void cancel() {
- // mCall can be null if the constructor gets aborted (e.g, under a NoRouteToHostException).
- if (mCall != null) {
- mCall.cancel();
- }
+ private static final int CONNECTION_ERROR = 0;
+ private static final int TEMPORARY_ERROR = 1;
+ private static final int PERMANENT_ERROR = 2;
- // TODO: We need a lock here because we can try
- // to cancel at the same time the request is getting
- // answered on the OkHTTP thread. We could get rid of
- // this lock by using Runnable when we move Android
- // implementation of mbgl::RunLoop to Looper.
- mLock.lock();
- mNativePtr = 0;
- mLock.unlock();
- }
+ // Reentrancy is not needed, but "Lock" is an
+ // abstract class.
+ private ReentrantLock mLock = new ReentrantLock();
- @Override
- public void onResponse(Call call, Response response) throws IOException {
- if (response.isSuccessful()) {
- Log.v(LOG_TAG, String.format("[HTTP] Request was successful (code = %d).", response.code()));
- } else {
- // We don't want to call this unsuccessful because a 304 isn't really an error
- String message = !TextUtils.isEmpty(response.message()) ? response.message() : "No additional information";
- Log.d(LOG_TAG, String.format(
- "[HTTP] Request with response code = %d: %s",
- response.code(), message));
- }
+ private long mNativePtr = 0;
- byte[] body;
- try {
- body = response.body().bytes();
- } catch (IOException e) {
- onFailure(e);
- //throw e;
- return;
- } finally {
- response.body().close();
- }
+ private Call mCall;
+ private Request mRequest;
- mLock.lock();
- if (mNativePtr != 0) {
- nativeOnResponse(response.code(),
- response.header("ETag"),
- response.header("Last-Modified"),
- response.header("Cache-Control"),
- response.header("Expires"),
- response.header("Retry-After"),
- response.header("x-rate-limit-reset"),
- body);
- }
- mLock.unlock();
- }
+ private native void nativeOnFailure(int type, String message);
- @Override
- public void onFailure(Call call, IOException e) {
- onFailure(e);
- }
+ private native void nativeOnResponse(int code, String etag, String modified, String cacheControl, String expires,
+ String retryAfter, String xRateLimitReset, byte[] body);
- private void onFailure(Exception e) {
- int type = PERMANENT_ERROR;
- if ((e instanceof NoRouteToHostException) || (e instanceof UnknownHostException) || (e instanceof SocketException) || (e instanceof ProtocolException) || (e instanceof SSLException)) {
- type = CONNECTION_ERROR;
- } else if ((e instanceof InterruptedIOException)) {
- type = TEMPORARY_ERROR;
- }
+ private HTTPRequest(long nativePtr, String resourceUrl, String etag, String modified) {
+ mNativePtr = nativePtr;
- String errorMessage = e.getMessage() != null ? e.getMessage() : "Error processing the request";
+ try {
+ // Don't try a request if we aren't connected
+ if (!Mapbox.isConnected()) {
+ throw new NoRouteToHostException("No Internet connection available.");
+ }
- if (type == TEMPORARY_ERROR) {
- Log.d(LOG_TAG, String.format(MapboxConstants.MAPBOX_LOCALE,
- "Request failed due to a temporary error: %s", errorMessage));
- } else if (type == CONNECTION_ERROR) {
- Log.i(LOG_TAG, String.format(MapboxConstants.MAPBOX_LOCALE,
- "Request failed due to a connection error: %s", errorMessage));
+ HttpUrl httpUrl = HttpUrl.parse(resourceUrl);
+ final String host = httpUrl.host().toLowerCase(MapboxConstants.MAPBOX_LOCALE);
+ if (host.equals("mapbox.com") || host.endsWith(".mapbox.com") || host.equals("mapbox.cn")
+ || host.endsWith(".mapbox.cn")) {
+ if (httpUrl.querySize() == 0) {
+ resourceUrl = resourceUrl + "?";
} else {
- // PERMANENT_ERROR
- Log.w(LOG_TAG, String.format(MapboxConstants.MAPBOX_LOCALE,
- "Request failed due to a permanent error: %s", errorMessage));
+ resourceUrl = resourceUrl + "&";
}
+ resourceUrl = resourceUrl + "events=true";
+ }
+
+ Request.Builder builder = new Request.Builder()
+ .url(resourceUrl)
+ .tag(resourceUrl.toLowerCase(MapboxConstants.MAPBOX_LOCALE))
+ .addHeader("User-Agent", getUserAgent());
+ if (etag.length() > 0) {
+ builder = builder.addHeader("If-None-Match", etag);
+ } else if (modified.length() > 0) {
+ builder = builder.addHeader("If-Modified-Since", modified);
+ }
+ mRequest = builder.build();
+ mCall = mClient.newCall(mRequest);
+ mCall.enqueue(this);
+ } catch (Exception exception) {
+ onFailure(exception);
+ }
+ }
- mLock.lock();
- if (mNativePtr != 0) {
- nativeOnFailure(type, errorMessage);
- }
- mLock.unlock();
+ public void cancel() {
+ // mCall can be null if the constructor gets aborted (e.g, under a NoRouteToHostException).
+ if (mCall != null) {
+ mCall.cancel();
}
- private String getUserAgent() {
- if (USER_AGENT_STRING == null) {
- return USER_AGENT_STRING = Util.toHumanReadableAscii(
- String.format("%s %s (%s) Android/%s (%s)",
- getApplicationIdentifier(),
- BuildConfig.MAPBOX_VERSION_STRING,
- BuildConfig.GIT_REVISION_SHORT,
- Build.VERSION.SDK_INT,
- Build.CPU_ABI)
- );
- } else {
- return USER_AGENT_STRING;
- }
+ // TODO: We need a lock here because we can try
+ // to cancel at the same time the request is getting
+ // answered on the OkHTTP thread. We could get rid of
+ // this lock by using Runnable when we move Android
+ // implementation of mbgl::RunLoop to Looper.
+ mLock.lock();
+ mNativePtr = 0;
+ mLock.unlock();
+ }
+
+ @Override
+ public void onResponse(Call call, Response response) throws IOException {
+ if (response.isSuccessful()) {
+ Timber.v(String.format("[HTTP] Request was successful (code = %d).", response.code()));
+ } else {
+ // We don't want to call this unsuccessful because a 304 isn't really an error
+ String message = !TextUtils.isEmpty(response.message()) ? response.message() : "No additional information";
+ Timber.d(String.format(
+ "[HTTP] Request with response code = %d: %s",
+ response.code(), message));
}
- private String getApplicationIdentifier() {
- try {
- Context context = MapboxAccountManager.getInstance().getApplicationContext();
- PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
- return String.format("%s/%s (%s)", context.getPackageName(), packageInfo.versionName, packageInfo.versionCode);
- } catch (Exception e) {
- return "";
- }
+ byte[] body;
+ try {
+ body = response.body().bytes();
+ } catch (IOException ioException) {
+ onFailure(ioException);
+ //throw ioException;
+ return;
+ } finally {
+ response.body().close();
+ }
+
+ mLock.lock();
+ if (mNativePtr != 0) {
+ nativeOnResponse(response.code(),
+ response.header("ETag"),
+ response.header("Last-Modified"),
+ response.header("Cache-Control"),
+ response.header("Expires"),
+ response.header("Retry-After"),
+ response.header("x-rate-limit-reset"),
+ body);
+ }
+ mLock.unlock();
+ }
+
+ @Override
+ public void onFailure(Call call, IOException e) {
+ onFailure(e);
+ }
+
+ private void onFailure(Exception e) {
+ int type = PERMANENT_ERROR;
+ if ((e instanceof NoRouteToHostException) || (e instanceof UnknownHostException) || (e instanceof SocketException)
+ || (e instanceof ProtocolException) || (e instanceof SSLException)) {
+ type = CONNECTION_ERROR;
+ } else if ((e instanceof InterruptedIOException)) {
+ type = TEMPORARY_ERROR;
+ }
+
+ String errorMessage = e.getMessage() != null ? e.getMessage() : "Error processing the request";
+
+ if (type == TEMPORARY_ERROR) {
+ Timber.d(String.format(MapboxConstants.MAPBOX_LOCALE,
+ "Request failed due to a temporary error: %s", errorMessage));
+ } else if (type == CONNECTION_ERROR) {
+ Timber.i(String.format(MapboxConstants.MAPBOX_LOCALE,
+ "Request failed due to a connection error: %s", errorMessage));
+ } else {
+ // PERMANENT_ERROR
+ Timber.w(String.format(MapboxConstants.MAPBOX_LOCALE,
+ "Request failed due to a permanent error: %s", errorMessage));
+ }
+
+ mLock.lock();
+ if (mNativePtr != 0) {
+ nativeOnFailure(type, errorMessage);
+ }
+ mLock.unlock();
+ }
+
+ private String getUserAgent() {
+ if (USER_AGENT_STRING == null) {
+ return USER_AGENT_STRING = Util.toHumanReadableAscii(
+ String.format("%s %s (%s) Android/%s (%s)",
+ getApplicationIdentifier(),
+ BuildConfig.MAPBOX_VERSION_STRING,
+ BuildConfig.GIT_REVISION_SHORT,
+ Build.VERSION.SDK_INT,
+ Build.CPU_ABI)
+ );
+ } else {
+ return USER_AGENT_STRING;
+ }
+ }
+
+ private String getApplicationIdentifier() {
+ try {
+ Context context = Mapbox.getApplicationContext();
+ PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
+ return String.format("%s/%s (%s)", context.getPackageName(), packageInfo.versionName, packageInfo.versionCode);
+ } catch (Exception exception) {
+ return "";
}
-}
+ }
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationListener.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationListener.java
index eb8c4100dc..7d86d8b096 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationListener.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationListener.java
@@ -7,10 +7,11 @@ import android.location.Location;
*/
public interface LocationListener {
- /**
- * Callback method for receiving location updates from LocationServices.
- * @param location The new Location data
- */
- void onLocationChanged(Location location);
+ /**
+ * Callback method for receiving location updates from LocationServices.
+ *
+ * @param location The new Location data
+ */
+ void onLocationChanged(Location location);
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationServices.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationServices.java
index 4fade484b4..666dcb565f 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationServices.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationServices.java
@@ -8,7 +8,8 @@ import android.location.Location;
import android.location.LocationManager;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
-import android.util.Log;
+
+import timber.log.Timber;
import com.mapbox.mapboxsdk.telemetry.TelemetryLocationReceiver;
import com.mapzen.android.lost.api.LocationRequest;
@@ -19,171 +20,174 @@ import java.util.concurrent.CopyOnWriteArrayList;
/**
* Manages locational updates. Contains methods to register and unregister location listeners.
* <ul>
- * <li>You can register a {@link LocationListener} with {@link #addLocationListener(LocationListener)} to receive location updates.</li>
+ * <li>You can register a {@link LocationListener} with {@link #addLocationListener(LocationListener)} to receive
+ * location updates.</li>
* <li> You can unregister a {@link LocationListener} with {@link #removeLocationListener(LocationListener)}.</li>
* </ul>
* <p>
- * Note: If registering a listener in your Activity.onResume() implementation, you should unregister it in Activity.onPause().
- * (You won't receive location updates when paused, and this will cut down on unnecessary system overhead).
- * Do not unregister in Activity.onSaveInstanceState(), because this won't be called if the user moves back in the history stack.
+ * Note: If registering a listener in your Activity.onStart() implementation, you should unregister it in
+ * Activity.onStop(). (You won't receive location updates when paused, and this will cut down on unnecessary system
+ * overhead). Do not unregister in Activity.onSaveInstanceState(), because this won't be called if the user moves back
+ * in the history stack.
* </p>
*/
public class LocationServices implements com.mapzen.android.lost.api.LocationListener {
- private static final String TAG = "LocationServices";
-
- private static LocationServices instance;
-
- private Context context;
- private LostApiClient locationClient;
- private Location lastLocation;
-
- private CopyOnWriteArrayList<LocationListener> locationListeners;
-
- private boolean isGPSEnabled;
-
- /**
- * Private constructor for singleton LocationServices
- */
- private LocationServices(Context context) {
- super();
- this.context = context;
- // Setup location services
- locationClient = new LostApiClient.Builder(context).build();
- locationListeners = new CopyOnWriteArrayList<>();
+ private static LocationServices instance;
+
+ private Context context;
+ private LostApiClient locationClient;
+ private Location lastLocation;
+
+ private CopyOnWriteArrayList<LocationListener> locationListeners;
+
+ private boolean isGpsEnabled;
+
+ /**
+ * Private constructor for singleton LocationServices
+ */
+ private LocationServices(Context context) {
+ super();
+ this.context = context;
+ // Setup location services
+ locationClient = new LostApiClient.Builder(context).build();
+ locationListeners = new CopyOnWriteArrayList<>();
+ }
+
+ /**
+ * Primary (singleton) access method for LocationServices
+ *
+ * @param context Context
+ * @return LocationServices
+ */
+ public static LocationServices getLocationServices(@NonNull final Context context) {
+ if (instance == null) {
+ instance = new LocationServices(context.getApplicationContext());
}
-
- /**
- * Primary (singleton) access method for LocationServices
- *
- * @param context Context
- * @return LocationServices
- */
- public static LocationServices getLocationServices(@NonNull final Context context) {
- if (instance == null) {
- instance = new LocationServices(context.getApplicationContext());
- }
- return instance;
+ return instance;
+ }
+
+ /**
+ * Enabled / Disable GPS focused location tracking
+ *
+ * @param enableGPS true if GPS is to be enabled, false if GPS is to be disabled
+ */
+ public void toggleGPS(boolean enableGPS) {
+ if (!areLocationPermissionsGranted()) {
+ Timber.w("Location Permissions Not Granted Yet. Try again after requesting.");
+ return;
}
- /**
- * Enabled / Disable GPS focused location tracking
- *
- * @param enableGPS true if GPS is to be enabled, false if GPS is to be disabled
- */
- public void toggleGPS(boolean enableGPS) {
- if (!areLocationPermissionsGranted()) {
- Log.w(TAG, "Location Permissions Not Granted Yet. Try again after requesting.");
- return;
- }
-
- // Disconnect
- if (locationClient.isConnected()) {
- // Disconnect first to ensure that the new requests are GPS
- com.mapzen.android.lost.api.LocationServices.FusedLocationApi.removeLocationUpdates(this);
- locationClient.disconnect();
- }
-
- // Setup Fresh
- locationClient.connect();
- Location lastLocation = com.mapzen.android.lost.api.LocationServices.FusedLocationApi.getLastLocation();
- if (lastLocation != null) {
- this.lastLocation = lastLocation;
- }
-
- LocationRequest locationRequest;
-
- if (enableGPS) {
- // LocationRequest Tuned for GPS
- locationRequest = LocationRequest.create()
- .setFastestInterval(1000)
- .setSmallestDisplacement(3.0f)
- .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
-
- com.mapzen.android.lost.api.LocationServices.FusedLocationApi.requestLocationUpdates(locationRequest, this);
- } else {
- // LocationRequest Tuned for PASSIVE
- locationRequest = LocationRequest.create()
- .setFastestInterval(1000)
- .setSmallestDisplacement(3.0f)
- .setPriority(LocationRequest.PRIORITY_NO_POWER);
-
- com.mapzen.android.lost.api.LocationServices.FusedLocationApi.requestLocationUpdates(locationRequest, this);
- }
-
- isGPSEnabled = enableGPS;
+ // Disconnect
+ if (locationClient.isConnected()) {
+ // Disconnect first to ensure that the new requests are GPS
+ com.mapzen.android.lost.api.LocationServices.FusedLocationApi.removeLocationUpdates(this);
+ locationClient.disconnect();
}
- /**
- * Returns if the GPS sensor is currently enabled
- *
- * @return active state of the GPS
- */
- public boolean isGPSEnabled() {
- return isGPSEnabled;
+ // Setup Fresh
+ locationClient.connect();
+ Location lastLocation = com.mapzen.android.lost.api.LocationServices.FusedLocationApi.getLastLocation();
+ if (lastLocation != null) {
+ this.lastLocation = lastLocation;
}
- /**
- * Called when the location has changed.
- *
- * @param location The updated location
- */
- @Override
- public void onLocationChanged(Location location) {
-// Log.d(TAG, "onLocationChanged()..." + location);
- this.lastLocation = location;
-
- // Update Listeners
- for (LocationListener listener : this.locationListeners) {
- listener.onLocationChanged(location);
- }
-
- // Update the Telemetry Receiver
- Intent locIntent = new Intent(TelemetryLocationReceiver.INTENT_STRING);
- locIntent.putExtra(LocationManager.KEY_LOCATION_CHANGED, location);
- context.sendBroadcast(locIntent);
- }
+ LocationRequest locationRequest;
- /**
- * Last known location
- *
- * @return Last known location data
- */
- public Location getLastLocation() {
- return lastLocation;
- }
+ if (enableGPS) {
+ // LocationRequest Tuned for GPS
+ locationRequest = LocationRequest.create()
+ .setFastestInterval(1000)
+ .setSmallestDisplacement(3.0f)
+ .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
- /**
- * Registers a LocationListener to receive location updates
- *
- * @param locationListener LocationListener
- */
- public void addLocationListener(@NonNull LocationListener locationListener) {
- if (!this.locationListeners.contains(locationListener)) {
- this.locationListeners.add(locationListener);
- }
+ com.mapzen.android.lost.api.LocationServices.FusedLocationApi.requestLocationUpdates(locationRequest, this);
+ } else {
+ // LocationRequest Tuned for PASSIVE
+ locationRequest = LocationRequest.create()
+ .setFastestInterval(1000)
+ .setSmallestDisplacement(3.0f)
+ .setPriority(LocationRequest.PRIORITY_NO_POWER);
+
+ com.mapzen.android.lost.api.LocationServices.FusedLocationApi.requestLocationUpdates(locationRequest, this);
}
- /**
- * Unregister a LocationListener to stop receiving location updates
- *
- * @param locationListener LocationListener to remove
- * @return True if LocationListener was found and removed, False if it was not
- */
- public boolean removeLocationListener(@NonNull LocationListener locationListener) {
- return this.locationListeners.remove(locationListener);
+ isGpsEnabled = enableGPS;
+ }
+
+ /**
+ * Returns if the GPS sensor is currently enabled
+ *
+ * @return active state of the GPS
+ */
+ public boolean isGpsEnabled() {
+ return isGpsEnabled;
+ }
+
+ /**
+ * Called when the location has changed.
+ *
+ * @param location The updated location
+ */
+ @Override
+ public void onLocationChanged(Location location) {
+ // Timber.d("onLocationChanged()..." + location);
+ this.lastLocation = location;
+
+ // Update Listeners
+ for (LocationListener listener : this.locationListeners) {
+ listener.onLocationChanged(location);
}
- /**
- * Check status of Location Permissions
- * @return True if granted to the app, False if not
- */
- public boolean areLocationPermissionsGranted() {
- if ((ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) &&
- (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)) {
- Log.w(TAG, "Location Permissions Not Granted Yet. Try again after requesting.");
- return false;
- }
- return true;
+ // Update the Telemetry Receiver
+ Intent locIntent = new Intent(TelemetryLocationReceiver.INTENT_STRING);
+ locIntent.putExtra(LocationManager.KEY_LOCATION_CHANGED, location);
+ context.sendBroadcast(locIntent);
+ }
+
+ /**
+ * Last known location
+ *
+ * @return Last known location data
+ */
+ public Location getLastLocation() {
+ return lastLocation;
+ }
+
+ /**
+ * Registers a LocationListener to receive location updates
+ *
+ * @param locationListener LocationListener
+ */
+ public void addLocationListener(@NonNull LocationListener locationListener) {
+ if (!this.locationListeners.contains(locationListener)) {
+ this.locationListeners.add(locationListener);
+ }
+ }
+
+ /**
+ * Unregister a LocationListener to stop receiving location updates
+ *
+ * @param locationListener LocationListener to remove
+ * @return True if LocationListener was found and removed, False if it was not
+ */
+ public boolean removeLocationListener(@NonNull LocationListener locationListener) {
+ return this.locationListeners.remove(locationListener);
+ }
+
+ /**
+ * Check status of Location Permissions
+ *
+ * @return True if granted to the app, False if not
+ */
+ public boolean areLocationPermissionsGranted() {
+ if ((ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION)
+ != PackageManager.PERMISSION_GRANTED)
+ && (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION)
+ != PackageManager.PERMISSION_GRANTED)) {
+ Timber.w("Location Permissions Not Granted Yet. Try again after requesting.");
+ return false;
}
+ return true;
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java
new file mode 100644
index 0000000000..17317522a3
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java
@@ -0,0 +1,683 @@
+package com.mapbox.mapboxsdk.maps;
+
+import android.graphics.PointF;
+import android.graphics.RectF;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v4.util.LongSparseArray;
+
+import com.mapbox.mapboxsdk.annotations.Annotation;
+import com.mapbox.mapboxsdk.annotations.BaseMarkerOptions;
+import com.mapbox.mapboxsdk.annotations.BaseMarkerViewOptions;
+import com.mapbox.mapboxsdk.annotations.Icon;
+import com.mapbox.mapboxsdk.annotations.Marker;
+import com.mapbox.mapboxsdk.annotations.MarkerView;
+import com.mapbox.mapboxsdk.annotations.MarkerViewManager;
+import com.mapbox.mapboxsdk.annotations.Polygon;
+import com.mapbox.mapboxsdk.annotations.PolygonOptions;
+import com.mapbox.mapboxsdk.annotations.Polyline;
+import com.mapbox.mapboxsdk.annotations.PolylineOptions;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Responsible for managing and tracking state of Annotations linked to Map. All events related to
+ * annotations that occur on {@link MapboxMap} are forwarded to this class.
+ * <p>
+ * Responsible for referencing {@link InfoWindowManager} and {@link MarkerViewManager}.
+ * </p>
+ * <p>
+ * Exposes convenience methods to add/remove/update all subtypes of annotations found in
+ * com.mapbox.mapboxsdk.annotations.
+ * </p>
+ */
+class AnnotationManager {
+
+ private final NativeMapView nativeMapView;
+ private final MapView mapView;
+ private final IconManager iconManager;
+ private final InfoWindowManager infoWindowManager = new InfoWindowManager();
+ private final MarkerViewManager markerViewManager;
+ private final LongSparseArray<Annotation> annotations = new LongSparseArray<>();
+ private final List<Marker> selectedMarkers = new ArrayList<>();
+
+ private MapboxMap mapboxMap;
+ private MapboxMap.OnMarkerClickListener onMarkerClickListener;
+
+ AnnotationManager(NativeMapView view, MapView mapView, MarkerViewManager markerViewManager) {
+ this.nativeMapView = view;
+ this.mapView = mapView;
+ this.iconManager = new IconManager(nativeMapView);
+ this.markerViewManager = markerViewManager;
+ if (view != null) {
+ // null checking needed for unit tests
+ nativeMapView.addOnMapChangedListener(markerViewManager);
+ }
+ }
+
+ // TODO refactor MapboxMap out for Projection and Transform
+ // Requires removing MapboxMap from Annotations by using Peer model from #6912
+ AnnotationManager bind(MapboxMap mapboxMap) {
+ this.mapboxMap = mapboxMap;
+ this.markerViewManager.bind(mapboxMap);
+ return this;
+ }
+
+ void update() {
+ markerViewManager.scheduleViewMarkerInvalidation();
+ infoWindowManager.update();
+ }
+
+ //
+ // Annotations
+ //
+
+ Annotation getAnnotation(long id) {
+ return annotations.get(id);
+ }
+
+ List<Annotation> getAnnotations() {
+ List<Annotation> annotations = new ArrayList<>();
+ for (int i = 0; i < this.annotations.size(); i++) {
+ annotations.add(this.annotations.get(this.annotations.keyAt(i)));
+ }
+ return annotations;
+ }
+
+ void removeAnnotation(@NonNull Annotation annotation) {
+ if (annotation instanceof Marker) {
+ Marker marker = (Marker) annotation;
+ marker.hideInfoWindow();
+ if (marker instanceof MarkerView) {
+ markerViewManager.removeMarkerView((MarkerView) marker);
+ }
+ }
+ long id = annotation.getId();
+ if (nativeMapView != null) {
+ nativeMapView.removeAnnotation(id);
+ }
+ annotations.remove(id);
+ }
+
+ void removeAnnotation(long id) {
+ if (nativeMapView != null) {
+ nativeMapView.removeAnnotation(id);
+ }
+ annotations.remove(id);
+ }
+
+ void removeAnnotations(@NonNull List<? extends Annotation> annotationList) {
+ int count = annotationList.size();
+ long[] ids = new long[count];
+ for (int i = 0; i < count; i++) {
+ Annotation annotation = annotationList.get(i);
+ if (annotation instanceof Marker) {
+ Marker marker = (Marker) annotation;
+ marker.hideInfoWindow();
+ if (marker instanceof MarkerView) {
+ markerViewManager.removeMarkerView((MarkerView) marker);
+ }
+ }
+ ids[i] = annotationList.get(i).getId();
+ }
+
+ if (nativeMapView != null) {
+ nativeMapView.removeAnnotations(ids);
+ }
+
+ for (long id : ids) {
+ annotations.remove(id);
+ }
+ }
+
+ void removeAnnotations() {
+ Annotation annotation;
+ int count = annotations.size();
+ long[] ids = new long[count];
+ for (int i = 0; i < count; i++) {
+ ids[i] = annotations.keyAt(i);
+ annotation = annotations.get(ids[i]);
+ if (annotation instanceof Marker) {
+ Marker marker = (Marker) annotation;
+ marker.hideInfoWindow();
+ if (marker instanceof MarkerView) {
+ markerViewManager.removeMarkerView((MarkerView) marker);
+ }
+ }
+ }
+
+ if (nativeMapView != null) {
+ nativeMapView.removeAnnotations(ids);
+ }
+
+ annotations.clear();
+ }
+
+ //
+ // Markers
+ //
+
+ Marker addMarker(@NonNull BaseMarkerOptions markerOptions, @NonNull MapboxMap mapboxMap) {
+ Marker marker = prepareMarker(markerOptions);
+ long id = nativeMapView != null ? nativeMapView.addMarker(marker) : 0;
+ marker.setMapboxMap(mapboxMap);
+ marker.setId(id);
+ annotations.put(id, marker);
+ return marker;
+ }
+
+ List<Marker> addMarkers(@NonNull List<? extends BaseMarkerOptions> markerOptionsList, @NonNull MapboxMap mapboxMap) {
+ int count = markerOptionsList.size();
+ List<Marker> markers = new ArrayList<>(count);
+ if (count > 0) {
+ BaseMarkerOptions markerOptions;
+ Marker marker;
+ for (int i = 0; i < count; i++) {
+ markerOptions = markerOptionsList.get(i);
+ marker = prepareMarker(markerOptions);
+ markers.add(marker);
+ }
+
+ if (markers.size() > 0) {
+ long[] ids = null;
+ if (nativeMapView != null) {
+ ids = nativeMapView.addMarkers(markers);
+ }
+
+ long id = 0;
+ Marker m;
+ for (int i = 0; i < markers.size(); i++) {
+ m = markers.get(i);
+ m.setMapboxMap(mapboxMap);
+ if (ids != null) {
+ id = ids[i];
+ } else {
+ //unit test
+ id++;
+ }
+ m.setId(id);
+ annotations.put(id, m);
+ }
+
+ }
+ }
+ return markers;
+ }
+
+ private Marker prepareMarker(BaseMarkerOptions markerOptions) {
+ Marker marker = markerOptions.getMarker();
+ Icon icon = iconManager.loadIconForMarker(marker);
+ marker.setTopOffsetPixels(iconManager.getTopOffsetPixelsForIcon(icon));
+ return marker;
+ }
+
+ MarkerView addMarker(@NonNull BaseMarkerViewOptions markerOptions, @NonNull MapboxMap mapboxMap,
+ @Nullable MarkerViewManager.OnMarkerViewAddedListener onMarkerViewAddedListener) {
+ final MarkerView marker = prepareViewMarker(markerOptions);
+
+ // add marker to map
+ marker.setMapboxMap(mapboxMap);
+ long id = nativeMapView.addMarker(marker);
+ marker.setId(id);
+ annotations.put(id, marker);
+
+ if (onMarkerViewAddedListener != null) {
+ markerViewManager.addOnMarkerViewAddedListener(marker, onMarkerViewAddedListener);
+ }
+ markerViewManager.setWaitingForRenderInvoke(true);
+ return marker;
+ }
+
+
+ List<MarkerView> addMarkerViews(@NonNull List<? extends BaseMarkerViewOptions> markerViewOptions,
+ @NonNull MapboxMap mapboxMap) {
+ List<MarkerView> markers = new ArrayList<>();
+ for (BaseMarkerViewOptions markerViewOption : markerViewOptions) {
+ // if last marker
+ if (markerViewOptions.indexOf(markerViewOption) == markerViewOptions.size() - 1) {
+ // get notified when render occurs to invalidate and draw MarkerViews
+ markerViewManager.setWaitingForRenderInvoke(true);
+ }
+ // add marker to map
+ MarkerView marker = prepareViewMarker(markerViewOption);
+ marker.setMapboxMap(mapboxMap);
+ long id = nativeMapView.addMarker(marker);
+ marker.setId(id);
+ annotations.put(id, marker);
+ markers.add(marker);
+ }
+ markerViewManager.invalidateViewMarkersInVisibleRegion();
+ return markers;
+ }
+
+ private MarkerView prepareViewMarker(BaseMarkerViewOptions markerViewOptions) {
+ MarkerView marker = markerViewOptions.getMarker();
+ iconManager.loadIconForMarkerView(marker);
+ return marker;
+ }
+
+ void updateMarker(@NonNull Marker updatedMarker, @NonNull MapboxMap mapboxMap) {
+ if (updatedMarker == null) {
+ return;
+ }
+
+ if (updatedMarker.getId() == -1) {
+ return;
+ }
+
+ if (!(updatedMarker instanceof MarkerView)) {
+ iconManager.ensureIconLoaded(updatedMarker, mapboxMap);
+ }
+
+ nativeMapView.updateMarker(updatedMarker);
+
+ int index = annotations.indexOfKey(updatedMarker.getId());
+ if (index > -1) {
+ annotations.setValueAt(index, updatedMarker);
+ }
+ }
+
+ List<Marker> getMarkers() {
+ List<Marker> markers = new ArrayList<>();
+ Annotation annotation;
+ for (int i = 0; i < annotations.size(); i++) {
+ annotation = annotations.get(annotations.keyAt(i));
+ if (annotation instanceof Marker) {
+ markers.add((Marker) annotation);
+ }
+ }
+ return markers;
+ }
+
+ void setOnMarkerClickListener(@Nullable MapboxMap.OnMarkerClickListener listener) {
+ onMarkerClickListener = listener;
+ }
+
+ void selectMarker(@NonNull Marker marker) {
+ if (selectedMarkers.contains(marker)) {
+ return;
+ }
+
+ // Need to deselect any currently selected annotation first
+ if (!infoWindowManager.isAllowConcurrentMultipleOpenInfoWindows()) {
+ deselectMarkers();
+ }
+
+ if (marker instanceof MarkerView) {
+ markerViewManager.select((MarkerView) marker, false);
+ markerViewManager.ensureInfoWindowOffset((MarkerView) marker);
+ }
+
+ if (infoWindowManager.isInfoWindowValidForMarker(marker) || infoWindowManager.getInfoWindowAdapter() != null) {
+ infoWindowManager.add(marker.showInfoWindow(mapboxMap, mapView));
+ }
+
+ // only add to selected markers if user didn't handle the click event themselves #3176
+ selectedMarkers.add(marker);
+ }
+
+ void deselectMarkers() {
+ if (selectedMarkers.isEmpty()) {
+ return;
+ }
+
+ for (Marker marker : selectedMarkers) {
+ if (marker.isInfoWindowShown()) {
+ marker.hideInfoWindow();
+ }
+
+ if (marker instanceof MarkerView) {
+ markerViewManager.deselect((MarkerView) marker, false);
+ }
+ }
+
+ // Removes all selected markers from the list
+ selectedMarkers.clear();
+ }
+
+ void deselectMarker(@NonNull Marker marker) {
+ if (!selectedMarkers.contains(marker)) {
+ return;
+ }
+
+ if (marker.isInfoWindowShown()) {
+ marker.hideInfoWindow();
+ }
+
+ if (marker instanceof MarkerView) {
+ markerViewManager.deselect((MarkerView) marker, false);
+ }
+
+ selectedMarkers.remove(marker);
+ }
+
+ List<Marker> getSelectedMarkers() {
+ return selectedMarkers;
+ }
+
+ List<Marker> getMarkersInRect(@NonNull RectF rectangle) {
+ // convert Rectangle to be density depedent
+ float pixelRatio = nativeMapView.getPixelRatio();
+ RectF rect = new RectF(rectangle.left / pixelRatio,
+ rectangle.top / pixelRatio,
+ rectangle.right / pixelRatio,
+ rectangle.bottom / pixelRatio);
+
+ long[] ids = nativeMapView.queryPointAnnotations(rect);
+
+ List<Long> idsList = new ArrayList<>(ids.length);
+ for (long id : ids) {
+ idsList.add(id);
+ }
+
+ List<Marker> annotations = new ArrayList<>(ids.length);
+ List<Annotation> annotationList = getAnnotations();
+ int count = annotationList.size();
+ for (int i = 0; i < count; i++) {
+ Annotation annotation = annotationList.get(i);
+ if (annotation instanceof com.mapbox.mapboxsdk.annotations.Marker && idsList.contains(annotation.getId())) {
+ annotations.add((com.mapbox.mapboxsdk.annotations.Marker) annotation);
+ }
+ }
+
+ return new ArrayList<>(annotations);
+ }
+
+ List<MarkerView> getMarkerViewsInRect(@NonNull RectF rectangle) {
+ float pixelRatio = nativeMapView.getPixelRatio();
+ RectF rect = new RectF(rectangle.left / pixelRatio,
+ rectangle.top / pixelRatio,
+ rectangle.right / pixelRatio,
+ rectangle.bottom / pixelRatio);
+
+ long[] ids = nativeMapView.queryPointAnnotations(rect);
+
+ List<Long> idsList = new ArrayList<>(ids.length);
+ for (long id : ids) {
+ idsList.add(id);
+ }
+
+ List<MarkerView> annotations = new ArrayList<>(ids.length);
+ List<Annotation> annotationList = getAnnotations();
+ int count = annotationList.size();
+ for (int i = 0; i < count; i++) {
+ Annotation annotation = annotationList.get(i);
+ if (annotation instanceof MarkerView && idsList.contains(annotation.getId())) {
+ annotations.add((MarkerView) annotation);
+ }
+ }
+
+ return new ArrayList<>(annotations);
+ }
+
+ //
+ // Polygons
+ //
+
+ Polygon addPolygon(@NonNull PolygonOptions polygonOptions, @NonNull MapboxMap mapboxMap) {
+ Polygon polygon = polygonOptions.getPolygon();
+ if (!polygon.getPoints().isEmpty()) {
+ long id = nativeMapView != null ? nativeMapView.addPolygon(polygon) : 0;
+ polygon.setId(id);
+ polygon.setMapboxMap(mapboxMap);
+ annotations.put(id, polygon);
+ }
+ return polygon;
+ }
+
+ List<Polygon> addPolygons(@NonNull List<PolygonOptions> polygonOptionsList, @NonNull MapboxMap mapboxMap) {
+ int count = polygonOptionsList.size();
+
+ Polygon polygon;
+ List<Polygon> polygons = new ArrayList<>(count);
+ if (count > 0) {
+ for (PolygonOptions polygonOptions : polygonOptionsList) {
+ polygon = polygonOptions.getPolygon();
+ if (!polygon.getPoints().isEmpty()) {
+ polygons.add(polygon);
+ }
+ }
+
+ long[] ids = null;
+ if (nativeMapView != null) {
+ ids = nativeMapView.addPolygons(polygons);
+ }
+
+ long id = 0;
+ for (int i = 0; i < polygons.size(); i++) {
+ polygon = polygons.get(i);
+ polygon.setMapboxMap(mapboxMap);
+ if (ids != null) {
+ id = ids[i];
+ } else {
+ // unit test
+ id++;
+ }
+ polygon.setId(id);
+ annotations.put(id, polygon);
+ }
+ }
+ return polygons;
+ }
+
+ void updatePolygon(Polygon polygon) {
+ if (polygon == null) {
+ return;
+ }
+
+ if (polygon.getId() == -1) {
+ return;
+ }
+
+ nativeMapView.updatePolygon(polygon);
+
+ int index = annotations.indexOfKey(polygon.getId());
+ if (index > -1) {
+ annotations.setValueAt(index, polygon);
+ }
+ }
+
+ List<Polygon> getPolygons() {
+ List<Polygon> polygons = new ArrayList<>();
+ Annotation annotation;
+ for (int i = 0; i < annotations.size(); i++) {
+ annotation = annotations.get(annotations.keyAt(i));
+ if (annotation instanceof Polygon) {
+ polygons.add((Polygon) annotation);
+ }
+ }
+ return polygons;
+ }
+
+ //
+ // Polylines
+ //
+
+ Polyline addPolyline(@NonNull PolylineOptions polylineOptions, @NonNull MapboxMap mapboxMap) {
+ Polyline polyline = polylineOptions.getPolyline();
+ if (!polyline.getPoints().isEmpty()) {
+ long id = nativeMapView != null ? nativeMapView.addPolyline(polyline) : 0;
+ polyline.setMapboxMap(mapboxMap);
+ polyline.setId(id);
+ annotations.put(id, polyline);
+ }
+ return polyline;
+ }
+
+ List<Polyline> addPolylines(@NonNull List<PolylineOptions> polylineOptionsList, @NonNull MapboxMap mapboxMap) {
+ int count = polylineOptionsList.size();
+ Polyline polyline;
+ List<Polyline> polylines = new ArrayList<>(count);
+
+ if (count > 0) {
+ for (PolylineOptions options : polylineOptionsList) {
+ polyline = options.getPolyline();
+ if (!polyline.getPoints().isEmpty()) {
+ polylines.add(polyline);
+ }
+ }
+
+ long[] ids = null;
+ if (nativeMapView != null) {
+ ids = nativeMapView.addPolylines(polylines);
+ }
+
+ long id = 0;
+ Polyline p;
+
+ for (int i = 0; i < polylines.size(); i++) {
+ p = polylines.get(i);
+ p.setMapboxMap(mapboxMap);
+ if (ids != null) {
+ id = ids[i];
+ } else {
+ // unit test
+ id++;
+ }
+ p.setId(id);
+ annotations.put(id, p);
+ }
+ }
+ return polylines;
+ }
+
+ void updatePolyline(Polyline polyline) {
+ if (polyline == null) {
+ return;
+ }
+
+ if (polyline.getId() == -1) {
+ return;
+ }
+
+ nativeMapView.updatePolyline(polyline);
+
+ int index = annotations.indexOfKey(polyline.getId());
+ if (index > -1) {
+ annotations.setValueAt(index, polyline);
+ }
+ }
+
+ List<Polyline> getPolylines() {
+ List<Polyline> polylines = new ArrayList<>();
+ Annotation annotation;
+ for (int i = 0; i < annotations.size(); i++) {
+ annotation = annotations.get(annotations.keyAt(i));
+ if (annotation instanceof Polyline) {
+ polylines.add((Polyline) annotation);
+ }
+ }
+ return polylines;
+ }
+
+ InfoWindowManager getInfoWindowManager() {
+ return infoWindowManager;
+ }
+
+ MarkerViewManager getMarkerViewManager() {
+ return markerViewManager;
+ }
+
+ void adjustTopOffsetPixels(MapboxMap mapboxMap) {
+ int count = annotations.size();
+ for (int i = 0; i < count; i++) {
+ Annotation annotation = annotations.get(i);
+ if (annotation instanceof Marker) {
+ Marker marker = (Marker) annotation;
+ marker.setTopOffsetPixels(
+ iconManager.getTopOffsetPixelsForIcon(marker.getIcon()));
+ }
+ }
+
+ for (Marker marker : selectedMarkers) {
+ if (marker.isInfoWindowShown()) {
+ marker.hideInfoWindow();
+ marker.showInfoWindow(mapboxMap, mapView);
+ }
+ }
+ }
+
+ void reloadMarkers() {
+ iconManager.reloadIcons();
+ int count = annotations.size();
+ for (int i = 0; i < count; i++) {
+ Annotation annotation = annotations.get(i);
+ if (annotation instanceof Marker) {
+ Marker marker = (Marker) annotation;
+ nativeMapView.removeAnnotation(annotation.getId());
+ long newId = nativeMapView.addMarker(marker);
+ marker.setId(newId);
+ }
+ }
+ }
+
+ //
+ // Click event
+ //
+
+ boolean onTap(PointF tapPoint, float screenDensity) {
+ float toleranceSides = 4 * screenDensity;
+ float toleranceTopBottom = 10 * screenDensity;
+
+ RectF tapRect = new RectF(tapPoint.x - iconManager.getAverageIconWidth() / 2 - toleranceSides,
+ tapPoint.y - iconManager.getAverageIconHeight() / 2 - toleranceTopBottom,
+ tapPoint.x + iconManager.getAverageIconWidth() / 2 + toleranceSides,
+ tapPoint.y + iconManager.getAverageIconHeight() / 2 + toleranceTopBottom);
+
+ List<Marker> nearbyMarkers = getMarkersInRect(tapRect);
+ long newSelectedMarkerId = -1;
+
+ if (nearbyMarkers != null && nearbyMarkers.size() > 0) {
+ Collections.sort(nearbyMarkers);
+ for (Marker nearbyMarker : nearbyMarkers) {
+ boolean found = false;
+ for (Marker selectedMarker : selectedMarkers) {
+ if (selectedMarker.equals(nearbyMarker)) {
+ found = true;
+ }
+ }
+ if (!found) {
+ newSelectedMarkerId = nearbyMarker.getId();
+ break;
+ }
+ }
+ }
+
+ if (newSelectedMarkerId >= 0) {
+ List<Annotation> annotations = getAnnotations();
+ int count = annotations.size();
+ for (int i = 0; i < count; i++) {
+ Annotation annotation = annotations.get(i);
+ if (annotation instanceof Marker) {
+ if (annotation.getId() == newSelectedMarkerId) {
+ Marker marker = (Marker) annotation;
+ boolean handledDefaultClick = false;
+
+ if (marker instanceof MarkerView) {
+ handledDefaultClick = markerViewManager.onClickMarkerView((MarkerView) marker);
+ } else {
+ if (onMarkerClickListener != null) {
+ // end developer has provided a custom click listener
+ handledDefaultClick = onMarkerClickListener.onMarkerClick(marker);
+ }
+ }
+
+ if (annotation instanceof MarkerView) {
+ markerViewManager.onClickMarkerView((MarkerView) annotation);
+ } else {
+ if (!handledDefaultClick) {
+ // only select marker if user didn't handle the click event themselves
+ selectMarker(marker);
+ }
+ }
+
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CompassViewSettings.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CompassViewSettings.java
deleted file mode 100644
index 3e1b14d641..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CompassViewSettings.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.mapbox.mapboxsdk.maps;
-
-/**
- * Settings for the overlain views of a MapboxMap. Used by UiSettings.
- */
-class CompassViewSettings extends ViewSettings{
-
- private boolean fadeFacingNorth = true;
-
- public CompassViewSettings() {
- super();
- }
-
- public boolean isFadeFacingNorth() {
- return fadeFacingNorth;
- }
-
- public void setFadeFacingNorth(boolean fadeFacingNorth) {
- this.fadeFacingNorth = fadeFacingNorth;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/FocalPointChangeListener.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/FocalPointChangeListener.java
new file mode 100644
index 0000000000..006122a4e2
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/FocalPointChangeListener.java
@@ -0,0 +1,8 @@
+package com.mapbox.mapboxsdk.maps;
+
+import android.graphics.PointF;
+
+public interface FocalPointChangeListener {
+
+ void onFocalPointChanged(PointF pointF);
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/IconManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/IconManager.java
new file mode 100644
index 0000000000..c9d81a88bc
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/IconManager.java
@@ -0,0 +1,158 @@
+package com.mapbox.mapboxsdk.maps;
+
+import android.graphics.Bitmap;
+import android.util.DisplayMetrics;
+
+import com.mapbox.mapboxsdk.annotations.Icon;
+import com.mapbox.mapboxsdk.annotations.IconFactory;
+import com.mapbox.mapboxsdk.annotations.Marker;
+import com.mapbox.mapboxsdk.annotations.MarkerView;
+import com.mapbox.mapboxsdk.exceptions.IconBitmapChangedException;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Responsible for managing icons added to the Map.
+ * <p>
+ * Maintains a {@link List} of {@link Icon} and is responsible for initialising default markers and
+ * setting up {@link MarkerView} annotation ghosting.
+ * </p>
+ * <p>
+ * Keep track of icons added and the resulting average icon size. This is used internally by our
+ * gestures detection to calculate the size of a touch target.
+ * </p>
+ */
+class IconManager {
+
+ private NativeMapView nativeMapView;
+ private List<Icon> icons;
+
+ private int averageIconHeight;
+ private int averageIconWidth;
+
+ IconManager(NativeMapView nativeMapView) {
+ this.nativeMapView = nativeMapView;
+ this.icons = new ArrayList<>();
+ // load transparent icon for MarkerView to trace actual markers, see #6352
+ loadIcon(IconFactory.recreate(IconFactory.ICON_MARKERVIEW_ID, IconFactory.ICON_MARKERVIEW_BITMAP));
+ }
+
+ Icon loadIconForMarker(Marker marker) {
+ Icon icon = marker.getIcon();
+
+ // calculating average before adding
+ int iconSize = icons.size() + 1;
+
+ // TODO replace former if case with anchor implementation,
+ // current workaround for having extra pixels is diving height by 2
+ if (icon == null) {
+ icon = IconFactory.getInstance(nativeMapView.getContext()).defaultMarker();
+ Bitmap bitmap = icon.getBitmap();
+ averageIconHeight = averageIconHeight + (bitmap.getHeight() / 2 - averageIconHeight) / iconSize;
+ averageIconWidth = averageIconWidth + (bitmap.getWidth() - averageIconWidth) / iconSize;
+ marker.setIcon(icon);
+ } else {
+ Bitmap bitmap = icon.getBitmap();
+ averageIconHeight = averageIconHeight + (bitmap.getHeight() - averageIconHeight) / iconSize;
+ averageIconWidth = averageIconWidth + (bitmap.getWidth() - averageIconWidth) / iconSize;
+ }
+
+ if (!icons.contains(icon)) {
+ icons.add(icon);
+ loadIcon(icon);
+ } else {
+ Icon oldIcon = icons.get(icons.indexOf(icon));
+ if (!oldIcon.getBitmap().sameAs(icon.getBitmap())) {
+ throw new IconBitmapChangedException();
+ }
+ }
+ return icon;
+ }
+
+ Icon loadIconForMarkerView(MarkerView marker) {
+ Icon icon = marker.getIcon();
+ int iconSize = icons.size() + 1;
+ if (icon == null) {
+ icon = IconFactory.getInstance(nativeMapView.getContext()).defaultMarkerView();
+ marker.setIcon(icon);
+ }
+ Bitmap bitmap = icon.getBitmap();
+ averageIconHeight = averageIconHeight + (bitmap.getHeight() - averageIconHeight) / iconSize;
+ averageIconWidth = averageIconWidth + (bitmap.getWidth() - averageIconWidth) / iconSize;
+ if (!icons.contains(icon)) {
+ icons.add(icon);
+ } else {
+ Icon oldIcon = icons.get(icons.indexOf(icon));
+ if (!oldIcon.getBitmap().sameAs(icon.getBitmap())) {
+ throw new IconBitmapChangedException();
+ }
+ }
+ return icon;
+ }
+
+ int getTopOffsetPixelsForIcon(Icon icon) {
+ return (int) (nativeMapView.getTopOffsetPixelsForAnnotationSymbol(icon.getId()) * nativeMapView.getPixelRatio());
+ }
+
+ void loadIcon(Icon icon) {
+ Bitmap bitmap = icon.getBitmap();
+ String id = icon.getId();
+ if (bitmap.getConfig() != Bitmap.Config.ARGB_8888) {
+ bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, false);
+ }
+ ByteBuffer buffer = ByteBuffer.allocate(bitmap.getRowBytes() * bitmap.getHeight());
+ bitmap.copyPixelsToBuffer(buffer);
+
+ float density = bitmap.getDensity();
+ if (density == Bitmap.DENSITY_NONE) {
+ density = DisplayMetrics.DENSITY_DEFAULT;
+ }
+ float scale = density / DisplayMetrics.DENSITY_DEFAULT;
+ nativeMapView.addAnnotationIcon(
+ id,
+ bitmap.getWidth(),
+ bitmap.getHeight(),
+ scale, buffer.array());
+ }
+
+ void reloadIcons() {
+ int count = icons.size();
+ for (int i = 0; i < count; i++) {
+ Icon icon = icons.get(i);
+ loadIcon(icon);
+ }
+ }
+
+ void ensureIconLoaded(Marker marker, MapboxMap mapboxMap) {
+ Icon icon = marker.getIcon();
+ if (icon == null) {
+ icon = IconFactory.getInstance(nativeMapView.getContext()).defaultMarker();
+ marker.setIcon(icon);
+ }
+ if (!icons.contains(icon)) {
+ icons.add(icon);
+ loadIcon(icon);
+ } else {
+ Icon oldIcon = icons.get(icons.indexOf(icon));
+ if (!oldIcon.getBitmap().sameAs(icon.getBitmap())) {
+ throw new IconBitmapChangedException();
+ }
+ }
+
+ // this seems to be a costly operation according to the profiler so I'm trying to save some calls
+ Marker previousMarker = marker.getId() != -1 ? (Marker) mapboxMap.getAnnotation(marker.getId()) : null;
+ if (previousMarker == null || previousMarker.getIcon() == null || previousMarker.getIcon() != marker.getIcon()) {
+ marker.setTopOffsetPixels(getTopOffsetPixelsForIcon(icon));
+ }
+ }
+
+ int getAverageIconHeight() {
+ return averageIconHeight;
+ }
+
+ int getAverageIconWidth() {
+ return averageIconWidth;
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/InfoWindowManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/InfoWindowManager.java
new file mode 100644
index 0000000000..7599b6afa6
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/InfoWindowManager.java
@@ -0,0 +1,94 @@
+package com.mapbox.mapboxsdk.maps;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.text.TextUtils;
+
+import com.mapbox.mapboxsdk.annotations.InfoWindow;
+import com.mapbox.mapboxsdk.annotations.Marker;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Responsible for managing InfoWindows shown on the Map.
+ * <p>
+ * Maintains a {@link List} of opened {@link InfoWindow} and tracks configurations as
+ * allowConcurrentMultipleInfoWindows which allows to have multiple {@link InfoWindow} open at the
+ * same time. Responsible for managing listeners as
+ * {@link com.mapbox.mapboxsdk.maps.MapboxMap.OnInfoWindowClickListener} and
+ * {@link com.mapbox.mapboxsdk.maps.MapboxMap.OnInfoWindowLongClickListener}.
+ * </p>
+ */
+class InfoWindowManager {
+
+ private List<InfoWindow> infoWindows;
+ private MapboxMap.InfoWindowAdapter infoWindowAdapter;
+ private boolean allowConcurrentMultipleInfoWindows;
+
+ private MapboxMap.OnInfoWindowClickListener onInfoWindowClickListener;
+ private MapboxMap.OnInfoWindowLongClickListener onInfoWindowLongClickListener;
+ private MapboxMap.OnInfoWindowCloseListener onInfoWindowCloseListener;
+
+ InfoWindowManager() {
+ this.infoWindows = new ArrayList<>();
+ }
+
+ void update() {
+ for (InfoWindow infoWindow : infoWindows) {
+ infoWindow.update();
+ }
+ }
+
+ void setInfoWindowAdapter(@Nullable MapboxMap.InfoWindowAdapter infoWindowAdapter) {
+ this.infoWindowAdapter = infoWindowAdapter;
+ }
+
+ MapboxMap.InfoWindowAdapter getInfoWindowAdapter() {
+ return infoWindowAdapter;
+ }
+
+ void setAllowConcurrentMultipleOpenInfoWindows(boolean allow) {
+ allowConcurrentMultipleInfoWindows = allow;
+ }
+
+ boolean isAllowConcurrentMultipleOpenInfoWindows() {
+ return allowConcurrentMultipleInfoWindows;
+ }
+
+ List<InfoWindow> getInfoWindows() {
+ return infoWindows;
+ }
+
+ boolean isInfoWindowValidForMarker(@NonNull Marker marker) {
+ return !TextUtils.isEmpty(marker.getTitle()) || !TextUtils.isEmpty(marker.getSnippet());
+ }
+
+ void setOnInfoWindowClickListener(@Nullable MapboxMap.OnInfoWindowClickListener listener) {
+ onInfoWindowClickListener = listener;
+ }
+
+ MapboxMap.OnInfoWindowClickListener getOnInfoWindowClickListener() {
+ return onInfoWindowClickListener;
+ }
+
+ void setOnInfoWindowLongClickListener(@Nullable MapboxMap.OnInfoWindowLongClickListener listener) {
+ onInfoWindowLongClickListener = listener;
+ }
+
+ MapboxMap.OnInfoWindowLongClickListener getOnInfoWindowLongClickListener() {
+ return onInfoWindowLongClickListener;
+ }
+
+ void setOnInfoWindowCloseListener(@Nullable MapboxMap.OnInfoWindowCloseListener listener) {
+ onInfoWindowCloseListener = listener;
+ }
+
+ MapboxMap.OnInfoWindowCloseListener getOnInfoWindowCloseListener() {
+ return onInfoWindowCloseListener;
+ }
+
+ public void add(InfoWindow infoWindow) {
+ infoWindows.add(infoWindow);
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapFragment.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapFragment.java
index 22f42c1d51..23827fa404 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapFragment.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapFragment.java
@@ -2,22 +2,17 @@ package com.mapbox.mapboxsdk.maps;
import android.app.Fragment;
import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
-import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import com.mapbox.mapboxsdk.MapboxAccountManager;
import com.mapbox.mapboxsdk.R;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
-import com.mapbox.mapboxsdk.exceptions.InvalidAccessTokenException;
/**
* Fragment wrapper around a map view.
@@ -35,194 +30,146 @@ import com.mapbox.mapboxsdk.exceptions.InvalidAccessTokenException;
*/
public final class MapFragment extends Fragment {
- private MapView map;
- private OnMapReadyCallback onMapReadyCallback;
-
- /**
- * Creates a MapFragment instance
- *
- * @param mapboxMapOptions The configuration options to be used.
- * @return MapFragment created.
- */
- public static MapFragment newInstance(@Nullable MapboxMapOptions mapboxMapOptions) {
- MapFragment mapFragment = new MapFragment();
- Bundle bundle = new Bundle();
- bundle.putParcelable(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS, mapboxMapOptions);
- mapFragment.setArguments(bundle);
- return mapFragment;
+ private MapView map;
+ private OnMapReadyCallback onMapReadyCallback;
+
+ /**
+ * Creates a MapFragment instance
+ *
+ * @param mapboxMapOptions The configuration options to be used.
+ * @return MapFragment created.
+ */
+ public static MapFragment newInstance(@Nullable MapboxMapOptions mapboxMapOptions) {
+ MapFragment mapFragment = new MapFragment();
+ Bundle bundle = new Bundle();
+ bundle.putParcelable(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS, mapboxMapOptions);
+ mapFragment.setArguments(bundle);
+ return mapFragment;
+ }
+
+ /**
+ * Creates the fragment view hierarchy.
+ *
+ * @param inflater Inflater used to inflate content.
+ * @param container The parent layout for the map fragment.
+ * @param savedInstanceState The saved instance state for the map fragment.
+ * @return The view created
+ */
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ Context context = inflater.getContext();
+ MapboxMapOptions options = null;
+
+ // Get bundle
+ Bundle bundle = getArguments();
+ if (bundle != null && bundle.containsKey(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS)) {
+ options = bundle.getParcelable(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS);
}
- /**
- * Creates the fragment view hierarchy.
- *
- * @param inflater Inflater used to inflate content.
- * @param container The parent layout for the map fragment.
- * @param savedInstanceState The saved instance state for the map fragment.
- * @return The view created
- */
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- super.onCreateView(inflater, container, savedInstanceState);
- Context context = inflater.getContext();
- MapboxMapOptions options = null;
-
- // Get bundle
- Bundle bundle = getArguments();
- if (bundle != null && bundle.containsKey(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS)) {
- options = bundle.getParcelable(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS);
- }
-
- // Assign an AccessToken if needed
- if (options == null || options.getAccessToken() == null) {
- String token = null;
- if (MapboxAccountManager.getInstance() != null) {
- token = MapboxAccountManager.getInstance().getAccessToken();
- } else {
- token = getToken(inflater.getContext());
- }
- if (TextUtils.isEmpty(token)) {
- throw new InvalidAccessTokenException();
- }
- if (options == null) {
- options = new MapboxMapOptions().accessToken(token);
- } else {
- options.accessToken(token);
- }
- }
-
- Drawable foregroundDrawable = options.getMyLocationForegroundDrawable();
- Drawable foregroundBearingDrawable = options.getMyLocationForegroundBearingDrawable();
- if (foregroundDrawable == null || foregroundBearingDrawable == null) {
- if (foregroundDrawable == null) {
- foregroundDrawable = ContextCompat.getDrawable(context, R.drawable.ic_mylocationview_normal);
- }
- if (foregroundBearingDrawable == null) {
- foregroundBearingDrawable = ContextCompat.getDrawable(context, R.drawable.ic_mylocationview_bearing);
- }
- options.myLocationForegroundDrawables(foregroundDrawable, foregroundBearingDrawable);
- }
-
- if (options.getMyLocationBackgroundDrawable() == null) {
- options.myLocationBackgroundDrawable(ContextCompat.getDrawable(context, R.drawable.ic_mylocationview_background));
- }
-
- return map = new MapView(inflater.getContext(), options);
+ Drawable foregroundDrawable = options.getMyLocationForegroundDrawable();
+ Drawable foregroundBearingDrawable = options.getMyLocationForegroundBearingDrawable();
+ if (foregroundDrawable == null || foregroundBearingDrawable == null) {
+ if (foregroundDrawable == null) {
+ foregroundDrawable = ContextCompat.getDrawable(context, R.drawable.mapbox_mylocation_icon_default);
+ }
+ if (foregroundBearingDrawable == null) {
+ foregroundBearingDrawable = ContextCompat.getDrawable(context, R.drawable.mapbox_mylocation_icon_bearing);
+ }
+ options.myLocationForegroundDrawables(foregroundDrawable, foregroundBearingDrawable);
}
- /**
- * <p>
- * Returns the Mapbox access token set in the app resources.
- * </p>
- * It will first search the application manifest for a {@link MapboxConstants#KEY_META_DATA_MANIFEST}
- * meta-data value. If not found it will then attempt to load the access token from the
- * {@code res/raw/token.txt} development file.
- *
- * @param context The {@link Context} of the {@link android.app.Activity} or {@link android.app.Fragment}.
- * @return The Mapbox access token or null if not found.
- * @see MapboxConstants#KEY_META_DATA_MANIFEST
- *
- * @deprecated As of release 4.1.0, replaced by {@link com.mapbox.mapboxsdk.MapboxAccountManager#start(Context, String)}
- */
- @Deprecated
- private String getToken(@NonNull Context context) {
- try {
- // read out AndroidManifest
- PackageManager packageManager = context.getPackageManager();
- ApplicationInfo appInfo = packageManager.getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
- String token = appInfo.metaData.getString(MapboxConstants.KEY_META_DATA_MANIFEST);
- if (token == null || token.isEmpty()) {
- throw new IllegalArgumentException();
- }
- return token;
- } catch (Exception e) {
- // use fallback on string resource, used for development
- int tokenResId = context.getResources().getIdentifier("mapbox_access_token", "string", context.getPackageName());
- return tokenResId != 0 ? context.getString(tokenResId) : null;
- }
+ if (options.getMyLocationBackgroundDrawable() == null) {
+ options.myLocationBackgroundDrawable(ContextCompat.getDrawable(context, R.drawable.mapbox_mylocation_bg_shape));
}
- /**
- * Called when the fragment view hierarchy is created.
- *
- * @param view The content view of the fragment
- * @param savedInstanceState THe saved instance state of the framgnt
- */
- @Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- map.onCreate(savedInstanceState);
- }
-
- /**
- * Called when the fragment is visible for the users.
- */
- @Override
- public void onStart() {
- super.onStart();
- map.getMapAsync(onMapReadyCallback);
- }
-
- /**
- * Called when the fragment is ready to be interacted with.
- */
- @Override
- public void onResume() {
- super.onResume();
- map.onResume();
- }
-
- /**
- * Called when the fragment is pausing.
- */
- @Override
- public void onPause() {
- super.onPause();
- map.onPause();
- }
-
- /**
- * Called when the fragment state needs to be saved.
- *
- * @param outState The saved state
- */
- @Override
- public void onSaveInstanceState(@NonNull Bundle outState) {
- super.onSaveInstanceState(outState);
- map.onSaveInstanceState(outState);
- }
-
- /**
- * Called when the fragment is no longer visible for the user.
- */
- @Override
- public void onStop() {
- super.onStop();
- }
-
- /**
- * Called when the fragment receives onLowMemory call from the hosting Activity.
- */
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- map.onLowMemory();
- }
-
- /**
- * Called when the fragment is view hiearchy is being destroyed.
- */
- @Override
- public void onDestroyView() {
- super.onDestroyView();
- map.onDestroy();
- }
-
- /**
- * Sets a callback object which will be triggered when the MapboxMap instance is ready to be used.
- *
- * @param onMapReadyCallback The callback to be invoked.
- */
- public void getMapAsync(@NonNull final OnMapReadyCallback onMapReadyCallback) {
- this.onMapReadyCallback = onMapReadyCallback;
- }
+ return map = new MapView(inflater.getContext(), options);
+ }
+
+ /**
+ * Called when the fragment view hierarchy is created.
+ *
+ * @param view The content view of the fragment
+ * @param savedInstanceState THe saved instance state of the framgnt
+ */
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ map.onCreate(savedInstanceState);
+ }
+
+ /**
+ * Called when the fragment is visible for the users.
+ */
+ @Override
+ public void onStart() {
+ super.onStart();
+ map.onStart();
+ map.getMapAsync(onMapReadyCallback);
+ }
+
+ /**
+ * Called when the fragment is ready to be interacted with.
+ */
+ @Override
+ public void onResume() {
+ super.onResume();
+ map.onResume();
+ }
+
+ /**
+ * Called when the fragment is pausing.
+ */
+ @Override
+ public void onPause() {
+ super.onPause();
+ map.onPause();
+ }
+
+ /**
+ * Called when the fragment state needs to be saved.
+ *
+ * @param outState The saved state
+ */
+ @Override
+ public void onSaveInstanceState(@NonNull Bundle outState) {
+ super.onSaveInstanceState(outState);
+ map.onSaveInstanceState(outState);
+ }
+
+ /**
+ * Called when the fragment is no longer visible for the user.
+ */
+ @Override
+ public void onStop() {
+ super.onStop();
+ map.onStop();
+ }
+
+ /**
+ * Called when the fragment receives onLowMemory call from the hosting Activity.
+ */
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ map.onLowMemory();
+ }
+
+ /**
+ * Called when the fragment is view hiearchy is being destroyed.
+ */
+ @Override
+ public void onDestroyView() {
+ super.onDestroyView();
+ map.onDestroy();
+ }
+
+ /**
+ * Sets a callback object which will be triggered when the MapboxMap instance is ready to be used.
+ *
+ * @param onMapReadyCallback The callback to be invoked.
+ */
+ public void getMapAsync(@NonNull final OnMapReadyCallback onMapReadyCallback) {
+ this.onMapReadyCallback = onMapReadyCallback;
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java
new file mode 100644
index 0000000000..93422b1837
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java
@@ -0,0 +1,636 @@
+package com.mapbox.mapboxsdk.maps;
+
+import android.content.Context;
+import android.graphics.PointF;
+import android.support.annotation.NonNull;
+import android.support.v4.view.GestureDetectorCompat;
+import android.support.v4.view.ScaleGestureDetectorCompat;
+import android.view.InputDevice;
+import android.view.MotionEvent;
+import android.view.ScaleGestureDetector;
+import android.view.ViewConfiguration;
+import android.widget.ZoomButtonsController;
+
+import com.almeros.android.multitouch.gesturedetectors.RotateGestureDetector;
+import com.almeros.android.multitouch.gesturedetectors.ShoveGestureDetector;
+import com.almeros.android.multitouch.gesturedetectors.TwoFingerGestureDetector;
+import com.mapbox.mapboxsdk.constants.MapboxConstants;
+import com.mapbox.mapboxsdk.telemetry.MapboxEvent;
+
+/**
+ * Manages gestures events on a MapView.
+ * <p>
+ * Relies on gesture detection code in almeros.android.multitouch.gesturedetectors.
+ * </p>
+ */
+final class MapGestureDetector {
+
+ private final Transform transform;
+ private final Projection projection;
+ private final UiSettings uiSettings;
+ private final TrackingSettings trackingSettings;
+ private final AnnotationManager annotationManager;
+
+ private final GestureDetectorCompat gestureDetector;
+ private final ScaleGestureDetector scaleGestureDetector;
+ private final RotateGestureDetector rotateGestureDetector;
+ private final ShoveGestureDetector shoveGestureDetector;
+
+ private MapboxMap.OnMapClickListener onMapClickListener;
+ private MapboxMap.OnMapLongClickListener onMapLongClickListener;
+ private MapboxMap.OnFlingListener onFlingListener;
+ private MapboxMap.OnScrollListener onScrollListener;
+
+ private PointF focalPoint;
+
+ private boolean twoTap = false;
+ private boolean zoomStarted = false;
+ private boolean dragStarted = false;
+ private boolean quickZoom = false;
+ private boolean scrollInProgress = false;
+
+ MapGestureDetector(Context context, Transform transform, Projection projection, UiSettings uiSettings,
+ TrackingSettings trackingSettings, AnnotationManager annotationManager) {
+ this.annotationManager = annotationManager;
+ this.transform = transform;
+ this.projection = projection;
+ this.uiSettings = uiSettings;
+ this.trackingSettings = trackingSettings;
+
+ // Touch gesture detectors
+ gestureDetector = new GestureDetectorCompat(context, new GestureListener());
+ gestureDetector.setIsLongpressEnabled(true);
+ scaleGestureDetector = new ScaleGestureDetector(context, new ScaleGestureListener());
+ ScaleGestureDetectorCompat.setQuickScaleEnabled(scaleGestureDetector, true);
+ rotateGestureDetector = new RotateGestureDetector(context, new RotateGestureListener());
+ shoveGestureDetector = new ShoveGestureDetector(context, new ShoveGestureListener());
+ }
+
+ /**
+ * Set the gesture focal point.
+ * <p>
+ * this is the center point used for calculate transformations from gestures, value is
+ * overridden if end user provides his own through {@link UiSettings#setFocalPoint(PointF)}.
+ * </p>
+ *
+ * @param focalPoint the center point for gestures
+ */
+ void setFocalPoint(PointF focalPoint) {
+ if (focalPoint == null) {
+ // resetting focal point,
+ if (uiSettings.getFocalPoint() != null) {
+ // using user provided one to reset
+ focalPoint = uiSettings.getFocalPoint();
+ }
+ }
+ this.focalPoint = focalPoint;
+ }
+
+
+ /**
+ * Called when user touches the screen, all positions are absolute.
+ * <p>
+ * Forwards event to the related gesture detectors.
+ * </p>
+ *
+ * @param event the MotionEvent
+ * @return True if touch event is handled
+ */
+ boolean onTouchEvent(@NonNull MotionEvent event) {
+ // Check and ignore non touch or left clicks
+ if ((event.getButtonState() != 0) && (event.getButtonState() != MotionEvent.BUTTON_PRIMARY)) {
+ return false;
+ }
+
+ // Check two finger gestures first
+ rotateGestureDetector.onTouchEvent(event);
+ scaleGestureDetector.onTouchEvent(event);
+ shoveGestureDetector.onTouchEvent(event);
+
+ // Handle two finger tap
+ switch (event.getActionMasked()) {
+ case MotionEvent.ACTION_DOWN:
+ // First pointer down
+ transform.setGestureInProgress(true);
+ break;
+
+ case MotionEvent.ACTION_POINTER_DOWN:
+ // Second pointer down
+ twoTap = event.getPointerCount() == 2
+ && uiSettings.isZoomGesturesEnabled();
+ if (twoTap) {
+ // Confirmed 2nd Finger Down
+ MapboxEvent.trackGestureEvent(projection,
+ MapboxEvent.GESTURE_TWO_FINGER_SINGLETAP, event.getX(), event.getY(), transform.getZoom());
+ }
+ break;
+
+ case MotionEvent.ACTION_POINTER_UP:
+ // Second pointer up
+ break;
+
+ case MotionEvent.ACTION_UP:
+ // First pointer up
+ long tapInterval = event.getEventTime() - event.getDownTime();
+ boolean isTap = tapInterval <= ViewConfiguration.getTapTimeout();
+ boolean inProgress = rotateGestureDetector.isInProgress()
+ || scaleGestureDetector.isInProgress()
+ || shoveGestureDetector.isInProgress();
+
+ if (twoTap && isTap && !inProgress) {
+ if (focalPoint != null) {
+ transform.zoom(false, focalPoint.x, focalPoint.y);
+ } else {
+ PointF focalPoint = TwoFingerGestureDetector.determineFocalPoint(event);
+ transform.zoom(false, focalPoint.x, focalPoint.y);
+ }
+ twoTap = false;
+ return true;
+ }
+
+ // Scroll / Pan Has Stopped
+ if (scrollInProgress) {
+ MapboxEvent.trackGestureDragEndEvent(projection, event.getX(), event.getY(), transform.getZoom());
+ scrollInProgress = false;
+ }
+
+ twoTap = false;
+ transform.setGestureInProgress(false);
+ break;
+
+ case MotionEvent.ACTION_CANCEL:
+ twoTap = false;
+ transform.setGestureInProgress(false);
+ break;
+ }
+
+ return gestureDetector.onTouchEvent(event);
+ }
+
+ /**
+ * Called for events that don't fit the other handlers.
+ * <p>
+ * Examples of such events are mouse scroll events, mouse moves, joystick & trackpad.
+ * </p>
+ *
+ * @param event The MotionEvent occured
+ * @return True is the event is handled
+ */
+ boolean onGenericMotionEvent(MotionEvent event) {
+ // Mouse events
+ //if (event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) { // this is not available before API 18
+ if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == InputDevice.SOURCE_CLASS_POINTER) {
+ // Choose the action
+ switch (event.getActionMasked()) {
+ // Mouse scrolls
+ case MotionEvent.ACTION_SCROLL:
+ if (!uiSettings.isZoomGesturesEnabled()) {
+ return false;
+ }
+
+ // Cancel any animation
+ transform.cancelTransitions();
+
+ // Get the vertical scroll amount, one click = 1
+ float scrollDist = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
+
+ // Scale the map by the appropriate power of two factor
+ transform.zoomBy(Math.pow(2.0, scrollDist), event.getX(), event.getY());
+
+ return true;
+
+ default:
+ // We are not interested in this event
+ return false;
+ }
+ }
+
+ // We are not interested in this event
+ return false;
+ }
+
+
+ /**
+ * Responsible for handling one finger gestures.
+ */
+ private class GestureListener extends android.view.GestureDetector.SimpleOnGestureListener {
+
+ @Override
+ public boolean onDown(MotionEvent event) {
+ return true;
+ }
+
+ @Override
+ public boolean onDoubleTapEvent(MotionEvent e) {
+ if (!uiSettings.isZoomGesturesEnabled()) {
+ return false;
+ }
+
+ switch (e.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ break;
+ case MotionEvent.ACTION_MOVE:
+ break;
+ case MotionEvent.ACTION_UP:
+ if (quickZoom) {
+ // insert here?
+ quickZoom = false;
+ break;
+ }
+
+ // Single finger double tap
+ if (focalPoint != null) {
+ // User provided focal point
+ transform.zoom(true, focalPoint.x, focalPoint.y);
+ } else {
+ // Zoom in on gesture
+ transform.zoom(true, e.getX(), e.getY());
+ }
+ break;
+ }
+
+ MapboxEvent.trackGestureEvent(projection, MapboxEvent.GESTURE_DOUBLETAP, e.getX(), e.getY(), transform.getZoom());
+
+ return true;
+ }
+
+ @Override
+ public boolean onSingleTapUp(MotionEvent motionEvent) {
+ // Cancel any animation
+ transform.cancelTransitions();
+ return true;
+ }
+
+ @Override
+ public boolean onSingleTapConfirmed(MotionEvent motionEvent) {
+ PointF tapPoint = new PointF(motionEvent.getX(), motionEvent.getY());
+ boolean tapHandled = annotationManager.onTap(tapPoint, uiSettings.getPixelRatio());
+
+ if (!tapHandled) {
+ if (uiSettings.isDeselectMarkersOnTap()) {
+ // deselect any selected marker
+ annotationManager.deselectMarkers();
+ }
+
+ // notify app of map click
+ if (onMapClickListener != null) {
+ onMapClickListener.onMapClick(projection.fromScreenLocation(tapPoint));
+ }
+ }
+
+ MapboxEvent.trackGestureEvent(projection,
+ MapboxEvent.GESTURE_SINGLETAP, motionEvent.getX(), motionEvent.getY(), transform.getZoom());
+ return true;
+ }
+
+ @Override
+ public void onLongPress(MotionEvent motionEvent) {
+ if (onMapLongClickListener != null && !quickZoom) {
+ onMapLongClickListener.onMapLongClick(
+ projection.fromScreenLocation(new PointF(motionEvent.getX(), motionEvent.getY())));
+ }
+ }
+
+ @Override
+ public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
+ if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
+ return false;
+ }
+
+ trackingSettings.resetTrackingModesIfRequired(true, false);
+
+ // Cancel any animation
+ transform.cancelTransitions();
+
+ float screenDensity = uiSettings.getPixelRatio();
+
+ double tilt = transform.getTilt();
+ // tilt results in a bigger translation, need to limit input #5281, limitFactor ranges from 2 -> 8
+ double limitFactor = 2 + ((tilt != 0) ? (tilt / 10) : 0);
+ double offsetX = velocityX / limitFactor / screenDensity;
+ double offsetY = velocityY / limitFactor / screenDensity;
+
+ transform.setGestureInProgress(true);
+ transform.moveBy(offsetX, offsetY, MapboxConstants.ANIMATION_DURATION_FLING);
+ transform.setGestureInProgress(false);
+
+ if (onFlingListener != null) {
+ onFlingListener.onFling();
+ }
+
+ MapboxEvent.trackGestureEvent(projection,
+ MapboxEvent.GESTURE_PAN_START, e1.getX(), e1.getY(), transform.getZoom());
+ return true;
+ }
+
+ // Called for drags
+ @Override
+ public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
+ if (!scrollInProgress) {
+ scrollInProgress = true;
+ }
+ if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
+ return false;
+ }
+
+ if (dragStarted) {
+ return false;
+ }
+
+ // reset tracking if needed
+ trackingSettings.resetTrackingModesIfRequired(true, false);
+ // Cancel any animation
+ transform.cancelTransitions();
+
+ // Scroll the map
+ transform.moveBy(-distanceX, -distanceY, 0 /*no duration*/);
+
+ if (onScrollListener != null) {
+ onScrollListener.onScroll();
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Responsible for handling two finger gestures and double-tap drag gestures.
+ */
+ private class ScaleGestureListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
+
+ long beginTime = 0;
+ float scaleFactor = 1.0f;
+
+ // Called when two fingers first touch the screen
+ @Override
+ public boolean onScaleBegin(ScaleGestureDetector detector) {
+ if (!uiSettings.isZoomGesturesEnabled()) {
+ return false;
+ }
+
+ beginTime = detector.getEventTime();
+ MapboxEvent.trackGestureEvent(projection,
+ MapboxEvent.GESTURE_PINCH_START, detector.getFocusX(), detector.getFocusY(), transform.getZoom());
+ return true;
+ }
+
+ // Called when fingers leave screen
+ @Override
+ public void onScaleEnd(ScaleGestureDetector detector) {
+ beginTime = 0;
+ scaleFactor = 1.0f;
+ zoomStarted = false;
+ }
+
+ // Called each time a finger moves
+ // Called for pinch zooms and quickzooms/quickscales
+ @Override
+ public boolean onScale(ScaleGestureDetector detector) {
+ if (!uiSettings.isZoomGesturesEnabled()) {
+ return super.onScale(detector);
+ }
+
+ // If scale is large enough ignore a tap
+ scaleFactor *= detector.getScaleFactor();
+ if ((scaleFactor > 1.05f) || (scaleFactor < 0.95f)) {
+ zoomStarted = true;
+ }
+
+ // Ignore short touches in case it is a tap
+ // Also ignore small scales
+ long time = detector.getEventTime();
+ long interval = time - beginTime;
+ if (!zoomStarted && (interval <= ViewConfiguration.getTapTimeout())) {
+ return false;
+ }
+
+ if (!zoomStarted) {
+ return false;
+ }
+
+ if (dragStarted) {
+ return false;
+ }
+
+ // Cancel any animation
+ transform.cancelTransitions();
+
+ // Gesture is a quickzoom if there aren't two fingers
+ quickZoom = !twoTap;
+
+ // make an assumption here; if the zoom center is specified by the gesture, it's NOT going
+ // to be in the center of the map. Therefore the zoom will translate the map center, so tracking
+ // should be disabled.
+
+ trackingSettings.resetTrackingModesIfRequired(!quickZoom, false);
+ // Scale the map
+ if (focalPoint != null) {
+ // arround user provided focal point
+ transform.zoomBy(detector.getScaleFactor(), focalPoint.x, focalPoint.y);
+ } else if (quickZoom) {
+ // around center map
+ transform.zoomBy(detector.getScaleFactor(), uiSettings.getWidth() / 2, uiSettings.getHeight() / 2);
+ } else {
+ // around gesture
+ transform.zoomBy(detector.getScaleFactor(), detector.getFocusX(), detector.getFocusY());
+ }
+
+ return true;
+ }
+ }
+
+ /**
+ * Responsible for handling rotation gestures.
+ */
+ private class RotateGestureListener extends RotateGestureDetector.SimpleOnRotateGestureListener {
+
+ long beginTime = 0;
+ float totalAngle = 0.0f;
+ boolean started = false;
+
+ // Called when two fingers first touch the screen
+ @Override
+ public boolean onRotateBegin(RotateGestureDetector detector) {
+ if (!trackingSettings.isRotateGestureCurrentlyEnabled()) {
+ return false;
+ }
+
+ beginTime = detector.getEventTime();
+ MapboxEvent.trackGestureEvent(projection,
+ MapboxEvent.GESTURE_ROTATION_START, detector.getFocusX(), detector.getFocusY(), transform.getZoom());
+ return true;
+ }
+
+ // Called when the fingers leave the screen
+ @Override
+ public void onRotateEnd(RotateGestureDetector detector) {
+ beginTime = 0;
+ totalAngle = 0.0f;
+ started = false;
+ }
+
+ // Called each time one of the two fingers moves
+ // Called for rotation
+ @Override
+ public boolean onRotate(RotateGestureDetector detector) {
+ if (!trackingSettings.isRotateGestureCurrentlyEnabled() || dragStarted) {
+ return false;
+ }
+
+ // If rotate is large enough ignore a tap
+ // Also is zoom already started, don't rotate
+ totalAngle += detector.getRotationDegreesDelta();
+ if (!zoomStarted && ((totalAngle > 20.0f) || (totalAngle < -20.0f))) {
+ started = true;
+ }
+
+ // Ignore short touches in case it is a tap
+ // Also ignore small rotate
+ long time = detector.getEventTime();
+ long interval = time - beginTime;
+ if (!started && (interval <= ViewConfiguration.getTapTimeout())) {
+ return false;
+ }
+
+ if (!started) {
+ return false;
+ }
+
+ // Cancel any animation
+ transform.cancelTransitions();
+
+ // rotation constitutes translation of anything except the center of
+ // rotation, so cancel both location and bearing tracking if required
+
+ trackingSettings.resetTrackingModesIfRequired(true, true);
+
+ // Get rotate value
+ double bearing = transform.getRawBearing();
+ bearing += detector.getRotationDegreesDelta();
+
+ // Rotate the map
+ if (focalPoint != null) {
+ // User provided focal point
+ transform.setBearing(bearing, focalPoint.x, focalPoint.y);
+ } else {
+ // around gesture
+ transform.setBearing(bearing, detector.getFocusX(), detector.getFocusY());
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Responsible for handling 2 finger shove gestures.
+ */
+ private class ShoveGestureListener implements ShoveGestureDetector.OnShoveGestureListener {
+
+ long beginTime = 0;
+ float totalDelta = 0.0f;
+ boolean started = false;
+
+ @Override
+ public boolean onShoveBegin(ShoveGestureDetector detector) {
+ if (!uiSettings.isTiltGesturesEnabled()) {
+ return false;
+ }
+
+ beginTime = detector.getEventTime();
+ MapboxEvent.trackGestureEvent(projection,
+ MapboxEvent.GESTURE_PITCH_START, detector.getFocusX(), detector.getFocusY(), transform.getZoom());
+ return true;
+ }
+
+ @Override
+ public void onShoveEnd(ShoveGestureDetector detector) {
+ beginTime = 0;
+ totalDelta = 0.0f;
+ started = false;
+ dragStarted = false;
+ }
+
+ @Override
+ public boolean onShove(ShoveGestureDetector detector) {
+ if (!uiSettings.isTiltGesturesEnabled()) {
+ return false;
+ }
+
+ // If tilt is large enough ignore a tap
+ // Also if zoom already started, don't tilt
+ totalDelta += detector.getShovePixelsDelta();
+ if (!zoomStarted && ((totalDelta > 10.0f) || (totalDelta < -10.0f))) {
+ started = true;
+ }
+
+ // Ignore short touches in case it is a tap
+ // Also ignore small tilt
+ long time = detector.getEventTime();
+ long interval = time - beginTime;
+ if (!started && (interval <= ViewConfiguration.getTapTimeout())) {
+ return false;
+ }
+
+ if (!started) {
+ return false;
+ }
+
+ // Cancel any animation
+ transform.cancelTransitions();
+
+ // Get tilt value (scale and clamp)
+ double pitch = transform.getTilt();
+ pitch -= 0.1 * detector.getShovePixelsDelta();
+ pitch = Math.max(MapboxConstants.MINIMUM_TILT, Math.min(MapboxConstants.MAXIMUM_TILT, pitch));
+
+ // Tilt the map
+ transform.setTilt(pitch);
+
+ dragStarted = true;
+
+ return true;
+ }
+ }
+
+ // This class handles input events from the zoom control buttons
+ // Zoom controls allow single touch only devices to zoom in and out
+ private static class OnZoomListener implements ZoomButtonsController.OnZoomListener {
+
+ private UiSettings uiSettings;
+ private Transform transform;
+
+ OnZoomListener(UiSettings uiSettings, Transform transform) {
+ this.uiSettings = uiSettings;
+ this.transform = transform;
+ }
+
+ // Not used
+ @Override
+ public void onVisibilityChanged(boolean visible) {
+ // Ignore
+ }
+
+ // Called when user pushes a zoom button
+ @Override
+ public void onZoom(boolean zoomIn) {
+ if (!uiSettings.isZoomGesturesEnabled()) {
+ return;
+ }
+ transform.zoom(zoomIn);
+ }
+ }
+
+ void setOnMapClickListener(MapboxMap.OnMapClickListener onMapClickListener) {
+ this.onMapClickListener = onMapClickListener;
+ }
+
+ void setOnMapLongClickListener(MapboxMap.OnMapLongClickListener onMapLongClickListener) {
+ this.onMapLongClickListener = onMapLongClickListener;
+ }
+
+ void setOnFlingListener(MapboxMap.OnFlingListener onFlingListener) {
+ this.onFlingListener = onFlingListener;
+ }
+
+ void setOnScrollListener(MapboxMap.OnScrollListener onScrollListener) {
+ this.onScrollListener = onScrollListener;
+ }
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapKeyListener.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapKeyListener.java
new file mode 100644
index 0000000000..c993cd3ec6
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapKeyListener.java
@@ -0,0 +1,265 @@
+package com.mapbox.mapboxsdk.maps;
+
+import android.os.Handler;
+import android.support.annotation.NonNull;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.ViewConfiguration;
+
+/**
+ * Manages key events on a MapView.
+ * <p>
+ * <ul>
+ * <li> Uses {@link Transform} to change the map state</li>
+ * <li> Uses {@link TrackingSettings} to verify validity of the current tracking mode.</li>
+ * <li> Uses {@link UiSettings} to verify validity of user restricted movement.</li>
+ * </ul>
+ * <p>
+ */
+final class MapKeyListener {
+
+ private final TrackingSettings trackingSettings;
+ private final Transform transform;
+ private final UiSettings uiSettings;
+
+ private TrackballLongPressTimeOut currentTrackballLongPressTimeOut;
+
+ MapKeyListener(@NonNull Transform transform, @NonNull TrackingSettings trackingSettings,
+ @NonNull UiSettings uiSettings) {
+ this.transform = transform;
+ this.trackingSettings = trackingSettings;
+ this.uiSettings = uiSettings;
+ }
+
+ /**
+ * Called when the user presses a key, alse called for repeated keys held down.
+ *
+ * @param keyCode the id of the pressed key
+ * @param event the related key event
+ * @return true if the wevent is handled
+ */
+ boolean onKeyDown(int keyCode, @NonNull KeyEvent event) {
+ // If the user has held the scroll key down for a while then accelerate
+ // the scroll speed
+ double scrollDist = event.getRepeatCount() >= 5 ? 50.0 : 10.0;
+
+ // Check which key was pressed via hardware/real key code
+ switch (keyCode) {
+ // Tell the system to track these keys for long presses on
+ // onKeyLongPress is fired
+ case KeyEvent.KEYCODE_ENTER:
+ case KeyEvent.KEYCODE_DPAD_CENTER:
+ event.startTracking();
+ return true;
+
+ case KeyEvent.KEYCODE_DPAD_LEFT:
+ if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
+ return false;
+ }
+
+ // Cancel any animation
+ transform.cancelTransitions();
+
+ // Move left
+ transform.moveBy(scrollDist, 0.0, 0 /*no animation*/);
+ return true;
+
+ case KeyEvent.KEYCODE_DPAD_RIGHT:
+ if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
+ return false;
+ }
+
+ // Cancel any animation
+ transform.cancelTransitions();
+
+ // Move right
+ transform.moveBy(-scrollDist, 0.0, 0 /*no animation*/);
+ return true;
+
+ case KeyEvent.KEYCODE_DPAD_UP:
+ if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
+ return false;
+ }
+
+ // Cancel any animation
+ transform.cancelTransitions();
+
+ // Move up
+ transform.moveBy(0.0, scrollDist, 0 /*no animation*/);
+ return true;
+
+ case KeyEvent.KEYCODE_DPAD_DOWN:
+ if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
+ return false;
+ }
+
+ // Cancel any animation
+ transform.cancelTransitions();
+
+ // Move down
+ transform.moveBy(0.0, -scrollDist, 0 /*no animation*/);
+ return true;
+
+ default:
+ // We are not interested in this key
+ return false;
+ }
+ }
+
+ /**
+ * Called when the user long presses a key that is being tracked.
+ *
+ * @param keyCode the id of the long pressed key
+ * @param event the related key event
+ * @return true if event is handled
+ */
+ boolean onKeyLongPress(int keyCode, KeyEvent event) {
+ // Check which key was pressed via hardware/real key code
+ switch (keyCode) {
+ // Tell the system to track these keys for long presses on
+ // onKeyLongPress is fired
+ case KeyEvent.KEYCODE_ENTER:
+ case KeyEvent.KEYCODE_DPAD_CENTER:
+ if (!uiSettings.isZoomGesturesEnabled()) {
+ return false;
+ }
+
+ // Zoom out
+ transform.zoom(false, uiSettings.getWidth() / 2, uiSettings.getHeight() / 2);
+ return true;
+
+ default:
+ // We are not interested in this key
+ return false;
+ }
+ }
+
+ /**
+ * Called when the user releases a key.
+ *
+ * @param keyCode the id of the released key
+ * @param event the related key event
+ * @return true if the event is handled
+ */
+ boolean onKeyUp(int keyCode, KeyEvent event) {
+ // Check if the key action was canceled (used for virtual keyboards)
+ if (event.isCanceled()) {
+ return false;
+ }
+
+ // Check which key was pressed via hardware/real key code
+ // Note if keyboard does not have physical key (ie primary non-shifted
+ // key) then it will not appear here
+ // Must use the key character map as physical to character is not
+ // fixed/guaranteed
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_ENTER:
+ case KeyEvent.KEYCODE_DPAD_CENTER:
+ if (!uiSettings.isZoomGesturesEnabled()) {
+ return false;
+ }
+
+ // Zoom in
+ transform.zoom(true, uiSettings.getWidth() / 2, uiSettings.getHeight() / 2);
+ return true;
+ }
+
+ // We are not interested in this key
+ return false;
+ }
+
+ /**
+ * Called for trackball events, all motions are relative in device specific units.
+ *
+ * @param event the related motion event
+ * @return true if the event is handled
+ */
+ boolean onTrackballEvent(MotionEvent event) {
+ // Choose the action
+ switch (event.getActionMasked()) {
+ // The trackball was rotated
+ case MotionEvent.ACTION_MOVE:
+ if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
+ return false;
+ }
+
+ // Cancel any animation
+ transform.cancelTransitions();
+
+ // Scroll the map
+ transform.moveBy(-10.0 * event.getX(), -10.0 * event.getY(), 0 /*no animation*/);
+ return true;
+
+ // Trackball was pushed in so start tracking and tell system we are
+ // interested
+ // We will then get the up action
+ case MotionEvent.ACTION_DOWN:
+ // Set up a delayed callback to check if trackball is still
+ // After waiting the system long press time out
+ if (currentTrackballLongPressTimeOut != null) {
+ currentTrackballLongPressTimeOut.cancel();
+ currentTrackballLongPressTimeOut = null;
+ }
+ currentTrackballLongPressTimeOut = new TrackballLongPressTimeOut();
+ new Handler().postDelayed(currentTrackballLongPressTimeOut,
+ ViewConfiguration.getLongPressTimeout());
+ return true;
+
+ // Trackball was released
+ case MotionEvent.ACTION_UP:
+ if (!uiSettings.isZoomGesturesEnabled()) {
+ return false;
+ }
+
+ // Only handle if we have not already long pressed
+ if (currentTrackballLongPressTimeOut != null) {
+ // Zoom in
+ transform.zoom(true, uiSettings.getWidth() / 2, uiSettings.getHeight() / 2);
+ }
+ return true;
+
+ // Trackball was cancelled
+ case MotionEvent.ACTION_CANCEL:
+ if (currentTrackballLongPressTimeOut != null) {
+ currentTrackballLongPressTimeOut.cancel();
+ currentTrackballLongPressTimeOut = null;
+ }
+ return true;
+
+ default:
+ // We are not interested in this event
+ return false;
+ }
+ }
+
+ /**
+ * This class implements the trackball long press time out callback
+ */
+ private class TrackballLongPressTimeOut implements Runnable {
+
+ // Track if we have been cancelled
+ private boolean cancelled;
+
+ TrackballLongPressTimeOut() {
+ cancelled = false;
+ }
+
+ // Cancel the timeout
+ public void cancel() {
+ cancelled = true;
+ }
+
+ // Called when long press time out expires
+ @Override
+ public void run() {
+ // Check if the trackball is still pressed
+ if (!cancelled) {
+ // Zoom out
+ transform.zoom(false, uiSettings.getWidth() / 2, uiSettings.getHeight() / 2);
+
+ // Ensure the up action is not run
+ currentTrackballLongPressTimeOut = null;
+ }
+ }
+ }
+}
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 32b327e8d0..5dee9bf43d 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
@@ -1,7 +1,5 @@
package com.mapbox.mapboxsdk.maps;
-import android.Manifest;
-import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.app.Fragment;
@@ -10,90 +8,53 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.PointF;
-import android.graphics.RectF;
import android.graphics.SurfaceTexture;
-import android.location.Location;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.CallSuper;
-import android.support.annotation.FloatRange;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
-import android.support.v4.content.ContextCompat;
-import android.support.v4.view.GestureDetectorCompat;
-import android.support.v4.view.ScaleGestureDetectorCompat;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.view.GestureDetector;
-import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
-import android.view.ScaleGestureDetector;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.TextureView;
import android.view.View;
-import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
-import android.widget.ZoomButtonsController;
-import com.almeros.android.multitouch.gesturedetectors.RotateGestureDetector;
-import com.almeros.android.multitouch.gesturedetectors.ShoveGestureDetector;
-import com.almeros.android.multitouch.gesturedetectors.TwoFingerGestureDetector;
-import com.mapbox.mapboxsdk.MapboxAccountManager;
+import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.R;
-import com.mapbox.mapboxsdk.annotations.Annotation;
-import com.mapbox.mapboxsdk.annotations.Icon;
-import com.mapbox.mapboxsdk.annotations.IconFactory;
-import com.mapbox.mapboxsdk.annotations.InfoWindow;
-import com.mapbox.mapboxsdk.annotations.Marker;
-import com.mapbox.mapboxsdk.annotations.MarkerView;
-import com.mapbox.mapboxsdk.annotations.Polygon;
-import com.mapbox.mapboxsdk.annotations.Polyline;
+import com.mapbox.mapboxsdk.annotations.MarkerViewManager;
import com.mapbox.mapboxsdk.camera.CameraPosition;
-import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
-import com.mapbox.mapboxsdk.constants.MyBearingTracking;
-import com.mapbox.mapboxsdk.constants.MyLocationTracking;
import com.mapbox.mapboxsdk.constants.Style;
-import com.mapbox.mapboxsdk.exceptions.IconBitmapChangedException;
-import com.mapbox.mapboxsdk.geometry.LatLng;
-import com.mapbox.mapboxsdk.location.LocationListener;
-import com.mapbox.mapboxsdk.location.LocationServices;
import com.mapbox.mapboxsdk.maps.widgets.CompassView;
import com.mapbox.mapboxsdk.maps.widgets.MyLocationView;
import com.mapbox.mapboxsdk.maps.widgets.MyLocationViewSettings;
import com.mapbox.mapboxsdk.telemetry.MapboxEvent;
import com.mapbox.mapboxsdk.telemetry.MapboxEventManager;
-import com.mapbox.mapboxsdk.utils.ColorUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.nio.ByteBuffer;
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
/**
* <p>
@@ -111,3090 +72,1004 @@ import java.util.concurrent.CopyOnWriteArrayList;
*/
public class MapView extends FrameLayout {
- private MapboxMap mapboxMap;
- private boolean initialLoad;
- private boolean destroyed;
-
- private List<Icon> icons;
- private int averageIconHeight;
- private int averageIconWidth;
-
- private NativeMapView nativeMapView;
- private boolean hasSurface = false;
-
- private ViewGroup markerViewContainer;
- private CompassView compassView;
- private ImageView logoView;
- private ImageView attributionsView;
- private MyLocationView myLocationView;
- private LocationListener myLocationListener;
-
- private Projection projection;
-
- private CopyOnWriteArrayList<OnMapChangedListener> onMapChangedListener;
- private ZoomButtonsController zoomButtonsController;
- private ConnectivityReceiver connectivityReceiver;
- private float screenDensity = 1.0f;
-
- private TrackballLongPressTimeOut currentTrackballLongPressTimeOut;
- private GestureDetectorCompat gestureDetector;
- private ScaleGestureDetector scaleGestureDetector;
- private RotateGestureDetector rotateGestureDetector;
- private ShoveGestureDetector shoveGestureDetector;
- private boolean twoTap = false;
- private boolean zoomStarted = false;
- private boolean dragStarted = false;
- private boolean quickZoom = false;
- private boolean scrollInProgress = false;
-
- private int contentPaddingLeft;
- private int contentPaddingTop;
- private int contentPaddingRight;
- private int contentPaddingBottom;
-
- private PointF focalPoint;
-
- private String styleUrl = Style.MAPBOX_STREETS;
- private boolean styleWasSet = false;
-
- private List<OnMapReadyCallback> onMapReadyCallbackList;
- private SnapshotRequest snapshotRequest;
-
- @UiThread
- public MapView(@NonNull Context context) {
- super(context);
- initialize(context, MapboxMapOptions.createFromAttributes(context, null));
- }
-
- @UiThread
- public MapView(@NonNull Context context, @Nullable AttributeSet attrs) {
- super(context, attrs);
- initialize(context, MapboxMapOptions.createFromAttributes(context, attrs));
- }
-
- @UiThread
- public MapView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- initialize(context, MapboxMapOptions.createFromAttributes(context, attrs));
- }
-
- @UiThread
- public MapView(@NonNull Context context, @Nullable MapboxMapOptions options) {
- super(context);
- initialize(context, options);
- }
-
- private void initialize(@NonNull Context context, @NonNull MapboxMapOptions options) {
- if (isInEditMode()) {
- // if we are in an editor mode we show an image of a map
- LayoutInflater.from(context).inflate(R.layout.mapview_preview, this);
- return;
- }
-
- initialLoad = true;
- 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);
-
- if (options.getTextureMode()) {
- TextureView textureView = new TextureView(context);
- textureView.setSurfaceTextureListener(new SurfaceTextureListener());
- addView(textureView, 0);
- } else {
- SurfaceView surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
- surfaceView.getHolder().addCallback(new SurfaceCallback());
- surfaceView.setVisibility(View.VISIBLE);
- }
-
- 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);
- setFocusable(true);
- setFocusableInTouchMode(true);
- requestFocus();
-
- // Touch gesture detectors
- gestureDetector = new GestureDetectorCompat(context, new GestureListener());
- gestureDetector.setIsLongpressEnabled(true);
- scaleGestureDetector = new ScaleGestureDetector(context, new ScaleGestureListener());
- ScaleGestureDetectorCompat.setQuickScaleEnabled(scaleGestureDetector, true);
- rotateGestureDetector = new RotateGestureDetector(context, new RotateGestureListener());
- shoveGestureDetector = new ShoveGestureDetector(context, new ShoveGestureListener());
-
- zoomButtonsController = new ZoomButtonsController(this);
- zoomButtonsController.setZoomSpeed(MapboxConstants.ANIMATION_DURATION);
- zoomButtonsController.setOnZoomListener(new OnZoomListener());
-
- // Connectivity
- onConnectivityChanged(isConnected());
-
- markerViewContainer = (ViewGroup) view.findViewById(R.id.markerViewContainer);
-
- myLocationView = (MyLocationView) view.findViewById(R.id.userLocationView);
- myLocationView.setMapboxMap(mapboxMap);
-
- compassView = (CompassView) view.findViewById(R.id.compassView);
- compassView.setMapboxMap(mapboxMap);
-
- logoView = (ImageView) view.findViewById(R.id.logoView);
-
- // Setup Attributions control
- attributionsView = (ImageView) view.findViewById(R.id.attributionView);
- attributionsView.setOnClickListener(new AttributionOnClickListener(this));
-
- screenDensity = context.getResources().getDisplayMetrics().density;
-
- setInitialState(options);
-
- // Shows the zoom controls
- if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH)) {
- mapboxMap.getUiSettings().setZoomControlsEnabled(true);
- }
- }
-
- private void setInitialState(MapboxMapOptions options) {
- mapboxMap.setDebugActive(options.getDebugActive());
-
- CameraPosition position = options.getCamera();
- if (position != null) {
- mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(position));
- myLocationView.setTilt(position.tilt);
- }
-
- // api base url
- String apiBaseUrl = options.getApiBaseUrl();
- if (!TextUtils.isEmpty(apiBaseUrl)) {
- setApiBaseUrl(apiBaseUrl);
- }
-
- // access token
- String accessToken = options.getAccessToken();
- if (!TextUtils.isEmpty(accessToken)) {
- mapboxMap.setAccessToken(accessToken);
- }
-
- // style url
- String style = options.getStyle();
- if (!TextUtils.isEmpty(style)) {
- styleUrl = style;
- }
-
- // MyLocationView
- MyLocationViewSettings myLocationViewSettings = mapboxMap.getMyLocationViewSettings();
- myLocationViewSettings.setForegroundDrawable(
- options.getMyLocationForegroundDrawable(), options.getMyLocationForegroundBearingDrawable());
- myLocationViewSettings.setForegroundTintColor(options.getMyLocationForegroundTintColor());
- myLocationViewSettings.setBackgroundDrawable(
- options.getMyLocationBackgroundDrawable(), options.getMyLocationBackgroundPadding());
- myLocationViewSettings.setBackgroundTintColor(options.getMyLocationBackgroundTintColor());
- myLocationViewSettings.setAccuracyAlpha(options.getMyLocationAccuracyAlpha());
- myLocationViewSettings.setAccuracyTintColor(options.getMyLocationAccuracyTintColor());
- mapboxMap.setMyLocationEnabled(options.getLocationEnabled());
-
- // Enable gestures
- UiSettings uiSettings = mapboxMap.getUiSettings();
- uiSettings.setZoomGesturesEnabled(options.getZoomGesturesEnabled());
- uiSettings.setZoomGestureChangeAllowed(options.getZoomGesturesEnabled());
- uiSettings.setScrollGesturesEnabled(options.getScrollGesturesEnabled());
- uiSettings.setScrollGestureChangeAllowed(options.getScrollGesturesEnabled());
- uiSettings.setRotateGesturesEnabled(options.getRotateGesturesEnabled());
- uiSettings.setRotateGestureChangeAllowed(options.getRotateGesturesEnabled());
- uiSettings.setTiltGesturesEnabled(options.getTiltGesturesEnabled());
- uiSettings.setTiltGestureChangeAllowed(options.getTiltGesturesEnabled());
-
- // Ui Controls
- uiSettings.setZoomControlsEnabled(options.getZoomControlsEnabled());
-
- // Zoom
- mapboxMap.setMaxZoom(options.getMaxZoom());
- mapboxMap.setMinZoom(options.getMinZoom());
-
- // Compass
- uiSettings.setCompassEnabled(options.getCompassEnabled());
- uiSettings.setCompassGravity(options.getCompassGravity());
- int[] compassMargins = options.getCompassMargins();
- if (compassMargins != null) {
- uiSettings.setCompassMargins(compassMargins[0], compassMargins[1], compassMargins[2], compassMargins[3]);
- } else {
- int tenDp = (int) getResources().getDimension(R.dimen.ten_dp);
- uiSettings.setCompassMargins(tenDp, tenDp, tenDp, tenDp);
- }
- uiSettings.setCompassFadeFacingNorth(options.getCompassFadeFacingNorth());
-
- // Logo
- uiSettings.setLogoEnabled(options.getLogoEnabled());
- uiSettings.setLogoGravity(options.getLogoGravity());
- int[] logoMargins = options.getLogoMargins();
- if (logoMargins != null) {
- uiSettings.setLogoMargins(logoMargins[0], logoMargins[1], logoMargins[2], logoMargins[3]);
- } else {
- int sixteenDp = (int) getResources().getDimension(R.dimen.sixteen_dp);
- uiSettings.setLogoMargins(sixteenDp, sixteenDp, sixteenDp, sixteenDp);
- }
-
- // Attribution
- uiSettings.setAttributionEnabled(options.getAttributionEnabled());
- uiSettings.setAttributionGravity(options.getAttributionGravity());
- int[] attributionMargins = options.getAttributionMargins();
- if (attributionMargins != null) {
- uiSettings.setAttributionMargins(attributionMargins[0], attributionMargins[1], attributionMargins[2], attributionMargins[3]);
- } else {
- Resources resources = getResources();
- int sevenDp = (int) resources.getDimension(R.dimen.seven_dp);
- int seventySixDp = (int) resources.getDimension(R.dimen.seventy_six_dp);
- uiSettings.setAttributionMargins(seventySixDp, sevenDp, sevenDp, sevenDp);
- }
-
- int attributionTintColor = options.getAttributionTintColor();
- uiSettings.setAttributionTintColor(attributionTintColor != -1
- ? attributionTintColor : ColorUtils.getPrimaryColor(getContext()));
- }
-
- //
- // Lifecycle events
- //
-
- /**
- * <p>
- * You must call this method from the parent's {@link android.app.Activity#onCreate(Bundle)} or
- * {@link android.app.Fragment#onCreate(Bundle)}.
- * </p>
- * You must set a valid access token with {@link MapView#setAccessToken(String)} before you this method
- * or an exception will be thrown.
- *
- * @param savedInstanceState Pass in the parent's savedInstanceState.
- * @see MapView#setAccessToken(String)
- */
- @UiThread
- public void onCreate(@Nullable Bundle savedInstanceState) {
- String accessToken = mapboxMap.getAccessToken();
- if (TextUtils.isEmpty(accessToken)) {
- accessToken = MapboxAccountManager.getInstance().getAccessToken();
- mapboxMap.setAccessToken(accessToken);
- } else {
- // user provided access token through xml attributes, need to start MapboxAccountManager
- MapboxAccountManager.start(getContext(), accessToken);
- }
-
- // Force a check for an access token
- MapboxAccountManager.validateAccessToken(accessToken);
-
- if (savedInstanceState != null && savedInstanceState.getBoolean(MapboxConstants.STATE_HAS_SAVED_STATE)) {
-
- // Get previous camera position
- CameraPosition cameraPosition = savedInstanceState.getParcelable(MapboxConstants.STATE_CAMERA_POSITION);
- if (cameraPosition != null) {
- mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder(cameraPosition).build()));
- }
-
- UiSettings uiSettings = mapboxMap.getUiSettings();
- uiSettings.setZoomGesturesEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_ZOOM_ENABLED));
- uiSettings.setZoomGestureChangeAllowed(savedInstanceState.getBoolean(MapboxConstants.STATE_ZOOM_ENABLED_CHANGE));
- uiSettings.setScrollGesturesEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_SCROLL_ENABLED));
- uiSettings.setScrollGestureChangeAllowed(savedInstanceState.getBoolean(MapboxConstants.STATE_SCROLL_ENABLED_CHANGE));
- uiSettings.setRotateGesturesEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_ROTATE_ENABLED));
- uiSettings.setRotateGestureChangeAllowed(savedInstanceState.getBoolean(MapboxConstants.STATE_ROTATE_ENABLED_CHANGE));
- uiSettings.setTiltGesturesEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_TILT_ENABLED));
- uiSettings.setTiltGestureChangeAllowed(savedInstanceState.getBoolean(MapboxConstants.STATE_TILT_ENABLED_CHANGE));
- uiSettings.setZoomControlsEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_ZOOM_CONTROLS_ENABLED));
-
- // Compass
- 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));
- uiSettings.setCompassFadeFacingNorth(savedInstanceState.getBoolean(MapboxConstants.STATE_COMPASS_FADE_WHEN_FACING_NORTH));
-
- // Logo
- uiSettings.setLogoEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_LOGO_ENABLED));
- uiSettings.setLogoGravity(savedInstanceState.getInt(MapboxConstants.STATE_LOGO_GRAVITY));
- uiSettings.setLogoMargins(savedInstanceState.getInt(MapboxConstants.STATE_LOGO_MARGIN_LEFT)
- , savedInstanceState.getInt(MapboxConstants.STATE_LOGO_MARGIN_TOP)
- , savedInstanceState.getInt(MapboxConstants.STATE_LOGO_MARGIN_RIGHT)
- , savedInstanceState.getInt(MapboxConstants.STATE_LOGO_MARGIN_BOTTOM));
-
- // Attribution
- uiSettings.setAttributionEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_ATTRIBUTION_ENABLED));
- uiSettings.setAttributionGravity(savedInstanceState.getInt(MapboxConstants.STATE_ATTRIBUTION_GRAVITY));
- uiSettings.setAttributionMargins(savedInstanceState.getInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_LEFT)
- , savedInstanceState.getInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_TOP)
- , savedInstanceState.getInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_RIGHT)
- , savedInstanceState.getInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_BOTTOM));
-
- mapboxMap.setDebugActive(savedInstanceState.getBoolean(MapboxConstants.STATE_DEBUG_ACTIVE));
- styleUrl = savedInstanceState.getString(MapboxConstants.STATE_STYLE_URL);
-
- // User location
- try {
- mapboxMap.setMyLocationEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_MY_LOCATION_ENABLED));
- } catch (SecurityException ignore) {
- // User did not accept location permissions
- }
-
- TrackingSettings trackingSettings = mapboxMap.getTrackingSettings();
- //noinspection ResourceType
- trackingSettings.setMyLocationTrackingMode(
- 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));
- trackingSettings.setDismissLocationTrackingOnGesture(
- savedInstanceState.getBoolean(MapboxConstants.STATE_MY_LOCATION_TRACKING_DISMISS, true));
- trackingSettings.setDismissBearingTrackingOnGesture(
- savedInstanceState.getBoolean(MapboxConstants.STATE_MY_BEARING_TRACKING_DISMISS, true));
- } else if (savedInstanceState == null) {
- // Start Telemetry (authorization determined in initial MapboxEventManager constructor)
- Log.i(MapView.class.getCanonicalName(), "MapView start Telemetry...");
- MapboxEventManager eventManager = MapboxEventManager.getMapboxEventManager();
- eventManager.initialize(getContext(), getAccessToken());
- }
-
- // Initialize EGL
- nativeMapView.initializeDisplay();
- nativeMapView.initializeContext();
-
- // Add annotation deselection listener
- addOnMapChangedListener(new OnMapChangedListener() {
- @Override
- public void onMapChanged(@MapChange int change) {
- if (change == DID_FINISH_LOADING_STYLE && initialLoad) {
- initialLoad = false;
- reloadIcons();
- reloadMarkers();
- adjustTopOffsetPixels();
-
- // Notify listeners the map is ready
- if (onMapReadyCallbackList.size() > 0) {
- Iterator<OnMapReadyCallback> iterator = onMapReadyCallbackList.iterator();
- while (iterator.hasNext()) {
- OnMapReadyCallback callback = iterator.next();
- callback.onMapReady(mapboxMap);
- iterator.remove();
- }
- }
-
- // 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();
-
- compassView.update(getDirection());
- myLocationView.update();
- mapboxMap.getMarkerViewManager().update();
-
- for (InfoWindow infoWindow : mapboxMap.getInfoWindows()) {
- infoWindow.update();
- }
- }
-
- }
- });
-
- // Fire MapLoad
- if (savedInstanceState == null) {
- Hashtable<String, Object> evt = new Hashtable<>();
- evt.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_MAP_LOAD);
- evt.put(MapboxEvent.ATTRIBUTE_CREATED, MapboxEventManager.generateCreateDate());
- MapboxEventManager.getMapboxEventManager().pushEvent(evt);
- }
- }
-
- /**
- * You must call this method from the parent's {@link android.app.Activity#onSaveInstanceState(Bundle)}
- * or {@link android.app.Fragment#onSaveInstanceState(Bundle)}.
- *
- * @param outState Pass in the parent's outState.
- */
-
- @UiThread
- public void onSaveInstanceState(@NonNull Bundle outState) {
- outState.putBoolean(MapboxConstants.STATE_HAS_SAVED_STATE, true);
- outState.putParcelable(MapboxConstants.STATE_CAMERA_POSITION, mapboxMap.getCameraPosition());
- outState.putBoolean(MapboxConstants.STATE_DEBUG_ACTIVE, mapboxMap.isDebugActive());
- outState.putString(MapboxConstants.STATE_STYLE_URL, styleUrl);
- outState.putBoolean(MapboxConstants.STATE_MY_LOCATION_ENABLED, mapboxMap.isMyLocationEnabled());
-
- // TrackingSettings
- TrackingSettings trackingSettings = mapboxMap.getTrackingSettings();
- outState.putInt(MapboxConstants.STATE_MY_LOCATION_TRACKING_MODE, trackingSettings.getMyLocationTrackingMode());
- outState.putInt(MapboxConstants.STATE_MY_BEARING_TRACKING_MODE, trackingSettings.getMyBearingTrackingMode());
- outState.putBoolean(MapboxConstants.STATE_MY_LOCATION_TRACKING_DISMISS, trackingSettings.isDismissLocationTrackingOnGesture());
- outState.putBoolean(MapboxConstants.STATE_MY_BEARING_TRACKING_DISMISS, trackingSettings.isDismissBearingTrackingOnGesture());
-
- // UiSettings
- UiSettings uiSettings = mapboxMap.getUiSettings();
- outState.putBoolean(MapboxConstants.STATE_ZOOM_ENABLED, uiSettings.isZoomGesturesEnabled());
- outState.putBoolean(MapboxConstants.STATE_ZOOM_ENABLED_CHANGE, uiSettings.isZoomGestureChangeAllowed());
- outState.putBoolean(MapboxConstants.STATE_SCROLL_ENABLED, uiSettings.isScrollGesturesEnabled());
- outState.putBoolean(MapboxConstants.STATE_SCROLL_ENABLED_CHANGE, uiSettings.isScrollGestureChangeAllowed());
- outState.putBoolean(MapboxConstants.STATE_ROTATE_ENABLED, uiSettings.isRotateGesturesEnabled());
- outState.putBoolean(MapboxConstants.STATE_ROTATE_ENABLED_CHANGE, uiSettings.isRotateGestureChangeAllowed());
- outState.putBoolean(MapboxConstants.STATE_TILT_ENABLED, uiSettings.isTiltGesturesEnabled());
- outState.putBoolean(MapboxConstants.STATE_TILT_ENABLED_CHANGE, uiSettings.isTiltGestureChangeAllowed());
- outState.putBoolean(MapboxConstants.STATE_ZOOM_CONTROLS_ENABLED, uiSettings.isZoomControlsEnabled());
-
- // UiSettings - Compass
- outState.putBoolean(MapboxConstants.STATE_COMPASS_ENABLED, uiSettings.isCompassEnabled());
- outState.putInt(MapboxConstants.STATE_COMPASS_GRAVITY, uiSettings.getCompassGravity());
- outState.putInt(MapboxConstants.STATE_COMPASS_MARGIN_LEFT, uiSettings.getCompassMarginLeft());
- outState.putInt(MapboxConstants.STATE_COMPASS_MARGIN_TOP, uiSettings.getCompassMarginTop());
- outState.putInt(MapboxConstants.STATE_COMPASS_MARGIN_BOTTOM, uiSettings.getCompassMarginBottom());
- outState.putInt(MapboxConstants.STATE_COMPASS_MARGIN_RIGHT, uiSettings.getCompassMarginRight());
- outState.putBoolean(MapboxConstants.STATE_COMPASS_FADE_WHEN_FACING_NORTH, uiSettings.isCompassFadeWhenFacingNorth());
-
- // UiSettings - Logo
- outState.putInt(MapboxConstants.STATE_LOGO_GRAVITY, uiSettings.getLogoGravity());
- outState.putInt(MapboxConstants.STATE_LOGO_MARGIN_LEFT, uiSettings.getLogoMarginLeft());
- outState.putInt(MapboxConstants.STATE_LOGO_MARGIN_TOP, uiSettings.getLogoMarginTop());
- outState.putInt(MapboxConstants.STATE_LOGO_MARGIN_RIGHT, uiSettings.getLogoMarginRight());
- outState.putInt(MapboxConstants.STATE_LOGO_MARGIN_BOTTOM, uiSettings.getLogoMarginBottom());
- outState.putBoolean(MapboxConstants.STATE_LOGO_ENABLED, uiSettings.isLogoEnabled());
-
- // UiSettings - Attribution
- outState.putInt(MapboxConstants.STATE_ATTRIBUTION_GRAVITY, uiSettings.getAttributionGravity());
- outState.putInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_LEFT, uiSettings.getAttributionMarginLeft());
- outState.putInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_TOP, uiSettings.getAttributionMarginTop());
- outState.putInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_RIGHT, uiSettings.getAttributionMarginRight());
- outState.putInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_BOTTOM, uiSettings.getAttributionMarginBottom());
- outState.putBoolean(MapboxConstants.STATE_ATTRIBUTION_ENABLED, uiSettings.isAttributionEnabled());
- }
-
- /**
- * You must call this method from the parent's {@link Activity#onDestroy()} or {@link Fragment#onDestroy()}.
- */
- @UiThread
- public void onDestroy() {
- destroyed = true;
- nativeMapView.terminateContext();
- nativeMapView.terminateDisplay();
- nativeMapView.destroySurface();
- nativeMapView.destroy();
- nativeMapView = null;
- }
-
- /**
- * You must call this method from the parent's {@link Activity#onPause()} or {@link Fragment#onPause()}.
- */
- @UiThread
- public void onPause() {
- // Unregister for connectivity changes
- if (connectivityReceiver != null) {
- getContext().unregisterReceiver(connectivityReceiver);
- connectivityReceiver = null;
- }
-
- myLocationView.onPause();
- }
-
- /**
- * You must call this method from the parent's {@link Activity#onResume()} or {@link Fragment#onResume()}.
- */
- @UiThread
- public void onResume() {
- // Register for connectivity changes
- connectivityReceiver = new ConnectivityReceiver();
- getContext().registerReceiver(connectivityReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
-
- nativeMapView.update();
- myLocationView.onResume();
-
- // In case that no style was set or was loaded through MapboxMapOptions
- if (!styleWasSet) {
- setStyleUrl(styleUrl);
- }
- }
-
- void setFocalPoint(PointF focalPoint) {
- if (focalPoint == null) {
- // resetting focal point,
- UiSettings uiSettings = mapboxMap.getUiSettings();
- // need to validate if we need to reset focal point with user provided one
- if (uiSettings.getFocalPoint() != null) {
- focalPoint = uiSettings.getFocalPoint();
- }
- }
- this.focalPoint = focalPoint;
- }
-
- /**
- * You must call this method from the parent's {@link Activity#onLowMemory()} or {@link Fragment#onLowMemory()}.
- */
- @UiThread
- public void onLowMemory() {
- nativeMapView.onLowMemory();
- }
-
- // Called when debug mode is enabled to update a FPS counter
- // Called via JNI from NativeMapView
- // Forward to any listener
- protected void onFpsChanged(final double fps) {
- post(new Runnable() {
- @Override
- public void run() {
- MapboxMap.OnFpsChangedListener listener = mapboxMap.getOnFpsChangedListener();
- if (listener != null) {
- listener.onFpsChanged(fps);
- }
- }
- });
- }
-
- //
- // LatLng / CenterCoordinate
- //
-
- LatLng getLatLng() {
- return nativeMapView.getLatLng();
- }
-
- //
- // Pitch / Tilt
- //
-
- double getTilt() {
- return nativeMapView.getPitch();
- }
-
- void setTilt(Double pitch) {
- mapboxMap.getMarkerViewManager().setTilt(pitch.floatValue());
- myLocationView.setTilt(pitch);
- nativeMapView.setPitch(pitch, 0);
- }
-
-
- //
- // Direction
- //
-
- double getDirection() {
- if (destroyed) {
- return 0;
- }
-
- double direction = -nativeMapView.getBearing();
-
- while (direction > 360) {
- direction -= 360;
- }
- while (direction < 0) {
- direction += 360;
- }
-
- return direction;
- }
-
- void setDirection(@FloatRange(from = MapboxConstants.MINIMUM_DIRECTION, to = MapboxConstants.MAXIMUM_DIRECTION) double direction) {
- if (destroyed) {
- return;
- }
- setDirection(direction, false);
- }
-
- void setDirection(@FloatRange(from = MapboxConstants.MINIMUM_DIRECTION, to = MapboxConstants.MAXIMUM_DIRECTION) double direction, boolean animated) {
- if (destroyed) {
- return;
- }
- long duration = animated ? MapboxConstants.ANIMATION_DURATION : 0;
- nativeMapView.cancelTransitions();
- // Out of range directions are normalised in setBearing
- nativeMapView.setBearing(-direction, duration);
- }
-
- void resetNorth() {
- if (destroyed) {
- return;
- }
- myLocationView.setBearing(0);
- nativeMapView.cancelTransitions();
- nativeMapView.resetNorth();
- }
-
- //
- // Content padding
- //
-
- int getContentPaddingLeft() {
- return contentPaddingLeft;
- }
-
- int getContentPaddingTop() {
- return contentPaddingTop;
- }
-
- int getContentPaddingRight() {
- return contentPaddingRight;
- }
-
- int getContentPaddingBottom() {
- return contentPaddingBottom;
- }
-
- int getContentWidth() {
- return getWidth() - contentPaddingLeft - contentPaddingRight;
- }
-
- int getContentHeight() {
- return getHeight() - contentPaddingBottom - contentPaddingTop;
- }
-
- //
- // Zoom
- //
-
- double getZoom() {
- if (destroyed) {
- return 0;
- }
- return nativeMapView.getZoom();
- }
-
- void setMinZoom(@FloatRange(from = MapboxConstants.MINIMUM_ZOOM, to = MapboxConstants.MAXIMUM_ZOOM) double minZoom) {
- if (destroyed) {
- return;
- }
- nativeMapView.setMinZoom(minZoom);
- }
-
- double getMinZoom() {
- if (destroyed) {
- return 0;
- }
- return nativeMapView.getMinZoom();
- }
-
- void setMaxZoom(@FloatRange(from = MapboxConstants.MINIMUM_ZOOM, to = MapboxConstants.MAXIMUM_ZOOM) double maxZoom) {
- if (destroyed) {
- return;
- }
- nativeMapView.setMaxZoom(maxZoom);
- }
-
- double getMaxZoom() {
- if (destroyed) {
- return 0;
- }
- return nativeMapView.getMaxZoom();
- }
-
- // Zoom in or out
- private void zoom(boolean zoomIn) {
- zoom(zoomIn, -1.0f, -1.0f);
- }
-
- private void zoom(boolean zoomIn, float x, float y) {
- // Cancel any animation
- nativeMapView.cancelTransitions();
-
- if (zoomIn) {
- nativeMapView.scaleBy(2.0, x / screenDensity, y / screenDensity, MapboxConstants.ANIMATION_DURATION);
- } else {
- nativeMapView.scaleBy(0.5, x / screenDensity, y / screenDensity, MapboxConstants.ANIMATION_DURATION);
- }
-
- // work around to invalidate camera position
- postDelayed(new ZoomInvalidator(mapboxMap), MapboxConstants.ANIMATION_DURATION);
- }
-
- //
- // Debug
- //
-
- boolean isDebugActive() {
- if (destroyed) {
- return false;
- }
- return nativeMapView.getDebug();
- }
-
- void setDebugActive(boolean debugActive) {
- if (destroyed) {
- return;
- }
- nativeMapView.setDebug(debugActive);
- }
-
- void cycleDebugOptions() {
- if (destroyed) {
- return;
- }
- nativeMapView.cycleDebugOptions();
- }
-
- //
- // Styling
- //
-
- /**
- * <p>
- * Loads a new map style from the specified URL.
- * </p>
- * {@code url} can take the following forms:
- * <ul>
- * <li>{@code Style.*}: load one of the bundled styles in {@link Style}.</li>
- * <li>{@code mapbox://styles/<user>/<style>}:
- * retrieves the style from a <a href="https://www.mapbox.com/account/">Mapbox account.</a>
- * {@code user} is your username. {@code style} is the ID of your custom
- * style created in <a href="https://www.mapbox.com/studio">Mapbox Studio</a>.</li>
- * <li>{@code http://...} or {@code https://...}:
- * retrieves the style over the Internet from any web server.</li>
- * <li>{@code asset://...}:
- * reads the style from the APK {@code assets/} directory.
- * This is used to load a style bundled with your app.</li>
- * <li>{@code null}: loads the default {@link Style#MAPBOX_STREETS} style.</li>
- * </ul>
- * <p>
- * This method is asynchronous and will return immediately before the style finishes loading.
- * If you wish to wait for the map to finish loading listen for the {@link MapView#DID_FINISH_LOADING_MAP} event.
- * </p>
- * If the style fails to load or an invalid style URL is set, the map view will become blank.
- * An error message will be logged in the Android logcat and {@link MapView#DID_FAIL_LOADING_MAP} event will be sent.
- *
- * @param url The URL of the map style
- * @see Style
- */
- public void setStyleUrl(@NonNull String url) {
- if (destroyed) {
- return;
- }
-
- // stopgap for https://github.com/mapbox/mapbox-gl-native/issues/6242
- if (TextUtils.isEmpty(nativeMapView.getAccessToken())) {
- setAccessToken(MapboxAccountManager.getInstance().getAccessToken());
- }
-
- styleUrl = url;
- nativeMapView.setStyleUrl(url);
- styleWasSet = true;
- }
-
- /**
- * <p>
- * Loads a new map style from the specified bundled style.
- * </p>
- * <p>
- * This method is asynchronous and will return immediately before the style finishes loading.
- * If you wish to wait for the map to finish loading listen for the {@link MapView#DID_FINISH_LOADING_MAP} event.
- * </p>
- * If the style fails to load or an invalid style URL is set, the map view will become blank.
- * An error message will be logged in the Android logcat and {@link MapView#DID_FAIL_LOADING_MAP} event will be sent.
- *
- * @param style The bundled style. Accepts one of the values from {@link Style}.
- * @see Style
- */
- @UiThread
- public void setStyle(@Style.StyleUrl String style) {
- setStyleUrl(style);
- }
-
- /**
- * <p>
- * Returns the map style currently displayed in the map view.
- * </p>
- * If the default style is currently displayed, a URL will be returned instead of null.
- *
- * @return The URL of the map style.
- */
- @UiThread
- @NonNull
- public String getStyleUrl() {
- return styleUrl;
- }
-
- //
- // API Base URL
- //
-
- @UiThread
- void setApiBaseUrl(@NonNull String baseUrl) {
- nativeMapView.setApiBaseUrl(baseUrl);
- }
-
- //
- // Access token
- //
-
- /**
- * <p>
- * DEPRECATED @see MapboxAccountManager#start(String)
- * </p>
- * <p>
- * Sets the current Mapbox access token used to load map styles and tiles.
- * </p>
- * <p>
- * You must set a valid access token before you call {@link MapView#onCreate(Bundle)}
- * or an exception will be thrown.
- * </p>
- *
- * @param accessToken Your public Mapbox access token.
- * @see MapView#onCreate(Bundle)
- * @deprecated As of release 4.1.0, replaced by {@link com.mapbox.mapboxsdk.MapboxAccountManager#start(Context, String)}
- */
- @Deprecated
- @UiThread
- public void setAccessToken(@NonNull String accessToken) {
- if (destroyed) {
- return;
- }
- // validateAccessToken does the null check
- if (!TextUtils.isEmpty(accessToken)) {
- accessToken = accessToken.trim();
- }
- MapboxAccountManager.validateAccessToken(accessToken);
- nativeMapView.setAccessToken(accessToken);
- }
-
- /**
- * <p>
- * DEPRECATED @see MapboxAccountManager#getAccessToken()
- * </p>
- * <p>
- * Returns the current Mapbox access token used to load map styles and tiles.
- * </p>
- *
- * @return The current Mapbox access token.
- * @deprecated As of release 4.1.0, replaced by {@link MapboxAccountManager#getAccessToken()}
- */
- @Deprecated
- @UiThread
- @Nullable
- public String getAccessToken() {
- if (destroyed) {
- return "";
- }
- return nativeMapView.getAccessToken();
- }
-
- //
- // Projection
- //
-
- /*
- * Internal use only, use Projection#fromScreenLocation instead
- */
- LatLng fromNativeScreenLocation(@NonNull PointF point) {
- if (destroyed) {
- return new LatLng();
- }
- return nativeMapView.latLngForPixel(point);
- }
-
- /*
- * Internal use only, use Projection#toScreenLocation instead.
- */
- PointF toNativeScreenLocation(@NonNull LatLng location) {
- if (destroyed || location == null) {
- return new PointF();
- }
- return nativeMapView.pixelForLatLng(location);
- }
-
- //
- // Annotations
- //
-
- Icon loadIconForMarker(Marker marker) {
- Icon icon = marker.getIcon();
-
- // calculating average before adding
- int iconSize = icons.size() + 1;
-
- // TODO replace former if case with anchor implementation,
- // current workaround for having extra pixels is diving height by 2
- if (icon == null) {
- icon = IconFactory.getInstance(getContext()).defaultMarker();
- Bitmap bitmap = icon.getBitmap();
- averageIconHeight = averageIconHeight + (bitmap.getHeight() / 2 - averageIconHeight) / iconSize;
- averageIconWidth = averageIconWidth + (bitmap.getWidth() - averageIconWidth) / iconSize;
- marker.setIcon(icon);
- } else {
- Bitmap bitmap = icon.getBitmap();
- averageIconHeight = averageIconHeight + (bitmap.getHeight() - averageIconHeight) / iconSize;
- averageIconWidth = averageIconWidth + (bitmap.getWidth() - averageIconWidth) / iconSize;
- }
-
- if (!icons.contains(icon)) {
- icons.add(icon);
- loadIcon(icon);
- } else {
- Icon oldIcon = icons.get(icons.indexOf(icon));
- if (!oldIcon.getBitmap().sameAs(icon.getBitmap())) {
- throw new IconBitmapChangedException();
- }
- }
- return icon;
- }
-
- Icon loadIconForMarkerView(MarkerView marker) {
- Icon icon = marker.getIcon();
- int iconSize = icons.size() + 1;
- if (icon == null) {
- icon = IconFactory.getInstance(getContext()).defaultMarkerView();
- marker.setIcon(icon);
- }
- Bitmap bitmap = icon.getBitmap();
- averageIconHeight = averageIconHeight + (bitmap.getHeight() - averageIconHeight) / iconSize;
- averageIconWidth = averageIconWidth + (bitmap.getWidth() - averageIconWidth) / iconSize;
- if (!icons.contains(icon)) {
- icons.add(icon);
- } else {
- Icon oldIcon = icons.get(icons.indexOf(icon));
- if (!oldIcon.getBitmap().sameAs(icon.getBitmap())) {
- throw new IconBitmapChangedException();
- }
- }
- return icon;
- }
-
- void loadIcon(Icon icon) {
- if (destroyed) {
- return;
- }
- Bitmap bitmap = icon.getBitmap();
- String id = icon.getId();
- if (bitmap.getConfig() != Bitmap.Config.ARGB_8888) {
- bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, false);
- }
- ByteBuffer buffer = ByteBuffer.allocate(bitmap.getRowBytes() * bitmap.getHeight());
- bitmap.copyPixelsToBuffer(buffer);
-
- float density = bitmap.getDensity();
- if (density == Bitmap.DENSITY_NONE) {
- density = DisplayMetrics.DENSITY_DEFAULT;
- }
- float scale = density / DisplayMetrics.DENSITY_DEFAULT;
- nativeMapView.addAnnotationIcon(
- id,
- bitmap.getWidth(),
- bitmap.getHeight(),
- scale, buffer.array());
- }
-
- void reloadIcons() {
- int count = icons.size();
- for (int i = 0; i < count; i++) {
- Icon icon = icons.get(i);
- loadIcon(icon);
- }
- }
-
- void updateMarker(@NonNull Marker updatedMarker) {
- if (destroyed) {
- return;
- }
- if (updatedMarker == null) {
- Log.w(MapboxConstants.TAG, "marker was null, doing nothing");
- return;
- }
-
- if (updatedMarker.getId() == -1) {
- Log.w(MapboxConstants.TAG, "marker has an id of -1, possibly was not added yet, doing nothing");
- return;
- }
-
- if (!(updatedMarker instanceof MarkerView)) {
- ensureIconLoaded(updatedMarker);
- }
-
- nativeMapView.updateMarker(updatedMarker);
- }
-
-
- void updatePolygon(Polygon polygon) {
- if (destroyed) {
- return;
- }
-
- if (polygon == null) {
- Log.w(MapboxConstants.TAG, "polygon was null, doing nothing");
- return;
- }
-
- if (polygon.getId() == -1) {
- Log.w(MapboxConstants.TAG, "polygon has an id of -1, indicating the polygon was not added to the map yet.");
- return;
- }
-
- nativeMapView.updatePolygon(polygon);
- }
-
- void updatePolyline(Polyline polyline) {
- if (destroyed) {
- return;
- }
-
- if (polyline == null) {
- Log.w(MapboxConstants.TAG, "polygon was null, doing nothing");
- return;
- }
-
- if (polyline.getId() == -1) {
- Log.w(MapboxConstants.TAG, "polygon has an id of -1, indicating the polygon was not added to the map yet.");
- return;
- }
-
- nativeMapView.updatePolyline(polyline);
- }
-
- private void ensureIconLoaded(Marker marker) {
- Icon icon = marker.getIcon();
- if (icon == null) {
- icon = IconFactory.getInstance(getContext()).defaultMarker();
- marker.setIcon(icon);
- }
- if (!icons.contains(icon)) {
- icons.add(icon);
- loadIcon(icon);
- } else {
- Icon oldIcon = icons.get(icons.indexOf(icon));
- if (!oldIcon.getBitmap().sameAs(icon.getBitmap())) {
- throw new IconBitmapChangedException();
- }
- }
-
- // this seems to be a costly operation according to the profiler so I'm trying to save some calls
- Marker previousMarker = marker.getId() != -1 ? (Marker) mapboxMap.getAnnotation(marker.getId()) : null;
- if (previousMarker == null || previousMarker.getIcon() == null || previousMarker.getIcon() != marker.getIcon()) {
- marker.setTopOffsetPixels(getTopOffsetPixelsForIcon(icon));
- }
- }
-
- long addMarker(@NonNull Marker marker) {
- if (destroyed) {
- return 0L;
- }
- return nativeMapView.addMarker(marker);
- }
-
- long[] addMarkers(@NonNull List<Marker> markerList) {
- if (destroyed) {
- return new long[]{};
- }
- return nativeMapView.addMarkers(markerList);
- }
-
- long addPolyline(@NonNull Polyline polyline) {
- if (destroyed) {
- return 0L;
- }
- return nativeMapView.addPolyline(polyline);
- }
-
- long[] addPolylines(@NonNull List<Polyline> polylines) {
- if (destroyed) {
- return new long[]{};
- }
- return nativeMapView.addPolylines(polylines);
- }
-
- long addPolygon(@NonNull Polygon polygon) {
- if (destroyed) {
- return 0L;
- }
- return nativeMapView.addPolygon(polygon);
- }
-
- long[] addPolygons(@NonNull List<Polygon> polygons) {
- if (destroyed) {
- return new long[]{};
- }
- return nativeMapView.addPolygons(polygons);
- }
-
- void removeAnnotation(long id) {
- if (destroyed) {
- return;
- }
- nativeMapView.removeAnnotation(id);
- }
-
- void removeAnnotations(@NonNull long[] ids) {
- if (destroyed) {
- return;
- }
- nativeMapView.removeAnnotations(ids);
- }
-
- List<Marker> getMarkersInRect(@NonNull RectF rect) {
- if (destroyed || rect == null) {
- return new ArrayList<>();
- }
-
- long[] ids = nativeMapView.queryPointAnnotations(rect);
-
- List<Long> idsList = new ArrayList<>(ids.length);
- for (int i = 0; i < ids.length; i++) {
- idsList.add(ids[i]);
- }
-
- List<Marker> annotations = new ArrayList<>(ids.length);
- List<Annotation> annotationList = mapboxMap.getAnnotations();
- int count = annotationList.size();
- for (int i = 0; i < count; i++) {
- Annotation annotation = annotationList.get(i);
- if (annotation instanceof Marker && idsList.contains(annotation.getId())) {
- annotations.add((Marker) annotation);
- }
- }
-
- return new ArrayList<>(annotations);
- }
-
- public List<MarkerView> getMarkerViewsInRect(@NonNull RectF rect) {
- if (destroyed || rect == null) {
- return new ArrayList<>();
- }
-
- long[] ids = nativeMapView.queryPointAnnotations(rect);
-
- List<Long> idsList = new ArrayList<>(ids.length);
- for (int i = 0; i < ids.length; i++) {
- idsList.add(ids[i]);
- }
-
- List<MarkerView> annotations = new ArrayList<>(ids.length);
- List<Annotation> annotationList = mapboxMap.getAnnotations();
- int count = annotationList.size();
- for (int i = 0; i < count; i++) {
- Annotation annotation = annotationList.get(i);
- if (annotation instanceof MarkerView) {
- annotations.add((MarkerView) annotation);
- }
- }
-
- return new ArrayList<>(annotations);
- }
-
- /**
- * @return the ViewGroup containing the marker views
- */
- public ViewGroup getMarkerViewContainer() {
- return markerViewContainer;
- }
-
-
- int getTopOffsetPixelsForIcon(Icon icon) {
- if (destroyed) {
- return 0;
+ private NativeMapView nativeMapView;
+ private boolean destroyed;
+ private boolean hasSurface = false;
+
+ private MapboxMap mapboxMap;
+ private MapCallback mapCallback;
+ private boolean onStartCalled;
+ private boolean onStopCalled;
+
+ private MapGestureDetector mapGestureDetector;
+ private MapKeyListener mapKeyListener;
+ private MapZoomButtonController mapZoomButtonController;
+
+ private ConnectivityReceiver connectivityReceiver;
+ private SnapshotRequest snapshotRequest;
+
+ @UiThread
+ public MapView(@NonNull Context context) {
+ super(context);
+ initialise(context, MapboxMapOptions.createFromAttributes(context, null));
+ }
+
+ @UiThread
+ public MapView(@NonNull Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ initialise(context, MapboxMapOptions.createFromAttributes(context, attrs));
+ }
+
+ @UiThread
+ public MapView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ initialise(context, MapboxMapOptions.createFromAttributes(context, attrs));
+ }
+
+ @UiThread
+ public MapView(@NonNull Context context, @NonNull MapboxMapOptions options) {
+ super(context);
+ initialise(context, options);
+ }
+
+ private void initialise(@NonNull final Context context, @NonNull final MapboxMapOptions options) {
+ if (isInEditMode()) {
+ // in IDE, show preview map
+ LayoutInflater.from(context).inflate(R.layout.mapbox_mapview_preview, this);
+ return;
+ }
+
+ // inflate view
+ View view = LayoutInflater.from(context).inflate(R.layout.mapbox_mapview_internal, this);
+ CompassView compassView = (CompassView) view.findViewById(R.id.compassView);
+ MyLocationView myLocationView = (MyLocationView) view.findViewById(R.id.userLocationView);
+ ImageView attrView = (ImageView) view.findViewById(R.id.attributionView);
+ initalizeDrawingSurface(context, options);
+
+ // create native Map object
+ nativeMapView = new NativeMapView(this);
+
+ // callback for focal point invalidation
+ FocalPointInvalidator focalPoint = new FocalPointInvalidator();
+
+ // callback for registering touch listeners
+ RegisterTouchListener registerTouchListener = new RegisterTouchListener();
+
+ // setup components for MapboxMap creation
+ Projection proj = new Projection(nativeMapView);
+ UiSettings uiSettings = new UiSettings(proj, focalPoint, compassView, attrView, view.findViewById(R.id.logoView));
+ TrackingSettings trackingSettings = new TrackingSettings(myLocationView, uiSettings, focalPoint);
+ MyLocationViewSettings myLocationViewSettings = new MyLocationViewSettings(myLocationView, proj, focalPoint);
+ MarkerViewManager markerViewManager = new MarkerViewManager((ViewGroup) findViewById(R.id.markerViewContainer));
+ AnnotationManager annotations = new AnnotationManager(nativeMapView, this, markerViewManager);
+ Transform transform = new Transform(nativeMapView, annotations.getMarkerViewManager(), trackingSettings);
+ mapboxMap = new MapboxMap(nativeMapView, transform, uiSettings, trackingSettings, myLocationViewSettings, proj,
+ registerTouchListener, annotations);
+
+ // user input
+ mapGestureDetector = new MapGestureDetector(context, transform, proj, uiSettings, trackingSettings, annotations);
+ mapKeyListener = new MapKeyListener(transform, trackingSettings, uiSettings);
+ mapZoomButtonController = new MapZoomButtonController(this, uiSettings, transform);
+
+ // inject widgets with MapboxMap
+ compassView.setMapboxMap(mapboxMap);
+ myLocationView.setMapboxMap(mapboxMap);
+ attrView.setOnClickListener(new AttributionOnClickListener(context, transform));
+
+ // Ensure this view is interactable
+ setClickable(true);
+ setLongClickable(true);
+ setFocusable(true);
+ setFocusableInTouchMode(true);
+ requestDisallowInterceptTouchEvent(true);
+
+ // allow onDraw invocation
+ setWillNotDraw(false);
+
+ // notify Map object about current connectivity state
+ nativeMapView.setReachability(isConnected());
+
+ // initialise MapboxMap
+ mapboxMap.initialise(context, options);
+ }
+
+ private void initalizeDrawingSurface(Context context, MapboxMapOptions options) {
+ if (options.getTextureMode()) {
+ TextureView textureView = new TextureView(context);
+ textureView.setSurfaceTextureListener(new SurfaceTextureListener());
+ addView(textureView, 0);
+ } else {
+ SurfaceView surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
+ surfaceView.getHolder().addCallback(new SurfaceCallback());
+ surfaceView.setVisibility(View.VISIBLE);
+ }
+ }
+
+ //
+ // Lifecycle events
+ //
+
+ /**
+ * <p>
+ * You must call this method from the parent's {@link android.app.Activity#onCreate(Bundle)} or
+ * {@link android.app.Fragment#onCreate(Bundle)}.
+ * </p>
+ * You must set a valid access token with {@link Mapbox#getInstance(Context, String)}) before you call this method
+ * or an exception will be thrown.
+ *
+ * @param savedInstanceState Pass in the parent's savedInstanceState.
+ * @see Mapbox#getInstance(Context, String)
+ */
+ @UiThread
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ Mapbox.validateAccessToken();
+ nativeMapView.setAccessToken(Mapbox.getAccessToken());
+
+ if (savedInstanceState == null) {
+ MapboxEvent.trackMapLoadEvent();
+ } else if (savedInstanceState.getBoolean(MapboxConstants.STATE_HAS_SAVED_STATE)) {
+ mapboxMap.onRestoreInstanceState(savedInstanceState);
+ }
+
+ // Initialize EGL
+ nativeMapView.initializeDisplay();
+ nativeMapView.initializeContext();
+
+ addOnMapChangedListener(mapCallback = new MapCallback(mapboxMap));
+ }
+
+ /**
+ * You must call this method from the parent's {@link android.app.Activity#onSaveInstanceState(Bundle)}
+ * or {@link android.app.Fragment#onSaveInstanceState(Bundle)}.
+ *
+ * @param outState Pass in the parent's outState.
+ */
+
+ @UiThread
+ public void onSaveInstanceState(@NonNull Bundle outState) {
+ outState.putBoolean(MapboxConstants.STATE_HAS_SAVED_STATE, true);
+ mapboxMap.onSaveInstanceState(outState);
+ }
+
+ /**
+ * You must call this method from the parent's {@link Activity#onStart()} or {@link Fragment#onStart()}
+ */
+ @UiThread
+ public void onStart() {
+ onStartCalled = true;
+ mapboxMap.onStart();
+ registerConnectivityReceiver();
+ }
+
+ /**
+ * You must call this method from the parent's {@link Activity#onResume()} or {@link Fragment#onResume()}.
+ */
+ @UiThread
+ public void onResume() {
+ if (!onStartCalled) {
+ // TODO: 26/10/16, can be removed after 5.0.0 release
+ throw new IllegalStateException("MapView#onStart() was not called. "
+ + "You must call this method from the parent's {@link Activity#onStart()} or {@link Fragment#onStart()}.");
+ }
+ }
+
+ /**
+ * You must call this method from the parent's {@link Activity#onPause()} or {@link Fragment#onPause()}.
+ */
+ @UiThread
+ public void onPause() {
+ // replaced by onStop in v5.0.0, keep around for future development
+ }
+
+ /**
+ * You must call this method from the parent's {@link Activity#onStop()} or {@link Fragment#onStop()}.
+ */
+ @UiThread
+ public void onStop() {
+ onStopCalled = true;
+ mapboxMap.onStop();
+ unregisterConnectivityReceiver();
+ }
+
+ /**
+ * You must call this method from the parent's {@link Activity#onDestroy()} or {@link Fragment#onDestroy()}.
+ */
+ @UiThread
+ public void onDestroy() {
+ if (!onStopCalled) {
+ // TODO: 26/10/16, can be removed after 5.0.0 release
+ throw new IllegalStateException("MapView#onStop() was not called. "
+ + "You must call this method from the parent's {@link Activity#onStop()} or {@link Fragment#onStop()}.");
+ }
+
+ destroyed = true;
+ nativeMapView.terminateContext();
+ nativeMapView.terminateDisplay();
+ nativeMapView.destroySurface();
+ nativeMapView.destroy();
+ nativeMapView = null;
+ }
+
+ private void registerConnectivityReceiver() {
+ getContext().registerReceiver(connectivityReceiver = new ConnectivityReceiver(),
+ new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
+ }
+
+ private void unregisterConnectivityReceiver() {
+ if (connectivityReceiver != null) {
+ getContext().unregisterReceiver(connectivityReceiver);
+ connectivityReceiver = null;
+ }
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ mapZoomButtonController.setVisible(true);
+ }
+ return mapGestureDetector.onTouchEvent(event) || super.onTouchEvent(event);
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ return mapKeyListener.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
+ }
+
+ @Override
+ public boolean onKeyLongPress(int keyCode, KeyEvent event) {
+ return mapKeyListener.onKeyLongPress(keyCode, event) || super.onKeyLongPress(keyCode, event);
+ }
+
+ @Override
+ public boolean onKeyUp(int keyCode, KeyEvent event) {
+ return mapKeyListener.onKeyUp(keyCode, event) || super.onKeyUp(keyCode, event);
+ }
+
+ @Override
+ public boolean onTrackballEvent(MotionEvent event) {
+ return mapKeyListener.onTrackballEvent(event) || super.onTrackballEvent(event);
+ }
+
+ @Override
+ public boolean onGenericMotionEvent(MotionEvent event) {
+ return mapGestureDetector.onGenericMotionEvent(event) || super.onGenericMotionEvent(event);
+ }
+
+ @Override
+ public boolean onHoverEvent(MotionEvent event) {
+ switch (event.getActionMasked()) {
+ case MotionEvent.ACTION_HOVER_ENTER:
+ case MotionEvent.ACTION_HOVER_MOVE:
+ mapZoomButtonController.setVisible(true);
+ return true;
+
+ case MotionEvent.ACTION_HOVER_EXIT:
+ mapZoomButtonController.setVisible(false);
+ return true;
+
+ default:
+ // We are not interested in this event
+ return false;
+ }
+ }
+
+ /**
+ * You must call this method from the parent's {@link Activity#onLowMemory()} or {@link Fragment#onLowMemory()}.
+ */
+ @UiThread
+ public void onLowMemory() {
+ nativeMapView.onLowMemory();
+ }
+
+ // Called when debug mode is enabled to update a FPS counter
+ // Called via JNI from NativeMapView
+ // Forward to any listener
+ protected void onFpsChanged(final double fps) {
+ final MapboxMap.OnFpsChangedListener listener = mapboxMap.getOnFpsChangedListener();
+ if (listener != null) {
+ post(new Runnable() {
+ @Override
+ public void run() {
+ listener.onFpsChanged(fps);
}
-
- return (int) (nativeMapView.getTopOffsetPixelsForAnnotationSymbol(icon.getId())
- * screenDensity);
+ });
}
+ }
- void setContentPadding(int left, int top, int right, int bottom) {
- if (destroyed) {
- return;
- }
-
-// if (left == contentPaddingLeft && top == contentPaddingTop && right == contentPaddingRight && bottom == contentPaddingBottom) {
-// return;
-// }
-
- contentPaddingLeft = left;
- contentPaddingTop = top;
- contentPaddingRight = right;
- contentPaddingBottom = bottom;
-
- int[] userLocationViewPadding = mapboxMap.getMyLocationViewSettings().getPadding();
- left += userLocationViewPadding[0];
- top += userLocationViewPadding[1];
- right += userLocationViewPadding[2];
- bottom += userLocationViewPadding[3];
-
- nativeMapView.setContentPadding(top / screenDensity, left / screenDensity, bottom / screenDensity, right / screenDensity);
+ /**
+ * <p>
+ * Loads a new map style from the specified URL.
+ * </p>
+ * {@code url} can take the following forms:
+ * <ul>
+ * <li>{@code Style.*}: load one of the bundled styles in {@link Style}.</li>
+ * <li>{@code mapbox://styles/<user>/<style>}:
+ * retrieves the style from a <a href="https://www.mapbox.com/account/">Mapbox account.</a>
+ * {@code user} is your username. {@code style} is the ID of your custom
+ * style created in <a href="https://www.mapbox.com/studio">Mapbox Studio</a>.</li>
+ * <li>{@code http://...} or {@code https://...}:
+ * retrieves the style over the Internet from any web server.</li>
+ * <li>{@code asset://...}:
+ * reads the style from the APK {@code assets/} directory.
+ * This is used to load a style bundled with your app.</li>
+ * <li>{@code null}: loads the default {@link Style#MAPBOX_STREETS} style.</li>
+ * </ul>
+ * <p>
+ * This method is asynchronous and will return immediately before the style finishes loading.
+ * If you wish to wait for the map to finish loading listen for the {@link MapView#DID_FINISH_LOADING_MAP} event.
+ * </p>
+ * If the style fails to load or an invalid style URL is set, the map view will become blank.
+ * An error message will be logged in the Android logcat and {@link MapView#DID_FAIL_LOADING_MAP} event will be sent.
+ *
+ * @param url The URL of the map style
+ * @see Style
+ */
+ public void setStyleUrl(@NonNull String url) {
+ if (destroyed) {
+ return;
}
- public void invalidateContentPadding() {
- setContentPadding(contentPaddingLeft, contentPaddingTop, contentPaddingRight, contentPaddingBottom);
-
- if (!mapboxMap.getTrackingSettings().isLocationTrackingDisabled()) {
- setFocalPoint(new PointF(myLocationView.getCenterX(), myLocationView.getCenterY()));
- } else {
- setFocalPoint(null);
- }
+ // stopgap for https://github.com/mapbox/mapbox-gl-native/issues/6242
+ if (TextUtils.isEmpty(nativeMapView.getAccessToken())) {
+ Mapbox.validateAccessToken();
+ nativeMapView.setAccessToken(Mapbox.getAccessToken());
}
- double getMetersPerPixelAtLatitude(@FloatRange(from = -180, to = 180) double latitude) {
- if (destroyed) {
- return 0;
- }
+ nativeMapView.setStyleUrl(url);
+ }
- return nativeMapView.getMetersPerPixelAtLatitude(latitude, getZoom()) / screenDensity;
- }
+ //
+ // Rendering
+ //
- //
- // Mapbox Core GL Camera
- //
+ // Called when the map needs to be rerendered
+ // Called via JNI from NativeMapView
+ protected void onInvalidate() {
+ postInvalidate();
+ }
- void jumpTo(double bearing, LatLng center, double pitch, double zoom) {
- if (destroyed) {
- return;
- }
- nativeMapView.cancelTransitions();
- nativeMapView.jumpTo(bearing, center, pitch, zoom);
+ @Override
+ public void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ if (isInEditMode()) {
+ return;
}
- void easeTo(double bearing, LatLng center, long duration, double pitch, double zoom, boolean easingInterpolator, @Nullable final MapboxMap.CancelableCallback cancelableCallback) {
- if (destroyed) {
- return;
- }
- nativeMapView.cancelTransitions();
-
- // Register callbacks early enough
- if (cancelableCallback != null) {
- addOnMapChangedListener(new OnMapChangedListener() {
- @Override
- public void onMapChanged(@MapChange int change) {
- if (change == REGION_DID_CHANGE_ANIMATED) {
- cancelableCallback.onFinish();
-
- // Clean up after self
- removeOnMapChangedListener(this);
- }
- }
- });
- }
-
- nativeMapView.easeTo(bearing, center, duration, pitch, zoom, easingInterpolator);
+ if (destroyed) {
+ return;
}
- void flyTo(double bearing, LatLng center, long duration, double pitch, double zoom, @Nullable final MapboxMap.CancelableCallback cancelableCallback) {
- if (destroyed) {
- return;
- }
- nativeMapView.cancelTransitions();
-
- // Register callbacks early enough
- if (cancelableCallback != null) {
- addOnMapChangedListener(new OnMapChangedListener() {
- @Override
- public void onMapChanged(@MapChange int change) {
- if (change == REGION_DID_CHANGE_ANIMATED) {
- cancelableCallback.onFinish();
-
- // Clean up after self
- removeOnMapChangedListener(this);
- }
- }
- });
- }
-
- nativeMapView.flyTo(bearing, center, duration, pitch, zoom);
+ if (!hasSurface) {
+ return;
}
- private void adjustTopOffsetPixels() {
- List<Annotation> annotations = mapboxMap.getAnnotations();
- int count = annotations.size();
- for (int i = 0; i < count; i++) {
- Annotation annotation = annotations.get(i);
- if (annotation instanceof Marker) {
- Marker marker = (Marker) annotation;
- marker.setTopOffsetPixels(
- getTopOffsetPixelsForIcon(marker.getIcon()));
- }
- }
+ nativeMapView.render();
+ }
- for (Marker marker : mapboxMap.getSelectedMarkers()) {
- if (marker.isInfoWindowShown()) {
- marker.hideInfoWindow();
- marker.showInfoWindow(mapboxMap, this);
- }
- }
+ @Override
+ protected void onSizeChanged(int width, int height, int oldw, int oldh) {
+ if (destroyed) {
+ return;
}
- private void reloadMarkers() {
- if (destroyed) {
- return;
- }
- List<Annotation> annotations = mapboxMap.getAnnotations();
- int count = annotations.size();
- for (int i = 0; i < count; i++) {
- Annotation annotation = annotations.get(i);
- if (annotation instanceof Marker) {
- Marker marker = (Marker) annotation;
- nativeMapView.removeAnnotation(annotation.getId());
- long newId = nativeMapView.addMarker(marker);
- marker.setId(newId);
- }
- }
+ if (!isInEditMode()) {
+ nativeMapView.resizeView(width, height);
}
+ }
- //
- // Rendering
- //
+ private class SurfaceCallback implements SurfaceHolder.Callback {
- // Called when the map needs to be rerendered
- // Called via JNI from NativeMapView
- protected void onInvalidate() {
- postInvalidate();
- }
+ private Surface surface;
@Override
- public void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- if (isInEditMode()) {
- return;
- }
-
- if (destroyed) {
- return;
- }
-
- if (!hasSurface) {
- return;
- }
-
- nativeMapView.render();
+ public void surfaceCreated(SurfaceHolder holder) {
+ nativeMapView.createSurface(surface = holder.getSurface());
+ hasSurface = true;
}
@Override
- protected void onSizeChanged(int width, int height, int oldw, int oldh) {
- if (destroyed) {
- return;
- }
-
- if (!isInEditMode()) {
- nativeMapView.resizeView((int) (width / screenDensity), (int) (height / screenDensity));
- }
- }
-
- double getScale() {
- if (destroyed) {
- return 0;
- }
-
- return nativeMapView.getScale();
- }
-
- private class SurfaceCallback implements SurfaceHolder.Callback {
-
- private Surface surface;
-
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- nativeMapView.createSurface(surface = holder.getSurface());
- hasSurface = true;
- }
-
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
- if (destroyed) {
- return;
- }
- nativeMapView.resizeFramebuffer(width, height);
- }
-
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- hasSurface = false;
-
- if (nativeMapView != null) {
- nativeMapView.destroySurface();
- }
- surface.release();
- }
+ public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+ if (destroyed) {
+ return;
+ }
+ nativeMapView.resizeFramebuffer(width, height);
}
- // This class handles TextureView callbacks
- private class SurfaceTextureListener implements TextureView.SurfaceTextureListener {
-
- private Surface surface;
-
- // Called when the native surface texture has been created
- // Must do all EGL/GL ES initialization here
- @Override
- public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
- nativeMapView.createSurface(this.surface = new Surface(surface));
- nativeMapView.resizeFramebuffer(width, height);
- hasSurface = true;
- }
-
- // Called when the native surface texture has been destroyed
- // Must do all EGL/GL ES destruction here
- @Override
- public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
- hasSurface = false;
-
- if (nativeMapView != null) {
- nativeMapView.destroySurface();
- }
- this.surface.release();
- return true;
- }
-
- // Called when the format or size of the native surface texture has been changed
- // Must handle window resizing here.
- @Override
- public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
- if (destroyed) {
- return;
- }
-
- nativeMapView.resizeFramebuffer(width, height);
- }
-
- // Called when the SurfaceTexure frame is drawn to screen
- // Must sync with UI here
- @Override
- public void onSurfaceTextureUpdated(SurfaceTexture surface) {
- if (destroyed) {
- return;
- }
- compassView.update(getDirection());
- myLocationView.update();
- mapboxMap.getMarkerViewManager().update();
-
- for (InfoWindow infoWindow : mapboxMap.getInfoWindows()) {
- infoWindow.update();
- }
- }
- }
+ @Override
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ hasSurface = false;
- CameraPosition invalidateCameraPosition() {
- if (destroyed) {
- return new CameraPosition.Builder().build();
- }
- CameraPosition position = new CameraPosition.Builder(nativeMapView.getCameraValues()).build();
- myLocationView.setCameraPosition(position);
- mapboxMap.getMarkerViewManager().setTilt((float) position.tilt);
- return position;
+ if (nativeMapView != null) {
+ nativeMapView.destroySurface();
+ }
+ surface.release();
}
+ }
- double getBearing() {
- if (destroyed) {
- return 0;
- }
-
- double direction = -nativeMapView.getBearing();
-
- while (direction > 360) {
- direction -= 360;
- }
- while (direction < 0) {
- direction += 360;
- }
+ // This class handles TextureView callbacks
+ private class SurfaceTextureListener implements TextureView.SurfaceTextureListener {
- return direction;
- }
+ private Surface surface;
- void setBearing(float bearing) {
- if (destroyed) {
- return;
- }
- myLocationView.setBearing(bearing);
- nativeMapView.setBearing(bearing);
+ // Called when the native surface texture has been created
+ // Must do all EGL/GL ES initialization here
+ @Override
+ public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
+ nativeMapView.createSurface(this.surface = new Surface(surface));
+ nativeMapView.resizeFramebuffer(width, height);
+ hasSurface = true;
}
- void setBearing(float bearing, long duration) {
- if (destroyed) {
- return;
- }
- myLocationView.setBearing(bearing);
- nativeMapView.setBearing(bearing, duration);
- }
+ // Called when the native surface texture has been destroyed
+ // Must do all EGL/GL ES destruction here
+ @Override
+ public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
+ hasSurface = false;
- void setBearing(double bearing, float focalX, float focalY) {
- if (destroyed) {
- return;
- }
- myLocationView.setBearing(bearing);
- nativeMapView.setBearing(bearing, focalX, focalY);
+ if (nativeMapView != null) {
+ nativeMapView.destroySurface();
+ }
+ this.surface.release();
+ return true;
}
- //
- // View events
- //
-
- // Called when view is no longer connected
+ // Called when the format or size of the native surface texture has been changed
+ // Must handle window resizing here.
@Override
- @CallSuper
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- // Required by ZoomButtonController (from Android SDK documentation)
- if (mapboxMap.getUiSettings().isZoomControlsEnabled()) {
- zoomButtonsController.setVisible(false);
- }
+ public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
+ if (destroyed) {
+ return;
+ }
- // make sure we don't leak location listener
- if (myLocationListener != null) {
- // cleanup to prevent memory leak
- LocationServices services = LocationServices.getLocationServices(getContext());
- services.removeLocationListener(myLocationListener);
- myLocationListener = null;
- }
+ nativeMapView.resizeFramebuffer(width, height);
}
- // Called when view is hidden and shown
+ // Called when the SurfaceTexure frame is drawn to screen
+ // Must sync with UI here
@Override
- protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
- if (isInEditMode()) {
- return;
- }
+ public void onSurfaceTextureUpdated(SurfaceTexture surface) {
+ if (destroyed) {
+ return;
+ }
+ mapboxMap.onUpdate();
+ }
+ }
+
+ //
+ // View events
+ //
+
+ // Called when view is no longer connected
+ @Override
+ @CallSuper
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ mapZoomButtonController.setVisible(false);
+ }
+
+ // Called when view is hidden and shown
+ @Override
+ protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
+ if (isInEditMode()) {
+ return;
+ }
+ mapZoomButtonController.setVisible(visibility == View.VISIBLE);
+ }
+
+ //
+ // Connectivity events
+ //
+
+ // This class handles connectivity changes
+ private class ConnectivityReceiver extends BroadcastReceiver {
+
+ // Called when an action we are listening to in the manifest has been sent
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (!destroyed && intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
+ nativeMapView.setReachability(!intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false));
+ }
+ }
+ }
+
+ // Called when MapView is being created
+ private boolean isConnected() {
+ ConnectivityManager connectivityManager = (ConnectivityManager)
+ getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo();
+ return (activeNetwork != null) && activeNetwork.isConnectedOrConnecting();
+ }
+
+ //
+ // Map events
+ //
+
+ /**
+ * <p>
+ * Add a callback that's invoked when the displayed map view changes.
+ * </p>
+ * To remove the callback, use {@link MapView#removeOnMapChangedListener(OnMapChangedListener)}.
+ *
+ * @param listener The callback that's invoked on every frame rendered to the map view.
+ * @see MapView#removeOnMapChangedListener(OnMapChangedListener)
+ */
+ public void addOnMapChangedListener(@Nullable OnMapChangedListener listener) {
+ if (listener != null) {
+ nativeMapView.addOnMapChangedListener(listener);
+ }
+ }
+
+ /**
+ * Remove a callback added with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}
+ *
+ * @param listener The previously added callback to remove.
+ * @see MapView#addOnMapChangedListener(OnMapChangedListener)
+ */
+ public void removeOnMapChangedListener(@Nullable OnMapChangedListener listener) {
+ if (listener != null) {
+ nativeMapView.removeOnMapChangedListener(listener);
+ }
+ }
+
+ // Called when the map view transformation has changed
+ // Called via JNI from NativeMapView
+ // Forward to any listeners
+ protected void onMapChanged(int mapChange) {
+ nativeMapView.onMapChangedEventDispatch(mapChange);
+ }
+
+
+ /**
+ * Sets a callback object which will be triggered when the {@link MapboxMap} instance is ready to be used.
+ *
+ * @param callback The callback object that will be triggered when the map is ready to be used.
+ */
+ @UiThread
+ public void getMapAsync(final OnMapReadyCallback callback) {
+ if (!mapCallback.isInitialLoad() && callback != null) {
+ callback.onMapReady(mapboxMap);
+ } else {
+ if (callback != null) {
+ mapCallback.addOnMapReadyCallback(callback);
+ }
+ }
+ }
+
+ MapboxMap getMapboxMap() {
+ return mapboxMap;
+ }
+
+ void setMapboxMap(MapboxMap mapboxMap) {
+ this.mapboxMap = mapboxMap;
+ }
+
+ //
+ // Snapshot API
+ //
+
+ @UiThread
+ void snapshot(@NonNull final MapboxMap.SnapshotReadyCallback callback, @Nullable final Bitmap bitmap) {
+ snapshotRequest = new SnapshotRequest(bitmap, callback);
+ nativeMapView.scheduleTakeSnapshot();
+ nativeMapView.render();
+ }
+
+ // Called when the snapshot method was executed
+ // Called via JNI from NativeMapView
+ // Forward to any listeners
+ protected void onSnapshotReady(byte[] bytes) {
+ if (snapshotRequest != null && bytes != null) {
+ BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inBitmap = snapshotRequest.getBitmap(); // the old Bitmap to be reused
+ options.inMutable = true;
+ options.inSampleSize = 1;
+ Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
+
+ MapboxMap.SnapshotReadyCallback callback = snapshotRequest.getCallback();
+ if (callback != null) {
+ callback.onSnapshotReady(bitmap);
+ }
+ }
+ }
+
+ private class SnapshotRequest {
+ private Bitmap bitmap;
+ private MapboxMap.SnapshotReadyCallback callback;
+
+ SnapshotRequest(Bitmap bitmap, MapboxMap.SnapshotReadyCallback callback) {
+ this.bitmap = bitmap;
+ this.callback = callback;
+ }
+
+ public Bitmap getBitmap() {
+ return bitmap;
+ }
+
+ public MapboxMap.SnapshotReadyCallback getCallback() {
+ return callback;
+ }
+ }
+
+ private static class AttributionOnClickListener implements View.OnClickListener, DialogInterface.OnClickListener {
+
+ private static final int ATTRIBUTION_INDEX_IMPROVE_THIS_MAP = 2;
+ private static final int ATTRIBUTION_INDEX_TELEMETRY_SETTINGS = 3;
+ private Context context;
+ private Transform transform;
- // Required by ZoomButtonController (from Android SDK documentation)
- if (visibility == View.VISIBLE) {
- if (mapboxMap != null && mapboxMap.getUiSettings().isZoomControlsEnabled()) {
- zoomButtonsController.setVisible(true);
- }
- } else {
- if (mapboxMap != null && mapboxMap.getUiSettings().isZoomControlsEnabled()) {
- zoomButtonsController.setVisible(false);
- }
- }
+ public AttributionOnClickListener(Context context, Transform transform) {
+ this.context = context;
+ this.transform = transform;
+ }
+
+ // Called when someone presses the attribution icon
+ @Override
+ public void onClick(View view) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.mapbox_AlertDialogStyle);
+ builder.setTitle(R.string.mapbox_attributionsDialogTitle);
+ String[] items = context.getResources().getStringArray(R.array.mapbox_attribution_names);
+ builder.setAdapter(new ArrayAdapter<>(context, R.layout.mapbox_attribution_list_item, items), this);
+ builder.show();
}
- //
- // Touch events
- //
-
- /**
- * Helper method for tracking gesture events
- *
- * @param gestureId Type of Gesture See {@see MapboxEvent#GESTURE_SINGLETAP MapboxEvent#GESTURE_DOUBLETAP MapboxEvent#GESTURE_TWO_FINGER_SINGLETAP MapboxEvent#GESTURE_QUICK_ZOOM MapboxEvent#GESTURE_PAN_START MapboxEvent#GESTURE_PINCH_START MapboxEvent#GESTURE_ROTATION_START MapboxEvent#GESTURE_PITCH_START}
- * @param xCoordinate Original x screen coordinate at start of gesture
- * @param yCoordinate Original y screen cooridnate at start of gesture
- */
- private void trackGestureEvent(@NonNull String gestureId, @NonNull float xCoordinate, @NonNull float 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())) {
- Log.d(MapView.class.getSimpleName(), "trackGestureEvent() has a NaN lat or lon. Returning.");
- return;
- }
-
- if (Double.isInfinite(tapLatLng.getLatitude()) || Double.isInfinite(tapLatLng.getLongitude())) {
- Log.d(MapView.class.getSimpleName(), "trackGestureEvent() has an Infinite lat or lon. Returning.");
- return;
- }
-
- Hashtable<String, Object> evt = new Hashtable<>();
- evt.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_MAP_CLICK);
- evt.put(MapboxEvent.ATTRIBUTE_CREATED, MapboxEventManager.generateCreateDate());
- evt.put(MapboxEvent.KEY_GESTURE_ID, gestureId);
- evt.put(MapboxEvent.KEY_LATITUDE, tapLatLng.getLatitude());
- evt.put(MapboxEvent.KEY_LONGITUDE, tapLatLng.getLongitude());
- evt.put(MapboxEvent.KEY_ZOOM, mapboxMap.getCameraPosition().zoom);
-
- MapboxEventManager.getMapboxEventManager().pushEvent(evt);
- }
+ // Called when someone selects an attribution, 'Improve this map' adds location data to the url
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ final Context context = ((Dialog) dialog).getContext();
+ if (which == ATTRIBUTION_INDEX_TELEMETRY_SETTINGS) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.mapbox_AlertDialogStyle);
+ builder.setTitle(R.string.mapbox_attributionTelemetryTitle);
+ builder.setMessage(R.string.mapbox_attributionTelemetryMessage);
+ builder.setPositiveButton(R.string.mapbox_attributionTelemetryPositive, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ MapboxEventManager.getMapboxEventManager().setTelemetryEnabled(true);
+ dialog.cancel();
+ }
+ });
+ builder.setNeutralButton(R.string.mapbox_attributionTelemetryNeutral, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ String url = context.getResources().getStringArray(R.array.mapbox_attribution_links)[3];
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ intent.setData(Uri.parse(url));
+ context.startActivity(intent);
+ dialog.cancel();
+ }
+ });
+ builder.setNegativeButton(R.string.mapbox_attributionTelemetryNegative, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ MapboxEventManager.getMapboxEventManager().setTelemetryEnabled(false);
+ dialog.cancel();
+ }
+ });
+ builder.show();
+ return;
+ }
+ String url = context.getResources().getStringArray(R.array.mapbox_attribution_links)[which];
+ if (which == ATTRIBUTION_INDEX_IMPROVE_THIS_MAP) {
+ CameraPosition cameraPosition = transform.getCameraPosition();
+ if (cameraPosition != null) {
+ url = String.format(url, cameraPosition.target.getLongitude(),
+ cameraPosition.target.getLatitude(), (int) cameraPosition.zoom);
+ }
+ }
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ intent.setData(Uri.parse(url));
+ context.startActivity(intent);
+ }
+ }
+
+ /**
+ * Definition of a map change event.
+ *
+ * @see MapView.OnMapChangedListener#onMapChanged(int)
+ */
+ @IntDef( {REGION_WILL_CHANGE,
+ REGION_WILL_CHANGE_ANIMATED,
+ REGION_IS_CHANGING,
+ REGION_DID_CHANGE,
+ REGION_DID_CHANGE_ANIMATED,
+ WILL_START_LOADING_MAP,
+ DID_FINISH_LOADING_MAP,
+ DID_FAIL_LOADING_MAP,
+ WILL_START_RENDERING_FRAME,
+ DID_FINISH_RENDERING_FRAME,
+ DID_FINISH_RENDERING_FRAME_FULLY_RENDERED,
+ WILL_START_RENDERING_MAP,
+ DID_FINISH_RENDERING_MAP,
+ DID_FINISH_RENDERING_MAP_FULLY_RENDERED,
+ DID_FINISH_LOADING_STYLE,
+ SOURCE_DID_CHANGE
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface MapChange {
+ }
+
+ /**
+ * This event is triggered whenever the currently displayed map region is about to changing
+ * without an animation.
+ * <p>
+ * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
+ * </p>
+ *
+ * @see MapChange
+ * @see MapView.OnMapChangedListener
+ */
+ public static final int REGION_WILL_CHANGE = 0;
+
+ /**
+ * This event is triggered whenever the currently displayed map region is about to changing
+ * with an animation.
+ * <p>
+ * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}
+ * </p>
+ *
+ * @see MapChange
+ * @see MapView.OnMapChangedListener
+ */
+ public static final int REGION_WILL_CHANGE_ANIMATED = 1;
+
+ /**
+ * This event is triggered whenever the currently displayed map region is changing.
+ * <p>
+ * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
+ * </p>
+ *
+ * @see MapChange
+ * @see MapView.OnMapChangedListener
+ */
+ public static final int REGION_IS_CHANGING = 2;
+
+ /**
+ * This event is triggered whenever the currently displayed map region finished changing
+ * without an animation.
+ * <p>
+ * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
+ * </p>
+ *
+ * @see MapChange
+ * @see MapView.OnMapChangedListener
+ */
+ public static final int REGION_DID_CHANGE = 3;
+
+ /**
+ * This event is triggered whenever the currently displayed map region finished changing
+ * with an animation.
+ * <p>
+ * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
+ * </p>
+ *
+ * @see MapChange
+ * @see MapView.OnMapChangedListener
+ */
+ public static final int REGION_DID_CHANGE_ANIMATED = 4;
+
+ /**
+ * This event is triggered when the map is about to start loading a new map style.
+ * <p>
+ * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
+ * </p>
+ *
+ * @see MapChange
+ * @see MapView.OnMapChangedListener
+ */
+ public static final int WILL_START_LOADING_MAP = 5;
+
+ /**
+ * This is triggered when the map has successfully loaded a new map style.
+ * <p>
+ * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
+ * </p>
+ *
+ * @see MapChange
+ * @see MapView.OnMapChangedListener
+ */
+ public static final int DID_FINISH_LOADING_MAP = 6;
+
+ /**
+ * This event is triggered when the map has failed to load a new map style.
+ * <p>
+ * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
+ * </p>
+ *
+ * @see MapChange
+ * @see MapView.OnMapChangedListener
+ */
+ public static final int DID_FAIL_LOADING_MAP = 7;
+
+ /**
+ * This event is triggered when the map will start rendering a frame.
+ * <p>
+ * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
+ * </p>
+ *
+ * @see MapChange
+ * @see MapView.OnMapChangedListener
+ */
+ public static final int WILL_START_RENDERING_FRAME = 8;
+
+ /**
+ * This event is triggered when the map finished rendering a frame.
+ * <p>
+ * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
+ * </p>
+ *
+ * @see MapChange
+ * @see MapView.OnMapChangedListener
+ */
+ public static final int DID_FINISH_RENDERING_FRAME = 9;
+
+ /**
+ * This event is triggered when the map finished rendeirng the frame fully.
+ * <p>
+ * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
+ * </p>
+ *
+ * @see MapChange
+ * @see MapView.OnMapChangedListener
+ */
+ public static final int DID_FINISH_RENDERING_FRAME_FULLY_RENDERED = 10;
+
+ /**
+ * This event is triggered when the map will start rendering the map.
+ * <p>
+ * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
+ * </p>
+ *
+ * @see MapChange
+ * @see MapView.OnMapChangedListener
+ */
+ public static final int WILL_START_RENDERING_MAP = 11;
+
+ /**
+ * This event is triggered when the map finished rendering the map.
+ * <p>
+ * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
+ * </p>
+ *
+ * @see MapChange
+ * @see MapView.OnMapChangedListener
+ */
+ public static final int DID_FINISH_RENDERING_MAP = 12;
+
+ /**
+ * This event is triggered when the map is fully rendered.
+ * <p>
+ * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
+ * </p>
+ *
+ * @see MapChange
+ * @see MapView.OnMapChangedListener
+ */
+ public static final int DID_FINISH_RENDERING_MAP_FULLY_RENDERED = 13;
+
+ /**
+ * This {@link MapChange} is triggered when a style has finished loading.
+ * <p>
+ * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
+ * </p>
+ *
+ * @see MapChange
+ * @see MapView.OnMapChangedListener
+ */
+ public static final int DID_FINISH_LOADING_STYLE = 14;
+
+ /**
+ * This {@link MapChange} is triggered when a source attribution changes.
+ * <p>
+ * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
+ * </p>
+ *
+ * @see MapChange
+ * @see MapView.OnMapChangedListener
+ */
+ public static final int SOURCE_DID_CHANGE = 15;
+
+ /**
+ * Interface definition for a callback to be invoked when the displayed map view changes.
+ * <p>
+ * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
+ * </p>
+ *
+ * @see MapView#addOnMapChangedListener(OnMapChangedListener)
+ * @see MapView.MapChange
+ */
+ public interface OnMapChangedListener {
/**
- * Helper method for tracking DragEnd gesture event
- * See {@see MapboxEvent#TYPE_MAP_DRAGEND}
+ * Called when the displayed map view changes.
*
- * @param xCoordinate Original x screen coordinate at end of drag
- * @param yCoordinate Orginal y screen coordinate at end of drag
+ * @param change Type of map change event, one of {@link #REGION_WILL_CHANGE},
+ * {@link #REGION_WILL_CHANGE_ANIMATED},
+ * {@link #REGION_IS_CHANGING},
+ * {@link #REGION_DID_CHANGE},
+ * {@link #REGION_DID_CHANGE_ANIMATED},
+ * {@link #WILL_START_LOADING_MAP},
+ * {@link #DID_FAIL_LOADING_MAP},
+ * {@link #DID_FINISH_LOADING_MAP},
+ * {@link #WILL_START_RENDERING_FRAME},
+ * {@link #DID_FINISH_RENDERING_FRAME},
+ * {@link #DID_FINISH_RENDERING_FRAME_FULLY_RENDERED},
+ * {@link #WILL_START_RENDERING_MAP},
+ * {@link #DID_FINISH_RENDERING_MAP},
+ * {@link #DID_FINISH_RENDERING_MAP_FULLY_RENDERED}.
*/
- private void trackGestureDragEndEvent(@NonNull float xCoordinate, @NonNull float 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())) {
- Log.d(MapView.class.getSimpleName(), "trackGestureDragEndEvent() has a NaN lat or lon. Returning.");
- return;
- }
-
- if (Double.isInfinite(tapLatLng.getLatitude()) || Double.isInfinite(tapLatLng.getLongitude())) {
- Log.d(MapView.class.getSimpleName(), "trackGestureDragEndEvent() has an Infinite lat or lon. Returning.");
- return;
- }
+ void onMapChanged(@MapChange int change);
+ }
- Hashtable<String, Object> evt = new Hashtable<>();
- evt.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_MAP_DRAGEND);
- evt.put(MapboxEvent.ATTRIBUTE_CREATED, MapboxEventManager.generateCreateDate());
- evt.put(MapboxEvent.KEY_LATITUDE, tapLatLng.getLatitude());
- evt.put(MapboxEvent.KEY_LONGITUDE, tapLatLng.getLongitude());
- evt.put(MapboxEvent.KEY_ZOOM, mapboxMap.getCameraPosition().zoom);
+ private class FocalPointInvalidator implements FocalPointChangeListener {
- MapboxEventManager.getMapboxEventManager().pushEvent(evt);
- }
-
- // Called when user touches the screen, all positions are absolute
@Override
- public boolean onTouchEvent(@NonNull MotionEvent event) {
- // Check and ignore non touch or left clicks
- if (destroyed) {
- return super.onTouchEvent(event);
- }
-
- if ((event.getButtonState() != 0) && (event.getButtonState() != MotionEvent.BUTTON_PRIMARY)) {
- return false;
- }
-
- // Check two finger gestures first
- rotateGestureDetector.onTouchEvent(event);
- scaleGestureDetector.onTouchEvent(event);
- shoveGestureDetector.onTouchEvent(event);
-
- // Handle two finger tap
- switch (event.getActionMasked()) {
- case MotionEvent.ACTION_DOWN:
- // First pointer down
- nativeMapView.setGestureInProgress(true);
- break;
-
- case MotionEvent.ACTION_POINTER_DOWN:
- // Second pointer down
- twoTap = event.getPointerCount() == 2
- && mapboxMap.getUiSettings().isZoomGesturesEnabled();
- if (twoTap) {
- // Confirmed 2nd Finger Down
- trackGestureEvent(MapboxEvent.GESTURE_TWO_FINGER_SINGLETAP, event.getX(), event.getY());
- }
- break;
-
- case MotionEvent.ACTION_POINTER_UP:
- // Second pointer up
- break;
-
- case MotionEvent.ACTION_UP:
- // First pointer up
- long tapInterval = event.getEventTime() - event.getDownTime();
- boolean isTap = tapInterval <= ViewConfiguration.getTapTimeout();
- boolean inProgress = rotateGestureDetector.isInProgress()
- || scaleGestureDetector.isInProgress()
- || shoveGestureDetector.isInProgress();
-
- if (twoTap && isTap && !inProgress) {
- if (focalPoint != null) {
- zoom(false, focalPoint.x, focalPoint.y);
- } else {
- PointF focalPoint = TwoFingerGestureDetector.determineFocalPoint(event);
- zoom(false, focalPoint.x, focalPoint.y);
- }
- twoTap = false;
- return true;
- }
-
- // Scroll / Pan Has Stopped
- if (scrollInProgress) {
- trackGestureDragEndEvent(event.getX(), event.getY());
- scrollInProgress = false;
- }
-
- twoTap = false;
- nativeMapView.setGestureInProgress(false);
- break;
-
- case MotionEvent.ACTION_CANCEL:
- twoTap = false;
- nativeMapView.setGestureInProgress(false);
- break;
- }
-
- boolean retVal = gestureDetector.onTouchEvent(event);
- return retVal || super.onTouchEvent(event);
- }
-
- // This class handles one finger gestures
- private class GestureListener extends GestureDetector.SimpleOnGestureListener {
-
- // Must always return true otherwise all events are ignored
- @Override
- @SuppressLint("ResourceType")
- public boolean onDown(MotionEvent event) {
- // Show the zoom controls
- if (mapboxMap.getUiSettings().isZoomControlsEnabled()) {
- zoomButtonsController.setVisible(true);
- }
- return true;
- }
-
- // Called for double taps
- @Override
- public boolean onDoubleTapEvent(MotionEvent e) {
- if (destroyed || !mapboxMap.getUiSettings().isZoomGesturesEnabled()) {
- return false;
- }
-
- switch (e.getAction()) {
- case MotionEvent.ACTION_DOWN:
- break;
- case MotionEvent.ACTION_MOVE:
- break;
- case MotionEvent.ACTION_UP:
- if (quickZoom) {
- // insert here?
- quickZoom = false;
- break;
- }
-
- // Single finger double tap
- if (focalPoint != null) {
- // User provided focal point
- zoom(true, focalPoint.x, focalPoint.y);
- } else {
- // Zoom in on gesture
- zoom(true, e.getX(), e.getY());
- }
- break;
- }
-
- trackGestureEvent(MapboxEvent.GESTURE_DOUBLETAP, e.getX(), e.getY());
-
- return true;
- }
-
- @Override
- public boolean onSingleTapUp(MotionEvent motionEvent) {
- if (destroyed) {
- return false;
- }
- // Cancel any animation
- nativeMapView.cancelTransitions();
- return true;
- }
-
- @Override
- public boolean onSingleTapConfirmed(MotionEvent motionEvent) {
- List<Marker> selectedMarkers = mapboxMap.getSelectedMarkers();
-
- PointF tapPoint = new PointF(motionEvent.getX(), motionEvent.getY());
- float toleranceSides = 4 * screenDensity;
- float toleranceTopBottom = 10 * screenDensity;
-
- RectF tapRect = new RectF((tapPoint.x - averageIconWidth / 2 - toleranceSides) / screenDensity,
- (tapPoint.y - averageIconHeight / 2 - toleranceTopBottom) / screenDensity,
- (tapPoint.x + averageIconWidth / 2 + toleranceSides) / screenDensity,
- (tapPoint.y + averageIconHeight / 2 + toleranceTopBottom) / screenDensity);
-
- List<Marker> nearbyMarkers = getMarkersInRect(tapRect);
- long newSelectedMarkerId = -1;
-
- if (nearbyMarkers != null && nearbyMarkers.size() > 0) {
- Collections.sort(nearbyMarkers);
- for (Marker nearbyMarker : nearbyMarkers) {
- boolean found = false;
- for (Marker selectedMarker : selectedMarkers) {
- if (selectedMarker.equals(nearbyMarker)) {
- found = true;
- }
- }
- if (!found) {
- newSelectedMarkerId = nearbyMarker.getId();
- break;
- }
- }
- }
-
- if (newSelectedMarkerId >= 0) {
- List<Annotation> annotations = mapboxMap.getAnnotations();
- int count = annotations.size();
- for (int i = 0; i < count; i++) {
- Annotation annotation = annotations.get(i);
- if (annotation instanceof Marker) {
- if (annotation.getId() == newSelectedMarkerId) {
- if (selectedMarkers.isEmpty() || !selectedMarkers.contains(annotation)) {
- if (!(annotation instanceof MarkerView)) {
- mapboxMap.selectMarker((Marker) annotation);
- } else {
- mapboxMap.getMarkerViewManager().onClickMarkerView((MarkerView) annotation);
- }
- }
- break;
- }
- }
- }
- } else {
- if (mapboxMap.getUiSettings().isDeselectMarkersOnTap()) {
- // deselect any selected marker
- mapboxMap.deselectMarkers();
- }
-
- // notify app of map click
- MapboxMap.OnMapClickListener listener = mapboxMap.getOnMapClickListener();
- if (listener != null) {
- LatLng point = projection.fromScreenLocation(tapPoint);
- listener.onMapClick(point);
- }
- }
-
- trackGestureEvent(MapboxEvent.GESTURE_SINGLETAP, motionEvent.getX(), motionEvent.getY());
- return true;
- }
-
- // Called for a long press
- @Override
- public void onLongPress(MotionEvent motionEvent) {
- MapboxMap.OnMapLongClickListener listener = mapboxMap.getOnMapLongClickListener();
- if (listener != null && !quickZoom) {
- LatLng point = projection.fromScreenLocation(new PointF(motionEvent.getX(), motionEvent.getY()));
- listener.onMapLongClick(point);
- }
- }
-
- // Called for flings
- @Override
- public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
- if (destroyed || !mapboxMap.getTrackingSettings().isScrollGestureCurrentlyEnabled()) {
- return false;
- }
-
- resetTrackingModesIfRequired(true, false);
-
- // Fling the map
- float ease = 0.25f;
-
- velocityX = velocityX * ease;
- velocityY = velocityY * ease;
-
- double speed = Math.sqrt(velocityX * velocityX + velocityY * velocityY);
- double deceleration = 2500;
- double duration = speed / (deceleration * ease);
-
- // Cancel any animation
- nativeMapView.cancelTransitions();
-
- nativeMapView.moveBy(velocityX * duration / 2.0 / screenDensity, velocityY * duration / 2.0 / screenDensity, (long) (duration * 1000.0f));
-
- MapboxMap.OnFlingListener listener = mapboxMap.getOnFlingListener();
- if (listener != null) {
- listener.onFling();
- }
-
- trackGestureEvent(MapboxEvent.GESTURE_PAN_START, e1.getX(), e1.getY());
- return true;
- }
-
- // Called for drags
- @Override
- public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
- if (!scrollInProgress) {
- scrollInProgress = true;
- }
- if (destroyed || !mapboxMap.getTrackingSettings().isScrollGestureCurrentlyEnabled()) {
- return false;
- }
-
- if (dragStarted) {
- return false;
- }
-
- requestDisallowInterceptTouchEvent(true);
-
- // reset tracking if needed
- resetTrackingModesIfRequired(true, false);
- // Cancel any animation
- nativeMapView.cancelTransitions();
-
- // Scroll the map
- nativeMapView.moveBy(-distanceX / screenDensity, -distanceY / screenDensity);
-
- MapboxMap.OnScrollListener listener = mapboxMap.getOnScrollListener();
- if (listener != null) {
- listener.onScroll();
- }
- return true;
- }
+ public void onFocalPointChanged(PointF pointF) {
+ mapGestureDetector.setFocalPoint(pointF);
}
+ }
- // This class handles two finger gestures and double-tap drag gestures
- private class ScaleGestureListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
-
- long beginTime = 0;
- float scaleFactor = 1.0f;
-
- // Called when two fingers first touch the screen
- @Override
- public boolean onScaleBegin(ScaleGestureDetector detector) {
- if (destroyed || !mapboxMap.getUiSettings().isZoomGesturesEnabled()) {
- return false;
- }
-
- beginTime = detector.getEventTime();
- trackGestureEvent(MapboxEvent.GESTURE_PINCH_START, detector.getFocusX(), detector.getFocusY());
- return true;
- }
-
- // Called when fingers leave screen
- @Override
- public void onScaleEnd(ScaleGestureDetector detector) {
- beginTime = 0;
- scaleFactor = 1.0f;
- zoomStarted = false;
- }
+ private class RegisterTouchListener implements MapboxMap.OnRegisterTouchListener {
- // Called each time a finger moves
- // Called for pinch zooms and quickzooms/quickscales
- @Override
- public boolean onScale(ScaleGestureDetector detector) {
- UiSettings uiSettings = mapboxMap.getUiSettings();
- if (destroyed || !uiSettings.isZoomGesturesEnabled()) {
- return super.onScale(detector);
- }
-
- // If scale is large enough ignore a tap
- scaleFactor *= detector.getScaleFactor();
- if ((scaleFactor > 1.05f) || (scaleFactor < 0.95f)) {
- zoomStarted = true;
- }
-
- // Ignore short touches in case it is a tap
- // Also ignore small scales
- long time = detector.getEventTime();
- long interval = time - beginTime;
- if (!zoomStarted && (interval <= ViewConfiguration.getTapTimeout())) {
- return false;
- }
-
- if (!zoomStarted) {
- return false;
- }
-
- if (dragStarted) {
- return false;
- }
-
- // Cancel any animation
- nativeMapView.cancelTransitions();
-
- // Gesture is a quickzoom if there aren't two fingers
- quickZoom = !twoTap;
-
- // make an assumption here; if the zoom center is specified by the gesture, it's NOT going
- // to be in the center of the map. Therefore the zoom will translate the map center, so tracking
- // should be disabled.
-
- resetTrackingModesIfRequired(!quickZoom, false);
- // Scale the map
- if (focalPoint != null) {
- // arround user provided focal point
- nativeMapView.scaleBy(detector.getScaleFactor(), focalPoint.x / screenDensity, focalPoint.y / screenDensity);
- } else if (quickZoom) {
- // around center map
- nativeMapView.scaleBy(detector.getScaleFactor(), (getWidth() / 2) / screenDensity, (getHeight() / 2) / screenDensity);
- } else {
- // around gesture
- nativeMapView.scaleBy(detector.getScaleFactor(), detector.getFocusX() / screenDensity, detector.getFocusY() / screenDensity);
- }
-
- return true;
- }
- }
-
- // This class handles two finger rotate gestures
- private class RotateGestureListener extends RotateGestureDetector.SimpleOnRotateGestureListener {
-
- long beginTime = 0;
- float totalAngle = 0.0f;
- boolean started = false;
-
- // Called when two fingers first touch the screen
- @Override
- public boolean onRotateBegin(RotateGestureDetector detector) {
- if (destroyed || !mapboxMap.getTrackingSettings().isRotateGestureCurrentlyEnabled()) {
- return false;
- }
-
- beginTime = detector.getEventTime();
- trackGestureEvent(MapboxEvent.GESTURE_ROTATION_START, detector.getFocusX(), detector.getFocusY());
- return true;
- }
-
- // Called when the fingers leave the screen
- @Override
- public void onRotateEnd(RotateGestureDetector detector) {
- beginTime = 0;
- totalAngle = 0.0f;
- started = false;
- }
-
- // Called each time one of the two fingers moves
- // Called for rotation
- @Override
- public boolean onRotate(RotateGestureDetector detector) {
- if (destroyed || !mapboxMap.getTrackingSettings().isRotateGestureCurrentlyEnabled() || dragStarted) {
- return false;
- }
-
- // If rotate is large enough ignore a tap
- // Also is zoom already started, don't rotate
- totalAngle += detector.getRotationDegreesDelta();
- if (!zoomStarted && ((totalAngle > 20.0f) || (totalAngle < -20.0f))) {
- started = true;
- }
-
- // Ignore short touches in case it is a tap
- // Also ignore small rotate
- long time = detector.getEventTime();
- long interval = time - beginTime;
- if (!started && (interval <= ViewConfiguration.getTapTimeout())) {
- return false;
- }
-
- if (!started) {
- return false;
- }
-
- // Cancel any animation
- nativeMapView.cancelTransitions();
-
- // rotation constitutes translation of anything except the center of
- // rotation, so cancel both location and bearing tracking if required
-
- resetTrackingModesIfRequired(true, true);
-
- // Get rotate value
- double bearing = nativeMapView.getBearing();
- bearing += detector.getRotationDegreesDelta();
-
- // Rotate the map
- if (focalPoint != null) {
- // User provided focal point
- setBearing(bearing, focalPoint.x / screenDensity, focalPoint.y / screenDensity);
- } else {
- // around gesture
- setBearing(bearing, detector.getFocusX() / screenDensity, detector.getFocusY() / screenDensity);
- }
- return true;
- }
- }
-
- // This class handles a vertical two-finger shove. (If you place two fingers on screen with
- // less than a 20 degree angle between them, this will detect movement on the Y-axis.)
- private class ShoveGestureListener implements ShoveGestureDetector.OnShoveGestureListener {
-
- long beginTime = 0;
- float totalDelta = 0.0f;
- boolean started = false;
-
- @Override
- public boolean onShoveBegin(ShoveGestureDetector detector) {
- if (!mapboxMap.getUiSettings().isTiltGesturesEnabled()) {
- return false;
- }
-
- beginTime = detector.getEventTime();
- trackGestureEvent(MapboxEvent.GESTURE_PITCH_START, detector.getFocusX(), detector.getFocusY());
- return true;
- }
-
- @Override
- public void onShoveEnd(ShoveGestureDetector detector) {
- beginTime = 0;
- totalDelta = 0.0f;
- started = false;
- dragStarted = false;
- }
-
- @Override
- public boolean onShove(ShoveGestureDetector detector) {
- if (destroyed || !mapboxMap.getUiSettings().isTiltGesturesEnabled()) {
- return false;
- }
-
- // If tilt is large enough ignore a tap
- // Also if zoom already started, don't tilt
- totalDelta += detector.getShovePixelsDelta();
- if (!zoomStarted && ((totalDelta > 10.0f) || (totalDelta < -10.0f))) {
- started = true;
- }
-
- // Ignore short touches in case it is a tap
- // Also ignore small tilt
- long time = detector.getEventTime();
- long interval = time - beginTime;
- if (!started && (interval <= ViewConfiguration.getTapTimeout())) {
- return false;
- }
-
- if (!started) {
- return false;
- }
-
- // Cancel any animation
- nativeMapView.cancelTransitions();
-
- // Get tilt value (scale and clamp)
- double pitch = getTilt();
- pitch -= 0.1 * detector.getShovePixelsDelta();
- pitch = Math.max(MapboxConstants.MINIMUM_TILT, Math.min(MapboxConstants.MAXIMUM_TILT, pitch));
-
- // Tilt the map
- mapboxMap.setTilt(pitch);
-
- dragStarted = true;
-
- return true;
- }
- }
-
- // This class handles input events from the zoom control buttons
- // Zoom controls allow single touch only devices to zoom in and out
- private class OnZoomListener implements ZoomButtonsController.OnZoomListener {
-
- // Not used
- @Override
- public void onVisibilityChanged(boolean visible) {
- // Ignore
- }
-
- // Called when user pushes a zoom button
- @Override
- public void onZoom(boolean zoomIn) {
- if (!mapboxMap.getUiSettings().isZoomGesturesEnabled()) {
- return;
- }
- zoom(zoomIn);
- }
- }
-
- //
- // Input events
- //
-
- // Called when the user presses a key, also called for repeating keys held
- // down
@Override
- public boolean onKeyDown(int keyCode, @NonNull KeyEvent event) {
- if (destroyed) {
- return super.onKeyDown(keyCode, event);
- }
-
- // If the user has held the scroll key down for a while then accelerate
- // the scroll speed
- double scrollDist = event.getRepeatCount() >= 5 ? 50.0 : 10.0;
-
- // Check which key was pressed via hardware/real key code
- switch (keyCode) {
- // Tell the system to track these keys for long presses on
- // onKeyLongPress is fired
- case KeyEvent.KEYCODE_ENTER:
- case KeyEvent.KEYCODE_DPAD_CENTER:
- event.startTracking();
- return true;
-
- case KeyEvent.KEYCODE_DPAD_LEFT:
- if (!mapboxMap.getTrackingSettings().isScrollGestureCurrentlyEnabled()) {
- return false;
- }
-
- // Cancel any animation
- nativeMapView.cancelTransitions();
-
- // Move left
- nativeMapView.moveBy(scrollDist / screenDensity, 0.0 / screenDensity);
- return true;
-
- case KeyEvent.KEYCODE_DPAD_RIGHT:
- if (!mapboxMap.getTrackingSettings().isScrollGestureCurrentlyEnabled()) {
- return false;
- }
-
- // Cancel any animation
- nativeMapView.cancelTransitions();
-
- // Move right
- nativeMapView.moveBy(-scrollDist / screenDensity, 0.0 / screenDensity);
- return true;
-
- case KeyEvent.KEYCODE_DPAD_UP:
- if (!mapboxMap.getTrackingSettings().isScrollGestureCurrentlyEnabled()) {
- return false;
- }
-
- // Cancel any animation
- nativeMapView.cancelTransitions();
-
- // Move up
- nativeMapView.moveBy(0.0 / screenDensity, scrollDist / screenDensity);
- return true;
-
- case KeyEvent.KEYCODE_DPAD_DOWN:
- if (!mapboxMap.getTrackingSettings().isScrollGestureCurrentlyEnabled()) {
- return false;
- }
-
- // Cancel any animation
- nativeMapView.cancelTransitions();
-
- // Move down
- nativeMapView.moveBy(0.0 / screenDensity, -scrollDist / screenDensity);
- return true;
-
- default:
- // We are not interested in this key
- return super.onKeyUp(keyCode, event);
- }
+ public void onRegisterMapClickListener(MapboxMap.OnMapClickListener listener) {
+ mapGestureDetector.setOnMapClickListener(listener);
}
- // Called when the user long presses a key that is being tracked
@Override
- public boolean onKeyLongPress(int keyCode, KeyEvent event) {
- // Check which key was pressed via hardware/real key code
- switch (keyCode) {
- // Tell the system to track these keys for long presses on
- // onKeyLongPress is fired
- case KeyEvent.KEYCODE_ENTER:
- case KeyEvent.KEYCODE_DPAD_CENTER:
- if (!mapboxMap.getUiSettings().isZoomGesturesEnabled()) {
- return false;
- }
-
- // Zoom out
- zoom(false);
- return true;
-
- default:
- // We are not interested in this key
- return super.onKeyUp(keyCode, event);
- }
+ public void onRegisterMapLongClickListener(MapboxMap.OnMapLongClickListener listener) {
+ mapGestureDetector.setOnMapLongClickListener(listener);
}
- // Called when the user releases a key
@Override
- public boolean onKeyUp(int keyCode, KeyEvent event) {
- // Check if the key action was canceled (used for virtual keyboards)
- if (event.isCanceled()) {
- return super.onKeyUp(keyCode, event);
- }
-
- // Check which key was pressed via hardware/real key code
- // Note if keyboard does not have physical key (ie primary non-shifted
- // key) then it will not appear here
- // Must use the key character map as physical to character is not
- // fixed/guaranteed
- switch (keyCode) {
- case KeyEvent.KEYCODE_ENTER:
- case KeyEvent.KEYCODE_DPAD_CENTER:
- if (!mapboxMap.getUiSettings().isZoomGesturesEnabled()) {
- return false;
- }
-
- // Zoom in
- zoom(true);
- return true;
- }
-
- // We are not interested in this key
- return super.onKeyUp(keyCode, event);
+ public void onRegisterScrollListener(MapboxMap.OnScrollListener listener) {
+ mapGestureDetector.setOnScrollListener(listener);
}
- // Called for trackball events, all motions are relative in device specific
- // units
@Override
- public boolean onTrackballEvent(MotionEvent event) {
- if (destroyed) {
- return false;
- }
- // Choose the action
- switch (event.getActionMasked()) {
- // The trackball was rotated
- case MotionEvent.ACTION_MOVE:
- if (!mapboxMap.getTrackingSettings().isScrollGestureCurrentlyEnabled()) {
- return false;
- }
-
- // Cancel any animation
- nativeMapView.cancelTransitions();
-
- // Scroll the map
- nativeMapView.moveBy(-10.0 * event.getX() / screenDensity, -10.0 * event.getY() / screenDensity);
- return true;
-
- // Trackball was pushed in so start tracking and tell system we are
- // interested
- // We will then get the up action
- case MotionEvent.ACTION_DOWN:
- // Set up a delayed callback to check if trackball is still
- // After waiting the system long press time out
- if (currentTrackballLongPressTimeOut != null) {
- currentTrackballLongPressTimeOut.cancel();
- currentTrackballLongPressTimeOut = null;
- }
- currentTrackballLongPressTimeOut = new TrackballLongPressTimeOut();
- postDelayed(currentTrackballLongPressTimeOut,
- ViewConfiguration.getLongPressTimeout());
- return true;
-
- // Trackball was released
- case MotionEvent.ACTION_UP:
- if (!mapboxMap.getUiSettings().isZoomGesturesEnabled()) {
- return false;
- }
-
- // Only handle if we have not already long pressed
- if (currentTrackballLongPressTimeOut != null) {
- // Zoom in
- zoom(true);
- }
- return true;
-
- // Trackball was cancelled
- case MotionEvent.ACTION_CANCEL:
- if (currentTrackballLongPressTimeOut != null) {
- currentTrackballLongPressTimeOut.cancel();
- currentTrackballLongPressTimeOut = null;
- }
- return true;
-
- default:
- // We are not interested in this event
- return super.onTrackballEvent(event);
- }
+ public void onRegisterFlingListener(MapboxMap.OnFlingListener listener) {
+ mapGestureDetector.setOnFlingListener(listener);
}
+ }
- // This class implements the trackball long press time out callback
- private class TrackballLongPressTimeOut implements Runnable {
-
- // Track if we have been cancelled
- private boolean cancelled;
-
- public TrackballLongPressTimeOut() {
- cancelled = false;
- }
+ private static class MapCallback implements OnMapChangedListener {
- // Cancel the timeout
- public void cancel() {
- cancelled = true;
- }
+ private final MapboxMap mapboxMap;
+ private final List<OnMapReadyCallback> onMapReadyCallbackList = new ArrayList<>();
+ private boolean initialLoad = true;
- // Called when long press time out expires
- @Override
- public void run() {
- // Check if the trackball is still pressed
- if (!cancelled) {
- // Zoom out
- zoom(false);
-
- // Ensure the up action is not run
- currentTrackballLongPressTimeOut = null;
- }
- }
+ MapCallback(MapboxMap mapboxMap) {
+ this.mapboxMap = mapboxMap;
}
- // Called for events that don't fit the other handlers
- // such as mouse scroll events, mouse moves, joystick, trackpad
@Override
- public boolean onGenericMotionEvent(MotionEvent event) {
- if (destroyed) {
- return false;
- }
- // Mouse events
- //if (event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) { // this is not available before API 18
- if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == InputDevice.SOURCE_CLASS_POINTER) {
- // Choose the action
- switch (event.getActionMasked()) {
- // Mouse scrolls
- case MotionEvent.ACTION_SCROLL:
- if (!mapboxMap.getUiSettings().isZoomGesturesEnabled()) {
- return false;
- }
-
- // Cancel any animation
- nativeMapView.cancelTransitions();
-
- // Get the vertical scroll amount, one click = 1
- float scrollDist = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
-
- // Scale the map by the appropriate power of two factor
- nativeMapView.scaleBy(Math.pow(2.0, scrollDist), event.getX() / screenDensity, event.getY() / screenDensity);
-
- return true;
-
- default:
- // We are not interested in this event
- return super.onGenericMotionEvent(event);
- }
- }
-
- // We are not interested in this event
- return super.onGenericMotionEvent(event);
- }
-
- // Called when the mouse pointer enters or exits the view
- // or when it fades in or out due to movement
- @Override
- public boolean onHoverEvent(@NonNull MotionEvent event) {
- switch (event.getActionMasked()) {
- case MotionEvent.ACTION_HOVER_ENTER:
- case MotionEvent.ACTION_HOVER_MOVE:
- // Show the zoom controls
- if (mapboxMap.getUiSettings().isZoomControlsEnabled()) {
- zoomButtonsController.setVisible(true);
- }
- return true;
-
- case MotionEvent.ACTION_HOVER_EXIT:
- // Hide the zoom controls
- if (mapboxMap.getUiSettings().isZoomControlsEnabled()) {
- zoomButtonsController.setVisible(false);
- }
- return true;
-
- default:
- // We are not interested in this event
- return super.onHoverEvent(event);
- }
- }
-
- //
- // Connectivity events
- //
-
- // This class handles connectivity changes
- private class ConnectivityReceiver extends BroadcastReceiver {
-
- // Called when an action we are listening to in the manifest has been sent
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
- boolean noConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
- onConnectivityChanged(!noConnectivity);
- }
- }
- }
-
- // Called when MapView is being created
- private boolean isConnected() {
- Context appContext = getContext().getApplicationContext();
- ConnectivityManager connectivityManager = (ConnectivityManager) appContext.getSystemService(Context.CONNECTIVITY_SERVICE);
- NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo();
- return (activeNetwork != null) && activeNetwork.isConnectedOrConnecting();
- }
-
- // Called when our Internet connectivity has changed
- private void onConnectivityChanged(boolean isConnected) {
- nativeMapView.setReachability(isConnected);
+ public void onMapChanged(@MapChange int change) {
+ if (change == DID_FINISH_LOADING_STYLE && initialLoad) {
+ initialLoad = false;
+ mapboxMap.onPreMapReady();
+ onMapReady();
+ mapboxMap.onPostMapReady();
+ } else if (change == REGION_IS_CHANGING || change == REGION_DID_CHANGE || change == DID_FINISH_LOADING_MAP) {
+ mapboxMap.onUpdate();
+ }
}
- //
- // Map events
- //
-
- /**
- * <p>
- * Add a callback that's invoked when the displayed map view changes.
- * </p>
- * To remove the callback, use {@link MapView#removeOnMapChangedListener(OnMapChangedListener)}.
- *
- * @param listener The callback that's invoked on every frame rendered to the map view.
- * @see MapView#removeOnMapChangedListener(OnMapChangedListener)
- */
- public void addOnMapChangedListener(@Nullable OnMapChangedListener listener) {
- if (listener != null) {
- onMapChangedListener.add(listener);
+ private void onMapReady() {
+ if (onMapReadyCallbackList.size() > 0) {
+ // Notify listeners, clear when done
+ Iterator<OnMapReadyCallback> iterator = onMapReadyCallbackList.iterator();
+ while (iterator.hasNext()) {
+ OnMapReadyCallback callback = iterator.next();
+ callback.onMapReady(mapboxMap);
+ iterator.remove();
}
+ }
}
- /**
- * Remove a callback added with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}
- *
- * @param listener The previously added callback to remove.
- * @see MapView#addOnMapChangedListener(OnMapChangedListener)
- */
- public void removeOnMapChangedListener(@Nullable OnMapChangedListener listener) {
- if (listener != null) {
- onMapChangedListener.remove(listener);
- }
+ public boolean isInitialLoad() {
+ return initialLoad;
}
- // Called when the map view transformation has changed
- // Called via JNI from NativeMapView
- // Forward to any listeners
- protected void onMapChanged(int mapChange) {
- if (onMapChangedListener != null) {
- OnMapChangedListener listener;
- final Iterator<OnMapChangedListener> iterator = onMapChangedListener.iterator();
- while (iterator.hasNext()) {
- listener = iterator.next();
- listener.onMapChanged(mapChange);
- }
- }
+ void addOnMapReadyCallback(OnMapReadyCallback callback) {
+ onMapReadyCallbackList.add(callback);
}
-
- //
- // User location
- //
-
- void setMyLocationEnabled(boolean enabled) {
- myLocationView.setEnabled(enabled);
- }
-
- Location getMyLocation() {
- return myLocationView.getLocation();
- }
-
- void setOnMyLocationChangeListener(@Nullable final MapboxMap.OnMyLocationChangeListener listener) {
- if (listener != null) {
- myLocationListener = new LocationListener() {
- @Override
- public void onLocationChanged(Location location) {
- if (listener != null) {
- listener.onMyLocationChange(location);
- }
- }
- };
- LocationServices.getLocationServices(getContext()).addLocationListener(myLocationListener);
- } else {
- LocationServices.getLocationServices(getContext()).removeLocationListener(myLocationListener);
- myLocationListener = null;
- }
- }
-
- void setMyLocationTrackingMode(@MyLocationTracking.Mode int myLocationTrackingMode) {
- if (myLocationTrackingMode != MyLocationTracking.TRACKING_NONE && !mapboxMap.isMyLocationEnabled()) {
- mapboxMap.setMyLocationEnabled(true);
- }
- myLocationView.setMyLocationTrackingMode(myLocationTrackingMode);
-
- if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW) {
- setFocalPoint(new PointF(myLocationView.getCenterX(), myLocationView.getCenterY()));
- } else {
- setFocalPoint(null);
- }
-
- MapboxMap.OnMyLocationTrackingModeChangeListener listener = mapboxMap.getOnMyLocationTrackingModeChangeListener();
- if (listener != null) {
- listener.onMyLocationTrackingModeChange(myLocationTrackingMode);
- }
- }
-
- void setMyBearingTrackingMode(@MyBearingTracking.Mode int myBearingTrackingMode) {
- if (myBearingTrackingMode != MyBearingTracking.NONE && !mapboxMap.isMyLocationEnabled()) {
- mapboxMap.setMyLocationEnabled(true);
- }
- myLocationView.setMyBearingTrackingMode(myBearingTrackingMode);
- MapboxMap.OnMyBearingTrackingModeChangeListener listener = mapboxMap.getOnMyBearingTrackingModeChangeListener();
- if (listener != null) {
- listener.onMyBearingTrackingModeChange(myBearingTrackingMode);
- }
- }
-
- boolean isPermissionsAccepted() {
- return (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) ||
- ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
- }
-
- /**
- * Reset the tracking modes as necessary. Location tracking is reset if the map center is changed,
- * bearing tracking if there is a rotation.
- *
- * @param translate
- * @param rotate
- */
- void resetTrackingModesIfRequired(boolean translate, boolean rotate) {
- TrackingSettings trackingSettings = mapboxMap.getTrackingSettings();
-
- // if tracking is on, and we should dismiss tracking with gestures, and this is a scroll action, turn tracking off
- if (translate && !trackingSettings.isLocationTrackingDisabled() && trackingSettings.isDismissLocationTrackingOnGesture()) {
- resetLocationTrackingMode();
- }
-
- // reset bearing tracking only on rotate
- if (rotate && !trackingSettings.isBearingTrackingDisabled() && trackingSettings.isDismissBearingTrackingOnGesture()) {
- resetBearingTrackingMode();
- }
- }
-
- void resetTrackingModesIfRequired(CameraPosition cameraPosition) {
- resetTrackingModesIfRequired(cameraPosition.target != null, cameraPosition.bearing != -1);
- }
-
- private void resetLocationTrackingMode() {
- try {
- TrackingSettings trackingSettings = mapboxMap.getTrackingSettings();
- trackingSettings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_NONE);
- } catch (SecurityException ignore) {
- // User did not accept location permissions
- }
- }
-
- private void resetBearingTrackingMode() {
- try {
- TrackingSettings trackingSettings = mapboxMap.getTrackingSettings();
- trackingSettings.setMyBearingTrackingMode(MyBearingTracking.NONE);
- } catch (SecurityException ignore) {
- // User did not accept location permissions
- }
- }
-
- //
- // Compass
- //
-
- void setCompassEnabled(boolean compassEnabled) {
- compassView.setEnabled(compassEnabled);
- }
-
- void setCompassGravity(int gravity) {
- setWidgetGravity(compassView, gravity);
- }
-
- void setCompassMargins(int left, int top, int right, int bottom) {
- setWidgetMargins(compassView, left, top, right, bottom);
- }
-
- void setCompassFadeFacingNorth(boolean compassFadeFacingNorth) {
- compassView.fadeCompassViewFacingNorth(compassFadeFacingNorth);
- }
-
- //
- // Logo
- //
-
- void setLogoGravity(int gravity) {
- setWidgetGravity(logoView, gravity);
- }
-
- void setLogoMargins(int left, int top, int right, int bottom) {
- setWidgetMargins(logoView, left, top, right, bottom);
- }
-
- void setLogoEnabled(boolean visible) {
- logoView.setVisibility(visible ? View.VISIBLE : View.GONE);
- }
-
- //
- // Attribution
- //
-
- void setAttributionGravity(int gravity) {
- setWidgetGravity(attributionsView, gravity);
- }
-
- void setAttributionMargins(int left, int top, int right, int bottom) {
- setWidgetMargins(attributionsView, left, top, right, bottom);
- }
-
- void setAttributionEnabled(int visibility) {
- attributionsView.setVisibility(visibility);
- }
-
- void setAtttibutionTintColor(int tintColor) {
- ColorUtils.setTintList(attributionsView, tintColor);
- }
-
- int getAttributionTintColor() {
- return mapboxMap.getUiSettings().getAttributionTintColor();
- }
-
- /**
- * Sets a callback object which will be triggered when the {@link MapboxMap} instance is ready to be used.
- *
- * @param callback The callback object that will be triggered when the map is ready to be used.
- */
- @UiThread
- public void getMapAsync(final OnMapReadyCallback callback) {
- if (!initialLoad && callback != null) {
- callback.onMapReady(mapboxMap);
- } else {
- if (callback != null) {
- onMapReadyCallbackList.add(callback);
- }
- }
- }
-
- MapboxMap getMapboxMap() {
- return mapboxMap;
- }
-
- void setMapboxMap(MapboxMap mapboxMap) {
- this.mapboxMap = mapboxMap;
- }
-
- MyLocationView getUserLocationView() {
- return myLocationView;
- }
-
- NativeMapView getNativeMapView() {
- return nativeMapView;
- }
-
- //
- // Snapshot API
- //
-
- @UiThread
- void snapshot(@NonNull final MapboxMap.SnapshotReadyCallback callback, @Nullable final Bitmap bitmap) {
- snapshotRequest = new SnapshotRequest(bitmap, callback);
- nativeMapView.scheduleTakeSnapshot();
- nativeMapView.render();
- }
-
- // Called when the snapshot method was executed
- // Called via JNI from NativeMapView
- // Forward to any listeners
- protected void onSnapshotReady(byte[] bytes) {
- if (snapshotRequest != null && bytes != null) {
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inBitmap = snapshotRequest.getBitmap(); // the old Bitmap to be reused
- options.inMutable = true;
- options.inSampleSize = 1;
- Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
-
- MapboxMap.SnapshotReadyCallback callback = snapshotRequest.getCallback();
- if (callback != null) {
- callback.onSnapshotReady(bitmap);
- }
- }
- }
-
- private class SnapshotRequest {
- private Bitmap bitmap;
- private MapboxMap.SnapshotReadyCallback callback;
-
- public SnapshotRequest(Bitmap bitmap, MapboxMap.SnapshotReadyCallback callback) {
- this.bitmap = bitmap;
- this.callback = callback;
- }
-
- public Bitmap getBitmap() {
- return bitmap;
- }
-
- public MapboxMap.SnapshotReadyCallback getCallback() {
- return callback;
- }
- }
-
- //
- // View utility methods
- //
-
- private void setWidgetGravity(@NonNull final View view, int gravity) {
- LayoutParams layoutParams = (LayoutParams) view.getLayoutParams();
- layoutParams.gravity = gravity;
- view.setLayoutParams(layoutParams);
- }
-
- private void setWidgetMargins(@NonNull final View view, int left, int top, int right, int bottom) {
- LayoutParams layoutParams = (LayoutParams) view.getLayoutParams();
- left += contentPaddingLeft;
- top += contentPaddingTop;
- right += contentPaddingRight;
- bottom += contentPaddingBottom;
- layoutParams.setMargins(left, top, right, bottom);
- view.setLayoutParams(layoutParams);
- }
-
- private static class AttributionOnClickListener implements View.OnClickListener, DialogInterface.OnClickListener {
-
- private static final int ATTRIBUTION_INDEX_IMPROVE_THIS_MAP = 2;
- private static final int ATTRIBUTION_INDEX_TELEMETRY_SETTINGS = 3;
- private MapView mapView;
-
- public AttributionOnClickListener(MapView mapView) {
- super();
- this.mapView = mapView;
- }
-
- // Called when someone presses the attribution icon
- @Override
- public void onClick(View view) {
-
- AlertDialog.Builder builder = new AlertDialog.Builder(mapView.getContext(), R.style.TelemAlertDialogStyle);
- builder.setTitle(R.string.attributionsDialogTitle);
- String[] items = mapView.getContext().getResources().getStringArray(R.array.attribution_names);
- builder.setAdapter(new ArrayAdapter<>(mapView.getContext(), R.layout.attribution_list_item, items), this);
- AlertDialog attributionDialog = builder.show();
-
- // TODO Change listview text color to mapView.getAttributionTintColor()
- }
-
- // Called when someone selects an attribution, 'Improve this map' adds location data to the url
- @Override
- public void onClick(DialogInterface dialog, int which) {
- final Context context = ((Dialog) dialog).getContext();
- if (which == ATTRIBUTION_INDEX_TELEMETRY_SETTINGS) {
- AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.TelemAlertDialogStyle);
- builder.setTitle(R.string.attributionTelemetryTitle);
- builder.setMessage(R.string.attributionTelemetryMessage);
- builder.setPositiveButton(R.string.attributionTelemetryPositive, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- MapboxEventManager.getMapboxEventManager().setTelemetryEnabled(true);
- dialog.cancel();
- }
- });
- builder.setNeutralButton(R.string.attributionTelemetryNeutral, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- String url = context.getResources().getStringArray(R.array.attribution_links)[3];
- Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setData(Uri.parse(url));
- context.startActivity(intent);
- dialog.cancel();
- }
- });
- builder.setNegativeButton(R.string.attributionTelemetryNegative, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- MapboxEventManager.getMapboxEventManager().setTelemetryEnabled(false);
- dialog.cancel();
- }
- });
-
- AlertDialog telemDialog = builder.show();
- telemDialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(mapView.getAttributionTintColor());
- telemDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(mapView.getAttributionTintColor());
- telemDialog.getButton(AlertDialog.BUTTON_NEUTRAL).setTextColor(mapView.getAttributionTintColor());
- return;
- }
- String url = context.getResources().getStringArray(R.array.attribution_links)[which];
- if (which == ATTRIBUTION_INDEX_IMPROVE_THIS_MAP) {
- LatLng latLng = mapView.getMapboxMap().getCameraPosition().target;
- url = String.format(url, latLng.getLongitude(), latLng.getLatitude(), (int) mapView.getZoom());
- }
- Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setData(Uri.parse(url));
- context.startActivity(intent);
- }
- }
-
- private static class ZoomInvalidator implements Runnable {
-
- private MapboxMap mapboxMap;
-
- public ZoomInvalidator(MapboxMap mapboxMap) {
- this.mapboxMap = mapboxMap;
- }
-
- @Override
- public void run() {
- // invalidate camera position
- mapboxMap.getCameraPosition();
- }
- }
-
- /**
- * Definition of a map change event.
- *
- * @see MapView.OnMapChangedListener#onMapChanged(int)
- */
- @IntDef({REGION_WILL_CHANGE,
- REGION_WILL_CHANGE_ANIMATED,
- REGION_IS_CHANGING,
- REGION_DID_CHANGE,
- REGION_DID_CHANGE_ANIMATED,
- WILL_START_LOADING_MAP,
- DID_FINISH_LOADING_MAP,
- DID_FAIL_LOADING_MAP,
- WILL_START_RENDERING_FRAME,
- DID_FINISH_RENDERING_FRAME,
- DID_FINISH_RENDERING_FRAME_FULLY_RENDERED,
- WILL_START_RENDERING_MAP,
- DID_FINISH_RENDERING_MAP,
- DID_FINISH_RENDERING_MAP_FULLY_RENDERED,
- DID_FINISH_LOADING_STYLE
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface MapChange {
- }
-
- /**
- * This event is triggered whenever the currently displayed map region is about to changing
- * without an animation.
- * <p>
- * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
- * </p>
- *
- * @see MapChange
- * @see MapView.OnMapChangedListener
- */
- public static final int REGION_WILL_CHANGE = 0;
-
- /**
- * This event is triggered whenever the currently displayed map region is about to changing
- * with an animation.
- * <p
- * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}
- * </p>
- *
- * @see MapChange
- * @see MapView.OnMapChangedListener
- */
- public static final int REGION_WILL_CHANGE_ANIMATED = 1;
-
- /**
- * This event is triggered whenever the currently displayed map region is changing.
- * <p>
- * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
- * </p>
- *
- * @see MapChange
- * @see MapView.OnMapChangedListener
- */
- public static final int REGION_IS_CHANGING = 2;
-
- /**
- * This event is triggered whenever the currently displayed map region finished changing
- * without an animation.
- * <p>
- * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
- * </p>
- *
- * @see MapChange
- * @see MapView.OnMapChangedListener
- */
- public static final int REGION_DID_CHANGE = 3;
-
- /**
- * This event is triggered whenever the currently displayed map region finished changing
- * with an animation.
- * <p>
- * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
- * </p>
- *
- * @see MapChange
- * @see MapView.OnMapChangedListener
- */
- public static final int REGION_DID_CHANGE_ANIMATED = 4;
-
- /**
- * This event is triggered when the map is about to start loading a new map style.
- * <p>
- * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
- * </p>
- *
- * @see MapChange
- * @see MapView.OnMapChangedListener
- */
- public static final int WILL_START_LOADING_MAP = 5;
-
- /**
- * This is triggered when the map has successfully loaded a new map style.
- * <p>
- * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
- * </p>
- *
- * @see MapChange
- * @see MapView.OnMapChangedListener
- */
- public static final int DID_FINISH_LOADING_MAP = 6;
-
- /**
- * This event is triggered when the map has failed to load a new map style.
- * <p>
- * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
- * </p>
- *
- * @see MapChange
- * @see MapView.OnMapChangedListener
- */
- public static final int DID_FAIL_LOADING_MAP = 7;
-
- /**
- * This event is triggered when the map will start rendering a frame.
- * <p>
- * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
- * </p>
- *
- * @see MapChange
- * @see MapView.OnMapChangedListener
- */
- public static final int WILL_START_RENDERING_FRAME = 8;
-
- /**
- * This event is triggered when the map finished rendering a frame.
- * <p>
- * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
- * </p>
- *
- * @see MapChange
- * @see MapView.OnMapChangedListener
- */
- public static final int DID_FINISH_RENDERING_FRAME = 9;
-
- /**
- * This event is triggered when the map finished rendeirng the frame fully.
- * <p>
- * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
- * </p>
- *
- * @see MapChange
- * @see MapView.OnMapChangedListener
- */
- public static final int DID_FINISH_RENDERING_FRAME_FULLY_RENDERED = 10;
-
- /**
- * This event is triggered when the map will start rendering the map.
- * <p>
- * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
- * </p>
- *
- * @see MapChange
- * @see MapView.OnMapChangedListener
- */
- public static final int WILL_START_RENDERING_MAP = 11;
-
- /**
- * This event is triggered when the map finished rendering the map.
- * <p>
- * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
- * </p>
- *
- * @see MapChange
- * @see MapView.OnMapChangedListener
- */
- public static final int DID_FINISH_RENDERING_MAP = 12;
-
- /**
- * This event is triggered when the map is fully rendered.
- * <p>
- * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
- * </p>
- *
- * @see MapChange
- * @see MapView.OnMapChangedListener
- */
- public static final int DID_FINISH_RENDERING_MAP_FULLY_RENDERED = 13;
-
-
- /**
- * This {@link MapChange} is triggered when a style has finished loading.
- * <p>
- * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
- * </p>
- *
- * @see MapChange
- * @see MapView.OnMapChangedListener
- */
- public static final int DID_FINISH_LOADING_STYLE = 14;
-
- /**
- * Interface definition for a callback to be invoked when the displayed map view changes.
- * <p>
- * Register to {@link MapChange} events with {@link MapView#addOnMapChangedListener(OnMapChangedListener)}.
- * </p>
- *
- * @see MapView#addOnMapChangedListener(OnMapChangedListener)
- * @see MapView.MapChange
- */
- public interface OnMapChangedListener {
- /**
- * Called when the displayed map view changes.
- *
- * @param change Type of map change event, one of {@link #REGION_WILL_CHANGE},
- * {@link #REGION_WILL_CHANGE_ANIMATED},
- * {@link #REGION_IS_CHANGING},
- * {@link #REGION_DID_CHANGE},
- * {@link #REGION_DID_CHANGE_ANIMATED},
- * {@link #WILL_START_LOADING_MAP},
- * {@link #DID_FAIL_LOADING_MAP},
- * {@link #DID_FINISH_LOADING_MAP},
- * {@link #WILL_START_RENDERING_FRAME},
- * {@link #DID_FINISH_RENDERING_FRAME},
- * {@link #DID_FINISH_RENDERING_FRAME_FULLY_RENDERED},
- * {@link #WILL_START_RENDERING_MAP},
- * {@link #DID_FINISH_RENDERING_MAP},
- * {@link #DID_FINISH_RENDERING_MAP_FULLY_RENDERED}.
- */
- void onMapChanged(@MapChange int change);
- }
-
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapZoomButtonController.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapZoomButtonController.java
new file mode 100644
index 0000000000..06084d906e
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapZoomButtonController.java
@@ -0,0 +1,59 @@
+package com.mapbox.mapboxsdk.maps;
+
+import android.support.annotation.NonNull;
+import android.view.View;
+import android.widget.ZoomButtonsController;
+
+import com.mapbox.mapboxsdk.constants.MapboxConstants;
+
+/**
+ * The MapZoomButtonController is a ui interface element shown on top of the map.
+ * <p>
+ * Allows single touch only devices to zoom in and out.
+ * </p>
+ */
+final class MapZoomButtonController extends ZoomButtonsController {
+
+ private UiSettings uiSettings;
+
+ MapZoomButtonController(@NonNull View ownerView, @NonNull UiSettings uiSettings, @NonNull Transform transform) {
+ super(ownerView);
+ this.uiSettings = uiSettings;
+ setZoomSpeed(MapboxConstants.ANIMATION_DURATION);
+ setOnZoomListener(new OnZoomListener(uiSettings, transform));
+ }
+
+ @Override
+ public void setVisible(boolean visible) {
+ if (uiSettings.isZoomControlsEnabled()) {
+ super.setVisible(visible);
+ }
+ }
+
+ // Zoom controls allow single touch only devices to zoom in and out
+ private static class OnZoomListener implements ZoomButtonsController.OnZoomListener {
+
+ private final UiSettings uiSettings;
+ private final Transform transform;
+
+ OnZoomListener(UiSettings uiSettings, Transform transform) {
+ this.uiSettings = uiSettings;
+ this.transform = transform;
+ }
+
+ // Not used
+ @Override
+ public void onVisibilityChanged(boolean visible) {
+ // Ignore
+ }
+
+ // Called when user pushes a zoom button
+ @Override
+ public void onZoom(boolean zoomIn) {
+ if (!uiSettings.isZoomGesturesEnabled()) {
+ return;
+ }
+ transform.zoom(zoomIn);
+ }
+ }
+}
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 b1f0984e3c..c09fd0ed49 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
@@ -5,24 +5,21 @@ import android.graphics.Bitmap;
import android.graphics.PointF;
import android.graphics.RectF;
import android.location.Location;
-import android.os.SystemClock;
+import android.os.Bundle;
+import android.os.Handler;
import android.support.annotation.FloatRange;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
-import android.support.v4.util.LongSparseArray;
import android.support.v4.util.Pools;
import android.text.TextUtils;
-import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
-import com.mapbox.mapboxsdk.MapboxAccountManager;
+import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.annotations.Annotation;
import com.mapbox.mapboxsdk.annotations.BaseMarkerOptions;
import com.mapbox.mapboxsdk.annotations.BaseMarkerViewOptions;
-import com.mapbox.mapboxsdk.annotations.Icon;
-import com.mapbox.mapboxsdk.annotations.InfoWindow;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
import com.mapbox.mapboxsdk.annotations.MarkerView;
@@ -47,9 +44,9 @@ import com.mapbox.mapboxsdk.style.sources.Source;
import com.mapbox.services.commons.geojson.Feature;
import java.lang.reflect.ParameterizedType;
-import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.TimeUnit;
+
+import timber.log.Timber;
/**
* The general class to interact with in the Android Mapbox SDK. It exposes the entry point for all
@@ -60,2165 +57,1937 @@ import java.util.concurrent.TimeUnit;
* Note: Similar to a View object, a MapboxMap should only be read and modified from the main thread.
* </p>
*/
-public class MapboxMap {
- private static final String TAG = MapboxMap.class.getSimpleName();
-
- private MapView mapView;
- private UiSettings uiSettings;
- private TrackingSettings trackingSettings;
- private MyLocationViewSettings myLocationViewSettings;
- private Projection projection;
- private CameraPosition cameraPosition;
- private boolean invalidCameraPosition;
- private LongSparseArray<Annotation> annotations;
-
- private List<Marker> selectedMarkers;
- private MarkerViewManager markerViewManager;
-
- private List<InfoWindow> infoWindows;
- private MapboxMap.InfoWindowAdapter infoWindowAdapter;
-
- private boolean myLocationEnabled;
- private boolean allowConcurrentMultipleInfoWindows;
-
- private MapboxMap.OnMapClickListener onMapClickListener;
- private MapboxMap.OnMapLongClickListener onMapLongClickListener;
- private MapboxMap.OnMarkerClickListener onMarkerClickListener;
- private MapboxMap.OnInfoWindowClickListener onInfoWindowClickListener;
- private MapboxMap.OnInfoWindowLongClickListener onInfoWindowLongClickListener;
- private MapboxMap.OnInfoWindowCloseListener onInfoWindowCloseListener;
- private MapboxMap.OnFlingListener onFlingListener;
- private MapboxMap.OnScrollListener onScrollListener;
- private MapboxMap.OnMyLocationTrackingModeChangeListener onMyLocationTrackingModeChangeListener;
- private MapboxMap.OnMyBearingTrackingModeChangeListener onMyBearingTrackingModeChangeListener;
- private MapboxMap.OnFpsChangedListener onFpsChangedListener;
- private MapboxMap.OnCameraChangeListener onCameraChangeListener;
-
- private double maxZoomLevel = -1;
- private double minZoomLevel = -1;
-
- MapboxMap(@NonNull MapView mapView) {
- this.mapView = mapView;
- this.mapView.addOnMapChangedListener(new MapChangeCameraPositionListener());
- uiSettings = new UiSettings(mapView);
- trackingSettings = new TrackingSettings(this.mapView, uiSettings);
- projection = new Projection(mapView);
- annotations = new LongSparseArray<>();
- selectedMarkers = new ArrayList<>();
- infoWindows = new ArrayList<>();
- markerViewManager = new MarkerViewManager(this, mapView);
- }
-
- // Style
-
- @Nullable
- @UiThread
- public Layer getLayer(@NonNull String layerId) {
- return getMapView().getNativeMapView().getLayer(layerId);
- }
-
- /**
- * Tries to cast the Layer to T, returns null if it's another type.
- *
- * @param layerId the layer id used to look up a layer
- * @param <T> the generic attribute of a Layer
- * @return the casted Layer, null if another type
- */
- @Nullable
- @UiThread
- public <T extends Layer> T getLayerAs(@NonNull String layerId) {
- try {
- //noinspection unchecked
- return (T) getMapView().getNativeMapView().getLayer(layerId);
- } catch (ClassCastException e) {
- Log.e(TAG, String.format("Layer: %s is a different type: %s", layerId, e.getMessage()));
- return null;
- }
- }
-
- @UiThread
- public void addLayer(@NonNull Layer layer) {
- addLayer(layer, null);
- }
-
- @UiThread
- public void addLayer(@NonNull Layer layer, String before) {
- getMapView().getNativeMapView().addLayer(layer, before);
- }
-
- @UiThread
- public void removeLayer(@NonNull String layerId) throws NoSuchLayerException {
- getMapView().getNativeMapView().removeLayer(layerId);
- }
-
- @Nullable
- @UiThread
- public Source getSource(@NonNull String sourceId) {
- return getMapView().getNativeMapView().getSource(sourceId);
- }
-
- /**
- * Tries to cast the Source to T, returns null if it's another type.
- *
- * @param sourceId the id used to look up a layer
- * @param <T> the generic type of a Source
- * @return the casted Source, null if another type
- */
- @Nullable
- @UiThread
- public <T extends Source> T getSourceAs(@NonNull String sourceId) {
- try {
- //noinspection unchecked
- return (T) getMapView().getNativeMapView().getSource(sourceId);
- } catch (ClassCastException e) {
- Log.e(TAG, String.format("Source: %s is a different type: %s", sourceId, e.getMessage()));
- return null;
- }
- }
-
- @UiThread
- public void addSource(@NonNull Source source) {
- getMapView().getNativeMapView().addSource(source);
- }
-
- @UiThread
- public void removeSource(@NonNull String sourceId) throws NoSuchSourceException {
- getMapView().getNativeMapView().removeSource(sourceId);
- }
-
- /**
- * Add an image to be used int hte map's style
- *
- * @param name the name of the image
- * @param image the pre-multiplied Bitmap
- */
- @UiThread
- public void addImage(@NonNull String name, @NonNull Bitmap image) {
- getMapView().getNativeMapView().addImage(name, image);
- }
-
- /**
- * Removes an image from the map's style
- *
- * @param name the name of the image to remove
- */
- @UiThread
- public void removeImage(String name) {
- getMapView().getNativeMapView().removeImage(name);
- }
-
- //
- // MinZoom
- //
-
- /**
- * <p>
- * Sets the minimum zoom level the map can be displayed at.
- * </p>
- *
- * @param minZoom The new minimum zoom level.
- */
- @UiThread
- public void setMinZoom(
- @FloatRange(from = MapboxConstants.MINIMUM_ZOOM, to = MapboxConstants.MAXIMUM_ZOOM) double minZoom) {
- if ((minZoom < MapboxConstants.MINIMUM_ZOOM) || (minZoom > MapboxConstants.MAXIMUM_ZOOM)) {
- Log.e(MapboxConstants.TAG, "Not setting minZoom, value is in unsupported range: " + minZoom);
- return;
- }
- minZoomLevel = minZoom;
- mapView.setMinZoom(minZoom);
- }
-
- /**
- * <p>
- * Gets the maximum zoom level the map can be displayed at.
- * </p>
- *
- * @return The minimum zoom level.
- */
- @UiThread
- public double getMinZoom() {
- if (minZoomLevel == -1) {
- return minZoomLevel = mapView.getMinZoom();
- }
- return minZoomLevel;
- }
-
- //
- // MaxZoom
- //
-
- /**
- * <p>
- * Sets the maximum zoom level the map can be displayed at.
- * </p>
- *
- * @param maxZoom The new maximum zoom level.
- */
- @UiThread
- public void setMaxZoom(
- @FloatRange(from = MapboxConstants.MINIMUM_ZOOM, to = MapboxConstants.MAXIMUM_ZOOM) double maxZoom) {
- if ((maxZoom < MapboxConstants.MINIMUM_ZOOM) || (maxZoom > MapboxConstants.MAXIMUM_ZOOM)) {
- Log.e(MapboxConstants.TAG, "Not setting maxZoom, value is in unsupported range: " + maxZoom);
- return;
- }
- maxZoomLevel = maxZoom;
- mapView.setMaxZoom(maxZoom);
- }
-
- /**
- * <p>
- * Gets the maximum zoom level the map can be displayed at.
- * </p>
- *
- * @return The maximum zoom level.
- */
- @UiThread
- public double getMaxZoom() {
- if (maxZoomLevel == -1) {
- return maxZoomLevel = mapView.getMaxZoom();
- }
- return maxZoomLevel;
- }
-
- //
- // UiSettings
- //
-
- /**
- * Gets the user interface settings for the map.
- *
- * @return the UiSettings associated with this map
- */
- public UiSettings getUiSettings() {
- return uiSettings;
- }
-
- //
- // TrackingSettings
- //
-
- /**
- * Gets the tracking interface settings for the map.
- *
- * @return the TrackingSettings asssociated with this map
- */
- public TrackingSettings getTrackingSettings() {
- return trackingSettings;
- }
-
- //
- // MyLocationViewSettings
- //
-
- /**
- * Gets the settings of the user location for the map.
- *
- * @return the MyLocationViewSettings associated with this map
- */
- public MyLocationViewSettings getMyLocationViewSettings() {
- if (myLocationViewSettings == null) {
- myLocationViewSettings = new MyLocationViewSettings(mapView, mapView.getUserLocationView());
- }
- return myLocationViewSettings;
- }
-
- //
- // Projection
- //
-
- /**
- * Get the Projection object that you can use to convert between screen coordinates and latitude/longitude
- * coordinates.
- *
- * @return the Projection associated with this map
- */
- public Projection getProjection() {
- return projection;
- }
-
- //
- // Camera API
- //
-
- /**
- * Gets the current position of the camera.
- * The CameraPosition returned is a snapshot of the current position, and will not automatically update when the
- * camera moves.
- *
- * @return The current position of the Camera.
- */
- public final CameraPosition getCameraPosition() {
- if (invalidCameraPosition) {
- invalidateCameraPosition();
- }
- return cameraPosition;
- }
-
- /**
- * Repositions the camera according to the cameraPosition.
- * The move is instantaneous, and a subsequent getCameraPosition() will reflect the new position.
- * See CameraUpdateFactory for a set of updates.
- *
- * @param cameraPosition the camera position to set
- */
- public void setCameraPosition(@NonNull CameraPosition cameraPosition) {
- moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
- }
-
- /**
- * Repositions the camera according to the instructions defined in the update.
- * The move is instantaneous, and a subsequent getCameraPosition() will reflect the new position.
- * See CameraUpdateFactory for a set of updates.
- *
- * @param update The change that should be applied to the camera.
- */
- @UiThread
- public final void moveCamera(CameraUpdate update) {
- moveCamera(update, null);
- }
-
- /**
- * Repositions the camera according to the instructions defined in the update.
- * The move is instantaneous, and a subsequent getCameraPosition() will reflect the new position.
- * See CameraUpdateFactory for a set of updates.
- *
- * @param update The change that should be applied to the camera
- * @param callback the callback to be invoked when an animation finishes or is canceled
- */
- @UiThread
- public final void moveCamera(CameraUpdate update, MapboxMap.CancelableCallback callback) {
- cameraPosition = update.getCameraPosition(this);
- mapView.resetTrackingModesIfRequired(cameraPosition);
- mapView.jumpTo(cameraPosition.bearing, cameraPosition.target, cameraPosition.tilt, cameraPosition.zoom);
- if (callback != null) {
- callback.onFinish();
- }
-
- if (onCameraChangeListener != null) {
- onCameraChangeListener.onCameraChange(this.cameraPosition);
- }
- }
-
- /**
- * Gradually move the camera by the default duration, zoom will not be affected unless specified
- * within {@link CameraUpdate}. If {@link #getCameraPosition()} is called during the animation,
- * it will return the current location of the camera in flight.
- *
- * @param update The change that should be applied to the camera.
- * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates.
- */
- @UiThread
- public final void easeCamera(CameraUpdate update) {
- easeCamera(update, MapboxConstants.ANIMATION_DURATION);
- }
-
- /**
- * Gradually move the camera by a specified duration in milliseconds, zoom will not be affected
- * unless specified within {@link CameraUpdate}. If {@link #getCameraPosition()} is called
- * during the animation, it will return the current location of the camera in flight.
- *
- * @param update The change that should be applied to the camera.
- * @param durationMs The duration of the animation in milliseconds. This must be strictly
- * positive, otherwise an IllegalArgumentException will be thrown.
- * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates.
- */
- @UiThread
- public final void easeCamera(CameraUpdate update, int durationMs) {
- easeCamera(update, durationMs, null);
- }
-
- /**
- * Gradually move the camera by a specified duration in milliseconds, zoom will not be affected
- * unless specified within {@link CameraUpdate}. A callback can be used to be notified when
- * easing the camera stops. If {@link #getCameraPosition()} is called during the animation, it
- * will return the current location of the camera in flight.
- * <p>
- * Note that this will cancel location tracking mode if enabled.
- * </p>
- *
- * @param update The change that should be applied to the camera.
- * @param durationMs The duration of the animation in milliseconds. This must be strictly
- * positive, otherwise an IllegalArgumentException will be thrown.
- * @param callback An optional callback to be notified from the main thread when the animation
- * stops. If the animation stops due to its natural completion, the callback
- * will be notified with onFinish(). If the animation stops due to interruption
- * by a later camera movement or a user gesture, onCancel() will be called.
- * Do not update or ease the camera from within onCancel().
- * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates.
- */
- @UiThread
- public final void easeCamera(CameraUpdate update, int durationMs, final MapboxMap.CancelableCallback callback) {
- easeCamera(update, durationMs, true, callback);
- }
-
- @UiThread
- public final void easeCamera(CameraUpdate update, int durationMs, boolean easingInterpolator) {
- easeCamera(update, durationMs, easingInterpolator, null);
- }
-
- @UiThread
- public final void easeCamera(
- CameraUpdate update, int durationMs, boolean easingInterpolator, final MapboxMap.CancelableCallback callback) {
- // dismiss tracking, moving camera is equal to a gesture
- easeCamera(update, durationMs, easingInterpolator, true, callback);
- }
-
- @UiThread
- public final void easeCamera(
- CameraUpdate update, int durationMs, boolean easingInterpolator, boolean resetTrackingMode, final MapboxMap.CancelableCallback callback) {
- // dismiss tracking, moving camera is equal to a gesture
- cameraPosition = update.getCameraPosition(this);
- if (resetTrackingMode) {
- mapView.resetTrackingModesIfRequired(cameraPosition);
- }
-
- mapView.easeTo(cameraPosition.bearing, cameraPosition.target, getDurationNano(durationMs), cameraPosition.tilt,
- cameraPosition.zoom, easingInterpolator, new CancelableCallback() {
- @Override
- public void onCancel() {
- if (callback != null) {
- callback.onCancel();
- }
- invalidateCameraPosition();
- }
-
- @Override
- public void onFinish() {
- if (callback != null) {
- callback.onFinish();
- }
- invalidateCameraPosition();
- }
- });
- }
-
- /**
- * Animate the camera to a new location defined within {@link CameraUpdate} using a transition
- * animation that evokes powered flight. The animation will last the default amount of time.
- * During the animation, a call to {@link #getCameraPosition()} returns an intermediate location
- * of the camera in flight.
- *
- * @param update The change that should be applied to the camera.
- * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates.
- */
- @UiThread
- public final void animateCamera(CameraUpdate update) {
- animateCamera(update, MapboxConstants.ANIMATION_DURATION, null);
- }
-
- /**
- * Animate the camera to a new location defined within {@link CameraUpdate} using a transition
- * animation that evokes powered flight. The animation will last the default amount of time. A
- * callback can be used to be notified when animating the camera stops. During the animation, a
- * call to {@link #getCameraPosition()} returns an intermediate location of the camera in flight.
- *
- * @param update The change that should be applied to the camera.
- * @param callback The callback to invoke from the main thread when the animation stops. If the
- * animation completes normally, onFinish() is called; otherwise, onCancel() is
- * called. Do not update or animate the camera from within onCancel().
- * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates.
- */
- @UiThread
- public final void animateCamera(CameraUpdate update, MapboxMap.CancelableCallback callback) {
- animateCamera(update, MapboxConstants.ANIMATION_DURATION, callback);
- }
-
- /**
- * Animate the camera to a new location defined within {@link CameraUpdate} using a transition
- * animation that evokes powered flight. The animation will last a specified amount of time
- * given in milliseconds. During the animation, a call to {@link #getCameraPosition()} returns
- * an intermediate location of the camera in flight.
- *
- * @param update The change that should be applied to the camera.
- * @param durationMs The duration of the animation in milliseconds. This must be strictly
- * positive, otherwise an IllegalArgumentException will be thrown.
- * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates.
- */
- @UiThread
- public final void animateCamera(CameraUpdate update, int durationMs) {
- animateCamera(update, durationMs, null);
- }
-
- /**
- * Animate the camera to a new location defined within {@link CameraUpdate} using a transition
- * animation that evokes powered flight. The animation will last a specified amount of time
- * given in milliseconds. A callback can be used to be notified when animating the camera stops.
- * During the animation, a call to {@link #getCameraPosition()} returns an intermediate location
- * of the camera in flight.
- *
- * @param update The change that should be applied to the camera.
- * @param durationMs The duration of the animation in milliseconds. This must be strictly
- * positive, otherwise an IllegalArgumentException will be thrown.
- * @param callback An optional callback to be notified from the main thread when the animation
- * stops. If the animation stops due to its natural completion, the callback
- * will be notified with onFinish(). If the animation stops due to interruption
- * by a later camera movement or a user gesture, onCancel() will be called.
- * Do not update or animate the camera from within onCancel(). If a callback
- * isn't required, leave it as null.
- * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates.
- */
- @UiThread
- public final void animateCamera(CameraUpdate update, int durationMs, final MapboxMap.CancelableCallback callback) {
- cameraPosition = update.getCameraPosition(this);
- mapView.resetTrackingModesIfRequired(cameraPosition);
- mapView.flyTo(cameraPosition.bearing, cameraPosition.target, getDurationNano(durationMs), cameraPosition.tilt,
- cameraPosition.zoom, new CancelableCallback() {
- @Override
- public void onCancel() {
- if (callback != null) {
- callback.onCancel();
- }
- invalidateCameraPosition();
- }
-
- @Override
- public void onFinish() {
- if (onCameraChangeListener != null) {
- onCameraChangeListener.onCameraChange(cameraPosition);
- }
-
- if (callback != null) {
- callback.onFinish();
- }
- invalidateCameraPosition();
- }
- });
- }
-
- /**
- * Converts milliseconds to nanoseconds
- *
- * @param durationMs The time in milliseconds
- * @return time in nanoseconds
- */
- private long getDurationNano(long durationMs) {
- return durationMs > 0 ? TimeUnit.NANOSECONDS.convert(durationMs, TimeUnit.MILLISECONDS) : 0;
- }
-
- /**
- * Invalidates the current camera position by reconstructing it from mbgl
- */
- private void invalidateCameraPosition() {
- if(invalidCameraPosition) {
- invalidCameraPosition = false;
-
- CameraPosition cameraPosition = mapView.invalidateCameraPosition();
- if (cameraPosition != null) {
- this.cameraPosition = cameraPosition;
- }
-
- if (onCameraChangeListener != null) {
- onCameraChangeListener.onCameraChange(this.cameraPosition);
- }
- }
- }
-
- //
- // Reset North
- //
-
- /**
- * Resets the map view to face north.
- */
- public void resetNorth() {
- mapView.resetNorth();
- }
+public final class MapboxMap {
+
+ private final NativeMapView nativeMapView;
+
+ private final UiSettings uiSettings;
+ private final TrackingSettings trackingSettings;
+ private final Projection projection;
+ private final Transform transform;
+ private final AnnotationManager annotationManager;
+ private final MyLocationViewSettings myLocationViewSettings;
+
+ private final OnRegisterTouchListener onRegisterTouchListener;
+
+ private MapboxMap.OnFpsChangedListener onFpsChangedListener;
+
+ MapboxMap(NativeMapView map, Transform transform, UiSettings ui, TrackingSettings tracking,
+ MyLocationViewSettings myLocationView, Projection projection, OnRegisterTouchListener listener,
+ AnnotationManager annotations) {
+ this.nativeMapView = map;
+ this.uiSettings = ui;
+ this.trackingSettings = tracking;
+ this.projection = projection;
+ this.myLocationViewSettings = myLocationView;
+ this.annotationManager = annotations.bind(this);
+ this.transform = transform;
+ this.onRegisterTouchListener = listener;
+ }
+
+ void initialise(@NonNull Context context, @NonNull MapboxMapOptions options) {
+ transform.initialise(this, options);
+ uiSettings.initialise(context, options);
+ myLocationViewSettings.initialise(options);
+ trackingSettings.initialise(options);
+
+ // Map configuration
+ setDebugActive(options.getDebugActive());
+ setApiBaseUrl(options);
+ setStyleUrl(options);
+ }
+
+ void onStart() {
+ nativeMapView.update();
+ trackingSettings.onStart();
+ if (TextUtils.isEmpty(nativeMapView.getStyleUrl())) {
+ // if user hasn't loaded a Style yet
+ nativeMapView.setStyleUrl(Style.MAPBOX_STREETS);
+ }
+ }
+
+ void onStop() {
+ trackingSettings.onStop();
+ }
+
+ void onSaveInstanceState(Bundle outState) {
+ outState.putParcelable(MapboxConstants.STATE_CAMERA_POSITION, transform.getCameraPosition());
+ outState.putBoolean(MapboxConstants.STATE_DEBUG_ACTIVE, nativeMapView.getDebug());
+ outState.putString(MapboxConstants.STATE_STYLE_URL, nativeMapView.getStyleUrl());
+ trackingSettings.onSaveInstanceState(outState);
+ uiSettings.onSaveInstanceState(outState);
+ }
+
+ void onRestoreInstanceState(Bundle savedInstanceState) {
+ final CameraPosition cameraPosition = savedInstanceState.getParcelable(MapboxConstants.STATE_CAMERA_POSITION);
+ if (cameraPosition != null) {
+ moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder(cameraPosition).build()));
+ }
+
+ uiSettings.onRestoreInstanceState(savedInstanceState);
+ trackingSettings.onRestoreInstanceState(savedInstanceState);
+ nativeMapView.setDebug(savedInstanceState.getBoolean(MapboxConstants.STATE_DEBUG_ACTIVE));
+
+ final String styleUrl = savedInstanceState.getString(MapboxConstants.STATE_STYLE_URL);
+ if (!TextUtils.isEmpty(styleUrl)) {
+ nativeMapView.setStyleUrl(savedInstanceState.getString(MapboxConstants.STATE_STYLE_URL));
+ }
+ }
+
+ /**
+ * Called before the OnMapReadyCallback is invoked.
+ */
+ void onPreMapReady() {
+ annotationManager.reloadMarkers();
+ annotationManager.adjustTopOffsetPixels(this);
+ }
+
+ /**
+ * Called when the OnMapReadyCallback has finished executing.
+ * <p>
+ * Invalidation of the camera position is required to update the added components in
+ * OnMapReadyCallback with the correct transformation.
+ * </p>
+ */
+ void onPostMapReady() {
+ invalidateCameraPosition();
+ }
+
+ /**
+ * Called when the user
+ */
+ void onUpdate() {
+ CameraPosition cameraPosition = transform.getCameraPosition();
+ uiSettings.update(cameraPosition);
+ // FIXME introduce update method with camera position
+ trackingSettings.update();
+ annotationManager.update();
+ }
+
+ // Style
+
+ @Nullable
+ @UiThread
+ public Layer getLayer(@NonNull String layerId) {
+ return nativeMapView.getLayer(layerId);
+ }
+
+ /**
+ * Tries to cast the Layer to T, returns null if it's another type.
+ *
+ * @param layerId the layer id used to look up a layer
+ * @param <T> the generic attribute of a Layer
+ * @return the casted Layer, null if another type
+ */
+ @Nullable
+ @UiThread
+ public <T extends Layer> T getLayerAs(@NonNull String layerId) {
+ try {
+ //noinspection unchecked
+ return (T) nativeMapView.getLayer(layerId);
+ } catch (ClassCastException exception) {
+ Timber.e(String.format("Layer: %s is a different type: %s", layerId, exception));
+ return null;
+ }
+ }
+
+ /**
+ * Adds the layer to the map. The layer must be newly created and not added to the map before
+ *
+ * @param layer the layer to add
+ */
+ @UiThread
+ public void addLayer(@NonNull Layer layer) {
+ addLayer(layer, null);
+ }
+
+ /**
+ * Adds the layer to the map. The layer must be newly created and not added to the map before
+ *
+ * @param layer the layer to add
+ * @param before the layer id to add this layer before
+ */
+ @UiThread
+ public void addLayer(@NonNull Layer layer, String before) {
+ nativeMapView.addLayer(layer, before);
+ }
+
+ /**
+ * Removes the layer. Any references to the layer become invalid and should not be used anymore
+ *
+ * @param layerId the layer to remove
+ * @throws NoSuchLayerException the exception thrown when layer with layerId doesn't exist
+ */
+ @UiThread
+ public void removeLayer(@NonNull String layerId) throws NoSuchLayerException {
+ nativeMapView.removeLayer(layerId);
+ }
+
+ /**
+ * Removes the layer. The reference is re-usable after this and can be re-added
+ *
+ * @param layer the layer to remove
+ * @throws NoSuchLayerException the exeption thrown when the layer doesn't exist
+ */
+ @UiThread
+ public void removeLayer(@NonNull Layer layer) throws NoSuchLayerException {
+ nativeMapView.removeLayer(layer);
+ }
+
+ @Nullable
+ @UiThread
+ public Source getSource(@NonNull String sourceId) {
+ return nativeMapView.getSource(sourceId);
+ }
+
+ /**
+ * Tries to cast the Source to T, returns null if it's another type.
+ *
+ * @param sourceId the id used to look up a layer
+ * @param <T> the generic type of a Source
+ * @return the casted Source, null if another type
+ */
+ @Nullable
+ @UiThread
+ public <T extends Source> T getSourceAs(@NonNull String sourceId) {
+ try {
+ //noinspection unchecked
+ return (T) nativeMapView.getSource(sourceId);
+ } catch (ClassCastException exception) {
+ Timber.e(String.format("Source: %s is a different type: %s", sourceId, exception));
+ return null;
+ }
+ }
+
+ /**
+ * Adds the source to the map. The source must be newly created and not added to the map before
+ *
+ * @param source the source to add
+ */
+ @UiThread
+ public void addSource(@NonNull Source source) {
+ nativeMapView.addSource(source);
+ }
+
+ /**
+ * Removes the source. Any references to the source become invalid and should not be used anymore
+ *
+ * @param sourceId the source to remove
+ * @throws NoSuchSourceException the exception thrown when the source with sourceId doesn't exist
+ */
+ @UiThread
+ public void removeSource(@NonNull String sourceId) throws NoSuchSourceException {
+ nativeMapView.removeSource(sourceId);
+ }
+
+ /**
+ * Removes the source, preserving the reverence for re-use
+ *
+ * @param source the source to remove
+ * @throws NoSuchSourceException the exception thrown when the source with sourceId doesn't exist
+ */
+ @UiThread
+ public void removeSource(@NonNull Source source) throws NoSuchSourceException {
+ nativeMapView.removeSource(source);
+ }
+
+ /**
+ * Adds an image to be used in the map's style
+ *
+ * @param name the name of the image
+ * @param image the pre-multiplied Bitmap
+ */
+ @UiThread
+ public void addImage(@NonNull String name, @NonNull Bitmap image) {
+ nativeMapView.addImage(name, image);
+ }
+
+ /**
+ * Removes an image from the map's style
+ *
+ * @param name the name of the image to remove
+ */
+ @UiThread
+ public void removeImage(String name) {
+ nativeMapView.removeImage(name);
+ }
+
+ //
+ // MinZoom
+ //
+
+ /**
+ * <p>
+ * Sets the minimum zoom level the map can be displayed at.
+ * </p>
+ *
+ * @param minZoom The new minimum zoom level.
+ */
+ @UiThread
+ public void setMinZoomPreference(
+ @FloatRange(from = MapboxConstants.MINIMUM_ZOOM, to = MapboxConstants.MAXIMUM_ZOOM) double minZoom) {
+ transform.setMinZoom(minZoom);
+ }
+
+ /**
+ * <p>
+ * Gets the maximum zoom level the map can be displayed at.
+ * </p>
+ *
+ * @return The minimum zoom level.
+ */
+ @UiThread
+ public double getMinZoomLevel() {
+ return transform.getMinZoom();
+ }
+
+ //
+ // MaxZoom
+ //
+
+ /**
+ * <p>
+ * Sets the maximum zoom level the map can be displayed at.
+ * </p>
+ *
+ * @param maxZoom The new maximum zoom level.
+ */
+ @UiThread
+ public void setMaxZoomPreference(@FloatRange(from = MapboxConstants.MINIMUM_ZOOM,
+ to = MapboxConstants.MAXIMUM_ZOOM) double maxZoom) {
+ transform.setMaxZoom(maxZoom);
+ }
+
+ /**
+ * <p>
+ * Gets the maximum zoom level the map can be displayed at.
+ * </p>
+ *
+ * @return The maximum zoom level.
+ */
+ @UiThread
+ public double getMaxZoomLevel() {
+ return transform.getMaxZoom();
+ }
+
+ //
+ // UiSettings
+ //
+
+ /**
+ * Gets the user interface settings for the map.
+ *
+ * @return the UiSettings associated with this map
+ */
+ public UiSettings getUiSettings() {
+ return uiSettings;
+ }
+
+ //
+ // TrackingSettings
+ //
+
+ /**
+ * Gets the tracking interface settings for the map.
+ *
+ * @return the TrackingSettings asssociated with this map
+ */
+ public TrackingSettings getTrackingSettings() {
+ return trackingSettings;
+ }
+
+ //
+ // MyLocationViewSettings
+ //
+
+ /**
+ * Gets the settings of the user location for the map.
+ *
+ * @return the MyLocationViewSettings associated with this map
+ */
+ public MyLocationViewSettings getMyLocationViewSettings() {
+ return myLocationViewSettings;
+ }
+
+ //
+ // Projection
+ //
+
+ /**
+ * Get the Projection object that you can use to convert between screen coordinates and latitude/longitude
+ * coordinates.
+ *
+ * @return the Projection associated with this map
+ */
+ public Projection getProjection() {
+ return projection;
+ }
+
+ //
+ // Camera API
+ //
+
+ /**
+ * Cancels ongoing animations.
+ * <p>
+ * This invokes the {@link CancelableCallback} for ongoing camera updates.
+ * </p>
+ */
+ public void cancelTransitions() {
+ transform.cancelTransitions();
+ }
+
+ /**
+ * Gets the current position of the camera.
+ * The CameraPosition returned is a snapshot of the current position, and will not automatically update when the
+ * camera moves.
+ *
+ * @return The current position of the Camera.
+ */
+ public final CameraPosition getCameraPosition() {
+ return transform.getCameraPosition();
+ }
+
+ /**
+ * Repositions the camera according to the cameraPosition.
+ * The move is instantaneous, and a subsequent getCameraPosition() will reflect the new position.
+ * See CameraUpdateFactory for a set of updates.
+ *
+ * @param cameraPosition the camera position to set
+ */
+ public void setCameraPosition(@NonNull CameraPosition cameraPosition) {
+ moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), null);
+ }
+
+ /**
+ * Repositions the camera according to the instructions defined in the update.
+ * The move is instantaneous, and a subsequent getCameraPosition() will reflect the new position.
+ * See CameraUpdateFactory for a set of updates.
+ *
+ * @param update The change that should be applied to the camera.
+ */
+ @UiThread
+ public final void moveCamera(CameraUpdate update) {
+ moveCamera(update, null);
+ // MapChange.REGION_DID_CHANGE_ANIMATED is not called for `jumpTo`
+ // invalidate camera position to provide OnCameraChange event.
+ invalidateCameraPosition();
+ }
+
+ /**
+ * Repositions the camera according to the instructions defined in the update.
+ * The move is instantaneous, and a subsequent getCameraPosition() will reflect the new position.
+ * See CameraUpdateFactory for a set of updates.
+ *
+ * @param update The change that should be applied to the camera
+ * @param callback the callback to be invoked when an animation finishes or is canceled
+ */
+ @UiThread
+ public final void moveCamera(final CameraUpdate update, final MapboxMap.CancelableCallback callback) {
+ new Handler().post(new Runnable() {
+ @Override
+ public void run() {
+ transform.moveCamera(MapboxMap.this, update, callback);
+ }
+ });
+ }
+
+ /**
+ * Gradually move the camera by the default duration, zoom will not be affected unless specified
+ * within {@link CameraUpdate}. If {@link #getCameraPosition()} is called during the animation,
+ * it will return the current location of the camera in flight.
+ *
+ * @param update The change that should be applied to the camera.
+ * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates.
+ */
+ @UiThread
+ public final void easeCamera(CameraUpdate update) {
+ easeCamera(update, MapboxConstants.ANIMATION_DURATION);
+ }
+
+ /**
+ * Gradually move the camera by a specified duration in milliseconds, zoom will not be affected
+ * unless specified within {@link CameraUpdate}. If {@link #getCameraPosition()} is called
+ * during the animation, it will return the current location of the camera in flight.
+ *
+ * @param update The change that should be applied to the camera.
+ * @param durationMs The duration of the animation in milliseconds. This must be strictly
+ * positive, otherwise an IllegalArgumentException will be thrown.
+ * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates.
+ */
+ @UiThread
+ public final void easeCamera(CameraUpdate update, int durationMs) {
+ easeCamera(update, durationMs, null);
+ }
+
+ /**
+ * Gradually move the camera by a specified duration in milliseconds, zoom will not be affected
+ * unless specified within {@link CameraUpdate}. A callback can be used to be notified when
+ * easing the camera stops. If {@link #getCameraPosition()} is called during the animation, it
+ * will return the current location of the camera in flight.
+ * <p>
+ * Note that this will cancel location tracking mode if enabled.
+ * </p>
+ *
+ * @param update The change that should be applied to the camera.
+ * @param durationMs The duration of the animation in milliseconds. This must be strictly
+ * positive, otherwise an IllegalArgumentException will be thrown.
+ * @param callback An optional callback to be notified from the main thread when the animation
+ * stops. If the animation stops due to its natural completion, the callback
+ * will be notified with onFinish(). If the animation stops due to interruption
+ * by a later camera movement or a user gesture, onCancel() will be called.
+ * Do not update or ease the camera from within onCancel().
+ * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates.
+ */
+ @UiThread
+ public final void easeCamera(CameraUpdate update, int durationMs, final MapboxMap.CancelableCallback callback) {
+ easeCamera(update, durationMs, true, callback);
+ }
+
+ /**
+ * Gradually move the camera by a specified duration in milliseconds, zoom will not be affected
+ * unless specified within {@link CameraUpdate}. A callback can be used to be notified when
+ * easing the camera stops. If {@link #getCameraPosition()} is called during the animation, it
+ * will return the current location of the camera in flight.
+ * <p>
+ * Note that this will cancel location tracking mode if enabled.
+ * </p>
+ *
+ * @param update The change that should be applied to the camera.
+ * @param durationMs The duration of the animation in milliseconds. This must be strictly
+ * positive, otherwise an IllegalArgumentException will be thrown.
+ * @param easingInterpolator True for easing interpolator, false for linear.
+ */
+ @UiThread
+ public final void easeCamera(CameraUpdate update, int durationMs, boolean easingInterpolator) {
+ easeCamera(update, durationMs, easingInterpolator, null);
+ }
+
+ /**
+ * Gradually move the camera by a specified duration in milliseconds, zoom will not be affected
+ * unless specified within {@link CameraUpdate}. A callback can be used to be notified when
+ * easing the camera stops. If {@link #getCameraPosition()} is called during the animation, it
+ * will return the current location of the camera in flight.
+ * <p>
+ * Note that this will cancel location tracking mode if enabled.
+ * </p>
+ *
+ * @param update The change that should be applied to the camera.
+ * @param durationMs The duration of the animation in milliseconds. This must be strictly
+ * positive, otherwise an IllegalArgumentException will be thrown.
+ * @param easingInterpolator True for easing interpolator, false for linear.
+ * @param callback An optional callback to be notified from the main thread when the animation
+ * stops. If the animation stops due to its natural completion, the callback
+ * will be notified with onFinish(). If the animation stops due to interruption
+ * by a later camera movement or a user gesture, onCancel() will be called.
+ * Do not update or ease the camera from within onCancel().
+ */
+ @UiThread
+ public final void easeCamera(
+ CameraUpdate update, int durationMs, boolean easingInterpolator, final MapboxMap.CancelableCallback callback) {
+ // dismiss tracking, moving camera is equal to a gesture
+ easeCamera(update, durationMs, easingInterpolator, true, callback);
+ }
+
+ /**
+ * Gradually move the camera by a specified duration in milliseconds, zoom will not be affected
+ * unless specified within {@link CameraUpdate}. A callback can be used to be notified when
+ * easing the camera stops. If {@link #getCameraPosition()} is called during the animation, it
+ * will return the current location of the camera in flight.
+ * <p>
+ * Note that this will cancel location tracking mode if enabled.
+ * </p>
+ *
+ * @param update The change that should be applied to the camera.
+ * @param durationMs The duration of the animation in milliseconds. This must be strictly
+ * positive, otherwise an IllegalArgumentException will be thrown.
+ * @param resetTrackingMode True to reset tracking modes if required, false to ignore
+ * @param easingInterpolator True for easing interpolator, false for linear.
+ * @param callback An optional callback to be notified from the main thread when the animation
+ * stops. If the animation stops due to its natural completion, the callback
+ * will be notified with onFinish(). If the animation stops due to interruption
+ * by a later camera movement or a user gesture, onCancel() will be called.
+ * Do not update or ease the camera from within onCancel().
+ */
+ @UiThread
+ public final void easeCamera(final CameraUpdate update, final int durationMs, final boolean easingInterpolator,
+ final boolean resetTrackingMode, final MapboxMap.CancelableCallback callback) {
+ new Handler().post(new Runnable() {
+ @Override
+ public void run() {
+ transform.easeCamera(MapboxMap.this, update, durationMs, easingInterpolator, resetTrackingMode, callback);
+ }
+ });
+ }
+
+ /**
+ * Animate the camera to a new location defined within {@link CameraUpdate} using a transition
+ * animation that evokes powered flight. The animation will last the default amount of time.
+ * During the animation, a call to {@link #getCameraPosition()} returns an intermediate location
+ * of the camera in flight.
+ *
+ * @param update The change that should be applied to the camera.
+ * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates.
+ */
+ @UiThread
+ public final void animateCamera(CameraUpdate update) {
+ animateCamera(update, MapboxConstants.ANIMATION_DURATION, null);
+ }
+
+ /**
+ * Animate the camera to a new location defined within {@link CameraUpdate} using a transition
+ * animation that evokes powered flight. The animation will last the default amount of time. A
+ * callback can be used to be notified when animating the camera stops. During the animation, a
+ * call to {@link #getCameraPosition()} returns an intermediate location of the camera in flight.
+ *
+ * @param update The change that should be applied to the camera.
+ * @param callback The callback to invoke from the main thread when the animation stops. If the
+ * animation completes normally, onFinish() is called; otherwise, onCancel() is
+ * called. Do not update or animate the camera from within onCancel().
+ * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates.
+ */
+ @UiThread
+ public final void animateCamera(CameraUpdate update, MapboxMap.CancelableCallback callback) {
+ animateCamera(update, MapboxConstants.ANIMATION_DURATION, callback);
+ }
+
+ /**
+ * Animate the camera to a new location defined within {@link CameraUpdate} using a transition
+ * animation that evokes powered flight. The animation will last a specified amount of time
+ * given in milliseconds. During the animation, a call to {@link #getCameraPosition()} returns
+ * an intermediate location of the camera in flight.
+ *
+ * @param update The change that should be applied to the camera.
+ * @param durationMs The duration of the animation in milliseconds. This must be strictly
+ * positive, otherwise an IllegalArgumentException will be thrown.
+ * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates.
+ */
+ @UiThread
+ public final void animateCamera(CameraUpdate update, int durationMs) {
+ animateCamera(update, durationMs, null);
+ }
+
+ /**
+ * Animate the camera to a new location defined within {@link CameraUpdate} using a transition
+ * animation that evokes powered flight. The animation will last a specified amount of time
+ * given in milliseconds. A callback can be used to be notified when animating the camera stops.
+ * During the animation, a call to {@link #getCameraPosition()} returns an intermediate location
+ * of the camera in flight.
+ *
+ * @param update The change that should be applied to the camera.
+ * @param durationMs The duration of the animation in milliseconds. This must be strictly
+ * positive, otherwise an IllegalArgumentException will be thrown.
+ * @param callback An optional callback to be notified from the main thread when the animation
+ * stops. If the animation stops due to its natural completion, the callback
+ * will be notified with onFinish(). If the animation stops due to interruption
+ * by a later camera movement or a user gesture, onCancel() will be called.
+ * Do not update or animate the camera from within onCancel(). If a callback
+ * isn't required, leave it as null.
+ * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates.
+ */
+ @UiThread
+ public final void animateCamera(final CameraUpdate update, final int durationMs,
+ final MapboxMap.CancelableCallback callback) {
+ new Handler().post(new Runnable() {
+ @Override
+ public void run() {
+ transform.animateCamera(MapboxMap.this, update, durationMs, callback);
+ }
+ });
+ }
+
+ /**
+ * Invalidates the current camera position by reconstructing it from mbgl
+ */
+ void invalidateCameraPosition() {
+ CameraPosition cameraPosition = transform.invalidateCameraPosition();
+ if (cameraPosition != null) {
+ transform.updateCameraPosition(cameraPosition);
+ }
+ }
+
+ //
+ // Reset North
+ //
+
+ /**
+ * Resets the map view to face north.
+ */
+ public void resetNorth() {
+ transform.resetNorth();
+ }
+
+ //
+ // Debug
+ //
+
+ /**
+ * Returns whether the map debug information is currently shown.
+ *
+ * @return If true, map debug information is currently shown.
+ */
+ @UiThread
+ public boolean isDebugActive() {
+ return nativeMapView.getDebug();
+ }
+
+ /**
+ * <p>
+ * Changes whether the map debug information is shown.
+ * </p>
+ * The default value is false.
+ *
+ * @param debugActive If true, map debug information is shown.
+ */
+ @UiThread
+ public void setDebugActive(boolean debugActive) {
+ nativeMapView.setDebug(debugActive);
+ }
+
+ /**
+ * <p>
+ * Cycles through the map debug options.
+ * </p>
+ * The value of isDebugActive reflects whether there are
+ * any map debug options enabled or disabled.
+ *
+ * @see #isDebugActive()
+ */
+ @UiThread
+ public void cycleDebugOptions() {
+ nativeMapView.cycleDebugOptions();
+ }
+
+ //
+ // API endpoint config
+ //
+
+ private void setApiBaseUrl(@NonNull MapboxMapOptions options) {
+ String apiBaseUrl = options.getApiBaseUrl();
+ if (!TextUtils.isEmpty(apiBaseUrl)) {
+ nativeMapView.setApiBaseUrl(apiBaseUrl);
+ }
+ }
+
+ //
+ // Styling
+ //
+
+ /**
+ * <p>
+ * Loads a new map style from the specified URL.
+ * </p>
+ * {@code url} can take the following forms:
+ * <ul>
+ * <li>{@code Style.*}: load one of the bundled styles in {@link Style}.</li>
+ * <li>{@code mapbox://styles/<user>/<style>}:
+ * retrieves the style from a <a href="https://www.mapbox.com/account/">Mapbox account.</a>
+ * {@code user} is your username. {@code style} is the ID of your custom
+ * style created in <a href="https://www.mapbox.com/studio">Mapbox Studio</a>.</li>
+ * <li>{@code http://...} or {@code https://...}:
+ * retrieves the style over the Internet from any web server.</li>
+ * <li>{@code asset://...}:
+ * reads the style from the APK {@code assets/} directory.
+ * This is used to load a style bundled with your app.</li>
+ * <li>{@code null}: loads the default {@link Style#MAPBOX_STREETS} style.</li>
+ * </ul>
+ * <p>
+ * This method is asynchronous and will return immediately before the style finishes loading.
+ * If you wish to wait for the map to finish loading listen for the {@link MapView#DID_FINISH_LOADING_MAP} event.
+ * </p>
+ * If the style fails to load or an invalid style URL is set, the map view will become blank.
+ * An error message will be logged in the Android logcat and {@link MapView#DID_FAIL_LOADING_MAP} event will be
+ * sent.
+ *
+ * @param url The URL of the map style
+ * @see Style
+ */
+ @UiThread
+ public void setStyleUrl(@NonNull String url) {
+ nativeMapView.setStyleUrl(url);
+ }
+
+ /**
+ * <p>
+ * Loads a new map style from the specified bundled style.
+ * </p>
+ * <p>
+ * This method is asynchronous and will return immediately before the style finishes loading.
+ * If you wish to wait for the map to finish loading listen for the {@link MapView#DID_FINISH_LOADING_MAP} event.
+ * </p>
+ * If the style fails to load or an invalid style URL is set, the map view will become blank.
+ * An error message will be logged in the Android logcat and {@link MapView#DID_FAIL_LOADING_MAP} event will be
+ * sent.
+ *
+ * @param style The bundled style. Accepts one of the values from {@link Style}.
+ * @see Style
+ * @deprecated use {@link #setStyleUrl(String)} instead with versioned url methods from {@link Style}
+ */
+ @UiThread
+ @Deprecated
+ public void setStyle(@Style.StyleUrl String style) {
+ setStyleUrl(style);
+ }
+
+ /**
+ * Loads a new map style from MapboxMapOptions if available.
+ *
+ * @param options the object containing the style url
+ */
+ private void setStyleUrl(@NonNull MapboxMapOptions options) {
+ String style = options.getStyle();
+ if (!TextUtils.isEmpty(style)) {
+ // stopgap for https://github.com/mapbox/mapbox-gl-native/issues/6242
+ if (TextUtils.isEmpty(nativeMapView.getAccessToken())) {
+ Mapbox.validateAccessToken();
+ nativeMapView.setAccessToken(Mapbox.getAccessToken());
+ }
+ setStyleUrl(style);
+ }
+ }
+
+ /**
+ * <p>
+ * Returns the map style currently displayed in the map view.
+ * </p>
+ * If the default style is currently displayed, a URL will be returned instead of null.
+ *
+ * @return The URL of the map style.
+ */
+ @UiThread
+ @NonNull
+ public String getStyleUrl() {
+ return nativeMapView.getStyleUrl();
+ }
+
+ //
+ // Annotations
+ //
+
+ /**
+ * <p>
+ * Adds a marker to this map.
+ * </p>
+ * The marker's icon is rendered on the map at the location {@code Marker.position}.
+ * If {@code Marker.title} is defined, the map shows an info box with the marker's title and snippet.
+ *
+ * @param markerOptions A marker options object that defines how to render the marker.
+ * @return The {@code Marker} that was added to the map.
+ */
+ @UiThread
+ @NonNull
+ public Marker addMarker(@NonNull MarkerOptions markerOptions) {
+ return annotationManager.addMarker(markerOptions, this);
+ }
+
+ /**
+ * <p>
+ * Adds a marker to this map.
+ * </p>
+ * The marker's icon is rendered on the map at the location {@code Marker.position}.
+ * If {@code Marker.title} is defined, the map shows an info box with the marker's title and snippet.
+ *
+ * @param markerOptions A marker options object that defines how to render the marker.
+ * @return The {@code Marker} that was added to the map.
+ */
+ @UiThread
+ @NonNull
+ public Marker addMarker(@NonNull BaseMarkerOptions markerOptions) {
+ return annotationManager.addMarker(markerOptions, this);
+ }
+
+ /**
+ * <p>
+ * Adds a marker to this map.
+ * </p>
+ * The marker's icon is rendered on the map at the location {@code Marker.position}.
+ * If {@code Marker.title} is defined, the map shows an info box with the marker's title and snippet.
+ *
+ * @param markerOptions A marker options object that defines how to render the marker.
+ * @return The {@code Marker} that was added to the map.
+ */
+ @UiThread
+ @NonNull
+ public MarkerView addMarker(@NonNull BaseMarkerViewOptions markerOptions) {
+ return annotationManager.addMarker(markerOptions, this, null);
+ }
+
+
+ /**
+ * <p>
+ * Adds a marker to this map.
+ * </p>
+ * The marker's icon is rendered on the map at the location {@code Marker.position}.
+ * If {@code Marker.title} is defined, the map shows an info box with the marker's title and snippet.
+ *
+ * @param markerOptions A marker options object that defines how to render the marker.
+ * @param onMarkerViewAddedListener Callback invoked when the View has been added to the map.
+ * @return The {@code Marker} that was added to the map.
+ */
+ @UiThread
+ @NonNull
+ public MarkerView addMarker(@NonNull BaseMarkerViewOptions markerOptions,
+ final MarkerViewManager.OnMarkerViewAddedListener onMarkerViewAddedListener) {
+ return annotationManager.addMarker(markerOptions, this, onMarkerViewAddedListener);
+ }
+
+ /**
+ * FIXME javadoc
+ */
+ @UiThread
+ @NonNull
+ public List<MarkerView> addMarkerViews(@NonNull List<? extends
+ BaseMarkerViewOptions> markerViewOptions) {
+ return annotationManager.addMarkerViews(markerViewOptions, this);
+ }
+
+ /**
+ * FIXME javadoc
+ */
+ @UiThread
+ @NonNull
+ public List<MarkerView> getMarkerViewsInRect(@NonNull RectF rect) {
+ return annotationManager.getMarkerViewsInRect(rect);
+ }
+
+ /**
+ * <p>
+ * Adds multiple markers to this map.
+ * </p>
+ * The marker's icon is rendered on the map at the location {@code Marker.position}.
+ * If {@code Marker.title} is defined, the map shows an info box with the marker's title and snippet.
+ *
+ * @param markerOptionsList A list of marker options objects that defines how to render the markers.
+ * @return A list of the {@code Marker}s that were added to the map.
+ */
+ @UiThread
+ @NonNull
+ public List<Marker> addMarkers(@NonNull List<? extends
+ BaseMarkerOptions> markerOptionsList) {
+ return annotationManager.addMarkers(markerOptionsList, this);
+ }
+
+ /**
+ * <p>
+ * Updates a marker on this map. Does nothing if the marker isn't already added.
+ * </p>
+ *
+ * @param updatedMarker An updated marker object.
+ */
+ @UiThread
+ public void updateMarker(@NonNull Marker updatedMarker) {
+ annotationManager.updateMarker(updatedMarker, this);
+ }
+
+ /**
+ * Adds a polyline to this map.
+ *
+ * @param polylineOptions A polyline options object that defines how to render the polyline.
+ * @return The {@code Polyine} that was added to the map.
+ */
+ @UiThread
+ @NonNull
+ public Polyline addPolyline(@NonNull PolylineOptions polylineOptions) {
+ return annotationManager.addPolyline(polylineOptions, this);
+ }
+
+ /**
+ * Adds multiple polylines to this map.
+ *
+ * @param polylineOptionsList A list of polyline options objects that defines how to render the polylines.
+ * @return A list of the {@code Polyline}s that were added to the map.
+ */
+ @UiThread
+ @NonNull
+ public List<Polyline> addPolylines(@NonNull List<PolylineOptions> polylineOptionsList) {
+ return annotationManager.addPolylines(polylineOptionsList, this);
+ }
+
+ /**
+ * Update a polyline on this map.
+ *
+ * @param polyline An updated polyline object.
+ */
+ @UiThread
+ public void updatePolyline(Polyline polyline) {
+ annotationManager.updatePolyline(polyline);
+ }
+
+ /**
+ * Adds a polygon to this map.
+ *
+ * @param polygonOptions A polygon options object that defines how to render the polygon.
+ * @return The {@code Polygon} that was added to the map.
+ */
+ @UiThread
+ @NonNull
+ public Polygon addPolygon(@NonNull PolygonOptions polygonOptions) {
+ return annotationManager.addPolygon(polygonOptions, this);
+ }
+
+ /**
+ * Adds multiple polygons to this map.
+ *
+ * @param polygonOptionsList A list of polygon options objects that defines how to render the polygons.
+ * @return A list of the {@code Polygon}s that were added to the map.
+ */
+ @UiThread
+ @NonNull
+ public List<Polygon> addPolygons(@NonNull List<PolygonOptions> polygonOptionsList) {
+ return annotationManager.addPolygons(polygonOptionsList, this);
+ }
+
+
+ /**
+ * Update a polygon on this map.
+ *
+ * @param polygon An updated polygon object.
+ */
+ @UiThread
+ public void updatePolygon(Polygon polygon) {
+ annotationManager.updatePolygon(polygon);
+ }
+
+ /**
+ * <p>
+ * Convenience method for removing a Marker from the map.
+ * </p>
+ * Calls removeAnnotation() internally
+ *
+ * @param marker Marker to remove
+ */
+ @UiThread
+ public void removeMarker(@NonNull Marker marker) {
+ annotationManager.removeAnnotation(marker);
+ }
+
+ /**
+ * <p>
+ * Convenience method for removing a Polyline from the map.
+ * </p>
+ * Calls removeAnnotation() internally
+ *
+ * @param polyline Polyline to remove
+ */
+ @UiThread
+ public void removePolyline(@NonNull Polyline polyline) {
+ annotationManager.removeAnnotation(polyline);
+ }
+
+ /**
+ * <p>
+ * Convenience method for removing a Polygon from the map.
+ * </p>
+ * Calls removeAnnotation() internally
+ *
+ * @param polygon Polygon to remove
+ */
+ @UiThread
+ public void removePolygon(@NonNull Polygon polygon) {
+ annotationManager.removeAnnotation(polygon);
+ }
+
+ /**
+ * Removes an annotation from the map.
+ *
+ * @param annotation The annotation object to remove.
+ */
+ @UiThread
+ public void removeAnnotation(@NonNull Annotation annotation) {
+ annotationManager.removeAnnotation(annotation);
+ }
+
+ /**
+ * Removes an annotation from the map
+ *
+ * @param id The identifier associated to the annotation to be removed
+ */
+ @UiThread
+ public void removeAnnotation(long id) {
+ annotationManager.removeAnnotation(id);
+ }
+
+ /**
+ * Removes multiple annotations from the map.
+ *
+ * @param annotationList A list of annotation objects to remove.
+ */
+ @UiThread
+ public void removeAnnotations(@NonNull List<? extends Annotation> annotationList) {
+ annotationManager.removeAnnotations(annotationList);
+ }
+
+ /**
+ * Removes all annotations from the map.
+ */
+ @UiThread
+ public void removeAnnotations() {
+ annotationManager.removeAnnotations();
+ }
+
+ /**
+ * Removes all markers, polylines, polygons, overlays, etc from the map.
+ */
+ @UiThread
+ public void clear() {
+ annotationManager.removeAnnotations();
+ }
+
+ /**
+ * Return a annotation based on its id.
+ *
+ * @param id the id used to look up an annotation
+ * @return An annotation with a matched id, null is returned if no match was found
+ */
+ @Nullable
+ public Annotation getAnnotation(long id) {
+ return annotationManager.getAnnotation(id);
+ }
+
+ /**
+ * Returns a list of all the annotations on the map.
+ *
+ * @return A list of all the annotation objects. The returned object is a copy so modifying this
+ * list will not update the map
+ */
+ @NonNull
+ public List<Annotation> getAnnotations() {
+ return annotationManager.getAnnotations();
+ }
+
+ /**
+ * Returns a list of all the markers on the map.
+ *
+ * @return A list of all the markers objects. The returned object is a copy so modifying this
+ * list will not update the map.
+ */
+ @NonNull
+ public List<Marker> getMarkers() {
+ return annotationManager.getMarkers();
+ }
+
+ /**
+ * Returns a list of all the polygons on the map.
+ *
+ * @return A list of all the polygon objects. The returned object is a copy so modifying this
+ * list will not update the map.
+ */
+ @NonNull
+ public List<Polygon> getPolygons() {
+ return annotationManager.getPolygons();
+ }
+
+ /**
+ * Returns a list of all the polylines on the map.
+ *
+ * @return A list of all the polylines objects. The returned object is a copy so modifying this
+ * list will not update the map.
+ */
+ @NonNull
+ public List<Polyline> getPolylines() {
+ return annotationManager.getPolylines();
+ }
+
+ /**
+ * Sets a callback that's invoked when the user clicks on a marker.
+ *
+ * @param listener The callback that's invoked when the user clicks on a marker.
+ * To unset the callback, use null.
+ */
+ @UiThread
+ public void setOnMarkerClickListener(@Nullable OnMarkerClickListener listener) {
+ annotationManager.setOnMarkerClickListener(listener);
+ }
+
+ /**
+ * <p>
+ * Selects a marker. The selected marker will have it's info window opened.
+ * Any other open info windows will be closed unless isAllowConcurrentMultipleOpenInfoWindows()
+ * is true.
+ * </p>
+ * Selecting an already selected marker will have no effect.
+ *
+ * @param marker The marker to select.
+ */
+ @UiThread
+ public void selectMarker(@NonNull Marker marker) {
+ if (marker == null) {
+ Timber.w("marker was null, so just returning");
+ return;
+ }
+ annotationManager.selectMarker(marker);
+ }
+
+ /**
+ * Deselects any currently selected marker. All markers will have it's info window closed.
+ */
+ @UiThread
+ public void deselectMarkers() {
+ annotationManager.deselectMarkers();
+ }
+
+ /**
+ * Deselects a currently selected marker. The selected marker will have it's info window closed.
+ *
+ * @param marker the marker to deselect
+ */
+ @UiThread
+ public void deselectMarker(@NonNull Marker marker) {
+ annotationManager.deselectMarker(marker);
+ }
+
+ /**
+ * Gets the currently selected marker.
+ *
+ * @return The currently selected marker.
+ */
+ @UiThread
+ public List<Marker> getSelectedMarkers() {
+ return annotationManager.getSelectedMarkers();
+ }
+
+ /**
+ * Get the MarkerViewManager associated to the MapView.
+ *
+ * @return the associated MarkerViewManager
+ */
+ public MarkerViewManager getMarkerViewManager() {
+ return annotationManager.getMarkerViewManager();
+ }
+
+ //
+ // InfoWindow
+ //
+
+ /**
+ * <p>
+ * Sets a custom renderer for the contents of info window.
+ * </p>
+ * When set your callback is invoked when an info window is about to be shown. By returning
+ * a custom {@link View}, the default info window will be replaced.
+ *
+ * @param infoWindowAdapter The callback to be invoked when an info window will be shown.
+ * To unset the callback, use null.
+ */
+ @UiThread
+ public void setInfoWindowAdapter(@Nullable InfoWindowAdapter infoWindowAdapter) {
+ annotationManager.getInfoWindowManager().setInfoWindowAdapter(infoWindowAdapter);
+ }
+
+ /**
+ * Gets the callback to be invoked when an info window will be shown.
+ *
+ * @return The callback to be invoked when an info window will be shown.
+ */
+ @UiThread
+ @Nullable
+ public InfoWindowAdapter getInfoWindowAdapter() {
+ return annotationManager.getInfoWindowManager().getInfoWindowAdapter();
+ }
+
+ /**
+ * Changes whether the map allows concurrent multiple infowindows to be shown.
+ *
+ * @param allow If true, map allows concurrent multiple infowindows to be shown.
+ */
+ @UiThread
+ public void setAllowConcurrentMultipleOpenInfoWindows(boolean allow) {
+ annotationManager.getInfoWindowManager().setAllowConcurrentMultipleOpenInfoWindows(allow);
+ }
+
+ /**
+ * Returns whether the map allows concurrent multiple infowindows to be shown.
+ *
+ * @return If true, map allows concurrent multiple infowindows to be shown.
+ */
+ @UiThread
+ public boolean isAllowConcurrentMultipleOpenInfoWindows() {
+ return annotationManager.getInfoWindowManager().isAllowConcurrentMultipleOpenInfoWindows();
+ }
+
+ //
+ // Padding
+ //
+
+ /**
+ * <p>
+ * Sets the distance from the edges of the map view’s frame to the edges of the map
+ * view’s logical viewport.
+ * </p>
+ * <p>
+ * When the value of this property is equal to {0,0,0,0}, viewport
+ * properties such as `centerCoordinate` assume a viewport that matches the map
+ * view’s frame. Otherwise, those properties are inset, excluding part of the
+ * frame from the viewport. For instance, if the only the top edge is inset, the
+ * map center is effectively shifted downward.
+ * </p>
+ *
+ * @param left The left margin in pixels.
+ * @param top The top margin in pixels.
+ * @param right The right margin in pixels.
+ * @param bottom The bottom margin in pixels.
+ */
+ public void setPadding(int left, int top, int right, int bottom) {
+ projection.setContentPadding(new int[] {left, top, right, bottom}, myLocationViewSettings.getPadding());
+ uiSettings.invalidate();
+ }
+
+ /**
+ * Returns the current configured content padding on map view.
+ *
+ * @return An array with length 4 in the LTRB order.
+ */
+ public int[] getPadding() {
+ return projection.getContentPadding();
+ }
+
+ //
+ // Map events
+ //
+
+ /**
+ * Sets a callback that's invoked on every change in camera position.
+ *
+ * @param listener The callback that's invoked on every camera change position.
+ * To unset the callback, use null.
+ */
+ @UiThread
+ public void setOnCameraChangeListener(@Nullable OnCameraChangeListener listener) {
+ transform.setOnCameraChangeListener(listener);
+ }
+
+ /**
+ * Sets a callback that's invoked on every frame rendered to the map view.
+ *
+ * @param listener The callback that's invoked on every frame rendered to the map view.
+ * To unset the callback, use null.
+ */
+ @UiThread
+ public void setOnFpsChangedListener(@Nullable OnFpsChangedListener listener) {
+ onFpsChangedListener = listener;
+ }
+
+ // used by MapView
+ OnFpsChangedListener getOnFpsChangedListener() {
+ return onFpsChangedListener;
+ }
+
+ /**
+ * Sets a callback that's invoked when the map is scrolled.
+ *
+ * @param listener The callback that's invoked when the map is scrolled.
+ * To unset the callback, use null.
+ */
+ @UiThread
+ public void setOnScrollListener(@Nullable OnScrollListener listener) {
+ onRegisterTouchListener.onRegisterScrollListener(listener);
+ }
+
+ /**
+ * Sets a callback that's invoked when the map is flinged.
+ *
+ * @param listener The callback that's invoked when the map is flinged.
+ * To unset the callback, use null.
+ */
+ @UiThread
+ public void setOnFlingListener(@Nullable OnFlingListener listener) {
+ onRegisterTouchListener.onRegisterFlingListener(listener);
+ }
+
+ /**
+ * Sets a callback that's invoked when the user clicks on the map view.
+ *
+ * @param listener The callback that's invoked when the user clicks on the map view.
+ * To unset the callback, use null.
+ */
+ @UiThread
+ public void setOnMapClickListener(@Nullable OnMapClickListener listener) {
+ onRegisterTouchListener.onRegisterMapClickListener(listener);
+ }
+
+ /**
+ * Sets a callback that's invoked when the user long clicks on the map view.
+ *
+ * @param listener The callback that's invoked when the user long clicks on the map view.
+ * To unset the callback, use null.
+ */
+ @UiThread
+ public void setOnMapLongClickListener(@Nullable OnMapLongClickListener listener) {
+ onRegisterTouchListener.onRegisterMapLongClickListener(listener);
+ }
+
+ /**
+ * Sets a callback that's invoked when the user clicks on an info window.
+ *
+ * @param listener The callback that's invoked when the user clicks on an info window.
+ * To unset the callback, use null.
+ */
+ @UiThread
+ public void setOnInfoWindowClickListener(@Nullable OnInfoWindowClickListener listener) {
+ annotationManager.getInfoWindowManager().setOnInfoWindowClickListener(listener);
+ }
+
+ /**
+ * Return the InfoWindow click listener
+ *
+ * @return Current active InfoWindow Click Listener
+ */
+ @UiThread
+ public OnInfoWindowClickListener getOnInfoWindowClickListener() {
+ return annotationManager.getInfoWindowManager().getOnInfoWindowClickListener();
+ }
+
+ /**
+ * Sets a callback that's invoked when a marker's info window is long pressed.
+ *
+ * @param listener The callback that's invoked when a marker's info window is long pressed. To unset the callback,
+ * use null.
+ */
+ @UiThread
+ public void setOnInfoWindowLongClickListener(@Nullable OnInfoWindowLongClickListener
+ listener) {
+ annotationManager.getInfoWindowManager().setOnInfoWindowLongClickListener(listener);
+ }
+
+ /**
+ * Return the InfoWindow long click listener
+ *
+ * @return Current active InfoWindow long Click Listener
+ */
+ public OnInfoWindowLongClickListener getOnInfoWindowLongClickListener() {
+ return annotationManager.getInfoWindowManager().getOnInfoWindowLongClickListener();
+ }
+
+ public void setOnInfoWindowCloseListener(@Nullable OnInfoWindowCloseListener listener) {
+ annotationManager.getInfoWindowManager().setOnInfoWindowCloseListener(listener);
+ }
+
+ /**
+ * Return the InfoWindow close listener
+ *
+ * @return Current active InfoWindow Close Listener
+ */
+ @UiThread
+ public OnInfoWindowCloseListener getOnInfoWindowCloseListener() {
+ return annotationManager.getInfoWindowManager().getOnInfoWindowCloseListener();
+ }
+
+ //
+ // User location
+ //
+
+ /**
+ * Returns the status of the my-location layer.
+ *
+ * @return True if the my-location layer is enabled, false otherwise.
+ */
+ @UiThread
+ public boolean isMyLocationEnabled() {
+ return trackingSettings.isMyLocationEnabled();
+ }
+
+ /**
+ * <p>
+ * Enables or disables the my-location layer.
+ * While enabled, the my-location layer continuously draws an indication of a user's current
+ * location and bearing.
+ * </p>
+ * In order to use the my-location layer feature you need to request permission for either
+ * android.Manifest.permission#ACCESS_COARSE_LOCATION or android.Manifest.permission#ACCESS_FINE_LOCATION.
+ *
+ * @param enabled True to enable; false to disable.
+ */
+ @UiThread
+ public void setMyLocationEnabled(boolean enabled) {
+ trackingSettings.setMyLocationEnabled(enabled);
+ }
+
+ /**
+ * Returns the currently displayed user location, or null if there is no location data available.
+ *
+ * @return The currently displayed user location.
+ */
+ @UiThread
+ @Nullable
+ public Location getMyLocation() {
+ return trackingSettings.getMyLocation();
+ }
+
+ /**
+ * Sets a callback that's invoked when the the My Location view
+ * (which signifies the user's location) changes location.
+ *
+ * @param listener The callback that's invoked when the user clicks on a marker.
+ * To unset the callback, use null.
+ */
+ @UiThread
+ public void setOnMyLocationChangeListener(@Nullable MapboxMap.OnMyLocationChangeListener
+ listener) {
+ trackingSettings.setOnMyLocationChangeListener(listener);
+ }
+
+ /**
+ * Sets a callback that's invoked when the location tracking mode changes.
+ *
+ * @param listener The callback that's invoked when the location tracking mode changes.
+ * To unset the callback, use null.
+ */
+ @UiThread
+ public void setOnMyLocationTrackingModeChangeListener(
+ @Nullable MapboxMap.OnMyLocationTrackingModeChangeListener listener) {
+ trackingSettings.setOnMyLocationTrackingModeChangeListener(listener);
+ }
+
+ /**
+ * Sets a callback that's invoked when the bearing tracking mode changes.
+ *
+ * @param listener The callback that's invoked when the bearing tracking mode changes.
+ * To unset the callback, use null.
+ */
+ @UiThread
+ public void setOnMyBearingTrackingModeChangeListener(@Nullable OnMyBearingTrackingModeChangeListener listener) {
+ trackingSettings.setOnMyBearingTrackingModeChangeListener(listener);
+ }
+
+ //
+ // Invalidate
+ //
+
+ /**
+ * Takes a snapshot of the map.
+ *
+ * @param callback Callback method invoked when the snapshot is taken.
+ * @param bitmap A pre-allocated bitmap.
+ */
+ @UiThread
+ public void snapshot(@NonNull SnapshotReadyCallback callback, @Nullable final Bitmap bitmap) {
+ // FIXME 12/02/2016
+ //mapView.snapshot(callback, bitmap);
+ }
+
+ /**
+ * Takes a snapshot of the map.
+ *
+ * @param callback Callback method invoked when the snapshot is taken.
+ */
+ @UiThread
+ public void snapshot(@NonNull SnapshotReadyCallback callback) {
+ // FIXME 12/02/2016
+ //mapView.snapshot(callback, null);
+ }
+
+ /**
+ * Queries the map for rendered features
+ *
+ * @param coordinates the point to query
+ * @param layerIds optionally - only query these layers
+ * @return the list of feature
+ */
+ @UiThread
+ @NonNull
+ public List<Feature> queryRenderedFeatures(@NonNull PointF coordinates, @Nullable String...
+ layerIds) {
+ return nativeMapView.queryRenderedFeatures(coordinates, layerIds);
+ }
+
+ /**
+ * Queries the map for rendered features
+ *
+ * @param coordinates the box to query
+ * @param layerIds optionally - only query these layers
+ * @return the list of feature
+ */
+ @UiThread
+ @NonNull
+ public List<Feature> queryRenderedFeatures(@NonNull RectF coordinates, @Nullable String...
+ layerIds) {
+ return nativeMapView.queryRenderedFeatures(coordinates, layerIds);
+ }
+
+ //
+ // Interfaces
+ //
+
+ /**
+ * Interface definition for a callback to be invoked when the map is flinged.
+ *
+ * @see MapboxMap#setOnFlingListener(OnFlingListener)
+ */
+ public interface OnFlingListener {
+ /**
+ * Called when the map is flinged.
+ */
+ void onFling();
+ }
+
+ /**
+ * Interface definition for a callback to be invoked when the map is scrolled.
+ *
+ * @see MapboxMap#setOnScrollListener(OnScrollListener)
+ */
+ public interface OnScrollListener {
+ /**
+ * Called when the map is scrolled.
+ */
+ void onScroll();
+ }
+
+ /**
+ * Interface definition for a callback to be invoked when the camera changes position.
+ */
+ public interface OnCameraChangeListener {
+ /**
+ * Called after the camera position has changed. During an animation,
+ * this listener may not be notified of intermediate camera positions.
+ * It is always called for the final position in the animation.
+ *
+ * @param position The CameraPosition at the end of the last camera change.
+ */
+ void onCameraChange(CameraPosition position);
+ }
+
+ /**
+ * Interface definition for a callback to be invoked when a frame is rendered to the map view.
+ *
+ * @see MapboxMap#setOnFpsChangedListener(OnFpsChangedListener)
+ */
+ public interface OnFpsChangedListener {
+ /**
+ * Called for every frame rendered to the map view.
+ *
+ * @param fps The average number of frames rendered over the last second.
+ */
+ void onFpsChanged(double fps);
+ }
+
+ /**
+ * Interface definition for a callback to be invoked when a user registers an listener that is
+ * related to touch and click events.
+ */
+ interface OnRegisterTouchListener {
+ void onRegisterMapClickListener(OnMapClickListener listener);
+
+ void onRegisterMapLongClickListener(OnMapLongClickListener listener);
+
+ void onRegisterScrollListener(OnScrollListener listener);
- //
- // Debug
- //
+ void onRegisterFlingListener(OnFlingListener listener);
+ }
+ /**
+ * Interface definition for a callback to be invoked when the user clicks on the map view.
+ *
+ * @see MapboxMap#setOnMapClickListener(OnMapClickListener)
+ */
+ public interface OnMapClickListener {
/**
- * Returns whether the map debug information is currently shown.
+ * Called when the user clicks on the map view.
*
- * @return If true, map debug information is currently shown.
+ * @param point The projected map coordinate the user clicked on.
*/
- @UiThread
- public boolean isDebugActive() {
- return mapView.isDebugActive();
- }
+ void onMapClick(@NonNull LatLng point);
+ }
+ /**
+ * Interface definition for a callback to be invoked when the user long clicks on the map view.
+ *
+ * @see MapboxMap#setOnMapLongClickListener(OnMapLongClickListener)
+ */
+ public interface OnMapLongClickListener {
/**
- * <p>
- * Changes whether the map debug information is shown.
- * </p>
- * The default value is false.
+ * Called when the user long clicks on the map view.
*
- * @param debugActive If true, map debug information is shown.
+ * @param point The projected map coordinate the user long clicked on.
*/
- @UiThread
- public void setDebugActive(boolean debugActive) {
- mapView.setDebugActive(debugActive);
- }
+ void onMapLongClick(@NonNull LatLng point);
+ }
+ /**
+ * Interface definition for a callback to be invoked when the user clicks on a marker.
+ *
+ * @see MapboxMap#setOnMarkerClickListener(OnMarkerClickListener)
+ */
+ public interface OnMarkerClickListener {
/**
- * <p>
- * Cycles through the map debug options.
- * </p>
- * The value of {@link MapView#isDebugActive()} reflects whether there are
- * any map debug options enabled or disabled.
+ * Called when the user clicks on a marker.
*
- * @see MapView#isDebugActive()
+ * @param marker The marker the user clicked on.
+ * @return If true the listener has consumed the event and the info window will not be shown.
*/
- @UiThread
- public void cycleDebugOptions() {
- mapView.cycleDebugOptions();
- }
-
- //
- // Styling
- //
+ boolean onMarkerClick(@NonNull Marker marker);
+ }
+ /**
+ * Interface definition for a callback to be invoked when the user clicks on an info window.
+ *
+ * @see MapboxMap#setOnInfoWindowClickListener(OnInfoWindowClickListener)
+ */
+ public interface OnInfoWindowClickListener {
/**
- * <p>
- * Loads a new map style from the specified URL.
- * </p>
- * {@code url} can take the following forms:
- * <ul>
- * <li>{@code Style.*}: load one of the bundled styles in {@link Style}.</li>
- * <li>{@code mapbox://styles/<user>/<style>}:
- * retrieves the style from a <a href="https://www.mapbox.com/account/">Mapbox account.</a>
- * {@code user} is your username. {@code style} is the ID of your custom
- * style created in <a href="https://www.mapbox.com/studio">Mapbox Studio</a>.</li>
- * <li>{@code http://...} or {@code https://...}:
- * retrieves the style over the Internet from any web server.</li>
- * <li>{@code asset://...}:
- * reads the style from the APK {@code assets/} directory.
- * This is used to load a style bundled with your app.</li>
- * <li>{@code null}: loads the default {@link Style#MAPBOX_STREETS} style.</li>
- * </ul>
- * <p>
- * This method is asynchronous and will return immediately before the style finishes loading.
- * If you wish to wait for the map to finish loading listen for the {@link MapView#DID_FINISH_LOADING_MAP} event.
- * </p>
- * If the style fails to load or an invalid style URL is set, the map view will become blank.
- * An error message will be logged in the Android logcat and {@link MapView#DID_FAIL_LOADING_MAP} event will be
- * sent.
+ * Called when the user clicks on an info window.
*
- * @param url The URL of the map style
- * @see Style
+ * @param marker The marker of the info window the user clicked on.
+ * @return If true the listener has consumed the event and the info window will not be closed.
*/
- @UiThread
- public void setStyleUrl(@NonNull String url) {
- mapView.setStyleUrl(url);
- }
+ boolean onInfoWindowClick(@NonNull Marker marker);
+ }
- /**
- * <p>
- * Loads a new map style from the specified bundled style.
- * </p>
- * <p>
- * This method is asynchronous and will return immediately before the style finishes loading.
- * If you wish to wait for the map to finish loading listen for the {@link MapView#DID_FINISH_LOADING_MAP} event.
- * </p>
- * If the style fails to load or an invalid style URL is set, the map view will become blank.
- * An error message will be logged in the Android logcat and {@link MapView#DID_FAIL_LOADING_MAP} event will be
- * sent.
- *
- * @param style The bundled style. Accepts one of the values from {@link Style}.
- * @see Style
- * @deprecated use {@link #setStyleUrl(String)} instead with versioned url methods from {@link Style}
- */
- @UiThread
- @Deprecated
- public void setStyle(@Style.StyleUrl String style) {
- setStyleUrl(style);
- }
+ /**
+ * Interface definition for a callback to be invoked when the user long presses on a marker's info window.
+ *
+ * @see MapboxMap#setOnInfoWindowClickListener(OnInfoWindowClickListener)
+ */
+ public interface OnInfoWindowLongClickListener {
/**
- * <p>
- * Returns the map style currently displayed in the map view.
- * </p>
- * If the default style is currently displayed, a URL will be returned instead of null.
+ * Called when the user makes a long-press gesture on the marker's info window.
*
- * @return The URL of the map style.
+ * @param marker The marker were the info window is attached to
*/
- @UiThread
- @NonNull
- public String getStyleUrl() {
- return mapView.getStyleUrl();
- }
+ void onInfoWindowLongClick(Marker marker);
+ }
- //
- // Access token
- //
+ /**
+ * Interface definition for a callback to be invoked when a marker's info window is closed.
+ *
+ * @see MapboxMap#setOnInfoWindowCloseListener(OnInfoWindowCloseListener)
+ */
+ public interface OnInfoWindowCloseListener {
/**
- * <p>
- * DEPRECATED @see MapboxAccountManager#start(String)
- * </p>
- * <p>
- * Sets the current Mapbox access token used to load map styles and tiles.
- * </p>
+ * Called when the marker's info window is closed.
*
- * @param accessToken Your public Mapbox access token.
- * @see MapView#setAccessToken(String)
- * @deprecated As of release 4.1.0, replaced by {@link com.mapbox.mapboxsdk.MapboxAccountManager#start(Context, String)}
+ * @param marker The marker of the info window that was closed.
*/
- @Deprecated
- @UiThread
- public void setAccessToken(@NonNull String accessToken) {
- mapView.setAccessToken(accessToken);
- }
+ void onInfoWindowClose(Marker marker);
+ }
+ /**
+ * Interface definition for a callback to be invoked when an info window will be shown.
+ *
+ * @see MapboxMap#setInfoWindowAdapter(InfoWindowAdapter)
+ */
+ public interface InfoWindowAdapter {
/**
- * <p>
- * DEPRECATED @see MapboxAccountManager#getAccessToken()
- * </p>
- * <p>
- * Returns the current Mapbox access token used to load map styles and tiles.
- * </p>
+ * Called when an info window will be shown as a result of a marker click.
*
- * @return The current Mapbox access token.
- * @deprecated As of release 4.1.0, replaced by {@link MapboxAccountManager#getAccessToken()}
+ * @param marker The marker the user clicked on.
+ * @return View to be shown as a info window. If null is returned the default
+ * info window will be shown.
*/
- @Deprecated
- @UiThread
@Nullable
- public String getAccessToken() {
- return mapView.getAccessToken();
- }
+ View getInfoWindow(@NonNull Marker marker);
+ }
- //
- // Annotations
- //
+ /**
+ * Interface definition for a callback to be invoked when an MarkerView will be shown.
+ *
+ * @param <U> the instance type of MarkerView
+ */
+ public abstract static class MarkerViewAdapter<U extends MarkerView> {
- void setTilt(double tilt) {
- mapView.setTilt(tilt);
- }
+ private Context context;
+ private final Class<U> persistentClass;
+ private final Pools.SimplePool<View> viewReusePool;
/**
- * <p>
- * Adds a marker to this map.
- * </p>
- * The marker's icon is rendered on the map at the location {@code Marker.position}.
- * If {@code Marker.title} is defined, the map shows an info box with the marker's title and snippet.
+ * Create an instance of MarkerViewAdapter.
*
- * @param markerOptions A marker options object that defines how to render the marker.
- * @return The {@code Marker} that was added to the map.
+ * @param context the context associated to a MapView
*/
- @UiThread
- @NonNull
- public Marker addMarker(@NonNull MarkerOptions markerOptions) {
- return addMarker((BaseMarkerOptions) markerOptions);
+ @SuppressWarnings("unchecked")
+ public MarkerViewAdapter(Context context) {
+ this.context = context;
+ persistentClass = (Class<U>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
+ viewReusePool = new Pools.SimplePool<>(10000);
}
/**
- * <p>
- * Adds a marker to this map.
- * </p>
- * The marker's icon is rendered on the map at the location {@code Marker.position}.
- * If {@code Marker.title} is defined, the map shows an info box with the marker's title and snippet.
- *
- * @param markerOptions A marker options object that defines how to render the marker.
- * @return The {@code Marker} that was added to the map.
- */
- @UiThread
- @NonNull
- public Marker addMarker(@NonNull BaseMarkerOptions markerOptions) {
- Marker marker = prepareMarker(markerOptions);
- long id = mapView.addMarker(marker);
- marker.setMapboxMap(this);
- marker.setId(id);
- annotations.put(id, marker);
- return marker;
- }
-
- /**
- * <p>
- * Adds a marker to this map.
- * </p>
- * The marker's icon is rendered on the map at the location {@code Marker.position}.
- * If {@code Marker.title} is defined, the map shows an info box with the marker's title and snippet.
- *
- * @param markerOptions A marker options object that defines how to render the marker.
- * @return The {@code Marker} that was added to the map.
- */
- @UiThread
- @NonNull
- public MarkerView addMarker(@NonNull BaseMarkerViewOptions markerOptions) {
- MarkerView marker = prepareViewMarker(markerOptions);
- marker.setMapboxMap(this);
- long id = mapView.addMarker(marker);
- marker.setId(id);
- annotations.put(id, marker);
- markerViewManager.invalidateViewMarkersInVisibleRegion();
- return marker;
- }
-
- @UiThread
- @NonNull
- public List<MarkerView> addMarkerViews(@NonNull List<? extends BaseMarkerViewOptions> markerViewOptions) {
- List<MarkerView> markers = new ArrayList<>();
- for (BaseMarkerViewOptions markerViewOption : markerViewOptions) {
- MarkerView marker = prepareViewMarker(markerViewOption);
- marker.setMapboxMap(this);
- long id = mapView.addMarker(marker);
- marker.setId(id);
- annotations.put(id, marker);
- markers.add(marker);
- }
- markerViewManager.invalidateViewMarkersInVisibleRegion();
- return markers;
- }
-
- /**
- * <p>
- * Adds multiple markers to this map.
- * </p>
- * The marker's icon is rendered on the map at the location {@code Marker.position}.
- * If {@code Marker.title} is defined, the map shows an info box with the marker's title and snippet.
- *
- * @param markerOptionsList A list of marker options objects that defines how to render the markers.
- * @return A list of the {@code Marker}s that were added to the map.
- */
- @UiThread
- @NonNull
- public List<Marker> addMarkers(@NonNull List<? extends BaseMarkerOptions> markerOptionsList) {
- int count = markerOptionsList.size();
- List<Marker> markers = new ArrayList<>(count);
- if (count > 0) {
- BaseMarkerOptions markerOptions;
- Marker marker;
- for (int i = 0; i < count; i++) {
- markerOptions = markerOptionsList.get(i);
- marker = prepareMarker(markerOptions);
- markers.add(marker);
- }
-
- if (markers.size() > 0) {
- long[] ids = mapView.addMarkers(markers);
-
- // if unittests or markers are correctly added to map
- if (ids == null || ids.length == markers.size()) {
- long id = 0;
- Marker m;
- for (int i = 0; i < markers.size(); i++) {
- m = markers.get(i);
- m.setMapboxMap(this);
- if (ids != null) {
- id = ids[i];
- } else {
- //unit test
- id++;
- }
- m.setId(id);
- annotations.put(id, m);
- }
- }
- }
- }
- return markers;
- }
-
- /**
- * <p>
- * Updates a marker on this map. Does nothing if the marker is already added.
- * </p>
- *
- * @param updatedMarker An updated marker object.
- */
- @UiThread
- public void updateMarker(@NonNull Marker updatedMarker) {
- mapView.updateMarker(updatedMarker);
-
- int index = annotations.indexOfKey(updatedMarker.getId());
- if (index > -1) {
- annotations.setValueAt(index, updatedMarker);
- }
- }
-
- /**
- * Update a polygon on this map.
- *
- * @param polygon An updated polygon object.
- */
- @UiThread
- public void updatePolygon(Polygon polygon) {
- mapView.updatePolygon(polygon);
-
- int index = annotations.indexOfKey(polygon.getId());
- if (index > -1) {
- annotations.setValueAt(index, polygon);
- }
- }
-
- /**
- * Update a polyline on this map.
- *
- * @param polyline An updated polyline object.
- */
- @UiThread
- public void updatePolyline(Polyline polyline) {
- mapView.updatePolyline(polyline);
-
- int index = annotations.indexOfKey(polyline.getId());
- if (index > -1) {
- annotations.setValueAt(index, polyline);
- }
- }
-
- /**
- * Adds a polyline to this map.
- *
- * @param polylineOptions A polyline options object that defines how to render the polyline.
- * @return The {@code Polyine} that was added to the map.
- */
- @UiThread
- @NonNull
- public Polyline addPolyline(@NonNull PolylineOptions polylineOptions) {
- Polyline polyline = polylineOptions.getPolyline();
- if (!polyline.getPoints().isEmpty()) {
- long id = mapView.addPolyline(polyline);
- polyline.setMapboxMap(this);
- polyline.setId(id);
- annotations.put(id, polyline);
- }
- return polyline;
- }
-
- /**
- * Adds multiple polylines to this map.
- *
- * @param polylineOptionsList A list of polyline options objects that defines how to render the polylines.
- * @return A list of the {@code Polyline}s that were added to the map.
- */
- @UiThread
- @NonNull
- public List<Polyline> addPolylines(@NonNull List<PolylineOptions> polylineOptionsList) {
- int count = polylineOptionsList.size();
- Polyline polyline;
- List<Polyline> polylines = new ArrayList<>(count);
-
- if (count > 0) {
- for (PolylineOptions options : polylineOptionsList) {
- polyline = options.getPolyline();
- if (!polyline.getPoints().isEmpty()) {
- polylines.add(polyline);
- }
- }
-
- long[] ids = mapView.addPolylines(polylines);
-
- // if unit tests or polylines are correctly added to map
- if (ids == null || ids.length == polylines.size()) {
- long id = 0;
- Polyline p;
-
- for (int i = 0; i < polylines.size(); i++) {
- p = polylines.get(i);
- p.setMapboxMap(this);
- if (ids != null) {
- id = ids[i];
- } else {
- // unit test
- id++;
- }
- p.setId(id);
- annotations.put(id, p);
- }
- }
- }
- return polylines;
- }
-
- /**
- * Adds a polygon to this map.
- *
- * @param polygonOptions A polygon options object that defines how to render the polygon.
- * @return The {@code Polygon} that was added to the map.
- */
- @UiThread
- @NonNull
- public Polygon addPolygon(@NonNull PolygonOptions polygonOptions) {
- Polygon polygon = polygonOptions.getPolygon();
- if (!polygon.getPoints().isEmpty()) {
- long id = mapView.addPolygon(polygon);
- polygon.setId(id);
- polygon.setMapboxMap(this);
- annotations.put(id, polygon);
- }
- return polygon;
- }
-
- /**
- * Adds multiple polygons to this map.
- *
- * @param polygonOptionsList A list of polygon options objects that defines how to render the polygons.
- * @return A list of the {@code Polygon}s that were added to the map.
- */
- @UiThread
- @NonNull
- public List<Polygon> addPolygons(@NonNull List<PolygonOptions> polygonOptionsList) {
- int count = polygonOptionsList.size();
-
- Polygon polygon;
- List<Polygon> polygons = new ArrayList<>(count);
- if (count > 0) {
- for (PolygonOptions polygonOptions : polygonOptionsList) {
- polygon = polygonOptions.getPolygon();
- if (!polygon.getPoints().isEmpty()) {
- polygons.add(polygon);
- }
- }
-
- long[] ids = mapView.addPolygons(polygons);
-
- // if unit tests or polygons correctly added to map
- if (ids == null || ids.length == polygons.size()) {
- long id = 0;
- for (int i = 0; i < polygons.size(); i++) {
- polygon = polygons.get(i);
- polygon.setMapboxMap(this);
- if (ids != null) {
- id = ids[i];
- } else {
- // unit test
- id++;
- }
- polygon.setId(id);
- annotations.put(id, polygon);
- }
- }
- }
- return polygons;
- }
-
- /**
- * <p>
- * Convenience method for removing a Marker from the map.
- * </p>
- * Calls removeAnnotation() internally
- *
- * @param marker Marker to remove
- */
- @UiThread
- public void removeMarker(@NonNull Marker marker) {
- removeAnnotation(marker);
- }
-
- /**
- * <p>
- * Convenience method for removing a Polyline from the map.
- * </p>
- * Calls removeAnnotation() internally
- *
- * @param polyline Polyline to remove
- */
- @UiThread
- public void removePolyline(@NonNull Polyline polyline) {
- removeAnnotation(polyline);
- }
-
- /**
- * <p>
- * Convenience method for removing a Polygon from the map.
- * </p>
- * Calls removeAnnotation() internally
+ * Called when an MarkerView will be added to the MapView.
*
- * @param polygon Polygon to remove
- */
- @UiThread
- public void removePolygon(@NonNull Polygon polygon) {
- removeAnnotation(polygon);
- }
-
- /**
- * Removes an annotation from the map.
- *
- * @param annotation The annotation object to remove.
- */
- @UiThread
- public void removeAnnotation(@NonNull Annotation annotation) {
- if (annotation instanceof Marker) {
- Marker marker = (Marker) annotation;
- marker.hideInfoWindow();
- if (marker instanceof MarkerView) {
- markerViewManager.removeMarkerView((MarkerView) marker);
- }
- }
- long id = annotation.getId();
- mapView.removeAnnotation(id);
- annotations.remove(id);
- }
-
- /**
- * Removes an annotation from the map
- *
- * @param id The identifier associated to the annotation to be removed
- */
- @UiThread
- public void removeAnnotation(long id) {
- mapView.removeAnnotation(id);
- annotations.remove(id);
- }
-
- /**
- * Removes multiple annotations from the map.
- *
- * @param annotationList A list of annotation objects to remove.
- */
- @UiThread
- public void removeAnnotations(@NonNull List<? extends Annotation> annotationList) {
- int count = annotationList.size();
- long[] ids = new long[count];
- for (int i = 0; i < count; i++) {
- Annotation annotation = annotationList.get(i);
- if (annotation instanceof Marker) {
- Marker marker = (Marker) annotation;
- marker.hideInfoWindow();
- if (marker instanceof MarkerView) {
- markerViewManager.removeMarkerView((MarkerView) marker);
- }
- }
- ids[i] = annotationList.get(i).getId();
- }
- mapView.removeAnnotations(ids);
- for (long id : ids) {
- annotations.remove(id);
- }
- }
-
- /**
- * Removes all annotations from the map.
- */
- @UiThread
- public void removeAnnotations() {
- Annotation annotation;
- int count = annotations.size();
- long[] ids = new long[count];
- for (int i = 0; i < count; i++) {
- ids[i] = annotations.keyAt(i);
- annotation = annotations.get(ids[i]);
- if (annotation instanceof Marker) {
- Marker marker = (Marker) annotation;
- marker.hideInfoWindow();
- if (marker instanceof MarkerView) {
- markerViewManager.removeMarkerView((MarkerView) marker);
- }
- }
- }
- mapView.removeAnnotations(ids);
- annotations.clear();
- }
-
- /**
- * Removes all markers, polylines, polygons, overlays, etc from the map.
- */
- @UiThread
- public void clear() {
- removeAnnotations();
- }
-
- /**
- * Return a annotation based on its id.
- *
- * @param id the id used to look up an annotation
- * @return An annotation with a matched id, null is returned if no match was found
+ * @param marker the model representing the MarkerView
+ * @param convertView the reusable view
+ * @param parent the parent ViewGroup of the convertview
+ * @return the View that is adapted to the contents of MarkerView
*/
@Nullable
- public Annotation getAnnotation(long id) {
- return annotations.get(id);
- }
-
- /**
- * Returns a list of all the annotations on the map.
- *
- * @return A list of all the annotation objects. The returned object is a copy so modifying this
- * list will not update the map
- */
- @NonNull
- public List<Annotation> getAnnotations() {
- List<Annotation> annotations = new ArrayList<>();
- for (int i = 0; i < this.annotations.size(); i++) {
- annotations.add(this.annotations.get(this.annotations.keyAt(i)));
- }
- return annotations;
- }
-
- /**
- * Returns a list of all the markers on the map.
- *
- * @return A list of all the markers objects. The returned object is a copy so modifying this
- * list will not update the map.
- */
- @NonNull
- public List<Marker> getMarkers() {
- List<Marker> markers = new ArrayList<>();
- Annotation annotation;
- for (int i = 0; i < annotations.size(); i++) {
- annotation = annotations.get(annotations.keyAt(i));
- if (annotation instanceof Marker) {
- markers.add((Marker) annotation);
- }
- }
- return markers;
- }
-
- /**
- * Returns a list of all the polygons on the map.
- *
- * @return A list of all the polygon objects. The returned object is a copy so modifying this
- * list will not update the map.
- */
- @NonNull
- public List<Polygon> getPolygons() {
- List<Polygon> polygons = new ArrayList<>();
- Annotation annotation;
- for (int i = 0; i < annotations.size(); i++) {
- annotation = annotations.get(annotations.keyAt(i));
- if (annotation instanceof Polygon) {
- polygons.add((Polygon) annotation);
- }
- }
- return polygons;
- }
-
- /**
- * Returns a list of all the polylines on the map.
- *
- * @return A list of all the polylines objects. The returned object is a copy so modifying this
- * list will not update the map.
- */
- @NonNull
- public List<Polyline> getPolylines() {
- List<Polyline> polylines = new ArrayList<>();
- Annotation annotation;
- for (int i = 0; i < annotations.size(); i++) {
- annotation = annotations.get(annotations.keyAt(i));
- if (annotation instanceof Polyline) {
- polylines.add((Polyline) annotation);
- }
- }
- return polylines;
- }
+ 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.
* <p>
- * Selects a marker. The selected marker will have it's info window opened.
- * Any other open info windows will be closed unless isAllowConcurrentMultipleOpenInfoWindows()
- * is true.
+ * This method should be used to reset an animated view back to it's original state for view reuse.
* </p>
- * Selecting an already selected marker will have no effect.
- *
- * @param marker The marker to select.
- */
- @UiThread
- public void selectMarker(@NonNull Marker marker) {
- if (marker == null) {
- Log.w(MapboxConstants.TAG, "marker was null, so just returning");
- return;
- }
-
- if (selectedMarkers.contains(marker)) {
- return;
- }
-
- // Need to deselect any currently selected annotation first
- if (!isAllowConcurrentMultipleOpenInfoWindows()) {
- deselectMarkers();
- }
-
- boolean handledDefaultClick = false;
- if (onMarkerClickListener != null) {
- // end developer has provided a custom click listener
- handledDefaultClick = onMarkerClickListener.onMarkerClick(marker);
- }
-
- if (!handledDefaultClick) {
- if (marker instanceof MarkerView) {
- markerViewManager.select((MarkerView) marker, false);
- markerViewManager.ensureInfoWindowOffset((MarkerView) marker);
- }
-
- if (isInfoWindowValidForMarker(marker) || getInfoWindowAdapter() != null) {
- infoWindows.add(marker.showInfoWindow(this, mapView));
- }
- }
-
- selectedMarkers.add(marker);
- }
-
- /**
- * Deselects any currently selected marker. All markers will have it's info window closed.
- */
- @UiThread
- public void deselectMarkers() {
- if (selectedMarkers.isEmpty()) {
- return;
- }
-
- for (Marker marker : selectedMarkers) {
- if (marker.isInfoWindowShown()) {
- marker.hideInfoWindow();
- }
-
- if (marker instanceof MarkerView) {
- markerViewManager.deselect((MarkerView) marker, false);
- }
- }
-
- // Removes all selected markers from the list
- selectedMarkers.clear();
- }
-
- /**
- * Deselects a currently selected marker. The selected marker will have it's info window closed.
- *
- * @param marker the marker to deselect
- */
- @UiThread
- public void deselectMarker(@NonNull Marker marker) {
- if (!selectedMarkers.contains(marker)) {
- return;
- }
-
- if (marker.isInfoWindowShown()) {
- marker.hideInfoWindow();
- }
-
- if (marker instanceof MarkerView) {
- markerViewManager.deselect((MarkerView) marker, false);
- }
-
- selectedMarkers.remove(marker);
- }
-
- /**
- * Gets the currently selected marker.
- *
- * @return The currently selected marker.
- */
- @UiThread
- public List<Marker> getSelectedMarkers() {
- return selectedMarkers;
- }
-
- private Marker prepareMarker(BaseMarkerOptions markerOptions) {
- Marker marker = markerOptions.getMarker();
- Icon icon = mapView.loadIconForMarker(marker);
- marker.setTopOffsetPixels(mapView.getTopOffsetPixelsForIcon(icon));
- return marker;
- }
-
- private MarkerView prepareViewMarker(BaseMarkerViewOptions markerViewOptions) {
- MarkerView marker = markerViewOptions.getMarker();
- mapView.loadIconForMarkerView(marker);
- return marker;
- }
-
- /**
- * Get the MarkerViewManager associated to the MapView.
- *
- * @return the associated MarkerViewManager
- */
- public MarkerViewManager getMarkerViewManager() {
- return markerViewManager;
- }
-
- //
- // InfoWindow
- //
-
- /**
* <p>
- * Sets a custom renderer for the contents of info window.
+ * Returning true indicates you want to the view reuse to be handled automatically.
+ * Returning false indicates you want to perform an animation and you are required calling
+ * {@link #releaseView(View)} yourself.
* </p>
- * When set your callback is invoked when an info window is about to be shown. By returning
- * a custom {@link View}, the default info window will be replaced.
- *
- * @param infoWindowAdapter The callback to be invoked when an info window will be shown.
- * To unset the callback, use null.
- */
- @UiThread
- public void setInfoWindowAdapter(@Nullable InfoWindowAdapter infoWindowAdapter) {
- this.infoWindowAdapter = infoWindowAdapter;
- }
-
- /**
- * Gets the callback to be invoked when an info window will be shown.
- *
- * @return The callback to be invoked when an info window will be shown.
- */
- @UiThread
- @Nullable
- public InfoWindowAdapter getInfoWindowAdapter() {
- return infoWindowAdapter;
- }
-
- /**
- * Changes whether the map allows concurrent multiple infowindows to be shown.
*
- * @param allow If true, map allows concurrent multiple infowindows to be shown.
+ * @param marker the model representing the MarkerView
+ * @param convertView the reusable view
+ * @return true if you want reuse to occur automatically, false if you want to manage this yourself.
*/
- @UiThread
- public void setAllowConcurrentMultipleOpenInfoWindows(boolean allow) {
- allowConcurrentMultipleInfoWindows = allow;
- }
-
- /**
- * Returns whether the map allows concurrent multiple infowindows to be shown.
- *
- * @return If true, map allows concurrent multiple infowindows to be shown.
- */
- @UiThread
- public boolean isAllowConcurrentMultipleOpenInfoWindows() {
- return allowConcurrentMultipleInfoWindows;
- }
-
- // used by MapView
- List<InfoWindow> getInfoWindows() {
- return infoWindows;
+ public boolean prepareViewForReuse(@NonNull MarkerView marker, @NonNull View convertView) {
+ return true;
}
- private boolean isInfoWindowValidForMarker(@NonNull Marker marker) {
- return !TextUtils.isEmpty(marker.getTitle()) || !TextUtils.isEmpty(marker.getSnippet());
- }
-
- //
- // Padding
- //
-
/**
+ * Called when a MarkerView is selected from the MapView.
* <p>
- * Sets the distance from the edges of the map view’s frame to the edges of the map
- * view’s logical viewport.
- * </p>
- * <p>
- * When the value of this property is equal to {0,0,0,0}, viewport
- * properties such as `centerCoordinate` assume a viewport that matches the map
- * view’s frame. Otherwise, those properties are inset, excluding part of the
- * frame from the viewport. For instance, if the only the top edge is inset, the
- * map center is effectively shifted downward.
+ * Returning true from this method indicates you want to move the MarkerView to the selected state.
+ * Returning false indicates you want to animate the View first an manually select the MarkerView when appropriate.
* </p>
*
- * @param left The left margin in pixels.
- * @param top The top margin in pixels.
- * @param right The right margin in pixels.
- * @param bottom The bottom margin in pixels.
+ * @param marker the model representing the MarkerView
+ * @param convertView the reusable view
+ * @param reselectionFromRecycling indicates if the onSelect callback is the initial selection
+ * callback or that selection occurs due to recreation of selected marker
+ * @return true if you want to select the Marker immediately, false if you want to manage this yourself.
*/
- public void setPadding(int left, int top, int right, int bottom) {
- mapView.setContentPadding(left, top, right, bottom);
- uiSettings.invalidate();
+ public boolean onSelect(@NonNull U marker, @NonNull View convertView, boolean reselectionFromRecycling) {
+ return true;
}
/**
- * Returns the current configured content padding on map view.
+ * Called when a MarkerView is deselected from the MapView.
*
- * @return An array with length 4 in the LTRB order.
+ * @param marker the model representing the MarkerView
+ * @param convertView the reusable view
*/
- public int[] getPadding() {
- return new int[]{mapView.getContentPaddingLeft(),
- mapView.getContentPaddingTop(),
- mapView.getContentPaddingRight(),
- mapView.getContentPaddingBottom()};
+ public void onDeselect(@NonNull U marker, @NonNull View convertView) {
}
- //
- // Map events
- //
-
/**
- * Sets a callback that's invoked on every change in camera position.
+ * Returns the generic type of the used MarkerView.
*
- * @param listener The callback that's invoked on every camera change position.
- * To unset the callback, use null.
+ * @return the generic type
*/
- @UiThread
- public void setOnCameraChangeListener(@Nullable OnCameraChangeListener listener) {
- onCameraChangeListener = listener;
+ public final Class<U> getMarkerClass() {
+ return persistentClass;
}
/**
- * Sets a callback that's invoked on every frame rendered to the map view.
+ * Returns the pool used to store reusable Views.
*
- * @param listener The callback that's invoked on every frame rendered to the map view.
- * To unset the callback, use null.
+ * @return the pool associated to this adapter
*/
- @UiThread
- public void setOnFpsChangedListener(@Nullable OnFpsChangedListener listener) {
- onFpsChangedListener = listener;
- }
-
- // used by MapView
- OnFpsChangedListener getOnFpsChangedListener() {
- return onFpsChangedListener;
+ public final Pools.SimplePool<View> getViewReusePool() {
+ return viewReusePool;
}
/**
- * Sets a callback that's invoked when the map is scrolled.
+ * Returns the context associated to the hosting MapView.
*
- * @param listener The callback that's invoked when the map is scrolled.
- * To unset the callback, use null.
+ * @return the context used
*/
- @UiThread
- public void setOnScrollListener(@Nullable OnScrollListener listener) {
- onScrollListener = listener;
- }
-
- // used by MapView
- OnScrollListener getOnScrollListener() {
- return onScrollListener;
+ public final Context getContext() {
+ return context;
}
/**
- * Sets a callback that's invoked when the map is flinged.
+ * Release a View to the ViewPool.
*
- * @param listener The callback that's invoked when the map is flinged.
- * To unset the callback, use null.
+ * @param view the view to be released
*/
- @UiThread
- public void setOnFlingListener(@Nullable OnFlingListener listener) {
- onFlingListener = listener;
+ public final void releaseView(View view) {
+ view.setVisibility(View.GONE);
+ viewReusePool.release(view);
}
+ }
- // used by MapView
- OnFlingListener getOnFlingListener() {
- return onFlingListener;
- }
+ /**
+ * Interface definition for a callback to be invoked when the user clicks on a MarkerView.
+ */
+ public interface OnMarkerViewClickListener {
/**
- * Sets a callback that's invoked when the user clicks on the map view.
+ * Called when the user clicks on a MarkerView.
*
- * @param listener The callback that's invoked when the user clicks on the map view.
- * To unset the callback, use null.
+ * @param marker the MarkerView associated to the clicked View
+ * @param view the clicked View
+ * @param adapter the adapter used to adapt the MarkerView to the View
+ * @return If true the listener has consumed the event and the info window will not be shown
*/
- @UiThread
- public void setOnMapClickListener(@Nullable OnMapClickListener listener) {
- onMapClickListener = listener;
- }
-
- // used by MapView
- OnMapClickListener getOnMapClickListener() {
- return onMapClickListener;
- }
+ boolean onMarkerClick(@NonNull Marker marker, @NonNull View view, @NonNull MarkerViewAdapter adapter);
+ }
+ /**
+ * Interface definition for a callback to be invoked when the the My Location view changes location.
+ *
+ * @see MapboxMap#setOnMyLocationChangeListener(OnMyLocationChangeListener)
+ */
+ public interface OnMyLocationChangeListener {
/**
- * Sets a callback that's invoked when the user long clicks on the map view.
+ * Called when the location of the My Location view has changed
+ * (be it latitude/longitude, bearing or accuracy).
*
- * @param listener The callback that's invoked when the user long clicks on the map view.
- * To unset the callback, use null.
+ * @param location The current location of the My Location view The type of map change event.
*/
- @UiThread
- public void setOnMapLongClickListener(@Nullable OnMapLongClickListener listener) {
- onMapLongClickListener = listener;
- }
+ void onMyLocationChange(@Nullable Location location);
+ }
- // used by MapView
- OnMapLongClickListener getOnMapLongClickListener() {
- return onMapLongClickListener;
- }
+ /**
+ * Interface definition for a callback to be invoked when the the My Location tracking mode changes.
+ *
+ * @see TrackingSettings#setMyLocationTrackingMode(int)
+ */
+ public interface OnMyLocationTrackingModeChangeListener {
/**
- * Sets a callback that's invoked when the user clicks on a marker.
+ * Called when the tracking mode of My Location tracking has changed
*
- * @param listener The callback that's invoked when the user clicks on a marker.
- * To unset the callback, use null.
+ * @param myLocationTrackingMode the current active location tracking mode
*/
- @UiThread
- public void setOnMarkerClickListener(@Nullable OnMarkerClickListener listener) {
- onMarkerClickListener = listener;
- }
+ void onMyLocationTrackingModeChange(@MyLocationTracking.Mode int myLocationTrackingMode);
+ }
- /**
- * Sets a callback that's invoked when the user clicks on an info window.
- *
- * @param listener The callback that's invoked when the user clicks on an info window.
- * To unset the callback, use null.
- */
- @UiThread
- public void setOnInfoWindowClickListener(@Nullable OnInfoWindowClickListener listener) {
- onInfoWindowClickListener = listener;
- }
+ /**
+ * Interface definition for a callback to be invoked when the the My Location tracking mode changes.
+ *
+ * @see TrackingSettings#setMyLocationTrackingMode(int)
+ */
+ public interface OnMyBearingTrackingModeChangeListener {
/**
- * Return the InfoWindow click listener
+ * Called when the tracking mode of My Bearing tracking has changed
*
- * @return Current active InfoWindow Click Listener
+ * @param myBearingTrackingMode the current active bearing tracking mode
*/
- @UiThread
- public OnInfoWindowClickListener getOnInfoWindowClickListener() {
- return onInfoWindowClickListener;
- }
+ void onMyBearingTrackingModeChange(@MyBearingTracking.Mode int myBearingTrackingMode);
+ }
+ /**
+ * Interface definition for a callback to be invoked when a task is complete or cancelled.
+ */
+ public interface CancelableCallback {
/**
- * Sets a callback that's invoked when a marker's info window is long pressed.
- *
- * @param listener The callback that's invoked when a marker's info window is long pressed. To unset the callback,
- * use null.
+ * Invoked when a task is cancelled.
*/
- @UiThread
- public void setOnInfoWindowLongClickListener(@Nullable OnInfoWindowLongClickListener listener) {
- onInfoWindowLongClickListener = listener;
- }
+ void onCancel();
/**
- * Return the InfoWindow long click listener
- *
- * @return Current active InfoWindow long Click Listener
+ * Invoked when a task is complete.
*/
- public OnInfoWindowLongClickListener getOnInfoWindowLongClickListener() {
- return onInfoWindowLongClickListener;
- }
-
- public void setOnInfoWindowCloseListener(@Nullable OnInfoWindowCloseListener listener) {
- onInfoWindowCloseListener = listener;
- }
+ void onFinish();
+ }
+ /**
+ * Interface definition for a callback to be invoked when the snapshot has been taken.
+ */
+ public interface SnapshotReadyCallback {
/**
- * Return the InfoWindow close listener
+ * Invoked when the snapshot has been taken.
*
- * @return Current active InfoWindow Close Listener
+ * @param snapshot the snapshot bitmap
*/
- @UiThread
- public OnInfoWindowCloseListener getOnInfoWindowCloseListener() {
- return onInfoWindowCloseListener;
- }
-
- //
- // User location
- //
+ void onSnapshotReady(Bitmap snapshot);
+ }
- /**
- * Returns the status of the my-location layer.
- *
- * @return True if the my-location layer is enabled, false otherwise.
- */
- @UiThread
- public boolean isMyLocationEnabled() {
- return myLocationEnabled;
- }
-
- /**
- * <p>
- * Enables or disables the my-location layer.
- * While enabled, the my-location layer continuously draws an indication of a user's current
- * location and bearing.
- * </p>
- * In order to use the my-location layer feature you need to request permission for either
- * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}
- * or @link android.Manifest.permission#ACCESS_FINE_LOCATION.
- *
- * @param enabled True to enable; false to disable.
- */
- @UiThread
- public void setMyLocationEnabled(boolean enabled) {
- if (!mapView.isPermissionsAccepted()) {
- Log.e(MapboxConstants.TAG, "Could not activate user location tracking: "
- + "user did not accept the permission or permissions were not requested.");
- return;
- }
- myLocationEnabled = enabled;
- mapView.setMyLocationEnabled(enabled);
- }
-
- /**
- * Returns the currently displayed user location, or null if there is no location data available.
- *
- * @return The currently displayed user location.
- */
- @UiThread
- @Nullable
- public Location getMyLocation() {
- return mapView.getMyLocation();
- }
-
- /**
- * Sets a callback that's invoked when the the My Location view
- * (which signifies the user's location) changes location.
- *
- * @param listener The callback that's invoked when the user clicks on a marker.
- * To unset the callback, use null.
- */
- @UiThread
- public void setOnMyLocationChangeListener(@Nullable MapboxMap.OnMyLocationChangeListener listener) {
- mapView.setOnMyLocationChangeListener(listener);
- }
-
- /**
- * Sets a callback that's invoked when the location tracking mode changes.
- *
- * @param listener The callback that's invoked when the location tracking mode changes.
- * To unset the callback, use null.
- */
- @UiThread
- public void setOnMyLocationTrackingModeChangeListener(@Nullable MapboxMap.OnMyLocationTrackingModeChangeListener listener) {
- onMyLocationTrackingModeChangeListener = listener;
- }
-
- // used by MapView
- MapboxMap.OnMyLocationTrackingModeChangeListener getOnMyLocationTrackingModeChangeListener() {
- return onMyLocationTrackingModeChangeListener;
- }
-
- /**
- * Sets a callback that's invoked when the bearing tracking mode changes.
- *
- * @param listener The callback that's invoked when the bearing tracking mode changes.
- * To unset the callback, use null.
- */
- @UiThread
- public void setOnMyBearingTrackingModeChangeListener(@Nullable OnMyBearingTrackingModeChangeListener listener) {
- onMyBearingTrackingModeChangeListener = listener;
- }
-
- // used by MapView
- OnMyBearingTrackingModeChangeListener getOnMyBearingTrackingModeChangeListener() {
- return onMyBearingTrackingModeChangeListener;
- }
-
- MapView getMapView() {
- return mapView;
- }
-
- void setUiSettings(UiSettings uiSettings) {
- this.uiSettings = uiSettings;
- }
-
- void setProjection(Projection projection) {
- this.projection = projection;
- }
-
- //
- // Invalidate
- //
-
- /**
- * Triggers an invalidation of the map view.
- */
- public void invalidate() {
- mapView.invalidate();
- }
-
- /**
- * Takes a snapshot of the map.
- *
- * @param callback Callback method invoked when the snapshot is taken.
- * @param bitmap A pre-allocated bitmap.
- */
- @UiThread
- public void snapshot(@NonNull SnapshotReadyCallback callback, @Nullable final Bitmap bitmap) {
- mapView.snapshot(callback, bitmap);
- }
-
- /**
- * Takes a snapshot of the map.
- *
- * @param callback Callback method invoked when the snapshot is taken.
- */
- @UiThread
- public void snapshot(@NonNull SnapshotReadyCallback callback) {
- mapView.snapshot(callback, null);
- }
-
- /**
- * Queries the map for rendered features
- *
- * @param coordinates the point to query
- * @param layerIds optionally - only query these layers
- * @return the list of feature
- */
- @UiThread
- @NonNull
- public List<Feature> queryRenderedFeatures(@NonNull PointF coordinates, @Nullable String... layerIds) {
- return mapView.getNativeMapView().queryRenderedFeatures(coordinates, layerIds);
- }
-
- /**
- * Queries the map for rendered features
- *
- * @param coordinates the box to query
- * @param layerIds optionally - only query these layers
- * @return the list of feature
- */
- @UiThread
- @NonNull
- public List<Feature> queryRenderedFeatures(@NonNull RectF coordinates, @Nullable String... layerIds) {
- return mapView.getNativeMapView().queryRenderedFeatures(coordinates, layerIds);
- }
-
- //
- // Interfaces
- //
-
- /**
- * Interface definition for a callback to be invoked when the map is flinged.
- *
- * @see MapboxMap#setOnFlingListener(OnFlingListener)
- */
- public interface OnFlingListener {
- /**
- * Called when the map is flinged.
- */
- void onFling();
- }
-
- /**
- * Interface definition for a callback to be invoked when the map is scrolled.
- *
- * @see MapboxMap#setOnScrollListener(OnScrollListener)
- */
- public interface OnScrollListener {
- /**
- * Called when the map is scrolled.
- */
- void onScroll();
- }
-
- /**
- * Interface definition for a callback to be invoked when the camera changes position.
- */
- public interface OnCameraChangeListener {
- /**
- * Called after the camera position has changed. During an animation,
- * this listener may not be notified of intermediate camera positions.
- * It is always called for the final position in the animation.
- *
- * @param position The CameraPosition at the end of the last camera change.
- */
- void onCameraChange(CameraPosition position);
- }
-
- /**
- * Interface definition for a callback to be invoked when a frame is rendered to the map view.
- *
- * @see MapboxMap#setOnFpsChangedListener(OnFpsChangedListener)
- */
- public interface OnFpsChangedListener {
- /**
- * Called for every frame rendered to the map view.
- *
- * @param fps The average number of frames rendered over the last second.
- */
- void onFpsChanged(double fps);
- }
-
- /**
- * Interface definition for a callback to be invoked when the user clicks on the map view.
- *
- * @see MapboxMap#setOnMapClickListener(OnMapClickListener)
- */
- public interface OnMapClickListener {
- /**
- * Called when the user clicks on the map view.
- *
- * @param point The projected map coordinate the user clicked on.
- */
- void onMapClick(@NonNull LatLng point);
- }
-
- /**
- * Interface definition for a callback to be invoked when the user long clicks on the map view.
- *
- * @see MapboxMap#setOnMapLongClickListener(OnMapLongClickListener)
- */
- public interface OnMapLongClickListener {
- /**
- * Called when the user long clicks on the map view.
- *
- * @param point The projected map coordinate the user long clicked on.
- */
- void onMapLongClick(@NonNull LatLng point);
- }
-
- /**
- * Interface definition for a callback to be invoked when the user clicks on a marker.
- *
- * @see MapboxMap#setOnMarkerClickListener(OnMarkerClickListener)
- */
- public interface OnMarkerClickListener {
- /**
- * Called when the user clicks on a marker.
- *
- * @param marker The marker the user clicked on.
- * @return If true the listener has consumed the event and the info window will not be shown.
- */
- boolean onMarkerClick(@NonNull Marker marker);
- }
-
- /**
- * Interface definition for a callback to be invoked when the user clicks on an info window.
- *
- * @see MapboxMap#setOnInfoWindowClickListener(OnInfoWindowClickListener)
- */
- public interface OnInfoWindowClickListener {
- /**
- * Called when the user clicks on an info window.
- *
- * @param marker The marker of the info window the user clicked on.
- * @return If true the listener has consumed the event and the info window will not be closed.
- */
- boolean onInfoWindowClick(@NonNull Marker marker);
- }
-
- /**
- * Interface definition for a callback to be invoked when the user long presses on a marker's info window.
- *
- * @see MapboxMap#setOnInfoWindowClickListener(OnInfoWindowClickListener)
- */
- public interface OnInfoWindowLongClickListener {
-
- /**
- * Called when the user makes a long-press gesture on the marker's info window.
- *
- * @param marker The marker were the info window is attached to
- */
- void onInfoWindowLongClick(Marker marker);
- }
-
- /**
- * Interface definition for a callback to be invoked when a marker's info window is closed.
- *
- * @see MapboxMap#setOnInfoWindowCloseListener(OnInfoWindowCloseListener)
- */
- public interface OnInfoWindowCloseListener {
-
- /**
- * Called when the marker's info window is closed.
- *
- * @param marker The marker of the info window that was closed.
- */
- void onInfoWindowClose(Marker marker);
- }
-
- /**
- * Interface definition for a callback to be invoked when an info window will be shown.
- *
- * @see MapboxMap#setInfoWindowAdapter(InfoWindowAdapter)
- */
- public interface InfoWindowAdapter {
- /**
- * Called when an info window will be shown as a result of a marker click.
- *
- * @param marker The marker the user clicked on.
- * @return View to be shown as a info window. If null is returned the default
- * info window will be shown.
- */
- @Nullable
- View getInfoWindow(@NonNull Marker marker);
- }
-
- /**
- * Interface definition for a callback to be invoked when an MarkerView will be shown.
- *
- * @param <U> the instance type of MarkerView
- */
- public abstract static class MarkerViewAdapter<U extends MarkerView> {
-
- private Context context;
- private final Class<U> persistentClass;
- private final Pools.SimplePool<View> viewReusePool;
-
- /**
- * Create an instance of MarkerViewAdapter.
- *
- * @param context the context associated to a MapView
- */
- @SuppressWarnings("unchecked")
- public MarkerViewAdapter(Context context) {
- this.context = context;
- persistentClass = (Class<U>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
- viewReusePool = new Pools.SimplePool<>(10000);
- }
-
- /**
- * Called when an MarkerView will be added to the MapView.
- *
- * @param marker the model representing the MarkerView
- * @param convertView the reusable view
- * @param parent the parent ViewGroup of the convertview
- * @return the View that is adapted to the contents of MarkerView
- */
- @Nullable
- 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.
- * <p>
- * This method should be used to reset an animated view back to it's original state for view reuse.
- * </p>
- * <p>
- * Returning true indicates you want to the view reuse to be handled automatically.
- * Returning false indicates you want to perform an animation and you are required calling {@link #releaseView(View)} yourself.
- * </p>
- *
- * @param marker the model representing the MarkerView
- * @param convertView the reusable view
- * @return true if you want reuse to occur automatically, false if you want to manage this yourself.
- */
- public boolean prepareViewForReuse(@NonNull MarkerView marker, @NonNull View convertView) {
- return true;
- }
-
- /**
- * Called when a MarkerView is selected from the MapView.
- * <p>
- * Returning true from this method indicates you want to move the MarkerView to the selected state.
- * Returning false indicates you want to animate the View first an manually select the MarkerView when appropriate.
- * </p>
- *
- * @param marker the model representing the MarkerView
- * @param convertView the reusable view
- * @param reselectionFromRecycling indicates if the onSelect callback is the initial selection
- * callback or that selection occurs due to recreation of selected marker
- * @return true if you want to select the Marker immediately, false if you want to manage this yourself.
- */
- public boolean onSelect(@NonNull U marker, @NonNull View convertView, boolean reselectionFromRecycling) {
- return true;
- }
-
- /**
- * Called when a MarkerView is deselected from the MapView.
- *
- * @param marker the model representing the MarkerView
- * @param convertView the reusable view
- */
- public void onDeselect(@NonNull U marker, @NonNull View convertView) {
- }
-
- /**
- * Returns the generic type of the used MarkerView.
- *
- * @return the generic type
- */
- public final Class<U> getMarkerClass() {
- return persistentClass;
- }
-
- /**
- * Returns the pool used to store reusable Views.
- *
- * @return the pool associated to this adapter
- */
- public final Pools.SimplePool<View> getViewReusePool() {
- return viewReusePool;
- }
-
- /**
- * Returns the context associated to the hosting MapView.
- *
- * @return the context used
- */
- public final Context getContext() {
- return context;
- }
-
- /**
- * Release a View to the ViewPool.
- *
- * @param view the view to be released
- */
- public final void releaseView(View view) {
- view.setVisibility(View.GONE);
- viewReusePool.release(view);
- }
- }
-
- /**
- * Interface definition for a callback to be invoked when the user clicks on a MarkerView.
- */
- public interface OnMarkerViewClickListener {
-
- /**
- * Called when the user clicks on a MarkerView.
- *
- * @param marker the MarkerView associated to the clicked View
- * @param view the clicked View
- * @param adapter the adapter used to adapt the MarkerView to the View
- * @return If true the listener has consumed the event and the info window will not be shown
- */
- boolean onMarkerClick(@NonNull Marker marker, @NonNull View view, @NonNull MarkerViewAdapter adapter);
- }
-
- /**
- * Interface definition for a callback to be invoked when the the My Location view changes location.
- *
- * @see MapboxMap#setOnMyLocationChangeListener(OnMyLocationChangeListener)
- */
- public interface OnMyLocationChangeListener {
- /**
- * Called when the location of the My Location view has changed
- * (be it latitude/longitude, bearing or accuracy).
- *
- * @param location The current location of the My Location view The type of map change event.
- */
- void onMyLocationChange(@Nullable Location location);
- }
-
- /**
- * Interface definition for a callback to be invoked when the the My Location tracking mode changes.
- *
- * @see MapView#setMyLocationTrackingMode(int)
- */
- public interface OnMyLocationTrackingModeChangeListener {
-
- /**
- * Called when the tracking mode of My Location tracking has changed
- *
- * @param myLocationTrackingMode the current active location tracking mode
- */
- void onMyLocationTrackingModeChange(@MyLocationTracking.Mode int myLocationTrackingMode);
- }
-
- /**
- * Interface definition for a callback to be invoked when the the My Location tracking mode changes.
- *
- * @see MapView#setMyLocationTrackingMode(int)
- */
- public interface OnMyBearingTrackingModeChangeListener {
-
- /**
- * Called when the tracking mode of My Bearing tracking has changed
- *
- * @param myBearingTrackingMode the current active bearing tracking mode
- */
- void onMyBearingTrackingModeChange(@MyBearingTracking.Mode int myBearingTrackingMode);
- }
-
- /**
- * Interface definition for a callback to be invoked when a task is complete or cancelled.
- */
- public interface CancelableCallback {
- /**
- * Invoked when a task is cancelled.
- */
- void onCancel();
-
- /**
- * Invoked when a task is complete.
- */
- void onFinish();
- }
-
- /**
- * Interface definition for a callback to be invoked when the snapshot has been taken.
- */
- public interface SnapshotReadyCallback {
- /**
- * Invoked when the snapshot has been taken.
- *
- * @param snapshot the snapshot bitmap
- */
- void onSnapshotReady(Bitmap snapshot);
- }
-
- private class MapChangeCameraPositionListener implements MapView.OnMapChangedListener {
-
- private static final long UPDATE_RATE_MS = 400;
- private long previousUpdateTimestamp = 0;
-
- @Override
- public void onMapChanged(@MapView.MapChange int change) {
- if (change >= MapView.REGION_WILL_CHANGE && change <= MapView.REGION_DID_CHANGE_ANIMATED) {
- invalidCameraPosition = true;
- long currentTime = SystemClock.elapsedRealtime();
- if (currentTime < previousUpdateTimestamp) {
- return;
- }
- invalidateCameraPosition();
- previousUpdateTimestamp = currentTime + UPDATE_RATE_MS;
- }
- }
- }
+ //
+ // Used for instrumentation testing
+ //
+ Transform getTransform() {
+ return transform;
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java
index a54d246913..518ef47329 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java
@@ -34,1051 +34,1131 @@ import java.util.Arrays;
*/
public class MapboxMapOptions implements Parcelable {
- private static final float DIMENSION_SEVEN_DP = 7f;
- private static final float DIMENSION_TEN_DP = 10f;
- private static final float DIMENSION_SIXTEEN_DP = 16f;
- private static final float DIMENSION_SEVENTY_SIX_DP = 76f;
-
- private CameraPosition cameraPosition;
-
- private boolean debugActive;
-
- private boolean compassEnabled = true;
- private boolean fadeCompassFacingNorth = true;
- private int compassGravity = Gravity.TOP | Gravity.END;
- private int[] compassMargins;
-
- private boolean logoEnabled = true;
- private int logoGravity = Gravity.BOTTOM | Gravity.START;
- private int[] logoMargins;
-
- @ColorInt
- private int attributionTintColor = -1;
- private boolean attributionEnabled = true;
- private int attributionGravity = Gravity.BOTTOM;
- private int[] attributionMargins;
-
- private float minZoom = MapboxConstants.MINIMUM_ZOOM;
- private float maxZoom = MapboxConstants.MAXIMUM_ZOOM;
-
- private boolean rotateGesturesEnabled = true;
- private boolean scrollGesturesEnabled = true;
- private boolean tiltGesturesEnabled = true;
- private boolean zoomGesturesEnabled = true;
- private boolean zoomControlsEnabled = false;
-
- private boolean myLocationEnabled;
- private Drawable myLocationForegroundDrawable;
- private Drawable myLocationForegroundBearingDrawable;
- private Drawable myLocationBackgroundDrawable;
- private int myLocationForegroundTintColor;
- private int myLocationBackgroundTintColor;
- private int[] myLocationBackgroundPadding;
- private int myLocationAccuracyTintColor;
- private int myLocationAccuracyAlpha;
-
- private String apiBaseUrl;
-
- @Deprecated
- private boolean textureMode;
-
- private String style;
- @Deprecated
- private String accessToken;
-
- /**
- * Creates a new MapboxMapOptions object.
- */
- public MapboxMapOptions() {
- }
-
- private MapboxMapOptions(Parcel in) {
- cameraPosition = in.readParcelable(CameraPosition.class.getClassLoader());
- debugActive = in.readByte() != 0;
-
- compassEnabled = in.readByte() != 0;
- compassGravity = in.readInt();
- compassMargins = in.createIntArray();
- fadeCompassFacingNorth = in.readByte() != 0;
-
- logoEnabled = in.readByte() != 0;
- logoGravity = in.readInt();
- logoMargins = in.createIntArray();
-
- attributionEnabled = in.readByte() != 0;
- attributionGravity = in.readInt();
- attributionMargins = in.createIntArray();
- attributionTintColor = in.readInt();
-
- minZoom = in.readFloat();
- maxZoom = in.readFloat();
-
- rotateGesturesEnabled = in.readByte() != 0;
- scrollGesturesEnabled = in.readByte() != 0;
- tiltGesturesEnabled = in.readByte() != 0;
- zoomControlsEnabled = in.readByte() != 0;
- zoomGesturesEnabled = in.readByte() != 0;
-
- myLocationEnabled = in.readByte() != 0;
-
- Bitmap foregroundBitmap = in.readParcelable(getClass().getClassLoader());
- if (foregroundBitmap != null) {
- myLocationForegroundDrawable = new BitmapDrawable(foregroundBitmap);
- }
-
- Bitmap foregroundBearingBitmap = in.readParcelable(getClass().getClassLoader());
- if (foregroundBearingBitmap != null) {
- myLocationForegroundBearingDrawable = new BitmapDrawable(foregroundBearingBitmap);
- }
-
- Bitmap backgroundBitmap = in.readParcelable(getClass().getClassLoader());
- if (backgroundBitmap != null) {
- myLocationBackgroundDrawable = new BitmapDrawable(backgroundBitmap);
- }
-
- myLocationForegroundTintColor = in.readInt();
- myLocationBackgroundTintColor = in.readInt();
- myLocationBackgroundPadding = in.createIntArray();
- myLocationAccuracyAlpha = in.readInt();
- myLocationAccuracyTintColor = in.readInt();
-
- style = in.readString();
- accessToken = in.readString();
- apiBaseUrl = in.readString();
- textureMode = in.readByte() != 0;
- }
-
- public static Bitmap getBitmapFromDrawable(Drawable drawable) {
- if (drawable instanceof BitmapDrawable) {
- return ((BitmapDrawable) drawable).getBitmap();
- } else {
- Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
- Canvas canvas = new Canvas(bitmap);
- drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
- drawable.draw(canvas);
- return bitmap;
- }
- }
-
- /**
- * Creates a MapboxMapsOptions from the attribute set.s
- *
- * @param context Context related to a map view.
- * @param attrs Attributeset containing configuration
- * @return the MapboxMapOptions created from attributes
- */
- public static MapboxMapOptions createFromAttributes(@NonNull Context context, @Nullable AttributeSet attrs) {
- MapboxMapOptions mapboxMapOptions = new MapboxMapOptions();
- float screenDensity = context.getResources().getDisplayMetrics().density;
- TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MapView, 0, 0);
- try {
- mapboxMapOptions.debugActive(typedArray.getBoolean(R.styleable.MapView_debug_active, false));
-
- mapboxMapOptions.camera(new CameraPosition.Builder(typedArray).build());
-
- mapboxMapOptions.accessToken(typedArray.getString(R.styleable.MapView_access_token));
- mapboxMapOptions.styleUrl(typedArray.getString(R.styleable.MapView_style_url));
- mapboxMapOptions.apiBaseUrl(typedArray.getString(R.styleable.MapView_api_base_url));
-
- mapboxMapOptions.zoomGesturesEnabled(typedArray.getBoolean(R.styleable.MapView_zoom_enabled, true));
- mapboxMapOptions.scrollGesturesEnabled(typedArray.getBoolean(R.styleable.MapView_scroll_enabled, true));
- mapboxMapOptions.rotateGesturesEnabled(typedArray.getBoolean(R.styleable.MapView_rotate_enabled, true));
- mapboxMapOptions.tiltGesturesEnabled(typedArray.getBoolean(R.styleable.MapView_tilt_enabled, true));
- mapboxMapOptions.zoomControlsEnabled(typedArray.getBoolean(R.styleable.MapView_zoom_controls_enabled, false));
-
- mapboxMapOptions.maxZoom(typedArray.getFloat(R.styleable.MapView_zoom_max, MapboxConstants.MAXIMUM_ZOOM));
- mapboxMapOptions.minZoom(typedArray.getFloat(R.styleable.MapView_zoom_min, MapboxConstants.MINIMUM_ZOOM));
-
- mapboxMapOptions.compassEnabled(typedArray.getBoolean(R.styleable.MapView_compass_enabled, true));
- mapboxMapOptions.compassGravity(typedArray.getInt(R.styleable.MapView_compass_gravity, Gravity.TOP | Gravity.END));
- mapboxMapOptions.compassMargins(new int[]{(int) (typedArray.getDimension(R.styleable.MapView_compass_margin_left, DIMENSION_TEN_DP) * screenDensity)
- , ((int) typedArray.getDimension(R.styleable.MapView_compass_margin_top, DIMENSION_TEN_DP * screenDensity))
- , ((int) typedArray.getDimension(R.styleable.MapView_compass_margin_right, DIMENSION_TEN_DP * screenDensity))
- , ((int) typedArray.getDimension(R.styleable.MapView_compass_margin_bottom, DIMENSION_TEN_DP * screenDensity))});
- mapboxMapOptions.compassFadesWhenFacingNorth(typedArray.getBoolean(R.styleable.MapView_compass_fade_facing_north, true));
-
- mapboxMapOptions.logoEnabled(typedArray.getBoolean(R.styleable.MapView_logo_enabled, true));
- mapboxMapOptions.logoGravity(typedArray.getInt(R.styleable.MapView_logo_gravity, Gravity.BOTTOM | Gravity.START));
- mapboxMapOptions.logoMargins(new int[]{(int) (typedArray.getDimension(R.styleable.MapView_logo_margin_left, DIMENSION_SIXTEEN_DP) * screenDensity)
- , (int) (typedArray.getDimension(R.styleable.MapView_logo_margin_top, DIMENSION_SIXTEEN_DP) * screenDensity)
- , (int) (typedArray.getDimension(R.styleable.MapView_logo_margin_right, DIMENSION_SIXTEEN_DP) * screenDensity)
- , (int) (typedArray.getDimension(R.styleable.MapView_logo_margin_bottom, DIMENSION_SIXTEEN_DP) * screenDensity)});
-
- mapboxMapOptions.attributionTintColor(typedArray.getColor(R.styleable.MapView_attribution_tint, -1));
- mapboxMapOptions.attributionEnabled(typedArray.getBoolean(R.styleable.MapView_attribution_enabled, true));
- mapboxMapOptions.attributionGravity(typedArray.getInt(R.styleable.MapView_attribution_gravity, Gravity.BOTTOM));
- mapboxMapOptions.attributionMargins(new int[]{(int) (typedArray.getDimension(R.styleable.MapView_attribution_margin_left, DIMENSION_SEVENTY_SIX_DP) * screenDensity)
- , (int) (typedArray.getDimension(R.styleable.MapView_attribution_margin_top, DIMENSION_SEVEN_DP) * screenDensity)
- , (int) (typedArray.getDimension(R.styleable.MapView_attribution_margin_right, DIMENSION_SEVEN_DP) * screenDensity)
- , (int) (typedArray.getDimension(R.styleable.MapView_attribution_margin_bottom, DIMENSION_SEVEN_DP) * screenDensity)});
-
- mapboxMapOptions.locationEnabled(typedArray.getBoolean(R.styleable.MapView_my_location_enabled, false));
- mapboxMapOptions.myLocationForegroundTintColor(typedArray.getColor(R.styleable.MapView_my_location_foreground_tint, Color.TRANSPARENT));
- mapboxMapOptions.myLocationBackgroundTintColor(typedArray.getColor(R.styleable.MapView_my_location_background_tint, Color.TRANSPARENT));
-
- Drawable foregroundDrawable = typedArray.getDrawable(R.styleable.MapView_my_location_foreground);
- if (foregroundDrawable == null) {
- foregroundDrawable = ContextCompat.getDrawable(context, R.drawable.ic_mylocationview_normal);
- }
-
- Drawable foregroundBearingDrawable = typedArray.getDrawable(R.styleable.MapView_my_location_foreground_bearing);
- if (foregroundBearingDrawable == null) {
- foregroundBearingDrawable = ContextCompat.getDrawable(context, R.drawable.ic_mylocationview_bearing);
- }
-
- Drawable backgroundDrawable = typedArray.getDrawable(R.styleable.MapView_my_location_background);
- if (backgroundDrawable == null) {
- backgroundDrawable = ContextCompat.getDrawable(context, R.drawable.ic_mylocationview_background);
- }
-
- mapboxMapOptions.myLocationForegroundDrawables(foregroundDrawable, foregroundBearingDrawable);
- mapboxMapOptions.myLocationBackgroundDrawable(backgroundDrawable);
- mapboxMapOptions.myLocationBackgroundPadding(new int[]{(int) (typedArray.getDimension(R.styleable.MapView_my_location_background_left, 0) * screenDensity)
- , (int) (typedArray.getDimension(R.styleable.MapView_my_location_background_top, 0) * screenDensity)
- , (int) (typedArray.getDimension(R.styleable.MapView_my_location_background_right, 0) * screenDensity)
- , (int) (typedArray.getDimension(R.styleable.MapView_my_location_background_bottom, 0) * screenDensity)});
- mapboxMapOptions.myLocationAccuracyAlpha(typedArray.getInt(R.styleable.MapView_my_location_accuracy_alpha, 100));
- mapboxMapOptions.myLocationAccuracyTint(typedArray.getColor(R.styleable.MapView_my_location_accuracy_tint, ColorUtils.getPrimaryColor(context)));
- mapboxMapOptions.textureMode(typedArray.getBoolean(R.styleable.MapView_texture_mode, false));
- } finally {
- typedArray.recycle();
- }
- return mapboxMapOptions;
- }
-
- /**
- * Specifies the URL used for API endpoint.
- *
- * @param apiBaseUrl The base of our API endpoint
- * @return This
- */
- public MapboxMapOptions apiBaseUrl(String apiBaseUrl) {
- this.apiBaseUrl = apiBaseUrl;
- return this;
- }
-
- /**
- * Specifies a the initial camera position for the map view.
- *
- * @param cameraPosition Inital camera position
- * @return This
- */
- public MapboxMapOptions camera(CameraPosition cameraPosition) {
- this.cameraPosition = cameraPosition;
- return this;
- }
-
- /**
- * <p>
- * DEPRECATED @see MapboxAccountManager#start(String)
- * </p>
- * Specifies the accesstoken associated with a map view.
- *
- * @param accessToken Token to be used to access the service
- * @return This
- * @deprecated As of release 4.1.0, replaced by {@link com.mapbox.mapboxsdk.MapboxAccountManager#start(Context, String)}
- */
- @Deprecated
- public MapboxMapOptions accessToken(String accessToken) {
- this.accessToken = accessToken;
- return this;
- }
-
- /**
- * Specifies the style url associated with a map view.
- *
- * @param styleUrl Url to be used to load a style
- * @return This
- */
- public MapboxMapOptions styleUrl(String styleUrl) {
- style = styleUrl;
- return this;
- }
-
- /**
- * Specifies the used debug type for a map view.
- *
- * @param enabled True is debug is enabled
- * @return This
- */
- public MapboxMapOptions debugActive(boolean enabled) {
- debugActive = enabled;
- return this;
- }
-
- /**
- * Specifies the used minimum zoom level for a map view.
- *
- * @param minZoom Zoom level to be used
- * @return This
- */
- public MapboxMapOptions minZoom(float minZoom) {
- this.minZoom = minZoom;
- return this;
- }
-
- /**
- * Specifies the used maximum zoom level for a map view.
- *
- * @param maxZoom Zoom level to be used
- * @return This
- */
- public MapboxMapOptions maxZoom(float maxZoom) {
- this.maxZoom = maxZoom;
- return this;
- }
-
- /**
- * Specifies the visibility state of a compass for a map view.
- *
- * @param enabled True and compass is shown
- * @return This
- */
- public MapboxMapOptions compassEnabled(boolean enabled) {
- compassEnabled = enabled;
- return this;
- }
-
- /**
- * Specifies the gravity state of compass for a map view.
- *
- * @param gravity see {@link android.view.Gravity}
- * @return This
- */
- public MapboxMapOptions compassGravity(int gravity) {
- compassGravity = gravity;
- return this;
- }
-
- /**
- * Specifies the margin state of compass for a map view
- *
- * @param margins 4 long array for LTRB margins
- * @return This
- */
- public MapboxMapOptions compassMargins(int[] margins) {
- compassMargins = margins;
- return this;
- }
-
- /**
- * Specifies if the compass fades to invisible when facing north.
- * <p>
- * By default this value is true.
- * </p>
- *
- * @param compassFadeWhenFacingNorth true is compass fades to invisble
- * @return This
- */
- public MapboxMapOptions compassFadesWhenFacingNorth(boolean compassFadeWhenFacingNorth) {
- this.fadeCompassFacingNorth = compassFadeWhenFacingNorth;
- return this;
- }
-
- /**
- * Specifies the visibility state of a logo for a map view.
- *
- * @param enabled True and logo is shown
- * @return This
- */
- public MapboxMapOptions logoEnabled(boolean enabled) {
- logoEnabled = enabled;
- return this;
- }
-
- /**
- * Specifies the gravity state of logo for a map view.
- *
- * @param gravity see {@link android.view.Gravity}
- * @return This
- */
- public MapboxMapOptions logoGravity(int gravity) {
- logoGravity = gravity;
- return this;
- }
+ private static final float DIMENSION_SEVEN_DP = 7f;
+ private static final float DIMENSION_TEN_DP = 10f;
+ private static final float DIMENSION_SIXTEEN_DP = 16f;
+ private static final float DIMENSION_SEVENTY_SIX_DP = 76f;
- /**
- * Specifies the margin state of logo for a map view
- *
- * @param margins 4 long array for LTRB margins
- * @return This
- */
- public MapboxMapOptions logoMargins(int[] margins) {
- logoMargins = margins;
- return this;
- }
+ private CameraPosition cameraPosition;
- /**
- * Specifies the visibility state of a attribution for a map view.
- *
- * @param enabled True and attribution is shown
- * @return This
- */
- public MapboxMapOptions attributionEnabled(boolean enabled) {
- attributionEnabled = enabled;
- return this;
- }
+ private boolean debugActive;
- /**
- * Specifies the gravity state of attribution for a map view.
- *
- * @param gravity see {@link android.view.Gravity}
- * @return This
- */
- public MapboxMapOptions attributionGravity(int gravity) {
- attributionGravity = gravity;
- return this;
- }
+ private boolean compassEnabled = true;
+ private boolean fadeCompassFacingNorth = true;
+ private int compassGravity = Gravity.TOP | Gravity.END;
+ private int[] compassMargins;
- /**
- * Specifies the margin state of attribution for a map view
- *
- * @param margins 4 long array for LTRB margins
- * @return This
- */
- public MapboxMapOptions attributionMargins(int[] margins) {
- attributionMargins = margins;
- return this;
- }
+ private boolean logoEnabled = true;
+ private int logoGravity = Gravity.BOTTOM | Gravity.START;
+ private int[] logoMargins;
+
+ @ColorInt
+ private int attributionTintColor = -1;
+ private boolean attributionEnabled = true;
+ private int attributionGravity = Gravity.BOTTOM;
+ private int[] attributionMargins;
+
+ private double minZoom = MapboxConstants.MINIMUM_ZOOM;
+ private double maxZoom = MapboxConstants.MAXIMUM_ZOOM;
+
+ private boolean rotateGesturesEnabled = true;
+ private boolean scrollGesturesEnabled = true;
+ private boolean tiltGesturesEnabled = true;
+ private boolean zoomGesturesEnabled = true;
+ private boolean zoomControlsEnabled = false;
+
+ private boolean myLocationEnabled;
+ private Drawable myLocationForegroundDrawable;
+ private Drawable myLocationForegroundBearingDrawable;
+ private Drawable myLocationBackgroundDrawable;
+ private int myLocationForegroundTintColor;
+ private int myLocationBackgroundTintColor;
+ private int[] myLocationBackgroundPadding;
+ private int myLocationAccuracyTintColor;
+ private int myLocationAccuracyAlpha;
+
+ private String apiBaseUrl;
+
+ @Deprecated
+ private boolean textureMode;
+
+ private String style;
+
+ /**
+ * Creates a new MapboxMapOptions object.
+ */
+ public MapboxMapOptions() {
+ }
+
+ private MapboxMapOptions(Parcel in) {
+ cameraPosition = in.readParcelable(CameraPosition.class.getClassLoader());
+ debugActive = in.readByte() != 0;
+
+ compassEnabled = in.readByte() != 0;
+ compassGravity = in.readInt();
+ compassMargins = in.createIntArray();
+ fadeCompassFacingNorth = in.readByte() != 0;
+
+ logoEnabled = in.readByte() != 0;
+ logoGravity = in.readInt();
+ logoMargins = in.createIntArray();
+
+ attributionEnabled = in.readByte() != 0;
+ attributionGravity = in.readInt();
+ attributionMargins = in.createIntArray();
+ attributionTintColor = in.readInt();
+
+ minZoom = in.readDouble();
+ maxZoom = in.readDouble();
+
+ rotateGesturesEnabled = in.readByte() != 0;
+ scrollGesturesEnabled = in.readByte() != 0;
+ tiltGesturesEnabled = in.readByte() != 0;
+ zoomControlsEnabled = in.readByte() != 0;
+ zoomGesturesEnabled = in.readByte() != 0;
+
+ myLocationEnabled = in.readByte() != 0;
+
+ Bitmap foregroundBitmap = in.readParcelable(getClass().getClassLoader());
+ if (foregroundBitmap != null) {
+ myLocationForegroundDrawable = new BitmapDrawable(foregroundBitmap);
+ }
+
+ Bitmap foregroundBearingBitmap = in.readParcelable(getClass().getClassLoader());
+ if (foregroundBearingBitmap != null) {
+ myLocationForegroundBearingDrawable = new BitmapDrawable(foregroundBearingBitmap);
+ }
+
+ Bitmap backgroundBitmap = in.readParcelable(getClass().getClassLoader());
+ if (backgroundBitmap != null) {
+ myLocationBackgroundDrawable = new BitmapDrawable(backgroundBitmap);
+ }
+
+ myLocationForegroundTintColor = in.readInt();
+ myLocationBackgroundTintColor = in.readInt();
+ myLocationBackgroundPadding = in.createIntArray();
+ myLocationAccuracyAlpha = in.readInt();
+ myLocationAccuracyTintColor = in.readInt();
+
+ style = in.readString();
+ apiBaseUrl = in.readString();
+ textureMode = in.readByte() != 0;
+ }
+
+ public static Bitmap getBitmapFromDrawable(Drawable drawable) {
+ if (drawable instanceof BitmapDrawable) {
+ return ((BitmapDrawable) drawable).getBitmap();
+ } else {
+ Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(),
+ Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(bitmap);
+ drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
+ drawable.draw(canvas);
+ return bitmap;
+ }
+ }
+
+ /**
+ * Creates a MapboxMapsOptions from the attribute set.s
+ *
+ * @param context Context related to a map view.
+ * @param attrs Attributeset containing configuration
+ * @return the MapboxMapOptions created from attributes
+ */
+ public static MapboxMapOptions createFromAttributes(@NonNull Context context, @Nullable AttributeSet attrs) {
+ MapboxMapOptions mapboxMapOptions = new MapboxMapOptions();
+ float pxlRatio = context.getResources().getDisplayMetrics().density;
+ TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.mapbox_MapView, 0, 0);
+ try {
+ mapboxMapOptions.camera(new CameraPosition.Builder(typedArray).build());
+ mapboxMapOptions.styleUrl(typedArray.getString(R.styleable.mapbox_MapView_mapbox_styleUrl));
+ mapboxMapOptions.apiBaseUrl(typedArray.getString(R.styleable.mapbox_MapView_mapbox_apiBaseUrl));
+
+ mapboxMapOptions.zoomGesturesEnabled(
+ typedArray.getBoolean(R.styleable.mapbox_MapView_mapbox_uiZoomGestures, true));
+ mapboxMapOptions.scrollGesturesEnabled(
+ typedArray.getBoolean(R.styleable.mapbox_MapView_mapbox_uiScrollGestures, true));
+ mapboxMapOptions.rotateGesturesEnabled(
+ typedArray.getBoolean(R.styleable.mapbox_MapView_mapbox_uiRotateGestures, true));
+ mapboxMapOptions.tiltGesturesEnabled(
+ typedArray.getBoolean(R.styleable.mapbox_MapView_mapbox_uiTiltGestures, true));
+ mapboxMapOptions.zoomControlsEnabled(
+ typedArray.getBoolean(R.styleable.mapbox_MapView_mapbox_uiZoomControls, false));
+
+ mapboxMapOptions.maxZoomPreference(typedArray.getFloat(R.styleable.mapbox_MapView_mapbox_cameraZoomMax,
+ MapboxConstants.MAXIMUM_ZOOM));
+ mapboxMapOptions.minZoomPreference(typedArray.getFloat(R.styleable.mapbox_MapView_mapbox_cameraZoomMin,
+ MapboxConstants.MINIMUM_ZOOM));
+
+ mapboxMapOptions.compassEnabled(typedArray.getBoolean(R.styleable.mapbox_MapView_mapbox_uiCompass, true));
+ mapboxMapOptions.compassGravity(typedArray.getInt(R.styleable.mapbox_MapView_mapbox_uiCompassGravity,
+ Gravity.TOP | Gravity.END));
+ mapboxMapOptions.compassMargins(new int[] {
+ (int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiCompassMarginLeft,
+ DIMENSION_TEN_DP * pxlRatio)),
+ ((int) typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiCompassMarginTop,
+ DIMENSION_TEN_DP * pxlRatio)),
+ ((int) typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiCompassMarginRight,
+ DIMENSION_TEN_DP * pxlRatio)),
+ ((int) typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiCompassMarginBottom,
+ DIMENSION_TEN_DP * pxlRatio))});
+ mapboxMapOptions.compassFadesWhenFacingNorth(typedArray.getBoolean(
+ R.styleable.mapbox_MapView_mapbox_uiCompassFadeFacingNorth, true));
+
+ mapboxMapOptions.logoEnabled(typedArray.getBoolean(R.styleable.mapbox_MapView_mapbox_uiLogo, true));
+ mapboxMapOptions.logoGravity(typedArray.getInt(R.styleable.mapbox_MapView_mapbox_uiLogoGravity,
+ Gravity.BOTTOM | Gravity.START));
+ mapboxMapOptions.logoMargins(new int[] {
+ (int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiLogoMarginLeft,
+ DIMENSION_SIXTEEN_DP * pxlRatio)),
+ (int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiLogoMarginTop,
+ DIMENSION_SIXTEEN_DP * pxlRatio)),
+ (int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiLogoMarginRight,
+ DIMENSION_SIXTEEN_DP * pxlRatio)),
+ (int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiLogoMarginBottom,
+ DIMENSION_SIXTEEN_DP * pxlRatio))});
+
+ mapboxMapOptions.attributionTintColor(typedArray.getColor(
+ R.styleable.mapbox_MapView_mapbox_uiAttributionTintColor, -1));
+ mapboxMapOptions.attributionEnabled(typedArray.getBoolean(
+ R.styleable.mapbox_MapView_mapbox_uiAttribution, true));
+ mapboxMapOptions.attributionGravity(typedArray.getInt(
+ R.styleable.mapbox_MapView_mapbox_uiAttributionGravity, Gravity.BOTTOM));
+ mapboxMapOptions.attributionMargins(new int[] {
+ (int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiAttributionMarginLeft,
+ DIMENSION_SEVENTY_SIX_DP) * pxlRatio),
+ (int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiAttributionMarginTop,
+ DIMENSION_SEVEN_DP * pxlRatio)),
+ (int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiAttributionMarginRight,
+ DIMENSION_SEVEN_DP * pxlRatio)),
+ (int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiAttributionMarginBottom,
+ DIMENSION_SEVEN_DP * pxlRatio))});
+
+ mapboxMapOptions.locationEnabled(typedArray.getBoolean(R.styleable.mapbox_MapView_mapbox_myLocation, false));
+ mapboxMapOptions.myLocationForegroundTintColor(
+ typedArray.getColor(R.styleable.mapbox_MapView_mapbox_myLocationTintColor,
+ ColorUtils.getPrimaryColor(context)));
+ mapboxMapOptions.myLocationBackgroundTintColor(
+ typedArray.getColor(R.styleable.mapbox_MapView_mapbox_myLocationBackgroundTintColor, Color.WHITE));
+
+ Drawable foregroundDrawable = typedArray.getDrawable(R.styleable.mapbox_MapView_mapbox_myLocationDrawable);
+ if (foregroundDrawable == null) {
+ foregroundDrawable = ContextCompat.getDrawable(context, R.drawable.mapbox_mylocation_icon_default);
+ }
+
+ Drawable foregroundBearingDrawable = typedArray.getDrawable(
+ R.styleable.mapbox_MapView_mapbox_myLocationBearingDrawable);
+ if (foregroundBearingDrawable == null) {
+ foregroundBearingDrawable = ContextCompat.getDrawable(context, R.drawable.mapbox_mylocation_icon_bearing);
+ }
+
+ Drawable backgroundDrawable = typedArray.getDrawable(
+ R.styleable.mapbox_MapView_mapbox_myLocationBackgroundDrawable);
+ if (backgroundDrawable == null) {
+ backgroundDrawable = ContextCompat.getDrawable(context, R.drawable.mapbox_mylocation_bg_shape);
+ }
+
+ mapboxMapOptions.myLocationForegroundDrawables(foregroundDrawable, foregroundBearingDrawable);
+ mapboxMapOptions.myLocationBackgroundDrawable(backgroundDrawable);
+ mapboxMapOptions.myLocationBackgroundPadding(new int[] {
+ (int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_myLocationBackgroundMarginLeft,
+ 0) * pxlRatio),
+ (int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_myLocationBackgroundMarginTop,
+ 0) * pxlRatio),
+ (int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_myLocationBackgroundMarginRight,
+ 0) * pxlRatio),
+ (int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_myLocationBackgroundMarginBottom,
+ 0) * pxlRatio)
+ });
+ mapboxMapOptions.myLocationAccuracyAlpha(
+ typedArray.getInt(R.styleable.mapbox_MapView_mapbox_myLocationAccuracyAlpha, 100));
+ mapboxMapOptions.myLocationAccuracyTint(
+ typedArray.getColor(R.styleable.mapbox_MapView_mapbox_myLocationAccuracyTintColor,
+ ColorUtils.getPrimaryColor(context)));
+ mapboxMapOptions.textureMode(
+ typedArray.getBoolean(R.styleable.mapbox_MapView_mapbox_renderTextureMode, false));
+ } finally {
+ typedArray.recycle();
+ }
+ return mapboxMapOptions;
+ }
+
+ /**
+ * Specifies the URL used for API endpoint.
+ *
+ * @param apiBaseUrl The base of our API endpoint
+ * @return This
+ */
+ public MapboxMapOptions apiBaseUrl(String apiBaseUrl) {
+ this.apiBaseUrl = apiBaseUrl;
+ return this;
+ }
+
+ /**
+ * Specifies a the initial camera position for the map view.
+ *
+ * @param cameraPosition Inital camera position
+ * @return This
+ */
+ public MapboxMapOptions camera(CameraPosition cameraPosition) {
+ this.cameraPosition = cameraPosition;
+ return this;
+ }
+
+ /**
+ * Specifies the style url associated with a map view.
+ *
+ * @param styleUrl Url to be used to load a style
+ * @return This
+ */
+ public MapboxMapOptions styleUrl(String styleUrl) {
+ style = styleUrl;
+ return this;
+ }
+
+ /**
+ * Specifies the used debug type for a map view.
+ *
+ * @param enabled True is debug is enabled
+ * @return This
+ */
+ public MapboxMapOptions debugActive(boolean enabled) {
+ debugActive = enabled;
+ return this;
+ }
+
+ /**
+ * Specifies the used minimum zoom level for a map view.
+ *
+ * @param minZoom Zoom level to be used
+ * @return This
+ */
+ public MapboxMapOptions minZoomPreference(double minZoom) {
+ this.minZoom = minZoom;
+ return this;
+ }
+
+ /**
+ * Specifies the used maximum zoom level for a map view.
+ *
+ * @param maxZoom Zoom level to be used
+ * @return This
+ */
+ public MapboxMapOptions maxZoomPreference(double maxZoom) {
+ this.maxZoom = maxZoom;
+ return this;
+ }
+
+ /**
+ * Specifies the visibility state of a mapbox_compass_icon for a map view.
+ *
+ * @param enabled True and mapbox_compass_icon is shown
+ * @return This
+ */
+ public MapboxMapOptions compassEnabled(boolean enabled) {
+ compassEnabled = enabled;
+ return this;
+ }
+
+ /**
+ * Specifies the gravity state of mapbox_compass_icon for a map view.
+ *
+ * @param gravity see {@link android.view.Gravity}
+ * @return This
+ */
+ public MapboxMapOptions compassGravity(int gravity) {
+ compassGravity = gravity;
+ return this;
+ }
+
+ /**
+ * Specifies the margin state of mapbox_compass_icon for a map view
+ *
+ * @param margins 4 long array for LTRB margins
+ * @return This
+ */
+ public MapboxMapOptions compassMargins(int[] margins) {
+ compassMargins = margins;
+ return this;
+ }
+
+ /**
+ * Specifies if the mapbox_compass_icon fades to invisible when facing north.
+ * <p>
+ * By default this value is true.
+ * </p>
+ *
+ * @param compassFadeWhenFacingNorth true is mapbox_compass_icon fades to invisble
+ * @return This
+ */
+ public MapboxMapOptions compassFadesWhenFacingNorth(boolean compassFadeWhenFacingNorth) {
+ this.fadeCompassFacingNorth = compassFadeWhenFacingNorth;
+ return this;
+ }
+
+ /**
+ * Specifies the visibility state of a logo for a map view.
+ *
+ * @param enabled True and logo is shown
+ * @return This
+ */
+ public MapboxMapOptions logoEnabled(boolean enabled) {
+ logoEnabled = enabled;
+ return this;
+ }
+
+ /**
+ * Specifies the gravity state of logo for a map view.
+ *
+ * @param gravity see {@link android.view.Gravity}
+ * @return This
+ */
+ public MapboxMapOptions logoGravity(int gravity) {
+ logoGravity = gravity;
+ return this;
+ }
+
+ /**
+ * Specifies the margin state of logo for a map view
+ *
+ * @param margins 4 long array for LTRB margins
+ * @return This
+ */
+ public MapboxMapOptions logoMargins(int[] margins) {
+ logoMargins = margins;
+ return this;
+ }
+
+ /**
+ * Specifies the visibility state of a attribution for a map view.
+ *
+ * @param enabled True and attribution is shown
+ * @return This
+ */
+ public MapboxMapOptions attributionEnabled(boolean enabled) {
+ attributionEnabled = enabled;
+ return this;
+ }
+
+ /**
+ * Specifies the gravity state of attribution for a map view.
+ *
+ * @param gravity see {@link android.view.Gravity}
+ * @return This
+ */
+ public MapboxMapOptions attributionGravity(int gravity) {
+ attributionGravity = gravity;
+ return this;
+ }
+
+ /**
+ * Specifies the margin state of attribution for a map view
+ *
+ * @param margins 4 long array for LTRB margins
+ * @return This
+ */
+ public MapboxMapOptions attributionMargins(int[] margins) {
+ attributionMargins = margins;
+ return this;
+ }
+
+ /**
+ * Specifies the tint color of the attribution for a map view
+ *
+ * @param color integer resembling a color
+ * @return This
+ */
+ public MapboxMapOptions attributionTintColor(@ColorInt int color) {
+ attributionTintColor = color;
+ return this;
+ }
+
+ /**
+ * Specifies if the rotate gesture is enabled for a map view.
+ *
+ * @param enabled True and gesture will be enabled
+ * @return This
+ */
+ public MapboxMapOptions rotateGesturesEnabled(boolean enabled) {
+ rotateGesturesEnabled = enabled;
+ return this;
+ }
+
+ /**
+ * Specifies if the scroll gesture is enabled for a map view.
+ *
+ * @param enabled True and gesture will be enabled
+ * @return This
+ */
+ public MapboxMapOptions scrollGesturesEnabled(boolean enabled) {
+ scrollGesturesEnabled = enabled;
+ return this;
+ }
+
+ /**
+ * Specifies if the tilt gesture is enabled for a map view.
+ *
+ * @param enabled True and gesture will be enabled
+ * @return This
+ */
+ public MapboxMapOptions tiltGesturesEnabled(boolean enabled) {
+ tiltGesturesEnabled = enabled;
+ return this;
+ }
+
+ /**
+ * Specifies if the zoom controls are enabled for a map view.
+ *
+ * @param enabled True and gesture will be enabled
+ * @return This
+ */
+ public MapboxMapOptions zoomControlsEnabled(boolean enabled) {
+ zoomControlsEnabled = enabled;
+ return this;
+ }
+
+ /**
+ * Specifies if the zoom gesture is enabled for a map view.
+ *
+ * @param enabled True and gesture will be enabled
+ * @return This
+ */
+ public MapboxMapOptions zoomGesturesEnabled(boolean enabled) {
+ zoomGesturesEnabled = enabled;
+ return this;
+ }
+
+ /**
+ * Specifies if the user location view is enabled for a map view.
+ *
+ * @param locationEnabled True and gesture will be enabled
+ * @return This
+ */
+ public MapboxMapOptions locationEnabled(boolean locationEnabled) {
+ this.myLocationEnabled = locationEnabled;
+ return this;
+ }
+
+ /**
+ * Set the foreground drawables of the MyLocationView.
+ *
+ * @param myLocationForegroundDrawable the drawable to show as foreground without bearing
+ * @param myLocationBearingDrawable the drawable to show as foreground when bearing is disabled
+ * @return This
+ */
+ public MapboxMapOptions myLocationForegroundDrawables(Drawable myLocationForegroundDrawable,
+ Drawable myLocationBearingDrawable) {
+ this.myLocationForegroundDrawable = myLocationForegroundDrawable;
+ this.myLocationForegroundBearingDrawable = myLocationBearingDrawable;
+ return this;
+ }
+
+ /**
+ * Set the foreground drawable of the MyLocationView.
+ * <p>
+ * The same drawable will be used for both bearing as non bearing modes.
+ * </p>
+ *
+ * @param myLocationForegroundDrawable the drawable to show as foreground
+ * @return This
+ */
+ public MapboxMapOptions myLocationForegroundDrawable(Drawable myLocationForegroundDrawable) {
+ this.myLocationForegroundDrawable = myLocationForegroundDrawable;
+ return this;
+ }
+
+ /**
+ * Set the background drawable of MyLocationView.
+ * <p>
+ * Padding can be added to provide an offset to the background.
+ * </p>
+ *
+ * @param myLocationBackgroundDrawable the drawable to show as background
+ * @return This
+ */
+ public MapboxMapOptions myLocationBackgroundDrawable(Drawable myLocationBackgroundDrawable) {
+ this.myLocationBackgroundDrawable = myLocationBackgroundDrawable;
+ return this;
+ }
+
+ /**
+ * Set the foreground tint color of MyLocationView.
+ * <p>
+ * The color will tint both the foreground and the bearing foreground drawable.
+ * </p>
+ *
+ * @param myLocationForegroundTintColor the color to tint the foreground drawable
+ * @return This
+ */
+ public MapboxMapOptions myLocationForegroundTintColor(@ColorInt int myLocationForegroundTintColor) {
+ this.myLocationForegroundTintColor = myLocationForegroundTintColor;
+ return this;
+ }
+
+ /**
+ * Set the background tint color of MyLocationView.
+ *
+ * @param myLocationBackgroundTintColor the color to tint the background
+ * @return This
+ */
+ public MapboxMapOptions myLocationBackgroundTintColor(@ColorInt int myLocationBackgroundTintColor) {
+ this.myLocationBackgroundTintColor = myLocationBackgroundTintColor;
+ return this;
+ }
+
+ /**
+ * Set the MyLocationView padding.
+ *
+ * @param myLocationBackgroundPadding the color to tint the background
+ * @return This
+ */
+ public MapboxMapOptions myLocationBackgroundPadding(int[] myLocationBackgroundPadding) {
+ this.myLocationBackgroundPadding = myLocationBackgroundPadding;
+ return this;
+ }
+
+ /**
+ * Set the MyLocationView accuracy circle tint color.
+ *
+ * @param myLocationAccuracyTintColor the color to tint the accuracy circle
+ * @return This
+ */
+ public MapboxMapOptions myLocationAccuracyTint(@ColorInt int myLocationAccuracyTintColor) {
+ this.myLocationAccuracyTintColor = myLocationAccuracyTintColor;
+ return this;
+ }
+
+ /**
+ * Set the MyLocationView accuracy alpha value.
+ *
+ * @param alpha the alpha value
+ * @return This
+ */
+ public MapboxMapOptions myLocationAccuracyAlpha(@IntRange(from = 0, to = 255) int alpha) {
+ this.myLocationAccuracyAlpha = alpha;
+ return this;
+ }
+
+ /**
+ * Enable TextureView as rendered surface.
+ * <p>
+ * Since the 4.2.0 release we replaced our TextureView with an SurfaceView implemenation.
+ * Enabling this option will use the deprecated TextureView instead.
+ * </p>
+ *
+ * @param textureMode True to enable texture mode
+ * @return This
+ * @deprecated As of the 4.2.0 release, using TextureView is deprecated.
+ */
+ public MapboxMapOptions textureMode(boolean textureMode) {
+ this.textureMode = textureMode;
+ return this;
+ }
+
+ /**
+ * Get the current configured API endpoint base URL.
+ *
+ * @return Base URL to be used API endpoint.
+ */
+ public String getApiBaseUrl() {
+ return apiBaseUrl;
+ }
+
+ /**
+ * Get the current configured initial camera position for a map view.
+ *
+ * @return CameraPosition to be initially used.
+ */
+ public CameraPosition getCamera() {
+ return cameraPosition;
+ }
+
+ /**
+ * Get the current configured min zoom for a map view.
+ *
+ * @return Mininum zoom level to be used.
+ */
+ public double getMinZoomPreference() {
+ return minZoom;
+ }
+
+ /**
+ * Get the current configured maximum zoom for a map view.
+ *
+ * @return Maximum zoom to be used.
+ */
+ public double getMaxZoomPreference() {
+ return maxZoom;
+ }
+
+ /**
+ * Get the current configured visibility state for mapbox_compass_icon for a map view.
+ *
+ * @return Visibility state of the mapbox_compass_icon
+ */
+ public boolean getCompassEnabled() {
+ return compassEnabled;
+ }
+
+ /**
+ * Get the current configured gravity state for mapbox_compass_icon for a map view.
+ *
+ * @return Gravity state of the mapbox_compass_icon
+ */
+ public int getCompassGravity() {
+ return compassGravity;
+ }
+
+ /**
+ * Get the current configured margins for mapbox_compass_icon for a map view.
+ *
+ * @return Margins state of the mapbox_compass_icon
+ */
+ public int[] getCompassMargins() {
+ return compassMargins;
+ }
+
+ /**
+ * Get the current configured state for fading the mapbox_compass_icon when facing north.
+ *
+ * @return True if mapbox_compass_icon fades to invisible when facing north
+ */
+ public boolean getCompassFadeFacingNorth() {
+ return fadeCompassFacingNorth;
+ }
+
+ /**
+ * Get the current configured visibility state for mapbox_compass_icon for a map view.
+ *
+ * @return Visibility state of the mapbox_compass_icon
+ */
+ public boolean getLogoEnabled() {
+ return logoEnabled;
+ }
+
+ /**
+ * Get the current configured gravity state for logo for a map view.
+ *
+ * @return Gravity state of the logo
+ */
+ public int getLogoGravity() {
+ return logoGravity;
+ }
+
+ /**
+ * Get the current configured margins for logo for a map view.
+ *
+ * @return Margins state of the logo
+ */
+ public int[] getLogoMargins() {
+ return logoMargins;
+ }
+
+ /**
+ * Get the current configured style url for a map view.
+ *
+ * @return Style url to be used.
+ */
+ public String getStyle() {
+ return style;
+ }
+
+ /**
+ * Get the current configured rotate gesture state for a map view.
+ *
+ * @return True indicates gesture is enabled
+ */
+ public boolean getRotateGesturesEnabled() {
+ return rotateGesturesEnabled;
+ }
+
+ /**
+ * Get the current configured scroll gesture state for a map view.
+ *
+ * @return True indicates gesture is enabled
+ */
+ public boolean getScrollGesturesEnabled() {
+ return scrollGesturesEnabled;
+ }
+
+ /**
+ * Get the current configured tilt gesture state for a map view.
+ *
+ * @return True indicates gesture is enabled
+ */
+ public boolean getTiltGesturesEnabled() {
+ return tiltGesturesEnabled;
+ }
+
+ /**
+ * Get the current configured zoom controls state for a map view.
+ *
+ * @return True indicates gesture is enabled
+ */
+ public boolean getZoomControlsEnabled() {
+ return zoomControlsEnabled;
+ }
+
+ /**
+ * Get the current configured zoom gesture state for a map view.
+ *
+ * @return True indicates gesture is enabled
+ */
+ public boolean getZoomGesturesEnabled() {
+ return zoomGesturesEnabled;
+ }
+
+ /**
+ * Get the current configured visibility state for attribution for a map view.
+ *
+ * @return Visibility state of the attribution
+ */
+ public boolean getAttributionEnabled() {
+ return attributionEnabled;
+ }
+
+ /**
+ * Get the current configured gravity state for attribution for a map view.
+ *
+ * @return Gravity state of the logo
+ */
+ public int getAttributionGravity() {
+ return attributionGravity;
+ }
+
+ /**
+ * Get the current configured margins for attribution for a map view.
+ *
+ * @return Margins state of the logo
+ */
+ public int[] getAttributionMargins() {
+ return attributionMargins;
+ }
+
+ /**
+ * Get the current configured tint color for attribution for a map view.
+ *
+ * @return the tint color
+ */
+ @ColorInt
+ public int getAttributionTintColor() {
+ return attributionTintColor;
+ }
+
+ /**
+ * Get the current configured user location view state for a map view.
+ *
+ * @return True and user location will be shown
+ */
+ public boolean getLocationEnabled() {
+ return myLocationEnabled;
+ }
+
+ /**
+ * Get the current configured MyLocationView foreground drawable.
+ *
+ * @return the drawable used as foreground
+ */
+ public Drawable getMyLocationForegroundDrawable() {
+ return myLocationForegroundDrawable;
+ }
+
+ /**
+ * Get the current configured MyLocationView foreground bearing drawable.
+ *
+ * @return the drawable used as foreground when bearing is enabled
+ */
+ public Drawable getMyLocationForegroundBearingDrawable() {
+ return myLocationForegroundBearingDrawable;
+ }
+
+ /**
+ * Get the current configured MyLocationView background drawable.
+ *
+ * @return the drawable used as background
+ */
+ public Drawable getMyLocationBackgroundDrawable() {
+ return myLocationBackgroundDrawable;
+ }
+
+ /**
+ * Get the current configured MyLocationView foreground tint color.
+ *
+ * @return the tint color
+ */
+ public int getMyLocationForegroundTintColor() {
+ return myLocationForegroundTintColor;
+ }
+
+ /**
+ * Get the current configured MyLocationView background tint color.
+ *
+ * @return the tint color
+ */
+ public int getMyLocationBackgroundTintColor() {
+ return myLocationBackgroundTintColor;
+ }
+
+ /**
+ * Get the current configured MyLocationView background padding.
+ *
+ * @return an array describing the padding in a LTRB manner
+ */
+ public int[] getMyLocationBackgroundPadding() {
+ return myLocationBackgroundPadding;
+ }
+
+ /**
+ * Get the current configured MyLocationView accuracy circle color tint value.
+ *
+ * @return the tint color
+ */
+ public int getMyLocationAccuracyTintColor() {
+ return myLocationAccuracyTintColor;
+ }
+
+ /**
+ * Get the current configured MyLocationView accuracy circle alpha value.
+ *
+ * @return the alpha value
+ */
+ public int getMyLocationAccuracyAlpha() {
+ return myLocationAccuracyAlpha;
+ }
+
+ /**
+ * Get the current configured debug state for a map view.
+ *
+ * @return True indicates debug is enabled.
+ */
+ public boolean getDebugActive() {
+ return debugActive;
+ }
+
+ /**
+ * Returns true if TextureView is being used a render view.
+ *
+ * @return True if TextureView is used.
+ * @deprecated As of the 4.2.0 release, using TextureView is deprecated.
+ */
+ public boolean getTextureMode() {
+ return textureMode;
+ }
+
+ public static final Parcelable.Creator<MapboxMapOptions> CREATOR = new Parcelable.Creator<MapboxMapOptions>() {
+ public MapboxMapOptions createFromParcel(Parcel in) {
+ return new MapboxMapOptions(in);
+ }
+
+ public MapboxMapOptions[] newArray(int size) {
+ return new MapboxMapOptions[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeParcelable(cameraPosition, flags);
+ dest.writeByte((byte) (debugActive ? 1 : 0));
+
+ dest.writeByte((byte) (compassEnabled ? 1 : 0));
+ dest.writeInt(compassGravity);
+ dest.writeIntArray(compassMargins);
+ dest.writeByte((byte) (fadeCompassFacingNorth ? 1 : 0));
+
+ dest.writeByte((byte) (logoEnabled ? 1 : 0));
+ dest.writeInt(logoGravity);
+ dest.writeIntArray(logoMargins);
+
+ dest.writeByte((byte) (attributionEnabled ? 1 : 0));
+ dest.writeInt(attributionGravity);
+ dest.writeIntArray(attributionMargins);
+ dest.writeInt(attributionTintColor);
+
+ dest.writeDouble(minZoom);
+ dest.writeDouble(maxZoom);
+
+ dest.writeByte((byte) (rotateGesturesEnabled ? 1 : 0));
+ dest.writeByte((byte) (scrollGesturesEnabled ? 1 : 0));
+ dest.writeByte((byte) (tiltGesturesEnabled ? 1 : 0));
+ dest.writeByte((byte) (zoomControlsEnabled ? 1 : 0));
+ dest.writeByte((byte) (zoomGesturesEnabled ? 1 : 0));
+
+ dest.writeByte((byte) (myLocationEnabled ? 1 : 0));
+
+ dest.writeParcelable(myLocationForegroundDrawable != null
+ ? getBitmapFromDrawable(myLocationForegroundDrawable) : null, flags);
+ dest.writeParcelable(myLocationForegroundBearingDrawable != null
+ ? getBitmapFromDrawable(myLocationForegroundBearingDrawable) : null, flags);
+ dest.writeParcelable(myLocationBackgroundDrawable != null
+ ? getBitmapFromDrawable(myLocationBackgroundDrawable) : null, flags);
+ dest.writeInt(myLocationForegroundTintColor);
+ dest.writeInt(myLocationBackgroundTintColor);
+ dest.writeIntArray(myLocationBackgroundPadding);
+ dest.writeInt(myLocationAccuracyAlpha);
+ dest.writeInt(myLocationAccuracyTintColor);
+
+ dest.writeString(style);
+ dest.writeString(apiBaseUrl);
+ dest.writeByte((byte) (textureMode ? 1 : 0));
+ }
- /**
- * Specifies the tint color of the attribution for a map view
- *
- * @param color integer resembling a color
- * @return This
- */
- public MapboxMapOptions attributionTintColor(@ColorInt int color) {
- attributionTintColor = color;
- return this;
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
}
-
- /**
- * Specifies if the rotate gesture is enabled for a map view.
- *
- * @param enabled True and gesture will be enabled
- * @return This
- */
- public MapboxMapOptions rotateGesturesEnabled(boolean enabled) {
- rotateGesturesEnabled = enabled;
- return this;
+ if (o == null || getClass() != o.getClass()) {
+ return false;
}
- /**
- * Specifies if the scroll gesture is enabled for a map view.
- *
- * @param enabled True and gesture will be enabled
- * @return This
- */
- public MapboxMapOptions scrollGesturesEnabled(boolean enabled) {
- scrollGesturesEnabled = enabled;
- return this;
- }
+ MapboxMapOptions options = (MapboxMapOptions) o;
- /**
- * Specifies if the tilt gesture is enabled for a map view.
- *
- * @param enabled True and gesture will be enabled
- * @return This
- */
- public MapboxMapOptions tiltGesturesEnabled(boolean enabled) {
- tiltGesturesEnabled = enabled;
- return this;
+ if (debugActive != options.debugActive) {
+ return false;
}
-
- /**
- * Specifies if the zoom controls are enabled for a map view.
- *
- * @param enabled True and gesture will be enabled
- * @return This
- */
- public MapboxMapOptions zoomControlsEnabled(boolean enabled) {
- zoomControlsEnabled = enabled;
- return this;
+ if (compassEnabled != options.compassEnabled) {
+ return false;
}
-
- /**
- * Specifies if the zoom gesture is enabled for a map view.
- *
- * @param enabled True and gesture will be enabled
- * @return This
- */
- public MapboxMapOptions zoomGesturesEnabled(boolean enabled) {
- zoomGesturesEnabled = enabled;
- return this;
+ if (fadeCompassFacingNorth != options.fadeCompassFacingNorth) {
+ return false;
}
-
- /**
- * Specifies if the user location view is enabled for a map view.
- *
- * @param locationEnabled True and gesture will be enabled
- * @return This
- */
- public MapboxMapOptions locationEnabled(boolean locationEnabled) {
- this.myLocationEnabled = locationEnabled;
- return this;
+ if (compassGravity != options.compassGravity) {
+ return false;
}
-
- /**
- * Set the foreground drawables of the MyLocationView.
- *
- * @param myLocationForegroundDrawable the drawable to show as foreground without bearing
- * @param myLocationBearingDrawable the drawable to show as foreground when bearing is disabled
- * @return This
- */
- public MapboxMapOptions myLocationForegroundDrawables(Drawable myLocationForegroundDrawable, Drawable myLocationBearingDrawable) {
- this.myLocationForegroundDrawable = myLocationForegroundDrawable;
- this.myLocationForegroundBearingDrawable = myLocationBearingDrawable;
- return this;
- }
-
- /**
- * Set the foreground drawable of the MyLocationView.
- * <p>
- * The same drawable will be used for both bearing as non bearing modes.
- * </p>
- *
- * @param myLocationForegroundDrawable the drawable to show as foreground
- * @return This
- */
- public MapboxMapOptions myLocationForegroundDrawable(Drawable myLocationForegroundDrawable) {
- this.myLocationForegroundDrawable = myLocationForegroundDrawable;
- return this;
+ if (logoEnabled != options.logoEnabled) {
+ return false;
}
-
- /**
- * Set the background drawable of MyLocationView.
- * <p>
- * Padding can be added to provide an offset to the background.
- * </p>
- *
- * @param myLocationBackgroundDrawable the drawable to show as background
- * @return This
- */
- public MapboxMapOptions myLocationBackgroundDrawable(Drawable myLocationBackgroundDrawable) {
- this.myLocationBackgroundDrawable = myLocationBackgroundDrawable;
- return this;
+ if (logoGravity != options.logoGravity) {
+ return false;
}
-
- /**
- * Set the foreground tint color of MyLocationView.
- * <p>
- * The color will tint both the foreground and the bearing foreground drawable.
- * </p>
- *
- * @param myLocationForegroundTintColor the color to tint the foreground drawable
- * @return This
- */
- public MapboxMapOptions myLocationForegroundTintColor(@ColorInt int myLocationForegroundTintColor) {
- this.myLocationForegroundTintColor = myLocationForegroundTintColor;
- return this;
+ if (attributionTintColor != options.attributionTintColor) {
+ return false;
}
-
- /**
- * Set the background tint color of MyLocationView.
- *
- * @param myLocationBackgroundTintColor the color to tint the background
- * @return This
- */
- public MapboxMapOptions myLocationBackgroundTintColor(@ColorInt int myLocationBackgroundTintColor) {
- this.myLocationBackgroundTintColor = myLocationBackgroundTintColor;
- return this;
+ if (attributionEnabled != options.attributionEnabled) {
+ return false;
}
-
- /**
- * Set the MyLocationView padding.
- *
- * @param myLocationBackgroundPadding the color to tint the background
- * @return This
- */
- public MapboxMapOptions myLocationBackgroundPadding(int[] myLocationBackgroundPadding) {
- this.myLocationBackgroundPadding = myLocationBackgroundPadding;
- return this;
+ if (attributionGravity != options.attributionGravity) {
+ return false;
}
-
- /**
- * Set the MyLocationView accuracy circle tint color.
- *
- * @param myLocationAccuracyTintColor the color to tint the accuracy circle
- * @return This
- */
- public MapboxMapOptions myLocationAccuracyTint(@ColorInt int myLocationAccuracyTintColor) {
- this.myLocationAccuracyTintColor = myLocationAccuracyTintColor;
- return this;
- }
-
- /**
- * Set the MyLocationView accuracy alpha value.
- *
- * @param alpha the alpha value
- * @return This
- */
- public MapboxMapOptions myLocationAccuracyAlpha(@IntRange(from = 0, to = 255) int alpha) {
- this.myLocationAccuracyAlpha = alpha;
- return this;
- }
-
- /**
- * Enable TextureView as rendered surface.
- * <p>
- * Since the 4.2.0 release we replaced our TextureView with an SurfaceView implemenation.
- * Enabling this option will use the deprecated TextureView instead.
- * </p>
- *
- * @param textureMode True to enable texture mode
- * @return This
- * @deprecated As of the 4.2.0 release, using TextureView is deprecated.
- */
- public MapboxMapOptions textureMode(boolean textureMode) {
- this.textureMode = textureMode;
- return this;
- }
-
- /**
- * Get the current configured API endpoint base URL.
- *
- * @return Base URL to be used API endpoint.
- */
- public String getApiBaseUrl() {
- return apiBaseUrl;
- }
-
- /**
- * Get the current configured initial camera position for a map view.
- *
- * @return CameraPosition to be initially used.
- */
- public CameraPosition getCamera() {
- return cameraPosition;
- }
-
- /**
- * Get the current configured min zoom for a map view.
- *
- * @return Mininum zoom level to be used.
- */
- public float getMinZoom() {
- return minZoom;
- }
-
- /**
- * Get the current configured maximum zoom for a map view.
- *
- * @return Maximum zoom to be used.
- */
- public float getMaxZoom() {
- return maxZoom;
- }
-
- /**
- * Get the current configured visibility state for compass for a map view.
- *
- * @return Visibility state of the compass
- */
- public boolean getCompassEnabled() {
- return compassEnabled;
- }
-
- /**
- * Get the current configured gravity state for compass for a map view.
- *
- * @return Gravity state of the compass
- */
- public int getCompassGravity() {
- return compassGravity;
- }
-
- /**
- * Get the current configured margins for compass for a map view.
- *
- * @return Margins state of the compass
- */
- public int[] getCompassMargins() {
- return compassMargins;
- }
-
- /**
- * Get the current configured state for fading the compass when facing north.
- *
- * @return True if compass fades to invisible when facing north
- */
- public boolean getCompassFadeFacingNorth() {
- return fadeCompassFacingNorth;
- }
-
- /**
- * Get the current configured visibility state for compass for a map view.
- *
- * @return Visibility state of the compass
- */
- public boolean getLogoEnabled() {
- return logoEnabled;
- }
-
- /**
- * Get the current configured gravity state for logo for a map view.
- *
- * @return Gravity state of the logo
- */
- public int getLogoGravity() {
- return logoGravity;
- }
-
- /**
- * Get the current configured margins for logo for a map view.
- *
- * @return Margins state of the logo
- */
- public int[] getLogoMargins() {
- return logoMargins;
- }
-
- /**
- * <p>
- * DEPRECATED @see MapboxAccountManager#start(String)
- * </p>
- * Get the current configured access token for a map view.
- *
- * @return Access token to be used.
- */
- @Deprecated
- public String getAccessToken() {
- return accessToken;
- }
-
- /**
- * Get the current configured style url for a map view.
- *
- * @return Style url to be used.
- */
- public String getStyle() {
- return style;
- }
-
- /**
- * Get the current configured rotate gesture state for a map view.
- *
- * @return True indicates gesture is enabled
- */
- public boolean getRotateGesturesEnabled() {
- return rotateGesturesEnabled;
- }
-
- /**
- * Get the current configured scroll gesture state for a map view.
- *
- * @return True indicates gesture is enabled
- */
- public boolean getScrollGesturesEnabled() {
- return scrollGesturesEnabled;
- }
-
- /**
- * Get the current configured tilt gesture state for a map view.
- *
- * @return True indicates gesture is enabled
- */
- public boolean getTiltGesturesEnabled() {
- return tiltGesturesEnabled;
- }
-
- /**
- * Get the current configured zoom controls state for a map view.
- *
- * @return True indicates gesture is enabled
- */
- public boolean getZoomControlsEnabled() {
- return zoomControlsEnabled;
- }
-
- /**
- * Get the current configured zoom gesture state for a map view.
- *
- * @return True indicates gesture is enabled
- */
- public boolean getZoomGesturesEnabled() {
- return zoomGesturesEnabled;
- }
-
- /**
- * Get the current configured visibility state for attribution for a map view.
- *
- * @return Visibility state of the attribution
- */
- public boolean getAttributionEnabled() {
- return attributionEnabled;
- }
-
- /**
- * Get the current configured gravity state for attribution for a map view.
- *
- * @return Gravity state of the logo
- */
- public int getAttributionGravity() {
- return attributionGravity;
- }
-
- /**
- * Get the current configured margins for attribution for a map view.
- *
- * @return Margins state of the logo
- */
- public int[] getAttributionMargins() {
- return attributionMargins;
- }
-
- /**
- * Get the current configured tint color for attribution for a map view.
- *
- * @return the tint color
- */
- @ColorInt
- public int getAttributionTintColor() {
- return attributionTintColor;
- }
-
- /**
- * Get the current configured user location view state for a map view.
- *
- * @return True and user location will be shown
- */
- public boolean getLocationEnabled() {
- return myLocationEnabled;
- }
-
- /**
- * Get the current configured MyLocationView foreground drawable.
- *
- * @return the drawable used as foreground
- */
- public Drawable getMyLocationForegroundDrawable() {
- return myLocationForegroundDrawable;
- }
-
- /**
- * Get the current configured MyLocationView foreground bearing drawable.
- *
- * @return the drawable used as foreground when bearing is enabled
- */
- public Drawable getMyLocationForegroundBearingDrawable() {
- return myLocationForegroundBearingDrawable;
- }
-
- /**
- * Get the current configured MyLocationView background drawable.
- *
- * @return the drawable used as background
- */
- public Drawable getMyLocationBackgroundDrawable() {
- return myLocationBackgroundDrawable;
- }
-
- /**
- * Get the current configured MyLocationView foreground tint color.
- *
- * @return the tint color
- */
- public int getMyLocationForegroundTintColor() {
- return myLocationForegroundTintColor;
- }
-
- /**
- * Get the current configured MyLocationView background tint color.
- *
- * @return the tint color
- */
- public int getMyLocationBackgroundTintColor() {
- return myLocationBackgroundTintColor;
- }
-
- /**
- * Get the current configured MyLocationView background padding.
- *
- * @return an array describing the padding in a LTRB manner
- */
- public int[] getMyLocationBackgroundPadding() {
- return myLocationBackgroundPadding;
- }
-
- /**
- * Get the current configured MyLocationView accuracy circle color tint value.
- *
- * @return the tint color
- */
- public int getMyLocationAccuracyTintColor() {
- return myLocationAccuracyTintColor;
- }
-
- /**
- * Get the current configured MyLocationView accuracy circle alpha value.
- *
- * @return the alpha value
- */
- public int getMyLocationAccuracyAlpha() {
- return myLocationAccuracyAlpha;
- }
-
- /**
- * Get the current configured debug state for a map view.
- *
- * @return True indicates debug is enabled.
- */
- public boolean getDebugActive() {
- return debugActive;
- }
-
- /**
- * Returns true if TextureView is being used a render view.
- *
- * @return True if TextureView is used.
- * @deprecated As of the 4.2.0 release, using TextureView is deprecated.
- */
- public boolean getTextureMode() {
- return textureMode;
- }
-
- public static final Parcelable.Creator<MapboxMapOptions> CREATOR
- = new Parcelable.Creator<MapboxMapOptions>() {
- public MapboxMapOptions createFromParcel(Parcel in) {
- return new MapboxMapOptions(in);
- }
-
- public MapboxMapOptions[] newArray(int size) {
- return new MapboxMapOptions[size];
- }
- };
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeParcelable(cameraPosition, flags);
- dest.writeByte((byte) (debugActive ? 1 : 0));
-
- dest.writeByte((byte) (compassEnabled ? 1 : 0));
- dest.writeInt(compassGravity);
- dest.writeIntArray(compassMargins);
- dest.writeByte((byte) (fadeCompassFacingNorth ? 1 : 0));
-
- dest.writeByte((byte) (logoEnabled ? 1 : 0));
- dest.writeInt(logoGravity);
- dest.writeIntArray(logoMargins);
-
- dest.writeByte((byte) (attributionEnabled ? 1 : 0));
- dest.writeInt(attributionGravity);
- dest.writeIntArray(attributionMargins);
- dest.writeInt(attributionTintColor);
-
- dest.writeFloat(minZoom);
- dest.writeFloat(maxZoom);
-
- dest.writeByte((byte) (rotateGesturesEnabled ? 1 : 0));
- dest.writeByte((byte) (scrollGesturesEnabled ? 1 : 0));
- dest.writeByte((byte) (tiltGesturesEnabled ? 1 : 0));
- dest.writeByte((byte) (zoomControlsEnabled ? 1 : 0));
- dest.writeByte((byte) (zoomGesturesEnabled ? 1 : 0));
-
- dest.writeByte((byte) (myLocationEnabled ? 1 : 0));
-
- dest.writeParcelable(myLocationForegroundDrawable != null ? getBitmapFromDrawable(myLocationForegroundDrawable) : null, flags);
- dest.writeParcelable(myLocationForegroundBearingDrawable != null ? getBitmapFromDrawable(myLocationForegroundBearingDrawable) : null, flags);
- dest.writeParcelable(myLocationBackgroundDrawable != null ? getBitmapFromDrawable(myLocationBackgroundDrawable) : null, flags);
- dest.writeInt(myLocationForegroundTintColor);
- dest.writeInt(myLocationBackgroundTintColor);
- dest.writeIntArray(myLocationBackgroundPadding);
- dest.writeInt(myLocationAccuracyAlpha);
- dest.writeInt(myLocationAccuracyTintColor);
-
- dest.writeString(style);
- dest.writeString(accessToken);
- dest.writeString(apiBaseUrl);
- dest.writeByte((byte) (textureMode ? 1 : 0));
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- MapboxMapOptions options = (MapboxMapOptions) o;
-
- if (debugActive != options.debugActive) return false;
- if (compassEnabled != options.compassEnabled) return false;
- if (fadeCompassFacingNorth != options.fadeCompassFacingNorth) return false;
- if (compassGravity != options.compassGravity) return false;
- if (logoEnabled != options.logoEnabled) return false;
- if (logoGravity != options.logoGravity) return false;
- if (attributionTintColor != options.attributionTintColor) return false;
- if (attributionEnabled != options.attributionEnabled) return false;
- if (attributionGravity != options.attributionGravity) return false;
- if (Float.compare(options.minZoom, minZoom) != 0) return false;
- if (Float.compare(options.maxZoom, maxZoom) != 0) return false;
- if (rotateGesturesEnabled != options.rotateGesturesEnabled) return false;
- if (scrollGesturesEnabled != options.scrollGesturesEnabled) return false;
- if (tiltGesturesEnabled != options.tiltGesturesEnabled) return false;
- if (zoomGesturesEnabled != options.zoomGesturesEnabled) return false;
- if (zoomControlsEnabled != options.zoomControlsEnabled) return false;
- if (myLocationEnabled != options.myLocationEnabled) return false;
- if (myLocationForegroundTintColor != options.myLocationForegroundTintColor) return false;
- if (myLocationBackgroundTintColor != options.myLocationBackgroundTintColor) return false;
- if (myLocationAccuracyTintColor != options.myLocationAccuracyTintColor) return false;
- if (myLocationAccuracyAlpha != options.myLocationAccuracyAlpha) return false;
- if (cameraPosition != null ? !cameraPosition.equals(options.cameraPosition) : options.cameraPosition != null)
- return false;
- if (!Arrays.equals(compassMargins, options.compassMargins)) return false;
- if (!Arrays.equals(logoMargins, options.logoMargins)) return false;
- if (!Arrays.equals(attributionMargins, options.attributionMargins)) return false;
- if (myLocationForegroundDrawable != null ? !myLocationForegroundDrawable.equals(options.myLocationForegroundDrawable) : options.myLocationForegroundDrawable != null)
- return false;
- if (myLocationForegroundBearingDrawable != null ? !myLocationForegroundBearingDrawable.equals(options.myLocationForegroundBearingDrawable) : options.myLocationForegroundBearingDrawable != null)
- return false;
- if (myLocationBackgroundDrawable != null ? !myLocationBackgroundDrawable.equals(options.myLocationBackgroundDrawable) : options.myLocationBackgroundDrawable != null)
- return false;
- if (!Arrays.equals(myLocationBackgroundPadding, options.myLocationBackgroundPadding))
- return false;
- if (style != null ? !style.equals(options.style) : options.style != null) return false;
- if (apiBaseUrl != null ? !apiBaseUrl.equals(options.apiBaseUrl) : options.apiBaseUrl != null)
- return false;
- return accessToken != null ? accessToken.equals(options.accessToken) : options.accessToken == null;
-
- }
-
- @Override
- public int hashCode() {
- int result = cameraPosition != null ? cameraPosition.hashCode() : 0;
- result = 31 * result + (debugActive ? 1 : 0);
- result = 31 * result + (compassEnabled ? 1 : 0);
- result = 31 * result + (fadeCompassFacingNorth ? 1 : 0);
- result = 31 * result + compassGravity;
- result = 31 * result + Arrays.hashCode(compassMargins);
- result = 31 * result + (logoEnabled ? 1 : 0);
- result = 31 * result + logoGravity;
- result = 31 * result + Arrays.hashCode(logoMargins);
- result = 31 * result + attributionTintColor;
- result = 31 * result + (attributionEnabled ? 1 : 0);
- result = 31 * result + attributionGravity;
- result = 31 * result + Arrays.hashCode(attributionMargins);
- result = 31 * result + (minZoom != +0.0f ? Float.floatToIntBits(minZoom) : 0);
- result = 31 * result + (maxZoom != +0.0f ? Float.floatToIntBits(maxZoom) : 0);
- result = 31 * result + (rotateGesturesEnabled ? 1 : 0);
- result = 31 * result + (scrollGesturesEnabled ? 1 : 0);
- result = 31 * result + (tiltGesturesEnabled ? 1 : 0);
- result = 31 * result + (zoomGesturesEnabled ? 1 : 0);
- result = 31 * result + (zoomControlsEnabled ? 1 : 0);
- result = 31 * result + (myLocationEnabled ? 1 : 0);
- result = 31 * result + (myLocationForegroundDrawable != null ? myLocationForegroundDrawable.hashCode() : 0);
- result = 31 * result + (myLocationForegroundBearingDrawable != null ? myLocationForegroundBearingDrawable.hashCode() : 0);
- result = 31 * result + (myLocationBackgroundDrawable != null ? myLocationBackgroundDrawable.hashCode() : 0);
- result = 31 * result + myLocationForegroundTintColor;
- result = 31 * result + myLocationBackgroundTintColor;
- result = 31 * result + Arrays.hashCode(myLocationBackgroundPadding);
- result = 31 * result + myLocationAccuracyTintColor;
- result = 31 * result + myLocationAccuracyAlpha;
- result = 31 * result + (style != null ? style.hashCode() : 0);
- result = 31 * result + (accessToken != null ? accessToken.hashCode() : 0);
- result = 31 * result + (apiBaseUrl != null ? apiBaseUrl.hashCode() : 0);
- return result;
+ if (Double.compare(options.minZoom, minZoom) != 0) {
+ return false;
}
-}
+ if (Double.compare(options.maxZoom, maxZoom) != 0) {
+ return false;
+ }
+ if (rotateGesturesEnabled != options.rotateGesturesEnabled) {
+ return false;
+ }
+ if (scrollGesturesEnabled != options.scrollGesturesEnabled) {
+ return false;
+ }
+ if (tiltGesturesEnabled != options.tiltGesturesEnabled) {
+ return false;
+ }
+ if (zoomGesturesEnabled != options.zoomGesturesEnabled) {
+ return false;
+ }
+ if (zoomControlsEnabled != options.zoomControlsEnabled) {
+ return false;
+ }
+ if (myLocationEnabled != options.myLocationEnabled) {
+ return false;
+ }
+ if (myLocationForegroundTintColor != options.myLocationForegroundTintColor) {
+ return false;
+ }
+ if (myLocationBackgroundTintColor != options.myLocationBackgroundTintColor) {
+ return false;
+ }
+ if (myLocationAccuracyTintColor != options.myLocationAccuracyTintColor) {
+ return false;
+ }
+ if (myLocationAccuracyAlpha != options.myLocationAccuracyAlpha) {
+ return false;
+ }
+ if (cameraPosition != null ? !cameraPosition.equals(options.cameraPosition) : options.cameraPosition != null) {
+ return false;
+ }
+ if (!Arrays.equals(compassMargins, options.compassMargins)) {
+ return false;
+ }
+ if (!Arrays.equals(logoMargins, options.logoMargins)) {
+ return false;
+ }
+ if (!Arrays.equals(attributionMargins, options.attributionMargins)) {
+ return false;
+ }
+ if (myLocationForegroundDrawable != null
+ ? !myLocationForegroundDrawable.equals(options.myLocationForegroundDrawable)
+ : options.myLocationForegroundDrawable != null) {
+ return false;
+ }
+ if (myLocationForegroundBearingDrawable != null
+ ? !myLocationForegroundBearingDrawable.equals(options.myLocationForegroundBearingDrawable)
+ : options.myLocationForegroundBearingDrawable != null) {
+ return false;
+ }
+ if (myLocationBackgroundDrawable != null
+ ? !myLocationBackgroundDrawable.equals(options.myLocationBackgroundDrawable)
+ : options.myLocationBackgroundDrawable != null) {
+ return false;
+ }
+ if (!Arrays.equals(myLocationBackgroundPadding, options.myLocationBackgroundPadding)) {
+ return false;
+ }
+ if (style != null ? !style.equals(options.style) : options.style != null) {
+ return false;
+ }
+ if (apiBaseUrl != null ? !apiBaseUrl.equals(options.apiBaseUrl) : options.apiBaseUrl != null) {
+ return false;
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ int result;
+ long temp;
+ result = cameraPosition != null ? cameraPosition.hashCode() : 0;
+ result = 31 * result + (debugActive ? 1 : 0);
+ result = 31 * result + (compassEnabled ? 1 : 0);
+ result = 31 * result + (fadeCompassFacingNorth ? 1 : 0);
+ result = 31 * result + compassGravity;
+ result = 31 * result + Arrays.hashCode(compassMargins);
+ result = 31 * result + (logoEnabled ? 1 : 0);
+ result = 31 * result + logoGravity;
+ result = 31 * result + Arrays.hashCode(logoMargins);
+ result = 31 * result + attributionTintColor;
+ result = 31 * result + (attributionEnabled ? 1 : 0);
+ result = 31 * result + attributionGravity;
+ result = 31 * result + Arrays.hashCode(attributionMargins);
+ temp = Double.doubleToLongBits(minZoom);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ temp = Double.doubleToLongBits(maxZoom);
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
+ result = 31 * result + (rotateGesturesEnabled ? 1 : 0);
+ result = 31 * result + (scrollGesturesEnabled ? 1 : 0);
+ result = 31 * result + (tiltGesturesEnabled ? 1 : 0);
+ result = 31 * result + (zoomGesturesEnabled ? 1 : 0);
+ result = 31 * result + (zoomControlsEnabled ? 1 : 0);
+ result = 31 * result + (myLocationEnabled ? 1 : 0);
+ result = 31 * result + (myLocationForegroundDrawable != null ? myLocationForegroundDrawable.hashCode() : 0);
+ result = 31 * result + (myLocationForegroundBearingDrawable != null
+ ? myLocationForegroundBearingDrawable.hashCode() : 0);
+ result = 31 * result + (myLocationBackgroundDrawable != null ? myLocationBackgroundDrawable.hashCode() : 0);
+ result = 31 * result + myLocationForegroundTintColor;
+ result = 31 * result + myLocationBackgroundTintColor;
+ result = 31 * result + Arrays.hashCode(myLocationBackgroundPadding);
+ result = 31 * result + myLocationAccuracyTintColor;
+ result = 31 * result + myLocationAccuracyAlpha;
+ result = 31 * result + (apiBaseUrl != null ? apiBaseUrl.hashCode() : 0);
+ result = 31 * result + (textureMode ? 1 : 0);
+ result = 31 * result + (style != null ? style.hashCode() : 0);
+ return result;
+ }
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java
index 4e0ce33c5b..95c0ae5327 100755
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java
@@ -9,14 +9,12 @@ import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.DisplayMetrics;
-import android.util.Log;
import android.view.Surface;
import com.mapbox.mapboxsdk.annotations.Icon;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.Polygon;
import com.mapbox.mapboxsdk.annotations.Polyline;
-import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.geometry.ProjectedMeters;
import com.mapbox.mapboxsdk.offline.OfflineManager;
@@ -30,741 +28,816 @@ import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import timber.log.Timber;
// Class that wraps the native methods for convenience
final class NativeMapView {
- //
- // Static members
- //
+ // Flag to indicating destroy was called
+ private boolean destroyed = false;
- //
- // Instance members
- //
+ // Holds the pointer to JNI NativeMapView
+ private long nativeMapViewPtr = 0;
- boolean destroyed = false;
+ // Used for callbacks
+ private MapView mapView;
- // Holds the pointer to JNI NativeMapView
- private long nativeMapViewPtr = 0;
+ // Device density
+ private final float pixelRatio;
- // Used for callbacks
- private MapView mapView;
+ // Listeners for Map change events
+ private CopyOnWriteArrayList<MapView.OnMapChangedListener> onMapChangedListeners;
- private final float pixelRatio;
+ //
+ // Static methods
+ //
- //
- // Static methods
- //
+ static {
+ System.loadLibrary("mapbox-gl");
+ }
- static {
- System.loadLibrary("mapbox-gl");
- }
+ //
+ // Constructors
+ //
- //
- // Constructors
- //
-
- public NativeMapView(MapView mapView) {
- Context context = mapView.getContext();
- String dataPath = OfflineManager.getDatabasePath(context);
-
- // With the availability of offline, we're unifying the ambient (cache) and the offline
- // databases to be in the same folder, outside cache, to avoid automatic deletion from
- // the system
- String cachePath = dataPath;
-
- pixelRatio = context.getResources().getDisplayMetrics().density;
- String apkPath = context.getPackageCodePath();
- int availableProcessors = Runtime.getRuntime().availableProcessors();
- ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
- ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
- activityManager.getMemoryInfo(memoryInfo);
- long totalMemory = memoryInfo.availMem;
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- totalMemory = memoryInfo.totalMem;
- }
-
- if (availableProcessors < 0) {
- throw new IllegalArgumentException("availableProcessors cannot be negative.");
- }
-
- if (totalMemory < 0) {
- throw new IllegalArgumentException("totalMemory cannot be negative.");
- }
-
- this.mapView = mapView;
- nativeMapViewPtr = nativeCreate(cachePath, dataPath, apkPath, pixelRatio, availableProcessors, totalMemory);
- }
+ public NativeMapView(MapView mapView) {
+ Context context = mapView.getContext();
+ String dataPath = OfflineManager.getDatabasePath(context);
- //
- // Methods
- //
+ // With the availability of offline, we're unifying the ambient (cache) and the offline
+ // databases to be in the same folder, outside cache, to avoid automatic deletion from
+ // the system
+ String cachePath = dataPath;
- public void destroy() {
- nativeDestroy(nativeMapViewPtr);
- nativeMapViewPtr = 0;
- mapView = null;
- destroyed = true;
+ pixelRatio = context.getResources().getDisplayMetrics().density;
+ String apkPath = context.getPackageCodePath();
+ int availableProcessors = Runtime.getRuntime().availableProcessors();
+ ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
+ ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+ activityManager.getMemoryInfo(memoryInfo);
+ long totalMemory = memoryInfo.availMem;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ totalMemory = memoryInfo.totalMem;
}
- public boolean wasDestroyed() {
- return destroyed;
+ if (availableProcessors < 0) {
+ throw new IllegalArgumentException("availableProcessors cannot be negative.");
}
- public void initializeDisplay() {
- nativeInitializeDisplay(nativeMapViewPtr);
+ if (totalMemory < 0) {
+ throw new IllegalArgumentException("totalMemory cannot be negative.");
}
+ onMapChangedListeners = new CopyOnWriteArrayList<>();
+ this.mapView = mapView;
+ nativeMapViewPtr = nativeCreate(cachePath, dataPath, apkPath, pixelRatio, availableProcessors, totalMemory);
+ }
- public void terminateDisplay() {
- nativeTerminateDisplay(nativeMapViewPtr);
- }
+ //
+ // Methods
+ //
- public void initializeContext() {
- nativeInitializeContext(nativeMapViewPtr);
- }
+ public void destroy() {
+ nativeDestroy(nativeMapViewPtr);
+ nativeMapViewPtr = 0;
+ mapView = null;
+ destroyed = true;
+ }
- public void terminateContext() {
- nativeTerminateContext(nativeMapViewPtr);
- }
+ public boolean wasDestroyed() {
+ return destroyed;
+ }
- public void createSurface(Surface surface) {
- nativeCreateSurface(nativeMapViewPtr, surface);
- }
+ public void initializeDisplay() {
+ nativeInitializeDisplay(nativeMapViewPtr);
+ }
- public void destroySurface() {
- nativeDestroySurface(nativeMapViewPtr);
- }
+ public void terminateDisplay() {
+ nativeTerminateDisplay(nativeMapViewPtr);
+ }
- public void update() {
- nativeUpdate(nativeMapViewPtr);
- }
+ public void initializeContext() {
+ nativeInitializeContext(nativeMapViewPtr);
+ }
- public void render() {
- nativeRender(nativeMapViewPtr);
- }
+ public void terminateContext() {
+ nativeTerminateContext(nativeMapViewPtr);
+ }
- public void resizeView(int width, int height) {
- if (width < 0) {
- throw new IllegalArgumentException("width cannot be negative.");
- }
-
- if (height < 0) {
- throw new IllegalArgumentException("height cannot be negative.");
- }
-
- if (width > 65535) {
- // we have seen edge cases where devices return incorrect values #6111
- Log.e(MapboxConstants.TAG, "Device returned an out of range width size, " +
- "capping value at 65535 instead of " + width);
- width = 65535;
- }
-
- if (height > 65535) {
- // we have seen edge cases where devices return incorrect values #6111
- Log.e(MapboxConstants.TAG, "Device returned an out of range height size, " +
- "capping value at 65535 instead of " + height);
- height = 65535;
- }
- nativeViewResize(nativeMapViewPtr, width, height);
- }
+ public void createSurface(Surface surface) {
+ nativeCreateSurface(nativeMapViewPtr, surface);
+ }
- public void resizeFramebuffer(int fbWidth, int fbHeight) {
- if (fbWidth < 0) {
- throw new IllegalArgumentException("fbWidth cannot be negative.");
- }
-
- if (fbHeight < 0) {
- throw new IllegalArgumentException("fbHeight cannot be negative.");
- }
-
- if (fbWidth > 65535) {
- throw new IllegalArgumentException(
- "fbWidth cannot be greater than 65535.");
- }
-
- if (fbHeight > 65535) {
- throw new IllegalArgumentException(
- "fbHeight cannot be greater than 65535.");
- }
- nativeFramebufferResize(nativeMapViewPtr, fbWidth, fbHeight);
- }
+ public void destroySurface() {
+ nativeDestroySurface(nativeMapViewPtr);
+ }
- public void addClass(String clazz) {
- nativeAddClass(nativeMapViewPtr, clazz);
- }
+ public void update() {
+ nativeUpdate(nativeMapViewPtr);
+ }
- public void removeClass(String clazz) {
- nativeRemoveClass(nativeMapViewPtr, clazz);
- }
+ public void render() {
+ nativeRender(nativeMapViewPtr);
+ }
- public boolean hasClass(String clazz) {
- return nativeHasClass(nativeMapViewPtr, clazz);
- }
+ public void resizeView(int width, int height) {
+ width = (int) (width / pixelRatio);
+ height = (int) (height / pixelRatio);
- public void setClasses(List<String> classes) {
- nativeSetClasses(nativeMapViewPtr, classes);
+ if (width < 0) {
+ throw new IllegalArgumentException("width cannot be negative.");
}
- public List<String> getClasses() {
- return nativeGetClasses(nativeMapViewPtr);
+ if (height < 0) {
+ throw new IllegalArgumentException("height cannot be negative.");
}
- public void setStyleUrl(String url) {
- nativeSetStyleUrl(nativeMapViewPtr, url);
+ if (width > 65535) {
+ // we have seen edge cases where devices return incorrect values #6111
+ Timber.e("Device returned an out of range width size, "
+ + "capping value at 65535 instead of " + width);
+ width = 65535;
}
- public void setStyleJson(String newStyleJson) {
- nativeSetStyleJson(nativeMapViewPtr, newStyleJson);
+ if (height > 65535) {
+ // we have seen edge cases where devices return incorrect values #6111
+ Timber.e("Device returned an out of range height size, "
+ + "capping value at 65535 instead of " + height);
+ height = 65535;
}
+ nativeViewResize(nativeMapViewPtr, width, height);
+ }
- public String getStyleJson() {
- return nativeGetStyleJson(nativeMapViewPtr);
+ public void resizeFramebuffer(int fbWidth, int fbHeight) {
+ if (fbWidth < 0) {
+ throw new IllegalArgumentException("fbWidth cannot be negative.");
}
- public void setAccessToken(String accessToken) {
- nativeSetAccessToken(nativeMapViewPtr, accessToken);
+ if (fbHeight < 0) {
+ throw new IllegalArgumentException("fbHeight cannot be negative.");
}
- public String getAccessToken() {
- return nativeGetAccessToken(nativeMapViewPtr);
+ if (fbWidth > 65535) {
+ throw new IllegalArgumentException(
+ "fbWidth cannot be greater than 65535.");
}
- public void cancelTransitions() {
- nativeCancelTransitions(nativeMapViewPtr);
+ if (fbHeight > 65535) {
+ throw new IllegalArgumentException(
+ "fbHeight cannot be greater than 65535.");
}
+ nativeFramebufferResize(nativeMapViewPtr, fbWidth, fbHeight);
+ }
- public void setGestureInProgress(boolean inProgress) {
- nativeSetGestureInProgress(nativeMapViewPtr, inProgress);
- }
+ public void addClass(String clazz) {
+ nativeAddClass(nativeMapViewPtr, clazz);
+ }
- public void moveBy(double dx, double dy) {
- moveBy(dx, dy, 0);
- }
+ public void removeClass(String clazz) {
+ nativeRemoveClass(nativeMapViewPtr, clazz);
+ }
- public void moveBy(double dx, double dy, long duration) {
- nativeMoveBy(nativeMapViewPtr, dx, dy, duration);
- }
+ public boolean hasClass(String clazz) {
+ return nativeHasClass(nativeMapViewPtr, clazz);
+ }
- public void setLatLng(LatLng latLng) {
- setLatLng(latLng, 0);
- }
+ public void setClasses(List<String> classes) {
+ nativeSetClasses(nativeMapViewPtr, classes);
+ }
- public void setLatLng(LatLng latLng, long duration) {
- nativeSetLatLng(nativeMapViewPtr, latLng.getLatitude(), latLng.getLongitude(), duration);
- }
+ public List<String> getClasses() {
+ return nativeGetClasses(nativeMapViewPtr);
+ }
- public LatLng getLatLng() {
- return nativeGetLatLng(nativeMapViewPtr);
- }
+ public void setStyleUrl(String url) {
+ nativeSetStyleUrl(nativeMapViewPtr, url);
+ }
- public void resetPosition() {
- nativeResetPosition(nativeMapViewPtr);
- }
+ public String getStyleUrl() {
+ return nativeGetStyleUrl(nativeMapViewPtr);
+ }
- public double getPitch() {
- return nativeGetPitch(nativeMapViewPtr);
- }
+ public void setStyleJson(String newStyleJson) {
+ nativeSetStyleJson(nativeMapViewPtr, newStyleJson);
+ }
- public void setPitch(double pitch, long duration) {
- nativeSetPitch(nativeMapViewPtr, pitch, duration);
- }
+ public String getStyleJson() {
+ return nativeGetStyleJson(nativeMapViewPtr);
+ }
- public void scaleBy(double ds) {
- scaleBy(ds, Double.NaN, Double.NaN);
- }
+ public void setAccessToken(String accessToken) {
+ nativeSetAccessToken(nativeMapViewPtr, accessToken);
+ }
- public void scaleBy(double ds, double cx, double cy) {
- scaleBy(ds, cx, cy, 0);
- }
+ public String getAccessToken() {
+ return nativeGetAccessToken(nativeMapViewPtr);
+ }
- public void scaleBy(double ds, double cx, double cy, long duration) {
- nativeScaleBy(nativeMapViewPtr, ds, cx, cy, duration);
- }
+ public void cancelTransitions() {
+ nativeCancelTransitions(nativeMapViewPtr);
+ }
- public void setScale(double scale) {
- setScale(scale, Double.NaN, Double.NaN);
- }
+ public void setGestureInProgress(boolean inProgress) {
+ nativeSetGestureInProgress(nativeMapViewPtr, inProgress);
+ }
- public void setScale(double scale, double cx, double cy) {
- setScale(scale, cx, cy, 0);
- }
+ public void moveBy(double dx, double dy) {
+ moveBy(dx, dy, 0);
+ }
- public void setScale(double scale, double cx, double cy, long duration) {
- nativeSetScale(nativeMapViewPtr, scale, cx, cy, duration);
- }
+ public void moveBy(double dx, double dy, long duration) {
+ nativeMoveBy(nativeMapViewPtr, dx / pixelRatio, dy / pixelRatio, duration);
+ }
- public double getScale() {
- return nativeGetScale(nativeMapViewPtr);
- }
+ public void setLatLng(LatLng latLng) {
+ setLatLng(latLng, 0);
+ }
- public void setZoom(double zoom) {
- setZoom(zoom, 0);
- }
+ public void setLatLng(LatLng latLng, long duration) {
+ nativeSetLatLng(nativeMapViewPtr, latLng.getLatitude(), latLng.getLongitude(), duration);
+ }
- public void setZoom(double zoom, long duration) {
- nativeSetZoom(nativeMapViewPtr, zoom, duration);
- }
+ public LatLng getLatLng() {
+ return nativeGetLatLng(nativeMapViewPtr);
+ }
- public double getZoom() {
- return nativeGetZoom(nativeMapViewPtr);
- }
+ public void resetPosition() {
+ nativeResetPosition(nativeMapViewPtr);
+ }
- public void resetZoom() {
- nativeResetZoom(nativeMapViewPtr);
- }
+ public double getPitch() {
+ return nativeGetPitch(nativeMapViewPtr);
+ }
- public void setMinZoom(double zoom) {
- nativeSetMinZoom(nativeMapViewPtr, zoom);
- }
+ public void setPitch(double pitch, long duration) {
+ nativeSetPitch(nativeMapViewPtr, pitch, duration);
+ }
- public double getMinZoom() {
- return nativeGetMinZoom(nativeMapViewPtr);
- }
+ public void scaleBy(double ds) {
+ scaleBy(ds, Double.NaN, Double.NaN);
+ }
- public void setMaxZoom(double zoom) {
- nativeSetMaxZoom(nativeMapViewPtr, zoom);
- }
+ public void scaleBy(double ds, double cx, double cy) {
+ scaleBy(ds, cx, cy, 0);
+ }
- public double getMaxZoom() {
- return nativeGetMaxZoom(nativeMapViewPtr);
- }
+ public void scaleBy(double ds, double cx, double cy, long duration) {
+ nativeScaleBy(nativeMapViewPtr, ds, cx / pixelRatio, cy / pixelRatio, duration);
+ }
+
+ public void setScale(double scale) {
+ setScale(scale, Double.NaN, Double.NaN);
+ }
+
+ public void setScale(double scale, double cx, double cy) {
+ setScale(scale, cx, cy, 0);
+ }
+
+ public void setScale(double scale, double cx, double cy, long duration) {
+ nativeSetScale(nativeMapViewPtr, scale, cx / pixelRatio, cy / pixelRatio, duration);
+ }
+
+ public double getScale() {
+ return nativeGetScale(nativeMapViewPtr);
+ }
+
+ public void setZoom(double zoom) {
+ setZoom(zoom, 0);
+ }
+
+ public void setZoom(double zoom, long duration) {
+ nativeSetZoom(nativeMapViewPtr, zoom, duration);
+ }
+
+ public double getZoom() {
+ return nativeGetZoom(nativeMapViewPtr);
+ }
+
+ public void resetZoom() {
+ nativeResetZoom(nativeMapViewPtr);
+ }
+
+ public void setMinZoom(double zoom) {
+ nativeSetMinZoom(nativeMapViewPtr, zoom);
+ }
+
+ public double getMinZoom() {
+ return nativeGetMinZoom(nativeMapViewPtr);
+ }
+
+ public void setMaxZoom(double zoom) {
+ nativeSetMaxZoom(nativeMapViewPtr, zoom);
+ }
+
+ public double getMaxZoom() {
+ return nativeGetMaxZoom(nativeMapViewPtr);
+ }
+
+ public void rotateBy(double sx, double sy, double ex, double ey) {
+ rotateBy(sx, sy, ex, ey, 0);
+ }
+
+ public void rotateBy(double sx, double sy, double ex, double ey,
+ long duration) {
+ nativeRotateBy(nativeMapViewPtr, sx / pixelRatio, sy / pixelRatio, ex, ey, duration);
+ }
+
+ public void setContentPadding(int[] padding) {
+ nativeSetContentPadding(nativeMapViewPtr,
+ padding[1] / pixelRatio,
+ padding[0] / pixelRatio,
+ padding[3] / pixelRatio,
+ padding[2] / pixelRatio);
+ }
+
+ public void setBearing(double degrees) {
+ setBearing(degrees, 0);
+ }
+
+ public void setBearing(double degrees, long duration) {
+ nativeSetBearing(nativeMapViewPtr, degrees, duration);
+ }
+
+ public void setBearing(double degrees, double cx, double cy) {
+ nativeSetBearingXY(nativeMapViewPtr, degrees, cx / pixelRatio, cy / pixelRatio);
+ }
+
+ public double getBearing() {
+ return nativeGetBearing(nativeMapViewPtr);
+ }
+
+ public void resetNorth() {
+ nativeResetNorth(nativeMapViewPtr);
+ }
+
+ public long addMarker(Marker marker) {
+ Marker[] markers = {marker};
+ return nativeAddMarkers(nativeMapViewPtr, markers)[0];
+ }
+
+ public long[] addMarkers(List<Marker> markers) {
+ return nativeAddMarkers(nativeMapViewPtr, markers.toArray(new Marker[markers.size()]));
+ }
+
+ public long addPolyline(Polyline polyline) {
+ Polyline[] polylines = {polyline};
+ return nativeAddPolylines(nativeMapViewPtr, polylines)[0];
+ }
+
+ public long[] addPolylines(List<Polyline> polylines) {
+ return nativeAddPolylines(nativeMapViewPtr, polylines.toArray(new Polyline[polylines.size()]));
+ }
+
+ public long addPolygon(Polygon polygon) {
+ Polygon[] polygons = {polygon};
+ return nativeAddPolygons(nativeMapViewPtr, polygons)[0];
+ }
+
+ public long[] addPolygons(List<Polygon> polygons) {
+ return nativeAddPolygons(nativeMapViewPtr, polygons.toArray(new Polygon[polygons.size()]));
+ }
+
+ public void updateMarker(Marker marker) {
+ LatLng position = marker.getPosition();
+ Icon icon = marker.getIcon();
+ nativeUpdateMarker(nativeMapViewPtr, marker.getId(), position.getLatitude(), position.getLongitude(), icon.getId());
+ }
+
+ public void updatePolygon(Polygon polygon) {
+ nativeUpdatePolygon(nativeMapViewPtr, polygon.getId(), polygon);
+ }
+
+ public void updatePolyline(Polyline polyline) {
+ nativeUpdatePolyline(nativeMapViewPtr, polyline.getId(), polyline);
+ }
+
+ public void removeAnnotation(long id) {
+ long[] ids = {id};
+ removeAnnotations(ids);
+ }
+
+ public void removeAnnotations(long[] ids) {
+ nativeRemoveAnnotations(nativeMapViewPtr, ids);
+ }
+
+ public long[] queryPointAnnotations(RectF rect) {
+ return nativeQueryPointAnnotations(nativeMapViewPtr, rect);
+ }
+
+ public void addAnnotationIcon(String symbol, int width, int height, float scale, byte[] pixels) {
+ nativeAddAnnotationIcon(nativeMapViewPtr, symbol, width, height, scale, pixels);
+ }
+
+ public void setVisibleCoordinateBounds(LatLng[] coordinates, RectF padding, double direction, long duration) {
+ nativeSetVisibleCoordinateBounds(nativeMapViewPtr, coordinates, padding, direction, duration);
+ }
+
+ public void onLowMemory() {
+ nativeOnLowMemory(nativeMapViewPtr);
+ }
+
+ public void setDebug(boolean debug) {
+ nativeSetDebug(nativeMapViewPtr, debug);
+ }
+
+ public void cycleDebugOptions() {
+ nativeToggleDebug(nativeMapViewPtr);
+ }
+
+ public boolean getDebug() {
+ return nativeGetDebug(nativeMapViewPtr);
+ }
+
+ public boolean isFullyLoaded() {
+ return nativeIsFullyLoaded(nativeMapViewPtr);
+ }
+
+ public void setReachability(boolean status) {
+ nativeSetReachability(nativeMapViewPtr, status);
+ }
+
+ public double getMetersPerPixelAtLatitude(double lat) {
+ return nativeGetMetersPerPixelAtLatitude(nativeMapViewPtr, lat, getZoom());
+ }
+
+ public ProjectedMeters projectedMetersForLatLng(LatLng latLng) {
+ return nativeProjectedMetersForLatLng(nativeMapViewPtr, latLng.getLatitude(), latLng.getLongitude());
+ }
+
+ public LatLng latLngForProjectedMeters(ProjectedMeters projectedMeters) {
+ return nativeLatLngForProjectedMeters(nativeMapViewPtr, projectedMeters.getNorthing(),
+ projectedMeters.getEasting());
+ }
+
+ public PointF pixelForLatLng(LatLng latLng) {
+ PointF pointF = nativePixelForLatLng(nativeMapViewPtr, latLng.getLatitude(), latLng.getLongitude());
+ pointF.set(pointF.x * pixelRatio, pointF.y * pixelRatio);
+ return pointF;
+ }
+
+ public LatLng latLngForPixel(PointF pixel) {
+ return nativeLatLngForPixel(nativeMapViewPtr, pixel.x / pixelRatio, pixel.y / pixelRatio);
+ }
+
+ public double getTopOffsetPixelsForAnnotationSymbol(String symbolName) {
+ return nativeGetTopOffsetPixelsForAnnotationSymbol(nativeMapViewPtr, symbolName);
+ }
+
+ public void jumpTo(double angle, LatLng center, double pitch, double zoom) {
+ nativeJumpTo(nativeMapViewPtr, angle, center.getLatitude(), center.getLongitude(), pitch, zoom);
+ }
+
+ public void easeTo(double angle, LatLng center, long duration, double pitch, double zoom,
+ boolean easingInterpolator) {
+ nativeEaseTo(nativeMapViewPtr, angle, center.getLatitude(), center.getLongitude(), duration, pitch, zoom,
+ easingInterpolator);
+ }
+
+ public void flyTo(double angle, LatLng center, long duration, double pitch, double zoom) {
+ nativeFlyTo(nativeMapViewPtr, angle, center.getLatitude(), center.getLongitude(), duration, pitch, zoom);
+ }
+
+ public double[] getCameraValues() {
+ return nativeGetCameraValues(nativeMapViewPtr);
+ }
+
+ // Runtime style Api
+
+ public Layer getLayer(String layerId) {
+ return nativeGetLayer(nativeMapViewPtr, layerId);
+ }
+
+ public void addLayer(@NonNull Layer layer, @Nullable String before) {
+ nativeAddLayer(nativeMapViewPtr, layer.getNativePtr(), before);
+ }
+
+ public void removeLayer(@NonNull String layerId) throws NoSuchLayerException {
+ nativeRemoveLayerById(nativeMapViewPtr, layerId);
+ }
+
+ public void removeLayer(@NonNull Layer layer) throws NoSuchLayerException {
+ nativeRemoveLayer(nativeMapViewPtr, layer.getNativePtr());
+ }
+
+ public Source getSource(@NonNull String sourceId) {
+ return nativeGetSource(nativeMapViewPtr, sourceId);
+ }
+
+ public void addSource(@NonNull Source source) {
+ nativeAddSource(nativeMapViewPtr, source.getNativePtr());
+ }
- public void rotateBy(double sx, double sy, double ex, double ey) {
- rotateBy(sx, sy, ex, ey, 0);
- }
+ public void removeSource(@NonNull String sourceId) throws NoSuchSourceException {
+ nativeRemoveSourceById(nativeMapViewPtr, sourceId);
+ }
- public void rotateBy(double sx, double sy, double ex, double ey,
- long duration) {
- nativeRotateBy(nativeMapViewPtr, sx, sy, ex, ey, duration);
- }
+ public void removeSource(@NonNull Source source) throws NoSuchSourceException {
+ nativeRemoveSource(nativeMapViewPtr, source.getNativePtr());
+ }
- public void setContentPadding(double top, double left, double bottom, double right) {
- nativeSetContentPadding(nativeMapViewPtr, top, left, bottom, right);
+ public void addImage(@NonNull String name, @NonNull Bitmap image) {
+ //Check/correct config
+ if (image.getConfig() != Bitmap.Config.ARGB_8888) {
+ image = image.copy(Bitmap.Config.ARGB_8888, false);
}
- public void setBearing(double degrees) {
- setBearing(degrees, 0);
- }
+ //Get pixels
+ ByteBuffer buffer = ByteBuffer.allocate(image.getByteCount());
+ image.copyPixelsToBuffer(buffer);
- public void setBearing(double degrees, long duration) {
- nativeSetBearing(nativeMapViewPtr, degrees, duration);
- }
+ //Determine pixel ratio
+ float density = image.getDensity() == Bitmap.DENSITY_NONE ? Bitmap.DENSITY_NONE : image.getDensity();
+ float pixelRatio = density / DisplayMetrics.DENSITY_DEFAULT;
- public void setBearing(double degrees, double cx, double cy) {
- nativeSetBearingXY(nativeMapViewPtr, degrees, cx, cy);
- }
+ nativeAddImage(nativeMapViewPtr, name, image.getWidth(), image.getHeight(), pixelRatio, buffer.array());
+ }
- public double getBearing() {
- return nativeGetBearing(nativeMapViewPtr);
- }
+ public void removeImage(String name) {
+ nativeRemoveImage(nativeMapViewPtr, name);
+ }
- public void resetNorth() {
- nativeResetNorth(nativeMapViewPtr);
- }
+ // Feature querying
- public long addMarker(Marker marker) {
- Marker[] markers = {marker};
- return nativeAddMarkers(nativeMapViewPtr, markers)[0];
- }
+ @NonNull
+ public List<Feature> queryRenderedFeatures(PointF coordinates, String... layerIds) {
+ Feature[] features = nativeQueryRenderedFeaturesForPoint(nativeMapViewPtr, coordinates.x / pixelRatio,
+ coordinates.y / pixelRatio, layerIds);
+ return features != null ? Arrays.asList(features) : new ArrayList<Feature>();
+ }
- public long[] addMarkers(List<Marker> markers) {
- return nativeAddMarkers(nativeMapViewPtr, markers.toArray(new Marker[markers.size()]));
- }
+ @NonNull
+ public List<Feature> queryRenderedFeatures(RectF coordinates, String... layerIds) {
+ Feature[] features = nativeQueryRenderedFeaturesForBox(
+ nativeMapViewPtr,
+ coordinates.left / pixelRatio,
+ coordinates.top / pixelRatio,
+ coordinates.right / pixelRatio,
+ coordinates.bottom / pixelRatio,
+ layerIds);
+ return features != null ? Arrays.asList(features) : new ArrayList<Feature>();
+ }
- public long addPolyline(Polyline polyline) {
- Polyline[] polylines = {polyline};
- return nativeAddPolylines(nativeMapViewPtr, polylines)[0];
- }
+ public void scheduleTakeSnapshot() {
+ nativeScheduleTakeSnapshot(nativeMapViewPtr);
+ }
- public long[] addPolylines(List<Polyline> polylines) {
- return nativeAddPolylines(nativeMapViewPtr, polylines.toArray(new Polyline[polylines.size()]));
- }
+ public void setApiBaseUrl(String baseUrl) {
+ nativeSetAPIBaseURL(nativeMapViewPtr, baseUrl);
+ }
- public long addPolygon(Polygon polygon) {
- Polygon[] polygons = {polygon};
- return nativeAddPolygons(nativeMapViewPtr, polygons)[0];
- }
+ public float getPixelRatio() {
+ return pixelRatio;
+ }
- public long[] addPolygons(List<Polygon> polygons) {
- return nativeAddPolygons(nativeMapViewPtr, polygons.toArray(new Polygon[polygons.size()]));
- }
+ public Context getContext() {
+ return mapView.getContext();
+ }
- public void updateMarker(Marker marker) {
- LatLng position = marker.getPosition();
- Icon icon = marker.getIcon();
- nativeUpdateMarker(nativeMapViewPtr, marker.getId(), position.getLatitude(), position.getLongitude(), icon.getId());
- }
+ //
+ // Callbacks
+ //
- public void updatePolygon(Polygon polygon) {
- nativeUpdatePolygon(nativeMapViewPtr, polygon.getId(), polygon);
- }
+ protected void onInvalidate() {
+ mapView.onInvalidate();
+ }
- public void updatePolyline(Polyline polyline) {
- nativeUpdatePolyline(nativeMapViewPtr, polyline.getId(), polyline);
- }
+ protected void onMapChanged(int rawChange) {
+ mapView.onMapChanged(rawChange);
+ }
- public void removeAnnotation(long id) {
- long[] ids = {id};
- removeAnnotations(ids);
- }
+ protected void onFpsChanged(double fps) {
+ mapView.onFpsChanged(fps);
+ }
- public void removeAnnotations(long[] ids) {
- nativeRemoveAnnotations(nativeMapViewPtr, ids);
- }
+ protected void onSnapshotReady(byte[] bytes) {
+ mapView.onSnapshotReady(bytes);
+ }
- public long[] queryPointAnnotations(RectF rect) {
- return nativeQueryPointAnnotations(nativeMapViewPtr, rect);
- }
+ //
+ // JNI methods
+ //
- public void addAnnotationIcon(String symbol, int width, int height, float scale, byte[] pixels) {
- nativeAddAnnotationIcon(nativeMapViewPtr, symbol, width, height, scale, pixels);
- }
+ private native long nativeCreate(String cachePath, String dataPath, String apkPath, float pixelRatio,
+ int availableProcessors, long totalMemory);
- public void setVisibleCoordinateBounds(LatLng[] coordinates, RectF padding, double direction, long duration) {
- nativeSetVisibleCoordinateBounds(nativeMapViewPtr, coordinates, padding, direction, duration);
- }
+ private native void nativeDestroy(long nativeMapViewPtr);
- public void onLowMemory() {
- nativeOnLowMemory(nativeMapViewPtr);
- }
+ private native void nativeInitializeDisplay(long nativeMapViewPtr);
- public void setDebug(boolean debug) {
- nativeSetDebug(nativeMapViewPtr, debug);
- }
+ private native void nativeTerminateDisplay(long nativeMapViewPtr);
- public void cycleDebugOptions() {
- nativeToggleDebug(nativeMapViewPtr);
- }
+ private native void nativeInitializeContext(long nativeMapViewPtr);
- public boolean getDebug() {
- return nativeGetDebug(nativeMapViewPtr);
- }
+ private native void nativeTerminateContext(long nativeMapViewPtr);
- public boolean isFullyLoaded() {
- return nativeIsFullyLoaded(nativeMapViewPtr);
- }
-
- public void setReachability(boolean status) {
- nativeSetReachability(nativeMapViewPtr, status);
- }
-
- public double getMetersPerPixelAtLatitude(double lat, double zoom) {
- return nativeGetMetersPerPixelAtLatitude(nativeMapViewPtr, lat, zoom);
- }
-
- public ProjectedMeters projectedMetersForLatLng(LatLng latLng) {
- return nativeProjectedMetersForLatLng(nativeMapViewPtr, latLng.getLatitude(), latLng.getLongitude());
- }
-
- public LatLng latLngForProjectedMeters(ProjectedMeters projectedMeters) {
- return nativeLatLngForProjectedMeters(nativeMapViewPtr, projectedMeters.getNorthing(), projectedMeters.getEasting());
- }
-
- public PointF pixelForLatLng(LatLng latLng) {
- return nativePixelForLatLng(nativeMapViewPtr, latLng.getLatitude(), latLng.getLongitude());
- }
-
- public LatLng latLngForPixel(PointF pixel) {
- return nativeLatLngForPixel(nativeMapViewPtr, pixel.x, pixel.y);
- }
-
- public double getTopOffsetPixelsForAnnotationSymbol(String symbolName) {
- return nativeGetTopOffsetPixelsForAnnotationSymbol(nativeMapViewPtr, symbolName);
- }
-
- public void jumpTo(double angle, LatLng center, double pitch, double zoom) {
- nativeJumpTo(nativeMapViewPtr, angle, center.getLatitude(), center.getLongitude(), pitch, zoom);
- }
+ private native void nativeCreateSurface(long nativeMapViewPtr,
+ Surface surface);
- public void easeTo(double angle, LatLng center, long duration, double pitch, double zoom, boolean easingInterpolator) {
- nativeEaseTo(nativeMapViewPtr, angle, center.getLatitude(), center.getLongitude(), duration, pitch, zoom, easingInterpolator);
- }
+ private native void nativeDestroySurface(long nativeMapViewPtr);
- public void flyTo(double angle, LatLng center, long duration, double pitch, double zoom) {
- nativeFlyTo(nativeMapViewPtr, angle, center.getLatitude(), center.getLongitude(), duration, pitch, zoom);
- }
+ private native void nativeUpdate(long nativeMapViewPtr);
- public double[] getCameraValues() {
- return nativeGetCameraValues(nativeMapViewPtr);
- }
+ private native void nativeRender(long nativeMapViewPtr);
- // Runtime style Api
+ private native void nativeViewResize(long nativeMapViewPtr, int width, int height);
- public Layer getLayer(String layerId) {
- return nativeGetLayer(nativeMapViewPtr, layerId);
- }
+ private native void nativeFramebufferResize(long nativeMapViewPtr, int fbWidth, int fbHeight);
- public void addLayer(@NonNull Layer layer, @Nullable String before) {
- nativeAddLayer(nativeMapViewPtr, layer.getNativePtr(), before);
- layer.invalidate();
- }
+ private native void nativeAddClass(long nativeMapViewPtr, String clazz);
- public void removeLayer(@NonNull String layerId) throws NoSuchLayerException {
- nativeRemoveLayer(nativeMapViewPtr, layerId);
- }
+ private native void nativeRemoveClass(long nativeMapViewPtr, String clazz);
- public Source getSource(@NonNull String sourceId) {
- return nativeGetSource(nativeMapViewPtr, sourceId);
- }
+ private native boolean nativeHasClass(long nativeMapViewPtr, String clazz);
- public void addSource(@NonNull Source source) {
- nativeAddSource(nativeMapViewPtr, source.getNativePtr());
- }
+ private native void nativeSetClasses(long nativeMapViewPtr,
+ List<String> classes);
- public void removeSource(@NonNull String sourceId) throws NoSuchSourceException {
- nativeRemoveSource(nativeMapViewPtr, sourceId);
- }
+ private native List<String> nativeGetClasses(long nativeMapViewPtr);
- public void addImage(@NonNull String name, @NonNull Bitmap image) {
- //Check/correct config
- if (image.getConfig() != Bitmap.Config.ARGB_8888) {
- image = image.copy(Bitmap.Config.ARGB_8888, false);
- }
+ private native void nativeSetStyleUrl(long nativeMapViewPtr, String url);
- //Get pixels
- ByteBuffer buffer = ByteBuffer.allocate(image.getByteCount());
- image.copyPixelsToBuffer(buffer);
+ private native String nativeGetStyleUrl(long nativeMapViewPtr);
- //Determine pixel ratio
- float density = image.getDensity() == Bitmap.DENSITY_NONE ? Bitmap.DENSITY_NONE : image.getDensity();
- float pixelRatio = density / DisplayMetrics.DENSITY_DEFAULT;
+ private native void nativeSetStyleJson(long nativeMapViewPtr, String newStyleJson);
- nativeAddImage(nativeMapViewPtr, name, image.getWidth(), image.getHeight(), pixelRatio, buffer.array());
- }
+ private native String nativeGetStyleJson(long nativeMapViewPtr);
- public void removeImage(String name) {
- nativeRemoveImage(nativeMapViewPtr, name);
- }
+ private native void nativeSetAccessToken(long nativeMapViewPtr, String accessToken);
- // Feature querying
+ private native String nativeGetAccessToken(long nativeMapViewPtr);
- @NonNull
- public List<Feature> queryRenderedFeatures(PointF coordinates, String... layerIds) {
- Feature[] features = nativeQueryRenderedFeaturesForPoint(nativeMapViewPtr, coordinates.x / pixelRatio, coordinates.y / pixelRatio, layerIds);
- return features != null ? Arrays.asList(features) : new ArrayList<Feature>();
- }
+ private native void nativeCancelTransitions(long nativeMapViewPtr);
- @NonNull
- public List<Feature> queryRenderedFeatures(RectF coordinates, String... layerIds) {
- Feature[] features = nativeQueryRenderedFeaturesForBox(
- nativeMapViewPtr,
- coordinates.left / pixelRatio,
- coordinates.top / pixelRatio,
- coordinates.right / pixelRatio,
- coordinates.bottom / pixelRatio,
- layerIds);
- return features != null ? Arrays.asList(features) : new ArrayList<Feature>();
- }
+ private native void nativeSetGestureInProgress(long nativeMapViewPtr, boolean inProgress);
- public void scheduleTakeSnapshot() {
- nativeScheduleTakeSnapshot(nativeMapViewPtr);
- }
+ private native void nativeMoveBy(long nativeMapViewPtr, double dx,
+ double dy, long duration);
- public void setApiBaseUrl(String baseUrl) {
- nativeSetAPIBaseURL(nativeMapViewPtr, baseUrl);
- }
-
- //
- // Callbacks
- //
-
- protected void onInvalidate() {
- mapView.onInvalidate();
- }
-
- protected void onMapChanged(int rawChange) {
- mapView.onMapChanged(rawChange);
- }
-
- protected void onFpsChanged(double fps) {
- mapView.onFpsChanged(fps);
- }
-
- protected void onSnapshotReady(byte[] bytes) {
- mapView.onSnapshotReady(bytes);
- }
-
- //
- // JNI methods
- //
-
- private native long nativeCreate(String cachePath, String dataPath, String apkPath, float pixelRatio, int availableProcessors, long totalMemory);
-
- private native void nativeDestroy(long nativeMapViewPtr);
-
- private native void nativeInitializeDisplay(long nativeMapViewPtr);
-
- private native void nativeTerminateDisplay(long nativeMapViewPtr);
-
- private native void nativeInitializeContext(long nativeMapViewPtr);
-
- private native void nativeTerminateContext(long nativeMapViewPtr);
-
- private native void nativeCreateSurface(long nativeMapViewPtr,
- Surface surface);
-
- private native void nativeDestroySurface(long nativeMapViewPtr);
-
- private native void nativeUpdate(long nativeMapViewPtr);
-
- private native void nativeRender(long nativeMapViewPtr);
-
- private native void nativeViewResize(long nativeMapViewPtr, int width, int height);
-
- private native void nativeFramebufferResize(long nativeMapViewPtr, int fbWidth, int fbHeight);
-
- private native void nativeAddClass(long nativeMapViewPtr, String clazz);
-
- private native void nativeRemoveClass(long nativeMapViewPtr, String clazz);
-
- private native boolean nativeHasClass(long nativeMapViewPtr, String clazz);
-
- private native void nativeSetClasses(long nativeMapViewPtr,
- List<String> classes);
-
- private native List<String> nativeGetClasses(long nativeMapViewPtr);
-
- private native void nativeSetStyleUrl(long nativeMapViewPtr, String url);
+ private native void nativeSetLatLng(long nativeMapViewPtr, double latitude, double longitude,
+ long duration);
- private native void nativeSetStyleJson(long nativeMapViewPtr, String newStyleJson);
+ private native LatLng nativeGetLatLng(long nativeMapViewPtr);
- private native String nativeGetStyleJson(long nativeMapViewPtr);
+ private native void nativeResetPosition(long nativeMapViewPtr);
- private native void nativeSetAccessToken(long nativeMapViewPtr, String accessToken);
+ private native double nativeGetPitch(long nativeMapViewPtr);
- private native String nativeGetAccessToken(long nativeMapViewPtr);
+ private native void nativeSetPitch(long nativeMapViewPtr, double pitch, long duration);
- private native void nativeCancelTransitions(long nativeMapViewPtr);
+ private native void nativeScaleBy(long nativeMapViewPtr, double ds,
+ double cx, double cy, long duration);
- private native void nativeSetGestureInProgress(long nativeMapViewPtr, boolean inProgress);
+ private native void nativeSetScale(long nativeMapViewPtr, double scale,
+ double cx, double cy, long duration);
- private native void nativeMoveBy(long nativeMapViewPtr, double dx,
- double dy, long duration);
+ private native double nativeGetScale(long nativeMapViewPtr);
- private native void nativeSetLatLng(long nativeMapViewPtr, double latitude, double longitude,
- long duration);
+ private native void nativeSetZoom(long nativeMapViewPtr, double zoom,
+ long duration);
- private native LatLng nativeGetLatLng(long nativeMapViewPtr);
+ private native double nativeGetZoom(long nativeMapViewPtr);
- private native void nativeResetPosition(long nativeMapViewPtr);
+ private native void nativeResetZoom(long nativeMapViewPtr);
- private native double nativeGetPitch(long nativeMapViewPtr);
+ private native void nativeSetMinZoom(long nativeMapViewPtr, double zoom);
- private native void nativeSetPitch(long nativeMapViewPtr, double pitch, long duration);
+ private native double nativeGetMinZoom(long nativeMapViewPtr);
- private native void nativeScaleBy(long nativeMapViewPtr, double ds,
- double cx, double cy, long duration);
+ private native void nativeSetMaxZoom(long nativeMapViewPtr, double zoom);
- private native void nativeSetScale(long nativeMapViewPtr, double scale,
- double cx, double cy, long duration);
+ private native double nativeGetMaxZoom(long nativeMapViewPtr);
- private native double nativeGetScale(long nativeMapViewPtr);
+ private native void nativeRotateBy(long nativeMapViewPtr, double sx,
+ double sy, double ex, double ey, long duration);
- private native void nativeSetZoom(long nativeMapViewPtr, double zoom,
- long duration);
+ private native void nativeSetContentPadding(long nativeMapViewPtr, double top, double left, double bottom,
+ double right);
- private native double nativeGetZoom(long nativeMapViewPtr);
+ private native void nativeSetBearing(long nativeMapViewPtr, double degrees,
+ long duration);
- private native void nativeResetZoom(long nativeMapViewPtr);
+ private native void nativeSetBearingXY(long nativeMapViewPtr, double degrees,
+ double cx, double cy);
- private native void nativeSetMinZoom(long nativeMapViewPtr, double zoom);
+ private native double nativeGetBearing(long nativeMapViewPtr);
- private native double nativeGetMinZoom(long nativeMapViewPtr);
+ private native void nativeResetNorth(long nativeMapViewPtr);
- private native void nativeSetMaxZoom(long nativeMapViewPtr, double zoom);
+ private native void nativeUpdateMarker(long nativeMapViewPtr, long markerId, double lat, double lon, String iconId);
- private native double nativeGetMaxZoom(long nativeMapViewPtr);
+ private native long[] nativeAddMarkers(long nativeMapViewPtr, Marker[] markers);
- private native void nativeRotateBy(long nativeMapViewPtr, double sx,
- double sy, double ex, double ey, long duration);
+ private native long[] nativeAddPolylines(long nativeMapViewPtr, Polyline[] polylines);
- private native void nativeSetContentPadding(long nativeMapViewPtr, double top, double left, double bottom, double right);
+ private native long[] nativeAddPolygons(long nativeMapViewPtr, Polygon[] polygons);
- private native void nativeSetBearing(long nativeMapViewPtr, double degrees,
- long duration);
+ private native void nativeRemoveAnnotations(long nativeMapViewPtr, long[] id);
- private native void nativeSetBearingXY(long nativeMapViewPtr, double degrees,
- double cx, double cy);
+ private native long[] nativeQueryPointAnnotations(long nativeMapViewPtr, RectF rect);
- private native double nativeGetBearing(long nativeMapViewPtr);
+ private native void nativeAddAnnotationIcon(long nativeMapViewPtr, String symbol,
+ int width, int height, float scale, byte[] pixels);
- private native void nativeResetNorth(long nativeMapViewPtr);
+ private native void nativeSetVisibleCoordinateBounds(long nativeMapViewPtr, LatLng[] coordinates,
+ RectF padding, double direction, long duration);
- private native void nativeUpdateMarker(long nativeMapViewPtr, long markerId, double lat, double lon, String iconId);
+ private native void nativeOnLowMemory(long nativeMapViewPtr);
- private native long[] nativeAddMarkers(long nativeMapViewPtr, Marker[] markers);
+ private native void nativeSetDebug(long nativeMapViewPtr, boolean debug);
- private native long[] nativeAddPolylines(long nativeMapViewPtr, Polyline[] polylines);
+ private native void nativeToggleDebug(long nativeMapViewPtr);
- private native long[] nativeAddPolygons(long nativeMapViewPtr, Polygon[] polygons);
+ private native boolean nativeGetDebug(long nativeMapViewPtr);
- private native void nativeRemoveAnnotations(long nativeMapViewPtr, long[] id);
+ private native boolean nativeIsFullyLoaded(long nativeMapViewPtr);
- private native long[] nativeQueryPointAnnotations(long nativeMapViewPtr, RectF rect);
+ private native void nativeSetReachability(long nativeMapViewPtr, boolean status);
- private native void nativeAddAnnotationIcon(long nativeMapViewPtr, String symbol,
- int width, int height, float scale, byte[] pixels);
+ private native double nativeGetMetersPerPixelAtLatitude(long nativeMapViewPtr, double lat, double zoom);
- private native void nativeSetVisibleCoordinateBounds(long nativeMapViewPtr, LatLng[] coordinates,
- RectF padding, double direction, long duration);
+ private native ProjectedMeters nativeProjectedMetersForLatLng(long nativeMapViewPtr, double latitude,
+ double longitude);
- private native void nativeOnLowMemory(long nativeMapViewPtr);
+ private native LatLng nativeLatLngForProjectedMeters(long nativeMapViewPtr, double northing, double easting);
- private native void nativeSetDebug(long nativeMapViewPtr, boolean debug);
+ private native PointF nativePixelForLatLng(long nativeMapViewPtr, double lat, double lon);
- private native void nativeToggleDebug(long nativeMapViewPtr);
+ private native LatLng nativeLatLngForPixel(long nativeMapViewPtr, float x, float y);
- private native boolean nativeGetDebug(long nativeMapViewPtr);
+ private native double nativeGetTopOffsetPixelsForAnnotationSymbol(long nativeMapViewPtr, String symbolName);
- private native boolean nativeIsFullyLoaded(long nativeMapViewPtr);
+ private native void nativeJumpTo(long nativeMapViewPtr, double angle, double latitude, double longitude,
+ double pitch, double zoom);
- private native void nativeSetReachability(long nativeMapViewPtr, boolean status);
+ private native void nativeEaseTo(long nativeMapViewPtr, double angle, double latitude, double longitude,
+ long duration, double pitch, double zoom, boolean easingInterpolator);
- private native double nativeGetMetersPerPixelAtLatitude(long nativeMapViewPtr, double lat, double zoom);
+ private native void nativeFlyTo(long nativeMapViewPtr, double angle, double latitude, double longitude,
+ long duration, double pitch, double zoom);
- private native ProjectedMeters nativeProjectedMetersForLatLng(long nativeMapViewPtr, double latitude, double longitude);
+ private native double[] nativeGetCameraValues(long nativeMapViewPtr);
- private native LatLng nativeLatLngForProjectedMeters(long nativeMapViewPtr, double northing, double easting);
+ private native Layer nativeGetLayer(long nativeMapViewPtr, String layerId);
- private native PointF nativePixelForLatLng(long nativeMapViewPtr, double lat, double lon);
+ private native void nativeAddLayer(long nativeMapViewPtr, long layerPtr, String before);
- private native LatLng nativeLatLngForPixel(long nativeMapViewPtr, float x, float y);
+ private native void nativeRemoveLayerById(long nativeMapViewPtr, String layerId) throws NoSuchLayerException;
- private native double nativeGetTopOffsetPixelsForAnnotationSymbol(long nativeMapViewPtr, String symbolName);
+ private native void nativeRemoveLayer(long nativeMapViewPtr, long layerId) throws NoSuchLayerException;
- private native void nativeJumpTo(long nativeMapViewPtr, double angle, double latitude, double longitude, double pitch, double zoom);
+ private native Source nativeGetSource(long nativeMapViewPtr, String sourceId);
- private native void nativeEaseTo(long nativeMapViewPtr, double angle, double latitude, double longitude, long duration, double pitch, double zoom, boolean easingInterpolator);
+ private native void nativeAddSource(long nativeMapViewPtr, long nativeSourcePtr);
- private native void nativeFlyTo(long nativeMapViewPtr, double angle, double latitude, double longitude, long duration, double pitch, double zoom);
+ private native void nativeRemoveSourceById(long nativeMapViewPtr, String sourceId) throws NoSuchSourceException;
- private native double[] nativeGetCameraValues(long nativeMapViewPtr);
+ private native void nativeRemoveSource(long nativeMapViewPtr, long sourcePtr) throws NoSuchSourceException;
- private native Layer nativeGetLayer(long nativeMapViewPtr, String layerId);
+ private native void nativeAddImage(long nativeMapViewPtr, String name, int width, int height, float pixelRatio,
+ byte[] array);
- private native void nativeAddLayer(long nativeMapViewPtr, long layerPtr, String before);
+ private native void nativeRemoveImage(long nativeMapViewPtr, String name);
- private native void nativeRemoveLayer(long nativeMapViewPtr, String layerId) throws NoSuchLayerException;
+ private native void nativeUpdatePolygon(long nativeMapViewPtr, long polygonId, Polygon polygon);
- private native Source nativeGetSource(long nativeMapViewPtr, String sourceId);
+ private native void nativeUpdatePolyline(long nativeMapviewPtr, long polylineId, Polyline polyline);
- private native void nativeAddSource(long nativeMapViewPtr, long nativeSourcePtr);
+ private native void nativeScheduleTakeSnapshot(long nativeMapViewPtr);
- private native void nativeRemoveSource(long nativeMapViewPtr, String sourceId) throws NoSuchSourceException;
+ private native Feature[] nativeQueryRenderedFeaturesForPoint(long nativeMapViewPtr, float x, float y, String[]
+ layerIds);
- private native void nativeAddImage(long nativeMapViewPtr, String name, int width, int height, float pixelRatio, byte[] array);
+ private native Feature[] nativeQueryRenderedFeaturesForBox(long nativeMapViewPtr, float left, float top, float right,
+ float bottom, String[] layerIds);
- private native void nativeRemoveImage(long nativeMapViewPtr, String name);
+ private native void nativeSetAPIBaseURL(long nativeMapViewPtr, String baseUrl);
- private native void nativeUpdatePolygon(long nativeMapViewPtr, long polygonId, Polygon polygon);
+ int getWidth() {
+ return mapView.getWidth();
+ }
- private native void nativeUpdatePolyline(long nativeMapviewPtr, long polylineId, Polyline polyline);
+ int getHeight() {
+ return mapView.getHeight();
+ }
- private native void nativeScheduleTakeSnapshot(long nativeMapViewPtr);
+ //
+ // MapChangeEvents
+ //
- private native Feature[] nativeQueryRenderedFeaturesForPoint(long nativeMapViewPtr, float x, float y, String[] layerIds);
+ void addOnMapChangedListener(@NonNull MapView.OnMapChangedListener listener) {
+ onMapChangedListeners.add(listener);
+ }
- private native Feature[] nativeQueryRenderedFeaturesForBox(long nativeMapViewPtr, float left, float top, float right, float bottom, String[] layerIds);
+ void removeOnMapChangedListener(@NonNull MapView.OnMapChangedListener listener) {
+ onMapChangedListeners.remove(listener);
+ }
- private native void nativeSetAPIBaseURL(long nativeMapViewPtr, String baseUrl);
+ void onMapChangedEventDispatch(int mapChange) {
+ if (onMapChangedListeners != null) {
+ for (MapView.OnMapChangedListener onMapChangedListener : onMapChangedListeners) {
+ onMapChangedListener.onMapChanged(mapChange);
+ }
+ }
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/OnMapReadyCallback.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/OnMapReadyCallback.java
index 7ace9ec2d3..fc92e5028b 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/OnMapReadyCallback.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/OnMapReadyCallback.java
@@ -4,16 +4,17 @@ package com.mapbox.mapboxsdk.maps;
* Interface definition for a callback to be invoked when the map is ready to be used.
* <p>
* Once an instance of this interface is set on a {@link MapFragment} or {@link MapView} object,
- * the onMapReady(MapboxMap) method is triggered when the map is ready to be used and provides an instance of {@link MapboxMap}.
+ * the onMapReady(MapboxMap) method is triggered when the map is ready to be used and provides an instance of
+ * {@link MapboxMap}.
* </p>
*/
public interface OnMapReadyCallback {
- /**
- * Called when the map is ready to be used.
- *
- * @param mapboxMap An instance of MapboxMap associated with the {@link MapFragment} or
- * {@link MapView} that defines the callback.
- */
- void onMapReady(MapboxMap mapboxMap);
+ /**
+ * Called when the map is ready to be used.
+ *
+ * @param mapboxMap An instance of MapboxMap associated with the {@link MapFragment} or
+ * {@link MapView} that defines the callback.
+ */
+ void onMapReady(MapboxMap mapboxMap);
}
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 e06ed38433..b7f93cc913 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,93 +15,106 @@ import com.mapbox.mapboxsdk.geometry.VisibleRegion;
*/
public class Projection {
- 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;
- }
-
- /**
- * <p>
- * Returns the distance spanned by one pixel at the specified latitude and current zoom level.
- * </p>
- * The distance between pixels decreases as the latitude approaches the poles.
- * This relationship parallels the relationship between longitudinal coordinates at different latitudes.
- *
- * @param latitude The latitude for which to return the value.
- * @return The distance measured in meters.
- */
- public double getMetersPerPixelAtLatitude(@FloatRange(from = -90, to = 90) double latitude) {
- return mapView.getMetersPerPixelAtLatitude(latitude);
- }
-
- /**
- * Returns the geographic location that corresponds to a screen location.
- * The screen location is specified in screen pixels (not display pixels) relative to the
- * top left of the map (not the top left of the whole screen).
- *
- * @param point A Point on the screen in screen pixels.
- * @return The LatLng corresponding to the point on the screen, or null if the ray through
- * the given screen point does not intersect the ground plane.
- */
- public LatLng fromScreenLocation(PointF point) {
- screenLocationPoint.set(point.x / screenDensity, point.y / screenDensity);
- return mapView.fromNativeScreenLocation(screenLocationPoint);
- }
-
- /**
- * Gets a projection of the viewing frustum for converting between screen coordinates and
- * geo-latitude/longitude coordinates.
- *
- * @return The projection of the viewing frustum in its current state.
- */
- public VisibleRegion getVisibleRegion() {
- LatLngBounds.Builder builder = new LatLngBounds.Builder();
-
- float left = mapView.getContentPaddingLeft();
- float right = mapView.getWidth() - mapView.getContentPaddingRight();
- float top = mapView.getContentPaddingTop();
- float bottom = mapView.getHeight() - mapView.getContentPaddingBottom();
-
- LatLng topLeft = fromScreenLocation(new PointF(left, top));
- LatLng topRight = fromScreenLocation(new PointF(right, top));
- LatLng bottomRight = fromScreenLocation(new PointF(right, bottom));
- LatLng bottomLeft = fromScreenLocation(new PointF(left, bottom));
-
- builder.include(topLeft)
- .include(topRight)
- .include(bottomRight)
- .include(bottomLeft);
-
- return new VisibleRegion(topLeft, topRight, bottomLeft, bottomRight, builder.build());
- }
-
- /**
- * Returns a screen location that corresponds to a geographical coordinate (LatLng).
- * The screen location is in screen pixels (not display pixels) relative to the top left
- * of the map (not of the whole screen).
- *
- * @param location A LatLng on the map to convert to a screen location.
- * @return A Point representing the screen location in screen pixels.
- */
- public PointF toScreenLocation(LatLng location) {
- PointF pointF = mapView.toNativeScreenLocation(location);
- pointF.set(pointF.x * screenDensity, pointF.y * screenDensity);
- return pointF;
- }
-
- /**
- * Calculates a zoom level based on minimum scale and current scale from MapView
- *
- * @param minScale The minimum scale to calculate the zoom level.
- * @return zoom level that fits the MapView.
- */
- public double calculateZoom(float minScale) {
- return Math.log(mapView.getScale() * minScale) / Math.log(2);
- }
+ private final NativeMapView nativeMapView;
+ private int[] contentPadding;
+
+ Projection(@NonNull NativeMapView nativeMapView) {
+ this.nativeMapView = nativeMapView;
+ this.contentPadding = new int[] {0, 0, 0, 0};
+ }
+
+ void setContentPadding(int[] contentPadding, int[] userLocationViewPadding) {
+ this.contentPadding = contentPadding;
+
+ int[] padding = new int[] {
+ contentPadding[0] + userLocationViewPadding[0],
+ contentPadding[1] + userLocationViewPadding[1],
+ contentPadding[2] + userLocationViewPadding[2],
+ contentPadding[3] + userLocationViewPadding[3]
+ };
+
+ nativeMapView.setContentPadding(padding);
+ }
+
+ int[] getContentPadding() {
+ return contentPadding;
+ }
+
+ public void invalidateContentPadding(int[] userLocationViewPadding) {
+ setContentPadding(contentPadding, userLocationViewPadding);
+ }
+
+ /**
+ * <p>
+ * Returns the distance spanned by one pixel at the specified latitude and current zoom level.
+ * </p>
+ * The distance between pixels decreases as the latitude approaches the poles.
+ * This relationship parallels the relationship between longitudinal coordinates at different latitudes.
+ *
+ * @param latitude The latitude for which to return the value.
+ * @return The distance measured in meters.
+ */
+ public double getMetersPerPixelAtLatitude(@FloatRange(from = -90, to = 90) double latitude) {
+ return nativeMapView.getMetersPerPixelAtLatitude(latitude);
+ }
+
+ /**
+ * Returns the geographic location that corresponds to a screen location.
+ * The screen location is specified in screen pixels (not display pixels) relative to the
+ * top left of the map (not the top left of the whole screen).
+ *
+ * @param point A Point on the screen in screen pixels.
+ * @return The LatLng corresponding to the point on the screen, or null if the ray through
+ * the given screen point does not intersect the ground plane.
+ */
+ public LatLng fromScreenLocation(PointF point) {
+ return nativeMapView.latLngForPixel(point);
+ }
+
+ /**
+ * Gets a projection of the viewing frustum for converting between screen coordinates and
+ * geo-latitude/longitude coordinates.
+ *
+ * @return The projection of the viewing frustum in its current state.
+ */
+ public VisibleRegion getVisibleRegion() {
+ LatLngBounds.Builder builder = new LatLngBounds.Builder();
+
+ float left = contentPadding[0];
+ float right = nativeMapView.getWidth() - contentPadding[2];
+ float top = contentPadding[1];
+ float bottom = nativeMapView.getHeight() - contentPadding[3];
+
+ LatLng topLeft = fromScreenLocation(new PointF(left, top));
+ LatLng topRight = fromScreenLocation(new PointF(right, top));
+ LatLng bottomRight = fromScreenLocation(new PointF(right, bottom));
+ LatLng bottomLeft = fromScreenLocation(new PointF(left, bottom));
+
+ builder.include(topLeft)
+ .include(topRight)
+ .include(bottomRight)
+ .include(bottomLeft);
+
+ return new VisibleRegion(topLeft, topRight, bottomLeft, bottomRight, builder.build());
+ }
+
+ /**
+ * Returns a screen location that corresponds to a geographical coordinate (LatLng).
+ * The screen location is in screen pixels (not display pixels) relative to the top left
+ * of the map (not of the whole screen).
+ *
+ * @param location A LatLng on the map to convert to a screen location.
+ * @return A Point representing the screen location in screen pixels.
+ */
+ public PointF toScreenLocation(LatLng location) {
+ return nativeMapView.pixelForLatLng(location);
+ }
+
+ float getHeight() {
+ return nativeMapView.getHeight();
+ }
+
+ float getWidth() {
+ return nativeMapView.getWidth();
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/SupportMapFragment.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/SupportMapFragment.java
index 72674c3bc9..09b87333b6 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/SupportMapFragment.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/SupportMapFragment.java
@@ -1,23 +1,18 @@
package com.mapbox.mapboxsdk.maps;
import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
-import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import com.mapbox.mapboxsdk.MapboxAccountManager;
import com.mapbox.mapboxsdk.R;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
-import com.mapbox.mapboxsdk.exceptions.InvalidAccessTokenException;
/**
* Support Fragment wrapper around a map view.
@@ -35,202 +30,155 @@ import com.mapbox.mapboxsdk.exceptions.InvalidAccessTokenException;
*/
public class SupportMapFragment extends Fragment {
- private MapView map;
- private OnMapReadyCallback onMapReadyCallback;
-
- /**
- * Creates a MapFragment instance
- *
- * @return MapFragment created
- */
- public static SupportMapFragment newInstance() {
- return new SupportMapFragment();
- }
-
- /**
- * Creates a MapFragment instance
- *
- * @param mapboxMapOptions The configuration options to be used.
- * @return MapFragment created.
- */
- public static SupportMapFragment newInstance(@Nullable MapboxMapOptions mapboxMapOptions) {
- SupportMapFragment mapFragment = new SupportMapFragment();
- Bundle bundle = new Bundle();
- bundle.putParcelable(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS, mapboxMapOptions);
- mapFragment.setArguments(bundle);
- return mapFragment;
- }
-
- /**
- * Creates the fragment view hierarchy.
- *
- * @param inflater Inflater used to inflate content.
- * @param container The parent layout for the map fragment.
- * @param savedInstanceState The saved instance state for the map fragment.
- * @return The view created
- */
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- super.onCreateView(inflater, container, savedInstanceState);
- Context context = inflater.getContext();
- MapboxMapOptions options = null;
-
- // Get bundle
- Bundle bundle = getArguments();
- if (bundle != null && bundle.containsKey(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS)) {
- options = bundle.getParcelable(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS);
- }
-
- // Assign an AccessToken if needed
- if (options == null || options.getAccessToken() == null) {
- String token = null;
- if (MapboxAccountManager.getInstance() != null) {
- token = MapboxAccountManager.getInstance().getAccessToken();
- } else {
- token = getToken(inflater.getContext());
- }
- if (TextUtils.isEmpty(token)) {
- throw new InvalidAccessTokenException();
- }
- if (options == null) {
- options = new MapboxMapOptions().accessToken(token);
- } else {
- options.accessToken(token);
- }
- }
-
- Drawable foregroundDrawable = options.getMyLocationForegroundDrawable();
- Drawable foregroundBearingDrawable = options.getMyLocationForegroundBearingDrawable();
- if (foregroundDrawable == null || foregroundBearingDrawable == null) {
- if (foregroundDrawable == null) {
- foregroundDrawable = ContextCompat.getDrawable(context, R.drawable.ic_mylocationview_normal);
- }
- if (foregroundBearingDrawable == null) {
- foregroundBearingDrawable = ContextCompat.getDrawable(context, R.drawable.ic_mylocationview_bearing);
- }
- options.myLocationForegroundDrawables(foregroundDrawable, foregroundBearingDrawable);
- }
-
- if (options.getMyLocationBackgroundDrawable() == null) {
- options.myLocationBackgroundDrawable(ContextCompat.getDrawable(context, R.drawable.ic_mylocationview_background));
- }
-
- return map = new MapView(inflater.getContext(), options);
- }
-
- /**
- * <p>
- * Returns the Mapbox access token set in the app resources.
- * </p>
- * It will first search the application manifest for a {@link MapboxConstants#KEY_META_DATA_MANIFEST}
- * meta-data value. If not found it will then attempt to load the access token from the
- * {@code res/raw/token.txt} development file.
- *
- * @param context The {@link Context} of the {@link android.app.Activity} or {@link android.app.Fragment}.
- * @return The Mapbox access token or null if not found.
- * @see MapboxConstants#KEY_META_DATA_MANIFEST
- * @deprecated As of release 4.1.0, replaced by {@link com.mapbox.mapboxsdk.MapboxAccountManager#start(Context, String)}
- */
- @Deprecated
- private String getToken(@NonNull Context context) {
- try {
- // read out AndroidManifest
- PackageManager packageManager = context.getPackageManager();
- ApplicationInfo appInfo = packageManager.getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
- String token = appInfo.metaData.getString(MapboxConstants.KEY_META_DATA_MANIFEST);
- if (token == null || token.isEmpty()) {
- throw new IllegalArgumentException();
- }
- return token;
- } catch (Exception exception) {
- // use fallback on string resource, used for development
- int tokenResId = context.getResources().getIdentifier("mapbox_access_token", "string", context.getPackageName());
- return tokenResId != 0 ? context.getString(tokenResId) : null;
- }
- }
-
- /**
- * Called when the fragment view hierarchy is created.
- *
- * @param view The content view of the fragment
- * @param savedInstanceState THe saved instance state of the framgnt
- */
- @Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- map.onCreate(savedInstanceState);
- }
-
- /**
- * Called when the fragment is visible for the users.
- */
- @Override
- public void onStart() {
- super.onStart();
- map.getMapAsync(onMapReadyCallback);
- }
-
- /**
- * Called when the fragment is ready to be interacted with.
- */
- @Override
- public void onResume() {
- super.onResume();
- map.onResume();
- }
-
- /**
- * Called when the fragment is pausing.
- */
- @Override
- public void onPause() {
- super.onPause();
- map.onPause();
+ private MapView map;
+ private OnMapReadyCallback onMapReadyCallback;
+
+ /**
+ * Creates a MapFragment instance
+ *
+ * @return MapFragment created
+ */
+ public static SupportMapFragment newInstance() {
+ return new SupportMapFragment();
+ }
+
+ /**
+ * Creates a MapFragment instance
+ *
+ * @param mapboxMapOptions The configuration options to be used.
+ * @return MapFragment created.
+ */
+ public static SupportMapFragment newInstance(@Nullable MapboxMapOptions mapboxMapOptions) {
+ SupportMapFragment mapFragment = new SupportMapFragment();
+ Bundle bundle = new Bundle();
+ bundle.putParcelable(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS, mapboxMapOptions);
+ mapFragment.setArguments(bundle);
+ return mapFragment;
+ }
+
+ /**
+ * Creates the fragment view hierarchy.
+ *
+ * @param inflater Inflater used to inflate content.
+ * @param container The parent layout for the map fragment.
+ * @param savedInstanceState The saved instance state for the map fragment.
+ * @return The view created
+ */
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ Context context = inflater.getContext();
+ MapboxMapOptions options = null;
+
+ // Get bundle
+ Bundle bundle = getArguments();
+ if (bundle != null && bundle.containsKey(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS)) {
+ options = bundle.getParcelable(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS);
}
- /**
- * Called when the fragment state needs to be saved.
- *
- * @param outState The saved state
- */
- @Override
- public void onSaveInstanceState(@NonNull Bundle outState) {
- super.onSaveInstanceState(outState);
- map.onSaveInstanceState(outState);
+ Drawable foregroundDrawable = options.getMyLocationForegroundDrawable();
+ Drawable foregroundBearingDrawable = options.getMyLocationForegroundBearingDrawable();
+ if (foregroundDrawable == null || foregroundBearingDrawable == null) {
+ if (foregroundDrawable == null) {
+ foregroundDrawable = ContextCompat.getDrawable(context, R.drawable.mapbox_mylocation_icon_default);
+ }
+ if (foregroundBearingDrawable == null) {
+ foregroundBearingDrawable = ContextCompat.getDrawable(context, R.drawable.mapbox_mylocation_icon_bearing);
+ }
+ options.myLocationForegroundDrawables(foregroundDrawable, foregroundBearingDrawable);
}
- /**
- * Called when the fragment is no longer visible for the user.
- */
- @Override
- public void onStop() {
- super.onStop();
+ if (options.getMyLocationBackgroundDrawable() == null) {
+ options.myLocationBackgroundDrawable(ContextCompat.getDrawable(context, R.drawable.mapbox_mylocation_bg_shape));
}
- /**
- * Called when the fragment receives onLowMemory call from the hosting Activity.
- */
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- map.onLowMemory();
- }
-
- /**
- * Called when the fragment is view hiearchy is being destroyed.
- */
- @Override
- public void onDestroyView() {
- super.onDestroyView();
- map.onDestroy();
- }
-
- /**
- * Sets a callback object which will be triggered when the MapboxMap instance is ready to be used.
- *
- * @param onMapReadyCallback The callback to be invoked.
- */
- public void getMapAsync(@NonNull final OnMapReadyCallback onMapReadyCallback) {
- this.onMapReadyCallback = onMapReadyCallback;
- }
-}
+ return map = new MapView(inflater.getContext(), options);
+ }
+
+ /**
+ * Called when the fragment view hierarchy is created.
+ *
+ * @param view The content view of the fragment
+ * @param savedInstanceState THe saved instance state of the framgnt
+ */
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ map.onCreate(savedInstanceState);
+ }
+
+ /**
+ * Called when the fragment is visible for the users.
+ */
+ @Override
+ public void onStart() {
+ super.onStart();
+ map.onStart();
+ map.getMapAsync(onMapReadyCallback);
+ }
+
+ /**
+ * Called when the fragment is ready to be interacted with.
+ */
+ @Override
+ public void onResume() {
+ super.onResume();
+ map.onResume();
+ }
+
+ /**
+ * Called when the fragment is pausing.
+ */
+ @Override
+ public void onPause() {
+ super.onPause();
+ map.onPause();
+ }
+
+ /**
+ * Called when the fragment state needs to be saved.
+ *
+ * @param outState The saved state
+ */
+ @Override
+ public void onSaveInstanceState(@NonNull Bundle outState) {
+ super.onSaveInstanceState(outState);
+ map.onSaveInstanceState(outState);
+ }
+
+ /**
+ * Called when the fragment is no longer visible for the user.
+ */
+ @Override
+ public void onStop() {
+ super.onStop();
+ map.onStop();
+ }
+
+ /**
+ * Called when the fragment receives onLowMemory call from the hosting Activity.
+ */
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ map.onLowMemory();
+ }
+
+ /**
+ * Called when the fragment is view hiearchy is being destroyed.
+ */
+ @Override
+ public void onDestroyView() {
+ super.onDestroyView();
+ map.onDestroy();
+ }
+
+ /**
+ * Sets a callback object which will be triggered when the MapboxMap instance is ready to be used.
+ *
+ * @param onMapReadyCallback The callback to be invoked.
+ */
+ public void getMapAsync(@NonNull final OnMapReadyCallback onMapReadyCallback) {
+ this.onMapReadyCallback = onMapReadyCallback;
+ }
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java
index 474af19853..28591cf68c 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java
@@ -1,214 +1,368 @@
package com.mapbox.mapboxsdk.maps;
+import android.Manifest;
+import android.content.pm.PackageManager;
+import android.graphics.PointF;
+import android.location.Location;
+import android.os.Bundle;
import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
+import android.support.v4.content.ContextCompat;
+import com.mapbox.mapboxsdk.camera.CameraPosition;
+import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.constants.MyBearingTracking;
import com.mapbox.mapboxsdk.constants.MyLocationTracking;
+import com.mapbox.mapboxsdk.location.LocationListener;
+import com.mapbox.mapboxsdk.location.LocationServices;
import com.mapbox.mapboxsdk.maps.widgets.MyLocationView;
+import timber.log.Timber;
+
/**
* Settings for the user location and bearing tracking of a MapboxMap.
*/
-public class TrackingSettings {
+public final class TrackingSettings {
- private MapView mapView;
- private UiSettings uiSettings;
- private boolean dismissLocationTrackingOnGesture = true;
- private boolean dismissBearingTrackingOnGesture = true;
+ private final MyLocationView myLocationView;
+ private final UiSettings uiSettings;
+ private final FocalPointChangeListener focalPointChangedListener;
+ private LocationListener myLocationListener;
- @MyLocationTracking.Mode
- private int myLocationTrackingMode;
+ private boolean myLocationEnabled;
+ private boolean dismissLocationTrackingOnGesture = true;
+ private boolean dismissBearingTrackingOnGesture = true;
- @MyBearingTracking.Mode
- private int myBearingTrackingMode;
+ private MapboxMap.OnMyLocationTrackingModeChangeListener onMyLocationTrackingModeChangeListener;
+ private MapboxMap.OnMyBearingTrackingModeChangeListener onMyBearingTrackingModeChangeListener;
- TrackingSettings(@NonNull MapView mapView, UiSettings uiSettings) {
- this.mapView = mapView;
- this.uiSettings = uiSettings;
- }
+ TrackingSettings(@NonNull MyLocationView myLocationView, UiSettings uiSettings,
+ FocalPointChangeListener focalPointChangedListener) {
+ this.myLocationView = myLocationView;
+ this.focalPointChangedListener = focalPointChangedListener;
+ this.uiSettings = uiSettings;
+ }
- /**
- * <p>
- * Set the current my location tracking mode.
- * </p>
- * <p>
- * Will enable my location if not active.
- * </p>
- * See {@link MyLocationTracking} for different values.
- *
- * @param myLocationTrackingMode The location tracking mode to be used.
- * @throws SecurityException if no suitable permission is present
- * @see MyLocationTracking
- */
- @UiThread
- public void setMyLocationTrackingMode(@MyLocationTracking.Mode int myLocationTrackingMode) {
- this.myLocationTrackingMode = myLocationTrackingMode;
- mapView.setMyLocationTrackingMode(myLocationTrackingMode);
- }
+ void initialise(MapboxMapOptions options) {
+ setMyLocationEnabled(options.getLocationEnabled());
+ }
- /**
- * Returns the current user location tracking mode.
- *
- * @return The current user location tracking mode.
- * One of the values from {@link MyLocationTracking.Mode}.
- * @see MyLocationTracking.Mode
- */
- @UiThread
- @MyLocationTracking.Mode
- public int getMyLocationTrackingMode() {
- return myLocationTrackingMode;
- }
+ void onSaveInstanceState(Bundle outState) {
+ outState.putInt(MapboxConstants.STATE_MY_LOCATION_TRACKING_MODE, getMyLocationTrackingMode());
+ outState.putInt(MapboxConstants.STATE_MY_BEARING_TRACKING_MODE, getMyBearingTrackingMode());
+ outState.putBoolean(MapboxConstants.STATE_MY_LOCATION_TRACKING_DISMISS, isDismissLocationTrackingOnGesture());
+ outState.putBoolean(MapboxConstants.STATE_MY_BEARING_TRACKING_DISMISS, isDismissBearingTrackingOnGesture());
+ outState.putBoolean(MapboxConstants.STATE_MY_LOCATION_ENABLED, isMyLocationEnabled());
+ }
- /**
- * <p>
- * Set the current my bearing tracking mode.
- * </p>
- * Shows the direction the user is heading.
- * <p>
- * When location tracking is disabled the direction of {@link MyLocationView} is rotated
- * When location tracking is enabled the {@link MapView} is rotated based on bearing value.
- * </p>
- * See {@link MyBearingTracking} for different values.
- *
- * @param myBearingTrackingMode The bearing tracking mode to be used.
- * @throws SecurityException if no suitable permission is present
- * @see MyBearingTracking
- */
- @UiThread
- public void setMyBearingTrackingMode(@MyBearingTracking.Mode int myBearingTrackingMode) {
- this.myBearingTrackingMode = myBearingTrackingMode;
- mapView.setMyBearingTrackingMode(myBearingTrackingMode);
+ void onRestoreInstanceState(Bundle savedInstanceState) {
+ try {
+ setMyLocationEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_MY_LOCATION_ENABLED));
+ } catch (SecurityException ignore) {
+ // User did not accept location permissions
}
+ //noinspection ResourceType
+ setMyLocationTrackingMode(savedInstanceState.getInt(
+ MapboxConstants.STATE_MY_LOCATION_TRACKING_MODE, MyLocationTracking.TRACKING_NONE));
+ //noinspection ResourceType
+ setMyBearingTrackingMode(savedInstanceState.getInt(
+ MapboxConstants.STATE_MY_BEARING_TRACKING_MODE, MyBearingTracking.NONE));
+ setDismissLocationTrackingOnGesture(savedInstanceState.getBoolean(
+ MapboxConstants.STATE_MY_LOCATION_TRACKING_DISMISS, true));
+ setDismissBearingTrackingOnGesture(savedInstanceState.getBoolean(
+ MapboxConstants.STATE_MY_BEARING_TRACKING_DISMISS, true));
+ }
- /**
- * Returns the current user bearing tracking mode.
- * See {@link MyBearingTracking} for possible return values.
- *
- * @return the current user bearing tracking mode.
- * @see MyBearingTracking
- */
- @UiThread
- @MyBearingTracking.Mode
- public int getMyBearingTrackingMode() {
- return myBearingTrackingMode;
- }
+ /**
+ * <p>
+ * Set the current my location tracking mode.
+ * </p>
+ * <p>
+ * Will enable my location if not active.
+ * </p>
+ * See {@link MyLocationTracking} for different values.
+ *
+ * @param myLocationTrackingMode The location tracking mode to be used.
+ * @throws SecurityException if no suitable permission is present
+ * @see MyLocationTracking
+ */
+ @UiThread
+ public void setMyLocationTrackingMode(@MyLocationTracking.Mode int myLocationTrackingMode) {
+ myLocationView.setMyLocationTrackingMode(myLocationTrackingMode);
- /**
- * Returns if the tracking modes will be dismissed when a gesture occurs.
- *
- * @return True to indicate the tracking modes will be dismissed.
- * @deprecated use @link #isAllDismissTrackingOnGestureinstead
- */
- @Deprecated
- public boolean isDismissTrackingOnGesture() {
- return dismissLocationTrackingOnGesture && dismissBearingTrackingOnGesture;
+ if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW) {
+ focalPointChangedListener.onFocalPointChanged(new PointF(myLocationView.getCenterX(),
+ myLocationView.getCenterY()));
+ } else {
+ focalPointChangedListener.onFocalPointChanged(null);
}
- /**
- * Returns if all tracking modes will be dismissed when a gesture occurs.
- *
- * @return True to indicate that location and bearing tracking will be dismissed.
- */
- public boolean isAllDismissTrackingOnGesture() {
- return dismissLocationTrackingOnGesture && dismissBearingTrackingOnGesture;
+ if (onMyLocationTrackingModeChangeListener != null) {
+ onMyLocationTrackingModeChangeListener.onMyLocationTrackingModeChange(myLocationTrackingMode);
}
+ }
- /**
- * Set the dismissal of the tracking modes if a gesture occurs.
- *
- * @param dismissTrackingOnGesture True to dismiss the tracking modes.
- * @deprecated use @link #setDismissAllTrackingOnGesture instead
- */
- @Deprecated
- public void setDismissTrackingOnGesture(boolean dismissTrackingOnGesture) {
- setDismissAllTrackingOnGesture(dismissTrackingOnGesture);
- }
+ /**
+ * Returns the current user location tracking mode.
+ *
+ * @return The current user location tracking mode.
+ * One of the values from {@link MyLocationTracking.Mode}.
+ * @see MyLocationTracking.Mode
+ */
+ @UiThread
+ @MyLocationTracking.Mode
+ public int getMyLocationTrackingMode() {
+ return myLocationView.getMyLocationTrackingMode();
+ }
- /**
- * Set the dismissal of the tracking modes if a gesture occurs.
- *
- * @param dismissTrackingOnGesture True to dismiss all the tracking modes.
- */
- public void setDismissAllTrackingOnGesture(boolean dismissTrackingOnGesture) {
- dismissLocationTrackingOnGesture = dismissTrackingOnGesture;
- dismissBearingTrackingOnGesture = dismissTrackingOnGesture;
+ /**
+ * <p>
+ * Set the current my bearing tracking mode.
+ * </p>
+ * Shows the direction the user is heading.
+ * <p>
+ * When location tracking is disabled the direction of {@link MyLocationView} is rotated. When
+ * location tracking is enabled the {@link MapView} is rotated based on the bearing value.
+ * </p>
+ * See {@link MyBearingTracking} for different values.
+ *
+ * @param myBearingTrackingMode The bearing tracking mode to be used.
+ * @throws SecurityException if no suitable permission is present
+ * @see MyBearingTracking
+ */
+ @UiThread
+ public void setMyBearingTrackingMode(@MyBearingTracking.Mode int myBearingTrackingMode) {
+ myLocationView.setMyBearingTrackingMode(myBearingTrackingMode);
+ if (onMyBearingTrackingModeChangeListener != null) {
+ onMyBearingTrackingModeChangeListener.onMyBearingTrackingModeChange(myBearingTrackingMode);
}
+ }
- /**
- * Set the dismissal of the tracking modes if a gesture occurs.
- *
- * @param dismissLocationTrackingOnGesture True to dismiss the location tracking mode.
- */
- public void setDismissLocationTrackingOnGesture(boolean dismissLocationTrackingOnGesture) {
- this.dismissLocationTrackingOnGesture = dismissLocationTrackingOnGesture;
- }
+ /**
+ * Returns the current user bearing tracking mode.
+ * See {@link MyBearingTracking} for possible return values.
+ *
+ * @return the current user bearing tracking mode.
+ * @see MyBearingTracking
+ */
+ @UiThread
+ @MyBearingTracking.Mode
+ public int getMyBearingTrackingMode() {
+ return myLocationView.getMyBearingTrackingMode();
+ }
- /**
- * Returns if the location tracking will be disabled when a gesture occurs
- *
- * @return True if location tracking will be disabled.
- */
- public boolean isDismissLocationTrackingOnGesture() {
- return dismissLocationTrackingOnGesture;
- }
+ /**
+ * Returns if the tracking modes will be dismissed when a gesture occurs.
+ *
+ * @return True to indicate the tracking modes will be dismissed.
+ * @deprecated use @link #isAllDismissTrackingOnGestureinstead
+ */
+ @Deprecated
+ public boolean isDismissTrackingOnGesture() {
+ return dismissLocationTrackingOnGesture && dismissBearingTrackingOnGesture;
+ }
- /**
- * Set the dismissal of the bearing tracking modes if a gesture occurs.
- *
- * @param dismissBearingTrackingOnGesture True to dimsiss the bearinf tracking mode
- */
- public void setDismissBearingTrackingOnGesture(boolean dismissBearingTrackingOnGesture) {
- this.dismissBearingTrackingOnGesture = dismissBearingTrackingOnGesture;
- }
+ /**
+ * Returns if all tracking modes will be dismissed when a gesture occurs.
+ *
+ * @return True to indicate that location and bearing tracking will be dismissed.
+ */
+ public boolean isAllDismissTrackingOnGesture() {
+ return dismissLocationTrackingOnGesture && dismissBearingTrackingOnGesture;
+ }
+
+ /**
+ * Set the dismissal of the tracking modes if a gesture occurs.
+ *
+ * @param dismissTrackingOnGesture True to dismiss the tracking modes.
+ * @deprecated use @link #setDismissAllTrackingOnGesture instead
+ */
+ @Deprecated
+ public void setDismissTrackingOnGesture(boolean dismissTrackingOnGesture) {
+ setDismissAllTrackingOnGesture(dismissTrackingOnGesture);
+ }
+
+ /**
+ * Set the dismissal of the tracking modes if a gesture occurs.
+ *
+ * @param dismissTrackingOnGesture True to dismiss all the tracking modes.
+ */
+ public void setDismissAllTrackingOnGesture(boolean dismissTrackingOnGesture) {
+ dismissLocationTrackingOnGesture = dismissTrackingOnGesture;
+ dismissBearingTrackingOnGesture = dismissTrackingOnGesture;
+ }
+
+ /**
+ * Set the dismissal of the tracking modes if a gesture occurs.
+ *
+ * @param dismissLocationTrackingOnGesture True to dismiss the location tracking mode.
+ */
+ public void setDismissLocationTrackingOnGesture(boolean dismissLocationTrackingOnGesture) {
+ this.dismissLocationTrackingOnGesture = dismissLocationTrackingOnGesture;
+ }
+
+ /**
+ * Returns if the location tracking will be disabled when a gesture occurs
+ *
+ * @return True if location tracking will be disabled.
+ */
+ public boolean isDismissLocationTrackingOnGesture() {
+ return dismissLocationTrackingOnGesture;
+ }
+
+ /**
+ * Set the dismissal of the bearing tracking modes if a gesture occurs.
+ *
+ * @param dismissBearingTrackingOnGesture True to dimsiss the bearinf tracking mode
+ */
+ public void setDismissBearingTrackingOnGesture(boolean dismissBearingTrackingOnGesture) {
+ this.dismissBearingTrackingOnGesture = dismissBearingTrackingOnGesture;
+ }
+
+ /**
+ * Returns if bearing will disabled when a gesture occurs
+ *
+ * @return True if bearing tracking will be disabled
+ */
+ public boolean isDismissBearingTrackingOnGesture() {
+ return dismissBearingTrackingOnGesture;
+ }
- /**
- * Returns if bearing will disabled when a gesture occurs
- *
- * @return True if bearing tracking will be disabled
- */
- public boolean isDismissBearingTrackingOnGesture() {
- return dismissBearingTrackingOnGesture;
+ /**
+ * Returns if location tracking is disabled
+ *
+ * @return True if location tracking is disabled.
+ */
+ public boolean isLocationTrackingDisabled() {
+ return myLocationView.getMyLocationTrackingMode() == MyLocationTracking.TRACKING_NONE;
+ }
+
+ /**
+ * Returns if bearing tracking disabled
+ *
+ * @return True if bearing tracking is disabled.
+ */
+ public boolean isBearingTrackingDisabled() {
+ return myLocationView.getMyBearingTrackingMode() == MyBearingTracking.NONE;
+ }
+
+ /**
+ * Returns if rotate gesture are currently enabled.
+ *
+ * @return True if rotate gestures are currently enabled.
+ */
+ public boolean isRotateGestureCurrentlyEnabled() {
+ // rotate gestures are recognised if:
+ // The user settings are enabled AND;
+ // EITHER bearing tracking is dismissed on gesture OR there is no bearing tracking
+ return uiSettings.isRotateGesturesEnabled()
+ && (dismissBearingTrackingOnGesture
+ || myLocationView.getMyBearingTrackingMode() == MyBearingTracking.NONE
+ || myLocationView.getMyLocationTrackingMode() == MyLocationTracking.TRACKING_NONE);
+ }
+
+ /**
+ * Returns if scroll gesture are currently enabled.
+ *
+ * @return True if scroll gestures are currently enabled.
+ */
+ public boolean isScrollGestureCurrentlyEnabled() {
+ return uiSettings.isScrollGesturesEnabled()
+ && (dismissLocationTrackingOnGesture
+ || myLocationView.getMyLocationTrackingMode() == MyLocationTracking.TRACKING_NONE);
+ }
+
+ /**
+ * Reset the tracking modes as necessary. Location tracking is reset if the map center is changed,
+ * bearing tracking if there is a rotation.
+ *
+ * @param translate true if translation
+ * @param rotate true if rotation
+ */
+ void resetTrackingModesIfRequired(boolean translate, boolean rotate) {
+ // if tracking is on, and we should dismiss tracking with gestures, and this is a scroll action, turn tracking off
+ if (translate && !isLocationTrackingDisabled() && isDismissLocationTrackingOnGesture()) {
+ setMyLocationTrackingMode(MyLocationTracking.TRACKING_NONE);
}
- /**
- * Returns if location tracking is disabled
- *
- * @return True if location tracking is disabled.
- */
- public boolean isLocationTrackingDisabled() {
- return myLocationTrackingMode == MyLocationTracking.TRACKING_NONE;
+ // reset bearing tracking only on rotate
+ if (rotate && !isBearingTrackingDisabled() && isDismissBearingTrackingOnGesture()) {
+ setMyBearingTrackingMode(MyBearingTracking.NONE);
}
+ }
- /**
- * Returns if bearing tracking disabled
- *
- * @return True if bearing tracking is disabled.
- */
- public boolean isBearingTrackingDisabled() {
- return myBearingTrackingMode == MyBearingTracking.NONE;
+ void resetTrackingModesIfRequired(CameraPosition cameraPosition) {
+ resetTrackingModesIfRequired(cameraPosition.target != null, cameraPosition.bearing != -1);
+ }
+
+ Location getMyLocation() {
+ return myLocationView.getLocation();
+ }
+
+ void setOnMyLocationChangeListener(@Nullable final MapboxMap.OnMyLocationChangeListener listener) {
+ if (listener != null) {
+ myLocationListener = new LocationListener() {
+ @Override
+ public void onLocationChanged(Location location) {
+ if (listener != null) {
+ listener.onMyLocationChange(location);
+ }
+ }
+ };
+ LocationServices.getLocationServices(myLocationView.getContext()).addLocationListener(myLocationListener);
+ } else {
+ LocationServices.getLocationServices(myLocationView.getContext()).removeLocationListener(myLocationListener);
+ myLocationListener = null;
}
+ }
+
+ boolean isPermissionsAccepted() {
+ return (ContextCompat.checkSelfPermission(myLocationView.getContext(),
+ Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED)
+ || ContextCompat.checkSelfPermission(myLocationView.getContext(),
+ Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
+ }
- /**
- * Returns if rotate gesture are currently enabled.
- *
- * @return True if rotate gestures are currently enabled.
- */
- public boolean isRotateGestureCurrentlyEnabled() {
- // rotate gestures are recognised if:
- // The user settings are enabled AND;
- // EITHER bearing tracking is dismissed on gesture OR there is no bearing tracking
- return uiSettings.isRotateGesturesEnabled() &&
- (dismissBearingTrackingOnGesture || myBearingTrackingMode == MyBearingTracking.NONE);
+ void setOnMyLocationTrackingModeChangeListener(MapboxMap.OnMyLocationTrackingModeChangeListener listener) {
+ this.onMyLocationTrackingModeChangeListener = listener;
+ }
+
+ void setOnMyBearingTrackingModeChangeListener(MapboxMap.OnMyBearingTrackingModeChangeListener listener) {
+ this.onMyBearingTrackingModeChangeListener = listener;
+ }
+
+ MyLocationView getMyLocationView() {
+ return myLocationView;
+ }
+
+
+ boolean isMyLocationEnabled() {
+ return myLocationEnabled;
+ }
+
+ void setMyLocationEnabled(boolean locationEnabled) {
+ if (!isPermissionsAccepted()) {
+ Timber.e("Could not activate user location tracking: "
+ + "user did not accept the permission or permissions were not requested.");
+ return;
}
+ myLocationEnabled = locationEnabled;
+ myLocationView.setEnabled(locationEnabled);
+ }
- /**
- * Returns if scroll gesture are currently enabled.
- *
- * @return True if scroll gestures are currently enabled.
- */
- public boolean isScrollGestureCurrentlyEnabled() {
- return uiSettings.isScrollGesturesEnabled() &&
- (dismissLocationTrackingOnGesture || myLocationTrackingMode == MyLocationTracking.TRACKING_NONE);
+ void update() {
+ if (!myLocationView.isEnabled()) {
+ return;
}
+ myLocationView.update();
+ }
+
+ void onStart() {
+ myLocationView.onStart();
+ }
+
+ void onStop() {
+ myLocationView.onStop();
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java
new file mode 100644
index 0000000000..88acc13356
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java
@@ -0,0 +1,300 @@
+package com.mapbox.mapboxsdk.maps;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.UiThread;
+
+import com.mapbox.mapboxsdk.annotations.MarkerViewManager;
+import com.mapbox.mapboxsdk.camera.CameraPosition;
+import com.mapbox.mapboxsdk.camera.CameraUpdate;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
+import com.mapbox.mapboxsdk.constants.MapboxConstants;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.maps.widgets.MyLocationView;
+
+import java.util.concurrent.TimeUnit;
+
+import timber.log.Timber;
+
+import static com.mapbox.mapboxsdk.maps.MapView.REGION_DID_CHANGE_ANIMATED;
+
+/**
+ * Resembles the current Map transformation.
+ * <p>
+ * Responsible for synchronising {@link CameraPosition} state and notifying
+ * {@link com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraChangeListener}.
+ * </p>
+ */
+final class Transform implements MapView.OnMapChangedListener {
+
+ private final NativeMapView mapView;
+ private final MarkerViewManager markerViewManager;
+ private final TrackingSettings trackingSettings;
+ private final MyLocationView myLocationView;
+
+ private CameraPosition cameraPosition;
+ private MapboxMap.CancelableCallback cameraCancelableCallback;
+ private MapboxMap.OnCameraChangeListener onCameraChangeListener;
+
+ Transform(NativeMapView mapView, MarkerViewManager markerViewManager, TrackingSettings trackingSettings) {
+ this.mapView = mapView;
+ this.markerViewManager = markerViewManager;
+ this.trackingSettings = trackingSettings;
+ this.myLocationView = trackingSettings.getMyLocationView();
+ }
+
+ void initialise(@NonNull MapboxMap mapboxMap, @NonNull MapboxMapOptions options) {
+ CameraPosition position = options.getCamera();
+ if (position != null && !position.equals(CameraPosition.DEFAULT)) {
+ moveCamera(mapboxMap, CameraUpdateFactory.newCameraPosition(position), null);
+ }
+ }
+
+ //
+ // Camera API
+ //
+
+ @UiThread
+ public final CameraPosition getCameraPosition() {
+ if (cameraPosition == null) {
+ cameraPosition = invalidateCameraPosition();
+ }
+ return cameraPosition;
+ }
+
+ @UiThread
+ void updateCameraPosition(@NonNull CameraPosition position) {
+ if (myLocationView != null) {
+ myLocationView.setCameraPosition(position);
+ }
+ markerViewManager.setTilt((float) position.tilt);
+ }
+
+ @Override
+ public void onMapChanged(@MapView.MapChange int change) {
+ if (change == REGION_DID_CHANGE_ANIMATED && cameraCancelableCallback != null) {
+ invalidateCameraPosition();
+ if (cameraCancelableCallback != null) {
+ cameraCancelableCallback.onFinish();
+ cameraCancelableCallback = null;
+ }
+ mapView.removeOnMapChangedListener(this);
+ }
+ }
+
+ @UiThread
+ final void moveCamera(MapboxMap mapboxMap, CameraUpdate update, MapboxMap.CancelableCallback callback) {
+ cameraPosition = update.getCameraPosition(mapboxMap);
+ trackingSettings.resetTrackingModesIfRequired(cameraPosition);
+ cancelTransitions();
+ mapView.jumpTo(cameraPosition.bearing, cameraPosition.target, cameraPosition.tilt, cameraPosition.zoom);
+ if (callback != null) {
+ callback.onFinish();
+ }
+ }
+
+ @UiThread
+ final void easeCamera(MapboxMap mapboxMap, CameraUpdate update, int durationMs, boolean easingInterpolator,
+ boolean resetTrackingMode, final MapboxMap.CancelableCallback callback) {
+ cameraPosition = update.getCameraPosition(mapboxMap);
+ if (resetTrackingMode) {
+ trackingSettings.resetTrackingModesIfRequired(cameraPosition);
+ }
+
+ cancelTransitions();
+ if (callback != null) {
+ cameraCancelableCallback = callback;
+ mapView.addOnMapChangedListener(this);
+ }
+
+ mapView.easeTo(cameraPosition.bearing, cameraPosition.target, getDurationNano(durationMs), cameraPosition.tilt,
+ cameraPosition.zoom, easingInterpolator);
+ }
+
+ @UiThread
+ final void animateCamera(MapboxMap mapboxMap, CameraUpdate update, int durationMs,
+ final MapboxMap.CancelableCallback callback) {
+ cameraPosition = update.getCameraPosition(mapboxMap);
+ trackingSettings.resetTrackingModesIfRequired(cameraPosition);
+
+ cancelTransitions();
+ if (callback != null) {
+ cameraCancelableCallback = callback;
+ mapView.addOnMapChangedListener(this);
+ }
+
+ mapView.flyTo(cameraPosition.bearing, cameraPosition.target, getDurationNano(durationMs), cameraPosition.tilt,
+ cameraPosition.zoom);
+ }
+
+ @UiThread
+ @Nullable
+ CameraPosition invalidateCameraPosition() {
+ if (mapView != null) {
+ cameraPosition = new CameraPosition.Builder(mapView.getCameraValues()).build();
+ if (onCameraChangeListener != null) {
+ onCameraChangeListener.onCameraChange(this.cameraPosition);
+ }
+ }
+ return cameraPosition;
+ }
+
+ void cancelTransitions() {
+ if (cameraCancelableCallback != null) {
+ cameraCancelableCallback.onCancel();
+ cameraCancelableCallback = null;
+ }
+ mapView.cancelTransitions();
+ }
+
+ @UiThread
+ void resetNorth() {
+ cancelTransitions();
+ mapView.resetNorth();
+ }
+
+ void setOnCameraChangeListener(@Nullable MapboxMap.OnCameraChangeListener listener) {
+ this.onCameraChangeListener = listener;
+ }
+
+ private long getDurationNano(long durationMs) {
+ return durationMs > 0 ? TimeUnit.NANOSECONDS.convert(durationMs, TimeUnit.MILLISECONDS) : 0;
+ }
+
+ //
+ // non Camera API
+ //
+
+ // Zoom in or out
+
+ double getZoom() {
+ return cameraPosition.zoom;
+ }
+
+ void zoom(boolean zoomIn) {
+ zoom(zoomIn, -1.0f, -1.0f);
+ }
+
+ void zoom(boolean zoomIn, float x, float y) {
+ // Cancel any animation
+ cancelTransitions();
+
+ if (zoomIn) {
+ mapView.scaleBy(2.0, x, y, MapboxConstants.ANIMATION_DURATION);
+ } else {
+ mapView.scaleBy(0.5, x, y, MapboxConstants.ANIMATION_DURATION);
+ }
+ }
+
+ // Direction
+ double getBearing() {
+ double direction = -mapView.getBearing();
+
+ while (direction > 360) {
+ direction -= 360;
+ }
+ while (direction < 0) {
+ direction += 360;
+ }
+
+ return direction;
+ }
+
+ double getRawBearing() {
+ return mapView.getBearing();
+ }
+
+ void setBearing(double bearing) {
+ if (myLocationView != null) {
+ myLocationView.setBearing(bearing);
+ }
+ mapView.setBearing(bearing);
+ }
+
+ void setBearing(double bearing, float focalX, float focalY) {
+ if (myLocationView != null) {
+ myLocationView.setBearing(bearing);
+ }
+ mapView.setBearing(bearing, focalX, focalY);
+ }
+
+
+ //
+ // LatLng / CenterCoordinate
+ //
+
+ LatLng getLatLng() {
+ return mapView.getLatLng();
+ }
+
+ //
+ // Pitch / Tilt
+ //
+
+ double getTilt() {
+ return mapView.getPitch();
+ }
+
+ void setTilt(Double pitch) {
+ if (myLocationView != null) {
+ myLocationView.setTilt(pitch);
+ }
+ markerViewManager.setTilt(pitch.floatValue());
+ mapView.setPitch(pitch, 0);
+ }
+
+ //
+ // Center coordinate
+ //
+
+ LatLng getCenterCoordinate() {
+ return mapView.getLatLng();
+ }
+
+ void setCenterCoordinate(LatLng centerCoordinate) {
+ mapView.setLatLng(centerCoordinate);
+ }
+
+ void setGestureInProgress(boolean gestureInProgress) {
+ mapView.setGestureInProgress(gestureInProgress);
+ if (!gestureInProgress) {
+ invalidateCameraPosition();
+ }
+ }
+
+ void zoomBy(double pow, float x, float y) {
+ mapView.scaleBy(pow, x, y);
+ }
+
+ void moveBy(double offsetX, double offsetY, long duration) {
+ mapView.moveBy(offsetX, offsetY, duration);
+ }
+
+ //
+ // Min & Max ZoomLevel
+ //
+
+ void setMinZoom(double minZoom) {
+ if ((minZoom < MapboxConstants.MINIMUM_ZOOM) || (minZoom > MapboxConstants.MAXIMUM_ZOOM)) {
+ Timber.e("Not setting minZoomPreference, value is in unsupported range: " + minZoom);
+ return;
+ }
+ mapView.setMinZoom(minZoom);
+ }
+
+ double getMinZoom() {
+ return mapView.getMinZoom();
+ }
+
+ void setMaxZoom(double maxZoom) {
+ if ((maxZoom < MapboxConstants.MINIMUM_ZOOM) || (maxZoom > MapboxConstants.MAXIMUM_ZOOM)) {
+ Timber.e("Not setting maxZoomPreference, value is in unsupported range: " + maxZoom);
+ return;
+ }
+ mapView.setMaxZoom(maxZoom);
+ }
+
+ double getMaxZoom() {
+ return mapView.getMaxZoom();
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java
index d6ad80d11e..0928f06310 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java
@@ -1,635 +1,843 @@
package com.mapbox.mapboxsdk.maps;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.graphics.Color;
import android.graphics.PointF;
+import android.os.Bundle;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
+import android.support.v4.content.ContextCompat;
import android.view.Gravity;
import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+
+import com.mapbox.mapboxsdk.R;
+import com.mapbox.mapboxsdk.camera.CameraPosition;
+import com.mapbox.mapboxsdk.constants.MapboxConstants;
+import com.mapbox.mapboxsdk.maps.widgets.CompassView;
+import com.mapbox.mapboxsdk.utils.ColorUtils;
/**
* Settings for the user interface of a MapboxMap. To obtain this interface, call getUiSettings().
*/
-public class UiSettings {
-
- private MapView mapView;
-
- private CompassViewSettings compassSettings;
- private ViewSettings logoSettings;
- private ViewSettings attributionSettings;
-
- private boolean rotateGesturesEnabled = true;
- private boolean rotateGestureChangeAllowed = true;
-
- private boolean tiltGesturesEnabled = true;
- private boolean tiltGestureChangeAllowed = true;
-
- private boolean zoomGesturesEnabled = true;
- private boolean zoomGestureChangeAllowed = true;
-
- private boolean scrollGesturesEnabled = true;
- private boolean scrollGestureChangeAllowed = true;
-
- private boolean zoomControlsEnabled;
-
- private boolean deselectMarkersOnTap = true;
-
- private PointF focalPoint;
-
- UiSettings(@NonNull MapView mapView) {
- this.mapView = mapView;
- this.compassSettings = new CompassViewSettings();
- this.logoSettings = new ViewSettings();
- this.attributionSettings = new ViewSettings();
- }
-
- /**
- * <p>
- * Enables or disables the compass. The compass is an icon on the map that indicates the
- * direction of north on the map. When a user clicks
- * the compass, the camera orients itself to its default orientation and fades away shortly
- * after. If disabled, the compass will never be displayed.
- * </p>
- * By default, the compass is enabled.
- *
- * @param compassEnabled True to enable the compass; false to disable the compass.
- */
- public void setCompassEnabled(boolean compassEnabled) {
- compassSettings.setEnabled(compassEnabled);
- mapView.setCompassEnabled(compassEnabled);
- }
-
- /**
- * Returns whether the compass is enabled.
- *
- * @return True if the compass is enabled; false if the compass is disabled.
- */
- public boolean isCompassEnabled() {
- return compassSettings.isEnabled();
- }
-
- /**
- * <p>
- * Sets the gravity of the compass view. Use this to change the corner of the map view that the
- * compass is displayed in.
- * </p>
- * By default, the compass is in the top right corner.
- *
- * @param gravity One of the values from {@link Gravity}.
- * @see Gravity
- */
- @UiThread
- public void setCompassGravity(int gravity) {
- compassSettings.setGravity(gravity);
- mapView.setCompassGravity(gravity);
- }
-
- /**
- * Enables or disables fading of the compass when facing north.
- * <p>
- * By default this feature is enabled
- * </p>
- *
- * @param compassFadeFacingNorth True to enable the fading animation; false to disable it
- */
- public void setCompassFadeFacingNorth(boolean compassFadeFacingNorth) {
- compassSettings.setFadeFacingNorth(compassFadeFacingNorth);
- mapView.setCompassFadeFacingNorth(compassFadeFacingNorth);
- }
-
- /**
- * Returns whether the compass performs a fading animation out when facing north.
- *
- * @return True if the compass will fade, false if it remains visible
- */
- public boolean isCompassFadeWhenFacingNorth(){
- return compassSettings.isFadeFacingNorth();
- }
-
- /**
- * Returns the gravity value of the CompassView
- *
- * @return The gravity
- */
- public int getCompassGravity() {
- return compassSettings.getGravity();
- }
-
- /**
- * Sets the margins of the compass view. Use this to change the distance of the compass from the
- * map view edge.
- *
- * @param left The left margin in pixels.
- * @param top The top margin in pixels.
- * @param right The right margin in pixels.
- * @param bottom The bottom margin in pixels.
- */
- @UiThread
- public void setCompassMargins(int left, int top, int right, int bottom) {
- compassSettings.setMargins(new int[]{left, top, right, bottom});
- mapView.setCompassMargins(left, top, right, bottom);
- }
-
- /**
- * Returns the left side margin of CompassView
- *
- * @return The left margin in pixels
- */
- public int getCompassMarginLeft() {
- return compassSettings.getMargins()[0];
- }
-
- /**
- * Returns the top side margin of CompassView
- *
- * @return The top margin in pixels
- */
- public int getCompassMarginTop() {
- return compassSettings.getMargins()[1];
- }
-
- /**
- * Returns the right side margin of CompassView
- *
- * @return The right margin in pixels
- */
- public int getCompassMarginRight() {
- return compassSettings.getMargins()[2];
- }
-
- /**
- * Returns the bottom side margin of CompassView
- *
- * @return The bottom margin in pixels
- */
- public int getCompassMarginBottom() {
- return compassSettings.getMargins()[3];
- }
-
- /**
- * <p>
- * Enables or disables the Mapbox logo.
- * </p>
- * By default, the compass is enabled.
- *
- * @param enabled True to enable the logo; false to disable the logo.
- */
- public void setLogoEnabled(boolean enabled) {
- logoSettings.setEnabled(enabled);
- mapView.setLogoEnabled(enabled);
- }
-
- /**
- * Returns whether the logo is enabled.
- *
- * @return True if the logo is enabled; false if the logo is disabled.
- */
- public boolean isLogoEnabled() {
- return logoSettings.isEnabled();
- }
-
- /**
- * <p>
- * Sets the gravity of the logo view. Use this to change the corner of the map view that the
- * Mapbox logo is displayed in.
- * </p>
- * By default, the logo is in the bottom left corner.
- *
- * @param gravity One of the values from {@link Gravity}.
- * @see Gravity
- */
- public void setLogoGravity(int gravity) {
- logoSettings.setGravity(gravity);
- mapView.setLogoGravity(gravity);
- }
-
- /**
- * Returns the gravity value of the logo
- *
- * @return The gravity
- */
- public int getLogoGravity() {
- return logoSettings.getGravity();
- }
-
- /**
- * Sets the margins of the logo view. Use this to change the distance of the Mapbox logo from the
- * map view edge.
- *
- * @param left The left margin in pixels.
- * @param top The top margin in pixels.
- * @param right The right margin in pixels.
- * @param bottom The bottom margin in pixels.
- */
- public void setLogoMargins(int left, int top, int right, int bottom) {
- logoSettings.setMargins(new int[]{left, top, right, bottom});
- mapView.setLogoMargins(left, top, right, bottom);
- }
-
- /**
- * Returns the left side margin of the logo
- *
- * @return The left margin in pixels
- */
- public int getLogoMarginLeft() {
- return logoSettings.getMargins()[0];
- }
-
- /**
- * Returns the top side margin of the logo
- *
- * @return The top margin in pixels
- */
- public int getLogoMarginTop() {
- return logoSettings.getMargins()[1];
- }
-
- /**
- * Returns the right side margin of the logo
- *
- * @return The right margin in pixels
- */
- public int getLogoMarginRight() {
- return logoSettings.getMargins()[2];
- }
-
- /**
- * Returns the bottom side margin of the logo
- *
- * @return The bottom margin in pixels
- */
- public int getLogoMarginBottom() {
- return logoSettings.getMargins()[3];
- }
-
- /**
- * <p>
- * Enables or disables the attribution.
- * </p>
- * By default, the attribution is enabled.
- *
- * @param enabled True to enable the attribution; false to disable the attribution.
- */
- public void setAttributionEnabled(boolean enabled) {
- attributionSettings.setEnabled(enabled);
- mapView.setAttributionEnabled(enabled ? View.VISIBLE : View.GONE);
- }
-
- /**
- * Returns whether the attribution is enabled.
- *
- * @return True if the attribution is enabled; false if the attribution is disabled.
- */
- public boolean isAttributionEnabled() {
- return attributionSettings.isEnabled();
- }
-
- /**
- * <p>
- * Sets the gravity of the attribution.
- * </p>
- * By default, the attribution is in the bottom left corner next to the Mapbox logo.
- *
- * @param gravity One of the values from {@link Gravity}.
- * @see Gravity
- */
- public void setAttributionGravity(int gravity) {
- attributionSettings.setGravity(gravity);
- mapView.setAttributionGravity(gravity);
- }
-
- /**
- * Returns the gravity value of the logo
- *
- * @return The gravity
- */
- public int getAttributionGravity() {
- return attributionSettings.getGravity();
- }
-
- /**
- * Sets the margins of the attribution view.
- *
- * @param left The left margin in pixels.
- * @param top The top margin in pixels.
- * @param right The right margin in pixels.
- * @param bottom The bottom margin in pixels.
- */
- public void setAttributionMargins(int left, int top, int right, int bottom) {
- attributionSettings.setMargins(new int[]{left, top, right, bottom});
- mapView.setAttributionMargins(left, top, right, bottom);
- }
-
- /**
- * <p>
- * Sets the tint of the attribution view. Use this to change the color of the attribution.
- * </p>
- * By default, the logo is tinted with the primary color of your theme.
- *
- * @param tintColor Color to tint the attribution.
- */
- public void setAttributionTintColor(@ColorInt int tintColor) {
- attributionSettings.setTintColor(tintColor);
- mapView.setAtttibutionTintColor(tintColor);
- }
-
- /**
- * Returns the tint color value of the attribution view.
- *
- * @return The tint color
- */
- public int getAttributionTintColor() {
- return attributionSettings.getTintColor();
- }
-
- /**
- * Returns the left side margin of the attribution view.
- *
- * @return The left margin in pixels
- */
- public int getAttributionMarginLeft() {
- return attributionSettings.getMargins()[0];
- }
-
- /**
- * Returns the top side margin of the attribution view.
- *
- * @return The top margin in pixels
- */
- public int getAttributionMarginTop() {
- return attributionSettings.getMargins()[1];
- }
-
- /**
- * Returns the right side margin of the attribution view.
- *
- * @return The right margin in pixels
- */
- public int getAttributionMarginRight() {
- return attributionSettings.getMargins()[2];
- }
-
- /**
- * Returns the bottom side margin of the logo
- *
- * @return The bottom margin in pixels
- */
- public int getAttributionMarginBottom() {
- return attributionSettings.getMargins()[3];
- }
-
- /**
- * <p>
- * Changes whether the user may rotate the map.
- * </p>
- * <p>
- * This setting controls only user interactions with the map. If you set the value to false,
- * you may still change the map location programmatically.
- * </p>
- * The default value is true.
- *
- * @param rotateGesturesEnabled If true, rotating is enabled.
- */
- public void setRotateGesturesEnabled(boolean rotateGesturesEnabled) {
- if (rotateGestureChangeAllowed) {
- this.rotateGesturesEnabled = rotateGesturesEnabled;
- }
- }
-
- /**
- * Returns whether the user may rotate the map.
- *
- * @return If true, rotating is enabled.
- */
- public boolean isRotateGesturesEnabled() {
- return rotateGesturesEnabled;
- }
-
- void setRotateGestureChangeAllowed(boolean rotateGestureChangeAllowed) {
- this.rotateGestureChangeAllowed = rotateGestureChangeAllowed;
- }
-
- boolean isRotateGestureChangeAllowed() {
- return rotateGestureChangeAllowed;
- }
-
- /**
- * <p>
- * Changes whether the user may tilt the map.
- * </p>
- * <p>
- * This setting controls only user interactions with the map. If you set the value to false,
- * you may still change the map location programmatically.
- * </p>
- * The default value is true.
- *
- * @param tiltGesturesEnabled If true, tilting is enabled.
- */
- public void setTiltGesturesEnabled(boolean tiltGesturesEnabled) {
- if (tiltGestureChangeAllowed) {
- this.tiltGesturesEnabled = tiltGesturesEnabled;
- }
- }
-
- /**
- * Returns whether the user may tilt the map.
- *
- * @return If true, tilting is enabled.
- */
- public boolean isTiltGesturesEnabled() {
- return tiltGesturesEnabled;
- }
-
- void setTiltGestureChangeAllowed(boolean tiltGestureChangeAllowed) {
- this.tiltGestureChangeAllowed = tiltGestureChangeAllowed;
- }
-
- boolean isTiltGestureChangeAllowed() {
- return tiltGestureChangeAllowed;
- }
-
- /**
- * <p>
- * Changes whether the user may zoom the map.
- * </p>
- * <p>
- * This setting controls only user interactions with the map. If you set the value to false,
- * you may still change the map location programmatically.
- * </p>
- * The default value is true.
- *
- * @param zoomGesturesEnabled If true, zooming is enabled.
- */
- public void setZoomGesturesEnabled(boolean zoomGesturesEnabled) {
- if (zoomGestureChangeAllowed) {
- this.zoomGesturesEnabled = zoomGesturesEnabled;
- }
- }
-
- /**
- * Returns whether the user may zoom the map.
- *
- * @return If true, zooming is enabled.
- */
- public boolean isZoomGesturesEnabled() {
- return zoomGesturesEnabled;
- }
-
- void setZoomGestureChangeAllowed(boolean zoomGestureChangeAllowed) {
- this.zoomGestureChangeAllowed = zoomGestureChangeAllowed;
- }
-
- boolean isZoomGestureChangeAllowed() {
- return zoomGestureChangeAllowed;
- }
-
- /**
- * <p>
- * Sets whether the zoom controls are enabled.
- * If enabled, the zoom controls are a pair of buttons
- * (one for zooming in, one for zooming out) that appear on the screen.
- * When pressed, they cause the camera to zoom in (or out) by one zoom level.
- * If disabled, the zoom controls are not shown.
- * </p>
- * By default the zoom controls are enabled if the device is only single touch capable;
- *
- * @param zoomControlsEnabled If true, the zoom controls are enabled.
- */
- public void setZoomControlsEnabled(boolean zoomControlsEnabled) {
- this.zoomControlsEnabled = zoomControlsEnabled;
- }
-
- /**
- * Gets whether the zoom controls are enabled.
- *
- * @return If true, the zoom controls are enabled.
- */
- public boolean isZoomControlsEnabled() {
- return zoomControlsEnabled;
- }
-
- /**
- * Gets whether the markers are automatically deselected (and therefore, their infowindows
- * closed) when a map tap is detected.
- *
- * @return If true, markers are deselected on a map tap.
- */
- public boolean isDeselectMarkersOnTap() {
- return deselectMarkersOnTap;
- }
-
- /**
- * Sets whether the markers are automatically deselected (and therefore, their infowindows
- * closed) when a map tap is detected.
- *
- * @param deselectMarkersOnTap determines if markers should be deslected on tap
- */
- public void setDeselectMarkersOnTap(boolean deselectMarkersOnTap) {
- this.deselectMarkersOnTap = deselectMarkersOnTap;
- }
-
- /**
- * <p>
- * Changes whether the user may scroll around the map.
- * </p>
- * <p>
- * This setting controls only user interactions with the map. If you set the value to false,
- * you may still change the map location programmatically.
- * </p>
- * The default value is true.
- *
- * @param scrollGesturesEnabled If true, scrolling is enabled.
- */
- public void setScrollGesturesEnabled(boolean scrollGesturesEnabled) {
- if (scrollGestureChangeAllowed) {
- this.scrollGesturesEnabled = scrollGesturesEnabled;
- }
- }
-
- /**
- * Returns whether the user may scroll around the map.
- *
- * @return If true, scrolling is enabled.
- */
- public boolean isScrollGesturesEnabled() {
- return scrollGesturesEnabled;
- }
-
- void setScrollGestureChangeAllowed(boolean scrollGestureChangeAllowed) {
- this.scrollGestureChangeAllowed = scrollGestureChangeAllowed;
- }
-
- boolean isScrollGestureChangeAllowed() {
- return scrollGestureChangeAllowed;
- }
-
- /**
- * <p>
- * Sets the preference for whether all gestures should be enabled or disabled.
- * </p>
- * <p>
- * This setting controls only user interactions with the map. If you set the value to false,
- * you may still change the map location programmatically.
- * </p>
- * The default value is true.
- *
- * @param enabled If true, all gestures are available; otherwise, all gestures are disabled.
- * @see #setZoomGesturesEnabled(boolean) )
- * @see #setScrollGesturesEnabled(boolean)
- * @see #setRotateGesturesEnabled(boolean)
- * @see #setTiltGesturesEnabled(boolean)
- */
- public void setAllGesturesEnabled(boolean enabled) {
- setScrollGesturesEnabled(enabled);
- setRotateGesturesEnabled(enabled);
- setTiltGesturesEnabled(enabled);
- setZoomGesturesEnabled(enabled);
- }
-
- /**
- * Sets the focal point used as center for a gesture
- *
- * @param focalPoint the focal point to be used.
- */
- public void setFocalPoint(@Nullable PointF focalPoint) {
- this.focalPoint = focalPoint;
- mapView.setFocalPoint(focalPoint);
- }
-
- /**
- * Returns the gesture focal point
- *
- * @return The focal point
- */
- public PointF getFocalPoint() {
- return focalPoint;
- }
-
- /**
- * Returns the measured height of the MapView
- *
- * @return height in pixels
- */
- public float getHeight() {
- return mapView.getMeasuredHeight();
- }
-
- /**
- * Returns the measured width of the MapView
- *
- * @return widht in pixels
- */
- public float getWidth() {
- return mapView.getMeasuredWidth();
- }
-
- /**
- * Invalidates the ViewSettings instances shown on top of the MapView
- */
- public void invalidate() {
- mapView.setLogoMargins(getLogoMarginLeft(), getLogoMarginTop(), getLogoMarginRight(), getLogoMarginBottom());
- mapView.setCompassMargins(getCompassMarginLeft(), getCompassMarginTop(), getCompassMarginRight(), getCompassMarginBottom());
- mapView.setAttributionMargins(getAttributionMarginLeft(), getAttributionMarginTop(), getAttributionMarginRight(), getAttributionMarginBottom());
- }
+public final class UiSettings {
+
+ private final FocalPointChangeListener focalPointChangeListener;
+ private final Projection projection;
+ private final CompassView compassView;
+ private final ImageView attributionsView;
+ private final View logoView;
+ private float pixelRatio;
+
+ private boolean rotateGesturesEnabled = true;
+ private boolean rotateGestureChangeAllowed = true;
+
+ private boolean tiltGesturesEnabled = true;
+ private boolean tiltGestureChangeAllowed = true;
+
+ private boolean zoomGesturesEnabled = true;
+ private boolean zoomGestureChangeAllowed = true;
+
+ private boolean scrollGesturesEnabled = true;
+ private boolean scrollGestureChangeAllowed = true;
+
+ private boolean zoomControlsEnabled;
+
+ private boolean deselectMarkersOnTap = true;
+
+ private PointF userProvidedFocalPoint;
+
+ UiSettings(@NonNull Projection projection, @NonNull FocalPointChangeListener listener,
+ @NonNull CompassView compassView, @NonNull ImageView attributionsView, @NonNull View logoView) {
+ this.projection = projection;
+ this.focalPointChangeListener = listener;
+ this.compassView = compassView;
+ this.attributionsView = attributionsView;
+ this.logoView = logoView;
+ if (logoView.getResources() != null) {
+ this.pixelRatio = logoView.getResources().getDisplayMetrics().density;
+ }
+ }
+
+ void initialise(@NonNull Context context, @NonNull MapboxMapOptions options) {
+ Resources resources = context.getResources();
+ initialiseGestures(options);
+ initialiseCompass(options, resources);
+ initialiseLogo(options, resources);
+ initialiseAttribution(context, options);
+ initialiseZoomControl(context);
+ }
+
+ void onSaveInstanceState(Bundle outState) {
+ saveGestures(outState);
+ saveCompass(outState);
+ saveLogo(outState);
+ saveAttribution(outState);
+ saveZoomControl(outState);
+ }
+
+ void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
+ restoreGestures(savedInstanceState);
+ restoreCompass(savedInstanceState);
+ restoreLogo(savedInstanceState);
+ restoreAttribution(savedInstanceState);
+ restoreZoomControl(savedInstanceState);
+ }
+
+ private void initialiseGestures(MapboxMapOptions options) {
+ setZoomGesturesEnabled(options.getZoomGesturesEnabled());
+ setZoomGestureChangeAllowed(options.getZoomGesturesEnabled());
+ setScrollGesturesEnabled(options.getScrollGesturesEnabled());
+ setScrollGestureChangeAllowed(options.getScrollGesturesEnabled());
+ setRotateGesturesEnabled(options.getRotateGesturesEnabled());
+ setRotateGestureChangeAllowed(options.getRotateGesturesEnabled());
+ setTiltGesturesEnabled(options.getTiltGesturesEnabled());
+ setTiltGestureChangeAllowed(options.getTiltGesturesEnabled());
+ setZoomControlsEnabled(options.getZoomControlsEnabled());
+ }
+
+ private void saveGestures(Bundle outState) {
+ outState.putBoolean(MapboxConstants.STATE_ZOOM_ENABLED, isZoomGesturesEnabled());
+ outState.putBoolean(MapboxConstants.STATE_ZOOM_ENABLED_CHANGE, isZoomGestureChangeAllowed());
+ outState.putBoolean(MapboxConstants.STATE_SCROLL_ENABLED, isScrollGesturesEnabled());
+ outState.putBoolean(MapboxConstants.STATE_SCROLL_ENABLED_CHANGE, isScrollGestureChangeAllowed());
+ outState.putBoolean(MapboxConstants.STATE_ROTATE_ENABLED, isRotateGesturesEnabled());
+ outState.putBoolean(MapboxConstants.STATE_ROTATE_ENABLED_CHANGE, isRotateGestureChangeAllowed());
+ outState.putBoolean(MapboxConstants.STATE_TILT_ENABLED, isTiltGesturesEnabled());
+ outState.putBoolean(MapboxConstants.STATE_TILT_ENABLED_CHANGE, isTiltGestureChangeAllowed());
+ }
+
+ private void restoreGestures(Bundle savedInstanceState) {
+ setZoomGesturesEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_ZOOM_ENABLED));
+ setZoomGestureChangeAllowed(savedInstanceState.getBoolean(MapboxConstants.STATE_ZOOM_ENABLED_CHANGE));
+ setScrollGesturesEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_SCROLL_ENABLED));
+ setScrollGestureChangeAllowed(savedInstanceState.getBoolean(MapboxConstants.STATE_SCROLL_ENABLED_CHANGE));
+ setRotateGesturesEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_ROTATE_ENABLED));
+ setRotateGestureChangeAllowed(savedInstanceState.getBoolean(MapboxConstants.STATE_ROTATE_ENABLED_CHANGE));
+ setTiltGesturesEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_TILT_ENABLED));
+ setTiltGestureChangeAllowed(savedInstanceState.getBoolean(MapboxConstants.STATE_TILT_ENABLED_CHANGE));
+ }
+
+ private void initialiseCompass(MapboxMapOptions options, Resources resources) {
+ setCompassEnabled(options.getCompassEnabled());
+ setCompassGravity(options.getCompassGravity());
+ int[] compassMargins = options.getCompassMargins();
+ if (compassMargins != null) {
+ setCompassMargins(compassMargins[0], compassMargins[1], compassMargins[2], compassMargins[3]);
+ } else {
+ int tenDp = (int) resources.getDimension(R.dimen.mapbox_ten_dp);
+ setCompassMargins(tenDp, tenDp, tenDp, tenDp);
+ }
+ setCompassFadeFacingNorth(options.getCompassFadeFacingNorth());
+ }
+
+ private void saveCompass(Bundle outState) {
+ outState.putBoolean(MapboxConstants.STATE_COMPASS_ENABLED, isCompassEnabled());
+ outState.putInt(MapboxConstants.STATE_COMPASS_GRAVITY, getCompassGravity());
+ outState.putInt(MapboxConstants.STATE_COMPASS_MARGIN_LEFT, getCompassMarginLeft());
+ outState.putInt(MapboxConstants.STATE_COMPASS_MARGIN_TOP, getCompassMarginTop());
+ outState.putInt(MapboxConstants.STATE_COMPASS_MARGIN_BOTTOM, getCompassMarginBottom());
+ outState.putInt(MapboxConstants.STATE_COMPASS_MARGIN_RIGHT, getCompassMarginRight());
+ outState.putBoolean(MapboxConstants.STATE_COMPASS_FADE_WHEN_FACING_NORTH, isCompassFadeWhenFacingNorth());
+ }
+
+ private void restoreCompass(Bundle savedInstanceState) {
+ setCompassEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_COMPASS_ENABLED));
+ setCompassGravity(savedInstanceState.getInt(MapboxConstants.STATE_COMPASS_GRAVITY));
+ 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));
+ setCompassFadeFacingNorth(savedInstanceState.getBoolean(MapboxConstants.STATE_COMPASS_FADE_WHEN_FACING_NORTH));
+ }
+
+ private void initialiseLogo(MapboxMapOptions options, Resources resources) {
+ setLogoEnabled(options.getLogoEnabled());
+ setLogoGravity(options.getLogoGravity());
+ int[] logoMargins = options.getLogoMargins();
+ if (logoMargins != null) {
+ setLogoMargins(logoMargins[0], logoMargins[1], logoMargins[2], logoMargins[3]);
+ } else {
+ int sixteenDp = (int) resources.getDimension(R.dimen.mapbox_sixteen_dp);
+ setLogoMargins(sixteenDp, sixteenDp, sixteenDp, sixteenDp);
+ }
+ }
+
+ private void saveLogo(Bundle outState) {
+ outState.putInt(MapboxConstants.STATE_LOGO_GRAVITY, getLogoGravity());
+ outState.putInt(MapboxConstants.STATE_LOGO_MARGIN_LEFT, getLogoMarginLeft());
+ outState.putInt(MapboxConstants.STATE_LOGO_MARGIN_TOP, getLogoMarginTop());
+ outState.putInt(MapboxConstants.STATE_LOGO_MARGIN_RIGHT, getLogoMarginRight());
+ outState.putInt(MapboxConstants.STATE_LOGO_MARGIN_BOTTOM, getLogoMarginBottom());
+ outState.putBoolean(MapboxConstants.STATE_LOGO_ENABLED, isLogoEnabled());
+ }
+
+ private void restoreLogo(Bundle savedInstanceState) {
+ setLogoEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_LOGO_ENABLED));
+ setLogoGravity(savedInstanceState.getInt(MapboxConstants.STATE_LOGO_GRAVITY));
+ setLogoMargins(savedInstanceState.getInt(MapboxConstants.STATE_LOGO_MARGIN_LEFT),
+ savedInstanceState.getInt(MapboxConstants.STATE_LOGO_MARGIN_TOP),
+ savedInstanceState.getInt(MapboxConstants.STATE_LOGO_MARGIN_RIGHT),
+ savedInstanceState.getInt(MapboxConstants.STATE_LOGO_MARGIN_BOTTOM));
+ }
+
+ private void initialiseAttribution(Context context, MapboxMapOptions options) {
+ Resources resources = context.getResources();
+ setAttributionEnabled(options.getAttributionEnabled());
+ setAttributionGravity(options.getAttributionGravity());
+ int[] attributionMargins = options.getAttributionMargins();
+ if (attributionMargins != null) {
+ setAttributionMargins(attributionMargins[0], attributionMargins[1], attributionMargins[2], attributionMargins[3]);
+ } else {
+ int sevenDp = (int) resources.getDimension(R.dimen.mapbox_seven_dp);
+ int seventySixDp = (int) resources.getDimension(R.dimen.mapbox_seventy_six_dp);
+ setAttributionMargins(seventySixDp, sevenDp, sevenDp, sevenDp);
+ }
+
+ int attributionTintColor = options.getAttributionTintColor();
+ setAttributionTintColor(attributionTintColor != -1
+ ? attributionTintColor : ColorUtils.getPrimaryColor(context));
+ }
+
+ private void saveAttribution(Bundle outState) {
+ outState.putInt(MapboxConstants.STATE_ATTRIBUTION_GRAVITY, getAttributionGravity());
+ outState.putInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_LEFT, getAttributionMarginLeft());
+ outState.putInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_TOP, getAttributionMarginTop());
+ outState.putInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_RIGHT, getAttributionMarginRight());
+ outState.putInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_BOTTOM, getAttributionMarginBottom());
+ outState.putBoolean(MapboxConstants.STATE_ATTRIBUTION_ENABLED, isAttributionEnabled());
+ }
+
+ private void restoreAttribution(Bundle savedInstanceState) {
+ setAttributionEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_ATTRIBUTION_ENABLED));
+ setAttributionGravity(savedInstanceState.getInt(MapboxConstants.STATE_ATTRIBUTION_GRAVITY));
+ setAttributionMargins(savedInstanceState.getInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_LEFT),
+ savedInstanceState.getInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_TOP),
+ savedInstanceState.getInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_RIGHT),
+ savedInstanceState.getInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_BOTTOM));
+ }
+
+ private void initialiseZoomControl(Context context) {
+ if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH)) {
+ setZoomControlsEnabled(true);
+ }
+ }
+
+ private void saveZoomControl(Bundle outState) {
+ outState.putBoolean(MapboxConstants.STATE_ZOOM_CONTROLS_ENABLED, isZoomControlsEnabled());
+ }
+
+ private void restoreZoomControl(Bundle savedInstanceState) {
+ setZoomControlsEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_ZOOM_CONTROLS_ENABLED));
+ }
+
+ /**
+ * <p>
+ * Enables or disables the compass. The compass is an icon on the map that indicates the
+ * direction of north on the map. When a user clicks
+ * the compass, the camera orients itself to its default orientation and fades away shortly
+ * after. If disabled, the compass will never be displayed.
+ * </p>
+ * By default, the compass is enabled.
+ *
+ * @param compassEnabled True to enable the compass; false to disable the compass.
+ */
+ public void setCompassEnabled(boolean compassEnabled) {
+ compassView.setEnabled(compassEnabled);
+ }
+
+ /**
+ * Returns whether the compass is enabled.
+ *
+ * @return True if the compass is enabled; false if the compass is disabled.
+ */
+ public boolean isCompassEnabled() {
+ return compassView.isEnabled();
+ }
+
+ /**
+ * <p>
+ * Sets the gravity of the compass view. Use this to change the corner of the map view that the
+ * compass is displayed in.
+ * </p>
+ * By default, the compass is in the top right corner.
+ *
+ * @param gravity One of the values from {@link Gravity}.
+ * @see Gravity
+ */
+ @UiThread
+ public void setCompassGravity(int gravity) {
+ setWidgetGravity(compassView, gravity);
+ }
+
+ /**
+ * Enables or disables fading of the compass when facing north.
+ * <p>
+ * By default this feature is enabled
+ * </p>
+ *
+ * @param compassFadeFacingNorth True to enable the fading animation; false to disable it
+ */
+ public void setCompassFadeFacingNorth(boolean compassFadeFacingNorth) {
+ compassView.fadeCompassViewFacingNorth(compassFadeFacingNorth);
+ }
+
+ /**
+ * Returns whether the compass performs a fading animation out when facing north.
+ *
+ * @return True if the compass will fade, false if it remains visible
+ */
+ public boolean isCompassFadeWhenFacingNorth() {
+ return compassView.isFadeCompassViewFacingNorth();
+ }
+
+ /**
+ * Returns the gravity value of the CompassView
+ *
+ * @return The gravity
+ */
+ public int getCompassGravity() {
+ return ((FrameLayout.LayoutParams) compassView.getLayoutParams()).gravity;
+ }
+
+ /**
+ * Sets the margins of the compass view. Use this to change the distance of the compass from the
+ * map view edge.
+ *
+ * @param left The left margin in pixels.
+ * @param top The top margin in pixels.
+ * @param right The right margin in pixels.
+ * @param bottom The bottom margin in pixels.
+ */
+ @UiThread
+ public void setCompassMargins(int left, int top, int right, int bottom) {
+ setWidgetMargins(compassView, left, top, right, bottom);
+ }
+
+ /**
+ * Returns the left side margin of CompassView
+ *
+ * @return The left margin in pixels
+ */
+ public int getCompassMarginLeft() {
+ return ((FrameLayout.LayoutParams) compassView.getLayoutParams()).leftMargin;
+ }
+
+ /**
+ * Returns the top side margin of CompassView
+ *
+ * @return The top margin in pixels
+ */
+ public int getCompassMarginTop() {
+ return ((FrameLayout.LayoutParams) compassView.getLayoutParams()).topMargin;
+ }
+
+ /**
+ * Returns the right side margin of CompassView
+ *
+ * @return The right margin in pixels
+ */
+ public int getCompassMarginRight() {
+ return ((FrameLayout.LayoutParams) compassView.getLayoutParams()).rightMargin;
+ }
+
+ /**
+ * Returns the bottom side margin of CompassView
+ *
+ * @return The bottom margin in pixels
+ */
+ public int getCompassMarginBottom() {
+ return ((FrameLayout.LayoutParams) compassView.getLayoutParams()).bottomMargin;
+ }
+
+ void update(@NonNull CameraPosition cameraPosition) {
+ if (!isCompassEnabled()) {
+ return;
+ }
+
+ compassView.update(cameraPosition.bearing);
+ }
+
+ /**
+ * <p>
+ * Enables or disables the Mapbox logo.
+ * </p>
+ * By default, the compass is enabled.
+ *
+ * @param enabled True to enable the logo; false to disable the logo.
+ */
+ public void setLogoEnabled(boolean enabled) {
+ logoView.setVisibility(enabled ? View.VISIBLE : View.GONE);
+ }
+
+ /**
+ * Returns whether the logo is enabled.
+ *
+ * @return True if the logo is enabled; false if the logo is disabled.
+ */
+ public boolean isLogoEnabled() {
+ return logoView.getVisibility() == View.VISIBLE;
+ }
+
+ /**
+ * <p>
+ * Sets the gravity of the logo view. Use this to change the corner of the map view that the
+ * Mapbox logo is displayed in.
+ * </p>
+ * By default, the logo is in the bottom left corner.
+ *
+ * @param gravity One of the values from {@link Gravity}.
+ * @see Gravity
+ */
+ public void setLogoGravity(int gravity) {
+ setWidgetGravity(logoView, gravity);
+ }
+
+ /**
+ * Returns the gravity value of the logo
+ *
+ * @return The gravity
+ */
+ public int getLogoGravity() {
+ return ((FrameLayout.LayoutParams) logoView.getLayoutParams()).gravity;
+ }
+
+ /**
+ * Sets the margins of the logo view. Use this to change the distance of the Mapbox logo from the
+ * map view edge.
+ *
+ * @param left The left margin in pixels.
+ * @param top The top margin in pixels.
+ * @param right The right margin in pixels.
+ * @param bottom The bottom margin in pixels.
+ */
+ public void setLogoMargins(int left, int top, int right, int bottom) {
+ setWidgetMargins(logoView, left, top, right, bottom);
+ }
+
+ /**
+ * Returns the left side margin of the logo
+ *
+ * @return The left margin in pixels
+ */
+ public int getLogoMarginLeft() {
+ return ((FrameLayout.LayoutParams) logoView.getLayoutParams()).leftMargin;
+ }
+
+ /**
+ * Returns the top side margin of the logo
+ *
+ * @return The top margin in pixels
+ */
+ public int getLogoMarginTop() {
+ return ((FrameLayout.LayoutParams) logoView.getLayoutParams()).topMargin;
+ }
+
+ /**
+ * Returns the right side margin of the logo
+ *
+ * @return The right margin in pixels
+ */
+ public int getLogoMarginRight() {
+ return ((FrameLayout.LayoutParams) logoView.getLayoutParams()).rightMargin;
+ }
+
+ /**
+ * Returns the bottom side margin of the logo
+ *
+ * @return The bottom margin in pixels
+ */
+ public int getLogoMarginBottom() {
+ return ((FrameLayout.LayoutParams) logoView.getLayoutParams()).bottomMargin;
+ }
+
+ /**
+ * <p>
+ * Enables or disables the attribution.
+ * </p>
+ * By default, the attribution is enabled.
+ *
+ * @param enabled True to enable the attribution; false to disable the attribution.
+ */
+ public void setAttributionEnabled(boolean enabled) {
+ attributionsView.setVisibility(enabled ? View.VISIBLE : View.GONE);
+ }
+
+ /**
+ * Returns whether the attribution is enabled.
+ *
+ * @return True if the attribution is enabled; false if the attribution is disabled.
+ */
+ public boolean isAttributionEnabled() {
+ return attributionsView.getVisibility() == View.VISIBLE;
+ }
+
+ /**
+ * <p>
+ * Sets the gravity of the attribution.
+ * </p>
+ * By default, the attribution is in the bottom left corner next to the Mapbox logo.
+ *
+ * @param gravity One of the values from {@link Gravity}.
+ * @see Gravity
+ */
+ public void setAttributionGravity(int gravity) {
+ setWidgetGravity(attributionsView, gravity);
+ }
+
+ /**
+ * Returns the gravity value of the logo
+ *
+ * @return The gravity
+ */
+ public int getAttributionGravity() {
+ return ((FrameLayout.LayoutParams) attributionsView.getLayoutParams()).gravity;
+ }
+
+ /**
+ * Sets the margins of the attribution view.
+ *
+ * @param left The left margin in pixels.
+ * @param top The top margin in pixels.
+ * @param right The right margin in pixels.
+ * @param bottom The bottom margin in pixels.
+ */
+ public void setAttributionMargins(int left, int top, int right, int bottom) {
+ setWidgetMargins(attributionsView, left, top, right, bottom);
+ }
+
+ /**
+ * <p>
+ * Sets the tint of the attribution view. Use this to change the color of the attribution.
+ * </p>
+ * By default, the logo is tinted with the primary color of your theme.
+ *
+ * @param tintColor Color to tint the attribution.
+ */
+ public void setAttributionTintColor(@ColorInt int tintColor) {
+ // Check that the tint color being passed in isn't transparent.
+ if (Color.alpha(tintColor) == 0) {
+ ColorUtils.setTintList(attributionsView,
+ ContextCompat.getColor(attributionsView.getContext(), R.color.mapbox_blue));
+ } else {
+ ColorUtils.setTintList(attributionsView, tintColor);
+ }
+ }
+
+ /**
+ * Returns the left side margin of the attribution view.
+ *
+ * @return The left margin in pixels
+ */
+ public int getAttributionMarginLeft() {
+ return ((FrameLayout.LayoutParams) attributionsView.getLayoutParams()).leftMargin;
+ }
+
+ /**
+ * Returns the top side margin of the attribution view.
+ *
+ * @return The top margin in pixels
+ */
+ public int getAttributionMarginTop() {
+ return ((FrameLayout.LayoutParams) attributionsView.getLayoutParams()).topMargin;
+ }
+
+ /**
+ * Returns the right side margin of the attribution view.
+ *
+ * @return The right margin in pixels
+ */
+ public int getAttributionMarginRight() {
+ return ((FrameLayout.LayoutParams) attributionsView.getLayoutParams()).rightMargin;
+ }
+
+ /**
+ * Returns the bottom side margin of the logo
+ *
+ * @return The bottom margin in pixels
+ */
+ public int getAttributionMarginBottom() {
+ return ((FrameLayout.LayoutParams) attributionsView.getLayoutParams()).bottomMargin;
+ }
+
+ /**
+ * <p>
+ * Changes whether the user may rotate the map.
+ * </p>
+ * <p>
+ * This setting controls only user interactions with the map. If you set the value to false,
+ * you may still change the map location programmatically.
+ * </p>
+ * The default value is true.
+ *
+ * @param rotateGesturesEnabled If true, rotating is enabled.
+ */
+ public void setRotateGesturesEnabled(boolean rotateGesturesEnabled) {
+ if (rotateGestureChangeAllowed) {
+ this.rotateGesturesEnabled = rotateGesturesEnabled;
+ }
+ }
+
+ /**
+ * Returns whether the user may rotate the map.
+ *
+ * @return If true, rotating is enabled.
+ */
+ public boolean isRotateGesturesEnabled() {
+ return rotateGesturesEnabled;
+ }
+
+ void setRotateGestureChangeAllowed(boolean rotateGestureChangeAllowed) {
+ this.rotateGestureChangeAllowed = rotateGestureChangeAllowed;
+ }
+
+ boolean isRotateGestureChangeAllowed() {
+ return rotateGestureChangeAllowed;
+ }
+
+ /**
+ * <p>
+ * Changes whether the user may tilt the map.
+ * </p>
+ * <p>
+ * This setting controls only user interactions with the map. If you set the value to false,
+ * you may still change the map location programmatically.
+ * </p>
+ * The default value is true.
+ *
+ * @param tiltGesturesEnabled If true, tilting is enabled.
+ */
+ public void setTiltGesturesEnabled(boolean tiltGesturesEnabled) {
+ if (tiltGestureChangeAllowed) {
+ this.tiltGesturesEnabled = tiltGesturesEnabled;
+ }
+ }
+
+ /**
+ * Returns whether the user may tilt the map.
+ *
+ * @return If true, tilting is enabled.
+ */
+ public boolean isTiltGesturesEnabled() {
+ return tiltGesturesEnabled;
+ }
+
+ void setTiltGestureChangeAllowed(boolean tiltGestureChangeAllowed) {
+ this.tiltGestureChangeAllowed = tiltGestureChangeAllowed;
+ }
+
+ boolean isTiltGestureChangeAllowed() {
+ return tiltGestureChangeAllowed;
+ }
+
+ /**
+ * <p>
+ * Changes whether the user may zoom the map.
+ * </p>
+ * <p>
+ * This setting controls only user interactions with the map. If you set the value to false,
+ * you may still change the map location programmatically.
+ * </p>
+ * The default value is true.
+ *
+ * @param zoomGesturesEnabled If true, zooming is enabled.
+ */
+ public void setZoomGesturesEnabled(boolean zoomGesturesEnabled) {
+ if (zoomGestureChangeAllowed) {
+ this.zoomGesturesEnabled = zoomGesturesEnabled;
+ }
+ }
+
+ /**
+ * Returns whether the user may zoom the map.
+ *
+ * @return If true, zooming is enabled.
+ */
+ public boolean isZoomGesturesEnabled() {
+ return zoomGesturesEnabled;
+ }
+
+ void setZoomGestureChangeAllowed(boolean zoomGestureChangeAllowed) {
+ this.zoomGestureChangeAllowed = zoomGestureChangeAllowed;
+ }
+
+ boolean isZoomGestureChangeAllowed() {
+ return zoomGestureChangeAllowed;
+ }
+
+ /**
+ * <p>
+ * Sets whether the zoom controls are enabled.
+ * If enabled, the zoom controls are a pair of buttons
+ * (one for zooming in, one for zooming out) that appear on the screen.
+ * When pressed, they cause the camera to zoom in (or out) by one zoom level.
+ * If disabled, the zoom controls are not shown.
+ * </p>
+ * By default the zoom controls are enabled if the device is only single touch capable;
+ *
+ * @param zoomControlsEnabled If true, the zoom controls are enabled.
+ */
+ public void setZoomControlsEnabled(boolean zoomControlsEnabled) {
+ this.zoomControlsEnabled = zoomControlsEnabled;
+ }
+
+ /**
+ * Gets whether the zoom controls are enabled.
+ *
+ * @return If true, the zoom controls are enabled.
+ */
+ public boolean isZoomControlsEnabled() {
+ return zoomControlsEnabled;
+ }
+
+ /**
+ * Gets whether the markers are automatically deselected (and therefore, their infowindows
+ * closed) when a map tap is detected.
+ *
+ * @return If true, markers are deselected on a map tap.
+ */
+ public boolean isDeselectMarkersOnTap() {
+ return deselectMarkersOnTap;
+ }
+
+ /**
+ * Sets whether the markers are automatically deselected (and therefore, their infowindows
+ * closed) when a map tap is detected.
+ *
+ * @param deselectMarkersOnTap determines if markers should be deslected on tap
+ */
+ public void setDeselectMarkersOnTap(boolean deselectMarkersOnTap) {
+ this.deselectMarkersOnTap = deselectMarkersOnTap;
+ }
+
+ /**
+ * <p>
+ * Changes whether the user may scroll around the map.
+ * </p>
+ * <p>
+ * This setting controls only user interactions with the map. If you set the value to false,
+ * you may still change the map location programmatically.
+ * </p>
+ * The default value is true.
+ *
+ * @param scrollGesturesEnabled If true, scrolling is enabled.
+ */
+ public void setScrollGesturesEnabled(boolean scrollGesturesEnabled) {
+ if (scrollGestureChangeAllowed) {
+ this.scrollGesturesEnabled = scrollGesturesEnabled;
+ }
+ }
+
+ /**
+ * Returns whether the user may scroll around the map.
+ *
+ * @return If true, scrolling is enabled.
+ */
+ public boolean isScrollGesturesEnabled() {
+ return scrollGesturesEnabled;
+ }
+
+ void setScrollGestureChangeAllowed(boolean scrollGestureChangeAllowed) {
+ this.scrollGestureChangeAllowed = scrollGestureChangeAllowed;
+ }
+
+ boolean isScrollGestureChangeAllowed() {
+ return scrollGestureChangeAllowed;
+ }
+
+ /**
+ * <p>
+ * Sets the preference for whether all gestures should be enabled or disabled.
+ * </p>
+ * <p>
+ * This setting controls only user interactions with the map. If you set the value to false,
+ * you may still change the map location programmatically.
+ * </p>
+ * The default value is true.
+ *
+ * @param enabled If true, all gestures are available; otherwise, all gestures are disabled.
+ * @see #setZoomGesturesEnabled(boolean) )
+ * @see #setScrollGesturesEnabled(boolean)
+ * @see #setRotateGesturesEnabled(boolean)
+ * @see #setTiltGesturesEnabled(boolean)
+ */
+ public void setAllGesturesEnabled(boolean enabled) {
+ setScrollGesturesEnabled(enabled);
+ setRotateGesturesEnabled(enabled);
+ setTiltGesturesEnabled(enabled);
+ setZoomGesturesEnabled(enabled);
+ }
+
+ /**
+ * Sets the focal point used as center for a gesture
+ *
+ * @param focalPoint the focal point to be used.
+ */
+ public void setFocalPoint(@Nullable PointF focalPoint) {
+ this.userProvidedFocalPoint = focalPoint;
+ focalPointChangeListener.onFocalPointChanged(focalPoint);
+ }
+
+ /**
+ * Returns the gesture focal point
+ *
+ * @return The focal point
+ */
+ public PointF getFocalPoint() {
+ return userProvidedFocalPoint;
+ }
+
+ /**
+ * Returns the measured height of the MapView
+ *
+ * @return height in pixels
+ */
+ public float getHeight() {
+ return projection.getHeight();
+ }
+
+ /**
+ * Returns the measured width of the MapView
+ *
+ * @return widht in pixels
+ */
+ public float getWidth() {
+ return projection.getWidth();
+ }
+
+ float getPixelRatio() {
+ return pixelRatio;
+ }
+
+ /**
+ * Invalidates the ViewSettings instances shown on top of the MapView
+ */
+ public void invalidate() {
+ setLogoMargins(getLogoMarginLeft(), getLogoMarginTop(), getLogoMarginRight(), getLogoMarginBottom());
+ setCompassMargins(getCompassMarginLeft(), getCompassMarginTop(), getCompassMarginRight(), getCompassMarginBottom());
+ setAttributionMargins(getAttributionMarginLeft(), getAttributionMarginTop(), getAttributionMarginRight(),
+ getAttributionMarginBottom());
+ }
+
+ private void setWidgetGravity(@NonNull final View view, int gravity) {
+ FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) view.getLayoutParams();
+ layoutParams.gravity = gravity;
+ view.setLayoutParams(layoutParams);
+ }
+
+ private void setWidgetMargins(@NonNull final View view, int left, int top, int right, int bottom) {
+ int[] contentPadding = projection.getContentPadding();
+ FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) view.getLayoutParams();
+ left += contentPadding[0];
+ top += contentPadding[1];
+ right += contentPadding[2];
+ bottom += contentPadding[3];
+ layoutParams.setMargins(left, top, right, bottom);
+ view.setLayoutParams(layoutParams);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/ViewSettings.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/ViewSettings.java
deleted file mode 100644
index 4478978853..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/ViewSettings.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.mapbox.mapboxsdk.maps;
-
-/**
- * Settings for the overlain views of a MapboxMap. Used by UiSettings.
- */
-class ViewSettings {
-
- private boolean enabled;
- private int gravity;
- private int[] margins;
- private int tintColor;
-
- public ViewSettings() {
- margins = new int[4];
- }
-
- public boolean isEnabled() {
- return enabled;
- }
-
- public void setEnabled(boolean enabled) {
- this.enabled = enabled;
- }
-
- public int getGravity() {
- return gravity;
- }
-
- public void setGravity(int gravity) {
- this.gravity = gravity;
- }
-
- public int[] getMargins() {
- return margins;
- }
-
- public void setMargins(int[] margins) {
- this.margins = margins;
- }
-
- public int getTintColor() {
- return tintColor;
- }
-
- public void setTintColor(int tintColor) {
- this.tintColor = tintColor;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/CompassView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/CompassView.java
index 163c7a610a..dc4a21f2fe 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/CompassView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/CompassView.java
@@ -27,133 +27,140 @@ import java.lang.ref.WeakReference;
*/
public final class CompassView extends ImageView implements Runnable {
- private static final long TIME_WAIT_IDLE = 500;
- private static final long TIME_FADE_ANIMATION = TIME_WAIT_IDLE;
- private static final long TIME_MAP_NORTH_ANIMATION = 150;
-
- private double direction = 0.0;
- private boolean fadeCompassViewFacingNorth = true;
- private ViewPropertyAnimatorCompat fadeAnimator;
-
- public CompassView(Context context) {
- super(context);
- initialize(context);
+ private static final long TIME_WAIT_IDLE = 500;
+ private static final long TIME_FADE_ANIMATION = TIME_WAIT_IDLE;
+ private static final long TIME_MAP_NORTH_ANIMATION = 150;
+
+ private double direction = 0.0;
+ private boolean fadeCompassViewFacingNorth = true;
+ private ViewPropertyAnimatorCompat fadeAnimator;
+
+ public CompassView(Context context) {
+ super(context);
+ initialize(context);
+ }
+
+ public CompassView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ initialize(context);
+ }
+
+ public CompassView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ initialize(context);
+ }
+
+ private void initialize(Context context) {
+ setImageDrawable(ContextCompat.getDrawable(getContext(), R.drawable.mapbox_compass_icon));
+ setContentDescription(getResources().getString(R.string.mapbox_compassContentDescription));
+ setEnabled(false);
+
+ // Layout params
+ float screenDensity = context.getResources().getDisplayMetrics().density;
+ ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams((int) (48 * screenDensity), (int) (48 * screenDensity));
+ setLayoutParams(lp);
+ }
+
+ // TODO refactor MapboxMap and replace with interface
+ public void setMapboxMap(@NonNull MapboxMap mapboxMap) {
+ setOnClickListener(new CompassClickListener(mapboxMap, this));
+ }
+
+ private void resetAnimation() {
+ if (fadeAnimator != null) {
+ fadeAnimator.cancel();
}
-
- public CompassView(Context context, AttributeSet attrs) {
- super(context, attrs);
- initialize(context);
+ fadeAnimator = null;
+ }
+
+ public boolean isHidden() {
+ return fadeCompassViewFacingNorth && isFacingNorth();
+ }
+
+ public boolean isFacingNorth() {
+ // increase range more than just 0.0
+ return direction >= 359.0 || direction <= 1.0;
+ }
+
+ @Override
+ public void setEnabled(boolean enabled) {
+ super.setEnabled(enabled);
+ if (enabled && !isHidden()) {
+ resetAnimation();
+ setAlpha(1.0f);
+ setVisibility(View.VISIBLE);
+ } else {
+ resetAnimation();
+ setAlpha(0.0f);
+ setVisibility(View.INVISIBLE);
}
+ }
- public CompassView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- initialize(context);
- }
+ public void update(final double direction) {
+ this.direction = direction;
- private void initialize(Context context) {
- setImageDrawable(ContextCompat.getDrawable(getContext(), R.drawable.compass));
- setContentDescription(getResources().getString(R.string.compassContentDescription));
- setEnabled(false);
-
- // Layout params
- float screenDensity = context.getResources().getDisplayMetrics().density;
- ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams((int) (48 * screenDensity), (int) (48 * screenDensity));
- setLayoutParams(lp);
+ if (!isEnabled()) {
+ return;
}
- public void setMapboxMap(@NonNull MapboxMap mapboxMap) {
- setOnClickListener(new CompassClickListener(mapboxMap, this));
+ if (isHidden()) {
+ if (getVisibility() == View.INVISIBLE || fadeAnimator != null) {
+ return;
+ }
+ postDelayed(this, TIME_WAIT_IDLE);
+ return;
+ } else {
+ resetAnimation();
+ setAlpha(1.0f);
+ setVisibility(View.VISIBLE);
}
- private void resetAnimation() {
- if (fadeAnimator != null) {
- fadeAnimator.cancel();
- }
- fadeAnimator = null;
- }
+ setRotation((float) direction);
+ }
- public boolean isHidden() {
- return fadeCompassViewFacingNorth && isFacingNorth();
- }
+ public void fadeCompassViewFacingNorth(boolean compassFadeFacingNorth) {
+ fadeCompassViewFacingNorth = compassFadeFacingNorth;
+ }
- public boolean isFacingNorth() {
- // increase range more than just 0.0
- return direction >= 359.0 || direction <= 1.0;
- }
+ public boolean isFadeCompassViewFacingNorth() {
+ return fadeCompassViewFacingNorth;
+ }
- @Override
- public void setEnabled(boolean enabled) {
- super.setEnabled(enabled);
- if (enabled && !isHidden()) {
- resetAnimation();
- setAlpha(1.0f);
- setVisibility(View.VISIBLE);
- } else {
- resetAnimation();
- setAlpha(0.0f);
- setVisibility(View.INVISIBLE);
+ @Override
+ public void run() {
+ if (isFacingNorth() && fadeCompassViewFacingNorth) {
+ resetAnimation();
+ setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ fadeAnimator = ViewCompat.animate(CompassView.this).alpha(0.0f).setDuration(TIME_FADE_ANIMATION);
+ fadeAnimator.setListener(new ViewPropertyAnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(View view) {
+ setLayerType(LAYER_TYPE_NONE, null);
+ setVisibility(View.INVISIBLE);
+ resetAnimation();
}
+ });
}
+ }
- public void update(final double direction) {
- this.direction = direction;
+ static class CompassClickListener implements View.OnClickListener {
- if (!isEnabled()) {
- return;
- }
+ private WeakReference<MapboxMap> mapboxMap;
+ private WeakReference<CompassView> compassView;
- if (isHidden()) {
- if (getVisibility() == View.INVISIBLE || fadeAnimator != null) {
- return;
- }
- postDelayed(this, TIME_WAIT_IDLE);
- return;
- } else {
- resetAnimation();
- setAlpha(1.0f);
- setVisibility(View.VISIBLE);
- }
-
- setRotation((float) direction);
- }
-
- public void fadeCompassViewFacingNorth(boolean compassFadeFacingNorth) {
- fadeCompassViewFacingNorth = compassFadeFacingNorth;
+ CompassClickListener(final MapboxMap mapboxMap, CompassView compassView) {
+ this.mapboxMap = new WeakReference<>(mapboxMap);
+ this.compassView = new WeakReference<>(compassView);
}
@Override
- public void run() {
- if (isFacingNorth() && fadeCompassViewFacingNorth) {
- resetAnimation();
- fadeAnimator = ViewCompat.animate(CompassView.this).alpha(0.0f).setDuration(TIME_FADE_ANIMATION).withLayer();
- fadeAnimator.setListener(new ViewPropertyAnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(View view) {
- setVisibility(View.INVISIBLE);
- resetAnimation();
- }
- });
- }
- }
-
- static class CompassClickListener implements View.OnClickListener {
-
- private WeakReference<MapboxMap> mapboxMap;
- private WeakReference<CompassView> compassView;
-
- CompassClickListener(final MapboxMap mapboxMap, CompassView compassView) {
- this.mapboxMap = new WeakReference<>(mapboxMap);
- this.compassView = new WeakReference<>(compassView);
- }
-
- @Override
- public void onClick(View view) {
- final MapboxMap mapboxMap = this.mapboxMap.get();
- final CompassView compassView = this.compassView.get();
- if (mapboxMap != null && compassView != null) {
- mapboxMap.resetNorth();
- compassView.postDelayed(compassView, TIME_WAIT_IDLE + TIME_MAP_NORTH_ANIMATION);
- }
- }
+ public void onClick(View view) {
+ final MapboxMap mapboxMap = this.mapboxMap.get();
+ final CompassView compassView = this.compassView.get();
+ if (mapboxMap != null && compassView != null) {
+ mapboxMap.resetNorth();
+ compassView.postDelayed(compassView, TIME_WAIT_IDLE + TIME_MAP_NORTH_ANIMATION);
+ }
}
+ }
}
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 45e0c4903e..d34b0f693d 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
@@ -4,7 +4,6 @@ import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Camera;
import android.graphics.Canvas;
-import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PointF;
@@ -44,728 +43,753 @@ import java.lang.ref.WeakReference;
*/
public class MyLocationView extends View {
- private MyLocationBehavior myLocationBehavior;
- private MapboxMap mapboxMap;
+ private MyLocationBehavior myLocationBehavior;
+ private MapboxMap mapboxMap;
- private Projection projection;
- private float[] projectedCoordinate = new float[2];
- private float projectedX;
- private float projectedY;
+ private Projection projection;
+ private float[] projectedCoordinate = new float[2];
+ private float projectedX;
+ private float projectedY;
- private float contentPaddingX;
- private float contentPaddingY;
+ private float contentPaddingX;
+ private float contentPaddingY;
- private LatLng latLng;
- private Location location;
- private long locationUpdateTimestamp;
- private float previousDirection;
+ private LatLng latLng;
+ private Location location;
+ private long locationUpdateTimestamp;
+ private float previousDirection;
- private float accuracy;
- private Paint accuracyPaint;
+ private float accuracy;
+ private Paint accuracyPaint;
- private ValueAnimator locationChangeAnimator;
- private ValueAnimator accuracyAnimator;
- private ValueAnimator directionAnimator;
+ private ValueAnimator locationChangeAnimator;
+ private ValueAnimator accuracyAnimator;
+ private ValueAnimator directionAnimator;
- private ValueAnimator.AnimatorUpdateListener invalidateSelfOnUpdateListener =
- new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- invalidate();
- }
- };
-
- private Drawable foregroundDrawable;
- private Drawable foregroundBearingDrawable;
- private Drawable backgroundDrawable;
+ private ValueAnimator.AnimatorUpdateListener invalidateSelfOnUpdateListener =
+ new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ invalidate();
+ }
+ };
- private Rect foregroundBounds;
- private Rect backgroundBounds;
+ private Drawable foregroundDrawable;
+ private Drawable foregroundBearingDrawable;
+ private Drawable backgroundDrawable;
- private int backgroundOffsetLeft;
- private int backgroundOffsetTop;
- private int backgroundOffsetRight;
- private int backgroundOffsetBottom;
+ private Rect foregroundBounds;
+ private Rect backgroundBounds;
- private Matrix matrix;
- private Camera camera;
- private PointF screenLocation;
+ private int backgroundOffsetLeft;
+ private int backgroundOffsetTop;
+ private int backgroundOffsetRight;
+ private int backgroundOffsetBottom;
- // camera vars
- private float bearing;
- private float tilt;
+ private Matrix matrix;
+ private Camera camera;
+ private PointF screenLocation;
- // Controls the compass update rate in milliseconds
- private static final int COMPASS_UPDATE_RATE_MS = 500;
+ // camera vars
+ private double tilt;
+ private double bearing;
+ private float magneticHeading;
- @MyLocationTracking.Mode
- private int myLocationTrackingMode;
+ // Controls the compass update rate in milliseconds
+ private static final int COMPASS_UPDATE_RATE_MS = 500;
- @MyBearingTracking.Mode
- private int myBearingTrackingMode;
+ @MyLocationTracking.Mode
+ private int myLocationTrackingMode;
- private GpsLocationListener userLocationListener;
- private CompassListener compassListener;
+ @MyBearingTracking.Mode
+ private int myBearingTrackingMode;
- public MyLocationView(Context context) {
- super(context);
- init(context);
- }
-
- public MyLocationView(Context context, AttributeSet attrs) {
- super(context, attrs);
- init(context);
- }
-
- public MyLocationView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- init(context);
- }
-
- private void init(Context context) {
- if (isInEditMode()) {
- return;
- }
+ private GpsLocationListener userLocationListener;
+ private CompassListener compassListener;
- setEnabled(false);
+ public MyLocationView(Context context) {
+ super(context);
+ init(context);
+ }
- // setup LayoutParams
- ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.MATCH_PARENT);
- setLayoutParams(lp);
+ public MyLocationView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context);
+ }
- matrix = new Matrix();
- camera = new Camera();
- camera.setLocation(0, 0, -1000);
- accuracyPaint = new Paint();
+ public MyLocationView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init(context);
+ }
- myLocationBehavior = new MyLocationBehaviorFactory().getBehavioralModel(MyLocationTracking.TRACKING_NONE);
- compassListener = new CompassListener(context);
+ private void init(Context context) {
+ if (isInEditMode()) {
+ return;
}
- public final void setForegroundDrawables(Drawable defaultDrawable, Drawable bearingDrawable) {
- if (defaultDrawable == null) {
- return;
- }
+ setEnabled(false);
- if (bearingDrawable == null) {
- // if user only provided one resource
- // use same for bearing mode
- bearingDrawable = defaultDrawable.getConstantState().newDrawable();
- }
+ // setup LayoutParams
+ ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ setLayoutParams(lp);
- if (backgroundDrawable == null) {
- // if the user didn't provide a background resource we will use the foreground resource instead,
- // we need to create a new drawable to handle tinting correctly
- backgroundDrawable = defaultDrawable.getConstantState().newDrawable();
- }
+ matrix = new Matrix();
+ camera = new Camera();
+ camera.setLocation(0, 0, -1000);
+ accuracyPaint = new Paint();
- if (defaultDrawable.getIntrinsicWidth() != bearingDrawable.getIntrinsicWidth() || defaultDrawable.getIntrinsicHeight() != bearingDrawable.getIntrinsicHeight()) {
- throw new RuntimeException("The dimensions from location and bearing drawables should be match");
- }
+ myLocationBehavior = new MyLocationBehaviorFactory().getBehavioralModel(MyLocationTracking.TRACKING_NONE);
+ compassListener = new CompassListener(context);
+ }
- foregroundDrawable = defaultDrawable;
- foregroundBearingDrawable = bearingDrawable;
+ public final void setForegroundDrawables(Drawable defaultDrawable, Drawable bearingDrawable) {
+ if (defaultDrawable == null) {
+ return;
+ }
- invalidateBounds();
+ if (bearingDrawable == null) {
+ // if user only provided one resource
+ // use same for bearing mode
+ bearingDrawable = defaultDrawable.getConstantState().newDrawable();
}
- public final void setForegroundDrawableTint(@ColorInt int color) {
- if (color != Color.TRANSPARENT) {
- if (foregroundDrawable != null) {
- foregroundDrawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
- }
- if (foregroundBearingDrawable != null) {
- foregroundBearingDrawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
- }
- }
- invalidate();
+ if (backgroundDrawable == null) {
+ // if the user didn't provide a background resource we will use the foreground resource instead,
+ // we need to create a new drawable to handle tinting correctly
+ backgroundDrawable = defaultDrawable.getConstantState().newDrawable();
}
- public final void setShadowDrawable(Drawable drawable) {
- setShadowDrawable(drawable, 0, 0, 0, 0);
+ if (defaultDrawable.getIntrinsicWidth() != bearingDrawable.getIntrinsicWidth()
+ || defaultDrawable.getIntrinsicHeight() != bearingDrawable.getIntrinsicHeight()) {
+ throw new RuntimeException("The dimensions from location and bearing drawables should be match");
}
- public final void setShadowDrawable(Drawable drawable, int left, int top, int right, int bottom) {
- if (drawable != null) {
- backgroundDrawable = drawable;
- }
+ foregroundDrawable = defaultDrawable;
+ foregroundBearingDrawable = bearingDrawable;
- backgroundOffsetLeft = left;
- backgroundOffsetTop = top;
- backgroundOffsetRight = right;
- backgroundOffsetBottom = bottom;
+ invalidateBounds();
+ }
- invalidateBounds();
+ public final void setForegroundDrawableTint(@ColorInt int color) {
+ if (foregroundDrawable != null) {
+ foregroundDrawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
}
-
- public final void setShadowDrawableTint(@ColorInt int color) {
- if (color != Color.TRANSPARENT) {
- if (backgroundDrawable == null) {
- return;
- }
- backgroundDrawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
- }
- invalidate();
+ if (foregroundBearingDrawable != null) {
+ foregroundBearingDrawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
}
+ invalidate();
+ }
- public final void setAccuracyTint(@ColorInt int color) {
- int alpha = accuracyPaint.getAlpha();
- accuracyPaint.setColor(color);
- accuracyPaint.setAlpha(alpha);
- invalidate();
- }
+ public final void setShadowDrawable(Drawable drawable) {
+ setShadowDrawable(drawable, 0, 0, 0, 0);
+ }
- public final void setAccuracyAlpha(@IntRange(from = 0, to = 255) int alpha) {
- accuracyPaint.setAlpha(alpha);
- invalidate();
+ public final void setShadowDrawable(Drawable drawable, int left, int top, int right, int bottom) {
+ if (drawable != null) {
+ backgroundDrawable = drawable;
}
- private void invalidateBounds() {
- if (backgroundDrawable == null || foregroundDrawable == null || foregroundBearingDrawable == null) {
- return;
- }
-
- int backgroundWidth = backgroundDrawable.getIntrinsicWidth();
- int backgroundHeight = backgroundDrawable.getIntrinsicHeight();
- int horizontalOffset = backgroundOffsetLeft - backgroundOffsetRight;
- int verticalOffset = backgroundOffsetTop - backgroundOffsetBottom;
- backgroundBounds = new Rect(-backgroundWidth / 2 + horizontalOffset, -backgroundHeight / 2 + verticalOffset, backgroundWidth / 2 + horizontalOffset, backgroundHeight / 2 + verticalOffset);
- backgroundDrawable.setBounds(backgroundBounds);
+ backgroundOffsetLeft = left;
+ backgroundOffsetTop = top;
+ backgroundOffsetRight = right;
+ backgroundOffsetBottom = bottom;
- int foregroundWidth = foregroundDrawable.getIntrinsicWidth();
- int foregroundHeight = foregroundDrawable.getIntrinsicHeight();
- foregroundBounds = new Rect(-foregroundWidth / 2, -foregroundHeight / 2, foregroundWidth / 2, foregroundHeight / 2);
- foregroundDrawable.setBounds(foregroundBounds);
- foregroundBearingDrawable.setBounds(foregroundBounds);
+ invalidateBounds();
+ }
- // invoke a new draw
- invalidate();
+ public final void setShadowDrawableTint(@ColorInt int color) {
+ if (backgroundDrawable == null) {
+ return;
}
+ backgroundDrawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
+ invalidate();
+ }
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
-
- if (location == null || foregroundBounds == null || backgroundBounds == null || accuracyAnimator == null || screenLocation == null) {
- // Not ready yet
- return;
- }
+ public final void setAccuracyTint(@ColorInt int color) {
+ int alpha = accuracyPaint.getAlpha();
+ accuracyPaint.setColor(color);
+ accuracyPaint.setAlpha(alpha);
+ invalidate();
+ }
- 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;
+ public final void setAccuracyAlpha(@IntRange(from = 0, to = 255) int alpha) {
+ accuracyPaint.setAlpha(alpha);
+ invalidate();
+ }
- // reset
- matrix.reset();
- projectedCoordinate[0] = 0;
- projectedCoordinate[1] = 0;
+ private void invalidateBounds() {
+ if (backgroundDrawable == null || foregroundDrawable == null || foregroundBearingDrawable == null) {
+ return;
+ }
- // put camera in position
- camera.save();
- camera.rotate(tilt, 0, 0);
- camera.getMatrix(matrix);
+ int backgroundWidth = backgroundDrawable.getIntrinsicWidth();
+ int backgroundHeight = backgroundDrawable.getIntrinsicHeight();
+ int horizontalOffset = backgroundOffsetLeft - backgroundOffsetRight;
+ int verticalOffset = backgroundOffsetTop - backgroundOffsetBottom;
+ backgroundBounds = new Rect(-backgroundWidth / 2 + horizontalOffset,
+ -backgroundHeight / 2 + verticalOffset, backgroundWidth / 2 + horizontalOffset, backgroundHeight / 2
+ + verticalOffset);
+ backgroundDrawable.setBounds(backgroundBounds);
- if (myBearingTrackingMode != MyBearingTracking.NONE && directionAnimator != null) {
- matrix.preRotate((Float) directionAnimator.getAnimatedValue());
- }
+ int foregroundWidth = foregroundDrawable.getIntrinsicWidth();
+ int foregroundHeight = foregroundDrawable.getIntrinsicHeight();
+ foregroundBounds = new Rect(-foregroundWidth / 2, -foregroundHeight / 2, foregroundWidth / 2, foregroundHeight / 2);
+ foregroundDrawable.setBounds(foregroundBounds);
+ foregroundBearingDrawable.setBounds(foregroundBounds);
- matrix.preTranslate(0, contentPaddingY);
- matrix.postTranslate(pointF.x, pointF.y - contentPaddingY);
+ // invoke a new draw
+ invalidate();
+ }
- // concat our matrix on canvas
- canvas.concat(matrix);
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
- // calculate focal point
- matrix.mapPoints(projectedCoordinate);
- projectedX = pointF.x - projectedCoordinate[0];
- projectedY = pointF.y - projectedCoordinate[1];
+ if (location == null || foregroundBounds == null || backgroundBounds == null || accuracyAnimator == null
+ || screenLocation == null) {
+ // Not ready yet
+ return;
+ }
- // restore orientation from camera
- camera.restore();
+ 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;
- // draw circle
- canvas.drawCircle(0, 0, accuracyPixels, accuracyPaint);
+ // reset
+ matrix.reset();
+ projectedCoordinate[0] = 0;
+ projectedCoordinate[1] = 0;
- // draw shadow
- if (backgroundDrawable != null) {
- backgroundDrawable.draw(canvas);
- }
+ // put camera in position
+ camera.save();
+ camera.rotate((float) tilt, 0, 0);
+ camera.getMatrix(matrix);
- // draw foreground
- if (myBearingTrackingMode == MyBearingTracking.NONE) {
- if (foregroundDrawable != null) {
- foregroundDrawable.draw(canvas);
- }
- } else if (foregroundBearingDrawable != null && foregroundBounds != null) {
- foregroundBearingDrawable.draw(canvas);
- }
- }
-
- 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()));
- }
+ if (myBearingTrackingMode != MyBearingTracking.NONE && directionAnimator != null) {
+ matrix.preRotate((Float) directionAnimator.getAnimatedValue());
}
- public void setBearing(double bearing) {
- this.bearing = (float) bearing;
- }
+ matrix.preTranslate(0, contentPaddingY);
+ matrix.postTranslate(pointF.x, pointF.y - contentPaddingY);
- public void setCameraPosition(CameraPosition position) {
- setTilt(position.tilt);
- setBearing(position.bearing);
- }
+ // concat our matrix on canvas
+ canvas.concat(matrix);
- public void onResume() {
- if (myBearingTrackingMode == MyBearingTracking.COMPASS) {
- compassListener.onResume();
- }
- if (isEnabled()) {
- toggleGps(true);
- }
- }
+ // calculate focal point
+ matrix.mapPoints(projectedCoordinate);
+ projectedX = pointF.x - projectedCoordinate[0];
+ projectedY = pointF.y - projectedCoordinate[1];
- public void onPause() {
- compassListener.onPause();
- toggleGps(false);
- }
+ // restore orientation from camera
+ camera.restore();
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- // cleanup to prevent memory leaks
- if (locationChangeAnimator != null) {
- locationChangeAnimator.cancel();
- locationChangeAnimator = null;
- }
+ // draw circle
+ canvas.drawCircle(0, 0, accuracyPixels, accuracyPaint);
- if (accuracyAnimator != null) {
- accuracyAnimator.cancel();
- accuracyAnimator = null;
- }
+ // draw shadow
+ if (backgroundDrawable != null) {
+ backgroundDrawable.draw(canvas);
+ }
- if (directionAnimator != null) {
- directionAnimator.cancel();
- directionAnimator = null;
- }
+ // draw foreground
+ if (myBearingTrackingMode == MyBearingTracking.NONE) {
+ if (foregroundDrawable != null) {
+ foregroundDrawable.draw(canvas);
+ }
+ } else if (foregroundBearingDrawable != null && foregroundBounds != null) {
+ foregroundBearingDrawable.draw(canvas);
+ }
+ }
+
+ public void setTilt(@FloatRange(from = 0, to = 60.0f) double tilt) {
+ this.tilt = tilt;
+ if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW) {
+ mapboxMap.getUiSettings().setFocalPoint(new PointF(getCenterX(), getCenterY()));
+ }
+ }
+
+ public void setBearing(double bearing) {
+ this.bearing = bearing;
+ if (myLocationTrackingMode == MyLocationTracking.TRACKING_NONE) {
+ if (myBearingTrackingMode == MyBearingTracking.GPS) {
+ setCompass(location.getBearing() - bearing);
+ } else if (myBearingTrackingMode == MyBearingTracking.COMPASS) {
+ setCompass(magneticHeading - bearing);
+ }
+ }
+ }
+
+ public void setCameraPosition(CameraPosition position) {
+ if (position != null) {
+ setTilt(position.tilt);
+ setBearing(position.bearing);
+ }
+ }
+
+ public void onStart() {
+ if (myBearingTrackingMode == MyBearingTracking.COMPASS) {
+ compassListener.onResume();
+ }
+ if (isEnabled()) {
+ toggleGps(true);
+ }
+ }
- if (userLocationListener != null) {
- LocationServices services = LocationServices.getLocationServices(getContext());
- services.removeLocationListener(userLocationListener);
- userLocationListener = null;
- }
+ public void onStop() {
+ compassListener.onPause();
+ toggleGps(false);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ // cleanup to prevent memory leaks
+ if (locationChangeAnimator != null) {
+ locationChangeAnimator.cancel();
+ locationChangeAnimator = null;
}
- public void update() {
- if (isEnabled()) {
- myLocationBehavior.invalidate();
- } else {
- setVisibility(View.INVISIBLE);
- }
+ if (accuracyAnimator != null) {
+ accuracyAnimator.cancel();
+ accuracyAnimator = null;
+ }
+
+ if (directionAnimator != null) {
+ directionAnimator.cancel();
+ directionAnimator = null;
+ }
+
+ if (userLocationListener != null) {
+ LocationServices services = LocationServices.getLocationServices(getContext());
+ services.removeLocationListener(userLocationListener);
+ userLocationListener = null;
+ }
+ }
+
+ public void update() {
+ if (isEnabled()) {
+ myLocationBehavior.invalidate();
+ } else {
+ setVisibility(View.INVISIBLE);
+ }
+ }
+
+ // TODO refactor MapboxMap out
+ public void setMapboxMap(MapboxMap mapboxMap) {
+ this.mapboxMap = mapboxMap;
+ this.projection = mapboxMap.getProjection();
+ }
+
+ @Override
+ public void setEnabled(boolean enabled) {
+ super.setEnabled(enabled);
+ setVisibility(enabled ? View.VISIBLE : View.INVISIBLE);
+ toggleGps(enabled);
+ }
+
+ @Override
+ protected Parcelable onSaveInstanceState() {
+ Bundle bundle = new Bundle();
+ bundle.putParcelable("superState", super.onSaveInstanceState());
+ bundle.putDouble("tilt", tilt);
+ return bundle;
+ }
+
+ @Override
+ public void onRestoreInstanceState(Parcelable state) {
+ if (state instanceof Bundle) {
+ Bundle bundle = (Bundle) state;
+ tilt = bundle.getDouble("tilt");
+ state = bundle.getParcelable("superState");
+ }
+ super.onRestoreInstanceState(state);
+ }
+
+ /**
+ * Enabled / Disable GPS location updates along with updating the UI
+ *
+ * @param enableGps true if GPS is to be enabled, false if GPS is to be disabled
+ */
+ private void toggleGps(boolean enableGps) {
+ LocationServices locationServices = LocationServices.getLocationServices(getContext());
+ if (enableGps) {
+ // Set an initial location if one available
+ Location lastLocation = locationServices.getLastLocation();
+
+ if (lastLocation != null) {
+ setLocation(lastLocation);
+ }
+
+ if (userLocationListener == null) {
+ userLocationListener = new GpsLocationListener(this);
+ }
+
+ locationServices.addLocationListener(userLocationListener);
+ } else {
+ // Disable location and user dot
+ location = null;
+ locationServices.removeLocationListener(userLocationListener);
+ }
+
+ locationServices.toggleGPS(enableGps);
+ }
+
+ public Location getLocation() {
+ return location;
+ }
+
+ public void setLocation(Location location) {
+ if (location == null) {
+ this.location = null;
+ return;
+ }
+
+ this.location = location;
+ myLocationBehavior.updateLatLng(location);
+ }
+
+ public void setMyBearingTrackingMode(@MyBearingTracking.Mode int myBearingTrackingMode) {
+ this.myBearingTrackingMode = myBearingTrackingMode;
+ if (myBearingTrackingMode == MyBearingTracking.COMPASS) {
+ compassListener.onResume();
+ } else {
+ compassListener.onPause();
+ if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW) {
+ // always face north
+ setCompass(0);
+ } else {
+ myLocationBehavior.invalidate();
+ }
+ }
+ invalidate();
+ }
+
+ public void setMyLocationTrackingMode(@MyLocationTracking.Mode int myLocationTrackingMode) {
+ MyLocationBehaviorFactory factory = new MyLocationBehaviorFactory();
+ myLocationBehavior = factory.getBehavioralModel(myLocationTrackingMode);
+
+ 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);
+ }
+
+ this.myLocationTrackingMode = myLocationTrackingMode;
+ invalidate();
+ }
+
+ @MyLocationTracking.Mode
+ public int getMyLocationTrackingMode() {
+ return myLocationTrackingMode;
+ }
+
+
+ @MyBearingTracking.Mode
+ public int getMyBearingTrackingMode() {
+ return myBearingTrackingMode;
+ }
+
+ private void setCompass(double bearing) {
+ setCompass(bearing, 0 /* no animation */);
+ }
+
+ private void setCompass(double bearing, long duration) {
+ float oldDir = previousDirection;
+ if (directionAnimator != null) {
+ oldDir = (Float) directionAnimator.getAnimatedValue();
+ directionAnimator.end();
+ directionAnimator = null;
+ }
+
+ float newDir = (float) bearing;
+ float diff = oldDir - newDir;
+ if (diff > 180.0f) {
+ newDir += 360.0f;
+ } else if (diff < -180.0f) {
+ newDir -= 360.f;
}
+ previousDirection = newDir;
- public void setMapboxMap(MapboxMap mapboxMap) {
- this.mapboxMap = mapboxMap;
- this.projection = mapboxMap.getProjection();
- }
+ directionAnimator = ValueAnimator.ofFloat(oldDir, newDir);
+ directionAnimator.setDuration(duration);
+ directionAnimator.addUpdateListener(invalidateSelfOnUpdateListener);
+ directionAnimator.start();
+ }
- @Override
- public void setEnabled(boolean enabled) {
- super.setEnabled(enabled);
- setVisibility(enabled ? View.VISIBLE : View.INVISIBLE);
- toggleGps(enabled);
- }
+ public float getCenterX() {
+ return (getX() + getMeasuredWidth()) / 2 + contentPaddingX - projectedX;
+ }
- @Override
- protected Parcelable onSaveInstanceState() {
- Bundle bundle = new Bundle();
- bundle.putParcelable("superState", super.onSaveInstanceState());
- bundle.putFloat("tilt", tilt);
- return bundle;
- }
+ public float getCenterY() {
+ return (getY() + getMeasuredHeight()) / 2 + contentPaddingY - projectedY;
+ }
- @Override
- public void onRestoreInstanceState(Parcelable state) {
- if (state instanceof Bundle) {
- Bundle bundle = (Bundle) state;
- tilt = bundle.getFloat("tilt");
- state = bundle.getParcelable("superState");
- }
- super.onRestoreInstanceState(state);
+ public void setContentPadding(int[] padding) {
+ contentPaddingX = (padding[0] - padding[2]) / 2;
+ contentPaddingY = (padding[1] - padding[3]) / 2;
+ }
+
+ private static class GpsLocationListener implements LocationListener {
+
+ private WeakReference<MyLocationView> userLocationView;
+
+ GpsLocationListener(MyLocationView myLocationView) {
+ userLocationView = new WeakReference<>(myLocationView);
}
/**
- * Enabled / Disable GPS location updates along with updating the UI
+ * Callback method for receiving location updates from LocationServices.
*
- * @param enableGps true if GPS is to be enabled, false if GPS is to be disabled
+ * @param location The new Location data
*/
- private void toggleGps(boolean enableGps) {
- LocationServices locationServices = LocationServices.getLocationServices(getContext());
- if (enableGps) {
- // Set an initial location if one available
- Location lastLocation = locationServices.getLastLocation();
+ @Override
+ public void onLocationChanged(Location location) {
+ MyLocationView locationView = userLocationView.get();
+ if (locationView != null) {
+ locationView.setLocation(location);
+ }
+ }
+ }
- if (lastLocation != null) {
- setLocation(lastLocation);
- }
+ private class CompassListener implements SensorEventListener {
- if (userLocationListener == null) {
- userLocationListener = new GpsLocationListener(this);
- }
+ private final SensorManager sensorManager;
- locationServices.addLocationListener(userLocationListener);
- } else {
- // Disable location and user dot
- location = null;
- locationServices.removeLocationListener(userLocationListener);
- }
+ private Sensor rotationVectorSensor;
+ float[] matrix = new float[9];
+ float[] orientation = new float[3];
- locationServices.toggleGPS(enableGps);
- }
+ // Compass data
+ private long compassUpdateNextTimestamp = 0;
- public Location getLocation() {
- return location;
+ CompassListener(Context context) {
+ sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
+ rotationVectorSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
}
- public void setLocation(Location location) {
- if (location == null) {
- this.location = null;
- return;
- }
-
- this.location = location;
- myLocationBehavior.updateLatLng(location);
+ public void onResume() {
+ sensorManager.registerListener(this, rotationVectorSensor, SensorManager.SENSOR_DELAY_GAME);
}
- public void setMyBearingTrackingMode(@MyBearingTracking.Mode int myBearingTrackingMode) {
- this.myBearingTrackingMode = myBearingTrackingMode;
- if (myBearingTrackingMode == MyBearingTracking.COMPASS) {
- compassListener.onResume();
- } else {
- compassListener.onPause();
- if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW) {
- // always face north
- setCompass(0);
- }
- }
- invalidate();
+ public void onPause() {
+ sensorManager.unregisterListener(this, rotationVectorSensor);
}
- public void setMyLocationTrackingMode(@MyLocationTracking.Mode int myLocationTrackingMode) {
- MyLocationBehaviorFactory factory = new MyLocationBehaviorFactory();
- myLocationBehavior = factory.getBehavioralModel(myLocationTrackingMode);
+ @Override
+ public void onSensorChanged(SensorEvent event) {
- 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);
- }
+ // check when the last time the compass was updated, return if too soon.
+ long currentTime = SystemClock.elapsedRealtime();
+ if (currentTime < compassUpdateNextTimestamp) {
+ return;
+ }
- this.myLocationTrackingMode = myLocationTrackingMode;
- invalidate();
- }
+ if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) {
- private void setCompass(float bearing) {
- float oldDir = previousDirection;
- if (directionAnimator != null) {
- oldDir = (Float) directionAnimator.getAnimatedValue();
- directionAnimator.end();
- directionAnimator = null;
- }
+ // calculate the rotation matrix
+ SensorManager.getRotationMatrixFromVector(matrix, event.values);
+ SensorManager.getOrientation(matrix, orientation);
- float newDir = bearing;
- float diff = oldDir - newDir;
- if (diff > 180.0f) {
- newDir += 360.0f;
- } else if (diff < -180.0f) {
- newDir -= 360.f;
+ magneticHeading = (float) Math.toDegrees(SensorManager.getOrientation(matrix, orientation)[0]);
+ if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW) {
+ // Change the user location view orientation to reflect the device orientation
+ rotateCamera(magneticHeading);
+ setCompass(0, COMPASS_UPDATE_RATE_MS);
+ } else {
+ // Change compass direction
+ setCompass(magneticHeading - bearing, COMPASS_UPDATE_RATE_MS);
}
- previousDirection = newDir;
- directionAnimator = ValueAnimator.ofFloat(oldDir, newDir);
- directionAnimator.setDuration(COMPASS_UPDATE_RATE_MS);
- directionAnimator.addUpdateListener(invalidateSelfOnUpdateListener);
- directionAnimator.start();
+ compassUpdateNextTimestamp = currentTime + COMPASS_UPDATE_RATE_MS;
+ }
}
- public float getCenterX() {
- return (getX() + getMeasuredWidth()) / 2 + contentPaddingX - projectedX;
+ private void rotateCamera(float rotation) {
+ CameraPosition.Builder builder = new CameraPosition.Builder();
+ builder.bearing(rotation);
+ mapboxMap.easeCamera(CameraUpdateFactory.newCameraPosition(builder.build()), COMPASS_UPDATE_RATE_MS,
+ false /*linear interpolator*/, false /*do not disable tracking*/, null);
}
- public float getCenterY() {
- return (getY() + getMeasuredHeight()) / 2 + contentPaddingY - projectedY;
- }
-
- public void setContentPadding(int[] padding) {
- contentPaddingX = (padding[0] - padding[2]) / 2;
- contentPaddingY = (padding[1] - padding[3]) / 2;
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
- private static class GpsLocationListener implements LocationListener {
+ }
- private WeakReference<MyLocationView> userLocationView;
+ private class MarkerCoordinateAnimatorListener implements ValueAnimator.AnimatorUpdateListener {
- GpsLocationListener(MyLocationView myLocationView) {
- userLocationView = new WeakReference<>(myLocationView);
- }
+ private MyLocationBehavior behavior;
+ private double fromLat;
+ private double fromLng;
+ private double toLat;
+ private double toLng;
- /**
- * Callback method for receiving location updates from LocationServices.
- *
- * @param location The new Location data
- */
- @Override
- public void onLocationChanged(Location location) {
- MyLocationView locationView = userLocationView.get();
- if (locationView != null) {
- locationView.setLocation(location);
- }
- }
+ private MarkerCoordinateAnimatorListener(MyLocationBehavior myLocationBehavior, LatLng from, LatLng to) {
+ behavior = myLocationBehavior;
+ fromLat = from.getLatitude();
+ fromLng = from.getLongitude();
+ toLat = to.getLatitude();
+ toLng = to.getLongitude();
}
- private class CompassListener implements SensorEventListener {
-
- private final SensorManager sensorManager;
-
- private Sensor rotationVectorSensor;
- float[] matrix = new float[9];
- float[] orientation = new float[3];
-
- private int currentDegree = 0;
-
- // Compass data
- private long compassUpdateNextTimestamp = 0;
-
- CompassListener(Context context) {
- sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
- rotationVectorSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
- }
-
- public void onResume() {
- sensorManager.registerListener(this, rotationVectorSensor, SensorManager.SENSOR_DELAY_GAME);
- }
-
- public void onPause() {
- sensorManager.unregisterListener(this, rotationVectorSensor);
- }
-
- @Override
- public void onSensorChanged(SensorEvent event) {
-
- // check when the last time the compass was updated, return if too soon.
- long currentTime = SystemClock.elapsedRealtime();
- if (currentTime < compassUpdateNextTimestamp) {
- return;
- }
-
- if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) {
-
- // calculate the rotation matrix
- SensorManager.getRotationMatrixFromVector(matrix, event.values);
- SensorManager.getOrientation(matrix, orientation);
-
- float magneticHeading = (float) Math.toDegrees(SensorManager.getOrientation(matrix, orientation)[0]);
- currentDegree = (int) (magneticHeading);
-
- // Change the user location view orientation to reflect the device orientation
- setCompass(currentDegree);
-
- if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW) {
- rotateCamera();
- }
-
- compassUpdateNextTimestamp = currentTime + COMPASS_UPDATE_RATE_MS;
- }
- }
-
- private void rotateCamera() {
- CameraPosition.Builder builder = new CameraPosition.Builder();
- builder.bearing(currentDegree);
- mapboxMap.easeCamera(CameraUpdateFactory.newCameraPosition(builder.build()), COMPASS_UPDATE_RATE_MS, false /*linear interpolator*/, false /*do not disable tracking*/, null);
- }
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ float frac = animation.getAnimatedFraction();
+ double latitude = fromLat + (toLat - fromLat) * frac;
+ double longitude = fromLng + (toLng - fromLng) * frac;
+ behavior.updateLatLng(latitude, longitude);
+ update();
+ }
+ }
- @Override
- public void onAccuracyChanged(Sensor sensor, int accuracy) {
- }
+ private class MyLocationBehaviorFactory {
+ MyLocationBehavior getBehavioralModel(@MyLocationTracking.Mode int mode) {
+ if (mode == MyLocationTracking.TRACKING_NONE) {
+ return new MyLocationShowBehavior();
+ } else {
+ return new MyLocationTrackingBehavior();
+ }
}
+ }
- private class MarkerCoordinateAnimatorListener implements ValueAnimator.AnimatorUpdateListener {
-
- private MyLocationBehavior behavior;
- private double fromLat;
- private double fromLng;
- private double toLat;
- private double toLng;
+ private abstract class MyLocationBehavior {
- private MarkerCoordinateAnimatorListener(MyLocationBehavior myLocationBehavior, LatLng from, LatLng to) {
- behavior = myLocationBehavior;
- fromLat = from.getLatitude();
- fromLng = from.getLongitude();
- toLat = to.getLatitude();
- toLng = to.getLongitude();
- }
+ void updateLatLng(@NonNull Location newLocation) {
+ location = newLocation;
+ }
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- float frac = animation.getAnimatedFraction();
- double latitude = fromLat + (toLat - fromLat) * frac;
- double longitude = fromLng + (toLng - fromLng) * frac;
- behavior.updateLatLng(latitude, longitude);
- update();
- }
+ void updateLatLng(double lat, double lon) {
+ if (latLng != null) {
+ latLng.setLatitude(lat);
+ latLng.setLongitude(lon);
+ }
}
- private class MyLocationBehaviorFactory {
+ void updateAccuracy(@NonNull Location location) {
+ if (accuracyAnimator != null && accuracyAnimator.isRunning()) {
+ // use current accuracy as a starting point
+ accuracy = (Float) accuracyAnimator.getAnimatedValue();
+ accuracyAnimator.end();
+ }
- MyLocationBehavior getBehavioralModel(@MyLocationTracking.Mode int mode) {
- if (mode == MyLocationTracking.TRACKING_NONE) {
- return new MyLocationShowBehavior();
- } else {
- return new MyLocationTrackingBehavior();
- }
- }
+ accuracyAnimator = ValueAnimator.ofFloat(accuracy * 10, location.getAccuracy() * 10);
+ accuracyAnimator.setDuration(750);
+ accuracyAnimator.start();
+ accuracy = location.getAccuracy();
}
- private abstract class MyLocationBehavior {
+ abstract void invalidate();
+ }
- void updateLatLng(@NonNull Location newLocation) {
- location = newLocation;
- }
+ private class MyLocationTrackingBehavior extends MyLocationBehavior {
- void updateLatLng(double lat, double lon) {
- if (latLng != null) {
- latLng.setLatitude(lat);
- latLng.setLongitude(lon);
- }
- }
+ @Override
+ void updateLatLng(@NonNull Location location) {
+ super.updateLatLng(location);
+ if (latLng == null) {
+ // first location fix
+ latLng = new LatLng(location);
+ locationUpdateTimestamp = SystemClock.elapsedRealtime();
+ }
+
+ // updateLatLng timestamp
+ float previousUpdateTimeStamp = locationUpdateTimestamp;
+ locationUpdateTimestamp = SystemClock.elapsedRealtime();
+
+ // calculate animation duration
+ float animationDuration;
+ if (previousUpdateTimeStamp == 0) {
+ animationDuration = 0;
+ } else {
+ animationDuration = (locationUpdateTimestamp - previousUpdateTimeStamp) * 1.1f
+ /*make animation slightly longer*/;
+ }
+
+ // calculate interpolated location
+ latLng = new LatLng(location);
+ CameraPosition.Builder builder = new CameraPosition.Builder().target(latLng);
+
+ // add direction
+ if (myBearingTrackingMode == MyBearingTracking.GPS) {
+ if (location.hasBearing()) {
+ builder.bearing(location.getBearing());
+ }
+ setCompass(0, COMPASS_UPDATE_RATE_MS);
+ }
+
+ // accuracy
+ updateAccuracy(location);
+
+ // ease to new camera position with a linear interpolator
+ mapboxMap.easeCamera(CameraUpdateFactory.newCameraPosition(builder.build()), (int) animationDuration,
+ false /*linear interpolator*/, false /*do not disable tracking*/, null);
+ }
- void updateAccuracy(@NonNull Location location) {
- if (accuracyAnimator != null && accuracyAnimator.isRunning()) {
- // use current accuracy as a starting point
- accuracy = (Float) accuracyAnimator.getAnimatedValue();
- accuracyAnimator.end();
- }
-
- accuracyAnimator = ValueAnimator.ofFloat(accuracy * 10, location.getAccuracy() * 10);
- accuracyAnimator.setDuration(750);
- accuracyAnimator.start();
- accuracy = location.getAccuracy();
- }
+ @Override
+ void invalidate() {
+ int[] mapPadding = mapboxMap.getPadding();
+ 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();
+ }
+ }
- abstract void invalidate();
- }
-
- private class MyLocationTrackingBehavior extends MyLocationBehavior {
-
- @Override
- void updateLatLng(@NonNull Location location) {
- super.updateLatLng(location);
- if (latLng == null) {
- // first location fix
- latLng = new LatLng(location);
- locationUpdateTimestamp = SystemClock.elapsedRealtime();
- }
-
- // updateLatLng timestamp
- float previousUpdateTimeStamp = locationUpdateTimestamp;
- locationUpdateTimestamp = SystemClock.elapsedRealtime();
-
- // calculate animation duration
- float animationDuration;
- if (previousUpdateTimeStamp == 0) {
- animationDuration = 0;
- } else {
- animationDuration = (locationUpdateTimestamp - previousUpdateTimeStamp) * 1.1f /*make animation slightly longer*/;
- }
-
- // calculate interpolated location
- latLng = new LatLng(location);
- CameraPosition.Builder builder = new CameraPosition.Builder().target(latLng);
-
- // add direction
- if (myBearingTrackingMode == MyBearingTracking.GPS) {
- if (location.hasBearing()) {
- builder.bearing(location.getBearing());
- }
- setCompass(0);
- }
-
- // accuracy
- updateAccuracy(location);
-
- // ease to new camera position with a linear interpolator
- mapboxMap.easeCamera(CameraUpdateFactory.newCameraPosition(builder.build()), (int) animationDuration, false /*linear interpolator*/, false /*do not disable tracking*/, null);
- }
+ private class MyLocationShowBehavior extends MyLocationBehavior {
- @Override
- void invalidate() {
- int[] mapPadding = mapboxMap.getPadding();
- 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();
- }
+ @Override
+ void updateLatLng(@NonNull final Location location) {
+ super.updateLatLng(location);
+ if (latLng == null) {
+ // first location update
+ latLng = new LatLng(location);
+ locationUpdateTimestamp = SystemClock.elapsedRealtime();
+ }
+
+ // update LatLng location
+ LatLng newLocation = new LatLng(location);
+
+ // update LatLng accuracy
+ updateAccuracy(location);
+
+ // calculate updateLatLng time + add some extra offset to improve animation
+ long previousUpdateTimeStamp = locationUpdateTimestamp;
+ locationUpdateTimestamp = SystemClock.elapsedRealtime();
+ long locationUpdateDuration = (long) ((locationUpdateTimestamp - previousUpdateTimeStamp) * 1.2f);
+
+ // animate changes
+ if (locationChangeAnimator != null) {
+ locationChangeAnimator.end();
+ locationChangeAnimator = null;
+ }
+
+ locationChangeAnimator = ValueAnimator.ofFloat(0.0f, 1.0f);
+ locationChangeAnimator.setDuration(locationUpdateDuration);
+ locationChangeAnimator.addUpdateListener(new MarkerCoordinateAnimatorListener(this,
+ latLng, newLocation
+ ));
+ locationChangeAnimator.start();
+ latLng = newLocation;
}
- private class MyLocationShowBehavior extends MyLocationBehavior {
-
- @Override
- void updateLatLng(@NonNull final Location location) {
- super.updateLatLng(location);
- if (latLng == null) {
- // first location update
- latLng = new LatLng(location);
- locationUpdateTimestamp = SystemClock.elapsedRealtime();
- }
-
- // update LatLng location
- LatLng newLocation = new LatLng(location);
-
- // update LatLng direction
- if (myBearingTrackingMode == MyBearingTracking.GPS && location.hasBearing()) {
- setCompass(location.getBearing() + bearing);
- }
-
- // update LatLng accuracy
- updateAccuracy(location);
-
- // calculate updateLatLng time + add some extra offset to improve animation
- long previousUpdateTimeStamp = locationUpdateTimestamp;
- locationUpdateTimestamp = SystemClock.elapsedRealtime();
- long locationUpdateDuration = (long) ((locationUpdateTimestamp - previousUpdateTimeStamp) * 1.2f);
-
- // animate changes
- if (locationChangeAnimator != null) {
- locationChangeAnimator.end();
- locationChangeAnimator = null;
- }
-
- locationChangeAnimator = ValueAnimator.ofFloat(0.0f, 1.0f);
- locationChangeAnimator.setDuration(locationUpdateDuration);
- locationChangeAnimator.addUpdateListener(new MarkerCoordinateAnimatorListener(this,
- latLng, newLocation
- ));
- locationChangeAnimator.start();
- latLng = newLocation;
- }
-
- @Override
- void invalidate() {
- if (latLng != null) {
- screenLocation = projection.toScreenLocation(latLng);
- }
- MyLocationView.this.invalidate();
- }
+ @Override
+ void invalidate() {
+ if (latLng != null) {
+ screenLocation = projection.toScreenLocation(latLng);
+ }
+ MyLocationView.this.invalidate();
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettings.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettings.java
index 80bd1b3bef..6cfbfed733 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettings.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettings.java
@@ -1,260 +1,298 @@
package com.mapbox.mapboxsdk.maps.widgets;
+import android.graphics.PointF;
import android.graphics.drawable.Drawable;
import android.support.annotation.ColorInt;
import android.support.annotation.IntRange;
+import android.support.annotation.NonNull;
-import com.mapbox.mapboxsdk.maps.MapView;
+import com.mapbox.mapboxsdk.constants.MyLocationTracking;
+import com.mapbox.mapboxsdk.maps.FocalPointChangeListener;
+import com.mapbox.mapboxsdk.camera.CameraPosition;
+import com.mapbox.mapboxsdk.maps.MapboxMapOptions;
+import com.mapbox.mapboxsdk.maps.Projection;
/**
* Settings to configure the visual appearance of the MyLocationView.
*/
public class MyLocationViewSettings {
- private MapView mapView;
- private MyLocationView myLocationView;
+ private Projection projection;
+ private MyLocationView myLocationView;
+ private FocalPointChangeListener focalPointChangeListener;
- //
- // State
- //
+ //
+ // State
+ //
- private boolean enabled;
+ private boolean enabled;
- //
- // Foreground
- //
+ //
+ // Foreground
+ //
- private Drawable foregroundDrawable;
- private Drawable foregroundBearingDrawable;
+ private Drawable foregroundDrawable;
+ private Drawable foregroundBearingDrawable;
- @ColorInt
- private int foregroundTintColor;
+ @ColorInt
+ private int foregroundTintColor;
- //
- // Background
- //
+ //
+ // Background
+ //
- private Drawable backgroundDrawable;
- private int[] backgroundOffset = new int[4];
+ private Drawable backgroundDrawable;
+ private int[] backgroundOffset = new int[4];
- @ColorInt
- private int backgroundTintColor;
+ @ColorInt
+ private int backgroundTintColor;
- //
- // Accuracy
- //
+ //
+ // Accuracy
+ //
- private int accuracyAlpha;
+ private int accuracyAlpha;
- @ColorInt
- private int accuracyTintColor;
+ @ColorInt
+ private int accuracyTintColor;
- //
- // Padding
- //
+ //
+ // Padding
+ //
- private int[] padding = new int[4];
+ private int[] padding = new int[4];
- /**
- * Creates an instance of MyLocationViewSettings
- *
- * @param mapView the MapView that hosts the MyLocationView
- * @param myLocationView the MyLocationView to apply the settings to
- * @see MyLocationView
- */
- public MyLocationViewSettings(MapView mapView, MyLocationView myLocationView) {
- this.mapView = mapView;
- this.myLocationView = myLocationView;
- }
+ /**
+ * Creates an instance of MyLocationViewSettings
+ * <p>
+ *
+ * @param myLocationView the MyLocationView to apply the settings to
+ * @param projection the MapView projection
+ * @param focalPointChangedListener the interface to be invoked when focal points changes
+ * @see MyLocationView
+ */
+ public MyLocationViewSettings(MyLocationView myLocationView, Projection projection, FocalPointChangeListener
+ focalPointChangedListener) {
+ this.myLocationView = myLocationView;
+ this.projection = projection;
+ this.focalPointChangeListener = focalPointChangedListener;
+ }
- /**
- * Returns if the MyLocationView is enabled
- *
- * @return true if MyLocationView is enabled,
- */
- public boolean isEnabled() {
- return enabled;
+ public void initialise(@NonNull MapboxMapOptions options) {
+ CameraPosition position = options.getCamera();
+ if (position != null && !position.equals(CameraPosition.DEFAULT)) {
+ setTilt(position.tilt);
}
-
- /**
- * Set the enabled state of MyLocationView
- *
- * @param enabled true shows the MyLocationView on the map
- */
- public void setEnabled(boolean enabled) {
- this.enabled = enabled;
- myLocationView.setEnabled(enabled);
+ setForegroundDrawable(options.getMyLocationForegroundDrawable(), options.getMyLocationForegroundBearingDrawable());
+ setForegroundTintColor(options.getMyLocationForegroundTintColor());
+ setBackgroundDrawable(options.getMyLocationBackgroundDrawable(), options.getMyLocationBackgroundPadding());
+ setBackgroundTintColor(options.getMyLocationBackgroundTintColor());
+ setAccuracyAlpha(options.getMyLocationAccuracyAlpha());
+ setAccuracyTintColor(options.getMyLocationAccuracyTintColor());
+ }
+
+ /**
+ * Returns if the MyLocationView is enabled
+ *
+ * @return true if MyLocationView is enabled,
+ */
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ /**
+ * Set the enabled state of MyLocationView
+ *
+ * @param enabled true shows the MyLocationView on the map
+ */
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ myLocationView.setEnabled(enabled);
+ }
+
+ /**
+ * Set the foreground drawable of the MyLocationView
+ * <p>
+ * The foreground drawable is the image visible on screen
+ * </p>
+ *
+ * @param foregroundDrawable the drawable to show as foreground without bearing
+ * @param foregroundBearingDrawable the drawable to show as foreground when bearing is enabled
+ */
+ public void setForegroundDrawable(Drawable foregroundDrawable, Drawable foregroundBearingDrawable) {
+ this.foregroundDrawable = foregroundDrawable;
+ this.foregroundBearingDrawable = foregroundBearingDrawable;
+ myLocationView.setForegroundDrawables(foregroundDrawable, foregroundBearingDrawable);
+ }
+
+ /**
+ * Get the foreground drawable when bearing is disabled.
+ *
+ * @return the drawable used as foreground
+ */
+ public Drawable getForegroundDrawable() {
+ return foregroundDrawable;
+ }
+
+ /**
+ * Get the foreground drawable when bearing is enabled.
+ *
+ * @return the bearing drawable used as foreground
+ */
+ public Drawable getForegroundBearingDrawable() {
+ return foregroundBearingDrawable;
+ }
+
+ /**
+ * Set the foreground tint color.
+ * <p>
+ * The color will tint both the foreground and the bearing foreground drawable.
+ * </p>
+ *
+ * @param foregroundTintColor the color to tint the foreground drawable
+ */
+ public void setForegroundTintColor(@ColorInt int foregroundTintColor) {
+ this.foregroundTintColor = foregroundTintColor;
+ myLocationView.setForegroundDrawableTint(foregroundTintColor);
+ }
+
+ /**
+ * Get the foreground tint color.
+ *
+ * @return the foreground tint color
+ */
+ public int getForegroundTintColor() {
+ return foregroundTintColor;
+ }
+
+ /**
+ * Set the background drawable of MyLocationView
+ * <p>
+ * Padding can be added to provide an offset to the background
+ * </p>
+ *
+ * @param backgroundDrawable the drawable to show as background
+ * @param padding the padding added to the background
+ */
+ public void setBackgroundDrawable(Drawable backgroundDrawable, int[] padding) {
+ this.backgroundDrawable = backgroundDrawable;
+ this.backgroundOffset = padding;
+ if (padding != null && padding.length == 4) {
+ myLocationView.setShadowDrawable(backgroundDrawable, padding[0], padding[1], padding[2], padding[3]);
+ } else {
+ myLocationView.setShadowDrawable(backgroundDrawable);
}
-
- /**
- * Set the foreground drawable of the MyLocationView
- * <p>
- * The foreground drawable is the image visible on screen
- * </p>
- *
- * @param foregroundDrawable the drawable to show as foreground without bearing
- * @param foregroundBearingDrawable the drawable to show as foreground when bearing is enabled
- */
- public void setForegroundDrawable(Drawable foregroundDrawable, Drawable foregroundBearingDrawable) {
- this.foregroundDrawable = foregroundDrawable;
- this.foregroundBearingDrawable = foregroundBearingDrawable;
- myLocationView.setForegroundDrawables(foregroundDrawable, foregroundBearingDrawable);
- }
-
- /**
- * Get the foreground drawable when bearing is disabled.
- *
- * @return the drawable used as foreground
- */
- public Drawable getForegroundDrawable() {
- return foregroundDrawable;
- }
-
- /**
- * Get the foreground drawable when bearing is enabled.
- *
- * @return the bearing drawable used as foreground
- */
- public Drawable getForegroundBearingDrawable() {
- return foregroundBearingDrawable;
- }
-
- /**
- * Set the foreground tint color.
- * <p>
- * The color will tint both the foreground and the bearing foreground drawable.
- * </p>
- *
- * @param foregroundTintColor the color to tint the foreground drawable
- */
- public void setForegroundTintColor(@ColorInt int foregroundTintColor) {
- this.foregroundTintColor = foregroundTintColor;
- myLocationView.setForegroundDrawableTint(foregroundTintColor);
- }
-
- /**
- * Get the foreground tint color.
- *
- * @return the foreground tint color
- */
- public int getForegroundTintColor() {
- return foregroundTintColor;
- }
-
- /**
- * Set the background drawable of MyLocationView
- * <p>
- * Padding can be added to provide an offset to the background
- * </p>
- *
- * @param backgroundDrawable the drawable to show as background
- * @param padding the padding added to the background
- */
- public void setBackgroundDrawable(Drawable backgroundDrawable, int[] padding) {
- this.backgroundDrawable = backgroundDrawable;
- this.backgroundOffset = padding;
- if (padding != null && padding.length == 4) {
- myLocationView.setShadowDrawable(backgroundDrawable, padding[0], padding[1], padding[2], padding[3]);
- } else {
- myLocationView.setShadowDrawable(backgroundDrawable);
- }
- }
-
- /**
- * Get the background drawable of MyLocationView.
- *
- * @return the drawable used as background
- */
- public Drawable getBackgroundDrawable() {
- return backgroundDrawable;
- }
-
- /**
- * Set the background tint color.
- *
- * @param backgroundTintColor the color to tint the background
- */
- public void setBackgroundTintColor(@ColorInt int backgroundTintColor) {
- this.backgroundTintColor = backgroundTintColor;
- myLocationView.setShadowDrawableTint(backgroundTintColor);
- }
-
- /**
- * Get the background tint color.
- *
- * @return the background tint color
- */
- public int getBackgroundTintColor() {
- return backgroundTintColor;
- }
-
- /**
- * Get the background offset.
- *
- * @return the background offset
- */
- public int[] getBackgroundOffset() {
- return backgroundOffset;
- }
-
- /**
- * Set the MyLocationView padding.
- *
- * @param left the padding left of MyLocationView
- * @param top the padding top of MyLocationView
- * @param right the padding right of MyLocationView
- * @param bottom the padding bottom of MyLocaionView
- */
- public void setPadding(int left, int top, int right, int bottom) {
- padding = new int[]{left, top, right, bottom};
- myLocationView.setContentPadding(padding);
- mapView.invalidateContentPadding();
- }
-
- /**
- * Get the MyLocationView padding.
- *
- * @return an array describing the padding in a LTRB manner
- */
- public int[] getPadding() {
- return padding;
- }
-
- /**
- * Get the alpha value of the accuracy circle of MyLocationView
- *
- * @return the alpha value
- */
- public int getAccuracyAlpha() {
- return accuracyAlpha;
- }
-
- /**
- * Set the alpha value of the accuracy circle of MyLocationView
- *
- * @param accuracyAlpha the alpha value to set
- */
- public void setAccuracyAlpha(@IntRange(from = 0, to = 255) int accuracyAlpha) {
- this.accuracyAlpha = accuracyAlpha;
- myLocationView.setAccuracyAlpha(accuracyAlpha);
- }
-
- /**
- * Get the accuracy tint color of MyLocationView.
- *
- * @return the tint color used for accuracy
- */
- public int getAccuracyTintColor() {
- return accuracyTintColor;
- }
-
- /**
- * Set the accuracy tint color of MyLocationView.
- *
- * @param accuracyTintColor the accuracy tint color
- */
- public void setAccuracyTintColor(@ColorInt int accuracyTintColor) {
- this.accuracyTintColor = accuracyTintColor;
- myLocationView.setAccuracyTint(accuracyTintColor);
+ }
+
+ /**
+ * Get the background drawable of MyLocationView.
+ *
+ * @return the drawable used as background
+ */
+ public Drawable getBackgroundDrawable() {
+ return backgroundDrawable;
+ }
+
+ /**
+ * Set the background tint color.
+ *
+ * @param backgroundTintColor the color to tint the background
+ */
+ public void setBackgroundTintColor(@ColorInt int backgroundTintColor) {
+ this.backgroundTintColor = backgroundTintColor;
+ myLocationView.setShadowDrawableTint(backgroundTintColor);
+ }
+
+ /**
+ * Get the background tint color.
+ *
+ * @return the background tint color
+ */
+ public int getBackgroundTintColor() {
+ return backgroundTintColor;
+ }
+
+ /**
+ * Get the background offset.
+ *
+ * @return the background offset
+ */
+ public int[] getBackgroundOffset() {
+ return backgroundOffset;
+ }
+
+ /**
+ * Set the MyLocationView padding.
+ *
+ * @param left the padding left of MyLocationView
+ * @param top the padding top of MyLocationView
+ * @param right the padding right of MyLocationView
+ * @param bottom the padding bottom of MyLocaionView
+ */
+ public void setPadding(int left, int top, int right, int bottom) {
+ padding = new int[] {left, top, right, bottom};
+ myLocationView.setContentPadding(padding);
+ projection.invalidateContentPadding(padding);
+ invalidateFocalPointForTracking(myLocationView);
+ }
+
+ /**
+ * Get the MyLocationView padding.
+ *
+ * @return an array describing the padding in a LTRB manner
+ */
+ public int[] getPadding() {
+ return padding;
+ }
+
+ /**
+ * Get the alpha value of the accuracy circle of MyLocationView
+ *
+ * @return the alpha value
+ */
+ public int getAccuracyAlpha() {
+ return accuracyAlpha;
+ }
+
+ /**
+ * Set the alpha value of the accuracy circle of MyLocationView
+ *
+ * @param accuracyAlpha the alpha value to set
+ */
+ public void setAccuracyAlpha(@IntRange(from = 0, to = 255) int accuracyAlpha) {
+ this.accuracyAlpha = accuracyAlpha;
+ myLocationView.setAccuracyAlpha(accuracyAlpha);
+ }
+
+ /**
+ * Get the accuracy tint color of MyLocationView.
+ *
+ * @return the tint color used for accuracy
+ */
+ public int getAccuracyTintColor() {
+ return accuracyTintColor;
+ }
+
+ /**
+ * Set the accuracy tint color of MyLocationView.
+ *
+ * @param accuracyTintColor the accuracy tint color
+ */
+ public void setAccuracyTintColor(@ColorInt int accuracyTintColor) {
+ this.accuracyTintColor = accuracyTintColor;
+ myLocationView.setAccuracyTint(accuracyTintColor);
+ }
+
+ public void setTilt(double tilt) {
+ myLocationView.setTilt(tilt);
+ }
+
+ private void invalidateFocalPointForTracking(MyLocationView myLocationView) {
+ if (!(myLocationView.getMyLocationTrackingMode() == MyLocationTracking.TRACKING_NONE)) {
+ focalPointChangeListener.onFocalPointChanged(new PointF(myLocationView.getCenterX(),
+ myLocationView.getCenterY()));
+ } else {
+ focalPointChangeListener.onFocalPointChanged(null);
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/net/ConnectivityListener.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/net/ConnectivityListener.java
index 0528194528..8f1046c79a 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/net/ConnectivityListener.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/net/ConnectivityListener.java
@@ -5,6 +5,6 @@ package com.mapbox.mapboxsdk.net;
*/
public interface ConnectivityListener {
- void onNetworkStateChanged(boolean connected);
+ void onNetworkStateChanged(boolean connected);
}
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 85695ec6c9..7c37569ae2 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
@@ -7,90 +7,90 @@ import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.annotation.NonNull;
-import android.util.Log;
-import com.mapbox.mapboxsdk.MapboxAccountManager;
+import com.mapbox.mapboxsdk.Mapbox;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
+import timber.log.Timber;
+
/**
* Interface definition for a callback to be invoked when connectivity changes.
* Not public api.
*/
public class ConnectivityReceiver extends BroadcastReceiver {
- private static final String TAG = ConnectivityReceiver.class.getSimpleName();
- private static ConnectivityReceiver INSTANCE;
-
- /**
- * Get or create the singleton instance
- */
- public static synchronized ConnectivityReceiver instance(Context context) {
- if (INSTANCE == null) {
- //Register new instance
- INSTANCE = new ConnectivityReceiver();
- context.registerReceiver(INSTANCE, new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE"));
-
- //Add default listeners
- INSTANCE.addListener(new NativeConnectivityListener());
- }
-
- return INSTANCE;
+ private static ConnectivityReceiver INSTANCE;
+
+ /**
+ * Get or create the singleton instance
+ */
+ public static synchronized ConnectivityReceiver instance(Context context) {
+ if (INSTANCE == null) {
+ //Register new instance
+ INSTANCE = new ConnectivityReceiver();
+ context.registerReceiver(INSTANCE, new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE"));
+
+ //Add default listeners
+ INSTANCE.addListener(new NativeConnectivityListener());
}
- private List<ConnectivityListener> listeners = new CopyOnWriteArrayList<>();
+ return INSTANCE;
+ }
- private ConnectivityReceiver() {
- }
+ private List<ConnectivityListener> listeners = new CopyOnWriteArrayList<>();
- /**
- * @see BroadcastReceiver#onReceive(Context, Intent)
- */
- @Override
- public void onReceive(Context context, Intent intent) {
- boolean connected = isConnected(context);
- Log.v(TAG, "Connected: " + connected);
-
- //Loop over listeners
- for (ConnectivityListener listener : listeners) {
- listener.onNetworkStateChanged(connected);
- }
- }
+ private ConnectivityReceiver() {
+ }
- /**
- * Add a listener to be notified
- *
- * @param listener the listener to add
- */
- public void addListener(@NonNull ConnectivityListener listener) {
- listeners.add(listener);
- }
+ /**
+ * @see BroadcastReceiver#onReceive(Context, Intent)
+ */
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ boolean connected = isConnected(context);
+ Timber.v("Connected: " + connected);
- /**
- * Remove a listener
- *
- * @param listener the listener to remove
- */
- public void removeListener(@NonNull ConnectivityListener listener) {
- listeners.remove(listener);
+ //Loop over listeners
+ for (ConnectivityListener listener : listeners) {
+ listener.onNetworkStateChanged(connected);
}
-
- /**
- * Get current connectivity state
- *
- * @param context current Context
- * @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());
+ }
+
+ /**
+ * Add a listener to be notified
+ *
+ * @param listener the listener to add
+ */
+ public void addListener(@NonNull ConnectivityListener listener) {
+ listeners.add(listener);
+ }
+
+ /**
+ * Remove a listener
+ *
+ * @param listener the listener to remove
+ */
+ public void removeListener(@NonNull ConnectivityListener listener) {
+ listeners.remove(listener);
+ }
+
+ /**
+ * Get current connectivity state
+ *
+ * @param context current Context
+ * @return true if connected
+ */
+ public boolean isConnected(Context context) {
+ Boolean connected = Mapbox.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/net/NativeConnectivityListener.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/net/NativeConnectivityListener.java
index 8b9307465c..76ce1de9d7 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/net/NativeConnectivityListener.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/net/NativeConnectivityListener.java
@@ -5,30 +5,30 @@ package com.mapbox.mapboxsdk.net;
*/
class NativeConnectivityListener implements ConnectivityListener {
- static {
- System.loadLibrary("mapbox-gl");
- }
+ static {
+ System.loadLibrary("mapbox-gl");
+ }
- private long nativePtr;
- private boolean invalidated;
+ private long nativePtr;
+ private boolean invalidated;
- NativeConnectivityListener(long nativePtr) {
- this.nativePtr = nativePtr;
- }
+ NativeConnectivityListener(long nativePtr) {
+ this.nativePtr = nativePtr;
+ }
- NativeConnectivityListener() {
- initialize();
- }
+ NativeConnectivityListener() {
+ initialize();
+ }
- @Override
- public void onNetworkStateChanged(boolean connected) {
- nativeOnConnectivityStateChanged(connected);
- }
+ @Override
+ public void onNetworkStateChanged(boolean connected) {
+ nativeOnConnectivityStateChanged(connected);
+ }
- protected native void nativeOnConnectivityStateChanged(boolean connected);
+ protected native void nativeOnConnectivityStateChanged(boolean connected);
- protected native void initialize();
+ protected native void initialize();
- @Override
- protected native void finalize() throws Throwable;
+ @Override
+ protected native void finalize() throws Throwable;
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java
index 80d5ff7db0..1a396f6897 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java
@@ -7,326 +7,324 @@ import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;
-import android.util.Log;
+import android.text.TextUtils;
-import com.mapbox.mapboxsdk.MapboxAccountManager;
+import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
import java.io.File;
+import timber.log.Timber;
+
/**
* The offline manager is the main entry point for offline-related functionality.
* It'll help you list and create offline regions.
*/
public class OfflineManager {
- private final static String LOG_TAG = "OfflineManager";
-
- //
- // Static methods
- //
+ //
+ // Static methods
+ //
- static {
- System.loadLibrary("mapbox-gl");
- }
+ static {
+ System.loadLibrary("mapbox-gl");
+ }
- // Default database name
- private final static String DATABASE_NAME = "mbgl-offline.db";
+ // Default database name
+ private static final String DATABASE_NAME = "mbgl-offline.db";
- /*
- * The maximumCacheSize parameter is a limit applied to non-offline resources only,
- * i.e. resources added to the database for the "ambient use" caching functionality.
- * There is no size limit for offline resources.
- */
- private final static long DEFAULT_MAX_CACHE_SIZE = 50 * 1024 * 1024;
+ /*
+ * The maximumCacheSize parameter is a limit applied to non-offline resources only,
+ * i.e. resources added to the database for the "ambient use" caching functionality.
+ * There is no size limit for offline resources.
+ */
+ private static final long DEFAULT_MAX_CACHE_SIZE = 50 * 1024 * 1024;
- // Holds the pointer to JNI DefaultFileSource
- private long mDefaultFileSourcePtr = 0;
+ // Holds the pointer to JNI DefaultFileSource
+ private long mDefaultFileSourcePtr = 0;
- // Makes sure callbacks come back to the main thread
- private Handler handler;
+ // Makes sure callbacks come back to the main thread
+ private Handler handler;
- // This object is implemented as a singleton
- private static OfflineManager instance;
+ // This object is implemented as a singleton
+ private static OfflineManager instance;
+ /**
+ * This callback receives an asynchronous response containing a list of all
+ * {@link OfflineRegion} in the database, or an error message otherwise.
+ */
+ public interface ListOfflineRegionsCallback {
/**
- * This callback receives an asynchronous response containing a list of all
- * {@link OfflineRegion} in the database, or an error message otherwise.
+ * Receives the list of offline regions.
+ *
+ * @param offlineRegions the offline region array
*/
- public interface ListOfflineRegionsCallback {
- /**
- * Receives the list of offline regions.
- *
- * @param offlineRegions the offline region array
- */
- void onList(OfflineRegion[] offlineRegions);
-
- /**
- * Receives the error message.
- *
- * @param error the error message
- */
- void onError(String error);
- }
+ void onList(OfflineRegion[] offlineRegions);
/**
- * This callback receives an asynchronous response containing the newly created
- * {@link OfflineRegion} in the database, or an error message otherwise.
+ * Receives the error message.
+ *
+ * @param error the error message
*/
- public interface CreateOfflineRegionCallback {
- /**
- * Receives the newly created offline region.
- *
- * @param offlineRegion the offline region to create
- */
- void onCreate(OfflineRegion offlineRegion);
-
- /**
- * Receives the error message.
- *
- * @param error the error message to be shown
- */
- void onError(String error);
- }
-
- /*
- * Constructors
+ void onError(String error);
+ }
+
+ /**
+ * This callback receives an asynchronous response containing the newly created
+ * {@link OfflineRegion} in the database, or an error message otherwise.
+ */
+ public interface CreateOfflineRegionCallback {
+ /**
+ * Receives the newly created offline region.
+ *
+ * @param offlineRegion the offline region to create
*/
-
- private OfflineManager(Context context) {
- // Get a pointer to the DefaultFileSource instance
- String assetRoot = getDatabasePath(context);
- String cachePath = assetRoot + File.separator + DATABASE_NAME;
- mDefaultFileSourcePtr = createDefaultFileSource(cachePath, assetRoot, DEFAULT_MAX_CACHE_SIZE);
-
- if (MapboxAccountManager.getInstance() != null) {
- setAccessToken(mDefaultFileSourcePtr, MapboxAccountManager.getInstance().getAccessToken());
- }
-
- // Delete any existing previous ambient cache database
- deleteAmbientDatabase(context);
- }
-
- public static String getDatabasePath(Context context) {
- // Default value
- boolean setStorageExternal = MapboxConstants.DEFAULT_SET_STORAGE_EXTERNAL;
-
- try {
- // Try getting a custom value from the app Manifest
- ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(
- context.getPackageName(), PackageManager.GET_META_DATA);
- setStorageExternal = appInfo.metaData.getBoolean(
- MapboxConstants.KEY_META_DATA_SET_STORAGE_EXTERNAL,
- MapboxConstants.DEFAULT_SET_STORAGE_EXTERNAL);
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(LOG_TAG, "Failed to read the package metadata: " + e.getMessage());
- } catch (Exception e) {
- Log.e(LOG_TAG, "Failed to read the storage key: " + e.getMessage());
- }
-
- String databasePath = null;
- if (setStorageExternal && isExternalStorageReadable()) {
- try {
- // Try getting the external storage path
- databasePath = context.getExternalFilesDir(null).getAbsolutePath();
- } catch (NullPointerException e) {
- Log.e(LOG_TAG, "Failed to obtain the external storage path: " + e.getMessage());
- }
- }
-
- if (databasePath == null) {
- // Default to internal storage
- databasePath = context.getFilesDir().getAbsolutePath();
- }
-
- return databasePath;
- }
+ void onCreate(OfflineRegion offlineRegion);
/**
- * Checks if external storage is available to at least read. In order for this to work, make
- * sure you include &lt;uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /&gt;
- * (or WRITE_EXTERNAL_STORAGE) for API level &lt; 18 in your app Manifest.
- * <p>
- * Code from https://developer.android.com/guide/topics/data/data-storage.html#filesExternal
- * </p>
+ * Receives the error message.
*
- * @return true if external storage is readable
+ * @param error the error message to be shown
*/
- public static boolean isExternalStorageReadable() {
- String state = Environment.getExternalStorageState();
- if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
- return true;
- }
-
- Log.w(LOG_TAG, "External storage was requested but it isn't readable. For API level < 18"
- + " make sure you've requested READ_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE"
- + " permissions in your app Manifest (defaulting to internal storage).");
-
- return false;
+ void onError(String error);
+ }
+
+ /*
+ * Constructors
+ */
+ private OfflineManager(Context context) {
+ // Get a pointer to the DefaultFileSource instance
+ String assetRoot = getDatabasePath(context);
+ String cachePath = assetRoot + File.separator + DATABASE_NAME;
+ mDefaultFileSourcePtr = createDefaultFileSource(cachePath, assetRoot, DEFAULT_MAX_CACHE_SIZE);
+
+ if (!TextUtils.isEmpty(Mapbox.getAccessToken())) {
+ setAccessToken(mDefaultFileSourcePtr, Mapbox.getAccessToken());
}
- private void deleteAmbientDatabase(final Context context) {
- // Delete the file in a separate thread to avoid affecting the UI
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- String path = context.getCacheDir().getAbsolutePath() + File.separator + "mbgl-cache.db";
- File file = new File(path);
- if (file.exists()) {
- file.delete();
- Log.d(LOG_TAG, "Old ambient cache database deleted to save space: " + path);
- }
- } catch (Exception e) {
- Log.e(LOG_TAG, "Failed to delete old ambient cache database: " + e.getMessage());
- }
- }
- }).start();
+ // Delete any existing previous ambient cache database
+ deleteAmbientDatabase(context);
+ }
+
+ public static String getDatabasePath(Context context) {
+ // Default value
+ boolean setStorageExternal = MapboxConstants.DEFAULT_SET_STORAGE_EXTERNAL;
+
+ try {
+ // Try getting a custom value from the app Manifest
+ ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(
+ context.getPackageName(), PackageManager.GET_META_DATA);
+ setStorageExternal = appInfo.metaData.getBoolean(
+ MapboxConstants.KEY_META_DATA_SET_STORAGE_EXTERNAL,
+ MapboxConstants.DEFAULT_SET_STORAGE_EXTERNAL);
+ } catch (PackageManager.NameNotFoundException exception) {
+ Timber.e("Failed to read the package metadata: ", exception);
+ } catch (Exception exception) {
+ Timber.e("Failed to read the storage key: ", exception);
}
- public static synchronized OfflineManager getInstance(Context context) {
- if (instance == null) {
- instance = new OfflineManager(context);
- }
-
- return instance;
+ String databasePath = null;
+ if (setStorageExternal && isExternalStorageReadable()) {
+ try {
+ // Try getting the external storage path
+ databasePath = context.getExternalFilesDir(null).getAbsolutePath();
+ } catch (NullPointerException exception) {
+ Timber.e("Failed to obtain the external storage path: ", exception);
+ }
}
- /**
- * Access token getter/setter
- *
- * @param accessToken the accessToken to be used by the offline manager.
- * @deprecated As of release 4.1.0, replaced by {@link MapboxAccountManager#start(Context, String)} ()}
- */
- @Deprecated
- public void setAccessToken(String accessToken) {
- setAccessToken(mDefaultFileSourcePtr, accessToken);
+ if (databasePath == null) {
+ // Default to internal storage
+ databasePath = context.getFilesDir().getAbsolutePath();
}
- /**
- * Get Access Token
- *
- * @return Access Token
- * @deprecated As of release 4.1.0, replaced by {@link MapboxAccountManager#getAccessToken()}
- */
- @Deprecated
- public String getAccessToken() {
- return getAccessToken(mDefaultFileSourcePtr);
+ return databasePath;
+ }
+
+ /**
+ * Checks if external storage is available to at least read. In order for this to work, make
+ * sure you include &lt;uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /&gt;
+ * (or WRITE_EXTERNAL_STORAGE) for API level &lt; 18 in your app Manifest.
+ * <p>
+ * Code from https://developer.android.com/guide/topics/data/data-storage.html#filesExternal
+ * </p>
+ *
+ * @return true if external storage is readable
+ */
+ public static boolean isExternalStorageReadable() {
+ String state = Environment.getExternalStorageState();
+ if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
+ return true;
}
- private Handler getHandler() {
- if (handler == null) {
- handler = new Handler(Looper.getMainLooper());
+ Timber.w("External storage was requested but it isn't readable. For API level < 18"
+ + " make sure you've requested READ_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE"
+ + " permissions in your app Manifest (defaulting to internal storage).");
+
+ return false;
+ }
+
+ private void deleteAmbientDatabase(final Context context) {
+ // Delete the file in a separate thread to avoid affecting the UI
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ String path = context.getCacheDir().getAbsolutePath() + File.separator + "mbgl-cache.db";
+ File file = new File(path);
+ if (file.exists()) {
+ file.delete();
+ Timber.d("Old ambient cache database deleted to save space: " + path);
+ }
+ } catch (Exception exception) {
+ Timber.e("Failed to delete old ambient cache database: ", exception);
}
+ }
+ }).start();
+ }
- return handler;
+ public static synchronized OfflineManager getInstance(Context context) {
+ if (instance == null) {
+ instance = new OfflineManager(context);
}
- /**
- * Retrieve all regions in the offline database.
- * <p>
- * The query will be executed asynchronously and the results passed to the given
- * callback on the main thread.
- * </p>
- *
- * @param callback the callback to be invoked
- */
- public void listOfflineRegions(@NonNull final ListOfflineRegionsCallback callback) {
- listOfflineRegions(mDefaultFileSourcePtr, new ListOfflineRegionsCallback() {
- @Override
- public void onList(final OfflineRegion[] offlineRegions) {
- getHandler().post(new Runnable() {
- @Override
- public void run() {
- callback.onList(offlineRegions);
- }
- });
- }
-
- @Override
- public void onError(final String error) {
- getHandler().post(new Runnable() {
- @Override
- public void run() {
- callback.onError(error);
- }
- });
- }
- });
+ return instance;
+ }
+
+ /**
+ * Access token getter/setter
+ *
+ * @param accessToken the accessToken to be used by the offline manager.
+ * @deprecated As of release 4.1.0, replaced by {@link Mapbox#getInstance(Context, String)}}
+ */
+ @Deprecated
+ public void setAccessToken(String accessToken) {
+ setAccessToken(mDefaultFileSourcePtr, accessToken);
+ }
+
+ /**
+ * Get Access Token
+ *
+ * @return Access Token
+ * @deprecated As of release 4.1.0, replaced by {@link Mapbox#getAccessToken()}
+ */
+ @Deprecated
+ public String getAccessToken() {
+ return getAccessToken(mDefaultFileSourcePtr);
+ }
+
+ private Handler getHandler() {
+ if (handler == null) {
+ handler = new Handler(Looper.getMainLooper());
}
- /**
- * Create an offline region in the database.
- * <p>
- * When the initial database queries have completed, the provided callback will be
- * executed on the main thread.
- * </p>
- * <p>
- * Note that the resulting region will be in an inactive download state; to begin
- * downloading resources, call `OfflineRegion.setDownloadState(DownloadState.STATE_ACTIVE)`,
- * optionally registering an `OfflineRegionObserver` beforehand.
- * </p>
- *
- * @param definition the offline region definition
- * @param metadata the metadata in bytes
- * @param callback the callback to be invoked
- */
- public void createOfflineRegion(
- @NonNull OfflineRegionDefinition definition,
- @NonNull byte[] metadata,
- @NonNull final CreateOfflineRegionCallback callback) {
-
- createOfflineRegion(mDefaultFileSourcePtr, definition, metadata, new CreateOfflineRegionCallback() {
- @Override
- public void onCreate(final OfflineRegion offlineRegion) {
- getHandler().post(new Runnable() {
- @Override
- public void run() {
- callback.onCreate(offlineRegion);
- }
- });
- }
-
- @Override
- public void onError(final String error) {
- getHandler().post(new Runnable() {
- @Override
- public void run() {
- callback.onError(error);
- }
- });
- }
+ return handler;
+ }
+
+ /**
+ * Retrieve all regions in the offline database.
+ * <p>
+ * The query will be executed asynchronously and the results passed to the given
+ * callback on the main thread.
+ * </p>
+ *
+ * @param callback the callback to be invoked
+ */
+ public void listOfflineRegions(@NonNull final ListOfflineRegionsCallback callback) {
+ listOfflineRegions(mDefaultFileSourcePtr, new ListOfflineRegionsCallback() {
+ @Override
+ public void onList(final OfflineRegion[] offlineRegions) {
+ getHandler().post(new Runnable() {
+ @Override
+ public void run() {
+ callback.onList(offlineRegions);
+ }
});
- }
-
- /*
- * Changing or bypassing this limit without permission from Mapbox is prohibited
- * by the Mapbox Terms of Service.
- */
- public void setOfflineMapboxTileCountLimit(long limit) {
- setOfflineMapboxTileCountLimit(mDefaultFileSourcePtr, limit);
- }
+ }
+
+ @Override
+ public void onError(final String error) {
+ getHandler().post(new Runnable() {
+ @Override
+ public void run() {
+ callback.onError(error);
+ }
+ });
+ }
+ });
+ }
+
+ /**
+ * Create an offline region in the database.
+ * <p>
+ * When the initial database queries have completed, the provided callback will be
+ * executed on the main thread.
+ * </p>
+ * <p>
+ * Note that the resulting region will be in an inactive download state; to begin
+ * downloading resources, call `OfflineRegion.setDownloadState(DownloadState.STATE_ACTIVE)`,
+ * optionally registering an `OfflineRegionObserver` beforehand.
+ * </p>
+ *
+ * @param definition the offline region definition
+ * @param metadata the metadata in bytes
+ * @param callback the callback to be invoked
+ */
+ public void createOfflineRegion(
+ @NonNull OfflineRegionDefinition definition,
+ @NonNull byte[] metadata,
+ @NonNull final CreateOfflineRegionCallback callback) {
+
+ createOfflineRegion(mDefaultFileSourcePtr, definition, metadata, new CreateOfflineRegionCallback() {
+ @Override
+ public void onCreate(final OfflineRegion offlineRegion) {
+ getHandler().post(new Runnable() {
+ @Override
+ public void run() {
+ callback.onCreate(offlineRegion);
+ }
+ });
+ }
+
+ @Override
+ public void onError(final String error) {
+ getHandler().post(new Runnable() {
+ @Override
+ public void run() {
+ callback.onError(error);
+ }
+ });
+ }
+ });
+ }
+ /*
+ * Changing or bypassing this limit without permission from Mapbox is prohibited
+ * by the Mapbox Terms of Service.
+ */
+ public void setOfflineMapboxTileCountLimit(long limit) {
+ setOfflineMapboxTileCountLimit(mDefaultFileSourcePtr, limit);
+ }
- /*
- * Native methods
- */
- private native long createDefaultFileSource(
- String cachePath, String assetRoot, long maximumCacheSize);
+ /*
+ * Native methods
+ */
+ private native long createDefaultFileSource(
+ String cachePath, String assetRoot, long maximumCacheSize);
- private native void setAccessToken(long defaultFileSourcePtr, String accessToken);
+ private native void setAccessToken(long defaultFileSourcePtr, String accessToken);
- private native String getAccessToken(long defaultFileSourcePtr);
+ private native String getAccessToken(long defaultFileSourcePtr);
- private native void listOfflineRegions(
- long defaultFileSourcePtr, ListOfflineRegionsCallback callback);
+ private native void listOfflineRegions(
+ long defaultFileSourcePtr, ListOfflineRegionsCallback callback);
- private native void createOfflineRegion(
- long defaultFileSourcePtr, OfflineRegionDefinition definition,
- byte[] metadata, CreateOfflineRegionCallback callback);
+ private native void createOfflineRegion(
+ long defaultFileSourcePtr, OfflineRegionDefinition definition,
+ byte[] metadata, CreateOfflineRegionCallback callback);
- private native void setOfflineMapboxTileCountLimit(
- long defaultFileSourcePtr, long limit);
+ private native void setOfflineMapboxTileCountLimit(
+ long defaultFileSourcePtr, long limit);
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java
index f52f20083a..a4d8a646d3 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java
@@ -4,7 +4,8 @@ import android.os.Handler;
import android.os.Looper;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
-import android.util.Log;
+
+import timber.log.Timber;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -16,416 +17,418 @@ import java.lang.annotation.RetentionPolicy;
*/
public class OfflineRegion {
- private final static String LOG_TAG = "OfflineRegion";
+ //
+ // Static methods
+ //
- //
- // Static methods
- //
+ static {
+ System.loadLibrary("mapbox-gl");
+ }
- static {
- System.loadLibrary("mapbox-gl");
- }
+ // Parent OfflineManager
+ private OfflineManager offlineManager;
- // Parent OfflineManager
- private OfflineManager offlineManager;
+ // Members
+ private long mId = 0;
+ private OfflineRegionDefinition mDefinition = null;
- // Members
- private long mId = 0;
- private OfflineRegionDefinition mDefinition = null;
+ /**
+ * Arbitrary binary region metadata. The contents are opaque to the SDK implementation;
+ * it just stores and retrieves a byte[]. Check the `OfflineActivity` in the TestApp
+ * for a sample implementation that uses JSON to store an offline region name.
+ */
+ private byte[] mMetadata = null;
- /**
- * Arbitrary binary region metadata. The contents are opaque to the SDK implementation;
- * it just stores and retrieves a byte[]. Check the `OfflineActivity` in the TestApp
- * for a sample implementation that uses JSON to store an offline region name.
- */
- private byte[] mMetadata = null;
+ // Holds the pointer to JNI OfflineRegion
+ private long mOfflineRegionPtr = 0;
- // Holds the pointer to JNI OfflineRegion
- private long mOfflineRegionPtr = 0;
-
- // Makes sure callbacks come back to the main thread
- private Handler handler;
+ // Makes sure callbacks come back to the main thread
+ private Handler handler;
+ /**
+ * A region can have a single observer, which gets notified whenever a change
+ * to the region's status occurs.
+ */
+ public interface OfflineRegionObserver {
/**
- * A region can have a single observer, which gets notified whenever a change
- * to the region's status occurs.
+ * Implement this method to be notified of a change in the status of an
+ * offline region. Status changes include any change in state of the members
+ * of OfflineRegionStatus.
+ * <p>
+ * This method will be executed on the main thread.
+ * </p>
+ *
+ * @param status the changed status
*/
- public interface OfflineRegionObserver {
- /**
- * Implement this method to be notified of a change in the status of an
- * offline region. Status changes include any change in state of the members
- * of OfflineRegionStatus.
- * <p>
- * This method will be executed on the main thread.
- * </p>
- *
- * @param status the changed status
- */
- void onStatusChanged(OfflineRegionStatus status);
-
- /**
- * Implement this method to be notified of errors encountered while downloading
- * regional resources. Such errors may be recoverable; for example the implementation
- * will attempt to re-request failed resources based on an exponential backoff
- * algorithm, or when it detects that network access has been restored.
- * <p>
- * This method will be executed on the main thread.
- * </p>
- *
- * @param error the offline region error message
- */
- void onError(OfflineRegionError error);
-
- /*
- * Implement this method to be notified when the limit on the number of Mapbox
- * tiles stored for offline regions has been reached.
- *
- * Once the limit has been reached, the SDK will not download further offline
- * tiles from Mapbox APIs until existing tiles have been removed. Contact your
- * Mapbox sales representative to raise the limit.
- *
- * This limit does not apply to non-Mapbox tile sources.
- *
- * This method will be executed on the main thread.
- */
- void mapboxTileCountLimitExceeded(long limit);
- }
+ void onStatusChanged(OfflineRegionStatus status);
/**
- * This callback receives an asynchronous response containing the {@link OfflineRegionStatus}
- * of the offline region, or a {@link String} error message otherwise.
+ * Implement this method to be notified of errors encountered while downloading
+ * regional resources. Such errors may be recoverable; for example the implementation
+ * will attempt to re-request failed resources based on an exponential backoff
+ * algorithm, or when it detects that network access has been restored.
+ * <p>
+ * This method will be executed on the main thread.
+ * </p>
+ *
+ * @param error the offline region error message
*/
- public interface OfflineRegionStatusCallback {
- /**
- * Receives the status
- *
- * @param status the offline region status
- */
- void onStatus(OfflineRegionStatus status);
-
- /**
- * Receives the error message
- *
- * @param error the error message
- */
- void onError(String error);
- }
+ void onError(OfflineRegionError error);
+ /*
+ * Implement this method to be notified when the limit on the number of Mapbox
+ * tiles stored for offline regions has been reached.
+ *
+ * Once the limit has been reached, the SDK will not download further offline
+ * tiles from Mapbox APIs until existing tiles have been removed. Contact your
+ * Mapbox sales representative to raise the limit.
+ *
+ * This limit does not apply to non-Mapbox tile sources.
+ *
+ * This method will be executed on the main thread.
+ */
+ void mapboxTileCountLimitExceeded(long limit);
+ }
+
+ /**
+ * This callback receives an asynchronous response containing the {@link OfflineRegionStatus}
+ * of the offline region, or a {@link String} error message otherwise.
+ */
+ public interface OfflineRegionStatusCallback {
/**
- * This callback receives an asynchronous response containing a notification when
- * an offline region has been deleted, or a {@link String} error message otherwise.
+ * Receives the status
+ *
+ * @param status the offline region status
*/
- public interface OfflineRegionDeleteCallback {
- /**
- * Receives the delete notification
- */
- void onDelete();
-
- /**
- * Receives the error message
- *
- * @param error the error message
- */
- void onError(String error);
- }
+ void onStatus(OfflineRegionStatus status);
/**
- * This callback receives an asynchronous response containing the newly update
- * OfflineMetadata in the database, or an error message otherwise.
+ * Receives the error message
+ *
+ * @param error the error message
*/
- public interface OfflineRegionUpdateMetadataCallback {
- /**
- * Receives the newly update offline region metadata.
- *
- * @param metadata the offline metadata to u[date
- */
- void onUpdate(byte[] metadata);
-
- /**
- * Receives the error message.
- *
- * @param error the error message to be shown
- */
- void onError(String error);
- }
-
+ void onError(String error);
+ }
+
+ /**
+ * This callback receives an asynchronous response containing a notification when
+ * an offline region has been deleted, or a {@link String} error message otherwise.
+ */
+ public interface OfflineRegionDeleteCallback {
/**
- * A region is either inactive (not downloading, but previously-downloaded
- * resources are available for use), or active (resources are being downloaded
- * or will be downloaded, if necessary, when network access is available).
- * <p>
- * This state is independent of whether or not the complete set of resources
- * is currently available for offline use. To check if that is the case, use
- * `OfflineRegionStatus.isComplete()`.
- * </p>
+ * Receives the delete notification
*/
-
- @IntDef({STATE_INACTIVE, STATE_ACTIVE})
- @Retention(RetentionPolicy.SOURCE)
- public @interface DownloadState {
- }
-
- public static final int STATE_INACTIVE = 0;
- public static final int STATE_ACTIVE = 1;
-
- // Keep track of the region state
- private int state = STATE_INACTIVE;
-
- private boolean deliverInactiveMessages = false;
+ void onDelete();
/**
- * Gets whether or not the `OfflineRegionObserver` will continue to deliver messages even if
- * the region state has been set as STATE_INACTIVE.
+ * Receives the error message
*
- * @return true if delivering inactive messages
+ * @param error the error message
*/
- public boolean isDeliveringInactiveMessages() {
- return deliverInactiveMessages;
- }
+ void onError(String error);
+ }
+
+ /**
+ * This callback receives an asynchronous response containing the newly update
+ * OfflineMetadata in the database, or an error message otherwise.
+ */
+ public interface OfflineRegionUpdateMetadataCallback {
+ /**
+ * Receives the newly update offline region metadata.
+ *
+ * @param metadata the offline metadata to u[date
+ */
+ void onUpdate(byte[] metadata);
/**
- * When set true, the `OfflineRegionObserver` will continue to deliver messages even if
- * the region state has been set as STATE_INACTIVE (operations happen asynchronously). If set
- * false, the client won't be notified of further messages.
+ * Receives the error message.
*
- * @param deliverInactiveMessages true if it should deliver inactive messages
+ * @param error the error message to be shown
*/
- public void setDeliverInactiveMessages(boolean deliverInactiveMessages) {
- this.deliverInactiveMessages = deliverInactiveMessages;
+ void onError(String error);
+ }
+
+ /**
+ * A region is either inactive (not downloading, but previously-downloaded
+ * resources are available for use), or active (resources are being downloaded
+ * or will be downloaded, if necessary, when network access is available).
+ * <p>
+ * This state is independent of whether or not the complete set of resources
+ * is currently available for offline use. To check if that is the case, use
+ * `OfflineRegionStatus.isComplete()`.
+ * </p>
+ */
+
+ @IntDef( {STATE_INACTIVE, STATE_ACTIVE})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface DownloadState {
+ }
+
+ public static final int STATE_INACTIVE = 0;
+ public static final int STATE_ACTIVE = 1;
+
+ // Keep track of the region state
+ private int state = STATE_INACTIVE;
+
+ private boolean deliverInactiveMessages = false;
+
+ /**
+ * Gets whether or not the `OfflineRegionObserver` will continue to deliver messages even if
+ * the region state has been set as STATE_INACTIVE.
+ *
+ * @return true if delivering inactive messages
+ */
+ public boolean isDeliveringInactiveMessages() {
+ return deliverInactiveMessages;
+ }
+
+ /**
+ * When set true, the `OfflineRegionObserver` will continue to deliver messages even if
+ * the region state has been set as STATE_INACTIVE (operations happen asynchronously). If set
+ * false, the client won't be notified of further messages.
+ *
+ * @param deliverInactiveMessages true if it should deliver inactive messages
+ */
+ public void setDeliverInactiveMessages(boolean deliverInactiveMessages) {
+ this.deliverInactiveMessages = deliverInactiveMessages;
+ }
+
+ private boolean deliverMessages() {
+ if (state == STATE_ACTIVE) {
+ return true;
}
-
- private boolean deliverMessages() {
- if (state == STATE_ACTIVE) return true;
- if (isDeliveringInactiveMessages()) return true;
- return false;
+ if (isDeliveringInactiveMessages()) {
+ return true;
}
+ return false;
+ }
- /*
- * Constructor
- */
-
- private OfflineRegion() {
- // For JNI use only, to create a new offline region, use
- // OfflineManager.createOfflineRegion() instead.
- }
+ /*
+ * Constructor
+ */
- /*
- * Getters
- */
+ private OfflineRegion() {
+ // For JNI use only, to create a new offline region, use
+ // OfflineManager.createOfflineRegion() instead.
+ }
- public long getID() {
- return mId;
- }
+ /*
+ * Getters
+ */
- public OfflineRegionDefinition getDefinition() {
- return mDefinition;
- }
+ public long getID() {
+ return mId;
+ }
- public byte[] getMetadata() {
- return mMetadata;
- }
+ public OfflineRegionDefinition getDefinition() {
+ return mDefinition;
+ }
- private Handler getHandler() {
- if (handler == null) {
- handler = new Handler(Looper.getMainLooper());
- }
+ public byte[] getMetadata() {
+ return mMetadata;
+ }
- return handler;
+ private Handler getHandler() {
+ if (handler == null) {
+ handler = new Handler(Looper.getMainLooper());
}
- /**
- * Register an observer to be notified when the state of the region changes.
- *
- * @param observer the observer to be notified
- */
- public void setObserver(@NonNull final OfflineRegionObserver observer) {
- setOfflineRegionObserver(new OfflineRegionObserver() {
+ return handler;
+ }
+
+ /**
+ * Register an observer to be notified when the state of the region changes.
+ *
+ * @param observer the observer to be notified
+ */
+ public void setObserver(@NonNull final OfflineRegionObserver observer) {
+ setOfflineRegionObserver(new OfflineRegionObserver() {
+ @Override
+ public void onStatusChanged(final OfflineRegionStatus status) {
+ if (deliverMessages()) {
+ getHandler().post(new Runnable() {
@Override
- public void onStatusChanged(final OfflineRegionStatus status) {
- if (deliverMessages()) {
- getHandler().post(new Runnable() {
- @Override
- public void run() {
- observer.onStatusChanged(status);
- }
- });
- }
+ public void run() {
+ observer.onStatusChanged(status);
}
+ });
+ }
+ }
+ @Override
+ public void onError(final OfflineRegionError error) {
+ if (deliverMessages()) {
+ getHandler().post(new Runnable() {
@Override
- public void onError(final OfflineRegionError error) {
- if (deliverMessages()) {
- getHandler().post(new Runnable() {
- @Override
- public void run() {
- observer.onError(error);
- }
- });
- }
+ public void run() {
+ observer.onError(error);
}
+ });
+ }
+ }
+ @Override
+ public void mapboxTileCountLimitExceeded(final long limit) {
+ if (deliverMessages()) {
+ getHandler().post(new Runnable() {
@Override
- public void mapboxTileCountLimitExceeded(final long limit) {
- if (deliverMessages()) {
- getHandler().post(new Runnable() {
- @Override
- public void run() {
- observer.mapboxTileCountLimitExceeded(limit);
- }
- });
- }
+ public void run() {
+ observer.mapboxTileCountLimitExceeded(limit);
}
+ });
+ }
+ }
+ });
+ }
+
+ /**
+ * Pause or resume downloading of regional resources.
+ *
+ * @param state the download state
+ */
+ public void setDownloadState(@DownloadState int state) {
+ this.state = state;
+ setOfflineRegionDownloadState(state);
+ }
+
+ /**
+ * Retrieve the current status of the region. The query will be executed
+ * asynchronously and the results passed to the given callback which will be
+ * executed on the main thread.
+ *
+ * @param callback the callback to invoked.
+ */
+ public void getStatus(@NonNull final OfflineRegionStatusCallback callback) {
+ getOfflineRegionStatus(new OfflineRegionStatusCallback() {
+ @Override
+ public void onStatus(final OfflineRegionStatus status) {
+ getHandler().post(new Runnable() {
+ @Override
+ public void run() {
+ callback.onStatus(status);
+ }
});
- }
-
- /**
- * Pause or resume downloading of regional resources.
- *
- * @param state the download state
- */
- public void setDownloadState(@DownloadState int state) {
- this.state = state;
- setOfflineRegionDownloadState(state);
- }
-
- /**
- * Retrieve the current status of the region. The query will be executed
- * asynchronously and the results passed to the given callback which will be
- * executed on the main thread.
- *
- * @param callback the callback to invoked.
- */
- public void getStatus(@NonNull final OfflineRegionStatusCallback callback) {
- getOfflineRegionStatus(new OfflineRegionStatusCallback() {
- @Override
- public void onStatus(final OfflineRegionStatus status) {
- getHandler().post(new Runnable() {
- @Override
- public void run() {
- callback.onStatus(status);
- }
- });
- }
-
- @Override
- public void onError(final String error) {
- getHandler().post(new Runnable() {
- @Override
- public void run() {
- callback.onError(error);
- }
- });
- }
+ }
+
+ @Override
+ public void onError(final String error) {
+ getHandler().post(new Runnable() {
+ @Override
+ public void run() {
+ callback.onError(error);
+ }
});
- }
-
- /**
- * Remove an offline region from the database and perform any resources evictions
- * necessary as a result.
- * <p>
- * Eviction works by removing the least-recently requested resources not also required
- * by other regions, until the database shrinks below a certain size.
- * </p>
- * <p>
- * When the operation is complete or encounters an error, the given callback will be
- * executed on the main thread.
- * </p>
- * <p>
- * After you call this method, you may not call any additional methods on this object.
- * </p>
- *
- * @param callback the callback to be invoked
- */
- public void delete(@NonNull final OfflineRegionDeleteCallback callback) {
- deleteOfflineRegion(new OfflineRegionDeleteCallback() {
- @Override
- public void onDelete() {
- getHandler().post(new Runnable() {
- @Override
- public void run() {
- callback.onDelete();
- OfflineRegion.this.finalize();
- }
- });
- }
-
- @Override
- public void onError(final String error) {
- getHandler().post(new Runnable() {
- @Override
- public void run() {
- callback.onError(error);
- }
- });
- }
+ }
+ });
+ }
+
+ /**
+ * Remove an offline region from the database and perform any resources evictions
+ * necessary as a result.
+ * <p>
+ * Eviction works by removing the least-recently requested resources not also required
+ * by other regions, until the database shrinks below a certain size.
+ * </p>
+ * <p>
+ * When the operation is complete or encounters an error, the given callback will be
+ * executed on the main thread.
+ * </p>
+ * <p>
+ * After you call this method, you may not call any additional methods on this object.
+ * </p>
+ *
+ * @param callback the callback to be invoked
+ */
+ public void delete(@NonNull final OfflineRegionDeleteCallback callback) {
+ deleteOfflineRegion(new OfflineRegionDeleteCallback() {
+ @Override
+ public void onDelete() {
+ getHandler().post(new Runnable() {
+ @Override
+ public void run() {
+ callback.onDelete();
+ OfflineRegion.this.finalize();
+ }
});
- }
-
- /**
- * Update an offline region metadata from the database.
- * <p>
- * When the operation is complete or encounters an error, the given callback will be
- * executed on the main thread.
- * </p>
- * <p>
- * After you call this method, you may not call any additional methods on this object.
- * </p>
- *
- * @param callback the callback to be invoked
- */
- public void updateMetadata(@NonNull final byte[] bytes, @NonNull final OfflineRegionUpdateMetadataCallback callback) {
- updateOfflineRegionMetadata(bytes, new OfflineRegionUpdateMetadataCallback() {
- @Override
- public void onUpdate(final byte[] metadata) {
- getHandler().post(new Runnable() {
- @Override
- public void run() {
- mMetadata = metadata;
- callback.onUpdate(metadata);
- }
- });
- }
-
- @Override
- public void onError(final String error) {
- getHandler().post(new Runnable() {
- @Override
- public void run() {
- callback.onError(error);
- }
- });
- }
+ }
+
+ @Override
+ public void onError(final String error) {
+ getHandler().post(new Runnable() {
+ @Override
+ public void run() {
+ callback.onError(error);
+ }
});
+ }
+ });
+ }
+
+ /**
+ * Update an offline region metadata from the database.
+ * <p>
+ * When the operation is complete or encounters an error, the given callback will be
+ * executed on the main thread.
+ * </p>
+ * <p>
+ * After you call this method, you may not call any additional methods on this object.
+ * </p>
+ *
+ * @param callback the callback to be invoked
+ */
+ public void updateMetadata(@NonNull final byte[] bytes, @NonNull final OfflineRegionUpdateMetadataCallback callback) {
+ updateOfflineRegionMetadata(bytes, new OfflineRegionUpdateMetadataCallback() {
+ @Override
+ public void onUpdate(final byte[] metadata) {
+ getHandler().post(new Runnable() {
+ @Override
+ public void run() {
+ mMetadata = metadata;
+ callback.onUpdate(metadata);
+ }
+ });
+ }
+
+ @Override
+ public void onError(final String error) {
+ getHandler().post(new Runnable() {
+ @Override
+ public void run() {
+ callback.onError(error);
+ }
+ });
+ }
+ });
+ }
+
+ @Override
+ protected void finalize() {
+ try {
+ super.finalize();
+ destroyOfflineRegion();
+ } catch (Throwable throwable) {
+ Timber.e("Failed to finalize OfflineRegion: " + throwable.getMessage());
}
+ }
- @Override
- protected void finalize() {
- try {
- super.finalize();
- destroyOfflineRegion();
- } catch (Throwable throwable) {
- Log.e(LOG_TAG, "Failed to finalize OfflineRegion: " + throwable.getMessage());
- }
- }
-
- /*
- * Native methods
- */
+ /*
+ * Native methods
+ */
- private native void destroyOfflineRegion();
+ private native void destroyOfflineRegion();
- private native void setOfflineRegionObserver(
- OfflineRegionObserver observerCallback);
+ private native void setOfflineRegionObserver(
+ OfflineRegionObserver observerCallback);
- private native void setOfflineRegionDownloadState(
- @DownloadState int offlineRegionDownloadState);
+ private native void setOfflineRegionDownloadState(
+ @DownloadState int offlineRegionDownloadState);
- private native void getOfflineRegionStatus(
- OfflineRegionStatusCallback statusCallback);
+ private native void getOfflineRegionStatus(
+ OfflineRegionStatusCallback statusCallback);
- private native void deleteOfflineRegion(
- OfflineRegionDeleteCallback deleteCallback);
+ private native void deleteOfflineRegion(
+ OfflineRegionDeleteCallback deleteCallback);
- private native void updateOfflineRegionMetadata(byte[] metadata, OfflineRegionUpdateMetadataCallback callback);
+ private native void updateOfflineRegionMetadata(byte[] metadata, OfflineRegionUpdateMetadataCallback callback);
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionDefinition.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionDefinition.java
index 0e7fb38e1c..a21ff0a443 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionDefinition.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionDefinition.java
@@ -2,7 +2,7 @@ package com.mapbox.mapboxsdk.offline;
/**
* This is the interface that all Offline Region definitions have to implement.
- *
+ * <p>
* For the present, a tile pyramid is the only type of offline region.
*/
public interface OfflineRegionDefinition {
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionError.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionError.java
index e7a57379c5..60c4a8661c 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionError.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionError.java
@@ -10,44 +10,47 @@ import java.lang.annotation.RetentionPolicy;
*/
public class OfflineRegionError {
- /**
- * Error code, as a string, self-explanatory.
- */
- @StringDef({REASON_SUCCESS, REASON_NOT_FOUND, REASON_SERVER, REASON_CONNECTION, REASON_OTHER})
- @Retention(RetentionPolicy.SOURCE)
- public @interface ErrorReason {}
-
- public static final String REASON_SUCCESS = "REASON_SUCCESS";
- public static final String REASON_NOT_FOUND = "REASON_NOT_FOUND";
- public static final String REASON_SERVER = "REASON_SERVER";
- public static final String REASON_CONNECTION = "REASON_CONNECTION";
- public static final String REASON_OTHER = "REASON_OTHER";
-
- private @ErrorReason String reason;
-
- /**
- /* An error message from the request handler, e.g. a server message or a system message
- /* informing the user about the reason for the failure.
- */
- private String message;
-
- /*
- * Constructors
- */
-
- private OfflineRegionError() {
- // For JNI use only
- }
-
- /*
- * Getters
- */
-
- public @ErrorReason String getReason() {
- return reason;
- }
-
- public String getMessage() {
- return message;
- }
+ /**
+ * Error code, as a string, self-explanatory.
+ */
+ @StringDef( {REASON_SUCCESS, REASON_NOT_FOUND, REASON_SERVER, REASON_CONNECTION, REASON_OTHER})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ErrorReason {
+ }
+
+ public static final String REASON_SUCCESS = "REASON_SUCCESS";
+ public static final String REASON_NOT_FOUND = "REASON_NOT_FOUND";
+ public static final String REASON_SERVER = "REASON_SERVER";
+ public static final String REASON_CONNECTION = "REASON_CONNECTION";
+ public static final String REASON_OTHER = "REASON_OTHER";
+
+ @ErrorReason
+ private String reason;
+
+ /**
+ * /* An error message from the request handler, e.g. a server message or a system message
+ * /* informing the user about the reason for the failure.
+ */
+ private String message;
+
+ /*
+ * Constructors
+ */
+
+ private OfflineRegionError() {
+ // For JNI use only
+ }
+
+ /*
+ * Getters
+ */
+
+ @ErrorReason
+ public String getReason() {
+ return reason;
+ }
+
+ public String getMessage() {
+ return message;
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionStatus.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionStatus.java
index 48609a13bb..11f2da132d 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionStatus.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionStatus.java
@@ -4,101 +4,103 @@ package com.mapbox.mapboxsdk.offline;
* A region's status includes its active/inactive state as well as counts
* of the number of resources that have completed downloading, their total
* size in bytes, and the total number of resources that are required.
- *
+ * <p>
* Note that the total required size in bytes is not currently available. A
* future API release may provide an estimate of this number.
*/
public class OfflineRegionStatus {
- @OfflineRegion.DownloadState private int downloadState = OfflineRegion.STATE_INACTIVE;
-
- /**
- * The number of resources (inclusive of tiles) that have been fully downloaded
- * and are ready for offline access.
- */
- private long completedResourceCount = 0;
-
- /**
- * The cumulative size, in bytes, of all resources (inclusive of tiles) that have
- * been fully downloaded.
- */
- private long completedResourceSize = 0;
-
- /**
- * The number of tiles that have been fully downloaded and are ready for
- * offline access.
- */
- private long completedTileCount = 0;
-
- /**
- * The cumulative size, in bytes, of all tiles that have been fully downloaded.
- */
- private long completedTileSize = 0;
-
- /**
- * The number of resources that are known to be required for this region. See the
- * documentation for `requiredResourceCountIsPrecise` for an important caveat
- * about this number.
- */
- private long requiredResourceCount = 0;
-
- /**
- * This property is true when the value of requiredResourceCount is a precise
- * count of the number of required resources, and false when it is merely a lower
- * bound.
- *
- * Specifically, it is false during early phases of an offline download. Once
- * style and tile sources have been downloaded, it is possible to calculate the
- * precise number of required resources, at which point it is set to true.
- */
- private boolean requiredResourceCountIsPrecise = true;
-
- /*
- * Use setObserver(OfflineRegionObserver observer) to obtain a OfflineRegionStatus object.
- */
-
- private OfflineRegionStatus() {
- // For JNI use only
- }
-
- /*
- * Is the region complete?
- */
-
- public boolean isComplete() {
- return (completedResourceCount == requiredResourceCount);
- }
-
- /*
- * Getters
- */
-
- public @OfflineRegion.DownloadState int getDownloadState() {
- return downloadState;
- }
-
- public long getCompletedResourceCount() {
- return completedResourceCount;
- }
-
- public long getCompletedResourceSize() {
- return completedResourceSize;
- }
-
- public long getCompletedTileCount() {
- return completedTileCount;
- }
-
- public long getCompletedTileSize() {
- return completedTileSize;
- }
-
- public long getRequiredResourceCount() {
- return requiredResourceCount;
- }
-
- public boolean isRequiredResourceCountPrecise() {
- return requiredResourceCountIsPrecise;
- }
+ @OfflineRegion.DownloadState
+ private int downloadState = OfflineRegion.STATE_INACTIVE;
+
+ /**
+ * The number of resources (inclusive of tiles) that have been fully downloaded
+ * and are ready for offline access.
+ */
+ private long completedResourceCount = 0;
+
+ /**
+ * The cumulative size, in bytes, of all resources (inclusive of tiles) that have
+ * been fully downloaded.
+ */
+ private long completedResourceSize = 0;
+
+ /**
+ * The number of tiles that have been fully downloaded and are ready for
+ * offline access.
+ */
+ private long completedTileCount = 0;
+
+ /**
+ * The cumulative size, in bytes, of all tiles that have been fully downloaded.
+ */
+ private long completedTileSize = 0;
+
+ /**
+ * The number of resources that are known to be required for this region. See the
+ * documentation for `requiredResourceCountIsPrecise` for an important caveat
+ * about this number.
+ */
+ private long requiredResourceCount = 0;
+
+ /**
+ * This property is true when the value of requiredResourceCount is a precise
+ * count of the number of required resources, and false when it is merely a lower
+ * bound.
+ * <p>
+ * Specifically, it is false during early phases of an offline download. Once
+ * style and tile sources have been downloaded, it is possible to calculate the
+ * precise number of required resources, at which point it is set to true.
+ */
+ private boolean requiredResourceCountIsPrecise = true;
+
+ /*
+ * Use setObserver(OfflineRegionObserver observer) to obtain a OfflineRegionStatus object.
+ */
+
+ private OfflineRegionStatus() {
+ // For JNI use only
+ }
+
+ /*
+ * Is the region complete?
+ */
+
+ public boolean isComplete() {
+ return (completedResourceCount == requiredResourceCount);
+ }
+
+ /*
+ * Getters
+ */
+
+ @OfflineRegion.DownloadState
+ public int getDownloadState() {
+ return downloadState;
+ }
+
+ public long getCompletedResourceCount() {
+ return completedResourceCount;
+ }
+
+ public long getCompletedResourceSize() {
+ return completedResourceSize;
+ }
+
+ public long getCompletedTileCount() {
+ return completedTileCount;
+ }
+
+ public long getCompletedTileSize() {
+ return completedTileSize;
+ }
+
+ public long getRequiredResourceCount() {
+ return requiredResourceCount;
+ }
+
+ public boolean isRequiredResourceCountPrecise() {
+ return requiredResourceCountIsPrecise;
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineTilePyramidRegionDefinition.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineTilePyramidRegionDefinition.java
index 5a0be6b33f..5fc844afe5 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineTilePyramidRegionDefinition.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineTilePyramidRegionDefinition.java
@@ -5,61 +5,61 @@ import com.mapbox.mapboxsdk.geometry.LatLngBounds;
/**
* An offline region defined by a style URL, geographic bounding box, zoom range, and
* device pixel ratio.
- *
+ * <p>
* Both minZoom and maxZoom must be ≥ 0, and maxZoom must be ≥ minZoom.
- *
+ * <p>
* maxZoom may be ∞, in which case for each tile source, the region will include
* tiles from minZoom up to the maximum zoom level provided by that source.
- *
+ * <p>
* pixelRatio must be ≥ 0 and should typically be 1.0 or 2.0.
*/
public class OfflineTilePyramidRegionDefinition implements OfflineRegionDefinition {
- private String styleURL;
- private LatLngBounds bounds;
- private double minZoom;
- private double maxZoom;
- private float pixelRatio;
+ private String styleURL;
+ private LatLngBounds bounds;
+ private double minZoom;
+ private double maxZoom;
+ private float pixelRatio;
- /*
- * Constructors
- */
+ /*
+ * Constructors
+ */
- private OfflineTilePyramidRegionDefinition() {
- // For JNI use only
- }
+ private OfflineTilePyramidRegionDefinition() {
+ // For JNI use only
+ }
- public OfflineTilePyramidRegionDefinition(
- String styleURL, LatLngBounds bounds, double minZoom, double maxZoom, float pixelRatio) {
- this.styleURL = styleURL;
- this.bounds = bounds;
- this.minZoom = minZoom;
- this.maxZoom = maxZoom;
- this.pixelRatio = pixelRatio;
- }
+ public OfflineTilePyramidRegionDefinition(
+ String styleURL, LatLngBounds bounds, double minZoom, double maxZoom, float pixelRatio) {
+ this.styleURL = styleURL;
+ this.bounds = bounds;
+ this.minZoom = minZoom;
+ this.maxZoom = maxZoom;
+ this.pixelRatio = pixelRatio;
+ }
- /*
- * Getters
- */
+ /*
+ * Getters
+ */
- public String getStyleURL() {
- return styleURL;
- }
+ public String getStyleURL() {
+ return styleURL;
+ }
- public LatLngBounds getBounds() {
- return bounds;
- }
+ public LatLngBounds getBounds() {
+ return bounds;
+ }
- public double getMinZoom() {
- return minZoom;
- }
+ public double getMinZoom() {
+ return minZoom;
+ }
- public double getMaxZoom() {
- return maxZoom;
- }
+ public double getMaxZoom() {
+ return maxZoom;
+ }
- public float getPixelRatio() {
- return pixelRatio;
- }
+ public float getPixelRatio() {
+ return pixelRatio;
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/BackgroundLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/BackgroundLayer.java
index 893ffbc1ec..45523b41ab 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/BackgroundLayer.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/BackgroundLayer.java
@@ -1,111 +1,108 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
package com.mapbox.mapboxsdk.style.layers;
-
-import com.mapbox.mapboxsdk.exceptions.ConversionException;
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
+import android.support.annotation.UiThread;
-import static com.mapbox.mapboxsdk.utils.ColorUtils.*;
+import static com.mapbox.mapboxsdk.utils.ColorUtils.rgbaToColor;
/**
* The background color or pattern of the map.
*
* @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#layers-background">The online documentation</a>
*/
+@UiThread
public class BackgroundLayer extends Layer {
- /**
- * Creates a BackgroundLayer.
- *
- * @param nativePtr pointer used by core
- */
- public BackgroundLayer(long nativePtr) {
- super(nativePtr);
+ /**
+ * Creates a BackgroundLayer.
+ *
+ * @param nativePtr pointer used by core
+ */
+ public BackgroundLayer(long nativePtr) {
+ super(nativePtr);
+ }
+
+ /**
+ * Creates a BackgroundLayer.
+ *
+ * @param layerId the id of the layer
+ */
+ public BackgroundLayer(String layerId) {
+ initialize(layerId);
+ }
+
+ protected native void initialize(String layerId);
+
+ /**
+ * Set a property or properties.
+ *
+ * @param properties the var-args properties
+ * @return This
+ */
+ public BackgroundLayer withProperties(@NonNull Property<?>... properties) {
+ setProperties(properties);
+ return this;
+ }
+
+ // Property getters
+
+ /**
+ * Get the BackgroundColor property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getBackgroundColor() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetBackgroundColor());
+ }
+
+ /**
+ * The color with which the background will be drawn.
+ *
+ * @return int representation of a rgba string color
+ * @throws RuntimeException thrown if property isn't a value
+ */
+ @ColorInt
+ public int getBackgroundColorAsInt() {
+ PropertyValue<String> value = getBackgroundColor();
+ if (value.isValue()) {
+ return rgbaToColor(value.getValue());
+ } else {
+ throw new RuntimeException("background-color was set as a Function");
}
+ }
- /**
- * Creates a BackgroundLayer.
- *
- * @param layerId the id of the layer
- */
- public BackgroundLayer(String layerId) {
- initialize(layerId);
- }
- protected native void initialize(String layerId);
-
- /**
- * Set a property or properties.
- *
- * @param properties the var-args properties
- * @return This
- */
- public BackgroundLayer withProperties(@NonNull Property<?>... properties) {
- setProperties(properties);
- return this;
- }
+ /**
+ * Get the BackgroundPattern property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getBackgroundPattern() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetBackgroundPattern());
+ }
- // Property getters
-
- /**
- * Get the BackgroundColor property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getBackgroundColor() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetBackgroundColor());
- }
- /**
- * The color with which the background will be drawn.
- *
- * @return int representation of a rgba string color
- * @throws RuntimeException thrown if property isn't a value
- */
- @ColorInt
- public int getBackgroundColorAsInt() {
- checkValidity();
- PropertyValue<String> value = getBackgroundColor();
- if (value.isValue()) {
- return rgbaToColor(value.getValue());
- } else {
- throw new RuntimeException("background-color was set as a Function");
- }
- }
+ /**
+ * Get the BackgroundOpacity property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getBackgroundOpacity() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetBackgroundOpacity());
+ }
-
- /**
- * Get the BackgroundPattern property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getBackgroundPattern() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetBackgroundPattern());
- }
-
- /**
- * Get the BackgroundOpacity property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getBackgroundOpacity() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetBackgroundOpacity());
- }
-
- private native Object nativeGetBackgroundColor();
+ private native Object nativeGetBackgroundColor();
- private native Object nativeGetBackgroundPattern();
+ private native Object nativeGetBackgroundPattern();
- private native Object nativeGetBackgroundOpacity();
+ private native Object nativeGetBackgroundOpacity();
- @Override
- protected native void finalize() throws Throwable;
+ @Override
+ protected native void finalize() throws Throwable;
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CannotAddLayerException.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CannotAddLayerException.java
new file mode 100644
index 0000000000..212493032d
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CannotAddLayerException.java
@@ -0,0 +1,12 @@
+package com.mapbox.mapboxsdk.style.layers;
+
+/**
+ * Thrown when adding a layer to a map twice
+ */
+public class CannotAddLayerException extends RuntimeException {
+
+ public CannotAddLayerException(String message) {
+ super(message);
+ }
+
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CircleLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CircleLayer.java
index a9f081b2fa..f16ab688d6 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CircleLayer.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CircleLayer.java
@@ -1,227 +1,271 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
package com.mapbox.mapboxsdk.style.layers;
-
-import com.mapbox.mapboxsdk.exceptions.ConversionException;
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
+import android.support.annotation.UiThread;
-import static com.mapbox.mapboxsdk.utils.ColorUtils.*;
+import static com.mapbox.mapboxsdk.utils.ColorUtils.rgbaToColor;
/**
* A filled circle.
*
* @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#layers-circle">The online documentation</a>
*/
+@UiThread
public class CircleLayer extends Layer {
- /**
- * Creates a CircleLayer.
- *
- * @param nativePtr pointer used by core
- */
- public CircleLayer(long nativePtr) {
- super(nativePtr);
- }
+ /**
+ * Creates a CircleLayer.
+ *
+ * @param nativePtr pointer used by core
+ */
+ public CircleLayer(long nativePtr) {
+ super(nativePtr);
+ }
- /**
- * Creates a CircleLayer.
- *
- * @param layerId the id of the layer
- * @param sourceId the id of the source
- */
- public CircleLayer(String layerId, String sourceId) {
- initialize(layerId, sourceId);
- }
+ /**
+ * Creates a CircleLayer.
+ *
+ * @param layerId the id of the layer
+ * @param sourceId the id of the source
+ */
+ public CircleLayer(String layerId, String sourceId) {
+ initialize(layerId, sourceId);
+ }
- protected native void initialize(String layerId, String sourceId);
+ protected native void initialize(String layerId, String sourceId);
- /**
- * Set the source layer.
- *
- * @param sourceLayer the source layer to set
- */
- public void setSourceLayer(String sourceLayer) {
- checkValidity();
- nativeSetSourceLayer(sourceLayer);
- }
+ /**
+ * Set the source layer.
+ *
+ * @param sourceLayer the source layer to set
+ */
+ public void setSourceLayer(String sourceLayer) {
+ nativeSetSourceLayer(sourceLayer);
+ }
- /**
- * Set the source Layer.
- *
- * @param sourceLayer the source layer to set
- * @return This
- */
- public CircleLayer withSourceLayer(String sourceLayer) {
- setSourceLayer(sourceLayer);
- return this;
- }
- /**
- * Set a single filter.
- *
- * @param filter the filter to set
- */
- public void setFilter(Filter.Statement filter) {
- checkValidity();
- this.setFilter(filter.toArray());
- }
+ /**
+ * Set the source Layer.
+ *
+ * @param sourceLayer the source layer to set
+ * @return This
+ */
+ public CircleLayer withSourceLayer(String sourceLayer) {
+ setSourceLayer(sourceLayer);
+ return this;
+ }
- /**
- * Set an array of filters.
- *
- * @param filter the filter array to set
- */
- public void setFilter(Object[] filter) {
- checkValidity();
- nativeSetFilter(filter);
- }
+ /**
+ * Set a single filter.
+ *
+ * @param filter the filter to set
+ */
+ public void setFilter(Filter.Statement filter) {
+ this.setFilter(filter.toArray());
+ }
- /**
- * Set an array of filters.
- *
- * @param filter tthe filter array to set
- * @return This
- */
- public CircleLayer withFilter(Object[] filter) {
- setFilter(filter);
- return this;
- }
+ /**
+ * Set an array of filters.
+ *
+ * @param filter the filter array to set
+ */
+ public void setFilter(Object[] filter) {
+ nativeSetFilter(filter);
+ }
- /**
- * Set a single filter.
- *
- * @param filter the filter to set
- * @return This
- */
- public CircleLayer withFilter(Filter.Statement filter) {
- setFilter(filter);
- return this;
- }
+ /**
+ * Set an array of filters.
+ *
+ * @param filter tthe filter array to set
+ * @return This
+ */
+ public CircleLayer withFilter(Object[] filter) {
+ setFilter(filter);
+ return this;
+ }
+ /**
+ * Set a single filter.
+ *
+ * @param filter the filter to set
+ * @return This
+ */
+ public CircleLayer withFilter(Filter.Statement filter) {
+ setFilter(filter);
+ return this;
+ }
- /**
- * Set a property or properties.
- *
- * @param properties the var-args properties
- * @return This
- */
- public CircleLayer withProperties(@NonNull Property<?>... properties) {
- setProperties(properties);
- return this;
- }
- // Property getters
-
- /**
- * Get the CircleRadius property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getCircleRadius() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetCircleRadius());
- }
-
- /**
- * Get the CircleColor property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getCircleColor() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetCircleColor());
- }
- /**
- * The fill color of the circle.
- *
- * @return int representation of a rgba string color
- * @throws RuntimeException thrown if property isn't a value
- */
- @ColorInt
- public int getCircleColorAsInt() {
- checkValidity();
- PropertyValue<String> value = getCircleColor();
- if (value.isValue()) {
- return rgbaToColor(value.getValue());
- } else {
- throw new RuntimeException("circle-color was set as a Function");
- }
- }
+ /**
+ * Set a property or properties.
+ *
+ * @param properties the var-args properties
+ * @return This
+ */
+ public CircleLayer withProperties(@NonNull Property<?>... properties) {
+ setProperties(properties);
+ return this;
+ }
-
- /**
- * Get the CircleBlur property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getCircleBlur() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetCircleBlur());
- }
-
- /**
- * Get the CircleOpacity property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getCircleOpacity() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetCircleOpacity());
- }
-
- /**
- * Get the CircleTranslate property
- *
- * @return property wrapper value around Float[]
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float[]> getCircleTranslate() {
- checkValidity();
- return (PropertyValue<Float[]>) new PropertyValue(nativeGetCircleTranslate());
- }
-
- /**
- * Get the CircleTranslateAnchor property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getCircleTranslateAnchor() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetCircleTranslateAnchor());
+ // Property getters
+
+ /**
+ * Get the CircleRadius property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getCircleRadius() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetCircleRadius());
+ }
+
+ /**
+ * Get the CircleColor property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getCircleColor() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetCircleColor());
+ }
+
+ /**
+ * The fill color of the circle.
+ *
+ * @return int representation of a rgba string color
+ * @throws RuntimeException thrown if property isn't a value
+ */
+ @ColorInt
+ public int getCircleColorAsInt() {
+ PropertyValue<String> value = getCircleColor();
+ if (value.isValue()) {
+ return rgbaToColor(value.getValue());
+ } else {
+ throw new RuntimeException("circle-color was set as a Function");
}
-
- /**
- * Get the CirclePitchScale property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getCirclePitchScale() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetCirclePitchScale());
+ }
+
+
+ /**
+ * Get the CircleBlur property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getCircleBlur() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetCircleBlur());
+ }
+
+ /**
+ * Get the CircleOpacity property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getCircleOpacity() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetCircleOpacity());
+ }
+
+ /**
+ * Get the CircleTranslate property
+ *
+ * @return property wrapper value around Float[]
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float[]> getCircleTranslate() {
+ return (PropertyValue<Float[]>) new PropertyValue(nativeGetCircleTranslate());
+ }
+
+ /**
+ * Get the CircleTranslateAnchor property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getCircleTranslateAnchor() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetCircleTranslateAnchor());
+ }
+
+ /**
+ * Get the CirclePitchScale property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getCirclePitchScale() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetCirclePitchScale());
+ }
+
+ /**
+ * Get the CircleStrokeWidth property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getCircleStrokeWidth() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetCircleStrokeWidth());
+ }
+
+ /**
+ * Get the CircleStrokeColor property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getCircleStrokeColor() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetCircleStrokeColor());
+ }
+
+ /**
+ * The stroke color of the circle.
+ *
+ * @return int representation of a rgba string color
+ * @throws RuntimeException thrown if property isn't a value
+ */
+ @ColorInt
+ public int getCircleStrokeColorAsInt() {
+ PropertyValue<String> value = getCircleStrokeColor();
+ if (value.isValue()) {
+ return rgbaToColor(value.getValue());
+ } else {
+ throw new RuntimeException("circle-stroke-color was set as a Function");
}
-
- private native Object nativeGetCircleRadius();
+ }
+
+
+ /**
+ * Get the CircleStrokeOpacity property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getCircleStrokeOpacity() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetCircleStrokeOpacity());
+ }
+
+ private native Object nativeGetCircleRadius();
+
+ private native Object nativeGetCircleColor();
+
+ private native Object nativeGetCircleBlur();
+
+ private native Object nativeGetCircleOpacity();
- private native Object nativeGetCircleColor();
+ private native Object nativeGetCircleTranslate();
- private native Object nativeGetCircleBlur();
+ private native Object nativeGetCircleTranslateAnchor();
- private native Object nativeGetCircleOpacity();
+ private native Object nativeGetCirclePitchScale();
- private native Object nativeGetCircleTranslate();
+ private native Object nativeGetCircleStrokeWidth();
- private native Object nativeGetCircleTranslateAnchor();
+ private native Object nativeGetCircleStrokeColor();
- private native Object nativeGetCirclePitchScale();
+ private native Object nativeGetCircleStrokeOpacity();
- @Override
- protected native void finalize() throws Throwable;
+ @Override
+ protected native void finalize() throws Throwable;
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CustomLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CustomLayer.java
index 4d578b54f8..7807556b78 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CustomLayer.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CustomLayer.java
@@ -8,27 +8,28 @@ package com.mapbox.mapboxsdk.style.layers;
*/
public class CustomLayer extends Layer {
- public CustomLayer(String id,
- long context,
- long initializeFunction,
- long renderFunction,
- long deinitializeFunction) {
- initialize(id, initializeFunction, renderFunction, deinitializeFunction, context);
- }
+ public CustomLayer(String id,
+ long context,
+ long initializeFunction,
+ long renderFunction,
+ long deinitializeFunction) {
+ initialize(id, initializeFunction, renderFunction, deinitializeFunction, context);
+ }
- public CustomLayer(long nativePtr) {
- super(nativePtr);
- }
+ public CustomLayer(long nativePtr) {
+ super(nativePtr);
+ }
- public void update() {
- nativeUpdate();
- }
+ public void update() {
+ nativeUpdate();
+ }
- protected native void initialize(String id, long initializeFunction, long renderFunction, long deinitializeFunction, long context);
+ protected native void initialize(String id, long initializeFunction, long renderFunction, long deinitializeFunction,
+ long context);
- protected native void nativeUpdate();
+ protected native void nativeUpdate();
- @Override
- protected native void finalize() throws Throwable;
+ @Override
+ protected native void finalize() throws Throwable;
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/FillLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/FillLayer.java
index e19dc20283..3f79c9306a 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/FillLayer.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/FillLayer.java
@@ -1,244 +1,236 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
package com.mapbox.mapboxsdk.style.layers;
-
-import com.mapbox.mapboxsdk.exceptions.ConversionException;
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
+import android.support.annotation.UiThread;
-import static com.mapbox.mapboxsdk.utils.ColorUtils.*;
+import static com.mapbox.mapboxsdk.utils.ColorUtils.rgbaToColor;
/**
* A filled polygon with an optional stroked border.
*
* @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#layers-fill">The online documentation</a>
*/
+@UiThread
public class FillLayer extends Layer {
- /**
- * Creates a FillLayer.
- *
- * @param nativePtr pointer used by core
- */
- public FillLayer(long nativePtr) {
- super(nativePtr);
- }
-
- /**
- * Creates a FillLayer.
- *
- * @param layerId the id of the layer
- * @param sourceId the id of the source
- */
- public FillLayer(String layerId, String sourceId) {
- initialize(layerId, sourceId);
- }
-
- protected native void initialize(String layerId, String sourceId);
-
- /**
- * Set the source layer.
- *
- * @param sourceLayer the source layer to set
- */
- public void setSourceLayer(String sourceLayer) {
- checkValidity();
- nativeSetSourceLayer(sourceLayer);
- }
-
- /**
- * Set the source Layer.
- *
- * @param sourceLayer the source layer to set
- * @return This
- */
- public FillLayer withSourceLayer(String sourceLayer) {
- setSourceLayer(sourceLayer);
- return this;
- }
- /**
- * Set a single filter.
- *
- * @param filter the filter to set
- */
- public void setFilter(Filter.Statement filter) {
- checkValidity();
- this.setFilter(filter.toArray());
- }
-
- /**
- * Set an array of filters.
- *
- * @param filter the filter array to set
- */
- public void setFilter(Object[] filter) {
- checkValidity();
- nativeSetFilter(filter);
- }
-
- /**
- * Set an array of filters.
- *
- * @param filter tthe filter array to set
- * @return This
- */
- public FillLayer withFilter(Object[] filter) {
- setFilter(filter);
- return this;
- }
-
- /**
- * Set a single filter.
- *
- * @param filter the filter to set
- * @return This
- */
- public FillLayer withFilter(Filter.Statement filter) {
- setFilter(filter);
- return this;
- }
-
-
- /**
- * Set a property or properties.
- *
- * @param properties the var-args properties
- * @return This
- */
- public FillLayer withProperties(@NonNull Property<?>... properties) {
- setProperties(properties);
- return this;
- }
-
- // Property getters
-
- /**
- * Get the FillAntialias property
- *
- * @return property wrapper value around Boolean
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Boolean> getFillAntialias() {
- checkValidity();
- return (PropertyValue<Boolean>) new PropertyValue(nativeGetFillAntialias());
- }
-
- /**
- * Get the FillOpacity property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getFillOpacity() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetFillOpacity());
- }
-
- /**
- * Get the FillColor property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getFillColor() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetFillColor());
- }
- /**
- * 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 1px stroke, if it is used.
- *
- * @return int representation of a rgba string color
- * @throws RuntimeException thrown if property isn't a value
- */
- @ColorInt
- public int getFillColorAsInt() {
- checkValidity();
- PropertyValue<String> value = getFillColor();
- if (value.isValue()) {
- return rgbaToColor(value.getValue());
- } else {
- throw new RuntimeException("fill-color was set as a Function");
- }
- }
-
-
- /**
- * Get the FillOutlineColor property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getFillOutlineColor() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetFillOutlineColor());
- }
- /**
- * The outline color of the fill. Matches the value of `fill-color` if unspecified.
- *
- * @return int representation of a rgba string color
- * @throws RuntimeException thrown if property isn't a value
- */
- @ColorInt
- public int getFillOutlineColorAsInt() {
- checkValidity();
- PropertyValue<String> value = getFillOutlineColor();
- if (value.isValue()) {
- return rgbaToColor(value.getValue());
- } else {
- throw new RuntimeException("fill-outline-color was set as a Function");
- }
- }
-
-
- /**
- * Get the FillTranslate property
- *
- * @return property wrapper value around Float[]
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float[]> getFillTranslate() {
- checkValidity();
- return (PropertyValue<Float[]>) new PropertyValue(nativeGetFillTranslate());
- }
-
- /**
- * Get the FillTranslateAnchor property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getFillTranslateAnchor() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetFillTranslateAnchor());
- }
-
- /**
- * Get the FillPattern property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getFillPattern() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetFillPattern());
- }
-
- private native Object nativeGetFillAntialias();
-
- private native Object nativeGetFillOpacity();
-
- private native Object nativeGetFillColor();
-
- private native Object nativeGetFillOutlineColor();
-
- private native Object nativeGetFillTranslate();
-
- private native Object nativeGetFillTranslateAnchor();
-
- private native Object nativeGetFillPattern();
-
-
- @Override
- protected native void finalize() throws Throwable;
+ /**
+ * Creates a FillLayer.
+ *
+ * @param nativePtr pointer used by core
+ */
+ public FillLayer(long nativePtr) {
+ super(nativePtr);
+ }
+
+ /**
+ * Creates a FillLayer.
+ *
+ * @param layerId the id of the layer
+ * @param sourceId the id of the source
+ */
+ public FillLayer(String layerId, String sourceId) {
+ initialize(layerId, sourceId);
+ }
+
+ protected native void initialize(String layerId, String sourceId);
+
+ /**
+ * Set the source layer.
+ *
+ * @param sourceLayer the source layer to set
+ */
+ public void setSourceLayer(String sourceLayer) {
+ nativeSetSourceLayer(sourceLayer);
+ }
+
+ /**
+ * Set the source Layer.
+ *
+ * @param sourceLayer the source layer to set
+ * @return This
+ */
+ public FillLayer withSourceLayer(String sourceLayer) {
+ setSourceLayer(sourceLayer);
+ return this;
+ }
+
+ /**
+ * Set a single filter.
+ *
+ * @param filter the filter to set
+ */
+ public void setFilter(Filter.Statement filter) {
+ this.setFilter(filter.toArray());
+ }
+
+ /**
+ * Set an array of filters.
+ *
+ * @param filter the filter array to set
+ */
+ public void setFilter(Object[] filter) {
+ nativeSetFilter(filter);
+ }
+
+ /**
+ * Set an array of filters.
+ *
+ * @param filter tthe filter array to set
+ * @return This
+ */
+ public FillLayer withFilter(Object[] filter) {
+ setFilter(filter);
+ return this;
+ }
+
+ /**
+ * Set a single filter.
+ *
+ * @param filter the filter to set
+ * @return This
+ */
+ public FillLayer withFilter(Filter.Statement filter) {
+ setFilter(filter);
+ return this;
+ }
+
+
+ /**
+ * Set a property or properties.
+ *
+ * @param properties the var-args properties
+ * @return This
+ */
+ public FillLayer withProperties(@NonNull Property<?>... properties) {
+ setProperties(properties);
+ return this;
+ }
+
+ // Property getters
+
+ /**
+ * Get the FillAntialias property
+ *
+ * @return property wrapper value around Boolean
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Boolean> getFillAntialias() {
+ return (PropertyValue<Boolean>) new PropertyValue(nativeGetFillAntialias());
+ }
+
+ /**
+ * Get the FillOpacity property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getFillOpacity() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetFillOpacity());
+ }
+
+ /**
+ * Get the FillColor property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getFillColor() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetFillColor());
+ }
+
+ /**
+ * 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 1px stroke, if it is used.
+ *
+ * @return int representation of a rgba string color
+ * @throws RuntimeException thrown if property isn't a value
+ */
+ @ColorInt
+ public int getFillColorAsInt() {
+ PropertyValue<String> value = getFillColor();
+ if (value.isValue()) {
+ return rgbaToColor(value.getValue());
+ } else {
+ throw new RuntimeException("fill-color was set as a Function");
+ }
+ }
+
+
+ /**
+ * Get the FillOutlineColor property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getFillOutlineColor() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetFillOutlineColor());
+ }
+
+ /**
+ * The outline color of the fill. Matches the value of `fill-color` if unspecified.
+ *
+ * @return int representation of a rgba string color
+ * @throws RuntimeException thrown if property isn't a value
+ */
+ @ColorInt
+ public int getFillOutlineColorAsInt() {
+ PropertyValue<String> value = getFillOutlineColor();
+ if (value.isValue()) {
+ return rgbaToColor(value.getValue());
+ } else {
+ throw new RuntimeException("fill-outline-color was set as a Function");
+ }
+ }
+
+
+ /**
+ * Get the FillTranslate property
+ *
+ * @return property wrapper value around Float[]
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float[]> getFillTranslate() {
+ return (PropertyValue<Float[]>) new PropertyValue(nativeGetFillTranslate());
+ }
+
+ /**
+ * Get the FillTranslateAnchor property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getFillTranslateAnchor() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetFillTranslateAnchor());
+ }
+
+ /**
+ * Get the FillPattern property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getFillPattern() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetFillPattern());
+ }
+
+ private native Object nativeGetFillAntialias();
+
+ private native Object nativeGetFillOpacity();
+
+ private native Object nativeGetFillColor();
+
+ private native Object nativeGetFillOutlineColor();
+
+ private native Object nativeGetFillTranslate();
+
+ private native Object nativeGetFillTranslateAnchor();
+
+ private native Object nativeGetFillPattern();
+
+
+ @Override
+ protected native void finalize() throws Throwable;
}
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 6f881e4960..643a126388 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
@@ -10,221 +10,221 @@ import java.util.Collections;
*/
public class Filter {
- /**
- * Base {@link Filter} statement. Subclassed to provide concrete statements.
- */
- public abstract static class Statement {
- protected final String operator;
-
- public Statement(String operator) {
- this.operator = operator;
- }
-
- /**
- * Generate a raw array representation of the filter
- *
- * @return the filter represented as an array
- */
- public abstract Object[] toArray();
- }
-
- /**
- * Represents a {@link Filter} statement. Can be unary (eg `has()`, etc) or take any number of values.
- */
- private static class SimpleStatement extends Statement {
- private final String key;
- private final Object[] values;
-
- /**
- * @param operator the operator (eg `=`, etc)
- * @param key the property key
- * @param values the values to operate on, if any
- */
- SimpleStatement(String operator, String key, Object... values) {
- super(operator);
- this.key = key;
- this.values = values;
- }
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Object[] toArray() {
- ArrayList<Object> array = new ArrayList<>(2 + values.length);
- array.add(operator);
- array.add(key);
- Collections.addAll(array, values);
- return array.toArray();
- }
- }
-
- /**
- * Represents a collection of {@link Statement}s with an operator that describes their relationship
- */
- private static class CompoundStatement extends Statement {
- private final Statement[] statements;
-
- /**
- * @param operator the relationship operator
- * @param statements the statements to compound
- */
- CompoundStatement(String operator, Statement... statements) {
- super(operator);
- this.statements = statements;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Object[] toArray() {
- ArrayList<Object> array = new ArrayList<>(1 + statements.length);
- array.add(operator);
- for (Statement statement : statements) {
- array.add(statement.toArray());
- }
- return array.toArray();
- }
- }
-
- /**
- * Groups a collection of statements in an 'all' relationship
- *
- * @param statements the collection of statements
- * @return the statements compounded
- */
- public static Statement all(Statement... statements) {
- return new CompoundStatement("all", statements);
- }
-
- /**
- * Groups a collection of statements in an 'any' relationship
- *
- * @param statements the collection of statements
- * @return the statements compounded
- */
- public static Statement any(Statement... statements) {
- return new CompoundStatement("any", statements);
- }
-
- /**
- * Groups a collection of statements in an 'none' relationship
- *
- * @param statements the collection of statements
- * @return the statements compounded
- */
- public static Statement none(Statement... statements) {
- return new CompoundStatement("none", statements);
- }
-
- /**
- * Check the property's existence
- *
- * @param key the property key
- * @return the statement
- */
- public static Statement has(String key) {
- return new SimpleStatement("has", key);
- }
+ /**
+ * Base {@link Filter} statement. Subclassed to provide concrete statements.
+ */
+ public abstract static class Statement {
+ protected final String operator;
- /**
- * Check the property's existence, negated
- *
- * @param key the property key
- * @return the statement
- */
- public static Statement notHas(String key) {
- return new SimpleStatement("!has", key);
+ public Statement(String operator) {
+ this.operator = operator;
}
/**
- * Check the property equals the given value
+ * Generate a raw array representation of the filter
*
- * @param key the property key
- * @param value the value to check against
- * @return the statement
- */
- public static Statement eq(String key, Object value) {
- return new SimpleStatement("==", key, value);
- }
-
- /**
- * Check the property does not equals the given value
- *
- * @param key the property key
- * @param value the value to check against
- * @return the statement
- */
- public static Statement neq(String key, Object value) {
- return new SimpleStatement("!=", key, value);
- }
-
- /**
- * Check the property exceeds the given value
- *
- * @param key the property key
- * @param value the value to check against
- * @return the statement
- */
- public static Statement gt(String key, Object value) {
- return new SimpleStatement(">", key, value);
- }
-
- /**
- * Check the property exceeds or equals the given value
- *
- * @param key the property key
- * @param value the value to check against
- * @return the statement
- */
- public static Statement gte(String key, Object value) {
- return new SimpleStatement(">=", key, value);
- }
-
- /**
- * Check the property does not exceeds the given value
- *
- * @param key the property key
- * @param value the value to check against
- * @return the statement
- */
- public static Statement lt(String key, Object value) {
- return new SimpleStatement("<", key, value);
- }
-
- /**
- * Check the property equals or does not exceeds the given value
- *
- * @param key the property key
- * @param value the value to check against
- * @return the statement
- */
- public static Statement lte(String key, Object value) {
- return new SimpleStatement("<=", key, value);
- }
-
- /**
- * Check the property is within the given set
- *
- * @param key the property key
- * @param values the set of values to check against
- * @return the statement
- */
- public static Statement in(String key, Object... values) {
- return new SimpleStatement("in", key, values);
- }
-
- /**
- * Check the property is not within the given set
- *
- * @param key the property key
- * @param values the set of values to check against
- * @return the statement
- */
- public static Statement notIn(String key, Object... values) {
- return new SimpleStatement("!in", key, values);
- }
+ * @return the filter represented as an array
+ */
+ public abstract Object[] toArray();
+ }
+
+ /**
+ * Represents a {@link Filter} statement. Can be unary (eg `has()`, etc) or take any number of values.
+ */
+ private static class SimpleStatement extends Statement {
+ private final String key;
+ private final Object[] values;
+
+ /**
+ * @param operator the operator (eg `=`, etc)
+ * @param key the property key
+ * @param values the values to operate on, if any
+ */
+ SimpleStatement(String operator, String key, Object... values) {
+ super(operator);
+ this.key = key;
+ this.values = values;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object[] toArray() {
+ ArrayList<Object> array = new ArrayList<>(2 + values.length);
+ array.add(operator);
+ array.add(key);
+ Collections.addAll(array, values);
+ return array.toArray();
+ }
+ }
+
+ /**
+ * Represents a collection of {@link Statement}s with an operator that describes their relationship
+ */
+ private static class CompoundStatement extends Statement {
+ private final Statement[] statements;
+
+ /**
+ * @param operator the relationship operator
+ * @param statements the statements to compound
+ */
+ CompoundStatement(String operator, Statement... statements) {
+ super(operator);
+ this.statements = statements;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object[] toArray() {
+ ArrayList<Object> array = new ArrayList<>(1 + statements.length);
+ array.add(operator);
+ for (Statement statement : statements) {
+ array.add(statement.toArray());
+ }
+ return array.toArray();
+ }
+ }
+
+ /**
+ * Groups a collection of statements in an 'all' relationship
+ *
+ * @param statements the collection of statements
+ * @return the statements compounded
+ */
+ public static Statement all(Statement... statements) {
+ return new CompoundStatement("all", statements);
+ }
+
+ /**
+ * Groups a collection of statements in an 'any' relationship
+ *
+ * @param statements the collection of statements
+ * @return the statements compounded
+ */
+ public static Statement any(Statement... statements) {
+ return new CompoundStatement("any", statements);
+ }
+
+ /**
+ * Groups a collection of statements in an 'none' relationship
+ *
+ * @param statements the collection of statements
+ * @return the statements compounded
+ */
+ public static Statement none(Statement... statements) {
+ return new CompoundStatement("none", statements);
+ }
+
+ /**
+ * Check the property's existence
+ *
+ * @param key the property key
+ * @return the statement
+ */
+ public static Statement has(String key) {
+ return new SimpleStatement("has", key);
+ }
+
+ /**
+ * Check the property's existence, negated
+ *
+ * @param key the property key
+ * @return the statement
+ */
+ public static Statement notHas(String key) {
+ return new SimpleStatement("!has", key);
+ }
+
+ /**
+ * Check the property equals the given value
+ *
+ * @param key the property key
+ * @param value the value to check against
+ * @return the statement
+ */
+ public static Statement eq(String key, Object value) {
+ return new SimpleStatement("==", key, value);
+ }
+
+ /**
+ * Check the property does not equals the given value
+ *
+ * @param key the property key
+ * @param value the value to check against
+ * @return the statement
+ */
+ public static Statement neq(String key, Object value) {
+ return new SimpleStatement("!=", key, value);
+ }
+
+ /**
+ * Check the property exceeds the given value
+ *
+ * @param key the property key
+ * @param value the value to check against
+ * @return the statement
+ */
+ public static Statement gt(String key, Object value) {
+ return new SimpleStatement(">", key, value);
+ }
+
+ /**
+ * Check the property exceeds or equals the given value
+ *
+ * @param key the property key
+ * @param value the value to check against
+ * @return the statement
+ */
+ public static Statement gte(String key, Object value) {
+ return new SimpleStatement(">=", key, value);
+ }
+
+ /**
+ * Check the property does not exceeds the given value
+ *
+ * @param key the property key
+ * @param value the value to check against
+ * @return the statement
+ */
+ public static Statement lt(String key, Object value) {
+ return new SimpleStatement("<", key, value);
+ }
+
+ /**
+ * Check the property equals or does not exceeds the given value
+ *
+ * @param key the property key
+ * @param value the value to check against
+ * @return the statement
+ */
+ public static Statement lte(String key, Object value) {
+ return new SimpleStatement("<=", key, value);
+ }
+
+ /**
+ * Check the property is within the given set
+ *
+ * @param key the property key
+ * @param values the set of values to check against
+ * @return the statement
+ */
+ public static Statement in(String key, Object... values) {
+ return new SimpleStatement("in", key, values);
+ }
+
+ /**
+ * Check the property is not within the given set
+ *
+ * @param key the property key
+ * @param values the set of values to check against
+ * @return the statement
+ */
+ public static Statement notIn(String key, Object... values) {
+ return new SimpleStatement("!in", key, values);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Function.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Function.java
index e147b5204f..900fe10476 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Function.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Function.java
@@ -19,119 +19,119 @@ import java.util.Map;
*/
public class Function<T> {
- /**
- * A stop represents a certain point in the range of this function
- *
- * @param <I> input
- * @param <O> output
- */
- public static class Stop<I, O> {
- public final I in;
- public final O out;
-
- Stop(I in, O out) {
- this.in = in;
- this.out = out;
- }
-
- /**
- * @return an array representation of the Stop
- */
- Object[] toValueObject() {
- return new Object[]{in, out};
- }
-
- @Override
- public String toString() {
- return String.format("[%s, %s]", in, out);
- }
- }
-
- /**
- * Zoom functions allow the appearance of a map feature to change with map’s zoom.
- * Zoom functions can be used to create the illusion of depth and control data density.
- * Each stop is an array with two elements, the first is a zoom and the second is a function output value.
- *
- * @param stops the stops that define the function
- * @param <T> the property type
- * @return the {@link Function}
- */
- @SafeVarargs
- public static <T> Function<T> zoom(@NonNull @Size(min = 1) Stop<Float, T>... stops) {
- return new Function<T>(stops);
+ /**
+ * A stop represents a certain point in the range of this function
+ *
+ * @param <I> input
+ * @param <O> output
+ */
+ public static class Stop<I, O> {
+ public final I in;
+ public final O out;
+
+ Stop(I in, O out) {
+ this.in = in;
+ this.out = out;
}
-
/**
- * Zoom functions allow the appearance of a map feature to change with map’s zoom.
- * Zoom functions can be used to create the illusion of depth and control data density.
- * Each stop is an array with two elements, the first is a zoom and the second is a function output value.
- *
- * @param stops the stops that define the function
- * @param base the exponential base of the interpolation curve - Default 1
- * @param <T> the property type
- * @return the {@link Function}
+ * @return an array representation of the Stop
*/
- @SafeVarargs
- public static <T> Function<T> zoom(
- @FloatRange(from = 0, to = 1, fromInclusive = false, toInclusive = false) float base,
- @NonNull @Size(min = 1) Stop<Float, T>... stops) {
- return new Function<T>(stops)
- .withBase(base);
+ Object[] toValueObject() {
+ return new Object[] {in, out};
}
- /**
- * Creates a stop to use in a {@link Function}
- *
- * @param in the input for the stop
- * @param output the output for the stop
- * @param <T> the output property type
- * @return the {@link Stop}
- */
- public static <T> Stop<Float, T> stop(float in, Property<T> output) {
- return new Stop<>(in, output.value);
+ @Override
+ public String toString() {
+ return String.format("[%s, %s]", in, out);
}
-
- private final Stop<Float, T>[] stops;
- private Float base;
-
- Function(@NonNull @Size(min = 1) Stop<Float, T>[] stops) {
- this.stops = stops;
+ }
+
+ /**
+ * Zoom functions allow the appearance of a map feature to change with map’s zoom.
+ * Zoom functions can be used to create the illusion of depth and control data density.
+ * Each stop is an array with two elements, the first is a zoom and the second is a function output value.
+ *
+ * @param stops the stops that define the function
+ * @param <T> the property type
+ * @return the {@link Function}
+ */
+ @SafeVarargs
+ public static <T> Function<T> zoom(@NonNull @Size(min = 1) Stop<Float, T>... stops) {
+ return new Function<T>(stops);
+ }
+
+
+ /**
+ * Zoom functions allow the appearance of a map feature to change with map’s zoom.
+ * Zoom functions can be used to create the illusion of depth and control data density.
+ * Each stop is an array with two elements, the first is a zoom and the second is a function output value.
+ *
+ * @param stops the stops that define the function
+ * @param base the exponential base of the interpolation curve - Default 1
+ * @param <T> the property type
+ * @return the {@link Function}
+ */
+ @SafeVarargs
+ public static <T> Function<T> zoom(
+ @FloatRange(from = 0, to = 1, fromInclusive = false, toInclusive = false) float base,
+ @NonNull @Size(min = 1) Stop<Float, T>... stops) {
+ return new Function<T>(stops)
+ .withBase(base);
+ }
+
+ /**
+ * Creates a stop to use in a {@link Function}
+ *
+ * @param in the input for the stop
+ * @param output the output for the stop
+ * @param <T> the output property type
+ * @return the {@link Stop}
+ */
+ public static <T> Stop<Float, T> stop(float in, Property<T> output) {
+ return new Stop<>(in, output.value);
+ }
+
+ private final Stop<Float, T>[] stops;
+ private Float base;
+
+ Function(@NonNull @Size(min = 1) Stop<Float, T>[] stops) {
+ this.stops = stops;
+ }
+
+ Function<T> withBase(float base) {
+ this.base = base;
+ return this;
+ }
+
+ /**
+ * @return the base
+ */
+ @Nullable
+ public Float getBase() {
+ return base;
+ }
+
+ /**
+ * @return the stops in this function
+ */
+ public Stop<Float, T>[] getStops() {
+ return stops;
+ }
+
+ Map<String, Object> toValueObject() {
+ Object[] stopsValue = new Object[stops.length];
+
+ for (int i = 0; i < stopsValue.length; i++) {
+ Stop stop = stops[i];
+ stopsValue[i] = stop.toValueObject();
}
- Function<T> withBase(float base) {
- this.base = base;
- return this;
- }
-
- /**
- * @return the base
- */
- @Nullable
- public Float getBase() {
- return base;
- }
-
- /**
- * @return the stops in this function
- */
- public Stop<Float, T>[] getStops() {
- return stops;
- }
-
- Map<String, Object> toValueObject() {
- Object[] stopsValue = new Object[stops.length];
-
- for (int i = 0; i < stopsValue.length; i++) {
- Stop stop = stops[i];
- stopsValue[i] = stop.toValueObject();
- }
-
- Map<String, Object> value = new HashMap<>();
- if (base != null) {
- value.put("base", base);
- }
- value.put("stops", stopsValue);
- return value;
+ Map<String, Object> value = new HashMap<>();
+ if (base != null) {
+ value.put("base", base);
}
+ value.put("stops", stopsValue);
+ return value;
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Layer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Layer.java
index 54d18962ce..2878d76430 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Layer.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Layer.java
@@ -7,101 +7,83 @@ import android.support.annotation.NonNull;
*/
public abstract class Layer {
- private long nativePtr;
- private boolean invalidated;
+ private long nativePtr;
+ private boolean invalidated;
- public Layer(long nativePtr) {
- this.nativePtr = nativePtr;
- }
-
- public Layer() {
- }
+ public Layer(long nativePtr) {
+ this.nativePtr = nativePtr;
+ }
- public void setProperties(@NonNull Property<?>... properties) {
- checkValidity();
-
- if (properties.length == 0) {
- return;
- }
-
- for (Property<?> property : properties) {
- Object converted = convertValue(property.value);
- if (property instanceof PaintProperty) {
- nativeSetPaintProperty(property.name, converted);
- } else {
- nativeSetLayoutProperty(property.name, converted);
- }
- }
- }
+ public Layer() {
+ }
- public String getId() {
- checkValidity();
- return nativeGetId();
+ public void setProperties(@NonNull Property<?>... properties) {
+ if (properties.length == 0) {
+ return;
}
- public PropertyValue<String> getVisibility() {
- checkValidity();
- return new PropertyValue<>(nativeGetVisibility());
+ for (Property<?> property : properties) {
+ Object converted = convertValue(property.value);
+ if (property instanceof PaintProperty) {
+ nativeSetPaintProperty(property.name, converted);
+ } else {
+ nativeSetLayoutProperty(property.name, converted);
+ }
}
+ }
- public float getMinZoom() {
- checkValidity();
- return nativeGetMinZoom();
- }
+ public String getId() {
+ return nativeGetId();
+ }
- public float getMaxZoom() {
- checkValidity();
- return nativeGetMaxZoom();
- }
+ public PropertyValue<String> getVisibility() {
+ return new PropertyValue<>(nativeGetVisibility());
+ }
- public void setMinZoom(float zoom) {
- checkValidity();
- nativeSetMinZoom(zoom);
- }
+ public float getMinZoom() {
+ return nativeGetMinZoom();
+ }
- public void setMaxZoom(float zoom) {
- checkValidity();
- nativeSetMaxZoom(zoom);
- }
+ public float getMaxZoom() {
+ return nativeGetMaxZoom();
+ }
- @Override
- protected native void finalize() throws Throwable;
+ public void setMinZoom(float zoom) {
+ nativeSetMinZoom(zoom);
+ }
- protected native String nativeGetId();
+ public void setMaxZoom(float zoom) {
+ nativeSetMaxZoom(zoom);
+ }
- protected native Object nativeGetVisibility();
+ @Override
+ protected native void finalize() throws Throwable;
- protected native void nativeSetLayoutProperty(String name, Object value);
+ protected native String nativeGetId();
- protected native void nativeSetPaintProperty(String name, Object value);
+ protected native Object nativeGetVisibility();
- protected native void nativeSetFilter(Object[] filter);
+ protected native void nativeSetLayoutProperty(String name, Object value);
- protected native void nativeSetSourceLayer(String sourceLayer);
+ protected native void nativeSetPaintProperty(String name, Object value);
- protected native float nativeGetMinZoom();
+ protected native void nativeSetFilter(Object[] filter);
- protected native float nativeGetMaxZoom();
+ protected native void nativeSetSourceLayer(String sourceLayer);
- protected native void nativeSetMinZoom(float zoom);
+ protected native float nativeGetMinZoom();
- protected native void nativeSetMaxZoom(float zoom);
+ protected native float nativeGetMaxZoom();
- public long getNativePtr() {
- return nativePtr;
- }
+ protected native void nativeSetMinZoom(float zoom);
- private Object convertValue(Object value) {
- return value != null && value instanceof Function ? ((Function) value).toValueObject() : value;
- }
+ protected native void nativeSetMaxZoom(float zoom);
- protected void checkValidity() {
- if (invalidated) {
- throw new RuntimeException("Layer has been invalidated. Request a new reference after adding");
- }
- }
+ public long getNativePtr() {
+ return nativePtr;
+ }
- public final void invalidate() {
- this.invalidated = true;
- }
+ private Object convertValue(Object value) {
+ return value != null && value instanceof Function ? ((Function) value).toValueObject() : value;
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/LayoutProperty.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/LayoutProperty.java
index 553554270e..4c0b52be55 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/LayoutProperty.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/LayoutProperty.java
@@ -2,8 +2,8 @@ package com.mapbox.mapboxsdk.style.layers;
class LayoutProperty<T> extends Property<T> {
- LayoutProperty(String name, T value) {
- super(name, value);
- }
+ LayoutProperty(String name, T value) {
+ super(name, value);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/LineLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/LineLayer.java
index 896558a011..4c52a40b05 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/LineLayer.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/LineLayer.java
@@ -1,318 +1,302 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
package com.mapbox.mapboxsdk.style.layers;
-
-import com.mapbox.mapboxsdk.exceptions.ConversionException;
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
+import android.support.annotation.UiThread;
-import static com.mapbox.mapboxsdk.utils.ColorUtils.*;
+import static com.mapbox.mapboxsdk.utils.ColorUtils.rgbaToColor;
/**
* A stroked line.
*
* @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#layers-line">The online documentation</a>
*/
+@UiThread
public class LineLayer extends Layer {
- /**
- * Creates a LineLayer.
- *
- * @param nativePtr pointer used by core
- */
- public LineLayer(long nativePtr) {
- super(nativePtr);
- }
-
- /**
- * Creates a LineLayer.
- *
- * @param layerId the id of the layer
- * @param sourceId the id of the source
- */
- public LineLayer(String layerId, String sourceId) {
- initialize(layerId, sourceId);
- }
-
- protected native void initialize(String layerId, String sourceId);
-
- /**
- * Set the source layer.
- *
- * @param sourceLayer the source layer to set
- */
- public void setSourceLayer(String sourceLayer) {
- checkValidity();
- nativeSetSourceLayer(sourceLayer);
- }
-
- /**
- * Set the source Layer.
- *
- * @param sourceLayer the source layer to set
- * @return This
- */
- public LineLayer withSourceLayer(String sourceLayer) {
- setSourceLayer(sourceLayer);
- return this;
- }
- /**
- * Set a single filter.
- *
- * @param filter the filter to set
- */
- public void setFilter(Filter.Statement filter) {
- checkValidity();
- this.setFilter(filter.toArray());
- }
-
- /**
- * Set an array of filters.
- *
- * @param filter the filter array to set
- */
- public void setFilter(Object[] filter) {
- checkValidity();
- nativeSetFilter(filter);
- }
-
- /**
- * Set an array of filters.
- *
- * @param filter tthe filter array to set
- * @return This
- */
- public LineLayer withFilter(Object[] filter) {
- setFilter(filter);
- return this;
- }
-
- /**
- * Set a single filter.
- *
- * @param filter the filter to set
- * @return This
- */
- public LineLayer withFilter(Filter.Statement filter) {
- setFilter(filter);
- return this;
- }
-
-
- /**
- * Set a property or properties.
- *
- * @param properties the var-args properties
- * @return This
- */
- public LineLayer withProperties(@NonNull Property<?>... properties) {
- setProperties(properties);
- return this;
- }
-
- // Property getters
-
- /**
- * Get the LineCap property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getLineCap() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetLineCap());
- }
-
- /**
- * Get the LineJoin property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getLineJoin() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetLineJoin());
- }
-
- /**
- * Get the LineMiterLimit property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getLineMiterLimit() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetLineMiterLimit());
- }
-
- /**
- * Get the LineRoundLimit property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getLineRoundLimit() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetLineRoundLimit());
- }
-
- /**
- * Get the LineOpacity property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getLineOpacity() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetLineOpacity());
- }
-
- /**
- * Get the LineColor property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getLineColor() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetLineColor());
- }
- /**
- * The color with which the line will be drawn.
- *
- * @return int representation of a rgba string color
- * @throws RuntimeException thrown if property isn't a value
- */
- @ColorInt
- public int getLineColorAsInt() {
- checkValidity();
- PropertyValue<String> value = getLineColor();
- if (value.isValue()) {
- return rgbaToColor(value.getValue());
- } else {
- throw new RuntimeException("line-color was set as a Function");
- }
- }
-
-
- /**
- * Get the LineTranslate property
- *
- * @return property wrapper value around Float[]
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float[]> getLineTranslate() {
- checkValidity();
- return (PropertyValue<Float[]>) new PropertyValue(nativeGetLineTranslate());
- }
-
- /**
- * Get the LineTranslateAnchor property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getLineTranslateAnchor() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetLineTranslateAnchor());
- }
-
- /**
- * Get the LineWidth property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getLineWidth() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetLineWidth());
- }
-
- /**
- * Get the LineGapWidth property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getLineGapWidth() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetLineGapWidth());
- }
-
- /**
- * Get the LineOffset property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getLineOffset() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetLineOffset());
+ /**
+ * Creates a LineLayer.
+ *
+ * @param nativePtr pointer used by core
+ */
+ public LineLayer(long nativePtr) {
+ super(nativePtr);
+ }
+
+ /**
+ * Creates a LineLayer.
+ *
+ * @param layerId the id of the layer
+ * @param sourceId the id of the source
+ */
+ public LineLayer(String layerId, String sourceId) {
+ initialize(layerId, sourceId);
+ }
+
+ protected native void initialize(String layerId, String sourceId);
+
+ /**
+ * Set the source layer.
+ *
+ * @param sourceLayer the source layer to set
+ */
+ public void setSourceLayer(String sourceLayer) {
+ nativeSetSourceLayer(sourceLayer);
+ }
+
+ /**
+ * Set the source Layer.
+ *
+ * @param sourceLayer the source layer to set
+ * @return This
+ */
+ public LineLayer withSourceLayer(String sourceLayer) {
+ setSourceLayer(sourceLayer);
+ return this;
+ }
+
+ /**
+ * Set a single filter.
+ *
+ * @param filter the filter to set
+ */
+ public void setFilter(Filter.Statement filter) {
+ this.setFilter(filter.toArray());
+ }
+
+ /**
+ * Set an array of filters.
+ *
+ * @param filter the filter array to set
+ */
+ public void setFilter(Object[] filter) {
+ nativeSetFilter(filter);
+ }
+
+ /**
+ * Set an array of filters.
+ *
+ * @param filter tthe filter array to set
+ * @return This
+ */
+ public LineLayer withFilter(Object[] filter) {
+ setFilter(filter);
+ return this;
+ }
+
+ /**
+ * Set a single filter.
+ *
+ * @param filter the filter to set
+ * @return This
+ */
+ public LineLayer withFilter(Filter.Statement filter) {
+ setFilter(filter);
+ return this;
+ }
+
+
+ /**
+ * Set a property or properties.
+ *
+ * @param properties the var-args properties
+ * @return This
+ */
+ public LineLayer withProperties(@NonNull Property<?>... properties) {
+ setProperties(properties);
+ return this;
+ }
+
+ // Property getters
+
+ /**
+ * Get the LineCap property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getLineCap() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetLineCap());
+ }
+
+ /**
+ * Get the LineJoin property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getLineJoin() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetLineJoin());
+ }
+
+ /**
+ * Get the LineMiterLimit property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getLineMiterLimit() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetLineMiterLimit());
+ }
+
+ /**
+ * Get the LineRoundLimit property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getLineRoundLimit() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetLineRoundLimit());
+ }
+
+ /**
+ * Get the LineOpacity property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getLineOpacity() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetLineOpacity());
+ }
+
+ /**
+ * Get the LineColor property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getLineColor() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetLineColor());
+ }
+
+ /**
+ * The color with which the line will be drawn.
+ *
+ * @return int representation of a rgba string color
+ * @throws RuntimeException thrown if property isn't a value
+ */
+ @ColorInt
+ public int getLineColorAsInt() {
+ PropertyValue<String> value = getLineColor();
+ if (value.isValue()) {
+ return rgbaToColor(value.getValue());
+ } else {
+ throw new RuntimeException("line-color was set as a Function");
}
-
- /**
- * Get the LineBlur property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getLineBlur() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetLineBlur());
- }
-
- /**
- * Get the LineDasharray property
- *
- * @return property wrapper value around Float[]
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float[]> getLineDasharray() {
- checkValidity();
- return (PropertyValue<Float[]>) new PropertyValue(nativeGetLineDasharray());
- }
-
- /**
- * Get the LinePattern property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getLinePattern() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetLinePattern());
- }
-
- private native Object nativeGetLineCap();
-
- private native Object nativeGetLineJoin();
-
- private native Object nativeGetLineMiterLimit();
-
- private native Object nativeGetLineRoundLimit();
-
- private native Object nativeGetLineOpacity();
-
- private native Object nativeGetLineColor();
-
- private native Object nativeGetLineTranslate();
-
- private native Object nativeGetLineTranslateAnchor();
-
- private native Object nativeGetLineWidth();
-
- private native Object nativeGetLineGapWidth();
-
- private native Object nativeGetLineOffset();
-
- private native Object nativeGetLineBlur();
-
- private native Object nativeGetLineDasharray();
-
- private native Object nativeGetLinePattern();
-
-
- @Override
- protected native void finalize() throws Throwable;
+ }
+
+
+ /**
+ * Get the LineTranslate property
+ *
+ * @return property wrapper value around Float[]
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float[]> getLineTranslate() {
+ return (PropertyValue<Float[]>) new PropertyValue(nativeGetLineTranslate());
+ }
+
+ /**
+ * Get the LineTranslateAnchor property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getLineTranslateAnchor() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetLineTranslateAnchor());
+ }
+
+ /**
+ * Get the LineWidth property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getLineWidth() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetLineWidth());
+ }
+
+ /**
+ * Get the LineGapWidth property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getLineGapWidth() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetLineGapWidth());
+ }
+
+ /**
+ * Get the LineOffset property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getLineOffset() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetLineOffset());
+ }
+
+ /**
+ * Get the LineBlur property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getLineBlur() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetLineBlur());
+ }
+
+ /**
+ * Get the LineDasharray property
+ *
+ * @return property wrapper value around Float[]
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float[]> getLineDasharray() {
+ return (PropertyValue<Float[]>) new PropertyValue(nativeGetLineDasharray());
+ }
+
+ /**
+ * Get the LinePattern property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getLinePattern() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetLinePattern());
+ }
+
+ private native Object nativeGetLineCap();
+
+ private native Object nativeGetLineJoin();
+
+ private native Object nativeGetLineMiterLimit();
+
+ private native Object nativeGetLineRoundLimit();
+
+ private native Object nativeGetLineOpacity();
+
+ private native Object nativeGetLineColor();
+
+ private native Object nativeGetLineTranslate();
+
+ private native Object nativeGetLineTranslateAnchor();
+
+ private native Object nativeGetLineWidth();
+
+ private native Object nativeGetLineGapWidth();
+
+ private native Object nativeGetLineOffset();
+
+ private native Object nativeGetLineBlur();
+
+ private native Object nativeGetLineDasharray();
+
+ private native Object nativeGetLinePattern();
+
+
+ @Override
+ protected native void finalize() throws Throwable;
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/NoSuchLayerException.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/NoSuchLayerException.java
index d6ef4f8824..3b8777080d 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/NoSuchLayerException.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/NoSuchLayerException.java
@@ -5,7 +5,7 @@ package com.mapbox.mapboxsdk.style.layers;
*/
public class NoSuchLayerException extends Exception {
- public NoSuchLayerException(String message) {
- super(message);
- }
+ public NoSuchLayerException(String message) {
+ super(message);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PaintProperty.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PaintProperty.java
index 6f1a9a0a16..69405177d9 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PaintProperty.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PaintProperty.java
@@ -2,8 +2,8 @@ package com.mapbox.mapboxsdk.style.layers;
class PaintProperty<T> extends Property<T> {
- PaintProperty(String name, T value) {
- super(name, value);
- }
+ PaintProperty(String name, T value) {
+ super(name, value);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Property.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Property.java
index 383d4217a8..bb060ddf15 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Property.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Property.java
@@ -1,5 +1,5 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
package com.mapbox.mapboxsdk.style.layers;
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
import android.support.annotation.StringDef;
@@ -11,448 +11,477 @@ import java.lang.annotation.RetentionPolicy;
*/
public abstract class Property<T> {
- //VISIBILITY: Whether this layer is displayed.
-
- /**
- * The layer is shown.
- */
- public static final String VISIBLE = "visible";
- /**
- * The layer is hidden.
- */
- public static final String NONE = "none";
-
- @StringDef({
- VISIBLE,
- NONE
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface VISIBILITY {}
-
- //LINE_CAP: The display of line endings.
-
- /**
- * A cap with a squared-off end which is drawn to the exact endpoint of the line.
- */
- public static final String LINE_CAP_BUTT = "butt";
- /**
- * 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.
- */
- public static final String LINE_CAP_ROUND = "round";
- /**
- * 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.
- */
- public static final String LINE_CAP_SQUARE = "square";
-
- /**
- * The display of line endings.
- */
- @StringDef({
- LINE_CAP_BUTT,
- LINE_CAP_ROUND,
- LINE_CAP_SQUARE,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface LINE_CAP {}
-
- //LINE_JOIN: The display of lines when joining.
-
- /**
- * 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.
- */
- public static final String LINE_JOIN_BEVEL = "bevel";
- /**
- * 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.
- */
- public static final String LINE_JOIN_ROUND = "round";
- /**
- * A join with a sharp, angled corner which is drawn with the outer sides beyond the endpoint of the path until they meet.
- */
- public static final String LINE_JOIN_MITER = "miter";
-
- /**
- * The display of lines when joining.
- */
- @StringDef({
- LINE_JOIN_BEVEL,
- LINE_JOIN_ROUND,
- LINE_JOIN_MITER,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface LINE_JOIN {}
-
- //SYMBOL_PLACEMENT: Label placement relative to its geometry.
-
- /**
- * The label is placed at the point where the geometry is located.
- */
- public static final String SYMBOL_PLACEMENT_POINT = "point";
- /**
- * The label is placed along the line of the geometry. Can only be used on LineString and Polygon geometries.
- */
- public static final String SYMBOL_PLACEMENT_LINE = "line";
-
- /**
- * Label placement relative to its geometry.
- */
- @StringDef({
- SYMBOL_PLACEMENT_POINT,
- SYMBOL_PLACEMENT_LINE,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface SYMBOL_PLACEMENT {}
-
- //ICON_ROTATION_ALIGNMENT: In combination with `symbol-placement`, determines the rotation behavior of icons.
-
- /**
- * When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_POINT}, aligns icons east-west. When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_LINE}, aligns icon x-axes with the line.
- */
- public static final String ICON_ROTATION_ALIGNMENT_MAP = "map";
- /**
- * Produces icons whose x-axes are aligned with the x-axis of the viewport, regardless of the value of {@link SYMBOL_PLACEMENT}.
- */
- public static final String ICON_ROTATION_ALIGNMENT_VIEWPORT = "viewport";
- /**
- * When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_POINT}, this is equivalent to {@link Property#ICON_ROTATION_ALIGNMENT_VIEWPORT}. When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_LINE}, this is equivalent to {@link Property#ICON_ROTATION_ALIGNMENT_MAP}.
- */
- public static final String ICON_ROTATION_ALIGNMENT_AUTO = "auto";
-
- /**
- * In combination with `symbol-placement`, determines the rotation behavior of icons.
- */
- @StringDef({
- ICON_ROTATION_ALIGNMENT_MAP,
- ICON_ROTATION_ALIGNMENT_VIEWPORT,
- ICON_ROTATION_ALIGNMENT_AUTO,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface ICON_ROTATION_ALIGNMENT {}
-
- //ICON_TEXT_FIT: Scales the icon to fit around the associated text.
-
- /**
- * The icon is displayed at its intrinsic aspect ratio.
- */
- public static final String ICON_TEXT_FIT_NONE = "none";
- /**
- * The icon is scaled in the x-dimension to fit the width of the text.
- */
- public static final String ICON_TEXT_FIT_WIDTH = "width";
- /**
- * The icon is scaled in the y-dimension to fit the height of the text.
- */
- public static final String ICON_TEXT_FIT_HEIGHT = "height";
- /**
- * The icon is scaled in both x- and y-dimensions.
- */
- public static final String ICON_TEXT_FIT_BOTH = "both";
-
- /**
- * Scales the icon to fit around the associated text.
- */
- @StringDef({
- ICON_TEXT_FIT_NONE,
- ICON_TEXT_FIT_WIDTH,
- ICON_TEXT_FIT_HEIGHT,
- ICON_TEXT_FIT_BOTH,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface ICON_TEXT_FIT {}
-
- //TEXT_PITCH_ALIGNMENT: Orientation of text when map is pitched.
-
- /**
- * The text is aligned to the plane of the map.
- */
- public static final String TEXT_PITCH_ALIGNMENT_MAP = "map";
- /**
- * The text is aligned to the plane of the viewport.
- */
- public static final String TEXT_PITCH_ALIGNMENT_VIEWPORT = "viewport";
- /**
- * Automatically matches the value of {@link TEXT_ROTATION_ALIGNMENT}.
- */
- public static final String TEXT_PITCH_ALIGNMENT_AUTO = "auto";
-
- /**
- * Orientation of text when map is pitched.
- */
- @StringDef({
- TEXT_PITCH_ALIGNMENT_MAP,
- TEXT_PITCH_ALIGNMENT_VIEWPORT,
- TEXT_PITCH_ALIGNMENT_AUTO,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface TEXT_PITCH_ALIGNMENT {}
-
- //TEXT_ROTATION_ALIGNMENT: In combination with `symbol-placement`, determines the rotation behavior of the individual glyphs forming the text.
-
- /**
- * When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_POINT}, aligns text east-west. When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_LINE}, aligns text x-axes with the line.
- */
- public static final String TEXT_ROTATION_ALIGNMENT_MAP = "map";
- /**
- * Produces glyphs whose x-axes are aligned with the x-axis of the viewport, regardless of the value of {@link SYMBOL_PLACEMENT}.
- */
- public static final String TEXT_ROTATION_ALIGNMENT_VIEWPORT = "viewport";
- /**
- * When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_POINT}, this is equivalent to {@link Property#TEXT_ROTATION_ALIGNMENT_VIEWPORT}. When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_LINE}, this is equivalent to {@link Property#TEXT_ROTATION_ALIGNMENT_MAP}.
- */
- public static final String TEXT_ROTATION_ALIGNMENT_AUTO = "auto";
-
- /**
- * In combination with `symbol-placement`, determines the rotation behavior of the individual glyphs forming the text.
- */
- @StringDef({
- TEXT_ROTATION_ALIGNMENT_MAP,
- TEXT_ROTATION_ALIGNMENT_VIEWPORT,
- TEXT_ROTATION_ALIGNMENT_AUTO,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface TEXT_ROTATION_ALIGNMENT {}
-
- //TEXT_JUSTIFY: Text justification options.
-
- /**
- * The text is aligned to the left.
- */
- public static final String TEXT_JUSTIFY_LEFT = "left";
- /**
- * The text is centered.
- */
- public static final String TEXT_JUSTIFY_CENTER = "center";
- /**
- * The text is aligned to the right.
- */
- public static final String TEXT_JUSTIFY_RIGHT = "right";
-
- /**
- * Text justification options.
- */
- @StringDef({
- TEXT_JUSTIFY_LEFT,
- TEXT_JUSTIFY_CENTER,
- TEXT_JUSTIFY_RIGHT,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface TEXT_JUSTIFY {}
-
- //TEXT_ANCHOR: Part of the text placed closest to the anchor.
-
- /**
- * The center of the text is placed closest to the anchor.
- */
- public static final String TEXT_ANCHOR_CENTER = "center";
- /**
- * The left side of the text is placed closest to the anchor.
- */
- public static final String TEXT_ANCHOR_LEFT = "left";
- /**
- * The right side of the text is placed closest to the anchor.
- */
- public static final String TEXT_ANCHOR_RIGHT = "right";
- /**
- * The top of the text is placed closest to the anchor.
- */
- public static final String TEXT_ANCHOR_TOP = "top";
- /**
- * The bottom of the text is placed closest to the anchor.
- */
- public static final String TEXT_ANCHOR_BOTTOM = "bottom";
- /**
- * The top left corner of the text is placed closest to the anchor.
- */
- public static final String TEXT_ANCHOR_TOP_LEFT = "top-left";
- /**
- * The top right corner of the text is placed closest to the anchor.
- */
- public static final String TEXT_ANCHOR_TOP_RIGHT = "top-right";
- /**
- * The bottom left corner of the text is placed closest to the anchor.
- */
- public static final String TEXT_ANCHOR_BOTTOM_LEFT = "bottom-left";
- /**
- * The bottom right corner of the text is placed closest to the anchor.
- */
- public static final String TEXT_ANCHOR_BOTTOM_RIGHT = "bottom-right";
-
- /**
- * Part of the text placed closest to the anchor.
- */
- @StringDef({
- TEXT_ANCHOR_CENTER,
- TEXT_ANCHOR_LEFT,
- TEXT_ANCHOR_RIGHT,
- TEXT_ANCHOR_TOP,
- TEXT_ANCHOR_BOTTOM,
- TEXT_ANCHOR_TOP_LEFT,
- TEXT_ANCHOR_TOP_RIGHT,
- TEXT_ANCHOR_BOTTOM_LEFT,
- TEXT_ANCHOR_BOTTOM_RIGHT,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface TEXT_ANCHOR {}
-
- //TEXT_TRANSFORM: Specifies how to capitalize text, similar to the CSS `text-transform` property.
-
- /**
- * The text is not altered.
- */
- public static final String TEXT_TRANSFORM_NONE = "none";
- /**
- * Forces all letters to be displayed in uppercase.
- */
- public static final String TEXT_TRANSFORM_UPPERCASE = "uppercase";
- /**
- * Forces all letters to be displayed in lowercase.
- */
- public static final String TEXT_TRANSFORM_LOWERCASE = "lowercase";
-
- /**
- * Specifies how to capitalize text, similar to the CSS `text-transform` property.
- */
- @StringDef({
- TEXT_TRANSFORM_NONE,
- TEXT_TRANSFORM_UPPERCASE,
- TEXT_TRANSFORM_LOWERCASE,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface TEXT_TRANSFORM {}
-
- //FILL_TRANSLATE_ANCHOR: Controls the translation reference point.
-
- /**
- * The fill is translated relative to the map.
- */
- public static final String FILL_TRANSLATE_ANCHOR_MAP = "map";
- /**
- * The fill is translated relative to the viewport.
- */
- public static final String FILL_TRANSLATE_ANCHOR_VIEWPORT = "viewport";
-
- /**
- * Controls the translation reference point.
- */
- @StringDef({
- FILL_TRANSLATE_ANCHOR_MAP,
- FILL_TRANSLATE_ANCHOR_VIEWPORT,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface FILL_TRANSLATE_ANCHOR {}
-
- //LINE_TRANSLATE_ANCHOR: Controls the translation reference point.
-
- /**
- * The line is translated relative to the map.
- */
- public static final String LINE_TRANSLATE_ANCHOR_MAP = "map";
- /**
- * The line is translated relative to the viewport.
- */
- public static final String LINE_TRANSLATE_ANCHOR_VIEWPORT = "viewport";
-
- /**
- * Controls the translation reference point.
- */
- @StringDef({
- LINE_TRANSLATE_ANCHOR_MAP,
- LINE_TRANSLATE_ANCHOR_VIEWPORT,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface LINE_TRANSLATE_ANCHOR {}
-
- //ICON_TRANSLATE_ANCHOR: Controls the translation reference point.
-
- /**
- * Icons are translated relative to the map.
- */
- public static final String ICON_TRANSLATE_ANCHOR_MAP = "map";
- /**
- * Icons are translated relative to the viewport.
- */
- public static final String ICON_TRANSLATE_ANCHOR_VIEWPORT = "viewport";
-
- /**
- * Controls the translation reference point.
- */
- @StringDef({
- ICON_TRANSLATE_ANCHOR_MAP,
- ICON_TRANSLATE_ANCHOR_VIEWPORT,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface ICON_TRANSLATE_ANCHOR {}
-
- //TEXT_TRANSLATE_ANCHOR: Controls the translation reference point.
-
- /**
- * The text is translated relative to the map.
- */
- public static final String TEXT_TRANSLATE_ANCHOR_MAP = "map";
- /**
- * The text is translated relative to the viewport.
- */
- public static final String TEXT_TRANSLATE_ANCHOR_VIEWPORT = "viewport";
-
- /**
- * Controls the translation reference point.
- */
- @StringDef({
- TEXT_TRANSLATE_ANCHOR_MAP,
- TEXT_TRANSLATE_ANCHOR_VIEWPORT,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface TEXT_TRANSLATE_ANCHOR {}
-
- //CIRCLE_TRANSLATE_ANCHOR: Controls the translation reference point.
-
- /**
- * The circle is translated relative to the map.
- */
- public static final String CIRCLE_TRANSLATE_ANCHOR_MAP = "map";
- /**
- * The circle is translated relative to the viewport.
- */
- public static final String CIRCLE_TRANSLATE_ANCHOR_VIEWPORT = "viewport";
-
- /**
- * Controls the translation reference point.
- */
- @StringDef({
- CIRCLE_TRANSLATE_ANCHOR_MAP,
- CIRCLE_TRANSLATE_ANCHOR_VIEWPORT,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface CIRCLE_TRANSLATE_ANCHOR {}
-
- //CIRCLE_PITCH_SCALE: Controls the scaling behavior of the circle when the map is pitched.
-
- /**
- * Circles are scaled according to their apparent distance to the camera.
- */
- public static final String CIRCLE_PITCH_SCALE_MAP = "map";
- /**
- * Circles are not scaled.
- */
- public static final String CIRCLE_PITCH_SCALE_VIEWPORT = "viewport";
-
- /**
- * Controls the scaling behavior of the circle when the map is pitched.
- */
- @StringDef({
- CIRCLE_PITCH_SCALE_MAP,
- CIRCLE_PITCH_SCALE_VIEWPORT,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface CIRCLE_PITCH_SCALE {}
-
-
- //Class definition
- public final String name;
- public final T value;
-
- /* package */ Property(String name, T value) {
- this.name = name;
- this.value = value;
- }
-
+ //VISIBILITY: Whether this layer is displayed.
+
+ /**
+ * The layer is shown.
+ */
+ public static final String VISIBLE = "visible";
+ /**
+ * The layer is hidden.
+ */
+ public static final String NONE = "none";
+
+ @StringDef( {
+ VISIBLE,
+ NONE
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface VISIBILITY {
+ }
+
+ //LINE_CAP: The display of line endings.
+
+ /**
+ * A cap with a squared-off end which is drawn to the exact endpoint of the line.
+ */
+ public static final String LINE_CAP_BUTT = "butt";
+ /**
+ * 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.
+ */
+ public static final String LINE_CAP_ROUND = "round";
+ /**
+ * 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.
+ */
+ public static final String LINE_CAP_SQUARE = "square";
+
+ /**
+ * The display of line endings.
+ */
+ @StringDef( {
+ LINE_CAP_BUTT,
+ LINE_CAP_ROUND,
+ LINE_CAP_SQUARE,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface LINE_CAP {
+ }
+
+ //LINE_JOIN: The display of lines when joining.
+
+ /**
+ * 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.
+ */
+ public static final String LINE_JOIN_BEVEL = "bevel";
+ /**
+ * 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.
+ */
+ public static final String LINE_JOIN_ROUND = "round";
+ /**
+ * A join with a sharp, angled corner which is drawn with the outer sides beyond the endpoint of the path until
+ * they meet.
+ */
+ public static final String LINE_JOIN_MITER = "miter";
+
+ /**
+ * The display of lines when joining.
+ */
+ @StringDef( {
+ LINE_JOIN_BEVEL,
+ LINE_JOIN_ROUND,
+ LINE_JOIN_MITER,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface LINE_JOIN {
+ }
+
+ //SYMBOL_PLACEMENT: Label placement relative to its geometry.
+
+ /**
+ * The label is placed at the point where the geometry is located.
+ */
+ public static final String SYMBOL_PLACEMENT_POINT = "point";
+ /**
+ * The label is placed along the line of the geometry. Can only be used on LineString and Polygon geometries.
+ */
+ public static final String SYMBOL_PLACEMENT_LINE = "line";
+
+ /**
+ * Label placement relative to its geometry.
+ */
+ @StringDef( {
+ SYMBOL_PLACEMENT_POINT,
+ SYMBOL_PLACEMENT_LINE,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface SYMBOL_PLACEMENT {
+ }
+
+ //ICON_ROTATION_ALIGNMENT: In combination with `symbol-placement`, determines the rotation behavior of icons.
+
+ /**
+ * When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_POINT}, aligns icons east-west. When
+ * {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_LINE}, aligns icon x-axes with the line.
+ */
+ public static final String ICON_ROTATION_ALIGNMENT_MAP = "map";
+ /**
+ * Produces icons whose x-axes are aligned with the x-axis of the viewport, regardless of the value of
+ * {@link SYMBOL_PLACEMENT}.
+ */
+ public static final String ICON_ROTATION_ALIGNMENT_VIEWPORT = "viewport";
+ /**
+ * When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_POINT}, this is equivalent to
+ * {@link Property#ICON_ROTATION_ALIGNMENT_VIEWPORT}. When {@link SYMBOL_PLACEMENT} is set to
+ * {@link Property#SYMBOL_PLACEMENT_LINE}, this is equivalent to {@link Property#ICON_ROTATION_ALIGNMENT_MAP}.
+ */
+ public static final String ICON_ROTATION_ALIGNMENT_AUTO = "auto";
+
+ /**
+ * In combination with `symbol-placement`, determines the rotation behavior of icons.
+ */
+ @StringDef( {
+ ICON_ROTATION_ALIGNMENT_MAP,
+ ICON_ROTATION_ALIGNMENT_VIEWPORT,
+ ICON_ROTATION_ALIGNMENT_AUTO,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ICON_ROTATION_ALIGNMENT {
+ }
+
+ //ICON_TEXT_FIT: Scales the icon to fit around the associated text.
+
+ /**
+ * The icon is displayed at its intrinsic aspect ratio.
+ */
+ public static final String ICON_TEXT_FIT_NONE = "none";
+ /**
+ * The icon is scaled in the x-dimension to fit the width of the text.
+ */
+ public static final String ICON_TEXT_FIT_WIDTH = "width";
+ /**
+ * The icon is scaled in the y-dimension to fit the height of the text.
+ */
+ public static final String ICON_TEXT_FIT_HEIGHT = "height";
+ /**
+ * The icon is scaled in both x- and y-dimensions.
+ */
+ public static final String ICON_TEXT_FIT_BOTH = "both";
+
+ /**
+ * Scales the icon to fit around the associated text.
+ */
+ @StringDef( {
+ ICON_TEXT_FIT_NONE,
+ ICON_TEXT_FIT_WIDTH,
+ ICON_TEXT_FIT_HEIGHT,
+ ICON_TEXT_FIT_BOTH,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ICON_TEXT_FIT {
+ }
+
+ //TEXT_PITCH_ALIGNMENT: Orientation of text when map is pitched.
+
+ /**
+ * The text is aligned to the plane of the map.
+ */
+ public static final String TEXT_PITCH_ALIGNMENT_MAP = "map";
+ /**
+ * The text is aligned to the plane of the viewport.
+ */
+ public static final String TEXT_PITCH_ALIGNMENT_VIEWPORT = "viewport";
+ /**
+ * Automatically matches the value of {@link TEXT_ROTATION_ALIGNMENT}.
+ */
+ public static final String TEXT_PITCH_ALIGNMENT_AUTO = "auto";
+
+ /**
+ * Orientation of text when map is pitched.
+ */
+ @StringDef( {
+ TEXT_PITCH_ALIGNMENT_MAP,
+ TEXT_PITCH_ALIGNMENT_VIEWPORT,
+ TEXT_PITCH_ALIGNMENT_AUTO,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface TEXT_PITCH_ALIGNMENT {
+ }
+
+ //TEXT_ROTATION_ALIGNMENT: In combination with `symbol-placement`, determines the rotation behavior of the individual
+ // glyphs forming the text.
+
+ /**
+ * When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_POINT}, aligns text east-west. When
+ * {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_LINE}, aligns text x-axes with the line.
+ */
+ public static final String TEXT_ROTATION_ALIGNMENT_MAP = "map";
+ /**
+ * Produces glyphs whose x-axes are aligned with the x-axis of the viewport, regardless of the value of
+ * {@link SYMBOL_PLACEMENT}.
+ */
+ public static final String TEXT_ROTATION_ALIGNMENT_VIEWPORT = "viewport";
+ /**
+ * When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_POINT}, this is equivalent to
+ * {@link Property#TEXT_ROTATION_ALIGNMENT_VIEWPORT}. When {@link SYMBOL_PLACEMENT} is set to
+ * {@link Property#SYMBOL_PLACEMENT_LINE}, this is equivalent to {@link Property#TEXT_ROTATION_ALIGNMENT_MAP}.
+ */
+ public static final String TEXT_ROTATION_ALIGNMENT_AUTO = "auto";
+
+ /**
+ * In combination with `symbol-placement`, determines the rotation behavior of the individual glyphs forming the text.
+ */
+ @StringDef( {
+ TEXT_ROTATION_ALIGNMENT_MAP,
+ TEXT_ROTATION_ALIGNMENT_VIEWPORT,
+ TEXT_ROTATION_ALIGNMENT_AUTO,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface TEXT_ROTATION_ALIGNMENT {
+ }
+
+ //TEXT_JUSTIFY: Text justification options.
+
+ /**
+ * The text is aligned to the left.
+ */
+ public static final String TEXT_JUSTIFY_LEFT = "left";
+ /**
+ * The text is centered.
+ */
+ public static final String TEXT_JUSTIFY_CENTER = "center";
+ /**
+ * The text is aligned to the right.
+ */
+ public static final String TEXT_JUSTIFY_RIGHT = "right";
+
+ /**
+ * Text justification options.
+ */
+ @StringDef( {
+ TEXT_JUSTIFY_LEFT,
+ TEXT_JUSTIFY_CENTER,
+ TEXT_JUSTIFY_RIGHT,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface TEXT_JUSTIFY {
+ }
+
+ //TEXT_ANCHOR: Part of the text placed closest to the anchor.
+
+ /**
+ * The center of the text is placed closest to the anchor.
+ */
+ public static final String TEXT_ANCHOR_CENTER = "center";
+ /**
+ * The left side of the text is placed closest to the anchor.
+ */
+ public static final String TEXT_ANCHOR_LEFT = "left";
+ /**
+ * The right side of the text is placed closest to the anchor.
+ */
+ public static final String TEXT_ANCHOR_RIGHT = "right";
+ /**
+ * The top of the text is placed closest to the anchor.
+ */
+ public static final String TEXT_ANCHOR_TOP = "top";
+ /**
+ * The bottom of the text is placed closest to the anchor.
+ */
+ public static final String TEXT_ANCHOR_BOTTOM = "bottom";
+ /**
+ * The top left corner of the text is placed closest to the anchor.
+ */
+ public static final String TEXT_ANCHOR_TOP_LEFT = "top-left";
+ /**
+ * The top right corner of the text is placed closest to the anchor.
+ */
+ public static final String TEXT_ANCHOR_TOP_RIGHT = "top-right";
+ /**
+ * The bottom left corner of the text is placed closest to the anchor.
+ */
+ public static final String TEXT_ANCHOR_BOTTOM_LEFT = "bottom-left";
+ /**
+ * The bottom right corner of the text is placed closest to the anchor.
+ */
+ public static final String TEXT_ANCHOR_BOTTOM_RIGHT = "bottom-right";
+
+ /**
+ * Part of the text placed closest to the anchor.
+ */
+ @StringDef( {
+ TEXT_ANCHOR_CENTER,
+ TEXT_ANCHOR_LEFT,
+ TEXT_ANCHOR_RIGHT,
+ TEXT_ANCHOR_TOP,
+ TEXT_ANCHOR_BOTTOM,
+ TEXT_ANCHOR_TOP_LEFT,
+ TEXT_ANCHOR_TOP_RIGHT,
+ TEXT_ANCHOR_BOTTOM_LEFT,
+ TEXT_ANCHOR_BOTTOM_RIGHT,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface TEXT_ANCHOR {
+ }
+
+ //TEXT_TRANSFORM: Specifies how to capitalize text, similar to the CSS `text-transform` property.
+
+ /**
+ * The text is not altered.
+ */
+ public static final String TEXT_TRANSFORM_NONE = "none";
+ /**
+ * Forces all letters to be displayed in uppercase.
+ */
+ public static final String TEXT_TRANSFORM_UPPERCASE = "uppercase";
+ /**
+ * Forces all letters to be displayed in lowercase.
+ */
+ public static final String TEXT_TRANSFORM_LOWERCASE = "lowercase";
+
+ /**
+ * Specifies how to capitalize text, similar to the CSS `text-transform` property.
+ */
+ @StringDef( {
+ TEXT_TRANSFORM_NONE,
+ TEXT_TRANSFORM_UPPERCASE,
+ TEXT_TRANSFORM_LOWERCASE,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface TEXT_TRANSFORM {
+ }
+
+ //FILL_TRANSLATE_ANCHOR: Controls the translation reference point.
+
+ /**
+ * The fill is translated relative to the map.
+ */
+ public static final String FILL_TRANSLATE_ANCHOR_MAP = "map";
+ /**
+ * The fill is translated relative to the viewport.
+ */
+ public static final String FILL_TRANSLATE_ANCHOR_VIEWPORT = "viewport";
+
+ /**
+ * Controls the translation reference point.
+ */
+ @StringDef( {
+ FILL_TRANSLATE_ANCHOR_MAP,
+ FILL_TRANSLATE_ANCHOR_VIEWPORT,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface FILL_TRANSLATE_ANCHOR {
+ }
+
+ //LINE_TRANSLATE_ANCHOR: Controls the translation reference point.
+
+ /**
+ * The line is translated relative to the map.
+ */
+ public static final String LINE_TRANSLATE_ANCHOR_MAP = "map";
+ /**
+ * The line is translated relative to the viewport.
+ */
+ public static final String LINE_TRANSLATE_ANCHOR_VIEWPORT = "viewport";
+
+ /**
+ * Controls the translation reference point.
+ */
+ @StringDef( {
+ LINE_TRANSLATE_ANCHOR_MAP,
+ LINE_TRANSLATE_ANCHOR_VIEWPORT,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface LINE_TRANSLATE_ANCHOR {
+ }
+
+ //ICON_TRANSLATE_ANCHOR: Controls the translation reference point.
+
+ /**
+ * Icons are translated relative to the map.
+ */
+ public static final String ICON_TRANSLATE_ANCHOR_MAP = "map";
+ /**
+ * Icons are translated relative to the viewport.
+ */
+ public static final String ICON_TRANSLATE_ANCHOR_VIEWPORT = "viewport";
+
+ /**
+ * Controls the translation reference point.
+ */
+ @StringDef( {
+ ICON_TRANSLATE_ANCHOR_MAP,
+ ICON_TRANSLATE_ANCHOR_VIEWPORT,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ICON_TRANSLATE_ANCHOR {
+ }
+
+ //TEXT_TRANSLATE_ANCHOR: Controls the translation reference point.
+
+ /**
+ * The text is translated relative to the map.
+ */
+ public static final String TEXT_TRANSLATE_ANCHOR_MAP = "map";
+ /**
+ * The text is translated relative to the viewport.
+ */
+ public static final String TEXT_TRANSLATE_ANCHOR_VIEWPORT = "viewport";
+
+ /**
+ * Controls the translation reference point.
+ */
+ @StringDef( {
+ TEXT_TRANSLATE_ANCHOR_MAP,
+ TEXT_TRANSLATE_ANCHOR_VIEWPORT,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface TEXT_TRANSLATE_ANCHOR {
+ }
+
+ //CIRCLE_TRANSLATE_ANCHOR: Controls the translation reference point.
+
+ /**
+ * The circle is translated relative to the map.
+ */
+ public static final String CIRCLE_TRANSLATE_ANCHOR_MAP = "map";
+ /**
+ * The circle is translated relative to the viewport.
+ */
+ public static final String CIRCLE_TRANSLATE_ANCHOR_VIEWPORT = "viewport";
+
+ /**
+ * Controls the translation reference point.
+ */
+ @StringDef( {
+ CIRCLE_TRANSLATE_ANCHOR_MAP,
+ CIRCLE_TRANSLATE_ANCHOR_VIEWPORT,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface CIRCLE_TRANSLATE_ANCHOR {
+ }
+
+ //CIRCLE_PITCH_SCALE: Controls the scaling behavior of the circle when the map is pitched.
+
+ /**
+ * Circles are scaled according to their apparent distance to the camera.
+ */
+ public static final String CIRCLE_PITCH_SCALE_MAP = "map";
+ /**
+ * Circles are not scaled.
+ */
+ public static final String CIRCLE_PITCH_SCALE_VIEWPORT = "viewport";
+
+ /**
+ * Controls the scaling behavior of the circle when the map is pitched.
+ */
+ @StringDef( {
+ CIRCLE_PITCH_SCALE_MAP,
+ CIRCLE_PITCH_SCALE_VIEWPORT,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface CIRCLE_PITCH_SCALE {
+ }
+
+ //Class definition
+ public final String name;
+ public final T value;
+
+ /* package */ Property(String name, T value) {
+ this.name = name;
+ this.value = value;
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java
index 0cb8fdeff9..8e7d516a39 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java
@@ -1,5 +1,5 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
package com.mapbox.mapboxsdk.style.layers;
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
import android.annotation.SuppressLint;
import android.support.annotation.ColorInt;
@@ -11,1839 +11,1947 @@ import android.support.annotation.ColorInt;
*/
public class PropertyFactory {
- /**
- * Set the property visibility.
- *
- * @param value the visibility value
- * @return property wrapper around visibility
- */
- public static Property<String> visibility(@Property.VISIBILITY String value) {
- return new LayoutProperty<>("visibility", value);
- }
-
- /**
- * Set the property visibility.
- *
- * @param function the visibility function
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> visibility(Function<String> function) {
- return new LayoutProperty<>("visibility", function);
- }
-
- /**
- * Whether or not the fill should be antialiased.
- *
- * @param value a Boolean value
- * @return property wrapper around Boolean
- */
- public static Property<Boolean> fillAntialias(Boolean value) {
- return new PaintProperty<>("fill-antialias", value);
- }
-
- /**
- * Whether or not the fill should be antialiased.
- *
- * @param function a wrapper function for Boolean
- * @return property wrapper around a Boolean function
- */
- public static Property<Function<Boolean>> fillAntialias(Function<Boolean> function) {
- return new PaintProperty<>("fill-antialias", function);
- }
-
- /**
- * The opacity of the entire fill layer. In contrast to the {@link PropertyFactory#fillColor}, this value will also affect the 1px stroke around the fill, if the stroke is used.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> fillOpacity(Float value) {
- return new PaintProperty<>("fill-opacity", value);
- }
-
- /**
- * The opacity of the entire fill layer. In contrast to the {@link PropertyFactory#fillColor}, this value will also affect the 1px stroke around the fill, if the stroke is used.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> fillOpacity(Function<Float> function) {
- return new PaintProperty<>("fill-opacity", function);
- }
-
- /**
- * 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 1px stroke, if it is used.
- *
- * @param value a int color value
- * @return property wrapper around String color
- */
- public static Property<String> fillColor(@ColorInt int value) {
- return new PaintProperty<>("fill-color", colorToRgbaString(value));
- }
-
- /**
- * 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 1px stroke, if it is used.
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> fillColor(String value) {
- return new PaintProperty<>("fill-color", value);
- }
-
- /**
- * 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 1px stroke, if it is used.
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> fillColor(Function<String> function) {
- return new PaintProperty<>("fill-color", function);
- }
-
- /**
- * The outline color of the fill. Matches the value of {@link PropertyFactory#fillColor} if unspecified.
- *
- * @param value a int color value
- * @return property wrapper around String color
- */
- public static Property<String> fillOutlineColor(@ColorInt int value) {
- return new PaintProperty<>("fill-outline-color", colorToRgbaString(value));
- }
-
- /**
- * The outline color of the fill. Matches the value of {@link PropertyFactory#fillColor} if unspecified.
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> fillOutlineColor(String value) {
- return new PaintProperty<>("fill-outline-color", value);
- }
-
- /**
- * The outline color of the fill. Matches the value of {@link PropertyFactory#fillColor} if unspecified.
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> fillOutlineColor(Function<String> function) {
- return new PaintProperty<>("fill-outline-color", function);
- }
-
- /**
- * The geometry's offset. Values are [x, y] where negatives indicate left and up, respectively.
- *
- * @param value a Float[] value
- * @return property wrapper around Float[]
- */
- public static Property<Float[]> fillTranslate(Float[] value) {
- return new PaintProperty<>("fill-translate", value);
- }
-
- /**
- * The geometry's offset. Values are [x, y] where negatives indicate left and up, respectively.
- *
- * @param function a wrapper function for Float[]
- * @return property wrapper around a Float[] function
- */
- public static Property<Function<Float[]>> fillTranslate(Function<Float[]> function) {
- return new PaintProperty<>("fill-translate", function);
- }
-
- /**
- * Controls the translation reference point.
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> fillTranslateAnchor(@Property.FILL_TRANSLATE_ANCHOR String value) {
- return new PaintProperty<>("fill-translate-anchor", value);
- }
-
- /**
- * Controls the translation reference point.
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> fillTranslateAnchor(Function<String> function) {
- return new PaintProperty<>("fill-translate-anchor", function);
- }
-
- /**
- * 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).
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> fillPattern(String value) {
- return new PaintProperty<>("fill-pattern", value);
- }
-
- /**
- * 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).
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> fillPattern(Function<String> function) {
- return new PaintProperty<>("fill-pattern", function);
- }
-
- /**
- * The opacity at which the line will be drawn.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> lineOpacity(Float value) {
- return new PaintProperty<>("line-opacity", value);
- }
-
- /**
- * The opacity at which the line will be drawn.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> lineOpacity(Function<Float> function) {
- return new PaintProperty<>("line-opacity", function);
- }
-
- /**
- * The color with which the line will be drawn.
- *
- * @param value a int color value
- * @return property wrapper around String color
- */
- public static Property<String> lineColor(@ColorInt int value) {
- return new PaintProperty<>("line-color", colorToRgbaString(value));
- }
-
- /**
- * The color with which the line will be drawn.
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> lineColor(String value) {
- return new PaintProperty<>("line-color", value);
- }
-
- /**
- * The color with which the line will be drawn.
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> lineColor(Function<String> function) {
- return new PaintProperty<>("line-color", function);
- }
-
- /**
- * The geometry's offset. Values are [x, y] where negatives indicate left and up, respectively.
- *
- * @param value a Float[] value
- * @return property wrapper around Float[]
- */
- public static Property<Float[]> lineTranslate(Float[] value) {
- return new PaintProperty<>("line-translate", value);
- }
-
- /**
- * The geometry's offset. Values are [x, y] where negatives indicate left and up, respectively.
- *
- * @param function a wrapper function for Float[]
- * @return property wrapper around a Float[] function
- */
- public static Property<Function<Float[]>> lineTranslate(Function<Float[]> function) {
- return new PaintProperty<>("line-translate", function);
- }
-
- /**
- * Controls the translation reference point.
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> lineTranslateAnchor(@Property.LINE_TRANSLATE_ANCHOR String value) {
- return new PaintProperty<>("line-translate-anchor", value);
- }
-
- /**
- * Controls the translation reference point.
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> lineTranslateAnchor(Function<String> function) {
- return new PaintProperty<>("line-translate-anchor", function);
- }
-
- /**
- * Stroke thickness.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> lineWidth(Float value) {
- return new PaintProperty<>("line-width", value);
- }
-
- /**
- * Stroke thickness.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> lineWidth(Function<Float> function) {
- return new PaintProperty<>("line-width", function);
- }
-
- /**
- * Draws a line casing outside of a line's actual path. Value indicates the width of the inner gap.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> lineGapWidth(Float value) {
- return new PaintProperty<>("line-gap-width", value);
- }
-
- /**
- * Draws a line casing outside of a line's actual path. Value indicates the width of the inner gap.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> lineGapWidth(Function<Float> function) {
- return new PaintProperty<>("line-gap-width", function);
- }
-
- /**
- * 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.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> lineOffset(Float value) {
- return new PaintProperty<>("line-offset", value);
- }
-
- /**
- * 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.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> lineOffset(Function<Float> function) {
- return new PaintProperty<>("line-offset", function);
- }
-
- /**
- * Blur applied to the line, in pixels.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> lineBlur(Float value) {
- return new PaintProperty<>("line-blur", value);
- }
-
- /**
- * Blur applied to the line, in pixels.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> lineBlur(Function<Float> function) {
- return new PaintProperty<>("line-blur", function);
- }
-
- /**
- * 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 pixels, multiply the length by the current line width.
- *
- * @param value a Float[] value
- * @return property wrapper around Float[]
- */
- public static Property<Float[]> lineDasharray(Float[] value) {
- return new PaintProperty<>("line-dasharray", value);
- }
-
- /**
- * 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 pixels, multiply the length by the current line width.
- *
- * @param function a wrapper function for Float[]
- * @return property wrapper around a Float[] function
- */
- public static Property<Function<Float[]>> lineDasharray(Function<Float[]> function) {
- return new PaintProperty<>("line-dasharray", function);
- }
-
- /**
- * 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).
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> linePattern(String value) {
- return new PaintProperty<>("line-pattern", value);
- }
-
- /**
- * 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).
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> linePattern(Function<String> function) {
- return new PaintProperty<>("line-pattern", function);
- }
-
- /**
- * The opacity at which the icon will be drawn.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> iconOpacity(Float value) {
- return new PaintProperty<>("icon-opacity", value);
- }
-
- /**
- * The opacity at which the icon will be drawn.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> iconOpacity(Function<Float> function) {
- return new PaintProperty<>("icon-opacity", function);
- }
-
- /**
- * The color of the icon. This can only be used with sdf icons.
- *
- * @param value a int color value
- * @return property wrapper around String color
- */
- public static Property<String> iconColor(@ColorInt int value) {
- return new PaintProperty<>("icon-color", colorToRgbaString(value));
- }
-
- /**
- * The color of the icon. This can only be used with sdf icons.
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> iconColor(String value) {
- return new PaintProperty<>("icon-color", value);
- }
-
- /**
- * The color of the icon. This can only be used with sdf icons.
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> iconColor(Function<String> function) {
- return new PaintProperty<>("icon-color", function);
- }
-
- /**
- * The color of the icon's halo. Icon halos can only be used with SDF icons.
- *
- * @param value a int color value
- * @return property wrapper around String color
- */
- public static Property<String> iconHaloColor(@ColorInt int value) {
- return new PaintProperty<>("icon-halo-color", colorToRgbaString(value));
- }
-
- /**
- * The color of the icon's halo. Icon halos can only be used with SDF icons.
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> iconHaloColor(String value) {
- return new PaintProperty<>("icon-halo-color", value);
- }
-
- /**
- * The color of the icon's halo. Icon halos can only be used with SDF icons.
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> iconHaloColor(Function<String> function) {
- return new PaintProperty<>("icon-halo-color", function);
- }
-
- /**
- * Distance of halo to the icon outline.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> iconHaloWidth(Float value) {
- return new PaintProperty<>("icon-halo-width", value);
- }
-
- /**
- * Distance of halo to the icon outline.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> iconHaloWidth(Function<Float> function) {
- return new PaintProperty<>("icon-halo-width", function);
- }
-
- /**
- * Fade out the halo towards the outside.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> iconHaloBlur(Float value) {
- return new PaintProperty<>("icon-halo-blur", value);
- }
-
- /**
- * Fade out the halo towards the outside.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> iconHaloBlur(Function<Float> function) {
- return new PaintProperty<>("icon-halo-blur", function);
- }
-
- /**
- * 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.
- *
- * @param value a Float[] value
- * @return property wrapper around Float[]
- */
- public static Property<Float[]> iconTranslate(Float[] value) {
- return new PaintProperty<>("icon-translate", value);
- }
-
- /**
- * 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.
- *
- * @param function a wrapper function for Float[]
- * @return property wrapper around a Float[] function
- */
- public static Property<Function<Float[]>> iconTranslate(Function<Float[]> function) {
- return new PaintProperty<>("icon-translate", function);
- }
-
- /**
- * Controls the translation reference point.
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> iconTranslateAnchor(@Property.ICON_TRANSLATE_ANCHOR String value) {
- return new PaintProperty<>("icon-translate-anchor", value);
- }
-
- /**
- * Controls the translation reference point.
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> iconTranslateAnchor(Function<String> function) {
- return new PaintProperty<>("icon-translate-anchor", function);
- }
-
- /**
- * The opacity at which the text will be drawn.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> textOpacity(Float value) {
- return new PaintProperty<>("text-opacity", value);
- }
-
- /**
- * The opacity at which the text will be drawn.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> textOpacity(Function<Float> function) {
- return new PaintProperty<>("text-opacity", function);
- }
-
- /**
- * The color with which the text will be drawn.
- *
- * @param value a int color value
- * @return property wrapper around String color
- */
- public static Property<String> textColor(@ColorInt int value) {
- return new PaintProperty<>("text-color", colorToRgbaString(value));
- }
-
- /**
- * The color with which the text will be drawn.
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> textColor(String value) {
- return new PaintProperty<>("text-color", value);
- }
-
- /**
- * The color with which the text will be drawn.
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> textColor(Function<String> function) {
- return new PaintProperty<>("text-color", function);
- }
-
- /**
- * The color of the text's halo, which helps it stand out from backgrounds.
- *
- * @param value a int color value
- * @return property wrapper around String color
- */
- public static Property<String> textHaloColor(@ColorInt int value) {
- return new PaintProperty<>("text-halo-color", colorToRgbaString(value));
- }
-
- /**
- * The color of the text's halo, which helps it stand out from backgrounds.
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> textHaloColor(String value) {
- return new PaintProperty<>("text-halo-color", value);
- }
-
- /**
- * The color of the text's halo, which helps it stand out from backgrounds.
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> textHaloColor(Function<String> function) {
- return new PaintProperty<>("text-halo-color", function);
- }
-
- /**
- * Distance of halo to the font outline. Max text halo width is 1/4 of the font-size.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> textHaloWidth(Float value) {
- return new PaintProperty<>("text-halo-width", value);
- }
-
- /**
- * Distance of halo to the font outline. Max text halo width is 1/4 of the font-size.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> textHaloWidth(Function<Float> function) {
- return new PaintProperty<>("text-halo-width", function);
- }
-
- /**
- * The halo's fadeout distance towards the outside.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> textHaloBlur(Float value) {
- return new PaintProperty<>("text-halo-blur", value);
- }
-
- /**
- * The halo's fadeout distance towards the outside.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> textHaloBlur(Function<Float> function) {
- return new PaintProperty<>("text-halo-blur", function);
- }
-
- /**
- * 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.
- *
- * @param value a Float[] value
- * @return property wrapper around Float[]
- */
- public static Property<Float[]> textTranslate(Float[] value) {
- return new PaintProperty<>("text-translate", value);
- }
-
- /**
- * 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.
- *
- * @param function a wrapper function for Float[]
- * @return property wrapper around a Float[] function
- */
- public static Property<Function<Float[]>> textTranslate(Function<Float[]> function) {
- return new PaintProperty<>("text-translate", function);
- }
-
- /**
- * Controls the translation reference point.
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> textTranslateAnchor(@Property.TEXT_TRANSLATE_ANCHOR String value) {
- return new PaintProperty<>("text-translate-anchor", value);
- }
-
- /**
- * Controls the translation reference point.
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> textTranslateAnchor(Function<String> function) {
- return new PaintProperty<>("text-translate-anchor", function);
- }
-
- /**
- * Circle radius.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> circleRadius(Float value) {
- return new PaintProperty<>("circle-radius", value);
- }
-
- /**
- * Circle radius.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> circleRadius(Function<Float> function) {
- return new PaintProperty<>("circle-radius", function);
- }
-
- /**
- * The fill color of the circle.
- *
- * @param value a int color value
- * @return property wrapper around String color
- */
- public static Property<String> circleColor(@ColorInt int value) {
- return new PaintProperty<>("circle-color", colorToRgbaString(value));
- }
-
- /**
- * The fill color of the circle.
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> circleColor(String value) {
- return new PaintProperty<>("circle-color", value);
- }
-
- /**
- * The fill color of the circle.
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> circleColor(Function<String> function) {
- return new PaintProperty<>("circle-color", function);
- }
-
- /**
- * Amount to blur the circle. 1 blurs the circle such that only the centerpoint is full opacity.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> circleBlur(Float value) {
- return new PaintProperty<>("circle-blur", value);
- }
-
- /**
- * Amount to blur the circle. 1 blurs the circle such that only the centerpoint is full opacity.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> circleBlur(Function<Float> function) {
- return new PaintProperty<>("circle-blur", function);
- }
-
- /**
- * The opacity at which the circle will be drawn.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> circleOpacity(Float value) {
- return new PaintProperty<>("circle-opacity", value);
- }
-
- /**
- * The opacity at which the circle will be drawn.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> circleOpacity(Function<Float> function) {
- return new PaintProperty<>("circle-opacity", function);
- }
-
- /**
- * The geometry's offset. Values are [x, y] where negatives indicate left and up, respectively.
- *
- * @param value a Float[] value
- * @return property wrapper around Float[]
- */
- public static Property<Float[]> circleTranslate(Float[] value) {
- return new PaintProperty<>("circle-translate", value);
- }
-
- /**
- * The geometry's offset. Values are [x, y] where negatives indicate left and up, respectively.
- *
- * @param function a wrapper function for Float[]
- * @return property wrapper around a Float[] function
- */
- public static Property<Function<Float[]>> circleTranslate(Function<Float[]> function) {
- return new PaintProperty<>("circle-translate", function);
- }
-
- /**
- * Controls the translation reference point.
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> circleTranslateAnchor(@Property.CIRCLE_TRANSLATE_ANCHOR String value) {
- return new PaintProperty<>("circle-translate-anchor", value);
- }
-
- /**
- * Controls the translation reference point.
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> circleTranslateAnchor(Function<String> function) {
- return new PaintProperty<>("circle-translate-anchor", function);
- }
-
- /**
- * Controls the scaling behavior of the circle when the map is pitched.
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> circlePitchScale(@Property.CIRCLE_PITCH_SCALE String value) {
- return new PaintProperty<>("circle-pitch-scale", value);
- }
-
- /**
- * Controls the scaling behavior of the circle when the map is pitched.
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> circlePitchScale(Function<String> function) {
- return new PaintProperty<>("circle-pitch-scale", function);
- }
-
- /**
- * The opacity at which the image will be drawn.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> rasterOpacity(Float value) {
- return new PaintProperty<>("raster-opacity", value);
- }
-
- /**
- * The opacity at which the image will be drawn.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> rasterOpacity(Function<Float> function) {
- return new PaintProperty<>("raster-opacity", function);
- }
-
- /**
- * Rotates hues around the color wheel.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> rasterHueRotate(Float value) {
- return new PaintProperty<>("raster-hue-rotate", value);
- }
-
- /**
- * Rotates hues around the color wheel.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> rasterHueRotate(Function<Float> function) {
- return new PaintProperty<>("raster-hue-rotate", function);
- }
-
- /**
- * Increase or reduce the brightness of the image. The value is the minimum brightness.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> rasterBrightnessMin(Float value) {
- return new PaintProperty<>("raster-brightness-min", value);
- }
-
- /**
- * Increase or reduce the brightness of the image. The value is the minimum brightness.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> rasterBrightnessMin(Function<Float> function) {
- return new PaintProperty<>("raster-brightness-min", function);
- }
-
- /**
- * Increase or reduce the brightness of the image. The value is the maximum brightness.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> rasterBrightnessMax(Float value) {
- return new PaintProperty<>("raster-brightness-max", value);
- }
-
- /**
- * Increase or reduce the brightness of the image. The value is the maximum brightness.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> rasterBrightnessMax(Function<Float> function) {
- return new PaintProperty<>("raster-brightness-max", function);
- }
-
- /**
- * Increase or reduce the saturation of the image.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> rasterSaturation(Float value) {
- return new PaintProperty<>("raster-saturation", value);
- }
-
- /**
- * Increase or reduce the saturation of the image.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> rasterSaturation(Function<Float> function) {
- return new PaintProperty<>("raster-saturation", function);
- }
-
- /**
- * Increase or reduce the contrast of the image.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> rasterContrast(Float value) {
- return new PaintProperty<>("raster-contrast", value);
- }
-
- /**
- * Increase or reduce the contrast of the image.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> rasterContrast(Function<Float> function) {
- return new PaintProperty<>("raster-contrast", function);
- }
-
- /**
- * Fade duration when a new tile is added.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> rasterFadeDuration(Float value) {
- return new PaintProperty<>("raster-fade-duration", value);
- }
-
- /**
- * Fade duration when a new tile is added.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> rasterFadeDuration(Function<Float> function) {
- return new PaintProperty<>("raster-fade-duration", function);
- }
-
- /**
- * The color with which the background will be drawn.
- *
- * @param value a int color value
- * @return property wrapper around String color
- */
- public static Property<String> backgroundColor(@ColorInt int value) {
- return new PaintProperty<>("background-color", colorToRgbaString(value));
- }
-
- /**
- * The color with which the background will be drawn.
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> backgroundColor(String value) {
- return new PaintProperty<>("background-color", value);
- }
-
- /**
- * The color with which the background will be drawn.
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> backgroundColor(Function<String> function) {
- return new PaintProperty<>("background-color", function);
- }
-
- /**
- * 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).
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> backgroundPattern(String value) {
- return new PaintProperty<>("background-pattern", value);
- }
-
- /**
- * 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).
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> backgroundPattern(Function<String> function) {
- return new PaintProperty<>("background-pattern", function);
- }
-
- /**
- * The opacity at which the background will be drawn.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> backgroundOpacity(Float value) {
- return new PaintProperty<>("background-opacity", value);
- }
-
- /**
- * The opacity at which the background will be drawn.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> backgroundOpacity(Function<Float> function) {
- return new PaintProperty<>("background-opacity", function);
- }
-
- /**
- * The display of line endings.
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> lineCap(@Property.LINE_CAP String value) {
- return new LayoutProperty<>("line-cap", value);
- }
-
- /**
- * The display of line endings.
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> lineCap(Function<String> function) {
- return new LayoutProperty<>("line-cap", function);
- }
-
- /**
- * The display of lines when joining.
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> lineJoin(@Property.LINE_JOIN String value) {
- return new LayoutProperty<>("line-join", value);
- }
-
- /**
- * The display of lines when joining.
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> lineJoin(Function<String> function) {
- return new LayoutProperty<>("line-join", function);
- }
-
- /**
- * Used to automatically convert miter joins to bevel joins for sharp angles.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> lineMiterLimit(Float value) {
- return new LayoutProperty<>("line-miter-limit", value);
- }
-
- /**
- * Used to automatically convert miter joins to bevel joins for sharp angles.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> lineMiterLimit(Function<Float> function) {
- return new LayoutProperty<>("line-miter-limit", function);
- }
-
- /**
- * Used to automatically convert round joins to miter joins for shallow angles.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> lineRoundLimit(Float value) {
- return new LayoutProperty<>("line-round-limit", value);
- }
-
- /**
- * Used to automatically convert round joins to miter joins for shallow angles.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> lineRoundLimit(Function<Float> function) {
- return new LayoutProperty<>("line-round-limit", function);
- }
-
- /**
- * Label placement relative to its geometry.
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> symbolPlacement(@Property.SYMBOL_PLACEMENT String value) {
- return new LayoutProperty<>("symbol-placement", value);
- }
-
- /**
- * Label placement relative to its geometry.
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> symbolPlacement(Function<String> function) {
- return new LayoutProperty<>("symbol-placement", function);
- }
-
- /**
- * Distance between two symbol anchors.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> symbolSpacing(Float value) {
- return new LayoutProperty<>("symbol-spacing", value);
- }
-
- /**
- * Distance between two symbol anchors.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> symbolSpacing(Function<Float> function) {
- return new LayoutProperty<>("symbol-spacing", function);
- }
-
- /**
- * 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.
- *
- * @param value a Boolean value
- * @return property wrapper around Boolean
- */
- public static Property<Boolean> symbolAvoidEdges(Boolean value) {
- return new LayoutProperty<>("symbol-avoid-edges", value);
- }
-
- /**
- * 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.
- *
- * @param function a wrapper function for Boolean
- * @return property wrapper around a Boolean function
- */
- public static Property<Function<Boolean>> symbolAvoidEdges(Function<Boolean> function) {
- return new LayoutProperty<>("symbol-avoid-edges", function);
- }
-
- /**
- * If true, the icon will be visible even if it collides with other previously drawn symbols.
- *
- * @param value a Boolean value
- * @return property wrapper around Boolean
- */
- public static Property<Boolean> iconAllowOverlap(Boolean value) {
- return new LayoutProperty<>("icon-allow-overlap", value);
- }
-
- /**
- * If true, the icon will be visible even if it collides with other previously drawn symbols.
- *
- * @param function a wrapper function for Boolean
- * @return property wrapper around a Boolean function
- */
- public static Property<Function<Boolean>> iconAllowOverlap(Function<Boolean> function) {
- return new LayoutProperty<>("icon-allow-overlap", function);
- }
-
- /**
- * If true, other symbols can be visible even if they collide with the icon.
- *
- * @param value a Boolean value
- * @return property wrapper around Boolean
- */
- public static Property<Boolean> iconIgnorePlacement(Boolean value) {
- return new LayoutProperty<>("icon-ignore-placement", value);
- }
-
- /**
- * If true, other symbols can be visible even if they collide with the icon.
- *
- * @param function a wrapper function for Boolean
- * @return property wrapper around a Boolean function
- */
- public static Property<Function<Boolean>> iconIgnorePlacement(Function<Boolean> function) {
- return new LayoutProperty<>("icon-ignore-placement", function);
- }
-
- /**
- * If true, text will display without their corresponding icons when the icon collides with other symbols and the text does not.
- *
- * @param value a Boolean value
- * @return property wrapper around Boolean
- */
- public static Property<Boolean> iconOptional(Boolean value) {
- return new LayoutProperty<>("icon-optional", value);
- }
-
- /**
- * If true, text will display without their corresponding icons when the icon collides with other symbols and the text does not.
- *
- * @param function a wrapper function for Boolean
- * @return property wrapper around a Boolean function
- */
- public static Property<Function<Boolean>> iconOptional(Function<Boolean> function) {
- return new LayoutProperty<>("icon-optional", function);
- }
-
- /**
- * In combination with {@link Property.SYMBOL_PLACEMENT}, determines the rotation behavior of icons.
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> iconRotationAlignment(@Property.ICON_ROTATION_ALIGNMENT String value) {
- return new LayoutProperty<>("icon-rotation-alignment", value);
- }
-
- /**
- * In combination with {@link Property.SYMBOL_PLACEMENT}, determines the rotation behavior of icons.
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> iconRotationAlignment(Function<String> function) {
- return new LayoutProperty<>("icon-rotation-alignment", function);
- }
-
- /**
- * Scale factor for icon. 1 is original size, 3 triples the size.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> iconSize(Float value) {
- return new LayoutProperty<>("icon-size", value);
- }
-
- /**
- * Scale factor for icon. 1 is original size, 3 triples the size.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> iconSize(Function<Float> function) {
- return new LayoutProperty<>("icon-size", function);
- }
-
- /**
- * Scales the icon to fit around the associated text.
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> iconTextFit(@Property.ICON_TEXT_FIT String value) {
- return new LayoutProperty<>("icon-text-fit", value);
- }
-
- /**
- * Scales the icon to fit around the associated text.
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> iconTextFit(Function<String> function) {
- return new LayoutProperty<>("icon-text-fit", function);
- }
-
- /**
- * Size of the additional area added to dimensions determined by {@link Property.ICON_TEXT_FIT}, in clockwise order: top, right, bottom, left.
- *
- * @param value a Float[] value
- * @return property wrapper around Float[]
- */
- public static Property<Float[]> iconTextFitPadding(Float[] value) {
- return new LayoutProperty<>("icon-text-fit-padding", value);
- }
-
- /**
- * Size of the additional area added to dimensions determined by {@link Property.ICON_TEXT_FIT}, in clockwise order: top, right, bottom, left.
- *
- * @param function a wrapper function for Float[]
- * @return property wrapper around a Float[] function
- */
- public static Property<Function<Float[]>> iconTextFitPadding(Function<Float[]> function) {
- return new LayoutProperty<>("icon-text-fit-padding", function);
- }
-
- /**
- * A string with {tokens} replaced, referencing the data property to pull from.
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> iconImage(String value) {
- return new LayoutProperty<>("icon-image", value);
- }
-
- /**
- * A string with {tokens} replaced, referencing the data property to pull from.
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> iconImage(Function<String> function) {
- return new LayoutProperty<>("icon-image", function);
- }
-
- /**
- * Rotates the icon clockwise.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> iconRotate(Float value) {
- return new LayoutProperty<>("icon-rotate", value);
- }
-
- /**
- * Rotates the icon clockwise.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> iconRotate(Function<Float> function) {
- return new LayoutProperty<>("icon-rotate", function);
- }
-
- /**
- * Size of the additional area around the icon bounding box used for detecting symbol collisions.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> iconPadding(Float value) {
- return new LayoutProperty<>("icon-padding", value);
- }
-
- /**
- * Size of the additional area around the icon bounding box used for detecting symbol collisions.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> iconPadding(Function<Float> function) {
- return new LayoutProperty<>("icon-padding", function);
- }
-
- /**
- * If true, the icon may be flipped to prevent it from being rendered upside-down.
- *
- * @param value a Boolean value
- * @return property wrapper around Boolean
- */
- public static Property<Boolean> iconKeepUpright(Boolean value) {
- return new LayoutProperty<>("icon-keep-upright", value);
- }
-
- /**
- * If true, the icon may be flipped to prevent it from being rendered upside-down.
- *
- * @param function a wrapper function for Boolean
- * @return property wrapper around a Boolean function
- */
- public static Property<Function<Boolean>> iconKeepUpright(Function<Boolean> function) {
- return new LayoutProperty<>("icon-keep-upright", function);
- }
-
- /**
- * Offset distance of icon from its anchor. Positive values indicate right and down, while negative values indicate left and up.
- *
- * @param value a Float[] value
- * @return property wrapper around Float[]
- */
- public static Property<Float[]> iconOffset(Float[] value) {
- return new LayoutProperty<>("icon-offset", value);
- }
-
- /**
- * Offset distance of icon from its anchor. Positive values indicate right and down, while negative values indicate left and up.
- *
- * @param function a wrapper function for Float[]
- * @return property wrapper around a Float[] function
- */
- public static Property<Function<Float[]>> iconOffset(Function<Float[]> function) {
- return new LayoutProperty<>("icon-offset", function);
- }
-
- /**
- * Orientation of text when map is pitched.
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> textPitchAlignment(@Property.TEXT_PITCH_ALIGNMENT String value) {
- return new LayoutProperty<>("text-pitch-alignment", value);
- }
-
- /**
- * Orientation of text when map is pitched.
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> textPitchAlignment(Function<String> function) {
- return new LayoutProperty<>("text-pitch-alignment", function);
- }
-
- /**
- * In combination with {@link Property.SYMBOL_PLACEMENT}, determines the rotation behavior of the individual glyphs forming the text.
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> textRotationAlignment(@Property.TEXT_ROTATION_ALIGNMENT String value) {
- return new LayoutProperty<>("text-rotation-alignment", value);
- }
-
- /**
- * In combination with {@link Property.SYMBOL_PLACEMENT}, determines the rotation behavior of the individual glyphs forming the text.
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> textRotationAlignment(Function<String> function) {
- return new LayoutProperty<>("text-rotation-alignment", function);
- }
-
- /**
- * Value to use for a text label. Feature properties are specified using tokens like {field_name}.
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> textField(String value) {
- return new LayoutProperty<>("text-field", value);
- }
-
- /**
- * Value to use for a text label. Feature properties are specified using tokens like {field_name}.
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> textField(Function<String> function) {
- return new LayoutProperty<>("text-field", function);
- }
-
- /**
- * Font stack to use for displaying text.
- *
- * @param value a String[] value
- * @return property wrapper around String[]
- */
- public static Property<String[]> textFont(String[] value) {
- return new LayoutProperty<>("text-font", value);
- }
-
- /**
- * Font stack to use for displaying text.
- *
- * @param function a wrapper function for String[]
- * @return property wrapper around a String[] function
- */
- public static Property<Function<String[]>> textFont(Function<String[]> function) {
- return new LayoutProperty<>("text-font", function);
- }
-
- /**
- * Font size.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> textSize(Float value) {
- return new LayoutProperty<>("text-size", value);
- }
-
- /**
- * Font size.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> textSize(Function<Float> function) {
- return new LayoutProperty<>("text-size", function);
- }
-
- /**
- * The maximum line width for text wrapping.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> textMaxWidth(Float value) {
- return new LayoutProperty<>("text-max-width", value);
- }
-
- /**
- * The maximum line width for text wrapping.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> textMaxWidth(Function<Float> function) {
- return new LayoutProperty<>("text-max-width", function);
- }
-
- /**
- * Text leading value for multi-line text.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> textLineHeight(Float value) {
- return new LayoutProperty<>("text-line-height", value);
- }
-
- /**
- * Text leading value for multi-line text.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> textLineHeight(Function<Float> function) {
- return new LayoutProperty<>("text-line-height", function);
- }
-
- /**
- * Text tracking amount.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> textLetterSpacing(Float value) {
- return new LayoutProperty<>("text-letter-spacing", value);
- }
-
- /**
- * Text tracking amount.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> textLetterSpacing(Function<Float> function) {
- return new LayoutProperty<>("text-letter-spacing", function);
- }
-
- /**
- * Text justification options.
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> textJustify(@Property.TEXT_JUSTIFY String value) {
- return new LayoutProperty<>("text-justify", value);
- }
-
- /**
- * Text justification options.
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> textJustify(Function<String> function) {
- return new LayoutProperty<>("text-justify", function);
- }
-
- /**
- * Part of the text placed closest to the anchor.
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> textAnchor(@Property.TEXT_ANCHOR String value) {
- return new LayoutProperty<>("text-anchor", value);
- }
-
- /**
- * Part of the text placed closest to the anchor.
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> textAnchor(Function<String> function) {
- return new LayoutProperty<>("text-anchor", function);
- }
-
- /**
- * Maximum angle change between adjacent characters.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> textMaxAngle(Float value) {
- return new LayoutProperty<>("text-max-angle", value);
- }
-
- /**
- * Maximum angle change between adjacent characters.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> textMaxAngle(Function<Float> function) {
- return new LayoutProperty<>("text-max-angle", function);
- }
-
- /**
- * Rotates the text clockwise.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> textRotate(Float value) {
- return new LayoutProperty<>("text-rotate", value);
- }
-
- /**
- * Rotates the text clockwise.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> textRotate(Function<Float> function) {
- return new LayoutProperty<>("text-rotate", function);
- }
-
- /**
- * Size of the additional area around the text bounding box used for detecting symbol collisions.
- *
- * @param value a Float value
- * @return property wrapper around Float
- */
- public static Property<Float> textPadding(Float value) {
- return new LayoutProperty<>("text-padding", value);
- }
-
- /**
- * Size of the additional area around the text bounding box used for detecting symbol collisions.
- *
- * @param function a wrapper function for Float
- * @return property wrapper around a Float function
- */
- public static Property<Function<Float>> textPadding(Function<Float> function) {
- return new LayoutProperty<>("text-padding", function);
- }
-
- /**
- * If true, the text may be flipped vertically to prevent it from being rendered upside-down.
- *
- * @param value a Boolean value
- * @return property wrapper around Boolean
- */
- public static Property<Boolean> textKeepUpright(Boolean value) {
- return new LayoutProperty<>("text-keep-upright", value);
- }
-
- /**
- * If true, the text may be flipped vertically to prevent it from being rendered upside-down.
- *
- * @param function a wrapper function for Boolean
- * @return property wrapper around a Boolean function
- */
- public static Property<Function<Boolean>> textKeepUpright(Function<Boolean> function) {
- return new LayoutProperty<>("text-keep-upright", function);
- }
-
- /**
- * Specifies how to capitalize text, similar to the CSS {@link PropertyFactory#textTransform} property.
- *
- * @param value a String value
- * @return property wrapper around String
- */
- public static Property<String> textTransform(@Property.TEXT_TRANSFORM String value) {
- return new LayoutProperty<>("text-transform", value);
- }
-
- /**
- * Specifies how to capitalize text, similar to the CSS {@link PropertyFactory#textTransform} property.
- *
- * @param function a wrapper function for String
- * @return property wrapper around a String function
- */
- public static Property<Function<String>> textTransform(Function<String> function) {
- return new LayoutProperty<>("text-transform", function);
- }
-
- /**
- * Offset distance of text from its anchor. Positive values indicate right and down, while negative values indicate left and up.
- *
- * @param value a Float[] value
- * @return property wrapper around Float[]
- */
- public static Property<Float[]> textOffset(Float[] value) {
- return new LayoutProperty<>("text-offset", value);
- }
-
- /**
- * Offset distance of text from its anchor. Positive values indicate right and down, while negative values indicate left and up.
- *
- * @param function a wrapper function for Float[]
- * @return property wrapper around a Float[] function
- */
- public static Property<Function<Float[]>> textOffset(Function<Float[]> function) {
- return new LayoutProperty<>("text-offset", function);
- }
-
- /**
- * If true, the text will be visible even if it collides with other previously drawn symbols.
- *
- * @param value a Boolean value
- * @return property wrapper around Boolean
- */
- public static Property<Boolean> textAllowOverlap(Boolean value) {
- return new LayoutProperty<>("text-allow-overlap", value);
- }
-
- /**
- * If true, the text will be visible even if it collides with other previously drawn symbols.
- *
- * @param function a wrapper function for Boolean
- * @return property wrapper around a Boolean function
- */
- public static Property<Function<Boolean>> textAllowOverlap(Function<Boolean> function) {
- return new LayoutProperty<>("text-allow-overlap", function);
- }
-
- /**
- * If true, other symbols can be visible even if they collide with the text.
- *
- * @param value a Boolean value
- * @return property wrapper around Boolean
- */
- public static Property<Boolean> textIgnorePlacement(Boolean value) {
- return new LayoutProperty<>("text-ignore-placement", value);
- }
-
- /**
- * If true, other symbols can be visible even if they collide with the text.
- *
- * @param function a wrapper function for Boolean
- * @return property wrapper around a Boolean function
- */
- public static Property<Function<Boolean>> textIgnorePlacement(Function<Boolean> function) {
- return new LayoutProperty<>("text-ignore-placement", function);
- }
-
- /**
- * If true, icons will display without their corresponding text when the text collides with other symbols and the icon does not.
- *
- * @param value a Boolean value
- * @return property wrapper around Boolean
- */
- public static Property<Boolean> textOptional(Boolean value) {
- return new LayoutProperty<>("text-optional", value);
- }
-
- /**
- * If true, icons will display without their corresponding text when the text collides with other symbols and the icon does not.
- *
- * @param function a wrapper function for Boolean
- * @return property wrapper around a Boolean function
- */
- public static Property<Function<Boolean>> textOptional(Function<Boolean> function) {
- return new LayoutProperty<>("text-optional", function);
- }
-
- @SuppressLint("DefaultLocale")
- static String colorToRgbaString(@ColorInt int value) {
- return String.format("rgba(%d, %d, %d, %d)", (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF, (value >> 24) & 0xFF);
- }
+ /**
+ * Set the property visibility.
+ *
+ * @param value the visibility value
+ * @return property wrapper around visibility
+ */
+ public static Property<String> visibility(@Property.VISIBILITY String value) {
+ return new LayoutProperty<>("visibility", value);
+ }
+
+ /**
+ * Set the property visibility.
+ *
+ * @param function the visibility function
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> visibility(Function<String> function) {
+ return new LayoutProperty<>("visibility", function);
+ }
+
+ /**
+ * Whether or not the fill should be antialiased.
+ *
+ * @param value a Boolean value
+ * @return property wrapper around Boolean
+ */
+ public static Property<Boolean> fillAntialias(Boolean value) {
+ return new PaintProperty<>("fill-antialias", value);
+ }
+
+ /**
+ * Whether or not the fill should be antialiased.
+ *
+ * @param function a wrapper function for Boolean
+ * @return property wrapper around a Boolean function
+ */
+ public static Property<Function<Boolean>> fillAntialias(Function<Boolean> function) {
+ return new PaintProperty<>("fill-antialias", function);
+ }
+
+ /**
+ * The opacity of the entire fill layer. In contrast to the {@link PropertyFactory#fillColor}, this value will also
+ * affect the 1px stroke around the fill, if the stroke is used.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> fillOpacity(Float value) {
+ return new PaintProperty<>("fill-opacity", value);
+ }
+
+ /**
+ * The opacity of the entire fill layer. In contrast to the {@link PropertyFactory#fillColor}, this value will also
+ * affect the 1px stroke around the fill, if the stroke is used.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> fillOpacity(Function<Float> function) {
+ return new PaintProperty<>("fill-opacity", function);
+ }
+
+ /**
+ * 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 1px stroke, if it is used.
+ *
+ * @param value a int color value
+ * @return property wrapper around String color
+ */
+ public static Property<String> fillColor(@ColorInt int value) {
+ return new PaintProperty<>("fill-color", colorToRgbaString(value));
+ }
+
+ /**
+ * 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 1px stroke, if it is used.
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> fillColor(String value) {
+ return new PaintProperty<>("fill-color", value);
+ }
+
+ /**
+ * 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 1px stroke, if it is used.
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> fillColor(Function<String> function) {
+ return new PaintProperty<>("fill-color", function);
+ }
+
+ /**
+ * The outline color of the fill. Matches the value of {@link PropertyFactory#fillColor} if unspecified.
+ *
+ * @param value a int color value
+ * @return property wrapper around String color
+ */
+ public static Property<String> fillOutlineColor(@ColorInt int value) {
+ return new PaintProperty<>("fill-outline-color", colorToRgbaString(value));
+ }
+
+ /**
+ * The outline color of the fill. Matches the value of {@link PropertyFactory#fillColor} if unspecified.
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> fillOutlineColor(String value) {
+ return new PaintProperty<>("fill-outline-color", value);
+ }
+
+ /**
+ * The outline color of the fill. Matches the value of {@link PropertyFactory#fillColor} if unspecified.
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> fillOutlineColor(Function<String> function) {
+ return new PaintProperty<>("fill-outline-color", function);
+ }
+
+ /**
+ * The geometry's offset. Values are [x, y] where negatives indicate left and up, respectively.
+ *
+ * @param value a Float[] value
+ * @return property wrapper around Float[]
+ */
+ public static Property<Float[]> fillTranslate(Float[] value) {
+ return new PaintProperty<>("fill-translate", value);
+ }
+
+ /**
+ * The geometry's offset. Values are [x, y] where negatives indicate left and up, respectively.
+ *
+ * @param function a wrapper function for Float[]
+ * @return property wrapper around a Float[] function
+ */
+ public static Property<Function<Float[]>> fillTranslate(Function<Float[]> function) {
+ return new PaintProperty<>("fill-translate", function);
+ }
+
+ /**
+ * Controls the translation reference point.
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> fillTranslateAnchor(@Property.FILL_TRANSLATE_ANCHOR String value) {
+ return new PaintProperty<>("fill-translate-anchor", value);
+ }
+
+ /**
+ * Controls the translation reference point.
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> fillTranslateAnchor(Function<String> function) {
+ return new PaintProperty<>("fill-translate-anchor", function);
+ }
+
+ /**
+ * 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).
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> fillPattern(String value) {
+ return new PaintProperty<>("fill-pattern", value);
+ }
+
+ /**
+ * 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).
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> fillPattern(Function<String> function) {
+ return new PaintProperty<>("fill-pattern", function);
+ }
+
+ /**
+ * The opacity at which the line will be drawn.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> lineOpacity(Float value) {
+ return new PaintProperty<>("line-opacity", value);
+ }
+
+ /**
+ * The opacity at which the line will be drawn.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> lineOpacity(Function<Float> function) {
+ return new PaintProperty<>("line-opacity", function);
+ }
+
+ /**
+ * The color with which the line will be drawn.
+ *
+ * @param value a int color value
+ * @return property wrapper around String color
+ */
+ public static Property<String> lineColor(@ColorInt int value) {
+ return new PaintProperty<>("line-color", colorToRgbaString(value));
+ }
+
+ /**
+ * The color with which the line will be drawn.
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> lineColor(String value) {
+ return new PaintProperty<>("line-color", value);
+ }
+
+ /**
+ * The color with which the line will be drawn.
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> lineColor(Function<String> function) {
+ return new PaintProperty<>("line-color", function);
+ }
+
+ /**
+ * The geometry's offset. Values are [x, y] where negatives indicate left and up, respectively.
+ *
+ * @param value a Float[] value
+ * @return property wrapper around Float[]
+ */
+ public static Property<Float[]> lineTranslate(Float[] value) {
+ return new PaintProperty<>("line-translate", value);
+ }
+
+ /**
+ * The geometry's offset. Values are [x, y] where negatives indicate left and up, respectively.
+ *
+ * @param function a wrapper function for Float[]
+ * @return property wrapper around a Float[] function
+ */
+ public static Property<Function<Float[]>> lineTranslate(Function<Float[]> function) {
+ return new PaintProperty<>("line-translate", function);
+ }
+
+ /**
+ * Controls the translation reference point.
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> lineTranslateAnchor(@Property.LINE_TRANSLATE_ANCHOR String value) {
+ return new PaintProperty<>("line-translate-anchor", value);
+ }
+
+ /**
+ * Controls the translation reference point.
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> lineTranslateAnchor(Function<String> function) {
+ return new PaintProperty<>("line-translate-anchor", function);
+ }
+
+ /**
+ * Stroke thickness.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> lineWidth(Float value) {
+ return new PaintProperty<>("line-width", value);
+ }
+
+ /**
+ * Stroke thickness.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> lineWidth(Function<Float> function) {
+ return new PaintProperty<>("line-width", function);
+ }
+
+ /**
+ * Draws a line casing outside of a line's actual path. Value indicates the width of the inner gap.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> lineGapWidth(Float value) {
+ return new PaintProperty<>("line-gap-width", value);
+ }
+
+ /**
+ * Draws a line casing outside of a line's actual path. Value indicates the width of the inner gap.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> lineGapWidth(Function<Float> function) {
+ return new PaintProperty<>("line-gap-width", function);
+ }
+
+ /**
+ * 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.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> lineOffset(Float value) {
+ return new PaintProperty<>("line-offset", value);
+ }
+
+ /**
+ * 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.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> lineOffset(Function<Float> function) {
+ return new PaintProperty<>("line-offset", function);
+ }
+
+ /**
+ * Blur applied to the line, in pixels.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> lineBlur(Float value) {
+ return new PaintProperty<>("line-blur", value);
+ }
+
+ /**
+ * Blur applied to the line, in pixels.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> lineBlur(Function<Float> function) {
+ return new PaintProperty<>("line-blur", function);
+ }
+
+ /**
+ * 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 pixels, multiply the length by the current line width.
+ *
+ * @param value a Float[] value
+ * @return property wrapper around Float[]
+ */
+ public static Property<Float[]> lineDasharray(Float[] value) {
+ return new PaintProperty<>("line-dasharray", value);
+ }
+
+ /**
+ * 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 pixels, multiply the length by the current line width.
+ *
+ * @param function a wrapper function for Float[]
+ * @return property wrapper around a Float[] function
+ */
+ public static Property<Function<Float[]>> lineDasharray(Function<Float[]> function) {
+ return new PaintProperty<>("line-dasharray", function);
+ }
+
+ /**
+ * 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).
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> linePattern(String value) {
+ return new PaintProperty<>("line-pattern", value);
+ }
+
+ /**
+ * 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).
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> linePattern(Function<String> function) {
+ return new PaintProperty<>("line-pattern", function);
+ }
+
+ /**
+ * The opacity at which the icon will be drawn.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> iconOpacity(Float value) {
+ return new PaintProperty<>("icon-opacity", value);
+ }
+
+ /**
+ * The opacity at which the icon will be drawn.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> iconOpacity(Function<Float> function) {
+ return new PaintProperty<>("icon-opacity", function);
+ }
+
+ /**
+ * The color of the icon. This can only be used with sdf icons.
+ *
+ * @param value a int color value
+ * @return property wrapper around String color
+ */
+ public static Property<String> iconColor(@ColorInt int value) {
+ return new PaintProperty<>("icon-color", colorToRgbaString(value));
+ }
+
+ /**
+ * The color of the icon. This can only be used with sdf icons.
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> iconColor(String value) {
+ return new PaintProperty<>("icon-color", value);
+ }
+
+ /**
+ * The color of the icon. This can only be used with sdf icons.
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> iconColor(Function<String> function) {
+ return new PaintProperty<>("icon-color", function);
+ }
+
+ /**
+ * The color of the icon's halo. Icon halos can only be used with SDF icons.
+ *
+ * @param value a int color value
+ * @return property wrapper around String color
+ */
+ public static Property<String> iconHaloColor(@ColorInt int value) {
+ return new PaintProperty<>("icon-halo-color", colorToRgbaString(value));
+ }
+
+ /**
+ * The color of the icon's halo. Icon halos can only be used with SDF icons.
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> iconHaloColor(String value) {
+ return new PaintProperty<>("icon-halo-color", value);
+ }
+
+ /**
+ * The color of the icon's halo. Icon halos can only be used with SDF icons.
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> iconHaloColor(Function<String> function) {
+ return new PaintProperty<>("icon-halo-color", function);
+ }
+
+ /**
+ * Distance of halo to the icon outline.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> iconHaloWidth(Float value) {
+ return new PaintProperty<>("icon-halo-width", value);
+ }
+
+ /**
+ * Distance of halo to the icon outline.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> iconHaloWidth(Function<Float> function) {
+ return new PaintProperty<>("icon-halo-width", function);
+ }
+
+ /**
+ * Fade out the halo towards the outside.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> iconHaloBlur(Float value) {
+ return new PaintProperty<>("icon-halo-blur", value);
+ }
+
+ /**
+ * Fade out the halo towards the outside.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> iconHaloBlur(Function<Float> function) {
+ return new PaintProperty<>("icon-halo-blur", function);
+ }
+
+ /**
+ * 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.
+ *
+ * @param value a Float[] value
+ * @return property wrapper around Float[]
+ */
+ public static Property<Float[]> iconTranslate(Float[] value) {
+ return new PaintProperty<>("icon-translate", value);
+ }
+
+ /**
+ * 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.
+ *
+ * @param function a wrapper function for Float[]
+ * @return property wrapper around a Float[] function
+ */
+ public static Property<Function<Float[]>> iconTranslate(Function<Float[]> function) {
+ return new PaintProperty<>("icon-translate", function);
+ }
+
+ /**
+ * Controls the translation reference point.
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> iconTranslateAnchor(@Property.ICON_TRANSLATE_ANCHOR String value) {
+ return new PaintProperty<>("icon-translate-anchor", value);
+ }
+
+ /**
+ * Controls the translation reference point.
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> iconTranslateAnchor(Function<String> function) {
+ return new PaintProperty<>("icon-translate-anchor", function);
+ }
+
+ /**
+ * The opacity at which the text will be drawn.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> textOpacity(Float value) {
+ return new PaintProperty<>("text-opacity", value);
+ }
+
+ /**
+ * The opacity at which the text will be drawn.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> textOpacity(Function<Float> function) {
+ return new PaintProperty<>("text-opacity", function);
+ }
+
+ /**
+ * The color with which the text will be drawn.
+ *
+ * @param value a int color value
+ * @return property wrapper around String color
+ */
+ public static Property<String> textColor(@ColorInt int value) {
+ return new PaintProperty<>("text-color", colorToRgbaString(value));
+ }
+
+ /**
+ * The color with which the text will be drawn.
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> textColor(String value) {
+ return new PaintProperty<>("text-color", value);
+ }
+
+ /**
+ * The color with which the text will be drawn.
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> textColor(Function<String> function) {
+ return new PaintProperty<>("text-color", function);
+ }
+
+ /**
+ * The color of the text's halo, which helps it stand out from backgrounds.
+ *
+ * @param value a int color value
+ * @return property wrapper around String color
+ */
+ public static Property<String> textHaloColor(@ColorInt int value) {
+ return new PaintProperty<>("text-halo-color", colorToRgbaString(value));
+ }
+
+ /**
+ * The color of the text's halo, which helps it stand out from backgrounds.
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> textHaloColor(String value) {
+ return new PaintProperty<>("text-halo-color", value);
+ }
+
+ /**
+ * The color of the text's halo, which helps it stand out from backgrounds.
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> textHaloColor(Function<String> function) {
+ return new PaintProperty<>("text-halo-color", function);
+ }
+
+ /**
+ * Distance of halo to the font outline. Max text halo width is 1/4 of the font-size.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> textHaloWidth(Float value) {
+ return new PaintProperty<>("text-halo-width", value);
+ }
+
+ /**
+ * Distance of halo to the font outline. Max text halo width is 1/4 of the font-size.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> textHaloWidth(Function<Float> function) {
+ return new PaintProperty<>("text-halo-width", function);
+ }
+
+ /**
+ * The halo's fadeout distance towards the outside.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> textHaloBlur(Float value) {
+ return new PaintProperty<>("text-halo-blur", value);
+ }
+
+ /**
+ * The halo's fadeout distance towards the outside.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> textHaloBlur(Function<Float> function) {
+ return new PaintProperty<>("text-halo-blur", function);
+ }
+
+ /**
+ * 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.
+ *
+ * @param value a Float[] value
+ * @return property wrapper around Float[]
+ */
+ public static Property<Float[]> textTranslate(Float[] value) {
+ return new PaintProperty<>("text-translate", value);
+ }
+
+ /**
+ * 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.
+ *
+ * @param function a wrapper function for Float[]
+ * @return property wrapper around a Float[] function
+ */
+ public static Property<Function<Float[]>> textTranslate(Function<Float[]> function) {
+ return new PaintProperty<>("text-translate", function);
+ }
+
+ /**
+ * Controls the translation reference point.
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> textTranslateAnchor(@Property.TEXT_TRANSLATE_ANCHOR String value) {
+ return new PaintProperty<>("text-translate-anchor", value);
+ }
+
+ /**
+ * Controls the translation reference point.
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> textTranslateAnchor(Function<String> function) {
+ return new PaintProperty<>("text-translate-anchor", function);
+ }
+
+ /**
+ * Circle radius.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> circleRadius(Float value) {
+ return new PaintProperty<>("circle-radius", value);
+ }
+
+ /**
+ * Circle radius.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> circleRadius(Function<Float> function) {
+ return new PaintProperty<>("circle-radius", function);
+ }
+
+ /**
+ * The fill color of the circle.
+ *
+ * @param value a int color value
+ * @return property wrapper around String color
+ */
+ public static Property<String> circleColor(@ColorInt int value) {
+ return new PaintProperty<>("circle-color", colorToRgbaString(value));
+ }
+
+ /**
+ * The fill color of the circle.
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> circleColor(String value) {
+ return new PaintProperty<>("circle-color", value);
+ }
+
+ /**
+ * The fill color of the circle.
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> circleColor(Function<String> function) {
+ return new PaintProperty<>("circle-color", function);
+ }
+
+ /**
+ * Amount to blur the circle. 1 blurs the circle such that only the centerpoint is full opacity.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> circleBlur(Float value) {
+ return new PaintProperty<>("circle-blur", value);
+ }
+
+ /**
+ * Amount to blur the circle. 1 blurs the circle such that only the centerpoint is full opacity.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> circleBlur(Function<Float> function) {
+ return new PaintProperty<>("circle-blur", function);
+ }
+
+ /**
+ * The opacity at which the circle will be drawn.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> circleOpacity(Float value) {
+ return new PaintProperty<>("circle-opacity", value);
+ }
+
+ /**
+ * The opacity at which the circle will be drawn.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> circleOpacity(Function<Float> function) {
+ return new PaintProperty<>("circle-opacity", function);
+ }
+
+ /**
+ * The geometry's offset. Values are [x, y] where negatives indicate left and up, respectively.
+ *
+ * @param value a Float[] value
+ * @return property wrapper around Float[]
+ */
+ public static Property<Float[]> circleTranslate(Float[] value) {
+ return new PaintProperty<>("circle-translate", value);
+ }
+
+ /**
+ * The geometry's offset. Values are [x, y] where negatives indicate left and up, respectively.
+ *
+ * @param function a wrapper function for Float[]
+ * @return property wrapper around a Float[] function
+ */
+ public static Property<Function<Float[]>> circleTranslate(Function<Float[]> function) {
+ return new PaintProperty<>("circle-translate", function);
+ }
+
+ /**
+ * Controls the translation reference point.
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> circleTranslateAnchor(@Property.CIRCLE_TRANSLATE_ANCHOR String value) {
+ return new PaintProperty<>("circle-translate-anchor", value);
+ }
+
+ /**
+ * Controls the translation reference point.
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> circleTranslateAnchor(Function<String> function) {
+ return new PaintProperty<>("circle-translate-anchor", function);
+ }
+
+ /**
+ * Controls the scaling behavior of the circle when the map is pitched.
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> circlePitchScale(@Property.CIRCLE_PITCH_SCALE String value) {
+ return new PaintProperty<>("circle-pitch-scale", value);
+ }
+
+ /**
+ * Controls the scaling behavior of the circle when the map is pitched.
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> circlePitchScale(Function<String> function) {
+ return new PaintProperty<>("circle-pitch-scale", function);
+ }
+
+ /**
+ * The width of the circle's stroke. Strokes are placed outside of the "circle-radius".
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> circleStrokeWidth(Float value) {
+ return new PaintProperty<>("circle-stroke-width", value);
+ }
+
+ /**
+ * The width of the circle's stroke. Strokes are placed outside of the "circle-radius".
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> circleStrokeWidth(Function<Float> function) {
+ return new PaintProperty<>("circle-stroke-width", function);
+ }
+
+ /**
+ * The stroke color of the circle.
+ *
+ * @param value a int color value
+ * @return property wrapper around String color
+ */
+ public static Property<String> circleStrokeColor(@ColorInt int value) {
+ return new PaintProperty<>("circle-stroke-color", colorToRgbaString(value));
+ }
+
+ /**
+ * The stroke color of the circle.
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> circleStrokeColor(String value) {
+ return new PaintProperty<>("circle-stroke-color", value);
+ }
+
+ /**
+ * The stroke color of the circle.
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> circleStrokeColor(Function<String> function) {
+ return new PaintProperty<>("circle-stroke-color", function);
+ }
+
+ /**
+ * The opacity of the circle's stroke.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> circleStrokeOpacity(Float value) {
+ return new PaintProperty<>("circle-stroke-opacity", value);
+ }
+
+ /**
+ * The opacity of the circle's stroke.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> circleStrokeOpacity(Function<Float> function) {
+ return new PaintProperty<>("circle-stroke-opacity", function);
+ }
+
+ /**
+ * The opacity at which the image will be drawn.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> rasterOpacity(Float value) {
+ return new PaintProperty<>("raster-opacity", value);
+ }
+
+ /**
+ * The opacity at which the image will be drawn.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> rasterOpacity(Function<Float> function) {
+ return new PaintProperty<>("raster-opacity", function);
+ }
+
+ /**
+ * Rotates hues around the color wheel.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> rasterHueRotate(Float value) {
+ return new PaintProperty<>("raster-hue-rotate", value);
+ }
+
+ /**
+ * Rotates hues around the color wheel.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> rasterHueRotate(Function<Float> function) {
+ return new PaintProperty<>("raster-hue-rotate", function);
+ }
+
+ /**
+ * Increase or reduce the brightness of the image. The value is the minimum brightness.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> rasterBrightnessMin(Float value) {
+ return new PaintProperty<>("raster-brightness-min", value);
+ }
+
+ /**
+ * Increase or reduce the brightness of the image. The value is the minimum brightness.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> rasterBrightnessMin(Function<Float> function) {
+ return new PaintProperty<>("raster-brightness-min", function);
+ }
+
+ /**
+ * Increase or reduce the brightness of the image. The value is the maximum brightness.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> rasterBrightnessMax(Float value) {
+ return new PaintProperty<>("raster-brightness-max", value);
+ }
+
+ /**
+ * Increase or reduce the brightness of the image. The value is the maximum brightness.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> rasterBrightnessMax(Function<Float> function) {
+ return new PaintProperty<>("raster-brightness-max", function);
+ }
+
+ /**
+ * Increase or reduce the saturation of the image.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> rasterSaturation(Float value) {
+ return new PaintProperty<>("raster-saturation", value);
+ }
+
+ /**
+ * Increase or reduce the saturation of the image.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> rasterSaturation(Function<Float> function) {
+ return new PaintProperty<>("raster-saturation", function);
+ }
+
+ /**
+ * Increase or reduce the contrast of the image.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> rasterContrast(Float value) {
+ return new PaintProperty<>("raster-contrast", value);
+ }
+
+ /**
+ * Increase or reduce the contrast of the image.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> rasterContrast(Function<Float> function) {
+ return new PaintProperty<>("raster-contrast", function);
+ }
+
+ /**
+ * Fade duration when a new tile is added.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> rasterFadeDuration(Float value) {
+ return new PaintProperty<>("raster-fade-duration", value);
+ }
+
+ /**
+ * Fade duration when a new tile is added.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> rasterFadeDuration(Function<Float> function) {
+ return new PaintProperty<>("raster-fade-duration", function);
+ }
+
+ /**
+ * The color with which the background will be drawn.
+ *
+ * @param value a int color value
+ * @return property wrapper around String color
+ */
+ public static Property<String> backgroundColor(@ColorInt int value) {
+ return new PaintProperty<>("background-color", colorToRgbaString(value));
+ }
+
+ /**
+ * The color with which the background will be drawn.
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> backgroundColor(String value) {
+ return new PaintProperty<>("background-color", value);
+ }
+
+ /**
+ * The color with which the background will be drawn.
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> backgroundColor(Function<String> function) {
+ return new PaintProperty<>("background-color", function);
+ }
+
+ /**
+ * 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).
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> backgroundPattern(String value) {
+ return new PaintProperty<>("background-pattern", value);
+ }
+
+ /**
+ * 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).
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> backgroundPattern(Function<String> function) {
+ return new PaintProperty<>("background-pattern", function);
+ }
+
+ /**
+ * The opacity at which the background will be drawn.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> backgroundOpacity(Float value) {
+ return new PaintProperty<>("background-opacity", value);
+ }
+
+ /**
+ * The opacity at which the background will be drawn.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> backgroundOpacity(Function<Float> function) {
+ return new PaintProperty<>("background-opacity", function);
+ }
+
+ /**
+ * The display of line endings.
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> lineCap(@Property.LINE_CAP String value) {
+ return new LayoutProperty<>("line-cap", value);
+ }
+
+ /**
+ * The display of line endings.
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> lineCap(Function<String> function) {
+ return new LayoutProperty<>("line-cap", function);
+ }
+
+ /**
+ * The display of lines when joining.
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> lineJoin(@Property.LINE_JOIN String value) {
+ return new LayoutProperty<>("line-join", value);
+ }
+
+ /**
+ * The display of lines when joining.
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> lineJoin(Function<String> function) {
+ return new LayoutProperty<>("line-join", function);
+ }
+
+ /**
+ * Used to automatically convert miter joins to bevel joins for sharp angles.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> lineMiterLimit(Float value) {
+ return new LayoutProperty<>("line-miter-limit", value);
+ }
+
+ /**
+ * Used to automatically convert miter joins to bevel joins for sharp angles.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> lineMiterLimit(Function<Float> function) {
+ return new LayoutProperty<>("line-miter-limit", function);
+ }
+
+ /**
+ * Used to automatically convert round joins to miter joins for shallow angles.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> lineRoundLimit(Float value) {
+ return new LayoutProperty<>("line-round-limit", value);
+ }
+
+ /**
+ * Used to automatically convert round joins to miter joins for shallow angles.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> lineRoundLimit(Function<Float> function) {
+ return new LayoutProperty<>("line-round-limit", function);
+ }
+
+ /**
+ * Label placement relative to its geometry.
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> symbolPlacement(@Property.SYMBOL_PLACEMENT String value) {
+ return new LayoutProperty<>("symbol-placement", value);
+ }
+
+ /**
+ * Label placement relative to its geometry.
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> symbolPlacement(Function<String> function) {
+ return new LayoutProperty<>("symbol-placement", function);
+ }
+
+ /**
+ * Distance between two symbol anchors.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> symbolSpacing(Float value) {
+ return new LayoutProperty<>("symbol-spacing", value);
+ }
+
+ /**
+ * Distance between two symbol anchors.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> symbolSpacing(Function<Float> function) {
+ return new LayoutProperty<>("symbol-spacing", function);
+ }
+
+ /**
+ * 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.
+ *
+ * @param value a Boolean value
+ * @return property wrapper around Boolean
+ */
+ public static Property<Boolean> symbolAvoidEdges(Boolean value) {
+ return new LayoutProperty<>("symbol-avoid-edges", value);
+ }
+
+ /**
+ * 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.
+ *
+ * @param function a wrapper function for Boolean
+ * @return property wrapper around a Boolean function
+ */
+ public static Property<Function<Boolean>> symbolAvoidEdges(Function<Boolean> function) {
+ return new LayoutProperty<>("symbol-avoid-edges", function);
+ }
+
+ /**
+ * If true, the icon will be visible even if it collides with other previously drawn symbols.
+ *
+ * @param value a Boolean value
+ * @return property wrapper around Boolean
+ */
+ public static Property<Boolean> iconAllowOverlap(Boolean value) {
+ return new LayoutProperty<>("icon-allow-overlap", value);
+ }
+
+ /**
+ * If true, the icon will be visible even if it collides with other previously drawn symbols.
+ *
+ * @param function a wrapper function for Boolean
+ * @return property wrapper around a Boolean function
+ */
+ public static Property<Function<Boolean>> iconAllowOverlap(Function<Boolean> function) {
+ return new LayoutProperty<>("icon-allow-overlap", function);
+ }
+
+ /**
+ * If true, other symbols can be visible even if they collide with the icon.
+ *
+ * @param value a Boolean value
+ * @return property wrapper around Boolean
+ */
+ public static Property<Boolean> iconIgnorePlacement(Boolean value) {
+ return new LayoutProperty<>("icon-ignore-placement", value);
+ }
+
+ /**
+ * If true, other symbols can be visible even if they collide with the icon.
+ *
+ * @param function a wrapper function for Boolean
+ * @return property wrapper around a Boolean function
+ */
+ public static Property<Function<Boolean>> iconIgnorePlacement(Function<Boolean> function) {
+ return new LayoutProperty<>("icon-ignore-placement", function);
+ }
+
+ /**
+ * If true, text will display without their corresponding icons when the icon collides with other symbols and the
+ * text does not.
+ *
+ * @param value a Boolean value
+ * @return property wrapper around Boolean
+ */
+ public static Property<Boolean> iconOptional(Boolean value) {
+ return new LayoutProperty<>("icon-optional", value);
+ }
+
+ /**
+ * If true, text will display without their corresponding icons when the icon collides with other symbols and the
+ * text does not.
+ *
+ * @param function a wrapper function for Boolean
+ * @return property wrapper around a Boolean function
+ */
+ public static Property<Function<Boolean>> iconOptional(Function<Boolean> function) {
+ return new LayoutProperty<>("icon-optional", function);
+ }
+
+ /**
+ * In combination with {@link Property.SYMBOL_PLACEMENT}, determines the rotation behavior of icons.
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> iconRotationAlignment(@Property.ICON_ROTATION_ALIGNMENT String value) {
+ return new LayoutProperty<>("icon-rotation-alignment", value);
+ }
+
+ /**
+ * In combination with {@link Property.SYMBOL_PLACEMENT}, determines the rotation behavior of icons.
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> iconRotationAlignment(Function<String> function) {
+ return new LayoutProperty<>("icon-rotation-alignment", function);
+ }
+
+ /**
+ * Scale factor for icon. 1 is original size, 3 triples the size.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> iconSize(Float value) {
+ return new LayoutProperty<>("icon-size", value);
+ }
+
+ /**
+ * Scale factor for icon. 1 is original size, 3 triples the size.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> iconSize(Function<Float> function) {
+ return new LayoutProperty<>("icon-size", function);
+ }
+
+ /**
+ * Scales the icon to fit around the associated text.
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> iconTextFit(@Property.ICON_TEXT_FIT String value) {
+ return new LayoutProperty<>("icon-text-fit", value);
+ }
+
+ /**
+ * Scales the icon to fit around the associated text.
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> iconTextFit(Function<String> function) {
+ return new LayoutProperty<>("icon-text-fit", function);
+ }
+
+ /**
+ * Size of the additional area added to dimensions determined by {@link Property.ICON_TEXT_FIT}, in clockwise order:
+ * top, right, bottom, left.
+ *
+ * @param value a Float[] value
+ * @return property wrapper around Float[]
+ */
+ public static Property<Float[]> iconTextFitPadding(Float[] value) {
+ return new LayoutProperty<>("icon-text-fit-padding", value);
+ }
+
+ /**
+ * Size of the additional area added to dimensions determined by {@link Property.ICON_TEXT_FIT}, in clockwise order:
+ * top, right, bottom, left.
+ *
+ * @param function a wrapper function for Float[]
+ * @return property wrapper around a Float[] function
+ */
+ public static Property<Function<Float[]>> iconTextFitPadding(Function<Float[]> function) {
+ return new LayoutProperty<>("icon-text-fit-padding", function);
+ }
+
+ /**
+ * A string with {tokens} replaced, referencing the data property to pull from.
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> iconImage(String value) {
+ return new LayoutProperty<>("icon-image", value);
+ }
+
+ /**
+ * A string with {tokens} replaced, referencing the data property to pull from.
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> iconImage(Function<String> function) {
+ return new LayoutProperty<>("icon-image", function);
+ }
+
+ /**
+ * Rotates the icon clockwise.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> iconRotate(Float value) {
+ return new LayoutProperty<>("icon-rotate", value);
+ }
+
+ /**
+ * Rotates the icon clockwise.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> iconRotate(Function<Float> function) {
+ return new LayoutProperty<>("icon-rotate", function);
+ }
+
+ /**
+ * Size of the additional area around the icon bounding box used for detecting symbol collisions.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> iconPadding(Float value) {
+ return new LayoutProperty<>("icon-padding", value);
+ }
+
+ /**
+ * Size of the additional area around the icon bounding box used for detecting symbol collisions.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> iconPadding(Function<Float> function) {
+ return new LayoutProperty<>("icon-padding", function);
+ }
+
+ /**
+ * If true, the icon may be flipped to prevent it from being rendered upside-down.
+ *
+ * @param value a Boolean value
+ * @return property wrapper around Boolean
+ */
+ public static Property<Boolean> iconKeepUpright(Boolean value) {
+ return new LayoutProperty<>("icon-keep-upright", value);
+ }
+
+ /**
+ * If true, the icon may be flipped to prevent it from being rendered upside-down.
+ *
+ * @param function a wrapper function for Boolean
+ * @return property wrapper around a Boolean function
+ */
+ public static Property<Function<Boolean>> iconKeepUpright(Function<Boolean> function) {
+ return new LayoutProperty<>("icon-keep-upright", function);
+ }
+
+ /**
+ * Offset distance of icon from its anchor. Positive values indicate right and down, while negative values indicate
+ * left and up.
+ *
+ * @param value a Float[] value
+ * @return property wrapper around Float[]
+ */
+ public static Property<Float[]> iconOffset(Float[] value) {
+ return new LayoutProperty<>("icon-offset", value);
+ }
+
+ /**
+ * Offset distance of icon from its anchor. Positive values indicate right and down, while negative values indicate
+ * left and up.
+ *
+ * @param function a wrapper function for Float[]
+ * @return property wrapper around a Float[] function
+ */
+ public static Property<Function<Float[]>> iconOffset(Function<Float[]> function) {
+ return new LayoutProperty<>("icon-offset", function);
+ }
+
+ /**
+ * Orientation of text when map is pitched.
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> textPitchAlignment(@Property.TEXT_PITCH_ALIGNMENT String value) {
+ return new LayoutProperty<>("text-pitch-alignment", value);
+ }
+
+ /**
+ * Orientation of text when map is pitched.
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> textPitchAlignment(Function<String> function) {
+ return new LayoutProperty<>("text-pitch-alignment", function);
+ }
+
+ /**
+ * In combination with {@link Property.SYMBOL_PLACEMENT}, determines the rotation behavior of the individual glyphs
+ * forming the text.
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> textRotationAlignment(@Property.TEXT_ROTATION_ALIGNMENT String value) {
+ return new LayoutProperty<>("text-rotation-alignment", value);
+ }
+
+ /**
+ * In combination with {@link Property.SYMBOL_PLACEMENT}, determines the rotation behavior of the individual glyphs
+ * forming the text.
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> textRotationAlignment(Function<String> function) {
+ return new LayoutProperty<>("text-rotation-alignment", function);
+ }
+
+ /**
+ * Value to use for a text label. Feature properties are specified using tokens like {field_name}.
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> textField(String value) {
+ return new LayoutProperty<>("text-field", value);
+ }
+
+ /**
+ * Value to use for a text label. Feature properties are specified using tokens like {field_name}.
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> textField(Function<String> function) {
+ return new LayoutProperty<>("text-field", function);
+ }
+
+ /**
+ * Font stack to use for displaying text.
+ *
+ * @param value a String[] value
+ * @return property wrapper around String[]
+ */
+ public static Property<String[]> textFont(String[] value) {
+ return new LayoutProperty<>("text-font", value);
+ }
+
+ /**
+ * Font stack to use for displaying text.
+ *
+ * @param function a wrapper function for String[]
+ * @return property wrapper around a String[] function
+ */
+ public static Property<Function<String[]>> textFont(Function<String[]> function) {
+ return new LayoutProperty<>("text-font", function);
+ }
+
+ /**
+ * Font size.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> textSize(Float value) {
+ return new LayoutProperty<>("text-size", value);
+ }
+
+ /**
+ * Font size.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> textSize(Function<Float> function) {
+ return new LayoutProperty<>("text-size", function);
+ }
+
+ /**
+ * The maximum line width for text wrapping.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> textMaxWidth(Float value) {
+ return new LayoutProperty<>("text-max-width", value);
+ }
+
+ /**
+ * The maximum line width for text wrapping.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> textMaxWidth(Function<Float> function) {
+ return new LayoutProperty<>("text-max-width", function);
+ }
+
+ /**
+ * Text leading value for multi-line text.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> textLineHeight(Float value) {
+ return new LayoutProperty<>("text-line-height", value);
+ }
+
+ /**
+ * Text leading value for multi-line text.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> textLineHeight(Function<Float> function) {
+ return new LayoutProperty<>("text-line-height", function);
+ }
+
+ /**
+ * Text tracking amount.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> textLetterSpacing(Float value) {
+ return new LayoutProperty<>("text-letter-spacing", value);
+ }
+
+ /**
+ * Text tracking amount.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> textLetterSpacing(Function<Float> function) {
+ return new LayoutProperty<>("text-letter-spacing", function);
+ }
+
+ /**
+ * Text justification options.
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> textJustify(@Property.TEXT_JUSTIFY String value) {
+ return new LayoutProperty<>("text-justify", value);
+ }
+
+ /**
+ * Text justification options.
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> textJustify(Function<String> function) {
+ return new LayoutProperty<>("text-justify", function);
+ }
+
+ /**
+ * Part of the text placed closest to the anchor.
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> textAnchor(@Property.TEXT_ANCHOR String value) {
+ return new LayoutProperty<>("text-anchor", value);
+ }
+
+ /**
+ * Part of the text placed closest to the anchor.
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> textAnchor(Function<String> function) {
+ return new LayoutProperty<>("text-anchor", function);
+ }
+
+ /**
+ * Maximum angle change between adjacent characters.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> textMaxAngle(Float value) {
+ return new LayoutProperty<>("text-max-angle", value);
+ }
+
+ /**
+ * Maximum angle change between adjacent characters.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> textMaxAngle(Function<Float> function) {
+ return new LayoutProperty<>("text-max-angle", function);
+ }
+
+ /**
+ * Rotates the text clockwise.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> textRotate(Float value) {
+ return new LayoutProperty<>("text-rotate", value);
+ }
+
+ /**
+ * Rotates the text clockwise.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> textRotate(Function<Float> function) {
+ return new LayoutProperty<>("text-rotate", function);
+ }
+
+ /**
+ * Size of the additional area around the text bounding box used for detecting symbol collisions.
+ *
+ * @param value a Float value
+ * @return property wrapper around Float
+ */
+ public static Property<Float> textPadding(Float value) {
+ return new LayoutProperty<>("text-padding", value);
+ }
+
+ /**
+ * Size of the additional area around the text bounding box used for detecting symbol collisions.
+ *
+ * @param function a wrapper function for Float
+ * @return property wrapper around a Float function
+ */
+ public static Property<Function<Float>> textPadding(Function<Float> function) {
+ return new LayoutProperty<>("text-padding", function);
+ }
+
+ /**
+ * If true, the text may be flipped vertically to prevent it from being rendered upside-down.
+ *
+ * @param value a Boolean value
+ * @return property wrapper around Boolean
+ */
+ public static Property<Boolean> textKeepUpright(Boolean value) {
+ return new LayoutProperty<>("text-keep-upright", value);
+ }
+
+ /**
+ * If true, the text may be flipped vertically to prevent it from being rendered upside-down.
+ *
+ * @param function a wrapper function for Boolean
+ * @return property wrapper around a Boolean function
+ */
+ public static Property<Function<Boolean>> textKeepUpright(Function<Boolean> function) {
+ return new LayoutProperty<>("text-keep-upright", function);
+ }
+
+ /**
+ * Specifies how to capitalize text, similar to the CSS {@link PropertyFactory#textTransform} property.
+ *
+ * @param value a String value
+ * @return property wrapper around String
+ */
+ public static Property<String> textTransform(@Property.TEXT_TRANSFORM String value) {
+ return new LayoutProperty<>("text-transform", value);
+ }
+
+ /**
+ * Specifies how to capitalize text, similar to the CSS {@link PropertyFactory#textTransform} property.
+ *
+ * @param function a wrapper function for String
+ * @return property wrapper around a String function
+ */
+ public static Property<Function<String>> textTransform(Function<String> function) {
+ return new LayoutProperty<>("text-transform", function);
+ }
+
+ /**
+ * Offset distance of text from its anchor. Positive values indicate right and down, while negative values indicate
+ * left and up.
+ *
+ * @param value a Float[] value
+ * @return property wrapper around Float[]
+ */
+ public static Property<Float[]> textOffset(Float[] value) {
+ return new LayoutProperty<>("text-offset", value);
+ }
+
+ /**
+ * Offset distance of text from its anchor. Positive values indicate right and down, while negative values indicate
+ * left and up.
+ *
+ * @param function a wrapper function for Float[]
+ * @return property wrapper around a Float[] function
+ */
+ public static Property<Function<Float[]>> textOffset(Function<Float[]> function) {
+ return new LayoutProperty<>("text-offset", function);
+ }
+
+ /**
+ * If true, the text will be visible even if it collides with other previously drawn symbols.
+ *
+ * @param value a Boolean value
+ * @return property wrapper around Boolean
+ */
+ public static Property<Boolean> textAllowOverlap(Boolean value) {
+ return new LayoutProperty<>("text-allow-overlap", value);
+ }
+
+ /**
+ * If true, the text will be visible even if it collides with other previously drawn symbols.
+ *
+ * @param function a wrapper function for Boolean
+ * @return property wrapper around a Boolean function
+ */
+ public static Property<Function<Boolean>> textAllowOverlap(Function<Boolean> function) {
+ return new LayoutProperty<>("text-allow-overlap", function);
+ }
+
+ /**
+ * If true, other symbols can be visible even if they collide with the text.
+ *
+ * @param value a Boolean value
+ * @return property wrapper around Boolean
+ */
+ public static Property<Boolean> textIgnorePlacement(Boolean value) {
+ return new LayoutProperty<>("text-ignore-placement", value);
+ }
+
+ /**
+ * If true, other symbols can be visible even if they collide with the text.
+ *
+ * @param function a wrapper function for Boolean
+ * @return property wrapper around a Boolean function
+ */
+ public static Property<Function<Boolean>> textIgnorePlacement(Function<Boolean> function) {
+ return new LayoutProperty<>("text-ignore-placement", function);
+ }
+
+ /**
+ * If true, icons will display without their corresponding text when the text collides with other symbols and the
+ * icon does not.
+ *
+ * @param value a Boolean value
+ * @return property wrapper around Boolean
+ */
+ public static Property<Boolean> textOptional(Boolean value) {
+ return new LayoutProperty<>("text-optional", value);
+ }
+
+ /**
+ * If true, icons will display without their corresponding text when the text collides with other symbols and the
+ * icon does not.
+ *
+ * @param function a wrapper function for Boolean
+ * @return property wrapper around a Boolean function
+ */
+ public static Property<Function<Boolean>> textOptional(Function<Boolean> function) {
+ return new LayoutProperty<>("text-optional", function);
+ }
+
+ @SuppressLint("DefaultLocale")
+ static String colorToRgbaString(@ColorInt int value) {
+ return String.format("rgba(%d, %d, %d, %d)", (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF,
+ (value >> 24) & 0xFF);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyValue.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyValue.java
index 204c154743..c404f07c76 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyValue.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyValue.java
@@ -1,56 +1,57 @@
package com.mapbox.mapboxsdk.style.layers;
import android.support.annotation.Nullable;
-import android.util.Log;
+
+import timber.log.Timber;
/**
* Properties for Layer
*/
public class PropertyValue<T> {
- private static final String TAG = PropertyValue.class.getSimpleName();
- private final Object value;
+ private final Object value;
- /* package */ PropertyValue(Object value) {
- this.value = value;
- }
+ /* package */ PropertyValue(Object value) {
+ this.value = value;
+ }
- public boolean isNull() {
- return value == null;
- }
+ public boolean isNull() {
+ return value == null;
+ }
- public boolean isFunction() {
- return !isNull() && value instanceof Function;
- }
+ public boolean isFunction() {
+ return !isNull() && value instanceof Function;
+ }
- public boolean isValue() {
- return !isNull() && !isFunction();
- }
+ public boolean isValue() {
+ return !isNull() && !isFunction();
+ }
- @Nullable
- public Function<T> getFunction() {
- if (isFunction()) {
- //noinspection unchecked
- return (Function<T>) value;
- } else {
- Log.w(TAG, "not a function, try value");
- return null;
- }
+ @Nullable
+ public Function<T> getFunction() {
+ if (isFunction()) {
+ //noinspection unchecked
+ return (Function<T>) value;
+ } else {
+ Timber.w("not a function, try value");
+ return null;
}
-
- @Nullable
- public T getValue() {
- if (isValue()) {
- //noinspection unchecked
- return (T) value;
- } else {
- Log.w(TAG, "not a value, try function");
- return null;
- }
+ }
+
+ @Nullable
+ public T getValue() {
+ if (isValue()) {
+ //noinspection unchecked
+ return (T) value;
+ } else {
+ Timber.w("not a value, try function");
+ return null;
}
+ }
- @Override
- public String toString() {
- return String.format("%s (%s)", getClass().getSimpleName(), value != null ? value.getClass().getSimpleName() : null);
- }
+ @Override
+ public String toString() {
+ return String.format("%s (%s)", getClass().getSimpleName(), value != null
+ ? value.getClass().getSimpleName() : null);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/RasterLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/RasterLayer.java
index e5f33aced6..785106c394 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/RasterLayer.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/RasterLayer.java
@@ -1,168 +1,157 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
package com.mapbox.mapboxsdk.style.layers;
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
-import com.mapbox.mapboxsdk.exceptions.ConversionException;
-
-import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
-
-import static com.mapbox.mapboxsdk.utils.ColorUtils.*;
+import android.support.annotation.UiThread;
/**
* Raster map textures such as satellite imagery.
*
* @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#layers-raster">The online documentation</a>
*/
+@UiThread
public class RasterLayer extends Layer {
- /**
- * Creates a RasterLayer.
- *
- * @param nativePtr pointer used by core
- */
- public RasterLayer(long nativePtr) {
- super(nativePtr);
- }
-
- /**
- * Creates a RasterLayer.
- *
- * @param layerId the id of the layer
- * @param sourceId the id of the source
- */
- public RasterLayer(String layerId, String sourceId) {
- initialize(layerId, sourceId);
- }
-
- protected native void initialize(String layerId, String sourceId);
-
- /**
- * Set the source layer.
- *
- * @param sourceLayer the source layer to set
- */
- public void setSourceLayer(String sourceLayer) {
- checkValidity();
- nativeSetSourceLayer(sourceLayer);
- }
-
- /**
- * Set the source Layer.
- *
- * @param sourceLayer the source layer to set
- * @return This
- */
- public RasterLayer withSourceLayer(String sourceLayer) {
- setSourceLayer(sourceLayer);
- return this;
- }
-
- /**
- * Set a property or properties.
- *
- * @param properties the var-args properties
- * @return This
- */
- public RasterLayer withProperties(@NonNull Property<?>... properties) {
- setProperties(properties);
- return this;
- }
-
- // Property getters
-
- /**
- * Get the RasterOpacity property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getRasterOpacity() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetRasterOpacity());
- }
-
- /**
- * Get the RasterHueRotate property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getRasterHueRotate() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetRasterHueRotate());
- }
-
- /**
- * Get the RasterBrightnessMin property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getRasterBrightnessMin() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetRasterBrightnessMin());
- }
-
- /**
- * Get the RasterBrightnessMax property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getRasterBrightnessMax() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetRasterBrightnessMax());
- }
-
- /**
- * Get the RasterSaturation property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getRasterSaturation() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetRasterSaturation());
- }
-
- /**
- * Get the RasterContrast property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getRasterContrast() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetRasterContrast());
- }
-
- /**
- * Get the RasterFadeDuration property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getRasterFadeDuration() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetRasterFadeDuration());
- }
-
- private native Object nativeGetRasterOpacity();
-
- private native Object nativeGetRasterHueRotate();
-
- private native Object nativeGetRasterBrightnessMin();
-
- private native Object nativeGetRasterBrightnessMax();
-
- private native Object nativeGetRasterSaturation();
-
- private native Object nativeGetRasterContrast();
-
- private native Object nativeGetRasterFadeDuration();
-
-
- @Override
- protected native void finalize() throws Throwable;
+ /**
+ * Creates a RasterLayer.
+ *
+ * @param nativePtr pointer used by core
+ */
+ public RasterLayer(long nativePtr) {
+ super(nativePtr);
+ }
+
+ /**
+ * Creates a RasterLayer.
+ *
+ * @param layerId the id of the layer
+ * @param sourceId the id of the source
+ */
+ public RasterLayer(String layerId, String sourceId) {
+ initialize(layerId, sourceId);
+ }
+
+ protected native void initialize(String layerId, String sourceId);
+
+ /**
+ * Set the source layer.
+ *
+ * @param sourceLayer the source layer to set
+ */
+ public void setSourceLayer(String sourceLayer) {
+ nativeSetSourceLayer(sourceLayer);
+ }
+
+ /**
+ * Set the source Layer.
+ *
+ * @param sourceLayer the source layer to set
+ * @return This
+ */
+ public RasterLayer withSourceLayer(String sourceLayer) {
+ setSourceLayer(sourceLayer);
+ return this;
+ }
+
+ /**
+ * Set a property or properties.
+ *
+ * @param properties the var-args properties
+ * @return This
+ */
+ public RasterLayer withProperties(@NonNull Property<?>... properties) {
+ setProperties(properties);
+ return this;
+ }
+
+ // Property getters
+
+ /**
+ * Get the RasterOpacity property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getRasterOpacity() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetRasterOpacity());
+ }
+
+ /**
+ * Get the RasterHueRotate property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getRasterHueRotate() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetRasterHueRotate());
+ }
+
+ /**
+ * Get the RasterBrightnessMin property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getRasterBrightnessMin() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetRasterBrightnessMin());
+ }
+
+ /**
+ * Get the RasterBrightnessMax property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getRasterBrightnessMax() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetRasterBrightnessMax());
+ }
+
+ /**
+ * Get the RasterSaturation property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getRasterSaturation() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetRasterSaturation());
+ }
+
+ /**
+ * Get the RasterContrast property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getRasterContrast() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetRasterContrast());
+ }
+
+ /**
+ * Get the RasterFadeDuration property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getRasterFadeDuration() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetRasterFadeDuration());
+ }
+
+ private native Object nativeGetRasterOpacity();
+
+ private native Object nativeGetRasterHueRotate();
+
+ private native Object nativeGetRasterBrightnessMin();
+
+ private native Object nativeGetRasterBrightnessMax();
+
+ private native Object nativeGetRasterSaturation();
+
+ private native Object nativeGetRasterContrast();
+
+ private native Object nativeGetRasterFadeDuration();
+
+
+ @Override
+ protected native void finalize() throws Throwable;
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/SymbolLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/SymbolLayer.java
index 4ceebd8bc1..abc516d6d0 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/SymbolLayer.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/SymbolLayer.java
@@ -1,811 +1,761 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
package com.mapbox.mapboxsdk.style.layers;
-
-import com.mapbox.mapboxsdk.exceptions.ConversionException;
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
+import android.support.annotation.UiThread;
-import static com.mapbox.mapboxsdk.utils.ColorUtils.*;
+import static com.mapbox.mapboxsdk.utils.ColorUtils.rgbaToColor;
/**
* An icon or a text label.
*
* @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#layers-symbol">The online documentation</a>
*/
+@UiThread
public class SymbolLayer extends Layer {
- /**
- * Creates a SymbolLayer.
- *
- * @param nativePtr pointer used by core
- */
- public SymbolLayer(long nativePtr) {
- super(nativePtr);
- }
-
- /**
- * Creates a SymbolLayer.
- *
- * @param layerId the id of the layer
- * @param sourceId the id of the source
- */
- public SymbolLayer(String layerId, String sourceId) {
- initialize(layerId, sourceId);
- }
-
- protected native void initialize(String layerId, String sourceId);
-
- /**
- * Set the source layer.
- *
- * @param sourceLayer the source layer to set
- */
- public void setSourceLayer(String sourceLayer) {
- checkValidity();
- nativeSetSourceLayer(sourceLayer);
- }
-
- /**
- * Set the source Layer.
- *
- * @param sourceLayer the source layer to set
- * @return This
- */
- public SymbolLayer withSourceLayer(String sourceLayer) {
- setSourceLayer(sourceLayer);
- return this;
- }
- /**
- * Set a single filter.
- *
- * @param filter the filter to set
- */
- public void setFilter(Filter.Statement filter) {
- checkValidity();
- this.setFilter(filter.toArray());
- }
-
- /**
- * Set an array of filters.
- *
- * @param filter the filter array to set
- */
- public void setFilter(Object[] filter) {
- checkValidity();
- nativeSetFilter(filter);
- }
-
- /**
- * Set an array of filters.
- *
- * @param filter tthe filter array to set
- * @return This
- */
- public SymbolLayer withFilter(Object[] filter) {
- setFilter(filter);
- return this;
- }
-
- /**
- * Set a single filter.
- *
- * @param filter the filter to set
- * @return This
- */
- public SymbolLayer withFilter(Filter.Statement filter) {
- setFilter(filter);
- return this;
- }
-
-
- /**
- * Set a property or properties.
- *
- * @param properties the var-args properties
- * @return This
- */
- public SymbolLayer withProperties(@NonNull Property<?>... properties) {
- setProperties(properties);
- return this;
- }
-
- // Property getters
-
- /**
- * Get the SymbolPlacement property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getSymbolPlacement() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetSymbolPlacement());
- }
-
- /**
- * Get the SymbolSpacing property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getSymbolSpacing() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetSymbolSpacing());
- }
-
- /**
- * Get the SymbolAvoidEdges property
- *
- * @return property wrapper value around Boolean
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Boolean> getSymbolAvoidEdges() {
- checkValidity();
- return (PropertyValue<Boolean>) new PropertyValue(nativeGetSymbolAvoidEdges());
- }
-
- /**
- * Get the IconAllowOverlap property
- *
- * @return property wrapper value around Boolean
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Boolean> getIconAllowOverlap() {
- checkValidity();
- return (PropertyValue<Boolean>) new PropertyValue(nativeGetIconAllowOverlap());
- }
-
- /**
- * Get the IconIgnorePlacement property
- *
- * @return property wrapper value around Boolean
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Boolean> getIconIgnorePlacement() {
- checkValidity();
- return (PropertyValue<Boolean>) new PropertyValue(nativeGetIconIgnorePlacement());
- }
-
- /**
- * Get the IconOptional property
- *
- * @return property wrapper value around Boolean
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Boolean> getIconOptional() {
- checkValidity();
- return (PropertyValue<Boolean>) new PropertyValue(nativeGetIconOptional());
- }
-
- /**
- * Get the IconRotationAlignment property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getIconRotationAlignment() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetIconRotationAlignment());
- }
-
- /**
- * Get the IconSize property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getIconSize() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetIconSize());
- }
-
- /**
- * Get the IconTextFit property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getIconTextFit() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetIconTextFit());
- }
-
- /**
- * Get the IconTextFitPadding property
- *
- * @return property wrapper value around Float[]
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float[]> getIconTextFitPadding() {
- checkValidity();
- return (PropertyValue<Float[]>) new PropertyValue(nativeGetIconTextFitPadding());
- }
-
- /**
- * Get the IconImage property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getIconImage() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetIconImage());
- }
-
- /**
- * Get the IconRotate property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getIconRotate() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetIconRotate());
- }
-
- /**
- * Get the IconPadding property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getIconPadding() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetIconPadding());
- }
-
- /**
- * Get the IconKeepUpright property
- *
- * @return property wrapper value around Boolean
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Boolean> getIconKeepUpright() {
- checkValidity();
- return (PropertyValue<Boolean>) new PropertyValue(nativeGetIconKeepUpright());
- }
-
- /**
- * Get the IconOffset property
- *
- * @return property wrapper value around Float[]
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float[]> getIconOffset() {
- checkValidity();
- return (PropertyValue<Float[]>) new PropertyValue(nativeGetIconOffset());
- }
-
- /**
- * Get the TextPitchAlignment property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getTextPitchAlignment() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetTextPitchAlignment());
- }
-
- /**
- * Get the TextRotationAlignment property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getTextRotationAlignment() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetTextRotationAlignment());
- }
-
- /**
- * Get the TextField property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getTextField() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetTextField());
- }
-
- /**
- * Get the TextFont property
- *
- * @return property wrapper value around String[]
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String[]> getTextFont() {
- checkValidity();
- return (PropertyValue<String[]>) new PropertyValue(nativeGetTextFont());
- }
-
- /**
- * Get the TextSize property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getTextSize() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetTextSize());
- }
-
- /**
- * Get the TextMaxWidth property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getTextMaxWidth() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetTextMaxWidth());
- }
-
- /**
- * Get the TextLineHeight property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getTextLineHeight() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetTextLineHeight());
- }
-
- /**
- * Get the TextLetterSpacing property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getTextLetterSpacing() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetTextLetterSpacing());
- }
-
- /**
- * Get the TextJustify property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getTextJustify() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetTextJustify());
- }
-
- /**
- * Get the TextAnchor property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getTextAnchor() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetTextAnchor());
- }
-
- /**
- * Get the TextMaxAngle property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getTextMaxAngle() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetTextMaxAngle());
- }
-
- /**
- * Get the TextRotate property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getTextRotate() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetTextRotate());
- }
-
- /**
- * Get the TextPadding property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getTextPadding() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetTextPadding());
- }
-
- /**
- * Get the TextKeepUpright property
- *
- * @return property wrapper value around Boolean
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Boolean> getTextKeepUpright() {
- checkValidity();
- return (PropertyValue<Boolean>) new PropertyValue(nativeGetTextKeepUpright());
- }
-
- /**
- * Get the TextTransform property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getTextTransform() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetTextTransform());
- }
-
- /**
- * Get the TextOffset property
- *
- * @return property wrapper value around Float[]
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float[]> getTextOffset() {
- checkValidity();
- return (PropertyValue<Float[]>) new PropertyValue(nativeGetTextOffset());
- }
-
- /**
- * Get the TextAllowOverlap property
- *
- * @return property wrapper value around Boolean
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Boolean> getTextAllowOverlap() {
- checkValidity();
- return (PropertyValue<Boolean>) new PropertyValue(nativeGetTextAllowOverlap());
- }
-
- /**
- * Get the TextIgnorePlacement property
- *
- * @return property wrapper value around Boolean
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Boolean> getTextIgnorePlacement() {
- checkValidity();
- return (PropertyValue<Boolean>) new PropertyValue(nativeGetTextIgnorePlacement());
- }
-
- /**
- * Get the TextOptional property
- *
- * @return property wrapper value around Boolean
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Boolean> getTextOptional() {
- checkValidity();
- return (PropertyValue<Boolean>) new PropertyValue(nativeGetTextOptional());
- }
-
- /**
- * Get the IconOpacity property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getIconOpacity() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetIconOpacity());
- }
-
- /**
- * Get the IconColor property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getIconColor() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetIconColor());
- }
- /**
- * The color of the icon. This can only be used with sdf icons.
- *
- * @return int representation of a rgba string color
- * @throws RuntimeException thrown if property isn't a value
- */
- @ColorInt
- public int getIconColorAsInt() {
- checkValidity();
- PropertyValue<String> value = getIconColor();
- if (value.isValue()) {
- return rgbaToColor(value.getValue());
- } else {
- throw new RuntimeException("icon-color was set as a Function");
- }
- }
+ /**
+ * Creates a SymbolLayer.
+ *
+ * @param nativePtr pointer used by core
+ */
+ public SymbolLayer(long nativePtr) {
+ super(nativePtr);
+ }
+
+ /**
+ * Creates a SymbolLayer.
+ *
+ * @param layerId the id of the layer
+ * @param sourceId the id of the source
+ */
+ public SymbolLayer(String layerId, String sourceId) {
+ initialize(layerId, sourceId);
+ }
+
+ protected native void initialize(String layerId, String sourceId);
+
+ /**
+ * Set the source layer.
+ *
+ * @param sourceLayer the source layer to set
+ */
+ public void setSourceLayer(String sourceLayer) {
+ nativeSetSourceLayer(sourceLayer);
+ }
+
+ /**
+ * Set the source Layer.
+ *
+ * @param sourceLayer the source layer to set
+ * @return This
+ */
+ public SymbolLayer withSourceLayer(String sourceLayer) {
+ setSourceLayer(sourceLayer);
+ return this;
+ }
+
+ /**
+ * Set a single filter.
+ *
+ * @param filter the filter to set
+ */
+ public void setFilter(Filter.Statement filter) {
+ this.setFilter(filter.toArray());
+ }
+
+ /**
+ * Set an array of filters.
+ *
+ * @param filter the filter array to set
+ */
+ public void setFilter(Object[] filter) {
+ nativeSetFilter(filter);
+ }
+
+ /**
+ * Set an array of filters.
+ *
+ * @param filter tthe filter array to set
+ * @return This
+ */
+ public SymbolLayer withFilter(Object[] filter) {
+ setFilter(filter);
+ return this;
+ }
+
+ /**
+ * Set a single filter.
+ *
+ * @param filter the filter to set
+ * @return This
+ */
+ public SymbolLayer withFilter(Filter.Statement filter) {
+ setFilter(filter);
+ return this;
+ }
+
+
+ /**
+ * Set a property or properties.
+ *
+ * @param properties the var-args properties
+ * @return This
+ */
+ public SymbolLayer withProperties(@NonNull Property<?>... properties) {
+ setProperties(properties);
+ return this;
+ }
+
+ // Property getters
+
+ /**
+ * Get the SymbolPlacement property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getSymbolPlacement() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetSymbolPlacement());
+ }
+
+ /**
+ * Get the SymbolSpacing property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getSymbolSpacing() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetSymbolSpacing());
+ }
+
+ /**
+ * Get the SymbolAvoidEdges property
+ *
+ * @return property wrapper value around Boolean
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Boolean> getSymbolAvoidEdges() {
+ return (PropertyValue<Boolean>) new PropertyValue(nativeGetSymbolAvoidEdges());
+ }
+
+ /**
+ * Get the IconAllowOverlap property
+ *
+ * @return property wrapper value around Boolean
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Boolean> getIconAllowOverlap() {
+ return (PropertyValue<Boolean>) new PropertyValue(nativeGetIconAllowOverlap());
+ }
+
+ /**
+ * Get the IconIgnorePlacement property
+ *
+ * @return property wrapper value around Boolean
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Boolean> getIconIgnorePlacement() {
+ return (PropertyValue<Boolean>) new PropertyValue(nativeGetIconIgnorePlacement());
+ }
+
+ /**
+ * Get the IconOptional property
+ *
+ * @return property wrapper value around Boolean
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Boolean> getIconOptional() {
+ return (PropertyValue<Boolean>) new PropertyValue(nativeGetIconOptional());
+ }
+
+ /**
+ * Get the IconRotationAlignment property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getIconRotationAlignment() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetIconRotationAlignment());
+ }
+
+ /**
+ * Get the IconSize property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getIconSize() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetIconSize());
+ }
+
+ /**
+ * Get the IconTextFit property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getIconTextFit() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetIconTextFit());
+ }
+
+ /**
+ * Get the IconTextFitPadding property
+ *
+ * @return property wrapper value around Float[]
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float[]> getIconTextFitPadding() {
+ return (PropertyValue<Float[]>) new PropertyValue(nativeGetIconTextFitPadding());
+ }
+
+ /**
+ * Get the IconImage property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getIconImage() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetIconImage());
+ }
+
+ /**
+ * Get the IconRotate property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getIconRotate() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetIconRotate());
+ }
+
+ /**
+ * Get the IconPadding property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getIconPadding() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetIconPadding());
+ }
+
+ /**
+ * Get the IconKeepUpright property
+ *
+ * @return property wrapper value around Boolean
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Boolean> getIconKeepUpright() {
+ return (PropertyValue<Boolean>) new PropertyValue(nativeGetIconKeepUpright());
+ }
+
+ /**
+ * Get the IconOffset property
+ *
+ * @return property wrapper value around Float[]
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float[]> getIconOffset() {
+ return (PropertyValue<Float[]>) new PropertyValue(nativeGetIconOffset());
+ }
+
+ /**
+ * Get the TextPitchAlignment property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getTextPitchAlignment() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetTextPitchAlignment());
+ }
+
+ /**
+ * Get the TextRotationAlignment property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getTextRotationAlignment() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetTextRotationAlignment());
+ }
+
+ /**
+ * Get the TextField property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getTextField() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetTextField());
+ }
+
+ /**
+ * Get the TextFont property
+ *
+ * @return property wrapper value around String[]
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String[]> getTextFont() {
+ return (PropertyValue<String[]>) new PropertyValue(nativeGetTextFont());
+ }
+
+ /**
+ * Get the TextSize property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getTextSize() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetTextSize());
+ }
+
+ /**
+ * Get the TextMaxWidth property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getTextMaxWidth() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetTextMaxWidth());
+ }
+
+ /**
+ * Get the TextLineHeight property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getTextLineHeight() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetTextLineHeight());
+ }
+
+ /**
+ * Get the TextLetterSpacing property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getTextLetterSpacing() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetTextLetterSpacing());
+ }
+
+ /**
+ * Get the TextJustify property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getTextJustify() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetTextJustify());
+ }
+
+ /**
+ * Get the TextAnchor property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getTextAnchor() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetTextAnchor());
+ }
+
+ /**
+ * Get the TextMaxAngle property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getTextMaxAngle() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetTextMaxAngle());
+ }
+
+ /**
+ * Get the TextRotate property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getTextRotate() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetTextRotate());
+ }
+
+ /**
+ * Get the TextPadding property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getTextPadding() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetTextPadding());
+ }
+
+ /**
+ * Get the TextKeepUpright property
+ *
+ * @return property wrapper value around Boolean
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Boolean> getTextKeepUpright() {
+ return (PropertyValue<Boolean>) new PropertyValue(nativeGetTextKeepUpright());
+ }
+
+ /**
+ * Get the TextTransform property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getTextTransform() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetTextTransform());
+ }
+
+ /**
+ * Get the TextOffset property
+ *
+ * @return property wrapper value around Float[]
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float[]> getTextOffset() {
+ return (PropertyValue<Float[]>) new PropertyValue(nativeGetTextOffset());
+ }
+
+ /**
+ * Get the TextAllowOverlap property
+ *
+ * @return property wrapper value around Boolean
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Boolean> getTextAllowOverlap() {
+ return (PropertyValue<Boolean>) new PropertyValue(nativeGetTextAllowOverlap());
+ }
+
+ /**
+ * Get the TextIgnorePlacement property
+ *
+ * @return property wrapper value around Boolean
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Boolean> getTextIgnorePlacement() {
+ return (PropertyValue<Boolean>) new PropertyValue(nativeGetTextIgnorePlacement());
+ }
+
+ /**
+ * Get the TextOptional property
+ *
+ * @return property wrapper value around Boolean
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Boolean> getTextOptional() {
+ return (PropertyValue<Boolean>) new PropertyValue(nativeGetTextOptional());
+ }
+
+ /**
+ * Get the IconOpacity property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getIconOpacity() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetIconOpacity());
+ }
+
+ /**
+ * Get the IconColor property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getIconColor() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetIconColor());
+ }
+
+ /**
+ * The color of the icon. This can only be used with sdf icons.
+ *
+ * @return int representation of a rgba string color
+ * @throws RuntimeException thrown if property isn't a value
+ */
+ @ColorInt
+ public int getIconColorAsInt() {
+ PropertyValue<String> value = getIconColor();
+ if (value.isValue()) {
+ return rgbaToColor(value.getValue());
+ } else {
+ throw new RuntimeException("icon-color was set as a Function");
+ }
+ }
+
+
+ /**
+ * Get the IconHaloColor property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getIconHaloColor() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetIconHaloColor());
+ }
+
+ /**
+ * The color of the icon's halo. Icon halos can only be used with SDF icons.
+ *
+ * @return int representation of a rgba string color
+ * @throws RuntimeException thrown if property isn't a value
+ */
+ @ColorInt
+ public int getIconHaloColorAsInt() {
+ PropertyValue<String> value = getIconHaloColor();
+ if (value.isValue()) {
+ return rgbaToColor(value.getValue());
+ } else {
+ throw new RuntimeException("icon-halo-color was set as a Function");
+ }
+ }
+
+
+ /**
+ * Get the IconHaloWidth property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getIconHaloWidth() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetIconHaloWidth());
+ }
+
+ /**
+ * Get the IconHaloBlur property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getIconHaloBlur() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetIconHaloBlur());
+ }
+
+ /**
+ * Get the IconTranslate property
+ *
+ * @return property wrapper value around Float[]
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float[]> getIconTranslate() {
+ return (PropertyValue<Float[]>) new PropertyValue(nativeGetIconTranslate());
+ }
+
+ /**
+ * Get the IconTranslateAnchor property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getIconTranslateAnchor() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetIconTranslateAnchor());
+ }
+
+ /**
+ * Get the TextOpacity property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getTextOpacity() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetTextOpacity());
+ }
+
+ /**
+ * Get the TextColor property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getTextColor() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetTextColor());
+ }
+
+ /**
+ * The color with which the text will be drawn.
+ *
+ * @return int representation of a rgba string color
+ * @throws RuntimeException thrown if property isn't a value
+ */
+ @ColorInt
+ public int getTextColorAsInt() {
+ PropertyValue<String> value = getTextColor();
+ if (value.isValue()) {
+ return rgbaToColor(value.getValue());
+ } else {
+ throw new RuntimeException("text-color was set as a Function");
+ }
+ }
+
+
+ /**
+ * Get the TextHaloColor property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getTextHaloColor() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetTextHaloColor());
+ }
+
+ /**
+ * The color of the text's halo, which helps it stand out from backgrounds.
+ *
+ * @return int representation of a rgba string color
+ * @throws RuntimeException thrown if property isn't a value
+ */
+ @ColorInt
+ public int getTextHaloColorAsInt() {
+ PropertyValue<String> value = getTextHaloColor();
+ if (value.isValue()) {
+ return rgbaToColor(value.getValue());
+ } else {
+ throw new RuntimeException("text-halo-color was set as a Function");
+ }
+ }
+
+
+ /**
+ * Get the TextHaloWidth property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getTextHaloWidth() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetTextHaloWidth());
+ }
-
- /**
- * Get the IconHaloColor property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getIconHaloColor() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetIconHaloColor());
- }
- /**
- * The color of the icon's halo. Icon halos can only be used with SDF icons.
- *
- * @return int representation of a rgba string color
- * @throws RuntimeException thrown if property isn't a value
- */
- @ColorInt
- public int getIconHaloColorAsInt() {
- checkValidity();
- PropertyValue<String> value = getIconHaloColor();
- if (value.isValue()) {
- return rgbaToColor(value.getValue());
- } else {
- throw new RuntimeException("icon-halo-color was set as a Function");
- }
- }
+ /**
+ * Get the TextHaloBlur property
+ *
+ * @return property wrapper value around Float
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float> getTextHaloBlur() {
+ return (PropertyValue<Float>) new PropertyValue(nativeGetTextHaloBlur());
+ }
-
- /**
- * Get the IconHaloWidth property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getIconHaloWidth() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetIconHaloWidth());
- }
-
- /**
- * Get the IconHaloBlur property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getIconHaloBlur() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetIconHaloBlur());
- }
-
- /**
- * Get the IconTranslate property
- *
- * @return property wrapper value around Float[]
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float[]> getIconTranslate() {
- checkValidity();
- return (PropertyValue<Float[]>) new PropertyValue(nativeGetIconTranslate());
- }
-
- /**
- * Get the IconTranslateAnchor property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getIconTranslateAnchor() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetIconTranslateAnchor());
- }
-
- /**
- * Get the TextOpacity property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getTextOpacity() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetTextOpacity());
- }
-
- /**
- * Get the TextColor property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getTextColor() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetTextColor());
- }
- /**
- * The color with which the text will be drawn.
- *
- * @return int representation of a rgba string color
- * @throws RuntimeException thrown if property isn't a value
- */
- @ColorInt
- public int getTextColorAsInt() {
- checkValidity();
- PropertyValue<String> value = getTextColor();
- if (value.isValue()) {
- return rgbaToColor(value.getValue());
- } else {
- throw new RuntimeException("text-color was set as a Function");
- }
- }
+ /**
+ * Get the TextTranslate property
+ *
+ * @return property wrapper value around Float[]
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<Float[]> getTextTranslate() {
+ return (PropertyValue<Float[]>) new PropertyValue(nativeGetTextTranslate());
+ }
-
- /**
- * Get the TextHaloColor property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getTextHaloColor() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetTextHaloColor());
- }
- /**
- * The color of the text's halo, which helps it stand out from backgrounds.
- *
- * @return int representation of a rgba string color
- * @throws RuntimeException thrown if property isn't a value
- */
- @ColorInt
- public int getTextHaloColorAsInt() {
- checkValidity();
- PropertyValue<String> value = getTextHaloColor();
- if (value.isValue()) {
- return rgbaToColor(value.getValue());
- } else {
- throw new RuntimeException("text-halo-color was set as a Function");
- }
- }
+ /**
+ * Get the TextTranslateAnchor property
+ *
+ * @return property wrapper value around String
+ */
+ @SuppressWarnings("unchecked")
+ public PropertyValue<String> getTextTranslateAnchor() {
+ return (PropertyValue<String>) new PropertyValue(nativeGetTextTranslateAnchor());
+ }
-
- /**
- * Get the TextHaloWidth property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getTextHaloWidth() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetTextHaloWidth());
- }
-
- /**
- * Get the TextHaloBlur property
- *
- * @return property wrapper value around Float
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float> getTextHaloBlur() {
- checkValidity();
- return (PropertyValue<Float>) new PropertyValue(nativeGetTextHaloBlur());
- }
-
- /**
- * Get the TextTranslate property
- *
- * @return property wrapper value around Float[]
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<Float[]> getTextTranslate() {
- checkValidity();
- return (PropertyValue<Float[]>) new PropertyValue(nativeGetTextTranslate());
- }
-
- /**
- * Get the TextTranslateAnchor property
- *
- * @return property wrapper value around String
- */
- @SuppressWarnings("unchecked")
- public PropertyValue<String> getTextTranslateAnchor() {
- checkValidity();
- return (PropertyValue<String>) new PropertyValue(nativeGetTextTranslateAnchor());
- }
-
- private native Object nativeGetSymbolPlacement();
+ private native Object nativeGetSymbolPlacement();
- private native Object nativeGetSymbolSpacing();
+ private native Object nativeGetSymbolSpacing();
- private native Object nativeGetSymbolAvoidEdges();
+ private native Object nativeGetSymbolAvoidEdges();
- private native Object nativeGetIconAllowOverlap();
+ private native Object nativeGetIconAllowOverlap();
- private native Object nativeGetIconIgnorePlacement();
+ private native Object nativeGetIconIgnorePlacement();
- private native Object nativeGetIconOptional();
+ private native Object nativeGetIconOptional();
- private native Object nativeGetIconRotationAlignment();
+ private native Object nativeGetIconRotationAlignment();
- private native Object nativeGetIconSize();
+ private native Object nativeGetIconSize();
- private native Object nativeGetIconTextFit();
+ private native Object nativeGetIconTextFit();
- private native Object nativeGetIconTextFitPadding();
+ private native Object nativeGetIconTextFitPadding();
- private native Object nativeGetIconImage();
+ private native Object nativeGetIconImage();
- private native Object nativeGetIconRotate();
+ private native Object nativeGetIconRotate();
- private native Object nativeGetIconPadding();
+ private native Object nativeGetIconPadding();
- private native Object nativeGetIconKeepUpright();
+ private native Object nativeGetIconKeepUpright();
- private native Object nativeGetIconOffset();
+ private native Object nativeGetIconOffset();
- private native Object nativeGetTextPitchAlignment();
+ private native Object nativeGetTextPitchAlignment();
- private native Object nativeGetTextRotationAlignment();
+ private native Object nativeGetTextRotationAlignment();
- private native Object nativeGetTextField();
+ private native Object nativeGetTextField();
- private native Object nativeGetTextFont();
+ private native Object nativeGetTextFont();
- private native Object nativeGetTextSize();
+ private native Object nativeGetTextSize();
- private native Object nativeGetTextMaxWidth();
+ private native Object nativeGetTextMaxWidth();
- private native Object nativeGetTextLineHeight();
+ private native Object nativeGetTextLineHeight();
- private native Object nativeGetTextLetterSpacing();
+ private native Object nativeGetTextLetterSpacing();
- private native Object nativeGetTextJustify();
+ private native Object nativeGetTextJustify();
- private native Object nativeGetTextAnchor();
+ private native Object nativeGetTextAnchor();
- private native Object nativeGetTextMaxAngle();
+ private native Object nativeGetTextMaxAngle();
- private native Object nativeGetTextRotate();
+ private native Object nativeGetTextRotate();
- private native Object nativeGetTextPadding();
+ private native Object nativeGetTextPadding();
- private native Object nativeGetTextKeepUpright();
+ private native Object nativeGetTextKeepUpright();
- private native Object nativeGetTextTransform();
+ private native Object nativeGetTextTransform();
- private native Object nativeGetTextOffset();
+ private native Object nativeGetTextOffset();
- private native Object nativeGetTextAllowOverlap();
+ private native Object nativeGetTextAllowOverlap();
- private native Object nativeGetTextIgnorePlacement();
+ private native Object nativeGetTextIgnorePlacement();
- private native Object nativeGetTextOptional();
+ private native Object nativeGetTextOptional();
- private native Object nativeGetIconOpacity();
+ private native Object nativeGetIconOpacity();
- private native Object nativeGetIconColor();
+ private native Object nativeGetIconColor();
- private native Object nativeGetIconHaloColor();
+ private native Object nativeGetIconHaloColor();
- private native Object nativeGetIconHaloWidth();
+ private native Object nativeGetIconHaloWidth();
- private native Object nativeGetIconHaloBlur();
+ private native Object nativeGetIconHaloBlur();
- private native Object nativeGetIconTranslate();
+ private native Object nativeGetIconTranslate();
- private native Object nativeGetIconTranslateAnchor();
+ private native Object nativeGetIconTranslateAnchor();
- private native Object nativeGetTextOpacity();
+ private native Object nativeGetTextOpacity();
- private native Object nativeGetTextColor();
+ private native Object nativeGetTextColor();
- private native Object nativeGetTextHaloColor();
+ private native Object nativeGetTextHaloColor();
- private native Object nativeGetTextHaloWidth();
+ private native Object nativeGetTextHaloWidth();
- private native Object nativeGetTextHaloBlur();
+ private native Object nativeGetTextHaloBlur();
- private native Object nativeGetTextTranslate();
+ private native Object nativeGetTextTranslate();
- private native Object nativeGetTextTranslateAnchor();
+ private native Object nativeGetTextTranslateAnchor();
- @Override
- protected native void finalize() throws Throwable;
+ @Override
+ protected native void finalize() throws Throwable;
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/layer.java.ejs b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/layer.java.ejs
index f7865c6b6c..4657037df8 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/layer.java.ejs
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/layer.java.ejs
@@ -3,10 +3,10 @@
const properties = locals.properties;
const doc = locals.doc;
-%>
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
package com.mapbox.mapboxsdk.style.layers;
-import com.mapbox.mapboxsdk.exceptions.ConversionException;
+import android.support.annotation.UiThread;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
@@ -18,6 +18,7 @@ import static com.mapbox.mapboxsdk.utils.ColorUtils.*;
*
* @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#layers-<%- type %>">The online documentation</a>
*/
+@UiThread
public class <%- camelize(type) %>Layer extends Layer {
/**
@@ -59,7 +60,6 @@ public class <%- camelize(type) %>Layer extends Layer {
* @param sourceLayer the source layer to set
*/
public void setSourceLayer(String sourceLayer) {
- checkValidity();
nativeSetSourceLayer(sourceLayer);
}
@@ -81,7 +81,6 @@ public class <%- camelize(type) %>Layer extends Layer {
* @param filter the filter to set
*/
public void setFilter(Filter.Statement filter) {
- checkValidity();
this.setFilter(filter.toArray());
}
@@ -91,7 +90,6 @@ public class <%- camelize(type) %>Layer extends Layer {
* @param filter the filter array to set
*/
public void setFilter(Object[] filter) {
- checkValidity();
nativeSetFilter(filter);
}
@@ -140,7 +138,6 @@ public class <%- camelize(type) %>Layer extends Layer {
*/
@SuppressWarnings("unchecked")
public PropertyValue<<%- propertyType(property) %>> get<%- camelize(property.name) %>() {
- checkValidity();
return (PropertyValue<<%- propertyType(property) %>>) new PropertyValue(nativeGet<%- camelize(property.name) %>());
}
<% if (property.type == 'color') { -%>
@@ -152,7 +149,6 @@ public class <%- camelize(type) %>Layer extends Layer {
*/
@ColorInt
public int get<%- camelize(property.name) %>AsInt() {
- checkValidity();
PropertyValue<<%- propertyType(property) %>> value = get<%- camelize(property.name) %>();
if (value.isValue()) {
return rgbaToColor(value.getValue());
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property.java.ejs b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property.java.ejs
index bad6f87a8e..3ce691775c 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property.java.ejs
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property.java.ejs
@@ -1,7 +1,7 @@
<%
const properties = locals.properties;
-%>
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
package com.mapbox.mapboxsdk.style.layers;
import android.support.annotation.StringDef;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property_factory.java.ejs b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property_factory.java.ejs
index a6e2aff839..e9b7b6dcd1 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property_factory.java.ejs
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property_factory.java.ejs
@@ -2,7 +2,7 @@
const paintProperties = locals.paintProperties;
const layoutProperties = locals.layoutProperties;
-%>
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
package com.mapbox.mapboxsdk.style.layers;
import android.annotation.SuppressLint;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CannotAddSourceException.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CannotAddSourceException.java
new file mode 100644
index 0000000000..ddc4c58cf1
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/CannotAddSourceException.java
@@ -0,0 +1,12 @@
+package com.mapbox.mapboxsdk.style.sources;
+
+/**
+ * Thrown when adding a source to a map twice
+ */
+public class CannotAddSourceException extends RuntimeException {
+
+ public CannotAddSourceException(String message) {
+ super(message);
+ }
+
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonOptions.java
index 55a9799cb7..27a3d5c898 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonOptions.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonOptions.java
@@ -9,70 +9,72 @@ import java.util.HashMap;
*/
public class GeoJsonOptions extends HashMap<String, Object> {
- /**
- * Maximum zoom level at which to create vector tiles (higher means greater detail at high zoom levels).
- *
- * @param maxZoom the maximum zoom - Defaults to 18.
- * @return the current instance for chaining
- */
- public GeoJsonOptions withMaxZoom(int maxZoom) {
- this.put("maxzoom", maxZoom);
- return this;
- }
+ /**
+ * Maximum zoom level at which to create vector tiles (higher means greater detail at high zoom levels).
+ *
+ * @param maxZoom the maximum zoom - Defaults to 18.
+ * @return the current instance for chaining
+ */
+ public GeoJsonOptions withMaxZoom(int maxZoom) {
+ this.put("maxzoom", maxZoom);
+ return this;
+ }
- /**
- * Tile buffer size on each side (measured in 1/512ths of a tile; higher means fewer rendering artifacts near tile edges but slower performance).
- *
- * @param buffer the buffer size - Defaults to 128.
- * @return the current instance for chaining
- */
- public GeoJsonOptions withBuffer(int buffer) {
- this.put("buffer", buffer);
- return this;
- }
+ /**
+ * Tile buffer size on each side (measured in 1/512ths of a tile; higher means fewer rendering artifacts near tile
+ * edges but slower performance).
+ *
+ * @param buffer the buffer size - Defaults to 128.
+ * @return the current instance for chaining
+ */
+ public GeoJsonOptions withBuffer(int buffer) {
+ this.put("buffer", buffer);
+ return this;
+ }
- /**
- * Douglas-Peucker simplification tolerance (higher means simpler geometries and faster performance).
- *
- * @param tolerance the tolerance - Defaults to 0.375
- * @return the current instance for chaining
- */
- public GeoJsonOptions withTolerance(float tolerance) {
- this.put("tolerance", tolerance);
- return this;
- }
+ /**
+ * Douglas-Peucker simplification tolerance (higher means simpler geometries and faster performance).
+ *
+ * @param tolerance the tolerance - Defaults to 0.375
+ * @return the current instance for chaining
+ */
+ public GeoJsonOptions withTolerance(float tolerance) {
+ this.put("tolerance", tolerance);
+ return this;
+ }
- /**
- * If the data is a collection of point features, setting this to true clusters the points by radius into groups.
- *
- * @param cluster cluster? - Defaults to false
- * @return the current instance for chaining
- */
- public GeoJsonOptions withCluster(boolean cluster) {
- this.put("cluster", cluster);
- return this;
- }
+ /**
+ * If the data is a collection of point features, setting this to true clusters the points by radius into groups.
+ *
+ * @param cluster cluster? - Defaults to false
+ * @return the current instance for chaining
+ */
+ public GeoJsonOptions withCluster(boolean cluster) {
+ this.put("cluster", cluster);
+ return this;
+ }
- /**
- * Max zoom to cluster points on.
- *
- * @param clusterMaxZoom clusterMaxZoom cluster maximum zoom - Defaults to one zoom less than maxzoom (so that last zoom features are not clustered)
- * @return the current instance for chaining
- */
- public GeoJsonOptions withClusterMaxZoom(int clusterMaxZoom) {
- this.put("clusterMaxZoom", clusterMaxZoom);
- return this;
- }
+ /**
+ * Max zoom to cluster points on.
+ *
+ * @param clusterMaxZoom clusterMaxZoom cluster maximum zoom - Defaults to one zoom less than maxzoom (so that last
+ * zoom features are not clustered)
+ * @return the current instance for chaining
+ */
+ public GeoJsonOptions withClusterMaxZoom(int clusterMaxZoom) {
+ this.put("clusterMaxZoom", clusterMaxZoom);
+ return this;
+ }
- /**
- * Radius of each cluster when clustering points, measured in 1/512ths of a tile.
- *
- * @param clusterRadius cluster radius - Defaults to 50
- * @return the current instance for chaining
- */
- public GeoJsonOptions withClusterRadius(int clusterRadius) {
- this.put("clusterRadius", clusterRadius);
- return this;
- }
+ /**
+ * Radius of each cluster when clustering points, measured in 1/512ths of a tile.
+ *
+ * @param clusterRadius cluster radius - Defaults to 50
+ * @return the current instance for chaining
+ */
+ public GeoJsonOptions withClusterRadius(int clusterRadius) {
+ this.put("clusterRadius", clusterRadius);
+ return this;
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonSource.java
index 80730d143c..0c2ee42ea0 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonSource.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonSource.java
@@ -14,166 +14,166 @@ import java.util.HashMap;
*/
public class GeoJsonSource extends Source {
- /**
- * Internal use
- *
- * @param nativePtr - pointer to native peer
- */
- public GeoJsonSource(long nativePtr) {
- super(nativePtr);
+ /**
+ * Internal use
+ *
+ * @param nativePtr - pointer to native peer
+ */
+ public GeoJsonSource(long nativePtr) {
+ super(nativePtr);
+ }
+
+ /**
+ * Create an empty GeoJsonSource
+ *
+ * @param id the source id
+ */
+ public GeoJsonSource(String id) {
+ initialize(id, null);
+ setGeoJson(FeatureCollection.fromFeatures(new ArrayList<Feature>()));
+ }
+
+ /**
+ * Create an empty GeoJsonSource with non-default {@link GeoJsonOptions}
+ *
+ * @param id the source id
+ * @param options options
+ */
+ public GeoJsonSource(String id, GeoJsonOptions options) {
+ initialize(id, options);
+ setGeoJson(FeatureCollection.fromFeatures(new ArrayList<Feature>()));
+ }
+
+ /**
+ * Create a GeoJsonSource from a raw json string
+ *
+ * @param id the source id
+ * @param geoJson raw Json FeatureCollection
+ */
+ public GeoJsonSource(String id, String geoJson) {
+ if (geoJson == null || geoJson.startsWith("http")) {
+ throw new IllegalArgumentException("Expected a raw json body");
}
-
- /**
- * Create an empty GeoJsonSource
- *
- * @param id the source id
- */
- public GeoJsonSource(String id) {
- initialize(id, null);
- setGeoJson(FeatureCollection.fromFeatures(new ArrayList<Feature>()));
- }
-
- /**
- * Create an empty GeoJsonSource with non-default {@link GeoJsonOptions}
- *
- * @param id the source id
- * @param options options
- */
- public GeoJsonSource(String id, GeoJsonOptions options) {
- initialize(id, options);
- setGeoJson(FeatureCollection.fromFeatures(new ArrayList<Feature>()));
- }
-
- /**
- * Create a GeoJsonSource from a raw json string
- *
- * @param id the source id
- * @param geoJson raw Json FeatureCollection
- */
- public GeoJsonSource(String id, String geoJson) {
- if (geoJson == null || geoJson.startsWith("http")) {
- throw new IllegalArgumentException("Expected a raw json body");
- }
- initialize(id, null);
- setGeoJson(geoJson);
- }
-
- /**
- * Create a GeoJsonSource from a raw json string and non-default {@link GeoJsonOptions}
- *
- * @param id the source id
- * @param geoJson raw Json body
- * @param options options
- */
- public GeoJsonSource(String id, String geoJson, GeoJsonOptions options) {
- if (geoJson == null || geoJson.startsWith("http")) {
- throw new IllegalArgumentException("Expected a raw json body");
- }
- initialize(id, options);
- setGeoJson(geoJson);
- }
-
- /**
- * Create a GeoJsonSource from a remote geo json file
- *
- * @param id the source id
- * @param url remote json file
- */
- public GeoJsonSource(String id, URL url) {
- initialize(id, null);
- nativeSetUrl(url.toExternalForm());
- }
-
- /**
- * Create a GeoJsonSource from a remote geo json file and non-default {@link GeoJsonOptions}
- *
- * @param id the source id
- * @param url remote json file
- * @param options options
- */
- public GeoJsonSource(String id, URL url, GeoJsonOptions options) {
- initialize(id, options);
- nativeSetUrl(url.toExternalForm());
- }
-
- /**
- * Create a GeoJsonSource from a {@link FeatureCollection}
- *
- * @param id the source id
- * @param features the features
- */
- public GeoJsonSource(String id, FeatureCollection features) {
- initialize(id, null);
- setGeoJson(features);
- }
-
- /**
- * Create a GeoJsonSource from a {@link FeatureCollection} and non-default {@link GeoJsonOptions}
- *
- * @param id the source id
- * @param features the features
- * @param options options
- */
- public GeoJsonSource(String id, FeatureCollection features, GeoJsonOptions options) {
- initialize(id, options);
- setGeoJson(features);
+ initialize(id, null);
+ setGeoJson(geoJson);
+ }
+
+ /**
+ * Create a GeoJsonSource from a raw json string and non-default {@link GeoJsonOptions}
+ *
+ * @param id the source id
+ * @param geoJson raw Json body
+ * @param options options
+ */
+ public GeoJsonSource(String id, String geoJson, GeoJsonOptions options) {
+ if (geoJson == null || geoJson.startsWith("http")) {
+ throw new IllegalArgumentException("Expected a raw json body");
}
-
- /**
- * Updates the GeoJson
- *
- * @param features the GeoJSON {@link FeatureCollection}
- */
- public void setGeoJson(FeatureCollection features) {
- checkValidity();
- setGeoJson(features.toJson());
- }
-
- /**
- * Updates the GeoJson
- *
- * @param json the raw GeoJson FeatureCollection string
- */
- public void setGeoJson(String json) {
- checkValidity();
- setRawJson(json);
- }
-
- /**
- * Updates the url
- *
- * @param url the GeoJSON FeatureCollection url
- */
- public void setUrl(URL url) {
- checkValidity();
- setUrl(url.toExternalForm());
- }
-
- /**
- * Updates the url
- *
- * @param url the GeoJSON FeatureCollection url
- */
- public void setUrl(String url) {
- checkValidity();
- nativeSetUrl(url);
- }
-
- protected void setRawJson(String geoJson) {
- //Wrap the String in a map as an Object is expected by the
- //style conversion template
- HashMap<String, String> wrapper = new HashMap<>();
- wrapper.put("data", geoJson);
- nativeSetGeoJson(wrapper);
- }
-
- protected native void initialize(String layerId, Object options);
-
- protected native void nativeSetUrl(String url);
-
- private native void nativeSetGeoJson(Object geoJson);
-
- @Override
- protected native void finalize() throws Throwable;
+ initialize(id, options);
+ setGeoJson(geoJson);
+ }
+
+ /**
+ * Create a GeoJsonSource from a remote geo json file
+ *
+ * @param id the source id
+ * @param url remote json file
+ */
+ public GeoJsonSource(String id, URL url) {
+ initialize(id, null);
+ nativeSetUrl(url.toExternalForm());
+ }
+
+ /**
+ * Create a GeoJsonSource from a remote geo json file and non-default {@link GeoJsonOptions}
+ *
+ * @param id the source id
+ * @param url remote json file
+ * @param options options
+ */
+ public GeoJsonSource(String id, URL url, GeoJsonOptions options) {
+ initialize(id, options);
+ nativeSetUrl(url.toExternalForm());
+ }
+
+ /**
+ * Create a GeoJsonSource from a {@link FeatureCollection}
+ *
+ * @param id the source id
+ * @param features the features
+ */
+ public GeoJsonSource(String id, FeatureCollection features) {
+ initialize(id, null);
+ setGeoJson(features);
+ }
+
+ /**
+ * Create a GeoJsonSource from a {@link FeatureCollection} and non-default {@link GeoJsonOptions}
+ *
+ * @param id the source id
+ * @param features the features
+ * @param options options
+ */
+ public GeoJsonSource(String id, FeatureCollection features, GeoJsonOptions options) {
+ initialize(id, options);
+ setGeoJson(features);
+ }
+
+ /**
+ * Updates the GeoJson
+ *
+ * @param features the GeoJSON {@link FeatureCollection}
+ */
+ public void setGeoJson(FeatureCollection features) {
+ checkValidity();
+ setGeoJson(features.toJson());
+ }
+
+ /**
+ * Updates the GeoJson
+ *
+ * @param json the raw GeoJson FeatureCollection string
+ */
+ public void setGeoJson(String json) {
+ checkValidity();
+ setRawJson(json);
+ }
+
+ /**
+ * Updates the url
+ *
+ * @param url the GeoJSON FeatureCollection url
+ */
+ public void setUrl(URL url) {
+ checkValidity();
+ setUrl(url.toExternalForm());
+ }
+
+ /**
+ * Updates the url
+ *
+ * @param url the GeoJSON FeatureCollection url
+ */
+ public void setUrl(String url) {
+ checkValidity();
+ nativeSetUrl(url);
+ }
+
+ protected void setRawJson(String geoJson) {
+ //Wrap the String in a map as an Object is expected by the
+ //style conversion template
+ HashMap<String, String> wrapper = new HashMap<>();
+ wrapper.put("data", geoJson);
+ nativeSetGeoJson(wrapper);
+ }
+
+ protected native void initialize(String layerId, Object options);
+
+ protected native void nativeSetUrl(String url);
+
+ private native void nativeSetGeoJson(Object geoJson);
+
+ @Override
+ protected native void finalize() throws Throwable;
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/NoSuchSourceException.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/NoSuchSourceException.java
index 4622d72445..06d35b598b 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/NoSuchSourceException.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/NoSuchSourceException.java
@@ -5,7 +5,7 @@ package com.mapbox.mapboxsdk.style.sources;
*/
public class NoSuchSourceException extends Exception {
- public NoSuchSourceException(String message) {
- super(message);
- }
+ public NoSuchSourceException(String message) {
+ super(message);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/RasterSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/RasterSource.java
index 7a7ae49909..eabbdb8395 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/RasterSource.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/RasterSource.java
@@ -8,72 +8,72 @@ import java.net.URL;
* @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-raster">The style specification</a>
*/
public class RasterSource extends Source {
- public static final int DEFAULT_TILE_SIZE = 512;
+ public static final int DEFAULT_TILE_SIZE = 512;
- /**
- * Internal use
- *
- * @param nativePtr - pointer to native peer
- */
- public RasterSource(long nativePtr) {
- super(nativePtr);
- }
+ /**
+ * Internal use
+ *
+ * @param nativePtr - pointer to native peer
+ */
+ public RasterSource(long nativePtr) {
+ super(nativePtr);
+ }
- /**
- * Create the raster source from an URL
- *
- * @param id the source id
- * @param url the source url
- */
- public RasterSource(String id, URL url) {
- this(id, url.toExternalForm());
- }
+ /**
+ * Create the raster source from an URL
+ *
+ * @param id the source id
+ * @param url the source url
+ */
+ public RasterSource(String id, URL url) {
+ this(id, url.toExternalForm());
+ }
- /**
- * Create the raster source from an URL
- *
- * @param id the source id
- * @param url the source url
- */
- public RasterSource(String id, String url) {
- initialize(id, url, DEFAULT_TILE_SIZE);
- }
+ /**
+ * Create the raster source from an URL
+ *
+ * @param id the source id
+ * @param url the source url
+ */
+ public RasterSource(String id, String url) {
+ initialize(id, url, DEFAULT_TILE_SIZE);
+ }
- /**
- * Create the raster source from an URL with a specific tile size
- *
- * @param id the source id
- * @param url the source url
- * @param tileSize the tile size
- */
- public RasterSource(String id, String url, int tileSize) {
- initialize(id, url, tileSize);
- }
+ /**
+ * Create the raster source from an URL with a specific tile size
+ *
+ * @param id the source id
+ * @param url the source url
+ * @param tileSize the tile size
+ */
+ public RasterSource(String id, String url, int tileSize) {
+ initialize(id, url, tileSize);
+ }
- /**
- * Create the raster source from a {@link TileSet}
- *
- * @param id the source id
- * @param tileSet the {@link TileSet}
- */
- public RasterSource(String id, TileSet tileSet) {
- initialize(id, tileSet.toValueObject(), DEFAULT_TILE_SIZE);
- }
+ /**
+ * Create the raster source from a {@link TileSet}
+ *
+ * @param id the source id
+ * @param tileSet the {@link TileSet}
+ */
+ public RasterSource(String id, TileSet tileSet) {
+ initialize(id, tileSet.toValueObject(), DEFAULT_TILE_SIZE);
+ }
- /**
- * Create the raster source from a {@link TileSet} with a specific tile size
- *
- * @param id the source id
- * @param tileSet the {@link TileSet}
- * @param tileSize tje tile size
- */
- public RasterSource(String id, TileSet tileSet, int tileSize) {
- initialize(id, tileSet.toValueObject(), tileSize);
- }
+ /**
+ * Create the raster source from a {@link TileSet} with a specific tile size
+ *
+ * @param id the source id
+ * @param tileSet the {@link TileSet}
+ * @param tileSize tje tile size
+ */
+ public RasterSource(String id, TileSet tileSet, int tileSize) {
+ initialize(id, tileSet.toValueObject(), tileSize);
+ }
- protected native void initialize(String layerId, Object payload, int tileSize);
+ protected native void initialize(String layerId, Object payload, int tileSize);
- @Override
- protected native void finalize() throws Throwable;
+ @Override
+ protected native void finalize() throws Throwable;
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/Source.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/Source.java
index 0856b117dc..6826fed1b5 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/Source.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/Source.java
@@ -4,52 +4,52 @@ package com.mapbox.mapboxsdk.style.sources;
* Base Peer class for sources. see source.hpp for the other half of the peer.
*/
public abstract class Source {
- private long nativePtr;
- private boolean invalidated;
-
- /**
- * Internal use
- *
- * @param nativePtr - pointer to native peer
- */
- public Source(long nativePtr) {
- this.nativePtr = nativePtr;
- }
-
- public Source() {
- }
-
- /**
- * Retrieve the source id
- *
- * @return the source id
- */
- public String getId() {
- checkValidity();
- return nativeGetId();
- }
-
- /**
- * Internal use
- *
- * @return the native peer pointer
- */
- public long getNativePtr() {
- return nativePtr;
- }
-
- protected native String nativeGetId();
-
- protected void checkValidity() {
- if (invalidated) {
- throw new RuntimeException("Layer has been invalidated. Request a new reference after adding");
- }
- }
-
- /**
- * Internal use - invalidates the source for further use (after adding it to the map)
- */
- public final void invalidate() {
- this.invalidated = true;
+ private long nativePtr;
+ private boolean invalidated;
+
+ /**
+ * Internal use
+ *
+ * @param nativePtr - pointer to native peer
+ */
+ public Source(long nativePtr) {
+ this.nativePtr = nativePtr;
+ }
+
+ public Source() {
+ }
+
+ /**
+ * Retrieve the source id
+ *
+ * @return the source id
+ */
+ public String getId() {
+ checkValidity();
+ return nativeGetId();
+ }
+
+ /**
+ * Internal use
+ *
+ * @return the native peer pointer
+ */
+ public long getNativePtr() {
+ return nativePtr;
+ }
+
+ protected native String nativeGetId();
+
+ protected void checkValidity() {
+ if (invalidated) {
+ throw new RuntimeException("Layer has been invalidated. Request a new reference after adding");
}
+ }
+
+ /**
+ * Internal use - invalidates the source for further use (after adding it to the map)
+ */
+ public final void invalidate() {
+ this.invalidated = true;
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/TileSet.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/TileSet.java
index b645020c21..9f403c2fb9 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/TileSet.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/TileSet.java
@@ -13,304 +13,307 @@ import java.util.Map;
* @see <a href="https://github.com/mapbox/tilejson-spec/tree/master/2.1.0">The tileset specification</a>
*/
public class TileSet {
- private final String tilejson;
- private String name;
- private String description;
- private String version;
- private String attribution;
- private String template;
- private String legend;
- private String scheme;
- private final String[] tiles;
- private String[] grids;
- private String[] data;
- private Float minZoom;
- private Float maxZoom;
- private Float[] bounds;
- private Float[] center;
-
- /**
- * @param tilejson A semver.org style version number. Describes the version of the TileJSON spec that is implemented by this JSON object.
- * @param tiles An array of tile endpoints. {z}, {x} and {y}, if present, are replaced with the corresponding integers.
- * If multiple endpoints are specified, clients may use any combination of endpoints. All endpoints MUST return the same
- * content for the same URL. The array MUST contain at least one endpoint.
- * Example: "http:localhost:8888/admin/1.0.0/world-light,broadband/{z}/{x}/{y}.png"
- */
- public TileSet(String tilejson, String... tiles) {
- this.tilejson = tilejson;
- this.tiles = tiles;
+ private final String tilejson;
+ private String name;
+ private String description;
+ private String version;
+ private String attribution;
+ private String template;
+ private String legend;
+ private String scheme;
+ private final String[] tiles;
+ private String[] grids;
+ private String[] data;
+ private Float minZoom;
+ private Float maxZoom;
+ private Float[] bounds;
+ private Float[] center;
+
+ /**
+ * @param tilejson A semver.org style version number. Describes the version of the TileJSON spec that is implemented
+ * by this JSON object.
+ * @param tiles An array of tile endpoints. {z}, {x} and {y}, if present, are replaced with the corresponding
+ * integers.
+ * If multiple endpoints are specified, clients may use any combination of endpoints. All endpoints
+ * MUST return the same
+ * content for the same URL. The array MUST contain at least one endpoint.
+ * Example: "http:localhost:8888/admin/1.0.0/world-light,broadband/{z}/{x}/{y}.png"
+ */
+ public TileSet(String tilejson, String... tiles) {
+ this.tilejson = tilejson;
+ this.tiles = tiles;
+ }
+
+ public String getTilejson() {
+ return tilejson;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * A name describing the tileset. The name can
+ * contain any legal character. Implementations SHOULD NOT interpret the
+ * name as HTML.
+ * "name": "compositing",
+ *
+ * @param name the name to be set
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * A text description of the tileset. The
+ * description can contain any legal character.
+ * Implementations SHOULD NOT
+ * interpret the description as HTML.
+ * "description": "A simple, light grey world."
+ *
+ * @param description the description to set
+ */
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public String getAttribution() {
+ return attribution;
+ }
+
+ /**
+ * Default: null. Contains an attribution to be displayed
+ * when the map is shown to a user. Implementations MAY decide to treat this
+ * as HTML or literal text. For security reasons, make absolutely sure that
+ * this field can't be abused as a vector for XSS or beacon tracking.
+ * "attribution": "<a href='http:openstreetmap.org'>OSM contributors</a>",
+ *
+ * @param attribution the attribution to set
+ */
+ public void setAttribution(String attribution) {
+ this.attribution = attribution;
+ }
+
+ public String getTemplate() {
+ return template;
+ }
+
+ /**
+ * Contains a mustache template to be used to
+ * format data from grids for interaction.
+ * See https:github.com/mapbox/utfgrid-spec/tree/master/1.2
+ * for the interactivity specification.
+ * "template": "{{#__teaser__}}{{NAME}}{{/__teaser__}}"
+ *
+ * @param template the template to set
+ */
+ public void setTemplate(String template) {
+ this.template = template;
+ }
+
+ public String getLegend() {
+ return legend;
+ }
+
+ /**
+ * Contains a legend to be displayed with the map.
+ * Implementations MAY decide to treat this as HTML or literal text.
+ * For security reasons, make absolutely sure that this field can't be
+ * abused as a vector for XSS or beacon tracking.
+ * "legend": "Dangerous zones are red, safe zones are green"
+ *
+ * @param legend the legend to set
+ */
+ public void setLegend(String legend) {
+ this.legend = legend;
+ }
+
+ public String getScheme() {
+ return scheme;
+ }
+
+ /**
+ * Default: "xyz". Either "xyz" or "tms". Influences the y
+ * direction of the tile coordinates.
+ * The global-mercator (aka Spherical Mercator) profile is assumed.
+ * "scheme": "xyz"
+ *
+ * @param scheme the scheme to set
+ */
+ public void setScheme(String scheme) {
+ this.scheme = scheme;
+ }
+
+ public String[] getTiles() {
+ return tiles;
+ }
+
+ public String[] getGrids() {
+ return grids;
+ }
+
+ /**
+ * An array of interactivity endpoints. {z}, {x}
+ * and {y}, if present, are replaced with the corresponding integers. If multiple
+ * endpoints are specified, clients may use any combination of endpoints.
+ * All endpoints MUST return the same content for the same URL.
+ * If the array doesn't contain any entries, interactivity is not supported
+ * for this tileset. See https:github.com/mapbox/utfgrid-spec/tree/master/1.2
+ * for the interactivity specification.
+ * <p>
+ * Example: "http:localhost:8888/admin/1.0.0/broadband/{z}/{x}/{y}.grid.json"
+ * </p>
+ *
+ * @param grids the grids to set
+ */
+ public void setGrids(String... grids) {
+ this.grids = grids;
+ }
+
+ public String[] getData() {
+ return data;
+ }
+
+ /**
+ * An array of data files in GeoJSON format.
+ * {z}, {x} and {y}, if present,
+ * are replaced with the corresponding integers. If multiple
+ * endpoints are specified, clients may use any combination of endpoints.
+ * All endpoints MUST return the same content for the same URL.
+ * If the array doesn't contain any entries, then no data is present in
+ * the map.
+ * <p>
+ * "http:localhost:8888/admin/data.geojson"
+ * </p>
+ *
+ * @param data the data array to set
+ */
+ public void setData(String... data) {
+ this.data = data;
+ }
+
+ public float getMinZoom() {
+ return minZoom;
+ }
+
+ /**
+ * 0. &gt;= 0, &lt; 22. An integer specifying the minimum zoom level.
+ *
+ * @param minZoom the minZoom level to set
+ */
+ public void setMinZoom(float minZoom) {
+ this.minZoom = minZoom;
+ }
+
+ public float getMaxZoom() {
+ return maxZoom;
+ }
+
+ /**
+ * 0. &gt;= 0, &lt;= 22. An integer specifying the maximum zoom level.
+ *
+ * @param maxZoom the maxZoom level to set
+ */
+ public void setMaxZoom(float maxZoom) {
+ this.maxZoom = maxZoom;
+ }
+
+ public Float[] getBounds() {
+ return bounds;
+ }
+
+ /**
+ * Default: [-180, -90, 180, 90]. The maximum extent of available map tiles. Bounds MUST define an area
+ * covered by all zoom levels. The bounds are represented in WGS:84
+ * latitude and longitude values, in the order left, bottom, right, top.
+ * Values may be integers or floating point numbers.
+ *
+ * @param bounds the Float array to set
+ */
+ public void setBounds(@Size(value = 4) Float... bounds) {
+ this.bounds = bounds;
+ }
+
+ public Float[] getCenter() {
+ return center;
+ }
+
+ /**
+ * The first value is the longitude, the second is latitude (both in
+ * WGS:84 values), the third value is the zoom level as an integer.
+ * Longitude and latitude MUST be within the specified bounds.
+ * The zoom level MUST be between minzoom and maxzoom.
+ * Implementations can use this value to set the default location. If the
+ * value is null, implementations may use their own algorithm for
+ * determining a default location.
+ *
+ * @param center the Float array to set
+ */
+ public void setCenter(@Size(value = 2) Float... center) {
+ this.center = center;
+ }
+
+ public void setCenter(LatLng center) {
+ this.center = new Float[] {(float) center.getLongitude(), (float) center.getLatitude()};
+ }
+
+ Map<String, Object> toValueObject() {
+ Map<String, Object> result = new HashMap<>();
+ result.put("tilejson", tilejson);
+ result.put("tiles", tiles);
+
+ if (name != null) {
+ result.put("name", name);
}
-
- public String getTilejson() {
- return tilejson;
- }
-
- public String getName() {
- return name;
- }
-
- /**
- * A name describing the tileset. The name can
- * contain any legal character. Implementations SHOULD NOT interpret the
- * name as HTML.
- * "name": "compositing",
- *
- * @param name the name to be set
- */
- public void setName(String name) {
- this.name = name;
- }
-
- public String getDescription() {
- return description;
- }
-
- /**
- * A text description of the tileset. The
- * description can contain any legal character.
- * Implementations SHOULD NOT
- * interpret the description as HTML.
- * "description": "A simple, light grey world."
- *
- * @param description the description to set
- */
- public void setDescription(String description) {
- this.description = description;
- }
-
- public String getVersion() {
- return version;
- }
-
- public void setVersion(String version) {
- this.version = version;
+ if (description != null) {
+ result.put("description", description);
}
-
- public String getAttribution() {
- return attribution;
+ if (version != null) {
+ result.put("version", version);
}
-
- /**
- * Default: null. Contains an attribution to be displayed
- * when the map is shown to a user. Implementations MAY decide to treat this
- * as HTML or literal text. For security reasons, make absolutely sure that
- * this field can't be abused as a vector for XSS or beacon tracking.
- * "attribution": "<a href='http:openstreetmap.org'>OSM contributors</a>",
- *
- * @param attribution the attribution to set
- */
- public void setAttribution(String attribution) {
- this.attribution = attribution;
+ if (attribution != null) {
+ result.put("attribution", attribution);
}
-
- public String getTemplate() {
- return template;
+ if (template != null) {
+ result.put("template", template);
}
-
- /**
- * Contains a mustache template to be used to
- * format data from grids for interaction.
- * See https:github.com/mapbox/utfgrid-spec/tree/master/1.2
- * for the interactivity specification.
- * "template": "{{#__teaser__}}{{NAME}}{{/__teaser__}}"
- *
- * @param template the template to set
- */
- public void setTemplate(String template) {
- this.template = template;
+ if (legend != null) {
+ result.put("legend", legend);
}
-
- public String getLegend() {
- return legend;
+ if (scheme != null) {
+ result.put("scheme", scheme);
}
-
- /**
- * Contains a legend to be displayed with the map.
- * Implementations MAY decide to treat this as HTML or literal text.
- * For security reasons, make absolutely sure that this field can't be
- * abused as a vector for XSS or beacon tracking.
- * "legend": "Dangerous zones are red, safe zones are green"
- *
- * @param legend the legend to set
- */
- public void setLegend(String legend) {
- this.legend = legend;
+ if (grids != null) {
+ result.put("grids", grids);
}
-
- public String getScheme() {
- return scheme;
+ if (data != null) {
+ result.put("data", data);
}
-
- /**
- * Default: "xyz". Either "xyz" or "tms". Influences the y
- * direction of the tile coordinates.
- * The global-mercator (aka Spherical Mercator) profile is assumed.
- * "scheme": "xyz"
- *
- * @param scheme the scheme to set
- */
- public void setScheme(String scheme) {
- this.scheme = scheme;
+ if (minZoom != null) {
+ result.put("minzoom", minZoom);
}
-
- public String[] getTiles() {
- return tiles;
+ if (maxZoom != null) {
+ result.put("maxzoom", maxZoom);
}
-
- public String[] getGrids() {
- return grids;
+ if (bounds != null) {
+ result.put("bounds", bounds);
}
-
- /**
- * An array of interactivity endpoints. {z}, {x}
- * and {y}, if present, are replaced with the corresponding integers. If multiple
- * endpoints are specified, clients may use any combination of endpoints.
- * All endpoints MUST return the same content for the same URL.
- * If the array doesn't contain any entries, interactivity is not supported
- * for this tileset. See https:github.com/mapbox/utfgrid-spec/tree/master/1.2
- * for the interactivity specification.
- * <p>
- * Example: "http:localhost:8888/admin/1.0.0/broadband/{z}/{x}/{y}.grid.json"
- * </p>
- *
- * @param grids the grids to set
- */
- public void setGrids(String... grids) {
- this.grids = grids;
+ if (center != null) {
+ result.put("center", center);
}
- public String[] getData() {
- return data;
- }
-
- /**
- * An array of data files in GeoJSON format.
- * {z}, {x} and {y}, if present,
- * are replaced with the corresponding integers. If multiple
- * endpoints are specified, clients may use any combination of endpoints.
- * All endpoints MUST return the same content for the same URL.
- * If the array doesn't contain any entries, then no data is present in
- * the map.
- * <p>
- * "http:localhost:8888/admin/data.geojson"
- * </p>
- *
- * @param data the data array to set
- */
- public void setData(String... data) {
- this.data = data;
- }
-
- public float getMinZoom() {
- return minZoom;
- }
-
- /**
- * 0. &gt;= 0, &lt; 22. An integer specifying the minimum zoom level.
- *
- * @param minZoom the minZoom level to set
- */
- public void setMinZoom(float minZoom) {
- this.minZoom = minZoom;
- }
-
- public float getMaxZoom() {
- return maxZoom;
- }
-
- /**
- * 0. &gt;= 0, &lt;= 22. An integer specifying the maximum zoom level.
- *
- * @param maxZoom the maxZoom level to set
- */
- public void setMaxZoom(float maxZoom) {
- this.maxZoom = maxZoom;
- }
-
- public Float[] getBounds() {
- return bounds;
- }
-
- /**
- * Default: [-180, -90, 180, 90]. The maximum extent of available map tiles. Bounds MUST define an area
- * covered by all zoom levels. The bounds are represented in WGS:84
- * latitude and longitude values, in the order left, bottom, right, top.
- * Values may be integers or floating point numbers.
- *
- * @param bounds the Float array to set
- */
- public void setBounds(@Size(value = 4) Float... bounds) {
- this.bounds = bounds;
- }
-
- public Float[] getCenter() {
- return center;
- }
-
- /**
- * The first value is the longitude, the second is latitude (both in
- * WGS:84 values), the third value is the zoom level as an integer.
- * Longitude and latitude MUST be within the specified bounds.
- * The zoom level MUST be between minzoom and maxzoom.
- * Implementations can use this value to set the default location. If the
- * value is null, implementations may use their own algorithm for
- * determining a default location.
- *
- * @param center the Float array to set
- */
- public void setCenter(@Size(value = 2) Float... center) {
- this.center = center;
- }
-
- public void setCenter(LatLng center) {
- this.center = new Float[]{(float) center.getLongitude(), (float) center.getLatitude()};
- }
-
- Map<String, Object> toValueObject() {
- Map<String, Object> result = new HashMap<>();
- result.put("tilejson", tilejson);
- result.put("tiles", tiles);
-
- if (name != null) {
- result.put("name", name);
- }
- if (description != null) {
- result.put("description", description);
- }
- if (version != null) {
- result.put("version", version);
- }
- if (attribution != null) {
- result.put("attribution", attribution);
- }
- if (template != null) {
- result.put("template", template);
- }
- if (legend != null) {
- result.put("legend", legend);
- }
- if (scheme != null) {
- result.put("scheme", scheme);
- }
- if (grids != null) {
- result.put("grids", grids);
- }
- if (data != null) {
- result.put("data", data);
- }
- if (minZoom != null) {
- result.put("minzoom", minZoom);
- }
- if (maxZoom != null) {
- result.put("maxzoom", maxZoom);
- }
- if (bounds != null) {
- result.put("bounds", bounds);
- }
- if (center != null) {
- result.put("center", center);
- }
-
- return result;
- }
+ return result;
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/VectorSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/VectorSource.java
index 689ea7c6bc..feaca839d3 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/VectorSource.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/VectorSource.java
@@ -9,47 +9,47 @@ import java.net.URL;
*/
public class VectorSource extends Source {
- /**
- * Internal use
- *
- * @param nativePtr - pointer to native peer
- */
- public VectorSource(long nativePtr) {
- super(nativePtr);
- }
-
- /**
- * Create a vector source from a remote url
- *
- * @param id the source id
- * @param url the url
- */
- public VectorSource(String id, URL url) {
- this(id, url.toExternalForm());
- }
-
- /**
- * Create a vector source from a remote url
- *
- * @param id the source id
- * @param url the url
- */
- public VectorSource(String id, String url) {
- initialize(id, url);
- }
-
- /**
- * Create a vector source from a tilset
- *
- * @param id the source id
- * @param tileSet the tileset
- */
- public VectorSource(String id, TileSet tileSet) {
- initialize(id, tileSet.toValueObject());
- }
-
- protected native void initialize(String layerId, Object payload);
-
- @Override
- protected native void finalize() throws Throwable;
+ /**
+ * Internal use
+ *
+ * @param nativePtr - pointer to native peer
+ */
+ public VectorSource(long nativePtr) {
+ super(nativePtr);
+ }
+
+ /**
+ * Create a vector source from a remote url
+ *
+ * @param id the source id
+ * @param url the url
+ */
+ public VectorSource(String id, URL url) {
+ this(id, url.toExternalForm());
+ }
+
+ /**
+ * Create a vector source from a remote url
+ *
+ * @param id the source id
+ * @param url the url
+ */
+ public VectorSource(String id, String url) {
+ initialize(id, url);
+ }
+
+ /**
+ * Create a vector source from a tilset
+ *
+ * @param id the source id
+ * @param tileSet the tileset
+ */
+ public VectorSource(String id, TileSet tileSet) {
+ initialize(id, tileSet.toValueObject());
+ }
+
+ protected native void initialize(String layerId, Object payload);
+
+ @Override
+ protected native void finalize() throws Throwable;
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/GzipRequestInterceptor.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/GzipRequestInterceptor.java
index 1b13e9502f..8457d24ff2 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/GzipRequestInterceptor.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/GzipRequestInterceptor.java
@@ -1,7 +1,9 @@
package com.mapbox.mapboxsdk.telemetry;
-import android.util.Log;
+import timber.log.Timber;
+
import java.io.IOException;
+
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
@@ -17,38 +19,40 @@ import okio.Okio;
*/
public final class GzipRequestInterceptor implements Interceptor {
- private static final String TAG = "GzipRequestInterceptor";
-
- @Override public Response intercept(Interceptor.Chain chain) throws IOException {
- Request originalRequest = chain.request();
- if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) {
- Log.d(TAG, "Not compressing");
- return chain.proceed(originalRequest);
- }
-
- Log.d(TAG, "Compressing");
- Request compressedRequest = originalRequest.newBuilder()
- .header("Content-Encoding", "gzip")
- .method(originalRequest.method(), gzip(originalRequest.body()))
- .build();
- return chain.proceed(compressedRequest);
+ @Override
+ public Response intercept(Interceptor.Chain chain) throws IOException {
+ Request originalRequest = chain.request();
+ if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) {
+ Timber.d("Not compressing");
+ return chain.proceed(originalRequest);
}
- private RequestBody gzip(final RequestBody body) {
- return new RequestBody() {
- @Override public MediaType contentType() {
- return body.contentType();
- }
-
- @Override public long contentLength() {
- return -1; // We don't know the compressed length in advance!
- }
-
- @Override public void writeTo(BufferedSink sink) throws IOException {
- BufferedSink gzipSink = Okio.buffer(new GzipSink(sink));
- body.writeTo(gzipSink);
- gzipSink.close();
- }
- };
- }
+ Timber.d("Compressing");
+ Request compressedRequest = originalRequest.newBuilder()
+ .header("Content-Encoding", "gzip")
+ .method(originalRequest.method(), gzip(originalRequest.body()))
+ .build();
+ return chain.proceed(compressedRequest);
+ }
+
+ private RequestBody gzip(final RequestBody body) {
+ return new RequestBody() {
+ @Override
+ public MediaType contentType() {
+ return body.contentType();
+ }
+
+ @Override
+ public long contentLength() {
+ return -1; // We don't know the compressed length in advance!
+ }
+
+ @Override
+ public void writeTo(BufferedSink sink) throws IOException {
+ BufferedSink gzipSink = Okio.buffer(new GzipSink(sink));
+ body.writeTo(gzipSink);
+ gzipSink.close();
+ }
+ };
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEvent.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEvent.java
index 22e37ec539..b5203bc02a 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEvent.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEvent.java
@@ -1,66 +1,161 @@
package com.mapbox.mapboxsdk.telemetry;
+import android.graphics.PointF;
+import android.support.annotation.NonNull;
+
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.maps.Projection;
+
import java.io.Serializable;
+import java.util.Hashtable;
+
+import timber.log.Timber;
/**
* Constants for Telemetry Metadata
*/
public class MapboxEvent implements Serializable {
- public static final int VERSION_NUMBER = 2;
- public static final String MAPBOX_EVENTS_BASE_URL = "https://events.mapbox.com";
- public static final String SOURCE_MAPBOX = "mapbox";
-
- // Event Types
- public static final String TYPE_TURNSTILE = "appUserTurnstile";
- public static final String TYPE_MAP_LOAD = "map.load";
- public static final String TYPE_MAP_CLICK = "map.click";
- public static final String TYPE_MAP_DRAGEND = "map.dragend";
- public static final String TYPE_LOCATION = "location";
- public static final String TYPE_VISIT = "visit";
-
- // Event Keys
- public static final String KEY_LATITUDE = "lat";
- public static final String KEY_LONGITUDE = "lng";
- public static final String KEY_SPEED = "speed";
- public static final String KEY_COURSE = "course";
- public static final String KEY_ALTITUDE = "altitude";
- public static final String KEY_HORIZONTAL_ACCURACY = "horizontalAccuracy";
- public static final String KEY_ZOOM = "zoom";
-
- public static final String KEY_PUSH_ENABLED = "enabled.push";
- public static final String KEY_EMAIL_ENABLED = "enabled.email";
- public static final String KEY_GESTURE_ID = "gesture";
- public static final String KEY_ARRIVAL_DATE = "arrivalDate";
- public static final String KEY_DEPARTURE_DATE = "departureDate";
-
- public static final String GESTURE_SINGLETAP = "SingleTap";
- public static final String GESTURE_DOUBLETAP = "DoubleTap";
- public static final String GESTURE_TWO_FINGER_SINGLETAP = "TwoFingerTap";
- public static final String GESTURE_QUICK_ZOOM = "QuickZoom";
- public static final String GESTURE_PAN_START = "Pan";
- public static final String GESTURE_PINCH_START = "Pinch";
- public static final String GESTURE_ROTATION_START = "Rotation";
- public static final String GESTURE_PITCH_START = "Pitch";
-
- // Event Attributes
- public static final String ATTRIBUTE_EVENT = "event";
- public static final String ATTRIBUTE_USERID = "userId";
- public static final String ATTRIBUTE_SOURCE = "source";
- public static final String ATTRIBUTE_ENABLED_TELEMETRY = "enabled.telemetry";
- public static final String ATTRIBUTE_SESSION_ID = "sessionId";
- public static final String ATTRIBUTE_VERSION = "version";
- public static final String ATTRIBUTE_CREATED = "created";
- public static final String ATTRIBUTE_VENDOR_ID = "vendorId";
- public static final String ATTRIBUTE_APP_BUNDLE_ID = "appBundleId";
- public static final String ATTRIBUTE_MODEL = "model";
- public static final String ATTRIBUTE_OPERATING_SYSTEM= "operatingSystem";
- public static final String ATTRIBUTE_ORIENTATION = "orientation";
- public static final String ATTRIBUTE_BATTERY_LEVEL = "batteryLevel";
- public static final String ATTRIBUTE_PLUGGED_IN = "pluggedIn";
- public static final String ATTRIBUTE_APPLICATION_STATE = "applicationState";
- public static final String ATTRIBUTE_RESOLUTION = "resolution";
- public static final String ATTRIBUTE_ACCESSIBILITY_FONT_SCALE = "accessibilityFontScale";
- public static final String ATTRIBUTE_CARRIER = "carrier";
- public static final String ATTRIBUTE_CELLULAR_NETWORK_TYPE = "cellularNetworkType";
- public static final String ATTRIBUTE_WIFI = "wifi";
+ public static final int VERSION_NUMBER = 2;
+ public static final String MAPBOX_EVENTS_BASE_URL = "https://events.mapbox.com";
+ public static final String SOURCE_MAPBOX = "mapbox";
+
+ // Event Types
+ public static final String TYPE_TURNSTILE = "appUserTurnstile";
+ public static final String TYPE_MAP_LOAD = "map.load";
+ public static final String TYPE_MAP_CLICK = "map.click";
+ public static final String TYPE_MAP_DRAGEND = "map.dragend";
+ public static final String TYPE_LOCATION = "location";
+ public static final String TYPE_VISIT = "visit";
+
+ // Event Keys
+ public static final String KEY_LATITUDE = "lat";
+ public static final String KEY_LONGITUDE = "lng";
+ public static final String KEY_SPEED = "speed";
+ public static final String KEY_COURSE = "course";
+ public static final String KEY_ALTITUDE = "altitude";
+ public static final String KEY_HORIZONTAL_ACCURACY = "horizontalAccuracy";
+ public static final String KEY_ZOOM = "zoom";
+
+ public static final String KEY_PUSH_ENABLED = "enabled.push";
+ public static final String KEY_EMAIL_ENABLED = "enabled.email";
+ public static final String KEY_GESTURE_ID = "gesture";
+ public static final String KEY_ARRIVAL_DATE = "arrivalDate";
+ public static final String KEY_DEPARTURE_DATE = "departureDate";
+
+ public static final String GESTURE_SINGLETAP = "SingleTap";
+ public static final String GESTURE_DOUBLETAP = "DoubleTap";
+ public static final String GESTURE_TWO_FINGER_SINGLETAP = "TwoFingerTap";
+ public static final String GESTURE_QUICK_ZOOM = "QuickZoom";
+ public static final String GESTURE_PAN_START = "Pan";
+ public static final String GESTURE_PINCH_START = "Pinch";
+ public static final String GESTURE_ROTATION_START = "Rotation";
+ public static final String GESTURE_PITCH_START = "Pitch";
+
+ // Event Attributes
+ public static final String ATTRIBUTE_EVENT = "event";
+ public static final String ATTRIBUTE_USERID = "userId";
+ public static final String ATTRIBUTE_SOURCE = "source";
+ public static final String ATTRIBUTE_ENABLED_TELEMETRY = "enabled.telemetry";
+ public static final String ATTRIBUTE_SESSION_ID = "sessionId";
+ public static final String ATTRIBUTE_VERSION = "version";
+ public static final String ATTRIBUTE_CREATED = "created";
+ public static final String ATTRIBUTE_VENDOR_ID = "vendorId";
+ public static final String ATTRIBUTE_APP_BUNDLE_ID = "appBundleId";
+ public static final String ATTRIBUTE_MODEL = "model";
+ public static final String ATTRIBUTE_OPERATING_SYSTEM = "operatingSystem";
+ public static final String ATTRIBUTE_ORIENTATION = "orientation";
+ public static final String ATTRIBUTE_BATTERY_LEVEL = "batteryLevel";
+ public static final String ATTRIBUTE_PLUGGED_IN = "pluggedIn";
+ public static final String ATTRIBUTE_APPLICATION_STATE = "applicationState";
+ public static final String ATTRIBUTE_RESOLUTION = "resolution";
+ public static final String ATTRIBUTE_ACCESSIBILITY_FONT_SCALE = "accessibilityFontScale";
+ public static final String ATTRIBUTE_CARRIER = "carrier";
+ public static final String ATTRIBUTE_CELLULAR_NETWORK_TYPE = "cellularNetworkType";
+ public static final String ATTRIBUTE_WIFI = "wifi";
+
+ /**
+ * Helper method for tracking gesture events
+ *
+ * @param projection Projection of the Map object
+ * @param gestureId Type of Gesture See {@see MapboxEvent#GESTURE_SINGLETAP
+ * MapboxEvent#GESTURE_DOUBLETAP
+ * MapboxEvent#GESTURE_TWO_FINGER_SINGLETAP
+ * MapboxEvent#GESTURE_QUICK_ZOOM
+ * MapboxEvent#GESTURE_PAN_START
+ * MapboxEvent#GESTURE_PINCH_START
+ * MapboxEvent#GESTURE_ROTATION_START
+ * MapboxEvent#GESTURE_PITCH_START}
+ * @param xCoordinate Original x screen coordinate at start of gesture
+ * @param yCoordinate Original y screen cooridnate at start of gesture
+ * @param zoom Zoom level to be registered
+ */
+ public static void trackGestureEvent(@NonNull Projection projection, @NonNull String gestureId, float xCoordinate,
+ float yCoordinate, double zoom) {
+ 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())) {
+ Timber.d("trackGestureEvent() has a NaN lat or lon. Returning.");
+ return;
+ }
+
+ if (Double.isInfinite(tapLatLng.getLatitude()) || Double.isInfinite(tapLatLng.getLongitude())) {
+ Timber.d("trackGestureEvent() has an Infinite lat or lon. Returning.");
+ return;
+ }
+
+ Hashtable<String, Object> evt = new Hashtable<>();
+ evt.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_MAP_CLICK);
+ evt.put(MapboxEvent.ATTRIBUTE_CREATED, MapboxEventManager.generateCreateDate());
+ evt.put(MapboxEvent.KEY_GESTURE_ID, gestureId);
+ evt.put(MapboxEvent.KEY_LATITUDE, tapLatLng.getLatitude());
+ evt.put(MapboxEvent.KEY_LONGITUDE, tapLatLng.getLongitude());
+ evt.put(MapboxEvent.KEY_ZOOM, zoom);
+
+ MapboxEventManager.getMapboxEventManager().pushEvent(evt);
+ }
+
+ /**
+ * Helper method for tracking DragEnd gesture event
+ * See {@see MapboxEvent#TYPE_MAP_DRAGEND}
+ *
+ * @param projection projection of the Map object.
+ * @param xCoordinate Original x screen coordinate at end of drag
+ * @param yCoordinate Orginal y screen coordinate at end of drag
+ * @param zoom Zoom level to be registered
+ */
+ public static void trackGestureDragEndEvent(@NonNull Projection projection, float xCoordinate, float yCoordinate,
+ double zoom) {
+ 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())) {
+ Timber.d("trackGestureDragEndEvent() has a NaN lat or lon. Returning.");
+ return;
+ }
+
+ if (Double.isInfinite(tapLatLng.getLatitude()) || Double.isInfinite(tapLatLng.getLongitude())) {
+ Timber.d("trackGestureDragEndEvent() has an Infinite lat or lon. Returning.");
+ return;
+ }
+
+ Hashtable<String, Object> evt = new Hashtable<>();
+ evt.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_MAP_DRAGEND);
+ evt.put(MapboxEvent.ATTRIBUTE_CREATED, MapboxEventManager.generateCreateDate());
+ evt.put(MapboxEvent.KEY_LATITUDE, tapLatLng.getLatitude());
+ evt.put(MapboxEvent.KEY_LONGITUDE, tapLatLng.getLongitude());
+ evt.put(MapboxEvent.KEY_ZOOM, zoom);
+
+ MapboxEventManager.getMapboxEventManager().pushEvent(evt);
+ }
+
+ /**
+ * Helper method for tracking map load event
+ */
+ public static void trackMapLoadEvent() {
+ Hashtable<String, Object> evt = new Hashtable<>();
+ evt.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_MAP_LOAD);
+ evt.put(MapboxEvent.ATTRIBUTE_CREATED, MapboxEventManager.generateCreateDate());
+ MapboxEventManager.getMapboxEventManager().pushEvent(evt);
+ }
}
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 bedb54ca46..9e607746c9 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
@@ -21,11 +21,10 @@ import android.support.annotation.NonNull;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.DisplayMetrics;
-import android.util.Log;
import android.view.WindowManager;
import com.mapbox.mapboxsdk.BuildConfig;
-import com.mapbox.mapboxsdk.MapboxAccountManager;
+import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.constants.GeoConstants;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.exceptions.TelemetryServiceNotConfiguredException;
@@ -53,6 +52,7 @@ import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.internal.Util;
+import timber.log.Timber;
/**
* Singleton control center for managing Telemetry Data.
@@ -60,733 +60,755 @@ import okhttp3.internal.Util;
*/
public class MapboxEventManager {
- private static final String TAG = "MapboxEventManager";
+ private static MapboxEventManager mapboxEventManager = null;
- private static MapboxEventManager mapboxEventManager = null;
+ private boolean initialized = false;
+ private boolean stagingEnv;
+ private boolean telemetryEnabled;
- private boolean initialized = false;
- private boolean stagingEnv;
- private boolean telemetryEnabled;
+ private final Vector<Hashtable<String, Object>> events = new Vector<>();
+ private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
+ private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ",
+ MapboxConstants.MAPBOX_LOCALE);
- private final Vector<Hashtable<String, Object>> events = new Vector<>();
- private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
- private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", MapboxConstants.MAPBOX_LOCALE);
+ private Context context = null;
+ private String accessToken = null;
+ private String eventsURL = MapboxEvent.MAPBOX_EVENTS_BASE_URL;
- private Context context = null;
- private String accessToken = null;
- private String eventsURL = MapboxEvent.MAPBOX_EVENTS_BASE_URL;
+ private String userAgent = BuildConfig.MAPBOX_EVENTS_USER_AGENT_BASE;
- private String userAgent = BuildConfig.MAPBOX_EVENTS_USER_AGENT_BASE;
+ private Intent batteryStatus = null;
+ private final String operatingSystem = "Android - " + Build.VERSION.RELEASE;
- private Intent batteryStatus = null;
- private final String operatingSystem = "Android - " + Build.VERSION.RELEASE;
+ private DisplayMetrics displayMetrics = null;
- private DisplayMetrics displayMetrics = null;
+ private String mapboxVendorId = null;
- private String mapboxVendorId = null;
+ private String mapboxSessionId = null;
+ private long mapboxSessionIdLastSet = 0;
+ private static long hourInMillis = 1000 * 60 * 60;
+ private static long flushDelayInitialInMillis = 1000 * 10; // 10 Seconds
+ private static long flushDelayInMillis = 1000 * 60 * 3; // 3 Minutes
+ private static final int SESSION_ID_ROTATION_HOURS = 24;
- private String mapboxSessionId = null;
- private long mapboxSessionIdLastSet = 0;
- private static long hourInMillis = 1000 * 60 * 60;
- private static long flushDelayInitialInMillis = 1000 * 10; // 10 Seconds
- private static long flushDelayInMillis = 1000 * 60 * 3; // 3 Minutes
- private static final int SESSION_ID_ROTATION_HOURS = 24;
+ private static final int FLUSH_EVENTS_CAP = 1000;
- private static final int FLUSH_EVENTS_CAP = 1000;
+ private static MessageDigest messageDigest = null;
- private static MessageDigest messageDigest = null;
+ private static final double locationEventAccuracy = 10000000;
- private static final double locationEventAccuracy = 10000000;
+ private Timer timer = null;
- private Timer timer = null;
+ /**
+ * Private Constructor for configuring the single instance per app.
+ */
+ private MapboxEventManager() {
+ super();
+ }
- /**
- * Private Constructor for configuring the single instance per app.
- */
- private MapboxEventManager() {
- super();
- }
-
- /**
- * Internal setup of MapboxEventsManager. It needs to be called once before @link MapboxEventManager#getMapboxEventManager
- *
- * This allows for a cleaner getMapboxEventManager() that doesn't require context and accessToken
- *
- * @param context The context associated with MapView
- * @param accessToken The accessToken to load MapView
- */
- public void initialize(@NonNull Context context, @NonNull String accessToken) {
-
- Log.i(TAG, "Telemetry initialize() called...");
-
- if (initialized) {
- Log.i(TAG, "Mapbox Telemetry has already been initialized.");
- return;
- }
-
- this.context = context.getApplicationContext();
- this.accessToken = accessToken;
-
- validateTelemetryServiceConfigured();
-
- // Setup Message Digest
- try {
- messageDigest = MessageDigest.getInstance("SHA-1");
- } catch (NoSuchAlgorithmException e) {
- Log.w(TAG, "Error getting Encryption Algorithm: " + e);
- }
-
- // Create Initial Session Id
- rotateSessionId();
-
- SharedPreferences prefs = context.getSharedPreferences(MapboxConstants.MAPBOX_SHARED_PREFERENCES_FILE, Context.MODE_PRIVATE);
+ /**
+ * Internal setup of MapboxEventsManager. It needs to be called once before @link
+ * MapboxEventManager#getMapboxEventManager
+ * <p>
+ * This allows for a cleaner getMapboxEventManager() that doesn't require context and accessToken
+ *
+ * @param context The context associated with MapView
+ * @param accessToken The accessToken to load MapView
+ */
+ public void initialize(@NonNull Context context, @NonNull String accessToken) {
- // Determine if Telemetry Should Be Enabled
- Log.i(TAG, "Right before Telemetry set enabled in initialized()");
- setTelemetryEnabled(prefs.getBoolean(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_ENABLED, true));
+ Timber.i("Telemetry initialize() called...");
- // Load / Create Vendor Id
- if (prefs.contains(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_VENDORID)) {
- mapboxVendorId = prefs.getString(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_VENDORID, "");
- }
- if (TextUtils.isEmpty(mapboxVendorId)) {
- String vendorId = UUID.randomUUID().toString();
- mapboxVendorId = encodeString(vendorId);
- SharedPreferences.Editor editor = prefs.edit();
- editor.putString(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_VENDORID, mapboxVendorId);
- editor.apply();
- editor.commit();
- }
-
- // Get DisplayMetrics Setup
- displayMetrics = new DisplayMetrics();
- ((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(displayMetrics);
+ if (initialized) {
+ Timber.i("Mapbox Telemetry has already been initialized.");
+ return;
+ }
- // Check for Staging Server Information
- try {
- ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
- String stagingURL = appInfo.metaData.getString(MapboxConstants.KEY_META_DATA_STAGING_SERVER);
- String stagingAccessToken = appInfo.metaData.getString(MapboxConstants.KEY_META_DATA_STAGING_ACCESS_TOKEN);
+ this.context = context.getApplicationContext();
+ this.accessToken = accessToken;
- if (TextUtils.isEmpty(stagingURL) || TextUtils.isEmpty(stagingAccessToken)) {
- Log.d(TAG, "Looking in SharedPreferences for Staging Credentials");
- stagingURL = prefs.getString(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_STAGING_URL, null);
- stagingAccessToken = prefs.getString(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_STAGING_ACCESS_TOKEN, null);
- }
+ validateTelemetryServiceConfigured();
- if (!TextUtils.isEmpty(stagingURL) && !TextUtils.isEmpty(stagingAccessToken)) {
- eventsURL = stagingURL;
- this.accessToken = accessToken;
- stagingEnv = true;
- }
+ // Setup Message Digest
+ try {
+ messageDigest = MessageDigest.getInstance("SHA-1");
+ } catch (NoSuchAlgorithmException exception) {
+ Timber.w("Error getting Encryption Algorithm: ", exception);
+ }
- // Build User Agent
- String appIdentifier = getApplicationIdentifier();
- if (TextUtils.equals(userAgent, BuildConfig.MAPBOX_EVENTS_USER_AGENT_BASE) && !TextUtils.isEmpty(appIdentifier)) {
- userAgent = Util.toHumanReadableAscii(String.format(MapboxConstants.MAPBOX_LOCALE, "%s %s", appIdentifier, userAgent));
- }
+ // Create Initial Session Id
+ rotateSessionId();
- } catch (Exception e) {
- Log.e(TAG, "Error Trying to load Staging Credentials: " + e.toString());
- }
+ SharedPreferences prefs = context.getSharedPreferences(MapboxConstants.MAPBOX_SHARED_PREFERENCES_FILE,
+ Context.MODE_PRIVATE);
- // Register for battery updates
- IntentFilter iFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
- batteryStatus = context.registerReceiver(null, iFilter);
+ // Determine if Telemetry Should Be Enabled
+ Timber.i("Right before Telemetry set enabled in initialized()");
+ setTelemetryEnabled(prefs.getBoolean(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_ENABLED, true));
- initialized = true;
+ // Load / Create Vendor Id
+ if (prefs.contains(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_VENDORID)) {
+ mapboxVendorId = prefs.getString(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_VENDORID, "");
}
-
- /**
- * Primary Access method using Singleton pattern
- *
- * @return MapboxEventManager
- */
- public static MapboxEventManager getMapboxEventManager() {
- if (mapboxEventManager == null) {
- mapboxEventManager = new MapboxEventManager();
- }
- return mapboxEventManager;
- }
-
- // Checks that TelemetryService has been configured by developer
- private void validateTelemetryServiceConfigured() {
- try {
- // Check Implementing app's AndroidManifest.xml
- PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SERVICES);
- if (packageInfo.services != null) {
- for (ServiceInfo service : packageInfo.services) {
- if (TextUtils.equals("com.mapbox.mapboxsdk.telemetry.TelemetryService", service.name)) {
- return;
- }
- }
- }
- } catch (Exception e) {
- Log.w(MapboxConstants.TAG, "Error checking for Telemetry Service Config: " + e);
- }
- throw new TelemetryServiceNotConfiguredException();
+ if (TextUtils.isEmpty(mapboxVendorId)) {
+ String vendorId = UUID.randomUUID().toString();
+ mapboxVendorId = encodeString(vendorId);
+ SharedPreferences.Editor editor = prefs.edit();
+ editor.putString(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_VENDORID, mapboxVendorId);
+ editor.apply();
+ editor.commit();
}
- public static String generateCreateDate() {
- return dateFormat.format(new Date());
+ // Get DisplayMetrics Setup
+ displayMetrics = new DisplayMetrics();
+ ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(displayMetrics);
+
+ // Check for Staging Server Information
+ try {
+ ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(),
+ PackageManager.GET_META_DATA);
+ String stagingURL = appInfo.metaData.getString(MapboxConstants.KEY_META_DATA_STAGING_SERVER);
+ String stagingAccessToken = appInfo.metaData.getString(MapboxConstants.KEY_META_DATA_STAGING_ACCESS_TOKEN);
+
+ if (TextUtils.isEmpty(stagingURL) || TextUtils.isEmpty(stagingAccessToken)) {
+ Timber.d("Looking in SharedPreferences for Staging Credentials");
+ stagingURL = prefs.getString(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_STAGING_URL, null);
+ stagingAccessToken = prefs.getString(
+ MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_STAGING_ACCESS_TOKEN, null);
+ }
+
+ if (!TextUtils.isEmpty(stagingURL) && !TextUtils.isEmpty(stagingAccessToken)) {
+ eventsURL = stagingURL;
+ this.accessToken = accessToken;
+ stagingEnv = true;
+ }
+
+ // Build User Agent
+ String appIdentifier = getApplicationIdentifier();
+ if (TextUtils.equals(userAgent, BuildConfig.MAPBOX_EVENTS_USER_AGENT_BASE) && !TextUtils.isEmpty(appIdentifier)) {
+ userAgent = Util
+ .toHumanReadableAscii(String.format(MapboxConstants.MAPBOX_LOCALE, "%s %s", appIdentifier, userAgent));
+ }
+
+ } catch (Exception exception) {
+ Timber.e("Error Trying to load Staging Credentials: ", exception);
}
- public boolean isTelemetryEnabled() {
- return telemetryEnabled;
+ // Register for battery updates
+ IntentFilter iFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
+ batteryStatus = context.registerReceiver(null, iFilter);
+
+ initialized = true;
+ }
+
+ /**
+ * Primary Access method using Singleton pattern
+ *
+ * @return MapboxEventManager
+ */
+ public static MapboxEventManager getMapboxEventManager() {
+ if (mapboxEventManager == null) {
+ mapboxEventManager = new MapboxEventManager();
}
-
- /**
- * Enables / Disables Telemetry
- * @param telemetryEnabled True to start telemetry, false to stop it
- */
- public void setTelemetryEnabled(boolean telemetryEnabled) {
- Log.i(TAG, "setTelemetryEnabled(); this.telemetryEnabled = " + this.telemetryEnabled + "; telemetryEnabled = " + telemetryEnabled);
- if (this.telemetryEnabled == telemetryEnabled) {
- Log.d(TAG, "No need to start / stop telemetry as it's already in that state.");
+ return mapboxEventManager;
+ }
+
+ // Checks that TelemetryService has been configured by developer
+ private void validateTelemetryServiceConfigured() {
+ try {
+ // Check Implementing app's AndroidManifest.xml
+ PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(),
+ PackageManager.GET_SERVICES);
+ if (packageInfo.services != null) {
+ for (ServiceInfo service : packageInfo.services) {
+ if (TextUtils.equals("com.mapbox.mapboxsdk.telemetry.TelemetryService", service.name)) {
return;
+ }
}
+ }
+ } catch (Exception exception) {
+ Timber.w("Error checking for Telemetry Service Config: ", exception);
+ }
+ throw new TelemetryServiceNotConfiguredException();
+ }
+
+ public static String generateCreateDate() {
+ return dateFormat.format(new Date());
+ }
+
+ public boolean isTelemetryEnabled() {
+ return telemetryEnabled;
+ }
+
+ /**
+ * Enables / Disables Telemetry
+ *
+ * @param telemetryEnabled True to start telemetry, false to stop it
+ */
+ public void setTelemetryEnabled(boolean telemetryEnabled) {
+ Timber.i("this.telemetryEnabled = " + this.telemetryEnabled + "; telemetryEnabled = " + telemetryEnabled);
+ if (this.telemetryEnabled == telemetryEnabled) {
+ Timber.d("No need to start / stop telemetry as it's already in that state.");
+ return;
+ }
- if (telemetryEnabled) {
- Log.d(TAG, "Starting Telemetry Up!");
- // Start It Up
- context.startService(new Intent(context, TelemetryService.class));
+ if (telemetryEnabled) {
+ Timber.d("Starting Telemetry Up!");
+ // Start It Up
+ context.startService(new Intent(context, TelemetryService.class));
- // Make sure Ambient Mode is started at a minimum
+ // Make sure Ambient Mode is started at a minimum
+ if (LocationServices.getLocationServices(context).areLocationPermissionsGranted()) {
+ Timber.i("Permissions are good, see if GPS is enabled and if not then setup Ambient.");
+ if (LocationServices.getLocationServices(context).isGpsEnabled()) {
+ LocationServices.getLocationServices(context).toggleGPS(false);
+ }
+ } else {
+ // Start timer that checks for Permissions
+ Timber.i("Permissions are not good. Need to do some looping to check on stuff.");
+
+ final Handler permsHandler = new Handler();
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
if (LocationServices.getLocationServices(context).areLocationPermissionsGranted()) {
- Log.i(TAG, "Permissions are good, see if GPS is enabled and if not then setup Ambient.");
- if (LocationServices.getLocationServices(context).isGPSEnabled()) {
- LocationServices.getLocationServices(context).toggleGPS(false);
- }
+ Timber.i("Permissions finally granted, so starting Ambient if GPS isn't already enabled");
+ // Start Ambient
+ if (LocationServices.getLocationServices(context).isGpsEnabled()) {
+ LocationServices.getLocationServices(context).toggleGPS(false);
+ }
} else {
- // Start timer that checks for Permissions
- Log.i(TAG, "Permissions are not good. Need to do some looping to check on stuff.");
-
- final Handler permsHandler = new Handler();
- Runnable runnable = new Runnable() {
- @Override
- public void run() {
- if (LocationServices.getLocationServices(context).areLocationPermissionsGranted()) {
- Log.i(TAG, "Permissions finally granted, so starting Ambient if GPS isn't already enabled");
- // Start Ambient
- if (LocationServices.getLocationServices(context).isGPSEnabled()) {
- LocationServices.getLocationServices(context).toggleGPS(false);
- }
- } else {
- // Restart Handler
- Log.i(TAG, "Permissions not granted yet... let's try again in 30 seconds");
- permsHandler.postDelayed(this, 1000 * 30);
- }
- }
- };
- permsHandler.postDelayed(runnable, 1000 * 10);
+ // Restart Handler
+ Timber.i("Permissions not granted yet... let's try again in 30 seconds");
+ permsHandler.postDelayed(this, 1000 * 30);
}
-
- // Manage Timer Flush
- timer = new Timer();
- timer.schedule(new FlushEventsTimerTask(), flushDelayInitialInMillis, flushDelayInMillis);
- } else {
- Log.d(TAG, "Shutting Telemetry Down");
- // Shut It Down
- events.removeAllElements();
- context.stopService(new Intent(context, TelemetryService.class));
-
- if (timer != null) {
- timer.cancel();
- timer = null;
- }
- }
-
- // Persist
- this.telemetryEnabled = telemetryEnabled;
- SharedPreferences prefs = context.getSharedPreferences(MapboxConstants.MAPBOX_SHARED_PREFERENCES_FILE, Context.MODE_PRIVATE);
- SharedPreferences.Editor editor = prefs.edit();
- editor.putBoolean(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_ENABLED, telemetryEnabled);
- editor.apply();
- editor.commit();
+ }
+ };
+ permsHandler.postDelayed(runnable, 1000 * 10);
+ }
+
+ // Manage Timer Flush
+ timer = new Timer();
+ timer.schedule(new FlushEventsTimerTask(), flushDelayInitialInMillis, flushDelayInMillis);
+ } else {
+ Timber.d("Shutting Telemetry Down");
+ // Shut It Down
+ events.removeAllElements();
+ context.stopService(new Intent(context, TelemetryService.class));
+
+ if (timer != null) {
+ timer.cancel();
+ timer = null;
+ }
}
- /**
- * Immediately attempt to send all events data in the queue to the server.
- *
- * NOTE: Permission set to package private to enable only telemetry code to use this.
- */
- void flushEventsQueueImmediately() {
- Log.i(TAG, "flushEventsQueueImmediately() called...");
- new FlushTheEventsTask().execute();
+ // Persist
+ this.telemetryEnabled = telemetryEnabled;
+ SharedPreferences prefs = context.getSharedPreferences(MapboxConstants.MAPBOX_SHARED_PREFERENCES_FILE,
+ Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = prefs.edit();
+ editor.putBoolean(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_ENABLED, telemetryEnabled);
+ editor.apply();
+ editor.commit();
+ }
+
+ /**
+ * Immediately attempt to send all events data in the queue to the server.
+ * <p>
+ * NOTE: Permission set to package private to enable only telemetry code to use this.
+ */
+ void flushEventsQueueImmediately() {
+ Timber.i("flushEventsQueueImmediately() called...");
+ new FlushTheEventsTask().execute();
+ }
+
+ /**
+ * Centralized method for adding populated event to the queue allowing for cap size checking
+ *
+ * @param event Event to add to the Events Queue
+ */
+ private void putEventOnQueue(@NonNull Hashtable<String, Object> event) {
+ if (event == null) {
+ return;
}
-
- /**
- * Centralized method for adding populated event to the queue allowing for cap size checking
- * @param event Event to add to the Events Queue
- */
- private void putEventOnQueue(@NonNull Hashtable<String, Object> event) {
- if (event == null) {
- return;
- }
- events.add(event);
- if (events.size() == FLUSH_EVENTS_CAP) {
- Log.d(TAG, "eventsSize == flushCap so send data.");
- flushEventsQueueImmediately();
- }
+ events.add(event);
+ if (events.size() == FLUSH_EVENTS_CAP) {
+ Timber.d("eventsSize == flushCap so send data.");
+ flushEventsQueueImmediately();
}
-
- /**
- * Adds a Location Event to the system for processing
- * @param location Location event
- */
- public void addLocationEvent(Location location) {
-
- // NaN and Infinite checks to prevent JSON errors at send to server time
- if (Double.isNaN(location.getLatitude()) || Double.isNaN(location.getLongitude()) || Double.isNaN(location.getAltitude())) {
- return;
- }
-
- if (Double.isInfinite(location.getLatitude()) || Double.isInfinite(location.getLongitude()) || Double.isInfinite(location.getAltitude())) {
- return;
- }
-
- // Add Location even to queue
- Hashtable<String, Object> event = new Hashtable<>();
- event.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_LOCATION);
- event.put(MapboxEvent.ATTRIBUTE_CREATED, generateCreateDate());
- event.put(MapboxEvent.ATTRIBUTE_SOURCE, MapboxEvent.SOURCE_MAPBOX);
- event.put(MapboxEvent.ATTRIBUTE_SESSION_ID, encodeString(mapboxSessionId));
- event.put(MapboxEvent.KEY_LATITUDE, Math.floor(location.getLatitude() * locationEventAccuracy) / locationEventAccuracy);
- event.put(MapboxEvent.KEY_LONGITUDE, Math.floor(location.getLongitude() * locationEventAccuracy) / locationEventAccuracy);
- event.put(MapboxEvent.KEY_ALTITUDE, location.getAltitude());
- event.put(MapboxEvent.ATTRIBUTE_OPERATING_SYSTEM, operatingSystem);
- event.put(MapboxEvent.ATTRIBUTE_APPLICATION_STATE, getApplicationState());
-
- putEventOnQueue(event);
-
- rotateSessionId();
+ }
+
+ /**
+ * Adds a Location Event to the system for processing
+ *
+ * @param location Location event
+ */
+ public void addLocationEvent(Location location) {
+
+ // NaN and Infinite checks to prevent JSON errors at send to server time
+ if (Double.isNaN(location.getLatitude()) || Double.isNaN(location.getLongitude())
+ || Double.isNaN(location.getAltitude()) || Float.isNaN(location.getAccuracy())) {
+ return;
}
- /**
- * Push Interactive Events to the system for processing
- *
- * @param eventWithAttributes Event with attributes
- */
- public void pushEvent(Hashtable<String, Object> eventWithAttributes) {
- if (context == null || accessToken == null) {
- return;
- }
-
- if (eventWithAttributes == null) {
- return;
- }
-
- String eventType = (String) eventWithAttributes.get(MapboxEvent.ATTRIBUTE_EVENT);
- if (TextUtils.isEmpty(eventType)) {
- return;
- }
-
- if (eventType.equalsIgnoreCase(MapboxEvent.TYPE_MAP_LOAD)) {
- // Map Load Data Model
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_USERID, mapboxVendorId);
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_MODEL, Build.MODEL);
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_OPERATING_SYSTEM, operatingSystem);
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_RESOLUTION, displayMetrics.density);
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_ACCESSIBILITY_FONT_SCALE, getAccesibilityFontScaleSize());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_ORIENTATION, getOrientation());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_BATTERY_LEVEL, getBatteryLevel());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_PLUGGED_IN, isPluggedIn());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_CARRIER, getCellularCarrier());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE, getCellularNetworkType());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_WIFI, getConnectedToWifi());
-
- // Put Map Load on events before Turnstile clears it
- putEventOnQueue(eventWithAttributes);
-
- // Turnstile
- pushTurnstileEvent();
-
- // Return immediately to avoid double adding of event
- return;
-
- } else if (eventType.equalsIgnoreCase(MapboxEvent.TYPE_MAP_CLICK)) {
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_ORIENTATION, getOrientation());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_BATTERY_LEVEL, getBatteryLevel());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_PLUGGED_IN, isPluggedIn());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_CARRIER, getCellularCarrier());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE, getCellularNetworkType());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_WIFI, getConnectedToWifi());
- } else if (eventType.equalsIgnoreCase(MapboxEvent.TYPE_MAP_DRAGEND)) {
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_ORIENTATION, getOrientation());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_BATTERY_LEVEL, getBatteryLevel());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_PLUGGED_IN, isPluggedIn());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_CARRIER, getCellularCarrier());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE, getCellularNetworkType());
- eventWithAttributes.put(MapboxEvent.ATTRIBUTE_WIFI, getConnectedToWifi());
- } else {
- Log.w(TAG, "This is not an event type in the Events Data Model.");
- return;
- }
-
- putEventOnQueue(eventWithAttributes);
+ if (Double.isInfinite(location.getLatitude()) || Double.isInfinite(location.getLongitude())
+ || Double.isInfinite(location.getAltitude()) || Float.isInfinite(location.getAccuracy())) {
+ return;
}
- /**
- * Pushes turnstile event for internal billing purposes
- */
- private void pushTurnstileEvent() {
-
- Hashtable<String, Object> event = new Hashtable<>();
- event.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_TURNSTILE);
- event.put(MapboxEvent.ATTRIBUTE_CREATED, generateCreateDate());
- event.put(MapboxEvent.ATTRIBUTE_USERID, mapboxVendorId);
- event.put(MapboxEvent.ATTRIBUTE_ENABLED_TELEMETRY, telemetryEnabled);
-
- events.add(event);
-
- // Send to Server Immediately
- flushEventsQueueImmediately();
- Log.d(TAG, "turnstile event pushed.");
+ // Add Location even to queue
+ Hashtable<String, Object> event = new Hashtable<>();
+ event.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_LOCATION);
+ event.put(MapboxEvent.ATTRIBUTE_CREATED, generateCreateDate());
+ event.put(MapboxEvent.ATTRIBUTE_SOURCE, MapboxEvent.SOURCE_MAPBOX);
+ event.put(MapboxEvent.ATTRIBUTE_SESSION_ID, encodeString(mapboxSessionId));
+ event.put(MapboxEvent.KEY_LATITUDE,
+ Math.floor(location.getLatitude() * locationEventAccuracy) / locationEventAccuracy);
+ event.put(MapboxEvent.KEY_LONGITUDE,
+ Math.floor(location.getLongitude() * locationEventAccuracy) / locationEventAccuracy);
+ event.put(MapboxEvent.KEY_ALTITUDE, location.getAltitude());
+ event.put(MapboxEvent.KEY_HORIZONTAL_ACCURACY, Math.round(location.getAccuracy()));
+ event.put(MapboxEvent.ATTRIBUTE_OPERATING_SYSTEM, operatingSystem);
+ event.put(MapboxEvent.ATTRIBUTE_APPLICATION_STATE, getApplicationState());
+
+ putEventOnQueue(event);
+
+ rotateSessionId();
+ }
+
+ /**
+ * Push Interactive Events to the system for processing
+ *
+ * @param eventWithAttributes Event with attributes
+ */
+ public void pushEvent(Hashtable<String, Object> eventWithAttributes) {
+ if (context == null || accessToken == null) {
+ return;
}
- /**
- * SHA-1 Encoding for strings
- * @param string String to encode
- * @return String encoded if no error, original string if error
- */
- private String encodeString(String string) {
- try {
- if (messageDigest != null) {
- messageDigest.reset();
- messageDigest.update(string.getBytes("UTF-8"));
- byte[] bytes = messageDigest.digest();
-
- // Get the Hex version of the digest
- StringBuilder sb = new StringBuilder();
- for (byte b : bytes) {
- sb.append( String.format("%02X", b) );
- }
- String hex = sb.toString();
-
- return hex;
- }
- } catch (Exception e) {
- Log.w(TAG, "Error encoding string, will return in original form." + e);
- }
- return string;
+ if (eventWithAttributes == null) {
+ return;
}
- /**
- * Changes Session Id based on time boundary
- */
- private void rotateSessionId() {
- long now = System.currentTimeMillis();
- if ((TextUtils.isEmpty(mapboxSessionId)) || (now - mapboxSessionIdLastSet > (SESSION_ID_ROTATION_HOURS * hourInMillis))) {
- mapboxSessionId = UUID.randomUUID().toString();
- mapboxSessionIdLastSet = System.currentTimeMillis();
- }
+ String eventType = (String) eventWithAttributes.get(MapboxEvent.ATTRIBUTE_EVENT);
+ if (TextUtils.isEmpty(eventType)) {
+ return;
}
- private String getOrientation() {
- switch (context.getResources().getConfiguration().orientation) {
- case Configuration.ORIENTATION_LANDSCAPE:
- return "Landscape";
- case Configuration.ORIENTATION_PORTRAIT:
- return "Portrait";
- default:
- return "";
- }
+ if (eventType.equalsIgnoreCase(MapboxEvent.TYPE_MAP_LOAD)) {
+ // Map Load Data Model
+ eventWithAttributes.put(MapboxEvent.ATTRIBUTE_USERID, mapboxVendorId);
+ eventWithAttributes.put(MapboxEvent.ATTRIBUTE_MODEL, Build.MODEL);
+ eventWithAttributes.put(MapboxEvent.ATTRIBUTE_OPERATING_SYSTEM, operatingSystem);
+ eventWithAttributes.put(MapboxEvent.ATTRIBUTE_RESOLUTION, displayMetrics.density);
+ eventWithAttributes.put(MapboxEvent.ATTRIBUTE_ACCESSIBILITY_FONT_SCALE, getAccesibilityFontScaleSize());
+ eventWithAttributes.put(MapboxEvent.ATTRIBUTE_ORIENTATION, getOrientation());
+ eventWithAttributes.put(MapboxEvent.ATTRIBUTE_BATTERY_LEVEL, getBatteryLevel());
+ eventWithAttributes.put(MapboxEvent.ATTRIBUTE_PLUGGED_IN, isPluggedIn());
+ eventWithAttributes.put(MapboxEvent.ATTRIBUTE_CARRIER, getCellularCarrier());
+ eventWithAttributes.put(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE, getCellularNetworkType());
+ eventWithAttributes.put(MapboxEvent.ATTRIBUTE_WIFI, getConnectedToWifi());
+
+ // Put Map Load on events before Turnstile clears it
+ putEventOnQueue(eventWithAttributes);
+
+ // Turnstile
+ pushTurnstileEvent();
+
+ // Return immediately to avoid double adding of event
+ return;
+
+ } else if (eventType.equalsIgnoreCase(MapboxEvent.TYPE_MAP_CLICK)) {
+ eventWithAttributes.put(MapboxEvent.ATTRIBUTE_ORIENTATION, getOrientation());
+ eventWithAttributes.put(MapboxEvent.ATTRIBUTE_BATTERY_LEVEL, getBatteryLevel());
+ eventWithAttributes.put(MapboxEvent.ATTRIBUTE_PLUGGED_IN, isPluggedIn());
+ eventWithAttributes.put(MapboxEvent.ATTRIBUTE_CARRIER, getCellularCarrier());
+ eventWithAttributes.put(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE, getCellularNetworkType());
+ eventWithAttributes.put(MapboxEvent.ATTRIBUTE_WIFI, getConnectedToWifi());
+ } else if (eventType.equalsIgnoreCase(MapboxEvent.TYPE_MAP_DRAGEND)) {
+ eventWithAttributes.put(MapboxEvent.ATTRIBUTE_ORIENTATION, getOrientation());
+ eventWithAttributes.put(MapboxEvent.ATTRIBUTE_BATTERY_LEVEL, getBatteryLevel());
+ eventWithAttributes.put(MapboxEvent.ATTRIBUTE_PLUGGED_IN, isPluggedIn());
+ eventWithAttributes.put(MapboxEvent.ATTRIBUTE_CARRIER, getCellularCarrier());
+ eventWithAttributes.put(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE, getCellularNetworkType());
+ eventWithAttributes.put(MapboxEvent.ATTRIBUTE_WIFI, getConnectedToWifi());
+ } else {
+ Timber.w("This is not an event type in the Events Data Model.");
+ return;
}
- private int getBatteryLevel() {
- int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
- int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
+ putEventOnQueue(eventWithAttributes);
+ }
+
+ /**
+ * Pushes turnstile event for internal billing purposes
+ */
+ private void pushTurnstileEvent() {
+
+ Hashtable<String, Object> event = new Hashtable<>();
+ event.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_TURNSTILE);
+ event.put(MapboxEvent.ATTRIBUTE_CREATED, generateCreateDate());
+ event.put(MapboxEvent.ATTRIBUTE_USERID, mapboxVendorId);
+ event.put(MapboxEvent.ATTRIBUTE_ENABLED_TELEMETRY, telemetryEnabled);
+
+ events.add(event);
+
+ // Send to Server Immediately
+ flushEventsQueueImmediately();
+ Timber.d("turnstile event pushed.");
+ }
+
+ /**
+ * SHA-1 Encoding for strings
+ *
+ * @param string String to encode
+ * @return String encoded if no error, original string if error
+ */
+ private String encodeString(String string) {
+ try {
+ if (messageDigest != null) {
+ messageDigest.reset();
+ messageDigest.update(string.getBytes("UTF-8"));
+ byte[] bytes = messageDigest.digest();
+
+ // Get the Hex version of the digest
+ StringBuilder sb = new StringBuilder();
+ for (byte b : bytes) {
+ sb.append(String.format("%02X", b));
+ }
+ String hex = sb.toString();
- return Math.round((level / (float)scale) * 100);
+ return hex;
+ }
+ } catch (Exception exception) {
+ Timber.w("Error encoding string, will return in original form.", exception);
+ }
+ return string;
+ }
+
+ /**
+ * Changes Session Id based on time boundary
+ */
+ private void rotateSessionId() {
+ long now = System.currentTimeMillis();
+ if ((TextUtils.isEmpty(mapboxSessionId))
+ || (now - mapboxSessionIdLastSet > (SESSION_ID_ROTATION_HOURS * hourInMillis))) {
+ mapboxSessionId = UUID.randomUUID().toString();
+ mapboxSessionIdLastSet = System.currentTimeMillis();
+ }
+ }
+
+ private String getOrientation() {
+ switch (context.getResources().getConfiguration().orientation) {
+ case Configuration.ORIENTATION_LANDSCAPE:
+ return "Landscape";
+ case Configuration.ORIENTATION_PORTRAIT:
+ return "Portrait";
+ default:
+ return "";
+ }
+ }
+
+ private int getBatteryLevel() {
+ int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
+ int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
+
+ return Math.round((level / (float) scale) * 100);
+ }
+
+ /**
+ * Determine if device is plugged in to power via USB or AC or not.
+ * <p>
+ * http://developer.android.com/reference/android/os/BatteryManager.html#EXTRA_PLUGGED
+ *
+ * @return true if plugged in, false if not
+ */
+ private boolean isPluggedIn() {
+
+ int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
+ if (chargePlug == BatteryManager.BATTERY_PLUGGED_USB || chargePlug == BatteryManager.BATTERY_PLUGGED_AC) {
+ return true;
}
- /**
- * Determine if device is plugged in to power via USB or AC or not.
- *
- * http://developer.android.com/reference/android/os/BatteryManager.html#EXTRA_PLUGGED
- * @return true if plugged in, false if not
- */
- private boolean isPluggedIn() {
+ return false;
+ }
- int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
- if (chargePlug == BatteryManager.BATTERY_PLUGGED_USB || chargePlug == BatteryManager.BATTERY_PLUGGED_AC) {
- return true;
- }
+ private String getApplicationState() {
- return false;
+ ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+ List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
+ if (appProcesses == null) {
+ return "";
}
-
- private String getApplicationState() {
-
- ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
- List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
- if (appProcesses == null) {
- return "";
- }
- final String packageName = context.getPackageName();
- for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
- if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) {
- return "Foreground";
- }
- }
- return "Background";
+ final String packageName = context.getPackageName();
+ for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
+ if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND
+ && appProcess.processName.equals(packageName)) {
+ return "Foreground";
+ }
}
-
- private float getAccesibilityFontScaleSize() {
- // Values
- // Small = 0.85
- // Normal = 1.0
- // Large = 1.15
- // Huge = 1.3
-
- return context.getResources().getConfiguration().fontScale;
+ return "Background";
+ }
+
+ private float getAccesibilityFontScaleSize() {
+ // Values
+ // Small = 0.85
+ // Normal = 1.0
+ // Large = 1.15
+ // Huge = 1.3
+
+ return context.getResources().getConfiguration().fontScale;
+ }
+
+ private String getCellularCarrier() {
+ TelephonyManager manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+ String carrierName = manager.getNetworkOperatorName();
+ if (TextUtils.isEmpty(carrierName)) {
+ carrierName = "";
}
-
- private String getCellularCarrier() {
- TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
- String carrierName = manager.getNetworkOperatorName();
- if (TextUtils.isEmpty(carrierName)) {
- carrierName = "";
- }
- return carrierName;
+ return carrierName;
+ }
+
+ private String getCellularNetworkType() {
+ TelephonyManager manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+ switch (manager.getNetworkType()) {
+ case TelephonyManager.NETWORK_TYPE_1xRTT:
+ return "1xRTT";
+ case TelephonyManager.NETWORK_TYPE_CDMA:
+ return "CDMA";
+ case TelephonyManager.NETWORK_TYPE_EDGE:
+ return "EDGE";
+ case TelephonyManager.NETWORK_TYPE_EHRPD:
+ return "EHRPD";
+ case TelephonyManager.NETWORK_TYPE_EVDO_0:
+ return "EVDO_0";
+ case TelephonyManager.NETWORK_TYPE_EVDO_A:
+ return "EVDO_A";
+ case TelephonyManager.NETWORK_TYPE_EVDO_B:
+ return "EVDO_B";
+ case TelephonyManager.NETWORK_TYPE_GPRS:
+ return "GPRS";
+ case TelephonyManager.NETWORK_TYPE_HSDPA:
+ return "HSDPA";
+ case TelephonyManager.NETWORK_TYPE_HSPA:
+ return "HSPA";
+ case TelephonyManager.NETWORK_TYPE_HSPAP:
+ return "HSPAP";
+ case TelephonyManager.NETWORK_TYPE_HSUPA:
+ return "HSUPA";
+ case TelephonyManager.NETWORK_TYPE_IDEN:
+ return "IDEN";
+ case TelephonyManager.NETWORK_TYPE_LTE:
+ return "LTE";
+ case TelephonyManager.NETWORK_TYPE_UMTS:
+ return "UMTS";
+ case TelephonyManager.NETWORK_TYPE_UNKNOWN:
+ return "Unknown";
+ default:
+ return "";
}
+ }
- private String getCellularNetworkType () {
- TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
- switch (manager.getNetworkType()) {
- case TelephonyManager.NETWORK_TYPE_1xRTT:
- return "1xRTT";
- case TelephonyManager.NETWORK_TYPE_CDMA:
- return "CDMA";
- case TelephonyManager.NETWORK_TYPE_EDGE:
- return "EDGE";
- case TelephonyManager.NETWORK_TYPE_EHRPD:
- return "EHRPD";
- case TelephonyManager.NETWORK_TYPE_EVDO_0:
- return "EVDO_0";
- case TelephonyManager.NETWORK_TYPE_EVDO_A:
- return "EVDO_A";
- case TelephonyManager.NETWORK_TYPE_EVDO_B:
- return "EVDO_B";
- case TelephonyManager.NETWORK_TYPE_GPRS:
- return "GPRS";
- case TelephonyManager.NETWORK_TYPE_HSDPA:
- return "HSDPA";
- case TelephonyManager.NETWORK_TYPE_HSPA:
- return "HSPA";
- case TelephonyManager.NETWORK_TYPE_HSPAP:
- return "HSPAP";
- case TelephonyManager.NETWORK_TYPE_HSUPA:
- return "HSUPA";
- case TelephonyManager.NETWORK_TYPE_IDEN:
- return "IDEN";
- case TelephonyManager.NETWORK_TYPE_LTE:
- return "LTE";
- case TelephonyManager.NETWORK_TYPE_UMTS:
- return "UMTS";
- case TelephonyManager.NETWORK_TYPE_UNKNOWN:
- return "Unknown";
- default:
- return "";
- }
- }
+ public Boolean getConnectedToWifi() {
- public Boolean getConnectedToWifi() {
-
- Boolean status = false;
- WifiManager wifiMgr = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
- if (wifiMgr.isWifiEnabled()) {
- try {
- WifiInfo wifiInfo = wifiMgr.getConnectionInfo();
- if (wifiInfo.getNetworkId() != -1){
- status = true;
- }
- } catch (Exception e) {
- Log.w(TAG, "Error getting Wifi Connection Status: " + e);
- status = false;
- }
+ Boolean status = false;
+ WifiManager wifiMgr = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+ if (wifiMgr.isWifiEnabled()) {
+ try {
+ WifiInfo wifiInfo = wifiMgr.getConnectionInfo();
+ if (wifiInfo.getNetworkId() != -1) {
+ status = true;
}
-
- return status;
+ } catch (Exception exception) {
+ Timber.w("Error getting Wifi Connection Status: ", exception);
+ status = false;
+ }
}
-
- /**
- * Task responsible for converting stored events and sending them to the server
- */
- private class FlushTheEventsTask extends AsyncTask<Void, Void, Void> {
-
- @Override
- protected Void doInBackground(Void... voids) {
-
- if (events.isEmpty()) {
- Log.d(TAG, "No events in the queue to send so returning.");
- return null;
+ return status;
+ }
+
+
+ /**
+ * Task responsible for converting stored events and sending them to the server
+ */
+ private class FlushTheEventsTask extends AsyncTask<Void, Void, Void> {
+
+ @Override
+ protected Void doInBackground(Void... voids) {
+
+ if (events.isEmpty()) {
+ Timber.d("No events in the queue to send so returning.");
+ return null;
+ }
+
+ // Check for NetworkConnectivity
+ if (!Mapbox.isConnected()) {
+ Timber.w("Not connected to network, so empty events cache and return without attempting to send events");
+ // Make sure that events don't pile up when Offline
+ // and thus impact available memory over time.
+ events.removeAllElements();
+ return null;
+ }
+
+ Response response = null;
+
+ try {
+ // Send data
+ // =========
+ JSONArray jsonArray = new JSONArray();
+
+ Vector<Hashtable<String, Object>> eventsClone = (Vector<Hashtable<String, Object>>) events.clone();
+
+ for (Hashtable<String, Object> evt : eventsClone) {
+ JSONObject jsonObject = new JSONObject();
+
+ // Build the JSON but only if there's a value for it in the evt
+ jsonObject.putOpt(MapboxEvent.ATTRIBUTE_EVENT, evt.get(MapboxEvent.ATTRIBUTE_EVENT));
+ jsonObject.putOpt(MapboxEvent.ATTRIBUTE_CREATED, evt.get(MapboxEvent.ATTRIBUTE_CREATED));
+ jsonObject.putOpt(MapboxEvent.ATTRIBUTE_USERID, evt.get(MapboxEvent.ATTRIBUTE_USERID));
+ jsonObject.putOpt(MapboxEvent.ATTRIBUTE_ENABLED_TELEMETRY, evt.get(MapboxEvent.ATTRIBUTE_ENABLED_TELEMETRY));
+ jsonObject.putOpt(MapboxEvent.ATTRIBUTE_SOURCE, evt.get(MapboxEvent.ATTRIBUTE_SOURCE));
+ jsonObject.putOpt(MapboxEvent.ATTRIBUTE_SESSION_ID, evt.get(MapboxEvent.ATTRIBUTE_SESSION_ID));
+ jsonObject.putOpt(MapboxEvent.KEY_LATITUDE, evt.get(MapboxEvent.KEY_LATITUDE));
+
+ // Make sure Longitude Is Wrapped
+ if (evt.containsKey(MapboxEvent.KEY_LONGITUDE)) {
+ double lon = (double) evt.get(MapboxEvent.KEY_LONGITUDE);
+ if ((lon < GeoConstants.MIN_LONGITUDE) || (lon > GeoConstants.MAX_LONGITUDE)) {
+ lon = MathUtils.wrap(lon, GeoConstants.MIN_LONGITUDE, GeoConstants.MAX_LONGITUDE);
}
-
- // Check for NetworkConnectivity
- if (!MapboxAccountManager.getInstance().isConnected()) {
- Log.w(TAG, "Not connected to network, so empty events cache and return without attempting to send events");
- // Make sure that events don't pile up when Offline
- // and thus impact available memory over time.
- events.removeAllElements();
- return null;
+ jsonObject.put(MapboxEvent.KEY_LONGITUDE, lon);
+ }
+
+ jsonObject.putOpt(MapboxEvent.KEY_ALTITUDE, evt.get(MapboxEvent.KEY_ALTITUDE));
+ jsonObject.putOpt(MapboxEvent.KEY_ZOOM, evt.get(MapboxEvent.KEY_ZOOM));
+ jsonObject.putOpt(MapboxEvent.ATTRIBUTE_OPERATING_SYSTEM, evt.get(MapboxEvent.ATTRIBUTE_OPERATING_SYSTEM));
+ jsonObject.putOpt(MapboxEvent.ATTRIBUTE_USERID, evt.get(MapboxEvent.ATTRIBUTE_USERID));
+ jsonObject.putOpt(MapboxEvent.ATTRIBUTE_MODEL, evt.get(MapboxEvent.ATTRIBUTE_MODEL));
+ jsonObject.putOpt(MapboxEvent.ATTRIBUTE_RESOLUTION, evt.get(MapboxEvent.ATTRIBUTE_RESOLUTION));
+ jsonObject.putOpt(MapboxEvent.ATTRIBUTE_ACCESSIBILITY_FONT_SCALE,
+ evt.get(MapboxEvent.ATTRIBUTE_ACCESSIBILITY_FONT_SCALE));
+ jsonObject.putOpt(MapboxEvent.ATTRIBUTE_BATTERY_LEVEL, evt.get(MapboxEvent.ATTRIBUTE_BATTERY_LEVEL));
+ jsonObject.putOpt(MapboxEvent.ATTRIBUTE_PLUGGED_IN, evt.get(MapboxEvent.ATTRIBUTE_PLUGGED_IN));
+ jsonObject.putOpt(MapboxEvent.ATTRIBUTE_WIFI, evt.get(MapboxEvent.ATTRIBUTE_WIFI));
+
+ // Special Cases where empty string is denoting null and therefore should not be sent at all
+ // This arises as thread safe Hashtable does not accept null values (nor keys)
+ if (evt.containsKey(MapboxEvent.ATTRIBUTE_ORIENTATION)) {
+ String orientation = (String) evt.get(MapboxEvent.ATTRIBUTE_ORIENTATION);
+ if (!TextUtils.isEmpty(orientation)) {
+ jsonObject.putOpt(MapboxEvent.ATTRIBUTE_ORIENTATION, orientation);
}
-
- Response response = null;
-
- try {
- // Send data
- // =========
- JSONArray jsonArray = new JSONArray();
-
- Vector<Hashtable<String, Object>> eventsClone = (Vector<Hashtable<String, Object>>) events.clone();
-
- for (Hashtable<String, Object> evt : eventsClone) {
- JSONObject jsonObject = new JSONObject();
-
- // Build the JSON but only if there's a value for it in the evt
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_EVENT, evt.get(MapboxEvent.ATTRIBUTE_EVENT));
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_CREATED, evt.get(MapboxEvent.ATTRIBUTE_CREATED));
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_USERID, evt.get(MapboxEvent.ATTRIBUTE_USERID));
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_ENABLED_TELEMETRY, evt.get(MapboxEvent.ATTRIBUTE_ENABLED_TELEMETRY));
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_SOURCE, evt.get(MapboxEvent.ATTRIBUTE_SOURCE));
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_SESSION_ID, evt.get(MapboxEvent.ATTRIBUTE_SESSION_ID));
- jsonObject.putOpt(MapboxEvent.KEY_LATITUDE, evt.get(MapboxEvent.KEY_LATITUDE));
-
- // Make sure Longitude Is Wrapped
- if (evt.containsKey(MapboxEvent.KEY_LONGITUDE)) {
- double lon = (double)evt.get(MapboxEvent.KEY_LONGITUDE);
- if ((lon < GeoConstants.MIN_LONGITUDE) || (lon > GeoConstants.MAX_LONGITUDE)) {
- lon = MathUtils.wrap(lon, GeoConstants.MIN_LONGITUDE, GeoConstants.MAX_LONGITUDE);
- }
- jsonObject.put(MapboxEvent.KEY_LONGITUDE, lon);
- }
-
- jsonObject.putOpt(MapboxEvent.KEY_ALTITUDE, evt.get(MapboxEvent.KEY_ALTITUDE));
- jsonObject.putOpt(MapboxEvent.KEY_ZOOM, evt.get(MapboxEvent.KEY_ZOOM));
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_OPERATING_SYSTEM, evt.get(MapboxEvent.ATTRIBUTE_OPERATING_SYSTEM));
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_USERID, evt.get(MapboxEvent.ATTRIBUTE_USERID));
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_MODEL, evt.get(MapboxEvent.ATTRIBUTE_MODEL));
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_RESOLUTION, evt.get(MapboxEvent.ATTRIBUTE_RESOLUTION));
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_ACCESSIBILITY_FONT_SCALE, evt.get(MapboxEvent.ATTRIBUTE_ACCESSIBILITY_FONT_SCALE));
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_BATTERY_LEVEL, evt.get(MapboxEvent.ATTRIBUTE_BATTERY_LEVEL));
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_PLUGGED_IN, evt.get(MapboxEvent.ATTRIBUTE_PLUGGED_IN));
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_WIFI, evt.get(MapboxEvent.ATTRIBUTE_WIFI));
-
- // Special Cases where empty string is denoting null and therefore should not be sent at all
- // This arises as thread safe Hashtable does not accept null values (nor keys)
- if (evt.containsKey(MapboxEvent.ATTRIBUTE_ORIENTATION)) {
- String orientation = (String)evt.get(MapboxEvent.ATTRIBUTE_ORIENTATION);
- if (!TextUtils.isEmpty(orientation)) {
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_ORIENTATION, orientation);
- }
- }
- if (evt.containsKey(MapboxEvent.ATTRIBUTE_CARRIER)) {
- String carrier = (String)evt.get(MapboxEvent.ATTRIBUTE_CARRIER);
- if (!TextUtils.isEmpty(carrier)) {
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_CARRIER, carrier);
- }
- }
- if (evt.containsKey(MapboxEvent.ATTRIBUTE_APPLICATION_STATE)) {
- String appState = (String)evt.get(MapboxEvent.ATTRIBUTE_APPLICATION_STATE);
- if (!TextUtils.isEmpty(appState)) {
- jsonObject.putOpt(MapboxEvent.ATTRIBUTE_APPLICATION_STATE, evt.get(MapboxEvent.ATTRIBUTE_APPLICATION_STATE));
- }
- }
-
- // Special Cases where null has to be passed if no value exists
- // Requires using put() instead of putOpt()
- String eventType = (String)evt.get(MapboxEvent.ATTRIBUTE_EVENT);
- if (!TextUtils.isEmpty(eventType) && eventType.equalsIgnoreCase(MapboxEvent.TYPE_MAP_CLICK)) {
- jsonObject.put(MapboxEvent.KEY_GESTURE_ID, evt.get(MapboxEvent.KEY_GESTURE_ID));
- }
- if (evt.containsKey(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE)) {
- String cellularNetworkType = (String)evt.get(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE);
- if (TextUtils.isEmpty(cellularNetworkType)) {
- jsonObject.put(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE, null);
- } else {
- jsonObject.put(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE, evt.get(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE));
- }
- }
-
- jsonArray.put(jsonObject);
- }
-
- // Based on http://square.github.io/okhttp/3.x/okhttp/okhttp3/CertificatePinner.html
- CertificatePinner.Builder certificatePinnerBuilder = new CertificatePinner.Builder();
- if(stagingEnv){
- // Staging - Geotrust
- certificatePinnerBuilder
- .add("cloudfront-staging.tilestream.net", "sha256/3euxrJOrEZI15R4104UsiAkDqe007EPyZ6eTL/XxdAY=")
- .add("cloudfront-staging.tilestream.net", "sha256/5kJvNEMw0KjrCAu7eXY5HZdvyCS13BbA0VJG1RSP91w=")
- .add("cloudfront-staging.tilestream.net", "sha256/r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=");
- }else{
- certificatePinnerBuilder
- // Prod - Geotrust
- .add("events.mapbox.com", "sha256/BhynraKizavqoC5U26qgYuxLZst6pCu9J5stfL6RSYY=")
- .add("events.mapbox.com", "sha256/owrR9U9FWDWtrFF+myoRIu75JwU4sJwzvhCNLZoY37g=")
- .add("events.mapbox.com", "sha256/SQVGZiOrQXi+kqxcvWWE96HhfydlLVqFr4lQTqI5qqo=")
- // Prod - DigiCert
- .add("events.mapbox.com", "sha256/Tb0uHZ/KQjWh8N9+CZFLc4zx36LONQ55l6laDi1qtT4=")
- .add("events.mapbox.com", "sha256/RRM1dGqnDFsCJXBTHky16vi1obOlCgFFn/yOhI/y+ho=")
- .add("events.mapbox.com", "sha256/WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=");
- }
-
- OkHttpClient client = new OkHttpClient.Builder()
- .certificatePinner(certificatePinnerBuilder.build())
- .addInterceptor(new GzipRequestInterceptor())
- .build();
- RequestBody body = RequestBody.create(JSON, jsonArray.toString());
-
- String url = eventsURL + "/events/v2?access_token=" + accessToken;
-
- Request request = new Request.Builder()
- .url(url)
- .header("User-Agent", userAgent)
- .post(body)
- .build();
- 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();
+ }
+ if (evt.containsKey(MapboxEvent.ATTRIBUTE_CARRIER)) {
+ String carrier = (String) evt.get(MapboxEvent.ATTRIBUTE_CARRIER);
+ if (!TextUtils.isEmpty(carrier)) {
+ jsonObject.putOpt(MapboxEvent.ATTRIBUTE_CARRIER, carrier);
}
+ }
+ if (evt.containsKey(MapboxEvent.ATTRIBUTE_APPLICATION_STATE)) {
+ String appState = (String) evt.get(MapboxEvent.ATTRIBUTE_APPLICATION_STATE);
+ if (!TextUtils.isEmpty(appState)) {
+ jsonObject.putOpt(MapboxEvent.ATTRIBUTE_APPLICATION_STATE,
+ evt.get(MapboxEvent.ATTRIBUTE_APPLICATION_STATE));
+ }
+ }
+
+ // Special Cases where null has to be passed if no value exists
+ // Requires using put() instead of putOpt()
+ String eventType = (String) evt.get(MapboxEvent.ATTRIBUTE_EVENT);
+ if (!TextUtils.isEmpty(eventType) && eventType.equalsIgnoreCase(MapboxEvent.TYPE_MAP_CLICK)) {
+ jsonObject.put(MapboxEvent.KEY_GESTURE_ID, evt.get(MapboxEvent.KEY_GESTURE_ID));
+ }
+ if (evt.containsKey(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE)) {
+ String cellularNetworkType = (String) evt.get(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE);
+ if (TextUtils.isEmpty(cellularNetworkType)) {
+ jsonObject.put(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE, null);
+ } else {
+ jsonObject.put(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE,
+ evt.get(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE));
+ }
+ }
+
+ jsonArray.put(jsonObject);
+ }
+
+ // Based on http://square.github.io/okhttp/3.x/okhttp/okhttp3/CertificatePinner.html
+ CertificatePinner.Builder certificatePinnerBuilder = new CertificatePinner.Builder();
+ if (stagingEnv) {
+ // Staging - Geotrust
+ certificatePinnerBuilder
+ .add("cloudfront-staging.tilestream.net", "sha256/3euxrJOrEZI15R4104UsiAkDqe007EPyZ6eTL/XxdAY=")
+ .add("cloudfront-staging.tilestream.net", "sha256/5kJvNEMw0KjrCAu7eXY5HZdvyCS13BbA0VJG1RSP91w=")
+ .add("cloudfront-staging.tilestream.net", "sha256/r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=");
+ } else {
+ certificatePinnerBuilder
+ // Prod - Geotrust
+ .add("events.mapbox.com", "sha256/BhynraKizavqoC5U26qgYuxLZst6pCu9J5stfL6RSYY=")
+ .add("events.mapbox.com", "sha256/owrR9U9FWDWtrFF+myoRIu75JwU4sJwzvhCNLZoY37g=")
+ .add("events.mapbox.com", "sha256/SQVGZiOrQXi+kqxcvWWE96HhfydlLVqFr4lQTqI5qqo=")
+ // Prod - DigiCert
+ .add("events.mapbox.com", "sha256/Tb0uHZ/KQjWh8N9+CZFLc4zx36LONQ55l6laDi1qtT4=")
+ .add("events.mapbox.com", "sha256/RRM1dGqnDFsCJXBTHky16vi1obOlCgFFn/yOhI/y+ho=")
+ .add("events.mapbox.com", "sha256/WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=");
+ }
- return null;
+ OkHttpClient client = new OkHttpClient.Builder()
+ .certificatePinner(certificatePinnerBuilder.build())
+ .addInterceptor(new GzipRequestInterceptor())
+ .build();
+ RequestBody body = RequestBody.create(JSON, jsonArray.toString());
+
+ String url = eventsURL + "/events/v2?access_token=" + accessToken;
+
+ Request request = new Request.Builder()
+ .url(url)
+ .header("User-Agent", userAgent)
+ .post(body)
+ .build();
+ response = client.newCall(request).execute();
+ Timber.d("response code = " + response.code() + " for events " + events.size());
+
+ } catch (Exception exception) {
+ Timber.e("FlushTheEventsTask borked: ", exception);
+ exception.printStackTrace();
+ } finally {
+ if (response != null && response.body() != null) {
+ response.body().close();
}
+ // Reset Events
+ // ============
+ events.removeAllElements();
+ }
+ return null;
}
+ }
+
+ /**
+ * TimerTask responsible for sending event data to server
+ */
+ private class FlushEventsTimerTask extends TimerTask {
/**
- * TimerTask responsible for sending event data to server
+ * The task to run should be specified in the implementation of the {@code run()}
+ * method.
*/
- private class FlushEventsTimerTask extends TimerTask {
- /**
- * The task to run should be specified in the implementation of the {@code run()}
- * method.
- */
- @Override
- public void run() {
- new FlushTheEventsTask().execute();
- }
+ @Override
+ public void run() {
+ new FlushTheEventsTask().execute();
}
-
- private String getApplicationIdentifier() {
- try {
- PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
- return String.format(MapboxConstants.MAPBOX_LOCALE, "%s/%s/%s", context.getPackageName(), packageInfo.versionName, packageInfo.versionCode);
- } catch (Exception e) {
- return "";
- }
+ }
+
+ private String getApplicationIdentifier() {
+ try {
+ PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
+ return String.format(MapboxConstants.MAPBOX_LOCALE, "%s/%s/%s", context.getPackageName(),
+ packageInfo.versionName, packageInfo.versionCode);
+ } catch (Exception exception) {
+ return "";
}
-}
+ }
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryLocationReceiver.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryLocationReceiver.java
index c18da41e4b..2274fb2b82 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryLocationReceiver.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryLocationReceiver.java
@@ -5,68 +5,66 @@ import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationManager;
-import android.os.Handler;
-import android.util.Log;
/**
* Listener for Location updates generated by implementing app.
*/
public class TelemetryLocationReceiver extends BroadcastReceiver {
- private static final String TAG = "TelemLocationReceiver";
+ public static final String INTENT_STRING = "com.mapbox.mapboxsdk.telemetry.TelemetryLocationReceiver";
- public static final String INTENT_STRING = "com.mapbox.mapboxsdk.telemetry.TelemetryLocationReceiver";
+ /**
+ * Default Constructor
+ */
+ public TelemetryLocationReceiver() {
+ super();
+ }
- /**
- * Default Constructor
- */
- public TelemetryLocationReceiver() {
- super();
+ /**
+ * This method is called when the BroadcastReceiver is receiving an Intent
+ * broadcast. During this time you can use the other methods on
+ * BroadcastReceiver to view/modify the current result values. This method
+ * is always called within the main thread of its process, unless you
+ * explicitly asked for it to be scheduled on a different thread using
+ * {@link Context#registerReceiver(BroadcastReceiver,
+ * android.content.IntentFilter, String, android.os.Handler)}. When it runs on the main
+ * thread you should
+ * never perform long-running operations in it (there is a timeout of
+ * 10 seconds that the system allows before considering the receiver to
+ * be blocked and a candidate to be killed). You cannot launch a popup dialog
+ * in your implementation of onReceive().
+ * <p>
+ * <p><b>If this BroadcastReceiver was launched through a &lt;receiver&gt; tag,
+ * then the object is no longer alive after returning from this
+ * function.</b> This means you should not perform any operations that
+ * return a result to you asynchronously -- in particular, for interacting
+ * with services, you should use
+ * {@link Context#startService(Intent)} instead of
+ * {@link Context#bindService(Intent, android.content.ServiceConnection, int)}. If you wish
+ * to interact with a service that is already running, you can use
+ * {@link #peekService}.
+ * <p>
+ * <p>The Intent filters used in {@link Context#registerReceiver}
+ * and in application manifests are <em>not</em> guaranteed to be exclusive. They
+ * are hints to the operating system about how to find suitable recipients. It is
+ * possible for senders to force delivery to specific recipients, bypassing filter
+ * resolution. For this reason, {@link #onReceive(Context, Intent) onReceive()}
+ * implementations should respond only to known actions, ignoring any unexpected
+ * Intents that they may receive.
+ *
+ * @param context The Context in which the receiver is running.
+ * @param intent The Intent being received.
+ */
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent == null || intent.getExtras() == null) {
+ // see https://github.com/mapbox/mapbox-gl-native/issues/6934
+ return;
}
- /**
- * This method is called when the BroadcastReceiver is receiving an Intent
- * broadcast. During this time you can use the other methods on
- * BroadcastReceiver to view/modify the current result values. This method
- * is always called within the main thread of its process, unless you
- * explicitly asked for it to be scheduled on a different thread using
- * {@link Context#registerReceiver(BroadcastReceiver,
- * IntentFilter, String, Handler)}. When it runs on the main
- * thread you should
- * never perform long-running operations in it (there is a timeout of
- * 10 seconds that the system allows before considering the receiver to
- * be blocked and a candidate to be killed). You cannot launch a popup dialog
- * in your implementation of onReceive().
- *
- * <p><b>If this BroadcastReceiver was launched through a &lt;receiver&gt; tag,
- * then the object is no longer alive after returning from this
- * function.</b> This means you should not perform any operations that
- * return a result to you asynchronously -- in particular, for interacting
- * with services, you should use
- * {@link Context#startService(Intent)} instead of
- * {@link Context#bindService(Intent, ServiceConnection, int)}. If you wish
- * to interact with a service that is already running, you can use
- * {@link #peekService}.
- *
- * <p>The Intent filters used in {@link Context#registerReceiver}
- * and in application manifests are <em>not</em> guaranteed to be exclusive. They
- * are hints to the operating system about how to find suitable recipients. It is
- * possible for senders to force delivery to specific recipients, bypassing filter
- * resolution. For this reason, {@link #onReceive(Context, Intent) onReceive()}
- * implementations should respond only to known actions, ignoring any unexpected
- * Intents that they may receive.
- *
- * @param context The Context in which the receiver is running.
- * @param intent The Intent being received.
- */
- @Override
- public void onReceive(Context context, Intent intent) {
- Location location = (Location)intent.getExtras().get(LocationManager.KEY_LOCATION_CHANGED);
- if (location != null) {
-// Log.d(TAG, "location received = " + location);
- MapboxEventManager.getMapboxEventManager().addLocationEvent(location);
- } else {
- Log.d(TAG, "location NOT received");
- }
+ Location location = (Location) intent.getExtras().get(LocationManager.KEY_LOCATION_CHANGED);
+ if (location != null) {
+ MapboxEventManager.getMapboxEventManager().addLocationEvent(location);
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryService.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryService.java
index 008f355f29..a965591f75 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryService.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryService.java
@@ -8,148 +8,147 @@ import android.content.pm.ServiceInfo;
import android.os.AsyncTask;
import android.os.IBinder;
import android.support.annotation.Nullable;
-import android.util.Log;
+
+import timber.log.Timber;
/**
* Manages Startup and Shutdown of Telemetry resources
*/
public class TelemetryService extends Service {
- private static final String TAG = "TelemetryService";
-
- private TelemetryLocationReceiver telemetryLocationReceiver = null;
-
- /**
- * Return the communication channel to the service. May return null if
- * clients can not bind to the service. The returned
- * {@link IBinder} is usually for a complex interface
- * that has been <a href="{@docRoot}guide/components/aidl.html">described using
- * aidl</a>.
- *
- * <p><em>Note that unlike other application components, calls on to the
- * IBinder interface returned here may not happen on the main thread
- * of the process</em>. More information about the main thread can be found in
- * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html">Processes and
- * Threads</a>.</p>
- *
- * @param intent The Intent that was used to bind to this service,
- * as given to {@link Context#bindService
- * Context.bindService}. Note that any extras that were included with
- * the Intent at that point will <em>not</em> be seen here.
- * @return Return an IBinder through which clients can call on to the
- * service.
- */
- @Nullable
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
-
-
- /**
- * Called by the system when the service is first created. Do not call this method directly.
- */
- @Override
- public void onCreate() {
- super.onCreate();
-
- Log.i(TAG, "onCreate() called");
-
- // Enable Location Listening for lifecycle of app
- IntentFilter filter = new IntentFilter(TelemetryLocationReceiver.INTENT_STRING);
- telemetryLocationReceiver = new TelemetryLocationReceiver();
- registerReceiver(telemetryLocationReceiver, filter);
- }
-
- /**
- * Called by the system to notify a Service that it is no longer used and is being removed. The
- * service should clean up any resources it holds (threads, registered
- * receivers, etc) at this point. Upon return, there will be no more calls
- * in to this Service object and it is effectively dead. Do not call this method directly.
- */
- @Override
- public void onDestroy() {
- shutdownTelemetry();
- super.onDestroy();
+ private TelemetryLocationReceiver telemetryLocationReceiver = null;
+
+ /**
+ * Return the communication channel to the service. May return null if
+ * clients can not bind to the service. The returned
+ * {@link IBinder} is usually for a complex interface
+ * that has been <a href="{@docRoot}guide/components/aidl.html">described using
+ * aidl</a>.
+ * <p>
+ * <p><em>Note that unlike other application components, calls on to the
+ * IBinder interface returned here may not happen on the main thread
+ * of the process</em>. More information about the main thread can be found in
+ * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html">Processes and
+ * Threads</a>.</p>
+ *
+ * @param intent The Intent that was used to bind to this service,
+ * as given to {@link Context#bindService
+ * Context.bindService}. Note that any extras that were included with
+ * the Intent at that point will <em>not</em> be seen here.
+ * @return Return an IBinder through which clients can call on to the
+ * service.
+ */
+ @Nullable
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+
+ /**
+ * Called by the system when the service is first created. Do not call this method directly.
+ */
+ @Override
+ public void onCreate() {
+ super.onCreate();
+
+ Timber.i("onCreate() called");
+
+ // Enable Location Listening for lifecycle of app
+ IntentFilter filter = new IntentFilter(TelemetryLocationReceiver.INTENT_STRING);
+ telemetryLocationReceiver = new TelemetryLocationReceiver();
+ registerReceiver(telemetryLocationReceiver, filter);
+ }
+
+ /**
+ * Called by the system to notify a Service that it is no longer used and is being removed. The
+ * service should clean up any resources it holds (threads, registered
+ * receivers, etc) at this point. Upon return, there will be no more calls
+ * in to this Service object and it is effectively dead. Do not call this method directly.
+ */
+ @Override
+ public void onDestroy() {
+ shutdownTelemetry();
+ super.onDestroy();
+ }
+
+ /**
+ * This is called if the service is currently running and the user has
+ * removed a task that comes from the service's application. If you have
+ * set {@link ServiceInfo#FLAG_STOP_WITH_TASK ServiceInfo.FLAG_STOP_WITH_TASK}
+ * then you will not receive this callback; instead, the service will simply
+ * be stopped.
+ *
+ * @param rootIntent The original root Intent that was used to launch
+ * the task that is being removed.
+ */
+ @Override
+ public void onTaskRemoved(Intent rootIntent) {
+ shutdownTelemetry();
+ super.onTaskRemoved(rootIntent);
+ }
+
+ /**
+ * Called by the system every time a client explicitly starts the service by calling
+ * {@link Context#startService}, providing the arguments it supplied and a
+ * unique integer token representing the start request. Do not call this method directly.
+ * <p>
+ * <p>For backwards compatibility, the default implementation calls
+ * {@link #onStart} and returns either {@link #START_STICKY}
+ * or {@link #START_STICKY_COMPATIBILITY}.
+ * </p>
+ * <p>If you need your application to run on platform versions prior to API
+ * level 5, you can use the following model to handle the older {@link #onStart}
+ * callback in that case. The <code>handleCommand</code> method is implemented by
+ * you as appropriate:
+ * </p>
+ * <p>
+ * <p class="caution">Note that the system calls this on your
+ * service's main thread. A service's main thread is the same
+ * thread where UI operations take place for Activities running in the
+ * same process. You should always avoid stalling the main
+ * thread's event loop. When doing long-running operations,
+ * network calls, or heavy disk I/O, you should kick off a new
+ * thread, or use {@link AsyncTask}.</p>
+ *
+ * @param intent The Intent supplied to {@link Context#startService},
+ * as given. This may be null if the service is being restarted after
+ * its process has gone away, and it had previously returned anything
+ * except {@link #START_STICKY_COMPATIBILITY}.
+ * @param flags Additional data about this start request. Currently either
+ * 0, {@link #START_FLAG_REDELIVERY}, or {@link #START_FLAG_RETRY}.
+ * @param startId A unique integer representing this specific request to
+ * start. Use with {@link #stopSelfResult(int)}.
+ * @return The return value indicates what semantics the system should
+ * use for the service's current started state. It may be one of the
+ * constants associated with the {@link #START_CONTINUATION_MASK} bits.
+ * @see #stopSelfResult(int)
+ */
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+
+ Timber.i("onStartCommand() called");
+
+ return START_NOT_STICKY;
+ }
+
+ private void shutdownTelemetry() {
+
+ // Send Any Remaining events to the server
+ MapboxEventManager.getMapboxEventManager().flushEventsQueueImmediately();
+
+ // Undesired, but needed trick to keep app alive long enough for data to get to server
+ try {
+ Thread.sleep(1000);
+ } catch (Exception exception) {
+ Timber.e("Error while trying to sleep for 1 second: " + exception);
}
- /**
- * This is called if the service is currently running and the user has
- * removed a task that comes from the service's application. If you have
- * set {@link ServiceInfo#FLAG_STOP_WITH_TASK ServiceInfo.FLAG_STOP_WITH_TASK}
- * then you will not receive this callback; instead, the service will simply
- * be stopped.
- *
- * @param rootIntent The original root Intent that was used to launch
- * the task that is being removed.
- */
- @Override
- public void onTaskRemoved(Intent rootIntent) {
- shutdownTelemetry();
- super.onTaskRemoved(rootIntent);
+ try {
+ unregisterReceiver(telemetryLocationReceiver);
+ } catch (IllegalArgumentException illegalArgumentException) {
+ Timber.e("Error when unregisterReceiver: " + illegalArgumentException);
}
- /**
- * Called by the system every time a client explicitly starts the service by calling
- * {@link Context#startService}, providing the arguments it supplied and a
- * unique integer token representing the start request. Do not call this method directly.
- *
- * <p>For backwards compatibility, the default implementation calls
- * {@link #onStart} and returns either {@link #START_STICKY}
- * or {@link #START_STICKY_COMPATIBILITY}.
- * </p>
- * <p>If you need your application to run on platform versions prior to API
- * level 5, you can use the following model to handle the older {@link #onStart}
- * callback in that case. The <code>handleCommand</code> method is implemented by
- * you as appropriate:
- * </p>
- *
- * <p class="caution">Note that the system calls this on your
- * service's main thread. A service's main thread is the same
- * thread where UI operations take place for Activities running in the
- * same process. You should always avoid stalling the main
- * thread's event loop. When doing long-running operations,
- * network calls, or heavy disk I/O, you should kick off a new
- * thread, or use {@link AsyncTask}.</p>
- *
- * @param intent The Intent supplied to {@link Context#startService},
- * as given. This may be null if the service is being restarted after
- * its process has gone away, and it had previously returned anything
- * except {@link #START_STICKY_COMPATIBILITY}.
- * @param flags Additional data about this start request. Currently either
- * 0, {@link #START_FLAG_REDELIVERY}, or {@link #START_FLAG_RETRY}.
- * @param startId A unique integer representing this specific request to
- * start. Use with {@link #stopSelfResult(int)}.
- * @return The return value indicates what semantics the system should
- * use for the service's current started state. It may be one of the
- * constants associated with the {@link #START_CONTINUATION_MASK} bits.
- * @see #stopSelfResult(int)
- */
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
-
- Log.i(TAG, "onStartCommand() called");
-
- return START_NOT_STICKY;
- }
-
- private void shutdownTelemetry() {
-
- // Send Any Remaining events to the server
- MapboxEventManager.getMapboxEventManager().flushEventsQueueImmediately();
-
- // Undesired, but needed trick to keep app alive long enough for data to get to server
- try {
- Thread.sleep(1000);
- } catch (Exception e) {
- Log.e(TAG, "Error while trying to sleep for 1 second: " + e);
- }
-
- try {
- unregisterReceiver(telemetryLocationReceiver);
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "Error when unregisterReceiver: " + e);
- }
-
- }
+ }
}
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 ab3b841043..7694604d9f 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
@@ -12,94 +12,98 @@ import android.view.View;
public class AnimatorUtils {
- public static void animate(@NonNull final View view, @AnimatorRes int animatorRes, @Nullable OnAnimationEndListener listener) {
- animate(view, animatorRes, -1, listener);
+ public static void animate(@NonNull final View view, @AnimatorRes int animatorRes,
+ @Nullable OnAnimationEndListener listener) {
+ animate(view, animatorRes, -1, listener);
+ }
+
+ public static void animate(final View view, @AnimatorRes int animatorRes, int duration,
+ @Nullable final OnAnimationEndListener listener) {
+ if (view == null) {
+ return;
}
- public static void animate(final View view, @AnimatorRes int animatorRes, int duration, @Nullable final OnAnimationEndListener listener) {
- if (view == null) {
- return;
- }
+ view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ Animator animator = AnimatorInflater.loadAnimator(view.getContext(), animatorRes);
+ if (duration != -1) {
+ animator.setDuration(duration);
+ }
- view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
- Animator animator = AnimatorInflater.loadAnimator(view.getContext(), animatorRes);
- if (duration != -1) {
- animator.setDuration(duration);
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ view.setLayerType(View.LAYER_TYPE_NONE, null);
+ if (listener != null) {
+ listener.onAnimationEnd();
}
+ }
+ });
+ animator.setTarget(view);
+ animator.start();
+ }
- animator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- view.setLayerType(View.LAYER_TYPE_NONE, null);
- if (listener != null) {
- listener.onAnimationEnd();
- }
- }
- });
- animator.setTarget(view);
- animator.start();
- }
+ public static void animate(@NonNull final View view, @AnimatorRes int animatorRes) {
+ animate(view, animatorRes, -1);
+ }
- public static void animate(@NonNull final View view, @AnimatorRes int animatorRes) {
- animate(view, animatorRes, -1);
- }
-
- public static void animate(@NonNull final View view, @AnimatorRes int animatorRes, int duration) {
- animate(view, animatorRes, duration, null);
- }
+ public static void animate(@NonNull final View view, @AnimatorRes int animatorRes, int duration) {
+ animate(view, animatorRes, duration, null);
+ }
- public static void rotate(@NonNull final View view, float rotation) {
- view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
- ObjectAnimator rotateAnimator = ObjectAnimator.ofFloat(view, View.ROTATION, view.getRotation(), rotation);
- rotateAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- view.setLayerType(View.LAYER_TYPE_NONE, null);
- }
- });
- rotateAnimator.start();
- }
+ public static void rotate(@NonNull final View view, float rotation) {
+ view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ ObjectAnimator rotateAnimator = ObjectAnimator.ofFloat(view, View.ROTATION, view.getRotation(), rotation);
+ rotateAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ view.setLayerType(View.LAYER_TYPE_NONE, null);
+ }
+ });
+ 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 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);
- rotateAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- super.onAnimationStart(animation);
- convertView.setVisibility(View.VISIBLE);
- }
+ 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);
+ rotateAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ super.onAnimationStart(animation);
+ convertView.setVisibility(View.VISIBLE);
+ }
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- convertView.setLayerType(View.LAYER_TYPE_NONE, null);
- if (listener != null) {
- listener.onAnimationEnd();
- }
- }
- });
- rotateAnimator.start();
- }
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ convertView.setLayerType(View.LAYER_TYPE_NONE, null);
+ if (listener != null) {
+ listener.onAnimationEnd();
+ }
+ }
+ });
+ rotateAnimator.start();
+ }
- public static void alpha(@NonNull final View convertView, float alpha) {
- alpha(convertView, alpha, null);
- }
+ public static void alpha(@NonNull final View convertView, float alpha) {
+ alpha(convertView, alpha, null);
+ }
- public interface OnAnimationEndListener {
- void onAnimationEnd();
- }
+ public interface OnAnimationEndListener {
+ void onAnimationEnd();
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/ColorUtils.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/ColorUtils.java
index 190e0b9b8f..d45d647247 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/ColorUtils.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/ColorUtils.java
@@ -19,101 +19,104 @@ import java.util.regex.Pattern;
public class ColorUtils {
- /**
- * Returns a color integer associated as primary color from a theme based on a {@link Context}.
- *
- * @param context The context used to style the color attributes.
- * @return The primary color value of current theme in the form 0xAARRGGBB.
- */
- @ColorInt
- public static int getPrimaryColor(@NonNull Context context) {
- TypedValue typedValue = new TypedValue();
- Resources.Theme theme = context.getTheme();
- theme.resolveAttribute(R.attr.colorPrimary, typedValue, true);
- return typedValue.data;
- }
+ /**
+ * Returns a color integer associated as primary color from a theme based on a {@link Context}.
+ *
+ * @param context The context used to style the color attributes.
+ * @return The primary color value of current theme in the form 0xAARRGGBB.
+ */
+ @ColorInt
+ public static int getPrimaryColor(@NonNull Context context) {
+ TypedValue typedValue = new TypedValue();
+ Resources.Theme theme = context.getTheme();
+ theme.resolveAttribute(R.attr.colorPrimary, typedValue, true);
+ return typedValue.data;
+ }
- /**
- * Returns a color integer associated as primary dark color from a theme based on a {@link Context}.
- *
- * @param context The context used to style the color attributes.
- * @return The primary dark color value of current theme in the form 0xAARRGGBB.
- */
- @ColorInt
- public static int getPrimaryDarkColor(@NonNull Context context) {
- TypedValue typedValue = new TypedValue();
- Resources.Theme theme = context.getTheme();
- theme.resolveAttribute(R.attr.colorPrimaryDark, typedValue, true);
- return typedValue.data;
- }
+ /**
+ * Returns a color integer associated as primary dark color from a theme based on a {@link Context}.
+ *
+ * @param context The context used to style the color attributes.
+ * @return The primary dark color value of current theme in the form 0xAARRGGBB.
+ */
+ @ColorInt
+ public static int getPrimaryDarkColor(@NonNull Context context) {
+ TypedValue typedValue = new TypedValue();
+ Resources.Theme theme = context.getTheme();
+ theme.resolveAttribute(R.attr.colorPrimaryDark, typedValue, true);
+ return typedValue.data;
+ }
- /**
- * Returns a color integer associated as accent color from a theme based on a {@link Context}.
- *
- * @param context The context used to style the color attributes.
- * @return The accent color value of current theme in the form 0xAARRGGBB.
- */
- @ColorInt
- public static int getAccentColor(@NonNull Context context) {
- TypedValue typedValue = new TypedValue();
- Resources.Theme theme = context.getTheme();
- theme.resolveAttribute(R.attr.colorAccent, typedValue, true);
- return typedValue.data;
- }
+ /**
+ * Returns a color integer associated as accent color from a theme based on a {@link Context}.
+ *
+ * @param context The context used to style the color attributes.
+ * @return The accent color value of current theme in the form 0xAARRGGBB.
+ */
+ @ColorInt
+ public static int getAccentColor(@NonNull Context context) {
+ TypedValue typedValue = new TypedValue();
+ Resources.Theme theme = context.getTheme();
+ theme.resolveAttribute(R.attr.colorAccent, typedValue, true);
+ return typedValue.data;
+ }
- /**
- * Returns a color state list associated with a theme based on a {@link Context}
- *
- * @param color The color used for tinting.
- * @return A ColorStateList object containing the primary color of a theme
- */
- @NonNull
- public static ColorStateList getSelector(@ColorInt int color) {
- return new ColorStateList(
- new int[][]{
- new int[]{android.R.attr.state_pressed},
- new int[]{}
- },
- new int[]{
- color,
- color
- }
- );
- }
+ /**
+ * Returns a color state list associated with a theme based on a {@link Context}
+ *
+ * @param color The color used for tinting.
+ * @return A ColorStateList object containing the primary color of a theme
+ */
+ @NonNull
+ public static ColorStateList getSelector(@ColorInt int color) {
+ return new ColorStateList(
+ new int[][] {
+ new int[] {android.R.attr.state_pressed},
+ new int[] {}
+ },
+ new int[] {
+ color,
+ color
+ }
+ );
+ }
- /**
- * Set a color tint list to the {@link Drawable} of an {@link ImageView}.
- *
- * @param imageView The view to set the default tint list.
- * @param tintColor The color to tint.
- */
- public static void setTintList(@NonNull ImageView imageView, @ColorInt int tintColor) {
- Drawable originalDrawable = imageView.getDrawable();
- Drawable wrappedDrawable = DrawableCompat.wrap(originalDrawable);
- DrawableCompat.setTintList(wrappedDrawable, getSelector(tintColor));
- }
+ /**
+ * Set a color tint list to the {@link Drawable} of an {@link ImageView}.
+ *
+ * @param imageView The view to set the default tint list.
+ * @param tintColor The color to tint.
+ */
+ public static void setTintList(@NonNull ImageView imageView, @ColorInt int tintColor) {
+ Drawable originalDrawable = imageView.getDrawable();
+ Drawable wrappedDrawable = DrawableCompat.wrap(originalDrawable);
+ DrawableCompat.setTintList(wrappedDrawable, getSelector(tintColor));
+ }
- static int normalizeColorComponent(String value) {
- return (int) (Float.parseFloat(value) * 255);
- }
+ static int normalizeColorComponent(String value) {
+ return (int) (Float.parseFloat(value) * 255);
+ }
- /**
- * Convert an rgba string to a Color int.
- *
- * @param value the String representation of rgba
- * @return the int representation of rgba
- * @throws ConversionException on illegal input
- */
- @ColorInt
- public static int rgbaToColor(String value) {
- Pattern c = Pattern.compile("rgba?\\s*\\(\\s*(\\d+\\.?\\d*)\\s*,\\s*(\\d+\\.?\\d*)\\s*,\\s*(\\d+\\.?\\d*)\\s*,?\\s*(\\d+\\.?\\d*)?\\s*\\)");
- Matcher m = c.matcher(value);
- if (m.matches() && m.groupCount() == 3) {
- return Color.rgb(normalizeColorComponent(m.group(1)), normalizeColorComponent(m.group(2)), normalizeColorComponent(m.group(3)));
- } else if (m.matches() && m.groupCount() == 4) {
- return Color.argb(normalizeColorComponent(m.group(4)), normalizeColorComponent(m.group(1)), normalizeColorComponent(m.group(2)), normalizeColorComponent(m.group(3)));
- } else {
- throw new ConversionException("Not a valid rgb/rgba value");
- }
+ /**
+ * Convert an rgba string to a Color int.
+ *
+ * @param value the String representation of rgba
+ * @return the int representation of rgba
+ * @throws ConversionException on illegal input
+ */
+ @ColorInt
+ public static int rgbaToColor(String value) {
+ Pattern c = Pattern.compile("rgba?\\s*\\(\\s*(\\d+\\.?\\d*)\\s*,\\s*(\\d+\\.?\\d*)\\s*,\\s*(\\d+\\.?\\d*)\\s*,"
+ + "?\\s*(\\d+\\.?\\d*)?\\s*\\)");
+ Matcher m = c.matcher(value);
+ if (m.matches() && m.groupCount() == 3) {
+ return Color.rgb(normalizeColorComponent(m.group(1)), normalizeColorComponent(m.group(2)),
+ normalizeColorComponent(m.group(3)));
+ } else if (m.matches() && m.groupCount() == 4) {
+ return Color.argb(normalizeColorComponent(m.group(4)), normalizeColorComponent(m.group(1)),
+ normalizeColorComponent(m.group(2)), normalizeColorComponent(m.group(3)));
+ } else {
+ throw new ConversionException("Not a valid rgb/rgba value");
}
+ }
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/MathUtils.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/MathUtils.java
index a92999c0d5..30ec214798 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/MathUtils.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/MathUtils.java
@@ -2,45 +2,65 @@ package com.mapbox.mapboxsdk.utils;
public class MathUtils {
- /**
- * Test a value in specified range, returning minimum if it's below, and maximum if it's above
- * @param value Value to test
- * @param min Minimum value of range
- * @param max Maximum value of range
- * @return value if it's between min and max, min if it's below, max if it's above
- */
- public static double clamp(double value, double min, double max) {
- return Math.max(min, Math.min(max, value));
- }
+ /**
+ * Test a value in specified range, returning minimum if it's below, and maximum if it's above
+ *
+ * @param value Value to test
+ * @param min Minimum value of range
+ * @param max Maximum value of range
+ * @return value if it's between min and max, min if it's below, max if it's above
+ */
+ public static double clamp(double value, double min, double max) {
+ return Math.max(min, Math.min(max, value));
+ }
- /**
- * Test a value in specified range, returning minimum if it's below, and maximum if it's above
- * @param value Value to test
- * @param min Minimum value of range
- * @param max Maximum value of range
- * @return value if it's between min and max, min if it's below, max if it's above
- */
- public static float clamp(float value, float min, float max) {
- return Math.max(min, Math.min(max, value));
- }
+ /**
+ * Test a value in specified range, returning minimum if it's below, and maximum if it's above
+ *
+ * @param value Value to test
+ * @param min Minimum value of range
+ * @param max Maximum value of range
+ * @return value if it's between min and max, min if it's below, max if it's above
+ */
+ public static float clamp(float value, float min, float max) {
+ return Math.max(min, Math.min(max, value));
+ }
+
+ /**
+ * Constrains value to the given range (including min, excluding max) via modular arithmetic.
+ * <p>
+ * Same formula as used in Core GL (wrap.hpp)
+ * std::fmod((std::fmod((value - min), d) + d), d) + min;
+ *
+ * @param value Value to wrap
+ * @param min Minimum value
+ * @param max Maximum value
+ * @return Wrapped value
+ */
+ public static double wrap(double value, double min, double max) {
+ double delta = max - min;
+
+ double firstMod = (value - min) % delta;
+ double secondMod = (firstMod + delta) % delta;
- /**
- * Constrains value to the given range (including min, excluding max) via modular arithmetic.
- *
- * Same formula as used in Core GL (wrap.hpp)
- * std::fmod((std::fmod((value - min), d) + d), d) + min;
- *
- * @param value Value to wrap
- * @param min Minimum value
- * @param max Maximum value
- * @return Wrapped value
- */
- public static double wrap(double value, double min, double max) {
- double delta = max - min;
-
- double firstMod = (value - min) % delta;
- double secondMod = (firstMod + delta) % delta;
-
- return secondMod + min;
+ return secondMod + min;
+ }
+
+ /**
+ * Convert bearing from core to match Android SDK value.
+ *
+ * @param nativeBearing bearing value coming from core
+ * @return bearing in degrees starting from 0 rotating clockwise
+ */
+ public static double convertNativeBearing(double nativeBearing) {
+ double direction = -nativeBearing;
+
+ while (direction > 360) {
+ direction -= 360;
+ }
+ while (direction < 0) {
+ direction += 360;
}
+ return direction;
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res-public/values/public.xml b/platform/android/MapboxGLAndroidSDK/src/main/res-public/values/public.xml
index 4fbf3d5fe1..5b2945d55d 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res-public/values/public.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res-public/values/public.xml
@@ -1,57 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <!--Add references to exposed resources-->
- <public name="AttributionAlertDialogStyle" type="style" />
-
- <public name="style_mapbox_streets" type="string" />
- <public name="style_emerald" type="string" />
- <public name="style_light" type="string" />
- <public name="style_dark" type="string" />
- <public name="style_satellite" type="string" />
- <public name="style_satellite_streets" type="string" />
-
- <public name="center_longitude" type="attr" />
- <public name="center_latitude" type="attr" />
- <public name="zoom_level" type="attr" />
- <public name="direction" type="attr" />
- <public name="zoom_enabled" type="attr" />
- <public name="scroll_enabled" type="attr" />
- <public name="rotate_enabled" type="attr" />
- <public name="zoom_controls_enabled" type="attr" />
- <public name="debug_active" type="attr" />
- <public name="style_url" type="attr" />
- <public name="access_token" type="attr" />
- <public name="style_classes" type="attr" />
- <public name="my_location_enabled" type="attr" />
- <public name="compass_enabled" type="attr" />
- <public name="compass_gravity" type="attr" />
- <public name="compass_margin_left" type="attr" />
- <public name="compass_margin_top" type="attr" />
- <public name="compass_margin_right" type="attr" />
- <public name="compass_margin_bottom" type="attr" />
- <public name="compass_fade_facing_north" type="attr" />
- <public name="logo_gravity" type="attr" />
- <public name="logo_margin_left" type="attr" />
- <public name="logo_margin_top" type="attr" />
- <public name="logo_margin_right" type="attr" />
- <public name="logo_margin_bottom" type="attr" />
- <public name="logo_visibility" type="attr" />
- <public name="attribution_gravity" type="attr" />
- <public name="attribution_margin_left" type="attr" />
- <public name="attribution_margin_top" type="attr" />
- <public name="attribution_margin_right" type="attr" />
- <public name="attribution_margin_bottom" type="attr" />
- <public name="attribution_visibility" type="attr" />
-
- <public name="attribution_logo" type="drawable" />
- <public name="compass" type="drawable" />
- <public name="default_marker" type="drawable" />
- <public name="attribution_button_pressed_selector" type="drawable" />
- <public name="attribution_button_pressed_normal" type="drawable" />
- <public name="attribution_button_pressed_pressed" type="drawable" />
- <public name="my_location" type="drawable" />
- <public name="my_location_bearing" type="drawable" />
- <public name="my_location_stale" type="drawable" />
- <public name="my_location_ring" type="color" />
+
+ <!-- This file contains attributes and styles that are part of the public API-->
+ <!-- Users can find these with code completion while other ones from this module will remain-->
+ <!-- hidden, though the user can reference them but won't show up during code completion-->
+
+ <public name="mapbox_AlertDialogStyle" type="style" />
+
+ <!-- Exposed attrs.xml -->
+ <public name="mapbox_accessToken" type="attr" />
+ <public name="mapbox_styleUrl" type="attr" />
+ <public name="mapbox_apiBaseUrl" type="attr" />
+
+ <public name="mapbox_cameraTargetLng" type="attr" />
+ <public name="mapbox_cameraTargetLat" type="attr" />
+ <public name="mapbox_cameraZoom_level" type="attr" />
+ <public name="mapbox_cameraBearing" type="attr" />
+
+ <public name="mapbox_uiZoomGestures" type="attr" />
+ <public name="mapbox_uiScrollGestures" type="attr" />
+ <public name="mapbox_uiRotateGestures" type="attr" />
+ <public name="mapbox_uiZoomControls" type="attr" />
+
+ <public name="mapbox_myLocation" type="attr" />
+ <public name="mapbox_myLocationTintColor" type="attr" />
+ <public name="mapbox_myLocationDrawable" type="attr" />
+ <public name="mapbox_myLocationBearingDrawable" type="attr" />
+ <public name="mapbox_myLocationBackgroundDrawable" type="attr" />
+ <public name="mapbox_myLocationBackgroundTintColor" type="attr" />
+ <public name="mapbox_myLocationBackgroundMarginLeft" type="attr" />
+ <public name="mapbox_myLocationBackgroundMarginTop" type="attr" />
+ <public name="mapbox_myLocationBackgroundMarginRight" type="attr" />
+ <public name="mapbox_myLocationBackgroundMarginBottom" type="attr" />
+ <public name="mapbox_myLocationAccuracyTintColor" type="attr" />
+ <public name="mapbox_myLocationAccuracyAlpha" type="attr" />
+
+ <public name="mapbox_uiCompass" type="attr" />
+ <public name="mapbox_uiCompassGravity" type="attr" />
+ <public name="mapbox_uiCompassMarginLeft" type="attr" />
+ <public name="mapbox_uiCompassMarginTop" type="attr" />
+ <public name="mapbox_uiCompassMarginRight" type="attr" />
+ <public name="mapbox_uiCompassMarginBottom" type="attr" />
+ <public name="mapbox_uiCompassFadeFacingNorth" type="attr" />
+
+ <public name="mapbox_uiLogo" type="attr" />
+ <public name="mapbox_uiLogoGravity" type="attr" />
+ <public name="mapbox_uiLogoMarginLeft" type="attr" />
+ <public name="mapbox_uiLogoMarginTop" type="attr" />
+ <public name="mapbox_uiLogoMarginRight" type="attr" />
+ <public name="mapbox_uiLogoMarginBottom" type="attr" />
+
+ <public name="mapbox_uiAttribution" type="attr" />
+ <public name="mapbox_uiAttributionGravity" type="attr" />
+ <public name="mapbox_uiAttributionMarginLeft" type="attr" />
+ <public name="mapbox_uiAttributionMarginTop" type="attr" />
+ <public name="mapbox_uiAttributionMarginRight" type="attr" />
+ <public name="mapbox_uiAttributionMarginBottom" type="attr" />
+
+ <public name="mapbox_renderTextureMode" type="attr" />
+
+ <!-- Exposed styles -->
+ <public name="mapbox_style_mapbox_streets" type="string" />
+ <public name="mapbox_style_emerald" type="string" />
+ <public name="mapbox_style_light" type="string" />
+ <public name="mapbox_style_dark" type="string" />
+ <public name="mapbox_style_satellite" type="string" />
+ <public name="mapbox_style_satellite_streets" type="string" />
+
+ <!-- Exposed drawables -->
+ <public name="mapbox_logo_icon" type="drawable" />
+ <public name="mapbox_compass_icon" type="drawable" />
+ <public name="mapbox_marker_icon_default" type="drawable" />
+ <public name="mapbox_info_bg_selector" type="drawable" />
+ <public name="mapbox_info_icon_default" type="drawable" />
+ <public name="mapbox_info_icon_selected" type="drawable" />
+ <public name="mapbox_mylocation_icon_default" type="drawable" />
+ <public name="mapbox_mylocation_icon_bearing" type="drawable" />
+
+ <!-- Exposed colors -->
+ <public name="mapbox_mylocation_ring" type="color" />
<public name="mapbox_blue" type="color" />
</resources>
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/color/material_bg_selector.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/color/mapbox_material_bg_selector.xml
index 64d7f46c2d..64d7f46c2d 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/color/material_bg_selector.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/color/mapbox_material_bg_selector.xml
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/compass.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/mapbox_compass_icon.png
index 6bb20027f4..6bb20027f4 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/compass.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/mapbox_compass_icon.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/attribution_logo.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/mapbox_logo_icon.png
index c0f4ed2c4c..c0f4ed2c4c 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/attribution_logo.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/mapbox_logo_icon.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/default_marker.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/mapbox_marker_icon_default.png
index 8b0af4c6ab..8b0af4c6ab 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/default_marker.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/mapbox_marker_icon_default.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/default_markerview.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/mapbox_markerview_icon_default.png
index 651482f3ee..651482f3ee 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/default_markerview.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/mapbox_markerview_icon_default.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/ic_mylocationview_bearing.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/mapbox_mylocation_icon_bearing.png
index c93fa4781a..c93fa4781a 100755
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/ic_mylocationview_bearing.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/mapbox_mylocation_icon_bearing.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/ic_mylocationview_normal.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/mapbox_mylocation_icon_default.png
index 120b7dd612..120b7dd612 100755
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/ic_mylocationview_normal.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-hdpi/mapbox_mylocation_icon_default.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/compass.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/mapbox_compass_icon.png
index cf15ed1876..cf15ed1876 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/compass.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/mapbox_compass_icon.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/attribution_logo.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/mapbox_logo_icon.png
index 5a9da3fe39..5a9da3fe39 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/attribution_logo.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/mapbox_logo_icon.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/default_marker.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/mapbox_marker_icon_default.png
index b112096c18..b112096c18 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/default_marker.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/mapbox_marker_icon_default.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/default_markerview.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/mapbox_markerview_icon_default.png
index 63cb7b5f4b..63cb7b5f4b 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/default_markerview.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/mapbox_markerview_icon_default.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/ic_mylocationview_bearing.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/mapbox_mylocation_icon_bearing.png
index 0d7d89a8b4..0d7d89a8b4 100755
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/ic_mylocationview_bearing.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/mapbox_mylocation_icon_bearing.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/ic_mylocationview_normal.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/mapbox_mylocation_icon_default.png
index 831ef1acf4..831ef1acf4 100755
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/ic_mylocationview_normal.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-mdpi/mapbox_mylocation_icon_default.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-v21/bg_default_selector.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-v21/mapbox_default_bg_selector.xml
index ef82c18f5d..ef82c18f5d 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-v21/bg_default_selector.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-v21/mapbox_default_bg_selector.xml
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/compass.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/mapbox_compass_icon.png
index 6257209368..6257209368 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/compass.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/mapbox_compass_icon.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/attribution_logo.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/mapbox_logo_icon.png
index 194aa64da2..194aa64da2 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/attribution_logo.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/mapbox_logo_icon.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/default_marker.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/mapbox_marker_icon_default.png
index d05c82bfe2..d05c82bfe2 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/default_marker.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/mapbox_marker_icon_default.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/default_markerview.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/mapbox_markerview_icon_default.png
index 175f88ff88..175f88ff88 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/default_markerview.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/mapbox_markerview_icon_default.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/ic_mylocationview_bearing.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/mapbox_mylocation_icon_bearing.png
index 1056d617e9..1056d617e9 100755
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/ic_mylocationview_bearing.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/mapbox_mylocation_icon_bearing.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/ic_mylocationview_normal.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/mapbox_mylocation_icon_default.png
index 37b1f7adbf..37b1f7adbf 100755
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/ic_mylocationview_normal.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xhdpi/mapbox_mylocation_icon_default.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/compass.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapbox_compass_icon.png
index c59b4c7528..c59b4c7528 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/compass.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapbox_compass_icon.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/attribution_logo.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapbox_logo_icon.png
index d1260a16f3..d1260a16f3 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/attribution_logo.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapbox_logo_icon.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapview_preview.jpg b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapbox_mapview_preview.jpg
index 3a21fc08bc..3a21fc08bc 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapview_preview.jpg
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapbox_mapview_preview.jpg
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/default_marker.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapbox_marker_icon_default.png
index 703b172c15..703b172c15 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/default_marker.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapbox_marker_icon_default.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/default_markerview.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapbox_markerview_icon_default.png
index be782e1d4b..be782e1d4b 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/default_markerview.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapbox_markerview_icon_default.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/ic_mylocationview_bearing.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapbox_mylocation_icon_bearing.png
index 1ff2590606..1ff2590606 100755
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/ic_mylocationview_bearing.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapbox_mylocation_icon_bearing.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/ic_mylocationview_normal.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapbox_mylocation_icon_default.png
index 520b85eff7..520b85eff7 100755
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/ic_mylocationview_normal.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxhdpi/mapbox_mylocation_icon_default.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/compass.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/mapbox_compass_icon.png
index da04f5b94c..da04f5b94c 100755
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/compass.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/mapbox_compass_icon.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/bg_infowindow_content.9.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/mapbox_infowindow_icon_bg.9.png
index 584b320299..584b320299 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/bg_infowindow_content.9.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/mapbox_infowindow_icon_bg.9.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/attribution_logo.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/mapbox_logo_icon.png
index 5f9647610a..5f9647610a 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/attribution_logo.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/mapbox_logo_icon.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/default_marker.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/mapbox_marker_icon_default.png
index 8331ffef71..8331ffef71 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/default_marker.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/mapbox_marker_icon_default.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/default_markerview.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/mapbox_markerview_icon_default.png
index fe1c486518..fe1c486518 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/default_markerview.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/mapbox_markerview_icon_default.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/ic_mylocationview_bearing.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/mapbox_mylocation_icon_bearing.png
index 671c33a08e..671c33a08e 100755
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/ic_mylocationview_bearing.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/mapbox_mylocation_icon_bearing.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/ic_mylocationview_normal.png b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/mapbox_mylocation_icon_default.png
index f9f4265d2a..f9f4265d2a 100755
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/ic_mylocationview_normal.png
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable-xxxhdpi/mapbox_mylocation_icon_default.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/bg_default_selector.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/bg_default_selector.xml
deleted file mode 100644
index 48e53e7ee8..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/bg_default_selector.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:drawable="@color/gray_light" android:state_pressed="true" />
- <item android:drawable="@color/gray_light" android:state_focused="true" />
- <item android:drawable="@android:color/transparent" />
-</selector> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/ic_info_outline_24dp_selector.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/ic_info_outline_24dp_selector.xml
deleted file mode 100644
index 7f6245b30a..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/ic_info_outline_24dp_selector.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:drawable="@drawable/ic_info_outline_24dp_selected" android:state_pressed="true" />
- <item android:drawable="@drawable/ic_info_outline_24dp" />
-</selector> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/ic_mylocationview_background.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/ic_mylocationview_background.xml
deleted file mode 100644
index e1df60788e..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/ic_mylocationview_background.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="oval">
-
- <solid android:color="@color/white" />
-
- <size
- android:width="@dimen/my_locationview_outer_circle"
- android:height="@dimen/my_locationview_outer_circle" />
-</shape> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/mapbox_default_bg_selector.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/mapbox_default_bg_selector.xml
new file mode 100644
index 0000000000..45073bb1f3
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/mapbox_default_bg_selector.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:drawable="@color/mapbox_gray_light" android:state_pressed="true" />
+ <item android:drawable="@color/mapbox_gray_light" android:state_focused="true" />
+ <item android:drawable="@android:color/transparent" />
+</selector> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/mapbox_info_bg_selector.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/mapbox_info_bg_selector.xml
new file mode 100644
index 0000000000..3ead19b781
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/mapbox_info_bg_selector.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:drawable="@drawable/mapbox_info_icon_selected" android:state_pressed="true" />
+ <item android:drawable="@drawable/mapbox_info_icon_default" />
+</selector> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/ic_info_outline_24dp.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/mapbox_info_icon_default.xml
index fa82bb8d9b..fa82bb8d9b 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/ic_info_outline_24dp.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/mapbox_info_icon_default.xml
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/ic_info_outline_24dp_selected.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/mapbox_info_icon_selected.xml
index 074928d05a..074928d05a 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/ic_info_outline_24dp_selected.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/mapbox_info_icon_selected.xml
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/mapbox_mylocation_bg_shape.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/mapbox_mylocation_bg_shape.xml
new file mode 100644
index 0000000000..df0687bbd3
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/drawable/mapbox_mylocation_bg_shape.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="oval">
+
+ <solid android:color="@android:color/white" />
+
+ <size
+ android:width="@dimen/mapbox_my_locationview_outer_circle"
+ android:height="@dimen/mapbox_my_locationview_outer_circle" />
+</shape> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/layout/attribution_list_item.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_attribution_list_item.xml
index 763bb118e0..763bb118e0 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/layout/attribution_list_item.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_attribution_list_item.xml
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/layout/infowindow_content.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_infowindow_content.xml
index 3e36cbf91a..e1673902ef 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/layout/infowindow_content.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_infowindow_content.xml
@@ -5,7 +5,7 @@
android:id="@+id/infowindow_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:background="@drawable/bg_infowindow_content"
+ android:background="@drawable/mapbox_infowindow_icon_bg"
android:orientation="vertical"
android:paddingBottom="16dp"
android:paddingLeft="20dp"
@@ -18,8 +18,8 @@
android:layout_height="wrap_content"
android:layout_marginBottom="2dp"
android:maxEms="17"
- android:text="@string/infoWindowTitle"
- android:textColor="@color/black"
+ android:text="@string/mapbox_infoWindowTitle"
+ android:textColor="@android:color/black"
android:textSize="18sp"
android:textStyle="bold" />
@@ -31,8 +31,8 @@
android:layout_marginTop="2dp"
android:lineSpacingExtra="1dp"
android:maxEms="17"
- android:text="@string/infoWindowDescription"
- android:textColor="@color/gray"
+ android:text="@string/mapbox_infoWindowDescription"
+ android:textColor="@color/mapbox_gray"
android:textSize="14sp" />
<TextView
@@ -40,15 +40,15 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxEms="17"
- android:text="@string/infoWindowAddress"
- android:textColor="@color/black"
+ android:text="@string/mapbox_infoWindowAddress"
+ android:textColor="@android:color/black"
android:textSize="12sp"
android:visibility="gone" />
</LinearLayout>
<com.mapbox.mapboxsdk.annotations.InfoWindowTipView
android:id="@+id/infowindow_tipview"
- android:layout_width="@dimen/infowindow_tipview_width"
+ android:layout_width="@dimen/mapbox_infowindow_tipview_width"
android:layout_height="14dp"
android:layout_below="@+id/infowindow_content" />
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/layout/infowindow_view.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_infowindow_view.xml
index ff47642426..ff47642426 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/layout/infowindow_view.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_infowindow_view.xml
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapview_internal.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_mapview_internal.xml
index 4f032c1008..c6dcd35a2f 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapview_internal.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_mapview_internal.xml
@@ -27,18 +27,18 @@
android:id="@+id/logoView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:contentDescription="@string/mapboxIconContentDescription"
- android:src="@drawable/attribution_logo" />
+ android:contentDescription="@string/mapbox_iconContentDescription"
+ android:src="@drawable/mapbox_logo_icon" />
<ImageView
android:id="@+id/attributionView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
- android:background="@drawable/bg_default_selector"
+ android:background="@drawable/mapbox_default_bg_selector"
android:clickable="true"
- android:contentDescription="@string/attributionsIconContentDescription"
+ android:contentDescription="@string/mapbox_attributionsIconContentDescription"
android:padding="7dp"
- android:src="@drawable/ic_info_outline_24dp_selector" />
+ android:src="@drawable/mapbox_info_bg_selector" />
</merge> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapview_preview.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_mapview_preview.xml
index d8f2193fd5..5517c0cfe6 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapview_preview.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_mapview_preview.xml
@@ -8,34 +8,34 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
- android:src="@drawable/mapview_preview" />
+ android:src="@drawable/mapbox_mapview_preview" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
- android:layout_marginBottom="@dimen/eight_dp"
- android:layout_marginLeft="@dimen/eight_dp"
- android:contentDescription="@string/mapboxIconContentDescription"
- android:src="@drawable/attribution_logo" />
+ android:layout_marginBottom="@dimen/mapbox_eight_dp"
+ android:layout_marginLeft="@dimen/mapbox_eight_dp"
+ android:contentDescription="@string/mapbox_iconContentDescription"
+ android:src="@drawable/mapbox_logo_icon" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
- android:layout_marginBottom="@dimen/seven_dp"
- android:layout_marginLeft="@dimen/seventy_six_dp"
- android:background="@drawable/bg_default_selector"
+ android:layout_marginBottom="@dimen/mapbox_seven_dp"
+ android:layout_marginLeft="@dimen/mapbox_seventy_six_dp"
+ android:background="@drawable/mapbox_default_bg_selector"
android:clickable="true"
- android:contentDescription="@string/attributionsIconContentDescription"
- android:src="@drawable/ic_info_outline_24dp_selector" />
+ android:contentDescription="@string/mapbox_attributionsIconContentDescription"
+ android:src="@drawable/mapbox_info_bg_selector" />
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentRight="true"
android:layout_margin="10dp"
- android:src="@drawable/compass" />
+ android:src="@drawable/mapbox_compass_icon" />
</RelativeLayout> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/layout/view_image_marker.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_view_image_marker.xml
index 7e4a079063..7e4a079063 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/layout/view_image_marker.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_view_image_marker.xml
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/values/arrays.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/values/arrays.xml
index bb466880aa..5a5fd6cb4c 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/values/arrays.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/values/arrays.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <array name="attribution_names">
+ <array name="mapbox_attribution_names">
<item>&#169; Mapbox</item>
<item>&#169; OpenStreetMap</item>
<item>Improve this map</item>
<item>Telemetry Settings</item>
</array>
<!-- If editing this array update MapView.ATTRIBUTION_INDEX_IMPROVE_THIS_MAP -->
- <array name="attribution_links" formatted="false" translatable="false">
+ <array name="mapbox_attribution_links" formatted="false" translatable="false">
<item>https://www.mapbox.com/about/maps/</item>
<item>http://www.openstreetmap.org/about/</item>
<item>https://www.mapbox.com/map-feedback/#/%1$f/%2$f/%3$d</item>
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/values/attrs.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/values/attrs.xml
index 458056c14e..12c395d46f 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/values/attrs.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/values/attrs.xml
@@ -1,50 +1,48 @@
<resources>
<!-- these are public -->
- <declare-styleable name="MapView">
+ <declare-styleable name="mapbox_MapView">
<!--Configuration-->
- <attr name="access_token" format="string" />
- <attr name="style_url" format="string" />
- <attr name="api_base_url" format="string" />
+ <attr name="mapbox_styleUrl" format="string" />
+ <attr name="mapbox_apiBaseUrl" format="string" />
<!--Camera-->
- <attr name="center_longitude" format="float" />
- <attr name="center_latitude" format="float" />
- <attr name="zoom" format="float" />
- <attr name="direction" format="float" />
- <attr name="tilt" format="float" />
+ <attr name="mapbox_cameraTargetLat" format="float" />
+ <attr name="mapbox_cameraTargetLng" format="float" />
+ <attr name="mapbox_cameraZoom" format="float" />
+ <attr name="mapbox_cameraBearing" format="float" />
+ <attr name="mapbox_cameraTilt" format="float" />
<!--Zoom-->
- <attr name="zoom_max" format="float" />
- <attr name="zoom_min" format="float" />
+ <attr name="mapbox_cameraZoomMax" format="float" />
+ <attr name="mapbox_cameraZoomMin" format="float" />
<!--Gestures-->
- <attr name="zoom_enabled" format="boolean" />
- <attr name="scroll_enabled" format="boolean" />
- <attr name="rotate_enabled" format="boolean" />
- <attr name="tilt_enabled" format="boolean" />
- <attr name="debug_active" format="boolean" />
+ <attr name="mapbox_uiZoomGestures" format="boolean" />
+ <attr name="mapbox_uiScrollGestures" format="boolean" />
+ <attr name="mapbox_uiRotateGestures" format="boolean" />
+ <attr name="mapbox_uiTiltGestures" format="boolean" />
<!--UI-Controls-->
- <attr name="zoom_controls_enabled" format="boolean" />
+ <attr name="mapbox_uiZoomControls" format="boolean" />
<!--MyLocation-->
- <attr name="my_location_enabled" format="boolean" />
- <attr name="my_location_foreground" format="reference" />
- <attr name="my_location_foreground_bearing" format="reference" />
- <attr name="my_location_foreground_tint" format="color" />
- <attr name="my_location_background" format="reference" />
- <attr name="my_location_background_tint" format="color" />
- <attr name="my_location_background_left" format="dimension" />
- <attr name="my_location_background_top" format="dimension" />
- <attr name="my_location_background_right" format="dimension" />
- <attr name="my_location_background_bottom" format="dimension" />
- <attr name="my_location_accuracy_tint" format="color" />
- <attr name="my_location_accuracy_alpha" format="integer" />
+ <attr name="mapbox_myLocation" format="boolean" />
+ <attr name="mapbox_myLocationTintColor" format="color" />
+ <attr name="mapbox_myLocationDrawable" format="reference" />
+ <attr name="mapbox_myLocationBearingDrawable" format="reference" />
+ <attr name="mapbox_myLocationBackgroundDrawable" format="reference" />
+ <attr name="mapbox_myLocationBackgroundTintColor" format="color" />
+ <attr name="mapbox_myLocationBackgroundMarginLeft" format="dimension" />
+ <attr name="mapbox_myLocationBackgroundMarginTop" format="dimension" />
+ <attr name="mapbox_myLocationBackgroundMarginRight" format="dimension" />
+ <attr name="mapbox_myLocationBackgroundMarginBottom" format="dimension" />
+ <attr name="mapbox_myLocationAccuracyTintColor" format="color" />
+ <attr name="mapbox_myLocationAccuracyAlpha" format="integer" />
<!--Compass-->
- <attr name="compass_enabled" format="boolean" />
- <attr name="compass_gravity">
+ <attr name="mapbox_uiCompass" format="boolean" />
+ <attr name="mapbox_uiCompassGravity">
<flag name="top" value="0x30" />
<flag name="bottom" value="0x50" />
<flag name="left" value="0x03" />
@@ -60,14 +58,15 @@
<flag name="start" value="0x00800003" />
<flag name="end" value="0x00800005" />
</attr>
- <attr name="compass_margin_left" format="dimension" />
- <attr name="compass_margin_top" format="dimension" />
- <attr name="compass_margin_right" format="dimension" />
- <attr name="compass_margin_bottom" format="dimension" />
- <attr name="compass_fade_facing_north" format="boolean" />
+ <attr name="mapbox_uiCompassMarginLeft" format="dimension" />
+ <attr name="mapbox_uiCompassMarginTop" format="dimension" />
+ <attr name="mapbox_uiCompassMarginRight" format="dimension" />
+ <attr name="mapbox_uiCompassMarginBottom" format="dimension" />
+ <attr name="mapbox_uiCompassFadeFacingNorth" format="boolean" />
<!--Logo-->
- <attr name="logo_gravity">
+ <attr name="mapbox_uiLogo" format="boolean" />
+ <attr name="mapbox_uiLogoGravity">
<flag name="top" value="0x30" />
<flag name="bottom" value="0x50" />
<flag name="left" value="0x03" />
@@ -83,14 +82,14 @@
<flag name="start" value="0x00800003" />
<flag name="end" value="0x00800005" />
</attr>
- <attr name="logo_margin_left" format="dimension" />
- <attr name="logo_margin_top" format="dimension" />
- <attr name="logo_margin_right" format="dimension" />
- <attr name="logo_margin_bottom" format="dimension" />
- <attr name="logo_enabled" format="boolean" />
+ <attr name="mapbox_uiLogoMarginLeft" format="dimension" />
+ <attr name="mapbox_uiLogoMarginTop" format="dimension" />
+ <attr name="mapbox_uiLogoMarginRight" format="dimension" />
+ <attr name="mapbox_uiLogoMarginBottom" format="dimension" />
<!--Attribution-->
- <attr name="attribution_gravity">
+ <attr name="mapbox_uiAttribution" format="boolean" />
+ <attr name="mapbox_uiAttributionGravity">
<flag name="top" value="0x30" />
<flag name="bottom" value="0x50" />
<flag name="left" value="0x03" />
@@ -106,14 +105,14 @@
<flag name="start" value="0x00800003" />
<flag name="end" value="0x00800005" />
</attr>
- <attr name="attribution_margin_left" format="dimension" />
- <attr name="attribution_margin_top" format="dimension" />
- <attr name="attribution_margin_right" format="dimension" />
- <attr name="attribution_margin_bottom" format="dimension" />
- <attr name="attribution_enabled" format="boolean" />
- <attr name="attribution_tint" format="color" />
+ <attr name="mapbox_uiAttributionMarginLeft" format="dimension" />
+ <attr name="mapbox_uiAttributionMarginTop" format="dimension" />
+ <attr name="mapbox_uiAttributionMarginRight" format="dimension" />
+ <attr name="mapbox_uiAttributionMarginBottom" format="dimension" />
+ <attr name="mapbox_uiAttributionTintColor" format="color" />
<!-- Deprecated to use TextureView-->
- <attr name="texture_mode" format="boolean" />
+ <attr name="mapbox_renderTextureMode" format="boolean" />
+
</declare-styleable>
</resources>
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/values/colors.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/values/colors.xml
index 63f739c30c..63ef42c2c3 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/values/colors.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/values/colors.xml
@@ -1,9 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <color name="white">#F9F9F9</color>
- <color name="black">#000000</color>
- <color name="gray">#7D7F80</color>
- <color name="gray_light">#EEEEEE</color>
+ <color name="mapbox_gray">#7D7F80</color>
+ <color name="mapbox_gray_light">#EEEEEE</color>
<color name="mapbox_blue">#1E8CAB</color>
- <color name="my_location_ring">@color/mapbox_blue</color>
+ <color name="mapbox_my_location_ring">@color/mapbox_blue</color>
</resources>
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/values/dimens.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/values/dimens.xml
index fd0f4b98e7..31b9dd2bcd 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/values/dimens.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/values/dimens.xml
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <dimen name="infowindow_tipview_width">20dp</dimen>
- <dimen name="infowindow_margin">8dp</dimen>
- <dimen name="infowindow_offset">-2dp</dimen>
- <dimen name="infowindow_line_width">1.5dp</dimen>
- <dimen name="seven_dp">7dp</dimen>
- <dimen name="eight_dp">8dp</dimen>
- <dimen name="ten_dp">10dp</dimen>
- <dimen name="sixteen_dp">16dp</dimen>
- <dimen name="seventy_six_dp">76dp</dimen>
- <dimen name="my_locationview_outer_circle">18dp</dimen>
+ <dimen name="mapbox_infowindow_tipview_width">20dp</dimen>
+ <dimen name="mapbox_infowindow_margin">8dp</dimen>
+ <dimen name="mapbox_infowindow_offset">-2dp</dimen>
+ <dimen name="mapbox_infowindow_line_width">1.5dp</dimen>
+ <dimen name="mapbox_seven_dp">7dp</dimen>
+ <dimen name="mapbox_eight_dp">8dp</dimen>
+ <dimen name="mapbox_ten_dp">10dp</dimen>
+ <dimen name="mapbox_sixteen_dp">16dp</dimen>
+ <dimen name="mapbox_seventy_six_dp">76dp</dimen>
+ <dimen name="mapbox_my_locationview_outer_circle">18dp</dimen>
</resources>
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/values/integers.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/values/integers.xml
deleted file mode 100644
index 3727365659..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/values/integers.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
- <integer name="style_version">9</integer>
-</resources> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/values/strings.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/values/strings.xml
index c8bb9d65ba..f15979efc1 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/values/strings.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/values/strings.xml
@@ -1,27 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <string name="compassContentDescription">Map compass. Click to reset the map rotation to North.</string>
- <string name="attributionsIconContentDescription">Attribution icon. Click to show attribution dialog.</string>
- <string name="attributionsDialogTitle">Mapbox Android SDK</string>
- <string name="attributionTelemetryTitle">Make Mapbox Maps Better</string>
- <string name="attributionTelemetryMessage">You are helping to make OpenStreetMap and Mapbox maps better by contributing anonymous usage data.</string>
- <string name="attributionTelemetryPositive">Agree</string>
- <string name="attributionTelemetryNegative">Disagree</string>
- <string name="attributionTelemetryNeutral">More info</string>
- <string name="mapboxIconContentDescription">The Mapbox logo.</string>
- <string name="infoWindowTitle">Title</string>
- <string name="infoWindowDescription">Description</string>
- <string name="infoWindowAddress">Address</string>
+ <string name="mapbox_compassContentDescription">Map compass. Click to reset the map rotation to North.</string>
+ <string name="mapbox_attributionsIconContentDescription">Attribution icon. Click to show attribution dialog.</string>
+ <string name="mapbox_attributionsDialogTitle">Mapbox Android SDK</string>
+ <string name="mapbox_attributionTelemetryTitle">Make Mapbox Maps Better</string>
+ <string name="mapbox_attributionTelemetryMessage">You are helping to make OpenStreetMap and Mapbox maps better by contributing anonymous usage data.</string>
+ <string name="mapbox_attributionTelemetryPositive">Agree</string>
+ <string name="mapbox_attributionTelemetryNegative">Disagree</string>
+ <string name="mapbox_attributionTelemetryNeutral">More info</string>
+ <string name="mapbox_iconContentDescription">The Mapbox logo.</string>
+ <string name="mapbox_infoWindowTitle">Title</string>
+ <string name="mapbox_infoWindowDescription">Description</string>
+ <string name="mapbox_infoWindowAddress">Address</string>
<!-- these are public -->
<!-- Using one of these constants means your map style will always use the latest version and
may change as we improve the style. -->
- <string name="style_mapbox_streets">mapbox://styles/mapbox/streets-v9</string>
- <string name="style_outdoors">mapbox://styles/mapbox/outdoors-v9</string>
+ <string name="mapbox_style_mapbox_streets">mapbox://styles/mapbox/streets-v9</string>
+ <string name="mapbox_style_outdoors">mapbox://styles/mapbox/outdoors-v9</string>
<!-- Note: Emerald style has been deprecated and will be removed in a future release-->
- <string name="style_emerald">mapbox://styles/mapbox/emerald-v8</string>
- <string name="style_light">mapbox://styles/mapbox/light-v9</string>
- <string name="style_dark">mapbox://styles/mapbox/dark-v9</string>
- <string name="style_satellite">mapbox://styles/mapbox/satellite-v9</string>
- <string name="style_satellite_streets">mapbox://styles/mapbox/satellite-streets-v9</string>
+ <string name="mapbox_style_emerald">mapbox://styles/mapbox/emerald-v8</string>
+ <string name="mapbox_style_light">mapbox://styles/mapbox/light-v9</string>
+ <string name="mapbox_style_dark">mapbox://styles/mapbox/dark-v9</string>
+ <string name="mapbox_style_satellite">mapbox://styles/mapbox/satellite-v9</string>
+ <string name="mapbox_style_satellite_streets">mapbox://styles/mapbox/satellite-streets-v9</string>
</resources>
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/values/styles.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/values/styles.xml
index 708cfc72e9..82d9d1e076 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/values/styles.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/values/styles.xml
@@ -1,11 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <!-- these are public -->
- <style name="AttributionAlertDialogStyle" parent="Theme.AppCompat.Dialog.Alert">
- <item name="android:textColorPrimary">@android:color/white</item>
- </style>
-
- <style name="TelemAlertDialogStyle" parent="Theme.AppCompat.Light.Dialog.Alert"/>
+ <style name="mapbox_AlertDialogStyle" parent="Theme.AppCompat.Light.Dialog.Alert"/>
</resources> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/build.gradle b/platform/android/MapboxGLAndroidSDKTestApp/build.gradle
index f5f4ec3f54..b4d5548ae5 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/build.gradle
+++ b/platform/android/MapboxGLAndroidSDKTestApp/build.gradle
@@ -1,43 +1,20 @@
-apply plugin: 'android-sdk-manager'
apply plugin: 'com.android.application'
-apply plugin: 'checkstyle'
-apply plugin: 'devicefarm'
-
-task accessToken {
- def tokenFile = new File("MapboxGLAndroidSDKTestApp/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')
-}
ext {
- supportLibVersion = '23.4.0'
+ supportLibVersion = '25.0.1'
}
android {
- compileSdkVersion 23
- buildToolsVersion "23.0.3"
+ compileSdkVersion 25
+ buildToolsVersion "25.0.1"
defaultConfig {
applicationId "com.mapbox.mapboxsdk.testapp"
minSdkVersion 15
- targetSdkVersion 23
- versionCode 9
- versionName "4.1.0"
+ targetSdkVersion 25
+ versionCode 11
+ versionName "5.0.0"
- // Specify AndroidJUnitRunner as the default test instrumentation runner
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
@@ -65,8 +42,9 @@ android {
buildTypes {
debug {
- // run code coverage reports
testCoverageEnabled = true
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
release {
minifyEnabled false
@@ -99,71 +77,19 @@ dependencies {
// Testing dependencies
testCompile 'junit:junit:4.12'
- testCompile 'org.mockito:mockito-core:1.10.19'
+ testCompile 'org.mockito:mockito-core:2.2.27'
androidTestCompile "com.android.support:support-annotations:${supportLibVersion}"
- androidTestCompile 'com.android.support.test:runner:0.4.1'
- androidTestCompile 'com.android.support.test:rules:0.4.1'
- androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1'
+ androidTestCompile 'com.android.support.test:runner:0.5'
+ androidTestCompile 'com.android.support.test:rules:0.5'
+ androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
androidTestCompile 'com.squareup.spoon:spoon-client:1.6.2'
+ androidTestCompile 'com.android.support.test.espresso:espresso-intents:2.2.2'
}
-checkstyle {
- configFile project.file('../checks.xml')
- showViolations true
-}
-
-def getAccessKeyDeviceFarm() {
- if (project.hasProperty('AWS_ACCESS_KEY_ID_DEVICE_FARM')) {
- return AWS_ACCESS_KEY_ID_DEVICE_FARM
- } else {
- println("Could not locate AWS_ACCESS_KEY_ID_DEVICE_FARM in gradle.properties")
- return ""
- }
-}
-
-def getSecretAccessKeyDeviceFarm() {
- if (project.hasProperty('AWS_SECRET_ACCESS_KEY_DEVICE_FARM')) {
- return AWS_SECRET_ACCESS_KEY_DEVICE_FARM
- } else {
- println("Could not locate AWS_SECRET_ACCESS_KEY_DEVICE_FARM in gradle.properties")
- return ""
- }
-}
-
-devicefarm {
-
- projectName "Mapbox GL Android" // required: Must already exists.
- devicePool "sanity" // optional: Defaults to "Top Devices"
-
- authentication {
- accessKey getAccessKeyDeviceFarm()
- secretKey getSecretAccessKeyDeviceFarm()
- }
-
- devicestate {
- wifi "on"
- bluetooth "off"
- gps "on"
- nfc "on"
- latitude 47.6204 // default
- longitude - 122.3491 // default
- }
-
- instrumentation {
-
- }
-}
-
-android.applicationVariants.all { variant ->
- def name = variant.buildType.name
- def checkstyle = project.tasks.create "checkstyle${name.capitalize()}", Checkstyle
- checkstyle.dependsOn variant.javaCompile
- checkstyle.source variant.javaCompile.source
- checkstyle.classpath = project.fileTree(variant.javaCompile.destinationDir)
- checkstyle.exclude('**/BuildConfig.java')
- checkstyle.exclude('**/R.java')
- project.tasks.getByName("check").dependsOn checkstyle
-}
-
+apply from: 'gradle-make.gradle'
+apply from: 'gradle-config.gradle'
+apply from: 'gradle-device-farm.gradle'
apply from: 'gradle-spoon.gradle'
+apply from: 'gradle-checkstyle.gradle'
+
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/gradle-checkstyle.gradle b/platform/android/MapboxGLAndroidSDKTestApp/gradle-checkstyle.gradle
new file mode 100644
index 0000000000..cdcc7f1e23
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/gradle-checkstyle.gradle
@@ -0,0 +1,17 @@
+apply plugin: 'checkstyle'
+
+checkstyle {
+ toolVersion = "7.1.1" // 7.3
+ configFile = "../checkstyle.xml" as File
+}
+
+task checkstyle(type: Checkstyle) {
+ description 'Checks if the code adheres to coding standards'
+ group 'verification'
+ configFile file("../checkstyle.xml")
+ source 'src'
+ include '**/*.java'
+ exclude '**/gen/**'
+ classpath = files()
+ ignoreFailures = false
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/gradle-config.gradle b/platform/android/MapboxGLAndroidSDKTestApp/gradle-config.gradle
new file mode 100644
index 0000000000..21da83c4a0
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/gradle-config.gradle
@@ -0,0 +1,22 @@
+//
+// Configuration file for gradle build execution.
+//
+
+task accessToken {
+ def tokenFile = new File("MapboxGLAndroidSDKTestApp/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')
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/gradle-device-farm.gradle b/platform/android/MapboxGLAndroidSDKTestApp/gradle-device-farm.gradle
new file mode 100644
index 0000000000..f455e263c0
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/gradle-device-farm.gradle
@@ -0,0 +1,43 @@
+apply plugin: 'devicefarm'
+
+def getAccessKeyDeviceFarm() {
+ if (project.hasProperty('AWS_ACCESS_KEY_ID_DEVICE_FARM')) {
+ return AWS_ACCESS_KEY_ID_DEVICE_FARM
+ } else {
+ println("Could not locate AWS_ACCESS_KEY_ID_DEVICE_FARM in gradle.properties")
+ return ""
+ }
+}
+
+def getSecretAccessKeyDeviceFarm() {
+ if (project.hasProperty('AWS_SECRET_ACCESS_KEY_DEVICE_FARM')) {
+ return AWS_SECRET_ACCESS_KEY_DEVICE_FARM
+ } else {
+ println("Could not locate AWS_SECRET_ACCESS_KEY_DEVICE_FARM in gradle.properties")
+ return ""
+ }
+}
+
+devicefarm {
+
+ projectName "Mapbox GL Android" // required: Must already exists.
+ devicePool "sanity" // optional: Defaults to "Top Devices"
+
+ authentication {
+ accessKey getAccessKeyDeviceFarm()
+ secretKey getSecretAccessKeyDeviceFarm()
+ }
+
+ devicestate {
+ wifi "on"
+ bluetooth "off"
+ gps "on"
+ nfc "on"
+ latitude 47.6204 // default
+ longitude - 122.3491 // default
+ }
+
+ instrumentation {
+
+ }
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/gradle-make.gradle b/platform/android/MapboxGLAndroidSDKTestApp/gradle-make.gradle
new file mode 100644
index 0000000000..29567df6f0
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/gradle-make.gradle
@@ -0,0 +1,18 @@
+//
+// Contains GL-native make commands
+//
+
+task makeClean(type: Exec) {
+ workingDir '../../'
+ commandLine 'make', 'clean'
+}
+
+task makeAndroid(type: Exec) {
+ workingDir '../../'
+ commandLine 'make', 'android'
+}
+
+task makeAndroidAll(type: Exec) {
+ workingDir '../../'
+ commandLine 'make', 'apackage'
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/lint.xml b/platform/android/MapboxGLAndroidSDKTestApp/lint.xml
deleted file mode 100644
index 94058fd4df..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/lint.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<lint>
- <!-- Ignore errors caused by icon burning -->
- <issue id="IconLauncherShape" severity="ignore">
- <ignore path="res/drawable-mdpi/icon.png" />
- <ignore path="res/drawable-hdpi/icon.png" />
- <ignore path="res/drawable-xdpi/icon.png" />
- <ignore path="res/drawable-xxdpi/icon.png" />
- <ignore path="res/drawable-mdpi/icon_burned.png" />
- <ignore path="res/drawable-hdpi/icon_burned.png" />
- <ignore path="res/drawable-xdpi/icon_burned.png" />
- <ignore path="res/drawable-xxdpi/icon_burned.png" />
- </issue>
- <issue id="IconDuplicates" severity="ignore">
- <ignore path="res/drawable-mdpi/icon.png" />
- <ignore path="res/drawable-hdpi/icon.png" />
- <ignore path="res/drawable-xdpi/icon.png" />
- <ignore path="res/drawable-xxdpi/icon.png" />
- <ignore path="res/drawable-mdpi/icon_burned.png" />
- <ignore path="res/drawable-hdpi/icon_burned.png" />
- <ignore path="res/drawable-xdpi/icon_burned.png" />
- <ignore path="res/drawable-xxdpi/icon_burned.png" />
- </issue>
- <issue id="UnusedResources" severity="ignore">
- <ignore path="res/drawable-mdpi/icon.png" />
- <ignore path="res/drawable-hdpi/icon.png" />
- <ignore path="res/drawable-xdpi/icon.png" />
- <ignore path="res/drawable-xxdpi/icon.png" />
- <ignore path="res/drawable-mdpi/icon_burned.png" />
- <ignore path="res/drawable-hdpi/icon_burned.png" />
- <ignore path="res/drawable-xdpi/icon_burned.png" />
- <ignore path="res/drawable-xxdpi/icon_burned.png" />
- </issue>
-</lint>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/proguard-rules.pro b/platform/android/MapboxGLAndroidSDKTestApp/proguard-rules.pro
index 49c6038041..5d944b5dd4 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/proguard-rules.pro
+++ b/platform/android/MapboxGLAndroidSDKTestApp/proguard-rules.pro
@@ -4,3 +4,5 @@
-dontwarn org.codehaus.**
-keep class com.google.**
-dontwarn com.google.**
+
+-keep class com.mapbox.mapboxsdk.testapp.model.customlayer.ExampleCustomLayer { *; }
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapViewUtils.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapViewUtils.java
new file mode 100644
index 0000000000..38d5297291
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapViewUtils.java
@@ -0,0 +1,33 @@
+package com.mapbox.mapboxsdk.maps;
+
+import com.mapbox.mapboxsdk.geometry.LatLng;
+
+/**
+ * Utility class to bypass package visibility
+ */
+public class MapViewUtils {
+
+ public static void setDirection(MapboxMap mapboxMap, float direction) {
+ mapboxMap.getTransform().setBearing(direction);
+ }
+
+ public static float getDirection(MapboxMap mapboxMap) {
+ return (float) mapboxMap.getTransform().getBearing();
+ }
+
+ public static void setTilt(MapboxMap mapboxMap, float tilt) {
+ mapboxMap.getTransform().setTilt((double) tilt);
+ }
+
+ public static float getTilt(MapboxMap mapboxMap) {
+ return (float) mapboxMap.getTransform().getTilt();
+ }
+
+ public static void setLatLng(MapboxMap mapboxMap, LatLng latLng) {
+ mapboxMap.getTransform().setCenterCoordinate(latLng);
+ }
+
+ public static LatLng getLatLng(MapboxMap mapboxMap) {
+ return mapboxMap.getTransform().getCenterCoordinate();
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapboxMapTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapboxMapTest.java
new file mode 100644
index 0000000000..330de1e9c8
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapboxMapTest.java
@@ -0,0 +1,826 @@
+package com.mapbox.mapboxsdk.maps;
+
+import android.graphics.Color;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.test.espresso.Espresso;
+import android.support.test.espresso.UiController;
+import android.support.test.espresso.ViewAction;
+import android.support.test.rule.ActivityTestRule;
+import android.view.View;
+
+import com.mapbox.mapboxsdk.annotations.BaseMarkerOptions;
+import com.mapbox.mapboxsdk.annotations.Marker;
+import com.mapbox.mapboxsdk.annotations.MarkerOptions;
+import com.mapbox.mapboxsdk.annotations.Polygon;
+import com.mapbox.mapboxsdk.annotations.PolygonOptions;
+import com.mapbox.mapboxsdk.annotations.Polyline;
+import com.mapbox.mapboxsdk.annotations.PolylineOptions;
+import com.mapbox.mapboxsdk.constants.MapboxConstants;
+import com.mapbox.mapboxsdk.exceptions.InvalidMarkerPositionException;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.testapp.R;
+import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity;
+import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource;
+import com.mapbox.mapboxsdk.testapp.utils.TestConstants;
+import com.mapbox.mapboxsdk.testapp.utils.ViewUtils;
+
+import org.hamcrest.Matcher;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import timber.log.Timber;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static junit.framework.TestCase.assertFalse;
+import static junit.framework.TestCase.assertNotNull;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * This test is responsible for testing the public API.
+ * <p>
+ * Methods executed on MapboxMap are called from a ViewAction to ensure correct synchronisation
+ * with the application UI-thread.
+ * </p>
+ */
+public class MapboxMapTest {
+
+ @Rule
+ public final ActivityTestRule<EspressoTestActivity> rule = new ActivityTestRule<>(EspressoTestActivity.class);
+
+ private OnMapReadyIdlingResource idlingResource;
+ private EspressoTestActivity activity;
+
+ @Before
+ public void beforeTest() {
+ activity = rule.getActivity();
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ idlingResource = new OnMapReadyIdlingResource(activity);
+ Espresso.registerIdlingResources(idlingResource);
+ }
+
+ @Test
+ public void testSanity() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ MapboxMap mapboxMap = activity.getMapboxMap();
+ assertNotNull("mapboxMap should not be null", mapboxMap);
+ }
+
+ //
+ // MinZoomLevel
+ //
+
+ @Test
+ public void testMinZoom() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ mapboxMap.setMinZoomPreference(10);
+ assertEquals("MinZoom should match", 10, mapboxMap.getMinZoomLevel(), 10);
+ }
+ }));
+ }
+
+ @Test
+ public void testMaxZoom() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ final double zoom = 10;
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ mapboxMap.setMaxZoomPreference(zoom);
+ assertEquals("MaxZoom should match", zoom, mapboxMap.getMaxZoomLevel(), 10);
+ }
+ }));
+ }
+
+ @Test
+ public void testInitialZoomLevels() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ assertEquals("MaxZoom should match", MapboxConstants.MAXIMUM_ZOOM, mapboxMap.getMaxZoomLevel(),
+ TestConstants.ZOOM_DELTA);
+ assertEquals("MinZoom should match", MapboxConstants.MINIMUM_ZOOM, mapboxMap.getMinZoomLevel(),
+ TestConstants.ZOOM_DELTA);
+ }
+ }));
+ }
+
+ //
+ // TrackingSettings
+ //
+
+ @Test
+ public void testTrackingSettings() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ MapboxMap mapboxMap = activity.getMapboxMap();
+ assertNotNull("TrackingSettings should not be null", mapboxMap.getTrackingSettings());
+ }
+
+ //
+ // InfoWindow
+ //
+
+ @Test
+ public void testConcurrentInfoWindowEnabled() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ mapboxMap.setAllowConcurrentMultipleOpenInfoWindows(true);
+ assertTrue("ConcurrentWindows should be true", mapboxMap.isAllowConcurrentMultipleOpenInfoWindows());
+ }
+ }));
+ }
+
+ @Test
+ public void testConcurrentInfoWindowDisabled() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ mapboxMap.setAllowConcurrentMultipleOpenInfoWindows(false);
+ assertFalse("ConcurrentWindows should be false", mapboxMap.isAllowConcurrentMultipleOpenInfoWindows());
+ }
+ }));
+ }
+
+ @Test
+ public void testInfoWindowAdapter() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ MapboxMap.InfoWindowAdapter infoWindowAdapter = new MapboxMap.InfoWindowAdapter() {
+ @Nullable
+ @Override
+ public View getInfoWindow(@NonNull Marker marker) {
+ return null;
+ }
+ };
+ mapboxMap.setInfoWindowAdapter(infoWindowAdapter);
+ assertEquals("InfoWindowAdpter should be the same", infoWindowAdapter, mapboxMap.getInfoWindowAdapter());
+ }
+ }));
+ }
+
+ //
+ // Location
+ //
+
+ @Test
+ @Ignore /* disabled due to enabling permissions during test #7177 */
+ public void testMyLocationEnabled() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ mapboxMap.setMyLocationEnabled(true);
+ assertTrue("MyLocationEnabled should be true", mapboxMap.isMyLocationEnabled());
+ }
+ }));
+ }
+
+ @Test
+ @Ignore /* can't create handler inside thread that not called Looper.prepare() */
+ public void testMyLocationDisabled() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ mapboxMap.setMyLocationEnabled(false);
+ assertFalse("MyLocationEnabled should be false", mapboxMap.isMyLocationEnabled());
+ }
+ }));
+ }
+
+ //
+ // setters/getters interfaces
+ //
+
+ @Test
+ public void testFpsListener() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ MapboxMap.OnFpsChangedListener fpsChangedListener = new MapboxMap.OnFpsChangedListener() {
+ @Override
+ public void onFpsChanged(double fps) {
+
+ }
+ };
+ mapboxMap.setOnFpsChangedListener(fpsChangedListener);
+ assertEquals("FpsListener should match", fpsChangedListener, mapboxMap.getOnFpsChangedListener());
+ }
+ }));
+ }
+
+ @Test
+ public void testInfoWindowClickListener() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ MapboxMap.OnInfoWindowClickListener clickListener = new MapboxMap.OnInfoWindowClickListener() {
+ @Override
+ public boolean onInfoWindowClick(@NonNull Marker marker) {
+ return false;
+ }
+ };
+ mapboxMap.setOnInfoWindowClickListener(clickListener);
+ assertEquals("InfoWidowClickListener should match", clickListener, mapboxMap.getOnInfoWindowClickListener());
+ }
+ }));
+ }
+
+ @Test
+ public void testInfoWindowCloseListener() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ MapboxMap.OnInfoWindowCloseListener listener = new MapboxMap.OnInfoWindowCloseListener() {
+ @Override
+ public void onInfoWindowClose(Marker marker) {
+
+ }
+ };
+ mapboxMap.setOnInfoWindowCloseListener(listener);
+ assertEquals("InfoWindowCloseListener should match", listener, mapboxMap.getOnInfoWindowCloseListener());
+ }
+ }));
+ }
+
+ @Test
+ public void testInfoWindowLongClickListener() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ MapboxMap.OnInfoWindowLongClickListener listener = new MapboxMap.OnInfoWindowLongClickListener() {
+ @Override
+ public void onInfoWindowLongClick(Marker marker) {
+
+ }
+ };
+ mapboxMap.setOnInfoWindowLongClickListener(listener);
+ assertEquals("InfoWindowLongClickListener should match", listener,
+ mapboxMap.getOnInfoWindowLongClickListener());
+ }
+ }));
+ }
+
+ //
+ // Annotations
+ //
+
+ @Test
+ public void testAddMarker() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ MarkerOptions markerOptions = new MarkerOptions().position(new LatLng());
+ Marker marker = mapboxMap.addMarker(markerOptions);
+ assertTrue("Marker should be contained", mapboxMap.getMarkers().contains(marker));
+ }
+ }));
+ }
+
+ @Test(expected = InvalidMarkerPositionException.class)
+ public void testAddMarkerInvalidPosition() {
+ new MarkerOptions().getMarker();
+ }
+
+ @Test
+ public void testAddMarkers() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ List<BaseMarkerOptions> markerList = new ArrayList<>();
+ MarkerOptions markerOptions1 = new MarkerOptions().position(new LatLng()).title("a");
+ MarkerOptions markerOptions2 = new MarkerOptions().position(new LatLng()).title("b");
+ markerList.add(markerOptions1);
+ markerList.add(markerOptions2);
+ List<Marker> markers = mapboxMap.addMarkers(markerList);
+ assertEquals("Markers size should be 2", 2, mapboxMap.getMarkers().size());
+ assertTrue(mapboxMap.getMarkers().contains(markers.get(0)));
+ assertTrue(mapboxMap.getMarkers().contains(markers.get(1)));
+ }
+ }));
+ }
+
+ @Test
+ public void testAddMarkersEmpty() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ List<BaseMarkerOptions> markerList = new ArrayList<>();
+ mapboxMap.addMarkers(markerList);
+ assertEquals("Markers size should be 0", 0, mapboxMap.getMarkers().size());
+ }
+ }));
+ }
+
+ @Test
+ public void testAddMarkersSingleMarker() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ List<BaseMarkerOptions> markerList = new ArrayList<>();
+ MarkerOptions markerOptions = new MarkerOptions().title("a").position(new LatLng());
+ markerList.add(markerOptions);
+ List<Marker> markers = mapboxMap.addMarkers(markerList);
+ assertEquals("Markers size should be 1", 1, mapboxMap.getMarkers().size());
+ assertTrue(mapboxMap.getMarkers().contains(markers.get(0)));
+ }
+ }));
+ }
+
+ @Test
+ public void testAddPolygon() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ PolygonOptions polygonOptions = new PolygonOptions().add(new LatLng());
+ Polygon polygon = mapboxMap.addPolygon(polygonOptions);
+ assertTrue("Polygon should be contained", mapboxMap.getPolygons().contains(polygon));
+ }
+ }));
+ }
+
+ @Test
+ public void testAddEmptyPolygon() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ PolygonOptions polygonOptions = new PolygonOptions();
+ Polygon polygon = mapboxMap.addPolygon(polygonOptions);
+ assertTrue("Polygon should be ignored", !mapboxMap.getPolygons().contains(polygon));
+ }
+ }));
+ }
+
+ @Test
+ public void testAddPolygons() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ List<PolygonOptions> polygonList = new ArrayList<>();
+ PolygonOptions polygonOptions1 = new PolygonOptions().fillColor(Color.BLACK).add(new LatLng());
+ PolygonOptions polygonOptions2 = new PolygonOptions().fillColor(Color.WHITE).add(new LatLng());
+ PolygonOptions polygonOptions3 = new PolygonOptions();
+ polygonList.add(polygonOptions1);
+ polygonList.add(polygonOptions2);
+ polygonList.add(polygonOptions3);
+ mapboxMap.addPolygons(polygonList);
+ assertEquals("Polygons size should be 2", 2, mapboxMap.getPolygons().size());
+ assertTrue(mapboxMap.getPolygons().contains(polygonOptions1.getPolygon()));
+ assertTrue(mapboxMap.getPolygons().contains(polygonOptions2.getPolygon()));
+ assertTrue("Polygon should be ignored", !mapboxMap.getPolygons().contains(polygonOptions3.getPolygon()));
+ }
+ }));
+ }
+
+ @Test
+ public void addPolygonsEmpty() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ mapboxMap.addPolygons(new ArrayList<PolygonOptions>());
+ assertEquals("Polygons size should be 0", 0, mapboxMap.getPolygons().size());
+ }
+ }));
+ }
+
+ @Test
+ public void addPolygonsSingle() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ List<PolygonOptions> polygonList = new ArrayList<>();
+ PolygonOptions polygonOptions = new PolygonOptions().fillColor(Color.BLACK).add(new LatLng());
+ polygonList.add(polygonOptions);
+ mapboxMap.addPolygons(polygonList);
+ assertEquals("Polygons size should be 1", 1, mapboxMap.getPolygons().size());
+ assertTrue(mapboxMap.getPolygons().contains(polygonOptions.getPolygon()));
+ }
+ }));
+ }
+
+ @Test
+ public void testAddPolyline() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ PolylineOptions polylineOptions = new PolylineOptions().add(new LatLng());
+ Polyline polyline = mapboxMap.addPolyline(polylineOptions);
+ assertTrue("Polyline should be contained", mapboxMap.getPolylines().contains(polyline));
+ }
+ }));
+ }
+
+ @Test
+ public void testAddEmptyPolyline() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ PolylineOptions polylineOptions = new PolylineOptions();
+ Polyline polyline = mapboxMap.addPolyline(polylineOptions);
+ assertTrue("Polyline should be ignored", !mapboxMap.getPolylines().contains(polyline));
+ }
+ }));
+ }
+
+ @Test
+ public void testAddPolylines() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ List<PolylineOptions> polylineList = new ArrayList<>();
+ PolylineOptions polygonOptions1 = new PolylineOptions().color(Color.BLACK).add(new LatLng());
+ PolylineOptions polygonOptions2 = new PolylineOptions().color(Color.WHITE).add(new LatLng());
+ PolylineOptions polygonOptions3 = new PolylineOptions();
+ polylineList.add(polygonOptions1);
+ polylineList.add(polygonOptions2);
+ polylineList.add(polygonOptions3);
+ mapboxMap.addPolylines(polylineList);
+ assertEquals("Polygons size should be 2", 2, mapboxMap.getPolylines().size());
+ assertTrue(mapboxMap.getPolylines().contains(polygonOptions1.getPolyline()));
+ assertTrue(mapboxMap.getPolylines().contains(polygonOptions2.getPolyline()));
+ assertTrue("Polyline should be ignored", !mapboxMap.getPolylines().contains(polygonOptions3.getPolyline()));
+ }
+ }));
+ }
+
+ @Test
+ public void testAddPolylinesEmpty() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ mapboxMap.addPolylines(new ArrayList<PolylineOptions>());
+ assertEquals("Polygons size should be 0", 0, mapboxMap.getPolylines().size());
+ }
+ }));
+ }
+
+ @Test
+ public void testAddPolylinesSingle() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ List<PolylineOptions> polylineList = new ArrayList<>();
+ PolylineOptions polygonOptions = new PolylineOptions().color(Color.BLACK).add(new LatLng());
+ polylineList.add(polygonOptions);
+ mapboxMap.addPolylines(polylineList);
+ assertEquals("Polygons size should be 1", 1, mapboxMap.getPolylines().size());
+ assertTrue(mapboxMap.getPolylines().contains(polygonOptions.getPolyline()));
+ }
+ }));
+ }
+
+ @Test
+ public void testRemoveMarker() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ MarkerOptions markerOptions = new MarkerOptions().position(new LatLng());
+ Marker marker = mapboxMap.addMarker(markerOptions);
+ mapboxMap.removeMarker(marker);
+ assertTrue("Markers should be empty", mapboxMap.getMarkers().isEmpty());
+ }
+ }));
+ }
+
+ @Test
+ public void testRemovePolygon() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ PolygonOptions polygonOptions = new PolygonOptions();
+ Polygon polygon = mapboxMap.addPolygon(polygonOptions);
+ mapboxMap.removePolygon(polygon);
+ assertTrue("Polygons should be empty", mapboxMap.getPolylines().isEmpty());
+ }
+ }));
+ }
+
+ @Test
+ public void testRemovePolyline() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ PolylineOptions polylineOptions = new PolylineOptions();
+ Polyline polyline = mapboxMap.addPolyline(polylineOptions);
+ mapboxMap.removePolyline(polyline);
+ assertTrue("Polylines should be empty", mapboxMap.getPolylines().isEmpty());
+ }
+ }));
+ }
+
+ @Test
+ public void testRemoveAnnotation() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ MarkerOptions markerOptions = new MarkerOptions().position(new LatLng());
+ Marker marker = mapboxMap.addMarker(markerOptions);
+ mapboxMap.removeAnnotation(marker);
+ assertTrue("Annotations should be empty", mapboxMap.getAnnotations().isEmpty());
+ }
+ }));
+ }
+
+ @Test
+ public void testRemoveAnnotationById() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ MarkerOptions markerOptions = new MarkerOptions().position(new LatLng());
+ mapboxMap.addMarker(markerOptions);
+ // id will always be 0 in unit tests
+ mapboxMap.removeAnnotation(0);
+ assertTrue("Annotations should be empty", mapboxMap.getAnnotations().isEmpty());
+ }
+ }));
+ }
+
+ @Test
+ public void testRemoveAnnotations() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ List<BaseMarkerOptions> markerList = new ArrayList<>();
+ MarkerOptions markerOptions1 = new MarkerOptions().title("a").position(new LatLng());
+ MarkerOptions markerOptions2 = new MarkerOptions().title("b").position(new LatLng());
+ markerList.add(markerOptions1);
+ markerList.add(markerOptions2);
+ mapboxMap.addMarkers(markerList);
+ mapboxMap.removeAnnotations();
+ assertTrue("Annotations should be empty", mapboxMap.getAnnotations().isEmpty());
+ }
+ }));
+ }
+
+ @Test
+ public void testClear() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ List<BaseMarkerOptions> markerList = new ArrayList<>();
+ MarkerOptions markerOptions1 = new MarkerOptions().title("a").position(new LatLng());
+ MarkerOptions markerOptions2 = new MarkerOptions().title("b").position(new LatLng());
+ markerList.add(markerOptions1);
+ markerList.add(markerOptions2);
+ mapboxMap.addMarkers(markerList);
+ mapboxMap.clear();
+ assertTrue("Annotations should be empty", mapboxMap.getAnnotations().isEmpty());
+ }
+ }));
+ }
+
+ @Test
+ public void testRemoveAnnotationsByList() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ List<BaseMarkerOptions> markerList = new ArrayList<>();
+ MarkerOptions markerOptions1 = new MarkerOptions().title("a").position(new LatLng());
+ MarkerOptions markerOptions2 = new MarkerOptions().title("b").position(new LatLng());
+ markerList.add(markerOptions1);
+ markerList.add(markerOptions2);
+ List<Marker> markers = mapboxMap.addMarkers(markerList);
+ Marker marker = mapboxMap.addMarker(new MarkerOptions().position(new LatLng()).title("c"));
+ mapboxMap.removeAnnotations(markers);
+ assertTrue("Annotations should not be empty", mapboxMap.getAnnotations().size() == 1);
+ assertTrue("Marker should be contained", mapboxMap.getAnnotations().contains(marker));
+ }
+ }));
+ }
+
+ @Test
+ public void testGetAnnotationById() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ MarkerOptions markerOptions = new MarkerOptions().position(new LatLng());
+ Marker initialMarker = mapboxMap.addMarker(markerOptions);
+ Marker retrievedMarker = (Marker) mapboxMap.getAnnotation(0);
+ assertEquals("Markers should match", initialMarker, retrievedMarker);
+ }
+ }));
+ }
+
+ @Test
+ public void testGetAnnotations() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ assertNotNull("Annotations should be non null", mapboxMap.getAnnotations());
+ }
+ }));
+ }
+
+ @Test
+ public void testGetMarkers() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ assertNotNull("Markers should be non null", mapboxMap.getMarkers());
+ }
+ }));
+ }
+
+ @Test
+ public void testGetPolygons() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ assertNotNull("Polygons should be non null", mapboxMap.getPolygons());
+ }
+ }));
+ }
+
+ @Test
+ public void testGetPolylines() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ assertNotNull("Polylines should be non null", mapboxMap.getPolylines());
+ }
+ }));
+ }
+
+ @Test
+ public void testGetSelectedMarkers() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ assertNotNull("Selected markers should be non null", mapboxMap.getSelectedMarkers());
+ }
+ }));
+ }
+
+ @Test
+ public void testSelectMarker() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ MarkerOptions markerOptions = new MarkerOptions().position(new LatLng());
+ Marker marker = mapboxMap.addMarker(markerOptions);
+ mapboxMap.selectMarker(marker);
+ assertTrue("Marker should be contained", mapboxMap.getSelectedMarkers().contains(marker));
+ }
+ }));
+ }
+
+ @Test
+ public void testDeselectMarker() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ MarkerOptions markerOptions = new MarkerOptions().position(new LatLng());
+ Marker marker = mapboxMap.addMarker(markerOptions);
+ mapboxMap.selectMarker(marker);
+ mapboxMap.deselectMarker(marker);
+ assertTrue("Selected markers should be empty", mapboxMap.getSelectedMarkers().isEmpty());
+ }
+ }));
+ }
+
+ @Test
+ public void testDeselectMarkers() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = activity.getMapboxMap();
+ onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() {
+ @Override
+ public void onViewAction(UiController uiController, View view) {
+ MarkerOptions markerOptions = new MarkerOptions().position(new LatLng());
+ Marker marker1 = mapboxMap.addMarker(markerOptions);
+ Marker marker2 = mapboxMap.addMarker(markerOptions);
+ mapboxMap.selectMarker(marker1);
+ mapboxMap.selectMarker(marker2);
+ mapboxMap.deselectMarkers();
+ assertTrue("Selected markers should be empty", mapboxMap.getSelectedMarkers().isEmpty());
+ }
+ }));
+ }
+
+ @After
+ public void afterTest() {
+ Timber.e("@After test: unregister idle resource");
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
+
+ private class MapboxMapAction implements ViewAction {
+
+ private InvokeViewAction invokeViewAction;
+
+ MapboxMapAction(InvokeViewAction invokeViewAction) {
+ this.invokeViewAction = invokeViewAction;
+ }
+
+ @Override
+ public Matcher<View> getConstraints() {
+ return isDisplayed();
+ }
+
+ @Override
+ public String getDescription() {
+ return getClass().getSimpleName();
+ }
+
+ @Override
+ public void perform(UiController uiController, View view) {
+ invokeViewAction.onViewAction(uiController, view);
+ }
+ }
+
+ interface InvokeViewAction {
+ void onViewAction(UiController uiController, View view);
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapboxMapUtils.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapboxMapUtils.java
deleted file mode 100644
index a88e5aeda5..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/maps/MapboxMapUtils.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.mapbox.mapboxsdk.maps;
-
-/**
- * Utility class to bypass package visibility
- */
-public class MapboxMapUtils {
-
- public static void setDirection(MapView mapView, float direction) {
- mapView.setBearing(direction);
- }
-
- public static void setTilt(MapView mapView, float tilt) {
- mapView.setTilt((double) tilt);
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/BaseActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/BaseActivityTest.java
index b00255a6c7..2f51140cd1 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/BaseActivityTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/BaseActivityTest.java
@@ -4,9 +4,9 @@ import android.app.Activity;
import android.support.test.espresso.Espresso;
import android.support.test.espresso.IdlingResourceTimeoutException;
import android.support.test.rule.ActivityTestRule;
-import android.util.Log;
-import com.mapbox.mapboxsdk.constants.MapboxConstants;
+import timber.log.Timber;
+
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.testapp.R;
import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource;
@@ -23,49 +23,50 @@ import static android.support.test.espresso.matcher.ViewMatchers.withId;
public abstract class BaseActivityTest {
- @Rule
- public ActivityTestRule<Activity> rule = new ActivityTestRule<>(getActivityClass());
- protected MapboxMap mapboxMap;
- protected OnMapReadyIdlingResource idlingResource;
+ @Rule
+ public ActivityTestRule<Activity> rule = new ActivityTestRule<>(getActivityClass());
+ protected MapboxMap mapboxMap;
+ protected OnMapReadyIdlingResource idlingResource;
- @Before
- public void beforeTest() {
- try {
- Log.e(MapboxConstants.TAG, "@Before test: register idle resource");
- idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
- Espresso.registerIdlingResources(idlingResource);
- checkViewIsDisplayed(R.id.mapView);
- mapboxMap = idlingResource.getMapboxMap();
- } catch (IdlingResourceTimeoutException e) {
- Log.e(MapboxConstants.TAG, "Idling resource timed out. Couldn't not validate if map is ready.");
- throw new RuntimeException("Could not start test for " + getActivityClass().getSimpleName() + ".\n" +
- "The ViewHierarchy doesn't contain a view with resource id = R.id.mapView or \n" +
- "the Activity doesn't contain an instance variable with a name equal to mapboxMap.\n" +
- "You can resolve this issue be implementing the requirements above or\n add " + getActivityClass().getSimpleName() + " to the excludeActivities array in `generate-test-code.js`.\n");
- }
+ @Before
+ public void beforeTest() {
+ try {
+ Timber.e("@Before test: register idle resource");
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ checkViewIsDisplayed(R.id.mapView);
+ mapboxMap = idlingResource.getMapboxMap();
+ } catch (IdlingResourceTimeoutException idlingResourceTimeoutException) {
+ Timber.e("Idling resource timed out. Couldn't not validate if map is ready.");
+ throw new RuntimeException("Could not start test for " + getActivityClass().getSimpleName() + ".\n"
+ + "The ViewHierarchy doesn't contain a view with resource id = R.id.mapView or \n"
+ + "the Activity doesn't contain an instance variable with a name equal to mapboxMap.\n"
+ + "You can resolve this issue be implementing the requirements above or\n add "
+ + getActivityClass().getSimpleName() + " to the excludeActivities array in `generate-test-code.js`.\n");
}
+ }
- protected abstract Class getActivityClass();
+ protected abstract Class getActivityClass();
- protected void checkViewIsDisplayed(int id) {
- onView(withId(id))
- .check(matches(isDisplayed()));
- }
+ protected void checkViewIsDisplayed(int id) {
+ onView(withId(id))
+ .check(matches(isDisplayed()));
+ }
- protected void takeScreenshot(final String name) {
- final Activity activity = rule.getActivity();
- activity.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- ScreenshotUtil.take(activity, name);
- }
- });
- }
+ protected void takeScreenshot(final String name) {
+ final Activity activity = rule.getActivity();
+ activity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ ScreenshotUtil.take(activity, name);
+ }
+ });
+ }
- @After
- public void afterTest() {
- Log.e(MapboxConstants.TAG, "@After test: unregister idle resource");
- Espresso.unregisterIdlingResources(idlingResource);
- }
+ @After
+ public void afterTest() {
+ Timber.e("@After test: unregister idle resource");
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/AddRemoveMarkerActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/AddRemoveMarkerActivityTest.java
deleted file mode 100644
index 76ee101904..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/AddRemoveMarkerActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.annotation;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.annotation.AddRemoveMarkerActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for AddRemoveMarkerActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class AddRemoveMarkerActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return AddRemoveMarkerActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/BulkMarkerActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/BulkMarkerActivityTest.java
deleted file mode 100644
index 33bfb23b25..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/BulkMarkerActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.annotation;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.annotation.BulkMarkerActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for BulkMarkerActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class BulkMarkerActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return BulkMarkerActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/DynamicMarkerChangeActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/DynamicMarkerChangeActivityTest.java
deleted file mode 100644
index 040affafda..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/DynamicMarkerChangeActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.annotation;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.annotation.DynamicMarkerChangeActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for DynamicMarkerChangeActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class DynamicMarkerChangeActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return DynamicMarkerChangeActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/MarkerViewActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/MarkerViewActivityTest.java
deleted file mode 100644
index 9a0b66d8bc..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/MarkerViewActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.annotation;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.annotation.MarkerViewActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for MarkerViewActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class MarkerViewActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return MarkerViewActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/MarkerViewScaleActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/MarkerViewScaleActivityTest.java
deleted file mode 100644
index 373b2d3d10..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/MarkerViewScaleActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.annotation;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.annotation.MarkerViewScaleActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for MarkerViewScaleActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class MarkerViewScaleActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return MarkerViewScaleActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/PolygonActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/PolygonActivityTest.java
deleted file mode 100644
index 9569b7880b..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/PolygonActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.annotation;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.annotation.PolygonActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for PolygonActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class PolygonActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return PolygonActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/PolylineActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/PolylineActivityTest.java
deleted file mode 100644
index 32f099cbc8..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/PolylineActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.annotation;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.annotation.PolylineActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for PolylineActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class PolylineActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return PolylineActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/PressForMarkerActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/PressForMarkerActivityTest.java
deleted file mode 100644
index 3475a47263..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/annotation/PressForMarkerActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.annotation;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.annotation.PressForMarkerActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for PressForMarkerActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class PressForMarkerActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return PressForMarkerActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/camera/CameraAnimationTypeActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/camera/CameraAnimationTypeActivityTest.java
deleted file mode 100644
index a4ee61de4d..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/camera/CameraAnimationTypeActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.camera;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.camera.CameraAnimationTypeActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for CameraAnimationTypeActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class CameraAnimationTypeActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return CameraAnimationTypeActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/camera/CameraPositionActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/camera/CameraPositionActivityTest.java
deleted file mode 100644
index 784488668c..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/camera/CameraPositionActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.camera;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.camera.CameraPositionActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for CameraPositionActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class CameraPositionActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return CameraPositionActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/camera/LatLngBoundsActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/camera/LatLngBoundsActivityTest.java
deleted file mode 100644
index f0b061a1c5..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/camera/LatLngBoundsActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.camera;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.camera.LatLngBoundsActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for LatLngBoundsActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class LatLngBoundsActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return LatLngBoundsActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/camera/ManualZoomActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/camera/ManualZoomActivityTest.java
deleted file mode 100644
index 2a50f5f820..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/camera/ManualZoomActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.camera;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.camera.ManualZoomActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for ManualZoomActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class ManualZoomActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return ManualZoomActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/camera/MaxMinZoomActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/camera/MaxMinZoomActivityTest.java
deleted file mode 100644
index cb63bb8838..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/camera/MaxMinZoomActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.camera;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.camera.MaxMinZoomActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for MaxMinZoomActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class MaxMinZoomActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return MaxMinZoomActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/camera/ScrollByActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/camera/ScrollByActivityTest.java
deleted file mode 100644
index ce594efd1f..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/camera/ScrollByActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.camera;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.camera.ScrollByActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for ScrollByActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class ScrollByActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return ScrollByActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/customlayer/CustomLayerActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/customlayer/CustomLayerActivityTest.java
deleted file mode 100644
index 56c2eae817..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/customlayer/CustomLayerActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.customlayer;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.customlayer.CustomLayerActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for CustomLayerActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class CustomLayerActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return CustomLayerActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/directions/DirectionsActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/directions/DirectionsActivityTest.java
deleted file mode 100644
index 379c57e55a..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/directions/DirectionsActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.directions;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.directions.DirectionsActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for DirectionsActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class DirectionsActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return DirectionsActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/feature/QueryRenderedFeaturesBoxCountActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/feature/QueryRenderedFeaturesBoxCountActivityTest.java
deleted file mode 100644
index c4a71d8279..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/feature/QueryRenderedFeaturesBoxCountActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.feature;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.feature.QueryRenderedFeaturesBoxCountActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for QueryRenderedFeaturesBoxCountActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class QueryRenderedFeaturesBoxCountActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return QueryRenderedFeaturesBoxCountActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/feature/QueryRenderedFeaturesPropertiesActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/feature/QueryRenderedFeaturesPropertiesActivityTest.java
deleted file mode 100644
index 8a474fb9bf..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/feature/QueryRenderedFeaturesPropertiesActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.feature;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.feature.QueryRenderedFeaturesPropertiesActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for QueryRenderedFeaturesPropertiesActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class QueryRenderedFeaturesPropertiesActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return QueryRenderedFeaturesPropertiesActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/geocoding/GeocoderActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/geocoding/GeocoderActivityTest.java
deleted file mode 100644
index 05d1f29547..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/geocoding/GeocoderActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.geocoding;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.geocoding.GeocoderActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for GeocoderActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class GeocoderActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return GeocoderActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/imagegenerator/PrintActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/imagegenerator/PrintActivityTest.java
deleted file mode 100644
index c14cc413cf..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/imagegenerator/PrintActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.imagegenerator;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.imagegenerator.PrintActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for PrintActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class PrintActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return PrintActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/infowindow/DynamicInfoWindowAdapterActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/infowindow/DynamicInfoWindowAdapterActivityTest.java
deleted file mode 100644
index b7a8245795..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/infowindow/DynamicInfoWindowAdapterActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.infowindow;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.infowindow.DynamicInfoWindowAdapterActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for DynamicInfoWindowAdapterActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class DynamicInfoWindowAdapterActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return DynamicInfoWindowAdapterActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/infowindow/InfoWindowActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/infowindow/InfoWindowActivityTest.java
deleted file mode 100644
index 5ba4d56a03..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/infowindow/InfoWindowActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.infowindow;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.infowindow.InfoWindowActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for InfoWindowActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class InfoWindowActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return InfoWindowActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/infowindow/InfoWindowAdapterActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/infowindow/InfoWindowAdapterActivityTest.java
deleted file mode 100644
index 7071874435..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/infowindow/InfoWindowAdapterActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.infowindow;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.infowindow.InfoWindowAdapterActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for InfoWindowAdapterActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class InfoWindowAdapterActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return InfoWindowAdapterActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/maplayout/DebugModeActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/maplayout/DebugModeActivityTest.java
deleted file mode 100644
index 5764d364e0..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/maplayout/DebugModeActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.maplayout;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.maplayout.DebugModeActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for DebugModeActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class DebugModeActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return DebugModeActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/maplayout/MapPaddingActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/maplayout/MapPaddingActivityTest.java
deleted file mode 100644
index 3f94b11246..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/maplayout/MapPaddingActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.maplayout;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.maplayout.MapPaddingActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for MapPaddingActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class MapPaddingActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return MapPaddingActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/maplayout/SurfaceViewMediaControlActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/maplayout/SurfaceViewMediaControlActivityTest.java
deleted file mode 100644
index a52a4b0edb..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/maplayout/SurfaceViewMediaControlActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.maplayout;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.maplayout.SurfaceViewMediaControlActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for SurfaceViewMediaControlActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class SurfaceViewMediaControlActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return SurfaceViewMediaControlActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/maplayout/VideoViewActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/maplayout/VideoViewActivityTest.java
deleted file mode 100644
index fb9330f0f4..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/maplayout/VideoViewActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.maplayout;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.maplayout.VideoViewActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for VideoViewActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class VideoViewActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return VideoViewActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/offline/OfflineActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/offline/OfflineActivityTest.java
deleted file mode 100644
index 00a953f37e..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/offline/OfflineActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.offline;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.offline.OfflineActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for OfflineActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class OfflineActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return OfflineActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/style/CircleLayerActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/style/CircleLayerActivityTest.java
deleted file mode 100644
index 5299f2e716..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/style/CircleLayerActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.style;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.style.CircleLayerActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for CircleLayerActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class CircleLayerActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return CircleLayerActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/style/CustomSpriteActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/style/CustomSpriteActivityTest.java
deleted file mode 100644
index 5e482b2b38..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/style/CustomSpriteActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.style;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.style.CustomSpriteActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for CustomSpriteActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class CustomSpriteActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return CustomSpriteActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/style/RuntimeStyleActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/style/RuntimeStyleActivityTest.java
deleted file mode 100644
index 37d5f64e8c..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/style/RuntimeStyleActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.style;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.style.RuntimeStyleActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for RuntimeStyleActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class RuntimeStyleActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return RuntimeStyleActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/style/RuntimeStyleTimingTestActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/style/RuntimeStyleTimingTestActivityTest.java
deleted file mode 100644
index 7320b8527c..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/style/RuntimeStyleTimingTestActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.style;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.style.RuntimeStyleTimingTestActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for RuntimeStyleTimingTestActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class RuntimeStyleTimingTestActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return RuntimeStyleTimingTestActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/style/StyleFileActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/style/StyleFileActivityTest.java
deleted file mode 100644
index 29116b85cb..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen/style/StyleFileActivityTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// This file is generated. Edit android/platform/scripts/generate-test-code.js, then run `make generate-test-android`.
-package com.mapbox.mapboxsdk.testapp.activity.gen.style;
-
-import android.support.test.runner.AndroidJUnit4;
-
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.style.StyleFileActivity;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.assertion.ViewAssertions.matches;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-/**
- * Sanity test for StyleFileActivity
- */
-@RunWith(AndroidJUnit4.class)
-public class StyleFileActivityTest extends BaseActivityTest {
-
- @Test
- public void testSanity() {
- onView(withId(R.id.mapView)).check(matches(isDisplayed()));
- }
-
- @Override
- protected Class getActivityClass() {
- return StyleFileActivity.class;
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/MarkerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/MarkerTest.java
new file mode 100644
index 0000000000..77025c8fa5
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/MarkerTest.java
@@ -0,0 +1,142 @@
+package com.mapbox.mapboxsdk.testapp.annotations;
+
+import android.support.test.espresso.Espresso;
+import android.support.test.espresso.UiController;
+import android.support.test.espresso.ViewAction;
+import android.support.test.rule.ActivityTestRule;
+import android.view.View;
+
+import com.mapbox.mapboxsdk.annotations.Marker;
+import com.mapbox.mapboxsdk.annotations.MarkerOptions;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.testapp.R;
+import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity;
+import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource;
+import com.mapbox.mapboxsdk.testapp.utils.TestConstants;
+import com.mapbox.mapboxsdk.testapp.utils.ViewUtils;
+
+import org.hamcrest.Matcher;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.assertion.ViewAssertions.matches;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static android.support.test.espresso.matcher.ViewMatchers.withText;
+import static org.junit.Assert.assertEquals;
+
+public class MarkerTest {
+
+ @Rule
+ public final ActivityTestRule<EspressoTestActivity> rule = new ActivityTestRule<>(EspressoTestActivity.class);
+
+ private OnMapReadyIdlingResource idlingResource;
+ private Marker marker;
+
+ @Before
+ public void registerIdlingResource() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ }
+
+ @Test
+ @Ignore
+ public void addMarkerTest() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+ assertEquals("Markers should be empty", 0, mapboxMap.getMarkers().size());
+
+ MarkerOptions options = new MarkerOptions();
+ options.setPosition(new LatLng());
+ options.setSnippet(TestConstants.TEXT_MARKER_SNIPPET);
+ options.setTitle(TestConstants.TEXT_MARKER_TITLE);
+
+ onView(withId(R.id.mapView)).perform(new AddMarkerAction(mapboxMap, options));
+ assertEquals("Markers sze should be 1, ", 1, mapboxMap.getMarkers().size());
+ assertEquals("Marker id should be 0", 0, marker.getId());
+ assertEquals("Marker target should match", new LatLng(), marker.getPosition());
+ assertEquals("Marker snippet should match", TestConstants.TEXT_MARKER_SNIPPET, marker.getSnippet());
+ assertEquals("Marker target should match", TestConstants.TEXT_MARKER_TITLE, marker.getTitle());
+ mapboxMap.clear();
+ assertEquals("Markers should be empty", 0, mapboxMap.getMarkers().size());
+ }
+
+ @Test
+ @Ignore
+ public void showInfoWindowTest() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ final MarkerOptions options = new MarkerOptions();
+ options.setPosition(new LatLng());
+ options.setSnippet(TestConstants.TEXT_MARKER_SNIPPET);
+ options.setTitle(TestConstants.TEXT_MARKER_TITLE);
+
+ onView(withId(R.id.mapView)).perform(new AddMarkerAction(mapboxMap, options));
+ onView(withId(R.id.mapView)).perform(new ShowInfoWindowAction(mapboxMap));
+ onView(withText(TestConstants.TEXT_MARKER_TITLE)).check(matches(isDisplayed()));
+ onView(withText(TestConstants.TEXT_MARKER_SNIPPET)).check(matches(isDisplayed()));
+ }
+
+ private class AddMarkerAction implements ViewAction {
+
+ private MapboxMap mapboxMap;
+ private MarkerOptions options;
+
+ AddMarkerAction(MapboxMap map, MarkerOptions markerOptions) {
+ mapboxMap = map;
+ options = markerOptions;
+ }
+
+ @Override
+ public Matcher<View> getConstraints() {
+ return isDisplayed();
+ }
+
+ @Override
+ public String getDescription() {
+ return getClass().getSimpleName();
+ }
+
+ @Override
+ public void perform(UiController uiController, View view) {
+ marker = mapboxMap.addMarker(options);
+ }
+ }
+
+ private class ShowInfoWindowAction implements ViewAction {
+
+ private MapboxMap mapboxMap;
+
+ ShowInfoWindowAction(MapboxMap map) {
+ mapboxMap = map;
+ }
+
+ @Override
+ public Matcher<View> getConstraints() {
+ return isDisplayed();
+ }
+
+ @Override
+ public String getDescription() {
+ return getClass().getSimpleName();
+ }
+
+ @Override
+ public void perform(UiController uiController, View view) {
+ mapboxMap.selectMarker(marker);
+
+ }
+ }
+
+
+ @After
+ public void unregisterIdlingResource() {
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/MarkerViewTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/MarkerViewTest.java
new file mode 100644
index 0000000000..9351ed1c10
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/MarkerViewTest.java
@@ -0,0 +1,147 @@
+package com.mapbox.mapboxsdk.testapp.annotations;
+
+import android.support.test.espresso.Espresso;
+import android.support.test.espresso.UiController;
+import android.support.test.espresso.ViewAction;
+import android.support.test.rule.ActivityTestRule;
+import android.view.View;
+
+import com.mapbox.mapboxsdk.annotations.Marker;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.testapp.R;
+import com.mapbox.mapboxsdk.testapp.activity.annotation.MarkerViewActivity;
+import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity;
+import com.mapbox.mapboxsdk.testapp.model.annotations.TextMarkerViewOptions;
+import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource;
+import com.mapbox.mapboxsdk.testapp.utils.TestConstants;
+import com.mapbox.mapboxsdk.testapp.utils.ViewUtils;
+
+import org.hamcrest.Matcher;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.assertion.ViewAssertions.matches;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static android.support.test.espresso.matcher.ViewMatchers.withText;
+import static org.junit.Assert.assertEquals;
+
+public class MarkerViewTest {
+
+ @Rule
+ public final ActivityTestRule<EspressoTestActivity> rule = new ActivityTestRule<>(EspressoTestActivity.class);
+
+ private OnMapReadyIdlingResource idlingResource;
+ private Marker marker;
+
+ @Before
+ public void registerIdlingResource() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ }
+
+ @Test
+ @Ignore
+ public void addMarkerViewTest() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+ assertEquals("Markers should be empty", 0, mapboxMap.getMarkers().size());
+
+ TextMarkerViewOptions options = new TextMarkerViewOptions();
+ options.text(TestConstants.TEXT_MARKER_TEXT);
+ options.position(new LatLng());
+ options.snippet(TestConstants.TEXT_MARKER_SNIPPET);
+ options.title(TestConstants.TEXT_MARKER_TITLE);
+
+ onView(withId(R.id.mapView)).perform(new AddTextMarkerViewAction(mapboxMap, options));
+ assertEquals("Markers sze should be 1, ", 1, mapboxMap.getMarkers().size());
+ assertEquals("Marker id should be 0", 0, marker.getId());
+ assertEquals("Marker target should match", new LatLng(), marker.getPosition());
+ assertEquals("Marker snippet should match", TestConstants.TEXT_MARKER_SNIPPET, marker.getSnippet());
+ assertEquals("Marker target should match", TestConstants.TEXT_MARKER_TITLE, marker.getTitle());
+ onView(withText(TestConstants.TEXT_MARKER_TEXT)).check(matches(isDisplayed()));
+ }
+
+ @Test
+ @Ignore
+ public void showInfoWindowTest() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ final TextMarkerViewOptions options = new TextMarkerViewOptions();
+ options.position(new LatLng());
+ options.text(TestConstants.TEXT_MARKER_TEXT);
+ options.snippet(TestConstants.TEXT_MARKER_SNIPPET);
+ options.title(TestConstants.TEXT_MARKER_TITLE);
+
+ onView(withId(R.id.mapView)).perform(new AddTextMarkerViewAction(mapboxMap, options));
+ onView(withText(TestConstants.TEXT_MARKER_TEXT)).check(matches(isDisplayed()));
+ onView(withId(R.id.mapView)).perform(new ShowInfoWindowAction(mapboxMap));
+ onView(withText(TestConstants.TEXT_MARKER_TITLE)).check(matches(isDisplayed()));
+ onView(withText(TestConstants.TEXT_MARKER_SNIPPET)).check(matches(isDisplayed()));
+ }
+
+ private class AddTextMarkerViewAction implements ViewAction {
+
+ private MapboxMap mapboxMap;
+ private TextMarkerViewOptions options;
+
+ AddTextMarkerViewAction(MapboxMap map, TextMarkerViewOptions markerOptions) {
+ mapboxMap = map;
+ options = markerOptions;
+ }
+
+ @Override
+ public Matcher<View> getConstraints() {
+ return isDisplayed();
+ }
+
+ @Override
+ public String getDescription() {
+ return getClass().getSimpleName();
+ }
+
+ @Override
+ public void perform(UiController uiController, View view) {
+ mapboxMap.getMarkerViewManager().addMarkerViewAdapter(
+ new MarkerViewActivity.TextAdapter(view.getContext(), mapboxMap));
+ marker = mapboxMap.addMarker(options);
+ uiController.loopMainThreadForAtLeast(250);
+ }
+ }
+
+ private class ShowInfoWindowAction implements ViewAction {
+
+ private MapboxMap mapboxMap;
+
+ ShowInfoWindowAction(MapboxMap map) {
+ mapboxMap = map;
+ }
+
+ @Override
+ public Matcher<View> getConstraints() {
+ return isDisplayed();
+ }
+
+ @Override
+ public String getDescription() {
+ return getClass().getSimpleName();
+ }
+
+ @Override
+ public void perform(UiController uiController, View view) {
+ mapboxMap.selectMarker(marker);
+ uiController.loopMainThreadForAtLeast(250);
+ }
+ }
+
+ @After
+ public void unregisterIdlingResource() {
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/PolygonTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/PolygonTest.java
new file mode 100644
index 0000000000..24b9b3bf01
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/PolygonTest.java
@@ -0,0 +1,105 @@
+package com.mapbox.mapboxsdk.testapp.annotations;
+
+import android.graphics.Color;
+import android.support.test.espresso.Espresso;
+import android.support.test.espresso.UiController;
+import android.support.test.espresso.ViewAction;
+import android.support.test.rule.ActivityTestRule;
+import android.view.View;
+
+import com.mapbox.mapboxsdk.annotations.Polygon;
+import com.mapbox.mapboxsdk.annotations.PolygonOptions;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.testapp.R;
+import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity;
+import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource;
+import com.mapbox.mapboxsdk.testapp.utils.ViewUtils;
+
+import org.hamcrest.Matcher;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static org.junit.Assert.assertEquals;
+
+public class PolygonTest {
+
+ @Rule
+ public final ActivityTestRule<EspressoTestActivity> rule = new ActivityTestRule<>(EspressoTestActivity.class);
+
+ private OnMapReadyIdlingResource idlingResource;
+ private Polygon polygon;
+
+ @Before
+ public void registerIdlingResource() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ }
+
+ @Test
+ @Ignore
+ /** native crash **/
+ public void addPolygonTest() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+ LatLng latLngOne = new LatLng();
+ LatLng latLngTwo = new LatLng(1, 0);
+ LatLng latLngThree = new LatLng(1, 1);
+
+ assertEquals("Polygons should be empty", 0, mapboxMap.getPolygons().size());
+
+ final PolygonOptions options = new PolygonOptions();
+ options.strokeColor(Color.BLUE);
+ options.fillColor(Color.RED);
+ options.add(latLngOne);
+ options.add(latLngTwo);
+ options.add(latLngThree);
+
+ onView(withId(R.id.mapView)).perform(new AddPolygonAction(mapboxMap, options));
+
+ assertEquals("Polygons should be 1", 1, mapboxMap.getPolygons().size());
+ assertEquals("Polygon id should be 0", 0, polygon.getId());
+ assertEquals("Polygon points size should match", 3, polygon.getPoints().size());
+ assertEquals("Polygon stroke color should match", Color.BLUE, polygon.getStrokeColor());
+ assertEquals("Polygon target should match", Color.RED, polygon.getFillColor());
+ mapboxMap.clear();
+ assertEquals("Polygons should be empty", 0, mapboxMap.getPolygons().size());
+ }
+
+ private class AddPolygonAction implements ViewAction {
+
+ private MapboxMap mapboxMap;
+ private PolygonOptions options;
+
+ AddPolygonAction(MapboxMap map, PolygonOptions polygonOptions) {
+ mapboxMap = map;
+ options = polygonOptions;
+ }
+
+ @Override
+ public Matcher<View> getConstraints() {
+ return isDisplayed();
+ }
+
+ @Override
+ public String getDescription() {
+ return getClass().getSimpleName();
+ }
+
+ @Override
+ public void perform(UiController uiController, View view) {
+ polygon = mapboxMap.addPolygon(options);
+ }
+ }
+
+ @After
+ public void unregisterIdlingResource() {
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/PolylineTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/PolylineTest.java
new file mode 100644
index 0000000000..607a4ad263
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/annotations/PolylineTest.java
@@ -0,0 +1,100 @@
+package com.mapbox.mapboxsdk.testapp.annotations;
+
+import android.graphics.Color;
+import android.support.test.espresso.Espresso;
+import android.support.test.espresso.UiController;
+import android.support.test.espresso.ViewAction;
+import android.support.test.rule.ActivityTestRule;
+import android.view.View;
+
+import com.mapbox.mapboxsdk.annotations.Polyline;
+import com.mapbox.mapboxsdk.annotations.PolylineOptions;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.testapp.R;
+import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity;
+import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource;
+import com.mapbox.mapboxsdk.testapp.utils.ViewUtils;
+
+import org.hamcrest.Matcher;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static org.junit.Assert.assertEquals;
+
+public class PolylineTest {
+
+ @Rule
+ public final ActivityTestRule<EspressoTestActivity> rule = new ActivityTestRule<>(EspressoTestActivity.class);
+
+ private OnMapReadyIdlingResource idlingResource;
+ private Polyline polyline;
+
+ @Before
+ public void registerIdlingResource() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ }
+
+ @Ignore
+ @Test
+ public void addPolylineTest() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+ LatLng latLngOne = new LatLng();
+ LatLng latLngTwo = new LatLng(1, 0);
+
+ assertEquals("Polygons should be empty", 0, mapboxMap.getPolygons().size());
+
+ final PolylineOptions options = new PolylineOptions();
+ options.color(Color.BLUE);
+ options.add(latLngOne);
+ options.add(latLngTwo);
+
+ onView(withId(R.id.mapView)).perform(new AddPolyLineAction(mapboxMap, options));
+
+ assertEquals("Polylines should be 1", 1, mapboxMap.getPolylines().size());
+ assertEquals("Polyline id should be 0", 0, polyline.getId());
+ assertEquals("Polyline points size should match", 2, polyline.getPoints().size());
+ assertEquals("Polyline stroke color should match", Color.BLUE, polyline.getColor());
+ mapboxMap.clear();
+ assertEquals("Polyline should be empty", 0, mapboxMap.getPolylines().size());
+ }
+
+ private class AddPolyLineAction implements ViewAction {
+
+ private MapboxMap mapboxMap;
+ private PolylineOptions options;
+
+ AddPolyLineAction(MapboxMap map, PolylineOptions polylineOptions) {
+ mapboxMap = map;
+ options = polylineOptions;
+ }
+
+ @Override
+ public Matcher<View> getConstraints() {
+ return isDisplayed();
+ }
+
+ @Override
+ public String getDescription() {
+ return getClass().getSimpleName();
+ }
+
+ @Override
+ public void perform(UiController uiController, View view) {
+ polyline = mapboxMap.addPolyline(options);
+ }
+ }
+
+ @After
+ public void unregisterIdlingResource() {
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraAnimateTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraAnimateTest.java
new file mode 100644
index 0000000000..5ead54eb7b
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraAnimateTest.java
@@ -0,0 +1,253 @@
+package com.mapbox.mapboxsdk.testapp.camera;
+
+import android.graphics.PointF;
+import android.support.test.espresso.Espresso;
+import android.support.test.espresso.UiController;
+import android.support.test.espresso.ViewAction;
+import android.support.test.rule.ActivityTestRule;
+import android.view.View;
+
+import com.mapbox.mapboxsdk.camera.CameraPosition;
+import com.mapbox.mapboxsdk.camera.CameraUpdate;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.geometry.LatLngBounds;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.testapp.R;
+import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity;
+import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource;
+import com.mapbox.mapboxsdk.testapp.utils.TestConstants;
+import com.mapbox.mapboxsdk.testapp.utils.ViewUtils;
+
+import org.hamcrest.Matcher;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static org.junit.Assert.assertEquals;
+
+public class CameraAnimateTest {
+
+ @Rule
+ public final ActivityTestRule<EspressoTestActivity> rule = new ActivityTestRule<>(EspressoTestActivity.class);
+
+ private OnMapReadyIdlingResource idlingResource;
+
+ @Before
+ public void registerIdlingResource() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ }
+
+ @Test
+ public void testAnimateToCameraPositionTarget() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ /*TODO remove zoom #6474*/
+ float zoom = 1.0f;
+ LatLng moveTarget = new LatLng(1, 1);
+
+ CameraPosition initialPosition = new CameraPosition.Builder().target(
+ new LatLng()).zoom(zoom).bearing(0).tilt(0).build();
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Default camera position should match default", cameraPosition, initialPosition);
+
+ onView(withId(R.id.mapView)).perform(new AnimateCameraAction(mapboxMap, CameraUpdateFactory.newLatLng(moveTarget)));
+ cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(),
+ moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA);
+ assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(),
+ moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA);
+ }
+
+ @Test
+ public void testAnimateToCameraPositionTargetZoom() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ final float moveZoom = 15.5f;
+ final LatLng moveTarget = new LatLng(1.0000000001, 1.0000000003);
+
+ onView(withId(R.id.mapView)).perform(new AnimateCameraAction(mapboxMap,
+ CameraUpdateFactory.newLatLngZoom(moveTarget, moveZoom)));
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(),
+ moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA);
+ assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(),
+ moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA);
+ assertEquals("Moved zoom should match", cameraPosition.zoom, moveZoom, TestConstants.ZOOM_DELTA);
+ }
+
+ @Test
+ public void testAnimateToCameraPosition() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ final LatLng moveTarget = new LatLng(1.0000000001, 1.0000000003);
+ final float moveZoom = 15.5f;
+ final float moveTilt = 45.5f;
+ final float moveBearing = 12.5f;
+
+ onView(withId(R.id.mapView)).perform(
+ new AnimateCameraAction(mapboxMap, CameraUpdateFactory.newCameraPosition(
+ new CameraPosition.Builder()
+ .target(moveTarget)
+ .zoom(moveZoom)
+ .tilt(moveTilt)
+ .bearing(moveBearing)
+ .build()))
+ );
+
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(),
+ moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA);
+ assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(),
+ moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA);
+ assertEquals("Moved zoom should match", cameraPosition.zoom, moveZoom, TestConstants.ZOOM_DELTA);
+ assertEquals("Moved zoom should match", cameraPosition.tilt, moveTilt, TestConstants.TILT_DELTA);
+ assertEquals("Moved bearing should match", cameraPosition.bearing, moveBearing, TestConstants.BEARING_DELTA);
+ }
+
+ @Test
+ public void testAnimateToBounds() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ final LatLng centerBounds = new LatLng(1, 1);
+ LatLng cornerOne = new LatLng();
+ LatLng cornerTwo = new LatLng(2, 2);
+
+ final LatLngBounds.Builder builder = new LatLngBounds.Builder();
+ builder.include(cornerOne);
+ builder.include(cornerTwo);
+
+ onView(withId(R.id.mapView)).perform(new AnimateCameraAction(mapboxMap,
+ CameraUpdateFactory.newLatLngBounds(builder.build(), 0)));
+
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Moved camera position latitude should match center bounds",
+ cameraPosition.target.getLatitude(),
+ centerBounds.getLatitude(),
+ TestConstants.LAT_LNG_DELTA);
+
+ assertEquals("Moved camera position longitude should match center bounds",
+ cameraPosition.target.getLongitude(),
+ centerBounds.getLongitude(),
+ TestConstants.LAT_LNG_DELTA);
+ }
+
+ @Test
+ public void testAnimateToMoveBy() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ final PointF centerPoint = mapboxMap.getProjection().toScreenLocation(mapboxMap.getCameraPosition().target);
+ final LatLng moveTarget = new LatLng(2, 2);
+ final PointF moveTargetPoint = mapboxMap.getProjection().toScreenLocation(moveTarget);
+
+ onView(withId(R.id.mapView)).perform(new AnimateCameraAction(mapboxMap, CameraUpdateFactory.scrollBy(
+ moveTargetPoint.x - centerPoint.x, moveTargetPoint.y - centerPoint.y)));
+
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(),
+ moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA_LARGE);
+ assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(),
+ moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA_LARGE);
+ }
+
+ @Test
+ public void testAnimateToZoomIn() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ /*TODO fix zoom #6474*/
+ float zoom = 1.0f;
+
+ onView(withId(R.id.mapView)).perform(new AnimateCameraAction(mapboxMap, CameraUpdateFactory.zoomIn()));
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoom + 1,
+ TestConstants.ZOOM_DELTA);
+ }
+
+ @Test
+ public void testAnimateToZoomOut() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ /*TODO fix zoom #6474*/
+ float zoom = 10.0f;
+ onView(withId(R.id.mapView)).perform(new AnimateCameraAction(mapboxMap,
+ CameraUpdateFactory.newLatLngZoom(new LatLng(), zoom)));
+ onView(withId(R.id.mapView)).perform(new AnimateCameraAction(mapboxMap, CameraUpdateFactory.zoomOut()));
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoom - 1,
+ TestConstants.ZOOM_DELTA);
+ }
+
+ @Test
+ public void testAnimateToZoomBy() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ /*TODO fix zoom #6474*/
+ float zoom = 1.0f;
+ final float zoomBy = 2.45f;
+
+ onView(withId(R.id.mapView)).perform(new AnimateCameraAction(mapboxMap, CameraUpdateFactory.zoomBy(zoomBy)));
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoom + zoomBy,
+ TestConstants.ZOOM_DELTA);
+ }
+
+ @Test
+ public void testAnimateToZoomTo() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ /*TODO fix zoom #6474*/
+ final float zoomTo = 2.45f;
+
+ onView(withId(R.id.mapView)).perform(new AnimateCameraAction(mapboxMap, CameraUpdateFactory.zoomTo(zoomTo)));
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoomTo,
+ TestConstants.ZOOM_DELTA);
+ }
+
+ @After
+ public void unregisterIdlingResource() {
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
+
+ private class AnimateCameraAction implements ViewAction {
+
+ private MapboxMap mapboxMap;
+ private CameraUpdate cameraUpdate;
+
+ AnimateCameraAction(MapboxMap map, CameraUpdate update) {
+ mapboxMap = map;
+ cameraUpdate = update;
+ }
+
+ @Override
+ public Matcher<View> getConstraints() {
+ return isDisplayed();
+ }
+
+ @Override
+ public String getDescription() {
+ return getClass().getSimpleName();
+ }
+
+ @Override
+ public void perform(UiController uiController, View view) {
+ mapboxMap.animateCamera(cameraUpdate);
+ uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME);
+ }
+ }
+}
+
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraEaseTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraEaseTest.java
new file mode 100644
index 0000000000..22af72cebb
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraEaseTest.java
@@ -0,0 +1,252 @@
+package com.mapbox.mapboxsdk.testapp.camera;
+
+import android.graphics.PointF;
+import android.support.test.espresso.Espresso;
+import android.support.test.espresso.UiController;
+import android.support.test.espresso.ViewAction;
+import android.support.test.rule.ActivityTestRule;
+import android.view.View;
+
+import com.mapbox.mapboxsdk.camera.CameraPosition;
+import com.mapbox.mapboxsdk.camera.CameraUpdate;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.geometry.LatLngBounds;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.testapp.R;
+import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity;
+import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource;
+import com.mapbox.mapboxsdk.testapp.utils.TestConstants;
+import com.mapbox.mapboxsdk.testapp.utils.ViewUtils;
+
+import org.hamcrest.Matcher;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static org.junit.Assert.assertEquals;
+
+public class CameraEaseTest {
+
+ @Rule
+ public final ActivityTestRule<EspressoTestActivity> rule = new ActivityTestRule<>(EspressoTestActivity.class);
+
+ private OnMapReadyIdlingResource idlingResource;
+
+ @Before
+ public void registerIdlingResource() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ }
+
+ @Test
+ public void testEaseToCameraPositionTarget() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ /*TODO remove zoom #6474*/
+ float zoom = 1.0f;
+ LatLng moveTarget = new LatLng(1, 1);
+
+ CameraPosition initialPosition = new CameraPosition.Builder().target(
+ new LatLng()).zoom(zoom).bearing(0).tilt(0).build();
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Default camera position should match default", cameraPosition, initialPosition);
+
+ onView(withId(R.id.mapView)).perform(new EaseCameraAction(mapboxMap, CameraUpdateFactory.newLatLng(moveTarget)));
+ cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(),
+ moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA);
+ assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(),
+ moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA);
+ }
+
+ @Test
+ public void testEaseToCameraPositionTargetZoom() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ final float moveZoom = 15.5f;
+ final LatLng moveTarget = new LatLng(1.0000000001, 1.0000000003);
+
+ onView(withId(R.id.mapView)).perform(new EaseCameraAction(mapboxMap,
+ CameraUpdateFactory.newLatLngZoom(moveTarget, moveZoom)));
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(),
+ moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA);
+ assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(),
+ moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA);
+ assertEquals("Moved zoom should match", cameraPosition.zoom, moveZoom, TestConstants.ZOOM_DELTA);
+ }
+
+ @Test
+ public void testEaseToCameraPosition() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ final LatLng moveTarget = new LatLng(1.0000000001, 1.0000000003);
+ final float moveZoom = 15.5f;
+ final float moveTilt = 45.5f;
+ final float moveBearing = 12.5f;
+
+ onView(withId(R.id.mapView)).perform(
+ new EaseCameraAction(mapboxMap, CameraUpdateFactory.newCameraPosition(
+ new CameraPosition.Builder()
+ .target(moveTarget)
+ .zoom(moveZoom)
+ .tilt(moveTilt)
+ .bearing(moveBearing)
+ .build()))
+ );
+
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(),
+ moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA);
+ assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(),
+ moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA);
+ assertEquals("Moved zoom should match", cameraPosition.zoom, moveZoom, TestConstants.ZOOM_DELTA);
+ assertEquals("Moved zoom should match", cameraPosition.tilt, moveTilt, TestConstants.TILT_DELTA);
+ assertEquals("Moved bearing should match", cameraPosition.bearing, moveBearing, TestConstants.BEARING_DELTA);
+ }
+
+ @Test
+ public void testEaseToBounds() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ final LatLng centerBounds = new LatLng(1, 1);
+ LatLng cornerOne = new LatLng();
+ LatLng cornerTwo = new LatLng(2, 2);
+
+ final LatLngBounds.Builder builder = new LatLngBounds.Builder();
+ builder.include(cornerOne);
+ builder.include(cornerTwo);
+
+ onView(withId(R.id.mapView)).perform(new EaseCameraAction(mapboxMap,
+ CameraUpdateFactory.newLatLngBounds(builder.build(), 0)));
+
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Moved camera position latitude should match center bounds",
+ cameraPosition.target.getLatitude(),
+ centerBounds.getLatitude(),
+ TestConstants.LAT_LNG_DELTA);
+
+ assertEquals("Moved camera position longitude should match center bounds",
+ cameraPosition.target.getLongitude(),
+ centerBounds.getLongitude(),
+ TestConstants.LAT_LNG_DELTA);
+ }
+
+ @Test
+ public void testEaseToMoveBy() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ final PointF centerPoint = mapboxMap.getProjection().toScreenLocation(mapboxMap.getCameraPosition().target);
+ final LatLng moveTarget = new LatLng(2, 2);
+ final PointF moveTargetPoint = mapboxMap.getProjection().toScreenLocation(moveTarget);
+
+ onView(withId(R.id.mapView)).perform(new EaseCameraAction(mapboxMap, CameraUpdateFactory.scrollBy(
+ moveTargetPoint.x - centerPoint.x, moveTargetPoint.y - centerPoint.y)));
+
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(),
+ moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA_LARGE);
+ assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(),
+ moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA_LARGE);
+ }
+
+ @Test
+ public void testEaseToZoomIn() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ /*TODO fix zoom #6474*/
+ float zoom = 1.0f;
+
+ onView(withId(R.id.mapView)).perform(new EaseCameraAction(mapboxMap, CameraUpdateFactory.zoomIn()));
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoom + 1,
+ TestConstants.ZOOM_DELTA);
+ }
+
+ @Test
+ public void testEaseToZoomOut() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ /*TODO fix zoom #6474*/
+ float zoom = 10.0f;
+ onView(withId(R.id.mapView)).perform(new EaseCameraAction(mapboxMap,
+ CameraUpdateFactory.newLatLngZoom(new LatLng(), zoom)));
+ onView(withId(R.id.mapView)).perform(new EaseCameraAction(mapboxMap, CameraUpdateFactory.zoomOut()));
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Moved camera zoom should match moved camera zoom", 9, cameraPosition.zoom, TestConstants.ZOOM_DELTA);
+ }
+
+ @Test
+ public void testEaseToZoomBy() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ /*TODO fix zoom #6474*/
+ float zoom = 1.0f;
+ final float zoomBy = 2.45f;
+
+ onView(withId(R.id.mapView)).perform(new EaseCameraAction(mapboxMap, CameraUpdateFactory.zoomBy(zoomBy)));
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoom + zoomBy,
+ TestConstants.ZOOM_DELTA);
+ }
+
+ @Test
+ public void testEaseToZoomTo() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ /*TODO fix zoom #6474*/
+ final float zoomTo = 2.45f;
+
+ onView(withId(R.id.mapView)).perform(new EaseCameraAction(mapboxMap, CameraUpdateFactory.zoomTo(zoomTo)));
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoomTo,
+ TestConstants.ZOOM_DELTA);
+ }
+
+ @After
+ public void unregisterIdlingResource() {
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
+
+ private class EaseCameraAction implements ViewAction {
+
+ private MapboxMap mapboxMap;
+ private CameraUpdate cameraUpdate;
+
+ EaseCameraAction(MapboxMap map, CameraUpdate update) {
+ mapboxMap = map;
+ cameraUpdate = update;
+ }
+
+ @Override
+ public Matcher<View> getConstraints() {
+ return isDisplayed();
+ }
+
+ @Override
+ public String getDescription() {
+ return getClass().getSimpleName();
+ }
+
+ @Override
+ public void perform(UiController uiController, View view) {
+ mapboxMap.easeCamera(cameraUpdate);
+ uiController.loopMainThreadForAtLeast(TestConstants.ANIMATION_TEST_TIME);
+ }
+ }
+}
+
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraInternalApiTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraInternalApiTest.java
new file mode 100644
index 0000000000..3ca61f7e9d
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraInternalApiTest.java
@@ -0,0 +1,169 @@
+package com.mapbox.mapboxsdk.testapp.camera;
+
+import android.support.test.espresso.Espresso;
+import android.support.test.espresso.UiController;
+import android.support.test.espresso.ViewAction;
+import android.support.test.rule.ActivityTestRule;
+import android.view.View;
+
+import com.mapbox.mapboxsdk.camera.CameraPosition;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.maps.MapViewUtils;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.testapp.R;
+import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity;
+import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource;
+import com.mapbox.mapboxsdk.testapp.utils.TestConstants;
+import com.mapbox.mapboxsdk.testapp.utils.ViewUtils;
+
+import org.hamcrest.Matcher;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Tests camera transformations that aren't part of our public API
+ */
+public class CameraInternalApiTest {
+
+ @Rule
+ public final ActivityTestRule<EspressoTestActivity> rule = new ActivityTestRule<>(EspressoTestActivity.class);
+
+ private OnMapReadyIdlingResource idlingResource;
+
+ @Before
+ public void registerIdlingResource() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ }
+
+ @Test
+ public void testBearing() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ EspressoTestActivity activity = rule.getActivity();
+ MapboxMap mapboxMap = activity.getMapboxMap();
+
+ CameraPosition initialPosition = new
+ CameraPosition.Builder().target(new LatLng()).zoom(1).bearing(0).tilt(0).build();
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Default camera position should match default", cameraPosition, initialPosition);
+
+ onView(withId(R.id.mapView)).perform(new BearingAction(mapboxMap));
+ assertEquals("Bearing should match", 45.1f, MapViewUtils.getDirection(mapboxMap), TestConstants.BEARING_DELTA);
+ }
+
+ @Test
+ public void testTilt() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ EspressoTestActivity activity = rule.getActivity();
+ MapboxMap mapboxMap = activity.getMapboxMap();
+
+ CameraPosition initialPosition = new CameraPosition.Builder().target(
+ new LatLng()).zoom(1).bearing(0).tilt(0).build();
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Default camera position should match default", cameraPosition, initialPosition);
+
+ onView(withId(R.id.mapView)).perform(new TiltAction(mapboxMap));
+ assertEquals("Tilt should match", 40.0f, MapViewUtils.getTilt(mapboxMap), TestConstants.TILT_DELTA);
+ }
+
+ @Test
+ public void testLatLng() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ EspressoTestActivity activity = rule.getActivity();
+ MapboxMap mapboxMap = activity.getMapboxMap();
+
+ CameraPosition initialPosition = new CameraPosition.Builder().target(
+ new LatLng()).zoom(1).bearing(0).tilt(0).build();
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Default camera position should match default", cameraPosition, initialPosition);
+
+ onView(withId(R.id.mapView)).perform(new LatLngAction(mapboxMap));
+ LatLng centerCoordinate = MapViewUtils.getLatLng(mapboxMap);
+ assertEquals("Latitude should match", 1.1f, centerCoordinate.getLatitude(), TestConstants.LAT_LNG_DELTA);
+ assertEquals("Longitude should match", 2.2f, centerCoordinate.getLongitude(), TestConstants.LAT_LNG_DELTA);
+ }
+
+ @After
+ public void unregisterIdlingResource() {
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
+
+ private class BearingAction implements ViewAction {
+
+ private MapboxMap mapboxMap;
+
+ BearingAction(MapboxMap mapboxMap) {
+ this.mapboxMap = mapboxMap;
+ }
+
+ @Override
+ public Matcher<View> getConstraints() {
+ return isDisplayed();
+ }
+
+ @Override
+ public String getDescription() {
+ return getClass().getSimpleName();
+ }
+
+ @Override
+ public void perform(UiController uiController, View view) {
+ MapViewUtils.setDirection(mapboxMap, -45.1f);
+ }
+ }
+
+ private class TiltAction implements ViewAction {
+
+ private MapboxMap mapboxMap;
+
+ TiltAction(MapboxMap mapboxMap) {
+ this.mapboxMap = mapboxMap;
+ }
+
+ @Override
+ public Matcher<View> getConstraints() {
+ return isDisplayed();
+ }
+
+ @Override
+ public String getDescription() {
+ return getClass().getSimpleName();
+ }
+
+ @Override
+ public void perform(UiController uiController, View view) {
+ MapViewUtils.setTilt(mapboxMap, 40.0f);
+ }
+ }
+
+ private class LatLngAction implements ViewAction {
+
+ private MapboxMap mapboxMap;
+
+ LatLngAction(MapboxMap mapboxMap) {
+ this.mapboxMap = mapboxMap;
+ }
+
+ @Override
+ public Matcher<View> getConstraints() {
+ return isDisplayed();
+ }
+
+ @Override
+ public String getDescription() {
+ return getClass().getSimpleName();
+ }
+
+ @Override
+ public void perform(UiController uiController, View view) {
+ MapViewUtils.setLatLng(mapboxMap, new LatLng(1.1, 2.2));
+ }
+ }
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraMoveTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraMoveTest.java
new file mode 100644
index 0000000000..b3a7fe0d11
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/CameraMoveTest.java
@@ -0,0 +1,252 @@
+package com.mapbox.mapboxsdk.testapp.camera;
+
+import android.graphics.PointF;
+import android.support.test.espresso.Espresso;
+import android.support.test.espresso.UiController;
+import android.support.test.espresso.ViewAction;
+import android.support.test.rule.ActivityTestRule;
+import android.view.View;
+
+import com.mapbox.mapboxsdk.camera.CameraPosition;
+import com.mapbox.mapboxsdk.camera.CameraUpdate;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.geometry.LatLngBounds;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.testapp.R;
+import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity;
+import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource;
+import com.mapbox.mapboxsdk.testapp.utils.TestConstants;
+import com.mapbox.mapboxsdk.testapp.utils.ViewUtils;
+
+import org.hamcrest.Matcher;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static org.junit.Assert.assertEquals;
+
+public class CameraMoveTest {
+
+ @Rule
+ public final ActivityTestRule<EspressoTestActivity> rule = new ActivityTestRule<>(EspressoTestActivity.class);
+
+ private OnMapReadyIdlingResource idlingResource;
+
+ @Before
+ public void registerIdlingResource() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ }
+
+ @Test
+ public void testMoveToCameraPositionTarget() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ /*TODO remove zoom #6474*/
+ float zoom = 1.0f;
+ LatLng moveTarget = new LatLng(1, 1);
+
+ CameraPosition initialPosition = new CameraPosition.Builder().target(
+ new LatLng()).zoom(zoom).bearing(0).tilt(0).build();
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Default camera position should match default", cameraPosition, initialPosition);
+
+ onView(withId(R.id.mapView)).perform(new MoveCameraAction(mapboxMap, CameraUpdateFactory.newLatLng(moveTarget)));
+ cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(),
+ moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA);
+ assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(),
+ moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA);
+ }
+
+ @Test
+ public void testMoveToCameraPositionTargetZoom() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ final float moveZoom = 15.5f;
+ final LatLng moveTarget = new LatLng(1.0000000001, 1.0000000003);
+
+ onView(withId(R.id.mapView)).perform(new MoveCameraAction(mapboxMap,
+ CameraUpdateFactory.newLatLngZoom(moveTarget, moveZoom)));
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(),
+ moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA);
+ assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(),
+ moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA);
+ assertEquals("Moved zoom should match", cameraPosition.zoom, moveZoom, TestConstants.ZOOM_DELTA);
+ }
+
+ @Test
+ public void testMoveToCameraPosition() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ final LatLng moveTarget = new LatLng(1.0000000001, 1.0000000003);
+ final float moveZoom = 15.5f;
+ final float moveTilt = 45.5f;
+ final float moveBearing = 12.5f;
+
+ onView(withId(R.id.mapView)).perform(
+ new MoveCameraAction(mapboxMap, CameraUpdateFactory.newCameraPosition(
+ new CameraPosition.Builder()
+ .target(moveTarget)
+ .zoom(moveZoom)
+ .tilt(moveTilt)
+ .bearing(moveBearing)
+ .build()))
+ );
+
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(),
+ moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA);
+ assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(),
+ moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA);
+ assertEquals("Moved zoom should match", cameraPosition.zoom, moveZoom, TestConstants.ZOOM_DELTA);
+ assertEquals("Moved zoom should match", cameraPosition.tilt, moveTilt, TestConstants.TILT_DELTA);
+ assertEquals("Moved bearing should match", cameraPosition.bearing, moveBearing, TestConstants.BEARING_DELTA);
+ }
+
+ @Test
+ public void testMoveToBounds() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ final LatLng centerBounds = new LatLng(1, 1);
+ LatLng cornerOne = new LatLng();
+ LatLng cornerTwo = new LatLng(2, 2);
+
+ final LatLngBounds.Builder builder = new LatLngBounds.Builder();
+ builder.include(cornerOne);
+ builder.include(cornerTwo);
+
+ onView(withId(R.id.mapView)).perform(new MoveCameraAction(mapboxMap,
+ CameraUpdateFactory.newLatLngBounds(builder.build(), 0)));
+
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Moved camera position latitude should match center bounds",
+ cameraPosition.target.getLatitude(),
+ centerBounds.getLatitude(),
+ TestConstants.LAT_LNG_DELTA);
+
+ assertEquals("Moved camera position longitude should match center bounds",
+ cameraPosition.target.getLongitude(),
+ centerBounds.getLongitude(),
+ TestConstants.LAT_LNG_DELTA);
+ }
+
+ @Test
+ public void testMoveToMoveBy() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ final PointF centerPoint = mapboxMap.getProjection().toScreenLocation(mapboxMap.getCameraPosition().target);
+ final LatLng moveTarget = new LatLng(2, 2);
+ final PointF moveTargetPoint = mapboxMap.getProjection().toScreenLocation(moveTarget);
+
+ onView(withId(R.id.mapView)).perform(new MoveCameraAction(mapboxMap, CameraUpdateFactory.scrollBy(
+ moveTargetPoint.x - centerPoint.x, moveTargetPoint.y - centerPoint.y)));
+
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Moved camera position latitude should match", cameraPosition.target.getLatitude(),
+ moveTarget.getLatitude(), TestConstants.LAT_LNG_DELTA_LARGE);
+ assertEquals("Moved camera position longitude should match", cameraPosition.target.getLongitude(),
+ moveTarget.getLongitude(), TestConstants.LAT_LNG_DELTA_LARGE);
+ }
+
+ @Test
+ public void testMoveToZoomIn() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ /*TODO fix zoom #6474*/
+ float zoom = 1.0f;
+
+ onView(withId(R.id.mapView)).perform(new MoveCameraAction(mapboxMap, CameraUpdateFactory.zoomIn()));
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoom + 1,
+ TestConstants.ZOOM_DELTA);
+ }
+
+ @Test
+ public void testMoveToZoomOut() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ /*TODO fix zoom #6474*/
+ float zoom = 10.0f;
+ onView(withId(R.id.mapView)).perform(new MoveCameraAction(mapboxMap,
+ CameraUpdateFactory.newLatLngZoom(new LatLng(), zoom)));
+ onView(withId(R.id.mapView)).perform(new MoveCameraAction(mapboxMap, CameraUpdateFactory.zoomOut()));
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoom - 1,
+ TestConstants.ZOOM_DELTA);
+ }
+
+ @Test
+ public void testMoveToZoomBy() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ /*TODO fix zoom #6474*/
+ float zoom = 1.0f;
+ final float zoomBy = 2.45f;
+
+ onView(withId(R.id.mapView)).perform(new MoveCameraAction(mapboxMap, CameraUpdateFactory.zoomBy(zoomBy)));
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoom + zoomBy,
+ TestConstants.ZOOM_DELTA);
+ }
+
+ @Test
+ public void testMoveToZoomTo() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ final MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ /*TODO fix zoom #6474*/
+ final float zoomTo = 2.45f;
+
+ onView(withId(R.id.mapView)).perform(new MoveCameraAction(mapboxMap, CameraUpdateFactory.zoomTo(zoomTo)));
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Moved camera zoom should match moved camera zoom", cameraPosition.zoom, zoomTo,
+ TestConstants.ZOOM_DELTA);
+ }
+
+ @After
+ public void unregisterIdlingResource() {
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
+
+ private class MoveCameraAction implements ViewAction {
+
+ private MapboxMap mapboxMap;
+ private CameraUpdate cameraUpdate;
+
+ MoveCameraAction(MapboxMap map, CameraUpdate update) {
+ mapboxMap = map;
+ cameraUpdate = update;
+ }
+
+ @Override
+ public Matcher<View> getConstraints() {
+ return isDisplayed();
+ }
+
+ @Override
+ public String getDescription() {
+ return getClass().getSimpleName();
+ }
+
+ @Override
+ public void perform(UiController uiController, View view) {
+ mapboxMap.moveCamera(cameraUpdate);
+ uiController.loopMainThreadForAtLeast(100);
+ }
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/RotateActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/RotateActivityTest.java
deleted file mode 100644
index edef97027e..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/RotateActivityTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package com.mapbox.mapboxsdk.testapp.camera;
-
-import android.support.test.espresso.UiController;
-import android.support.test.espresso.ViewAction;
-import android.view.View;
-
-import com.mapbox.mapboxsdk.maps.MapView;
-import com.mapbox.mapboxsdk.maps.MapboxMapUtils;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.activity.infowindow.InfoWindowActivity;
-
-import org.hamcrest.Matcher;
-import org.junit.Test;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-public class RotateActivityTest extends BaseActivityTest {
-
- @Test
- // longer testing change second param
- public void testRotate() {
- onView(withId(R.id.mapView)).perform(new RotateAction(0, 1));
- }
-
- @Override
- public Class getActivityClass() {
- return InfoWindowActivity.class;
- }
-
- private class RotateAction implements ViewAction {
-
- private float startDegree;
- private float endDegree;
-
- public RotateAction(float startDegree, float endDegree) {
- this.startDegree = startDegree;
- this.endDegree = endDegree;
- }
-
- @Override
- public Matcher<View> getConstraints() {
- return isDisplayed();
- }
-
- @Override
- public String getDescription() {
- return "rotateAction";
- }
-
- @Override
- public void perform(UiController uiController, View view) {
- uiController.loopMainThreadForAtLeast(500);
- for (float i = startDegree; i < endDegree; i++) {
- MapboxMapUtils.setDirection((MapView) view, i);
- uiController.loopMainThreadForAtLeast(1);
- }
- }
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/TiltActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/TiltActivityTest.java
deleted file mode 100644
index 8f21f60fb0..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/TiltActivityTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package com.mapbox.mapboxsdk.testapp.camera;
-
-import android.support.test.espresso.UiController;
-import android.support.test.espresso.ViewAction;
-import android.view.View;
-
-import com.mapbox.mapboxsdk.maps.MapView;
-import com.mapbox.mapboxsdk.maps.MapboxMapUtils;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.activity.annotation.DynamicMarkerChangeActivity;
-
-import org.hamcrest.Matcher;
-import org.junit.Test;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-public class TiltActivityTest extends BaseActivityTest {
-
- @Test
- // longer testing change param
- public void testTilt() {
- onView(withId(R.id.mapView)).perform(new TiltAction(0, 1));
- }
-
- @Override
- public Class getActivityClass() {
- return DynamicMarkerChangeActivity.class;
- }
-
- private class TiltAction implements ViewAction {
-
- private float startDegree;
- private float endDegree;
-
- public TiltAction(float startDegree, float endDegree) {
- this.startDegree = startDegree;
- this.endDegree = endDegree;
- }
-
- @Override
- public Matcher<View> getConstraints() {
- return isDisplayed();
- }
-
- @Override
- public String getDescription() {
- return "tiltAction";
- }
-
- @Override
- public void perform(UiController uiController, View view) {
- uiController.loopMainThreadForAtLeast(500);
- for (float i = startDegree; i < endDegree; i++) {
- MapboxMapUtils.setTilt((MapView) view, i);
- uiController.loopMainThreadForAtLeast(1);
- }
- }
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/ZoomActivityTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/ZoomActivityTest.java
deleted file mode 100644
index 700e8f6c5c..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/camera/ZoomActivityTest.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package com.mapbox.mapboxsdk.testapp.camera;
-
-import android.support.test.espresso.UiController;
-import android.support.test.espresso.ViewAction;
-import android.view.View;
-
-import com.mapbox.mapboxsdk.camera.CameraPosition;
-import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
-import com.mapbox.mapboxsdk.constants.MapboxConstants;
-import com.mapbox.mapboxsdk.geometry.LatLng;
-import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.activity.BaseActivityTest;
-import com.mapbox.mapboxsdk.testapp.activity.maplayout.DebugModeActivity;
-
-import org.hamcrest.Matcher;
-import org.junit.Test;
-
-import static android.support.test.espresso.Espresso.onView;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
-
-public class ZoomActivityTest extends BaseActivityTest {
-
- @Test
- // longer testing increase second param
- public void testZoom() throws Exception {
- onView(withId(R.id.mapView)).perform(new ZoomAction(MapboxConstants.MINIMUM_ZOOM, MapboxConstants.MINIMUM_ZOOM - 1));
- }
-
- @Override
- public Class getActivityClass() {
- return DebugModeActivity.class;
- }
-
- private class ZoomAction implements ViewAction {
-
- private float fromZoom;
- private float toZoom;
-
- public ZoomAction(float fromZoom, float toZoom) {
- this.fromZoom = fromZoom;
- this.toZoom = toZoom;
- }
-
- @Override
- public Matcher<View> getConstraints() {
- return isDisplayed();
- }
-
- @Override
- public String getDescription() {
- return "zoomAction";
- }
-
- @Override
- public void perform(UiController uiController, View view) {
- // move camera above denver
- mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(
- new CameraPosition.Builder()
- .target(new LatLng(39.749750, -104.949559))
- .build()));
-
- uiController.loopMainThreadForAtLeast(500);
-
- for (float i = fromZoom; i < toZoom; i++) {
- mapboxMap.animateCamera(CameraUpdateFactory.zoomTo(i));
- uiController.loopMainThreadForAtLeast(200);
- }
- }
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/feature/QueryRenderedFeaturesBoxCountTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/feature/QueryRenderedFeaturesBoxCountTest.java
new file mode 100644
index 0000000000..b4be73be7a
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/feature/QueryRenderedFeaturesBoxCountTest.java
@@ -0,0 +1,61 @@
+package com.mapbox.mapboxsdk.testapp.feature;
+
+import android.support.test.espresso.Espresso;
+import android.support.test.rule.ActivityTestRule;
+
+import com.mapbox.mapboxsdk.testapp.R;
+import com.mapbox.mapboxsdk.testapp.activity.feature.QueryRenderedFeaturesBoxCountActivity;
+import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.assertion.ViewAssertions.matches;
+import static android.support.test.espresso.matcher.RootMatchers.withDecorView;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static android.support.test.espresso.matcher.ViewMatchers.withText;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+
+/**
+ * Instrumentation test to validate if clicking on the blue rectangle from
+ * QueryRenderedFeaturesBoxSymbolCountActivity shows a Toast that 149 features were found.
+ */
+public class QueryRenderedFeaturesBoxCountTest {
+
+ @Rule
+ public final ActivityTestRule<QueryRenderedFeaturesBoxCountActivity> rule =
+ new ActivityTestRule<>(QueryRenderedFeaturesBoxCountActivity.class);
+
+ private OnMapReadyIdlingResource idlingResource;
+
+ @Before
+ public void registerIdlingResource() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ }
+
+ @Test
+ @Ignore
+ public void testCountFeatures() {
+ // click on box to query map
+ onView(withId(R.id.selection_box)).perform(click());
+
+ // validate if toast is shown
+ onView(withText("149 features in box"))
+ .inRoot(withDecorView(not(is(rule.getActivity().getWindow().getDecorView()))))
+ .check(matches(isDisplayed()));
+ }
+
+ @After
+ public void unregisterIdlingResource() {
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
+
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/feature/QueryRenderedFeaturesHighlightTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/feature/QueryRenderedFeaturesHighlightTest.java
new file mode 100644
index 0000000000..b8cd46e612
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/feature/QueryRenderedFeaturesHighlightTest.java
@@ -0,0 +1,81 @@
+package com.mapbox.mapboxsdk.testapp.feature;
+
+import android.support.test.espresso.Espresso;
+import android.support.test.espresso.ViewAction;
+import android.support.test.espresso.action.CoordinatesProvider;
+import android.support.test.espresso.action.GeneralClickAction;
+import android.support.test.espresso.action.Press;
+import android.support.test.espresso.action.Tap;
+import android.support.test.rule.ActivityTestRule;
+import android.view.View;
+
+import com.mapbox.mapboxsdk.testapp.R;
+import com.mapbox.mapboxsdk.testapp.activity.feature.QueryRenderedFeaturesBoxHighlightActivity;
+import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.assertion.ViewAssertions.matches;
+import static android.support.test.espresso.matcher.RootMatchers.withDecorView;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static android.support.test.espresso.matcher.ViewMatchers.withText;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+
+/**
+ * Instrumentation test to validate if clicking box on screen highlights features.
+ */
+public class QueryRenderedFeaturesHighlightTest {
+
+ @Rule
+ public final ActivityTestRule<QueryRenderedFeaturesBoxHighlightActivity> rule =
+ new ActivityTestRule<>(QueryRenderedFeaturesBoxHighlightActivity.class);
+
+ private OnMapReadyIdlingResource idlingResource;
+
+ @Before
+ public void registerIdlingResource() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ }
+
+ @Test
+ @Ignore
+ public void testCountFeatures() {
+ // click on box to query map
+ onView(withId(R.id.selection_box)).perform(click());
+
+ // validate if toast is shown
+ onView(withText("50 features in box"))
+ .inRoot(withDecorView(not(is(rule.getActivity().getWindow().getDecorView()))))
+ .check(matches(isDisplayed()));
+ }
+
+ @After
+ public void unregisterIdlingResource() {
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
+
+ private static ViewAction clickXY(final float x, final float y) {
+ return new GeneralClickAction(
+ Tap.SINGLE,
+ new CoordinatesProvider() {
+ @Override
+ public float[] calculateCoordinates(View view) {
+ final int[] screenPos = new int[2];
+ view.getLocationOnScreen(screenPos);
+ final float screenX = screenPos[0] + x;
+ final float screenY = screenPos[1] + y;
+ return new float[] {screenX, screenY};
+ }
+ },
+ Press.FINGER);
+ }
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/feature/QueryRenderedFeaturesPropertiesTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/feature/QueryRenderedFeaturesPropertiesTest.java
new file mode 100644
index 0000000000..3b86397603
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/feature/QueryRenderedFeaturesPropertiesTest.java
@@ -0,0 +1,78 @@
+package com.mapbox.mapboxsdk.testapp.feature;
+
+import android.graphics.PointF;
+import android.support.test.espresso.Espresso;
+import android.support.test.espresso.ViewAction;
+import android.support.test.espresso.action.CoordinatesProvider;
+import android.support.test.espresso.action.GeneralClickAction;
+import android.support.test.espresso.action.Press;
+import android.support.test.espresso.action.Tap;
+import android.support.test.rule.ActivityTestRule;
+import android.view.View;
+
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.testapp.R;
+import com.mapbox.mapboxsdk.testapp.activity.feature.QueryRenderedFeaturesPropertiesActivity;
+import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.assertion.ViewAssertions.matches;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static android.support.test.espresso.matcher.ViewMatchers.withText;
+
+/**
+ * Instrumentation test to validate if clicking center of screen returns the correct features.
+ */
+public class QueryRenderedFeaturesPropertiesTest {
+
+ @Rule
+ public final ActivityTestRule<QueryRenderedFeaturesPropertiesActivity> rule =
+ new ActivityTestRule<>(QueryRenderedFeaturesPropertiesActivity.class);
+
+ private OnMapReadyIdlingResource idlingResource;
+
+ @Before
+ public void registerIdlingResource() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ }
+
+ @Test
+ @Ignore
+ public void testCountFeatures() {
+ MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+ LatLng centerScreen = mapboxMap.getCameraPosition().target;
+ PointF centerPixel = mapboxMap.getProjection().toScreenLocation(centerScreen);
+ onView(withId(R.id.mapView)).perform(clickXY(centerPixel.x, centerPixel.y));
+ onView(withText("Found 4 features")).check(matches(isDisplayed()));
+ }
+
+ @After
+ public void unregisterIdlingResource() {
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
+
+ private static ViewAction clickXY(final float x, final float y) {
+ return new GeneralClickAction(
+ Tap.SINGLE,
+ new CoordinatesProvider() {
+ @Override
+ public float[] calculateCoordinates(View view) {
+ final int[] screenPos = new int[2];
+ view.getLocationOnScreen(screenPos);
+ final float screenX = screenPos[0] + x;
+ final float screenY = screenPos[1] + y;
+ return new float[] {screenX, screenY};
+ }
+ },
+ Press.FINGER);
+ }
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/feature/QueryRenderedSymbolBoxCountTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/feature/QueryRenderedSymbolBoxCountTest.java
new file mode 100644
index 0000000000..ea80e8689a
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/feature/QueryRenderedSymbolBoxCountTest.java
@@ -0,0 +1,62 @@
+package com.mapbox.mapboxsdk.testapp.feature;
+
+import android.support.test.espresso.Espresso;
+import android.support.test.rule.ActivityTestRule;
+
+import com.mapbox.mapboxsdk.testapp.R;
+import com.mapbox.mapboxsdk.testapp.activity.feature.QueryRenderedFeaturesBoxSymbolCountActivity;
+import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.assertion.ViewAssertions.matches;
+import static android.support.test.espresso.matcher.RootMatchers.withDecorView;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static android.support.test.espresso.matcher.ViewMatchers.withText;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+
+/**
+ * Instrumentation test to validate if clicking on the blue rectangle from
+ * QueryRenderedFeaturesBoxSymbolCountActivity shows a Toast that 2 symbols were found.
+ */
+public class QueryRenderedSymbolBoxCountTest {
+
+ @Rule
+ public final ActivityTestRule<QueryRenderedFeaturesBoxSymbolCountActivity> rule =
+ new ActivityTestRule<>(QueryRenderedFeaturesBoxSymbolCountActivity.class);
+
+ private OnMapReadyIdlingResource idlingResource;
+
+ @Before
+ public void registerIdlingResource() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ }
+
+ @Test
+ @Ignore
+ public void testCountSymbols() {
+ // click on box to query map
+ onView(withId(R.id.selection_box)).perform(click());
+
+ // validate if toast is shown
+ onView(withText("2 features in box"))
+ .inRoot(withDecorView(not(is(rule.getActivity().getWindow().getDecorView()))))
+ .check(matches(isDisplayed()));
+ }
+
+ @After
+ public void unregisterIdlingResource() {
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
+
+}
+
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/AttributionTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/AttributionTest.java
new file mode 100644
index 0000000000..fa1451092a
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/AttributionTest.java
@@ -0,0 +1,156 @@
+package com.mapbox.mapboxsdk.testapp.maps.widgets;
+
+import android.app.Instrumentation;
+import android.content.Intent;
+import android.net.Uri;
+import android.support.test.espresso.Espresso;
+import android.support.test.espresso.UiController;
+import android.support.test.espresso.ViewAction;
+import android.support.test.espresso.intent.Intents;
+import android.support.test.rule.ActivityTestRule;
+import android.view.View;
+
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.testapp.R;
+import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity;
+import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource;
+import com.mapbox.mapboxsdk.testapp.utils.ViewUtils;
+
+import org.hamcrest.Matcher;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.assertion.ViewAssertions.matches;
+import static android.support.test.espresso.intent.Intents.intended;
+import static android.support.test.espresso.intent.Intents.intending;
+import static android.support.test.espresso.intent.matcher.IntentMatchers.hasAction;
+import static android.support.test.espresso.intent.matcher.IntentMatchers.hasData;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static android.support.test.espresso.matcher.ViewMatchers.withText;
+import static org.hamcrest.Matchers.allOf;
+import static org.hamcrest.core.IsNot.not;
+
+public class AttributionTest {
+
+ @Rule
+ public final ActivityTestRule<EspressoTestActivity> rule = new ActivityTestRule<>(EspressoTestActivity.class);
+
+ private OnMapReadyIdlingResource idlingResource;
+
+ private String[] dialogTexts;
+ private String[] dialogLinks;
+
+ @Before
+ public void beforeTest() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ Intents.init();
+ dialogTexts = rule.getActivity().getResources().getStringArray(R.array.mapbox_attribution_names);
+ dialogLinks = rule.getActivity().getResources().getStringArray(R.array.mapbox_attribution_links);
+ }
+
+ @Test
+ public void testDisabled() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ // Default
+ onView(withId(R.id.attributionView)).check(matches(isDisplayed()));
+
+ // Disabled
+ onView(withId(R.id.attributionView))
+ .perform(new DisableAction(mapboxMap))
+ .check(matches(not(isDisplayed())));
+ }
+
+ @Test
+ public void testMapboxLink() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+
+ // click on View to open dialog
+ onView(withId(R.id.attributionView)).perform(click());
+ onView(withText(R.string.mapbox_attributionsDialogTitle)).check(matches(isDisplayed()));
+
+ // click on link and validate browser opening
+ Matcher<Intent> expectedIntent = allOf(hasAction(Intent.ACTION_VIEW), hasData(Uri.parse(dialogLinks[0])));
+ intending(expectedIntent).respondWith(new Instrumentation.ActivityResult(0, null));
+ onView(withText(dialogTexts[0])).perform(click());
+ intended(expectedIntent);
+ }
+
+ @Test
+ public void testOpenStreetMapLink() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+
+ // click on View to open dialog
+ onView(withId(R.id.attributionView)).perform(click());
+ onView(withText(R.string.mapbox_attributionsDialogTitle)).check(matches(isDisplayed()));
+
+ // click on link and validate browser opening
+ Matcher<Intent> expectedIntent = allOf(hasAction(Intent.ACTION_VIEW), hasData(Uri.parse(dialogLinks[1])));
+ intending(expectedIntent).respondWith(new Instrumentation.ActivityResult(0, null));
+ onView(withText(dialogTexts[1])).perform(click());
+ }
+
+ @Test
+ public void testImproveMapLink() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+
+ // click on View to open dialog
+ onView(withId(R.id.attributionView)).perform(click());
+ onView(withText(R.string.mapbox_attributionsDialogTitle)).check(matches(isDisplayed()));
+
+ // click on Mapbox link and validate browser opening
+ Matcher<Intent> expectedIntent = allOf(hasAction(Intent.ACTION_VIEW), hasData(Uri.parse(dialogLinks[3])));
+ intending(expectedIntent).respondWith(new Instrumentation.ActivityResult(0, null));
+ onView(withText(dialogTexts[3])).perform(click());
+ }
+
+ @Test
+ public void testTelemetryDialog() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+
+ // click on View to open dialog
+ onView(withId(R.id.attributionView)).perform(click());
+ onView(withText(R.string.mapbox_attributionsDialogTitle)).check(matches(isDisplayed()));
+
+ // click on item to open second dialog
+ onView(withText(dialogTexts[3])).perform(click());
+ onView(withText(R.string.mapbox_attributionTelemetryTitle)).check(matches(isDisplayed()));
+ }
+
+ @After
+ public void afterTest() {
+ Intents.release();
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
+
+ private class DisableAction implements ViewAction {
+
+ private MapboxMap mapboxMap;
+
+ DisableAction(MapboxMap map) {
+ mapboxMap = map;
+ }
+
+ @Override
+ public Matcher<View> getConstraints() {
+ return isDisplayed();
+ }
+
+ @Override
+ public String getDescription() {
+ return getClass().getSimpleName();
+ }
+
+ @Override
+ public void perform(UiController uiController, View view) {
+ mapboxMap.getUiSettings().setAttributionEnabled(false);
+ }
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/CompassViewTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/CompassViewTest.java
new file mode 100644
index 0000000000..02fec41f65
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/CompassViewTest.java
@@ -0,0 +1,153 @@
+package com.mapbox.mapboxsdk.testapp.maps.widgets;
+
+import android.support.test.espresso.Espresso;
+import android.support.test.espresso.UiController;
+import android.support.test.espresso.ViewAction;
+import android.support.test.rule.ActivityTestRule;
+import android.view.View;
+
+import com.mapbox.mapboxsdk.camera.CameraPosition;
+import com.mapbox.mapboxsdk.camera.CameraUpdate;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.testapp.R;
+import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity;
+import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource;
+import com.mapbox.mapboxsdk.testapp.utils.TestConstants;
+import com.mapbox.mapboxsdk.testapp.utils.ViewUtils;
+
+import org.hamcrest.Matcher;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.assertion.ViewAssertions.matches;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertEquals;
+
+public class CompassViewTest {
+
+ @Rule
+ public final ActivityTestRule<EspressoTestActivity> rule = new ActivityTestRule<>(EspressoTestActivity.class);
+
+ private OnMapReadyIdlingResource idlingResource;
+
+ @Before
+ public void registerIdlingResource() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ }
+
+ @Test
+ public void testDefault() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ onView(withId(R.id.compassView)).check(matches(not(isDisplayed())));
+ }
+
+ @Test
+ public void testVisible() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ onView(withId(R.id.mapView)).perform(new MoveCameraAction(mapboxMap,
+ CameraUpdateFactory.newCameraPosition(
+ new CameraPosition.Builder()
+ .bearing(45)
+ .zoom(1)
+ .target(new LatLng())
+ .build()
+ )
+ )
+ );
+
+ onView(withId(R.id.compassView)).check(matches(isDisplayed()));
+ }
+
+ @Test
+ @Ignore // 10-31-2016 click action is not working
+ public void testClick() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ onView(withId(R.id.mapView)).perform(new MoveCameraAction(mapboxMap,
+ CameraUpdateFactory.newCameraPosition(
+ new CameraPosition.Builder()
+ .bearing(45)
+ .zoom(1)
+ .target(new LatLng())
+ .build()
+ )
+ )
+ );
+
+ onView(withId(R.id.compassView)).perform(click());
+ onView(withId(R.id.mapView)).perform(new WaitAction(3000));
+ onView(withId(R.id.compassView)).check(matches(not(isDisplayed())));
+
+ CameraPosition cameraPosition = mapboxMap.getCameraPosition();
+ assertEquals("Camera bearing should face north, ", 0, cameraPosition.bearing, TestConstants.BEARING_DELTA);
+ }
+
+ @After
+ public void unregisterIdlingResource() {
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
+
+ private class WaitAction implements ViewAction {
+
+ private long waitTime;
+
+ WaitAction(long waitTime) {
+ this.waitTime = waitTime;
+ }
+
+ @Override
+ public Matcher<View> getConstraints() {
+ return isDisplayed();
+ }
+
+ @Override
+ public String getDescription() {
+ return getClass().getSimpleName();
+ }
+
+ @Override
+ public void perform(UiController uiController, View view) {
+ uiController.loopMainThreadForAtLeast(waitTime);
+ }
+ }
+
+ private class MoveCameraAction implements ViewAction {
+
+ private MapboxMap mapboxMap;
+ private CameraUpdate cameraUpdate;
+
+ MoveCameraAction(MapboxMap map, CameraUpdate update) {
+ mapboxMap = map;
+ cameraUpdate = update;
+ }
+
+ @Override
+ public Matcher<View> getConstraints() {
+ return isDisplayed();
+ }
+
+ @Override
+ public String getDescription() {
+ return getClass().getSimpleName();
+ }
+
+ @Override
+ public void perform(UiController uiController, View view) {
+ mapboxMap.moveCamera(cameraUpdate);
+ }
+ }
+}
+
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/LogoTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/LogoTest.java
new file mode 100644
index 0000000000..f12b2bf160
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/LogoTest.java
@@ -0,0 +1,84 @@
+package com.mapbox.mapboxsdk.testapp.maps.widgets;
+
+import android.support.test.espresso.Espresso;
+import android.support.test.espresso.UiController;
+import android.support.test.espresso.ViewAction;
+import android.support.test.rule.ActivityTestRule;
+import android.view.View;
+
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.testapp.R;
+import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity;
+import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource;
+import com.mapbox.mapboxsdk.testapp.utils.ViewUtils;
+
+import org.hamcrest.Matcher;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.assertion.ViewAssertions.matches;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static org.hamcrest.Matchers.not;
+
+public class LogoTest {
+
+ @Rule
+ public final ActivityTestRule<EspressoTestActivity> rule = new ActivityTestRule<>(EspressoTestActivity.class);
+
+ private OnMapReadyIdlingResource idlingResource;
+
+ @Before
+ public void registerIdlingResource() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ }
+
+ @Test
+ public void testDefault() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ onView(withId(R.id.logoView)).check(matches(isDisplayed()));
+ }
+
+ @Test
+ public void testDisabled() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ onView(withId(R.id.logoView))
+ .perform(new DisableAction(mapboxMap))
+ .check(matches(not(isDisplayed())));
+ }
+
+ @After
+ public void unregisterIdlingResource() {
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
+
+ private class DisableAction implements ViewAction {
+
+ private MapboxMap mapboxMap;
+
+ DisableAction(MapboxMap map) {
+ mapboxMap = map;
+ }
+
+ @Override
+ public Matcher<View> getConstraints() {
+ return isDisplayed();
+ }
+
+ @Override
+ public String getDescription() {
+ return getClass().getSimpleName();
+ }
+
+ @Override
+ public void perform(UiController uiController, View view) {
+ mapboxMap.getUiSettings().setLogoEnabled(false);
+ }
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/MyLocationViewTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/MyLocationViewTest.java
new file mode 100644
index 0000000000..ac10d11922
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/MyLocationViewTest.java
@@ -0,0 +1,246 @@
+package com.mapbox.mapboxsdk.testapp.maps.widgets;
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.support.test.espresso.Espresso;
+import android.support.test.espresso.UiController;
+import android.support.test.espresso.ViewAction;
+import android.support.test.rule.ActivityTestRule;
+import android.view.View;
+
+import com.mapbox.mapboxsdk.camera.CameraPosition;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
+import com.mapbox.mapboxsdk.constants.MyBearingTracking;
+import com.mapbox.mapboxsdk.constants.MyLocationTracking;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.location.LocationServices;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.maps.widgets.MyLocationView;
+import com.mapbox.mapboxsdk.testapp.R;
+import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity;
+import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource;
+import com.mapbox.mapboxsdk.testapp.utils.ViewUtils;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.assertion.ViewAssertions.matches;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static org.hamcrest.Matchers.not;
+
+/**
+ * Experimental MyLocationView tests,
+ * requires application to be granted with runtime location permissions.
+ * <p>
+ * Tests for enabling and disabling the {@link MyLocationView}.
+ * Tests for enabling tracking modes and if the correct default images are shown when toggling
+ * {@link com.mapbox.mapboxsdk.maps.TrackingSettings#setMyLocationTrackingMode(int)} &
+ * {@link com.mapbox.mapboxsdk.maps.TrackingSettings#setMyBearingTrackingMode(int)}.
+ * </p>
+ */
+public class MyLocationViewTest {
+
+ @Rule
+ public final ActivityTestRule<EspressoTestActivity> rule = new ActivityTestRule<>(EspressoTestActivity.class);
+
+ private OnMapReadyIdlingResource idlingResource;
+
+ @Before
+ public void beforeTest() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ }
+
+ @Test
+ @Ignore // requires runtime permissions, disabled for CI
+ public void testEnabled() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+ onView(withId(R.id.userLocationView)).check(matches(not(isDisplayed())));
+ onView(withId(R.id.mapView)).perform(new ToggleLocationAction(mapboxMap, true));
+ onView(withId(R.id.userLocationView)).check(matches(isDisplayed()));
+ onView(withId(R.id.mapView)).perform(new ToggleLocationAction(mapboxMap, false));
+ onView(withId(R.id.userLocationView)).check(matches(not(isDisplayed())));
+ }
+
+ @Test
+ @Ignore
+ // requires runtime permissions, disabled for CI + issue with android.support.test.espresso.AppNotIdleException:
+ // Looped for 5049 iterations over 60 SECONDS.
+ public void testTracking() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+ onView(withId(R.id.userLocationView)).check(matches(not(isDisplayed())));
+ onView(withId(R.id.mapView)).perform(new EnableLocationTrackingAction(mapboxMap));
+ onView(withId(R.id.userLocationView)).check(matches(isDisplayed()));
+ onView(withId(R.id.userLocationView)).check(matches(new DrawableMatcher(mapboxMap,
+ R.drawable.mapbox_mylocation_icon_default, false)));
+ onView(withId(R.id.mapView)).perform(new EnableCompassBearingTrackingAction(mapboxMap));
+ onView(withId(R.id.userLocationView)).check(matches(new DrawableMatcher(mapboxMap,
+ R.drawable.mapbox_mylocation_icon_bearing, true)));
+ }
+
+ @After
+ public void afterTest() {
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
+
+ private class ToggleLocationAction implements ViewAction {
+
+ private MapboxMap mapboxMap;
+ private boolean isEnabled;
+
+ ToggleLocationAction(MapboxMap map, boolean enable) {
+ mapboxMap = map;
+ isEnabled = enable;
+ }
+
+ @Override
+ public Matcher<View> getConstraints() {
+ return isDisplayed();
+ }
+
+ @Override
+ public String getDescription() {
+ return getClass().getSimpleName();
+ }
+
+ @Override
+ public void perform(UiController uiController, View view) {
+ if (isEnabled) {
+ // move camera above user location
+ mapboxMap.moveCamera(
+ CameraUpdateFactory.newCameraPosition(
+ new CameraPosition.Builder()
+ .target(new LatLng(LocationServices.getLocationServices(view.getContext()).getLastLocation()))
+ .build()
+ )
+ );
+ }
+
+ // show loction on screen
+ mapboxMap.setMyLocationEnabled(isEnabled);
+ }
+ }
+
+ private class EnableLocationTrackingAction implements ViewAction {
+
+ private MapboxMap mapboxMap;
+
+ EnableLocationTrackingAction(MapboxMap map) {
+ mapboxMap = map;
+ }
+
+ @Override
+ public Matcher<View> getConstraints() {
+ return isDisplayed();
+ }
+
+ @Override
+ public String getDescription() {
+ return getClass().getSimpleName();
+ }
+
+ @Override
+ public void perform(UiController uiController, View view) {
+ mapboxMap.getTrackingSettings().setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW);
+ }
+ }
+
+ private class EnableCompassBearingTrackingAction implements ViewAction {
+
+ private MapboxMap mapboxMap;
+
+ EnableCompassBearingTrackingAction(MapboxMap map) {
+ mapboxMap = map;
+ }
+
+ @Override
+ public Matcher<View> getConstraints() {
+ return isDisplayed();
+ }
+
+ @Override
+ public String getDescription() {
+ return getClass().getSimpleName();
+ }
+
+ @Override
+ public void perform(UiController uiController, View view) {
+ mapboxMap.getTrackingSettings().setMyBearingTrackingMode(MyBearingTracking.COMPASS);
+ // wait for next compass update cycle
+ uiController.loopMainThreadForAtLeast(500);
+ }
+ }
+
+ private class DrawableMatcher extends TypeSafeMatcher<View> {
+
+ private MapboxMap mapboxMap;
+ private boolean isBearingDrawable;
+ private final int expectedId;
+
+ DrawableMatcher(MapboxMap mapboxMap, int expectedId, boolean isBearingDrawable) {
+ super(MyLocationView.class);
+ this.mapboxMap = mapboxMap;
+ this.expectedId = expectedId;
+ this.isBearingDrawable = isBearingDrawable;
+ }
+
+ @Override
+ protected boolean matchesSafely(View target) {
+ Drawable currentDrawable = isBearingDrawable
+ ? mapboxMap.getMyLocationViewSettings().getForegroundBearingDrawable() :
+ mapboxMap.getMyLocationViewSettings().getForegroundDrawable();
+
+ Resources resources = target.getContext().getResources();
+ Drawable expectedDrawable = resources.getDrawable(expectedId);
+ return areDrawablesIdentical(currentDrawable, expectedDrawable);
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("trying to match MyLocationView drawable to " + expectedId);
+ }
+
+ boolean areDrawablesIdentical(Drawable drawableA, Drawable drawableB) {
+ Drawable.ConstantState stateA = drawableA.getConstantState();
+ Drawable.ConstantState stateB = drawableB.getConstantState();
+ return (stateA != null && stateB != null && stateA.equals(stateB))
+ || getBitmap(drawableA).sameAs(getBitmap(drawableB));
+ }
+
+ Bitmap getBitmap(Drawable drawable) {
+ Bitmap result;
+ if (drawable instanceof BitmapDrawable) {
+ result = ((BitmapDrawable) drawable).getBitmap();
+ } else {
+ int width = drawable.getIntrinsicWidth();
+ int height = drawable.getIntrinsicHeight();
+ // Some drawables have no intrinsic width - e.g. solid colours.
+ if (width <= 0) {
+ width = 1;
+ }
+ if (height <= 0) {
+ height = 1;
+ }
+
+ result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(result);
+ drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
+ drawable.draw(canvas);
+ }
+ return result;
+ }
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BackgroundLayerStyleTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BackgroundLayerStyleTest.java
index d4c00c5f05..68ed5cb05d 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BackgroundLayerStyleTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BackgroundLayerStyleTest.java
@@ -1,11 +1,10 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
package com.mapbox.mapboxsdk.testapp.style;
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
import android.graphics.Color;
import android.support.test.espresso.Espresso;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
-import android.util.Log;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.style.layers.BackgroundLayer;
@@ -19,118 +18,124 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import static org.junit.Assert.*;
-import static com.mapbox.mapboxsdk.style.layers.Property.*;
-import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*;
+import timber.log.Timber;
+
+import static com.mapbox.mapboxsdk.style.layers.Property.NONE;
+import static com.mapbox.mapboxsdk.style.layers.Property.VISIBLE;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.backgroundColor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.backgroundOpacity;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.backgroundPattern;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.visibility;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
/**
* Basic smoke tests for BackgroundLayer
*/
@RunWith(AndroidJUnit4.class)
public class BackgroundLayerStyleTest extends BaseStyleTest {
- private static final String TAG = BackgroundLayerStyleTest.class.getSimpleName();
- @Rule
- public final ActivityTestRule<RuntimeStyleTestActivity> rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class);
+ @Rule
+ public final ActivityTestRule<RuntimeStyleTestActivity> rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class);
- private BackgroundLayer layer;
+ private BackgroundLayer layer;
- private OnMapReadyIdlingResource idlingResource;
+ private OnMapReadyIdlingResource idlingResource;
- private MapboxMap mapboxMap;
+ private MapboxMap mapboxMap;
- @Before
- public void setup() {
- idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
- Espresso.registerIdlingResources(idlingResource);
- }
+ @Before
+ public void setup() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ }
- @Test
- public void testSetVisibility() {
- checkViewIsDisplayed(R.id.mapView);
+ @Test
+ public void testSetVisibility() {
+ checkViewIsDisplayed(R.id.mapView);
- mapboxMap = rule.getActivity().getMapboxMap();
+ mapboxMap = rule.getActivity().getMapboxMap();
- Log.i(TAG, "Retrieving layer");
- layer = mapboxMap.getLayerAs("background");
- Log.i(TAG, "visibility");
- assertNotNull(layer);
+ Timber.i("Retrieving layer");
+ layer = mapboxMap.getLayerAs("background");
+ Timber.i("visibility");
+ assertNotNull(layer);
- //Get initial
- assertEquals(layer.getVisibility().getValue(), VISIBLE);
+ //Get initial
+ assertEquals(layer.getVisibility().getValue(), VISIBLE);
- //Set
- layer.setProperties(visibility(NONE));
- assertEquals(layer.getVisibility().getValue(), NONE);
- }
+ //Set
+ layer.setProperties(visibility(NONE));
+ assertEquals(layer.getVisibility().getValue(), NONE);
+ }
- @Test
- public void testBackgroundColor() {
- checkViewIsDisplayed(R.id.mapView);
+ @Test
+ public void testBackgroundColor() {
+ checkViewIsDisplayed(R.id.mapView);
- mapboxMap = rule.getActivity().getMapboxMap();
+ mapboxMap = rule.getActivity().getMapboxMap();
- Log.i(TAG, "Retrieving layer");
- layer = mapboxMap.getLayerAs("background");
- Log.i(TAG, "background-color");
- assertNotNull(layer);
+ Timber.i("Retrieving layer");
+ layer = mapboxMap.getLayerAs("background");
+ Timber.i("background-color");
+ assertNotNull(layer);
- //Set and Get
- layer.setProperties(backgroundColor("rgba(0, 0, 0, 1)"));
- assertEquals((String) layer.getBackgroundColor().getValue(), (String) "rgba(0, 0, 0, 1)");
- }
+ //Set and Get
+ layer.setProperties(backgroundColor("rgba(0, 0, 0, 1)"));
+ assertEquals((String) layer.getBackgroundColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ }
- @Test
- public void testBackgroundColorAsInt() {
- checkViewIsDisplayed(R.id.mapView);
+ @Test
+ public void testBackgroundColorAsInt() {
+ checkViewIsDisplayed(R.id.mapView);
- mapboxMap = rule.getActivity().getMapboxMap();
+ mapboxMap = rule.getActivity().getMapboxMap();
- Log.i(TAG, "Retrieving layer");
- layer = mapboxMap.getLayerAs("background");
- Log.i(TAG, "background-color");
- assertNotNull(layer);
+ Timber.i("Retrieving layer");
+ layer = mapboxMap.getLayerAs("background");
+ Timber.i("background-color");
+ assertNotNull(layer);
- //Set and Get
- layer.setProperties(backgroundColor(Color.RED));
- assertEquals(layer.getBackgroundColorAsInt(), Color.RED);
- }
+ //Set and Get
+ layer.setProperties(backgroundColor(Color.RED));
+ assertEquals(layer.getBackgroundColorAsInt(), Color.RED);
+ }
- @Test
- public void testBackgroundPattern() {
- checkViewIsDisplayed(R.id.mapView);
+ @Test
+ public void testBackgroundPattern() {
+ checkViewIsDisplayed(R.id.mapView);
- mapboxMap = rule.getActivity().getMapboxMap();
+ mapboxMap = rule.getActivity().getMapboxMap();
- Log.i(TAG, "Retrieving layer");
- layer = mapboxMap.getLayerAs("background");
- Log.i(TAG, "background-pattern");
- assertNotNull(layer);
+ Timber.i("Retrieving layer");
+ layer = mapboxMap.getLayerAs("background");
+ Timber.i("background-pattern");
+ assertNotNull(layer);
- //Set and Get
- layer.setProperties(backgroundPattern("pedestrian-polygon"));
- assertEquals((String) layer.getBackgroundPattern().getValue(), (String) "pedestrian-polygon");
- }
+ //Set and Get
+ layer.setProperties(backgroundPattern("pedestrian-polygon"));
+ assertEquals((String) layer.getBackgroundPattern().getValue(), (String) "pedestrian-polygon");
+ }
- @Test
- public void testBackgroundOpacity() {
- checkViewIsDisplayed(R.id.mapView);
+ @Test
+ public void testBackgroundOpacity() {
+ checkViewIsDisplayed(R.id.mapView);
- mapboxMap = rule.getActivity().getMapboxMap();
+ mapboxMap = rule.getActivity().getMapboxMap();
- Log.i(TAG, "Retrieving layer");
- layer = mapboxMap.getLayerAs("background");
- Log.i(TAG, "background-opacity");
- assertNotNull(layer);
+ Timber.i("Retrieving layer");
+ layer = mapboxMap.getLayerAs("background");
+ Timber.i("background-opacity");
+ assertNotNull(layer);
- //Set and Get
- layer.setProperties(backgroundOpacity(0.3f));
- assertEquals((Float) layer.getBackgroundOpacity().getValue(), (Float) 0.3f);
- }
+ //Set and Get
+ layer.setProperties(backgroundOpacity(0.3f));
+ assertEquals((Float) layer.getBackgroundOpacity().getValue(), (Float) 0.3f);
+ }
- @After
- public void unregisterIntentServiceIdlingResource() {
- Espresso.unregisterIdlingResources(idlingResource);
- }
+ @After
+ public void unregisterIntentServiceIdlingResource() {
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BackgroundLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BackgroundLayerTest.java
index b56c8f648f..ab53ae0487 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BackgroundLayerTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BackgroundLayerTest.java
@@ -1,11 +1,10 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
package com.mapbox.mapboxsdk.testapp.style;
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
import android.graphics.Color;
import android.support.test.espresso.Espresso;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
-import android.util.Log;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.style.layers.BackgroundLayer;
@@ -19,118 +18,124 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import static org.junit.Assert.*;
-import static com.mapbox.mapboxsdk.style.layers.Property.*;
-import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*;
+import timber.log.Timber;
+
+import static com.mapbox.mapboxsdk.style.layers.Property.NONE;
+import static com.mapbox.mapboxsdk.style.layers.Property.VISIBLE;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.backgroundColor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.backgroundOpacity;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.backgroundPattern;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.visibility;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
/**
* Basic smoke tests for BackgroundLayer
*/
@RunWith(AndroidJUnit4.class)
public class BackgroundLayerTest extends BaseStyleTest {
- private static final String TAG = BackgroundLayerTest.class.getSimpleName();
- @Rule
- public final ActivityTestRule<RuntimeStyleTestActivity> rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class);
+ @Rule
+ public final ActivityTestRule<RuntimeStyleTestActivity> rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class);
- private BackgroundLayer layer;
+ private BackgroundLayer layer;
- private OnMapReadyIdlingResource idlingResource;
+ private OnMapReadyIdlingResource idlingResource;
- private MapboxMap mapboxMap;
+ private MapboxMap mapboxMap;
- @Before
- public void setup() {
- idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
- Espresso.registerIdlingResources(idlingResource);
- }
+ @Before
+ public void setup() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ }
- @Test
- public void testSetVisibility() {
- checkViewIsDisplayed(R.id.mapView);
+ @Test
+ public void testSetVisibility() {
+ checkViewIsDisplayed(R.id.mapView);
- mapboxMap = rule.getActivity().getMapboxMap();
+ mapboxMap = rule.getActivity().getMapboxMap();
- Log.i(TAG, "Retrieving layer");
- layer = mapboxMap.getLayerAs("background");
- Log.i(TAG, "visibility");
- assertNotNull(layer);
+ Timber.i("Retrieving layer");
+ layer = mapboxMap.getLayerAs("background");
+ Timber.i("visibility");
+ assertNotNull(layer);
- //Get initial
- assertEquals(layer.getVisibility().getValue(), VISIBLE);
+ //Get initial
+ assertEquals(layer.getVisibility().getValue(), VISIBLE);
- //Set
- layer.setProperties(visibility(NONE));
- assertEquals(layer.getVisibility().getValue(), NONE);
- }
+ //Set
+ layer.setProperties(visibility(NONE));
+ assertEquals(layer.getVisibility().getValue(), NONE);
+ }
- @Test
- public void testBackgroundColor() {
- checkViewIsDisplayed(R.id.mapView);
+ @Test
+ public void testBackgroundColor() {
+ checkViewIsDisplayed(R.id.mapView);
- mapboxMap = rule.getActivity().getMapboxMap();
+ mapboxMap = rule.getActivity().getMapboxMap();
- Log.i(TAG, "Retrieving layer");
- layer = mapboxMap.getLayerAs("background");
- Log.i(TAG, "background-color");
- assertNotNull(layer);
+ Timber.i("Retrieving layer");
+ layer = mapboxMap.getLayerAs("background");
+ Timber.i("background-color");
+ assertNotNull(layer);
- //Set and Get
- layer.setProperties(backgroundColor("rgba(0, 0, 0, 1)"));
- assertEquals((String) layer.getBackgroundColor().getValue(), (String) "rgba(0, 0, 0, 1)");
- }
+ //Set and Get
+ layer.setProperties(backgroundColor("rgba(0, 0, 0, 1)"));
+ assertEquals((String) layer.getBackgroundColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ }
- @Test
- public void testBackgroundColorAsInt() {
- checkViewIsDisplayed(R.id.mapView);
+ @Test
+ public void testBackgroundColorAsInt() {
+ checkViewIsDisplayed(R.id.mapView);
- mapboxMap = rule.getActivity().getMapboxMap();
+ mapboxMap = rule.getActivity().getMapboxMap();
- Log.i(TAG, "Retrieving layer");
- layer = mapboxMap.getLayerAs("background");
- Log.i(TAG, "background-color");
- assertNotNull(layer);
+ Timber.i("Retrieving layer");
+ layer = mapboxMap.getLayerAs("background");
+ Timber.i("background-color");
+ assertNotNull(layer);
- //Set and Get
- layer.setProperties(backgroundColor(Color.RED));
- assertEquals(layer.getBackgroundColorAsInt(), Color.RED);
- }
+ //Set and Get
+ layer.setProperties(backgroundColor(Color.RED));
+ assertEquals(layer.getBackgroundColorAsInt(), Color.RED);
+ }
- @Test
- public void testBackgroundPattern() {
- checkViewIsDisplayed(R.id.mapView);
+ @Test
+ public void testBackgroundPattern() {
+ checkViewIsDisplayed(R.id.mapView);
- mapboxMap = rule.getActivity().getMapboxMap();
+ mapboxMap = rule.getActivity().getMapboxMap();
- Log.i(TAG, "Retrieving layer");
- layer = mapboxMap.getLayerAs("background");
- Log.i(TAG, "background-pattern");
- assertNotNull(layer);
+ Timber.i("Retrieving layer");
+ layer = mapboxMap.getLayerAs("background");
+ Timber.i("background-pattern");
+ assertNotNull(layer);
- //Set and Get
- layer.setProperties(backgroundPattern("pedestrian-polygon"));
- assertEquals((String) layer.getBackgroundPattern().getValue(), (String) "pedestrian-polygon");
- }
+ //Set and Get
+ layer.setProperties(backgroundPattern("pedestrian-polygon"));
+ assertEquals((String) layer.getBackgroundPattern().getValue(), (String) "pedestrian-polygon");
+ }
- @Test
- public void testBackgroundOpacity() {
- checkViewIsDisplayed(R.id.mapView);
+ @Test
+ public void testBackgroundOpacity() {
+ checkViewIsDisplayed(R.id.mapView);
- mapboxMap = rule.getActivity().getMapboxMap();
+ mapboxMap = rule.getActivity().getMapboxMap();
- Log.i(TAG, "Retrieving layer");
- layer = mapboxMap.getLayerAs("background");
- Log.i(TAG, "background-opacity");
- assertNotNull(layer);
+ Timber.i("Retrieving layer");
+ layer = mapboxMap.getLayerAs("background");
+ Timber.i("background-opacity");
+ assertNotNull(layer);
- //Set and Get
- layer.setProperties(backgroundOpacity(0.3f));
- assertEquals((Float) layer.getBackgroundOpacity().getValue(), (Float) 0.3f);
- }
+ //Set and Get
+ layer.setProperties(backgroundOpacity(0.3f));
+ assertEquals((Float) layer.getBackgroundOpacity().getValue(), (Float) 0.3f);
+ }
- @After
- public void unregisterIntentServiceIdlingResource() {
- Espresso.unregisterIdlingResources(idlingResource);
- }
+ @After
+ public void unregisterIntentServiceIdlingResource() {
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BaseStyleTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BaseStyleTest.java
index 5ec4e5437b..620e15579f 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BaseStyleTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/BaseStyleTest.java
@@ -14,31 +14,31 @@ import static android.support.test.espresso.matcher.ViewMatchers.withId;
*/
public class BaseStyleTest {
- protected final static String HOME_BUTTON_STRING = "Navigate up";
+ protected static final String HOME_BUTTON_STRING = "Navigate up";
- /*
- * Shortcuts for common UI tests
- */
+ /*
+ * Shortcuts for common UI tests
+ */
- protected void checkViewIsDisplayed(int id) {
- onView(withId(id))
- .check(matches(isDisplayed()));
- }
+ protected void checkViewIsDisplayed(int id) {
+ onView(withId(id))
+ .check(matches(isDisplayed()));
+ }
- /*
- * Screenshots logic
- */
+ /*
+ * Screenshots logic
+ */
- protected void takeNamedScreenshot(final Activity activity, final String name) {
+ protected void takeNamedScreenshot(final Activity activity, final String name) {
- // Screenshots need to be taken on the UI thread
- activity.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- ScreenshotUtil.take(activity, name);
- }
- });
+ // Screenshots need to be taken on the UI thread
+ activity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ ScreenshotUtil.take(activity, name);
+ }
+ });
- }
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerStyleTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerStyleTest.java
index a7301962d1..58fda51f07 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerStyleTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerStyleTest.java
@@ -1,11 +1,10 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
package com.mapbox.mapboxsdk.testapp.style;
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
import android.graphics.Color;
import android.support.test.espresso.Espresso;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
-import android.util.Log;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.style.layers.CircleLayer;
@@ -19,236 +18,248 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import static org.junit.Assert.*;
-import static com.mapbox.mapboxsdk.style.layers.Property.*;
-import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*;
+import timber.log.Timber;
+
+import static com.mapbox.mapboxsdk.style.layers.Property.CIRCLE_PITCH_SCALE_MAP;
+import static com.mapbox.mapboxsdk.style.layers.Property.CIRCLE_TRANSLATE_ANCHOR_MAP;
+import static com.mapbox.mapboxsdk.style.layers.Property.NONE;
+import static com.mapbox.mapboxsdk.style.layers.Property.VISIBLE;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleBlur;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleColor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleOpacity;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circlePitchScale;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleRadius;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleTranslate;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleTranslateAnchor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.visibility;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
/**
* Basic smoke tests for CircleLayer
*/
@RunWith(AndroidJUnit4.class)
public class CircleLayerStyleTest extends BaseStyleTest {
- private static final String TAG = CircleLayerStyleTest.class.getSimpleName();
- @Rule
- public final ActivityTestRule<RuntimeStyleTestActivity> rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class);
+ @Rule
+ public final ActivityTestRule<RuntimeStyleTestActivity> rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class);
- private CircleLayer layer;
+ private CircleLayer layer;
- private OnMapReadyIdlingResource idlingResource;
+ private OnMapReadyIdlingResource idlingResource;
- private MapboxMap mapboxMap;
+ private MapboxMap mapboxMap;
- @Before
- public void setup() {
- idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
- Espresso.registerIdlingResources(idlingResource);
- }
+ @Before
+ public void setup() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ }
- @Test
- public void testSetVisibility() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new CircleLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "visibility");
- assertNotNull(layer);
-
- //Get initial
- assertEquals(layer.getVisibility().getValue(), VISIBLE);
-
- //Set
- layer.setProperties(visibility(NONE));
- assertEquals(layer.getVisibility().getValue(), NONE);
- }
+ @Test
+ public void testSetVisibility() {
+ checkViewIsDisplayed(R.id.mapView);
- @Test
- public void testCircleRadius() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new CircleLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "circle-radius");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(circleRadius(0.3f));
- assertEquals((Float) layer.getCircleRadius().getValue(), (Float) 0.3f);
- }
+ mapboxMap = rule.getActivity().getMapboxMap();
- @Test
- public void testCircleColor() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new CircleLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "circle-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(circleColor("rgba(0, 0, 0, 1)"));
- assertEquals((String) layer.getCircleColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new CircleLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testCircleColorAsInt() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new CircleLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "circle-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(circleColor(Color.RED));
- assertEquals(layer.getCircleColorAsInt(), Color.RED);
+ Timber.i("visibility");
+ assertNotNull(layer);
+
+ //Get initial
+ assertEquals(layer.getVisibility().getValue(), VISIBLE);
+
+ //Set
+ layer.setProperties(visibility(NONE));
+ assertEquals(layer.getVisibility().getValue(), NONE);
+ }
+
+ @Test
+ public void testCircleRadius() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new CircleLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testCircleBlur() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new CircleLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "circle-blur");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(circleBlur(0.3f));
- assertEquals((Float) layer.getCircleBlur().getValue(), (Float) 0.3f);
+ Timber.i("circle-radius");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(circleRadius(0.3f));
+ assertEquals((Float) layer.getCircleRadius().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testCircleColor() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new CircleLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testCircleOpacity() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new CircleLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "circle-opacity");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(circleOpacity(0.3f));
- assertEquals((Float) layer.getCircleOpacity().getValue(), (Float) 0.3f);
+ Timber.i("circle-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(circleColor("rgba(0, 0, 0, 1)"));
+ assertEquals((String) layer.getCircleColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ }
+
+ @Test
+ public void testCircleColorAsInt() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new CircleLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testCircleTranslate() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new CircleLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "circle-translate");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(circleTranslate(new Float[]{0f,0f}));
- assertEquals((Float[]) layer.getCircleTranslate().getValue(), (Float[]) new Float[]{0f,0f});
+ Timber.i("circle-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(circleColor(Color.RED));
+ assertEquals(layer.getCircleColorAsInt(), Color.RED);
+ }
+
+ @Test
+ public void testCircleBlur() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new CircleLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testCircleTranslateAnchor() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new CircleLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "circle-translate-anchor");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(circleTranslateAnchor(CIRCLE_TRANSLATE_ANCHOR_MAP));
- assertEquals((String) layer.getCircleTranslateAnchor().getValue(), (String) CIRCLE_TRANSLATE_ANCHOR_MAP);
+ Timber.i("circle-blur");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(circleBlur(0.3f));
+ assertEquals((Float) layer.getCircleBlur().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testCircleOpacity() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new CircleLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testCirclePitchScale() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new CircleLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "circle-pitch-scale");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(circlePitchScale(CIRCLE_PITCH_SCALE_MAP));
- assertEquals((String) layer.getCirclePitchScale().getValue(), (String) CIRCLE_PITCH_SCALE_MAP);
+ Timber.i("circle-opacity");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(circleOpacity(0.3f));
+ assertEquals((Float) layer.getCircleOpacity().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testCircleTranslate() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new CircleLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
+ Timber.i("circle-translate");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(circleTranslate(new Float[] {0f, 0f}));
+ assertEquals((Float[]) layer.getCircleTranslate().getValue(), (Float[]) new Float[] {0f, 0f});
+ }
+
+ @Test
+ public void testCircleTranslateAnchor() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new CircleLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
+ }
+ Timber.i("circle-translate-anchor");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(circleTranslateAnchor(CIRCLE_TRANSLATE_ANCHOR_MAP));
+ assertEquals((String) layer.getCircleTranslateAnchor().getValue(), (String) CIRCLE_TRANSLATE_ANCHOR_MAP);
+ }
+
+ @Test
+ public void testCirclePitchScale() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new CircleLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
+ }
+ Timber.i("circle-pitch-scale");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(circlePitchScale(CIRCLE_PITCH_SCALE_MAP));
+ assertEquals((String) layer.getCirclePitchScale().getValue(), (String) CIRCLE_PITCH_SCALE_MAP);
+ }
- @After
- public void unregisterIntentServiceIdlingResource() {
- Espresso.unregisterIdlingResources(idlingResource);
- }
+ @After
+ public void unregisterIntentServiceIdlingResource() {
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerTest.java
index 8b0f1af17b..782598a0b2 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/CircleLayerTest.java
@@ -1,11 +1,10 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
package com.mapbox.mapboxsdk.testapp.style;
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
import android.graphics.Color;
import android.support.test.espresso.Espresso;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
-import android.util.Log;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.style.layers.CircleLayer;
@@ -19,236 +18,339 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import static org.junit.Assert.*;
-import static com.mapbox.mapboxsdk.style.layers.Property.*;
-import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*;
+import timber.log.Timber;
+
+import static com.mapbox.mapboxsdk.style.layers.Property.CIRCLE_PITCH_SCALE_MAP;
+import static com.mapbox.mapboxsdk.style.layers.Property.CIRCLE_TRANSLATE_ANCHOR_MAP;
+import static com.mapbox.mapboxsdk.style.layers.Property.NONE;
+import static com.mapbox.mapboxsdk.style.layers.Property.VISIBLE;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleBlur;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleColor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleOpacity;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circlePitchScale;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleRadius;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleStrokeColor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleStrokeOpacity;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleStrokeWidth;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleTranslate;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleTranslateAnchor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.visibility;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
/**
* Basic smoke tests for CircleLayer
*/
@RunWith(AndroidJUnit4.class)
public class CircleLayerTest extends BaseStyleTest {
- private static final String TAG = CircleLayerTest.class.getSimpleName();
- @Rule
- public final ActivityTestRule<RuntimeStyleTestActivity> rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class);
+ @Rule
+ public final ActivityTestRule<RuntimeStyleTestActivity> rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class);
- private CircleLayer layer;
+ private CircleLayer layer;
- private OnMapReadyIdlingResource idlingResource;
+ private OnMapReadyIdlingResource idlingResource;
- private MapboxMap mapboxMap;
+ private MapboxMap mapboxMap;
- @Before
- public void setup() {
- idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
- Espresso.registerIdlingResources(idlingResource);
- }
+ @Before
+ public void setup() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ }
- @Test
- public void testSetVisibility() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new CircleLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "visibility");
- assertNotNull(layer);
-
- //Get initial
- assertEquals(layer.getVisibility().getValue(), VISIBLE);
-
- //Set
- layer.setProperties(visibility(NONE));
- assertEquals(layer.getVisibility().getValue(), NONE);
- }
+ @Test
+ public void testSetVisibility() {
+ checkViewIsDisplayed(R.id.mapView);
- @Test
- public void testCircleRadius() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new CircleLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "circle-radius");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(circleRadius(0.3f));
- assertEquals((Float) layer.getCircleRadius().getValue(), (Float) 0.3f);
- }
+ mapboxMap = rule.getActivity().getMapboxMap();
- @Test
- public void testCircleColor() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new CircleLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "circle-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(circleColor("rgba(0, 0, 0, 1)"));
- assertEquals((String) layer.getCircleColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new CircleLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testCircleColorAsInt() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new CircleLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "circle-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(circleColor(Color.RED));
- assertEquals(layer.getCircleColorAsInt(), Color.RED);
+ Timber.i("visibility");
+ assertNotNull(layer);
+
+ //Get initial
+ assertEquals(layer.getVisibility().getValue(), VISIBLE);
+
+ //Set
+ layer.setProperties(visibility(NONE));
+ assertEquals(layer.getVisibility().getValue(), NONE);
+ }
+
+ @Test
+ public void testCircleRadius() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new CircleLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testCircleBlur() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new CircleLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "circle-blur");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(circleBlur(0.3f));
- assertEquals((Float) layer.getCircleBlur().getValue(), (Float) 0.3f);
+ Timber.i("circle-radius");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(circleRadius(0.3f));
+ assertEquals((Float) layer.getCircleRadius().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testCircleColor() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new CircleLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testCircleOpacity() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new CircleLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "circle-opacity");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(circleOpacity(0.3f));
- assertEquals((Float) layer.getCircleOpacity().getValue(), (Float) 0.3f);
+ Timber.i("circle-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(circleColor("rgba(0, 0, 0, 1)"));
+ assertEquals((String) layer.getCircleColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ }
+
+ @Test
+ public void testCircleColorAsInt() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new CircleLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testCircleTranslate() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new CircleLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "circle-translate");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(circleTranslate(new Float[]{0f,0f}));
- assertEquals((Float[]) layer.getCircleTranslate().getValue(), (Float[]) new Float[]{0f,0f});
+ Timber.i("circle-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(circleColor(Color.RED));
+ assertEquals(layer.getCircleColorAsInt(), Color.RED);
+ }
+
+ @Test
+ public void testCircleBlur() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new CircleLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testCircleTranslateAnchor() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new CircleLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "circle-translate-anchor");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(circleTranslateAnchor(CIRCLE_TRANSLATE_ANCHOR_MAP));
- assertEquals((String) layer.getCircleTranslateAnchor().getValue(), (String) CIRCLE_TRANSLATE_ANCHOR_MAP);
+ Timber.i("circle-blur");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(circleBlur(0.3f));
+ assertEquals((Float) layer.getCircleBlur().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testCircleOpacity() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new CircleLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testCirclePitchScale() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new CircleLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "circle-pitch-scale");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(circlePitchScale(CIRCLE_PITCH_SCALE_MAP));
- assertEquals((String) layer.getCirclePitchScale().getValue(), (String) CIRCLE_PITCH_SCALE_MAP);
+ Timber.i("circle-opacity");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(circleOpacity(0.3f));
+ assertEquals((Float) layer.getCircleOpacity().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testCircleTranslate() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new CircleLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
+ }
+ Timber.i("circle-translate");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(circleTranslate(new Float[] {0f, 0f}));
+ assertEquals((Float[]) layer.getCircleTranslate().getValue(), (Float[]) new Float[] {0f, 0f});
+ }
+
+ @Test
+ public void testCircleTranslateAnchor() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new CircleLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
+ }
+ Timber.i("circle-translate-anchor");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(circleTranslateAnchor(CIRCLE_TRANSLATE_ANCHOR_MAP));
+ assertEquals((String) layer.getCircleTranslateAnchor().getValue(), (String) CIRCLE_TRANSLATE_ANCHOR_MAP);
+ }
+
+ @Test
+ public void testCirclePitchScale() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new CircleLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
+ }
+ Timber.i("circle-pitch-scale");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(circlePitchScale(CIRCLE_PITCH_SCALE_MAP));
+ assertEquals((String) layer.getCirclePitchScale().getValue(), (String) CIRCLE_PITCH_SCALE_MAP);
+ }
+
+ @Test
+ public void testCircleStrokeWidth() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new CircleLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
+ Timber.i("circle-stroke-width");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(circleStrokeWidth(0.3f));
+ assertEquals((Float) layer.getCircleStrokeWidth().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testCircleStrokeColor() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new CircleLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
+ }
+ Timber.i("circle-stroke-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(circleStrokeColor("rgba(0, 0, 0, 1)"));
+ assertEquals((String) layer.getCircleStrokeColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ }
+
+ @Test
+ public void testCircleStrokeColorAsInt() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new CircleLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
+ }
+ Timber.i("circle-stroke-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(circleStrokeColor(Color.RED));
+ assertEquals(layer.getCircleStrokeColorAsInt(), Color.RED);
+ }
+
+ @Test
+ public void testCircleStrokeOpacity() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new CircleLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
+ }
+ Timber.i("circle-stroke-opacity");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(circleStrokeOpacity(0.3f));
+ assertEquals((Float) layer.getCircleStrokeOpacity().getValue(), (Float) 0.3f);
+ }
- @After
- public void unregisterIntentServiceIdlingResource() {
- Espresso.unregisterIdlingResources(idlingResource);
- }
+ @After
+ public void unregisterIntentServiceIdlingResource() {
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillLayerStyleTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillLayerStyleTest.java
index 46ad1da879..c8668fa407 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillLayerStyleTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillLayerStyleTest.java
@@ -1,11 +1,10 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
package com.mapbox.mapboxsdk.testapp.style;
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
import android.graphics.Color;
import android.support.test.espresso.Espresso;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
-import android.util.Log;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.style.layers.FillLayer;
@@ -19,258 +18,269 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import static org.junit.Assert.*;
-import static com.mapbox.mapboxsdk.style.layers.Property.*;
-import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*;
+import timber.log.Timber;
+
+import static com.mapbox.mapboxsdk.style.layers.Property.FILL_TRANSLATE_ANCHOR_MAP;
+import static com.mapbox.mapboxsdk.style.layers.Property.NONE;
+import static com.mapbox.mapboxsdk.style.layers.Property.VISIBLE;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillAntialias;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillColor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillOpacity;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillOutlineColor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillPattern;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillTranslate;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillTranslateAnchor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.visibility;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
/**
* Basic smoke tests for FillLayer
*/
@RunWith(AndroidJUnit4.class)
public class FillLayerStyleTest extends BaseStyleTest {
- private static final String TAG = FillLayerStyleTest.class.getSimpleName();
- @Rule
- public final ActivityTestRule<RuntimeStyleTestActivity> rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class);
+ @Rule
+ public final ActivityTestRule<RuntimeStyleTestActivity> rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class);
- private FillLayer layer;
+ private FillLayer layer;
- private OnMapReadyIdlingResource idlingResource;
+ private OnMapReadyIdlingResource idlingResource;
- private MapboxMap mapboxMap;
+ private MapboxMap mapboxMap;
- @Before
- public void setup() {
- idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
- Espresso.registerIdlingResources(idlingResource);
- }
+ @Before
+ public void setup() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ }
- @Test
- public void testSetVisibility() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new FillLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "visibility");
- assertNotNull(layer);
-
- //Get initial
- assertEquals(layer.getVisibility().getValue(), VISIBLE);
-
- //Set
- layer.setProperties(visibility(NONE));
- assertEquals(layer.getVisibility().getValue(), NONE);
- }
+ @Test
+ public void testSetVisibility() {
+ checkViewIsDisplayed(R.id.mapView);
- @Test
- public void testFillAntialias() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new FillLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "fill-antialias");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(fillAntialias(true));
- assertEquals((Boolean) layer.getFillAntialias().getValue(), (Boolean) true);
- }
+ mapboxMap = rule.getActivity().getMapboxMap();
- @Test
- public void testFillOpacity() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new FillLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "fill-opacity");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(fillOpacity(0.3f));
- assertEquals((Float) layer.getFillOpacity().getValue(), (Float) 0.3f);
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new FillLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testFillColor() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new FillLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "fill-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(fillColor("rgba(0, 0, 0, 1)"));
- assertEquals((String) layer.getFillColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ Timber.i("visibility");
+ assertNotNull(layer);
+
+ //Get initial
+ assertEquals(layer.getVisibility().getValue(), VISIBLE);
+
+ //Set
+ layer.setProperties(visibility(NONE));
+ assertEquals(layer.getVisibility().getValue(), NONE);
+ }
+
+ @Test
+ public void testFillAntialias() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new FillLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testFillColorAsInt() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new FillLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "fill-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(fillColor(Color.RED));
- assertEquals(layer.getFillColorAsInt(), Color.RED);
+ Timber.i("fill-antialias");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(fillAntialias(true));
+ assertEquals((Boolean) layer.getFillAntialias().getValue(), (Boolean) true);
+ }
+
+ @Test
+ public void testFillOpacity() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new FillLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testFillOutlineColor() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new FillLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "fill-outline-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(fillOutlineColor("rgba(0, 0, 0, 1)"));
- assertEquals((String) layer.getFillOutlineColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ Timber.i("fill-opacity");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(fillOpacity(0.3f));
+ assertEquals((Float) layer.getFillOpacity().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testFillColor() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new FillLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testFillOutlineColorAsInt() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new FillLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "fill-outline-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(fillOutlineColor(Color.RED));
- assertEquals(layer.getFillOutlineColorAsInt(), Color.RED);
+ Timber.i("fill-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(fillColor("rgba(0, 0, 0, 1)"));
+ assertEquals((String) layer.getFillColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ }
+
+ @Test
+ public void testFillColorAsInt() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new FillLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testFillTranslate() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new FillLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "fill-translate");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(fillTranslate(new Float[]{0f,0f}));
- assertEquals((Float[]) layer.getFillTranslate().getValue(), (Float[]) new Float[]{0f,0f});
+ Timber.i("fill-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(fillColor(Color.RED));
+ assertEquals(layer.getFillColorAsInt(), Color.RED);
+ }
+
+ @Test
+ public void testFillOutlineColor() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new FillLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testFillTranslateAnchor() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new FillLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "fill-translate-anchor");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(fillTranslateAnchor(FILL_TRANSLATE_ANCHOR_MAP));
- assertEquals((String) layer.getFillTranslateAnchor().getValue(), (String) FILL_TRANSLATE_ANCHOR_MAP);
+ Timber.i("fill-outline-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(fillOutlineColor("rgba(0, 0, 0, 1)"));
+ assertEquals((String) layer.getFillOutlineColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ }
+
+ @Test
+ public void testFillOutlineColorAsInt() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new FillLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testFillPattern() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new FillLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "fill-pattern");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(fillPattern("pedestrian-polygon"));
- assertEquals((String) layer.getFillPattern().getValue(), (String) "pedestrian-polygon");
+ Timber.i("fill-outline-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(fillOutlineColor(Color.RED));
+ assertEquals(layer.getFillOutlineColorAsInt(), Color.RED);
+ }
+
+ @Test
+ public void testFillTranslate() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new FillLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
+ Timber.i("fill-translate");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(fillTranslate(new Float[] {0f, 0f}));
+ assertEquals((Float[]) layer.getFillTranslate().getValue(), (Float[]) new Float[] {0f, 0f});
+ }
+
+ @Test
+ public void testFillTranslateAnchor() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new FillLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
+ }
+ Timber.i("fill-translate-anchor");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(fillTranslateAnchor(FILL_TRANSLATE_ANCHOR_MAP));
+ assertEquals((String) layer.getFillTranslateAnchor().getValue(), (String) FILL_TRANSLATE_ANCHOR_MAP);
+ }
+
+ @Test
+ public void testFillPattern() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new FillLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
+ }
+ Timber.i("fill-pattern");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(fillPattern("pedestrian-polygon"));
+ assertEquals((String) layer.getFillPattern().getValue(), (String) "pedestrian-polygon");
+ }
- @After
- public void unregisterIntentServiceIdlingResource() {
- Espresso.unregisterIdlingResources(idlingResource);
- }
+ @After
+ public void unregisterIntentServiceIdlingResource() {
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillLayerTest.java
index 593d444bc4..95360e1273 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillLayerTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/FillLayerTest.java
@@ -1,11 +1,10 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
package com.mapbox.mapboxsdk.testapp.style;
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
import android.graphics.Color;
import android.support.test.espresso.Espresso;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
-import android.util.Log;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.style.layers.FillLayer;
@@ -19,258 +18,269 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import static org.junit.Assert.*;
-import static com.mapbox.mapboxsdk.style.layers.Property.*;
-import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*;
+import timber.log.Timber;
+
+import static com.mapbox.mapboxsdk.style.layers.Property.FILL_TRANSLATE_ANCHOR_MAP;
+import static com.mapbox.mapboxsdk.style.layers.Property.NONE;
+import static com.mapbox.mapboxsdk.style.layers.Property.VISIBLE;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillAntialias;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillColor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillOpacity;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillOutlineColor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillPattern;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillTranslate;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillTranslateAnchor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.visibility;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
/**
* Basic smoke tests for FillLayer
*/
@RunWith(AndroidJUnit4.class)
public class FillLayerTest extends BaseStyleTest {
- private static final String TAG = FillLayerTest.class.getSimpleName();
- @Rule
- public final ActivityTestRule<RuntimeStyleTestActivity> rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class);
+ @Rule
+ public final ActivityTestRule<RuntimeStyleTestActivity> rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class);
- private FillLayer layer;
+ private FillLayer layer;
- private OnMapReadyIdlingResource idlingResource;
+ private OnMapReadyIdlingResource idlingResource;
- private MapboxMap mapboxMap;
+ private MapboxMap mapboxMap;
- @Before
- public void setup() {
- idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
- Espresso.registerIdlingResources(idlingResource);
- }
+ @Before
+ public void setup() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ }
- @Test
- public void testSetVisibility() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new FillLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "visibility");
- assertNotNull(layer);
-
- //Get initial
- assertEquals(layer.getVisibility().getValue(), VISIBLE);
-
- //Set
- layer.setProperties(visibility(NONE));
- assertEquals(layer.getVisibility().getValue(), NONE);
- }
+ @Test
+ public void testSetVisibility() {
+ checkViewIsDisplayed(R.id.mapView);
- @Test
- public void testFillAntialias() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new FillLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "fill-antialias");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(fillAntialias(true));
- assertEquals((Boolean) layer.getFillAntialias().getValue(), (Boolean) true);
- }
+ mapboxMap = rule.getActivity().getMapboxMap();
- @Test
- public void testFillOpacity() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new FillLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "fill-opacity");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(fillOpacity(0.3f));
- assertEquals((Float) layer.getFillOpacity().getValue(), (Float) 0.3f);
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new FillLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testFillColor() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new FillLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "fill-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(fillColor("rgba(0, 0, 0, 1)"));
- assertEquals((String) layer.getFillColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ Timber.i("visibility");
+ assertNotNull(layer);
+
+ //Get initial
+ assertEquals(layer.getVisibility().getValue(), VISIBLE);
+
+ //Set
+ layer.setProperties(visibility(NONE));
+ assertEquals(layer.getVisibility().getValue(), NONE);
+ }
+
+ @Test
+ public void testFillAntialias() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new FillLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testFillColorAsInt() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new FillLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "fill-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(fillColor(Color.RED));
- assertEquals(layer.getFillColorAsInt(), Color.RED);
+ Timber.i("fill-antialias");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(fillAntialias(true));
+ assertEquals((Boolean) layer.getFillAntialias().getValue(), (Boolean) true);
+ }
+
+ @Test
+ public void testFillOpacity() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new FillLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testFillOutlineColor() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new FillLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "fill-outline-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(fillOutlineColor("rgba(0, 0, 0, 1)"));
- assertEquals((String) layer.getFillOutlineColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ Timber.i("fill-opacity");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(fillOpacity(0.3f));
+ assertEquals((Float) layer.getFillOpacity().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testFillColor() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new FillLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testFillOutlineColorAsInt() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new FillLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "fill-outline-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(fillOutlineColor(Color.RED));
- assertEquals(layer.getFillOutlineColorAsInt(), Color.RED);
+ Timber.i("fill-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(fillColor("rgba(0, 0, 0, 1)"));
+ assertEquals((String) layer.getFillColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ }
+
+ @Test
+ public void testFillColorAsInt() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new FillLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testFillTranslate() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new FillLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "fill-translate");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(fillTranslate(new Float[]{0f,0f}));
- assertEquals((Float[]) layer.getFillTranslate().getValue(), (Float[]) new Float[]{0f,0f});
+ Timber.i("fill-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(fillColor(Color.RED));
+ assertEquals(layer.getFillColorAsInt(), Color.RED);
+ }
+
+ @Test
+ public void testFillOutlineColor() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new FillLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testFillTranslateAnchor() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new FillLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "fill-translate-anchor");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(fillTranslateAnchor(FILL_TRANSLATE_ANCHOR_MAP));
- assertEquals((String) layer.getFillTranslateAnchor().getValue(), (String) FILL_TRANSLATE_ANCHOR_MAP);
+ Timber.i("fill-outline-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(fillOutlineColor("rgba(0, 0, 0, 1)"));
+ assertEquals((String) layer.getFillOutlineColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ }
+
+ @Test
+ public void testFillOutlineColorAsInt() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new FillLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testFillPattern() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new FillLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "fill-pattern");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(fillPattern("pedestrian-polygon"));
- assertEquals((String) layer.getFillPattern().getValue(), (String) "pedestrian-polygon");
+ Timber.i("fill-outline-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(fillOutlineColor(Color.RED));
+ assertEquals(layer.getFillOutlineColorAsInt(), Color.RED);
+ }
+
+ @Test
+ public void testFillTranslate() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new FillLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
+ Timber.i("fill-translate");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(fillTranslate(new Float[] {0f, 0f}));
+ assertEquals((Float[]) layer.getFillTranslate().getValue(), (Float[]) new Float[] {0f, 0f});
+ }
+
+ @Test
+ public void testFillTranslateAnchor() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new FillLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
+ }
+ Timber.i("fill-translate-anchor");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(fillTranslateAnchor(FILL_TRANSLATE_ANCHOR_MAP));
+ assertEquals((String) layer.getFillTranslateAnchor().getValue(), (String) FILL_TRANSLATE_ANCHOR_MAP);
+ }
+
+ @Test
+ public void testFillPattern() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new FillLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
+ }
+ Timber.i("fill-pattern");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(fillPattern("pedestrian-polygon"));
+ assertEquals((String) layer.getFillPattern().getValue(), (String) "pedestrian-polygon");
+ }
- @After
- public void unregisterIntentServiceIdlingResource() {
- Espresso.unregisterIdlingResources(idlingResource);
- }
+ @After
+ public void unregisterIntentServiceIdlingResource() {
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerStyleTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerStyleTest.java
index 09c1ae797d..47a38a11ab 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerStyleTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerStyleTest.java
@@ -1,11 +1,10 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
package com.mapbox.mapboxsdk.testapp.style;
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
import android.graphics.Color;
import android.support.test.espresso.Espresso;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
-import android.util.Log;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.style.layers.LineLayer;
@@ -19,390 +18,410 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import static org.junit.Assert.*;
-import static com.mapbox.mapboxsdk.style.layers.Property.*;
-import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*;
+import timber.log.Timber;
+
+import static com.mapbox.mapboxsdk.style.layers.Property.LINE_CAP_BUTT;
+import static com.mapbox.mapboxsdk.style.layers.Property.LINE_JOIN_BEVEL;
+import static com.mapbox.mapboxsdk.style.layers.Property.LINE_TRANSLATE_ANCHOR_MAP;
+import static com.mapbox.mapboxsdk.style.layers.Property.NONE;
+import static com.mapbox.mapboxsdk.style.layers.Property.VISIBLE;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineBlur;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineCap;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineColor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineDasharray;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineGapWidth;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineJoin;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineMiterLimit;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineOffset;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineOpacity;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.linePattern;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineRoundLimit;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineTranslate;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineTranslateAnchor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineWidth;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.visibility;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
/**
* Basic smoke tests for LineLayer
*/
@RunWith(AndroidJUnit4.class)
public class LineLayerStyleTest extends BaseStyleTest {
- private static final String TAG = LineLayerStyleTest.class.getSimpleName();
- @Rule
- public final ActivityTestRule<RuntimeStyleTestActivity> rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class);
+ @Rule
+ public final ActivityTestRule<RuntimeStyleTestActivity> rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class);
- private LineLayer layer;
+ private LineLayer layer;
- private OnMapReadyIdlingResource idlingResource;
+ private OnMapReadyIdlingResource idlingResource;
- private MapboxMap mapboxMap;
+ private MapboxMap mapboxMap;
- @Before
- public void setup() {
- idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
- Espresso.registerIdlingResources(idlingResource);
- }
+ @Before
+ public void setup() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ }
- @Test
- public void testSetVisibility() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "visibility");
- assertNotNull(layer);
-
- //Get initial
- assertEquals(layer.getVisibility().getValue(), VISIBLE);
-
- //Set
- layer.setProperties(visibility(NONE));
- assertEquals(layer.getVisibility().getValue(), NONE);
- }
+ @Test
+ public void testSetVisibility() {
+ checkViewIsDisplayed(R.id.mapView);
- @Test
- public void testLineCap() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-cap");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(lineCap(LINE_CAP_BUTT));
- assertEquals((String) layer.getLineCap().getValue(), (String) LINE_CAP_BUTT);
- }
+ mapboxMap = rule.getActivity().getMapboxMap();
- @Test
- public void testLineJoin() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-join");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(lineJoin(LINE_JOIN_BEVEL));
- assertEquals((String) layer.getLineJoin().getValue(), (String) LINE_JOIN_BEVEL);
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testLineMiterLimit() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-miter-limit");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(lineMiterLimit(0.3f));
- assertEquals((Float) layer.getLineMiterLimit().getValue(), (Float) 0.3f);
+ Timber.i("visibility");
+ assertNotNull(layer);
+
+ //Get initial
+ assertEquals(layer.getVisibility().getValue(), VISIBLE);
+
+ //Set
+ layer.setProperties(visibility(NONE));
+ assertEquals(layer.getVisibility().getValue(), NONE);
+ }
+
+ @Test
+ public void testLineCap() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testLineRoundLimit() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-round-limit");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(lineRoundLimit(0.3f));
- assertEquals((Float) layer.getLineRoundLimit().getValue(), (Float) 0.3f);
+ Timber.i("line-cap");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(lineCap(LINE_CAP_BUTT));
+ assertEquals((String) layer.getLineCap().getValue(), (String) LINE_CAP_BUTT);
+ }
+
+ @Test
+ public void testLineJoin() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testLineOpacity() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-opacity");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(lineOpacity(0.3f));
- assertEquals((Float) layer.getLineOpacity().getValue(), (Float) 0.3f);
+ Timber.i("line-join");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(lineJoin(LINE_JOIN_BEVEL));
+ assertEquals((String) layer.getLineJoin().getValue(), (String) LINE_JOIN_BEVEL);
+ }
+
+ @Test
+ public void testLineMiterLimit() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testLineColor() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(lineColor("rgba(0, 0, 0, 1)"));
- assertEquals((String) layer.getLineColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ Timber.i("line-miter-limit");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(lineMiterLimit(0.3f));
+ assertEquals((Float) layer.getLineMiterLimit().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testLineRoundLimit() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testLineColorAsInt() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(lineColor(Color.RED));
- assertEquals(layer.getLineColorAsInt(), Color.RED);
+ Timber.i("line-round-limit");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(lineRoundLimit(0.3f));
+ assertEquals((Float) layer.getLineRoundLimit().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testLineOpacity() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testLineTranslate() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-translate");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(lineTranslate(new Float[]{0f,0f}));
- assertEquals((Float[]) layer.getLineTranslate().getValue(), (Float[]) new Float[]{0f,0f});
+ Timber.i("line-opacity");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(lineOpacity(0.3f));
+ assertEquals((Float) layer.getLineOpacity().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testLineColor() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testLineTranslateAnchor() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-translate-anchor");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(lineTranslateAnchor(LINE_TRANSLATE_ANCHOR_MAP));
- assertEquals((String) layer.getLineTranslateAnchor().getValue(), (String) LINE_TRANSLATE_ANCHOR_MAP);
+ Timber.i("line-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(lineColor("rgba(0, 0, 0, 1)"));
+ assertEquals((String) layer.getLineColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ }
+
+ @Test
+ public void testLineColorAsInt() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testLineWidth() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-width");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(lineWidth(0.3f));
- assertEquals((Float) layer.getLineWidth().getValue(), (Float) 0.3f);
+ Timber.i("line-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(lineColor(Color.RED));
+ assertEquals(layer.getLineColorAsInt(), Color.RED);
+ }
+
+ @Test
+ public void testLineTranslate() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testLineGapWidth() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-gap-width");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(lineGapWidth(0.3f));
- assertEquals((Float) layer.getLineGapWidth().getValue(), (Float) 0.3f);
+ Timber.i("line-translate");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(lineTranslate(new Float[] {0f, 0f}));
+ assertEquals((Float[]) layer.getLineTranslate().getValue(), (Float[]) new Float[] {0f, 0f});
+ }
+
+ @Test
+ public void testLineTranslateAnchor() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testLineOffset() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-offset");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(lineOffset(0.3f));
- assertEquals((Float) layer.getLineOffset().getValue(), (Float) 0.3f);
+ Timber.i("line-translate-anchor");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(lineTranslateAnchor(LINE_TRANSLATE_ANCHOR_MAP));
+ assertEquals((String) layer.getLineTranslateAnchor().getValue(), (String) LINE_TRANSLATE_ANCHOR_MAP);
+ }
+
+ @Test
+ public void testLineWidth() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testLineBlur() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-blur");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(lineBlur(0.3f));
- assertEquals((Float) layer.getLineBlur().getValue(), (Float) 0.3f);
+ Timber.i("line-width");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(lineWidth(0.3f));
+ assertEquals((Float) layer.getLineWidth().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testLineGapWidth() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testLineDasharray() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-dasharray");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(lineDasharray(new Float[]{}));
- assertEquals((Float[]) layer.getLineDasharray().getValue(), (Float[]) new Float[]{});
+ Timber.i("line-gap-width");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(lineGapWidth(0.3f));
+ assertEquals((Float) layer.getLineGapWidth().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testLineOffset() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testLinePattern() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-pattern");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(linePattern("pedestrian-polygon"));
- assertEquals((String) layer.getLinePattern().getValue(), (String) "pedestrian-polygon");
+ Timber.i("line-offset");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(lineOffset(0.3f));
+ assertEquals((Float) layer.getLineOffset().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testLineBlur() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
+ }
+ Timber.i("line-blur");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(lineBlur(0.3f));
+ assertEquals((Float) layer.getLineBlur().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testLineDasharray() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
+ Timber.i("line-dasharray");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(lineDasharray(new Float[] {}));
+ assertEquals((Float[]) layer.getLineDasharray().getValue(), (Float[]) new Float[] {});
+ }
+
+ @Test
+ public void testLinePattern() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
+ }
+ Timber.i("line-pattern");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(linePattern("pedestrian-polygon"));
+ assertEquals((String) layer.getLinePattern().getValue(), (String) "pedestrian-polygon");
+ }
- @After
- public void unregisterIntentServiceIdlingResource() {
- Espresso.unregisterIdlingResources(idlingResource);
- }
+ @After
+ public void unregisterIntentServiceIdlingResource() {
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerTest.java
index 15fd35f0a8..ad091c78b3 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/LineLayerTest.java
@@ -1,11 +1,10 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
package com.mapbox.mapboxsdk.testapp.style;
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
import android.graphics.Color;
import android.support.test.espresso.Espresso;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
-import android.util.Log;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.style.layers.LineLayer;
@@ -19,390 +18,410 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import static org.junit.Assert.*;
-import static com.mapbox.mapboxsdk.style.layers.Property.*;
-import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*;
+import timber.log.Timber;
+
+import static com.mapbox.mapboxsdk.style.layers.Property.LINE_CAP_BUTT;
+import static com.mapbox.mapboxsdk.style.layers.Property.LINE_JOIN_BEVEL;
+import static com.mapbox.mapboxsdk.style.layers.Property.LINE_TRANSLATE_ANCHOR_MAP;
+import static com.mapbox.mapboxsdk.style.layers.Property.NONE;
+import static com.mapbox.mapboxsdk.style.layers.Property.VISIBLE;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineBlur;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineCap;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineColor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineDasharray;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineGapWidth;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineJoin;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineMiterLimit;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineOffset;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineOpacity;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.linePattern;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineRoundLimit;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineTranslate;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineTranslateAnchor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineWidth;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.visibility;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
/**
* Basic smoke tests for LineLayer
*/
@RunWith(AndroidJUnit4.class)
public class LineLayerTest extends BaseStyleTest {
- private static final String TAG = LineLayerTest.class.getSimpleName();
- @Rule
- public final ActivityTestRule<RuntimeStyleTestActivity> rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class);
+ @Rule
+ public final ActivityTestRule<RuntimeStyleTestActivity> rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class);
- private LineLayer layer;
+ private LineLayer layer;
- private OnMapReadyIdlingResource idlingResource;
+ private OnMapReadyIdlingResource idlingResource;
- private MapboxMap mapboxMap;
+ private MapboxMap mapboxMap;
- @Before
- public void setup() {
- idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
- Espresso.registerIdlingResources(idlingResource);
- }
+ @Before
+ public void setup() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ }
- @Test
- public void testSetVisibility() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "visibility");
- assertNotNull(layer);
-
- //Get initial
- assertEquals(layer.getVisibility().getValue(), VISIBLE);
-
- //Set
- layer.setProperties(visibility(NONE));
- assertEquals(layer.getVisibility().getValue(), NONE);
- }
+ @Test
+ public void testSetVisibility() {
+ checkViewIsDisplayed(R.id.mapView);
- @Test
- public void testLineCap() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-cap");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(lineCap(LINE_CAP_BUTT));
- assertEquals((String) layer.getLineCap().getValue(), (String) LINE_CAP_BUTT);
- }
+ mapboxMap = rule.getActivity().getMapboxMap();
- @Test
- public void testLineJoin() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-join");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(lineJoin(LINE_JOIN_BEVEL));
- assertEquals((String) layer.getLineJoin().getValue(), (String) LINE_JOIN_BEVEL);
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testLineMiterLimit() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-miter-limit");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(lineMiterLimit(0.3f));
- assertEquals((Float) layer.getLineMiterLimit().getValue(), (Float) 0.3f);
+ Timber.i("visibility");
+ assertNotNull(layer);
+
+ //Get initial
+ assertEquals(layer.getVisibility().getValue(), VISIBLE);
+
+ //Set
+ layer.setProperties(visibility(NONE));
+ assertEquals(layer.getVisibility().getValue(), NONE);
+ }
+
+ @Test
+ public void testLineCap() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testLineRoundLimit() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-round-limit");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(lineRoundLimit(0.3f));
- assertEquals((Float) layer.getLineRoundLimit().getValue(), (Float) 0.3f);
+ Timber.i("line-cap");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(lineCap(LINE_CAP_BUTT));
+ assertEquals((String) layer.getLineCap().getValue(), (String) LINE_CAP_BUTT);
+ }
+
+ @Test
+ public void testLineJoin() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testLineOpacity() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-opacity");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(lineOpacity(0.3f));
- assertEquals((Float) layer.getLineOpacity().getValue(), (Float) 0.3f);
+ Timber.i("line-join");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(lineJoin(LINE_JOIN_BEVEL));
+ assertEquals((String) layer.getLineJoin().getValue(), (String) LINE_JOIN_BEVEL);
+ }
+
+ @Test
+ public void testLineMiterLimit() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testLineColor() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(lineColor("rgba(0, 0, 0, 1)"));
- assertEquals((String) layer.getLineColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ Timber.i("line-miter-limit");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(lineMiterLimit(0.3f));
+ assertEquals((Float) layer.getLineMiterLimit().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testLineRoundLimit() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testLineColorAsInt() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(lineColor(Color.RED));
- assertEquals(layer.getLineColorAsInt(), Color.RED);
+ Timber.i("line-round-limit");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(lineRoundLimit(0.3f));
+ assertEquals((Float) layer.getLineRoundLimit().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testLineOpacity() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testLineTranslate() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-translate");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(lineTranslate(new Float[]{0f,0f}));
- assertEquals((Float[]) layer.getLineTranslate().getValue(), (Float[]) new Float[]{0f,0f});
+ Timber.i("line-opacity");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(lineOpacity(0.3f));
+ assertEquals((Float) layer.getLineOpacity().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testLineColor() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testLineTranslateAnchor() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-translate-anchor");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(lineTranslateAnchor(LINE_TRANSLATE_ANCHOR_MAP));
- assertEquals((String) layer.getLineTranslateAnchor().getValue(), (String) LINE_TRANSLATE_ANCHOR_MAP);
+ Timber.i("line-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(lineColor("rgba(0, 0, 0, 1)"));
+ assertEquals((String) layer.getLineColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ }
+
+ @Test
+ public void testLineColorAsInt() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testLineWidth() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-width");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(lineWidth(0.3f));
- assertEquals((Float) layer.getLineWidth().getValue(), (Float) 0.3f);
+ Timber.i("line-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(lineColor(Color.RED));
+ assertEquals(layer.getLineColorAsInt(), Color.RED);
+ }
+
+ @Test
+ public void testLineTranslate() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testLineGapWidth() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-gap-width");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(lineGapWidth(0.3f));
- assertEquals((Float) layer.getLineGapWidth().getValue(), (Float) 0.3f);
+ Timber.i("line-translate");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(lineTranslate(new Float[] {0f, 0f}));
+ assertEquals((Float[]) layer.getLineTranslate().getValue(), (Float[]) new Float[] {0f, 0f});
+ }
+
+ @Test
+ public void testLineTranslateAnchor() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testLineOffset() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-offset");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(lineOffset(0.3f));
- assertEquals((Float) layer.getLineOffset().getValue(), (Float) 0.3f);
+ Timber.i("line-translate-anchor");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(lineTranslateAnchor(LINE_TRANSLATE_ANCHOR_MAP));
+ assertEquals((String) layer.getLineTranslateAnchor().getValue(), (String) LINE_TRANSLATE_ANCHOR_MAP);
+ }
+
+ @Test
+ public void testLineWidth() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testLineBlur() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-blur");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(lineBlur(0.3f));
- assertEquals((Float) layer.getLineBlur().getValue(), (Float) 0.3f);
+ Timber.i("line-width");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(lineWidth(0.3f));
+ assertEquals((Float) layer.getLineWidth().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testLineGapWidth() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testLineDasharray() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-dasharray");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(lineDasharray(new Float[]{}));
- assertEquals((Float[]) layer.getLineDasharray().getValue(), (Float[]) new Float[]{});
+ Timber.i("line-gap-width");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(lineGapWidth(0.3f));
+ assertEquals((Float) layer.getLineGapWidth().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testLineOffset() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testLinePattern() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new LineLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "line-pattern");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(linePattern("pedestrian-polygon"));
- assertEquals((String) layer.getLinePattern().getValue(), (String) "pedestrian-polygon");
+ Timber.i("line-offset");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(lineOffset(0.3f));
+ assertEquals((Float) layer.getLineOffset().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testLineBlur() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
+ }
+ Timber.i("line-blur");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(lineBlur(0.3f));
+ assertEquals((Float) layer.getLineBlur().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testLineDasharray() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
+ Timber.i("line-dasharray");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(lineDasharray(new Float[] {}));
+ assertEquals((Float[]) layer.getLineDasharray().getValue(), (Float[]) new Float[] {});
+ }
+
+ @Test
+ public void testLinePattern() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new LineLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
+ }
+ Timber.i("line-pattern");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(linePattern("pedestrian-polygon"));
+ assertEquals((String) layer.getLinePattern().getValue(), (String) "pedestrian-polygon");
+ }
- @After
- public void unregisterIntentServiceIdlingResource() {
- Espresso.unregisterIdlingResources(idlingResource);
- }
+ @After
+ public void unregisterIntentServiceIdlingResource() {
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RasterLayerStyleTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RasterLayerStyleTest.java
index 2baddd6fa1..eb67b48f7a 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RasterLayerStyleTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RasterLayerStyleTest.java
@@ -1,10 +1,9 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
package com.mapbox.mapboxsdk.testapp.style;
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
import android.support.test.espresso.Espresso;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
-import android.util.Log;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.style.layers.RasterLayer;
@@ -18,214 +17,224 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import static org.junit.Assert.*;
-import static com.mapbox.mapboxsdk.style.layers.Property.*;
-import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*;
+import timber.log.Timber;
+
+import static com.mapbox.mapboxsdk.style.layers.Property.NONE;
+import static com.mapbox.mapboxsdk.style.layers.Property.VISIBLE;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.rasterBrightnessMax;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.rasterBrightnessMin;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.rasterContrast;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.rasterFadeDuration;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.rasterHueRotate;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.rasterOpacity;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.rasterSaturation;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.visibility;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
/**
* Basic smoke tests for RasterLayer
*/
@RunWith(AndroidJUnit4.class)
public class RasterLayerStyleTest extends BaseStyleTest {
- private static final String TAG = RasterLayerStyleTest.class.getSimpleName();
- @Rule
- public final ActivityTestRule<RuntimeStyleTestActivity> rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class);
+ @Rule
+ public final ActivityTestRule<RuntimeStyleTestActivity> rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class);
- private RasterLayer layer;
+ private RasterLayer layer;
- private OnMapReadyIdlingResource idlingResource;
+ private OnMapReadyIdlingResource idlingResource;
- private MapboxMap mapboxMap;
+ private MapboxMap mapboxMap;
- @Before
- public void setup() {
- idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
- Espresso.registerIdlingResources(idlingResource);
- }
+ @Before
+ public void setup() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ }
- @Test
- public void testSetVisibility() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new RasterLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "visibility");
- assertNotNull(layer);
-
- //Get initial
- assertEquals(layer.getVisibility().getValue(), VISIBLE);
-
- //Set
- layer.setProperties(visibility(NONE));
- assertEquals(layer.getVisibility().getValue(), NONE);
- }
+ @Test
+ public void testSetVisibility() {
+ checkViewIsDisplayed(R.id.mapView);
- @Test
- public void testRasterOpacity() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new RasterLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "raster-opacity");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(rasterOpacity(0.3f));
- assertEquals((Float) layer.getRasterOpacity().getValue(), (Float) 0.3f);
- }
+ mapboxMap = rule.getActivity().getMapboxMap();
- @Test
- public void testRasterHueRotate() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new RasterLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "raster-hue-rotate");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(rasterHueRotate(0.3f));
- assertEquals((Float) layer.getRasterHueRotate().getValue(), (Float) 0.3f);
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new RasterLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testRasterBrightnessMin() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new RasterLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "raster-brightness-min");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(rasterBrightnessMin(0.3f));
- assertEquals((Float) layer.getRasterBrightnessMin().getValue(), (Float) 0.3f);
+ Timber.i("visibility");
+ assertNotNull(layer);
+
+ //Get initial
+ assertEquals(layer.getVisibility().getValue(), VISIBLE);
+
+ //Set
+ layer.setProperties(visibility(NONE));
+ assertEquals(layer.getVisibility().getValue(), NONE);
+ }
+
+ @Test
+ public void testRasterOpacity() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new RasterLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testRasterBrightnessMax() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new RasterLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "raster-brightness-max");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(rasterBrightnessMax(0.3f));
- assertEquals((Float) layer.getRasterBrightnessMax().getValue(), (Float) 0.3f);
+ Timber.i("raster-opacity");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(rasterOpacity(0.3f));
+ assertEquals((Float) layer.getRasterOpacity().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testRasterHueRotate() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new RasterLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testRasterSaturation() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new RasterLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "raster-saturation");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(rasterSaturation(0.3f));
- assertEquals((Float) layer.getRasterSaturation().getValue(), (Float) 0.3f);
+ Timber.i("raster-hue-rotate");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(rasterHueRotate(0.3f));
+ assertEquals((Float) layer.getRasterHueRotate().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testRasterBrightnessMin() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new RasterLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testRasterContrast() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new RasterLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "raster-contrast");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(rasterContrast(0.3f));
- assertEquals((Float) layer.getRasterContrast().getValue(), (Float) 0.3f);
+ Timber.i("raster-brightness-min");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(rasterBrightnessMin(0.3f));
+ assertEquals((Float) layer.getRasterBrightnessMin().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testRasterBrightnessMax() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new RasterLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testRasterFadeDuration() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new RasterLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "raster-fade-duration");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(rasterFadeDuration(0.3f));
- assertEquals((Float) layer.getRasterFadeDuration().getValue(), (Float) 0.3f);
+ Timber.i("raster-brightness-max");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(rasterBrightnessMax(0.3f));
+ assertEquals((Float) layer.getRasterBrightnessMax().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testRasterSaturation() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new RasterLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
+ Timber.i("raster-saturation");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(rasterSaturation(0.3f));
+ assertEquals((Float) layer.getRasterSaturation().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testRasterContrast() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new RasterLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
+ }
+ Timber.i("raster-contrast");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(rasterContrast(0.3f));
+ assertEquals((Float) layer.getRasterContrast().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testRasterFadeDuration() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new RasterLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
+ }
+ Timber.i("raster-fade-duration");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(rasterFadeDuration(0.3f));
+ assertEquals((Float) layer.getRasterFadeDuration().getValue(), (Float) 0.3f);
+ }
- @After
- public void unregisterIntentServiceIdlingResource() {
- Espresso.unregisterIdlingResources(idlingResource);
- }
+ @After
+ public void unregisterIntentServiceIdlingResource() {
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RasterLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RasterLayerTest.java
index b64c9a244c..169d747b9c 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RasterLayerTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RasterLayerTest.java
@@ -1,11 +1,9 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
package com.mapbox.mapboxsdk.testapp.style;
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
-import android.graphics.Color;
import android.support.test.espresso.Espresso;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
-import android.util.Log;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.style.layers.RasterLayer;
@@ -19,214 +17,224 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import static org.junit.Assert.*;
-import static com.mapbox.mapboxsdk.style.layers.Property.*;
-import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*;
+import timber.log.Timber;
+
+import static com.mapbox.mapboxsdk.style.layers.Property.NONE;
+import static com.mapbox.mapboxsdk.style.layers.Property.VISIBLE;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.rasterBrightnessMax;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.rasterBrightnessMin;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.rasterContrast;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.rasterFadeDuration;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.rasterHueRotate;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.rasterOpacity;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.rasterSaturation;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.visibility;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
/**
* Basic smoke tests for RasterLayer
*/
@RunWith(AndroidJUnit4.class)
public class RasterLayerTest extends BaseStyleTest {
- private static final String TAG = RasterLayerTest.class.getSimpleName();
- @Rule
- public final ActivityTestRule<RuntimeStyleTestActivity> rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class);
+ @Rule
+ public final ActivityTestRule<RuntimeStyleTestActivity> rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class);
- private RasterLayer layer;
+ private RasterLayer layer;
- private OnMapReadyIdlingResource idlingResource;
+ private OnMapReadyIdlingResource idlingResource;
- private MapboxMap mapboxMap;
+ private MapboxMap mapboxMap;
- @Before
- public void setup() {
- idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
- Espresso.registerIdlingResources(idlingResource);
- }
+ @Before
+ public void setup() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ }
- @Test
- public void testSetVisibility() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new RasterLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "visibility");
- assertNotNull(layer);
-
- //Get initial
- assertEquals(layer.getVisibility().getValue(), VISIBLE);
-
- //Set
- layer.setProperties(visibility(NONE));
- assertEquals(layer.getVisibility().getValue(), NONE);
- }
+ @Test
+ public void testSetVisibility() {
+ checkViewIsDisplayed(R.id.mapView);
- @Test
- public void testRasterOpacity() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new RasterLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "raster-opacity");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(rasterOpacity(0.3f));
- assertEquals((Float) layer.getRasterOpacity().getValue(), (Float) 0.3f);
- }
+ mapboxMap = rule.getActivity().getMapboxMap();
- @Test
- public void testRasterHueRotate() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new RasterLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "raster-hue-rotate");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(rasterHueRotate(0.3f));
- assertEquals((Float) layer.getRasterHueRotate().getValue(), (Float) 0.3f);
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new RasterLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testRasterBrightnessMin() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new RasterLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "raster-brightness-min");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(rasterBrightnessMin(0.3f));
- assertEquals((Float) layer.getRasterBrightnessMin().getValue(), (Float) 0.3f);
+ Timber.i("visibility");
+ assertNotNull(layer);
+
+ //Get initial
+ assertEquals(layer.getVisibility().getValue(), VISIBLE);
+
+ //Set
+ layer.setProperties(visibility(NONE));
+ assertEquals(layer.getVisibility().getValue(), NONE);
+ }
+
+ @Test
+ public void testRasterOpacity() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new RasterLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testRasterBrightnessMax() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new RasterLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "raster-brightness-max");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(rasterBrightnessMax(0.3f));
- assertEquals((Float) layer.getRasterBrightnessMax().getValue(), (Float) 0.3f);
+ Timber.i("raster-opacity");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(rasterOpacity(0.3f));
+ assertEquals((Float) layer.getRasterOpacity().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testRasterHueRotate() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new RasterLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testRasterSaturation() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new RasterLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "raster-saturation");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(rasterSaturation(0.3f));
- assertEquals((Float) layer.getRasterSaturation().getValue(), (Float) 0.3f);
+ Timber.i("raster-hue-rotate");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(rasterHueRotate(0.3f));
+ assertEquals((Float) layer.getRasterHueRotate().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testRasterBrightnessMin() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new RasterLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testRasterContrast() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new RasterLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "raster-contrast");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(rasterContrast(0.3f));
- assertEquals((Float) layer.getRasterContrast().getValue(), (Float) 0.3f);
+ Timber.i("raster-brightness-min");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(rasterBrightnessMin(0.3f));
+ assertEquals((Float) layer.getRasterBrightnessMin().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testRasterBrightnessMax() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new RasterLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testRasterFadeDuration() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new RasterLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "raster-fade-duration");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(rasterFadeDuration(0.3f));
- assertEquals((Float) layer.getRasterFadeDuration().getValue(), (Float) 0.3f);
+ Timber.i("raster-brightness-max");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(rasterBrightnessMax(0.3f));
+ assertEquals((Float) layer.getRasterBrightnessMax().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testRasterSaturation() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new RasterLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
+ }
+ Timber.i("raster-saturation");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(rasterSaturation(0.3f));
+ assertEquals((Float) layer.getRasterSaturation().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testRasterContrast() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new RasterLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
+ Timber.i("raster-contrast");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(rasterContrast(0.3f));
+ assertEquals((Float) layer.getRasterContrast().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testRasterFadeDuration() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new RasterLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
+ }
+ Timber.i("raster-fade-duration");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(rasterFadeDuration(0.3f));
+ assertEquals((Float) layer.getRasterFadeDuration().getValue(), (Float) 0.3f);
+ }
- @After
- public void unregisterIntentServiceIdlingResource() {
- Espresso.unregisterIdlingResources(idlingResource);
- }
+ @After
+ public void unregisterIntentServiceIdlingResource() {
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleBackgroundLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleBackgroundLayerTest.java
index f562a5d8a3..762ae4f846 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleBackgroundLayerTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleBackgroundLayerTest.java
@@ -3,7 +3,8 @@ package com.mapbox.mapboxsdk.testapp.style;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import android.test.ActivityInstrumentationTestCase2;
-import android.util.Log;
+
+import timber.log.Timber;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
@@ -22,40 +23,39 @@ import org.junit.runner.RunWith;
*/
@RunWith(AndroidJUnit4.class)
public class RuntimeStyleBackgroundLayerTest
- extends ActivityInstrumentationTestCase2<RuntimeStyleTestActivity> {
- private static final String TAG = RuntimeStyleBackgroundLayerTest.class.getSimpleName();
-
- public RuntimeStyleBackgroundLayerTest() {
- super(RuntimeStyleTestActivity.class);
- }
-
- @Before
- public void setUp() throws Exception {
- super.setUp();
- injectInstrumentation(InstrumentationRegistry.getInstrumentation());
- }
-
- @Test
- public void testSetVisibility() {
- getActivity().mapView.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(MapboxMap mapboxMap) {
- Log.i(TAG, "visibility");
- BackgroundLayer layer = mapboxMap.getLayerAs("background");
- assertNotNull(layer);
-
- //Get initial
- assertEquals(layer.getVisibility().getValue(), Property.VISIBLE);
-
- //Set
- layer.setProperties(PropertyFactory.visibility(Property.NONE));
- assertEquals(layer.getVisibility().getValue(), Property.NONE);
- }
- });
- }
-
- @After
- public void tearDown() throws Exception {
- super.tearDown();
- }
+ extends ActivityInstrumentationTestCase2<RuntimeStyleTestActivity> {
+
+ public RuntimeStyleBackgroundLayerTest() {
+ super(RuntimeStyleTestActivity.class);
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ injectInstrumentation(InstrumentationRegistry.getInstrumentation());
+ }
+
+ @Test
+ public void testSetVisibility() {
+ getActivity().mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(MapboxMap mapboxMap) {
+ Timber.i("visibility");
+ BackgroundLayer layer = mapboxMap.getLayerAs("background");
+ assertNotNull(layer);
+
+ //Get initial
+ assertEquals(layer.getVisibility().getValue(), Property.VISIBLE);
+
+ //Set
+ layer.setProperties(PropertyFactory.visibility(Property.NONE));
+ assertEquals(layer.getVisibility().getValue(), Property.NONE);
+ }
+ });
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleTests.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleTests.java
index 783601b1dd..eec00bdde9 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleTests.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleTests.java
@@ -1,100 +1,201 @@
package com.mapbox.mapboxsdk.testapp.style;
+import android.graphics.Color;
import android.support.test.espresso.Espresso;
+import android.support.test.espresso.UiController;
+import android.support.test.espresso.ViewAction;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
+import android.view.View;
import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.style.layers.CannotAddLayerException;
import com.mapbox.mapboxsdk.style.layers.FillLayer;
import com.mapbox.mapboxsdk.style.layers.NoSuchLayerException;
import com.mapbox.mapboxsdk.style.layers.Property;
import com.mapbox.mapboxsdk.style.layers.PropertyFactory;
+import com.mapbox.mapboxsdk.style.sources.CannotAddSourceException;
import com.mapbox.mapboxsdk.style.sources.NoSuchSourceException;
+import com.mapbox.mapboxsdk.style.sources.Source;
import com.mapbox.mapboxsdk.style.sources.VectorSource;
import com.mapbox.mapboxsdk.testapp.R;
import com.mapbox.mapboxsdk.testapp.activity.style.RuntimeStyleTestActivity;
import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource;
+import com.mapbox.mapboxsdk.testapp.utils.ViewUtils;
+import junit.framework.Assert;
+
+import org.hamcrest.Matcher;
import org.junit.After;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import static org.junit.Assert.assertFalse;
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static junit.framework.Assert.fail;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
/**
* Basic smoke tests for Layer and Source
*/
@RunWith(AndroidJUnit4.class)
-public class RuntimeStyleTests extends BaseStyleTest {
+public class RuntimeStyleTests {
+
+ @Rule
+ public final ActivityTestRule<RuntimeStyleTestActivity> rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class);
+
+ private OnMapReadyIdlingResource idlingResource;
+
+ @Before
+ public void registerIdlingResource() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ }
+
+ @Test
+ public void testGetAddRemoveLayer() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+ onView(withId(R.id.mapView)).perform(new AddRemoveLayerAction());
+ }
+
+ @Test
+ public void testAddRemoveSource() {
+ ViewUtils.checkViewIsDisplayed(R.id.mapView);
+
+ MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+ mapboxMap.addSource(new VectorSource("my-source", "mapbox://mapbox.mapbox-terrain-v2"));
+ try {
+ mapboxMap.removeSource("my-source");
+ } catch (NoSuchSourceException noSuchSourceException) {
+ // it's ok..
+ }
+
+ onView(withId(R.id.mapView)).perform(new AddRemoveSourceAction());
+ }
+
+ private class AddRemoveLayerAction implements ViewAction {
- @Rule
- public final ActivityTestRule<RuntimeStyleTestActivity> rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class);
+ @Override
+ public Matcher<View> getConstraints() {
+ return isDisplayed();
+ }
- private OnMapReadyIdlingResource idlingResource;
+ @Override
+ public String getDescription() {
+ return getClass().getSimpleName();
+ }
- @Before
- public void registerIdlingResource() {
- idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
- Espresso.registerIdlingResources(idlingResource);
+ @Override
+ public void perform(UiController uiController, View view) {
+ MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ //Get initial
+ assertNotNull(mapboxMap.getLayer("building"));
+
+ //Remove
+ try {
+ mapboxMap.removeLayer("building");
+ } catch (NoSuchLayerException noSuchSourceException) {
+ fail("Definitively exists: " + noSuchSourceException.getMessage());
+ }
+ assertNull(mapboxMap.getLayer("building"));
+
+ //Add
+ FillLayer layer = new FillLayer("building", "composite");
+ layer.setSourceLayer("building");
+ mapboxMap.addLayer(layer);
+ assertNotNull(mapboxMap.getLayer("building"));
+
+ //Assure the reference still works
+ layer.setProperties(PropertyFactory.visibility(Property.VISIBLE));
+
+ //Remove, preserving the reference
+ try {
+ mapboxMap.removeLayer(layer);
+ } catch (NoSuchLayerException noSuchSourceException) {
+ fail("Definitively exists: " + noSuchSourceException.getMessage());
+ }
+
+ //Property setters should still work
+ layer.setProperties(PropertyFactory.fillColor(Color.RED));
+
+ //Re-add the reference...
+ mapboxMap.addLayer(layer);
+
+ //Ensure it's there
+ Assert.assertNotNull(mapboxMap.getLayer(layer.getId()));
+
+ //Test adding a duplicate layer
+ try {
+ mapboxMap.addLayer(new FillLayer("building", "composite"));
+ fail("Should not have been allowed to add a layer with a duplicate id");
+ } catch (CannotAddLayerException cannotAddLayerException) {
+ //OK
+ }
}
+ }
- /**
- * TODO fix failing test
- */
- @Test
- @Ignore
- public void testGetAddRemoveLayer() {
- checkViewIsDisplayed(R.id.mapView);
-
- MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
-
- //Get initial
- assertNotNull(mapboxMap.getLayer("building"));
-
- //Remove
- try {
- mapboxMap.removeLayer("building");
- } catch (NoSuchLayerException e) {
- assertFalse(true);
- }
- assertNull(mapboxMap.getLayer("building"));
-
- //Add
- FillLayer layer = new FillLayer("building", "composite");
- layer.setSourceLayer("building");
- mapboxMap.addLayer(layer);
-
- assertNotNull(mapboxMap.getLayer("building"));
-
- try {
- layer.setProperties(PropertyFactory.visibility(Property.VISIBLE));
- assertTrue("Never reached as the reference is invalid after adding", false);
- } catch (Exception e) {
- //Expected, reference is no longer valid
- }
+ private class AddRemoveSourceAction implements ViewAction {
+
+ @Override
+ public Matcher<View> getConstraints() {
+ return isDisplayed();
}
- @Test
- public void testAddRemoveSource() {
- checkViewIsDisplayed(R.id.mapView);
-
- MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
- mapboxMap.addSource(new VectorSource("my-source", "mapbox://mapbox.mapbox-terrain-v2"));
- try {
- mapboxMap.removeSource("my-source");
- } catch (NoSuchSourceException e) {
- // it's ok..
- }
+ @Override
+ public String getDescription() {
+ return getClass().getSimpleName();
}
- @After
- public void unregisterIntentServiceIdlingResource() {
- Espresso.unregisterIdlingResources(idlingResource);
+ @Override
+ public void perform(UiController uiController, View view) {
+ MapboxMap mapboxMap = rule.getActivity().getMapboxMap();
+
+ //Add initial source
+ mapboxMap.addSource(new VectorSource("my-source", "mapbox://mapbox.mapbox-terrain-v2"));
+
+ //Remove
+ try {
+ mapboxMap.removeSource("my-source");
+ } catch (NoSuchSourceException noSuchSourceException) {
+ fail("Definitively exists: " + noSuchSourceException.getMessage());
+ }
+ assertNull(mapboxMap.getLayer("my-source"));
+
+ //Add
+ Source source = new VectorSource("my-source", "mapbox://mapbox.mapbox-terrain-v2");
+ mapboxMap.addSource(source);
+
+ //Remove, preserving the reference
+ try {
+ mapboxMap.removeSource(source);
+ } catch (NoSuchSourceException noSuchSourceException) {
+ fail("Definitively exists: " + noSuchSourceException.getMessage());
+ }
+
+ //Re-add the reference...
+ mapboxMap.addSource(source);
+
+ //Ensure it's there
+ Assert.assertNotNull(mapboxMap.getSource(source.getId()));
+
+ //Test adding a duplicate source
+ try {
+ Source source2 = new VectorSource("my-source", "mapbox://mapbox.mapbox-terrain-v2");
+ mapboxMap.addSource(source2);
+ fail("Should not have been allowed to add a source with a duplicate id");
+ } catch (CannotAddSourceException cannotAddSourceException) {
+ //OK
+ }
}
+ }
+
+ @After
+ public void unregisterIntentServiceIdlingResource() {
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleTimingTests.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleTimingTests.java
index 0282e1bcd0..57b0fe72ff 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleTimingTests.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/RuntimeStyleTimingTests.java
@@ -20,25 +20,26 @@ import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class RuntimeStyleTimingTests extends BaseStyleTest {
- @Rule
- public final ActivityTestRule<RuntimeStyleTimingTestActivity> rule = new ActivityTestRule<>(RuntimeStyleTimingTestActivity.class);
-
- private OnMapReadyIdlingResource idlingResource;
-
- @Before
- public void registerIdlingResource() {
- idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
- Espresso.registerIdlingResources(idlingResource);
- }
-
- @Test
- public void testGetAddRemoveLayer() {
- checkViewIsDisplayed(R.id.mapView);
- //We're good if it didn't crash
- }
-
- @After
- public void unregisterIntentServiceIdlingResource() {
- Espresso.unregisterIdlingResources(idlingResource);
- }
+ @Rule
+ public final ActivityTestRule<RuntimeStyleTimingTestActivity> rule =
+ new ActivityTestRule<>(RuntimeStyleTimingTestActivity.class);
+
+ private OnMapReadyIdlingResource idlingResource;
+
+ @Before
+ public void registerIdlingResource() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ }
+
+ @Test
+ public void testGetAddRemoveLayer() {
+ checkViewIsDisplayed(R.id.mapView);
+ //We're good if it didn't crash
+ }
+
+ @After
+ public void unregisterIntentServiceIdlingResource() {
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerStyleTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerStyleTest.java
index 7132705ca9..5b59d4ceae 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerStyleTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerStyleTest.java
@@ -1,11 +1,10 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
package com.mapbox.mapboxsdk.testapp.style;
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
import android.graphics.Color;
import android.support.test.espresso.Espresso;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
-import android.util.Log;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.style.layers.SymbolLayer;
@@ -19,1204 +18,1266 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import static org.junit.Assert.*;
-import static com.mapbox.mapboxsdk.style.layers.Property.*;
-import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*;
+import timber.log.Timber;
+
+import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_MAP;
+import static com.mapbox.mapboxsdk.style.layers.Property.ICON_TEXT_FIT_NONE;
+import static com.mapbox.mapboxsdk.style.layers.Property.ICON_TRANSLATE_ANCHOR_MAP;
+import static com.mapbox.mapboxsdk.style.layers.Property.NONE;
+import static com.mapbox.mapboxsdk.style.layers.Property.SYMBOL_PLACEMENT_POINT;
+import static com.mapbox.mapboxsdk.style.layers.Property.TEXT_ANCHOR_CENTER;
+import static com.mapbox.mapboxsdk.style.layers.Property.TEXT_JUSTIFY_LEFT;
+import static com.mapbox.mapboxsdk.style.layers.Property.TEXT_PITCH_ALIGNMENT_MAP;
+import static com.mapbox.mapboxsdk.style.layers.Property.TEXT_ROTATION_ALIGNMENT_MAP;
+import static com.mapbox.mapboxsdk.style.layers.Property.TEXT_TRANSFORM_NONE;
+import static com.mapbox.mapboxsdk.style.layers.Property.TEXT_TRANSLATE_ANCHOR_MAP;
+import static com.mapbox.mapboxsdk.style.layers.Property.VISIBLE;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconAllowOverlap;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconColor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconHaloBlur;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconHaloColor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconHaloWidth;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconIgnorePlacement;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconImage;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconKeepUpright;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconOffset;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconOpacity;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconOptional;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconPadding;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconRotate;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconRotationAlignment;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconSize;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconTextFit;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconTextFitPadding;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconTranslate;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconTranslateAnchor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.symbolAvoidEdges;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.symbolPlacement;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.symbolSpacing;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textAllowOverlap;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textAnchor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textColor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textField;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textFont;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textHaloBlur;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textHaloColor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textHaloWidth;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textIgnorePlacement;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textJustify;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textKeepUpright;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textLetterSpacing;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textLineHeight;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textMaxAngle;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textMaxWidth;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textOffset;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textOpacity;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textOptional;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textPadding;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textPitchAlignment;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textRotate;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textRotationAlignment;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textSize;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textTransform;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textTranslate;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textTranslateAnchor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.visibility;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
/**
* Basic smoke tests for SymbolLayer
*/
@RunWith(AndroidJUnit4.class)
public class SymbolLayerStyleTest extends BaseStyleTest {
- private static final String TAG = SymbolLayerStyleTest.class.getSimpleName();
- @Rule
- public final ActivityTestRule<RuntimeStyleTestActivity> rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class);
+ @Rule
+ public final ActivityTestRule<RuntimeStyleTestActivity> rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class);
- private SymbolLayer layer;
+ private SymbolLayer layer;
- private OnMapReadyIdlingResource idlingResource;
+ private OnMapReadyIdlingResource idlingResource;
- private MapboxMap mapboxMap;
+ private MapboxMap mapboxMap;
- @Before
- public void setup() {
- idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
- Espresso.registerIdlingResources(idlingResource);
- }
+ @Before
+ public void setup() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ }
- @Test
- public void testSetVisibility() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "visibility");
- assertNotNull(layer);
-
- //Get initial
- assertEquals(layer.getVisibility().getValue(), VISIBLE);
-
- //Set
- layer.setProperties(visibility(NONE));
- assertEquals(layer.getVisibility().getValue(), NONE);
- }
+ @Test
+ public void testSetVisibility() {
+ checkViewIsDisplayed(R.id.mapView);
- @Test
- public void testSymbolPlacement() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "symbol-placement");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(symbolPlacement(SYMBOL_PLACEMENT_POINT));
- assertEquals((String) layer.getSymbolPlacement().getValue(), (String) SYMBOL_PLACEMENT_POINT);
- }
+ mapboxMap = rule.getActivity().getMapboxMap();
- @Test
- public void testSymbolSpacing() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "symbol-spacing");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(symbolSpacing(0.3f));
- assertEquals((Float) layer.getSymbolSpacing().getValue(), (Float) 0.3f);
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testSymbolAvoidEdges() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "symbol-avoid-edges");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(symbolAvoidEdges(true));
- assertEquals((Boolean) layer.getSymbolAvoidEdges().getValue(), (Boolean) true);
+ Timber.i("visibility");
+ assertNotNull(layer);
+
+ //Get initial
+ assertEquals(layer.getVisibility().getValue(), VISIBLE);
+
+ //Set
+ layer.setProperties(visibility(NONE));
+ assertEquals(layer.getVisibility().getValue(), NONE);
+ }
+
+ @Test
+ public void testSymbolPlacement() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconAllowOverlap() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-allow-overlap");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconAllowOverlap(true));
- assertEquals((Boolean) layer.getIconAllowOverlap().getValue(), (Boolean) true);
+ Timber.i("symbol-placement");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(symbolPlacement(SYMBOL_PLACEMENT_POINT));
+ assertEquals((String) layer.getSymbolPlacement().getValue(), (String) SYMBOL_PLACEMENT_POINT);
+ }
+
+ @Test
+ public void testSymbolSpacing() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconIgnorePlacement() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-ignore-placement");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconIgnorePlacement(true));
- assertEquals((Boolean) layer.getIconIgnorePlacement().getValue(), (Boolean) true);
+ Timber.i("symbol-spacing");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(symbolSpacing(0.3f));
+ assertEquals((Float) layer.getSymbolSpacing().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testSymbolAvoidEdges() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconOptional() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-optional");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconOptional(true));
- assertEquals((Boolean) layer.getIconOptional().getValue(), (Boolean) true);
+ Timber.i("symbol-avoid-edges");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(symbolAvoidEdges(true));
+ assertEquals((Boolean) layer.getSymbolAvoidEdges().getValue(), (Boolean) true);
+ }
+
+ @Test
+ public void testIconAllowOverlap() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconRotationAlignment() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-rotation-alignment");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconRotationAlignment(ICON_ROTATION_ALIGNMENT_MAP));
- assertEquals((String) layer.getIconRotationAlignment().getValue(), (String) ICON_ROTATION_ALIGNMENT_MAP);
+ Timber.i("icon-allow-overlap");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconAllowOverlap(true));
+ assertEquals((Boolean) layer.getIconAllowOverlap().getValue(), (Boolean) true);
+ }
+
+ @Test
+ public void testIconIgnorePlacement() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconSize() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-size");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconSize(0.3f));
- assertEquals((Float) layer.getIconSize().getValue(), (Float) 0.3f);
+ Timber.i("icon-ignore-placement");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconIgnorePlacement(true));
+ assertEquals((Boolean) layer.getIconIgnorePlacement().getValue(), (Boolean) true);
+ }
+
+ @Test
+ public void testIconOptional() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconTextFit() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-text-fit");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconTextFit(ICON_TEXT_FIT_NONE));
- assertEquals((String) layer.getIconTextFit().getValue(), (String) ICON_TEXT_FIT_NONE);
+ Timber.i("icon-optional");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconOptional(true));
+ assertEquals((Boolean) layer.getIconOptional().getValue(), (Boolean) true);
+ }
+
+ @Test
+ public void testIconRotationAlignment() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconTextFitPadding() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-text-fit-padding");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconTextFitPadding(new Float[]{0f,0f,0f,0f}));
- assertEquals((Float[]) layer.getIconTextFitPadding().getValue(), (Float[]) new Float[]{0f,0f,0f,0f});
+ Timber.i("icon-rotation-alignment");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconRotationAlignment(ICON_ROTATION_ALIGNMENT_MAP));
+ assertEquals((String) layer.getIconRotationAlignment().getValue(), (String) ICON_ROTATION_ALIGNMENT_MAP);
+ }
+
+ @Test
+ public void testIconSize() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconImage() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-image");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconImage("undefined"));
- assertEquals((String) layer.getIconImage().getValue(), (String) "undefined");
+ Timber.i("icon-size");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconSize(0.3f));
+ assertEquals((Float) layer.getIconSize().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testIconTextFit() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconRotate() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-rotate");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconRotate(0.3f));
- assertEquals((Float) layer.getIconRotate().getValue(), (Float) 0.3f);
+ Timber.i("icon-text-fit");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconTextFit(ICON_TEXT_FIT_NONE));
+ assertEquals((String) layer.getIconTextFit().getValue(), (String) ICON_TEXT_FIT_NONE);
+ }
+
+ @Test
+ public void testIconTextFitPadding() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconPadding() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-padding");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconPadding(0.3f));
- assertEquals((Float) layer.getIconPadding().getValue(), (Float) 0.3f);
+ Timber.i("icon-text-fit-padding");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconTextFitPadding(new Float[] {0f, 0f, 0f, 0f}));
+ assertEquals((Float[]) layer.getIconTextFitPadding().getValue(), (Float[]) new Float[] {0f, 0f, 0f, 0f});
+ }
+
+ @Test
+ public void testIconImage() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconKeepUpright() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-keep-upright");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconKeepUpright(true));
- assertEquals((Boolean) layer.getIconKeepUpright().getValue(), (Boolean) true);
+ Timber.i("icon-image");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconImage("undefined"));
+ assertEquals((String) layer.getIconImage().getValue(), (String) "undefined");
+ }
+
+ @Test
+ public void testIconRotate() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconOffset() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-offset");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconOffset(new Float[]{0f,0f}));
- assertEquals((Float[]) layer.getIconOffset().getValue(), (Float[]) new Float[]{0f,0f});
+ Timber.i("icon-rotate");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconRotate(0.3f));
+ assertEquals((Float) layer.getIconRotate().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testIconPadding() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextPitchAlignment() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-pitch-alignment");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textPitchAlignment(TEXT_PITCH_ALIGNMENT_MAP));
- assertEquals((String) layer.getTextPitchAlignment().getValue(), (String) TEXT_PITCH_ALIGNMENT_MAP);
+ Timber.i("icon-padding");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconPadding(0.3f));
+ assertEquals((Float) layer.getIconPadding().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testIconKeepUpright() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextRotationAlignment() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-rotation-alignment");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textRotationAlignment(TEXT_ROTATION_ALIGNMENT_MAP));
- assertEquals((String) layer.getTextRotationAlignment().getValue(), (String) TEXT_ROTATION_ALIGNMENT_MAP);
+ Timber.i("icon-keep-upright");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconKeepUpright(true));
+ assertEquals((Boolean) layer.getIconKeepUpright().getValue(), (Boolean) true);
+ }
+
+ @Test
+ public void testIconOffset() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextField() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-field");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textField(""));
- assertEquals((String) layer.getTextField().getValue(), (String) "");
+ Timber.i("icon-offset");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconOffset(new Float[] {0f, 0f}));
+ assertEquals((Float[]) layer.getIconOffset().getValue(), (Float[]) new Float[] {0f, 0f});
+ }
+
+ @Test
+ public void testTextPitchAlignment() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextFont() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-font");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textFont(new String[]{"Open Sans Regular", "Arial Unicode MS Regular"}));
- assertEquals((String[]) layer.getTextFont().getValue(), (String[]) new String[]{"Open Sans Regular", "Arial Unicode MS Regular"});
+ Timber.i("text-pitch-alignment");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textPitchAlignment(TEXT_PITCH_ALIGNMENT_MAP));
+ assertEquals((String) layer.getTextPitchAlignment().getValue(), (String) TEXT_PITCH_ALIGNMENT_MAP);
+ }
+
+ @Test
+ public void testTextRotationAlignment() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextSize() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-size");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textSize(0.3f));
- assertEquals((Float) layer.getTextSize().getValue(), (Float) 0.3f);
+ Timber.i("text-rotation-alignment");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textRotationAlignment(TEXT_ROTATION_ALIGNMENT_MAP));
+ assertEquals((String) layer.getTextRotationAlignment().getValue(), (String) TEXT_ROTATION_ALIGNMENT_MAP);
+ }
+
+ @Test
+ public void testTextField() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextMaxWidth() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-max-width");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textMaxWidth(0.3f));
- assertEquals((Float) layer.getTextMaxWidth().getValue(), (Float) 0.3f);
+ Timber.i("text-field");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textField(""));
+ assertEquals((String) layer.getTextField().getValue(), (String) "");
+ }
+
+ @Test
+ public void testTextFont() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextLineHeight() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-line-height");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textLineHeight(0.3f));
- assertEquals((Float) layer.getTextLineHeight().getValue(), (Float) 0.3f);
+ Timber.i("text-font");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textFont(new String[] {"Open Sans Regular", "Arial Unicode MS Regular"}));
+ assertEquals((String[]) layer.getTextFont().getValue(), (String[]) new String[] {"Open Sans Regular",
+ "Arial Unicode MS Regular"});
+ }
+
+ @Test
+ public void testTextSize() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextLetterSpacing() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-letter-spacing");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textLetterSpacing(0.3f));
- assertEquals((Float) layer.getTextLetterSpacing().getValue(), (Float) 0.3f);
+ Timber.i("text-size");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textSize(0.3f));
+ assertEquals((Float) layer.getTextSize().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testTextMaxWidth() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextJustify() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-justify");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textJustify(TEXT_JUSTIFY_LEFT));
- assertEquals((String) layer.getTextJustify().getValue(), (String) TEXT_JUSTIFY_LEFT);
+ Timber.i("text-max-width");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textMaxWidth(0.3f));
+ assertEquals((Float) layer.getTextMaxWidth().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testTextLineHeight() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextAnchor() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-anchor");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textAnchor(TEXT_ANCHOR_CENTER));
- assertEquals((String) layer.getTextAnchor().getValue(), (String) TEXT_ANCHOR_CENTER);
+ Timber.i("text-line-height");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textLineHeight(0.3f));
+ assertEquals((Float) layer.getTextLineHeight().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testTextLetterSpacing() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextMaxAngle() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-max-angle");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textMaxAngle(0.3f));
- assertEquals((Float) layer.getTextMaxAngle().getValue(), (Float) 0.3f);
+ Timber.i("text-letter-spacing");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textLetterSpacing(0.3f));
+ assertEquals((Float) layer.getTextLetterSpacing().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testTextJustify() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextRotate() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-rotate");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textRotate(0.3f));
- assertEquals((Float) layer.getTextRotate().getValue(), (Float) 0.3f);
+ Timber.i("text-justify");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textJustify(TEXT_JUSTIFY_LEFT));
+ assertEquals((String) layer.getTextJustify().getValue(), (String) TEXT_JUSTIFY_LEFT);
+ }
+
+ @Test
+ public void testTextAnchor() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextPadding() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-padding");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textPadding(0.3f));
- assertEquals((Float) layer.getTextPadding().getValue(), (Float) 0.3f);
+ Timber.i("text-anchor");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textAnchor(TEXT_ANCHOR_CENTER));
+ assertEquals((String) layer.getTextAnchor().getValue(), (String) TEXT_ANCHOR_CENTER);
+ }
+
+ @Test
+ public void testTextMaxAngle() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextKeepUpright() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-keep-upright");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textKeepUpright(true));
- assertEquals((Boolean) layer.getTextKeepUpright().getValue(), (Boolean) true);
+ Timber.i("text-max-angle");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textMaxAngle(0.3f));
+ assertEquals((Float) layer.getTextMaxAngle().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testTextRotate() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextTransform() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-transform");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textTransform(TEXT_TRANSFORM_NONE));
- assertEquals((String) layer.getTextTransform().getValue(), (String) TEXT_TRANSFORM_NONE);
+ Timber.i("text-rotate");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textRotate(0.3f));
+ assertEquals((Float) layer.getTextRotate().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testTextPadding() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextOffset() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-offset");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textOffset(new Float[]{0f,0f}));
- assertEquals((Float[]) layer.getTextOffset().getValue(), (Float[]) new Float[]{0f,0f});
+ Timber.i("text-padding");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textPadding(0.3f));
+ assertEquals((Float) layer.getTextPadding().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testTextKeepUpright() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextAllowOverlap() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-allow-overlap");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textAllowOverlap(true));
- assertEquals((Boolean) layer.getTextAllowOverlap().getValue(), (Boolean) true);
+ Timber.i("text-keep-upright");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textKeepUpright(true));
+ assertEquals((Boolean) layer.getTextKeepUpright().getValue(), (Boolean) true);
+ }
+
+ @Test
+ public void testTextTransform() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextIgnorePlacement() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-ignore-placement");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textIgnorePlacement(true));
- assertEquals((Boolean) layer.getTextIgnorePlacement().getValue(), (Boolean) true);
+ Timber.i("text-transform");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textTransform(TEXT_TRANSFORM_NONE));
+ assertEquals((String) layer.getTextTransform().getValue(), (String) TEXT_TRANSFORM_NONE);
+ }
+
+ @Test
+ public void testTextOffset() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextOptional() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-optional");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textOptional(true));
- assertEquals((Boolean) layer.getTextOptional().getValue(), (Boolean) true);
+ Timber.i("text-offset");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textOffset(new Float[] {0f, 0f}));
+ assertEquals((Float[]) layer.getTextOffset().getValue(), (Float[]) new Float[] {0f, 0f});
+ }
+
+ @Test
+ public void testTextAllowOverlap() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconOpacity() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-opacity");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconOpacity(0.3f));
- assertEquals((Float) layer.getIconOpacity().getValue(), (Float) 0.3f);
+ Timber.i("text-allow-overlap");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textAllowOverlap(true));
+ assertEquals((Boolean) layer.getTextAllowOverlap().getValue(), (Boolean) true);
+ }
+
+ @Test
+ public void testTextIgnorePlacement() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconColor() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconColor("rgba(0, 0, 0, 1)"));
- assertEquals((String) layer.getIconColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ Timber.i("text-ignore-placement");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textIgnorePlacement(true));
+ assertEquals((Boolean) layer.getTextIgnorePlacement().getValue(), (Boolean) true);
+ }
+
+ @Test
+ public void testTextOptional() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconColorAsInt() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconColor(Color.RED));
- assertEquals(layer.getIconColorAsInt(), Color.RED);
+ Timber.i("text-optional");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textOptional(true));
+ assertEquals((Boolean) layer.getTextOptional().getValue(), (Boolean) true);
+ }
+
+ @Test
+ public void testIconOpacity() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconHaloColor() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-halo-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconHaloColor("rgba(0, 0, 0, 1)"));
- assertEquals((String) layer.getIconHaloColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ Timber.i("icon-opacity");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconOpacity(0.3f));
+ assertEquals((Float) layer.getIconOpacity().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testIconColor() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconHaloColorAsInt() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-halo-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconHaloColor(Color.RED));
- assertEquals(layer.getIconHaloColorAsInt(), Color.RED);
+ Timber.i("icon-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconColor("rgba(0, 0, 0, 1)"));
+ assertEquals((String) layer.getIconColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ }
+
+ @Test
+ public void testIconColorAsInt() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconHaloWidth() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-halo-width");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconHaloWidth(0.3f));
- assertEquals((Float) layer.getIconHaloWidth().getValue(), (Float) 0.3f);
+ Timber.i("icon-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconColor(Color.RED));
+ assertEquals(layer.getIconColorAsInt(), Color.RED);
+ }
+
+ @Test
+ public void testIconHaloColor() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconHaloBlur() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-halo-blur");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconHaloBlur(0.3f));
- assertEquals((Float) layer.getIconHaloBlur().getValue(), (Float) 0.3f);
+ Timber.i("icon-halo-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconHaloColor("rgba(0, 0, 0, 1)"));
+ assertEquals((String) layer.getIconHaloColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ }
+
+ @Test
+ public void testIconHaloColorAsInt() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconTranslate() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-translate");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconTranslate(new Float[]{0f,0f}));
- assertEquals((Float[]) layer.getIconTranslate().getValue(), (Float[]) new Float[]{0f,0f});
+ Timber.i("icon-halo-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconHaloColor(Color.RED));
+ assertEquals(layer.getIconHaloColorAsInt(), Color.RED);
+ }
+
+ @Test
+ public void testIconHaloWidth() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconTranslateAnchor() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-translate-anchor");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconTranslateAnchor(ICON_TRANSLATE_ANCHOR_MAP));
- assertEquals((String) layer.getIconTranslateAnchor().getValue(), (String) ICON_TRANSLATE_ANCHOR_MAP);
+ Timber.i("icon-halo-width");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconHaloWidth(0.3f));
+ assertEquals((Float) layer.getIconHaloWidth().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testIconHaloBlur() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextOpacity() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-opacity");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textOpacity(0.3f));
- assertEquals((Float) layer.getTextOpacity().getValue(), (Float) 0.3f);
+ Timber.i("icon-halo-blur");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconHaloBlur(0.3f));
+ assertEquals((Float) layer.getIconHaloBlur().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testIconTranslate() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextColor() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textColor("rgba(0, 0, 0, 1)"));
- assertEquals((String) layer.getTextColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ Timber.i("icon-translate");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconTranslate(new Float[] {0f, 0f}));
+ assertEquals((Float[]) layer.getIconTranslate().getValue(), (Float[]) new Float[] {0f, 0f});
+ }
+
+ @Test
+ public void testIconTranslateAnchor() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextColorAsInt() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textColor(Color.RED));
- assertEquals(layer.getTextColorAsInt(), Color.RED);
+ Timber.i("icon-translate-anchor");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconTranslateAnchor(ICON_TRANSLATE_ANCHOR_MAP));
+ assertEquals((String) layer.getIconTranslateAnchor().getValue(), (String) ICON_TRANSLATE_ANCHOR_MAP);
+ }
+
+ @Test
+ public void testTextOpacity() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextHaloColor() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-halo-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textHaloColor("rgba(0, 0, 0, 1)"));
- assertEquals((String) layer.getTextHaloColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ Timber.i("text-opacity");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textOpacity(0.3f));
+ assertEquals((Float) layer.getTextOpacity().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testTextColor() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextHaloColorAsInt() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-halo-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textHaloColor(Color.RED));
- assertEquals(layer.getTextHaloColorAsInt(), Color.RED);
+ Timber.i("text-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textColor("rgba(0, 0, 0, 1)"));
+ assertEquals((String) layer.getTextColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ }
+
+ @Test
+ public void testTextColorAsInt() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextHaloWidth() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-halo-width");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textHaloWidth(0.3f));
- assertEquals((Float) layer.getTextHaloWidth().getValue(), (Float) 0.3f);
+ Timber.i("text-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textColor(Color.RED));
+ assertEquals(layer.getTextColorAsInt(), Color.RED);
+ }
+
+ @Test
+ public void testTextHaloColor() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextHaloBlur() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-halo-blur");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textHaloBlur(0.3f));
- assertEquals((Float) layer.getTextHaloBlur().getValue(), (Float) 0.3f);
+ Timber.i("text-halo-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textHaloColor("rgba(0, 0, 0, 1)"));
+ assertEquals((String) layer.getTextHaloColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ }
+
+ @Test
+ public void testTextHaloColorAsInt() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextTranslate() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-translate");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textTranslate(new Float[]{0f,0f}));
- assertEquals((Float[]) layer.getTextTranslate().getValue(), (Float[]) new Float[]{0f,0f});
+ Timber.i("text-halo-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textHaloColor(Color.RED));
+ assertEquals(layer.getTextHaloColorAsInt(), Color.RED);
+ }
+
+ @Test
+ public void testTextHaloWidth() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextTranslateAnchor() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-translate-anchor");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textTranslateAnchor(TEXT_TRANSLATE_ANCHOR_MAP));
- assertEquals((String) layer.getTextTranslateAnchor().getValue(), (String) TEXT_TRANSLATE_ANCHOR_MAP);
+ Timber.i("text-halo-width");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textHaloWidth(0.3f));
+ assertEquals((Float) layer.getTextHaloWidth().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testTextHaloBlur() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
+ Timber.i("text-halo-blur");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textHaloBlur(0.3f));
+ assertEquals((Float) layer.getTextHaloBlur().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testTextTranslate() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
+ }
+ Timber.i("text-translate");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textTranslate(new Float[] {0f, 0f}));
+ assertEquals((Float[]) layer.getTextTranslate().getValue(), (Float[]) new Float[] {0f, 0f});
+ }
+
+ @Test
+ public void testTextTranslateAnchor() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
+ }
+ Timber.i("text-translate-anchor");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textTranslateAnchor(TEXT_TRANSLATE_ANCHOR_MAP));
+ assertEquals((String) layer.getTextTranslateAnchor().getValue(), (String) TEXT_TRANSLATE_ANCHOR_MAP);
+ }
- @After
- public void unregisterIntentServiceIdlingResource() {
- Espresso.unregisterIdlingResources(idlingResource);
- }
+ @After
+ public void unregisterIntentServiceIdlingResource() {
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java
index 5bc3f597c1..f4c50a2ffb 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/SymbolLayerTest.java
@@ -1,11 +1,10 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
package com.mapbox.mapboxsdk.testapp.style;
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
import android.graphics.Color;
import android.support.test.espresso.Espresso;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
-import android.util.Log;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.style.layers.SymbolLayer;
@@ -19,1204 +18,1266 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import static org.junit.Assert.*;
-import static com.mapbox.mapboxsdk.style.layers.Property.*;
-import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*;
+import timber.log.Timber;
+
+import static com.mapbox.mapboxsdk.style.layers.Property.ICON_ROTATION_ALIGNMENT_MAP;
+import static com.mapbox.mapboxsdk.style.layers.Property.ICON_TEXT_FIT_NONE;
+import static com.mapbox.mapboxsdk.style.layers.Property.ICON_TRANSLATE_ANCHOR_MAP;
+import static com.mapbox.mapboxsdk.style.layers.Property.NONE;
+import static com.mapbox.mapboxsdk.style.layers.Property.SYMBOL_PLACEMENT_POINT;
+import static com.mapbox.mapboxsdk.style.layers.Property.TEXT_ANCHOR_CENTER;
+import static com.mapbox.mapboxsdk.style.layers.Property.TEXT_JUSTIFY_LEFT;
+import static com.mapbox.mapboxsdk.style.layers.Property.TEXT_PITCH_ALIGNMENT_MAP;
+import static com.mapbox.mapboxsdk.style.layers.Property.TEXT_ROTATION_ALIGNMENT_MAP;
+import static com.mapbox.mapboxsdk.style.layers.Property.TEXT_TRANSFORM_NONE;
+import static com.mapbox.mapboxsdk.style.layers.Property.TEXT_TRANSLATE_ANCHOR_MAP;
+import static com.mapbox.mapboxsdk.style.layers.Property.VISIBLE;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconAllowOverlap;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconColor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconHaloBlur;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconHaloColor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconHaloWidth;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconIgnorePlacement;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconImage;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconKeepUpright;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconOffset;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconOpacity;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconOptional;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconPadding;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconRotate;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconRotationAlignment;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconSize;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconTextFit;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconTextFitPadding;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconTranslate;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconTranslateAnchor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.symbolAvoidEdges;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.symbolPlacement;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.symbolSpacing;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textAllowOverlap;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textAnchor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textColor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textField;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textFont;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textHaloBlur;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textHaloColor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textHaloWidth;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textIgnorePlacement;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textJustify;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textKeepUpright;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textLetterSpacing;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textLineHeight;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textMaxAngle;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textMaxWidth;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textOffset;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textOpacity;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textOptional;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textPadding;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textPitchAlignment;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textRotate;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textRotationAlignment;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textSize;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textTransform;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textTranslate;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textTranslateAnchor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.visibility;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
/**
* Basic smoke tests for SymbolLayer
*/
@RunWith(AndroidJUnit4.class)
public class SymbolLayerTest extends BaseStyleTest {
- private static final String TAG = SymbolLayerTest.class.getSimpleName();
- @Rule
- public final ActivityTestRule<RuntimeStyleTestActivity> rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class);
+ @Rule
+ public final ActivityTestRule<RuntimeStyleTestActivity> rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class);
- private SymbolLayer layer;
+ private SymbolLayer layer;
- private OnMapReadyIdlingResource idlingResource;
+ private OnMapReadyIdlingResource idlingResource;
- private MapboxMap mapboxMap;
+ private MapboxMap mapboxMap;
- @Before
- public void setup() {
- idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
- Espresso.registerIdlingResources(idlingResource);
- }
+ @Before
+ public void setup() {
+ idlingResource = new OnMapReadyIdlingResource(rule.getActivity());
+ Espresso.registerIdlingResources(idlingResource);
+ }
- @Test
- public void testSetVisibility() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "visibility");
- assertNotNull(layer);
-
- //Get initial
- assertEquals(layer.getVisibility().getValue(), VISIBLE);
-
- //Set
- layer.setProperties(visibility(NONE));
- assertEquals(layer.getVisibility().getValue(), NONE);
- }
+ @Test
+ public void testSetVisibility() {
+ checkViewIsDisplayed(R.id.mapView);
- @Test
- public void testSymbolPlacement() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "symbol-placement");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(symbolPlacement(SYMBOL_PLACEMENT_POINT));
- assertEquals((String) layer.getSymbolPlacement().getValue(), (String) SYMBOL_PLACEMENT_POINT);
- }
+ mapboxMap = rule.getActivity().getMapboxMap();
- @Test
- public void testSymbolSpacing() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "symbol-spacing");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(symbolSpacing(0.3f));
- assertEquals((Float) layer.getSymbolSpacing().getValue(), (Float) 0.3f);
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testSymbolAvoidEdges() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "symbol-avoid-edges");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(symbolAvoidEdges(true));
- assertEquals((Boolean) layer.getSymbolAvoidEdges().getValue(), (Boolean) true);
+ Timber.i("visibility");
+ assertNotNull(layer);
+
+ //Get initial
+ assertEquals(layer.getVisibility().getValue(), VISIBLE);
+
+ //Set
+ layer.setProperties(visibility(NONE));
+ assertEquals(layer.getVisibility().getValue(), NONE);
+ }
+
+ @Test
+ public void testSymbolPlacement() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconAllowOverlap() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-allow-overlap");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconAllowOverlap(true));
- assertEquals((Boolean) layer.getIconAllowOverlap().getValue(), (Boolean) true);
+ Timber.i("symbol-placement");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(symbolPlacement(SYMBOL_PLACEMENT_POINT));
+ assertEquals((String) layer.getSymbolPlacement().getValue(), (String) SYMBOL_PLACEMENT_POINT);
+ }
+
+ @Test
+ public void testSymbolSpacing() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconIgnorePlacement() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-ignore-placement");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconIgnorePlacement(true));
- assertEquals((Boolean) layer.getIconIgnorePlacement().getValue(), (Boolean) true);
+ Timber.i("symbol-spacing");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(symbolSpacing(0.3f));
+ assertEquals((Float) layer.getSymbolSpacing().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testSymbolAvoidEdges() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconOptional() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-optional");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconOptional(true));
- assertEquals((Boolean) layer.getIconOptional().getValue(), (Boolean) true);
+ Timber.i("symbol-avoid-edges");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(symbolAvoidEdges(true));
+ assertEquals((Boolean) layer.getSymbolAvoidEdges().getValue(), (Boolean) true);
+ }
+
+ @Test
+ public void testIconAllowOverlap() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconRotationAlignment() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-rotation-alignment");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconRotationAlignment(ICON_ROTATION_ALIGNMENT_MAP));
- assertEquals((String) layer.getIconRotationAlignment().getValue(), (String) ICON_ROTATION_ALIGNMENT_MAP);
+ Timber.i("icon-allow-overlap");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconAllowOverlap(true));
+ assertEquals((Boolean) layer.getIconAllowOverlap().getValue(), (Boolean) true);
+ }
+
+ @Test
+ public void testIconIgnorePlacement() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconSize() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-size");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconSize(0.3f));
- assertEquals((Float) layer.getIconSize().getValue(), (Float) 0.3f);
+ Timber.i("icon-ignore-placement");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconIgnorePlacement(true));
+ assertEquals((Boolean) layer.getIconIgnorePlacement().getValue(), (Boolean) true);
+ }
+
+ @Test
+ public void testIconOptional() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconTextFit() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-text-fit");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconTextFit(ICON_TEXT_FIT_NONE));
- assertEquals((String) layer.getIconTextFit().getValue(), (String) ICON_TEXT_FIT_NONE);
+ Timber.i("icon-optional");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconOptional(true));
+ assertEquals((Boolean) layer.getIconOptional().getValue(), (Boolean) true);
+ }
+
+ @Test
+ public void testIconRotationAlignment() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconTextFitPadding() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-text-fit-padding");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconTextFitPadding(new Float[]{0f,0f,0f,0f}));
- assertEquals((Float[]) layer.getIconTextFitPadding().getValue(), (Float[]) new Float[]{0f,0f,0f,0f});
+ Timber.i("icon-rotation-alignment");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconRotationAlignment(ICON_ROTATION_ALIGNMENT_MAP));
+ assertEquals((String) layer.getIconRotationAlignment().getValue(), (String) ICON_ROTATION_ALIGNMENT_MAP);
+ }
+
+ @Test
+ public void testIconSize() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconImage() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-image");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconImage("undefined"));
- assertEquals((String) layer.getIconImage().getValue(), (String) "undefined");
+ Timber.i("icon-size");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconSize(0.3f));
+ assertEquals((Float) layer.getIconSize().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testIconTextFit() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconRotate() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-rotate");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconRotate(0.3f));
- assertEquals((Float) layer.getIconRotate().getValue(), (Float) 0.3f);
+ Timber.i("icon-text-fit");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconTextFit(ICON_TEXT_FIT_NONE));
+ assertEquals((String) layer.getIconTextFit().getValue(), (String) ICON_TEXT_FIT_NONE);
+ }
+
+ @Test
+ public void testIconTextFitPadding() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconPadding() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-padding");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconPadding(0.3f));
- assertEquals((Float) layer.getIconPadding().getValue(), (Float) 0.3f);
+ Timber.i("icon-text-fit-padding");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconTextFitPadding(new Float[] {0f, 0f, 0f, 0f}));
+ assertEquals((Float[]) layer.getIconTextFitPadding().getValue(), (Float[]) new Float[] {0f, 0f, 0f, 0f});
+ }
+
+ @Test
+ public void testIconImage() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconKeepUpright() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-keep-upright");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconKeepUpright(true));
- assertEquals((Boolean) layer.getIconKeepUpright().getValue(), (Boolean) true);
+ Timber.i("icon-image");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconImage("undefined"));
+ assertEquals((String) layer.getIconImage().getValue(), (String) "undefined");
+ }
+
+ @Test
+ public void testIconRotate() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconOffset() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-offset");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconOffset(new Float[]{0f,0f}));
- assertEquals((Float[]) layer.getIconOffset().getValue(), (Float[]) new Float[]{0f,0f});
+ Timber.i("icon-rotate");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconRotate(0.3f));
+ assertEquals((Float) layer.getIconRotate().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testIconPadding() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextPitchAlignment() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-pitch-alignment");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textPitchAlignment(TEXT_PITCH_ALIGNMENT_MAP));
- assertEquals((String) layer.getTextPitchAlignment().getValue(), (String) TEXT_PITCH_ALIGNMENT_MAP);
+ Timber.i("icon-padding");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconPadding(0.3f));
+ assertEquals((Float) layer.getIconPadding().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testIconKeepUpright() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextRotationAlignment() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-rotation-alignment");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textRotationAlignment(TEXT_ROTATION_ALIGNMENT_MAP));
- assertEquals((String) layer.getTextRotationAlignment().getValue(), (String) TEXT_ROTATION_ALIGNMENT_MAP);
+ Timber.i("icon-keep-upright");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconKeepUpright(true));
+ assertEquals((Boolean) layer.getIconKeepUpright().getValue(), (Boolean) true);
+ }
+
+ @Test
+ public void testIconOffset() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextField() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-field");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textField(""));
- assertEquals((String) layer.getTextField().getValue(), (String) "");
+ Timber.i("icon-offset");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconOffset(new Float[] {0f, 0f}));
+ assertEquals((Float[]) layer.getIconOffset().getValue(), (Float[]) new Float[] {0f, 0f});
+ }
+
+ @Test
+ public void testTextPitchAlignment() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextFont() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-font");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textFont(new String[]{"Open Sans Regular", "Arial Unicode MS Regular"}));
- assertEquals((String[]) layer.getTextFont().getValue(), (String[]) new String[]{"Open Sans Regular", "Arial Unicode MS Regular"});
+ Timber.i("text-pitch-alignment");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textPitchAlignment(TEXT_PITCH_ALIGNMENT_MAP));
+ assertEquals((String) layer.getTextPitchAlignment().getValue(), (String) TEXT_PITCH_ALIGNMENT_MAP);
+ }
+
+ @Test
+ public void testTextRotationAlignment() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextSize() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-size");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textSize(0.3f));
- assertEquals((Float) layer.getTextSize().getValue(), (Float) 0.3f);
+ Timber.i("text-rotation-alignment");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textRotationAlignment(TEXT_ROTATION_ALIGNMENT_MAP));
+ assertEquals((String) layer.getTextRotationAlignment().getValue(), (String) TEXT_ROTATION_ALIGNMENT_MAP);
+ }
+
+ @Test
+ public void testTextField() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextMaxWidth() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-max-width");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textMaxWidth(0.3f));
- assertEquals((Float) layer.getTextMaxWidth().getValue(), (Float) 0.3f);
+ Timber.i("text-field");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textField(""));
+ assertEquals((String) layer.getTextField().getValue(), (String) "");
+ }
+
+ @Test
+ public void testTextFont() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextLineHeight() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-line-height");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textLineHeight(0.3f));
- assertEquals((Float) layer.getTextLineHeight().getValue(), (Float) 0.3f);
+ Timber.i("text-font");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textFont(new String[] {"Open Sans Regular", "Arial Unicode MS Regular"}));
+ assertEquals((String[]) layer.getTextFont().getValue(), (String[]) new String[] {"Open Sans Regular",
+ "Arial Unicode MS Regular"});
+ }
+
+ @Test
+ public void testTextSize() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextLetterSpacing() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-letter-spacing");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textLetterSpacing(0.3f));
- assertEquals((Float) layer.getTextLetterSpacing().getValue(), (Float) 0.3f);
+ Timber.i("text-size");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textSize(0.3f));
+ assertEquals((Float) layer.getTextSize().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testTextMaxWidth() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextJustify() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-justify");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textJustify(TEXT_JUSTIFY_LEFT));
- assertEquals((String) layer.getTextJustify().getValue(), (String) TEXT_JUSTIFY_LEFT);
+ Timber.i("text-max-width");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textMaxWidth(0.3f));
+ assertEquals((Float) layer.getTextMaxWidth().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testTextLineHeight() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextAnchor() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-anchor");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textAnchor(TEXT_ANCHOR_CENTER));
- assertEquals((String) layer.getTextAnchor().getValue(), (String) TEXT_ANCHOR_CENTER);
+ Timber.i("text-line-height");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textLineHeight(0.3f));
+ assertEquals((Float) layer.getTextLineHeight().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testTextLetterSpacing() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextMaxAngle() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-max-angle");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textMaxAngle(0.3f));
- assertEquals((Float) layer.getTextMaxAngle().getValue(), (Float) 0.3f);
+ Timber.i("text-letter-spacing");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textLetterSpacing(0.3f));
+ assertEquals((Float) layer.getTextLetterSpacing().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testTextJustify() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextRotate() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-rotate");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textRotate(0.3f));
- assertEquals((Float) layer.getTextRotate().getValue(), (Float) 0.3f);
+ Timber.i("text-justify");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textJustify(TEXT_JUSTIFY_LEFT));
+ assertEquals((String) layer.getTextJustify().getValue(), (String) TEXT_JUSTIFY_LEFT);
+ }
+
+ @Test
+ public void testTextAnchor() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextPadding() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-padding");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textPadding(0.3f));
- assertEquals((Float) layer.getTextPadding().getValue(), (Float) 0.3f);
+ Timber.i("text-anchor");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textAnchor(TEXT_ANCHOR_CENTER));
+ assertEquals((String) layer.getTextAnchor().getValue(), (String) TEXT_ANCHOR_CENTER);
+ }
+
+ @Test
+ public void testTextMaxAngle() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextKeepUpright() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-keep-upright");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textKeepUpright(true));
- assertEquals((Boolean) layer.getTextKeepUpright().getValue(), (Boolean) true);
+ Timber.i("text-max-angle");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textMaxAngle(0.3f));
+ assertEquals((Float) layer.getTextMaxAngle().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testTextRotate() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextTransform() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-transform");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textTransform(TEXT_TRANSFORM_NONE));
- assertEquals((String) layer.getTextTransform().getValue(), (String) TEXT_TRANSFORM_NONE);
+ Timber.i("text-rotate");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textRotate(0.3f));
+ assertEquals((Float) layer.getTextRotate().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testTextPadding() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextOffset() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-offset");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textOffset(new Float[]{0f,0f}));
- assertEquals((Float[]) layer.getTextOffset().getValue(), (Float[]) new Float[]{0f,0f});
+ Timber.i("text-padding");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textPadding(0.3f));
+ assertEquals((Float) layer.getTextPadding().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testTextKeepUpright() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextAllowOverlap() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-allow-overlap");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textAllowOverlap(true));
- assertEquals((Boolean) layer.getTextAllowOverlap().getValue(), (Boolean) true);
+ Timber.i("text-keep-upright");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textKeepUpright(true));
+ assertEquals((Boolean) layer.getTextKeepUpright().getValue(), (Boolean) true);
+ }
+
+ @Test
+ public void testTextTransform() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextIgnorePlacement() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-ignore-placement");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textIgnorePlacement(true));
- assertEquals((Boolean) layer.getTextIgnorePlacement().getValue(), (Boolean) true);
+ Timber.i("text-transform");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textTransform(TEXT_TRANSFORM_NONE));
+ assertEquals((String) layer.getTextTransform().getValue(), (String) TEXT_TRANSFORM_NONE);
+ }
+
+ @Test
+ public void testTextOffset() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextOptional() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-optional");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textOptional(true));
- assertEquals((Boolean) layer.getTextOptional().getValue(), (Boolean) true);
+ Timber.i("text-offset");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textOffset(new Float[] {0f, 0f}));
+ assertEquals((Float[]) layer.getTextOffset().getValue(), (Float[]) new Float[] {0f, 0f});
+ }
+
+ @Test
+ public void testTextAllowOverlap() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconOpacity() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-opacity");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconOpacity(0.3f));
- assertEquals((Float) layer.getIconOpacity().getValue(), (Float) 0.3f);
+ Timber.i("text-allow-overlap");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textAllowOverlap(true));
+ assertEquals((Boolean) layer.getTextAllowOverlap().getValue(), (Boolean) true);
+ }
+
+ @Test
+ public void testTextIgnorePlacement() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconColor() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconColor("rgba(0, 0, 0, 1)"));
- assertEquals((String) layer.getIconColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ Timber.i("text-ignore-placement");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textIgnorePlacement(true));
+ assertEquals((Boolean) layer.getTextIgnorePlacement().getValue(), (Boolean) true);
+ }
+
+ @Test
+ public void testTextOptional() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconColorAsInt() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconColor(Color.RED));
- assertEquals(layer.getIconColorAsInt(), Color.RED);
+ Timber.i("text-optional");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textOptional(true));
+ assertEquals((Boolean) layer.getTextOptional().getValue(), (Boolean) true);
+ }
+
+ @Test
+ public void testIconOpacity() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconHaloColor() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-halo-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconHaloColor("rgba(0, 0, 0, 1)"));
- assertEquals((String) layer.getIconHaloColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ Timber.i("icon-opacity");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconOpacity(0.3f));
+ assertEquals((Float) layer.getIconOpacity().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testIconColor() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconHaloColorAsInt() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-halo-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconHaloColor(Color.RED));
- assertEquals(layer.getIconHaloColorAsInt(), Color.RED);
+ Timber.i("icon-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconColor("rgba(0, 0, 0, 1)"));
+ assertEquals((String) layer.getIconColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ }
+
+ @Test
+ public void testIconColorAsInt() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconHaloWidth() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-halo-width");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconHaloWidth(0.3f));
- assertEquals((Float) layer.getIconHaloWidth().getValue(), (Float) 0.3f);
+ Timber.i("icon-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconColor(Color.RED));
+ assertEquals(layer.getIconColorAsInt(), Color.RED);
+ }
+
+ @Test
+ public void testIconHaloColor() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconHaloBlur() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-halo-blur");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconHaloBlur(0.3f));
- assertEquals((Float) layer.getIconHaloBlur().getValue(), (Float) 0.3f);
+ Timber.i("icon-halo-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconHaloColor("rgba(0, 0, 0, 1)"));
+ assertEquals((String) layer.getIconHaloColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ }
+
+ @Test
+ public void testIconHaloColorAsInt() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconTranslate() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-translate");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconTranslate(new Float[]{0f,0f}));
- assertEquals((Float[]) layer.getIconTranslate().getValue(), (Float[]) new Float[]{0f,0f});
+ Timber.i("icon-halo-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconHaloColor(Color.RED));
+ assertEquals(layer.getIconHaloColorAsInt(), Color.RED);
+ }
+
+ @Test
+ public void testIconHaloWidth() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testIconTranslateAnchor() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "icon-translate-anchor");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(iconTranslateAnchor(ICON_TRANSLATE_ANCHOR_MAP));
- assertEquals((String) layer.getIconTranslateAnchor().getValue(), (String) ICON_TRANSLATE_ANCHOR_MAP);
+ Timber.i("icon-halo-width");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconHaloWidth(0.3f));
+ assertEquals((Float) layer.getIconHaloWidth().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testIconHaloBlur() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextOpacity() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-opacity");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textOpacity(0.3f));
- assertEquals((Float) layer.getTextOpacity().getValue(), (Float) 0.3f);
+ Timber.i("icon-halo-blur");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconHaloBlur(0.3f));
+ assertEquals((Float) layer.getIconHaloBlur().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testIconTranslate() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextColor() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textColor("rgba(0, 0, 0, 1)"));
- assertEquals((String) layer.getTextColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ Timber.i("icon-translate");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconTranslate(new Float[] {0f, 0f}));
+ assertEquals((Float[]) layer.getIconTranslate().getValue(), (Float[]) new Float[] {0f, 0f});
+ }
+
+ @Test
+ public void testIconTranslateAnchor() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextColorAsInt() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textColor(Color.RED));
- assertEquals(layer.getTextColorAsInt(), Color.RED);
+ Timber.i("icon-translate-anchor");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(iconTranslateAnchor(ICON_TRANSLATE_ANCHOR_MAP));
+ assertEquals((String) layer.getIconTranslateAnchor().getValue(), (String) ICON_TRANSLATE_ANCHOR_MAP);
+ }
+
+ @Test
+ public void testTextOpacity() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextHaloColor() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-halo-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textHaloColor("rgba(0, 0, 0, 1)"));
- assertEquals((String) layer.getTextHaloColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ Timber.i("text-opacity");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textOpacity(0.3f));
+ assertEquals((Float) layer.getTextOpacity().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testTextColor() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextHaloColorAsInt() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-halo-color");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textHaloColor(Color.RED));
- assertEquals(layer.getTextHaloColorAsInt(), Color.RED);
+ Timber.i("text-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textColor("rgba(0, 0, 0, 1)"));
+ assertEquals((String) layer.getTextColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ }
+
+ @Test
+ public void testTextColorAsInt() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextHaloWidth() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-halo-width");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textHaloWidth(0.3f));
- assertEquals((Float) layer.getTextHaloWidth().getValue(), (Float) 0.3f);
+ Timber.i("text-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textColor(Color.RED));
+ assertEquals(layer.getTextColorAsInt(), Color.RED);
+ }
+
+ @Test
+ public void testTextHaloColor() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextHaloBlur() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-halo-blur");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textHaloBlur(0.3f));
- assertEquals((Float) layer.getTextHaloBlur().getValue(), (Float) 0.3f);
+ Timber.i("text-halo-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textHaloColor("rgba(0, 0, 0, 1)"));
+ assertEquals((String) layer.getTextHaloColor().getValue(), (String) "rgba(0, 0, 0, 1)");
+ }
+
+ @Test
+ public void testTextHaloColorAsInt() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextTranslate() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-translate");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textTranslate(new Float[]{0f,0f}));
- assertEquals((Float[]) layer.getTextTranslate().getValue(), (Float[]) new Float[]{0f,0f});
+ Timber.i("text-halo-color");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textHaloColor(Color.RED));
+ assertEquals(layer.getTextHaloColorAsInt(), Color.RED);
+ }
+
+ @Test
+ public void testTextHaloWidth() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
-
- @Test
- public void testTextTranslateAnchor() {
- checkViewIsDisplayed(R.id.mapView);
-
- mapboxMap = rule.getActivity().getMapboxMap();
-
- if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
- layer = new SymbolLayer("my-layer", "composite");
- layer.setSourceLayer("composite");
- mapboxMap.addLayer(layer);
- //Layer reference is now stale, get new reference
- layer = mapboxMap.getLayerAs("my-layer");
- }
- Log.i(TAG, "text-translate-anchor");
- assertNotNull(layer);
-
- //Set and Get
- layer.setProperties(textTranslateAnchor(TEXT_TRANSLATE_ANCHOR_MAP));
- assertEquals((String) layer.getTextTranslateAnchor().getValue(), (String) TEXT_TRANSLATE_ANCHOR_MAP);
+ Timber.i("text-halo-width");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textHaloWidth(0.3f));
+ assertEquals((Float) layer.getTextHaloWidth().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testTextHaloBlur() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
}
+ Timber.i("text-halo-blur");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textHaloBlur(0.3f));
+ assertEquals((Float) layer.getTextHaloBlur().getValue(), (Float) 0.3f);
+ }
+
+ @Test
+ public void testTextTranslate() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
+ }
+ Timber.i("text-translate");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textTranslate(new Float[] {0f, 0f}));
+ assertEquals((Float[]) layer.getTextTranslate().getValue(), (Float[]) new Float[] {0f, 0f});
+ }
+
+ @Test
+ public void testTextTranslateAnchor() {
+ checkViewIsDisplayed(R.id.mapView);
+
+ mapboxMap = rule.getActivity().getMapboxMap();
+
+ if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
+ Timber.i("Adding layer");
+ layer = new SymbolLayer("my-layer", "composite");
+ layer.setSourceLayer("composite");
+ mapboxMap.addLayer(layer);
+ //Layer reference is now stale, get new reference
+ layer = mapboxMap.getLayerAs("my-layer");
+ }
+ Timber.i("text-translate-anchor");
+ assertNotNull(layer);
+
+ //Set and Get
+ layer.setProperties(textTranslateAnchor(TEXT_TRANSLATE_ANCHOR_MAP));
+ assertEquals((String) layer.getTextTranslateAnchor().getValue(), (String) TEXT_TRANSLATE_ANCHOR_MAP);
+ }
- @After
- public void unregisterIntentServiceIdlingResource() {
- Espresso.unregisterIdlingResources(idlingResource);
- }
+ @After
+ public void unregisterIntentServiceIdlingResource() {
+ Espresso.unregisterIdlingResources(idlingResource);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/layer.junit.ejs b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/layer.junit.ejs
index bc0d22bb25..3b81b0805b 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/layer.junit.ejs
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/layer.junit.ejs
@@ -2,14 +2,14 @@
const type = locals.type;
const properties = locals.properties;
-%>
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
package com.mapbox.mapboxsdk.testapp.style;
import android.graphics.Color;
import android.support.test.espresso.Espresso;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
-import android.util.Log;
+import timber.log.Timber;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.style.layers.<%- camelize(type) %>Layer;
@@ -32,7 +32,6 @@ import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*;
*/
@RunWith(AndroidJUnit4.class)
public class <%- camelize(type) %>LayerTest extends BaseStyleTest {
- private static final String TAG = <%- camelize(type) %>LayerTest.class.getSimpleName();
@Rule
public final ActivityTestRule<RuntimeStyleTestActivity> rule = new ActivityTestRule<>(RuntimeStyleTestActivity.class);
@@ -56,11 +55,11 @@ public class <%- camelize(type) %>LayerTest extends BaseStyleTest {
mapboxMap = rule.getActivity().getMapboxMap();
<% if (type === 'background') { -%>
- Log.i(TAG, "Retrieving layer");
+ Timber.i("Retrieving layer");
layer = mapboxMap.getLayerAs("background");
<% } else { -%>
if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
+ Timber.i("Adding layer");
layer = new <%- camelize(type) %>Layer("my-layer", "composite");
layer.setSourceLayer("composite");
mapboxMap.addLayer(layer);
@@ -68,7 +67,7 @@ public class <%- camelize(type) %>LayerTest extends BaseStyleTest {
layer = mapboxMap.getLayerAs("my-layer");
}
<% } -%>
- Log.i(TAG, "visibility");
+ Timber.i("visibility");
assertNotNull(layer);
//Get initial
@@ -87,11 +86,11 @@ public class <%- camelize(type) %>LayerTest extends BaseStyleTest {
mapboxMap = rule.getActivity().getMapboxMap();
<% if (type === 'background') { -%>
- Log.i(TAG, "Retrieving layer");
+ Timber.i("Retrieving layer");
layer = mapboxMap.getLayerAs("background");
<% } else { -%>
if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
+ Timber.i("Adding layer");
layer = new <%- camelize(type) %>Layer("my-layer", "composite");
layer.setSourceLayer("composite");
mapboxMap.addLayer(layer);
@@ -99,7 +98,7 @@ public class <%- camelize(type) %>LayerTest extends BaseStyleTest {
layer = mapboxMap.getLayerAs("my-layer");
}
<% } -%>
- Log.i(TAG, "<%- property.name %>");
+ Timber.i("<%- property.name %>");
assertNotNull(layer);
//Set and Get
@@ -115,11 +114,11 @@ public class <%- camelize(type) %>LayerTest extends BaseStyleTest {
mapboxMap = rule.getActivity().getMapboxMap();
<% if (type === 'background') { -%>
- Log.i(TAG, "Retrieving layer");
+ Timber.i("Retrieving layer");
layer = mapboxMap.getLayerAs("background");
<% } else { -%>
if ((layer = mapboxMap.getLayerAs("my-layer")) == null) {
- Log.i(TAG, "Adding layer");
+ Timber.i("Adding layer");
layer = new <%- camelize(type) %>Layer("my-layer", "composite");
layer.setSourceLayer("composite");
mapboxMap.addLayer(layer);
@@ -127,7 +126,7 @@ public class <%- camelize(type) %>LayerTest extends BaseStyleTest {
layer = mapboxMap.getLayerAs("my-layer");
}
<% } -%>
- Log.i(TAG, "<%- property.name %>");
+ Timber.i("<%- property.name %>");
assertNotNull(layer);
//Set and Get
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/DrawerUtils.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/DrawerUtils.java
index 8d8905fdf4..d9ced47369 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/DrawerUtils.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/DrawerUtils.java
@@ -15,15 +15,15 @@ import static android.support.test.espresso.matcher.ViewMatchers.withContentDesc
public class DrawerUtils {
- private final static String HOME_BUTTON_STRING = "Navigate up";
+ private static final String HOME_BUTTON_STRING = "Navigate up";
- public static void openDrawer(){
- onView(withContentDescription(HOME_BUTTON_STRING)).perform(click());
- }
+ public static void openDrawer() {
+ onView(withContentDescription(HOME_BUTTON_STRING)).perform(click());
+ }
- public static void clickItem(@StringRes int txtId){
- Espresso.onView(Matchers.allOf(ViewMatchers.withId(R.id.design_menu_item_text),
- ViewMatchers.hasSibling(ViewMatchers.withText(txtId)))).perform(ViewActions.click());
- }
+ public static void clickItem(@StringRes int txtId) {
+ Espresso.onView(Matchers.allOf(ViewMatchers.withId(R.id.design_menu_item_text),
+ ViewMatchers.hasSibling(ViewMatchers.withText(txtId)))).perform(ViewActions.click());
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/GestureUtils.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/GestureUtils.java
index 114fbc549e..3376f5eda4 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/GestureUtils.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/GestureUtils.java
@@ -8,8 +8,8 @@ import static android.support.test.espresso.matcher.ViewMatchers.withId;
public class GestureUtils {
- public static void doubleClickGesture(@IdRes int id){
- onView(withId(id)).perform(doubleClick());
- }
+ public static void doubleClickGesture(@IdRes int id) {
+ onView(withId(id)).perform(doubleClick());
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/OnMapReadyIdlingResource.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/OnMapReadyIdlingResource.java
index c966f61f8c..6e582c6a3a 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/OnMapReadyIdlingResource.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/OnMapReadyIdlingResource.java
@@ -2,56 +2,56 @@ package com.mapbox.mapboxsdk.testapp.utils;
import android.app.Activity;
import android.support.test.espresso.IdlingResource;
-import android.util.Log;
-import com.mapbox.mapboxsdk.constants.MapboxConstants;
+import timber.log.Timber;
+
import com.mapbox.mapboxsdk.maps.MapboxMap;
import java.lang.reflect.Field;
public class OnMapReadyIdlingResource implements IdlingResource {
- private final Activity activity;
- private MapboxMap mapboxMap;
- private IdlingResource.ResourceCallback resourceCallback;
+ private final Activity activity;
+ private MapboxMap mapboxMap;
+ private IdlingResource.ResourceCallback resourceCallback;
- public OnMapReadyIdlingResource(Activity activity) {
- this.activity = activity;
- }
+ public OnMapReadyIdlingResource(Activity activity) {
+ this.activity = activity;
+ }
- @Override
- public String getName() {
- return getClass().getSimpleName();
- }
+ @Override
+ public String getName() {
+ return getClass().getSimpleName();
+ }
- @Override
- public boolean isIdleNow() {
- boolean idle = isMapboxMapReady();
- if (idle && resourceCallback != null) {
- resourceCallback.onTransitionToIdle();
- }
- return idle;
+ @Override
+ public boolean isIdleNow() {
+ boolean idle = isMapboxMapReady();
+ if (idle && resourceCallback != null) {
+ resourceCallback.onTransitionToIdle();
}
-
- @Override
- public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
- this.resourceCallback = resourceCallback;
+ return idle;
+ }
+
+ @Override
+ public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
+ this.resourceCallback = resourceCallback;
+ }
+
+ private boolean isMapboxMapReady() {
+ try {
+ Field field = activity.getClass().getDeclaredField("mapboxMap");
+ field.setAccessible(true);
+ mapboxMap = (MapboxMap) field.get(activity);
+ Timber.e("isMapboxReady called with value " + (mapboxMap != null));
+ return mapboxMap != null;
+ } catch (Exception exception) {
+ Timber.e("could not reflect", exception);
+ return false;
}
+ }
- private boolean isMapboxMapReady() {
- try {
- Field field = activity.getClass().getDeclaredField("mapboxMap");
- field.setAccessible(true);
- mapboxMap = (MapboxMap) field.get(activity);
- Log.e(MapboxConstants.TAG, "isMapboxReady called with value " + (mapboxMap != null));
- return mapboxMap != null;
- } catch (Exception e) {
- Log.e(MapboxConstants.TAG, "could not reflect", e);
- return false;
- }
- }
-
- public MapboxMap getMapboxMap() {
- return mapboxMap;
- }
+ public MapboxMap getMapboxMap() {
+ return mapboxMap;
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/ScreenshotUtil.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/ScreenshotUtil.java
index 8fedf38619..77bfc519bf 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/ScreenshotUtil.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/ScreenshotUtil.java
@@ -4,7 +4,9 @@ import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.os.Environment;
-import android.util.Log;
+
+import timber.log.Timber;
+
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
@@ -23,114 +25,113 @@ import java.util.UUID;
*/
public class ScreenshotUtil {
- private static final String LOG_TAG = ScreenshotUtil.class.getName();
+ // Where to store the files. This path is required by AWS Device Farm:
+ // http://docs.aws.amazon.com/devicefarm/latest/developerguide/test-types-android-instrumentation.html
+ // #test-types-android-instrumentation-screenshots
+ private static final String SCREENSHOT_FOLDER = "test-screenshots";
- // Where to store the files. This path is required by AWS Device Farm:
- // http://docs.aws.amazon.com/devicefarm/latest/developerguide/test-types-android-instrumentation.html#test-types-android-instrumentation-screenshots
- private static final String SCREENSHOT_FOLDER = "test-screenshots";
+ // Image type and quality
+ private static final String DEFAULT_IMAGE_EXTENSION = ".png";
+ private static final Bitmap.CompressFormat DEFAULT_IMAGE_FORMAT = Bitmap.CompressFormat.PNG;
+ private static final int DEFAULT_IMAGE_QUALITY = 100;
- // Image type and quality
- private static final String DEFAULT_IMAGE_EXTENSION = ".png";
- private static final Bitmap.CompressFormat DEFAULT_IMAGE_FORMAT = Bitmap.CompressFormat.PNG;
- private static final int DEFAULT_IMAGE_QUALITY = 100;
+ public static void take(Activity activity, String testName) {
- public static void take(Activity activity, String testName) {
-
- // Check if storage is available
- if (!isExternalStorageWritable()) {
- Log.d(LOG_TAG, "External storage is not available.");
- return;
- }
+ // Check if storage is available
+ if (!isExternalStorageWritable()) {
+ Timber.d("External storage is not available.");
+ return;
+ }
- // Get a bitmap from the activity root view. When the drawing cache is enabled,
-// // the next call to getDrawingCache() will draw the view in a bitmap.
- View rootView = activity.getWindow().getDecorView().getRootView();
-// rootView.setDrawingCacheEnabled(true);r
-// rootView.setDrawingCacheEnabled(false);
-
- Bitmap bitmap = null;
-
- // Add the SurfaceView bit (see getAllTextureViews() below)
- List<TextureView> tilingViews = getAllTextureViews(rootView);
- if (tilingViews.size() > 0) {
- bitmap = Bitmap.createBitmap(tilingViews.get(0).getHeight(),tilingViews.get(0).getWidth(), Bitmap.Config.ARGB_8888);
- Canvas canvas = new Canvas(bitmap);
- for (TextureView TextureView : tilingViews) {
- Bitmap b = TextureView.getBitmap(TextureView.getWidth(), TextureView.getHeight());
- int[] location = new int[2];
- TextureView.getLocationInWindow(location);
- int[] location2 = new int[2];
- TextureView.getLocationOnScreen(location2);
- canvas.drawBitmap(b, 0,0, null);
- }
- }
+ // Get a bitmap from the activity root view. When the drawing cache is enabled,
+ // the next call to getDrawingCache() will draw the view in a bitmap.
+ View rootView = activity.getWindow().getDecorView().getRootView();
+ // rootView.setDrawingCacheEnabled(true);r
+ // rootView.setDrawingCacheEnabled(false);
+
+ Bitmap bitmap = null;
+
+ // Add the SurfaceView bit (see getAllTextureViews() below)
+ List<TextureView> tilingViews = getAllTextureViews(rootView);
+ if (tilingViews.size() > 0) {
+ bitmap = Bitmap.createBitmap(tilingViews.get(0).getHeight(), tilingViews.get(0).getWidth(),
+ Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(bitmap);
+ for (TextureView TextureView : tilingViews) {
+ Bitmap b = TextureView.getBitmap(TextureView.getWidth(), TextureView.getHeight());
+ int[] location = new int[2];
+ TextureView.getLocationInWindow(location);
+ int[] location2 = new int[2];
+ TextureView.getLocationOnScreen(location2);
+ canvas.drawBitmap(b, 0, 0, null);
+ }
+ }
- // Save the bitmap in external storage
- String uniqueAbsolutePath = getUniqueAbsolutePath(testName);
- File outputFile = new File(uniqueAbsolutePath);
- OutputStream outputStream = null;
+ // Save the bitmap in external storage
+ String uniqueAbsolutePath = getUniqueAbsolutePath(testName);
+ File outputFile = new File(uniqueAbsolutePath);
+ OutputStream outputStream = null;
+ try {
+ outputStream = new FileOutputStream(outputFile);
+ bitmap.compress(DEFAULT_IMAGE_FORMAT, DEFAULT_IMAGE_QUALITY, outputStream);
+ outputStream.flush();
+ } catch (Exception exception) {
+
+ exception.printStackTrace();
+ } finally {
+ if (outputStream != null) {
try {
- outputStream = new FileOutputStream(outputFile);
- bitmap.compress(DEFAULT_IMAGE_FORMAT, DEFAULT_IMAGE_QUALITY, outputStream);
- outputStream.flush();
- } catch (Exception e) {
-
- e.printStackTrace();
- } finally {
- if (outputStream != null) {
- try {
- outputStream.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
+ outputStream.close();
+ } catch (IOException ioException) {
+ ioException.printStackTrace();
}
+ }
}
-
- /*
- * The classic way of taking a screenshot (above) doesn't work with TextureView, this fixes it:
- * http://stackoverflow.com/questions/19704060/screen-capture-textureview-is-black-using-drawingcache
- */
-
- public static List<TextureView> getAllTextureViews(View view)
- {
- List<TextureView> tilingViews = new ArrayList<TextureView>();
- if (view instanceof TextureView) {
- tilingViews.add((TextureView)view);
- } else if(view instanceof ViewGroup) {
- ViewGroup viewGroup = (ViewGroup)view;
- for (int i = 0; i < viewGroup.getChildCount(); i++) {
- tilingViews.addAll(getAllTextureViews(viewGroup.getChildAt(i)));
- }
- }
-
- return tilingViews;
+ }
+
+ /*
+ * The classic way of taking a screenshot (above) doesn't work with TextureView, this fixes it:
+ * http://stackoverflow.com/questions/19704060/screen-capture-textureview-is-black-using-drawingcache
+ */
+
+ public static List<TextureView> getAllTextureViews(View view) {
+ List<TextureView> tilingViews = new ArrayList<TextureView>();
+ if (view instanceof TextureView) {
+ tilingViews.add((TextureView) view);
+ } else if (view instanceof ViewGroup) {
+ ViewGroup viewGroup = (ViewGroup) view;
+ for (int i = 0; i < viewGroup.getChildCount(); i++) {
+ tilingViews.addAll(getAllTextureViews(viewGroup.getChildAt(i)));
+ }
}
- /*
- * Utils
- */
+ return tilingViews;
+ }
- public static boolean isExternalStorageWritable() {
- // Checks if external storage is available for read and write
- String state = Environment.getExternalStorageState();
- return Environment.MEDIA_MOUNTED.equals(state);
- }
+ /*
+ * Utils
+ */
- private static String getUniqueAbsolutePath(String testName) {
- // A screenshot after every test vs. manual tests
- String filename = UUID.randomUUID().toString() + DEFAULT_IMAGE_EXTENSION;
- if (testName != null && !testName.isEmpty()) {
- filename = testName + DEFAULT_IMAGE_EXTENSION;
- }
+ public static boolean isExternalStorageWritable() {
+ // Checks if external storage is available for read and write
+ String state = Environment.getExternalStorageState();
+ return Environment.MEDIA_MOUNTED.equals(state);
+ }
- String externalPath = Environment.getExternalStorageDirectory().toString();
- String path = externalPath + File.separator + SCREENSHOT_FOLDER;
- File dir = new File(path);
- dir.mkdirs();
- path += File.separator + filename;
- Log.d(LOG_TAG, "Screenshot path: " + path);
- return path;
+ private static String getUniqueAbsolutePath(String testName) {
+ // A screenshot after every test vs. manual tests
+ String filename = UUID.randomUUID().toString() + DEFAULT_IMAGE_EXTENSION;
+ if (testName != null && !testName.isEmpty()) {
+ filename = testName + DEFAULT_IMAGE_EXTENSION;
}
+ String externalPath = Environment.getExternalStorageDirectory().toString();
+ String path = externalPath + File.separator + SCREENSHOT_FOLDER;
+ File dir = new File(path);
+ dir.mkdirs();
+ path += File.separator + filename;
+ Timber.d("Screenshot path: " + path);
+ return path;
+ }
+
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/TestConstants.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/TestConstants.java
new file mode 100644
index 0000000000..965f5d1443
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/TestConstants.java
@@ -0,0 +1,18 @@
+package com.mapbox.mapboxsdk.testapp.utils;
+
+import com.mapbox.mapboxsdk.constants.MapboxConstants;
+
+public class TestConstants {
+
+ public static final long ANIMATION_TEST_TIME = MapboxConstants.ANIMATION_DURATION * 2;
+
+ public static final double LAT_LNG_DELTA_LARGE = 0.1;
+ public static final double LAT_LNG_DELTA = 0.01;
+ public static final double BEARING_DELTA = 0.1;
+ public static final double TILT_DELTA = 0.1;
+ public static final double ZOOM_DELTA = 0.3;
+
+ public static final String TEXT_MARKER_TEXT = "Text";
+ public static final String TEXT_MARKER_TITLE = "Marker";
+ public static final String TEXT_MARKER_SNIPPET = "Snippet";
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/ViewUtils.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/ViewUtils.java
index 01ee3e9b9f..5c4d5a03c3 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/ViewUtils.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/utils/ViewUtils.java
@@ -4,12 +4,19 @@ import android.support.annotation.IdRes;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.assertion.ViewAssertions.matches;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
public class ViewUtils {
- public static void clickView(@IdRes int viewRes) {
- onView(withId(viewRes))
- .perform(click());
- }
+ public static void clickView(@IdRes int viewRes) {
+ onView(withId(viewRes))
+ .perform(click());
+ }
+
+ public static void checkViewIsDisplayed(int id) {
+ onView(withId(id))
+ .check(matches(isDisplayed()));
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
index c8a0de9826..cd1555b072 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
@@ -13,6 +13,7 @@
android:allowBackup="true"
android:fullBackupContent="true"
android:icon="@drawable/icon"
+ android:roundIcon="@drawable/ic_launcher_round"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
@@ -317,9 +318,9 @@
android:value="@string/category_fragment" />
</activity>
<activity
- android:name=".activity.maplayout.VideoViewActivity"
- android:description="@string/description_video_view"
- android:label="@string/activity_video_view">
+ android:name=".activity.maplayout.SimpleMapActivity"
+ android:description="@string/description_simple_map"
+ android:label="@string/activity_simple_map">
<meta-data
android:name="@string/category"
android:value="@string/category_maplayout" />
@@ -338,7 +339,15 @@
android:label="@string/activity_circle">
<meta-data
android:name="@string/category"
- android:value="@string/category_style" />
+ android:value="@string/category_style"/>
+ </activity>
+ <activity
+ android:name=".activity.style.SymbolLayerActivity"
+ android:description="@string/description_symbol_layer"
+ android:label="@string/activity_symbol_layer">
+ <meta-data
+ android:name="@string/category"
+ android:value="@string/category_style"/>
</activity>
<activity
android:name=".activity.style.GeoJsonClusteringActivity"
@@ -379,14 +388,6 @@
android:name="@string/category"
android:value="@string/category_imagegenerator" />
</activity>
- <activity
- android:name=".activity.maplayout.SurfaceViewMediaControlActivity"
- android:description="@string/description_surfaceview_mediacontrols"
- android:label="@string/activity_surfaceview_overlay">
- <meta-data
- android:name="@string/category"
- android:value="@string/category_maplayout" />
- </activity>
<!-- Features -->
<activity
@@ -406,6 +407,14 @@
android:value="@string/category_features" />
</activity>
<activity
+ android:name=".activity.feature.QueryRenderedFeaturesBoxSymbolCountActivity"
+ android:description="@string/description_query_rendered_features_box_symbol_count"
+ android:label="@string/activity_query_rendered_features_box_symbol_count">
+ <meta-data
+ android:name="@string/category"
+ android:value="@string/category_features" />
+ </activity>
+ <activity
android:name=".activity.feature.QueryRenderedFeaturesBoxHighlightActivity"
android:description="@string/description_query_rendered_features_box_highlight"
android:label="@string/activity_query_rendered_features_box_highlight">
@@ -437,10 +446,19 @@
android:name="@string/category"
android:value="@string/category_maplayout" />
</activity>
+ <activity
+ android:name=".activity.annotation.MarkerViewsInRectangleActivity"
+ android:description="@string/description_marker_view_rectangle"
+ android:label="@string/activity_marker_view_rectangle">
+ <meta-data
+ android:name="@string/category"
+ android:value="@string/category_annotation" />
+ </activity>
- <!-- For Unit tests -->
+ <!-- For Instrumentation tests -->
<activity android:name=".activity.style.RuntimeStyleTestActivity" />
<activity android:name=".activity.style.RuntimeStyleTimingTestActivity" />
+ <activity android:name=".activity.espresso.EspressoTestActivity" />
<!-- Configuration Settings -->
<meta-data
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 5b4c730cfb..a10c6eaad3 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
@@ -3,34 +3,46 @@ package com.mapbox.mapboxsdk.testapp;
import android.app.Application;
import android.os.StrictMode;
-import com.mapbox.mapboxsdk.MapboxAccountManager;
+import com.mapbox.mapboxsdk.Mapbox;
import com.squareup.leakcanary.LeakCanary;
+import timber.log.Timber;
+
+import static timber.log.Timber.DebugTree;
+
public class MapboxApplication extends Application {
- @Override
- public void onCreate() {
- super.onCreate();
-
- 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()
- .penaltyLog()
- .build());
- StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
- .detectLeakedSqlLiteObjects()
- .penaltyLog()
- .penaltyDeath()
- .build());
-
- MapboxAccountManager.start(getApplicationContext(), getString(R.string.mapbox_access_token));
+ @Override
+ public void onCreate() {
+ super.onCreate();
+
+ 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);
+
+ initializeLogger();
+
+ StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
+ .detectDiskReads()
+ .detectDiskWrites()
+ .detectNetwork()
+ .penaltyLog()
+ .build());
+ StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
+ .detectLeakedSqlLiteObjects()
+ .penaltyLog()
+ .penaltyDeath()
+ .build());
+
+ Mapbox.getInstance(getApplicationContext(), getString(R.string.mapbox_access_token));
+ }
+
+ private void initializeLogger() {
+ if (BuildConfig.DEBUG) {
+ Timber.plant(new DebugTree());
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/FeatureOverviewActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/FeatureOverviewActivity.java
index c3ade57986..9ba51e2694 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/FeatureOverviewActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/FeatureOverviewActivity.java
@@ -19,10 +19,11 @@ import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
-import android.util.Log;
+
+import timber.log.Timber;
+
import android.view.View;
-import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.testapp.R;
import com.mapbox.mapboxsdk.testapp.adapter.FeatureAdapter;
import com.mapbox.mapboxsdk.testapp.adapter.FeatureSectionAdapter;
@@ -36,199 +37,199 @@ import java.util.List;
public class FeatureOverviewActivity extends AppCompatActivity {
- private static final String KEY_STATE_FEATURES = "featureList";
+ private static final String KEY_STATE_FEATURES = "featureList";
- private RecyclerView recyclerView;
- private FeatureSectionAdapter sectionAdapter;
- private List<Feature> features;
+ private RecyclerView recyclerView;
+ private FeatureSectionAdapter sectionAdapter;
+ private List<Feature> features;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- toolbar.setTitle(getString(R.string.app_name));
- setSupportActionBar(toolbar);
-
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setElevation(getResources().getDimension(R.dimen.toolbar_shadow));
- }
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ toolbar.setTitle(getString(R.string.app_name));
+ setSupportActionBar(toolbar);
- recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
- recyclerView.setLayoutManager(new LinearLayoutManager(this));
- recyclerView.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener());
- recyclerView.setHasFixedSize(true);
-
- ItemClickSupport.addTo(recyclerView).setOnItemClickListener(new ItemClickSupport.OnItemClickListener() {
- @Override
- public void onItemClicked(RecyclerView recyclerView, int position, View view) {
- if (!sectionAdapter.isSectionHeaderPosition(position)) {
- int itemPosition = sectionAdapter.getConvertedPosition(position);
- Feature feature = features.get(itemPosition);
- if (feature.isRequiresLocationPermission()) {
- if (requestLocationPermission(itemPosition)) {
- return;
- }
- }
- startFeature(feature);
- }
- }
- });
-
- if (savedInstanceState == null) {
- loadFeatures();
- } else {
- features = savedInstanceState.getParcelableArrayList(KEY_STATE_FEATURES);
- onFeaturesLoaded(features);
- }
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setElevation(getResources().getDimension(R.dimen.toolbar_shadow));
}
- private void loadFeatures() {
- try {
- new LoadFeatureTask().execute(
- getPackageManager().getPackageInfo(getPackageName(),
- PackageManager.GET_ACTIVITIES | PackageManager.GET_META_DATA));
- } catch (PackageManager.NameNotFoundException exception) {
- Log.e(MapboxConstants.TAG, "Could not resolve package info", exception);
- }
- }
-
- private void onFeaturesLoaded(List<Feature> featuresList) {
- features = featuresList;
-
- List<FeatureSectionAdapter.Section> sections = new ArrayList<>();
- String currentCat = "";
- for (int i = 0; i < features.size(); i++) {
- String category = features.get(i).getCategory();
- if (!currentCat.equals(category)) {
- sections.add(new FeatureSectionAdapter.Section(i, category));
- currentCat = category;
+ recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
+ recyclerView.setLayoutManager(new LinearLayoutManager(this));
+ recyclerView.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener());
+ recyclerView.setHasFixedSize(true);
+
+ ItemClickSupport.addTo(recyclerView).setOnItemClickListener(new ItemClickSupport.OnItemClickListener() {
+ @Override
+ public void onItemClicked(RecyclerView recyclerView, int position, View view) {
+ if (!sectionAdapter.isSectionHeaderPosition(position)) {
+ int itemPosition = sectionAdapter.getConvertedPosition(position);
+ Feature feature = features.get(itemPosition);
+ if (feature.isRequiresLocationPermission()) {
+ if (requestLocationPermission(itemPosition)) {
+ return;
}
+ }
+ startFeature(feature);
}
-
- FeatureSectionAdapter.Section[] dummy = new FeatureSectionAdapter.Section[sections.size()];
- sectionAdapter = new FeatureSectionAdapter(
- this, R.layout.section_main_layout, R.id.section_text, new FeatureAdapter(features));
- sectionAdapter.setSections(sections.toArray(dummy));
- recyclerView.setAdapter(sectionAdapter);
+ }
+ });
+
+ if (savedInstanceState == null) {
+ loadFeatures();
+ } else {
+ features = savedInstanceState.getParcelableArrayList(KEY_STATE_FEATURES);
+ onFeaturesLoaded(features);
}
-
- private void startFeature(Feature feature) {
- Intent intent = new Intent();
- intent.setComponent(new ComponentName(getPackageName(), feature.getName()));
- startActivity(intent);
+ }
+
+ private void loadFeatures() {
+ try {
+ new LoadFeatureTask().execute(
+ getPackageManager().getPackageInfo(getPackageName(),
+ PackageManager.GET_ACTIVITIES | PackageManager.GET_META_DATA));
+ } catch (PackageManager.NameNotFoundException exception) {
+ Timber.e("Could not resolve package info", exception);
}
-
- private boolean requestLocationPermission(final int positionInList) {
- if ((ContextCompat.checkSelfPermission(FeatureOverviewActivity.this,
- Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
- || (ContextCompat.checkSelfPermission(FeatureOverviewActivity.this,
- Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)) {
- ActivityCompat.requestPermissions(FeatureOverviewActivity.this, new String[]{
- Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, positionInList);
- return true;
- } else {
- return false;
- }
+ }
+
+ private void onFeaturesLoaded(List<Feature> featuresList) {
+ features = featuresList;
+
+ List<FeatureSectionAdapter.Section> sections = new ArrayList<>();
+ String currentCat = "";
+ for (int i = 0; i < features.size(); i++) {
+ String category = features.get(i).getCategory();
+ if (!currentCat.equals(category)) {
+ sections.add(new FeatureSectionAdapter.Section(i, category));
+ currentCat = category;
+ }
}
- @Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
- if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
- startFeature(features.get(requestCode));
- } else {
- Snackbar.make(
- findViewById(android.R.id.content),
- "Can't open without accepting the location permission.",
- Snackbar.LENGTH_SHORT).show();
- }
+ FeatureSectionAdapter.Section[] dummy = new FeatureSectionAdapter.Section[sections.size()];
+ sectionAdapter = new FeatureSectionAdapter(
+ this, R.layout.section_main_layout, R.id.section_text, new FeatureAdapter(features));
+ sectionAdapter.setSections(sections.toArray(dummy));
+ recyclerView.setAdapter(sectionAdapter);
+ }
+
+ private void startFeature(Feature feature) {
+ Intent intent = new Intent();
+ intent.setComponent(new ComponentName(getPackageName(), feature.getName()));
+ startActivity(intent);
+ }
+
+ private boolean requestLocationPermission(final int positionInList) {
+ if ((ContextCompat.checkSelfPermission(FeatureOverviewActivity.this,
+ Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
+ || (ContextCompat.checkSelfPermission(FeatureOverviewActivity.this,
+ Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)) {
+ ActivityCompat.requestPermissions(FeatureOverviewActivity.this, new String[] {
+ Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, positionInList);
+ return true;
+ } else {
+ return false;
}
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- outState.putParcelableArrayList(KEY_STATE_FEATURES, (ArrayList<Feature>) features);
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+ if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ startFeature(features.get(requestCode));
+ } else {
+ Snackbar.make(
+ findViewById(android.R.id.content),
+ "Can't open without accepting the location permission.",
+ Snackbar.LENGTH_SHORT).show();
}
+ }
- private class LoadFeatureTask extends AsyncTask<PackageInfo, Void, List<Feature>> {
-
- @Override
- protected List<Feature> doInBackground(PackageInfo... params) {
- List<Feature> features = new ArrayList<>();
- PackageInfo app = params[0];
-
- String packageName = getApplicationContext().getPackageName();
- String metaDataKey = getString(R.string.category);
- for (ActivityInfo info : app.activities) {
- if (info.labelRes != 0 && info.name.startsWith(packageName)
- && !info.name.equals(FeatureOverviewActivity.class.getName())) {
- String label = getString(info.labelRes);
- String description = resolveString(info.descriptionRes);
- String category = resolveMetaData(info.metaData, metaDataKey);
- boolean requiresLocationPermission = requiresLocationPermission(label, category);
- features.add(new Feature(info.name, label, description, category, requiresLocationPermission));
- }
- }
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putParcelableArrayList(KEY_STATE_FEATURES, (ArrayList<Feature>) features);
+ }
- if (!features.isEmpty()) {
- Comparator<Feature> comparator = new Comparator<Feature>() {
- @Override
- public int compare(Feature lhs, Feature rhs) {
- int result = lhs.getCategory().compareToIgnoreCase(rhs.getCategory());
- if (result == 0) {
- result = lhs.getLabel().compareToIgnoreCase(rhs.getLabel());
- }
- return result;
- }
- };
- Collections.sort(features, comparator);
- }
+ private class LoadFeatureTask extends AsyncTask<PackageInfo, Void, List<Feature>> {
- return features;
+ @Override
+ protected List<Feature> doInBackground(PackageInfo... params) {
+ List<Feature> features = new ArrayList<>();
+ PackageInfo app = params[0];
+
+ String packageName = getApplicationContext().getPackageName();
+ String metaDataKey = getString(R.string.category);
+ for (ActivityInfo info : app.activities) {
+ if (info.labelRes != 0 && info.name.startsWith(packageName)
+ && !info.name.equals(FeatureOverviewActivity.class.getName())) {
+ String label = getString(info.labelRes);
+ String description = resolveString(info.descriptionRes);
+ String category = resolveMetaData(info.metaData, metaDataKey);
+ boolean requiresLocationPermission = requiresLocationPermission(label, category);
+ features.add(new Feature(info.name, label, description, category, requiresLocationPermission));
}
-
- private String resolveMetaData(Bundle bundle, String key) {
- String category = null;
- if (bundle != null) {
- category = bundle.getString(key);
+ }
+
+ if (!features.isEmpty()) {
+ Comparator<Feature> comparator = new Comparator<Feature>() {
+ @Override
+ public int compare(Feature lhs, Feature rhs) {
+ int result = lhs.getCategory().compareToIgnoreCase(rhs.getCategory());
+ if (result == 0) {
+ result = lhs.getLabel().compareToIgnoreCase(rhs.getLabel());
}
- return category;
- }
+ return result;
+ }
+ };
+ Collections.sort(features, comparator);
+ }
- private String resolveString(@StringRes int stringRes) {
- try {
- return getString(stringRes);
- } catch (Resources.NotFoundException exception) {
- return "-";
- }
- }
+ return features;
+ }
- private boolean requiresLocationPermission(String name, String category) {
- final Resources resources = getResources();
+ private String resolveMetaData(Bundle bundle, String key) {
+ String category = null;
+ if (bundle != null) {
+ category = bundle.getString(key);
+ }
+ return category;
+ }
- List<String> requiresPermissionCategories = new ArrayList<String>() {
- {
- add(resources.getString(R.string.category_userlocation));
- }
- };
+ private String resolveString(@StringRes int stringRes) {
+ try {
+ return getString(stringRes);
+ } catch (Resources.NotFoundException exception) {
+ return "-";
+ }
+ }
- List<String> requiresPermissionActvities = new ArrayList<String>() {
- {
- add(resources.getString(R.string.activity_double_map));
- add(getString(R.string.activity_location_picker));
- add(getString(R.string.activity_car_driving));
- }
- };
+ private boolean requiresLocationPermission(String name, String category) {
+ final Resources resources = getResources();
- return requiresPermissionCategories.contains(category) || requiresPermissionActvities.contains(name);
+ List<String> requiresPermissionCategories = new ArrayList<String>() {
+ {
+ add(resources.getString(R.string.category_userlocation));
}
+ };
- @Override
- protected void onPostExecute(List<Feature> features) {
- super.onPostExecute(features);
- onFeaturesLoaded(features);
+ List<String> requiresPermissionActvities = new ArrayList<String>() {
+ {
+ add(resources.getString(R.string.activity_double_map));
+ add(getString(R.string.activity_location_picker));
+ add(getString(R.string.activity_car_driving));
}
+ };
+
+ return requiresPermissionCategories.contains(category) || requiresPermissionActvities.contains(name);
+ }
+
+ @Override
+ protected void onPostExecute(List<Feature> features) {
+ super.onPostExecute(features);
+ onFeaturesLoaded(features);
}
+ }
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/AddRemoveMarkerActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/AddRemoveMarkerActivity.java
index 811a87c0ad..6c56aa4a7a 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/AddRemoveMarkerActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/AddRemoveMarkerActivity.java
@@ -4,7 +4,9 @@ import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
-import android.util.Log;
+
+import timber.log.Timber;
+
import android.view.MenuItem;
import com.mapbox.mapboxsdk.annotations.Icon;
@@ -13,7 +15,6 @@ import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
-import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
@@ -22,150 +23,161 @@ import com.mapbox.mapboxsdk.testapp.R;
public class AddRemoveMarkerActivity extends AppCompatActivity {
- public static final double THRESHOLD = 5.0;
-
- private MapView mapView;
- private MapboxMap mapboxMap;
- private double lastZoom;
- private boolean isShowingHighThresholdMarker;
- private boolean isShowingLowThresholdMarker;
-
- private MarkerOptions lowThresholdMarker;
- private MarkerOptions highThresholdMarker;
- private Marker activeMarker;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_add_remove_marker);
-
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
-
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- final Icon icon1 = IconFactory.getInstance(this).fromResource(R.drawable.ic_arsenal);
- final Icon icon2 = IconFactory.getInstance(this).fromResource(R.drawable.ic_chelsea);
-
- lowThresholdMarker = new MarkerOptions()
- .icon(icon1)
- .position(new LatLng(-0.1, 0));
-
- highThresholdMarker = new MarkerOptions()
- .icon(icon2)
- .position(new LatLng(0.1, 0));
-
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(MapboxMap mapboxMap) {
- AddRemoveMarkerActivity.this.mapboxMap = mapboxMap;
- updateZoom(mapboxMap.getCameraPosition().zoom);
- mapboxMap.moveCamera(CameraUpdateFactory.zoomTo(4.9f));
- mapboxMap.setOnCameraChangeListener(new MapboxMap.OnCameraChangeListener() {
- @Override
- public void onCameraChange(CameraPosition position) {
- updateZoom(position.zoom);
- }
- });
- }
- });
- }
+ public static final double THRESHOLD = 5.0;
- private void updateZoom(double zoom) {
- if (lastZoom == zoom) {
- return;
- }
-
- lastZoom = zoom;
- if (zoom > THRESHOLD) {
- showHighThresholdMarker();
- } else {
- showLowThresholdMarker();
- }
- }
+ private MapView mapView;
+ private MapboxMap mapboxMap;
+ private double lastZoom;
+ private boolean isShowingHighThresholdMarker;
+ private boolean isShowingLowThresholdMarker;
- private void showLowThresholdMarker() {
- if (isShowingLowThresholdMarker) {
- return;
- }
+ private MarkerOptions lowThresholdMarker;
+ private MarkerOptions highThresholdMarker;
+ private Marker activeMarker;
- isShowingLowThresholdMarker = true;
- isShowingHighThresholdMarker = false;
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_add_remove_marker);
- if (activeMarker != null) {
- Log.d(MapboxConstants.TAG, "Remove marker with " + activeMarker.getId());
- mapboxMap.removeMarker(activeMarker);
- } else {
- Log.e(MapboxConstants.TAG, "active marker is null");
- }
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- activeMarker = mapboxMap.addMarker(lowThresholdMarker);
- Log.d(MapboxConstants.TAG, "showLowThresholdMarker() " + activeMarker.getId());
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
- private void showHighThresholdMarker() {
- if (isShowingHighThresholdMarker) {
- return;
- }
+ final Icon icon1 = IconFactory.getInstance(this).fromResource(R.drawable.ic_arsenal);
+ final Icon icon2 = IconFactory.getInstance(this).fromResource(R.drawable.ic_chelsea);
+
+ lowThresholdMarker = new MarkerOptions()
+ .icon(icon1)
+ .position(new LatLng(-0.1, 0));
+
+ highThresholdMarker = new MarkerOptions()
+ .icon(icon2)
+ .position(new LatLng(0.1, 0));
+
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(MapboxMap mapboxMap) {
+ AddRemoveMarkerActivity.this.mapboxMap = mapboxMap;
+ updateZoom(mapboxMap.getCameraPosition().zoom);
+ mapboxMap.moveCamera(CameraUpdateFactory.zoomTo(4.9f));
+ mapboxMap.setOnCameraChangeListener(new MapboxMap.OnCameraChangeListener() {
+ @Override
+ public void onCameraChange(CameraPosition position) {
+ updateZoom(position.zoom);
+ }
+ });
+ }
+ });
+ }
- isShowingLowThresholdMarker = false;
- isShowingHighThresholdMarker = true;
+ private void updateZoom(double zoom) {
+ if (lastZoom == zoom) {
+ return;
+ }
- if (activeMarker != null) {
- Log.d(MapboxConstants.TAG, "Remove marker with " + activeMarker.getId());
- mapboxMap.removeMarker(activeMarker);
- } else {
- Log.e(MapboxConstants.TAG, "active marker is null");
- }
+ lastZoom = zoom;
+ if (zoom > THRESHOLD) {
+ showHighThresholdMarker();
+ } else {
+ showLowThresholdMarker();
+ }
+ }
- activeMarker = mapboxMap.addMarker(highThresholdMarker);
- Log.d(MapboxConstants.TAG, "showHighThresholdMarker() " + activeMarker.getId());
+ private void showLowThresholdMarker() {
+ if (isShowingLowThresholdMarker) {
+ return;
}
+ isShowingLowThresholdMarker = true;
+ isShowingHighThresholdMarker = false;
- @Override
- protected void onResume() {
- super.onResume();
- mapView.onResume();
+ if (activeMarker != null) {
+ Timber.d("Remove marker with " + activeMarker.getId());
+ mapboxMap.removeMarker(activeMarker);
+ } else {
+ Timber.e("active marker is null");
}
- @Override
- protected void onPause() {
- mapView.onPause();
- super.onPause();
- }
+ activeMarker = mapboxMap.addMarker(lowThresholdMarker);
+ Timber.d("showLowThresholdMarker() " + activeMarker.getId());
+ }
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
+ private void showHighThresholdMarker() {
+ if (isShowingHighThresholdMarker) {
+ return;
}
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
- }
+ isShowingLowThresholdMarker = false;
+ isShowingHighThresholdMarker = true;
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
+ if (activeMarker != null) {
+ Timber.d("Remove marker with " + activeMarker.getId());
+ mapboxMap.removeMarker(activeMarker);
+ } else {
+ Timber.e("active marker is null");
}
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- }
- return super.onOptionsItemSelected(item);
+ activeMarker = mapboxMap.addMarker(highThresholdMarker);
+ Timber.d("showHighThresholdMarker() " + activeMarker.getId());
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
}
+ return super.onOptionsItemSelected(item);
+ }
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/AnimatedMarkerActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/AnimatedMarkerActivity.java
index 569d5298a4..59c1877cc1 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/AnimatedMarkerActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/AnimatedMarkerActivity.java
@@ -18,6 +18,7 @@ import com.mapbox.mapboxsdk.annotations.Icon;
import com.mapbox.mapboxsdk.annotations.IconFactory;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerView;
+import com.mapbox.mapboxsdk.annotations.MarkerViewManager;
import com.mapbox.mapboxsdk.annotations.MarkerViewOptions;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.geometry.LatLng;
@@ -26,226 +27,245 @@ import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.testapp.R;
+import com.mapbox.services.commons.models.Position;
+import com.mapbox.services.commons.turf.TurfMeasurement;
import java.util.Random;
public class AnimatedMarkerActivity extends AppCompatActivity {
- private MapView mapView;
- private MapboxMap mapboxMap;
+ private MapView mapView;
+ private MapboxMap mapboxMap;
- private LatLng dupontCircle = new LatLng(38.90962, -77.04341);
+ private LatLng dupontCircle = new LatLng(38.90962, -77.04341);
- private Marker passengerMarker = null;
- private MarkerView carMarker = null;
+ private Marker passengerMarker = null;
+ private MarkerView carMarker = null;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_animated_marker);
-
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
-
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(new OnMapReadyCallback() {
-
- @Override
- public void onMapReady(@NonNull final MapboxMap mapboxMap) {
- AnimatedMarkerActivity.this.mapboxMap = mapboxMap;
- setupMap();
-
- for (int i = 0; i < 10; i++) {
- addRandomCar();
- }
-
- addPassenger();
- addMainCar();
- animateMoveToPassenger(carMarker);
- }
- });
- }
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_animated_marker);
- private void setupMap() {
- CameraPosition cameraPosition = new CameraPosition.Builder()
- .target(dupontCircle)
- .zoom(15)
- .build();
- mapboxMap.setCameraPosition(cameraPosition);
- }
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- private void addPassenger() {
- LatLng randomLatLng = getLatLngInBounds();
-
- if (passengerMarker == null) {
- Icon icon = IconFactory.getInstance(AnimatedMarkerActivity.this)
- .fromResource(R.drawable.ic_directions_run_black_24dp);
- passengerMarker = mapboxMap.addMarker(new MarkerViewOptions()
- .position(randomLatLng)
- .icon(icon));
- } else {
- passengerMarker.setPosition(randomLatLng);
- }
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
- private void addMainCar() {
- LatLng randomLatLng = getLatLngInBounds();
-
- if (carMarker == null) {
- carMarker = createCarMarker(randomLatLng, R.drawable.ic_taxi_top);
- } else {
- carMarker.setPosition(randomLatLng);
- }
-
- // Make sure the car marker is selected so that it's always brought to the front (#5285)
- mapboxMap.selectMarker(carMarker);
- }
-
- private void animateMoveToPassenger(final MarkerView car) {
- ValueAnimator animator = animateMoveMarker(car, passengerMarker.getPosition());
- animator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- addPassenger();
- animateMoveToPassenger(car);
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(new OnMapReadyCallback() {
+
+ @Override
+ public void onMapReady(@NonNull final MapboxMap mapboxMap) {
+ AnimatedMarkerActivity.this.mapboxMap = mapboxMap;
+ setupMap();
+ mapView.post(new Runnable() {
+ @Override
+ public void run() {
+ for (int i = 0; i < 10; i++) {
+ addRandomCar();
}
+ addPassenger();
+ addMainCar();
+ }
});
+ }
+ });
+ }
+
+ private void setupMap() {
+ CameraPosition cameraPosition = new CameraPosition.Builder()
+ .target(dupontCircle)
+ .zoom(15)
+ .build();
+ mapboxMap.setCameraPosition(cameraPosition);
+ }
+
+ private void addPassenger() {
+ LatLng randomLatLng = getLatLngInBounds();
+
+ if (passengerMarker == null) {
+ Icon icon = IconFactory.getInstance(AnimatedMarkerActivity.this)
+ .fromResource(R.drawable.ic_directions_run_black_24dp);
+ passengerMarker = mapboxMap.addMarker(new MarkerViewOptions()
+ .position(randomLatLng)
+ .icon(icon));
+ } else {
+ passengerMarker.setPosition(randomLatLng);
}
-
- protected void addRandomCar() {
- MarkerView car = createCarMarker(getLatLngInBounds(), R.drawable.ic_car_top);
- randomlyMoveMarker(car);
- }
-
- private void randomlyMoveMarker(final MarkerView marker) {
- ValueAnimator animator = animateMoveMarker(marker, getLatLngInBounds());
-
- //Add listener to restart animation on end
- animator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- randomlyMoveMarker(marker);
- }
+ }
+
+ private void addMainCar() {
+ LatLng randomLatLng = getLatLngInBounds();
+
+ if (carMarker == null) {
+ carMarker = createCarMarker(randomLatLng, R.drawable.ic_taxi_top,
+ new MarkerViewManager.OnMarkerViewAddedListener() {
+ @Override
+ public void onViewAdded(@NonNull MarkerView markerView) {
+ // Make sure the car marker is selected so that it's always brought to the front (#5285)
+ mapboxMap.selectMarker(carMarker);
+ animateMoveToPassenger(carMarker);
+ }
});
- }
-
- private ValueAnimator animateMoveMarker(final MarkerView marker, LatLng to) {
- marker.setRotation((float) getBearing(marker.getPosition(), to));
-
- final ValueAnimator markerAnimator = ObjectAnimator.ofObject(
- marker, "position", new LatLngEvaluator(), marker.getPosition(), to);
- markerAnimator.setDuration((long) (10 * marker.getPosition().distanceTo(to)));
- markerAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
- // Start
- markerAnimator.start();
-
- return markerAnimator;
+ } else {
+ carMarker.setPosition(randomLatLng);
}
-
- private MarkerView createCarMarker(LatLng start, @DrawableRes int carResource) {
- Icon icon = IconFactory.getInstance(AnimatedMarkerActivity.this)
- .fromResource(carResource);
-
- //View Markers
- return mapboxMap.addMarker(new MarkerViewOptions()
- .position(start)
- .icon(icon));
-
- //GL Markers
+ }
+
+ private void animateMoveToPassenger(final MarkerView car) {
+ ValueAnimator animator = animateMoveMarker(car, passengerMarker.getPosition());
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ addPassenger();
+ animateMoveToPassenger(car);
+ }
+ });
+ }
+
+ protected void addRandomCar() {
+ createCarMarker(getLatLngInBounds(), R.drawable.ic_car_top, new MarkerViewManager.OnMarkerViewAddedListener() {
+ @Override
+ public void onViewAdded(@NonNull MarkerView markerView) {
+ randomlyMoveMarker(markerView);
+ }
+ });
+ }
+
+ private void randomlyMoveMarker(final MarkerView marker) {
+ ValueAnimator animator = animateMoveMarker(marker, getLatLngInBounds());
+
+ //Add listener to restart animation on end
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ randomlyMoveMarker(marker);
+ }
+ });
+ }
+
+ private ValueAnimator animateMoveMarker(final MarkerView marker, LatLng to) {
+ marker.setRotation((float) getBearing(marker.getPosition(), to));
+
+ final ValueAnimator markerAnimator = ObjectAnimator.ofObject(
+ marker, "position", new LatLngEvaluator(), marker.getPosition(), to);
+ markerAnimator.setDuration((long) (10 * marker.getPosition().distanceTo(to)));
+ markerAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
+
+ // Start
+ markerAnimator.start();
+
+ return markerAnimator;
+ }
+
+ private MarkerView createCarMarker(LatLng start, @DrawableRes int carResource,
+ MarkerViewManager.OnMarkerViewAddedListener listener) {
+ Icon icon = IconFactory.getInstance(AnimatedMarkerActivity.this)
+ .fromResource(carResource);
+
+ //View Markers
+ return mapboxMap.addMarker(new MarkerViewOptions()
+ .position(start)
+ .icon(icon), listener);
+
+ //GL Markers
// return mapboxMap.addMarker(new MarkerOptions()
// .position(start)
// .icon(icon));
+ }
+
+ private LatLng getLatLngInBounds() {
+ LatLngBounds bounds = mapboxMap.getProjection().getVisibleRegion().latLngBounds;
+ Random generator = new Random();
+ double randomLat = bounds.getLatSouth() + generator.nextDouble()
+ * (bounds.getLatNorth() - bounds.getLatSouth());
+ double randomLon = bounds.getLonWest() + generator.nextDouble()
+ * (bounds.getLonEast() - bounds.getLonWest());
+ return new LatLng(randomLat, randomLon);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
-
- private LatLng getLatLngInBounds() {
- LatLngBounds bounds = mapboxMap.getProjection().getVisibleRegion().latLngBounds;
- Random generator = new Random();
- double randomLat = bounds.getLatSouth() + generator.nextDouble()
- * (bounds.getLatNorth() - bounds.getLatSouth());
- double randomLon = bounds.getLonWest() + generator.nextDouble()
- * (bounds.getLonEast() - bounds.getLonWest());
- return new LatLng(randomLat, randomLon);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ /**
+ * Evaluator for LatLng pairs
+ */
+ private static class LatLngEvaluator implements TypeEvaluator<LatLng> {
+
+ private LatLng latLng = new LatLng();
@Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
- }
-
- /**
- * Evaluator for LatLng pairs
- */
- private static class LatLngEvaluator implements TypeEvaluator<LatLng> {
-
- private LatLng latLng = new LatLng();
-
- @Override
- public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue) {
- latLng.setLatitude(startValue.getLatitude()
- + ((endValue.getLatitude() - startValue.getLatitude()) * fraction));
- latLng.setLongitude(startValue.getLongitude()
- + ((endValue.getLongitude() - startValue.getLongitude()) * fraction));
- return latLng;
- }
- }
-
- private double getBearing(LatLng from, LatLng to) {
- double degrees2radians = Math.PI / 180;
- double radians2degrees = 180 / Math.PI;
-
- double lon1 = degrees2radians * from.getLongitude();
- double lon2 = degrees2radians * to.getLongitude();
- double lat1 = degrees2radians * from.getLatitude();
- double lat2 = degrees2radians * to.getLatitude();
- double a = Math.sin(lon2 - lon1) * Math.cos(lat2);
- double b = Math.cos(lat1) * Math.sin(lat2)
- - Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1);
-
- return radians2degrees * Math.atan2(a, b);
+ public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue) {
+ latLng.setLatitude(startValue.getLatitude()
+ + ((endValue.getLatitude() - startValue.getLatitude()) * fraction));
+ latLng.setLongitude(startValue.getLongitude()
+ + ((endValue.getLongitude() - startValue.getLongitude()) * fraction));
+ return latLng;
}
+ }
+
+ private double getBearing(LatLng from, LatLng to) {
+ return TurfMeasurement.bearing(
+ Position.fromCoordinates(from.getLongitude(), from.getLatitude()),
+ Position.fromCoordinates(to.getLongitude(), to.getLatitude())
+ );
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/BulkMarkerActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/BulkMarkerActivity.java
index 148207bab9..0d97289e56 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/BulkMarkerActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/BulkMarkerActivity.java
@@ -8,11 +8,14 @@ import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
+import android.support.v4.content.ContextCompat;
import android.support.v4.content.res.ResourcesCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
-import android.util.Log;
+
+import timber.log.Timber;
+
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
@@ -43,247 +46,259 @@ import java.util.Random;
public class BulkMarkerActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
- private MapboxMap mapboxMap;
- private MapView mapView;
- private boolean customMarkerView;
- private List<LatLng> locations;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_marker_bulk);
-
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
-
- final ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayShowTitleEnabled(false);
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(@NonNull MapboxMap mapboxMap) {
- BulkMarkerActivity.this.mapboxMap = mapboxMap;
-
- if (actionBar != null) {
- ArrayAdapter<CharSequence> spinnerAdapter = ArrayAdapter.createFromResource(
- actionBar.getThemedContext(), R.array.bulk_marker_list, android.R.layout.simple_spinner_item);
- spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- Spinner spinner = (Spinner) findViewById(R.id.spinner);
- spinner.setAdapter(spinnerAdapter);
- spinner.setOnItemSelectedListener(BulkMarkerActivity.this);
- }
- }
- });
+ private MapboxMap mapboxMap;
+ private MapView mapView;
+ private boolean customMarkerView;
+ private List<LatLng> locations;
- final View fab = findViewById(R.id.fab);
- if (fab != null) {
- fab.setOnClickListener(new FabClickListener());
- }
- }
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_marker_bulk);
- @Override
- public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
- int amount = Integer.valueOf(getResources().getStringArray(R.array.bulk_marker_list)[position]);
- if (locations == null) {
- new LoadLocationTask(this, amount).execute();
- } else {
- showMarkers(amount);
- }
- }
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- private void onLatLngListLoaded(List<LatLng> latLngs, int amount) {
- locations = latLngs;
- showMarkers(amount);
+ final ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayShowTitleEnabled(false);
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
- private void showMarkers(int amount) {
- mapboxMap.clear();
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(@NonNull MapboxMap mapboxMap) {
+ BulkMarkerActivity.this.mapboxMap = mapboxMap;
- if (locations.size() < amount) {
- amount = locations.size();
+ if (actionBar != null) {
+ ArrayAdapter<CharSequence> spinnerAdapter = ArrayAdapter.createFromResource(
+ actionBar.getThemedContext(), R.array.bulk_marker_list, android.R.layout.simple_spinner_item);
+ spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ Spinner spinner = (Spinner) findViewById(R.id.spinner);
+ spinner.setAdapter(spinnerAdapter);
+ spinner.setOnItemSelectedListener(BulkMarkerActivity.this);
}
+ }
+ });
- if (customMarkerView) {
- showViewMarkers(amount);
- } else {
- showGlMarkers(amount);
- }
+ final View fab = findViewById(R.id.fab);
+ if (fab != null) {
+ fab.setOnClickListener(new FabClickListener());
}
-
- private void showViewMarkers(int amount) {
- DecimalFormat formatter = new DecimalFormat("#.#####");
- Random random = new Random();
- int randomIndex;
-
- Drawable drawable = ResourcesCompat.getDrawable(getResources(), R.drawable.ic_droppin_24dp, getTheme());
- int redColor = ResourcesCompat.getColor(getResources(), android.R.color.holo_red_dark, getTheme());
- drawable.setColorFilter(redColor, PorterDuff.Mode.SRC_IN);
- Icon icon = IconFactory.getInstance(this).fromDrawable(drawable);
-
- List<MarkerViewOptions> markerOptionsList = new ArrayList<>();
- for (int i = 0; i < amount; i++) {
- randomIndex = random.nextInt(locations.size());
- LatLng latLng = locations.get(randomIndex);
- MarkerViewOptions markerOptions = new MarkerViewOptions()
- .position(latLng)
- .icon(icon)
- .title(String.valueOf(i))
- .snippet(formatter.format(latLng.getLatitude()) + ", " + formatter.format(latLng.getLongitude()));
- markerOptionsList.add(markerOptions);
- }
- mapboxMap.addMarkerViews(markerOptionsList);
+ }
+
+ @Override
+ public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+ int amount = Integer.valueOf(getResources().getStringArray(R.array.bulk_marker_list)[position]);
+ if (locations == null) {
+ new LoadLocationTask(this, amount).execute();
+ } else {
+ showMarkers(amount);
}
+ }
- private void showGlMarkers(int amount) {
- List<MarkerOptions> markerOptionsList = new ArrayList<>();
- DecimalFormat formatter = new DecimalFormat("#.#####");
- Random random = new Random();
- int randomIndex;
-
- for (int i = 0; i < amount; i++) {
- randomIndex = random.nextInt(locations.size());
- LatLng latLng = locations.get(randomIndex);
- markerOptionsList.add(new MarkerOptions()
- .position(latLng)
- .title(String.valueOf(i))
- .snippet(formatter.format(latLng.getLatitude()) + ", " + formatter.format(latLng.getLongitude())));
- }
+ private void onLatLngListLoaded(List<LatLng> latLngs, int amount) {
+ locations = latLngs;
+ showMarkers(amount);
+ }
- mapboxMap.addMarkers(markerOptionsList);
- }
+ private void showMarkers(int amount) {
+ mapboxMap.clear();
- @Override
- public void onNothingSelected(AdapterView<?> parent) {
- // nothing selected, nothing to do!
+ if (locations.size() < amount) {
+ amount = locations.size();
}
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
+ if (customMarkerView) {
+ showViewMarkers(amount);
+ } else {
+ showGlMarkers(amount);
}
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
+ }
+
+ private void showViewMarkers(int amount) {
+ DecimalFormat formatter = new DecimalFormat("#.#####");
+ Random random = new Random();
+ int randomIndex;
+
+ Drawable drawable = ContextCompat.getDrawable(BulkMarkerActivity.this, R.drawable.ic_droppin_24dp);
+
+ int redColor = ResourcesCompat.getColor(getResources(), android.R.color.holo_red_dark, getTheme());
+ drawable.setColorFilter(redColor, PorterDuff.Mode.SRC_IN);
+ Icon icon = IconFactory.getInstance(this).fromDrawable(drawable);
+
+ List<MarkerViewOptions> markerOptionsList = new ArrayList<>();
+ for (int i = 0; i < amount; i++) {
+ randomIndex = random.nextInt(locations.size());
+ LatLng latLng = locations.get(randomIndex);
+ MarkerViewOptions markerOptions = new MarkerViewOptions()
+ .position(latLng)
+ .icon(icon)
+ .title(String.valueOf(i))
+ .snippet(formatter.format(latLng.getLatitude()) + ", " + formatter.format(latLng.getLongitude()));
+ markerOptionsList.add(markerOptions);
}
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
+ mapboxMap.addMarkerViews(markerOptionsList);
+ }
+
+ private void showGlMarkers(int amount) {
+ List<MarkerOptions> markerOptionsList = new ArrayList<>();
+ DecimalFormat formatter = new DecimalFormat("#.#####");
+ Random random = new Random();
+ int randomIndex;
+
+ for (int i = 0; i < amount; i++) {
+ randomIndex = random.nextInt(locations.size());
+ LatLng latLng = locations.get(randomIndex);
+ markerOptionsList.add(new MarkerOptions()
+ .position(latLng)
+ .title(String.valueOf(i))
+ .snippet(formatter.format(latLng.getLatitude()) + ", " + formatter.format(latLng.getLongitude())));
}
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
+ mapboxMap.addMarkers(markerOptionsList);
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {
+ // nothing selected, nothing to do!
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
+ private class FabClickListener implements View.OnClickListener {
@Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
+ public void onClick(final View view) {
+ if (mapboxMap != null) {
+ customMarkerView = true;
+
+ // remove fab
+ view.animate().alpha(0).setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ view.setVisibility(View.GONE);
+ }
+ }).start();
+
+ // reload markers
+ Spinner spinner = (Spinner) findViewById(R.id.spinner);
+ if (spinner != null) {
+ int amount = Integer.valueOf(
+ getResources().getStringArray(R.array.bulk_marker_list)[spinner.getSelectedItemPosition()]);
+ showMarkers(amount);
}
- }
- private class FabClickListener implements View.OnClickListener {
- @Override
- public void onClick(final View v) {
- if (mapboxMap != null) {
- customMarkerView = true;
-
- // remove fab
- v.animate().alpha(0).setListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- v.setVisibility(View.GONE);
- }
- }).start();
-
- // reload markers
- Spinner spinner = (Spinner) findViewById(R.id.spinner);
- if (spinner != null) {
- int amount = Integer.valueOf(
- getResources().getStringArray(R.array.bulk_marker_list)[spinner.getSelectedItemPosition()]);
- showMarkers(amount);
- }
-
- mapView.addOnMapChangedListener(new MapView.OnMapChangedListener() {
- @Override
- public void onMapChanged(@MapView.MapChange int change) {
- if (change == MapView.REGION_IS_CHANGING || change == MapView.REGION_DID_CHANGE) {
- if (!mapboxMap.getMarkerViewManager().getMarkerViewAdapters().isEmpty()) {
- TextView viewCountView = (TextView) findViewById(R.id.countView);
- viewCountView.setText("ViewCache size " + (mapView.getChildCount() - 5));
- }
- }
- }
- });
-
- mapboxMap.getMarkerViewManager().setOnMarkerViewClickListener(
- new MapboxMap.OnMarkerViewClickListener() {
- @Override
- public boolean onMarkerClick(
- @NonNull Marker marker, @NonNull View view, @NonNull MapboxMap.MarkerViewAdapter adapter) {
- Toast.makeText(
- BulkMarkerActivity.this,
- "Hello " + marker.getId(),
- Toast.LENGTH_SHORT).show();
- return false;
- }
- });
+ mapView.addOnMapChangedListener(new MapView.OnMapChangedListener() {
+ @Override
+ public void onMapChanged(@MapView.MapChange int change) {
+ if (change == MapView.REGION_IS_CHANGING || change == MapView.REGION_DID_CHANGE) {
+ if (!mapboxMap.getMarkerViewManager().getMarkerViewAdapters().isEmpty()) {
+ TextView viewCountView = (TextView) findViewById(R.id.countView);
+ viewCountView.setText("ViewCache size " + (mapView.getChildCount() - 5));
+ }
}
- }
+ }
+ });
+
+ mapboxMap.getMarkerViewManager().setOnMarkerViewClickListener(
+ new MapboxMap.OnMarkerViewClickListener() {
+ @Override
+ public boolean onMarkerClick(
+ @NonNull Marker marker, @NonNull View view, @NonNull MapboxMap.MarkerViewAdapter adapter) {
+ Toast.makeText(
+ BulkMarkerActivity.this,
+ "Hello " + marker.getId(),
+ Toast.LENGTH_SHORT).show();
+ return false;
+ }
+ });
+ }
}
+ }
- private static class LoadLocationTask extends AsyncTask<Void, Integer, List<LatLng>> {
+ private static class LoadLocationTask extends AsyncTask<Void, Integer, List<LatLng>> {
- private static final String TAG = "LoadLocationTask";
- private BulkMarkerActivity activity;
- private ProgressDialog progressDialog;
- private int amount;
+ private BulkMarkerActivity activity;
+ private ProgressDialog progressDialog;
+ private int amount;
- public LoadLocationTask(BulkMarkerActivity activity, int amount) {
- this.amount = amount;
- this.activity = activity;
- progressDialog = ProgressDialog.show(activity, "Loading", "Fetching markers", false);
- }
+ private LoadLocationTask(BulkMarkerActivity activity, int amount) {
+ this.amount = amount;
+ this.activity = activity;
+ progressDialog = ProgressDialog.show(activity, "Loading", "Fetching markers", false);
+ }
- @Override
- protected List<LatLng> doInBackground(Void... params) {
- try {
- String json = GeoParseUtil.loadStringFromAssets(activity.getApplicationContext(), "points.geojson");
- return GeoParseUtil.parseGeoJSONCoordinates(json);
- } catch (IOException | JSONException exception) {
- Log.e(TAG, "Could not add markers,", exception);
- return null;
- }
- }
+ @Override
+ protected List<LatLng> doInBackground(Void... params) {
+ try {
+ String json = GeoParseUtil.loadStringFromAssets(activity.getApplicationContext(), "points.geojson");
+ return GeoParseUtil.parseGeoJsonCoordinates(json);
+ } catch (IOException | JSONException exception) {
+ Timber.e("Could not add markers,", exception);
+ return null;
+ }
+ }
- @Override
- protected void onPostExecute(List<LatLng> locations) {
- super.onPostExecute(locations);
- activity.onLatLngListLoaded(locations, amount);
- progressDialog.hide();
- }
+ @Override
+ protected void onPostExecute(List<LatLng> locations) {
+ super.onPostExecute(locations);
+ activity.onLatLngListLoaded(locations, amount);
+ progressDialog.hide();
}
+ }
}
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 3c3399168a..8446329e43 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
@@ -13,8 +13,6 @@ import android.view.View;
import com.mapbox.mapboxsdk.annotations.IconFactory;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
-import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
-import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
@@ -23,111 +21,123 @@ import com.mapbox.mapboxsdk.testapp.R;
public class DynamicMarkerChangeActivity extends AppCompatActivity {
- private static final LatLng LAT_LNG_CHELSEA = new LatLng(51.481670, -0.190849);
- private static final LatLng LAT_LNG_ARSENAL = new LatLng(51.555062, -0.108417);
+ private static final LatLng LAT_LNG_CHELSEA = new LatLng(51.481670, -0.190849);
+ private static final LatLng LAT_LNG_ARSENAL = new LatLng(51.555062, -0.108417);
- private MapView mapView;
- private MapboxMap mapboxMap;
- private IconFactory iconFactory;
- private Marker marker;
+ private MapView mapView;
+ private MapboxMap mapboxMap;
+ private IconFactory iconFactory;
+ private Marker marker;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_dynamic_marker);
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_dynamic_marker);
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- iconFactory = IconFactory.getInstance(this);
-
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.setTag(false);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(@NonNull MapboxMap mapboxMap) {
- DynamicMarkerChangeActivity.this.mapboxMap = mapboxMap;
- // Create marker
- MarkerOptions markerOptions = new MarkerOptions()
- .position(LAT_LNG_CHELSEA)
- .icon(iconFactory.fromResource(R.drawable.ic_chelsea))
- .title(getString(R.string.dynamic_marker_chelsea_title))
- .snippet(getString(R.string.dynamic_marker_chelsea_snippet));
- marker = mapboxMap.addMarker(markerOptions);
- }
- });
-
- FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
- fab.setColorFilter(ContextCompat.getColor(this, R.color.primary));
- fab.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- if (mapboxMap != null) {
- updateMarker();
- }
- }
- });
- }
-
- private void updateMarker() {
- // update model
- boolean first = (boolean) mapView.getTag();
- mapView.setTag(!first);
-
- // update marker
- marker.setPosition(first ? LAT_LNG_CHELSEA : LAT_LNG_ARSENAL);
- marker.setIcon(iconFactory.fromResource(first ? R.drawable.ic_chelsea : R.drawable.ic_arsenal));
- marker.setTitle(first
- ? getString(R.string.dynamic_marker_chelsea_title) : getString(R.string.dynamic_marker_arsenal_title));
- marker.setSnippet(first
- ? getString(R.string.dynamic_marker_chelsea_snippet) : getString(R.string.dynamic_marker_arsenal_snippet));
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
-
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
+ iconFactory = IconFactory.getInstance(this);
+
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.setTag(false);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(@NonNull MapboxMap mapboxMap) {
+ DynamicMarkerChangeActivity.this.mapboxMap = mapboxMap;
+ // Create marker
+ MarkerOptions markerOptions = new MarkerOptions()
+ .position(LAT_LNG_CHELSEA)
+ .icon(iconFactory.fromResource(R.drawable.ic_chelsea))
+ .title(getString(R.string.dynamic_marker_chelsea_title))
+ .snippet(getString(R.string.dynamic_marker_chelsea_snippet));
+ marker = mapboxMap.addMarker(markerOptions);
+ }
+ });
+
+ FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
+ fab.setColorFilter(ContextCompat.getColor(this, R.color.primary));
+ fab.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ if (mapboxMap != null) {
+ updateMarker();
}
+ }
+ });
+ }
+
+ private void updateMarker() {
+ // update model
+ boolean first = (boolean) mapView.getTag();
+ mapView.setTag(!first);
+
+ // update marker
+ marker.setPosition(first ? LAT_LNG_CHELSEA : LAT_LNG_ARSENAL);
+ marker.setIcon(iconFactory.fromResource(first ? R.drawable.ic_chelsea : R.drawable.ic_arsenal));
+ marker.setTitle(first
+ ? getString(R.string.dynamic_marker_chelsea_title) : getString(R.string.dynamic_marker_arsenal_title));
+ marker.setSnippet(first
+ ? getString(R.string.dynamic_marker_chelsea_snippet) : getString(R.string.dynamic_marker_arsenal_snippet));
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
}
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 fe20b75a8d..f1dc7f8c0d 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,434 +41,458 @@ 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();
-
- // 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) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_marker_view);
-
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
+ 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();
+
+ // 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) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_marker_view);
+
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+
+ final ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
+ }
- final ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
+ final TextView viewCountView = (TextView) findViewById(R.id.countView);
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(@NonNull MapboxMap mapboxMap) {
+ MarkerViewActivity.this.mapboxMap = mapboxMap;
+
+ final MarkerViewManager markerViewManager = mapboxMap.getMarkerViewManager();
+
+ Icon usFlag = IconFactory.getInstance(MarkerViewActivity.this)
+ .fromResource(R.drawable.ic_us);
+
+ // add default ViewMarker markers
+ for (int i = 0; i < LAT_LNGS.length; i++) {
+ MarkerViewActivity.this.mapboxMap.addMarker(new MarkerViewOptions()
+ .position(LAT_LNGS[i])
+ .title(String.valueOf(i))
+ .alpha(0.5f)
+ .icon(usFlag)
+ );
}
- final TextView viewCountView = (TextView) findViewById(R.id.countView);
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(@NonNull MapboxMap mapboxMap) {
- MarkerViewActivity.this.mapboxMap = mapboxMap;
-
- final MarkerViewManager markerViewManager = mapboxMap.getMarkerViewManager();
-
- Icon usFlag = IconFactory.getInstance(MarkerViewActivity.this)
- .fromResource(R.drawable.ic_us);
-
- // add default ViewMarker markers
- for (int i = 0; i < LAT_LNGS.length; i++) {
- MarkerViewActivity.this.mapboxMap.addMarker(new MarkerViewOptions()
- .position(LAT_LNGS[i])
- .title(String.valueOf(i))
- .alpha(0.5f)
- .icon(usFlag)
- );
- }
-
- // add custom ViewMarker
- CountryMarkerViewOptions options = new CountryMarkerViewOptions();
- options.flagRes(R.drawable.icon_burned);
- options.abbrevName("Mapbox");
- options.title("Hello");
- options.position(new LatLng(38.899774, -77.023237));
- options.flat(true);
- mapboxMap.addMarker(options);
-
- MarkerViewActivity.this.mapboxMap.addMarker(new MarkerOptions()
- .title("United States")
- .position(new LatLng(38.902580, -77.050102))
- );
-
- 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")
- .position(new LatLng(38.907327, -77.041293))
- );
-
- MarkerViewActivity.this.mapboxMap.addMarker(new TextMarkerViewOptions()
- .text("C")
- .position(new LatLng(38.897642, -77.041980))
- );
-
- // if you want to customise a ViewMarker you need to extend ViewMarker and provide an adapter implementation
- // set adapters for child classes of ViewMarker
- markerViewManager.addMarkerViewAdapter(new CountryAdapter(MarkerViewActivity.this, mapboxMap));
- markerViewManager.addMarkerViewAdapter(new TextAdapter(MarkerViewActivity.this, mapboxMap));
-
- // add a change listener to validate the size of amount of child views
- mapView.addOnMapChangedListener(new MapView.OnMapChangedListener() {
- @Override
- 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.getMarkerViewContainer().getChildCount());
- }
- }
- }
- });
-
- // add a OnMarkerView click listener
- MarkerViewActivity.this.mapboxMap.getMarkerViewManager().setOnMarkerViewClickListener(new MapboxMap.OnMarkerViewClickListener() {
- @Override
- public boolean onMarkerClick(@NonNull Marker marker, @NonNull View view, @NonNull MapboxMap.MarkerViewAdapter adapter) {
- Toast.makeText(MarkerViewActivity.this, "Hello " + marker.getId(), Toast.LENGTH_SHORT).show();
- return false;
- }
- });
-
- movingMarkerOne = MarkerViewActivity.this.mapboxMap.addMarker(new MarkerViewOptions()
- .position(CarLocation.CAR_0_LNGS[0])
- .icon(IconFactory.getInstance(mapView.getContext())
- .fromResource(R.drawable.ic_chelsea))
- );
-
- movingMarkerTwo = mapboxMap.addMarker(new MarkerViewOptions()
- .position(CarLocation.CAR_1_LNGS[0])
- .icon(IconFactory.getInstance(mapView.getContext())
- .fromResource(R.drawable.ic_arsenal))
- );
+ // add custom ViewMarker
+ CountryMarkerViewOptions options = new CountryMarkerViewOptions();
+ options.flagRes(R.drawable.icon_burned);
+ options.abbrevName("Mapbox");
+ options.title("Hello");
+ options.position(new LatLng(38.899774, -77.023237));
+ options.flat(true);
+ mapboxMap.addMarker(options);
+
+ MarkerViewActivity.this.mapboxMap.addMarker(new MarkerOptions()
+ .title("United States")
+ .position(new LatLng(38.902580, -77.050102))
+ );
+
+ 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")
+ .position(new LatLng(38.907327, -77.041293))
+ );
+
+ MarkerViewActivity.this.mapboxMap.addMarker(new TextMarkerViewOptions()
+ .text("C")
+ .position(new LatLng(38.897642, -77.041980))
+ );
+
+ // if you want to customise a ViewMarker you need to extend ViewMarker and provide an adapter implementation
+ // set adapters for child classes of ViewMarker
+ markerViewManager.addMarkerViewAdapter(new CountryAdapter(MarkerViewActivity.this, mapboxMap));
+ markerViewManager.addMarkerViewAdapter(new TextAdapter(MarkerViewActivity.this, mapboxMap));
+
+ final ViewGroup markerViewContainer = markerViewManager.getMarkerViewContainer();
+
+ // add a change listener to validate the size of amount of child views
+ mapView.addOnMapChangedListener(new MapView.OnMapChangedListener() {
+ @Override
+ 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 " + markerViewContainer.getChildCount());
+ }
}
+ }
});
- }
-
- private void loopMarkerRotate() {
- rotateUpdateHandler.postDelayed(rotateMarkerRunnable, 800);
- }
+ // add a OnMarkerView click listener
+ MarkerViewActivity.this.mapboxMap.getMarkerViewManager().setOnMarkerViewClickListener(
+ new MapboxMap.OnMarkerViewClickListener() {
+ @Override
+ public boolean onMarkerClick(@NonNull Marker marker, @NonNull View view,
+ @NonNull MapboxMap.MarkerViewAdapter adapter) {
+ Toast.makeText(MarkerViewActivity.this, "Hello " + marker.getId(), Toast.LENGTH_SHORT).show();
+ return false;
+ }
+ });
+
+ movingMarkerOne = MarkerViewActivity.this.mapboxMap.addMarker(new MarkerViewOptions()
+ .position(CarLocation.CAR_0_LNGS[0])
+ .icon(IconFactory.getInstance(mapView.getContext())
+ .fromResource(R.drawable.ic_chelsea))
+ );
+
+ movingMarkerTwo = mapboxMap.addMarker(new MarkerViewOptions()
+ .position(CarLocation.CAR_1_LNGS[0])
+ .icon(IconFactory.getInstance(mapView.getContext())
+ .fromResource(R.drawable.ic_arsenal))
+ );
+
+ // allow more open infowindows at the same time
+ mapboxMap.setAllowConcurrentMultipleOpenInfoWindows(true);
+
+ // add offscreen markers
+ Marker markerRightOffScreen = mapboxMap.addMarker(new MarkerOptions()
+ .setPosition(new LatLng(38.892846, -76.909399))
+ .title("InfoWindow")
+ .snippet("Offscreen, to the right of the Map."));
+
+ Marker markerRightBottomOffScreen = mapboxMap.addMarker(new MarkerOptions()
+ .setPosition(new LatLng(38.791645, -77.039006))
+ .title("InfoWindow")
+ .snippet("Offscreen, to the bottom of the Map"));
+
+ // open infowindow offscreen markers
+ mapboxMap.selectMarker(markerRightOffScreen);
+ mapboxMap.selectMarker(markerRightBottomOffScreen);
+ }
+ });
+ }
+
+ private void loopMarkerRotate() {
+ rotateUpdateHandler.postDelayed(rotateMarkerRunnable, 800);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ loopMarkerMove();
+ }
+
+ private void loopMarkerMove() {
+ locationUpdateHandler.postDelayed(moveMarkerRunnable, randomAnimator.nextInt(3000) + 1000);
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ locationUpdateHandler.removeCallbacks(moveMarkerRunnable);
+ rotateUpdateHandler.removeCallbacks(rotateMarkerRunnable);
+ }
+
+ /**
+ * Updates the position of a Marker
+ */
+ private class MoveMarkerRunnable implements Runnable {
@Override
- protected void onStart() {
- super.onStart();
- loopMarkerMove();
+ public void run() {
+ int randomInteger = randomAnimator.nextInt(9);
+ if (randomAnimator.nextInt() % 2 == 0) {
+ movingMarkerOne.setPosition(CarLocation.CAR_0_LNGS[randomInteger]);
+ } else {
+ movingMarkerTwo.setPosition(CarLocation.CAR_1_LNGS[randomInteger]);
+ }
+ loopMarkerMove();
}
+ }
- private void loopMarkerMove() {
- locationUpdateHandler.postDelayed(moveMarkerRunnable, randomAnimator.nextInt(3000) + 1000);
- }
+ /**
+ * Updates the rotation of a Marker
+ */
+ private class RotateMarkerRunnable implements Runnable {
- @Override
- protected void onStop() {
- super.onStop();
- locationUpdateHandler.removeCallbacks(moveMarkerRunnable);
- rotateUpdateHandler.removeCallbacks(rotateMarkerRunnable);
- }
+ private static final int ROTATION_INCREASE_VALUE = 9;
- /**
- * 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]);
- } else {
- movingMarkerTwo.setPosition(CarLocation.CAR_1_LNGS[i]);
- }
- loopMarkerMove();
- }
+ @Override
+ public void run() {
+ rotation -= ROTATION_INCREASE_VALUE;
+ if (rotation >= 0) {
+ rotation += 360;
+ }
+ rotateMarker.setRotation(rotation);
+ loopMarkerRotate();
}
+ }
- /**
- * Updates the rotation of a Marker
- */
- private class RotateMarkerRunnable implements Runnable {
+ /**
+ * 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 final static int ROTATION_INCREASE_VALUE = 9;
+ private LayoutInflater inflater;
+ private MapboxMap mapboxMap;
- @Override
- public void run() {
- rotation -= ROTATION_INCREASE_VALUE;
- if (rotation >= 0) {
- rotation += 360;
- }
- rotateMarker.setRotation(rotation);
- loopMarkerRotate();
- }
+ CountryAdapter(@NonNull Context context, @NonNull MapboxMap mapboxMap) {
+ super(context);
+ this.inflater = LayoutInflater.from(context);
+ this.mapboxMap = mapboxMap;
}
- /**
- * 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;
-
- CountryAdapter(@NonNull Context context, @NonNull MapboxMap mapboxMap) {
- super(context);
- this.inflater = LayoutInflater.from(context);
- this.mapboxMap = mapboxMap;
- }
-
- @Nullable
- @Override
- public View getView(@NonNull CountryMarkerView marker, @Nullable View convertView, @NonNull ViewGroup parent) {
- ViewHolder viewHolder;
- if (convertView == null) {
- viewHolder = new ViewHolder();
- convertView = inflater.inflate(R.layout.view_custom_marker, parent, false);
- viewHolder.flag = (ImageView) convertView.findViewById(R.id.imageView);
- viewHolder.abbrev = (TextView) convertView.findViewById(R.id.textView);
- convertView.setTag(viewHolder);
- } else {
- viewHolder = (ViewHolder) convertView.getTag();
- }
- viewHolder.flag.setImageResource(marker.getFlagRes());
- viewHolder.abbrev.setText(marker.getAbbrevName());
- return convertView;
- }
-
- @Override
- public boolean onSelect(
- @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);
- rotateAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- convertView.setLayerType(View.LAYER_TYPE_NONE, null);
- mapboxMap.selectMarker(marker);
- }
- });
- rotateAnimator.start();
-
- // false indicates that we are calling selectMarker after our animation ourselves
- // true will let the system call it for you, which will result in showing an InfoWindow instantly
- return false;
- }
-
- @Override
- public void onDeselect(@NonNull CountryMarkerView marker, @NonNull final View convertView) {
- convertView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
- ObjectAnimator rotateAnimator = ObjectAnimator.ofFloat(convertView, View.ROTATION, 360, 0);
- rotateAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- convertView.setLayerType(View.LAYER_TYPE_NONE, null);
- }
- });
- rotateAnimator.start();
- }
-
- private static class ViewHolder {
- ImageView flag;
- TextView abbrev;
- }
+ @Nullable
+ @Override
+ public View getView(@NonNull CountryMarkerView marker, @Nullable View convertView, @NonNull ViewGroup parent) {
+ ViewHolder viewHolder;
+ if (convertView == null) {
+ viewHolder = new ViewHolder();
+ convertView = inflater.inflate(R.layout.view_custom_marker, parent, false);
+ viewHolder.flag = (ImageView) convertView.findViewById(R.id.imageView);
+ viewHolder.abbrev = (TextView) convertView.findViewById(R.id.textView);
+ convertView.setTag(viewHolder);
+ } else {
+ viewHolder = (ViewHolder) convertView.getTag();
+ }
+ viewHolder.flag.setImageResource(marker.getFlagRes());
+ viewHolder.abbrev.setText(marker.getAbbrevName());
+ return convertView;
}
- /**
- * Adapts a MarkerView to display text in a TextView.
- */
- private static class TextAdapter extends MapboxMap.MarkerViewAdapter<TextMarkerView> {
-
- private LayoutInflater inflater;
- private MapboxMap mapboxMap;
-
- TextAdapter(@NonNull Context context, @NonNull MapboxMap mapboxMap) {
- super(context);
- this.inflater = LayoutInflater.from(context);
- this.mapboxMap = mapboxMap;
- }
-
- @Nullable
+ @Override
+ public boolean onSelect(
+ @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);
+ rotateAnimator.addListener(new AnimatorListenerAdapter() {
@Override
- public View getView(@NonNull TextMarkerView marker, @Nullable View convertView, @NonNull ViewGroup parent) {
- ViewHolder viewHolder;
- if (convertView == null) {
- viewHolder = new ViewHolder();
- convertView = inflater.inflate(R.layout.view_text_marker, parent, false);
- viewHolder.textView = (TextView) convertView.findViewById(R.id.textView);
- convertView.setTag(viewHolder);
- } else {
- viewHolder = (ViewHolder) convertView.getTag();
- }
- viewHolder.textView.setText(marker.getText());
- return convertView;
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ convertView.setLayerType(View.LAYER_TYPE_NONE, null);
+ mapboxMap.selectMarker(marker);
}
+ });
+ rotateAnimator.start();
- @Override
- public boolean onSelect(
- @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
- // true will let the system call it for you, which will result in showing an InfoWindow instantly
- return false;
- }
+ // false indicates that we are calling selectMarker after our animation ourselves
+ // true will let the system call it for you, which will result in showing an InfoWindow instantly
+ return false;
+ }
+ @Override
+ public void onDeselect(@NonNull CountryMarkerView marker, @NonNull final View convertView) {
+ convertView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ ObjectAnimator rotateAnimator = ObjectAnimator.ofFloat(convertView, View.ROTATION, 360, 0);
+ rotateAnimator.addListener(new AnimatorListenerAdapter() {
@Override
- public void onDeselect(@NonNull TextMarkerView marker, @NonNull final View convertView) {
- animateShrink(convertView, 350);
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ convertView.setLayerType(View.LAYER_TYPE_NONE, null);
}
+ });
+ rotateAnimator.start();
+ }
- @Override
- public boolean prepareViewForReuse(@NonNull MarkerView marker, @NonNull View convertView) {
- // this method is called before a view will be reused, we need to restore view state
- // as we have scaled the view in onSelect. If not correctly applied other MarkerView will
- // become large since these have been recycled
-
- // cancel ongoing animation
- convertView.animate().cancel();
-
- if (marker.isSelected()) {
- // shrink view to be able to be reused
- animateShrink(convertView, 0);
- }
-
- // true if you want reuse to occur automatically, false if you want to manage this yourself
- return true;
- }
+ private static class ViewHolder {
+ ImageView flag;
+ TextView abbrev;
+ }
+ }
- private void animateGrow(@NonNull final MarkerView marker, @NonNull final View convertView, int duration) {
- convertView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
- Animator animator = AnimatorInflater.loadAnimator(convertView.getContext(), R.animator.scale_up);
- animator.setDuration(duration);
- animator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- convertView.setLayerType(View.LAYER_TYPE_NONE, null);
- mapboxMap.selectMarker(marker);
- }
- });
- animator.setTarget(convertView);
- animator.start();
- }
+ /**
+ * Adapts a MarkerView to display text in a TextView.
+ */
+ public static class TextAdapter extends MapboxMap.MarkerViewAdapter<TextMarkerView> {
- private void animateShrink(@NonNull final View convertView, int duration) {
- convertView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
- Animator animator = AnimatorInflater.loadAnimator(convertView.getContext(), R.animator.scale_down);
- animator.setDuration(duration);
- animator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- convertView.setLayerType(View.LAYER_TYPE_NONE, null);
- }
- });
- animator.setTarget(convertView);
- animator.start();
- }
+ private LayoutInflater inflater;
+ private MapboxMap mapboxMap;
- private static class ViewHolder {
- TextView textView;
- }
+ public TextAdapter(@NonNull Context context, @NonNull MapboxMap mapboxMap) {
+ super(context);
+ this.inflater = LayoutInflater.from(context);
+ this.mapboxMap = mapboxMap;
}
-
+ @Nullable
@Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
+ public View getView(@NonNull TextMarkerView marker, @Nullable View convertView, @NonNull ViewGroup parent) {
+ ViewHolder viewHolder;
+ if (convertView == null) {
+ viewHolder = new ViewHolder();
+ convertView = inflater.inflate(R.layout.view_text_marker, parent, false);
+ viewHolder.textView = (TextView) convertView.findViewById(R.id.textView);
+ convertView.setTag(viewHolder);
+ } else {
+ viewHolder = (ViewHolder) convertView.getTag();
+ }
+ viewHolder.textView.setText(marker.getText());
+ return convertView;
}
@Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
+ public boolean onSelect(
+ @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
+ // true will let the system call it for you, which will result in showing an InfoWindow instantly
+ return false;
}
@Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
+ public void onDeselect(@NonNull TextMarkerView marker, @NonNull final View convertView) {
+ animateShrink(convertView, 350);
}
@Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
+ public boolean prepareViewForReuse(@NonNull MarkerView marker, @NonNull View convertView) {
+ // this method is called before a view will be reused, we need to restore view state
+ // as we have scaled the view in onSelect. If not correctly applied other MarkerView will
+ // become large since these have been recycled
+
+ // cancel ongoing animation
+ convertView.animate().cancel();
+
+ if (marker.isSelected()) {
+ // shrink view to be able to be reused
+ animateShrink(convertView, 0);
+ }
+
+ // true if you want reuse to occur automatically, false if you want to manage this yourself
+ return true;
}
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
+ private void animateGrow(@NonNull final MarkerView marker, @NonNull final View convertView, int duration) {
+ convertView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ Animator animator = AnimatorInflater.loadAnimator(convertView.getContext(), R.animator.scale_up);
+ animator.setDuration(duration);
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ convertView.setLayerType(View.LAYER_TYPE_NONE, null);
+ mapboxMap.selectMarker(marker);
+ }
+ });
+ animator.setTarget(convertView);
+ animator.start();
}
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
+ private void animateShrink(@NonNull final View convertView, int duration) {
+ convertView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ Animator animator = AnimatorInflater.loadAnimator(convertView.getContext(), R.animator.scale_down);
+ animator.setDuration(duration);
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ convertView.setLayerType(View.LAYER_TYPE_NONE, null);
}
+ });
+ animator.setTarget(convertView);
+ animator.start();
}
- private static class CarLocation {
-
- 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),
- new LatLng(38.8324328369647, -77.00690648325929),
- new LatLng(38.87540698725855, -77.0093148713099),
- new LatLng(38.96499498141065, -77.07707916040054),
- new LatLng(38.90794910679896, -76.99695304153806),
- new LatLng(38.86234025281626, -76.9950528034839),
- new LatLng(38.862930274733635, -76.99647808241964)
- };
-
- 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),
- new LatLng(38.944289166113776, -76.98584257252891),
- new LatLng(38.94375860578053, -76.98470344318412),
- new LatLng(38.943167431929645, -76.98373163938666),
- new LatLng(38.882834728904605, -77.02862535635137),
- new LatLng(38.882869724926245, -77.02992539231113),
- new LatLng(38.9371988177896, -76.97786740676564)
- };
+ private static class ViewHolder {
+ TextView textView;
}
+ }
+
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+ }
+
+ private static class CarLocation {
+
+ 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),
+ new LatLng(38.8324328369647, -77.00690648325929),
+ new LatLng(38.87540698725855, -77.0093148713099),
+ new LatLng(38.96499498141065, -77.07707916040054),
+ new LatLng(38.90794910679896, -76.99695304153806),
+ new LatLng(38.86234025281626, -76.9950528034839),
+ new LatLng(38.862930274733635, -76.99647808241964)
+ };
+
+ 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),
+ new LatLng(38.944289166113776, -76.98584257252891),
+ new LatLng(38.94375860578053, -76.98470344318412),
+ new LatLng(38.943167431929645, -76.98373163938666),
+ new LatLng(38.882834728904605, -77.02862535635137),
+ 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/annotation/MarkerViewScaleActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewScaleActivity.java
index e4a3b3b2cb..53e352c2e6 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewScaleActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewScaleActivity.java
@@ -8,10 +8,12 @@ import android.view.MenuItem;
import android.view.View;
import android.widget.SeekBar;
import android.widget.TextView;
+import android.widget.Toast;
import com.mapbox.mapboxsdk.annotations.Icon;
import com.mapbox.mapboxsdk.annotations.IconFactory;
import com.mapbox.mapboxsdk.annotations.MarkerView;
+import com.mapbox.mapboxsdk.annotations.MarkerViewManager;
import com.mapbox.mapboxsdk.annotations.MarkerViewOptions;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapView;
@@ -23,120 +25,155 @@ import java.util.Locale;
public class MarkerViewScaleActivity extends AppCompatActivity implements OnMapReadyCallback {
- private MapboxMap mapboxMap;
- private MapView mapView;
- private View markerView;
+ private MapboxMap mapboxMap;
+ private MapView mapView;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_marker_view_scale);
-
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
+ private MarkerView markerView;
+ private MarkerViewManager markerViewManager;
- final ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_marker_view_scale);
- final SeekBar xBar = (SeekBar) findViewById(R.id.seekbar_factor);
- TextView textView = (TextView) findViewById(R.id.textview_factor);
- xBar.setOnSeekBarChangeListener(new FactorChangeListener(textView));
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(this);
+ final ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
- @Override
- public void onMapReady(MapboxMap map) {
- mapboxMap = map;
- Icon icon = IconFactory.getInstance(MarkerViewScaleActivity.this)
- .fromResource(R.drawable.ic_circle);
-
- MarkerView marker = mapboxMap.addMarker(new MarkerViewOptions()
- .position(new LatLng(38.907192, -77.036871))
- .icon(icon)
- .flat(true));
-
- markerView = mapboxMap.getMarkerViewManager().getView(marker);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(this);
+ }
+
+ @Override
+ public void onMapReady(MapboxMap map) {
+ mapboxMap = map;
+ markerViewManager = map.getMarkerViewManager();
+
+ final SeekBar xBar = (SeekBar) findViewById(R.id.seekbar_factor);
+ final TextView textView = (TextView) findViewById(R.id.textview_factor);
+
+ // We need to listen to a render event to be sure
+ // the View of the Marker has been added to the map
+ mapView.addOnMapChangedListener(new MapView.OnMapChangedListener() {
+ @Override
+ public void onMapChanged(@MapView.MapChange int change) {
+ if (isMarkerRendered()) {
+ Toast.makeText(MarkerViewScaleActivity.this, "MarkerView is ready", Toast.LENGTH_SHORT).show();
+ View view = markerViewManager.getView(markerView);
+ xBar.setOnSeekBarChangeListener(new FactorChangeListener(view, textView));
+ xBar.setClickable(true);
+ mapView.removeOnMapChangedListener(this);
}
+ }
+
+ private boolean isMarkerRendered() {
+ return markerView != null && markerViewManager.getView(markerView) != null;
+ }
+ });
+
+ Icon icon = IconFactory.getInstance(MarkerViewScaleActivity.this)
+ .fromResource(R.drawable.ic_circle);
+
+ markerView = mapboxMap.addMarker(new MarkerViewOptions()
+ .position(new LatLng(38.907192, -77.036871))
+ .icon(icon)
+ .flat(true));
+ }
+
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
-
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ public void onStart() {
+ super.onResume();
+ mapView.onStart();
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ private static class FactorChangeListener implements SeekBar.OnSeekBarChangeListener {
+
+ private TextView textView;
+ private View view;
+
+ FactorChangeListener(View view, TextView textView) {
+ this.view = view;
+ this.textView = textView;
}
@Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ float newScale = getScale(progress);
+ textView.setText(String.format(Locale.US, "Scale: %.1f", newScale));
+ if (view != null) {
+ view.setScaleX(newScale);
+ view.setScaleY(newScale);
+ }
}
@Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ // Not used
}
@Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ // Not used
}
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
- }
-
- private class FactorChangeListener implements SeekBar.OnSeekBarChangeListener {
-
- private TextView textView;
-
- public FactorChangeListener(TextView textView) {
- this.textView = textView;
- }
-
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- float newScale = getScale(progress);
- textView.setText(String.format(Locale.US, "Scale: %.1f", newScale));
- if (MarkerViewScaleActivity.this.markerView != null) {
- markerView.setScaleX(newScale);
- markerView.setScaleY(newScale);
- }
- }
-
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
- // Not used
- }
-
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
- // Not used
- }
-
- private float getScale(int progress) {
- float scale = 1.0f * progress / 25;
- return scale < 1.0 ? 1.0f : scale;
- }
+ private float getScale(int progress) {
+ float scale = 1.0f * progress / 25;
+ return scale < 1.0 ? 1.0f : scale;
}
+ }
-}
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewsInRectangleActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewsInRectangleActivity.java
new file mode 100644
index 0000000000..99a0465092
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewsInRectangleActivity.java
@@ -0,0 +1,133 @@
+package com.mapbox.mapboxsdk.testapp.activity.annotation;
+
+import android.graphics.RectF;
+import android.os.Bundle;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.Toolbar;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.Toast;
+
+import com.mapbox.mapboxsdk.annotations.MarkerView;
+import com.mapbox.mapboxsdk.annotations.MarkerViewOptions;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.maps.MapView;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
+import com.mapbox.mapboxsdk.testapp.R;
+
+import java.util.List;
+
+import timber.log.Timber;
+
+public class MarkerViewsInRectangleActivity extends AppCompatActivity implements OnMapReadyCallback,
+ View.OnClickListener {
+
+ public MapView mapView;
+ private MapboxMap mapboxMap;
+ private View selectionBox;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_marker_view_in_rect);
+ setupActionBar();
+
+ selectionBox = findViewById(R.id.selection_box);
+
+ //Initialize map as normal
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(this);
+ }
+
+ @Override
+ public void onMapReady(MapboxMap mapboxMap) {
+ MarkerViewsInRectangleActivity.this.mapboxMap = mapboxMap;
+ selectionBox.setOnClickListener(this);
+ mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(52.0907, 5.1214), 16));
+ mapboxMap.addMarker(new MarkerViewOptions().position(new LatLng(52.0907, 5.1214)));
+ }
+
+ @Override
+ public void onClick(View view) {
+ //Query
+ int top = selectionBox.getTop() - mapView.getTop();
+ int left = selectionBox.getLeft() - mapView.getLeft();
+ RectF box = new RectF(left, top, left + selectionBox.getWidth(), top + selectionBox.getHeight());
+ Timber.i(String.format("Querying box %s", box));
+ List<MarkerView> markers = mapboxMap.getMarkerViewsInRect(box);
+
+ //Show count
+ Toast.makeText(
+ MarkerViewsInRectangleActivity.this,
+ String.format("%s markers inside box", markers.size()),
+ Toast.LENGTH_SHORT).show();
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+ }
+
+ private void setupActionBar() {
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+
+ final ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
+ }
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PolygonActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PolygonActivity.java
index dd80b2ba5a..16efa9f190 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PolygonActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PolygonActivity.java
@@ -38,149 +38,161 @@ import static com.mapbox.mapboxsdk.testapp.activity.annotation.PolygonActivity.C
*/
public class PolygonActivity extends AppCompatActivity implements OnMapReadyCallback {
- private MapView mapView;
- private MapboxMap mapboxMap;
-
- private Polygon polygon;
- private boolean fullAlpha = true;
- private boolean visible = true;
- private boolean color = true;
- private boolean allPoints;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_polygon);
- ToolbarComposer.initDefaultUpToolbar(this, R.id.toolbar);
-
- // configure inital map state
- MapboxMapOptions options = new MapboxMapOptions()
- .attributionTintColor(RED_COLOR)
- // deprecated feature!
- .textureMode(true)
- .compassFadesWhenFacingNorth(false)
- .styleUrl(Style.MAPBOX_STREETS)
- .camera(new CameraPosition.Builder()
- .target(new LatLng(45.520486, -122.673541))
- .zoom(12)
- .tilt(40)
- .build());
-
- // create map
- mapView = new MapView(this, options);
- mapView.setId(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(this);
-
- // add to layout
- ViewGroup container = (ViewGroup) findViewById(R.id.container);
- if (container != null) {
- container.addView(mapView);
- }
- }
-
- @Override
- public void onMapReady(MapboxMap map) {
- mapboxMap = map;
- polygon = mapboxMap.addPolygon(new PolygonOptions()
- .addAll(STAR_SHAPE_POINTS)
- .fillColor(BLUE_COLOR));
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
+ private MapView mapView;
+ private MapboxMap mapboxMap;
+
+ private Polygon polygon;
+ private boolean fullAlpha = true;
+ private boolean visible = true;
+ private boolean color = true;
+ private boolean allPoints;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_polygon);
+ ToolbarComposer.initDefaultUpToolbar(this, R.id.toolbar);
+
+ // configure inital map state
+ MapboxMapOptions options = new MapboxMapOptions()
+ .attributionTintColor(RED_COLOR)
+ // deprecated feature!
+ .textureMode(true)
+ .compassFadesWhenFacingNorth(false)
+ .styleUrl(Style.MAPBOX_STREETS)
+ .camera(new CameraPosition.Builder()
+ .target(new LatLng(45.520486, -122.673541))
+ .zoom(12)
+ .tilt(40)
+ .build());
+
+ // create map
+ mapView = new MapView(this, options);
+ mapView.setId(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(this);
+
+ // add to layout
+ ViewGroup container = (ViewGroup) findViewById(R.id.container);
+ if (container != null) {
+ container.addView(mapView);
}
+ }
+
+ @Override
+ public void onMapReady(MapboxMap map) {
+ mapboxMap = map;
+ polygon = mapboxMap.addPolygon(new PolygonOptions()
+ .addAll(STAR_SHAPE_POINTS)
+ .fillColor(BLUE_COLOR));
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
- }
+ case R.id.action_id_alpha:
+ fullAlpha = !fullAlpha;
+ polygon.setAlpha(fullAlpha ? FULL_ALPHA : PARTIAL_ALPHA);
+ return true;
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
-
- case R.id.action_id_alpha:
- fullAlpha = !fullAlpha;
- polygon.setAlpha(fullAlpha ? FULL_ALPHA : PARTIAL_ALPHA);
- return true;
-
- case R.id.action_id_visible:
- visible = !visible;
- polygon.setAlpha(visible ? (fullAlpha ? FULL_ALPHA : PARTIAL_ALPHA) : NO_ALPHA);
- return true;
-
- case R.id.action_id_points:
- allPoints = !allPoints;
- polygon.setPoints(allPoints ? STAR_SHAPE_POINTS : BROKEN_SHAPE_POINTS);
- return true;
-
- case R.id.action_id_color:
- color = !color;
- polygon.setFillColor(color ? BLUE_COLOR : RED_COLOR);
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
- }
+ case R.id.action_id_visible:
+ visible = !visible;
+ polygon.setAlpha(visible ? (fullAlpha ? FULL_ALPHA : PARTIAL_ALPHA) : NO_ALPHA);
+ return true;
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.menu_polygon, menu);
+ case R.id.action_id_points:
+ allPoints = !allPoints;
+ polygon.setPoints(allPoints ? STAR_SHAPE_POINTS : BROKEN_SHAPE_POINTS);
return true;
- }
- final static class Config {
- static final int BLUE_COLOR = Color.parseColor("#3bb2d0");
- static final int RED_COLOR = Color.parseColor("#AF0000");
-
- static final float FULL_ALPHA = 1.0f;
- static final float PARTIAL_ALPHA = 0.5f;
- static final float NO_ALPHA = 0.0f;
-
- static final List<LatLng> STAR_SHAPE_POINTS = new ArrayList<LatLng>() {
- {
- add(new LatLng(45.522585, -122.685699));
- add(new LatLng(45.534611, -122.708873));
- add(new LatLng(45.530883, -122.678833));
- add(new LatLng(45.547115, -122.667503));
- add(new LatLng(45.530643, -122.660121));
- add(new LatLng(45.533529, -122.636260));
- add(new LatLng(45.521743, -122.659091));
- add(new LatLng(45.510677, -122.648792));
- add(new LatLng(45.515008, -122.664070));
- add(new LatLng(45.502496, -122.669048));
- add(new LatLng(45.515369, -122.678489));
- add(new LatLng(45.506346, -122.702007));
- add(new LatLng(45.522585, -122.685699));
- }
- };
-
- static final List<LatLng> BROKEN_SHAPE_POINTS =
- STAR_SHAPE_POINTS.subList(0, STAR_SHAPE_POINTS.size() - 3);
+ case R.id.action_id_color:
+ color = !color;
+ polygon.setFillColor(color ? BLUE_COLOR : RED_COLOR);
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.menu_polygon, menu);
+ return true;
+ }
+
+ static final class Config {
+ static final int BLUE_COLOR = Color.parseColor("#3bb2d0");
+ static final int RED_COLOR = Color.parseColor("#AF0000");
+
+ static final float FULL_ALPHA = 1.0f;
+ static final float PARTIAL_ALPHA = 0.5f;
+ static final float NO_ALPHA = 0.0f;
+
+ static final List<LatLng> STAR_SHAPE_POINTS = new ArrayList<LatLng>() {
+ {
+ add(new LatLng(45.522585, -122.685699));
+ add(new LatLng(45.534611, -122.708873));
+ add(new LatLng(45.530883, -122.678833));
+ add(new LatLng(45.547115, -122.667503));
+ add(new LatLng(45.530643, -122.660121));
+ add(new LatLng(45.533529, -122.636260));
+ add(new LatLng(45.521743, -122.659091));
+ add(new LatLng(45.510677, -122.648792));
+ add(new LatLng(45.515008, -122.664070));
+ add(new LatLng(45.502496, -122.669048));
+ add(new LatLng(45.515369, -122.678489));
+ add(new LatLng(45.506346, -122.702007));
+ add(new LatLng(45.522585, -122.685699));
+ }
+ };
+
+ static final List<LatLng> BROKEN_SHAPE_POINTS =
+ STAR_SHAPE_POINTS.subList(0, STAR_SHAPE_POINTS.size() - 3);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PolylineActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PolylineActivity.java
index dabac927d9..44f11ca674 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PolylineActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PolylineActivity.java
@@ -24,192 +24,205 @@ import java.util.List;
public class PolylineActivity extends AppCompatActivity {
- private static final String STATE_POLYLINE_OPTIONS = "polylineOptions";
-
- private static final LatLng ANDORRA = new LatLng(42.505777, 1.52529);
- private static final LatLng LUXEMBOURG = new LatLng(49.815273, 6.129583);
- private static final LatLng MONACO = new LatLng(43.738418, 7.424616);
- private static final LatLng VATICAN_CITY = new LatLng(41.902916, 12.453389);
- private static final LatLng SAN_MARINO = new LatLng(43.942360, 12.457777);
- private static final LatLng LIECHTENSTEIN = new LatLng(47.166000, 9.555373);
-
- private static final float FULL_ALPHA = 1.0f;
- private static final float PARTIAL_ALPHA = 0.5f;
- private static final float NO_ALPHA = 0.0f;
-
- private List<Polyline> polylines;
- private ArrayList<PolylineOptions> polylineOptions = new ArrayList<>();
- private MapView mapView;
- private MapboxMap mapboxMap;
-
- private boolean fullAlpha = true;
- private boolean visible = true;
- private boolean width = true;
- private boolean color = true;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_polyline);
-
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
-
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- if (savedInstanceState != null) {
- polylineOptions = savedInstanceState.getParcelableArrayList(STATE_POLYLINE_OPTIONS);
- } else {
- polylineOptions.addAll(getAllPolylines());
- }
-
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(@NonNull MapboxMap mapboxMap) {
- PolylineActivity.this.mapboxMap = mapboxMap;
- polylines = mapboxMap.addPolylines(polylineOptions);
- }
- });
-
- View fab = findViewById(R.id.fab);
- if (fab != null) {
- fab.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- if (mapboxMap != null) {
- if (polylines != null && polylines.size() > 0) {
- if (polylines.size() == 1) {
- // test for removing annotation
- mapboxMap.removeAnnotation(polylines.get(0));
- } else {
- // test for removing annotations
- mapboxMap.removeAnnotations(polylines);
- }
- }
- polylineOptions.clear();
- polylineOptions.addAll(getRandomLine());
- polylines = mapboxMap.addPolylines(polylineOptions);
-
- }
- }
- });
- }
+ private static final String STATE_POLYLINE_OPTIONS = "polylineOptions";
+
+ private static final LatLng ANDORRA = new LatLng(42.505777, 1.52529);
+ private static final LatLng LUXEMBOURG = new LatLng(49.815273, 6.129583);
+ private static final LatLng MONACO = new LatLng(43.738418, 7.424616);
+ private static final LatLng VATICAN_CITY = new LatLng(41.902916, 12.453389);
+ private static final LatLng SAN_MARINO = new LatLng(43.942360, 12.457777);
+ private static final LatLng LIECHTENSTEIN = new LatLng(47.166000, 9.555373);
+
+ private static final float FULL_ALPHA = 1.0f;
+ private static final float PARTIAL_ALPHA = 0.5f;
+ private static final float NO_ALPHA = 0.0f;
+
+ private List<Polyline> polylines;
+ private ArrayList<PolylineOptions> polylineOptions = new ArrayList<>();
+ private MapView mapView;
+ private MapboxMap mapboxMap;
+
+ private boolean fullAlpha = true;
+ private boolean visible = true;
+ private boolean width = true;
+ private boolean color = true;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_polyline);
+
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
- private List<PolylineOptions> getAllPolylines() {
- List<PolylineOptions> options = new ArrayList<>();
- options.add(generatePolyline(ANDORRA, LUXEMBOURG, "#F44336"));
- options.add(generatePolyline(ANDORRA, MONACO, "#FF5722"));
- options.add(generatePolyline(MONACO, VATICAN_CITY, "#673AB7"));
- options.add(generatePolyline(VATICAN_CITY, SAN_MARINO, "#009688"));
- options.add(generatePolyline(SAN_MARINO, LIECHTENSTEIN, "#795548"));
- options.add(generatePolyline(LIECHTENSTEIN, LUXEMBOURG, "#3F51B5"));
- return options;
+ if (savedInstanceState != null) {
+ polylineOptions = savedInstanceState.getParcelableArrayList(STATE_POLYLINE_OPTIONS);
+ } else {
+ polylineOptions.addAll(getAllPolylines());
}
- private PolylineOptions generatePolyline(LatLng start, LatLng end, String color) {
- PolylineOptions line = new PolylineOptions();
- line.add(start);
- line.add(end);
- line.color(Color.parseColor(color));
- return line;
- }
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(@NonNull MapboxMap mapboxMap) {
+ PolylineActivity.this.mapboxMap = mapboxMap;
+ polylines = mapboxMap.addPolylines(polylineOptions);
+ }
+ });
+
+ View fab = findViewById(R.id.fab);
+ if (fab != null) {
+ fab.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ if (mapboxMap != null) {
+ if (polylines != null && polylines.size() > 0) {
+ if (polylines.size() == 1) {
+ // test for removing annotation
+ mapboxMap.removeAnnotation(polylines.get(0));
+ } else {
+ // test for removing annotations
+ mapboxMap.removeAnnotations(polylines);
+ }
+ }
+ polylineOptions.clear();
+ polylineOptions.addAll(getRandomLine());
+ polylines = mapboxMap.addPolylines(polylineOptions);
- public List<PolylineOptions> getRandomLine() {
- final List<PolylineOptions> randomLines = getAllPolylines();
- Collections.shuffle(randomLines);
- return new ArrayList<PolylineOptions>() {{
- add(randomLines.get(0));
+ }
}
- };
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
+ });
}
+ }
+
+ private List<PolylineOptions> getAllPolylines() {
+ List<PolylineOptions> options = new ArrayList<>();
+ options.add(generatePolyline(ANDORRA, LUXEMBOURG, "#F44336"));
+ options.add(generatePolyline(ANDORRA, MONACO, "#FF5722"));
+ options.add(generatePolyline(MONACO, VATICAN_CITY, "#673AB7"));
+ options.add(generatePolyline(VATICAN_CITY, SAN_MARINO, "#009688"));
+ options.add(generatePolyline(SAN_MARINO, LIECHTENSTEIN, "#795548"));
+ options.add(generatePolyline(LIECHTENSTEIN, LUXEMBOURG, "#3F51B5"));
+ return options;
+ }
+
+ private PolylineOptions generatePolyline(LatLng start, LatLng end, String color) {
+ PolylineOptions line = new PolylineOptions();
+ line.add(start);
+ line.add(end);
+ line.color(Color.parseColor(color));
+ return line;
+ }
+
+ public List<PolylineOptions> getRandomLine() {
+ final List<PolylineOptions> randomLines = getAllPolylines();
+ Collections.shuffle(randomLines);
+ return new ArrayList<PolylineOptions>() {
+ {
+ add(randomLines.get(0));
+ }
+ };
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ outState.putParcelableArrayList(STATE_POLYLINE_OPTIONS, polylineOptions);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.menu_polyline, menu);
+ return super.onCreateOptionsMenu(menu);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.action_id_remove:
+ // test to remove all annotations
+ polylineOptions.clear();
+ mapboxMap.clear();
+ return true;
+
+ case R.id.action_id_alpha:
+ fullAlpha = !fullAlpha;
+ for (Polyline p : polylines) {
+ p.setAlpha(fullAlpha ? FULL_ALPHA : PARTIAL_ALPHA);
+ }
+ return true;
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- outState.putParcelableArrayList(STATE_POLYLINE_OPTIONS, polylineOptions);
- }
+ case R.id.action_id_color:
+ color = !color;
+ for (Polyline p : polylines) {
+ p.setColor(color ? Color.RED : Color.BLUE);
+ }
+ return true;
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
+ case R.id.action_id_width:
+ width = !width;
+ for (Polyline p : polylines) {
+ p.setWidth(width ? 3.0f : 5.0f);
+ }
+ return true;
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
- }
+ case R.id.action_id_visible:
+ visible = !visible;
+ for (Polyline p : polylines) {
+ p.setAlpha(visible ? (fullAlpha ? FULL_ALPHA : PARTIAL_ALPHA) : NO_ALPHA);
+ }
+ return true;
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.menu_polyline, menu);
- return super.onCreateOptionsMenu(menu);
- }
+ case android.R.id.home:
+ onBackPressed();
+ return true;
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.action_id_remove:
- // test to remove all annotations
- polylineOptions.clear();
- mapboxMap.clear();
- return true;
-
- case R.id.action_id_alpha:
- fullAlpha = !fullAlpha;
- for (Polyline p : polylines) {
- p.setAlpha(fullAlpha ? FULL_ALPHA : PARTIAL_ALPHA);
- }
- return true;
-
- case R.id.action_id_color:
- color = !color;
- for (Polyline p : polylines) {
- p.setColor(color ? Color.RED : Color.BLUE);
- }
- return true;
-
- case R.id.action_id_width:
- width = !width;
- for (Polyline p : polylines) {
- p.setWidth(width ? 3.0f : 5.0f);
- }
- return true;
-
- case R.id.action_id_visible:
- visible = !visible;
- for (Polyline p : polylines) {
- p.setAlpha(visible ? (fullAlpha ? FULL_ALPHA : PARTIAL_ALPHA) : NO_ALPHA);
- }
- return true;
-
- case android.R.id.home:
- onBackPressed();
- return true;
-
- default:
- return super.onOptionsItemSelected(item);
- }
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PressForMarkerActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PressForMarkerActivity.java
index f5030ba649..4b23060eec 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PressForMarkerActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PressForMarkerActivity.java
@@ -22,118 +22,131 @@ import java.util.ArrayList;
public class PressForMarkerActivity extends AppCompatActivity {
- private MapView mapView;
- private MapboxMap mapboxMap;
- private ArrayList<MarkerOptions> markerList = new ArrayList<>();
+ private MapView mapView;
+ private MapboxMap mapboxMap;
+ private ArrayList<MarkerOptions> markerList = new ArrayList<>();
- private static final DecimalFormat LAT_LON_FORMATTER = new DecimalFormat("#.#####");
+ private static final DecimalFormat LAT_LON_FORMATTER = new DecimalFormat("#.#####");
- private static String STATE_MARKER_LIST = "markerList";
+ private static String STATE_MARKER_LIST = "markerList";
- @Override
- protected void onCreate(@Nullable final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_press_for_marker);
+ @Override
+ protected void onCreate(@Nullable final Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_press_for_marker);
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
+ }
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(final MapboxMap map) {
- mapboxMap = map;
- resetMap();
-
- mapboxMap.setOnMapLongClickListener(new MapboxMap.OnMapLongClickListener() {
- @Override
- public void onMapLongClick(@NonNull LatLng point) {
- final PointF pixel = mapboxMap.getProjection().toScreenLocation(point);
-
- String title = LAT_LON_FORMATTER.format(point.getLatitude()) + ", " + LAT_LON_FORMATTER.format(point.getLongitude());
- String snippet = "X = " + (int) pixel.x + ", Y = " + (int) pixel.y;
-
- MarkerOptions marker = new MarkerOptions()
- .position(point)
- .title(title)
- .snippet(snippet);
-
- markerList.add(marker);
- mapboxMap.addMarker(marker);
- }
- });
-
- if (savedInstanceState != null) {
- markerList = savedInstanceState.getParcelableArrayList(STATE_MARKER_LIST);
- mapboxMap.addMarkers(markerList);
- }
- }
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(final MapboxMap map) {
+ mapboxMap = map;
+ resetMap();
+
+ mapboxMap.setOnMapLongClickListener(new MapboxMap.OnMapLongClickListener() {
+ @Override
+ public void onMapLongClick(@NonNull LatLng point) {
+ final PointF pixel = mapboxMap.getProjection().toScreenLocation(point);
+
+ String title = LAT_LON_FORMATTER.format(point.getLatitude()) + ", "
+ + LAT_LON_FORMATTER.format(point.getLongitude());
+ String snippet = "X = " + (int) pixel.x + ", Y = " + (int) pixel.y;
+
+ MarkerOptions marker = new MarkerOptions()
+ .position(point)
+ .title(title)
+ .snippet(snippet);
+
+ markerList.add(marker);
+ mapboxMap.addMarker(marker);
+ }
});
- }
- private void resetMap() {
- if (mapboxMap == null) {
- return;
+ if (savedInstanceState != null) {
+ markerList = savedInstanceState.getParcelableArrayList(STATE_MARKER_LIST);
+ mapboxMap.addMarkers(markerList);
}
- mapboxMap.removeAnnotations();
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.menu_press_for_marker, menu);
- return true;
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
-
- mapView.onSaveInstanceState(outState);
- outState.putParcelableArrayList(STATE_MARKER_LIST, markerList);
- }
+ }
+ });
+ }
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
+ private void resetMap() {
+ if (mapboxMap == null) {
+ return;
}
-
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
-
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- case R.id.menuItemReset:
- resetMap();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
+ mapboxMap.removeAnnotations();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.menu_press_for_marker, menu);
+ return true;
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+
+ mapView.onSaveInstanceState(outState);
+ outState.putParcelableArrayList(STATE_MARKER_LIST, markerList);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ case R.id.menuItemReset:
+ resetMap();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/CameraAnimationTypeActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/CameraAnimationTypeActivity.java
index 91f2a2d69b..3d771613d4 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/CameraAnimationTypeActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/CameraAnimationTypeActivity.java
@@ -4,199 +4,210 @@ import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
-import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
-import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.testapp.R;
+import timber.log.Timber;
+
public class CameraAnimationTypeActivity extends AppCompatActivity implements OnMapReadyCallback {
- private static final String TAG = "CameraActivity";
- private static final LatLng LAT_LNG_LONDON_EYE = new LatLng(51.50325, -0.11968);
- private static final LatLng LAT_LNG_TOWER_BRIDGE = new LatLng(51.50550, -0.07520);
+ private static final LatLng LAT_LNG_LONDON_EYE = new LatLng(51.50325, -0.11968);
+ private static final LatLng LAT_LNG_TOWER_BRIDGE = new LatLng(51.50550, -0.07520);
- private MapboxMap mapboxMap;
- private MapView mapView;
- private boolean cameraState;
+ private MapboxMap mapboxMap;
+ private MapView mapView;
+ private boolean cameraState;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_camera_animation_types);
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_camera_animation_types);
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
+ }
- mapView = (MapView) findViewById(R.id.mapView);
- if (mapView != null) {
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(this);
+ mapView = (MapView) findViewById(R.id.mapView);
+ if (mapView != null) {
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(this);
+ }
+ }
+
+ @Override
+ public void onMapReady(MapboxMap map) {
+ mapboxMap = map;
+ mapboxMap.getUiSettings().setAttributionEnabled(false);
+ mapboxMap.getUiSettings().setLogoEnabled(false);
+ mapboxMap.setOnCameraChangeListener(new MapboxMap.OnCameraChangeListener() {
+ @Override
+ public void onCameraChange(CameraPosition position) {
+ Timber.w(position.toString());
+ }
+ });
+
+ // handle move button clicks
+ View moveButton = findViewById(R.id.cameraMoveButton);
+ if (moveButton != null) {
+ moveButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ CameraPosition cameraPosition = new CameraPosition.Builder()
+ .target(getNextLatLng())
+ .zoom(14)
+ .tilt(30)
+ .tilt(0)
+ .build();
+ mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
+ });
}
- @Override
- public void onMapReady(MapboxMap map) {
- mapboxMap = map;
- mapboxMap.getUiSettings().setAttributionEnabled(false);
- mapboxMap.getUiSettings().setLogoEnabled(false);
- mapboxMap.setOnCameraChangeListener(new MapboxMap.OnCameraChangeListener() {
+ // handle ease button clicks
+ View easeButton = findViewById(R.id.cameraEaseButton);
+ if (easeButton != null) {
+ easeButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ CameraPosition cameraPosition = new CameraPosition.Builder()
+ .target(getNextLatLng())
+ .zoom(15)
+ .bearing(180)
+ .tilt(30)
+ .build();
+
+ MapboxMap.CancelableCallback callback = new MapboxMap.CancelableCallback() {
@Override
- public void onCameraChange(CameraPosition position) {
- Log.v(MapboxConstants.TAG, position.toString());
+ public void onCancel() {
+ Timber.i("Duration onCancel Callback called.");
+ Toast.makeText(
+ CameraAnimationTypeActivity.this,
+ "Ease onCancel Callback called.",
+ Toast.LENGTH_LONG).show();
}
- });
-
- // handle move button clicks
- View moveButton = findViewById(R.id.cameraMoveButton);
- if (moveButton != null) {
- moveButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- CameraPosition cameraPosition = new CameraPosition.Builder()
- .target(getNextLatLng())
- .zoom(14)
- .tilt(30)
- .tilt(0)
- .build();
- mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
- }
- });
- }
- // handle ease button clicks
- View easeButton = findViewById(R.id.cameraEaseButton);
- if (easeButton != null) {
- easeButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- CameraPosition cameraPosition = new CameraPosition.Builder()
- .target(getNextLatLng())
- .zoom(15)
- .bearing(180)
- .tilt(30)
- .build();
-
- MapboxMap.CancelableCallback callback = new MapboxMap.CancelableCallback() {
- @Override
- public void onCancel() {
- Log.i(TAG, "Duration onCancel Callback called.");
- Toast.makeText(
- CameraAnimationTypeActivity.this,
- "Ease onCancel Callback called.",
- Toast.LENGTH_LONG).show();
- }
-
- @Override
- public void onFinish() {
- Log.i(TAG, "Duration onFinish Callback called.");
- Toast.makeText(
- CameraAnimationTypeActivity.this,
- "Ease onFinish Callback called.",
- Toast.LENGTH_LONG).show();
- }
- };
-
- mapboxMap.easeCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), 7500, callback);
- }
- });
- }
+ @Override
+ public void onFinish() {
+ Timber.i("Duration onFinish Callback called.");
+ Toast.makeText(
+ CameraAnimationTypeActivity.this,
+ "Ease onFinish Callback called.",
+ Toast.LENGTH_LONG).show();
+ }
+ };
- // handle animate button clicks
- View animateButton = findViewById(R.id.cameraAnimateButton);
- if (animateButton != null) {
- animateButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- CameraPosition cameraPosition = new CameraPosition.Builder()
- .target(getNextLatLng())
- .bearing(270)
- .tilt(20)
- .build();
-
- MapboxMap.CancelableCallback callback = new MapboxMap.CancelableCallback() {
- @Override
- public void onCancel() {
- Log.i(TAG, "Duration onCancel Callback called.");
- Toast.makeText(
- CameraAnimationTypeActivity.this,
- "Duration onCancel Callback called.",
- Toast.LENGTH_LONG).show();
- }
-
- @Override
- public void onFinish() {
- Log.i(TAG, "Duration onFinish Callback called.");
- Toast.makeText(
- CameraAnimationTypeActivity.this,
- "Duration onFinish Callback called.",
- Toast.LENGTH_LONG).show();
- }
- };
-
- mapboxMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), 7500, callback);
- }
- });
+ mapboxMap.easeCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), 7500, callback);
}
+ });
}
- private LatLng getNextLatLng() {
- cameraState = !cameraState;
- return cameraState ? LAT_LNG_TOWER_BRIDGE : LAT_LNG_LONDON_EYE;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
+ // handle animate button clicks
+ View animateButton = findViewById(R.id.cameraAnimateButton);
+ if (animateButton != null) {
+ animateButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ CameraPosition cameraPosition = new CameraPosition.Builder()
+ .target(getNextLatLng())
+ .bearing(270)
+ .tilt(20)
+ .build();
+
+ MapboxMap.CancelableCallback callback = new MapboxMap.CancelableCallback() {
+ @Override
+ public void onCancel() {
+ Timber.i("Duration onCancel Callback called.");
+ Toast.makeText(
+ CameraAnimationTypeActivity.this,
+ "Duration onCancel Callback called.",
+ Toast.LENGTH_LONG).show();
+ }
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
- }
+ @Override
+ public void onFinish() {
+ Timber.i("Duration onFinish Callback called.");
+ Toast.makeText(
+ CameraAnimationTypeActivity.this,
+ "Duration onFinish Callback called.",
+ Toast.LENGTH_LONG).show();
+ }
+ };
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
+ mapboxMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), 7500, callback);
}
+ });
+ }
+ }
+
+ private LatLng getNextLatLng() {
+ cameraState = !cameraState;
+ return cameraState ? LAT_LNG_TOWER_BRIDGE : LAT_LNG_LONDON_EYE;
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/CameraPositionActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/CameraPositionActivity.java
index 925244b4a4..193b59a9db 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/CameraPositionActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/CameraPositionActivity.java
@@ -11,7 +11,9 @@ import android.support.v7.app.ActionBar;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
-import android.util.Log;
+
+import timber.log.Timber;
+
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
@@ -20,7 +22,6 @@ import android.widget.TextView;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
-import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
@@ -29,157 +30,188 @@ import com.mapbox.mapboxsdk.testapp.R;
public class CameraPositionActivity extends AppCompatActivity implements OnMapReadyCallback {
- private MapView mapView;
- private MapboxMap mapboxMap;
+ private MapView mapView;
+ private MapboxMap mapboxMap;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_camera_position);
-
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
-
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(this);
- }
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_camera_position);
- @Override
- public void onMapReady(@NonNull final MapboxMap mapboxMap) {
- this.mapboxMap = mapboxMap;
- // add a listener to FAB
- FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
- fab.setColorFilter(ContextCompat.getColor(CameraPositionActivity.this, R.color.primary));
- fab.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- Context context = v.getContext();
- final View dialogContent = LayoutInflater.from(context).inflate(R.layout.dialog_camera_position, null);
- AlertDialog.Builder builder = new AlertDialog.Builder(
- context, com.mapbox.mapboxsdk.R.style.AttributionAlertDialogStyle);
- builder.setTitle(R.string.dialog_camera_position);
- builder.setView(onInflateDialogContent(dialogContent));
- builder.setPositiveButton("Animate", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- double latitude = Double.parseDouble(
- ((TextView) dialogContent.findViewById(R.id.value_lat)).getText().toString());
- double longitude = Double.parseDouble(
- ((TextView) dialogContent.findViewById(R.id.value_lon)).getText().toString());
- double zoom = Double.parseDouble(
- ((TextView) dialogContent.findViewById(R.id.value_zoom)).getText().toString());
- double bearing = Double.parseDouble(
- ((TextView) dialogContent.findViewById(R.id.value_bearing)).getText().toString());
- double tilt = Double.parseDouble(
- ((TextView) dialogContent.findViewById(R.id.value_tilt)).getText().toString());
-
- CameraPosition cameraPosition = new CameraPosition.Builder()
- .target(new LatLng(latitude, longitude))
- .zoom(zoom)
- .bearing(bearing)
- .tilt(tilt)
- .build();
-
- mapboxMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), 5000);
- Log.v(MapboxConstants.TAG, cameraPosition.toString());
- }
- });
- builder.setNegativeButton("Cancel", null);
- builder.setCancelable(false);
- builder.show();
- }
- });
- }
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(this);
+ }
+
+ @Override
+ public void onMapReady(@NonNull final MapboxMap mapboxMap) {
+ this.mapboxMap = mapboxMap;
+
+ mapboxMap.setOnCameraChangeListener(new MapboxMap.OnCameraChangeListener() {
+ @Override
+ public void onCameraChange(CameraPosition position) {
+ Timber.w("OnCameraChange: " + position);
+ }
+ });
+
+ // add a listener to FAB
+ FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
+ fab.setColorFilter(ContextCompat.getColor(CameraPositionActivity.this, R.color.primary));
+ fab.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Context context = view.getContext();
+ final View dialogContent = LayoutInflater.from(context).inflate(R.layout.dialog_camera_position, null);
+ AlertDialog.Builder builder = new AlertDialog.Builder(
+ context, com.mapbox.mapboxsdk.R.style.mapbox_AlertDialogStyle);
+ builder.setTitle(R.string.dialog_camera_position);
+ builder.setView(onInflateDialogContent(dialogContent));
+ builder.setPositiveButton("Animate", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ double latitude = Double.parseDouble(
+ ((TextView) dialogContent.findViewById(R.id.value_lat)).getText().toString());
+ double longitude = Double.parseDouble(
+ ((TextView) dialogContent.findViewById(R.id.value_lon)).getText().toString());
+ double zoom = Double.parseDouble(
+ ((TextView) dialogContent.findViewById(R.id.value_zoom)).getText().toString());
+ double bearing = Double.parseDouble(
+ ((TextView) dialogContent.findViewById(R.id.value_bearing)).getText().toString());
+ double tilt = Double.parseDouble(
+ ((TextView) dialogContent.findViewById(R.id.value_tilt)).getText().toString());
+
+ CameraPosition cameraPosition = new CameraPosition.Builder()
+ .target(new LatLng(latitude, longitude))
+ .zoom(zoom)
+ .bearing(bearing)
+ .tilt(tilt)
+ .build();
+
+ mapboxMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), 5000,
+ new MapboxMap.CancelableCallback() {
+ @Override
+ public void onCancel() {
+ Timber.v("OnCancel called");
+ }
+
+ @Override
+ public void onFinish() {
+ Timber.v("OnFinish called");
+ }
+ });
+ Timber.v(cameraPosition.toString());
+ }
+ });
+ builder.setNegativeButton("Cancel", null);
+ builder.setCancelable(false);
+ builder.show();
+ }
+ });
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
+ }
+
+ private View onInflateDialogContent(View view) {
+ linkTextView(view, R.id.value_lat, R.id.seekbar_lat, new LatLngChangeListener(), 180 + 38);
+ linkTextView(view, R.id.value_lon, R.id.seekbar_lon, new LatLngChangeListener(), 180 - 77);
+ linkTextView(view, R.id.value_zoom, R.id.seekbar_zoom, new ValueChangeListener(), 6);
+ linkTextView(view, R.id.value_bearing, R.id.seekbar_bearing, new ValueChangeListener(), 90);
+ linkTextView(view, R.id.value_tilt, R.id.seekbar_tilt, new ValueChangeListener(), 40);
+ return view;
+ }
+
+ private void linkTextView(
+ View view, @IdRes int textViewRes, @IdRes int seekBarRes, ValueChangeListener listener, int defaultValue) {
+ final TextView value = (TextView) view.findViewById(textViewRes);
+ SeekBar seekBar = (SeekBar) view.findViewById(seekBarRes);
+ listener.setLinkedValueView(value);
+ seekBar.setOnSeekBarChangeListener(listener);
+ seekBar.setProgress(defaultValue);
+ }
+
+ private class ValueChangeListener implements SeekBar.OnSeekBarChangeListener {
+
+ protected TextView textView;
+
+ public void setLinkedValueView(TextView textView) {
+ this.textView = textView;
}
@Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- }
+ public void onStartTrackingTouch(SeekBar seekBar) {
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
}
- private View onInflateDialogContent(View view) {
- linkTextView(view, R.id.value_lat, R.id.seekbar_lat, new LatLngChangeListener(), 180 + 38);
- linkTextView(view, R.id.value_lon, R.id.seekbar_lon, new LatLngChangeListener(), 180 - 77);
- linkTextView(view, R.id.value_zoom, R.id.seekbar_zoom, new ValueChangeListener(), 6);
- linkTextView(view, R.id.value_bearing, R.id.seekbar_bearing, new ValueChangeListener(), 90);
- linkTextView(view, R.id.value_tilt, R.id.seekbar_tilt, new ValueChangeListener(), 40);
- return view;
- }
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
- private void linkTextView(
- View view, @IdRes int textViewRes, @IdRes int seekBarRes, ValueChangeListener listener, int defaultValue) {
- final TextView value = (TextView) view.findViewById(textViewRes);
- SeekBar seekBar = (SeekBar) view.findViewById(seekBarRes);
- listener.setLinkedValueView(value);
- seekBar.setOnSeekBarChangeListener(listener);
- seekBar.setProgress(defaultValue);
}
- private class ValueChangeListener implements SeekBar.OnSeekBarChangeListener {
-
- protected TextView textView;
-
- public void setLinkedValueView(TextView textView) {
- this.textView = textView;
- }
-
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
-
- }
-
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
-
- }
-
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- textView.setText(String.valueOf(progress));
- }
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ textView.setText(String.valueOf(progress));
}
+ }
- private class LatLngChangeListener extends ValueChangeListener {
+ private class LatLngChangeListener extends ValueChangeListener {
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- super.onProgressChanged(seekBar, progress - 180, fromUser);
- }
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ super.onProgressChanged(seekBar, progress - 180, fromUser);
}
-}
+ }
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/LatLngBoundsActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/LatLngBoundsActivity.java
index 311991d0d1..3dd6a6344d 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/LatLngBoundsActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/LatLngBoundsActivity.java
@@ -4,12 +4,13 @@ import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
-import android.util.Log;
+
+import timber.log.Timber;
+
import android.view.MenuItem;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
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;
@@ -24,108 +25,120 @@ import java.util.List;
public class LatLngBoundsActivity extends AppCompatActivity implements OnMapReadyCallback {
- private static final LatLng LOS_ANGELES = new LatLng(34.053940, -118.242622);
- private static final LatLng NEW_YORK = new LatLng(40.712730, -74.005953);
-
- private MapView mapView;
- private MapboxMap mapboxMap;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_visible_bounds);
+ private static final LatLng LOS_ANGELES = new LatLng(34.053940, -118.242622);
+ private static final LatLng NEW_YORK = new LatLng(40.712730, -74.005953);
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
+ private MapView mapView;
+ private MapboxMap mapboxMap;
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.setStyleUrl(Style.DARK);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(this);
- }
-
- @Override
- public void onMapReady(MapboxMap map) {
- mapboxMap = map;
- UiSettings uiSettings = mapboxMap.getUiSettings();
- uiSettings.setAllGesturesEnabled(false);
-
- mapboxMap.addMarker(new MarkerOptions()
- .title("Los Angeles")
- .snippet("City Hall")
- .position(LOS_ANGELES));
-
- mapboxMap.addMarker(new MarkerOptions()
- .title("New York")
- .snippet("City Hall")
- .position(NEW_YORK));
-
- List<LatLng> points = new ArrayList<>();
- points.add(NEW_YORK);
- points.add(LOS_ANGELES);
-
- // Create Bounds
- final LatLngBounds bounds = new LatLngBounds.Builder()
- .includes(points)
- .build();
-
- // Add map padding
- int mapPadding = (int) getResources().getDimension(R.dimen.fab_margin);
- mapboxMap.setPadding(mapPadding, mapPadding, mapPadding, mapPadding);
-
- // Move camera to the bounds with added padding
- int padding = (int) getResources().getDimension(R.dimen.coordinatebounds_margin);
- mapboxMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, padding));
-
- // Log data
- Log.e(MapboxConstants.TAG, "Move to bounds: " + bounds.toString());
- Log.e(MapboxConstants.TAG, "Resulting bounds:" + mapboxMap.getProjection().getVisibleRegion().latLngBounds.toString());
- }
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_visible_bounds);
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.setStyleUrl(Style.DARK);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(this);
+ }
+
+ @Override
+ public void onMapReady(MapboxMap map) {
+ mapboxMap = map;
+ UiSettings uiSettings = mapboxMap.getUiSettings();
+ uiSettings.setAllGesturesEnabled(false);
+
+ mapboxMap.addMarker(new MarkerOptions()
+ .title("Los Angeles")
+ .snippet("City Hall")
+ .position(LOS_ANGELES));
+
+ mapboxMap.addMarker(new MarkerOptions()
+ .title("New York")
+ .snippet("City Hall")
+ .position(NEW_YORK));
+
+ List<LatLng> points = new ArrayList<>();
+ points.add(NEW_YORK);
+ points.add(LOS_ANGELES);
+
+ // Create Bounds
+ final LatLngBounds bounds = new LatLngBounds.Builder()
+ .includes(points)
+ .build();
+
+ // Add map padding
+ int mapPadding = (int) getResources().getDimension(R.dimen.fab_margin);
+ mapboxMap.setPadding(mapPadding, mapPadding, mapPadding, mapPadding);
+
+ // Move camera to the bounds with added padding
+ int padding = (int) getResources().getDimension(R.dimen.coordinatebounds_margin);
+ mapboxMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, padding));
+
+ // Log data
+ Timber.e("Move to bounds: " + bounds.toString());
+ Timber.e("Resulting bounds:" + mapboxMap.getProjection().getVisibleRegion().latLngBounds.toString());
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/ManualZoomActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/ManualZoomActivity.java
index 740efd5536..4bc30157f8 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/ManualZoomActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/ManualZoomActivity.java
@@ -20,104 +20,116 @@ import com.mapbox.mapboxsdk.testapp.R;
public class ManualZoomActivity extends AppCompatActivity {
- private MapboxMap mapboxMap;
- private MapView mapView;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_manual_zoom);
-
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
-
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.setStyleUrl(Style.SATELLITE);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(@NonNull final MapboxMap mapboxMap) {
- ManualZoomActivity.this.mapboxMap = mapboxMap;
-
- UiSettings uiSettings = ManualZoomActivity.this.mapboxMap.getUiSettings();
- uiSettings.setAllGesturesEnabled(false);
- }
- });
- }
+ private MapboxMap mapboxMap;
+ private MapView mapView;
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.menu_zoom, menu);
- return true;
- }
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_manual_zoom);
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
-
- case android.R.id.home:
- onBackPressed();
- return true;
-
- case R.id.action_zoom_in:
- mapboxMap.animateCamera(CameraUpdateFactory.zoomIn());
- return true;
-
- case R.id.action_zoom_out:
- mapboxMap.animateCamera(CameraUpdateFactory.zoomOut());
- return true;
-
- case R.id.action_zoom_by:
- mapboxMap.animateCamera(CameraUpdateFactory.zoomBy(2));
- return true;
- case R.id.action_zoom_to:
- mapboxMap.animateCamera(CameraUpdateFactory.zoomTo(2));
- return true;
-
- case R.id.action_zoom_to_point:
- View view = getWindow().getDecorView();
- mapboxMap.animateCamera(
- CameraUpdateFactory.zoomBy(1, new Point(view.getMeasuredWidth() / 4, view.getMeasuredHeight() / 4)));
- return true;
-
- default:
- return super.onOptionsItemSelected(item);
- }
- }
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
- }
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.setStyleUrl(Style.SATELLITE);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(@NonNull final MapboxMap mapboxMap) {
+ ManualZoomActivity.this.mapboxMap = mapboxMap;
+
+ UiSettings uiSettings = ManualZoomActivity.this.mapboxMap.getUiSettings();
+ uiSettings.setAllGesturesEnabled(false);
+ }
+ });
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.menu_zoom, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+
+ case android.R.id.home:
+ onBackPressed();
+ return true;
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- }
+ case R.id.action_zoom_in:
+ mapboxMap.animateCamera(CameraUpdateFactory.zoomIn());
+ return true;
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
+ case R.id.action_zoom_out:
+ mapboxMap.animateCamera(CameraUpdateFactory.zoomOut());
+ return true;
+
+ case R.id.action_zoom_by:
+ mapboxMap.animateCamera(CameraUpdateFactory.zoomBy(2));
+ return true;
+ case R.id.action_zoom_to:
+ mapboxMap.animateCamera(CameraUpdateFactory.zoomTo(2));
+ return true;
+
+ case R.id.action_zoom_to_point:
+ View view = getWindow().getDecorView();
+ mapboxMap.animateCamera(
+ CameraUpdateFactory.zoomBy(1, new Point(view.getMeasuredWidth() / 4, view.getMeasuredHeight() / 4)));
+ return true;
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/MaxMinZoomActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/MaxMinZoomActivity.java
index 9fcdfa3880..71e8cc0a08 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/MaxMinZoomActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/MaxMinZoomActivity.java
@@ -13,74 +13,86 @@ import com.mapbox.mapboxsdk.testapp.R;
public class MaxMinZoomActivity extends AppCompatActivity implements OnMapReadyCallback {
- private MapView mapView;
- private MapboxMap mapboxMap;
+ private MapView mapView;
+ private MapboxMap mapboxMap;
- @Override
+ @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_maxmin_zoom);
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_maxmin_zoom);
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(this);
- }
-
- @Override
- public void onMapReady(MapboxMap map) {
- mapboxMap = map;
- mapboxMap.setMinZoom(3);
- mapboxMap.setMaxZoom(5);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- }
- return false;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(this);
+ }
+
+ @Override
+ public void onMapReady(MapboxMap map) {
+ mapboxMap = map;
+ mapboxMap.setMinZoomPreference(3);
+ mapboxMap.setMaxZoomPreference(5);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
}
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
-
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
- }
-
-}
+ return false;
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/ScrollByActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/ScrollByActivity.java
index e3dc849ce0..2f16e862ee 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/ScrollByActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/ScrollByActivity.java
@@ -22,127 +22,139 @@ import com.mapbox.mapboxsdk.testapp.R;
public class ScrollByActivity extends AppCompatActivity implements OnMapReadyCallback {
- public static final int MULTIPLIER_PER_PIXEL = 50;
+ public static final int MULTIPLIER_PER_PIXEL = 50;
- private MapView mapView;
- private MapboxMap mapboxMap;
- private SeekBar xBar;
- private SeekBar yBar;
+ private MapView mapView;
+ private MapboxMap mapboxMap;
+ private SeekBar seekBarX;
+ private SeekBar seekBarY;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_scroll_by);
-
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
-
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- xBar = (SeekBar) findViewById(R.id.seekbar_move_x);
- TextView xText = (TextView) findViewById(R.id.textview_x);
- xBar.setOnSeekBarChangeListener(new PixelBarChangeListener(xText, R.string.scrollby_x_value));
-
- yBar = (SeekBar) findViewById(R.id.seekbar_move_y);
- TextView yText = (TextView) findViewById(R.id.textview_y);
- yBar.setOnSeekBarChangeListener(new PixelBarChangeListener(yText, R.string.scrollby_y_value));
-
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.setTag(true);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(this);
- }
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_scroll_by);
- @Override
- public void onMapReady(MapboxMap map) {
- mapboxMap = map;
- UiSettings uiSettings = mapboxMap.getUiSettings();
- uiSettings.setLogoEnabled(false);
- uiSettings.setAttributionEnabled(false);
-
- FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
- fab.setColorFilter(ContextCompat.getColor(ScrollByActivity.this, R.color.primary));
- fab.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- mapboxMap.easeCamera(CameraUpdateFactory.scrollBy(
- xBar.getProgress() * MULTIPLIER_PER_PIXEL,
- yBar.getProgress() * MULTIPLIER_PER_PIXEL)
- );
- }
- });
- }
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
+ seekBarX = (SeekBar) findViewById(R.id.seekbar_move_x);
+ TextView textViewX = (TextView) findViewById(R.id.textview_x);
+ seekBarX.setOnSeekBarChangeListener(new PixelBarChangeListener(textViewX, R.string.scrollby_x_value));
+
+ seekBarY = (SeekBar) findViewById(R.id.seekbar_move_y);
+ TextView textViewY = (TextView) findViewById(R.id.textview_y);
+ seekBarY.setOnSeekBarChangeListener(new PixelBarChangeListener(textViewY, R.string.scrollby_y_value));
+
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.setTag(true);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(this);
+ }
+
+ @Override
+ public void onMapReady(MapboxMap map) {
+ mapboxMap = map;
+ UiSettings uiSettings = mapboxMap.getUiSettings();
+ uiSettings.setLogoEnabled(false);
+ uiSettings.setAttributionEnabled(false);
+
+ FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
+ fab.setColorFilter(ContextCompat.getColor(ScrollByActivity.this, R.color.primary));
+ fab.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ mapboxMap.easeCamera(CameraUpdateFactory.scrollBy(
+ seekBarX.getProgress() * MULTIPLIER_PER_PIXEL,
+ seekBarY.getProgress() * MULTIPLIER_PER_PIXEL)
+ );
+ }
+ });
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- }
+ private static class PixelBarChangeListener implements SeekBar.OnSeekBarChangeListener {
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
+ @StringRes
+ private int prefixTextResource;
+ private TextView valueView;
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
+ public PixelBarChangeListener(@NonNull TextView textView, @StringRes int textRes) {
+ valueView = textView;
+ prefixTextResource = textRes;
}
@Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ int value = progress * ScrollByActivity.MULTIPLIER_PER_PIXEL;
+ valueView.setText(String.format(seekBar.getResources().getString(prefixTextResource), value));
}
- private static class PixelBarChangeListener implements SeekBar.OnSeekBarChangeListener {
-
- @StringRes
- private int prefixTextResource;
- private TextView valueView;
-
- public PixelBarChangeListener(@NonNull TextView textView, @StringRes int textRes) {
- valueView = textView;
- prefixTextResource = textRes;
- }
-
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- int value = progress * ScrollByActivity.MULTIPLIER_PER_PIXEL;
- valueView.setText(String.format(seekBar.getResources().getString(prefixTextResource), value));
- }
-
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
- }
+ }
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
- }
}
+ }
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/customlayer/CustomLayerActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/customlayer/CustomLayerActivity.java
index a1aced6eaa..8e4b58366f 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/customlayer/CustomLayerActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/customlayer/CustomLayerActivity.java
@@ -6,7 +6,9 @@ import android.support.v4.content.ContextCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
-import android.util.Log;
+
+import timber.log.Timber;
+
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
@@ -22,131 +24,148 @@ import com.mapbox.mapboxsdk.testapp.R;
import com.mapbox.mapboxsdk.testapp.model.customlayer.ExampleCustomLayer;
public class CustomLayerActivity extends AppCompatActivity {
- private static final String TAG = CustomLayerActivity.class.getSimpleName();
-
- private MapboxMap mapboxMap;
- private MapView mapView;
-
- private boolean isShowingCustomLayer = false;
- private FloatingActionButton fab;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_custom_layer);
-
- setupActionBar();
-
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(MapboxMap map) {
- mapboxMap = map;
-
- mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(39.91448, -243.60947), 10));
-
- }
- });
-
- fab = (FloatingActionButton) findViewById(R.id.fab);
- fab.setColorFilter(ContextCompat.getColor(this, R.color.primary));
- fab.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- if (mapboxMap != null) {
- swapCustomLayer();
- }
- }
- });
- }
-
- private void swapCustomLayer() {
-
- if (isShowingCustomLayer) {
- try {
- mapboxMap.removeLayer("custom");
- } catch (NoSuchLayerException noSuchLayerException) {
- Log.e(TAG, "No custom layer to remove");
- }
- fab.setImageResource(R.drawable.ic_layers_24dp);
- } else {
- mapboxMap.addLayer(new CustomLayer("custom",
- ExampleCustomLayer.createContext(),
- ExampleCustomLayer.InitializeFunction,
- ExampleCustomLayer.RenderFunction,
- ExampleCustomLayer.DeinitializeFunction), "building");
- fab.setImageResource(R.drawable.ic_layers_clear_24dp);
- }
-
- isShowingCustomLayer = !isShowingCustomLayer;
- }
- private void updateLayer() {
- CustomLayer custom = mapboxMap.getLayerAs("custom");
- if (custom != null) {
- custom.update();
+ private MapboxMap mapboxMap;
+ private MapView mapView;
+ private CustomLayer customLayer;
+
+ private FloatingActionButton fab;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_custom_layer);
+
+ setupActionBar();
+
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(MapboxMap map) {
+ mapboxMap = map;
+ mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(39.91448, -243.60947), 10));
+
+ }
+ });
+
+ fab = (FloatingActionButton) findViewById(R.id.fab);
+ fab.setColorFilter(ContextCompat.getColor(this, R.color.primary));
+ fab.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ if (mapboxMap != null) {
+ swapCustomLayer();
}
+ }
+ });
+ }
+
+ private void swapCustomLayer() {
+ if (customLayer != null) {
+ try {
+ mapboxMap.removeLayer(customLayer.getId());
+ customLayer = null;
+ } catch (NoSuchLayerException noSuchLayerException) {
+ Timber.e("No custom layer to remove");
+ }
+ fab.setImageResource(R.drawable.ic_layers_24dp);
+ } else {
+ customLayer = new CustomLayer("custom",
+ ExampleCustomLayer.createContext(),
+ ExampleCustomLayer.InitializeFunction,
+ ExampleCustomLayer.RenderFunction,
+ ExampleCustomLayer.DeinitializeFunction);
+ mapboxMap.addLayer(customLayer, "building");
+ fab.setImageResource(R.drawable.ic_layers_clear_24dp);
}
+ }
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
-
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
+ private void updateLayer() {
+ if (customLayer != null) {
+ customLayer.update();
}
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.menu_custom_layer, menu);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.menu_custom_layer, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
return true;
+ case R.id.action_update_layer:
+ updateLayer();
+ return true;
+ case R.id.action_set_color_red:
+ ExampleCustomLayer.setColor(1, 0, 0, 1);
+ return true;
+ case R.id.action_set_color_green:
+ ExampleCustomLayer.setColor(0, 1, 0, 1);
+ return true;
+ case R.id.action_set_color_blue:
+ ExampleCustomLayer.setColor(0, 0, 1, 1);
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- case R.id.action_update_layer:
- updateLayer();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
- }
-
- private void setupActionBar() {
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
+ private void setupActionBar() {
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- final ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
+ final ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/directions/DirectionsActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/directions/DirectionsActivity.java
index 6d5d63dbf7..fc8f5059be 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/directions/DirectionsActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/directions/DirectionsActivity.java
@@ -6,8 +6,11 @@ import android.support.annotation.NonNull;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
-import android.util.Log;
+
+import timber.log.Timber;
+
import android.view.MenuItem;
+
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
import com.mapbox.mapboxsdk.annotations.PolylineOptions;
import com.mapbox.mapboxsdk.camera.CameraPosition;
@@ -21,169 +24,190 @@ import com.mapbox.services.Constants;
import com.mapbox.services.commons.ServicesException;
import com.mapbox.services.commons.geojson.LineString;
import com.mapbox.services.commons.models.Position;
-import com.mapbox.services.directions.v4.DirectionsCriteria;
-import com.mapbox.services.directions.v4.MapboxDirections;
-import com.mapbox.services.directions.v4.models.DirectionsResponse;
-import com.mapbox.services.directions.v4.models.DirectionsRoute;
-import com.mapbox.services.directions.v4.models.Waypoint;
+import com.mapbox.services.directions.v5.DirectionsCriteria;
+import com.mapbox.services.directions.v5.MapboxDirections;
+import com.mapbox.services.directions.v5.models.DirectionsResponse;
+import com.mapbox.services.directions.v5.models.DirectionsRoute;
+
+import java.util.ArrayList;
+import java.util.List;
+
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class DirectionsActivity extends AppCompatActivity {
- private static final String LOG_TAG = "DirectionsActivity";
-
- private MapView mapView;
- private MapboxMap mapboxMap;
+ private MapView mapView;
+ private MapboxMap mapboxMap;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_directions);
-
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
-
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(@NonNull MapboxMap mapboxMap) {
- DirectionsActivity.this.mapboxMap = mapboxMap;
- loadRoute();
- }
- });
- }
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_directions);
- private void loadRoute() {
- // Dupont Circle (Washington, DC)
- Waypoint origin = new Waypoint(-77.04341, 38.90962);
-
- // The White House (Washington, DC)
- Waypoint destination = new Waypoint(-77.0365, 38.8977);
-
- // Set map at centroid
- LatLng centroid = new LatLng(
- (origin.getLatitude() + destination.getLatitude()) / 2,
- (origin.getLongitude() + destination.getLongitude()) / 2);
-
- mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder()
- .target(centroid)
- .zoom(14)
- .build()));
-
- // Add origin and destination to the map
- mapboxMap.addMarker(new MarkerOptions()
- .position(new LatLng(origin.getLatitude(), origin.getLongitude()))
- .title("Origin")
- .snippet("Dupont Circle"));
- mapboxMap.addMarker(new MarkerOptions()
- .position(new LatLng(destination.getLatitude(), destination.getLongitude()))
- .title("Destination")
- .snippet("The White House"));
-
- // Get route from API
- getRoute(origin, destination);
- }
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- private void getRoute(Waypoint origin, Waypoint destination) {
- try {
- MapboxDirections md = new MapboxDirections.Builder()
- .setAccessToken(getString(R.string.mapbox_access_token))
- .setOrigin(origin)
- .setDestination(destination)
- .setProfile(DirectionsCriteria.PROFILE_WALKING)
- .build();
-
- md.enqueueCall(new Callback<DirectionsResponse>() {
-
- @Override
- public void onFailure(Call<DirectionsResponse> call, Throwable throwable) {
- Log.e(LOG_TAG, "Error: " + throwable.getMessage());
- }
-
- @Override
- public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
- // You can get generic HTTP info about the response
- Log.d(LOG_TAG, "Response code: " + response.code());
-
- // Print some info about the route
- DirectionsRoute currentRoute = response.body().getRoutes().get(0);
- Log.d(LOG_TAG, "Distance: " + currentRoute.getDistance());
-
- // Draw the route on the map
- drawRoute(currentRoute);
- }
-
- });
- } catch (ServicesException servicesException) {
- Log.e(LOG_TAG, "Error displaying route: " + servicesException.toString());
- servicesException.printStackTrace();
- }
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
- private void drawRoute(DirectionsRoute route) {
-
- PolylineOptions builder = new PolylineOptions();
- builder.color(Color.parseColor("#3887be"));
- builder.alpha(0.5f);
- builder.width(5);
- builder.width(5);
- LineString lineString = route.asLineString(Constants.OSRM_PRECISION_V4);
- for (Position coordinates : lineString.getCoordinates()) {
- builder.add(new LatLng(coordinates.getLatitude(), coordinates.getLongitude()));
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(@NonNull MapboxMap mapboxMap) {
+ DirectionsActivity.this.mapboxMap = mapboxMap;
+ loadRoute();
+ }
+ });
+ }
+
+ private void loadRoute() {
+ // Dupont Circle (Washington, DC)
+ Position origin = Position.fromCoordinates(-77.04341, 38.90962);
+
+ // The White House (Washington, DC)
+ Position destination = Position.fromCoordinates(-77.0365, 38.8977);
+
+ // Set map at centroid
+ LatLng centroid = new LatLng(
+ (origin.getLatitude() + destination.getLatitude()) / 2,
+ (origin.getLongitude() + destination.getLongitude()) / 2);
+
+ mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder()
+ .target(centroid)
+ .zoom(14)
+ .build()));
+
+ // Add origin and destination to the map
+ mapboxMap.addMarker(new MarkerOptions()
+ .position(new LatLng(origin.getLatitude(), origin.getLongitude()))
+ .title("Origin")
+ .snippet("Dupont Circle"));
+ mapboxMap.addMarker(new MarkerOptions()
+ .position(new LatLng(destination.getLatitude(), destination.getLongitude()))
+ .title("Destination")
+ .snippet("The White House"));
+
+ // Get route from API
+ getRoute(origin, destination);
+ }
+
+ private void getRoute(Position origin, Position destination) {
+ try {
+ MapboxDirections md = new MapboxDirections.Builder()
+ .setAccessToken(getString(R.string.mapbox_access_token))
+ .setOrigin(origin)
+ .setOverview(DirectionsCriteria.OVERVIEW_FULL)
+ .setDestination(destination)
+ .setProfile(DirectionsCriteria.PROFILE_WALKING)
+ .build();
+
+ md.enqueueCall(new Callback<DirectionsResponse>() {
+
+ @Override
+ public void onFailure(Call<DirectionsResponse> call, Throwable throwable) {
+ Timber.e("Error: " + throwable.getMessage());
}
- // Draw Points on MapView
- mapboxMap.addPolyline(builder);
- }
+ @Override
+ public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
+ // You can get generic HTTP info about the response
+ Timber.d("Response code: " + response.code());
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
+ // Print some info about the route
+ DirectionsRoute currentRoute = response.body().getRoutes().get(0);
+ Timber.d("Distance: " + currentRoute.getDistance());
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
- }
+ // Draw the route on the map
+ drawRoute(currentRoute);
+ }
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
+ });
+ } catch (ServicesException servicesException) {
+ Timber.e("Error displaying route: " + servicesException.toString());
+ servicesException.printStackTrace();
}
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
+ }
+
+ private void drawRoute(DirectionsRoute route) {
+
+ PolylineOptions builder = new PolylineOptions();
+ builder.color(Color.parseColor("#3887be"));
+ builder.alpha(0.5f);
+ builder.width(5);
+ builder.width(5);
+
+ LineString lineString = LineString.fromPolyline(route.getGeometry(), Constants.OSRM_PRECISION_V5);
+ List<Position> coordinates = lineString.getCoordinates();
+ List<LatLng> points = new ArrayList<>();
+ for (int i = 0; i < coordinates.size(); i++) {
+ points.add(new LatLng(
+ coordinates.get(i).getLatitude(),
+ coordinates.get(i).getLongitude()));
}
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
+ builder.addAll(points);
+
+ // Draw Points on MapView
+ mapboxMap.addPolyline(builder);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/espresso/EspressoTestActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/espresso/EspressoTestActivity.java
new file mode 100644
index 0000000000..677e09e719
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/espresso/EspressoTestActivity.java
@@ -0,0 +1,80 @@
+package com.mapbox.mapboxsdk.testapp.activity.espresso;
+
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+
+import com.mapbox.mapboxsdk.maps.MapView;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
+import com.mapbox.mapboxsdk.testapp.R;
+
+/**
+ * Base activity for instrumentation testing
+ */
+public class EspressoTestActivity extends AppCompatActivity implements OnMapReadyCallback {
+
+ public MapView mapView;
+ protected MapboxMap mapboxMap;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_camera_test);
+
+ //Initialize map as normal
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(this);
+ }
+
+ @Override
+ public void onMapReady(MapboxMap map) {
+ mapboxMap = map;
+ }
+
+ public MapboxMap getMapboxMap() {
+ return mapboxMap;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxCountActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxCountActivity.java
index f9a067daf0..00cc8dfac7 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxCountActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxCountActivity.java
@@ -5,15 +5,11 @@ import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
-import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import com.google.gson.JsonElement;
-import com.mapbox.mapboxsdk.annotations.Marker;
-import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
-import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
@@ -23,137 +19,143 @@ import com.mapbox.services.commons.geojson.Feature;
import java.util.List;
import java.util.Map;
+import timber.log.Timber;
+
/**
* Demo's query rendered features
*/
public class QueryRenderedFeaturesBoxCountActivity extends AppCompatActivity {
- private static final String TAG = QueryRenderedFeaturesBoxCountActivity.class.getSimpleName();
-
- public MapView mapView;
- private MapboxMap mapboxMap;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_query_features_box);
- setupActionBar();
-
- final float density = getResources().getDisplayMetrics().density;
-
- final View selectionBox = findViewById(R.id.selection_box);
-
- //Initialize map as normal
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(new OnMapReadyCallback() {
- @SuppressWarnings("ConstantConditions")
- @Override
- public void onMapReady(final MapboxMap mapboxMap) {
- QueryRenderedFeaturesBoxCountActivity.this.mapboxMap = mapboxMap;
-
-
- selectionBox.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- //Query
- int top = selectionBox.getTop() - mapView.getTop();
- int left = selectionBox.getLeft() - mapView.getLeft();
- RectF box = new RectF(left, top, left + selectionBox.getWidth(), top + selectionBox.getHeight());
- Log.i(TAG, String.format("Querying box %s", box));
- List<Feature> features = mapboxMap.queryRenderedFeatures(box);
-
- //Show count
- Toast.makeText(
- QueryRenderedFeaturesBoxCountActivity.this,
- String.format("%s features in box", features.size()),
- Toast.LENGTH_SHORT).show();
-
- //Debug output
- debugOutput(features);
- }
- });
-
- //Little taste of home
- mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(52.0907, 5.1214), 16));
- }
- });
- }
-
- private void debugOutput(List<Feature> features) {
- Log.i(TAG, String.format("Got %s features", features.size()));
- for (Feature feature : features) {
- if (feature != null) {
- Log.i(TAG, String.format("Got feature %s with %s properties and Geometry %s",
- feature.getId(),
- feature.getProperties() != null ? feature.getProperties().entrySet().size() : "<null>",
- feature.getGeometry() != null ? feature.getGeometry().getClass().getSimpleName() : "<null>")
- );
- if (feature.getProperties() != null) {
- for (Map.Entry<String, JsonElement> entry : feature.getProperties().entrySet()) {
- Log.i(TAG, String.format("Prop %s - %s", entry.getKey(), entry.getValue()));
- }
- }
- } else {
- Log.i(TAG, "Got NULL feature %s");
- }
+ public MapView mapView;
+ private MapboxMap mapboxMap;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_query_features_box);
+ setupActionBar();
+
+ final View selectionBox = findViewById(R.id.selection_box);
+
+ //Initialize map as normal
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @SuppressWarnings("ConstantConditions")
+ @Override
+ public void onMapReady(final MapboxMap mapboxMap) {
+ QueryRenderedFeaturesBoxCountActivity.this.mapboxMap = mapboxMap;
+ selectionBox.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ //Query
+ int top = selectionBox.getTop() - mapView.getTop();
+ int left = selectionBox.getLeft() - mapView.getLeft();
+ RectF box = new RectF(left, top, left + selectionBox.getWidth(), top + selectionBox.getHeight());
+ Timber.i(String.format("Querying box %s", box));
+ List<Feature> features = mapboxMap.queryRenderedFeatures(box);
+
+ //Show count
+ Toast.makeText(
+ QueryRenderedFeaturesBoxCountActivity.this,
+ String.format("%s features in box", features.size()),
+ Toast.LENGTH_SHORT).show();
+
+ //Debug output
+ debugOutput(features);
+ }
+ });
+ }
+ });
+ }
+
+ private void debugOutput(List<Feature> features) {
+ Timber.i(String.format("Got %s features", features.size()));
+ for (Feature feature : features) {
+ if (feature != null) {
+ Timber.i(String.format("Got feature %s with %s properties and Geometry %s",
+ feature.getId(),
+ feature.getProperties() != null ? feature.getProperties().entrySet().size() : "<null>",
+ feature.getGeometry() != null ? feature.getGeometry().getClass().getSimpleName() : "<null>")
+ );
+ if (feature.getProperties() != null) {
+ for (Map.Entry<String, JsonElement> entry : feature.getProperties().entrySet()) {
+ Timber.i(String.format("Prop %s - %s", entry.getKey(), entry.getValue()));
+ }
}
+ } else {
+ // TODO Question: Why not formatting here??
+ Timber.i("Got NULL feature %s");
+ }
}
-
- public MapboxMap getMapboxMap() {
- return mapboxMap;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
-
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
+ }
+
+ public MapboxMap getMapboxMap() {
+ return mapboxMap;
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
- }
+ private void setupActionBar() {
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- private void setupActionBar() {
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
-
- final ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
+ final ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxHighlightActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxHighlightActivity.java
index 1e8f91857b..8c4a499f9b 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxHighlightActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxHighlightActivity.java
@@ -6,14 +6,10 @@ import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
-import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
-import com.mapbox.mapboxsdk.annotations.Marker;
-import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
-import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
@@ -25,128 +21,138 @@ import com.mapbox.services.commons.geojson.FeatureCollection;
import java.util.List;
+import timber.log.Timber;
+
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.fillColor;
/**
* Demo's query rendered features
*/
public class QueryRenderedFeaturesBoxHighlightActivity extends AppCompatActivity {
- private static final String TAG = QueryRenderedFeaturesBoxHighlightActivity.class.getSimpleName();
-
- public MapView mapView;
- private MapboxMap mapboxMap;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_query_features_box);
- setupActionBar();
-
- final View selectionBox = findViewById(R.id.selection_box);
-
- //Initialize map as normal
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(new OnMapReadyCallback() {
- @SuppressWarnings("ConstantConditions")
- @Override
- public void onMapReady(final MapboxMap mapboxMap) {
- QueryRenderedFeaturesBoxHighlightActivity.this.mapboxMap = mapboxMap;
-
- //Add a fill layer to display stuff on
-
- selectionBox.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- //Query
- int top = selectionBox.getTop() - mapView.getTop();
- int left = selectionBox.getLeft() - mapView.getLeft();
- RectF box = new RectF(left, top, left + selectionBox.getWidth(), top + selectionBox.getHeight());
- Log.i(TAG, String.format("Querying box %s for buildings", box));
- List<Feature> features = mapboxMap.queryRenderedFeatures(box, "building");
-
- //Show count
- Toast.makeText(
- QueryRenderedFeaturesBoxHighlightActivity.this,
- String.format("%s features in box", features.size()),
- Toast.LENGTH_SHORT).show();
-
- //remove layer / source if already added
- try {
- mapboxMap.removeSource("highlighted-shapes-source");
- mapboxMap.removeLayer("highlighted-shapes-layer");
- } catch (Exception exception) {
- //that's ok
- }
-
- //Add layer / source
- mapboxMap.addSource(new GeoJsonSource("highlighted-shapes-source", FeatureCollection.fromFeatures(features)));
- mapboxMap.addLayer(new FillLayer("highlighted-shapes-layer", "highlighted-shapes-source")
- .withProperties(fillColor(Color.RED)));
- }
- });
-
- //Little taste of home
- mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(52.0907, 5.1214), 16));
- }
- });
-
- }
-
- public MapboxMap getMapboxMap() {
- return mapboxMap;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
-
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
- }
+ public MapView mapView;
+ private MapboxMap mapboxMap;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_query_features_box);
+ setupActionBar();
+
+ final View selectionBox = findViewById(R.id.selection_box);
+
+ //Initialize map as normal
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @SuppressWarnings("ConstantConditions")
+ @Override
+ public void onMapReady(final MapboxMap mapboxMap) {
+ QueryRenderedFeaturesBoxHighlightActivity.this.mapboxMap = mapboxMap;
+ selectionBox.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ //Query
+ int top = selectionBox.getTop() - mapView.getTop();
+ int left = selectionBox.getLeft() - mapView.getLeft();
+ RectF box = new RectF(left, top, left + selectionBox.getWidth(), top + selectionBox.getHeight());
+ Timber.i(String.format("Querying box %s for buildings", box));
+ List<Feature> features = mapboxMap.queryRenderedFeatures(box, "building");
+
+ //Show count
+ Toast.makeText(
+ QueryRenderedFeaturesBoxHighlightActivity.this,
+ String.format("%s features in box", features.size()),
+ Toast.LENGTH_SHORT).show();
+
+ //remove layer / source if already added
+ try {
+ mapboxMap.removeSource("highlighted-shapes-source");
+ mapboxMap.removeLayer("highlighted-shapes-layer");
+ } catch (Exception exception) {
+ //that's ok
+ }
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
+ //Add layer / source
+ mapboxMap.addSource(
+ new GeoJsonSource("highlighted-shapes-source",
+ FeatureCollection.fromFeatures(features))
+ );
+ mapboxMap.addLayer(new FillLayer("highlighted-shapes-layer", "highlighted-shapes-source")
+ .withProperties(fillColor(Color.RED)));
+ }
+ });
+ }
+ });
+
+ }
+
+ public MapboxMap getMapboxMap() {
+ return mapboxMap;
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
- private void setupActionBar() {
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
+ private void setupActionBar() {
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- final ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
+ final ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxSymbolCountActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxSymbolCountActivity.java
new file mode 100644
index 0000000000..4b7bbb9614
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxSymbolCountActivity.java
@@ -0,0 +1,186 @@
+package com.mapbox.mapboxsdk.testapp.activity.feature;
+
+import android.graphics.BitmapFactory;
+import android.graphics.RectF;
+import android.os.Bundle;
+import android.support.annotation.RawRes;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.Toolbar;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.Toast;
+
+import com.mapbox.mapboxsdk.maps.MapView;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
+import com.mapbox.mapboxsdk.style.layers.SymbolLayer;
+import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;
+import com.mapbox.mapboxsdk.testapp.R;
+import com.mapbox.services.commons.geojson.Feature;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.List;
+
+import timber.log.Timber;
+
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconImage;
+
+/**
+ * Demo's query rendered features on Symbols
+ */
+public class QueryRenderedFeaturesBoxSymbolCountActivity extends AppCompatActivity {
+
+ public MapView mapView;
+ private MapboxMap mapboxMap;
+
+ private Toast toast;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_query_features_box);
+ setupActionBar();
+
+ final View selectionBox = findViewById(R.id.selection_box);
+
+ //Initialize map as normal
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @SuppressWarnings("ConstantConditions")
+ @Override
+ public void onMapReady(final MapboxMap mapboxMap) {
+ QueryRenderedFeaturesBoxSymbolCountActivity.this.mapboxMap = mapboxMap;
+
+ //Add a symbol layer (also works with annotations)
+ try {
+ mapboxMap.addSource(new GeoJsonSource("symbols-source", readRawResource(R.raw.test_points_utrecht)));
+ } catch (IOException ioException) {
+ Timber.e("Could not load geojson: " + ioException.getMessage());
+ return;
+ }
+ mapboxMap.addImage(
+ "test-icon",
+ BitmapFactory.decodeResource(getResources(),
+ R.drawable.mapbox_marker_icon_default)
+ );
+ mapboxMap.addLayer(new SymbolLayer("symbols-layer", "symbols-source").withProperties(iconImage("test-icon")));
+
+ selectionBox.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ //Query
+ int top = selectionBox.getTop() - mapView.getTop();
+ int left = selectionBox.getLeft() - mapView.getLeft();
+ RectF box = new RectF(left, top, left + selectionBox.getWidth(), top + selectionBox.getHeight());
+ Timber.i(String.format("Querying box %s", box));
+ List<Feature> features = mapboxMap.queryRenderedFeatures(box, "symbols-layer");
+
+ //Show count
+ if (toast != null) {
+ toast.cancel();
+ }
+ toast = Toast.makeText(
+ QueryRenderedFeaturesBoxSymbolCountActivity.this,
+ String.format("%s features in box", features.size()),
+ Toast.LENGTH_SHORT);
+ toast.show();
+ }
+ });
+ }
+ });
+ }
+
+ private String readRawResource(@RawRes int rawResource) throws IOException {
+ InputStream is = getResources().openRawResource(rawResource);
+ Writer writer = new StringWriter();
+ char[] buffer = new char[1024];
+ try {
+ Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+ int numRead;
+ while ((numRead = reader.read(buffer)) != -1) {
+ writer.write(buffer, 0, numRead);
+ }
+ } finally {
+ is.close();
+ }
+
+ return writer.toString();
+ }
+
+ public MapboxMap getMapboxMap() {
+ return mapboxMap;
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+ }
+
+ private void setupActionBar() {
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+
+ final ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
+ }
+ }
+
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesPropertiesActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesPropertiesActivity.java
index 8abf638d16..17dfbc18b4 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesPropertiesActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesPropertiesActivity.java
@@ -9,7 +9,9 @@ import android.support.annotation.NonNull;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
-import android.util.Log;
+
+import timber.log.Timber;
+
import android.view.MenuItem;
import android.view.View;
import android.widget.LinearLayout;
@@ -18,7 +20,6 @@ import android.widget.TextView;
import com.google.gson.JsonElement;
import com.mapbox.mapboxsdk.annotations.BaseMarkerOptions;
import com.mapbox.mapboxsdk.annotations.Marker;
-import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
@@ -33,229 +34,236 @@ import java.util.Map;
* Demo's query rendered features
*/
public class QueryRenderedFeaturesPropertiesActivity extends AppCompatActivity {
- private static final String TAG = QueryRenderedFeaturesPropertiesActivity.class.getSimpleName();
- public MapView mapView;
- private MapboxMap mapboxMap;
- private Marker marker;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_query_features_point);
- setupActionBar();
-
- final float density = getResources().getDisplayMetrics().density;
-
- //Initialize map as normal
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(final MapboxMap mapboxMap) {
- QueryRenderedFeaturesPropertiesActivity.this.mapboxMap = mapboxMap;
-
- //Add custom window adapter
- addCustomInfoWindowAdapter(mapboxMap);
-
- //Add a click listener
- mapboxMap.setOnMapClickListener(new MapboxMap.OnMapClickListener() {
- @Override
- public void onMapClick(@NonNull LatLng point) {
- //Query
- final PointF pixel = mapboxMap.getProjection().toScreenLocation(point);
- Log.i(TAG, String.format(
- "Requesting features for %sx%s (%sx%s adjusted for density)",
- pixel.x, pixel.y, pixel.x / density, pixel.y / density)
- );
- List<Feature> features = mapboxMap.queryRenderedFeatures(pixel);
-
- //Debug output
- debugOutput(features);
-
- //Remove any previous markers
- if (marker != null) {
- mapboxMap.removeMarker(marker);
- }
-
- //Add a marker on the clicked point
- marker = mapboxMap.addMarker(new CustomMarkerOptions().position(point).features(features));
- mapboxMap.selectMarker(marker);
- }
- });
-
- //Little taste of home
- mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(52.0907, 5.1214), 16));
+ public MapView mapView;
+ private MapboxMap mapboxMap;
+ private Marker marker;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_query_features_point);
+ setupActionBar();
+
+ final float density = getResources().getDisplayMetrics().density;
+
+ //Initialize map as normal
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(final MapboxMap mapboxMap) {
+ QueryRenderedFeaturesPropertiesActivity.this.mapboxMap = mapboxMap;
+
+ //Add custom window adapter
+ addCustomInfoWindowAdapter(mapboxMap);
+
+ //Add a click listener
+ mapboxMap.setOnMapClickListener(new MapboxMap.OnMapClickListener() {
+ @Override
+ public void onMapClick(@NonNull LatLng point) {
+ //Query
+ final PointF pixel = mapboxMap.getProjection().toScreenLocation(point);
+ Timber.i(String.format(
+ "Requesting features for %sx%s (%sx%s adjusted for density)",
+ pixel.x, pixel.y, pixel.x / density, pixel.y / density)
+ );
+ List<Feature> features = mapboxMap.queryRenderedFeatures(pixel);
+
+ //Debug output
+ debugOutput(features);
+
+ //Remove any previous markers
+ if (marker != null) {
+ mapboxMap.removeMarker(marker);
}
+
+ //Add a marker on the clicked point
+ marker = mapboxMap.addMarker(new CustomMarkerOptions().position(point).features(features));
+ mapboxMap.selectMarker(marker);
+ }
});
+ }
+ });
+
+ }
+
+ private void debugOutput(List<Feature> features) {
+ Timber.i(String.format("Got %s features", features.size()));
+ for (Feature feature : features) {
+ if (feature != null) {
+ Timber.i(String.format("Got feature %s with %s properties and Geometry %s",
+ feature.getId(),
+ feature.getProperties() != null ? feature.getProperties().entrySet().size() : "<null>",
+ feature.getGeometry() != null ? feature.getGeometry().getClass().getSimpleName() : "<null>")
+ );
+ if (feature.getProperties() != null) {
+ for (Map.Entry<String, JsonElement> entry : feature.getProperties().entrySet()) {
+ Timber.i(String.format("Prop %s - %s", entry.getKey(), entry.getValue()));
+ }
+ }
+ } else {
+ // TODO Question: Why not formatting here??
+ Timber.i("Got NULL feature %s");
+ }
+ }
+ }
+
+ private void addCustomInfoWindowAdapter(MapboxMap mapboxMap) {
+ mapboxMap.setInfoWindowAdapter(new MapboxMap.InfoWindowAdapter() {
+
+ private TextView row(String text) {
+ TextView view = new TextView(QueryRenderedFeaturesPropertiesActivity.this);
+ view.setText(text);
+ return view;
+ }
+
+ @Override
+ public View getInfoWindow(@NonNull Marker marker) {
+ CustomMarker customMarker = (CustomMarker) marker;
+ LinearLayout view = new LinearLayout(QueryRenderedFeaturesPropertiesActivity.this);
+ view.setOrientation(LinearLayout.VERTICAL);
+ view.setBackgroundColor(Color.WHITE);
+
+ if (customMarker.features.size() > 0) {
+ view.addView(row(String.format("Found %s features", customMarker.features.size())));
+ Feature feature = customMarker.features.get(0);
+ for (Map.Entry<String, JsonElement> prop : feature.getProperties().entrySet()) {
+ view.addView(row(String.format("%s: %s", prop.getKey(), prop.getValue())));
+ }
+ } else {
+ view.addView(row("No features here"));
+ }
+ return view;
+ }
+ });
+ }
+
+ public MapboxMap getMapboxMap() {
+ return mapboxMap;
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
- private void debugOutput(List<Feature> features) {
- Log.i(TAG, String.format("Got %s features", features.size()));
- for (Feature feature : features) {
- if (feature != null) {
- Log.i(TAG, String.format("Got feature %s with %s properties and Geometry %s",
- feature.getId(),
- feature.getProperties() != null ? feature.getProperties().entrySet().size() : "<null>",
- feature.getGeometry() != null ? feature.getGeometry().getClass().getSimpleName() : "<null>")
- );
- if (feature.getProperties() != null) {
- for (Map.Entry<String, JsonElement> entry : feature.getProperties().entrySet()) {
- Log.i(TAG, String.format("Prop %s - %s", entry.getKey(), entry.getValue()));
- }
- }
- } else {
- Log.i(TAG, "Got NULL feature %s");
- }
- }
+ private void setupActionBar() {
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+
+ final ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
+ }
- private void addCustomInfoWindowAdapter(MapboxMap mapboxMap) {
- mapboxMap.setInfoWindowAdapter(new MapboxMap.InfoWindowAdapter() {
+ private static class CustomMarker extends Marker {
- private TextView row(String text) {
- TextView view = new TextView(QueryRenderedFeaturesPropertiesActivity.this);
- view.setText(text);
- return view;
- }
+ private final List<Feature> features;
- private int tenDp = (int) getResources().getDimension(R.dimen.attr_margin);
-
- @Override
- public View getInfoWindow(@NonNull Marker marker) {
- CustomMarker customMarker = (CustomMarker) marker;
- LinearLayout view = new LinearLayout(QueryRenderedFeaturesPropertiesActivity.this);
- view.setOrientation(LinearLayout.VERTICAL);
- view.setBackgroundColor(Color.WHITE);
-
- if (customMarker.features.size() > 0) {
- view.addView(row(String.format("Found %s features", customMarker.features.size())));
- Feature feature = customMarker.features.get(0);
- for (Map.Entry<String, JsonElement> prop : feature.getProperties().entrySet()) {
- view.addView(row(String.format("%s: %s", prop.getKey(), prop.getValue())));
- }
- } else {
- view.addView(row("No features here"));
- }
-
- return view;
- }
- });
+ public CustomMarker(BaseMarkerOptions baseMarkerOptions, List<Feature> features) {
+ super(baseMarkerOptions);
+ this.features = features;
}
+ }
- public MapboxMap getMapboxMap() {
- return mapboxMap;
- }
+ private static class CustomMarkerOptions extends BaseMarkerOptions<CustomMarker, CustomMarkerOptions> {
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
- }
+ private List<Feature> features;
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
+ public CustomMarkerOptions features(List<Feature> features) {
+ this.features = features;
+ return this;
}
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
+ public CustomMarkerOptions() {
}
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
+ private CustomMarkerOptions(Parcel in) {
+ //Should implement this
}
@Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
+ public CustomMarkerOptions getThis() {
+ return this;
}
- private void setupActionBar() {
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
-
- final ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
- }
-
- private static class CustomMarker extends Marker {
-
- private final List<Feature> features;
-
- public CustomMarker(BaseMarkerOptions baseMarkerOptions, List<Feature> features) {
- super(baseMarkerOptions);
- this.features = features;
- }
+ @Override
+ public CustomMarker getMarker() {
+ return new CustomMarker(this, features);
}
- private static class CustomMarkerOptions extends BaseMarkerOptions<CustomMarker, CustomMarkerOptions> {
-
-
- private List<Feature> features;
-
- public CustomMarkerOptions features(List<Feature> features) {
- this.features = features;
- return this;
- }
-
- public CustomMarkerOptions() {
- }
-
- private CustomMarkerOptions(Parcel in) {
- //Should implement this
- }
-
- @Override
- public CustomMarkerOptions getThis() {
- return this;
+ public static final Parcelable.Creator<CustomMarkerOptions> CREATOR
+ = new Parcelable.Creator<CustomMarkerOptions>() {
+ public CustomMarkerOptions createFromParcel(Parcel in) {
+ return new CustomMarkerOptions(in);
}
- @Override
- public CustomMarker getMarker() {
- return new CustomMarker(this, features);
+ public CustomMarkerOptions[] newArray(int size) {
+ return new CustomMarkerOptions[size];
}
+ };
- public static final Parcelable.Creator<CustomMarkerOptions> CREATOR
- = new Parcelable.Creator<CustomMarkerOptions>() {
- public CustomMarkerOptions createFromParcel(Parcel in) {
- return new CustomMarkerOptions(in);
- }
-
- public CustomMarkerOptions[] newArray(int size) {
- return new CustomMarkerOptions[size];
- }
- };
-
- @Override
- public int describeContents() {
- return 0;
- }
+ @Override
+ public int describeContents() {
+ return 0;
+ }
- @Override
- public void writeToParcel(Parcel out, int flags) {
- //Should implement this
- }
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ //Should implement this
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/MapFragmentActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/MapFragmentActivity.java
index e97f21327e..1c259b1304 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/MapFragmentActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/MapFragmentActivity.java
@@ -19,71 +19,71 @@ import com.mapbox.mapboxsdk.testapp.R;
public class MapFragmentActivity extends AppCompatActivity implements OnMapReadyCallback {
- private MapboxMap mapboxMap;
+ private MapboxMap mapboxMap;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_map_fragment);
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_map_fragment);
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- MapFragment mapFragment;
- if (savedInstanceState == null) {
- FragmentTransaction transaction = getFragmentManager().beginTransaction();
-
- MapboxMapOptions options = new MapboxMapOptions();
- options.styleUrl(Style.OUTDOORS);
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
+ }
- options.scrollGesturesEnabled(false);
- options.zoomGesturesEnabled(false);
- options.tiltGesturesEnabled(false);
- options.rotateGesturesEnabled(false);
+ MapFragment mapFragment;
+ if (savedInstanceState == null) {
+ final FragmentTransaction transaction = getFragmentManager().beginTransaction();
- options.debugActive(false);
+ MapboxMapOptions options = new MapboxMapOptions();
+ options.styleUrl(Style.OUTDOORS);
- LatLng dc = new LatLng(38.90252, -77.02291);
+ options.scrollGesturesEnabled(false);
+ options.zoomGesturesEnabled(false);
+ options.tiltGesturesEnabled(false);
+ options.rotateGesturesEnabled(false);
- options.minZoom(9);
- options.maxZoom(11);
- options.camera(new CameraPosition.Builder()
- .target(dc)
- .zoom(11)
- .build());
+ options.debugActive(false);
- mapFragment = MapFragment.newInstance(options);
+ LatLng dc = new LatLng(38.90252, -77.02291);
- transaction.add(R.id.fragment_container, mapFragment, "com.mapbox.map");
- transaction.commit();
- } else {
- mapFragment = (MapFragment) getFragmentManager().findFragmentByTag("com.mapbox.map");
- }
+ options.minZoomPreference(9);
+ options.maxZoomPreference(11);
+ options.camera(new CameraPosition.Builder()
+ .target(dc)
+ .zoom(11)
+ .build());
- mapFragment.getMapAsync(this);
- }
+ mapFragment = MapFragment.newInstance(options);
- @Override
- public void onMapReady(MapboxMap map) {
- mapboxMap = map;
- mapboxMap.animateCamera(
- CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder().tilt(45.0).build()), 10000);
+ transaction.add(R.id.fragment_container, mapFragment, "com.mapbox.map");
+ transaction.commit();
+ } else {
+ mapFragment = (MapFragment) getFragmentManager().findFragmentByTag("com.mapbox.map");
}
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
+ mapFragment.getMapAsync(this);
+ }
+
+ @Override
+ public void onMapReady(MapboxMap map) {
+ mapboxMap = map;
+ mapboxMap.animateCamera(
+ CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder().tilt(45.0).build()), 10000);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
}
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
index 526f9ae107..d5d51887dd 100644
--- 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
@@ -7,9 +7,9 @@ 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);
- }
+ @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/fragment/SupportMapFragmentActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/SupportMapFragmentActivity.java
index 03444a871d..ca499c871e 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/SupportMapFragmentActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/SupportMapFragmentActivity.java
@@ -19,74 +19,69 @@ import com.mapbox.mapboxsdk.testapp.R;
public class SupportMapFragmentActivity extends AppCompatActivity implements OnMapReadyCallback {
- private MapboxMap mapboxMap;
+ private MapboxMap mapboxMap;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_map_fragment);
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_map_fragment);
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- SupportMapFragment mapFragment;
- if (savedInstanceState == null) {
- FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
-
- MapboxMapOptions options = new MapboxMapOptions();
- options.styleUrl(Style.SATELLITE_STREETS);
-
- options.scrollGesturesEnabled(false);
- options.zoomGesturesEnabled(false);
- options.tiltGesturesEnabled(false);
- options.rotateGesturesEnabled(false);
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
+ }
- options.debugActive(false);
- options.compassEnabled(false);
- options.attributionEnabled(false);
- options.logoEnabled(false);
+ SupportMapFragment mapFragment;
+ if (savedInstanceState == null) {
+ final FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
- LatLng dc = new LatLng(38.90252, -77.02291);
+ MapboxMapOptions options = new MapboxMapOptions();
+ options.styleUrl(Style.SATELLITE_STREETS);
- options.minZoom(9);
- options.maxZoom(11);
- options.camera(new CameraPosition.Builder()
- .target(dc)
- .zoom(11)
- .build());
+ options.debugActive(false);
+ options.compassEnabled(false);
+ options.attributionEnabled(false);
+ options.logoEnabled(false);
- mapFragment = SupportMapFragment.newInstance(options);
+ LatLng dc = new LatLng(38.90252, -77.02291);
- transaction.add(R.id.fragment_container, mapFragment, "com.mapbox.map");
- transaction.commit();
- } else {
- mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentByTag("com.mapbox.map");
- }
+ options.minZoomPreference(9);
+ options.maxZoomPreference(11);
+ options.camera(new CameraPosition.Builder()
+ .target(dc)
+ .zoom(11)
+ .build());
- mapFragment.getMapAsync(this);
- }
+ mapFragment = SupportMapFragment.newInstance(options);
- @Override
- public void onMapReady(MapboxMap map) {
- mapboxMap = map;
- mapboxMap.animateCamera(
- CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder().tilt(45.0).build()), 10000);
+ transaction.add(R.id.fragment_container, mapFragment, "com.mapbox.map");
+ transaction.commit();
+ } else {
+ mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentByTag("com.mapbox.map");
}
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
+ mapFragment.getMapAsync(this);
+ }
+
+ @Override
+ public void onMapReady(MapboxMap map) {
+ mapboxMap = map;
+ mapboxMap.animateCamera(
+ CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder().tilt(45.0).build()), 10000);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/ViewPagerActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/ViewPagerActivity.java
index 6cd3fd62a1..e6953bd3d2 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/ViewPagerActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/ViewPagerActivity.java
@@ -19,81 +19,81 @@ import com.mapbox.mapboxsdk.testapp.R;
public class ViewPagerActivity extends AppCompatActivity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_viewpager);
+
+ final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
+ }
+
+ ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
+ if (viewPager != null) {
+ MapFragmentAdapter adapter = new MapFragmentAdapter(getSupportFragmentManager());
+ viewPager.setAdapter(adapter);
+ }
+ }
+
+ public static class MapFragmentAdapter extends FragmentPagerAdapter {
+
+ private static int NUM_ITEMS = 3;
+
+ public MapFragmentAdapter(FragmentManager fragmentManager) {
+ super(fragmentManager);
+ }
+
@Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_viewpager);
-
- final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
-
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
- if (viewPager != null) {
- MapFragmentAdapter adapter = new MapFragmentAdapter(getSupportFragmentManager());
- viewPager.setAdapter(adapter);
- }
+ public int getCount() {
+ return NUM_ITEMS;
}
- public static class MapFragmentAdapter extends FragmentPagerAdapter {
-
- private static int NUM_ITEMS = 3;
-
- public MapFragmentAdapter(FragmentManager fragmentManager) {
- super(fragmentManager);
- }
-
- @Override
- public int getCount() {
- return NUM_ITEMS;
- }
-
- @Override
- public Fragment getItem(int position) {
- SupportMapFragment fragment = null;
- MapboxMapOptions options = new MapboxMapOptions();
-
- switch (position) {
- case 0:
- options.styleUrl(Style.MAPBOX_STREETS);
- options.camera(new CameraPosition.Builder().target(new LatLng(34.920526, 102.634774)).zoom(3).build());
- fragment = SupportMapFragment.newInstance(options);
- break;
- case 1:
- options.styleUrl(Style.DARK);
- options.camera(new CameraPosition.Builder().target(new LatLng(62.326440, 92.764913)).zoom(3).build());
- fragment = SupportMapFragment.newInstance(options);
- break;
- case 2:
- options.styleUrl(Style.SATELLITE);
- options.camera(new CameraPosition.Builder().target(new LatLng(-25.007786, 133.623852)).zoom(3).build());
- fragment = SupportMapFragment.newInstance(options);
- break;
- }
- return fragment;
- }
-
-
- @Override
- public CharSequence getPageTitle(int position) {
- return "Page " + position;
- }
+ @Override
+ public Fragment getItem(int position) {
+ SupportMapFragment fragment = null;
+ MapboxMapOptions options = new MapboxMapOptions();
+
+ switch (position) {
+ case 0:
+ options.styleUrl(Style.MAPBOX_STREETS);
+ options.camera(new CameraPosition.Builder().target(new LatLng(34.920526, 102.634774)).zoom(3).build());
+ fragment = SupportMapFragment.newInstance(options);
+ break;
+ case 1:
+ options.styleUrl(Style.DARK);
+ options.camera(new CameraPosition.Builder().target(new LatLng(62.326440, 92.764913)).zoom(3).build());
+ fragment = SupportMapFragment.newInstance(options);
+ break;
+ case 2:
+ options.styleUrl(Style.SATELLITE);
+ options.camera(new CameraPosition.Builder().target(new LatLng(-25.007786, 133.623852)).zoom(3).build());
+ fragment = SupportMapFragment.newInstance(options);
+ break;
+ }
+ return fragment;
}
+
@Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
+ public CharSequence getPageTitle(int position) {
+ return "Page " + position;
+ }
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/geocoding/GeocoderActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/geocoding/GeocoderActivity.java
index baa020fe95..43feb5eaad 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/geocoding/GeocoderActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/geocoding/GeocoderActivity.java
@@ -6,7 +6,9 @@ import android.support.annotation.NonNull;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
-import android.util.Log;
+
+import timber.log.Timber;
+
import android.view.Gravity;
import android.view.MenuItem;
import android.view.ViewGroup;
@@ -37,157 +39,167 @@ import retrofit2.Response;
public class GeocoderActivity extends AppCompatActivity implements OnMapReadyCallback {
- private static final String LOG_TAG = "GeocoderActivity";
-
- private MapboxMap mapboxMap;
- private MapView mapView;
- private ImageView dropPinView;
- private TextView textView;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_geocoder);
+ private MapboxMap mapboxMap;
+ private MapView mapView;
+ private ImageView dropPinView;
+ private TextView textView;
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_geocoder);
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- textView = (TextView) findViewById(R.id.message);
- setMessage(getString(R.string.geocoder_instructions));
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.setStyleUrl(Style.MAPBOX_STREETS);
- mapView.onCreate(savedInstanceState);
-
- dropPinView = new ImageView(this);
- dropPinView.setImageResource(R.drawable.ic_droppin_24dp);
- FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER);
- dropPinView.setLayoutParams(params);
- mapView.addView(dropPinView);
- mapView.getMapAsync(this);
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
- @Override
- public void onMapReady(MapboxMap map) {
- mapboxMap = map;
- final Projection projection = mapboxMap.getProjection();
- final int width = mapView.getMeasuredWidth();
- final int height = mapView.getMeasuredHeight();
-
- // Click listener
- mapboxMap.setOnMapClickListener(new MapboxMap.OnMapClickListener() {
- @Override
- public void onMapClick(@NonNull LatLng point) {
- PointF centerPoint = new PointF(width / 2, (height + dropPinView.getHeight()) / 2);
- LatLng centerLatLng = new LatLng(projection.fromScreenLocation(centerPoint));
+ textView = (TextView) findViewById(R.id.message);
+ setMessage(getString(R.string.geocoder_instructions));
+
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.setStyleUrl(Style.MAPBOX_STREETS);
+ mapView.onCreate(savedInstanceState);
+
+ dropPinView = new ImageView(this);
+ dropPinView.setImageResource(R.drawable.ic_droppin_24dp);
+ FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER);
+ dropPinView.setLayoutParams(params);
+ mapView.addView(dropPinView);
+ mapView.getMapAsync(this);
+ }
+
+ @Override
+ public void onMapReady(MapboxMap map) {
+ mapboxMap = map;
+ final Projection projection = mapboxMap.getProjection();
+ final int width = mapView.getMeasuredWidth();
+ final int height = mapView.getMeasuredHeight();
+
+ // Click listener
+ mapboxMap.setOnMapClickListener(new MapboxMap.OnMapClickListener() {
+ @Override
+ public void onMapClick(@NonNull LatLng point) {
+ PointF centerPoint = new PointF(width / 2, (height + dropPinView.getHeight()) / 2);
+ LatLng centerLatLng = new LatLng(projection.fromScreenLocation(centerPoint));
+
+ setMessage("Geocoding...");
+
+ mapboxMap.removeAnnotations();
+ mapboxMap.addMarker(new MarkerOptions().position(centerLatLng));
+
+ geocode(centerLatLng);
+ }
+ });
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ /*
+ * Forward geocoding
+ */
+
+ private void geocode(final LatLng point) {
+
+ try {
+ MapboxGeocoding client = new MapboxGeocoding.Builder()
+ .setAccessToken(getString(R.string.mapbox_access_token))
+ .setCoordinates(Position.fromCoordinates(point.getLongitude(), point.getLatitude()))
+ .setGeocodingType(GeocodingCriteria.TYPE_POI)
+ .build();
+
+ client.enqueueCall(new Callback<GeocodingResponse>() {
+ @Override
+ public void onResponse(Call<GeocodingResponse> call, Response<GeocodingResponse> response) {
+
+ List<CarmenFeature> results = response.body().getFeatures();
+ if (results.size() > 0) {
+ String placeName = results.get(0).getPlaceName();
+ setSuccess(placeName);
+ } else {
+ setMessage("No results.");
+ }
- setMessage("Geocoding...");
-
- mapboxMap.removeAnnotations();
- mapboxMap.addMarker(new MarkerOptions().position(centerLatLng));
-
- geocode(centerLatLng);
- }
- });
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- }
-
- /*
- * Forward geocoding
- */
-
- private void geocode(final LatLng point) {
-
- try {
- MapboxGeocoding client = new MapboxGeocoding.Builder()
- .setAccessToken(getString(R.string.mapbox_access_token))
- .setCoordinates(Position.fromCoordinates(point.getLongitude(), point.getLatitude()))
- .setGeocodingType(GeocodingCriteria.TYPE_POI)
- .build();
-
- client.enqueueCall(new Callback<GeocodingResponse>() {
- @Override
- public void onResponse(Call<GeocodingResponse> call, Response<GeocodingResponse> response) {
-
- List<CarmenFeature> results = response.body().getFeatures();
- if (results.size() > 0) {
- String placeName = results.get(0).getPlaceName();
- setSuccess(placeName);
- } else {
- setMessage("No results.");
- }
-
- }
-
- @Override
- public void onFailure(Call<GeocodingResponse> call, Throwable throwable) {
- setError(throwable.getMessage());
- }
- });
- } catch (ServicesException servicesException) {
- Log.e(LOG_TAG, "Error geocoding: " + servicesException.toString());
- servicesException.printStackTrace();
- setError(servicesException.getMessage());
}
- }
-
- /*
- * Update text view
- */
- private void setMessage(String message) {
- Log.d(LOG_TAG, "Message: " + message);
- textView.setText(message);
- }
-
- private void setSuccess(String placeName) {
- Log.d(LOG_TAG, "Place name: " + placeName);
- textView.setText(placeName);
- }
-
- private void setError(String message) {
- Log.e(LOG_TAG, "Error: " + message);
- textView.setText("Error: " + message);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
+ @Override
+ public void onFailure(Call<GeocodingResponse> call, Throwable throwable) {
+ setError(throwable.getMessage());
}
+ });
+ } catch (ServicesException servicesException) {
+ Timber.e("Error geocoding: " + servicesException.toString());
+ servicesException.printStackTrace();
+ setError(servicesException.getMessage());
+ }
+ }
+
+ /*
+ * Update text view
+ */
+
+ private void setMessage(String message) {
+ Timber.d("Message: " + message);
+ textView.setText(message);
+ }
+
+ private void setSuccess(String placeName) {
+ Timber.d("Place name: " + placeName);
+ textView.setText(placeName);
+ }
+
+ private void setError(String message) {
+ Timber.e("Error: " + message);
+ textView.setText("Error: " + message);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/imagegenerator/PrintActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/imagegenerator/PrintActivity.java
index 18353003d1..7f3c16d7b8 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/imagegenerator/PrintActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/imagegenerator/PrintActivity.java
@@ -17,91 +17,103 @@ import com.mapbox.mapboxsdk.testapp.R;
public class PrintActivity extends AppCompatActivity implements MapboxMap.SnapshotReadyCallback {
- private MapView mapView;
- private MapboxMap mapboxMap;
+ private MapView mapView;
+ private MapboxMap mapboxMap;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_print);
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_print);
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- final ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(@NonNull MapboxMap mapboxMap) {
- PrintActivity.this.mapboxMap = mapboxMap;
- }
- });
-
- final View fab = findViewById(R.id.fab);
- if (fab != null) {
- fab.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- if (mapboxMap != null) {
- mapboxMap.snapshot(PrintActivity.this);
- }
- }
- });
- }
- }
-
- @Override
- public void onSnapshotReady(Bitmap snapshot) {
- PrintHelper photoPrinter = new PrintHelper(this);
- photoPrinter.setScaleMode(PrintHelper.SCALE_MODE_FIT);
- photoPrinter.printBitmap("map.jpg - mapbox print job", snapshot);
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
-
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
+ final ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(@NonNull MapboxMap mapboxMap) {
+ PrintActivity.this.mapboxMap = mapboxMap;
+ }
+ });
+
+ final View fab = findViewById(R.id.fab);
+ if (fab != null) {
+ fab.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ if (mapboxMap != null) {
+ mapboxMap.snapshot(PrintActivity.this);
+ }
}
+ });
+ }
+ }
+
+ @Override
+ public void onSnapshotReady(Bitmap snapshot) {
+ PrintHelper photoPrinter = new PrintHelper(this);
+ photoPrinter.setScaleMode(PrintHelper.SCALE_MODE_FIT);
+ photoPrinter.printBitmap("map.jpg - mapbox print job", snapshot);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/imagegenerator/SnapshotActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/imagegenerator/SnapshotActivity.java
index ab4188fd52..3912dfa918 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/imagegenerator/SnapshotActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/imagegenerator/SnapshotActivity.java
@@ -20,95 +20,107 @@ import com.mapbox.mapboxsdk.testapp.R;
public class SnapshotActivity extends AppCompatActivity implements OnMapReadyCallback, View.OnClickListener {
- private MapView mapView;
- private MapboxMap mapboxMap;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_snapshot);
-
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
-
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(this);
- }
-
- @Override
- public void onMapReady(MapboxMap map) {
- mapboxMap = map;
- mapboxMap.setStyleUrl(Style.OUTDOORS);
- FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
- if (fab != null) {
- fab.setColorFilter(ContextCompat.getColor(SnapshotActivity.this, R.color.primary));
- fab.setOnClickListener(this);
- }
- }
-
- @Override
- public void onClick(View view) {
- final long startTime = System.nanoTime();
- mapboxMap.snapshot(new MapboxMap.SnapshotReadyCallback() {
- @Override
- public void onSnapshotReady(Bitmap snapshot) {
- long endTime = System.nanoTime();
- long duration = (long) ((endTime - startTime) / 1e6);
- ImageView snapshotView = (ImageView) findViewById(R.id.imageView);
- snapshotView.setImageBitmap(snapshot);
- Toast.makeText(
- SnapshotActivity.this,
- String.format("Snapshot taken in %d ms", duration),
- Toast.LENGTH_LONG).show();
- }
- });
- }
+ private MapView mapView;
+ private MapboxMap mapboxMap;
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_snapshot);
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
- }
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(this);
+ }
+
+ @Override
+ public void onMapReady(MapboxMap map) {
+ mapboxMap = map;
+ mapboxMap.setStyleUrl(Style.OUTDOORS);
+ FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
+ if (fab != null) {
+ fab.setColorFilter(ContextCompat.getColor(SnapshotActivity.this, R.color.primary));
+ fab.setOnClickListener(this);
}
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
+ }
+
+ @Override
+ public void onClick(View view) {
+ final long startTime = System.nanoTime();
+ mapboxMap.snapshot(new MapboxMap.SnapshotReadyCallback() {
+ @Override
+ public void onSnapshotReady(Bitmap snapshot) {
+ long endTime = System.nanoTime();
+ long duration = (long) ((endTime - startTime) / 1e6);
+ ImageView snapshotView = (ImageView) findViewById(R.id.imageView);
+ snapshotView.setImageBitmap(snapshot);
+ Toast.makeText(
+ SnapshotActivity.this,
+ String.format("Snapshot taken in %d ms", duration),
+ Toast.LENGTH_LONG).show();
+ }
+ });
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/infowindow/DynamicInfoWindowAdapterActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/infowindow/DynamicInfoWindowAdapterActivity.java
index cf522d7f39..c70e263be5 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/infowindow/DynamicInfoWindowAdapterActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/infowindow/DynamicInfoWindowAdapterActivity.java
@@ -31,142 +31,157 @@ import com.mapbox.mapboxsdk.testapp.R;
*/
public class DynamicInfoWindowAdapterActivity extends AppCompatActivity implements OnMapReadyCallback {
- private MapboxMap mapboxMap;
- private MapView mapView;
+ private MapboxMap mapboxMap;
+ private MapView mapView;
- private LatLng paris = new LatLng(48.864716, 2.349014);
+ private LatLng paris = new LatLng(48.864716, 2.349014);
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_infowindow_adapter);
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_infowindow_adapter);
- setupActionBar();
+ setupActionBar();
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(this);
- }
-
- @Override
- public void onMapReady(MapboxMap map) {
-
- mapboxMap = map;
-
- //Add info window adapter
- addCustomInfoWindowAdapter(mapboxMap);
-
- //Keep info windows open on click
- mapboxMap.getUiSettings().setDeselectMarkersOnTap(false);
-
- //Add a marker
- final MarkerView marker = addMarker(mapboxMap);
- mapboxMap.selectMarker(marker);
-
- //On map click, change the info window contents
- mapboxMap.setOnMapClickListener(new MapboxMap.OnMapClickListener() {
- @Override
- public void onMapClick(@NonNull LatLng point) {
- //Distance from click to marker
- double distanceKm = marker.getPosition().distanceTo(point) / 1000;
-
- //Get the info window
- InfoWindow infoWindow = marker.getInfoWindow();
-
- //Get the view from the info window
- if (infoWindow != null && infoWindow.getView() != null) {
- //Set the new text on the text view in the info window
- ((TextView) infoWindow.getView()).setText(String.format("%.2fkm", distanceKm));
-
- //Update the info window position (as the text length changes)
- infoWindow.update();
- }
- }
- });
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(this);
+ }
- //Focus on Paris
- mapboxMap.animateCamera(CameraUpdateFactory.newLatLng(paris));
- }
+ @Override
+ public void onMapReady(MapboxMap map) {
- private MarkerView addMarker(MapboxMap mapboxMap) {
- IconFactory iconFactory = IconFactory.getInstance(this);
- Drawable iconDrawable = ContextCompat.getDrawable(this, R.drawable.ic_location_city_24dp);
- iconDrawable.setColorFilter(getResources().getColor(R.color.mapbox_blue), PorterDuff.Mode.SRC_IN);
+ mapboxMap = map;
- return mapboxMap.addMarker(
- new MarkerViewOptions()
- .position(paris)
- .icon(iconFactory.fromDrawable(iconDrawable))
- );
- }
+ //Add info window adapter
+ addCustomInfoWindowAdapter(mapboxMap);
- private void addCustomInfoWindowAdapter(final MapboxMap mapboxMap) {
- final int padding = (int) getResources().getDimension(R.dimen.attr_margin);
- mapboxMap.setInfoWindowAdapter(new MapboxMap.InfoWindowAdapter() {
-
- @Nullable
- @Override
- public View getInfoWindow(@NonNull Marker marker) {
- TextView textView = new TextView(DynamicInfoWindowAdapterActivity.this);
- textView.setText(marker.getTitle());
- textView.setBackgroundColor(Color.WHITE);
- textView.setText("Click the map to calculate the distance");
- textView.setPadding(padding, padding, padding, padding);
-
- return textView;
- }
- });
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
+ //Keep info windows open on click
+ mapboxMap.getUiSettings().setDeselectMarkersOnTap(false);
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
- }
+ //Add a marker
+ final MarkerView marker = addMarker(mapboxMap);
+ mapboxMap.selectMarker(marker);
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- }
+ //On map click, change the info window contents
+ mapboxMap.setOnMapClickListener(new MapboxMap.OnMapClickListener() {
+ @Override
+ public void onMapClick(@NonNull LatLng point) {
+ //Distance from click to marker
+ double distanceKm = marker.getPosition().distanceTo(point) / 1000;
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
+ //Get the info window
+ InfoWindow infoWindow = marker.getInfoWindow();
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
- }
+ //Get the view from the info window
+ if (infoWindow != null && infoWindow.getView() != null) {
+ //Set the new text on the text view in the info window
+ ((TextView) infoWindow.getView()).setText(String.format("%.2fkm", distanceKm));
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
+ //Update the info window position (as the text length changes)
+ infoWindow.update();
}
+ }
+ });
+
+ //Focus on Paris
+ mapboxMap.animateCamera(CameraUpdateFactory.newLatLng(paris));
+ }
+
+ private MarkerView addMarker(MapboxMap mapboxMap) {
+ IconFactory iconFactory = IconFactory.getInstance(this);
+ Drawable iconDrawable = ContextCompat.getDrawable(this, R.drawable.ic_location_city_24dp);
+ iconDrawable.setColorFilter(
+ ContextCompat.getColor(DynamicInfoWindowAdapterActivity.this, R.color.mapbox_blue),
+ PorterDuff.Mode.SRC_IN
+ );
+
+ return mapboxMap.addMarker(
+ new MarkerViewOptions()
+ .position(paris)
+ .icon(iconFactory.fromDrawable(iconDrawable))
+ );
+ }
+
+ private void addCustomInfoWindowAdapter(final MapboxMap mapboxMap) {
+ final int padding = (int) getResources().getDimension(R.dimen.attr_margin);
+ mapboxMap.setInfoWindowAdapter(new MapboxMap.InfoWindowAdapter() {
+
+ @Nullable
+ @Override
+ public View getInfoWindow(@NonNull Marker marker) {
+ TextView textView = new TextView(DynamicInfoWindowAdapterActivity.this);
+ textView.setText(marker.getTitle());
+ textView.setBackgroundColor(Color.WHITE);
+ textView.setText("Click the map to calculate the distance");
+ textView.setPadding(padding, padding, padding, padding);
+
+ return textView;
+ }
+ });
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
- private void setupActionBar() {
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
+ private void setupActionBar() {
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/infowindow/InfoWindowActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/infowindow/InfoWindowActivity.java
index 113c46c3e5..0c2af9b7e3 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/infowindow/InfoWindowActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/infowindow/InfoWindowActivity.java
@@ -8,6 +8,7 @@ import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
+
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
@@ -15,170 +16,183 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.testapp.R;
import com.mapbox.mapboxsdk.maps.MapView;
+
import java.text.DecimalFormat;
public class InfoWindowActivity extends AppCompatActivity
- implements OnMapReadyCallback, MapboxMap.OnInfoWindowCloseListener, MapboxMap.OnMapLongClickListener,
- MapboxMap.OnInfoWindowClickListener, MapboxMap.OnInfoWindowLongClickListener {
-
- private MapboxMap mapboxMap;
- private MapView mapView;
- private Marker customMarker;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_infowindow);
-
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
-
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(this);
- }
-
- @Override
- public void onMapReady(@NonNull MapboxMap mapboxMap) {
- this.mapboxMap = mapboxMap;
- addMarkers();
- addInfoWindowListeners();
- }
-
- private void addMarkers() {
- mapboxMap.addMarker(new MarkerOptions()
- .title("Intersection")
- .snippet("H St NW with 15th St NW")
- .position(new LatLng(38.9002073, -77.03364419)));
-
- mapboxMap.addMarker(new MarkerOptions().title("Intersection")
- .snippet("E St NW with 17th St NW")
- .position(new LatLng(38.8954236, -77.0394623)));
-
- mapboxMap.addMarker(new MarkerOptions().title("The Ellipse").position(new LatLng(38.89393, -77.03654)));
-
- mapboxMap.addMarker(new MarkerOptions().position(new LatLng(38.89596, -77.03434)));
-
- mapboxMap.addMarker(new MarkerOptions().snippet("Lafayette Square").position(new LatLng(38.89949, -77.03656)));
-
- Marker marker = mapboxMap.addMarker(new MarkerOptions()
- .title("White House")
- .snippet("The official residence and principal workplace of the President of the United States, "
- + "located at 1600 Pennsylvania Avenue NW in Washington, D.C. It has been the residence of every"
- + "U.S. president since John Adams in 1800.")
- .position(new LatLng(38.897705003219784, -77.03655168667463)));
-
- // open InfoWindow at startup
- mapboxMap.selectMarker(marker);
- }
-
- private void addInfoWindowListeners() {
- mapboxMap.setOnInfoWindowCloseListener(this);
- mapboxMap.setOnMapLongClickListener(this);
- mapboxMap.setOnInfoWindowClickListener(this);
- mapboxMap.setOnInfoWindowLongClickListener(this);
- }
-
- private void toggleConcurrentInfoWindow(boolean allowConcurrentInfoWindow) {
- mapboxMap.deselectMarkers();
- mapboxMap.setAllowConcurrentMultipleOpenInfoWindows(allowConcurrentInfoWindow);
- }
-
- private void toggleDeselectMarkersOnTap(boolean deselectMarkersOnTap) {
- mapboxMap.getUiSettings().setDeselectMarkersOnTap(deselectMarkersOnTap);
- }
-
- @Override
- public boolean onInfoWindowClick(@NonNull Marker marker) {
- Toast.makeText(getApplicationContext(), "OnClick: " + marker.getTitle(), Toast.LENGTH_LONG).show();
- // returning true will leave the info window open
- return false;
- }
-
- @Override
- public void onInfoWindowClose(Marker marker) {
- Toast.makeText(getApplicationContext(), "OnClose: " + marker.getTitle(), Toast.LENGTH_LONG).show();
- }
-
- @Override
- public void onInfoWindowLongClick(Marker marker) {
- Toast.makeText(getApplicationContext(), "OnLongClick: " + marker.getTitle(), Toast.LENGTH_LONG).show();
- }
-
- @Override
- public void onMapLongClick(@NonNull LatLng point) {
- if (customMarker != null) {
- // Remove previous added marker
- mapboxMap.removeAnnotation(customMarker);
- customMarker = null;
- }
-
- // Add marker on long click location with default marker image
- customMarker = mapboxMap.addMarker(new MarkerOptions()
- .title("Custom Marker")
- .snippet(new DecimalFormat("#.#####").format(point.getLatitude()) + ", "
- + new DecimalFormat("#.#####").format(point.getLongitude()))
- .position(point));
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
-
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.menu_infowindow, menu);
+ implements OnMapReadyCallback, MapboxMap.OnInfoWindowCloseListener, MapboxMap.OnMapLongClickListener,
+ MapboxMap.OnInfoWindowClickListener, MapboxMap.OnInfoWindowLongClickListener {
+
+ private MapboxMap mapboxMap;
+ private MapView mapView;
+ private Marker customMarker;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_infowindow);
+
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
+ }
+
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(this);
+ }
+
+ @Override
+ public void onMapReady(@NonNull MapboxMap mapboxMap) {
+ this.mapboxMap = mapboxMap;
+ addMarkers();
+ addInfoWindowListeners();
+ }
+
+ private void addMarkers() {
+ mapboxMap.addMarker(new MarkerOptions()
+ .title("Intersection")
+ .snippet("H St NW with 15th St NW")
+ .position(new LatLng(38.9002073, -77.03364419)));
+
+ mapboxMap.addMarker(new MarkerOptions().title("Intersection")
+ .snippet("E St NW with 17th St NW")
+ .position(new LatLng(38.8954236, -77.0394623)));
+
+ mapboxMap.addMarker(new MarkerOptions().title("The Ellipse").position(new LatLng(38.89393, -77.03654)));
+
+ mapboxMap.addMarker(new MarkerOptions().position(new LatLng(38.89596, -77.03434)));
+
+ mapboxMap.addMarker(new MarkerOptions().snippet("Lafayette Square").position(new LatLng(38.89949, -77.03656)));
+
+ Marker marker = mapboxMap.addMarker(new MarkerOptions()
+ .title("White House")
+ .snippet("The official residence and principal workplace of the President of the United States, "
+ + "located at 1600 Pennsylvania Avenue NW in Washington, D.C. It has been the residence of every"
+ + "U.S. president since John Adams in 1800.")
+ .position(new LatLng(38.897705003219784, -77.03655168667463)));
+
+ // open InfoWindow at startup
+ mapboxMap.selectMarker(marker);
+ }
+
+ private void addInfoWindowListeners() {
+ mapboxMap.setOnInfoWindowCloseListener(this);
+ mapboxMap.setOnMapLongClickListener(this);
+ mapboxMap.setOnInfoWindowClickListener(this);
+ mapboxMap.setOnInfoWindowLongClickListener(this);
+ }
+
+ private void toggleConcurrentInfoWindow(boolean allowConcurrentInfoWindow) {
+ mapboxMap.deselectMarkers();
+ mapboxMap.setAllowConcurrentMultipleOpenInfoWindows(allowConcurrentInfoWindow);
+ }
+
+ private void toggleDeselectMarkersOnTap(boolean deselectMarkersOnTap) {
+ mapboxMap.getUiSettings().setDeselectMarkersOnTap(deselectMarkersOnTap);
+ }
+
+ @Override
+ public boolean onInfoWindowClick(@NonNull Marker marker) {
+ Toast.makeText(getApplicationContext(), "OnClick: " + marker.getTitle(), Toast.LENGTH_LONG).show();
+ // returning true will leave the info window open
+ return false;
+ }
+
+ @Override
+ public void onInfoWindowClose(Marker marker) {
+ Toast.makeText(getApplicationContext(), "OnClose: " + marker.getTitle(), Toast.LENGTH_LONG).show();
+ }
+
+ @Override
+ public void onInfoWindowLongClick(Marker marker) {
+ Toast.makeText(getApplicationContext(), "OnLongClick: " + marker.getTitle(), Toast.LENGTH_LONG).show();
+ }
+
+ @Override
+ public void onMapLongClick(@NonNull LatLng point) {
+ if (customMarker != null) {
+ // Remove previous added marker
+ mapboxMap.removeAnnotation(customMarker);
+ customMarker = null;
+ }
+
+ // Add marker on long click location with default marker image
+ customMarker = mapboxMap.addMarker(new MarkerOptions()
+ .title("Custom Marker")
+ .snippet(new DecimalFormat("#.#####").format(point.getLatitude()) + ", "
+ + new DecimalFormat("#.#####").format(point.getLongitude()))
+ .position(point));
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.menu_infowindow, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.action_toggle_concurrent_infowindow:
+ toggleConcurrentInfoWindow(!item.isChecked());
+ item.setChecked(!item.isChecked());
return true;
+ case R.id.action_toggle_deselect_markers_on_tap:
+ toggleDeselectMarkersOnTap(!item.isChecked());
+ item.setChecked(!item.isChecked());
+ return true;
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.action_toggle_concurrent_infowindow:
- toggleConcurrentInfoWindow(!item.isChecked());
- item.setChecked(!item.isChecked());
- return true;
- case R.id.action_toggle_deselect_markers_on_tap:
- toggleDeselectMarkersOnTap(!item.isChecked());
- item.setChecked(!item.isChecked());
- return true;
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
- }
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/infowindow/InfoWindowAdapterActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/infowindow/InfoWindowAdapterActivity.java
index 8066dbc60e..08f64abcba 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/infowindow/InfoWindowAdapterActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/infowindow/InfoWindowAdapterActivity.java
@@ -26,121 +26,133 @@ import com.mapbox.mapboxsdk.testapp.model.annotations.CityStateMarkerOptions;
public class InfoWindowAdapterActivity extends AppCompatActivity {
- private MapView mapView;
- private MapboxMap mapboxMap;
- private IconFactory iconFactory;
- private Drawable iconDrawable;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_infowindow_adapter);
-
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
-
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- iconFactory = IconFactory.getInstance(this);
- iconDrawable = ContextCompat.getDrawable(this, R.drawable.ic_location_city_24dp);
-
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(@NonNull MapboxMap map) {
- mapboxMap = map;
- addMarkers();
- addCustomInfoWindowAdapter();
- }
- });
- }
-
- private void addMarkers() {
- mapboxMap.addMarker(generateCityStateMarker("Andorra", 42.505777, 1.52529, "#F44336"));
- mapboxMap.addMarker(generateCityStateMarker("Luxembourg", 49.815273, 6.129583, "#3F51B5"));
- mapboxMap.addMarker(generateCityStateMarker("Monaco", 43.738418, 7.424616, "#673AB7"));
- mapboxMap.addMarker(generateCityStateMarker("Vatican City", 41.902916, 12.453389, "#009688"));
- mapboxMap.addMarker(generateCityStateMarker("San Marino", 43.942360, 12.457777, "#795548"));
- mapboxMap.addMarker(generateCityStateMarker("Liechtenstein", 47.166000, 9.555373, "#FF5722"));
- }
-
- private CityStateMarkerOptions generateCityStateMarker(String title, double lat, double lng, String color) {
- CityStateMarkerOptions marker = new CityStateMarkerOptions();
- marker.title(title);
- marker.position(new LatLng(lat, lng));
- marker.infoWindowBackground(color);
-
- iconDrawable.setColorFilter(Color.parseColor(color), PorterDuff.Mode.SRC_IN);
- Icon icon = iconFactory.fromDrawable(iconDrawable);
- marker.icon(icon);
- return marker;
- }
-
- private void addCustomInfoWindowAdapter() {
- mapboxMap.setInfoWindowAdapter(new MapboxMap.InfoWindowAdapter() {
-
- private int tenDp = (int) getResources().getDimension(R.dimen.attr_margin);
-
- @Override
- public View getInfoWindow(@NonNull Marker marker) {
- TextView textView = new TextView(InfoWindowAdapterActivity.this);
- textView.setText(marker.getTitle());
- textView.setTextColor(Color.WHITE);
-
- if (marker instanceof CityStateMarker) {
- CityStateMarker cityStateMarker = (CityStateMarker) marker;
- textView.setBackgroundColor(Color.parseColor(cityStateMarker.getInfoWindowBackgroundColor()));
- }
-
- textView.setPadding(tenDp, tenDp, tenDp, tenDp);
- return textView;
- }
- });
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
+ private MapView mapView;
+ private MapboxMap mapboxMap;
+ private IconFactory iconFactory;
+ private Drawable iconDrawable;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_infowindow_adapter);
+
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
+ iconFactory = IconFactory.getInstance(this);
+ iconDrawable = ContextCompat.getDrawable(this, R.drawable.ic_location_city_24dp);
+
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(@NonNull MapboxMap map) {
+ mapboxMap = map;
+ addMarkers();
+ addCustomInfoWindowAdapter();
+ }
+ });
+ }
+
+ private void addMarkers() {
+ mapboxMap.addMarker(generateCityStateMarker("Andorra", 42.505777, 1.52529, "#F44336"));
+ mapboxMap.addMarker(generateCityStateMarker("Luxembourg", 49.815273, 6.129583, "#3F51B5"));
+ mapboxMap.addMarker(generateCityStateMarker("Monaco", 43.738418, 7.424616, "#673AB7"));
+ mapboxMap.addMarker(generateCityStateMarker("Vatican City", 41.902916, 12.453389, "#009688"));
+ mapboxMap.addMarker(generateCityStateMarker("San Marino", 43.942360, 12.457777, "#795548"));
+ mapboxMap.addMarker(generateCityStateMarker("Liechtenstein", 47.166000, 9.555373, "#FF5722"));
+ }
+
+ private CityStateMarkerOptions generateCityStateMarker(String title, double lat, double lng, String color) {
+ CityStateMarkerOptions marker = new CityStateMarkerOptions();
+ marker.title(title);
+ marker.position(new LatLng(lat, lng));
+ marker.infoWindowBackground(color);
+
+ iconDrawable.setColorFilter(Color.parseColor(color), PorterDuff.Mode.SRC_IN);
+ Icon icon = iconFactory.fromDrawable(iconDrawable);
+ marker.icon(icon);
+ return marker;
+ }
+
+ private void addCustomInfoWindowAdapter() {
+ mapboxMap.setInfoWindowAdapter(new MapboxMap.InfoWindowAdapter() {
+
+ private int tenDp = (int) getResources().getDimension(R.dimen.attr_margin);
+
+ @Override
+ public View getInfoWindow(@NonNull Marker marker) {
+ TextView textView = new TextView(InfoWindowAdapterActivity.this);
+ textView.setText(marker.getTitle());
+ textView.setTextColor(Color.WHITE);
+
+ if (marker instanceof CityStateMarker) {
+ CityStateMarker cityStateMarker = (CityStateMarker) marker;
+ textView.setBackgroundColor(Color.parseColor(cityStateMarker.getInfoWindowBackgroundColor()));
}
+
+ textView.setPadding(tenDp, tenDp, tenDp, tenDp);
+ return textView;
+ }
+ });
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/DebugModeActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/DebugModeActivity.java
index 377d5d18f0..5c9d927e9b 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/DebugModeActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/DebugModeActivity.java
@@ -6,7 +6,9 @@ import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
-import android.util.Log;
+
+import timber.log.Timber;
+
import android.view.MenuItem;
import android.view.View;
@@ -18,113 +20,123 @@ import com.mapbox.mapboxsdk.testapp.R;
public class DebugModeActivity extends AppCompatActivity {
- private static final String TAG = "DebugModeActivity";
-
- private MapView mapView;
- private MapboxMap mapboxMap;
+ private MapView mapView;
+ private MapboxMap mapboxMap;
- private int currentStyleIndex = 0;
+ private int currentStyleIndex = 0;
- private static final String[] STYLES = new String[]{
- Style.MAPBOX_STREETS,
- Style.OUTDOORS,
- Style.LIGHT,
- Style.DARK,
- Style.SATELLITE,
- Style.SATELLITE_STREETS
- };
+ private static final String[] STYLES = new String[] {
+ Style.MAPBOX_STREETS,
+ Style.OUTDOORS,
+ Style.LIGHT,
+ Style.DARK,
+ Style.SATELLITE,
+ Style.SATELLITE_STREETS
+ };
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_debug_mode);
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_debug_mode);
- final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
-
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.setTag(true);
- mapView.setStyleUrl(STYLES[currentStyleIndex]);
- mapView.onCreate(savedInstanceState);
-
- mapView.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(@NonNull MapboxMap map) {
- mapboxMap = map;
- }
- });
-
- FloatingActionButton fabDebug = (FloatingActionButton) findViewById(R.id.fabDebug);
- fabDebug.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- if (mapboxMap != null) {
- Log.d(TAG, "Debug FAB: isDebug Active? " + mapboxMap.isDebugActive());
- mapboxMap.cycleDebugOptions();
- }
- }
- });
-
- FloatingActionButton fabStyles = (FloatingActionButton) findViewById(R.id.fabStyles);
- fabStyles.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- if (mapboxMap != null) {
- currentStyleIndex++;
- if (currentStyleIndex == STYLES.length) {
- currentStyleIndex = 0;
- }
- mapboxMap.setStyleUrl(STYLES[currentStyleIndex]);
- }
- }
- });
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
+ final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
-
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
-
- default:
- return super.onOptionsItemSelected(item);
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.setTag(true);
+ mapView.setStyleUrl(STYLES[currentStyleIndex]);
+ mapView.onCreate(savedInstanceState);
+
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(@NonNull MapboxMap map) {
+ mapboxMap = map;
+ }
+ });
+
+ FloatingActionButton fabDebug = (FloatingActionButton) findViewById(R.id.fabDebug);
+ fabDebug.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ if (mapboxMap != null) {
+ Timber.d("Debug FAB: isDebug Active? " + mapboxMap.isDebugActive());
+ mapboxMap.cycleDebugOptions();
+ }
+ }
+ });
+
+ FloatingActionButton fabStyles = (FloatingActionButton) findViewById(R.id.fabStyles);
+ fabStyles.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ if (mapboxMap != null) {
+ currentStyleIndex++;
+ if (currentStyleIndex == STYLES.length) {
+ currentStyleIndex = 0;
+ }
+ mapboxMap.setStyleUrl(STYLES[currentStyleIndex]);
}
+ }
+ });
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/DoubleMapActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/DoubleMapActivity.java
index b34962a792..5cb340bdd3 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/DoubleMapActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/DoubleMapActivity.java
@@ -28,165 +28,165 @@ import com.mapbox.mapboxsdk.testapp.R;
public class DoubleMapActivity extends AppCompatActivity {
- private static final String TAG_FRAGMENT = "map";
+ private static final String TAG_FRAGMENT = "map";
- // used for ui tests
- private MapboxMap mapboxMap;
+ // used for ui tests
+ private MapboxMap mapboxMap;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_map_fragment);
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_map_fragment);
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
+ }
- Fragment mapFragment;
- if (savedInstanceState == null) {
- FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
- transaction.add(R.id.fragment_container, mapFragment = new DoubleMapFragment(), TAG_FRAGMENT);
- transaction.commit();
- } else {
- mapFragment = (DoubleMapFragment) getSupportFragmentManager().findFragmentByTag(TAG_FRAGMENT);
- }
+ Fragment mapFragment;
+ if (savedInstanceState == null) {
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+ transaction.add(R.id.fragment_container, mapFragment = new DoubleMapFragment(), TAG_FRAGMENT);
+ transaction.commit();
+ } else {
+ mapFragment = (DoubleMapFragment) getSupportFragmentManager().findFragmentByTag(TAG_FRAGMENT);
+ }
+ }
+
+ public void setMapboxMap(MapboxMap map) {
+ // we need to set mapboxmap on the parent activity,
+ // for auto-generated ui tests
+
+ mapboxMap = map;
+ mapboxMap.setStyleUrl(Style.DARK);
+ mapboxMap.moveCamera(CameraUpdateFactory.zoomTo(18));
+ try {
+ TrackingSettings settings = mapboxMap.getTrackingSettings();
+ settings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW);
+ } catch (SecurityException securityException) {
+ // permission is handled in MainActivity
+ finish();
}
+ }
- public void setMapboxMap(MapboxMap map) {
- // we need to set mapboxmap on the parent activity,
- // for auto-generated ui tests
+ public static class DoubleMapFragment extends Fragment {
- mapboxMap = map;
- mapboxMap.setStyleUrl(Style.DARK);
- mapboxMap.moveCamera(CameraUpdateFactory.zoomTo(18));
- try {
- TrackingSettings settings = mapboxMap.getTrackingSettings();
- settings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW);
- } catch (SecurityException securityException) {
- // permission is handled in MainActivity
- finish();
- }
+ private DoubleMapActivity activity;
+ private MapView mapView;
+ private MapView mapViewMini;
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ activity = (DoubleMapActivity) context;
}
- public static class DoubleMapFragment extends Fragment {
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.fragment_double_map, container, false);
+ }
- private DoubleMapActivity activity;
- private MapView mapView;
- private MapView mapViewMini;
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ // MapView large
+ mapView = (MapView) view.findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(new OnMapReadyCallback() {
@Override
- public void onAttach(Context context) {
- super.onAttach(context);
- activity = (DoubleMapActivity) context;
+ public void onMapReady(@NonNull MapboxMap mapboxMap) {
+ if (activity != null) {
+ activity.setMapboxMap(mapboxMap);
+ }
}
+ });
+ // MapView mini
+ mapViewMini = (MapView) view.findViewById(R.id.mini_map);
+ mapViewMini.onCreate(savedInstanceState);
+ mapViewMini.getMapAsync(new OnMapReadyCallback() {
@Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- return inflater.inflate(R.layout.fragment_double_map, container, false);
- }
+ public void onMapReady(@NonNull MapboxMap mapboxMap) {
+ mapboxMap.setStyleUrl(Style.LIGHT);
+ mapboxMap.moveCamera(CameraUpdateFactory.zoomTo(4));
- @Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
-
- // MapView large
- mapView = (MapView) view.findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(@NonNull MapboxMap mapboxMap) {
- if (activity != null) {
- activity.setMapboxMap(mapboxMap);
- }
- }
- });
-
- // MapView mini
- mapViewMini = (MapView) view.findViewById(R.id.mini_map);
- mapViewMini.onCreate(savedInstanceState);
- mapViewMini.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(@NonNull MapboxMap mapboxMap) {
- mapboxMap.setStyleUrl(Style.LIGHT);
- mapboxMap.moveCamera(CameraUpdateFactory.zoomTo(4));
-
- UiSettings uiSettings = mapboxMap.getUiSettings();
- uiSettings.setAllGesturesEnabled(false);
- uiSettings.setCompassEnabled(false);
- uiSettings.setAttributionEnabled(false);
- uiSettings.setLogoEnabled(false);
-
- try {
- TrackingSettings settings = mapboxMap.getTrackingSettings();
- settings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW);
- } catch (SecurityException securityException) {
- // permission is handled in MainActivity
- getActivity().finish();
- }
-
- mapboxMap.setOnMapClickListener(new MapboxMap.OnMapClickListener() {
- @Override
- public void onMapClick(@NonNull LatLng point) {
- // test if we can open 2 activities after each other
- startActivity(new Intent(mapViewMini.getContext(), DoubleMapActivity.class));
- }
- });
- }
- });
-
- SurfaceView surfaceViewMini = (SurfaceView) mapViewMini.findViewById(R.id.surfaceView);
- surfaceViewMini.setZOrderMediaOverlay(true);
- }
+ UiSettings uiSettings = mapboxMap.getUiSettings();
+ uiSettings.setAllGesturesEnabled(false);
+ uiSettings.setCompassEnabled(false);
+ uiSettings.setAttributionEnabled(false);
+ uiSettings.setLogoEnabled(false);
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- mapViewMini.onResume();
+ try {
+ TrackingSettings settings = mapboxMap.getTrackingSettings();
+ settings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW);
+ } catch (SecurityException securityException) {
+ // permission is handled in MainActivity
+ getActivity().finish();
+ }
+
+ mapboxMap.setOnMapClickListener(new MapboxMap.OnMapClickListener() {
+ @Override
+ public void onMapClick(@NonNull LatLng point) {
+ // test if we can open 2 activities after each other
+ startActivity(new Intent(mapViewMini.getContext(), DoubleMapActivity.class));
+ }
+ });
}
+ });
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
- mapViewMini.onPause();
- }
+ SurfaceView surfaceViewMini = (SurfaceView) mapViewMini.findViewById(R.id.surfaceView);
+ surfaceViewMini.setZOrderMediaOverlay(true);
+ }
- @Override
- public void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- mapViewMini.onDestroy();
- }
+ @Override
+ public void onResume() {
+ super.onResume();
+ mapView.onResume();
+ mapViewMini.onResume();
+ }
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
- mapViewMini.onLowMemory();
- }
+ @Override
+ public void onPause() {
+ super.onPause();
+ mapView.onPause();
+ mapViewMini.onPause();
+ }
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- mapViewMini.onSaveInstanceState(outState);
- }
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ mapViewMini.onDestroy();
}
@Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ mapViewMini.onLowMemory();
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ mapViewMini.onSaveInstanceState(outState);
+ }
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/MapInDialogActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/MapInDialogActivity.java
index 3df236f43c..ed3f315e06 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/MapInDialogActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/MapInDialogActivity.java
@@ -14,103 +14,114 @@ import android.view.ViewGroup;
import android.widget.Button;
import com.mapbox.mapboxsdk.maps.MapView;
-import com.mapbox.mapboxsdk.maps.MapboxMap;
-import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.testapp.R;
public class MapInDialogActivity extends AppCompatActivity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_map_in_dialog);
+
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
+ }
+
+ Button button = (Button) findViewById(R.id.button_open_dialog);
+ button.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ FragmentManager fm = getSupportFragmentManager();
+ MapDialogFragment editNameDialogFragment = MapDialogFragment.newInstance("Map Dialog");
+ editNameDialogFragment.show(fm, "fragment_dialog_map");
+ }
+ });
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+ }
+
+ public static class MapDialogFragment extends DialogFragment {
+
+ private MapView mapView;
+
+ public MapDialogFragment() {
+ }
+
+ public static MapDialogFragment newInstance(String title) {
+ MapDialogFragment frag = new MapDialogFragment();
+ Bundle args = new Bundle();
+ args.putString("title", title);
+ frag.setArguments(args);
+ return frag;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.fragment_dialog_map, container);
+ }
+
+ @Override
+ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+
+ mapView = (MapView) view.findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
@Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_map_in_dialog);
-
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
-
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- Button button = (Button) findViewById(R.id.button_open_dialog);
- button.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- FragmentManager fm = getSupportFragmentManager();
- MapDialogFragment editNameDialogFragment = MapDialogFragment.newInstance("Map Dialog");
- editNameDialogFragment.show(fm, "fragment_dialog_map");
- }
- });
+ public void onStop() {
+ super.onStop();
+ mapView.onStop();
}
@Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
+ public void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
}
- public static class MapDialogFragment extends DialogFragment {
-
- private MapView mapView;
-
- public MapDialogFragment() {}
-
- public static MapDialogFragment newInstance(String title) {
- MapDialogFragment frag = new MapDialogFragment();
- Bundle args = new Bundle();
- args.putString("title", title);
- frag.setArguments(args);
- return frag;
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- return inflater.inflate(R.layout.fragment_dialog_map, container);
- }
-
- @Override
- public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
-
- mapView = (MapView) view.findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
-
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
- }
-
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- }
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
}
+ }
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/MapPaddingActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/MapPaddingActivity.java
index 114262220a..90b91057ed 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/MapPaddingActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/MapPaddingActivity.java
@@ -21,131 +21,143 @@ import com.mapbox.mapboxsdk.testapp.R;
public class MapPaddingActivity extends AppCompatActivity {
- private MapView mapView;
- private MapboxMap mapboxMap;
+ private MapView mapView;
+ private MapboxMap mapboxMap;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_map_padding);
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_map_padding);
- final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
+ final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.setTag(true);
- mapView.onCreate(savedInstanceState);
-
- mapView.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(@NonNull MapboxMap mapboxMap) {
- MapPaddingActivity.this.mapboxMap = mapboxMap;
-
- int paddingLeft = (int) getResources().getDimension(R.dimen.map_padding_left);
- int paddingBottom = (int) getResources().getDimension(R.dimen.map_padding_bottom);
- int paddingRight = (int) getResources().getDimension(R.dimen.map_padding_right);
- mapboxMap.setPadding(paddingLeft, toolbar.getHeight(), paddingRight, paddingBottom);
-
- moveToBangalore();
- }
- });
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.setTag(true);
+ mapView.onCreate(savedInstanceState);
+
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(@NonNull MapboxMap mapboxMap) {
+ MapPaddingActivity.this.mapboxMap = mapboxMap;
+
+ int paddingLeft = (int) getResources().getDimension(R.dimen.map_padding_left);
+ int paddingBottom = (int) getResources().getDimension(R.dimen.map_padding_bottom);
+ int paddingRight = (int) getResources().getDimension(R.dimen.map_padding_right);
+ mapboxMap.setPadding(paddingLeft, toolbar.getHeight(), paddingRight, paddingBottom);
+
+ moveToBangalore();
+ }
+ });
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.menu_padding, menu);
+ return true;
+ }
+
+ private void toggleGps(boolean enable) {
+ try {
+ // Enable user location
+ mapboxMap.setMyLocationEnabled(enable);
+
+ TrackingSettings trackingSettings = mapboxMap.getTrackingSettings();
+ trackingSettings.setDismissLocationTrackingOnGesture(false);
+ trackingSettings.setMyLocationTrackingMode(
+ enable ? MyLocationTracking.TRACKING_FOLLOW : MyLocationTracking.TRACKING_NONE);
+ } catch (SecurityException securityException) {
+ // permission not granted is handled in FeatureOverviewActivity
+ finish();
}
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
-
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.menu_padding, menu);
+ }
+
+ private void moveToBangalore() {
+ toggleGps(false);
+
+ LatLng bangalore = new LatLng(12.9810816, 77.6368034);
+ CameraPosition cameraPosition = new CameraPosition.Builder()
+ .zoom(16)
+ .target(bangalore)
+ .bearing(40)
+ .tilt(45)
+ .build();
+
+ mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
+ mapboxMap.addMarker(new MarkerOptions().title("Center map").position(bangalore));
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
return true;
- }
- private void toggleGps(boolean enable) {
- try {
- // Enable user location
- mapboxMap.setMyLocationEnabled(enable);
-
- TrackingSettings trackingSettings = mapboxMap.getTrackingSettings();
- trackingSettings.setDismissTrackingOnGesture(false);
- trackingSettings.setMyLocationTrackingMode(
- enable ? MyLocationTracking.TRACKING_FOLLOW : MyLocationTracking.TRACKING_NONE);
- } catch (SecurityException securityException) {
- // permission not granted is handled in FeatureOverviewActivity
- finish();
+ case R.id.action_user_tracking:
+ if (mapboxMap != null) {
+ toggleGps(true);
}
- }
-
- private void moveToBangalore() {
- toggleGps(false);
-
- LatLng bangalore = new LatLng(12.9810816, 77.6368034);
- CameraPosition cameraPosition = new CameraPosition.Builder()
- .zoom(16)
- .target(bangalore)
- .bearing(40)
- .tilt(45)
- .build();
-
- mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
- mapboxMap.addMarker(new MarkerOptions().title("Center map").position(bangalore));
- }
+ return true;
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
-
- case R.id.action_user_tracking:
- if (mapboxMap != null) {
- toggleGps(true);
- }
- return true;
-
- case R.id.action_bangalore:
- if (mapboxMap != null) {
- moveToBangalore();
- }
- return true;
-
- default:
- return super.onOptionsItemSelected(item);
+ case R.id.action_bangalore:
+ if (mapboxMap != null) {
+ moveToBangalore();
}
+ return true;
+
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/NavigationDrawerActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/NavigationDrawerActivity.java
index 76363ef808..7f59dd3bdb 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/NavigationDrawerActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/NavigationDrawerActivity.java
@@ -32,221 +32,221 @@ import com.mapbox.mapboxsdk.testapp.R;
public class NavigationDrawerActivity extends AppCompatActivity {
- private boolean firstStyle = true;
- private MapboxMap mapboxMap;
+ private boolean firstStyle = true;
+ private MapboxMap mapboxMap;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_navigation_drawer);
+
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+
+ NavigationDrawerFragment navigationDrawerFragment;
+
+ getFragmentManager()
+ .beginTransaction()
+ .add(R.id.navigation_drawer, navigationDrawerFragment = new NavigationDrawerFragment())
+ .commit();
+
+ navigationDrawerFragment.setUp(this,
+ R.id.navigation_drawer,
+ (DrawerLayout) findViewById(R.id.drawer_layout),
+ getSupportActionBar());
+ }
+
+ public void onNavigationDrawerItemSelected(int position) {
+ // update the main content by replacing fragments
+ switch (position) {
+ case 0:
+ // options
+ MapboxMapOptions options = new MapboxMapOptions();
+ options.styleUrl(firstStyle ? Style.LIGHT : Style.SATELLITE);
+ options.camera(new CameraPosition.Builder()
+ .target(new LatLng(39.913271, 116.413891))
+ .zoom(12)
+ .build());
+
+ // fragment
+ MapFragment mapFragment = MapFragment.newInstance(options);
+ FragmentManager fragmentManager = getFragmentManager();
+ fragmentManager.beginTransaction()
+ .replace(R.id.container, mapFragment)
+ .commit();
+
+ // get callback when map is ready
+ mapFragment.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(MapboxMap map) {
+ mapboxMap = map;
+ }
+ });
+
+ firstStyle = !firstStyle;
+ break;
+ case 1:
+ Snackbar.make(
+ findViewById(android.R.id.content),
+ "Hello from snackbar",
+ Snackbar.LENGTH_LONG)
+ .show();
+ break;
+ }
+ }
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_navigation_drawer);
+ public static class NavigationDrawerFragment extends Fragment {
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
+ private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position";
+ private static final String PREF_USER_LEARNED_DRAWER = "navigation_drawer_learned";
- NavigationDrawerFragment navigationDrawerFragment;
+ private ActionBarDrawerToggle drawerToggle;
- getFragmentManager()
- .beginTransaction()
- .add(R.id.navigation_drawer, navigationDrawerFragment = new NavigationDrawerFragment())
- .commit();
+ private DrawerLayout drawerLayout;
+ private ListView drawerListView;
+ private View fragmentContainerView;
- navigationDrawerFragment.setUp(this,
- R.id.navigation_drawer,
- (DrawerLayout) findViewById(R.id.drawer_layout),
- getSupportActionBar());
- }
+ private int currentSelectedPosition = 0;
+ private boolean fromSavedInstanceState;
+ private boolean userLearnedDrawer;
- public void onNavigationDrawerItemSelected(int position) {
- // update the main content by replacing fragments
- switch (position) {
- case 0:
- // options
- MapboxMapOptions options = new MapboxMapOptions();
- options.styleUrl(firstStyle ? Style.LIGHT : Style.SATELLITE);
- options.camera(new CameraPosition.Builder()
- .target(new LatLng(39.913271, 116.413891))
- .zoom(12)
- .build());
-
- // fragment
- MapFragment mapFragment = MapFragment.newInstance(options);
- FragmentManager fragmentManager = getFragmentManager();
- fragmentManager.beginTransaction()
- .replace(R.id.container, mapFragment)
- .commit();
-
- // get callback when map is ready
- mapFragment.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(MapboxMap map) {
- mapboxMap = map;
- }
- });
-
- firstStyle = !firstStyle;
- break;
- case 1:
- Snackbar.make(
- findViewById(android.R.id.content),
- "Hello from snackbar",
- Snackbar.LENGTH_LONG)
- .show();
- break;
- }
+ public NavigationDrawerFragment() {
}
- public static class NavigationDrawerFragment extends Fragment {
-
- private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position";
- private static final String PREF_USER_LEARNED_DRAWER = "navigation_drawer_learned";
-
- private ActionBarDrawerToggle drawerToggle;
-
- private DrawerLayout drawerLayout;
- private ListView drawerListView;
- private View fragmentContainerView;
-
- private int currentSelectedPosition = 0;
- private boolean fromSavedInstanceState;
- private boolean userLearnedDrawer;
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
+ userLearnedDrawer = sp.getBoolean(PREF_USER_LEARNED_DRAWER, false);
+
+ if (savedInstanceState != null) {
+ currentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION);
+ fromSavedInstanceState = true;
+ }
+ selectItem(currentSelectedPosition);
+ }
- public NavigationDrawerFragment() {
- }
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ setHasOptionsMenu(true);
+ }
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ drawerListView = (ListView) inflater.inflate(
+ R.layout.drawer_navigation_drawer, container, false);
+ drawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
- userLearnedDrawer = sp.getBoolean(PREF_USER_LEARNED_DRAWER, false);
-
- if (savedInstanceState != null) {
- currentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION);
- fromSavedInstanceState = true;
- }
- selectItem(currentSelectedPosition);
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ selectItem(position);
}
+ });
+ drawerListView.setAdapter(new ArrayAdapter<>(
+ inflater.getContext(),
+ android.R.layout.simple_list_item_activated_1,
+ android.R.id.text1,
+ new String[] {
+ getString(R.string.title_section1),
+ getString(R.string.title_section2)
+ }));
+ drawerListView.setItemChecked(currentSelectedPosition, true);
+ return drawerListView;
+ }
+ /**
+ * Users of this fragment must call this method to set up the navigation drawer interactions.
+ *
+ * @param fragmentId The android:id of this fragment in its activity's layout.
+ * @param drawerLayout The DrawerLayout containing this fragment's UI.
+ */
+ public void setUp(Activity activity, int fragmentId, DrawerLayout drawerLayout, ActionBar actionBar) {
+ fragmentContainerView = activity.findViewById(fragmentId);
+ this.drawerLayout = drawerLayout;
+ // drawerLayout.setScrimColor(Color.TRANSPARENT);
+
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setHomeButtonEnabled(true);
+
+ drawerToggle = new ActionBarDrawerToggle(
+ activity,
+ NavigationDrawerFragment.this.drawerLayout,
+ R.string.navigation_drawer_open,
+ R.string.navigation_drawer_close
+ ) {
@Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- setHasOptionsMenu(true);
+ public void onDrawerClosed(View drawerView) {
+ super.onDrawerClosed(drawerView);
+ if (!isAdded()) {
+ return;
+ }
+ getActivity().invalidateOptionsMenu();
}
@Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- drawerListView = (ListView) inflater.inflate(
- R.layout.drawer_navigation_drawer, container, false);
- drawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- selectItem(position);
- }
- });
- drawerListView.setAdapter(new ArrayAdapter<>(
- inflater.getContext(),
- android.R.layout.simple_list_item_activated_1,
- android.R.id.text1,
- new String[]{
- getString(R.string.title_section1),
- getString(R.string.title_section2)
- }));
- drawerListView.setItemChecked(currentSelectedPosition, true);
- return drawerListView;
+ public void onDrawerOpened(View drawerView) {
+ super.onDrawerOpened(drawerView);
+ if (!isAdded()) {
+ return;
+ }
+
+ if (!userLearnedDrawer) {
+ userLearnedDrawer = true;
+ SharedPreferences sp = PreferenceManager
+ .getDefaultSharedPreferences(getActivity());
+ sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).apply();
+ }
+ getActivity().invalidateOptionsMenu();
}
+ };
- /**
- * Users of this fragment must call this method to set up the navigation drawer interactions.
- *
- * @param fragmentId The android:id of this fragment in its activity's layout.
- * @param drawerLayout The DrawerLayout containing this fragment's UI.
- */
- public void setUp(Activity activity, int fragmentId, DrawerLayout drawerLayout, ActionBar actionBar) {
- fragmentContainerView = activity.findViewById(fragmentId);
- this.drawerLayout = drawerLayout;
- // drawerLayout.setScrimColor(Color.TRANSPARENT);
-
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setHomeButtonEnabled(true);
-
- drawerToggle = new ActionBarDrawerToggle(
- activity,
- NavigationDrawerFragment.this.drawerLayout,
- R.string.navigation_drawer_open,
- R.string.navigation_drawer_close
- ) {
- @Override
- public void onDrawerClosed(View drawerView) {
- super.onDrawerClosed(drawerView);
- if (!isAdded()) {
- return;
- }
- getActivity().invalidateOptionsMenu();
- }
-
- @Override
- public void onDrawerOpened(View drawerView) {
- super.onDrawerOpened(drawerView);
- if (!isAdded()) {
- return;
- }
-
- if (!userLearnedDrawer) {
- userLearnedDrawer = true;
- SharedPreferences sp = PreferenceManager
- .getDefaultSharedPreferences(getActivity());
- sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).apply();
- }
- getActivity().invalidateOptionsMenu();
- }
- };
-
- if (!userLearnedDrawer && !fromSavedInstanceState) {
- this.drawerLayout.openDrawer(fragmentContainerView);
- }
- this.drawerLayout.post(new Runnable() {
- @Override
- public void run() {
- drawerToggle.syncState();
- }
- });
- this.drawerLayout.setDrawerListener(drawerToggle);
+ if (!userLearnedDrawer && !fromSavedInstanceState) {
+ this.drawerLayout.openDrawer(fragmentContainerView);
+ }
+ this.drawerLayout.post(new Runnable() {
+ @Override
+ public void run() {
+ drawerToggle.syncState();
}
+ });
+ this.drawerLayout.setDrawerListener(drawerToggle);
+ }
- private void selectItem(int position) {
- currentSelectedPosition = position;
- if (drawerListView != null) {
- drawerListView.setItemChecked(position, true);
- }
- if (drawerLayout != null) {
- drawerLayout.closeDrawer(fragmentContainerView);
- }
-
- Activity activity = getActivity();
- if (activity != null && activity instanceof NavigationDrawerActivity) {
- NavigationDrawerActivity navActivity = (NavigationDrawerActivity) activity;
- navActivity.onNavigationDrawerItemSelected(position);
- }
- }
+ private void selectItem(int position) {
+ currentSelectedPosition = position;
+ if (drawerListView != null) {
+ drawerListView.setItemChecked(position, true);
+ }
+ if (drawerLayout != null) {
+ drawerLayout.closeDrawer(fragmentContainerView);
+ }
+
+ Activity activity = getActivity();
+ if (activity != null && activity instanceof NavigationDrawerActivity) {
+ NavigationDrawerActivity navActivity = (NavigationDrawerActivity) activity;
+ navActivity.onNavigationDrawerItemSelected(position);
+ }
+ }
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- outState.putInt(STATE_SELECTED_POSITION, currentSelectedPosition);
- }
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putInt(STATE_SELECTED_POSITION, currentSelectedPosition);
+ }
- @Override
- public void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- drawerToggle.onConfigurationChanged(newConfig);
- }
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ drawerToggle.onConfigurationChanged(newConfig);
+ }
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if (drawerToggle.onOptionsItemSelected(item)) {
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (drawerToggle.onOptionsItemSelected(item)) {
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/SimpleMapActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/SimpleMapActivity.java
new file mode 100644
index 0000000000..7e04b95e20
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/SimpleMapActivity.java
@@ -0,0 +1,86 @@
+package com.mapbox.mapboxsdk.testapp.activity.maplayout;
+
+import android.os.Bundle;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.Toolbar;
+import android.view.MenuItem;
+
+import com.mapbox.mapboxsdk.maps.MapView;
+import com.mapbox.mapboxsdk.testapp.R;
+
+public class SimpleMapActivity extends AppCompatActivity {
+
+ private MapView mapView;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_map_simple);
+
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+
+ final ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
+ }
+
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @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);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/SurfaceViewMediaControlActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/SurfaceViewMediaControlActivity.java
deleted file mode 100644
index 43b4264661..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/SurfaceViewMediaControlActivity.java
+++ /dev/null
@@ -1,151 +0,0 @@
-package com.mapbox.mapboxsdk.testapp.activity.maplayout;
-
-import android.content.Context;
-import android.opengl.GLSurfaceView;
-import android.os.Bundle;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.Toolbar;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.widget.FrameLayout;
-
-import com.mapbox.mapboxsdk.maps.MapView;
-import com.mapbox.mapboxsdk.maps.MapboxMap;
-import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
-import com.mapbox.mapboxsdk.testapp.R;
-
-import javax.microedition.khronos.egl.EGLConfig;
-import javax.microedition.khronos.opengles.GL10;
-
-public class SurfaceViewMediaControlActivity extends AppCompatActivity implements OnMapReadyCallback {
-
- private MapView mapView;
- private MapboxMap mapboxMap;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_surfaceview_mediacontrols);
-
- final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
-
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(this);
-
- // add another SurfaceView to the Layout
- FrameLayout container = (FrameLayout) findViewById(R.id.container);
- GLSurfaceView mediaControlSurfaceView = new ClearGLSurfaceView(this);
- mediaControlSurfaceView.setZOrderMediaOverlay(true);
- container.addView(mediaControlSurfaceView);
- }
-
- @Override
- public void onMapReady(MapboxMap mapboxMap) {
- this.mapboxMap = mapboxMap;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
-
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.menu_padding, menu);
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
- }
-
- class ClearGLSurfaceView extends GLSurfaceView {
-
- private ClearRenderer renderer;
-
- public ClearGLSurfaceView(Context context) {
- super(context);
- renderer = new ClearRenderer();
- setRenderer(renderer);
- }
-
- public boolean onTouchEvent(final MotionEvent event) {
- queueEvent(new Runnable() {
- public void run() {
- renderer.setColor(event.getRawX() / getWidth(),
- event.getRawY() / getHeight(), 1.0f);
- }
- });
- return true;
- }
- }
-
- class ClearRenderer implements GLSurfaceView.Renderer {
-
- private float red;
- private float green;
- private float blue;
-
- public void onSurfaceCreated(GL10 gl, EGLConfig config) {
- // Do nothing special.
- }
-
- public void onSurfaceChanged(GL10 gl, int width, int height) {
- gl.glViewport(0, 0, width, height);
- }
-
- public void onDrawFrame(GL10 gl) {
- gl.glClearColor(red, green, blue, 1.0f);
- gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
- }
-
- public void setColor(float red, float green, float blue) {
- this.red = red;
- this.green = green;
- this.blue = blue;
- }
- }
-}
-
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/VideoViewActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/VideoViewActivity.java
deleted file mode 100644
index 96637fae87..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/VideoViewActivity.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package com.mapbox.mapboxsdk.testapp.activity.maplayout;
-
-import android.media.MediaPlayer;
-import android.net.Uri;
-import android.os.Bundle;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.Toolbar;
-import android.view.MenuItem;
-import android.widget.VideoView;
-
-import com.mapbox.mapboxsdk.maps.MapView;
-import com.mapbox.mapboxsdk.maps.MapboxMap;
-import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
-import com.mapbox.mapboxsdk.testapp.R;
-
-import static android.media.MediaPlayer.OnPreparedListener;
-
-public class VideoViewActivity extends AppCompatActivity {
-
- private MapView mapView;
- private MapboxMap mapboxMap;
- private VideoView videoView;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_video_view);
-
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
-
- final ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- // Setup the video
- videoView = (VideoView) findViewById(R.id.video_view);
- videoView.setVideoURI(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.sea_waves));
- videoView.start();
-
- // Used to repeat the video.
- videoView.setOnPreparedListener(new OnPreparedListener() {
- @Override
- public void onPrepared(MediaPlayer mediaPlayer) {
- mediaPlayer.setLooping(true);
- }
- });
-
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(MapboxMap mapboxMap) {
- VideoViewActivity.this.mapboxMap = mapboxMap;
- }
- });
- }
-
- @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);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/navigation/CarDrivingActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/navigation/CarDrivingActivity.java
index a40ec0534c..4bb6bc5f39 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/navigation/CarDrivingActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/navigation/CarDrivingActivity.java
@@ -32,158 +32,170 @@ import com.mapbox.mapboxsdk.testapp.R;
public class CarDrivingActivity extends AppCompatActivity implements MapboxMap.OnMyLocationChangeListener {
- private static final int PERMISSIONS_LOCATION = 0;
+ private static final int PERMISSIONS_LOCATION = 0;
- private MapView mapView;
- private MapboxMap mapboxMap;
- private Location location;
+ private MapView mapView;
+ private MapboxMap mapboxMap;
+ private Location location;
- @Override
- protected void onCreate(final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_car_driving);
+ @Override
+ protected void onCreate(final Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_car_driving);
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- final ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(@NonNull MapboxMap mapboxMap) {
- CarDrivingActivity.this.mapboxMap = mapboxMap;
-
- // view settings
- MyLocationViewSettings settings = mapboxMap.getMyLocationViewSettings();
- settings.setPadding(0, getWindow().getDecorView().getMeasuredHeight() / 3, 0, 0);
-
- // get car
- Drawable car = ResourcesCompat.getDrawable(getResources(), R.drawable.ic_taxi_top_small, getTheme());
- settings.setForegroundTintColor(Color.TRANSPARENT);
- settings.setForegroundDrawable(car, car);
-
- // remove accuracy circle
- settings.setAccuracyAlpha(0);
-
- // disable dismissal when a gesture occurs
- TrackingSettings trackingSettings = mapboxMap.getTrackingSettings();
- trackingSettings.setDismissLocationTrackingOnGesture(false);
- trackingSettings.setDismissBearingTrackingOnGesture(false);
-
- mapboxMap.setOnMyLocationChangeListener(CarDrivingActivity.this);
-
- if (savedInstanceState == null) {
- toggleGps(true);
- }
- }
- });
+ final ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
- @UiThread
- public void toggleGps(boolean enableGps) {
- if (enableGps) {
- if ((ContextCompat.checkSelfPermission(this,
- Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
- || (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
- != PackageManager.PERMISSION_GRANTED)) {
- ActivityCompat.requestPermissions(this, new String[]{
- Manifest.permission.ACCESS_COARSE_LOCATION,
- Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_LOCATION);
- } else {
- enableLocation(true);
- }
- } else {
- enableLocation(false);
- }
- }
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(@NonNull MapboxMap mapboxMap) {
+ CarDrivingActivity.this.mapboxMap = mapboxMap;
- private void enableLocation(boolean enabled) {
- if (enabled) {
- mapboxMap.setMyLocationEnabled(true);
- Location location = mapboxMap.getMyLocation();
- if (location != null) {
- setInitialPosition(new LatLng(location));
- }
- } else {
- mapboxMap.setMyLocationEnabled(false);
- }
- }
+ // view settings
+ MyLocationViewSettings settings = mapboxMap.getMyLocationViewSettings();
+ settings.setPadding(0, getWindow().getDecorView().getMeasuredHeight() / 3, 0, 0);
- @Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
- if (requestCode == PERMISSIONS_LOCATION) {
- if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
- enableLocation(true);
- }
- }
- }
+ // get car
+ Drawable car = ResourcesCompat.getDrawable(getResources(), R.drawable.ic_taxi_top_small, getTheme());
+ settings.setForegroundTintColor(Color.TRANSPARENT);
+ settings.setForegroundDrawable(car, car);
- private void setInitialPosition(LatLng latLng) {
- mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(
- new CameraPosition.Builder().target(latLng).zoom(15).tilt(20f).build()));
- mapboxMap.setMyLocationEnabled(true);
+ // remove accuracy circle
+ settings.setAccuracyAlpha(0);
+ // disable dismissal when a gesture occurs
TrackingSettings trackingSettings = mapboxMap.getTrackingSettings();
- trackingSettings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW);
- trackingSettings.setMyBearingTrackingMode(MyBearingTracking.GPS);
- }
+ trackingSettings.setDismissLocationTrackingOnGesture(false);
+ trackingSettings.setDismissBearingTrackingOnGesture(false);
- @Override
- public void onMyLocationChange(@Nullable Location location) {
- if (location != null) {
- if (this.location == null) {
- // initial location to reposition map
- setInitialPosition(new LatLng(location));
- }
- this.location = location;
- }
- }
+ mapboxMap.setOnMyLocationChangeListener(CarDrivingActivity.this);
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
+ if (savedInstanceState == null) {
+ toggleGps(true);
+ }
+ }
+ });
+ }
+
+ @UiThread
+ public void toggleGps(boolean enableGps) {
+ if (enableGps) {
+ if ((ContextCompat.checkSelfPermission(this,
+ Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
+ || (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
+ != PackageManager.PERMISSION_GRANTED)) {
+ ActivityCompat.requestPermissions(this, new String[] {
+ Manifest.permission.ACCESS_COARSE_LOCATION,
+ Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_LOCATION);
+ } else {
+ enableLocation(true);
+ }
+ } else {
+ enableLocation(false);
}
-
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
+ }
+
+ private void enableLocation(boolean enabled) {
+ if (enabled) {
+ mapboxMap.setMyLocationEnabled(true);
+ Location location = mapboxMap.getMyLocation();
+ if (location != null) {
+ setInitialPosition(new LatLng(location));
+ }
+ } else {
+ mapboxMap.setMyLocationEnabled(false);
}
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+ if (requestCode == PERMISSIONS_LOCATION) {
+ if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ enableLocation(true);
+ }
}
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
+ }
+
+ private void setInitialPosition(LatLng latLng) {
+ mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(
+ new CameraPosition.Builder().target(latLng).zoom(15).tilt(20f).build()));
+ mapboxMap.setMyLocationEnabled(true);
+
+ TrackingSettings trackingSettings = mapboxMap.getTrackingSettings();
+ trackingSettings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW);
+ trackingSettings.setMyBearingTrackingMode(MyBearingTracking.GPS);
+ }
+
+ @Override
+ public void onMyLocationChange(@Nullable Location location) {
+ if (location != null) {
+ if (this.location == null) {
+ // initial location to reposition map
+ setInitialPosition(new LatLng(location));
+ }
+ this.location = location;
}
-
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/navigation/LocationPickerActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/navigation/LocationPickerActivity.java
index be5498babb..bb6b28393e 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/navigation/LocationPickerActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/navigation/LocationPickerActivity.java
@@ -14,7 +14,9 @@ import android.support.v4.app.ActivityCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
-import android.util.Log;
+
+import timber.log.Timber;
+
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MenuItem;
@@ -59,412 +61,417 @@ import retrofit2.Response;
* Sample Activity to show a typical location picker use case
*/
public class LocationPickerActivity extends AppCompatActivity {
- private static final String TAG = "LocationPickerActivity";
- private static final int REQUEST_PERMISSIONS = 101;
-
- private MapView mapView;
- private MapboxMap mapboxMap;
-
- private ImageView dropPinView;
- private Marker addressPin;
- private ImageButton clearDisplayViewButton;
- private MarkerView userMarker;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_location_picker);
-
- setupActionBar();
-
- //Initialize map as normal
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
-
- //Create ui elements
- createDropPin();
- createSelectLocationButton();
- createClearSelectionButton();
-
- mapView.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(MapboxMap map) {
- //Store for later
- mapboxMap = map;
-
- //Add user marker
- mapboxMap.getMarkerViewManager().addMarkerViewAdapter(
- new PulseMarkerViewAdapter(LocationPickerActivity.this));
- userMarker = createCustomUserMarker(new LatLng(0, 0));
-
- //Fix the focal point to the center of the map
- PointF focalPoint = new PointF(
- (mapView.getX() + mapView.getWidth() / 2), (mapView.getY() + mapView.getHeight() / 2));
- mapboxMap.getUiSettings().setFocalPoint(focalPoint);
-
- //Track camera updates to animate the user location views
- trackUserLocationView(userMarker);
- }
- });
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
-
- //Check permissions
- if (arePermissionsGranted()) {
- mapView.getMapAsync(new OnMapReadyCallback() {
-
- @Override
- public void onMapReady(final MapboxMap mapboxMap) {
- //Get the user's location
- final LocationServices locationServices = LocationServices.getLocationServices(getApplicationContext());
-
- Location location = locationServices.getLastLocation();
- if (location != null) {
- zoomInOn(location);
- userMarker.setPosition(new LatLng(location));
- } else {
- final ProgressDialog loadingDialog = ProgressDialog.show(
- LocationPickerActivity.this, "Loading", "Getting user location", false);
- locationServices.addLocationListener(new LocationListener() {
- @Override
- public void onLocationChanged(@Nullable Location location) {
- //Move the camera to the user
- if (location != null) {
- zoomInOn(location);
- userMarker.setPosition(new LatLng(location));
- locationServices.removeLocationListener(this);
- loadingDialog.hide();
- }
- }
- });
- }
-
- locationServices.toggleGPS(true);
- }
- });
- }
+ private static final int REQUEST_PERMISSIONS = 101;
+
+ private MapView mapView;
+ private MapboxMap mapboxMap;
+
+ private ImageView dropPinView;
+ private Marker addressPin;
+ private ImageButton clearDisplayViewButton;
+ private MarkerView userMarker;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_location_picker);
+
+ setupActionBar();
+
+ //Initialize map as normal
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+
+ //Create ui elements
+ createDropPin();
+ createSelectLocationButton();
+ createClearSelectionButton();
+
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(MapboxMap map) {
+ //Store for later
+ mapboxMap = map;
+
+ //Add user marker
+ mapboxMap.getMarkerViewManager().addMarkerViewAdapter(
+ new PulseMarkerViewAdapter(LocationPickerActivity.this));
+ userMarker = createCustomUserMarker(new LatLng(0, 0));
+
+ //Fix the focal point to the center of the map
+ PointF focalPoint = new PointF(
+ (mapView.getX() + mapView.getWidth() / 2), (mapView.getY() + mapView.getHeight() / 2));
+ mapboxMap.getUiSettings().setFocalPoint(focalPoint);
+
+ //Track camera updates to animate the user location views
+ trackUserLocationView(userMarker);
+ }
+ });
+ }
+
+ private void zoomInOn(Location location) {
+ //Move the camera to the user
+ if (location != null) {
+ mapboxMap.setCameraPosition(new CameraPosition.Builder()
+ .target(new LatLng(location))
+ .zoom(16)
+ .bearing(0)
+ .tilt(0)
+ .build());
}
+ }
- private void zoomInOn(Location location) {
- //Move the camera to the user
- if (location != null) {
- mapboxMap.setCameraPosition(new CameraPosition.Builder()
- .target(new LatLng(location))
- .zoom(16)
- .bearing(0)
- .tilt(0)
- .build());
- }
- }
+ /**
+ * Tracks the camera to animate the marker when overlapping with the picker.
+ * Makes sure the marker actually points to the user's position by tracking it.
+ */
+ private void trackUserLocationView(final MarkerView markerView) {
+ final float circleDiameterSize = getResources().getDimension(R.dimen.circle_size);
- /**
- * Tracks the camera to animate the marker when overlapping with the picker.
- * Makes sure the marker actually points to the user's position by tracking it.
- */
- private void trackUserLocationView(final MarkerView markerView) {
- final float circleDiameterSize = getResources().getDimension(R.dimen.circle_size);
+ //Track camera changes to check for overlap
+ mapboxMap.setOnCameraChangeListener(new MapboxMap.OnCameraChangeListener() {
- //Track camera changes to check for overlap
- mapboxMap.setOnCameraChangeListener(new MapboxMap.OnCameraChangeListener() {
+ private Animation pulseAnimation;
- private Animation pulseAnimation;
-
- @Override
- public void onCameraChange(CameraPosition position) {
- if (markerView == null) {
- return;
- }
+ @Override
+ public void onCameraChange(CameraPosition position) {
+ if (markerView == null) {
+ return;
+ }
- //Make drop pin visible, if it wasn't already
- showDropPin();
-
- //Get the distance from the tip of the location picker to the MarkerView
- double distance = getLocationPickerLocation().distanceTo(markerView.getPosition());
-
- //If closeby, animate, otherwise, stop animation
- View view = mapboxMap.getMarkerViewManager().getView(markerView);
- if (view != null) {
- View backgroundView = view.findViewById(R.id.background_imageview);
- if (pulseAnimation == null && distance < 0.5f * circleDiameterSize) {
- pulseAnimation = AnimationUtils.loadAnimation(LocationPickerActivity.this, R.anim.pulse);
- pulseAnimation.setRepeatCount(Animation.INFINITE);
- pulseAnimation.setRepeatMode(Animation.RESTART);
- backgroundView.startAnimation(pulseAnimation);
- } else if (pulseAnimation != null && distance >= 0.5f * circleDiameterSize) {
- backgroundView.clearAnimation();
- pulseAnimation = null;
- }
- }
- }
- });
-
- //Track location updates to move the user marker
- LocationServices.getLocationServices(getApplicationContext()).addLocationListener(new LocationListener() {
- @Override
- public void onLocationChanged(Location location) {
- if (location != null && markerView != null) {
- markerView.setPosition(new LatLng(location));
- }
- }
- });
- }
+ //Make drop pin visible, if it wasn't already
+ showDropPin();
- private MarkerView createCustomUserMarker(LatLng markerPosition) {
- return mapboxMap.addMarker(new PulseMarkerViewOptions()
- .icon(IconFactory.getInstance(getApplicationContext()).fromResource(R.drawable.ic_my_location_24dp))
- .position(markerPosition)
- );
- }
+ //Get the distance from the tip of the location picker to the MarkerView
+ double distance = getLocationPickerLocation().distanceTo(markerView.getPosition());
- private void createClearSelectionButton() {
- clearDisplayViewButton = (ImageButton) findViewById(R.id.clearDisplayViewButton);
- clearDisplayViewButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- removeAddressPin();
- hide(clearDisplayViewButton);
- showDropPin();
- }
- });
+ //If closeby, animate, otherwise, stop animation
+ View view = mapboxMap.getMarkerViewManager().getView(markerView);
+ if (view != null) {
+ View backgroundView = view.findViewById(R.id.background_imageview);
+ if (pulseAnimation == null && distance < 0.5f * circleDiameterSize) {
+ pulseAnimation = AnimationUtils.loadAnimation(LocationPickerActivity.this, R.anim.pulse);
+ pulseAnimation.setRepeatCount(Animation.INFINITE);
+ pulseAnimation.setRepeatMode(Animation.RESTART);
+ backgroundView.startAnimation(pulseAnimation);
+ } else if (pulseAnimation != null && distance >= 0.5f * circleDiameterSize) {
+ backgroundView.clearAnimation();
+ pulseAnimation = null;
+ }
+ }
+ }
+ });
+
+ //Track location updates to move the user marker
+ LocationServices.getLocationServices(getApplicationContext()).addLocationListener(new LocationListener() {
+ @Override
+ public void onLocationChanged(Location location) {
+ if (location != null && markerView != null) {
+ markerView.setPosition(new LatLng(location));
+ }
+ }
+ });
+ }
+
+ private MarkerView createCustomUserMarker(LatLng markerPosition) {
+ return mapboxMap.addMarker(new PulseMarkerViewOptions()
+ .icon(IconFactory.getInstance(getApplicationContext()).fromResource(R.drawable.ic_my_location_24dp))
+ .position(markerPosition)
+ );
+ }
+
+ private void createClearSelectionButton() {
+ clearDisplayViewButton = (ImageButton) findViewById(R.id.clearDisplayViewButton);
+ clearDisplayViewButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ removeAddressPin();
+ hide(clearDisplayViewButton);
+ showDropPin();
+ }
+ });
+ }
+
+ private void createSelectLocationButton() {
+ Button selectLocationButton = (Button) findViewById(R.id.selectLocationButton);
+ //noinspection ConstantConditions
+ selectLocationButton.setOnClickListener(
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Timber.i("Location Selected!");
+ if (mapboxMap != null) {
+ //Control button's state
+ clearDisplayViewButton.setVisibility(View.VISIBLE);
+ dropPinView.setVisibility(View.INVISIBLE);
+
+ //Get position for the drop pin
+ LatLng position = getLocationPickerLocation();
+
+ //Show the address pin (result)
+ showAddressPin(position);
+
+ //Get the address for that location and update the marker
+ geocode(position, new GeocodeCallbacks() {
+ @Override
+ public void onResult(String result) {
+ updateAddressPin(result);
+ }
+
+ @Override
+ public void onFailure(Throwable failure) {
+ showFeedbackMessage("Could not retrieve address: " + failure.getMessage());
+ }
+ });
+ }
+ }
+ }
+ );
+ }
+
+ private void createDropPin() {
+ float density = getResources().getDisplayMetrics().density;
+
+ dropPinView = new ImageView(this);
+ dropPinView.setImageResource(R.drawable.ic_droppin_24dp);
+ FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER);
+ params.bottomMargin = (int) (12 * density);
+ dropPinView.setLayoutParams(params);
+
+ mapView.addView(dropPinView);
+ }
+
+ private void showDropPin() {
+ if (dropPinView != null && dropPinView.getVisibility() != View.VISIBLE) {
+ dropPinView.setVisibility(View.VISIBLE);
}
+ }
- private void createSelectLocationButton() {
- Button selectLocationButton = (Button) findViewById(R.id.selectLocationButton);
- //noinspection ConstantConditions
- selectLocationButton.setOnClickListener(
- new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- Log.i(TAG, "Location Selected!");
- if (mapboxMap != null) {
- //Control button's state
- clearDisplayViewButton.setVisibility(View.VISIBLE);
- dropPinView.setVisibility(View.INVISIBLE);
-
- //Get position for the drop pin
- LatLng position = getLocationPickerLocation();
-
- //Show the address pin (result)
- showAddressPin(position);
-
- //Get the address for that location and update the marker
- geocode(position, new GeocodeCallbacks() {
- @Override
- public void onResult(String result) {
- updateAddressPin(result);
- }
-
- @Override
- public void onFailure(Throwable failure) {
- showFeedbackMessage("Could not retrieve address: " + failure.getMessage());
- }
- });
- }
- }
- }
- );
+ private void hide(View view) {
+ if (view != null) {
+ view.setVisibility(View.INVISIBLE);
}
+ }
- private void createDropPin() {
- float density = getResources().getDisplayMetrics().density;
-
- dropPinView = new ImageView(this);
- dropPinView.setImageResource(R.drawable.ic_droppin_24dp);
- FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER);
- params.bottomMargin = (int) (12 * density);
- dropPinView.setLayoutParams(params);
+ private void setupActionBar() {
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- mapView.addView(dropPinView);
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
-
- private void showDropPin() {
- if (dropPinView != null && dropPinView.getVisibility() != View.VISIBLE) {
- dropPinView.setVisibility(View.VISIBLE);
+ }
+
+ /**
+ * Get address for the given location
+ */
+ private void geocode(LatLng point, final GeocodeCallbacks callbacks) {
+ try {
+ //Create Geocoding client
+ MapboxGeocoding client = new MapboxGeocoding.Builder()
+ .setAccessToken(getString(R.string.mapbox_access_token))
+ .setCoordinates(Position.fromCoordinates(point.getLongitude(), point.getLatitude()))
+ .setGeocodingType(GeocodingCriteria.TYPE_ADDRESS)
+ .build();
+
+ //Place the request
+ client.enqueueCall(new Callback<GeocodingResponse>() {
+ @Override
+ public void onResponse(Call<GeocodingResponse> call, Response<GeocodingResponse> response) {
+
+ List<CarmenFeature> results = response.body().getFeatures();
+ String address = null;
+ if (results.size() > 0) {
+ CarmenFeature feature = results.get(0);
+ address = feature.getAddress() + " " + feature.getText();
+ Timber.i("address " + address);
+ } else {
+ showFeedbackMessage("No results for search.");
+ }
+
+ callbacks.onResult(address);
}
- }
- private void hide(View view) {
- if (view != null) {
- view.setVisibility(View.INVISIBLE);
+ @Override
+ public void onFailure(Call<GeocodingResponse> call, Throwable throwable) {
+ Timber.e("Geocoding Failure: " + throwable.getMessage());
+ callbacks.onFailure(throwable);
}
+ });
+ } catch (ServicesException servicesException) {
+ Timber.e("Error geocoding: " + servicesException.toString());
+ callbacks.onFailure(servicesException);
}
-
- private void setupActionBar() {
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
-
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
+ }
+
+ private LatLng getLocationPickerLocation() {
+ return mapboxMap.getProjection().fromScreenLocation(
+ new PointF(dropPinView.getLeft() + (dropPinView.getWidth() / 2), dropPinView.getBottom())
+ );
+ }
+
+ private Marker showAddressPin(LatLng position) {
+ if (addressPin != null) {
+ //Remove previous pin
+ removeAddressPin();
}
- /**
- * Get address for the given location
- */
- private void geocode(LatLng point, final GeocodeCallbacks callbacks) {
- try {
- //Create Geocoding client
- MapboxGeocoding client = new MapboxGeocoding.Builder()
- .setAccessToken(getString(R.string.mapbox_access_token))
- .setCoordinates(Position.fromCoordinates(point.getLongitude(), point.getLatitude()))
- .setGeocodingType(GeocodingCriteria.TYPE_ADDRESS)
- .build();
-
- //Place the request
- client.enqueueCall(new Callback<GeocodingResponse>() {
- @Override
- public void onResponse(Call<GeocodingResponse> call, Response<GeocodingResponse> response) {
-
- List<CarmenFeature> results = response.body().getFeatures();
- String address = null;
- if (results.size() > 0) {
- CarmenFeature feature = results.get(0);
- address = feature.getAddress() + " " + feature.getText();
- Log.i(TAG, "address " + address);
- } else {
- showFeedbackMessage("No results for search.");
- }
-
- callbacks.onResult(address);
- }
+ //Create new one
+ addressPin = mapboxMap.addMarker(new MarkerViewOptions().title("Loading address...").position(position));
+ mapboxMap.selectMarker(addressPin);
+ return addressPin;
+ }
- @Override
- public void onFailure(Call<GeocodingResponse> call, Throwable throwable) {
- Log.e(TAG, "Geocoding Failure: " + throwable.getMessage());
- callbacks.onFailure(throwable);
- }
- });
- } catch (ServicesException servicesException) {
- Log.e(TAG, "Error geocoding: " + servicesException.toString());
- callbacks.onFailure(servicesException);
- }
+ private void removeAddressPin() {
+ if (mapboxMap != null && addressPin != null) {
+ mapboxMap.removeMarker(addressPin);
}
+ }
- private LatLng getLocationPickerLocation() {
- return mapboxMap.getProjection().fromScreenLocation(
- new PointF(dropPinView.getLeft() + (dropPinView.getWidth() / 2), dropPinView.getBottom())
- );
+ private void updateAddressPin(@Nullable String address) {
+ if (addressPin != null) {
+ addressPin.setTitle(address == null ? "No address found" : address);
}
-
- private Marker showAddressPin(LatLng position) {
- if (addressPin != null) {
- //Remove previous pin
- removeAddressPin();
- }
-
- //Create new one
- addressPin = mapboxMap.addMarker(new MarkerViewOptions().title("Loading address...").position(position));
- mapboxMap.selectMarker(addressPin);
- return addressPin;
+ }
+
+ private void showFeedbackMessage(String message) {
+ Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
+ }
+
+ private boolean arePermissionsGranted() {
+ if (Build.VERSION.SDK_INT >= 23
+ && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
+ && checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
+ Timber.i("Requesting permissions");
+ ActivityCompat.requestPermissions(this, new String[] {
+ Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_PERMISSIONS);
+ return false;
}
+ Timber.i("Permissions already granted");
+ return true;
+ }
- private void removeAddressPin() {
- if (mapboxMap != null && addressPin != null) {
- mapboxMap.removeMarker(addressPin);
- }
- }
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
- private void updateAddressPin(@Nullable String address) {
- if (addressPin != null) {
- addressPin.setTitle(address == null ? "No address found" : address);
- }
- }
+ //Check permissions
+ if (arePermissionsGranted()) {
+ mapView.getMapAsync(new OnMapReadyCallback() {
- private void showFeedbackMessage(String message) {
- Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
- }
+ @Override
+ public void onMapReady(final MapboxMap mapboxMap) {
+ //Get the user's location
+ final LocationServices locationServices = LocationServices.getLocationServices(getApplicationContext());
+
+ Location location = locationServices.getLastLocation();
+ if (location != null) {
+ zoomInOn(location);
+ userMarker.setPosition(new LatLng(location));
+ } else {
+ final ProgressDialog loadingDialog = ProgressDialog.show(
+ LocationPickerActivity.this, "Loading", "Getting user location", false);
+ locationServices.addLocationListener(new LocationListener() {
+ @Override
+ public void onLocationChanged(@Nullable Location location) {
+ //Move the camera to the user
+ if (location != null) {
+ zoomInOn(location);
+ userMarker.setPosition(new LatLng(location));
+ locationServices.removeLocationListener(this);
+ loadingDialog.hide();
+ }
+ }
+ });
+ }
- private boolean arePermissionsGranted() {
- if (Build.VERSION.SDK_INT >= 23
- && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
- && checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
- Log.i(TAG, "Requesting permissions");
- ActivityCompat.requestPermissions(this, new String[]{
- Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_PERMISSIONS);
- return false;
+ locationServices.toggleGPS(true);
}
- Log.i(TAG, "Permissions already granted");
- return true;
+ });
}
-
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- }
+ /**
+ * Custom MarkerViewAdapter for the pulsing marker
+ */
+ private static class PulseMarkerViewAdapter extends MapboxMap.MarkerViewAdapter<PulseMarkerView> {
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
+ private LayoutInflater inflater;
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
+ public PulseMarkerViewAdapter(@NonNull Context context) {
+ super(context);
+ this.inflater = LayoutInflater.from(context);
}
+ @Nullable
@Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
+ public View getView(@NonNull PulseMarkerView marker, @Nullable View convertView, @NonNull ViewGroup parent) {
+ ViewHolder viewHolder;
+ if (convertView == null) {
+ viewHolder = new ViewHolder();
+ convertView = inflater.inflate(R.layout.view_pulse_marker, parent, false);
+ viewHolder.foregroundImageView = (ImageView) convertView.findViewById(R.id.foreground_imageView);
+ viewHolder.backgroundImageView = (ImageView) convertView.findViewById(R.id.background_imageview);
+ convertView.setTag(viewHolder);
+ }
+ return convertView;
}
- /**
- * Custom MarkerViewAdapter for the pulsing marker
- */
- private static class PulseMarkerViewAdapter extends MapboxMap.MarkerViewAdapter<PulseMarkerView> {
-
- private LayoutInflater inflater;
-
- public PulseMarkerViewAdapter(@NonNull Context context) {
- super(context);
- this.inflater = LayoutInflater.from(context);
- }
-
- @Nullable
- @Override
- public View getView(@NonNull PulseMarkerView marker, @Nullable View convertView, @NonNull ViewGroup parent) {
- ViewHolder viewHolder;
- if (convertView == null) {
- viewHolder = new ViewHolder();
- convertView = inflater.inflate(R.layout.view_pulse_marker, parent, false);
- viewHolder.foregroundImageView = (ImageView) convertView.findViewById(R.id.foreground_imageView);
- viewHolder.backgroundImageView = (ImageView) convertView.findViewById(R.id.background_imageview);
- convertView.setTag(viewHolder);
- }
- return convertView;
- }
-
- private static class ViewHolder {
- ImageView foregroundImageView;
- ImageView backgroundImageView;
- }
+ private static class ViewHolder {
+ ImageView foregroundImageView;
+ ImageView backgroundImageView;
}
+ }
- private interface GeocodeCallbacks {
- void onResult(String result);
+ private interface GeocodeCallbacks {
+ void onResult(String result);
- void onFailure(Throwable failure);
- }
+ void onFailure(Throwable failure);
+ }
}
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 e9dd9dc5f4..e2eda0e6b1 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
@@ -6,14 +6,13 @@ import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
-import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;
-import com.mapbox.mapboxsdk.MapboxAccountManager;
+import com.mapbox.mapboxsdk.Mapbox;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
@@ -35,309 +34,319 @@ import com.mapbox.mapboxsdk.testapp.utils.OfflineUtils;
import java.util.ArrayList;
-public class OfflineActivity extends AppCompatActivity
- implements OfflineDownloadRegionDialog.DownloadRegionDialogListener {
-
- private static final String LOG_TAG = "OfflineActivity";
-
- // JSON encoding/decoding
- public static final String JSON_CHARSET = "UTF-8";
- public static final String JSON_FIELD_REGION_NAME = "FIELD_REGION_NAME";
-
- /*
- * UI elements
- */
- private MapView mapView;
- private MapboxMap mapboxMap;
- private ProgressBar progressBar;
- private Button downloadRegion;
- private Button listRegions;
-
- private boolean isEndNotified;
-
- /*
- * Offline objects
- */
- private OfflineManager offlineManager;
- private OfflineRegion offlineRegion;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_offline);
-
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
-
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- 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);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(@NonNull MapboxMap mapboxMap) {
- Log.d(LOG_TAG, "Map is ready");
- OfflineActivity.this.mapboxMap = mapboxMap;
-
- // Set initial position to UNHQ in NYC
- mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(
- new CameraPosition.Builder()
- .target(new LatLng(40.749851, -73.967966))
- .zoom(14)
- .bearing(0)
- .tilt(0)
- .build()));
- }
- });
-
- // The progress bar
- progressBar = (ProgressBar) findViewById(R.id.progress_bar);
-
- // Set up button listeners
- downloadRegion = (Button) findViewById(R.id.button_download_region);
- downloadRegion.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- handleDownloadRegion();
- }
- });
-
- listRegions = (Button) findViewById(R.id.button_list_regions);
- listRegions.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- handleListRegions();
- }
- });
-
- // Set up the OfflineManager
- offlineManager = OfflineManager.getInstance(this);
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
- }
+import timber.log.Timber;
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
+public class OfflineActivity extends AppCompatActivity
+ implements OfflineDownloadRegionDialog.DownloadRegionDialogListener {
+
+ // JSON encoding/decoding
+ public static final String JSON_CHARSET = "UTF-8";
+ public static final String JSON_FIELD_REGION_NAME = "FIELD_REGION_NAME";
+
+ // Style URL
+ public static final String STYLE_URL = Style.MAPBOX_STREETS;
+
+ /*
+ * UI elements
+ */
+ private MapView mapView;
+ private MapboxMap mapboxMap;
+ private ProgressBar progressBar;
+ private Button downloadRegion;
+ private Button listRegions;
+
+ private boolean isEndNotified;
+
+ /*
+ * Offline objects
+ */
+ private OfflineManager offlineManager;
+ private OfflineRegion offlineRegion;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_offline);
+
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
+ // You can use Mapbox.setConnected(Boolean) to manually set the connectivity
+ // state of your app. This will override any checks performed via the ConnectivityManager.
+ //Mapbox.getInstance().setConnected(false);
+ Boolean connected = Mapbox.isConnected();
+ Timber.d(String.format(MapboxConstants.MAPBOX_LOCALE,
+ "Mapbox is connected: %b", connected));
+
+ // Set up map
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.setStyleUrl(STYLE_URL);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(@NonNull MapboxMap mapboxMap) {
+ Timber.d("Map is ready");
+ OfflineActivity.this.mapboxMap = mapboxMap;
+
+ // Set initial position to UNHQ in NYC
+ mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(
+ new CameraPosition.Builder()
+ .target(new LatLng(40.749851, -73.967966))
+ .zoom(14)
+ .bearing(0)
+ .tilt(0)
+ .build()));
+ }
+ });
+
+ // The progress bar
+ progressBar = (ProgressBar) findViewById(R.id.progress_bar);
+
+ // Set up button listeners
+ downloadRegion = (Button) findViewById(R.id.button_download_region);
+ downloadRegion.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ handleDownloadRegion();
+ }
+ });
+
+ listRegions = (Button) findViewById(R.id.button_list_regions);
+ listRegions.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ handleListRegions();
+ }
+ });
+
+ // Set up the OfflineManager
+ offlineManager = OfflineManager.getInstance(this);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
+ }
+
+ /*
+ * Buttons logic
+ */
+ private void handleDownloadRegion() {
+ Timber.d("handleDownloadRegion");
+
+ // Show dialog
+ OfflineDownloadRegionDialog offlineDownloadRegionDialog = new OfflineDownloadRegionDialog();
+ offlineDownloadRegionDialog.show(getSupportFragmentManager(), "download");
+ }
+
+ private void handleListRegions() {
+ Timber.d("handleListRegions");
+
+ // Query the DB asynchronously
+ offlineManager.listOfflineRegions(new OfflineManager.ListOfflineRegionsCallback() {
+ @Override
+ public void onList(OfflineRegion[] offlineRegions) {
+ // Check result
+ if (offlineRegions == null || offlineRegions.length == 0) {
+ Toast.makeText(OfflineActivity.this, "You have no regions yet.", Toast.LENGTH_SHORT).show();
+ return;
}
- }
- /*
- * Buttons logic
- */
+ // Get regions info
+ ArrayList<String> offlineRegionsNames = new ArrayList<>();
+ for (OfflineRegion offlineRegion : offlineRegions) {
+ offlineRegionsNames.add(OfflineUtils.convertRegionName(offlineRegion.getMetadata()));
+ }
- private void handleDownloadRegion() {
- Log.d(LOG_TAG, "handleDownloadRegion");
+ // Create args
+ Bundle args = new Bundle();
+ args.putStringArrayList(OfflineListRegionsDialog.ITEMS, offlineRegionsNames);
// Show dialog
- OfflineDownloadRegionDialog offlineDownloadRegionDialog = new OfflineDownloadRegionDialog();
- offlineDownloadRegionDialog.show(getSupportFragmentManager(), "download");
+ OfflineListRegionsDialog offlineListRegionsDialog = new OfflineListRegionsDialog();
+ offlineListRegionsDialog.setArguments(args);
+ offlineListRegionsDialog.show(getSupportFragmentManager(), "list");
+ }
+
+ @Override
+ public void onError(String error) {
+ Timber.e("Error: " + error);
+ }
+ });
+ }
+
+ /*
+ * Dialogs
+ */
+ @Override
+ public void onDownloadRegionDialogPositiveClick(final String regionName) {
+ if (TextUtils.isEmpty(regionName)) {
+ Toast.makeText(OfflineActivity.this, "Region name cannot be empty.", Toast.LENGTH_SHORT).show();
+ return;
}
- private void handleListRegions() {
- Log.d(LOG_TAG, "handleListRegions");
-
- // Query the DB asynchronously
- offlineManager.listOfflineRegions(new OfflineManager.ListOfflineRegionsCallback() {
- @Override
- public void onList(OfflineRegion[] offlineRegions) {
- // Check result
- if (offlineRegions == null || offlineRegions.length == 0) {
- Toast.makeText(OfflineActivity.this, "You have no regions yet.", Toast.LENGTH_SHORT).show();
- return;
- }
-
- // Get regions info
- ArrayList<String> offlineRegionsNames = new ArrayList<>();
- for (OfflineRegion offlineRegion : offlineRegions) {
- offlineRegionsNames.add(OfflineUtils.convertRegionName(offlineRegion.getMetadata()));
- }
-
- // Create args
- Bundle args = new Bundle();
- args.putStringArrayList(OfflineListRegionsDialog.ITEMS, offlineRegionsNames);
-
- // Show dialog
- OfflineListRegionsDialog offlineListRegionsDialog = new OfflineListRegionsDialog();
- offlineListRegionsDialog.setArguments(args);
- offlineListRegionsDialog.show(getSupportFragmentManager(), "list");
- }
-
- @Override
- public void onError(String error) {
- Log.e(LOG_TAG, "Error: " + error);
- }
- });
- }
-
- /*
- * Dialogs
- */
-
- @Override
- public void onDownloadRegionDialogPositiveClick(final String regionName) {
- if (TextUtils.isEmpty(regionName)) {
- Toast.makeText(OfflineActivity.this, "Region name cannot be empty.", Toast.LENGTH_SHORT).show();
- return;
+ // Start progress bar
+ Timber.d("Download started: " + regionName);
+ startProgress();
+
+ // Definition
+ LatLngBounds bounds = mapboxMap.getProjection().getVisibleRegion().latLngBounds;
+ double minZoom = mapboxMap.getCameraPosition().zoom;
+ double maxZoom = mapboxMap.getMaxZoomLevel();
+ float pixelRatio = this.getResources().getDisplayMetrics().density;
+ OfflineTilePyramidRegionDefinition definition = new OfflineTilePyramidRegionDefinition(
+ STYLE_URL, bounds, minZoom, maxZoom, pixelRatio);
+
+ // Sample way of encoding metadata from a JSONObject
+ byte[] metadata = OfflineUtils.convertRegionName(regionName);
+
+ // Create region
+ offlineManager.createOfflineRegion(definition, metadata, new OfflineManager.CreateOfflineRegionCallback() {
+ @Override
+ public void onCreate(OfflineRegion offlineRegion) {
+ Timber.d("Offline region created: " + regionName);
+ OfflineActivity.this.offlineRegion = offlineRegion;
+ launchDownload();
+ }
+
+ @Override
+ public void onError(String error) {
+ Timber.e("Error: " + error);
+ }
+ });
+ }
+
+ private void launchDownload() {
+ // Set an observer
+ offlineRegion.setObserver(new OfflineRegion.OfflineRegionObserver() {
+ @Override
+ public void onStatusChanged(OfflineRegionStatus status) {
+ // Compute a percentage
+ double percentage = status.getRequiredResourceCount() >= 0
+ ? (100.0 * status.getCompletedResourceCount() / status.getRequiredResourceCount()) :
+ 0.0;
+
+ if (status.isComplete()) {
+ // Download complete
+ endProgress("Region downloaded successfully.");
+ return;
+ } else if (status.isRequiredResourceCountPrecise()) {
+ // Switch to determinate state
+ setPercentage((int) Math.round(percentage));
}
- // Start progress bar
- Log.d(LOG_TAG, "Download started: " + regionName);
- startProgress();
-
- // Definition
- String styleUrl = mapboxMap.getStyleUrl();
- LatLngBounds bounds = mapboxMap.getProjection().getVisibleRegion().latLngBounds;
- double minZoom = mapboxMap.getCameraPosition().zoom;
- double maxZoom = mapboxMap.getMaxZoom();
- float pixelRatio = this.getResources().getDisplayMetrics().density;
- OfflineTilePyramidRegionDefinition definition = new OfflineTilePyramidRegionDefinition(
- styleUrl, bounds, minZoom, maxZoom, pixelRatio);
-
- // Sample way of encoding metadata from a JSONObject
- byte[] metadata = OfflineUtils.convertRegionName(regionName);
-
- // Create region
- offlineManager.createOfflineRegion(definition, metadata, new OfflineManager.CreateOfflineRegionCallback() {
- @Override
- public void onCreate(OfflineRegion offlineRegion) {
- Log.d(LOG_TAG, "Offline region created: " + regionName);
- OfflineActivity.this.offlineRegion = offlineRegion;
- launchDownload();
- }
-
- @Override
- public void onError(String error) {
- Log.e(LOG_TAG, "Error: " + error);
- }
- });
- }
-
- private void launchDownload() {
- // Set an observer
- offlineRegion.setObserver(new OfflineRegion.OfflineRegionObserver() {
- @Override
- public void onStatusChanged(OfflineRegionStatus status) {
- // Compute a percentage
- double percentage = status.getRequiredResourceCount() >= 0
- ? (100.0 * status.getCompletedResourceCount() / status.getRequiredResourceCount()) :
- 0.0;
-
- if (status.isComplete()) {
- // Download complete
- endProgress("Region downloaded successfully.");
- return;
- } else if (status.isRequiredResourceCountPrecise()) {
- // Switch to determinate state
- setPercentage((int) Math.round(percentage));
- }
-
- // Debug
- Log.d(LOG_TAG, String.format("%s/%s resources; %s bytes downloaded.",
- String.valueOf(status.getCompletedResourceCount()),
- String.valueOf(status.getRequiredResourceCount()),
- String.valueOf(status.getCompletedResourceSize())));
- }
-
- @Override
- public void onError(OfflineRegionError error) {
- Log.e(LOG_TAG, "onError reason: " + error.getReason());
- Log.e(LOG_TAG, "onError message: " + error.getMessage());
- }
-
- @Override
- public void mapboxTileCountLimitExceeded(long limit) {
- Log.e(LOG_TAG, "Mapbox tile count limit exceeded: " + limit);
- }
- });
-
- // Change the region state
- offlineRegion.setDownloadState(OfflineRegion.STATE_ACTIVE);
- }
-
- /*
- * Progress bar
- */
-
- private void startProgress() {
- // Disable buttons
- downloadRegion.setEnabled(false);
- listRegions.setEnabled(false);
-
- // Start and show the progress bar
- isEndNotified = false;
- progressBar.setIndeterminate(true);
- progressBar.setVisibility(View.VISIBLE);
- }
-
- private void setPercentage(final int percentage) {
- progressBar.setIndeterminate(false);
- progressBar.setProgress(percentage);
+ // Debug
+ Timber.d(String.format("%s/%s resources; %s bytes downloaded.",
+ String.valueOf(status.getCompletedResourceCount()),
+ String.valueOf(status.getRequiredResourceCount()),
+ String.valueOf(status.getCompletedResourceSize())));
+ }
+
+ @Override
+ public void onError(OfflineRegionError error) {
+ Timber.e("onError reason: " + error.getReason());
+ Timber.e("onError message: " + error.getMessage());
+ }
+
+ @Override
+ public void mapboxTileCountLimitExceeded(long limit) {
+ Timber.e("Mapbox tile count limit exceeded: " + limit);
+ }
+ });
+
+ // Change the region state
+ offlineRegion.setDownloadState(OfflineRegion.STATE_ACTIVE);
+ }
+
+ /*
+ * Progress bar
+ */
+ private void startProgress() {
+ // Disable buttons
+ downloadRegion.setEnabled(false);
+ listRegions.setEnabled(false);
+
+ // Start and show the progress bar
+ isEndNotified = false;
+ progressBar.setIndeterminate(true);
+ progressBar.setVisibility(View.VISIBLE);
+ }
+
+ private void setPercentage(final int percentage) {
+ progressBar.setIndeterminate(false);
+ progressBar.setProgress(percentage);
+ }
+
+ private void endProgress(final String message) {
+ // Don't notify more than once
+ if (isEndNotified) {
+ return;
}
- private void endProgress(final String message) {
- // Don't notify more than once
- if (isEndNotified) {
- return;
- }
+ // Enable buttons
+ downloadRegion.setEnabled(true);
+ listRegions.setEnabled(true);
- // Enable buttons
- downloadRegion.setEnabled(true);
- listRegions.setEnabled(true);
-
- // Stop and hide the progress bar
- isEndNotified = true;
- progressBar.setIndeterminate(false);
- progressBar.setVisibility(View.GONE);
-
- // Show a toast
- Toast.makeText(OfflineActivity.this, message, Toast.LENGTH_LONG).show();
- }
+ // Stop and hide the progress bar
+ isEndNotified = true;
+ progressBar.setIndeterminate(false);
+ progressBar.setVisibility(View.GONE);
+ // Show a toast
+ Toast.makeText(OfflineActivity.this, message, Toast.LENGTH_LONG).show();
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/UpdateMetadataActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/UpdateMetadataActivity.java
index 0530f1c157..a83cabba12 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/UpdateMetadataActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/UpdateMetadataActivity.java
@@ -33,154 +33,158 @@ import java.util.List;
*/
public class UpdateMetadataActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
- private OfflineRegionMetadataAdapter adapter;
+ private OfflineRegionMetadataAdapter adapter;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_metadata_update);
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_metadata_update);
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
+ }
- ListView listView = (ListView) findViewById(R.id.listView);
- listView.setAdapter(adapter = new OfflineRegionMetadataAdapter(this));
- listView.setEmptyView(findViewById(android.R.id.empty));
- listView.setOnItemClickListener(this);
+ ListView listView = (ListView) findViewById(R.id.listView);
+ listView.setAdapter(adapter = new OfflineRegionMetadataAdapter(this));
+ listView.setEmptyView(findViewById(android.R.id.empty));
+ listView.setOnItemClickListener(this);
+ }
+
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ final OfflineRegion region = adapter.getItem(position);
+ String metadata = OfflineUtils.convertRegionName(region.getMetadata());
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle("Rename metadata");
+
+ final EditText input = new EditText(this);
+ input.setText(metadata);
+ input.setInputType(InputType.TYPE_CLASS_TEXT);
+ input.setSelection(metadata.length());
+ builder.setView(input);
+
+ builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ updateMetadata(region, OfflineUtils.convertRegionName(input.getText().toString()));
+ }
+ });
+ builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.cancel();
+ }
+ });
+
+ builder.show();
+ }
+
+ private void updateMetadata(OfflineRegion region, byte[] metadata) {
+ region.updateMetadata(metadata, new OfflineRegion.OfflineRegionUpdateMetadataCallback() {
+ @Override
+ public void onUpdate(byte[] metadata) {
+ adapter.notifyDataSetChanged();
+ }
+
+ @Override
+ public void onError(String error) {
+ Toast.makeText(
+ UpdateMetadataActivity.this,
+ "Region metadata update failed with " + error,
+ Toast.LENGTH_LONG
+ ).show();
+ }
+ });
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ loadOfflineRegions();
+ }
+
+ private void loadOfflineRegions() {
+ OfflineManager.getInstance(this).listOfflineRegions(new OfflineManager.ListOfflineRegionsCallback() {
+ @Override
+ public void onList(OfflineRegion[] offlineRegions) {
+ if (offlineRegions != null && offlineRegions.length > 0) {
+ adapter.setOfflineRegions(Arrays.asList(offlineRegions));
+ }
+ }
+
+ @Override
+ public void onError(String error) {
+ Toast.makeText(UpdateMetadataActivity.this, "Error loading regions " + error, Toast.LENGTH_LONG).show();
+ }
+ });
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- final OfflineRegion region = adapter.getItem(position);
- String metadata = OfflineUtils.convertRegionName(region.getMetadata());
-
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle("Rename metadata");
-
- final EditText input = new EditText(this);
- input.setText(metadata);
- input.setInputType(InputType.TYPE_CLASS_TEXT);
- input.setSelection(metadata.length());
- builder.setView(input);
-
- builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- updateMetadata(region, OfflineUtils.convertRegionName(input.getText().toString()));
- }
- });
- builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- dialog.cancel();
- }
- });
-
- builder.show();
+ private static class OfflineRegionMetadataAdapter extends BaseAdapter {
+
+ private Context context;
+ private List<OfflineRegion> offlineRegions;
+
+ OfflineRegionMetadataAdapter(Context ctx) {
+ context = ctx;
+ offlineRegions = new ArrayList<>();
}
- private void updateMetadata(OfflineRegion region, byte[] metadata) {
- region.updateMetadata(metadata, new OfflineRegion.OfflineRegionUpdateMetadataCallback() {
- @Override
- public void onUpdate(byte[] metadata) {
- adapter.notifyDataSetChanged();
- }
-
- @Override
- public void onError(String error) {
- Toast.makeText(UpdateMetadataActivity.this, "Region metadata update failed with " + error, Toast.LENGTH_LONG).show();
- }
- });
+ void setOfflineRegions(List<OfflineRegion> offlineRegions) {
+ this.offlineRegions = offlineRegions;
+ notifyDataSetChanged();
}
@Override
- protected void onStart() {
- super.onStart();
- loadOfflineRegions();
+ public int getCount() {
+ return offlineRegions.size();
}
- private void loadOfflineRegions() {
- OfflineManager.getInstance(this).listOfflineRegions(new OfflineManager.ListOfflineRegionsCallback() {
- @Override
- public void onList(OfflineRegion[] offlineRegions) {
- if (offlineRegions != null && offlineRegions.length > 0) {
- adapter.setOfflineRegions(Arrays.asList(offlineRegions));
- }
- }
-
- @Override
- public void onError(String error) {
- Toast.makeText(UpdateMetadataActivity.this, "Error loading regions " + error, Toast.LENGTH_LONG).show();
- }
- });
+ @Override
+ public OfflineRegion getItem(int position) {
+ return offlineRegions.get(position);
}
@Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
+ public long getItemId(int position) {
+ return position;
}
- private static class OfflineRegionMetadataAdapter extends BaseAdapter {
-
- private Context context;
- private List<OfflineRegion> offlineRegions;
-
- OfflineRegionMetadataAdapter(Context ctx) {
- context = ctx;
- offlineRegions = new ArrayList<>();
- }
-
- void setOfflineRegions(List<OfflineRegion> offlineRegions) {
- this.offlineRegions = offlineRegions;
- notifyDataSetChanged();
- }
-
- @Override
- public int getCount() {
- return offlineRegions.size();
- }
-
- @Override
- public OfflineRegion getItem(int position) {
- return offlineRegions.get(position);
- }
-
- @Override
- public long getItemId(int position) {
- return position;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- ViewHolder holder;
-
- if (convertView == null) {
- holder = new ViewHolder();
- convertView = LayoutInflater.from(context).inflate(android.R.layout.simple_list_item_1, parent, false);
- holder.text = (TextView) convertView.findViewById(android.R.id.text1);
- convertView.setTag(holder);
- } else {
- holder = (ViewHolder) convertView.getTag();
- }
-
- holder.text.setText(OfflineUtils.convertRegionName(getItem(position).getMetadata()));
- return convertView;
- }
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ ViewHolder holder;
+
+ if (convertView == null) {
+ holder = new ViewHolder();
+ convertView = LayoutInflater.from(context).inflate(android.R.layout.simple_list_item_1, parent, false);
+ holder.text = (TextView) convertView.findViewById(android.R.id.text1);
+ convertView.setTag(holder);
+ } else {
+ holder = (ViewHolder) convertView.getTag();
+ }
+
+ holder.text.setText(OfflineUtils.convertRegionName(getItem(position).getMetadata()));
+ return convertView;
+ }
- static class ViewHolder {
- TextView text;
- }
+ static class ViewHolder {
+ TextView text;
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/CircleLayerActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/CircleLayerActivity.java
index 44380ae5b5..1d90511888 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/CircleLayerActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/CircleLayerActivity.java
@@ -8,11 +8,12 @@ import android.support.v4.content.res.ResourcesCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
-import android.util.Log;
+
+import timber.log.Timber;
+
import android.view.MenuItem;
import android.view.View;
-import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
@@ -34,110 +35,120 @@ import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleRadius;
*/
public class CircleLayerActivity extends AppCompatActivity {
- private MapboxMap mapboxMap;
- private MapView mapView;
- private Layer circleLayer;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_circlelayer);
-
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
-
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(@NonNull final MapboxMap map) {
- mapboxMap = map;
- FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
- fab.setColorFilter(ContextCompat.getColor(CircleLayerActivity.this, R.color.primary));
- fab.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- if (circleLayer == null) {
- // first time
- try {
- mapboxMap.addSource(new GeoJsonSource("point", new URL("https://gist.githubusercontent.com/anonymous/87eca90e80a72b1b42be9d0201ec3c8e/raw/acbb46384fd56044a504f122950d0637d98b4e7a/map.geojson")));
- } catch (MalformedURLException malformedUrlException) {
- Log.e(
- MapboxConstants.TAG,
- "That's not an url... " + malformedUrlException.getMessage()
- );
- }
-
- circleLayer = new CircleLayer("circleLayer", "point");
- circleLayer.setProperties(
- circleColor(ResourcesCompat.getColor(getResources(), R.color.primary_dark, getTheme())),
- circleRadius(getResources().getDimension(R.dimen.circle_size))
- );
-
- // lets add a circle below labels!
- mapboxMap.addLayer(circleLayer, "waterway-label");
- } else {
- // change size and color
- circleLayer = mapboxMap.getLayer("circleLayer");
- circleLayer.setProperties(
- circleRadius(mapView.getTag() == null
- ? getResources().getDimension(R.dimen.activity_horizontal_margin)
- : getResources().getDimension(R.dimen.circle_size)),
- circleColor(mapView.getTag() == null ? ResourcesCompat.getColor(
- getResources(), R.color.blue_accent, getTheme()) : ResourcesCompat.getColor(
- getResources(), R.color.green_accent, getTheme())));
- mapView.setTag(mapView.getTag() == null ? mapboxMap : null);
- }
- }
- });
- }
- });
- }
+ private MapboxMap mapboxMap;
+ private MapView mapView;
+ private Layer circleLayer;
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_circlelayer);
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
- }
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(@NonNull final MapboxMap map) {
+ mapboxMap = map;
+ FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
+ fab.setColorFilter(ContextCompat.getColor(CircleLayerActivity.this, R.color.primary));
+ fab.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ if (circleLayer == null) {
+ // first time
+ try {
+ mapboxMap.addSource(new GeoJsonSource("point", new URL("https://gist.githubusercontent.com/anonymous/87eca90e80a72b1b42be9d0201ec3c8e/raw/acbb46384fd56044a504f122950d0637d98b4e7a/map.geojson")));
+ } catch (MalformedURLException malformedUrlException) {
+ Timber.e(
+ "That's not an url... " + malformedUrlException.getMessage()
+ );
+ }
+
+ circleLayer = new CircleLayer("circleLayer", "point");
+ circleLayer.setProperties(
+ circleColor(ResourcesCompat.getColor(getResources(), R.color.primary_dark, getTheme())),
+ circleRadius(getResources().getDimension(R.dimen.circle_size))
+ );
+
+ // lets add a circle below labels!
+ mapboxMap.addLayer(circleLayer, "waterway-label");
+ } else {
+ // change size and color
+ circleLayer.setProperties(
+ circleRadius(mapView.getTag() == null
+ ? getResources().getDimension(R.dimen.activity_horizontal_margin)
+ : getResources().getDimension(R.dimen.circle_size)),
+ circleColor(mapView.getTag() == null ? ResourcesCompat.getColor(
+ getResources(), R.color.blue_accent, getTheme()) : ResourcesCompat.getColor(
+ getResources(), R.color.green_accent, getTheme())));
+ mapView.setTag(mapView.getTag() == null ? mapboxMap : null);
+ }
+ }
+ });
+ }
+ });
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/CustomSpriteActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/CustomSpriteActivity.java
index 69108c6e1b..d68872a5ba 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/CustomSpriteActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/CustomSpriteActivity.java
@@ -1,156 +1,166 @@
package com.mapbox.mapboxsdk.testapp.activity.style;
-import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
-import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.content.ContextCompat;
-import android.support.v4.content.res.ResourcesCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
-import android.util.Log;
+
+import timber.log.Timber;
+
import android.view.MenuItem;
import android.view.View;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
-import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
-import com.mapbox.mapboxsdk.style.layers.CircleLayer;
import com.mapbox.mapboxsdk.style.layers.Layer;
import com.mapbox.mapboxsdk.style.layers.SymbolLayer;
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;
-import com.mapbox.mapboxsdk.style.sources.Source;
import com.mapbox.mapboxsdk.testapp.R;
import com.mapbox.services.commons.geojson.Feature;
import com.mapbox.services.commons.geojson.FeatureCollection;
import com.mapbox.services.commons.geojson.Point;
import com.mapbox.services.commons.models.Position;
-import java.net.MalformedURLException;
-import java.net.URL;
-
-import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleColor;
-import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleRadius;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconImage;
/**
* Example to add a sprite image and use it in a Symbol Layer
*/
public class CustomSpriteActivity extends AppCompatActivity {
- private static final String TAG = CustomSpriteActivity.class.getSimpleName();
- private static final String CUSTOM_ICON = "custom-icon";
-
- private MapboxMap mapboxMap;
- private MapView mapView;
- private Layer layer;
-
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_add_sprite);
-
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
-
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(@NonNull final MapboxMap map) {
- mapboxMap = map;
- final FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
- fab.setColorFilter(ContextCompat.getColor(CustomSpriteActivity.this, R.color.primary));
- fab.setOnClickListener(new View.OnClickListener() {
- private Point point;
-
- @Override
- public void onClick(View view) {
- if (point == null) {
- Log.i(TAG, "First click -> Car");
- // Add an icon to reference later
- mapboxMap.addImage(CUSTOM_ICON, BitmapFactory.decodeResource(getResources(), R.drawable.ic_car_top));
-
- //Add a source with a geojson point
- point = Point.fromCoordinates(Position.fromCoordinates(13.400972d, 52.519003d));
- mapboxMap.addSource(new GeoJsonSource("point", FeatureCollection.fromFeatures(new Feature[]{Feature.fromGeometry(point)})));
-
- //Add a symbol layer that references that point source
- layer = new SymbolLayer("layer", "point");
- layer.setProperties(
- //Set the id of the sprite to use
- iconImage(CUSTOM_ICON)
- );
-
- // lets add a circle below labels!
- mapboxMap.addLayer(layer, "waterway-label");
-
- fab.setImageResource(R.drawable.ic_directions_car_black_24dp);
- } else {
- //Update point
- point = Point.fromCoordinates(Position.fromCoordinates(point.getCoordinates().getLongitude() + 0.001, point.getCoordinates().getLatitude() + 0.001));
- GeoJsonSource source = mapboxMap.getSourceAs("point");
- source.setGeoJson(FeatureCollection.fromFeatures(new Feature[]{Feature.fromGeometry(point)}));
-
- //Move the camera as well
- mapboxMap.moveCamera(CameraUpdateFactory.newLatLng(new LatLng(point.getCoordinates().getLatitude(), point.getCoordinates().getLongitude())));
- }
- }
- });
- }
- });
- }
+ private static final String CUSTOM_ICON = "custom-icon";
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
+ private MapboxMap mapboxMap;
+ private MapView mapView;
+ private Layer layer;
+ private GeoJsonSource source;
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
- }
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- }
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_add_sprite);
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
- }
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- @Override
- public void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(@NonNull final MapboxMap map) {
+ mapboxMap = map;
+ final FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
+ fab.setColorFilter(ContextCompat.getColor(CustomSpriteActivity.this, R.color.primary));
+ fab.setOnClickListener(new View.OnClickListener() {
+ private Point point;
+
+ @Override
+ public void onClick(View view) {
+ if (point == null) {
+ Timber.i("First click -> Car");
+ // Add an icon to reference later
+ mapboxMap.addImage(CUSTOM_ICON, BitmapFactory.decodeResource(getResources(), R.drawable.ic_car_top));
+
+ //Add a source with a geojson point
+ point = Point.fromCoordinates(Position.fromCoordinates(13.400972d, 52.519003d));
+ source = new GeoJsonSource(
+ "point",
+ FeatureCollection.fromFeatures(new Feature[] {Feature.fromGeometry(point)})
+ );
+ mapboxMap.addSource(source);
+
+ //Add a symbol layer that references that point source
+ layer = new SymbolLayer("layer", "point");
+ layer.setProperties(
+ //Set the id of the sprite to use
+ iconImage(CUSTOM_ICON)
+ );
+
+ // lets add a circle below labels!
+ mapboxMap.addLayer(layer, "waterway-label");
+
+ fab.setImageResource(R.drawable.ic_directions_car_black_24dp);
+ } else {
+ //Update point
+ point = Point.fromCoordinates(
+ Position.fromCoordinates(point.getCoordinates().getLongitude() + 0.001,
+ point.getCoordinates().getLatitude() + 0.001)
+ );
+ source.setGeoJson(FeatureCollection.fromFeatures(new Feature[] {Feature.fromGeometry(point)}));
+
+ //Move the camera as well
+ mapboxMap.moveCamera(CameraUpdateFactory.newLatLng(new LatLng(
+ point.getCoordinates().getLatitude(), point.getCoordinates().getLongitude())));
+ }
+ }
+ });
+ }
+ });
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/GeoJsonClusteringActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/GeoJsonClusteringActivity.java
index 9d13ee165d..33fc7f60a6 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/GeoJsonClusteringActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/GeoJsonClusteringActivity.java
@@ -6,7 +6,9 @@ import android.support.v4.content.res.ResourcesCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
-import android.util.Log;
+
+import timber.log.Timber;
+
import android.view.MenuItem;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
@@ -37,140 +39,151 @@ import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textSize;
* Sample Activity to show off geojson source clustering and filter usage
*/
public class GeoJsonClusteringActivity extends AppCompatActivity {
- private static final String TAG = GeoJsonClusteringActivity.class.getSimpleName();
-
- private MapView mapView;
- private MapboxMap mapboxMap;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_geojson_clustering);
- setupActionBar();
-
- //Initialize map as normal
- mapView = (MapView) findViewById(R.id.mapView);
- //noinspection ConstantConditions
- mapView.onCreate(savedInstanceState);
-
- mapView.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(MapboxMap map) {
- mapboxMap = map;
- mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(37.7749, 122.4194), 0));
-
- //Add a clustered source with some layers
- addClusteredGeoJsonSource();
- }
- });
+ private MapView mapView;
+ private MapboxMap mapboxMap;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_geojson_clustering);
+
+ setupActionBar();
+
+ //Initialize map as normal
+ mapView = (MapView) findViewById(R.id.mapView);
+ //noinspection ConstantConditions
+ mapView.onCreate(savedInstanceState);
+
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(MapboxMap map) {
+ mapboxMap = map;
+ mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(37.7749, 122.4194), 0));
+
+ //Add a clustered source with some layers
+ addClusteredGeoJsonSource();
+ }
+ });
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
-
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
+ }
+
+ private void addClusteredGeoJsonSource() {
+ //Add a clustered source
+ try {
+ mapboxMap.addSource(
+ new GeoJsonSource("earthquakes",
+ new URL("https://www.mapbox.com/mapbox-gl-js/assets/earthquakes.geojson"),
+ new GeoJsonOptions()
+ .withCluster(true)
+ .withClusterMaxZoom(14)
+ .withClusterRadius(50)
+ )
+ );
+ } catch (MalformedURLException malformedUrlException) {
+ Timber.e("That's not an url... " + malformedUrlException.getMessage());
}
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
+ //Add unclustered layer
+ int[][] layers = new int[][] {
+ new int[] {150, ResourcesCompat.getColor(getResources(), R.color.red_accent, getTheme())},
+ new int[] {20, ResourcesCompat.getColor(getResources(), R.color.green_accent, getTheme())},
+ new int[] {0, ResourcesCompat.getColor(getResources(), R.color.blue_accent, getTheme())}
+ };
+
+ SymbolLayer unclustered = new SymbolLayer("unclustered-points", "earthquakes");
+ unclustered.setProperties(iconImage("marker-15"));
+ mapboxMap.addLayer(unclustered);
+
+ for (int i = 0; i < layers.length; i++) {
+ //Add some nice circles
+ CircleLayer circles = new CircleLayer("cluster-" + i, "earthquakes");
+ circles.setProperties(
+ circleColor(layers[i][1]),
+ circleRadius(18f)
+ );
+ circles.setFilter(
+ i == 0
+ ? gte("point_count", layers[i][0]) :
+ all(gte("point_count", layers[i][0]), lt("point_count", layers[i - 1][0]))
+ );
+ mapboxMap.addLayer(circles);
}
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
+ //Add the count labels
+ SymbolLayer count = new SymbolLayer("count", "earthquakes");
+ count.setProperties(
+ textField("{point_count}"),
+ textSize(12f),
+ textColor(Color.WHITE)
+ );
+ mapboxMap.addLayer(count);
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
- }
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
- }
-
- private void addClusteredGeoJsonSource() {
- //Add a clustered source
- try {
- mapboxMap.addSource(
- new GeoJsonSource("earthquakes",
- new URL("https://www.mapbox.com/mapbox-gl-js/assets/earthquakes.geojson"),
- new GeoJsonOptions()
- .withCluster(true)
- .withClusterMaxZoom(14)
- .withClusterRadius(50)
- )
- );
- } catch (MalformedURLException malformedUrlException) {
- Log.e(TAG, "That's not an url... " + malformedUrlException.getMessage());
- }
-
- //Add unclustered layer
- int[][] layers = new int[][]{
- new int[]{150, ResourcesCompat.getColor(getResources(), R.color.red_accent, getTheme())},
- new int[]{20, ResourcesCompat.getColor(getResources(), R.color.green_accent, getTheme())},
- new int[]{0, ResourcesCompat.getColor(getResources(), R.color.blue_accent, getTheme())}
- };
-
- SymbolLayer unclustered = new SymbolLayer("unclustered-points", "earthquakes");
- unclustered.setProperties(iconImage("marker-15"));
- mapboxMap.addLayer(unclustered);
-
- for (int i = 0; i < layers.length; i++) {
- //Add some nice circles
- CircleLayer circles = new CircleLayer("cluster-" + i, "earthquakes");
- circles.setProperties(
- circleColor(layers[i][1]),
- circleRadius(18f)
- );
- circles.setFilter(
- i == 0
- ? gte("point_count", layers[i][0]) :
- all(gte("point_count", layers[i][0]), lt("point_count", layers[i - 1][0]))
- );
- mapboxMap.addLayer(circles);
- }
-
- //Add the count labels
- SymbolLayer count = new SymbolLayer("count", "earthquakes");
- count.setProperties(
- textField("{point_count}"),
- textSize(12f),
- textColor(Color.WHITE)
- );
- mapboxMap.addLayer(count);
-
-
- //Zoom out to start
- mapboxMap.animateCamera(CameraUpdateFactory.zoomTo(1));
- }
+ //Zoom out to start
+ mapboxMap.animateCamera(CameraUpdateFactory.zoomTo(1));
+ }
- private void setupActionBar() {
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
+ private void setupActionBar() {
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RealTimeGeoJsonActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RealTimeGeoJsonActivity.java
index debd44fb1f..fad4f9714d 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RealTimeGeoJsonActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RealTimeGeoJsonActivity.java
@@ -6,10 +6,11 @@ import android.support.annotation.NonNull;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
-import android.util.Log;
+
+import timber.log.Timber;
+
import android.view.MenuItem;
-import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
@@ -30,112 +31,119 @@ import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconImage;
*/
public class RealTimeGeoJsonActivity extends AppCompatActivity implements OnMapReadyCallback {
- private final static String ID_GEOJSON_LAYER = "wanderdrone";
- private final static String ID_GEOJSON_SOURCE = ID_GEOJSON_LAYER;
- private final static String URL_GEOJSON_SOURCE = "https://wanderdrone.appspot.com/";
+ private static final String ID_GEOJSON_LAYER = "wanderdrone";
+ private static final String ID_GEOJSON_SOURCE = ID_GEOJSON_LAYER;
+ private static final String URL_GEOJSON_SOURCE = "https://wanderdrone.appspot.com/";
- private MapView mapView;
- private MapboxMap mapboxMap;
+ private MapView mapView;
+ private MapboxMap mapboxMap;
- private Handler handler;
- private Runnable runnable;
+ private Handler handler;
+ private Runnable runnable;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_default);
-
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
-
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(this);
- }
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_default);
- @Override
- public void onMapReady(@NonNull final MapboxMap map) {
- mapboxMap = map;
-
- // add source
- try {
- mapboxMap.addSource(new GeoJsonSource(ID_GEOJSON_SOURCE, new URL(URL_GEOJSON_SOURCE)));
- }catch (MalformedURLException e){
- Log.e(MapboxConstants.TAG, "Invalid URL", e);
- }
-
- // add layer
- SymbolLayer layer = new SymbolLayer(ID_GEOJSON_LAYER, ID_GEOJSON_SOURCE);
- layer.setProperties(iconImage("rocket-15"));
- mapboxMap.addLayer(layer);
-
- // loop refresh geojson
- handler = new Handler();
- runnable = new RefreshGeoJsonRunnable(mapboxMap, handler);
- handler.postDelayed(runnable, 2000);
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
- @Override
- protected void onStop() {
- super.onStop();
- handler.removeCallbacks(runnable);
- }
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(this);
+ }
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
+ @Override
+ public void onMapReady(@NonNull final MapboxMap map) {
+ mapboxMap = map;
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
+ // add source
+ try {
+ mapboxMap.addSource(new GeoJsonSource(ID_GEOJSON_SOURCE, new URL(URL_GEOJSON_SOURCE)));
+ } catch (MalformedURLException malformedUrlException) {
+ Timber.e("Invalid URL", malformedUrlException);
}
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
+ // add layer
+ SymbolLayer layer = new SymbolLayer(ID_GEOJSON_LAYER, ID_GEOJSON_SOURCE);
+ layer.setProperties(iconImage("rocket-15"));
+ mapboxMap.addLayer(layer);
+
+ // loop refresh geojson
+ handler = new Handler();
+ runnable = new RefreshGeoJsonRunnable(mapboxMap, handler);
+ handler.postDelayed(runnable, 2000);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ handler.removeCallbacks(runnable);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
- private static class RefreshGeoJsonRunnable implements Runnable {
+ private static class RefreshGeoJsonRunnable implements Runnable {
- private MapboxMap mapboxMap;
- private Handler handler;
+ private MapboxMap mapboxMap;
+ private Handler handler;
- RefreshGeoJsonRunnable(MapboxMap mapboxMap, Handler handler) {
- this.mapboxMap = mapboxMap;
- this.handler = handler;
- }
+ RefreshGeoJsonRunnable(MapboxMap mapboxMap, Handler handler) {
+ this.mapboxMap = mapboxMap;
+ this.handler = handler;
+ }
- @Override
- public void run() {
- ((GeoJsonSource) mapboxMap.getSource(ID_GEOJSON_SOURCE)).setUrl(URL_GEOJSON_SOURCE);
- handler.postDelayed(this, 2000);
- }
+ @Override
+ public void run() {
+ ((GeoJsonSource) mapboxMap.getSource(ID_GEOJSON_SOURCE)).setUrl(URL_GEOJSON_SOURCE);
+ handler.postDelayed(this, 2000);
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleActivity.java
index efe82ee9a6..2ac3a6fb00 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleActivity.java
@@ -7,7 +7,6 @@ import android.support.annotation.RawRes;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
-import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
@@ -44,7 +43,8 @@ import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
-import static android.os.Looper.getMainLooper;
+import timber.log.Timber;
+
import static com.mapbox.mapboxsdk.style.layers.Filter.all;
import static com.mapbox.mapboxsdk.style.layers.Filter.eq;
import static com.mapbox.mapboxsdk.style.layers.Filter.gte;
@@ -74,498 +74,513 @@ import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.visibility;
* Sample Activity to show off the runtime style api
*/
public class RuntimeStyleActivity extends AppCompatActivity {
- private static final String TAG = RuntimeStyleActivity.class.getSimpleName();
-
- private MapView mapView;
- private MapboxMap mapboxMap;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_runtime_style);
-
- setupActionBar();
-
- //Initialize map as normal
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
-
- mapView.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(MapboxMap map) {
- //Store for later
- mapboxMap = map;
-
- //Center and Zoom (Amsterdam, zoomed to streets)
- mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(52.379189, 4.899431), 14));
- }
- });
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.menu_runtime_style, menu);
+ private MapView mapView;
+ private MapboxMap mapboxMap;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_runtime_style);
+
+ setupActionBar();
+
+ //Initialize map as normal
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+
+
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(MapboxMap map) {
+ //Store for later
+ mapboxMap = map;
+
+ //Center and Zoom (Amsterdam, zoomed to streets)
+ mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(52.379189, 4.899431), 14));
+ }
+ });
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.menu_runtime_style, menu);
+ return true;
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
return true;
+ case R.id.action_water_color:
+ setWaterColor();
+ return true;
+ case R.id.action_background_opacity:
+ setBackgroundOpacity();
+ return true;
+ case R.id.action_road_avoid_edges:
+ setRoadSymbolPlacement();
+ return true;
+ case R.id.action_layer_visibility:
+ setLayerInvisible();
+ return true;
+ case R.id.action_remove_layer:
+ removeBuildings();
+ return true;
+ case R.id.action_add_parks_layer:
+ addParksLayer();
+ return true;
+ case R.id.action_add_dynamic_parks_layer:
+ addDynamicParksLayer();
+ return true;
+ case R.id.action_add_terrain_layer:
+ addTerrainLayer();
+ return true;
+ case R.id.action_add_satellite_layer:
+ addSatelliteLayer();
+ return true;
+ case R.id.action_update_water_color_on_zoom:
+ updateWaterColorOnZoom();
+ return true;
+ case R.id.action_add_custom_tiles:
+ addCustomTileSource();
+ return true;
+ case R.id.action_fill_filter:
+ styleFillFilterLayer();
+ return true;
+ case R.id.action_line_filter:
+ styleLineFilterLayer();
+ return true;
+ case R.id.action_numeric_filter:
+ styleNumericFillLayer();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
-
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
+ }
+
+ private void setLayerInvisible() {
+ String[] roadLayers = new String[] {"water"};
+ for (String roadLayer : roadLayers) {
+ Layer layer = mapboxMap.getLayer(roadLayer);
+ if (layer != null) {
+ layer.setProperties(visibility(NONE));
+ }
}
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
+ }
+
+ private void setRoadSymbolPlacement() {
+ //Zoom so that the labels are visible first
+ mapboxMap.animateCamera(CameraUpdateFactory.zoomTo(14), new DefaultCallback() {
+ @Override
+ public void onFinish() {
+ String[] roadLayers = new String[] {"road-label-small", "road-label-medium", "road-label-large"};
+ for (String roadLayer : roadLayers) {
+ Layer layer = mapboxMap.getLayer(roadLayer);
+ if (layer != null) {
+ layer.setProperties(symbolPlacement(SYMBOL_PLACEMENT_POINT));
+ }
+ }
+ }
+ });
+ }
+
+ private void setBackgroundOpacity() {
+ Layer background = mapboxMap.getLayer("background");
+ if (background != null) {
+ background.setProperties(backgroundOpacity(0.2f));
}
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
+ }
+
+ private void setWaterColor() {
+ Layer water = mapboxMap.getLayer("water");
+ if (water != null) {
+ water.setProperties(
+ visibility(VISIBLE),
+ fillColor(Color.RED)
+ );
+ } else {
+ Toast.makeText(RuntimeStyleActivity.this, "No water layer in this style", Toast.LENGTH_SHORT).show();
}
-
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
+ }
+
+ private void removeBuildings() {
+ //Zoom to see buildings first
+ try {
+ mapboxMap.removeLayer("building");
+ } catch (NoSuchLayerException noSuchLayerException) {
+ Toast.makeText(RuntimeStyleActivity.this, noSuchLayerException.getMessage(), Toast.LENGTH_SHORT).show();
}
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- case R.id.action_water_color:
- setWaterColor();
- return true;
- case R.id.action_background_opacity:
- setBackgroundOpacity();
- return true;
- case R.id.action_road_avoid_edges:
- setRoadSymbolPlacement();
- return true;
- case R.id.action_layer_visibility:
- setLayerInvisible();
- return true;
- case R.id.action_remove_layer:
- removeBuildings();
- return true;
- case R.id.action_add_parks_layer:
- addParksLayer();
- return true;
- case R.id.action_add_dynamic_parks_layer:
- addDynamicParksLayer();
- return true;
- case R.id.action_add_terrain_layer:
- addTerrainLayer();
- return true;
- case R.id.action_add_satellite_layer:
- addSatelliteLayer();
- return true;
- case R.id.action_update_water_color_on_zoom:
- updateWaterColorOnZoom();
- return true;
- case R.id.action_add_custom_tiles:
- addCustomTileSource();
- return true;
- case R.id.action_fill_filter:
- styleFillFilterLayer();
- return true;
- case R.id.action_line_filter:
- styleLineFilterLayer();
- return true;
- case R.id.action_numeric_filter:
- styleNumericFillLayer();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
+ }
+
+ private void addParksLayer() {
+ //Add a source
+ Source source;
+ try {
+ source = new GeoJsonSource("amsterdam-spots", readRawResource(R.raw.amsterdam));
+ } catch (IOException ioException) {
+ Toast.makeText(
+ RuntimeStyleActivity.this,
+ "Couldn't add source: " + ioException.getMessage(),
+ Toast.LENGTH_SHORT).show();
+ return;
}
- private void setLayerInvisible() {
- String[] roadLayers = new String[]{"water"};
- for (String roadLayer : roadLayers) {
- Layer layer = mapboxMap.getLayer(roadLayer);
- if (layer != null) {
- layer.setProperties(visibility(NONE));
- }
- }
+ mapboxMap.addSource(source);
+
+ FillLayer layer = new FillLayer("parksLayer", "amsterdam-spots");
+ layer.setProperties(
+ fillColor(Color.RED),
+ fillOutlineColor(Color.BLUE),
+ fillOpacity(0.3f),
+ fillAntialias(true)
+ );
+
+ //Only show me parks (except westerpark with stroke-width == 3)
+ layer.setFilter(all(eq("type", "park"), eq("stroke-width", 2)));
+
+ mapboxMap.addLayer(layer, "building");
+ //layer.setPaintProperty(fillColor(Color.RED)); //XXX But not after the object is attached
+
+ //Or get the object later and set it. It's all good.
+ mapboxMap.getLayer("parksLayer").setProperties(fillColor(Color.RED));
+
+ //You can get a typed layer, if you're sure it's of that type. Use with care
+ layer = mapboxMap.getLayerAs("parksLayer");
+ //And get some properties
+ PropertyValue<Boolean> fillAntialias = layer.getFillAntialias();
+ Timber.d("Fill anti alias: " + fillAntialias.getValue());
+ layer.setProperties(fillTranslateAnchor(FILL_TRANSLATE_ANCHOR_MAP));
+ PropertyValue<String> fillTranslateAnchor = layer.getFillTranslateAnchor();
+ Timber.d("Fill translate anchor: " + fillTranslateAnchor.getValue());
+ PropertyValue<String> visibility = layer.getVisibility();
+ Timber.d("Visibility: " + visibility.getValue());
+
+ //Get a good look at it all
+ mapboxMap.animateCamera(CameraUpdateFactory.zoomTo(12));
+ }
+
+ private void addDynamicParksLayer() {
+ //Load some data
+ FeatureCollection parks;
+ try {
+ String json = readRawResource(R.raw.amsterdam);
+ parks = FeatureCollection.fromJson(json);
+ } catch (IOException ioException) {
+ Toast.makeText(
+ RuntimeStyleActivity.this,
+ "Couldn't add source: " + ioException.getMessage(),
+ Toast.LENGTH_SHORT
+ ).show();
+ return;
}
- private void setRoadSymbolPlacement() {
- //Zoom so that the labels are visible first
- mapboxMap.animateCamera(CameraUpdateFactory.zoomTo(14), new DefaultCallback() {
- @Override
- public void onFinish() {
- String[] roadLayers = new String[]{"road-label-small", "road-label-medium", "road-label-large"};
- for (String roadLayer : roadLayers) {
- Layer layer = mapboxMap.getLayer(roadLayer);
- if (layer != null) {
- layer.setProperties(symbolPlacement(SYMBOL_PLACEMENT_POINT));
- }
- }
- }
- });
- }
+ //Add an empty source
+ mapboxMap.addSource(new GeoJsonSource("dynamic-park-source"));
- private void setBackgroundOpacity() {
- Layer background = mapboxMap.getLayer("background");
- if (background != null) {
- background.setProperties(backgroundOpacity(0.2f));
- }
- }
+ FillLayer layer = new FillLayer("dynamic-parks-layer", "dynamic-park-source");
+ layer.setProperties(
+ fillColor(Color.GREEN),
+ fillOutlineColor(Color.GREEN),
+ fillOpacity(0.8f),
+ fillAntialias(true)
+ );
- private void setWaterColor() {
- Layer water = mapboxMap.getLayer("water");
- if (water != null) {
- water.setProperties(
- visibility(VISIBLE),
- fillColor(Color.RED)
- );
- } else {
- Toast.makeText(RuntimeStyleActivity.this, "No water layer in this style", Toast.LENGTH_SHORT).show();
- }
- }
+ //Only show me parks
+ layer.setFilter(all(eq("type", "park")));
- private void removeBuildings() {
- //Zoom to see buildings first
- try {
- mapboxMap.removeLayer("building");
- } catch (NoSuchLayerException noSuchLayerException) {
- Toast.makeText(RuntimeStyleActivity.this, noSuchLayerException.getMessage(), Toast.LENGTH_SHORT).show();
- }
- }
+ mapboxMap.addLayer(layer);
- private void addParksLayer() {
- //Add a source
- Source source;
- try {
- source = new GeoJsonSource("amsterdam-spots", readRawResource(R.raw.amsterdam));
- } catch (IOException ioException) {
- Toast.makeText(
- RuntimeStyleActivity.this,
- "Couldn't add source: " + ioException.getMessage(),
- Toast.LENGTH_SHORT).show();
- return;
- }
+ //Get a good look at it all
+ mapboxMap.animateCamera(CameraUpdateFactory.zoomTo(12));
- mapboxMap.addSource(source);
-
- FillLayer layer = new FillLayer("parksLayer", "amsterdam-spots");
- layer.setProperties(
- fillColor(Color.RED),
- fillOutlineColor(Color.BLUE),
- fillOpacity(0.3f),
- fillAntialias(true)
- );
-
- //Only show me parks (except westerpark with stroke-width == 3)
- layer.setFilter(all(eq("type", "park"), eq("stroke-width", 2)));
-
- mapboxMap.addLayer(layer, "building");
- //layer.setPaintProperty(fillColor(Color.RED)); //XXX But not after the object is attached
-
- //Or get the object later and set it. It's all good.
- mapboxMap.getLayer("parksLayer").setProperties(fillColor(Color.RED));
-
- //You can get a typed layer, if you're sure it's of that type. Use with care
- layer = mapboxMap.getLayerAs("parksLayer");
- //And get some properties
- PropertyValue<Boolean> fillAntialias = layer.getFillAntialias();
- Log.d(TAG, "Fill anti alias: " + fillAntialias.getValue());
- layer.setProperties(fillTranslateAnchor(FILL_TRANSLATE_ANCHOR_MAP));
- PropertyValue<String> fillTranslateAnchor = layer.getFillTranslateAnchor();
- Log.d(TAG, "Fill translate anchor: " + fillTranslateAnchor.getValue());
- PropertyValue<String> visibility = layer.getVisibility();
- Log.d(TAG, "Visibility: " + visibility.getValue());
-
- //Get a good look at it all
- mapboxMap.animateCamera(CameraUpdateFactory.zoomTo(12));
- }
+ //Animate the parks source
+ animateParksSource(parks, 0);
+ }
- private void addDynamicParksLayer() {
- //Load some data
- FeatureCollection parks;
- try {
- String json = readRawResource(R.raw.amsterdam);
- parks = FeatureCollection.fromJson(json);
- } catch (IOException e) {
- Toast.makeText(RuntimeStyleActivity.this, "Couldn't add source: " + e.getMessage(), Toast.LENGTH_SHORT).show();
- return;
+ private void animateParksSource(final FeatureCollection parks, final int counter) {
+ Handler handler = new Handler(getMainLooper());
+ handler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ if (mapboxMap == null) {
+ return;
}
- //Add an empty source
- mapboxMap.addSource(new GeoJsonSource("dynamic-park-source"));
+ Timber.d("Updating parks source");
+ //change the source
+ int park = counter < parks.getFeatures().size() - 1 ? counter : 0;
- FillLayer layer = new FillLayer("dynamic-parks-layer", "dynamic-park-source");
- layer.setProperties(
- fillColor(Color.GREEN),
- fillOutlineColor(Color.GREEN),
- fillOpacity(0.8f),
- fillAntialias(true)
- );
+ GeoJsonSource source = mapboxMap.getSourceAs("dynamic-park-source");
- //Only show me parks
- layer.setFilter(all(eq("type", "park")));
-
- mapboxMap.addLayer(layer);
-
- //Get a good look at it all
- mapboxMap.animateCamera(CameraUpdateFactory.zoomTo(12));
+ if (source == null) {
+ Timber.e("Source not found");
+ Toast.makeText(RuntimeStyleActivity.this, "Source not found", Toast.LENGTH_SHORT).show();
+ return;
+ }
- //Animate the parks source
- animateParksSource(parks, 0);
+ List<Feature> features = new ArrayList<>();
+ features.add(parks.getFeatures().get(park));
+ source.setGeoJson(FeatureCollection.fromFeatures(features));
+
+ //Re-post
+ animateParksSource(parks, park + 1);
+ }
+ }, counter == 0 ? 100 : 1000);
+ }
+
+ private void addTerrainLayer() {
+ //Add a source
+ Source source = new VectorSource("my-terrain-source", "mapbox://mapbox.mapbox-terrain-v2");
+ mapboxMap.addSource(source);
+
+ LineLayer layer = new LineLayer("terrainLayer", "my-terrain-source");
+ layer.setSourceLayer("contour");
+ layer.setProperties(
+ lineJoin(Property.LINE_JOIN_ROUND),
+ lineCap(Property.LINE_CAP_ROUND),
+ lineColor(Color.RED),
+ lineWidth(20f)
+ );
+
+ mapboxMap.addLayer(layer);
+
+ //Need to get a fresh handle
+ layer = mapboxMap.getLayerAs("terrainLayer");
+
+ //Make sure it's also applied after the fact
+ layer.setMinZoom(10);
+ layer.setMaxZoom(15);
+
+ layer = (LineLayer) mapboxMap.getLayer("terrainLayer");
+ Toast.makeText(this, String.format(
+ "Set min/max zoom to %s - %s", layer.getMinZoom(), layer.getMaxZoom()), Toast.LENGTH_SHORT).show();
+ }
+
+ private void addSatelliteLayer() {
+ //Add a source
+ Source source = new RasterSource("my-raster-source", "mapbox://mapbox.satellite", 512);
+ mapboxMap.addSource(source);
+
+ //Add a layer
+ mapboxMap.addLayer(new RasterLayer("satellite-layer", "my-raster-source"));
+ }
+
+ private void updateWaterColorOnZoom() {
+ FillLayer layer = mapboxMap.getLayerAs("water");
+ if (layer == null) {
+ return;
}
- private void animateParksSource(final FeatureCollection parks, final int counter) {
- Handler handler = new Handler(getMainLooper());
- handler.postDelayed(new Runnable() {
- @Override
- public void run() {
- if (mapboxMap == null) {
- return;
- }
-
- Log.d(TAG, "Updating parks source");
- //change the source
- int park = counter < parks.getFeatures().size() - 1 ? counter : 0;
-
- GeoJsonSource source = mapboxMap.getSourceAs("dynamic-park-source");
-
- if (source == null) {
- Log.e(TAG, "Source not found");
- Toast.makeText(RuntimeStyleActivity.this, "Source not found", Toast.LENGTH_SHORT).show();
- return;
- }
-
- List<Feature> features = new ArrayList<>();
- features.add(parks.getFeatures().get(park));
- source.setGeoJson(FeatureCollection.fromFeatures(features));
-
- //Re-post
- animateParksSource(parks, park + 1);
- }
- }, counter == 0 ? 100 : 1000);
+ //Set a zoom function to update the color of the water
+ layer.setProperties(fillColor(zoom(0.8f,
+ stop(1, fillColor(Color.GREEN)),
+ stop(4, fillColor(Color.BLUE)),
+ stop(12, fillColor(Color.RED)),
+ stop(20, fillColor(Color.BLACK))
+ )));
+
+ //do some animations to show it off properly
+ mapboxMap.animateCamera(CameraUpdateFactory.zoomTo(1), 1500);
+
+ PropertyValue<String> fillColor = layer.getFillColor();
+ Function<String> function = fillColor.getFunction();
+ if (function != null) {
+ Timber.d("Fill color base: " + function.getBase());
+ Timber.d("Fill color #stops: " + function.getStops().length);
+ if (function.getStops() != null) {
+ for (Stop stop : function.getStops()) {
+ Timber.d("Fill color #stops: " + stop);
+ }
+ }
+ }
+ }
+
+ private String readRawResource(@RawRes int rawResource) throws IOException {
+ InputStream is = getResources().openRawResource(rawResource);
+ Writer writer = new StringWriter();
+ char[] buffer = new char[1024];
+ try {
+ Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+ int numRead;
+ while ((numRead = reader.read(buffer)) != -1) {
+ writer.write(buffer, 0, numRead);
+ }
+ } finally {
+ is.close();
}
- private void addTerrainLayer() {
- //Add a source
- Source source = new VectorSource("my-terrain-source", "mapbox://mapbox.mapbox-terrain-v2");
- mapboxMap.addSource(source);
-
- LineLayer layer = new LineLayer("terrainLayer", "my-terrain-source");
- layer.setSourceLayer("contour");
- layer.setProperties(
- lineJoin(Property.LINE_JOIN_ROUND),
- lineCap(Property.LINE_CAP_ROUND),
- lineColor(Color.RED),
- lineWidth(20f)
- );
-
- mapboxMap.addLayer(layer);
-
- //Need to get a fresh handle
- layer = mapboxMap.getLayerAs("terrainLayer");
+ return writer.toString();
+ }
- //Make sure it's also applied after the fact
- layer.setMinZoom(10);
- layer.setMaxZoom(15);
+ private void setupActionBar() {
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- layer = (LineLayer) mapboxMap.getLayer("terrainLayer");
- Toast.makeText(this, String.format(
- "Set min/max zoom to %s - %s", layer.getMinZoom(), layer.getMaxZoom()), Toast.LENGTH_SHORT).show();
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
+ }
+
+ private void addCustomTileSource() {
+ //Add a source
+ Source source = new VectorSource("custom-tile-source", new TileSet("2.1.0", "https://vector.mapzen.com/osm/all/{z}/{x}/{y}.mvt?api_key=vector-tiles-LM25tq4"));
+ mapboxMap.addSource(source);
+
+ //Add a layer
+ mapboxMap.addLayer(
+ new FillLayer("custom-tile-layers", "custom-tile-source")
+ .withSourceLayer("water")
+ );
+ }
+
+ private void styleFillFilterLayer() {
+ mapboxMap.setStyleUrl("asset://fill_filter_style.json");
+ mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(31, -100), 3));
+
+ Handler handler = new Handler(getMainLooper());
+ handler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ if (mapboxMap == null) {
+ return;
+ }
- private void addSatelliteLayer() {
- //Add a source
- Source source = new RasterSource("my-raster-source", "mapbox://mapbox.satellite", 512);
- mapboxMap.addSource(source);
+ Timber.d("Styling filtered fill layer");
- //Add a layer
- mapboxMap.addLayer(new RasterLayer("satellite-layer", "my-raster-source"));
- }
+ FillLayer states = (FillLayer) mapboxMap.getLayer("states");
- private void updateWaterColorOnZoom() {
- FillLayer layer = mapboxMap.getLayerAs("water");
- if (layer == null) {
- return;
- }
+ if (states != null) {
+ states.setFilter(eq("name", "Texas"));
- //Set a zoom function to update the color of the water
- layer.setProperties(fillColor(zoom(0.8f,
- stop(1, fillColor(Color.GREEN)),
- stop(4, fillColor(Color.BLUE)),
- stop(12, fillColor(Color.RED)),
- stop(20, fillColor(Color.BLACK))
- )));
-
- //do some animations to show it off properly
- mapboxMap.animateCamera(CameraUpdateFactory.zoomTo(1), 1500);
-
- PropertyValue<String> fillColor = layer.getFillColor();
- Function<String> function = fillColor.getFunction();
- if (function != null) {
- Log.d(TAG, "Fill color base: " + function.getBase());
- Log.d(TAG, "Fill color #stops: " + function.getStops().length);
- if (function.getStops() != null) {
- for (Stop stop : function.getStops()) {
- Log.d(TAG, "Fill color #stops: " + stop);
- }
- }
+ states.setProperties(
+ fillColor(Color.RED),
+ fillOpacity(0.25f)
+ );
+ } else {
+ Toast.makeText(RuntimeStyleActivity.this, "No states layer in this style", Toast.LENGTH_SHORT).show();
}
- }
-
- private String readRawResource(@RawRes int rawResource) throws IOException {
- InputStream is = getResources().openRawResource(rawResource);
- Writer writer = new StringWriter();
- char[] buffer = new char[1024];
- try {
- Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
- int n;
- while ((n = reader.read(buffer)) != -1) {
- writer.write(buffer, 0, n);
- }
- } finally {
- is.close();
+ }
+ }, 2000);
+ }
+
+ private void styleLineFilterLayer() {
+ mapboxMap.setStyleUrl("asset://line_filter_style.json");
+ mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(40, -97), 5));
+
+ Handler handler = new Handler(getMainLooper());
+ handler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ if (mapboxMap == null) {
+ return;
}
- return writer.toString();
- }
+ Timber.d("Styling filtered line layer");
+
+ LineLayer counties = (LineLayer) mapboxMap.getLayer("counties");
- private void setupActionBar() {
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
+ if (counties != null) {
+ counties.setFilter(eq("NAME10", "Washington"));
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
+ counties.setProperties(
+ lineColor(Color.RED),
+ lineOpacity(0.75f),
+ lineWidth(5f)
+ );
+ } else {
+ Toast.makeText(RuntimeStyleActivity.this, "No counties layer in this style", Toast.LENGTH_SHORT).show();
+ }
+ }
+ }, 2000);
+ }
+
+ private void styleNumericFillLayer() {
+ mapboxMap.setStyleUrl("asset://numeric_filter_style.json");
+ mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(40, -97), 5));
+
+ Handler handler = new Handler(getMainLooper());
+ handler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ if (mapboxMap == null) {
+ return;
}
- }
- private void addCustomTileSource() {
- //Add a source
- Source source = new VectorSource("custom-tile-source", new TileSet("2.1.0", "https://vector.mapzen.com/osm/all/{z}/{x}/{y}.mvt?api_key=vector-tiles-LM25tq4"));
- mapboxMap.addSource(source);
+ Timber.d("Styling numeric fill layer");
- //Add a layer
- mapboxMap.addLayer(
- new FillLayer("custom-tile-layers", "custom-tile-source")
- .withSourceLayer("water")
- );
- }
+ FillLayer regions = (FillLayer) mapboxMap.getLayer("regions");
- private void styleFillFilterLayer() {
- mapboxMap.setStyleUrl("asset://fill_filter_style.json");
- mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(31, -100), 3));
-
- Handler handler = new Handler(getMainLooper());
- handler.postDelayed(new Runnable() {
- @Override
- public void run() {
- if (mapboxMap == null) {
- return;
- }
-
- Log.d(TAG, "Styling filtered fill layer");
-
- FillLayer states = (FillLayer) mapboxMap.getLayer("states");
-
- if (states != null) {
- states.setFilter(eq("name", "Texas"));
-
- states.setProperties(
- fillColor(Color.RED),
- fillOpacity(0.25f)
- );
- } else {
- Toast.makeText(RuntimeStyleActivity.this, "No states layer in this style", Toast.LENGTH_SHORT).show();
- }
- }
- }, 2000);
- }
+ if (regions != null) {
+ regions.setFilter(all(gte("HRRNUM", 200), lt("HRRNUM", 300)));
- private void styleLineFilterLayer() {
- mapboxMap.setStyleUrl("asset://line_filter_style.json");
- mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(40, -97), 5));
-
- Handler handler = new Handler(getMainLooper());
- handler.postDelayed(new Runnable() {
- @Override
- public void run() {
- if (mapboxMap == null) {
- return;
- }
-
- Log.d(TAG, "Styling filtered line layer");
-
- LineLayer counties = (LineLayer) mapboxMap.getLayer("counties");
-
- if (counties != null) {
- counties.setFilter(eq("NAME10", "Washington"));
-
- counties.setProperties(
- lineColor(Color.RED),
- lineOpacity(0.75f),
- lineWidth(5f)
- );
- } else {
- Toast.makeText(RuntimeStyleActivity.this, "No counties layer in this style", Toast.LENGTH_SHORT).show();
- }
- }
- }, 2000);
- }
-
- private void styleNumericFillLayer() {
- mapboxMap.setStyleUrl("asset://numeric_filter_style.json");
- mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(40, -97), 5));
-
- Handler handler = new Handler(getMainLooper());
- handler.postDelayed(new Runnable() {
- @Override
- public void run() {
- if (mapboxMap == null) {
- return;
- }
-
- Log.d(TAG, "Styling numeric fill layer");
-
- FillLayer regions = (FillLayer) mapboxMap.getLayer("regions");
-
- if (regions != null) {
- regions.setFilter(all(gte("HRRNUM", 200), lt("HRRNUM", 300)));
-
- regions.setProperties(
- fillColor(Color.BLUE),
- fillOpacity(0.5f)
- );
- } else {
- Toast.makeText(RuntimeStyleActivity.this, "No regions layer in this style", Toast.LENGTH_SHORT).show();
- }
- }
- }, 2000);
- }
+ regions.setProperties(
+ fillColor(Color.BLUE),
+ fillOpacity(0.5f)
+ );
+ } else {
+ Toast.makeText(RuntimeStyleActivity.this, "No regions layer in this style", Toast.LENGTH_SHORT).show();
+ }
+ }
+ }, 2000);
+ }
- private static class DefaultCallback implements MapboxMap.CancelableCallback {
+ private static class DefaultCallback implements MapboxMap.CancelableCallback {
- @Override
- public void onCancel() {
- //noop
- }
+ @Override
+ public void onCancel() {
+ //noop
+ }
- @Override
- public void onFinish() {
- //noop
- }
+ @Override
+ public void onFinish() {
+ //noop
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleTestActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleTestActivity.java
index 6f04852ca1..1d242359bc 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleTestActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleTestActivity.java
@@ -12,58 +12,69 @@ import com.mapbox.mapboxsdk.testapp.R;
* Test activity for unit test execution
*/
public class RuntimeStyleTestActivity extends AppCompatActivity {
- private static final String TAG = RuntimeStyleTestActivity.class.getSimpleName();
- public MapView mapView;
- private MapboxMap mapboxMap;
+ public MapView mapView;
+ private MapboxMap mapboxMap;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_runtime_style);
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_runtime_style);
- //Initialize map as normal
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(MapboxMap mapboxMap) {
- RuntimeStyleTestActivity.this.mapboxMap = mapboxMap;
- }
- });
- }
+ //Initialize map as normal
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(MapboxMap mapboxMap) {
+ RuntimeStyleTestActivity.this.mapboxMap = mapboxMap;
+ }
+ });
+ }
- public MapboxMap getMapboxMap() {
- return mapboxMap;
- }
+ public MapboxMap getMapboxMap() {
+ return mapboxMap;
+ }
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
- }
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- }
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
- }
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleTimingTestActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleTimingTestActivity.java
index 83378148ae..c57bc0069a 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleTimingTestActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleTimingTestActivity.java
@@ -20,70 +20,81 @@ import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.visibility;
* Test activity for unit test execution
*/
public class RuntimeStyleTimingTestActivity extends AppCompatActivity {
- private static final String TAG = RuntimeStyleTimingTestActivity.class.getSimpleName();
-
- public MapView mapView;
- private MapboxMap mapboxMap;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_runtime_style);
-
- //Initialize map as normal
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(MapboxMap mapboxMap) {
- RuntimeStyleTimingTestActivity.this.mapboxMap = mapboxMap;
- VectorSource museums = new VectorSource("museums_source", "mapbox://mapbox.2opop9hr");
- mapboxMap.addSource(museums);
-
- CircleLayer museumsLayer = new CircleLayer("museums", "museums_source");
- museumsLayer.setSourceLayer("museum-cusco");
- museumsLayer.setProperties(
- visibility(VISIBLE),
- circleRadius(8f),
- circleColor(Color.argb(1, 55, 148, 179))
- );
-
- mapboxMap.addLayer(museumsLayer);
- }
- });
- }
-
- public MapboxMap getMapboxMap() {
- return mapboxMap;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
-
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
- }
+
+ public MapView mapView;
+ private MapboxMap mapboxMap;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_runtime_style);
+
+ //Initialize map as normal
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(MapboxMap mapboxMap) {
+ RuntimeStyleTimingTestActivity.this.mapboxMap = mapboxMap;
+ VectorSource museums = new VectorSource("museums_source", "mapbox://mapbox.2opop9hr");
+ mapboxMap.addSource(museums);
+
+ CircleLayer museumsLayer = new CircleLayer("museums", "museums_source");
+ museumsLayer.setSourceLayer("museum-cusco");
+ museumsLayer.setProperties(
+ visibility(VISIBLE),
+ circleRadius(8f),
+ circleColor(Color.argb(1, 55, 148, 179))
+ );
+
+ mapboxMap.addLayer(museumsLayer);
+ }
+ });
+ }
+
+ public MapboxMap getMapboxMap() {
+ return mapboxMap;
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/StyleFileActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/StyleFileActivity.java
index aa739be229..73e6bc985a 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/StyleFileActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/StyleFileActivity.java
@@ -9,7 +9,6 @@ import android.support.v4.content.ContextCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
-import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
@@ -30,14 +29,12 @@ import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
-import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleColor;
-import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.circleRadius;
+import timber.log.Timber;
/**
* Example on how to use a file:// resource for the style.json
*/
public class StyleFileActivity extends AppCompatActivity {
- private static final String TAG = StyleFileActivity.class.getSimpleName();
private MapboxMap mapboxMap;
private MapView mapView;
@@ -68,7 +65,7 @@ public class StyleFileActivity extends AppCompatActivity {
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
- Log.i(TAG, "Loading style file");
+ Timber.i("Loading style file");
new CreateStyleFileTask().execute();
}
});
@@ -87,12 +84,12 @@ public class StyleFileActivity extends AppCompatActivity {
try {
cacheStyleFile = File.createTempFile("my-", ".style.json");
cacheStyleFile.createNewFile();
- Log.i(TAG, "Writing style file to: " + cacheStyleFile.getAbsolutePath());
+ Timber.i("Writing style file to: " + cacheStyleFile.getAbsolutePath());
writeToFile(cacheStyleFile, readRawResource(R.raw.local_style));
- } catch (Exception e) {
+ } catch (Exception exception) {
Toast.makeText(StyleFileActivity.this, "Could not create style file in cache dir", Toast.LENGTH_SHORT).show();
}
- return 1l;
+ return 1L;
}
protected void onPostExecute(Long result) {
@@ -106,9 +103,9 @@ public class StyleFileActivity extends AppCompatActivity {
char[] buffer = new char[1024];
try {
Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
- int n;
- while ((n = reader.read(buffer)) != -1) {
- writer.write(buffer, 0, n);
+ int numRead;
+ while ((numRead = reader.read(buffer)) != -1) {
+ writer.write(buffer, 0, numRead);
}
} finally {
is.close();
@@ -131,18 +128,30 @@ public class StyleFileActivity extends AppCompatActivity {
}
@Override
- public void onResume() {
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
super.onResume();
mapView.onResume();
}
@Override
- public void onPause() {
+ protected void onPause() {
super.onPause();
mapView.onPause();
}
@Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/SymbolLayerActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/SymbolLayerActivity.java
new file mode 100644
index 0000000000..be71e58eba
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/SymbolLayerActivity.java
@@ -0,0 +1,215 @@
+package com.mapbox.mapboxsdk.testapp.activity.style;
+
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.PointF;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.Toolbar;
+import android.view.Menu;
+import android.view.MenuItem;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.maps.MapView;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
+import com.mapbox.mapboxsdk.style.layers.SymbolLayer;
+import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;
+import com.mapbox.mapboxsdk.testapp.R;
+import com.mapbox.services.commons.geojson.Feature;
+import com.mapbox.services.commons.geojson.FeatureCollection;
+import com.mapbox.services.commons.geojson.Point;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconAllowOverlap;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconImage;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconSize;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textColor;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textField;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textFont;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textSize;
+
+/**
+ * Example to test runtime manipulation of symbol layers
+ */
+public class SymbolLayerActivity extends AppCompatActivity implements MapboxMap.OnMapClickListener {
+
+ public static final String MARKER_SOURCE = "marker-source";
+ public static final String MARKER_LAYER = "marker-layer";
+ private MapboxMap mapboxMap;
+ private MapView mapView;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_symbollayer);
+
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
+ }
+
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(@NonNull final MapboxMap map) {
+ mapboxMap = map;
+
+ //Add a image for the makers
+ mapboxMap.addImage(
+ "my-marker-image",
+ BitmapFactory.decodeResource(SymbolLayerActivity.this.getResources(),
+ R.drawable.mapbox_marker_icon_default)
+ );
+
+ //Add a source
+ FeatureCollection markers = FeatureCollection.fromFeatures(new Feature[] {
+ Feature.fromGeometry(Point.fromCoordinates(new double[] {4.91638, 52.35673}), featureProperties("Marker 1")),
+ Feature.fromGeometry(Point.fromCoordinates(new double[] {4.91638, 52.34673}), featureProperties("Marker 2"))
+ });
+ mapboxMap.addSource(new GeoJsonSource(MARKER_SOURCE, markers));
+
+ //Add the symbol-layer
+ mapboxMap.addLayer(
+ new SymbolLayer(MARKER_LAYER, MARKER_SOURCE)
+ .withProperties(
+ iconImage("my-marker-image"),
+ iconAllowOverlap(true),
+ textField("{title}"),
+ textColor(Color.RED),
+ textSize(10f)
+ )
+ );
+
+ //Show
+ mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(52.35273, 4.91638), 14));
+
+ //Set a click-listener so we can manipulate the map
+ mapboxMap.setOnMapClickListener(SymbolLayerActivity.this);
+ }
+ });
+ }
+
+ @Override
+ public void onMapClick(@NonNull LatLng point) {
+ //Query which features are clicked
+ PointF screenLoc = mapboxMap.getProjection().toScreenLocation(point);
+ List<Feature> features = mapboxMap.queryRenderedFeatures(screenLoc, MARKER_LAYER);
+
+ SymbolLayer layer = mapboxMap.getLayerAs(MARKER_LAYER);
+ if (features.size() == 0) {
+ //Reset
+ layer.setProperties(iconSize(1f));
+ } else {
+ layer.setProperties(iconSize(3f));
+ }
+ }
+
+ private void toggleTextSize() {
+ SymbolLayer layer = mapboxMap.getLayerAs(MARKER_LAYER);
+ layer.setProperties(layer.getTextSize().getValue() > 10 ? textSize(10f) : textSize(20f));
+ }
+
+ private void toggleTextField() {
+ SymbolLayer layer = mapboxMap.getLayerAs(MARKER_LAYER);
+ layer.setProperties("{title}".equals(layer.getTextField().getValue()) ? textField("āA") : textField("{title}"));
+ }
+
+ private void toggleTextFont() {
+ SymbolLayer layer = mapboxMap.getLayerAs(MARKER_LAYER);
+
+ String[] fonts = layer.getTextFont().getValue();
+ if (fonts == null || fonts.length == 0 || Arrays.asList(fonts).contains("Arial Unicode MS Regular")) {
+ layer.setProperties(textFont(new String[] {"DIN Offc Pro Bold", "Arial Unicode MS Bold"}));
+ } else {
+ layer.setProperties(textFont(new String[] {"DIN Offc Pro Medium", "Arial Unicode MS Regular"}));
+ }
+ }
+
+ private JsonObject featureProperties(String title) {
+ JsonObject object = new JsonObject();
+ object.add("title", new JsonPrimitive(title));
+ return object;
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.menu_symbol_layer, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ case R.id.action_toggle_text_size:
+ toggleTextSize();
+ return true;
+ case R.id.action_toggle_text_field:
+ toggleTextField();
+ return true;
+ case R.id.action_toggle_text_font:
+ toggleTextFont();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+ }
+
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationDrawableActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationDrawableActivity.java
index 301636611c..e20455b1ce 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationDrawableActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationDrawableActivity.java
@@ -29,142 +29,154 @@ import com.mapbox.mapboxsdk.testapp.R;
public class MyLocationDrawableActivity extends AppCompatActivity implements LocationListener {
- private static final int PERMISSIONS_LOCATION = 0;
-
- private MapView mapView;
- private MapboxMap mapboxMap;
-
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_my_location_customization);
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
-
- final ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- findViewById(R.id.progress).setVisibility(View.GONE);
-
- MapboxMapOptions mapboxMapOptions = new MapboxMapOptions();
- mapboxMapOptions.styleUrl(Style.MAPBOX_STREETS);
-
- // configure MyLocationView drawables
- mapboxMapOptions.myLocationForegroundDrawable(ContextCompat.getDrawable(this, R.drawable.ic_chelsea));
- mapboxMapOptions.myLocationBackgroundDrawable(ContextCompat.getDrawable(this, R.drawable.ic_arsenal));
- mapboxMapOptions.myLocationForegroundTintColor(Color.GREEN);
- mapboxMapOptions.myLocationBackgroundTintColor(Color.YELLOW);
- mapboxMapOptions.myLocationBackgroundPadding(new int[]{0, 0,
- (int) getResources().getDimension(R.dimen.locationview_background_drawable_padding),
- (int) getResources().getDimension(R.dimen.locationview_background_drawable_padding)});
-
- mapboxMapOptions.myLocationAccuracyTint(Color.RED);
- mapboxMapOptions.myLocationAccuracyAlpha(155);
-
- mapView = new MapView(this, mapboxMapOptions);
- mapView.setId(R.id.mapView);
- ViewGroup parent = (ViewGroup) findViewById(R.id.container);
- parent.addView(mapView);
-
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(MapboxMap map) {
- mapboxMap = map;
- toggleGps(true);
- }
- });
+ private static final int PERMISSIONS_LOCATION = 0;
+
+ private MapView mapView;
+ private MapboxMap mapboxMap;
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_my_location_customization);
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+
+ final ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
- public void toggleGps(boolean enableGps) {
- if (enableGps) {
- if ((ContextCompat.checkSelfPermission(this,
- Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
- || (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
- != PackageManager.PERMISSION_GRANTED)) {
- ActivityCompat.requestPermissions(this, new String[]{
- Manifest.permission.ACCESS_COARSE_LOCATION,
- Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_LOCATION);
- } else {
- enableLocation(true);
- }
- } else {
- enableLocation(false);
- }
+ findViewById(R.id.progress).setVisibility(View.GONE);
+
+ MapboxMapOptions mapboxMapOptions = new MapboxMapOptions();
+ mapboxMapOptions.styleUrl(Style.MAPBOX_STREETS);
+
+ // configure MyLocationView drawables
+ mapboxMapOptions.myLocationForegroundDrawable(ContextCompat.getDrawable(this, R.drawable.ic_chelsea));
+ mapboxMapOptions.myLocationBackgroundDrawable(ContextCompat.getDrawable(this, R.drawable.ic_arsenal));
+ mapboxMapOptions.myLocationForegroundTintColor(Color.GREEN);
+ mapboxMapOptions.myLocationBackgroundTintColor(Color.YELLOW);
+ mapboxMapOptions.myLocationBackgroundPadding(new int[] {0, 0,
+ (int) getResources().getDimension(R.dimen.locationview_background_drawable_padding),
+ (int) getResources().getDimension(R.dimen.locationview_background_drawable_padding)});
+
+ mapboxMapOptions.myLocationAccuracyTint(Color.RED);
+ mapboxMapOptions.myLocationAccuracyAlpha(155);
+
+ mapView = new MapView(this, mapboxMapOptions);
+ mapView.setId(R.id.mapView);
+ ViewGroup parent = (ViewGroup) findViewById(R.id.container);
+ parent.addView(mapView);
+
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(MapboxMap map) {
+ mapboxMap = map;
+ toggleGps(true);
+ }
+ });
+ }
+
+ public void toggleGps(boolean enableGps) {
+ if (enableGps) {
+ if ((ContextCompat.checkSelfPermission(this,
+ Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
+ || (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
+ != PackageManager.PERMISSION_GRANTED)) {
+ ActivityCompat.requestPermissions(this, new String[] {
+ Manifest.permission.ACCESS_COARSE_LOCATION,
+ Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_LOCATION);
+ } else {
+ enableLocation(true);
+ }
+ } else {
+ enableLocation(false);
}
-
- private void enableLocation(boolean enabled) {
- if (enabled) {
- mapboxMap.setMyLocationEnabled(true);
- Location location = mapboxMap.getMyLocation();
- if (location != null) {
- onLocationChanged(location);
- } else {
- LocationServices.getLocationServices(this).addLocationListener(this);
- }
- } else {
- mapboxMap.setMyLocationEnabled(false);
- }
- }
-
- @Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
- if (requestCode == PERMISSIONS_LOCATION) {
- if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
- enableLocation(true);
- }
- }
+ }
+
+ private void enableLocation(boolean enabled) {
+ if (enabled) {
+ mapboxMap.setMyLocationEnabled(true);
+ Location location = mapboxMap.getMyLocation();
+ if (location != null) {
+ onLocationChanged(location);
+ } else {
+ LocationServices.getLocationServices(this).addLocationListener(this);
+ }
+ } else {
+ mapboxMap.setMyLocationEnabled(false);
}
-
- @Override
- public void onLocationChanged(Location location) {
- if (mapboxMap != null) {
- mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location), 14));
- }
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+ if (requestCode == PERMISSIONS_LOCATION) {
+ if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ enableLocation(true);
+ }
}
+ }
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
+ @Override
+ public void onLocationChanged(Location location) {
+ if (mapboxMap != null) {
+ mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location), 14));
}
-
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
-
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
}
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 929c2f0b75..2da3bedcbf 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
@@ -3,6 +3,7 @@ package com.mapbox.mapboxsdk.testapp.activity.userlocation;
import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
+import android.graphics.Color;
import android.location.Location;
import android.os.Bundle;
import android.support.annotation.IdRes;
@@ -31,200 +32,217 @@ import com.mapbox.mapboxsdk.testapp.R;
public class MyLocationTintActivity extends AppCompatActivity implements LocationListener {
- private MapView mapView;
- private MapboxMap mapboxMap;
- private boolean firstRun;
+ private MapView mapView;
+ private MapboxMap mapboxMap;
+ private boolean firstRun;
- private static final int PERMISSIONS_LOCATION = 0;
+ private static final int PERMISSIONS_LOCATION = 0;
- @Override
- protected void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_my_location_dot_color);
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_my_location_dot_color);
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
+ ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
+ }
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(new OnMapReadyCallback() {
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @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(
+ MyLocationTintActivity.this,
+ R.id.default_user_dot_coloring_button,
+ new View.OnClickListener() {
@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(
- MyLocationTintActivity.this,
- R.id.default_user_dot_coloring_button,
- new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- myLocationViewSettings.setAccuracyTintColor(ContextCompat.getColor(
- MyLocationTintActivity.this, R.color.my_location_ring));
- myLocationViewSettings.setForegroundTintColor(ContextCompat.getColor(
- MyLocationTintActivity.this, R.color.mapbox_blue));
- }
- });
-
- // handle tint user dot button clicks
- ViewUtils.attachClickListener(
- MyLocationTintActivity.this,
- R.id.tint_user_dot_button,
- new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- myLocationViewSettings.setAccuracyTintColor(
- ContextCompat.getColor(MyLocationTintActivity.this, R.color.mapbox_green));
- myLocationViewSettings.setForegroundTintColor(
- ContextCompat.getColor(MyLocationTintActivity.this, R.color.mapbox_green));
- }
- });
-
- // handle tint accuracy ring button clicks
- ViewUtils.attachClickListener(
- MyLocationTintActivity.this,
- R.id.user_accuracy_ring_tint_button,
- new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- myLocationViewSettings.setAccuracyTintColor(
- ContextCompat.getColor(MyLocationTintActivity.this, R.color.accent));
- myLocationViewSettings.setForegroundTintColor(
- ContextCompat.getColor(MyLocationTintActivity.this, R.color.mapbox_blue));
- }
- });
+ public void onClick(View view) {
+ myLocationViewSettings.setAccuracyTintColor(ContextCompat.getColor(
+ MyLocationTintActivity.this, R.color.mapbox_blue));
+ myLocationViewSettings.setForegroundTintColor(ContextCompat.getColor(
+ MyLocationTintActivity.this, R.color.mapbox_blue));
+ myLocationViewSettings.setBackgroundTintColor(Color.WHITE);
}
- });
-
- }
-
- @Override
- public void onLocationChanged(Location location) {
- if (mapboxMap != null && firstRun) {
- mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location), 15));
- firstRun = false;
- }
- }
-
- @Override
- protected void onStart() {
- super.onStart();
- LocationServices.getLocationServices(this).addLocationListener(this);
- }
+ });
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
- }
-
- @Override
- protected void onStop() {
- super.onStop();
- LocationServices.getLocationServices(this).removeLocationListener(this);
- }
-
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
- }
+ // handle tint user dot button clicks
+ ViewUtils.attachClickListener(
+ MyLocationTintActivity.this,
+ R.id.tint_user_dot_button,
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ myLocationViewSettings.setAccuracyTintColor(
+ ContextCompat.getColor(MyLocationTintActivity.this, R.color.mapbox_green));
+ myLocationViewSettings.setForegroundTintColor(
+ ContextCompat.getColor(MyLocationTintActivity.this, R.color.mapbox_green));
+ myLocationViewSettings.setBackgroundTintColor(Color.WHITE);
+ }
+ });
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
+ // handle tint accuracy ring button clicks
+ ViewUtils.attachClickListener(
+ MyLocationTintActivity.this,
+ R.id.user_accuracy_ring_tint_button,
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ myLocationViewSettings.setAccuracyTintColor(
+ ContextCompat.getColor(MyLocationTintActivity.this, R.color.accent));
+ myLocationViewSettings.setForegroundTintColor(
+ ContextCompat.getColor(MyLocationTintActivity.this, R.color.mapbox_blue));
+ myLocationViewSettings.setBackgroundTintColor(Color.WHITE);
+ }
+ });
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
+ ViewUtils.attachClickListener(
+ MyLocationTintActivity.this,
+ R.id.user_dot_transparent_button,
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ myLocationViewSettings.setForegroundTintColor(Color.TRANSPARENT);
+ myLocationViewSettings.setBackgroundTintColor(Color.TRANSPARENT);
+ }
+ }
+ );
+ }
+ });
+
+ }
+
+ @Override
+ public void onLocationChanged(Location location) {
+ if (mapboxMap != null && firstRun) {
+ mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location), 15));
+ firstRun = false;
}
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ LocationServices.getLocationServices(this).addLocationListener(this);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ LocationServices.getLocationServices(this).removeLocationListener(this);
+ mapView.onStop();
+ }
+
+ @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);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
-
- @UiThread
- public void toggleGps(boolean enableGps) {
- if (enableGps) {
- if ((ContextCompat.checkSelfPermission(this,
- Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
- || (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
- != PackageManager.PERMISSION_GRANTED)) {
- ActivityCompat.requestPermissions(this, new String[]{
- Manifest.permission.ACCESS_COARSE_LOCATION,
- Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_LOCATION);
- } else {
- enableLocation(true);
- }
- } else {
- enableLocation(false);
- }
+ }
+
+ @UiThread
+ public void toggleGps(boolean enableGps) {
+ if (enableGps) {
+ if ((ContextCompat.checkSelfPermission(this,
+ Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
+ || (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
+ != PackageManager.PERMISSION_GRANTED)) {
+ ActivityCompat.requestPermissions(this, new String[] {
+ Manifest.permission.ACCESS_COARSE_LOCATION,
+ Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_LOCATION);
+ } else {
+ enableLocation(true);
+ }
+ } else {
+ enableLocation(false);
}
-
- private void enableLocation(boolean enabled) {
- if (enabled) {
- mapboxMap.setMyLocationEnabled(true);
- if (mapboxMap.getMyLocation() != null) {
- mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
- new LatLng(mapboxMap.getMyLocation().getLatitude(),
- mapboxMap.getMyLocation().getLongitude()), 15));
- }
- } else {
- mapboxMap.setMyLocationEnabled(false);
- }
+ }
+
+ private void enableLocation(boolean enabled) {
+ if (enabled) {
+ mapboxMap.setMyLocationEnabled(true);
+ if (mapboxMap.getMyLocation() != null) {
+ mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
+ new LatLng(mapboxMap.getMyLocation().getLatitude(),
+ mapboxMap.getMyLocation().getLongitude()), 15));
+ }
+ } else {
+ mapboxMap.setMyLocationEnabled(false);
}
-
- @Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
- if (requestCode == PERMISSIONS_LOCATION) {
- if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
- enableLocation(true);
- }
- }
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+ if (requestCode == PERMISSIONS_LOCATION) {
+ if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ enableLocation(true);
+ }
}
+ }
- private static class ViewUtils {
+ private static class ViewUtils {
- public static void attachClickListener(
- @NonNull Activity activity, @IdRes int buttonId, @Nullable View.OnClickListener clickListener) {
- View view = activity.findViewById(buttonId);
- if (view != null) {
- view.setOnClickListener(clickListener);
- }
- }
+ public static void attachClickListener(
+ @NonNull Activity activity, @IdRes int buttonId, @Nullable View.OnClickListener clickListener) {
+ View view = activity.findViewById(buttonId);
+ if (view != null) {
+ view.setOnClickListener(clickListener);
+ }
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationToggleActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationToggleActivity.java
index c2498223a2..e522840038 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationToggleActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationToggleActivity.java
@@ -15,6 +15,7 @@ import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.view.View;
+
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapView;
@@ -24,138 +25,150 @@ import com.mapbox.mapboxsdk.testapp.R;
public class MyLocationToggleActivity extends AppCompatActivity {
- private MapView mapView;
- private MapboxMap mapboxMap;
- private FloatingActionButton locationToggleFab;
-
- private static final int PERMISSIONS_LOCATION = 0;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_my_location_toggle);
-
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
-
- final ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayShowTitleEnabled(true);
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
- mapView.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(MapboxMap map) {
- mapboxMap = map;
- }
- });
-
- locationToggleFab = (FloatingActionButton) findViewById(R.id.fabLocationToggle);
- locationToggleFab.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- if (mapboxMap != null) {
- toggleGps(!mapboxMap.isMyLocationEnabled());
- }
- }
- });
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
- }
+ private MapView mapView;
+ private MapboxMap mapboxMap;
+ private FloatingActionButton locationToggleFab;
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
- }
+ private static final int PERMISSIONS_LOCATION = 0;
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
- }
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_my_location_toggle);
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
- }
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
+ final ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayShowTitleEnabled(true);
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- default:
- return false;
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(MapboxMap map) {
+ mapboxMap = map;
+ }
+ });
+
+ locationToggleFab = (FloatingActionButton) findViewById(R.id.fabLocationToggle);
+ locationToggleFab.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ if (mapboxMap != null) {
+ toggleGps(!mapboxMap.isMyLocationEnabled());
}
+ }
+ });
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ default:
+ return false;
}
-
- @UiThread
- public void toggleGps(boolean enableGps) {
- if (enableGps) {
- if ((ContextCompat.checkSelfPermission(this,
- Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
- || (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
- != PackageManager.PERMISSION_GRANTED)) {
- ActivityCompat.requestPermissions(this, new String[]{
- Manifest.permission.ACCESS_COARSE_LOCATION,
- Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_LOCATION);
- } else {
- enableLocation(true);
- }
- } else {
- enableLocation(false);
- }
+ }
+
+ @UiThread
+ public void toggleGps(boolean enableGps) {
+ if (enableGps) {
+ if ((ContextCompat.checkSelfPermission(this,
+ Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
+ || (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
+ != PackageManager.PERMISSION_GRANTED)) {
+ ActivityCompat.requestPermissions(this, new String[] {
+ Manifest.permission.ACCESS_COARSE_LOCATION,
+ Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_LOCATION);
+ } else {
+ enableLocation(true);
+ }
+ } else {
+ enableLocation(false);
}
-
- private void enableLocation(boolean enabled) {
- if (enabled) {
- mapboxMap.setOnMyLocationChangeListener(new MapboxMap.OnMyLocationChangeListener() {
- @Override
- public void onMyLocationChange(@Nullable Location location) {
- if (location != null) {
- mapboxMap.setCameraPosition(new CameraPosition.Builder()
- .target(new LatLng(location))
- .zoom(16)
- .bearing(0)
- .tilt(0)
- .build());
- mapboxMap.setOnMyLocationChangeListener(null);
- }
- }
- });
- locationToggleFab.setImageResource(R.drawable.ic_location_disabled_24dp);
- } else {
- locationToggleFab.setImageResource(R.drawable.ic_my_location_24dp);
+ }
+
+ private void enableLocation(boolean enabled) {
+ if (enabled) {
+ mapboxMap.setOnMyLocationChangeListener(new MapboxMap.OnMyLocationChangeListener() {
+ @Override
+ public void onMyLocationChange(@Nullable Location location) {
+ if (location != null) {
+ mapboxMap.setCameraPosition(new CameraPosition.Builder()
+ .target(new LatLng(location))
+ .zoom(16)
+ .bearing(0)
+ .tilt(0)
+ .build());
+ mapboxMap.setOnMyLocationChangeListener(null);
+ }
}
-
- mapboxMap.setMyLocationEnabled(enabled);
+ });
+ locationToggleFab.setImageResource(R.drawable.ic_location_disabled_24dp);
+ } else {
+ locationToggleFab.setImageResource(R.drawable.ic_my_location_24dp);
}
- @Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
- if (requestCode == PERMISSIONS_LOCATION) {
- if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
- enableLocation(true);
- }
- }
+ mapboxMap.setMyLocationEnabled(enabled);
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+ if (requestCode == PERMISSIONS_LOCATION) {
+ if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ enableLocation(true);
+ }
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTrackingModeActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTrackingModeActivity.java
index 2c923a3ba9..3d08399abf 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTrackingModeActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationTrackingModeActivity.java
@@ -34,308 +34,320 @@ import com.mapbox.mapboxsdk.maps.UiSettings;
import com.mapbox.mapboxsdk.testapp.R;
public class MyLocationTrackingModeActivity extends AppCompatActivity
- implements MapboxMap.OnMyLocationChangeListener, AdapterView.OnItemSelectedListener {
-
- public static final int TRACKING_NONE_INDEX = 0;
- public static final int TRACKING_FOLLOW_INDEX = 1;
- public static final int BEARING_NONE_INDEX = 0;
- public static final int BEARING_GPS_INDEX = 1;
- public static final int BEARING_COMPASS_INDEX = 2;
- private MapView mapView;
- private MapboxMap mapboxMap;
- private Spinner locationSpinner;
- private Spinner bearingSpinner;
- private Location location;
- private static final int PERMISSIONS_LOCATION = 0;
- private MenuItem dismissLocationTrackingOnGestureItem;
- private MenuItem dismissBearingTrackingOnGestureItem;
- private MenuItem enableRotateGesturesItem;
- private MenuItem enableScrollGesturesItem;
-
- @Override
- protected void onCreate(final Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_my_location_tracking);
-
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
-
- final ActionBar actionBar = getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayShowTitleEnabled(false);
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
-
- locationSpinner = (Spinner) findViewById(R.id.spinner_location);
- ArrayAdapter<CharSequence> locationTrackingAdapter = ArrayAdapter.createFromResource(
- actionBar.getThemedContext(), R.array.user_tracking_mode, android.R.layout.simple_spinner_item);
- locationTrackingAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- locationSpinner.setAdapter(locationTrackingAdapter);
-
- bearingSpinner = (Spinner) findViewById(R.id.spinner_bearing);
- ArrayAdapter<CharSequence> bearingTrackingAdapter = ArrayAdapter.createFromResource(
- actionBar.getThemedContext(), R.array.user_bearing_mode, android.R.layout.simple_spinner_item);
- bearingTrackingAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- bearingSpinner.setAdapter(bearingTrackingAdapter);
-
- mapView = (MapView) findViewById(R.id.mapView);
- mapView.onCreate(savedInstanceState);
-
- mapView.getMapAsync(new OnMapReadyCallback() {
- @Override
- public void onMapReady(@NonNull MapboxMap mapboxMap) {
- MyLocationTrackingModeActivity.this.mapboxMap = mapboxMap;
-
- locationSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this);
- bearingSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this);
- setCheckBoxes();
-
- mapboxMap.setOnMyLocationChangeListener(MyLocationTrackingModeActivity.this);
-
- mapboxMap.setOnMyLocationTrackingModeChangeListener(new MapboxMap.OnMyLocationTrackingModeChangeListener() {
- @Override
- public void onMyLocationTrackingModeChange(@MyLocationTracking.Mode int myLocationTrackingMode) {
- locationSpinner.setOnItemSelectedListener(null);
- switch (myLocationTrackingMode) {
- case MyLocationTracking.TRACKING_NONE:
- locationSpinner.setSelection(TRACKING_NONE_INDEX);
- break;
- case MyLocationTracking.TRACKING_FOLLOW:
- locationSpinner.setSelection(TRACKING_FOLLOW_INDEX);
- break;
- }
- locationSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this);
- }
- });
-
- mapboxMap.setOnMyBearingTrackingModeChangeListener(new MapboxMap.OnMyBearingTrackingModeChangeListener() {
- @Override
- public void onMyBearingTrackingModeChange(@MyBearingTracking.Mode int myBearingTrackingMode) {
- bearingSpinner.setOnItemSelectedListener(null);
- switch (myBearingTrackingMode) {
- case MyBearingTracking.NONE:
- bearingSpinner.setSelection(BEARING_NONE_INDEX);
- break;
-
- case MyBearingTracking.GPS:
- bearingSpinner.setSelection(BEARING_GPS_INDEX);
- break;
-
- case MyBearingTracking.COMPASS:
- bearingSpinner.setSelection(BEARING_COMPASS_INDEX);
- break;
- }
- bearingSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this);
- }
- });
-
- if (savedInstanceState == null) {
- toggleGps(true);
- }
- }
- });
+ implements MapboxMap.OnMyLocationChangeListener, AdapterView.OnItemSelectedListener {
+
+ public static final int TRACKING_NONE_INDEX = 0;
+ public static final int TRACKING_FOLLOW_INDEX = 1;
+ public static final int BEARING_NONE_INDEX = 0;
+ public static final int BEARING_GPS_INDEX = 1;
+ public static final int BEARING_COMPASS_INDEX = 2;
+ private MapView mapView;
+ private MapboxMap mapboxMap;
+ private Spinner locationSpinner;
+ private Spinner bearingSpinner;
+ private Location location;
+ private static final int PERMISSIONS_LOCATION = 0;
+ private MenuItem dismissLocationTrackingOnGestureItem;
+ private MenuItem dismissBearingTrackingOnGestureItem;
+ private MenuItem enableRotateGesturesItem;
+ private MenuItem enableScrollGesturesItem;
+
+ @Override
+ protected void onCreate(final Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_my_location_tracking);
+
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+
+ final ActionBar actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayShowTitleEnabled(false);
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
}
- @UiThread
- public void toggleGps(boolean enableGps) {
- if (enableGps) {
- if ((ContextCompat.checkSelfPermission(this,
- Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
- || (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
- != PackageManager.PERMISSION_GRANTED)) {
- ActivityCompat.requestPermissions(this, new String[]{
- Manifest.permission.ACCESS_COARSE_LOCATION,
- Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_LOCATION);
- } else {
- enableLocation(true);
- }
- } else {
- enableLocation(false);
- }
- }
+ locationSpinner = (Spinner) findViewById(R.id.spinner_location);
+ ArrayAdapter<CharSequence> locationTrackingAdapter = ArrayAdapter.createFromResource(
+ actionBar.getThemedContext(), R.array.user_tracking_mode, android.R.layout.simple_spinner_item);
+ locationTrackingAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ locationSpinner.setAdapter(locationTrackingAdapter);
- private void enableLocation(boolean enabled) {
- if (enabled) {
- mapboxMap.setMyLocationEnabled(true);
- Location location = mapboxMap.getMyLocation();
- if (location != null) {
- setInitialPosition(new LatLng(location));
- }
- } else {
- mapboxMap.setMyLocationEnabled(false);
- }
- }
+ bearingSpinner = (Spinner) findViewById(R.id.spinner_bearing);
+ ArrayAdapter<CharSequence> bearingTrackingAdapter = ArrayAdapter.createFromResource(
+ actionBar.getThemedContext(), R.array.user_bearing_mode, android.R.layout.simple_spinner_item);
+ bearingTrackingAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ bearingSpinner.setAdapter(bearingTrackingAdapter);
- @Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
- if (requestCode == PERMISSIONS_LOCATION) {
- if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
- enableLocation(true);
- }
- }
- }
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
- private void setInitialPosition(LatLng latLng) {
- mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 14));
- mapboxMap.setMyLocationEnabled(true);
- locationSpinner.setEnabled(true);
- bearingSpinner.setEnabled(true);
- }
+ mapView.getMapAsync(new OnMapReadyCallback() {
+ @Override
+ public void onMapReady(@NonNull MapboxMap mapboxMap) {
+ MyLocationTrackingModeActivity.this.mapboxMap = mapboxMap;
+
+ locationSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this);
+ bearingSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this);
+ setCheckBoxes();
- @Override
- public void onMyLocationChange(@Nullable Location location) {
- if (location != null) {
- if (this.location == null) {
- // initial location to reposition map
- setInitialPosition(new LatLng(location));
+ mapboxMap.setOnMyLocationChangeListener(MyLocationTrackingModeActivity.this);
+
+ mapboxMap.setOnMyLocationTrackingModeChangeListener(new MapboxMap.OnMyLocationTrackingModeChangeListener() {
+ @Override
+ public void onMyLocationTrackingModeChange(@MyLocationTracking.Mode int myLocationTrackingMode) {
+ locationSpinner.setOnItemSelectedListener(null);
+ switch (myLocationTrackingMode) {
+ case MyLocationTracking.TRACKING_NONE:
+ locationSpinner.setSelection(TRACKING_NONE_INDEX);
+ break;
+ case MyLocationTracking.TRACKING_FOLLOW:
+ locationSpinner.setSelection(TRACKING_FOLLOW_INDEX);
+ break;
}
- this.location = location;
- showSnackBar();
- }
- }
+ locationSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this);
+ }
+ });
- private void showSnackBar() {
- String desc = "Loc Chg: ";
- boolean noInfo = true;
- if (location.hasSpeed()) {
- desc += String.format(MapboxConstants.MAPBOX_LOCALE, "Spd = %.1f km/h ", location.getSpeed() * 3.6f);
- noInfo = false;
- }
- if (location.hasAltitude()) {
- desc += String.format(MapboxConstants.MAPBOX_LOCALE, "Alt = %.0f m ", location.getAltitude());
- noInfo = false;
- }
- if (location.hasAccuracy()) {
- desc += String.format(MapboxConstants.MAPBOX_LOCALE, "Acc = %.0f m", location.getAccuracy());
- }
+ mapboxMap.setOnMyBearingTrackingModeChangeListener(new MapboxMap.OnMyBearingTrackingModeChangeListener() {
+ @Override
+ public void onMyBearingTrackingModeChange(@MyBearingTracking.Mode int myBearingTrackingMode) {
+ bearingSpinner.setOnItemSelectedListener(null);
+ switch (myBearingTrackingMode) {
+ case MyBearingTracking.NONE:
+ bearingSpinner.setSelection(BEARING_NONE_INDEX);
+ break;
+
+ case MyBearingTracking.GPS:
+ bearingSpinner.setSelection(BEARING_GPS_INDEX);
+ break;
+
+ case MyBearingTracking.COMPASS:
+ bearingSpinner.setSelection(BEARING_COMPASS_INDEX);
+ break;
+ }
+ bearingSpinner.setOnItemSelectedListener(MyLocationTrackingModeActivity.this);
+ }
+ });
- if (noInfo) {
- desc += "No extra info";
+ if (savedInstanceState == null) {
+ toggleGps(true);
}
- Snackbar.make(findViewById(android.R.id.content), desc, Snackbar.LENGTH_SHORT).show();
+ }
+ });
+ }
+
+ @UiThread
+ public void toggleGps(boolean enableGps) {
+ if (enableGps) {
+ if ((ContextCompat.checkSelfPermission(this,
+ Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
+ || (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
+ != PackageManager.PERMISSION_GRANTED)) {
+ ActivityCompat.requestPermissions(this, new String[] {
+ Manifest.permission.ACCESS_COARSE_LOCATION,
+ Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_LOCATION);
+ } else {
+ enableLocation(true);
+ }
+ } else {
+ enableLocation(false);
}
-
- @Override
- public void onItemSelected(AdapterView<?> parent, View view, int position, long id) throws SecurityException {
- TrackingSettings trackingSettings = mapboxMap.getTrackingSettings();
- if (parent.getId() == R.id.spinner_location) {
- switch (position) {
- case TRACKING_NONE_INDEX:
- trackingSettings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_NONE);
- break;
-
- case TRACKING_FOLLOW_INDEX:
- trackingSettings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW);
- break;
- }
- } else if (parent.getId() == R.id.spinner_bearing) {
- switch (position) {
- case BEARING_NONE_INDEX:
- trackingSettings.setMyBearingTrackingMode(MyBearingTracking.NONE);
- break;
-
- case BEARING_GPS_INDEX:
- trackingSettings.setMyBearingTrackingMode(MyBearingTracking.GPS);
- break;
-
- case BEARING_COMPASS_INDEX:
- trackingSettings.setMyBearingTrackingMode(MyBearingTracking.COMPASS);
- break;
- }
- }
+ }
+
+ private void enableLocation(boolean enabled) {
+ if (enabled) {
+ mapboxMap.setMyLocationEnabled(true);
+ Location location = mapboxMap.getMyLocation();
+ if (location != null) {
+ setInitialPosition(new LatLng(location));
+ }
+ } else {
+ mapboxMap.setMyLocationEnabled(false);
}
-
- @Override
- public void onNothingSelected(AdapterView<?> parent) {
-
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+ if (requestCode == PERMISSIONS_LOCATION) {
+ if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ enableLocation(true);
+ }
}
-
- @Override
- public void onResume() {
- super.onResume();
- mapView.onResume();
+ }
+
+ private void setInitialPosition(LatLng latLng) {
+ mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 14));
+ mapboxMap.setMyLocationEnabled(true);
+ locationSpinner.setEnabled(true);
+ bearingSpinner.setEnabled(true);
+ }
+
+ @Override
+ public void onMyLocationChange(@Nullable Location location) {
+ if (location != null) {
+ if (this.location == null) {
+ // initial location to reposition map
+ setInitialPosition(new LatLng(location));
+ }
+ this.location = location;
+ showSnackBar();
}
-
- @Override
- public void onPause() {
- super.onPause();
- mapView.onPause();
+ }
+
+ private void showSnackBar() {
+ String desc = "Loc Chg: ";
+ boolean noInfo = true;
+ if (location.hasSpeed()) {
+ desc += String.format(MapboxConstants.MAPBOX_LOCALE, "Spd = %.1f km/h ", location.getSpeed() * 3.6f);
+ noInfo = false;
}
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- mapView.onSaveInstanceState(outState);
+ if (location.hasAltitude()) {
+ desc += String.format(MapboxConstants.MAPBOX_LOCALE, "Alt = %.0f m ", location.getAltitude());
+ noInfo = false;
}
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapView.onDestroy();
+ if (location.hasAccuracy()) {
+ desc += String.format(MapboxConstants.MAPBOX_LOCALE, "Acc = %.0f m", location.getAccuracy());
}
- @Override
- public void onLowMemory() {
- super.onLowMemory();
- mapView.onLowMemory();
+ if (noInfo) {
+ desc += "No extra info";
}
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.menu_tracking, menu);
- dismissLocationTrackingOnGestureItem = menu.findItem(R.id.action_toggle_dismissible_location);
- dismissBearingTrackingOnGestureItem = menu.findItem(R.id.action_toggle_dismissible_bearing);
- enableRotateGesturesItem = menu.findItem(R.id.action_toggle_rotate_gesture_enabled);
- enableScrollGesturesItem = menu.findItem(R.id.action_toggle_scroll_gesture_enabled);
- setCheckBoxes();
- return true;
+ Snackbar.make(findViewById(android.R.id.content), desc, Snackbar.LENGTH_SHORT).show();
+ }
+
+ @Override
+ public void onItemSelected(AdapterView<?> parent, View view, int position, long id) throws SecurityException {
+ TrackingSettings trackingSettings = mapboxMap.getTrackingSettings();
+ if (parent.getId() == R.id.spinner_location) {
+ switch (position) {
+ case TRACKING_NONE_INDEX:
+ trackingSettings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_NONE);
+ break;
+
+ case TRACKING_FOLLOW_INDEX:
+ trackingSettings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW);
+ break;
+ }
+ } else if (parent.getId() == R.id.spinner_bearing) {
+ switch (position) {
+ case BEARING_NONE_INDEX:
+ trackingSettings.setMyBearingTrackingMode(MyBearingTracking.NONE);
+ break;
+
+ case BEARING_GPS_INDEX:
+ trackingSettings.setMyBearingTrackingMode(MyBearingTracking.GPS);
+ break;
+
+ case BEARING_COMPASS_INDEX:
+ trackingSettings.setMyBearingTrackingMode(MyBearingTracking.COMPASS);
+ break;
+ }
}
-
- private void setCheckBoxes() {
- if (mapboxMap != null && dismissBearingTrackingOnGestureItem != null) {
- TrackingSettings trackingSettings = mapboxMap.getTrackingSettings();
- UiSettings uiSettings = mapboxMap.getUiSettings();
- dismissBearingTrackingOnGestureItem.setChecked(trackingSettings.isDismissBearingTrackingOnGesture());
- dismissLocationTrackingOnGestureItem.setChecked(trackingSettings.isDismissLocationTrackingOnGesture());
- enableRotateGesturesItem.setChecked(uiSettings.isRotateGesturesEnabled());
- enableScrollGesturesItem.setChecked(uiSettings.isScrollGesturesEnabled());
- }
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {
+
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ public void onLowMemory() {
+ super.onLowMemory();
+ mapView.onLowMemory();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.menu_tracking, menu);
+ dismissLocationTrackingOnGestureItem = menu.findItem(R.id.action_toggle_dismissible_location);
+ dismissBearingTrackingOnGestureItem = menu.findItem(R.id.action_toggle_dismissible_bearing);
+ enableRotateGesturesItem = menu.findItem(R.id.action_toggle_rotate_gesture_enabled);
+ enableScrollGesturesItem = menu.findItem(R.id.action_toggle_scroll_gesture_enabled);
+ setCheckBoxes();
+ return true;
+ }
+
+ private void setCheckBoxes() {
+ if (mapboxMap != null && dismissBearingTrackingOnGestureItem != null) {
+ TrackingSettings trackingSettings = mapboxMap.getTrackingSettings();
+ UiSettings uiSettings = mapboxMap.getUiSettings();
+ dismissBearingTrackingOnGestureItem.setChecked(trackingSettings.isDismissBearingTrackingOnGesture());
+ dismissLocationTrackingOnGestureItem.setChecked(trackingSettings.isDismissLocationTrackingOnGesture());
+ enableRotateGesturesItem.setChecked(uiSettings.isRotateGesturesEnabled());
+ enableScrollGesturesItem.setChecked(uiSettings.isScrollGesturesEnabled());
}
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- boolean state;
- switch (item.getItemId()) {
- case android.R.id.home:
- onBackPressed();
- return true;
- case R.id.action_toggle_dismissible_location:
- state = !item.isChecked();
- mapboxMap.getTrackingSettings().setDismissLocationTrackingOnGesture(state);
- Toast.makeText(this, "Dismiss tracking mode on gesture = " + state, Toast.LENGTH_SHORT).show();
- item.setChecked(state);
- return true;
- case R.id.action_toggle_dismissible_bearing:
- state = !item.isChecked();
- mapboxMap.getTrackingSettings().setDismissBearingTrackingOnGesture(state);
- Toast.makeText(this, "Dismiss bearing mode on gesture = " + state, Toast.LENGTH_SHORT).show();
- item.setChecked(state);
- return true;
- case R.id.action_toggle_rotate_gesture_enabled:
- state = !item.isChecked();
- mapboxMap.getUiSettings().setRotateGesturesEnabled(state);
- Toast.makeText(this, "Rotate gesture enabled = " + state, Toast.LENGTH_SHORT).show();
- item.setChecked(state);
- return true;
- case R.id.action_toggle_scroll_gesture_enabled:
- state = !item.isChecked();
- mapboxMap.getUiSettings().setScrollGesturesEnabled(state);
- Toast.makeText(this, "Scroll gesture enabled = " + state, Toast.LENGTH_SHORT).show();
- item.setChecked(state);
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ boolean state;
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ onBackPressed();
+ return true;
+ case R.id.action_toggle_dismissible_location:
+ state = !item.isChecked();
+ mapboxMap.getTrackingSettings().setDismissLocationTrackingOnGesture(state);
+ Toast.makeText(this, "Dismiss tracking mode on gesture = " + state, Toast.LENGTH_SHORT).show();
+ item.setChecked(state);
+ return true;
+ case R.id.action_toggle_dismissible_bearing:
+ state = !item.isChecked();
+ mapboxMap.getTrackingSettings().setDismissBearingTrackingOnGesture(state);
+ Toast.makeText(this, "Dismiss bearing mode on gesture = " + state, Toast.LENGTH_SHORT).show();
+ item.setChecked(state);
+ return true;
+ case R.id.action_toggle_rotate_gesture_enabled:
+ state = !item.isChecked();
+ mapboxMap.getUiSettings().setRotateGesturesEnabled(state);
+ Toast.makeText(this, "Rotate gesture enabled = " + state, Toast.LENGTH_SHORT).show();
+ item.setChecked(state);
+ return true;
+ case R.id.action_toggle_scroll_gesture_enabled:
+ state = !item.isChecked();
+ mapboxMap.getUiSettings().setScrollGesturesEnabled(state);
+ Toast.makeText(this, "Scroll gesture enabled = " + state, Toast.LENGTH_SHORT).show();
+ item.setChecked(state);
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/adapter/FeatureAdapter.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/adapter/FeatureAdapter.java
index 71adba8ac7..a935c2134f 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/adapter/FeatureAdapter.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/adapter/FeatureAdapter.java
@@ -15,41 +15,41 @@ import java.util.List;
public class FeatureAdapter extends RecyclerView.Adapter<FeatureAdapter.ViewHolder> {
- private List<Feature> features;
+ private List<Feature> features;
- public static class ViewHolder extends RecyclerView.ViewHolder {
+ public static class ViewHolder extends RecyclerView.ViewHolder {
- public TextView labelView;
- public TextView descriptionView;
+ public TextView labelView;
+ public TextView descriptionView;
- public ViewHolder(View view) {
- super(view);
- Typeface typeface = FontCache.get("Roboto-Regular.ttf",view.getContext());
- labelView = (TextView) view.findViewById(R.id.nameView);
- labelView.setTypeface(typeface);
- descriptionView = (TextView) view.findViewById(R.id.descriptionView);
- descriptionView.setTypeface(typeface);
- }
- }
-
- public FeatureAdapter(List<Feature> features) {
- this.features = features;
- }
-
- @Override
- public FeatureAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_main_feature, parent, false);
- return new ViewHolder(view);
- }
-
- @Override
- public void onBindViewHolder(ViewHolder holder, int position) {
- holder.labelView.setText(features.get(position).getLabel());
- holder.descriptionView.setText(features.get(position).getDescription());
- }
-
- @Override
- public int getItemCount() {
- return features.size();
+ public ViewHolder(View view) {
+ super(view);
+ Typeface typeface = FontCache.get("Roboto-Regular.ttf", view.getContext());
+ labelView = (TextView) view.findViewById(R.id.nameView);
+ labelView.setTypeface(typeface);
+ descriptionView = (TextView) view.findViewById(R.id.descriptionView);
+ descriptionView.setTypeface(typeface);
}
+ }
+
+ public FeatureAdapter(List<Feature> features) {
+ this.features = features;
+ }
+
+ @Override
+ public FeatureAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_main_feature, parent, false);
+ return new ViewHolder(view);
+ }
+
+ @Override
+ public void onBindViewHolder(ViewHolder holder, int position) {
+ holder.labelView.setText(features.get(position).getLabel());
+ holder.descriptionView.setText(features.get(position).getDescription());
+ }
+
+ @Override
+ public int getItemCount() {
+ return features.size();
+ }
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/adapter/FeatureSectionAdapter.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/adapter/FeatureSectionAdapter.java
index d86e06ea6d..012bbed4ca 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/adapter/FeatureSectionAdapter.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/adapter/FeatureSectionAdapter.java
@@ -18,161 +18,162 @@ import java.util.Comparator;
public class FeatureSectionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
- private static final int SECTION_TYPE = 0;
-
- private final Context context;
- private final SparseArray<Section> sections;
- private final RecyclerView.Adapter adapter;
-
- @LayoutRes
- private final int sectionRes;
-
- @IdRes
- private final int textRes;
-
- private boolean valid = true;
-
- public FeatureSectionAdapter(Context ctx, int sectionResourceId, int textResourceId, RecyclerView.Adapter baseAdapter) {
- context = ctx;
- sectionRes = sectionResourceId;
- textRes = textResourceId;
- adapter = baseAdapter;
- sections = new SparseArray<>();
- adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
- @Override
- public void onChanged() {
- valid = adapter.getItemCount() > 0;
- notifyDataSetChanged();
- }
-
- @Override
- public void onItemRangeChanged(int positionStart, int itemCount) {
- valid = adapter.getItemCount() > 0;
- notifyItemRangeChanged(positionStart, itemCount);
- }
-
- @Override
- public void onItemRangeInserted(int positionStart, int itemCount) {
- valid = adapter.getItemCount() > 0;
- notifyItemRangeInserted(positionStart, itemCount);
- }
-
- @Override
- public void onItemRangeRemoved(int positionStart, int itemCount) {
- valid = adapter.getItemCount() > 0;
- notifyItemRangeRemoved(positionStart, itemCount);
- }
- });
- }
+ private static final int SECTION_TYPE = 0;
+
+ private final Context context;
+ private final SparseArray<Section> sections;
+ private final RecyclerView.Adapter adapter;
+
+ @LayoutRes
+ private final int sectionRes;
+
+ @IdRes
+ private final int textRes;
+
+ private boolean valid = true;
+
+ public FeatureSectionAdapter(Context ctx, int sectionResourceId, int textResourceId,
+ RecyclerView.Adapter baseAdapter) {
+ context = ctx;
+ sectionRes = sectionResourceId;
+ textRes = textResourceId;
+ adapter = baseAdapter;
+ sections = new SparseArray<>();
+ adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
+ @Override
+ public void onChanged() {
+ valid = adapter.getItemCount() > 0;
+ notifyDataSetChanged();
+ }
+ @Override
+ public void onItemRangeChanged(int positionStart, int itemCount) {
+ valid = adapter.getItemCount() > 0;
+ notifyItemRangeChanged(positionStart, itemCount);
+ }
- public static class SectionViewHolder extends RecyclerView.ViewHolder {
+ @Override
+ public void onItemRangeInserted(int positionStart, int itemCount) {
+ valid = adapter.getItemCount() > 0;
+ notifyItemRangeInserted(positionStart, itemCount);
+ }
- public TextView title;
+ @Override
+ public void onItemRangeRemoved(int positionStart, int itemCount) {
+ valid = adapter.getItemCount() > 0;
+ notifyItemRangeRemoved(positionStart, itemCount);
+ }
+ });
+ }
- public SectionViewHolder(@NonNull View view, @IdRes int textRes) {
- super(view);
- title = (TextView) view.findViewById(textRes);
- title.setTypeface(FontCache.get("Roboto-Medium.ttf", view.getContext()));
- }
- }
- @Override
- public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int typeView) {
- if (typeView == SECTION_TYPE) {
- final View view = LayoutInflater.from(context).inflate(sectionRes, parent, false);
- return new SectionViewHolder(view, textRes);
- } else {
- return adapter.onCreateViewHolder(parent, typeView - 1);
- }
- }
+ public static class SectionViewHolder extends RecyclerView.ViewHolder {
- @Override
- public void onBindViewHolder(RecyclerView.ViewHolder sectionViewHolder, int position) {
- if (isSectionHeaderPosition(position)) {
- ((SectionViewHolder) sectionViewHolder).title.setText(sections.get(position).title);
- } else {
- adapter.onBindViewHolder(sectionViewHolder, getConvertedPosition(position));
- }
+ public TextView title;
+ public SectionViewHolder(@NonNull View view, @IdRes int textRes) {
+ super(view);
+ title = (TextView) view.findViewById(textRes);
+ title.setTypeface(FontCache.get("Roboto-Medium.ttf", view.getContext()));
}
-
- @Override
- public int getItemViewType(int position) {
- return isSectionHeaderPosition(position)
- ? SECTION_TYPE
- : adapter.getItemViewType(getConvertedPosition(position)) + 1;
+ }
+
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int typeView) {
+ if (typeView == SECTION_TYPE) {
+ final View view = LayoutInflater.from(context).inflate(sectionRes, parent, false);
+ return new SectionViewHolder(view, textRes);
+ } else {
+ return adapter.onCreateViewHolder(parent, typeView - 1);
}
-
-
- public static class Section {
- int firstPosition;
- int sectionedPosition;
- CharSequence title;
-
- public Section(int firstPosition, CharSequence title) {
- this.firstPosition = firstPosition;
- this.title = title;
- }
-
- public CharSequence getTitle() {
- return title;
- }
+ }
+
+ @Override
+ public void onBindViewHolder(RecyclerView.ViewHolder sectionViewHolder, int position) {
+ if (isSectionHeaderPosition(position)) {
+ ((SectionViewHolder) sectionViewHolder).title.setText(sections.get(position).title);
+ } else {
+ adapter.onBindViewHolder(sectionViewHolder, getConvertedPosition(position));
}
+ }
- public void setSections(Section[] sections) {
- this.sections.clear();
+ @Override
+ public int getItemViewType(int position) {
+ return isSectionHeaderPosition(position)
+ ? SECTION_TYPE
+ : adapter.getItemViewType(getConvertedPosition(position)) + 1;
+ }
- Arrays.sort(sections, new Comparator<Section>() {
- @Override
- public int compare(Section o, Section o1) {
- return (o.firstPosition == o1.firstPosition)
- ? 0
- : ((o.firstPosition < o1.firstPosition) ? -1 : 1);
- }
- });
- int offset = 0;
- for (Section section : sections) {
- section.sectionedPosition = section.firstPosition + offset;
- this.sections.append(section.sectionedPosition, section);
- ++offset;
- }
+ public static class Section {
+ int firstPosition;
+ int sectionedPosition;
+ CharSequence title;
- notifyDataSetChanged();
+ public Section(int firstPosition, CharSequence title) {
+ this.firstPosition = firstPosition;
+ this.title = title;
}
- public int getConvertedPosition(int sectionedPosition) {
- if (isSectionHeaderPosition(sectionedPosition)) {
- return RecyclerView.NO_POSITION;
- }
-
- int offset = 0;
- for (int i = 0; i < sections.size(); i++) {
- if (sections.valueAt(i).sectionedPosition > sectionedPosition) {
- break;
- }
- --offset;
- }
- return sectionedPosition + offset;
+ public CharSequence getTitle() {
+ return title;
}
-
- public boolean isSectionHeaderPosition(int position) {
- return sections.get(position) != null;
+ }
+
+
+ public void setSections(Section[] sections) {
+ this.sections.clear();
+
+ Arrays.sort(sections, new Comparator<Section>() {
+ @Override
+ public int compare(Section section, Section section1) {
+ return (section.firstPosition == section1.firstPosition)
+ ? 0
+ : ((section.firstPosition < section1.firstPosition) ? -1 : 1);
+ }
+ });
+
+ int offset = 0;
+ for (Section section : sections) {
+ section.sectionedPosition = section.firstPosition + offset;
+ this.sections.append(section.sectionedPosition, section);
+ ++offset;
}
+ notifyDataSetChanged();
+ }
- @Override
- public long getItemId(int position) {
- return isSectionHeaderPosition(position)
- ? Integer.MAX_VALUE - sections.indexOfKey(position)
- : adapter.getItemId(getConvertedPosition(position));
+ public int getConvertedPosition(int sectionedPosition) {
+ if (isSectionHeaderPosition(sectionedPosition)) {
+ return RecyclerView.NO_POSITION;
}
- @Override
- public int getItemCount() {
- return (valid ? adapter.getItemCount() + sections.size() : 0);
+ int offset = 0;
+ for (int i = 0; i < sections.size(); i++) {
+ if (sections.valueAt(i).sectionedPosition > sectionedPosition) {
+ break;
+ }
+ --offset;
}
+ return sectionedPosition + offset;
+ }
+
+ public boolean isSectionHeaderPosition(int position) {
+ return sections.get(position) != null;
+ }
+
+
+ @Override
+ public long getItemId(int position) {
+ return isSectionHeaderPosition(position)
+ ? Integer.MAX_VALUE - sections.indexOfKey(position)
+ : adapter.getItemId(getConvertedPosition(position));
+ }
+
+ @Override
+ public int getItemCount() {
+ return (valid ? adapter.getItemCount() + sections.size() : 0);
+ }
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/activity/Feature.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/activity/Feature.java
index a54e55529e..d745982388 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/activity/Feature.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/activity/Feature.java
@@ -5,73 +5,73 @@ import android.os.Parcelable;
public class Feature implements Parcelable {
- private String name;
- private String label;
- private String description;
- private String category;
- private boolean requiresLocationPermission;
+ private String name;
+ private String label;
+ private String description;
+ private String category;
+ private boolean requiresLocationPermission;
- public Feature(String name, String label, String description, String category, boolean requiresLocationPermission) {
- this.name = name;
- this.label = label;
- this.description = description;
- this.category = category;
- this.requiresLocationPermission = requiresLocationPermission;
- }
+ public Feature(String name, String label, String description, String category, boolean requiresLocationPermission) {
+ this.name = name;
+ this.label = label;
+ this.description = description;
+ this.category = category;
+ this.requiresLocationPermission = requiresLocationPermission;
+ }
- private Feature(Parcel in) {
- name = in.readString();
- label = in.readString();
- description = in.readString();
- category = in.readString();
- requiresLocationPermission = in.readByte() != 0;
- }
+ private Feature(Parcel in) {
+ name = in.readString();
+ label = in.readString();
+ description = in.readString();
+ category = in.readString();
+ requiresLocationPermission = in.readByte() != 0;
+ }
- public String getName() {
- return name;
- }
+ public String getName() {
+ return name;
+ }
- public String getSimpleName() {
- String[] split = name.split("\\.");
- return split[split.length - 1];
- }
+ public String getSimpleName() {
+ String[] split = name.split("\\.");
+ return split[split.length - 1];
+ }
- public String getLabel() {
- return label != null ? label : getSimpleName();
- }
+ public String getLabel() {
+ return label != null ? label : getSimpleName();
+ }
- public String getDescription() {
- return description != null ? description : "-";
- }
+ public String getDescription() {
+ return description != null ? description : "-";
+ }
- public String getCategory() {
- return category;
- }
+ public String getCategory() {
+ return category;
+ }
- public boolean isRequiresLocationPermission() {
- return requiresLocationPermission;
- }
+ public boolean isRequiresLocationPermission() {
+ return requiresLocationPermission;
+ }
- public int describeContents() {
- return 0;
- }
+ public int describeContents() {
+ return 0;
+ }
- public void writeToParcel(Parcel out, int flags) {
- out.writeString(name);
- out.writeString(label);
- out.writeString(description);
- out.writeString(category);
- out.writeByte((byte) (requiresLocationPermission ? 1 : 0));
- }
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(name);
+ out.writeString(label);
+ out.writeString(description);
+ out.writeString(category);
+ out.writeByte((byte) (requiresLocationPermission ? 1 : 0));
+ }
- public static final Parcelable.Creator<Feature> CREATOR
- = new Parcelable.Creator<Feature>() {
- public Feature createFromParcel(Parcel in) {
- return new Feature(in);
- }
+ public static final Parcelable.Creator<Feature> CREATOR
+ = new Parcelable.Creator<Feature>() {
+ public Feature createFromParcel(Parcel in) {
+ return new Feature(in);
+ }
- public Feature[] newArray(int size) {
- return new Feature[size];
- }
+ public Feature[] newArray(int size) {
+ return new Feature[size];
+ }
};
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CityStateMarker.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CityStateMarker.java
index 4eabb0a3bb..3b9f67aa1e 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CityStateMarker.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CityStateMarker.java
@@ -4,15 +4,15 @@ import com.mapbox.mapboxsdk.annotations.Marker;
public class CityStateMarker extends Marker {
- private String infoWindowBackgroundColor;
+ private String infoWindowBackgroundColor;
- public CityStateMarker(CityStateMarkerOptions cityStateOptions, String color) {
- super(cityStateOptions);
- infoWindowBackgroundColor = color;
- }
+ public CityStateMarker(CityStateMarkerOptions cityStateOptions, String color) {
+ super(cityStateOptions);
+ infoWindowBackgroundColor = color;
+ }
- public String getInfoWindowBackgroundColor() {
- return infoWindowBackgroundColor;
- }
+ public String getInfoWindowBackgroundColor() {
+ return infoWindowBackgroundColor;
+ }
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CityStateMarkerOptions.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CityStateMarkerOptions.java
index a4c32da92c..874c644af7 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CityStateMarkerOptions.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CityStateMarkerOptions.java
@@ -11,58 +11,58 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
public class CityStateMarkerOptions extends BaseMarkerOptions<CityStateMarker, CityStateMarkerOptions> {
- private String infoWindowBackgroundColor;
+ private String infoWindowBackgroundColor;
- public CityStateMarkerOptions infoWindowBackground(String color) {
- infoWindowBackgroundColor = color;
- return getThis();
- }
+ public CityStateMarkerOptions infoWindowBackground(String color) {
+ infoWindowBackgroundColor = color;
+ return getThis();
+ }
- public CityStateMarkerOptions() {
- }
+ public CityStateMarkerOptions() {
+ }
- private CityStateMarkerOptions(Parcel in) {
- position((LatLng) in.readParcelable(LatLng.class.getClassLoader()));
- snippet(in.readString());
- String iconId = in.readString();
- Bitmap iconBitmap = in.readParcelable(Bitmap.class.getClassLoader());
- Icon icon = IconFactory.recreate(iconId, iconBitmap);
- icon(icon);
- title(in.readString());
- }
+ private CityStateMarkerOptions(Parcel in) {
+ position((LatLng) in.readParcelable(LatLng.class.getClassLoader()));
+ snippet(in.readString());
+ String iconId = in.readString();
+ Bitmap iconBitmap = in.readParcelable(Bitmap.class.getClassLoader());
+ Icon icon = IconFactory.recreate(iconId, iconBitmap);
+ icon(icon);
+ title(in.readString());
+ }
- @Override
- public CityStateMarkerOptions getThis() {
- return this;
- }
+ @Override
+ public CityStateMarkerOptions getThis() {
+ return this;
+ }
- @Override
- public CityStateMarker getMarker() {
- return new CityStateMarker(this, infoWindowBackgroundColor);
- }
+ @Override
+ public CityStateMarker getMarker() {
+ return new CityStateMarker(this, infoWindowBackgroundColor);
+ }
- public static final Parcelable.Creator<CityStateMarkerOptions> CREATOR
- = new Parcelable.Creator<CityStateMarkerOptions>() {
- public CityStateMarkerOptions createFromParcel(Parcel in) {
- return new CityStateMarkerOptions(in);
- }
+ public static final Parcelable.Creator<CityStateMarkerOptions> CREATOR
+ = new Parcelable.Creator<CityStateMarkerOptions>() {
+ public CityStateMarkerOptions createFromParcel(Parcel in) {
+ return new CityStateMarkerOptions(in);
+ }
- public CityStateMarkerOptions[] newArray(int size) {
- return new CityStateMarkerOptions[size];
- }
+ public CityStateMarkerOptions[] newArray(int size) {
+ return new CityStateMarkerOptions[size];
+ }
};
- @Override
- public int describeContents() {
- return 0;
- }
+ @Override
+ public int describeContents() {
+ return 0;
+ }
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeParcelable(position, flags);
- out.writeString(snippet);
- out.writeString(icon.getId());
- out.writeParcelable(icon.getBitmap(), flags);
- out.writeString(title);
- }
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeParcelable(position, flags);
+ out.writeString(snippet);
+ out.writeString(icon.getId());
+ out.writeParcelable(icon.getBitmap(), flags);
+ out.writeString(title);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CountryMarker.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CountryMarker.java
index 7503b48df3..af97c9df69 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CountryMarker.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CountryMarker.java
@@ -5,20 +5,20 @@ import com.mapbox.mapboxsdk.annotations.Marker;
public class CountryMarker extends Marker {
- private String abbrevName;
- private int flagRes;
+ private String abbrevName;
+ private int flagRes;
- public CountryMarker(BaseMarkerOptions baseMarkerOptions, String abbrevName, int iconRes) {
- super(baseMarkerOptions);
- this.abbrevName = abbrevName;
- this.flagRes = iconRes;
- }
+ public CountryMarker(BaseMarkerOptions baseMarkerOptions, String abbrevName, int iconRes) {
+ super(baseMarkerOptions);
+ this.abbrevName = abbrevName;
+ this.flagRes = iconRes;
+ }
- public String getAbbrevName() {
- return abbrevName;
- }
+ public String getAbbrevName() {
+ return abbrevName;
+ }
- public int getFlagRes() {
- return flagRes;
- }
+ public int getFlagRes() {
+ return flagRes;
+ }
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CountryMarkerOptions.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CountryMarkerOptions.java
index ac1ff25bf2..0a64359979 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CountryMarkerOptions.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CountryMarkerOptions.java
@@ -11,65 +11,65 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
public class CountryMarkerOptions extends BaseMarkerOptions<CountryMarker, CountryMarkerOptions> {
- private String abbrevName;
- private int flagRes;
+ private String abbrevName;
+ private int flagRes;
- public CountryMarkerOptions abbrevName(String name) {
- abbrevName = name;
- return getThis();
- }
+ public CountryMarkerOptions abbrevName(String name) {
+ abbrevName = name;
+ return getThis();
+ }
- public CountryMarkerOptions flagRes(int imageRes) {
- flagRes = imageRes;
- return getThis();
- }
+ public CountryMarkerOptions flagRes(int imageRes) {
+ flagRes = imageRes;
+ return getThis();
+ }
- public CountryMarkerOptions() {
- }
+ public CountryMarkerOptions() {
+ }
- private CountryMarkerOptions(Parcel in) {
- position((LatLng) in.readParcelable(LatLng.class.getClassLoader()));
- snippet(in.readString());
- String iconId = in.readString();
- Bitmap iconBitmap = in.readParcelable(Bitmap.class.getClassLoader());
- Icon icon = IconFactory.recreate(iconId, iconBitmap);
- icon(icon);
- title(in.readString());
- }
+ private CountryMarkerOptions(Parcel in) {
+ position((LatLng) in.readParcelable(LatLng.class.getClassLoader()));
+ snippet(in.readString());
+ String iconId = in.readString();
+ Bitmap iconBitmap = in.readParcelable(Bitmap.class.getClassLoader());
+ Icon icon = IconFactory.recreate(iconId, iconBitmap);
+ icon(icon);
+ title(in.readString());
+ }
- @Override
- public CountryMarkerOptions getThis() {
- return this;
- }
+ @Override
+ public CountryMarkerOptions getThis() {
+ return this;
+ }
- @Override
- public CountryMarker getMarker() {
- return new CountryMarker(this, abbrevName, flagRes);
- }
+ @Override
+ public CountryMarker getMarker() {
+ return new CountryMarker(this, abbrevName, flagRes);
+ }
- public static final Parcelable.Creator<CountryMarkerOptions> CREATOR
- = new Parcelable.Creator<CountryMarkerOptions>() {
- public CountryMarkerOptions createFromParcel(Parcel in) {
- return new CountryMarkerOptions(in);
- }
+ public static final Parcelable.Creator<CountryMarkerOptions> CREATOR
+ = new Parcelable.Creator<CountryMarkerOptions>() {
+ public CountryMarkerOptions createFromParcel(Parcel in) {
+ return new CountryMarkerOptions(in);
+ }
- public CountryMarkerOptions[] newArray(int size) {
- return new CountryMarkerOptions[size];
- }
+ public CountryMarkerOptions[] newArray(int size) {
+ return new CountryMarkerOptions[size];
+ }
};
- @Override
- public int describeContents() {
- return 0;
- }
+ @Override
+ public int describeContents() {
+ return 0;
+ }
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeParcelable(position, flags);
- out.writeString(snippet);
- out.writeString(icon.getId());
- out.writeParcelable(icon.getBitmap(), flags);
- out.writeString(title);
- }
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeParcelable(position, flags);
+ out.writeString(snippet);
+ out.writeString(icon.getId());
+ out.writeParcelable(icon.getBitmap(), flags);
+ out.writeString(title);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CountryMarkerView.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CountryMarkerView.java
index 64f0565026..cab03e4f7a 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CountryMarkerView.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CountryMarkerView.java
@@ -5,20 +5,20 @@ import com.mapbox.mapboxsdk.annotations.MarkerView;
public class CountryMarkerView extends MarkerView {
- private String abbrevName;
- private int flagRes;
+ private String abbrevName;
+ private int flagRes;
- public CountryMarkerView(BaseMarkerViewOptions baseMarkerViewOptions, String abbrevName, int flagRes) {
- super(baseMarkerViewOptions);
- this.abbrevName = abbrevName;
- this.flagRes = flagRes;
- }
+ public CountryMarkerView(BaseMarkerViewOptions baseMarkerViewOptions, String abbrevName, int flagRes) {
+ super(baseMarkerViewOptions);
+ this.abbrevName = abbrevName;
+ this.flagRes = flagRes;
+ }
- public String getAbbrevName() {
- return abbrevName;
- }
+ public String getAbbrevName() {
+ return abbrevName;
+ }
- public int getFlagRes() {
- return flagRes;
- }
+ public int getFlagRes() {
+ return flagRes;
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CountryMarkerViewOptions.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CountryMarkerViewOptions.java
index 9059b5978b..4dc9195ffd 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CountryMarkerViewOptions.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CountryMarkerViewOptions.java
@@ -11,91 +11,89 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
public class CountryMarkerViewOptions extends BaseMarkerViewOptions<CountryMarkerView, CountryMarkerViewOptions> {
- private String abbrevName;
- private int flagRes;
-
- public CountryMarkerViewOptions() {
- }
-
- protected CountryMarkerViewOptions(Parcel in) {
- position((LatLng) in.readParcelable(LatLng.class.getClassLoader()));
- snippet(in.readString());
- title(in.readString());
- flat(in.readByte() != 0);
- anchor(in.readFloat(), in.readFloat());
- infoWindowAnchor(in.readFloat(), in.readFloat());
- rotation(in.readFloat());
- visible(in.readByte() != 0);
- alpha(in.readFloat());
- if (in.readByte() != 0) {
- // this means we have an icon
- String iconId = in.readString();
- Bitmap iconBitmap = in.readParcelable(Bitmap.class.getClassLoader());
- Icon icon = IconFactory.recreate(iconId, iconBitmap);
- icon(icon);
- }
- abbrevName(in.readString());
- flagRes(in.readInt());
- }
-
- @Override
- public CountryMarkerViewOptions getThis() {
- return this;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeParcelable(getPosition(), flags);
- out.writeString(getSnippet());
- out.writeString(getTitle());
- out.writeByte((byte) (isFlat() ? 1 : 0));
- out.writeFloat(getAnchorU());
- out.writeFloat(getAnchorV());
- out.writeFloat(getInfoWindowAnchorU());
- out.writeFloat(getInfoWindowAnchorV());
- out.writeFloat(getRotation());
- out.writeByte((byte) (isVisible() ? 1 : 0));
- out.writeFloat(getAlpha());
- Icon icon = getIcon();
- out.writeByte((byte) (icon != null ? 1 : 0));
- if (icon != null) {
- out.writeString(getIcon().getId());
- out.writeParcelable(getIcon().getBitmap(), flags);
- }
- out.writeString(abbrevName);
- out.writeInt(flagRes);
+ private String abbrevName;
+ private int flagRes;
+
+ public CountryMarkerViewOptions() {
+ }
+
+ protected CountryMarkerViewOptions(Parcel in) {
+ position((LatLng) in.readParcelable(LatLng.class.getClassLoader()));
+ snippet(in.readString());
+ title(in.readString());
+ flat(in.readByte() != 0);
+ anchor(in.readFloat(), in.readFloat());
+ infoWindowAnchor(in.readFloat(), in.readFloat());
+ rotation(in.readFloat());
+ visible(in.readByte() != 0);
+ alpha(in.readFloat());
+ if (in.readByte() != 0) {
+ // this means we have an icon
+ String iconId = in.readString();
+ Bitmap iconBitmap = in.readParcelable(Bitmap.class.getClassLoader());
+ Icon icon = IconFactory.recreate(iconId, iconBitmap);
+ icon(icon);
}
-
- @Override
- public CountryMarkerView getMarker() {
- return new CountryMarkerView(this, abbrevName, flagRes);
- }
-
- public CountryMarkerViewOptions abbrevName(String abbrevName) {
- this.abbrevName = abbrevName;
- return getThis();
- }
-
- public CountryMarkerViewOptions flagRes(int flagRes) {
- this.flagRes = flagRes;
- return getThis();
+ abbrevName(in.readString());
+ flagRes(in.readInt());
+ }
+
+ @Override
+ public CountryMarkerViewOptions getThis() {
+ return this;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeParcelable(getPosition(), flags);
+ out.writeString(getSnippet());
+ out.writeString(getTitle());
+ out.writeByte((byte) (isFlat() ? 1 : 0));
+ out.writeFloat(getAnchorU());
+ out.writeFloat(getAnchorV());
+ out.writeFloat(getInfoWindowAnchorU());
+ out.writeFloat(getInfoWindowAnchorV());
+ out.writeFloat(getRotation());
+ out.writeByte((byte) (isVisible() ? 1 : 0));
+ out.writeFloat(getAlpha());
+ Icon icon = getIcon();
+ out.writeByte((byte) (icon != null ? 1 : 0));
+ if (icon != null) {
+ out.writeString(getIcon().getId());
+ out.writeParcelable(getIcon().getBitmap(), flags);
}
-
- public static final Parcelable.Creator<CountryMarkerViewOptions> CREATOR
- = new Parcelable.Creator<CountryMarkerViewOptions>() {
- public CountryMarkerViewOptions createFromParcel(Parcel in) {
- return new CountryMarkerViewOptions(in);
- }
-
- public CountryMarkerViewOptions[] newArray(int size) {
- return new CountryMarkerViewOptions[size];
- }
+ out.writeString(abbrevName);
+ out.writeInt(flagRes);
+ }
+
+ @Override
+ public CountryMarkerView getMarker() {
+ return new CountryMarkerView(this, abbrevName, flagRes);
+ }
+
+ public CountryMarkerViewOptions abbrevName(String abbrevName) {
+ this.abbrevName = abbrevName;
+ return getThis();
+ }
+
+ public CountryMarkerViewOptions flagRes(int flagRes) {
+ this.flagRes = flagRes;
+ return getThis();
+ }
+
+ public static final Parcelable.Creator<CountryMarkerViewOptions> CREATOR
+ = new Parcelable.Creator<CountryMarkerViewOptions>() {
+ public CountryMarkerViewOptions createFromParcel(Parcel in) {
+ return new CountryMarkerViewOptions(in);
+ }
+
+ public CountryMarkerViewOptions[] newArray(int size) {
+ return new CountryMarkerViewOptions[size];
+ }
};
-
-
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/PulseMarkerView.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/PulseMarkerView.java
index 48867ea5eb..971c3359b2 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/PulseMarkerView.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/PulseMarkerView.java
@@ -5,7 +5,7 @@ import com.mapbox.mapboxsdk.annotations.MarkerView;
public class PulseMarkerView extends MarkerView {
- public PulseMarkerView(BaseMarkerViewOptions baseMarkerViewOptions) {
- super(baseMarkerViewOptions);
- }
+ public PulseMarkerView(BaseMarkerViewOptions baseMarkerViewOptions) {
+ super(baseMarkerViewOptions);
+ }
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/PulseMarkerViewOptions.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/PulseMarkerViewOptions.java
index 70ff6a22e2..20c479fc9b 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/PulseMarkerViewOptions.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/PulseMarkerViewOptions.java
@@ -11,69 +11,69 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
public class PulseMarkerViewOptions extends BaseMarkerViewOptions<PulseMarkerView, PulseMarkerViewOptions> {
- public PulseMarkerViewOptions() {
- }
+ public PulseMarkerViewOptions() {
+ }
- protected PulseMarkerViewOptions(Parcel in) {
- position((LatLng) in.readParcelable(LatLng.class.getClassLoader()));
- snippet(in.readString());
- title(in.readString());
- flat(in.readByte() != 0);
- anchor(in.readFloat(), in.readFloat());
- selected = in.readByte() != 0;
- rotation(in.readFloat());
- if (in.readByte() != 0) {
- // this means we have an icon
- String iconId = in.readString();
- Bitmap iconBitmap = in.readParcelable(Bitmap.class.getClassLoader());
- Icon icon = IconFactory.recreate(iconId, iconBitmap);
- icon(icon);
- }
+ protected PulseMarkerViewOptions(Parcel in) {
+ position((LatLng) in.readParcelable(LatLng.class.getClassLoader()));
+ snippet(in.readString());
+ title(in.readString());
+ flat(in.readByte() != 0);
+ anchor(in.readFloat(), in.readFloat());
+ selected = in.readByte() != 0;
+ rotation(in.readFloat());
+ if (in.readByte() != 0) {
+ // this means we have an icon
+ String iconId = in.readString();
+ Bitmap iconBitmap = in.readParcelable(Bitmap.class.getClassLoader());
+ Icon icon = IconFactory.recreate(iconId, iconBitmap);
+ icon(icon);
}
+ }
- @Override
- public PulseMarkerViewOptions getThis() {
- return this;
- }
+ @Override
+ public PulseMarkerViewOptions getThis() {
+ return this;
+ }
- @Override
- public int describeContents() {
- return 0;
- }
+ @Override
+ public int describeContents() {
+ return 0;
+ }
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeParcelable(getPosition(), flags);
- out.writeString(getSnippet());
- out.writeString(getTitle());
- out.writeByte((byte) (isFlat() ? 1 : 0));
- out.writeFloat(getAnchorU());
- out.writeFloat(getAnchorV());
- out.writeFloat(getInfoWindowAnchorU());
- out.writeFloat(getInfoWindowAnchorV());
- out.writeByte((byte) (selected ? 1 : 0));
- out.writeFloat(getRotation());
- Icon icon = getIcon();
- out.writeByte((byte) (icon != null ? 1 : 0));
- if (icon != null) {
- out.writeString(getIcon().getId());
- out.writeParcelable(getIcon().getBitmap(), flags);
- }
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeParcelable(getPosition(), flags);
+ out.writeString(getSnippet());
+ out.writeString(getTitle());
+ out.writeByte((byte) (isFlat() ? 1 : 0));
+ out.writeFloat(getAnchorU());
+ out.writeFloat(getAnchorV());
+ out.writeFloat(getInfoWindowAnchorU());
+ out.writeFloat(getInfoWindowAnchorV());
+ out.writeByte((byte) (selected ? 1 : 0));
+ out.writeFloat(getRotation());
+ Icon icon = getIcon();
+ out.writeByte((byte) (icon != null ? 1 : 0));
+ if (icon != null) {
+ out.writeString(getIcon().getId());
+ out.writeParcelable(getIcon().getBitmap(), flags);
}
+ }
- @Override
- public PulseMarkerView getMarker() {
- return new PulseMarkerView(this);
- }
+ @Override
+ public PulseMarkerView getMarker() {
+ return new PulseMarkerView(this);
+ }
- public static final Parcelable.Creator<CountryMarkerViewOptions> CREATOR
- = new Parcelable.Creator<CountryMarkerViewOptions>() {
- public CountryMarkerViewOptions createFromParcel(Parcel in) {
- return new CountryMarkerViewOptions(in);
- }
+ public static final Parcelable.Creator<CountryMarkerViewOptions> CREATOR
+ = new Parcelable.Creator<CountryMarkerViewOptions>() {
+ public CountryMarkerViewOptions createFromParcel(Parcel in) {
+ return new CountryMarkerViewOptions(in);
+ }
- public CountryMarkerViewOptions[] newArray(int size) {
- return new CountryMarkerViewOptions[size];
- }
+ public CountryMarkerViewOptions[] newArray(int size) {
+ return new CountryMarkerViewOptions[size];
+ }
};
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/TextMarkerView.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/TextMarkerView.java
index c0a589cb57..f507c5f1ab 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/TextMarkerView.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/TextMarkerView.java
@@ -5,14 +5,14 @@ import com.mapbox.mapboxsdk.annotations.MarkerView;
public class TextMarkerView extends MarkerView {
- private String text;
+ private String text;
- public TextMarkerView(BaseMarkerViewOptions baseMarkerViewOptions, String text) {
- super(baseMarkerViewOptions);
- this.text = text;
- }
+ public TextMarkerView(BaseMarkerViewOptions baseMarkerViewOptions, String text) {
+ super(baseMarkerViewOptions);
+ this.text = text;
+ }
- public String getText() {
- return text;
- }
+ public String getText() {
+ return text;
+ }
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/TextMarkerViewOptions.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/TextMarkerViewOptions.java
index a91ec5e541..df7c575f74 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/TextMarkerViewOptions.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/TextMarkerViewOptions.java
@@ -11,81 +11,81 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
public class TextMarkerViewOptions extends BaseMarkerViewOptions<TextMarkerView, TextMarkerViewOptions> {
- private String text;
+ private String text;
- public TextMarkerViewOptions() {
- }
+ public TextMarkerViewOptions() {
+ }
- protected TextMarkerViewOptions(Parcel in) {
- position((LatLng) in.readParcelable(LatLng.class.getClassLoader()));
- snippet(in.readString());
- title(in.readString());
- flat(in.readByte() != 0);
- anchor(in.readFloat(), in.readFloat());
- infoWindowAnchor(in.readFloat(), in.readFloat());
- rotation(in.readFloat());
- visible(in.readByte() != 0);
- alpha(in.readFloat());
- if (in.readByte() != 0) {
- // this means we have an icon
- String iconId = in.readString();
- Bitmap iconBitmap = in.readParcelable(Bitmap.class.getClassLoader());
- Icon icon = IconFactory.recreate(iconId, iconBitmap);
- icon(icon);
- }
- text(in.readString());
+ protected TextMarkerViewOptions(Parcel in) {
+ position((LatLng) in.readParcelable(LatLng.class.getClassLoader()));
+ snippet(in.readString());
+ title(in.readString());
+ flat(in.readByte() != 0);
+ anchor(in.readFloat(), in.readFloat());
+ infoWindowAnchor(in.readFloat(), in.readFloat());
+ rotation(in.readFloat());
+ visible(in.readByte() != 0);
+ alpha(in.readFloat());
+ if (in.readByte() != 0) {
+ // this means we have an icon
+ String iconId = in.readString();
+ Bitmap iconBitmap = in.readParcelable(Bitmap.class.getClassLoader());
+ Icon icon = IconFactory.recreate(iconId, iconBitmap);
+ icon(icon);
}
+ text(in.readString());
+ }
- @Override
- public TextMarkerViewOptions getThis() {
- return this;
- }
+ @Override
+ public TextMarkerViewOptions getThis() {
+ return this;
+ }
- @Override
- public int describeContents() {
- return 0;
- }
+ @Override
+ public int describeContents() {
+ return 0;
+ }
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeParcelable(getPosition(), flags);
- out.writeString(getSnippet());
- out.writeString(getTitle());
- out.writeByte((byte) (isFlat() ? 1 : 0));
- out.writeFloat(getAnchorU());
- out.writeFloat(getAnchorV());
- out.writeFloat(getInfoWindowAnchorU());
- out.writeFloat(getInfoWindowAnchorV());
- out.writeFloat(getRotation());
- out.writeByte((byte) (isVisible() ? 1 : 0));
- out.writeFloat(alpha);
- Icon icon = getIcon();
- out.writeByte((byte) (icon != null ? 1 : 0));
- if (icon != null) {
- out.writeString(getIcon().getId());
- out.writeParcelable(getIcon().getBitmap(), flags);
- }
- out.writeString(text);
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeParcelable(getPosition(), flags);
+ out.writeString(getSnippet());
+ out.writeString(getTitle());
+ out.writeByte((byte) (isFlat() ? 1 : 0));
+ out.writeFloat(getAnchorU());
+ out.writeFloat(getAnchorV());
+ out.writeFloat(getInfoWindowAnchorU());
+ out.writeFloat(getInfoWindowAnchorV());
+ out.writeFloat(getRotation());
+ out.writeByte((byte) (isVisible() ? 1 : 0));
+ out.writeFloat(alpha);
+ Icon icon = getIcon();
+ out.writeByte((byte) (icon != null ? 1 : 0));
+ if (icon != null) {
+ out.writeString(getIcon().getId());
+ out.writeParcelable(getIcon().getBitmap(), flags);
}
+ out.writeString(text);
+ }
- @Override
- public TextMarkerView getMarker() {
- return new TextMarkerView(this, text);
- }
+ @Override
+ public TextMarkerView getMarker() {
+ return new TextMarkerView(this, text);
+ }
- public TextMarkerViewOptions text(String text) {
- this.text = text;
- return getThis();
- }
+ public TextMarkerViewOptions text(String text) {
+ this.text = text;
+ return getThis();
+ }
- public static final Parcelable.Creator<CountryMarkerViewOptions> CREATOR
- = new Parcelable.Creator<CountryMarkerViewOptions>() {
- public CountryMarkerViewOptions createFromParcel(Parcel in) {
- return new CountryMarkerViewOptions(in);
- }
+ public static final Parcelable.Creator<CountryMarkerViewOptions> CREATOR
+ = new Parcelable.Creator<CountryMarkerViewOptions>() {
+ public CountryMarkerViewOptions createFromParcel(Parcel in) {
+ return new CountryMarkerViewOptions(in);
+ }
- public CountryMarkerViewOptions[] newArray(int size) {
- return new CountryMarkerViewOptions[size];
- }
+ public CountryMarkerViewOptions[] newArray(int size) {
+ return new CountryMarkerViewOptions[size];
+ }
};
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/constants/AppConstant.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/constants/AppConstant.java
index 095e47a3d2..aaef7f8a51 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/constants/AppConstant.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/constants/AppConstant.java
@@ -2,5 +2,5 @@ package com.mapbox.mapboxsdk.testapp.model.constants;
public class AppConstant {
- public static final int STYLE_VERSION = 9;
+ public static final int STYLE_VERSION = 9;
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/customlayer/ExampleCustomLayer.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/customlayer/ExampleCustomLayer.java
index 2901060459..8c049d7730 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/customlayer/ExampleCustomLayer.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/customlayer/ExampleCustomLayer.java
@@ -1,12 +1,15 @@
package com.mapbox.mapboxsdk.testapp.model.customlayer;
public class ExampleCustomLayer {
- static {
- System.loadLibrary("example-custom-layer");
- }
-
- public native static long createContext();
- public static long InitializeFunction;
- public static long RenderFunction;
- public static long DeinitializeFunction;
+ static {
+ System.loadLibrary("example-custom-layer");
+ }
+
+ public static native long createContext();
+
+ public static native void setColor(float red, float green, float blue, float alpha);
+
+ public static long InitializeFunction;
+ public static long RenderFunction;
+ public static long DeinitializeFunction;
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/other/OfflineDownloadRegionDialog.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/other/OfflineDownloadRegionDialog.java
index 493153d1c1..b70144123f 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/other/OfflineDownloadRegionDialog.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/other/OfflineDownloadRegionDialog.java
@@ -7,51 +7,51 @@ import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
-import android.util.Log;
+
+import timber.log.Timber;
+
import android.widget.EditText;
import com.mapbox.mapboxsdk.testapp.R;
public class OfflineDownloadRegionDialog extends DialogFragment {
- private static final String LOG_TAG = "OfflineDownloadRegionDialog";
-
- public interface DownloadRegionDialogListener {
- void onDownloadRegionDialogPositiveClick(String regionName);
- }
-
- DownloadRegionDialogListener listener;
-
- @Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
- listener = (DownloadRegionDialogListener) activity;
- }
-
- @NonNull
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
-
- // Let the user choose a name for the region
- final EditText regionNameEdit = new EditText(getActivity());
-
- builder.setTitle("Choose a name for the region")
- .setIcon(R.drawable.ic_airplanemode_active_black_24dp)
- .setView(regionNameEdit)
- .setPositiveButton("Start", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- String regionName = regionNameEdit.getText().toString();
- listener.onDownloadRegionDialogPositiveClick(regionName);
- }
- }).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- Log.d(LOG_TAG, "Download cancelled.");
- }
- });
-
- return builder.create();
- }
+ public interface DownloadRegionDialogListener {
+ void onDownloadRegionDialogPositiveClick(String regionName);
+ }
+
+ DownloadRegionDialogListener listener;
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ listener = (DownloadRegionDialogListener) activity;
+ }
+
+ @NonNull
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+
+ // Let the user choose a name for the region
+ final EditText regionNameEdit = new EditText(getActivity());
+
+ builder.setTitle("Choose a name for the region")
+ .setIcon(R.drawable.ic_airplanemode_active_black_24dp)
+ .setView(regionNameEdit)
+ .setPositiveButton("Start", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ String regionName = regionNameEdit.getText().toString();
+ listener.onDownloadRegionDialogPositiveClick(regionName);
+ }
+ }).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ Timber.d("Download cancelled.");
+ }
+ });
+
+ return builder.create();
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/other/OfflineListRegionsDialog.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/other/OfflineListRegionsDialog.java
index 2a5de869a5..65c4102a8c 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/other/OfflineListRegionsDialog.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/other/OfflineListRegionsDialog.java
@@ -6,7 +6,8 @@ import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog;
-import android.util.Log;
+
+import timber.log.Timber;
import com.mapbox.mapboxsdk.testapp.R;
@@ -14,35 +15,33 @@ import java.util.ArrayList;
public class OfflineListRegionsDialog extends DialogFragment {
- private static final String LOG_TAG = "OfflineListRegionsDialog";
-
- public static final String ITEMS = "ITEMS";
-
- @NonNull
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
-
- // Read args
- Bundle args = getArguments();
- ArrayList<String> offlineRegionsNames = (args == null ? null : args.getStringArrayList(ITEMS));
- CharSequence[] items = offlineRegionsNames.toArray(new CharSequence[offlineRegionsNames.size()]);
-
- builder.setTitle("List of offline regions")
- .setIcon(R.drawable.ic_airplanemode_active_black_24dp)
- .setItems(items, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- Log.d(LOG_TAG, "Selected item: " + which);
- }
- })
- .setPositiveButton("Accept", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- Log.d(LOG_TAG, "Dialog dismissed");
- }
- });
-
- return builder.create();
- }
+ public static final String ITEMS = "ITEMS";
+
+ @NonNull
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+
+ // Read args
+ Bundle args = getArguments();
+ ArrayList<String> offlineRegionsNames = (args == null ? null : args.getStringArrayList(ITEMS));
+ CharSequence[] items = offlineRegionsNames.toArray(new CharSequence[offlineRegionsNames.size()]);
+
+ builder.setTitle("List of offline regions")
+ .setIcon(R.drawable.ic_airplanemode_active_black_24dp)
+ .setItems(items, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ Timber.d("Selected item: " + which);
+ }
+ })
+ .setPositiveButton("Accept", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ Timber.d("Dialog dismissed");
+ }
+ });
+
+ return builder.create();
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/FontCache.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/FontCache.java
index 97bfb90d41..e2271bd5ff 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/FontCache.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/FontCache.java
@@ -2,26 +2,25 @@ package com.mapbox.mapboxsdk.testapp.utils;
import android.content.Context;
import android.graphics.Typeface;
-import android.util.Log;
-import com.mapbox.mapboxsdk.constants.MapboxConstants;
+import timber.log.Timber;
import java.util.Hashtable;
public class FontCache {
- private static Hashtable<String, Typeface> fontCache = new Hashtable<>();
+ private static Hashtable<String, Typeface> fontCache = new Hashtable<>();
- public static Typeface get(String name, Context context) {
- Typeface tf = fontCache.get(name);
- if (tf == null) {
- try {
- tf = Typeface.createFromAsset(context.getAssets(), name);
- fontCache.put(name, tf);
- } catch (Exception exception) {
- Log.e(MapboxConstants.TAG, "Font not found");
- }
- }
- return tf;
+ public static Typeface get(String name, Context context) {
+ Typeface tf = fontCache.get(name);
+ if (tf == null) {
+ try {
+ tf = Typeface.createFromAsset(context.getAssets(), name);
+ fontCache.put(name, tf);
+ } catch (Exception exception) {
+ Timber.e("Font not found");
+ }
}
+ return tf;
+ }
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/GeoParseUtil.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/GeoParseUtil.java
index d6a8280c6a..0d21fd2c71 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/GeoParseUtil.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/GeoParseUtil.java
@@ -20,54 +20,54 @@ import java.util.List;
public class GeoParseUtil {
- public static String loadStringFromAssets(final Context context, final String fileName) throws IOException {
- if (TextUtils.isEmpty(fileName)) {
- throw new NullPointerException("No GeoJSON File Name passed in.");
- }
- InputStream is = context.getAssets().open(fileName);
- BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
- return readAll(rd);
+ public static String loadStringFromAssets(final Context context, final String fileName) throws IOException {
+ if (TextUtils.isEmpty(fileName)) {
+ throw new NullPointerException("No GeoJSON File Name passed in.");
}
+ InputStream is = context.getAssets().open(fileName);
+ BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
+ return readAll(rd);
+ }
- public static List<LatLng> parseGeoJSONCoordinates(String geojsonStr) throws JSONException {
- List<LatLng> latLngs = new ArrayList<>();
- JSONObject jsonObject = new JSONObject(geojsonStr);
- JSONArray features = jsonObject.getJSONArray("features");
- int featureLength = features.length();
- for (int j = 0; j < featureLength; ++j) {
- JSONObject feature = features.getJSONObject(j);
- JSONObject geometry = feature.getJSONObject("geometry");
- String type = geometry.getString("type");
- JSONArray coordinates;
- if (type.equals("Polygon")) {
- coordinates = geometry.getJSONArray("coordinates").getJSONArray(0);
- } else {
- coordinates = geometry.getJSONArray("coordinates");
- }
- int len = coordinates.length();
- for (int i = 0; i < len; ++i) {
- if (coordinates.get(i) instanceof JSONArray) {
- JSONArray coord = coordinates.getJSONArray(i);
- double lng = coord.getDouble(0);
- double lat = coord.getDouble(1);
- latLngs.add(new LatLng(lat, lng));
- } else {
- double lng = coordinates.getDouble(0);
- double lat = coordinates.getDouble(1);
- latLngs.add(new LatLng(lat, lng));
- break;
- }
- }
+ public static List<LatLng> parseGeoJsonCoordinates(String geojsonStr) throws JSONException {
+ List<LatLng> latLngs = new ArrayList<>();
+ JSONObject jsonObject = new JSONObject(geojsonStr);
+ JSONArray features = jsonObject.getJSONArray("features");
+ int featureLength = features.length();
+ for (int j = 0; j < featureLength; ++j) {
+ JSONObject feature = features.getJSONObject(j);
+ JSONObject geometry = feature.getJSONObject("geometry");
+ String type = geometry.getString("type");
+ JSONArray coordinates;
+ if (type.equals("Polygon")) {
+ coordinates = geometry.getJSONArray("coordinates").getJSONArray(0);
+ } else {
+ coordinates = geometry.getJSONArray("coordinates");
+ }
+ int len = coordinates.length();
+ for (int i = 0; i < len; ++i) {
+ if (coordinates.get(i) instanceof JSONArray) {
+ JSONArray coord = coordinates.getJSONArray(i);
+ double lng = coord.getDouble(0);
+ double lat = coord.getDouble(1);
+ latLngs.add(new LatLng(lat, lng));
+ } else {
+ double lng = coordinates.getDouble(0);
+ double lat = coordinates.getDouble(1);
+ latLngs.add(new LatLng(lat, lng));
+ break;
}
- return latLngs;
+ }
}
+ return latLngs;
+ }
- private static String readAll(Reader rd) throws IOException {
- StringBuilder sb = new StringBuilder();
- int cp;
- while ((cp = rd.read()) != -1) {
- sb.append((char) cp);
- }
- return sb.toString();
+ private static String readAll(Reader rd) throws IOException {
+ StringBuilder sb = new StringBuilder();
+ int cp;
+ while ((cp = rd.read()) != -1) {
+ sb.append((char) cp);
}
+ return sb.toString();
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/ItemClickSupport.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/ItemClickSupport.java
index ba74d1d837..414a781544 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/ItemClickSupport.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/ItemClickSupport.java
@@ -6,90 +6,90 @@ import android.view.View;
import com.mapbox.mapboxsdk.testapp.R;
public class ItemClickSupport {
- private final RecyclerView recyclerView;
- private OnItemClickListener onItemClickListener;
- private OnItemLongClickListener onItemLongClickListener;
- private View.OnClickListener onClickListener = new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- if (onItemClickListener != null) {
- RecyclerView.ViewHolder holder = recyclerView.getChildViewHolder(view);
- onItemClickListener.onItemClicked(recyclerView, holder.getAdapterPosition(), view);
- }
+ private final RecyclerView recyclerView;
+ private OnItemClickListener onItemClickListener;
+ private OnItemLongClickListener onItemLongClickListener;
+ private View.OnClickListener onClickListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ if (onItemClickListener != null) {
+ RecyclerView.ViewHolder holder = recyclerView.getChildViewHolder(view);
+ onItemClickListener.onItemClicked(recyclerView, holder.getAdapterPosition(), view);
+ }
+ }
+ };
+ private View.OnLongClickListener onLongClickListener = new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View view) {
+ if (onItemLongClickListener != null) {
+ RecyclerView.ViewHolder holder = recyclerView.getChildViewHolder(view);
+ return onItemLongClickListener.onItemLongClicked(recyclerView, holder.getAdapterPosition(), view);
+ }
+ return false;
+ }
+ };
+ private RecyclerView.OnChildAttachStateChangeListener attachListener
+ = new RecyclerView.OnChildAttachStateChangeListener() {
+ @Override
+ public void onChildViewAttachedToWindow(View view) {
+ if (onItemClickListener != null) {
+ view.setOnClickListener(onClickListener);
}
- };
- private View.OnLongClickListener onLongClickListener = new View.OnLongClickListener() {
- @Override
- public boolean onLongClick(View view) {
- if (onItemLongClickListener != null) {
- RecyclerView.ViewHolder holder = recyclerView.getChildViewHolder(view);
- return onItemLongClickListener.onItemLongClicked(recyclerView, holder.getAdapterPosition(), view);
- }
- return false;
- }
- };
- private RecyclerView.OnChildAttachStateChangeListener attachListener
- = new RecyclerView.OnChildAttachStateChangeListener() {
- @Override
- public void onChildViewAttachedToWindow(View view) {
- if (onItemClickListener != null) {
- view.setOnClickListener(onClickListener);
- }
- if (onItemLongClickListener != null) {
- view.setOnLongClickListener(onLongClickListener);
- }
+ if (onItemLongClickListener != null) {
+ view.setOnLongClickListener(onLongClickListener);
}
+ }
- @Override
- public void onChildViewDetachedFromWindow(View view) {
+ @Override
+ public void onChildViewDetachedFromWindow(View view) {
- }
+ }
};
- private ItemClickSupport(RecyclerView recyclerView) {
- this.recyclerView = recyclerView;
- this.recyclerView.setTag(R.id.item_click_support, this);
- this.recyclerView.addOnChildAttachStateChangeListener(attachListener);
- }
+ private ItemClickSupport(RecyclerView recyclerView) {
+ this.recyclerView = recyclerView;
+ this.recyclerView.setTag(R.id.item_click_support, this);
+ this.recyclerView.addOnChildAttachStateChangeListener(attachListener);
+ }
- public static ItemClickSupport addTo(RecyclerView view) {
- ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support);
- if (support == null) {
- support = new ItemClickSupport(view);
- }
- return support;
+ public static ItemClickSupport addTo(RecyclerView view) {
+ ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support);
+ if (support == null) {
+ support = new ItemClickSupport(view);
}
+ return support;
+ }
- public static ItemClickSupport removeFrom(RecyclerView view) {
- ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support);
- if (support != null) {
- support.detach(view);
- }
- return support;
+ public static ItemClickSupport removeFrom(RecyclerView view) {
+ ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support);
+ if (support != null) {
+ support.detach(view);
}
+ return support;
+ }
- public ItemClickSupport setOnItemClickListener(OnItemClickListener listener) {
- onItemClickListener = listener;
- return this;
- }
+ public ItemClickSupport setOnItemClickListener(OnItemClickListener listener) {
+ onItemClickListener = listener;
+ return this;
+ }
- public ItemClickSupport setOnItemLongClickListener(OnItemLongClickListener listener) {
- onItemLongClickListener = listener;
- return this;
- }
+ public ItemClickSupport setOnItemLongClickListener(OnItemLongClickListener listener) {
+ onItemLongClickListener = listener;
+ return this;
+ }
- private void detach(RecyclerView view) {
- view.removeOnChildAttachStateChangeListener(attachListener);
- view.setTag(R.id.item_click_support, null);
- }
+ private void detach(RecyclerView view) {
+ view.removeOnChildAttachStateChangeListener(attachListener);
+ view.setTag(R.id.item_click_support, null);
+ }
- public interface OnItemClickListener {
+ public interface OnItemClickListener {
- void onItemClicked(RecyclerView recyclerView, int position, View view);
- }
+ void onItemClicked(RecyclerView recyclerView, int position, View view);
+ }
- public interface OnItemLongClickListener {
+ public interface OnItemLongClickListener {
- boolean onItemLongClicked(RecyclerView recyclerView, int position, View view);
- }
+ boolean onItemLongClicked(RecyclerView recyclerView, int position, View view);
+ }
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/OfflineUtils.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/OfflineUtils.java
index ee4ae039ee..8c6ab3e211 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/OfflineUtils.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/OfflineUtils.java
@@ -1,7 +1,8 @@
package com.mapbox.mapboxsdk.testapp.utils;
import android.support.annotation.NonNull;
-import android.util.Log;
+
+import timber.log.Timber;
import org.json.JSONObject;
@@ -10,27 +11,27 @@ import static com.mapbox.mapboxsdk.testapp.activity.offline.OfflineActivity.JSON
public class OfflineUtils {
- public static String convertRegionName(@NonNull byte[] metadata) {
- try {
- String json = new String(metadata, JSON_CHARSET);
- JSONObject jsonObject = new JSONObject(json);
- return jsonObject.getString(JSON_FIELD_REGION_NAME);
- } catch (Exception exception) {
- return null;
- }
+ public static String convertRegionName(@NonNull byte[] metadata) {
+ try {
+ String json = new String(metadata, JSON_CHARSET);
+ JSONObject jsonObject = new JSONObject(json);
+ return jsonObject.getString(JSON_FIELD_REGION_NAME);
+ } catch (Exception exception) {
+ return null;
}
+ }
- public static byte[] convertRegionName(String regionName) {
- byte[] metadata = null;
- try {
- JSONObject jsonObject = new JSONObject();
- jsonObject.put(JSON_FIELD_REGION_NAME, regionName);
- String json = jsonObject.toString();
- metadata = json.getBytes(JSON_CHARSET);
- } catch (Exception exception) {
- Log.e("OfflineUtils", "Failed to encode metadata: " + exception.getMessage());
- }
- return metadata;
+ public static byte[] convertRegionName(String regionName) {
+ byte[] metadata = null;
+ try {
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put(JSON_FIELD_REGION_NAME, regionName);
+ String json = jsonObject.toString();
+ metadata = json.getBytes(JSON_CHARSET);
+ } catch (Exception exception) {
+ Timber.e("Failed to encode metadata: " + exception.getMessage());
}
-
+ return metadata;
+ }
+
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/TimingLogger.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/TimingLogger.java
index 544e737780..e096aa202d 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/TimingLogger.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/TimingLogger.java
@@ -1,3 +1,4 @@
+package com.mapbox.mapboxsdk.testapp.utils;
/*
* Copyright (C) 2007 The Android Open Source Project
*
@@ -13,17 +14,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.mapbox.mapboxsdk.testapp.utils;
+
+import android.os.SystemClock;
import java.util.ArrayList;
-import android.os.SystemClock;
-import android.util.Log;
+import timber.log.Timber;
/**
* A utility class to help log timings splits throughout a method call.
* Typical usage is:
- *
+ * <p>
* <pre>
* TimingLogger timings = new TimingLogger(TAG, "methodA");
* // ... do some work A ...
@@ -34,9 +35,9 @@ import android.util.Log;
* timings.addSplit("work C");
* timings.dumpToLog();
* </pre>
- *
+ * <p>
* <p>The dumpToLog call would add the following to the log:</p>
- *
+ * <p>
* <pre>
* D/TAG ( 3459): methodA: begin
* D/TAG ( 3459): methodA: 9 ms, work A
@@ -46,108 +47,114 @@ import android.util.Log;
* </pre>
*/
public class TimingLogger {
- /**
- * The Log tag to use for checking Log.isLoggable and for
- * logging the timings.
- */
- private String mTag;
- /**
- * A label to be included in every log.
- */
- private String mLabel;
- /**
- * Used to track whether Log.isLoggable was enabled at reset time.
- */
- private boolean mDisabled;
- /**
- * Stores the time of each split.
- */
- ArrayList<Long> mSplits;
- /**
- * Stores the labels for each split.
- */
- ArrayList<String> mSplitLabels;
+ /**
+ * The Log tag to use for checking Log.isLoggable and for
+ * logging the timings.
+ */
+ private String tag;
+ /**
+ * A label to be included in every log.
+ */
+ private String label;
+ /**
+ * Used to track whether Log.isLoggable was enabled at reset time.
+ */
+ private boolean disabled;
+ /**
+ * Stores the time of each split.
+ */
+ private ArrayList<Long> splits;
+ /**
+ * Stores the labels for each split.
+ */
+ private ArrayList<String> splitLabels;
- /**
- * Create and initialize a TimingLogger object that will log using
- * the specific tag. If the Log.isLoggable is not enabled to at
- * least the Log.VERBOSE level for that tag at creation time then
- * the addSplit and dumpToLog call will do nothing.
- *
- * @param tag the log tag to use while logging the timings
- * @param label a string to be displayed with each log
- */
- public TimingLogger(String tag, String label) {
- reset(tag, label);
- }
+ /**
+ * Create and initialize a TimingLogger object that will log using
+ * the specific tag. If the Log.isLoggable is not enabled to at
+ * least the Log.VERBOSE level for that tag at creation time then
+ * the addSplit and dumpToLog call will do nothing.
+ *
+ * @param tag the log tag to use while logging the timings
+ * @param label a string to be displayed with each log
+ */
+ public TimingLogger(String tag, String label) {
+ reset(tag, label);
+ }
- /**
- * Clear and initialize a TimingLogger object that will log using
- * the specific tag. If the Log.isLoggable is not enabled to at
- * least the Log.VERBOSE level for that tag at creation time then
- * the addSplit and dumpToLog call will do nothing.
- *
- * @param tag the log tag to use while logging the timings
- * @param label a string to be displayed with each log
- */
- public void reset(String tag, String label) {
- mTag = tag;
- mLabel = label;
- reset();
- }
+ /**
+ * Clear and initialize a TimingLogger object that will log using
+ * the specific tag. If the Log.isLoggable is not enabled to at
+ * least the Log.VERBOSE level for that tag at creation time then
+ * the addSplit and dumpToLog call will do nothing.
+ *
+ * @param tag the log tag to use while logging the timings
+ * @param label a string to be displayed with each log
+ */
+ public void reset(String tag, String label) {
+ this.tag = tag;
+ this.label = label;
+ reset();
+ }
- /**
- * Clear and initialize a TimingLogger object that will log using
- * the tag and label that was specified previously, either via
- * the constructor or a call to reset(tag, label). If the
- * Log.isLoggable is not enabled to at least the Log.VERBOSE
- * level for that tag at creation time then the addSplit and
- * dumpToLog call will do nothing.
- */
- public void reset() {
- mDisabled = false; //!Log.isLoggable(mTag, Log.VERBOSE);
- if (mDisabled) return;
- if (mSplits == null) {
- mSplits = new ArrayList<Long>();
- mSplitLabels = new ArrayList<String>();
- } else {
- mSplits.clear();
- mSplitLabels.clear();
- }
- addSplit(null);
+ /**
+ * Clear and initialize a TimingLogger object that will log using
+ * the tag and label that was specified previously, either via
+ * the constructor or a call to reset(tag, label). If the
+ * Log.isLoggable is not enabled to at least the Log.VERBOSE
+ * level for that tag at creation time then the addSplit and
+ * dumpToLog call will do nothing.
+ */
+ public void reset() {
+ disabled = false; //!Log.isLoggable(tag, Log.VERBOSE);
+ if (disabled) {
+ return;
+ }
+ if (splits == null) {
+ splits = new ArrayList<Long>();
+ splitLabels = new ArrayList<String>();
+ } else {
+ splits.clear();
+ splitLabels.clear();
}
+ addSplit(null);
+ }
- /**
- * Add a split for the current time, labeled with splitLabel. If
- * Log.isLoggable was not enabled to at least the Log.VERBOSE for
- * the specified tag at construction or reset() time then this
- * call does nothing.
- *
- * @param splitLabel a label to associate with this split.
- */
- public void addSplit(String splitLabel) {
- if (mDisabled) return;
- long now = SystemClock.elapsedRealtime();
- mSplits.add(now);
- mSplitLabels.add(splitLabel);
+ /**
+ * Add a split for the current time, labeled with splitLabel. If
+ * Log.isLoggable was not enabled to at least the Log.VERBOSE for
+ * the specified tag at construction or reset() time then this
+ * call does nothing.
+ *
+ * @param splitLabel a label to associate with this split.
+ */
+ public void addSplit(String splitLabel) {
+ if (disabled) {
+ return;
}
+ long now = SystemClock.elapsedRealtime();
+ splits.add(now);
+ splitLabels.add(splitLabel);
+ }
- /**
- * Dumps the timings to the log using Log.d(). If Log.isLoggable was
- * not enabled to at least the Log.VERBOSE for the specified tag at
- * construction or reset() time then this call does nothing.
- */
- public void dumpToLog() {
- if (mDisabled) return;
- Log.d(mTag, mLabel + ": begin");
- final long first = mSplits.get(0);
- long now = first;
- for (int i = 1; i < mSplits.size(); i++) {
- now = mSplits.get(i);
- final String splitLabel = mSplitLabels.get(i);
- final long prev = mSplits.get(i - 1);
- Log.d(mTag, mLabel + ": " + (now - prev) + " ms, " + splitLabel);
- }
- Log.d(mTag, mLabel + ": end, " + (now - first) + " ms");
+ /**
+ * Dumps the timings to the log using Timber.d(). If Log.isLoggable was
+ * not enabled to at least the Log.VERBOSE for the specified tag at
+ * construction or reset() time then this call does nothing.
+ */
+ public void dumpToLog() {
+ if (disabled) {
+ return;
+ }
+ Timber.d(label + ": begin");
+ final long first = splits.get(0);
+ long now = first;
+ for (int i = 1; i < splits.size(); i++) {
+ now = splits.get(i);
+ final String splitLabel = splitLabels.get(i);
+ final long prev = splits.get(i - 1);
+ Timber.d(label + ": " + (now - prev) + " ms, " + splitLabel);
}
+ Timber.d(label + ": end, " + (now - first) + " ms");
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/ToolbarComposer.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/ToolbarComposer.java
index 7822e41bd9..3fa3bcd26f 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/ToolbarComposer.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/ToolbarComposer.java
@@ -15,35 +15,35 @@ import com.mapbox.mapboxsdk.testapp.R;
public class ToolbarComposer {
- /**
- * Initialises an up navigation toolbar with id R.id.toolbar on an AppCompatActivity.
- *
- * @param activity The activity hosting the Toolbar with id R.id.toolbar
- */
- @Nullable
- public static Toolbar initDefaultUpToolbar(@NonNull AppCompatActivity activity) {
- return initDefaultUpToolbar(activity, R.id.toolbar);
- }
-
- /**
- * Initialises an up navigation toolbar given a view id on an AppCompatActivity.
- *
- * @param activity The activity hosting the Toolbar
- * @param toolbarRes The view id resource used to look up the Toolbar
- */
- @Nullable
- public static Toolbar initDefaultUpToolbar(@NonNull AppCompatActivity activity, @IdRes int toolbarRes) {
- Toolbar toolbar = (Toolbar) activity.findViewById(toolbarRes);
- if (toolbar != null) {
- activity.setSupportActionBar(toolbar);
-
- ActionBar actionBar = activity.getSupportActionBar();
- if (actionBar != null) {
- actionBar.setDisplayHomeAsUpEnabled(true);
- actionBar.setDisplayShowHomeEnabled(true);
- }
- }
- return toolbar;
+ /**
+ * Initialises an up navigation toolbar with id R.id.toolbar on an AppCompatActivity.
+ *
+ * @param activity The activity hosting the Toolbar with id R.id.toolbar
+ */
+ @Nullable
+ public static Toolbar initDefaultUpToolbar(@NonNull AppCompatActivity activity) {
+ return initDefaultUpToolbar(activity, R.id.toolbar);
+ }
+
+ /**
+ * Initialises an up navigation toolbar given a view id on an AppCompatActivity.
+ *
+ * @param activity The activity hosting the Toolbar
+ * @param toolbarRes The view id resource used to look up the Toolbar
+ */
+ @Nullable
+ public static Toolbar initDefaultUpToolbar(@NonNull AppCompatActivity activity, @IdRes int toolbarRes) {
+ Toolbar toolbar = (Toolbar) activity.findViewById(toolbarRes);
+ if (toolbar != null) {
+ activity.setSupportActionBar(toolbar);
+
+ ActionBar actionBar = activity.getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setDisplayShowHomeEnabled(true);
+ }
}
+ return toolbar;
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-hdpi/ic_launcher_round.png b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000000..b5e1edc785
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-hdpi/ic_launcher_round.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/ic_launcher_round.png b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000000..0b28b92c61
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/ic_launcher_round.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xhdpi/ic_launcher_round.png b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000000..eeddbaca3f
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xhdpi/ic_launcher_round.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxhdpi/ic_launcher_round.png b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000000..bbc99eae41
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxhdpi/ic_launcher_round.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxxhdpi/ic_launcher_round.png b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000000..70ab174fc2
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxxhdpi/ic_launcher_round.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_add_sprite.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_add_sprite.xml
index 086b18fea1..e0e2cbfdab 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_add_sprite.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_add_sprite.xml
@@ -16,10 +16,10 @@
android:id="@id/mapView"
android:layout_below="@id/toolbar"
android:layout_width="match_parent"
- app:center_latitude="52.519003"
- app:center_longitude="13.400972"
- app:style_url="@string/style_mapbox_streets"
- app:zoom="16"
+ app:mapbox_cameraTargetLat="52.519003"
+ app:mapbox_cameraTargetLng="13.400972"
+ app:mapbox_styleUrl="@string/mapbox_style_mapbox_streets"
+ app:mapbox_cameraZoom="16"
android:layout_height="match_parent"/>
<android.support.design.widget.FloatingActionButton
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_animated_marker.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_animated_marker.xml
index eabfc30b25..6534c23c72 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_animated_marker.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_animated_marker.xml
@@ -17,9 +17,9 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/toolbar"
- app:center_latitude="51.502615"
- app:center_longitude="4.972326"
- app:style_url="@string/style_light"
- app:zoom="6" />
+ app:mapbox_cameraTargetLat="51.502615"
+ app:mapbox_cameraTargetLng="4.972326"
+ app:mapbox_styleUrl="@string/mapbox_style_light"
+ app:mapbox_cameraZoom="6" />
</RelativeLayout>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_camera_animation_types.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_camera_animation_types.xml
index 5a5fb5f604..8a139083f8 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_camera_animation_types.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_camera_animation_types.xml
@@ -17,9 +17,9 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/toolbar"
- app:center_latitude="51.50325"
- app:center_longitude="-0.11968"
- app:zoom="15" />
+ app:mapbox_cameraTargetLat="51.50325"
+ app:mapbox_cameraTargetLng="-0.11968"
+ app:mapbox_cameraZoom="15" />
<LinearLayout
android:layout_width="match_parent"
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_camera_position.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_camera_position.xml
index 2e08f79e95..a1d7a8351d 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_camera_position.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_camera_position.xml
@@ -21,7 +21,7 @@
android:id="@id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:style_url="@string/style_mapbox_streets" />
+ app:mapbox_styleUrl="@string/mapbox_style_mapbox_streets" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_camera_test.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_camera_test.xml
new file mode 100644
index 0000000000..4f86120097
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_camera_test.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <android.support.v7.widget.Toolbar
+ android:id="@+id/toolbar"
+ android:layout_width="match_parent"
+ android:layout_height="?attr/actionBarSize"
+ android:background="@color/primary"
+ android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
+
+ <!-- TODO remove zoom #6747-->
+ <com.mapbox.mapboxsdk.maps.MapView
+ android:id="@id/mapView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_below="@id/toolbar"
+ app:mapbox_cameraZoom="1" />
+
+</RelativeLayout>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_car_driving.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_car_driving.xml
index c61055ee4e..f52d5e70c2 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_car_driving.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_car_driving.xml
@@ -16,9 +16,9 @@
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:my_location_foreground_tint="@color/primary"
- app:my_location_accuracy_tint="@color/primary"
- app:style_url="@string/style_mapbox_streets"
- app:zoom="15" />
+ app:mapbox_myLocationTintColor="@color/primary"
+ app:mapbox_myLocationAccuracyTintColor="@color/primary"
+ app:mapbox_styleUrl="@string/mapbox_style_mapbox_streets"
+ app:mapbox_cameraZoom="15" />
</LinearLayout>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_circlelayer.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_circlelayer.xml
index 086b18fea1..e0e2cbfdab 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_circlelayer.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_circlelayer.xml
@@ -16,10 +16,10 @@
android:id="@id/mapView"
android:layout_below="@id/toolbar"
android:layout_width="match_parent"
- app:center_latitude="52.519003"
- app:center_longitude="13.400972"
- app:style_url="@string/style_mapbox_streets"
- app:zoom="16"
+ app:mapbox_cameraTargetLat="52.519003"
+ app:mapbox_cameraTargetLng="13.400972"
+ app:mapbox_styleUrl="@string/mapbox_style_mapbox_streets"
+ app:mapbox_cameraZoom="16"
android:layout_height="match_parent"/>
<android.support.design.widget.FloatingActionButton
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_directions.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_directions.xml
index 5de3651272..bc100b6059 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_directions.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_directions.xml
@@ -16,6 +16,6 @@
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:style_url="@string/style_mapbox_streets" />
+ app:mapbox_styleUrl="@string/mapbox_style_mapbox_streets" />
</LinearLayout>
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 d6507559ec..2625e65bbf 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
@@ -26,12 +26,12 @@
android:id="@id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:center_latitude="51.506675"
- app:center_longitude="-0.128699"
- app:compass_fade_facing_north="false"
- app:direction="90"
- app:tilt="40"
- app:zoom="10" />
+ app:mapbox_cameraTargetLat="51.506675"
+ app:mapbox_cameraTargetLng="-0.128699"
+ app:mapbox_uiCompassFadeFacingNorth="false"
+ app:mapbox_cameraBearing="90"
+ app:mapbox_cameraTilt="40"
+ app:mapbox_cameraZoom="10" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_geocoder.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_geocoder.xml
index 002ece58bf..d13d16a73e 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_geocoder.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_geocoder.xml
@@ -17,9 +17,9 @@
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="5"
- app:center_latitude="38.90962"
- app:center_longitude="-77.04341"
- app:zoom="15" />
+ app:mapbox_cameraTargetLat="38.90962"
+ app:mapbox_cameraTargetLng="-77.04341"
+ app:mapbox_cameraZoom="15" />
<TextView
android:id="@+id/message"
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow.xml
index e69983941a..1c8e33fb33 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow.xml
@@ -16,9 +16,9 @@
android:id="@id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:center_latitude="38.897705003219784"
- app:center_longitude="-77.03655168667463"
- app:style_url="@string/style_mapbox_streets"
- app:zoom="15" />
+ app:mapbox_cameraTargetLat="38.897705003219784"
+ app:mapbox_cameraTargetLng="-77.03655168667463"
+ app:mapbox_styleUrl="@string/mapbox_style_mapbox_streets"
+ app:mapbox_cameraZoom="15" />
</LinearLayout>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow_adapter.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow_adapter.xml
index dde63c8420..134c3f331e 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow_adapter.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow_adapter.xml
@@ -16,9 +16,9 @@
android:id="@id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:center_latitude="47.798202"
- app:center_longitude="7.573781"
- app:style_url="@string/style_mapbox_streets"
- app:zoom="4" />
+ app:mapbox_cameraTargetLat="47.798202"
+ app:mapbox_cameraTargetLng="7.573781"
+ app:mapbox_styleUrl="@string/mapbox_style_mapbox_streets"
+ app:mapbox_cameraZoom="4" />
</LinearLayout>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow_adapter_dynamic.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow_adapter_dynamic.xml
index dde63c8420..134c3f331e 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow_adapter_dynamic.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_infowindow_adapter_dynamic.xml
@@ -16,9 +16,9 @@
android:id="@id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:center_latitude="47.798202"
- app:center_longitude="7.573781"
- app:style_url="@string/style_mapbox_streets"
- app:zoom="4" />
+ app:mapbox_cameraTargetLat="47.798202"
+ app:mapbox_cameraTargetLng="7.573781"
+ app:mapbox_styleUrl="@string/mapbox_style_mapbox_streets"
+ app:mapbox_cameraZoom="4" />
</LinearLayout>
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 c1f09a36d0..3732326f39 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
@@ -14,10 +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"
+ app:mapbox_cameraTargetLat="50.871062"
+ app:mapbox_cameraTargetLng="1.583210"
+ app:mapbox_cameraBearing="220"
+ app:mapbox_cameraZoom="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_map_simple.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_map_simple.xml
new file mode 100644
index 0000000000..4ad49e4a9f
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_map_simple.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <android.support.v7.widget.Toolbar
+ android:id="@+id/toolbar"
+ android:layout_width="match_parent"
+ android:layout_height="?attr/actionBarSize"
+ android:background="@color/primary"
+ android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
+
+ <com.mapbox.mapboxsdk.maps.MapView
+ android:id="@id/mapView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+</LinearLayout>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_marker_bulk.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_marker_bulk.xml
index 90cb1a90b3..229d8e87c1 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_marker_bulk.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_marker_bulk.xml
@@ -22,11 +22,11 @@
android:id="@id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:center_latitude="38.87031"
+ app:mapbox_cameraTargetLat="38.87031"
android:layout_below="@id/toolbar"
- app:center_longitude="-77.00897"
- app:style_url="@string/style_mapbox_streets"
- app:zoom="10" />
+ app:mapbox_cameraTargetLng="-77.00897"
+ app:mapbox_styleUrl="@string/mapbox_style_mapbox_streets"
+ app:mapbox_cameraZoom="10" />
<TextView
android:id="@+id/countView"
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_marker_view.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_marker_view.xml
index 5d285958f1..f06975466b 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_marker_view.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_marker_view.xml
@@ -16,10 +16,10 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/toolbar"
- app:center_latitude="38.907192"
- app:center_longitude="-77.036871"
- app:style_url="@string/style_mapbox_streets"
- app:zoom="12" />
+ app:mapbox_cameraTargetLat="38.907192"
+ app:mapbox_cameraTargetLng="-77.036871"
+ app:mapbox_styleUrl="@string/mapbox_style_mapbox_streets"
+ app:mapbox_cameraZoom="12" />
<TextView
android:id="@+id/countView"
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_marker_view_in_rect.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_marker_view_in_rect.xml
new file mode 100644
index 0000000000..36dd89c885
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_marker_view_in_rect.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <android.support.v7.widget.Toolbar
+ android:id="@+id/toolbar"
+ android:layout_width="match_parent"
+ android:layout_height="?attr/actionBarSize"
+ android:background="@color/primary"
+ android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
+
+ <com.mapbox.mapboxsdk.maps.MapView
+ android:id="@+id/mapView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_below="@id/toolbar"/>
+
+ <FrameLayout
+ android:id="@+id/selection_box"
+ android:layout_width="150dp"
+ android:layout_height="150dp"
+ android:layout_centerInParent="true"
+ android:alpha="0.3"
+ android:background="#1d72da"/>
+
+</RelativeLayout>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_marker_view_scale.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_marker_view_scale.xml
index c59f41539c..8f98b5bea2 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_marker_view_scale.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_marker_view_scale.xml
@@ -39,6 +39,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/title"
+ android:clickable="false"
android:layout_marginLeft="56dp"
android:progress="0" />
@@ -52,9 +53,9 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/toolbar"
- app:center_latitude="38.907192"
- app:center_longitude="-77.036871"
- app:style_url="@string/style_mapbox_streets"
- app:zoom="12" />
+ app:mapbox_cameraTargetLat="38.907192"
+ app:mapbox_cameraTargetLng="-77.036871"
+ app:mapbox_styleUrl="@string/mapbox_style_mapbox_streets"
+ app:mapbox_cameraZoom="12" />
</RelativeLayout>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_maxmin_zoom.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_maxmin_zoom.xml
index 951344e35a..20de7c00bf 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_maxmin_zoom.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_maxmin_zoom.xml
@@ -17,9 +17,9 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/toolbar"
- app:center_latitude="-1.063510"
- app:center_longitude=" 32.895425"
- app:style_url="@string/style_satellite_streets"
- app:zoom="4" />
+ app:mapbox_cameraTargetLat="-1.063510"
+ app:mapbox_cameraTargetLng=" 32.895425"
+ app:mapbox_styleUrl="@string/mapbox_style_satellite_streets"
+ app:mapbox_cameraZoom="4" />
</RelativeLayout>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_my_location_dot_color.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_my_location_dot_color.xml
index af755c72a1..d41cc79326 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_my_location_dot_color.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_my_location_dot_color.xml
@@ -1,50 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:mapbox="http://schemas.android.com/tools"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
+ android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/primary"
- android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
+ android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<com.mapbox.mapboxsdk.maps.MapView
android:id="@id/mapView"
- android:layout_below="@+id/toolbar"
android:layout_width="match_parent"
- android:layout_height="match_parent"/>
+ android:layout_height="match_parent"
+ android:layout_below="@+id/toolbar"
+ mapbox:mapbox_uiAttribution="false"
+ mapbox:mapbox_uiLogo="false"/>
<LinearLayout
+ style="?android:attr/buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
+ android:background="@color/accent"
android:orientation="horizontal"
- android:weightSum="3">
+ android:weightSum="4">
<Button
android:id="@+id/default_user_dot_coloring_button"
+ style="?android:attr/buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
- android:text="@string/button_user_dot_default" />
+ android:text="@string/button_user_dot_default"
+ android:textColor="@color/white"/>
<Button
android:id="@+id/tint_user_dot_button"
+ style="?android:attr/buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
- android:text="@string/button_user_dot_tint" />
+ android:text="@string/button_user_dot_tint"
+ android:textColor="@color/white"/>
<Button
android:id="@+id/user_accuracy_ring_tint_button"
+ style="?android:attr/buttonBarButtonStyle"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="@string/button_user_accuracy_ring_tint"
+ android:textColor="@color/white"/>
+
+ <Button
+ android:id="@+id/user_dot_transparent_button"
+ style="?android:attr/buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
- android:text="@string/button_user_accuracy_ring_tint" />
+ android:text="@string/button_user_transparent_tint"
+ android:textColor="@color/white"/>
- </LinearLayout>
+ </LinearLayout>
</RelativeLayout> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_my_location_tracking.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_my_location_tracking.xml
index 19c30dbb8d..95f084506b 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_my_location_tracking.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_my_location_tracking.xml
@@ -42,9 +42,9 @@
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:my_location_foreground_tint="@color/primary"
- app:my_location_accuracy_tint="@color/primary"
- app:style_url="@string/style_mapbox_streets"
- app:zoom="15" />
+ app:mapbox_myLocationTintColor="@color/primary"
+ app:mapbox_myLocationAccuracyTintColor="@color/primary"
+ app:mapbox_styleUrl="@string/mapbox_style_mapbox_streets"
+ app:mapbox_cameraZoom="15" />
</LinearLayout>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_polyline.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_polyline.xml
index 9e2f875192..d856676260 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_polyline.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_polyline.xml
@@ -17,11 +17,11 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/toolbar"
- app:attribution_tint="@android:color/holo_green_dark"
- app:center_latitude="47.798202"
- app:center_longitude="7.573781"
- app:style_url="@string/style_mapbox_streets"
- app:zoom="4" />
+ app:mapbox_uiAttributionTintColor="@android:color/holo_green_dark"
+ app:mapbox_cameraTargetLat="47.798202"
+ app:mapbox_cameraTargetLng="7.573781"
+ app:mapbox_styleUrl="@string/mapbox_style_mapbox_streets"
+ app:mapbox_cameraZoom="4" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_press_for_marker.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_press_for_marker.xml
index 9ff79686d2..f5a9a17917 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_press_for_marker.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_press_for_marker.xml
@@ -17,12 +17,12 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/toolbar"
- app:attribution_gravity="top|end"
- app:center_latitude="45.1855569"
- app:center_longitude="5.7215506"
- app:logo_gravity="top|end"
- app:logo_margin_right="10dp"
- app:style_url="@string/style_mapbox_streets"
- app:zoom="11" />
+ app:mapbox_uiAttributionGravity="top|end"
+ app:mapbox_cameraTargetLat="45.1855569"
+ app:mapbox_cameraTargetLng="5.7215506"
+ app:mapbox_uiLogoGravity="top|end"
+ app:mapbox_uiLogoMarginRight="10dp"
+ app:mapbox_styleUrl="@string/mapbox_style_mapbox_streets"
+ app:mapbox_cameraZoom="11" />
</RelativeLayout>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_query_features_box.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_query_features_box.xml
index e1d710880c..dfd067cec7 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_query_features_box.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_query_features_box.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
@@ -14,7 +15,10 @@
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout_below="@id/toolbar" />
+ android:layout_below="@id/toolbar"
+ app:mapbox_cameraTargetLat="52.0907"
+ app:mapbox_cameraTargetLng="5.1214"
+ app:mapbox_cameraZoom="16" />
<FrameLayout
android:id="@+id/selection_box"
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_query_features_point.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_query_features_point.xml
index 4c0d067c14..6889a5fac1 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_query_features_point.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_query_features_point.xml
@@ -1,19 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<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:layout_width="match_parent"
+ android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/primary"
- android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
+ android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
<com.mapbox.mapboxsdk.maps.MapView
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout_below="@id/toolbar"/>
+ android:layout_below="@id/toolbar"
+ app:mapbox_cameraTargetLat="52.0907"
+ app:mapbox_cameraTargetLng="5.1214"
+ app:mapbox_cameraZoom="16" />
</RelativeLayout>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_scroll_by.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_scroll_by.xml
index c5bb8d71b3..5e80a0e1b6 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_scroll_by.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_scroll_by.xml
@@ -80,10 +80,10 @@
android:id="@id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
- app:center_latitude="37.176546"
- app:center_longitude="-3.599007"
- app:style_url="@string/style_emerald"
- app:zoom="15" />
+ app:mapbox_cameraTargetLat="37.176546"
+ app:mapbox_cameraTargetLng="-3.599007"
+ app:mapbox_styleUrl="@string/mapbox_style_emerald"
+ app:mapbox_cameraZoom="15" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_style_file.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_style_file.xml
index 086b18fea1..e0e2cbfdab 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_style_file.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_style_file.xml
@@ -16,10 +16,10 @@
android:id="@id/mapView"
android:layout_below="@id/toolbar"
android:layout_width="match_parent"
- app:center_latitude="52.519003"
- app:center_longitude="13.400972"
- app:style_url="@string/style_mapbox_streets"
- app:zoom="16"
+ app:mapbox_cameraTargetLat="52.519003"
+ app:mapbox_cameraTargetLng="13.400972"
+ app:mapbox_styleUrl="@string/mapbox_style_mapbox_streets"
+ app:mapbox_cameraZoom="16"
android:layout_height="match_parent"/>
<android.support.design.widget.FloatingActionButton
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_surfaceview_mediacontrols.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_surfaceview_mediacontrols.xml
index 8fa94041ff..364e86adda 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_surfaceview_mediacontrols.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_surfaceview_mediacontrols.xml
@@ -17,7 +17,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/toolbar"
- app:style_url="@string/style_light" />
+ app:mapbox_styleUrl="@string/mapbox_style_light" />
<FrameLayout
android:id="@+id/container"
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_symbollayer.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_symbollayer.xml
new file mode 100644
index 0000000000..67892abbd1
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_symbollayer.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <android.support.v7.widget.Toolbar
+ android:id="@+id/toolbar"
+ android:layout_width="match_parent"
+ android:layout_height="?attr/actionBarSize"
+ android:background="@color/primary"
+ android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
+
+ <com.mapbox.mapboxsdk.maps.MapView
+ android:id="@id/mapView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_below="@id/toolbar"
+ app:mapbox_styleUrl="@string/mapbox_style_mapbox_streets"/>
+
+</RelativeLayout>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_video_view.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_video_view.xml
index 979b30d2b4..b640f9f878 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_video_view.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_video_view.xml
@@ -27,11 +27,11 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/toolbar"
- mapbox:attribution_gravity="top"
- mapbox:center_latitude="34.4021"
- mapbox:center_longitude="-119.7081"
- mapbox:logo_gravity="top"
- mapbox:style_url="mapbox://styles/mapbox/streets-v9"
- mapbox:zoom="13" />
+ mapbox:mapbox_uiAttributionGravity="top"
+ mapbox:mapbox_cameraTargetLat="34.4021"
+ mapbox:mapbox_cameraTargetLng="-119.7081"
+ mapbox:mapbox_uiLogoGravity="top"
+ mapbox:mapbox_styleUrl="mapbox://styles/mapbox/streets-v9"
+ mapbox:mapbox_cameraZoom="13" />
</RelativeLayout> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/fragment_dialog_map.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/fragment_dialog_map.xml
index 51ec3c4677..b40ad1273d 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/fragment_dialog_map.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/fragment_dialog_map.xml
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:mapbox="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -10,9 +9,10 @@
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
- mapbox:center_latitude="47.6077"
- mapbox:center_longitude="-122.3421"
- mapbox:style_url="mapbox://styles/mapbox/streets-v9"
- mapbox:zoom="11"/>
+ mapbox:mapbox_cameraTargetLat="47.6077"
+ mapbox:mapbox_cameraTargetLng="-122.3421"
+ mapbox:mapbox_cameraZoom="11"
+ mapbox:mapbox_renderTextureMode="true"
+ mapbox:mapbox_styleUrl="mapbox://styles/mapbox/streets-v9" />
</LinearLayout> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_custom_layer.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_custom_layer.xml
index 43465cce62..ec1f756333 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_custom_layer.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_custom_layer.xml
@@ -5,4 +5,13 @@
<item
android:id="@+id/action_update_layer"
android:title="Update layer (invalidate)" />
+ <item
+ android:id="@+id/action_set_color_red"
+ android:title="Red" />
+ <item
+ android:id="@+id/action_set_color_green"
+ android:title="Green" />
+ <item
+ android:id="@+id/action_set_color_blue"
+ android:title="Blue" />
</menu> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_symbol_layer.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_symbol_layer.xml
new file mode 100644
index 0000000000..e6fd1fce45
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/menu/menu_symbol_layer.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item
+ android:id="@+id/action_toggle_text_size"
+ android:title="Toggle text size"/>
+
+ <item
+ android:id="@+id/action_toggle_text_field"
+ android:title="Toggle text field contents"/>
+
+ <item
+ android:id="@+id/action_toggle_text_font"
+ android:title="Toggle text font"/>
+
+</menu> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/raw/test_points_utrecht.geojson b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/raw/test_points_utrecht.geojson
new file mode 100644
index 0000000000..d7b8ede72f
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/raw/test_points_utrecht.geojson
@@ -0,0 +1,49 @@
+{
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 5.12100,
+ 52.09082
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 5.12160,
+ 52.09082
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 5.12160,
+ 52.09056
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 5.12100,
+ 52.09056
+ ]
+ }
+ }
+ ]
+} \ 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 a4f19f1e01..72b0ecb69c 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
@@ -62,15 +62,17 @@
<string name="activity_geojson_clustering">GeoJson Clustering</string>
<string name="activity_geojson_realtime">Add live realtime data</string>
<string name="activity_print">Print a map</string>
- <string name="activity_surfaceview_overlay">SurfaceView MediaOverlay</string>
<string name="activity_query_rendered_feature_properties">Query feature properties</string>
<string name="activity_query_rendered_features_box_count">Count features in box</string>
+ <string name="activity_query_rendered_features_box_symbol_count">Count symbols in box</string>
<string name="activity_query_rendered_features_box_highlight">Highlight features in box</string>
<string name="activity_circle">Add Circle</string>
+ <string name="activity_symbol_layer">Symbols</string>
<string name="activity_add_sprite">Add Custom Sprite</string>
<string name="activity_navigation_drawer">Android SDK View integration</string>
- <string name="activity_video_view">Video View</string>
+ <string name="activity_simple_map">Simple Map</string>
<string name="activity_map_in_dialog">Dialog with map</string>
+ <string name="activity_marker_view_rectangle">Marker views in rectangle</string>
<!-- Description -->
<string name="description_user_location_tracking">Tracks the location of the user</string>
@@ -112,20 +114,22 @@
<string name="description_viewpager">Use SupportMapFragments in a ViewPager</string>
<string name="description_runtime_style">Adopt the map style on the fly</string>
<string name="description_circle">Use GeoJson source to show a circle</string>
+ <string name="description_symbol_layer">Manipulate symbols at runtime</string>
<string name="description_custom_sprite">Use a custom sprite in a Symbol Layer</string>
<string name="description_geojson_clustering">Use GeoJson sources and dynamic layers to cluster information</string>
<string name="description_geojson_realtime">Use realtime GeoJSON data streams to move a symbol on your map</string>
<string name="description_print">Shows how to print a map</string>
<string name="description_navigation_drawer">Test animation of Android SDK View components</string>
- <string name="description_surfaceview_mediacontrols">Test overlaying SurfaceView</string>
<string name="description_query_rendered_feature_properties_point">Query rendered feature properties on click</string>
<string name="description_query_rendered_features_box_count">Count all rendered features in box</string>
+ <string name="description_query_rendered_features_box_symbol_count">Count all rendered symbols in box</string>
<string name="description_query_rendered_features_box_highlight">Hightligh buildings in box</string>
<string name="description_car_driving">MyLocationView follow map update example</string>
- <string name="description_video_view">Android video view on top of the map view</string>
+ <string name="description_simple_map">Shows a simple map</string>
<string name="description_add_remove_markers">Based on zoom level</string>
<string name="description_style_file">Use a local file as the style</string>
<string name="description_map_in_dialog">Display a map inside a dialog fragment</string>
+ <string name="description_marker_view_rectangle">Marker Views within a rectangle</string>
<string name="menuitem_title_concurrent_infowindow">Concurrent Open InfoWindows</string>
<string name="menuitem_title_deselect_markers_on_tap">Deselect Markers On Tap</string>
@@ -165,6 +169,7 @@
<string name="button_user_dot_default">Default</string>
<string name="button_user_dot_tint">Tint dot</string>
<string name="button_user_accuracy_ring_tint">Tint ring</string>
+ <string name="button_user_transparent_tint">tran</string>
<string name="button_open_dialog">Open dialog</string>
<string name="label_fps">FPS:</string>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/AnnotationTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/AnnotationTest.java
index 76658c242f..611e4f978c 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/AnnotationTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/AnnotationTest.java
@@ -17,75 +17,75 @@ import static org.mockito.Mockito.verify;
public class AnnotationTest {
- @InjectMocks
- private MapboxMap mapboxMap = mock(MapboxMap.class);
- private Annotation annotation;
- private Annotation compare = new Annotation() {
- @Override
- public long getId() {
- return 1;
- }
- };
-
- @Before
- public void beforeTest() {
- annotation = new Annotation() {
- // empty child
- };
+ @InjectMocks
+ private MapboxMap mapboxMap = mock(MapboxMap.class);
+ private Annotation annotation;
+ private Annotation compare = new Annotation() {
+ @Override
+ public long getId() {
+ return 1;
}
+ };
- @Test
- public void testSanity() {
- assertNotNull("markerOptions should not be null", annotation);
- }
+ @Before
+ public void beforeTest() {
+ annotation = new Annotation() {
+ // empty child
+ };
+ }
- @Test
- public void testRemove() {
- annotation.setId(1);
- annotation.setMapboxMap(mapboxMap);
- annotation.remove();
- verify(mapboxMap, times(1)).removeAnnotation(annotation);
- }
+ @Test
+ public void testSanity() {
+ assertNotNull("markerOptions should not be null", annotation);
+ }
- @Test
- public void testRemoveUnboundMapboxMap() {
- annotation.setId(1);
- annotation.remove();
- verify(mapboxMap, times(0)).removeAnnotation(annotation);
- }
+ @Test
+ public void testRemove() {
+ annotation.setId(1);
+ annotation.setMapboxMap(mapboxMap);
+ annotation.remove();
+ verify(mapboxMap, times(1)).removeAnnotation(annotation);
+ }
- @Test
- public void testCompareToEqual() {
- annotation.setId(1);
- assertEquals("conparable equal", 0, annotation.compareTo(compare));
- }
+ @Test
+ public void testRemoveUnboundMapboxMap() {
+ annotation.setId(1);
+ annotation.remove();
+ verify(mapboxMap, times(0)).removeAnnotation(annotation);
+ }
- @Test
- public void testCompareToHigher() {
- annotation.setId(3);
- assertEquals("conparable higher", -1, annotation.compareTo(compare));
- }
+ @Test
+ public void testCompareToEqual() {
+ annotation.setId(1);
+ assertEquals("conparable equal", 0, annotation.compareTo(compare));
+ }
- @Test
- public void testCompareTolower() {
- annotation.setId(0);
- assertEquals("conparable lower", 1, annotation.compareTo(compare));
- }
+ @Test
+ public void testCompareToHigher() {
+ annotation.setId(3);
+ assertEquals("conparable higher", -1, annotation.compareTo(compare));
+ }
- @Test
- public void testEquals() {
- Annotation holder = null;
- assertFalse(annotation.equals(holder));
- holder = annotation;
- assertTrue(annotation.equals(holder));
- assertFalse(annotation.equals(new Object()));
- }
+ @Test
+ public void testCompareTolower() {
+ annotation.setId(0);
+ assertEquals("conparable lower", 1, annotation.compareTo(compare));
+ }
- @Test
- public void testHashcode() {
- int id = 1;
- annotation.setId(id);
- assertSame("hashcode should match", annotation.hashCode(), id);
- }
+ @Test
+ public void testEquals() {
+ Annotation holder = null;
+ assertFalse(annotation.equals(holder));
+ holder = annotation;
+ assertTrue(annotation.equals(holder));
+ assertFalse(annotation.equals(new Object()));
+ }
+
+ @Test
+ public void testHashcode() {
+ int id = 1;
+ annotation.setId(id);
+ assertSame("hashcode should match", annotation.hashCode(), id);
+ }
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/IconTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/IconTest.java
index 9e95451cb1..5f6f6b6c6d 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/IconTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/IconTest.java
@@ -12,44 +12,44 @@ import static junit.framework.Assert.assertNotSame;
public class IconTest {
- @Mock
- Bitmap mBitmap;
-
- @Before
- public void beforeTest() {
- MockitoAnnotations.initMocks(this);
- }
-
- @Test
- public void testId() {
- String id = "test";
- Icon icon = IconFactory.recreate(id, Bitmap.createBitmap(0, 0, Bitmap.Config.ALPHA_8));
- assertEquals("id should match", id, icon.getId());
- }
-
- @Test
- public void testBitmap() {
- Icon icon = IconFactory.recreate("test", mBitmap);
- assertEquals("bitmap should match", mBitmap, icon.getBitmap());
- }
-
- @Test
- public void testEquals() {
- Icon icon1 = IconFactory.recreate("test", mBitmap);
- Icon icon2 = IconFactory.recreate("test", mBitmap);
- assertEquals("icons should not match", icon1, icon2);
- }
-
- @Test
- public void testEqualsObject() {
- Icon icon = IconFactory.recreate("test", Bitmap.createBitmap(0, 0, Bitmap.Config.ALPHA_8));
- assertNotSame("icon should not match", new Object(), icon);
- }
-
- @Test
- public void testHashcode() {
- Icon icon = IconFactory.recreate("test", mBitmap);
- long expectedHashcode = 31 * mBitmap.hashCode() + "test".hashCode();
- assertEquals("hashcode should match", expectedHashcode, icon.hashCode());
- }
+ @Mock
+ Bitmap bitmap;
+
+ @Before
+ public void beforeTest() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test
+ public void testId() {
+ String id = "test";
+ Icon icon = IconFactory.recreate(id, Bitmap.createBitmap(0, 0, Bitmap.Config.ALPHA_8));
+ assertEquals("id should match", id, icon.getId());
+ }
+
+ @Test
+ public void testBitmap() {
+ Icon icon = IconFactory.recreate("test", bitmap);
+ assertEquals("bitmap should match", bitmap, icon.getBitmap());
+ }
+
+ @Test
+ public void testEquals() {
+ Icon icon1 = IconFactory.recreate("test", bitmap);
+ Icon icon2 = IconFactory.recreate("test", bitmap);
+ assertEquals("icons should not match", icon1, icon2);
+ }
+
+ @Test
+ public void testEqualsObject() {
+ Icon icon = IconFactory.recreate("test", Bitmap.createBitmap(0, 0, Bitmap.Config.ALPHA_8));
+ assertNotSame("icon should not match", new Object(), icon);
+ }
+
+ @Test
+ public void testHashcode() {
+ Icon icon = IconFactory.recreate("test", bitmap);
+ long expectedHashcode = 31 * bitmap.hashCode() + "test".hashCode();
+ assertEquals("hashcode should match", expectedHashcode, icon.hashCode());
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/InfoWindowTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/InfoWindowTest.java
index 1398f40009..94b629860e 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/InfoWindowTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/InfoWindowTest.java
@@ -17,70 +17,70 @@ import static org.mockito.Mockito.when;
public class InfoWindowTest {
- @InjectMocks
- MapView mMapView = mock(MapView.class);
-
- @InjectMocks
- MapboxMap mMapboxMap = mock(MapboxMap.class);
-
- @Test
- public void testSanity() {
- InfoWindow infoWindow = new InfoWindow(mMapView, mMapboxMap);
- assertNotNull("infoWindow should exist", infoWindow);
- }
-
- @Test
- public void testBoundMarker() {
- MarkerOptions markerOptions = new MarkerOptions();
- Marker marker = markerOptions.position(new LatLng()).getMarker();
- InfoWindow infoWindow = new InfoWindow(mMapView, mMapboxMap).setBoundMarker(marker);
- assertEquals("marker should match", marker, infoWindow.getBoundMarker());
- }
-
- @Test
- public void testClose() {
- InfoWindow infoWindow = new InfoWindow(mMapView, mMapboxMap);
- infoWindow.close();
- assertEquals("infowindow should not be visible", false, infoWindow.isVisible());
- }
-
-
- @Test
- public void testOpen() {
- LatLng latLng = new LatLng(0, 0);
- Projection projection = mock(Projection.class);
- when(mMapboxMap.getProjection()).thenReturn(projection);
- when(projection.toScreenLocation(latLng)).thenReturn(new PointF(0, 0));
-
- InfoWindow infoWindow = new InfoWindow(mMapView, mMapboxMap);
- infoWindow.open(mMapView, new MarkerOptions().position(new LatLng()).getMarker(), latLng, 0, 0);
- assertEquals("infowindow should not be visible", true, infoWindow.isVisible());
- }
-
- @Test
- public void testOpenClose() {
- LatLng latLng = new LatLng(0, 0);
- Projection projection = mock(Projection.class);
- when(mMapboxMap.getProjection()).thenReturn(projection);
- when(projection.toScreenLocation(latLng)).thenReturn(new PointF(0, 0));
-
- InfoWindow infoWindow = new InfoWindow(mMapView, mMapboxMap);
- infoWindow.open(mMapView, new MarkerOptions().position(new LatLng()).getMarker(), latLng, 0, 0);
- infoWindow.close();
- assertEquals("infowindow should not be visible", false, infoWindow.isVisible());
- }
-
-
- @Test
- public void testUpdate() {
- LatLng latLng = new LatLng(0, 0);
- Projection projection = mock(Projection.class);
- when(mMapboxMap.getProjection()).thenReturn(projection);
- when(projection.toScreenLocation(latLng)).thenReturn(new PointF(0, 0));
-
- InfoWindow infoWindow = new InfoWindow(mMapView, mMapboxMap);
- infoWindow.open(mMapView, new MarkerOptions().position(latLng).getMarker(), latLng, 0, 0);
- infoWindow.update();
- }
+ @InjectMocks
+ MapView mMapView = mock(MapView.class);
+
+ @InjectMocks
+ MapboxMap mMapboxMap = mock(MapboxMap.class);
+
+ @Test
+ public void testSanity() {
+ InfoWindow infoWindow = new InfoWindow(mMapView, mMapboxMap);
+ assertNotNull("infoWindow should exist", infoWindow);
+ }
+
+ @Test
+ public void testBoundMarker() {
+ MarkerOptions markerOptions = new MarkerOptions();
+ Marker marker = markerOptions.position(new LatLng()).getMarker();
+ InfoWindow infoWindow = new InfoWindow(mMapView, mMapboxMap).setBoundMarker(marker);
+ assertEquals("marker should match", marker, infoWindow.getBoundMarker());
+ }
+
+ @Test
+ public void testClose() {
+ InfoWindow infoWindow = new InfoWindow(mMapView, mMapboxMap);
+ infoWindow.close();
+ assertEquals("infowindow should not be visible", false, infoWindow.isVisible());
+ }
+
+
+ @Test
+ public void testOpen() {
+ LatLng latLng = new LatLng(0, 0);
+ Projection projection = mock(Projection.class);
+ when(mMapboxMap.getProjection()).thenReturn(projection);
+ when(projection.toScreenLocation(latLng)).thenReturn(new PointF(0, 0));
+
+ InfoWindow infoWindow = new InfoWindow(mMapView, mMapboxMap);
+ infoWindow.open(mMapView, new MarkerOptions().position(new LatLng()).getMarker(), latLng, 0, 0);
+ assertEquals("infowindow should not be visible", true, infoWindow.isVisible());
+ }
+
+ @Test
+ public void testOpenClose() {
+ LatLng latLng = new LatLng(0, 0);
+ Projection projection = mock(Projection.class);
+ when(mMapboxMap.getProjection()).thenReturn(projection);
+ when(projection.toScreenLocation(latLng)).thenReturn(new PointF(0, 0));
+
+ InfoWindow infoWindow = new InfoWindow(mMapView, mMapboxMap);
+ infoWindow.open(mMapView, new MarkerOptions().position(new LatLng()).getMarker(), latLng, 0, 0);
+ infoWindow.close();
+ assertEquals("infowindow should not be visible", false, infoWindow.isVisible());
+ }
+
+
+ @Test
+ public void testUpdate() {
+ LatLng latLng = new LatLng(0, 0);
+ Projection projection = mock(Projection.class);
+ when(mMapboxMap.getProjection()).thenReturn(projection);
+ when(projection.toScreenLocation(latLng)).thenReturn(new PointF(0, 0));
+
+ InfoWindow infoWindow = new InfoWindow(mMapView, mMapboxMap);
+ infoWindow.open(mMapView, new MarkerOptions().position(latLng).getMarker(), latLng, 0, 0);
+ infoWindow.update();
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/MarkerTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/MarkerTest.java
index c4c294fb98..fa571e06b1 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/MarkerTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/MarkerTest.java
@@ -16,145 +16,145 @@ import static org.mockito.Mockito.mock;
public class MarkerTest {
- @Test
- public void testSanity() {
- MarkerOptions markerOptions = new MarkerOptions();
- assertNotNull("markerOptions should not be null", markerOptions);
- }
-
- @Test
- public void testMarker() {
- MarkerOptions markerOptions = new MarkerOptions().position(new LatLng());
- assertNotNull("marker should not be null", markerOptions.getMarker());
- }
-
- @Test(expected = InvalidMarkerPositionException.class)
- public void testInvalidMarker(){
- new MarkerOptions().getMarker();
- }
-
- @Test
- public void testPosition() {
- MarkerOptions markerOptions = new MarkerOptions().position(new LatLng(10, 12));
- Marker marker = markerOptions.getMarker();
- assertEquals(marker.getPosition(), new LatLng(10, 12));
- assertEquals(markerOptions.getPosition(), new LatLng(10, 12));
- }
-
- @Test
- public void testTitle() {
- MarkerOptions markerOptions = new MarkerOptions().title("Mapbox").position(new LatLng());
- Marker marker = markerOptions.getMarker();
- assertEquals(marker.getTitle(), "Mapbox");
- assertEquals(markerOptions.getTitle(), "Mapbox");
- }
-
- @Test
- public void testSnippet() {
- MarkerOptions markerOptions = new MarkerOptions().snippet("Mapbox").position(new LatLng());
- Marker marker = markerOptions.getMarker();
- assertEquals(marker.getSnippet(), "Mapbox");
- }
-
- @Test
- public void testBuilder() {
- Marker marker = new MarkerOptions().title("title").snippet("snippet").position(new LatLng(10, 12)).getMarker();
- assertEquals(marker.getSnippet(), "snippet");
-
- assertEquals(marker.getPosition(), new LatLng(10, 12));
- }
-
- @Test
- public void testIcon() {
- Bitmap bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_4444);
- Icon icon = IconFactory.recreate("test", bitmap);
- MarkerOptions markerOptions = new MarkerOptions().position(new LatLng()).icon(icon);
- Marker marker = markerOptions.getMarker();
- assertEquals("Icon should match", icon, marker.getIcon());
- assertEquals("Icon should match", icon, markerOptions.getIcon());
- }
-
- @Test
- public void testHashCode() {
- Marker marker = new MarkerOptions().position(new LatLng()).getMarker();
- assertEquals("hash code should match", marker.hashCode(), 0);
- }
-
- @Test
- public void testHashCodeBuilder() {
- MarkerOptions markerOptions = new MarkerOptions().position(new LatLng(10, 12));
- assertEquals("hash code should match", markerOptions.hashCode(), 579999617);
- }
-
- @Test
- public void testEquals() {
- Marker markerOne = new MarkerOptions().position(new LatLng(0, 0)).getMarker();
- Marker markerTwo = new MarkerOptions().position(new LatLng(0, 0)).getMarker();
- assertEquals(markerOne, markerTwo);
- }
-
- @Test
- public void testEqualityDifferentLocation() {
- MarkerOptions marker = new MarkerOptions().position(new LatLng(0, 0));
- MarkerOptions other = new MarkerOptions().position(new LatLng(1, 0));
- assertNotEquals("Should not match", other, marker);
- }
-
-
- @Test
- public void testEqualityDifferentSnippet() {
- MarkerOptions marker = new MarkerOptions().snippet("s");
- MarkerOptions other = new MarkerOptions();
- assertNotEquals("Should not match", other, marker);
- }
-
- @Test
- public void testEqualityDifferentIcon() {
- MarkerOptions marker = new MarkerOptions().icon(mock(Icon.class));
- MarkerOptions other = new MarkerOptions();
- assertNotEquals("Should not match", other, marker);
- }
-
- @Test
- public void testEqualityDifferentTitle() {
- MarkerOptions marker = new MarkerOptions().title("t");
- MarkerOptions other = new MarkerOptions();
- assertNotEquals("Should not match", other, marker);
- }
-
- @Test
- public void testEqualsItself() {
- MarkerOptions markerOptions = new MarkerOptions().position(new LatLng(0, 0));
- Marker marker = markerOptions.getMarker();
- assertEquals("Marker should match", marker, marker);
- assertEquals("MarkerOptions should match", markerOptions, markerOptions);
- }
-
- @Test
- public void testNotEquals() {
- MarkerOptions markerOptions = new MarkerOptions().position(new LatLng(0, 0));
- Marker marker = markerOptions.getMarker();
- assertNotEquals("MarkerOptions should match", markerOptions, new Object());
- assertNotEquals("Marker should match", marker, new Object());
- }
-
- @Test
- public void testEqualityBuilder() {
- MarkerOptions markerOne = new MarkerOptions().position(new LatLng(0, 0));
- MarkerOptions markerTwo = new MarkerOptions().position(new LatLng(0, 0));
- assertEquals(markerOne, markerTwo);
- }
-
- @Test
- public void testToString() {
- Marker marker = new MarkerOptions().position(new LatLng(0, 0)).getMarker();
- assertEquals(marker.toString(), "Marker [position[" + "LatLng [latitude=0.0, longitude=0.0, altitude=0.0]" + "]]");
- }
-
- @Test
- public void testParcelable() {
- MarkerOptions markerOptions = new MarkerOptions().position(new LatLng()).title("t").snippet("s");
- Parcelable parcelable = MockParcel.obtain(markerOptions);
- assertEquals("Parcel should match original object", parcelable, markerOptions);
- }
+ @Test
+ public void testSanity() {
+ MarkerOptions markerOptions = new MarkerOptions();
+ assertNotNull("markerOptions should not be null", markerOptions);
+ }
+
+ @Test
+ public void testMarker() {
+ MarkerOptions markerOptions = new MarkerOptions().position(new LatLng());
+ assertNotNull("marker should not be null", markerOptions.getMarker());
+ }
+
+ @Test(expected = InvalidMarkerPositionException.class)
+ public void testInvalidMarker() {
+ new MarkerOptions().getMarker();
+ }
+
+ @Test
+ public void testPosition() {
+ MarkerOptions markerOptions = new MarkerOptions().position(new LatLng(10, 12));
+ Marker marker = markerOptions.getMarker();
+ assertEquals(marker.getPosition(), new LatLng(10, 12));
+ assertEquals(markerOptions.getPosition(), new LatLng(10, 12));
+ }
+
+ @Test
+ public void testTitle() {
+ MarkerOptions markerOptions = new MarkerOptions().title("Mapbox").position(new LatLng());
+ Marker marker = markerOptions.getMarker();
+ assertEquals(marker.getTitle(), "Mapbox");
+ assertEquals(markerOptions.getTitle(), "Mapbox");
+ }
+
+ @Test
+ public void testSnippet() {
+ MarkerOptions markerOptions = new MarkerOptions().snippet("Mapbox").position(new LatLng());
+ Marker marker = markerOptions.getMarker();
+ assertEquals(marker.getSnippet(), "Mapbox");
+ }
+
+ @Test
+ public void testBuilder() {
+ Marker marker = new MarkerOptions().title("title").snippet("snippet").position(new LatLng(10, 12)).getMarker();
+ assertEquals(marker.getSnippet(), "snippet");
+
+ assertEquals(marker.getPosition(), new LatLng(10, 12));
+ }
+
+ @Test
+ public void testIcon() {
+ Bitmap bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_4444);
+ Icon icon = IconFactory.recreate("test", bitmap);
+ MarkerOptions markerOptions = new MarkerOptions().position(new LatLng()).icon(icon);
+ Marker marker = markerOptions.getMarker();
+ assertEquals("Icon should match", icon, marker.getIcon());
+ assertEquals("Icon should match", icon, markerOptions.getIcon());
+ }
+
+ @Test
+ public void testHashCode() {
+ Marker marker = new MarkerOptions().position(new LatLng()).getMarker();
+ assertEquals("hash code should match", marker.hashCode(), 0);
+ }
+
+ @Test
+ public void testHashCodeBuilder() {
+ MarkerOptions markerOptions = new MarkerOptions().position(new LatLng(10, 12));
+ assertEquals("hash code should match", markerOptions.hashCode(), 579999617);
+ }
+
+ @Test
+ public void testEquals() {
+ Marker markerOne = new MarkerOptions().position(new LatLng(0, 0)).getMarker();
+ Marker markerTwo = new MarkerOptions().position(new LatLng(0, 0)).getMarker();
+ assertEquals(markerOne, markerTwo);
+ }
+
+ @Test
+ public void testEqualityDifferentLocation() {
+ MarkerOptions marker = new MarkerOptions().position(new LatLng(0, 0));
+ MarkerOptions other = new MarkerOptions().position(new LatLng(1, 0));
+ assertNotEquals("Should not match", other, marker);
+ }
+
+
+ @Test
+ public void testEqualityDifferentSnippet() {
+ MarkerOptions marker = new MarkerOptions().snippet("s");
+ MarkerOptions other = new MarkerOptions();
+ assertNotEquals("Should not match", other, marker);
+ }
+
+ @Test
+ public void testEqualityDifferentIcon() {
+ MarkerOptions marker = new MarkerOptions().icon(mock(Icon.class));
+ MarkerOptions other = new MarkerOptions();
+ assertNotEquals("Should not match", other, marker);
+ }
+
+ @Test
+ public void testEqualityDifferentTitle() {
+ MarkerOptions marker = new MarkerOptions().title("t");
+ MarkerOptions other = new MarkerOptions();
+ assertNotEquals("Should not match", other, marker);
+ }
+
+ @Test
+ public void testEqualsItself() {
+ MarkerOptions markerOptions = new MarkerOptions().position(new LatLng(0, 0));
+ Marker marker = markerOptions.getMarker();
+ assertEquals("Marker should match", marker, marker);
+ assertEquals("MarkerOptions should match", markerOptions, markerOptions);
+ }
+
+ @Test
+ public void testNotEquals() {
+ MarkerOptions markerOptions = new MarkerOptions().position(new LatLng(0, 0));
+ Marker marker = markerOptions.getMarker();
+ assertNotEquals("MarkerOptions should match", markerOptions, new Object());
+ assertNotEquals("Marker should match", marker, new Object());
+ }
+
+ @Test
+ public void testEqualityBuilder() {
+ MarkerOptions markerOne = new MarkerOptions().position(new LatLng(0, 0));
+ MarkerOptions markerTwo = new MarkerOptions().position(new LatLng(0, 0));
+ assertEquals(markerOne, markerTwo);
+ }
+
+ @Test
+ public void testToString() {
+ Marker marker = new MarkerOptions().position(new LatLng(0, 0)).getMarker();
+ assertEquals(marker.toString(), "Marker [position[" + "LatLng [latitude=0.0, longitude=0.0, altitude=0.0]" + "]]");
+ }
+
+ @Test
+ public void testParcelable() {
+ MarkerOptions markerOptions = new MarkerOptions().position(new LatLng()).title("t").snippet("s");
+ Parcelable parcelable = MockParcel.obtain(markerOptions);
+ assertEquals("Parcel should match original object", parcelable, markerOptions);
+ }
}
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 6cef1898bd..3c52c16422 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
@@ -23,265 +23,264 @@ 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();
- assertNotNull("markerOptions should not be null", markerOptions);
- }
-
- @Test
- public void testMarker() {
- MarkerViewOptions markerOptions = new MarkerViewOptions().position(new LatLng());
- assertNotNull("marker should not be null", markerOptions.getMarker());
- }
-
- @Test(expected = InvalidMarkerPositionException.class)
- public void testInvalidMarker() {
- new MarkerViewOptions().getMarker();
- }
-
- @Test
- public void testPosition() {
- MarkerViewOptions markerOptions = new MarkerViewOptions().position(new LatLng(10, 12));
- MarkerView marker = markerOptions.getMarker();
- assertEquals(marker.getPosition(), new LatLng(10, 12));
- assertEquals(markerOptions.getPosition(), new LatLng(10, 12));
- }
-
- @Test
- public void testSnippet() {
- MarkerViewOptions markerOptions = new MarkerViewOptions().snippet("Mapbox").position(new LatLng());
- MarkerView marker = markerOptions.getMarker();
- assertEquals(marker.getSnippet(), "Mapbox");
- }
-
- @Test
- public void testTitle() {
- MarkerViewOptions markerOptions = new MarkerViewOptions().title("Mapbox").position(new LatLng());
- MarkerView marker = markerOptions.getMarker();
- assertEquals(marker.getTitle(), "Mapbox");
- assertEquals(markerOptions.getTitle(), "Mapbox");
- }
-
- @Test
- public void testFlat() {
- MarkerViewOptions markerOptions = new MarkerViewOptions().flat(true).position(new LatLng());
- MarkerView marker = markerOptions.getMarker();
- assertTrue("flat should be true", marker.isFlat());
- }
-
- @Test
- public void testFlatDefault() {
- assertFalse("default value of flat should be false", new MarkerViewOptions().position(new LatLng()).getMarker().isFlat());
- }
-
- @Test
- public void testAnchor() {
- float anchorU = 1;
- float anchorV = 1;
- MarkerViewOptions markerOptions = new MarkerViewOptions().anchor(anchorU, anchorV).position(new LatLng());
- MarkerView marker = markerOptions.getMarker();
- assertEquals("anchorU should match ", anchorU, marker.getAnchorU(), 0);
- assertEquals("anchorU should match ", anchorV, marker.getAnchorV(), 0);
- }
-
- @Test
- public void testAnchorDefault() {
- MarkerView marker = new MarkerViewOptions().position(new LatLng()).getMarker();
- assertEquals("anchorU should match ", 0.5, marker.getAnchorU(), 0);
- assertEquals("anchorU should match ", 1, marker.getAnchorV(), 0);
- }
-
- @Test
- public void testInfoWindowAnchor() {
- float anchorU = 1;
- float anchorV = 1;
- MarkerViewOptions markerOptions = new MarkerViewOptions().position(new LatLng()).infoWindowAnchor(anchorU, anchorV);
- MarkerView marker = markerOptions.getMarker();
- assertEquals("anchorU should match ", 1, marker.getInfoWindowAnchorU(), 0);
- assertEquals("anchorU should match ", 1, marker.getInfoWindowAnchorV(), 0);
- }
-
- @Test
- public void testInfoWindowAnchorDefault() {
- MarkerView marker = new MarkerViewOptions().position(new LatLng()).getMarker();
- assertEquals("anchorU should match ", 0.5, marker.getInfoWindowAnchorU(), 0);
- assertEquals("anchorU should match ", 0, marker.getInfoWindowAnchorV(), 0);
- }
-
- @Test
- public void testRotation() {
- int rotation = 90;
- MarkerViewOptions markerOptions = new MarkerViewOptions().position(new LatLng()).rotation(rotation);
- MarkerView marker = markerOptions.getMarker();
- assertEquals("rotation should match ", rotation, marker.getRotation(), 0);
- }
-
- @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());
- MarkerView marker = markerOptions.getMarker();
- assertEquals("visible should match ", visible, marker.isVisible());
- }
-
- @Test
- public void testVisibleDefault() {
- assertTrue(new MarkerViewOptions().position(new LatLng()).getMarker().isVisible());
- }
-
- @Test
- public void testBuilder() {
- MarkerView marker = new MarkerViewOptions().title("title").snippet("snippet").position(new LatLng(10, 12)).getMarker();
- assertEquals(marker.getSnippet(), "snippet");
- assertEquals(marker.getPosition(), new LatLng(10, 12));
- }
-
- @Test
- public void testHashCode() {
- MarkerView marker = new MarkerViewOptions().position(new LatLng()).getMarker();
- assertEquals("hash code should match", marker.hashCode(), 0);
- }
-
- @Test
- public void testHashCodeBuilder() {
- MarkerViewOptions markerOptions = new MarkerViewOptions().position(new LatLng(10, 12));
- assertEquals("hash code should match", markerOptions.hashCode(), 0);
- }
-
- @Test
- public void testEquals() {
- MarkerView markerOne = new MarkerViewOptions().position(new LatLng(0, 0)).getMarker();
- MarkerView markerTwo = new MarkerViewOptions().position(new LatLng(0, 0)).getMarker();
- assertEquals(markerOne, markerTwo);
- }
-
- @Test
- public void testEqualsItself() {
- MarkerViewOptions markerOptions = new MarkerViewOptions().position(new LatLng(0, 0));
- MarkerView marker = markerOptions.getMarker();
- assertEquals("MarkerView should match", marker, marker);
- assertEquals("MarkerViewOptions should match", markerOptions, markerOptions);
- }
-
- @Test
- public void testNotEquals() {
- MarkerViewOptions markerOptions = new MarkerViewOptions().position(new LatLng(0, 0));
- MarkerView marker = markerOptions.getMarker();
- assertNotEquals("MarkerViewOptions should match", markerOptions, new Object());
- assertNotEquals("MarkerView should match", marker, new Object());
- }
-
- @Test
- public void testEqualityBuilder() {
- MarkerViewOptions markerOne = new MarkerViewOptions().position(new LatLng(0, 0));
- MarkerViewOptions markerTwo = new MarkerViewOptions().position(new LatLng(0, 0));
- assertEquals(markerOne, markerTwo);
- }
-
- @Test
- public void testToString() {
- MarkerView marker = new MarkerViewOptions().position(new LatLng(0, 0)).getMarker();
- assertEquals(marker.toString(), "MarkerView [position[" + "LatLng [latitude=0.0, longitude=0.0, altitude=0.0]" + "]]");
- }
-
- @Test
- public void testParcelable() {
- MarkerViewOptions markerOptions = new MarkerViewOptions().position(new LatLng()).title("t").snippet("s");
- Parcelable parcelable = MockParcel.obtain(markerOptions);
- assertEquals("Parcel should match original object", parcelable, markerOptions);
- }
+ @Mock
+ MapboxMap mapboxMap;
+
+ @Mock
+ MarkerViewManager markerViewManager;
+
+ @Before
+ public void beforeTest() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test
+ public void testSanity() {
+ MarkerViewOptions markerOptions = new MarkerViewOptions();
+ assertNotNull("markerOptions should not be null", markerOptions);
+ }
+
+ @Test
+ public void testMarker() {
+ MarkerViewOptions markerOptions = new MarkerViewOptions().position(new LatLng());
+ assertNotNull("marker should not be null", markerOptions.getMarker());
+ }
+
+ @Test(expected = InvalidMarkerPositionException.class)
+ public void testInvalidMarker() {
+ new MarkerViewOptions().getMarker();
+ }
+
+ @Test
+ public void testPosition() {
+ MarkerViewOptions markerOptions = new MarkerViewOptions().position(new LatLng(10, 12));
+ MarkerView marker = markerOptions.getMarker();
+ assertEquals(marker.getPosition(), new LatLng(10, 12));
+ assertEquals(markerOptions.getPosition(), new LatLng(10, 12));
+ }
+
+ @Test
+ public void testSnippet() {
+ MarkerViewOptions markerOptions = new MarkerViewOptions().snippet("Mapbox").position(new LatLng());
+ MarkerView marker = markerOptions.getMarker();
+ assertEquals(marker.getSnippet(), "Mapbox");
+ }
+
+ @Test
+ public void testTitle() {
+ MarkerViewOptions markerOptions = new MarkerViewOptions().title("Mapbox").position(new LatLng());
+ MarkerView marker = markerOptions.getMarker();
+ assertEquals(marker.getTitle(), "Mapbox");
+ assertEquals(markerOptions.getTitle(), "Mapbox");
+ }
+
+ @Test
+ public void testFlat() {
+ MarkerViewOptions markerOptions = new MarkerViewOptions().flat(true).position(new LatLng());
+ MarkerView marker = markerOptions.getMarker();
+ assertTrue("flat should be true", marker.isFlat());
+ }
+
+ @Test
+ public void testFlatDefault() {
+ assertFalse("default value of flat should be false", new MarkerViewOptions().position(
+ new LatLng()).getMarker().isFlat());
+ }
+
+ @Test
+ public void testAnchor() {
+ float anchorU = 1;
+ float anchorV = 1;
+ MarkerViewOptions markerOptions = new MarkerViewOptions().anchor(anchorU, anchorV).position(new LatLng());
+ MarkerView marker = markerOptions.getMarker();
+ assertEquals("anchorU should match ", anchorU, marker.getAnchorU(), 0);
+ assertEquals("anchorU should match ", anchorV, marker.getAnchorV(), 0);
+ }
+
+ @Test
+ public void testAnchorDefault() {
+ MarkerView marker = new MarkerViewOptions().position(new LatLng()).getMarker();
+ assertEquals("anchorU should match ", 0.5, marker.getAnchorU(), 0);
+ assertEquals("anchorU should match ", 1, marker.getAnchorV(), 0);
+ }
+
+ @Test
+ public void testInfoWindowAnchor() {
+ float anchorU = 1;
+ float anchorV = 1;
+ MarkerViewOptions markerOptions = new MarkerViewOptions().position(new LatLng()).infoWindowAnchor(anchorU, anchorV);
+ MarkerView marker = markerOptions.getMarker();
+ assertEquals("anchorU should match ", 1, marker.getInfoWindowAnchorU(), 0);
+ assertEquals("anchorU should match ", 1, marker.getInfoWindowAnchorV(), 0);
+ }
+
+ @Test
+ public void testInfoWindowAnchorDefault() {
+ MarkerView marker = new MarkerViewOptions().position(new LatLng()).getMarker();
+ assertEquals("anchorU should match ", 0.5, marker.getInfoWindowAnchorU(), 0);
+ assertEquals("anchorU should match ", 0, marker.getInfoWindowAnchorV(), 0);
+ }
+
+ @Test
+ public void testRotation() {
+ int rotation = 90;
+ MarkerViewOptions markerOptions = new MarkerViewOptions().position(new LatLng()).rotation(rotation);
+ MarkerView marker = markerOptions.getMarker();
+ assertEquals("rotation should match ", rotation, marker.getRotation(), 0);
+ }
+
+ @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;
+
+ // 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, endRotation);
+ }
+
+ @Test
+ public void testRotationUpdateNegative() {
+ float startRotation = 10;
+ float endRotation = 270;
+
+ // 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, endRotation);
+ }
+
+ @Test
+ public void testRotationUpdateMax() {
+ float startRotation = 359;
+ float endRotation = 0;
+
+ // 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, 0);
+ }
+
+ @Test
+ public void testRotationUpdateMin() {
+ float startRotation = 0;
+ float endRotation = 359;
+
+ // 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, endRotation);
+ }
+
+ @Test
+ public void testVisible() {
+ boolean visible = false;
+ MarkerViewOptions markerOptions = new MarkerViewOptions().visible(visible).position(new LatLng());
+ MarkerView marker = markerOptions.getMarker();
+ assertEquals("visible should match ", visible, marker.isVisible());
+ }
+
+ @Test
+ public void testVisibleDefault() {
+ assertTrue(new MarkerViewOptions().position(new LatLng()).getMarker().isVisible());
+ }
+
+ @Test
+ public void testBuilder() {
+ MarkerView marker = new MarkerViewOptions().title("title").snippet("snippet").position(
+ new LatLng(10, 12)).getMarker();
+ assertEquals(marker.getSnippet(), "snippet");
+ assertEquals(marker.getPosition(), new LatLng(10, 12));
+ }
+
+ @Test
+ public void testHashCode() {
+ MarkerView marker = new MarkerViewOptions().position(new LatLng()).getMarker();
+ assertEquals("hash code should match", marker.hashCode(), 0);
+ }
+
+ @Test
+ public void testHashCodeBuilder() {
+ MarkerViewOptions markerOptions = new MarkerViewOptions().position(new LatLng(10, 12));
+ assertEquals("hash code should match", markerOptions.hashCode(), 0);
+ }
+
+ @Test
+ public void testEquals() {
+ MarkerView markerOne = new MarkerViewOptions().position(new LatLng(0, 0)).getMarker();
+ MarkerView markerTwo = new MarkerViewOptions().position(new LatLng(0, 0)).getMarker();
+ assertEquals(markerOne, markerTwo);
+ }
+
+ @Test
+ public void testEqualsItself() {
+ MarkerViewOptions markerOptions = new MarkerViewOptions().position(new LatLng(0, 0));
+ MarkerView marker = markerOptions.getMarker();
+ assertEquals("MarkerView should match", marker, marker);
+ assertEquals("MarkerViewOptions should match", markerOptions, markerOptions);
+ }
+
+ @Test
+ public void testNotEquals() {
+ MarkerViewOptions markerOptions = new MarkerViewOptions().position(new LatLng(0, 0));
+ MarkerView marker = markerOptions.getMarker();
+ assertNotEquals("MarkerViewOptions should match", markerOptions, new Object());
+ assertNotEquals("MarkerView should match", marker, new Object());
+ }
+
+ @Test
+ public void testEqualityBuilder() {
+ MarkerViewOptions markerOne = new MarkerViewOptions().position(new LatLng(0, 0));
+ MarkerViewOptions markerTwo = new MarkerViewOptions().position(new LatLng(0, 0));
+ assertEquals(markerOne, markerTwo);
+ }
+
+ @Test
+ public void testToString() {
+ MarkerView marker = new MarkerViewOptions().position(new LatLng(0, 0)).getMarker();
+ assertEquals(marker.toString(), "MarkerView [position["
+ + "LatLng [latitude=0.0, longitude=0.0, altitude=0.0]" + "]]");
+ }
+
+ @Test
+ public void testParcelable() {
+ MarkerViewOptions markerOptions = new MarkerViewOptions().position(new LatLng()).title("t").snippet("s");
+ Parcelable parcelable = MockParcel.obtain(markerOptions);
+ assertEquals("Parcel should match original object", parcelable, markerOptions);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/PolygonTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/PolygonTest.java
index 744bf55c07..3933c68887 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/PolygonTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/PolygonTest.java
@@ -1,9 +1,5 @@
package com.mapbox.mapboxsdk.annotations;
-import com.mapbox.mapboxsdk.annotations.Polygon;
-import com.mapbox.mapboxsdk.annotations.PolygonOptions;
-import com.mapbox.mapboxsdk.annotations.Polyline;
-import com.mapbox.mapboxsdk.annotations.PolylineOptions;
import com.mapbox.mapboxsdk.geometry.LatLng;
import org.junit.Test;
@@ -16,64 +12,64 @@ import static org.junit.Assert.assertNotNull;
public class PolygonTest {
- @Test
- public void testSanity() {
- PolygonOptions polygonOptions = new PolygonOptions();
- assertNotNull("polygonOptions should not be null", polygonOptions);
- }
+ @Test
+ public void testSanity() {
+ PolygonOptions polygonOptions = new PolygonOptions();
+ assertNotNull("polygonOptions should not be null", polygonOptions);
+ }
- @Test
- public void testPolygon() {
- Polygon polygon = new PolygonOptions().getPolygon();
- assertNotNull("polyline should not be null", polygon);
- }
+ @Test
+ public void testPolygon() {
+ Polygon polygon = new PolygonOptions().getPolygon();
+ assertNotNull("polyline should not be null", polygon);
+ }
- @Test
- public void testAlpha() {
- Polygon polygon = new PolygonOptions().alpha(0.5f).getPolygon();
- assertEquals(0.5f, polygon.getAlpha(), 0.0f);
- }
+ @Test
+ public void testAlpha() {
+ Polygon polygon = new PolygonOptions().alpha(0.5f).getPolygon();
+ assertEquals(0.5f, polygon.getAlpha(), 0.0f);
+ }
- @Test
- public void testStrokeColor() {
- Polygon polygon = new PolygonOptions().strokeColor(1).getPolygon();
- assertEquals(1, polygon.getStrokeColor());
- }
+ @Test
+ public void testStrokeColor() {
+ Polygon polygon = new PolygonOptions().strokeColor(1).getPolygon();
+ assertEquals(1, polygon.getStrokeColor());
+ }
- @Test
- public void testFillColor() {
- Polygon polygon = new PolygonOptions().fillColor(1).getPolygon();
- assertEquals(1, polygon.getFillColor());
- }
+ @Test
+ public void testFillColor() {
+ Polygon polygon = new PolygonOptions().fillColor(1).getPolygon();
+ assertEquals(1, polygon.getFillColor());
+ }
- @Test
- public void testLatLng() {
- Polygon polygon = new PolygonOptions().add(new LatLng(0, 0)).getPolygon();
- assertNotNull("points should not be null", polygon.getPoints());
- assertEquals(new LatLng(0, 0), polygon.getPoints().get(0));
- }
+ @Test
+ public void testLatLng() {
+ Polygon polygon = new PolygonOptions().add(new LatLng(0, 0)).getPolygon();
+ assertNotNull("points should not be null", polygon.getPoints());
+ assertEquals(new LatLng(0, 0), polygon.getPoints().get(0));
+ }
- @Test
- public void testAddAllLatLng() {
- List<LatLng> coordinates = new ArrayList<>();
- coordinates.add(new LatLng(0, 0));
- Polygon polygon = new PolygonOptions().addAll(coordinates).getPolygon();
- assertNotNull(polygon.getPoints());
- assertEquals(new LatLng(0, 0), polygon.getPoints().get(0));
- }
+ @Test
+ public void testAddAllLatLng() {
+ List<LatLng> coordinates = new ArrayList<>();
+ coordinates.add(new LatLng(0, 0));
+ Polygon polygon = new PolygonOptions().addAll(coordinates).getPolygon();
+ assertNotNull(polygon.getPoints());
+ assertEquals(new LatLng(0, 0), polygon.getPoints().get(0));
+ }
- @Test
- public void testBuilder() {
- PolylineOptions polylineOptions = new PolylineOptions();
- polylineOptions.width(1.0f);
- polylineOptions.color(2);
- polylineOptions.add(new LatLng(0, 0));
+ @Test
+ public void testBuilder() {
+ PolylineOptions polylineOptions = new PolylineOptions();
+ polylineOptions.width(1.0f);
+ polylineOptions.color(2);
+ polylineOptions.add(new LatLng(0, 0));
- Polyline polyline = polylineOptions.getPolyline();
- assertEquals(1.0f, polyline.getWidth(), 0);
- assertEquals(2, polyline.getColor());
- assertNotNull("Points should not be null", polyline.getPoints());
- assertEquals(new LatLng(0, 0), polyline.getPoints().get(0));
- }
+ Polyline polyline = polylineOptions.getPolyline();
+ assertEquals(1.0f, polyline.getWidth(), 0);
+ assertEquals(2, polyline.getColor());
+ assertNotNull("Points should not be null", polyline.getPoints());
+ assertEquals(new LatLng(0, 0), polyline.getPoints().get(0));
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/PolylineTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/PolylineTest.java
index b95c9dba2a..54bb0e8cf4 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/PolylineTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/PolylineTest.java
@@ -1,7 +1,5 @@
package com.mapbox.mapboxsdk.annotations;
-import com.mapbox.mapboxsdk.annotations.Polyline;
-import com.mapbox.mapboxsdk.annotations.PolylineOptions;
import com.mapbox.mapboxsdk.geometry.LatLng;
import org.junit.Test;
@@ -14,64 +12,64 @@ import static org.junit.Assert.assertNotNull;
public class PolylineTest {
- @Test
- public void testSanity() {
- PolylineOptions polylineOptions = new PolylineOptions();
- assertNotNull("polylineOptions should not be null", polylineOptions);
- }
+ @Test
+ public void testSanity() {
+ PolylineOptions polylineOptions = new PolylineOptions();
+ assertNotNull("polylineOptions should not be null", polylineOptions);
+ }
- @Test
- public void testPolyline() {
- Polyline polyline = new PolylineOptions().getPolyline();
- assertNotNull("polyline should not be null", polyline);
- }
+ @Test
+ public void testPolyline() {
+ Polyline polyline = new PolylineOptions().getPolyline();
+ assertNotNull("polyline should not be null", polyline);
+ }
- @Test
- public void testAlpha() {
- Polyline polyline = new PolylineOptions().alpha(0.2f).getPolyline();
- assertEquals(0.2f, polyline.getAlpha(), 0.0f);
- }
+ @Test
+ public void testAlpha() {
+ Polyline polyline = new PolylineOptions().alpha(0.2f).getPolyline();
+ assertEquals(0.2f, polyline.getAlpha(), 0.0f);
+ }
- @Test
- public void testWidth() {
- Polyline polyline = new PolylineOptions().width(1).getPolyline();
- assertEquals(1.0f, polyline.getWidth(), 0);
- }
+ @Test
+ public void testWidth() {
+ Polyline polyline = new PolylineOptions().width(1).getPolyline();
+ assertEquals(1.0f, polyline.getWidth(), 0);
+ }
- @Test
- public void testColor() {
- Polyline polyline = new PolylineOptions().color(1).getPolyline();
- assertEquals(1, polyline.getColor());
- }
+ @Test
+ public void testColor() {
+ Polyline polyline = new PolylineOptions().color(1).getPolyline();
+ assertEquals(1, polyline.getColor());
+ }
- @Test
- public void testAddLatLng() {
- Polyline polyline = new PolylineOptions().add(new LatLng(0, 0)).getPolyline();
- assertNotNull("Points should not be null", polyline.getPoints());
- assertEquals(new LatLng(0, 0), polyline.getPoints().get(0));
- }
+ @Test
+ public void testAddLatLng() {
+ Polyline polyline = new PolylineOptions().add(new LatLng(0, 0)).getPolyline();
+ assertNotNull("Points should not be null", polyline.getPoints());
+ assertEquals(new LatLng(0, 0), polyline.getPoints().get(0));
+ }
- @Test
- public void testAddAllLatLng() {
- List<LatLng> coordinates = new ArrayList<>();
- coordinates.add(new LatLng(0, 0));
- Polyline polyline = new PolylineOptions().addAll(coordinates).getPolyline();
- assertNotNull(polyline.getPoints());
- assertEquals(new LatLng(0, 0), polyline.getPoints().get(0));
- }
+ @Test
+ public void testAddAllLatLng() {
+ List<LatLng> coordinates = new ArrayList<>();
+ coordinates.add(new LatLng(0, 0));
+ Polyline polyline = new PolylineOptions().addAll(coordinates).getPolyline();
+ assertNotNull(polyline.getPoints());
+ assertEquals(new LatLng(0, 0), polyline.getPoints().get(0));
+ }
- @Test
- public void testBuilder() {
- PolylineOptions polylineOptions = new PolylineOptions();
- polylineOptions.width(1.0f);
- polylineOptions.color(2);
- polylineOptions.add(new LatLng(0, 0));
+ @Test
+ public void testBuilder() {
+ PolylineOptions polylineOptions = new PolylineOptions();
+ polylineOptions.width(1.0f);
+ polylineOptions.color(2);
+ polylineOptions.add(new LatLng(0, 0));
- Polyline polyline = polylineOptions.getPolyline();
- assertEquals(1.0f, polyline.getWidth(), 0);
- assertEquals(2, polyline.getColor());
- assertNotNull("Points should not be null", polyline.getPoints());
- assertEquals(new LatLng(0, 0), polyline.getPoints().get(0));
- }
+ Polyline polyline = polylineOptions.getPolyline();
+ assertEquals(1.0f, polyline.getWidth(), 0);
+ assertEquals(2, polyline.getColor());
+ assertNotNull("Points should not be null", polyline.getPoints());
+ assertEquals(new LatLng(0, 0), polyline.getPoints().get(0));
+ }
}
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 bce020255e..a8aad8d639 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
@@ -18,108 +18,109 @@ import static org.mockito.Mockito.when;
public class CameraPositionTest {
- private static final double DELTA = 1e-15;
-
- @Test
- public void testSanity() {
- LatLng latLng = new LatLng(1, 2);
- CameraPosition cameraPosition = new CameraPosition(latLng, 3, 4, 5);
- assertNotNull("cameraPosition should not be null", cameraPosition);
- }
-
- @Test
- public void testDefaultTypedArrayBuilder() {
- TypedArray typedArray = null;
- CameraPosition cameraPosition = new CameraPosition.Builder(typedArray).build();
- assertEquals("bearing should match", -1, cameraPosition.bearing, DELTA);
- assertEquals("latlng should match", null, cameraPosition.target);
- assertEquals("tilt should match", -1, cameraPosition.tilt, DELTA);
- assertEquals("zoom should match", -1, cameraPosition.zoom, DELTA);
- }
-
- @Test
- public void testTypedArrayBuilder() {
- float bearing = 180;
- float zoom = 12;
- float latitude = 10;
- float longitude = 11;
- float tilt = 44;
-
- TypedArray typedArray = mock(TypedArray.class);
- when(typedArray.getFloat(R.styleable.MapView_direction, 0.0f)).thenReturn(bearing);
- when(typedArray.getFloat(R.styleable.MapView_center_latitude, 0.0f)).thenReturn(latitude);
- when(typedArray.getFloat(R.styleable.MapView_center_longitude, 0.0f)).thenReturn(longitude);
- when(typedArray.getFloat(R.styleable.MapView_zoom, 0.0f)).thenReturn(zoom);
- when(typedArray.getFloat(R.styleable.MapView_tilt, 0.0f)).thenReturn(tilt);
- doNothing().when(typedArray).recycle();
-
- 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", tilt, cameraPosition.tilt, DELTA);
- assertEquals("zoom should match", zoom, cameraPosition.zoom, DELTA);
- }
-
- @Test
- public void testJniBuilder() {
- double bearing = 180;
- double zoom = 12;
- double latitude = 10;
- double longitude = 11;
- double tilt = 44;
-
- double[] cameraVars = new double[]{latitude, longitude, bearing, tilt, zoom};
- CameraPosition cameraPosition = new CameraPosition.Builder(cameraVars).build();
- assertEquals("bearing should match", bearing, cameraPosition.bearing, DELTA);
- assertEquals("latlng should match", new LatLng(latitude, longitude), cameraPosition.target);
- assertEquals("tilt should match", tilt, cameraPosition.tilt, DELTA);
- assertEquals("zoom should match", zoom, cameraPosition.zoom, DELTA);
- }
-
- @Test
- public void testToString() {
- LatLng latLng = new LatLng(1, 2);
- CameraPosition cameraPosition = new CameraPosition(latLng, 3, 4, 5);
- assertEquals("toString should match", "Target: LatLng [latitude=1.0, longitude=2.0, altitude=0.0], Zoom:3.0, Bearing:5.0, Tilt:4.0", cameraPosition.toString());
- }
-
- @Test
- public void testHashcode() {
- LatLng latLng = new LatLng(1, 2);
- CameraPosition cameraPosition = new CameraPosition(latLng, 3, 4, 5);
- assertEquals("hashCode should match", -1007681505, cameraPosition.hashCode());
- }
-
- @Test
- public void testZoomUpdateBuilder() {
- float zoomLevel = 5;
- CameraPosition.Builder builder = new CameraPosition.Builder(
- (CameraUpdateFactory.ZoomUpdate) CameraUpdateFactory.zoomTo(zoomLevel));
- assertEquals("zoom should match", zoomLevel, builder.build().zoom, 0);
- }
-
- @Test
- public void testEquals() {
- LatLng latLng = new LatLng(1, 2);
- CameraPosition cameraPosition = new CameraPosition(latLng, 3, 4, 5);
- CameraPosition cameraPositionBearing = new CameraPosition(latLng, 3, 4, 9);
- CameraPosition cameraPositionTilt = new CameraPosition(latLng, 3, 9, 5);
- CameraPosition cameraPositionZoom = new CameraPosition(latLng, 9, 4, 5);
- CameraPosition cameraPositionTarget = new CameraPosition(new LatLng(), 3, 4, 5);
-
- assertEquals("cameraPosition should match itself", cameraPosition, cameraPosition);
- assertNotEquals("cameraPosition should not match null", null, cameraPosition);
- assertNotEquals("cameraPosition should not match object", new Object(), cameraPosition);
- assertNotEquals("cameraPosition should not match for bearing", cameraPositionBearing, cameraPosition);
- assertNotEquals("cameraPosition should not match for tilt", cameraPositionTilt, cameraPosition);
- assertNotEquals("cameraPosition should not match for zoom", cameraPositionZoom, cameraPosition);
- assertNotEquals("cameraPosition should not match for target", cameraPositionTarget, cameraPosition);
- }
-
- @Test
- public void testParcelable() {
- CameraPosition object = new CameraPosition(new LatLng(1, 2), 3, 4, 5);
- Parcelable parcelable = MockParcel.obtain(object);
- assertEquals("Parcel should match original object", parcelable, object);
- }
-}
+ private static final double DELTA = 1e-15;
+
+ @Test
+ public void testSanity() {
+ LatLng latLng = new LatLng(1, 2);
+ CameraPosition cameraPosition = new CameraPosition(latLng, 3, 4, 5);
+ assertNotNull("cameraPosition should not be null", cameraPosition);
+ }
+
+ @Test
+ public void testDefaultTypedArrayBuilder() {
+ TypedArray typedArray = null;
+ CameraPosition cameraPosition = new CameraPosition.Builder(typedArray).build();
+ assertEquals("bearing should match", -1, cameraPosition.bearing, DELTA);
+ assertEquals("latlng should match", null, cameraPosition.target);
+ assertEquals("tilt should match", -1, cameraPosition.tilt, DELTA);
+ assertEquals("zoom should match", -1, cameraPosition.zoom, DELTA);
+ }
+
+ @Test
+ public void testTypedArrayBuilder() {
+ float bearing = 180;
+ float zoom = 12;
+ float latitude = 10;
+ float longitude = 11;
+ float tilt = 44;
+
+ TypedArray typedArray = mock(TypedArray.class);
+ when(typedArray.getFloat(R.styleable.mapbox_MapView_mapbox_cameraBearing, 0.0f)).thenReturn(bearing);
+ when(typedArray.getFloat(R.styleable.mapbox_MapView_mapbox_cameraTargetLat, 0.0f)).thenReturn(latitude);
+ when(typedArray.getFloat(R.styleable.mapbox_MapView_mapbox_cameraTargetLng, 0.0f)).thenReturn(longitude);
+ when(typedArray.getFloat(R.styleable.mapbox_MapView_mapbox_cameraZoom, 0.0f)).thenReturn(zoom);
+ when(typedArray.getFloat(R.styleable.mapbox_MapView_mapbox_cameraTilt, 0.0f)).thenReturn(tilt);
+ doNothing().when(typedArray).recycle();
+
+ 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", tilt, cameraPosition.tilt, DELTA);
+ assertEquals("zoom should match", zoom, cameraPosition.zoom, DELTA);
+ }
+
+ @Test
+ public void testJniBuilder() {
+ double bearing = 180;
+ double zoom = 12;
+ double latitude = 10;
+ double longitude = 11;
+ double tilt = 44;
+
+ double[] cameraVars = new double[]{latitude, longitude, bearing, tilt, zoom};
+ CameraPosition cameraPosition = new CameraPosition.Builder(cameraVars).build();
+ assertEquals("bearing should match", bearing, cameraPosition.bearing, DELTA);
+ assertEquals("latlng should match", new LatLng(latitude, longitude), cameraPosition.target);
+ assertEquals("tilt should match", tilt, cameraPosition.tilt, DELTA);
+ assertEquals("zoom should match", zoom, cameraPosition.zoom, DELTA);
+ }
+
+ @Test
+ public void testToString() {
+ LatLng latLng = new LatLng(1, 2);
+ CameraPosition cameraPosition = new CameraPosition(latLng, 3, 4, 5);
+ assertEquals("toString should match", "Target: LatLng [latitude=1.0, longitude=2.0, altitude=0.0], Zoom:3.0, "
+ + "Bearing:5.0, Tilt:4.0", cameraPosition.toString());
+ }
+
+ @Test
+ public void testHashcode() {
+ LatLng latLng = new LatLng(1, 2);
+ CameraPosition cameraPosition = new CameraPosition(latLng, 3, 4, 5);
+ assertEquals("hashCode should match", -1007681505, cameraPosition.hashCode());
+ }
+
+ @Test
+ public void testZoomUpdateBuilder() {
+ float zoomLevel = 5;
+ CameraPosition.Builder builder = new CameraPosition.Builder(
+ (CameraUpdateFactory.ZoomUpdate) CameraUpdateFactory.zoomTo(zoomLevel));
+ assertEquals("zoom should match", zoomLevel, builder.build().zoom, 0);
+ }
+
+ @Test
+ public void testEquals() {
+ LatLng latLng = new LatLng(1, 2);
+ CameraPosition cameraPosition = new CameraPosition(latLng, 3, 4, 5);
+ CameraPosition cameraPositionBearing = new CameraPosition(latLng, 3, 4, 9);
+ CameraPosition cameraPositionTilt = new CameraPosition(latLng, 3, 9, 5);
+ CameraPosition cameraPositionZoom = new CameraPosition(latLng, 9, 4, 5);
+ CameraPosition cameraPositionTarget = new CameraPosition(new LatLng(), 3, 4, 5);
+
+ assertEquals("cameraPosition should match itself", cameraPosition, cameraPosition);
+ assertNotEquals("cameraPosition should not match null", null, cameraPosition);
+ assertNotEquals("cameraPosition should not match object", new Object(), cameraPosition);
+ assertNotEquals("cameraPosition should not match for bearing", cameraPositionBearing, cameraPosition);
+ assertNotEquals("cameraPosition should not match for tilt", cameraPositionTilt, cameraPosition);
+ assertNotEquals("cameraPosition should not match for zoom", cameraPositionZoom, cameraPosition);
+ assertNotEquals("cameraPosition should not match for target", cameraPositionTarget, cameraPosition);
+ }
+
+ @Test
+ public void testParcelable() {
+ CameraPosition object = new CameraPosition(new LatLng(1, 2), 3, 4, 5);
+ Parcelable parcelable = MockParcel.obtain(object);
+ assertEquals("Parcel should match original object", parcelable, object);
+ }
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/constants/StyleVersionTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/constants/StyleVersionTest.java
index 3d9b2a9364..5623afeb58 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/constants/StyleVersionTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/constants/StyleVersionTest.java
@@ -9,13 +9,13 @@ import static junit.framework.Assert.assertEquals;
public class StyleVersionTest {
- private static final double DELTA = 1e-15;
+ private static final double DELTA = 1e-15;
- @Test
- public void testSanity() {
- assertEquals("Style version should match, when upgrading, verify that integers.xml is updated",
- AppConstant.STYLE_VERSION,
- 9,
- DELTA);
- }
+ @Test
+ public void testSanity() {
+ assertEquals("Style version should match, when upgrading, verify that integers.xml is updated",
+ AppConstant.STYLE_VERSION,
+ 9,
+ DELTA);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngBoundsTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngBoundsTest.java
index b2cc1e9046..a42ca96cf5 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngBoundsTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngBoundsTest.java
@@ -20,185 +20,186 @@ import static org.junit.Assert.assertTrue;
public class LatLngBoundsTest {
- private static final double DELTA = 1e-15;
-
- private LatLngBounds mLatLngBounds;
- private static final LatLng LAT_LNG_NULL_ISLAND = new LatLng(0, 0);
- private static final LatLng LAT_LNG_NOT_NULL_ISLAND = new LatLng(2, 2);
-
- @Before
- public void beforeTest() {
- mLatLngBounds = new LatLngBounds.Builder()
- .include(LAT_LNG_NULL_ISLAND)
- .include(LAT_LNG_NOT_NULL_ISLAND)
- .build();
- }
-
- @Test
- public void testSanity() {
- LatLngBounds.Builder latLngBoundsBuilder = new LatLngBounds.Builder();
- latLngBoundsBuilder.include(LAT_LNG_NULL_ISLAND).include(LAT_LNG_NOT_NULL_ISLAND);
- assertNotNull("latLng should not be null", latLngBoundsBuilder.build());
- }
-
- @Test(expected = InvalidLatLngBoundsException.class)
- public void testNoLatLngs() {
- new LatLngBounds.Builder().build();
- }
-
- @Test(expected = InvalidLatLngBoundsException.class)
- public void testOneLatLngs() {
- new LatLngBounds.Builder().include(LAT_LNG_NULL_ISLAND).build();
- }
-
- @Test
- public void testLatitiudeSpan() {
- assertEquals("Span should be the same", 2, mLatLngBounds.getLatitudeSpan(), DELTA);
- }
-
- @Test
- public void testLongitudeSpan() {
- assertEquals("Span should be the same", 2, mLatLngBounds.getLongitudeSpan(), DELTA);
- }
-
- @Test
- public void testCoordinateSpan() {
- LatLngSpan latLngSpan = mLatLngBounds.getSpan();
- assertEquals("LatLngSpan should be the same", new LatLngSpan(2, 2), latLngSpan);
- }
-
- @Test
- public void testCenter() {
- LatLng center = mLatLngBounds.getCenter();
- assertEquals("Center should match", new LatLng(1, 1), center);
- }
-
- @Test
- public void testEmptySpan() {
- mLatLngBounds = new LatLngBounds.Builder()
- .include(LAT_LNG_NOT_NULL_ISLAND)
- .include(LAT_LNG_NOT_NULL_ISLAND)
- .build();
- assertTrue("Should be empty", mLatLngBounds.isEmptySpan());
- }
-
- @Test
- public void testNotEmptySpan() {
- mLatLngBounds = new LatLngBounds.Builder()
- .include(LAT_LNG_NOT_NULL_ISLAND)
- .include(LAT_LNG_NULL_ISLAND)
- .build();
- assertFalse("Should not be empty", mLatLngBounds.isEmptySpan());
- }
-
- @Test
- public void testToLatLngs() {
- mLatLngBounds = new LatLngBounds.Builder()
- .include(LAT_LNG_NOT_NULL_ISLAND)
- .include(LAT_LNG_NULL_ISLAND)
- .build();
-
- assertArrayEquals("LatLngs should match",
- new LatLng[]{LAT_LNG_NOT_NULL_ISLAND, LAT_LNG_NULL_ISLAND},
- mLatLngBounds.toLatLngs());
- }
-
- @Test
- public void testIncluding() {
- assertTrue("LatLng should be included", mLatLngBounds.contains(new LatLng(1, 1)));
- }
-
- @Test
- public void testIncludes() {
- List<LatLng> points = new ArrayList<>();
- points.add(LAT_LNG_NULL_ISLAND);
- points.add(LAT_LNG_NOT_NULL_ISLAND);
-
- LatLngBounds latLngBounds1 = new LatLngBounds.Builder()
- .includes(points)
- .build();
-
- LatLngBounds latLngBounds2 = new LatLngBounds.Builder()
- .include(LAT_LNG_NULL_ISLAND)
- .include(LAT_LNG_NOT_NULL_ISLAND)
- .build();
-
- assertEquals("LatLngBounds should match", latLngBounds1, latLngBounds2);
- }
-
- @Test
- public void testNoIncluding() {
- assertFalse("LatLng should not be included", mLatLngBounds.contains(new LatLng(3, 1)));
- }
-
- @Test
- public void testHashCode() {
- assertEquals(2147483647, mLatLngBounds.hashCode(), -1946419200);
- }
-
- @Test
- public void testEquality() {
- LatLngBounds latLngBounds = new LatLngBounds.Builder()
- .include(LAT_LNG_NULL_ISLAND)
- .include(LAT_LNG_NOT_NULL_ISLAND)
- .build();
- assertEquals("equality should match", mLatLngBounds, latLngBounds);
- assertEquals("not equal to a different object type", mLatLngBounds.equals(LAT_LNG_NOT_NULL_ISLAND), false);
- }
-
- @Test
- public void testToString() {
- assertEquals(mLatLngBounds.toString(), "N:2.0; E:2.0; S:0.0; W:0.0");
- }
-
- @Test
- public void testIntersect() {
- LatLngBounds latLngBounds = new LatLngBounds.Builder()
- .include(new LatLng(1, 1))
- .include(LAT_LNG_NULL_ISLAND)
- .build();
- assertEquals("intersect should match", latLngBounds, latLngBounds.intersect(mLatLngBounds.getLatNorth(), mLatLngBounds.getLonEast(), mLatLngBounds.getLatSouth(), mLatLngBounds.getLonWest()));
- }
-
- @Test
- public void testNoIntersect() {
- LatLngBounds latLngBounds = new LatLngBounds.Builder()
- .include(new LatLng(10, 10))
- .include(new LatLng(9, 8))
- .build();
- assertNull(latLngBounds.intersect(mLatLngBounds));
- }
-
- @Test
- public void testInnerUnion() {
- LatLngBounds latLngBounds = new LatLngBounds.Builder()
- .include(new LatLng(1, 1))
- .include(LAT_LNG_NULL_ISLAND)
- .build();
- assertEquals("union should match", latLngBounds, latLngBounds.intersect(mLatLngBounds));
- }
-
- @Test
- public void testOuterUnion() {
- LatLngBounds latLngBounds = new LatLngBounds.Builder()
- .include(new LatLng(10, 10))
- .include(new LatLng(9, 8))
- .build();
- assertEquals("outer union should match",
- latLngBounds.union(mLatLngBounds),
- new LatLngBounds.Builder()
- .include(new LatLng(10, 10))
- .include(LAT_LNG_NULL_ISLAND)
- .build());
- }
-
- @Test
- public void testParcelable() {
- LatLngBounds latLngBounds = new LatLngBounds.Builder()
- .include(new LatLng(10, 10))
- .include(new LatLng(9, 8))
- .build();
- Parcelable parcel = MockParcel.obtain(latLngBounds);
- assertEquals("Parcel should match original object", parcel, latLngBounds);
- }
+ private static final double DELTA = 1e-15;
+
+ private LatLngBounds latLngBounds;
+ private static final LatLng LAT_LNG_NULL_ISLAND = new LatLng(0, 0);
+ private static final LatLng LAT_LNG_NOT_NULL_ISLAND = new LatLng(2, 2);
+
+ @Before
+ public void beforeTest() {
+ latLngBounds = new LatLngBounds.Builder()
+ .include(LAT_LNG_NULL_ISLAND)
+ .include(LAT_LNG_NOT_NULL_ISLAND)
+ .build();
+ }
+
+ @Test
+ public void testSanity() {
+ LatLngBounds.Builder latLngBoundsBuilder = new LatLngBounds.Builder();
+ latLngBoundsBuilder.include(LAT_LNG_NULL_ISLAND).include(LAT_LNG_NOT_NULL_ISLAND);
+ assertNotNull("latLng should not be null", latLngBoundsBuilder.build());
+ }
+
+ @Test(expected = InvalidLatLngBoundsException.class)
+ public void testNoLatLngs() {
+ new LatLngBounds.Builder().build();
+ }
+
+ @Test(expected = InvalidLatLngBoundsException.class)
+ public void testOneLatLngs() {
+ new LatLngBounds.Builder().include(LAT_LNG_NULL_ISLAND).build();
+ }
+
+ @Test
+ public void testLatitiudeSpan() {
+ assertEquals("Span should be the same", 2, latLngBounds.getLatitudeSpan(), DELTA);
+ }
+
+ @Test
+ public void testLongitudeSpan() {
+ assertEquals("Span should be the same", 2, latLngBounds.getLongitudeSpan(), DELTA);
+ }
+
+ @Test
+ public void testCoordinateSpan() {
+ LatLngSpan latLngSpan = latLngBounds.getSpan();
+ assertEquals("LatLngSpan should be the same", new LatLngSpan(2, 2), latLngSpan);
+ }
+
+ @Test
+ public void testCenter() {
+ LatLng center = latLngBounds.getCenter();
+ assertEquals("Center should match", new LatLng(1, 1), center);
+ }
+
+ @Test
+ public void testEmptySpan() {
+ latLngBounds = new LatLngBounds.Builder()
+ .include(LAT_LNG_NOT_NULL_ISLAND)
+ .include(LAT_LNG_NOT_NULL_ISLAND)
+ .build();
+ assertTrue("Should be empty", latLngBounds.isEmptySpan());
+ }
+
+ @Test
+ public void testNotEmptySpan() {
+ latLngBounds = new LatLngBounds.Builder()
+ .include(LAT_LNG_NOT_NULL_ISLAND)
+ .include(LAT_LNG_NULL_ISLAND)
+ .build();
+ assertFalse("Should not be empty", latLngBounds.isEmptySpan());
+ }
+
+ @Test
+ public void testToLatLngs() {
+ latLngBounds = new LatLngBounds.Builder()
+ .include(LAT_LNG_NOT_NULL_ISLAND)
+ .include(LAT_LNG_NULL_ISLAND)
+ .build();
+
+ assertArrayEquals("LatLngs should match",
+ new LatLng[] {LAT_LNG_NOT_NULL_ISLAND, LAT_LNG_NULL_ISLAND},
+ latLngBounds.toLatLngs());
+ }
+
+ @Test
+ public void testIncluding() {
+ assertTrue("LatLng should be included", latLngBounds.contains(new LatLng(1, 1)));
+ }
+
+ @Test
+ public void testIncludes() {
+ List<LatLng> points = new ArrayList<>();
+ points.add(LAT_LNG_NULL_ISLAND);
+ points.add(LAT_LNG_NOT_NULL_ISLAND);
+
+ LatLngBounds latLngBounds1 = new LatLngBounds.Builder()
+ .includes(points)
+ .build();
+
+ LatLngBounds latLngBounds2 = new LatLngBounds.Builder()
+ .include(LAT_LNG_NULL_ISLAND)
+ .include(LAT_LNG_NOT_NULL_ISLAND)
+ .build();
+
+ assertEquals("LatLngBounds should match", latLngBounds1, latLngBounds2);
+ }
+
+ @Test
+ public void testNoIncluding() {
+ assertFalse("LatLng should not be included", latLngBounds.contains(new LatLng(3, 1)));
+ }
+
+ @Test
+ public void testHashCode() {
+ assertEquals(2147483647, latLngBounds.hashCode(), -1946419200);
+ }
+
+ @Test
+ public void testEquality() {
+ LatLngBounds latLngBounds = new LatLngBounds.Builder()
+ .include(LAT_LNG_NULL_ISLAND)
+ .include(LAT_LNG_NOT_NULL_ISLAND)
+ .build();
+ assertEquals("equality should match", this.latLngBounds, latLngBounds);
+ assertEquals("not equal to a different object type", this.latLngBounds.equals(LAT_LNG_NOT_NULL_ISLAND), false);
+ }
+
+ @Test
+ public void testToString() {
+ assertEquals(latLngBounds.toString(), "N:2.0; E:2.0; S:0.0; W:0.0");
+ }
+
+ @Test
+ public void testIntersect() {
+ LatLngBounds latLngBounds = new LatLngBounds.Builder()
+ .include(new LatLng(1, 1))
+ .include(LAT_LNG_NULL_ISLAND)
+ .build();
+ assertEquals("intersect should match", latLngBounds, latLngBounds.intersect(this.latLngBounds.getLatNorth(),
+ this.latLngBounds.getLonEast(), this.latLngBounds.getLatSouth(), this.latLngBounds.getLonWest()));
+ }
+
+ @Test
+ public void testNoIntersect() {
+ LatLngBounds latLngBounds = new LatLngBounds.Builder()
+ .include(new LatLng(10, 10))
+ .include(new LatLng(9, 8))
+ .build();
+ assertNull(latLngBounds.intersect(this.latLngBounds));
+ }
+
+ @Test
+ public void testInnerUnion() {
+ LatLngBounds latLngBounds = new LatLngBounds.Builder()
+ .include(new LatLng(1, 1))
+ .include(LAT_LNG_NULL_ISLAND)
+ .build();
+ assertEquals("union should match", latLngBounds, latLngBounds.intersect(this.latLngBounds));
+ }
+
+ @Test
+ public void testOuterUnion() {
+ LatLngBounds latLngBounds = new LatLngBounds.Builder()
+ .include(new LatLng(10, 10))
+ .include(new LatLng(9, 8))
+ .build();
+ assertEquals("outer union should match",
+ latLngBounds.union(this.latLngBounds),
+ new LatLngBounds.Builder()
+ .include(new LatLng(10, 10))
+ .include(LAT_LNG_NULL_ISLAND)
+ .build());
+ }
+
+ @Test
+ public void testParcelable() {
+ LatLngBounds latLngBounds = new LatLngBounds.Builder()
+ .include(new LatLng(10, 10))
+ .include(new LatLng(9, 8))
+ .build();
+ Parcelable parcel = MockParcel.obtain(latLngBounds);
+ assertEquals("Parcel should match original object", parcel, latLngBounds);
+ }
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngSpanTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngSpanTest.java
index e184097a43..12297247cf 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngSpanTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngSpanTest.java
@@ -11,55 +11,55 @@ import static org.junit.Assert.assertNotNull;
public class LatLngSpanTest {
- private static final double DELTA = 1e-15;
- private static final LatLng LAT_LNG_NULL_ISLAND = new LatLng(0, 0);
+ private static final double DELTA = 1e-15;
+ private static final LatLng LAT_LNG_NULL_ISLAND = new LatLng(0, 0);
- @Test
- public void testSanity() {
- LatLngSpan latLngSpan = new LatLngSpan(0.0, 0.0);
- assertNotNull("latLngSpan should not be null", latLngSpan);
- }
+ @Test
+ public void testSanity() {
+ LatLngSpan latLngSpan = new LatLngSpan(0.0, 0.0);
+ assertNotNull("latLngSpan should not be null", latLngSpan);
+ }
- @Test
- public void testEquality() {
- LatLngSpan latLngSpan = new LatLngSpan(0.0, 0.0);
- assertEquals("latLngSpan is not equal to a LatLng", latLngSpan.equals(LAT_LNG_NULL_ISLAND), false);
- }
+ @Test
+ public void testEquality() {
+ LatLngSpan latLngSpan = new LatLngSpan(0.0, 0.0);
+ assertEquals("latLngSpan is not equal to a LatLng", latLngSpan.equals(LAT_LNG_NULL_ISLAND), false);
+ }
- @Test
- public void testLatitudeConstructor() {
- double latitude = 1.23;
- LatLngSpan latLngSpan = new LatLngSpan(latitude, 0.0);
- assertEquals("latitude in constructor", latLngSpan.getLatitudeSpan(), latitude, DELTA);
- }
+ @Test
+ public void testLatitudeConstructor() {
+ double latitude = 1.23;
+ LatLngSpan latLngSpan = new LatLngSpan(latitude, 0.0);
+ assertEquals("latitude in constructor", latLngSpan.getLatitudeSpan(), latitude, DELTA);
+ }
- @Test
- public void testLongitudeConstructor() {
- double longitude = 1.23;
- LatLngSpan latLngSpan = new LatLngSpan(0.0, longitude);
- assertEquals("latitude in constructor", latLngSpan.getLongitudeSpan(), longitude, DELTA);
- }
+ @Test
+ public void testLongitudeConstructor() {
+ double longitude = 1.23;
+ LatLngSpan latLngSpan = new LatLngSpan(0.0, longitude);
+ assertEquals("latitude in constructor", latLngSpan.getLongitudeSpan(), longitude, DELTA);
+ }
- @Test
- public void testLatitudeMethod() {
- double latitude = 1.23;
- LatLngSpan latLngSpan = new LatLngSpan(0.0, 0.0);
- latLngSpan.setLatitudeSpan(latitude);
- assertEquals("latitude in constructor", latLngSpan.getLatitudeSpan(), latitude, DELTA);
- }
+ @Test
+ public void testLatitudeMethod() {
+ double latitude = 1.23;
+ LatLngSpan latLngSpan = new LatLngSpan(0.0, 0.0);
+ latLngSpan.setLatitudeSpan(latitude);
+ assertEquals("latitude in constructor", latLngSpan.getLatitudeSpan(), latitude, DELTA);
+ }
- @Test
- public void testLongitudeMethod() {
- double longitude = 1.23;
- LatLngSpan latLngSpan = new LatLngSpan(0.0, 0.0);
- latLngSpan.setLongitudeSpan(longitude);
- assertEquals("latitude in constructor", latLngSpan.getLongitudeSpan(), longitude, DELTA);
- }
+ @Test
+ public void testLongitudeMethod() {
+ double longitude = 1.23;
+ LatLngSpan latLngSpan = new LatLngSpan(0.0, 0.0);
+ latLngSpan.setLongitudeSpan(longitude);
+ assertEquals("latitude in constructor", latLngSpan.getLongitudeSpan(), longitude, DELTA);
+ }
- @Test
- public void testParcelable() {
- LatLngSpan object = new LatLngSpan(1, 2);
- Parcelable parcel = MockParcel.obtain(object);
- assertEquals("parcel should match initial object", object, parcel);
- }
+ @Test
+ public void testParcelable() {
+ LatLngSpan object = new LatLngSpan(1, 2);
+ Parcelable parcel = MockParcel.obtain(object);
+ assertEquals("parcel should match initial object", object, parcel);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngTest.java
index de5dbc5e09..5cbf1fa63c 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngTest.java
@@ -16,182 +16,182 @@ import static org.mockito.Mockito.when;
public class LatLngTest {
- private static final double DELTA = 1e-15;
-
- @Test
- public void testSanity() {
- LatLng latLng = new LatLng(0.0, 0.0);
- assertNotNull("latLng should not be null", latLng);
- }
-
- @Test
- public void testLatitudeEmptyConstructor() {
- LatLng latLng = new LatLng();
- assertEquals("latitude default value", latLng.getLatitude(), 0, DELTA);
- }
-
- @Test
- public void testLongitudeEmptyConstructor() {
- LatLng latLng = new LatLng();
- assertEquals("longitude default value", latLng.getLongitude(), 0, DELTA);
- }
-
- @Test
- public void testAltitudeEmptyConstructor() {
- LatLng latLng1 = new LatLng();
- assertEquals("altitude default value", latLng1.getAltitude(), 0.0, DELTA);
- }
-
- @Test
- public void testLatitudeConstructor() {
- double latitude = 1.2;
- LatLng latLng = new LatLng(latitude, 3.4);
- assertEquals("latitude should match", latLng.getLatitude(), latitude, DELTA);
- }
-
- @Test
- public void testLongitudeConstructor() {
- double longitude = 3.4;
- LatLng latLng = new LatLng(1.2, longitude);
- assertEquals("longitude should match", latLng.getLongitude(), longitude, DELTA);
- }
-
- @Test
- public void testAltitudeConstructor() {
- LatLng latLng1 = new LatLng(1.2, 3.4);
- assertEquals("altitude default value", latLng1.getAltitude(), 0.0, DELTA);
-
- double altitude = 5.6;
- LatLng latLng2 = new LatLng(1.2, 3.4, altitude);
- assertEquals("altitude default value", latLng2.getAltitude(), altitude, DELTA);
- }
-
- @Test
- public void testLatitudeSetter() {
- LatLng latLng = new LatLng(1.2, 3.4);
- latLng.setLatitude(3);
- assertEquals("latitude should match", 3, latLng.getLatitude(), DELTA);
- }
-
- @Test
- public void testLongitudeSetter() {
- LatLng latLng = new LatLng(1.2, 3.4);
- latLng.setLongitude(3);
- assertEquals("longitude should match", 3, latLng.getLongitude(), DELTA);
- }
-
- @Test
- public void testAltitudeSetter() {
- LatLng latLng = new LatLng(1.2, 3.4);
- latLng.setAltitude(3);
- assertEquals("altitude should match", 3, latLng.getAltitude(), DELTA);
- }
-
- @Test
- public void testLatLngConstructor() {
- LatLng latLng1 = new LatLng(1.2, 3.4);
- LatLng latLng2 = new LatLng(latLng1);
- assertEquals("latLng should match", latLng1, latLng2);
- }
-
- @Test
- public void testDistanceTo() {
- LatLng latLng1 = new LatLng(0.0, 0.0);
- LatLng latLng2 = new LatLng(1.0, 1.0);
- assertEquals("distances should match",
- latLng1.distanceTo(latLng2),
- 157425.53710839353, DELTA);
- }
-
- @Test
- public void testDistanceToSamePoint() {
- LatLng latLng1 = new LatLng(40.71199035644531, -74.0081);
- LatLng latLng2 = new LatLng(40.71199035644531, -74.0081);
- double distance = latLng1.distanceTo(latLng2);
- assertEquals("distance should match", 0.0, distance, DELTA);
- }
-
- @Test
- public void testLocationProvider() {
- double latitude = 1.2;
- double longitude = 3.4;
- double altitude = 5.6;
-
- // Mock the location class
- Location locationMocked = mock(Location.class);
- when(locationMocked.getLatitude()).thenReturn(latitude);
- when(locationMocked.getLongitude()).thenReturn(longitude);
- when(locationMocked.getAltitude()).thenReturn(altitude);
-
- // Test the constructor
- LatLng latLng = new LatLng(locationMocked);
- assertEquals("latitude should match", latLng.getLatitude(), latitude, DELTA);
- assertEquals("longitude should match", latLng.getLongitude(), longitude, DELTA);
- assertEquals("altitude should match", latLng.getAltitude(), altitude, DELTA);
- }
-
- @Test
- public void testHashCode() {
- double latitude = 1.2;
- double longitude = 3.4;
- double altitude = 5.6;
- LatLng latLng = new LatLng(latitude, longitude, altitude);
- assertEquals("hash code should match", latLng.hashCode(), -151519232);
- }
-
- @Test
- public void testToString() {
- double latitude = 1.2;
- double longitude = 3.4;
- double altitude = 5.6;
- LatLng latLng = new LatLng(latitude, longitude, altitude);
- assertEquals("string should match",
- latLng.toString(),
- "LatLng [latitude=1.2, longitude=3.4, altitude=5.6]");
- }
-
- @Test
- public void testEqualsOther() {
- double latitude = 1.2;
- double longitude = 3.4;
- double altitude = 5.6;
- LatLng latLng1 = new LatLng(latitude, longitude, altitude);
- LatLng latLng2 = new LatLng(latitude, longitude, altitude);
- assertEquals("LatLng should match", latLng1, latLng2);
- }
-
- @Test
- public void testEqualsItself() {
- LatLng latLng = new LatLng(1, 2, 3);
- assertEquals("LatLng should match", latLng, latLng);
- }
-
- @Test
- public void testNotEquals() {
- LatLng latLng = new LatLng(1, 2);
- assertNotEquals("LatLng should match", latLng, new Object());
- }
-
- @Test
- public void testParcelable() {
- LatLng latLng = new LatLng(45.0, -185.0);
- Parcelable parcel = MockParcel.obtain(latLng);
- assertEquals("parcel should match initial object", latLng, parcel);
- }
-
- @Test
- public void testWrapped() {
- LatLng latLng = new LatLng(45.0, -185.0);
- LatLng wrapped = latLng.wrap();
- assertNotSame(latLng, wrapped);
- assertEquals("longitude wrapped value", wrapped.getLongitude(), 175.0, DELTA);
- }
-
- @Test
- public void testUnnecessaryWrapped() {
- LatLng latLng = new LatLng(45.0, 50.0);
- LatLng wrapped = latLng.wrap();
- assertNotSame(latLng, wrapped);
- assertEquals("longitude wrapped value", wrapped.getLongitude(), 50.0, DELTA);
- }
+ private static final double DELTA = 1e-15;
+
+ @Test
+ public void testSanity() {
+ LatLng latLng = new LatLng(0.0, 0.0);
+ assertNotNull("latLng should not be null", latLng);
+ }
+
+ @Test
+ public void testLatitudeEmptyConstructor() {
+ LatLng latLng = new LatLng();
+ assertEquals("latitude default value", latLng.getLatitude(), 0, DELTA);
+ }
+
+ @Test
+ public void testLongitudeEmptyConstructor() {
+ LatLng latLng = new LatLng();
+ assertEquals("longitude default value", latLng.getLongitude(), 0, DELTA);
+ }
+
+ @Test
+ public void testAltitudeEmptyConstructor() {
+ LatLng latLng1 = new LatLng();
+ assertEquals("altitude default value", latLng1.getAltitude(), 0.0, DELTA);
+ }
+
+ @Test
+ public void testLatitudeConstructor() {
+ double latitude = 1.2;
+ LatLng latLng = new LatLng(latitude, 3.4);
+ assertEquals("latitude should match", latLng.getLatitude(), latitude, DELTA);
+ }
+
+ @Test
+ public void testLongitudeConstructor() {
+ double longitude = 3.4;
+ LatLng latLng = new LatLng(1.2, longitude);
+ assertEquals("longitude should match", latLng.getLongitude(), longitude, DELTA);
+ }
+
+ @Test
+ public void testAltitudeConstructor() {
+ LatLng latLng1 = new LatLng(1.2, 3.4);
+ assertEquals("altitude default value", latLng1.getAltitude(), 0.0, DELTA);
+
+ double altitude = 5.6;
+ LatLng latLng2 = new LatLng(1.2, 3.4, altitude);
+ assertEquals("altitude default value", latLng2.getAltitude(), altitude, DELTA);
+ }
+
+ @Test
+ public void testLatitudeSetter() {
+ LatLng latLng = new LatLng(1.2, 3.4);
+ latLng.setLatitude(3);
+ assertEquals("latitude should match", 3, latLng.getLatitude(), DELTA);
+ }
+
+ @Test
+ public void testLongitudeSetter() {
+ LatLng latLng = new LatLng(1.2, 3.4);
+ latLng.setLongitude(3);
+ assertEquals("longitude should match", 3, latLng.getLongitude(), DELTA);
+ }
+
+ @Test
+ public void testAltitudeSetter() {
+ LatLng latLng = new LatLng(1.2, 3.4);
+ latLng.setAltitude(3);
+ assertEquals("altitude should match", 3, latLng.getAltitude(), DELTA);
+ }
+
+ @Test
+ public void testLatLngConstructor() {
+ LatLng latLng1 = new LatLng(1.2, 3.4);
+ LatLng latLng2 = new LatLng(latLng1);
+ assertEquals("latLng should match", latLng1, latLng2);
+ }
+
+ @Test
+ public void testDistanceTo() {
+ LatLng latLng1 = new LatLng(0.0, 0.0);
+ LatLng latLng2 = new LatLng(1.0, 1.0);
+ assertEquals("distances should match",
+ latLng1.distanceTo(latLng2),
+ 157425.53710839353, DELTA);
+ }
+
+ @Test
+ public void testDistanceToSamePoint() {
+ LatLng latLng1 = new LatLng(40.71199035644531, -74.0081);
+ LatLng latLng2 = new LatLng(40.71199035644531, -74.0081);
+ double distance = latLng1.distanceTo(latLng2);
+ assertEquals("distance should match", 0.0, distance, DELTA);
+ }
+
+ @Test
+ public void testLocationProvider() {
+ double latitude = 1.2;
+ double longitude = 3.4;
+ double altitude = 5.6;
+
+ // Mock the location class
+ Location locationMocked = mock(Location.class);
+ when(locationMocked.getLatitude()).thenReturn(latitude);
+ when(locationMocked.getLongitude()).thenReturn(longitude);
+ when(locationMocked.getAltitude()).thenReturn(altitude);
+
+ // Test the constructor
+ LatLng latLng = new LatLng(locationMocked);
+ assertEquals("latitude should match", latLng.getLatitude(), latitude, DELTA);
+ assertEquals("longitude should match", latLng.getLongitude(), longitude, DELTA);
+ assertEquals("altitude should match", latLng.getAltitude(), altitude, DELTA);
+ }
+
+ @Test
+ public void testHashCode() {
+ double latitude = 1.2;
+ double longitude = 3.4;
+ double altitude = 5.6;
+ LatLng latLng = new LatLng(latitude, longitude, altitude);
+ assertEquals("hash code should match", latLng.hashCode(), -151519232);
+ }
+
+ @Test
+ public void testToString() {
+ double latitude = 1.2;
+ double longitude = 3.4;
+ double altitude = 5.6;
+ LatLng latLng = new LatLng(latitude, longitude, altitude);
+ assertEquals("string should match",
+ latLng.toString(),
+ "LatLng [latitude=1.2, longitude=3.4, altitude=5.6]");
+ }
+
+ @Test
+ public void testEqualsOther() {
+ double latitude = 1.2;
+ double longitude = 3.4;
+ double altitude = 5.6;
+ LatLng latLng1 = new LatLng(latitude, longitude, altitude);
+ LatLng latLng2 = new LatLng(latitude, longitude, altitude);
+ assertEquals("LatLng should match", latLng1, latLng2);
+ }
+
+ @Test
+ public void testEqualsItself() {
+ LatLng latLng = new LatLng(1, 2, 3);
+ assertEquals("LatLng should match", latLng, latLng);
+ }
+
+ @Test
+ public void testNotEquals() {
+ LatLng latLng = new LatLng(1, 2);
+ assertNotEquals("LatLng should match", latLng, new Object());
+ }
+
+ @Test
+ public void testParcelable() {
+ LatLng latLng = new LatLng(45.0, -185.0);
+ Parcelable parcel = MockParcel.obtain(latLng);
+ assertEquals("parcel should match initial object", latLng, parcel);
+ }
+
+ @Test
+ public void testWrapped() {
+ LatLng latLng = new LatLng(45.0, -185.0);
+ LatLng wrapped = latLng.wrap();
+ assertNotSame(latLng, wrapped);
+ assertEquals("longitude wrapped value", wrapped.getLongitude(), 175.0, DELTA);
+ }
+
+ @Test
+ public void testUnnecessaryWrapped() {
+ LatLng latLng = new LatLng(45.0, 50.0);
+ LatLng wrapped = latLng.wrap();
+ assertNotSame(latLng, wrapped);
+ assertEquals("longitude wrapped value", wrapped.getLongitude(), 50.0, DELTA);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/ProjectedMetersTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/ProjectedMetersTest.java
index 5525684601..00fd125a1a 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/ProjectedMetersTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/ProjectedMetersTest.java
@@ -11,56 +11,56 @@ import static org.junit.Assert.assertNotNull;
public class ProjectedMetersTest {
- private static final LatLng LAT_LNG_NULL_ISLAND = new LatLng(0, 0);
+ private static final LatLng LAT_LNG_NULL_ISLAND = new LatLng(0, 0);
- @Test
- public void testSanity() {
- ProjectedMeters projectedMeters = new ProjectedMeters(0.0, 0.0);
- assertNotNull("projectedMeters should not be null", projectedMeters);
- }
+ @Test
+ public void testSanity() {
+ ProjectedMeters projectedMeters = new ProjectedMeters(0.0, 0.0);
+ assertNotNull("projectedMeters should not be null", projectedMeters);
+ }
- @Test
- public void testEquality() {
- ProjectedMeters projectedMeters = new ProjectedMeters(0.0, 0.0);
- assertEquals("projectedMeters is not equal to a LatLng", projectedMeters.equals(LAT_LNG_NULL_ISLAND), false);
- assertEquals("projectedMeters is equal to itself", projectedMeters.equals(projectedMeters), true);
- }
+ @Test
+ public void testEquality() {
+ ProjectedMeters projectedMeters = new ProjectedMeters(0.0, 0.0);
+ assertEquals("projectedMeters is not equal to a LatLng", projectedMeters.equals(LAT_LNG_NULL_ISLAND), false);
+ assertEquals("projectedMeters is equal to itself", projectedMeters.equals(projectedMeters), true);
+ }
- @Test
- public void testNorthing() {
- ProjectedMeters projectedMeters = new ProjectedMeters(1.0, 0.0);
- assertEquals("northing should be 1", 1, projectedMeters.getNorthing(), 0);
- }
+ @Test
+ public void testNorthing() {
+ ProjectedMeters projectedMeters = new ProjectedMeters(1.0, 0.0);
+ assertEquals("northing should be 1", 1, projectedMeters.getNorthing(), 0);
+ }
- @Test
- public void testEasting() {
- ProjectedMeters projectedMeters = new ProjectedMeters(0.0, 1.0);
- assertEquals("easting should be 1", 1, projectedMeters.getEasting(), 0);
- }
+ @Test
+ public void testEasting() {
+ ProjectedMeters projectedMeters = new ProjectedMeters(0.0, 1.0);
+ assertEquals("easting should be 1", 1, projectedMeters.getEasting(), 0);
+ }
- @Test
- public void testConstructor() {
- ProjectedMeters projectedMeters1 = new ProjectedMeters(1, 2);
- ProjectedMeters projectedMeters2 = new ProjectedMeters(projectedMeters1);
- assertEquals("projectedmeters should match", projectedMeters1, projectedMeters2);
- }
+ @Test
+ public void testConstructor() {
+ ProjectedMeters projectedMeters1 = new ProjectedMeters(1, 2);
+ ProjectedMeters projectedMeters2 = new ProjectedMeters(projectedMeters1);
+ assertEquals("projectedmeters should match", projectedMeters1, projectedMeters2);
+ }
- @Test
- public void testHashcode() {
- ProjectedMeters meters = new ProjectedMeters(1, 2);
- assertEquals("hashcode should match", -1048576, meters.hashCode());
- }
+ @Test
+ public void testHashcode() {
+ ProjectedMeters meters = new ProjectedMeters(1, 2);
+ assertEquals("hashcode should match", -1048576, meters.hashCode());
+ }
- @Test
- public void testToString() {
- ProjectedMeters meters = new ProjectedMeters(1, 1);
- assertEquals("toString should match", "ProjectedMeters [northing=1.0, easting=1.0]", meters.toString());
- }
+ @Test
+ public void testToString() {
+ ProjectedMeters meters = new ProjectedMeters(1, 1);
+ assertEquals("toString should match", "ProjectedMeters [northing=1.0, easting=1.0]", meters.toString());
+ }
- @Test
- public void testParcelable() {
- ProjectedMeters meters = new ProjectedMeters(1, 1);
- Parcelable parcel = MockParcel.obtain(meters);
- assertEquals("parcel should match initial object", meters, parcel);
- }
+ @Test
+ public void testParcelable() {
+ ProjectedMeters meters = new ProjectedMeters(1, 1);
+ Parcelable parcel = MockParcel.obtain(meters);
+ assertEquals("parcel should match initial object", meters, parcel);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/VisibleRegionTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/VisibleRegionTest.java
index cad268c2ba..12b779de5d 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/VisibleRegionTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/VisibleRegionTest.java
@@ -11,84 +11,85 @@ import static org.junit.Assert.assertNotNull;
public class VisibleRegionTest {
- private static final LatLng FAR_LEFT = new LatLng(52, -12);
- private static final LatLng NEAR_LEFT = new LatLng(34, -12);
- private static final LatLng FAR_RIGHT = new LatLng(52, 26);
- private static final LatLng NEAR_RIGHT = new LatLng(34, 26);
- private static final LatLngBounds BOUNDS = new LatLngBounds.Builder().include(FAR_LEFT).include(FAR_RIGHT).include(NEAR_LEFT).include(NEAR_RIGHT).build();
-
- @Test
- public void testSanity() {
- VisibleRegion region = new VisibleRegion(FAR_LEFT, FAR_RIGHT, NEAR_LEFT, NEAR_RIGHT, BOUNDS);
- assertNotNull("region should not be null", region);
- }
-
- @Test
- public void testEquality() {
- VisibleRegion region = new VisibleRegion(FAR_LEFT, FAR_RIGHT, NEAR_LEFT, NEAR_RIGHT, BOUNDS);
- assertEquals("visibleRegion is not equal to a LatLng", region.equals(FAR_LEFT), false);
- assertEquals("visibleRegion is equal to itself", region.equals(region), true);
- }
-
- @Test
- public void testFarLeftConstructor() {
- VisibleRegion region = new VisibleRegion(FAR_LEFT, FAR_RIGHT, NEAR_LEFT, NEAR_RIGHT, BOUNDS);
- assertEquals("LatLng should match", region.farLeft, FAR_LEFT);
- }
-
- @Test
- public void testNearLeftConstructor() {
- VisibleRegion region = new VisibleRegion(FAR_LEFT, FAR_RIGHT, NEAR_LEFT, NEAR_RIGHT, BOUNDS);
- assertEquals("LatLng should match", region.nearLeft, NEAR_LEFT);
- }
-
- @Test
- public void testFarRightConstructor() {
- VisibleRegion region = new VisibleRegion(FAR_LEFT, FAR_RIGHT, NEAR_LEFT, NEAR_RIGHT, BOUNDS);
- assertEquals("LatLng should match", region.farRight, FAR_RIGHT);
- }
-
- @Test
- public void testNearRightConstructor() {
- VisibleRegion region = new VisibleRegion(FAR_LEFT, FAR_RIGHT, NEAR_LEFT, NEAR_RIGHT, BOUNDS);
- assertEquals("LatLng should match", region.nearRight, NEAR_RIGHT);
- }
-
- @Test
- public void testLatLngBoundsConstructor() {
- VisibleRegion region = new VisibleRegion(FAR_LEFT, FAR_RIGHT, NEAR_LEFT, NEAR_RIGHT, BOUNDS);
- assertEquals("LatLngBounds should match", region.latLngBounds, BOUNDS);
- }
-
- @Test
- public void testEquals() {
- VisibleRegion regionLeft = new VisibleRegion(FAR_LEFT, FAR_RIGHT, NEAR_LEFT, NEAR_RIGHT, BOUNDS);
- VisibleRegion regionRight = new VisibleRegion(FAR_LEFT, FAR_RIGHT, NEAR_LEFT, NEAR_RIGHT, BOUNDS);
- assertEquals("VisibleRegions should match", regionLeft, regionRight);
- }
-
- @Test
- public void testHashcode() {
- VisibleRegion region = new VisibleRegion(FAR_LEFT, FAR_RIGHT, NEAR_LEFT, NEAR_RIGHT, BOUNDS);
- assertEquals("hashcode should match", -923534102, region.hashCode());
- }
-
- @Test
- public void testToString() {
- VisibleRegion region = new VisibleRegion(FAR_LEFT, FAR_RIGHT, NEAR_LEFT, NEAR_RIGHT, BOUNDS);
- assertEquals("string should match",
- "[farLeft [LatLng [latitude=52.0, longitude=-12.0, altitude=0.0]], " +
- "farRight [LatLng [latitude=52.0, longitude=26.0, altitude=0.0]], " +
- "nearLeft [LatLng [latitude=34.0, longitude=-12.0, altitude=0.0]], " +
- "nearRight [LatLng [latitude=34.0, longitude=26.0, altitude=0.0]], " +
- "latLngBounds [N:52.0; E:26.0; S:34.0; W:-12.0]]"
- , region.toString());
- }
-
- @Test
- public void testParcelable() {
- VisibleRegion region = new VisibleRegion(FAR_LEFT, FAR_RIGHT, NEAR_LEFT, NEAR_RIGHT, BOUNDS);
- Parcelable parcel = MockParcel.obtain(region);
- assertEquals("parcel should match initial object", region, parcel);
- }
+ private static final LatLng FAR_LEFT = new LatLng(52, -12);
+ private static final LatLng NEAR_LEFT = new LatLng(34, -12);
+ private static final LatLng FAR_RIGHT = new LatLng(52, 26);
+ private static final LatLng NEAR_RIGHT = new LatLng(34, 26);
+ private static final LatLngBounds BOUNDS =
+ new LatLngBounds.Builder().include(FAR_LEFT).include(FAR_RIGHT).include(NEAR_LEFT).include(NEAR_RIGHT).build();
+
+ @Test
+ public void testSanity() {
+ VisibleRegion region = new VisibleRegion(FAR_LEFT, FAR_RIGHT, NEAR_LEFT, NEAR_RIGHT, BOUNDS);
+ assertNotNull("region should not be null", region);
+ }
+
+ @Test
+ public void testEquality() {
+ VisibleRegion region = new VisibleRegion(FAR_LEFT, FAR_RIGHT, NEAR_LEFT, NEAR_RIGHT, BOUNDS);
+ assertEquals("visibleRegion is not equal to a LatLng", region.equals(FAR_LEFT), false);
+ assertEquals("visibleRegion is equal to itself", region.equals(region), true);
+ }
+
+ @Test
+ public void testFarLeftConstructor() {
+ VisibleRegion region = new VisibleRegion(FAR_LEFT, FAR_RIGHT, NEAR_LEFT, NEAR_RIGHT, BOUNDS);
+ assertEquals("LatLng should match", region.farLeft, FAR_LEFT);
+ }
+
+ @Test
+ public void testNearLeftConstructor() {
+ VisibleRegion region = new VisibleRegion(FAR_LEFT, FAR_RIGHT, NEAR_LEFT, NEAR_RIGHT, BOUNDS);
+ assertEquals("LatLng should match", region.nearLeft, NEAR_LEFT);
+ }
+
+ @Test
+ public void testFarRightConstructor() {
+ VisibleRegion region = new VisibleRegion(FAR_LEFT, FAR_RIGHT, NEAR_LEFT, NEAR_RIGHT, BOUNDS);
+ assertEquals("LatLng should match", region.farRight, FAR_RIGHT);
+ }
+
+ @Test
+ public void testNearRightConstructor() {
+ VisibleRegion region = new VisibleRegion(FAR_LEFT, FAR_RIGHT, NEAR_LEFT, NEAR_RIGHT, BOUNDS);
+ assertEquals("LatLng should match", region.nearRight, NEAR_RIGHT);
+ }
+
+ @Test
+ public void testLatLngBoundsConstructor() {
+ VisibleRegion region = new VisibleRegion(FAR_LEFT, FAR_RIGHT, NEAR_LEFT, NEAR_RIGHT, BOUNDS);
+ assertEquals("LatLngBounds should match", region.latLngBounds, BOUNDS);
+ }
+
+ @Test
+ public void testEquals() {
+ VisibleRegion regionLeft = new VisibleRegion(FAR_LEFT, FAR_RIGHT, NEAR_LEFT, NEAR_RIGHT, BOUNDS);
+ VisibleRegion regionRight = new VisibleRegion(FAR_LEFT, FAR_RIGHT, NEAR_LEFT, NEAR_RIGHT, BOUNDS);
+ assertEquals("VisibleRegions should match", regionLeft, regionRight);
+ }
+
+ @Test
+ public void testHashcode() {
+ VisibleRegion region = new VisibleRegion(FAR_LEFT, FAR_RIGHT, NEAR_LEFT, NEAR_RIGHT, BOUNDS);
+ assertEquals("hashcode should match", -923534102, region.hashCode());
+ }
+
+ @Test
+ public void testToString() {
+ VisibleRegion region = new VisibleRegion(FAR_LEFT, FAR_RIGHT, NEAR_LEFT, NEAR_RIGHT, BOUNDS);
+ assertEquals("string should match",
+ "[farLeft [LatLng [latitude=52.0, longitude=-12.0, altitude=0.0]], "
+ + "farRight [LatLng [latitude=52.0, longitude=26.0, altitude=0.0]], "
+ + "nearLeft [LatLng [latitude=34.0, longitude=-12.0, altitude=0.0]], "
+ + "nearRight [LatLng [latitude=34.0, longitude=26.0, altitude=0.0]], "
+ + "latLngBounds [N:52.0; E:26.0; S:34.0; W:-12.0]]",
+ region.toString());
+ }
+
+ @Test
+ public void testParcelable() {
+ VisibleRegion region = new VisibleRegion(FAR_LEFT, FAR_RIGHT, NEAR_LEFT, NEAR_RIGHT, BOUNDS);
+ Parcelable parcel = MockParcel.obtain(region);
+ assertEquals("parcel should match initial object", region, parcel);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapOptionsTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapOptionsTest.java
index dbde9a4420..ce0cb00b0b 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapOptionsTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapOptionsTest.java
@@ -7,7 +7,6 @@ import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.geometry.LatLng;
-import com.mapbox.mapboxsdk.utils.MockParcel;
import org.junit.Test;
@@ -22,174 +21,170 @@ import static org.junit.Assert.assertTrue;
public class MapboxMapOptionsTest {
- @Test
- public void testSanity() {
- assertNotNull("should not be null", new MapboxMapOptions());
- }
-
- @Test
- public void testDebugEnabled() {
- assertFalse(new MapboxMapOptions().getDebugActive());
- assertTrue(new MapboxMapOptions().debugActive(true).getDebugActive());
- assertFalse(new MapboxMapOptions().debugActive(false).getDebugActive());
- }
-
- @Test
- public void testCompassEnabled() {
- assertTrue(new MapboxMapOptions().compassEnabled(true).getCompassEnabled());
- assertFalse(new MapboxMapOptions().compassEnabled(false).getCompassEnabled());
- }
-
- @Test
- public void testCompassGravity() {
- assertEquals(Gravity.TOP | Gravity.END, new MapboxMapOptions().getCompassGravity());
- assertEquals(Gravity.BOTTOM, new MapboxMapOptions().compassGravity(Gravity.BOTTOM).getCompassGravity());
- assertNotEquals(Gravity.START, new MapboxMapOptions().compassGravity(Gravity.BOTTOM).getCompassGravity());
- }
-
- @Test
- public void testCompassMargins() {
- assertTrue(Arrays.equals(new int[]{0, 1, 2, 3}, new MapboxMapOptions().compassMargins(new int[]{0, 1, 2, 3}).getCompassMargins()));
- assertFalse(Arrays.equals(new int[]{0, 1, 2, 3}, new MapboxMapOptions().compassMargins(new int[]{0, 0, 0, 0}).getCompassMargins()));
- }
-
- @Test
- public void testLogoEnabled() {
- assertTrue(new MapboxMapOptions().logoEnabled(true).getLogoEnabled());
- assertFalse(new MapboxMapOptions().logoEnabled(false).getLogoEnabled());
- }
-
- @Test
- public void testLogoGravity() {
- assertEquals(Gravity.BOTTOM | Gravity.START, new MapboxMapOptions().getLogoGravity());
- assertEquals(Gravity.BOTTOM, new MapboxMapOptions().logoGravity(Gravity.BOTTOM).getLogoGravity());
- assertNotEquals(Gravity.START, new MapboxMapOptions().logoGravity(Gravity.BOTTOM).getLogoGravity());
- }
-
- @Test
- public void testLogoMargins() {
- assertTrue(Arrays.equals(new int[]{0, 1, 2, 3}, new MapboxMapOptions().logoMargins(new int[]{0, 1, 2, 3}).getLogoMargins()));
- assertFalse(Arrays.equals(new int[]{0, 1, 2, 3}, new MapboxMapOptions().logoMargins(new int[]{0, 0, 0, 0}).getLogoMargins()));
- }
-
- @Test
- public void testAttributionTintColor() {
- assertEquals(-1, new MapboxMapOptions().getAttributionTintColor());
- assertEquals(Color.RED, new MapboxMapOptions().attributionTintColor(Color.RED).getAttributionTintColor());
- }
-
- @Test
- public void testAttributionEnabled() {
- assertTrue(new MapboxMapOptions().attributionEnabled(true).getAttributionEnabled());
- assertFalse(new MapboxMapOptions().attributionEnabled(false).getAttributionEnabled());
- }
-
- @Test
- public void testAttributionGravity() {
- assertEquals(Gravity.BOTTOM, new MapboxMapOptions().getAttributionGravity());
- assertEquals(Gravity.BOTTOM, new MapboxMapOptions().attributionGravity(Gravity.BOTTOM).getAttributionGravity());
- assertNotEquals(Gravity.START, new MapboxMapOptions().attributionGravity(Gravity.BOTTOM).getAttributionGravity());
- }
-
- @Test
- public void testAttributionMargins() {
- assertTrue(Arrays.equals(new int[]{0, 1, 2, 3}, new MapboxMapOptions().attributionMargins(new int[]{0, 1, 2, 3}).getAttributionMargins()));
- assertFalse(Arrays.equals(new int[]{0, 1, 2, 3}, new MapboxMapOptions().attributionMargins(new int[]{0, 0, 0, 0}).getAttributionMargins()));
- }
-
- @Test
- public void testMinZoom() {
- assertEquals(MapboxConstants.MINIMUM_ZOOM, new MapboxMapOptions().getMinZoom());
- assertEquals(5.0f, new MapboxMapOptions().minZoom(5.0f).getMinZoom());
- assertNotEquals(2.0f, new MapboxMapOptions().minZoom(5.0f).getMinZoom());
- }
-
- @Test
- public void testMaxZoom() {
- assertEquals(MapboxConstants.MAXIMUM_ZOOM, new MapboxMapOptions().getMaxZoom());
- assertEquals(5.0f, new MapboxMapOptions().maxZoom(5.0f).getMaxZoom());
- assertNotEquals(2.0f, new MapboxMapOptions().maxZoom(5.0f).getMaxZoom());
- }
-
- @Test
- public void testLocationEnabled() {
- assertFalse(new MapboxMapOptions().getLocationEnabled());
- assertTrue(new MapboxMapOptions().locationEnabled(true).getLocationEnabled());
- assertFalse(new MapboxMapOptions().locationEnabled(false).getLocationEnabled());
- }
-
- @Test
- public void testTiltGesturesEnabled() {
- assertTrue(new MapboxMapOptions().getTiltGesturesEnabled());
- assertTrue(new MapboxMapOptions().tiltGesturesEnabled(true).getTiltGesturesEnabled());
- assertFalse(new MapboxMapOptions().tiltGesturesEnabled(false).getTiltGesturesEnabled());
- }
-
- @Test
- public void testScrollGesturesEnabled() {
- assertTrue(new MapboxMapOptions().getScrollGesturesEnabled());
- assertTrue(new MapboxMapOptions().scrollGesturesEnabled(true).getScrollGesturesEnabled());
- assertFalse(new MapboxMapOptions().scrollGesturesEnabled(false).getScrollGesturesEnabled());
- }
-
- @Test
- public void testZoomGesturesEnabled() {
- assertTrue(new MapboxMapOptions().getZoomGesturesEnabled());
- assertTrue(new MapboxMapOptions().zoomGesturesEnabled(true).getZoomGesturesEnabled());
- assertFalse(new MapboxMapOptions().zoomGesturesEnabled(false).getZoomGesturesEnabled());
- }
-
- @Test
- public void testRotateGesturesEnabled() {
- assertTrue(new MapboxMapOptions().getRotateGesturesEnabled());
- assertTrue(new MapboxMapOptions().rotateGesturesEnabled(true).getRotateGesturesEnabled());
- assertFalse(new MapboxMapOptions().rotateGesturesEnabled(false).getRotateGesturesEnabled());
- }
-
- @Test
- public void testZoomControlsEnabled() {
- assertFalse(new MapboxMapOptions().getZoomControlsEnabled());
- assertTrue(new MapboxMapOptions().zoomControlsEnabled(true).getZoomControlsEnabled());
- assertFalse(new MapboxMapOptions().zoomControlsEnabled(false).getZoomControlsEnabled());
- }
-
- @Test
- public void testStyleUrl() {
- assertEquals(Style.DARK, new MapboxMapOptions().styleUrl(Style.DARK).getStyle());
- assertNotEquals(Style.LIGHT, new MapboxMapOptions().styleUrl(Style.DARK).getStyle());
- assertNull(new MapboxMapOptions().getStyle());
- }
-
- @Test
- public void testCamera() {
- CameraPosition position = new CameraPosition.Builder().build();
- assertEquals(new CameraPosition.Builder(position).build(), new MapboxMapOptions().camera(position).getCamera());
- assertNotEquals(new CameraPosition.Builder().target(new LatLng(1, 1)), new MapboxMapOptions().camera(position));
- assertNull(new MapboxMapOptions().getCamera());
- }
-
- @Test
- public void testMyLocationForegroundTint() {
- assertEquals(Color.BLUE, new MapboxMapOptions().myLocationForegroundTintColor(Color.BLUE).getMyLocationForegroundTintColor());
- }
-
- @Test
- public void testMyLocationBackgroundTint() {
- assertEquals(Color.BLUE, new MapboxMapOptions().myLocationBackgroundTintColor(Color.BLUE).getMyLocationBackgroundTintColor());
- }
-
- @Test
- public void testParceable() {
- MapboxMapOptions options = new MapboxMapOptions().camera(new CameraPosition.Builder().build()).styleUrl("s").accessToken("a").debugActive(true).compassMargins(new int[]{0, 1, 2, 3});
- MapboxMapOptions parceled = (MapboxMapOptions) MockParcel.obtain(options);
- assertEquals(options, parceled);
- }
-
- @Test
- public void testAccessToken() {
- assertNull(new MapboxMapOptions().getAccessToken());
- assertEquals("test", new MapboxMapOptions().accessToken("test").getAccessToken());
- assertNotEquals("nottest", new MapboxMapOptions().accessToken("test").getStyle());
- }
+ private static final double DELTA = 1e-15;
+
+ @Test
+ public void testSanity() {
+ assertNotNull("should not be null", new MapboxMapOptions());
+ }
+
+ @Test
+ public void testDebugEnabled() {
+ assertFalse(new MapboxMapOptions().getDebugActive());
+ assertTrue(new MapboxMapOptions().debugActive(true).getDebugActive());
+ assertFalse(new MapboxMapOptions().debugActive(false).getDebugActive());
+ }
+
+ @Test
+ public void testCompassEnabled() {
+ assertTrue(new MapboxMapOptions().compassEnabled(true).getCompassEnabled());
+ assertFalse(new MapboxMapOptions().compassEnabled(false).getCompassEnabled());
+ }
+
+ @Test
+ public void testCompassGravity() {
+ assertEquals(Gravity.TOP | Gravity.END, new MapboxMapOptions().getCompassGravity());
+ assertEquals(Gravity.BOTTOM, new MapboxMapOptions().compassGravity(Gravity.BOTTOM).getCompassGravity());
+ assertNotEquals(Gravity.START, new MapboxMapOptions().compassGravity(Gravity.BOTTOM).getCompassGravity());
+ }
+
+ @Test
+ public void testCompassMargins() {
+ assertTrue(Arrays.equals(new int[] {0, 1, 2, 3}, new MapboxMapOptions().compassMargins(
+ new int[] {0, 1, 2, 3}).getCompassMargins()));
+ assertFalse(Arrays.equals(new int[] {0, 1, 2, 3}, new MapboxMapOptions().compassMargins(
+ new int[] {0, 0, 0, 0}).getCompassMargins()));
+ }
+
+ @Test
+ public void testLogoEnabled() {
+ assertTrue(new MapboxMapOptions().logoEnabled(true).getLogoEnabled());
+ assertFalse(new MapboxMapOptions().logoEnabled(false).getLogoEnabled());
+ }
+
+ @Test
+ public void testLogoGravity() {
+ assertEquals(Gravity.BOTTOM | Gravity.START, new MapboxMapOptions().getLogoGravity());
+ assertEquals(Gravity.BOTTOM, new MapboxMapOptions().logoGravity(Gravity.BOTTOM).getLogoGravity());
+ assertNotEquals(Gravity.START, new MapboxMapOptions().logoGravity(Gravity.BOTTOM).getLogoGravity());
+ }
+
+ @Test
+ public void testLogoMargins() {
+ assertTrue(Arrays.equals(new int[] {0, 1, 2, 3}, new MapboxMapOptions().logoMargins(
+ new int[] {0, 1, 2, 3}).getLogoMargins()));
+ assertFalse(Arrays.equals(new int[] {0, 1, 2, 3}, new MapboxMapOptions().logoMargins(
+ new int[] {0, 0, 0, 0}).getLogoMargins()));
+ }
+
+ @Test
+ public void testAttributionTintColor() {
+ assertEquals(-1, new MapboxMapOptions().getAttributionTintColor());
+ assertEquals(Color.RED, new MapboxMapOptions().attributionTintColor(Color.RED).getAttributionTintColor());
+ }
+
+ @Test
+ public void testAttributionEnabled() {
+ assertTrue(new MapboxMapOptions().attributionEnabled(true).getAttributionEnabled());
+ assertFalse(new MapboxMapOptions().attributionEnabled(false).getAttributionEnabled());
+ }
+
+ @Test
+ public void testAttributionGravity() {
+ assertEquals(Gravity.BOTTOM, new MapboxMapOptions().getAttributionGravity());
+ assertEquals(Gravity.BOTTOM, new MapboxMapOptions().attributionGravity(Gravity.BOTTOM).getAttributionGravity());
+ assertNotEquals(Gravity.START, new MapboxMapOptions().attributionGravity(Gravity.BOTTOM).getAttributionGravity());
+ }
+
+ @Test
+ public void testAttributionMargins() {
+ assertTrue(Arrays.equals(new int[] {0, 1, 2, 3}, new MapboxMapOptions().attributionMargins(
+ new int[] {0, 1, 2, 3}).getAttributionMargins()));
+ assertFalse(Arrays.equals(new int[] {0, 1, 2, 3}, new MapboxMapOptions().attributionMargins(
+ new int[] {0, 0, 0, 0}).getAttributionMargins()));
+ }
+
+ @Test
+ public void testMinZoom() {
+ assertEquals(MapboxConstants.MINIMUM_ZOOM, new MapboxMapOptions().getMinZoomPreference(), DELTA);
+ assertEquals(5.0f, new MapboxMapOptions().minZoomPreference(5.0f).getMinZoomPreference(), DELTA);
+ assertNotEquals(2.0f, new MapboxMapOptions().minZoomPreference(5.0f).getMinZoomPreference(), DELTA);
+ }
+
+ @Test
+ public void testMaxZoom() {
+ assertEquals(MapboxConstants.MAXIMUM_ZOOM, new MapboxMapOptions().getMaxZoomPreference(), DELTA);
+ assertEquals(5.0f, new MapboxMapOptions().maxZoomPreference(5.0f).getMaxZoomPreference(), DELTA);
+ assertNotEquals(2.0f, new MapboxMapOptions().maxZoomPreference(5.0f).getMaxZoomPreference(), DELTA);
+ }
+
+ @Test
+ public void testLocationEnabled() {
+ assertFalse(new MapboxMapOptions().getLocationEnabled());
+ assertTrue(new MapboxMapOptions().locationEnabled(true).getLocationEnabled());
+ assertFalse(new MapboxMapOptions().locationEnabled(false).getLocationEnabled());
+ }
+
+ @Test
+ public void testTiltGesturesEnabled() {
+ assertTrue(new MapboxMapOptions().getTiltGesturesEnabled());
+ assertTrue(new MapboxMapOptions().tiltGesturesEnabled(true).getTiltGesturesEnabled());
+ assertFalse(new MapboxMapOptions().tiltGesturesEnabled(false).getTiltGesturesEnabled());
+ }
+
+ @Test
+ public void testScrollGesturesEnabled() {
+ assertTrue(new MapboxMapOptions().getScrollGesturesEnabled());
+ assertTrue(new MapboxMapOptions().scrollGesturesEnabled(true).getScrollGesturesEnabled());
+ assertFalse(new MapboxMapOptions().scrollGesturesEnabled(false).getScrollGesturesEnabled());
+ }
+
+ @Test
+ public void testZoomGesturesEnabled() {
+ assertTrue(new MapboxMapOptions().getZoomGesturesEnabled());
+ assertTrue(new MapboxMapOptions().zoomGesturesEnabled(true).getZoomGesturesEnabled());
+ assertFalse(new MapboxMapOptions().zoomGesturesEnabled(false).getZoomGesturesEnabled());
+ }
+
+ @Test
+ public void testRotateGesturesEnabled() {
+ assertTrue(new MapboxMapOptions().getRotateGesturesEnabled());
+ assertTrue(new MapboxMapOptions().rotateGesturesEnabled(true).getRotateGesturesEnabled());
+ assertFalse(new MapboxMapOptions().rotateGesturesEnabled(false).getRotateGesturesEnabled());
+ }
+
+ @Test
+ public void testZoomControlsEnabled() {
+ assertFalse(new MapboxMapOptions().getZoomControlsEnabled());
+ assertTrue(new MapboxMapOptions().zoomControlsEnabled(true).getZoomControlsEnabled());
+ assertFalse(new MapboxMapOptions().zoomControlsEnabled(false).getZoomControlsEnabled());
+ }
+
+ @Test
+ public void testStyleUrl() {
+ assertEquals(Style.DARK, new MapboxMapOptions().styleUrl(Style.DARK).getStyle());
+ assertNotEquals(Style.LIGHT, new MapboxMapOptions().styleUrl(Style.DARK).getStyle());
+ assertNull(new MapboxMapOptions().getStyle());
+ }
+
+ @Test
+ public void testCamera() {
+ CameraPosition position = new CameraPosition.Builder().build();
+ assertEquals(new CameraPosition.Builder(position).build(), new MapboxMapOptions().camera(position).getCamera());
+ assertNotEquals(new CameraPosition.Builder().target(new LatLng(1, 1)), new MapboxMapOptions().camera(position));
+ assertNull(new MapboxMapOptions().getCamera());
+ }
+
+ @Test
+ public void testMyLocationForegroundTint() {
+ assertEquals(Color.BLUE, new MapboxMapOptions()
+ .myLocationForegroundTintColor(Color.BLUE).getMyLocationForegroundTintColor());
+ }
+
+ @Test
+ public void testMyLocationBackgroundTint() {
+ assertEquals(Color.BLUE, new MapboxMapOptions()
+ .myLocationBackgroundTintColor(Color.BLUE).getMyLocationBackgroundTintColor());
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapTest.java
deleted file mode 100644
index 9d0a1c0ad7..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/MapboxMapTest.java
+++ /dev/null
@@ -1,868 +0,0 @@
-package com.mapbox.mapboxsdk.maps;
-
-import android.graphics.Color;
-import android.graphics.Point;
-import android.graphics.PointF;
-
-import com.mapbox.mapboxsdk.annotations.BaseMarkerOptions;
-import com.mapbox.mapboxsdk.annotations.Marker;
-import com.mapbox.mapboxsdk.annotations.MarkerOptions;
-import com.mapbox.mapboxsdk.annotations.Polygon;
-import com.mapbox.mapboxsdk.annotations.PolygonOptions;
-import com.mapbox.mapboxsdk.annotations.Polyline;
-import com.mapbox.mapboxsdk.annotations.PolylineOptions;
-import com.mapbox.mapboxsdk.camera.CameraPosition;
-import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
-import com.mapbox.mapboxsdk.exceptions.InvalidMarkerPositionException;
-import com.mapbox.mapboxsdk.geometry.LatLng;
-import com.mapbox.mapboxsdk.geometry.LatLngBounds;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class MapboxMapTest {
-
- private MapboxMap mMapboxMap;
-
- @InjectMocks
- MapView mMapView = mock(MapView.class);
-
- @Mock
- MapboxMap.OnMarkerClickListener mOnMarkerClickListener;
-
- @Mock
- MapboxMap.OnCameraChangeListener mOnCameraChangeListener;
-
- @Mock
- MapboxMap.InfoWindowAdapter mInfoWindowAdapter;
-
- @Mock
- MapboxMap.OnScrollListener mScrollListener;
-
- @Mock
- MapboxMap.OnFlingListener mFlingListener;
-
- @Mock
- MapboxMap.OnFpsChangedListener mFpsChangedListener;
-
- @Mock
- MapboxMap.OnInfoWindowClickListener mWindowClickListener;
-
- @Mock
- MapboxMap.OnInfoWindowCloseListener mWindowCloseListener;
-
- @Mock
- MapboxMap.OnInfoWindowLongClickListener mWindowLongClickListener;
-
- @Mock
- MapboxMap.OnMyLocationChangeListener mLocationChangeListener;
-
- @Mock
- MapboxMap.OnMyLocationTrackingModeChangeListener mMyLocationTrackingModeChangeListener;
-
- @Mock
- MapboxMap.OnMyBearingTrackingModeChangeListener mMyBearingTrackingModeChangeListener;
-
- @Before
- public void beforeTest() {
- MockitoAnnotations.initMocks(this);
- mMapboxMap = new MapboxMap(mMapView);
- }
-
- @Test
- public void testSanity() {
- assertNotNull("mMapboxMap should not be null", mMapboxMap);
- }
-
- @Test
- public void testMock() {
- assertNotNull("mMapView should be mocked", mMapView);
- }
-
- @Test
- public void testGetMapView() {
- assertNotNull("MapView should be non null", mMapboxMap.getMapView());
- }
-
- //
- // UiSettings
- //
-
- @Test
- public void testUiSettings() {
- assertNotNull("UiSettings should not be null", mMapboxMap.getUiSettings());
- }
-
- //
- // MinZoomLevel
- //
-
- @Test
- public void testMinZoom() {
- double zoom = 10;
- mMapboxMap.setMinZoom(zoom);
- assertEquals("MinZoom should match", zoom, mMapboxMap.getMinZoom(), 0);
- }
-
- @Test
- public void testMaxZoom() {
- double zoom = 10;
- mMapboxMap.setMaxZoom(zoom);
- assertEquals("MaxZoom should match", zoom, mMapboxMap.getMaxZoom(), 0);
- }
-
- @Test
- public void testInitialZoomLevels() {
- assertEquals("MaxZoom should match", 0, mMapboxMap.getMaxZoom(), 0);
- assertEquals("MinZoom should match", 0, mMapboxMap.getMinZoom(), 0);
- }
-
- //
- // TrackingSettings
- //
-
- @Test
- public void testTrackingSettings() {
- assertNotNull("TrackingSettings should not be null", mMapboxMap.getTrackingSettings());
- }
-
- //
- // Projection
- //
-
- @Test
- public void testProjection() {
- assertNotNull("Projection should not be null", mMapboxMap.getProjection());
- }
-
- //
- // InfoWindow
- //
-
- @Test
- public void testConcurrentInfoWindowEnabled() {
- mMapboxMap.setAllowConcurrentMultipleOpenInfoWindows(true);
- assertTrue("ConcurrentWindows should be true", mMapboxMap.isAllowConcurrentMultipleOpenInfoWindows());
- }
-
- @Test
- public void testConcurrentInfoWindowDisabled() {
- mMapboxMap.setAllowConcurrentMultipleOpenInfoWindows(false);
- assertFalse("ConcurrentWindows should be false", mMapboxMap.isAllowConcurrentMultipleOpenInfoWindows());
- }
-
- @Test
- public void testInfoWindowAdapter() {
- mMapboxMap.setInfoWindowAdapter(mInfoWindowAdapter);
- assertEquals("InfoWindowAdpter should be the same", mInfoWindowAdapter, mMapboxMap.getInfoWindowAdapter());
- }
-
- //
- // Location
- //
-
- @Test
- public void testMyLocationEnabled() {
- when(mMapView.isPermissionsAccepted()).thenReturn(true);
- mMapboxMap.setMyLocationEnabled(true);
- assertTrue("MyLocationEnabled should be true", mMapboxMap.isMyLocationEnabled());
-
- }
-
- @Test
- public void testMyLocationDisabled() {
- when(mMapView.isPermissionsAccepted()).thenReturn(true);
- mMapboxMap.setMyLocationEnabled(false);
- assertFalse("MyLocationEnabled should be false", mMapboxMap.isMyLocationEnabled());
- }
-
- //
- // padding
- //
-
- @Test
- public void testPadding() {
- mMapboxMap.setOnCameraChangeListener(mOnCameraChangeListener);
- CameraPosition position = new CameraPosition.Builder().bearing(1).tilt(2).zoom(3).target(new LatLng(4, 5)).build();
- mMapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(position));
- mMapboxMap.setPadding(0, 0, 0, 0);
- verify(mOnCameraChangeListener, times(1)).onCameraChange(position);
- }
-
- //
- // setters/getters interfaces
- //
-
- @Test
- public void testScrollListener() {
- mMapboxMap.setOnScrollListener(mScrollListener);
- assertEquals("ScrollListener should match", mScrollListener, mMapboxMap.getOnScrollListener());
- }
-
- @Test
- public void testFlingListener() {
- mMapboxMap.setOnFlingListener(mFlingListener);
- assertEquals("FlingListener should match", mFlingListener, mMapboxMap.getOnFlingListener());
- }
-
- @Test
- public void testFpsListener() {
- mMapboxMap.setOnFpsChangedListener(mFpsChangedListener);
- assertEquals("FpsListener should match", mFpsChangedListener, mMapboxMap.getOnFpsChangedListener());
- }
-
- @Test
- public void testInfoWindowClickListener() {
- mMapboxMap.setOnInfoWindowClickListener(mWindowClickListener);
- assertEquals("InfoWidowClickListener should match", mWindowClickListener, mMapboxMap.getOnInfoWindowClickListener());
- }
-
- @Test
- public void testInfoWindowCloseListener() {
- mMapboxMap.setOnInfoWindowCloseListener(mWindowCloseListener);
- assertEquals("InfoWindowCloseListener should match", mWindowCloseListener, mMapboxMap.getOnInfoWindowCloseListener());
- }
-
- @Test
- public void testInfoWindowLongClickListener() {
- mMapboxMap.setOnInfoWindowLongClickListener(mWindowLongClickListener);
- assertEquals("InfoWindowLongClickListener should match", mWindowLongClickListener, mMapboxMap.getOnInfoWindowLongClickListener());
- }
-
- @Test
- public void testOnBearingTrackingModeChangeListener() {
- mMapboxMap.setOnMyBearingTrackingModeChangeListener(mMyBearingTrackingModeChangeListener);
- assertEquals("MyBearingTrackingChangeListerner should match", mMyBearingTrackingModeChangeListener, mMapboxMap.getOnMyBearingTrackingModeChangeListener());
- }
-
- @Test
- public void testOnLocationTrackingModeChangeListener() {
- mMapboxMap.setOnMyLocationTrackingModeChangeListener(mMyLocationTrackingModeChangeListener);
- assertEquals("MyLocationTrackigChangeListener should match", mMyLocationTrackingModeChangeListener, mMapboxMap.getOnMyLocationTrackingModeChangeListener());
- }
-
- //
- // CameraPosition
- //
-
- @Test
- public void testCameraPosition() {
- CameraPosition position = new CameraPosition.Builder().bearing(1).tilt(2).zoom(3).target(new LatLng(4, 5)).build();
- mMapboxMap.setCameraPosition(position);
- assertEquals("CameraPosition should be same", position, mMapboxMap.getCameraPosition());
- }
-
- //
- // Camera - moveCamera
- //
-
- @Test
- public void testNewCameraPositionMoveCamera() {
- CameraPosition position = new CameraPosition.Builder().bearing(1).tilt(2).zoom(3).target(new LatLng(4, 5)).build();
- mMapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(position));
- assertEquals("CameraPosition should be same", position, mMapboxMap.getCameraPosition());
- }
-
- //
- // Camera - animateCamera
- //
-
- @Test
- public void testNewCameraPositionAnimateCamera() {
- CameraPosition position = new CameraPosition.Builder().bearing(1).tilt(2).zoom(3).target(new LatLng(4, 5)).build();
- mMapboxMap.animateCamera(CameraUpdateFactory.newCameraPosition(position));
- assertEquals("CameraPosition should be same", position, mMapboxMap.getCameraPosition());
- }
-
- @Test
- public void testNewCameraPositionAnimateCameraWithCallbackParameter() {
- CameraPosition position = new CameraPosition.Builder().bearing(1).tilt(2).zoom(3).target(new LatLng(4, 5)).build();
- mMapboxMap.animateCamera(CameraUpdateFactory.newCameraPosition(position), null);
- assertEquals("CameraPosition should be same", position, mMapboxMap.getCameraPosition());
- }
-
- @Test
- public void testNewCameraPositionAnimateCameraWithDurationParameter() {
- CameraPosition position = new CameraPosition.Builder().bearing(1).tilt(2).zoom(3).target(new LatLng(4, 5)).build();
- mMapboxMap.animateCamera(CameraUpdateFactory.newCameraPosition(position), 0);
- assertEquals("CameraPosition should be same", position, mMapboxMap.getCameraPosition());
- }
-
- @Test
- public void testNewCameraPositionAnimateCameraWithDurationAndCallbackParameter() {
- CameraPosition position = new CameraPosition.Builder().bearing(1).tilt(2).zoom(3).target(new LatLng(4, 5)).build();
- mMapboxMap.animateCamera(CameraUpdateFactory.newCameraPosition(position), 0, null);
- assertEquals("CameraPosition should be same", position, mMapboxMap.getCameraPosition());
- }
-
- //
- // Camera - easeCamera
- //
-
- @Test
- public void testNewCameraPositionEaseCamera() {
- CameraPosition position = new CameraPosition.Builder().bearing(1).tilt(2).zoom(3).target(new LatLng(4, 5)).build();
- mMapboxMap.easeCamera(CameraUpdateFactory.newCameraPosition(position));
- assertEquals("CameraPosition should be same", position, mMapboxMap.getCameraPosition());
- }
-
- @Test
- public void testNewCameraPositionEaseCameraWithCallbackParameter() {
- CameraPosition position = new CameraPosition.Builder().bearing(1).tilt(2).zoom(3).target(new LatLng(4, 5)).build();
- mMapboxMap.easeCamera(CameraUpdateFactory.newCameraPosition(position), 1000, null);
- assertEquals("CameraPosition should be same", position, mMapboxMap.getCameraPosition());
- }
-
- //
- // Camera - LatLng
- //
-
- @Test
- public void testLatLngMoveCamera() {
- mMapboxMap.moveCamera(CameraUpdateFactory.newLatLng(new LatLng(4, 5)));
- assertEquals("LatLng should be same", new LatLng(4, 5), mMapboxMap.getCameraPosition().target);
- }
-
- @Test
- public void testLatLngAnimateCamera() {
- mMapboxMap.animateCamera(CameraUpdateFactory.newLatLng(new LatLng(4, 5)));
- assertEquals("LatLng should be same", new LatLng(4, 5), mMapboxMap.getCameraPosition().target);
- }
-
- @Test
- public void testLatLngEaseCamera() {
- mMapboxMap.easeCamera(CameraUpdateFactory.newLatLng(new LatLng(4, 5)), 1000);
- assertEquals("LatLng should be same", new LatLng(4, 5), mMapboxMap.getCameraPosition().target);
- }
-
- //
- // Camera - LatLngZoom
- //
-
- @Test
- public void testLatLngZoomMoveCamera() {
- mMapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(4, 5), 10));
- assertEquals("LatLng should be same", new LatLng(4, 5), mMapboxMap.getCameraPosition().target);
- assertTrue("Zoomlevel should be same", 10 == mMapboxMap.getCameraPosition().zoom);
- }
-
- @Test
- public void testLatLngZoomAnimateCamera() {
- mMapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(4, 5), 10));
- assertEquals("LatLng should be same", new LatLng(4, 5), mMapboxMap.getCameraPosition().target);
- assertTrue("Zoomlevel should be same", 10 == mMapboxMap.getCameraPosition().zoom);
- }
-
- @Test
- public void testLatLngZoomEaseCamera() {
- mMapboxMap.easeCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(4, 5), 10), 1000);
- assertEquals("LatLng should be same", new LatLng(4, 5), mMapboxMap.getCameraPosition().target);
- assertTrue("Zoomlevel should be same", 10 == mMapboxMap.getCameraPosition().zoom);
- }
-
- //
- // Camera - LatLngBounds
- //
- @Test
- public void testLatLngBounds() {
- LatLng la = new LatLng(34.053940, -118.242622);
- LatLng ny = new LatLng(40.712730, -74.005953);
- LatLng centroid = new LatLng(
- (la.getLatitude() + ny.getLatitude()) / 2,
- (la.getLongitude() + ny.getLongitude()) / 2);
-
- Projection projection = mock(Projection.class);
- when(projection.toScreenLocation(la)).thenReturn(new PointF(20, 20));
- when(projection.toScreenLocation(ny)).thenReturn(new PointF(100, 100));
- when(projection.fromScreenLocation(any(PointF.class))).thenReturn(centroid);
-
- UiSettings uiSettings = mock(UiSettings.class);
- when(uiSettings.getHeight()).thenReturn(1000f);
-
- mMapboxMap.setProjection(projection);
- mMapboxMap.setUiSettings(uiSettings);
-
- LatLngBounds bounds = new LatLngBounds.Builder().include(la).include(ny).build();
- mMapboxMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 1));
-
- assertEquals("LatLng should be same", centroid, mMapboxMap.getCameraPosition().target);
- }
-
-
- //
- // CameraPositionUpdate - NPX target
- //
- @Test
- public void testCamerePositionUpdateNullTarget() {
- LatLng latLng = new LatLng(1, 1);
- mMapboxMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
- mMapboxMap.moveCamera(CameraUpdateFactory.newLatLng(null));
- assertEquals("LatLng should be same", latLng, mMapboxMap.getCameraPosition().target);
- }
-
- //
- // Camera - ScrollBy
- //
- @Test
- public void testScrollBy() {
- LatLng latLng = new LatLng(1, 1);
- mMapboxMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
- mMapboxMap.moveCamera(CameraUpdateFactory.scrollBy(0, 0));
- assertEquals("LatLng should be same", latLng, mMapboxMap.getCameraPosition().target);
- mMapboxMap.moveCamera(CameraUpdateFactory.scrollBy(12, 12));
- }
-
- //
- // Camera - Zoom
- //
-
- @Test
- public void testZoomInMoveCamera() {
- CameraPosition position = new CameraPosition.Builder().bearing(1).tilt(2).zoom(3).target(new LatLng(4, 5)).build();
- mMapboxMap.setCameraPosition(position);
- mMapboxMap.moveCamera(CameraUpdateFactory.zoomIn());
- assertTrue("Zoomlevel should be same", 4 == mMapboxMap.getCameraPosition().zoom);
- }
-
- @Test
- public void testZoomOutMoveCamera() {
- CameraPosition position = new CameraPosition.Builder().bearing(1).tilt(2).zoom(3).target(new LatLng(4, 5)).build();
- mMapboxMap.setCameraPosition(position);
- mMapboxMap.moveCamera(CameraUpdateFactory.zoomOut());
- assertTrue("Zoomlevel should be same", 2 == mMapboxMap.getCameraPosition().zoom);
- }
-
- @Test
- public void testZoomByMoveCamera() {
- CameraPosition position = new CameraPosition.Builder().bearing(1).tilt(2).zoom(3).target(new LatLng(4, 5)).build();
- mMapboxMap.setCameraPosition(position);
- mMapboxMap.moveCamera(CameraUpdateFactory.zoomBy(3));
- assertTrue("Zoomlevel should be same", 6 == mMapboxMap.getCameraPosition().zoom);
- }
-
- @Test
- public void testZoomByPointMoveCamera() {
- CameraPosition position = new CameraPosition.Builder().bearing(1).tilt(2).zoom(3).target(new LatLng(4, 5)).build();
- mMapboxMap.setCameraPosition(position);
- mMapboxMap.moveCamera(CameraUpdateFactory.zoomBy(3, new Point(0, 0)));
- assertTrue("Zoomlevel should be same", 6 == mMapboxMap.getCameraPosition().zoom);
- // todo calculate and check LatLng
- }
-
- @Test
- public void testZoomToMoveCamera() {
- CameraPosition position = new CameraPosition.Builder().bearing(1).tilt(2).zoom(3).target(new LatLng(4, 5)).build();
- mMapboxMap.setCameraPosition(position);
- mMapboxMap.moveCamera(CameraUpdateFactory.zoomTo(12));
- assertTrue("Zoomlevel should be same", 12 == mMapboxMap.getCameraPosition().zoom);
- }
-
- @Test
- public void testZoomInAnimateCamera() {
- CameraPosition position = new CameraPosition.Builder().bearing(1).tilt(2).zoom(3).target(new LatLng(4, 5)).build();
- mMapboxMap.setCameraPosition(position);
- mMapboxMap.animateCamera(CameraUpdateFactory.zoomIn());
- assertTrue("Zoomlevel should be same", 4 == mMapboxMap.getCameraPosition().zoom);
- }
-
- @Test
- public void testZoomOutAnimateCamera() {
- CameraPosition position = new CameraPosition.Builder().bearing(1).tilt(2).zoom(3).target(new LatLng(4, 5)).build();
- mMapboxMap.setCameraPosition(position);
- mMapboxMap.animateCamera(CameraUpdateFactory.zoomOut());
- assertTrue("Zoomlevel should be same", 2 == mMapboxMap.getCameraPosition().zoom);
- }
-
- @Test
- public void testZoomByAnimateCamera() {
- CameraPosition position = new CameraPosition.Builder().bearing(1).tilt(2).zoom(3).target(new LatLng(4, 5)).build();
- mMapboxMap.setCameraPosition(position);
- mMapboxMap.animateCamera(CameraUpdateFactory.zoomBy(3));
- assertTrue("Zoomlevel should be same", 6 == mMapboxMap.getCameraPosition().zoom);
- }
-
- @Test
- public void testZoomToAnimateCamera() {
- CameraPosition position = new CameraPosition.Builder().bearing(1).tilt(2).zoom(3).target(new LatLng(4, 5)).build();
- mMapboxMap.setCameraPosition(position);
- mMapboxMap.animateCamera(CameraUpdateFactory.zoomTo(12));
- assertTrue("Zoomlevel should be same", 12 == mMapboxMap.getCameraPosition().zoom);
- }
-
- @Test
- public void testZoomByPointAnimateCamera() {
- CameraPosition position = new CameraPosition.Builder().bearing(1).tilt(2).zoom(3).target(new LatLng(4, 5)).build();
- mMapboxMap.setCameraPosition(position);
- mMapboxMap.animateCamera(CameraUpdateFactory.zoomBy(1, new Point(0, 0)));
- assertTrue("Zoomlevel should be same", 4 == mMapboxMap.getCameraPosition().zoom);
- // todo calculate and check LatLng
- }
-
- @Test
- public void testZoomInEaseCamera() {
- CameraPosition position = new CameraPosition.Builder().bearing(1).tilt(2).zoom(3).target(new LatLng(4, 5)).build();
- mMapboxMap.setCameraPosition(position);
- mMapboxMap.easeCamera(CameraUpdateFactory.zoomIn(), 1000);
- assertTrue("Zoomlevel should be same", 4 == mMapboxMap.getCameraPosition().zoom);
- }
-
- @Test
- public void testZoomOutEaseCamera() {
- CameraPosition position = new CameraPosition.Builder().bearing(1).tilt(2).zoom(3).target(new LatLng(4, 5)).build();
- mMapboxMap.setCameraPosition(position);
- mMapboxMap.easeCamera(CameraUpdateFactory.zoomOut(), 1000);
- assertTrue("Zoomlevel should be same", 2 == mMapboxMap.getCameraPosition().zoom);
- }
-
- @Test
- public void testZoomByEaseCamera() {
- CameraPosition position = new CameraPosition.Builder().bearing(1).tilt(2).zoom(3).target(new LatLng(4, 5)).build();
- mMapboxMap.setCameraPosition(position);
- mMapboxMap.easeCamera(CameraUpdateFactory.zoomBy(3), 1000);
- assertTrue("Zoomlevel should be same", 6 == mMapboxMap.getCameraPosition().zoom);
- }
-
- @Test
- public void testZoomByPointCamera() {
- CameraPosition position = new CameraPosition.Builder().bearing(1).tilt(2).zoom(3).target(new LatLng(4, 5)).build();
- mMapboxMap.setCameraPosition(position);
- mMapboxMap.easeCamera(CameraUpdateFactory.zoomBy(3, new Point(0, 0)), 1000);
- assertTrue("Zoomlevel should be same", 6 == mMapboxMap.getCameraPosition().zoom);
- // todo calculate and check LatLng
- }
-
- @Test
- public void testZoomToEaseCamera() {
- CameraPosition position = new CameraPosition.Builder().bearing(1).tilt(2).zoom(3).target(new LatLng(4, 5)).build();
- mMapboxMap.setCameraPosition(position);
- mMapboxMap.easeCamera(CameraUpdateFactory.zoomTo(12), 1000);
- assertTrue("Zoomlevel should be same", 12 == mMapboxMap.getCameraPosition().zoom);
- }
-
- //
- // OnCameraChangeListener
- //
-
- @Test
- public void testOnCameraChangeListener() {
- CameraPosition position = new CameraPosition.Builder().bearing(1).tilt(2).zoom(3).target(new LatLng(4, 5)).build();
- mMapboxMap.setOnCameraChangeListener(mOnCameraChangeListener);
- mMapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(position));
- verify(mOnCameraChangeListener, times(1)).onCameraChange(position);
- }
-
- //
- // Annotations
- //
-
- @Test
- public void testAddMarker() {
- MarkerOptions markerOptions = new MarkerOptions().position(new LatLng());
- Marker marker = mMapboxMap.addMarker(markerOptions);
- assertTrue("Marker should be contained", mMapboxMap.getMarkers().contains(marker));
- }
-
- @Test(expected = InvalidMarkerPositionException.class)
- public void testAddMarkerInvalidPosition(){
- new MarkerOptions().getMarker();
- }
-
- @Test
- public void testAddMarkers() {
- List<BaseMarkerOptions> markerList = new ArrayList<>();
- MarkerOptions markerOptions1 = new MarkerOptions().position(new LatLng()).title("a");
- MarkerOptions markerOptions2 = new MarkerOptions().position(new LatLng()).title("b");
- markerList.add(markerOptions1);
- markerList.add(markerOptions2);
- List<Marker> markers = mMapboxMap.addMarkers(markerList);
- assertEquals("Markers size should be 2", 2, mMapboxMap.getMarkers().size());
- assertTrue(mMapboxMap.getMarkers().contains(markers.get(0)));
- assertTrue(mMapboxMap.getMarkers().contains(markers.get(1)));
- }
-
- @Test
- public void testAddMarkersEmpty() {
- List<BaseMarkerOptions> markerList = new ArrayList<>();
- mMapboxMap.addMarkers(markerList);
- assertEquals("Markers size should be 0", 0, mMapboxMap.getMarkers().size());
- }
-
- @Test
- public void testAddMarkersSingleMarker() {
- List<BaseMarkerOptions> markerList = new ArrayList<>();
- MarkerOptions markerOptions = new MarkerOptions().title("a").position(new LatLng());
- markerList.add(markerOptions);
- List<Marker> markers = mMapboxMap.addMarkers(markerList);
- assertEquals("Markers size should be 1", 1, mMapboxMap.getMarkers().size());
- assertTrue(mMapboxMap.getMarkers().contains(markers.get(0)));
- }
-
- @Test
- public void testAddPolygon() {
- PolygonOptions polygonOptions = new PolygonOptions().add(new LatLng());
- Polygon polygon = mMapboxMap.addPolygon(polygonOptions);
- assertTrue("Polygon should be contained", mMapboxMap.getPolygons().contains(polygon));
- }
-
- @Test
- public void testAddEmptyPolygon() {
- PolygonOptions polygonOptions = new PolygonOptions();
- Polygon polygon = mMapboxMap.addPolygon(polygonOptions);
- assertTrue("Polygon should be ignored", !mMapboxMap.getPolygons().contains(polygon));
- }
-
- @Test
- public void testAddPolygons() {
- List<PolygonOptions> polygonList = new ArrayList<>();
- PolygonOptions polygonOptions1 = new PolygonOptions().fillColor(Color.BLACK).add(new LatLng());
- PolygonOptions polygonOptions2 = new PolygonOptions().fillColor(Color.WHITE).add(new LatLng());
- PolygonOptions polygonOptions3 = new PolygonOptions();
- polygonList.add(polygonOptions1);
- polygonList.add(polygonOptions2);
- polygonList.add(polygonOptions3);
- mMapboxMap.addPolygons(polygonList);
- assertEquals("Polygons size should be 2", 2, mMapboxMap.getPolygons().size());
- assertTrue(mMapboxMap.getPolygons().contains(polygonOptions1.getPolygon()));
- assertTrue(mMapboxMap.getPolygons().contains(polygonOptions2.getPolygon()));
- assertTrue("Polygon should be ignored", !mMapboxMap.getPolygons().contains(polygonOptions3.getPolygon()));
- }
-
- @Test
- public void addPolygonsEmpty() {
- mMapboxMap.addPolygons(new ArrayList<PolygonOptions>());
- assertEquals("Polygons size should be 0", 0, mMapboxMap.getPolygons().size());
- }
-
- @Test
- public void addPolygonsSingle() {
- List<PolygonOptions> polygonList = new ArrayList<>();
- PolygonOptions polygonOptions = new PolygonOptions().fillColor(Color.BLACK).add(new LatLng());
- polygonList.add(polygonOptions);
- mMapboxMap.addPolygons(polygonList);
- assertEquals("Polygons size should be 1", 1, mMapboxMap.getPolygons().size());
- assertTrue(mMapboxMap.getPolygons().contains(polygonOptions.getPolygon()));
- }
-
- @Test
- public void testAddPolyline() {
- PolylineOptions polylineOptions = new PolylineOptions().add(new LatLng());
- Polyline polyline = mMapboxMap.addPolyline(polylineOptions);
- assertTrue("Polyline should be contained", mMapboxMap.getPolylines().contains(polyline));
- }
-
- @Test
- public void testAddEmptyPolyline() {
- PolylineOptions polylineOptions = new PolylineOptions();
- Polyline polyline = mMapboxMap.addPolyline(polylineOptions);
- assertTrue("Polyline should be ignored", !mMapboxMap.getPolylines().contains(polyline));
- }
-
- @Test
- public void testAddPolylines() {
- List<PolylineOptions> polylineList = new ArrayList<>();
- PolylineOptions polygonOptions1 = new PolylineOptions().color(Color.BLACK).add(new LatLng());
- PolylineOptions polygonOptions2 = new PolylineOptions().color(Color.WHITE).add(new LatLng());
- PolylineOptions polygonOptions3 = new PolylineOptions();
- polylineList.add(polygonOptions1);
- polylineList.add(polygonOptions2);
- polylineList.add(polygonOptions3);
- mMapboxMap.addPolylines(polylineList);
- assertEquals("Polygons size should be 2", 2, mMapboxMap.getPolylines().size());
- assertTrue(mMapboxMap.getPolylines().contains(polygonOptions1.getPolyline()));
- assertTrue(mMapboxMap.getPolylines().contains(polygonOptions2.getPolyline()));
- assertTrue("Polyline should be ignored", !mMapboxMap.getPolylines().contains(polygonOptions3.getPolyline()));
- }
-
- @Test
- public void testAddPolylinesEmpty() {
- mMapboxMap.addPolylines(new ArrayList<PolylineOptions>());
- assertEquals("Polygons size should be 0", 0, mMapboxMap.getPolylines().size());
- }
-
- @Test
- public void testAddPolylinesSingle() {
- List<PolylineOptions> polylineList = new ArrayList<>();
- PolylineOptions polygonOptions = new PolylineOptions().color(Color.BLACK).add(new LatLng());
- polylineList.add(polygonOptions);
- mMapboxMap.addPolylines(polylineList);
- assertEquals("Polygons size should be 1", 1, mMapboxMap.getPolylines().size());
- assertTrue(mMapboxMap.getPolylines().contains(polygonOptions.getPolyline()));
- }
-
- @Test
- public void testRemoveMarker() {
- MarkerOptions markerOptions = new MarkerOptions().position(new LatLng());
- Marker marker = mMapboxMap.addMarker(markerOptions);
- mMapboxMap.removeMarker(marker);
- assertTrue("Markers should be empty", mMapboxMap.getMarkers().isEmpty());
- }
-
- @Test
- public void testRemovePolygon() {
- PolygonOptions polygonOptions = new PolygonOptions();
- Polygon polygon = mMapboxMap.addPolygon(polygonOptions);
- mMapboxMap.removePolygon(polygon);
- assertTrue("Polygons should be empty", mMapboxMap.getPolylines().isEmpty());
- }
-
- @Test
- public void testRemovePolyline() {
- PolylineOptions polylineOptions = new PolylineOptions();
- Polyline polyline = mMapboxMap.addPolyline(polylineOptions);
- mMapboxMap.removePolyline(polyline);
- assertTrue("Polylines should be empty", mMapboxMap.getPolylines().isEmpty());
- }
-
- @Test
- public void testRemoveAnnotation() {
- MarkerOptions markerOptions = new MarkerOptions().position(new LatLng());
- Marker marker = mMapboxMap.addMarker(markerOptions);
- mMapboxMap.removeAnnotation(marker);
- assertTrue("Annotations should be empty", mMapboxMap.getAnnotations().isEmpty());
- }
-
- @Test
- public void testRemoveAnnotationById() {
- MarkerOptions markerOptions = new MarkerOptions().position(new LatLng());
- mMapboxMap.addMarker(markerOptions);
- // id will always be 0 in unit tests
- mMapboxMap.removeAnnotation(0);
- assertTrue("Annotations should be empty", mMapboxMap.getAnnotations().isEmpty());
- }
-
- @Test
- public void testRemoveAnnotations() {
- List<BaseMarkerOptions> markerList = new ArrayList<>();
- MarkerOptions markerOptions1 = new MarkerOptions().title("a").position(new LatLng());
- MarkerOptions markerOptions2 = new MarkerOptions().title("b").position(new LatLng());
- markerList.add(markerOptions1);
- markerList.add(markerOptions2);
- mMapboxMap.addMarkers(markerList);
- mMapboxMap.removeAnnotations();
- assertTrue("Annotations should be empty", mMapboxMap.getAnnotations().isEmpty());
- }
-
- @Test
- public void testClear() {
- List<BaseMarkerOptions> markerList = new ArrayList<>();
- MarkerOptions markerOptions1 = new MarkerOptions().title("a").position(new LatLng());
- MarkerOptions markerOptions2 = new MarkerOptions().title("b").position(new LatLng());
- markerList.add(markerOptions1);
- markerList.add(markerOptions2);
- mMapboxMap.addMarkers(markerList);
- mMapboxMap.clear();
- assertTrue("Annotations should be empty", mMapboxMap.getAnnotations().isEmpty());
- }
-
- @Test
- public void testRemoveAnnotationsByList() {
- List<BaseMarkerOptions> markerList = new ArrayList<>();
- MarkerOptions markerOptions1 = new MarkerOptions().title("a").position(new LatLng());
- MarkerOptions markerOptions2 = new MarkerOptions().title("b").position(new LatLng());
- markerList.add(markerOptions1);
- markerList.add(markerOptions2);
- List<Marker> markers = mMapboxMap.addMarkers(markerList);
- Marker marker = mMapboxMap.addMarker(new MarkerOptions().position(new LatLng()).title("c"));
- mMapboxMap.removeAnnotations(markers);
- assertTrue("Annotations should not be empty", mMapboxMap.getAnnotations().size() == 1);
- assertTrue("Marker should be contained", mMapboxMap.getAnnotations().contains(marker));
- }
-
- @Test
- public void testGetAnnotationById() {
- MarkerOptions markerOptions = new MarkerOptions().position(new LatLng());
- Marker initialMarker = mMapboxMap.addMarker(markerOptions);
- Marker retrievedMarker = (Marker) mMapboxMap.getAnnotation(0);
- assertEquals("Markers should match", initialMarker, retrievedMarker);
- }
-
- @Test
- public void testGetAnnotations() {
- assertNotNull("Annotations should be non null", mMapboxMap.getAnnotations());
- }
-
- @Test
- public void testGetMarkers() {
- assertNotNull("Markers should be non null", mMapboxMap.getMarkers());
- }
-
- @Test
- public void testGetPolygons() {
- assertNotNull("Polygons should be non null", mMapboxMap.getPolygons());
- }
-
- @Test
- public void testGetPolylines() {
- assertNotNull("Polylines should be non null", mMapboxMap.getPolylines());
- }
-
- @Test
- public void testGetSelectedMarkers() {
- assertNotNull("Selected markers should be non null", mMapboxMap.getSelectedMarkers());
- }
-
- @Test
- public void testSelectMarker() {
- mMapboxMap.setOnMarkerClickListener(mOnMarkerClickListener);
- MarkerOptions markerOptions = new MarkerOptions().position(new LatLng());
- Marker marker = mMapboxMap.addMarker(markerOptions);
- when(mOnMarkerClickListener.onMarkerClick(marker)).thenReturn(true);
- mMapboxMap.selectMarker(marker);
- assertTrue("Marker should be contained", mMapboxMap.getSelectedMarkers().contains(marker));
- }
-
- @Test
- public void testDeselectMarker() {
- mMapboxMap.setOnMarkerClickListener(mOnMarkerClickListener);
- MarkerOptions markerOptions = new MarkerOptions().position(new LatLng());
- Marker marker = mMapboxMap.addMarker(markerOptions);
- when(mOnMarkerClickListener.onMarkerClick(marker)).thenReturn(true);
- mMapboxMap.selectMarker(marker);
- mMapboxMap.deselectMarker(marker);
- assertTrue("Selected markers should be empty", mMapboxMap.getSelectedMarkers().isEmpty());
- }
-
- @Test
- public void testDeselectMarkers() {
- mMapboxMap.setOnMarkerClickListener(mOnMarkerClickListener);
- MarkerOptions markerOptions = new MarkerOptions().position(new LatLng());
- Marker marker1 = mMapboxMap.addMarker(markerOptions);
- Marker marker2 = mMapboxMap.addMarker(markerOptions);
- when(mOnMarkerClickListener.onMarkerClick(marker1)).thenReturn(true);
- when(mOnMarkerClickListener.onMarkerClick(marker2)).thenReturn(true);
- mMapboxMap.selectMarker(marker1);
- mMapboxMap.selectMarker(marker2);
- mMapboxMap.deselectMarkers();
- assertTrue("Selected markers should be empty", mMapboxMap.getSelectedMarkers().isEmpty());
- }
-
- //
- // OnMarkerClick interface
- //
-
- @Test
- public void testOnMarkerClick() {
- mMapboxMap.setOnMarkerClickListener(mOnMarkerClickListener);
- Marker marker = new MarkerOptions().position(new LatLng()).getMarker();
- when(mOnMarkerClickListener.onMarkerClick(marker)).thenReturn(true);
- mMapboxMap.selectMarker(marker);
- verify(mOnMarkerClickListener, times(1)).onMarkerClick(marker);
- }
-
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/ProjectionTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/ProjectionTest.java
deleted file mode 100644
index fac06de16b..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/ProjectionTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.mapbox.mapboxsdk.maps;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.InjectMocks;
-import org.mockito.MockitoAnnotations;
-
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Mockito.mock;
-
-public class ProjectionTest {
-
- @InjectMocks
- MapView mMapView = mock(MapView.class);
-
- @Before
- public void beforeTest() {
- MockitoAnnotations.initMocks(this);
- }
-
- @Test
- public void testSanity() {
- Projection projection = new Projection(mMapView);
- assertNotNull("projection should not be null", projection);
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/TrackingSettingsTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/TrackingSettingsTest.java
index 266bbadd95..57f3b942af 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/TrackingSettingsTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/TrackingSettingsTest.java
@@ -1,53 +1,70 @@
package com.mapbox.mapboxsdk.maps;
-import com.mapbox.mapboxsdk.constants.MyBearingTracking;
+import android.Manifest;
+import android.content.Context;
+import android.content.pm.PackageManager;
+
import com.mapbox.mapboxsdk.constants.MyLocationTracking;
+import com.mapbox.mapboxsdk.maps.widgets.MyLocationView;
+import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
-import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
public class TrackingSettingsTest {
- @InjectMocks
- MapView mMapView = mock(MapView.class);
-
- @Test
- public void testSanity() {
- TrackingSettings trackingSettings = new TrackingSettings(mMapView, new UiSettings(mMapView));
- assertNotNull("trackingsettings should not be null", trackingSettings);
- }
-
- @Test
- public void testMyLocationTrackingMode() {
- TrackingSettings trackingSettings = new TrackingSettings(mMapView, new UiSettings(mMapView));
- trackingSettings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW);
- assertEquals("MyLocationTrackingMode should match", MyLocationTracking.TRACKING_FOLLOW, trackingSettings.getMyLocationTrackingMode());
- }
-
- @Test
- public void testMyBearingTrackingMode() {
- TrackingSettings trackingSettings = new TrackingSettings(mMapView, new UiSettings(mMapView));
- trackingSettings.setMyBearingTrackingMode(MyBearingTracking.COMPASS);
- assertEquals("MyLocationTrackingMode should match", MyBearingTracking.COMPASS, trackingSettings.getMyBearingTrackingMode());
- }
-
- @Test
- public void testDismissTrackingModesOnGesture() {
- TrackingSettings trackingSettings = new TrackingSettings(mMapView, new UiSettings(mMapView));
- trackingSettings.setDismissTrackingOnGesture(false);
- assertFalse("DismissTrackingOnGesture should be false", trackingSettings.isDismissTrackingOnGesture());
- }
-
- @Test
- public void testValidateGesturesForTrackingModes(){
- TrackingSettings trackingSettings = new TrackingSettings(mMapView, new UiSettings(mMapView));
- trackingSettings.setDismissTrackingOnGesture(false);
- trackingSettings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW);
- assertFalse("DismissTrackingOnGesture should be false", trackingSettings.isDismissTrackingOnGesture());
- }
+ @InjectMocks
+ MyLocationView myLocationView = mock(MyLocationView.class);
+
+ @InjectMocks
+ UiSettings uiSettings = mock(UiSettings.class);
+
+ @InjectMocks
+ FocalPointChangeListener focalPointChangeListener = mock(FocalPointChangeListener.class);
+
+ private TrackingSettings trackingSettings;
+
+ @Before
+ public void beforeTest() {
+ trackingSettings = new TrackingSettings(myLocationView, uiSettings, focalPointChangeListener);
+ }
+
+ @Test
+ public void testSanity() {
+ assertNotNull("trackingsettings should not be null", trackingSettings);
+ }
+
+ @Test
+ public void testDismissTrackingModesOnGesture() {
+ trackingSettings.setDismissTrackingOnGesture(false);
+ assertFalse("DismissTrackingOnGesture should be false", trackingSettings.isDismissTrackingOnGesture());
+ }
+
+ @Test
+ public void testValidateGesturesForTrackingModes() {
+ trackingSettings.setDismissTrackingOnGesture(false);
+ trackingSettings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW);
+ assertFalse("DismissTrackingOnGesture should be false", trackingSettings.isDismissTrackingOnGesture());
+ }
+
+ @Test
+ public void testMyLocationEnabled() {
+ // setup mock context to provide accepted location permission
+ Context context = mock(Context.class);
+ when(myLocationView.getContext()).thenReturn(context);
+ when(context.checkPermission(eq(Manifest.permission.ACCESS_COARSE_LOCATION), anyInt(),
+ anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED);
+
+ assertFalse("Location should be disabled by default.", trackingSettings.isMyLocationEnabled());
+ trackingSettings.setMyLocationEnabled(true);
+ assertTrue("Location should be enabled", trackingSettings.isMyLocationEnabled());
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/UiSettingsTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/UiSettingsTest.java
index 14fc84723d..1f532255d7 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/UiSettingsTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/UiSettingsTest.java
@@ -1,6 +1,11 @@
package com.mapbox.mapboxsdk.maps;
import android.view.Gravity;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+
+import com.mapbox.mapboxsdk.maps.widgets.CompassView;
import org.junit.Before;
import org.junit.Test;
@@ -15,293 +20,321 @@ import static org.mockito.Mockito.when;
public class UiSettingsTest {
- @InjectMocks
- MapView mMapView = mock(MapView.class);
-
- UiSettings uiSettings;
-
- @Before
- public void beforeTest() {
- uiSettings = new UiSettings(mMapView);
- }
-
- @Test
- public void testSanity() {
- assertNotNull("uiSettings should not be null", uiSettings);
- }
-
- @Test
- public void testCompassEnabled() {
- uiSettings.setCompassEnabled(true);
- assertEquals("Compass should be enabled", true, uiSettings.isCompassEnabled());
- }
-
- @Test
- public void testCompassDisabled() {
- uiSettings.setCompassEnabled(false);
- assertEquals("Compass should be disabled", false, uiSettings.isCompassEnabled());
- }
-
- @Test
- public void testCompassGravity() {
- uiSettings.setCompassGravity(Gravity.LEFT);
- assertEquals("Compass gravity should be same", Gravity.LEFT, uiSettings.getCompassGravity());
- }
-
- @Test
- public void testCompassMargins() {
- uiSettings.setCompassMargins(1, 2, 3, 4);
- assertTrue("Compass margin left should be same", uiSettings.getCompassMarginLeft() == 1);
- assertTrue("Compass margin top should be same", uiSettings.getCompassMarginTop() == 2);
- assertTrue("Compass margin right should be same", uiSettings.getCompassMarginRight() == 3);
- assertTrue("Compass margin bottom should be same", uiSettings.getCompassMarginBottom() == 4);
- }
-
- @Test
- public void testCompassFadeWhenFacingNorth(){
- assertTrue("Compass should fade when facing north by default.", uiSettings.isCompassFadeWhenFacingNorth());
- uiSettings.setCompassFadeFacingNorth(false);
- assertFalse("Compass fading should be disabled", uiSettings.isCompassFadeWhenFacingNorth());
- }
-
- @Test
- public void testLogoEnabled() {
- uiSettings.setLogoEnabled(true);
- assertEquals("Logo should be enabled", true, uiSettings.isLogoEnabled());
- }
-
- @Test
- public void testLogoDisabled() {
- uiSettings.setLogoEnabled(false);
- assertEquals("Logo should be disabled", false, uiSettings.isLogoEnabled());
- }
-
- @Test
- public void testLogoGravity() {
- uiSettings.setLogoGravity(Gravity.RIGHT);
- assertEquals("Logo gravity should be same", Gravity.RIGHT, uiSettings.getLogoGravity());
- }
-
- @Test
- public void testLogoMargins() {
- uiSettings.setLogoMargins(1, 2, 3, 4);
- assertTrue("Compass margin left should be same", uiSettings.getLogoMarginLeft() == 1);
- assertTrue("Compass margin top should be same", uiSettings.getLogoMarginTop() == 2);
- assertTrue("Compass margin right should be same", uiSettings.getLogoMarginRight() == 3);
- assertTrue("Compass margin bottom should be same", uiSettings.getLogoMarginBottom() == 4);
- }
-
- @Test
- public void testAttributionEnabled() {
- uiSettings.setAttributionEnabled(true);
- assertEquals("Attribution should be enabled", true, uiSettings.isAttributionEnabled());
- }
-
- @Test
- public void testAttributionDisabled() {
- uiSettings.setAttributionEnabled(false);
- assertEquals("Attribution should be disabled", false, uiSettings.isLogoEnabled());
- }
-
- @Test
- public void testAttributionGravity() {
- uiSettings.setAttributionGravity(Gravity.RIGHT);
- assertEquals("Attribution gravity should be same", Gravity.RIGHT, uiSettings.getAttributionGravity());
- }
-
- @Test
- public void testAttributionMargins() {
- uiSettings.setAttributionMargins(1, 2, 3, 4);
- assertTrue("Attribution margin left should be same", uiSettings.getAttributionMarginLeft() == 1);
- assertTrue("Attribution margin top should be same", uiSettings.getAttributionMarginTop() == 2);
- assertTrue("Attribution margin right should be same", uiSettings.getAttributionMarginRight() == 3);
- assertTrue("Attribution margin bottom should be same", uiSettings.getAttributionMarginBottom() == 4);
- }
-
- @Test
- public void testRotateGesturesEnabled() {
- uiSettings.setRotateGesturesEnabled(true);
- assertEquals("Rotate gesture should be enabled", true, uiSettings.isRotateGesturesEnabled());
- }
-
- @Test
- public void testRotateGesturesDisabled() {
- uiSettings.setRotateGesturesEnabled(false);
- assertEquals("Rotate gesture should be disabled", false, uiSettings.isRotateGesturesEnabled());
- }
-
- @Test
- public void testRotateGestureChange() {
- assertEquals("Default state should be true", true, uiSettings.isRotateGestureChangeAllowed());
- uiSettings.setRotateGestureChangeAllowed(false);
- assertEquals("State should have been changed", false, uiSettings.isRotateGestureChangeAllowed());
- }
-
- @Test
- public void testRotateGestureChangeAllowed() {
- uiSettings.setRotateGesturesEnabled(false);
- assertEquals("Rotate gesture should be false", false, uiSettings.isRotateGesturesEnabled());
- uiSettings.setRotateGesturesEnabled(true);
- assertEquals("Rotate gesture should be true", true, uiSettings.isRotateGesturesEnabled());
- }
-
- @Test
- public void testRotateGestureChangeDisallowed() {
- assertEquals("Rotate gesture should be true", true, uiSettings.isRotateGesturesEnabled());
- uiSettings.setRotateGestureChangeAllowed(false);
- uiSettings.setRotateGesturesEnabled(false);
- assertEquals("Rotate gesture change should be ignored", true, uiSettings.isRotateGesturesEnabled());
- }
-
- @Test
- public void testTiltGesturesEnabled() {
- uiSettings.setTiltGesturesEnabled(true);
- assertEquals("Tilt gesture should be enabled", true, uiSettings.isTiltGesturesEnabled());
- }
-
- @Test
- public void testTiltGesturesDisabled() {
- uiSettings.setTiltGesturesEnabled(false);
- assertEquals("Tilt gesture should be disabled", false, uiSettings.isTiltGesturesEnabled());
- }
-
- @Test
- public void testTiltGestureChange() {
- assertEquals("Default state should be true", true, uiSettings.isTiltGestureChangeAllowed());
- uiSettings.setTiltGestureChangeAllowed(false);
- assertEquals("State should have been changed", false, uiSettings.isTiltGestureChangeAllowed());
- }
-
- @Test
- public void testTiltGestureChangeAllowed() {
- uiSettings.setTiltGesturesEnabled(false);
- assertEquals("Tilt gesture should be false", false, uiSettings.isTiltGesturesEnabled());
- uiSettings.setTiltGesturesEnabled(true);
- assertEquals("Tilt gesture should be true", true, uiSettings.isTiltGesturesEnabled());
- }
-
- @Test
- public void testTiltGestureChangeDisallowed() {
- assertEquals("Tilt gesture should be true", true, uiSettings.isTiltGesturesEnabled());
- uiSettings.setTiltGestureChangeAllowed(false);
- uiSettings.setTiltGesturesEnabled(false);
- assertEquals("Tilt gesture change should be ignored", true, uiSettings.isTiltGesturesEnabled());
- }
-
- @Test
- public void testZoomGesturesEnabled() {
- uiSettings.setZoomGesturesEnabled(true);
- assertEquals("Zoom gesture should be enabled", true, uiSettings.isZoomGesturesEnabled());
- }
-
- @Test
- public void testZoomGesturesDisabled() {
- uiSettings.setZoomGesturesEnabled(false);
- assertEquals("Zoom gesture should be disabled", false, uiSettings.isZoomGesturesEnabled());
- }
-
- @Test
- public void testZoomGestureChange() {
- assertEquals("Default state should be true", true, uiSettings.isZoomGestureChangeAllowed());
- uiSettings.setZoomGestureChangeAllowed(false);
- assertEquals("State should have been changed", false, uiSettings.isZoomGestureChangeAllowed());
- }
-
- @Test
- public void testZoomGestureChangeAllowed() {
- uiSettings.setZoomGesturesEnabled(false);
- assertEquals("Zoom gesture should be false", false, uiSettings.isZoomGesturesEnabled());
- uiSettings.setZoomGesturesEnabled(true);
- assertEquals("Zoom gesture should be true", true, uiSettings.isZoomGesturesEnabled());
- }
-
- @Test
- public void testZoomGestureChangeDisallowed() {
- assertEquals("Zoom gesture should be true", true, uiSettings.isZoomGesturesEnabled());
- uiSettings.setZoomGestureChangeAllowed(false);
- uiSettings.setZoomGesturesEnabled(false);
- assertEquals("Zooom gesture change should be ignored", true, uiSettings.isZoomGesturesEnabled());
- }
-
- @Test
- public void testZoomControlsEnabled() {
- uiSettings.setZoomControlsEnabled(true);
- assertEquals("Zoom controls should be enabled", true, uiSettings.isZoomControlsEnabled());
- }
-
- @Test
- public void testZoomControlsDisabled() {
- uiSettings.setZoomControlsEnabled(false);
- assertEquals("Zoom controls should be disabled", false, uiSettings.isZoomControlsEnabled());
- }
-
- @Test
- public void testScrollGesturesEnabled() {
- uiSettings.setScrollGesturesEnabled(true);
- assertEquals("Scroll gesture should be enabled", true, uiSettings.isScrollGesturesEnabled());
- }
-
- @Test
- public void testScrollGesturesDisabled() {
- uiSettings.setScrollGesturesEnabled(false);
- assertEquals("Scroll gesture should be disabled", false, uiSettings.isScrollGesturesEnabled());
- }
-
- @Test
- public void testScrollGestureChange() {
- assertEquals("Default state should be true", true, uiSettings.isScrollGestureChangeAllowed());
- uiSettings.setScrollGestureChangeAllowed(false);
- assertEquals("State should have been changed", false, uiSettings.isScrollGestureChangeAllowed());
- }
-
- @Test
- public void testScrollGestureChangeAllowed() {
- uiSettings.setScrollGesturesEnabled(false);
- assertEquals("Scroll gesture should be false", false, uiSettings.isScrollGesturesEnabled());
- uiSettings.setScrollGesturesEnabled(true);
- assertEquals("Scroll gesture should be true", true, uiSettings.isScrollGesturesEnabled());
- }
-
- @Test
- public void testScrollGestureChangeDisallowed() {
- assertEquals("Scroll gesture should be true", true, uiSettings.isScrollGesturesEnabled());
- uiSettings.setScrollGestureChangeAllowed(false);
- uiSettings.setScrollGesturesEnabled(false);
- assertEquals("Scroll gesture change should be ignored", true, uiSettings.isScrollGesturesEnabled());
- }
-
- @Test
- public void testAllGesturesEnabled() {
- uiSettings.setAllGesturesEnabled(true);
- assertEquals("Rotate gesture should be enabled", true, uiSettings.isRotateGesturesEnabled());
- assertEquals("Tilt gesture should be enabled", true, uiSettings.isTiltGesturesEnabled());
- assertEquals("Zoom gesture should be enabled", true, uiSettings.isZoomGesturesEnabled());
- assertEquals("Scroll gesture should be enabled", true, uiSettings.isScrollGesturesEnabled());
- }
-
- @Test
- public void testAllGesturesDisabled() {
- uiSettings.setAllGesturesEnabled(false);
- assertEquals("Rotate gesture should be enabled", false, uiSettings.isRotateGesturesEnabled());
- assertEquals("Tilt gesture should be disabled", false, uiSettings.isTiltGesturesEnabled());
- assertEquals("Zoom gesture should be disabled", false, uiSettings.isZoomGesturesEnabled());
- assertEquals("Scroll gesture should be disabled", false, uiSettings.isScrollGesturesEnabled());
- }
-
- @Test
- public void testInvalidate() {
- uiSettings.invalidate();
- }
-
- @Test
- public void testHeight() {
- when(mMapView.getMeasuredHeight()).thenReturn(1);
- assertEquals("height should be same as mocked instance", 1, uiSettings.getHeight(), 0);
- }
-
- @Test
- public void testWidth() {
- when(mMapView.getMeasuredWidth()).thenReturn(1);
- assertEquals("width should be same as mocked instance", 1, uiSettings.getWidth(), 0);
- }
+ @InjectMocks
+ Projection projection = mock(Projection.class);
+
+ @InjectMocks
+ FocalPointChangeListener focalPointChangeListener = mock(FocalPointChangeListener.class);
+
+ @InjectMocks
+ CompassView compassView = mock(CompassView.class);
+
+ @InjectMocks
+ ImageView imageView = mock(ImageView.class);
+
+ @InjectMocks
+ ImageView logoView = mock(ImageView.class);
+
+ @InjectMocks
+ FrameLayout.LayoutParams layoutParams = mock(FrameLayout.LayoutParams.class);
+
+ private UiSettings uiSettings;
+
+ @Before
+ public void beforeTest() {
+ uiSettings = new UiSettings(projection, focalPointChangeListener, compassView, imageView, logoView);
+ }
+
+ @Test
+ public void testSanity() {
+ assertNotNull("uiSettings should not be null", uiSettings);
+ }
+
+ @Test
+ public void testCompassEnabled() {
+ when(compassView.isEnabled()).thenReturn(true);
+ uiSettings.setCompassEnabled(true);
+ assertEquals("Compass should be enabled", true, uiSettings.isCompassEnabled());
+ }
+
+ @Test
+ public void testCompassDisabled() {
+ uiSettings.setCompassEnabled(false);
+ assertEquals("Compass should be disabled", false, uiSettings.isCompassEnabled());
+ }
+
+ @Test
+ public void testCompassGravity() {
+ when(compassView.getLayoutParams()).thenReturn(layoutParams);
+ layoutParams.gravity = Gravity.START;
+ uiSettings.setCompassGravity(Gravity.START);
+ assertEquals("Compass gravity should be same", Gravity.START, uiSettings.getCompassGravity());
+ }
+
+ @Test
+ public void testCompassMargins() {
+ when(projection.getContentPadding()).thenReturn(new int[] {0, 0, 0, 0});
+ when(compassView.getLayoutParams()).thenReturn(layoutParams);
+ layoutParams.leftMargin = 1;
+ layoutParams.topMargin = 2;
+ layoutParams.rightMargin = 3;
+ layoutParams.bottomMargin = 4;
+ uiSettings.setCompassMargins(1, 2, 3, 4);
+ assertTrue("Compass margin left should be same", uiSettings.getCompassMarginLeft() == 1);
+ assertTrue("Compass margin top should be same", uiSettings.getCompassMarginTop() == 2);
+ assertTrue("Compass margin right should be same", uiSettings.getCompassMarginRight() == 3);
+ assertTrue("Compass margin bottom should be same", uiSettings.getCompassMarginBottom() == 4);
+ }
+
+ @Test
+ public void testCompassFadeWhenFacingNorth() {
+ when(compassView.isFadeCompassViewFacingNorth()).thenReturn(true);
+ assertTrue("Compass should fade when facing north by default.", uiSettings.isCompassFadeWhenFacingNorth());
+ uiSettings.setCompassFadeFacingNorth(false);
+ when(compassView.isFadeCompassViewFacingNorth()).thenReturn(false);
+ assertFalse("Compass fading should be disabled", uiSettings.isCompassFadeWhenFacingNorth());
+ }
+
+ @Test
+ public void testLogoEnabled() {
+ uiSettings.setLogoEnabled(true);
+ assertEquals("Logo should be enabled", true, uiSettings.isLogoEnabled());
+ }
+
+ @Test
+ public void testLogoDisabled() {
+ when(logoView.getVisibility()).thenReturn(View.GONE);
+ uiSettings.setLogoEnabled(false);
+ assertEquals("Logo should be disabled", false, uiSettings.isLogoEnabled());
+ }
+
+ @Test
+ public void testLogoGravity() {
+ layoutParams.gravity = Gravity.END;
+ when(logoView.getLayoutParams()).thenReturn(layoutParams);
+ uiSettings.setLogoGravity(Gravity.END);
+ assertEquals("Logo gravity should be same", Gravity.END, uiSettings.getLogoGravity());
+ }
+
+ @Test
+ public void testLogoMargins() {
+ when(projection.getContentPadding()).thenReturn(new int[] {0, 0, 0, 0});
+ when(logoView.getLayoutParams()).thenReturn(layoutParams);
+ layoutParams.leftMargin = 1;
+ layoutParams.topMargin = 2;
+ layoutParams.rightMargin = 3;
+ layoutParams.bottomMargin = 4;
+ uiSettings.setLogoMargins(1, 2, 3, 4);
+ assertTrue("Compass margin left should be same", uiSettings.getLogoMarginLeft() == 1);
+ assertTrue("Compass margin top should be same", uiSettings.getLogoMarginTop() == 2);
+ assertTrue("Compass margin right should be same", uiSettings.getLogoMarginRight() == 3);
+ assertTrue("Compass margin bottom should be same", uiSettings.getLogoMarginBottom() == 4);
+ }
+
+ @Test
+ public void testAttributionEnabled() {
+ when(imageView.getVisibility()).thenReturn(View.VISIBLE);
+ uiSettings.setAttributionEnabled(true);
+ assertEquals("Attribution should be enabled", true, uiSettings.isAttributionEnabled());
+ }
+
+ @Test
+ public void testAttributionDisabled() {
+ when(imageView.getVisibility()).thenReturn(View.GONE);
+ uiSettings.setAttributionEnabled(false);
+ assertEquals("Attribution should be disabled", false, uiSettings.isAttributionEnabled());
+ }
+
+ @Test
+ public void testAttributionGravity() {
+ when(imageView.getLayoutParams()).thenReturn(layoutParams);
+ layoutParams.gravity = Gravity.END;
+ uiSettings.setAttributionGravity(Gravity.END);
+ assertEquals("Attribution gravity should be same", Gravity.END, uiSettings.getAttributionGravity());
+ }
+
+ @Test
+ public void testAttributionMargins() {
+ when(imageView.getLayoutParams()).thenReturn(layoutParams);
+ when(projection.getContentPadding()).thenReturn(new int[] {0, 0, 0, 0});
+ layoutParams.leftMargin = 1;
+ layoutParams.topMargin = 2;
+ layoutParams.rightMargin = 3;
+ layoutParams.bottomMargin = 4;
+ uiSettings.setAttributionMargins(1, 2, 3, 4);
+ assertTrue("Attribution margin left should be same", uiSettings.getAttributionMarginLeft() == 1);
+ assertTrue("Attribution margin top should be same", uiSettings.getAttributionMarginTop() == 2);
+ assertTrue("Attribution margin right should be same", uiSettings.getAttributionMarginRight() == 3);
+ assertTrue("Attribution margin bottom should be same", uiSettings.getAttributionMarginBottom() == 4);
+ }
+
+ @Test
+ public void testRotateGesturesEnabled() {
+ uiSettings.setRotateGesturesEnabled(true);
+ assertEquals("Rotate gesture should be enabled", true, uiSettings.isRotateGesturesEnabled());
+ }
+
+ @Test
+ public void testRotateGesturesDisabled() {
+ uiSettings.setRotateGesturesEnabled(false);
+ assertEquals("Rotate gesture should be disabled", false, uiSettings.isRotateGesturesEnabled());
+ }
+
+ @Test
+ public void testRotateGestureChange() {
+ assertEquals("Default state should be true", true, uiSettings.isRotateGestureChangeAllowed());
+ uiSettings.setRotateGestureChangeAllowed(false);
+ assertEquals("State should have been changed", false, uiSettings.isRotateGestureChangeAllowed());
+ }
+
+ @Test
+ public void testRotateGestureChangeAllowed() {
+ uiSettings.setRotateGesturesEnabled(false);
+ assertEquals("Rotate gesture should be false", false, uiSettings.isRotateGesturesEnabled());
+ uiSettings.setRotateGesturesEnabled(true);
+ assertEquals("Rotate gesture should be true", true, uiSettings.isRotateGesturesEnabled());
+ }
+
+ @Test
+ public void testRotateGestureChangeDisallowed() {
+ assertEquals("Rotate gesture should be true", true, uiSettings.isRotateGesturesEnabled());
+ uiSettings.setRotateGestureChangeAllowed(false);
+ uiSettings.setRotateGesturesEnabled(false);
+ assertEquals("Rotate gesture change should be ignored", true, uiSettings.isRotateGesturesEnabled());
+ }
+
+ @Test
+ public void testTiltGesturesEnabled() {
+ uiSettings.setTiltGesturesEnabled(true);
+ assertEquals("Tilt gesture should be enabled", true, uiSettings.isTiltGesturesEnabled());
+ }
+
+ @Test
+ public void testTiltGesturesDisabled() {
+ uiSettings.setTiltGesturesEnabled(false);
+ assertEquals("Tilt gesture should be disabled", false, uiSettings.isTiltGesturesEnabled());
+ }
+
+ @Test
+ public void testTiltGestureChange() {
+ assertEquals("Default state should be true", true, uiSettings.isTiltGestureChangeAllowed());
+ uiSettings.setTiltGestureChangeAllowed(false);
+ assertEquals("State should have been changed", false, uiSettings.isTiltGestureChangeAllowed());
+ }
+
+ @Test
+ public void testTiltGestureChangeAllowed() {
+ uiSettings.setTiltGesturesEnabled(false);
+ assertEquals("Tilt gesture should be false", false, uiSettings.isTiltGesturesEnabled());
+ uiSettings.setTiltGesturesEnabled(true);
+ assertEquals("Tilt gesture should be true", true, uiSettings.isTiltGesturesEnabled());
+ }
+
+ @Test
+ public void testTiltGestureChangeDisallowed() {
+ assertEquals("Tilt gesture should be true", true, uiSettings.isTiltGesturesEnabled());
+ uiSettings.setTiltGestureChangeAllowed(false);
+ uiSettings.setTiltGesturesEnabled(false);
+ assertEquals("Tilt gesture change should be ignored", true, uiSettings.isTiltGesturesEnabled());
+ }
+
+ @Test
+ public void testZoomGesturesEnabled() {
+ uiSettings.setZoomGesturesEnabled(true);
+ assertEquals("Zoom gesture should be enabled", true, uiSettings.isZoomGesturesEnabled());
+ }
+
+ @Test
+ public void testZoomGesturesDisabled() {
+ uiSettings.setZoomGesturesEnabled(false);
+ assertEquals("Zoom gesture should be disabled", false, uiSettings.isZoomGesturesEnabled());
+ }
+
+ @Test
+ public void testZoomGestureChange() {
+ assertEquals("Default state should be true", true, uiSettings.isZoomGestureChangeAllowed());
+ uiSettings.setZoomGestureChangeAllowed(false);
+ assertEquals("State should have been changed", false, uiSettings.isZoomGestureChangeAllowed());
+ }
+
+ @Test
+ public void testZoomGestureChangeAllowed() {
+ uiSettings.setZoomGesturesEnabled(false);
+ assertEquals("Zoom gesture should be false", false, uiSettings.isZoomGesturesEnabled());
+ uiSettings.setZoomGesturesEnabled(true);
+ assertEquals("Zoom gesture should be true", true, uiSettings.isZoomGesturesEnabled());
+ }
+
+ @Test
+ public void testZoomGestureChangeDisallowed() {
+ assertEquals("Zoom gesture should be true", true, uiSettings.isZoomGesturesEnabled());
+ uiSettings.setZoomGestureChangeAllowed(false);
+ uiSettings.setZoomGesturesEnabled(false);
+ assertEquals("Zooom gesture change should be ignored", true, uiSettings.isZoomGesturesEnabled());
+ }
+
+ @Test
+ public void testZoomControlsEnabled() {
+ uiSettings.setZoomControlsEnabled(true);
+ assertEquals("Zoom controls should be enabled", true, uiSettings.isZoomControlsEnabled());
+ }
+
+ @Test
+ public void testZoomControlsDisabled() {
+ uiSettings.setZoomControlsEnabled(false);
+ assertEquals("Zoom controls should be disabled", false, uiSettings.isZoomControlsEnabled());
+ }
+
+ @Test
+ public void testScrollGesturesEnabled() {
+ uiSettings.setScrollGesturesEnabled(true);
+ assertEquals("Scroll gesture should be enabled", true, uiSettings.isScrollGesturesEnabled());
+ }
+
+ @Test
+ public void testScrollGesturesDisabled() {
+ uiSettings.setScrollGesturesEnabled(false);
+ assertEquals("Scroll gesture should be disabled", false, uiSettings.isScrollGesturesEnabled());
+ }
+
+ @Test
+ public void testScrollGestureChange() {
+ assertEquals("Default state should be true", true, uiSettings.isScrollGestureChangeAllowed());
+ uiSettings.setScrollGestureChangeAllowed(false);
+ assertEquals("State should have been changed", false, uiSettings.isScrollGestureChangeAllowed());
+ }
+
+ @Test
+ public void testScrollGestureChangeAllowed() {
+ uiSettings.setScrollGesturesEnabled(false);
+ assertEquals("Scroll gesture should be false", false, uiSettings.isScrollGesturesEnabled());
+ uiSettings.setScrollGesturesEnabled(true);
+ assertEquals("Scroll gesture should be true", true, uiSettings.isScrollGesturesEnabled());
+ }
+
+ @Test
+ public void testScrollGestureChangeDisallowed() {
+ assertEquals("Scroll gesture should be true", true, uiSettings.isScrollGesturesEnabled());
+ uiSettings.setScrollGestureChangeAllowed(false);
+ uiSettings.setScrollGesturesEnabled(false);
+ assertEquals("Scroll gesture change should be ignored", true, uiSettings.isScrollGesturesEnabled());
+ }
+
+ @Test
+ public void testAllGesturesEnabled() {
+ uiSettings.setAllGesturesEnabled(true);
+ assertEquals("Rotate gesture should be enabled", true, uiSettings.isRotateGesturesEnabled());
+ assertEquals("Tilt gesture should be enabled", true, uiSettings.isTiltGesturesEnabled());
+ assertEquals("Zoom gesture should be enabled", true, uiSettings.isZoomGesturesEnabled());
+ assertEquals("Scroll gesture should be enabled", true, uiSettings.isScrollGesturesEnabled());
+ }
+
+ @Test
+ public void testAllGesturesDisabled() {
+ uiSettings.setAllGesturesEnabled(false);
+ assertEquals("Rotate gesture should be enabled", false, uiSettings.isRotateGesturesEnabled());
+ assertEquals("Tilt gesture should be disabled", false, uiSettings.isTiltGesturesEnabled());
+ assertEquals("Zoom gesture should be disabled", false, uiSettings.isZoomGesturesEnabled());
+ assertEquals("Scroll gesture should be disabled", false, uiSettings.isScrollGesturesEnabled());
+ }
} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettingsTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettingsTest.java
index fd70308931..c9ce19dc85 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettingsTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettingsTest.java
@@ -3,7 +3,9 @@ package com.mapbox.mapboxsdk.maps.widgets;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
-import com.mapbox.mapboxsdk.maps.MapView;
+import com.mapbox.mapboxsdk.maps.FocalPointChangeListener;
+import com.mapbox.mapboxsdk.maps.Projection;
+import com.mapbox.mapboxsdk.maps.TrackingSettings;
import org.junit.Before;
import org.junit.Test;
@@ -20,64 +22,85 @@ import static org.mockito.Mockito.when;
public class MyLocationViewSettingsTest {
- @InjectMocks
- MapView mMapView = mock(MapView.class);
-
- @InjectMocks
- MyLocationView myLocationView = mock(MyLocationView.class);
-
- MyLocationViewSettings locationViewSettings;
-
- @Before
- public void beforeTest() {
- locationViewSettings = new MyLocationViewSettings(mMapView, myLocationView);
- }
-
- @Test
- public void testSanity() {
- assertNotNull("should not be null", locationViewSettings);
- }
-
- @Test
- public void testForegroundDrawables() {
- Drawable foregroundDrawable = mock(Drawable.class);
- Drawable foregroundBearingDrawable = mock(Drawable.class);
- Drawable.ConstantState constantState = mock(Drawable.ConstantState.class);
- when(foregroundDrawable.getConstantState()).thenReturn(constantState);
- when(constantState.newDrawable()).thenReturn(foregroundDrawable);
- locationViewSettings.setForegroundDrawable(foregroundDrawable, foregroundBearingDrawable);
- assertEquals("foreground should match", foregroundDrawable, locationViewSettings.getForegroundDrawable());
- assertEquals("foreground bearing should match", foregroundBearingDrawable, locationViewSettings.getForegroundBearingDrawable());
- }
-
- @Test
- public void testBackgroundDrawable() {
- Drawable backgroundDrawable = mock(Drawable.class);
- int[] offset = new int[]{1, 2, 3, 4};
- locationViewSettings.setBackgroundDrawable(backgroundDrawable, offset);
- assertEquals("foreground should match", backgroundDrawable, locationViewSettings.getBackgroundDrawable());
- assertTrue("offsets should match", Arrays.equals(offset, locationViewSettings.getBackgroundOffset()));
- }
-
- @Test
- public void testForegroundTint() {
- int color = Color.RED;
- locationViewSettings.setForegroundTintColor(Color.RED);
- assertEquals("color should match", color, locationViewSettings.getForegroundTintColor());
- }
-
- @Test
- public void testBackgroundTint() {
- int color = Color.RED;
- locationViewSettings.setBackgroundTintColor(Color.RED);
- assertEquals("color should match", color, locationViewSettings.getBackgroundTintColor());
- }
-
- @Test
- public void testEnabled() {
- assertFalse("initial state should be false", locationViewSettings.isEnabled());
- locationViewSettings.setEnabled(true);
- assertTrue("state should be true", locationViewSettings.isEnabled());
- }
-
+ @InjectMocks
+ Projection projection = mock(Projection.class);
+
+ @InjectMocks
+ MyLocationView myLocationView = mock(MyLocationView.class);
+
+ @InjectMocks
+ TrackingSettings trackingSettings = mock(TrackingSettings.class);
+
+ @InjectMocks
+ FocalPointChangeListener focalPointChangeListener = mock(FocalPointChangeListener.class);
+
+ private MyLocationViewSettings locationViewSettings;
+
+ @Before
+ public void beforeTest() {
+ locationViewSettings = new MyLocationViewSettings(myLocationView, projection, focalPointChangeListener);
+ }
+
+ @Test
+ public void testSanity() {
+ assertNotNull("should not be null", locationViewSettings);
+ }
+
+ @Test
+ public void testForegroundDrawables() {
+ Drawable foregroundDrawable = mock(Drawable.class);
+ Drawable foregroundBearingDrawable = mock(Drawable.class);
+ Drawable.ConstantState constantState = mock(Drawable.ConstantState.class);
+ when(foregroundDrawable.getConstantState()).thenReturn(constantState);
+ when(constantState.newDrawable()).thenReturn(foregroundDrawable);
+ locationViewSettings.setForegroundDrawable(foregroundDrawable, foregroundBearingDrawable);
+ assertEquals("foreground should match", foregroundDrawable, locationViewSettings.getForegroundDrawable());
+ assertEquals("foreground bearing should match", foregroundBearingDrawable,
+ locationViewSettings.getForegroundBearingDrawable());
+ }
+
+ @Test
+ public void testBackgroundDrawable() {
+ Drawable backgroundDrawable = mock(Drawable.class);
+ int[] offset = new int[] {1, 2, 3, 4};
+ locationViewSettings.setBackgroundDrawable(backgroundDrawable, offset);
+ assertEquals("foreground should match", backgroundDrawable, locationViewSettings.getBackgroundDrawable());
+ assertTrue("offsets should match", Arrays.equals(offset, locationViewSettings.getBackgroundOffset()));
+ }
+
+ @Test
+ public void testForegroundTint() {
+ int color = Color.RED;
+ locationViewSettings.setForegroundTintColor(Color.RED);
+ assertEquals("color should match", color, locationViewSettings.getForegroundTintColor());
+ }
+
+ @Test
+ public void testForegroundTransparentTint() {
+ int color = Color.TRANSPARENT;
+ locationViewSettings.setForegroundTintColor(Color.TRANSPARENT);
+ assertEquals("color should match", color, locationViewSettings.getForegroundTintColor());
+ }
+
+ @Test
+ public void testBackgroundTint() {
+ int color = Color.RED;
+ locationViewSettings.setBackgroundTintColor(Color.RED);
+ assertEquals("color should match", color, locationViewSettings.getBackgroundTintColor());
+ }
+
+ @Test
+ public void testBackgroundTransparentTint() {
+ int color = Color.TRANSPARENT;
+ locationViewSettings.setBackgroundTintColor(Color.TRANSPARENT);
+ assertEquals("color should match", color, locationViewSettings.getBackgroundTintColor());
+ }
+
+ @Test
+ public void testEnabled() {
+ assertFalse("initial state should be false", locationViewSettings.isEnabled());
+ locationViewSettings.setEnabled(true);
+ assertTrue("state should be true", locationViewSettings.isEnabled());
+ }
}
+
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/style/layers/FilterTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/style/layers/FilterTest.java
index 3e312d3b0a..933bf05b39 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/style/layers/FilterTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/style/layers/FilterTest.java
@@ -2,89 +2,101 @@ package com.mapbox.mapboxsdk.style.layers;
import org.junit.Test;
-import static org.junit.Assert.*;
-import static com.mapbox.mapboxsdk.style.layers.Filter.*;
+import static com.mapbox.mapboxsdk.style.layers.Filter.all;
+import static com.mapbox.mapboxsdk.style.layers.Filter.any;
+import static com.mapbox.mapboxsdk.style.layers.Filter.eq;
+import static com.mapbox.mapboxsdk.style.layers.Filter.gt;
+import static com.mapbox.mapboxsdk.style.layers.Filter.gte;
+import static com.mapbox.mapboxsdk.style.layers.Filter.has;
+import static com.mapbox.mapboxsdk.style.layers.Filter.in;
+import static com.mapbox.mapboxsdk.style.layers.Filter.lt;
+import static com.mapbox.mapboxsdk.style.layers.Filter.lte;
+import static com.mapbox.mapboxsdk.style.layers.Filter.neq;
+import static com.mapbox.mapboxsdk.style.layers.Filter.none;
+import static com.mapbox.mapboxsdk.style.layers.Filter.notHas;
+import static com.mapbox.mapboxsdk.style.layers.Filter.notIn;
+import static org.junit.Assert.assertArrayEquals;
/**
* Tests for Filter
*/
public class FilterTest {
- @Test
- public void testAll() {
- assertArrayEquals(all().toArray(), new Object[]{"all"});
- assertArrayEquals(
- all(eq("key", 2), neq("key", 3)).toArray(),
- new Object[]{"all", new Object[]{"==", "key", 2}, new Object[]{"!=", "key", 3}}
- );
- }
-
- @Test
- public void testAny() {
- assertArrayEquals(any().toArray(), new Object[]{"any"});
- assertArrayEquals(
- any(eq("key", 2), neq("key", 3)).toArray(),
- new Object[]{"any", new Object[]{"==", "key", 2}, new Object[]{"!=", "key", 3}}
- );
- }
-
- @Test
- public void testNone() {
- assertArrayEquals(none().toArray(), new Object[]{"none"});
- assertArrayEquals(
- none(eq("key", 2), neq("key", 3)).toArray(),
- new Object[]{"none", new Object[]{"==", "key", 2}, new Object[]{"!=", "key", 3}}
- );
- }
-
- @Test
- public void testHas() {
- assertArrayEquals(has("key").toArray(), new Object[]{"has", "key"});
- }
-
- @Test
- public void testHasNot() {
- assertArrayEquals(notHas("key").toArray(), new Object[]{"!has", "key"});
- }
-
- @Test
- public void testEq() {
- assertArrayEquals(eq("key", 1).toArray(), new Object[]{"==", "key", 1});
-
- }
-
- @Test
- public void testNeq() {
- assertArrayEquals(neq("key", 1).toArray(), new Object[]{"!=", "key", 1});
- }
-
- @Test
- public void testGt() {
- assertArrayEquals(gt("key", 1).toArray(), new Object[]{">", "key", 1});
- }
-
- @Test
- public void testGte() {
- assertArrayEquals(gte("key", 1).toArray(), new Object[]{">=", "key", 1});
- }
-
- @Test
- public void testLt() {
- assertArrayEquals(lt("key", 1).toArray(), new Object[]{"<", "key", 1});
- }
-
- @Test
- public void testLte() {
- assertArrayEquals(lte("key", 1).toArray(), new Object[]{"<=", "key", 1});
- }
-
- @Test
- public void testIn() {
- assertArrayEquals(in("key", 1, 2, "Aap").toArray(), new Object[]{"in", "key", 1, 2, "Aap"});
- }
-
- @Test
- public void testNotIn() {
- assertArrayEquals(notIn("key", 1, 2, "Noot").toArray(), new Object[]{"!in", "key", 1, 2, "Noot"});
- }
+ @Test
+ public void testAll() {
+ assertArrayEquals(all().toArray(), new Object[] {"all"});
+ assertArrayEquals(
+ all(eq("key", 2), neq("key", 3)).toArray(),
+ new Object[] {"all", new Object[] {"==", "key", 2}, new Object[] {"!=", "key", 3}}
+ );
+ }
+
+ @Test
+ public void testAny() {
+ assertArrayEquals(any().toArray(), new Object[] {"any"});
+ assertArrayEquals(
+ any(eq("key", 2), neq("key", 3)).toArray(),
+ new Object[] {"any", new Object[] {"==", "key", 2}, new Object[] {"!=", "key", 3}}
+ );
+ }
+
+ @Test
+ public void testNone() {
+ assertArrayEquals(none().toArray(), new Object[] {"none"});
+ assertArrayEquals(
+ none(eq("key", 2), neq("key", 3)).toArray(),
+ new Object[] {"none", new Object[] {"==", "key", 2}, new Object[] {"!=", "key", 3}}
+ );
+ }
+
+ @Test
+ public void testHas() {
+ assertArrayEquals(has("key").toArray(), new Object[] {"has", "key"});
+ }
+
+ @Test
+ public void testHasNot() {
+ assertArrayEquals(notHas("key").toArray(), new Object[] {"!has", "key"});
+ }
+
+ @Test
+ public void testEq() {
+ assertArrayEquals(eq("key", 1).toArray(), new Object[] {"==", "key", 1});
+
+ }
+
+ @Test
+ public void testNeq() {
+ assertArrayEquals(neq("key", 1).toArray(), new Object[] {"!=", "key", 1});
+ }
+
+ @Test
+ public void testGt() {
+ assertArrayEquals(gt("key", 1).toArray(), new Object[] {">", "key", 1});
+ }
+
+ @Test
+ public void testGte() {
+ assertArrayEquals(gte("key", 1).toArray(), new Object[] {">=", "key", 1});
+ }
+
+ @Test
+ public void testLt() {
+ assertArrayEquals(lt("key", 1).toArray(), new Object[] {"<", "key", 1});
+ }
+
+ @Test
+ public void testLte() {
+ assertArrayEquals(lte("key", 1).toArray(), new Object[] {"<=", "key", 1});
+ }
+
+ @Test
+ public void testIn() {
+ assertArrayEquals(in("key", 1, 2, "Aap").toArray(), new Object[] {"in", "key", 1, 2, "Aap"});
+ }
+
+ @Test
+ public void testNotIn() {
+ assertArrayEquals(notIn("key", 1, 2, "Noot").toArray(), new Object[] {"!in", "key", 1, 2, "Noot"});
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/style/layers/FunctionTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/style/layers/FunctionTest.java
index 1106009ea8..4e82ca2318 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/style/layers/FunctionTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/style/layers/FunctionTest.java
@@ -2,28 +2,29 @@ package com.mapbox.mapboxsdk.style.layers;
import org.junit.Test;
-import static com.mapbox.mapboxsdk.style.layers.Function.*;
-import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*;
-
-import static org.junit.Assert.*;
+import static com.mapbox.mapboxsdk.style.layers.Function.stop;
+import static com.mapbox.mapboxsdk.style.layers.Function.zoom;
+import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.lineBlur;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertNotNull;
/**
* Tests Function
*/
public class FunctionTest {
- @Test
- public void testZoomFunction() {
- Function zoomF = zoom(
- stop(1f, lineBlur(1f)),
- stop(10f, lineBlur(20f))
- );
+ @Test
+ public void testZoomFunction() {
+ Function zoomF = zoom(
+ stop(1f, lineBlur(1f)),
+ stop(10f, lineBlur(20f))
+ );
- assertNotNull(zoomF.toValueObject());
- assertArrayEquals(
- new Object[]{new Object[]{1f, 1f}, new Object[]{10f, 20f}},
- (Object[]) zoomF.toValueObject().get("stops")
- );
- }
+ assertNotNull(zoomF.toValueObject());
+ assertArrayEquals(
+ new Object[] {new Object[] {1f, 1f}, new Object[] {10f, 20f}},
+ (Object[]) zoomF.toValueObject().get("stops")
+ );
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/telemetry/HttpTransportTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/telemetry/HttpTransportTest.java
index 8be0d2c663..94a6dc2194 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/telemetry/HttpTransportTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/telemetry/HttpTransportTest.java
@@ -1,17 +1,20 @@
package com.mapbox.mapboxsdk.telemetry;
import org.junit.Test;
+
import okhttp3.internal.Util;
+
import static junit.framework.Assert.assertEquals;
public class HttpTransportTest {
- @Test
- public void testNonAsciiUserAgent() {
+ @Test
+ public void testNonAsciiUserAgent() {
- final String swedishUserAgent = "Sveriges Fjäll/1.0/1 MapboxEventsAndroid/4.0.0-SNAPSHOT";
- final String asciiVersion = "Sveriges Fj?ll/1.0/1 MapboxEventsAndroid/4.0.0-SNAPSHOT";
+ final String swedishUserAgent = "Sveriges Fjäll/1.0/1 MapboxEventsAndroid/4.0.0-SNAPSHOT";
+ final String asciiVersion = "Sveriges Fj?ll/1.0/1 MapboxEventsAndroid/4.0.0-SNAPSHOT";
- assertEquals("asciiVersion and swedishUserAgent should match", asciiVersion, Util.toHumanReadableAscii(swedishUserAgent));
- }
+ assertEquals("asciiVersion and swedishUserAgent should match", asciiVersion,
+ Util.toHumanReadableAscii(swedishUserAgent));
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/utils/MockParcel.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/utils/MockParcel.java
index aa0a4edd13..dd4c7b25ee 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/utils/MockParcel.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/utils/MockParcel.java
@@ -13,7 +13,6 @@ import java.util.ArrayList;
import java.util.List;
import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertNotNull;
import static org.junit.Assert.assertArrayEquals;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyByte;
@@ -29,227 +28,227 @@ import static org.mockito.Mockito.when;
public class MockParcel {
- public static Parcelable obtain(@NonNull Parcelable object) {
- return obtain(object, 0);
+ public static Parcelable obtain(@NonNull Parcelable object) {
+ return obtain(object, 0);
+ }
+
+ public static Parcelable obtain(@NonNull Parcelable object, int describeContentsValue) {
+ testDescribeContents(object, describeContentsValue);
+ testParcelableArray(object);
+ return testParcelable(object);
+ }
+
+ public static Parcelable testParcelable(@NonNull Parcelable object) {
+ Parcel parcel = ParcelMocker.obtain(object);
+ object.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+
+ try {
+ Field field = object.getClass().getDeclaredField("CREATOR");
+ field.setAccessible(true);
+ Class<?> creatorClass = field.getType();
+ Object fieldValue = field.get(object);
+ Method myMethod = creatorClass.getDeclaredMethod("createFromParcel", Parcel.class);
+ return (Parcelable) myMethod.invoke(fieldValue, parcel);
+ } catch (Exception exception) {
+ return null;
}
+ }
+
+ public static void testParcelableArray(@NonNull Parcelable object) {
+ Parcelable[] objects = new Parcelable[] {object};
+ Parcel parcel = ParcelMocker.obtain(objects);
+ parcel.writeParcelableArray(objects, 0);
+ parcel.setDataPosition(0);
+ Parcelable[] parcelableArray = parcel.readParcelableArray(object.getClass().getClassLoader());
+ assertArrayEquals("parcel should match initial object", objects, parcelableArray);
+ }
+
+ public static void testDescribeContents(@NonNull Parcelable object, int describeContentsValue) {
+ if (describeContentsValue == 0) {
+ assertEquals("\nExpecting a describeContents() value of 0 for a " + object.getClass().getSimpleName()
+ + " instance." + "\nYou can provide a different value for describeContentValue through the obtain method.",
+ 0,
+ object.describeContents());
+ } else {
+ assertEquals("Expecting a describeContents() value of " + describeContentsValue,
+ describeContentsValue,
+ object.describeContents());
+ }
+ }
+
+ private static class ParcelMocker {
- public static Parcelable obtain(@NonNull Parcelable object, int describeContentsValue) {
- testDescribeContents(object, describeContentsValue);
- testParcelableArray(object);
- return testParcelable(object);
+ public static Parcel obtain(@NonNull Parcelable target) {
+ Parcel parcel = new ParcelMocker(target).getMockedParcel();
+ target.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+ return parcel;
}
- public static Parcelable testParcelable(@NonNull Parcelable object) {
- Parcel parcel = ParcelMocker.obtain(object);
- object.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
-
- try {
- Field field = object.getClass().getDeclaredField("CREATOR");
- field.setAccessible(true);
- Class<?> creatorClass = field.getType();
- Object fieldValue = field.get(object);
- Method myMethod = creatorClass.getDeclaredMethod("createFromParcel", Parcel.class);
- return (Parcelable) myMethod.invoke(fieldValue, parcel);
- } catch (Exception e) {
- return null;
- }
+ public static Parcel obtain(@NonNull Parcelable[] targets) {
+ if (targets.length == 0) {
+ throw new IllegalArgumentException("The passed argument may not be empty");
+ }
+ Parcel parcel = new ParcelMocker(targets[0]).getMockedParcel();
+ parcel.writeParcelableArray(targets, 0);
+ parcel.setDataPosition(0);
+ return parcel;
}
- public static void testParcelableArray(@NonNull Parcelable object) {
- Parcelable[] objects = new Parcelable[]{object};
- Parcel parcel = ParcelMocker.obtain(objects);
- parcel.writeParcelableArray(objects, 0);
- parcel.setDataPosition(0);
- Parcelable[] parcelableArray = parcel.readParcelableArray(object.getClass().getClassLoader());
- assertArrayEquals("parcel should match initial object", objects, parcelableArray);
+ private List<Object> objects;
+ private Object object;
+ private Parcel mockedParcel;
+ private int position;
+
+ private ParcelMocker(Object o) {
+ this.object = o;
+ mockedParcel = mock(Parcel.class);
+ objects = new ArrayList<>();
+ setupMock();
}
- public static void testDescribeContents(@NonNull Parcelable object, int describeContentsValue) {
- if (describeContentsValue == 0) {
- assertEquals("\nExpecting a describeContents() value of 0 for a " + object.getClass().getSimpleName() + " instance." +
- "\nYou can provide a different value for describeContentValue through the obtain method.",
- 0,
- object.describeContents());
- } else {
- assertEquals("Expecting a describeContents() value of " + describeContentsValue,
- describeContentsValue,
- object.describeContents());
- }
+ private Parcel getMockedParcel() {
+ return mockedParcel;
}
- private static class ParcelMocker {
+ private void setupMock() {
+ setupWrites();
+ setupReads();
+ setupOthers();
+ }
- public static Parcel obtain(@NonNull Parcelable target) {
- Parcel parcel = new ParcelMocker(target).getMockedParcel();
- target.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
- return parcel;
+ private void setupWrites() {
+ Answer<Void> writeValueAnswer = new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) throws Throwable {
+ Object parameter = invocation.getArguments()[0];
+ objects.add(parameter);
+ return null;
}
-
- public static Parcel obtain(@NonNull Parcelable[] targets) {
- if (targets.length == 0) {
- throw new IllegalArgumentException("The passed argument may not be empty");
+ };
+ Answer<Void> writeArrayAnswer = new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) throws Throwable {
+ Object[] parameters = (Object[]) invocation.getArguments()[0];
+ objects.add(parameters.length);
+ for (Object o : parameters) {
+ objects.add(o);
+ }
+ return null;
+ }
+ };
+ Answer<Void> writeIntArrayAnswer = new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) throws Throwable {
+ int[] parameters = (int[]) invocation.getArguments()[0];
+ if (parameters != null) {
+ objects.add(parameters.length);
+ for (Object o : parameters) {
+ objects.add(o);
}
- Parcel parcel = new ParcelMocker(targets[0]).getMockedParcel();
- parcel.writeParcelableArray(targets, 0);
- parcel.setDataPosition(0);
- return parcel;
+ } else {
+ objects.add(-1);
+ }
+ return null;
}
+ };
+ doAnswer(writeValueAnswer).when(mockedParcel).writeByte(anyByte());
+ doAnswer(writeValueAnswer).when(mockedParcel).writeLong(anyLong());
+ doAnswer(writeValueAnswer).when(mockedParcel).writeString(anyString());
+ doAnswer(writeValueAnswer).when(mockedParcel).writeInt(anyInt());
+ doAnswer(writeIntArrayAnswer).when(mockedParcel).writeIntArray(any(int[].class));
+ doAnswer(writeValueAnswer).when(mockedParcel).writeDouble(anyDouble());
+ doAnswer(writeValueAnswer).when(mockedParcel).writeFloat(anyFloat());
+ doAnswer(writeValueAnswer).when(mockedParcel).writeParcelable(any(Parcelable.class), eq(0));
+ doAnswer(writeArrayAnswer).when(mockedParcel).writeParcelableArray(any(Parcelable[].class), eq(0));
+ }
- private List<Object> objects;
- private Object object;
- private Parcel mockedParcel;
- private int position;
-
- private ParcelMocker(Object o) {
- this.object = o;
- mockedParcel = mock(Parcel.class);
- objects = new ArrayList<>();
- setupMock();
+ private void setupReads() {
+ when(mockedParcel.readInt()).then(new Answer<Integer>() {
+ @Override
+ public Integer answer(InvocationOnMock invocation) throws Throwable {
+ return (Integer) objects.get(position++);
}
-
- private Parcel getMockedParcel() {
- return mockedParcel;
+ });
+ when(mockedParcel.readByte()).thenAnswer(new Answer<Byte>() {
+ @Override
+ public Byte answer(InvocationOnMock invocation) throws Throwable {
+ return (Byte) objects.get(position++);
}
-
- private void setupMock() {
- setupWrites();
- setupReads();
- setupOthers();
+ });
+ when(mockedParcel.readLong()).thenAnswer(new Answer<Long>() {
+ @Override
+ public Long answer(InvocationOnMock invocation) throws Throwable {
+ return (Long) objects.get(position++);
}
-
- private void setupWrites() {
- Answer<Void> writeValueAnswer = new Answer<Void>() {
- @Override
- public Void answer(InvocationOnMock invocation) throws Throwable {
- Object parameter = invocation.getArguments()[0];
- objects.add(parameter);
- return null;
- }
- };
- Answer<Void> writeArrayAnswer = new Answer<Void>() {
- @Override
- public Void answer(InvocationOnMock invocation) throws Throwable {
- Object[] parameters = (Object[]) invocation.getArguments()[0];
- objects.add(parameters.length);
- for (Object o : parameters) {
- objects.add(o);
- }
- return null;
- }
- };
- Answer<Void> writeIntArrayAnswer = new Answer<Void>() {
- @Override
- public Void answer(InvocationOnMock invocation) throws Throwable {
- int[] parameters = (int[]) invocation.getArguments()[0];
- if (parameters != null) {
- objects.add(parameters.length);
- for (Object o : parameters) {
- objects.add(o);
- }
- } else {
- objects.add(-1);
- }
- return null;
- }
- };
- doAnswer(writeValueAnswer).when(mockedParcel).writeByte(anyByte());
- doAnswer(writeValueAnswer).when(mockedParcel).writeLong(anyLong());
- doAnswer(writeValueAnswer).when(mockedParcel).writeString(anyString());
- doAnswer(writeValueAnswer).when(mockedParcel).writeInt(anyInt());
- doAnswer(writeIntArrayAnswer).when(mockedParcel).writeIntArray(any(int[].class));
- doAnswer(writeValueAnswer).when(mockedParcel).writeDouble(anyDouble());
- doAnswer(writeValueAnswer).when(mockedParcel).writeFloat(anyFloat());
- doAnswer(writeValueAnswer).when(mockedParcel).writeParcelable(any(Parcelable.class), eq(0));
- doAnswer(writeArrayAnswer).when(mockedParcel).writeParcelableArray(any(Parcelable[].class), eq(0));
+ });
+ when(mockedParcel.readString()).thenAnswer(new Answer<String>() {
+ @Override
+ public String answer(InvocationOnMock invocation) throws Throwable {
+ return (String) objects.get(position++);
+ }
+ });
+ when(mockedParcel.readDouble()).thenAnswer(new Answer<Double>() {
+ @Override
+ public Double answer(InvocationOnMock invocation) throws Throwable {
+ return (Double) objects.get(position++);
+ }
+ });
+ when(mockedParcel.readFloat()).thenAnswer(new Answer<Float>() {
+ @Override
+ public Float answer(InvocationOnMock invocation) throws Throwable {
+ return (Float) objects.get(position++);
}
+ });
+ when(mockedParcel.readParcelable(Parcelable.class.getClassLoader())).thenAnswer(new Answer<Parcelable>() {
+ @Override
+ public Parcelable answer(InvocationOnMock invocation) throws Throwable {
+ return (Parcelable) objects.get(position++);
+ }
+ });
+ when(mockedParcel.readParcelableArray(Parcelable.class.getClassLoader())).thenAnswer(new Answer<Object[]>() {
+ @Override
+ public Object[] answer(InvocationOnMock invocation) throws Throwable {
+ int size = (Integer) objects.get(position++);
+ Field field = object.getClass().getDeclaredField("CREATOR");
+ field.setAccessible(true);
+ Class<?> creatorClass = field.getType();
+ Object fieldValue = field.get(object);
+ Method myMethod = creatorClass.getDeclaredMethod("newArray", int.class);
+ Object[] array = (Object[]) myMethod.invoke(fieldValue, size);
+ for (int i = 0; i < size; i++) {
+ array[i] = objects.get(position++);
+ }
+ return array;
+ }
+ });
+ when(mockedParcel.createIntArray()).then(new Answer<int[]>() {
+ @Override
+ public int[] answer(InvocationOnMock invocation) throws Throwable {
+ int size = (Integer) objects.get(position++);
+ if (size == -1) {
+ return null;
+ }
- private void setupReads() {
- when(mockedParcel.readInt()).then(new Answer<Integer>() {
- @Override
- public Integer answer(InvocationOnMock invocation) throws Throwable {
- return (Integer) objects.get(position++);
- }
- });
- when(mockedParcel.readByte()).thenAnswer(new Answer<Byte>() {
- @Override
- public Byte answer(InvocationOnMock invocation) throws Throwable {
- return (Byte) objects.get(position++);
- }
- });
- when(mockedParcel.readLong()).thenAnswer(new Answer<Long>() {
- @Override
- public Long answer(InvocationOnMock invocation) throws Throwable {
- return (Long) objects.get(position++);
- }
- });
- when(mockedParcel.readString()).thenAnswer(new Answer<String>() {
- @Override
- public String answer(InvocationOnMock invocation) throws Throwable {
- return (String) objects.get(position++);
- }
- });
- when(mockedParcel.readDouble()).thenAnswer(new Answer<Double>() {
- @Override
- public Double answer(InvocationOnMock invocation) throws Throwable {
- return (Double) objects.get(position++);
- }
- });
- when(mockedParcel.readFloat()).thenAnswer(new Answer<Float>() {
- @Override
- public Float answer(InvocationOnMock invocation) throws Throwable {
- return (Float) objects.get(position++);
- }
- });
- when(mockedParcel.readParcelable(Parcelable.class.getClassLoader())).thenAnswer(new Answer<Parcelable>() {
- @Override
- public Parcelable answer(InvocationOnMock invocation) throws Throwable {
- return (Parcelable) objects.get(position++);
- }
- });
- when(mockedParcel.readParcelableArray(Parcelable.class.getClassLoader())).thenAnswer(new Answer<Object[]>() {
- @Override
- public Object[] answer(InvocationOnMock invocation) throws Throwable {
- int size = (Integer) objects.get(position++);
- Field field = object.getClass().getDeclaredField("CREATOR");
- field.setAccessible(true);
- Class<?> creatorClass = field.getType();
- Object fieldValue = field.get(object);
- Method myMethod = creatorClass.getDeclaredMethod("newArray", int.class);
- Object[] array = (Object[]) myMethod.invoke(fieldValue, size);
- for (int i = 0; i < size; i++) {
- array[i] = objects.get(position++);
- }
- return array;
- }
- });
- when(mockedParcel.createIntArray()).then(new Answer<int[]>() {
- @Override
- public int[] answer(InvocationOnMock invocation) throws Throwable {
- int size = (Integer) objects.get(position++);
- if (size == -1) {
- return null;
- }
-
- int[] array = new int[size];
- for (int i = 0; i < size; i++) {
- array[i] = (Integer) objects.get(position++);
- }
-
- return array;
- }
- });
+ int[] array = new int[size];
+ for (int i = 0; i < size; i++) {
+ array[i] = (Integer) objects.get(position++);
+ }
+
+ return array;
}
+ });
+ }
- private void setupOthers() {
- doAnswer(new Answer<Void>() {
- @Override
- public Void answer(InvocationOnMock invocation) throws Throwable {
- position = ((Integer) invocation.getArguments()[0]);
- return null;
- }
- }).when(mockedParcel).setDataPosition(anyInt());
+ private void setupOthers() {
+ doAnswer(new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) throws Throwable {
+ position = ((Integer) invocation.getArguments()[0]);
+ return null;
}
+ }).when(mockedParcel).setDataPosition(anyInt());
}
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/platform/android/MapboxGLAndroidSDKTestApp/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
new file mode 100644
index 0000000000..ca6ee9cea8
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
@@ -0,0 +1 @@
+mock-maker-inline \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/update_icons.sh b/platform/android/MapboxGLAndroidSDKTestApp/update_icons.sh
deleted file mode 100755
index ef5213d4f9..0000000000
--- a/platform/android/MapboxGLAndroidSDKTestApp/update_icons.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/bash
-
-if [[ -z `which iconoblast` ]]; then
- echo "Requires https://github.com/mapbox/iconoblast"
- exit 1
-fi
-
-commit=`git rev-parse --short HEAD`
-branch=`git rev-parse --abbrev-ref HEAD`
-repo=`git remote show origin | grep 'Fetch URL' | sed -e 's/.*github\.com:mapbox\///' -e 's/\.git$//' -e 's/^mapbox-//'`
-
-pwd=`pwd`
-cd src/main/res
-for folder in `find . -maxdepth 1 -type d -name drawable-\*`
-do
- cd ${folder}
- cp icon.png icon_burned.png
- iconoblast icon_burned.png $commit $branch $repo
- cd ..
-done
-cd ${pwd}
diff --git a/platform/android/MapboxGLAndroidSDKWearTestApp/build.gradle b/platform/android/MapboxGLAndroidSDKWearTestApp/build.gradle
index 6bd1fac322..29056e7685 100644
--- a/platform/android/MapboxGLAndroidSDKWearTestApp/build.gradle
+++ b/platform/android/MapboxGLAndroidSDKWearTestApp/build.gradle
@@ -1,34 +1,15 @@
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"
+ compileSdkVersion 25
+ buildToolsVersion "25.0.0"
defaultConfig {
applicationId "com.mapbox.mapboxsdk.testapp"
minSdkVersion 21
- targetSdkVersion 24
- versionCode 1
- versionName "1.0"
+ targetSdkVersion 25
+ versionCode 11
+ versionName "5.0.0"
}
buildTypes {
@@ -44,14 +25,16 @@ dependencies {
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'
-
+ // Wear
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'
+
+ // Leak Canary
+ 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'
}
-apply from: '../checkstyle.gradle' \ No newline at end of file
+apply from: 'gradle-config.gradle'
+apply from: 'gradle-checkstyle.gradle' \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKWearTestApp/gradle-checkstyle.gradle b/platform/android/MapboxGLAndroidSDKWearTestApp/gradle-checkstyle.gradle
new file mode 100644
index 0000000000..cdcc7f1e23
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKWearTestApp/gradle-checkstyle.gradle
@@ -0,0 +1,17 @@
+apply plugin: 'checkstyle'
+
+checkstyle {
+ toolVersion = "7.1.1" // 7.3
+ configFile = "../checkstyle.xml" as File
+}
+
+task checkstyle(type: Checkstyle) {
+ description 'Checks if the code adheres to coding standards'
+ group 'verification'
+ configFile file("../checkstyle.xml")
+ source 'src'
+ include '**/*.java'
+ exclude '**/gen/**'
+ classpath = files()
+ ignoreFailures = false
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKWearTestApp/gradle-config.gradle b/platform/android/MapboxGLAndroidSDKWearTestApp/gradle-config.gradle
new file mode 100644
index 0000000000..fac47cb2a9
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKWearTestApp/gradle-config.gradle
@@ -0,0 +1,22 @@
+//
+// Configuration file for gradle build execution.
+//
+
+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')
+} \ 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
index 390c7370cb..cbbdcb8493 100644
--- a/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/MapboxApplication.java
+++ b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/java/com/mapbox/weartestapp/MapboxApplication.java
@@ -3,7 +3,7 @@ package com.mapbox.weartestapp;
import android.app.Application;
import android.os.StrictMode;
-import com.mapbox.mapboxsdk.MapboxAccountManager;
+import com.mapbox.mapboxsdk.Mapbox;
import com.squareup.leakcanary.LeakCanary;
public class MapboxApplication extends Application {
@@ -11,7 +11,7 @@ public class MapboxApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
- MapboxAccountManager.start(getApplicationContext(), getString(R.string.mapbox_access_token));
+ Mapbox.getInstance(getApplicationContext(), getString(R.string.mapbox_access_token));
LeakCanary.install(this);
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
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
index 7f2caa4d67..2a8bf9396f 100644
--- 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
@@ -15,7 +15,6 @@ 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;
@@ -32,7 +31,8 @@ public class FeatureOverviewActivity extends WearableActivity implements Feature
wearableRecyclerView.setOffsettingHelper(offsettingHelper);
exampleItemModels = new ArrayList<>();
- exampleItemModels.add(new Feature(R.string.activity_simple_mapview_title, new Intent(FeatureOverviewActivity.this, SimpleMapViewActivity.class)));
+ 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);
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
index d6f3ccd410..b24b626fe6 100644
--- 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
@@ -29,18 +29,30 @@ public class SimpleMapViewActivity extends WearableActivity {
}
@Override
- public void onResume() {
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ protected void onResume() {
super.onResume();
mapView.onResume();
}
@Override
- public void onPause() {
+ protected void onPause() {
super.onPause();
mapView.onPause();
}
@Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ }
+
+ @Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
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
index 2c1e5fe2eb..948f92e30b 100644
--- a/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/layout/activity_simple_mapview.xml
+++ b/platform/android/MapboxGLAndroidSDKWearTestApp/src/main/res/layout/activity_simple_mapview.xml
@@ -13,10 +13,10 @@
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"/>
+ mapbox:mapbox_cameraTargetLat="40.73581"
+ mapbox:mapbox_cameraTargetLng="-73.99155"
+ mapbox:mapbox_styleUrl="mapbox://styles/mapbox/streets-v9"
+ mapbox:mapbox_cameraZoom="11"
+ mapbox:mapbox_uiZoomControls="false"/>
</FrameLayout> \ No newline at end of file
diff --git a/platform/android/bitrise.yml b/platform/android/bitrise.yml
index c168a9a6d6..bffcd95b65 100644
--- a/platform/android/bitrise.yml
+++ b/platform/android/bitrise.yml
@@ -6,6 +6,8 @@ trigger_map:
workflow: devicefarmUpload
- pattern: scheduled
workflow: scheduled
+- pattern: nightly-release
+ workflow: nightly-release
- pattern: "*"
workflow: primary
workflows:
@@ -35,6 +37,14 @@ workflows:
curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -
sudo apt-get install -y pkg-config nodejs cmake
- script:
+ title: Run Checkstyle
+ run_if: '{{enveq "SKIPCI" "false"}}'
+ inputs:
+ - content: |-
+ #!/bin/bash
+ # Run checkstyle gradle task on all modules
+ cd platform/android && ./gradlew checkstyle
+ - script:
title: Configure Google Cloud SDK
run_if: '{{enveq "SKIPCI" "false"}}'
inputs:
@@ -50,10 +60,10 @@ workflows:
export CLOUD_SDK_REPO="cloud-sdk-$(lsb_release -c -s)"
echo "deb http://packages.cloud.google.com/apt $CLOUD_SDK_REPO main" | sudo tee /etc/apt/sources.list.d/google-cloud-sdk.list
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
- sudo apt-get update && sudo apt-get install google-cloud-sdk
+ sudo apt-get update && sudo apt-get install -y google-cloud-sdk
# Get authentication secret
- echo "Downloading Google Cloud authnetication:"
+ echo "Downloading Google Cloud authentication:"
wget -O secret.json "$BITRISEIO_GCLOUD_SERVICE_ACCOUNT_JSON_URL"
- script:
title: Build libmapbox-gl.so for armeabi-v7a
@@ -65,13 +75,21 @@ workflows:
export BUILDTYPE=Debug
make android-lib-arm-v7
- script:
+ title: Compile Core tests
+ run_if: '{{enveq "SKIPCI" "false"}}'
+ inputs:
+ - content: |-
+ #!/bin/bash
+ echo "Compiling core tests:"
+ BUILDTYPE=Debug make android-test-lib-arm-v7
+ - script:
title: Run local JVM Unit tests
run_if: '{{enveq "SKIPCI" "false"}}'
inputs:
- content: |-
#!/bin/bash
echo "Running unit tests from testapp/src/test:"
- make android-test
+ make run-android-unit-test
- script:
title: Generate Espresso sanity tests
run_if: '{{enveq "SKIPCI" "false"}}'
@@ -79,7 +97,7 @@ workflows:
- content: |-
#!/bin/bash
echo "Generate these test locally by executing:"
- make android-generate-test
+ make test-code-android
- script:
title: Run Firebase instrumentation tests
run_if: '{{enveq "SKIPCI" "false"}}'
@@ -90,13 +108,12 @@ workflows:
wget -O platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/developer-config.xml "$BITRISEIO_TEST_ACCESS_TOKEN_UI_TEST_URL"
echo "Build seperate test apk:"
- make android-test-apk
+ make android-ui-test
echo "Run tests on firebase:"
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 --test-targets "class com.mapbox.mapboxsdk.testapp.camera.RotateActivityTest"
- echo "The details are made available as a zipped build artefact on top of this page."
+ 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.apk --device-ids shamu --os-version-ids 22 --locales en --orientations portrait --timeout 15m
- script:
title: Download Firebase results
run_if: '{{enveq "SKIPCI" "false"}}'
@@ -104,10 +121,12 @@ workflows:
inputs:
- content: |-
#!/bin/bash
+ mkdir -p platform/android/MapboxGLAndroidSDKTestApp/build/outputs/apk
+
echo "The details from Firebase will be downloaded, zipped and attached as a build artefact."
testUri=$(gsutil ls "gs://test-lab-wrrntqk05p31w-h3y1qk44vuunw/" | tail -n1)
echo "Downloading from : "$testUri
- cd platform/android/MapboxGLAndroidSDKTestApp/build/outputs/apk && gsutil -m cp -R -Z $testUri .
+ gsutil -m cp -R -Z $testUri platform/android/MapboxGLAndroidSDKTestApp/build/outputs/apk
echo "Try running ndk-stack on downloaded logcat to symbolicate the stacktraces:"
find platform/android/MapboxGLAndroidSDKTestApp/build/outputs/apk -type f -name "logcat" -print0 | xargs -0 -Imylogcat mv -i mylogcat ./
@@ -223,7 +242,7 @@ workflows:
- content: |-
#!/bin/bash
echo "Generate these test locally by executing:"
- make android-generate-test
+ make test-code-android
- script:
title: Run AWS Device Farm instrumentation tests
inputs:
@@ -242,3 +261,35 @@ workflows:
- message_on_error: '<${BITRISE_BUILD_URL}|Build #${BITRISE_BUILD_NUMBER}> for devicefarmUpload failed'
- icon_url: https://bitrise-public-content-production.s3.amazonaws.com/slack/bitrise-slack-icon-128.png
- icon_url_on_error: https://bitrise-public-content-production.s3.amazonaws.com/slack/bitrise-slack-error-icon-128.png
+ nightly-release:
+ steps:
+ - script:
+ title: Configure GL-native build environement
+ inputs:
+ - content: |-
+ #!/bin/bash
+ set -eu -o pipefail
+ curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -
+ sudo apt-get install -y pkg-config nodejs cmake
+ - script:
+ title: Configure AWS-CLI
+ inputs:
+ - content: |-
+ #!/bin/bash
+ apt-get install -y python-pip python-dev build-essential
+ pip install awscli
+ - script:
+ title: Build release
+ inputs:
+ - content: |-
+ #!/bin/bash
+ echo "Compile libmapbox-gl.so for all supportd abi's:"
+ export BUILDTYPE=Release
+ make apackage
+ - script:
+ title: Log metrics
+ inputs:
+ - content: |-
+ #!/bin/bash
+ echo "Log binary size metrics to AWS CloudWatch:"
+ CLOUDWATCH=true platform/android/scripts/metrics.sh
diff --git a/platform/android/build.gradle b/platform/android/build.gradle
index aed761c837..9ba9210af4 100644
--- a/platform/android/build.gradle
+++ b/platform/android/build.gradle
@@ -4,8 +4,7 @@ buildscript {
maven { url 'https://jitpack.io' }
}
dependencies {
- classpath 'com.android.tools.build:gradle:2.1.3'
- classpath 'com.github.JakeWharton:sdk-manager-plugin:220bf7a88a7072df3ed16dc8466fb144f2817070'
+ classpath 'com.android.tools.build:gradle:2.2.3'
classpath 'com.amazonaws:aws-devicefarm-gradle-plugin:1.2'
classpath 'com.stanfy.spoon:spoon-gradle-plugin:1.2.1'
}
@@ -18,8 +17,6 @@ allprojects {
}
}
-apply from: 'checkstyle.gradle'
-
task wrapper(type: Wrapper) {
- gradleVersion = '2.14.1'
+ gradleVersion = '3.2.1'
}
diff --git a/platform/android/checkstyle.gradle b/platform/android/checkstyle.gradle
deleted file mode 100644
index 69f7f41ff4..0000000000
--- a/platform/android/checkstyle.gradle
+++ /dev/null
@@ -1,16 +0,0 @@
-apply plugin: 'checkstyle'
-
-checkstyle.toolVersion = '7.1'
-
-task checkstyle(type: Checkstyle) {
- description 'Checks if the code adheres to coding standards'
- group 'verification'
-
- configFile = new File(rootDir, "checkstyle.xml")
- source 'src'
- include '**/*.java'
- exclude '**/gen/**'
-
- classpath = files()
- ignoreFailures = false
-}
diff --git a/platform/android/checkstyle.xml b/platform/android/checkstyle.xml
index 3b4fba7b2e..6a429858a6 100644
--- a/platform/android/checkstyle.xml
+++ b/platform/android/checkstyle.xml
@@ -6,8 +6,8 @@
<module name = "Checker">
<property name="charset" value="UTF-8"/>
- <!-- <property name="severity" value="error"/> -->
- <property name="severity" value="warning"/>
+ <property name="severity" value="error"/>
+ <!-- <property name="severity" value="warning"/> -->
<property name="fileExtensions" value="java, properties, xml"/>
<!-- Checks for whitespace -->
@@ -72,7 +72,7 @@
<module name="OneStatementPerLine"/>
<module name="MultipleVariableDeclarations"/>
<module name="ArrayTypeStyle"/>
- <module name="MissingSwitchDefault"/>
+ <!--<module name="MissingSwitchDefault"/>-->
<module name="FallThrough"/>
<module name="UpperEll"/>
<module name="ModifierOrder"/>
@@ -92,32 +92,32 @@
<message key="name.invalidPattern"
value="Package name ''{0}'' must match pattern ''{1}''."/>
</module>
- <module name="TypeName">
+ <!-- <module name="TypeName">
<message key="name.invalidPattern"
value="Type name ''{0}'' must match pattern ''{1}''."/>
- </module>
- <module name="MemberName">
+ </module> -->
+ <!--<module name="MemberName">
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$"/>
<message key="name.invalidPattern"
value="Member name ''{0}'' must match pattern ''{1}''."/>
- </module>
- <module name="ParameterName">
+ </module>-->
+ <!-- <module name="ParameterName">
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$"/>
<message key="name.invalidPattern"
value="Parameter name ''{0}'' must match pattern ''{1}''."/>
- </module>
+ </module> -->
<module name="CatchParameterName">
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$"/>
<message key="name.invalidPattern"
value="Catch parameter name ''{0}'' must match pattern ''{1}''."/>
</module>
- <module name="LocalVariableName">
+ <!-- <module name="LocalVariableName">
<property name="tokens" value="VARIABLE_DEF"/>
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$"/>
<property name="allowOneCharVarInForLoop" value="true"/>
<message key="name.invalidPattern"
value="Local variable name ''{0}'' must match pattern ''{1}''."/>
- </module>
+ </module> -->
<module name="ClassTypeParameterName">
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
<message key="name.invalidPattern"
@@ -133,7 +133,7 @@
<message key="name.invalidPattern"
value="Interface type name ''{0}'' must match pattern ''{1}''."/>
</module>
- <module name="NoFinalizer"/>
+ <!-- <module name="NoFinalizer"/> -->
<module name="GenericWhitespace">
<message key="ws.followed"
value="GenericWhitespace ''{0}'' is followed by whitespace."/>
@@ -153,12 +153,12 @@
<property name="arrayInitIndent" value="2"/>
<!-- <property name="forceStrictCondition" value="true"/> -->
</module>
- <module name="AbbreviationAsWordInName">
+ <!-- <module name="AbbreviationAsWordInName">
<property name="ignoreFinal" value="false"/>
<property name="allowedAbbreviationLength" value="1"/>
- </module>
- <module name="OverloadMethodsDeclarationOrder"/>
- <module name="VariableDeclarationUsageDistance"/>
+ </module> -->
+ <!--<module name="OverloadMethodsDeclarationOrder"/>-->
+ <!--<module name="VariableDeclarationUsageDistance"/>-->
<module name="AvoidStarImport"/>
<module name="IllegalImport"/> <!-- defaults to sun.* packages -->
<module name="RedundantImport"/>
diff --git a/platform/android/config.cmake b/platform/android/config.cmake
index 05037589fb..635c27a44f 100644
--- a/platform/android/config.cmake
+++ b/platform/android/config.cmake
@@ -1,14 +1,52 @@
add_definitions(-DMBGL_USE_GLES2=1)
+include(cmake/test-files.cmake)
+
#Include to use build specific variables
include(${CMAKE_CURRENT_BINARY_DIR}/toolchain.cmake)
+# Build thin archives.
+set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> cruT <TARGET> <LINK_FLAGS> <OBJECTS>")
+set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> cruT <TARGET> <LINK_FLAGS> <OBJECTS>")
+set(CMAKE_CXX_ARCHIVE_APPEND "<CMAKE_AR> ruT <TARGET> <LINK_FLAGS> <OBJECTS>")
+set(CMAKE_C_ARCHIVE_APPEND "<CMAKE_AR> ruT <TARGET> <LINK_FLAGS> <OBJECTS>")
+
+if ((ANDROID_ABI STREQUAL "armeabi") OR (ANDROID_ABI STREQUAL "armeabi-v7a") OR (ANDROID_ABI STREQUAL "arm64-v8a") OR
+ (ANDROID_ABI STREQUAL "x86") OR (ANDROID_ABI STREQUAL "x86_64"))
+ # Use Identical Code Folding on platforms that support the gold linker.
+ set(CMAKE_EXE_LINKER_FLAGS "-fuse-ld=gold -Wl,--icf=safe ${CMAKE_EXE_LINKER_FLAGS}")
+ set(CMAKE_SHARED_LINKER_FLAGS "-fuse-ld=gold -Wl,--icf=safe ${CMAKE_SHARED_LINKER_FLAGS}")
+endif()
+
mason_use(jni.hpp VERSION 2.0.0 HEADER_ONLY)
mason_use(libjpeg-turbo VERSION 1.5.0)
mason_use(libpng VERSION 1.6.25)
mason_use(libzip VERSION 1.1.3)
mason_use(nunicode VERSION 1.7.1)
mason_use(sqlite VERSION 3.14.2)
+mason_use(gtest VERSION 1.7.0)
+mason_use(icu VERSION 58.1)
+
+set(ANDROID_SDK_PROJECT_DIR ${CMAKE_SOURCE_DIR}/platform/android/MapboxGLAndroidSDK)
+set(ANDROID_JNI_TARGET_DIR ${ANDROID_SDK_PROJECT_DIR}/src/main/jniLibs/${ANDROID_JNIDIR})
+set(ANDROID_ASSETS_TARGET_DIR ${ANDROID_SDK_PROJECT_DIR}/src/main/assets)
+set(ANDROID_TEST_APP_JNI_TARGET_DIR ${CMAKE_SOURCE_DIR}/platform/android/MapboxGLAndroidSDKTestApp/src/main/jniLibs/${ANDROID_JNIDIR})
+
+macro(mbgl_android_copy_asset source target)
+ add_custom_command(
+ OUTPUT ${ANDROID_ASSETS_TARGET_DIR}/${target}
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/${source} ${ANDROID_ASSETS_TARGET_DIR}/${target}
+ DEPENDS ${CMAKE_SOURCE_DIR}/${source}
+ )
+endmacro()
+
+mbgl_android_copy_asset(common/ca-bundle.crt ca-bundle.crt)
+
+add_custom_target(mbgl-copy-android-assets
+ DEPENDS ${ANDROID_ASSETS_TARGET_DIR}/ca-bundle.crt
+)
+
+## mbgl core ##
macro(mbgl_platform_core)
@@ -38,23 +76,85 @@ macro(mbgl_platform_core)
PRIVATE platform/default/sqlite3.hpp
# Misc
- PRIVATE platform/android/src/log_android.cpp
+ PRIVATE platform/android/src/logging_android.cpp
PRIVATE platform/default/string_stdlib.cpp
+ PRIVATE platform/default/bidi.cpp
# Image handling
PRIVATE platform/default/image.cpp
PRIVATE platform/default/png_reader.cpp
PRIVATE platform/default/jpeg_reader.cpp
- # Headless view
- # TODO
-
# Thread pool
- PRIVATE platform/default/thread_pool.cpp
+ PRIVATE platform/default/mbgl/util/default_thread_pool.cpp
+ PRIVATE platform/default/mbgl/util/default_thread_pool.hpp
+
+ # Conversion C++ -> Java
+ platform/android/src/conversion/constant.hpp
+ platform/android/src/conversion/conversion.hpp
+ platform/android/src/style/conversion/function.hpp
+ platform/android/src/style/conversion/property_value.hpp
+ platform/android/src/style/conversion/types.hpp
+ platform/android/src/style/conversion/types_string_values.hpp
+
+ # Style conversion Java -> C++
+ platform/android/src/style/android_conversion.hpp
+ platform/android/src/style/conversion/geojson.hpp
+ platform/android/src/style/value.cpp
+ platform/android/src/style/value.hpp
+ platform/android/src/style/conversion/url_or_tileset.hpp
+
+ # Style
+ platform/android/src/style/layers/background_layer.cpp
+ platform/android/src/style/layers/background_layer.hpp
+ platform/android/src/style/layers/circle_layer.cpp
+ platform/android/src/style/layers/circle_layer.hpp
+ platform/android/src/style/layers/custom_layer.cpp
+ platform/android/src/style/layers/custom_layer.hpp
+ platform/android/src/style/layers/fill_layer.cpp
+ platform/android/src/style/layers/fill_layer.hpp
+ platform/android/src/style/layers/layer.cpp
+ platform/android/src/style/layers/layer.hpp
+ platform/android/src/style/layers/layers.cpp
+ platform/android/src/style/layers/layers.hpp
+ platform/android/src/style/layers/line_layer.cpp
+ platform/android/src/style/layers/line_layer.hpp
+ platform/android/src/style/layers/raster_layer.cpp
+ platform/android/src/style/layers/raster_layer.hpp
+ platform/android/src/style/layers/symbol_layer.cpp
+ platform/android/src/style/layers/symbol_layer.hpp
+ platform/android/src/style/sources/geojson_source.cpp
+ platform/android/src/style/sources/geojson_source.hpp
+ platform/android/src/style/sources/source.cpp
+ platform/android/src/style/sources/source.hpp
+ platform/android/src/style/sources/sources.cpp
+ platform/android/src/style/sources/sources.hpp
+ platform/android/src/style/sources/raster_source.cpp
+ platform/android/src/style/sources/raster_source.hpp
+ platform/android/src/style/sources/vector_source.cpp
+ platform/android/src/style/sources/vector_source.hpp
+
+ # Connectivity
+ platform/android/src/connectivity_listener.cpp
+ platform/android/src/connectivity_listener.hpp
+
+ # Native map
+ platform/android/src/native_map_view.cpp
+ platform/android/src/native_map_view.hpp
+
+ # Main jni bindings
+ platform/android/src/attach_env.cpp
+ platform/android/src/attach_env.hpp
+ platform/android/src/java_types.cpp
+ platform/android/src/java_types.hpp
+
+ # Main entry point
+ platform/android/src/jni.hpp
+ platform/android/src/jni.cpp
)
target_include_directories(mbgl-core
- PRIVATE platform/default
+ PUBLIC platform/default
)
target_add_mason_package(mbgl-core PUBLIC sqlite)
@@ -64,9 +164,13 @@ macro(mbgl_platform_core)
target_add_mason_package(mbgl-core PUBLIC libzip)
target_add_mason_package(mbgl-core PUBLIC geojson)
target_add_mason_package(mbgl-core PUBLIC jni.hpp)
+ target_add_mason_package(mbgl-core PUBLIC rapidjson)
+ target_add_mason_package(mbgl-core PUBLIC icu)
target_compile_options(mbgl-core
PRIVATE -fvisibility=hidden
+ PRIVATE -ffunction-sections
+ PRIVATE -fdata-sections
PRIVATE -Os
)
@@ -78,114 +182,118 @@ macro(mbgl_platform_core)
PUBLIC -lstdc++
PUBLIC -latomic
PUBLIC -lz
+ PUBLIC -Wl,--gc-sections
)
endmacro()
+## Main library ##
+
add_library(mapbox-gl SHARED
- # Conversion C++ -> Java
- platform/android/src/conversion/constant.hpp
- platform/android/src/conversion/conversion.hpp
- platform/android/src/style/conversion/function.hpp
- platform/android/src/style/conversion/property_value.hpp
- platform/android/src/style/conversion/types.hpp
- platform/android/src/style/conversion/types_string_values.hpp
-
- # Style conversion Java -> C++
- platform/android/src/style/android_conversion.hpp
- platform/android/src/style/conversion/geojson.hpp
- platform/android/src/style/value.cpp
- platform/android/src/style/value.hpp
- platform/android/src/style/conversion/url_or_tileset.hpp
-
- # Style
- platform/android/src/style/layers/background_layer.cpp
- platform/android/src/style/layers/background_layer.hpp
- platform/android/src/style/layers/circle_layer.cpp
- platform/android/src/style/layers/circle_layer.hpp
- platform/android/src/style/layers/custom_layer.cpp
- platform/android/src/style/layers/custom_layer.hpp
- platform/android/src/style/layers/fill_layer.cpp
- platform/android/src/style/layers/fill_layer.hpp
- platform/android/src/style/layers/layer.cpp
- platform/android/src/style/layers/layer.hpp
- platform/android/src/style/layers/layers.cpp
- platform/android/src/style/layers/layers.hpp
- platform/android/src/style/layers/line_layer.cpp
- platform/android/src/style/layers/line_layer.hpp
- platform/android/src/style/layers/raster_layer.cpp
- platform/android/src/style/layers/raster_layer.hpp
- platform/android/src/style/layers/symbol_layer.cpp
- platform/android/src/style/layers/symbol_layer.hpp
- platform/android/src/style/sources/geojson_source.cpp
- platform/android/src/style/sources/geojson_source.hpp
- platform/android/src/style/sources/source.cpp
- platform/android/src/style/sources/source.hpp
- platform/android/src/style/sources/sources.cpp
- platform/android/src/style/sources/sources.hpp
- platform/android/src/style/sources/raster_source.cpp
- platform/android/src/style/sources/raster_source.hpp
- platform/android/src/style/sources/vector_source.cpp
- platform/android/src/style/sources/vector_source.hpp
-
- # Native map
- platform/android/src/native_map_view.cpp
- platform/android/src/native_map_view.hpp
-
- # Connectivity
- platform/android/src/connectivity_listener.cpp
- platform/android/src/connectivity_listener.hpp
-
- # Main jni bindings
- platform/android/src/jni.cpp
- platform/android/src/jni.hpp
- platform/android/src/attach_env.cpp
- platform/android/src/attach_env.hpp
- platform/android/src/java_types.cpp
- platform/android/src/java_types.hpp
+ platform/android/src/main.cpp
)
-target_add_mason_package(mapbox-gl PUBLIC rapidjson)
+add_dependencies(mapbox-gl
+ mbgl-copy-android-assets
+)
target_compile_options(mapbox-gl
PRIVATE -fvisibility=hidden
+ PRIVATE -ffunction-sections
+ PRIVATE -fdata-sections
PRIVATE -Os
)
target_link_libraries(mapbox-gl
PUBLIC mbgl-core
+ PUBLIC -Wl,--gc-sections
)
-add_library(example-custom-layer SHARED
- platform/android/src/example_custom_layer.cpp
+# Create a stripped version of the library and copy it to the JNIDIR.
+add_custom_command(TARGET mapbox-gl POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${ANDROID_JNI_TARGET_DIR}
+ COMMAND ${STRIP_COMMAND} $<TARGET_FILE:mapbox-gl> -o ${ANDROID_JNI_TARGET_DIR}/$<TARGET_FILE_NAME:mapbox-gl>)
+
+## Test library ##
+
+add_library(mbgl-test SHARED
+ # Actual tests
+ ${MBGL_TEST_FILES}
+
+ # Main test entry point
+ platform/android/src/test/main.jni.cpp
+
)
-target_compile_options(example-custom-layer
+add_dependencies(mbgl-test
+ mapbox-gl
+)
+
+target_sources(mbgl-test
+ # Headless view
+ PRIVATE platform/default/mbgl/gl/headless_backend.cpp
+ PRIVATE platform/default/mbgl/gl/headless_backend.hpp
+ PRIVATE platform/default/mbgl/gl/offscreen_view.cpp
+ PRIVATE platform/default/mbgl/gl/offscreen_view.hpp
+
+ PRIVATE platform/linux/src/headless_backend_egl.cpp
+ PRIVATE platform/linux/src/headless_display_egl.cpp
+)
+
+target_compile_options(mbgl-test
PRIVATE -fvisibility=hidden
PRIVATE -Os
)
-target_link_libraries(example-custom-layer
+target_compile_definitions(mbgl-test
+ PRIVATE MBGL_ASSET_ZIP=1
+)
+
+target_include_directories(mbgl-test
+ PRIVATE include
+ PRIVATE src # TODO: eliminate
+ PRIVATE test/include
+ PRIVATE test/src
+ PRIVATE platform/default
+ PRIVATE ${MBGL_GENERATED}/include
+)
+
+target_link_libraries(mbgl-test
PRIVATE mbgl-core
)
-set(ANDROID_SDK_PROJECT_DIR ${CMAKE_SOURCE_DIR}/platform/android/MapboxGLAndroidSDK)
-set(ANDROID_JNI_TARGET_DIR ${ANDROID_SDK_PROJECT_DIR}/src/main/jniLibs/${ANDROID_JNIDIR}/)
-set(ANDROID_ASSETS_TARGET_DIR ${ANDROID_SDK_PROJECT_DIR}/src/main/assets/)
-set(ANDROID_TEST_APP_JNI_TARGET_DIR ${CMAKE_SOURCE_DIR}/platform/android/MapboxGLAndroidSDKTestApp/src/main/jniLibs/${ANDROID_JNIDIR}/)
-
-add_custom_target(copy-files
- DEPENDS mapbox-gl
- DEPENDS example-custom-layer
- COMMAND ${CMAKE_COMMAND} -E make_directory ${ANDROID_JNI_TARGET_DIR}
- COMMAND ${STRIP_COMMAND} $<TARGET_FILE:mapbox-gl> -o ${ANDROID_JNI_TARGET_DIR}$<TARGET_FILE_NAME:mapbox-gl>
- COMMAND ${CMAKE_COMMAND} -E make_directory ${ANDROID_ASSETS_TARGET_DIR}
- COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/common/ca-bundle.crt ${ANDROID_ASSETS_TARGET_DIR}
- COMMAND ${CMAKE_COMMAND} -E make_directory ${ANDROID_TEST_APP_JNI_TARGET_DIR}
- COMMAND ${STRIP_COMMAND} $<TARGET_FILE:example-custom-layer> -o ${ANDROID_TEST_APP_JNI_TARGET_DIR}$<TARGET_FILE_NAME:example-custom-layer>
+target_add_mason_package(mbgl-test PRIVATE geometry)
+target_add_mason_package(mbgl-test PRIVATE variant)
+target_add_mason_package(mbgl-test PRIVATE unique_resource)
+target_add_mason_package(mbgl-test PRIVATE rapidjson)
+target_add_mason_package(mbgl-test PRIVATE gtest)
+target_add_mason_package(mbgl-test PRIVATE pixelmatch)
+target_add_mason_package(mbgl-test PRIVATE boost)
+target_add_mason_package(mbgl-test PRIVATE geojson)
+target_add_mason_package(mbgl-test PRIVATE geojsonvt)
+
+add_custom_command(TARGET mbgl-test POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/stripped
+ COMMAND ${STRIP_COMMAND} $<TARGET_FILE:mapbox-gl> -o ${CMAKE_CURRENT_BINARY_DIR}/stripped/$<TARGET_FILE_NAME:mapbox-gl>
+ COMMAND ${STRIP_COMMAND} $<TARGET_FILE:mbgl-test> -o ${CMAKE_CURRENT_BINARY_DIR}/stripped/$<TARGET_FILE_NAME:mbgl-test>)
+
+## Custom layer example ##
+
+add_library(example-custom-layer SHARED
+ platform/android/src/example_custom_layer.cpp
)
-add_custom_target(_all ALL
- DEPENDS mapbox-gl
- DEPENDS example-custom-layer
- DEPENDS copy-files
+target_compile_options(example-custom-layer
+ PRIVATE -fvisibility=hidden
+ PRIVATE -ffunction-sections
+ PRIVATE -fdata-sections
+ PRIVATE -Os
+)
+
+target_link_libraries(example-custom-layer
+ PRIVATE mapbox-gl
+ PUBLIC -Wl,--gc-sections
)
+
+add_custom_command(TARGET example-custom-layer POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${ANDROID_TEST_APP_JNI_TARGET_DIR}
+ COMMAND ${STRIP_COMMAND} $<TARGET_FILE:example-custom-layer> -o ${ANDROID_TEST_APP_JNI_TARGET_DIR}/$<TARGET_FILE_NAME:example-custom-layer>)
diff --git a/platform/android/gradle/wrapper/gradle-wrapper.jar b/platform/android/gradle/wrapper/gradle-wrapper.jar
index 3baa851b28..51288f9c2f 100644
--- a/platform/android/gradle/wrapper/gradle-wrapper.jar
+++ b/platform/android/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/platform/android/gradle/wrapper/gradle-wrapper.properties b/platform/android/gradle/wrapper/gradle-wrapper.properties
index 1a4f00cd31..20b2b0894c 100644
--- a/platform/android/gradle/wrapper/gradle-wrapper.properties
+++ b/platform/android/gradle/wrapper/gradle-wrapper.properties
@@ -1,7 +1,6 @@
-#Wed Aug 17 09:21:12 EDT 2016
+#Mon Dec 12 10:58:15 CET 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
-distributionSha256Sum=88a910cdf2e03ebbb5fe90f7ecf534fc9ac22e12112dc9a2fee810c598a76091
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.2.1-bin.zip
diff --git a/platform/android/gradlew b/platform/android/gradlew
index 27309d9231..4453ccea33 100755
--- a/platform/android/gradlew
+++ b/platform/android/gradlew
@@ -1,4 +1,4 @@
-#!/usr/bin/env bash
+#!/usr/bin/env sh
##############################################################################
##
@@ -154,11 +154,19 @@ if $cygwin ; then
esac
fi
-# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
-function splitJvmOpts() {
- JVM_OPTS=("$@")
+# Escape application args
+save ( ) {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
}
-eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
-JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+APP_ARGS=$(save "$@")
-exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/platform/android/gradlew.bat b/platform/android/gradlew.bat
index f6d5974e72..e95643d6a2 100644
--- a/platform/android/gradlew.bat
+++ b/platform/android/gradlew.bat
@@ -49,7 +49,6 @@ goto fail
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
-if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
@@ -60,11 +59,6 @@ set _SKIP=2
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
-goto execute
-
-:4NT_args
-@rem Get arguments from the 4NT Shell from JP Software
-set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
diff --git a/platform/android/scripts/generate-style-code.js b/platform/android/scripts/generate-style-code.js
index 1216bd4cbe..bcfd6bc0df 100644
--- a/platform/android/scripts/generate-style-code.js
+++ b/platform/android/scripts/generate-style-code.js
@@ -5,6 +5,8 @@ const ejs = require('ejs');
const spec = require('mapbox-gl-style-spec').latest;
const _ = require('lodash');
+require('../../../scripts/style-code');
+
// Specification parsing //
//Collect layer types from spec
@@ -38,29 +40,6 @@ const paintProperties = _(layers).map('paintProperties').flatten().value();
const allProperties = _(layoutProperties).union(paintProperties).value();
const enumProperties = _(allProperties).filter({'type': 'enum'}).value();
-// Global functions //
-
-global.iff = function (condition, val) {
- return condition() ? val : "";
-}
-
-
-global.camelize = function (str) {
- return str.replace(/(?:^|-)(.)/g, function (_, x) {
- return x.toUpperCase();
- });
-}
-
-global.camelizeWithLeadingLowercase = function (str) {
- return str.replace(/-(.)/g, function (_, x) {
- return x.toUpperCase();
- });
-}
-
-global.snakeCaseUpper = function snakeCaseUpper(str) {
- return str.replace(/-/g, "_").toUpperCase();
-}
-
global.propertyType = function propertyType(property) {
switch (property.type) {
case 'boolean':
@@ -235,7 +214,6 @@ global.propertyValueDoc = function (property, value) {
// Template processing //
-
// Java + JNI Layers (Peer model)
const layerHpp = ejs.compile(fs.readFileSync('platform/android/src/style/layers/layer.hpp.ejs', 'utf8'), {strict: true});
const layerCpp = ejs.compile(fs.readFileSync('platform/android/src/style/layers/layer.cpp.ejs', 'utf8'), {strict: true});
@@ -243,23 +221,23 @@ const layerJava = ejs.compile(fs.readFileSync('platform/android/MapboxGLAndroidS
const layerJavaUnitTests = ejs.compile(fs.readFileSync('platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/layer.junit.ejs', 'utf8'), {strict: true});
for (const layer of layers) {
- fs.writeFileSync(`platform/android/src/style/layers/${layer.type}_layer.hpp`, layerHpp(layer));
- fs.writeFileSync(`platform/android/src/style/layers/${layer.type}_layer.cpp`, layerCpp(layer));
- fs.writeFileSync(`platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/${camelize(layer.type)}Layer.java`, layerJava(layer));
- fs.writeFileSync(`platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/${camelize(layer.type)}LayerTest.java`, layerJavaUnitTests(layer));
+ writeIfModified(`platform/android/src/style/layers/${layer.type.replace('-', '_')}_layer.hpp`, layerHpp(layer));
+ writeIfModified(`platform/android/src/style/layers/${layer.type.replace('-', '_')}_layer.cpp`, layerCpp(layer));
+ writeIfModified(`platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/${camelize(layer.type)}Layer.java`, layerJava(layer));
+ writeIfModified(`platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/style/${camelize(layer.type)}LayerTest.java`, layerJavaUnitTests(layer));
}
// Java PropertyFactory
const propertiesTemplate = ejs.compile(fs.readFileSync('platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property_factory.java.ejs', 'utf8'), {strict: true});
-fs.writeFileSync(
+writeIfModified(
`platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java`,
propertiesTemplate({layoutProperties: layoutProperties, paintProperties: paintProperties})
);
// Java Property
const enumPropertyJavaTemplate = ejs.compile(fs.readFileSync('platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property.java.ejs', 'utf8'), {strict: true});
-fs.writeFileSync(
+writeIfModified(
`platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Property.java`,
enumPropertyJavaTemplate({properties: enumProperties})
);
@@ -269,14 +247,14 @@ const enumPropertiesDeDup = _(enumProperties).uniqBy(global.propertyNativeType).
// JNI Enum property conversion templates
const enumPropertyHppTypeStringValueTemplate = ejs.compile(fs.readFileSync('platform/android/src/style/conversion/types_string_values.hpp.ejs', 'utf8'), {strict: true});
-fs.writeFileSync(
+writeIfModified(
`platform/android/src/style/conversion/types_string_values.hpp`,
enumPropertyHppTypeStringValueTemplate({properties: enumPropertiesDeDup})
);
// JNI property value types conversion templates
const enumPropertyHppTypeTemplate = ejs.compile(fs.readFileSync('platform/android/src/style/conversion/types.hpp.ejs', 'utf8'), {strict: true});
-fs.writeFileSync(
+writeIfModified(
`platform/android/src/style/conversion/types.hpp`,
enumPropertyHppTypeTemplate({properties: enumPropertiesDeDup})
);
diff --git a/platform/android/scripts/generate-test-code.js b/platform/android/scripts/generate-test-code.js
index 17f0079906..2fd98f701f 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", "MultiMapActivity", "MapInDialogActivity"];
+const excludeActivities = ["RealTimeGeoJsonActivity","UpdateMetadataActivity","CarDrivingActivity","MyLocationTrackingModeActivity","MyLocationToggleActivity","MyLocationTintActivity","MyLocationDrawableActivity","DoubleMapActivity", "LocationPickerActivity","GeoJsonClusteringActivity","RuntimeStyleTestActivity", "AnimatedMarkerActivity", "ViewPagerActivity","MapFragmentActivity","SupportMapFragmentActivity","SnapshotActivity","NavigationDrawerActivity", "QueryRenderedFeaturesBoxHighlightActivity", "MultiMapActivity", "MapInDialogActivity", "SimpleMapActivity"];
const appBasePath = 'platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity';
const testBasePath = 'platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/activity/gen';
const subPackages = fs.readdirSync(appBasePath);
diff --git a/platform/android/scripts/metrics.sh b/platform/android/scripts/metrics.sh
new file mode 100755
index 0000000000..37d8c1de65
--- /dev/null
+++ b/platform/android/scripts/metrics.sh
@@ -0,0 +1,15 @@
+#!/usr/bin/env bash
+
+set -e
+set -o pipefail
+
+# Track individual architectures
+scripts/log_binary_size.sh "platform/android/MapboxGLAndroidSDK/src/main/jniLibs/armeabi/libmapbox-gl.so" "Platform=Android,Arch=arm-v5"
+scripts/log_binary_size.sh "platform/android/MapboxGLAndroidSDK/src/main/jniLibs/armeabi-v7a/libmapbox-gl.so" "Platform=Android,Arch=arm-v7"
+scripts/log_binary_size.sh "platform/android/MapboxGLAndroidSDK/src/main/jniLibs/arm64-v8a/libmapbox-gl.so" "Platform=Android,Arch=arm-v8"
+scripts/log_binary_size.sh "platform/android/MapboxGLAndroidSDK/src/main/jniLibs/x86/libmapbox-gl.so" "Platform=Android,Arch=x86"
+scripts/log_binary_size.sh "platform/android/MapboxGLAndroidSDK/src/main/jniLibs/x86_64/libmapbox-gl.so" "Platform=Android,Arch=x86_64"
+scripts/log_binary_size.sh "platform/android/MapboxGLAndroidSDK/src/main/jniLibs/mips/libmapbox-gl.so" "Platform=Android,Arch=mips"
+
+# Track overall library size
+scripts/log_binary_size.sh "platform/android/MapboxGLAndroidSDK/build/outputs/aar/MapboxGLAndroidSDK-release.aar" "Platform=Android,Arch=Archive"
diff --git a/platform/android/src/connectivity_listener.cpp b/platform/android/src/connectivity_listener.cpp
index df5c60a485..cc2f0a4a81 100644
--- a/platform/android/src/connectivity_listener.cpp
+++ b/platform/android/src/connectivity_listener.cpp
@@ -1,7 +1,7 @@
#include "connectivity_listener.hpp"
#include <mbgl/storage/network_status.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
#include <jni/jni.hpp>
diff --git a/platform/android/src/example_custom_layer.cpp b/platform/android/src/example_custom_layer.cpp
index 516a8f2cd5..c55c9c3527 100644
--- a/platform/android/src/example_custom_layer.cpp
+++ b/platform/android/src/example_custom_layer.cpp
@@ -1,14 +1,17 @@
#include <jni.h>
#include <GLES2/gl2.h>
+#include <mbgl/util/logging.hpp>
+
#include <mbgl/style/layers/custom_layer.hpp>
static const GLchar * vertexShaderSource = "attribute vec2 a_pos; void main() { gl_Position = vec4(a_pos, 0, 1); }";
-static const GLchar * fragmentShaderSource = "void main() { gl_FragColor = vec4(0, 1, 0, 1); }";
+static const GLchar * fragmentShaderSource = "uniform vec4 fill_color; void main() { gl_FragColor = fill_color; }";
class ExampleCustomLayer {
public:
~ExampleCustomLayer() {
+ mbgl::Log::Info(mbgl::Event::General, "~ExampleCustomLayer");
if (program) {
glDeleteBuffers(1, &buffer);
glDetachShader(program, vertexShader);
@@ -20,6 +23,7 @@ public:
}
void initialize() {
+ mbgl::Log::Info(mbgl::Event::General, "Initialize");
program = glCreateProgram();
vertexShader = glCreateShader(GL_VERTEX_SHADER);
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
@@ -32,6 +36,7 @@ public:
glAttachShader(program, fragmentShader);
glLinkProgram(program);
a_pos = glGetAttribLocation(program, "a_pos");
+ fill_color = glGetUniformLocation(program, "fill_color");
GLfloat background[] = { -1,-1, 1,-1, -1,1, 1,1 };
glGenBuffers(1, &buffer);
@@ -40,12 +45,15 @@ public:
}
void render() {
+ mbgl::Log::Info(mbgl::Event::General, "Render");
glUseProgram(program);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glEnableVertexAttribArray(a_pos);
glVertexAttribPointer(a_pos, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glDisable(GL_STENCIL_TEST);
glDisable(GL_DEPTH_TEST);
+ glUniform4fv(fill_color, 1, color);
+
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
@@ -54,35 +62,54 @@ public:
GLuint fragmentShader = 0;
GLuint buffer = 0;
GLuint a_pos = 0;
+ GLuint fill_color = 0;
+
+ static GLfloat color[];
};
+GLfloat ExampleCustomLayer::color[] = { 0.0f, 1.0f, 0.0f, 1.0f };
+
jlong JNICALL nativeCreateContext(JNIEnv*, jobject) {
- return reinterpret_cast<jlong>(new ExampleCustomLayer());
+ mbgl::Log::Info(mbgl::Event::General, "nativeCreateContext");
+ return reinterpret_cast<jlong>(new ExampleCustomLayer());
+}
+
+void JNICALL nativeSetColor(JNIEnv*, jobject, jfloat red, jfloat green, jfloat blue, jfloat alpha) {
+ mbgl::Log::Info(mbgl::Event::General, "nativeSetColor: %.2f, %.2f, %.2f, %.2f", red, green, blue, alpha);
+ ExampleCustomLayer::color[0] = red;
+ ExampleCustomLayer::color[1] = green;
+ ExampleCustomLayer::color[2] = blue;
+ ExampleCustomLayer::color[3] = alpha;
}
void nativeInitialize(void *context) {
+ mbgl::Log::Info(mbgl::Event::General, "nativeInitialize");
reinterpret_cast<ExampleCustomLayer*>(context)->initialize();
}
void nativeRender(void *context, const mbgl::style::CustomLayerRenderParameters& /*parameters*/) {
+ mbgl::Log::Info(mbgl::Event::General, "nativeRender");
reinterpret_cast<ExampleCustomLayer*>(context)->render();
}
void nativeDenitialize(void *context) {
+ mbgl::Log::Info(mbgl::Event::General, "nativeDeinitialize");
delete reinterpret_cast<ExampleCustomLayer*>(context);
}
extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
+ mbgl::Log::Info(mbgl::Event::General, "OnLoad");
JNIEnv *env = nullptr;
vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6);
jclass customLayerClass = env->FindClass("com/mapbox/mapboxsdk/testapp/model/customlayer/ExampleCustomLayer");
JNINativeMethod methods[] = {
- {"createContext", "()J", reinterpret_cast<void *>(&nativeCreateContext)}
+ {"createContext", "()J", reinterpret_cast<void *>(&nativeCreateContext)},
+ {"setColor", "(FFFF)V", reinterpret_cast<void *>(&nativeSetColor)}
};
- if (env->RegisterNatives(customLayerClass, methods, 1) < 0) {
+ if (env->RegisterNatives(customLayerClass, methods, 2) < 0) {
env->ExceptionDescribe();
return JNI_ERR;
}
diff --git a/platform/android/src/geometry/conversion/feature.hpp b/platform/android/src/geometry/conversion/feature.hpp
index 9f75b9c8f1..f0c77c3389 100644
--- a/platform/android/src/geometry/conversion/feature.hpp
+++ b/platform/android/src/geometry/conversion/feature.hpp
@@ -16,7 +16,7 @@
#include <vector>
#include <sstream>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
namespace mbgl {
namespace android {
diff --git a/platform/android/src/http_file_source.cpp b/platform/android/src/http_file_source.cpp
index ed4d81391f..ee1429bd74 100644
--- a/platform/android/src/http_file_source.cpp
+++ b/platform/android/src/http_file_source.cpp
@@ -1,7 +1,7 @@
#include <mbgl/storage/http_file_source.hpp>
#include <mbgl/storage/resource.hpp>
#include <mbgl/storage/response.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
#include <mbgl/util/async_task.hpp>
#include <mbgl/util/util.hpp>
diff --git a/platform/android/src/jni.cpp b/platform/android/src/jni.cpp
index 6dcd177cd6..5182e268f3 100755
--- a/platform/android/src/jni.cpp
+++ b/platform/android/src/jni.cpp
@@ -25,8 +25,8 @@
#include <mbgl/style/layer.hpp>
#include <mbgl/style/source.hpp>
#include <mbgl/sprite/sprite_image.hpp>
-#include <mbgl/platform/event.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/event.hpp>
+#include <mbgl/util/logging.hpp>
#include <mbgl/storage/network_status.hpp>
#include <mbgl/util/exception.hpp>
#include <mbgl/util/optional.hpp>
@@ -431,6 +431,12 @@ void nativeSetStyleUrl(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, j
nativeMapView->getMap().setStyleURL(std_string_from_jstring(env, url));
}
+jni::jstring* nativeGetStyleUrl(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr){
+ assert(nativeMapViewPtr != 0);
+ NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
+ return std_string_to_jstring(env, nativeMapView->getMap().getStyleURL());
+}
+
void nativeSetStyleJson(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* newStyleJson) {
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
@@ -471,8 +477,7 @@ void nativeMoveBy(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdoubl
jlong duration) {
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
- mbgl::ScreenCoordinate center(dx, dy);
- nativeMapView->getMap().moveBy(center, mbgl::Milliseconds(duration));
+ nativeMapView->getMap().moveBy({dx, dy}, mbgl::Milliseconds(duration));
}
void nativeSetLatLng(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble latitude, jdouble longitude, jlong duration) {
@@ -498,7 +503,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()-360);
+ buf[2] = -nativeMapView->getMap().getBearing();
buf[3] = nativeMapView->getMap().getPitch();
buf[4] = nativeMapView->getMap().getZoom();
env->SetDoubleArrayRegion(output, start, leng, buf);
@@ -833,9 +838,10 @@ void nativeAddAnnotationIcon(JNIEnv *env, jni::jobject* obj, jlong nativeMapView
NullCheck(*env, jpixels);
std::size_t size = jni::GetArrayLength(*env, *jpixels);
- mbgl::PremultipliedImage premultipliedImage(width, height);
+ mbgl::PremultipliedImage premultipliedImage(
+ { static_cast<uint32_t>(width), static_cast<uint32_t>(height) });
- if (premultipliedImage.size() != uint32_t(size)) {
+ if (premultipliedImage.bytes() != uint32_t(size)) {
throw mbgl::util::SpriteImageException("Sprite image pixel count mismatch");
}
@@ -1007,7 +1013,7 @@ void nativeJumpTo(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdoubl
mbgl::CameraOptions options;
if (angle != -1) {
- options.angle = angle * M_PI / 180;
+ options.angle = (-angle * M_PI) / 180;
}
options.center = mbgl::LatLng(latitude, longitude);
options.padding = nativeMapView->getInsets();
@@ -1027,7 +1033,7 @@ void nativeEaseTo(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdoubl
mbgl::CameraOptions cameraOptions;
if (angle != -1) {
- cameraOptions.angle = angle * M_PI / 180;
+ cameraOptions.angle = (-angle * M_PI) / 180;
}
cameraOptions.center = mbgl::LatLng(latitude, longitude);
cameraOptions.padding = nativeMapView->getInsets();
@@ -1060,7 +1066,7 @@ void nativeFlyTo(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jdouble
mbgl::CameraOptions cameraOptions;
if (angle != -1) {
- cameraOptions.angle = angle * M_PI / 180 ;
+ cameraOptions.angle = (-angle * M_PI) / 180 ;
}
cameraOptions.center = mbgl::LatLng(latitude, longitude);
cameraOptions.padding = nativeMapView->getInsets();
@@ -1099,15 +1105,19 @@ void nativeAddLayer(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jlon
assert(nativeLayerPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
- Layer *layer = reinterpret_cast<Layer *>(nativeLayerPtr);
- nativeMapView->getMap().addLayer(
- layer->releaseCoreLayer(),
- before ? mbgl::optional<std::string>(std_string_from_jstring(env, before)) : mbgl::optional<std::string>()
- );
+ Layer *layer = reinterpret_cast<Layer *>(nativeLayerPtr);
+ try {
+ layer->addToMap(nativeMapView->getMap(), before ? mbgl::optional<std::string>(std_string_from_jstring(env, before)) : mbgl::optional<std::string>());
+ } catch (const std::runtime_error& error) {
+ jni::ThrowNew(*env, jni::FindClass(*env, "com/mapbox/mapboxsdk/style/layers/CannotAddLayerException"), error.what());
+ }
}
-void nativeRemoveLayer(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* id) {
+/**
+ * Remove by layer id. Ownership is not transferred back
+ */
+void nativeRemoveLayerById(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* id) {
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
try {
@@ -1117,6 +1127,22 @@ void nativeRemoveLayer(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, j
}
}
+/**
+ * Remove with wrapper object id. Ownership is transferred back to the wrapper
+ */
+void nativeRemoveLayer(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jlong layerPtr) {
+ assert(nativeMapViewPtr != 0);
+ NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
+ mbgl::android::Layer *layer = reinterpret_cast<mbgl::android::Layer *>(layerPtr);
+ try {
+ std::unique_ptr<mbgl::style::Layer> coreLayer = nativeMapView->getMap().removeLayer(layer->get().getID());
+ layer->setLayer(std::move(coreLayer));
+ } catch (const std::runtime_error& error) {
+ jni::ThrowNew(*env, jni::FindClass(*env, "com/mapbox/mapboxsdk/style/layers/NoSuchLayerException"), error.what());
+ }
+}
+
+
jni::jobject* nativeGetSource(JNIEnv *env, jni::jobject* obj, jni::jlong nativeMapViewPtr, jni::jstring* sourceId) {
assert(env);
assert(nativeMapViewPtr != 0);
@@ -1140,16 +1166,32 @@ void nativeAddSource(JNIEnv *env, jni::jobject* obj, jni::jlong nativeMapViewPtr
assert(nativeSourcePtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
+
Source *source = reinterpret_cast<Source *>(nativeSourcePtr);
+ try {
+ source->addToMap(nativeMapView->getMap());
+ } catch (const std::runtime_error& error) {
+ jni::ThrowNew(*env, jni::FindClass(*env, "com/mapbox/mapboxsdk/style/sources/CannotAddSourceException"), error.what());
+ }
+}
- nativeMapView->getMap().addSource(source->releaseCoreSource());
+void nativeRemoveSourceById(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* id) {
+ assert(nativeMapViewPtr != 0);
+ NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
+ try {
+ nativeMapView->getMap().removeSource(std_string_from_jstring(env, id));
+ } catch (const std::runtime_error& error) {
+ jni::ThrowNew(*env, jni::FindClass(*env, "com/mapbox/mapboxsdk/style/sources/NoSuchSourceException"), error.what());
+ }
}
-void nativeRemoveSource(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jstring* id) {
+void nativeRemoveSource(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jlong sourcePtr) {
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
+ mbgl::android::Source *source = reinterpret_cast<mbgl::android::Source *>(sourcePtr);
try {
- nativeMapView->getMap().removeSource(std_string_from_jstring(env, id));
+ std::unique_ptr<mbgl::style::Source> coreSource = nativeMapView->getMap().removeSource(source->get().getID());
+ source->setSource(std::move(coreSource));
} catch (const std::runtime_error& error) {
jni::ThrowNew(*env, jni::FindClass(*env, "com/mapbox/mapboxsdk/style/sources/NoSuchSourceException"), error.what());
}
@@ -1162,9 +1204,10 @@ void nativeAddImage(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni:
// Create Pre-multiplied image from byte[]
NullCheck(*env, data);
std::size_t size = jni::GetArrayLength(*env, *data);
- mbgl::PremultipliedImage premultipliedImage(width, height);
+ mbgl::PremultipliedImage premultipliedImage(
+ { static_cast<uint32_t>(width), static_cast<uint32_t>(height) });
- if (premultipliedImage.size() != uint32_t(size)) {
+ if (premultipliedImage.bytes() != uint32_t(size)) {
throw mbgl::util::SpriteImageException("Sprite image pixel count mismatch");
}
@@ -1666,9 +1709,12 @@ void updateOfflineRegionMetadata(JNIEnv *env, jni::jobject* offlineRegion_, jni:
// Offline calls end
-}
+} // anonymous
-extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
+namespace mbgl {
+namespace android {
+
+void registerNatives(JavaVM *vm) {
theJVM = vm;
jni::JNIEnv& env = jni::GetEnv(*vm, jni::jni_version_1_6);
@@ -1776,6 +1822,7 @@ extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
MAKE_NATIVE_METHOD(nativeSetClasses, "(JLjava/util/List;)V"),
MAKE_NATIVE_METHOD(nativeGetClasses, "(J)Ljava/util/List;"),
MAKE_NATIVE_METHOD(nativeSetStyleUrl, "(JLjava/lang/String;)V"),
+ MAKE_NATIVE_METHOD(nativeGetStyleUrl, "(J)Ljava/lang/String;"),
MAKE_NATIVE_METHOD(nativeSetStyleJson, "(JLjava/lang/String;)V"),
MAKE_NATIVE_METHOD(nativeGetStyleJson, "(J)Ljava/lang/String;"),
MAKE_NATIVE_METHOD(nativeSetAccessToken, "(JLjava/lang/String;)V"),
@@ -1831,10 +1878,12 @@ extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
MAKE_NATIVE_METHOD(nativeFlyTo, "(JDDDJDD)V"),
MAKE_NATIVE_METHOD(nativeGetLayer, "(JLjava/lang/String;)Lcom/mapbox/mapboxsdk/style/layers/Layer;"),
MAKE_NATIVE_METHOD(nativeAddLayer, "(JJLjava/lang/String;)V"),
- MAKE_NATIVE_METHOD(nativeRemoveLayer, "(JLjava/lang/String;)V"),
+ MAKE_NATIVE_METHOD(nativeRemoveLayerById, "(JLjava/lang/String;)V"),
+ MAKE_NATIVE_METHOD(nativeRemoveLayer, "(JJ)V"),
MAKE_NATIVE_METHOD(nativeGetSource, "(JLjava/lang/String;)Lcom/mapbox/mapboxsdk/style/sources/Source;"),
MAKE_NATIVE_METHOD(nativeAddSource, "(JJ)V"),
- MAKE_NATIVE_METHOD(nativeRemoveSource, "(JLjava/lang/String;)V"),
+ MAKE_NATIVE_METHOD(nativeRemoveSourceById, "(JLjava/lang/String;)V"),
+ MAKE_NATIVE_METHOD(nativeRemoveSource, "(JJ)V"),
MAKE_NATIVE_METHOD(nativeAddImage, "(JLjava/lang/String;IIF[B)V"),
MAKE_NATIVE_METHOD(nativeRemoveImage, "(JLjava/lang/String;)V"),
MAKE_NATIVE_METHOD(nativeSetContentPadding, "(JDDDD)V"),
@@ -1949,6 +1998,7 @@ extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
char release[PROP_VALUE_MAX] = "";
__system_property_get("ro.build.version.release", release);
androidRelease = std::string(release);
-
- return JNI_VERSION_1_6;
}
+
+} // android
+} // mbgl
diff --git a/platform/android/src/jni.hpp b/platform/android/src/jni.hpp
index 0810ee656d..90ec914cf2 100644
--- a/platform/android/src/jni.hpp
+++ b/platform/android/src/jni.hpp
@@ -23,6 +23,8 @@ extern jmethodID onSnapshotReadyId;
extern bool attach_jni_thread(JavaVM* vm, JNIEnv** env, std::string threadName);
extern void detach_jni_thread(JavaVM* vm, JNIEnv** env, bool detach);
+
+extern void registerNatives(JavaVM* vm);
-}
-}
+} //android
+} //mbgl
diff --git a/platform/android/src/log_android.cpp b/platform/android/src/logging_android.cpp
index e5c8cfd812..2e025c059f 100644
--- a/platform/android/src/log_android.cpp
+++ b/platform/android/src/logging_android.cpp
@@ -1,4 +1,4 @@
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
#include <android/log.h>
diff --git a/platform/android/src/main.cpp b/platform/android/src/main.cpp
new file mode 100644
index 0000000000..03a8288719
--- /dev/null
+++ b/platform/android/src/main.cpp
@@ -0,0 +1,9 @@
+#include "jni.hpp"
+#include <jni/jni.hpp>
+
+extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *) {
+ assert(vm != nullptr);
+ mbgl::android::registerNatives(vm);
+ return JNI_VERSION_1_6;
+}
+
diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp
index 84daf82e8b..8234b74af2 100755
--- a/platform/android/src/native_map_view.cpp
+++ b/platform/android/src/native_map_view.cpp
@@ -10,13 +10,10 @@
#include <sys/system_properties.h>
-#include <GLES2/gl2.h>
-
-#include <mbgl/platform/platform.hpp>
-#include <mbgl/platform/event.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/platform.hpp>
+#include <mbgl/util/event.hpp>
+#include <mbgl/util/logging.hpp>
#include <mbgl/gl/extension.hpp>
-#include <mbgl/gl/gl.hpp>
#include <mbgl/gl/context.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/image.hpp>
@@ -40,23 +37,6 @@ void log_egl_string(EGLDisplay display, EGLint name, const char *label) {
}
}
-void log_gl_string(GLenum name, const char *label) {
- const GLubyte *str = glGetString(name);
- if (str == nullptr) {
- mbgl::Log::Error(mbgl::Event::OpenGL, "glGetString(%d) returned error %d", name,
- glGetError());
- throw std::runtime_error("glGetString() failed");
- } else {
- char buf[513];
- for (int len = std::strlen(reinterpret_cast<const char *>(str)), pos = 0; len > 0;
- len -= 512, pos += 512) {
- strncpy(buf, reinterpret_cast<const char *>(str) + pos, 512);
- buf[512] = 0;
- mbgl::Log::Info(mbgl::Event::OpenGL, "GL %s: %s", label, buf);
- }
- }
-}
-
NativeMapView::NativeMapView(JNIEnv *env_, jobject obj_, float pixelRatio, int availableProcessors_, size_t totalMemory_)
: env(env_),
availableProcessors(availableProcessors_),
@@ -83,15 +63,14 @@ NativeMapView::NativeMapView(JNIEnv *env_, jobject obj_, float pixelRatio, int a
mbgl::android::apkPath);
map = std::make_unique<mbgl::Map>(
- *this,
- std::array<uint16_t, 2>{{ static_cast<uint16_t>(width), static_cast<uint16_t>(height) }},
+ *this, mbgl::Size{ static_cast<uint32_t>(width), static_cast<uint32_t>(height) },
pixelRatio, *fileSource, threadPool, MapMode::Continuous);
float zoomFactor = map->getMaxZoom() - map->getMinZoom() + 1;
float cpuFactor = availableProcessors;
float memoryFactor = static_cast<float>(totalMemory) / 1000.0f / 1000.0f / 1000.0f;
- float sizeFactor = (static_cast<float>(map->getWidth()) / mbgl::util::tileSize) *
- (static_cast<float>(map->getHeight()) / mbgl::util::tileSize);
+ float sizeFactor = (static_cast<float>(map->getSize().width) / mbgl::util::tileSize) *
+ (static_cast<float>(map->getSize().height) / mbgl::util::tileSize);
size_t cacheSize = zoomFactor * cpuFactor * memoryFactor * sizeFactor * 0.5f;
@@ -117,14 +96,20 @@ NativeMapView::~NativeMapView() {
vm = nullptr;
}
+mbgl::Size NativeMapView::getFramebufferSize() const {
+ return { static_cast<uint32_t>(fbWidth), static_cast<uint32_t>(fbHeight) };
+}
+
void NativeMapView::updateViewBinding() {
getContext().bindFramebuffer.setCurrentValue(0);
- getContext().viewport.setCurrentValue({ 0, 0, static_cast<uint16_t>(fbWidth), static_cast<uint16_t>(fbHeight) });
+ assert(mbgl::gl::value::BindFramebuffer::Get() == getContext().bindFramebuffer.getCurrentValue());
+ getContext().viewport.setCurrentValue({ 0, 0, getFramebufferSize() });
+ assert(mbgl::gl::value::Viewport::Get() == getContext().viewport.getCurrentValue());
}
void NativeMapView::bind() {
getContext().bindFramebuffer = 0;
- getContext().viewport = { 0, 0, static_cast<uint16_t>(fbWidth), static_cast<uint16_t>(fbHeight) };
+ getContext().viewport = { 0, 0, getFramebufferSize() };
}
void NativeMapView::activate() {
@@ -192,6 +177,11 @@ void NativeMapView::invalidate() {
void NativeMapView::render() {
BackendScope guard(*this);
+ if (framebufferSizeChanged) {
+ getContext().viewport = { 0, 0, getFramebufferSize() };
+ framebufferSizeChanged = false;
+ }
+
updateViewBinding();
map->render(*this);
@@ -199,18 +189,7 @@ void NativeMapView::render() {
snapshot = false;
// take snapshot
- const unsigned int w = fbWidth;
- const unsigned int h = fbHeight;
- mbgl::PremultipliedImage image { static_cast<uint16_t>(w), static_cast<uint16_t>(h) };
- MBGL_CHECK_ERROR(glReadPixels(0, 0, w, h, 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();
- for (int i = 0, j = h - 1; i < j; i++, j--) {
- std::memcpy(tmp.get(), rgba + i * stride, stride);
- std::memcpy(rgba + i * stride, rgba + j * stride, stride);
- std::memcpy(rgba + j * stride, tmp.get(), stride);
- }
+ auto image = getContext().readFramebuffer<mbgl::PremultipliedImage>(getFramebufferSize());
// encode and convert to jbytes
std::string string = encodePNG(image);
@@ -241,13 +220,6 @@ mbgl::Map &NativeMapView::getMap() { return *map; }
mbgl::DefaultFileSource &NativeMapView::getFileSource() { return *fileSource; }
-bool NativeMapView::inEmulator() {
- // Detect if we are in emulator
- char prop[PROP_VALUE_MAX];
- __system_property_get("ro.kernel.qemu", prop);
- return strtol(prop, nullptr, 0) == 1;
-}
-
void NativeMapView::initializeDisplay() {
mbgl::Log::Debug(mbgl::Event::Android, "NativeMapView::initializeDisplay");
@@ -277,22 +249,39 @@ void NativeMapView::initializeDisplay() {
log_egl_string(display, EGL_CLIENT_APIS, "Client APIs");
log_egl_string(display, EGL_EXTENSIONS, "Client Extensions");
- // Detect if we are in emulator
- if (inEmulator()) {
+ // Detect if we are in emulator.
+ const bool inEmulator = []() {
+ char prop[PROP_VALUE_MAX];
+ __system_property_get("ro.kernel.qemu", prop);
+ return strtol(prop, nullptr, 0) == 1;
+ }();
+
+ if (inEmulator) {
+ // XXX https://code.google.com/p/android/issues/detail?id=78977
mbgl::Log::Warning(mbgl::Event::Android, "In emulator! Enabling hacks :-(");
}
+ if (!eglBindAPI(EGL_OPENGL_ES_API)) {
+ mbgl::Log::Error(mbgl::Event::OpenGL, "eglBindAPI(EGL_OPENGL_ES_API) returned error %d", eglGetError());
+ throw std::runtime_error("eglBindAPI() failed");
+ }
+
// Get all configs at least RGB 565 with 16 depth and 8 stencil
EGLint configAttribs[] = {
- EGL_CONFIG_CAVEAT, EGL_NONE, EGL_RENDERABLE_TYPE,
- EGL_OPENGL_ES2_BIT, EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
- EGL_BUFFER_SIZE, 16, EGL_RED_SIZE,
- 5, EGL_GREEN_SIZE, 6,
- EGL_BLUE_SIZE, 5, EGL_DEPTH_SIZE,
- 16, EGL_STENCIL_SIZE, 8,
- (inEmulator() ? EGL_NONE : EGL_CONFORMANT), EGL_OPENGL_ES2_BIT, // Ugly hack
- (inEmulator() ? EGL_NONE : EGL_COLOR_BUFFER_TYPE), EGL_RGB_BUFFER, // Ugly hack
- EGL_NONE};
+ EGL_CONFIG_CAVEAT, EGL_NONE,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_BUFFER_SIZE, 16,
+ EGL_RED_SIZE, 5,
+ EGL_GREEN_SIZE, 6,
+ EGL_BLUE_SIZE, 5,
+ EGL_DEPTH_SIZE, 16,
+ EGL_STENCIL_SIZE, 8,
+ (inEmulator ? EGL_NONE : EGL_CONFORMANT), EGL_OPENGL_ES2_BIT,
+ (inEmulator ? EGL_NONE : EGL_COLOR_BUFFER_TYPE), EGL_RGB_BUFFER,
+ EGL_NONE
+ };
+
EGLint numConfigs;
if (!eglChooseConfig(display, configAttribs, nullptr, 0, &numConfigs)) {
mbgl::Log::Error(mbgl::Event::OpenGL, "eglChooseConfig(NULL) returned error %d",
@@ -427,16 +416,6 @@ void NativeMapView::createSurface(ANativeWindow *window_) {
throw std::runtime_error("eglMakeCurrent() failed");
}
- log_gl_string(GL_VENDOR, "Vendor");
- log_gl_string(GL_RENDERER, "Renderer");
- log_gl_string(GL_VERSION, "Version");
- if (!inEmulator()) {
- log_gl_string(GL_SHADING_LANGUAGE_VERSION,
- "SL Version"); // In the emulator this returns NULL with error code 0?
- // https://code.google.com/p/android/issues/detail?id=78977
- }
-
- log_gl_string(GL_EXTENSIONS, "Extensions");
mbgl::gl::InitializeExtensions([] (const char * name) {
return reinterpret_cast<mbgl::gl::glProc>(eglGetProcAddress(name));
});
@@ -714,12 +693,13 @@ void NativeMapView::updateFps() {
void NativeMapView::resizeView(int w, int h) {
width = w;
height = h;
- map->setSize({{ static_cast<uint16_t>(width), static_cast<uint16_t>(height) }});
+ map->setSize({ static_cast<uint32_t>(width), static_cast<uint32_t>(height) });
}
void NativeMapView::resizeFramebuffer(int w, int h) {
fbWidth = w;
fbHeight = h;
+ framebufferSizeChanged = true;
invalidate();
}
diff --git a/platform/android/src/native_map_view.hpp b/platform/android/src/native_map_view.hpp
index 00cb6e591e..e7379700a9 100755
--- a/platform/android/src/native_map_view.hpp
+++ b/platform/android/src/native_map_view.hpp
@@ -4,7 +4,7 @@
#include <mbgl/map/view.hpp>
#include <mbgl/map/backend.hpp>
#include <mbgl/util/noncopyable.hpp>
-#include <mbgl/platform/default/thread_pool.hpp>
+#include <mbgl/util/default_thread_pool.hpp>
#include <mbgl/storage/default_file_source.hpp>
#include <string>
@@ -20,6 +20,7 @@ public:
NativeMapView(JNIEnv *env, jobject obj, float pixelRatio, int availableProcessors, size_t totalMemory);
virtual ~NativeMapView();
+ mbgl::Size getFramebufferSize() const;
void updateViewBinding();
void bind() override;
@@ -58,8 +59,6 @@ protected:
private:
EGLConfig chooseConfig(const EGLConfig configs[], EGLint numConfigs);
- bool inEmulator();
-
private:
JavaVM *vm = nullptr;
JNIEnv *env = nullptr;
@@ -91,6 +90,7 @@ private:
int height = 0;
int fbWidth = 0;
int fbHeight = 0;
+ bool framebufferSizeChanged = true;
int availableProcessors = 0;
size_t totalMemory = 0;
diff --git a/platform/android/src/run_loop.cpp b/platform/android/src/run_loop.cpp
index 1e5fc9b4ba..170b05c23c 100644
--- a/platform/android/src/run_loop.cpp
+++ b/platform/android/src/run_loop.cpp
@@ -1,6 +1,6 @@
#include "run_loop_impl.hpp"
-#include <mbgl/platform/platform.hpp>
+#include <mbgl/util/platform.hpp>
#include <mbgl/util/thread_context.hpp>
#include <mbgl/util/thread_local.hpp>
#include <mbgl/util/timer.hpp>
diff --git a/platform/android/src/style/android_conversion.hpp b/platform/android/src/style/android_conversion.hpp
index cea7ce6d2a..de0ac91502 100644
--- a/platform/android/src/style/android_conversion.hpp
+++ b/platform/android/src/style/android_conversion.hpp
@@ -2,7 +2,7 @@
#include "value.hpp"
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
#include <mbgl/style/conversion.hpp>
#include <mbgl/util/feature.hpp>
#include <mbgl/util/optional.hpp>
diff --git a/platform/android/src/style/conversion/geojson.hpp b/platform/android/src/style/conversion/geojson.hpp
index 920c670fcb..6bc48b3700 100644
--- a/platform/android/src/style/conversion/geojson.hpp
+++ b/platform/android/src/style/conversion/geojson.hpp
@@ -6,7 +6,7 @@
#include <mbgl/style/conversion.hpp>
#include <mbgl/style/conversion/geojson.hpp>
#include <mbgl/util/rapidjson.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
#include <jni/jni.hpp>
#include <sstream>
diff --git a/platform/android/src/style/conversion/types.hpp b/platform/android/src/style/conversion/types.hpp
index d3c12ff89a..1c433bb264 100644
--- a/platform/android/src/style/conversion/types.hpp
+++ b/platform/android/src/style/conversion/types.hpp
@@ -1,4 +1,4 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
#pragma once
#include "types_string_values.hpp"
diff --git a/platform/android/src/style/conversion/types.hpp.ejs b/platform/android/src/style/conversion/types.hpp.ejs
index de26d061f7..d248d42b72 100644
--- a/platform/android/src/style/conversion/types.hpp.ejs
+++ b/platform/android/src/style/conversion/types.hpp.ejs
@@ -1,7 +1,7 @@
<%
const properties = locals.properties;
-%>
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
#pragma once
#include "types_string_values.hpp"
diff --git a/platform/android/src/style/conversion/types_string_values.hpp b/platform/android/src/style/conversion/types_string_values.hpp
index b42ca52acd..9f21a2fed9 100644
--- a/platform/android/src/style/conversion/types_string_values.hpp
+++ b/platform/android/src/style/conversion/types_string_values.hpp
@@ -1,4 +1,4 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
#pragma once
#include <mbgl/style/types.hpp>
diff --git a/platform/android/src/style/conversion/types_string_values.hpp.ejs b/platform/android/src/style/conversion/types_string_values.hpp.ejs
index 39021d390d..c1646baa1a 100644
--- a/platform/android/src/style/conversion/types_string_values.hpp.ejs
+++ b/platform/android/src/style/conversion/types_string_values.hpp.ejs
@@ -1,7 +1,7 @@
<%
const properties = locals.properties;
-%>
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
#pragma once
#include <mbgl/style/types.hpp>
diff --git a/platform/android/src/style/layers/background_layer.cpp b/platform/android/src/style/layers/background_layer.cpp
index 25526a07fa..021ac947ad 100644
--- a/platform/android/src/style/layers/background_layer.cpp
+++ b/platform/android/src/style/layers/background_layer.cpp
@@ -1,4 +1,4 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
#include "background_layer.hpp"
diff --git a/platform/android/src/style/layers/background_layer.hpp b/platform/android/src/style/layers/background_layer.hpp
index f201213e46..bd62c024f4 100644
--- a/platform/android/src/style/layers/background_layer.hpp
+++ b/platform/android/src/style/layers/background_layer.hpp
@@ -1,4 +1,4 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
#pragma once
diff --git a/platform/android/src/style/layers/circle_layer.cpp b/platform/android/src/style/layers/circle_layer.cpp
index c2d6ff06d1..4a6ba95d31 100644
--- a/platform/android/src/style/layers/circle_layer.cpp
+++ b/platform/android/src/style/layers/circle_layer.cpp
@@ -1,4 +1,4 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
#include "circle_layer.hpp"
@@ -63,6 +63,24 @@ namespace android {
return jni::Object<jni::ObjectTag>(*converted);
}
+ jni::Object<jni::ObjectTag> CircleLayer::getCircleStrokeWidth(jni::JNIEnv& env) {
+ using namespace mbgl::android::conversion;
+ Result<jni::jobject*> converted = convert<jni::jobject*>(env, layer.as<mbgl::style::CircleLayer>()->CircleLayer::getCircleStrokeWidth());
+ return jni::Object<jni::ObjectTag>(*converted);
+ }
+
+ jni::Object<jni::ObjectTag> CircleLayer::getCircleStrokeColor(jni::JNIEnv& env) {
+ using namespace mbgl::android::conversion;
+ Result<jni::jobject*> converted = convert<jni::jobject*>(env, layer.as<mbgl::style::CircleLayer>()->CircleLayer::getCircleStrokeColor());
+ return jni::Object<jni::ObjectTag>(*converted);
+ }
+
+ jni::Object<jni::ObjectTag> CircleLayer::getCircleStrokeOpacity(jni::JNIEnv& env) {
+ using namespace mbgl::android::conversion;
+ Result<jni::jobject*> converted = convert<jni::jobject*>(env, layer.as<mbgl::style::CircleLayer>()->CircleLayer::getCircleStrokeOpacity());
+ return jni::Object<jni::ObjectTag>(*converted);
+ }
+
jni::Class<CircleLayer> CircleLayer::javaClass;
jni::jobject* CircleLayer::createJavaPeer(jni::JNIEnv& env) {
@@ -88,7 +106,10 @@ namespace android {
METHOD(&CircleLayer::getCircleOpacity, "nativeGetCircleOpacity"),
METHOD(&CircleLayer::getCircleTranslate, "nativeGetCircleTranslate"),
METHOD(&CircleLayer::getCircleTranslateAnchor, "nativeGetCircleTranslateAnchor"),
- METHOD(&CircleLayer::getCirclePitchScale, "nativeGetCirclePitchScale"));
+ METHOD(&CircleLayer::getCirclePitchScale, "nativeGetCirclePitchScale"),
+ METHOD(&CircleLayer::getCircleStrokeWidth, "nativeGetCircleStrokeWidth"),
+ METHOD(&CircleLayer::getCircleStrokeColor, "nativeGetCircleStrokeColor"),
+ METHOD(&CircleLayer::getCircleStrokeOpacity, "nativeGetCircleStrokeOpacity"));
}
} // namespace android
diff --git a/platform/android/src/style/layers/circle_layer.hpp b/platform/android/src/style/layers/circle_layer.hpp
index 91c99c686e..d45984f23b 100644
--- a/platform/android/src/style/layers/circle_layer.hpp
+++ b/platform/android/src/style/layers/circle_layer.hpp
@@ -1,4 +1,4 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
#pragma once
@@ -39,6 +39,12 @@ public:
jni::Object<jni::ObjectTag> getCirclePitchScale(jni::JNIEnv&);
+ jni::Object<jni::ObjectTag> getCircleStrokeWidth(jni::JNIEnv&);
+
+ jni::Object<jni::ObjectTag> getCircleStrokeColor(jni::JNIEnv&);
+
+ jni::Object<jni::ObjectTag> getCircleStrokeOpacity(jni::JNIEnv&);
+
jni::jobject* createJavaPeer(jni::JNIEnv&);
}; // class CircleLayer
diff --git a/platform/android/src/style/layers/custom_layer.cpp b/platform/android/src/style/layers/custom_layer.cpp
index 6568455c67..d5d330a019 100644
--- a/platform/android/src/style/layers/custom_layer.cpp
+++ b/platform/android/src/style/layers/custom_layer.cpp
@@ -2,7 +2,7 @@
#include <string>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
namespace mbgl {
namespace android {
diff --git a/platform/android/src/style/layers/fill_layer.cpp b/platform/android/src/style/layers/fill_layer.cpp
index 8cb96c9cd3..84d47b6afe 100644
--- a/platform/android/src/style/layers/fill_layer.cpp
+++ b/platform/android/src/style/layers/fill_layer.cpp
@@ -1,4 +1,4 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
#include "fill_layer.hpp"
diff --git a/platform/android/src/style/layers/fill_layer.hpp b/platform/android/src/style/layers/fill_layer.hpp
index 5dbd7a3412..7609a5742f 100644
--- a/platform/android/src/style/layers/fill_layer.hpp
+++ b/platform/android/src/style/layers/fill_layer.hpp
@@ -1,4 +1,4 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
#pragma once
diff --git a/platform/android/src/style/layers/layer.cpp b/platform/android/src/style/layers/layer.cpp
index 3c1fc0af62..c0c57c839d 100644
--- a/platform/android/src/style/layers/layer.cpp
+++ b/platform/android/src/style/layers/layer.cpp
@@ -3,7 +3,7 @@
#include <jni/jni.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
//Java -> C++ conversion
#include <mbgl/style/conversion.hpp>
@@ -32,8 +32,21 @@ namespace android {
Layer::~Layer() {
}
- jni::String Layer::getId(jni::JNIEnv& env) {
- return jni::Make<jni::String>(env, layer.getID());
+ void Layer::addToMap(mbgl::Map& _map, mbgl::optional<std::string> before) {
+ //Check to see if we own the layer first
+ if (!ownedLayer) {
+ throw std::runtime_error("Cannot add layer twice");
+ }
+
+ //Add layer to map
+ _map.addLayer(releaseCoreLayer(), before);
+
+ //Save pointer to the map
+ this->map = &_map;
+ }
+
+ void Layer::setLayer(std::unique_ptr<mbgl::style::Layer> sourceLayer) {
+ this->ownedLayer = std::move(sourceLayer);
}
std::unique_ptr<mbgl::style::Layer> Layer::releaseCoreLayer() {
@@ -41,6 +54,14 @@ namespace android {
return std::move(ownedLayer);
}
+ jni::String Layer::getId(jni::JNIEnv& env) {
+ return jni::Make<jni::String>(env, layer.getID());
+ }
+
+ style::Layer& Layer::get() {
+ return layer;
+ }
+
void Layer::setLayoutProperty(jni::JNIEnv& env, jni::String jname, jni::Object<> jvalue) {
Value value(env, jvalue);
diff --git a/platform/android/src/style/layers/layer.cpp.ejs b/platform/android/src/style/layers/layer.cpp.ejs
index 68dd27b801..500c76ea7a 100644
--- a/platform/android/src/style/layers/layer.cpp.ejs
+++ b/platform/android/src/style/layers/layer.cpp.ejs
@@ -2,9 +2,9 @@
const type = locals.type;
const properties = locals.properties;
-%>
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
-#include "<%- type %>_layer.hpp"
+#include "<%- type.replace('-', '_') %>_layer.hpp"
#include <string>
diff --git a/platform/android/src/style/layers/layer.hpp b/platform/android/src/style/layers/layer.hpp
index 024a3c38b7..f3cd073552 100644
--- a/platform/android/src/style/layers/layer.hpp
+++ b/platform/android/src/style/layers/layer.hpp
@@ -34,10 +34,16 @@ public:
virtual jni::jobject* createJavaPeer(jni::JNIEnv&) = 0;
+ /**
+ * Set core layer (ie return ownership after remove)
+ */
+ void setLayer(std::unique_ptr<mbgl::style::Layer>);
+
+ void addToMap(mbgl::Map&, mbgl::optional<std::string>);
+
jni::String getId(jni::JNIEnv&);
- //Release the owned view and return it
- std::unique_ptr<mbgl::style::Layer> releaseCoreLayer();
+ style::Layer& get();
void setLayoutProperty(jni::JNIEnv&, jni::String, jni::Object<> value);
@@ -64,8 +70,16 @@ public:
jni::Object<jni::ObjectTag> getVisibility(jni::JNIEnv&);
protected:
+ //Release the owned view and return it
+ std::unique_ptr<mbgl::style::Layer> releaseCoreLayer();
+
+ //Owned layer is set when creating a new layer, before adding it to the map
std::unique_ptr<mbgl::style::Layer> ownedLayer;
+
+ //Raw reference to the layer
mbgl::style::Layer& layer;
+
+ //Map is set when the layer is retrieved or after adding to the map
mbgl::Map* map;
};
diff --git a/platform/android/src/style/layers/layer.hpp.ejs b/platform/android/src/style/layers/layer.hpp.ejs
index 826e133fca..3d715746ff 100644
--- a/platform/android/src/style/layers/layer.hpp.ejs
+++ b/platform/android/src/style/layers/layer.hpp.ejs
@@ -2,12 +2,12 @@
const type = locals.type;
const properties = locals.properties;
-%>
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
#pragma once
#include "layer.hpp"
-#include <mbgl/style/layers/<%- type %>_layer.hpp>
+#include <mbgl/style/layers/<%- type.replace('-', '_') %>_layer.hpp>
#include <jni/jni.hpp>
namespace mbgl {
diff --git a/platform/android/src/style/layers/line_layer.cpp b/platform/android/src/style/layers/line_layer.cpp
index 91d3e4a1cd..2dce8b618a 100644
--- a/platform/android/src/style/layers/line_layer.cpp
+++ b/platform/android/src/style/layers/line_layer.cpp
@@ -1,4 +1,4 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
#include "line_layer.hpp"
diff --git a/platform/android/src/style/layers/line_layer.hpp b/platform/android/src/style/layers/line_layer.hpp
index da9b564325..e2fc93329e 100644
--- a/platform/android/src/style/layers/line_layer.hpp
+++ b/platform/android/src/style/layers/line_layer.hpp
@@ -1,4 +1,4 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
#pragma once
diff --git a/platform/android/src/style/layers/raster_layer.cpp b/platform/android/src/style/layers/raster_layer.cpp
index da78ccb8e3..25b26155ae 100644
--- a/platform/android/src/style/layers/raster_layer.cpp
+++ b/platform/android/src/style/layers/raster_layer.cpp
@@ -1,4 +1,4 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
#include "raster_layer.hpp"
diff --git a/platform/android/src/style/layers/raster_layer.hpp b/platform/android/src/style/layers/raster_layer.hpp
index e59cd05f87..3cc2d96dde 100644
--- a/platform/android/src/style/layers/raster_layer.hpp
+++ b/platform/android/src/style/layers/raster_layer.hpp
@@ -1,4 +1,4 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
#pragma once
diff --git a/platform/android/src/style/layers/symbol_layer.cpp b/platform/android/src/style/layers/symbol_layer.cpp
index fd69b6591f..9318d42d5b 100644
--- a/platform/android/src/style/layers/symbol_layer.cpp
+++ b/platform/android/src/style/layers/symbol_layer.cpp
@@ -1,4 +1,4 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
#include "symbol_layer.hpp"
diff --git a/platform/android/src/style/layers/symbol_layer.hpp b/platform/android/src/style/layers/symbol_layer.hpp
index f5165327bf..1048b01b14 100644
--- a/platform/android/src/style/layers/symbol_layer.hpp
+++ b/platform/android/src/style/layers/symbol_layer.hpp
@@ -1,4 +1,4 @@
-// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make style-code-android`.
+// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`.
#pragma once
diff --git a/platform/android/src/style/sources/source.cpp b/platform/android/src/style/sources/source.cpp
index f3daa777d1..aca7bd6a84 100644
--- a/platform/android/src/style/sources/source.cpp
+++ b/platform/android/src/style/sources/source.cpp
@@ -3,7 +3,7 @@
#include <jni/jni.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
//Java -> C++ conversion
#include <mbgl/style/conversion.hpp>
@@ -31,10 +31,31 @@ namespace android {
Source::~Source() {
}
+ style::Source& Source::get() {
+ return source;
+ }
+
+ void Source::setSource(std::unique_ptr<style::Source> coreSource) {
+ this->ownedSource = std::move(coreSource);
+ }
+
jni::String Source::getId(jni::JNIEnv& env) {
return jni::Make<jni::String>(env, source.getID());
}
+ void Source::addToMap(mbgl::Map& _map) {
+ //Check to see if we own the source first
+ if (!ownedSource) {
+ throw std::runtime_error("Cannot add source twice");
+ }
+
+ //Add source to map
+ _map.addSource(releaseCoreSource());
+
+ //Save pointer to the map
+ this->map = &_map;
+ }
+
std::unique_ptr<mbgl::style::Source> Source::releaseCoreSource() {
assert(ownedSource != nullptr);
return std::move(ownedSource);
diff --git a/platform/android/src/style/sources/source.hpp b/platform/android/src/style/sources/source.hpp
index 0785e4d4e0..0e5d354d93 100644
--- a/platform/android/src/style/sources/source.hpp
+++ b/platform/android/src/style/sources/source.hpp
@@ -32,16 +32,30 @@ public:
virtual ~Source();
+ /**
+ * Set core source (ie return ownership after remove)
+ */
+ void setSource(std::unique_ptr<style::Source>);
+
+ style::Source& get();
+
+ void addToMap(mbgl::Map&);
+
virtual jni::jobject* createJavaPeer(jni::JNIEnv&) = 0;
jni::String getId(jni::JNIEnv&);
+protected:
//Release the owned view and return it
std::unique_ptr<mbgl::style::Source> releaseCoreSource();
-protected:
+ //Set on newly created sources until added to the map
std::unique_ptr<mbgl::style::Source> ownedSource;
+
+ //Raw pointer that is valid until the source is removed from the map
mbgl::style::Source& source;
+
+ //Map pointer is valid for newly created sources only after adding to the map
mbgl::Map* map;
};
diff --git a/platform/android/src/test/Main.java b/platform/android/src/test/Main.java
new file mode 100644
index 0000000000..2abcf2bfdb
--- /dev/null
+++ b/platform/android/src/test/Main.java
@@ -0,0 +1,15 @@
+
+public class Main {
+ public native void runAllTests();
+
+ public static void main(String[] args) throws Exception {
+ //Load the tests
+ System.loadLibrary("mbgl-test");
+
+ //Run the tests
+ new Main().runAllTests();
+
+ //Exit explicitly otherwise dalvikvm won't quit
+ System.exit(0);
+ }
+}
diff --git a/platform/android/src/test/main.jni.cpp b/platform/android/src/test/main.jni.cpp
new file mode 100644
index 0000000000..d37b908202
--- /dev/null
+++ b/platform/android/src/test/main.jni.cpp
@@ -0,0 +1,76 @@
+#include "../jni.hpp"
+
+#include <android/log.h>
+#include <jni/jni.hpp>
+
+#include <mbgl/util/logging.hpp>
+#include <mbgl/test.hpp>
+
+#pragma clang diagnostic ignored "-Wunused-parameter"
+
+#define MAKE_NATIVE_METHOD(name, sig) jni::MakeNativeMethod<decltype(name), name>( #name, sig )
+
+namespace {
+
+/**
+ * JNI Bound to Main#runAllTests()
+ */
+void runAllTests(JNIEnv *env, jni::jobject* obj) {
+ mbgl::Log::Info(mbgl::Event::JNI, "Starting tests");
+ mbgl::runTests(0, nullptr);
+}
+
+}
+
+// JNI Bindings to stub the android.util.Log implementation
+
+static jboolean isLoggable(JNIEnv* env, jni::jobject* clazz, jni::jstring* tag, jint level) {
+ return true;
+}
+
+static jint println_native(JNIEnv* env, jni::jobject* clazz, jint bufID, jint priority, jni::jstring* jtag, jni::jstring* jmessage) {
+ if (jtag == nullptr || jmessage == nullptr) {
+ return false;
+ }
+
+ std::string tag = jni::Make<std::string>(*env, jni::String(jtag));
+ std::string message = jni::Make<std::string>(*env, jni::String(jmessage));
+
+ return __android_log_print(priority, tag.c_str(), "%s", message.c_str());
+}
+
+static jint logger_entry_max_payload_native(JNIEnv* env, jni::jobject* clazz) {
+ return static_cast<jint>(4068);
+}
+
+
+// Main entry point
+
+extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
+ //Load the main library jni bindings
+ mbgl::Log::Info(mbgl::Event::JNI, "Registering main JNI Methods");
+ mbgl::android::registerNatives(vm);
+
+ //Load the test library jni bindings
+ mbgl::Log::Info(mbgl::Event::JNI, "Registering test JNI Methods");
+
+ jni::JNIEnv& env = jni::GetEnv(*vm, jni::jni_version_1_6);
+
+ //Main class (entry point for tests from dalvikvm)
+ struct Main { static constexpr auto Name() { return "Main"; } };
+ jni::RegisterNatives(env, jni::Class<Main>::Find(env), MAKE_NATIVE_METHOD(runAllTests, "()V"));
+
+ //Bindings for system classes
+ struct Log { static constexpr auto Name() { return "android/util/Log"; } };
+ try {
+ jni::RegisterNatives(env, jni::Class<Log>::Find(env),
+ MAKE_NATIVE_METHOD(isLoggable, "(Ljava/lang/String;I)Z"),
+ MAKE_NATIVE_METHOD(logger_entry_max_payload_native, "()I"),
+ MAKE_NATIVE_METHOD(println_native, "(IILjava/lang/String;Ljava/lang/String;)I")
+ );
+ } catch (jni::PendingJavaException ex) {
+ env.ThrowNew(jni::JavaErrorClass(env), "Could not register Log mocks");
+ }
+
+ return JNI_VERSION_1_6;
+}
diff --git a/platform/android/src/thread.cpp b/platform/android/src/thread.cpp
index 77f9815866..c708dfdceb 100644
--- a/platform/android/src/thread.cpp
+++ b/platform/android/src/thread.cpp
@@ -1,5 +1,5 @@
-#include <mbgl/platform/log.hpp>
-#include <mbgl/platform/platform.hpp>
+#include <mbgl/util/logging.hpp>
+#include <mbgl/util/platform.hpp>
#include <sys/prctl.h>
#include <sys/resource.h>
diff --git a/platform/android/tests/docs/ACTIVITY_SANITY_TEST.md b/platform/android/tests/docs/ACTIVITY_SANITY_TEST.md
index 14e4335111..7422599c38 100644
--- a/platform/android/tests/docs/ACTIVITY_SANITY_TEST.md
+++ b/platform/android/tests/docs/ACTIVITY_SANITY_TEST.md
@@ -6,7 +6,7 @@ This type of test checks if an Activity doesn't crash at start up. For this proj
The generation is done by executing:
-> make android-generate-test
+> make test-code-android
This command underneath executes the following js file found in:
diff --git a/include/mbgl/platform/darwin/reachability.h b/platform/darwin/mbgl/storage/reachability.h
index 78e302eafc..78e302eafc 100644
--- a/include/mbgl/platform/darwin/reachability.h
+++ b/platform/darwin/mbgl/storage/reachability.h
diff --git a/platform/darwin/src/reachability.m b/platform/darwin/mbgl/storage/reachability.m
index 8abcf5ae6d..aa6746a2a9 100644
--- a/platform/darwin/src/reachability.m
+++ b/platform/darwin/mbgl/storage/reachability.m
@@ -25,7 +25,7 @@
POSSIBILITY OF SUCH DAMAGE.
*/
-#import <mbgl/platform/darwin/reachability.h>
+#import <mbgl/storage/reachability.h>
#import <sys/socket.h>
#import <netinet/in.h>
diff --git a/platform/darwin/resources/zh-Hans.lproj/Foundation.strings b/platform/darwin/resources/zh-Hans.lproj/Foundation.strings
new file mode 100644
index 0000000000..7dec6184e5
--- /dev/null
+++ b/platform/darwin/resources/zh-Hans.lproj/Foundation.strings
@@ -0,0 +1,291 @@
+/* Clock position format, long: {hours} o’clock */
+"CLOCK_FMT_LONG" = "%@点";
+
+/* Clock position format, medium: {hours} o’clock */
+"CLOCK_FMT_MEDIUM" = "%@点";
+
+/* Clock position format, short: {hours}:00 */
+"CLOCK_FMT_SHORT" = "%@:00";
+
+/* East, long */
+"COMPASS_E_LONG" = "东";
+
+/* East, short */
+"COMPASS_E_SHORT" = "东";
+
+/* East by north, long */
+"COMPASS_EbN_LONG" = "东微北";
+
+/* East by north, short */
+"COMPASS_EbN_SHORT" = "东微北";
+
+/* East by south, long */
+"COMPASS_EbS_LONG" = "东微南";
+
+/* East by south, short */
+"COMPASS_EbS_SHORT" = "东微南";
+
+/* East-northeast, long */
+"COMPASS_ENE_LONG" = "东北偏东";
+
+/* East-northeast, short */
+"COMPASS_ENE_SHORT" = "东北偏东";
+
+/* East-southeast, long */
+"COMPASS_ESE_LONG" = "东南偏东";
+
+/* East-southeast, short */
+"COMPASS_ESE_SHORT" = "东南偏东";
+
+/* North, long */
+"COMPASS_N_LONG" = "北";
+
+/* North, short */
+"COMPASS_N_SHORT" = "北";
+
+/* North by east, long */
+"COMPASS_NbE_LONG" = "北微东";
+
+/* North by east, short */
+"COMPASS_NbE_SHORT" = "北微东";
+
+/* North by west, long */
+"COMPASS_NbW_LONG" = "北微西";
+
+/* North by west, short */
+"COMPASS_NbW_SHORT" = "北微西";
+
+/* Northeast, long */
+"COMPASS_NE_LONG" = "东北";
+
+/* Northeast, short */
+"COMPASS_NE_SHORT" = "东北";
+
+/* Northeast by east, long */
+"COMPASS_NEbE_LONG" = "东北微东";
+
+/* Northeast by east, short */
+"COMPASS_NEbE_SHORT" = "东北微东";
+
+/* Northeast by north, long */
+"COMPASS_NEbN_LONG" = "东北微北";
+
+/* Northeast by north, short */
+"COMPASS_NEbN_SHORT" = "东北微北";
+
+/* North-northeast, long */
+"COMPASS_NNE_LONG" = "东北偏北";
+
+/* North-northeast, short */
+"COMPASS_NNE_SHORT" = "东北偏北";
+
+/* North-northwest, long */
+"COMPASS_NNW_LONG" = "西北偏北";
+
+/* North-northwest, short */
+"COMPASS_NNW_SHORT" = "西北偏北";
+
+/* Northwest, long */
+"COMPASS_NW_LONG" = "西北";
+
+/* Northwest, short */
+"COMPASS_NW_SHORT" = "西北";
+
+/* Northwest by north, long */
+"COMPASS_NWbN_LONG" = "西北微北";
+
+/* Northwest by north, short */
+"COMPASS_NWbN_SHORT" = "西北微北";
+
+/* Northwest by west, long */
+"COMPASS_NWbW_LONG" = "西北微西";
+
+/* Northwest by west, short */
+"COMPASS_NWbW_SHORT" = "西北微西";
+
+/* South, long */
+"COMPASS_S_LONG" = "南";
+
+/* South, short */
+"COMPASS_S_SHORT" = "南";
+
+/* South by east, long */
+"COMPASS_SbE_LONG" = "南微东";
+
+/* South by east, short */
+"COMPASS_SbE_SHORT" = "南微东";
+
+/* South by west, long */
+"COMPASS_SbW_LONG" = "南微西";
+
+/* South by west, short */
+"COMPASS_SbW_SHORT" = "南微西";
+
+/* Southeast, long */
+"COMPASS_SE_LONG" = "东南";
+
+/* Southeast, short */
+"COMPASS_SE_SHORT" = "东南";
+
+/* Southeast by east, long */
+"COMPASS_SEbE_LONG" = "东南微东";
+
+/* Southeast by east, short */
+"COMPASS_SEbE_SHORT" = "东南微东";
+
+/* Southeast by south, long */
+"COMPASS_SEbS_LONG" = "东南微南";
+
+/* Southeast by south, short */
+"COMPASS_SEbS_SHORT" = "东南微南";
+
+/* South-southeast, long */
+"COMPASS_SSE_LONG" = "东南偏南";
+
+/* South-southeast, short */
+"COMPASS_SSE_SHORT" = "东南偏南";
+
+/* South-southwest, long */
+"COMPASS_SSW_LONG" = "西南偏南";
+
+/* South-southwest, short */
+"COMPASS_SSW_SHORT" = "西南偏南";
+
+/* Southwest, long */
+"COMPASS_SW_LONG" = "西南";
+
+/* Southwest, short */
+"COMPASS_SW_SHORT" = "西南";
+
+/* Southwest by south, long */
+"COMPASS_SWbS_LONG" = "西南偏南";
+
+/* Southwest by south, short */
+"COMPASS_SWbS_SHORT" = "西南偏南";
+
+/* Southwest by west, long */
+"COMPASS_SWbW_LONG" = "西南偏西";
+
+/* Southwest by west, short */
+"COMPASS_SWbW_SHORT" = "西南偏西";
+
+/* West, long */
+"COMPASS_W_LONG" = "西";
+
+/* West, short */
+"COMPASS_W_SHORT" = "西";
+
+/* West by north, long */
+"COMPASS_WbN_LONG" = "西微北";
+
+/* West by north, short */
+"COMPASS_WbN_SHORT" = "西微北";
+
+/* West by south, long */
+"COMPASS_WbS_LONG" = "西微南";
+
+/* West by south, short */
+"COMPASS_WbS_SHORT" = "西微南";
+
+/* West-northwest, long */
+"COMPASS_WNW_LONG" = "西北偏西";
+
+/* West-northwest, short */
+"COMPASS_WNW_SHORT" = "西北偏西";
+
+/* West-southwest, long */
+"COMPASS_WSW_LONG" = "西南偏西";
+
+/* West-southwest, short */
+"COMPASS_WSW_SHORT" = "西南偏西";
+
+/* Degrees format, long */
+"COORD_DEG_LONG" = "%d度";
+
+/* Degrees format, medium: {degrees} */
+"COORD_DEG_MEDIUM" = "%d°";
+
+/* Degrees format, short: {degrees} */
+"COORD_DEG_SHORT" = "%d°";
+
+/* Coordinate format, long: {degrees}{minutes} */
+"COORD_DM_LONG" = "%1$@度%2$@分";
+
+/* Coordinate format, medium: {degrees}{minutes} */
+"COORD_DM_MEDIUM" = "%1$@度%2$@";
+
+/* Coordinate format, short: {degrees}{minutes} */
+"COORD_DM_SHORT" = "%1$@%度2$@";
+
+/* Coordinate format, long: {degrees}{minutes}{seconds} */
+"COORD_DMS_LONG" = "%1$@度%2$@分%3$@秒";
+
+/* Coordinate format, medium: {degrees}{minutes}{seconds} */
+"COORD_DMS_MEDIUM" = "%1$@度%2$@分%3$@秒";
+
+/* Coordinate format, short: {degrees}{minutes}{seconds} */
+"COORD_DMS_SHORT" = "%1$@%度2$@分%3$@秒";
+
+/* East longitude format, long: {longitude} */
+"COORD_E_LONG" = "东经%@";
+
+/* East longitude format, medium: {longitude} */
+"COORD_E_MEDIUM" = "东经%@";
+
+/* East longitude format, short: {longitude} */
+"COORD_E_SHORT" = "%@E";
+
+/* Coordinate pair format, long: {latitude}, {longitude} */
+"COORD_FMT_LONG" = "%1$@,%2$@";
+
+/* Coordinate pair format, medium: {latitude}, {longitude} */
+"COORD_FMT_MEDIUM" = "%1$@,%2$@";
+
+/* Coordinate pair format, short: {latitude}, {longitude} */
+"COORD_FMT_SHORT" = "%1$@,%2$@";
+
+/* Minutes format, long */
+"COORD_MIN_LONG" = "%d分";
+
+/* Minutes format, medium: {minutes} */
+"COORD_MIN_MEDIUM" = "%d′";
+
+/* Minutes format, short: {minutes} */
+"COORD_MIN_SHORT" = "%d′";
+
+/* North latitude format, long: {latitude} */
+"COORD_N_LONG" = "北纬%@";
+
+/* North latitude format, medium: {latitude} */
+"COORD_N_MEDIUM" = "北纬%@";
+
+/* North latitude format, short: {latitude} */
+"COORD_N_SHORT" = "%@N";
+
+/* South latitude format, long: {latitude} */
+"COORD_S_LONG" = "南纬%@";
+
+/* South latitude format, medium: {latitude} */
+"COORD_S_MEDIUM" = "南纬%@";
+
+/* South latitude format, short: {latitude} */
+"COORD_S_SHORT" = "%@S";
+
+/* Seconds format, long */
+"COORD_SEC_LONG" = "%d秒";
+
+/* Seconds format, medium: {seconds} */
+"COORD_SEC_MEDIUM" = "%d″";
+
+/* Seconds format, short: {seconds} */
+"COORD_SEC_SHORT" = "%d″";
+
+/* West longitude format, long: {longitude} */
+"COORD_W_LONG" = "西经%@";
+
+/* West longitude format, medium: {longitude} */
+"COORD_W_MEDIUM" = "西经%@";
+
+/* West longitude format, short: {longitude} */
+"COORD_W_SHORT" = "%@W";
+
diff --git a/platform/darwin/scripts/generate-style-code.js b/platform/darwin/scripts/generate-style-code.js
index 9e79d0a321..e7041ad9f3 100644
--- a/platform/darwin/scripts/generate-style-code.js
+++ b/platform/darwin/scripts/generate-style-code.js
@@ -4,6 +4,9 @@ const fs = require('fs');
const ejs = require('ejs');
const _ = require('lodash');
const colorParser = require('csscolorparser');
+
+require('../../../scripts/style-code');
+
const cocoaConventions = require('./style-spec-cocoa-conventions-v8.json');
let spec = _.merge(require('mapbox-gl-style-spec').latest, require('./style-spec-overrides-v8.json'));
const prefix = 'MGL';
@@ -46,18 +49,6 @@ _.forOwn(cocoaConventions, function (properties, kind) {
})
});
-global.camelize = function (str) {
- return str.replace(/(?:^|-)(.)/g, function (_, x) {
- return x.toUpperCase();
- });
-};
-
-global.camelizeWithLeadingLowercase = function (str) {
- return str.replace(/-(.)/g, function (_, x) {
- return x.toUpperCase();
- });
-};
-
global.objCName = function (property) {
return camelizeWithLeadingLowercase(property.name);
}
@@ -403,9 +394,9 @@ for (var layer of layers) {
const containsEnumerationProperties = _.filter(layer.layoutProperties, function(property){ return property["type"] === "enum"; }).length || _.filter(layer.paintProperties, function(property){ return property["type"] === "enum"; }).length;
layer.containsEnumerationProperties = containsEnumerationProperties;
- fs.writeFileSync(`platform/darwin/src/${prefix}${camelize(layer.type)}${suffix}.h`, duplicatePlatformDecls(layerH(layer)));
- fs.writeFileSync(`platform/darwin/src/${prefix}${camelize(layer.type)}${suffix}.mm`, layerM(layer));
- fs.writeFileSync(`platform/darwin/test/${prefix}${camelize(layer.type)}${suffix}Tests.m`, testLayers(layer));
+ writeIfModified(`platform/darwin/src/${prefix}${camelize(layer.type)}${suffix}.h`, duplicatePlatformDecls(layerH(layer)));
+ writeIfModified(`platform/darwin/src/${prefix}${camelize(layer.type)}${suffix}.mm`, layerM(layer));
+ writeIfModified(`platform/darwin/test/${prefix}${camelize(layer.type)}${suffix}Tests.m`, testLayers(layer));
}
fs.writeFileSync(`platform/darwin/src/NSValue+MGLStyleEnumAttributeAdditions.h`, categoryH({
diff --git a/platform/darwin/src/MGLCircleStyleLayer.h b/platform/darwin/src/MGLCircleStyleLayer.h
index 2d88a664ba..8c95b72123 100644
--- a/platform/darwin/src/MGLCircleStyleLayer.h
+++ b/platform/darwin/src/MGLCircleStyleLayer.h
@@ -94,6 +94,38 @@ typedef NS_ENUM(NSUInteger, MGLCircleTranslateAnchor) {
*/
@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *circleRadius;
+#if TARGET_OS_IPHONE
+/**
+ The stroke color of the circle.
+
+ 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) MGLStyleValue<MGLColor *> *circleStrokeColor;
+#else
+/**
+ The stroke color of the circle.
+
+ 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) MGLStyleValue<MGLColor *> *circleStrokeColor;
+#endif
+
+/**
+ The opacity of the circle's stroke.
+
+ 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) MGLStyleValue<NSNumber *> *circleStrokeOpacity;
+
+/**
+ The width of the circle's stroke. Strokes are placed outside of the `circleRadius`.
+
+ This property is measured in points.
+
+ 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) MGLStyleValue<NSNumber *> *circleStrokeWidth;
+
/**
The geometry's offset.
diff --git a/platform/darwin/src/MGLCircleStyleLayer.mm b/platform/darwin/src/MGLCircleStyleLayer.mm
index 266f2d836e..e8ee2bca7e 100644
--- a/platform/darwin/src/MGLCircleStyleLayer.mm
+++ b/platform/darwin/src/MGLCircleStyleLayer.mm
@@ -194,6 +194,48 @@ namespace mbgl {
return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
}
+- (void)setCircleStrokeColor:(MGLStyleValue<MGLColor *> *)circleStrokeColor {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue(circleStrokeColor);
+ self.rawLayer->setCircleStrokeColor(mbglValue);
+}
+
+- (MGLStyleValue<MGLColor *> *)circleStrokeColor {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = self.rawLayer->getCircleStrokeColor() ?: self.rawLayer->getDefaultCircleStrokeColor();
+ return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(propertyValue);
+}
+
+- (void)setCircleStrokeOpacity:(MGLStyleValue<NSNumber *> *)circleStrokeOpacity {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(circleStrokeOpacity);
+ self.rawLayer->setCircleStrokeOpacity(mbglValue);
+}
+
+- (MGLStyleValue<NSNumber *> *)circleStrokeOpacity {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = self.rawLayer->getCircleStrokeOpacity() ?: self.rawLayer->getDefaultCircleStrokeOpacity();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
+}
+
+- (void)setCircleStrokeWidth:(MGLStyleValue<NSNumber *> *)circleStrokeWidth {
+ MGLAssertStyleLayerIsValid();
+
+ auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue(circleStrokeWidth);
+ self.rawLayer->setCircleStrokeWidth(mbglValue);
+}
+
+- (MGLStyleValue<NSNumber *> *)circleStrokeWidth {
+ MGLAssertStyleLayerIsValid();
+
+ auto propertyValue = self.rawLayer->getCircleStrokeWidth() ?: self.rawLayer->getDefaultCircleStrokeWidth();
+ return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue);
+}
+
- (void)setCircleTranslate:(MGLStyleValue<NSValue *> *)circleTranslate {
MGLAssertStyleLayerIsValid();
diff --git a/platform/darwin/src/MGLStyle.mm b/platform/darwin/src/MGLStyle.mm
index c2ae75ed9c..9ea9e760f5 100644
--- a/platform/darwin/src/MGLStyle.mm
+++ b/platform/darwin/src/MGLStyle.mm
@@ -36,7 +36,6 @@
#include <mbgl/style/sources/geojson_source.hpp>
#include <mbgl/style/sources/vector_source.hpp>
#include <mbgl/style/sources/raster_source.hpp>
-#include <mbgl/mbgl.hpp>
#if TARGET_OS_IPHONE
#import "UIImage+MGLAdditions.h"
@@ -71,7 +70,11 @@ static_assert(mbgl::util::default_styles::currentVersion == MGLStyleDefaultVersi
} \
\
+ (NSURL *)name##StyleURL##WithVersion:(NSInteger)version { \
- return [NSURL URLWithString:[@"mapbox://styles/mapbox/" #fileName "-v" stringByAppendingFormat:@"%li", (long)version]]; \
+ if (mbgl::util::default_styles::currentVersion == version) { \
+ return [NSURL URLWithString:@(mbgl::util::default_styles::name.url)]; \
+ } else { \
+ return [NSURL URLWithString:[@"mapbox://styles/mapbox/" #fileName "-v" stringByAppendingFormat:@"%li", (long)version]]; \
+ } \
}
MGL_DEFINE_STYLE(streets, streets)
diff --git a/platform/darwin/src/MGLStyleLayer.mm.ejs b/platform/darwin/src/MGLStyleLayer.mm.ejs
index 6178eaad51..baeed3b882 100644
--- a/platform/darwin/src/MGLStyleLayer.mm.ejs
+++ b/platform/darwin/src/MGLStyleLayer.mm.ejs
@@ -14,7 +14,7 @@
#import "MGLStyleValue_Private.h"
#import "MGL<%- camelize(type) %>StyleLayer.h"
-#include <mbgl/style/layers/<%- type %>_layer.hpp>
+#include <mbgl/style/layers/<%- type.replace('-', '_') %>_layer.hpp>
<% if (containsEnumerationProperties) { -%>
namespace mbgl {
diff --git a/platform/darwin/src/NSDate+MGLAdditions.h b/platform/darwin/src/NSDate+MGLAdditions.h
index a116ef32de..918aae233f 100644
--- a/platform/darwin/src/NSDate+MGLAdditions.h
+++ b/platform/darwin/src/NSDate+MGLAdditions.h
@@ -1,6 +1,5 @@
#import <Foundation/Foundation.h>
-#include <mbgl/mbgl.hpp>
#include <mbgl/util/chrono.hpp>
@interface NSDate (MGLAdditions)
diff --git a/platform/darwin/src/NSExpression+MGLAdditions.mm b/platform/darwin/src/NSExpression+MGLAdditions.mm
index 392a6d7f5b..25a2945cfb 100644
--- a/platform/darwin/src/NSExpression+MGLAdditions.mm
+++ b/platform/darwin/src/NSExpression+MGLAdditions.mm
@@ -72,7 +72,7 @@
NSNumber *number = (NSNumber *)value;
if ((strcmp([number objCType], @encode(char)) == 0) ||
(strcmp([number objCType], @encode(BOOL)) == 0)) {
- return mbglValue.get<bool>();
+ return uint64_t(mbglValue.get<bool>());
} else if ( strcmp([number objCType], @encode(double)) == 0 ||
strcmp([number objCType], @encode(float)) == 0) {
return mbglValue.get<double>();
diff --git a/platform/darwin/src/headless_backend_cgl.cpp b/platform/darwin/src/headless_backend_cgl.cpp
index 4ca567f55c..7069738fb1 100644
--- a/platform/darwin/src/headless_backend_cgl.cpp
+++ b/platform/darwin/src/headless_backend_cgl.cpp
@@ -1,6 +1,7 @@
-#include <mbgl/platform/default/headless_backend.hpp>
-#include <mbgl/platform/default/headless_display.hpp>
+#include <mbgl/gl/headless_backend.hpp>
+#include <mbgl/gl/headless_display.hpp>
+#include <OpenGL/OpenGL.h>
#include <CoreFoundation/CoreFoundation.h>
#include <string>
@@ -8,6 +9,33 @@
namespace mbgl {
+struct CGLImpl : public HeadlessBackend::Impl {
+ CGLImpl(CGLContextObj glContext_) : glContext(glContext_) {
+ }
+
+ ~CGLImpl() {
+ CGLDestroyContext(glContext);
+ }
+
+ void activateContext() final {
+ CGLError error = CGLSetCurrentContext(glContext);
+ if (error != kCGLNoError) {
+ throw std::runtime_error(std::string("Switching OpenGL context failed:") +
+ CGLErrorString(error) + "\n");
+ }
+ }
+
+ void deactivateContext() final {
+ CGLError error = CGLSetCurrentContext(nullptr);
+ if (error != kCGLNoError) {
+ throw std::runtime_error(std::string("Removing OpenGL context failed:") +
+ CGLErrorString(error) + "\n");
+ }
+ }
+
+ CGLContextObj glContext = nullptr;
+};
+
gl::glProc HeadlessBackend::initializeExtension(const char* name) {
static CFBundleRef framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
if (!framework) {
@@ -21,8 +49,18 @@ gl::glProc HeadlessBackend::initializeExtension(const char* name) {
return reinterpret_cast<gl::glProc>(symbol);
}
+bool HeadlessBackend::hasDisplay() {
+ if (!display) {
+ display.reset(new HeadlessDisplay);
+ }
+ return bool(display);
+}
+
void HeadlessBackend::createContext() {
- CGLError error = CGLCreateContext(display->pixelFormat, nullptr, &glContext);
+ assert(!hasContext());
+
+ CGLContextObj glContext = nullptr;
+ CGLError error = CGLCreateContext(display->attribute<CGLPixelFormatObj>(), nullptr, &glContext);
if (error != kCGLNoError) {
throw std::runtime_error(std::string("Error creating GL context object:") +
CGLErrorString(error) + "\n");
@@ -33,26 +71,8 @@ void HeadlessBackend::createContext() {
throw std::runtime_error(std::string("Error enabling OpenGL multithreading:") +
CGLErrorString(error) + "\n");
}
-}
-
-void HeadlessBackend::destroyContext() {
- CGLDestroyContext(glContext);
-}
-
-void HeadlessBackend::activateContext() {
- CGLError error = CGLSetCurrentContext(glContext);
- if (error != kCGLNoError) {
- throw std::runtime_error(std::string("Switching OpenGL context failed:") +
- CGLErrorString(error) + "\n");
- }
-}
-void HeadlessBackend::deactivateContext() {
- CGLError error = CGLSetCurrentContext(nullptr);
- if (error != kCGLNoError) {
- throw std::runtime_error(std::string("Removing OpenGL context failed:") +
- CGLErrorString(error) + "\n");
- }
+ impl.reset(new CGLImpl(glContext));
}
} // namespace mbgl
diff --git a/platform/darwin/src/headless_backend_eagl.mm b/platform/darwin/src/headless_backend_eagl.mm
index 0a1ae706b8..bd4a202ec5 100644
--- a/platform/darwin/src/headless_backend_eagl.mm
+++ b/platform/darwin/src/headless_backend_eagl.mm
@@ -1,4 +1,4 @@
-#include <mbgl/platform/default/headless_backend.hpp>
+#include <mbgl/gl/headless_backend.hpp>
#include <mbgl/gl/extension.hpp>
@@ -8,6 +8,27 @@
namespace mbgl {
+struct EAGLImpl : public HeadlessBackend::Impl {
+ EAGLImpl(EAGLContext* glContext_) : glContext(glContext_) {
+ [reinterpret_cast<EAGLContext*>(glContext) retain];
+ reinterpret_cast<EAGLContext*>(glContext).multiThreaded = YES;
+ }
+
+ ~EAGLImpl() {
+ [glContext release];
+ }
+
+ void activateContext() {
+ [EAGLContext setCurrentContext:glContext];
+ }
+
+ void deactivateContext() {
+ [EAGLContext setCurrentContext:nil];
+ }
+
+ EAGLContext* glContext = nullptr;
+};
+
gl::glProc HeadlessBackend::initializeExtension(const char* name) {
static CFBundleRef framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengles"));
if (!framework) {
@@ -21,26 +42,17 @@ gl::glProc HeadlessBackend::initializeExtension(const char* name) {
return reinterpret_cast<gl::glProc>(symbol);
}
+bool HeadlessBackend::hasDisplay() {
+ return true;
+}
+
void HeadlessBackend::createContext() {
- glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
+ EAGLContext* glContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
if (glContext == nil) {
throw std::runtime_error("Error creating GL context object");
}
- [reinterpret_cast<EAGLContext*>(glContext) retain];
- reinterpret_cast<EAGLContext*>(glContext).multiThreaded = YES;
-}
-
-void HeadlessBackend::destroyContext() {
- [reinterpret_cast<EAGLContext*>(glContext) release];
- glContext = nil;
-}
-
-void HeadlessBackend::activateContext() {
- [EAGLContext setCurrentContext:reinterpret_cast<EAGLContext*>(glContext)];
-}
-void HeadlessBackend::deactivateContext() {
- [EAGLContext setCurrentContext:nil];
+ impl.reset(new EAGLImpl(glContext));
}
} // namespace mbgl
diff --git a/platform/darwin/src/headless_display_cgl.cpp b/platform/darwin/src/headless_display_cgl.cpp
new file mode 100644
index 0000000000..90d187d3db
--- /dev/null
+++ b/platform/darwin/src/headless_display_cgl.cpp
@@ -0,0 +1,52 @@
+#include <mbgl/gl/headless_display.hpp>
+
+#include <OpenGL/OpenGL.h>
+
+#include <stdexcept>
+#include <string>
+
+namespace mbgl {
+
+class HeadlessDisplay::Impl {
+public:
+ Impl();
+ ~Impl();
+ CGLPixelFormatObj pixelFormat = nullptr;
+};
+
+HeadlessDisplay::Impl::Impl() {
+ // TODO: test if OpenGL 4.1 with GL_ARB_ES2_compatibility is supported
+ // If it is, use kCGLOGLPVersion_3_2_Core and enable that extension.
+ CGLPixelFormatAttribute attributes[] = {
+ kCGLPFAOpenGLProfile,
+ static_cast<CGLPixelFormatAttribute>(kCGLOGLPVersion_Legacy),
+ static_cast<CGLPixelFormatAttribute>(0)
+ };
+
+ GLint num;
+ CGLError error = CGLChoosePixelFormat(attributes, &pixelFormat, &num);
+ if (error != kCGLNoError) {
+ throw std::runtime_error(std::string("Error choosing pixel format:") + CGLErrorString(error) + "\n");
+ }
+ if (num <= 0) {
+ throw std::runtime_error("No pixel formats found.");
+ }
+}
+
+HeadlessDisplay::Impl::~Impl() {
+ CGLDestroyPixelFormat(pixelFormat);
+}
+
+template <>
+CGLPixelFormatObj HeadlessDisplay::attribute() const {
+ return impl->pixelFormat;
+}
+
+HeadlessDisplay::HeadlessDisplay()
+ : impl(std::make_unique<Impl>()) {
+}
+
+HeadlessDisplay::~HeadlessDisplay() {
+}
+
+} // namespace mbgl
diff --git a/platform/darwin/src/image.mm b/platform/darwin/src/image.mm
index 066535a58c..3a707d4a36 100644
--- a/platform/darwin/src/image.mm
+++ b/platform/darwin/src/image.mm
@@ -11,7 +11,7 @@
namespace mbgl {
std::string encodePNG(const PremultipliedImage& src) {
- CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, src.data.get(), src.size(), NULL);
+ CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, src.data.get(), src.bytes(), NULL);
if (!provider) {
return "";
}
@@ -22,9 +22,10 @@ std::string encodePNG(const PremultipliedImage& src) {
return "";
}
- CGImageRef image = CGImageCreate(src.width, src.height, 8, 32, 4 * src.width, color_space,
- kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast, provider, NULL, false,
- kCGRenderingIntentDefault);
+ CGImageRef image =
+ CGImageCreate(src.size.width, src.size.height, 8, 32, 4 * src.size.width, color_space,
+ kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast, provider, NULL,
+ false, kCGRenderingIntentDefault);
if (!image) {
CGColorSpaceRelease(color_space);
CGDataProviderRelease(provider);
@@ -92,11 +93,12 @@ PremultipliedImage decodeImage(const std::string &source_data) {
throw std::runtime_error("CGColorSpaceCreateDeviceRGB failed");
}
- PremultipliedImage result{ static_cast<uint16_t>(CGImageGetWidth(image)),
- static_cast<uint16_t>(CGImageGetHeight(image)) };
+ PremultipliedImage result({ static_cast<uint32_t>(CGImageGetWidth(image)),
+ static_cast<uint32_t>(CGImageGetHeight(image)) });
- CGContextRef context = CGBitmapContextCreate(result.data.get(), result.width, result.height, 8, result.stride(),
- color_space, kCGImageAlphaPremultipliedLast);
+ CGContextRef context =
+ CGBitmapContextCreate(result.data.get(), result.size.width, result.size.height, 8,
+ result.stride(), color_space, kCGImageAlphaPremultipliedLast);
if (!context) {
CGColorSpaceRelease(color_space);
CGImageRelease(image);
@@ -107,7 +109,9 @@ PremultipliedImage decodeImage(const std::string &source_data) {
CGContextSetBlendMode(context, kCGBlendModeCopy);
- CGRect rect = {{ 0, 0 }, { static_cast<CGFloat>(result.width), static_cast<CGFloat>(result.height) }};
+ CGRect rect = { { 0, 0 },
+ { static_cast<CGFloat>(result.size.width),
+ static_cast<CGFloat>(result.size.height) } };
CGContextDrawImage(context, rect, image);
CGContextRelease(context);
diff --git a/platform/darwin/src/log_nslog.mm b/platform/darwin/src/logging_nslog.mm
index 49583ae3c4..dd428f56b1 100644
--- a/platform/darwin/src/log_nslog.mm
+++ b/platform/darwin/src/logging_nslog.mm
@@ -1,4 +1,4 @@
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
#include <mbgl/util/enum.hpp>
#import <Foundation/Foundation.h>
diff --git a/platform/darwin/src/nsthread.mm b/platform/darwin/src/nsthread.mm
index eee6d6991b..6caa1be43e 100644
--- a/platform/darwin/src/nsthread.mm
+++ b/platform/darwin/src/nsthread.mm
@@ -1,6 +1,6 @@
#import <Foundation/Foundation.h>
-#include <mbgl/platform/platform.hpp>
+#include <mbgl/util/platform.hpp>
#include <pthread.h>
diff --git a/platform/darwin/src/string_nsstring.mm b/platform/darwin/src/string_nsstring.mm
index 9bf199afc0..08f9aeccef 100644
--- a/platform/darwin/src/string_nsstring.mm
+++ b/platform/darwin/src/string_nsstring.mm
@@ -1,6 +1,6 @@
#import <Foundation/Foundation.h>
-#include <mbgl/platform/platform.hpp>
+#include <mbgl/util/platform.hpp>
namespace mbgl {
namespace platform {
diff --git a/platform/darwin/test/MGLCircleStyleLayerTests.m b/platform/darwin/test/MGLCircleStyleLayerTests.m
index 66c05f15c9..ce17d93557 100644
--- a/platform/darwin/test/MGLCircleStyleLayerTests.m
+++ b/platform/darwin/test/MGLCircleStyleLayerTests.m
@@ -25,6 +25,9 @@
layer.circleOpacity = [MGLRuntimeStylingHelper testNumber];
layer.circlePitchScale = [MGLRuntimeStylingHelper testEnum:MGLCirclePitchScaleViewport type:@encode(MGLCirclePitchScale)];
layer.circleRadius = [MGLRuntimeStylingHelper testNumber];
+ layer.circleStrokeColor = [MGLRuntimeStylingHelper testColor];
+ layer.circleStrokeOpacity = [MGLRuntimeStylingHelper testNumber];
+ layer.circleStrokeWidth = [MGLRuntimeStylingHelper testNumber];
layer.circleTranslate = [MGLRuntimeStylingHelper testOffset];
layer.circleTranslateAnchor = [MGLRuntimeStylingHelper testEnum:MGLCircleTranslateAnchorViewport type:@encode(MGLCircleTranslateAnchor)];
@@ -36,6 +39,9 @@
XCTAssert([gLayer.circlePitchScale isKindOfClass:[MGLStyleConstantValue class]]);
XCTAssertEqualObjects(gLayer.circlePitchScale, [MGLRuntimeStylingHelper testEnum:MGLCirclePitchScaleViewport type:@encode(MGLCirclePitchScale)]);
XCTAssertEqualObjects(gLayer.circleRadius, [MGLRuntimeStylingHelper testNumber]);
+ XCTAssertEqualObjects(gLayer.circleStrokeColor, [MGLRuntimeStylingHelper testColor]);
+ XCTAssertEqualObjects(gLayer.circleStrokeOpacity, [MGLRuntimeStylingHelper testNumber]);
+ XCTAssertEqualObjects(gLayer.circleStrokeWidth, [MGLRuntimeStylingHelper testNumber]);
XCTAssertEqualObjects(gLayer.circleTranslate, [MGLRuntimeStylingHelper testOffset]);
XCTAssert([gLayer.circleTranslateAnchor isKindOfClass:[MGLStyleConstantValue class]]);
XCTAssertEqualObjects(gLayer.circleTranslateAnchor, [MGLRuntimeStylingHelper testEnum:MGLCircleTranslateAnchorViewport type:@encode(MGLCircleTranslateAnchor)]);
@@ -45,6 +51,9 @@
layer.circleOpacity = [MGLRuntimeStylingHelper testNumberFunction];
layer.circlePitchScale = [MGLRuntimeStylingHelper testEnumFunction:MGLCirclePitchScaleViewport type:@encode(MGLCirclePitchScale)];
layer.circleRadius = [MGLRuntimeStylingHelper testNumberFunction];
+ layer.circleStrokeColor = [MGLRuntimeStylingHelper testColorFunction];
+ layer.circleStrokeOpacity = [MGLRuntimeStylingHelper testNumberFunction];
+ layer.circleStrokeWidth = [MGLRuntimeStylingHelper testNumberFunction];
layer.circleTranslate = [MGLRuntimeStylingHelper testOffsetFunction];
layer.circleTranslateAnchor = [MGLRuntimeStylingHelper testEnumFunction:MGLCircleTranslateAnchorViewport type:@encode(MGLCircleTranslateAnchor)];
@@ -53,6 +62,9 @@
XCTAssertEqualObjects(gLayer.circleOpacity, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.circlePitchScale, [MGLRuntimeStylingHelper testEnumFunction:MGLCirclePitchScaleViewport type:@encode(MGLCirclePitchScale)]);
XCTAssertEqualObjects(gLayer.circleRadius, [MGLRuntimeStylingHelper testNumberFunction]);
+ XCTAssertEqualObjects(gLayer.circleStrokeColor, [MGLRuntimeStylingHelper testColorFunction]);
+ XCTAssertEqualObjects(gLayer.circleStrokeOpacity, [MGLRuntimeStylingHelper testNumberFunction]);
+ XCTAssertEqualObjects(gLayer.circleStrokeWidth, [MGLRuntimeStylingHelper testNumberFunction]);
XCTAssertEqualObjects(gLayer.circleTranslate, [MGLRuntimeStylingHelper testOffsetFunction]);
XCTAssertEqualObjects(gLayer.circleTranslateAnchor, [MGLRuntimeStylingHelper testEnumFunction:MGLCircleTranslateAnchorViewport type:@encode(MGLCircleTranslateAnchor)]);
}
@@ -63,6 +75,9 @@
[self testPropertyName:@"circle-opacity" isBoolean:NO];
[self testPropertyName:@"circle-pitch-scale" isBoolean:NO];
[self testPropertyName:@"circle-radius" isBoolean:NO];
+ [self testPropertyName:@"circle-stroke-color" isBoolean:NO];
+ [self testPropertyName:@"circle-stroke-opacity" isBoolean:NO];
+ [self testPropertyName:@"circle-stroke-width" isBoolean:NO];
[self testPropertyName:@"circle-translate" isBoolean:NO];
[self testPropertyName:@"circle-translate-anchor" isBoolean:NO];
}
diff --git a/platform/darwin/test/MGLFeatureTests.mm b/platform/darwin/test/MGLFeatureTests.mm
index 33c146e723..efc30d307b 100644
--- a/platform/darwin/test/MGLFeatureTests.mm
+++ b/platform/darwin/test/MGLFeatureTests.mm
@@ -91,7 +91,7 @@
mbgl::Point<double> point = { -90.066667, 29.95 };
mbgl::Feature pointFeature { point };
pointFeature.id = { UINT64_MAX };
- pointFeature.properties["null"] = nullptr;
+ pointFeature.properties["null"] = mapbox::geometry::null_value;
pointFeature.properties["bool"] = true;
pointFeature.properties["unsigned int"] = UINT64_MAX;
pointFeature.properties["int"] = INT64_MIN;
diff --git a/platform/darwin/test/MGLStyleLayerTests.xib b/platform/darwin/test/MGLStyleLayerTests.xib
index cc336191ef..23ad22e7e3 100644
--- a/platform/darwin/test/MGLStyleLayerTests.xib
+++ b/platform/darwin/test/MGLStyleLayerTests.xib
@@ -4,14 +4,14 @@
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
</dependencies>
<objects>
- <customObject id="-2" userLabel="File's Owner" customClass="MGLMapViewTests">
+ <customObject id="-2" userLabel="File's Owner" customClass="MGLStyleLayerTests">
<connections>
<outlet property="mapView" destination="6RL-d9-juy" id="0ch-aR-Um6"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
- <window title="MGLMapViewTests" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g">
+ <window title="MGLStyleLayerTests" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="256" height="256"/>
diff --git a/platform/darwin/test/MGLStyleTests.mm b/platform/darwin/test/MGLStyleTests.mm
index c67497640b..e9ba4a9afa 100644
--- a/platform/darwin/test/MGLStyleTests.mm
+++ b/platform/darwin/test/MGLStyleTests.mm
@@ -1,6 +1,5 @@
#import "MGLMapView.h"
#import "MGLStyle_Private.h"
-#import "MGLOpenGLStyleLayer.h"
#import "MGLShapeSource.h"
#import "MGLRasterSource.h"
@@ -10,6 +9,7 @@
#import "MGLCircleStyleLayer.h"
#import "MGLFillStyleLayer.h"
#import "MGLLineStyleLayer.h"
+#import "MGLOpenGLStyleLayer.h"
#import "MGLRasterStyleLayer.h"
#import "MGLSymbolStyleLayer.h"
diff --git a/platform/default/bidi.cpp b/platform/default/bidi.cpp
new file mode 100644
index 0000000000..5b0c2f8da7
--- /dev/null
+++ b/platform/default/bidi.cpp
@@ -0,0 +1,128 @@
+#include <memory>
+
+#include <mbgl/text/bidi.hpp>
+#include <unicode/ubidi.h>
+#include <unicode/ushape.h>
+
+namespace mbgl {
+
+class BiDiImpl {
+public:
+ BiDiImpl() : bidiText(ubidi_open()), bidiLine(ubidi_open()) {}
+ ~BiDiImpl() { ubidi_close(bidiText); ubidi_close(bidiLine); }
+
+ UBiDi* bidiText = nullptr;
+ UBiDi* bidiLine = nullptr;
+};
+
+// Takes UTF16 input in logical order and applies Arabic shaping to the input while maintaining
+// logical order
+// Output won't be intelligible until the bidirectional algorithm is applied
+std::u16string applyArabicShaping(const std::u16string& input) {
+ UErrorCode errorCode = U_ZERO_ERROR;
+
+ int32_t outputLength =
+ u_shapeArabic(input.c_str(), static_cast<int32_t>(input.size()), NULL, 0,
+ (U_SHAPE_LETTERS_SHAPE & U_SHAPE_LETTERS_MASK) |
+ (U_SHAPE_TEXT_DIRECTION_LOGICAL & U_SHAPE_TEXT_DIRECTION_MASK),
+ &errorCode);
+
+ // Pre-flighting will always set U_BUFFER_OVERFLOW_ERROR
+ errorCode = U_ZERO_ERROR;
+
+ std::unique_ptr<UChar[]> outputText = std::make_unique<UChar[]>(outputLength);
+ u_shapeArabic(input.c_str(), static_cast<int32_t>(input.size()), outputText.get(), outputLength,
+ (U_SHAPE_LETTERS_SHAPE & U_SHAPE_LETTERS_MASK) |
+ (U_SHAPE_TEXT_DIRECTION_LOGICAL & U_SHAPE_TEXT_DIRECTION_MASK),
+ &errorCode);
+
+ // If the algorithm fails for any reason, fall back to non-transformed text
+ if (U_FAILURE(errorCode))
+ return input;
+
+ return std::u16string(outputText.get(), outputLength);
+}
+
+ProcessedBiDiText::ProcessedBiDiText(BiDi& p_bidi) : bidi(p_bidi) {
+}
+
+void ProcessedBiDiText::mergeParagraphLineBreaks(std::set<int32_t>& lineBreakPoints) {
+ int32_t paragraphCount = ubidi_countParagraphs(bidi.impl->bidiText);
+ for (int32_t i = 0; i < paragraphCount; i++) {
+ UErrorCode errorCode = U_ZERO_ERROR;
+ int32_t paragraphEndIndex;
+ ubidi_getParagraphByIndex(bidi.impl->bidiText, i, NULL, &paragraphEndIndex, NULL, &errorCode);
+
+ if (U_FAILURE(errorCode))
+ throw std::runtime_error(std::string("ProcessedBiDiText::mergeParagraphLineBreaks: ") +
+ u_errorName(errorCode));
+
+ lineBreakPoints.insert(paragraphEndIndex);
+ }
+}
+
+std::vector<std::u16string>
+ProcessedBiDiText::applyLineBreaking(std::set<int32_t> lineBreakPoints) {
+ // BiDi::getLine will error if called across a paragraph boundary, so we need to ensure that all
+ // paragraph
+ // boundaries are included in the set of line break points. The calling code might not include
+ // the line break because it
+ // didn't need to wrap at that point, or because the text was separated with a more exotic code
+ // point such as (U+001C)
+ mergeParagraphLineBreaks(lineBreakPoints);
+
+ std::vector<std::u16string> transformedLines;
+ int32_t start = 0;
+ for (int32_t lineBreakPoint : lineBreakPoints) {
+ transformedLines.push_back(bidi.getLine(start, lineBreakPoint));
+ start = lineBreakPoint;
+ }
+
+ return transformedLines;
+}
+
+BiDi::BiDi() : impl(std::make_unique<BiDiImpl>())
+{
+}
+
+BiDi::~BiDi() {
+}
+
+ProcessedBiDiText BiDi::processText(const std::u16string& input) {
+ UErrorCode errorCode = U_ZERO_ERROR;
+
+ ubidi_setPara(impl->bidiText, input.c_str(), static_cast<int32_t>(input.size()), UBIDI_DEFAULT_LTR,
+ NULL, &errorCode);
+
+ if (U_FAILURE(errorCode))
+ throw std::runtime_error(std::string("BiDi::processText: ") + u_errorName(errorCode));
+
+ return ProcessedBiDiText(*this);
+}
+
+std::u16string BiDi::getLine(int32_t start, int32_t end) {
+ UErrorCode errorCode = U_ZERO_ERROR;
+ ubidi_setLine(impl->bidiText, start, end, impl->bidiLine, &errorCode);
+
+ if (U_FAILURE(errorCode))
+ throw std::runtime_error(std::string("BiDi::getLine (setLine): ") + u_errorName(errorCode));
+
+ // Because we set UBIDI_REMOVE_BIDI_CONTROLS, the output may be smaller than what we reserve
+ // Setting UBIDI_INSERT_LRM_FOR_NUMERIC would require
+ // ubidi_getLength(pBiDi)+2*ubidi_countRuns(pBiDi)
+ int32_t outputLength = ubidi_getProcessedLength(impl->bidiLine);
+ std::unique_ptr<UChar[]> outputText = std::make_unique<UChar[]>(outputLength);
+
+ // UBIDI_DO_MIRRORING: Apply unicode mirroring of characters like parentheses
+ // UBIDI_REMOVE_BIDI_CONTROLS: Now that all the lines are set, remove control characters so that
+ // they don't show up on screen (some fonts have glyphs representing them)
+ ubidi_writeReordered(impl->bidiLine, outputText.get(), outputLength,
+ UBIDI_DO_MIRRORING | UBIDI_REMOVE_BIDI_CONTROLS, &errorCode);
+
+ if (U_FAILURE(errorCode))
+ throw std::runtime_error(std::string("BiDi::getLine (writeReordered): ") + u_errorName(errorCode));
+
+ return std::u16string(outputText.get(), outputLength);
+}
+
+} // end namespace mbgl
diff --git a/platform/default/default_file_source.cpp b/platform/default/default_file_source.cpp
index 7b52637c15..c4222b5a12 100644
--- a/platform/default/default_file_source.cpp
+++ b/platform/default/default_file_source.cpp
@@ -5,7 +5,7 @@
#include <mbgl/storage/offline_database.hpp>
#include <mbgl/storage/offline_download.hpp>
-#include <mbgl/platform/platform.hpp>
+#include <mbgl/util/platform.hpp>
#include <mbgl/util/url.hpp>
#include <mbgl/util/thread.hpp>
#include <mbgl/util/work_request.hpp>
diff --git a/platform/default/headless_backend_glx.cpp b/platform/default/headless_backend_glx.cpp
deleted file mode 100644
index bbfd19345b..0000000000
--- a/platform/default/headless_backend_glx.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-#include <mbgl/platform/default/headless_backend.hpp>
-#include <mbgl/platform/default/headless_display.hpp>
-
-#include <mbgl/platform/log.hpp>
-
-// #include <cassert>
-
-#include <GL/glx.h>
-
-namespace mbgl {
-
-gl::glProc HeadlessBackend::initializeExtension(const char* name) {
- return glXGetProcAddress(reinterpret_cast<const GLubyte*>(name));
-}
-
-void HeadlessBackend::createContext() {
- xDisplay = display->xDisplay;
- fbConfigs = display->fbConfigs;
-
- if (!glContext) {
- // Try to create a legacy context
- glContext = glXCreateNewContext(xDisplay, fbConfigs[0], GLX_RGBA_TYPE, None, True);
- if (glContext) {
- if (!glXIsDirect(xDisplay, glContext)) {
- Log::Error(Event::OpenGL, "failed to create direct OpenGL Legacy context");
- glXDestroyContext(xDisplay, glContext);
- glContext = nullptr;
- }
- }
- }
-
- if (glContext == nullptr) {
- throw std::runtime_error("Error creating GL context object.");
- }
-
- // Create a dummy pbuffer. We will render to framebuffers anyway, but we need a pbuffer to
- // activate the context.
- int pbufferAttributes[] = {
- GLX_PBUFFER_WIDTH, 8,
- GLX_PBUFFER_HEIGHT, 8,
- None
- };
- glxPbuffer = glXCreatePbuffer(xDisplay, fbConfigs[0], pbufferAttributes);
-}
-
-void HeadlessBackend::destroyContext() {
- if (glxPbuffer) {
- glXDestroyPbuffer(xDisplay, glxPbuffer);
- glxPbuffer = 0;
- }
-
- glXDestroyContext(xDisplay, glContext);
-}
-
-void HeadlessBackend::activateContext() {
- if (!glXMakeContextCurrent(xDisplay, glxPbuffer, glxPbuffer, glContext)) {
- throw std::runtime_error("Switching OpenGL context failed.\n");
- }
-}
-
-void HeadlessBackend::deactivateContext() {
- if (!glXMakeContextCurrent(xDisplay, 0, 0, nullptr)) {
- throw std::runtime_error("Removing OpenGL context failed.\n");
- }
-}
-
-} // namespace mbgl
diff --git a/platform/default/headless_backend_osmesa.cpp b/platform/default/headless_backend_osmesa.cpp
index e0e385fcc6..081bddf170 100644
--- a/platform/default/headless_backend_osmesa.cpp
+++ b/platform/default/headless_backend_osmesa.cpp
@@ -1,47 +1,54 @@
-#include <mbgl/platform/default/headless_backend.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/gl/headless_backend.hpp>
+#include <mbgl/util/logging.hpp>
-namespace mbgl {
+#include <GL/osmesa.h>
-gl::glProc HeadlessBackend::initializeExtension(const char* name) {
- return OSMesaGetProcAddress(name);
-}
+#include <cassert>
-void HeadlessBackend::createContext() {
- if (glContext == nullptr) {
-#if OSMESA_MAJOR_VERSION * 100 + OSMESA_MINOR_VERSION >= 305
- glContext = OSMesaCreateContextExt(OSMESA_RGBA, 16, 0, 0, nullptr);
-#else
- glContext = OSMesaCreateContext(OSMESA_RGBA, nullptr);
-#endif
- if (glContext == nullptr) {
- Log::Error(Event::OpenGL, "failed to create OSMesa context");
- }
- }
+namespace mbgl {
- if (glContext == nullptr) {
- throw std::runtime_error("Error creating GL context object.");
+struct OSMesaImpl : public HeadlessBackend::Impl {
+ OSMesaImpl(OSMesaContext glContext_) : glContext(glContext_) {
}
-}
-void HeadlessBackend::destroyContext() {
- if (glContext) {
+ ~OSMesaImpl() {
if (glContext != OSMesaGetCurrentContext()) {
activateContext();
}
OSMesaDestroyContext(glContext);
- glContext = nullptr;
}
-}
-void HeadlessBackend::activateContext() {
- if (!OSMesaMakeCurrent(glContext, &fakeBuffer, GL_UNSIGNED_BYTE, 1, 1)) {
- throw std::runtime_error("Switching OpenGL context failed.\n");
+ void activateContext() final {
+ if (!OSMesaMakeCurrent(glContext, &fakeBuffer, GL_UNSIGNED_BYTE, 1, 1)) {
+ throw std::runtime_error("Switching OpenGL context failed.\n");
+ }
}
+
+ OSMesaContext glContext = nullptr;
+ GLubyte fakeBuffer = 0;
+};
+
+gl::glProc HeadlessBackend::initializeExtension(const char* name) {
+ return OSMesaGetProcAddress(name);
}
-void HeadlessBackend::deactivateContext() {
- // no-op.
+bool HeadlessBackend::hasDisplay() {
+ return true;
+};
+
+void HeadlessBackend::createContext() {
+ assert(!hasContext());
+
+#if OSMESA_MAJOR_VERSION * 100 + OSMESA_MINOR_VERSION >= 305
+ OSMesaContext glContext = OSMesaCreateContextExt(OSMESA_RGBA, 16, 0, 0, nullptr);
+#else
+ OSMesaContext glContext = OSMesaCreateContext(OSMESA_RGBA, nullptr);
+#endif
+ if (glContext == nullptr) {
+ throw std::runtime_error("Error creating GL context object.");
+ }
+
+ impl.reset(new OSMesaImpl(glContext));
}
} // namespace mbgl
diff --git a/platform/default/http_file_source.cpp b/platform/default/http_file_source.cpp
index ce6987fbdd..867d85fa4d 100644
--- a/platform/default/http_file_source.cpp
+++ b/platform/default/http_file_source.cpp
@@ -1,7 +1,7 @@
#include <mbgl/storage/http_file_source.hpp>
#include <mbgl/storage/resource.hpp>
#include <mbgl/storage/response.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
#include <mbgl/util/util.hpp>
#include <mbgl/util/optional.hpp>
diff --git a/platform/default/image.cpp b/platform/default/image.cpp
index 890d442683..84db1e9c71 100644
--- a/platform/default/image.cpp
+++ b/platform/default/image.cpp
@@ -25,8 +25,8 @@ const static bool png_version_check __attribute__((unused)) = []() {
namespace mbgl {
std::string encodePNG(const PremultipliedImage& pre) {
- PremultipliedImage copy { pre.width, pre.height };
- std::copy(pre.data.get(), pre.data.get() + pre.size(), copy.data.get());
+ PremultipliedImage copy(pre.size);
+ std::copy(pre.data.get(), pre.data.get() + pre.bytes(), copy.data.get());
UnassociatedImage src = util::unpremultiply(std::move(copy));
@@ -42,8 +42,8 @@ std::string encodePNG(const PremultipliedImage& pre) {
throw std::runtime_error("couldn't create info_ptr");
}
- png_set_IHDR(png_ptr, info_ptr, src.width, src.height, 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
- PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+ png_set_IHDR(png_ptr, info_ptr, src.size.width, src.size.height, 8, PNG_COLOR_TYPE_RGB_ALPHA,
+ PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
jmp_buf *jmp_context = (jmp_buf *)png_get_error_ptr(png_ptr);
if (jmp_context) {
@@ -61,9 +61,9 @@ std::string encodePNG(const PremultipliedImage& pre) {
ptrs(size_t count) : rows(new png_bytep[count]) {}
~ptrs() { delete[] rows; }
png_bytep *rows = nullptr;
- } pointers(src.height);
+ } pointers(src.size.height);
- for (size_t i = 0; i < src.height; i++) {
+ for (size_t i = 0; i < src.size.height; i++) {
pointers.rows[i] = src.data.get() + src.stride() * i;
}
diff --git a/platform/default/jpeg_reader.cpp b/platform/default/jpeg_reader.cpp
index 5151060a12..78c74f2fd7 100644
--- a/platform/default/jpeg_reader.cpp
+++ b/platform/default/jpeg_reader.cpp
@@ -119,7 +119,7 @@ PremultipliedImage decodeJPEG(const uint8_t* data, size_t size) {
size_t components = cinfo.output_components;
size_t rowStride = components * width;
- PremultipliedImage image { static_cast<uint16_t>(width), static_cast<uint16_t>(height) };
+ PremultipliedImage image({ static_cast<uint32_t>(width), static_cast<uint32_t>(height) });
uint8_t* dst = image.data.get();
JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, rowStride, 1);
diff --git a/platform/default/log_stderr.cpp b/platform/default/logging_stderr.cpp
index 145cdeda03..41585fb7bb 100644
--- a/platform/default/log_stderr.cpp
+++ b/platform/default/logging_stderr.cpp
@@ -1,4 +1,4 @@
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
#include <mbgl/util/enum.hpp>
#include <iostream>
diff --git a/platform/default/headless_backend.cpp b/platform/default/mbgl/gl/headless_backend.cpp
index 279a7973c9..0bfdf11c98 100644
--- a/platform/default/headless_backend.cpp
+++ b/platform/default/mbgl/gl/headless_backend.cpp
@@ -1,17 +1,18 @@
-#include <mbgl/platform/default/headless_backend.hpp>
-#include <mbgl/platform/default/headless_display.hpp>
+#include <mbgl/gl/headless_backend.hpp>
+#include <mbgl/gl/headless_display.hpp>
#include <cassert>
#include <stdexcept>
+#include <type_traits>
namespace mbgl {
-HeadlessBackend::HeadlessBackend() : display(std::make_shared<HeadlessDisplay>()) {
+HeadlessBackend::HeadlessBackend() {
activate();
}
HeadlessBackend::HeadlessBackend(std::shared_ptr<HeadlessDisplay> display_)
- : display(std::move(display_)) {
+ : display(std::move(display_)) {
activate();
}
@@ -23,8 +24,8 @@ HeadlessBackend::~HeadlessBackend() {
void HeadlessBackend::activate() {
active = true;
- if (!glContext) {
- if (!display) {
+ if (!hasContext()) {
+ if (!hasDisplay()) {
throw std::runtime_error("Display is not set");
}
createContext();
@@ -47,6 +48,21 @@ void HeadlessBackend::invalidate() {
assert(false);
}
+void HeadlessBackend::destroyContext() {
+ assert(hasContext());
+ impl.reset();
+}
+
+void HeadlessBackend::activateContext() {
+ assert(hasContext());
+ impl->activateContext();
+}
+
+void HeadlessBackend::deactivateContext() {
+ assert(hasContext());
+ impl->deactivateContext();
+}
+
void HeadlessBackend::notifyMapChange(MapChange change) {
if (mapChangeCallback) {
mapChangeCallback(change);
diff --git a/include/mbgl/platform/default/headless_backend.hpp b/platform/default/mbgl/gl/headless_backend.hpp
index b6c654943f..da8c55e044 100644
--- a/include/mbgl/platform/default/headless_backend.hpp
+++ b/platform/default/mbgl/gl/headless_backend.hpp
@@ -1,23 +1,8 @@
#pragma once
-#include <mbgl/gl/implementation.hpp>
-
-#if MBGL_USE_QT
-class QGLWidget;
-#elif MBGL_USE_CGL
-#include <OpenGL/OpenGL.h>
-#elif MBGL_USE_GLX
-typedef struct _XDisplay Display;
-typedef struct __GLXcontextRec* GLXContext;
-typedef struct __GLXFBConfigRec* GLXFBConfig;
-typedef long unsigned int XID;
-typedef XID GLXPbuffer;
-#elif MBGL_USE_OSMESA
-#include <GL/osmesa.h>
-#endif
+#include <mbgl/gl/extension.hpp>
#include <mbgl/map/backend.hpp>
-#include <mbgl/gl/extension.hpp>
#include <memory>
#include <functional>
@@ -39,47 +24,34 @@ public:
void setMapChangeCallback(std::function<void(MapChange)>&& cb) { mapChangeCallback = std::move(cb); }
-private:
- void activateContext();
- void deactivateContext();
+ struct Impl {
+ virtual ~Impl() {}
+ virtual void activateContext() = 0;
+ virtual void deactivateContext() {}
+ };
private:
// Implementation specific functions
static gl::glProc initializeExtension(const char*);
+
+ bool hasContext() const { return bool(impl); }
+ bool hasDisplay();
+
void createContext();
+
+private:
void destroyContext();
+ void activateContext();
+ void deactivateContext();
+
+ std::unique_ptr<Impl> impl;
std::shared_ptr<HeadlessDisplay> display;
bool extensionsLoaded = false;
bool active = false;
-#if MBGL_USE_QT
- QGLWidget* glContext = nullptr;
-#endif
-
-#if MBGL_USE_CGL
- CGLContextObj glContext = nullptr;
-#endif
-
-#if MBGL_USE_EAGL
- void *glContext = nullptr;
-#endif
-
-#if MBGL_USE_GLX
- Display *xDisplay = nullptr;
- GLXFBConfig *fbConfigs = nullptr;
- GLXContext glContext = nullptr;
- GLXPbuffer glxPbuffer = 0;
-#endif
-
-#if MBGL_USE_OSMESA
- OSMesaContext glContext = nullptr;
- GLubyte fakeBuffer = 0;
-#endif
-
std::function<void(MapChange)> mapChangeCallback;
-
};
} // namespace mbgl
diff --git a/platform/default/mbgl/gl/headless_display.cpp b/platform/default/mbgl/gl/headless_display.cpp
new file mode 100644
index 0000000000..6247046c29
--- /dev/null
+++ b/platform/default/mbgl/gl/headless_display.cpp
@@ -0,0 +1,15 @@
+#include <mbgl/gl/headless_display.hpp>
+
+namespace mbgl {
+
+class HeadlessDisplay::Impl {};
+
+HeadlessDisplay::HeadlessDisplay() {
+ // no-op
+}
+
+HeadlessDisplay::~HeadlessDisplay() {
+ // no-op
+}
+
+} // namespace mbgl
diff --git a/platform/default/mbgl/gl/headless_display.hpp b/platform/default/mbgl/gl/headless_display.hpp
new file mode 100644
index 0000000000..a5c95085b8
--- /dev/null
+++ b/platform/default/mbgl/gl/headless_display.hpp
@@ -0,0 +1,20 @@
+#pragma once
+
+#include <memory>
+
+namespace mbgl {
+
+class HeadlessDisplay {
+public:
+ HeadlessDisplay();
+ ~HeadlessDisplay();
+
+ template <typename DisplayAttribute>
+ DisplayAttribute attribute() const;
+
+private:
+ class Impl;
+ std::unique_ptr<Impl> impl;
+};
+
+} // namespace mbgl
diff --git a/platform/default/mbgl/gl/offscreen_view.cpp b/platform/default/mbgl/gl/offscreen_view.cpp
new file mode 100644
index 0000000000..16faf6a4a9
--- /dev/null
+++ b/platform/default/mbgl/gl/offscreen_view.cpp
@@ -0,0 +1,30 @@
+#include <mbgl/gl/offscreen_view.hpp>
+#include <mbgl/gl/context.hpp>
+
+#include <cstring>
+#include <cassert>
+
+namespace mbgl {
+
+OffscreenView::OffscreenView(gl::Context& context_, const Size size_)
+ : size(std::move(size_)), context(context_) {
+ assert(size);
+}
+
+void OffscreenView::bind() {
+ if (!framebuffer) {
+ color = context.createRenderbuffer<gl::RenderbufferType::RGBA>(size);
+ depthStencil = context.createRenderbuffer<gl::RenderbufferType::DepthStencil>(size);
+ framebuffer = context.createFramebuffer(*color, *depthStencil);
+ } else {
+ context.bindFramebuffer = framebuffer->framebuffer;
+ }
+
+ context.viewport = { 0, 0, size };
+}
+
+PremultipliedImage OffscreenView::readStillImage() {
+ return context.readFramebuffer<PremultipliedImage>(size);
+}
+
+} // namespace mbgl
diff --git a/include/mbgl/platform/default/offscreen_view.hpp b/platform/default/mbgl/gl/offscreen_view.hpp
index 034aa3aaf3..0e839e14cc 100644
--- a/include/mbgl/platform/default/offscreen_view.hpp
+++ b/platform/default/mbgl/gl/offscreen_view.hpp
@@ -14,17 +14,17 @@ class Context;
class OffscreenView : public View {
public:
- OffscreenView(gl::Context&, std::array<uint16_t, 2> size = {{ 256, 256 }});
+ OffscreenView(gl::Context&, Size size = { 256, 256 });
void bind() override;
PremultipliedImage readStillImage();
- std::array<uint16_t, 2> getSize() const;
+public:
+ const Size size;
private:
gl::Context& context;
- std::array<uint16_t, 2> size;
optional<gl::Framebuffer> framebuffer;
optional<gl::Renderbuffer<gl::RenderbufferType::RGBA>> color;
optional<gl::Renderbuffer<gl::RenderbufferType::DepthStencil>> depthStencil;
diff --git a/platform/default/mbgl/storage/offline_database.cpp b/platform/default/mbgl/storage/offline_database.cpp
index 4bcc9ad711..73364b042f 100644
--- a/platform/default/mbgl/storage/offline_database.cpp
+++ b/platform/default/mbgl/storage/offline_database.cpp
@@ -4,7 +4,7 @@
#include <mbgl/util/io.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/util/chrono.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
#include "sqlite3.hpp"
#include <sqlite3.h>
diff --git a/platform/default/mbgl/storage/offline_download.cpp b/platform/default/mbgl/storage/offline_download.cpp
index 9e2e11c86f..3edc75845c 100644
--- a/platform/default/mbgl/storage/offline_download.cpp
+++ b/platform/default/mbgl/storage/offline_download.cpp
@@ -184,7 +184,7 @@ void OfflineDownload::activateDownload() {
if (!parser.glyphURL.empty()) {
for (const auto& fontStack : parser.fontStacks()) {
- for (uint32_t i = 0; i < GLYPH_RANGES_PER_FONT_STACK; i++) {
+ for (char16_t i = 0; i < GLYPH_RANGES_PER_FONT_STACK; i++) {
queueResource(Resource::glyphs(parser.glyphURL, fontStack, getGlyphRange(i * GLYPHS_PER_GLYPH_RANGE)));
}
}
diff --git a/src/mbgl/util/default_styles.cpp b/platform/default/mbgl/util/default_styles.cpp
index 17cc2f5740..17cc2f5740 100644
--- a/src/mbgl/util/default_styles.cpp
+++ b/platform/default/mbgl/util/default_styles.cpp
diff --git a/include/mbgl/util/default_styles.hpp b/platform/default/mbgl/util/default_styles.hpp
index eb7e034722..eb7e034722 100644
--- a/include/mbgl/util/default_styles.hpp
+++ b/platform/default/mbgl/util/default_styles.hpp
diff --git a/platform/default/thread_pool.cpp b/platform/default/mbgl/util/default_thread_pool.cpp
index b7e02db157..92c0f06745 100644
--- a/platform/default/thread_pool.cpp
+++ b/platform/default/mbgl/util/default_thread_pool.cpp
@@ -1,4 +1,4 @@
-#include <mbgl/platform/default/thread_pool.hpp>
+#include <mbgl/util/default_thread_pool.hpp>
#include <mbgl/actor/mailbox.hpp>
namespace mbgl {
diff --git a/include/mbgl/platform/default/thread_pool.hpp b/platform/default/mbgl/util/default_thread_pool.hpp
index a14d16d771..a14d16d771 100644
--- a/include/mbgl/platform/default/thread_pool.hpp
+++ b/platform/default/mbgl/util/default_thread_pool.hpp
diff --git a/platform/default/offscreen_view.cpp b/platform/default/offscreen_view.cpp
deleted file mode 100644
index eaf87d0f87..0000000000
--- a/platform/default/offscreen_view.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-#include <mbgl/platform/default/offscreen_view.hpp>
-#include <mbgl/gl/context.hpp>
-#include <mbgl/gl/gl.hpp>
-
-#include <cstring>
-#include <cassert>
-
-namespace mbgl {
-
-OffscreenView::OffscreenView(gl::Context& context_, std::array<uint16_t, 2> size_)
- : context(context_), size(std::move(size_)) {
- assert(size[0] > 0 && size[1] > 0);
-}
-
-void OffscreenView::bind() {
- if (!framebuffer) {
- color = context.createRenderbuffer<gl::RenderbufferType::RGBA>(size);
- depthStencil = context.createRenderbuffer<gl::RenderbufferType::DepthStencil>(size);
- framebuffer = context.createFramebuffer(*color, *depthStencil);
- } else {
- context.bindFramebuffer = framebuffer->framebuffer;
- }
-
- context.viewport = { 0, 0, size[0], size[1] };
-}
-
-PremultipliedImage OffscreenView::readStillImage() {
- 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 auto stride = image.stride();
- auto tmp = std::make_unique<uint8_t[]>(stride);
- uint8_t* rgba = image.data.get();
- for (int i = 0, j = size[1] - 1; i < j; i++, j--) {
- std::memcpy(tmp.get(), rgba + i * stride, stride);
- std::memcpy(rgba + i * stride, rgba + j * stride, stride);
- std::memcpy(rgba + j * stride, tmp.get(), stride);
- }
-
- return image;
-}
-
-std::array<uint16_t, 2> OffscreenView::getSize() const {
- return size;
-}
-
-} // namespace mbgl
diff --git a/platform/default/online_file_source.cpp b/platform/default/online_file_source.cpp
index 4f191f6cf7..0f2bc5ff56 100644
--- a/platform/default/online_file_source.cpp
+++ b/platform/default/online_file_source.cpp
@@ -3,7 +3,7 @@
#include <mbgl/storage/network_status.hpp>
#include <mbgl/storage/response.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/thread.hpp>
diff --git a/platform/default/png_reader.cpp b/platform/default/png_reader.cpp
index 5111edaa59..5ae74d74db 100644
--- a/platform/default/png_reader.cpp
+++ b/platform/default/png_reader.cpp
@@ -1,7 +1,7 @@
#include <mbgl/util/image.hpp>
#include <mbgl/util/premultiply.hpp>
#include <mbgl/util/char_array_buffer.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
#include <istream>
#include <sstream>
@@ -80,7 +80,7 @@ PremultipliedImage decodePNG(const uint8_t* data, size_t size) {
int color_type = 0;
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, nullptr, nullptr, nullptr);
- UnassociatedImage image { static_cast<uint16_t>(width), static_cast<uint16_t>(height) };
+ UnassociatedImage image({ width, height });
if (color_type == PNG_COLOR_TYPE_PALETTE)
png_set_expand(png_ptr);
diff --git a/platform/default/sqlite3.cpp b/platform/default/sqlite3.cpp
index 578e407739..670b7b84cc 100644
--- a/platform/default/sqlite3.cpp
+++ b/platform/default/sqlite3.cpp
@@ -7,7 +7,7 @@
#include <chrono>
#include <experimental/optional>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
namespace mapbox {
namespace sqlite {
diff --git a/platform/default/string_stdlib.cpp b/platform/default/string_stdlib.cpp
index 90a75c1738..2642e88aff 100644
--- a/platform/default/string_stdlib.cpp
+++ b/platform/default/string_stdlib.cpp
@@ -1,10 +1,10 @@
-#include <mbgl/platform/platform.hpp>
-#include <mbgl/util/utf.hpp>
+#include <mbgl/util/platform.hpp>
#define NU_WITH_TOUPPER
#define NU_WITH_TOLOWER
#define NU_WITH_UTF8_WRITER
#include <libnu/libnu.h>
#include <cstring>
+#include <sstream>
namespace mbgl { namespace platform {
diff --git a/platform/default/thread.cpp b/platform/default/thread.cpp
index f4d0b9a855..c7c79b4fb0 100644
--- a/platform/default/thread.cpp
+++ b/platform/default/thread.cpp
@@ -1,5 +1,5 @@
-#include <mbgl/platform/platform.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/platform.hpp>
+#include <mbgl/util/logging.hpp>
#include <string>
diff --git a/platform/default/webp_reader.cpp b/platform/default/webp_reader.cpp
index 6f90fe02f5..2c01fb4479 100644
--- a/platform/default/webp_reader.cpp
+++ b/platform/default/webp_reader.cpp
@@ -1,6 +1,6 @@
#include <mbgl/util/image.hpp>
#include <mbgl/util/premultiply.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
extern "C"
{
@@ -23,8 +23,8 @@ PremultipliedImage decodeWebP(const uint8_t* data, size_t size) {
throw std::runtime_error("failed to decode WebP data");
}
- UnassociatedImage image{ static_cast<uint16_t>(width), static_cast<uint16_t>(height),
- std::move(webp) };
+ UnassociatedImage image({ static_cast<uint32_t>(width), static_cast<uint32_t>(height) },
+ std::move(webp));
return util::premultiply(std::move(image));
}
diff --git a/platform/default/glfw_view.cpp b/platform/glfw/glfw_view.cpp
index 47551d786f..fdf82fda8f 100644
--- a/platform/default/glfw_view.cpp
+++ b/platform/glfw/glfw_view.cpp
@@ -1,12 +1,13 @@
-#include <mbgl/platform/default/glfw_view.hpp>
+#include "glfw_view.hpp"
+
#include <mbgl/annotation/annotation.hpp>
#include <mbgl/sprite/sprite_image.hpp>
#include <mbgl/style/transition_options.hpp>
#include <mbgl/gl/gl.hpp>
#include <mbgl/gl/extension.hpp>
#include <mbgl/gl/context.hpp>
-#include <mbgl/platform/log.hpp>
-#include <mbgl/platform/platform.hpp>
+#include <mbgl/util/logging.hpp>
+#include <mbgl/util/platform.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/util/chrono.hpp>
#include <mbgl/map/camera.hpp>
@@ -132,14 +133,14 @@ void GLFWView::setMap(mbgl::Map *map_) {
void GLFWView::updateViewBinding() {
getContext().bindFramebuffer.setCurrentValue(0);
- getContext().viewport.setCurrentValue(
- { 0, 0, static_cast<uint16_t>(fbWidth), static_cast<uint16_t>(fbHeight) });
+ assert(mbgl::gl::value::BindFramebuffer::Get() == getContext().bindFramebuffer.getCurrentValue());
+ getContext().viewport.setCurrentValue({ 0, 0, getFramebufferSize() });
+ assert(mbgl::gl::value::Viewport::Get() == getContext().viewport.getCurrentValue());
}
void GLFWView::bind() {
getContext().bindFramebuffer = 0;
- getContext().viewport = { 0, 0, static_cast<uint16_t>(fbWidth),
- static_cast<uint16_t>(fbHeight) };
+ getContext().viewport = { 0, 0, getFramebufferSize() };
}
void GLFWView::onKey(GLFWwindow *window, int key, int /*scancode*/, int action, int mods) {
@@ -172,6 +173,7 @@ void GLFWView::onKey(GLFWwindow *window, int key, int /*scancode*/, int action,
}
}
break;
+#if not MBGL_USE_GLES2
case GLFW_KEY_B: {
auto debug = view->map->getDebug();
if (debug & mbgl::MapDebugOptions::StencilClip) {
@@ -184,6 +186,7 @@ void GLFWView::onKey(GLFWwindow *window, int key, int /*scancode*/, int action,
}
view->map->setDebug(debug);
} break;
+#endif // MBGL_USE_GLES2
case GLFW_KEY_N:
if (!mods)
view->map->resetNorth();
@@ -192,7 +195,7 @@ void GLFWView::onKey(GLFWwindow *window, int key, int /*scancode*/, int action,
view->nextOrientation();
break;
case GLFW_KEY_Q: {
- auto result = view->map->queryPointAnnotations({ {}, { double(view->getSize()[0]), double(view->getSize()[1]) } });
+ auto result = view->map->queryPointAnnotations({ {}, { double(view->getSize().width), double(view->getSize().height) } });
printf("visible point annotations: %lu\n", result.size());
} break;
case GLFW_KEY_C:
@@ -267,7 +270,7 @@ GLFWView::makeSpriteImage(int width, int height, float pixelRatio) {
const int w = std::ceil(pixelRatio * width);
const int h = std::ceil(pixelRatio * height);
- mbgl::PremultipliedImage image(w, h);
+ mbgl::PremultipliedImage image({ static_cast<uint32_t>(w), static_cast<uint32_t>(h) });
auto data = reinterpret_cast<uint32_t*>(image.data.get());
const int dist = (w / 2) * (w / 2);
for (int y = 0; y < h; y++) {
@@ -374,8 +377,7 @@ void GLFWView::onWindowResize(GLFWwindow *window, int width, int height) {
GLFWView *view = reinterpret_cast<GLFWView *>(glfwGetWindowUserPointer(window));
view->width = width;
view->height = height;
- view->map->setSize({{ static_cast<uint16_t>(view->width),
- static_cast<uint16_t>(view->height) }});
+ view->map->setSize({ static_cast<uint32_t>(view->width), static_cast<uint32_t>(view->height) });
}
void GLFWView::onFramebufferResize(GLFWwindow *window, int width, int height) {
@@ -480,12 +482,12 @@ float GLFWView::getPixelRatio() const {
return pixelRatio;
}
-std::array<uint16_t, 2> GLFWView::getSize() const {
- return {{ static_cast<uint16_t>(width), static_cast<uint16_t>(height) }};
+mbgl::Size GLFWView::getSize() const {
+ return { static_cast<uint32_t>(width), static_cast<uint32_t>(height) };
}
-std::array<uint16_t, 2> GLFWView::getFramebufferSize() const {
- return {{ static_cast<uint16_t>(fbWidth), static_cast<uint16_t>(fbHeight) }};
+mbgl::Size GLFWView::getFramebufferSize() const {
+ return { static_cast<uint32_t>(fbWidth), static_cast<uint32_t>(fbHeight) };
}
void GLFWView::activate() {
diff --git a/include/mbgl/platform/default/glfw_view.hpp b/platform/glfw/glfw_view.hpp
index e832cd70d1..672fa2e13c 100644
--- a/include/mbgl/platform/default/glfw_view.hpp
+++ b/platform/glfw/glfw_view.hpp
@@ -1,6 +1,7 @@
#pragma once
-#include <mbgl/mbgl.hpp>
+#include <mbgl/map/map.hpp>
+#include <mbgl/map/view.hpp>
#include <mbgl/map/backend.hpp>
#include <mbgl/util/run_loop.hpp>
#include <mbgl/util/timer.hpp>
@@ -34,8 +35,8 @@ public:
// mbgl::View implementation
void updateViewBinding();
void bind() override;
- std::array<uint16_t, 2> getSize() const;
- std::array<uint16_t, 2> getFramebufferSize() const;
+ mbgl::Size getSize() const;
+ mbgl::Size getFramebufferSize() const;
// mbgl::Backend implementation
void activate() override;
diff --git a/bin/glfw.cpp b/platform/glfw/main.cpp
index b51846b4e8..1f683b185f 100644
--- a/bin/glfw.cpp
+++ b/platform/glfw/main.cpp
@@ -1,10 +1,10 @@
-#include <mbgl/mbgl.hpp>
+#include "glfw_view.hpp"
+#include "settings_json.hpp"
+
#include <mbgl/util/default_styles.hpp>
-#include <mbgl/platform/log.hpp>
-#include <mbgl/platform/platform.hpp>
-#include <mbgl/platform/default/settings_json.hpp>
-#include <mbgl/platform/default/glfw_view.hpp>
-#include <mbgl/platform/default/thread_pool.hpp>
+#include <mbgl/util/logging.hpp>
+#include <mbgl/util/platform.hpp>
+#include <mbgl/util/default_thread_pool.hpp>
#include <mbgl/storage/default_file_source.hpp>
#include <signal.h>
diff --git a/platform/default/settings_json.cpp b/platform/glfw/settings_json.cpp
index ef53aa83e7..2ba1038dc7 100644
--- a/platform/default/settings_json.cpp
+++ b/platform/glfw/settings_json.cpp
@@ -1,4 +1,4 @@
-#include <mbgl/platform/default/settings_json.hpp>
+#include "settings_json.hpp"
#include <fstream>
namespace mbgl {
diff --git a/include/mbgl/platform/default/settings_json.hpp b/platform/glfw/settings_json.hpp
index eb23b28bc8..eb23b28bc8 100644
--- a/include/mbgl/platform/default/settings_json.hpp
+++ b/platform/glfw/settings_json.hpp
diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md
index 18763b68ee..9105afce6d 100644
--- a/platform/ios/CHANGELOG.md
+++ b/platform/ios/CHANGELOG.md
@@ -2,6 +2,13 @@
Mapbox welcomes participation and contributions from everyone. Please read [CONTRIBUTING.md](../../CONTRIBUTING.md) to get started.
+## master
+
+* Labels written in Arabic, Hebrew, and other scripts are written right-to-left. Arabic characters are correctly shaped. ([#6984](https://github.com/mapbox/mapbox-gl-native/pull/6984), [#7123](https://github.com/mapbox/mapbox-gl-native/pull/7123))
+* Improved the line wrapping behavior of point-placed labels written in Chinese, Japanese, and Yi. ([#6828](https://github.com/mapbox/mapbox-gl-native/pull/6828))
+* Fixed an issue where translucent, non-view-backed point annotations along tile boundaries would be drawn darker than expected. ([#6832](https://github.com/mapbox/mapbox-gl-native/pull/6832))
+* Added the Simplified Chinese localization. ([#7316](https://github.com/mapbox/mapbox-gl-native/pull/7316))
+
## 3.4.0
### Packaging
@@ -66,7 +73,6 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
### 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 a crash that sometimes occurred when initializing an MGLMapView. ([#5932](https://github.com/mapbox/mapbox-gl-native/pull/5932))
* 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))
* 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))
diff --git a/platform/ios/bitrise.yml b/platform/ios/bitrise.yml
index d8a9a4fcd0..93d1d4afd8 100644
--- a/platform/ios/bitrise.yml
+++ b/platform/ios/bitrise.yml
@@ -2,6 +2,8 @@
format_version: 1.0.0
default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git
trigger_map:
+- pattern: nightly-release
+ workflow: nightly-release
- pattern: "*"
is_pull_request_allowed: true
workflow: primary
@@ -72,3 +74,32 @@ workflows:
failed'
- icon_url: https://bitrise-public-content-production.s3.amazonaws.com/slack/bitrise-slack-icon-128.png
- icon_url_on_error: https://bitrise-public-content-production.s3.amazonaws.com/slack/bitrise-slack-error-icon-128.png
+ nightly-release:
+ steps:
+ - script:
+ title: Install Dependencies
+ inputs:
+ - content: |-
+ #!/bin/bash
+ set -eu -o pipefail
+ brew install cmake
+ - is_debug: 'yes'
+ - script:
+ title: Configure AWS-CLI
+ inputs:
+ - content: |-
+ #!/bin/bash
+ apt-get install -y python-pip python-dev build-essential
+ pip install awscli
+ - script:
+ title: Build package
+ inputs:
+ - content: |-
+ #!/bin/bash
+ set -eu -o pipefail
+ export BUILDTYPE=Release
+ export BUILD_DEVICE=true
+ export FORMAT=dynamic
+ make ipackage-strip
+ CLOUDWATCH=true platform/ios/scripts/metrics.sh
+ - is_debug: 'yes'
diff --git a/platform/ios/config.cmake b/platform/ios/config.cmake
index 0813d0338f..12db02921c 100644
--- a/platform/ios/config.cmake
+++ b/platform/ios/config.cmake
@@ -1,9 +1,12 @@
add_definitions(-DMBGL_USE_GLES2=1)
+mason_use(icu VERSION 58.1)
+
macro(mbgl_platform_core)
set_xcode_property(mbgl-core IPHONEOS_DEPLOYMENT_TARGET "8.0")
set_xcode_property(mbgl-core ENABLE_BITCODE "YES")
set_xcode_property(mbgl-core BITCODE_GENERATION_MODE bitcode)
+ set_xcode_property(mbgl-core ONLY_ACTIVE_ARCH $<$<CONFIG:Debug>:YES>)
target_sources(mbgl-core
# Loop
@@ -18,6 +21,10 @@ macro(mbgl_platform_core)
PRIVATE platform/default/local_file_source.cpp
PRIVATE platform/default/online_file_source.cpp
+ # Default styles
+ PRIVATE platform/default/mbgl/util/default_styles.hpp
+ PRIVATE platform/default/mbgl/util/default_styles.cpp
+
# Offline
PRIVATE platform/default/mbgl/storage/offline.cpp
PRIVATE platform/default/mbgl/storage/offline_database.cpp
@@ -28,25 +35,32 @@ macro(mbgl_platform_core)
PRIVATE platform/default/sqlite3.hpp
# Misc
- PRIVATE platform/darwin/src/log_nslog.mm
+ PRIVATE platform/darwin/mbgl/storage/reachability.h
+ PRIVATE platform/darwin/mbgl/storage/reachability.m
+ PRIVATE platform/darwin/src/logging_nslog.mm
PRIVATE platform/darwin/src/nsthread.mm
- PRIVATE platform/darwin/src/reachability.m
PRIVATE platform/darwin/src/string_nsstring.mm
+ PRIVATE platform/default/bidi.cpp
# Image handling
PRIVATE platform/darwin/src/image.mm
# Headless view
+ PRIVATE platform/default/mbgl/gl/headless_backend.cpp
+ PRIVATE platform/default/mbgl/gl/headless_backend.hpp
PRIVATE platform/darwin/src/headless_backend_eagl.mm
- PRIVATE platform/default/headless_backend.cpp
- PRIVATE platform/default/headless_display.cpp
- PRIVATE platform/default/offscreen_view.cpp
+ PRIVATE platform/default/mbgl/gl/headless_display.cpp
+ PRIVATE platform/default/mbgl/gl/headless_display.hpp
+ PRIVATE platform/default/mbgl/gl/offscreen_view.cpp
+ PRIVATE platform/default/mbgl/gl/offscreen_view.hpp
# Thread pool
- PRIVATE platform/default/thread_pool.cpp
+ PRIVATE platform/default/mbgl/util/default_thread_pool.cpp
+ PRIVATE platform/default/mbgl/util/default_thread_pool.cpp
)
target_add_mason_package(mbgl-core PUBLIC geojson)
+ target_add_mason_package(mbgl-core PUBLIC icu)
target_compile_options(mbgl-core
PRIVATE -fobjc-arc
@@ -60,7 +74,8 @@ macro(mbgl_platform_core)
)
target_include_directories(mbgl-core
- PRIVATE platform/default
+ PUBLIC platform/darwin
+ PUBLIC platform/default
)
target_link_libraries(mbgl-core
diff --git a/platform/ios/framework/Settings.bundle/zh-Hans.lproj/Root.strings b/platform/ios/framework/Settings.bundle/zh-Hans.lproj/Root.strings
new file mode 100644
index 0000000000..3cfb1a4bad
--- /dev/null
+++ b/platform/ios/framework/Settings.bundle/zh-Hans.lproj/Root.strings
@@ -0,0 +1,3 @@
+"TELEMETRY_GROUP_TITLE" = "隐私设置";
+"TELEMETRY_SWITCH_TITLE" = "Mapbox传感数据";
+"TELEMETRY_GROUP_FOOTER" = "此设置允许应用将用户位置和数据以匿名的方式分享给Mapbox。";
diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj
index c637cca7e8..c606c74ea1 100644
--- a/platform/ios/ios.xcodeproj/project.pbxproj
+++ b/platform/ios/ios.xcodeproj/project.pbxproj
@@ -507,6 +507,9 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
+ 20DABE861DF78148007AC5FF /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Foundation.strings"; sourceTree = "<group>"; };
+ 20DABE881DF78148007AC5FF /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = "<group>"; };
+ 20DABE8A1DF78149007AC5FF /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Root.strings"; sourceTree = "<group>"; };
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>"; };
@@ -939,6 +942,8 @@
3575798F1D513EF1000B822E /* Layers */ = {
isa = PBXGroup;
children = (
+ DA2DBBCC1D51E80400D38FF9 /* MGLStyleLayerTests.h */,
+ DA2DBBCD1D51E80400D38FF9 /* MGLStyleLayerTests.m */,
3575797F1D501E09000B822E /* MGLFillStyleLayerTests.m */,
357579821D502AE6000B822E /* MGLRasterStyleLayerTests.m */,
357579841D502AF5000B822E /* MGLSymbolStyleLayerTests.m */,
@@ -1086,8 +1091,6 @@
DA35A2A91CCA058D00E826B2 /* MGLCoordinateFormatterTests.m */,
DA0CD58F1CF56F6A00A5F5A5 /* MGLFeatureTests.mm */,
DA2E885C1CC0382C00F24E7B /* MGLGeometryTests.mm */,
- DA2DBBCC1D51E80400D38FF9 /* MGLStyleLayerTests.h */,
- DA2DBBCD1D51E80400D38FF9 /* MGLStyleLayerTests.m */,
35E208A61D24210F00EC9A46 /* MGLNSDataAdditionsTests.m */,
DA2E885D1CC0382C00F24E7B /* MGLOfflinePackTests.m */,
DA2E885E1CC0382C00F24E7B /* MGLOfflineRegionTests.m */,
@@ -1796,6 +1799,7 @@
knownRegions = (
en,
Base,
+ "zh-Hans",
);
mainGroup = DA1DC9411CB6C1C2006E619F;
productRefGroup = DA1DC94B1CB6C1C2006E619F /* Products */;
@@ -2162,6 +2166,7 @@
isa = PBXVariantGroup;
children = (
DA25D5C51CCDA06800607828 /* Base */,
+ 20DABE8A1DF78149007AC5FF /* zh-Hans */,
);
name = Root.strings;
sourceTree = "<group>";
@@ -2170,6 +2175,7 @@
isa = PBXVariantGroup;
children = (
DA8933A01CCC951200E68420 /* Base */,
+ 20DABE881DF78148007AC5FF /* zh-Hans */,
);
name = Localizable.strings;
sourceTree = "<group>";
@@ -2178,6 +2184,7 @@
isa = PBXVariantGroup;
children = (
DA8933BB1CCD2CA100E68420 /* Base */,
+ 20DABE861DF78148007AC5FF /* zh-Hans */,
);
name = Foundation.strings;
sourceTree = "<group>";
@@ -2213,6 +2220,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LIBRARY = "libc++";
@@ -2264,6 +2272,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LIBRARY = "libc++";
diff --git a/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/CI.xcscheme b/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/CI.xcscheme
index cb3d7b0242..437f000a3c 100644
--- a/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/CI.xcscheme
+++ b/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/CI.xcscheme
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
- LastUpgradeVersion = "0800"
+ LastUpgradeVersion = "0810"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
diff --git a/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/bench.xcscheme b/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/bench.xcscheme
index 5f80514b41..0a12923924 100644
--- a/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/bench.xcscheme
+++ b/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/bench.xcscheme
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
- LastUpgradeVersion = "0800"
+ LastUpgradeVersion = "0810"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
diff --git a/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/dynamic+static.xcscheme b/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/dynamic+static.xcscheme
index 67f630ea41..2bba3a3e05 100644
--- a/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/dynamic+static.xcscheme
+++ b/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/dynamic+static.xcscheme
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
- LastUpgradeVersion = "0800"
+ LastUpgradeVersion = "0810"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
diff --git a/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/dynamic.xcscheme b/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/dynamic.xcscheme
index ae4ebcc5d4..31c86be795 100644
--- a/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/dynamic.xcscheme
+++ b/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/dynamic.xcscheme
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
- LastUpgradeVersion = "0800"
+ LastUpgradeVersion = "0810"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
diff --git a/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/iosapp.xcscheme b/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/iosapp.xcscheme
index 05d05b2ec9..a299ab49b1 100644
--- a/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/iosapp.xcscheme
+++ b/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/iosapp.xcscheme
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
- LastUpgradeVersion = "0800"
+ LastUpgradeVersion = "0810"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
diff --git a/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/static.xcscheme b/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/static.xcscheme
index f56be478f7..9bfc8aac36 100644
--- a/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/static.xcscheme
+++ b/platform/ios/ios.xcodeproj/xcshareddata/xcschemes/static.xcscheme
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
- LastUpgradeVersion = "0800"
+ LastUpgradeVersion = "0810"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
diff --git a/platform/ios/resources/zh-Hans.lproj/Localizable.strings b/platform/ios/resources/zh-Hans.lproj/Localizable.strings
new file mode 100644
index 0000000000..087a09dbb8
--- /dev/null
+++ b/platform/ios/resources/zh-Hans.lproj/Localizable.strings
@@ -0,0 +1,84 @@
+/* Accessibility hint */
+"ANNOTATION_A11Y_HINT" = "显示信息";
+
+/* No comment provided by engineer. */
+"API_CLIENT_400_DESC" = "The session data task failed. Original request was: %@";
+
+/* No comment provided by engineer. */
+"API_CLIENT_400_REASON" = "The status code was %ld";
+
+/* No comment provided by engineer. */
+"CANCEL" = "取消";
+
+/* Accessibility hint */
+"COMPASS_A11Y_HINT" = "旋转地图使正北朝上";
+
+/* Accessibility label */
+"COMPASS_A11Y_LABEL" = "指南针";
+
+/* Compass abbreviation for north */
+"COMPASS_NORTH" = "北";
+
+/* Copyright notice in attribution sheet */
+"COPY_MAPBOX" = "© Mapbox";
+
+/* Copyright notice in attribution sheet */
+"COPY_OSM" = "© OpenStreetMap";
+
+/* Instructions in Interface Builder designable; {key}, {plist file name} */
+"DESIGNABLE" = "在%2$@中将你的access token设为%1$@可在这里显示Mapbox上的地图\n\n更多说明请见";
+
+/* Setup documentation URL display string; keep as short as possible */
+"FIRST_STEPS_URL" = "mapbox.com/help/first-steps-ios-sdk";
+
+/* Accessibility hint */
+"INFO_A11Y_HINT" = "显示致谢、用户反馈及更多";
+
+/* Accessibility label */
+"INFO_A11Y_LABEL" = "关于这个地图";
+
+/* Accessibility label */
+"LOGO_A11Y_LABEL" = "Mapbox";
+
+/* Accessibility label */
+"MAP_A11Y_LABEL" = "地图";
+
+/* Map accessibility value */
+"MAP_A11Y_VALUE" = "地图缩放%1$d倍\n有%2$ld处标记可见";
+
+/* Action in attribution sheet */
+"MAP_FEEDBACK" = "改进地图";
+
+/* Action sheet title */
+"SDK_NAME" = "Mapbox iOS SDK";
+
+/* Telemetry prompt message */
+"TELEMETRY_DISABLED_MSG" = "你可以提供匿名数据来帮助OpenStreetMap和Mapbox的地图变得更好。";
+
+/* Telemetry prompt button */
+"TELEMETRY_DISABLED_OFF" = "暂不参与";
+
+/* Telemetry prompt button */
+"TELEMETRY_DISABLED_ON" = "我要参与";
+
+/* Telemetry prompt message */
+"TELEMETRY_ENABLED_MSG" = "你的匿名数据在帮助OpenStreetMap和Mapbox的地图变得更好。";
+
+/* Telemetry prompt button */
+"TELEMETRY_ENABLED_OFF" = "不再参与";
+
+/* Telemetry prompt button */
+"TELEMETRY_ENABLED_ON" = "继续参与";
+
+/* Telemetry prompt button */
+"TELEMETRY_MORE" = "详细信息";
+
+/* Action in attribution sheet */
+"TELEMETRY_NAME" = "Mapbox传感数据";
+
+/* Telemetry prompt title */
+"TELEMETRY_TITLE" = "让Mapbox地图变得更好";
+
+/* Default user location annotation title */
+"USER_DOT_TITLE" = "你在这里";
+
diff --git a/platform/ios/scripts/metrics.sh b/platform/ios/scripts/metrics.sh
new file mode 100755
index 0000000000..c45beb3a11
--- /dev/null
+++ b/platform/ios/scripts/metrics.sh
@@ -0,0 +1,20 @@
+#!/usr/bin/env bash
+
+set -e
+set -o pipefail
+
+# Generate stripped versions for every architecture
+xcrun bitcode_strip build/ios/pkg/dynamic/Mapbox.framework/Mapbox -r -o build/ios/pkg/dynamic/Mapbox-stripped
+lipo build/ios/pkg/dynamic/Mapbox-stripped -extract armv7 -output build/ios/pkg/dynamic/Mapbox-stripped-armv7
+lipo build/ios/pkg/dynamic/Mapbox-stripped -extract arm64 -output build/ios/pkg/dynamic/Mapbox-stripped-arm64
+lipo build/ios/pkg/dynamic/Mapbox-stripped -extract i386 -output build/ios/pkg/dynamic/Mapbox-stripped-i386
+lipo build/ios/pkg/dynamic/Mapbox-stripped -extract x86_64 -output build/ios/pkg/dynamic/Mapbox-stripped-x86_64
+
+# Track individual architectures
+scripts/log_binary_size.sh "build/ios/pkg/dynamic/Mapbox-stripped-armv7" "Platform=iOS,Arch=armv7"
+scripts/log_binary_size.sh "build/ios/pkg/dynamic/Mapbox-stripped-arm64" "Platform=iOS,Arch=arm64"
+scripts/log_binary_size.sh "build/ios/pkg/dynamic/Mapbox-stripped-i386" "Platform=iOS,Arch=i386"
+scripts/log_binary_size.sh "build/ios/pkg/dynamic/Mapbox-stripped-x86_64" "Platform=iOS,Arch=x86_64"
+
+# Track overall library size
+scripts/log_binary_size.sh "build/ios/pkg/dynamic/Mapbox-stripped" "Platform=iOS,Arch=Dynamic"
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm
index b01ab09fb4..608acf016d 100644
--- a/platform/ios/src/MGLMapView.mm
+++ b/platform/ios/src/MGLMapView.mm
@@ -1,20 +1,20 @@
#import "MGLMapView_Private.h"
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
#include <mbgl/gl/extension.hpp>
#include <mbgl/gl/context.hpp>
#import <GLKit/GLKit.h>
#import <OpenGLES/EAGL.h>
-#include <mbgl/mbgl.hpp>
+#include <mbgl/map/view.hpp>
#include <mbgl/annotation/annotation.hpp>
#include <mbgl/sprite/sprite_image.hpp>
#include <mbgl/map/camera.hpp>
#include <mbgl/map/mode.hpp>
-#include <mbgl/platform/platform.hpp>
-#include <mbgl/platform/darwin/reachability.h>
-#include <mbgl/platform/default/thread_pool.hpp>
+#include <mbgl/util/platform.hpp>
+#include <mbgl/storage/reachability.h>
+#include <mbgl/util/default_thread_pool.hpp>
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/storage/network_status.hpp>
#include <mbgl/style/transition_options.hpp>
@@ -419,12 +419,10 @@ public:
[[NSFileManager defaultManager] removeItemAtPath:fileCachePath error:NULL];
// setup mbgl map
- const std::array<uint16_t, 2> size = {{ static_cast<uint16_t>(self.bounds.size.width),
- static_cast<uint16_t>(self.bounds.size.height) }};
mbgl::DefaultFileSource *mbglFileSource = [MGLOfflineStorage sharedOfflineStorage].mbglFileSource;
const float scaleFactor = [UIScreen instancesRespondToSelector:@selector(nativeScale)] ? [[UIScreen mainScreen] nativeScale] : [[UIScreen mainScreen] scale];
_mbglThreadPool = new mbgl::ThreadPool(4);
- _mbglMap = new mbgl::Map(*_mbglView, size, scaleFactor, *mbglFileSource, *_mbglThreadPool, mbgl::MapMode::Continuous, mbgl::GLContextMode::Unique, mbgl::ConstrainMode::None, mbgl::ViewportMode::Default);
+ _mbglMap = new mbgl::Map(*_mbglView, self.size, scaleFactor, *mbglFileSource, *_mbglThreadPool, mbgl::MapMode::Continuous, mbgl::GLContextMode::Unique, mbgl::ConstrainMode::None, mbgl::ViewportMode::Default);
[self validateTileCacheSize];
// start paused if in IB
@@ -567,6 +565,18 @@ public:
}
}
+- (mbgl::Size)size
+{
+ return { static_cast<uint32_t>(self.bounds.size.width),
+ static_cast<uint32_t>(self.bounds.size.height) };
+}
+
+- (mbgl::Size)framebufferSize
+{
+ return { static_cast<uint32_t>(self.glView.drawableWidth),
+ static_cast<uint32_t>(self.glView.drawableHeight) };
+}
+
- (void)createGLView
{
if (_context) return;
@@ -875,10 +885,8 @@ public:
[self adjustContentInset];
- if ( ! _isTargetingInterfaceBuilder)
- {
- _mbglMap->setSize({{ static_cast<uint16_t>(self.bounds.size.width),
- static_cast<uint16_t>(self.bounds.size.height) }});
+ if (!_isTargetingInterfaceBuilder) {
+ _mbglMap->setSize([self size]);
}
if (self.attributionSheet.visible)
@@ -5124,13 +5132,11 @@ public:
class MBGLView : public mbgl::View, public mbgl::Backend
{
public:
- MBGLView(MGLMapView* nativeView_)
- : nativeView(nativeView_) {
+ MBGLView(MGLMapView* nativeView_) : nativeView(nativeView_) {
}
mbgl::gl::value::Viewport::Type getViewport() const {
- return { 0, 0, static_cast<uint16_t>(nativeView.glView.drawableWidth),
- static_cast<uint16_t>(nativeView.glView.drawableHeight) };
+ return { 0, 0, nativeView.framebufferSize };
}
/// This function is called before we start rendering, when iOS invokes our rendering method.
@@ -5140,6 +5146,7 @@ public:
// We are using 0 as the placeholder value for the GLKView's framebuffer.
getContext().bindFramebuffer.setCurrentValue(0);
getContext().viewport.setCurrentValue(getViewport());
+ assert(mbgl::gl::value::Viewport::Get() == getContext().viewport.getCurrentValue());
}
void bind() override {
diff --git a/platform/ios/src/MGLMapView_Private.h b/platform/ios/src/MGLMapView_Private.h
index 5c74ba6dc8..6b6a898f93 100644
--- a/platform/ios/src/MGLMapView_Private.h
+++ b/platform/ios/src/MGLMapView_Private.h
@@ -1,6 +1,6 @@
#import <Mapbox/Mapbox.h>
-#include <mbgl/mbgl.hpp>
+#import <mbgl/map/map.hpp>
/// Minimum size of an annotation’s accessibility element.
extern const CGSize MGLAnnotationAccessibilityElementMinimumSize;
diff --git a/platform/ios/src/MGLMapboxEvents.m b/platform/ios/src/MGLMapboxEvents.m
index 2658cdfaa4..2c25cf0a62 100644
--- a/platform/ios/src/MGLMapboxEvents.m
+++ b/platform/ios/src/MGLMapboxEvents.m
@@ -7,7 +7,7 @@
#import "MGLAPIClient.h"
#import "MGLLocationManager.h"
-#include <mbgl/platform/darwin/reachability.h>
+#include <mbgl/storage/reachability.h>
#include <sys/sysctl.h>
// Event types
diff --git a/platform/ios/src/UIImage+MGLAdditions.mm b/platform/ios/src/UIImage+MGLAdditions.mm
index e4d072e136..7b5737f5e4 100644
--- a/platform/ios/src/UIImage+MGLAdditions.mm
+++ b/platform/ios/src/UIImage+MGLAdditions.mm
@@ -22,7 +22,7 @@
size_t width = CGImageGetWidth(cgImage);
size_t height = CGImageGetHeight(cgImage);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
- mbgl::PremultipliedImage cPremultipliedImage(width, height);
+ mbgl::PremultipliedImage cPremultipliedImage({ static_cast<uint32_t>(width), static_cast<uint32_t>(height) });
size_t bytesPerPixel = 4;
size_t bytesPerRow = bytesPerPixel * width;
size_t bitsPerComponent = 8;
diff --git a/platform/ios/test/MGLSourceTests.m b/platform/ios/test/MGLSourceTests.m
new file mode 100644
index 0000000000..90ec4e3a0b
--- /dev/null
+++ b/platform/ios/test/MGLSourceTests.m
@@ -0,0 +1,24 @@
+#import "MGLMapViewTests.h"
+
+@interface MGLSourceTests : MGLMapViewTests
+
+@end
+
+@implementation MGLSourceTests
+
+- (void)testDuplicateSources {
+ MGLVectorSource *source1 = [[MGLVectorSource alloc] initWithIdentifier:@"my-source" URL:[NSURL URLWithString:@"mapbox://mapbox.mapbox-terrain-v2"]];
+ MGLVectorSource *source2 = [[MGLVectorSource alloc] initWithIdentifier:@"my-source" URL:[NSURL URLWithString:@"mapbox://mapbox.mapbox-terrain-v2"]];
+
+ [self.mapView.style addSource: source1];
+
+ @try {
+ [self.mapView.style addSource: source2];
+ XCTFail(@"Should not have reached this point");
+ }
+ @catch (NSException *e) {
+ XCTAssertNotNil(e, @"Should have thrown an exception");
+ }
+}
+
+@end
diff --git a/platform/ios/toolchain.cmake b/platform/ios/toolchain.cmake
index 60dbac07c7..512b46b6d9 100644
--- a/platform/ios/toolchain.cmake
+++ b/platform/ios/toolchain.cmake
@@ -113,13 +113,6 @@ set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY)
set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
-
-# This little macro lets you set any XCode specific property
-macro (set_xcode_property TARGET XCODE_PROPERTY XCODE_VALUE)
- set_property (TARGET ${TARGET} PROPERTY XCODE_ATTRIBUTE_${XCODE_PROPERTY} ${XCODE_VALUE})
-endmacro (set_xcode_property)
-
-
# This macro lets you find executable programs on the host system
macro (find_host_package)
set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
diff --git a/platform/ios/uitest/KIF b/platform/ios/uitest/KIF
-Subproject bcb58d0419cfaefe286f3df1c8618bac43b4592
+Subproject 973a4cb653b54c3e8b2c0681f4097568ff0ac34
diff --git a/platform/ios/uitest/OHHTTPStubs b/platform/ios/uitest/OHHTTPStubs
-Subproject e3cd0173c459b8cd43f202fe8816f1675916717
+Subproject deed01a1592210a4c37f3f5c5f2b32fe0e41c60
diff --git a/platform/linux/config.cmake b/platform/linux/config.cmake
index 8acb6e7e14..51aecb86a9 100644
--- a/platform/linux/config.cmake
+++ b/platform/linux/config.cmake
@@ -1,6 +1,8 @@
mason_use(glfw VERSION 3.2.1)
-mason_use(mesa VERSION 13.0.0${MASON_CXXABI_SUFFIX})
-mason_use(boost_libprogram_options VERSION 1.60.0)
+if(IS_CI_BUILD AND NOT WITH_EGL)
+ mason_use(mesa VERSION 13.0.0${MASON_MESA_SUFFIX}${MASON_CXXABI_SUFFIX})
+endif()
+mason_use(boost_libprogram_options VERSION 1.62.0)
mason_use(sqlite VERSION 3.14.2)
mason_use(libuv VERSION 1.9.1)
mason_use(nunicode VERSION 1.7.1)
@@ -9,35 +11,43 @@ mason_use(libjpeg-turbo VERSION 1.5.0)
mason_use(webp VERSION 0.5.1)
mason_use(gtest VERSION 1.7.0${MASON_CXXABI_SUFFIX})
mason_use(benchmark VERSION 1.0.0)
+mason_use(icu VERSION 58.1)
include(cmake/loop-uv.cmake)
-macro(use_glx_backend _TARGET)
- target_sources(${_TARGET}
- PRIVATE platform/default/headless_backend_glx.cpp
- )
-
- target_link_libraries(${_TARGET}
- PUBLIC -lGL
- PUBLIC -lX11
- )
-endmacro()
-
-macro(use_osmesa_backend _TARGET)
- target_sources(${_TARGET}
- PRIVATE platform/default/headless_backend_osmesa.cpp
- )
-
- target_add_mason_package(${_TARGET}
- PUBLIC mesa
- )
-endmacro()
-
macro(mbgl_platform_core)
- if (WITH_OSMESA)
- use_osmesa_backend(mbgl-core)
+ if(WITH_OSMESA)
+ target_sources(mbgl-core
+ PRIVATE platform/default/headless_backend_osmesa.cpp
+ PRIVATE platform/default/mbgl/gl/headless_display.cpp
+ )
+ target_add_mason_package(mbgl-core PUBLIC mesa)
+ elseif(WITH_EGL)
+ target_sources(mbgl-core
+ PRIVATE platform/linux/src/headless_backend_egl.cpp
+ PRIVATE platform/linux/src/headless_display_egl.cpp
+ )
+ # TODO: Provide surface-less EGL mesa for CI builds.
+ # https://github.com/mapbox/mapbox-gl-native/issues/7020
+ target_link_libraries(mbgl-core
+ PUBLIC -lGLESv2
+ PUBLIC -lEGL
+ PUBLIC -lgbm
+ )
else()
- use_glx_backend(mbgl-core)
+ target_sources(mbgl-core
+ PRIVATE platform/linux/src/headless_backend_glx.cpp
+ PRIVATE platform/linux/src/headless_display_glx.cpp
+ )
+ if (IS_CI_BUILD)
+ target_add_mason_package(mbgl-core PUBLIC mesa)
+ target_link_libraries(mbgl-core PUBLIC -lX11)
+ else()
+ target_link_libraries(mbgl-core
+ PUBLIC -lGL
+ PUBLIC -lX11
+ )
+ endif()
endif()
target_sources(mbgl-core
@@ -58,9 +68,10 @@ macro(mbgl_platform_core)
PRIVATE platform/default/sqlite3.hpp
# Misc
- PRIVATE platform/default/log_stderr.cpp
+ PRIVATE platform/default/logging_stderr.cpp
PRIVATE platform/default/string_stdlib.cpp
PRIVATE platform/default/thread.cpp
+ PRIVATE platform/default/bidi.cpp
# Image handling
PRIVATE platform/default/image.cpp
@@ -69,12 +80,15 @@ macro(mbgl_platform_core)
PRIVATE platform/default/webp_reader.cpp
# Headless view
- PRIVATE platform/default/headless_backend.cpp
- PRIVATE platform/default/headless_display.cpp
- PRIVATE platform/default/offscreen_view.cpp
+ PRIVATE platform/default/mbgl/gl/headless_backend.cpp
+ PRIVATE platform/default/mbgl/gl/headless_backend.hpp
+ PRIVATE platform/default/mbgl/gl/headless_display.hpp
+ PRIVATE platform/default/mbgl/gl/offscreen_view.cpp
+ PRIVATE platform/default/mbgl/gl/offscreen_view.hpp
# Thread pool
- PRIVATE platform/default/thread_pool.cpp
+ PRIVATE platform/default/mbgl/util/default_thread_pool.cpp
+ PRIVATE platform/default/mbgl/util/default_thread_pool.cpp
)
target_include_directories(mbgl-core
@@ -86,6 +100,7 @@ macro(mbgl_platform_core)
target_add_mason_package(mbgl-core PUBLIC libpng)
target_add_mason_package(mbgl-core PUBLIC libjpeg-turbo)
target_add_mason_package(mbgl-core PUBLIC webp)
+ target_add_mason_package(mbgl-core PUBLIC icu)
target_link_libraries(mbgl-core
PUBLIC -lz
diff --git a/platform/linux/scripts/after_success.sh b/platform/linux/scripts/after_success.sh
new file mode 100755
index 0000000000..3531e3fb74
--- /dev/null
+++ b/platform/linux/scripts/after_success.sh
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+
+set -e
+set -o pipefail
+
+if [ "${TRAVIS_PULL_REQUEST_BRANCH:-${TRAVIS_BRANCH}}" = "master" ] && [ "${BUILDTYPE}" = "Release" ]; then
+ CLOUDWATCH=true platform/linux/scripts/metrics.sh
+else
+ echo "Not logging binary size for branch or Debug build"
+fi
diff --git a/platform/linux/scripts/metrics.sh b/platform/linux/scripts/metrics.sh
new file mode 100755
index 0000000000..82dcf98d5c
--- /dev/null
+++ b/platform/linux/scripts/metrics.sh
@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+
+set -e
+set -o pipefail
+
+# Generate stripped version
+ARCH=$(uname -m)
+RENDER=build/linux-${ARCH}/Release/mbgl-render
+strip -s -x "${RENDER}" -o "${RENDER}-stripped"
+
+# Track individual architecture
+scripts/log_binary_size.sh "${RENDER}-stripped" "Platform=Linux,Compiler=${_CC},Arch=${ARCH}"
diff --git a/platform/linux/src/headless_backend_egl.cpp b/platform/linux/src/headless_backend_egl.cpp
new file mode 100644
index 0000000000..87e7c1d0ed
--- /dev/null
+++ b/platform/linux/src/headless_backend_egl.cpp
@@ -0,0 +1,103 @@
+#include <mbgl/gl/headless_backend.hpp>
+#include <mbgl/gl/headless_display.hpp>
+
+#include <mbgl/util/logging.hpp>
+
+#include <EGL/egl.h>
+
+#include <cassert>
+
+namespace mbgl {
+
+struct EGLImpl : public HeadlessBackend::Impl {
+ EGLImpl(EGLContext glContext_, EGLDisplay display_, EGLConfig config_)
+ : glContext(glContext_),
+ display(display_),
+ config(config_) {
+#if __ANDROID__
+ // Create a pixel buffer surface (in conjunction with EGL_SURFACE_TYPE, EGL_PBUFFER_BIT).
+ const EGLint surfAttribs[] = {
+ EGL_WIDTH, 512,
+ EGL_HEIGHT, 512,
+ EGL_LARGEST_PBUFFER, EGL_TRUE,
+ EGL_NONE
+ };
+
+ glSurface = eglCreatePbufferSurface(display, config, surfAttribs);
+ if (glSurface == EGL_NO_SURFACE) {
+ throw std::runtime_error("Could not create surface: " + std::to_string(eglGetError()));
+ }
+#endif // __ANDROID__
+ }
+
+ ~EGLImpl() {
+ if (glContext != eglGetCurrentContext()) {
+ activateContext();
+ }
+ if (!eglDestroyContext(display, glContext)) {
+ throw std::runtime_error("Failed to destroy EGL context.\n");
+ }
+ if (glSurface != EGL_NO_SURFACE) {
+ if (!eglDestroySurface(display, glSurface)) {
+ throw std::runtime_error("Failed to destroy EGL context.\n");
+ }
+ glSurface = EGL_NO_SURFACE;
+ }
+ }
+
+ void activateContext() final {
+ if (!eglMakeCurrent(display, glSurface, glSurface, glContext)) {
+ throw std::runtime_error("Switching OpenGL context failed.\n");
+ }
+ }
+
+ void deactivateContext() final {
+ if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) {
+ throw std::runtime_error("Removing OpenGL context failed.\n");
+ }
+ }
+
+ EGLContext glContext = EGL_NO_CONTEXT;
+ EGLDisplay display = EGL_NO_DISPLAY;
+ EGLConfig config = 0;
+ EGLSurface glSurface = EGL_NO_SURFACE;
+};
+
+gl::glProc HeadlessBackend::initializeExtension(const char* name) {
+ return eglGetProcAddress(name);
+}
+
+bool HeadlessBackend::hasDisplay() {
+ if (!display) {
+ display.reset(new HeadlessDisplay);
+ }
+ return bool(display);
+};
+
+void HeadlessBackend::createContext() {
+ assert(!hasContext());
+ assert(hasDisplay());
+
+ EGLDisplay display_ = display->attribute<EGLDisplay>();
+ EGLConfig& config = display->attribute<EGLConfig&>();
+
+ // EGL initializes the context client version to 1 by default. We want to
+ // use OpenGL ES 2.0 which has the ability to create shader and program
+ // objects and also to write vertex and fragment shaders in the OpenGL ES
+ // Shading Language.
+ const EGLint attribs[] = {
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL_NONE
+ };
+
+ EGLContext glContext = eglCreateContext(display_, config, EGL_NO_CONTEXT, attribs);
+ if (glContext == EGL_NO_CONTEXT) {
+ mbgl::Log::Error(mbgl::Event::OpenGL, "eglCreateContext() returned error 0x%04x",
+ eglGetError());
+ throw std::runtime_error("Error creating the EGL context object.\n");
+ }
+
+ impl.reset(new EGLImpl(glContext, display_, config));
+}
+
+} // namespace mbgl
diff --git a/platform/linux/src/headless_backend_glx.cpp b/platform/linux/src/headless_backend_glx.cpp
new file mode 100644
index 0000000000..5791f1892f
--- /dev/null
+++ b/platform/linux/src/headless_backend_glx.cpp
@@ -0,0 +1,87 @@
+#include <mbgl/gl/headless_backend.hpp>
+#include <mbgl/gl/headless_display.hpp>
+
+#include <mbgl/util/logging.hpp>
+
+#include <cassert>
+
+#include <GL/glx.h>
+
+namespace mbgl {
+
+struct GLXImpl : public HeadlessBackend::Impl {
+ GLXImpl(GLXContext glContext_, GLXPbuffer glxPbuffer_, Display* xDisplay_, GLXFBConfig* fbConfigs_)
+ : glContext(glContext_),
+ glxPbuffer(glxPbuffer_),
+ xDisplay(xDisplay_),
+ fbConfigs(fbConfigs_) {
+ }
+
+ ~GLXImpl() {
+ if (glxPbuffer) {
+ glXDestroyPbuffer(xDisplay, glxPbuffer);
+ }
+ glXDestroyContext(xDisplay, glContext);
+ }
+
+ void activateContext() final {
+ if (!glXMakeContextCurrent(xDisplay, glxPbuffer, glxPbuffer, glContext)) {
+ throw std::runtime_error("Switching OpenGL context failed.\n");
+ }
+ }
+
+ void deactivateContext() final {
+ if (!glXMakeContextCurrent(xDisplay, 0, 0, nullptr)) {
+ throw std::runtime_error("Removing OpenGL context failed.\n");
+ }
+ }
+
+ GLXContext glContext = nullptr;
+ GLXPbuffer glxPbuffer = 0;
+
+ // Needed for ImplDeleter.
+ Display* xDisplay = nullptr;
+ GLXFBConfig* fbConfigs = nullptr;
+};
+
+gl::glProc HeadlessBackend::initializeExtension(const char* name) {
+ return glXGetProcAddress(reinterpret_cast<const GLubyte*>(name));
+}
+
+bool HeadlessBackend::hasDisplay() {
+ if (!display) {
+ display.reset(new HeadlessDisplay);
+ }
+ return bool(display);
+};
+
+void HeadlessBackend::createContext() {
+ assert(!hasContext());
+
+ Display* xDisplay = display->attribute<Display*>();
+ GLXFBConfig* fbConfigs = display->attribute<GLXFBConfig*>();
+
+ // Try to create a legacy context.
+ GLXContext glContext = glXCreateNewContext(xDisplay, fbConfigs[0], GLX_RGBA_TYPE, None, True);
+ if (glContext && !glXIsDirect(xDisplay, glContext)) {
+ Log::Error(Event::OpenGL, "failed to create direct OpenGL Legacy context");
+ glXDestroyContext(xDisplay, glContext);
+ glContext = nullptr;
+ }
+ if (glContext == nullptr) {
+ throw std::runtime_error("Error creating GL context object.");
+ }
+
+ // Create a dummy pbuffer. We will render to framebuffers anyway, but we need a pbuffer to
+ // activate the context.
+ int pbufferAttributes[] = {
+ GLX_PBUFFER_WIDTH, 8,
+ GLX_PBUFFER_HEIGHT, 8,
+ None
+ };
+ GLXPbuffer glxPbuffer = glXCreatePbuffer(xDisplay, fbConfigs[0], pbufferAttributes);
+
+ impl.reset(new GLXImpl(glContext, glxPbuffer, xDisplay, fbConfigs));
+}
+
+} // namespace mbgl
diff --git a/platform/linux/src/headless_display_egl.cpp b/platform/linux/src/headless_display_egl.cpp
new file mode 100644
index 0000000000..eddc05feaf
--- /dev/null
+++ b/platform/linux/src/headless_display_egl.cpp
@@ -0,0 +1,69 @@
+#include <mbgl/gl/headless_display.hpp>
+#include <mbgl/util/logging.hpp>
+#include <mbgl/util/string.hpp>
+
+#include <EGL/egl.h>
+
+namespace mbgl {
+
+class HeadlessDisplay::Impl {
+public:
+ Impl();
+ ~Impl();
+
+ EGLDisplay display = EGL_NO_DISPLAY;
+ EGLConfig config = 0;
+};
+
+HeadlessDisplay::Impl::Impl() {
+ display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (display == EGL_NO_DISPLAY) {
+ throw std::runtime_error("Failed to obtain a valid EGL display.\n");
+ }
+
+ EGLint major, minor, numConfigs;
+ if (!eglInitialize(display, &major, &minor)) {
+ throw std::runtime_error("eglInitialize() failed.\n");
+ }
+
+ if (!eglBindAPI(EGL_OPENGL_ES_API)) {
+ mbgl::Log::Error(mbgl::Event::OpenGL, "eglBindAPI(EGL_OPENGL_ES_API) returned error %d", eglGetError());
+ throw std::runtime_error("eglBindAPI() failed");
+ }
+
+ const EGLint attribs[] = {
+#if __ANDROID__
+ // Android emulator requires a pixel buffer to generate renderable unit
+ // test results.
+ EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
+#endif // __ANDROID__
+ EGL_NONE
+ };
+
+ if (!eglChooseConfig(display, attribs, &config, 1, &numConfigs) || numConfigs != 1) {
+ throw std::runtime_error("Failed to choose ARGB config.\n");
+ }
+}
+
+HeadlessDisplay::Impl::~Impl() {
+ eglTerminate(display);
+}
+
+template <>
+EGLDisplay HeadlessDisplay::attribute() const {
+ return impl->display;
+}
+
+template <>
+EGLConfig& HeadlessDisplay::attribute() const {
+ return impl->config;
+}
+
+HeadlessDisplay::HeadlessDisplay()
+ : impl(std::make_unique<Impl>()) {
+}
+
+HeadlessDisplay::~HeadlessDisplay() {
+}
+
+} // namespace mbgl
diff --git a/platform/default/headless_display.cpp b/platform/linux/src/headless_display_glx.cpp
index b98aef7903..4275ebb646 100644
--- a/platform/default/headless_display.cpp
+++ b/platform/linux/src/headless_display_glx.cpp
@@ -1,8 +1,6 @@
-#include <mbgl/platform/default/headless_display.hpp>
+#include <mbgl/gl/headless_display.hpp>
-#if MBGL_USE_GLX
#include <GL/glx.h>
-#endif
#include <cstring>
#include <stdexcept>
@@ -10,27 +8,16 @@
namespace mbgl {
-HeadlessDisplay::HeadlessDisplay() {
-#if MBGL_USE_CGL
- // TODO: test if OpenGL 4.1 with GL_ARB_ES2_compatibility is supported
- // If it is, use kCGLOGLPVersion_3_2_Core and enable that extension.
- CGLPixelFormatAttribute attributes[] = {
- kCGLPFAOpenGLProfile,
- static_cast<CGLPixelFormatAttribute>(kCGLOGLPVersion_Legacy),
- static_cast<CGLPixelFormatAttribute>(0)
- };
+class HeadlessDisplay::Impl {
+public:
+ Impl();
+ ~Impl();
- GLint num;
- CGLError error = CGLChoosePixelFormat(attributes, &pixelFormat, &num);
- if (error != kCGLNoError) {
- throw std::runtime_error(std::string("Error choosing pixel format:") + CGLErrorString(error) + "\n");
- }
- if (num <= 0) {
- throw std::runtime_error("No pixel formats found.");
- }
-#endif
+ Display* xDisplay = nullptr;
+ GLXFBConfig* fbConfigs = nullptr;
+};
-#if MBGL_USE_GLX
+HeadlessDisplay::Impl::Impl() {
if (!XInitThreads()) {
throw std::runtime_error("Failed to XInitThreads.");
}
@@ -65,18 +52,28 @@ HeadlessDisplay::HeadlessDisplay() {
if (configs <= 0) {
throw std::runtime_error("No Framebuffer configurations.");
}
-#endif
}
-HeadlessDisplay::~HeadlessDisplay() {
-#if MBGL_USE_CGL
- CGLDestroyPixelFormat(pixelFormat);
-#endif
-
-#if MBGL_USE_GLX
+HeadlessDisplay::Impl::~Impl() {
XFree(fbConfigs);
XCloseDisplay(xDisplay);
-#endif
+}
+
+template <>
+Display* HeadlessDisplay::attribute() const {
+ return impl->xDisplay;
+}
+
+template <>
+GLXFBConfig* HeadlessDisplay::attribute() const {
+ return impl->fbConfigs;
+}
+
+HeadlessDisplay::HeadlessDisplay()
+ : impl(std::make_unique<Impl>()) {
+}
+
+HeadlessDisplay::~HeadlessDisplay() {
}
} // namespace mbgl
diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md
index 8482cc5e0b..2495cd0e06 100644
--- a/platform/macos/CHANGELOG.md
+++ b/platform/macos/CHANGELOG.md
@@ -1,5 +1,11 @@
# Changelog for Mapbox macOS SDK
+## master
+
+* Labels written in Arabic, Hebrew, and other scripts are written right-to-left. Arabic characters are correctly shaped. ([#6984](https://github.com/mapbox/mapbox-gl-native/pull/6984), [#7123](https://github.com/mapbox/mapbox-gl-native/pull/7123))
+* Improved the line wrapping behavior of point-placed labels written in Chinese, Japanese, and Yi. ([#6828](https://github.com/mapbox/mapbox-gl-native/pull/6828))
+* Fixed an issue where translucent point annotations along tile boundaries would be drawn darker than expected. ([#6832](https://github.com/mapbox/mapbox-gl-native/pull/6832))
+
## 0.3.0
### Packaging
diff --git a/platform/macos/bitrise.yml b/platform/macos/bitrise.yml
index 340d72e27c..2de6bce1fc 100644
--- a/platform/macos/bitrise.yml
+++ b/platform/macos/bitrise.yml
@@ -2,6 +2,8 @@ format_version: 1.1.0
default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git
trigger_map:
+- pattern: nightly-release
+ workflow: nightly-release
- pattern: "*"
is_pull_request_allowed: true
workflow: primary
@@ -78,3 +80,31 @@ workflows:
failed'
- icon_url: https://bitrise-public-content-production.s3.amazonaws.com/slack/bitrise-slack-icon-128.png
- icon_url_on_error: https://bitrise-public-content-production.s3.amazonaws.com/slack/bitrise-slack-error-icon-128.png
+ nightly-release:
+ steps:
+ - script:
+ title: Install Dependencies
+ inputs:
+ - content: |-
+ #!/bin/bash
+ set -eu -o pipefail
+ brew install cmake
+ - is_debug: 'yes'
+ - script:
+ title: Configure AWS-CLI
+ inputs:
+ - content: |-
+ #!/bin/bash
+ apt-get install -y python-pip python-dev build-essential
+ pip install awscli
+ - script:
+ title: Build package
+ inputs:
+ - content: |-
+ #!/bin/bash
+ set -eu -o pipefail
+ export BUILDTYPE=Release
+ export SYMBOLS=NO
+ make xpackage
+ CLOUDWATCH=true platform/macos/scripts/metrics.sh
+ - is_debug: 'yes'
diff --git a/platform/macos/config.cmake b/platform/macos/config.cmake
index 27bf555ec6..dab507d42a 100644
--- a/platform/macos/config.cmake
+++ b/platform/macos/config.cmake
@@ -1,13 +1,16 @@
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.10)
mason_use(glfw VERSION 3.2.1)
-mason_use(boost_libprogram_options VERSION 1.60.0)
+mason_use(boost_libprogram_options VERSION 1.62.0)
mason_use(gtest VERSION 1.7.0${MASON_CXXABI_SUFFIX})
mason_use(benchmark VERSION 1.0.0)
+mason_use(icu VERSION 58.1)
include(cmake/loop-darwin.cmake)
macro(mbgl_platform_core)
+ set_xcode_property(mbgl-core GCC_SYMBOLS_PRIVATE_EXTERN YES)
+
target_sources(mbgl-core
# File source
PRIVATE platform/darwin/src/http_file_source.mm
@@ -16,6 +19,10 @@ macro(mbgl_platform_core)
PRIVATE platform/default/local_file_source.cpp
PRIVATE platform/default/online_file_source.cpp
+ # Default styles
+ PRIVATE platform/default/mbgl/util/default_styles.hpp
+ PRIVATE platform/default/mbgl/util/default_styles.cpp
+
# Offline
PRIVATE platform/default/mbgl/storage/offline.cpp
PRIVATE platform/default/mbgl/storage/offline_database.cpp
@@ -26,32 +33,40 @@ macro(mbgl_platform_core)
PRIVATE platform/default/sqlite3.hpp
# Misc
- PRIVATE platform/darwin/src/log_nslog.mm
+ PRIVATE platform/darwin/mbgl/storage/reachability.h
+ PRIVATE platform/darwin/mbgl/storage/reachability.m
+ PRIVATE platform/darwin/src/logging_nslog.mm
PRIVATE platform/darwin/src/nsthread.mm
- PRIVATE platform/darwin/src/reachability.m
PRIVATE platform/darwin/src/string_nsstring.mm
+ PRIVATE platform/default/bidi.cpp
# Image handling
PRIVATE platform/darwin/src/image.mm
# Headless view
+ PRIVATE platform/default/mbgl/gl/headless_backend.cpp
+ PRIVATE platform/default/mbgl/gl/headless_backend.hpp
PRIVATE platform/darwin/src/headless_backend_cgl.cpp
- PRIVATE platform/default/headless_backend.cpp
- PRIVATE platform/default/headless_display.cpp
- PRIVATE platform/default/offscreen_view.cpp
+ PRIVATE platform/default/mbgl/gl/headless_display.hpp
+ PRIVATE platform/darwin/src/headless_display_cgl.cpp
+ PRIVATE platform/default/mbgl/gl/offscreen_view.cpp
+ PRIVATE platform/default/mbgl/gl/offscreen_view.hpp
# Thread pool
- PRIVATE platform/default/thread_pool.cpp
+ PRIVATE platform/default/mbgl/util/default_thread_pool.cpp
+ PRIVATE platform/default/mbgl/util/default_thread_pool.cpp
)
target_add_mason_package(mbgl-core PUBLIC geojson)
+ target_add_mason_package(mbgl-core PUBLIC icu)
target_compile_options(mbgl-core
PRIVATE -fobjc-arc
)
target_include_directories(mbgl-core
- PRIVATE platform/default
+ PUBLIC platform/darwin
+ PUBLIC platform/default
)
target_link_libraries(mbgl-core
@@ -70,6 +85,8 @@ endmacro()
macro(mbgl_platform_render)
+ set_xcode_property(mbgl-render GCC_SYMBOLS_PRIVATE_EXTERN YES)
+
target_link_libraries(mbgl-render
PRIVATE mbgl-loop
PRIVATE "-framework Foundation"
@@ -83,6 +100,8 @@ endmacro()
macro(mbgl_platform_offline)
+ set_xcode_property(mbgl-offline GCC_SYMBOLS_PRIVATE_EXTERN YES)
+
target_link_libraries(mbgl-offline
PRIVATE mbgl-loop
PRIVATE "-framework Foundation"
@@ -96,6 +115,8 @@ endmacro()
macro(mbgl_platform_test)
+ set_xcode_property(mbgl-test GCC_SYMBOLS_PRIVATE_EXTERN YES)
+
target_sources(mbgl-test
PRIVATE test/src/main.cpp
)
@@ -118,6 +139,8 @@ macro(mbgl_platform_test)
endmacro()
macro(mbgl_platform_benchmark)
+ set_xcode_property(mbgl-benchmark GCC_SYMBOLS_PRIVATE_EXTERN YES)
+
target_sources(mbgl-benchmark
PRIVATE benchmark/src/main.cpp
)
@@ -140,8 +163,11 @@ macro(mbgl_platform_benchmark)
endmacro()
macro(mbgl_platform_node)
+ set_xcode_property(mbgl-node GCC_SYMBOLS_PRIVATE_EXTERN YES)
+
target_link_libraries(mbgl-node
PRIVATE "-framework Foundation"
PRIVATE "-framework OpenGL"
+ PRIVATE "-Wl,-bind_at_load"
)
endmacro()
diff --git a/platform/macos/macos.xcodeproj/project.pbxproj b/platform/macos/macos.xcodeproj/project.pbxproj
index 5edb4429fb..106c370998 100644
--- a/platform/macos/macos.xcodeproj/project.pbxproj
+++ b/platform/macos/macos.xcodeproj/project.pbxproj
@@ -1535,6 +1535,7 @@
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_VERSION = A;
+ GCC_SYMBOLS_PRIVATE_EXTERN = YES;
HEADER_SEARCH_PATHS = (
"$(mbgl_core_INCLUDE_DIRECTORIES)",
"$(mbgl_loop_INCLUDE_DIRECTORIES)",
@@ -1560,11 +1561,14 @@
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
+ DEAD_CODE_STRIPPING = YES;
DEFINES_MODULE = YES;
+ DEPLOYMENT_POSTPROCESSING = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_VERSION = A;
+ GCC_SYMBOLS_PRIVATE_EXTERN = YES;
HEADER_SEARCH_PATHS = (
"$(mbgl_core_INCLUDE_DIRECTORIES)",
"$(mbgl_loop_INCLUDE_DIRECTORIES)",
@@ -1579,6 +1583,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.mapbox.MapboxGL;
PRODUCT_NAME = Mapbox;
SKIP_INSTALL = YES;
+ STRIP_STYLE = "non-global";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
diff --git a/platform/macos/macos.xcodeproj/xcshareddata/xcschemes/CI.xcscheme b/platform/macos/macos.xcodeproj/xcshareddata/xcschemes/CI.xcscheme
index eca3be86dc..a049928fdd 100644
--- a/platform/macos/macos.xcodeproj/xcshareddata/xcschemes/CI.xcscheme
+++ b/platform/macos/macos.xcodeproj/xcshareddata/xcschemes/CI.xcscheme
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
- LastUpgradeVersion = "0800"
+ LastUpgradeVersion = "0810"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
diff --git a/platform/macos/macos.xcodeproj/xcshareddata/xcschemes/dynamic.xcscheme b/platform/macos/macos.xcodeproj/xcshareddata/xcschemes/dynamic.xcscheme
index 189596d94f..95351f7f04 100644
--- a/platform/macos/macos.xcodeproj/xcshareddata/xcschemes/dynamic.xcscheme
+++ b/platform/macos/macos.xcodeproj/xcshareddata/xcschemes/dynamic.xcscheme
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
- LastUpgradeVersion = "0800"
+ LastUpgradeVersion = "0810"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
diff --git a/platform/macos/macos.xcodeproj/xcshareddata/xcschemes/macosapp.xcscheme b/platform/macos/macos.xcodeproj/xcshareddata/xcschemes/macosapp.xcscheme
index 0867fc0c23..a58ef5c9cf 100644
--- a/platform/macos/macos.xcodeproj/xcshareddata/xcschemes/macosapp.xcscheme
+++ b/platform/macos/macos.xcodeproj/xcshareddata/xcschemes/macosapp.xcscheme
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
- LastUpgradeVersion = "0800"
+ LastUpgradeVersion = "0810"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
diff --git a/platform/macos/scripts/executable.xcscheme b/platform/macos/scripts/executable.xcscheme
index 4353aad846..c6a8d04d30 100644
--- a/platform/macos/scripts/executable.xcscheme
+++ b/platform/macos/scripts/executable.xcscheme
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
- LastUpgradeVersion = "0730"
+ LastUpgradeVersion = "0810"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -46,7 +46,8 @@
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
- useCustomWorkingDirectory = "NO"
+ useCustomWorkingDirectory = "YES"
+ customWorkingDirectory = "{{WORKING_DIRECTORY}}"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
@@ -81,7 +82,8 @@
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
- useCustomWorkingDirectory = "NO"
+ useCustomWorkingDirectory = "YES"
+ customWorkingDirectory = "{{WORKING_DIRECTORY}}"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
diff --git a/platform/macos/scripts/library.xcscheme b/platform/macos/scripts/library.xcscheme
index 012bc900c2..5472d3c821 100644
--- a/platform/macos/scripts/library.xcscheme
+++ b/platform/macos/scripts/library.xcscheme
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
- LastUpgradeVersion = "0730"
+ LastUpgradeVersion = "0810"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
diff --git a/platform/macos/scripts/metrics.sh b/platform/macos/scripts/metrics.sh
new file mode 100755
index 0000000000..56790fc1e6
--- /dev/null
+++ b/platform/macos/scripts/metrics.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+
+set -e
+set -o pipefail
+
+# Track individual architectures
+scripts/log_binary_size.sh "build/macos/pkg/Mapbox.framework/Versions/Current/Mapbox" "Platform=macOS,Arch=x86_64"
diff --git a/platform/macos/scripts/node.xcscheme b/platform/macos/scripts/node.xcscheme
index 361ed58a37..6f541deca3 100644
--- a/platform/macos/scripts/node.xcscheme
+++ b/platform/macos/scripts/node.xcscheme
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
- LastUpgradeVersion = "0730"
+ LastUpgradeVersion = "0810"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -76,7 +76,8 @@
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
- useCustomWorkingDirectory = "NO"
+ useCustomWorkingDirectory = "YES"
+ customWorkingDirectory = "{{WORKING_DIRECTORY}}"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
diff --git a/platform/macos/src/MGLMapView.mm b/platform/macos/src/MGLMapView.mm
index bf31daffad..92aa0a6c6b 100644
--- a/platform/macos/src/MGLMapView.mm
+++ b/platform/macos/src/MGLMapView.mm
@@ -19,13 +19,12 @@
#import "MGLAnnotationImage.h"
#import "MGLMapViewDelegate.h"
-#import <mbgl/mbgl.hpp>
+#import <mbgl/map/view.hpp>
#import <mbgl/annotation/annotation.hpp>
#import <mbgl/map/camera.hpp>
-#import <mbgl/platform/darwin/reachability.h>
-#import <mbgl/platform/default/thread_pool.hpp>
+#import <mbgl/storage/reachability.h>
+#import <mbgl/util/default_thread_pool.hpp>
#import <mbgl/gl/extension.hpp>
-#import <mbgl/gl/gl.hpp>
#import <mbgl/gl/context.hpp>
#import <mbgl/map/backend.hpp>
#import <mbgl/sprite/sprite_image.hpp>
@@ -260,10 +259,8 @@ public:
mbgl::DefaultFileSource* mbglFileSource = [MGLOfflineStorage sharedOfflineStorage].mbglFileSource;
- const std::array<uint16_t, 2> size = {{ static_cast<uint16_t>(self.bounds.size.width),
- static_cast<uint16_t>(self.bounds.size.height) }};
_mbglThreadPool = new mbgl::ThreadPool(4);
- _mbglMap = new mbgl::Map(*_mbglView, size, [NSScreen mainScreen].backingScaleFactor, *mbglFileSource, *_mbglThreadPool, mbgl::MapMode::Continuous, mbgl::GLContextMode::Unique, mbgl::ConstrainMode::None, mbgl::ViewportMode::Default);
+ _mbglMap = new mbgl::Map(*_mbglView, self.size, [NSScreen mainScreen].backingScaleFactor, *mbglFileSource, *_mbglThreadPool, mbgl::MapMode::Continuous, mbgl::GLContextMode::Unique, mbgl::ConstrainMode::None, mbgl::ViewportMode::Default);
[self validateTileCacheSize];
// Install the OpenGL layer. Interface Builder’s synchronous drawing means
@@ -303,6 +300,16 @@ public:
_pendingLongitude = NAN;
}
+- (mbgl::Size)size {
+ return { static_cast<uint32_t>(self.bounds.size.width),
+ static_cast<uint32_t>(self.bounds.size.height) };
+}
+
+- (mbgl::Size)framebufferSize {
+ NSRect bounds = [self convertRectToBacking:self.bounds];
+ return { static_cast<uint32_t>(bounds.size.width), static_cast<uint32_t>(bounds.size.height) };
+}
+
/// Adds zoom controls to the lower-right corner.
- (void)installZoomControls {
_zoomControls = [[NSSegmentedControl alloc] initWithFrame:NSZeroRect];
@@ -671,8 +678,7 @@ public:
[self validateTileCacheSize];
}
if (!_isTargetingInterfaceBuilder) {
- _mbglMap->setSize({{ static_cast<uint16_t>(self.bounds.size.width),
- static_cast<uint16_t>(self.bounds.size.height) }});
+ _mbglMap->setSize(self.size);
}
}
@@ -2679,14 +2685,14 @@ public:
}
mbgl::gl::value::Viewport::Type getViewport() const {
- return { 0, 0, static_cast<uint16_t>(nativeView.bounds.size.width),
- static_cast<uint16_t>(nativeView.bounds.size.height) };
+ return { 0, 0, nativeView.framebufferSize };
}
void updateViewBinding() {
fbo = mbgl::gl::value::BindFramebuffer::Get();
getContext().bindFramebuffer.setCurrentValue(fbo);
getContext().viewport.setCurrentValue(getViewport());
+ assert(mbgl::gl::value::Viewport::Get() == getContext().viewport.getCurrentValue());
}
void bind() override {
@@ -2695,23 +2701,7 @@ public:
}
mbgl::PremultipliedImage readStillImage() {
- NSRect bounds = [nativeView convertRectToBacking:nativeView.bounds];
- const uint16_t width = bounds.size.width;
- const uint16_t height = bounds.size.height;
- mbgl::PremultipliedImage image{ width, height };
- MBGL_CHECK_ERROR(
- glReadPixels(0, 0, width, height, 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();
- for (int i = 0, j = height - 1; i < j; i++, j--) {
- std::memcpy(tmp.get(), rgba + i * stride, stride);
- std::memcpy(rgba + i * stride, rgba + j * stride, stride);
- std::memcpy(rgba + j * stride, tmp.get(), stride);
- }
-
- return image;
+ return getContext().readFramebuffer<mbgl::PremultipliedImage>(nativeView.framebufferSize);
}
private:
diff --git a/platform/macos/src/MGLMapView_Private.h b/platform/macos/src/MGLMapView_Private.h
index f0a61773a9..0980252fb5 100644
--- a/platform/macos/src/MGLMapView_Private.h
+++ b/platform/macos/src/MGLMapView_Private.h
@@ -1,6 +1,6 @@
#import "MGLMapView.h"
-#import <mbgl/mbgl.hpp>
+#include <mbgl/map/map.hpp>
@interface MGLMapView (Private)
diff --git a/platform/macos/src/MGLOpenGLLayer.mm b/platform/macos/src/MGLOpenGLLayer.mm
index e8fa521351..296e30179b 100644
--- a/platform/macos/src/MGLOpenGLLayer.mm
+++ b/platform/macos/src/MGLOpenGLLayer.mm
@@ -2,8 +2,6 @@
#import "MGLMapView_Private.h"
-#import <mbgl/gl/gl.hpp>
-
@implementation MGLOpenGLLayer
- (MGLMapView *)mapView {
diff --git a/platform/macos/src/NSImage+MGLAdditions.mm b/platform/macos/src/NSImage+MGLAdditions.mm
index 9036ab24ae..72ddec83f7 100644
--- a/platform/macos/src/NSImage+MGLAdditions.mm
+++ b/platform/macos/src/NSImage+MGLAdditions.mm
@@ -21,8 +21,8 @@
NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:{ NSZeroPoint, self.size }];
[self unlockFocus];
- mbgl::PremultipliedImage cPremultipliedImage(rep.pixelsWide, rep.pixelsHigh);
- std::copy(rep.bitmapData, rep.bitmapData + cPremultipliedImage.size(), cPremultipliedImage.data.get());
+ mbgl::PremultipliedImage cPremultipliedImage({ static_cast<uint32_t>(rep.pixelsWide), static_cast<uint32_t>(rep.pixelsHigh) });
+ std::copy(rep.bitmapData, rep.bitmapData + cPremultipliedImage.bytes(), cPremultipliedImage.data.get());
return std::make_unique<mbgl::SpriteImage>(std::move(cPremultipliedImage),
(float)(rep.pixelsWide / self.size.width),
[self isTemplate]);
diff --git a/platform/node/CHANGELOG.md b/platform/node/CHANGELOG.md
index d64aa5238c..aabed907e1 100644
--- a/platform/node/CHANGELOG.md
+++ b/platform/node/CHANGELOG.md
@@ -1,3 +1,17 @@
+# 3.4.2 - November 15, 2016
+
+- Switches back to publishing Linux binaries with GLX, to eliminate a runtime dependency on `libOSMesa.so.8` and enable dynamically linking against `libGL.so` provided by an alternate implementation, such as the NVIDIA proproetary drivers ([#7503](https://github.com/mapbox/mapbox-gl-native/pull/7053))
+
+# 3.4.1 - November 10, 2016
+
+- Skips assigning clip IDs to tiles that won't be rendered, mitigating a `stencil mask overflow` error ([#6871](https://github.com/mapbox/mapbox-gl-native/pull/6871))
+- Fixes camera logic to avoid unnecessary or redundant setting of camera options ([#6990](https://github.com/mapbox/mapbox-gl-native/pull/6990))
+
+# 3.4.0 - November 2, 2016
+
+- Fixes Bitrise configuration to automatically publish macOS binaries ([#6789](https://github.com/mapbox/mapbox-gl-native/pull/6789))
+- Switches from using individual thread pools for each `mbgl::Map` object to sharing the built-in Node.js thread pool for NodeMap implementations ([#6687](https://github.com/mapbox/mapbox-gl-native/pull/6687))
+
# 3.3.3 - September 6, 2016
- Switches to using a NodeRequest member function (with a JavaScript shim in front to preserve the API) instead of a new `v8::Context` to avoid a memory leak ([#5704](https://github.com/mapbox/mapbox-gl-native/pull/5704))
diff --git a/platform/node/bitrise.yml b/platform/node/bitrise.yml
index 998e97301b..0323f944a3 100644
--- a/platform/node/bitrise.yml
+++ b/platform/node/bitrise.yml
@@ -57,6 +57,7 @@ workflows:
#!/bin/bash
set -eu -o pipefail
make test-node || envman add --key RESULT --value $?
+ ./platform/node/scripts/after_script.sh ${BITRISE_BUILD_NUMBER}
- script:
title: Run publish script
run_if: '{{enveq "SKIPCI" "false"}}'
@@ -64,7 +65,7 @@ workflows:
- content: |-
#!/bin/bash
set -eu -o pipefail
- ./platform/node/scripts/after_script.sh ${BITRISE_BUILD_NUMBER}
+ ./platform/node/scripts/after_success.sh
exit ${RESULT:-0}
- slack:
title: Post to Slack
diff --git a/platform/node/scripts/after_script.sh b/platform/node/scripts/after_script.sh
index c805e453a2..4228d13dfe 100755
--- a/platform/node/scripts/after_script.sh
+++ b/platform/node/scripts/after_script.sh
@@ -5,19 +5,10 @@ set -o pipefail
JOB=$1
-if [[ -n ${PUBLISH:-} ]]; then
- if [[ "${BUILDTYPE}" == "Debug" ]]; then
- echo "Please run this script in release mode (BUILDTYPE=Release)."
- exit 1
- else
- ./node_modules/.bin/node-pre-gyp package publish info
- fi
-else
- if [ ! -z "${AWS_ACCESS_KEY_ID}" ] && [ ! -z "${AWS_SECRET_ACCESS_KEY}" ] ; then
- gzip --stdout node_modules/mapbox-gl-test-suite/render-tests/index.html | \
- aws s3 cp --acl public-read --content-encoding gzip --content-type text/html \
- - s3://mapbox/mapbox-gl-native/render-tests/$JOB/index.html
+if [ ! -z "${AWS_ACCESS_KEY_ID}" ] && [ ! -z "${AWS_SECRET_ACCESS_KEY}" ] ; then
+ gzip --stdout node_modules/mapbox-gl-test-suite/render-tests/index.html | \
+ aws s3 cp --acl public-read --content-encoding gzip --content-type text/html \
+ - s3://mapbox/mapbox-gl-native/render-tests/$JOB/index.html
- echo http://mapbox.s3.amazonaws.com/mapbox-gl-native/render-tests/$JOB/index.html
- fi
+ echo http://mapbox.s3.amazonaws.com/mapbox-gl-native/render-tests/$JOB/index.html
fi
diff --git a/platform/node/scripts/after_success.sh b/platform/node/scripts/after_success.sh
new file mode 100755
index 0000000000..7ef8f53545
--- /dev/null
+++ b/platform/node/scripts/after_success.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+set -e
+set -o pipefail
+
+if [[ -n ${PUBLISH:-} ]]; then
+ if [[ "${BUILDTYPE}" == "Debug" ]]; then
+ echo "Please run this script in release mode (BUILDTYPE=Release)."
+ exit 1
+ else
+ ./node_modules/.bin/node-pre-gyp package publish info
+ fi
+fi
diff --git a/platform/node/src/node_log.cpp b/platform/node/src/node_logging.cpp
index 0a97ebce36..5e7326e90a 100644
--- a/platform/node/src/node_log.cpp
+++ b/platform/node/src/node_logging.cpp
@@ -1,4 +1,4 @@
-#include "node_log.hpp"
+#include "node_logging.hpp"
#include <mbgl/util/enum.hpp>
diff --git a/platform/node/src/node_log.hpp b/platform/node/src/node_logging.hpp
index a19c61284b..a12603ba6e 100644
--- a/platform/node/src/node_log.hpp
+++ b/platform/node/src/node_logging.hpp
@@ -2,7 +2,7 @@
#include "util/async_queue.hpp"
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
diff --git a/platform/node/src/node_map.cpp b/platform/node/src/node_map.cpp
index 671bf3e0fd..acf83eef66 100644
--- a/platform/node/src/node_map.cpp
+++ b/platform/node/src/node_map.cpp
@@ -4,7 +4,7 @@
#include "node_conversion.hpp"
#include "node_geojson.hpp"
-#include <mbgl/platform/default/headless_display.hpp>
+#include <mbgl/gl/headless_display.hpp>
#include <mbgl/util/exception.hpp>
#include <mbgl/style/conversion/source.hpp>
#include <mbgl/style/conversion/layer.hpp>
@@ -62,7 +62,9 @@ void NodeMap::Init(v8::Local<v8::Object> target) {
Nan::SetPrototypeMethod(tpl, "setPaintProperty", SetPaintProperty);
Nan::SetPrototypeMethod(tpl, "setFilter", SetFilter);
Nan::SetPrototypeMethod(tpl, "setCenter", SetCenter);
+ Nan::SetPrototypeMethod(tpl, "setZoom", SetZoom);
Nan::SetPrototypeMethod(tpl, "setBearing", SetBearing);
+ Nan::SetPrototypeMethod(tpl, "setPitch", SetPitch);
Nan::SetPrototypeMethod(tpl, "dumpDebugLogs", DumpDebugLogs);
Nan::SetPrototypeMethod(tpl, "queryRenderedFeatures", QueryRenderedFeatures);
@@ -356,20 +358,39 @@ void NodeMap::Render(const Nan::FunctionCallbackInfo<v8::Value>& info) {
}
void NodeMap::startRender(NodeMap::RenderOptions options) {
- map->setSize(std::array<uint16_t, 2>{{ static_cast<uint16_t>(options.width),
- static_cast<uint16_t>(options.height) }});
+ map->setSize({ options.width, options.height });
- const std::array<uint16_t, 2> fbSize{{ static_cast<uint16_t>(options.width * pixelRatio),
- static_cast<uint16_t>(options.height * pixelRatio) }};
- if (!view || view->getSize() != fbSize) {
+ const mbgl::Size fbSize{ static_cast<uint32_t>(options.width * pixelRatio),
+ static_cast<uint32_t>(options.height * pixelRatio) };
+ if (!view || view->size != fbSize) {
view.reset();
view = std::make_unique<mbgl::OffscreenView>(backend.getContext(), fbSize);
}
- map->setClasses(options.classes);
- map->setLatLngZoom(mbgl::LatLng(options.latitude, options.longitude), options.zoom);
- map->setBearing(options.bearing);
- map->setPitch(options.pitch);
- map->setDebug(options.debugOptions);
+
+ if (map->getClasses() != options.classes) {
+ map->setClasses(options.classes);
+ }
+
+ if (map->getZoom() != options.zoom) {
+ map->setZoom(options.zoom);
+ }
+
+ mbgl::LatLng latLng(options.latitude, options.longitude);
+ if (map->getLatLng() != latLng) {
+ map->setLatLng(latLng);
+ }
+
+ if (map->getBearing() != options.bearing) {
+ map->setBearing(options.bearing);
+ }
+
+ if (map->getPitch() != options.pitch) {
+ map->setPitch(options.pitch);
+ }
+
+ if (map->getDebug() != options.debugOptions) {
+ map->setDebug(options.debugOptions);
+ }
map->renderStill(*view, [this](const std::exception_ptr eptr) {
if (eptr) {
@@ -430,7 +451,7 @@ void NodeMap::renderFinished() {
cb->Call(1, argv);
} else if (img.data) {
v8::Local<v8::Object> pixels = Nan::NewBuffer(
- reinterpret_cast<char *>(img.data.get()), img.size(),
+ reinterpret_cast<char *>(img.data.get()), img.bytes(),
// Retain the data until the buffer is deleted.
[](char *, void * hint) {
delete [] reinterpret_cast<uint8_t*>(hint);
@@ -706,6 +727,23 @@ void NodeMap::SetCenter(const Nan::FunctionCallbackInfo<v8::Value>& info) {
info.GetReturnValue().SetUndefined();
}
+void NodeMap::SetZoom(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->setZoom(info[0]->NumberValue());
+ } 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());
@@ -723,6 +761,23 @@ void NodeMap::SetBearing(const Nan::FunctionCallbackInfo<v8::Value>& info) {
info.GetReturnValue().SetUndefined();
}
+void NodeMap::SetPitch(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->setPitch(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());
@@ -790,7 +845,7 @@ NodeMap::NodeMap(v8::Local<v8::Object> options)
}()),
backend(sharedDisplay()),
map(std::make_unique<mbgl::Map>(backend,
- std::array<uint16_t, 2>{{ 256, 256 }},
+ mbgl::Size{ 256, 256 },
pixelRatio,
*this,
threadpool,
diff --git a/platform/node/src/node_map.hpp b/platform/node/src/node_map.hpp
index 45de2733cc..c68f543b02 100644
--- a/platform/node/src/node_map.hpp
+++ b/platform/node/src/node_map.hpp
@@ -4,8 +4,8 @@
#include <mbgl/map/map.hpp>
#include <mbgl/storage/file_source.hpp>
-#include <mbgl/platform/default/headless_backend.hpp>
-#include <mbgl/platform/default/offscreen_view.hpp>
+#include <mbgl/gl/headless_backend.hpp>
+#include <mbgl/gl/offscreen_view.hpp>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
@@ -41,7 +41,9 @@ public:
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 SetZoom(const Nan::FunctionCallbackInfo<v8::Value>&);
static void SetBearing(const Nan::FunctionCallbackInfo<v8::Value>&);
+ static void SetPitch(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/src/node_mapbox_gl_native.cpp b/platform/node/src/node_mapbox_gl_native.cpp
index 042def9fdd..cdcc982220 100644
--- a/platform/node/src/node_mapbox_gl_native.cpp
+++ b/platform/node/src/node_mapbox_gl_native.cpp
@@ -8,7 +8,7 @@
#include <mbgl/util/run_loop.hpp>
#include "node_map.hpp"
-#include "node_log.hpp"
+#include "node_logging.hpp"
#include "node_request.hpp"
void RegisterModule(v8::Local<v8::Object> target, v8::Local<v8::Object> module) {
diff --git a/platform/node/test/fixtures/zoom-center/expected.png b/platform/node/test/fixtures/zoom-center/expected.png
new file mode 100644
index 0000000000..93365c04d2
--- /dev/null
+++ b/platform/node/test/fixtures/zoom-center/expected.png
Binary files differ
diff --git a/platform/node/test/js/map.test.js b/platform/node/test/js/map.test.js
index 7321572637..e3b287f68f 100644
--- a/platform/node/test/js/map.test.js
+++ b/platform/node/test/js/map.test.js
@@ -115,7 +115,9 @@ test('Map', function(t) {
'setPaintProperty',
'setFilter',
'setCenter',
+ 'setZoom',
'setBearing',
+ 'setPitch',
'dumpDebugLogs',
'queryRenderedFeatures'
]);
@@ -369,6 +371,48 @@ test('Map', function(t) {
map.release();
t.end();
});
+
+ // This can't be tested with a test-suite render test because zoom and center
+ // are set via a different code path when included as style properties.
+ t.test('sets zoom before center', function(t) {
+ var map = new mbgl.Map(options);
+ map.load({
+ "version": 8,
+ "sources": {
+ "geojson": {
+ "type": "geojson",
+ "data": {
+ "type": "Point",
+ "coordinates": [
+ 18.05489,
+ 59.32744
+ ]
+ }
+ }
+ },
+ "layers": [
+ {
+ "id": "circle",
+ "type": "circle",
+ "source": "geojson",
+ "paint": {
+ "circle-color": "red"
+ }
+ }
+ ]
+ });
+ map.render({width: 400, height: 400, zoom: 5, center: [18.05489, 59.32744]}, function(err, actual) {
+ t.error(err);
+
+ var PNG = require('pngjs').PNG;
+ var pixelmatch = require('pixelmatch');
+ var expected = PNG.sync.read(
+ fs.readFileSync(path.join(__dirname, '../fixtures/zoom-center/expected.png'))).data;
+ var numPixels = pixelmatch(actual, expected, undefined, 400, 400, { threshold: 0.13 });
+ t.equal(numPixels, 0);
+ t.end();
+ });
+ })
});
t.test('request callback', function (t) {
diff --git a/platform/node/test/suite_implementation.js b/platform/node/test/suite_implementation.js
index bde8acde18..3abf4136c4 100644
--- a/platform/node/test/suite_implementation.js
+++ b/platform/node/test/suite_implementation.js
@@ -30,16 +30,17 @@ module.exports = function (style, options, callback) {
callback(new Error('timed out after 20 seconds'));
}, 20000);
- options.center = style.center;
- options.zoom = style.zoom;
- options.bearing = style.bearing;
- options.pitch = style.pitch;
options.debug = {
tileBorders: options.debug,
collision: options.collisionDebug,
overdraw: options.showOverdrawInspector,
};
+ options.center = style.center || [0, 0];
+ options.zoom = style.zoom || 0;
+ options.bearing = style.bearing || 0;
+ options.pitch = style.pitch || 0;
+
map.load(style);
applyOperations(options.operations, function() {
@@ -60,16 +61,22 @@ module.exports = function (style, options, callback) {
callback();
} else if (operation[0] === 'wait') {
- var wait = function() {
- if (map.loaded()) {
- applyOperations(operations.slice(1), callback);
- } else {
- map.render(options, wait);
- }
- };
- wait();
+ map.render(options, function () {
+ applyOperations(operations.slice(1), callback);
+ });
} else {
+ // Ensure that the next `map.render(options)` does not overwrite this change.
+ if (operation[0] === 'setCenter') {
+ options.center = operation[1];
+ } else if (operation[0] === 'setZoom') {
+ options.zoom = operation[1];
+ } else if (operation[0] === 'setBearing') {
+ options.bearing = operation[1];
+ } else if (operation[0] === 'setPitch') {
+ options.pitch = operation[1];
+ }
+
map[operation[0]].apply(map, operation.slice(1));
applyOperations(operations.slice(1), callback);
}
diff --git a/platform/qt/app/mapwindow.cpp b/platform/qt/app/mapwindow.cpp
index e8e3a13489..28a3f1df4b 100644
--- a/platform/qt/app/mapwindow.cpp
+++ b/platform/qt/app/mapwindow.cpp
@@ -17,44 +17,30 @@ int kAnimationDuration = 10000;
MapWindow::MapWindow(const QMapboxGLSettings &settings)
- : m_map(nullptr, settings, size(), pixelRatio())
- , m_bearingAnimation(&m_map, "bearing")
- , m_zoomAnimation(&m_map, "zoom")
+ : m_settings(settings)
{
- connect(&m_map, SIGNAL(needsRendering()), this, SLOT(updateGL()));
-
- // Set default location to Helsinki.
- m_map.setCoordinateZoom(QMapbox::Coordinate(60.170448, 24.942046), 14);
-
- QString styleUrl = qgetenv("MAPBOX_STYLE_URL");
- if (styleUrl.isEmpty()) {
- changeStyle();
- } else {
- m_map.setStyleUrl(styleUrl);
- setWindowTitle(QString("Mapbox GL: ") + styleUrl);
- }
-
- connect(&m_zoomAnimation, SIGNAL(finished()), this, SLOT(animationFinished()));
- connect(&m_zoomAnimation, SIGNAL(valueChanged(const QVariant&)), this, SLOT(animationValueChanged()));
-
setWindowIcon(QIcon(":icon.png"));
}
void MapWindow::selfTest()
{
- m_bearingAnimation.setDuration(kAnimationDuration);
- m_bearingAnimation.setEndValue(m_map.bearing() + 360 * 4);
- m_bearingAnimation.start();
+ if (m_bearingAnimation) {
+ m_bearingAnimation->setDuration(kAnimationDuration);
+ m_bearingAnimation->setEndValue(m_map->bearing() + 360 * 4);
+ m_bearingAnimation->start();
+ }
- m_zoomAnimation.setDuration(kAnimationDuration);
- m_zoomAnimation.setEndValue(m_map.zoom() + 3);
- m_zoomAnimation.start();
+ if (m_zoomAnimation) {
+ m_zoomAnimation->setDuration(kAnimationDuration);
+ m_zoomAnimation->setEndValue(m_map->zoom() + 3);
+ m_zoomAnimation->start();
+ }
}
qreal MapWindow::pixelRatio() {
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
+#if QT_VERSION >= 0x050600
return devicePixelRatioF();
-#elif (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+#elif QT_VERSION >= 0x050000
return devicePixelRatio();
#else
return 1;
@@ -81,7 +67,7 @@ void MapWindow::changeStyle()
auto& styles = QMapbox::defaultStyles();
- m_map.setStyleUrl(styles[currentStyleIndex].first);
+ m_map->setStyleUrl(styles[currentStyleIndex].first);
setWindowTitle(QString("Mapbox GL: ") + styles[currentStyleIndex].second);
if (++currentStyleIndex == styles.size()) {
@@ -113,81 +99,81 @@ void MapWindow::keyPressEvent(QKeyEvent *ev)
QVariantMap routeSource;
routeSource["type"] = "geojson";
routeSource["data"] = geojson.readAll();
- m_map.addSource("routeSource", routeSource);
+ m_map->addSource("routeSource", routeSource);
// The route case, painted before the route
QVariantMap routeCase;
routeCase["id"] = "routeCase";
routeCase["type"] = "line";
routeCase["source"] = "routeSource";
- m_map.addLayer(routeCase);
+ m_map->addLayer(routeCase);
- m_map.setPaintProperty("routeCase", "line-color", QColor("white"));
- m_map.setPaintProperty("routeCase", "line-width", 20.0);
- m_map.setLayoutProperty("routeCase", "line-join", "round");
- m_map.setLayoutProperty("routeCase", "line-cap", "round");
+ m_map->setPaintProperty("routeCase", "line-color", QColor("white"));
+ m_map->setPaintProperty("routeCase", "line-width", 20.0);
+ m_map->setLayoutProperty("routeCase", "line-join", "round");
+ m_map->setLayoutProperty("routeCase", "line-cap", "round");
// The route, painted on top of the route case
QVariantMap route;
route["id"] = "route";
route["type"] = "line";
route["source"] = "routeSource";
- m_map.addLayer(route);
+ m_map->addLayer(route);
- m_map.setPaintProperty("route", "line-color", QColor("blue"));
- m_map.setPaintProperty("route", "line-width", 8.0);
- m_map.setLayoutProperty("route", "line-join", "round");
- m_map.setLayoutProperty("route", "line-cap", "round");
+ m_map->setPaintProperty("route", "line-color", QColor("blue"));
+ m_map->setPaintProperty("route", "line-width", 8.0);
+ m_map->setLayoutProperty("route", "line-join", "round");
+ m_map->setLayoutProperty("route", "line-cap", "round");
// Markers at the beginning and end of the route
- m_map.addImage("label-arrow", QImage(":label-arrow.svg"));
- m_map.addImage("label-background", QImage(":label-background.svg"));
+ m_map->addImage("label-arrow", QImage(":label-arrow.svg"));
+ m_map->addImage("label-background", QImage(":label-background.svg"));
QVariantMap makerArrow;
makerArrow["id"] = "makerArrow";
makerArrow["type"] = "symbol";
makerArrow["source"] = "routeSource";
- m_map.addLayer(makerArrow);
+ m_map->addLayer(makerArrow);
- m_map.setLayoutProperty("makerArrow", "icon-image", "label-arrow");
- m_map.setLayoutProperty("makerArrow", "icon-size", 0.5);
- m_map.setLayoutProperty("makerArrow", "icon-ignore-placement", true);
+ m_map->setLayoutProperty("makerArrow", "icon-image", "label-arrow");
+ m_map->setLayoutProperty("makerArrow", "icon-size", 0.5);
+ m_map->setLayoutProperty("makerArrow", "icon-ignore-placement", true);
QVariantList arrowOffset;
arrowOffset.append(0.0);
arrowOffset.append(-15.0);
- m_map.setLayoutProperty("makerArrow", "icon-offset", arrowOffset);
+ m_map->setLayoutProperty("makerArrow", "icon-offset", arrowOffset);
QVariantMap makerBackground;
makerBackground["id"] = "makerBackground";
makerBackground["type"] = "symbol";
makerBackground["source"] = "routeSource";
- m_map.addLayer(makerBackground);
-
- m_map.setLayoutProperty("makerBackground", "icon-image", "label-background");
- m_map.setLayoutProperty("makerBackground", "text-field", "{name}");
- m_map.setLayoutProperty("makerBackground", "icon-text-fit", "both");
- m_map.setLayoutProperty("makerBackground", "icon-ignore-placement", true);
- m_map.setLayoutProperty("makerBackground", "text-ignore-placement", true);
- m_map.setLayoutProperty("makerBackground", "text-anchor", "left");
- m_map.setLayoutProperty("makerBackground", "text-size", 16.0);
- m_map.setLayoutProperty("makerBackground", "text-padding", 0.0);
- m_map.setLayoutProperty("makerBackground", "text-line-height", 1.0);
- m_map.setLayoutProperty("makerBackground", "text-max-width", 8.0);
+ m_map->addLayer(makerBackground);
+
+ m_map->setLayoutProperty("makerBackground", "icon-image", "label-background");
+ m_map->setLayoutProperty("makerBackground", "text-field", "{name}");
+ m_map->setLayoutProperty("makerBackground", "icon-text-fit", "both");
+ m_map->setLayoutProperty("makerBackground", "icon-ignore-placement", true);
+ m_map->setLayoutProperty("makerBackground", "text-ignore-placement", true);
+ m_map->setLayoutProperty("makerBackground", "text-anchor", "left");
+ m_map->setLayoutProperty("makerBackground", "text-size", 16.0);
+ m_map->setLayoutProperty("makerBackground", "text-padding", 0.0);
+ m_map->setLayoutProperty("makerBackground", "text-line-height", 1.0);
+ m_map->setLayoutProperty("makerBackground", "text-max-width", 8.0);
QVariantList iconTextFitPadding;
iconTextFitPadding.append(15.0);
iconTextFitPadding.append(10.0);
iconTextFitPadding.append(15.0);
iconTextFitPadding.append(10.0);
- m_map.setLayoutProperty("makerBackground", "icon-text-fit-padding", iconTextFitPadding);
+ m_map->setLayoutProperty("makerBackground", "icon-text-fit-padding", iconTextFitPadding);
QVariantList backgroundOffset;
backgroundOffset.append(-0.5);
backgroundOffset.append(-1.5);
- m_map.setLayoutProperty("makerBackground", "text-offset", backgroundOffset);
+ m_map->setLayoutProperty("makerBackground", "text-offset", backgroundOffset);
- m_map.setPaintProperty("makerBackground", "text-color", QColor("white"));
+ m_map->setPaintProperty("makerBackground", "text-color", QColor("white"));
QVariantList filterExpression;
filterExpression.append("==");
@@ -197,29 +183,29 @@ void MapWindow::keyPressEvent(QKeyEvent *ev)
QVariantList filter;
filter.append(filterExpression);
- m_map.setFilter("makerArrow", filter);
- m_map.setFilter("makerBackground", filter);
+ m_map->setFilter("makerArrow", filter);
+ m_map->setFilter("makerBackground", filter);
// Tilt the labels when tilting the map and make them larger
- m_map.setLayoutProperty("road-label-large", "text-size", 30.0);
- m_map.setLayoutProperty("road-label-large", "text-pitch-alignment", "viewport");
+ m_map->setLayoutProperty("road-label-large", "text-size", 30.0);
+ m_map->setLayoutProperty("road-label-large", "text-pitch-alignment", "viewport");
- m_map.setLayoutProperty("road-label-medium", "text-size", 30.0);
- m_map.setLayoutProperty("road-label-medium", "text-pitch-alignment", "viewport");
+ m_map->setLayoutProperty("road-label-medium", "text-size", 30.0);
+ m_map->setLayoutProperty("road-label-medium", "text-pitch-alignment", "viewport");
- m_map.setLayoutProperty("road-label-small", "text-pitch-alignment", "viewport");
- m_map.setLayoutProperty("road-label-small", "text-size", 30.0);
+ m_map->setLayoutProperty("road-label-small", "text-pitch-alignment", "viewport");
+ m_map->setLayoutProperty("road-label-small", "text-size", 30.0);
}
break;
case Qt::Key_Tab:
- m_map.cycleDebugOptions();
+ m_map->cycleDebugOptions();
break;
case Qt::Key_R: {
- m_map.setTransitionOptions(transition);
- if (m_map.hasClass("night")) {
- m_map.removeClass("night");
+ m_map->setTransitionOptions(transition);
+ if (m_map->hasClass("night")) {
+ m_map->removeClass("night");
} else {
- m_map.addClass("night");
+ m_map->addClass("night");
}
} break;
default:
@@ -245,9 +231,9 @@ void MapWindow::mousePressEvent(QMouseEvent *ev)
if (ev->type() == QEvent::MouseButtonDblClick) {
if (ev->buttons() == Qt::LeftButton) {
- m_map.scaleBy(2.0, m_lastPos);
+ m_map->scaleBy(2.0, m_lastPos);
} else if (ev->buttons() == Qt::RightButton) {
- m_map.scaleBy(0.5, m_lastPos);
+ m_map->scaleBy(0.5, m_lastPos);
}
}
@@ -264,14 +250,14 @@ void MapWindow::mouseMoveEvent(QMouseEvent *ev)
if (!delta.isNull()) {
if (ev->buttons() == Qt::LeftButton && ev->modifiers() & Qt::ShiftModifier) {
- m_map.setPitch(m_map.pitch() - delta.y());
+ m_map->setPitch(m_map->pitch() - delta.y());
} else if (ev->buttons() == Qt::LeftButton) {
- m_map.moveBy(delta);
+ m_map->moveBy(delta);
} else if (ev->buttons() == Qt::RightButton) {
#if QT_VERSION < 0x050000
- m_map.rotateBy(m_lastPos, ev->posF());
+ m_map->rotateBy(m_lastPos, ev->posF());
#else
- m_map.rotateBy(m_lastPos, ev->localPos());
+ m_map->rotateBy(m_lastPos, ev->localPos());
#endif
}
}
@@ -295,29 +281,38 @@ void MapWindow::wheelEvent(QWheelEvent *ev)
factor = factor > -1 ? factor : 1 / factor;
}
- m_map.scaleBy(1 + factor, ev->pos());
+ m_map->scaleBy(1 + factor, ev->pos());
ev->accept();
}
void MapWindow::initializeGL()
{
QMapbox::initializeGLExtensions();
+
+ m_map.reset(new QMapboxGL(nullptr, m_settings, size(), pixelRatio()));
+ connect(m_map.data(), SIGNAL(needsRendering()), this, SLOT(update()));
+
+ // Set default location to Helsinki.
+ m_map->setCoordinateZoom(QMapbox::Coordinate(60.170448, 24.942046), 14);
+
+ QString styleUrl = qgetenv("MAPBOX_STYLE_URL");
+ if (styleUrl.isEmpty()) {
+ changeStyle();
+ } else {
+ m_map->setStyleUrl(styleUrl);
+ setWindowTitle(QString("Mapbox GL: ") + styleUrl);
+ }
+
+ m_bearingAnimation = new QPropertyAnimation(m_map.data(), "bearing");
+ m_zoomAnimation = new QPropertyAnimation(m_map.data(), "zoom");
+
+ connect(m_zoomAnimation, SIGNAL(finished()), this, SLOT(animationFinished()));
+ connect(m_zoomAnimation, SIGNAL(valueChanged(const QVariant&)), this, SLOT(animationValueChanged()));
}
void MapWindow::paintGL()
{
m_frameDraws++;
-
- m_map.resize(size(), size() * pixelRatio());
-
-#if QT_VERSION < 0x050400 && defined(__APPLE__)
- // XXX GL framebuffer is valid only after first attempt of painting on
- // older versions of Qt on macOS.
- // See https://bugreports.qt.io/browse/QTBUG-36802 for details.
- static bool first = true;
- if (!first) m_map.render();
- first = false;
-#else
- m_map.render();
-#endif
+ m_map->resize(size(), size() * pixelRatio());
+ m_map->render();
}
diff --git a/platform/qt/app/mapwindow.hpp b/platform/qt/app/mapwindow.hpp
index a579a5bcc5..23880902d3 100644
--- a/platform/qt/app/mapwindow.hpp
+++ b/platform/qt/app/mapwindow.hpp
@@ -1,15 +1,29 @@
#ifndef MAPWINDOW_H
#define MAPWINDOW_H
-#include <QGLWidget>
#include <QMapboxGL>
+
+#include <QtGlobal>
+
+// XXX http://stackoverflow.com/questions/24899558/how-to-check-qt-version-to-include-different-header#comment59591604_29887388
+#if QT_VERSION >= 0x050400
+#include <QOpenGLWidget>
+#else
+#include <QGLWidget>
+#endif // QT_VERSION
+
#include <QPropertyAnimation>
+#include <QScopedPointer>
class QKeyEvent;
class QMouseEvent;
class QWheelEvent;
+#if QT_VERSION >= 0x050400
+class MapWindow : public QOpenGLWidget
+#else
class MapWindow : public QGLWidget
+#endif // QT_VERSION
{
Q_OBJECT
@@ -26,21 +40,23 @@ private:
void changeStyle();
qreal pixelRatio();
- // QGLWidget implementation.
+ // QWidget implementation.
void keyPressEvent(QKeyEvent *ev) final;
void mousePressEvent(QMouseEvent *ev) final;
void mouseMoveEvent(QMouseEvent *ev) final;
void wheelEvent(QWheelEvent *ev) final;
+ // Q{,Open}GLWidget implementation.
void initializeGL() final;
void paintGL() final;
QPointF m_lastPos;
- QMapboxGL m_map;
+ QMapboxGLSettings m_settings;
+ QScopedPointer<QMapboxGL> m_map;
- QPropertyAnimation m_bearingAnimation;
- QPropertyAnimation m_zoomAnimation;
+ QPropertyAnimation *m_bearingAnimation;
+ QPropertyAnimation *m_zoomAnimation;
unsigned m_animationTicks = 0;
unsigned m_frameDraws = 0;
diff --git a/platform/qt/config.cmake b/platform/qt/config.cmake
index ff86a0dee1..f2beedcfa2 100644
--- a/platform/qt/config.cmake
+++ b/platform/qt/config.cmake
@@ -9,13 +9,17 @@ if(NOT WITH_QT_DECODERS)
mason_use(webp VERSION 0.5.1)
endif()
+if(NOT WITH_QT_I18N)
+ mason_use(icu VERSION 58.1)
+endif()
+
macro(mbgl_platform_core)
target_sources(mbgl-core
${MBGL_QT_FILES}
)
target_include_directories(mbgl-core
- PRIVATE platform/default
+ PUBLIC platform/default
PRIVATE platform/qt/include
)
@@ -38,16 +42,27 @@ macro(mbgl_platform_core)
else()
add_definitions(-DQT_IMAGE_DECODERS)
endif()
+
+ if(NOT WITH_QT_I18N)
+ target_sources(mbgl-core PRIVATE platform/default/bidi.cpp)
+ target_add_mason_package(mbgl-core PRIVATE icu)
+ else()
+ target_sources(mbgl-core PRIVATE platform/qt/src/bidi.cpp)
+ endif()
+
endmacro()
macro(mbgl_platform_test)
target_sources(mbgl-test
PRIVATE test/src/main.cpp
- PRIVATE platform/qt/test/headless_backend_qt.cpp
PRIVATE platform/qt/test/qmapboxgl.cpp
- PRIVATE platform/default/headless_backend.cpp
- PRIVATE platform/default/headless_display.cpp
- PRIVATE platform/default/offscreen_view.cpp
+ PRIVATE platform/default/mbgl/gl/headless_backend.cpp
+ PRIVATE platform/default/mbgl/gl/headless_backend.hpp
+ PRIVATE platform/default/mbgl/gl/headless_display.cpp
+ PRIVATE platform/default/mbgl/gl/headless_display.hpp
+ PRIVATE platform/default/mbgl/gl/offscreen_view.cpp
+ PRIVATE platform/default/mbgl/gl/offscreen_view.hpp
+ PRIVATE platform/qt/test/headless_backend_qt.cpp
)
set_source_files_properties(
diff --git a/platform/qt/include/qmapboxgl.hpp b/platform/qt/include/qmapboxgl.hpp
index d3937ce083..8a77bbffab 100644
--- a/platform/qt/include/qmapboxgl.hpp
+++ b/platform/qt/include/qmapboxgl.hpp
@@ -186,6 +186,7 @@ public:
QMargins margins() const;
void addSource(const QString &sourceID, const QVariantMap& params);
+ void updateSource(const QString &sourceID, const QVariantMap& params);
void removeSource(const QString &sourceID);
void addImage(const QString &name, const QImage &sprite);
@@ -213,6 +214,7 @@ public slots:
signals:
void needsRendering();
void mapChanged(QMapbox::MapChange);
+ void copyrightsChanged(const QString &copyrightsHtml);
private:
Q_DISABLE_COPY(QMapboxGL)
diff --git a/platform/qt/qmlapp/main.qml b/platform/qt/qmlapp/main.qml
index fa157333d0..fd62193b42 100644
--- a/platform/qt/qmlapp/main.qml
+++ b/platform/qt/qmlapp/main.qml
@@ -30,10 +30,11 @@ ApplicationWindow {
property var fillColor: waterColorDialog.color
},
MapParameter {
+ id: source
property var type: "source"
property var name: "routeSource"
property var sourceType: "geojson"
- property var data: ":source.geojson"
+ property var data: ":source1.geojson"
},
MapParameter {
property var type: "layer"
@@ -256,11 +257,11 @@ ApplicationWindow {
title: "Style:"
ColumnLayout {
- ExclusiveGroup { id: group }
+ ExclusiveGroup { id: styleGroup }
RadioButton {
text: "Streets"
checked: true
- exclusiveGroup: group
+ exclusiveGroup: styleGroup
onClicked: {
style.url = "mapbox://styles/mapbox/streets-v9"
landColorDialog.color = "#e0ded8"
@@ -269,7 +270,7 @@ ApplicationWindow {
}
RadioButton {
text: "Dark"
- exclusiveGroup: group
+ exclusiveGroup: styleGroup
onClicked: {
style.url = "mapbox://styles/mapbox/dark-v9"
landColorDialog.color = "#343332"
@@ -278,7 +279,7 @@ ApplicationWindow {
}
RadioButton {
text: "Satellite"
- exclusiveGroup: group
+ exclusiveGroup: styleGroup
onClicked: {
style.url = "mapbox://styles/mapbox/satellite-v9"
}
@@ -300,6 +301,41 @@ ApplicationWindow {
onClicked: waterColorDialog.open()
}
+ GroupBox {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ title: "Route:"
+
+ ColumnLayout {
+ ExclusiveGroup { id: sourceGroup }
+ RadioButton {
+ text: "Route 1"
+ checked: true
+ exclusiveGroup: sourceGroup
+ onClicked: {
+ source.data = ":source1.geojson"
+ }
+ }
+ RadioButton {
+ text: "Route 2"
+ exclusiveGroup: sourceGroup
+ onClicked: {
+ source.data = ":source2.geojson"
+ }
+ }
+ RadioButton {
+ text: "Route 3"
+ exclusiveGroup: sourceGroup
+ onClicked: {
+ source.data = '{ "type": "FeatureCollection", "features": \
+ [{ "type": "Feature", "properties": {}, "geometry": { \
+ "type": "LineString", "coordinates": [[ 24.934938848018646, \
+ 60.16830257086771 ], [ 24.943315386772156, 60.16227776476442 ]]}}]}'
+ }
+ }
+ }
+ }
+
CheckBox {
id: toggleRoute
anchors.left: parent.left
diff --git a/platform/qt/qt.cmake b/platform/qt/qt.cmake
index 398e173cfa..2950e1fb15 100644
--- a/platform/qt/qt.cmake
+++ b/platform/qt/qt.cmake
@@ -2,6 +2,7 @@
# support `mason` (i.e. Yocto). Do not add any `mason` macro.
option(WITH_QT_DECODERS "Use builtin Qt image decoders" OFF)
+option(WITH_QT_I18N "Use builtin Qt i18n support" OFF)
option(WITH_QT_4 "Use Qt4 instead of Qt5" OFF)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -D__QT__")
@@ -28,10 +29,11 @@ set(MBGL_QT_FILES
PRIVATE platform/default/sqlite3.hpp
# Misc
- PRIVATE platform/default/log_stderr.cpp
+ PRIVATE platform/default/logging_stderr.cpp
# Thread pool
- PRIVATE platform/default/thread_pool.cpp
+ PRIVATE platform/default/mbgl/util/default_thread_pool.cpp
+ PRIVATE platform/default/mbgl/util/default_thread_pool.cpp
# Platform integration
PRIVATE platform/qt/src/async_task.cpp
@@ -59,6 +61,8 @@ add_library(qmapboxgl SHARED
platform/qt/src/qmapbox.cpp
platform/qt/src/qmapboxgl.cpp
platform/qt/src/qmapboxgl_p.hpp
+ platform/default/mbgl/util/default_styles.hpp
+ platform/default/mbgl/util/default_styles.cpp
)
# C++ app
@@ -92,3 +96,11 @@ else()
PRIVATE -lGL
)
endif()
+
+add_custom_command(
+ TARGET qmapboxgl
+ POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_directory
+ ${CMAKE_SOURCE_DIR}/platform/qt/include
+ ${CMAKE_CURRENT_BINARY_DIR}/platform/qt/include
+)
diff --git a/platform/qt/resources/common.qrc b/platform/qt/resources/common.qrc
index e9fd46cfa7..9d409760cc 100644
--- a/platform/qt/resources/common.qrc
+++ b/platform/qt/resources/common.qrc
@@ -1,6 +1,7 @@
<RCC>
<qresource prefix="/">
- <file>source.geojson</file>
+ <file>source1.geojson</file>
+ <file>source2.geojson</file>
<file>label-arrow.svg</file>
<file>label-background.svg</file>
</qresource>
diff --git a/platform/qt/resources/source.geojson b/platform/qt/resources/source1.geojson
index 1d270ba189..1d270ba189 100644
--- a/platform/qt/resources/source.geojson
+++ b/platform/qt/resources/source1.geojson
diff --git a/platform/qt/resources/source2.geojson b/platform/qt/resources/source2.geojson
new file mode 100644
index 0000000000..df300d1040
--- /dev/null
+++ b/platform/qt/resources/source2.geojson
@@ -0,0 +1,92 @@
+{
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "properties": {
+ "type": "label",
+ "name": "Start"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 24.943320751190186,
+ 60.166471893909794
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "type": "label",
+ "name": "End"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 24.942440986633297,
+ 60.16715507391703
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "type": "label",
+ "name": "Traffic Accident"
+ },
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 24.94018793106079,
+ 60.16696293097573
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ 24.943320751190186,
+ 60.166471893909794
+ ],
+ [
+ 24.934544563293453,
+ 60.16347213858629
+ ],
+ [
+ 24.93321418762207,
+ 60.16446497048834
+ ],
+ [
+ 24.94018793106079,
+ 60.16696293097573
+ ],
+ [
+ 24.93875026702881,
+ 60.16806240040351
+ ],
+ [
+ 24.937891960144043,
+ 60.16777419352904
+ ],
+ [
+ 24.936089515686035,
+ 60.169033745694826
+ ],
+ [
+ 24.9384069442749,
+ 60.16984495711831
+ ],
+ [
+ 24.942440986633297,
+ 60.16715507391703
+ ]
+ ]
+ }
+ }
+ ]
+}
diff --git a/platform/qt/src/bidi.cpp b/platform/qt/src/bidi.cpp
new file mode 100644
index 0000000000..184d1daf9a
--- /dev/null
+++ b/platform/qt/src/bidi.cpp
@@ -0,0 +1,56 @@
+#include <memory>
+
+#include <mbgl/text/bidi.hpp>
+
+#include <QString>
+
+namespace mbgl {
+
+class BiDiImpl {
+public:
+ QString string;
+};
+
+std::u16string applyArabicShaping(const std::u16string& input) {
+ QString utf16string = QString::fromStdU16String(input);
+ return utf16string.toStdU16String();
+}
+
+ProcessedBiDiText::ProcessedBiDiText(BiDi& p_bidi) : bidi(p_bidi) {
+}
+
+void ProcessedBiDiText::mergeParagraphLineBreaks(std::set<int32_t>& lineBreakPoints) {
+ lineBreakPoints.insert(bidi.impl->string.length());
+}
+
+std::vector<std::u16string>
+ProcessedBiDiText::applyLineBreaking(std::set<int32_t> lineBreakPoints) {
+ mergeParagraphLineBreaks(lineBreakPoints);
+
+ std::vector<std::u16string> transformedLines;
+ int32_t start = 0;
+ for (int32_t lineBreakPoint : lineBreakPoints) {
+ transformedLines.push_back(bidi.getLine(start, lineBreakPoint));
+ start = lineBreakPoint;
+ }
+
+ return transformedLines;
+}
+
+BiDi::BiDi() : impl(std::make_unique<BiDiImpl>())
+{
+}
+
+BiDi::~BiDi() {
+}
+
+ProcessedBiDiText BiDi::processText(const std::u16string& input) {
+ impl->string = QString::fromStdU16String(input);
+ return ProcessedBiDiText(*this);
+}
+
+std::u16string BiDi::getLine(int32_t start, int32_t end) {
+ return impl->string.mid(start, end - start).toStdU16String();
+}
+
+} // end namespace mbgl
diff --git a/platform/qt/src/http_file_source.cpp b/platform/qt/src/http_file_source.cpp
index 61fa1ca612..9bf2cc5fac 100644
--- a/platform/qt/src/http_file_source.cpp
+++ b/platform/qt/src/http_file_source.cpp
@@ -1,7 +1,7 @@
#include "http_file_source.hpp"
#include "http_request.hpp"
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
#include <QByteArray>
#include <QDir>
diff --git a/platform/qt/src/image.cpp b/platform/qt/src/image.cpp
index 3918b35208..403ca9cbd3 100644
--- a/platform/qt/src/image.cpp
+++ b/platform/qt/src/image.cpp
@@ -7,7 +7,7 @@
namespace mbgl {
std::string encodePNG(const PremultipliedImage& pre) {
- QImage image(pre.data.get(), pre.width, pre.height,
+ QImage image(pre.data.get(), pre.size.width, pre.size.height,
QImage::Format_ARGB32_Premultiplied);
QByteArray array;
@@ -57,7 +57,7 @@ PremultipliedImage decodeImage(const std::string& string) {
auto img = std::make_unique<uint8_t[]>(image.byteCount());
memcpy(img.get(), image.constBits(), image.byteCount());
- return { static_cast<uint16_t>(image.width()), static_cast<uint16_t>(image.height()),
+ return { { static_cast<uint32_t>(image.width()), static_cast<uint32_t>(image.height()) },
std::move(img) };
}
}
diff --git a/platform/qt/src/qmapboxgl.cpp b/platform/qt/src/qmapboxgl.cpp
index edda1f9599..ae4c028eed 100644
--- a/platform/qt/src/qmapboxgl.cpp
+++ b/platform/qt/src/qmapboxgl.cpp
@@ -13,6 +13,7 @@
#include <mbgl/style/conversion/layer.hpp>
#include <mbgl/style/conversion/source.hpp>
#include <mbgl/style/layers/custom_layer.hpp>
+#include <mbgl/style/sources/geojson_source.hpp>
#include <mbgl/style/transition_options.hpp>
#include <mbgl/sprite/sprite_image.hpp>
#include <mbgl/storage/network_status.hpp>
@@ -25,6 +26,7 @@
#include <QGuiApplication>
#include <QWindow>
#include <QOpenGLFramebufferObject>
+#include <QOpenGLContext>
#else
#include <QCoreApplication>
#endif
@@ -122,8 +124,9 @@ std::unique_ptr<const mbgl::SpriteImage> toSpriteImage(const QImage &sprite) {
memcpy(img.get(), swapped.constBits(), swapped.byteCount());
return std::make_unique<mbgl::SpriteImage>(
- mbgl::PremultipliedImage{ static_cast<uint16_t>(swapped.width()),
- static_cast<uint16_t>(swapped.height()), std::move(img) },
+ mbgl::PremultipliedImage(
+ { static_cast<uint32_t>(swapped.width()), static_cast<uint32_t>(swapped.height()) },
+ std::move(img)),
1.0);
}
@@ -611,7 +614,8 @@ void QMapboxGL::resize(const QSize& size, const QSize& framebufferSize)
d_ptr->size = size;
d_ptr->fbSize = framebufferSize;
- d_ptr->mapObj->setSize({{ static_cast<uint16_t>(size.width()), static_cast<uint16_t>(size.height()) }});
+ d_ptr->mapObj->setSize(
+ { static_cast<uint32_t>(size.width()), static_cast<uint32_t>(size.height()) });
}
void QMapboxGL::addAnnotationIcon(const QString &name, const QImage &sprite)
@@ -700,9 +704,38 @@ void QMapboxGL::addSource(const QString &sourceID, const QVariantMap &params)
d_ptr->mapObj->addSource(std::move(*source));
}
+void QMapboxGL::updateSource(const QString &sourceID, const QVariantMap &params)
+{
+ using namespace mbgl::style;
+ using namespace mbgl::style::conversion;
+
+ auto source = d_ptr->mapObj->getSource(sourceID.toStdString());
+ if (!source) {
+ addSource(sourceID, params);
+ return;
+ }
+
+ auto sourceGeoJSON = source->as<GeoJSONSource>();
+ if (!sourceGeoJSON) {
+ qWarning() << "Unable to update source: only GeoJSON sources are mutable.";
+ return;
+ }
+
+ if (params.contains("data")) {
+ auto result = convertGeoJSON(params["data"]);
+ if (result) {
+ sourceGeoJSON->setGeoJSON(*result);
+ }
+ }
+}
+
void QMapboxGL::removeSource(const QString& sourceID)
{
- d_ptr->mapObj->removeSource(sourceID.toStdString());
+ auto sourceIDStdString = sourceID.toStdString();
+
+ if (d_ptr->mapObj->getSource(sourceIDStdString)) {
+ d_ptr->mapObj->removeSource(sourceIDStdString);
+ }
}
void QMapboxGL::addCustomLayer(const QString &id,
@@ -798,12 +831,20 @@ void QMapboxGL::setFilter(const QString& layer_, const QVariant& filter_)
void QMapboxGL::render(QOpenGLFramebufferObject *fbo)
{
d_ptr->dirty = false;
- d_ptr->updateFramebufferBinding(fbo);
+ d_ptr->fbo = fbo;
d_ptr->mapObj->render(*d_ptr);
}
#else
void QMapboxGL::render()
{
+#if defined(__APPLE__)
+ // FIXME Qt 4.x provides an incomplete FBO at start.
+ // See https://bugreports.qt.io/browse/QTBUG-36802 for details.
+ if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
+ return;
+ }
+#endif
+
d_ptr->dirty = false;
d_ptr->mapObj->render(*d_ptr);
}
@@ -824,7 +865,7 @@ QMapboxGLPrivate::QMapboxGLPrivate(QMapboxGL *q, const QMapboxGLSettings &settin
settings.cacheDatabaseMaximumSize()))
, threadPool(4)
, mapObj(std::make_unique<mbgl::Map>(
- *this, std::array<uint16_t, 2>{{ static_cast<uint16_t>(size.width()), static_cast<uint16_t>(size.height()) }},
+ *this, mbgl::Size{ static_cast<uint32_t>(size.width()), static_cast<uint32_t>(size.height()) },
pixelRatio, *fileSourceObj, threadPool,
static_cast<mbgl::MapMode>(settings.mapMode()),
static_cast<mbgl::GLContextMode>(settings.contextMode()),
@@ -836,6 +877,7 @@ QMapboxGLPrivate::QMapboxGLPrivate(QMapboxGL *q, const QMapboxGLSettings &settin
fileSourceObj->setAccessToken(settings.accessToken().toStdString());
connect(this, SIGNAL(needsRendering()), q_ptr, SIGNAL(needsRendering()), Qt::QueuedConnection);
connect(this, SIGNAL(mapChanged(QMapbox::MapChange)), q_ptr, SIGNAL(mapChanged(QMapbox::MapChange)), Qt::QueuedConnection);
+ connect(this, SIGNAL(copyrightsChanged(QString)), q_ptr, SIGNAL(copyrightsChanged(QString)), Qt::QueuedConnection);
}
QMapboxGLPrivate::~QMapboxGLPrivate()
@@ -843,39 +885,21 @@ QMapboxGLPrivate::~QMapboxGLPrivate()
}
#if QT_VERSION >= 0x050000
-void QMapboxGLPrivate::updateFramebufferBinding(QOpenGLFramebufferObject *fbo_)
-{
- fbo = fbo_;
- if (fbo) {
- getContext().bindFramebuffer.setDirty();
- getContext().viewport.setCurrentValue(
- { 0, 0, static_cast<uint16_t>(fbo->width()), static_cast<uint16_t>(fbo->height()) });
- } else {
- getContext().bindFramebuffer.setCurrentValue(0);
- getContext().viewport.setCurrentValue({ 0, 0, static_cast<uint16_t>(fbSize.width()),
- static_cast<uint16_t>(fbSize.height()) });
- }
-}
-
-void QMapboxGLPrivate::bind()
-{
+void QMapboxGLPrivate::bind() {
if (fbo) {
fbo->bind();
getContext().bindFramebuffer.setDirty();
- getContext().viewport = { 0, 0, static_cast<uint16_t>(fbo->width()),
- static_cast<uint16_t>(fbo->height()) };
- } else {
- getContext().bindFramebuffer = 0;
- getContext().viewport = { 0, 0, static_cast<uint16_t>(fbSize.width()),
- static_cast<uint16_t>(fbSize.height()) };
+ getContext().viewport = {
+ 0, 0, { static_cast<uint32_t>(fbo->width()), static_cast<uint32_t>(fbo->height()) }
+ };
}
}
#else
-void QMapboxGLPrivate::bind()
-{
+void QMapboxGLPrivate::bind() {
getContext().bindFramebuffer = 0;
- getContext().viewport = { 0, 0, static_cast<uint16_t>(fbSize.width()),
- static_cast<uint16_t>(fbSize.height()) };
+ getContext().viewport = {
+ 0, 0, { static_cast<uint32_t>(fbSize.width()), static_cast<uint32_t>(fbSize.height()) }
+ };
}
#endif
@@ -889,6 +913,16 @@ void QMapboxGLPrivate::invalidate()
void QMapboxGLPrivate::notifyMapChange(mbgl::MapChange change)
{
+ if (change == mbgl::MapChangeSourceDidChange) {
+ std::string attribution;
+ for (const auto& source : mapObj->getSources()) {
+ // Avoid duplicates by using the most complete attribution HTML snippet.
+ if (source->getAttribution() && (attribution.size() < source->getAttribution()->size()))
+ attribution = *source->getAttribution();
+ }
+ emit copyrightsChanged(QString::fromStdString(attribution));
+ }
+
emit mapChanged(static_cast<QMapbox::MapChange>(change));
}
diff --git a/platform/qt/src/qmapboxgl_p.hpp b/platform/qt/src/qmapboxgl_p.hpp
index e7a14601c1..bfa5b8c326 100644
--- a/platform/qt/src/qmapboxgl_p.hpp
+++ b/platform/qt/src/qmapboxgl_p.hpp
@@ -5,7 +5,7 @@
#include <mbgl/map/map.hpp>
#include <mbgl/map/backend.hpp>
#include <mbgl/map/view.hpp>
-#include <mbgl/platform/default/thread_pool.hpp>
+#include <mbgl/util/default_thread_pool.hpp>
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/util/geo.hpp>
@@ -31,10 +31,6 @@ public:
void invalidate() final;
void notifyMapChange(mbgl::MapChange) final;
-#if QT_VERSION >= 0x050000
- void updateFramebufferBinding(QOpenGLFramebufferObject *);
-#endif
-
mbgl::EdgeInsets margins;
QSize size { 0, 0 };
QSize fbSize { 0, 0 };
@@ -55,4 +51,5 @@ public slots:
signals:
void needsRendering();
void mapChanged(QMapbox::MapChange);
+ void copyrightsChanged(const QString &copyrightsHtml);
};
diff --git a/platform/qt/src/qquickmapboxgl.cpp b/platform/qt/src/qquickmapboxgl.cpp
index b17d8bfe3e..579bea72f2 100644
--- a/platform/qt/src/qquickmapboxgl.cpp
+++ b/platform/qt/src/qquickmapboxgl.cpp
@@ -290,9 +290,14 @@ bool QQuickMapboxGL::parseStyleSource(QQuickMapboxGLMapParameter *param)
source["url"] = param->property("url");
m_sourceChanges << source;
} else if (sourceType == "geojson") {
- QFile geojson(param->property("data").toString());
- geojson.open(QIODevice::ReadOnly);
- source["data"] = geojson.readAll();
+ auto data = param->property("data").toString();
+ if (data.startsWith(':')) {
+ QFile geojson(data);
+ geojson.open(QIODevice::ReadOnly);
+ source["data"] = geojson.readAll();
+ } else {
+ source["data"] = data.toUtf8();
+ }
m_sourceChanges << source;
} else {
m_error = QGeoServiceProvider::UnknownParameterError;
diff --git a/platform/qt/src/qquickmapboxglrenderer.cpp b/platform/qt/src/qquickmapboxglrenderer.cpp
index 903e1c0b05..880d7b2e40 100644
--- a/platform/qt/src/qquickmapboxglrenderer.cpp
+++ b/platform/qt/src/qquickmapboxglrenderer.cpp
@@ -88,7 +88,7 @@ void QQuickMapboxGLRenderer::synchronize(QQuickFramebufferObject *item)
}
for (const auto& change : quickMap->m_sourceChanges) {
- m_map->addSource(change.value("id").toString(), change);
+ m_map->updateSource(change.value("id").toString(), change);
}
quickMap->m_sourceChanges.clear();
diff --git a/platform/qt/src/qt_conversion.hpp b/platform/qt/src/qt_conversion.hpp
index acb7ed7d54..e49b6dbe3e 100644
--- a/platform/qt/src/qt_conversion.hpp
+++ b/platform/qt/src/qt_conversion.hpp
@@ -94,9 +94,9 @@ inline optional<Value> toValue(const QVariant& value) {
} else if (value.type() == QVariant::Color) {
return { value.value<QColor>().name().toStdString() };
} else if (value.type() == QVariant::Int) {
- return { value.toInt() };
+ return { int64_t(value.toInt()) };
} else if (value.canConvert(QVariant::Double)) {
- return { value.toFloat() };
+ return { value.toDouble() };
} else {
return {};
}
diff --git a/platform/qt/src/run_loop_impl.hpp b/platform/qt/src/run_loop_impl.hpp
index ea64e4b977..c1fe8578e3 100644
--- a/platform/qt/src/run_loop_impl.hpp
+++ b/platform/qt/src/run_loop_impl.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
#include <mbgl/util/async_task.hpp>
#include <mbgl/util/run_loop.hpp>
diff --git a/platform/qt/src/string_stdlib.cpp b/platform/qt/src/string_stdlib.cpp
index c4adecea06..635a01352e 100644
--- a/platform/qt/src/string_stdlib.cpp
+++ b/platform/qt/src/string_stdlib.cpp
@@ -1,4 +1,4 @@
-#include <mbgl/platform/platform.hpp>
+#include <mbgl/util/platform.hpp>
#include <QByteArray>
#include <QString>
diff --git a/platform/qt/test/headless_backend_qt.cpp b/platform/qt/test/headless_backend_qt.cpp
index 3f287ae578..1992cab2fa 100644
--- a/platform/qt/test/headless_backend_qt.cpp
+++ b/platform/qt/test/headless_backend_qt.cpp
@@ -1,5 +1,4 @@
-#include <mbgl/platform/default/headless_backend.hpp>
-#include <mbgl/platform/default/headless_display.hpp>
+#include <mbgl/gl/headless_backend.hpp>
#include <QApplication>
#include <QGLContext>
@@ -9,8 +8,22 @@
#include <QOpenGLContext>
#endif
+#include <cassert>
+
namespace mbgl {
+struct QtImpl : public HeadlessBackend::Impl {
+ void activateContext() final {
+ widget.makeCurrent();
+ }
+
+ void deactivateContext() final {
+ widget.doneCurrent();
+ }
+
+ QGLWidget widget;
+};
+
gl::glProc HeadlessBackend::initializeExtension(const char* name) {
#if QT_VERSION >= 0x050000
QOpenGLContext* thisContext = QOpenGLContext::currentContext();
@@ -21,26 +34,20 @@ gl::glProc HeadlessBackend::initializeExtension(const char* name) {
#endif
}
+bool HeadlessBackend::hasDisplay() {
+ return true;
+};
+
void HeadlessBackend::createContext() {
+ assert(!hasContext());
+
static const char* argv[] = { "mbgl" };
static int argc = 1;
static auto* app = new QApplication(argc, const_cast<char**>(argv));
Q_UNUSED(app);
- glContext = new QGLWidget;
-}
-
-void HeadlessBackend::destroyContext() {
- delete glContext;
-}
-
-void HeadlessBackend::activateContext() {
- glContext->makeCurrent();
-}
-
-void HeadlessBackend::deactivateContext() {
- glContext->doneCurrent();
+ impl.reset(new QtImpl);
}
} // namespace mbgl
diff --git a/scripts/build-shaders.js b/scripts/build-shaders.js
index 9090f19e6d..d00762acf0 100755
--- a/scripts/build-shaders.js
+++ b/scripts/build-shaders.js
@@ -4,68 +4,57 @@ var path = require('path');
var fs = require('fs');
var mkdirp = require('mkdirp');
-var input_file = process.argv[2]
-var output_file = process.argv[3];
+var shaderName = process.argv[2];
+var inputPath = process.argv[3];
+var outputPath = process.argv[4];
-if (!input_file || !output_file) {
- console.warn('No input or output file given.');
- console.warn('Usage: %s [input.vertex.glsl] [output.vertex.hpp]', path.basename(process.argv[1]));
+if (!shaderName || !inputPath || !outputPath) {
+ console.warn('Not enough arguments.');
+ console.warn('Usage: %s shaderName /path-to-shader-sources /output-path', path.basename(process.argv[1]));
process.exit(1);
}
-var components = path.basename(input_file).split('.');
+var pragmaMapboxRe = /(\s*)#pragma\s+mapbox\s*:\s+(define|initialize)\s+(low|medium|high)p\s+(float|vec(?:2|3|4))\s+(.*)/;
-var shader_name = components[0];
-var shader_type = components[1];
-var extension = components[2];
-var data = fs.readFileSync(input_file, 'utf8');
-
-// Replace uniform pragmas
-
-var pragma_mapbox_regex = /(\s*)#pragma\s+mapbox\s*:\s+(define|initialize)\s+(low|medium|high)p\s+(float|vec(?:2|3|4))\s+(.*)/;
-
-var data = data.split('\n').map(function(line) {
- var params = line.match(pragma_mapbox_regex);
- if (params) {
- if (params[2] === 'define') {
- return params[1] + 'uniform ' + params[3] + 'p ' + params[4] + ' u_' + params[5] + ';';
+function applyPragmas(source) {
+ return '\n' + source.split('\n').map(function(line) {
+ var params = line.match(pragmaMapboxRe);
+ if (params) {
+ if (params[2] === 'define') {
+ return params[1] + 'uniform ' + params[3] + 'p ' + params[4] + ' u_' + params[5] + ';';
+ } else {
+ return params[1] + params[3] + 'p ' + params[4] + ' ' + params[5] + ' = u_' + params[5] + ';';
+ }
} else {
- return params[1] + params[3] + 'p ' + params[4] + ' ' + params[5] + ' = u_' + params[5] + ';';
+ return line;
}
- } else {
- return line;
- }
-}).join('\n');
-
-
-var content =
- '#pragma once\n' +
- '\n' +
- '// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.\n' +
- '\n' +
- '#include <mbgl/gl/gl.hpp>\n' +
- '\n' +
- 'namespace mbgl {\n' +
- 'namespace shaders {\n' +
- 'namespace ' + shader_name + ' {\n' +
- '\n' +
- '#ifndef MBGL_SHADER_NAME_' + shader_name.toUpperCase() + '\n' +
- '#define MBGL_SHADER_NAME_' + shader_name.toUpperCase() + '\n' +
- 'constexpr const char* name = "' + shader_name + '";\n' +
- '#endif // MBGL_SHADER_NAME_' + shader_name.toUpperCase() + '\n' +
- '\n' +
- 'constexpr const char* ' + shader_type + ' =\n' +
- '#ifdef GL_ES_VERSION_2_0\n' +
- ' "precision highp float;"\n' +
- '#else\n' +
- ' "#version 120"\n' +
- '#endif\n' +
- ' R"MBGL_SHADER(\n' + data + ')MBGL_SHADER";\n' +
- '\n' +
- '} // namespace ' + shader_name + '\n' +
- '} // namespace shaders\n' +
- '} // namespace mbgl\n';
+ }).join('\n');
+}
-mkdirp.sync(path.dirname(output_file));
-fs.writeFileSync(output_file, content);
+var vertexPrelude = fs.readFileSync(path.join(inputPath, '_prelude.vertex.glsl'));
+var fragmentPrelude = fs.readFileSync(path.join(inputPath, '_prelude.fragment.glsl'));
+var vertexSource = vertexPrelude + fs.readFileSync(path.join(inputPath, shaderName + '.vertex.glsl'), 'utf8');
+var fragmentSource = fragmentPrelude + fs.readFileSync(path.join(inputPath, shaderName + '.fragment.glsl'), 'utf8');
+
+var content = "#pragma once\n" +
+"\n" +
+"// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED.\n" +
+"\n" +
+"#include <mbgl/gl/gl.hpp>\n" +
+"\n" +
+"namespace mbgl {\n" +
+"namespace shaders {\n" +
+"\n" +
+"class " + shaderName + " {\n" +
+"public:\n" +
+" static constexpr const char* name = \"" + shaderName + "\";\n" +
+" static constexpr const char* vertexSource = R\"MBGL_SHADER(" + applyPragmas(vertexSource) + ")MBGL_SHADER\";\n" +
+" static constexpr const char* fragmentSource = R\"MBGL_SHADER(" + applyPragmas(fragmentSource) + ")MBGL_SHADER\";\n" +
+"};\n" +
+"\n" +
+"} // namespace shaders\n" +
+"} // namespace mbgl\n";
+
+mkdirp.sync(outputPath);
+fs.writeFileSync(path.join(outputPath, shaderName + '.hpp'), content);
diff --git a/scripts/clang-tools.sh b/scripts/clang-tools.sh
index fa9825f4a4..b49aadf520 100755
--- a/scripts/clang-tools.sh
+++ b/scripts/clang-tools.sh
@@ -45,17 +45,12 @@ export -f check_tidy check_format
echo "Running clang checks... (this might take a while)"
if [[ -n $2 ]] && [[ $2 == "--diff" ]]; then
- git diff-index --quiet HEAD || {
- echo "Your repository contains unstaged and/or uncommitted changes."
- echo "Please commit all changes before proceeding."
- exit 1
- }
- DIFF_FILES=$(for file in `git diff origin/master..HEAD --name-only | grep "pp$"`; do echo $file; done)
+ DIFF_FILES=$(for file in `git diff origin/master --name-only | grep "pp$"`; do echo $file; done)
if [[ -n $DIFF_FILES ]]; then
echo "${DIFF_FILES}" | xargs -I{} -P ${JOBS} bash -c 'check_tidy --fix' {}
# XXX disabled until we run clang-format over the entire codebase.
#echo "${DIFF_FILES}" | xargs -I{} -P ${JOBS} bash -c 'check_format' {}
- git diff-index --quiet HEAD || {
+ git diff --quiet || {
echo "Changes were made to source files - please review them before committing."
exit 1
}
diff --git a/scripts/generate-style-code.js b/scripts/generate-style-code.js
index dcb527e8c9..f2acb12a2a 100644
--- a/scripts/generate-style-code.js
+++ b/scripts/generate-style-code.js
@@ -3,27 +3,17 @@
const fs = require('fs');
const ejs = require('ejs');
const spec = require('mapbox-gl-style-spec').latest;
-var colorParser = require('csscolorparser');
+const colorParser = require('csscolorparser');
+
+require('./style-code');
function parseCSSColor(str) {
- var color = colorParser.parseCSSColor(str);
+ const color = colorParser.parseCSSColor(str);
return [
color[0] / 255 * color[3], color[1] / 255 * color[3], color[2] / 255 * color[3], color[3]
];
}
-global.camelize = function (str) {
- return str.replace(/(?:^|-)(.)/g, function (_, x) {
- return x.toUpperCase();
- });
-}
-
-global.camelizeWithLeadingLowercase = function (str) {
- return str.replace(/-(.)/g, function (_, x) {
- return x.toUpperCase();
- });
-}
-
global.propertyType = function (property) {
if (/-translate-anchor$/.test(property.name)) {
return 'TranslateAnchorType';
@@ -50,7 +40,7 @@ global.propertyType = function (property) {
}
default: throw new Error(`unknown type for ${property.name}`)
}
-}
+};
global.defaultValue = function (property) {
// https://github.com/mapbox/mapbox-gl-native/issues/5258
@@ -74,7 +64,7 @@ global.defaultValue = function (property) {
return `${propertyType(property)}::${camelize(property.default)}`;
}
case 'color':
- var color = parseCSSColor(property.default).join(', ');
+ const color = parseCSSColor(property.default).join(', ');
switch (color) {
case '0, 0, 0, 0':
return '{}';
@@ -95,7 +85,7 @@ global.defaultValue = function (property) {
default:
return property.default;
}
-}
+};
const layerHpp = ejs.compile(fs.readFileSync('include/mbgl/style/layers/layer.hpp.ejs', 'utf8'), {strict: true});
const layerCpp = ejs.compile(fs.readFileSync('src/mbgl/style/layers/layer.cpp.ejs', 'utf8'), {strict: true});
@@ -121,16 +111,21 @@ const layers = Object.keys(spec.layer.type.values).map((type) => {
type: type,
layoutProperties: layoutProperties,
paintProperties: paintProperties,
+ doc: spec.layer.type.values[type].doc,
+ layoutPropertiesByName: spec[`layout_${type}`],
+ paintPropertiesByName: spec[`paint_${type}`],
};
});
for (const layer of layers) {
- fs.writeFileSync(`include/mbgl/style/layers/${layer.type}_layer.hpp`, layerHpp(layer));
- fs.writeFileSync(`src/mbgl/style/layers/${layer.type}_layer.cpp`, layerCpp(layer));
+ const layerFileName = layer.type.replace('-', '_');
+
+ writeIfModified(`include/mbgl/style/layers/${layerFileName}_layer.hpp`, layerHpp(layer));
+ writeIfModified(`src/mbgl/style/layers/${layerFileName}_layer.cpp`, layerCpp(layer));
- fs.writeFileSync(`src/mbgl/style/layers/${layer.type}_layer_properties.hpp`, propertiesHpp(layer));
- fs.writeFileSync(`src/mbgl/style/layers/${layer.type}_layer_properties.cpp`, propertiesCpp(layer));
+ writeIfModified(`src/mbgl/style/layers/${layerFileName}_layer_properties.hpp`, propertiesHpp(layer));
+ writeIfModified(`src/mbgl/style/layers/${layerFileName}_layer_properties.cpp`, propertiesCpp(layer));
}
const propertySettersHpp = ejs.compile(fs.readFileSync('include/mbgl/style/conversion/make_property_setters.hpp.ejs', 'utf8'), {strict: true});
-fs.writeFileSync('include/mbgl/style/conversion/make_property_setters.hpp', propertySettersHpp({layers: layers}));
+writeIfModified('include/mbgl/style/conversion/make_property_setters.hpp', propertySettersHpp({layers: layers}));
diff --git a/scripts/log_binary_size.sh b/scripts/log_binary_size.sh
new file mode 100755
index 0000000000..3c55be15f1
--- /dev/null
+++ b/scripts/log_binary_size.sh
@@ -0,0 +1,42 @@
+#!/usr/bin/env bash
+
+set -e
+set -o pipefail
+set -u
+
+# Logs metrics on binary size to CloudWatch
+
+FILE=$1
+DIMENSIONS=$2
+
+if [ -z "${DIMENSIONS}" ]; then
+ echo "* No dimensions specified for '${FILE}'"
+ exit 1
+fi
+
+function filesize {
+ if [ `uname -s` = 'Darwin' ]; then
+ stat -f%z $1
+ else
+ stat --printf=%s $1
+ fi
+}
+
+if [ -f "${FILE}" ]; then
+ SIZE=`filesize ${FILE}`
+ if [ ${CLOUDWATCH:-} ]; then
+ echo "* Reporting `LC_NUMERIC=en_US printf "%'10.f\n" ${SIZE}` bytes for '${DIMENSIONS}' (${FILE})"
+ aws --region us-east-1 cloudwatch put-metric-data \
+ --namespace "Mapbox/GL" \
+ --metric-name "BinarySize" \
+ --unit "Bytes" \
+ --value ${SIZE} \
+ --dimensions "${DIMENSIONS}"
+
+ ./scripts/publish_binary_size.sh "${DIMENSIONS}"
+ else
+ echo "* Measured `LC_NUMERIC=en_US printf "%'10.f\n" ${SIZE}` bytes for '${DIMENSIONS}' (${FILE})"
+ fi
+else
+ echo "* File '${FILE}' does not exist"
+fi
diff --git a/scripts/publish_binary_size.sh b/scripts/publish_binary_size.sh
new file mode 100755
index 0000000000..d5ab71b8c4
--- /dev/null
+++ b/scripts/publish_binary_size.sh
@@ -0,0 +1,75 @@
+#!/usr/bin/env bash
+
+set -e
+set -o pipefail
+set -u
+
+# Downloads log data from AWS CloudWatch and uploads it as a JSON file to S3 for public access.
+
+function publish_binary_size {
+ local DIMENSIONS=$1
+
+ if [ -z "${DIMENSIONS}" ]; then
+ echo "* No dimensions specified"
+ exit 1
+ fi
+
+ function print_dimensions {
+ for ITEM in ${DIMENSIONS//,/ } ; do
+ echo -n "Name=${ITEM//=/,Value=} "
+ done
+ }
+
+ local DATE_FORMAT="%Y-%m-%dT%H:%M:%SZ"
+ local DATE_END=$(date -u +${DATE_FORMAT})
+
+ if [ `uname -s` = 'Darwin' ]; then # BSD date
+ local DATE_BEGIN=$(date -jf "${DATE_FORMAT}" -v-30d "${DATE_END}" +"${DATE_FORMAT}")
+ else # GNU date
+ local DATE_BEGIN=$(date --date="${DATE_END} - 30 days" +"${DATE_FORMAT}")
+ fi
+
+ # Download the metrics, gzip, and upload to S3.
+ aws --region us-east-1 cloudwatch get-metric-statistics \
+ --namespace "Mapbox/GL" \
+ --metric-name "BinarySize" \
+ --unit "Bytes" \
+ --start-time "${DATE_BEGIN}" \
+ --end-time "${DATE_END}" \
+ --period 3600 \
+ --statistics Maximum \
+ --dimensions `print_dimensions` \
+ | gzip | aws s3 cp \
+ --acl public-read \
+ --cache-control "max-age=300" \
+ --content-encoding gzip \
+ --content-type application/json \
+ - "s3://mapbox/mapbox-gl-native/metrics/binary-size/${DIMENSIONS}.json"
+
+ echo "* Uploaded data to 's3://mapbox/mapbox-gl-native/metrics/binary-size/${DIMENSIONS}.json'"
+}
+
+if [ $# -gt 0 ]; then
+ # Upload the specified dimension only
+ publish_binary_size "$1"
+else
+ # Upload all dimensions that we are tracking
+ publish_binary_size "Platform=iOS,Arch=armv7"
+ publish_binary_size "Platform=iOS,Arch=arm64"
+ publish_binary_size "Platform=iOS,Arch=i386"
+ publish_binary_size "Platform=iOS,Arch=x86_64"
+ publish_binary_size "Platform=iOS,Arch=Dynamic"
+
+ publish_binary_size "Platform=macOS,Arch=x86_64"
+
+ publish_binary_size "Platform=Linux,Compiler=clang-3.8,Arch=x86_64"
+ publish_binary_size "Platform=Linux,Compiler=gcc-5,Arch=x86_64"
+
+ publish_binary_size "Platform=Android,Arch=arm-v5"
+ publish_binary_size "Platform=Android,Arch=arm-v7"
+ publish_binary_size "Platform=Android,Arch=arm-v8"
+ publish_binary_size "Platform=Android,Arch=x86"
+ publish_binary_size "Platform=Android,Arch=x86_64"
+ publish_binary_size "Platform=Android,Arch=mips"
+ publish_binary_size "Platform=Android,Arch=Archive"
+fi
diff --git a/scripts/style-code.js b/scripts/style-code.js
new file mode 100644
index 0000000000..156934a240
--- /dev/null
+++ b/scripts/style-code.js
@@ -0,0 +1,36 @@
+// Global functions //
+
+const fs = require('fs');
+
+global.iff = function (condition, val) {
+ return condition() ? val : "";
+};
+
+global.camelize = function (str) {
+ return str.replace(/(?:^|-)(.)/g, function (_, x) {
+ return x.toUpperCase();
+ });
+};
+
+global.camelizeWithLeadingLowercase = function (str) {
+ return str.replace(/-(.)/g, function (_, x) {
+ return x.toUpperCase();
+ });
+};
+
+global.snakeCaseUpper = function snakeCaseUpper(str) {
+ return str.replace(/-/g, "_").toUpperCase();
+};
+
+global.writeIfModified = function(filename, newContent) {
+ try {
+ const oldContent = fs.readFileSync(filename, 'utf8');
+ if (oldContent == newContent) {
+ console.warn(`* Skipping current file '${filename}'`);
+ return;
+ }
+ } catch(err) {
+ }
+ fs.writeFileSync(filename, newContent);
+ console.warn(`* Updating outdated file '${filename}'`);
+};
diff --git a/scripts/travis_setup.sh b/scripts/travis_setup.sh
index 47df36788d..8551e1cb97 100755
--- a/scripts/travis_setup.sh
+++ b/scripts/travis_setup.sh
@@ -25,7 +25,9 @@ fi
echo "export CXX=\"${CXX}\""
echo "export CC=\"${CC}\""
-${CXX} --version
+if [ -x $(which ${CXX}) ]; then
+ ${CXX} --version
+fi
# Ensure mason is on the PATH
export PATH="`pwd`/.mason:${PATH}" MASON_DIR="`pwd`/.mason"
@@ -37,20 +39,34 @@ git submodule update --init .mason
mapbox_time "touch_package_json" \
touch package.json
-# Start the mock X server
-if [ -f /etc/init.d/xvfb ] && [ ! -z "${RUN_XVFB}" ]; then
+function mapbox_start_xvfb {
+ if [ ! -f /etc/init.d/xvfb ]; then
+ echo "Error: Could not start Xvfb mock server."
+ exit 1
+ fi
+
mapbox_time "start_xvfb" \
sh -e /etc/init.d/xvfb start
sleep 2 # sometimes, xvfb takes some time to start up
# Make sure we're connecting to xvfb
export DISPLAY=:99.0
+}
+
+export -f mapbox_start_xvfb
+function mapbox_export_mesa_library_path {
+ CXX11ABI=""
+ if [ `scripts/check-cxx11abi.sh` = 'ON' ]; then
+ CXX11ABI="-cxx11abi"
+ fi
# Install and set up to load a more recent version of mesa
mapbox_time "install_mesa" \
- mason install mesa 11.2.2
- export LD_LIBRARY_PATH="`mason prefix mesa 11.2.2`/lib:${LD_LIBRARY_PATH:-}"
-fi
+ mason install mesa 13.0.0-glx${CXX11ABI}
+ export LD_LIBRARY_PATH="`mason prefix mesa 13.0.0-glx${CXX11ABI}`/lib:${LD_LIBRARY_PATH:-}"
+}
+
+export -f mapbox_export_mesa_library_path
# Install and set up to load awscli
pip install --user awscli
diff --git a/scripts/valgrind.sup b/scripts/valgrind.sup
index f21f54be54..ea3e3d635a 100644
--- a/scripts/valgrind.sup
+++ b/scripts/valgrind.sup
@@ -180,3 +180,89 @@
fun:draw_wide_line
...
}
+{
+ Ubuntu 14.04 - Travis + Qt5
+ Memcheck:Leak
+ ...
+ obj:*/libQt5Core.*
+ ...
+}
+{
+ Ubuntu 14.04 - Travis + Qt5
+ Memcheck:Cond
+ ...
+ obj:*/libQt5Core.*
+ ...
+}
+{
+ Ubuntu 14.04 - Travis + Qt5
+ Memcheck:Value8
+ ...
+ obj:*/libQt5Core.*
+ ...
+}
+{
+ Ubuntu 14.04 - Travis + Qt5
+ Memcheck:Leak
+ ...
+ obj:*/libQt5Gui.*
+ ...
+}
+{
+ Ubuntu 14.04 - Travis + Qt5
+ Memcheck:Cond
+ ...
+ obj:*/libQt5Gui.*
+ ...
+}
+{
+ Ubuntu 14.04 - Travis + Qt5
+ Memcheck:Value8
+ ...
+ obj:*/libQt5Gui.*
+ ...
+}
+{
+ Ubuntu 14.04 - Travis + mesa 13.0.0-glx
+ Memcheck:Cond
+ ...
+ obj:*/mesa/libGL.so.*
+ ...
+}
+{
+ Ubuntu 14.04 - Travis + mesa 13.0.0-glx
+ Memcheck:Value8
+ ...
+ obj:*/mesa/libGL.so.*
+ ...
+}
+{
+ Ubuntu 14.04 - Travis + mesa 13.0.0-glx
+ Memcheck:Cond
+ ...
+ fun:do_rasterize_bin
+ ...
+}
+{
+ Ubuntu 14.04 - Travis + mesa 13.0.0-glx
+ Memcheck:Value8
+ ...
+ fun:do_rasterize_bin
+ ...
+}
+{
+ Ubuntu 14.04 - Travis + mesa 13.0.0-glx
+ Memcheck:Cond
+ ...
+ fun:_ZN6mapbox10pixelmatchEPKhS1_mmPhdb
+ ...
+}
+{
+ Ubuntu 14.04 - Travis + mesa 13.0.0-glx
+ Memcheck:Param
+ write(buf)
+ ...
+ obj:*/libc-*
+ fun:_ZN4mbgl4util10write_fileERKSsS2_
+ ...
+}
diff --git a/src/mbgl/algorithm/generate_clip_ids_impl.hpp b/src/mbgl/algorithm/generate_clip_ids_impl.hpp
index ff8f8d3fdf..59ca66bf66 100644
--- a/src/mbgl/algorithm/generate_clip_ids_impl.hpp
+++ b/src/mbgl/algorithm/generate_clip_ids_impl.hpp
@@ -1,8 +1,8 @@
#pragma once
#include <mbgl/algorithm/generate_clip_ids.hpp>
-#include <mbgl/util/math.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/math/log2.hpp>
+#include <mbgl/util/logging.hpp>
namespace mbgl {
namespace algorithm {
@@ -15,6 +15,10 @@ void ClipIDGenerator::update(Renderables& renderables) {
for (auto it = renderables.begin(); it != end; it++) {
auto& tileID = it->first;
auto& renderable = it->second;
+ if (!renderable.used) {
+ continue;
+ }
+
renderable.clip = {};
Leaf leaf{ renderable.clip };
@@ -58,6 +62,9 @@ void ClipIDGenerator::update(Renderables& renderables) {
uint8_t count = 1;
for (auto& pair : renderables) {
auto& renderable = pair.second;
+ if (!renderable.used) {
+ continue;
+ }
renderable.clip.mask |= mask;
// Assign only to clip IDs that have no value yet.
diff --git a/src/mbgl/annotation/annotation_manager.cpp b/src/mbgl/annotation/annotation_manager.cpp
index dbd5f1f433..f8c1c3adf7 100644
--- a/src/mbgl/annotation/annotation_manager.cpp
+++ b/src/mbgl/annotation/annotation_manager.cpp
@@ -20,7 +20,7 @@ const std::string AnnotationManager::SourceID = "com.mapbox.annotations";
const std::string AnnotationManager::PointLayerID = "com.mapbox.annotations.points";
AnnotationManager::AnnotationManager(float pixelRatio)
- : spriteAtlas(1024, 1024, pixelRatio) {
+ : spriteAtlas({ 1024, 1024 }, pixelRatio) {
struct NullFileSource : public FileSource {
std::unique_ptr<AsyncRequest> request(const Resource&, Callback) override {
@@ -232,7 +232,7 @@ void AnnotationManager::removeIcon(const std::string& name) {
double AnnotationManager::getTopOffsetPixelsForIcon(const std::string& name) {
auto sprite = spriteAtlas.getSprite(name);
- return sprite ? -(sprite->image.height / sprite->pixelRatio) / 2 : 0;
+ return sprite ? -(sprite->image.size.height / sprite->pixelRatio) / 2 : 0;
}
} // namespace mbgl
diff --git a/src/mbgl/annotation/annotation_tile.hpp b/src/mbgl/annotation/annotation_tile.hpp
index d43ec82d38..bf73075992 100644
--- a/src/mbgl/annotation/annotation_tile.hpp
+++ b/src/mbgl/annotation/annotation_tile.hpp
@@ -31,7 +31,7 @@ public:
FeatureType getType() const override { return type; }
optional<Value> getValue(const std::string&) const override;
- optional<FeatureIdentifier> getID() const override { return { id }; }
+ optional<FeatureIdentifier> getID() const override { return { static_cast<uint64_t>(id) }; }
GeometryCollection getGeometries() const override { return geometries; }
const AnnotationID id;
diff --git a/src/mbgl/geometry/line_atlas.cpp b/src/mbgl/geometry/line_atlas.cpp
index 50e82cc015..71a855b943 100644
--- a/src/mbgl/geometry/line_atlas.cpp
+++ b/src/mbgl/geometry/line_atlas.cpp
@@ -1,8 +1,7 @@
#include <mbgl/geometry/line_atlas.hpp>
-#include <mbgl/gl/gl.hpp>
#include <mbgl/gl/context.hpp>
-#include <mbgl/platform/log.hpp>
-#include <mbgl/platform/platform.hpp>
+#include <mbgl/util/logging.hpp>
+#include <mbgl/util/platform.hpp>
#include <boost/functional/hash.hpp>
@@ -11,10 +10,8 @@
namespace mbgl {
-LineAtlas::LineAtlas(uint16_t w, uint16_t h)
- : width(w),
- height(h),
- data(std::make_unique<char[]>(w * h)),
+LineAtlas::LineAtlas(const Size size)
+ : image(size),
dirty(true) {
}
@@ -40,11 +37,11 @@ LinePatternPos LineAtlas::getDashPosition(const std::vector<float>& dasharray,
}
LinePatternPos LineAtlas::addDash(const std::vector<float>& dasharray, LinePatternCap patternCap) {
- int n = patternCap == LinePatternCap::Round ? 7 : 0;
- int dashheight = 2 * n + 1;
+ const uint8_t n = patternCap == LinePatternCap::Round ? 7 : 0;
+ const uint8_t dashheight = 2 * n + 1;
const uint8_t offset = 128;
- if (nextRow + dashheight > height) {
+ if (nextRow + dashheight > image.size.height) {
Log::Warning(Event::OpenGL, "line atlas bitmap overflow");
return LinePatternPos();
}
@@ -54,7 +51,7 @@ LinePatternPos LineAtlas::addDash(const std::vector<float>& dasharray, LinePatte
length += part;
}
- float stretch = width / length;
+ float stretch = image.size.width / length;
float halfWidth = stretch * 0.5;
// If dasharray has an odd length, both the first and last parts
// are dashes and should be joined seamlessly.
@@ -62,7 +59,7 @@ LinePatternPos LineAtlas::addDash(const std::vector<float>& dasharray, LinePatte
for (int y = -n; y <= n; y++) {
int row = nextRow + n + y;
- int index = width * row;
+ int index = image.size.width * row;
float left = 0;
float right = dasharray[0];
@@ -72,7 +69,7 @@ LinePatternPos LineAtlas::addDash(const std::vector<float>& dasharray, LinePatte
left -= dasharray.back();
}
- for (int x = 0; x < width; x++) {
+ for (uint32_t x = 0; x < image.size.width; x++) {
while (right < x / stretch) {
left = right;
@@ -104,13 +101,13 @@ LinePatternPos LineAtlas::addDash(const std::vector<float>& dasharray, LinePatte
signedDistance = int((inside ? 1 : -1) * dist);
}
- data[index + x] = fmax(0, fmin(255, signedDistance + offset));
+ image.data[index + x] = fmax(0, fmin(255, signedDistance + offset));
}
}
LinePatternPos position;
- position.y = (0.5 + nextRow + n) / height;
- position.height = (2.0 * n) / height;
+ position.y = (0.5 + nextRow + n) / image.size.height;
+ position.height = (2.0 * n) / image.size.height;
position.width = length;
nextRow += dashheight;
@@ -120,59 +117,24 @@ LinePatternPos LineAtlas::addDash(const std::vector<float>& dasharray, LinePatte
return position;
}
-void LineAtlas::upload(gl::Context& context, gl::TextureUnit unit) {
- if (dirty) {
- bind(context, unit);
- }
+Size LineAtlas::getSize() const {
+ return image.size;
}
-void LineAtlas::bind(gl::Context& context, gl::TextureUnit unit) {
- bool first = false;
+void LineAtlas::upload(gl::Context& context, gl::TextureUnit unit) {
if (!texture) {
- texture = context.createTexture();
- context.activeTexture = unit;
- context.texture[unit] = *texture;
- MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
- MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
- MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT));
- MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
- first = true;
- } else if (context.texture[unit] != *texture) {
- context.activeTexture = unit;
- context.texture[unit] = *texture;
+ texture = context.createTexture(image, unit);
+ } else if (dirty) {
+ context.updateTexture(*texture, image, unit);
}
- if (dirty) {
- context.activeTexture = unit;
- if (first) {
- MBGL_CHECK_ERROR(glTexImage2D(
- GL_TEXTURE_2D, // GLenum target
- 0, // GLint level
- GL_ALPHA, // GLint internalformat
- width, // GLsizei width
- height, // GLsizei height
- 0, // GLint border
- GL_ALPHA, // GLenum format
- GL_UNSIGNED_BYTE, // GLenum type
- data.get() // const GLvoid * data
- ));
- } else {
- MBGL_CHECK_ERROR(glTexSubImage2D(
- GL_TEXTURE_2D, // GLenum target
- 0, // GLint level
- 0, // GLint xoffset
- 0, // GLint yoffset
- width, // GLsizei width
- height, // GLsizei height
- GL_ALPHA, // GLenum format
- GL_UNSIGNED_BYTE, // GLenum type
- data.get() // const GLvoid *pixels
- ));
- }
-
+ dirty = false;
+}
- dirty = false;
- }
+void LineAtlas::bind(gl::Context& context, gl::TextureUnit unit) {
+ upload(context, unit);
+ context.bindTexture(*texture, unit, gl::TextureFilter::Linear, gl::TextureMipMap::No,
+ gl::TextureWrap::Repeat, gl::TextureWrap::Clamp);
}
} // namespace mbgl
diff --git a/src/mbgl/geometry/line_atlas.hpp b/src/mbgl/geometry/line_atlas.hpp
index e974b4ff02..b1e7a670c1 100644
--- a/src/mbgl/geometry/line_atlas.hpp
+++ b/src/mbgl/geometry/line_atlas.hpp
@@ -1,6 +1,8 @@
#pragma once
+#include <mbgl/gl/texture.hpp>
#include <mbgl/gl/object.hpp>
+#include <mbgl/util/image.hpp>
#include <mbgl/util/optional.hpp>
#include <vector>
@@ -13,11 +15,12 @@ namespace gl {
class Context;
} // namespace gl
-typedef struct {
+class LinePatternPos {
+public:
float width;
float height;
float y;
-} LinePatternPos;
+};
enum class LinePatternCap : bool {
Square = false,
@@ -26,7 +29,7 @@ enum class LinePatternCap : bool {
class LineAtlas {
public:
- LineAtlas(uint16_t width, uint16_t height);
+ LineAtlas(Size);
~LineAtlas();
// Binds the atlas texture to the GPU, and uploads data if it is out of date.
@@ -39,14 +42,13 @@ public:
LinePatternPos getDashPosition(const std::vector<float>&, LinePatternCap);
LinePatternPos addDash(const std::vector<float>& dasharray, LinePatternCap);
- const uint16_t width;
- const uint16_t height;
+ Size getSize() const;
private:
- const std::unique_ptr<char[]> data;
+ const AlphaImage image;
bool dirty;
- mbgl::optional<gl::UniqueTexture> texture;
- int nextRow = 0;
+ mbgl::optional<gl::Texture> texture;
+ uint32_t nextRow = 0;
std::unordered_map<size_t, LinePatternPos> positions;
};
diff --git a/src/mbgl/gl/attribute.cpp b/src/mbgl/gl/attribute.cpp
new file mode 100644
index 0000000000..7432fff590
--- /dev/null
+++ b/src/mbgl/gl/attribute.cpp
@@ -0,0 +1,29 @@
+#include <mbgl/gl/attribute.hpp>
+#include <mbgl/gl/gl.hpp>
+
+namespace mbgl {
+namespace gl {
+
+AttributeLocation bindAttributeLocation(ProgramID id, AttributeLocation location, const char* name) {
+ MBGL_CHECK_ERROR(glBindAttribLocation(id, location, name));
+ return location;
+}
+
+void bindAttribute(AttributeLocation location,
+ std::size_t count,
+ DataType type,
+ std::size_t vertexSize,
+ std::size_t vertexOffset,
+ std::size_t attributeOffset) {
+ MBGL_CHECK_ERROR(glEnableVertexAttribArray(location));
+ MBGL_CHECK_ERROR(glVertexAttribPointer(
+ location,
+ static_cast<GLint>(count),
+ static_cast<GLenum>(type),
+ GL_FALSE,
+ static_cast<GLsizei>(vertexSize),
+ reinterpret_cast<GLvoid*>(attributeOffset + (vertexSize * vertexOffset))));
+}
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/gl/attribute.hpp b/src/mbgl/gl/attribute.hpp
index 8bc474e967..e45014127b 100644
--- a/src/mbgl/gl/attribute.hpp
+++ b/src/mbgl/gl/attribute.hpp
@@ -1,50 +1,171 @@
#pragma once
#include <mbgl/gl/types.hpp>
-#include <mbgl/gl/shader.hpp>
+#include <mbgl/util/ignore.hpp>
+#include <mbgl/util/indexed_tuple.hpp>
#include <cstddef>
-#include <limits>
-#include <vector>
+#include <functional>
namespace mbgl {
namespace gl {
-template <typename T, std::size_t N>
+template <class Tag, class T, std::size_t N>
class Attribute {
public:
- Attribute(const char* name, const Shader& shader)
- : location(shader.getAttributeLocation(name)) {}
+ using Type = T[N];
- AttributeLocation location;
+ class State {
+ public:
+ explicit State(AttributeLocation location_)
+ : location(location_) {}
+
+ AttributeLocation location;
+ static constexpr std::size_t count = N;
+ static constexpr DataType type = DataTypeOf<T>::value;
+ };
};
-class AttributeBinding {
+#define MBGL_DEFINE_ATTRIBUTE(type_, n_, name_) \
+ struct name_ : ::mbgl::gl::Attribute<name_, type_, n_> { static constexpr auto name = #name_; }
+
+namespace detail {
+
+// Attribute binding requires member offsets. The only standard way to
+// obtain an offset is the offsetof macro. The offsetof macro has defined
+// behavior only for standard layout types. That rules out std::tuple and
+// any other solution that relies on chained inheritance. Manually implemented
+// variadic specialization looks like the only solution. Fortunately, we
+// only use a maximum of five attributes.
+
+template <class... As>
+class Vertex;
+
+template <class A1>
+class Vertex<A1> {
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");
- }
+ typename A1::Type a1;
- AttributeLocation location;
- DataType type;
- uint8_t count;
- std::size_t offset;
+ using VertexType = Vertex<A1>;
+ static const std::size_t attributeOffsets[1];
};
-#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 A1, class A2>
+class Vertex<A1, A2> {
+public:
+ typename A1::Type a1;
+ typename A2::Type a2;
+
+ using VertexType = Vertex<A1, A2>;
+ static const std::size_t attributeOffsets[2];
+};
+
+template <class A1, class A2, class A3>
+class Vertex<A1, A2, A3> {
+public:
+ typename A1::Type a1;
+ typename A2::Type a2;
+ typename A3::Type a3;
+
+ using VertexType = Vertex<A1, A2, A3>;
+ static const std::size_t attributeOffsets[3];
+};
+
+template <class A1, class A2, class A3, class A4>
+class Vertex<A1, A2, A3, A4> {
+public:
+ typename A1::Type a1;
+ typename A2::Type a2;
+ typename A3::Type a3;
+ typename A4::Type a4;
+
+ using VertexType = Vertex<A1, A2, A3, A4>;
+ static const std::size_t attributeOffsets[4];
+};
+
+template <class A1, class A2, class A3, class A4, class A5>
+class Vertex<A1, A2, A3, A4, A5> {
+public:
+ typename A1::Type a1;
+ typename A2::Type a2;
+ typename A3::Type a3;
+ typename A4::Type a4;
+ typename A5::Type a5;
+
+ using VertexType = Vertex<A1, A2, A3, A4, A5>;
+ static const std::size_t attributeOffsets[5];
+};
-template <class Shader, class Vertex> struct AttributeBindings;
+template <class A1>
+const std::size_t Vertex<A1>::attributeOffsets[1] = {
+ offsetof(VertexType, a1)
+};
+
+template <class A1, class A2>
+const std::size_t Vertex<A1, A2>::attributeOffsets[2] = {
+ offsetof(VertexType, a1),
+ offsetof(VertexType, a2)
+};
+
+template <class A1, class A2, class A3>
+const std::size_t Vertex<A1, A2, A3>::attributeOffsets[3] = {
+ offsetof(VertexType, a1),
+ offsetof(VertexType, a2),
+ offsetof(VertexType, a3)
+};
+
+template <class A1, class A2, class A3, class A4>
+const std::size_t Vertex<A1, A2, A3, A4>::attributeOffsets[4] = {
+ offsetof(VertexType, a1),
+ offsetof(VertexType, a2),
+ offsetof(VertexType, a3),
+ offsetof(VertexType, a4)
+};
+
+template <class A1, class A2, class A3, class A4, class A5>
+const std::size_t Vertex<A1, A2, A3, A4, A5>::attributeOffsets[5] = {
+ offsetof(VertexType, a1),
+ offsetof(VertexType, a2),
+ offsetof(VertexType, a3),
+ offsetof(VertexType, a4),
+ offsetof(VertexType, a5)
+};
+
+} // namespace detail
+
+AttributeLocation bindAttributeLocation(ProgramID, AttributeLocation, const char * name);
+
+void bindAttribute(AttributeLocation location,
+ std::size_t count,
+ DataType type,
+ std::size_t vertexSize,
+ std::size_t vertexOffset,
+ std::size_t attributeOffset);
+
+template <class... As>
+class Attributes {
+public:
+ using State = IndexedTuple<TypeList<As...>, TypeList<typename As::State...>>;
+ using Vertex = detail::Vertex<As...>;
+
+ template <class A>
+ static constexpr std::size_t Index = TypeIndex<A, As...>::value;
+
+ static State state(const ProgramID& id) {
+ return State { typename As::State(bindAttributeLocation(id, Index<As>, As::name))... };
+ }
+
+ static std::function<void (std::size_t)> binder(const State& state) {
+ return [&state] (std::size_t vertexOffset) {
+ util::ignore({ (bindAttribute(state.template get<As>().location,
+ state.template get<As>().count,
+ state.template get<As>().type,
+ sizeof(Vertex),
+ vertexOffset,
+ Vertex::attributeOffsets[Index<As>]), 0)... });
+ };
+ }
+};
} // namespace gl
} // namespace mbgl
diff --git a/src/mbgl/gl/color_mode.cpp b/src/mbgl/gl/color_mode.cpp
new file mode 100644
index 0000000000..e838c8e2ff
--- /dev/null
+++ b/src/mbgl/gl/color_mode.cpp
@@ -0,0 +1,44 @@
+#include <mbgl/gl/color_mode.hpp>
+#include <mbgl/gl/gl.hpp>
+#include <mbgl/util/traits.hpp>
+
+namespace mbgl {
+namespace gl {
+
+static_assert(underlying_type(ColorMode::BlendEquation::Add) == GL_FUNC_ADD, "OpenGL enum mismatch");
+static_assert(underlying_type(ColorMode::BlendEquation::Subtract) == GL_FUNC_SUBTRACT, "OpenGL enum mismatch");
+static_assert(underlying_type(ColorMode::BlendEquation::ReverseSubtract) == GL_FUNC_REVERSE_SUBTRACT, "OpenGL enum mismatch");
+
+static_assert(underlying_type(ColorMode::Zero) == GL_ZERO, "OpenGL enum mismatch");
+static_assert(underlying_type(ColorMode::One) == GL_ONE, "OpenGL enum mismatch");
+static_assert(underlying_type(ColorMode::SrcColor) == GL_SRC_COLOR, "OpenGL enum mismatch");
+static_assert(underlying_type(ColorMode::OneMinusSrcColor) == GL_ONE_MINUS_SRC_COLOR, "OpenGL enum mismatch");
+static_assert(underlying_type(ColorMode::DstColor) == GL_DST_COLOR, "OpenGL enum mismatch");
+static_assert(underlying_type(ColorMode::OneMinusDstColor) == GL_ONE_MINUS_DST_COLOR, "OpenGL enum mismatch");
+static_assert(underlying_type(ColorMode::SrcAlpha) == GL_SRC_ALPHA, "OpenGL enum mismatch");
+static_assert(underlying_type(ColorMode::OneMinusSrcAlpha) == GL_ONE_MINUS_SRC_ALPHA, "OpenGL enum mismatch");
+static_assert(underlying_type(ColorMode::DstAlpha) == GL_DST_ALPHA, "OpenGL enum mismatch");
+static_assert(underlying_type(ColorMode::OneMinusDstAlpha) == GL_ONE_MINUS_DST_ALPHA, "OpenGL enum mismatch");
+static_assert(underlying_type(ColorMode::ConstantColor) == GL_CONSTANT_COLOR, "OpenGL enum mismatch");
+static_assert(underlying_type(ColorMode::OneMinusConstantColor) == GL_ONE_MINUS_CONSTANT_COLOR, "OpenGL enum mismatch");
+static_assert(underlying_type(ColorMode::ConstantAlpha) == GL_CONSTANT_ALPHA, "OpenGL enum mismatch");
+static_assert(underlying_type(ColorMode::OneMinusConstantAlpha) == GL_ONE_MINUS_CONSTANT_ALPHA, "OpenGL enum mismatch");
+static_assert(underlying_type(ColorMode::SrcAlphaSaturate) == GL_SRC_ALPHA_SATURATE, "OpenGL enum mismatch");
+
+static_assert(underlying_type(ColorMode::Zero) == GL_ZERO, "OpenGL enum mismatch");
+static_assert(underlying_type(ColorMode::One) == GL_ONE, "OpenGL enum mismatch");
+static_assert(underlying_type(ColorMode::SrcColor) == GL_SRC_COLOR, "OpenGL enum mismatch");
+static_assert(underlying_type(ColorMode::OneMinusSrcColor) == GL_ONE_MINUS_SRC_COLOR, "OpenGL enum mismatch");
+static_assert(underlying_type(ColorMode::DstColor) == GL_DST_COLOR, "OpenGL enum mismatch");
+static_assert(underlying_type(ColorMode::OneMinusDstColor) == GL_ONE_MINUS_DST_COLOR, "OpenGL enum mismatch");
+static_assert(underlying_type(ColorMode::SrcAlpha) == GL_SRC_ALPHA, "OpenGL enum mismatch");
+static_assert(underlying_type(ColorMode::OneMinusSrcAlpha) == GL_ONE_MINUS_SRC_ALPHA, "OpenGL enum mismatch");
+static_assert(underlying_type(ColorMode::DstAlpha) == GL_DST_ALPHA, "OpenGL enum mismatch");
+static_assert(underlying_type(ColorMode::OneMinusDstAlpha) == GL_ONE_MINUS_DST_ALPHA, "OpenGL enum mismatch");
+static_assert(underlying_type(ColorMode::ConstantColor) == GL_CONSTANT_COLOR, "OpenGL enum mismatch");
+static_assert(underlying_type(ColorMode::OneMinusConstantColor) == GL_ONE_MINUS_CONSTANT_COLOR, "OpenGL enum mismatch");
+static_assert(underlying_type(ColorMode::ConstantAlpha) == GL_CONSTANT_ALPHA, "OpenGL enum mismatch");
+static_assert(underlying_type(ColorMode::OneMinusConstantAlpha) == GL_ONE_MINUS_CONSTANT_ALPHA, "OpenGL enum mismatch");
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/gl/color_mode.hpp b/src/mbgl/gl/color_mode.hpp
new file mode 100644
index 0000000000..e73c8737eb
--- /dev/null
+++ b/src/mbgl/gl/color_mode.hpp
@@ -0,0 +1,95 @@
+#pragma once
+
+#include <mbgl/util/variant.hpp>
+#include <mbgl/util/color.hpp>
+
+namespace mbgl {
+namespace gl {
+
+class ColorMode {
+public:
+ enum class BlendEquation {
+ Add = 0x8006,
+ Subtract = 0x800A,
+ ReverseSubtract = 0x800B
+ };
+
+ enum BlendFactor {
+ Zero = 0x0000,
+ One = 0x0001,
+ SrcColor = 0x0300,
+ OneMinusSrcColor = 0x0301,
+ SrcAlpha = 0x0302,
+ OneMinusSrcAlpha = 0x0303,
+ DstAlpha = 0x0304,
+ OneMinusDstAlpha = 0x0305,
+ DstColor = 0x0306,
+ OneMinusDstColor = 0x0307,
+ SrcAlphaSaturate = 0x0308,
+ ConstantColor = 0x8001,
+ OneMinusConstantColor = 0x8002,
+ ConstantAlpha = 0x8003,
+ OneMinusConstantAlpha = 0x8004
+ };
+
+ template <BlendEquation E>
+ struct ConstantBlend {
+ static constexpr BlendEquation equation = E;
+ static constexpr BlendFactor srcFactor = One;
+ static constexpr BlendFactor dstFactor = One;
+ };
+
+ template <BlendEquation E>
+ struct LinearBlend {
+ static constexpr BlendEquation equation = E;
+ BlendFactor srcFactor;
+ BlendFactor dstFactor;
+ };
+
+ struct Replace {
+ static constexpr BlendEquation equation = BlendEquation::Add;
+ static constexpr BlendFactor srcFactor = One;
+ static constexpr BlendFactor dstFactor = One;
+ };
+
+ using Add = LinearBlend<BlendEquation::Add>;
+ using Subtract = LinearBlend<BlendEquation::Subtract>;
+ using ReverseSubtract = LinearBlend<BlendEquation::ReverseSubtract>;
+
+ using BlendFunction = variant<
+ Replace,
+ Add,
+ Subtract,
+ ReverseSubtract>;
+
+ BlendFunction blendFunction;
+ Color blendColor;
+
+ struct Mask {
+ bool r;
+ bool g;
+ bool b;
+ bool a;
+ };
+
+ Mask mask;
+
+ static ColorMode disabled() {
+ return ColorMode { Replace(), {}, { false, false, false, false } };
+ }
+
+ static ColorMode unblended() {
+ return ColorMode { Replace(), {}, { true, true, true, true } };
+ }
+
+ static ColorMode alphaBlended() {
+ return ColorMode { Add { One, OneMinusSrcAlpha }, {}, { true, true, true, true } };
+ }
+};
+
+constexpr bool operator!=(const ColorMode::Mask& a, const ColorMode::Mask& b) {
+ return a.r != b.r || a.g != b.g || a.b != b.b || a.a != b.a;
+}
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp
index 23b28a15df..5048ffcd66 100644
--- a/src/mbgl/gl/context.cpp
+++ b/src/mbgl/gl/context.cpp
@@ -3,10 +3,25 @@
#include <mbgl/gl/gl.hpp>
#include <mbgl/gl/vertex_array.hpp>
#include <mbgl/util/traits.hpp>
+#include <mbgl/util/std.hpp>
+#include <mbgl/util/logging.hpp>
+
+#include <cstring>
namespace mbgl {
namespace gl {
+static_assert(underlying_type(ShaderType::Vertex) == GL_VERTEX_SHADER, "OpenGL type mismatch");
+static_assert(underlying_type(ShaderType::Fragment) == GL_FRAGMENT_SHADER, "OpenGL type mismatch");
+
+static_assert(underlying_type(PrimitiveType::Points) == GL_POINTS, "OpenGL type mismatch");
+static_assert(underlying_type(PrimitiveType::Lines) == GL_LINES, "OpenGL type mismatch");
+static_assert(underlying_type(PrimitiveType::LineLoop) == GL_LINE_LOOP, "OpenGL type mismatch");
+static_assert(underlying_type(PrimitiveType::LineStrip) == GL_LINE_STRIP, "OpenGL type mismatch");
+static_assert(underlying_type(PrimitiveType::Triangles) == GL_TRIANGLES, "OpenGL type mismatch");
+static_assert(underlying_type(PrimitiveType::TriangleStrip) == GL_TRIANGLE_STRIP, "OpenGL type mismatch");
+static_assert(underlying_type(PrimitiveType::TriangleFan) == GL_TRIANGLE_FAN, "OpenGL type mismatch");
+
static_assert(std::is_same<ProgramID, GLuint>::value, "OpenGL type mismatch");
static_assert(std::is_same<ShaderID, GLuint>::value, "OpenGL type mismatch");
static_assert(std::is_same<BufferID, GLuint>::value, "OpenGL type mismatch");
@@ -15,81 +30,66 @@ static_assert(std::is_same<VertexArrayID, GLuint>::value, "OpenGL type mismatch"
static_assert(std::is_same<FramebufferID, GLuint>::value, "OpenGL type mismatch");
static_assert(std::is_same<RenderbufferID, GLuint>::value, "OpenGL type mismatch");
-static_assert(std::is_same<StencilValue, GLint>::value, "OpenGL type mismatch");
-static_assert(std::is_same<StencilMaskValue, GLuint>::value, "OpenGL type mismatch");
-
-static_assert(underlying_type(StencilTestFunction::Never) == GL_NEVER, "OpenGL enum mismatch");
-static_assert(underlying_type(StencilTestFunction::Less) == GL_LESS, "OpenGL enum mismatch");
-static_assert(underlying_type(StencilTestFunction::Equal) == GL_EQUAL, "OpenGL enum mismatch");
-static_assert(underlying_type(StencilTestFunction::LessEqual) == GL_LEQUAL, "OpenGL enum mismatch");
-static_assert(underlying_type(StencilTestFunction::Greater) == GL_GREATER, "OpenGL enum mismatch");
-static_assert(underlying_type(StencilTestFunction::NotEqual) == GL_NOTEQUAL, "OpenGL enum mismatch");
-static_assert(underlying_type(StencilTestFunction::GreaterEqual) == GL_GEQUAL, "OpenGL enum mismatch");
-static_assert(underlying_type(StencilTestFunction::Always) == GL_ALWAYS, "OpenGL enum mismatch");
-
-static_assert(underlying_type(StencilTestOperation::Keep) == GL_KEEP, "OpenGL enum mismatch");
-static_assert(underlying_type(StencilTestOperation::Zero) == GL_ZERO, "OpenGL enum mismatch");
-static_assert(underlying_type(StencilTestOperation::Replace) == GL_REPLACE, "OpenGL enum mismatch");
-static_assert(underlying_type(StencilTestOperation::Increment) == GL_INCR, "OpenGL enum mismatch");
-static_assert(underlying_type(StencilTestOperation::IncrementWrap) == GL_INCR_WRAP, "OpenGL enum mismatch");
-static_assert(underlying_type(StencilTestOperation::Decrement) == GL_DECR, "OpenGL enum mismatch");
-static_assert(underlying_type(StencilTestOperation::DecrementWrap) == GL_DECR_WRAP, "OpenGL enum mismatch");
-static_assert(underlying_type(StencilTestOperation::Invert) == GL_INVERT, "OpenGL enum mismatch");
-
-static_assert(underlying_type(DepthTestFunction::Never) == GL_NEVER, "OpenGL enum mismatch");
-static_assert(underlying_type(DepthTestFunction::Less) == GL_LESS, "OpenGL enum mismatch");
-static_assert(underlying_type(DepthTestFunction::Equal) == GL_EQUAL, "OpenGL enum mismatch");
-static_assert(underlying_type(DepthTestFunction::LessEqual) == GL_LEQUAL, "OpenGL enum mismatch");
-static_assert(underlying_type(DepthTestFunction::Greater) == GL_GREATER, "OpenGL enum mismatch");
-static_assert(underlying_type(DepthTestFunction::NotEqual) == GL_NOTEQUAL, "OpenGL enum mismatch");
-static_assert(underlying_type(DepthTestFunction::GreaterEqual) == GL_GEQUAL, "OpenGL enum mismatch");
-static_assert(underlying_type(DepthTestFunction::Always) == GL_ALWAYS, "OpenGL enum mismatch");
-
-static_assert(underlying_type(BlendSourceFactor::Zero) == GL_ZERO, "OpenGL enum mismatch");
-static_assert(underlying_type(BlendSourceFactor::One) == GL_ONE, "OpenGL enum mismatch");
-static_assert(underlying_type(BlendSourceFactor::SrcColor) == GL_SRC_COLOR, "OpenGL enum mismatch");
-static_assert(underlying_type(BlendSourceFactor::OneMinusSrcColor) == GL_ONE_MINUS_SRC_COLOR, "OpenGL enum mismatch");
-static_assert(underlying_type(BlendSourceFactor::DstColor) == GL_DST_COLOR, "OpenGL enum mismatch");
-static_assert(underlying_type(BlendSourceFactor::OneMinusDstColor) == GL_ONE_MINUS_DST_COLOR, "OpenGL enum mismatch");
-static_assert(underlying_type(BlendSourceFactor::SrcAlpha) == GL_SRC_ALPHA, "OpenGL enum mismatch");
-static_assert(underlying_type(BlendSourceFactor::OneMinusSrcAlpha) == GL_ONE_MINUS_SRC_ALPHA, "OpenGL enum mismatch");
-static_assert(underlying_type(BlendSourceFactor::DstAlpha) == GL_DST_ALPHA, "OpenGL enum mismatch");
-static_assert(underlying_type(BlendSourceFactor::OneMinusDstAlpha) == GL_ONE_MINUS_DST_ALPHA, "OpenGL enum mismatch");
-static_assert(underlying_type(BlendSourceFactor::ConstantColor) == GL_CONSTANT_COLOR, "OpenGL enum mismatch");
-static_assert(underlying_type(BlendSourceFactor::OneMinusConstantColor) == GL_ONE_MINUS_CONSTANT_COLOR, "OpenGL enum mismatch");
-static_assert(underlying_type(BlendSourceFactor::ConstantAlpha) == GL_CONSTANT_ALPHA, "OpenGL enum mismatch");
-static_assert(underlying_type(BlendSourceFactor::OneMinusConstantAlpha) == GL_ONE_MINUS_CONSTANT_ALPHA, "OpenGL enum mismatch");
-static_assert(underlying_type(BlendSourceFactor::SrcAlphaSaturate) == GL_SRC_ALPHA_SATURATE, "OpenGL enum mismatch");
-
-static_assert(underlying_type(BlendDestinationFactor::Zero) == GL_ZERO, "OpenGL enum mismatch");
-static_assert(underlying_type(BlendDestinationFactor::One) == GL_ONE, "OpenGL enum mismatch");
-static_assert(underlying_type(BlendDestinationFactor::SrcColor) == GL_SRC_COLOR, "OpenGL enum mismatch");
-static_assert(underlying_type(BlendDestinationFactor::OneMinusSrcColor) == GL_ONE_MINUS_SRC_COLOR, "OpenGL enum mismatch");
-static_assert(underlying_type(BlendDestinationFactor::DstColor) == GL_DST_COLOR, "OpenGL enum mismatch");
-static_assert(underlying_type(BlendDestinationFactor::OneMinusDstColor) == GL_ONE_MINUS_DST_COLOR, "OpenGL enum mismatch");
-static_assert(underlying_type(BlendDestinationFactor::SrcAlpha) == GL_SRC_ALPHA, "OpenGL enum mismatch");
-static_assert(underlying_type(BlendDestinationFactor::OneMinusSrcAlpha) == GL_ONE_MINUS_SRC_ALPHA, "OpenGL enum mismatch");
-static_assert(underlying_type(BlendDestinationFactor::DstAlpha) == GL_DST_ALPHA, "OpenGL enum mismatch");
-static_assert(underlying_type(BlendDestinationFactor::OneMinusDstAlpha) == GL_ONE_MINUS_DST_ALPHA, "OpenGL enum mismatch");
-static_assert(underlying_type(BlendDestinationFactor::ConstantColor) == GL_CONSTANT_COLOR, "OpenGL enum mismatch");
-static_assert(underlying_type(BlendDestinationFactor::OneMinusConstantColor) == GL_ONE_MINUS_CONSTANT_COLOR, "OpenGL enum mismatch");
-static_assert(underlying_type(BlendDestinationFactor::ConstantAlpha) == GL_CONSTANT_ALPHA, "OpenGL enum mismatch");
-static_assert(underlying_type(BlendDestinationFactor::OneMinusConstantAlpha) == GL_ONE_MINUS_CONSTANT_ALPHA, "OpenGL enum mismatch");
+static_assert(std::is_same<std::underlying_type_t<TextureFormat>, GLenum>::value, "OpenGL type mismatch");
+static_assert(underlying_type(TextureFormat::RGBA) == GL_RGBA, "OpenGL type mismatch");
+static_assert(underlying_type(TextureFormat::Alpha) == GL_ALPHA, "OpenGL type mismatch");
Context::~Context() {
reset();
}
-UniqueProgram Context::createProgram() {
- return UniqueProgram{ MBGL_CHECK_ERROR(glCreateProgram()), { this } };
+UniqueShader Context::createShader(ShaderType type, const std::string& source) {
+ UniqueShader result { MBGL_CHECK_ERROR(glCreateShader(static_cast<GLenum>(type))), { this } };
+
+ const GLchar* sources = source.data();
+ const GLsizei lengths = static_cast<GLsizei>(source.length());
+ MBGL_CHECK_ERROR(glShaderSource(result, 1, &sources, &lengths));
+ MBGL_CHECK_ERROR(glCompileShader(result));
+
+ GLint status = 0;
+ MBGL_CHECK_ERROR(glGetShaderiv(result, GL_COMPILE_STATUS, &status));
+ if (status != 0) {
+ return result;
+ }
+
+ GLint logLength;
+ MBGL_CHECK_ERROR(glGetShaderiv(result, GL_INFO_LOG_LENGTH, &logLength));
+ if (logLength > 0) {
+ const auto log = std::make_unique<GLchar[]>(logLength);
+ MBGL_CHECK_ERROR(glGetShaderInfoLog(result, logLength, &logLength, log.get()));
+ Log::Error(Event::Shader, "Shader failed to compile: %s", log.get());
+ }
+
+ throw std::runtime_error("shader failed to compile");
}
-UniqueShader Context::createVertexShader() {
- return UniqueShader{ MBGL_CHECK_ERROR(glCreateShader(GL_VERTEX_SHADER)), { this } };
+UniqueProgram Context::createProgram(ShaderID vertexShader, ShaderID fragmentShader) {
+ UniqueProgram result { MBGL_CHECK_ERROR(glCreateProgram()), { this } };
+
+ MBGL_CHECK_ERROR(glAttachShader(result, vertexShader));
+ MBGL_CHECK_ERROR(glAttachShader(result, fragmentShader));
+
+ return result;
}
-UniqueShader Context::createFragmentShader() {
- return UniqueShader{ MBGL_CHECK_ERROR(glCreateShader(GL_FRAGMENT_SHADER)), { this } };
+void Context::linkProgram(ProgramID program_) {
+ MBGL_CHECK_ERROR(glLinkProgram(program_));
+
+ GLint status;
+ MBGL_CHECK_ERROR(glGetProgramiv(program_, GL_LINK_STATUS, &status));
+ if (status == GL_TRUE) {
+ return;
+ }
+
+ GLint logLength;
+ MBGL_CHECK_ERROR(glGetProgramiv(program_, GL_INFO_LOG_LENGTH, &logLength));
+ const auto log = std::make_unique<GLchar[]>(logLength);
+ if (logLength > 0) {
+ MBGL_CHECK_ERROR(glGetProgramInfoLog(program_, logLength, &logLength, log.get()));
+ Log::Error(Event::Shader, "Program failed to link: %s", log.get());
+ }
+
+ throw std::runtime_error("program failed to link");
}
UniqueBuffer Context::createVertexBuffer(const void* data, std::size_t size) {
@@ -105,21 +105,12 @@ 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 } };
+ vertexArrayObject = 0;
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() {
if (pooledTextures.empty()) {
pooledTextures.resize(TextureMax);
@@ -131,31 +122,60 @@ UniqueTexture Context::createTexture() {
return UniqueTexture{ std::move(id), { this } };
}
-UniqueVertexArray Context::createVertexArray() {
- VertexArrayID id = 0;
- MBGL_CHECK_ERROR(gl::GenVertexArrays(1, &id));
- return UniqueVertexArray{ std::move(id), { this } };
-}
-
UniqueFramebuffer Context::createFramebuffer() {
FramebufferID id = 0;
MBGL_CHECK_ERROR(glGenFramebuffers(1, &id));
return UniqueFramebuffer{ std::move(id), { this } };
}
-UniqueRenderbuffer Context::createRenderbuffer(const RenderbufferType type,
- const uint16_t width,
- const uint16_t height) {
+UniqueRenderbuffer Context::createRenderbuffer(const RenderbufferType type, const Size size) {
RenderbufferID id = 0;
MBGL_CHECK_ERROR(glGenRenderbuffers(1, &id));
UniqueRenderbuffer renderbuffer{ std::move(id), { this } };
bindRenderbuffer = renderbuffer;
MBGL_CHECK_ERROR(
- glRenderbufferStorage(GL_RENDERBUFFER, static_cast<GLenum>(type), width, height));
+ glRenderbufferStorage(GL_RENDERBUFFER, static_cast<GLenum>(type), size.width, size.height));
return renderbuffer;
}
+std::unique_ptr<uint8_t[]> Context::readFramebuffer(const Size size, const TextureFormat format, const bool flip) {
+ const size_t stride = size.width * (format == TextureFormat::RGBA ? 4 : 1);
+ auto data = std::make_unique<uint8_t[]>(stride * size.height);
+
+#if not MBGL_USE_GLES2
+ // When reading data from the framebuffer, make sure that we are storing the values
+ // tightly packed into the buffer to avoid buffer overruns.
+ pixelStorePack = { 1 };
+#endif // MBGL_USE_GLES2
+
+ MBGL_CHECK_ERROR(glReadPixels(0, 0, size.width, size.height, static_cast<GLenum>(format),
+ GL_UNSIGNED_BYTE, data.get()));
+
+ if (flip) {
+ auto tmp = std::make_unique<uint8_t[]>(stride);
+ uint8_t* rgba = data.get();
+ for (int i = 0, j = size.height - 1; i < j; i++, j--) {
+ std::memcpy(tmp.get(), rgba + i * stride, stride);
+ std::memcpy(rgba + i * stride, rgba + j * stride, stride);
+ std::memcpy(rgba + j * stride, tmp.get(), stride);
+ }
+ }
+
+ return data;
+}
+
+#if not MBGL_USE_GLES2
+void Context::drawPixels(const Size size, const void* data, TextureFormat format) {
+ pixelStoreUnpack = { 1 };
+ if (format != TextureFormat::RGBA) {
+ format = static_cast<TextureFormat>(GL_LUMINANCE);
+ }
+ MBGL_CHECK_ERROR(glDrawPixels(size.width, size.height, static_cast<GLenum>(GL_LUMINANCE),
+ GL_UNSIGNED_BYTE, data));
+}
+#endif // MBGL_USE_GLES2
+
namespace {
void checkFramebuffer() {
@@ -251,35 +271,62 @@ Framebuffer Context::createFramebuffer(const Texture& color) {
}
UniqueTexture
-Context::createTexture(uint16_t width, uint16_t height, const void* data, TextureUnit unit) {
+Context::createTexture(const Size size, const void* data, TextureFormat format, TextureUnit unit) {
auto obj = createTexture();
- activeTexture = unit;
- texture[unit] = obj;
+ updateTexture(obj, size, data, format, unit);
+ // We are using clamp to edge here since OpenGL ES doesn't allow GL_REPEAT on NPOT textures.
+ // We use those when the pixelRatio isn't a power of two, e.g. on iPhone 6 Plus.
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
- MBGL_CHECK_ERROR(
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data));
return obj;
}
+void Context::updateTexture(
+ TextureID id, const Size size, const void* data, TextureFormat format, TextureUnit unit) {
+ activeTexture = unit;
+ texture[unit] = id;
+ MBGL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, static_cast<GLenum>(format), size.width,
+ size.height, 0, static_cast<GLenum>(format), GL_UNSIGNED_BYTE,
+ data));
+}
+
void Context::bindTexture(Texture& obj,
TextureUnit unit,
TextureFilter filter,
- TextureMipMap mipmap) {
- if (filter != obj.filter || mipmap != obj.mipmap) {
+ TextureMipMap mipmap,
+ TextureWrap wrapX,
+ TextureWrap wrapY) {
+ if (filter != obj.filter || mipmap != obj.mipmap || wrapX != obj.wrapX || wrapY != obj.wrapY) {
activeTexture = unit;
texture[unit] = obj.texture;
- MBGL_CHECK_ERROR(glTexParameteri(
- GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
- filter == TextureFilter::Linear
- ? (mipmap == TextureMipMap::Yes ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR)
- : (mipmap == TextureMipMap::Yes ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST)));
- MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
- filter == TextureFilter::Linear ? GL_LINEAR : GL_NEAREST));
- obj.filter = filter;
- obj.mipmap = mipmap;
+
+ if (filter != obj.filter || mipmap != obj.mipmap) {
+ MBGL_CHECK_ERROR(glTexParameteri(
+ GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ filter == TextureFilter::Linear
+ ? (mipmap == TextureMipMap::Yes ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR)
+ : (mipmap == TextureMipMap::Yes ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST)));
+ MBGL_CHECK_ERROR(
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+ filter == TextureFilter::Linear ? GL_LINEAR : GL_NEAREST));
+ obj.filter = filter;
+ obj.mipmap = mipmap;
+ }
+ if (wrapX != obj.wrapX) {
+
+ MBGL_CHECK_ERROR(
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
+ wrapX == TextureWrap::Clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT));
+ obj.wrapX = wrapX;
+ }
+ if (wrapY != obj.wrapY) {
+ MBGL_CHECK_ERROR(
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
+ wrapY == TextureWrap::Clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT));
+ obj.wrapY = wrapY;
+ }
} else if (texture[unit] != obj.texture) {
// We are checking first to avoid setting the active texture without a subsequent
// texture bind.
@@ -306,6 +353,7 @@ void Context::setDirtyState() {
depthTest.setDirty();
depthFunc.setDirty();
blend.setDirty();
+ blendEquation.setDirty();
blendFunc.setDirty();
blendColor.setDirty();
colorMask.setDirty();
@@ -316,8 +364,13 @@ void Context::setDirtyState() {
lineWidth.setDirty();
activeTexture.setDirty();
#if not MBGL_USE_GLES2
+ pointSize.setDirty();
pixelZoom.setDirty();
rasterPos.setDirty();
+ pixelStorePack.setDirty();
+ pixelStoreUnpack.setDirty();
+ pixelTransferDepth.setDirty();
+ pixelTransferStencil.setDirty();
#endif // MBGL_USE_GLES2
for (auto& tex : texture) {
tex.setDirty();
@@ -327,6 +380,153 @@ void Context::setDirtyState() {
vertexArrayObject.setDirty();
}
+void Context::clear(optional<mbgl::Color> color,
+ optional<float> depth,
+ optional<int32_t> stencil) {
+ GLbitfield mask = 0;
+
+ if (color) {
+ mask |= GL_COLOR_BUFFER_BIT;
+ clearColor = *color;
+ colorMask = { true, true, true, true };
+ }
+
+ if (depth) {
+ mask |= GL_DEPTH_BUFFER_BIT;
+ clearDepth = *depth;
+ depthMask = true;
+ }
+
+ if (stencil) {
+ mask |= GL_STENCIL_BUFFER_BIT;
+ clearStencil = *stencil;
+ stencilMask = 0xFF;
+ }
+
+ MBGL_CHECK_ERROR(glClear(mask));
+}
+
+#if not MBGL_USE_GLES2
+PrimitiveType Context::operator()(const Points& points) {
+ pointSize = points.pointSize;
+ return PrimitiveType::Points;
+}
+#else
+PrimitiveType Context::operator()(const Points&) {
+ return PrimitiveType::Points;
+}
+#endif // MBGL_USE_GLES2
+
+PrimitiveType Context::operator()(const Lines& lines) {
+ lineWidth = lines.lineWidth;
+ return PrimitiveType::Lines;
+}
+
+PrimitiveType Context::operator()(const LineStrip& lineStrip) {
+ lineWidth = lineStrip.lineWidth;
+ return PrimitiveType::LineStrip;
+}
+
+PrimitiveType Context::operator()(const Triangles&) {
+ return PrimitiveType::Triangles;
+}
+
+PrimitiveType Context::operator()(const TriangleStrip&) {
+ return PrimitiveType::TriangleStrip;
+}
+
+void Context::setDepthMode(const DepthMode& depth) {
+ if (depth.func == DepthMode::Always && !depth.mask) {
+ depthTest = false;
+ } else {
+ depthTest = true;
+ depthFunc = depth.func;
+ depthMask = depth.mask;
+ depthRange = depth.range;
+ }
+}
+
+void Context::setStencilMode(const StencilMode& stencil) {
+ if (stencil.test.is<StencilMode::Always>() && !stencil.mask) {
+ stencilTest = false;
+ } else {
+ stencilTest = true;
+ stencilMask = stencil.mask;
+ stencilOp = { stencil.fail, stencil.depthFail, stencil.pass };
+ apply_visitor([&] (const auto& test) {
+ stencilFunc = { test.func, stencil.ref, test.mask };
+ }, stencil.test);
+ }
+}
+
+void Context::setColorMode(const ColorMode& color) {
+ if (color.blendFunction.is<ColorMode::Replace>()) {
+ blend = false;
+ } else {
+ blend = true;
+ blendColor = color.blendColor;
+ apply_visitor([&] (const auto& blendFunction) {
+ blendEquation = ColorMode::BlendEquation(blendFunction.equation);
+ blendFunc = { blendFunction.srcFactor, blendFunction.dstFactor };
+ }, color.blendFunction);
+ }
+
+ colorMask = color.mask;
+}
+
+void Context::draw(const Drawable& drawable) {
+ if (drawable.segments.empty()) {
+ return;
+ }
+
+ PrimitiveType primitiveType = apply_visitor([&] (auto m) { return (*this)(m); }, drawable.drawMode);
+
+ setDepthMode(drawable.depthMode);
+ setStencilMode(drawable.stencilMode);
+ setColorMode(drawable.colorMode);
+
+ program = drawable.program;
+
+ drawable.bindUniforms();
+
+ for (const auto& segment : drawable.segments) {
+ auto needAttributeBindings = [&] () {
+ if (!gl::GenVertexArrays || !gl::BindVertexArray) {
+ return true;
+ }
+
+ if (segment.vao) {
+ vertexArrayObject = *segment.vao;
+ return false;
+ }
+
+ VertexArrayID id = 0;
+ MBGL_CHECK_ERROR(gl::GenVertexArrays(1, &id));
+ vertexArrayObject = id;
+ segment.vao = UniqueVertexArray(std::move(id), { this });
+
+ // If we are initializing a new VAO, we need to force the buffers
+ // to be rebound. VAOs don't inherit the existing buffer bindings.
+ vertexBuffer.setDirty();
+ elementBuffer.setDirty();
+
+ return true;
+ };
+
+ if (needAttributeBindings()) {
+ vertexBuffer = drawable.vertexBuffer;
+ elementBuffer = drawable.indexBuffer;
+ drawable.bindAttributes(segment.vertexOffset);
+ }
+
+ MBGL_CHECK_ERROR(glDrawElements(
+ static_cast<GLenum>(primitiveType),
+ static_cast<GLsizei>(segment.indexLength),
+ GL_UNSIGNED_SHORT,
+ reinterpret_cast<GLvoid*>(sizeof(uint16_t) * segment.indexOffset)));
+ }
+}
+
void Context::performCleanup() {
for (auto id : abandonedPrograms) {
if (program == id) {
diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp
index cf8bb2658b..093afa20ed 100644
--- a/src/mbgl/gl/context.hpp
+++ b/src/mbgl/gl/context.hpp
@@ -8,12 +8,21 @@
#include <mbgl/gl/framebuffer.hpp>
#include <mbgl/gl/vertex_buffer.hpp>
#include <mbgl/gl/index_buffer.hpp>
-#include <mbgl/gl/attribute.hpp>
+#include <mbgl/gl/types.hpp>
+#include <mbgl/gl/draw_mode.hpp>
+#include <mbgl/gl/depth_mode.hpp>
+#include <mbgl/gl/stencil_mode.hpp>
+#include <mbgl/gl/color_mode.hpp>
+#include <mbgl/gl/segment.hpp>
#include <mbgl/util/noncopyable.hpp>
+
+#include <functional>
#include <memory>
#include <vector>
#include <array>
+#include <string>
+#include <unordered_map>
namespace mbgl {
@@ -27,32 +36,31 @@ class Context : private util::noncopyable {
public:
~Context();
- UniqueProgram createProgram();
- UniqueShader createVertexShader();
- UniqueShader createFragmentShader();
+ UniqueShader createShader(ShaderType type, const std::string& source);
+ UniqueProgram createProgram(ShaderID vertexShader, ShaderID fragmentShader);
+ void linkProgram(ProgramID);
UniqueTexture createTexture();
- UniqueVertexArray createVertexArray();
- template <class V>
- VertexBuffer<V> createVertexBuffer(std::vector<V>&& v) {
- return VertexBuffer<V> {
- v.size(),
- createVertexBuffer(v.data(), v.size() * sizeof(V))
+ template <class Vertex, class DrawMode>
+ VertexBuffer<Vertex, DrawMode> createVertexBuffer(VertexVector<Vertex, DrawMode>&& v) {
+ return VertexBuffer<Vertex, DrawMode> {
+ v.vertexSize(),
+ createVertexBuffer(v.data(), v.byteSize())
};
}
- template <class P>
- IndexBuffer<P> createIndexBuffer(std::vector<P>&& v) {
- return IndexBuffer<P> {
- createIndexBuffer(v.data(), v.size() * sizeof(P))
+ template <class DrawMode>
+ IndexBuffer<DrawMode> createIndexBuffer(IndexVector<DrawMode>&& v) {
+ return IndexBuffer<DrawMode> {
+ createIndexBuffer(v.data(), v.byteSize())
};
}
template <RenderbufferType type>
- Renderbuffer<type> createRenderbuffer(const std::array<uint16_t, 2>& size) {
+ Renderbuffer<type> createRenderbuffer(const Size size) {
static_assert(type == RenderbufferType::RGBA || type == RenderbufferType::DepthStencil,
"invalid renderbuffer type");
- return { size, createRenderbuffer(type, size[0], size[1]) };
+ return { size, createRenderbuffer(type, size) };
}
Framebuffer createFramebuffer(const Renderbuffer<RenderbufferType::RGBA>&,
@@ -62,30 +70,73 @@ public:
const Renderbuffer<RenderbufferType::DepthStencil>&);
Framebuffer createFramebuffer(const Texture&);
+ template <typename Image,
+ TextureFormat format = Image::channels == 4 ? TextureFormat::RGBA
+ : TextureFormat::Alpha>
+ Image readFramebuffer(const Size size, bool flip = true) {
+ static_assert(Image::channels == (format == TextureFormat::RGBA ? 4 : 1),
+ "image format mismatch");
+ return { size, readFramebuffer(size, format, flip) };
+ }
+
+#if not MBGL_USE_GLES2
+ template <typename Image>
+ void drawPixels(const Image& image) {
+ auto format = image.channels == 4 ? TextureFormat::RGBA : TextureFormat::Alpha;
+ drawPixels(image.size, image.data.get(), format);
+ }
+#endif // MBGL_USE_GLES2
+
// Create a texture from an image with data.
template <typename Image>
Texture createTexture(const Image& image, TextureUnit unit = 0) {
- return { {{ image.width, image.height }},
- createTexture(image.width, image.height, image.data.get(), unit) };
+ auto format = image.channels == 4 ? TextureFormat::RGBA : TextureFormat::Alpha;
+ return { image.size, createTexture(image.size, image.data.get(), format, unit) };
+ }
+
+ template <typename Image>
+ void updateTexture(Texture& obj, const Image& image, TextureUnit unit = 0) {
+ auto format = image.channels == 4 ? TextureFormat::RGBA : TextureFormat::Alpha;
+ updateTexture(obj.texture.get(), image.size, image.data.get(), format, unit);
+ obj.size = image.size;
}
// Creates an empty texture with the specified dimensions.
- Texture createTexture(const std::array<uint16_t, 2>& size, TextureUnit unit = 0) {
- return { size, createTexture(size[0], size[1], nullptr, unit) };
+ Texture createTexture(const Size size,
+ TextureFormat format = TextureFormat::RGBA,
+ TextureUnit unit = 0) {
+ return { size, createTexture(size, nullptr, format, unit) };
}
void bindTexture(Texture&,
TextureUnit = 0,
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);
- }
- }
+ TextureMipMap = TextureMipMap::No,
+ TextureWrap wrapX = TextureWrap::Clamp,
+ TextureWrap wrapY = TextureWrap::Clamp);
+
+ void clear(optional<mbgl::Color> color,
+ optional<float> depth,
+ optional<int32_t> stencil);
+
+ struct Drawable {
+ DrawMode drawMode;
+ DepthMode depthMode;
+ StencilMode stencilMode;
+ ColorMode colorMode;
+ gl::ProgramID program;
+ gl::BufferID vertexBuffer;
+ gl::BufferID indexBuffer;
+ const std::vector<Segment>& segments;
+ std::function<void ()> bindUniforms;
+ std::function<void (std::size_t)> bindAttributes;
+ };
+
+ void draw(const Drawable&);
+
+ void setDepthMode(const DepthMode&);
+ void setStencilMode(const StencilMode&);
+ void setColorMode(const ColorMode&);
// Actually remove the objects we marked as abandoned with the above methods.
// Only call this while the OpenGL context is exclusive to this thread.
@@ -107,6 +158,23 @@ public:
void setDirtyState();
+ State<value::ActiveTexture> activeTexture;
+ State<value::BindFramebuffer> bindFramebuffer;
+ State<value::Viewport> viewport;
+ std::array<State<value::BindTexture>, 2> texture;
+ State<value::BindVertexArray> vertexArrayObject;
+ State<value::Program> program;
+
+#if not MBGL_USE_GLES2
+ State<value::PixelZoom> pixelZoom;
+ State<value::RasterPos> rasterPos;
+ State<value::PixelStorePack> pixelStorePack;
+ State<value::PixelStoreUnpack> pixelStoreUnpack;
+ State<value::PixelTransferDepth> pixelTransferDepth;
+ State<value::PixelTransferStencil> pixelTransferStencil;
+#endif // MBGL_USE_GLES2
+
+private:
State<value::StencilFunc> stencilFunc;
State<value::StencilMask> stencilMask;
State<value::StencilTest> stencilTest;
@@ -116,34 +184,37 @@ public:
State<value::DepthTest> depthTest;
State<value::DepthFunc> depthFunc;
State<value::Blend> blend;
+ State<value::BlendEquation> blendEquation;
State<value::BlendFunc> blendFunc;
State<value::BlendColor> blendColor;
State<value::ColorMask> colorMask;
State<value::ClearDepth> clearDepth;
State<value::ClearColor> clearColor;
State<value::ClearStencil> clearStencil;
- State<value::Program> program;
State<value::LineWidth> lineWidth;
- State<value::ActiveTexture> activeTexture;
- State<value::BindFramebuffer> bindFramebuffer;
- State<value::Viewport> viewport;
State<value::BindRenderbuffer> bindRenderbuffer;
#if not MBGL_USE_GLES2
- State<value::PixelZoom> pixelZoom;
- State<value::RasterPos> rasterPos;
+ State<value::PointSize> pointSize;
#endif // MBGL_USE_GLES2
- std::array<State<value::BindTexture>, 2> texture;
State<value::BindVertexBuffer> vertexBuffer;
State<value::BindElementBuffer> elementBuffer;
- 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);
+ UniqueTexture createTexture(Size size, const void* data, TextureFormat, TextureUnit);
+ void updateTexture(TextureID, Size size, const void* data, TextureFormat, TextureUnit);
UniqueFramebuffer createFramebuffer();
- UniqueRenderbuffer createRenderbuffer(RenderbufferType, uint16_t width, uint16_t height);
- void bindAttribute(const AttributeBinding&, std::size_t stride, const int8_t* offset);
+ UniqueRenderbuffer createRenderbuffer(RenderbufferType, Size size);
+ std::unique_ptr<uint8_t[]> readFramebuffer(Size, TextureFormat, bool flip);
+#if not MBGL_USE_GLES2
+ void drawPixels(Size size, const void* data, TextureFormat);
+#endif // MBGL_USE_GLES2
+
+ PrimitiveType operator()(const Points&);
+ PrimitiveType operator()(const Lines&);
+ PrimitiveType operator()(const LineStrip&);
+ PrimitiveType operator()(const Triangles&);
+ PrimitiveType operator()(const TriangleStrip&);
friend detail::ProgramDeleter;
friend detail::ShaderDeleter;
diff --git a/src/mbgl/gl/debugging.cpp b/src/mbgl/gl/debugging.cpp
index 1d82b6afb0..8037fc5ef5 100644
--- a/src/mbgl/gl/debugging.cpp
+++ b/src/mbgl/gl/debugging.cpp
@@ -2,8 +2,8 @@
#include <mbgl/gl/debugging.hpp>
#include <mbgl/gl/gl.hpp>
#include <mbgl/gl/extension.hpp>
-#include <mbgl/platform/event.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/event.hpp>
+#include <mbgl/util/logging.hpp>
#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243
diff --git a/src/mbgl/gl/depth_mode.cpp b/src/mbgl/gl/depth_mode.cpp
new file mode 100644
index 0000000000..21af75a391
--- /dev/null
+++ b/src/mbgl/gl/depth_mode.cpp
@@ -0,0 +1,18 @@
+#include <mbgl/gl/depth_mode.hpp>
+#include <mbgl/gl/gl.hpp>
+#include <mbgl/util/traits.hpp>
+
+namespace mbgl {
+namespace gl {
+
+static_assert(underlying_type(DepthMode::Never) == GL_NEVER, "OpenGL enum mismatch");
+static_assert(underlying_type(DepthMode::Less) == GL_LESS, "OpenGL enum mismatch");
+static_assert(underlying_type(DepthMode::Equal) == GL_EQUAL, "OpenGL enum mismatch");
+static_assert(underlying_type(DepthMode::LessEqual) == GL_LEQUAL, "OpenGL enum mismatch");
+static_assert(underlying_type(DepthMode::Greater) == GL_GREATER, "OpenGL enum mismatch");
+static_assert(underlying_type(DepthMode::NotEqual) == GL_NOTEQUAL, "OpenGL enum mismatch");
+static_assert(underlying_type(DepthMode::GreaterEqual) == GL_GEQUAL, "OpenGL enum mismatch");
+static_assert(underlying_type(DepthMode::Always) == GL_ALWAYS, "OpenGL enum mismatch");
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/gl/depth_mode.hpp b/src/mbgl/gl/depth_mode.hpp
new file mode 100644
index 0000000000..37617e3c34
--- /dev/null
+++ b/src/mbgl/gl/depth_mode.hpp
@@ -0,0 +1,36 @@
+#pragma once
+
+#include <mbgl/util/range.hpp>
+
+namespace mbgl {
+namespace gl {
+
+class DepthMode {
+public:
+ enum Function {
+ Never = 0x0200,
+ Less = 0x0201,
+ Equal = 0x0202,
+ LessEqual = 0x0203,
+ Greater = 0x0204,
+ NotEqual = 0x0205,
+ GreaterEqual = 0x0206,
+ Always = 0x0207
+ };
+
+ enum Mask : bool {
+ ReadOnly = false,
+ ReadWrite = true
+ };
+
+ Function func;
+ Mask mask;
+ Range<float> range;
+
+ static DepthMode disabled() {
+ return DepthMode { Always, ReadOnly, { 0.0, 1.0 } };
+ }
+};
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/gl/draw_mode.hpp b/src/mbgl/gl/draw_mode.hpp
new file mode 100644
index 0000000000..ab86d5e469
--- /dev/null
+++ b/src/mbgl/gl/draw_mode.hpp
@@ -0,0 +1,76 @@
+#pragma once
+
+#include <mbgl/gl/primitives.hpp>
+#include <mbgl/util/variant.hpp>
+
+#include <cassert>
+
+namespace mbgl {
+namespace gl {
+
+class Points {
+public:
+ using Primitive = Point;
+ static constexpr std::size_t bufferGroupSize = 1;
+
+ explicit Points(float pointSize_) : pointSize(pointSize_) {}
+
+ float pointSize;
+};
+
+class Lines {
+public:
+ using Primitive = Line;
+ static constexpr std::size_t bufferGroupSize = 2;
+
+ explicit Lines(float lineWidth_) : lineWidth(lineWidth_) {
+ assert(lineWidth > 0);
+ }
+
+ float lineWidth;
+};
+
+class LineStrip {
+public:
+ // LineStrip is a form of "Line" rendering, but the element buffer
+ // cannot be grouped into logical elements beyond a single Point.
+ using Primitive = Line;
+ static constexpr std::size_t bufferGroupSize = 1;
+
+ explicit LineStrip(float lineWidth_) : lineWidth(lineWidth_) {
+ assert(lineWidth > 0);
+ }
+
+ float lineWidth;
+};
+
+class Triangles {
+public:
+ using Primitive = Triangle;
+ static constexpr std::size_t bufferGroupSize = 3;
+};
+
+class TriangleStrip {
+public:
+ // TriangleStrip is a form of "Triangle" rendering, but the element buffer
+ // cannot be grouped into logical elements beyond a single Point.
+ using Primitive = Triangle;
+ static constexpr std::size_t bufferGroupSize = 1;
+};
+
+// Special draw mode for use with VertexVector<Indexed, Vertex>, in which
+// case the true draw mode is denoted by the IndexVector type.
+class Indexed {
+public:
+ static constexpr std::size_t bufferGroupSize = 1;
+};
+
+using DrawMode = variant<
+ Points,
+ Lines,
+ LineStrip,
+ Triangles,
+ TriangleStrip>;
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/gl/extension.cpp b/src/mbgl/gl/extension.cpp
index ee94e8ecfd..e6b4d9156e 100644
--- a/src/mbgl/gl/extension.cpp
+++ b/src/mbgl/gl/extension.cpp
@@ -4,6 +4,7 @@
#include <mutex>
#include <string>
#include <vector>
+#include <cstring>
namespace mbgl {
namespace gl {
@@ -26,18 +27,14 @@ static std::once_flag initializeExtensionsOnce;
void InitializeExtensions(glProc (*getProcAddress)(const char*)) {
std::call_once(initializeExtensionsOnce, [getProcAddress] {
- const char* extensionsPtr =
- reinterpret_cast<const char*>(MBGL_CHECK_ERROR(glGetString(GL_EXTENSIONS)));
-
- if (!extensionsPtr)
- return;
-
- const std::string extensions = extensionsPtr;
- for (auto fn : detail::extensionFunctions()) {
- for (auto probe : fn.second) {
- if (extensions.find(probe.first) != std::string::npos) {
- *fn.first = getProcAddress(probe.second);
- break;
+ if (const char* extensions =
+ reinterpret_cast<const char*>(MBGL_CHECK_ERROR(glGetString(GL_EXTENSIONS)))) {
+ for (auto fn : detail::extensionFunctions()) {
+ for (auto probe : fn.second) {
+ if (strstr(extensions, probe.first) != nullptr) {
+ *fn.first = getProcAddress(probe.second);
+ break;
+ }
}
}
}
diff --git a/src/mbgl/gl/framebuffer.hpp b/src/mbgl/gl/framebuffer.hpp
index 880fed159e..91ed467b40 100644
--- a/src/mbgl/gl/framebuffer.hpp
+++ b/src/mbgl/gl/framebuffer.hpp
@@ -1,15 +1,14 @@
#pragma once
#include <mbgl/gl/object.hpp>
-
-#include <array>
+#include <mbgl/util/size.hpp>
namespace mbgl {
namespace gl {
class Framebuffer {
public:
- std::array<uint16_t, 2> size;
+ Size size;
gl::UniqueFramebuffer framebuffer;
};
diff --git a/src/mbgl/gl/index_buffer.hpp b/src/mbgl/gl/index_buffer.hpp
index f38d7fd4f5..b3610f4154 100644
--- a/src/mbgl/gl/index_buffer.hpp
+++ b/src/mbgl/gl/index_buffer.hpp
@@ -1,39 +1,38 @@
#pragma once
#include <mbgl/gl/object.hpp>
+#include <mbgl/gl/draw_mode.hpp>
+#include <mbgl/util/ignore.hpp>
+
+#include <vector>
namespace mbgl {
namespace gl {
-class Line {
+template <class DrawMode>
+class IndexVector {
public:
- Line(uint16_t a_, uint16_t b_)
- : a(a_), b(b_) {}
-
- uint16_t a;
- uint16_t b;
+ static constexpr std::size_t groupSize = DrawMode::bufferGroupSize;
- static constexpr std::size_t IndexCount = 2;
-};
+ template <class... Args>
+ void emplace_back(Args&&... args) {
+ static_assert(sizeof...(args) == groupSize, "wrong buffer element count");
+ util::ignore({(v.emplace_back(std::forward<Args>(args)), 0)...});
+ }
-class Triangle {
-public:
- Triangle(uint16_t a_, uint16_t b_, uint16_t c_)
- : a(a_), b(b_), c(c_) {}
+ std::size_t indexSize() const { return v.size(); }
+ std::size_t byteSize() const { return v.size() * sizeof(uint16_t); }
- uint16_t a;
- uint16_t b;
- uint16_t c;
+ bool empty() const { return v.empty(); }
+ const uint16_t* data() const { return v.data(); }
- static constexpr std::size_t IndexCount = 3;
+private:
+ std::vector<uint16_t> v;
};
-template <class Primitive>
+template <class DrawMode>
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;
};
diff --git a/src/mbgl/gl/primitives.hpp b/src/mbgl/gl/primitives.hpp
new file mode 100644
index 0000000000..fe6b1b2e5b
--- /dev/null
+++ b/src/mbgl/gl/primitives.hpp
@@ -0,0 +1,22 @@
+#pragma once
+
+namespace mbgl {
+namespace gl {
+
+class Point {
+public:
+ static constexpr std::size_t vertexCount = 1;
+};
+
+class Line {
+public:
+ static constexpr std::size_t vertexCount = 2;
+};
+
+class Triangle {
+public:
+ static constexpr std::size_t vertexCount = 3;
+};
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/gl/program.hpp b/src/mbgl/gl/program.hpp
new file mode 100644
index 0000000000..33387e9d4e
--- /dev/null
+++ b/src/mbgl/gl/program.hpp
@@ -0,0 +1,70 @@
+#pragma once
+
+#include <mbgl/gl/types.hpp>
+#include <mbgl/gl/object.hpp>
+#include <mbgl/gl/context.hpp>
+#include <mbgl/gl/vertex_buffer.hpp>
+#include <mbgl/gl/index_buffer.hpp>
+#include <mbgl/gl/attribute.hpp>
+#include <mbgl/gl/uniform.hpp>
+
+#include <string>
+
+namespace mbgl {
+namespace gl {
+
+template <class P, class As, class Us>
+class Program {
+public:
+ using Primitive = P;
+ using Attributes = As;
+ using Uniforms = Us;
+
+ using Vertex = typename Attributes::Vertex;
+ using UniformValues = typename Uniforms::Values;
+
+ static_assert(std::is_standard_layout<Vertex>::value, "vertex type must use standard layout");
+
+ Program(Context& context, const std::string& vertexSource, const std::string& fragmentSource)
+ : vertexShader(context.createShader(ShaderType::Vertex, vertexSource)),
+ fragmentShader(context.createShader(ShaderType::Fragment, fragmentSource)),
+ program(context.createProgram(vertexShader, fragmentShader)),
+ attributesState(Attributes::state(program)),
+ uniformsState((context.linkProgram(program), Uniforms::state(program))) {}
+
+ template <class DrawMode>
+ void draw(Context& context,
+ DrawMode drawMode,
+ DepthMode depthMode,
+ StencilMode stencilMode,
+ ColorMode colorMode,
+ UniformValues&& uniformValues,
+ const VertexBuffer<Vertex>& vertexBuffer,
+ const IndexBuffer<DrawMode>& indexBuffer,
+ const SegmentVector<Attributes>& segments) {
+ static_assert(std::is_same<Primitive, typename DrawMode::Primitive>::value, "incompatible draw mode");
+ context.draw({
+ std::move(drawMode),
+ std::move(depthMode),
+ std::move(stencilMode),
+ std::move(colorMode),
+ program,
+ vertexBuffer.buffer,
+ indexBuffer.buffer,
+ segments,
+ Uniforms::binder(uniformsState, std::move(uniformValues)),
+ Attributes::binder(attributesState)
+ });
+ }
+
+private:
+ UniqueShader vertexShader;
+ UniqueShader fragmentShader;
+ UniqueProgram program;
+
+ typename Attributes::State attributesState;
+ typename Uniforms::State uniformsState;
+};
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/gl/renderbuffer.hpp b/src/mbgl/gl/renderbuffer.hpp
index 9e8993bb77..cc8ff13268 100644
--- a/src/mbgl/gl/renderbuffer.hpp
+++ b/src/mbgl/gl/renderbuffer.hpp
@@ -1,8 +1,7 @@
#pragma once
#include <mbgl/gl/object.hpp>
-
-#include <array>
+#include <mbgl/util/size.hpp>
namespace mbgl {
namespace gl {
@@ -11,7 +10,7 @@ template <RenderbufferType renderbufferType>
class Renderbuffer {
public:
using type = std::integral_constant<RenderbufferType, renderbufferType>;
- std::array<uint16_t, 2> size;
+ Size size;
gl::UniqueRenderbuffer renderbuffer;
};
diff --git a/src/mbgl/gl/segment.hpp b/src/mbgl/gl/segment.hpp
new file mode 100644
index 0000000000..8f74afd237
--- /dev/null
+++ b/src/mbgl/gl/segment.hpp
@@ -0,0 +1,39 @@
+#pragma once
+
+#include <mbgl/util/optional.hpp>
+
+#include <cstddef>
+
+namespace mbgl {
+namespace gl {
+
+class Segment {
+public:
+ Segment(std::size_t vertexOffset_,
+ std::size_t indexOffset_,
+ std::size_t vertexLength_ = 0,
+ std::size_t indexLength_ = 0)
+ : vertexOffset(vertexOffset_),
+ indexOffset(indexOffset_),
+ vertexLength(vertexLength_),
+ indexLength(indexLength_) {}
+
+ const std::size_t vertexOffset;
+ const std::size_t indexOffset;
+
+ std::size_t vertexLength;
+ std::size_t indexLength;
+
+private:
+ friend class Context;
+ mutable optional<UniqueVertexArray> vao;
+};
+
+template <class Attributes>
+class SegmentVector : public std::vector<Segment> {
+public:
+ SegmentVector() = default;
+};
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/gl/shader.cpp b/src/mbgl/gl/shader.cpp
deleted file mode 100644
index d8ee734567..0000000000
--- a/src/mbgl/gl/shader.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-#include <mbgl/gl/shader.hpp>
-#include <mbgl/gl/gl.hpp>
-#include <mbgl/gl/context.hpp>
-#include <mbgl/util/stopwatch.hpp>
-#include <mbgl/util/exception.hpp>
-#include <mbgl/platform/log.hpp>
-#include <mbgl/platform/platform.hpp>
-
-#include <cstring>
-#include <cassert>
-#include <iostream>
-#include <string>
-#include <fstream>
-#include <cstdio>
-#include <cassert>
-
-namespace mbgl {
-namespace gl {
-
-Shader::Shader(const char* name_,
- const char* vertexSource,
- const char* fragmentSource,
- Context& context,
- Defines defines)
- : name(name_),
- program(context.createProgram()),
- vertexShader(context.createVertexShader()),
- fragmentShader(context.createFragmentShader()) {
- util::stopwatch stopwatch("shader compilation", Event::Shader);
-
- if (!compileShader(vertexShader, vertexSource)) {
- Log::Error(Event::Shader, "Vertex shader %s failed to compile: %s", name, vertexSource);
- throw util::ShaderException(std::string { "Vertex shader " } + name + " failed to compile");
- }
-
- std::string fragment(fragmentSource);
- if (defines & Defines::Overdraw) {
- assert(fragment.find("#ifdef OVERDRAW_INSPECTOR") != std::string::npos);
- fragment.replace(fragment.find_first_of('\n'), 1, "\n#define OVERDRAW_INSPECTOR\n");
- }
-
- if (!compileShader(fragmentShader, fragment.c_str())) {
- Log::Error(Event::Shader, "Fragment shader %s failed to compile: %s", name, fragmentSource);
- throw util::ShaderException(std::string { "Fragment shader " } + name + " failed to compile");
- }
-
- // Attach shaders
- MBGL_CHECK_ERROR(glAttachShader(program.get(), vertexShader.get()));
- MBGL_CHECK_ERROR(glAttachShader(program.get(), fragmentShader.get()));
-
- // Link program
- GLint status;
- MBGL_CHECK_ERROR(glLinkProgram(program.get()));
-
- MBGL_CHECK_ERROR(glGetProgramiv(program.get(), GL_LINK_STATUS, &status));
- if (status == 0) {
- GLint logLength;
- MBGL_CHECK_ERROR(glGetProgramiv(program.get(), GL_INFO_LOG_LENGTH, &logLength));
- const auto log = std::make_unique<GLchar[]>(logLength);
- if (logLength > 0) {
- MBGL_CHECK_ERROR(glGetProgramInfoLog(program.get(), logLength, &logLength, log.get()));
- Log::Error(Event::Shader, "Program failed to link: %s", log.get());
- }
- throw util::ShaderException(std::string { "Program " } + name + " failed to link: " + log.get());
- }
-}
-
-bool Shader::compileShader(UniqueShader& shader, const GLchar *source) {
- GLint status = 0;
-
- const GLsizei lengths = static_cast<GLsizei>(std::strlen(source));
- MBGL_CHECK_ERROR(glShaderSource(shader.get(), 1, &source, &lengths));
-
- MBGL_CHECK_ERROR(glCompileShader(shader.get()));
-
- MBGL_CHECK_ERROR(glGetShaderiv(shader.get(), GL_COMPILE_STATUS, &status));
- if (status == 0) {
- GLint logLength;
- MBGL_CHECK_ERROR(glGetShaderiv(shader.get(), GL_INFO_LOG_LENGTH, &logLength));
- if (logLength > 0) {
- const auto log = std::make_unique<GLchar[]>(logLength);
- MBGL_CHECK_ERROR(glGetShaderInfoLog(shader.get(), logLength, &logLength, log.get()));
- Log::Error(Event::Shader, "Shader failed to compile: %s", log.get());
- }
- return false;
- }
-
- MBGL_CHECK_ERROR(glGetShaderiv(shader.get(), GL_COMPILE_STATUS, &status));
- if (status == GL_FALSE) {
- Log::Error(Event::Shader, "Shader %s failed to compile.", name);
- return false;
- }
-
- return true;
-}
-
-Shader::~Shader() {
- if (program.get()) {
- MBGL_CHECK_ERROR(glDetachShader(program.get(), vertexShader.get()));
- MBGL_CHECK_ERROR(glDetachShader(program.get(), fragmentShader.get()));
- }
-}
-
-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
deleted file mode 100644
index f88bd4f867..0000000000
--- a/src/mbgl/gl/shader.hpp
+++ /dev/null
@@ -1,45 +0,0 @@
-#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/stencil_mode.cpp b/src/mbgl/gl/stencil_mode.cpp
new file mode 100644
index 0000000000..6858d6d106
--- /dev/null
+++ b/src/mbgl/gl/stencil_mode.cpp
@@ -0,0 +1,27 @@
+#include <mbgl/gl/stencil_mode.hpp>
+#include <mbgl/gl/gl.hpp>
+#include <mbgl/util/traits.hpp>
+
+namespace mbgl {
+namespace gl {
+
+static_assert(StencilMode::Never::func == GL_NEVER, "OpenGL enum mismatch");
+static_assert(StencilMode::Less::func == GL_LESS, "OpenGL enum mismatch");
+static_assert(StencilMode::Equal::func == GL_EQUAL, "OpenGL enum mismatch");
+static_assert(StencilMode::LessEqual::func == GL_LEQUAL, "OpenGL enum mismatch");
+static_assert(StencilMode::Greater::func == GL_GREATER, "OpenGL enum mismatch");
+static_assert(StencilMode::NotEqual::func == GL_NOTEQUAL, "OpenGL enum mismatch");
+static_assert(StencilMode::GreaterEqual::func == GL_GEQUAL, "OpenGL enum mismatch");
+static_assert(StencilMode::Always::func == GL_ALWAYS, "OpenGL enum mismatch");
+
+static_assert(underlying_type(StencilMode::Keep) == GL_KEEP, "OpenGL enum mismatch");
+static_assert(underlying_type(StencilMode::Zero) == GL_ZERO, "OpenGL enum mismatch");
+static_assert(underlying_type(StencilMode::Replace) == GL_REPLACE, "OpenGL enum mismatch");
+static_assert(underlying_type(StencilMode::Increment) == GL_INCR, "OpenGL enum mismatch");
+static_assert(underlying_type(StencilMode::IncrementWrap) == GL_INCR_WRAP, "OpenGL enum mismatch");
+static_assert(underlying_type(StencilMode::Decrement) == GL_DECR, "OpenGL enum mismatch");
+static_assert(underlying_type(StencilMode::DecrementWrap) == GL_DECR_WRAP, "OpenGL enum mismatch");
+static_assert(underlying_type(StencilMode::Invert) == GL_INVERT, "OpenGL enum mismatch");
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/gl/stencil_mode.hpp b/src/mbgl/gl/stencil_mode.hpp
new file mode 100644
index 0000000000..bc959c9a73
--- /dev/null
+++ b/src/mbgl/gl/stencil_mode.hpp
@@ -0,0 +1,66 @@
+#pragma once
+
+#include <mbgl/util/variant.hpp>
+
+namespace mbgl {
+namespace gl {
+
+class StencilMode {
+public:
+ template <uint32_t F>
+ struct SimpleTest {
+ static constexpr uint32_t func = F;
+ static constexpr uint32_t mask = 0;
+ };
+
+ template <uint32_t F>
+ struct MaskedTest {
+ static constexpr uint32_t func = F;
+ uint32_t mask;
+ };
+
+ using Never = SimpleTest<0x0200>;
+ using Less = MaskedTest<0x0201>;
+ using Equal = MaskedTest<0x0202>;
+ using LessEqual = MaskedTest<0x0203>;
+ using Greater = MaskedTest<0x0204>;
+ using NotEqual = MaskedTest<0x0205>;
+ using GreaterEqual = MaskedTest<0x0206>;
+ using Always = SimpleTest<0x0207>;
+
+ using Test = variant<
+ Never,
+ Less,
+ Equal,
+ LessEqual,
+ Greater,
+ NotEqual,
+ GreaterEqual,
+ Always>;
+
+ enum Op {
+ Zero = 0x0000,
+ Keep = 0x1E00,
+ Replace = 0x1E01,
+ Increment = 0x1E02,
+ Decrement = 0x1E03,
+ Invert = 0x150A,
+ IncrementWrap = 0x8507,
+ DecrementWrap = 0x8508
+ };
+
+ Test test;
+ int32_t ref;
+ uint32_t mask;
+
+ Op fail;
+ Op depthFail;
+ Op pass;
+
+ static StencilMode disabled() {
+ return StencilMode { Always(), 0, 0, Keep, Keep, Keep };
+ }
+};
+
+} // namespace gl
+} // namespace mbgl
diff --git a/src/mbgl/gl/texture.hpp b/src/mbgl/gl/texture.hpp
index 49e1323095..5330689ac2 100644
--- a/src/mbgl/gl/texture.hpp
+++ b/src/mbgl/gl/texture.hpp
@@ -1,18 +1,19 @@
#pragma once
#include <mbgl/gl/object.hpp>
-
-#include <array>
+#include <mbgl/util/size.hpp>
namespace mbgl {
namespace gl {
class Texture {
public:
- std::array<uint16_t, 2> size;
+ Size size;
UniqueTexture texture;
TextureFilter filter = TextureFilter::Nearest;
TextureMipMap mipmap = TextureMipMap::No;
+ TextureWrap wrapX = TextureWrap::Clamp;
+ TextureWrap wrapY = TextureWrap::Clamp;
};
} // namespace gl
diff --git a/src/mbgl/gl/types.hpp b/src/mbgl/gl/types.hpp
index dccc61b03a..577629d5d3 100644
--- a/src/mbgl/gl/types.hpp
+++ b/src/mbgl/gl/types.hpp
@@ -19,9 +19,10 @@ using AttributeLocation = int32_t;
using UniformLocation = int32_t;
using TextureUnit = uint8_t;
-using DepthValue = double;
-using StencilValue = int32_t;
-using StencilMaskValue = uint32_t;
+enum class ShaderType : uint32_t {
+ Vertex = 0x8B31,
+ Fragment = 0x8B30
+};
enum class DataType : uint32_t {
Byte = 0x1400,
@@ -43,11 +44,6 @@ template <> struct DataTypeOf<int32_t> : std::integral_constant<DataType, DataT
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
-};
-
enum class RenderbufferType : uint32_t {
RGBA = 0x8058,
DepthStencil = 0x88F0,
@@ -55,74 +51,37 @@ enum class RenderbufferType : uint32_t {
enum class TextureMipMap : bool { No = false, Yes = true };
enum class TextureFilter : bool { Nearest = false, Linear = true };
-
-enum class StencilTestFunction : uint32_t {
- Never = 0x0200,
- Less = 0x0201,
- Equal = 0x0202,
- LessEqual = 0x0203,
- Greater = 0x0204,
- NotEqual = 0x0205,
- GreaterEqual = 0x0206,
- Always = 0x0207,
+enum class TextureWrap : bool { Clamp, Repeat };
+enum class TextureFormat : uint32_t {
+ RGBA = 0x1908,
+ Alpha = 0x1906,
+#if not MBGL_USE_GLES2
+ Stencil = 0x1901,
+ Depth = 0x1902,
+#endif // MBGL_USE_GLES2
};
-enum class StencilTestOperation : uint32_t {
- Keep = 0x1E00,
- Zero = 0x0000,
- Replace = 0x1E01,
- Increment = 0x1E02,
- IncrementWrap = 0x8507,
- Decrement = 0x1E03,
- DecrementWrap = 0x8508,
- Invert = 0x150A,
+enum class PrimitiveType {
+ Points = 0x0000,
+ Lines = 0x0001,
+ LineLoop = 0x0002,
+ LineStrip = 0x0003,
+ Triangles = 0x0004,
+ TriangleStrip = 0x0005,
+ TriangleFan = 0x0006
};
-enum class DepthTestFunction : uint32_t {
- Never = 0x0200,
- Less = 0x0201,
- Equal = 0x0202,
- LessEqual = 0x0203,
- Greater = 0x0204,
- NotEqual = 0x0205,
- GreaterEqual = 0x0206,
- Always = 0x0207,
-};
+#if not MBGL_USE_GLES2
-enum class BlendSourceFactor : uint32_t {
- Zero = 0x0000,
- One = 0x0001,
- SrcColor = 0x0300,
- OneMinusSrcColor = 0x0301,
- DstColor = 0x0306,
- OneMinusDstColor = 0x0307,
- SrcAlpha = 0x0302,
- OneMinusSrcAlpha = 0x0303,
- DstAlpha = 0x0304,
- OneMinusDstAlpha = 0x0305,
- ConstantColor = 0x8001,
- OneMinusConstantColor = 0x8002,
- ConstantAlpha = 0x8003,
- OneMinusConstantAlpha = 0x8004,
- SrcAlphaSaturate = 0x0308,
+struct PixelStorageType {
+ int32_t alignment;
};
-enum class BlendDestinationFactor : uint32_t {
- Zero = 0x0000,
- One = 0x0001,
- SrcColor = 0x0300,
- OneMinusSrcColor = 0x0301,
- DstColor = 0x0306,
- OneMinusDstColor = 0x0307,
- SrcAlpha = 0x0302,
- OneMinusSrcAlpha = 0x0303,
- DstAlpha = 0x0304,
- OneMinusDstAlpha = 0x0305,
- ConstantColor = 0x8001,
- OneMinusConstantColor = 0x8002,
- ConstantAlpha = 0x8003,
- OneMinusConstantAlpha = 0x8004,
-};
+constexpr bool operator!=(const PixelStorageType& a, const PixelStorageType& b) {
+ return a.alignment != b.alignment;
+}
+
+#endif // MBGL_USE_GLES2
} // namespace gl
} // namespace mbgl
diff --git a/src/mbgl/gl/uniform.cpp b/src/mbgl/gl/uniform.cpp
index 07a27963d9..7b674f2cde 100644
--- a/src/mbgl/gl/uniform.cpp
+++ b/src/mbgl/gl/uniform.cpp
@@ -1,54 +1,80 @@
#include <mbgl/gl/uniform.hpp>
#include <mbgl/gl/gl.hpp>
#include <mbgl/util/color.hpp>
+#include <mbgl/util/size.hpp>
+#include <mbgl/util/convert.hpp>
namespace mbgl {
namespace gl {
+UniformLocation uniformLocation(ProgramID id, const char* name) {
+ return MBGL_CHECK_ERROR(glGetUniformLocation(id, name));
+}
+
template <>
-void Uniform<float>::bind(const float& t) {
+void bindUniform<float>(UniformLocation location, const float& t) {
MBGL_CHECK_ERROR(glUniform1f(location, t));
}
template <>
-void Uniform<int32_t>::bind(const int32_t& t) {
+void bindUniform<int32_t>(UniformLocation location, const int32_t& t) {
MBGL_CHECK_ERROR(glUniform1i(location, t));
}
template <>
-void Uniform<std::array<float, 2>>::bind(const std::array<float, 2>& t) {
+void bindUniform<std::array<float, 2>>(UniformLocation location, const std::array<float, 2>& t) {
MBGL_CHECK_ERROR(glUniform2fv(location, 1, t.data()));
}
template <>
-void Uniform<std::array<float, 3>>::bind(const std::array<float, 3>& t) {
+void bindUniform<std::array<float, 3>>(UniformLocation location, const std::array<float, 3>& t) {
MBGL_CHECK_ERROR(glUniform3fv(location, 1, t.data()));
}
template <>
-void Uniform<std::array<float, 4>>::bind(const std::array<float, 4>& t) {
+void bindUniform<std::array<float, 4>>(UniformLocation location, const std::array<float, 4>& t) {
MBGL_CHECK_ERROR(glUniform4fv(location, 1, t.data()));
}
template <>
-void Uniform<Color>::bind(const Color& t) {
- std::array<float, 4> a = {{ t.r, t.g, t.b, t.a }};
- MBGL_CHECK_ERROR(glUniform4fv(location, 1, a.data()));
+void bindUniform<std::array<double, 4>>(UniformLocation location, const std::array<double, 4>& t) {
+ MBGL_CHECK_ERROR(glUniformMatrix2fv(location, 1, GL_FALSE, util::convert<float>(t).data()));
+}
+
+template <>
+void bindUniform<std::array<double, 9>>(UniformLocation location, const std::array<double, 9>& t) {
+ MBGL_CHECK_ERROR(glUniformMatrix3fv(location, 1, GL_FALSE, util::convert<float>(t).data()));
+}
+
+template <>
+void bindUniform<std::array<double, 16>>(UniformLocation location, const std::array<double, 16>& t) {
+ MBGL_CHECK_ERROR(glUniformMatrix4fv(location, 1, GL_FALSE, util::convert<float>(t).data()));
+}
+
+
+template <>
+void bindUniform<bool>(UniformLocation location, const bool& t) {
+ return bindUniform(location, int32_t(t));
+}
+
+template <>
+void bindUniform<uint8_t>(UniformLocation location, const uint8_t& t) {
+ bindUniform(location, int32_t(t));
}
template <>
-void UniformMatrix<2>::bind(const std::array<float, 4>& t) {
- MBGL_CHECK_ERROR(glUniformMatrix2fv(location, 1, GL_FALSE, t.data()));
+void bindUniform<Color>(UniformLocation location, const Color& t) {
+ bindUniform(location, std::array<float, 4> {{ t.r, t.g, t.b, t.a }});
}
template <>
-void UniformMatrix<3>::bind(const std::array<float, 9>& t) {
- MBGL_CHECK_ERROR(glUniformMatrix3fv(location, 1, GL_FALSE, t.data()));
+void bindUniform<Size>(UniformLocation location, const Size& t) {
+ bindUniform(location, util::convert<float>(std::array<uint32_t, 2> {{ t.width, t.height }}));
}
template <>
-void UniformMatrix<4>::bind(const std::array<float, 16>& t) {
- MBGL_CHECK_ERROR(glUniformMatrix4fv(location, 1, GL_FALSE, t.data()));
+void bindUniform<std::array<uint16_t, 2>>(UniformLocation location, const std::array<uint16_t, 2>& t) {
+ bindUniform(location, util::convert<float>(t));
}
// Add more as needed.
diff --git a/src/mbgl/gl/uniform.hpp b/src/mbgl/gl/uniform.hpp
index 5af781043d..726cd4fe10 100644
--- a/src/mbgl/gl/uniform.hpp
+++ b/src/mbgl/gl/uniform.hpp
@@ -1,60 +1,80 @@
#pragma once
-#include <mbgl/gl/shader.hpp>
+#include <mbgl/gl/types.hpp>
+#include <mbgl/util/optional.hpp>
+#include <mbgl/util/ignore.hpp>
+#include <mbgl/util/indexed_tuple.hpp>
#include <array>
+#include <functional>
namespace mbgl {
namespace gl {
-template <typename T>
+template <class T>
+void bindUniform(UniformLocation, const T&);
+
+template <class Tag, class T>
+class UniformValue {
+public:
+ explicit UniformValue(T t_) : t(std::move(t_)) {}
+ T t;
+};
+
+template <class Tag, class T>
class Uniform {
public:
- Uniform(const char* name, const Shader& shader)
- : current(), location(shader.getUniformLocation(name)) {
- }
+ using Value = UniformValue<Tag, T>;
- void operator=(const T& t) {
- if (current != t) {
- current = t;
- bind(t);
+ class State {
+ public:
+ void operator=(const Value& value) {
+ if (!current || *current != value.t) {
+ current = value.t;
+ bindUniform(location, value.t);
+ }
}
- }
-
-private:
- void bind(const T&);
- T current;
- UniformLocation location;
+ UniformLocation location;
+ optional<T> current = {};
+ };
};
-template <size_t C, size_t R = C>
-class UniformMatrix {
+template <class Tag, class T>
+using UniformScalar = Uniform<Tag, T>;
+
+template <class Tag, class T, size_t N>
+using UniformVector = Uniform<Tag, std::array<T, N>>;
+
+template <class Tag, class T, size_t N>
+using UniformMatrix = Uniform<Tag, std::array<T, N*N>>;
+
+#define MBGL_DEFINE_UNIFORM_SCALAR(type_, name_) \
+ struct name_ : ::mbgl::gl::UniformScalar<name_, type_> { static constexpr auto name = #name_; }
+
+#define MBGL_DEFINE_UNIFORM_VECTOR(type_, n_, name_) \
+ struct name_ : ::mbgl::gl::UniformVector<name_, type_, n_> { static constexpr auto name = #name_; }
+
+#define MBGL_DEFINE_UNIFORM_MATRIX(type_, n_, name_) \
+ struct name_ : ::mbgl::gl::UniformMatrix<name_, type_, n_> { static constexpr auto name = #name_; }
+
+UniformLocation uniformLocation(ProgramID, const char * name);
+
+template <class... Us>
+class Uniforms {
public:
- typedef std::array<float, C*R> T;
+ using State = IndexedTuple<TypeList<Us...>, TypeList<typename Us::State...>>;
+ using Values = IndexedTuple<TypeList<Us...>, TypeList<typename Us::Value...>>;
- UniformMatrix(const char* name, const Shader& shader)
- : current(), location(shader.getUniformLocation(name)) {
+ static State state(const ProgramID& id) {
+ return State { { uniformLocation(id, Us::name) }... };
}
- void operator=(const std::array<double, C*R>& t) {
- bool dirty = false;
- for (unsigned int i = 0; i < C*R; i++) {
- if (current[i] != t[i]) {
- current[i] = t[i];
- dirty = true;
- }
- }
- if (dirty) {
- bind(current);
- }
+ static std::function<void ()> binder(State& state, Values&& values_) {
+ return [&state, values = std::move(values_)] () mutable {
+ util::ignore({ (state.template get<Us>() = values.template get<Us>(), 0)... });
+ };
}
-
-private:
- void bind(const T&);
-
- T current;
- UniformLocation location;
};
} // namespace gl
diff --git a/src/mbgl/gl/value.cpp b/src/mbgl/gl/value.cpp
index 14cd03efc4..86218f3d9a 100644
--- a/src/mbgl/gl/value.cpp
+++ b/src/mbgl/gl/value.cpp
@@ -94,7 +94,7 @@ StencilFunc::Type StencilFunc::Get() {
MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_FUNC, &func));
MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_REF, &ref));
MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask));
- return { static_cast<StencilTestFunction>(func), ref, static_cast<StencilMaskValue>(mask) };
+ return { static_cast<uint32_t>(func), ref, static_cast<uint32_t>(mask) };
}
const constexpr StencilTest::Type StencilTest::Default;
@@ -122,17 +122,17 @@ StencilOp::Type StencilOp::Get() {
MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_FAIL, &sfail));
MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &dpfail));
MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &dppass));
- return { static_cast<StencilTestOperation>(sfail), static_cast<StencilTestOperation>(dpfail),
- static_cast<StencilTestOperation>(dppass) };
+ return { static_cast<StencilMode::Op>(sfail), static_cast<StencilMode::Op>(dpfail),
+ static_cast<StencilMode::Op>(dppass) };
}
const constexpr DepthRange::Type DepthRange::Default;
void DepthRange::Set(const Type& value) {
#if MBGL_USE_GLES2
- MBGL_CHECK_ERROR(glDepthRangef(value.near, value.far));
+ MBGL_CHECK_ERROR(glDepthRangef(value.min, value.max));
#else
- MBGL_CHECK_ERROR(glDepthRange(value.near, value.far));
+ MBGL_CHECK_ERROR(glDepthRange(value.min, value.max));
#endif
}
@@ -178,6 +178,18 @@ Blend::Type Blend::Get() {
return blend;
}
+const constexpr BlendEquation::Type BlendEquation::Default;
+
+void BlendEquation::Set(const Type& value) {
+ MBGL_CHECK_ERROR(glBlendEquation(static_cast<GLenum>(value)));
+}
+
+BlendEquation::Type BlendEquation::Get() {
+ GLint blend;
+ MBGL_CHECK_ERROR(glGetIntegerv(GL_BLEND_EQUATION_RGB, &blend));
+ return static_cast<Type>(blend);
+}
+
const constexpr BlendFunc::Type BlendFunc::Default;
void BlendFunc::Set(const Type& value) {
@@ -189,8 +201,8 @@ BlendFunc::Type BlendFunc::Get() {
GLint sfactor, dfactor;
MBGL_CHECK_ERROR(glGetIntegerv(GL_BLEND_SRC_ALPHA, &sfactor));
MBGL_CHECK_ERROR(glGetIntegerv(GL_BLEND_DST_ALPHA, &dfactor));
- return { static_cast<BlendSourceFactor>(sfactor),
- static_cast<BlendDestinationFactor>(dfactor) };
+ return { static_cast<ColorMode::BlendFactor>(sfactor),
+ static_cast<ColorMode::BlendFactor>(dfactor) };
}
const constexpr BlendColor::Type BlendColor::Default;
@@ -244,14 +256,14 @@ ActiveTexture::Type ActiveTexture::Get() {
const constexpr Viewport::Type Viewport::Default;
void Viewport::Set(const Type& value) {
- MBGL_CHECK_ERROR(glViewport(value.x, value.y, value.width, value.height));
+ MBGL_CHECK_ERROR(glViewport(value.x, value.y, value.size.width, value.size.height));
}
Viewport::Type Viewport::Get() {
GLint viewport[4];
MBGL_CHECK_ERROR(glGetIntegerv(GL_VIEWPORT, viewport));
return { static_cast<int32_t>(viewport[0]), static_cast<int32_t>(viewport[1]),
- static_cast<uint16_t>(viewport[2]), static_cast<uint16_t>(viewport[3]) };
+ { static_cast<uint32_t>(viewport[2]), static_cast<uint32_t>(viewport[3]) } };
}
const constexpr BindFramebuffer::Type BindFramebuffer::Default;
@@ -340,6 +352,18 @@ BindVertexArray::Type BindVertexArray::Get() {
#if not MBGL_USE_GLES2
+const constexpr PointSize::Type PointSize::Default;
+
+void PointSize::Set(const Type& value) {
+ MBGL_CHECK_ERROR(glPointSize(value));
+}
+
+PointSize::Type PointSize::Get() {
+ GLfloat pointSize;
+ MBGL_CHECK_ERROR(glGetFloatv(GL_POINT_SIZE, &pointSize));
+ return pointSize;
+}
+
const constexpr PixelZoom::Type PixelZoom::Default;
void PixelZoom::Set(const Type& value) {
@@ -365,8 +389,63 @@ RasterPos::Type RasterPos::Get() {
return { pos[0], pos[1], pos[2], pos[3] };
}
-#endif // MBGL_USE_GLES2
+const constexpr PixelStorePack::Type PixelStorePack::Default;
+
+void PixelStorePack::Set(const Type& value) {
+ assert(value.alignment == 1 || value.alignment == 2 || value.alignment == 4 ||
+ value.alignment == 8);
+ MBGL_CHECK_ERROR(glPixelStorei(GL_PACK_ALIGNMENT, value.alignment));
+}
+
+PixelStorePack::Type PixelStorePack::Get() {
+ Type value;
+ MBGL_CHECK_ERROR(glGetIntegerv(GL_PACK_ALIGNMENT, &value.alignment));
+ return value;
+}
+
+const constexpr PixelStoreUnpack::Type PixelStoreUnpack::Default;
+void PixelStoreUnpack::Set(const Type& value) {
+ assert(value.alignment == 1 || value.alignment == 2 || value.alignment == 4 ||
+ value.alignment == 8);
+ MBGL_CHECK_ERROR(glPixelStorei(GL_UNPACK_ALIGNMENT, value.alignment));
+}
+
+PixelStoreUnpack::Type PixelStoreUnpack::Get() {
+ Type value;
+ MBGL_CHECK_ERROR(glGetIntegerv(GL_UNPACK_ALIGNMENT, &value.alignment));
+ return value;
+}
+
+const constexpr PixelTransferDepth::Type PixelTransferDepth::Default;
+
+void PixelTransferDepth::Set(const Type& value) {
+ MBGL_CHECK_ERROR(glPixelTransferf(GL_DEPTH_SCALE, value.scale));
+ MBGL_CHECK_ERROR(glPixelTransferf(GL_DEPTH_BIAS, value.bias));
+}
+
+PixelTransferDepth::Type PixelTransferDepth::Get() {
+ Type value;
+ MBGL_CHECK_ERROR(glGetFloatv(GL_DEPTH_SCALE, &value.scale));
+ MBGL_CHECK_ERROR(glGetFloatv(GL_DEPTH_BIAS, &value.bias));
+ return value;
+}
+
+const constexpr PixelTransferStencil::Type PixelTransferStencil::Default;
+
+void PixelTransferStencil::Set(const Type& value) {
+ MBGL_CHECK_ERROR(glPixelTransferf(GL_INDEX_SHIFT, value.shift));
+ MBGL_CHECK_ERROR(glPixelTransferf(GL_INDEX_OFFSET, value.offset));
+}
+
+PixelTransferStencil::Type PixelTransferStencil::Get() {
+ Type value;
+ MBGL_CHECK_ERROR(glGetIntegerv(GL_INDEX_SHIFT, &value.shift));
+ MBGL_CHECK_ERROR(glGetIntegerv(GL_INDEX_OFFSET, &value.offset));
+ return value;
+}
+
+#endif // MBGL_USE_GLES2
} // namespace value
} // namespace gl
diff --git a/src/mbgl/gl/value.hpp b/src/mbgl/gl/value.hpp
index 866ce389a4..3586c26bda 100644
--- a/src/mbgl/gl/value.hpp
+++ b/src/mbgl/gl/value.hpp
@@ -1,7 +1,12 @@
#pragma once
#include <mbgl/gl/types.hpp>
+#include <mbgl/gl/depth_mode.hpp>
+#include <mbgl/gl/stencil_mode.hpp>
+#include <mbgl/gl/color_mode.hpp>
#include <mbgl/util/color.hpp>
+#include <mbgl/util/size.hpp>
+#include <mbgl/util/range.hpp>
namespace mbgl {
namespace gl {
@@ -22,14 +27,14 @@ struct ClearColor {
};
struct ClearStencil {
- using Type = StencilValue;
+ using Type = int32_t;
static const constexpr Type Default = 0;
static void Set(const Type&);
static Type Get();
};
struct StencilMask {
- using Type = StencilMaskValue;
+ using Type = uint32_t;
static const constexpr Type Default = ~0u;
static void Set(const Type&);
static Type Get();
@@ -43,28 +48,19 @@ struct DepthMask {
};
struct ColorMask {
- struct Type {
- bool r;
- bool g;
- bool b;
- bool a;
- };
+ using Type = ColorMode::Mask;
static const constexpr Type Default = { true, true, true, true };
static void Set(const Type&);
static Type Get();
};
-constexpr bool operator!=(const ColorMask::Type& a, const ColorMask::Type& b) {
- return a.r != b.r || a.g != b.g || a.b != b.b || a.a != b.a;
-}
-
struct StencilFunc {
struct Type {
- StencilTestFunction func;
- StencilValue ref;
- StencilMaskValue mask;
+ uint32_t func;
+ int32_t ref;
+ uint32_t mask;
};
- static const constexpr Type Default = { StencilTestFunction::Always, 0, ~0u };
+ static const constexpr Type Default = { StencilMode::Always::func, 0, ~0u };
static void Set(const Type&);
static Type Get();
};
@@ -82,12 +78,11 @@ struct StencilTest {
struct StencilOp {
struct Type {
- StencilTestOperation sfail;
- StencilTestOperation dpfail;
- StencilTestOperation dppass;
+ StencilMode::Op sfail;
+ StencilMode::Op dpfail;
+ StencilMode::Op dppass;
};
- static const constexpr Type Default = { StencilTestOperation::Keep, StencilTestOperation::Keep,
- StencilTestOperation::Keep };
+ static const constexpr Type Default = { StencilMode::Keep, StencilMode::Keep, StencilMode::Keep };
static void Set(const Type&);
static Type Get();
};
@@ -97,19 +92,12 @@ constexpr bool operator!=(const StencilOp::Type& a, const StencilOp::Type& b) {
}
struct DepthRange {
- struct Type {
- float near;
- float far;
- };
+ using Type = Range<float>;
static const constexpr Type Default = { 0, 1 };
static void Set(const Type&);
static Type Get();
};
-constexpr bool operator!=(const DepthRange::Type& a, const DepthRange::Type& b) {
- return a.near != b.near || a.far != b.far;
-}
-
struct DepthTest {
using Type = bool;
static const constexpr Type Default = false;
@@ -118,8 +106,8 @@ struct DepthTest {
};
struct DepthFunc {
- using Type = DepthTestFunction;
- static const constexpr Type Default = DepthTestFunction::Less;
+ using Type = DepthMode::Function;
+ static const constexpr Type Default = DepthMode::Less;
static void Set(const Type&);
static Type Get();
};
@@ -131,12 +119,19 @@ struct Blend {
static Type Get();
};
+struct BlendEquation {
+ using Type = ColorMode::BlendEquation;
+ static const constexpr Type Default = ColorMode::BlendEquation::Add;
+ static void Set(const Type&);
+ static Type Get();
+};
+
struct BlendFunc {
struct Type {
- BlendSourceFactor sfactor;
- BlendDestinationFactor dfactor;
+ ColorMode::BlendFactor sfactor;
+ ColorMode::BlendFactor dfactor;
};
- static const constexpr Type Default = { BlendSourceFactor::One, BlendDestinationFactor::Zero };
+ static const constexpr Type Default = { ColorMode::One, ColorMode::Zero };
static void Set(const Type&);
static Type Get();
};
@@ -177,16 +172,19 @@ struct Viewport {
struct Type {
int32_t x;
int32_t y;
- uint16_t width;
- uint16_t height;
+ Size size;
};
- static const constexpr Type Default = { 0, 0, 0, 0 };
+ static const constexpr Type Default = { 0, 0, { 0, 0 } };
static void Set(const Type&);
static Type Get();
};
constexpr bool operator!=(const Viewport::Type& a, const Viewport::Type& b) {
- return a.x != b.x || a.y != b.y || a.width != b.width || a.height != b.height;
+ return a.x != b.x || a.y != b.y || a.size != b.size;
+}
+
+constexpr bool operator==(const Viewport::Type& a, const Viewport::Type& b) {
+ return !(a != b);
}
struct BindFramebuffer {
@@ -233,6 +231,13 @@ struct BindVertexArray {
#if not MBGL_USE_GLES2
+struct PointSize {
+ using Type = float;
+ static const constexpr Type Default = 1;
+ static void Set(const Type&);
+ static Type Get();
+};
+
struct PixelZoom {
struct Type {
float xfactor;
@@ -254,7 +259,7 @@ struct RasterPos {
double z;
double w;
};
- static const constexpr Type Default = { 0, 0, 0, 0 };
+ static const constexpr Type Default = { 0, 0, 0, 1 };
static void Set(const Type&);
static Type Get();
};
@@ -263,6 +268,48 @@ constexpr bool operator!=(const RasterPos::Type& a, const RasterPos::Type& b) {
return a.x != b.x || a.y != b.y || a.z != b.z || a.w != b.w;
}
+struct PixelStorePack {
+ using Type = PixelStorageType;
+ static const constexpr Type Default = { 4 };
+ static void Set(const Type&);
+ static Type Get();
+};
+
+struct PixelStoreUnpack {
+ using Type = PixelStorageType;
+ static const constexpr Type Default = { 4 };
+ static void Set(const Type&);
+ static Type Get();
+};
+
+struct PixelTransferDepth {
+ struct Type {
+ float scale;
+ float bias;
+ };
+ static const constexpr Type Default = { 1, 0 };
+ static void Set(const Type&);
+ static Type Get();
+};
+
+constexpr bool operator!=(const PixelTransferDepth::Type& a, const PixelTransferDepth::Type& b) {
+ return a.scale != b.scale || a.bias != b.bias;
+}
+
+struct PixelTransferStencil {
+ struct Type {
+ int32_t shift;
+ int32_t offset;
+ };
+ static const constexpr Type Default = { 0, 0 };
+ static void Set(const Type&);
+ static Type Get();
+};
+
+constexpr bool operator!=(const PixelTransferStencil::Type& a, const PixelTransferStencil::Type& b) {
+ return a.shift != b.shift || a.offset != b.offset;
+}
+
#endif // MBGL_USE_GLES2
} // namespace value
diff --git a/src/mbgl/gl/vao.cpp b/src/mbgl/gl/vao.cpp
deleted file mode 100644
index b235b0e63b..0000000000
--- a/src/mbgl/gl/vao.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-#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 {
-
-void VertexArrayObject::bindVertexArrayObject(Context& context) {
- if (!GenVertexArrays || !BindVertexArray) {
- static bool reported = false;
- if (!reported) {
- Log::Warning(Event::OpenGL, "Not using Vertex Array Objects");
- reported = true;
- }
- return;
- }
-
- if (!vertexArray) {
- vertexArray = context.createVertexArray();
- context.vertexBuffer.setDirty();
- context.elementBuffer.setDirty();
- }
-
- context.vertexArrayObject = *vertexArray;
-}
-
-void VertexArrayObject::verifyBinding(Shader& shader,
- 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 " +
- util::toString(bound_shader) + "(" + bound_shader_name + ") to " +
- util::toString(shader.getID()) + "(" + shader.name + ")" ));
- } else if (bound_offset != offset) {
- throw std::runtime_error("trying to bind VAO to another offset");
- } else if (bound_vertex_buffer != vertexBuffer) {
- throw std::runtime_error("trying to bind VAO to another vertex buffer");
- } else if (bound_elements_buffer != elementsBuffer) {
- throw std::runtime_error("trying to bind VAO to another elements buffer");
- }
-}
-
-void VertexArrayObject::storeBinding(Shader& shader,
- BufferID vertexBuffer,
- BufferID elementsBuffer,
- int8_t* offset) {
- bound_shader = shader.getID();
- bound_shader_name = shader.name;
- bound_offset = offset;
- bound_vertex_buffer = vertexBuffer;
- bound_elements_buffer = elementsBuffer;
-}
-
-} // namespace gl
-} // namespace mbgl
diff --git a/src/mbgl/gl/vao.hpp b/src/mbgl/gl/vao.hpp
deleted file mode 100644
index 826c028d32..0000000000
--- a/src/mbgl/gl/vao.hpp
+++ /dev/null
@@ -1,78 +0,0 @@
-#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
index c77a9a4213..c9bc01f3e8 100644
--- a/src/mbgl/gl/vertex_buffer.hpp
+++ b/src/mbgl/gl/vertex_buffer.hpp
@@ -1,14 +1,43 @@
#pragma once
#include <mbgl/gl/object.hpp>
+#include <mbgl/gl/primitives.hpp>
+#include <mbgl/gl/draw_mode.hpp>
+#include <mbgl/util/ignore.hpp>
+
+#include <vector>
namespace mbgl {
namespace gl {
-template <class Vertex>
+template <class V, class DrawMode = Indexed>
+class VertexVector {
+public:
+ using Vertex = V;
+ static constexpr std::size_t groupSize = DrawMode::bufferGroupSize;
+
+ template <class... Args>
+ void emplace_back(Args&&... args) {
+ static_assert(sizeof...(args) == groupSize, "wrong buffer element count");
+ util::ignore({(v.emplace_back(std::forward<Args>(args)), 0)...});
+ }
+
+ std::size_t vertexSize() const { return v.size(); }
+ std::size_t byteSize() const { return v.size() * sizeof(Vertex); }
+
+ bool empty() const { return v.empty(); }
+ const Vertex* data() const { return v.data(); }
+
+private:
+ std::vector<Vertex> v;
+};
+
+template <class V, class DrawMode = Indexed>
class VertexBuffer {
public:
+ using Vertex = V;
static constexpr std::size_t vertexSize = sizeof(Vertex);
+
std::size_t vertexCount;
UniqueBuffer buffer;
};
diff --git a/src/mbgl/layout/merge_lines.cpp b/src/mbgl/layout/merge_lines.cpp
index f4fdb82617..676cbc092d 100644
--- a/src/mbgl/layout/merge_lines.cpp
+++ b/src/mbgl/layout/merge_lines.cpp
@@ -47,10 +47,10 @@ enum class Side {
};
size_t
-getKey(const std::u32string& text, const GeometryCollection& geom, Side side) {
+getKey(const std::u16string& text, const GeometryCollection& geom, Side side) {
const GeometryCoordinate& coord = side == Side::Right ? geom[0].back() : geom[0].front();
- auto hash = std::hash<std::u32string>()(text);
+ auto hash = std::hash<std::u16string>()(text);
boost::hash_combine(hash, coord.x);
boost::hash_combine(hash, coord.y);
return hash;
diff --git a/src/mbgl/layout/symbol_feature.hpp b/src/mbgl/layout/symbol_feature.hpp
index 99db4f9ac5..5dd61d9156 100644
--- a/src/mbgl/layout/symbol_feature.hpp
+++ b/src/mbgl/layout/symbol_feature.hpp
@@ -9,8 +9,9 @@ namespace mbgl {
class SymbolFeature {
public:
+ FeatureType type;
GeometryCollection geometry;
- optional<std::u32string> text;
+ optional<std::u16string> text;
optional<std::string> icon;
std::size_t index;
};
diff --git a/src/mbgl/layout/symbol_instance.cpp b/src/mbgl/layout/symbol_instance.cpp
index 64b913200e..fafcc7c15d 100644
--- a/src/mbgl/layout/symbol_instance.cpp
+++ b/src/mbgl/layout/symbol_instance.cpp
@@ -7,7 +7,7 @@ using namespace style;
SymbolInstance::SymbolInstance(Anchor& anchor, const GeometryCoordinates& line,
const Shaping& shapedText, const PositionedIcon& shapedIcon,
- const SymbolLayoutProperties& layout, const bool addToBuffers, const uint32_t index_,
+ const SymbolLayoutProperties::Evaluated& layout, const bool addToBuffers, const uint32_t index_,
const float textBoxScale, const float textPadding, const SymbolPlacementType textPlacement,
const float iconBoxScale, const float iconPadding, const SymbolPlacementType iconPlacement,
const GlyphPositions& face, const IndexedSubfeature& indexedFeature) :
diff --git a/src/mbgl/layout/symbol_instance.hpp b/src/mbgl/layout/symbol_instance.hpp
index 3087bf09f9..508c11a394 100644
--- a/src/mbgl/layout/symbol_instance.hpp
+++ b/src/mbgl/layout/symbol_instance.hpp
@@ -2,21 +2,18 @@
#include <mbgl/text/quads.hpp>
#include <mbgl/text/collision_feature.hpp>
+#include <mbgl/style/layers/symbol_layer_properties.hpp>
namespace mbgl {
struct Anchor;
class IndexedSubfeature;
-namespace style {
-class SymbolLayoutProperties;
-} // namespace style
-
class SymbolInstance {
public:
explicit SymbolInstance(Anchor& anchor, const GeometryCoordinates& line,
const Shaping& shapedText, const PositionedIcon& shapedIcon,
- const style::SymbolLayoutProperties&, const bool inside, const uint32_t index,
+ const style::SymbolLayoutProperties::Evaluated&, const bool inside, const uint32_t index,
const float textBoxScale, const float textPadding, style::SymbolPlacementType textPlacement,
const float iconBoxScale, const float iconPadding, style::SymbolPlacementType iconPlacement,
const GlyphPositions& face, const IndexedSubfeature& indexedfeature);
diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp
index 07ba2bf4a3..7be2c13ada 100644
--- a/src/mbgl/layout/symbol_layout.cpp
+++ b/src/mbgl/layout/symbol_layout.cpp
@@ -11,14 +11,14 @@
#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>
+#include <mbgl/math/log2.hpp>
+#include <mbgl/util/platform.hpp>
+#include <mbgl/util/logging.hpp>
namespace mbgl {
@@ -31,7 +31,7 @@ SymbolLayout::SymbolLayout(std::string bucketName_,
const MapMode mode_,
const GeometryTileLayer& layer,
const style::Filter& filter,
- style::SymbolLayoutProperties layout_,
+ style::SymbolLayoutProperties::Evaluated layout_,
float textMaxSize_,
SpriteAtlas& spriteAtlas_)
: bucketName(std::move(bucketName_)),
@@ -45,8 +45,8 @@ SymbolLayout::SymbolLayout(std::string bucketName_,
tileSize(util::tileSize * overscaling_),
tilePixelRatio(float(util::EXTENT) / tileSize) {
- const bool hasText = !layout.textField.value.empty() && !layout.textFont.value.empty();
- const bool hasIcon = !layout.iconImage.value.empty();
+ const bool hasText = !layout.get<TextField>().empty() && !layout.get<TextFont>().empty();
+ const bool hasIcon = !layout.get<IconImage>().empty();
if (!hasText && !hasIcon) {
return;
@@ -82,42 +82,34 @@ SymbolLayout::SymbolLayout(std::string bucketName_,
};
if (hasText) {
- std::string u8string = util::replaceTokens(layout.textField, getValue);
+ std::string u8string = util::replaceTokens(layout.get<TextField>(), getValue);
- if (layout.textTransform == TextTransformType::Uppercase) {
+ if (layout.get<TextTransform>() == TextTransformType::Uppercase) {
u8string = platform::uppercase(u8string);
- } else if (layout.textTransform == TextTransformType::Lowercase) {
+ } else if (layout.get<TextTransform>() == TextTransformType::Lowercase) {
u8string = platform::lowercase(u8string);
}
- ft.text = util::utf8_to_utf32::convert(u8string);
+ ft.text = applyArabicShaping(util::utf8_to_utf16::convert(u8string));
// Loop through all characters of this text and collect unique codepoints.
- for (char32_t chr : *ft.text) {
+ for (char16_t chr : *ft.text) {
ranges.insert(getGlyphRange(chr));
}
}
if (hasIcon) {
- ft.icon = util::replaceTokens(layout.iconImage, getValue);
+ ft.icon = util::replaceTokens(layout.get<IconImage>(), getValue);
}
if (ft.text || ft.icon) {
- auto &multiline = ft.geometry;
-
- GeometryCollection geometryCollection = feature->getGeometries();
- for (auto& line : geometryCollection) {
- multiline.emplace_back();
- for (auto& point : line) {
- multiline.back().emplace_back(point.x, point.y);
- }
- }
-
+ ft.type = feature->getType();
+ ft.geometry = feature->getGeometries();
features.push_back(std::move(ft));
}
}
- if (layout.symbolPlacement == SymbolPlacementType::Line) {
+ if (layout.get<SymbolPlacement>() == SymbolPlacementType::Line) {
util::mergeLines(features);
}
}
@@ -127,11 +119,11 @@ bool SymbolLayout::hasSymbolInstances() const {
}
bool SymbolLayout::canPrepare(GlyphAtlas& glyphAtlas) {
- if (!layout.textField.value.empty() && !layout.textFont.value.empty() && !glyphAtlas.hasGlyphRanges(layout.textFont, ranges)) {
+ if (!layout.get<TextField>().empty() && !layout.get<TextFont>().empty() && !glyphAtlas.hasGlyphRanges(layout.get<TextFont>(), ranges)) {
return false;
}
- if (!layout.iconImage.value.empty() && !spriteAtlas.isLoaded()) {
+ if (!layout.get<IconImage>().empty() && !spriteAtlas.isLoaded()) {
return false;
}
@@ -143,7 +135,7 @@ void SymbolLayout::prepare(uintptr_t tileUID,
float horizontalAlign = 0.5;
float verticalAlign = 0.5;
- switch (layout.textAnchor) {
+ switch (layout.get<TextAnchor>()) {
case TextAnchorType::Top:
case TextAnchorType::Bottom:
case TextAnchorType::Center:
@@ -160,7 +152,7 @@ void SymbolLayout::prepare(uintptr_t tileUID,
break;
}
- switch (layout.textAnchor) {
+ switch (layout.get<TextAnchor>()) {
case TextAnchorType::Left:
case TextAnchorType::Right:
case TextAnchorType::Center:
@@ -177,11 +169,11 @@ void SymbolLayout::prepare(uintptr_t tileUID,
break;
}
- const float justify = layout.textJustify == TextJustifyType::Right ? 1 :
- layout.textJustify == TextJustifyType::Left ? 0 :
+ const float justify = layout.get<TextJustify>() == TextJustifyType::Right ? 1 :
+ layout.get<TextJustify>() == TextJustifyType::Left ? 0 :
0.5;
- auto glyphSet = glyphAtlas.getGlyphSet(layout.textFont);
+ auto glyphSet = glyphAtlas.getGlyphSet(layout.get<TextFont>());
for (const auto& feature : features) {
if (feature.geometry.empty()) continue;
@@ -194,18 +186,19 @@ void SymbolLayout::prepare(uintptr_t tileUID,
if (feature.text) {
shapedText = glyphSet->getShaping(
/* string */ *feature.text,
- /* maxWidth: ems */ layout.symbolPlacement != SymbolPlacementType::Line ?
- layout.textMaxWidth * 24 : 0,
- /* lineHeight: ems */ layout.textLineHeight * 24,
+ /* maxWidth: ems */ layout.get<SymbolPlacement>() != SymbolPlacementType::Line ?
+ layout.get<TextMaxWidth>() * 24 : 0,
+ /* lineHeight: ems */ layout.get<TextLineHeight>() * 24,
/* horizontalAlign */ horizontalAlign,
/* verticalAlign */ verticalAlign,
/* justify */ justify,
- /* spacing: ems */ layout.textLetterSpacing * 24,
- /* translate */ Point<float>(layout.textOffset.value[0], layout.textOffset.value[1]));
+ /* spacing: ems */ layout.get<TextLetterSpacing>() * 24,
+ /* translate */ Point<float>(layout.get<TextOffset>()[0], layout.get<TextOffset>()[1]),
+ /* bidirectional algorithm object */ bidi);
// Add the glyphs we need for this label to the glyph atlas.
if (shapedText) {
- glyphAtlas.addGlyphs(tileUID, *feature.text, layout.textFont, **glyphSet, face);
+ glyphAtlas.addGlyphs(tileUID, *feature.text, layout.get<TextFont>(), **glyphSet, face);
}
}
@@ -220,7 +213,7 @@ void SymbolLayout::prepare(uintptr_t tileUID,
}
if ((*image).relativePixelRatio != 1.0f) {
iconsNeedLinear = true;
- } else if (layout.iconRotate != 0) {
+ } else if (layout.get<IconRotate>() != 0) {
iconsNeedLinear = true;
}
}
@@ -228,93 +221,114 @@ void SymbolLayout::prepare(uintptr_t tileUID,
// if either shapedText or icon position is present, add the feature
if (shapedText || shapedIcon) {
- addFeature(feature.geometry, shapedText, shapedIcon, face, feature.index);
+ addFeature(feature, shapedText, shapedIcon, face);
}
}
features.clear();
}
-
-void SymbolLayout::addFeature(const GeometryCollection &lines,
- const Shaping &shapedText, const PositionedIcon &shapedIcon, const GlyphPositions &face, const size_t index) {
-
+void SymbolLayout::addFeature(const SymbolFeature& feature,
+ const Shaping& shapedText,
+ const PositionedIcon& shapedIcon,
+ const GlyphPositions& face) {
const float minScale = 0.5f;
const float glyphSize = 24.0f;
- const float fontScale = layout.textSize / glyphSize;
+ const float fontScale = layout.get<TextSize>() / glyphSize;
const float textBoxScale = tilePixelRatio * fontScale;
const float textMaxBoxScale = tilePixelRatio * textMaxSize / glyphSize;
- const float iconBoxScale = tilePixelRatio * layout.iconSize;
- const float symbolSpacing = tilePixelRatio * layout.symbolSpacing;
- const bool avoidEdges = layout.symbolAvoidEdges && layout.symbolPlacement != SymbolPlacementType::Line;
- const float textPadding = layout.textPadding * tilePixelRatio;
- const float iconPadding = layout.iconPadding * tilePixelRatio;
- const float textMaxAngle = layout.textMaxAngle * util::DEG2RAD;
- const SymbolPlacementType textPlacement = layout.textRotationAlignment != AlignmentType::Map
+ const float iconBoxScale = tilePixelRatio * layout.get<IconSize>();
+ const float symbolSpacing = tilePixelRatio * layout.get<SymbolSpacing>();
+ const bool avoidEdges = layout.get<SymbolAvoidEdges>() && layout.get<SymbolPlacement>() != SymbolPlacementType::Line;
+ const float textPadding = layout.get<TextPadding>() * tilePixelRatio;
+ const float iconPadding = layout.get<IconPadding>() * tilePixelRatio;
+ const float textMaxAngle = layout.get<TextMaxAngle>() * util::DEG2RAD;
+ const SymbolPlacementType textPlacement = layout.get<TextRotationAlignment>() != AlignmentType::Map
? SymbolPlacementType::Point
- : layout.symbolPlacement;
- const SymbolPlacementType iconPlacement = layout.iconRotationAlignment != AlignmentType::Map
+ : layout.get<SymbolPlacement>();
+ const SymbolPlacementType iconPlacement = layout.get<IconRotationAlignment>() != AlignmentType::Map
? SymbolPlacementType::Point
- : layout.symbolPlacement;
- const bool mayOverlap = layout.textAllowOverlap || layout.iconAllowOverlap ||
- layout.textIgnorePlacement || layout.iconIgnorePlacement;
- const bool isLine = layout.symbolPlacement == SymbolPlacementType::Line;
+ : layout.get<SymbolPlacement>();
const float textRepeatDistance = symbolSpacing / 2;
-
- auto& clippedLines = isLine ?
- util::clipLines(lines, 0, 0, util::EXTENT, util::EXTENT) :
- lines;
-
- IndexedSubfeature indexedFeature = {index, sourceLayerName, bucketName, symbolInstances.size()};
-
- for (const auto& line : clippedLines) {
- if (line.empty()) continue;
-
- // Calculate the anchor points around which you want to place labels
- Anchors anchors = isLine ?
- getAnchors(line, symbolSpacing, textMaxAngle, shapedText.left, shapedText.right, shapedIcon.left, shapedIcon.right, glyphSize, textMaxBoxScale, overscaling) :
- Anchors({ Anchor(float(line[0].x), float(line[0].y), 0, minScale) });
-
- // For each potential label, create the placement features used to check for collisions, and the quads use for rendering.
- for (Anchor &anchor : anchors) {
- if (shapedText && isLine) {
- if (anchorIsTooClose(shapedText.text, textRepeatDistance, anchor)) {
- continue;
+ IndexedSubfeature indexedFeature = {feature.index, sourceLayerName, bucketName, symbolInstances.size()};
+
+ auto addSymbolInstance = [&] (const GeometryCoordinates& line, Anchor& anchor) {
+ // https://github.com/mapbox/vector-tile-spec/tree/master/2.1#41-layers
+ // +-------------------+ Symbols with anchors located on tile edges
+ // |(0,0) || are duplicated on neighbor tiles.
+ // | ||
+ // | || In continuous mode, to avoid overdraw we
+ // | || skip symbols located on the extent edges.
+ // | Tile || In still mode, we include the features in
+ // | || the buffers for both tiles and clip them
+ // | || at draw time.
+ // | ||
+ // +-------------------| In this scenario, the inner bounding box
+ // +-------------------+ is called 'withinPlus0', and the outer
+ // (extent,extent) is called 'inside'.
+ const bool withinPlus0 = anchor.point.x >= 0 && anchor.point.x < util::EXTENT && anchor.point.y >= 0 && anchor.point.y < util::EXTENT;
+ const bool inside = withinPlus0 || anchor.point.x == util::EXTENT || anchor.point.y == util::EXTENT;
+
+ if (avoidEdges && !inside) return;
+
+ const bool addToBuffers = mode == MapMode::Still || withinPlus0;
+
+ symbolInstances.emplace_back(anchor, line, shapedText, shapedIcon, layout, addToBuffers, symbolInstances.size(),
+ textBoxScale, textPadding, textPlacement,
+ iconBoxScale, iconPadding, iconPlacement,
+ face, indexedFeature);
+ };
+
+ if (layout.get<SymbolPlacement>() == SymbolPlacementType::Line) {
+ auto clippedLines = util::clipLines(feature.geometry, 0, 0, util::EXTENT, util::EXTENT);
+ for (const auto& line : clippedLines) {
+ Anchors anchors = getAnchors(line,
+ symbolSpacing,
+ textMaxAngle,
+ shapedText.left,
+ shapedText.right,
+ shapedIcon.left,
+ shapedIcon.right,
+ glyphSize,
+ textMaxBoxScale,
+ overscaling);
+
+ for (auto& anchor : anchors) {
+ if (!shapedText || !anchorIsTooClose(shapedText.text, textRepeatDistance, anchor)) {
+ addSymbolInstance(line, anchor);
}
}
-
- const bool inside = !(anchor.point.x < 0 || anchor.point.x > util::EXTENT || anchor.point.y < 0 || anchor.point.y > util::EXTENT);
-
- if (avoidEdges && !inside) continue;
-
- // Normally symbol layers are drawn across tile boundaries. Only symbols
- // with their anchors within the tile boundaries are added to the buffers
- // to prevent symbols from being drawn twice.
- //
- // Symbols in layers with overlap are sorted in the y direction so that
- // symbols lower on the canvas are drawn on top of symbols near the top.
- // To preserve this order across tile boundaries these symbols can't
- // be drawn across tile boundaries. Instead they need to be included in
- // the buffers for both tiles and clipped to tile boundaries at draw time.
- //
- // TODO remove the `&& false` when is #1673 implemented
- const bool addToBuffers = (mode == MapMode::Still) || inside || (mayOverlap && false);
-
- symbolInstances.emplace_back(anchor, line, shapedText, shapedIcon, layout, addToBuffers, symbolInstances.size(),
- textBoxScale, textPadding, textPlacement,
- iconBoxScale, iconPadding, iconPlacement,
- face, indexedFeature);
+ }
+ } else if (feature.type == FeatureType::Polygon) {
+ // TODO: pole of inaccessibility
+ for (const auto& ring : feature.geometry) {
+ for (const auto& point : ring) {
+ Anchor anchor(point.x, point.y, 0, minScale);
+ addSymbolInstance(ring, anchor);
+ }
+ }
+ } else if (feature.type == FeatureType::LineString) {
+ for (const auto& line : feature.geometry) {
+ Anchor anchor(line[0].x, line[0].y, 0, minScale);
+ addSymbolInstance(line, anchor);
+ }
+ } else if (feature.type == FeatureType::Point) {
+ for (const auto& points : feature.geometry) {
+ for (const auto& point : points) {
+ Anchor anchor(point.x, point.y, 0, minScale);
+ addSymbolInstance({point}, anchor);
+ }
}
}
}
-bool SymbolLayout::anchorIsTooClose(const std::u32string &text, const float repeatDistance, Anchor &anchor) {
+bool SymbolLayout::anchorIsTooClose(const std::u16string& text, const float repeatDistance, const Anchor& anchor) {
if (compareText.find(text) == compareText.end()) {
compareText.emplace(text, Anchors());
} else {
auto otherAnchors = compareText.find(text)->second;
- for (Anchor &otherAnchor : otherAnchors) {
+ for (const Anchor& otherAnchor : otherAnchors) {
if (util::dist<float>(anchor.point, otherAnchor.point) < repeatDistance) {
return true;
}
@@ -330,15 +344,15 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile)
// Calculate which labels can be shown and when they can be shown and
// create the bufers used for rendering.
- const SymbolPlacementType textPlacement = layout.textRotationAlignment != AlignmentType::Map
+ const SymbolPlacementType textPlacement = layout.get<TextRotationAlignment>() != AlignmentType::Map
? SymbolPlacementType::Point
- : layout.symbolPlacement;
- const SymbolPlacementType iconPlacement = layout.iconRotationAlignment != AlignmentType::Map
+ : layout.get<SymbolPlacement>();
+ const SymbolPlacementType iconPlacement = layout.get<IconRotationAlignment>() != AlignmentType::Map
? SymbolPlacementType::Point
- : layout.symbolPlacement;
+ : layout.get<SymbolPlacement>();
- const bool mayOverlap = layout.textAllowOverlap || layout.iconAllowOverlap ||
- layout.textIgnorePlacement || layout.iconIgnorePlacement;
+ const bool mayOverlap = layout.get<TextAllowOverlap>() || layout.get<IconAllowOverlap>() ||
+ layout.get<TextIgnorePlacement>() || layout.get<IconIgnorePlacement>();
// Sort symbols by their y position on the canvas so that they lower symbols
// are drawn on top of higher symbols.
@@ -362,18 +376,18 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile)
const bool hasText = symbolInstance.hasText;
const bool hasIcon = symbolInstance.hasIcon;
- const bool iconWithoutText = layout.textOptional || !hasText;
- const bool textWithoutIcon = layout.iconOptional || !hasIcon;
+ const bool iconWithoutText = layout.get<TextOptional>() || !hasText;
+ const bool textWithoutIcon = layout.get<IconOptional>() || !hasIcon;
// Calculate the scales at which the text and icon can be placed without collision.
float glyphScale = hasText ?
collisionTile.placeFeature(symbolInstance.textCollisionFeature,
- layout.textAllowOverlap, layout.symbolAvoidEdges) :
+ layout.get<TextAllowOverlap>(), layout.get<SymbolAvoidEdges>()) :
collisionTile.minScale;
float iconScale = hasIcon ?
collisionTile.placeFeature(symbolInstance.iconCollisionFeature,
- layout.iconAllowOverlap, layout.symbolAvoidEdges) :
+ layout.get<IconAllowOverlap>(), layout.get<SymbolAvoidEdges>()) :
collisionTile.minScale;
@@ -391,20 +405,20 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile)
// Insert final placement into collision tree and add glyphs/icons to buffers
if (hasText) {
- collisionTile.insertFeature(symbolInstance.textCollisionFeature, glyphScale, layout.textIgnorePlacement);
+ collisionTile.insertFeature(symbolInstance.textCollisionFeature, glyphScale, layout.get<TextIgnorePlacement>());
if (glyphScale < collisionTile.maxScale) {
addSymbols(
bucket->text, symbolInstance.glyphQuads, glyphScale,
- layout.textKeepUpright, textPlacement, collisionTile.config.angle);
+ layout.get<TextKeepUpright>(), textPlacement, collisionTile.config.angle);
}
}
if (hasIcon) {
- collisionTile.insertFeature(symbolInstance.iconCollisionFeature, iconScale, layout.iconIgnorePlacement);
+ collisionTile.insertFeature(symbolInstance.iconCollisionFeature, iconScale, layout.get<IconIgnorePlacement>());
if (iconScale < collisionTile.maxScale) {
addSymbols(
bucket->icon, symbolInstance.iconQuads, iconScale,
- layout.iconKeepUpright, iconPlacement, collisionTile.config.angle);
+ layout.get<IconKeepUpright>(), iconPlacement, collisionTile.config.angle);
}
}
}
@@ -418,8 +432,8 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place(CollisionTile& collisionTile)
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);
+ constexpr const uint16_t vertexLength = 4;
+ const float placementZoom = util::max(util::log2(scale) + zoom, 0.0f);
for (const auto& symbol : symbols) {
const auto &tl = symbol.tl;
@@ -428,9 +442,8 @@ void SymbolLayout::addSymbols(Buffer &buffer, const SymbolQuads &symbols, float
const auto &br = symbol.br;
const auto &tex = symbol.tex;
- float minZoom =
- util::max(static_cast<float>(zoom + log(symbol.minScale) / log(2)), placementZoom);
- float maxZoom = util::min(static_cast<float>(zoom + log(symbol.maxScale) / log(2)), 25.0f);
+ float minZoom = util::max(zoom + util::log2(symbol.minScale), placementZoom);
+ float maxZoom = util::min(zoom + util::log2(symbol.maxScale), util::MAX_ZOOM_F);
const auto &anchorPoint = symbol.anchorPoint;
// drop upside down versions of glyphs
@@ -449,41 +462,35 @@ void SymbolLayout::addSymbols(Buffer &buffer, const SymbolQuads &symbols, float
minZoom = 0;
}
- const int glyph_vertex_length = 4;
-
- 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();
+ if (buffer.segments.empty() || buffer.segments.back().vertexLength + vertexLength > std::numeric_limits<uint16_t>::max()) {
+ buffer.segments.emplace_back(buffer.vertices.vertexSize(), buffer.triangles.indexSize());
}
// We're generating triangle fans, so we always start with the first
// coordinate in this polygon.
- auto& group = buffer.groups.back();
- size_t index = group.vertexLength;
+ auto& segment = buffer.segments.back();
+ assert(segment.vertexLength <= std::numeric_limits<uint16_t>::max());
+ uint16_t index = segment.vertexLength;
// Encode angle of glyph
uint8_t glyphAngle = std::round((symbol.glyphAngle / (M_PI * 2)) * 256);
// coordinates (2 triangles)
- buffer.vertices.emplace_back(anchorPoint.x, anchorPoint.y, tl.x, tl.y, tex.x, tex.y, minZoom,
- maxZoom, placementZoom, glyphAngle);
- buffer.vertices.emplace_back(anchorPoint.x, anchorPoint.y, tr.x, tr.y, tex.x + tex.w, tex.y,
- minZoom, maxZoom, placementZoom, glyphAngle);
- buffer.vertices.emplace_back(anchorPoint.x, anchorPoint.y, bl.x, bl.y, tex.x, tex.y + tex.h,
- minZoom, maxZoom, placementZoom, glyphAngle);
- buffer.vertices.emplace_back(anchorPoint.x, anchorPoint.y, br.x, br.y, tex.x + tex.w, tex.y + tex.h,
- minZoom, maxZoom, placementZoom, glyphAngle);
+ buffer.vertices.emplace_back(SymbolAttributes::vertex(anchorPoint, tl, tex.x, tex.y,
+ minZoom, maxZoom, placementZoom, glyphAngle));
+ buffer.vertices.emplace_back(SymbolAttributes::vertex(anchorPoint, tr, tex.x + tex.w, tex.y,
+ minZoom, maxZoom, placementZoom, glyphAngle));
+ buffer.vertices.emplace_back(SymbolAttributes::vertex(anchorPoint, bl, tex.x, tex.y + tex.h,
+ minZoom, maxZoom, placementZoom, glyphAngle));
+ buffer.vertices.emplace_back(SymbolAttributes::vertex(anchorPoint, br, 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.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;
+ buffer.triangles.emplace_back(index + 0, index + 1, index + 2);
+ buffer.triangles.emplace_back(index + 1, index + 2, index + 3);
+
+ segment.vertexLength += vertexLength;
+ segment.indexLength += 6;
}
}
@@ -496,10 +503,6 @@ void SymbolLayout::addToDebugBuffers(CollisionTile& collisionTile, SymbolBucket&
const float yStretch = collisionTile.yStretch;
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) {
@@ -515,20 +518,31 @@ void SymbolLayout::addToDebugBuffers(CollisionTile& collisionTile, SymbolBucket&
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);
+ const float maxZoom = util::clamp(zoom + util::log2(box.maxScale), util::MIN_ZOOM_F, util::MAX_ZOOM_F);
+ const float placementZoom = util::clamp(zoom + util::log2(box.placementScale), util::MIN_ZOOM_F, util::MAX_ZOOM_F);
+
+ static constexpr std::size_t vertexLength = 4;
+ static constexpr std::size_t indexLength = 8;
+
+ if (collisionBox.segments.empty() || collisionBox.segments.back().vertexLength + vertexLength > std::numeric_limits<uint16_t>::max()) {
+ collisionBox.segments.emplace_back(collisionBox.vertices.vertexSize(), collisionBox.lines.indexSize());
+ }
+
+ auto& segment = collisionBox.segments.back();
+ uint16_t index = segment.vertexLength;
+
+ collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, tl, maxZoom, placementZoom));
+ collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, tr, maxZoom, placementZoom));
+ collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, br, maxZoom, placementZoom));
+ collisionBox.vertices.emplace_back(CollisionBoxProgram::vertex(anchor, bl, maxZoom, placementZoom));
- 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);
+ collisionBox.lines.emplace_back(index + 0, index + 1);
+ collisionBox.lines.emplace_back(index + 1, index + 2);
+ collisionBox.lines.emplace_back(index + 2, index + 3);
+ collisionBox.lines.emplace_back(index + 3, index + 0);
- auto& group = collisionBox.groups.back();
- group.vertexLength += 8;
+ segment.vertexLength += vertexLength;
+ segment.indexLength += indexLength;
}
};
populateCollisionBox(symbolInstance.textCollisionFeature);
diff --git a/src/mbgl/layout/symbol_layout.hpp b/src/mbgl/layout/symbol_layout.hpp
index 54acf84aaf..18fb9ff4bc 100644
--- a/src/mbgl/layout/symbol_layout.hpp
+++ b/src/mbgl/layout/symbol_layout.hpp
@@ -4,6 +4,7 @@
#include <mbgl/style/layers/symbol_layer_properties.hpp>
#include <mbgl/layout/symbol_feature.hpp>
#include <mbgl/layout/symbol_instance.hpp>
+#include <mbgl/text/bidi.hpp>
#include <memory>
#include <map>
@@ -33,7 +34,7 @@ public:
const MapMode,
const GeometryTileLayer&,
const style::Filter&,
- style::SymbolLayoutProperties,
+ style::SymbolLayoutProperties::Evaluated,
float textMaxSize,
SpriteAtlas&);
@@ -58,14 +59,13 @@ public:
const std::string sourceLayerName;
private:
- void addFeature(const GeometryCollection&,
+ void addFeature(const SymbolFeature&,
const Shaping& shapedText,
const PositionedIcon& shapedIcon,
- const GlyphPositions& face,
- const size_t index);
+ const GlyphPositions& face);
- bool anchorIsTooClose(const std::u32string& text, const float repeatDistance, Anchor&);
- std::map<std::u32string, std::vector<Anchor>> compareText;
+ bool anchorIsTooClose(const std::u16string& text, const float repeatDistance, const Anchor&);
+ std::map<std::u16string, std::vector<Anchor>> compareText;
void addToDebugBuffers(CollisionTile&, SymbolBucket&);
@@ -77,7 +77,7 @@ private:
const float overscaling;
const float zoom;
const MapMode mode;
- const style::SymbolLayoutProperties layout;
+ const style::SymbolLayoutProperties::Evaluated layout;
const float textMaxSize;
SpriteAtlas& spriteAtlas;
@@ -91,6 +91,8 @@ private:
GlyphRangeSet ranges;
std::vector<SymbolInstance> symbolInstances;
std::vector<SymbolFeature> features;
+
+ BiDi bidi; // Consider moving this up to geometry tile worker to reduce reinstantiation costs; use of BiDi/ubiditransform object must be constrained to one thread
};
} // namespace mbgl
diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp
index 1efc1c063a..d76044cd47 100644
--- a/src/mbgl/map/map.cpp
+++ b/src/mbgl/map/map.cpp
@@ -23,7 +23,8 @@
#include <mbgl/util/mapbox.hpp>
#include <mbgl/util/tile_coordinate.hpp>
#include <mbgl/actor/scheduler.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
+#include <mbgl/math/log2.hpp>
namespace mbgl {
@@ -46,7 +47,8 @@ struct StillImageRequest {
class Map::Impl : public style::Observer {
public:
- Impl(Backend&,
+ Impl(Map&,
+ Backend&,
float pixelRatio,
FileSource&,
Scheduler&,
@@ -66,6 +68,7 @@ public:
void loadStyleJSON(const std::string&);
+ Map& map;
Backend& backend;
FileSource& fileSource;
Scheduler& scheduler;
@@ -89,6 +92,7 @@ public:
std::string styleURL;
std::string styleJSON;
bool styleMutated = false;
+ bool cameraMutated = false;
std::unique_ptr<AsyncRequest> styleRequest;
@@ -99,7 +103,7 @@ public:
};
Map::Map(Backend& backend,
- const std::array<uint16_t, 2> size,
+ const Size size,
const float pixelRatio,
FileSource& fileSource,
Scheduler& scheduler,
@@ -107,7 +111,8 @@ Map::Map(Backend& backend,
GLContextMode contextMode,
ConstrainMode constrainMode,
ViewportMode viewportMode)
- : impl(std::make_unique<Impl>(backend,
+ : impl(std::make_unique<Impl>(*this,
+ backend,
pixelRatio,
fileSource,
scheduler,
@@ -118,7 +123,8 @@ Map::Map(Backend& backend,
impl->transform.resize(size);
}
-Map::Impl::Impl(Backend& backend_,
+Map::Impl::Impl(Map& map_,
+ Backend& backend_,
float pixelRatio_,
FileSource& fileSource_,
Scheduler& scheduler_,
@@ -126,7 +132,8 @@ Map::Impl::Impl(Backend& backend_,
GLContextMode contextMode_,
ConstrainMode constrainMode_,
ViewportMode viewportMode_)
- : backend(backend_),
+ : map(map_),
+ backend(backend_),
fileSource(fileSource_),
scheduler(scheduler_),
transform([this](MapChange change) { backend.notifyMapChange(change); },
@@ -282,7 +289,7 @@ void Map::Impl::update() {
void Map::Impl::render(View& view) {
if (!painter) {
- painter = std::make_unique<Painter>(backend.getContext(), transform.getState());
+ painter = std::make_unique<Painter>(backend.getContext(), transform.getState(), pixelRatio);
}
FrameData frameData { timePoint,
@@ -384,6 +391,14 @@ void Map::Impl::loadStyleJSON(const std::string& json) {
// force style cascade, causing all pending transitions to complete.
style->cascade(Clock::now(), mode);
+ if (!cameraMutated) {
+ // Zoom first because it may constrain subsequent operations.
+ map.setZoom(map.getDefaultZoom());
+ map.setLatLng(map.getDefaultLatLng());
+ map.setBearing(map.getDefaultBearing());
+ map.setPitch(map.getDefaultPitch());
+ }
+
updateFlags |= Update::Classes | Update::RecalculateStyle | Update::AnnotationStyle;
asyncUpdate.send();
}
@@ -431,16 +446,19 @@ CameraOptions Map::getCameraOptions(optional<EdgeInsets> padding) const {
}
void Map::jumpTo(const CameraOptions& camera) {
+ impl->cameraMutated = true;
impl->transform.jumpTo(camera);
impl->onUpdate(camera.zoom ? Update::RecalculateStyle : Update::Repaint);
}
void Map::easeTo(const CameraOptions& camera, const AnimationOptions& animation) {
+ impl->cameraMutated = true;
impl->transform.easeTo(camera, animation);
impl->onUpdate(camera.zoom ? Update::RecalculateStyle : Update::Repaint);
}
void Map::flyTo(const CameraOptions& camera, const AnimationOptions& animation) {
+ impl->cameraMutated = true;
impl->transform.flyTo(camera, animation);
impl->onUpdate(Update::RecalculateStyle);
}
@@ -448,20 +466,24 @@ void Map::flyTo(const CameraOptions& camera, const AnimationOptions& animation)
#pragma mark - Position
void Map::moveBy(const ScreenCoordinate& point, const Duration& duration) {
+ impl->cameraMutated = true;
impl->transform.moveBy(point, duration);
impl->onUpdate(Update::Repaint);
}
void Map::setLatLng(const LatLng& latLng, const Duration& duration) {
+ impl->cameraMutated = true;
setLatLng(latLng, optional<ScreenCoordinate> {}, duration);
}
void Map::setLatLng(const LatLng& latLng, optional<EdgeInsets> padding, const Duration& duration) {
+ impl->cameraMutated = true;
impl->transform.setLatLng(latLng, padding, duration);
impl->onUpdate(Update::Repaint);
}
void Map::setLatLng(const LatLng& latLng, optional<ScreenCoordinate> anchor, const Duration& duration) {
+ impl->cameraMutated = true;
impl->transform.setLatLng(latLng, anchor, duration);
impl->onUpdate(Update::Repaint);
}
@@ -471,6 +493,7 @@ LatLng Map::getLatLng(optional<EdgeInsets> padding) const {
}
void Map::resetPosition(optional<EdgeInsets> padding) {
+ impl->cameraMutated = true;
CameraOptions camera;
camera.angle = 0;
camera.pitch = 0;
@@ -485,11 +508,13 @@ void Map::resetPosition(optional<EdgeInsets> padding) {
#pragma mark - Scale
void Map::scaleBy(double ds, optional<ScreenCoordinate> anchor, const Duration& duration) {
+ impl->cameraMutated = true;
impl->transform.scaleBy(ds, anchor, duration);
impl->onUpdate(Update::RecalculateStyle);
}
void Map::setScale(double scale, optional<ScreenCoordinate> anchor, const Duration& duration) {
+ impl->cameraMutated = true;
impl->transform.setScale(scale, anchor, duration);
impl->onUpdate(Update::RecalculateStyle);
}
@@ -499,10 +524,12 @@ double Map::getScale() const {
}
void Map::setZoom(double zoom, const Duration& duration) {
+ impl->cameraMutated = true;
setZoom(zoom, {}, duration);
}
void Map::setZoom(double zoom, optional<EdgeInsets> padding, const Duration& duration) {
+ impl->cameraMutated = true;
impl->transform.setZoom(zoom, padding, duration);
impl->onUpdate(Update::RecalculateStyle);
}
@@ -512,10 +539,12 @@ double Map::getZoom() const {
}
void Map::setLatLngZoom(const LatLng& latLng, double zoom, const Duration& duration) {
+ impl->cameraMutated = true;
setLatLngZoom(latLng, zoom, {}, duration);
}
void Map::setLatLngZoom(const LatLng& latLng, double zoom, optional<EdgeInsets> padding, const Duration& duration) {
+ impl->cameraMutated = true;
impl->transform.setLatLngZoom(latLng, zoom, padding, duration);
impl->onUpdate(Update::RecalculateStyle);
}
@@ -538,7 +567,7 @@ CameraOptions Map::cameraForLatLngs(const std::vector<LatLng>& latLngs, optional
// Calculate the bounds of the possibly rotated shape with respect to the viewport.
ScreenCoordinate nePixel = {-INFINITY, -INFINITY};
ScreenCoordinate swPixel = {INFINITY, INFINITY};
- double viewportHeight = getHeight();
+ double viewportHeight = getSize().height;
for (LatLng latLng : latLngs) {
ScreenCoordinate pixel = pixelForLatLng(latLng);
swPixel.x = std::min(swPixel.x, pixel.x);
@@ -552,8 +581,8 @@ CameraOptions Map::cameraForLatLngs(const std::vector<LatLng>& latLngs, optional
// Calculate the zoom level.
double minScale = INFINITY;
if (width > 0 || height > 0) {
- double scaleX = getWidth() / width;
- double scaleY = getHeight() / height;
+ double scaleX = double(getSize().width) / width;
+ double scaleY = double(getSize().height) / height;
if (padding && *padding) {
scaleX -= (padding->left + padding->right) / width;
scaleY -= (padding->top + padding->bottom) / height;
@@ -587,6 +616,7 @@ CameraOptions Map::cameraForLatLngs(const std::vector<LatLng>& latLngs, optional
}
void Map::resetZoom() {
+ impl->cameraMutated = true;
setZoom(0);
}
@@ -614,36 +644,36 @@ double Map::getMaxZoom() const {
#pragma mark - Size
-void Map::setSize(const std::array<uint16_t, 2>& size) {
+void Map::setSize(const Size size) {
impl->transform.resize(size);
impl->onUpdate(Update::Repaint);
}
-uint16_t Map::getWidth() const {
- return impl->transform.getState().getWidth();
-}
-
-uint16_t Map::getHeight() const {
- return impl->transform.getState().getHeight();
+Size Map::getSize() const {
+ return impl->transform.getState().getSize();
}
#pragma mark - Rotation
void Map::rotateBy(const ScreenCoordinate& first, const ScreenCoordinate& second, const Duration& duration) {
+ impl->cameraMutated = true;
impl->transform.rotateBy(first, second, duration);
impl->onUpdate(Update::Repaint);
}
void Map::setBearing(double degrees, const Duration& duration) {
+ impl->cameraMutated = true;
setBearing(degrees, EdgeInsets(), duration);
}
void Map::setBearing(double degrees, optional<ScreenCoordinate> anchor, const Duration& duration) {
+ impl->cameraMutated = true;
impl->transform.setAngle(-degrees * util::DEG2RAD, anchor, duration);
impl->onUpdate(Update::Repaint);
}
void Map::setBearing(double degrees, optional<EdgeInsets> padding, const Duration& duration) {
+ impl->cameraMutated = true;
impl->transform.setAngle(-degrees * util::DEG2RAD, padding, duration);
impl->onUpdate(Update::Repaint);
}
@@ -653,6 +683,7 @@ double Map::getBearing() const {
}
void Map::resetNorth(const Duration& duration) {
+ impl->cameraMutated = true;
impl->transform.setAngle(0, duration);
impl->onUpdate(Update::Repaint);
}
@@ -660,10 +691,12 @@ void Map::resetNorth(const Duration& duration) {
#pragma mark - Pitch
void Map::setPitch(double pitch, const Duration& duration) {
+ impl->cameraMutated = true;
setPitch(pitch, {}, duration);
}
void Map::setPitch(double pitch, optional<ScreenCoordinate> anchor, const Duration& duration) {
+ impl->cameraMutated = true;
impl->transform.setPitch(pitch * util::DEG2RAD, anchor, duration);
impl->onUpdate(Update::Repaint);
}
@@ -789,7 +822,8 @@ AnnotationIDs Map::queryPointAnnotations(const ScreenBox& box) {
std::set<AnnotationID> set;
for (auto &feature : features) {
assert(feature.id);
- assert(*feature.id <= std::numeric_limits<AnnotationID>::max());
+ assert(feature.id->is<uint64_t>());
+ assert(feature.id->get<uint64_t>() <= std::numeric_limits<AnnotationID>::max());
set.insert(static_cast<AnnotationID>(feature.id->get<uint64_t>()));
}
AnnotationIDs ids;
@@ -826,7 +860,7 @@ std::unique_ptr<Source> Map::removeSource(const std::string& sourceID) {
}
return nullptr;
}
-
+
std::vector<style::Layer*> Map::getLayers() {
return impl->style ? impl->style->getLayers() : std::vector<style::Layer*>();
}
diff --git a/src/mbgl/map/transform.cpp b/src/mbgl/map/transform.cpp
index 85805a109d..ba5e205301 100644
--- a/src/mbgl/map/transform.cpp
+++ b/src/mbgl/map/transform.cpp
@@ -9,8 +9,8 @@
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/projection.hpp>
#include <mbgl/math/clamp.hpp>
-#include <mbgl/platform/log.hpp>
-#include <mbgl/platform/platform.hpp>
+#include <mbgl/util/logging.hpp>
+#include <mbgl/util/platform.hpp>
#include <cstdio>
#include <cmath>
@@ -45,8 +45,8 @@ Transform::Transform(std::function<void(MapChange)> callback_,
#pragma mark - Map View
-bool Transform::resize(const std::array<uint16_t, 2> size) {
- if (state.width == size[0] && state.height == size[1]) {
+bool Transform::resize(const Size size) {
+ if (state.size == size) {
return false;
}
@@ -54,8 +54,7 @@ bool Transform::resize(const std::array<uint16_t, 2> size) {
callback(MapChangeRegionWillChange);
}
- state.width = size[0];
- state.height = size[1];
+ state.size = size;
state.constrain(state.scale, state.x, state.y);
if (callback) {
@@ -117,7 +116,7 @@ void Transform::easeTo(const CameraOptions& camera, const AnimationOptions& anim
const Point<double> endPoint = Projection::project(latLng, state.scale);
ScreenCoordinate center = getScreenCoordinate(padding);
- center.y = state.height - center.y;
+ center.y = state.size.height - center.y;
// Constrain camera options.
zoom = util::clamp(zoom, state.getMinZoom(), state.getMaxZoom());
@@ -187,7 +186,7 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima
const Point<double> endPoint = Projection::project(latLng, state.scale);
ScreenCoordinate center = getScreenCoordinate(padding);
- center.y = state.height - center.y;
+ center.y = state.size.height - center.y;
// Constrain camera options.
zoom = util::clamp(zoom, state.getMinZoom(), state.getMaxZoom());
@@ -203,9 +202,9 @@ void Transform::flyTo(const CameraOptions &camera, const AnimationOptions &anima
/// w₀: Initial visible span, measured in pixels at the initial scale.
/// Known henceforth as a <i>screenful</i>.
- double w0 = padding ? std::max(state.width, state.height)
- : std::max(state.width - padding.left - padding.right,
- state.height - padding.top - padding.bottom);
+ double w0 = padding ? std::max(state.size.width, state.size.height)
+ : std::max(state.size.width - padding.left - padding.right,
+ state.size.height - padding.top - padding.bottom);
/// w₁: Final visible span, measured in pixels with respect to the initial
/// scale.
double w1 = w0 / state.zoomScale(zoom - startZoom);
@@ -355,8 +354,8 @@ void Transform::setLatLng(const LatLng& latLng, optional<ScreenCoordinate> ancho
EdgeInsets padding;
padding.top = anchor->y;
padding.left = anchor->x;
- padding.bottom = state.height - anchor->y;
- padding.right = state.width - anchor->x;
+ padding.bottom = state.size.height - anchor->y;
+ padding.right = state.size.width - anchor->x;
if (padding) camera.padding = padding;
}
easeTo(camera, duration);
@@ -378,7 +377,7 @@ void Transform::setLatLngZoom(const LatLng& latLng, double zoom, optional<EdgeIn
LatLng Transform::getLatLng(optional<EdgeInsets> padding) const {
if (padding && *padding) {
- return screenCoordinateToLatLng(padding->getCenter(state.width, state.height));
+ return screenCoordinateToLatLng(padding->getCenter(state.size.width, state.size.height));
} else {
return state.getLatLng();
}
@@ -386,9 +385,9 @@ LatLng Transform::getLatLng(optional<EdgeInsets> padding) const {
ScreenCoordinate Transform::getScreenCoordinate(optional<EdgeInsets> padding) const {
if (padding && *padding) {
- return padding->getCenter(state.width, state.height);
+ return padding->getCenter(state.size.width, state.size.height);
} else {
- return { state.width / 2., state.height / 2. };
+ return { state.size.width / 2., state.size.height / 2. };
}
}
@@ -565,7 +564,7 @@ void Transform::startTransition(const CameraOptions& camera,
optional<ScreenCoordinate> anchor = camera.anchor;
LatLng anchorLatLng;
if (anchor) {
- anchor->y = state.getHeight() - anchor->y;
+ anchor->y = state.size.height - anchor->y;
anchorLatLng = state.screenCoordinateToLatLng(*anchor);
}
@@ -650,13 +649,13 @@ ScreenCoordinate Transform::latLngToScreenCoordinate(const LatLng& latLng) const
LatLng unwrappedLatLng = latLng.wrapped();
unwrappedLatLng.unwrapForShortestPath(getLatLng());
ScreenCoordinate point = state.latLngToScreenCoordinate(unwrappedLatLng);
- point.y = state.height - point.y;
+ point.y = state.size.height - point.y;
return point;
}
LatLng Transform::screenCoordinateToLatLng(const ScreenCoordinate& point) const {
ScreenCoordinate flippedPoint = point;
- flippedPoint.y = state.height - flippedPoint.y;
+ flippedPoint.y = state.size.height - flippedPoint.y;
return state.screenCoordinateToLatLng(flippedPoint).wrapped();
}
diff --git a/src/mbgl/map/transform.hpp b/src/mbgl/map/transform.hpp
index abc301b1cb..febe71035d 100644
--- a/src/mbgl/map/transform.hpp
+++ b/src/mbgl/map/transform.hpp
@@ -23,7 +23,7 @@ public:
ViewportMode = ViewportMode::Default);
// Map view
- bool resize(std::array<uint16_t, 2> size);
+ bool resize(Size size);
// Camera
/** Returns the current camera options. */
diff --git a/src/mbgl/map/transform_state.cpp b/src/mbgl/map/transform_state.cpp
index 4f6bcecdb6..59ae129518 100644
--- a/src/mbgl/map/transform_state.cpp
+++ b/src/mbgl/map/transform_state.cpp
@@ -2,7 +2,7 @@
#include <mbgl/tile/tile_id.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/interpolate.hpp>
-#include <mbgl/util/math.hpp>
+#include <mbgl/math/log2.hpp>
#include <mbgl/math/clamp.hpp>
namespace mbgl {
@@ -33,15 +33,16 @@ void TransformState::getProjMatrix(mat4& projMatrix) const {
// Calculate z value of the farthest fragment that should be rendered.
double farZ = std::cos(M_PI / 2.0f - getPitch()) * topHalfSurfaceDistance + getAltitude();
- matrix::perspective(projMatrix, 2.0f * std::atan((getHeight() / 2.0f) / getAltitude()),
- double(getWidth()) / getHeight(), 0.1, farZ);
+ matrix::perspective(projMatrix, 2.0f * std::atan((size.height / 2.0f) / getAltitude()),
+ double(size.width) / size.height, 0.1, farZ);
matrix::translate(projMatrix, projMatrix, 0, 0, -getAltitude());
// After the rotateX, z values are in pixel units. Convert them to
// altitude unites. 1 altitude unit = the screen height.
const bool flippedY = viewportMode == ViewportMode::FlippedY;
- matrix::scale(projMatrix, projMatrix, 1, flippedY ? 1 : -1, 1.0f / (rotatedNorth() ? getWidth() : getHeight()));
+ matrix::scale(projMatrix, projMatrix, 1, flippedY ? 1 : -1,
+ 1.0f / (rotatedNorth() ? size.width : size.height));
using NO = NorthOrientation;
switch (getNorthOrientation()) {
@@ -53,18 +54,14 @@ void TransformState::getProjMatrix(mat4& projMatrix) const {
matrix::rotate_z(projMatrix, projMatrix, getAngle() + getNorthOrientationAngle());
- matrix::translate(projMatrix, projMatrix, pixel_x() - getWidth() / 2.0f,
- pixel_y() - getHeight() / 2.0f, 0);
+ matrix::translate(projMatrix, projMatrix, pixel_x() - size.width / 2.0f,
+ pixel_y() - size.height / 2.0f, 0);
}
#pragma mark - Dimensions
-uint16_t TransformState::getWidth() const {
- return width;
-}
-
-uint16_t TransformState::getHeight() const {
- return height;
+Size TransformState::getSize() const {
+ return size;
}
#pragma mark - North Orientation
@@ -108,23 +105,23 @@ LatLng TransformState::getLatLng(LatLng::WrapMode wrapMode) const {
}
double TransformState::pixel_x() const {
- const double center = (width - Projection::worldSize(scale)) / 2;
+ const double center = (size.width - Projection::worldSize(scale)) / 2;
return center + x;
}
double TransformState::pixel_y() const {
- const double center = (height - Projection::worldSize(scale)) / 2;
+ const double center = (size.height - Projection::worldSize(scale)) / 2;
return center + y;
}
#pragma mark - Zoom
double TransformState::getZoom() const {
- return std::log(scale) / M_LN2;
+ return scaleZoom(scale);
}
int32_t TransformState::getIntegerZoom() const {
- return std::floor(getZoom());
+ return getZoom();
}
double TransformState::getZoomFraction() const {
@@ -202,7 +199,7 @@ bool TransformState::isGestureInProgress() const {
#pragma mark - Projection
double TransformState::zoomScale(double zoom) const {
- return std::pow(2.0f, zoom);
+ return std::pow(2.0, zoom);
}
double TransformState::scaleZoom(double s) const {
@@ -210,7 +207,7 @@ double TransformState::scaleZoom(double s) const {
}
ScreenCoordinate TransformState::latLngToScreenCoordinate(const LatLng& latLng) const {
- if (width == 0 || height == 0) {
+ if (!size) {
return {};
}
@@ -219,11 +216,11 @@ ScreenCoordinate TransformState::latLngToScreenCoordinate(const LatLng& latLng)
Point<double> pt = Projection::project(latLng, scale) / double(util::tileSize);
vec4 c = {{ pt.x, pt.y, 0, 1 }};
matrix::transformMat4(p, c, mat);
- return { p[0] / p[3], height - p[1] / p[3] };
+ return { p[0] / p[3], size.height - p[1] / p[3] };
}
LatLng TransformState::screenCoordinateToLatLng(const ScreenCoordinate& point, LatLng::WrapMode wrapMode) const {
- if (width == 0 || height == 0) {
+ if (!size) {
return {};
}
@@ -235,7 +232,7 @@ LatLng TransformState::screenCoordinateToLatLng(const ScreenCoordinate& point, L
if (err) throw std::runtime_error("failed to invert coordinatePointMatrix");
- double flippedY = height - point.y;
+ double flippedY = size.height - point.y;
// since we don't know the correct projected z value for the point,
// unproject two points to get a line and then find the point on that
@@ -273,7 +270,8 @@ mat4 TransformState::coordinatePointMatrix(double z) const {
mat4 TransformState::getPixelMatrix() const {
mat4 m;
matrix::identity(m);
- matrix::scale(m, m, width / 2.0f, -height / 2.0f, 1);
+ matrix::scale(m, m,
+ static_cast<double>(size.width) / 2, -static_cast<double>(size.height) / 2, 1);
matrix::translate(m, m, 1, -1, 0);
return m;
}
@@ -289,17 +287,17 @@ bool TransformState::rotatedNorth() const {
void TransformState::constrain(double& scale_, double& x_, double& y_) const {
// Constrain minimum scale to avoid zooming out far enough to show off-world areas.
scale_ = util::max(scale_,
- static_cast<double>((rotatedNorth() ? height : width) / util::tileSize),
- static_cast<double>((rotatedNorth() ? width : height) / util::tileSize));
+ static_cast<double>(rotatedNorth() ? size.height : size.width) / util::tileSize,
+ static_cast<double>(rotatedNorth() ? size.width : size.height) / util::tileSize);
// Constrain min/max pan to avoid showing off-world areas.
if (constrainMode == ConstrainMode::WidthAndHeight) {
- double max_x = (scale_ * util::tileSize - (rotatedNorth() ? height : width)) / 2;
+ double max_x = (scale_ * util::tileSize - (rotatedNorth() ? size.height : size.width)) / 2;
x_ = std::max(-max_x, std::min(x_, max_x));
}
if (constrainMode != ConstrainMode::None) {
- double max_y = (scale_ * util::tileSize - (rotatedNorth() ? width : height)) / 2;
+ double max_y = (scale_ * util::tileSize - (rotatedNorth() ? size.width : size.height)) / 2;
y_ = std::max(-max_y, std::min(y_, max_y));
}
}
diff --git a/src/mbgl/map/transform_state.hpp b/src/mbgl/map/transform_state.hpp
index 8a12b62a9e..6faaf4ac41 100644
--- a/src/mbgl/map/transform_state.hpp
+++ b/src/mbgl/map/transform_state.hpp
@@ -6,6 +6,7 @@
#include <mbgl/util/constants.hpp>
#include <mbgl/util/projection.hpp>
#include <mbgl/util/mat4.hpp>
+#include <mbgl/util/size.hpp>
#include <cstdint>
#include <array>
@@ -26,8 +27,7 @@ public:
void getProjMatrix(mat4& matrix) const;
// Dimensions
- uint16_t getWidth() const;
- uint16_t getHeight() const;
+ Size getSize() const;
// North Orientation
NorthOrientation getNorthOrientation() const;
@@ -84,7 +84,7 @@ private:
NorthOrientation orientation = NorthOrientation::Upwards;
// logical dimensions
- uint16_t width = 0, height = 0;
+ Size size;
mat4 coordinatePointMatrix(double z) const;
mat4 getPixelMatrix() const;
diff --git a/src/mbgl/util/math.cpp b/src/mbgl/math/log2.cpp
index 7b1516c041..222e67dbd7 100644
--- a/src/mbgl/util/math.cpp
+++ b/src/mbgl/math/log2.cpp
@@ -1,4 +1,4 @@
-#include <mbgl/util/math.hpp>
+#include <mbgl/math/log2.hpp>
namespace mbgl {
namespace util {
@@ -21,15 +21,5 @@ uint32_t ceil_log2(uint64_t x) {
return y;
}
-double log2(double x) {
-// log2() is producing wrong results on ARMv5 binaries
-// running on ARMv7+ CPUs.
-#if defined(__ANDROID__)
- return std::log(x) / 0.6931471805599453; // log(x) / log(2)
-#else
- return ::log2(x);
-#endif
-}
-
} // namespace util
} // namespace mbgl
diff --git a/src/mbgl/programs/attributes.hpp b/src/mbgl/programs/attributes.hpp
new file mode 100644
index 0000000000..38bbe89377
--- /dev/null
+++ b/src/mbgl/programs/attributes.hpp
@@ -0,0 +1,23 @@
+#pragma once
+
+#include <mbgl/gl/attribute.hpp>
+
+#include <cstdint>
+
+namespace mbgl {
+namespace attributes {
+
+// Attributes common to several shaders.
+
+MBGL_DEFINE_ATTRIBUTE(int16_t, 2, a_pos);
+MBGL_DEFINE_ATTRIBUTE(int16_t, 2, a_offset);
+MBGL_DEFINE_ATTRIBUTE(int16_t, 2, a_extrude);
+MBGL_DEFINE_ATTRIBUTE(uint16_t, 2, a_texture_pos);
+
+template <std::size_t N>
+struct a_data : gl::Attribute<a_data<N>, uint8_t, N> {
+ static constexpr auto name = "a_data";
+};
+
+} // namespace attributes
+} // namespace mbgl
diff --git a/src/mbgl/programs/circle_program.cpp b/src/mbgl/programs/circle_program.cpp
new file mode 100644
index 0000000000..d6bc439feb
--- /dev/null
+++ b/src/mbgl/programs/circle_program.cpp
@@ -0,0 +1,7 @@
+#include <mbgl/programs/circle_program.hpp>
+
+namespace mbgl {
+
+static_assert(sizeof(CircleProgram::Vertex) == 4, "expected CircleVertex size");
+
+} // namespace mbgl
diff --git a/src/mbgl/programs/circle_program.hpp b/src/mbgl/programs/circle_program.hpp
new file mode 100644
index 0000000000..c9aea1d137
--- /dev/null
+++ b/src/mbgl/programs/circle_program.hpp
@@ -0,0 +1,59 @@
+#pragma once
+
+#include <mbgl/programs/program.hpp>
+#include <mbgl/programs/attributes.hpp>
+#include <mbgl/programs/uniforms.hpp>
+#include <mbgl/shader/circle.hpp>
+#include <mbgl/util/geometry.hpp>
+
+namespace mbgl {
+
+namespace uniforms {
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_radius);
+MBGL_DEFINE_UNIFORM_SCALAR(Color, u_stroke_color);
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_stroke_width);
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_stroke_opacity);
+MBGL_DEFINE_UNIFORM_SCALAR(bool, u_scale_with_map);
+} // namespace uniforms
+
+using CircleAttributes = gl::Attributes<
+ attributes::a_pos>;
+
+class CircleProgram : public Program<
+ shaders::circle,
+ gl::Triangle,
+ CircleAttributes,
+ gl::Uniforms<
+ uniforms::u_matrix,
+ uniforms::u_opacity,
+ uniforms::u_color,
+ uniforms::u_radius,
+ uniforms::u_blur,
+ uniforms::u_stroke_color,
+ uniforms::u_stroke_width,
+ uniforms::u_stroke_opacity,
+ uniforms::u_scale_with_map,
+ uniforms::u_extrude_scale>>
+{
+public:
+ using Program::Program;
+
+ /*
+ * @param {number} x vertex position
+ * @param {number} y vertex position
+ * @param {number} ex extrude normal
+ * @param {number} ey extrude normal
+ */
+ static Vertex vertex(Point<int16_t> p, float ex, float ey) {
+ return Vertex {
+ {
+ static_cast<int16_t>((p.x * 2) + ((ex + 1) / 2)),
+ static_cast<int16_t>((p.y * 2) + ((ey + 1) / 2))
+ }
+ };
+ }
+};
+
+using CircleVertex = CircleProgram::Vertex;
+
+} // namespace mbgl
diff --git a/src/mbgl/programs/collision_box_program.cpp b/src/mbgl/programs/collision_box_program.cpp
new file mode 100644
index 0000000000..d6a36e54a1
--- /dev/null
+++ b/src/mbgl/programs/collision_box_program.cpp
@@ -0,0 +1,7 @@
+#include <mbgl/programs/collision_box_program.hpp>
+
+namespace mbgl {
+
+static_assert(sizeof(CollisionBoxProgram::Vertex) == 10, "expected CollisionBoxVertex size");
+
+} // namespace mbgl
diff --git a/src/mbgl/programs/collision_box_program.hpp b/src/mbgl/programs/collision_box_program.hpp
new file mode 100644
index 0000000000..26e38419a4
--- /dev/null
+++ b/src/mbgl/programs/collision_box_program.hpp
@@ -0,0 +1,56 @@
+#pragma once
+
+#include <mbgl/programs/program.hpp>
+#include <mbgl/programs/attributes.hpp>
+#include <mbgl/programs/uniforms.hpp>
+#include <mbgl/shader/collision_box.hpp>
+#include <mbgl/util/geometry.hpp>
+
+#include <cmath>
+
+namespace mbgl {
+
+namespace uniforms {
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_scale);
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_maxzoom);
+} // namespace uniforms
+
+using CollisionBoxAttributes = gl::Attributes<
+ attributes::a_pos,
+ attributes::a_extrude,
+ attributes::a_data<2>>;
+
+class CollisionBoxProgram : public Program<
+ shaders::collision_box,
+ gl::Line,
+ CollisionBoxAttributes,
+ gl::Uniforms<
+ uniforms::u_matrix,
+ uniforms::u_scale,
+ uniforms::u_zoom,
+ uniforms::u_maxzoom>>
+{
+public:
+ using Program::Program;
+
+ static Vertex vertex(Point<float> a, Point<float> o, float maxzoom, float placementZoom) {
+ return Vertex {
+ {
+ static_cast<int16_t>(a.x),
+ static_cast<int16_t>(a.y)
+ },
+ {
+ static_cast<int16_t>(::round(o.x)),
+ static_cast<int16_t>(::round(o.y))
+ },
+ {
+ static_cast<uint8_t>(maxzoom * 10),
+ static_cast<uint8_t>(placementZoom * 10)
+ }
+ };
+ }
+};
+
+using CollisionBoxVertex = CollisionBoxProgram::Vertex;
+
+} // namespace mbgl
diff --git a/src/mbgl/programs/debug_program.hpp b/src/mbgl/programs/debug_program.hpp
new file mode 100644
index 0000000000..cd4e08b1bc
--- /dev/null
+++ b/src/mbgl/programs/debug_program.hpp
@@ -0,0 +1,27 @@
+#pragma once
+
+#include <mbgl/programs/program.hpp>
+#include <mbgl/programs/attributes.hpp>
+#include <mbgl/programs/uniforms.hpp>
+#include <mbgl/shader/debug.hpp>
+
+namespace mbgl {
+
+using DebugAttributes = gl::Attributes<
+ attributes::a_pos>;
+
+class DebugProgram : public Program<
+ shaders::debug,
+ gl::Line,
+ DebugAttributes,
+ gl::Uniforms<
+ uniforms::u_matrix,
+ uniforms::u_color>>
+{
+public:
+ using Program::Program;
+};
+
+using DebugVertex = DebugProgram::Vertex;
+
+} // namespace mbgl
diff --git a/src/mbgl/programs/fill_program.cpp b/src/mbgl/programs/fill_program.cpp
new file mode 100644
index 0000000000..a8154d08f9
--- /dev/null
+++ b/src/mbgl/programs/fill_program.cpp
@@ -0,0 +1,47 @@
+#include <mbgl/programs/fill_program.hpp>
+#include <mbgl/sprite/sprite_atlas.hpp>
+#include <mbgl/style/cross_faded_property_evaluator.hpp>
+#include <mbgl/tile/tile_id.hpp>
+#include <mbgl/map/transform_state.hpp>
+
+namespace mbgl {
+
+using namespace style;
+
+static_assert(sizeof(FillAttributes::Vertex) == 4, "expected FillVertex size");
+
+FillPatternUniforms::Values
+FillPatternUniforms::values(mat4 matrix,
+ float opacity,
+ Size framebufferSize,
+ const SpriteAtlasPosition& a,
+ const SpriteAtlasPosition& b,
+ const Faded<std::string>& fading,
+ const UnwrappedTileID& tileID,
+ const TransformState& state)
+{
+ int32_t tileSizeAtNearestZoom = util::tileSize * state.zoomScale(state.getIntegerZoom() - tileID.canonical.z);
+ int32_t pixelX = tileSizeAtNearestZoom * (tileID.canonical.x + tileID.wrap * state.zoomScale(tileID.canonical.z));
+ int32_t pixelY = tileSizeAtNearestZoom * tileID.canonical.y;
+
+ return FillPatternUniforms::Values {
+ uniforms::u_matrix::Value{ matrix },
+ uniforms::u_opacity::Value{ opacity },
+ uniforms::u_world::Value{ framebufferSize },
+ uniforms::u_pattern_tl_a::Value{ a.tl },
+ uniforms::u_pattern_br_a::Value{ a.br },
+ uniforms::u_pattern_tl_b::Value{ b.tl },
+ uniforms::u_pattern_br_b::Value{ b.br },
+ uniforms::u_pattern_size_a::Value{ a.size },
+ uniforms::u_pattern_size_b::Value{ b.size },
+ uniforms::u_scale_a::Value{ fading.fromScale },
+ uniforms::u_scale_b::Value{ fading.toScale },
+ uniforms::u_mix::Value{ fading.t },
+ uniforms::u_image::Value{ 0 },
+ uniforms::u_pixel_coord_upper::Value{ std::array<float, 2> {{ float(pixelX >> 16), float(pixelY >> 16) }} },
+ uniforms::u_pixel_coord_lower::Value{ std::array<float, 2> {{ float(pixelX & 0xFFFF), float(pixelY & 0xFFFF) }} },
+ uniforms::u_tile_units_to_pixels::Value{ 1.0f / tileID.pixelsToTileUnits(1.0f, state.getIntegerZoom()) },
+ };
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/programs/fill_program.hpp b/src/mbgl/programs/fill_program.hpp
new file mode 100644
index 0000000000..d885215c59
--- /dev/null
+++ b/src/mbgl/programs/fill_program.hpp
@@ -0,0 +1,123 @@
+#pragma once
+
+#include <mbgl/programs/program.hpp>
+#include <mbgl/programs/attributes.hpp>
+#include <mbgl/programs/uniforms.hpp>
+#include <mbgl/shader/fill.hpp>
+#include <mbgl/shader/fill_pattern.hpp>
+#include <mbgl/shader/fill_outline.hpp>
+#include <mbgl/shader/fill_outline_pattern.hpp>
+#include <mbgl/util/geometry.hpp>
+#include <mbgl/util/mat4.hpp>
+#include <mbgl/util/size.hpp>
+
+#include <string>
+
+namespace mbgl {
+
+class SpriteAtlasPosition;
+class UnwrappedTileID;
+class TransformState;
+
+namespace style {
+template <class> class Faded;
+} // namespace style
+
+namespace uniforms {
+MBGL_DEFINE_UNIFORM_SCALAR(Size, u_world);
+MBGL_DEFINE_UNIFORM_SCALAR(Color, u_outline_color);
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_scale_a);
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_scale_b);
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_tile_units_to_pixels);
+MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_pixel_coord_upper);
+MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_pixel_coord_lower);
+} // namespace uniforms
+
+struct FillAttributes : gl::Attributes<
+ attributes::a_pos>
+{
+ static Vertex vertex(Point<int16_t> p) {
+ return Vertex {
+ {
+ p.x,
+ p.y
+ }
+ };
+ }
+};
+
+using FillVertex = FillAttributes::Vertex;
+
+struct FillUniforms : gl::Uniforms<
+ uniforms::u_matrix,
+ uniforms::u_opacity,
+ uniforms::u_color,
+ uniforms::u_outline_color,
+ uniforms::u_world>
+{};
+
+struct FillPatternUniforms : gl::Uniforms<
+ uniforms::u_matrix,
+ uniforms::u_opacity,
+ uniforms::u_world,
+ uniforms::u_pattern_tl_a,
+ uniforms::u_pattern_br_a,
+ uniforms::u_pattern_tl_b,
+ uniforms::u_pattern_br_b,
+ uniforms::u_pattern_size_a,
+ uniforms::u_pattern_size_b,
+ uniforms::u_scale_a,
+ uniforms::u_scale_b,
+ uniforms::u_mix,
+ uniforms::u_image,
+ uniforms::u_pixel_coord_upper,
+ uniforms::u_pixel_coord_lower,
+ uniforms::u_tile_units_to_pixels>
+{
+ static Values values(mat4 matrix,
+ float opacity,
+ Size framebufferSize,
+ const SpriteAtlasPosition&,
+ const SpriteAtlasPosition&,
+ const style::Faded<std::string>&,
+ const UnwrappedTileID&,
+ const TransformState&);
+};
+
+class FillProgram : public Program<
+ shaders::fill,
+ gl::Triangle,
+ FillAttributes,
+ FillUniforms>
+{
+ using Program::Program;
+};
+
+class FillPatternProgram : public Program<
+ shaders::fill_pattern,
+ gl::Triangle,
+ FillAttributes,
+ FillPatternUniforms>
+{
+ using Program::Program;
+};
+
+class FillOutlineProgram : public Program<
+ shaders::fill_outline,
+ gl::Line,
+ FillAttributes,
+ FillUniforms>
+{
+ using Program::Program;
+};
+
+class FillOutlinePatternProgram : public Program<
+ shaders::fill_outline_pattern,
+ gl::Line,
+ FillAttributes,
+ FillPatternUniforms>
+{
+ using Program::Program;
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/programs/line_program.cpp b/src/mbgl/programs/line_program.cpp
new file mode 100644
index 0000000000..2cadaa6c11
--- /dev/null
+++ b/src/mbgl/programs/line_program.cpp
@@ -0,0 +1,129 @@
+#include <mbgl/programs/line_program.hpp>
+#include <mbgl/style/layers/line_layer_properties.hpp>
+#include <mbgl/renderer/render_tile.hpp>
+#include <mbgl/map/transform_state.hpp>
+#include <mbgl/util/mat2.hpp>
+#include <mbgl/sprite/sprite_atlas.hpp>
+#include <mbgl/geometry/line_atlas.hpp>
+
+namespace mbgl {
+
+using namespace style;
+
+static_assert(sizeof(LineAttributes::Vertex) == 8, "expected LineVertex size");
+
+template <class Values, class...Args>
+Values makeValues(const LinePaintProperties::Evaluated& properties,
+ const RenderTile& tile,
+ const TransformState& state,
+ Args&&... args) {
+
+ mat2 antialiasingMatrix;
+ matrix::identity(antialiasingMatrix);
+ matrix::scale(antialiasingMatrix, antialiasingMatrix, 1.0, std::cos(state.getPitch()));
+ matrix::rotate(antialiasingMatrix, antialiasingMatrix, state.getAngle());
+
+ // calculate how much longer the real world distance is at the top of the screen
+ // than at the middle of the screen.
+ float topedgelength = std::sqrt(std::pow(state.getSize().height, 2.0f) / 4.0f * (1.0f + std::pow(state.getAltitude(), 2.0f)));
+ float x = state.getSize().height / 2.0f * std::tan(state.getPitch());
+
+ return Values {
+ uniforms::u_matrix::Value{
+ tile.translatedMatrix(properties.get<LineTranslate>(),
+ properties.get<LineTranslateAnchor>(),
+ state)
+ },
+ uniforms::u_opacity::Value{ properties.get<LineOpacity>() },
+ uniforms::u_width::Value{ properties.get<LineWidth>() },
+ uniforms::u_gapwidth::Value{ properties.get<LineGapWidth>() },
+ uniforms::u_blur::Value{ properties.get<LineBlur>() },
+ uniforms::u_offset::Value{ properties.get<LineOffset>() },
+ uniforms::u_antialiasingmatrix::Value{ antialiasingMatrix },
+ uniforms::u_ratio::Value{ 1.0f / tile.id.pixelsToTileUnits(1.0, state.getZoom()) },
+ uniforms::u_extra::Value{ (topedgelength + x) / topedgelength - 1.0f },
+ std::forward<Args>(args)...
+ };
+}
+
+LineProgram::UniformValues
+LineProgram::uniformValues(const LinePaintProperties::Evaluated& properties,
+ const RenderTile& tile,
+ const TransformState& state) {
+ return makeValues<LineProgram::UniformValues>(
+ properties,
+ tile,
+ state,
+ uniforms::u_color::Value{ properties.get<LineColor>() }
+ );
+}
+
+LineSDFProgram::UniformValues
+LineSDFProgram::uniformValues(const LinePaintProperties::Evaluated& properties,
+ float pixelRatio,
+ const RenderTile& tile,
+ const TransformState& state,
+ const LinePatternPos& posA,
+ const LinePatternPos& posB,
+ float dashLineWidth,
+ float atlasWidth) {
+ const float widthA = posA.width * properties.get<LineDasharray>().fromScale * dashLineWidth;
+ const float widthB = posB.width * properties.get<LineDasharray>().toScale * dashLineWidth;
+
+ std::array<float, 2> scaleA {{
+ 1.0f / tile.id.pixelsToTileUnits(widthA, state.getIntegerZoom()),
+ -posA.height / 2.0f
+ }};
+
+ std::array<float, 2> scaleB {{
+ 1.0f / tile.id.pixelsToTileUnits(widthB, state.getIntegerZoom()),
+ -posB.height / 2.0f
+ }};
+
+ return makeValues<LineSDFProgram::UniformValues>(
+ properties,
+ tile,
+ state,
+ uniforms::u_color::Value{ properties.get<LineColor>() },
+ uniforms::u_patternscale_a::Value{ scaleA },
+ uniforms::u_patternscale_b::Value{ scaleB },
+ uniforms::u_tex_y_a::Value{ posA.y },
+ uniforms::u_tex_y_b::Value{ posB.y },
+ uniforms::u_mix::Value{ properties.get<LineDasharray>().t },
+ uniforms::u_sdfgamma::Value{ atlasWidth / (std::min(widthA, widthB) * 256.0f * pixelRatio) / 2.0f },
+ uniforms::u_image::Value{ 0 }
+ );
+}
+
+LinePatternProgram::UniformValues
+LinePatternProgram::uniformValues(const LinePaintProperties::Evaluated& properties,
+ const RenderTile& tile,
+ const TransformState& state,
+ const SpriteAtlasPosition& posA,
+ const SpriteAtlasPosition& posB) {
+ std::array<float, 2> sizeA {{
+ tile.id.pixelsToTileUnits(posA.size[0] * properties.get<LinePattern>().fromScale, state.getIntegerZoom()),
+ posA.size[1]
+ }};
+
+ std::array<float, 2> sizeB {{
+ tile.id.pixelsToTileUnits(posB.size[0] * properties.get<LinePattern>().toScale, state.getIntegerZoom()),
+ posB.size[1]
+ }};
+
+ return makeValues<LinePatternProgram::UniformValues>(
+ properties,
+ tile,
+ state,
+ uniforms::u_pattern_tl_a::Value{ posA.tl },
+ uniforms::u_pattern_br_a::Value{ posA.br },
+ uniforms::u_pattern_tl_b::Value{ posB.tl },
+ uniforms::u_pattern_br_b::Value{ posB.br },
+ uniforms::u_pattern_size_a::Value{ sizeA },
+ uniforms::u_pattern_size_b::Value{ sizeB },
+ uniforms::u_fade::Value{ properties.get<LinePattern>().t },
+ uniforms::u_image::Value{ 0 }
+ );
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/programs/line_program.hpp b/src/mbgl/programs/line_program.hpp
new file mode 100644
index 0000000000..059806ffb2
--- /dev/null
+++ b/src/mbgl/programs/line_program.hpp
@@ -0,0 +1,178 @@
+#pragma once
+
+#include <mbgl/programs/program.hpp>
+#include <mbgl/programs/attributes.hpp>
+#include <mbgl/programs/uniforms.hpp>
+#include <mbgl/shader/line.hpp>
+#include <mbgl/shader/line_pattern.hpp>
+#include <mbgl/shader/line_sdf.hpp>
+#include <mbgl/style/layers/line_layer_properties.hpp>
+#include <mbgl/util/geometry.hpp>
+
+#include <cmath>
+
+namespace mbgl {
+
+class RenderTile;
+class TransformState;
+class LinePatternPos;
+class SpriteAtlasPosition;
+
+namespace uniforms {
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_ratio);
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_width);
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_gapwidth);
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_extra);
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_offset);
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_tex_y_a);
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_tex_y_b);
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_sdfgamma);
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_fade);
+MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_patternscale_a);
+MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_patternscale_b);
+MBGL_DEFINE_UNIFORM_MATRIX(double, 2, u_antialiasingmatrix);
+} // namespace uniforms
+
+struct LineAttributes : gl::Attributes<
+ attributes::a_pos,
+ attributes::a_data<4>>
+{
+ /*
+ * @param p vertex position
+ * @param e extrude normal
+ * @param t texture normal
+ * @param dir direction of the line cap (-1/0/1)
+ */
+ static Vertex vertex(Point<int16_t> p, Point<double> e, Point<bool> t, int8_t dir, int32_t linesofar = 0) {
+ return Vertex {
+ {
+ static_cast<int16_t>((p.x * 2) | t.x),
+ static_cast<int16_t>((p.y * 2) | t.y)
+ },
+ {
+ // add 128 to store an byte in an unsigned byte
+ static_cast<uint8_t>(::round(extrudeScale * e.x) + 128),
+ static_cast<uint8_t>(::round(extrudeScale * e.y) + 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)
+ }
+ };
+ }
+
+ /*
+ * 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;
+};
+
+using LineVertex = LineAttributes::Vertex;
+
+class LineProgram : public Program<
+ shaders::line,
+ gl::Triangle,
+ LineAttributes,
+ gl::Uniforms<
+ uniforms::u_matrix,
+ uniforms::u_opacity,
+ uniforms::u_width,
+ uniforms::u_gapwidth,
+ uniforms::u_blur,
+ uniforms::u_offset,
+ uniforms::u_antialiasingmatrix,
+ uniforms::u_ratio,
+ uniforms::u_extra,
+ uniforms::u_color>>
+{
+public:
+ using Program::Program;
+
+ static UniformValues uniformValues(const style::LinePaintProperties::Evaluated&,
+ const RenderTile&,
+ const TransformState&);
+};
+
+class LinePatternProgram : public Program<
+ shaders::line_pattern,
+ gl::Triangle,
+ LineAttributes,
+ gl::Uniforms<
+ uniforms::u_matrix,
+ uniforms::u_opacity,
+ uniforms::u_width,
+ uniforms::u_gapwidth,
+ uniforms::u_blur,
+ uniforms::u_offset,
+ uniforms::u_antialiasingmatrix,
+ uniforms::u_ratio,
+ uniforms::u_extra,
+ uniforms::u_pattern_tl_a,
+ uniforms::u_pattern_br_a,
+ uniforms::u_pattern_tl_b,
+ uniforms::u_pattern_br_b,
+ uniforms::u_pattern_size_a,
+ uniforms::u_pattern_size_b,
+ uniforms::u_fade,
+ uniforms::u_image>>
+{
+public:
+ using Program::Program;
+
+ static UniformValues uniformValues(const style::LinePaintProperties::Evaluated&,
+ const RenderTile&,
+ const TransformState&,
+ const SpriteAtlasPosition& posA,
+ const SpriteAtlasPosition& posB);
+};
+
+class LineSDFProgram : public Program<
+ shaders::line_sdf,
+ gl::Triangle,
+ LineAttributes,
+ gl::Uniforms<
+ uniforms::u_matrix,
+ uniforms::u_opacity,
+ uniforms::u_width,
+ uniforms::u_gapwidth,
+ uniforms::u_blur,
+ uniforms::u_offset,
+ uniforms::u_antialiasingmatrix,
+ uniforms::u_ratio,
+ uniforms::u_extra,
+ uniforms::u_color,
+ uniforms::u_patternscale_a,
+ uniforms::u_patternscale_b,
+ uniforms::u_tex_y_a,
+ uniforms::u_tex_y_b,
+ uniforms::u_mix,
+ uniforms::u_sdfgamma,
+ uniforms::u_image>>
+{
+public:
+ using Program::Program;
+
+ static UniformValues uniformValues(const style::LinePaintProperties::Evaluated&,
+ float pixelRatio,
+ const RenderTile&,
+ const TransformState&,
+ const LinePatternPos& posA,
+ const LinePatternPos& posB,
+ float dashLineWidth,
+ float atlasWidth);
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/programs/program.hpp b/src/mbgl/programs/program.hpp
new file mode 100644
index 0000000000..e5aae24997
--- /dev/null
+++ b/src/mbgl/programs/program.hpp
@@ -0,0 +1,43 @@
+#pragma once
+
+#include <mbgl/gl/program.hpp>
+#include <mbgl/programs/program_parameters.hpp>
+
+#include <sstream>
+#include <cassert>
+
+namespace mbgl {
+
+template <class Shaders, class Primitive, class Attributes, class Uniforms>
+class Program : public gl::Program<Primitive, Attributes, Uniforms> {
+public:
+ using ParentType = gl::Program<Primitive, Attributes, Uniforms>;
+
+ Program(gl::Context& context, const ProgramParameters& programParameters)
+ : ParentType(context, vertexSource(programParameters), fragmentSource(programParameters))
+ {}
+
+ static std::string pixelRatioDefine(const ProgramParameters& parameters) {
+ std::ostringstream pixelRatioSS;
+ pixelRatioSS.imbue(std::locale("C"));
+ pixelRatioSS.setf(std::ios_base::showpoint);
+ pixelRatioSS << parameters.pixelRatio;
+ return std::string("#define DEVICE_PIXEL_RATIO ") + pixelRatioSS.str() + "\n";
+ }
+
+ static std::string fragmentSource(const ProgramParameters& parameters) {
+ std::string source = pixelRatioDefine(parameters) + Shaders::fragmentSource;
+ if (parameters.overdraw) {
+ assert(source.find("#ifdef OVERDRAW_INSPECTOR") != std::string::npos);
+ source.replace(source.find_first_of('\n'), 1, "\n#define OVERDRAW_INSPECTOR\n");
+ }
+ return source;
+ }
+
+ static std::string vertexSource(const ProgramParameters& parameters) {
+ return pixelRatioDefine(parameters) + Shaders::vertexSource;
+ }
+
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/programs/program_parameters.hpp b/src/mbgl/programs/program_parameters.hpp
new file mode 100644
index 0000000000..ad8cbf1bf8
--- /dev/null
+++ b/src/mbgl/programs/program_parameters.hpp
@@ -0,0 +1,16 @@
+#pragma once
+
+namespace mbgl {
+
+class ProgramParameters {
+public:
+ ProgramParameters(float pixelRatio_ = 1.0, bool overdraw_ = false)
+ : pixelRatio(pixelRatio_),
+ overdraw(overdraw_) {}
+
+ float pixelRatio;
+ bool overdraw;
+};
+
+} // namespace mbgl
+
diff --git a/src/mbgl/programs/programs.hpp b/src/mbgl/programs/programs.hpp
new file mode 100644
index 0000000000..dd71c2ce97
--- /dev/null
+++ b/src/mbgl/programs/programs.hpp
@@ -0,0 +1,50 @@
+#pragma once
+
+#include <mbgl/programs/circle_program.hpp>
+#include <mbgl/programs/fill_program.hpp>
+#include <mbgl/programs/line_program.hpp>
+#include <mbgl/programs/raster_program.hpp>
+#include <mbgl/programs/symbol_program.hpp>
+#include <mbgl/programs/debug_program.hpp>
+#include <mbgl/programs/collision_box_program.hpp>
+#include <mbgl/programs/program_parameters.hpp>
+
+namespace mbgl {
+
+class Programs {
+public:
+ Programs(gl::Context& context, const ProgramParameters& programParameters)
+ : circle(context, programParameters),
+ fill(context, programParameters),
+ fillPattern(context, programParameters),
+ fillOutline(context, programParameters),
+ fillOutlinePattern(context, programParameters),
+ line(context, programParameters),
+ lineSDF(context, programParameters),
+ linePattern(context, programParameters),
+ raster(context, programParameters),
+ symbolIcon(context, programParameters),
+ symbolIconSDF(context, programParameters),
+ symbolGlyph(context, programParameters),
+ debug(context, ProgramParameters(programParameters.pixelRatio, false)),
+ collisionBox(context, ProgramParameters(programParameters.pixelRatio, false)) {
+ }
+
+ CircleProgram circle;
+ FillProgram fill;
+ FillPatternProgram fillPattern;
+ FillOutlineProgram fillOutline;
+ FillOutlinePatternProgram fillOutlinePattern;
+ LineProgram line;
+ LineSDFProgram lineSDF;
+ LinePatternProgram linePattern;
+ RasterProgram raster;
+ SymbolIconProgram symbolIcon;
+ SymbolSDFProgram symbolIconSDF;
+ SymbolSDFProgram symbolGlyph;
+
+ DebugProgram debug;
+ CollisionBoxProgram collisionBox;
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/programs/raster_program.cpp b/src/mbgl/programs/raster_program.cpp
new file mode 100644
index 0000000000..ebec4c68cc
--- /dev/null
+++ b/src/mbgl/programs/raster_program.cpp
@@ -0,0 +1,7 @@
+#include <mbgl/programs/raster_program.hpp>
+
+namespace mbgl {
+
+static_assert(sizeof(RasterProgram::Vertex) == 8, "expected RasterVertex size");
+
+} // namespace mbgl
diff --git a/src/mbgl/programs/raster_program.hpp b/src/mbgl/programs/raster_program.hpp
new file mode 100644
index 0000000000..d6179904d2
--- /dev/null
+++ b/src/mbgl/programs/raster_program.hpp
@@ -0,0 +1,68 @@
+#pragma once
+
+#include <mbgl/programs/program.hpp>
+#include <mbgl/programs/attributes.hpp>
+#include <mbgl/programs/uniforms.hpp>
+#include <mbgl/shader/raster.hpp>
+#include <mbgl/util/geometry.hpp>
+
+namespace mbgl {
+
+namespace uniforms {
+MBGL_DEFINE_UNIFORM_SCALAR(gl::TextureUnit, u_image0);
+MBGL_DEFINE_UNIFORM_SCALAR(gl::TextureUnit, u_image1);
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_opacity0);
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_opacity1);
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_buffer_scale);
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_brightness_low);
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_brightness_high);
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_saturation_factor);
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_contrast_factor);
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_scale_parent);
+MBGL_DEFINE_UNIFORM_VECTOR(float, 3, u_spin_weights);
+MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_tl_parent);
+} // namespace uniforms
+
+using RasterAttributes = gl::Attributes<
+ attributes::a_pos,
+ attributes::a_texture_pos>;
+
+class RasterProgram : public Program<
+ shaders::raster,
+ gl::Triangle,
+ RasterAttributes,
+ gl::Uniforms<
+ uniforms::u_matrix,
+ uniforms::u_image0,
+ uniforms::u_image1,
+ uniforms::u_opacity0,
+ uniforms::u_opacity1,
+ uniforms::u_brightness_low,
+ uniforms::u_brightness_high,
+ uniforms::u_saturation_factor,
+ uniforms::u_contrast_factor,
+ uniforms::u_spin_weights,
+ uniforms::u_buffer_scale,
+ uniforms::u_scale_parent,
+ uniforms::u_tl_parent>>
+{
+public:
+ using Program::Program;
+
+ static Vertex vertex(Point<int16_t> p, Point<uint16_t> t) {
+ return Vertex {
+ {
+ p.x,
+ p.y
+ },
+ {
+ t.x,
+ t.y
+ }
+ };
+ }
+};
+
+using RasterVertex = RasterProgram::Vertex;
+
+} // namespace mbgl
diff --git a/src/mbgl/programs/symbol_program.cpp b/src/mbgl/programs/symbol_program.cpp
new file mode 100644
index 0000000000..8c9c34210c
--- /dev/null
+++ b/src/mbgl/programs/symbol_program.cpp
@@ -0,0 +1,145 @@
+#include <mbgl/programs/symbol_program.hpp>
+#include <mbgl/renderer/render_tile.hpp>
+#include <mbgl/map/transform_state.hpp>
+#include <mbgl/style/layers/symbol_layer_impl.hpp>
+
+namespace mbgl {
+
+using namespace style;
+
+static_assert(sizeof(SymbolAttributes::Vertex) == 16, "expected SymbolVertex size");
+
+template <class Values, class...Args>
+Values makeValues(const style::SymbolPropertyValues& values,
+ const Size& texsize,
+ const std::array<float, 2>& pixelsToGLUnits,
+ const RenderTile& tile,
+ const TransformState& state,
+ Args&&... args) {
+ std::array<float, 2> extrudeScale;
+
+ const float scale = values.paintSize / values.sdfScale;
+ if (values.pitchAlignment == AlignmentType::Map) {
+ extrudeScale.fill(tile.id.pixelsToTileUnits(1, state.getZoom()) * scale);
+ } else {
+ extrudeScale = {{
+ pixelsToGLUnits[0] * scale * state.getAltitude(),
+ pixelsToGLUnits[1] * scale * state.getAltitude()
+ }};
+ }
+
+ // adjust min/max zooms for variable font sies
+ float zoomAdjust = std::log(values.paintSize / values.layoutSize) / std::log(2);
+
+ return Values {
+ uniforms::u_matrix::Value{ tile.translatedMatrix(values.translate,
+ values.translateAnchor,
+ state) },
+ uniforms::u_opacity::Value{ values.opacity },
+ uniforms::u_extrude_scale::Value{ extrudeScale },
+ uniforms::u_texsize::Value{ std::array<float, 2> {{ float(texsize.width) / 4, float(texsize.height) / 4 }} },
+ uniforms::u_zoom::Value{ float((state.getZoom() - zoomAdjust) * 10) },
+ uniforms::u_rotate_with_map::Value{ values.rotationAlignment == AlignmentType::Map },
+ uniforms::u_texture::Value{ 0 },
+ uniforms::u_fadetexture::Value{ 1 },
+ std::forward<Args>(args)...
+ };
+}
+
+SymbolIconProgram::UniformValues
+SymbolIconProgram::uniformValues(const style::SymbolPropertyValues& values,
+ const Size& texsize,
+ const std::array<float, 2>& pixelsToGLUnits,
+ const RenderTile& tile,
+ const TransformState& state)
+{
+ return makeValues<SymbolIconProgram::UniformValues>(
+ values,
+ texsize,
+ pixelsToGLUnits,
+ tile,
+ state
+ );
+}
+
+static SymbolSDFProgram::UniformValues makeSDFValues(const style::SymbolPropertyValues& values,
+ const Size& texsize,
+ const std::array<float, 2>& pixelsToGLUnits,
+ const RenderTile& tile,
+ const TransformState& state,
+ float pixelRatio,
+ Color color,
+ float buffer,
+ float gammaAdjust)
+{
+ // The default gamma value has to be adjust for the current pixelratio so that we're not
+ // drawing blurry font on retina screens.
+ const float gammaBase = 0.105 * values.sdfScale / values.paintSize / pixelRatio;
+ const float gammaScale = values.pitchAlignment == AlignmentType::Map
+ ? 1.0 / std::cos(state.getPitch())
+ : 1.0;
+
+ return makeValues<SymbolSDFProgram::UniformValues>(
+ values,
+ texsize,
+ pixelsToGLUnits,
+ tile,
+ state,
+ uniforms::u_color::Value{ color },
+ uniforms::u_buffer::Value{ buffer },
+ uniforms::u_gamma::Value{ (gammaBase + gammaAdjust) * gammaScale },
+ uniforms::u_pitch::Value{ state.getPitch() },
+ uniforms::u_bearing::Value{ -1.0f * state.getAngle() },
+ uniforms::u_aspect_ratio::Value{ (state.getSize().width * 1.0f) / (state.getSize().height * 1.0f) },
+ uniforms::u_pitch_with_map::Value{ values.pitchAlignment == AlignmentType::Map }
+ );
+}
+
+SymbolSDFProgram::UniformValues
+SymbolSDFProgram::haloUniformValues(const style::SymbolPropertyValues& values,
+ const Size& texsize,
+ const std::array<float, 2>& pixelsToGLUnits,
+ const RenderTile& tile,
+ const TransformState& state,
+ float pixelRatio)
+{
+ const float scale = values.paintSize / values.sdfScale;
+ const float sdfPx = 8.0f;
+ const float blurOffset = 1.19f;
+ const float haloOffset = 6.0f;
+
+ return makeSDFValues(
+ values,
+ texsize,
+ pixelsToGLUnits,
+ tile,
+ state,
+ pixelRatio,
+ values.haloColor,
+ (haloOffset - values.haloWidth / scale) / sdfPx,
+ values.haloBlur * blurOffset / scale / sdfPx
+ );
+}
+
+SymbolSDFProgram::UniformValues
+SymbolSDFProgram::foregroundUniformValues(const style::SymbolPropertyValues& values,
+ const Size& texsize,
+ const std::array<float, 2>& pixelsToGLUnits,
+ const RenderTile& tile,
+ const TransformState& state,
+ float pixelRatio)
+{
+ return makeSDFValues(
+ values,
+ texsize,
+ pixelsToGLUnits,
+ tile,
+ state,
+ pixelRatio,
+ values.color,
+ (256.0f - 64.0f) / 256.0f,
+ 0
+ );
+}
+
+} // namespace mbgl
diff --git a/src/mbgl/programs/symbol_program.hpp b/src/mbgl/programs/symbol_program.hpp
new file mode 100644
index 0000000000..be987551c0
--- /dev/null
+++ b/src/mbgl/programs/symbol_program.hpp
@@ -0,0 +1,136 @@
+#pragma once
+
+#include <mbgl/programs/program.hpp>
+#include <mbgl/programs/attributes.hpp>
+#include <mbgl/programs/uniforms.hpp>
+#include <mbgl/shader/symbol_icon.hpp>
+#include <mbgl/shader/symbol_sdf.hpp>
+#include <mbgl/util/geometry.hpp>
+#include <mbgl/util/size.hpp>
+
+#include <cmath>
+#include <array>
+
+namespace mbgl {
+
+namespace style {
+class SymbolPropertyValues;
+} // namespace style
+
+class RenderTile;
+class TransformState;
+
+namespace uniforms {
+MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_texsize);
+MBGL_DEFINE_UNIFORM_SCALAR(bool, u_rotate_with_map);
+MBGL_DEFINE_UNIFORM_SCALAR(bool, u_pitch_with_map);
+MBGL_DEFINE_UNIFORM_SCALAR(gl::TextureUnit, u_texture);
+MBGL_DEFINE_UNIFORM_SCALAR(gl::TextureUnit, u_fadetexture);
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_buffer);
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_gamma);
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_aspect_ratio);
+} // namespace uniforms
+
+struct SymbolAttributes : gl::Attributes<
+ attributes::a_pos,
+ attributes::a_offset,
+ attributes::a_texture_pos,
+ attributes::a_data<4>>
+{
+ static Vertex vertex(Point<float> a,
+ Point<float> o,
+ uint16_t tx,
+ uint16_t ty,
+ float minzoom,
+ float maxzoom,
+ float labelminzoom,
+ uint8_t labelangle) {
+ return Vertex {
+ {
+ static_cast<int16_t>(a.x),
+ static_cast<int16_t>(a.y)
+ },
+ {
+ static_cast<int16_t>(::round(o.x * 64)), // use 1/64 pixels for placement
+ static_cast<int16_t>(::round(o.y * 64))
+ },
+ {
+ static_cast<uint16_t>(tx / 4),
+ static_cast<uint16_t>(ty / 4)
+ },
+ {
+ 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)
+ }
+ };
+ }
+};
+
+using SymbolVertex = SymbolAttributes::Vertex;
+
+class SymbolIconProgram : public Program<
+ shaders::symbol_icon,
+ gl::Triangle,
+ SymbolAttributes,
+ gl::Uniforms<
+ uniforms::u_matrix,
+ uniforms::u_opacity,
+ uniforms::u_extrude_scale,
+ uniforms::u_texsize,
+ uniforms::u_zoom,
+ uniforms::u_rotate_with_map,
+ uniforms::u_texture,
+ uniforms::u_fadetexture>>
+{
+public:
+ using Program::Program;
+
+ static UniformValues uniformValues(const style::SymbolPropertyValues&,
+ const Size& texsize,
+ const std::array<float, 2>& pixelsToGLUnits,
+ const RenderTile&,
+ const TransformState&);
+};
+
+class SymbolSDFProgram : public Program<
+ shaders::symbol_sdf,
+ gl::Triangle,
+ SymbolAttributes,
+ gl::Uniforms<
+ uniforms::u_matrix,
+ uniforms::u_opacity,
+ uniforms::u_extrude_scale,
+ uniforms::u_texsize,
+ uniforms::u_zoom,
+ uniforms::u_rotate_with_map,
+ uniforms::u_texture,
+ uniforms::u_fadetexture,
+ uniforms::u_color,
+ uniforms::u_buffer,
+ uniforms::u_gamma,
+ uniforms::u_pitch,
+ uniforms::u_bearing,
+ uniforms::u_aspect_ratio,
+ uniforms::u_pitch_with_map>>
+{
+public:
+ using Program::Program;
+
+ static UniformValues haloUniformValues(const style::SymbolPropertyValues&,
+ const Size& texsize,
+ const std::array<float, 2>& pixelsToGLUnits,
+ const RenderTile&,
+ const TransformState&,
+ float pixelRatio);
+
+ static UniformValues foregroundUniformValues(const style::SymbolPropertyValues&,
+ const Size& texsize,
+ const std::array<float, 2>& pixelsToGLUnits,
+ const RenderTile&,
+ const TransformState&,
+ float pixelRatio);
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/programs/uniforms.hpp b/src/mbgl/programs/uniforms.hpp
new file mode 100644
index 0000000000..e0c5a0d361
--- /dev/null
+++ b/src/mbgl/programs/uniforms.hpp
@@ -0,0 +1,33 @@
+#pragma once
+
+#include <mbgl/gl/uniform.hpp>
+#include <mbgl/util/color.hpp>
+
+namespace mbgl {
+namespace uniforms {
+
+// Uniforms common to several shaders.
+
+MBGL_DEFINE_UNIFORM_MATRIX(double, 4, u_matrix);
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_opacity);
+MBGL_DEFINE_UNIFORM_SCALAR(Color, u_color);
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_blur);
+
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_zoom);
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_pitch);
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_bearing);
+
+MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_extrude_scale);
+
+MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_pattern_tl_a);
+MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_pattern_br_a);
+MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_pattern_tl_b);
+MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_pattern_br_b);
+MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_pattern_size_a);
+MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_pattern_size_b);
+
+MBGL_DEFINE_UNIFORM_SCALAR(float, u_mix);
+MBGL_DEFINE_UNIFORM_SCALAR(gl::TextureUnit, u_image);
+
+} // namespace uniforms
+} // namespace mbgl
diff --git a/src/mbgl/renderer/bucket.hpp b/src/mbgl/renderer/bucket.hpp
index 2c3c7a6e47..49619c14f7 100644
--- a/src/mbgl/renderer/bucket.hpp
+++ b/src/mbgl/renderer/bucket.hpp
@@ -5,9 +5,6 @@
#include <atomic>
-#define BUFFER_OFFSET_0 ((int8_t*)nullptr)
-#define BUFFER_OFFSET(i) ((BUFFER_OFFSET_0) + (i))
-
namespace mbgl {
class Painter;
@@ -38,8 +35,6 @@ public:
virtual bool hasData() const = 0;
- virtual bool needsClipping() const = 0;
-
bool needsUpload() const {
return !uploaded;
}
diff --git a/src/mbgl/renderer/circle_bucket.cpp b/src/mbgl/renderer/circle_bucket.cpp
index f12139d004..ba2285c4eb 100644
--- a/src/mbgl/renderer/circle_bucket.cpp
+++ b/src/mbgl/renderer/circle_bucket.cpp
@@ -1,8 +1,8 @@
#include <mbgl/renderer/circle_bucket.hpp>
#include <mbgl/renderer/painter.hpp>
-#include <mbgl/gl/gl.hpp>
+#include <mbgl/gl/context.hpp>
-#include <mbgl/shader/circle_shader.hpp>
+#include <mbgl/programs/circle_program.hpp>
#include <mbgl/style/layers/circle_layer.hpp>
#include <mbgl/util/constants.hpp>
@@ -13,10 +13,6 @@ using namespace style;
CircleBucket::CircleBucket(MapMode mode_) : mode(mode_) {
}
-CircleBucket::~CircleBucket() {
- // Do not remove. header file only contains forward definitions to unique pointers.
-}
-
void CircleBucket::upload(gl::Context& context) {
vertexBuffer = context.createVertexBuffer(std::move(vertices));
indexBuffer = context.createIndexBuffer(std::move(triangles));
@@ -31,18 +27,16 @@ void CircleBucket::render(Painter& painter,
}
bool CircleBucket::hasData() const {
- return !groups.empty();
-}
-
-bool CircleBucket::needsClipping() const {
- return true;
+ return !segments.empty();
}
void CircleBucket::addGeometry(const GeometryCollection& geometryCollection) {
+ constexpr const uint16_t vertexLength = 4;
+
for (auto& circle : geometryCollection) {
- for(auto & geometry : circle) {
- auto x = geometry.x;
- auto y = geometry.y;
+ for(auto& point : circle) {
+ auto x = point.x;
+ auto y = point.y;
// Do not include points that are outside the tile boundaries.
// Include all points in Still mode. You need to include points from
@@ -50,6 +44,11 @@ void CircleBucket::addGeometry(const GeometryCollection& geometryCollection) {
if ((mode != MapMode::Still) &&
(x < 0 || x >= util::EXTENT || y < 0 || y >= util::EXTENT)) continue;
+ if (segments.empty() || segments.back().vertexLength + vertexLength > std::numeric_limits<uint16_t>::max()) {
+ // Move to a new segments because the old one can't hold the geometry.
+ segments.emplace_back(vertices.vertexSize(), triangles.indexSize());
+ }
+
// this geometry will be of the Point type, and we'll derive
// two triangles from it.
//
@@ -59,47 +58,23 @@ void CircleBucket::addGeometry(const GeometryCollection& geometryCollection) {
// │ 1 2 │
// └─────────┘
//
- 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 (!groups.size() || groups.back().vertexLength + 4 > 65535) {
- // Move to a new group because the old one can't hold the geometry.
- groups.emplace_back();
- }
+ vertices.emplace_back(CircleProgram::vertex(point, -1, -1)); // 1
+ vertices.emplace_back(CircleProgram::vertex(point, 1, -1)); // 2
+ vertices.emplace_back(CircleProgram::vertex(point, 1, 1)); // 3
+ vertices.emplace_back(CircleProgram::vertex(point, -1, 1)); // 4
- auto& group = groups.back();
- uint16_t index = group.vertexLength;
+ auto& segment = segments.back();
+ assert(segment.vertexLength <= std::numeric_limits<uint16_t>::max());
+ uint16_t index = segment.vertexLength;
// 1, 2, 3
// 1, 4, 3
- 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, PaintMode paintMode) {
- GLbyte* vertexIndex = BUFFER_OFFSET(0);
- GLbyte* elementsIndex = BUFFER_OFFSET(0);
+ triangles.emplace_back(index, index + 1, index + 2);
+ triangles.emplace_back(index, index + 3, index + 2);
- for (auto& group : groups) {
- if (!group.indexLength) continue;
-
- group.getVAO(shader, paintMode).bind(shader, *vertexBuffer, *indexBuffer, vertexIndex, context);
-
- MBGL_CHECK_ERROR(glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(group.indexLength * 3), GL_UNSIGNED_SHORT, elementsIndex));
-
- vertexIndex += group.vertexLength * vertexBuffer->vertexSize;
- elementsIndex += group.indexLength * indexBuffer->primitiveSize;
+ segment.vertexLength += vertexLength;
+ segment.indexLength += 6;
+ }
}
}
diff --git a/src/mbgl/renderer/circle_bucket.hpp b/src/mbgl/renderer/circle_bucket.hpp
index 2f3faccdec..af7041a238 100644
--- a/src/mbgl/renderer/circle_bucket.hpp
+++ b/src/mbgl/renderer/circle_bucket.hpp
@@ -1,39 +1,31 @@
#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/gl/vertex_buffer.hpp>
#include <mbgl/gl/index_buffer.hpp>
-#include <mbgl/shader/circle_vertex.hpp>
+#include <mbgl/gl/segment.hpp>
+#include <mbgl/programs/circle_program.hpp>
namespace mbgl {
-class CircleShader;
-
class CircleBucket : public Bucket {
public:
CircleBucket(const MapMode);
- ~CircleBucket() override;
void upload(gl::Context&) override;
void render(Painter&, PaintParameters&, const style::Layer&, const RenderTile&) override;
bool hasData() const override;
- bool needsClipping() const override;
void addGeometry(const GeometryCollection&);
- void drawCircles(CircleShader&, gl::Context&, PaintMode);
-
-private:
- std::vector<CircleVertex> vertices;
- std::vector<gl::Triangle> triangles;
-
- std::vector<ElementGroup<CircleShader>> groups;
+ gl::VertexVector<CircleVertex> vertices;
+ gl::IndexVector<gl::Triangles> triangles;
+ gl::SegmentVector<CircleAttributes> segments;
optional<gl::VertexBuffer<CircleVertex>> vertexBuffer;
- optional<gl::IndexBuffer<gl::Triangle>> indexBuffer;
+ optional<gl::IndexBuffer<gl::Triangles>> indexBuffer;
const MapMode mode;
};
diff --git a/src/mbgl/renderer/debug_bucket.cpp b/src/mbgl/renderer/debug_bucket.cpp
index c47ae434be..167df4376f 100644
--- a/src/mbgl/renderer/debug_bucket.cpp
+++ b/src/mbgl/renderer/debug_bucket.cpp
@@ -1,25 +1,30 @@
#include <mbgl/renderer/debug_bucket.hpp>
#include <mbgl/renderer/painter.hpp>
-#include <mbgl/shader/fill_shader.hpp>
-#include <mbgl/shader/fill_vertex.hpp>
+#include <mbgl/programs/fill_program.hpp>
#include <mbgl/geometry/debug_font_data.hpp>
#include <mbgl/util/string.hpp>
-#include <mbgl/gl/gl.hpp>
-
#include <cmath>
#include <string>
#include <vector>
namespace mbgl {
-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;
+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_) {
+
+ gl::VertexVector<FillVertex> vertices;
+ gl::IndexVector<gl::Lines> indices;
auto addText = [&] (const std::string& text, double left, double baseline, double scale) {
for (uint8_t c : text) {
@@ -38,9 +43,11 @@ std::vector<FillVertex> buildTextVertices(const OverscaledTileID& id,
int16_t(::round(baseline - glyph.data[j + 1] * scale))
};
+ vertices.emplace_back(FillAttributes::vertex(p));
+
if (prev) {
- textPoints.emplace_back(prev->x, prev->y);
- textPoints.emplace_back(p.x, p.y);
+ indices.emplace_back(vertices.vertexSize() - 2,
+ vertices.vertexSize() - 1);
}
prev = p;
@@ -67,36 +74,10 @@ std::vector<FillVertex> buildTextVertices(const OverscaledTileID& id,
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_))) {
-}
+ segments.emplace_back(0, 0, vertices.vertexSize(), indices.indexSize());
-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(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)));
- }
+ vertexBuffer = context.createVertexBuffer(std::move(vertices));
+ indexBuffer = context.createIndexBuffer(std::move(indices));
}
} // namespace mbgl
diff --git a/src/mbgl/renderer/debug_bucket.hpp b/src/mbgl/renderer/debug_bucket.hpp
index 89087f0010..4676381789 100644
--- a/src/mbgl/renderer/debug_bucket.hpp
+++ b/src/mbgl/renderer/debug_bucket.hpp
@@ -6,13 +6,12 @@
#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>
+#include <mbgl/gl/index_buffer.hpp>
+#include <mbgl/programs/debug_program.hpp>
namespace mbgl {
class OverscaledTileID;
-class FillShader;
namespace gl {
class Context;
@@ -28,18 +27,15 @@ public:
MapDebugOptions,
gl::Context&);
- void drawLines(FillShader&, gl::Context&);
- void drawPoints(FillShader&, gl::Context&);
-
const bool renderable;
const bool complete;
const optional<Timestamp> modified;
const optional<Timestamp> expires;
const MapDebugOptions debugMode;
-private:
- gl::VertexBuffer<FillVertex> vertexBuffer;
- gl::VertexArrayObject array;
+ gl::SegmentVector<DebugAttributes> segments;
+ optional<gl::VertexBuffer<DebugVertex>> vertexBuffer;
+ optional<gl::IndexBuffer<gl::Lines>> indexBuffer;
};
} // namespace mbgl
diff --git a/src/mbgl/renderer/element_group.hpp b/src/mbgl/renderer/element_group.hpp
deleted file mode 100644
index 59b5c3068d..0000000000
--- a/src/mbgl/renderer/element_group.hpp
+++ /dev/null
@@ -1,28 +0,0 @@
-#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 cd4277cabc..b89e982057 100644
--- a/src/mbgl/renderer/fill_bucket.cpp
+++ b/src/mbgl/renderer/fill_bucket.cpp
@@ -1,12 +1,8 @@
#include <mbgl/renderer/fill_bucket.hpp>
#include <mbgl/style/layers/fill_layer.hpp>
#include <mbgl/renderer/painter.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>
+#include <mbgl/programs/fill_program.hpp>
+#include <mbgl/util/logging.hpp>
#include <mapbox/earcut.hpp>
@@ -30,11 +26,6 @@ using namespace style;
struct GeometryTooLongException : std::exception {};
-FillBucket::FillBucket() {
-}
-
-FillBucket::~FillBucket() = default;
-
void FillBucket::addGeometry(const GeometryCollection& geometry) {
for (auto& polygon : classifyRings(geometry)) {
// Optimize polygons with many interior rings for earcut tesselation.
@@ -44,34 +35,36 @@ void FillBucket::addGeometry(const GeometryCollection& geometry) {
for (const auto& ring : polygon) {
totalVertices += ring.size();
- if (totalVertices > 65535)
+ if (totalVertices > std::numeric_limits<uint16_t>::max())
throw GeometryTooLongException();
}
+ std::size_t startVertices = vertices.vertexSize();
+
for (const auto& ring : polygon) {
std::size_t nVertices = ring.size();
if (nVertices == 0)
continue;
- if (lineGroups.empty() || lineGroups.back().vertexLength + nVertices > 65535)
- lineGroups.emplace_back();
+ if (lineSegments.empty() || lineSegments.back().vertexLength + nVertices > std::numeric_limits<uint16_t>::max()) {
+ lineSegments.emplace_back(vertices.vertexSize(), lines.indexSize());
+ }
- auto& lineGroup = lineGroups.back();
- uint16_t lineIndex = lineGroup.vertexLength;
+ auto& lineSegment = lineSegments.back();
+ assert(lineSegment.vertexLength <= std::numeric_limits<uint16_t>::max());
+ uint16_t lineIndex = lineSegment.vertexLength;
- vertices.emplace_back(ring[0].x, ring[0].y);
- lines.emplace_back(static_cast<uint16_t>(lineIndex + nVertices - 1),
- static_cast<uint16_t>(lineIndex));
+ vertices.emplace_back(FillAttributes::vertex(ring[0]));
+ lines.emplace_back(lineIndex + nVertices - 1, lineIndex);
for (uint32_t i = 1; i < nVertices; 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));
+ vertices.emplace_back(FillAttributes::vertex(ring[i]));
+ lines.emplace_back(lineIndex + i - 1, lineIndex + i);
}
- lineGroup.vertexLength += nVertices;
- lineGroup.indexLength += nVertices;
+ lineSegment.vertexLength += nVertices;
+ lineSegment.indexLength += nVertices * 2;
}
std::vector<uint32_t> indices = mapbox::earcut(polygon);
@@ -79,21 +72,22 @@ void FillBucket::addGeometry(const GeometryCollection& geometry) {
std::size_t nIndicies = indices.size();
assert(nIndicies % 3 == 0);
- if (triangleGroups.empty() || triangleGroups.back().vertexLength + totalVertices > 65535) {
- triangleGroups.emplace_back();
+ if (triangleSegments.empty() || triangleSegments.back().vertexLength + totalVertices > std::numeric_limits<uint16_t>::max()) {
+ triangleSegments.emplace_back(startVertices, triangles.indexSize());
}
- auto& triangleGroup = triangleGroups.back();
- uint16_t triangleIndex = triangleGroup.vertexLength;
+ auto& triangleSegment = triangleSegments.back();
+ assert(triangleSegment.vertexLength <= std::numeric_limits<uint16_t>::max());
+ uint16_t triangleIndex = triangleSegment.vertexLength;
for (uint32_t i = 0; i < nIndicies; i += 3) {
- 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]));
+ triangles.emplace_back(triangleIndex + indices[i],
+ triangleIndex + indices[i + 1],
+ triangleIndex + indices[i + 2]);
}
- triangleGroup.vertexLength += totalVertices;
- triangleGroup.indexLength += nIndicies / 3;
+ triangleSegment.vertexLength += totalVertices;
+ triangleSegment.indexLength += nIndicies;
}
}
@@ -114,71 +108,7 @@ void FillBucket::render(Painter& painter,
}
bool FillBucket::hasData() const {
- return !triangleGroups.empty() || !lineGroups.empty();
-}
-
-bool FillBucket::needsClipping() const {
- return true;
-}
-
-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) {
- 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.vertexLength * vertexBuffer->vertexSize;
- elements_index += group.indexLength * triangleIndexBuffer->primitiveSize;
- }
-}
-
-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) {
- 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.vertexLength * vertexBuffer->vertexSize;
- elements_index += group.indexLength * triangleIndexBuffer->primitiveSize;
- }
-}
-
-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) {
- 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.vertexLength * vertexBuffer->vertexSize;
- elements_index += group.indexLength * lineIndexBuffer->primitiveSize;
- }
-}
-
-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) {
- 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.vertexLength * vertexBuffer->vertexSize;
- elements_index += group.indexLength * lineIndexBuffer->primitiveSize;
- }
+ return !triangleSegments.empty() || !lineSegments.empty();
}
} // namespace mbgl
diff --git a/src/mbgl/renderer/fill_bucket.hpp b/src/mbgl/renderer/fill_bucket.hpp
index 34cd886687..edb1521c1d 100644
--- a/src/mbgl/renderer/fill_bucket.hpp
+++ b/src/mbgl/renderer/fill_bucket.hpp
@@ -1,50 +1,33 @@
#pragma once
#include <mbgl/renderer/bucket.hpp>
-#include <mbgl/renderer/element_group.hpp>
#include <mbgl/tile/geometry_tile_data.hpp>
#include <mbgl/gl/vertex_buffer.hpp>
#include <mbgl/gl/index_buffer.hpp>
-#include <mbgl/shader/fill_vertex.hpp>
+#include <mbgl/gl/segment.hpp>
+#include <mbgl/programs/fill_program.hpp>
#include <vector>
-#include <memory>
namespace mbgl {
-class FillShader;
-class FillPatternShader;
-class FillOutlineShader;
-class FillOutlinePatternShader;
-
class FillBucket : public Bucket {
public:
- FillBucket();
- ~FillBucket() override;
-
void upload(gl::Context&) override;
void render(Painter&, PaintParameters&, const style::Layer&, const RenderTile&) override;
bool hasData() const override;
- bool needsClipping() const override;
void addGeometry(const GeometryCollection&);
- 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:
- std::vector<FillVertex> vertices;
- std::vector<gl::Line> lines;
- std::vector<gl::Triangle> triangles;
-
- std::vector<ElementGroup<FillOutlineShader, FillOutlinePatternShader>> lineGroups;
- std::vector<ElementGroup<FillShader, FillPatternShader>> triangleGroups;
+ gl::VertexVector<FillVertex> vertices;
+ gl::IndexVector<gl::Lines> lines;
+ gl::IndexVector<gl::Triangles> triangles;
+ gl::SegmentVector<FillAttributes> lineSegments;
+ gl::SegmentVector<FillAttributes> triangleSegments;
optional<gl::VertexBuffer<FillVertex>> vertexBuffer;
- optional<gl::IndexBuffer<gl::Line>> lineIndexBuffer;
- optional<gl::IndexBuffer<gl::Triangle>> triangleIndexBuffer;
+ optional<gl::IndexBuffer<gl::Lines>> lineIndexBuffer;
+ optional<gl::IndexBuffer<gl::Triangles>> triangleIndexBuffer;
};
} // namespace mbgl
diff --git a/src/mbgl/renderer/frame_history.cpp b/src/mbgl/renderer/frame_history.cpp
index daf24c8c37..1ee53d87b2 100644
--- a/src/mbgl/renderer/frame_history.cpp
+++ b/src/mbgl/renderer/frame_history.cpp
@@ -1,13 +1,14 @@
#include <mbgl/renderer/frame_history.hpp>
#include <mbgl/math/minmax.hpp>
#include <mbgl/gl/context.hpp>
-#include <mbgl/gl/gl.hpp>
+
+#include <cassert>
namespace mbgl {
FrameHistory::FrameHistory() {
changeOpacities.fill(0);
- opacities.fill(0);
+ std::fill(opacities.data.get(), opacities.data.get() + opacities.bytes(), 0);
}
void FrameHistory::record(const TimePoint& now, float zoom, const Duration& duration) {
@@ -18,7 +19,7 @@ void FrameHistory::record(const TimePoint& now, float zoom, const Duration& dura
changeTimes.fill(now);
for (int16_t z = 0; z <= zoomIndex; z++) {
- opacities[z] = 255u;
+ opacities.data[z] = 255u;
}
firstFrame = false;
}
@@ -26,12 +27,12 @@ void FrameHistory::record(const TimePoint& now, float zoom, const Duration& dura
if (zoomIndex < previousZoomIndex) {
for (int16_t z = zoomIndex + 1; z <= previousZoomIndex; z++) {
changeTimes[z] = now;
- changeOpacities[z] = opacities[z];
+ changeOpacities[z] = opacities.data[z];
}
} else {
for (int16_t z = zoomIndex; z > previousZoomIndex; z--) {
changeTimes[z] = now;
- changeOpacities[z] = opacities[z];
+ changeOpacities[z] = opacities.data[z];
}
}
@@ -39,13 +40,13 @@ void FrameHistory::record(const TimePoint& now, float zoom, const Duration& dura
std::chrono::duration<float> timeDiff = now - changeTimes[z];
int32_t opacityChange = (duration == Milliseconds(0) ? 1 : (timeDiff / duration)) * 255;
if (z <= zoomIndex) {
- opacities[z] = util::min(255, changeOpacities[z] + opacityChange);
+ opacities.data[z] = util::min(255, changeOpacities[z] + opacityChange);
} else {
- opacities[z] = util::max(0, changeOpacities[z] - opacityChange);
+ opacities.data[z] = util::max(0, changeOpacities[z] - opacityChange);
}
}
- changed = true;
+ dirty = true;
if (zoomIndex != previousZoomIndex) {
previousZoomIndex = zoomIndex;
@@ -60,58 +61,17 @@ bool FrameHistory::needsAnimation(const Duration& duration) const {
}
void FrameHistory::upload(gl::Context& context, uint32_t unit) {
-
- if (changed) {
- const bool first = !texture;
- bind(context, unit);
-
- if (first) {
- MBGL_CHECK_ERROR(glTexImage2D(
- GL_TEXTURE_2D, // GLenum target
- 0, // GLint level
- GL_ALPHA, // GLint internalformat
- width, // GLsizei width
- height, // GLsizei height
- 0, // GLint border
- GL_ALPHA, // GLenum format
- GL_UNSIGNED_BYTE, // GLenum type
- opacities.data()
- ));
- } else {
- MBGL_CHECK_ERROR(glTexSubImage2D(
- GL_TEXTURE_2D, // GLenum target
- 0, // GLint level
- 0, // GLint xoffset
- 0, // GLint yoffset
- width, // GLsizei width
- height, // GLsizei height
- GL_ALPHA, // GLenum format
- GL_UNSIGNED_BYTE, // GLenum type
- opacities.data()
- ));
- }
-
- changed = false;
-
+ if (!texture) {
+ texture = context.createTexture(opacities, unit);
+ } else if (dirty) {
+ context.updateTexture(*texture, opacities, unit);
}
+ dirty = false;
}
void FrameHistory::bind(gl::Context& context, uint32_t unit) {
- if (!texture) {
- texture = context.createTexture();
- context.activeTexture = unit;
- context.texture[unit] = *texture;
-#if not MBGL_USE_GLES2
- MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
-#endif
- MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
- MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
- MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
- MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
- } else if (context.texture[unit] != *texture) {
- context.activeTexture = unit;
- context.texture[unit] = *texture;
- }
+ upload(context, unit);
+ context.bindTexture(*texture, unit);
}
} // namespace mbgl
diff --git a/src/mbgl/renderer/frame_history.hpp b/src/mbgl/renderer/frame_history.hpp
index 063930af26..fffbd113ed 100644
--- a/src/mbgl/renderer/frame_history.hpp
+++ b/src/mbgl/renderer/frame_history.hpp
@@ -2,9 +2,10 @@
#include <array>
-#include <mbgl/platform/platform.hpp>
-#include <mbgl/gl/object.hpp>
+#include <mbgl/util/platform.hpp>
+#include <mbgl/gl/texture.hpp>
#include <mbgl/util/chrono.hpp>
+#include <mbgl/util/image.hpp>
#include <mbgl/util/optional.hpp>
namespace mbgl {
@@ -23,20 +24,17 @@ public:
void upload(gl::Context&, uint32_t);
private:
- const int width = 256;
- const int height = 1;
-
std::array<TimePoint, 256> changeTimes;
std::array<uint8_t, 256> changeOpacities;
- std::array<uint8_t, 256> opacities;
+ const AlphaImage opacities{ { 256, 1 } };
int16_t previousZoomIndex = 0;
- TimePoint previousTime = TimePoint::min();
- TimePoint time = TimePoint::min();
+ TimePoint previousTime;
+ TimePoint time;
bool firstFrame = true;
- bool changed = true;
+ bool dirty = true;
- mbgl::optional<gl::UniqueTexture> texture;
+ mbgl::optional<gl::Texture> texture;
};
} // namespace mbgl
diff --git a/src/mbgl/renderer/line_bucket.cpp b/src/mbgl/renderer/line_bucket.cpp
index 7a5309bafc..007060bd1b 100644
--- a/src/mbgl/renderer/line_bucket.cpp
+++ b/src/mbgl/renderer/line_bucket.cpp
@@ -1,12 +1,8 @@
#include <mbgl/renderer/line_bucket.hpp>
#include <mbgl/style/layers/line_layer.hpp>
#include <mbgl/renderer/painter.hpp>
-#include <mbgl/shader/line_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>
#include <cassert>
@@ -54,8 +50,8 @@ const float LINE_DISTANCE_SCALE = 1.0 / 2.0;
const float MAX_LINE_DISTANCE = std::pow(2, LINE_DISTANCE_BUFFER_BITS) / LINE_DISTANCE_SCALE;
void LineBucket::addGeometry(const GeometryCoordinates& coordinates) {
- const GLsizei len = [&coordinates] {
- GLsizei l = static_cast<GLsizei>(coordinates.size());
+ const std::size_t len = [&coordinates] {
+ std::size_t l = coordinates.size();
// If the line has duplicate vertices at the end, adjust length to remove them.
while (l > 2 && coordinates[l - 1] == coordinates[l - 2]) {
l--;
@@ -68,7 +64,7 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates) {
return;
}
- const float miterLimit = layout.lineJoin == LineJoinType::Bevel ? 1.05f : float(layout.lineMiterLimit);
+ const float miterLimit = layout.get<LineJoin>() == LineJoinType::Bevel ? 1.05f : float(layout.get<LineMiterLimit>());
const double sharpCornerOffset = SHARP_CORNER_OFFSET * (float(util::EXTENT) / (util::tileSize * overscaling));
@@ -81,8 +77,8 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates) {
return;
}
- const LineCapType beginCap = layout.lineCap;
- const LineCapType endCap = closed ? LineCapType::Butt : LineCapType(layout.lineCap);
+ const LineCapType beginCap = layout.get<LineCap>();
+ const LineCapType endCap = closed ? LineCapType::Butt : LineCapType(layout.get<LineCap>());
double distance = 0;
bool startOfLine = true;
@@ -100,10 +96,10 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates) {
nextNormal = util::perp(util::unit(convertPoint<double>(firstCoordinate - *currentCoordinate)));
}
- const std::size_t startVertex = vertices.size();
+ const std::size_t startVertex = vertices.vertexSize();
std::vector<TriangleElement> triangleStore;
- for (GLsizei i = 0; i < len; ++i) {
+ for (std::size_t i = 0; i < len; ++i) {
if (closed && i == len - 1) {
// if the line is closed, we treat the last vertex like the first
nextCoordinate = coordinates[1];
@@ -175,12 +171,12 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates) {
// The join if a middle vertex, otherwise the cap
const bool middleVertex = prevCoordinate && nextCoordinate;
- LineJoinType currentJoin = layout.lineJoin;
+ LineJoinType currentJoin = layout.get<LineJoin>();
const LineCapType currentCap = nextCoordinate ? beginCap : endCap;
if (middleVertex) {
if (currentJoin == LineJoinType::Round) {
- if (miterLength < layout.lineRoundLimit) {
+ if (miterLength < layout.get<LineRoundLimit>()) {
currentJoin = LineJoinType::Miter;
} else if (miterLength <= 2) {
currentJoin = LineJoinType::FakeRound;
@@ -349,25 +345,23 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates) {
startOfLine = false;
}
- const std::size_t endVertex = vertices.size();
+ const std::size_t endVertex = vertices.vertexSize();
const std::size_t vertexCount = endVertex - startVertex;
- 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();
+ if (segments.empty() || segments.back().vertexLength + vertexCount > std::numeric_limits<uint16_t>::max()) {
+ segments.emplace_back(startVertex, triangles.indexSize());
}
- auto& group = groups.back();
- uint16_t index = group.vertexLength;
+ auto& segment = segments.back();
+ assert(segment.vertexLength <= std::numeric_limits<uint16_t>::max());
+ uint16_t index = segment.vertexLength;
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));
+ triangles.emplace_back(index + triangle.a, index + triangle.b, index + triangle.c);
}
- group.vertexLength += vertexCount;
- group.indexLength += triangleStore.size();
+ segment.vertexLength += vertexCount;
+ segment.indexLength += triangleStore.size() * 3;
}
void LineBucket::addCurrentVertex(const GeometryCoordinate& currentCoordinate,
@@ -378,13 +372,11 @@ void LineBucket::addCurrentVertex(const GeometryCoordinate& currentCoordinate,
bool round,
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);
- vertices.emplace_back(currentCoordinate.x, currentCoordinate.y, extrude.x, extrude.y, tx, 0, endLeft, distance * LINE_DISTANCE_SCALE);
- e3 = vertices.size() - 1 - startVertex;
+ vertices.emplace_back(LineAttributes::vertex(currentCoordinate, extrude, { round, false }, endLeft, distance * LINE_DISTANCE_SCALE));
+ e3 = vertices.vertexSize() - 1 - startVertex;
if (e1 >= 0 && e2 >= 0) {
triangleStore.emplace_back(e1, e2, e3);
}
@@ -394,8 +386,8 @@ void LineBucket::addCurrentVertex(const GeometryCoordinate& currentCoordinate,
extrude = normal * -1.0;
if (endRight)
extrude = extrude - (util::perp(normal) * endRight);
- vertices.emplace_back(currentCoordinate.x, currentCoordinate.y, extrude.x, extrude.y, tx, 1, -endRight, distance * LINE_DISTANCE_SCALE);
- e3 = vertices.size() - 1 - startVertex;
+ vertices.emplace_back(LineAttributes::vertex(currentCoordinate, extrude, { round, true }, -endRight, distance * LINE_DISTANCE_SCALE));
+ e3 = vertices.vertexSize() - 1 - startVertex;
if (e1 >= 0 && e2 >= 0) {
triangleStore.emplace_back(e1, e2, e3);
}
@@ -418,11 +410,9 @@ void LineBucket::addPieSliceVertex(const GeometryCoordinate& currentVertex,
bool lineTurnsLeft,
std::size_t startVertex,
std::vector<TriangleElement>& triangleStore) {
- int8_t ty = lineTurnsLeft;
-
Point<double> flippedExtrude = extrude * (lineTurnsLeft ? -1.0 : 1.0);
- vertices.emplace_back(currentVertex.x, currentVertex.y, flippedExtrude.x, flippedExtrude.y, 0, ty, 0, distance * LINE_DISTANCE_SCALE);
- e3 = vertices.size() - 1 - startVertex;
+ vertices.emplace_back(LineAttributes::vertex(currentVertex, flippedExtrude, { false, lineTurnsLeft }, 0, distance * LINE_DISTANCE_SCALE));
+ e3 = vertices.vertexSize() - 1 - startVertex;
if (e1 >= 0 && e2 >= 0) {
triangleStore.emplace_back(e1, e2, e3);
}
@@ -450,65 +440,7 @@ void LineBucket::render(Painter& painter,
}
bool LineBucket::hasData() const {
- return !groups.empty();
-}
-
-bool LineBucket::needsClipping() const {
- return true;
-}
-
-void LineBucket::drawLines(LineShader& shader,
- gl::Context& context,
- PaintMode paintMode) {
- GLbyte* vertex_index = BUFFER_OFFSET(0);
- GLbyte* elements_index = BUFFER_OFFSET(0);
- for (auto& group : groups) {
- if (!group.indexLength) {
- continue;
- }
- 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.vertexLength * vertexBuffer->vertexSize;
- elements_index += group.indexLength * indexBuffer->primitiveSize;
- }
-}
-
-void LineBucket::drawLineSDF(LineSDFShader& shader,
- gl::Context& context,
- PaintMode paintMode) {
- GLbyte* vertex_index = BUFFER_OFFSET(0);
- GLbyte* elements_index = BUFFER_OFFSET(0);
- for (auto& group : groups) {
- if (!group.indexLength) {
- continue;
- }
- 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.vertexLength * vertexBuffer->vertexSize;
- elements_index += group.indexLength * indexBuffer->primitiveSize;
- }
-}
-
-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 : groups) {
- if (!group.indexLength) {
- continue;
- }
- 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.vertexLength * vertexBuffer->vertexSize;
- elements_index += group.indexLength * indexBuffer->primitiveSize;
- }
+ return !segments.empty();
}
} // namespace mbgl
diff --git a/src/mbgl/renderer/line_bucket.hpp b/src/mbgl/renderer/line_bucket.hpp
index 14af710877..d11d78ff69 100644
--- a/src/mbgl/renderer/line_bucket.hpp
+++ b/src/mbgl/renderer/line_bucket.hpp
@@ -1,23 +1,18 @@
#pragma once
#include <mbgl/renderer/bucket.hpp>
-#include <mbgl/renderer/element_group.hpp>
#include <mbgl/tile/geometry_tile_data.hpp>
#include <mbgl/gl/vertex_buffer.hpp>
#include <mbgl/gl/index_buffer.hpp>
-#include <mbgl/shader/line_vertex.hpp>
+#include <mbgl/gl/segment.hpp>
+#include <mbgl/programs/line_program.hpp>
#include <mbgl/style/layers/line_layer_properties.hpp>
#include <vector>
namespace mbgl {
-class LineShader;
-class LineSDFShader;
-class LinePatternShader;
-
class LineBucket : public Bucket {
-
public:
LineBucket(uint32_t overscaling);
~LineBucket() override;
@@ -25,14 +20,18 @@ public:
void upload(gl::Context&) override;
void render(Painter&, PaintParameters&, const style::Layer&, const RenderTile&) override;
bool hasData() const override;
- bool needsClipping() const override;
void addGeometry(const GeometryCollection&);
void addGeometry(const GeometryCoordinates& line);
- void drawLines(LineShader&, gl::Context&, PaintMode);
- void drawLineSDF(LineSDFShader&, gl::Context&, PaintMode);
- void drawLinePatterns(LinePatternShader&, gl::Context&, PaintMode);
+ style::LineLayoutProperties::Evaluated layout;
+
+ gl::VertexVector<LineVertex> vertices;
+ gl::IndexVector<gl::Triangles> triangles;
+ gl::SegmentVector<LineAttributes> segments;
+
+ optional<gl::VertexBuffer<LineVertex>> vertexBuffer;
+ optional<gl::IndexBuffer<gl::Triangles>> indexBuffer;
private:
struct TriangleElement {
@@ -46,18 +45,6 @@ private:
const Point<double>& extrude, bool lineTurnsLeft, std::size_t startVertex,
std::vector<TriangleElement>& triangleStore);
-public:
- style::LineLayoutProperties layout;
-
-private:
- std::vector<LineVertex> vertices;
- std::vector<gl::Triangle> triangles;
-
- std::vector<ElementGroup<LineShader, LineSDFShader, LinePatternShader>> groups;
-
- optional<gl::VertexBuffer<LineVertex>> vertexBuffer;
- optional<gl::IndexBuffer<gl::Triangle>> indexBuffer;
-
std::ptrdiff_t e1;
std::ptrdiff_t e2;
std::ptrdiff_t e3;
diff --git a/src/mbgl/renderer/paint_parameters.hpp b/src/mbgl/renderer/paint_parameters.hpp
index bd67dc9cfd..213c01cfbd 100644
--- a/src/mbgl/renderer/paint_parameters.hpp
+++ b/src/mbgl/renderer/paint_parameters.hpp
@@ -2,12 +2,12 @@
namespace mbgl {
-class Shaders;
+class Programs;
class View;
class PaintParameters {
public:
- Shaders& shaders;
+ Programs& programs;
View& view;
};
diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp
index fc61d6e0a0..5894912ef3 100644
--- a/src/mbgl/renderer/painter.cpp
+++ b/src/mbgl/renderer/painter.cpp
@@ -7,8 +7,7 @@
#include <mbgl/map/view.hpp>
-#include <mbgl/platform/log.hpp>
-#include <mbgl/gl/gl.hpp>
+#include <mbgl/util/logging.hpp>
#include <mbgl/gl/debugging.hpp>
#include <mbgl/style/style.hpp>
@@ -22,7 +21,8 @@
#include <mbgl/geometry/line_atlas.hpp>
#include <mbgl/text/glyph_atlas.hpp>
-#include <mbgl/shader/shaders.hpp>
+#include <mbgl/programs/program_parameters.hpp>
+#include <mbgl/programs/programs.hpp>
#include <mbgl/algorithm/generate_clip_ids.hpp>
#include <mbgl/algorithm/generate_clip_ids_impl.hpp>
@@ -42,37 +42,63 @@ namespace mbgl {
using namespace style;
-Painter::Painter(gl::Context& context_, const TransformState& state_)
+static gl::VertexVector<FillVertex> tileVertices() {
+ gl::VertexVector<FillVertex> result;
+ result.emplace_back(FillAttributes::vertex({ 0, 0 }));
+ result.emplace_back(FillAttributes::vertex({ util::EXTENT, 0 }));
+ result.emplace_back(FillAttributes::vertex({ 0, util::EXTENT }));
+ result.emplace_back(FillAttributes::vertex({ util::EXTENT, util::EXTENT }));
+ return result;
+}
+
+static gl::IndexVector<gl::Triangles> tileTriangleIndices() {
+ gl::IndexVector<gl::Triangles> result;
+ result.emplace_back(0, 1, 2);
+ result.emplace_back(1, 2, 3);
+ return result;
+}
+
+static gl::IndexVector<gl::LineStrip> tileLineStripIndices() {
+ gl::IndexVector<gl::LineStrip> result;
+ result.emplace_back(0);
+ result.emplace_back(1);
+ result.emplace_back(3);
+ result.emplace_back(2);
+ result.emplace_back(0);
+ return result;
+}
+
+static gl::VertexVector<RasterVertex> rasterVertices() {
+ gl::VertexVector<RasterVertex> result;
+ result.emplace_back(RasterProgram::vertex({ 0, 0 }, { 0, 0 }));
+ result.emplace_back(RasterProgram::vertex({ util::EXTENT, 0 }, { 32767, 0 }));
+ result.emplace_back(RasterProgram::vertex({ 0, util::EXTENT }, { 0, 32767 }));
+ result.emplace_back(RasterProgram::vertex({ util::EXTENT, util::EXTENT }, { 32767, 32767 }));
+ return result;
+}
+
+Painter::Painter(gl::Context& context_, const TransformState& state_, float pixelRatio)
: context(context_),
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 }
- }})) {
+ tileVertexBuffer(context.createVertexBuffer(tileVertices())),
+ rasterVertexBuffer(context.createVertexBuffer(rasterVertices())),
+ tileTriangleIndexBuffer(context.createIndexBuffer(tileTriangleIndices())),
+ tileBorderIndexBuffer(context.createIndexBuffer(tileLineStripIndices())) {
+
+ tileTriangleSegments.emplace_back(0, 0, 4, 6);
+ tileBorderSegments.emplace_back(0, 0, 4, 5);
+ rasterSegments.emplace_back(0, 0, 4, 6);
+
#ifndef NDEBUG
gl::debugging::enable();
#endif
- shaders = std::make_unique<Shaders>(context);
+ ProgramParameters programParameters{ pixelRatio, false };
+ programs = std::make_unique<Programs>(context, programParameters);
#ifndef NDEBUG
- overdrawShaders = std::make_unique<Shaders>(context, gl::Shader::Overdraw);
+
+ ProgramParameters programParametersOverdraw{ pixelRatio, true };
+ overdrawPrograms = std::make_unique<Programs>(context, programParametersOverdraw);
#endif
}
@@ -82,12 +108,6 @@ bool Painter::needsAnimation() const {
return frameHistory.needsAnimation(util::DEFAULT_FADE_DURATION);
}
-void Painter::setClipping(const ClipID& clip) {
- const GLint ref = (GLint)clip.reference.to_ulong();
- const GLuint mask = (GLuint)clip.mask.to_ulong();
- context.stencilFunc = { gl::StencilTestFunction::Equal, ref, mask };
-}
-
void Painter::cleanup() {
context.performCleanup();
}
@@ -100,9 +120,9 @@ void Painter::render(const Style& style, const FrameData& frame_, View& view, Sp
PaintParameters parameters {
#ifndef NDEBUG
- paintMode() == PaintMode::Overdraw ? *overdrawShaders : *shaders,
+ paintMode() == PaintMode::Overdraw ? *overdrawPrograms : *programs,
#else
- *shaders,
+ *programs,
#endif
view
};
@@ -111,15 +131,14 @@ void Painter::render(const Style& style, const FrameData& frame_, View& view, Sp
spriteAtlas = style.spriteAtlas.get();
lineAtlas = style.lineAtlas.get();
- RenderData renderData = style.getRenderData(frame.debugOptions);
+ RenderData renderData = style.getRenderData(frame.debugOptions, state.getAngle());
const std::vector<RenderItem>& order = renderData.order;
const std::unordered_set<Source*>& sources = renderData.sources;
- const Color& background = renderData.backgroundColor;
// Update the default matrices to the current viewport dimensions.
state.getProjMatrix(projMatrix);
- pixelsToGLUnits = {{ 2.0f / state.getWidth(), -2.0f / state.getHeight() }};
+ pixelsToGLUnits = {{ 2.0f / state.getSize().width, -2.0f / state.getSize().height }};
if (state.getViewportMode() == ViewportMode::FlippedY) {
pixelsToGLUnits[1] *= -1;
}
@@ -153,26 +172,11 @@ void Painter::render(const Style& style, const FrameData& frame_, View& view, Sp
{
MBGL_DEBUG_GROUP("clear");
view.bind();
- context.stencilFunc = { gl::StencilTestFunction::Always, 0, ~0u };
- context.stencilTest = true;
- context.stencilMask = 0xFF;
- context.depthTest = false;
- context.depthMask = true;
- context.colorMask = { true, true, true, true };
-
- if (paintMode() == PaintMode::Overdraw) {
- context.blend = true;
- context.blendFunc = { gl::BlendSourceFactor::ConstantColor,
- gl::BlendDestinationFactor::One };
- const float overdraw = 1.0f / 8.0f;
- context.blendColor = { overdraw, overdraw, overdraw, 0.0f };
- context.clearColor = Color::black();
- } else {
- context.clearColor = background;
- }
- context.clearStencil = 0;
- context.clearDepth = 1;
- MBGL_CHECK_ERROR(glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
+ context.clear(paintMode() == PaintMode::Overdraw
+ ? Color::black()
+ : renderData.backgroundColor,
+ 1.0f,
+ 0);
}
// - CLIPPING MASKS ----------------------------------------------------------------------------
@@ -186,7 +190,12 @@ void Painter::render(const Style& style, const FrameData& frame_, View& view, Sp
source->baseImpl->startRender(generator, projMatrix, state);
}
- drawClippingMasks(parameters, generator.getStencils());
+ MBGL_DEBUG_GROUP("clipping masks");
+
+ for (const auto& stencil : generator.getStencils()) {
+ MBGL_DEBUG_GROUP(std::string{ "mask: " } + util::toString(stencil.first));
+ renderClippingMask(stencil.first, stencil.second);
+ }
}
#if not MBGL_USE_GLES2 and not defined(NDEBUG)
@@ -214,7 +223,7 @@ void Painter::render(const Style& style, const FrameData& frame_, View& view, Sp
renderPass(parameters,
RenderPass::Translucent,
order.begin(), order.end(),
- static_cast<GLsizei>(order.size()) - 1, -1);
+ static_cast<uint32_t>(order.size()) - 1, -1);
if (debug::renderTree) { Log::Info(Event::Render, "}"); indent--; }
@@ -275,19 +284,6 @@ void Painter::renderPass(PaintParameters& parameters,
if (!layer.baseImpl->hasRenderPass(pass))
continue;
- if (paintMode() == PaintMode::Overdraw) {
- context.blend = true;
- } else if (pass == RenderPass::Translucent) {
- context.blend = true;
- context.blendFunc = { gl::BlendSourceFactor::One,
- gl::BlendDestinationFactor::OneMinusSrcAlpha };
- } else {
- context.blend = false;
- }
-
- context.colorMask = { true, true, true, true };
- context.stencilMask = 0x0;
-
if (layer.is<BackgroundLayer>()) {
MBGL_DEBUG_GROUP("background");
renderBackground(parameters, *layer.as<BackgroundLayer>());
@@ -296,11 +292,9 @@ void Painter::renderPass(PaintParameters& parameters,
// Reset GL state to a known state so the CustomLayer always has a clean slate.
context.vertexArrayObject = 0;
- context.depthFunc = gl::DepthTestFunction::LessEqual;
- context.depthTest = true;
- context.depthMask = false;
- context.stencilTest = false;
- setDepthSublayer(0);
+ context.setDepthMode(depthModeForSublayer(0, gl::DepthMode::ReadOnly));
+ context.setStencilMode(gl::StencilMode::disabled());
+ context.setColorMode(colorModeForRenderPass());
layer.as<CustomLayer>()->impl->render(state);
@@ -310,9 +304,6 @@ void Painter::renderPass(PaintParameters& parameters,
context.setDirtyState();
} else {
MBGL_DEBUG_GROUP(layer.baseImpl->id + " - " + util::toString(item.tile->id));
- if (item.bucket->needsClipping()) {
- setClipping(item.tile->clip);
- }
item.bucket->render(*this, parameters, layer, *item.tile);
}
}
@@ -322,10 +313,46 @@ void Painter::renderPass(PaintParameters& parameters,
}
}
-void Painter::setDepthSublayer(int n) {
+mat4 Painter::matrixForTile(const UnwrappedTileID& tileID) {
+ mat4 matrix;
+ state.matrixFor(matrix, tileID);
+ matrix::multiply(matrix, projMatrix, matrix);
+ return matrix;
+}
+
+gl::DepthMode Painter::depthModeForSublayer(uint8_t n, gl::DepthMode::Mask mask) const {
float nearDepth = ((1 + currentLayer) * numSublayers + n) * depthEpsilon;
float farDepth = nearDepth + depthRangeSize;
- context.depthRange = { nearDepth, farDepth };
+ return gl::DepthMode { gl::DepthMode::LessEqual, mask, { nearDepth, farDepth } };
+}
+
+gl::StencilMode Painter::stencilModeForClipping(const ClipID& id) const {
+ return gl::StencilMode {
+ gl::StencilMode::Equal { static_cast<uint32_t>(id.mask.to_ulong()) },
+ static_cast<int32_t>(id.reference.to_ulong()),
+ 0,
+ gl::StencilMode::Keep,
+ gl::StencilMode::Keep,
+ gl::StencilMode::Replace
+ };
+}
+
+gl::ColorMode Painter::colorModeForRenderPass() const {
+ if (paintMode() == PaintMode::Overdraw) {
+ const float overdraw = 1.0f / 8.0f;
+ return gl::ColorMode {
+ gl::ColorMode::Add {
+ gl::ColorMode::ConstantColor,
+ gl::ColorMode::One
+ },
+ Color { overdraw, overdraw, overdraw, 0.0f },
+ gl::ColorMode::Mask { true, true, true, true }
+ };
+ } else if (pass == RenderPass::Translucent) {
+ return gl::ColorMode::alphaBlended();
+ } else {
+ return gl::ColorMode::unblended();
+ }
}
} // namespace mbgl
diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp
index f339ed1aed..dec7fa57fd 100644
--- a/src/mbgl/renderer/painter.hpp
+++ b/src/mbgl/renderer/painter.hpp
@@ -8,10 +8,11 @@
#include <mbgl/renderer/render_item.hpp>
#include <mbgl/renderer/bucket.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/programs/debug_program.hpp>
+#include <mbgl/programs/program_parameters.hpp>
+#include <mbgl/programs/fill_program.hpp>
+#include <mbgl/programs/raster_program.hpp>
#include <mbgl/style/style.hpp>
@@ -41,8 +42,7 @@ class CircleBucket;
class SymbolBucket;
class RasterBucket;
-class Shaders;
-class SymbolSDFShader;
+class Programs;
class PaintParameters;
struct ClipID;
@@ -68,7 +68,7 @@ struct FrameData {
class Painter : private util::noncopyable {
public:
- Painter(gl::Context&, const TransformState&);
+ Painter(gl::Context&, const TransformState&, float pixelRatio);
~Painter();
void render(const style::Style&,
@@ -78,20 +78,8 @@ public:
void cleanup();
- // Renders debug information for a tile.
+ void renderClippingMask(const UnwrappedTileID&, const ClipID&);
void renderTileDebug(const RenderTile&);
-
- // Renders the red debug frame around a tile, visualizing its perimeter.
- void renderDebugFrame(const mat4 &matrix);
-
-#ifndef NDEBUG
- // Renders tile clip boundaries, using stencil buffer to calculate fill color.
- void renderClipMasks(PaintParameters&);
- // Renders the depth buffer.
- void renderDepthBuffer(PaintParameters&);
-#endif
-
- void renderDebugText(Tile&, const mat4&);
void renderFill(PaintParameters&, FillBucket&, const style::FillLayer&, const RenderTile&);
void renderLine(PaintParameters&, LineBucket&, const style::LineLayer&, const RenderTile&);
void renderCircle(PaintParameters&, CircleBucket&, const style::CircleLayer&, const RenderTile&);
@@ -99,11 +87,12 @@ public:
void renderRaster(PaintParameters&, RasterBucket&, const style::RasterLayer&, const RenderTile&);
void renderBackground(PaintParameters&, const style::BackgroundLayer&);
- float saturationFactor(float saturation);
- float contrastFactor(float contrast);
- std::array<float, 3> spinWeights(float spin_value);
-
- void drawClippingMasks(PaintParameters&, const std::map<UnwrappedTileID, ClipID>&);
+#ifndef NDEBUG
+ // Renders tile clip boundaries, using stencil buffer to calculate fill color.
+ void renderClipMasks(PaintParameters&);
+ // Renders the depth buffer.
+ void renderDepthBuffer(PaintParameters&);
+#endif
bool needsAnimation() const;
@@ -116,31 +105,10 @@ private:
Iterator it, Iterator end,
uint32_t i, int8_t increment);
- void setClipping(const ClipID&);
-
- void renderSDF(SymbolBucket&,
- const RenderTile&,
- float scaleDivisor,
- std::array<float, 2> texsize,
- SymbolSDFShader& sdfShader,
- void (SymbolBucket::*drawSDF)(SymbolSDFShader&, gl::Context&, PaintMode),
-
- // Layout
- style::AlignmentType rotationAlignment,
- style::AlignmentType pitchAlignment,
- float layoutSize,
-
- // Paint
- float opacity,
- Color color,
- Color haloColor,
- float haloWidth,
- float haloBlur,
- std::array<float, 2> translate,
- style::TranslateAnchorType translateAnchor,
- float paintSize);
-
- void setDepthSublayer(int n);
+ mat4 matrixForTile(const UnwrappedTileID&);
+ gl::DepthMode depthModeForSublayer(uint8_t n, gl::DepthMode::Mask) const;
+ gl::StencilMode stencilModeForClipping(const ClipID&) const;
+ gl::ColorMode colorModeForRenderPass() const;
#ifndef NDEBUG
PaintMode paintMode() const {
@@ -185,16 +153,20 @@ private:
FrameHistory frameHistory;
- std::unique_ptr<Shaders> shaders;
+ std::unique_ptr<Programs> programs;
#ifndef NDEBUG
- std::unique_ptr<Shaders> overdrawShaders;
+ std::unique_ptr<Programs> overdrawPrograms;
#endif
- gl::VertexBuffer<FillVertex> tileTriangleVertexBuffer;
- gl::VertexBuffer<FillVertex> tileLineStripVertexBuffer;
+ gl::VertexBuffer<FillVertex> tileVertexBuffer;
gl::VertexBuffer<RasterVertex> rasterVertexBuffer;
- gl::VertexArrayObject tileBorderArray;
+ gl::IndexBuffer<gl::Triangles> tileTriangleIndexBuffer;
+ gl::IndexBuffer<gl::LineStrip> tileBorderIndexBuffer;
+
+ gl::SegmentVector<FillAttributes> tileTriangleSegments;
+ gl::SegmentVector<DebugAttributes> tileBorderSegments;
+ gl::SegmentVector<RasterAttributes> rasterSegments;
};
} // namespace mbgl
diff --git a/src/mbgl/renderer/painter_background.cpp b/src/mbgl/renderer/painter_background.cpp
index 61ec76d1d8..4a3e41701d 100644
--- a/src/mbgl/renderer/painter_background.cpp
+++ b/src/mbgl/renderer/painter_background.cpp
@@ -1,12 +1,10 @@
#include <mbgl/renderer/painter.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
-#include <mbgl/gl/gl.hpp>
-
#include <mbgl/style/layers/background_layer.hpp>
#include <mbgl/style/layers/background_layer_impl.hpp>
-#include <mbgl/shader/shaders.hpp>
+#include <mbgl/programs/programs.hpp>
+#include <mbgl/programs/fill_program.hpp>
#include <mbgl/sprite/sprite_atlas.hpp>
-#include <mbgl/util/mat4.hpp>
#include <mbgl/util/tile_cover.hpp>
namespace mbgl {
@@ -16,75 +14,61 @@ using namespace style;
void Painter::renderBackground(PaintParameters& parameters, const BackgroundLayer& layer) {
// Note that for bottommost layers without a pattern, the background color is drawn with
// glClear rather than this method.
- const BackgroundPaintProperties& properties = layer.impl->paint;
-
- bool isPatterned = !properties.backgroundPattern.value.to.empty();// && false;
- optional<SpriteAtlasPosition> imagePosA;
- optional<SpriteAtlasPosition> imagePosB;
-
- auto& patternShader = parameters.shaders.fillPattern;
- auto& plainShader = parameters.shaders.fill;
- auto& arrayBackgroundPattern = parameters.shaders.backgroundPatternArray;
- auto& arrayBackground = parameters.shaders.backgroundArray;
+ const BackgroundPaintProperties::Evaluated& properties = layer.impl->paint.evaluated;
- if (isPatterned) {
- imagePosA = spriteAtlas->getPosition(properties.backgroundPattern.value.from,
- SpritePatternMode::Repeating);
- imagePosB = spriteAtlas->getPosition(properties.backgroundPattern.value.to,
- SpritePatternMode::Repeating);
+ if (!properties.get<BackgroundPattern>().to.empty()) {
+ optional<SpriteAtlasPosition> imagePosA = spriteAtlas->getPosition(
+ properties.get<BackgroundPattern>().from, SpritePatternMode::Repeating);
+ optional<SpriteAtlasPosition> imagePosB = spriteAtlas->getPosition(
+ properties.get<BackgroundPattern>().to, SpritePatternMode::Repeating);
if (!imagePosA || !imagePosB)
return;
- context.program = patternShader.getID();
- patternShader.u_matrix = identityMatrix;
- patternShader.u_pattern_tl_a = imagePosA->tl;
- patternShader.u_pattern_br_a = imagePosA->br;
- patternShader.u_pattern_tl_b = imagePosB->tl;
- patternShader.u_pattern_br_b = imagePosB->br;
- patternShader.u_mix = properties.backgroundPattern.value.t;
- patternShader.u_opacity = properties.backgroundOpacity;
-
spriteAtlas->bind(true, context, 0);
- arrayBackgroundPattern.bind(patternShader, tileTriangleVertexBuffer, BUFFER_OFFSET(0), context);
+ for (const auto& tileID : util::tileCover(state, state.getIntegerZoom())) {
+ parameters.programs.fillPattern.draw(
+ context,
+ gl::Triangles(),
+ depthModeForSublayer(0, gl::DepthMode::ReadOnly),
+ gl::StencilMode::disabled(),
+ colorModeForRenderPass(),
+ FillPatternUniforms::values(
+ matrixForTile(tileID),
+ properties.get<BackgroundOpacity>(),
+ context.viewport.getCurrentValue().size,
+ *imagePosA,
+ *imagePosB,
+ properties.get<BackgroundPattern>(),
+ tileID,
+ state
+ ),
+ tileVertexBuffer,
+ tileTriangleIndexBuffer,
+ tileTriangleSegments
+ );
+ }
} else {
- context.program = plainShader.getID();
- plainShader.u_color = properties.backgroundColor;
- plainShader.u_opacity = properties.backgroundOpacity;
-
- arrayBackground.bind(plainShader, tileTriangleVertexBuffer, BUFFER_OFFSET(0), context);
- }
-
- context.stencilTest = false;
- context.depthFunc = gl::DepthTestFunction::LessEqual;
- context.depthTest = true;
- context.depthMask = false;
- setDepthSublayer(0);
-
- for (const auto& tileID : util::tileCover(state, state.getIntegerZoom())) {
- mat4 vertexMatrix;
- state.matrixFor(vertexMatrix, tileID);
- matrix::multiply(vertexMatrix, projMatrix, vertexMatrix);
-
- if (isPatterned) {
- patternShader.u_matrix = vertexMatrix;
- patternShader.u_pattern_size_a = imagePosA->size;
- patternShader.u_pattern_size_b = imagePosB->size;
- patternShader.u_scale_a = properties.backgroundPattern.value.fromScale;
- patternShader.u_scale_b = properties.backgroundPattern.value.toScale;
- patternShader.u_tile_units_to_pixels = 1.0f / tileID.pixelsToTileUnits(1.0f, state.getIntegerZoom());
-
- GLint tileSizeAtNearestZoom = util::tileSize * state.zoomScale(state.getIntegerZoom() - tileID.canonical.z);
- GLint pixelX = tileSizeAtNearestZoom * (tileID.canonical.x + tileID.wrap * state.zoomScale(tileID.canonical.z));
- GLint pixelY = tileSizeAtNearestZoom * tileID.canonical.y;
- patternShader.u_pixel_coord_upper = {{ float(pixelX >> 16), float(pixelY >> 16) }};
- patternShader.u_pixel_coord_lower = {{ float(pixelX & 0xFFFF), float(pixelY & 0xFFFF) }};
- } else {
- plainShader.u_matrix = vertexMatrix;
+ for (const auto& tileID : util::tileCover(state, state.getIntegerZoom())) {
+ parameters.programs.fill.draw(
+ context,
+ gl::Triangles(),
+ depthModeForSublayer(0, gl::DepthMode::ReadOnly),
+ gl::StencilMode::disabled(),
+ colorModeForRenderPass(),
+ FillProgram::UniformValues {
+ uniforms::u_matrix::Value{ matrixForTile(tileID) },
+ uniforms::u_opacity::Value{ properties.get<BackgroundOpacity>() },
+ uniforms::u_color::Value{ properties.get<BackgroundColor>() },
+ uniforms::u_outline_color::Value{ properties.get<BackgroundColor>() },
+ uniforms::u_world::Value{ context.viewport.getCurrentValue().size },
+ },
+ tileVertexBuffer,
+ tileTriangleIndexBuffer,
+ tileTriangleSegments
+ );
}
-
- 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 462ed59ebf..9385b7b1a3 100644
--- a/src/mbgl/renderer/painter_circle.cpp
+++ b/src/mbgl/renderer/painter_circle.cpp
@@ -2,11 +2,11 @@
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/circle_bucket.hpp>
#include <mbgl/renderer/render_tile.hpp>
-
#include <mbgl/style/layers/circle_layer.hpp>
#include <mbgl/style/layers/circle_layer_impl.hpp>
-
-#include <mbgl/shader/shaders.hpp>
+#include <mbgl/programs/programs.hpp>
+#include <mbgl/programs/circle_program.hpp>
+#include <mbgl/gl/context.hpp>
namespace mbgl {
@@ -16,42 +16,46 @@ void Painter::renderCircle(PaintParameters& parameters,
CircleBucket& bucket,
const CircleLayer& layer,
const RenderTile& tile) {
- // Abort early.
- if (pass == RenderPass::Opaque) return;
-
- context.stencilTest = frame.mapMode == MapMode::Still;
- context.depthFunc = gl::DepthTestFunction::LessEqual;
- context.depthTest = true;
- context.depthMask = false;
- setDepthSublayer(0);
-
- const CirclePaintProperties& properties = layer.impl->paint;
- auto& circleShader = parameters.shaders.circle;
-
- context.program = circleShader.getID();
-
- circleShader.u_matrix = tile.translatedMatrix(properties.circleTranslate,
- properties.circleTranslateAnchor,
- state);
-
- if (properties.circlePitchScale == CirclePitchScaleType::Map) {
- circleShader.u_extrude_scale = {{
- pixelsToGLUnits[0] * state.getAltitude(),
- pixelsToGLUnits[1] * state.getAltitude()
- }};
- circleShader.u_scale_with_map = true;
- } else {
- circleShader.u_extrude_scale = pixelsToGLUnits;
- circleShader.u_scale_with_map = false;
+ if (pass == RenderPass::Opaque) {
+ return;
}
- circleShader.u_devicepixelratio = frame.pixelRatio;
- circleShader.u_color = properties.circleColor;
- circleShader.u_radius = properties.circleRadius;
- circleShader.u_blur = properties.circleBlur;
- circleShader.u_opacity = properties.circleOpacity;
-
- bucket.drawCircles(circleShader, context, paintMode());
+ const CirclePaintProperties::Evaluated& properties = layer.impl->paint.evaluated;
+ const bool scaleWithMap = properties.get<CirclePitchScale>() == CirclePitchScaleType::Map;
+
+ parameters.programs.circle.draw(
+ context,
+ gl::Triangles(),
+ depthModeForSublayer(0, gl::DepthMode::ReadOnly),
+ frame.mapMode == MapMode::Still
+ ? stencilModeForClipping(tile.clip)
+ : gl::StencilMode::disabled(),
+ colorModeForRenderPass(),
+ CircleProgram::UniformValues {
+ uniforms::u_matrix::Value{
+ tile.translatedMatrix(properties.get<CircleTranslate>(),
+ properties.get<CircleTranslateAnchor>(),
+ state)
+ },
+ uniforms::u_opacity::Value{ properties.get<CircleOpacity>() },
+ uniforms::u_color::Value{ properties.get<CircleColor>() },
+ uniforms::u_radius::Value{ properties.get<CircleRadius>() },
+ uniforms::u_blur::Value{ properties.get<CircleBlur>() },
+ uniforms::u_stroke_color::Value{ properties.get<CircleStrokeColor>() },
+ uniforms::u_stroke_width::Value{ properties.get<CircleStrokeWidth>() },
+ uniforms::u_stroke_opacity::Value{ properties.get<CircleStrokeOpacity>() },
+ uniforms::u_scale_with_map::Value{ scaleWithMap },
+ uniforms::u_extrude_scale::Value{ scaleWithMap
+ ? std::array<float, 2> {{
+ pixelsToGLUnits[0] * state.getAltitude(),
+ pixelsToGLUnits[1] * state.getAltitude()
+ }}
+ : pixelsToGLUnits }
+ },
+ *bucket.vertexBuffer,
+ *bucket.indexBuffer,
+ bucket.segments
+ );
}
} // namespace mbgl
diff --git a/src/mbgl/renderer/painter_clipping.cpp b/src/mbgl/renderer/painter_clipping.cpp
index 68f580c280..a2529561fe 100644
--- a/src/mbgl/renderer/painter_clipping.cpp
+++ b/src/mbgl/renderer/painter_clipping.cpp
@@ -1,49 +1,35 @@
#include <mbgl/renderer/painter.hpp>
-#include <mbgl/renderer/paint_parameters.hpp>
-#include <mbgl/gl/gl.hpp>
-
-#include <mbgl/style/source.hpp>
-#include <mbgl/shader/shaders.hpp>
+#include <mbgl/programs/programs.hpp>
+#include <mbgl/programs/fill_program.hpp>
#include <mbgl/util/clip_id.hpp>
-#include <mbgl/util/string.hpp>
-#include <mbgl/gl/debugging.hpp>
namespace mbgl {
-
-void Painter::drawClippingMasks(PaintParameters& parameters, const std::map<UnwrappedTileID, ClipID>& stencils) {
- MBGL_DEBUG_GROUP("clipping masks");
-
- auto& plainShader = parameters.shaders.fill;
- auto& arrayCoveringPlain = parameters.shaders.coveringPlainArray;
-
- mat4 matrix;
- const GLuint mask = 0b11111111;
-
- context.program = plainShader.getID();
- context.stencilOp = { gl::StencilTestOperation::Keep, gl::StencilTestOperation::Keep,
- gl::StencilTestOperation::Replace };
- context.stencilTest = true;
- context.depthTest = false;
- context.depthMask = false;
- context.colorMask = { false, false, false, false };
- context.stencilMask = mask;
-
- arrayCoveringPlain.bind(plainShader, tileTriangleVertexBuffer, BUFFER_OFFSET_0, context);
-
- for (const auto& stencil : stencils) {
- const auto& id = stencil.first;
- const auto& clip = stencil.second;
-
- MBGL_DEBUG_GROUP(std::string{ "mask: " } + util::toString(id));
- state.matrixFor(matrix, id);
- matrix::multiply(matrix, projMatrix, matrix);
- plainShader.u_matrix = matrix;
-
- const GLint ref = (GLint)(clip.reference.to_ulong());
- context.stencilFunc = { gl::StencilTestFunction::Always, ref, mask };
- MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(tileTriangleVertexBuffer.vertexCount)));
- }
+void Painter::renderClippingMask(const UnwrappedTileID& tileID, const ClipID& clip) {
+ programs->fill.draw(
+ context,
+ gl::Triangles(),
+ gl::DepthMode::disabled(),
+ gl::StencilMode {
+ gl::StencilMode::Always(),
+ static_cast<int32_t>(clip.reference.to_ulong()),
+ 0b11111111,
+ gl::StencilMode::Keep,
+ gl::StencilMode::Keep,
+ gl::StencilMode::Replace
+ },
+ gl::ColorMode::disabled(),
+ FillProgram::UniformValues {
+ uniforms::u_matrix::Value{ matrixForTile(tileID) },
+ uniforms::u_opacity::Value{ 0.0f },
+ uniforms::u_color::Value{ Color {} },
+ uniforms::u_outline_color::Value{ Color {} },
+ uniforms::u_world::Value{ context.viewport.getCurrentValue().size },
+ },
+ tileVertexBuffer,
+ tileTriangleIndexBuffer,
+ tileTriangleSegments
+ );
}
} // namespace mbgl
diff --git a/src/mbgl/renderer/painter_debug.cpp b/src/mbgl/renderer/painter_debug.cpp
index e57bb2205e..2b838dec0e 100644
--- a/src/mbgl/renderer/painter_debug.cpp
+++ b/src/mbgl/renderer/painter_debug.cpp
@@ -4,161 +4,121 @@
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/map/view.hpp>
#include <mbgl/tile/tile.hpp>
-#include <mbgl/shader/shaders.hpp>
+#include <mbgl/programs/programs.hpp>
+#include <mbgl/programs/fill_program.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/gl/debugging.hpp>
-#include <mbgl/gl/gl.hpp>
#include <mbgl/util/color.hpp>
namespace mbgl {
-void Painter::renderTileDebug(const RenderTile& tile) {
- MBGL_DEBUG_GROUP(std::string { "debug " } + util::toString(tile.id));
- if (frame.debugOptions != MapDebugOptions::NoDebug) {
- setClipping(tile.clip);
- if (frame.debugOptions & (MapDebugOptions::Timestamps | MapDebugOptions::ParseStatus)) {
- renderDebugText(tile.tile, tile.matrix);
+void Painter::renderTileDebug(const RenderTile& renderTile) {
+ if (frame.debugOptions == MapDebugOptions::NoDebug)
+ return;
+
+ MBGL_DEBUG_GROUP(std::string { "debug " } + util::toString(renderTile.id));
+
+ auto draw = [&] (Color color, const auto& vertexBuffer, const auto& indexBuffer, const auto& segments, auto drawMode) {
+ programs->debug.draw(
+ context,
+ drawMode,
+ gl::DepthMode::disabled(),
+ stencilModeForClipping(renderTile.clip),
+ gl::ColorMode::unblended(),
+ DebugProgram::UniformValues {
+ uniforms::u_matrix::Value{ renderTile.matrix },
+ uniforms::u_color::Value{ color }
+ },
+ vertexBuffer,
+ indexBuffer,
+ segments
+ );
+ };
+
+ if (frame.debugOptions & (MapDebugOptions::Timestamps | MapDebugOptions::ParseStatus)) {
+ Tile& tile = renderTile.tile;
+ if (!tile.debugBucket || tile.debugBucket->renderable != tile.isRenderable() ||
+ tile.debugBucket->complete != tile.isComplete() ||
+ !(tile.debugBucket->modified == tile.modified) ||
+ !(tile.debugBucket->expires == tile.expires) ||
+ tile.debugBucket->debugMode != frame.debugOptions) {
+ tile.debugBucket = std::make_unique<DebugBucket>(
+ tile.id, tile.isRenderable(), tile.isComplete(), tile.modified,
+ tile.expires, frame.debugOptions, context);
}
- if (frame.debugOptions & MapDebugOptions::TileBorders) {
- renderDebugFrame(tile.matrix);
- }
- }
-}
-void Painter::renderDebugText(Tile& tile, const mat4 &matrix) {
- MBGL_DEBUG_GROUP("debug text");
-
- context.depthTest = false;
-
- if (!tile.debugBucket || tile.debugBucket->renderable != tile.isRenderable() ||
- tile.debugBucket->complete != tile.isComplete() ||
- !(tile.debugBucket->modified == tile.modified) ||
- !(tile.debugBucket->expires == tile.expires) ||
- tile.debugBucket->debugMode != frame.debugOptions) {
- tile.debugBucket = std::make_unique<DebugBucket>(
- tile.id, tile.isRenderable(), tile.isComplete(), tile.modified,
- tile.expires, frame.debugOptions, context);
+ draw(Color::white(),
+ *tile.debugBucket->vertexBuffer,
+ *tile.debugBucket->indexBuffer,
+ tile.debugBucket->segments,
+ gl::Lines { 4.0f * frame.pixelRatio });
+
+ draw(Color::black(),
+ *tile.debugBucket->vertexBuffer,
+ *tile.debugBucket->indexBuffer,
+ tile.debugBucket->segments,
+ gl::Lines { 2.0f * frame.pixelRatio });
}
- auto& plainShader = shaders->fill;
- context.program = plainShader.getID();
- plainShader.u_matrix = matrix;
- plainShader.u_opacity = 1.0f;
-
- // Draw white outline
- plainShader.u_color = Color::white();
- context.lineWidth = 4.0f * frame.pixelRatio;
- tile.debugBucket->drawLines(plainShader, context);
-
-#if not MBGL_USE_GLES2
- // Draw line "end caps"
- MBGL_CHECK_ERROR(glPointSize(2));
- tile.debugBucket->drawPoints(plainShader, context);
-#endif // MBGL_USE_GLES2
-
- // Draw black text.
- plainShader.u_color = Color::black();
- context.lineWidth = 2.0f * frame.pixelRatio;
- tile.debugBucket->drawLines(plainShader, context);
-
- context.depthFunc = gl::DepthTestFunction::LessEqual;
- context.depthTest = true;
-}
-
-void Painter::renderDebugFrame(const mat4 &matrix) {
- MBGL_DEBUG_GROUP("debug frame");
-
- // Disable depth test and don't count this towards the depth buffer,
- // but *don't* disable stencil test, as we want to clip the red tile border
- // to the tile viewport.
- context.depthTest = false;
- context.stencilOp = { gl::StencilTestOperation::Keep, gl::StencilTestOperation::Keep,
- gl::StencilTestOperation::Replace };
- context.stencilTest = true;
-
- auto& plainShader = shaders->fill;
- context.program = plainShader.getID();
- plainShader.u_matrix = matrix;
- plainShader.u_opacity = 1.0f;
-
- // draw tile outline
- 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, static_cast<GLsizei>(tileLineStripVertexBuffer.vertexCount)));
+ if (frame.debugOptions & MapDebugOptions::TileBorders) {
+ draw(Color::red(),
+ tileVertexBuffer,
+ tileBorderIndexBuffer,
+ tileBorderSegments,
+ gl::LineStrip { 4.0f * frame.pixelRatio });
+ }
}
#ifndef NDEBUG
void Painter::renderClipMasks(PaintParameters&) {
- context.stencilTest = false;
- context.depthTest = false;
+ context.setStencilMode(gl::StencilMode::disabled());
+ context.setDepthMode(gl::DepthMode::disabled());
+ context.setColorMode(gl::ColorMode::unblended());
context.program = 0;
- context.colorMask = { true, true, true, true };
#if not MBGL_USE_GLES2
- context.pixelZoom = { 1, 1 };
- context.rasterPos = { -1, -1, 0, 0 };
+ // Reset the value in case someone else changed it, or it's dirty.
+ context.pixelTransferStencil = gl::value::PixelTransferStencil::Default;
// Read the stencil buffer
const auto viewport = context.viewport.getCurrentValue();
- auto pixels = std::make_unique<uint8_t[]>(viewport.width * viewport.height);
- MBGL_CHECK_ERROR(glReadPixels(
- viewport.x, // GLint x
- viewport.y, // GLint y
- viewport.width, // GLsizei width
- viewport.height, // GLsizei height
- GL_STENCIL_INDEX, // GLenum format
- GL_UNSIGNED_BYTE, // GLenum type
- pixels.get() // GLvoid * data
- ));
+ auto image =
+ context.readFramebuffer<AlphaImage, gl::TextureFormat::Stencil>(viewport.size, false);
// Scale the Stencil buffer to cover the entire color space.
- auto it = pixels.get();
- auto end = it + viewport.width * viewport.height;
+ auto it = image.data.get();
+ auto end = it + viewport.size.width * viewport.size.height;
const auto factor = 255.0f / *std::max_element(it, end);
for (; it != end; ++it) {
*it *= factor;
}
- MBGL_CHECK_ERROR(glWindowPos2i(viewport.x, viewport.y));
- MBGL_CHECK_ERROR(glDrawPixels(viewport.width, viewport.height, GL_LUMINANCE, GL_UNSIGNED_BYTE,
- pixels.get()));
+ context.pixelZoom = { 1, 1 };
+ context.rasterPos = { -1, -1, 0, 1 };
+ context.drawPixels(image);
#endif // MBGL_USE_GLES2
}
-#endif // NDEBUG
-#ifndef NDEBUG
void Painter::renderDepthBuffer(PaintParameters&) {
- context.stencilTest = false;
- context.depthTest = false;
+ context.setStencilMode(gl::StencilMode::disabled());
+ context.setDepthMode(gl::DepthMode::disabled());
+ context.setColorMode(gl::ColorMode::unblended());
context.program = 0;
- context.colorMask = { true, true, true, true };
#if not MBGL_USE_GLES2
- context.pixelZoom = { 1, 1 };
- context.rasterPos = { -1, -1, 0, 0 };
+ // Scales the values in the depth buffer so that they cover the entire grayscale range. This
+ // makes it easier to spot tiny differences.
+ const float base = 1.0f / (1.0f - depthRangeSize);
+ context.pixelTransferDepth = { base, 1.0f - base };
// Read the stencil buffer
- const auto viewport = context.viewport.getCurrentValue();
- auto pixels = std::make_unique<uint8_t[]>(viewport.width * viewport.height);
-
- const double base = 1.0 / (1.0 - depthRangeSize);
- glPixelTransferf(GL_DEPTH_SCALE, base);
- glPixelTransferf(GL_DEPTH_BIAS, 1.0 - base);
-
- MBGL_CHECK_ERROR(glReadPixels(
- viewport.x, // GLint x
- viewport.y, // GLint y
- viewport.width, // GLsizei width
- viewport.height, // GLsizei height
- GL_DEPTH_COMPONENT, // GLenum format
- GL_UNSIGNED_BYTE, // GLenum type
- pixels.get() // GLvoid * data
- ));
-
- MBGL_CHECK_ERROR(glWindowPos2i(viewport.x, viewport.y));
- MBGL_CHECK_ERROR(glDrawPixels(viewport.width, viewport.height, GL_LUMINANCE, GL_UNSIGNED_BYTE,
- pixels.get()));
+ auto viewport = context.viewport.getCurrentValue();
+ auto image =
+ context.readFramebuffer<AlphaImage, gl::TextureFormat::Depth>(viewport.size, false);
+
+ context.pixelZoom = { 1, 1 };
+ context.rasterPos = { -1, -1, 0, 1 };
+ context.drawPixels(image);
#endif // MBGL_USE_GLES2
}
#endif // NDEBUG
diff --git a/src/mbgl/renderer/painter_fill.cpp b/src/mbgl/renderer/painter_fill.cpp
index b6606ca40b..356ccfc0b2 100644
--- a/src/mbgl/renderer/painter_fill.cpp
+++ b/src/mbgl/renderer/painter_fill.cpp
@@ -1,14 +1,12 @@
#include <mbgl/renderer/painter.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
-#include <mbgl/gl/gl.hpp>
-#include <mbgl/map/view.hpp>
-
#include <mbgl/renderer/fill_bucket.hpp>
#include <mbgl/renderer/render_tile.hpp>
#include <mbgl/style/layers/fill_layer.hpp>
#include <mbgl/style/layers/fill_layer_impl.hpp>
#include <mbgl/sprite/sprite_atlas.hpp>
-#include <mbgl/shader/shaders.hpp>
+#include <mbgl/programs/programs.hpp>
+#include <mbgl/programs/fill_program.hpp>
#include <mbgl/util/convert.hpp>
namespace mbgl {
@@ -19,160 +17,131 @@ void Painter::renderFill(PaintParameters& parameters,
FillBucket& bucket,
const FillLayer& layer,
const RenderTile& tile) {
- const FillPaintProperties& properties = layer.impl->paint;
- mat4 vertexMatrix = tile.translatedMatrix(properties.fillTranslate,
- properties.fillTranslateAnchor,
- state);
-
- Color fillColor = properties.fillColor;
- float opacity = properties.fillOpacity;
-
- const bool isOutlineColorDefined = !properties.fillOutlineColor.isUndefined();
- Color strokeColor = isOutlineColorDefined? properties.fillOutlineColor : fillColor;
-
- const auto viewport = context.viewport.getCurrentValue();
- const std::array<GLfloat, 2> worldSize{ { static_cast<GLfloat>(viewport.width),
- static_cast<GLfloat>(viewport.height) } };
-
- bool pattern = !properties.fillPattern.value.from.empty();
- bool outline = properties.fillAntialias && !pattern && isOutlineColorDefined;
- bool fringeline = properties.fillAntialias && !pattern && !isOutlineColorDefined;
-
- context.stencilOp = { gl::StencilTestOperation::Keep, gl::StencilTestOperation::Keep,
- gl::StencilTestOperation::Replace };
- context.stencilTest = true;
- context.depthFunc = gl::DepthTestFunction::LessEqual;
- context.depthTest = true;
- context.depthMask = true;
- context.lineWidth = 2.0f; // This is always fixed and does not depend on the pixelRatio!
-
- auto& outlineShader = parameters.shaders.fillOutline;
- auto& patternShader = parameters.shaders.fillPattern;
- auto& outlinePatternShader = parameters.shaders.fillOutlinePattern;
- auto& plainShader = parameters.shaders.fill;
+ const FillPaintProperties::Evaluated& properties = layer.impl->paint.evaluated;
- // Because we're drawing top-to-bottom, and we update the stencil mask
- // befrom, we have to draw the outline first (!)
- if (outline && pass == RenderPass::Translucent) {
- context.program = outlineShader.getID();
- outlineShader.u_matrix = vertexMatrix;
-
- outlineShader.u_outline_color = strokeColor;
- outlineShader.u_opacity = opacity;
-
- // Draw the entire line
- outlineShader.u_world = worldSize;
- if (isOutlineColorDefined) {
- // If we defined a different color for the fill outline, we are
- // going to ignore the bits in 0x07 and just care about the global
- // clipping mask.
- setDepthSublayer(2); // OK
- } else {
- // Otherwise, we only want to drawFill the antialiased parts that are
- // *outside* the current shape. This is important in case the fill
- // or stroke color is translucent. If we wouldn't clip to outside
- // the current shape, some pixels from the outline stroke overlapped
- // the (non-antialiased) fill.
- setDepthSublayer(0); // OK
+ if (!properties.get<FillPattern>().from.empty()) {
+ if (pass != RenderPass::Translucent) {
+ return;
}
- bucket.drawVertices(outlineShader, context, paintMode());
- }
- if (pattern) {
optional<SpriteAtlasPosition> imagePosA = spriteAtlas->getPosition(
- properties.fillPattern.value.from, SpritePatternMode::Repeating);
- optional<SpriteAtlasPosition> imagePosB =
- spriteAtlas->getPosition(properties.fillPattern.value.to, SpritePatternMode::Repeating);
-
- // Image fill.
- if (pass == RenderPass::Translucent && imagePosA && imagePosB) {
- context.program = patternShader.getID();
- patternShader.u_matrix = vertexMatrix;
- patternShader.u_pattern_tl_a = imagePosA->tl;
- patternShader.u_pattern_br_a = imagePosA->br;
- patternShader.u_pattern_tl_b = imagePosB->tl;
- patternShader.u_pattern_br_b = imagePosB->br;
- patternShader.u_opacity = properties.fillOpacity;
- patternShader.u_image = 0;
- patternShader.u_mix = properties.fillPattern.value.t;
- patternShader.u_pattern_size_a = imagePosA->size;
- patternShader.u_pattern_size_b = imagePosB->size;
- patternShader.u_scale_a = properties.fillPattern.value.fromScale;
- patternShader.u_scale_b = properties.fillPattern.value.toScale;
- patternShader.u_tile_units_to_pixels = 1.0f / tile.id.pixelsToTileUnits(1.0f, state.getIntegerZoom());
-
- GLint tileSizeAtNearestZoom = util::tileSize * state.zoomScale(state.getIntegerZoom() - tile.id.canonical.z);
- GLint pixelX = tileSizeAtNearestZoom * (tile.id.canonical.x + tile.id.wrap * state.zoomScale(tile.id.canonical.z));
- GLint pixelY = tileSizeAtNearestZoom * tile.id.canonical.y;
- patternShader.u_pixel_coord_upper = {{ float(pixelX >> 16), float(pixelY >> 16) }};
- patternShader.u_pixel_coord_lower = {{ float(pixelX & 0xFFFF), float(pixelY & 0xFFFF) }};
-
- spriteAtlas->bind(true, context, 0);
+ properties.get<FillPattern>().from, SpritePatternMode::Repeating);
+ optional<SpriteAtlasPosition> imagePosB = spriteAtlas->getPosition(
+ properties.get<FillPattern>().to, SpritePatternMode::Repeating);
- // Draw the actual triangles into the color & stencil buffer.
- setDepthSublayer(0);
- bucket.drawElements(patternShader, context, paintMode());
-
- if (properties.fillAntialias && !isOutlineColorDefined) {
- context.program = outlinePatternShader.getID();
- outlinePatternShader.u_matrix = vertexMatrix;
-
- outlinePatternShader.u_pattern_tl_a = imagePosA->tl;
- outlinePatternShader.u_pattern_br_a = imagePosA->br;
- outlinePatternShader.u_pattern_tl_b = imagePosB->tl;
- outlinePatternShader.u_pattern_br_b = imagePosB->br;
- outlinePatternShader.u_opacity = properties.fillOpacity;
- outlinePatternShader.u_image = 0;
- outlinePatternShader.u_mix = properties.fillPattern.value.t;
- outlinePatternShader.u_pattern_size_a = imagePosA->size;
- outlinePatternShader.u_pattern_size_b = imagePosB->size;
- outlinePatternShader.u_scale_a = properties.fillPattern.value.fromScale;
- outlinePatternShader.u_scale_b = properties.fillPattern.value.toScale;
- outlinePatternShader.u_tile_units_to_pixels = 1.0f / tile.id.pixelsToTileUnits(1.0f, state.getIntegerZoom());
- outlinePatternShader.u_pixel_coord_upper = {{ float(pixelX >> 16), float(pixelY >> 16) }};
- outlinePatternShader.u_pixel_coord_lower = {{ float(pixelX & 0xFFFF), float(pixelY & 0xFFFF) }};
-
- // Draw the entire line
- outlinePatternShader.u_world = worldSize;
-
- spriteAtlas->bind(true, context, 0);
-
- setDepthSublayer(2);
- bucket.drawVertices(outlinePatternShader, context, paintMode());
- }
+ if (!imagePosA || !imagePosB) {
+ return;
}
- } else {
- // No image fill.
- if ((fillColor.a >= 1.0f && opacity >= 1.0f) == (pass == RenderPass::Opaque)) {
- // Only draw the fill when it's either opaque and we're drawing opaque
- // fragments or when it's translucent and we're drawing translucent
- // fragments
- // Draw filling rectangle.
- context.program = plainShader.getID();
- plainShader.u_matrix = vertexMatrix;
- plainShader.u_color = fillColor;
- plainShader.u_opacity = opacity;
- // Draw the actual triangles into the color & stencil buffer.
- setDepthSublayer(1);
- bucket.drawElements(plainShader, context, paintMode());
+ spriteAtlas->bind(true, context, 0);
+
+ auto draw = [&] (uint8_t sublayer,
+ auto& program,
+ const auto& drawMode,
+ const auto& vertexBuffer,
+ const auto& indexBuffer,
+ const auto& segments) {
+ program.draw(
+ context,
+ drawMode,
+ depthModeForSublayer(sublayer, gl::DepthMode::ReadWrite),
+ stencilModeForClipping(tile.clip),
+ colorModeForRenderPass(),
+ FillPatternUniforms::values(
+ tile.translatedMatrix(properties.get<FillTranslate>(),
+ properties.get<FillTranslateAnchor>(),
+ state),
+ properties.get<FillOpacity>(),
+ context.viewport.getCurrentValue().size,
+ *imagePosA,
+ *imagePosB,
+ properties.get<FillPattern>(),
+ tile.id,
+ state
+ ),
+ vertexBuffer,
+ indexBuffer,
+ segments
+ );
+ };
+
+ draw(0,
+ parameters.programs.fillPattern,
+ gl::Triangles(),
+ *bucket.vertexBuffer,
+ *bucket.triangleIndexBuffer,
+ bucket.triangleSegments);
+
+ if (!properties.get<FillAntialias>() || !layer.impl->paint.unevaluated.get<FillOutlineColor>().isUndefined()) {
+ return;
}
- }
-
- // Because we're drawing top-to-bottom, and we update the stencil mask
- // below, we have to draw the outline first (!)
- if (fringeline && pass == RenderPass::Translucent) {
- context.program = outlineShader.getID();
- outlineShader.u_matrix = vertexMatrix;
- outlineShader.u_outline_color = fillColor;
- outlineShader.u_opacity = opacity;
+ draw(2,
+ parameters.programs.fillOutlinePattern,
+ gl::Lines { 2.0f },
+ *bucket.vertexBuffer,
+ *bucket.lineIndexBuffer,
+ bucket.lineSegments);
+ } else {
+ auto draw = [&] (uint8_t sublayer,
+ auto& program,
+ Color outlineColor,
+ const auto& drawMode,
+ const auto& vertexBuffer,
+ const auto& indexBuffer,
+ const auto& segments) {
+ program.draw(
+ context,
+ drawMode,
+ depthModeForSublayer(sublayer, gl::DepthMode::ReadWrite),
+ stencilModeForClipping(tile.clip),
+ colorModeForRenderPass(),
+ FillProgram::UniformValues {
+ uniforms::u_matrix::Value{ tile.translatedMatrix(properties.get<FillTranslate>(),
+ properties.get<FillTranslateAnchor>(),
+ state) },
+ uniforms::u_opacity::Value{ properties.get<FillOpacity>() },
+ uniforms::u_color::Value{ properties.get<FillColor>() },
+ uniforms::u_outline_color::Value{ outlineColor },
+ uniforms::u_world::Value{ context.viewport.getCurrentValue().size },
+ },
+ vertexBuffer,
+ indexBuffer,
+ segments
+ );
+ };
+
+ if (properties.get<FillAntialias>() && !layer.impl->paint.unevaluated.get<FillOutlineColor>().isUndefined() && pass == RenderPass::Translucent) {
+ draw(2,
+ parameters.programs.fillOutline,
+ properties.get<FillOutlineColor>(),
+ gl::Lines { 2.0f },
+ *bucket.vertexBuffer,
+ *bucket.lineIndexBuffer,
+ bucket.lineSegments);
+ }
- // Draw the entire line
- outlineShader.u_world = worldSize;
+ // Only draw the fill when it's opaque and we're drawing opaque fragments,
+ // or when it's translucent and we're drawing translucent fragments.
+ if ((properties.get<FillColor>().a >= 1.0f && properties.get<FillOpacity>() >= 1.0f) == (pass == RenderPass::Opaque)) {
+ draw(1,
+ parameters.programs.fill,
+ properties.get<FillOutlineColor>(),
+ gl::Triangles(),
+ *bucket.vertexBuffer,
+ *bucket.triangleIndexBuffer,
+ bucket.triangleSegments);
+ }
- setDepthSublayer(2);
- bucket.drawVertices(outlineShader, context, paintMode());
+ if (properties.get<FillAntialias>() && layer.impl->paint.unevaluated.get<FillOutlineColor>().isUndefined() && pass == RenderPass::Translucent) {
+ draw(2,
+ parameters.programs.fillOutline,
+ properties.get<FillColor>(),
+ gl::Lines { 2.0f },
+ *bucket.vertexBuffer,
+ *bucket.lineIndexBuffer,
+ bucket.lineSegments);
+ }
}
}
diff --git a/src/mbgl/renderer/painter_line.cpp b/src/mbgl/renderer/painter_line.cpp
index 85a5786353..a66f53a856 100644
--- a/src/mbgl/renderer/painter_line.cpp
+++ b/src/mbgl/renderer/painter_line.cpp
@@ -4,10 +4,10 @@
#include <mbgl/renderer/render_tile.hpp>
#include <mbgl/style/layers/line_layer.hpp>
#include <mbgl/style/layers/line_layer_impl.hpp>
-#include <mbgl/shader/shaders.hpp>
+#include <mbgl/programs/programs.hpp>
+#include <mbgl/programs/line_program.hpp>
#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/geometry/line_atlas.hpp>
-#include <mbgl/util/mat2.hpp>
namespace mbgl {
@@ -17,150 +17,70 @@ void Painter::renderLine(PaintParameters& parameters,
LineBucket& bucket,
const LineLayer& layer,
const RenderTile& tile) {
- // Abort early.
- if (pass == RenderPass::Opaque) return;
-
- context.stencilOp = { gl::StencilTestOperation::Keep, gl::StencilTestOperation::Keep,
- gl::StencilTestOperation::Replace };
- context.stencilTest = true;
- context.depthFunc = gl::DepthTestFunction::LessEqual;
- context.depthTest = true;
- context.depthMask = false;
-
- const auto& properties = layer.impl->paint;
- const auto& layout = bucket.layout;
-
- // the distance over which the line edge fades out.
- // Retina devices need a smaller distance to avoid aliasing.
- float antialiasing = 1.0 / frame.pixelRatio;
-
- float blur = properties.lineBlur + antialiasing;
-
- const Color color = properties.lineColor;
- const float opacity = properties.lineOpacity;
- const float ratio = 1.0 / tile.id.pixelsToTileUnits(1.0, state.getZoom());
-
- mat2 antialiasingMatrix;
- matrix::identity(antialiasingMatrix);
- matrix::scale(antialiasingMatrix, antialiasingMatrix, 1.0, std::cos(state.getPitch()));
- matrix::rotate(antialiasingMatrix, antialiasingMatrix, state.getAngle());
-
- // calculate how much longer the real world distance is at the top of the screen
- // than at the middle of the screen.
- float topedgelength = std::sqrt(std::pow(state.getHeight(), 2.0f) / 4.0f * (1.0f + std::pow(state.getAltitude(), 2.0f)));
- float x = state.getHeight() / 2.0f * std::tan(state.getPitch());
- float extra = (topedgelength + x) / topedgelength - 1.0f;
-
- mat4 vtxMatrix = tile.translatedMatrix(properties.lineTranslate,
- properties.lineTranslateAnchor,
- state);
-
- setDepthSublayer(0);
-
- auto& linesdfShader = parameters.shaders.lineSDF;
- auto& linepatternShader = parameters.shaders.linePattern;
- auto& lineShader = parameters.shaders.line;
-
- if (!properties.lineDasharray.value.from.empty()) {
- context.program = linesdfShader.getID();
-
- linesdfShader.u_matrix = vtxMatrix;
- linesdfShader.u_linewidth = properties.lineWidth / 2;
- linesdfShader.u_gapwidth = properties.lineGapWidth / 2;
- linesdfShader.u_antialiasing = antialiasing / 2;
- linesdfShader.u_ratio = ratio;
- linesdfShader.u_blur = blur;
- linesdfShader.u_color = color;
- linesdfShader.u_opacity = opacity;
-
- const LinePatternCap cap =
- layout.lineCap == LineCapType::Round ? LinePatternCap::Round : LinePatternCap::Square;
- LinePatternPos posA = lineAtlas->getDashPosition(properties.lineDasharray.value.from, cap);
- LinePatternPos posB = lineAtlas->getDashPosition(properties.lineDasharray.value.to, cap);
-
- const float widthA = posA.width * properties.lineDasharray.value.fromScale * layer.impl->dashLineWidth;
- const float widthB = posB.width * properties.lineDasharray.value.toScale * layer.impl->dashLineWidth;
-
- float scaleXA = 1.0 / tile.id.pixelsToTileUnits(widthA, state.getIntegerZoom());
- float scaleYA = -posA.height / 2.0;
- float scaleXB = 1.0 / tile.id.pixelsToTileUnits(widthB, state.getIntegerZoom());
- float scaleYB = -posB.height / 2.0;
+ if (pass == RenderPass::Opaque) {
+ return;
+ }
- linesdfShader.u_patternscale_a = {{ scaleXA, scaleYA }};
- linesdfShader.u_tex_y_a = posA.y;
- linesdfShader.u_patternscale_b = {{ scaleXB, scaleYB }};
- linesdfShader.u_tex_y_b = posB.y;
- linesdfShader.u_sdfgamma = lineAtlas->width / (std::min(widthA, widthB) * 256.0 * frame.pixelRatio) / 2;
- linesdfShader.u_mix = properties.lineDasharray.value.t;
- linesdfShader.u_extra = extra;
- linesdfShader.u_offset = -properties.lineOffset;
- linesdfShader.u_antialiasingmatrix = antialiasingMatrix;
+ const LinePaintProperties::Evaluated& properties = layer.impl->paint.evaluated;
+
+ auto draw = [&] (auto& program, auto&& uniformValues) {
+ program.draw(
+ context,
+ gl::Triangles(),
+ depthModeForSublayer(0, gl::DepthMode::ReadOnly),
+ stencilModeForClipping(tile.clip),
+ colorModeForRenderPass(),
+ std::move(uniformValues),
+ *bucket.vertexBuffer,
+ *bucket.indexBuffer,
+ bucket.segments
+ );
+ };
+
+ if (!properties.get<LineDasharray>().from.empty()) {
+ const LinePatternCap cap = bucket.layout.get<LineCap>() == LineCapType::Round
+ ? LinePatternCap::Round : LinePatternCap::Square;
+ LinePatternPos posA = lineAtlas->getDashPosition(properties.get<LineDasharray>().from, cap);
+ LinePatternPos posB = lineAtlas->getDashPosition(properties.get<LineDasharray>().to, cap);
- linesdfShader.u_image = 0;
lineAtlas->bind(context, 0);
- bucket.drawLineSDF(linesdfShader, context, paintMode());
-
- } else if (!properties.linePattern.value.from.empty()) {
- optional<SpriteAtlasPosition> imagePosA = spriteAtlas->getPosition(
- properties.linePattern.value.from, SpritePatternMode::Repeating);
- optional<SpriteAtlasPosition> imagePosB =
- spriteAtlas->getPosition(properties.linePattern.value.to, SpritePatternMode::Repeating);
-
- if (!imagePosA || !imagePosB)
+ draw(parameters.programs.lineSDF,
+ LineSDFProgram::uniformValues(
+ properties,
+ frame.pixelRatio,
+ tile,
+ state,
+ posA,
+ posB,
+ layer.impl->dashLineWidth,
+ lineAtlas->getSize().width));
+
+ } else if (!properties.get<LinePattern>().from.empty()) {
+ optional<SpriteAtlasPosition> posA = spriteAtlas->getPosition(
+ properties.get<LinePattern>().from, SpritePatternMode::Repeating);
+ optional<SpriteAtlasPosition> posB = spriteAtlas->getPosition(
+ properties.get<LinePattern>().to, SpritePatternMode::Repeating);
+
+ if (!posA || !posB)
return;
- context.program = linepatternShader.getID();
-
- linepatternShader.u_matrix = vtxMatrix;
- linepatternShader.u_linewidth = properties.lineWidth / 2;
- linepatternShader.u_gapwidth = properties.lineGapWidth / 2;
- linepatternShader.u_antialiasing = antialiasing / 2;
- linepatternShader.u_ratio = ratio;
- linepatternShader.u_blur = blur;
-
- linepatternShader.u_pattern_size_a = {{
- tile.id.pixelsToTileUnits((*imagePosA).size[0] * properties.linePattern.value.fromScale, state.getIntegerZoom()),
- (*imagePosA).size[1]
- }};
- linepatternShader.u_pattern_tl_a = (*imagePosA).tl;
- linepatternShader.u_pattern_br_a = (*imagePosA).br;
-
- linepatternShader.u_pattern_size_b = {{
- tile.id.pixelsToTileUnits((*imagePosB).size[0] * properties.linePattern.value.toScale, state.getIntegerZoom()),
- (*imagePosB).size[1]
- }};
- linepatternShader.u_pattern_tl_b = (*imagePosB).tl;
- linepatternShader.u_pattern_br_b = (*imagePosB).br;
-
- linepatternShader.u_fade = properties.linePattern.value.t;
- linepatternShader.u_opacity = properties.lineOpacity;
- linepatternShader.u_extra = extra;
- linepatternShader.u_offset = -properties.lineOffset;
- linepatternShader.u_antialiasingmatrix = antialiasingMatrix;
-
- linepatternShader.u_image = 0;
spriteAtlas->bind(true, context, 0);
- bucket.drawLinePatterns(linepatternShader, context, paintMode());
+ draw(parameters.programs.linePattern,
+ LinePatternProgram::uniformValues(
+ properties,
+ tile,
+ state,
+ *posA,
+ *posB));
} else {
- context.program = lineShader.getID();
-
- lineShader.u_matrix = vtxMatrix;
- lineShader.u_linewidth = properties.lineWidth / 2;
- lineShader.u_gapwidth = properties.lineGapWidth / 2;
- lineShader.u_antialiasing = antialiasing / 2;
- lineShader.u_ratio = ratio;
- lineShader.u_blur = blur;
- lineShader.u_extra = extra;
- lineShader.u_offset = -properties.lineOffset;
- lineShader.u_antialiasingmatrix = antialiasingMatrix;
-
- lineShader.u_color = color;
- lineShader.u_opacity = opacity;
-
- bucket.drawLines(lineShader, context, paintMode());
+ draw(parameters.programs.line,
+ LineProgram::uniformValues(
+ properties,
+ tile,
+ state));
}
}
diff --git a/src/mbgl/renderer/painter_raster.cpp b/src/mbgl/renderer/painter_raster.cpp
index 8b39c8adf8..96bb6dc565 100644
--- a/src/mbgl/renderer/painter_raster.cpp
+++ b/src/mbgl/renderer/painter_raster.cpp
@@ -1,57 +1,17 @@
#include <mbgl/renderer/painter.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/render_tile.hpp>
-#include <mbgl/gl/gl.hpp>
#include <mbgl/renderer/raster_bucket.hpp>
#include <mbgl/style/layers/raster_layer.hpp>
#include <mbgl/style/layers/raster_layer_impl.hpp>
-#include <mbgl/shader/shaders.hpp>
+#include <mbgl/programs/programs.hpp>
+#include <mbgl/programs/raster_program.hpp>
namespace mbgl {
using namespace style;
-void Painter::renderRaster(PaintParameters& parameters,
- RasterBucket& bucket,
- const RasterLayer& layer,
- const RenderTile& tile) {
- if (pass != RenderPass::Translucent) return;
-
- const RasterPaintProperties& properties = layer.impl->paint;
-
- if (bucket.hasData()) {
- auto& rasterShader = parameters.shaders.raster;
- auto& rasterVAO = parameters.shaders.coveringRasterArray;
-
- context.program = rasterShader.getID();
- rasterShader.u_matrix = tile.matrix;
- rasterShader.u_buffer_scale = 1.0f;
- rasterShader.u_opacity0 = properties.rasterOpacity;
- rasterShader.u_opacity1 = 0;
-
- rasterShader.u_brightness_low = properties.rasterBrightnessMin;
- rasterShader.u_brightness_high = properties.rasterBrightnessMax;
- rasterShader.u_saturation_factor = saturationFactor(properties.rasterSaturation);
- rasterShader.u_contrast_factor = contrastFactor(properties.rasterContrast);
- rasterShader.u_spin_weights = spinWeights(properties.rasterHueRotate);
-
- context.stencilTest = false;
-
- rasterShader.u_image0 = 0; // GL_TEXTURE0
- rasterShader.u_image1 = 1; // GL_TEXTURE1
- rasterShader.u_tl_parent = {{ 0.0f, 0.0f }};
- rasterShader.u_scale_parent = 1.0f;
-
- context.depthFunc = gl::DepthTestFunction::LessEqual;
- context.depthTest = true;
- context.depthMask = false;
- setDepthSublayer(0);
-
- bucket.drawRaster(rasterShader, rasterVertexBuffer, rasterVAO, context);
- }
-}
-
-float Painter::saturationFactor(float saturation) {
+static float saturationFactor(float saturation) {
if (saturation > 0) {
return 1 - 1 / (1.001 - saturation);
} else {
@@ -59,7 +19,7 @@ float Painter::saturationFactor(float saturation) {
}
}
-float Painter::contrastFactor(float contrast) {
+static float contrastFactor(float contrast) {
if (contrast > 0) {
return 1 / (1 - contrast);
} else {
@@ -67,7 +27,7 @@ float Painter::contrastFactor(float contrast) {
}
}
-std::array<float, 3> Painter::spinWeights(float spin) {
+static std::array<float, 3> spinWeights(float spin) {
spin *= util::DEG2RAD;
float s = std::sin(spin);
float c = std::cos(spin);
@@ -79,4 +39,46 @@ std::array<float, 3> Painter::spinWeights(float spin) {
return spin_weights;
}
+void Painter::renderRaster(PaintParameters& parameters,
+ RasterBucket& bucket,
+ const RasterLayer& layer,
+ const RenderTile& tile) {
+ if (pass != RenderPass::Translucent)
+ return;
+ if (!bucket.hasData())
+ return;
+
+ const RasterPaintProperties::Evaluated& properties = layer.impl->paint.evaluated;
+
+ assert(bucket.texture);
+ context.bindTexture(*bucket.texture, 0, gl::TextureFilter::Linear);
+ context.bindTexture(*bucket.texture, 1, gl::TextureFilter::Linear);
+
+ parameters.programs.raster.draw(
+ context,
+ gl::Triangles(),
+ depthModeForSublayer(0, gl::DepthMode::ReadOnly),
+ gl::StencilMode::disabled(),
+ colorModeForRenderPass(),
+ RasterProgram::UniformValues {
+ uniforms::u_matrix::Value{ tile.matrix },
+ uniforms::u_image0::Value{ 0 },
+ uniforms::u_image1::Value{ 1 },
+ uniforms::u_opacity0::Value{ properties.get<RasterOpacity>() },
+ uniforms::u_opacity1::Value{ 0 },
+ uniforms::u_brightness_low::Value{ properties.get<RasterBrightnessMin>() },
+ uniforms::u_brightness_high::Value{ properties.get<RasterBrightnessMax>() },
+ uniforms::u_saturation_factor::Value{ saturationFactor(properties.get<RasterSaturation>()) },
+ uniforms::u_contrast_factor::Value{ contrastFactor(properties.get<RasterContrast>()) },
+ uniforms::u_spin_weights::Value{ spinWeights(properties.get<RasterHueRotate>()) },
+ uniforms::u_buffer_scale::Value{ 1.0f },
+ uniforms::u_scale_parent::Value{ 1.0f },
+ uniforms::u_tl_parent::Value{ std::array<float, 2> {{ 0.0f, 0.0f }} },
+ },
+ rasterVertexBuffer,
+ tileTriangleIndexBuffer,
+ rasterSegments
+ );
+}
+
} // namespace mbgl
diff --git a/src/mbgl/renderer/painter_symbol.cpp b/src/mbgl/renderer/painter_symbol.cpp
index 2ed6facad8..39075976a0 100644
--- a/src/mbgl/renderer/painter_symbol.cpp
+++ b/src/mbgl/renderer/painter_symbol.cpp
@@ -6,8 +6,11 @@
#include <mbgl/style/layers/symbol_layer_impl.hpp>
#include <mbgl/text/glyph_atlas.hpp>
#include <mbgl/sprite/sprite_atlas.hpp>
-#include <mbgl/shader/shaders.hpp>
+#include <mbgl/programs/programs.hpp>
+#include <mbgl/programs/symbol_program.hpp>
+#include <mbgl/programs/collision_box_program.hpp>
#include <mbgl/util/math.hpp>
+#include <mbgl/tile/tile.hpp>
#include <cmath>
@@ -15,254 +18,114 @@ namespace mbgl {
using namespace style;
-void Painter::renderSDF(SymbolBucket& bucket,
- const RenderTile& tile,
- float sdfFontSize,
- std::array<float, 2> texsize,
- SymbolSDFShader& sdfShader,
- void (SymbolBucket::*drawSDF)(SymbolSDFShader&, gl::Context&, PaintMode),
-
- // Layout
- AlignmentType rotationAlignment,
- AlignmentType pitchAlignment,
- float layoutSize,
-
- // Paint
- float opacity,
- Color color,
- Color haloColor,
- float haloWidth,
- float haloBlur,
- std::array<float, 2> translate,
- TranslateAnchorType translateAnchor,
- float paintSize)
-{
- mat4 vtxMatrix = tile.translatedMatrix(translate, translateAnchor, state);
-
- // If layerStyle.size > bucket.info.fontSize then labels may collide
- float fontSize = paintSize;
- float fontScale = fontSize / sdfFontSize;
-
- bool rotateWithMap = rotationAlignment == AlignmentType::Map;
- bool pitchWithMap = pitchAlignment == AlignmentType::Map;
-
- std::array<float, 2> extrudeScale;
- float gammaScale;
-
- if (pitchWithMap) {
- gammaScale = 1.0 / std::cos(state.getPitch());
- extrudeScale.fill(tile.id.pixelsToTileUnits(1, state.getZoom()) * fontScale);
- } else {
- gammaScale = 1.0;
- extrudeScale = {{
- pixelsToGLUnits[0] * fontScale * state.getAltitude(),
- pixelsToGLUnits[1] * fontScale * state.getAltitude()
- }};
- }
-
- context.program = sdfShader.getID();
- sdfShader.u_matrix = vtxMatrix;
- sdfShader.u_extrude_scale = extrudeScale;
- sdfShader.u_texsize = texsize;
- sdfShader.u_rotate_with_map = rotateWithMap;
- sdfShader.u_pitch_with_map = pitchWithMap;
- sdfShader.u_texture = 0;
- sdfShader.u_pitch = state.getPitch();
- sdfShader.u_bearing = -1.0f * state.getAngle();
- sdfShader.u_aspect_ratio = (state.getWidth() * 1.0f) / (state.getHeight() * 1.0f);
-
- // adjust min/max zooms for variable font sies
- float zoomAdjust = std::log(fontSize / layoutSize) / std::log(2);
-
- sdfShader.u_zoom = (state.getZoom() - zoomAdjust) * 10; // current zoom level
-
- frameHistory.bind(context, 1);
- sdfShader.u_fadetexture = 1;
-
- // The default gamma value has to be adjust for the current pixelratio so that we're not
- // drawing blurry font on retina screens.
- const float gamma = 0.105 * sdfFontSize / fontSize / frame.pixelRatio;
-
- const float sdfPx = 8.0f;
- const float blurOffset = 1.19f;
- const float haloOffset = 6.0f;
-
- // We're drawing in the translucent pass which is bottom-to-top, so we need
- // to draw the halo first.
- if (haloColor.a > 0.0f && haloWidth > 0.0f) {
- sdfShader.u_gamma = (haloBlur * blurOffset / fontScale / sdfPx + gamma) * gammaScale;
- sdfShader.u_color = haloColor;
- sdfShader.u_opacity = opacity;
- sdfShader.u_buffer = (haloOffset - haloWidth / fontScale) / sdfPx;
- (bucket.*drawSDF)(sdfShader, context, paintMode());
- }
-
- // Then, we draw the text/icon over the halo
- if (color.a > 0.0f) {
- sdfShader.u_gamma = gamma * gammaScale;
- sdfShader.u_color = color;
- sdfShader.u_opacity = opacity;
- sdfShader.u_buffer = (256.0f - 64.0f) / 256.0f;
- (bucket.*drawSDF)(sdfShader, context, paintMode());
- }
-}
-
void Painter::renderSymbol(PaintParameters& parameters,
SymbolBucket& bucket,
const SymbolLayer& layer,
const RenderTile& tile) {
- // Abort early.
if (pass == RenderPass::Opaque) {
return;
}
- const auto& paint = layer.impl->paint;
const auto& layout = bucket.layout;
- context.depthMask = false;
-
- // TODO remove the `true ||` when #1673 is implemented
- const bool drawAcrossEdges = (frame.mapMode == MapMode::Continuous) && (true || !(layout.textAllowOverlap || layout.iconAllowOverlap ||
- layout.textIgnorePlacement || layout.iconIgnorePlacement));
-
- // Disable the stencil test so that labels aren't clipped to tile boundaries.
- //
- // Layers with features that may be drawn overlapping aren't clipped. These
- // layers are sorted in the y direction, and to draw the correct ordering near
- // tile edges the icons are included in both tiles and clipped when drawing.
- if (drawAcrossEdges) {
- context.stencilTest = false;
- } else {
- context.stencilOp = { gl::StencilTestOperation::Keep, gl::StencilTestOperation::Keep,
- gl::StencilTestOperation::Replace };
- context.stencilTest = true;
- }
+ frameHistory.bind(context, 1);
- setDepthSublayer(0);
+ auto draw = [&] (auto& program,
+ auto&& uniformValues,
+ const auto& buffers,
+ const SymbolPropertyValues& values_)
+ {
+ // We clip symbols to their tile extent in still mode.
+ const bool needsClipping = frame.mapMode == MapMode::Still;
+
+ program.draw(
+ context,
+ gl::Triangles(),
+ values_.pitchAlignment == AlignmentType::Map
+ ? depthModeForSublayer(0, gl::DepthMode::ReadOnly)
+ : gl::DepthMode::disabled(),
+ needsClipping
+ ? stencilModeForClipping(tile.clip)
+ : gl::StencilMode::disabled(),
+ colorModeForRenderPass(),
+ std::move(uniformValues),
+ *buffers.vertexBuffer,
+ *buffers.indexBuffer,
+ buffers.segments
+ );
+ };
if (bucket.hasIconData()) {
- if (layout.iconRotationAlignment == AlignmentType::Map) {
- context.depthFunc = gl::DepthTestFunction::LessEqual;
- context.depthTest = true;
- } else {
- context.depthTest = false;
- }
+ auto values = layer.impl->iconPropertyValues(layout);
- bool sdf = bucket.sdfIcons;
+ SpriteAtlas& atlas = *layer.impl->spriteAtlas;
+ const bool iconScaled = values.paintSize != 1.0f || frame.pixelRatio != atlas.getPixelRatio() || bucket.iconsNeedLinear;
+ const bool iconTransformed = values.rotationAlignment == AlignmentType::Map || state.getPitch() != 0;
+ atlas.bind(bucket.sdfIcons || state.isChanging() || iconScaled || iconTransformed, context, 0);
- const float angleOffset =
- layout.iconRotationAlignment == AlignmentType::Map
- ? state.getAngle()
- : 0;
+ const Size texsize = atlas.getSize();
- const float fontSize = layer.impl->iconSize;
- const float fontScale = fontSize / 1.0f;
-
- SpriteAtlas* activeSpriteAtlas = layer.impl->spriteAtlas;
- const bool iconScaled = fontScale != 1 || frame.pixelRatio != activeSpriteAtlas->getPixelRatio() || bucket.iconsNeedLinear;
- const bool iconTransformed = layout.iconRotationAlignment == AlignmentType::Map || angleOffset != 0 || state.getPitch() != 0;
- activeSpriteAtlas->bind(sdf || state.isChanging() || iconScaled || iconTransformed, context, 0);
-
- if (sdf) {
- renderSDF(bucket,
- tile,
- 1.0f,
- {{ float(activeSpriteAtlas->getWidth()) / 4.0f, float(activeSpriteAtlas->getHeight()) / 4.0f }},
- parameters.shaders.symbolIconSDF,
- &SymbolBucket::drawIcons,
- layout.iconRotationAlignment,
- // icon-pitch-alignment is not yet implemented
- // and we simply inherit the rotation alignment
- layout.iconRotationAlignment,
- layout.iconSize,
- paint.iconOpacity,
- paint.iconColor,
- paint.iconHaloColor,
- paint.iconHaloWidth,
- paint.iconHaloBlur,
- paint.iconTranslate,
- paint.iconTranslateAnchor,
- layer.impl->iconSize);
- } else {
- mat4 vtxMatrix = tile.translatedMatrix(paint.iconTranslate,
- paint.iconTranslateAnchor,
- state);
-
- std::array<float, 2> extrudeScale;
-
- const bool alignedWithMap = layout.iconRotationAlignment == AlignmentType::Map;
- if (alignedWithMap) {
- extrudeScale.fill(tile.id.pixelsToTileUnits(1, state.getZoom()) * fontScale);
- } else {
- extrudeScale = {{
- pixelsToGLUnits[0] * fontScale * state.getAltitude(),
- pixelsToGLUnits[1] * fontScale * state.getAltitude()
- }};
+ if (bucket.sdfIcons) {
+ if (values.hasHalo()) {
+ draw(parameters.programs.symbolIconSDF,
+ SymbolSDFProgram::haloUniformValues(values, texsize, pixelsToGLUnits, tile, state, frame.pixelRatio),
+ bucket.icon,
+ values);
}
- auto& iconShader = parameters.shaders.symbolIcon;
+ if (values.hasForeground()) {
+ draw(parameters.programs.symbolIconSDF,
+ SymbolSDFProgram::foregroundUniformValues(values, texsize, pixelsToGLUnits, tile, state, frame.pixelRatio),
+ bucket.icon,
+ values);
+ }
+ } else {
+ draw(parameters.programs.symbolIcon,
+ SymbolIconProgram::uniformValues(values, texsize, pixelsToGLUnits, tile, state),
+ bucket.icon,
+ values);
+ }
+ }
- context.program = iconShader.getID();
- iconShader.u_matrix = vtxMatrix;
- iconShader.u_extrude_scale = extrudeScale;
- iconShader.u_texsize = {{ float(activeSpriteAtlas->getWidth()) / 4.0f, float(activeSpriteAtlas->getHeight()) / 4.0f }};
- iconShader.u_rotate_with_map = alignedWithMap;
- iconShader.u_texture = 0;
+ if (bucket.hasTextData()) {
+ glyphAtlas->bind(context, 0);
- // adjust min/max zooms for variable font sies
- float zoomAdjust = std::log(fontSize / layout.iconSize) / std::log(2);
- iconShader.u_zoom = (state.getZoom() - zoomAdjust) * 10; // current zoom level
- iconShader.u_opacity = paint.iconOpacity;
+ auto values = layer.impl->textPropertyValues(layout);
- frameHistory.bind(context, 1);
- iconShader.u_fadetexture = 1;
+ const Size texsize = glyphAtlas->getSize();
- bucket.drawIcons(iconShader, context, paintMode());
+ if (values.hasHalo()) {
+ draw(parameters.programs.symbolGlyph,
+ SymbolSDFProgram::haloUniformValues(values, texsize, pixelsToGLUnits, tile, state, frame.pixelRatio),
+ bucket.text,
+ values);
}
- }
- if (bucket.hasTextData()) {
- if (layout.textPitchAlignment == AlignmentType::Map) {
- context.depthFunc = gl::DepthTestFunction::LessEqual;
- context.depthTest = true;
- } else {
- context.depthTest = false;
+ if (values.hasForeground()) {
+ draw(parameters.programs.symbolGlyph,
+ SymbolSDFProgram::foregroundUniformValues(values, texsize, pixelsToGLUnits, tile, state, frame.pixelRatio),
+ bucket.text,
+ values);
}
-
- glyphAtlas->bind(context, 0);
-
- renderSDF(bucket,
- tile,
- 24.0f,
- {{ float(glyphAtlas->width) / 4, float(glyphAtlas->height) / 4 }},
- parameters.shaders.symbolGlyph,
- &SymbolBucket::drawGlyphs,
- layout.textRotationAlignment,
- layout.textPitchAlignment,
- layout.textSize,
- paint.textOpacity,
- paint.textColor,
- paint.textHaloColor,
- paint.textHaloWidth,
- paint.textHaloBlur,
- paint.textTranslate,
- paint.textTranslateAnchor,
- layer.impl->textSize);
}
if (bucket.hasCollisionBoxData()) {
- context.stencilTest = false;
-
- auto& collisionBoxShader = shaders->collisionBox;
- context.program = collisionBoxShader.getID();
- collisionBoxShader.u_matrix = tile.matrix;
- // TODO: This was the overscaled z instead of the canonical z.
- collisionBoxShader.u_scale = std::pow(2, state.getZoom() - tile.id.canonical.z);
- collisionBoxShader.u_zoom = state.getZoom() * 10;
- collisionBoxShader.u_maxzoom = (tile.id.canonical.z + 1) * 10;
- context.lineWidth = 1.0f;
-
- bucket.drawCollisionBoxes(collisionBoxShader, context);
+ programs->collisionBox.draw(
+ context,
+ gl::Lines { 1.0f },
+ gl::DepthMode::disabled(),
+ gl::StencilMode::disabled(),
+ colorModeForRenderPass(),
+ CollisionBoxProgram::UniformValues {
+ uniforms::u_matrix::Value{ tile.matrix },
+ uniforms::u_scale::Value{ std::pow(2.0f, float(state.getZoom() - tile.tile.id.overscaledZ)) },
+ uniforms::u_zoom::Value{ float(state.getZoom() * 10) },
+ uniforms::u_maxzoom::Value{ float((tile.id.canonical.z + 1) * 10) },
+ },
+ *bucket.collisionBox.vertexBuffer,
+ *bucket.collisionBox.indexBuffer,
+ bucket.collisionBox.segments
+ );
}
}
diff --git a/src/mbgl/renderer/raster_bucket.cpp b/src/mbgl/renderer/raster_bucket.cpp
index 80d6dfe8dd..0355911296 100644
--- a/src/mbgl/renderer/raster_bucket.cpp
+++ b/src/mbgl/renderer/raster_bucket.cpp
@@ -1,8 +1,7 @@
#include <mbgl/renderer/raster_bucket.hpp>
#include <mbgl/style/layers/raster_layer.hpp>
-#include <mbgl/shader/raster_shader.hpp>
+#include <mbgl/programs/raster_program.hpp>
#include <mbgl/renderer/painter.hpp>
-#include <mbgl/gl/gl.hpp>
#include <mbgl/gl/context.hpp>
namespace mbgl {
@@ -25,23 +24,8 @@ void RasterBucket::render(Painter& painter,
painter.renderRaster(parameters, *this, *layer.as<RasterLayer>(), tile);
}
-void RasterBucket::drawRaster(RasterShader& shader,
- 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, static_cast<GLsizei>(vertices.vertexCount)));
-}
-
bool RasterBucket::hasData() const {
return true;
}
-bool RasterBucket::needsClipping() const {
- return false;
-}
-
} // namespace mbgl
diff --git a/src/mbgl/renderer/raster_bucket.hpp b/src/mbgl/renderer/raster_bucket.hpp
index b0d3ca49c7..9648e954bd 100644
--- a/src/mbgl/renderer/raster_bucket.hpp
+++ b/src/mbgl/renderer/raster_bucket.hpp
@@ -7,15 +7,6 @@
namespace mbgl {
-class RasterShader;
-class RasterVertex;
-
-namespace gl {
-class Context;
-template <class> class VertexBuffer;
-class VertexArrayObject;
-} // namespace gl
-
class RasterBucket : public Bucket {
public:
RasterBucket(PremultipliedImage&&);
@@ -23,11 +14,7 @@ public:
void upload(gl::Context&) override;
void render(Painter&, PaintParameters&, const style::Layer&, const RenderTile&) override;
bool hasData() const override;
- bool needsClipping() const override;
-
- void drawRaster(RasterShader&, gl::VertexBuffer<RasterVertex>&, gl::VertexArrayObject&, gl::Context&);
-private:
PremultipliedImage image;
optional<gl::Texture> texture;
};
diff --git a/src/mbgl/renderer/render_tile.hpp b/src/mbgl/renderer/render_tile.hpp
index 74669faaf9..e2e0c3d656 100644
--- a/src/mbgl/renderer/render_tile.hpp
+++ b/src/mbgl/renderer/render_tile.hpp
@@ -24,6 +24,7 @@ public:
Tile& tile;
ClipID clip;
mat4 matrix;
+ bool used = false;
mat4 translatedMatrix(const std::array<float, 2>& translate,
style::TranslateAnchorType anchor,
diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp
index 565c58c7ed..0f2c89339f 100644
--- a/src/mbgl/renderer/symbol_bucket.cpp
+++ b/src/mbgl/renderer/symbol_bucket.cpp
@@ -1,17 +1,13 @@
#include <mbgl/renderer/symbol_bucket.hpp>
#include <mbgl/renderer/painter.hpp>
#include <mbgl/style/layers/symbol_layer.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>
namespace mbgl {
using namespace style;
SymbolBucket::SymbolBucket(const MapMode mode_,
- style::SymbolLayoutProperties layout_,
+ style::SymbolLayoutProperties::Evaluated layout_,
bool sdfIcons_,
bool iconsNeedLinear_)
: mode(mode_),
@@ -31,8 +27,9 @@ void SymbolBucket::upload(gl::Context& context) {
icon.indexBuffer = context.createIndexBuffer(std::move(icon.triangles));
}
- if (hasCollisionBoxData()) {
+ if (!collisionBox.vertices.empty()) {
collisionBox.vertexBuffer = context.createVertexBuffer(std::move(collisionBox.vertices));
+ collisionBox.indexBuffer = context.createIndexBuffer(std::move(collisionBox.lines));
}
uploaded = true;
@@ -46,79 +43,20 @@ void SymbolBucket::render(Painter& painter,
}
bool SymbolBucket::hasData() const {
- assert(false); // Should be calling SymbolLayout::hasSymbolInstances() instead.
+ assert(false); // Should be calling SymbolLayout::has{Text,Icon,CollisonBox}Data() instead.
return false;
}
bool SymbolBucket::hasTextData() const {
- return !text.groups.empty();
+ return !text.segments.empty();
}
bool SymbolBucket::hasIconData() const {
- return !icon.groups.empty();
+ return !icon.segments.empty();
}
bool SymbolBucket::hasCollisionBoxData() const {
- return !collisionBox.groups.empty();
-}
-
-bool SymbolBucket::needsClipping() const {
- return mode == MapMode::Still;
-}
-
-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) {
- 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.vertexLength * text.vertexBuffer->vertexSize;
- elements_index += group.indexLength * text.indexBuffer->primitiveSize;
- }
-}
-
-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) {
- 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.vertexLength * icon.vertexBuffer->vertexSize;
- elements_index += group.indexLength * icon.indexBuffer->primitiveSize;
- }
-}
-
-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) {
- 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.vertexLength * icon.vertexBuffer->vertexSize;
- elements_index += group.indexLength * icon.indexBuffer->primitiveSize;
- }
-}
-
-void SymbolBucket::drawCollisionBoxes(CollisionBoxShader& shader,
- gl::Context& context) {
- GLbyte* vertex_index = BUFFER_OFFSET_0;
- for (auto& group : collisionBox.groups) {
- group.getVAO(shader, PaintMode::Regular).bind(
- shader, *collisionBox.vertexBuffer, vertex_index, context);
- MBGL_CHECK_ERROR(glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(group.vertexLength)));
- }
+ return !collisionBox.segments.empty();
}
} // namespace mbgl
diff --git a/src/mbgl/renderer/symbol_bucket.hpp b/src/mbgl/renderer/symbol_bucket.hpp
index e5180c31e2..d62a61aab7 100644
--- a/src/mbgl/renderer/symbol_bucket.hpp
+++ b/src/mbgl/renderer/symbol_bucket.hpp
@@ -1,28 +1,23 @@
#pragma once
#include <mbgl/renderer/bucket.hpp>
-#include <mbgl/renderer/element_group.hpp>
#include <mbgl/map/mode.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/gl/segment.hpp>
+#include <mbgl/programs/symbol_program.hpp>
+#include <mbgl/programs/collision_box_program.hpp>
#include <mbgl/text/glyph_range.hpp>
#include <mbgl/style/layers/symbol_layer_properties.hpp>
-#include <memory>
#include <vector>
namespace mbgl {
-class SymbolSDFShader;
-class SymbolIconShader;
-class CollisionBoxShader;
-
class SymbolBucket : public Bucket {
public:
SymbolBucket(const MapMode,
- style::SymbolLayoutProperties,
+ style::SymbolLayoutProperties::Evaluated,
bool sdfIcons,
bool iconsNeedLinear);
@@ -32,46 +27,37 @@ public:
bool hasTextData() const;
bool hasIconData() const;
bool hasCollisionBoxData() const;
- bool needsClipping() const override;
-
- 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;
- const style::SymbolLayoutProperties layout;
+ const style::SymbolLayoutProperties::Evaluated layout;
const bool sdfIcons;
const bool iconsNeedLinear;
-private:
- friend class SymbolLayout;
-
struct TextBuffer {
- std::vector<SymbolVertex> vertices;
- std::vector<gl::Triangle> triangles;
- std::vector<ElementGroup<SymbolSDFShader>> groups;
+ gl::VertexVector<SymbolVertex> vertices;
+ gl::IndexVector<gl::Triangles> triangles;
+ gl::SegmentVector<SymbolAttributes> segments;
optional<gl::VertexBuffer<SymbolVertex>> vertexBuffer;
- optional<gl::IndexBuffer<gl::Triangle>> indexBuffer;
+ optional<gl::IndexBuffer<gl::Triangles>> indexBuffer;
} text;
struct IconBuffer {
- std::vector<SymbolVertex> vertices;
- std::vector<gl::Triangle> triangles;
- std::vector<ElementGroup<SymbolSDFShader, SymbolIconShader>> groups;
+ gl::VertexVector<SymbolVertex> vertices;
+ gl::IndexVector<gl::Triangles> triangles;
+ gl::SegmentVector<SymbolAttributes> segments;
optional<gl::VertexBuffer<SymbolVertex>> vertexBuffer;
- optional<gl::IndexBuffer<gl::Triangle>> indexBuffer;
+ optional<gl::IndexBuffer<gl::Triangles>> indexBuffer;
} icon;
struct CollisionBoxBuffer {
- std::vector<CollisionBoxVertex> vertices;
- std::vector<gl::Line> lines;
- std::vector<ElementGroup<CollisionBoxShader>> groups;
+ gl::VertexVector<CollisionBoxVertex> vertices;
+ gl::IndexVector<gl::Lines> lines;
+ gl::SegmentVector<CollisionBoxAttributes> segments;
optional<gl::VertexBuffer<CollisionBoxVertex>> vertexBuffer;
- optional<gl::IndexBuffer<gl::Line>> indexBuffer;
+ optional<gl::IndexBuffer<gl::Lines>> indexBuffer;
} collisionBox;
};
diff --git a/src/mbgl/shader/circle_shader.cpp b/src/mbgl/shader/circle_shader.cpp
deleted file mode 100644
index 9e294f8d76..0000000000
--- a/src/mbgl/shader/circle_shader.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#include <mbgl/shader/circle_shader.hpp>
-#include <mbgl/shader/circle.vertex.hpp>
-#include <mbgl/shader/circle.fragment.hpp>
-#include <mbgl/shader/circle_vertex.hpp>
-
-namespace mbgl {
-
-CircleShader::CircleShader(gl::Context& context, Defines defines)
- : Shader(shaders::circle::name,
- shaders::circle::vertex,
- shaders::circle::fragment,
- context, defines) {
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/circle_shader.hpp b/src/mbgl/shader/circle_shader.hpp
deleted file mode 100644
index c2c4053ba4..0000000000
--- a/src/mbgl/shader/circle_shader.hpp
+++ /dev/null
@@ -1,30 +0,0 @@
-#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 CircleVertex;
-
-class CircleShader : public gl::Shader {
-public:
- CircleShader(gl::Context&, Defines defines = None);
-
- using VertexType = CircleVertex;
-
- 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_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
deleted file mode 100644
index 8beb88e650..0000000000
--- a/src/mbgl/shader/circle_vertex.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-#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
deleted file mode 100644
index 4fce49f137..0000000000
--- a/src/mbgl/shader/circle_vertex.hpp
+++ /dev/null
@@ -1,39 +0,0 @@
-#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
deleted file mode 100644
index d61c849cd1..0000000000
--- a/src/mbgl/shader/collision_box_shader.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#include <mbgl/shader/collision_box_shader.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::collision_box::name,
- shaders::collision_box::vertex,
- shaders::collision_box::fragment,
- context) {
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/collision_box_shader.hpp b/src/mbgl/shader/collision_box_shader.hpp
deleted file mode 100644
index 2f5c506168..0000000000
--- a/src/mbgl/shader/collision_box_shader.hpp
+++ /dev/null
@@ -1,27 +0,0 @@
-#pragma once
-
-#include <mbgl/gl/shader.hpp>
-#include <mbgl/gl/attribute.hpp>
-#include <mbgl/gl/uniform.hpp>
-
-namespace mbgl {
-
-class CollisionBoxVertex;
-
-class CollisionBoxShader : public gl::Shader {
-public:
- CollisionBoxShader(gl::Context&);
-
- 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};
-
- 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
deleted file mode 100644
index 397fbfe6a3..0000000000
--- a/src/mbgl/shader/collision_box_vertex.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-#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
deleted file mode 100644
index ba72b1c0ee..0000000000
--- a/src/mbgl/shader/collision_box_vertex.hpp
+++ /dev/null
@@ -1,43 +0,0 @@
-#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
deleted file mode 100644
index b03921d384..0000000000
--- a/src/mbgl/shader/fill_outline_pattern_shader.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#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
deleted file mode 100644
index 630e6a7ce8..0000000000
--- a/src/mbgl/shader/fill_outline_pattern_shader.hpp
+++ /dev/null
@@ -1,37 +0,0 @@
-#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
deleted file mode 100644
index 6e6d8c2239..0000000000
--- a/src/mbgl/shader/fill_outline_shader.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#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
deleted file mode 100644
index c20bc187d3..0000000000
--- a/src/mbgl/shader/fill_outline_shader.hpp
+++ /dev/null
@@ -1,26 +0,0 @@
-#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
deleted file mode 100644
index 60be6d79ad..0000000000
--- a/src/mbgl/shader/fill_pattern_shader.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#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
deleted file mode 100644
index 36be538000..0000000000
--- a/src/mbgl/shader/fill_pattern_shader.hpp
+++ /dev/null
@@ -1,36 +0,0 @@
-#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
deleted file mode 100644
index 7026bb2f1c..0000000000
--- a/src/mbgl/shader/fill_shader.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#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
deleted file mode 100644
index 1240b73aa2..0000000000
--- a/src/mbgl/shader/fill_shader.hpp
+++ /dev/null
@@ -1,25 +0,0 @@
-#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
deleted file mode 100644
index c39a0b96b1..0000000000
--- a/src/mbgl/shader/fill_vertex.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-#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
deleted file mode 100644
index 1b8130382a..0000000000
--- a/src/mbgl/shader/fill_vertex.hpp
+++ /dev/null
@@ -1,30 +0,0 @@
-#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/line_pattern_shader.cpp b/src/mbgl/shader/line_pattern_shader.cpp
deleted file mode 100644
index e6bc32a5c9..0000000000
--- a/src/mbgl/shader/line_pattern_shader.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#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
deleted file mode 100644
index 1bd6085c8b..0000000000
--- a/src/mbgl/shader/line_pattern_shader.hpp
+++ /dev/null
@@ -1,41 +0,0 @@
-#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
deleted file mode 100644
index dd724365ea..0000000000
--- a/src/mbgl/shader/line_sdf_shader.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#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
deleted file mode 100644
index d74e42e50f..0000000000
--- a/src/mbgl/shader/line_sdf_shader.hpp
+++ /dev/null
@@ -1,42 +0,0 @@
-#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
deleted file mode 100644
index 4e934cd60c..0000000000
--- a/src/mbgl/shader/line_shader.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#include <mbgl/shader/line_shader.hpp>
-#include <mbgl/shader/line.vertex.hpp>
-#include <mbgl/shader/line.fragment.hpp>
-#include <mbgl/shader/line_vertex.hpp>
-
-namespace mbgl {
-
-LineShader::LineShader(gl::Context& context, Defines defines)
- : Shader(shaders::line::name,
- shaders::line::vertex,
- shaders::line::fragment,
- context, defines) {
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/line_shader.hpp b/src/mbgl/shader/line_shader.hpp
deleted file mode 100644
index 79991e1883..0000000000
--- a/src/mbgl/shader/line_shader.hpp
+++ /dev/null
@@ -1,35 +0,0 @@
-#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 LineShader : public gl::Shader {
-public:
- LineShader(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_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};
-};
-
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/line_vertex.cpp b/src/mbgl/shader/line_vertex.cpp
deleted file mode 100644
index ad466310d8..0000000000
--- a/src/mbgl/shader/line_vertex.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-#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
deleted file mode 100644
index 086100810e..0000000000
--- a/src/mbgl/shader/line_vertex.hpp
+++ /dev/null
@@ -1,72 +0,0 @@
-#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/raster_shader.cpp b/src/mbgl/shader/raster_shader.cpp
deleted file mode 100644
index 34b2bdf47b..0000000000
--- a/src/mbgl/shader/raster_shader.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#include <mbgl/shader/raster_shader.hpp>
-#include <mbgl/shader/raster.vertex.hpp>
-#include <mbgl/shader/raster.fragment.hpp>
-#include <mbgl/shader/raster_vertex.hpp>
-
-namespace mbgl {
-
-RasterShader::RasterShader(gl::Context& context, Defines defines)
- : Shader(shaders::raster::name,
- shaders::raster::vertex,
- shaders::raster::fragment,
- context, defines) {
-}
-
-} // namespace mbgl
diff --git a/src/mbgl/shader/raster_shader.hpp b/src/mbgl/shader/raster_shader.hpp
deleted file mode 100644
index 9633fd5fa0..0000000000
--- a/src/mbgl/shader/raster_shader.hpp
+++ /dev/null
@@ -1,35 +0,0 @@
-#pragma once
-
-#include <mbgl/gl/shader.hpp>
-#include <mbgl/gl/attribute.hpp>
-#include <mbgl/gl/uniform.hpp>
-
-namespace mbgl {
-
-class RasterVertex;
-
-class RasterShader : public gl::Shader {
-public:
- RasterShader(gl::Context&, Defines defines = None);
-
- 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
deleted file mode 100644
index fc9b1f11c2..0000000000
--- a/src/mbgl/shader/raster_vertex.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-#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
deleted file mode 100644
index 70e08c609d..0000000000
--- a/src/mbgl/shader/raster_vertex.hpp
+++ /dev/null
@@ -1,39 +0,0 @@
-#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/shaders.hpp b/src/mbgl/shader/shaders.hpp
deleted file mode 100644
index 937ee85f44..0000000000
--- a/src/mbgl/shader/shaders.hpp
+++ /dev/null
@@ -1,58 +0,0 @@
-#pragma once
-
-#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/line_sdf_shader.hpp>
-#include <mbgl/shader/line_pattern_shader.hpp>
-#include <mbgl/shader/raster_shader.hpp>
-#include <mbgl/shader/symbol_icon_shader.hpp>
-#include <mbgl/shader/symbol_sdf_shader.hpp>
-
-#include <mbgl/shader/collision_box_shader.hpp>
-
-namespace mbgl {
-
-class Shaders {
-public:
- 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),
- raster(context, defines),
- symbolIcon(context, defines),
- symbolIconSDF(context, defines),
- symbolGlyph(context, defines),
- collisionBox(context) {
- }
-
- CircleShader circle;
- FillShader fill;
- FillPatternShader fillPattern;
- FillOutlineShader fillOutline;
- FillOutlinePatternShader fillOutlinePattern;
- LineShader line;
- LineSDFShader lineSDF;
- LinePatternShader linePattern;
- RasterShader raster;
- SymbolIconShader symbolIcon;
- SymbolSDFShader symbolIconSDF;
- SymbolSDFShader symbolGlyph;
-
- CollisionBoxShader collisionBox;
-
- 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
deleted file mode 100644
index 2655a1c9b5..0000000000
--- a/src/mbgl/shader/symbol_icon_shader.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#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
deleted file mode 100644
index 5281beb60c..0000000000
--- a/src/mbgl/shader/symbol_icon_shader.hpp
+++ /dev/null
@@ -1,32 +0,0 @@
-#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
deleted file mode 100644
index 63c3bd5a4a..0000000000
--- a/src/mbgl/shader/symbol_sdf_shader.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#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
deleted file mode 100644
index 8d3b3df939..0000000000
--- a/src/mbgl/shader/symbol_sdf_shader.hpp
+++ /dev/null
@@ -1,40 +0,0 @@
-#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
deleted file mode 100644
index 4075d749ea..0000000000
--- a/src/mbgl/shader/symbol_vertex.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-#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
deleted file mode 100644
index 4eba86f946..0000000000
--- a/src/mbgl/shader/symbol_vertex.hpp
+++ /dev/null
@@ -1,54 +0,0 @@
-#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/sprite/sprite_atlas.cpp b/src/mbgl/sprite/sprite_atlas.cpp
index 198b0a6c57..ea055ce5ec 100644
--- a/src/mbgl/sprite/sprite_atlas.cpp
+++ b/src/mbgl/sprite/sprite_atlas.cpp
@@ -1,10 +1,9 @@
#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/sprite/sprite_atlas_observer.hpp>
#include <mbgl/sprite/sprite_parser.hpp>
-#include <mbgl/gl/gl.hpp>
#include <mbgl/gl/context.hpp>
-#include <mbgl/platform/log.hpp>
-#include <mbgl/platform/platform.hpp>
+#include <mbgl/util/logging.hpp>
+#include <mbgl/util/platform.hpp>
#include <mbgl/util/math.hpp>
#include <mbgl/util/std.hpp>
#include <mbgl/util/constants.hpp>
@@ -28,15 +27,12 @@ struct SpriteAtlas::Loader {
std::unique_ptr<AsyncRequest> spriteRequest;
};
-SpriteAtlas::SpriteAtlas(dimension width_, dimension height_, float pixelRatio_)
- : width(width_),
- height(height_),
- pixelWidth(std::ceil(width * pixelRatio_)),
- pixelHeight(std::ceil(height * pixelRatio_)),
+SpriteAtlas::SpriteAtlas(Size size_, float pixelRatio_)
+ : size(std::move(size_)),
pixelRatio(pixelRatio_),
observer(&nullObserver),
- bin(width_, height_),
- dirtyFlag(true) {
+ bin(size.width, size.height),
+ dirty(true) {
}
SpriteAtlas::~SpriteAtlas() = default;
@@ -128,7 +124,7 @@ void SpriteAtlas::_setSprite(const std::string& name,
auto it = sprites.find(name);
if (it != sprites.end()) {
// There is already a sprite with that name in our store.
- if ((it->second->image.width != sprite->image.width || it->second->image.height != sprite->image.height)) {
+ if (it->second->image.size != sprite->image.size) {
Log::Warning(Event::Sprite, "Can't change sprite dimensions for '%s'", name.c_str());
return;
}
@@ -162,10 +158,10 @@ std::shared_ptr<const SpriteImage> SpriteAtlas::getSprite(const std::string& nam
}
}
-Rect<SpriteAtlas::dimension> SpriteAtlas::allocateImage(const SpriteImage& spriteImage) {
+Rect<uint16_t> SpriteAtlas::allocateImage(const SpriteImage& spriteImage) {
- const uint16_t pixel_width = std::ceil(spriteImage.image.width / pixelRatio);
- const uint16_t pixel_height = std::ceil(spriteImage.image.height / pixelRatio);
+ const uint16_t pixel_width = std::ceil(spriteImage.image.size.width / pixelRatio);
+ const uint16_t pixel_height = std::ceil(spriteImage.image.size.height / pixelRatio);
// Increase to next number divisible by 4, but at least 1.
// This is so we can scale down the texture coordinates and pack them
@@ -175,7 +171,7 @@ Rect<SpriteAtlas::dimension> SpriteAtlas::allocateImage(const SpriteImage& sprit
// We have to allocate a new area in the bin, and store an empty image in it.
// Add a 1px border around every image.
- Rect<dimension> rect = bin.allocate(pack_width, pack_height);
+ Rect<uint16_t> rect = bin.allocate(pack_width, pack_height);
if (rect.w == 0) {
return rect;
}
@@ -197,7 +193,7 @@ optional<SpriteAtlasElement> SpriteAtlas::getImage(const std::string& name,
return {};
}
- Rect<dimension> rect = allocateImage(*sprite);
+ Rect<uint16_t> rect = allocateImage(*sprite);
if (rect.w == 0) {
if (debug::spriteWarnings) {
Log::Warning(Event::Sprite, "sprite atlas bitmap overflow");
@@ -230,8 +226,8 @@ optional<SpriteAtlasPosition> SpriteAtlas::getPosition(const std::string& name,
return SpriteAtlasPosition {
{{ float(spriteImage->getWidth()), spriteImage->getHeight() }},
- {{ float(rect.x + padding) / width, float(rect.y + padding) / height }},
- {{ float(rect.x + padding + w) / width, float(rect.y + padding + h) / height }}
+ {{ float(rect.x + padding) / size.width, float(rect.y + padding) / size.height }},
+ {{ float(rect.x + padding + w) / size.width, float(rect.y + padding + h) / size.height }}
};
}
@@ -264,28 +260,25 @@ void copyBitmap(const uint32_t *src, const uint32_t srcStride, const uint32_t sr
}
void SpriteAtlas::copy(const Holder& holder, const SpritePatternMode mode) {
- if (!data) {
- data = std::make_unique<uint32_t[]>(pixelWidth * pixelHeight);
- std::fill(data.get(), data.get() + pixelWidth * pixelHeight, 0);
+ if (!image.valid()) {
+ image = PremultipliedImage({ static_cast<uint32_t>(std::ceil(size.width * pixelRatio)),
+ static_cast<uint32_t>(std::ceil(size.height * pixelRatio)) });
+ std::fill(image.data.get(), image.data.get() + image.bytes(), 0);
}
- const uint32_t *srcData = reinterpret_cast<const uint32_t *>(holder.spriteImage->image.data.get());
+ const uint32_t* srcData =
+ reinterpret_cast<const uint32_t*>(holder.spriteImage->image.data.get());
if (!srcData) return;
- uint32_t *const dstData = data.get();
+ uint32_t* const dstData = reinterpret_cast<uint32_t*>(image.data.get());
const int padding = 1;
- copyBitmap(srcData, uint32_t(holder.spriteImage->image.width), 0, 0,
- dstData, pixelWidth, (holder.pos.x + padding) * pixelRatio, (holder.pos.y + padding) * pixelRatio, pixelWidth * pixelHeight,
- uint32_t(holder.spriteImage->image.width), uint32_t(holder.spriteImage->image.height), mode);
+ copyBitmap(srcData, holder.spriteImage->image.size.width, 0, 0, dstData, image.size.width,
+ (holder.pos.x + padding) * pixelRatio, (holder.pos.y + padding) * pixelRatio,
+ image.size.width * image.size.height, holder.spriteImage->image.size.width,
+ holder.spriteImage->image.size.height, mode);
- dirtyFlag = true;
-}
-
-void SpriteAtlas::upload(gl::Context& context, gl::TextureUnit unit) {
- if (dirtyFlag) {
- bind(false, context, unit);
- }
+ dirty = true;
}
void SpriteAtlas::updateDirty() {
@@ -316,77 +309,31 @@ void SpriteAtlas::updateDirty() {
dirtySprites.clear();
}
-void SpriteAtlas::bind(bool linear, gl::Context& context, gl::TextureUnit unit) {
- if (!data) {
- return; // Empty atlas
+void SpriteAtlas::upload(gl::Context& context, gl::TextureUnit unit) {
+ if (!texture) {
+ texture = context.createTexture(image, unit);
+ } else if (dirty) {
+ context.updateTexture(*texture, image, unit);
}
- if (!texture) {
- texture = context.createTexture();
- context.activeTexture = unit;
- context.texture[unit] = *texture;
#if not MBGL_USE_GLES2
- MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
+// if (dirty) {
+// platform::showColorDebugImage("Sprite Atlas",
+// reinterpret_cast<const char*>(image.data.get()), size.width,
+// size.height, image.size.width, image.size.height);
+// }
#endif // MBGL_USE_GLES2
- // We are using clamp to edge here since OpenGL ES doesn't allow GL_REPEAT on NPOT textures.
- // We use those when the pixelRatio isn't a power of two, e.g. on iPhone 6 Plus.
- MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
- MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
- fullUploadRequired = true;
- } else if (context.texture[unit] != *texture) {
- context.activeTexture = unit;
- context.texture[unit] = *texture;
- }
- GLuint filter_val = linear ? GL_LINEAR : GL_NEAREST;
- if (filter_val != filter) {
- context.activeTexture = unit;
- MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter_val));
- MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter_val));
- filter = filter_val;
- }
-
- if (dirtyFlag) {
- std::lock_guard<std::recursive_mutex> lock(mtx);
-
- context.activeTexture = unit;
- if (fullUploadRequired) {
- MBGL_CHECK_ERROR(glTexImage2D(
- GL_TEXTURE_2D, // GLenum target
- 0, // GLint level
- GL_RGBA, // GLint internalformat
- pixelWidth, // GLsizei width
- pixelHeight, // GLsizei height
- 0, // GLint border
- GL_RGBA, // GLenum format
- GL_UNSIGNED_BYTE, // GLenum type
- data.get() // const GLvoid * data
- ));
- fullUploadRequired = false;
- } else {
- MBGL_CHECK_ERROR(glTexSubImage2D(
- GL_TEXTURE_2D, // GLenum target
- 0, // GLint level
- 0, // GLint xoffset
- 0, // GLint yoffset
- pixelWidth, // GLsizei width
- pixelHeight, // GLsizei height
- GL_RGBA, // GLenum format
- GL_UNSIGNED_BYTE, // GLenum type
- data.get() // const GLvoid *pixels
- ));
- }
-
- dirtyFlag = false;
+ dirty = false;
+}
-#if not MBGL_USE_GLES2
- // platform::showColorDebugImage("Sprite Atlas", reinterpret_cast<const char*>(data.get()),
- // pixelWidth, pixelHeight, pixelWidth, pixelHeight);
-#endif // MBGL_USE_GLES2
- }
+void SpriteAtlas::bind(bool linear, gl::Context& context, gl::TextureUnit unit) {
+ upload(context, unit);
+ context.bindTexture(*texture, unit,
+ linear ? gl::TextureFilter::Linear : gl::TextureFilter::Nearest);
}
-SpriteAtlas::Holder::Holder(std::shared_ptr<const SpriteImage> spriteImage_, Rect<dimension> pos_)
+SpriteAtlas::Holder::Holder(std::shared_ptr<const SpriteImage> spriteImage_, Rect<uint16_t> pos_)
: spriteImage(std::move(spriteImage_)), pos(std::move(pos_)) {
}
diff --git a/src/mbgl/sprite/sprite_atlas.hpp b/src/mbgl/sprite/sprite_atlas.hpp
index 3a0aea2dad..c79aec135e 100644
--- a/src/mbgl/sprite/sprite_atlas.hpp
+++ b/src/mbgl/sprite/sprite_atlas.hpp
@@ -1,7 +1,7 @@
#pragma once
#include <mbgl/geometry/binpack.hpp>
-#include <mbgl/gl/object.hpp>
+#include <mbgl/gl/texture.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/optional.hpp>
#include <mbgl/sprite/sprite_image.hpp>
@@ -26,13 +26,15 @@ class Context;
class SpriteImage;
class SpritePosition;
-struct SpriteAtlasPosition {
+class SpriteAtlasPosition {
+public:
std::array<float, 2> size = {{ 0, 0 }};
std::array<float, 2> tl = {{ 0, 0 }};
std::array<float, 2> br = {{ 0, 0 }};
};
-struct SpriteAtlasElement {
+class SpriteAtlasElement {
+public:
Rect<uint16_t> pos;
std::shared_ptr<const SpriteImage> spriteImage;
float relativePixelRatio;
@@ -45,10 +47,9 @@ enum class SpritePatternMode : bool {
class SpriteAtlas : public util::noncopyable {
public:
- typedef uint16_t dimension;
using Sprites = std::map<std::string, std::shared_ptr<const SpriteImage>>;
- SpriteAtlas(dimension width, dimension height, float pixelRatio);
+ SpriteAtlas(Size, float pixelRatio);
~SpriteAtlas();
void load(const std::string& url, FileSource&);
@@ -91,21 +92,19 @@ public:
// the texture is only bound when the data is out of date (=dirty).
void upload(gl::Context&, gl::TextureUnit unit);
- dimension getWidth() const { return width; }
- dimension getHeight() const { return height; }
- dimension getTextureWidth() const { return pixelWidth; }
- dimension getTextureHeight() const { return pixelHeight; }
+ Size getSize() const { return size; }
float getPixelRatio() const { return pixelRatio; }
// Only for use in tests.
- const uint32_t* getData() const { return data.get(); }
+ const PremultipliedImage& getAtlasImage() const {
+ return image;
+ }
private:
void _setSprite(const std::string&, const std::shared_ptr<const SpriteImage>& = nullptr);
void emitSpriteLoadedIfComplete();
- const uint16_t width, height;
- const dimension pixelWidth, pixelHeight;
+ const Size size;
const float pixelRatio;
struct Loader;
@@ -125,26 +124,24 @@ private:
Sprites dirtySprites;
struct Holder : private util::noncopyable {
- Holder(std::shared_ptr<const SpriteImage>, Rect<dimension>);
+ Holder(std::shared_ptr<const SpriteImage>, Rect<uint16_t>);
Holder(Holder&&);
std::shared_ptr<const SpriteImage> spriteImage;
- const Rect<dimension> pos;
+ const Rect<uint16_t> pos;
};
using Key = std::pair<std::string, SpritePatternMode>;
- Rect<SpriteAtlas::dimension> allocateImage(const SpriteImage&);
+ Rect<uint16_t> allocateImage(const SpriteImage&);
void copy(const Holder& holder, SpritePatternMode mode);
std::recursive_mutex mtx;
- BinPack<dimension> bin;
+ BinPack<uint16_t> bin;
std::map<Key, Holder> images;
std::unordered_set<std::string> uninitialized;
- std::unique_ptr<uint32_t[]> data;
- std::atomic<bool> dirtyFlag;
- bool fullUploadRequired = true;
- mbgl::optional<gl::UniqueTexture> texture;
- uint32_t filter = 0;
+ PremultipliedImage image;
+ mbgl::optional<gl::Texture> texture;
+ std::atomic<bool> dirty;
static const int buffer = 1;
};
diff --git a/src/mbgl/sprite/sprite_image.cpp b/src/mbgl/sprite/sprite_image.cpp
index d7e422ed1d..1579d9d89e 100644
--- a/src/mbgl/sprite/sprite_image.cpp
+++ b/src/mbgl/sprite/sprite_image.cpp
@@ -13,7 +13,7 @@ SpriteImage::SpriteImage(PremultipliedImage&& image_,
pixelRatio(pixelRatio_),
sdf(sdf_) {
- if (image.size() == 0) {
+ if (!image.valid()) {
throw util::SpriteImageException("Sprite image dimensions may not be zero");
} else if (pixelRatio <= 0) {
throw util::SpriteImageException("Sprite pixelRatio may not be <= 0");
diff --git a/src/mbgl/sprite/sprite_parser.cpp b/src/mbgl/sprite/sprite_parser.cpp
index 34b1d875b6..9de8515e14 100644
--- a/src/mbgl/sprite/sprite_parser.cpp
+++ b/src/mbgl/sprite/sprite_parser.cpp
@@ -1,10 +1,11 @@
#include <mbgl/sprite/sprite_parser.hpp>
#include <mbgl/sprite/sprite_image.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
#include <mbgl/util/image.hpp>
#include <mbgl/util/rapidjson.hpp>
+#include <mbgl/util/string.hpp>
#include <cmath>
#include <limits>
@@ -13,30 +14,34 @@
namespace mbgl {
SpriteImagePtr createSpriteImage(const PremultipliedImage& image,
- const uint16_t srcX,
- const uint16_t srcY,
- const uint16_t width,
- const uint16_t height,
+ const uint32_t srcX,
+ const uint32_t srcY,
+ const uint32_t width,
+ const uint32_t height,
const double ratio,
const bool sdf) {
// Disallow invalid parameter configurations.
if (width <= 0 || height <= 0 || width > 1024 || height > 1024 ||
ratio <= 0 || ratio > 10 ||
- srcX + width > image.width || srcY + height > image.height) {
- Log::Error(Event::Sprite, "Can't create sprite with invalid metrics");
+ srcX >= image.size.width || srcY >= image.size.height ||
+ srcX + width > image.size.width || srcY + height > image.size.height) {
+ Log::Error(Event::Sprite, "Can't create sprite with invalid metrics: %ux%u@%u,%u in %ux%u@%sx sprite",
+ width, height, srcX, srcY,
+ image.size.width, image.size.height,
+ util::toString(ratio).c_str());
return nullptr;
}
- PremultipliedImage dstImage(width, height);
+ PremultipliedImage dstImage({ width, height });
auto srcData = reinterpret_cast<const uint32_t*>(image.data.get());
auto dstData = reinterpret_cast<uint32_t*>(dstImage.data.get());
// Copy from the source image into our individual sprite image
- for (uint16_t y = 0; y < height; ++y) {
+ for (uint32_t y = 0; y < height; ++y) {
const auto dstRow = y * width;
- const auto srcRow = (y + srcY) * image.width + srcX;
- for (uint16_t x = 0; x < width; ++x) {
+ const auto srcRow = (y + srcY) * image.size.width + srcX;
+ for (uint32_t x = 0; x < width; ++x) {
dstData[dstRow + x] = srcData[srcRow + x];
}
}
diff --git a/src/mbgl/sprite/sprite_parser.hpp b/src/mbgl/sprite/sprite_parser.hpp
index 6a564ce330..4a63d4858a 100644
--- a/src/mbgl/sprite/sprite_parser.hpp
+++ b/src/mbgl/sprite/sprite_parser.hpp
@@ -17,10 +17,10 @@ using SpriteImagePtr = std::shared_ptr<const SpriteImage>;
// Extracts an individual image from a spritesheet from the given location.
SpriteImagePtr createSpriteImage(const PremultipliedImage&,
- uint16_t srcX,
- uint16_t srcY,
- uint16_t srcWidth,
- uint16_t srcHeight,
+ uint32_t srcX,
+ uint32_t srcY,
+ uint32_t srcWidth,
+ uint32_t srcHeight,
double ratio,
bool sdf);
diff --git a/src/mbgl/style/class_dictionary.hpp b/src/mbgl/style/class_dictionary.hpp
index e609fb5303..37eb488240 100644
--- a/src/mbgl/style/class_dictionary.hpp
+++ b/src/mbgl/style/class_dictionary.hpp
@@ -9,7 +9,6 @@ namespace mbgl {
namespace style {
enum class ClassID : uint32_t {
- Fallback = 0, // These values are from the fallback properties
Default = 1, // These values are from the default style for a layer
Named = 2 // These values (and all subsequent IDs) are from a named style from the layer
};
diff --git a/src/mbgl/style/cross_faded_property_evaluator.cpp b/src/mbgl/style/cross_faded_property_evaluator.cpp
new file mode 100644
index 0000000000..4de939576e
--- /dev/null
+++ b/src/mbgl/style/cross_faded_property_evaluator.cpp
@@ -0,0 +1,53 @@
+#include <mbgl/style/cross_faded_property_evaluator.hpp>
+#include <mbgl/util/chrono.hpp>
+
+#include <cmath>
+
+namespace mbgl {
+namespace style {
+
+template <typename T>
+Faded<T> CrossFadedPropertyEvaluator<T>::operator()(const Undefined&) const {
+ return calculate(defaultValue, defaultValue, defaultValue);
+}
+
+template <typename T>
+Faded<T> CrossFadedPropertyEvaluator<T>::operator()(const T& constant) const {
+ return calculate(constant, constant, constant);
+}
+
+template <typename T>
+T getBiggestStopLessThan(const Function<T>& function, float z) {
+ const auto& stops = function.getStops();
+ for (uint32_t i = 0; i < stops.size(); i++) {
+ if (stops[i].first > z) {
+ return stops[i == 0 ? i : i - 1].second;
+ }
+ }
+ return stops.at(stops.size() - 1).second;
+}
+
+template <typename T>
+Faded<T> CrossFadedPropertyEvaluator<T>::operator()(const Function<T>& function) const {
+ return calculate(getBiggestStopLessThan(function, parameters.z - 1.0f),
+ getBiggestStopLessThan(function, parameters.z),
+ getBiggestStopLessThan(function, parameters.z + 1.0f));
+}
+
+template <typename T>
+Faded<T> CrossFadedPropertyEvaluator<T>::calculate(const T& min, const T& mid, const T& max) const {
+ const float z = parameters.z;
+ const float fraction = z - std::floor(z);
+ const std::chrono::duration<float> d = parameters.defaultFadeDuration;
+ const float t = std::min((parameters.now - parameters.zoomHistory.lastIntegerZoomTime) / d, 1.0f);
+
+ return z > parameters.zoomHistory.lastIntegerZoom
+ ? Faded<T> { min, mid, 2.0f, 1.0f, fraction + (1.0f - fraction) * t }
+ : Faded<T> { max, mid, 0.5f, 1.0f, 1 - (1 - t) * fraction };
+}
+
+template class CrossFadedPropertyEvaluator<std::string>;
+template class CrossFadedPropertyEvaluator<std::vector<float>>;
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/cross_faded_property_evaluator.hpp b/src/mbgl/style/cross_faded_property_evaluator.hpp
new file mode 100644
index 0000000000..70c8c0c978
--- /dev/null
+++ b/src/mbgl/style/cross_faded_property_evaluator.hpp
@@ -0,0 +1,48 @@
+#pragma once
+
+#include <mbgl/style/property_value.hpp>
+#include <mbgl/style/property_evaluation_parameters.hpp>
+#include <mbgl/util/interpolate.hpp>
+
+namespace mbgl {
+namespace style {
+
+template <typename T>
+class Faded {
+public:
+ T from;
+ T to;
+ float fromScale;
+ float toScale;
+ float t;
+};
+
+template <typename T>
+class CrossFadedPropertyEvaluator {
+public:
+ using ResultType = Faded<T>;
+
+ CrossFadedPropertyEvaluator(const PropertyEvaluationParameters& parameters_, T defaultValue_)
+ : parameters(parameters_),
+ defaultValue(std::move(defaultValue_)) {}
+
+ Faded<T> operator()(const Undefined&) const;
+ Faded<T> operator()(const T& constant) const;
+ Faded<T> operator()(const Function<T>&) const;
+
+private:
+ Faded<T> calculate(const T& min, const T& mid, const T& max) const;
+
+ const PropertyEvaluationParameters& parameters;
+ T defaultValue;
+};
+
+} // namespace style
+
+namespace util {
+template <typename T>
+struct Interpolator<style::Faded<T>>
+ : Uninterpolated {};
+} // namespace util
+
+} // namespace mbgl
diff --git a/src/mbgl/style/function.cpp b/src/mbgl/style/function.cpp
new file mode 100644
index 0000000000..02750c7d2e
--- /dev/null
+++ b/src/mbgl/style/function.cpp
@@ -0,0 +1,81 @@
+#include <mbgl/style/function.hpp>
+#include <mbgl/style/types.hpp>
+#include <mbgl/util/color.hpp>
+#include <mbgl/util/interpolate.hpp>
+
+#include <cmath>
+
+namespace mbgl {
+namespace style {
+
+template <typename T>
+T Function<T>::evaluate(float z) const {
+ bool smaller = false;
+ float smaller_z = 0.0f;
+ T smaller_val = T();
+ bool larger = false;
+ float larger_z = 0.0f;
+ T larger_val = T();
+
+ for (uint32_t i = 0; i < stops.size(); i++) {
+ float stop_z = stops[i].first;
+ T stop_val = stops[i].second;
+ if (stop_z <= z && (!smaller || smaller_z < stop_z)) {
+ smaller = true;
+ smaller_z = stop_z;
+ smaller_val = stop_val;
+ }
+ if (stop_z >= z && (!larger || larger_z > stop_z)) {
+ larger = true;
+ larger_z = stop_z;
+ larger_val = stop_val;
+ }
+ }
+
+ if (smaller && larger) {
+ if (larger_z == smaller_z || larger_val == smaller_val) {
+ return smaller_val;
+ }
+ const float zoomDiff = larger_z - smaller_z;
+ const float zoomProgress = z - smaller_z;
+ if (base == 1.0f) {
+ const float t = zoomProgress / zoomDiff;
+ return util::interpolate(smaller_val, larger_val, t);
+ } else {
+ const float t = (std::pow(base, zoomProgress) - 1) / (std::pow(base, zoomDiff) - 1);
+ return util::interpolate(smaller_val, larger_val, t);
+ }
+ } else if (larger) {
+ return larger_val;
+ } else if (smaller) {
+ return smaller_val;
+ } else {
+ // No stop defined.
+ assert(false);
+ return T();
+ }
+}
+
+template class Function<bool>;
+template class Function<float>;
+template class Function<Color>;
+template class Function<std::vector<float>>;
+template class Function<std::vector<std::string>>;
+template class Function<std::array<float, 2>>;
+template class Function<std::array<float, 4>>;
+
+template class Function<std::string>;
+template class Function<TranslateAnchorType>;
+template class Function<RotateAnchorType>;
+template class Function<CirclePitchScaleType>;
+template class Function<LineCapType>;
+template class Function<LineJoinType>;
+template class Function<SymbolPlacementType>;
+template class Function<TextAnchorType>;
+template class Function<TextJustifyType>;
+template class Function<TextTransformType>;
+template class Function<AlignmentType>;
+template class Function<IconTextFitType>;
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/layer_impl.hpp b/src/mbgl/style/layer_impl.hpp
index 4bf2956a6d..38ac32e1de 100644
--- a/src/mbgl/style/layer_impl.hpp
+++ b/src/mbgl/style/layer_impl.hpp
@@ -19,7 +19,7 @@ class Bucket;
namespace style {
class CascadeParameters;
-class CalculationParameters;
+class PropertyEvaluationParameters;
class BucketParameters;
/**
@@ -57,7 +57,7 @@ public:
// Fully evaluate cascaded paint properties based on a zoom level.
// Returns true if any paint properties have active transitions.
- virtual bool recalculate(const CalculationParameters&) = 0;
+ virtual bool evaluate(const PropertyEvaluationParameters&) = 0;
virtual std::unique_ptr<Bucket> createBucket(BucketParameters&) const = 0;
diff --git a/src/mbgl/style/layers/background_layer.cpp b/src/mbgl/style/layers/background_layer.cpp
index 5e5faf37e6..a54115d1a7 100644
--- a/src/mbgl/style/layers/background_layer.cpp
+++ b/src/mbgl/style/layers/background_layer.cpp
@@ -42,13 +42,13 @@ PropertyValue<Color> BackgroundLayer::getDefaultBackgroundColor() {
}
PropertyValue<Color> BackgroundLayer::getBackgroundColor(const optional<std::string>& klass) const {
- return impl->paint.backgroundColor.get(klass);
+ return impl->paint.get<BackgroundColor>(klass);
}
void BackgroundLayer::setBackgroundColor(PropertyValue<Color> value, const optional<std::string>& klass) {
if (value == getBackgroundColor(klass))
return;
- impl->paint.backgroundColor.set(value, klass);
+ impl->paint.set<BackgroundColor>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -57,13 +57,13 @@ PropertyValue<std::string> BackgroundLayer::getDefaultBackgroundPattern() {
}
PropertyValue<std::string> BackgroundLayer::getBackgroundPattern(const optional<std::string>& klass) const {
- return impl->paint.backgroundPattern.get(klass);
+ return impl->paint.get<BackgroundPattern>(klass);
}
void BackgroundLayer::setBackgroundPattern(PropertyValue<std::string> value, const optional<std::string>& klass) {
if (value == getBackgroundPattern(klass))
return;
- impl->paint.backgroundPattern.set(value, klass);
+ impl->paint.set<BackgroundPattern>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -72,13 +72,13 @@ PropertyValue<float> BackgroundLayer::getDefaultBackgroundOpacity() {
}
PropertyValue<float> BackgroundLayer::getBackgroundOpacity(const optional<std::string>& klass) const {
- return impl->paint.backgroundOpacity.get(klass);
+ return impl->paint.get<BackgroundOpacity>(klass);
}
void BackgroundLayer::setBackgroundOpacity(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getBackgroundOpacity(klass))
return;
- impl->paint.backgroundOpacity.set(value, klass);
+ impl->paint.set<BackgroundOpacity>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
diff --git a/src/mbgl/style/layers/background_layer_impl.cpp b/src/mbgl/style/layers/background_layer_impl.cpp
index ea389b828e..9a7db9416e 100644
--- a/src/mbgl/style/layers/background_layer_impl.cpp
+++ b/src/mbgl/style/layers/background_layer_impl.cpp
@@ -8,12 +8,12 @@ void BackgroundLayer::Impl::cascade(const CascadeParameters& parameters) {
paint.cascade(parameters);
}
-bool BackgroundLayer::Impl::recalculate(const CalculationParameters& parameters) {
- bool hasTransitions = paint.recalculate(parameters);
+bool BackgroundLayer::Impl::evaluate(const PropertyEvaluationParameters& parameters) {
+ paint.evaluate(parameters);
- passes = paint.backgroundOpacity > 0 ? RenderPass::Translucent : RenderPass::None;
+ passes = paint.evaluated.get<BackgroundOpacity>() > 0 ? RenderPass::Translucent : RenderPass::None;
- return hasTransitions;
+ return paint.hasTransition();
}
std::unique_ptr<Bucket> BackgroundLayer::Impl::createBucket(BucketParameters&) const {
diff --git a/src/mbgl/style/layers/background_layer_impl.hpp b/src/mbgl/style/layers/background_layer_impl.hpp
index abbb740f42..6ede1b7d97 100644
--- a/src/mbgl/style/layers/background_layer_impl.hpp
+++ b/src/mbgl/style/layers/background_layer_impl.hpp
@@ -13,7 +13,7 @@ public:
std::unique_ptr<Layer> cloneRef(const std::string& id) const override;
void cascade(const CascadeParameters&) override;
- bool recalculate(const CalculationParameters&) override;
+ bool evaluate(const PropertyEvaluationParameters&) override;
std::unique_ptr<Bucket> createBucket(BucketParameters&) const override;
diff --git a/src/mbgl/style/layers/background_layer_properties.cpp b/src/mbgl/style/layers/background_layer_properties.cpp
index 558093a255..ba3e638977 100644
--- a/src/mbgl/style/layers/background_layer_properties.cpp
+++ b/src/mbgl/style/layers/background_layer_properties.cpp
@@ -5,21 +5,5 @@
namespace mbgl {
namespace style {
-void BackgroundPaintProperties::cascade(const CascadeParameters& parameters) {
- backgroundColor.cascade(parameters);
- backgroundPattern.cascade(parameters);
- backgroundOpacity.cascade(parameters);
-}
-
-bool BackgroundPaintProperties::recalculate(const CalculationParameters& parameters) {
- bool hasTransitions = false;
-
- hasTransitions |= backgroundColor.calculate(parameters);
- hasTransitions |= backgroundPattern.calculate(parameters);
- hasTransitions |= backgroundOpacity.calculate(parameters);
-
- return hasTransitions;
-}
-
} // namespace style
} // namespace mbgl
diff --git a/src/mbgl/style/layers/background_layer_properties.hpp b/src/mbgl/style/layers/background_layer_properties.hpp
index 78a35a4f0c..792bf3de94 100644
--- a/src/mbgl/style/layers/background_layer_properties.hpp
+++ b/src/mbgl/style/layers/background_layer_properties.hpp
@@ -9,18 +9,23 @@
namespace mbgl {
namespace style {
-class CascadeParameters;
-class CalculationParameters;
+struct BackgroundColor : PaintProperty<Color> {
+ static Color defaultValue() { return Color::black(); }
+};
-class BackgroundPaintProperties {
-public:
- void cascade(const CascadeParameters&);
- bool recalculate(const CalculationParameters&);
+struct BackgroundPattern : CrossFadedPaintProperty<std::string> {
+ static std::string defaultValue() { return ""; }
+};
- PaintProperty<Color> backgroundColor { Color::black() };
- PaintProperty<std::string, CrossFadedPropertyEvaluator> backgroundPattern { "" };
- PaintProperty<float> backgroundOpacity { 1 };
+struct BackgroundOpacity : PaintProperty<float> {
+ static float defaultValue() { return 1; }
};
+class BackgroundPaintProperties : public PaintProperties<
+ BackgroundColor,
+ BackgroundPattern,
+ BackgroundOpacity
+> {};
+
} // namespace style
} // namespace mbgl
diff --git a/src/mbgl/style/layers/circle_layer.cpp b/src/mbgl/style/layers/circle_layer.cpp
index a2b8d316d6..e3a506e895 100644
--- a/src/mbgl/style/layers/circle_layer.cpp
+++ b/src/mbgl/style/layers/circle_layer.cpp
@@ -67,13 +67,13 @@ PropertyValue<float> CircleLayer::getDefaultCircleRadius() {
}
PropertyValue<float> CircleLayer::getCircleRadius(const optional<std::string>& klass) const {
- return impl->paint.circleRadius.get(klass);
+ return impl->paint.get<CircleRadius>(klass);
}
void CircleLayer::setCircleRadius(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getCircleRadius(klass))
return;
- impl->paint.circleRadius.set(value, klass);
+ impl->paint.set<CircleRadius>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -82,13 +82,13 @@ PropertyValue<Color> CircleLayer::getDefaultCircleColor() {
}
PropertyValue<Color> CircleLayer::getCircleColor(const optional<std::string>& klass) const {
- return impl->paint.circleColor.get(klass);
+ return impl->paint.get<CircleColor>(klass);
}
void CircleLayer::setCircleColor(PropertyValue<Color> value, const optional<std::string>& klass) {
if (value == getCircleColor(klass))
return;
- impl->paint.circleColor.set(value, klass);
+ impl->paint.set<CircleColor>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -97,13 +97,13 @@ PropertyValue<float> CircleLayer::getDefaultCircleBlur() {
}
PropertyValue<float> CircleLayer::getCircleBlur(const optional<std::string>& klass) const {
- return impl->paint.circleBlur.get(klass);
+ return impl->paint.get<CircleBlur>(klass);
}
void CircleLayer::setCircleBlur(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getCircleBlur(klass))
return;
- impl->paint.circleBlur.set(value, klass);
+ impl->paint.set<CircleBlur>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -112,13 +112,13 @@ PropertyValue<float> CircleLayer::getDefaultCircleOpacity() {
}
PropertyValue<float> CircleLayer::getCircleOpacity(const optional<std::string>& klass) const {
- return impl->paint.circleOpacity.get(klass);
+ return impl->paint.get<CircleOpacity>(klass);
}
void CircleLayer::setCircleOpacity(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getCircleOpacity(klass))
return;
- impl->paint.circleOpacity.set(value, klass);
+ impl->paint.set<CircleOpacity>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -127,13 +127,13 @@ PropertyValue<std::array<float, 2>> CircleLayer::getDefaultCircleTranslate() {
}
PropertyValue<std::array<float, 2>> CircleLayer::getCircleTranslate(const optional<std::string>& klass) const {
- return impl->paint.circleTranslate.get(klass);
+ return impl->paint.get<CircleTranslate>(klass);
}
void CircleLayer::setCircleTranslate(PropertyValue<std::array<float, 2>> value, const optional<std::string>& klass) {
if (value == getCircleTranslate(klass))
return;
- impl->paint.circleTranslate.set(value, klass);
+ impl->paint.set<CircleTranslate>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -142,13 +142,13 @@ PropertyValue<TranslateAnchorType> CircleLayer::getDefaultCircleTranslateAnchor(
}
PropertyValue<TranslateAnchorType> CircleLayer::getCircleTranslateAnchor(const optional<std::string>& klass) const {
- return impl->paint.circleTranslateAnchor.get(klass);
+ return impl->paint.get<CircleTranslateAnchor>(klass);
}
void CircleLayer::setCircleTranslateAnchor(PropertyValue<TranslateAnchorType> value, const optional<std::string>& klass) {
if (value == getCircleTranslateAnchor(klass))
return;
- impl->paint.circleTranslateAnchor.set(value, klass);
+ impl->paint.set<CircleTranslateAnchor>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -157,13 +157,58 @@ PropertyValue<CirclePitchScaleType> CircleLayer::getDefaultCirclePitchScale() {
}
PropertyValue<CirclePitchScaleType> CircleLayer::getCirclePitchScale(const optional<std::string>& klass) const {
- return impl->paint.circlePitchScale.get(klass);
+ return impl->paint.get<CirclePitchScale>(klass);
}
void CircleLayer::setCirclePitchScale(PropertyValue<CirclePitchScaleType> value, const optional<std::string>& klass) {
if (value == getCirclePitchScale(klass))
return;
- impl->paint.circlePitchScale.set(value, klass);
+ impl->paint.set<CirclePitchScale>(value, klass);
+ impl->observer->onLayerPaintPropertyChanged(*this);
+}
+
+PropertyValue<float> CircleLayer::getDefaultCircleStrokeWidth() {
+ return { 0 };
+}
+
+PropertyValue<float> CircleLayer::getCircleStrokeWidth(const optional<std::string>& klass) const {
+ return impl->paint.get<CircleStrokeWidth>(klass);
+}
+
+void CircleLayer::setCircleStrokeWidth(PropertyValue<float> value, const optional<std::string>& klass) {
+ if (value == getCircleStrokeWidth(klass))
+ return;
+ impl->paint.set<CircleStrokeWidth>(value, klass);
+ impl->observer->onLayerPaintPropertyChanged(*this);
+}
+
+PropertyValue<Color> CircleLayer::getDefaultCircleStrokeColor() {
+ return { Color::black() };
+}
+
+PropertyValue<Color> CircleLayer::getCircleStrokeColor(const optional<std::string>& klass) const {
+ return impl->paint.get<CircleStrokeColor>(klass);
+}
+
+void CircleLayer::setCircleStrokeColor(PropertyValue<Color> value, const optional<std::string>& klass) {
+ if (value == getCircleStrokeColor(klass))
+ return;
+ impl->paint.set<CircleStrokeColor>(value, klass);
+ impl->observer->onLayerPaintPropertyChanged(*this);
+}
+
+PropertyValue<float> CircleLayer::getDefaultCircleStrokeOpacity() {
+ return { 1 };
+}
+
+PropertyValue<float> CircleLayer::getCircleStrokeOpacity(const optional<std::string>& klass) const {
+ return impl->paint.get<CircleStrokeOpacity>(klass);
+}
+
+void CircleLayer::setCircleStrokeOpacity(PropertyValue<float> value, const optional<std::string>& klass) {
+ if (value == getCircleStrokeOpacity(klass))
+ return;
+ impl->paint.set<CircleStrokeOpacity>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
diff --git a/src/mbgl/style/layers/circle_layer_impl.cpp b/src/mbgl/style/layers/circle_layer_impl.cpp
index 33699b6665..6599126702 100644
--- a/src/mbgl/style/layers/circle_layer_impl.cpp
+++ b/src/mbgl/style/layers/circle_layer_impl.cpp
@@ -12,13 +12,13 @@ void CircleLayer::Impl::cascade(const CascadeParameters& parameters) {
paint.cascade(parameters);
}
-bool CircleLayer::Impl::recalculate(const CalculationParameters& parameters) {
- bool hasTransitions = paint.recalculate(parameters);
+bool CircleLayer::Impl::evaluate(const PropertyEvaluationParameters& parameters) {
+ paint.evaluate(parameters);
- passes = (paint.circleRadius > 0 && paint.circleColor.value.a > 0 && paint.circleOpacity > 0)
+ passes = (paint.evaluated.get<CircleRadius>() > 0 && paint.evaluated.get<CircleColor>().a > 0 && paint.evaluated.get<CircleOpacity>() > 0)
? RenderPass::Translucent : RenderPass::None;
- return hasTransitions;
+ return paint.hasTransition();
}
std::unique_ptr<Bucket> CircleLayer::Impl::createBucket(BucketParameters& parameters) const {
@@ -35,8 +35,8 @@ std::unique_ptr<Bucket> CircleLayer::Impl::createBucket(BucketParameters& parame
}
float CircleLayer::Impl::getQueryRadius() const {
- const std::array<float, 2>& translate = paint.circleTranslate;
- return paint.circleRadius + util::length(translate[0], translate[1]);
+ const std::array<float, 2>& translate = paint.evaluated.get<CircleTranslate>();
+ return paint.evaluated.get<CircleRadius>() + util::length(translate[0], translate[1]);
}
bool CircleLayer::Impl::queryIntersectsGeometry(
@@ -46,9 +46,9 @@ bool CircleLayer::Impl::queryIntersectsGeometry(
const float pixelsToTileUnits) const {
auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry(
- queryGeometry, paint.circleTranslate, paint.circleTranslateAnchor, bearing, pixelsToTileUnits);
+ queryGeometry, paint.evaluated.get<CircleTranslate>(), paint.evaluated.get<CircleTranslateAnchor>(), bearing, pixelsToTileUnits);
- auto circleRadius = paint.circleRadius * pixelsToTileUnits;
+ auto circleRadius = paint.evaluated.get<CircleRadius>() * pixelsToTileUnits;
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 14baaf84e4..df3b34cc1a 100644
--- a/src/mbgl/style/layers/circle_layer_impl.hpp
+++ b/src/mbgl/style/layers/circle_layer_impl.hpp
@@ -13,7 +13,7 @@ public:
std::unique_ptr<Layer> cloneRef(const std::string& id) const override;
void cascade(const CascadeParameters&) override;
- bool recalculate(const CalculationParameters&) override;
+ bool evaluate(const PropertyEvaluationParameters&) override;
std::unique_ptr<Bucket> createBucket(BucketParameters&) const override;
diff --git a/src/mbgl/style/layers/circle_layer_properties.cpp b/src/mbgl/style/layers/circle_layer_properties.cpp
index 7243cf87f4..af727fa36f 100644
--- a/src/mbgl/style/layers/circle_layer_properties.cpp
+++ b/src/mbgl/style/layers/circle_layer_properties.cpp
@@ -5,29 +5,5 @@
namespace mbgl {
namespace style {
-void CirclePaintProperties::cascade(const CascadeParameters& parameters) {
- circleRadius.cascade(parameters);
- circleColor.cascade(parameters);
- circleBlur.cascade(parameters);
- circleOpacity.cascade(parameters);
- circleTranslate.cascade(parameters);
- circleTranslateAnchor.cascade(parameters);
- circlePitchScale.cascade(parameters);
-}
-
-bool CirclePaintProperties::recalculate(const CalculationParameters& parameters) {
- bool hasTransitions = false;
-
- hasTransitions |= circleRadius.calculate(parameters);
- hasTransitions |= circleColor.calculate(parameters);
- hasTransitions |= circleBlur.calculate(parameters);
- hasTransitions |= circleOpacity.calculate(parameters);
- hasTransitions |= circleTranslate.calculate(parameters);
- hasTransitions |= circleTranslateAnchor.calculate(parameters);
- hasTransitions |= circlePitchScale.calculate(parameters);
-
- return hasTransitions;
-}
-
} // namespace style
} // namespace mbgl
diff --git a/src/mbgl/style/layers/circle_layer_properties.hpp b/src/mbgl/style/layers/circle_layer_properties.hpp
index 0166bc8be4..ea36b31949 100644
--- a/src/mbgl/style/layers/circle_layer_properties.hpp
+++ b/src/mbgl/style/layers/circle_layer_properties.hpp
@@ -9,22 +9,58 @@
namespace mbgl {
namespace style {
-class CascadeParameters;
-class CalculationParameters;
-
-class CirclePaintProperties {
-public:
- void cascade(const CascadeParameters&);
- bool recalculate(const CalculationParameters&);
-
- PaintProperty<float> circleRadius { 5 };
- PaintProperty<Color> circleColor { Color::black() };
- PaintProperty<float> circleBlur { 0 };
- PaintProperty<float> circleOpacity { 1 };
- PaintProperty<std::array<float, 2>> circleTranslate { {{ 0, 0 }} };
- PaintProperty<TranslateAnchorType> circleTranslateAnchor { TranslateAnchorType::Map };
- PaintProperty<CirclePitchScaleType> circlePitchScale { CirclePitchScaleType::Map };
+struct CircleRadius : PaintProperty<float> {
+ static float defaultValue() { return 5; }
};
+struct CircleColor : PaintProperty<Color> {
+ static Color defaultValue() { return Color::black(); }
+};
+
+struct CircleBlur : PaintProperty<float> {
+ static float defaultValue() { return 0; }
+};
+
+struct CircleOpacity : PaintProperty<float> {
+ static float defaultValue() { return 1; }
+};
+
+struct CircleTranslate : PaintProperty<std::array<float, 2>> {
+ static std::array<float, 2> defaultValue() { return {{ 0, 0 }}; }
+};
+
+struct CircleTranslateAnchor : PaintProperty<TranslateAnchorType> {
+ static TranslateAnchorType defaultValue() { return TranslateAnchorType::Map; }
+};
+
+struct CirclePitchScale : PaintProperty<CirclePitchScaleType> {
+ static CirclePitchScaleType defaultValue() { return CirclePitchScaleType::Map; }
+};
+
+struct CircleStrokeWidth : PaintProperty<float> {
+ static float defaultValue() { return 0; }
+};
+
+struct CircleStrokeColor : PaintProperty<Color> {
+ static Color defaultValue() { return Color::black(); }
+};
+
+struct CircleStrokeOpacity : PaintProperty<float> {
+ static float defaultValue() { return 1; }
+};
+
+class CirclePaintProperties : public PaintProperties<
+ CircleRadius,
+ CircleColor,
+ CircleBlur,
+ CircleOpacity,
+ CircleTranslate,
+ CircleTranslateAnchor,
+ CirclePitchScale,
+ CircleStrokeWidth,
+ CircleStrokeColor,
+ CircleStrokeOpacity
+> {};
+
} // namespace style
} // namespace mbgl
diff --git a/src/mbgl/style/layers/custom_layer_impl.cpp b/src/mbgl/style/layers/custom_layer_impl.cpp
index 8896d04ca1..50dcc0dda9 100644
--- a/src/mbgl/style/layers/custom_layer_impl.cpp
+++ b/src/mbgl/style/layers/custom_layer_impl.cpp
@@ -50,8 +50,8 @@ void CustomLayer::Impl::render(const TransformState& state) const {
CustomLayerRenderParameters parameters;
- parameters.width = state.getWidth();
- parameters.height = state.getHeight();
+ parameters.width = state.getSize().width;
+ parameters.height = state.getSize().height;
parameters.latitude = state.getLatLng().latitude;
parameters.longitude = state.getLatLng().longitude;
parameters.zoom = state.getZoom();
@@ -62,7 +62,7 @@ void CustomLayer::Impl::render(const TransformState& state) const {
renderFn(context, parameters);
}
-bool CustomLayer::Impl::recalculate(const CalculationParameters&) {
+bool CustomLayer::Impl::evaluate(const PropertyEvaluationParameters&) {
passes = RenderPass::Translucent;
return false;
}
diff --git a/src/mbgl/style/layers/custom_layer_impl.hpp b/src/mbgl/style/layers/custom_layer_impl.hpp
index b5b626ca5e..56e3f3146c 100644
--- a/src/mbgl/style/layers/custom_layer_impl.hpp
+++ b/src/mbgl/style/layers/custom_layer_impl.hpp
@@ -29,7 +29,7 @@ private:
std::unique_ptr<Layer> cloneRef(const std::string& id) const override;
void cascade(const CascadeParameters&) final {}
- bool recalculate(const CalculationParameters&) final;
+ bool evaluate(const PropertyEvaluationParameters&) final;
std::unique_ptr<Bucket> createBucket(BucketParameters&) const final;
diff --git a/src/mbgl/style/layers/fill_extrusion_layer.cpp b/src/mbgl/style/layers/fill_extrusion_layer.cpp
new file mode 100644
index 0000000000..64efb1dd6a
--- /dev/null
+++ b/src/mbgl/style/layers/fill_extrusion_layer.cpp
@@ -0,0 +1,171 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
+#include <mbgl/style/layers/fill_extrusion_layer.hpp>
+#include <mbgl/style/layers/fill_extrusion_layer_impl.hpp>
+
+namespace mbgl {
+namespace style {
+
+FillExtrusionLayer::FillExtrusionLayer(const std::string& layerID, const std::string& sourceID)
+ : Layer(Type::FillExtrusion, std::make_unique<Impl>())
+ , impl(static_cast<Impl*>(baseImpl.get())) {
+ impl->id = layerID;
+ impl->source = sourceID;
+}
+
+FillExtrusionLayer::FillExtrusionLayer(const Impl& other)
+ : Layer(Type::FillExtrusion, std::make_unique<Impl>(other))
+ , impl(static_cast<Impl*>(baseImpl.get())) {
+}
+
+FillExtrusionLayer::~FillExtrusionLayer() = default;
+
+std::unique_ptr<Layer> FillExtrusionLayer::Impl::clone() const {
+ return std::make_unique<FillExtrusionLayer>(*this);
+}
+
+std::unique_ptr<Layer> FillExtrusionLayer::Impl::cloneRef(const std::string& id_) const {
+ auto result = std::make_unique<FillExtrusionLayer>(*this);
+ result->impl->id = id_;
+ result->impl->ref = this->id;
+ result->impl->paint = FillExtrusionPaintProperties();
+ return std::move(result);
+}
+
+// Source
+
+const std::string& FillExtrusionLayer::getSourceID() const {
+ return impl->source;
+}
+
+void FillExtrusionLayer::setSourceLayer(const std::string& sourceLayer) {
+ impl->sourceLayer = sourceLayer;
+}
+
+const std::string& FillExtrusionLayer::getSourceLayer() const {
+ return impl->sourceLayer;
+}
+
+// Filter
+
+void FillExtrusionLayer::setFilter(const Filter& filter) {
+ impl->filter = filter;
+ impl->observer->onLayerFilterChanged(*this);
+}
+
+const Filter& FillExtrusionLayer::getFilter() const {
+ return impl->filter;
+}
+
+// Layout properties
+
+
+// Paint properties
+
+PropertyValue<float> FillExtrusionLayer::getDefaultFillExtrusionOpacity() {
+ return { 1 };
+}
+
+PropertyValue<float> FillExtrusionLayer::getFillExtrusionOpacity(const optional<std::string>& klass) const {
+ return impl->paint.get<FillExtrusionOpacity>(klass);
+}
+
+void FillExtrusionLayer::setFillExtrusionOpacity(PropertyValue<float> value, const optional<std::string>& klass) {
+ if (value == getFillExtrusionOpacity(klass))
+ return;
+ impl->paint.set<FillExtrusionOpacity>(value, klass);
+ impl->observer->onLayerPaintPropertyChanged(*this);
+}
+
+PropertyValue<Color> FillExtrusionLayer::getDefaultFillExtrusionColor() {
+ return { Color::black() };
+}
+
+PropertyValue<Color> FillExtrusionLayer::getFillExtrusionColor(const optional<std::string>& klass) const {
+ return impl->paint.get<FillExtrusionColor>(klass);
+}
+
+void FillExtrusionLayer::setFillExtrusionColor(PropertyValue<Color> value, const optional<std::string>& klass) {
+ if (value == getFillExtrusionColor(klass))
+ return;
+ impl->paint.set<FillExtrusionColor>(value, klass);
+ impl->observer->onLayerPaintPropertyChanged(*this);
+}
+
+PropertyValue<std::array<float, 2>> FillExtrusionLayer::getDefaultFillExtrusionTranslate() {
+ return { {{ 0, 0 }} };
+}
+
+PropertyValue<std::array<float, 2>> FillExtrusionLayer::getFillExtrusionTranslate(const optional<std::string>& klass) const {
+ return impl->paint.get<FillExtrusionTranslate>(klass);
+}
+
+void FillExtrusionLayer::setFillExtrusionTranslate(PropertyValue<std::array<float, 2>> value, const optional<std::string>& klass) {
+ if (value == getFillExtrusionTranslate(klass))
+ return;
+ impl->paint.set<FillExtrusionTranslate>(value, klass);
+ impl->observer->onLayerPaintPropertyChanged(*this);
+}
+
+PropertyValue<TranslateAnchorType> FillExtrusionLayer::getDefaultFillExtrusionTranslateAnchor() {
+ return { TranslateAnchorType::Map };
+}
+
+PropertyValue<TranslateAnchorType> FillExtrusionLayer::getFillExtrusionTranslateAnchor(const optional<std::string>& klass) const {
+ return impl->paint.get<FillExtrusionTranslateAnchor>(klass);
+}
+
+void FillExtrusionLayer::setFillExtrusionTranslateAnchor(PropertyValue<TranslateAnchorType> value, const optional<std::string>& klass) {
+ if (value == getFillExtrusionTranslateAnchor(klass))
+ return;
+ impl->paint.set<FillExtrusionTranslateAnchor>(value, klass);
+ impl->observer->onLayerPaintPropertyChanged(*this);
+}
+
+PropertyValue<std::string> FillExtrusionLayer::getDefaultFillExtrusionPattern() {
+ return { "" };
+}
+
+PropertyValue<std::string> FillExtrusionLayer::getFillExtrusionPattern(const optional<std::string>& klass) const {
+ return impl->paint.get<FillExtrusionPattern>(klass);
+}
+
+void FillExtrusionLayer::setFillExtrusionPattern(PropertyValue<std::string> value, const optional<std::string>& klass) {
+ if (value == getFillExtrusionPattern(klass))
+ return;
+ impl->paint.set<FillExtrusionPattern>(value, klass);
+ impl->observer->onLayerPaintPropertyChanged(*this);
+}
+
+PropertyValue<float> FillExtrusionLayer::getDefaultFillExtrusionHeight() {
+ return { 0 };
+}
+
+PropertyValue<float> FillExtrusionLayer::getFillExtrusionHeight(const optional<std::string>& klass) const {
+ return impl->paint.get<FillExtrusionHeight>(klass);
+}
+
+void FillExtrusionLayer::setFillExtrusionHeight(PropertyValue<float> value, const optional<std::string>& klass) {
+ if (value == getFillExtrusionHeight(klass))
+ return;
+ impl->paint.set<FillExtrusionHeight>(value, klass);
+ impl->observer->onLayerPaintPropertyChanged(*this);
+}
+
+PropertyValue<float> FillExtrusionLayer::getDefaultFillExtrusionBase() {
+ return { 0 };
+}
+
+PropertyValue<float> FillExtrusionLayer::getFillExtrusionBase(const optional<std::string>& klass) const {
+ return impl->paint.get<FillExtrusionBase>(klass);
+}
+
+void FillExtrusionLayer::setFillExtrusionBase(PropertyValue<float> value, const optional<std::string>& klass) {
+ if (value == getFillExtrusionBase(klass))
+ return;
+ impl->paint.set<FillExtrusionBase>(value, klass);
+ impl->observer->onLayerPaintPropertyChanged(*this);
+}
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/fill_extrusion_layer_impl.cpp b/src/mbgl/style/layers/fill_extrusion_layer_impl.cpp
new file mode 100644
index 0000000000..239f7754d0
--- /dev/null
+++ b/src/mbgl/style/layers/fill_extrusion_layer_impl.cpp
@@ -0,0 +1,19 @@
+#include <mbgl/style/layers/fill_extrusion_layer_impl.hpp>
+#include <mbgl/renderer/bucket.hpp>
+
+namespace mbgl {
+namespace style {
+
+void FillExtrusionLayer::Impl::cascade(const CascadeParameters&) {
+}
+
+bool FillExtrusionLayer::Impl::evaluate(const PropertyEvaluationParameters&) {
+ return false;
+}
+
+std::unique_ptr<Bucket> FillExtrusionLayer::Impl::createBucket(BucketParameters&) const {
+ return nullptr;
+}
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/fill_extrusion_layer_impl.hpp b/src/mbgl/style/layers/fill_extrusion_layer_impl.hpp
new file mode 100644
index 0000000000..79ae02dd5b
--- /dev/null
+++ b/src/mbgl/style/layers/fill_extrusion_layer_impl.hpp
@@ -0,0 +1,24 @@
+#pragma once
+
+#include <mbgl/style/layer_impl.hpp>
+#include <mbgl/style/layers/fill_extrusion_layer.hpp>
+#include <mbgl/style/layers/fill_extrusion_layer_properties.hpp>
+
+namespace mbgl {
+namespace style {
+
+class FillExtrusionLayer::Impl : public Layer::Impl {
+public:
+ std::unique_ptr<Layer> clone() const override;
+ std::unique_ptr<Layer> cloneRef(const std::string& id) const override;
+
+ void cascade(const CascadeParameters&) override;
+ bool evaluate(const PropertyEvaluationParameters&) override;
+
+ std::unique_ptr<Bucket> createBucket(BucketParameters&) const override;
+
+ FillExtrusionPaintProperties paint;
+};
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/fill_extrusion_layer_properties.cpp b/src/mbgl/style/layers/fill_extrusion_layer_properties.cpp
new file mode 100644
index 0000000000..59572bd3ab
--- /dev/null
+++ b/src/mbgl/style/layers/fill_extrusion_layer_properties.cpp
@@ -0,0 +1,9 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
+#include <mbgl/style/layers/fill_extrusion_layer_properties.hpp>
+
+namespace mbgl {
+namespace style {
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp b/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp
new file mode 100644
index 0000000000..a2d01199a5
--- /dev/null
+++ b/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp
@@ -0,0 +1,51 @@
+// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
+
+#pragma once
+
+#include <mbgl/style/types.hpp>
+#include <mbgl/style/layout_property.hpp>
+#include <mbgl/style/paint_property.hpp>
+
+namespace mbgl {
+namespace style {
+
+struct FillExtrusionOpacity : PaintProperty<float> {
+ static float defaultValue() { return 1; }
+};
+
+struct FillExtrusionColor : PaintProperty<Color> {
+ static Color defaultValue() { return Color::black(); }
+};
+
+struct FillExtrusionTranslate : PaintProperty<std::array<float, 2>> {
+ static std::array<float, 2> defaultValue() { return {{ 0, 0 }}; }
+};
+
+struct FillExtrusionTranslateAnchor : PaintProperty<TranslateAnchorType> {
+ static TranslateAnchorType defaultValue() { return TranslateAnchorType::Map; }
+};
+
+struct FillExtrusionPattern : CrossFadedPaintProperty<std::string> {
+ static std::string defaultValue() { return ""; }
+};
+
+struct FillExtrusionHeight : PaintProperty<float> {
+ static float defaultValue() { return 0; }
+};
+
+struct FillExtrusionBase : PaintProperty<float> {
+ static float defaultValue() { return 0; }
+};
+
+class FillExtrusionPaintProperties : public PaintProperties<
+ FillExtrusionOpacity,
+ FillExtrusionColor,
+ FillExtrusionTranslate,
+ FillExtrusionTranslateAnchor,
+ FillExtrusionPattern,
+ FillExtrusionHeight,
+ FillExtrusionBase
+> {};
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/layers/fill_layer.cpp b/src/mbgl/style/layers/fill_layer.cpp
index c61de81d1a..3bea9b56b0 100644
--- a/src/mbgl/style/layers/fill_layer.cpp
+++ b/src/mbgl/style/layers/fill_layer.cpp
@@ -67,13 +67,13 @@ PropertyValue<bool> FillLayer::getDefaultFillAntialias() {
}
PropertyValue<bool> FillLayer::getFillAntialias(const optional<std::string>& klass) const {
- return impl->paint.fillAntialias.get(klass);
+ return impl->paint.get<FillAntialias>(klass);
}
void FillLayer::setFillAntialias(PropertyValue<bool> value, const optional<std::string>& klass) {
if (value == getFillAntialias(klass))
return;
- impl->paint.fillAntialias.set(value, klass);
+ impl->paint.set<FillAntialias>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -82,13 +82,13 @@ PropertyValue<float> FillLayer::getDefaultFillOpacity() {
}
PropertyValue<float> FillLayer::getFillOpacity(const optional<std::string>& klass) const {
- return impl->paint.fillOpacity.get(klass);
+ return impl->paint.get<FillOpacity>(klass);
}
void FillLayer::setFillOpacity(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getFillOpacity(klass))
return;
- impl->paint.fillOpacity.set(value, klass);
+ impl->paint.set<FillOpacity>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -97,13 +97,13 @@ PropertyValue<Color> FillLayer::getDefaultFillColor() {
}
PropertyValue<Color> FillLayer::getFillColor(const optional<std::string>& klass) const {
- return impl->paint.fillColor.get(klass);
+ return impl->paint.get<FillColor>(klass);
}
void FillLayer::setFillColor(PropertyValue<Color> value, const optional<std::string>& klass) {
if (value == getFillColor(klass))
return;
- impl->paint.fillColor.set(value, klass);
+ impl->paint.set<FillColor>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -112,13 +112,13 @@ PropertyValue<Color> FillLayer::getDefaultFillOutlineColor() {
}
PropertyValue<Color> FillLayer::getFillOutlineColor(const optional<std::string>& klass) const {
- return impl->paint.fillOutlineColor.get(klass);
+ return impl->paint.get<FillOutlineColor>(klass);
}
void FillLayer::setFillOutlineColor(PropertyValue<Color> value, const optional<std::string>& klass) {
if (value == getFillOutlineColor(klass))
return;
- impl->paint.fillOutlineColor.set(value, klass);
+ impl->paint.set<FillOutlineColor>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -127,13 +127,13 @@ PropertyValue<std::array<float, 2>> FillLayer::getDefaultFillTranslate() {
}
PropertyValue<std::array<float, 2>> FillLayer::getFillTranslate(const optional<std::string>& klass) const {
- return impl->paint.fillTranslate.get(klass);
+ return impl->paint.get<FillTranslate>(klass);
}
void FillLayer::setFillTranslate(PropertyValue<std::array<float, 2>> value, const optional<std::string>& klass) {
if (value == getFillTranslate(klass))
return;
- impl->paint.fillTranslate.set(value, klass);
+ impl->paint.set<FillTranslate>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -142,13 +142,13 @@ PropertyValue<TranslateAnchorType> FillLayer::getDefaultFillTranslateAnchor() {
}
PropertyValue<TranslateAnchorType> FillLayer::getFillTranslateAnchor(const optional<std::string>& klass) const {
- return impl->paint.fillTranslateAnchor.get(klass);
+ return impl->paint.get<FillTranslateAnchor>(klass);
}
void FillLayer::setFillTranslateAnchor(PropertyValue<TranslateAnchorType> value, const optional<std::string>& klass) {
if (value == getFillTranslateAnchor(klass))
return;
- impl->paint.fillTranslateAnchor.set(value, klass);
+ impl->paint.set<FillTranslateAnchor>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -157,13 +157,13 @@ PropertyValue<std::string> FillLayer::getDefaultFillPattern() {
}
PropertyValue<std::string> FillLayer::getFillPattern(const optional<std::string>& klass) const {
- return impl->paint.fillPattern.get(klass);
+ return impl->paint.get<FillPattern>(klass);
}
void FillLayer::setFillPattern(PropertyValue<std::string> value, const optional<std::string>& klass) {
if (value == getFillPattern(klass))
return;
- impl->paint.fillPattern.set(value, klass);
+ impl->paint.set<FillPattern>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
diff --git a/src/mbgl/style/layers/fill_layer_impl.cpp b/src/mbgl/style/layers/fill_layer_impl.cpp
index fc439f1cd1..6a690ba447 100644
--- a/src/mbgl/style/layers/fill_layer_impl.cpp
+++ b/src/mbgl/style/layers/fill_layer_impl.cpp
@@ -12,22 +12,22 @@ void FillLayer::Impl::cascade(const CascadeParameters& parameters) {
paint.cascade(parameters);
}
-bool FillLayer::Impl::recalculate(const CalculationParameters& parameters) {
- bool hasTransitions = paint.recalculate(parameters);
+bool FillLayer::Impl::evaluate(const PropertyEvaluationParameters& parameters) {
+ paint.evaluate(parameters);
passes = RenderPass::None;
- if (paint.fillAntialias) {
+ if (paint.evaluated.get<FillAntialias>()) {
passes |= RenderPass::Translucent;
}
- if (!paint.fillPattern.value.from.empty() || (paint.fillColor.value.a * paint.fillOpacity) < 1.0f) {
+ if (!paint.evaluated.get<FillPattern>().from.empty() || (paint.evaluated.get<FillColor>().a * paint.evaluated.get<FillOpacity>()) < 1.0f) {
passes |= RenderPass::Translucent;
} else {
passes |= RenderPass::Opaque;
}
- return hasTransitions;
+ return paint.hasTransition();
}
std::unique_ptr<Bucket> FillLayer::Impl::createBucket(BucketParameters& parameters) const {
@@ -44,7 +44,7 @@ std::unique_ptr<Bucket> FillLayer::Impl::createBucket(BucketParameters& paramete
}
float FillLayer::Impl::getQueryRadius() const {
- const std::array<float, 2>& translate = paint.fillTranslate;
+ const std::array<float, 2>& translate = paint.evaluated.get<FillTranslate>();
return util::length(translate[0], translate[1]);
}
@@ -55,7 +55,7 @@ bool FillLayer::Impl::queryIntersectsGeometry(
const float pixelsToTileUnits) const {
auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry(
- queryGeometry, paint.fillTranslate, paint.fillTranslateAnchor, bearing, pixelsToTileUnits);
+ queryGeometry, paint.evaluated.get<FillTranslate>(), paint.evaluated.get<FillTranslateAnchor>(), bearing, pixelsToTileUnits);
return util::polygonIntersectsMultiPolygon(translatedQueryGeometry.value_or(queryGeometry), geometry);
}
diff --git a/src/mbgl/style/layers/fill_layer_impl.hpp b/src/mbgl/style/layers/fill_layer_impl.hpp
index 54cfb80c86..53276d744a 100644
--- a/src/mbgl/style/layers/fill_layer_impl.hpp
+++ b/src/mbgl/style/layers/fill_layer_impl.hpp
@@ -13,7 +13,7 @@ public:
std::unique_ptr<Layer> cloneRef(const std::string& id) const override;
void cascade(const CascadeParameters&) override;
- bool recalculate(const CalculationParameters&) override;
+ bool evaluate(const PropertyEvaluationParameters&) override;
std::unique_ptr<Bucket> createBucket(BucketParameters&) const override;
diff --git a/src/mbgl/style/layers/fill_layer_properties.cpp b/src/mbgl/style/layers/fill_layer_properties.cpp
index 9a55cbc145..b07a083950 100644
--- a/src/mbgl/style/layers/fill_layer_properties.cpp
+++ b/src/mbgl/style/layers/fill_layer_properties.cpp
@@ -5,29 +5,5 @@
namespace mbgl {
namespace style {
-void FillPaintProperties::cascade(const CascadeParameters& parameters) {
- fillAntialias.cascade(parameters);
- fillOpacity.cascade(parameters);
- fillColor.cascade(parameters);
- fillOutlineColor.cascade(parameters);
- fillTranslate.cascade(parameters);
- fillTranslateAnchor.cascade(parameters);
- fillPattern.cascade(parameters);
-}
-
-bool FillPaintProperties::recalculate(const CalculationParameters& parameters) {
- bool hasTransitions = false;
-
- hasTransitions |= fillAntialias.calculate(parameters);
- hasTransitions |= fillOpacity.calculate(parameters);
- hasTransitions |= fillColor.calculate(parameters);
- hasTransitions |= fillOutlineColor.calculate(parameters);
- hasTransitions |= fillTranslate.calculate(parameters);
- hasTransitions |= fillTranslateAnchor.calculate(parameters);
- hasTransitions |= fillPattern.calculate(parameters);
-
- return hasTransitions;
-}
-
} // namespace style
} // namespace mbgl
diff --git a/src/mbgl/style/layers/fill_layer_properties.hpp b/src/mbgl/style/layers/fill_layer_properties.hpp
index d12eb8d6f4..b2d926c31e 100644
--- a/src/mbgl/style/layers/fill_layer_properties.hpp
+++ b/src/mbgl/style/layers/fill_layer_properties.hpp
@@ -9,22 +9,43 @@
namespace mbgl {
namespace style {
-class CascadeParameters;
-class CalculationParameters;
-
-class FillPaintProperties {
-public:
- void cascade(const CascadeParameters&);
- bool recalculate(const CalculationParameters&);
-
- PaintProperty<bool> fillAntialias { true };
- PaintProperty<float> fillOpacity { 1 };
- PaintProperty<Color> fillColor { Color::black() };
- PaintProperty<Color> fillOutlineColor { {} };
- PaintProperty<std::array<float, 2>> fillTranslate { {{ 0, 0 }} };
- PaintProperty<TranslateAnchorType> fillTranslateAnchor { TranslateAnchorType::Map };
- PaintProperty<std::string, CrossFadedPropertyEvaluator> fillPattern { "" };
+struct FillAntialias : PaintProperty<bool> {
+ static bool defaultValue() { return true; }
};
+struct FillOpacity : PaintProperty<float> {
+ static float defaultValue() { return 1; }
+};
+
+struct FillColor : PaintProperty<Color> {
+ static Color defaultValue() { return Color::black(); }
+};
+
+struct FillOutlineColor : PaintProperty<Color> {
+ static Color defaultValue() { return {}; }
+};
+
+struct FillTranslate : PaintProperty<std::array<float, 2>> {
+ static std::array<float, 2> defaultValue() { return {{ 0, 0 }}; }
+};
+
+struct FillTranslateAnchor : PaintProperty<TranslateAnchorType> {
+ static TranslateAnchorType defaultValue() { return TranslateAnchorType::Map; }
+};
+
+struct FillPattern : CrossFadedPaintProperty<std::string> {
+ static std::string defaultValue() { return ""; }
+};
+
+class FillPaintProperties : public PaintProperties<
+ FillAntialias,
+ FillOpacity,
+ FillColor,
+ FillOutlineColor,
+ FillTranslate,
+ FillTranslateAnchor,
+ FillPattern
+> {};
+
} // namespace style
} // namespace mbgl
diff --git a/src/mbgl/style/layers/layer.cpp.ejs b/src/mbgl/style/layers/layer.cpp.ejs
index c2cbc56a09..5fe78519ec 100644
--- a/src/mbgl/style/layers/layer.cpp.ejs
+++ b/src/mbgl/style/layers/layer.cpp.ejs
@@ -5,8 +5,8 @@
-%>
// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
-#include <mbgl/style/layers/<%- type %>_layer.hpp>
-#include <mbgl/style/layers/<%- type %>_layer_impl.hpp>
+#include <mbgl/style/layers/<%- type.replace('-', '_') %>_layer.hpp>
+#include <mbgl/style/layers/<%- type.replace('-', '_') %>_layer_impl.hpp>
namespace mbgl {
namespace style {
@@ -78,17 +78,17 @@ const Filter& <%- camelize(type) %>Layer::getFilter() const {
<% for (const property of layoutProperties) { -%>
PropertyValue<<%- propertyType(property) %>> <%- camelize(type) %>Layer::getDefault<%- camelize(property.name) %>() {
- return { <%- defaultValue(property) %> };
+ return <%- camelize(property.name) %>::defaultValue();
}
PropertyValue<<%- propertyType(property) %>> <%- camelize(type) %>Layer::get<%- camelize(property.name) %>() const {
- return impl->layout.<%- camelizeWithLeadingLowercase(property.name) %>.get();
+ return impl->layout.unevaluated.get<<%- camelize(property.name) %>>();
}
void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>(PropertyValue<<%- propertyType(property) %>> value) {
if (value == get<%- camelize(property.name) %>())
return;
- impl->layout.<%- camelizeWithLeadingLowercase(property.name) %>.set(value);
+ impl->layout.unevaluated.get<<%- camelize(property.name) %>>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "<%- property.name %>");
}
<% } -%>
@@ -100,13 +100,13 @@ PropertyValue<<%- propertyType(property) %>> <%- camelize(type) %>Layer::getDefa
}
PropertyValue<<%- propertyType(property) %>> <%- camelize(type) %>Layer::get<%- camelize(property.name) %>(const optional<std::string>& klass) const {
- return impl->paint.<%- camelizeWithLeadingLowercase(property.name) %>.get(klass);
+ return impl->paint.get<<%- camelize(property.name) %>>(klass);
}
void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>(PropertyValue<<%- propertyType(property) %>> value, const optional<std::string>& klass) {
if (value == get<%- camelize(property.name) %>(klass))
return;
- impl->paint.<%- camelizeWithLeadingLowercase(property.name) %>.set(value, klass);
+ impl->paint.set<<%- camelize(property.name) %>>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
<% } -%>
diff --git a/src/mbgl/style/layers/layer_properties.cpp.ejs b/src/mbgl/style/layers/layer_properties.cpp.ejs
index b781a4a9d9..e5523e5439 100644
--- a/src/mbgl/style/layers/layer_properties.cpp.ejs
+++ b/src/mbgl/style/layers/layer_properties.cpp.ejs
@@ -5,34 +5,10 @@
-%>
// This file is generated. Edit scripts/generate-style-code.js, then run `make style-code`.
-#include <mbgl/style/layers/<%- type %>_layer_properties.hpp>
+#include <mbgl/style/layers/<%- type.replace('-', '_') %>_layer_properties.hpp>
namespace mbgl {
namespace style {
-<% if (layoutProperties.length) { -%>
-void <%- camelize(type) %>LayoutProperties::recalculate(const CalculationParameters& parameters) {
-<% for (const property of layoutProperties) { -%>
- <%- camelizeWithLeadingLowercase(property.name) %>.calculate(parameters);
-<% } -%>
-}
-
-<% } -%>
-void <%- camelize(type) %>PaintProperties::cascade(const CascadeParameters& parameters) {
-<% for (const property of paintProperties) { -%>
- <%- camelizeWithLeadingLowercase(property.name) %>.cascade(parameters);
-<% } -%>
-}
-
-bool <%- camelize(type) %>PaintProperties::recalculate(const CalculationParameters& parameters) {
- bool hasTransitions = false;
-
-<% for (const property of paintProperties) { -%>
- hasTransitions |= <%- camelizeWithLeadingLowercase(property.name) %>.calculate(parameters);
-<% } -%>
-
- return hasTransitions;
-}
-
} // namespace style
} // namespace mbgl
diff --git a/src/mbgl/style/layers/layer_properties.hpp.ejs b/src/mbgl/style/layers/layer_properties.hpp.ejs
index 0c91ecba8c..f490a636f9 100644
--- a/src/mbgl/style/layers/layer_properties.hpp.ejs
+++ b/src/mbgl/style/layers/layer_properties.hpp.ejs
@@ -14,33 +14,35 @@
namespace mbgl {
namespace style {
-class CascadeParameters;
-class CalculationParameters;
-
-<% if (layoutProperties.length) { -%>
-class <%- camelize(type) %>LayoutProperties {
-public:
- void recalculate(const CalculationParameters&);
-
<% for (const property of layoutProperties) { -%>
- LayoutProperty<<%- propertyType(property) %>> <%- camelizeWithLeadingLowercase(property.name) %> { <%- defaultValue(property) %> };
+struct <%- camelize(property.name) %> : LayoutProperty<<%- propertyType(property) %>> {
+ static <%- propertyType(property) %> defaultValue() { return <%- defaultValue(property) %>; }
+};
+
<% } -%>
+<% for (const property of paintProperties) { -%>
+struct <%- camelize(property.name) %> : <%
+if (/-pattern$/.test(property.name) || property.name === 'line-dasharray') {
+%>CrossFaded<% } -%>PaintProperty<<%- propertyType(property) %>> {
+ static <%- propertyType(property) %> defaultValue() { return <%- defaultValue(property) %>; }
};
<% } -%>
-class <%- camelize(type) %>PaintProperties {
-public:
- void cascade(const CascadeParameters&);
- bool recalculate(const CalculationParameters&);
+<% if (layoutProperties.length) { -%>
+class <%- camelize(type) %>LayoutProperties : public LayoutProperties<
+<% for (const property of layoutProperties.slice(0, -1)) { -%>
+ <%- camelize(property.name) %>,
+<% } -%>
+ <%- camelize(layoutProperties.slice(-1)[0].name) %>
+> {};
-<% for (const property of paintProperties) { -%>
-<% if (/-pattern$/.test(property.name) || property.name === 'line-dasharray') { -%>
- PaintProperty<<%- propertyType(property) %>, CrossFadedPropertyEvaluator> <%- camelizeWithLeadingLowercase(property.name) %> { <%- defaultValue(property) %> };
-<% } else { -%>
- PaintProperty<<%- propertyType(property) %>> <%- camelizeWithLeadingLowercase(property.name) %> { <%- defaultValue(property) %> };
<% } -%>
+class <%- camelize(type) %>PaintProperties : public PaintProperties<
+<% for (const property of paintProperties.slice(0, -1)) { -%>
+ <%- camelize(property.name) %>,
<% } -%>
-};
+ <%- camelize(paintProperties.slice(-1)[0].name) %>
+> {};
} // namespace style
} // namespace mbgl
diff --git a/src/mbgl/style/layers/line_layer.cpp b/src/mbgl/style/layers/line_layer.cpp
index 49ecf63c18..8c38ef5694 100644
--- a/src/mbgl/style/layers/line_layer.cpp
+++ b/src/mbgl/style/layers/line_layer.cpp
@@ -60,59 +60,59 @@ const Filter& LineLayer::getFilter() const {
// Layout properties
PropertyValue<LineCapType> LineLayer::getDefaultLineCap() {
- return { LineCapType::Butt };
+ return LineCap::defaultValue();
}
PropertyValue<LineCapType> LineLayer::getLineCap() const {
- return impl->layout.lineCap.get();
+ return impl->layout.unevaluated.get<LineCap>();
}
void LineLayer::setLineCap(PropertyValue<LineCapType> value) {
if (value == getLineCap())
return;
- impl->layout.lineCap.set(value);
+ impl->layout.unevaluated.get<LineCap>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "line-cap");
}
PropertyValue<LineJoinType> LineLayer::getDefaultLineJoin() {
- return { LineJoinType::Miter };
+ return LineJoin::defaultValue();
}
PropertyValue<LineJoinType> LineLayer::getLineJoin() const {
- return impl->layout.lineJoin.get();
+ return impl->layout.unevaluated.get<LineJoin>();
}
void LineLayer::setLineJoin(PropertyValue<LineJoinType> value) {
if (value == getLineJoin())
return;
- impl->layout.lineJoin.set(value);
+ impl->layout.unevaluated.get<LineJoin>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "line-join");
}
PropertyValue<float> LineLayer::getDefaultLineMiterLimit() {
- return { 2 };
+ return LineMiterLimit::defaultValue();
}
PropertyValue<float> LineLayer::getLineMiterLimit() const {
- return impl->layout.lineMiterLimit.get();
+ return impl->layout.unevaluated.get<LineMiterLimit>();
}
void LineLayer::setLineMiterLimit(PropertyValue<float> value) {
if (value == getLineMiterLimit())
return;
- impl->layout.lineMiterLimit.set(value);
+ impl->layout.unevaluated.get<LineMiterLimit>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "line-miter-limit");
}
PropertyValue<float> LineLayer::getDefaultLineRoundLimit() {
- return { 1 };
+ return LineRoundLimit::defaultValue();
}
PropertyValue<float> LineLayer::getLineRoundLimit() const {
- return impl->layout.lineRoundLimit.get();
+ return impl->layout.unevaluated.get<LineRoundLimit>();
}
void LineLayer::setLineRoundLimit(PropertyValue<float> value) {
if (value == getLineRoundLimit())
return;
- impl->layout.lineRoundLimit.set(value);
+ impl->layout.unevaluated.get<LineRoundLimit>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "line-round-limit");
}
@@ -123,13 +123,13 @@ PropertyValue<float> LineLayer::getDefaultLineOpacity() {
}
PropertyValue<float> LineLayer::getLineOpacity(const optional<std::string>& klass) const {
- return impl->paint.lineOpacity.get(klass);
+ return impl->paint.get<LineOpacity>(klass);
}
void LineLayer::setLineOpacity(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getLineOpacity(klass))
return;
- impl->paint.lineOpacity.set(value, klass);
+ impl->paint.set<LineOpacity>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -138,13 +138,13 @@ PropertyValue<Color> LineLayer::getDefaultLineColor() {
}
PropertyValue<Color> LineLayer::getLineColor(const optional<std::string>& klass) const {
- return impl->paint.lineColor.get(klass);
+ return impl->paint.get<LineColor>(klass);
}
void LineLayer::setLineColor(PropertyValue<Color> value, const optional<std::string>& klass) {
if (value == getLineColor(klass))
return;
- impl->paint.lineColor.set(value, klass);
+ impl->paint.set<LineColor>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -153,13 +153,13 @@ PropertyValue<std::array<float, 2>> LineLayer::getDefaultLineTranslate() {
}
PropertyValue<std::array<float, 2>> LineLayer::getLineTranslate(const optional<std::string>& klass) const {
- return impl->paint.lineTranslate.get(klass);
+ return impl->paint.get<LineTranslate>(klass);
}
void LineLayer::setLineTranslate(PropertyValue<std::array<float, 2>> value, const optional<std::string>& klass) {
if (value == getLineTranslate(klass))
return;
- impl->paint.lineTranslate.set(value, klass);
+ impl->paint.set<LineTranslate>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -168,13 +168,13 @@ PropertyValue<TranslateAnchorType> LineLayer::getDefaultLineTranslateAnchor() {
}
PropertyValue<TranslateAnchorType> LineLayer::getLineTranslateAnchor(const optional<std::string>& klass) const {
- return impl->paint.lineTranslateAnchor.get(klass);
+ return impl->paint.get<LineTranslateAnchor>(klass);
}
void LineLayer::setLineTranslateAnchor(PropertyValue<TranslateAnchorType> value, const optional<std::string>& klass) {
if (value == getLineTranslateAnchor(klass))
return;
- impl->paint.lineTranslateAnchor.set(value, klass);
+ impl->paint.set<LineTranslateAnchor>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -183,13 +183,13 @@ PropertyValue<float> LineLayer::getDefaultLineWidth() {
}
PropertyValue<float> LineLayer::getLineWidth(const optional<std::string>& klass) const {
- return impl->paint.lineWidth.get(klass);
+ return impl->paint.get<LineWidth>(klass);
}
void LineLayer::setLineWidth(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getLineWidth(klass))
return;
- impl->paint.lineWidth.set(value, klass);
+ impl->paint.set<LineWidth>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -198,13 +198,13 @@ PropertyValue<float> LineLayer::getDefaultLineGapWidth() {
}
PropertyValue<float> LineLayer::getLineGapWidth(const optional<std::string>& klass) const {
- return impl->paint.lineGapWidth.get(klass);
+ return impl->paint.get<LineGapWidth>(klass);
}
void LineLayer::setLineGapWidth(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getLineGapWidth(klass))
return;
- impl->paint.lineGapWidth.set(value, klass);
+ impl->paint.set<LineGapWidth>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -213,13 +213,13 @@ PropertyValue<float> LineLayer::getDefaultLineOffset() {
}
PropertyValue<float> LineLayer::getLineOffset(const optional<std::string>& klass) const {
- return impl->paint.lineOffset.get(klass);
+ return impl->paint.get<LineOffset>(klass);
}
void LineLayer::setLineOffset(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getLineOffset(klass))
return;
- impl->paint.lineOffset.set(value, klass);
+ impl->paint.set<LineOffset>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -228,13 +228,13 @@ PropertyValue<float> LineLayer::getDefaultLineBlur() {
}
PropertyValue<float> LineLayer::getLineBlur(const optional<std::string>& klass) const {
- return impl->paint.lineBlur.get(klass);
+ return impl->paint.get<LineBlur>(klass);
}
void LineLayer::setLineBlur(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getLineBlur(klass))
return;
- impl->paint.lineBlur.set(value, klass);
+ impl->paint.set<LineBlur>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -243,13 +243,13 @@ PropertyValue<std::vector<float>> LineLayer::getDefaultLineDasharray() {
}
PropertyValue<std::vector<float>> LineLayer::getLineDasharray(const optional<std::string>& klass) const {
- return impl->paint.lineDasharray.get(klass);
+ return impl->paint.get<LineDasharray>(klass);
}
void LineLayer::setLineDasharray(PropertyValue<std::vector<float>> value, const optional<std::string>& klass) {
if (value == getLineDasharray(klass))
return;
- impl->paint.lineDasharray.set(value, klass);
+ impl->paint.set<LineDasharray>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -258,13 +258,13 @@ PropertyValue<std::string> LineLayer::getDefaultLinePattern() {
}
PropertyValue<std::string> LineLayer::getLinePattern(const optional<std::string>& klass) const {
- return impl->paint.linePattern.get(klass);
+ return impl->paint.get<LinePattern>(klass);
}
void LineLayer::setLinePattern(PropertyValue<std::string> value, const optional<std::string>& klass) {
if (value == getLinePattern(klass))
return;
- impl->paint.linePattern.set(value, klass);
+ impl->paint.set<LinePattern>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
diff --git a/src/mbgl/style/layers/line_layer_impl.cpp b/src/mbgl/style/layers/line_layer_impl.cpp
index c116af5fc2..e6ec21a659 100644
--- a/src/mbgl/style/layers/line_layer_impl.cpp
+++ b/src/mbgl/style/layers/line_layer_impl.cpp
@@ -12,26 +12,24 @@ void LineLayer::Impl::cascade(const CascadeParameters& parameters) {
paint.cascade(parameters);
}
-bool LineLayer::Impl::recalculate(const CalculationParameters& parameters) {
+bool LineLayer::Impl::evaluate(const PropertyEvaluationParameters& parameters) {
// for scaling dasharrays
- CalculationParameters dashArrayParams = parameters;
+ PropertyEvaluationParameters dashArrayParams = parameters;
dashArrayParams.z = std::floor(dashArrayParams.z);
- paint.lineWidth.calculate(dashArrayParams);
- dashLineWidth = paint.lineWidth;
+ dashLineWidth = paint.evaluate<LineWidth>(dashArrayParams);
- bool hasTransitions = paint.recalculate(parameters);
+ paint.evaluate(parameters);
- passes = (paint.lineOpacity > 0 && paint.lineColor.value.a > 0 && paint.lineWidth > 0)
+ passes = (paint.evaluated.get<LineOpacity>() > 0 && paint.evaluated.get<LineColor>().a > 0 && paint.evaluated.get<LineWidth>() > 0)
? RenderPass::Translucent : RenderPass::None;
- return hasTransitions;
+ return paint.hasTransition();
}
std::unique_ptr<Bucket> LineLayer::Impl::createBucket(BucketParameters& parameters) const {
auto bucket = std::make_unique<LineBucket>(parameters.tileID.overscaleFactor());
- bucket->layout = layout;
- bucket->layout.recalculate(CalculationParameters(parameters.tileID.overscaledZ));
+ bucket->layout = layout.evaluate(PropertyEvaluationParameters(parameters.tileID.overscaledZ));
auto& name = bucketName();
parameters.eachFilteredFeature(filter, [&] (const auto& feature, std::size_t index, const std::string& layerName) {
@@ -44,10 +42,10 @@ std::unique_ptr<Bucket> LineLayer::Impl::createBucket(BucketParameters& paramete
}
float LineLayer::Impl::getLineWidth() const {
- if (paint.lineGapWidth > 0) {
- return paint.lineGapWidth + 2 * paint.lineWidth;
+ if (paint.evaluated.get<LineGapWidth>() > 0) {
+ return paint.evaluated.get<LineGapWidth>() + 2 * paint.evaluated.get<LineWidth>();
} else {
- return paint.lineWidth;
+ return paint.evaluated.get<LineWidth>();
}
}
@@ -82,8 +80,8 @@ optional<GeometryCollection> offsetLine(const GeometryCollection& rings, const d
}
float LineLayer::Impl::getQueryRadius() const {
- const std::array<float, 2>& translate = paint.lineTranslate;
- return getLineWidth() / 2.0 + std::abs(paint.lineOffset) + util::length(translate[0], translate[1]);
+ const std::array<float, 2>& translate = paint.evaluated.get<LineTranslate>();
+ return getLineWidth() / 2.0 + std::abs(paint.evaluated.get<LineOffset>()) + util::length(translate[0], translate[1]);
}
bool LineLayer::Impl::queryIntersectsGeometry(
@@ -95,8 +93,8 @@ bool LineLayer::Impl::queryIntersectsGeometry(
const float halfWidth = getLineWidth() / 2.0 * pixelsToTileUnits;
auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry(
- queryGeometry, paint.lineTranslate, paint.lineTranslateAnchor, bearing, pixelsToTileUnits);
- auto offsetGeometry = offsetLine(geometry, paint.lineOffset * pixelsToTileUnits);
+ queryGeometry, paint.evaluated.get<LineTranslate>(), paint.evaluated.get<LineTranslateAnchor>(), bearing, pixelsToTileUnits);
+ auto offsetGeometry = offsetLine(geometry, paint.evaluated.get<LineOffset>() * pixelsToTileUnits);
return util::polygonIntersectsBufferedMultiLine(
translatedQueryGeometry.value_or(queryGeometry),
diff --git a/src/mbgl/style/layers/line_layer_impl.hpp b/src/mbgl/style/layers/line_layer_impl.hpp
index c6b4be3bec..3387db07f0 100644
--- a/src/mbgl/style/layers/line_layer_impl.hpp
+++ b/src/mbgl/style/layers/line_layer_impl.hpp
@@ -13,7 +13,7 @@ public:
std::unique_ptr<Layer> cloneRef(const std::string& id) const override;
void cascade(const CascadeParameters&) override;
- bool recalculate(const CalculationParameters&) override;
+ bool evaluate(const PropertyEvaluationParameters&) override;
std::unique_ptr<Bucket> createBucket(BucketParameters&) const override;
diff --git a/src/mbgl/style/layers/line_layer_properties.cpp b/src/mbgl/style/layers/line_layer_properties.cpp
index 2d6092745e..174239bcc8 100644
--- a/src/mbgl/style/layers/line_layer_properties.cpp
+++ b/src/mbgl/style/layers/line_layer_properties.cpp
@@ -5,42 +5,5 @@
namespace mbgl {
namespace style {
-void LineLayoutProperties::recalculate(const CalculationParameters& parameters) {
- lineCap.calculate(parameters);
- lineJoin.calculate(parameters);
- lineMiterLimit.calculate(parameters);
- lineRoundLimit.calculate(parameters);
-}
-
-void LinePaintProperties::cascade(const CascadeParameters& parameters) {
- lineOpacity.cascade(parameters);
- lineColor.cascade(parameters);
- lineTranslate.cascade(parameters);
- lineTranslateAnchor.cascade(parameters);
- lineWidth.cascade(parameters);
- lineGapWidth.cascade(parameters);
- lineOffset.cascade(parameters);
- lineBlur.cascade(parameters);
- lineDasharray.cascade(parameters);
- linePattern.cascade(parameters);
-}
-
-bool LinePaintProperties::recalculate(const CalculationParameters& parameters) {
- bool hasTransitions = false;
-
- hasTransitions |= lineOpacity.calculate(parameters);
- hasTransitions |= lineColor.calculate(parameters);
- hasTransitions |= lineTranslate.calculate(parameters);
- hasTransitions |= lineTranslateAnchor.calculate(parameters);
- hasTransitions |= lineWidth.calculate(parameters);
- hasTransitions |= lineGapWidth.calculate(parameters);
- hasTransitions |= lineOffset.calculate(parameters);
- hasTransitions |= lineBlur.calculate(parameters);
- hasTransitions |= lineDasharray.calculate(parameters);
- hasTransitions |= linePattern.calculate(parameters);
-
- return hasTransitions;
-}
-
} // namespace style
} // namespace mbgl
diff --git a/src/mbgl/style/layers/line_layer_properties.hpp b/src/mbgl/style/layers/line_layer_properties.hpp
index b73e3f2ef2..07458cd634 100644
--- a/src/mbgl/style/layers/line_layer_properties.hpp
+++ b/src/mbgl/style/layers/line_layer_properties.hpp
@@ -9,35 +9,81 @@
namespace mbgl {
namespace style {
-class CascadeParameters;
-class CalculationParameters;
-
-class LineLayoutProperties {
-public:
- void recalculate(const CalculationParameters&);
-
- LayoutProperty<LineCapType> lineCap { LineCapType::Butt };
- LayoutProperty<LineJoinType> lineJoin { LineJoinType::Miter };
- LayoutProperty<float> lineMiterLimit { 2 };
- LayoutProperty<float> lineRoundLimit { 1 };
-};
-
-class LinePaintProperties {
-public:
- void cascade(const CascadeParameters&);
- bool recalculate(const CalculationParameters&);
-
- PaintProperty<float> lineOpacity { 1 };
- PaintProperty<Color> lineColor { Color::black() };
- PaintProperty<std::array<float, 2>> lineTranslate { {{ 0, 0 }} };
- PaintProperty<TranslateAnchorType> lineTranslateAnchor { TranslateAnchorType::Map };
- PaintProperty<float> lineWidth { 1 };
- PaintProperty<float> lineGapWidth { 0 };
- PaintProperty<float> lineOffset { 0 };
- PaintProperty<float> lineBlur { 0 };
- PaintProperty<std::vector<float>, CrossFadedPropertyEvaluator> lineDasharray { { } };
- PaintProperty<std::string, CrossFadedPropertyEvaluator> linePattern { "" };
+struct LineCap : LayoutProperty<LineCapType> {
+ static LineCapType defaultValue() { return LineCapType::Butt; }
};
+struct LineJoin : LayoutProperty<LineJoinType> {
+ static LineJoinType defaultValue() { return LineJoinType::Miter; }
+};
+
+struct LineMiterLimit : LayoutProperty<float> {
+ static float defaultValue() { return 2; }
+};
+
+struct LineRoundLimit : LayoutProperty<float> {
+ static float defaultValue() { return 1; }
+};
+
+struct LineOpacity : PaintProperty<float> {
+ static float defaultValue() { return 1; }
+};
+
+struct LineColor : PaintProperty<Color> {
+ static Color defaultValue() { return Color::black(); }
+};
+
+struct LineTranslate : PaintProperty<std::array<float, 2>> {
+ static std::array<float, 2> defaultValue() { return {{ 0, 0 }}; }
+};
+
+struct LineTranslateAnchor : PaintProperty<TranslateAnchorType> {
+ static TranslateAnchorType defaultValue() { return TranslateAnchorType::Map; }
+};
+
+struct LineWidth : PaintProperty<float> {
+ static float defaultValue() { return 1; }
+};
+
+struct LineGapWidth : PaintProperty<float> {
+ static float defaultValue() { return 0; }
+};
+
+struct LineOffset : PaintProperty<float> {
+ static float defaultValue() { return 0; }
+};
+
+struct LineBlur : PaintProperty<float> {
+ static float defaultValue() { return 0; }
+};
+
+struct LineDasharray : CrossFadedPaintProperty<std::vector<float>> {
+ static std::vector<float> defaultValue() { return { }; }
+};
+
+struct LinePattern : CrossFadedPaintProperty<std::string> {
+ static std::string defaultValue() { return ""; }
+};
+
+class LineLayoutProperties : public LayoutProperties<
+ LineCap,
+ LineJoin,
+ LineMiterLimit,
+ LineRoundLimit
+> {};
+
+class LinePaintProperties : public PaintProperties<
+ LineOpacity,
+ LineColor,
+ LineTranslate,
+ LineTranslateAnchor,
+ LineWidth,
+ LineGapWidth,
+ LineOffset,
+ LineBlur,
+ LineDasharray,
+ LinePattern
+> {};
+
} // namespace style
} // namespace mbgl
diff --git a/src/mbgl/style/layers/raster_layer.cpp b/src/mbgl/style/layers/raster_layer.cpp
index 238bfef6e4..21d72a0fdc 100644
--- a/src/mbgl/style/layers/raster_layer.cpp
+++ b/src/mbgl/style/layers/raster_layer.cpp
@@ -49,13 +49,13 @@ PropertyValue<float> RasterLayer::getDefaultRasterOpacity() {
}
PropertyValue<float> RasterLayer::getRasterOpacity(const optional<std::string>& klass) const {
- return impl->paint.rasterOpacity.get(klass);
+ return impl->paint.get<RasterOpacity>(klass);
}
void RasterLayer::setRasterOpacity(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getRasterOpacity(klass))
return;
- impl->paint.rasterOpacity.set(value, klass);
+ impl->paint.set<RasterOpacity>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -64,13 +64,13 @@ PropertyValue<float> RasterLayer::getDefaultRasterHueRotate() {
}
PropertyValue<float> RasterLayer::getRasterHueRotate(const optional<std::string>& klass) const {
- return impl->paint.rasterHueRotate.get(klass);
+ return impl->paint.get<RasterHueRotate>(klass);
}
void RasterLayer::setRasterHueRotate(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getRasterHueRotate(klass))
return;
- impl->paint.rasterHueRotate.set(value, klass);
+ impl->paint.set<RasterHueRotate>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -79,13 +79,13 @@ PropertyValue<float> RasterLayer::getDefaultRasterBrightnessMin() {
}
PropertyValue<float> RasterLayer::getRasterBrightnessMin(const optional<std::string>& klass) const {
- return impl->paint.rasterBrightnessMin.get(klass);
+ return impl->paint.get<RasterBrightnessMin>(klass);
}
void RasterLayer::setRasterBrightnessMin(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getRasterBrightnessMin(klass))
return;
- impl->paint.rasterBrightnessMin.set(value, klass);
+ impl->paint.set<RasterBrightnessMin>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -94,13 +94,13 @@ PropertyValue<float> RasterLayer::getDefaultRasterBrightnessMax() {
}
PropertyValue<float> RasterLayer::getRasterBrightnessMax(const optional<std::string>& klass) const {
- return impl->paint.rasterBrightnessMax.get(klass);
+ return impl->paint.get<RasterBrightnessMax>(klass);
}
void RasterLayer::setRasterBrightnessMax(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getRasterBrightnessMax(klass))
return;
- impl->paint.rasterBrightnessMax.set(value, klass);
+ impl->paint.set<RasterBrightnessMax>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -109,13 +109,13 @@ PropertyValue<float> RasterLayer::getDefaultRasterSaturation() {
}
PropertyValue<float> RasterLayer::getRasterSaturation(const optional<std::string>& klass) const {
- return impl->paint.rasterSaturation.get(klass);
+ return impl->paint.get<RasterSaturation>(klass);
}
void RasterLayer::setRasterSaturation(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getRasterSaturation(klass))
return;
- impl->paint.rasterSaturation.set(value, klass);
+ impl->paint.set<RasterSaturation>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -124,13 +124,13 @@ PropertyValue<float> RasterLayer::getDefaultRasterContrast() {
}
PropertyValue<float> RasterLayer::getRasterContrast(const optional<std::string>& klass) const {
- return impl->paint.rasterContrast.get(klass);
+ return impl->paint.get<RasterContrast>(klass);
}
void RasterLayer::setRasterContrast(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getRasterContrast(klass))
return;
- impl->paint.rasterContrast.set(value, klass);
+ impl->paint.set<RasterContrast>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -139,13 +139,13 @@ PropertyValue<float> RasterLayer::getDefaultRasterFadeDuration() {
}
PropertyValue<float> RasterLayer::getRasterFadeDuration(const optional<std::string>& klass) const {
- return impl->paint.rasterFadeDuration.get(klass);
+ return impl->paint.get<RasterFadeDuration>(klass);
}
void RasterLayer::setRasterFadeDuration(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getRasterFadeDuration(klass))
return;
- impl->paint.rasterFadeDuration.set(value, klass);
+ impl->paint.set<RasterFadeDuration>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
diff --git a/src/mbgl/style/layers/raster_layer_impl.cpp b/src/mbgl/style/layers/raster_layer_impl.cpp
index 879bfa4559..3be4bb4fbd 100644
--- a/src/mbgl/style/layers/raster_layer_impl.cpp
+++ b/src/mbgl/style/layers/raster_layer_impl.cpp
@@ -8,12 +8,12 @@ void RasterLayer::Impl::cascade(const CascadeParameters& parameters) {
paint.cascade(parameters);
}
-bool RasterLayer::Impl::recalculate(const CalculationParameters& parameters) {
- bool hasTransitions = paint.recalculate(parameters);
+bool RasterLayer::Impl::evaluate(const PropertyEvaluationParameters& parameters) {
+ paint.evaluate(parameters);
- passes = paint.rasterOpacity > 0 ? RenderPass::Translucent : RenderPass::None;
+ passes = paint.evaluated.get<RasterOpacity>() > 0 ? RenderPass::Translucent : RenderPass::None;
- return hasTransitions;
+ return paint.hasTransition();
}
std::unique_ptr<Bucket> RasterLayer::Impl::createBucket(BucketParameters&) const {
diff --git a/src/mbgl/style/layers/raster_layer_impl.hpp b/src/mbgl/style/layers/raster_layer_impl.hpp
index a5b396e2ed..df5d388bdf 100644
--- a/src/mbgl/style/layers/raster_layer_impl.hpp
+++ b/src/mbgl/style/layers/raster_layer_impl.hpp
@@ -13,7 +13,7 @@ public:
std::unique_ptr<Layer> cloneRef(const std::string& id) const override;
void cascade(const CascadeParameters&) override;
- bool recalculate(const CalculationParameters&) override;
+ bool evaluate(const PropertyEvaluationParameters&) override;
std::unique_ptr<Bucket> createBucket(BucketParameters&) const override;
diff --git a/src/mbgl/style/layers/raster_layer_properties.cpp b/src/mbgl/style/layers/raster_layer_properties.cpp
index 68d9d1d35d..303719af40 100644
--- a/src/mbgl/style/layers/raster_layer_properties.cpp
+++ b/src/mbgl/style/layers/raster_layer_properties.cpp
@@ -5,29 +5,5 @@
namespace mbgl {
namespace style {
-void RasterPaintProperties::cascade(const CascadeParameters& parameters) {
- rasterOpacity.cascade(parameters);
- rasterHueRotate.cascade(parameters);
- rasterBrightnessMin.cascade(parameters);
- rasterBrightnessMax.cascade(parameters);
- rasterSaturation.cascade(parameters);
- rasterContrast.cascade(parameters);
- rasterFadeDuration.cascade(parameters);
-}
-
-bool RasterPaintProperties::recalculate(const CalculationParameters& parameters) {
- bool hasTransitions = false;
-
- hasTransitions |= rasterOpacity.calculate(parameters);
- hasTransitions |= rasterHueRotate.calculate(parameters);
- hasTransitions |= rasterBrightnessMin.calculate(parameters);
- hasTransitions |= rasterBrightnessMax.calculate(parameters);
- hasTransitions |= rasterSaturation.calculate(parameters);
- hasTransitions |= rasterContrast.calculate(parameters);
- hasTransitions |= rasterFadeDuration.calculate(parameters);
-
- return hasTransitions;
-}
-
} // namespace style
} // namespace mbgl
diff --git a/src/mbgl/style/layers/raster_layer_properties.hpp b/src/mbgl/style/layers/raster_layer_properties.hpp
index ddfb833e12..caa6d0c58d 100644
--- a/src/mbgl/style/layers/raster_layer_properties.hpp
+++ b/src/mbgl/style/layers/raster_layer_properties.hpp
@@ -9,22 +9,43 @@
namespace mbgl {
namespace style {
-class CascadeParameters;
-class CalculationParameters;
-
-class RasterPaintProperties {
-public:
- void cascade(const CascadeParameters&);
- bool recalculate(const CalculationParameters&);
-
- PaintProperty<float> rasterOpacity { 1 };
- PaintProperty<float> rasterHueRotate { 0 };
- PaintProperty<float> rasterBrightnessMin { 0 };
- PaintProperty<float> rasterBrightnessMax { 1 };
- PaintProperty<float> rasterSaturation { 0 };
- PaintProperty<float> rasterContrast { 0 };
- PaintProperty<float> rasterFadeDuration { 300 };
+struct RasterOpacity : PaintProperty<float> {
+ static float defaultValue() { return 1; }
};
+struct RasterHueRotate : PaintProperty<float> {
+ static float defaultValue() { return 0; }
+};
+
+struct RasterBrightnessMin : PaintProperty<float> {
+ static float defaultValue() { return 0; }
+};
+
+struct RasterBrightnessMax : PaintProperty<float> {
+ static float defaultValue() { return 1; }
+};
+
+struct RasterSaturation : PaintProperty<float> {
+ static float defaultValue() { return 0; }
+};
+
+struct RasterContrast : PaintProperty<float> {
+ static float defaultValue() { return 0; }
+};
+
+struct RasterFadeDuration : PaintProperty<float> {
+ static float defaultValue() { return 300; }
+};
+
+class RasterPaintProperties : public PaintProperties<
+ RasterOpacity,
+ RasterHueRotate,
+ RasterBrightnessMin,
+ RasterBrightnessMax,
+ RasterSaturation,
+ RasterContrast,
+ RasterFadeDuration
+> {};
+
} // namespace style
} // namespace mbgl
diff --git a/src/mbgl/style/layers/symbol_layer.cpp b/src/mbgl/style/layers/symbol_layer.cpp
index d49e8d7fe3..61f360ff64 100644
--- a/src/mbgl/style/layers/symbol_layer.cpp
+++ b/src/mbgl/style/layers/symbol_layer.cpp
@@ -60,479 +60,479 @@ const Filter& SymbolLayer::getFilter() const {
// Layout properties
PropertyValue<SymbolPlacementType> SymbolLayer::getDefaultSymbolPlacement() {
- return { SymbolPlacementType::Point };
+ return SymbolPlacement::defaultValue();
}
PropertyValue<SymbolPlacementType> SymbolLayer::getSymbolPlacement() const {
- return impl->layout.symbolPlacement.get();
+ return impl->layout.unevaluated.get<SymbolPlacement>();
}
void SymbolLayer::setSymbolPlacement(PropertyValue<SymbolPlacementType> value) {
if (value == getSymbolPlacement())
return;
- impl->layout.symbolPlacement.set(value);
+ impl->layout.unevaluated.get<SymbolPlacement>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "symbol-placement");
}
PropertyValue<float> SymbolLayer::getDefaultSymbolSpacing() {
- return { 250 };
+ return SymbolSpacing::defaultValue();
}
PropertyValue<float> SymbolLayer::getSymbolSpacing() const {
- return impl->layout.symbolSpacing.get();
+ return impl->layout.unevaluated.get<SymbolSpacing>();
}
void SymbolLayer::setSymbolSpacing(PropertyValue<float> value) {
if (value == getSymbolSpacing())
return;
- impl->layout.symbolSpacing.set(value);
+ impl->layout.unevaluated.get<SymbolSpacing>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "symbol-spacing");
}
PropertyValue<bool> SymbolLayer::getDefaultSymbolAvoidEdges() {
- return { false };
+ return SymbolAvoidEdges::defaultValue();
}
PropertyValue<bool> SymbolLayer::getSymbolAvoidEdges() const {
- return impl->layout.symbolAvoidEdges.get();
+ return impl->layout.unevaluated.get<SymbolAvoidEdges>();
}
void SymbolLayer::setSymbolAvoidEdges(PropertyValue<bool> value) {
if (value == getSymbolAvoidEdges())
return;
- impl->layout.symbolAvoidEdges.set(value);
+ impl->layout.unevaluated.get<SymbolAvoidEdges>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "symbol-avoid-edges");
}
PropertyValue<bool> SymbolLayer::getDefaultIconAllowOverlap() {
- return { false };
+ return IconAllowOverlap::defaultValue();
}
PropertyValue<bool> SymbolLayer::getIconAllowOverlap() const {
- return impl->layout.iconAllowOverlap.get();
+ return impl->layout.unevaluated.get<IconAllowOverlap>();
}
void SymbolLayer::setIconAllowOverlap(PropertyValue<bool> value) {
if (value == getIconAllowOverlap())
return;
- impl->layout.iconAllowOverlap.set(value);
+ impl->layout.unevaluated.get<IconAllowOverlap>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "icon-allow-overlap");
}
PropertyValue<bool> SymbolLayer::getDefaultIconIgnorePlacement() {
- return { false };
+ return IconIgnorePlacement::defaultValue();
}
PropertyValue<bool> SymbolLayer::getIconIgnorePlacement() const {
- return impl->layout.iconIgnorePlacement.get();
+ return impl->layout.unevaluated.get<IconIgnorePlacement>();
}
void SymbolLayer::setIconIgnorePlacement(PropertyValue<bool> value) {
if (value == getIconIgnorePlacement())
return;
- impl->layout.iconIgnorePlacement.set(value);
+ impl->layout.unevaluated.get<IconIgnorePlacement>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "icon-ignore-placement");
}
PropertyValue<bool> SymbolLayer::getDefaultIconOptional() {
- return { false };
+ return IconOptional::defaultValue();
}
PropertyValue<bool> SymbolLayer::getIconOptional() const {
- return impl->layout.iconOptional.get();
+ return impl->layout.unevaluated.get<IconOptional>();
}
void SymbolLayer::setIconOptional(PropertyValue<bool> value) {
if (value == getIconOptional())
return;
- impl->layout.iconOptional.set(value);
+ impl->layout.unevaluated.get<IconOptional>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "icon-optional");
}
PropertyValue<AlignmentType> SymbolLayer::getDefaultIconRotationAlignment() {
- return { AlignmentType::Auto };
+ return IconRotationAlignment::defaultValue();
}
PropertyValue<AlignmentType> SymbolLayer::getIconRotationAlignment() const {
- return impl->layout.iconRotationAlignment.get();
+ return impl->layout.unevaluated.get<IconRotationAlignment>();
}
void SymbolLayer::setIconRotationAlignment(PropertyValue<AlignmentType> value) {
if (value == getIconRotationAlignment())
return;
- impl->layout.iconRotationAlignment.set(value);
+ impl->layout.unevaluated.get<IconRotationAlignment>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "icon-rotation-alignment");
}
PropertyValue<float> SymbolLayer::getDefaultIconSize() {
- return { 1 };
+ return IconSize::defaultValue();
}
PropertyValue<float> SymbolLayer::getIconSize() const {
- return impl->layout.iconSize.get();
+ return impl->layout.unevaluated.get<IconSize>();
}
void SymbolLayer::setIconSize(PropertyValue<float> value) {
if (value == getIconSize())
return;
- impl->layout.iconSize.set(value);
+ impl->layout.unevaluated.get<IconSize>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "icon-size");
}
PropertyValue<IconTextFitType> SymbolLayer::getDefaultIconTextFit() {
- return { IconTextFitType::None };
+ return IconTextFit::defaultValue();
}
PropertyValue<IconTextFitType> SymbolLayer::getIconTextFit() const {
- return impl->layout.iconTextFit.get();
+ return impl->layout.unevaluated.get<IconTextFit>();
}
void SymbolLayer::setIconTextFit(PropertyValue<IconTextFitType> value) {
if (value == getIconTextFit())
return;
- impl->layout.iconTextFit.set(value);
+ impl->layout.unevaluated.get<IconTextFit>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "icon-text-fit");
}
PropertyValue<std::array<float, 4>> SymbolLayer::getDefaultIconTextFitPadding() {
- return { {{ 0, 0, 0, 0 }} };
+ return IconTextFitPadding::defaultValue();
}
PropertyValue<std::array<float, 4>> SymbolLayer::getIconTextFitPadding() const {
- return impl->layout.iconTextFitPadding.get();
+ return impl->layout.unevaluated.get<IconTextFitPadding>();
}
void SymbolLayer::setIconTextFitPadding(PropertyValue<std::array<float, 4>> value) {
if (value == getIconTextFitPadding())
return;
- impl->layout.iconTextFitPadding.set(value);
+ impl->layout.unevaluated.get<IconTextFitPadding>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "icon-text-fit-padding");
}
PropertyValue<std::string> SymbolLayer::getDefaultIconImage() {
- return { "" };
+ return IconImage::defaultValue();
}
PropertyValue<std::string> SymbolLayer::getIconImage() const {
- return impl->layout.iconImage.get();
+ return impl->layout.unevaluated.get<IconImage>();
}
void SymbolLayer::setIconImage(PropertyValue<std::string> value) {
if (value == getIconImage())
return;
- impl->layout.iconImage.set(value);
+ impl->layout.unevaluated.get<IconImage>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "icon-image");
}
PropertyValue<float> SymbolLayer::getDefaultIconRotate() {
- return { 0 };
+ return IconRotate::defaultValue();
}
PropertyValue<float> SymbolLayer::getIconRotate() const {
- return impl->layout.iconRotate.get();
+ return impl->layout.unevaluated.get<IconRotate>();
}
void SymbolLayer::setIconRotate(PropertyValue<float> value) {
if (value == getIconRotate())
return;
- impl->layout.iconRotate.set(value);
+ impl->layout.unevaluated.get<IconRotate>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "icon-rotate");
}
PropertyValue<float> SymbolLayer::getDefaultIconPadding() {
- return { 2 };
+ return IconPadding::defaultValue();
}
PropertyValue<float> SymbolLayer::getIconPadding() const {
- return impl->layout.iconPadding.get();
+ return impl->layout.unevaluated.get<IconPadding>();
}
void SymbolLayer::setIconPadding(PropertyValue<float> value) {
if (value == getIconPadding())
return;
- impl->layout.iconPadding.set(value);
+ impl->layout.unevaluated.get<IconPadding>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "icon-padding");
}
PropertyValue<bool> SymbolLayer::getDefaultIconKeepUpright() {
- return { false };
+ return IconKeepUpright::defaultValue();
}
PropertyValue<bool> SymbolLayer::getIconKeepUpright() const {
- return impl->layout.iconKeepUpright.get();
+ return impl->layout.unevaluated.get<IconKeepUpright>();
}
void SymbolLayer::setIconKeepUpright(PropertyValue<bool> value) {
if (value == getIconKeepUpright())
return;
- impl->layout.iconKeepUpright.set(value);
+ impl->layout.unevaluated.get<IconKeepUpright>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "icon-keep-upright");
}
PropertyValue<std::array<float, 2>> SymbolLayer::getDefaultIconOffset() {
- return { {{ 0, 0 }} };
+ return IconOffset::defaultValue();
}
PropertyValue<std::array<float, 2>> SymbolLayer::getIconOffset() const {
- return impl->layout.iconOffset.get();
+ return impl->layout.unevaluated.get<IconOffset>();
}
void SymbolLayer::setIconOffset(PropertyValue<std::array<float, 2>> value) {
if (value == getIconOffset())
return;
- impl->layout.iconOffset.set(value);
+ impl->layout.unevaluated.get<IconOffset>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "icon-offset");
}
PropertyValue<AlignmentType> SymbolLayer::getDefaultTextPitchAlignment() {
- return { AlignmentType::Auto };
+ return TextPitchAlignment::defaultValue();
}
PropertyValue<AlignmentType> SymbolLayer::getTextPitchAlignment() const {
- return impl->layout.textPitchAlignment.get();
+ return impl->layout.unevaluated.get<TextPitchAlignment>();
}
void SymbolLayer::setTextPitchAlignment(PropertyValue<AlignmentType> value) {
if (value == getTextPitchAlignment())
return;
- impl->layout.textPitchAlignment.set(value);
+ impl->layout.unevaluated.get<TextPitchAlignment>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "text-pitch-alignment");
}
PropertyValue<AlignmentType> SymbolLayer::getDefaultTextRotationAlignment() {
- return { AlignmentType::Auto };
+ return TextRotationAlignment::defaultValue();
}
PropertyValue<AlignmentType> SymbolLayer::getTextRotationAlignment() const {
- return impl->layout.textRotationAlignment.get();
+ return impl->layout.unevaluated.get<TextRotationAlignment>();
}
void SymbolLayer::setTextRotationAlignment(PropertyValue<AlignmentType> value) {
if (value == getTextRotationAlignment())
return;
- impl->layout.textRotationAlignment.set(value);
+ impl->layout.unevaluated.get<TextRotationAlignment>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "text-rotation-alignment");
}
PropertyValue<std::string> SymbolLayer::getDefaultTextField() {
- return { "" };
+ return TextField::defaultValue();
}
PropertyValue<std::string> SymbolLayer::getTextField() const {
- return impl->layout.textField.get();
+ return impl->layout.unevaluated.get<TextField>();
}
void SymbolLayer::setTextField(PropertyValue<std::string> value) {
if (value == getTextField())
return;
- impl->layout.textField.set(value);
+ impl->layout.unevaluated.get<TextField>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "text-field");
}
PropertyValue<std::vector<std::string>> SymbolLayer::getDefaultTextFont() {
- return { { "Open Sans Regular", "Arial Unicode MS Regular" } };
+ return TextFont::defaultValue();
}
PropertyValue<std::vector<std::string>> SymbolLayer::getTextFont() const {
- return impl->layout.textFont.get();
+ return impl->layout.unevaluated.get<TextFont>();
}
void SymbolLayer::setTextFont(PropertyValue<std::vector<std::string>> value) {
if (value == getTextFont())
return;
- impl->layout.textFont.set(value);
+ impl->layout.unevaluated.get<TextFont>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "text-font");
}
PropertyValue<float> SymbolLayer::getDefaultTextSize() {
- return { 16 };
+ return TextSize::defaultValue();
}
PropertyValue<float> SymbolLayer::getTextSize() const {
- return impl->layout.textSize.get();
+ return impl->layout.unevaluated.get<TextSize>();
}
void SymbolLayer::setTextSize(PropertyValue<float> value) {
if (value == getTextSize())
return;
- impl->layout.textSize.set(value);
+ impl->layout.unevaluated.get<TextSize>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "text-size");
}
PropertyValue<float> SymbolLayer::getDefaultTextMaxWidth() {
- return { 10 };
+ return TextMaxWidth::defaultValue();
}
PropertyValue<float> SymbolLayer::getTextMaxWidth() const {
- return impl->layout.textMaxWidth.get();
+ return impl->layout.unevaluated.get<TextMaxWidth>();
}
void SymbolLayer::setTextMaxWidth(PropertyValue<float> value) {
if (value == getTextMaxWidth())
return;
- impl->layout.textMaxWidth.set(value);
+ impl->layout.unevaluated.get<TextMaxWidth>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "text-max-width");
}
PropertyValue<float> SymbolLayer::getDefaultTextLineHeight() {
- return { 1.2 };
+ return TextLineHeight::defaultValue();
}
PropertyValue<float> SymbolLayer::getTextLineHeight() const {
- return impl->layout.textLineHeight.get();
+ return impl->layout.unevaluated.get<TextLineHeight>();
}
void SymbolLayer::setTextLineHeight(PropertyValue<float> value) {
if (value == getTextLineHeight())
return;
- impl->layout.textLineHeight.set(value);
+ impl->layout.unevaluated.get<TextLineHeight>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "text-line-height");
}
PropertyValue<float> SymbolLayer::getDefaultTextLetterSpacing() {
- return { 0 };
+ return TextLetterSpacing::defaultValue();
}
PropertyValue<float> SymbolLayer::getTextLetterSpacing() const {
- return impl->layout.textLetterSpacing.get();
+ return impl->layout.unevaluated.get<TextLetterSpacing>();
}
void SymbolLayer::setTextLetterSpacing(PropertyValue<float> value) {
if (value == getTextLetterSpacing())
return;
- impl->layout.textLetterSpacing.set(value);
+ impl->layout.unevaluated.get<TextLetterSpacing>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "text-letter-spacing");
}
PropertyValue<TextJustifyType> SymbolLayer::getDefaultTextJustify() {
- return { TextJustifyType::Center };
+ return TextJustify::defaultValue();
}
PropertyValue<TextJustifyType> SymbolLayer::getTextJustify() const {
- return impl->layout.textJustify.get();
+ return impl->layout.unevaluated.get<TextJustify>();
}
void SymbolLayer::setTextJustify(PropertyValue<TextJustifyType> value) {
if (value == getTextJustify())
return;
- impl->layout.textJustify.set(value);
+ impl->layout.unevaluated.get<TextJustify>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "text-justify");
}
PropertyValue<TextAnchorType> SymbolLayer::getDefaultTextAnchor() {
- return { TextAnchorType::Center };
+ return TextAnchor::defaultValue();
}
PropertyValue<TextAnchorType> SymbolLayer::getTextAnchor() const {
- return impl->layout.textAnchor.get();
+ return impl->layout.unevaluated.get<TextAnchor>();
}
void SymbolLayer::setTextAnchor(PropertyValue<TextAnchorType> value) {
if (value == getTextAnchor())
return;
- impl->layout.textAnchor.set(value);
+ impl->layout.unevaluated.get<TextAnchor>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "text-anchor");
}
PropertyValue<float> SymbolLayer::getDefaultTextMaxAngle() {
- return { 45 };
+ return TextMaxAngle::defaultValue();
}
PropertyValue<float> SymbolLayer::getTextMaxAngle() const {
- return impl->layout.textMaxAngle.get();
+ return impl->layout.unevaluated.get<TextMaxAngle>();
}
void SymbolLayer::setTextMaxAngle(PropertyValue<float> value) {
if (value == getTextMaxAngle())
return;
- impl->layout.textMaxAngle.set(value);
+ impl->layout.unevaluated.get<TextMaxAngle>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "text-max-angle");
}
PropertyValue<float> SymbolLayer::getDefaultTextRotate() {
- return { 0 };
+ return TextRotate::defaultValue();
}
PropertyValue<float> SymbolLayer::getTextRotate() const {
- return impl->layout.textRotate.get();
+ return impl->layout.unevaluated.get<TextRotate>();
}
void SymbolLayer::setTextRotate(PropertyValue<float> value) {
if (value == getTextRotate())
return;
- impl->layout.textRotate.set(value);
+ impl->layout.unevaluated.get<TextRotate>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "text-rotate");
}
PropertyValue<float> SymbolLayer::getDefaultTextPadding() {
- return { 2 };
+ return TextPadding::defaultValue();
}
PropertyValue<float> SymbolLayer::getTextPadding() const {
- return impl->layout.textPadding.get();
+ return impl->layout.unevaluated.get<TextPadding>();
}
void SymbolLayer::setTextPadding(PropertyValue<float> value) {
if (value == getTextPadding())
return;
- impl->layout.textPadding.set(value);
+ impl->layout.unevaluated.get<TextPadding>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "text-padding");
}
PropertyValue<bool> SymbolLayer::getDefaultTextKeepUpright() {
- return { true };
+ return TextKeepUpright::defaultValue();
}
PropertyValue<bool> SymbolLayer::getTextKeepUpright() const {
- return impl->layout.textKeepUpright.get();
+ return impl->layout.unevaluated.get<TextKeepUpright>();
}
void SymbolLayer::setTextKeepUpright(PropertyValue<bool> value) {
if (value == getTextKeepUpright())
return;
- impl->layout.textKeepUpright.set(value);
+ impl->layout.unevaluated.get<TextKeepUpright>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "text-keep-upright");
}
PropertyValue<TextTransformType> SymbolLayer::getDefaultTextTransform() {
- return { TextTransformType::None };
+ return TextTransform::defaultValue();
}
PropertyValue<TextTransformType> SymbolLayer::getTextTransform() const {
- return impl->layout.textTransform.get();
+ return impl->layout.unevaluated.get<TextTransform>();
}
void SymbolLayer::setTextTransform(PropertyValue<TextTransformType> value) {
if (value == getTextTransform())
return;
- impl->layout.textTransform.set(value);
+ impl->layout.unevaluated.get<TextTransform>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "text-transform");
}
PropertyValue<std::array<float, 2>> SymbolLayer::getDefaultTextOffset() {
- return { {{ 0, 0 }} };
+ return TextOffset::defaultValue();
}
PropertyValue<std::array<float, 2>> SymbolLayer::getTextOffset() const {
- return impl->layout.textOffset.get();
+ return impl->layout.unevaluated.get<TextOffset>();
}
void SymbolLayer::setTextOffset(PropertyValue<std::array<float, 2>> value) {
if (value == getTextOffset())
return;
- impl->layout.textOffset.set(value);
+ impl->layout.unevaluated.get<TextOffset>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "text-offset");
}
PropertyValue<bool> SymbolLayer::getDefaultTextAllowOverlap() {
- return { false };
+ return TextAllowOverlap::defaultValue();
}
PropertyValue<bool> SymbolLayer::getTextAllowOverlap() const {
- return impl->layout.textAllowOverlap.get();
+ return impl->layout.unevaluated.get<TextAllowOverlap>();
}
void SymbolLayer::setTextAllowOverlap(PropertyValue<bool> value) {
if (value == getTextAllowOverlap())
return;
- impl->layout.textAllowOverlap.set(value);
+ impl->layout.unevaluated.get<TextAllowOverlap>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "text-allow-overlap");
}
PropertyValue<bool> SymbolLayer::getDefaultTextIgnorePlacement() {
- return { false };
+ return TextIgnorePlacement::defaultValue();
}
PropertyValue<bool> SymbolLayer::getTextIgnorePlacement() const {
- return impl->layout.textIgnorePlacement.get();
+ return impl->layout.unevaluated.get<TextIgnorePlacement>();
}
void SymbolLayer::setTextIgnorePlacement(PropertyValue<bool> value) {
if (value == getTextIgnorePlacement())
return;
- impl->layout.textIgnorePlacement.set(value);
+ impl->layout.unevaluated.get<TextIgnorePlacement>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "text-ignore-placement");
}
PropertyValue<bool> SymbolLayer::getDefaultTextOptional() {
- return { false };
+ return TextOptional::defaultValue();
}
PropertyValue<bool> SymbolLayer::getTextOptional() const {
- return impl->layout.textOptional.get();
+ return impl->layout.unevaluated.get<TextOptional>();
}
void SymbolLayer::setTextOptional(PropertyValue<bool> value) {
if (value == getTextOptional())
return;
- impl->layout.textOptional.set(value);
+ impl->layout.unevaluated.get<TextOptional>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "text-optional");
}
@@ -543,13 +543,13 @@ PropertyValue<float> SymbolLayer::getDefaultIconOpacity() {
}
PropertyValue<float> SymbolLayer::getIconOpacity(const optional<std::string>& klass) const {
- return impl->paint.iconOpacity.get(klass);
+ return impl->paint.get<IconOpacity>(klass);
}
void SymbolLayer::setIconOpacity(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getIconOpacity(klass))
return;
- impl->paint.iconOpacity.set(value, klass);
+ impl->paint.set<IconOpacity>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -558,13 +558,13 @@ PropertyValue<Color> SymbolLayer::getDefaultIconColor() {
}
PropertyValue<Color> SymbolLayer::getIconColor(const optional<std::string>& klass) const {
- return impl->paint.iconColor.get(klass);
+ return impl->paint.get<IconColor>(klass);
}
void SymbolLayer::setIconColor(PropertyValue<Color> value, const optional<std::string>& klass) {
if (value == getIconColor(klass))
return;
- impl->paint.iconColor.set(value, klass);
+ impl->paint.set<IconColor>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -573,13 +573,13 @@ PropertyValue<Color> SymbolLayer::getDefaultIconHaloColor() {
}
PropertyValue<Color> SymbolLayer::getIconHaloColor(const optional<std::string>& klass) const {
- return impl->paint.iconHaloColor.get(klass);
+ return impl->paint.get<IconHaloColor>(klass);
}
void SymbolLayer::setIconHaloColor(PropertyValue<Color> value, const optional<std::string>& klass) {
if (value == getIconHaloColor(klass))
return;
- impl->paint.iconHaloColor.set(value, klass);
+ impl->paint.set<IconHaloColor>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -588,13 +588,13 @@ PropertyValue<float> SymbolLayer::getDefaultIconHaloWidth() {
}
PropertyValue<float> SymbolLayer::getIconHaloWidth(const optional<std::string>& klass) const {
- return impl->paint.iconHaloWidth.get(klass);
+ return impl->paint.get<IconHaloWidth>(klass);
}
void SymbolLayer::setIconHaloWidth(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getIconHaloWidth(klass))
return;
- impl->paint.iconHaloWidth.set(value, klass);
+ impl->paint.set<IconHaloWidth>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -603,13 +603,13 @@ PropertyValue<float> SymbolLayer::getDefaultIconHaloBlur() {
}
PropertyValue<float> SymbolLayer::getIconHaloBlur(const optional<std::string>& klass) const {
- return impl->paint.iconHaloBlur.get(klass);
+ return impl->paint.get<IconHaloBlur>(klass);
}
void SymbolLayer::setIconHaloBlur(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getIconHaloBlur(klass))
return;
- impl->paint.iconHaloBlur.set(value, klass);
+ impl->paint.set<IconHaloBlur>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -618,13 +618,13 @@ PropertyValue<std::array<float, 2>> SymbolLayer::getDefaultIconTranslate() {
}
PropertyValue<std::array<float, 2>> SymbolLayer::getIconTranslate(const optional<std::string>& klass) const {
- return impl->paint.iconTranslate.get(klass);
+ return impl->paint.get<IconTranslate>(klass);
}
void SymbolLayer::setIconTranslate(PropertyValue<std::array<float, 2>> value, const optional<std::string>& klass) {
if (value == getIconTranslate(klass))
return;
- impl->paint.iconTranslate.set(value, klass);
+ impl->paint.set<IconTranslate>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -633,13 +633,13 @@ PropertyValue<TranslateAnchorType> SymbolLayer::getDefaultIconTranslateAnchor()
}
PropertyValue<TranslateAnchorType> SymbolLayer::getIconTranslateAnchor(const optional<std::string>& klass) const {
- return impl->paint.iconTranslateAnchor.get(klass);
+ return impl->paint.get<IconTranslateAnchor>(klass);
}
void SymbolLayer::setIconTranslateAnchor(PropertyValue<TranslateAnchorType> value, const optional<std::string>& klass) {
if (value == getIconTranslateAnchor(klass))
return;
- impl->paint.iconTranslateAnchor.set(value, klass);
+ impl->paint.set<IconTranslateAnchor>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -648,13 +648,13 @@ PropertyValue<float> SymbolLayer::getDefaultTextOpacity() {
}
PropertyValue<float> SymbolLayer::getTextOpacity(const optional<std::string>& klass) const {
- return impl->paint.textOpacity.get(klass);
+ return impl->paint.get<TextOpacity>(klass);
}
void SymbolLayer::setTextOpacity(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getTextOpacity(klass))
return;
- impl->paint.textOpacity.set(value, klass);
+ impl->paint.set<TextOpacity>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -663,13 +663,13 @@ PropertyValue<Color> SymbolLayer::getDefaultTextColor() {
}
PropertyValue<Color> SymbolLayer::getTextColor(const optional<std::string>& klass) const {
- return impl->paint.textColor.get(klass);
+ return impl->paint.get<TextColor>(klass);
}
void SymbolLayer::setTextColor(PropertyValue<Color> value, const optional<std::string>& klass) {
if (value == getTextColor(klass))
return;
- impl->paint.textColor.set(value, klass);
+ impl->paint.set<TextColor>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -678,13 +678,13 @@ PropertyValue<Color> SymbolLayer::getDefaultTextHaloColor() {
}
PropertyValue<Color> SymbolLayer::getTextHaloColor(const optional<std::string>& klass) const {
- return impl->paint.textHaloColor.get(klass);
+ return impl->paint.get<TextHaloColor>(klass);
}
void SymbolLayer::setTextHaloColor(PropertyValue<Color> value, const optional<std::string>& klass) {
if (value == getTextHaloColor(klass))
return;
- impl->paint.textHaloColor.set(value, klass);
+ impl->paint.set<TextHaloColor>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -693,13 +693,13 @@ PropertyValue<float> SymbolLayer::getDefaultTextHaloWidth() {
}
PropertyValue<float> SymbolLayer::getTextHaloWidth(const optional<std::string>& klass) const {
- return impl->paint.textHaloWidth.get(klass);
+ return impl->paint.get<TextHaloWidth>(klass);
}
void SymbolLayer::setTextHaloWidth(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getTextHaloWidth(klass))
return;
- impl->paint.textHaloWidth.set(value, klass);
+ impl->paint.set<TextHaloWidth>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -708,13 +708,13 @@ PropertyValue<float> SymbolLayer::getDefaultTextHaloBlur() {
}
PropertyValue<float> SymbolLayer::getTextHaloBlur(const optional<std::string>& klass) const {
- return impl->paint.textHaloBlur.get(klass);
+ return impl->paint.get<TextHaloBlur>(klass);
}
void SymbolLayer::setTextHaloBlur(PropertyValue<float> value, const optional<std::string>& klass) {
if (value == getTextHaloBlur(klass))
return;
- impl->paint.textHaloBlur.set(value, klass);
+ impl->paint.set<TextHaloBlur>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -723,13 +723,13 @@ PropertyValue<std::array<float, 2>> SymbolLayer::getDefaultTextTranslate() {
}
PropertyValue<std::array<float, 2>> SymbolLayer::getTextTranslate(const optional<std::string>& klass) const {
- return impl->paint.textTranslate.get(klass);
+ return impl->paint.get<TextTranslate>(klass);
}
void SymbolLayer::setTextTranslate(PropertyValue<std::array<float, 2>> value, const optional<std::string>& klass) {
if (value == getTextTranslate(klass))
return;
- impl->paint.textTranslate.set(value, klass);
+ impl->paint.set<TextTranslate>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
@@ -738,13 +738,13 @@ PropertyValue<TranslateAnchorType> SymbolLayer::getDefaultTextTranslateAnchor()
}
PropertyValue<TranslateAnchorType> SymbolLayer::getTextTranslateAnchor(const optional<std::string>& klass) const {
- return impl->paint.textTranslateAnchor.get(klass);
+ return impl->paint.get<TextTranslateAnchor>(klass);
}
void SymbolLayer::setTextTranslateAnchor(PropertyValue<TranslateAnchorType> value, const optional<std::string>& klass) {
if (value == getTextTranslateAnchor(klass))
return;
- impl->paint.textTranslateAnchor.set(value, klass);
+ impl->paint.set<TextTranslateAnchor>(value, klass);
impl->observer->onLayerPaintPropertyChanged(*this);
}
diff --git a/src/mbgl/style/layers/symbol_layer_impl.cpp b/src/mbgl/style/layers/symbol_layer_impl.cpp
index e85f3a90f9..957bc1993e 100644
--- a/src/mbgl/style/layers/symbol_layer_impl.cpp
+++ b/src/mbgl/style/layers/symbol_layer_impl.cpp
@@ -10,20 +10,18 @@ void SymbolLayer::Impl::cascade(const CascadeParameters& parameters) {
paint.cascade(parameters);
}
-bool SymbolLayer::Impl::recalculate(const CalculationParameters& parameters) {
- bool hasTransitions = paint.recalculate(parameters);
+bool SymbolLayer::Impl::evaluate(const PropertyEvaluationParameters& parameters) {
+ paint.evaluate(parameters);
// text-size and icon-size are layout properties but they also need to be evaluated as paint properties:
- layout.iconSize.calculate(parameters);
- layout.textSize.calculate(parameters);
- iconSize = layout.iconSize;
- textSize = layout.textSize;
+ iconSize = layout.evaluate<IconSize>(parameters);
+ textSize = layout.evaluate<TextSize>(parameters);
- passes = ((paint.iconOpacity > 0 && (paint.iconColor.value.a > 0 || paint.iconHaloColor.value.a > 0) && iconSize > 0)
- || (paint.textOpacity > 0 && (paint.textColor.value.a > 0 || paint.textHaloColor.value.a > 0) && textSize > 0))
+ passes = ((paint.evaluated.get<IconOpacity>() > 0 && (paint.evaluated.get<IconColor>().a > 0 || paint.evaluated.get<IconHaloColor>().a > 0) && iconSize > 0)
+ || (paint.evaluated.get<TextOpacity>() > 0 && (paint.evaluated.get<TextColor>().a > 0 || paint.evaluated.get<TextHaloColor>().a > 0) && textSize > 0))
? RenderPass::Translucent : RenderPass::None;
- return hasTransitions;
+ return paint.hasTransition();
}
std::unique_ptr<Bucket> SymbolLayer::Impl::createBucket(BucketParameters&) const {
@@ -32,37 +30,34 @@ std::unique_ptr<Bucket> SymbolLayer::Impl::createBucket(BucketParameters&) const
}
std::unique_ptr<SymbolLayout> SymbolLayer::Impl::createLayout(BucketParameters& parameters) const {
- SymbolLayoutProperties layoutProperties = layout;
+ PropertyEvaluationParameters p(parameters.tileID.overscaledZ);
+ SymbolLayoutProperties::Evaluated evaluated = layout.evaluate(p);
- CalculationParameters p(parameters.tileID.overscaledZ);
- layoutProperties.recalculate(p);
-
- if (layoutProperties.iconRotationAlignment.value == AlignmentType::Auto) {
- if (layoutProperties.symbolPlacement.value == SymbolPlacementType::Line) {
- layoutProperties.iconRotationAlignment.value = AlignmentType::Map;
+ if (evaluated.get<IconRotationAlignment>() == AlignmentType::Auto) {
+ if (evaluated.get<SymbolPlacement>() == SymbolPlacementType::Line) {
+ evaluated.get<IconRotationAlignment>() = AlignmentType::Map;
} else {
- layoutProperties.iconRotationAlignment.value = AlignmentType::Viewport;
+ evaluated.get<IconRotationAlignment>() = AlignmentType::Viewport;
}
}
- if (layoutProperties.textRotationAlignment.value == AlignmentType::Auto) {
- if (layoutProperties.symbolPlacement.value == SymbolPlacementType::Line) {
- layoutProperties.textRotationAlignment.value = AlignmentType::Map;
+ if (evaluated.get<TextRotationAlignment>() == AlignmentType::Auto) {
+ if (evaluated.get<SymbolPlacement>() == SymbolPlacementType::Line) {
+ evaluated.get<TextRotationAlignment>() = AlignmentType::Map;
} else {
- layoutProperties.textRotationAlignment.value = AlignmentType::Viewport;
+ evaluated.get<TextRotationAlignment>() = AlignmentType::Viewport;
}
}
// If unspecified `text-pitch-alignment` inherits `text-rotation-alignment`
- if (layoutProperties.textPitchAlignment.value == AlignmentType::Auto) {
- layoutProperties.textPitchAlignment.value = layoutProperties.textRotationAlignment.value;
+ if (evaluated.get<TextPitchAlignment>() == AlignmentType::Auto) {
+ evaluated.get<TextPitchAlignment>() = evaluated.get<TextRotationAlignment>();
}
- layoutProperties.textSize.calculate(CalculationParameters(18));
- float textMaxSize = layoutProperties.textSize;
+ float textMaxSize = layout.evaluate<TextSize>(PropertyEvaluationParameters(18));
- layoutProperties.iconSize.calculate(CalculationParameters(p.z + 1));
- layoutProperties.textSize.calculate(CalculationParameters(p.z + 1));
+ evaluated.get<IconSize>() = layout.evaluate<IconSize>(PropertyEvaluationParameters(p.z + 1));
+ evaluated.get<TextSize>() = layout.evaluate<TextSize>(PropertyEvaluationParameters(p.z + 1));
return std::make_unique<SymbolLayout>(id,
parameters.layer.getName(),
@@ -71,10 +66,44 @@ std::unique_ptr<SymbolLayout> SymbolLayer::Impl::createLayout(BucketParameters&
parameters.mode,
parameters.layer,
filter,
- layoutProperties,
+ evaluated,
textMaxSize,
*spriteAtlas);
}
+SymbolPropertyValues SymbolLayer::Impl::iconPropertyValues(const SymbolLayoutProperties::Evaluated& layout_) const {
+ return SymbolPropertyValues {
+ layout_.get<IconRotationAlignment>(), // icon-pitch-alignment is not yet implemented; inherit the rotation alignment
+ layout_.get<IconRotationAlignment>(),
+ layout_.get<IconSize>(),
+ paint.evaluated.get<IconOpacity>(),
+ paint.evaluated.get<IconColor>(),
+ paint.evaluated.get<IconHaloColor>(),
+ paint.evaluated.get<IconHaloWidth>(),
+ paint.evaluated.get<IconHaloBlur>(),
+ paint.evaluated.get<IconTranslate>(),
+ paint.evaluated.get<IconTranslateAnchor>(),
+ iconSize,
+ 1.0f
+ };
+}
+
+SymbolPropertyValues SymbolLayer::Impl::textPropertyValues(const SymbolLayoutProperties::Evaluated& layout_) const {
+ return SymbolPropertyValues {
+ layout_.get<TextPitchAlignment>(),
+ layout_.get<TextRotationAlignment>(),
+ layout_.get<TextSize>(),
+ paint.evaluated.get<TextOpacity>(),
+ paint.evaluated.get<TextColor>(),
+ paint.evaluated.get<TextHaloColor>(),
+ paint.evaluated.get<TextHaloWidth>(),
+ paint.evaluated.get<TextHaloBlur>(),
+ paint.evaluated.get<TextTranslate>(),
+ paint.evaluated.get<TextTranslateAnchor>(),
+ textSize,
+ 24.0f
+ };
+}
+
} // namespace style
} // namespace mbgl
diff --git a/src/mbgl/style/layers/symbol_layer_impl.hpp b/src/mbgl/style/layers/symbol_layer_impl.hpp
index fe37ba86ea..46ed75b231 100644
--- a/src/mbgl/style/layers/symbol_layer_impl.hpp
+++ b/src/mbgl/style/layers/symbol_layer_impl.hpp
@@ -11,17 +11,50 @@ class SymbolLayout;
namespace style {
+// Repackaging evaluated values from SymbolLayoutProperties + SymbolPaintProperties
+// for genericity over icons vs. text.
+class SymbolPropertyValues {
+public:
+ // Layout
+ AlignmentType pitchAlignment;
+ AlignmentType rotationAlignment;
+ float layoutSize;
+
+ // Paint
+ float opacity;
+ Color color;
+ Color haloColor;
+ float haloWidth;
+ float haloBlur;
+ std::array<float, 2> translate;
+ TranslateAnchorType translateAnchor;
+ float paintSize;
+
+ float sdfScale; // Constant (1.0 or 24.0)
+
+ bool hasHalo() const {
+ return haloColor.a > 0.0f && haloWidth > 0.0f;
+ }
+
+ bool hasForeground() const {
+ return color.a > 0.0f;
+ }
+};
+
class SymbolLayer::Impl : public Layer::Impl {
public:
std::unique_ptr<Layer> clone() const override;
std::unique_ptr<Layer> cloneRef(const std::string& id) const override;
void cascade(const CascadeParameters&) override;
- bool recalculate(const CalculationParameters&) override;
+ bool evaluate(const PropertyEvaluationParameters&) override;
std::unique_ptr<Bucket> createBucket(BucketParameters&) const override;
std::unique_ptr<SymbolLayout> createLayout(BucketParameters&) const;
+ SymbolPropertyValues iconPropertyValues(const SymbolLayoutProperties::Evaluated&) const;
+ SymbolPropertyValues textPropertyValues(const SymbolLayoutProperties::Evaluated&) const;
+
SymbolLayoutProperties layout;
SymbolPaintProperties paint;
diff --git a/src/mbgl/style/layers/symbol_layer_properties.cpp b/src/mbgl/style/layers/symbol_layer_properties.cpp
index 59a73d3d59..5a1ce713ba 100644
--- a/src/mbgl/style/layers/symbol_layer_properties.cpp
+++ b/src/mbgl/style/layers/symbol_layer_properties.cpp
@@ -5,80 +5,5 @@
namespace mbgl {
namespace style {
-void SymbolLayoutProperties::recalculate(const CalculationParameters& parameters) {
- symbolPlacement.calculate(parameters);
- symbolSpacing.calculate(parameters);
- symbolAvoidEdges.calculate(parameters);
- iconAllowOverlap.calculate(parameters);
- iconIgnorePlacement.calculate(parameters);
- iconOptional.calculate(parameters);
- iconRotationAlignment.calculate(parameters);
- iconSize.calculate(parameters);
- iconTextFit.calculate(parameters);
- iconTextFitPadding.calculate(parameters);
- iconImage.calculate(parameters);
- iconRotate.calculate(parameters);
- iconPadding.calculate(parameters);
- iconKeepUpright.calculate(parameters);
- iconOffset.calculate(parameters);
- textPitchAlignment.calculate(parameters);
- textRotationAlignment.calculate(parameters);
- textField.calculate(parameters);
- textFont.calculate(parameters);
- textSize.calculate(parameters);
- textMaxWidth.calculate(parameters);
- textLineHeight.calculate(parameters);
- textLetterSpacing.calculate(parameters);
- textJustify.calculate(parameters);
- textAnchor.calculate(parameters);
- textMaxAngle.calculate(parameters);
- textRotate.calculate(parameters);
- textPadding.calculate(parameters);
- textKeepUpright.calculate(parameters);
- textTransform.calculate(parameters);
- textOffset.calculate(parameters);
- textAllowOverlap.calculate(parameters);
- textIgnorePlacement.calculate(parameters);
- textOptional.calculate(parameters);
-}
-
-void SymbolPaintProperties::cascade(const CascadeParameters& parameters) {
- iconOpacity.cascade(parameters);
- iconColor.cascade(parameters);
- iconHaloColor.cascade(parameters);
- iconHaloWidth.cascade(parameters);
- iconHaloBlur.cascade(parameters);
- iconTranslate.cascade(parameters);
- iconTranslateAnchor.cascade(parameters);
- textOpacity.cascade(parameters);
- textColor.cascade(parameters);
- textHaloColor.cascade(parameters);
- textHaloWidth.cascade(parameters);
- textHaloBlur.cascade(parameters);
- textTranslate.cascade(parameters);
- textTranslateAnchor.cascade(parameters);
-}
-
-bool SymbolPaintProperties::recalculate(const CalculationParameters& parameters) {
- bool hasTransitions = false;
-
- hasTransitions |= iconOpacity.calculate(parameters);
- hasTransitions |= iconColor.calculate(parameters);
- hasTransitions |= iconHaloColor.calculate(parameters);
- hasTransitions |= iconHaloWidth.calculate(parameters);
- hasTransitions |= iconHaloBlur.calculate(parameters);
- hasTransitions |= iconTranslate.calculate(parameters);
- hasTransitions |= iconTranslateAnchor.calculate(parameters);
- hasTransitions |= textOpacity.calculate(parameters);
- hasTransitions |= textColor.calculate(parameters);
- hasTransitions |= textHaloColor.calculate(parameters);
- hasTransitions |= textHaloWidth.calculate(parameters);
- hasTransitions |= textHaloBlur.calculate(parameters);
- hasTransitions |= textTranslate.calculate(parameters);
- hasTransitions |= textTranslateAnchor.calculate(parameters);
-
- return hasTransitions;
-}
-
} // namespace style
} // namespace mbgl
diff --git a/src/mbgl/style/layers/symbol_layer_properties.hpp b/src/mbgl/style/layers/symbol_layer_properties.hpp
index fefa0ae05e..8b72c4347a 100644
--- a/src/mbgl/style/layers/symbol_layer_properties.hpp
+++ b/src/mbgl/style/layers/symbol_layer_properties.hpp
@@ -9,69 +9,251 @@
namespace mbgl {
namespace style {
-class CascadeParameters;
-class CalculationParameters;
-
-class SymbolLayoutProperties {
-public:
- void recalculate(const CalculationParameters&);
-
- LayoutProperty<SymbolPlacementType> symbolPlacement { SymbolPlacementType::Point };
- LayoutProperty<float> symbolSpacing { 250 };
- LayoutProperty<bool> symbolAvoidEdges { false };
- LayoutProperty<bool> iconAllowOverlap { false };
- LayoutProperty<bool> iconIgnorePlacement { false };
- LayoutProperty<bool> iconOptional { false };
- LayoutProperty<AlignmentType> iconRotationAlignment { AlignmentType::Auto };
- LayoutProperty<float> iconSize { 1 };
- LayoutProperty<IconTextFitType> iconTextFit { IconTextFitType::None };
- LayoutProperty<std::array<float, 4>> iconTextFitPadding { {{ 0, 0, 0, 0 }} };
- LayoutProperty<std::string> iconImage { "" };
- LayoutProperty<float> iconRotate { 0 };
- LayoutProperty<float> iconPadding { 2 };
- LayoutProperty<bool> iconKeepUpright { false };
- LayoutProperty<std::array<float, 2>> iconOffset { {{ 0, 0 }} };
- LayoutProperty<AlignmentType> textPitchAlignment { AlignmentType::Auto };
- LayoutProperty<AlignmentType> textRotationAlignment { AlignmentType::Auto };
- LayoutProperty<std::string> textField { "" };
- LayoutProperty<std::vector<std::string>> textFont { { "Open Sans Regular", "Arial Unicode MS Regular" } };
- LayoutProperty<float> textSize { 16 };
- LayoutProperty<float> textMaxWidth { 10 };
- LayoutProperty<float> textLineHeight { 1.2 };
- LayoutProperty<float> textLetterSpacing { 0 };
- LayoutProperty<TextJustifyType> textJustify { TextJustifyType::Center };
- LayoutProperty<TextAnchorType> textAnchor { TextAnchorType::Center };
- LayoutProperty<float> textMaxAngle { 45 };
- LayoutProperty<float> textRotate { 0 };
- LayoutProperty<float> textPadding { 2 };
- LayoutProperty<bool> textKeepUpright { true };
- LayoutProperty<TextTransformType> textTransform { TextTransformType::None };
- LayoutProperty<std::array<float, 2>> textOffset { {{ 0, 0 }} };
- LayoutProperty<bool> textAllowOverlap { false };
- LayoutProperty<bool> textIgnorePlacement { false };
- LayoutProperty<bool> textOptional { false };
-};
-
-class SymbolPaintProperties {
-public:
- void cascade(const CascadeParameters&);
- bool recalculate(const CalculationParameters&);
-
- PaintProperty<float> iconOpacity { 1 };
- PaintProperty<Color> iconColor { Color::black() };
- PaintProperty<Color> iconHaloColor { {} };
- PaintProperty<float> iconHaloWidth { 0 };
- PaintProperty<float> iconHaloBlur { 0 };
- PaintProperty<std::array<float, 2>> iconTranslate { {{ 0, 0 }} };
- PaintProperty<TranslateAnchorType> iconTranslateAnchor { TranslateAnchorType::Map };
- PaintProperty<float> textOpacity { 1 };
- PaintProperty<Color> textColor { Color::black() };
- PaintProperty<Color> textHaloColor { {} };
- PaintProperty<float> textHaloWidth { 0 };
- PaintProperty<float> textHaloBlur { 0 };
- PaintProperty<std::array<float, 2>> textTranslate { {{ 0, 0 }} };
- PaintProperty<TranslateAnchorType> textTranslateAnchor { TranslateAnchorType::Map };
+struct SymbolPlacement : LayoutProperty<SymbolPlacementType> {
+ static SymbolPlacementType defaultValue() { return SymbolPlacementType::Point; }
};
+struct SymbolSpacing : LayoutProperty<float> {
+ static float defaultValue() { return 250; }
+};
+
+struct SymbolAvoidEdges : LayoutProperty<bool> {
+ static bool defaultValue() { return false; }
+};
+
+struct IconAllowOverlap : LayoutProperty<bool> {
+ static bool defaultValue() { return false; }
+};
+
+struct IconIgnorePlacement : LayoutProperty<bool> {
+ static bool defaultValue() { return false; }
+};
+
+struct IconOptional : LayoutProperty<bool> {
+ static bool defaultValue() { return false; }
+};
+
+struct IconRotationAlignment : LayoutProperty<AlignmentType> {
+ static AlignmentType defaultValue() { return AlignmentType::Auto; }
+};
+
+struct IconSize : LayoutProperty<float> {
+ static float defaultValue() { return 1; }
+};
+
+struct IconTextFit : LayoutProperty<IconTextFitType> {
+ static IconTextFitType defaultValue() { return IconTextFitType::None; }
+};
+
+struct IconTextFitPadding : LayoutProperty<std::array<float, 4>> {
+ static std::array<float, 4> defaultValue() { return {{ 0, 0, 0, 0 }}; }
+};
+
+struct IconImage : LayoutProperty<std::string> {
+ static std::string defaultValue() { return ""; }
+};
+
+struct IconRotate : LayoutProperty<float> {
+ static float defaultValue() { return 0; }
+};
+
+struct IconPadding : LayoutProperty<float> {
+ static float defaultValue() { return 2; }
+};
+
+struct IconKeepUpright : LayoutProperty<bool> {
+ static bool defaultValue() { return false; }
+};
+
+struct IconOffset : LayoutProperty<std::array<float, 2>> {
+ static std::array<float, 2> defaultValue() { return {{ 0, 0 }}; }
+};
+
+struct TextPitchAlignment : LayoutProperty<AlignmentType> {
+ static AlignmentType defaultValue() { return AlignmentType::Auto; }
+};
+
+struct TextRotationAlignment : LayoutProperty<AlignmentType> {
+ static AlignmentType defaultValue() { return AlignmentType::Auto; }
+};
+
+struct TextField : LayoutProperty<std::string> {
+ static std::string defaultValue() { return ""; }
+};
+
+struct TextFont : LayoutProperty<std::vector<std::string>> {
+ static std::vector<std::string> defaultValue() { return { "Open Sans Regular", "Arial Unicode MS Regular" }; }
+};
+
+struct TextSize : LayoutProperty<float> {
+ static float defaultValue() { return 16; }
+};
+
+struct TextMaxWidth : LayoutProperty<float> {
+ static float defaultValue() { return 10; }
+};
+
+struct TextLineHeight : LayoutProperty<float> {
+ static float defaultValue() { return 1.2; }
+};
+
+struct TextLetterSpacing : LayoutProperty<float> {
+ static float defaultValue() { return 0; }
+};
+
+struct TextJustify : LayoutProperty<TextJustifyType> {
+ static TextJustifyType defaultValue() { return TextJustifyType::Center; }
+};
+
+struct TextAnchor : LayoutProperty<TextAnchorType> {
+ static TextAnchorType defaultValue() { return TextAnchorType::Center; }
+};
+
+struct TextMaxAngle : LayoutProperty<float> {
+ static float defaultValue() { return 45; }
+};
+
+struct TextRotate : LayoutProperty<float> {
+ static float defaultValue() { return 0; }
+};
+
+struct TextPadding : LayoutProperty<float> {
+ static float defaultValue() { return 2; }
+};
+
+struct TextKeepUpright : LayoutProperty<bool> {
+ static bool defaultValue() { return true; }
+};
+
+struct TextTransform : LayoutProperty<TextTransformType> {
+ static TextTransformType defaultValue() { return TextTransformType::None; }
+};
+
+struct TextOffset : LayoutProperty<std::array<float, 2>> {
+ static std::array<float, 2> defaultValue() { return {{ 0, 0 }}; }
+};
+
+struct TextAllowOverlap : LayoutProperty<bool> {
+ static bool defaultValue() { return false; }
+};
+
+struct TextIgnorePlacement : LayoutProperty<bool> {
+ static bool defaultValue() { return false; }
+};
+
+struct TextOptional : LayoutProperty<bool> {
+ static bool defaultValue() { return false; }
+};
+
+struct IconOpacity : PaintProperty<float> {
+ static float defaultValue() { return 1; }
+};
+
+struct IconColor : PaintProperty<Color> {
+ static Color defaultValue() { return Color::black(); }
+};
+
+struct IconHaloColor : PaintProperty<Color> {
+ static Color defaultValue() { return {}; }
+};
+
+struct IconHaloWidth : PaintProperty<float> {
+ static float defaultValue() { return 0; }
+};
+
+struct IconHaloBlur : PaintProperty<float> {
+ static float defaultValue() { return 0; }
+};
+
+struct IconTranslate : PaintProperty<std::array<float, 2>> {
+ static std::array<float, 2> defaultValue() { return {{ 0, 0 }}; }
+};
+
+struct IconTranslateAnchor : PaintProperty<TranslateAnchorType> {
+ static TranslateAnchorType defaultValue() { return TranslateAnchorType::Map; }
+};
+
+struct TextOpacity : PaintProperty<float> {
+ static float defaultValue() { return 1; }
+};
+
+struct TextColor : PaintProperty<Color> {
+ static Color defaultValue() { return Color::black(); }
+};
+
+struct TextHaloColor : PaintProperty<Color> {
+ static Color defaultValue() { return {}; }
+};
+
+struct TextHaloWidth : PaintProperty<float> {
+ static float defaultValue() { return 0; }
+};
+
+struct TextHaloBlur : PaintProperty<float> {
+ static float defaultValue() { return 0; }
+};
+
+struct TextTranslate : PaintProperty<std::array<float, 2>> {
+ static std::array<float, 2> defaultValue() { return {{ 0, 0 }}; }
+};
+
+struct TextTranslateAnchor : PaintProperty<TranslateAnchorType> {
+ static TranslateAnchorType defaultValue() { return TranslateAnchorType::Map; }
+};
+
+class SymbolLayoutProperties : public LayoutProperties<
+ SymbolPlacement,
+ SymbolSpacing,
+ SymbolAvoidEdges,
+ IconAllowOverlap,
+ IconIgnorePlacement,
+ IconOptional,
+ IconRotationAlignment,
+ IconSize,
+ IconTextFit,
+ IconTextFitPadding,
+ IconImage,
+ IconRotate,
+ IconPadding,
+ IconKeepUpright,
+ IconOffset,
+ TextPitchAlignment,
+ TextRotationAlignment,
+ TextField,
+ TextFont,
+ TextSize,
+ TextMaxWidth,
+ TextLineHeight,
+ TextLetterSpacing,
+ TextJustify,
+ TextAnchor,
+ TextMaxAngle,
+ TextRotate,
+ TextPadding,
+ TextKeepUpright,
+ TextTransform,
+ TextOffset,
+ TextAllowOverlap,
+ TextIgnorePlacement,
+ TextOptional
+> {};
+
+class SymbolPaintProperties : public PaintProperties<
+ IconOpacity,
+ IconColor,
+ IconHaloColor,
+ IconHaloWidth,
+ IconHaloBlur,
+ IconTranslate,
+ IconTranslateAnchor,
+ TextOpacity,
+ TextColor,
+ TextHaloColor,
+ TextHaloWidth,
+ TextHaloBlur,
+ TextTranslate,
+ TextTranslateAnchor
+> {};
+
} // namespace style
} // namespace mbgl
diff --git a/src/mbgl/style/layout_property.hpp b/src/mbgl/style/layout_property.hpp
index db1a1ebf28..6ea06ce556 100644
--- a/src/mbgl/style/layout_property.hpp
+++ b/src/mbgl/style/layout_property.hpp
@@ -1,43 +1,55 @@
#pragma once
-#include <mbgl/style/property_value.hpp>
-#include <mbgl/style/property_parsing.hpp>
#include <mbgl/style/property_evaluator.hpp>
-
-#include <utility>
+#include <mbgl/util/indexed_tuple.hpp>
namespace mbgl {
namespace style {
-template <typename T>
+class PropertyEvaluationParameters;
+
+template <class T>
class LayoutProperty {
public:
- explicit LayoutProperty(T v)
- : value(std::move(v)),
- defaultValue(value) {}
-
- const PropertyValue<T>& get() const {
- return currentValue;
- }
+ using EvaluatorType = PropertyEvaluator<T>;
+ using UnevaluatedType = PropertyValue<T>;
+ using EvaluatedType = T;
+};
- void set(const PropertyValue<T>& value_) {
- currentValue = value_;
+template <class... Ps>
+class LayoutProperties {
+public:
+ using Properties = TypeList<Ps...>;
+ using EvaluatedTypes = TypeList<typename Ps::EvaluatedType...>;
+ using UnevaluatedTypes = TypeList<typename Ps::UnevaluatedType...>;
+
+ template <class TypeList>
+ using Tuple = IndexedTuple<Properties, TypeList>;
+
+ class Evaluated : public Tuple<EvaluatedTypes> {
+ public:
+ using Tuple<EvaluatedTypes>::Tuple;
+ };
+
+ class Unevaluated : public Tuple<UnevaluatedTypes> {
+ public:
+ using Tuple<UnevaluatedTypes>::Tuple;
+ };
+
+ template <class P>
+ auto evaluate(const PropertyEvaluationParameters& parameters) const {
+ using Evaluator = typename P::EvaluatorType;
+ return unevaluated.template get<P>()
+ .evaluate(Evaluator(parameters, P::defaultValue()));
}
- void calculate(const CalculationParameters& parameters) {
- if (currentValue) {
- PropertyEvaluator<T> evaluator(parameters, defaultValue);
- value = PropertyValue<T>::visit(currentValue, evaluator);
- }
+ Evaluated evaluate(const PropertyEvaluationParameters& parameters) const {
+ return Evaluated {
+ evaluate<Ps>(parameters)...
+ };
}
- // TODO: remove / privatize
- operator T() const { return value; }
- T value;
-
-private:
- T defaultValue;
- PropertyValue<T> currentValue;
+ Unevaluated unevaluated;
};
} // namespace style
diff --git a/src/mbgl/style/paint_property.hpp b/src/mbgl/style/paint_property.hpp
index 4a620706ec..15df2a77c7 100644
--- a/src/mbgl/style/paint_property.hpp
+++ b/src/mbgl/style/paint_property.hpp
@@ -1,14 +1,15 @@
#pragma once
#include <mbgl/style/class_dictionary.hpp>
-#include <mbgl/style/property_parsing.hpp>
#include <mbgl/style/property_evaluator.hpp>
+#include <mbgl/style/cross_faded_property_evaluator.hpp>
#include <mbgl/style/transition_options.hpp>
#include <mbgl/style/cascade_parameters.hpp>
-#include <mbgl/style/calculation_parameters.hpp>
+#include <mbgl/style/property_evaluation_parameters.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/interpolate.hpp>
-#include <mbgl/util/rapidjson.hpp>
+#include <mbgl/util/indexed_tuple.hpp>
+#include <mbgl/util/ignore.hpp>
#include <unordered_map>
#include <utility>
@@ -16,29 +17,59 @@
namespace mbgl {
namespace style {
-template <class T, template <class S> class Evaluator = PropertyEvaluator>
-class PaintProperty {
+template <class T, class Evaluator>
+class UnevaluatedPaintProperty {
public:
- using Result = typename Evaluator<T>::ResultType;
+ using Result = typename Evaluator::ResultType;
+
+ UnevaluatedPaintProperty() = default;
+
+ UnevaluatedPaintProperty(PropertyValue<T> value_,
+ UnevaluatedPaintProperty<T, Evaluator> prior_,
+ TransitionOptions transition,
+ TimePoint now)
+ : begin(now + transition.delay.value_or(Duration::zero())),
+ end(begin + transition.duration.value_or(Duration::zero())),
+ value(std::move(value_)) {
+ if (transition) {
+ prior = { std::move(prior_) };
+ }
+ }
- explicit PaintProperty(T defaultValue_)
- : defaultValue(defaultValue_) {
- values.emplace(ClassID::Fallback, defaultValue_);
+ Result evaluate(const PropertyEvaluationParameters& parameters, T defaultValue) {
+ Result finalValue = value.evaluate(Evaluator(parameters, defaultValue));
+ if (!prior) {
+ // No prior value.
+ return finalValue;
+ } else if (parameters.now >= end) {
+ // Transition from prior value is now complete.
+ prior = {};
+ return finalValue;
+ } else {
+ // Interpolate between recursively-calculated prior value and final.
+ float t = std::chrono::duration<float>(parameters.now - begin) / (end - begin);
+ return util::interpolate(prior->get().evaluate(parameters, defaultValue), finalValue, util::DEFAULT_TRANSITION_EASE.solve(t, 0.001));
+ }
}
- PaintProperty(const PaintProperty& other)
- : defaultValue(other.defaultValue),
- values(other.values),
- transitions(other.transitions) {
+ bool hasTransition() const {
+ return bool(prior);
}
- PaintProperty& operator=(const PaintProperty& other) {
- defaultValue = other.defaultValue;
- values = other.values;
- transitions = other.transitions;
- return *this;
+ bool isUndefined() const {
+ return value.isUndefined();
}
+private:
+ optional<mapbox::util::recursive_wrapper<UnevaluatedPaintProperty<T, Evaluator>>> prior;
+ TimePoint begin;
+ TimePoint end;
+ PropertyValue<T> value;
+};
+
+template <class T>
+class CascadingPaintProperty {
+public:
bool isUndefined() const {
return values.find(ClassID::Default) == values.end();
}
@@ -57,82 +88,119 @@ public:
transitions[klass ? ClassDictionary::Get().lookup(*klass) : ClassID::Default] = transition;
}
- void cascade(const CascadeParameters& params) {
- const bool overrideTransition = !params.transition.delay && !params.transition.duration;
- Duration delay = params.transition.delay.value_or(Duration::zero());
- Duration duration = params.transition.duration.value_or(Duration::zero());
+ template <class UnevaluatedPaintProperty>
+ UnevaluatedPaintProperty cascade(const CascadeParameters& params, UnevaluatedPaintProperty prior) const {
+ TransitionOptions transition;
+ PropertyValue<T> value;
for (const auto classID : params.classes) {
- if (values.find(classID) == values.end())
- continue;
-
- if (overrideTransition && transitions.find(classID) != transitions.end()) {
- const TransitionOptions& transition = transitions[classID];
- if (transition.delay) delay = *transition.delay;
- if (transition.duration) duration = *transition.duration;
+ if (values.find(classID) != values.end()) {
+ value = values.at(classID);
+ break;
}
-
- cascaded = std::make_unique<CascadedValue>(std::move(cascaded),
- params.now + delay,
- params.now + delay + duration,
- values.at(classID));
-
- break;
}
- assert(cascaded);
- }
+ for (const auto classID : params.classes) {
+ if (transitions.find(classID) != transitions.end()) {
+ transition = transitions.at(classID).reverseMerge(transition);
+ break;
+ }
+ }
- bool calculate(const CalculationParameters& parameters) {
- assert(cascaded);
- Evaluator<T> evaluator(parameters, defaultValue);
- value = cascaded->calculate(evaluator, parameters.now);
- return cascaded->prior.operator bool();
+ return UnevaluatedPaintProperty(std::move(value),
+ std::move(prior),
+ transition.reverseMerge(params.transition),
+ params.now);
}
- // TODO: remove / privatize
- operator T() const { return value; }
- Result value;
-
private:
- T defaultValue;
std::unordered_map<ClassID, PropertyValue<T>> values;
std::unordered_map<ClassID, TransitionOptions> transitions;
+};
- struct CascadedValue {
- CascadedValue(std::unique_ptr<CascadedValue> prior_,
- TimePoint begin_,
- TimePoint end_,
- PropertyValue<T> value_)
- : prior(std::move(prior_)),
- begin(std::move(begin_)),
- end(std::move(end_)),
- value(std::move(value_)) {
- }
+template <class T>
+class PaintProperty {
+public:
+ using ValueType = PropertyValue<T>;
+ using CascadingType = CascadingPaintProperty<T>;
+ using EvaluatorType = PropertyEvaluator<T>;
+ using UnevaluatedType = UnevaluatedPaintProperty<T, EvaluatorType>;
+ using EvaluatedType = T;
+};
- Result calculate(const Evaluator<T>& evaluator, const TimePoint& now) {
- Result finalValue = PropertyValue<T>::visit(value, evaluator);
- if (!prior) {
- // No prior value.
- return finalValue;
- } else if (now >= end) {
- // Transition from prior value is now complete.
- prior.reset();
- return finalValue;
- } else {
- // Interpolate between recursively-calculated prior value and final.
- float t = std::chrono::duration<float>(now - begin) / (end - begin);
- return util::interpolate(prior->calculate(evaluator, now), finalValue, util::DEFAULT_TRANSITION_EASE.solve(t, 0.001));
- }
- }
+template <class T>
+class CrossFadedPaintProperty {
+public:
+ using ValueType = PropertyValue<T>;
+ using CascadingType = CascadingPaintProperty<T>;
+ using EvaluatorType = CrossFadedPropertyEvaluator<T>;
+ using UnevaluatedType = UnevaluatedPaintProperty<T, EvaluatorType>;
+ using EvaluatedType = Faded<T>;
+};
- std::unique_ptr<CascadedValue> prior;
- TimePoint begin;
- TimePoint end;
- PropertyValue<T> value;
+template <class... Ps>
+class PaintProperties {
+public:
+ using Properties = TypeList<Ps...>;
+ using EvaluatedTypes = TypeList<typename Ps::EvaluatedType...>;
+ using UnevaluatedTypes = TypeList<typename Ps::UnevaluatedType...>;
+ using CascadingTypes = TypeList<typename Ps::CascadingType...>;
+
+ template <class TypeList>
+ using Tuple = IndexedTuple<Properties, TypeList>;
+
+ class Evaluated : public Tuple<EvaluatedTypes> {
+ public:
+ using Tuple<EvaluatedTypes>::Tuple;
+ };
+
+ class Unevaluated : public Tuple<UnevaluatedTypes> {
+ public:
+ using Tuple<UnevaluatedTypes>::Tuple;
};
- std::unique_ptr<CascadedValue> cascaded;
+ class Cascading : public Tuple<CascadingTypes> {
+ public:
+ using Tuple<CascadingTypes>::Tuple;
+ };
+
+ template <class P>
+ auto get(const optional<std::string>& klass) const {
+ return cascading.template get<P>().get(klass);
+ }
+
+ template <class P>
+ void set(const typename P::ValueType& value, const optional<std::string>& klass) {
+ cascading.template get<P>().set(value, klass);
+ }
+
+ void cascade(const CascadeParameters& parameters) {
+ unevaluated = Unevaluated {
+ cascading.template get<Ps>().cascade(parameters,
+ std::move(unevaluated.template get<Ps>()))...
+ };
+ }
+
+ template <class P>
+ auto evaluate(const PropertyEvaluationParameters& parameters) {
+ return unevaluated.template get<P>().evaluate(parameters, P::defaultValue());
+ }
+
+ void evaluate(const PropertyEvaluationParameters& parameters) {
+ evaluated = Evaluated {
+ evaluate<Ps>(parameters)...
+ };
+ }
+
+ bool hasTransition() const {
+ bool result = false;
+ util::ignore({ result |= unevaluated.template get<Ps>().hasTransition()... });
+ return result;
+ }
+
+ Cascading cascading;
+ Unevaluated unevaluated;
+ Evaluated evaluated;
};
} // namespace style
diff --git a/src/mbgl/style/parser.cpp b/src/mbgl/style/parser.cpp
index 059082980d..c6c6e50dd7 100644
--- a/src/mbgl/style/parser.cpp
+++ b/src/mbgl/style/parser.cpp
@@ -5,7 +5,7 @@
#include <mbgl/style/conversion/source.hpp>
#include <mbgl/style/conversion/layer.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
#include <mapbox/geojsonvt.hpp>
diff --git a/src/mbgl/style/calculation_parameters.hpp b/src/mbgl/style/property_evaluation_parameters.hpp
index e1f059c524..2591fc07a1 100644
--- a/src/mbgl/style/calculation_parameters.hpp
+++ b/src/mbgl/style/property_evaluation_parameters.hpp
@@ -6,12 +6,12 @@
namespace mbgl {
namespace style {
-class CalculationParameters {
+class PropertyEvaluationParameters {
public:
- explicit CalculationParameters(float z_)
+ explicit PropertyEvaluationParameters(float z_)
: z(z_) {}
- CalculationParameters(float z_,
+ PropertyEvaluationParameters(float z_,
TimePoint now_,
ZoomHistory zoomHistory_,
Duration defaultFadeDuration_)
diff --git a/src/mbgl/style/property_evaluator.cpp b/src/mbgl/style/property_evaluator.cpp
deleted file mode 100644
index abb3681efa..0000000000
--- a/src/mbgl/style/property_evaluator.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-#include <mbgl/style/property_evaluator.hpp>
-#include <mbgl/style/calculation_parameters.hpp>
-#include <mbgl/style/types.hpp>
-#include <mbgl/util/interpolate.hpp>
-#include <mbgl/util/chrono.hpp>
-#include <mbgl/util/color.hpp>
-
-#include <cmath>
-
-namespace mbgl {
-namespace style {
-
-template <typename T>
-T defaultStopsValue();
-
-template <> bool defaultStopsValue() { return true; }
-template <> float defaultStopsValue() { return 1.0f; }
-template <> Color defaultStopsValue() { return { 0, 0, 0, 1 }; }
-template <> std::vector<float> defaultStopsValue() { return {{ 1, 0 }}; }
-template <> std::vector<std::string> defaultStopsValue() { return {{}}; }
-template <> std::array<float, 2> defaultStopsValue() { return {{ 0, 0 }}; }
-template <> std::array<float, 4> defaultStopsValue() { return {{ 0, 0, 0, 0 }}; }
-
-template <> std::string defaultStopsValue() { return {}; }
-template <> TranslateAnchorType defaultStopsValue() { return {}; }
-template <> RotateAnchorType defaultStopsValue() { return {}; }
-template <> CirclePitchScaleType defaultStopsValue() { return {}; }
-template <> LineCapType defaultStopsValue() { return {}; }
-template <> LineJoinType defaultStopsValue() { return {}; }
-template <> SymbolPlacementType defaultStopsValue() { return {}; }
-template <> TextAnchorType defaultStopsValue() { return {}; }
-template <> TextJustifyType defaultStopsValue() { return {}; }
-template <> TextTransformType defaultStopsValue() { return {}; }
-template <> AlignmentType defaultStopsValue() { return {}; }
-template <> IconTextFitType defaultStopsValue() { return {}; };
-
-template <typename T>
-T PropertyEvaluator<T>::operator()(const Function<T>& fn) const {
- float base = fn.getBase();
- const std::vector<std::pair<float, T>>& stops = fn.getStops();
- float z = parameters.z;
- bool smaller = false;
- float smaller_z = 0.0f;
- T smaller_val = T();
- bool larger = false;
- float larger_z = 0.0f;
- T larger_val = T();
-
- for (uint32_t i = 0; i < stops.size(); i++) {
- float stop_z = stops[i].first;
- T stop_val = stops[i].second;
- if (stop_z <= z && (!smaller || smaller_z < stop_z)) {
- smaller = true;
- smaller_z = stop_z;
- smaller_val = stop_val;
- }
- if (stop_z >= z && (!larger || larger_z > stop_z)) {
- larger = true;
- larger_z = stop_z;
- larger_val = stop_val;
- }
- }
-
- if (smaller && larger) {
- if (larger_z == smaller_z || larger_val == smaller_val) {
- return smaller_val;
- }
- const float zoomDiff = larger_z - smaller_z;
- const float zoomProgress = z - smaller_z;
- if (base == 1.0f) {
- const float t = zoomProgress / zoomDiff;
- return util::interpolate(smaller_val, larger_val, t);
- } else {
- const float t = (std::pow(base, zoomProgress) - 1) / (std::pow(base, zoomDiff) - 1);
- return util::interpolate(smaller_val, larger_val, t);
- }
- } else if (larger) {
- return larger_val;
- } else if (smaller) {
- return smaller_val;
- } else {
- // No stop defined.
- return defaultStopsValue<T>();
- }
-}
-
-template class PropertyEvaluator<bool>;
-template class PropertyEvaluator<float>;
-template class PropertyEvaluator<Color>;
-template class PropertyEvaluator<std::vector<float>>;
-template class PropertyEvaluator<std::vector<std::string>>;
-template class PropertyEvaluator<std::array<float, 2>>;
-template class PropertyEvaluator<std::array<float, 4>>;
-
-template class PropertyEvaluator<std::string>;
-template class PropertyEvaluator<TranslateAnchorType>;
-template class PropertyEvaluator<RotateAnchorType>;
-template class PropertyEvaluator<CirclePitchScaleType>;
-template class PropertyEvaluator<LineCapType>;
-template class PropertyEvaluator<LineJoinType>;
-template class PropertyEvaluator<SymbolPlacementType>;
-template class PropertyEvaluator<TextAnchorType>;
-template class PropertyEvaluator<TextJustifyType>;
-template class PropertyEvaluator<TextTransformType>;
-template class PropertyEvaluator<AlignmentType>;
-template class PropertyEvaluator<IconTextFitType>;
-
-template <typename T>
-Faded<T> CrossFadedPropertyEvaluator<T>::operator()(const Undefined&) const {
- return calculate(defaultValue, defaultValue, defaultValue);
-}
-
-template <typename T>
-Faded<T> CrossFadedPropertyEvaluator<T>::operator()(const T& constant) const {
- return calculate(constant, constant, constant);
-}
-
-template <typename T>
-T getBiggestStopLessThan(const Function<T>& function, float z) {
- const auto& stops = function.getStops();
- for (uint32_t i = 0; i < stops.size(); i++) {
- if (stops[i].first > z) {
- return stops[i == 0 ? i : i - 1].second;
- }
- }
- return stops.at(stops.size() - 1).second;
-}
-
-template <typename T>
-Faded<T> CrossFadedPropertyEvaluator<T>::operator()(const Function<T>& function) const {
- return calculate(getBiggestStopLessThan(function, parameters.z - 1.0f),
- getBiggestStopLessThan(function, parameters.z),
- getBiggestStopLessThan(function, parameters.z + 1.0f));
-}
-
-template <typename T>
-Faded<T> CrossFadedPropertyEvaluator<T>::calculate(const T& min, const T& mid, const T& max) const {
- const float z = parameters.z;
- const float fraction = z - std::floor(z);
- const std::chrono::duration<float> d = parameters.defaultFadeDuration;
- const float t = std::min((parameters.now - parameters.zoomHistory.lastIntegerZoomTime) / d, 1.0f);
-
- return z > parameters.zoomHistory.lastIntegerZoom
- ? Faded<T> { min, mid, 2.0f, 1.0f, fraction + (1.0f - fraction) * t }
- : Faded<T> { max, mid, 0.5f, 1.0f, 1 - (1 - t) * fraction };
-}
-
-template class CrossFadedPropertyEvaluator<std::string>;
-template class CrossFadedPropertyEvaluator<std::vector<float>>;
-
-} // namespace style
-} // namespace mbgl
diff --git a/src/mbgl/style/property_evaluator.hpp b/src/mbgl/style/property_evaluator.hpp
index a0bce2f499..ca4962d948 100644
--- a/src/mbgl/style/property_evaluator.hpp
+++ b/src/mbgl/style/property_evaluator.hpp
@@ -1,66 +1,28 @@
#pragma once
#include <mbgl/style/property_value.hpp>
-#include <mbgl/util/interpolate.hpp>
+#include <mbgl/style/property_evaluation_parameters.hpp>
namespace mbgl {
namespace style {
-class CalculationParameters;
-
template <typename T>
class PropertyEvaluator {
public:
using ResultType = T;
- PropertyEvaluator(const CalculationParameters& parameters_, T defaultValue_)
+ PropertyEvaluator(const PropertyEvaluationParameters& parameters_, T defaultValue_)
: parameters(parameters_),
defaultValue(std::move(defaultValue_)) {}
T operator()(const Undefined&) const { return defaultValue; }
T operator()(const T& constant) const { return constant; }
- T operator()(const Function<T>&) const;
+ T operator()(const Function<T>& fn) const { return fn.evaluate(parameters.z); }
private:
- const CalculationParameters& parameters;
- T defaultValue;
-};
-
-template <typename T>
-struct Faded {
- T from;
- T to;
- float fromScale;
- float toScale;
- float t;
-};
-
-template <typename T>
-class CrossFadedPropertyEvaluator {
-public:
- using ResultType = Faded<T>;
-
- CrossFadedPropertyEvaluator(const CalculationParameters& parameters_, T defaultValue_)
- : parameters(parameters_),
- defaultValue(std::move(defaultValue_)) {}
-
- Faded<T> operator()(const Undefined&) const;
- Faded<T> operator()(const T& constant) const;
- Faded<T> operator()(const Function<T>&) const;
-
-private:
- Faded<T> calculate(const T& min, const T& mid, const T& max) const;
-
- const CalculationParameters& parameters;
+ const PropertyEvaluationParameters& parameters;
T defaultValue;
};
} // namespace style
-
-namespace util {
-template <typename T>
-struct Interpolator<style::Faded<T>>
- : Uninterpolated {};
-} // namespace util
-
} // namespace mbgl
diff --git a/src/mbgl/style/property_parsing.hpp b/src/mbgl/style/property_parsing.hpp
index 8c2bd2c0f4..b542c8ae47 100644
--- a/src/mbgl/style/property_parsing.hpp
+++ b/src/mbgl/style/property_parsing.hpp
@@ -5,7 +5,7 @@
#include <mbgl/style/rapidjson_conversion.hpp>
#include <mbgl/style/conversion/property_value.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
namespace mbgl {
namespace style {
diff --git a/src/mbgl/style/source_impl.cpp b/src/mbgl/style/source_impl.cpp
index d0ae54092d..149bf99f9d 100644
--- a/src/mbgl/style/source_impl.cpp
+++ b/src/mbgl/style/source_impl.cpp
@@ -6,7 +6,7 @@
#include <mbgl/style/update_parameters.hpp>
#include <mbgl/style/query_parameters.hpp>
#include <mbgl/text/placement_config.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
#include <mbgl/math/clamp.hpp>
#include <mbgl/util/tile_cover.hpp>
#include <mbgl/util/enum.hpp>
@@ -70,11 +70,13 @@ void Source::Impl::startRender(algorithm::ClipIDGenerator& generator,
void Source::Impl::finishRender(Painter& painter) {
for (auto& pair : renderTiles) {
auto& tile = pair.second;
- painter.renderTileDebug(tile);
+ if (tile.used) {
+ painter.renderTileDebug(tile);
+ }
}
}
-const std::map<UnwrappedTileID, RenderTile>& Source::Impl::getRenderTiles() const {
+std::map<UnwrappedTileID, RenderTile>& Source::Impl::getRenderTiles() {
return renderTiles;
}
@@ -139,13 +141,26 @@ void Source::Impl::updateTiles(const UpdateParameters& parameters) {
if (type != SourceType::Annotations && cache.getSize() == 0) {
size_t conservativeCacheSize =
- std::max((float)parameters.transformState.getWidth() / util::tileSize, 1.0f) *
- std::max((float)parameters.transformState.getHeight() / util::tileSize, 1.0f) *
+ std::max((float)parameters.transformState.getSize().width / util::tileSize, 1.0f) *
+ std::max((float)parameters.transformState.getSize().height / util::tileSize, 1.0f) *
(parameters.transformState.getMaxZoom() - parameters.transformState.getMinZoom() + 1) *
0.5;
cache.setSize(conservativeCacheSize);
}
+ removeStaleTiles(retain);
+
+ const PlacementConfig config { parameters.transformState.getAngle(),
+ parameters.transformState.getPitch(),
+ parameters.debugOptions & MapDebugOptions::Collision };
+
+ for (auto& pair : tiles) {
+ pair.second->setPlacementConfig(config);
+ }
+}
+
+// Moves all tiles to the cache except for those specified in the retain set.
+void Source::Impl::removeStaleTiles(const std::set<OverscaledTileID>& retain) {
// Remove stale tiles. This goes through the (sorted!) tiles map and retain set in lockstep
// and removes items from tiles that don't have the corresponding key in the retain set.
auto tilesIt = tiles.begin();
@@ -162,13 +177,12 @@ void Source::Impl::updateTiles(const UpdateParameters& parameters) {
++retainIt;
}
}
+}
- const PlacementConfig config { parameters.transformState.getAngle(),
- parameters.transformState.getPitch(),
- parameters.debugOptions & MapDebugOptions::Collision };
-
- for (auto& pair : tiles) {
- pair.second->setPlacementConfig(config);
+void Source::Impl::removeTiles() {
+ renderTiles.clear();
+ if (!tiles.empty()) {
+ removeStaleTiles({});
}
}
@@ -196,7 +210,7 @@ std::unordered_map<std::string, std::vector<Feature>> Source::Impl::queryRendere
for (const auto& p : parameters.geometry) {
queryGeometry.push_back(TileCoordinate::fromScreenCoordinate(
- parameters.transformState, 0, { p.x, parameters.transformState.getHeight() - p.y }).p);
+ parameters.transformState, 0, { p.x, parameters.transformState.getSize().height - p.y }).p);
}
mapbox::geometry::box<double> box = mapbox::geometry::envelope(queryGeometry);
diff --git a/src/mbgl/style/source_impl.hpp b/src/mbgl/style/source_impl.hpp
index a4dd48444e..e6340ae1cb 100644
--- a/src/mbgl/style/source_impl.hpp
+++ b/src/mbgl/style/source_impl.hpp
@@ -63,7 +63,7 @@ public:
const TransformState&);
void finishRender(Painter&);
- const std::map<UnwrappedTileID, RenderTile>& getRenderTiles() const;
+ std::map<UnwrappedTileID, RenderTile>& getRenderTiles();
std::unordered_map<std::string, std::vector<Feature>>
queryRenderedFeatures(const QueryParameters&) const;
@@ -88,6 +88,7 @@ public:
protected:
void invalidateTiles();
+ void removeStaleTiles(const std::set<OverscaledTileID>&);
Source& base;
SourceObserver* observer = nullptr;
diff --git a/src/mbgl/style/sources/geojson_source_impl.cpp b/src/mbgl/style/sources/geojson_source_impl.cpp
index 4800b9c4be..7f41e0e321 100644
--- a/src/mbgl/style/sources/geojson_source_impl.cpp
+++ b/src/mbgl/style/sources/geojson_source_impl.cpp
@@ -1,4 +1,4 @@
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
#include <mbgl/storage/file_source.hpp>
#include <mbgl/style/conversion/geojson.hpp>
#include <mbgl/style/source_observer.hpp>
diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp
index d28963aa64..2d11d16b1f 100644
--- a/src/mbgl/style/style.cpp
+++ b/src/mbgl/style/style.cpp
@@ -8,6 +8,7 @@
#include <mbgl/style/layers/background_layer.hpp>
#include <mbgl/style/layers/background_layer_impl.hpp>
#include <mbgl/style/layers/fill_layer.hpp>
+#include <mbgl/style/layers/fill_extrusion_layer.hpp>
#include <mbgl/style/layers/line_layer.hpp>
#include <mbgl/style/layers/circle_layer.hpp>
#include <mbgl/style/layers/raster_layer.hpp>
@@ -18,7 +19,7 @@
#include <mbgl/style/class_dictionary.hpp>
#include <mbgl/style/update_parameters.hpp>
#include <mbgl/style/cascade_parameters.hpp>
-#include <mbgl/style/calculation_parameters.hpp>
+#include <mbgl/style/property_evaluation_parameters.hpp>
#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/text/glyph_atlas.hpp>
#include <mbgl/geometry/line_atlas.hpp>
@@ -26,7 +27,7 @@
#include <mbgl/renderer/render_tile.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/string.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
#include <mbgl/math/minmax.hpp>
#include <algorithm>
@@ -38,9 +39,9 @@ static Observer nullObserver;
Style::Style(FileSource& fileSource_, float pixelRatio)
: fileSource(fileSource_),
- glyphAtlas(std::make_unique<GlyphAtlas>(2048, 2048, fileSource)),
- spriteAtlas(std::make_unique<SpriteAtlas>(1024, 1024, pixelRatio)),
- lineAtlas(std::make_unique<LineAtlas>(256, 512)),
+ glyphAtlas(std::make_unique<GlyphAtlas>(Size{ 2048, 2048 }, fileSource)),
+ spriteAtlas(std::make_unique<SpriteAtlas>(Size{ 1024, 1024 }, pixelRatio)),
+ lineAtlas(std::make_unique<LineAtlas>(Size{ 256, 512 })),
observer(&nullObserver) {
glyphAtlas->setObserver(this);
spriteAtlas->setObserver(this);
@@ -262,7 +263,9 @@ double Style::getDefaultPitch() const {
void Style::updateTiles(const UpdateParameters& parameters) {
for (const auto& source : sources) {
- source->baseImpl->updateTiles(parameters);
+ if (source->baseImpl->enabled) {
+ source->baseImpl->updateTiles(parameters);
+ }
}
}
@@ -275,8 +278,9 @@ void Style::updateSymbolDependentTiles() {
void Style::relayout() {
for (const auto& sourceID : updateBatch.sourceIDs) {
Source* source = getSource(sourceID);
- if (!source) continue;
- source->baseImpl->reloadTiles();
+ if (source && source->baseImpl->enabled) {
+ source->baseImpl->reloadTiles();
+ }
}
updateBatch.sourceIDs.clear();
}
@@ -291,7 +295,6 @@ void Style::cascade(const TimePoint& timePoint, MapMode mode) {
classIDs.push_back(ClassDictionary::Get().lookup(className));
}
classIDs.push_back(ClassID::Default);
- classIDs.push_back(ClassID::Fallback);
const CascadeParameters parameters {
classIDs,
@@ -305,13 +308,15 @@ void Style::cascade(const TimePoint& timePoint, MapMode mode) {
}
void Style::recalculate(float z, const TimePoint& timePoint, MapMode mode) {
+ // Disable all sources first. If we find an enabled layer that uses this source, we will
+ // re-enable it later.
for (const auto& source : sources) {
source->baseImpl->enabled = false;
}
zoomHistory.update(z, timePoint);
- const CalculationParameters parameters {
+ const PropertyEvaluationParameters parameters {
z,
mode == MapMode::Continuous ? timePoint : Clock::time_point::max(),
zoomHistory,
@@ -320,7 +325,7 @@ void Style::recalculate(float z, const TimePoint& timePoint, MapMode mode) {
hasPendingTransitions = false;
for (const auto& layer : layers) {
- const bool hasTransitions = layer->baseImpl->recalculate(parameters);
+ const bool hasTransitions = layer->baseImpl->evaluate(parameters);
// Disable this layer if it doesn't need to be rendered.
const bool needsRendering = layer->baseImpl->needsRendering(zoomHistory.lastZoom);
@@ -338,6 +343,13 @@ void Style::recalculate(float z, const TimePoint& timePoint, MapMode mode) {
}
}
}
+
+ // Remove the existing tiles if we didn't end up re-enabling the source.
+ for (const auto& source : sources) {
+ if (!source->baseImpl->enabled) {
+ source->baseImpl->removeTiles();
+ }
+ }
}
std::vector<const Source*> Style::getSources() const {
@@ -388,7 +400,7 @@ bool Style::isLoaded() const {
return true;
}
-RenderData Style::getRenderData(MapDebugOptions debugOptions) const {
+RenderData Style::getRenderData(MapDebugOptions debugOptions, float angle) const {
RenderData result;
for (const auto& source : sources) {
@@ -397,6 +409,9 @@ RenderData Style::getRenderData(MapDebugOptions debugOptions) const {
}
}
+ const bool isLeft = std::abs(angle) > M_PI_2;
+ const bool isBottom = angle < 0;
+
for (const auto& layer : layers) {
if (!layer->baseImpl->needsRendering(zoomHistory.lastZoom)) {
continue;
@@ -408,10 +423,10 @@ RenderData Style::getRenderData(MapDebugOptions debugOptions) const {
result.order.emplace_back(*layer);
continue;
}
- const BackgroundPaintProperties& paint = background->impl->paint;
- if (layer.get() == layers[0].get() && paint.backgroundPattern.value.from.empty()) {
+ const BackgroundPaintProperties::Evaluated& paint = background->impl->paint.evaluated;
+ if (layer.get() == layers[0].get() && paint.get<BackgroundPattern>().from.empty()) {
// This is a solid background. We can use glClear().
- result.backgroundColor = paint.backgroundColor * paint.backgroundOpacity;
+ result.backgroundColor = paint.get<BackgroundColor>() * paint.get<BackgroundOpacity>();
} else {
// This is a textured background, or not the bottommost layer. We need to render it with a quad.
result.order.emplace_back(*layer);
@@ -430,8 +445,29 @@ RenderData Style::getRenderData(MapDebugOptions debugOptions) const {
continue;
}
- for (auto& pair : source->baseImpl->getRenderTiles()) {
- auto& tile = pair.second;
+ auto& renderTiles = source->baseImpl->getRenderTiles();
+ const bool symbolLayer = layer->is<SymbolLayer>();
+
+ // Sort symbol tiles in opposite y position, so tiles with overlapping
+ // symbols are drawn on top of each other, with lower symbols being
+ // drawn on top of higher symbols.
+ std::vector<std::reference_wrapper<RenderTile>> sortedTiles;
+ std::transform(renderTiles.begin(), renderTiles.end(), std::back_inserter(sortedTiles),
+ [](auto& pair) { return std::ref(pair.second); });
+ if (symbolLayer) {
+ std::sort(sortedTiles.begin(), sortedTiles.end(),
+ [isLeft, isBottom](const RenderTile& a, const RenderTile& b) {
+ bool sortX = a.id.canonical.x > b.id.canonical.x;
+ bool sortW = a.id.wrap > b.id.wrap;
+ bool sortY = a.id.canonical.y > b.id.canonical.y;
+ return
+ a.id.canonical.y != b.id.canonical.y ? (isLeft ? sortY : !sortY) :
+ a.id.wrap != b.id.wrap ? (isBottom ? sortW : !sortW) : (isBottom ? sortX : !sortX);
+ });
+ }
+
+ for (auto& tileRef : sortedTiles) {
+ auto& tile = tileRef.get();
if (!tile.tile.isRenderable()) {
continue;
}
@@ -439,7 +475,7 @@ RenderData Style::getRenderData(MapDebugOptions debugOptions) const {
// We're not clipping symbol layers, so when we have both parents and children of symbol
// layers, we drop all children in favor of their parent to avoid duplicate labels.
// See https://github.com/mapbox/mapbox-gl-native/issues/2482
- if (layer->is<SymbolLayer>()) {
+ if (symbolLayer) {
bool skip = false;
// Look back through the buckets we decided to render to find out whether there is
// already a bucket from this layer that is a parent of this tile. Tiles are ordered
@@ -458,6 +494,7 @@ RenderData Style::getRenderData(MapDebugOptions debugOptions) const {
auto bucket = tile.tile.getBucket(*layer);
if (bucket) {
result.order.emplace_back(*layer, &tile, bucket);
+ tile.used = true;
}
}
}
diff --git a/src/mbgl/style/style.hpp b/src/mbgl/style/style.hpp
index 1da22b8cf3..d46e80e8bf 100644
--- a/src/mbgl/style/style.hpp
+++ b/src/mbgl/style/style.hpp
@@ -93,7 +93,7 @@ public:
bool hasClass(const std::string&) const;
std::vector<std::string> getClasses() const;
- RenderData getRenderData(MapDebugOptions) const;
+ RenderData getRenderData(MapDebugOptions, float angle) const;
std::vector<Feature> queryRenderedFeatures(const QueryParameters&) const;
@@ -118,9 +118,9 @@ private:
// Defaults
std::string name;
LatLng defaultLatLng;
- double defaultZoom;
- double defaultBearing;
- double defaultPitch;
+ double defaultZoom = 0;
+ double defaultBearing = 0;
+ double defaultPitch = 0;
std::vector<std::unique_ptr<Layer>>::const_iterator findLayer(const std::string& layerID) const;
void reloadLayerSource(Layer&);
diff --git a/src/mbgl/text/bidi.hpp b/src/mbgl/text/bidi.hpp
new file mode 100644
index 0000000000..6c209c427c
--- /dev/null
+++ b/src/mbgl/text/bidi.hpp
@@ -0,0 +1,46 @@
+#pragma once
+
+#include <set>
+#include <string>
+#include <vector>
+#include <memory>
+
+#include <mbgl/util/noncopyable.hpp>
+
+namespace mbgl {
+
+class BiDi;
+class BiDiImpl;
+
+std::u16string applyArabicShaping(const std::u16string&);
+
+class ProcessedBiDiText {
+public:
+ ProcessedBiDiText(BiDi&);
+
+ std::vector<std::u16string> applyLineBreaking(std::set<int32_t>);
+
+private:
+ void mergeParagraphLineBreaks(std::set<int32_t>&);
+
+ BiDi& bidi;
+};
+
+class BiDi : private util::noncopyable {
+public:
+ BiDi();
+ ~BiDi();
+
+ // Calling processText resets internal state, invalidating any existing ProcessedBiDiText
+ // objects
+ ProcessedBiDiText processText(const std::u16string&);
+
+ friend class ProcessedBiDiText;
+
+private:
+ std::u16string getLine(int32_t start, int32_t end);
+
+ std::unique_ptr<BiDiImpl> impl;
+};
+
+} // end namespace mbgl
diff --git a/src/mbgl/text/collision_tile.cpp b/src/mbgl/text/collision_tile.cpp
index e485fbf36c..419ab31a79 100644
--- a/src/mbgl/text/collision_tile.cpp
+++ b/src/mbgl/text/collision_tile.cpp
@@ -1,5 +1,6 @@
#include <mbgl/text/collision_tile.hpp>
#include <mbgl/geometry/feature_index.hpp>
+#include <mbgl/math/log2.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/math.hpp>
#include <mbgl/math/minmax.hpp>
diff --git a/src/mbgl/text/get_anchors.cpp b/src/mbgl/text/get_anchors.cpp
index ce45e05d9c..b912c7763e 100644
--- a/src/mbgl/text/get_anchors.cpp
+++ b/src/mbgl/text/get_anchors.cpp
@@ -72,6 +72,7 @@ Anchors getAnchors(const GeometryCoordinates &line, float spacing,
const float maxAngle, const float textLeft, const float textRight,
const float iconLeft, const float iconRight,
const float glyphSize, const float boxScale, const float overscaling) {
+ if (line.empty()) return {};
// Resample a line to get anchor points for labels and check that each
// potential label passes text-max-angle check and has enough froom to fit
diff --git a/src/mbgl/text/glyph.cpp b/src/mbgl/text/glyph.cpp
index a877d7a799..29929b73e6 100644
--- a/src/mbgl/text/glyph.cpp
+++ b/src/mbgl/text/glyph.cpp
@@ -3,7 +3,7 @@
namespace mbgl {
// Note: this only works for the BMP
-GlyphRange getGlyphRange(char32_t glyph) {
+GlyphRange getGlyphRange(char16_t glyph) {
unsigned start = (glyph/256) * 256;
unsigned end = (start + 255);
if (start > 65280) start = 65280;
diff --git a/src/mbgl/text/glyph.hpp b/src/mbgl/text/glyph.hpp
index 975dc4ad23..d07fbdff21 100644
--- a/src/mbgl/text/glyph.hpp
+++ b/src/mbgl/text/glyph.hpp
@@ -11,10 +11,10 @@
namespace mbgl {
// Note: this only works for the BMP
-GlyphRange getGlyphRange(char32_t glyph);
+GlyphRange getGlyphRange(char16_t glyph);
struct GlyphMetrics {
- operator bool() const {
+ explicit operator bool() const {
return !(width == 0 && height == 0 && advance == 0);
}
@@ -27,12 +27,20 @@ struct GlyphMetrics {
};
+inline bool operator==(const GlyphMetrics& lhs, const GlyphMetrics& rhs) {
+ return lhs.width == rhs.width &&
+ lhs.height == rhs.height &&
+ lhs.left == rhs.left &&
+ lhs.top == rhs.top &&
+ lhs.advance == rhs.advance;
+}
+
struct Glyph {
explicit Glyph() : rect(0, 0, 0, 0), metrics() {}
explicit Glyph(Rect<uint16_t> rect_, GlyphMetrics metrics_)
: rect(std::move(rect_)), metrics(std::move(metrics_)) {}
- operator bool() const {
+ explicit operator bool() const {
return metrics || rect.hasArea();
}
@@ -55,16 +63,16 @@ public:
class Shaping {
public:
explicit Shaping() : top(0), bottom(0), left(0), right(0) {}
- explicit Shaping(float x, float y, std::u32string text_)
+ explicit Shaping(float x, float y, std::u16string text_)
: text(std::move(text_)), top(y), bottom(y), left(x), right(x) {}
std::vector<PositionedGlyph> positionedGlyphs;
- std::u32string text;
+ std::u16string text;
int32_t top;
int32_t bottom;
int32_t left;
int32_t right;
- operator bool() const { return !positionedGlyphs.empty(); }
+ explicit operator bool() const { return !positionedGlyphs.empty(); }
};
class SDFGlyph {
diff --git a/src/mbgl/text/glyph_atlas.cpp b/src/mbgl/text/glyph_atlas.cpp
index 2f8c44db59..5d30dacdce 100644
--- a/src/mbgl/text/glyph_atlas.cpp
+++ b/src/mbgl/text/glyph_atlas.cpp
@@ -1,10 +1,9 @@
#include <mbgl/text/glyph_atlas.hpp>
#include <mbgl/text/glyph_atlas_observer.hpp>
#include <mbgl/text/glyph_pbf.hpp>
-#include <mbgl/gl/gl.hpp>
#include <mbgl/gl/context.hpp>
-#include <mbgl/platform/log.hpp>
-#include <mbgl/platform/platform.hpp>
+#include <mbgl/util/logging.hpp>
+#include <mbgl/util/platform.hpp>
#include <cassert>
#include <algorithm>
@@ -13,13 +12,11 @@ namespace mbgl {
static GlyphAtlasObserver nullObserver;
-GlyphAtlas::GlyphAtlas(uint16_t width_, uint16_t height_, FileSource& fileSource_)
- : width(width_),
- height(height_),
- fileSource(fileSource_),
+GlyphAtlas::GlyphAtlas(const Size size, FileSource& fileSource_)
+ : fileSource(fileSource_),
observer(&nullObserver),
- bin(width_, height_),
- data(std::make_unique<uint8_t[]>(width_ * height_)),
+ bin(size.width, size.height),
+ image(size),
dirty(true) {
}
@@ -84,7 +81,7 @@ void GlyphAtlas::setObserver(GlyphAtlasObserver* observer_) {
}
void GlyphAtlas::addGlyphs(uintptr_t tileUID,
- const std::u32string& text,
+ const std::u16string& text,
const FontStack& fontStack,
const GlyphSet& glyphSet,
GlyphPositions& face)
@@ -93,7 +90,7 @@ void GlyphAtlas::addGlyphs(uintptr_t tileUID,
const std::map<uint32_t, SDFGlyph>& sdfs = glyphSet.getSDFs();
- for (uint32_t chr : text)
+ for (char16_t chr : text)
{
auto sdf_it = sdfs.find(chr);
if (sdf_it == sdfs.end()) {
@@ -148,18 +145,18 @@ Rect<uint16_t> GlyphAtlas::addGlyph(uintptr_t tileUID,
return rect;
}
- assert(rect.x + rect.w <= width);
- assert(rect.y + rect.h <= height);
+ assert(rect.x + rect.w <= image.size.width);
+ assert(rect.y + rect.h <= image.size.height);
face.emplace(glyph.id, GlyphValue { rect, tileUID });
// Copy the bitmap
const uint8_t* source = reinterpret_cast<const uint8_t*>(glyph.bitmap.data());
for (uint32_t y = 0; y < buffered_height; y++) {
- uint32_t y1 = width * (rect.y + y + padding) + rect.x + padding;
+ uint32_t y1 = image.size.width * (rect.y + y + padding) + rect.x + padding;
uint32_t y2 = buffered_width * y;
for (uint32_t x = 0; x < buffered_width; x++) {
- data[y1 + x] = source[y2 + x];
+ image.data[y1 + x] = source[y2 + x];
}
}
@@ -181,9 +178,9 @@ void GlyphAtlas::removeGlyphs(uintptr_t tileUID) {
const Rect<uint16_t>& rect = value.rect;
// Clear out the bitmap.
- uint8_t *target = data.get();
+ uint8_t *target = image.data.get();
for (uint32_t y = 0; y < rect.h; y++) {
- uint32_t y1 = width * (rect.y + y) + rect.x;
+ uint32_t y1 = image.size.width * (rect.y + y) + rect.x;
for (uint32_t x = 0; x < rect.w; x++) {
target[y1 + x] = 0;
}
@@ -203,60 +200,25 @@ void GlyphAtlas::removeGlyphs(uintptr_t tileUID) {
}
}
+Size GlyphAtlas::getSize() const {
+ return image.size;
+}
+
void GlyphAtlas::upload(gl::Context& context, gl::TextureUnit unit) {
- if (dirty) {
- const bool first = !texture;
- bind(context, unit);
-
- std::lock_guard<std::mutex> lock(mtx);
-
- context.activeTexture = unit;
- if (first) {
- MBGL_CHECK_ERROR(glTexImage2D(
- GL_TEXTURE_2D, // GLenum target
- 0, // GLint level
- GL_ALPHA, // GLint internalformat
- width, // GLsizei width
- height, // GLsizei height
- 0, // GLint border
- GL_ALPHA, // GLenum format
- GL_UNSIGNED_BYTE, // GLenum type
- data.get() // const GLvoid* data
- ));
- } else {
- MBGL_CHECK_ERROR(glTexSubImage2D(
- GL_TEXTURE_2D, // GLenum target
- 0, // GLint level
- 0, // GLint xoffset
- 0, // GLint yoffset
- width, // GLsizei width
- height, // GLsizei height
- GL_ALPHA, // GLenum format
- GL_UNSIGNED_BYTE, // GLenum type
- data.get() // const GLvoid* data
- ));
- }
+ std::lock_guard<std::mutex> lock(mtx);
- dirty = false;
+ if (!texture) {
+ texture = context.createTexture(image, unit);
+ } else if (dirty) {
+ context.updateTexture(*texture, image, unit);
}
+
+ dirty = false;
}
void GlyphAtlas::bind(gl::Context& context, gl::TextureUnit unit) {
- if (!texture) {
- texture = context.createTexture();
- context.activeTexture = unit;
- context.texture[unit] = *texture;
-#if not MBGL_USE_GLES2
- MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
-#endif
- MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
- MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
- MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
- MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
- } else if (context.texture[unit] != *texture) {
- context.activeTexture = unit;
- context.texture[unit] = *texture;
- }
+ upload(context, unit);
+ context.bindTexture(*texture, unit, gl::TextureFilter::Linear);
}
} // namespace mbgl
diff --git a/src/mbgl/text/glyph_atlas.hpp b/src/mbgl/text/glyph_atlas.hpp
index 84875bdd78..af14aace5b 100644
--- a/src/mbgl/text/glyph_atlas.hpp
+++ b/src/mbgl/text/glyph_atlas.hpp
@@ -8,6 +8,8 @@
#include <mbgl/util/font_stack.hpp>
#include <mbgl/util/exclusive.hpp>
#include <mbgl/util/work_queue.hpp>
+#include <mbgl/util/image.hpp>
+#include <mbgl/gl/texture.hpp>
#include <mbgl/gl/object.hpp>
#include <atomic>
@@ -30,7 +32,7 @@ class Context;
class GlyphAtlas : public util::noncopyable {
public:
- GlyphAtlas(uint16_t width, uint16_t height, FileSource&);
+ GlyphAtlas(Size, FileSource&);
~GlyphAtlas();
util::exclusive<GlyphSet> getGlyphSet(const FontStack&);
@@ -53,7 +55,7 @@ public:
void setObserver(GlyphAtlasObserver* observer);
void addGlyphs(uintptr_t tileUID,
- const std::u32string& text,
+ const std::u16string& text,
const FontStack&,
const GlyphSet&,
GlyphPositions&);
@@ -66,8 +68,7 @@ public:
// the texture is only bound when the data is out of date (=dirty).
void upload(gl::Context&, gl::TextureUnit unit);
- const uint16_t width;
- const uint16_t height;
+ Size getSize() const;
private:
void requestGlyphRange(const FontStack&, const GlyphRange&);
@@ -100,9 +101,9 @@ private:
std::mutex mtx;
BinPack<uint16_t> bin;
std::unordered_map<FontStack, std::map<uint32_t, GlyphValue>, FontStackHash> index;
- const std::unique_ptr<uint8_t[]> data;
+ const AlphaImage image;
std::atomic<bool> dirty;
- mbgl::optional<gl::UniqueTexture> texture;
+ mbgl::optional<gl::Texture> texture;
};
} // namespace mbgl
diff --git a/src/mbgl/text/glyph_set.cpp b/src/mbgl/text/glyph_set.cpp
index 0875a83850..f1cb85a03a 100644
--- a/src/mbgl/text/glyph_set.cpp
+++ b/src/mbgl/text/glyph_set.cpp
@@ -1,7 +1,11 @@
-#include <mbgl/text/glyph_set.hpp>
-#include <mbgl/platform/log.hpp>
#include <mbgl/math/minmax.hpp>
+#include <mbgl/text/glyph_set.hpp>
+#include <mbgl/util/i18n.hpp>
+#include <mbgl/util/logging.hpp>
+
+#include <boost/algorithm/string.hpp>
+#include <algorithm>
#include <cassert>
namespace mbgl {
@@ -26,44 +30,47 @@ void GlyphSet::insert(uint32_t id, SDFGlyph&& glyph) {
}
}
-const std::map<uint32_t, SDFGlyph> &GlyphSet::getSDFs() const {
+const std::map<uint32_t, SDFGlyph>& GlyphSet::getSDFs() const {
return sdfs;
}
-const Shaping GlyphSet::getShaping(const std::u32string &string, const float maxWidth,
- const float lineHeight, const float horizontalAlign,
- const float verticalAlign, const float justify,
- const float spacing, const Point<float> &translate) const {
- Shaping shaping(translate.x * 24, translate.y * 24, string);
+const Shaping GlyphSet::getShaping(const std::u16string& logicalInput,
+ const float maxWidth,
+ const float lineHeight,
+ const float horizontalAlign,
+ const float verticalAlign,
+ const float justify,
+ const float spacing,
+ const Point<float>& translate,
+ BiDi& bidi) const {
- // the y offset *should* be part of the font metadata
- const int32_t yOffset = -17;
+ // The string stored in shaping.text is used for finding duplicates, but may end up quite
+ // different from the glyphs that get shown
+ Shaping shaping(translate.x * 24, translate.y * 24, logicalInput);
- float x = 0;
- const float y = yOffset;
+ ProcessedBiDiText processedText = bidi.processText(logicalInput);
- // Loop through all characters of this label and shape.
- for (uint32_t chr : string) {
- auto it = sdfs.find(chr);
- if (it != sdfs.end()) {
- shaping.positionedGlyphs.emplace_back(chr, x, y);
- x += it->second.metrics.advance + spacing;
- }
- }
+ std::vector<std::u16string> reorderedLines =
+ processedText.applyLineBreaking(determineLineBreaks(logicalInput, spacing, maxWidth));
- if (shaping.positionedGlyphs.empty())
- return shaping;
-
- lineWrap(shaping, lineHeight, maxWidth, horizontalAlign, verticalAlign, justify, translate);
+ shapeLines(shaping, reorderedLines, spacing, lineHeight, horizontalAlign, verticalAlign,
+ justify, translate);
return shaping;
}
-void align(Shaping &shaping, const float justify, const float horizontalAlign,
- const float verticalAlign, const uint32_t maxLineLength, const float lineHeight,
- const uint32_t line, const Point<float> &translate) {
- const float shiftX = (justify - horizontalAlign) * maxLineLength + ::round(translate.x * 24/* one em */);
- const float shiftY = (-verticalAlign * (line + 1) + 0.5) * lineHeight + ::round(translate.y * 24/* one em */);
+void align(Shaping& shaping,
+ const float justify,
+ const float horizontalAlign,
+ const float verticalAlign,
+ const float maxLineLength,
+ const float lineHeight,
+ const uint32_t lineCount,
+ const Point<float>& translate) {
+ const float shiftX =
+ (justify - horizontalAlign) * maxLineLength + ::round(translate.x * 24 /* one em */);
+ const float shiftY =
+ (-verticalAlign * lineCount + 0.5) * lineHeight + ::round(translate.y * 24 /* one em */);
for (auto& glyph : shaping.positionedGlyphs) {
glyph.x += shiftX;
@@ -71,9 +78,16 @@ void align(Shaping &shaping, const float justify, const float horizontalAlign,
}
}
-void justifyLine(std::vector<PositionedGlyph> &positionedGlyphs, const std::map<uint32_t, SDFGlyph> &sdfs, uint32_t start,
- uint32_t end, float justify) {
- PositionedGlyph &glyph = positionedGlyphs[end];
+// justify left = 0, right = 1, center = .5
+void justifyLine(std::vector<PositionedGlyph>& positionedGlyphs,
+ const std::map<uint32_t, SDFGlyph>& sdfs,
+ uint32_t start,
+ uint32_t end,
+ float justify) {
+ if (!justify)
+ return;
+
+ PositionedGlyph& glyph = positionedGlyphs[end];
auto it = sdfs.find(glyph.glyph);
if (it != sdfs.end()) {
const uint32_t lastAdvance = it->second.metrics.advance;
@@ -85,80 +99,122 @@ void justifyLine(std::vector<PositionedGlyph> &positionedGlyphs, const std::map<
}
}
-void GlyphSet::lineWrap(Shaping &shaping, const float lineHeight, const float maxWidth,
- const float horizontalAlign, const float verticalAlign,
- const float justify, const Point<float> &translate) const {
+float GlyphSet::determineIdeographicLineWidth(const std::u16string& logicalInput,
+ const float spacing,
+ float maxWidth) const {
+ float totalWidth = 0;
+
+ // totalWidth doesn't include the last character for magical tuning reasons. This makes the
+ // algorithm a little
+ // more agressive about trying to fit the text into fewer lines, taking advantage of the
+ // tolerance for going a little
+ // over maxWidth
+ for (uint32_t i = 0; i < logicalInput.size() - 1; i++) {
+ auto it = sdfs.find(logicalInput[i]);
+ if (it != sdfs.end())
+ totalWidth += it->second.metrics.advance + spacing;
+ }
+
+ int32_t lineCount = std::fmax(1, std::ceil(totalWidth / maxWidth));
+ return totalWidth / lineCount;
+}
+
+// We determine line breaks based on shaped text in logical order. Working in visual order would be
+// more intuitive, but we can't do that because the visual order may be changed by line breaks!
+std::set<int32_t> GlyphSet::determineLineBreaks(const std::u16string& logicalInput,
+ const float spacing,
+ float maxWidth) const {
+ if (!maxWidth)
+ return {};
+
+ if (logicalInput.empty())
+ return {};
+
+ if (util::i18n::allowsIdeographicBreaking(logicalInput))
+ maxWidth = determineIdeographicLineWidth(logicalInput, spacing, maxWidth);
+
+ std::set<int32_t> lineBreakPoints;
+ float currentX = 0;
uint32_t lastSafeBreak = 0;
+ float lastSafeBreakX = 0;
+
+ for (uint32_t i = 0; i < logicalInput.size(); i++) {
+ auto it = sdfs.find(logicalInput[i]);
+ if (it == sdfs.end())
+ continue;
+
+ const SDFGlyph& glyph = it->second;
- uint32_t lengthBeforeCurrentLine = 0;
- uint32_t lineStartIndex = 0;
- uint32_t line = 0;
-
- uint32_t maxLineLength = 0;
-
- std::vector<PositionedGlyph> &positionedGlyphs = shaping.positionedGlyphs;
-
- if (maxWidth) {
- for (uint32_t i = 0; i < positionedGlyphs.size(); i++) {
- PositionedGlyph &shape = positionedGlyphs[i];
-
- shape.x -= lengthBeforeCurrentLine;
- shape.y += lineHeight * line;
-
- if (shape.x > maxWidth && lastSafeBreak > 0) {
-
- uint32_t lineLength = positionedGlyphs[lastSafeBreak + 1].x;
- maxLineLength = util::max(lineLength, maxLineLength);
-
- for (uint32_t k = lastSafeBreak + 1; k <= i; k++) {
- positionedGlyphs[k].y += lineHeight;
- positionedGlyphs[k].x -= lineLength;
- }
-
- if (justify) {
- // Collapse invisible characters.
- uint32_t breakGlyph = positionedGlyphs[lastSafeBreak].glyph;
- uint32_t lineEnd = lastSafeBreak;
- if (breakGlyph == 0x20 /* space */
- || breakGlyph == 0x200b /* zero-width space */) {
- lineEnd--;
- }
-
- justifyLine(positionedGlyphs, sdfs, lineStartIndex, lineEnd, justify);
- }
-
- lineStartIndex = lastSafeBreak + 1;
- lastSafeBreak = 0;
- lengthBeforeCurrentLine += lineLength;
- line++;
- }
-
- // Spaces, plus word-breaking punctuation that often appears without surrounding spaces.
- if (shape.glyph == 0x20 /* space */
- || shape.glyph == 0x26 /* ampersand */
- || shape.glyph == 0x2b /* plus sign */
- || shape.glyph == 0x2d /* hyphen-minus */
- || shape.glyph == 0x2f /* solidus */
- || shape.glyph == 0xad /* soft hyphen */
- || shape.glyph == 0xb7 /* middle dot */
- || shape.glyph == 0x200b /* zero-width space */
- || shape.glyph == 0x2010 /* hyphen */
- || shape.glyph == 0x2013 /* en dash */) {
- lastSafeBreak = i;
- }
+ // Ideographic characters, spaces, and word-breaking punctuation that often appear without
+ // surrounding spaces.
+ if (util::i18n::allowsWordBreaking(glyph.id) ||
+ util::i18n::allowsIdeographicBreaking(glyph.id)) {
+ lastSafeBreak = i;
+ lastSafeBreakX = currentX;
}
+
+ if (currentX > maxWidth && lastSafeBreak > 0) {
+ lineBreakPoints.insert(lastSafeBreak);
+ currentX -= lastSafeBreakX;
+ lastSafeBreakX = 0;
+ }
+
+ currentX += glyph.metrics.advance + spacing;
}
- const PositionedGlyph& lastPositionedGlyph = positionedGlyphs.back();
- const auto lastGlyphIt = sdfs.find(lastPositionedGlyph.glyph);
- assert(lastGlyphIt != sdfs.end());
- const uint32_t lastLineLength = lastPositionedGlyph.x + lastGlyphIt->second.metrics.advance;
- maxLineLength = std::max(maxLineLength, lastLineLength);
+ return lineBreakPoints;
+}
+
+void GlyphSet::shapeLines(Shaping& shaping,
+ const std::vector<std::u16string>& lines,
+ const float spacing,
+ const float lineHeight,
+ const float horizontalAlign,
+ const float verticalAlign,
+ const float justify,
+ const Point<float>& translate) const {
+
+ // the y offset *should* be part of the font metadata
+ const int32_t yOffset = -17;
+
+ float x = 0;
+ float y = yOffset;
+
+ float maxLineLength = 0;
- const uint32_t height = (line + 1) * lineHeight;
+ for (std::u16string line : lines) {
+ // Collapse whitespace so it doesn't throw off justification
+ boost::algorithm::trim_if(line, boost::algorithm::is_any_of(u" \t\n\v\f\r"));
+
+ if (line.empty())
+ continue;
+
+ uint32_t lineStartIndex = static_cast<uint32_t>(shaping.positionedGlyphs.size());
+ for (char16_t chr : line) {
+ auto it = sdfs.find(chr);
+ if (it == sdfs.end())
+ continue;
+
+ const SDFGlyph& glyph = it->second;
+ shaping.positionedGlyphs.emplace_back(chr, x, y);
+ x += glyph.metrics.advance + spacing;
+ }
+
+ if (static_cast<uint32_t>(shaping.positionedGlyphs.size()) == lineStartIndex)
+ continue;
+
+ maxLineLength = util::max(x, maxLineLength);
+
+ justifyLine(shaping.positionedGlyphs, sdfs, lineStartIndex,
+ static_cast<uint32_t>(shaping.positionedGlyphs.size()) - 1, justify);
+
+ x = 0;
+ y += lineHeight; // Move to next line
+ }
- justifyLine(positionedGlyphs, sdfs, lineStartIndex, uint32_t(positionedGlyphs.size()) - 1, justify);
- align(shaping, justify, horizontalAlign, verticalAlign, maxLineLength, lineHeight, line, translate);
+ align(shaping, justify, horizontalAlign, verticalAlign, maxLineLength, lineHeight,
+ static_cast<uint32_t>(lines.size()), translate);
+ const uint32_t height = lines.size() * lineHeight;
// Calculate the bounding box
shaping.top += -verticalAlign * height;
diff --git a/src/mbgl/text/glyph_set.hpp b/src/mbgl/text/glyph_set.hpp
index 37ffdb070a..b48973b6ea 100644
--- a/src/mbgl/text/glyph_set.hpp
+++ b/src/mbgl/text/glyph_set.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include <mbgl/text/bidi.hpp>
#include <mbgl/text/glyph.hpp>
#include <mbgl/util/geometry.hpp>
@@ -8,14 +9,34 @@ namespace mbgl {
class GlyphSet {
public:
void insert(uint32_t id, SDFGlyph&&);
- const std::map<uint32_t, SDFGlyph> &getSDFs() const;
- const Shaping getShaping(const std::u32string &string, float maxWidth, float lineHeight,
- float horizontalAlign, float verticalAlign, float justify,
- float spacing, const Point<float> &translate) const;
- void lineWrap(Shaping &shaping, float lineHeight, float maxWidth, float horizontalAlign,
- float verticalAlign, float justify, const Point<float> &translate) const;
+ const std::map<uint32_t, SDFGlyph>& getSDFs() const;
+ const Shaping getShaping(const std::u16string& string,
+ float maxWidth,
+ float lineHeight,
+ float horizontalAlign,
+ float verticalAlign,
+ float justify,
+ float spacing,
+ const Point<float>& translate,
+ BiDi& bidi) const;
private:
+ float determineIdeographicLineWidth(const std::u16string& logicalInput,
+ const float spacing,
+ float maxWidth) const;
+ std::set<int32_t> determineLineBreaks(const std::u16string& logicalInput,
+ const float spacing,
+ float maxWidth) const;
+
+ void shapeLines(Shaping& shaping,
+ const std::vector<std::u16string>& lines,
+ const float spacing,
+ float lineHeight,
+ float horizontalAlign,
+ float verticalAlign,
+ float justify,
+ const Point<float>& translate) const;
+
std::map<uint32_t, SDFGlyph> sdfs;
};
diff --git a/src/mbgl/text/quads.cpp b/src/mbgl/text/quads.cpp
index 3f142cd908..1a05e6f94f 100644
--- a/src/mbgl/text/quads.cpp
+++ b/src/mbgl/text/quads.cpp
@@ -14,7 +14,7 @@ using namespace style;
const float globalMinScale = 0.5f; // underscale by 1 zoom level
SymbolQuads getIconQuads(Anchor& anchor, const PositionedIcon& shapedIcon,
- const GeometryCoordinates& line, const SymbolLayoutProperties& layout,
+ const GeometryCoordinates& line, const SymbolLayoutProperties::Evaluated& layout,
const style::SymbolPlacementType placement, const Shaping& shapedText) {
auto image = *(shapedIcon.image);
@@ -29,24 +29,24 @@ SymbolQuads getIconQuads(Anchor& anchor, const PositionedIcon& shapedIcon,
Point<float> br;
Point<float> bl;
- if (layout.iconTextFit != IconTextFitType::None && shapedText) {
+ if (layout.get<IconTextFit>() != IconTextFitType::None && shapedText) {
auto iconWidth = right - left;
auto iconHeight = bottom - top;
- auto size = layout.textSize / 24.0f;
+ auto size = layout.get<TextSize>() / 24.0f;
auto textLeft = shapedText.left * size;
auto textRight = shapedText.right * size;
auto textTop = shapedText.top * size;
auto textBottom = shapedText.bottom * size;
auto textWidth = textRight - textLeft;
auto textHeight = textBottom - textTop;;
- auto padT = layout.iconTextFitPadding.value[0];
- auto padR = layout.iconTextFitPadding.value[1];
- auto padB = layout.iconTextFitPadding.value[2];
- auto padL = layout.iconTextFitPadding.value[3];
- auto offsetY = layout.iconTextFit == IconTextFitType::Width ? (textHeight - iconHeight) * 0.5 : 0;
- auto offsetX = layout.iconTextFit == IconTextFitType::Height ? (textWidth - iconWidth) * 0.5 : 0;
- auto width = layout.iconTextFit == IconTextFitType::Width || layout.iconTextFit == IconTextFitType::Both ? textWidth : iconWidth;
- auto height = layout.iconTextFit == IconTextFitType::Height || layout.iconTextFit == IconTextFitType::Both ? textHeight : iconHeight;
+ auto padT = layout.get<IconTextFitPadding>()[0];
+ auto padR = layout.get<IconTextFitPadding>()[1];
+ auto padB = layout.get<IconTextFitPadding>()[2];
+ auto padL = layout.get<IconTextFitPadding>()[3];
+ auto offsetY = layout.get<IconTextFit>() == IconTextFitType::Width ? (textHeight - iconHeight) * 0.5 : 0;
+ auto offsetX = layout.get<IconTextFit>() == IconTextFitType::Height ? (textWidth - iconWidth) * 0.5 : 0;
+ auto width = layout.get<IconTextFit>() == IconTextFitType::Width || layout.get<IconTextFit>() == IconTextFitType::Both ? textWidth : iconWidth;
+ auto height = layout.get<IconTextFit>() == IconTextFitType::Height || layout.get<IconTextFit>() == IconTextFitType::Both ? textHeight : iconHeight;
left = textLeft + offsetX - padL;
top = textTop + offsetY - padT;
right = textLeft + offsetX + padR + width;
@@ -62,7 +62,7 @@ SymbolQuads getIconQuads(Anchor& anchor, const PositionedIcon& shapedIcon,
bl = {left, bottom};
}
- float angle = layout.iconRotate * util::DEG2RAD;
+ float angle = layout.get<IconRotate>() * util::DEG2RAD;
if (placement == style::SymbolPlacementType::Line) {
assert(static_cast<unsigned int>(anchor.segment) < line.size());
const GeometryCoordinate &prev= line[anchor.segment];
@@ -165,11 +165,11 @@ void getSegmentGlyphs(std::back_insert_iterator<GlyphInstances> glyphs, Anchor &
}
SymbolQuads getGlyphQuads(Anchor& anchor, const Shaping& shapedText,
- const float boxScale, const GeometryCoordinates& line, const SymbolLayoutProperties& layout,
+ const float boxScale, const GeometryCoordinates& line, const SymbolLayoutProperties::Evaluated& layout,
const style::SymbolPlacementType placement, const GlyphPositions& face) {
- const float textRotate = layout.textRotate * util::DEG2RAD;
- const bool keepUpright = layout.textKeepUpright;
+ const float textRotate = layout.get<TextRotate>() * util::DEG2RAD;
+ const bool keepUpright = layout.get<TextKeepUpright>();
SymbolQuads quads;
diff --git a/src/mbgl/text/quads.hpp b/src/mbgl/text/quads.hpp
index d4edbf9493..75fb53aade 100644
--- a/src/mbgl/text/quads.hpp
+++ b/src/mbgl/text/quads.hpp
@@ -2,6 +2,7 @@
#include <mbgl/text/glyph.hpp>
#include <mbgl/style/types.hpp>
+#include <mbgl/style/layers/symbol_layer_properties.hpp>
#include <mbgl/tile/geometry_tile_data.hpp>
#include <vector>
@@ -11,10 +12,6 @@ namespace mbgl {
struct Anchor;
class PositionedIcon;
-namespace style {
-class SymbolLayoutProperties;
-} // namespace style
-
struct SymbolQuad {
explicit SymbolQuad(Point<float> tl_, Point<float> tr_, Point<float> bl_, Point<float> br_,
Rect<uint16_t> tex_, float anchorAngle_, float glyphAngle_, Point<float> anchorPoint_,
@@ -40,11 +37,11 @@ struct SymbolQuad {
typedef std::vector<SymbolQuad> SymbolQuads;
SymbolQuads getIconQuads(Anchor& anchor, const PositionedIcon& shapedIcon,
- const GeometryCoordinates& line, const style::SymbolLayoutProperties&,
+ const GeometryCoordinates& line, const style::SymbolLayoutProperties::Evaluated&,
style::SymbolPlacementType placement, const Shaping& shapedText);
SymbolQuads getGlyphQuads(Anchor& anchor, const Shaping& shapedText,
- const float boxScale, const GeometryCoordinates& line, const style::SymbolLayoutProperties&,
+ const float boxScale, const GeometryCoordinates& line, const style::SymbolLayoutProperties::Evaluated&,
style::SymbolPlacementType placement, const GlyphPositions& face);
} // namespace mbgl
diff --git a/src/mbgl/text/shaping.cpp b/src/mbgl/text/shaping.cpp
index 1091cd6e94..062066aaf4 100644
--- a/src/mbgl/text/shaping.cpp
+++ b/src/mbgl/text/shaping.cpp
@@ -3,9 +3,11 @@
namespace mbgl {
-PositionedIcon shapeIcon(const SpriteAtlasElement& image, const style::SymbolLayoutProperties& layout) {
- float dx = layout.iconOffset.value[0];
- float dy = layout.iconOffset.value[1];
+using namespace style;
+
+PositionedIcon shapeIcon(const SpriteAtlasElement& image, const SymbolLayoutProperties::Evaluated& layout) {
+ float dx = layout.get<IconOffset>()[0];
+ float dy = layout.get<IconOffset>()[1];
float x1 = dx - image.spriteImage->getWidth() / 2.0f;
float x2 = x1 + image.spriteImage->getWidth();
float y1 = dy - image.spriteImage->getHeight() / 2.0f;
diff --git a/src/mbgl/text/shaping.hpp b/src/mbgl/text/shaping.hpp
index cd5e8105fd..30375179b6 100644
--- a/src/mbgl/text/shaping.hpp
+++ b/src/mbgl/text/shaping.hpp
@@ -3,15 +3,12 @@
#include <mbgl/text/glyph.hpp>
#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/sprite/sprite_image.hpp>
+#include <mbgl/style/layers/symbol_layer_properties.hpp>
#include <mbgl/util/optional.hpp>
namespace mbgl {
-struct SpriteAtlasElement;
-
-namespace style {
-class SymbolLayoutProperties;
-} // namespace style
+class SpriteAtlasElement;
class PositionedIcon {
public:
@@ -26,9 +23,9 @@ class PositionedIcon {
float left = 0;
float right = 0;
- operator bool() const { return image && (*image).pos.hasArea(); }
+ explicit operator bool() const { return image && (*image).pos.hasArea(); }
};
-PositionedIcon shapeIcon(const SpriteAtlasElement& image, const style::SymbolLayoutProperties&);
+PositionedIcon shapeIcon(const SpriteAtlasElement& image, const style::SymbolLayoutProperties::Evaluated&);
} // namespace mbgl
diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp
index 84455e4787..10c0e1b244 100644
--- a/src/mbgl/tile/geometry_tile.cpp
+++ b/src/mbgl/tile/geometry_tile.cpp
@@ -61,6 +61,12 @@ void GeometryTile::setPlacementConfig(const PlacementConfig& desiredConfig) {
return;
}
+ // Mark the tile as pending again if it was complete before to prevent signaling a complete
+ // state despite pending parse operations.
+ if (availableData == DataAvailability::All) {
+ availableData = DataAvailability::Some;
+ }
+
++correlationID;
requestedConfig = desiredConfig;
worker.invoke(&GeometryTileWorker::setPlacementConfig, desiredConfig, correlationID);
diff --git a/src/mbgl/tile/geometry_tile_worker.cpp b/src/mbgl/tile/geometry_tile_worker.cpp
index abb3894d34..738c78572d 100644
--- a/src/mbgl/tile/geometry_tile_worker.cpp
+++ b/src/mbgl/tile/geometry_tile_worker.cpp
@@ -8,7 +8,7 @@
#include <mbgl/style/layers/symbol_layer.hpp>
#include <mbgl/style/layers/symbol_layer_impl.hpp>
#include <mbgl/renderer/symbol_bucket.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/util/exception.hpp>
diff --git a/src/mbgl/tile/tile.cpp b/src/mbgl/tile/tile.cpp
index 1375263107..e84eaaf780 100644
--- a/src/mbgl/tile/tile.cpp
+++ b/src/mbgl/tile/tile.cpp
@@ -2,7 +2,7 @@
#include <mbgl/tile/tile_observer.hpp>
#include <mbgl/renderer/debug_bucket.hpp>
#include <mbgl/util/string.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
namespace mbgl {
diff --git a/src/mbgl/tile/tile.hpp b/src/mbgl/tile/tile.hpp
index eea89bd634..cebf913f56 100644
--- a/src/mbgl/tile/tile.hpp
+++ b/src/mbgl/tile/tile.hpp
@@ -75,9 +75,6 @@ public:
bool isComplete() const {
return availableData == DataAvailability::All;
}
- bool isIncomplete() const {
- return availableData == DataAvailability::Some;
- }
void dumpDebugLogs() const;
diff --git a/src/mbgl/platform/event.cpp b/src/mbgl/util/event.cpp
index 68d75a2941..3a3be20f5c 100644
--- a/src/mbgl/platform/event.cpp
+++ b/src/mbgl/util/event.cpp
@@ -1,4 +1,4 @@
-#include <mbgl/platform/event.hpp>
+#include <mbgl/util/event.hpp>
#include <mbgl/util/enum.hpp>
namespace mbgl {
diff --git a/src/mbgl/util/i18n.cpp b/src/mbgl/util/i18n.cpp
new file mode 100644
index 0000000000..4be624d2e5
--- /dev/null
+++ b/src/mbgl/util/i18n.cpp
@@ -0,0 +1,355 @@
+#include "i18n.hpp"
+
+namespace {
+
+/** Defines a function that returns true if a codepoint is in a named block.
+ @param name The name of the block in CamelCase.
+ @param first The first codepoint in the block, inclusive.
+ @param last The last codepoint in the block, inclusive.
+ */
+#define DEFINE_IS_IN_UNICODE_BLOCK(name, first, last) \
+ inline bool isIn##name(uint16_t codepoint) { \
+ return codepoint >= first && codepoint <= last; \
+ }
+
+// The following table comes from <http://www.unicode.org/Public/9.0.0/ucd/Blocks.txt>.
+// Keep it synchronized with <http://www.unicode.org/Public/UCD/latest/ucd/Blocks.txt>.
+
+// DEFINE_IS_IN_UNICODE_BLOCK(BasicLatin, 0x0000, 0x007F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Latin1Supplement, 0x0080, 0x00FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(LatinExtendedA, 0x0100, 0x017F)
+// DEFINE_IS_IN_UNICODE_BLOCK(LatinExtendedB, 0x0180, 0x024F)
+// DEFINE_IS_IN_UNICODE_BLOCK(IPAExtensions, 0x0250, 0x02AF)
+// DEFINE_IS_IN_UNICODE_BLOCK(SpacingModifierLetters, 0x02B0, 0x02FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(CombiningDiacriticalMarks, 0x0300, 0x036F)
+// DEFINE_IS_IN_UNICODE_BLOCK(GreekandCoptic, 0x0370, 0x03FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Cyrillic, 0x0400, 0x04FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(CyrillicSupplement, 0x0500, 0x052F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Armenian, 0x0530, 0x058F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Hebrew, 0x0590, 0x05FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Arabic, 0x0600, 0x06FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Syriac, 0x0700, 0x074F)
+// DEFINE_IS_IN_UNICODE_BLOCK(ArabicSupplement, 0x0750, 0x077F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Thaana, 0x0780, 0x07BF)
+// DEFINE_IS_IN_UNICODE_BLOCK(NKo, 0x07C0, 0x07FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Samaritan, 0x0800, 0x083F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Mandaic, 0x0840, 0x085F)
+// DEFINE_IS_IN_UNICODE_BLOCK(ArabicExtendedA, 0x08A0, 0x08FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Devanagari, 0x0900, 0x097F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Bengali, 0x0980, 0x09FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Gurmukhi, 0x0A00, 0x0A7F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Gujarati, 0x0A80, 0x0AFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Oriya, 0x0B00, 0x0B7F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Tamil, 0x0B80, 0x0BFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Telugu, 0x0C00, 0x0C7F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Kannada, 0x0C80, 0x0CFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Malayalam, 0x0D00, 0x0D7F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Sinhala, 0x0D80, 0x0DFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Thai, 0x0E00, 0x0E7F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Lao, 0x0E80, 0x0EFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Tibetan, 0x0F00, 0x0FFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Myanmar, 0x1000, 0x109F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Georgian, 0x10A0, 0x10FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(HangulJamo, 0x1100, 0x11FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Ethiopic, 0x1200, 0x137F)
+// DEFINE_IS_IN_UNICODE_BLOCK(EthiopicSupplement, 0x1380, 0x139F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Cherokee, 0x13A0, 0x13FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(UnifiedCanadianAboriginalSyllabics, 0x1400, 0x167F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Ogham, 0x1680, 0x169F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Runic, 0x16A0, 0x16FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Tagalog, 0x1700, 0x171F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Hanunoo, 0x1720, 0x173F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Buhid, 0x1740, 0x175F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Tagbanwa, 0x1760, 0x177F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Khmer, 0x1780, 0x17FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Mongolian, 0x1800, 0x18AF)
+// DEFINE_IS_IN_UNICODE_BLOCK(UnifiedCanadianAboriginalSyllabicsExtended, 0x18B0, 0x18FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Limbu, 0x1900, 0x194F)
+// DEFINE_IS_IN_UNICODE_BLOCK(TaiLe, 0x1950, 0x197F)
+// DEFINE_IS_IN_UNICODE_BLOCK(NewTaiLue, 0x1980, 0x19DF)
+// DEFINE_IS_IN_UNICODE_BLOCK(KhmerSymbols, 0x19E0, 0x19FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Buginese, 0x1A00, 0x1A1F)
+// DEFINE_IS_IN_UNICODE_BLOCK(TaiTham, 0x1A20, 0x1AAF)
+// DEFINE_IS_IN_UNICODE_BLOCK(CombiningDiacriticalMarksExtended, 0x1AB0, 0x1AFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Balinese, 0x1B00, 0x1B7F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Sundanese, 0x1B80, 0x1BBF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Batak, 0x1BC0, 0x1BFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Lepcha, 0x1C00, 0x1C4F)
+// DEFINE_IS_IN_UNICODE_BLOCK(OlChiki, 0x1C50, 0x1C7F)
+// DEFINE_IS_IN_UNICODE_BLOCK(CyrillicExtendedC, 0x1C80, 0x1C8F)
+// DEFINE_IS_IN_UNICODE_BLOCK(SundaneseSupplement, 0x1CC0, 0x1CCF)
+// DEFINE_IS_IN_UNICODE_BLOCK(VedicExtensions, 0x1CD0, 0x1CFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(PhoneticExtensions, 0x1D00, 0x1D7F)
+// DEFINE_IS_IN_UNICODE_BLOCK(PhoneticExtensionsSupplement, 0x1D80, 0x1DBF)
+// DEFINE_IS_IN_UNICODE_BLOCK(CombiningDiacriticalMarksSupplement, 0x1DC0, 0x1DFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(LatinExtendedAdditional, 0x1E00, 0x1EFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(GreekExtended, 0x1F00, 0x1FFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(GeneralPunctuation, 0x2000, 0x206F)
+// DEFINE_IS_IN_UNICODE_BLOCK(SuperscriptsandSubscripts, 0x2070, 0x209F)
+// DEFINE_IS_IN_UNICODE_BLOCK(CurrencySymbols, 0x20A0, 0x20CF)
+// DEFINE_IS_IN_UNICODE_BLOCK(CombiningDiacriticalMarksforSymbols, 0x20D0, 0x20FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(LetterlikeSymbols, 0x2100, 0x214F)
+// DEFINE_IS_IN_UNICODE_BLOCK(NumberForms, 0x2150, 0x218F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Arrows, 0x2190, 0x21FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(MathematicalOperators, 0x2200, 0x22FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(MiscellaneousTechnical, 0x2300, 0x23FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(ControlPictures, 0x2400, 0x243F)
+// DEFINE_IS_IN_UNICODE_BLOCK(OpticalCharacterRecognition, 0x2440, 0x245F)
+// DEFINE_IS_IN_UNICODE_BLOCK(EnclosedAlphanumerics, 0x2460, 0x24FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(BoxDrawing, 0x2500, 0x257F)
+// DEFINE_IS_IN_UNICODE_BLOCK(BlockElements, 0x2580, 0x259F)
+// DEFINE_IS_IN_UNICODE_BLOCK(GeometricShapes, 0x25A0, 0x25FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(MiscellaneousSymbols, 0x2600, 0x26FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Dingbats, 0x2700, 0x27BF)
+// DEFINE_IS_IN_UNICODE_BLOCK(MiscellaneousMathematicalSymbolsA, 0x27C0, 0x27EF)
+// DEFINE_IS_IN_UNICODE_BLOCK(SupplementalArrowsA, 0x27F0, 0x27FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(BraillePatterns, 0x2800, 0x28FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(SupplementalArrowsB, 0x2900, 0x297F)
+// DEFINE_IS_IN_UNICODE_BLOCK(MiscellaneousMathematicalSymbolsB, 0x2980, 0x29FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(SupplementalMathematicalOperators, 0x2A00, 0x2AFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(MiscellaneousSymbolsandArrows, 0x2B00, 0x2BFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Glagolitic, 0x2C00, 0x2C5F)
+// DEFINE_IS_IN_UNICODE_BLOCK(LatinExtendedC, 0x2C60, 0x2C7F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Coptic, 0x2C80, 0x2CFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(GeorgianSupplement, 0x2D00, 0x2D2F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Tifinagh, 0x2D30, 0x2D7F)
+// DEFINE_IS_IN_UNICODE_BLOCK(EthiopicExtended, 0x2D80, 0x2DDF)
+// DEFINE_IS_IN_UNICODE_BLOCK(CyrillicExtendedA, 0x2DE0, 0x2DFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(SupplementalPunctuation, 0x2E00, 0x2E7F)
+DEFINE_IS_IN_UNICODE_BLOCK(CJKRadicalsSupplement, 0x2E80, 0x2EFF)
+DEFINE_IS_IN_UNICODE_BLOCK(KangxiRadicals, 0x2F00, 0x2FDF)
+DEFINE_IS_IN_UNICODE_BLOCK(IdeographicDescriptionCharacters, 0x2FF0, 0x2FFF)
+DEFINE_IS_IN_UNICODE_BLOCK(CJKSymbolsandPunctuation, 0x3000, 0x303F)
+DEFINE_IS_IN_UNICODE_BLOCK(Hiragana, 0x3040, 0x309F)
+DEFINE_IS_IN_UNICODE_BLOCK(Katakana, 0x30A0, 0x30FF)
+DEFINE_IS_IN_UNICODE_BLOCK(Bopomofo, 0x3100, 0x312F)
+// DEFINE_IS_IN_UNICODE_BLOCK(HangulCompatibilityJamo, 0x3130, 0x318F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Kanbun, 0x3190, 0x319F)
+DEFINE_IS_IN_UNICODE_BLOCK(BopomofoExtended, 0x31A0, 0x31BF)
+DEFINE_IS_IN_UNICODE_BLOCK(CJKStrokes, 0x31C0, 0x31EF)
+DEFINE_IS_IN_UNICODE_BLOCK(KatakanaPhoneticExtensions, 0x31F0, 0x31FF)
+DEFINE_IS_IN_UNICODE_BLOCK(EnclosedCJKLettersandMonths, 0x3200, 0x32FF)
+DEFINE_IS_IN_UNICODE_BLOCK(CJKCompatibility, 0x3300, 0x33FF)
+DEFINE_IS_IN_UNICODE_BLOCK(CJKUnifiedIdeographsExtensionA, 0x3400, 0x4DBF)
+// DEFINE_IS_IN_UNICODE_BLOCK(YijingHexagramSymbols, 0x4DC0, 0x4DFF)
+DEFINE_IS_IN_UNICODE_BLOCK(CJKUnifiedIdeographs, 0x4E00, 0x9FFF)
+DEFINE_IS_IN_UNICODE_BLOCK(YiSyllables, 0xA000, 0xA48F)
+DEFINE_IS_IN_UNICODE_BLOCK(YiRadicals, 0xA490, 0xA4CF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Lisu, 0xA4D0, 0xA4FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Vai, 0xA500, 0xA63F)
+// DEFINE_IS_IN_UNICODE_BLOCK(CyrillicExtendedB, 0xA640, 0xA69F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Bamum, 0xA6A0, 0xA6FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(ModifierToneLetters, 0xA700, 0xA71F)
+// DEFINE_IS_IN_UNICODE_BLOCK(LatinExtendedD, 0xA720, 0xA7FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(SylotiNagri, 0xA800, 0xA82F)
+// DEFINE_IS_IN_UNICODE_BLOCK(CommonIndicNumberForms, 0xA830, 0xA83F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Phagspa, 0xA840, 0xA87F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Saurashtra, 0xA880, 0xA8DF)
+// DEFINE_IS_IN_UNICODE_BLOCK(DevanagariExtended, 0xA8E0, 0xA8FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(KayahLi, 0xA900, 0xA92F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Rejang, 0xA930, 0xA95F)
+// DEFINE_IS_IN_UNICODE_BLOCK(HangulJamoExtendedA, 0xA960, 0xA97F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Javanese, 0xA980, 0xA9DF)
+// DEFINE_IS_IN_UNICODE_BLOCK(MyanmarExtendedB, 0xA9E0, 0xA9FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Cham, 0xAA00, 0xAA5F)
+// DEFINE_IS_IN_UNICODE_BLOCK(MyanmarExtendedA, 0xAA60, 0xAA7F)
+// DEFINE_IS_IN_UNICODE_BLOCK(TaiViet, 0xAA80, 0xAADF)
+// DEFINE_IS_IN_UNICODE_BLOCK(MeeteiMayekExtensions, 0xAAE0, 0xAAFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(EthiopicExtendedA, 0xAB00, 0xAB2F)
+// DEFINE_IS_IN_UNICODE_BLOCK(LatinExtendedE, 0xAB30, 0xAB6F)
+// DEFINE_IS_IN_UNICODE_BLOCK(CherokeeSupplement, 0xAB70, 0xABBF)
+// DEFINE_IS_IN_UNICODE_BLOCK(MeeteiMayek, 0xABC0, 0xABFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(HangulSyllables, 0xAC00, 0xD7AF)
+// DEFINE_IS_IN_UNICODE_BLOCK(HangulJamoExtendedB, 0xD7B0, 0xD7FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(HighSurrogates, 0xD800, 0xDB7F)
+// DEFINE_IS_IN_UNICODE_BLOCK(HighPrivateUseSurrogates, 0xDB80, 0xDBFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(LowSurrogates, 0xDC00, 0xDFFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(PrivateUseArea, 0xE000, 0xF8FF)
+DEFINE_IS_IN_UNICODE_BLOCK(CJKCompatibilityIdeographs, 0xF900, 0xFAFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(AlphabeticPresentationForms, 0xFB00, 0xFB4F)
+// DEFINE_IS_IN_UNICODE_BLOCK(ArabicPresentationFormsA, 0xFB50, 0xFDFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(VariationSelectors, 0xFE00, 0xFE0F)
+DEFINE_IS_IN_UNICODE_BLOCK(VerticalForms, 0xFE10, 0xFE1F)
+// DEFINE_IS_IN_UNICODE_BLOCK(CombiningHalfMarks, 0xFE20, 0xFE2F)
+DEFINE_IS_IN_UNICODE_BLOCK(CJKCompatibilityForms, 0xFE30, 0xFE4F)
+// DEFINE_IS_IN_UNICODE_BLOCK(SmallFormVariants, 0xFE50, 0xFE6F)
+// DEFINE_IS_IN_UNICODE_BLOCK(ArabicPresentationFormsB, 0xFE70, 0xFEFF)
+DEFINE_IS_IN_UNICODE_BLOCK(HalfwidthandFullwidthForms, 0xFF00, 0xFFEF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Specials, 0xFFF0, 0xFFFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(LinearBSyllabary, 0x10000, 0x1007F)
+// DEFINE_IS_IN_UNICODE_BLOCK(LinearBIdeograms, 0x10080, 0x100FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(AegeanNumbers, 0x10100, 0x1013F)
+// DEFINE_IS_IN_UNICODE_BLOCK(AncientGreekNumbers, 0x10140, 0x1018F)
+// DEFINE_IS_IN_UNICODE_BLOCK(AncientSymbols, 0x10190, 0x101CF)
+// DEFINE_IS_IN_UNICODE_BLOCK(PhaistosDisc, 0x101D0, 0x101FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Lycian, 0x10280, 0x1029F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Carian, 0x102A0, 0x102DF)
+// DEFINE_IS_IN_UNICODE_BLOCK(CopticEpactNumbers, 0x102E0, 0x102FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(OldItalic, 0x10300, 0x1032F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Gothic, 0x10330, 0x1034F)
+// DEFINE_IS_IN_UNICODE_BLOCK(OldPermic, 0x10350, 0x1037F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Ugaritic, 0x10380, 0x1039F)
+// DEFINE_IS_IN_UNICODE_BLOCK(OldPersian, 0x103A0, 0x103DF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Deseret, 0x10400, 0x1044F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Shavian, 0x10450, 0x1047F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Osmanya, 0x10480, 0x104AF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Osage, 0x104B0, 0x104FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Elbasan, 0x10500, 0x1052F)
+// DEFINE_IS_IN_UNICODE_BLOCK(CaucasianAlbanian, 0x10530, 0x1056F)
+// DEFINE_IS_IN_UNICODE_BLOCK(LinearA, 0x10600, 0x1077F)
+// DEFINE_IS_IN_UNICODE_BLOCK(CypriotSyllabary, 0x10800, 0x1083F)
+// DEFINE_IS_IN_UNICODE_BLOCK(ImperialAramaic, 0x10840, 0x1085F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Palmyrene, 0x10860, 0x1087F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Nabataean, 0x10880, 0x108AF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Hatran, 0x108E0, 0x108FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Phoenician, 0x10900, 0x1091F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Lydian, 0x10920, 0x1093F)
+// DEFINE_IS_IN_UNICODE_BLOCK(MeroiticHieroglyphs, 0x10980, 0x1099F)
+// DEFINE_IS_IN_UNICODE_BLOCK(MeroiticCursive, 0x109A0, 0x109FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Kharoshthi, 0x10A00, 0x10A5F)
+// DEFINE_IS_IN_UNICODE_BLOCK(OldSouthArabian, 0x10A60, 0x10A7F)
+// DEFINE_IS_IN_UNICODE_BLOCK(OldNorthArabian, 0x10A80, 0x10A9F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Manichaean, 0x10AC0, 0x10AFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Avestan, 0x10B00, 0x10B3F)
+// DEFINE_IS_IN_UNICODE_BLOCK(InscriptionalParthian, 0x10B40, 0x10B5F)
+// DEFINE_IS_IN_UNICODE_BLOCK(InscriptionalPahlavi, 0x10B60, 0x10B7F)
+// DEFINE_IS_IN_UNICODE_BLOCK(PsalterPahlavi, 0x10B80, 0x10BAF)
+// DEFINE_IS_IN_UNICODE_BLOCK(OldTurkic, 0x10C00, 0x10C4F)
+// DEFINE_IS_IN_UNICODE_BLOCK(OldHungarian, 0x10C80, 0x10CFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(RumiNumeralSymbols, 0x10E60, 0x10E7F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Brahmi, 0x11000, 0x1107F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Kaithi, 0x11080, 0x110CF)
+// DEFINE_IS_IN_UNICODE_BLOCK(SoraSompeng, 0x110D0, 0x110FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Chakma, 0x11100, 0x1114F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Mahajani, 0x11150, 0x1117F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Sharada, 0x11180, 0x111DF)
+// DEFINE_IS_IN_UNICODE_BLOCK(SinhalaArchaicNumbers, 0x111E0, 0x111FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Khojki, 0x11200, 0x1124F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Multani, 0x11280, 0x112AF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Khudawadi, 0x112B0, 0x112FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Grantha, 0x11300, 0x1137F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Newa, 0x11400, 0x1147F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Tirhuta, 0x11480, 0x114DF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Siddham, 0x11580, 0x115FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Modi, 0x11600, 0x1165F)
+// DEFINE_IS_IN_UNICODE_BLOCK(MongolianSupplement, 0x11660, 0x1167F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Takri, 0x11680, 0x116CF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Ahom, 0x11700, 0x1173F)
+// DEFINE_IS_IN_UNICODE_BLOCK(WarangCiti, 0x118A0, 0x118FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(PauCinHau, 0x11AC0, 0x11AFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Bhaiksuki, 0x11C00, 0x11C6F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Marchen, 0x11C70, 0x11CBF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Cuneiform, 0x12000, 0x123FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(CuneiformNumbersandPunctuation, 0x12400, 0x1247F)
+// DEFINE_IS_IN_UNICODE_BLOCK(EarlyDynasticCuneiform, 0x12480, 0x1254F)
+// DEFINE_IS_IN_UNICODE_BLOCK(EgyptianHieroglyphs, 0x13000, 0x1342F)
+// DEFINE_IS_IN_UNICODE_BLOCK(AnatolianHieroglyphs, 0x14400, 0x1467F)
+// DEFINE_IS_IN_UNICODE_BLOCK(BamumSupplement, 0x16800, 0x16A3F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Mro, 0x16A40, 0x16A6F)
+// DEFINE_IS_IN_UNICODE_BLOCK(BassaVah, 0x16AD0, 0x16AFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(PahawhHmong, 0x16B00, 0x16B8F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Miao, 0x16F00, 0x16F9F)
+// DEFINE_IS_IN_UNICODE_BLOCK(IdeographicSymbolsandPunctuation, 0x16FE0, 0x16FFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Tangut, 0x17000, 0x187FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(TangutComponents, 0x18800, 0x18AFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(KanaSupplement, 0x1B000, 0x1B0FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Duployan, 0x1BC00, 0x1BC9F)
+// DEFINE_IS_IN_UNICODE_BLOCK(ShorthandFormatControls, 0x1BCA0, 0x1BCAF)
+// DEFINE_IS_IN_UNICODE_BLOCK(ByzantineMusicalSymbols, 0x1D000, 0x1D0FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(MusicalSymbols, 0x1D100, 0x1D1FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(AncientGreekMusicalNotation, 0x1D200, 0x1D24F)
+// DEFINE_IS_IN_UNICODE_BLOCK(TaiXuanJingSymbols, 0x1D300, 0x1D35F)
+// DEFINE_IS_IN_UNICODE_BLOCK(CountingRodNumerals, 0x1D360, 0x1D37F)
+// DEFINE_IS_IN_UNICODE_BLOCK(MathematicalAlphanumericSymbols, 0x1D400, 0x1D7FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(SuttonSignWriting, 0x1D800, 0x1DAAF)
+// DEFINE_IS_IN_UNICODE_BLOCK(GlagoliticSupplement, 0x1E000, 0x1E02F)
+// DEFINE_IS_IN_UNICODE_BLOCK(MendeKikakui, 0x1E800, 0x1E8DF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Adlam, 0x1E900, 0x1E95F)
+// DEFINE_IS_IN_UNICODE_BLOCK(ArabicMathematicalAlphabeticSymbols, 0x1EE00, 0x1EEFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(MahjongTiles, 0x1F000, 0x1F02F)
+// DEFINE_IS_IN_UNICODE_BLOCK(DominoTiles, 0x1F030, 0x1F09F)
+// DEFINE_IS_IN_UNICODE_BLOCK(PlayingCards, 0x1F0A0, 0x1F0FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(EnclosedAlphanumericSupplement, 0x1F100, 0x1F1FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(EnclosedIdeographicSupplement, 0x1F200, 0x1F2FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(MiscellaneousSymbolsandPictographs, 0x1F300, 0x1F5FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(Emoticons, 0x1F600, 0x1F64F)
+// DEFINE_IS_IN_UNICODE_BLOCK(OrnamentalDingbats, 0x1F650, 0x1F67F)
+// DEFINE_IS_IN_UNICODE_BLOCK(TransportandMapSymbols, 0x1F680, 0x1F6FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(AlchemicalSymbols, 0x1F700, 0x1F77F)
+// DEFINE_IS_IN_UNICODE_BLOCK(GeometricShapesExtended, 0x1F780, 0x1F7FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(SupplementalArrowsC, 0x1F800, 0x1F8FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(SupplementalSymbolsandPictographs, 0x1F900, 0x1F9FF)
+// DEFINE_IS_IN_UNICODE_BLOCK(CJKUnifiedIdeographsExtensionB, 0x20000, 0x2A6DF)
+// DEFINE_IS_IN_UNICODE_BLOCK(CJKUnifiedIdeographsExtensionC, 0x2A700, 0x2B73F)
+// DEFINE_IS_IN_UNICODE_BLOCK(CJKUnifiedIdeographsExtensionD, 0x2B740, 0x2B81F)
+// DEFINE_IS_IN_UNICODE_BLOCK(CJKUnifiedIdeographsExtensionE, 0x2B820, 0x2CEAF)
+// DEFINE_IS_IN_UNICODE_BLOCK(CJKCompatibilityIdeographsSupplement, 0x2F800, 0x2FA1F)
+// DEFINE_IS_IN_UNICODE_BLOCK(Tags, 0xE0000, 0xE007F)
+// DEFINE_IS_IN_UNICODE_BLOCK(VariationSelectorsSupplement, 0xE0100, 0xE01EF)
+// DEFINE_IS_IN_UNICODE_BLOCK(SupplementaryPrivateUseAreaA, 0xF0000, 0xFFFFF)
+// DEFINE_IS_IN_UNICODE_BLOCK(SupplementaryPrivateUseAreaB, 0x100000, 0x10FFFF)
+}
+
+namespace mbgl {
+namespace util {
+namespace i18n {
+
+bool allowsWordBreaking(uint16_t chr) {
+ return (chr == 0x0a /* newline */
+ || chr == 0x20 /* space */
+ || chr == 0x26 /* ampersand */
+ || chr == 0x2b /* plus sign */
+ || chr == 0x2d /* hyphen-minus */
+ || chr == 0x2f /* solidus */
+ || chr == 0xad /* soft hyphen */
+ || chr == 0xb7 /* middle dot */
+ || chr == 0x200b /* zero-width space */
+ || chr == 0x2010 /* hyphen */
+ || chr == 0x2013 /* en dash */);
+}
+
+bool allowsIdeographicBreaking(const std::u16string& string) {
+ for (uint16_t chr : string) {
+ if (!allowsIdeographicBreaking(chr)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool allowsIdeographicBreaking(uint16_t chr) {
+ // Allow U+2027 "Interpunct" for hyphenation of Chinese words
+ if (chr == 0x2027)
+ return true;
+
+ // Return early for characters outside all ideographic ranges.
+ if (chr < 0x2E80)
+ return false;
+
+ return (isInBopomofo(chr) || isInBopomofoExtended(chr) || isInCJKCompatibility(chr) ||
+ isInCJKCompatibilityForms(chr) || isInCJKCompatibilityIdeographs(chr) ||
+ isInCJKRadicalsSupplement(chr) || isInCJKStrokes(chr) ||
+ isInCJKSymbolsandPunctuation(chr) || isInCJKUnifiedIdeographs(chr) ||
+ isInCJKUnifiedIdeographsExtensionA(chr) || isInEnclosedCJKLettersandMonths(chr) ||
+ isInHalfwidthandFullwidthForms(chr) || isInHiragana(chr) ||
+ isInIdeographicDescriptionCharacters(chr) || isInKangxiRadicals(chr) ||
+ isInKatakana(chr) || isInKatakanaPhoneticExtensions(chr) || isInVerticalForms(chr) ||
+ isInYiRadicals(chr) || isInYiSyllables(chr));
+
+ // The following blocks also allow ideographic breaking; however, for other
+ // reasons, Mapbox GL lacks support for codepoints beyond U+FFFF.
+ // https://github.com/mapbox/mapbox-gl/issues/29
+ // return (isInTangut(chr)
+ // || isInTangutComponents(chr)
+ // || isInIdeographicSymbolsandPunctuation(chr)
+ // || isInEnclosedIdeographicSupplement(chr)
+ // || isInCJKUnifiedIdeographsExtensionB(chr)
+ // || isInCJKUnifiedIdeographsExtensionC(chr)
+ // || isInCJKUnifiedIdeographsExtensionD(chr)
+ // || isInCJKUnifiedIdeographsExtensionE(chr)
+ // || isInCJKCompatibilityIdeographsSupplement(chr));
+}
+
+} // namespace i18n
+} // namespace util
+} // namespace mbgl
diff --git a/src/mbgl/util/i18n.hpp b/src/mbgl/util/i18n.hpp
new file mode 100644
index 0000000000..f1d3f53f72
--- /dev/null
+++ b/src/mbgl/util/i18n.hpp
@@ -0,0 +1,24 @@
+#pragma once
+
+#include <string>
+
+namespace mbgl {
+namespace util {
+namespace i18n {
+
+/** Returns whether a line break can be inserted after the character indicated
+ by the given Unicode codepoint due to word breaking. */
+bool allowsWordBreaking(uint16_t chr);
+
+/** Returns whether a line break can be inserted after any character in the
+ given string. If false, line breaking should occur on word boundaries
+ instead. */
+bool allowsIdeographicBreaking(const std::u16string& string);
+
+/** Returns whether a line break can be inserted after the character indicated
+ by the given Unicode codepoint due to ideographic breaking. */
+bool allowsIdeographicBreaking(uint16_t chr);
+
+} // namespace i18n
+} // namespace util
+} // namespace mbgl
diff --git a/src/mbgl/util/ignore.hpp b/src/mbgl/util/ignore.hpp
new file mode 100644
index 0000000000..955b1de2fa
--- /dev/null
+++ b/src/mbgl/util/ignore.hpp
@@ -0,0 +1,23 @@
+#pragma once
+
+#include <initializer_list>
+
+namespace mbgl {
+namespace util {
+
+// Accept any number of parameters of any types, and do nothing with them.
+// Useful for providing a context for parameter pack expansion where a legal
+// expansion context is not otherwise available.
+//
+// See https://github.com/mapbox/cpp/blob/master/C%2B%2B%20Structural%20Metaprogramming.md
+// for more details.
+//
+template <class... Ts> void ignore(Ts&&...) {}
+
+// std::initializer_list overload, for situations where you need sequenced
+// modifications.
+//
+template <class T> void ignore(const std::initializer_list<T>&) {}
+
+} // namespace util
+} // namespace mbgl
diff --git a/src/mbgl/util/indexed_tuple.hpp b/src/mbgl/util/indexed_tuple.hpp
new file mode 100644
index 0000000000..110e7dce12
--- /dev/null
+++ b/src/mbgl/util/indexed_tuple.hpp
@@ -0,0 +1,47 @@
+#pragma once
+
+#include <type_traits>
+#include <tuple>
+
+namespace mbgl {
+
+template <class T, class... Ts>
+struct TypeIndex;
+
+template <class T, class... Ts>
+struct TypeIndex<T, T, Ts...> : std::integral_constant<std::size_t, 0> {};
+
+template <class T, class U, class... Ts>
+struct TypeIndex<T, U, Ts...> : std::integral_constant<std::size_t, 1 + TypeIndex<T, Ts...>::value> {};
+
+template <class...> class TypeList {};
+
+template <class...> class IndexedTuple;
+
+// A tuple of Ts, where individual members can be accessed via `t.get<I>()` for I ∈ Is.
+//
+// See https://github.com/mapbox/cpp/blob/master/C%2B%2B%20Structural%20Metaprogramming.md
+// for motivation.
+//
+template <class... Is, class... Ts>
+class IndexedTuple<TypeList<Is...>, TypeList<Ts...>> : public std::tuple<Ts...> {
+public:
+ static_assert(sizeof...(Is) == sizeof...(Ts), "IndexedTuple size mismatch");
+
+ using std::tuple<Ts...>::tuple;
+
+ template <class I>
+ static constexpr std::size_t Index = TypeIndex<I, Is...>::value;
+
+ template <class I>
+ auto& get() {
+ return std::get<Index<I>>(*this);
+ }
+
+ template <class I>
+ const auto& get() const {
+ return std::get<Index<I>>(*this);
+ }
+};
+
+} // namespace mbgl
diff --git a/src/mbgl/platform/log.cpp b/src/mbgl/util/logging.cpp
index b140485dd6..939f1def64 100644
--- a/src/mbgl/platform/log.cpp
+++ b/src/mbgl/util/logging.cpp
@@ -1,4 +1,4 @@
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
#include <mbgl/util/enum.hpp>
#include <mbgl/util/thread.hpp>
diff --git a/src/mbgl/util/mapbox.cpp b/src/mbgl/util/mapbox.cpp
index 9cf250f7a3..839924d77c 100644
--- a/src/mbgl/util/mapbox.cpp
+++ b/src/mbgl/util/mapbox.cpp
@@ -1,11 +1,10 @@
#include <mbgl/util/mapbox.hpp>
#include <mbgl/util/constants.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
#include <stdexcept>
#include <vector>
#include <iostream>
-#include <regex>
namespace {
@@ -192,14 +191,22 @@ std::string canonicalizeTileURL(const std::string& url, SourceType type, uint16_
}
result += "." + extension;
-
+
// get the query and remove access_token, if more parameters exist, add them to the final result
if (queryIdx != url.length()) {
- const auto query = url.substr(queryIdx + 1);
- std::regex re ("&?access_token=([^&]*)");
- std::string replace = std::regex_replace(query, re, "");
- std::string subQuery = (replace.find("&") == 0) ? replace.substr(1, replace.length()) : replace;
- if (subQuery.length() > 0) result += "?" + subQuery;
+ auto idx = queryIdx;
+ bool hasQuery = false;
+ while (idx != std::string::npos) {
+ idx++; // skip & or ?
+ auto ampersandIdx = url.find("&", idx);
+ if (url.substr(idx, 13) != "access_token=") {
+ result += hasQuery ? "&" : "?";
+ result += url.substr(idx, ampersandIdx != std::string::npos ? ampersandIdx - idx
+ : std::string::npos);
+ hasQuery = true;
+ }
+ idx = ampersandIdx;
+ }
}
return result;
diff --git a/src/mbgl/util/math.hpp b/src/mbgl/util/math.hpp
index 5d4220d0a2..f969ecaedd 100644
--- a/src/mbgl/util/math.hpp
+++ b/src/mbgl/util/math.hpp
@@ -106,11 +106,5 @@ T smoothstep(T edge0, T edge1, T x) {
return t * t * (T(3) - T(2) * t);
}
-// Computes the log2(x) rounded up to the next integer.
-// (== number of bits required to store x)
-uint32_t ceil_log2(uint64_t x);
-
-double log2(double x);
-
} // namespace util
} // namespace mbgl
diff --git a/src/mbgl/util/offscreen_texture.cpp b/src/mbgl/util/offscreen_texture.cpp
index 40bb70b70e..aad20e59d3 100644
--- a/src/mbgl/util/offscreen_texture.cpp
+++ b/src/mbgl/util/offscreen_texture.cpp
@@ -1,15 +1,14 @@
#include <mbgl/util/offscreen_texture.hpp>
#include <mbgl/gl/context.hpp>
-#include <mbgl/gl/gl.hpp>
#include <cstring>
#include <cassert>
namespace mbgl {
-OffscreenTexture::OffscreenTexture(gl::Context& context_, std::array<uint16_t, 2> size_)
- : context(context_), size(std::move(size_)) {
- assert(size[0] > 0 && size[1] > 0);
+OffscreenTexture::OffscreenTexture(gl::Context& context_, const Size size_)
+ : size(std::move(size_)), context(context_) {
+ assert(size);
}
void OffscreenTexture::bind() {
@@ -20,7 +19,7 @@ void OffscreenTexture::bind() {
context.bindFramebuffer = framebuffer->framebuffer;
}
- context.viewport = { 0, 0, size[0], size[1] };
+ context.viewport = { 0, 0, size };
}
gl::Texture& OffscreenTexture::getTexture() {
@@ -29,19 +28,7 @@ gl::Texture& OffscreenTexture::getTexture() {
}
PremultipliedImage OffscreenTexture::readStillImage() {
- 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 auto stride = image.stride();
- auto tmp = std::make_unique<uint8_t[]>(stride);
- uint8_t* rgba = image.data.get();
- for (int i = 0, j = size[1] - 1; i < j; i++, j--) {
- std::memcpy(tmp.get(), rgba + i * stride, stride);
- std::memcpy(rgba + i * stride, rgba + j * stride, stride);
- std::memcpy(rgba + j * stride, tmp.get(), stride);
- }
-
- return image;
+ return context.readFramebuffer<PremultipliedImage>(size);
}
diff --git a/src/mbgl/util/offscreen_texture.hpp b/src/mbgl/util/offscreen_texture.hpp
index 8928bc2434..64eb7bc565 100644
--- a/src/mbgl/util/offscreen_texture.hpp
+++ b/src/mbgl/util/offscreen_texture.hpp
@@ -14,7 +14,7 @@ class Context;
class OffscreenTexture : public View {
public:
- OffscreenTexture(gl::Context&, std::array<uint16_t, 2> size = {{ 256, 256 }});
+ OffscreenTexture(gl::Context&, Size size = { 256, 256 });
void bind() override;
@@ -22,9 +22,11 @@ public:
gl::Texture& getTexture();
+public:
+ const Size size;
+
private:
gl::Context& context;
- std::array<uint16_t, 2> size;
optional<gl::Framebuffer> framebuffer;
optional<gl::Texture> texture;
};
diff --git a/src/mbgl/util/premultiply.cpp b/src/mbgl/util/premultiply.cpp
index e0178fda33..219273d7cc 100644
--- a/src/mbgl/util/premultiply.cpp
+++ b/src/mbgl/util/premultiply.cpp
@@ -8,12 +8,11 @@ namespace util {
PremultipliedImage premultiply(UnassociatedImage&& src) {
PremultipliedImage dst;
- dst.width = src.width;
- dst.height = src.height;
+ dst.size = src.size;
dst.data = std::move(src.data);
uint8_t* data = dst.data.get();
- for (size_t i = 0; i < dst.size(); i += 4) {
+ for (size_t i = 0; i < dst.bytes(); i += 4) {
uint8_t& r = data[i + 0];
uint8_t& g = data[i + 1];
uint8_t& b = data[i + 2];
@@ -29,12 +28,11 @@ PremultipliedImage premultiply(UnassociatedImage&& src) {
UnassociatedImage unpremultiply(PremultipliedImage&& src) {
UnassociatedImage dst;
- dst.width = src.width;
- dst.height = src.height;
+ dst.size = src.size;
dst.data = std::move(src.data);
uint8_t* data = dst.data.get();
- for (size_t i = 0; i < dst.size(); i += 4) {
+ for (size_t i = 0; i < dst.bytes(); i += 4) {
uint8_t& r = data[i + 0];
uint8_t& g = data[i + 1];
uint8_t& b = data[i + 2];
diff --git a/src/mbgl/util/stopwatch.cpp b/src/mbgl/util/stopwatch.cpp
index d588b79254..3883d8535f 100644
--- a/src/mbgl/util/stopwatch.cpp
+++ b/src/mbgl/util/stopwatch.cpp
@@ -2,7 +2,7 @@
#include <mbgl/util/stopwatch.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/util/chrono.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
#include <iostream>
#include <atomic>
diff --git a/src/mbgl/util/stopwatch.hpp b/src/mbgl/util/stopwatch.hpp
index 74cc2c412d..6214dae958 100644
--- a/src/mbgl/util/stopwatch.hpp
+++ b/src/mbgl/util/stopwatch.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include <mbgl/platform/event.hpp>
+#include <mbgl/util/event.hpp>
#include <mbgl/util/chrono.hpp>
#include <string>
diff --git a/src/mbgl/util/thread.hpp b/src/mbgl/util/thread.hpp
index 91eef745fa..8cfef8a764 100644
--- a/src/mbgl/util/thread.hpp
+++ b/src/mbgl/util/thread.hpp
@@ -8,7 +8,7 @@
#include <mbgl/util/run_loop.hpp>
#include <mbgl/util/thread_context.hpp>
-#include <mbgl/platform/platform.hpp>
+#include <mbgl/util/platform.hpp>
#include <pthread.h>
diff --git a/src/mbgl/util/tile_cover.cpp b/src/mbgl/util/tile_cover.cpp
index c6bf7d362a..2fb7371aba 100644
--- a/src/mbgl/util/tile_cover.cpp
+++ b/src/mbgl/util/tile_cover.cpp
@@ -157,8 +157,8 @@ std::vector<UnwrappedTileID> tileCover(const LatLngBounds& bounds_, int32_t z) {
}
std::vector<UnwrappedTileID> tileCover(const TransformState& state, int32_t z) {
- const double w = state.getWidth();
- const double h = state.getHeight();
+ const double w = state.getSize().width;
+ const double h = state.getSize().height;
return tileCover(
TileCoordinate::fromScreenCoordinate(state, z, { 0, 0 }).p,
TileCoordinate::fromScreenCoordinate(state, z, { w, 0 }).p,
diff --git a/src/mbgl/util/url.cpp b/src/mbgl/util/url.cpp
index bf6fc70ff5..9831bc9038 100644
--- a/src/mbgl/util/url.cpp
+++ b/src/mbgl/util/url.cpp
@@ -1,12 +1,30 @@
#include <mbgl/util/url.hpp>
-#include <cctype>
#include <iomanip>
#include <sstream>
#include <string>
#include <cstdlib>
#include <algorithm>
+
+namespace {
+
+// std::alnum etc. suffer from locale-dependence.
+
+inline bool isAlphaCharacter(char c) {
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
+}
+
+inline bool isAlphaNumericCharacter(char c) {
+ return isAlphaCharacter(c) || (c >= '0' && c <= '9');
+}
+
+inline bool isSchemeCharacter(char c) {
+ return isAlphaNumericCharacter(c) || c == '-' || c == '+' || c == '.';
+}
+
+} // namespace
+
namespace mbgl {
namespace util {
@@ -17,7 +35,7 @@ std::string percentEncode(const std::string& input) {
encoded << std::hex;
for (auto c : input) {
- if (std::isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
+ if (isAlphaNumericCharacter(c) || c == '-' || c == '_' || c == '.' || c == '~') {
encoded << c;
} else {
encoded << '%' << std::setw(2) << int(c);
@@ -47,5 +65,18 @@ std::string percentDecode(const std::string& input) {
return decoded;
}
+// Checks whether the input string contains ://, and the part before it is all alphanumeric ASCII.
+bool isURL(const std::string& input) {
+ auto it = input.begin();
+ // First character has to be alphabetic
+ if (it == input.end() || !isAlphaCharacter(*it++)) return false;
+ // The remaining characters of the scheme can be alphanumeric, or be one of +.-
+ while (it != input.end() && isSchemeCharacter(*it)) ++it;
+ // Check that :// follows
+ return (it != input.end() && *it++ == ':') &&
+ (it != input.end() && *it++ == '/') &&
+ (it != input.end() && *it++ == '/');
+}
+
} // namespace util
} // namespace mbgl
diff --git a/src/mbgl/util/url.hpp b/src/mbgl/util/url.hpp
index b9c66261df..2d18f7476a 100644
--- a/src/mbgl/util/url.hpp
+++ b/src/mbgl/util/url.hpp
@@ -8,6 +8,7 @@ namespace util {
std::string percentEncode(const std::string&);
std::string percentDecode(const std::string&);
+bool isURL(const std::string&);
} // namespace util
} // namespace mbgl
diff --git a/src/mbgl/util/utf.hpp b/src/mbgl/util/utf.hpp
index 560ca3ba7f..81330cfc83 100644
--- a/src/mbgl/util/utf.hpp
+++ b/src/mbgl/util/utf.hpp
@@ -2,18 +2,17 @@
#include <memory>
-#include <boost/regex/pending/unicode_iterator.hpp>
+#include <locale>
+#include <codecvt>
namespace mbgl {
namespace util {
-class utf8_to_utf32 {
- public:
- static std::u32string convert(std::string const& utf8)
- {
- boost::u8_to_u32_iterator<std::string::const_iterator> begin(utf8.begin());
- boost::u8_to_u32_iterator<std::string::const_iterator> end(utf8.end());
- return std::u32string(begin,end);
+class utf8_to_utf16 {
+public:
+ static std::u16string convert(std::string const& utf8) {
+ std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter;
+ return converter.from_bytes(utf8);
}
};
diff --git a/test/actor/actor.test.cpp b/test/actor/actor.test.cpp
index c24d0b6c25..03f41a6e64 100644
--- a/test/actor/actor.test.cpp
+++ b/test/actor/actor.test.cpp
@@ -1,5 +1,5 @@
#include <mbgl/actor/actor.hpp>
-#include <mbgl/platform/default/thread_pool.hpp>
+#include <mbgl/util/default_thread_pool.hpp>
#include <mbgl/test/util.hpp>
diff --git a/test/actor/actor_ref.test.cpp b/test/actor/actor_ref.test.cpp
index 4be714278e..78721c965e 100644
--- a/test/actor/actor_ref.test.cpp
+++ b/test/actor/actor_ref.test.cpp
@@ -1,5 +1,5 @@
#include <mbgl/actor/actor.hpp>
-#include <mbgl/platform/default/thread_pool.hpp>
+#include <mbgl/util/default_thread_pool.hpp>
#include <mbgl/test/util.hpp>
diff --git a/test/algorithm/generate_clip_ids.test.cpp b/test/algorithm/generate_clip_ids.test.cpp
index 5b7f4afb26..8ca0191b3a 100644
--- a/test/algorithm/generate_clip_ids.test.cpp
+++ b/test/algorithm/generate_clip_ids.test.cpp
@@ -6,6 +6,7 @@ using namespace mbgl;
struct Renderable {
ClipID clip;
+ bool used = true;
bool operator==(const Renderable& rhs) const {
return clip == rhs.clip;
diff --git a/test/api/annotations.test.cpp b/test/api/annotations.test.cpp
index 2c875796bd..72a2d62bde 100644
--- a/test/api/annotations.test.cpp
+++ b/test/api/annotations.test.cpp
@@ -1,12 +1,12 @@
#include <mbgl/test/util.hpp>
#include <mbgl/test/stub_file_source.hpp>
-#include <mbgl/platform/default/thread_pool.hpp>
+#include <mbgl/util/default_thread_pool.hpp>
#include <mbgl/annotation/annotation.hpp>
#include <mbgl/sprite/sprite_image.hpp>
#include <mbgl/map/map.hpp>
-#include <mbgl/platform/default/headless_backend.hpp>
-#include <mbgl/platform/default/offscreen_view.hpp>
+#include <mbgl/gl/headless_backend.hpp>
+#include <mbgl/gl/offscreen_view.hpp>
#include <mbgl/util/io.hpp>
#include <mbgl/util/run_loop.hpp>
#include <mbgl/util/color.hpp>
@@ -23,11 +23,11 @@ std::shared_ptr<SpriteImage> namedMarker(const std::string &name) {
class AnnotationTest {
public:
util::RunLoop loop;
- HeadlessBackend backend;
- OffscreenView view{ backend.getContext() };
+ HeadlessBackend backend { test::sharedDisplay() };
+ OffscreenView view { backend.getContext() };
StubFileSource fileSource;
ThreadPool threadPool { 4 };
- Map map { backend, view.getSize(), 1, fileSource, threadPool, MapMode::Still };
+ Map map { backend, view.size, 1, fileSource, threadPool, MapMode::Still };
void checkRendering(const char * name) {
test::checkImage(std::string("test/fixtures/annotations/") + name,
@@ -45,16 +45,13 @@ 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());
- test.checkRendering("point_annotation");
-
- features = test.map.queryPointAnnotations(screenBox);
- EXPECT_EQ(features.size(), 1u);
+ auto size = test.view.size;
+ auto screenBox = ScreenBox { {}, { double(size.width), double(size.height) } };
+ for (uint8_t zoom = test.map.getMinZoom(); zoom <= test.map.getMaxZoom(); ++zoom) {
+ test.map.setZoom(zoom);
+ test.checkRendering("point_annotation");
+ EXPECT_EQ(test.map.queryPointAnnotations(screenBox).size(), 1u);
+ }
}
TEST(Annotations, LineAnnotation) {
@@ -62,7 +59,7 @@ TEST(Annotations, LineAnnotation) {
LineString<double> line = {{ { 0, 0 }, { 45, 45 }, { 30, 0 } }};
LineAnnotation annotation { line };
- annotation.color = { { 255, 0, 0, 1 } };
+ annotation.color = Color::red();
annotation.width = { 5 };
test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
@@ -78,7 +75,7 @@ TEST(Annotations, FillAnnotation) {
Polygon<double> polygon = {{ {{ { 0, 0 }, { 0, 45 }, { 45, 45 }, { 45, 0 } }} }};
FillAnnotation annotation { polygon };
- annotation.color = { { 255, 0, 0, 1 } };
+ annotation.color = Color::red();
test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
test.map.addAnnotation(annotation);
@@ -97,13 +94,13 @@ TEST(Annotations, AntimeridianAnnotationSmall) {
LineString<double> line = {{ { antimeridian, 20 }, { antimeridian, -20 } }};
LineAnnotation lineAnnotation { line };
- lineAnnotation.color = { { 255, 0, 0, 1 } };
+ lineAnnotation.color = Color::red();
lineAnnotation.width = { 2 };
test.map.addAnnotation(lineAnnotation);
Polygon<double> polygon = {{ {{ { antimeridian+10, 0 }, { antimeridian - 10, 10 }, { antimeridian-10, -10 } }} }};
FillAnnotation polygonAnnotation { polygon };
- polygonAnnotation.color = { { 0, 0, 255, 1 } };
+ polygonAnnotation.color = Color::blue();
test.map.addAnnotation(polygonAnnotation);
test.checkRendering("antimeridian_annotation_small");
@@ -118,13 +115,13 @@ TEST(Annotations, AntimeridianAnnotationLarge) {
LineString<double> line = {{ { antimeridian, 20 }, { antimeridian, -20 } }};
LineAnnotation lineAnnotation { line };
- lineAnnotation.color = { { 255, 0, 0, 1 } };
+ lineAnnotation.color = Color::red();
lineAnnotation.width = { 2 };
test.map.addAnnotation(lineAnnotation);
Polygon<double> polygon = {{ {{ { antimeridian-10, 0 }, { -antimeridian+10, 10 }, { -antimeridian+10, -10 } }} }};
FillAnnotation polygonAnnotation { polygon };
- polygonAnnotation.color = { { 0, 0, 255, 1 } };
+ polygonAnnotation.color = Color::blue();
test.map.addAnnotation(polygonAnnotation);
test.checkRendering("antimeridian_annotation_large");
@@ -135,9 +132,9 @@ TEST(Annotations, OverlappingFillAnnotation) {
Polygon<double> polygon = {{ {{ { 0, 0 }, { 0, 45 }, { 45, 45 }, { 45, 0 } }} }};
FillAnnotation underlaidAnnotation { polygon };
- underlaidAnnotation.color = { { 0, 255, 0, 1 } };
+ underlaidAnnotation.color = Color::green();
FillAnnotation overlaidAnnotation { polygon };
- overlaidAnnotation.color = { { 255, 0, 0, 1 } };
+ overlaidAnnotation.color = Color::red();
test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
test.map.addAnnotation(underlaidAnnotation);
@@ -176,7 +173,7 @@ TEST(Annotations, NonImmediateAdd) {
Polygon<double> polygon = {{ {{ { 0, 0 }, { 0, 45 }, { 45, 45 }, { 45, 0 } }} }};
FillAnnotation annotation { polygon };
- annotation.color = { { 255, 0, 0, 1 } };
+ annotation.color = Color::red();
test.map.addAnnotation(annotation);
test.checkRendering("non_immediate_add");
@@ -214,7 +211,7 @@ TEST(Annotations, UpdateLineAnnotationGeometry) {
AnnotationTest test;
LineAnnotation annotation { LineString<double> {{ { 0, 0 }, { 45, 45 }, { 30, 0 } }} };
- annotation.color = { { 255, 0, 0, 1 } };
+ annotation.color = Color::red();
annotation.width = { 5 };
test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
@@ -231,7 +228,7 @@ TEST(Annotations, UpdateLineAnnotationStyle) {
AnnotationTest test;
LineAnnotation annotation { LineString<double> {{ { 0, 0 }, { 45, 45 }, { 30, 0 } }} };
- annotation.color = { { 255, 0, 0, 1 } };
+ annotation.color = Color::red();
annotation.width = { 5 };
test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
@@ -239,7 +236,7 @@ TEST(Annotations, UpdateLineAnnotationStyle) {
test::render(test.map, test.view);
- annotation.color = { { 0, 255, 0, 1 } };
+ annotation.color = Color::green();
annotation.width = { 2 };
test.map.updateAnnotation(line, annotation);
test.checkRendering("update_line_style");
@@ -249,7 +246,7 @@ TEST(Annotations, UpdateFillAnnotationGeometry) {
AnnotationTest test;
FillAnnotation annotation { Polygon<double> {{ {{ { 0, 0 }, { 0, 45 }, { 45, 45 }, { 45, 0 } }} }} };
- annotation.color = { { 255, 0, 0, 1 } };
+ annotation.color = Color::red();
test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
AnnotationID fill = test.map.addAnnotation(annotation);
@@ -266,14 +263,14 @@ TEST(Annotations, UpdateFillAnnotationStyle) {
Polygon<double> polygon = {{ {{ { 0, 0 }, { 0, 45 }, { 45, 45 }, { 45, 0 } }} }};
FillAnnotation annotation { polygon };
- annotation.color = { { 255, 0, 0, 1 } };
+ annotation.color = Color::red();
test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
AnnotationID fill = test.map.addAnnotation(annotation);
test::render(test.map, test.view);
- annotation.color = { { 0, 255, 0, 1 } };
+ annotation.color = Color::green();
test.map.updateAnnotation(fill, annotation);
test.checkRendering("update_fill_style");
}
@@ -296,7 +293,7 @@ TEST(Annotations, RemoveShape) {
LineString<double> line = {{ { 0, 0 }, { 45, 45 } }};
LineAnnotation annotation { line };
- annotation.color = { { 255, 0, 0, 1 } };
+ annotation.color = Color::red();
annotation.width = { 5 };
test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
@@ -343,19 +340,19 @@ TEST(Annotations, QueryRenderedFeatures) {
auto features = test.map.queryRenderedFeatures(test.map.pixelForLatLng({ 0, 0 }));
EXPECT_EQ(features.size(), 1u);
EXPECT_TRUE(!!features[0].id);
- EXPECT_EQ(*features[0].id, 0);
+ EXPECT_EQ(*features[0].id, uint64_t(0));
auto features2 = test.map.queryRenderedFeatures(test.map.pixelForLatLng({ 50, 0 }));
EXPECT_EQ(features2.size(), 1u);
EXPECT_TRUE(!!features2[0].id);
- EXPECT_EQ(*features2[0].id, 1);
+ EXPECT_EQ(*features2[0].id, uint64_t(1));
}
TEST(Annotations, QueryFractionalZoomLevels) {
AnnotationTest test;
- auto viewSize = test.view.getSize();
- auto box = ScreenBox { {}, { double(viewSize[0]), double(viewSize[1]) } };
+ auto viewSize = test.view.size;
+ auto box = ScreenBox { {}, { double(viewSize.width), double(viewSize.height) } };
test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
test.map.addAnnotationIcon("default_marker", namedMarker("default_marker.png"));
@@ -386,8 +383,8 @@ TEST(Annotations, QueryFractionalZoomLevels) {
TEST(Annotations, VisibleFeatures) {
AnnotationTest test;
- auto viewSize = test.view.getSize();
- auto box = ScreenBox { {}, { double(viewSize[0]), double(viewSize[1]) } };
+ auto viewSize = test.view.size;
+ auto box = ScreenBox { {}, { double(viewSize.width), double(viewSize.height) } };
test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
test.map.addAnnotationIcon("default_marker", namedMarker("default_marker.png"));
@@ -419,3 +416,32 @@ TEST(Annotations, VisibleFeatures) {
features.erase(std::unique(features.begin(), features.end(), sameID), features.end());
EXPECT_EQ(features.size(), ids.size());
}
+
+
+TEST(Annotations, DebugEmpty) {
+ // This test should render nothing, not even the tile borders. Tile borders are only rendered
+ // when there is an actual tile we're trying to render, but since there is no annotation, we
+ // should not render them.
+ AnnotationTest test;
+
+ test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.setDebug(MapDebugOptions::TileBorders);
+ test.map.setZoom(1);
+
+ test.checkRendering("debug_empty");
+}
+
+
+TEST(Annotations, DebugSparse) {
+ // This test should only render the top right tile with the associated tile border, but no other
+ // tiles because they're all empty.
+ AnnotationTest test;
+
+ test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.setDebug(MapDebugOptions::TileBorders);
+ test.map.setZoom(1);
+ test.map.addAnnotationIcon("default_marker", namedMarker("default_marker.png"));
+ test.map.addAnnotation(SymbolAnnotation { Point<double>(10, 10), "default_marker" });
+
+ test.checkRendering("debug_sparse");
+}
diff --git a/test/api/api_misuse.test.cpp b/test/api/api_misuse.test.cpp
index eb271b0258..34272f5366 100644
--- a/test/api/api_misuse.test.cpp
+++ b/test/api/api_misuse.test.cpp
@@ -3,10 +3,10 @@
#include <mbgl/test/fixture_log_observer.hpp>
#include <mbgl/map/map.hpp>
-#include <mbgl/platform/default/headless_backend.hpp>
-#include <mbgl/platform/default/offscreen_view.hpp>
+#include <mbgl/gl/headless_backend.hpp>
+#include <mbgl/gl/offscreen_view.hpp>
#include <mbgl/storage/online_file_source.hpp>
-#include <mbgl/platform/default/thread_pool.hpp>
+#include <mbgl/util/default_thread_pool.hpp>
#include <mbgl/util/exception.hpp>
#include <mbgl/util/run_loop.hpp>
@@ -14,19 +14,20 @@
using namespace mbgl;
+
TEST(API, RenderWithoutCallback) {
auto log = new FixtureLogObserver();
Log::setObserver(std::unique_ptr<Log::Observer>(log));
util::RunLoop loop;
- HeadlessBackend backend;
- OffscreenView view(backend.getContext(), {{ 128, 512 }});
+ HeadlessBackend backend { test::sharedDisplay() };
+ OffscreenView view { backend.getContext(), { 128, 512 } };
StubFileSource fileSource;
ThreadPool threadPool(4);
std::unique_ptr<Map> map =
- std::make_unique<Map>(backend, view.getSize(), 1, fileSource, threadPool, MapMode::Still);
+ std::make_unique<Map>(backend, view.size, 1, fileSource, threadPool, MapMode::Still);
map->renderStill(view, nullptr);
// Force Map thread to join.
@@ -45,12 +46,12 @@ TEST(API, RenderWithoutCallback) {
TEST(API, RenderWithoutStyle) {
util::RunLoop loop;
- HeadlessBackend backend;
- OffscreenView view(backend.getContext(), {{ 128, 512 }});
+ HeadlessBackend backend { test::sharedDisplay() };
+ OffscreenView view { backend.getContext(), { 128, 512 } };
StubFileSource fileSource;
ThreadPool threadPool(4);
- Map map(backend, view.getSize(), 1, fileSource, threadPool, MapMode::Still);
+ Map map(backend, view.size, 1, fileSource, threadPool, MapMode::Still);
std::exception_ptr error;
map.renderStill(view, [&](std::exception_ptr error_) {
diff --git a/test/api/custom_layer.test.cpp b/test/api/custom_layer.test.cpp
index 70de102b80..73b4e94af5 100644
--- a/test/api/custom_layer.test.cpp
+++ b/test/api/custom_layer.test.cpp
@@ -2,9 +2,9 @@
#include <mbgl/gl/gl.hpp>
#include <mbgl/map/map.hpp>
-#include <mbgl/platform/default/headless_backend.hpp>
-#include <mbgl/platform/default/offscreen_view.hpp>
-#include <mbgl/platform/default/thread_pool.hpp>
+#include <mbgl/gl/headless_backend.hpp>
+#include <mbgl/gl/offscreen_view.hpp>
+#include <mbgl/util/default_thread_pool.hpp>
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/style/layers/custom_layer.hpp>
#include <mbgl/style/layers/fill_layer.hpp>
@@ -85,8 +85,8 @@ public:
TEST(CustomLayer, Basic) {
util::RunLoop loop;
- HeadlessBackend backend;
- OffscreenView view(backend.getContext());
+ HeadlessBackend backend { test::sharedDisplay() };
+ OffscreenView view { backend.getContext() };
#ifdef MBGL_ASSET_ZIP
// Regenerate with `cd test/fixtures/api/ && zip -r assets.zip assets/`
@@ -97,7 +97,7 @@ TEST(CustomLayer, Basic) {
ThreadPool threadPool(4);
- Map map(backend, view.getSize(), 1, fileSource, threadPool, MapMode::Still);
+ Map map(backend, view.size, 1, fileSource, threadPool, MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/water.json"));
map.setLatLngZoom({ 37.8, -122.5 }, 10);
map.addLayer(std::make_unique<CustomLayer>(
diff --git a/test/api/query.test.cpp b/test/api/query.test.cpp
index 8e59c19afc..86687fc818 100644
--- a/test/api/query.test.cpp
+++ b/test/api/query.test.cpp
@@ -1,7 +1,7 @@
#include <mbgl/map/map.hpp>
-#include <mbgl/platform/default/headless_backend.hpp>
-#include <mbgl/platform/default/offscreen_view.hpp>
-#include <mbgl/platform/default/thread_pool.hpp>
+#include <mbgl/gl/headless_backend.hpp>
+#include <mbgl/gl/offscreen_view.hpp>
+#include <mbgl/util/default_thread_pool.hpp>
#include <mbgl/sprite/sprite_image.hpp>
#include <mbgl/test/stub_file_source.hpp>
#include <mbgl/test/util.hpp>
@@ -26,11 +26,11 @@ public:
}
util::RunLoop loop;
- HeadlessBackend backend;
+ HeadlessBackend backend { test::sharedDisplay() };
OffscreenView view { backend.getContext() };
StubFileSource fileSource;
ThreadPool threadPool { 4 };
- Map map { backend, view.getSize(), 1, fileSource, threadPool, MapMode::Still };
+ Map map { backend, view.size, 1, fileSource, threadPool, MapMode::Still };
};
} // end namespace
diff --git a/test/api/render_missing.test.cpp b/test/api/render_missing.test.cpp
index 366d71e67d..a5c59913bc 100644
--- a/test/api/render_missing.test.cpp
+++ b/test/api/render_missing.test.cpp
@@ -2,9 +2,9 @@
#include <mbgl/test/fixture_log_observer.hpp>
#include <mbgl/map/map.hpp>
-#include <mbgl/platform/default/headless_backend.hpp>
-#include <mbgl/platform/default/offscreen_view.hpp>
-#include <mbgl/platform/default/thread_pool.hpp>
+#include <mbgl/gl/headless_backend.hpp>
+#include <mbgl/gl/offscreen_view.hpp>
+#include <mbgl/util/default_thread_pool.hpp>
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/util/image.hpp>
#include <mbgl/util/io.hpp>
@@ -25,8 +25,8 @@ TEST(API, TEST_REQUIRES_SERVER(RenderMissingTile)) {
const auto style = util::read_file("test/fixtures/api/water_missing_tiles.json");
- HeadlessBackend backend;
- OffscreenView view(backend.getContext(), {{ 256, 512 }});
+ HeadlessBackend backend { test::sharedDisplay() };
+ OffscreenView view { backend.getContext(), { 256, 512 } };
#ifdef MBGL_ASSET_ZIP
// Regenerate with `cd test/fixtures/api/ && zip -r assets.zip assets/`
DefaultFileSource fileSource(":memory:", "test/fixtures/api/assets.zip");
@@ -38,7 +38,7 @@ TEST(API, TEST_REQUIRES_SERVER(RenderMissingTile)) {
Log::setObserver(std::make_unique<FixtureLogObserver>());
- Map map(backend, view.getSize(), 1, fileSource, threadPool, MapMode::Still);
+ Map map(backend, view.size, 1, fileSource, threadPool, MapMode::Still);
std::string message;
diff --git a/test/api/repeated_render.test.cpp b/test/api/repeated_render.test.cpp
index 715b49b289..49b9a31b0b 100644
--- a/test/api/repeated_render.test.cpp
+++ b/test/api/repeated_render.test.cpp
@@ -2,9 +2,9 @@
#include <mbgl/test/fixture_log_observer.hpp>
#include <mbgl/map/map.hpp>
-#include <mbgl/platform/default/headless_backend.hpp>
-#include <mbgl/platform/default/offscreen_view.hpp>
-#include <mbgl/platform/default/thread_pool.hpp>
+#include <mbgl/gl/headless_backend.hpp>
+#include <mbgl/gl/offscreen_view.hpp>
+#include <mbgl/util/default_thread_pool.hpp>
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/util/image.hpp>
#include <mbgl/util/io.hpp>
@@ -12,15 +12,17 @@
#include <future>
+using namespace mbgl;
+
+
TEST(API, RepeatedRender) {
- using namespace mbgl;
util::RunLoop loop;
const auto style = util::read_file("test/fixtures/api/water.json");
- HeadlessBackend backend;
- OffscreenView view(backend.getContext(), {{ 256, 512 }});
+ HeadlessBackend backend { test::sharedDisplay() };
+ OffscreenView view { backend.getContext(), { 256, 512 } };
#ifdef MBGL_ASSET_ZIP
// Regenerate with `cd test/fixtures/api/ && zip -r assets.zip assets/`
DefaultFileSource fileSource(":memory:", "test/fixtures/api/assets.zip");
@@ -32,7 +34,7 @@ TEST(API, RepeatedRender) {
Log::setObserver(std::make_unique<FixtureLogObserver>());
- Map map(backend, view.getSize(), 1, fileSource, threadPool, MapMode::Still);
+ Map map(backend, view.size, 1, fileSource, threadPool, MapMode::Still);
{
map.setStyleJSON(style);
@@ -41,12 +43,12 @@ TEST(API, RepeatedRender) {
result = view.readStillImage();
});
- while (!result.size()) {
+ while (!result.valid()) {
loop.runOnce();
}
- ASSERT_EQ(256u, result.width);
- ASSERT_EQ(512u, result.height);
+ ASSERT_EQ(256u, result.size.width);
+ ASSERT_EQ(512u, result.size.height);
#if !TEST_READ_ONLY
util::write_file("test/fixtures/api/1.png", encodePNG(result));
#endif
@@ -59,12 +61,12 @@ TEST(API, RepeatedRender) {
result = view.readStillImage();
});
- while (!result.size()) {
+ while (!result.valid()) {
loop.runOnce();
}
- ASSERT_EQ(256u, result.width);
- ASSERT_EQ(512u, result.height);
+ ASSERT_EQ(256u, result.size.width);
+ ASSERT_EQ(512u, result.size.height);
#if !TEST_READ_ONLY
util::write_file("test/fixtures/api/2.png", encodePNG(result));
#endif
diff --git a/test/fixtures/annotations/assets.zip b/test/fixtures/annotations/assets.zip
deleted file mode 100644
index 869380034f..0000000000
--- a/test/fixtures/annotations/assets.zip
+++ /dev/null
Binary files differ
diff --git a/test/fixtures/annotations/debug_empty/expected.png b/test/fixtures/annotations/debug_empty/expected.png
new file mode 100644
index 0000000000..04f8682f88
--- /dev/null
+++ b/test/fixtures/annotations/debug_empty/expected.png
Binary files differ
diff --git a/test/fixtures/annotations/debug_sparse/expected.png b/test/fixtures/annotations/debug_sparse/expected.png
new file mode 100644
index 0000000000..3c1ad1599c
--- /dev/null
+++ b/test/fixtures/annotations/debug_sparse/expected.png
Binary files differ
diff --git a/test/fixtures/api/assets.zip b/test/fixtures/api/assets.zip
deleted file mode 100644
index fe00443f61..0000000000
--- a/test/fixtures/api/assets.zip
+++ /dev/null
Binary files differ
diff --git a/test/fixtures/storage/assets.zip b/test/fixtures/storage/assets.zip
deleted file mode 100644
index 4006ee10f2..0000000000
--- a/test/fixtures/storage/assets.zip
+++ /dev/null
Binary files differ
diff --git a/test/fixtures/style_parser/stop-zoom-value.info.json b/test/fixtures/style_parser/stop-zoom-value.info.json
index 386dce9d29..39d7c68495 100644
--- a/test/fixtures/style_parser/stop-zoom-value.info.json
+++ b/test/fixtures/style_parser/stop-zoom-value.info.json
@@ -1,6 +1,7 @@
{
"default": {
"log": [
+ [1, "WARNING", "ParseStyle", "function must have at least one stop"],
[1, "WARNING", "ParseStyle", "function stop must have two elements"]
]
}
diff --git a/test/gl/bucket.test.cpp b/test/gl/bucket.test.cpp
new file mode 100644
index 0000000000..03cdc63a91
--- /dev/null
+++ b/test/gl/bucket.test.cpp
@@ -0,0 +1,41 @@
+#include <mbgl/test/util.hpp>
+
+#include <mbgl/renderer/circle_bucket.hpp>
+#include <mbgl/renderer/fill_bucket.hpp>
+#include <mbgl/renderer/line_bucket.hpp>
+#include <mbgl/renderer/symbol_bucket.hpp>
+
+#include <mbgl/style/layers/symbol_layer_properties.hpp>
+
+#include <mbgl/map/mode.hpp>
+
+TEST(Buckets, CircleBucket) {
+ mbgl::MapMode mapMode = mbgl::MapMode::Still;
+
+ mbgl::CircleBucket bucket { mapMode };
+ ASSERT_FALSE(bucket.hasData());
+}
+
+TEST(Buckets, FillBucket) {
+ mbgl::FillBucket bucket;
+ ASSERT_FALSE(bucket.hasData());
+}
+
+TEST(Buckets, LineBucket) {
+ uint32_t overscaling = 0;
+
+ mbgl::LineBucket bucket { overscaling };
+ ASSERT_FALSE(bucket.hasData());
+}
+
+TEST(Buckets, SymbolBucket) {
+ mbgl::MapMode mapMode = mbgl::MapMode::Still;
+ mbgl::style::SymbolLayoutProperties::Evaluated properties;
+ bool sdfIcons = false;
+ bool iconsNeedLinear = false;
+
+ mbgl::SymbolBucket bucket { mapMode, properties, sdfIcons, iconsNeedLinear };
+ ASSERT_FALSE(bucket.hasIconData());
+ ASSERT_FALSE(bucket.hasTextData());
+ ASSERT_FALSE(bucket.hasCollisionBoxData());
+}
diff --git a/test/gl/object.test.cpp b/test/gl/object.test.cpp
index a3457d28c6..f1da93f1da 100644
--- a/test/gl/object.test.cpp
+++ b/test/gl/object.test.cpp
@@ -1,13 +1,14 @@
#include <mbgl/test/util.hpp>
-#include <mbgl/platform/default/headless_backend.hpp>
-#include <mbgl/platform/default/offscreen_view.hpp>
+#include <mbgl/gl/headless_backend.hpp>
+#include <mbgl/gl/offscreen_view.hpp>
-#include <mbgl/gl/gl.hpp>
#include <mbgl/gl/context.hpp>
#include <memory>
+using namespace mbgl;
+
namespace {
static bool getFlag = false;
@@ -28,7 +29,7 @@ TEST(GLObject, PreserveState) {
getFlag = false;
setFlag = false;
- auto object = std::make_unique<mbgl::gl::PreserveState<MockGLObject>>();
+ auto object = std::make_unique<gl::PreserveState<MockGLObject>>();
EXPECT_TRUE(getFlag);
EXPECT_FALSE(setFlag);
@@ -41,7 +42,7 @@ TEST(GLObject, PreserveState) {
TEST(GLObject, Value) {
setFlag = false;
- auto object = std::make_unique<mbgl::gl::State<MockGLObject>>();
+ auto object = std::make_unique<gl::State<MockGLObject>>();
EXPECT_EQ(object->getCurrentValue(), false);
EXPECT_TRUE(object->isDirty());
EXPECT_FALSE(setFlag);
@@ -59,27 +60,13 @@ TEST(GLObject, Value) {
}
TEST(GLObject, Store) {
- mbgl::HeadlessBackend backend;
- mbgl::OffscreenView view(backend.getContext());
+ HeadlessBackend backend { test::sharedDisplay() };
+ OffscreenView view(backend.getContext());
- mbgl::gl::Context context;
+ gl::Context context;
EXPECT_TRUE(context.empty());
- mbgl::gl::UniqueProgram program = context.createProgram();
- EXPECT_NE(program.get(), 0u);
- program.reset();
- EXPECT_FALSE(context.empty());
- context.performCleanup();
- EXPECT_TRUE(context.empty());
-
- mbgl::gl::UniqueShader shader = context.createVertexShader();
- EXPECT_NE(shader.get(), 0u);
- shader.reset();
- EXPECT_FALSE(context.empty());
- context.performCleanup();
- EXPECT_TRUE(context.empty());
-
- mbgl::gl::UniqueTexture texture = context.createTexture();
+ gl::UniqueTexture texture = context.createTexture();
EXPECT_NE(texture.get(), 0u);
texture.reset();
EXPECT_FALSE(context.empty());
@@ -88,13 +75,6 @@ TEST(GLObject, Store) {
context.reset();
EXPECT_TRUE(context.empty());
- mbgl::gl::UniqueVertexArray vao = context.createVertexArray();
- EXPECT_NE(vao.get(), 0u);
- vao.reset();
- EXPECT_FALSE(context.empty());
- context.performCleanup();
- EXPECT_TRUE(context.empty());
-
context.reset();
EXPECT_TRUE(context.empty());
diff --git a/test/map/map.test.cpp b/test/map/map.test.cpp
index 5311aeb17f..8eedeb3c01 100644
--- a/test/map/map.test.cpp
+++ b/test/map/map.test.cpp
@@ -4,15 +4,16 @@
#include <mbgl/test/fixture_log_observer.hpp>
#include <mbgl/map/map.hpp>
-#include <mbgl/platform/default/headless_backend.hpp>
-#include <mbgl/platform/default/offscreen_view.hpp>
-#include <mbgl/platform/default/thread_pool.hpp>
+#include <mbgl/gl/headless_backend.hpp>
+#include <mbgl/gl/offscreen_view.hpp>
+#include <mbgl/util/default_thread_pool.hpp>
#include <mbgl/sprite/sprite_image.hpp>
#include <mbgl/storage/network_status.hpp>
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/util/image.hpp>
#include <mbgl/util/io.hpp>
#include <mbgl/util/run_loop.hpp>
+#include <mbgl/util/async_task.hpp>
#include <mbgl/style/layers/background_layer.hpp>
#include <mbgl/util/color.hpp>
@@ -22,7 +23,7 @@ using namespace std::literals::string_literals;
struct MapTest {
util::RunLoop runLoop;
- HeadlessBackend backend;
+ HeadlessBackend backend { test::sharedDisplay() };
OffscreenView view { backend.getContext() };
StubFileSource fileSource;
ThreadPool threadPool { 4 };
@@ -30,7 +31,7 @@ struct MapTest {
TEST(Map, LatLngBehavior) {
MapTest test;
- Map map(test.backend, test.view.getSize(), 1, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.size, 1, test.fileSource, test.threadPool, MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
@@ -64,7 +65,7 @@ TEST(Map, Offline) {
fileSource.put(Resource::glyphs(prefix + "{fontstack}/{range}.pbf", {{"Helvetica"}}, {0, 255}), expiredItem("glyph.pbf"));
NetworkStatus::Set(NetworkStatus::Status::Offline);
- Map map(test.backend, test.view.getSize(), 1, fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.size, 1, fileSource, test.threadPool, MapMode::Still);
map.setStyleURL(prefix + "style.json");
test::checkImage("test/fixtures/map/offline",
@@ -88,7 +89,7 @@ TEST(Map, SetStyleInvalidJSON) {
});
{
- Map map(test.backend, test.view.getSize(), 1, test.fileSource, test.threadPool,
+ Map map(test.backend, test.view.size, 1, test.fileSource, test.threadPool,
MapMode::Still);
map.setStyleJSON("invalid");
}
@@ -120,7 +121,7 @@ TEST(Map, SetStyleInvalidURL) {
}
});
- Map map(test.backend, test.view.getSize(), 1, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.size, 1, test.fileSource, test.threadPool, MapMode::Still);
map.setStyleURL("mapbox://bar");
test.runLoop.run();
@@ -129,7 +130,7 @@ TEST(Map, SetStyleInvalidURL) {
TEST(Map, DoubleStyleLoad) {
MapTest test;
- Map map(test.backend, test.view.getSize(), 1, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.size, 1, test.fileSource, test.threadPool, MapMode::Still);
map.setStyleJSON("");
map.setStyleJSON("");
}
@@ -140,7 +141,7 @@ TEST(Map, StyleFresh) {
MapTest test;
FakeFileSource fileSource;
- Map map(test.backend, test.view.getSize(), 1, fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.size, 1, fileSource, test.threadPool, MapMode::Still);
map.setStyleURL("mapbox://styles/test");
EXPECT_EQ(1u, fileSource.requests.size());
@@ -160,7 +161,7 @@ TEST(Map, StyleExpired) {
MapTest test;
FakeFileSource fileSource;
- Map map(test.backend, test.view.getSize(), 1, fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.size, 1, fileSource, test.threadPool, MapMode::Still);
map.setStyleURL("mapbox://styles/test");
EXPECT_EQ(1u, fileSource.requests.size());
@@ -187,7 +188,7 @@ TEST(Map, StyleExpiredWithAnnotations) {
MapTest test;
FakeFileSource fileSource;
- Map map(test.backend, test.view.getSize(), 1, fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.size, 1, fileSource, test.threadPool, MapMode::Still);
map.setStyleURL("mapbox://styles/test");
EXPECT_EQ(1u, fileSource.requests.size());
@@ -211,7 +212,7 @@ TEST(Map, StyleEarlyMutation) {
MapTest test;
FakeFileSource fileSource;
- Map map(test.backend, test.view.getSize(), 1, fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.size, 1, fileSource, test.threadPool, MapMode::Still);
map.setStyleURL("mapbox://styles/test");
map.addLayer(std::make_unique<style::BackgroundLayer>("bg"));
@@ -225,7 +226,7 @@ TEST(Map, StyleEarlyMutation) {
TEST(Map, StyleLoadedSignal) {
MapTest test;
- Map map(test.backend, test.view.getSize(), 1, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.size, 1, test.fileSource, test.threadPool, MapMode::Still);
// The map should emit a signal on style loaded
bool emitted = false;
@@ -246,7 +247,7 @@ TEST(Map, StyleLoadedSignal) {
TEST(Map, AddLayer) {
MapTest test;
- Map map(test.backend, test.view.getSize(), 1, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.size, 1, test.fileSource, test.threadPool, MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
auto layer = std::make_unique<BackgroundLayer>("background");
@@ -259,7 +260,7 @@ TEST(Map, AddLayer) {
TEST(Map, RemoveLayer) {
MapTest test;
- Map map(test.backend, test.view.getSize(), 1, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.size, 1, test.fileSource, test.threadPool, MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
auto layer = std::make_unique<BackgroundLayer>("background");
@@ -284,7 +285,7 @@ TEST(Map, DisabledSources) {
return {};
};
- Map map(test.backend, test.view.getSize(), 1, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.size, 1, test.fileSource, test.threadPool, MapMode::Still);
map.setZoom(1);
// This stylesheet has two raster layers, one that starts at zoom 1, the other at zoom 0.
@@ -334,7 +335,7 @@ TEST(Map, DisabledSources) {
TEST(Map, Classes) {
MapTest test;
- Map map(test.backend, test.view.getSize(), 1, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.size, 1, test.fileSource, test.threadPool, MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
EXPECT_FALSE(map.getTransitionOptions().duration);
@@ -368,7 +369,7 @@ TEST(Map, Classes) {
TEST(Map, AddImage) {
MapTest test;
- Map map(test.backend, test.view.getSize(), 1, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.size, 1, test.fileSource, test.threadPool, MapMode::Still);
auto decoded1 = decodeImage(util::read_file("test/fixtures/sprites/default_marker.png"));
auto decoded2 = decodeImage(util::read_file("test/fixtures/sprites/default_marker.png"));
auto image1 = std::make_unique<SpriteImage>(std::move(decoded1), 1.0);
@@ -385,7 +386,7 @@ TEST(Map, AddImage) {
TEST(Map, RemoveImage) {
MapTest test;
- Map map(test.backend, test.view.getSize(), 1, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.size, 1, test.fileSource, test.threadPool, MapMode::Still);
auto decoded = decodeImage(util::read_file("test/fixtures/sprites/default_marker.png"));
auto image = std::make_unique<SpriteImage>(std::move(decoded), 1.0);
@@ -398,7 +399,7 @@ TEST(Map, RemoveImage) {
TEST(Map, GetImage) {
MapTest test;
- Map map(test.backend, test.view.getSize(), 1, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.size, 1, test.fileSource, test.threadPool, MapMode::Still);
auto decoded = decodeImage(util::read_file("test/fixtures/sprites/default_marker.png"));
auto image = std::make_unique<SpriteImage>(std::move(decoded), 1.0);
@@ -406,3 +407,113 @@ TEST(Map, GetImage) {
map.addImage("test-icon", std::move(image));
test::checkImage("test/fixtures/map/get_icon", map.getImage("test-icon")->image);
}
+
+TEST(Map, DontLoadUnneededTiles) {
+ MapTest test;
+
+ Map map(test.backend, test.view.size, 1, test.fileSource, test.threadPool, MapMode::Still);
+ map.setStyleJSON(R"STYLE({
+ "sources": {
+ "a": { "type": "vector", "tiles": [ "a/{z}/{x}/{y}" ] }
+ },
+ "layers": [{
+ "id": "a",
+ "type": "fill",
+ "source": "a",
+ "source-layer": "a",
+ "minzoom": 0.3,
+ "maxzoom": 1.6
+ }]
+})STYLE");
+
+ using Tiles = std::unordered_set<std::string>;
+ Tiles tiles;
+
+ test.fileSource.tileResponse = [&](const Resource& rsc) {
+ tiles.emplace(rsc.url);
+ Response res;
+ res.noContent = true;
+ return res;
+ };
+
+ std::unordered_map<double, Tiles> referenceTiles = {
+ // Since the layer's minzoom is 0.3, we shouldn't load tiles before z0.3
+ { 0.3, { "a/0/0/0" } },
+ { 1.0, { "a/1/1/0", "a/1/0/1", "a/1/0/0", "a/1/1/1" } },
+ // Since the layer's maxzoom is 1.6, we should never load z2 or z3 tiles.
+ };
+
+ // Loop through zoom levels from 0 to 3 and check that the correct tiles are loaded at every
+ // step. The source is marked with maxzoom 1.0, which means that it won't be visible anymore
+ // after z1.0, so we should under no circumstances attempt to load z2 tiles.
+ for (unsigned zoom = 0; zoom <= 30; zoom++) { // times 10
+ // Note: using z += 0.1 in the loop doesn't produce accurate floating point numbers.
+ const double z = double(zoom) / 10;
+ tiles.clear();
+ map.setZoom(z);
+ test::render(map, test.view);
+ EXPECT_EQ(referenceTiles[z], tiles) << "zoom level " << z;
+ }
+}
+
+
+class MockBackend : public HeadlessBackend {
+public:
+ MockBackend(std::shared_ptr<HeadlessDisplay> display_)
+ : HeadlessBackend(display_) {
+ }
+
+ std::function<void()> callback;
+ void invalidate() override {
+ if (callback) {
+ callback();
+ }
+ }
+};
+
+TEST(Map, TEST_DISABLED_ON_CI(ContinuousRendering)) {
+ util::RunLoop runLoop;
+ MockBackend backend { test::sharedDisplay() };
+ OffscreenView view { backend.getContext() };
+ ThreadPool threadPool { 4 };
+
+#ifdef MBGL_ASSET_ZIP
+ // Regenerate with `cd test/fixtures/api/ && zip -r assets.zip assets/`
+ DefaultFileSource fileSource(":memory:", "test/fixtures/api/assets.zip");
+#else
+ DefaultFileSource fileSource(":memory:", "test/fixtures/api/assets");
+#endif
+
+ Map map(backend, view.size, 1, fileSource, threadPool, MapMode::Continuous);
+
+ using namespace std::chrono_literals;
+
+ util::Timer emergencyShutoff;
+ emergencyShutoff.start(10s, 0s, [&] {
+ util::RunLoop::Get()->stop();
+ FAIL() << "Did not stop rendering";
+ });
+
+ util::Timer timer;
+ util::AsyncTask render{[&] {
+ if (map.isFullyLoaded()) {
+ // Abort the test after 1 second after the map loading fully. Note that a "fully loaded
+ // map" doesn't mean that we won't render anymore: we could still render fade in/fade
+ // out or other animations.
+ // If we are continuing to render indefinitely, the emergency shutoff above will trigger
+ // and the test will fail since the regular time will be constantly reset.
+ timer.start(1s, 0s, [&] {
+ util::RunLoop::Get()->stop();
+ });
+ }
+
+ map.render(view);
+ }};
+
+ backend.callback = [&] {
+ render.send();
+ };
+
+ map.setStyleJSON(util::read_file("test/fixtures/api/water.json"));
+ util::RunLoop::Get()->run();
+}
diff --git a/test/map/transform.test.cpp b/test/map/transform.test.cpp
index afb655abca..7f3a5e0556 100644
--- a/test/map/transform.test.cpp
+++ b/test/map/transform.test.cpp
@@ -103,11 +103,40 @@ TEST(Transform, InvalidBearing) {
ASSERT_DOUBLE_EQ(2, transform.getAngle());
}
+TEST(Transform, IntegerZoom) {
+ Transform transform;
+
+ auto checkIntegerZoom = [&transform](uint8_t zoomInt, double zoom) {
+ double scale = transform.getState().zoomScale(zoom);
+ transform.setScale(scale);
+#if __ANDROID__
+ // Android uses log(x) / M_LN2 instead of log2(x) because the latter
+ // is _broken in ARMv5 - that approach being less precise than log2(x).
+ ASSERT_NEAR(transform.getScale(), scale, 0.0001);
+#else
+ ASSERT_DOUBLE_EQ(transform.getScale(), scale);
+#endif
+ ASSERT_NEAR(transform.getZoom(), zoom, 0.0001);
+ ASSERT_EQ(transform.getState().getIntegerZoom(), zoomInt);
+ ASSERT_NEAR(transform.getState().getZoomFraction(), zoom - zoomInt, 0.0001);
+ };
+
+ for (uint8_t zoomInt = 0; zoomInt < 20; ++zoomInt) {
+ for (uint32_t percent = 0; percent < 100; ++percent) {
+ double zoom = zoomInt + (0.01 * percent);
+ checkIntegerZoom(zoomInt, zoom);
+ }
+ }
+
+ // Special case zoom 20.
+ checkIntegerZoom(20, 20.0);
+}
+
TEST(Transform, PerspectiveProjection) {
LatLng loc;
Transform transform;
- transform.resize({{ 1000, 1000 }});
+ transform.resize({ 1000, 1000 });
transform.setScale(2 << 9);
transform.setPitch(0.9);
transform.setLatLng(LatLng(38, -77));
@@ -137,7 +166,7 @@ TEST(Transform, PerspectiveProjection) {
TEST(Transform, UnwrappedLatLng) {
Transform transform;
- transform.resize({{ 1000, 1000 }});
+ transform.resize({ 1000, 1000 });
transform.setScale(2 << 9);
transform.setPitch(0.9);
transform.setLatLng(LatLng(38, -77));
@@ -169,7 +198,7 @@ TEST(Transform, ConstrainHeightOnly) {
LatLng loc;
Transform transform;
- transform.resize({{ 1000, 1000 }});
+ transform.resize({ 1000, 1000 });
transform.setScale(std::pow(2, util::MAX_ZOOM));
transform.setLatLng(LatLngBounds::world().southwest());
@@ -187,7 +216,7 @@ TEST(Transform, ConstrainWidthAndHeight) {
LatLng loc;
Transform transform(nullptr, ConstrainMode::WidthAndHeight);
- transform.resize({{ 1000, 1000 }});
+ transform.resize({ 1000, 1000 });
transform.setScale(std::pow(2, util::MAX_ZOOM));
transform.setLatLng(LatLngBounds::world().southwest());
@@ -203,7 +232,7 @@ TEST(Transform, ConstrainWidthAndHeight) {
TEST(Transform, Anchor) {
Transform transform;
- transform.resize({{ 1000, 1000 }});
+ transform.resize({ 1000, 1000 });
const LatLng latLng { 10, -100 };
transform.setLatLngZoom(latLng, 10);
@@ -303,7 +332,7 @@ TEST(Transform, Anchor) {
TEST(Transform, Padding) {
Transform transform;
- transform.resize({{ 1000, 1000 }});
+ transform.resize({ 1000, 1000 });
ASSERT_DOUBLE_EQ(0, transform.getLatLng().latitude);
ASSERT_DOUBLE_EQ(0, transform.getLatLng().longitude);
@@ -340,7 +369,7 @@ TEST(Transform, Padding) {
TEST(Transform, MoveBy) {
Transform transform;
- transform.resize({{ 1000, 1000 }});
+ transform.resize({ 1000, 1000 });
transform.setLatLngZoom({ 0, 0 }, 10);
LatLng trueCenter = transform.getLatLng();
@@ -367,7 +396,7 @@ TEST(Transform, MoveBy) {
TEST(Transform, Antimeridian) {
Transform transform;
- transform.resize({{ 1000, 1000 }});
+ transform.resize({ 1000, 1000 });
transform.setLatLngZoom({ 0, 0 }, 1);
const LatLng coordinateSanFrancisco { 37.7833, -122.4167 };
@@ -410,7 +439,7 @@ TEST(Transform, Antimeridian) {
TEST(Transform, Camera) {
Transform transform;
- transform.resize({{ 1000, 1000 }});
+ transform.resize({ 1000, 1000 });
const LatLng latLng1 { 45, 135 };
CameraOptions cameraOptions1;
@@ -481,8 +510,8 @@ TEST(Transform, DefaultTransform) {
LatLng nullIsland, latLng = {};
ScreenCoordinate center, point = {};
- const uint16_t min = std::numeric_limits<uint16_t>::min();
- const uint16_t max = std::numeric_limits<uint16_t>::max();
+ const uint32_t min = 0;
+ const uint32_t max = 65535;
auto testConversions = [&](const LatLng& coord, const ScreenCoordinate& screenCoord) {
latLng = state.screenCoordinateToLatLng(center);
@@ -496,21 +525,21 @@ TEST(Transform, DefaultTransform) {
testConversions(nullIsland, center);
// Cannot assign the current size.
- ASSERT_FALSE(transform.resize({{}}));
+ ASSERT_FALSE(transform.resize({}));
- ASSERT_TRUE(transform.resize({{ min, max }}));
+ ASSERT_TRUE(transform.resize({ min, max }));
testConversions(nullIsland, center);
- ASSERT_TRUE(transform.resize({{ max, min }}));
+ ASSERT_TRUE(transform.resize({ max, min }));
testConversions(nullIsland, center);
- ASSERT_TRUE(transform.resize({{ min, min }}));
+ ASSERT_TRUE(transform.resize({ min, min }));
testConversions(nullIsland, center);
center = { max / 2., max / 2. };
- // -1 evaluates to UINT_MAX.
- ASSERT_TRUE(transform.resize({{ static_cast<uint16_t>(-1), static_cast<uint16_t>(-1) }}));
- ASSERT_FALSE(transform.resize({{ max, max }}));
+ // Double resize
+ ASSERT_TRUE(transform.resize({ max, max }));
+ ASSERT_FALSE(transform.resize({ max, max }));
testConversions(nullIsland, center);
}
diff --git a/test/sprite/sprite_atlas.test.cpp b/test/sprite/sprite_atlas.test.cpp
index f84e17cbcf..c9576013d4 100644
--- a/test/sprite/sprite_atlas.test.cpp
+++ b/test/sprite/sprite_atlas.test.cpp
@@ -21,14 +21,6 @@ auto readImage(const std::string& name) {
return decodeImage(util::read_file(name));
}
-auto imageFromAtlas(const SpriteAtlas& atlas) {
- const size_t bytes = atlas.getTextureWidth() * atlas.getTextureHeight() * 4;
- auto data = std::make_unique<uint8_t[]>(bytes);
- const auto src = reinterpret_cast<const uint8_t*>(atlas.getData());
- std::copy(src, src + bytes, data.get());
- return PremultipliedImage{ atlas.getTextureWidth(), atlas.getTextureHeight(), std::move(data) };
-}
-
} // namespace
TEST(SpriteAtlas, Basic) {
@@ -37,17 +29,12 @@ TEST(SpriteAtlas, Basic) {
auto spriteParseResult = parseSprite(util::read_file("test/fixtures/annotations/emerald.png"),
util::read_file("test/fixtures/annotations/emerald.json"));
- SpriteAtlas atlas(63, 112, 1);
+ SpriteAtlas atlas({ 63, 112 }, 1);
atlas.setSprites(spriteParseResult.get<Sprites>());
EXPECT_EQ(1.0f, atlas.getPixelRatio());
- EXPECT_EQ(63, atlas.getWidth());
- EXPECT_EQ(112, atlas.getHeight());
- EXPECT_EQ(63, atlas.getTextureWidth());
- EXPECT_EQ(112, atlas.getTextureHeight());
-
- // Image hasn't been created yet.
- EXPECT_FALSE(atlas.getData());
+ EXPECT_EQ(63u, atlas.getSize().width);
+ EXPECT_EQ(112u, atlas.getSize().height);
auto metro = *atlas.getImage("metro", SpritePatternMode::Single);
EXPECT_EQ(0, metro.pos.x);
@@ -56,11 +43,12 @@ TEST(SpriteAtlas, Basic) {
EXPECT_EQ(20, metro.pos.h);
EXPECT_EQ(18, metro.spriteImage->getWidth());
EXPECT_EQ(18, metro.spriteImage->getHeight());
- EXPECT_EQ(18u, metro.spriteImage->image.width);
- EXPECT_EQ(18u, metro.spriteImage->image.height);
+ EXPECT_EQ(18u, metro.spriteImage->image.size.width);
+ EXPECT_EQ(18u, metro.spriteImage->image.size.height);
EXPECT_EQ(1.0f, metro.spriteImage->pixelRatio);
- EXPECT_TRUE(atlas.getData());
+ EXPECT_EQ(63u, atlas.getAtlasImage().size.width);
+ EXPECT_EQ(112u, atlas.getAtlasImage().size.height);
auto pos = *atlas.getPosition("metro", SpritePatternMode::Single);
EXPECT_DOUBLE_EQ(18, pos.size[0]);
@@ -87,21 +75,19 @@ TEST(SpriteAtlas, Basic) {
EXPECT_EQ(20, metro2.pos.w);
EXPECT_EQ(20, metro2.pos.h);
- EXPECT_EQ(readImage("test/fixtures/annotations/result-spriteatlas.png"), imageFromAtlas(atlas));
+ EXPECT_EQ(readImage("test/fixtures/annotations/result-spriteatlas.png"), atlas.getAtlasImage());
}
TEST(SpriteAtlas, Size) {
auto spriteParseResult = parseSprite(util::read_file("test/fixtures/annotations/emerald.png"),
util::read_file("test/fixtures/annotations/emerald.json"));
- SpriteAtlas atlas(63, 112, 1.4);
+ SpriteAtlas atlas({ 63, 112 }, 1.4);
atlas.setSprites(spriteParseResult.get<Sprites>());
EXPECT_DOUBLE_EQ(1.4f, atlas.getPixelRatio());
- EXPECT_EQ(63, atlas.getWidth());
- EXPECT_EQ(112, atlas.getHeight());
- EXPECT_EQ(89, atlas.getTextureWidth());
- EXPECT_EQ(157, atlas.getTextureHeight());
+ EXPECT_EQ(63u, atlas.getSize().width);
+ EXPECT_EQ(112u, atlas.getSize().height);
auto metro = *atlas.getImage("metro", SpritePatternMode::Single);
EXPECT_EQ(0, metro.pos.x);
@@ -110,24 +96,26 @@ TEST(SpriteAtlas, Size) {
EXPECT_EQ(16, metro.pos.h);
EXPECT_EQ(18, metro.spriteImage->getWidth());
EXPECT_EQ(18, metro.spriteImage->getHeight());
- EXPECT_EQ(18u, metro.spriteImage->image.width);
- EXPECT_EQ(18u, metro.spriteImage->image.height);
+ EXPECT_EQ(18u, metro.spriteImage->image.size.width);
+ EXPECT_EQ(18u, metro.spriteImage->image.size.height);
EXPECT_EQ(1.0f, metro.spriteImage->pixelRatio);
+ // Now the image was created lazily.
+ EXPECT_EQ(89u, atlas.getAtlasImage().size.width);
+ EXPECT_EQ(157u, atlas.getAtlasImage().size.height);
+
EXPECT_EQ(readImage("test/fixtures/annotations/result-spriteatlassize.png"),
- imageFromAtlas(atlas));
+ atlas.getAtlasImage());
}
TEST(SpriteAtlas, Updates) {
- SpriteAtlas atlas(32, 32, 1);
+ SpriteAtlas atlas({ 32, 32 }, 1);
EXPECT_EQ(1.0f, atlas.getPixelRatio());
- EXPECT_EQ(32, atlas.getWidth());
- EXPECT_EQ(32, atlas.getHeight());
- EXPECT_EQ(32, atlas.getTextureWidth());
- EXPECT_EQ(32, atlas.getTextureHeight());
+ EXPECT_EQ(32u, atlas.getSize().width);
+ EXPECT_EQ(32u, atlas.getSize().height);
- atlas.setSprite("one", std::make_shared<SpriteImage>(PremultipliedImage(16, 12), 1));
+ atlas.setSprite("one", std::make_shared<SpriteImage>(PremultipliedImage({ 16, 12 }), 1));
auto one = *atlas.getImage("one", SpritePatternMode::Single);
EXPECT_EQ(0, one.pos.x);
EXPECT_EQ(0, one.pos.y);
@@ -135,16 +123,20 @@ TEST(SpriteAtlas, Updates) {
EXPECT_EQ(16, one.pos.h);
EXPECT_EQ(16, one.spriteImage->getWidth());
EXPECT_EQ(12, one.spriteImage->getHeight());
- EXPECT_EQ(16u, one.spriteImage->image.width);
- EXPECT_EQ(12u, one.spriteImage->image.height);
+ EXPECT_EQ(16u, one.spriteImage->image.size.width);
+ EXPECT_EQ(12u, one.spriteImage->image.size.height);
EXPECT_EQ(1.0f, one.spriteImage->pixelRatio);
+ // Now the image was created lazily.
+ EXPECT_EQ(32u, atlas.getAtlasImage().size.width);
+ EXPECT_EQ(32u, atlas.getAtlasImage().size.height);
+
EXPECT_EQ(readImage("test/fixtures/annotations/result-spriteatlas-empty.png"),
- imageFromAtlas(atlas));
+ atlas.getAtlasImage());
// Update sprite
- PremultipliedImage image2(16, 12);
- for (size_t i = 0; i < image2.size(); i++) {
+ PremultipliedImage image2({ 16, 12 });
+ for (size_t i = 0; i < image2.bytes(); i++) {
image2.data.get()[i] = 255;
}
auto newSprite = std::make_shared<SpriteImage>(std::move(image2), 1);
@@ -153,23 +145,23 @@ TEST(SpriteAtlas, Updates) {
// Atlas texture hasn't changed yet.
EXPECT_EQ(readImage("test/fixtures/annotations/result-spriteatlas-empty.png"),
- imageFromAtlas(atlas));
+ atlas.getAtlasImage());
atlas.updateDirty();
// Now the atlas texture has changed.
EXPECT_EQ(readImage("test/fixtures/annotations/result-spriteatlas-updated.png"),
- imageFromAtlas(atlas));
+ atlas.getAtlasImage());
}
TEST(SpriteAtlas, AddRemove) {
FixtureLog log;
- const auto sprite1 = std::make_shared<SpriteImage>(PremultipliedImage(16, 16), 2);
- const auto sprite2 = std::make_shared<SpriteImage>(PremultipliedImage(16, 16), 2);
- const auto sprite3 = std::make_shared<SpriteImage>(PremultipliedImage(16, 16), 2);
+ const auto sprite1 = std::make_shared<SpriteImage>(PremultipliedImage({ 16, 16 }), 2);
+ const auto sprite2 = std::make_shared<SpriteImage>(PremultipliedImage({ 16, 16 }), 2);
+ const auto sprite3 = std::make_shared<SpriteImage>(PremultipliedImage({ 16, 16 }), 2);
- SpriteAtlas atlas(32, 32, 1);
+ SpriteAtlas atlas({ 32, 32 }, 1);
// Adding single
atlas.setSprite("one", sprite1);
@@ -210,19 +202,19 @@ TEST(SpriteAtlas, AddRemove) {
TEST(SpriteAtlas, OtherPixelRatio) {
FixtureLog log;
- const auto sprite1 = std::make_shared<SpriteImage>(PremultipliedImage(8, 8), 1);
+ const auto sprite1 = std::make_shared<SpriteImage>(PremultipliedImage({ 8, 8 }), 1);
- SpriteAtlas atlas(32, 32, 1);
+ SpriteAtlas atlas({ 32, 32 }, 1);
// Adding mismatched sprite image
atlas.setSprite("one", sprite1);
}
TEST(SpriteAtlas, Multiple) {
- const auto sprite1 = std::make_shared<SpriteImage>(PremultipliedImage(16, 16), 2);
- const auto sprite2 = std::make_shared<SpriteImage>(PremultipliedImage(16, 16), 2);
+ const auto sprite1 = std::make_shared<SpriteImage>(PremultipliedImage({ 16, 16 }), 2);
+ const auto sprite2 = std::make_shared<SpriteImage>(PremultipliedImage({ 16, 16 }), 2);
- SpriteAtlas atlas(32, 32, 1);
+ SpriteAtlas atlas({ 32, 32 }, 1);
atlas.setSprites({
{ "one", sprite1 }, { "two", sprite2 },
@@ -232,10 +224,10 @@ TEST(SpriteAtlas, Multiple) {
TEST(SpriteAtlas, Replace) {
FixtureLog log;
- const auto sprite1 = std::make_shared<SpriteImage>(PremultipliedImage(16, 16), 2);
- const auto sprite2 = std::make_shared<SpriteImage>(PremultipliedImage(16, 16), 2);
+ const auto sprite1 = std::make_shared<SpriteImage>(PremultipliedImage({ 16, 16 }), 2);
+ const auto sprite2 = std::make_shared<SpriteImage>(PremultipliedImage({ 16, 16 }), 2);
- SpriteAtlas atlas(32, 32, 1);
+ SpriteAtlas atlas({ 32, 32 }, 1);
atlas.setSprite("sprite", sprite1);
EXPECT_EQ(sprite1, atlas.getSprite("sprite"));
@@ -246,12 +238,12 @@ TEST(SpriteAtlas, Replace) {
TEST(SpriteAtlas, ReplaceWithDifferentDimensions) {
FixtureLog log;
- PremultipliedImage image(16, 16);
- PremultipliedImage image2(18, 18);
- const auto sprite1 = std::make_shared<SpriteImage>(PremultipliedImage(16, 16), 2);
- const auto sprite2 = std::make_shared<SpriteImage>(PremultipliedImage(18, 18), 2);
+ PremultipliedImage image({ 16, 16 });
+ PremultipliedImage image2({ 18, 18 });
+ const auto sprite1 = std::make_shared<SpriteImage>(PremultipliedImage({ 16, 16 }), 2);
+ const auto sprite2 = std::make_shared<SpriteImage>(PremultipliedImage({ 18, 18 }), 2);
- SpriteAtlas atlas(32, 32, 1);
+ SpriteAtlas atlas({ 32, 32 }, 1);
atlas.setSprite("sprite", sprite1);
atlas.setSprite("sprite", sprite2);
@@ -273,7 +265,7 @@ public:
util::RunLoop loop;
StubFileSource fileSource;
StubStyleObserver observer;
- SpriteAtlas spriteAtlas { 32, 32, 1 };
+ SpriteAtlas spriteAtlas{ { 32, 32 }, 1 };
void run() {
// Squelch logging.
diff --git a/test/sprite/sprite_image.test.cpp b/test/sprite/sprite_image.test.cpp
index f8982826a3..97a37513ac 100644
--- a/test/sprite/sprite_image.test.cpp
+++ b/test/sprite/sprite_image.test.cpp
@@ -7,7 +7,7 @@
using namespace mbgl;
TEST(Sprite, SpriteImageZeroWidth) {
- PremultipliedImage image(0, 16);
+ PremultipliedImage image({ 0, 16 });
try {
SpriteImage(std::move(image), 2.0);
FAIL() << "Expected exception";
@@ -17,7 +17,7 @@ TEST(Sprite, SpriteImageZeroWidth) {
}
TEST(Sprite, SpriteImageZeroHeight) {
- PremultipliedImage image(16, 0);
+ PremultipliedImage image({ 16, 0 });
try {
SpriteImage(std::move(image), 2.0);
FAIL() << "Expected exception";
@@ -27,7 +27,7 @@ TEST(Sprite, SpriteImageZeroHeight) {
}
TEST(Sprite, SpriteImageZeroRatio) {
- PremultipliedImage image(16, 16);
+ PremultipliedImage image({ 16, 16 });
try {
SpriteImage(std::move(image), 0.0);
FAIL() << "Expected exception";
@@ -37,21 +37,21 @@ TEST(Sprite, SpriteImageZeroRatio) {
}
TEST(Sprite, SpriteImage) {
- PremultipliedImage image(32, 24);
+ PremultipliedImage image({ 32, 24 });
SpriteImage sprite(std::move(image), 2.0);
EXPECT_EQ(16, sprite.getWidth());
- EXPECT_EQ(32u, sprite.image.width);
+ EXPECT_EQ(32u, sprite.image.size.width);
EXPECT_EQ(12, sprite.getHeight());
- EXPECT_EQ(24u, sprite.image.height);
+ EXPECT_EQ(24u, sprite.image.size.height);
EXPECT_EQ(2, sprite.pixelRatio);
}
TEST(Sprite, SpriteImageFractionalRatio) {
- PremultipliedImage image(20, 12);
+ PremultipliedImage image({ 20, 12 });
SpriteImage sprite(std::move(image), 1.5);
EXPECT_EQ(float(20.0 / 1.5), sprite.getWidth());
- EXPECT_EQ(20u, sprite.image.width);
+ EXPECT_EQ(20u, sprite.image.size.width);
EXPECT_EQ(float(12.0 / 1.5), sprite.getHeight());
- EXPECT_EQ(12u, sprite.image.height);
+ EXPECT_EQ(12u, sprite.image.size.height);
EXPECT_EQ(1.5, sprite.pixelRatio);
}
diff --git a/test/sprite/sprite_parser.test.cpp b/test/sprite/sprite_parser.test.cpp
index 8d32d081bf..d634df1c1a 100644
--- a/test/sprite/sprite_parser.test.cpp
+++ b/test/sprite/sprite_parser.test.cpp
@@ -24,8 +24,8 @@ TEST(Sprite, SpriteImageCreationInvalid) {
const PremultipliedImage image_1x = decodeImage(util::read_file("test/fixtures/annotations/emerald.png"));
- ASSERT_EQ(200u, image_1x.width);
- ASSERT_EQ(299u, image_1x.height);
+ ASSERT_EQ(200u, image_1x.size.width);
+ ASSERT_EQ(299u, image_1x.size.height);
ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, 0, 16, 1, false)); // width == 0
ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, 16, 0, 1, false)); // height == 0
@@ -38,30 +38,115 @@ TEST(Sprite, SpriteImageCreationInvalid) {
ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, 16, 1025, 1, false)); // too tall
ASSERT_EQ(nullptr, createSpriteImage(image_1x, -1, 0, 16, 16, 1, false)); // srcX < 0
ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, -1, 16, 16, 1, false)); // srcY < 0
- ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, image_1x.width + 1, 16, 1, false)); // right edge out of bounds
- ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, 16, image_1x.height + 1, 1, false)); // bottom edge out of bounds
+ ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, image_1x.size.width + 1, 16, 1, false)); // right edge out of bounds
+ ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, 16, image_1x.size.height + 1, 1, false)); // bottom edge out of bounds
- EXPECT_EQ(13u, log.count({
+ EXPECT_EQ(1u, log.count({
+ EventSeverity::Error,
+ Event::Sprite,
+ int64_t(-1),
+ "Can't create sprite with invalid metrics: 0x16@0,0 in 200x299@1x sprite",
+ }));
+
+ EXPECT_EQ(1u, log.count({
+ EventSeverity::Error,
+ Event::Sprite,
+ int64_t(-1),
+ "Can't create sprite with invalid metrics: 16x0@0,0 in 200x299@1x sprite",
+ }));
+
+ EXPECT_EQ(1u, log.count({
+ EventSeverity::Error,
+ Event::Sprite,
+ int64_t(-1),
+ "Can't create sprite with invalid metrics: 4294967295x16@0,0 in 200x299@1x sprite",
+ }));
+
+ EXPECT_EQ(1u, log.count({
+ EventSeverity::Error,
+ Event::Sprite,
+ int64_t(-1),
+ "Can't create sprite with invalid metrics: 16x4294967295@0,0 in 200x299@1x sprite",
+ }));
+
+ EXPECT_EQ(1u, log.count({
+ EventSeverity::Error,
+ Event::Sprite,
+ int64_t(-1),
+ "Can't create sprite with invalid metrics: 1x1@0,0 in 200x299@0x sprite",
+ }));
+
+ EXPECT_EQ(1u, log.count({
+ EventSeverity::Error,
+ Event::Sprite,
+ int64_t(-1),
+ "Can't create sprite with invalid metrics: 1x1@0,0 in 200x299@-1x sprite",
+ }));
+
+ EXPECT_EQ(1u, log.count({
EventSeverity::Error,
Event::Sprite,
int64_t(-1),
- "Can't create sprite with invalid metrics",
+ "Can't create sprite with invalid metrics: 1x1@0,0 in 200x299@23x sprite",
}));
+
+ EXPECT_EQ(1u, log.count({
+ EventSeverity::Error,
+ Event::Sprite,
+ int64_t(-1),
+ "Can't create sprite with invalid metrics: 2048x16@0,0 in 200x299@1x sprite",
+ }));
+
+ EXPECT_EQ(1u, log.count({
+ EventSeverity::Error,
+ Event::Sprite,
+ int64_t(-1),
+ "Can't create sprite with invalid metrics: 16x1025@0,0 in 200x299@1x sprite",
+ }));
+
+ EXPECT_EQ(1u, log.count({
+ EventSeverity::Error,
+ Event::Sprite,
+ int64_t(-1),
+ "Can't create sprite with invalid metrics: 16x16@4294967295,0 in 200x299@1x sprite",
+ }));
+
+ EXPECT_EQ(1u, log.count({
+ EventSeverity::Error,
+ Event::Sprite,
+ int64_t(-1),
+ "Can't create sprite with invalid metrics: 16x16@0,4294967295 in 200x299@1x sprite",
+ }));
+
+ EXPECT_EQ(1u, log.count({
+ EventSeverity::Error,
+ Event::Sprite,
+ int64_t(-1),
+ "Can't create sprite with invalid metrics: 201x16@0,0 in 200x299@1x sprite",
+ }));
+
+ EXPECT_EQ(1u, log.count({
+ EventSeverity::Error,
+ Event::Sprite,
+ int64_t(-1),
+ "Can't create sprite with invalid metrics: 16x300@0,0 in 200x299@1x sprite",
+ }));
+
}
TEST(Sprite, SpriteImageCreation1x) {
const PremultipliedImage image_1x = decodeImage(util::read_file("test/fixtures/annotations/emerald.png"));
- ASSERT_EQ(200u, image_1x.width);
- ASSERT_EQ(299u, image_1x.height);
+ ASSERT_EQ(200u, image_1x.size.width);
+ ASSERT_EQ(299u, image_1x.size.height);
{ // "museum_icon":{"x":177,"y":187,"width":18,"height":18,"pixelRatio":1,"sdf":false}
const auto sprite = createSpriteImage(image_1x, 177, 187, 18, 18, 1, false);
ASSERT_TRUE(sprite.get());
EXPECT_EQ(18, sprite->getWidth());
EXPECT_EQ(18, sprite->getHeight());
- EXPECT_EQ(18u, sprite->image.width);
- EXPECT_EQ(18u, sprite->image.height);
+ EXPECT_EQ(18u, sprite->image.size.width);
+ EXPECT_EQ(18u, sprite->image.size.height);
EXPECT_EQ(1, sprite->pixelRatio);
EXPECT_EQ(readImage("test/fixtures/annotations/result-spriteimagecreation1x-museum.png"),
sprite->image);
@@ -76,8 +161,8 @@ TEST(Sprite, SpriteImageCreation2x) {
ASSERT_TRUE(sprite.get());
EXPECT_EQ(18, sprite->getWidth());
EXPECT_EQ(18, sprite->getHeight());
- EXPECT_EQ(36u, sprite->image.width);
- EXPECT_EQ(36u, sprite->image.height);
+ EXPECT_EQ(36u, sprite->image.size.width);
+ EXPECT_EQ(36u, sprite->image.size.height);
EXPECT_EQ(2, sprite->pixelRatio);
EXPECT_EQ(readImage("test/fixtures/annotations/result-spriteimagecreation2x.png"),
sprite->image);
@@ -91,8 +176,8 @@ TEST(Sprite, SpriteImageCreation1_5x) {
ASSERT_TRUE(sprite.get());
EXPECT_EQ(24, sprite->getWidth());
EXPECT_EQ(24, sprite->getHeight());
- EXPECT_EQ(36u, sprite->image.width);
- EXPECT_EQ(36u, sprite->image.height);
+ EXPECT_EQ(36u, sprite->image.size.width);
+ EXPECT_EQ(36u, sprite->image.size.height);
EXPECT_EQ(1.5, sprite->pixelRatio);
EXPECT_EQ(readImage("test/fixtures/annotations/result-spriteimagecreation1_5x-museum.png"),
sprite->image);
@@ -102,8 +187,8 @@ TEST(Sprite, SpriteImageCreation1_5x) {
ASSERT_TRUE(sprite2.get());
EXPECT_EQ(float(35 / 1.5), sprite2->getWidth());
EXPECT_EQ(float(35 / 1.5), sprite2->getHeight());
- EXPECT_EQ(35u, sprite2->image.width);
- EXPECT_EQ(35u, sprite2->image.height);
+ EXPECT_EQ(35u, sprite2->image.size.width);
+ EXPECT_EQ(35u, sprite2->image.size.height);
EXPECT_EQ(1.5, sprite2->pixelRatio);
EXPECT_EQ(readImage("test/fixtures/annotations/result-spriteimagecreation1_5x-hospital.png"),
sprite2->image);
@@ -198,8 +283,8 @@ TEST(Sprite, SpriteParsing) {
auto sprite = images.find("generic-metro")->second;
EXPECT_EQ(18, sprite->getWidth());
EXPECT_EQ(18, sprite->getHeight());
- EXPECT_EQ(18u, sprite->image.width);
- EXPECT_EQ(18u, sprite->image.height);
+ EXPECT_EQ(18u, sprite->image.size.width);
+ EXPECT_EQ(18u, sprite->image.size.height);
EXPECT_EQ(1, sprite->pixelRatio);
EXPECT_EQ(readImage("test/fixtures/annotations/result-spriteparsing.png"), sprite->image);
}
@@ -228,7 +313,7 @@ TEST(Sprite, SpriteParsingEmptyImage) {
EventSeverity::Error,
Event::Sprite,
int64_t(-1),
- "Can't create sprite with invalid metrics",
+ "Can't create sprite with invalid metrics: 0x0@0,0 in 200x299@1x sprite",
}));
}
@@ -261,7 +346,7 @@ TEST(Sprite, SpriteParsingWidthTooBig) {
EventSeverity::Error,
Event::Sprite,
int64_t(-1),
- "Can't create sprite with invalid metrics",
+ "Can't create sprite with invalid metrics: 0x32@0,0 in 200x299@1x sprite",
}));
}
@@ -284,7 +369,7 @@ TEST(Sprite, SpriteParsingNegativeWidth) {
EventSeverity::Error,
Event::Sprite,
int64_t(-1),
- "Can't create sprite with invalid metrics",
+ "Can't create sprite with invalid metrics: 0x32@0,0 in 200x299@1x sprite",
}));
}
@@ -301,6 +386,6 @@ TEST(Sprite, SpriteParsingNullRatio) {
EventSeverity::Error,
Event::Sprite,
int64_t(-1),
- "Can't create sprite with invalid metrics",
+ "Can't create sprite with invalid metrics: 32x32@0,0 in 200x299@0x sprite",
}));
}
diff --git a/test/src/mbgl/test/conversion_stubs.hpp b/test/src/mbgl/test/conversion_stubs.hpp
index b80a2c98bd..ddffb1e3b2 100644
--- a/test/src/mbgl/test/conversion_stubs.hpp
+++ b/test/src/mbgl/test/conversion_stubs.hpp
@@ -104,7 +104,7 @@ inline optional<mbgl::Value> toValue(const Value& value) {
} else if (value.is<std::string>()) {
return { value.get<std::string>() };
} else if (value.is<float>()) {
- return { value.get<float>() };
+ return { double(value.get<float>()) };
} else {
return {};
}
diff --git a/test/src/mbgl/test/fixture_log_observer.hpp b/test/src/mbgl/test/fixture_log_observer.hpp
index 918bbee18c..96ddc2c54f 100644
--- a/test/src/mbgl/test/fixture_log_observer.hpp
+++ b/test/src/mbgl/test/fixture_log_observer.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
#include <vector>
#include <cstdarg>
diff --git a/test/src/mbgl/test/util.cpp b/test/src/mbgl/test/util.cpp
index 7f98c43dc9..7ca2d72504 100644
--- a/test/src/mbgl/test/util.cpp
+++ b/test/src/mbgl/test/util.cpp
@@ -1,8 +1,9 @@
#include <mbgl/test/util.hpp>
#include <mbgl/map/map.hpp>
-#include <mbgl/platform/default/offscreen_view.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/gl/offscreen_view.hpp>
+#include <mbgl/gl/headless_display.hpp>
+#include <mbgl/util/logging.hpp>
#include <mbgl/util/image.hpp>
#include <mbgl/util/io.hpp>
#include <mbgl/util/chrono.hpp>
@@ -98,13 +99,18 @@ Server::~Server() {
}
}
+std::shared_ptr<HeadlessDisplay> sharedDisplay() {
+ static auto display = std::make_shared<HeadlessDisplay>();
+ return display;
+}
+
PremultipliedImage render(Map& map, OffscreenView& view) {
PremultipliedImage result;
map.renderStill(view, [&](std::exception_ptr) {
result = view.readStillImage();
});
- while (!result.size()) {
+ while (!result.valid()) {
util::RunLoop::Get()->runOnce();
}
@@ -132,24 +138,23 @@ void checkImage(const std::string& base,
}
PremultipliedImage expected = decodeImage(expected_image);
- PremultipliedImage diff { expected.width, expected.height };
+ PremultipliedImage diff { expected.size };
#if !TEST_READ_ONLY
util::write_file(base + "/actual.png", encodePNG(actual));
#endif
- ASSERT_EQ(expected.width, actual.width);
- ASSERT_EQ(expected.height, actual.height);
+ ASSERT_EQ(expected.size, actual.size);
double pixels = mapbox::pixelmatch(actual.data.get(),
expected.data.get(),
- expected.width,
- expected.height,
+ expected.size.width,
+ expected.size.height,
diff.data.get(),
pixelThreshold);
- EXPECT_LE(pixels / (expected.width * expected.height), imageThreshold);
+ EXPECT_LE(pixels / (expected.size.width * expected.size.height), imageThreshold);
#if !TEST_READ_ONLY
util::write_file(base + "/diff.png", encodePNG(diff));
diff --git a/test/src/mbgl/test/util.hpp b/test/src/mbgl/test/util.hpp
index b8ecf175aa..34d8969d3c 100644
--- a/test/src/mbgl/test/util.hpp
+++ b/test/src/mbgl/test/util.hpp
@@ -4,7 +4,10 @@
#include <TargetConditionals.h>
#endif
-#if TARGET_OS_IOS
+#if __ANDROID__
+#define TEST_READ_ONLY 0
+#define TEST_HAS_SERVER 0
+#elif TARGET_OS_IOS
#define TEST_READ_ONLY 1
#define TEST_HAS_SERVER 0
#else
@@ -46,6 +49,7 @@
#include <mbgl/util/chrono.hpp>
#include <cstdint>
+#include <memory>
#include <gtest/gtest.h>
@@ -53,6 +57,7 @@ namespace mbgl {
class Map;
class OffscreenView;
+class HeadlessDisplay;
namespace test {
@@ -65,6 +70,8 @@ private:
int fd = -1;
};
+std::shared_ptr<HeadlessDisplay> sharedDisplay();
+
PremultipliedImage render(Map&, OffscreenView&);
void checkImage(const std::string& base,
diff --git a/test/storage/asset_file_source.test.cpp b/test/storage/asset_file_source.test.cpp
index ab214ff793..7e634fc68e 100644
--- a/test/storage/asset_file_source.test.cpp
+++ b/test/storage/asset_file_source.test.cpp
@@ -1,5 +1,5 @@
#include <mbgl/storage/asset_file_source.hpp>
-#include <mbgl/platform/platform.hpp>
+#include <mbgl/util/platform.hpp>
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/run_loop.hpp>
#include <mbgl/util/thread.hpp>
@@ -27,7 +27,7 @@ TEST(AssetFileSource, Load) {
AssetFileSource fs(getFileSourceRoot());
// iOS seems to run out of file descriptors...
-#if TARGET_OS_IPHONE
+#if TARGET_OS_IPHONE || __ANDROID__
unsigned numThreads = 30;
#else
unsigned numThreads = 50;
diff --git a/test/storage/local_file_source.test.cpp b/test/storage/local_file_source.test.cpp
index afb418d735..c2f04d7543 100644
--- a/test/storage/local_file_source.test.cpp
+++ b/test/storage/local_file_source.test.cpp
@@ -1,5 +1,5 @@
#include <mbgl/storage/local_file_source.hpp>
-#include <mbgl/platform/platform.hpp>
+#include <mbgl/util/platform.hpp>
#include <mbgl/util/run_loop.hpp>
#include <unistd.h>
diff --git a/test/storage/online_file_source.test.cpp b/test/storage/online_file_source.test.cpp
index 95b330390f..966ef6239a 100644
--- a/test/storage/online_file_source.test.cpp
+++ b/test/storage/online_file_source.test.cpp
@@ -149,7 +149,7 @@ TEST(OnlineFileSource, TEST_REQUIRES_SERVER(RetryDelayOnExpiredTile)) {
std::unique_ptr<AsyncRequest> req = fs.request(resource, [&](Response res) {
counter++;
EXPECT_EQ(nullptr, res.error);
- EXPECT_GT(util::now(), res.expires);
+ EXPECT_GT(util::now(), *res.expires);
});
util::Timer timer;
@@ -173,14 +173,14 @@ TEST(OnlineFileSource, TEST_REQUIRES_SERVER(RetryOnClockSkew)) {
switch (counter++) {
case 0: {
EXPECT_EQ(nullptr, res.error);
- EXPECT_GT(util::now(), res.expires);
+ EXPECT_GT(util::now(), *res.expires);
} break;
case 1: {
EXPECT_EQ(nullptr, res.error);
auto now = util::now();
- EXPECT_LT(now + Seconds(40), res.expires) << "Expiration not interpolated to 60s";
- EXPECT_GT(now + Seconds(80), res.expires) << "Expiration not interpolated to 60s";
+ EXPECT_LT(now + Seconds(40), *res.expires) << "Expiration not interpolated to 60s";
+ EXPECT_GT(now + Seconds(80), *res.expires) << "Expiration not interpolated to 60s";
loop.stop();
} break;
@@ -413,4 +413,4 @@ TEST(OnlineFileSource, ChangeAPIBaseURL){
const std::string customURL = "test.domain";
fs.setAPIBaseURL(customURL);
EXPECT_EQ(customURL, fs.getAPIBaseURL());
-} \ No newline at end of file
+}
diff --git a/test/style/conversion/geojson_options.test.cpp b/test/style/conversion/geojson_options.test.cpp
index 46a2aa950b..14a7adbba7 100644
--- a/test/style/conversion/geojson_options.test.cpp
+++ b/test/style/conversion/geojson_options.test.cpp
@@ -4,7 +4,7 @@
#include <mbgl/style/conversion/geojson_options.hpp>
#include <mbgl/test/conversion_stubs.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
using namespace mbgl::style;
using namespace mbgl::style::conversion;
@@ -17,7 +17,7 @@ TEST(GeoJSONOptions, Basic) {
}
TEST(GeoJSONOptions, ErrorHandling) {
- ValueMap map {{"maxzoom", "should not be a string"}};
+ ValueMap map {{"maxzoom", std::string{"should not be a string"}}};
Value raw(map);
Result<GeoJSONOptions> converted = convert<GeoJSONOptions>(raw);
ASSERT_FALSE((bool) converted);
@@ -44,14 +44,14 @@ TEST(GeoJSONOptions, RetainsDefaults) {
TEST(GeoJSONOptions, FullConversion) {
ValueMap map {
//GeoJSON-VT
- {"maxzoom", 1},
- {"buffer", 2},
- {"tolerance", 3},
+ {"maxzoom", 1.0f},
+ {"buffer", 2.0f},
+ {"tolerance", 3.0f},
//Supercluster
{"cluster", true},
- {"clusterRadius", 4},
- {"clusterMaxZoom", 5}
+ {"clusterRadius", 4.0f},
+ {"clusterMaxZoom", 5.0f}
};
Value raw(map);
GeoJSONOptions converted = *convert<GeoJSONOptions>(raw);
diff --git a/test/style/filter.test.cpp b/test/style/filter.test.cpp
index b49f424a39..33b64978f5 100644
--- a/test/style/filter.test.cpp
+++ b/test/style/filter.test.cpp
@@ -42,7 +42,7 @@ TEST(Filter, EqualsNumber) {
ASSERT_FALSE(f(feature({{ "foo", std::string("0") }})));
ASSERT_FALSE(f(feature({{ "foo", false }})));
ASSERT_FALSE(f(feature({{ "foo", true }})));
- ASSERT_FALSE(f(feature({{ "foo", nullptr }})));
+ ASSERT_FALSE(f(feature({{ "foo", mapbox::geometry::null_value }})));
ASSERT_FALSE(f(feature({{}})));
}
@@ -113,13 +113,13 @@ TEST(Filter, NotHas) {
TEST(Filter, ID) {
Feature feature1 { Point<double>() };
- feature1.id = { 1234 };
+ feature1.id = { uint64_t(1234) };
ASSERT_TRUE(parse("[\"==\", \"$id\", 1234]")(feature1));
ASSERT_FALSE(parse("[\"==\", \"$id\", \"1234\"]")(feature1));
Feature feature2 { Point<double>() };
- feature2.properties["id"] = { 1234 };
+ feature2.properties["id"] = { uint64_t(1234) };
ASSERT_FALSE(parse("[\"==\", \"$id\", 1234]")(feature2));
}
diff --git a/test/style/functions.test.cpp b/test/style/functions.test.cpp
index 9577bcc633..c50787814b 100644
--- a/test/style/functions.test.cpp
+++ b/test/style/functions.test.cpp
@@ -2,16 +2,16 @@
#include <mbgl/test/util.hpp>
#include <mbgl/style/property_evaluator.hpp>
-#include <mbgl/style/calculation_parameters.hpp>
+#include <mbgl/style/property_evaluation_parameters.hpp>
using namespace mbgl;
using namespace mbgl::style;
float evaluate(PropertyValue<float> value, float zoom) {
- return PropertyValue<float>::visit(value, PropertyEvaluator<float>(CalculationParameters(zoom), 0));
+ return value.evaluate(PropertyEvaluator<float>(PropertyEvaluationParameters(zoom), 0));
}
std::string evaluate(PropertyValue<std::string> value, float zoom) {
- return PropertyValue<std::string>::visit(value, PropertyEvaluator<std::string>(CalculationParameters(zoom), ""));
+ return value.evaluate(PropertyEvaluator<std::string>(PropertyEvaluationParameters(zoom), ""));
}
TEST(Function, Constant) {
@@ -50,12 +50,6 @@ TEST(Function, Stops) {
EXPECT_EQ(3.0, evaluate(slope_2, 15));
EXPECT_EQ(3.0, evaluate(slope_2, 22));
- // Test no values.
- Function<float> slope_3({}, 1.75);
- EXPECT_EQ(1, evaluate(slope_3, 2));
- EXPECT_EQ(1, evaluate(slope_3, 6));
- EXPECT_EQ(1, evaluate(slope_3, 12));
-
// Explicit constant slope in fringe regions.
Function<float> slope_4({ { 0, 2 }, { 8, 10 } }, 1);
diff --git a/test/style/source.test.cpp b/test/style/source.test.cpp
index 73908a144b..01f54d6b18 100644
--- a/test/style/source.test.cpp
+++ b/test/style/source.test.cpp
@@ -11,8 +11,8 @@
#include <mbgl/util/string.hpp>
#include <mbgl/util/io.hpp>
#include <mbgl/util/tileset.hpp>
-#include <mbgl/platform/default/thread_pool.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/default_thread_pool.hpp>
+#include <mbgl/util/logging.hpp>
#include <mbgl/map/transform.hpp>
#include <mbgl/style/style.hpp>
@@ -50,7 +50,7 @@ public:
// Squelch logging.
Log::setObserver(std::make_unique<Log::NullObserver>());
- transform.resize({{ 512, 512 }});
+ transform.resize({ 512, 512 });
transform.setLatLngZoom({0, 0}, 0);
transformState = transform.getState();
diff --git a/test/text/glyph_atlas.test.cpp b/test/text/glyph_atlas.test.cpp
index 8634cbe913..020a7140cb 100644
--- a/test/text/glyph_atlas.test.cpp
+++ b/test/text/glyph_atlas.test.cpp
@@ -7,7 +7,7 @@
#include <mbgl/util/run_loop.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/util/io.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
using namespace mbgl;
@@ -16,7 +16,7 @@ public:
util::RunLoop loop;
StubFileSource fileSource;
StubStyleObserver observer;
- GlyphAtlas glyphAtlas { 32, 32, fileSource };
+ GlyphAtlas glyphAtlas{ { 32, 32 }, fileSource };
void run(const std::string& url, const FontStack& fontStack, const GlyphRangeSet& glyphRanges) {
// Squelch logging.
diff --git a/test/text/quads.test.cpp b/test/text/quads.test.cpp
index 421d2f362d..c20218a82f 100644
--- a/test/text/quads.test.cpp
+++ b/test/text/quads.test.cpp
@@ -10,7 +10,7 @@ using namespace mbgl;
using namespace mbgl::style;
TEST(getIconQuads, normal) {
- SymbolLayoutProperties layout;
+ SymbolLayoutProperties::Evaluated layout;
Anchor anchor(2.0, 3.0, 0.0, 0.5f, 0);
SpriteAtlasElement image = {
Rect<uint16_t>( 0, 0, 15, 11 ),
@@ -58,7 +58,7 @@ TEST(getIconQuads, style) {
// none
{
- SymbolLayoutProperties layout;
+ SymbolLayoutProperties::Evaluated layout;
SymbolQuads quads =
getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
@@ -80,9 +80,9 @@ TEST(getIconQuads, style) {
// width
{
- SymbolLayoutProperties layout;
- layout.textSize = LayoutProperty<float>(24.0f);
- layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Width);
+ SymbolLayoutProperties::Evaluated layout;
+ layout.get<TextSize>() = 24.0f;
+ layout.get<IconTextFit>() = IconTextFitType::Width;
SymbolQuads quads =
getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
@@ -98,9 +98,9 @@ TEST(getIconQuads, style) {
// width x textSize
{
- SymbolLayoutProperties layout;
- layout.textSize = LayoutProperty<float>(12.0f);
- layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Width);
+ SymbolLayoutProperties::Evaluated layout;
+ layout.get<TextSize>() = 12.0f;
+ layout.get<IconTextFit>() = IconTextFitType::Width;
SymbolQuads quads =
getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
@@ -116,13 +116,13 @@ TEST(getIconQuads, style) {
// width x textSize + padding
{
- SymbolLayoutProperties layout;
- layout.textSize = LayoutProperty<float>(12.0f);
- layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Width);
- layout.iconTextFitPadding.value[0] = 5.0f;
- layout.iconTextFitPadding.value[1] = 10.0f;
- layout.iconTextFitPadding.value[2] = 5.0f;
- layout.iconTextFitPadding.value[3] = 10.0f;
+ SymbolLayoutProperties::Evaluated layout;
+ layout.get<TextSize>() = 12.0f;
+ layout.get<IconTextFit>() = IconTextFitType::Width;
+ layout.get<IconTextFitPadding>()[0] = 5.0f;
+ layout.get<IconTextFitPadding>()[1] = 10.0f;
+ layout.get<IconTextFitPadding>()[2] = 5.0f;
+ layout.get<IconTextFitPadding>()[3] = 10.0f;
SymbolQuads quads =
getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
@@ -138,9 +138,9 @@ TEST(getIconQuads, style) {
// height
{
- SymbolLayoutProperties layout;
- layout.textSize = LayoutProperty<float>(24.0f);
- layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Height);
+ SymbolLayoutProperties::Evaluated layout;
+ layout.get<TextSize>() = 24.0f;
+ layout.get<IconTextFit>() = IconTextFitType::Height;
SymbolQuads quads =
getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
@@ -156,9 +156,9 @@ TEST(getIconQuads, style) {
// height x textSize
{
- SymbolLayoutProperties layout;
- layout.textSize = LayoutProperty<float>(12.0f);
- layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Height);
+ SymbolLayoutProperties::Evaluated layout;
+ layout.get<TextSize>() = 12.0f;
+ layout.get<IconTextFit>() = IconTextFitType::Height;
SymbolQuads quads =
getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
@@ -174,13 +174,13 @@ TEST(getIconQuads, style) {
// height x textSize + padding
{
- SymbolLayoutProperties layout;
- layout.textSize = LayoutProperty<float>(12.0f);
- layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Height);
- layout.iconTextFitPadding.value[0] = 5.0f;
- layout.iconTextFitPadding.value[1] = 10.0f;
- layout.iconTextFitPadding.value[2] = 5.0f;
- layout.iconTextFitPadding.value[3] = 10.0f;
+ SymbolLayoutProperties::Evaluated layout;
+ layout.get<TextSize>() = 12.0f;
+ layout.get<IconTextFit>() = IconTextFitType::Height;
+ layout.get<IconTextFitPadding>()[0] = 5.0f;
+ layout.get<IconTextFitPadding>()[1] = 10.0f;
+ layout.get<IconTextFitPadding>()[2] = 5.0f;
+ layout.get<IconTextFitPadding>()[3] = 10.0f;
SymbolQuads quads =
getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
@@ -196,9 +196,9 @@ TEST(getIconQuads, style) {
// both
{
- SymbolLayoutProperties layout;
- layout.textSize = LayoutProperty<float>(24.0f);
- layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Both);
+ SymbolLayoutProperties::Evaluated layout;
+ layout.get<TextSize>() = 24.0f;
+ layout.get<IconTextFit>() = IconTextFitType::Both;
SymbolQuads quads =
getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
@@ -214,9 +214,9 @@ TEST(getIconQuads, style) {
// both x textSize
{
- SymbolLayoutProperties layout;
- layout.textSize = LayoutProperty<float>(12.0f);
- layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Both);
+ SymbolLayoutProperties::Evaluated layout;
+ layout.get<TextSize>() = 12.0f;
+ layout.get<IconTextFit>() = IconTextFitType::Both;
SymbolQuads quads =
getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
@@ -232,13 +232,13 @@ TEST(getIconQuads, style) {
// both x textSize + padding
{
- SymbolLayoutProperties layout;
- layout.textSize = LayoutProperty<float>(12.0f);
- layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Both);
- layout.iconTextFitPadding.value[0] = 5.0f;
- layout.iconTextFitPadding.value[1] = 10.0f;
- layout.iconTextFitPadding.value[2] = 5.0f;
- layout.iconTextFitPadding.value[3] = 10.0f;
+ SymbolLayoutProperties::Evaluated layout;
+ layout.get<TextSize>() = 12.0f;
+ layout.get<IconTextFit>() = IconTextFitType::Both;
+ layout.get<IconTextFitPadding>()[0] = 5.0f;
+ layout.get<IconTextFitPadding>()[1] = 10.0f;
+ layout.get<IconTextFitPadding>()[2] = 5.0f;
+ layout.get<IconTextFitPadding>()[3] = 10.0f;
SymbolQuads quads =
getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
@@ -254,13 +254,13 @@ TEST(getIconQuads, style) {
// both x textSize + padding t/r/b/l
{
- SymbolLayoutProperties layout;
- layout.textSize = LayoutProperty<float>(12.0f);
- layout.iconTextFit = LayoutProperty<IconTextFitType>(IconTextFitType::Both);
- layout.iconTextFitPadding.value[0] = 0.0f;
- layout.iconTextFitPadding.value[1] = 5.0f;
- layout.iconTextFitPadding.value[2] = 10.0f;
- layout.iconTextFitPadding.value[3] = 15.0f;
+ SymbolLayoutProperties::Evaluated layout;
+ layout.get<TextSize>() = 12.0f;
+ layout.get<IconTextFit>() = IconTextFitType::Both;
+ layout.get<IconTextFitPadding>()[0] = 0.0f;
+ layout.get<IconTextFitPadding>()[1] = 5.0f;
+ layout.get<IconTextFitPadding>()[2] = 10.0f;
+ layout.get<IconTextFitPadding>()[3] = 15.0f;
SymbolQuads quads =
getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
diff --git a/test/tile/raster_tile.test.cpp b/test/tile/raster_tile.test.cpp
index 2a15fd1b99..0d599ceae0 100644
--- a/test/tile/raster_tile.test.cpp
+++ b/test/tile/raster_tile.test.cpp
@@ -3,7 +3,7 @@
#include <mbgl/tile/raster_tile.hpp>
#include <mbgl/tile/tile_loader_impl.hpp>
-#include <mbgl/platform/default/thread_pool.hpp>
+#include <mbgl/util/default_thread_pool.hpp>
#include <mbgl/util/run_loop.hpp>
#include <mbgl/map/transform.hpp>
#include <mbgl/style/style.hpp>
diff --git a/test/tile/tile_coordinate.test.cpp b/test/tile/tile_coordinate.test.cpp
index 740a03894d..4d58bf8c51 100644
--- a/test/tile/tile_coordinate.test.cpp
+++ b/test/tile/tile_coordinate.test.cpp
@@ -26,8 +26,7 @@ TEST(TileCoordinate, FromLatLng) {
Transform transform(onMapChange);
const double max = util::tileSize;
- const std::array<uint16_t, 2> size { { uint16_t(max), uint16_t(max) } };
- transform.resize(size);
+ transform.resize({ static_cast<uint32_t>(max), static_cast<uint32_t>(max) });
// Center, top-left, bottom-left, bottom-right, top-right edges.
std::vector<std::pair<LatLng, ScreenCoordinate>> edges {
diff --git a/test/tile/vector_tile.test.cpp b/test/tile/vector_tile.test.cpp
index c07db42c3c..210422feec 100644
--- a/test/tile/vector_tile.test.cpp
+++ b/test/tile/vector_tile.test.cpp
@@ -3,7 +3,7 @@
#include <mbgl/tile/vector_tile.hpp>
#include <mbgl/tile/tile_loader_impl.hpp>
-#include <mbgl/platform/default/thread_pool.hpp>
+#include <mbgl/util/default_thread_pool.hpp>
#include <mbgl/util/run_loop.hpp>
#include <mbgl/map/transform.hpp>
#include <mbgl/style/style.hpp>
diff --git a/test/util/http_timeout.test.cpp b/test/util/http_timeout.test.cpp
index 365c40523f..e99c703159 100644
--- a/test/util/http_timeout.test.cpp
+++ b/test/util/http_timeout.test.cpp
@@ -1,6 +1,6 @@
#include <mbgl/test/util.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
#include <mbgl/util/http_timeout.hpp>
#include <regex>
#include <iostream>
diff --git a/test/util/image.test.cpp b/test/util/image.test.cpp
index b2814e66da..b15ddc1b3f 100644
--- a/test/util/image.test.cpp
+++ b/test/util/image.test.cpp
@@ -7,7 +7,7 @@
using namespace mbgl;
TEST(Image, PNGRoundTrip) {
- PremultipliedImage rgba { 1, 1 };
+ PremultipliedImage rgba({ 1, 1 });
rgba.data[0] = 128;
rgba.data[1] = 0;
rgba.data[2] = 0;
@@ -21,7 +21,7 @@ TEST(Image, PNGRoundTrip) {
}
TEST(Image, PNGRoundTripAlpha) {
- PremultipliedImage rgba { 1, 1 };
+ PremultipliedImage rgba({ 1, 1 });
rgba.data[0] = 128;
rgba.data[1] = 0;
rgba.data[2] = 0;
@@ -68,26 +68,26 @@ TEST(Image, PNGReadProfileAlpha) {
TEST(Image, PNGTile) {
PremultipliedImage image = decodeImage(util::read_file("test/fixtures/image/tile.png"));
- EXPECT_EQ(256u, image.width);
- EXPECT_EQ(256u, image.height);
+ EXPECT_EQ(256u, image.size.width);
+ EXPECT_EQ(256u, image.size.height);
}
TEST(Image, JPEGTile) {
PremultipliedImage image = decodeImage(util::read_file("test/fixtures/image/tile.jpeg"));
- EXPECT_EQ(256u, image.width);
- EXPECT_EQ(256u, image.height);
+ EXPECT_EQ(256u, image.size.width);
+ EXPECT_EQ(256u, image.size.height);
}
#if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(QT_IMAGE_DECODERS)
TEST(Image, WebPTile) {
PremultipliedImage image = decodeImage(util::read_file("test/fixtures/image/tile.webp"));
- EXPECT_EQ(256u, image.width);
- EXPECT_EQ(256u, image.height);
+ EXPECT_EQ(256u, image.size.width);
+ EXPECT_EQ(256u, image.size.height);
}
#endif // !defined(__ANDROID__) && !defined(__APPLE__) && !defined(QT_IMAGE_DECODERS)
TEST(Image, Premultiply) {
- UnassociatedImage rgba { 1, 1 };
+ UnassociatedImage rgba({ 1, 1 });
rgba.data[0] = 255;
rgba.data[1] = 254;
rgba.data[2] = 253;
diff --git a/test/util/mapbox.test.cpp b/test/util/mapbox.test.cpp
index 04c9808ed3..70bb8d0700 100644
--- a/test/util/mapbox.test.cpp
+++ b/test/util/mapbox.test.cpp
@@ -1,6 +1,6 @@
#include <mbgl/test/util.hpp>
-#include <mbgl/platform/log.hpp>
+#include <mbgl/util/logging.hpp>
#include <mbgl/util/mapbox.hpp>
#include <mbgl/util/constants.hpp>
#include <regex>
diff --git a/test/util/memory.test.cpp b/test/util/memory.test.cpp
index a1e47d6c2b..984e7a3e24 100644
--- a/test/util/memory.test.cpp
+++ b/test/util/memory.test.cpp
@@ -2,9 +2,9 @@
#include <mbgl/test/util.hpp>
#include <mbgl/map/map.hpp>
-#include <mbgl/platform/default/headless_backend.hpp>
-#include <mbgl/platform/default/offscreen_view.hpp>
-#include <mbgl/platform/default/thread_pool.hpp>
+#include <mbgl/gl/headless_backend.hpp>
+#include <mbgl/gl/offscreen_view.hpp>
+#include <mbgl/util/default_thread_pool.hpp>
#include <mbgl/util/io.hpp>
#include <mbgl/util/run_loop.hpp>
@@ -56,8 +56,8 @@ public:
}
util::RunLoop runLoop;
- HeadlessBackend backend;
- OffscreenView view{ backend.getContext(), {{ 512, 512 }} };
+ HeadlessBackend backend { test::sharedDisplay() };
+ OffscreenView view{ backend.getContext(), { 512, 512 } };
StubFileSource fileSource;
ThreadPool threadPool { 4 };
@@ -93,7 +93,7 @@ private:
TEST(Memory, Vector) {
MemoryTest test;
- Map map(test.backend, { { 256, 256 } }, 2, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, { 256, 256 }, 2, test.fileSource, test.threadPool, MapMode::Still);
map.setZoom(16); // more map features
map.setStyleURL("mapbox://streets");
@@ -103,7 +103,7 @@ TEST(Memory, Vector) {
TEST(Memory, Raster) {
MemoryTest test;
- Map map(test.backend, { { 256, 256 } }, 2, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, { 256, 256 }, 2, test.fileSource, test.threadPool, MapMode::Still);
map.setStyleURL("mapbox://satellite");
test::render(map, test.view);
@@ -129,7 +129,7 @@ TEST(Memory, Footprint) {
// Warm up buffers and cache.
for (unsigned i = 0; i < 10; ++i) {
- Map map(test.backend, {{ 256, 256 }}, 2, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, { 256, 256 }, 2, test.fileSource, test.threadPool, MapMode::Still);
renderMap(map, "mapbox://streets");
renderMap(map, "mapbox://satellite");
};
@@ -143,8 +143,8 @@ TEST(Memory, Footprint) {
long vectorInitialRSS = getRSS();
for (unsigned i = 0; i < runs; ++i) {
- auto vector = std::make_unique<Map>(test.backend, std::array<uint16_t, 2>{ { 256, 256 } },
- 2, test.fileSource, test.threadPool, MapMode::Still);
+ auto vector = std::make_unique<Map>(test.backend, Size{ 256, 256 }, 2, test.fileSource,
+ test.threadPool, MapMode::Still);
renderMap(*vector, "mapbox://streets");
maps.push_back(std::move(vector));
};
@@ -153,8 +153,8 @@ TEST(Memory, Footprint) {
long rasterInitialRSS = getRSS();
for (unsigned i = 0; i < runs; ++i) {
- auto raster = std::make_unique<Map>(test.backend, std::array<uint16_t, 2>{ { 256, 256 } },
- 2, test.fileSource, test.threadPool, MapMode::Still);
+ auto raster = std::make_unique<Map>(test.backend, Size{ 256, 256 }, 2, test.fileSource,
+ test.threadPool, MapMode::Still);
renderMap(*raster, "mapbox://satellite");
maps.push_back(std::move(raster));
};
diff --git a/test/util/merge_lines.test.cpp b/test/util/merge_lines.test.cpp
index db81d8b209..4856a734fe 100644
--- a/test/util/merge_lines.test.cpp
+++ b/test/util/merge_lines.test.cpp
@@ -3,27 +3,29 @@
#include <mbgl/layout/merge_lines.hpp>
#include <mbgl/layout/symbol_feature.hpp>
-const std::u32string aaa = U"a";
-const std::u32string bbb = U"b";
+const std::u16string aaa = u"a";
+const std::u16string bbb = u"b";
+
+using namespace mbgl;
TEST(MergeLines, SameText) {
// merges lines with the same text
std::vector<mbgl::SymbolFeature> input1 = {
- { {{{0, 0}, {1, 0}, {2, 0}}}, aaa, {}, 0 },
- { {{{4, 0}, {5, 0}, {6, 0}}}, bbb, {}, 0 },
- { {{{8, 0}, {9, 0}}}, aaa, {}, 0 },
- { {{{2, 0}, {3, 0}, {4, 0}}}, aaa, {}, 0 },
- { {{{6, 0}, {7, 0}, {8, 0}}}, aaa, {}, 0 },
- { {{{5, 0}, {6, 0}}}, aaa, {}, 0 }
+ { FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}}}, aaa, {}, 0 },
+ { FeatureType::LineString, {{{4, 0}, {5, 0}, {6, 0}}}, bbb, {}, 0 },
+ { FeatureType::LineString, {{{8, 0}, {9, 0}}}, aaa, {}, 0 },
+ { FeatureType::LineString, {{{2, 0}, {3, 0}, {4, 0}}}, aaa, {}, 0 },
+ { FeatureType::LineString, {{{6, 0}, {7, 0}, {8, 0}}}, aaa, {}, 0 },
+ { FeatureType::LineString, {{{5, 0}, {6, 0}}}, aaa, {}, 0 }
};
const std::vector<mbgl::SymbolFeature> expected1 = {
- { {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}}}, aaa, {}, 0 },
- { {{{4, 0}, {5, 0}, {6, 0}}}, bbb, {}, 0 },
- { {{{5, 0}, {6, 0}, {7, 0}, {8, 0}, {9, 0}}}, aaa, {}, 0 },
- { {{}}, aaa, {}, 0 },
- { {{}}, aaa, {}, 0 },
- { {{}}, aaa, {}, 0 }
+ { FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}}}, aaa, {}, 0 },
+ { FeatureType::LineString, {{{4, 0}, {5, 0}, {6, 0}}}, bbb, {}, 0 },
+ { FeatureType::LineString, {{{5, 0}, {6, 0}, {7, 0}, {8, 0}, {9, 0}}}, aaa, {}, 0 },
+ { FeatureType::LineString, {{}}, aaa, {}, 0 },
+ { FeatureType::LineString, {{}}, aaa, {}, 0 },
+ { FeatureType::LineString, {{}}, aaa, {}, 0 }
};
mbgl::util::mergeLines(input1);
@@ -36,15 +38,15 @@ TEST(MergeLines, SameText) {
TEST(MergeLines, BothEnds) {
// mergeLines handles merge from both ends
std::vector<mbgl::SymbolFeature> input2 = {
- { {{{0, 0}, {1, 0}, {2, 0}}}, aaa, {}, 0 },
- { {{{4, 0}, {5, 0}, {6, 0}}}, aaa, {}, 0 },
- { {{{2, 0}, {3, 0}, {4, 0}}}, aaa, {}, 0 }
+ { FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}}}, aaa, {}, 0 },
+ { FeatureType::LineString, {{{4, 0}, {5, 0}, {6, 0}}}, aaa, {}, 0 },
+ { FeatureType::LineString, {{{2, 0}, {3, 0}, {4, 0}}}, aaa, {}, 0 }
};
const std::vector<mbgl::SymbolFeature> expected2 = {
- { {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}}}, aaa, {}, 0 },
- { {{}}, aaa, {}, 0 },
- { {{}}, aaa, {}, 0 }
+ { FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}}}, aaa, {}, 0 },
+ { FeatureType::LineString, {{}}, aaa, {}, 0 },
+ { FeatureType::LineString, {{}}, aaa, {}, 0 }
};
mbgl::util::mergeLines(input2);
@@ -57,15 +59,15 @@ TEST(MergeLines, BothEnds) {
TEST(MergeLines, CircularLines) {
// mergeLines handles circular lines
std::vector<mbgl::SymbolFeature> input3 = {
- { {{{0, 0}, {1, 0}, {2, 0}}}, aaa, {}, 0 },
- { {{{2, 0}, {3, 0}, {4, 0}}}, aaa, {}, 0 },
- { {{{4, 0}, {0, 0}}}, aaa, {}, 0 }
+ { FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}}}, aaa, {}, 0 },
+ { FeatureType::LineString, {{{2, 0}, {3, 0}, {4, 0}}}, aaa, {}, 0 },
+ { FeatureType::LineString, {{{4, 0}, {0, 0}}}, aaa, {}, 0 }
};
const std::vector<mbgl::SymbolFeature> expected3 = {
- { {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {0, 0}}}, aaa, {}, 0 },
- { {{}}, aaa, {}, 0 },
- { {{}}, aaa, {}, 0 }
+ { FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {0, 0}}}, aaa, {}, 0 },
+ { FeatureType::LineString, {{}}, aaa, {}, 0 },
+ { FeatureType::LineString, {{}}, aaa, {}, 0 }
};
mbgl::util::mergeLines(input3);
diff --git a/test/util/offscreen_texture.test.cpp b/test/util/offscreen_texture.test.cpp
index 4aded07b2f..31fb985394 100644
--- a/test/util/offscreen_texture.test.cpp
+++ b/test/util/offscreen_texture.test.cpp
@@ -2,16 +2,16 @@
#include <mbgl/gl/gl.hpp>
#include <mbgl/gl/context.hpp>
-#include <mbgl/platform/default/headless_backend.hpp>
-#include <mbgl/platform/default/offscreen_view.hpp>
+#include <mbgl/gl/headless_backend.hpp>
+#include <mbgl/gl/offscreen_view.hpp>
#include <mbgl/util/offscreen_texture.hpp>
using namespace mbgl;
TEST(OffscreenTexture, EmptyRed) {
- HeadlessBackend backend;
- OffscreenView view(backend.getContext(), {{ 512, 256 }});
+ HeadlessBackend backend { test::sharedDisplay() };
+ OffscreenView view(backend.getContext(), { 512, 256 });
view.bind();
MBGL_CHECK_ERROR(glClearColor(1.0f, 0.0f, 0.0f, 1.0f));
@@ -67,24 +67,33 @@ struct Buffer {
TEST(OffscreenTexture, RenderToTexture) {
- HeadlessBackend backend;
+ HeadlessBackend backend { test::sharedDisplay() };
auto& context = backend.getContext();
MBGL_CHECK_ERROR(glEnable(GL_BLEND));
MBGL_CHECK_ERROR(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
Shader paintShader(R"MBGL_SHADER(
+#ifdef GL_ES
+precision mediump float;
+#endif
attribute vec2 a_pos;
void main() {
gl_Position = vec4(a_pos, 0, 1);
}
)MBGL_SHADER", R"MBGL_SHADER(
+#ifdef GL_ES
+precision mediump float;
+#endif
void main() {
gl_FragColor = vec4(0, 0.8, 0, 0.8);
}
)MBGL_SHADER");
Shader compositeShader(R"MBGL_SHADER(
+#ifdef GL_ES
+precision mediump float;
+#endif
attribute vec2 a_pos;
varying vec2 v_texcoord;
void main() {
@@ -92,6 +101,9 @@ void main() {
v_texcoord = (a_pos + 1.0) / 2.0;
}
)MBGL_SHADER", R"MBGL_SHADER(
+#ifdef GL_ES
+precision mediump float;
+#endif
uniform sampler2D u_texture;
varying vec2 v_texcoord;
void main() {
@@ -106,22 +118,20 @@ void main() {
// Make sure the texture gets destructed before we call context.reset();
{
- OffscreenView view(context, {{ 512, 256 }});
+ OffscreenView view(context, { 512, 256 });
+ view.bind();
// First, draw red to the bound FBO.
- context.clearColor = { 1, 0, 0, 1 };
- view.bind();
- MBGL_CHECK_ERROR(glClear(GL_COLOR_BUFFER_BIT));
+ context.clear(Color::red(), {}, {});
// Then, create a texture, bind it, and render yellow to that texture. This should not
// affect the originally bound FBO.
- OffscreenTexture texture(context, {{ 128, 128 }});
+ OffscreenTexture texture(context, { 128, 128 });
texture.bind();
- context.clearColor = { 0, 0, 0, 0 };
- MBGL_CHECK_ERROR(glClear(GL_COLOR_BUFFER_BIT));
+ context.clear(Color(), {}, {});
- context.program = paintShader.program;
+ MBGL_CHECK_ERROR(glUseProgram(paintShader.program));
MBGL_CHECK_ERROR(glBindBuffer(GL_ARRAY_BUFFER, triangleBuffer.buffer));
MBGL_CHECK_ERROR(glEnableVertexAttribArray(paintShader.a_pos));
MBGL_CHECK_ERROR(
@@ -138,8 +148,8 @@ void main() {
test::checkImage("test/fixtures/offscreen_texture/render-to-fbo", image, 0, 0);
// Now, composite the Framebuffer texture we've rendered to onto the main FBO.
- context.program = compositeShader.program;
context.bindTexture(texture.getTexture(), 0, gl::TextureFilter::Linear);
+ MBGL_CHECK_ERROR(glUseProgram(compositeShader.program));
MBGL_CHECK_ERROR(glUniform1i(u_texture, 0));
MBGL_CHECK_ERROR(glBindBuffer(GL_ARRAY_BUFFER, viewportBuffer.buffer));
MBGL_CHECK_ERROR(glEnableVertexAttribArray(compositeShader.a_pos));
diff --git a/test/util/text_conversions.test.cpp b/test/util/text_conversions.test.cpp
index 19e30d9f3d..442a49fa0c 100644
--- a/test/util/text_conversions.test.cpp
+++ b/test/util/text_conversions.test.cpp
@@ -2,7 +2,7 @@
#include <mbgl/test/util.hpp>
#include <mbgl/util/utf.hpp>
-#include <mbgl/platform/platform.hpp>
+#include <mbgl/util/platform.hpp>
using namespace mbgl;
diff --git a/test/util/tile_cover.test.cpp b/test/util/tile_cover.test.cpp
index cc183509d9..47440ff0b5 100644
--- a/test/util/tile_cover.test.cpp
+++ b/test/util/tile_cover.test.cpp
@@ -29,7 +29,7 @@ TEST(TileCover, WorldZ0) {
TEST(TileCover, Pitch) {
Transform transform;
- transform.resize({ { 512, 512 } });
+ transform.resize({ 512, 512 });
transform.setZoom(2);
transform.setPitch(40.0 * M_PI / 180.0);
diff --git a/test/util/url.test.cpp b/test/util/url.test.cpp
new file mode 100644
index 0000000000..c0ee30efab
--- /dev/null
+++ b/test/util/url.test.cpp
@@ -0,0 +1,25 @@
+#include <mbgl/test/util.hpp>
+
+#include <mbgl/util/url.hpp>
+
+#include <memory>
+
+using namespace mbgl::util;
+
+TEST(URL, isURL) {
+ EXPECT_TRUE(isURL("mapbox://foo"));
+ EXPECT_TRUE(isURL("mapbox://"));
+ EXPECT_TRUE(isURL("mapbox-test-scheme://foo"));
+ EXPECT_TRUE(isURL("mapbox+style://foo"));
+ EXPECT_TRUE(isURL("mapbox-2.0://foo"));
+ EXPECT_TRUE(isURL("mapbox99://foo"));
+
+ EXPECT_FALSE(isURL("mapbox:/"));
+ EXPECT_FALSE(isURL(" mapbox://"));
+ EXPECT_FALSE(isURL("://"));
+ EXPECT_FALSE(isURL("mapbox"));
+ EXPECT_FALSE(isURL("mapbox:foo"));
+ EXPECT_FALSE(isURL("mapbox:/foo"));
+ EXPECT_FALSE(isURL("test/mapbox://foo"));
+ EXPECT_FALSE(isURL("123://foo"));
+}