From 95fdf3ca0d52acfbee62f677c5fef2e4e180f720 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Wed, 1 Mar 2017 16:23:23 -0500 Subject: [android] - add unit test for Mapbox (#8228) --- .../src/main/java/com/mapbox/mapboxsdk/Mapbox.java | 2 +- .../test/java/com/mapbox/mapboxsdk/MapboxTest.java | 92 ++++++++++++++++++++++ 2 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/MapboxTest.java 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 index f954073974..296d93d0ca 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java @@ -43,7 +43,7 @@ public final class Mapbox { return INSTANCE; } - private Mapbox(@NonNull Context context, @NonNull String accessToken) { + Mapbox(@NonNull Context context, @NonNull String accessToken) { this.context = context; this.accessToken = accessToken; } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/MapboxTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/MapboxTest.java new file mode 100644 index 0000000000..0c1f28515d --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/MapboxTest.java @@ -0,0 +1,92 @@ +package com.mapbox.mapboxsdk; + +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; + +import com.mapbox.mapboxsdk.exceptions.InvalidAccessTokenException; + +import org.junit.Before; +import org.junit.Test; + +import java.lang.reflect.Field; + +import static junit.framework.TestCase.assertNotNull; +import static junit.framework.TestCase.assertSame; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class MapboxTest { + + private Context context; + private Context appContext; + + @Before + public void before() { + context = mock(Context.class); + appContext = mock(Context.class); + when(context.getApplicationContext()).thenReturn(appContext); + } + + @Test + public void testGetAccessToken() { + final String accessToken = "pk.0000000001"; + injectMapboxSingleton(accessToken); + assertSame(accessToken, Mapbox.getAccessToken()); + } + + @Test(expected = InvalidAccessTokenException.class) + public void testGetInvalidAccessToken() { + final String accessToken = "dummy"; + injectMapboxSingleton(accessToken); + assertSame(accessToken, Mapbox.getAccessToken()); + } + + @Test + public void testApplicationContext() { + injectMapboxSingleton("dummy"); + assertNotNull(Mapbox.getApplicationContext()); + assertNotEquals(context, appContext); + assertEquals(appContext, appContext); + } + + @Test + public void testConnected() { + injectMapboxSingleton("dummy"); + + // test Android connectivity + ConnectivityManager connectivityManager = mock(ConnectivityManager.class); + NetworkInfo networkInfo = mock(NetworkInfo.class); + when(appContext.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn(connectivityManager); + when(connectivityManager.getActiveNetworkInfo()).thenReturn(networkInfo); + when(networkInfo.isConnected()).thenReturn(false); + assertFalse(Mapbox.isConnected()); + when(networkInfo.isConnected()).thenReturn(true); + assertTrue(Mapbox.isConnected()); + + // test manual connectivity + Mapbox.setConnected(true); + assertTrue(Mapbox.isConnected()); + Mapbox.setConnected(false); + assertFalse(Mapbox.isConnected()); + + // reset to Android connectivity + Mapbox.setConnected(null); + assertTrue(Mapbox.isConnected()); + } + + private void injectMapboxSingleton(String accessToken) { + Mapbox mapbox = new Mapbox(appContext, accessToken); + try { + Field field = Mapbox.class.getDeclaredField("INSTANCE"); + field.setAccessible(true); + field.set(mapbox, mapbox); + } catch (Exception exception) { + throw new AssertionError(); + } + } +} -- cgit v1.2.1 From ef82095a21b46916cc5a69e0c6996e599e550a80 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Wed, 1 Mar 2017 17:07:01 -0500 Subject: [android] - add accessibility support to the Android SDK by applying content descriptions on Views overlain on the map. (#8230) --- .../mapboxsdk/annotations/MarkerViewManager.java | 1 + .../main/java/com/mapbox/mapboxsdk/maps/MapView.java | 3 +++ .../com/mapbox/mapboxsdk/maps/widgets/CompassView.java | 1 - .../src/main/res-public/values/public.xml | 6 ++++++ .../src/main/res/layout/mapbox_mapview_internal.xml | 18 +++++++++++------- .../src/main/res/layout/mapbox_mapview_preview.xml | 4 ++-- .../MapboxGLAndroidSDK/src/main/res/values/strings.xml | 7 ++++--- 7 files changed, 27 insertions(+), 13 deletions(-) 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 17a1866379..315e12d280 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 @@ -636,6 +636,7 @@ public class MarkerViewManager implements MapView.OnMapChangedListener { viewHolder = (ViewHolder) convertView.getTag(); } viewHolder.imageView.setImageBitmap(marker.getIcon().getBitmap()); + viewHolder.imageView.setContentDescription(marker.getTitle()); return convertView; } 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 16b7bf1800..8fa2d0b152 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 @@ -118,6 +118,9 @@ public class MapView extends FrameLayout { ImageView attrView = (ImageView) view.findViewById(R.id.attributionView); initalizeDrawingSurface(context, options); + // add accessibility support + setContentDescription(context.getString(R.string.mapbox_mapActionDescription)); + // create native Map object nativeMapView = new NativeMapView(this); 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 6d8adc1e2a..5c9cf93ebc 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 @@ -56,7 +56,6 @@ public final class CompassView extends AppCompatImageView implements Runnable, F 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 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 e786aaca4c..641020906a 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/res-public/values/public.xml +++ b/platform/android/MapboxGLAndroidSDK/src/main/res-public/values/public.xml @@ -74,6 +74,12 @@ + + + + + + diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_mapview_internal.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_mapview_internal.xml index 9810e8900b..e6a2677785 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_mapview_internal.xml +++ b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_mapview_internal.xml @@ -5,30 +5,34 @@ android:id="@+id/surfaceView" android:layout_width="match_parent" android:layout_height="match_parent" - android:visibility="gone" /> + android:contentDescription="@null" + android:visibility="gone"/> + android:background="@android:color/transparent" + android:contentDescription="@null"/> + android:layout_height="match_parent" + android:contentDescription="@string/mapbox_myLocationViewContentDescription"/> + android:layout_height="wrap_content" + android:contentDescription="@string/mapbox_compassContentDescription"/> + android:contentDescription="@null" + android:src="@drawable/mapbox_logo_icon"/> + android:src="@drawable/mapbox_info_bg_selector"/> diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_mapview_preview.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_mapview_preview.xml index d87f443586..d015bc5785 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_mapview_preview.xml +++ b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapbox_mapview_preview.xml @@ -17,8 +17,8 @@ android:layout_alignParentLeft="true" 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" /> + android:contentDescription="@null" + android:src="@drawable/mapbox_logo_icon"/> - Map compass. Click to reset the map rotation to North. - Attribution icon. Click to show attribution dialog. + Map compass. Activate to reset the map rotation to North. + Attribution icon. Activate to show attribution dialog. + Location View. This shows your location on the map. + Showing a Map created with Mapbox. Scroll by dragging two fingers. Zoom by pinching two fingers. Mapbox Android SDK Make Mapbox Maps Better You are helping to make OpenStreetMap and Mapbox maps better by contributing anonymous usage data. Agree Disagree More info - The Mapbox logo. Title Description Address -- cgit v1.2.1 From 0c3521d46caeac7ba6c27840f883b4cd3b612316 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Mon, 27 Feb 2017 17:00:42 -0800 Subject: [core] privatize OffscreenTexture implementation --- src/mbgl/util/offscreen_texture.cpp | 66 ++++++++++++++++++++++++++++--------- src/mbgl/util/offscreen_texture.hpp | 13 +++----- 2 files changed, 55 insertions(+), 24 deletions(-) diff --git a/src/mbgl/util/offscreen_texture.cpp b/src/mbgl/util/offscreen_texture.cpp index aad20e59d3..cbe33c8d58 100644 --- a/src/mbgl/util/offscreen_texture.cpp +++ b/src/mbgl/util/offscreen_texture.cpp @@ -1,35 +1,69 @@ -#include #include +#include -#include #include +#include namespace mbgl { -OffscreenTexture::OffscreenTexture(gl::Context& context_, const Size size_) - : size(std::move(size_)), context(context_) { +class OffscreenTexture::Impl { +public: + Impl(gl::Context& context_, const Size size_) : context(context_), size(std::move(size_)) { + assert(size); + } + + void bind() { + if (!framebuffer) { + texture = context.createTexture(size); + framebuffer = context.createFramebuffer(*texture); + } else { + context.bindFramebuffer = framebuffer->framebuffer; + } + + context.viewport = { 0, 0, size }; + } + + PremultipliedImage readStillImage() { + return context.readFramebuffer(size); + } + + gl::Texture& getTexture() { + assert(texture); + return *texture; + } + + const Size& getSize() const { + return size; + } + +private: + gl::Context& context; + const Size size; + optional framebuffer; + optional texture; +}; + +OffscreenTexture::OffscreenTexture(gl::Context& context, const Size size) + : impl(std::make_unique(context, std::move(size))) { assert(size); } +OffscreenTexture::~OffscreenTexture() = default; + void OffscreenTexture::bind() { - if (!framebuffer) { - texture = context.createTexture(size); - framebuffer = context.createFramebuffer(*texture); - } else { - context.bindFramebuffer = framebuffer->framebuffer; - } + impl->bind(); +} - context.viewport = { 0, 0, size }; +PremultipliedImage OffscreenTexture::readStillImage() { + return impl->readStillImage(); } gl::Texture& OffscreenTexture::getTexture() { - assert(texture); - return *texture; + return impl->getTexture(); } -PremultipliedImage OffscreenTexture::readStillImage() { - return context.readFramebuffer(size); +const Size& OffscreenTexture::getSize() const { + return impl->getSize(); } - } // namespace mbgl diff --git a/src/mbgl/util/offscreen_texture.hpp b/src/mbgl/util/offscreen_texture.hpp index 64eb7bc565..b8bfabf7d3 100644 --- a/src/mbgl/util/offscreen_texture.hpp +++ b/src/mbgl/util/offscreen_texture.hpp @@ -1,20 +1,19 @@ #pragma once #include -#include -#include -#include #include namespace mbgl { namespace gl { class Context; +class Texture; } // namespace gl class OffscreenTexture : public View { public: OffscreenTexture(gl::Context&, Size size = { 256, 256 }); + ~OffscreenTexture(); void bind() override; @@ -22,13 +21,11 @@ public: gl::Texture& getTexture(); -public: - const Size size; + const Size& getSize() const; private: - gl::Context& context; - optional framebuffer; - optional texture; + class Impl; + const std::unique_ptr impl; }; } // namespace mbgl -- cgit v1.2.1 From c461dad5eecb17d963c5dcce5db9db28e74f0429 Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Wed, 1 Mar 2017 17:01:22 -0800 Subject: [core] Safeguard ICU UChar usage --- include/mbgl/util/traits.hpp | 16 ++++++++++++++++ platform/default/bidi.cpp | 12 +++++++----- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/include/mbgl/util/traits.hpp b/include/mbgl/util/traits.hpp index 9d6f947cd2..5b9401aad7 100644 --- a/include/mbgl/util/traits.hpp +++ b/include/mbgl/util/traits.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include namespace mbgl { @@ -9,4 +10,19 @@ constexpr auto underlying_type(T t) -> typename std::underlying_type_t { return typename std::underlying_type_t(t); } +template struct is_utf16char_like: std::false_type {}; +template struct is_utf16char_like: is_utf16char_like {}; +template <> struct is_utf16char_like: std::true_type {}; +template <> struct is_utf16char_like: std::true_type {}; +template <> struct is_utf16char_like: std::true_type {}; + +template using is_utf16char_like_pointer = std::integral_constant::value + && is_utf16char_like::type>::value>; + +template +typename std::enable_if::value && is_utf16char_like_pointer::value, OutPointer>::type utf16char_cast(InChar *in) +{ + return reinterpret_cast(in); +} + } // namespace mbgl diff --git a/platform/default/bidi.cpp b/platform/default/bidi.cpp index 08a02ee60f..d9ed2658ef 100644 --- a/platform/default/bidi.cpp +++ b/platform/default/bidi.cpp @@ -1,9 +1,11 @@ -#include - #include +#include + #include #include +#include + namespace mbgl { class BiDiImpl { @@ -28,7 +30,7 @@ std::u16string applyArabicShaping(const std::u16string& input) { UErrorCode errorCode = U_ZERO_ERROR; const int32_t outputLength = - u_shapeArabic(input.c_str(), static_cast(input.size()), NULL, 0, + u_shapeArabic(mbgl::utf16char_cast(input.c_str()), static_cast(input.size()), NULL, 0, (U_SHAPE_LETTERS_SHAPE & U_SHAPE_LETTERS_MASK) | (U_SHAPE_TEXT_DIRECTION_LOGICAL & U_SHAPE_TEXT_DIRECTION_MASK), &errorCode); @@ -38,7 +40,7 @@ std::u16string applyArabicShaping(const std::u16string& input) { std::u16string outputText(outputLength, 0); - u_shapeArabic(input.c_str(), static_cast(input.size()), &outputText[0], outputLength, + u_shapeArabic(mbgl::utf16char_cast(input.c_str()), static_cast(input.size()), mbgl::utf16char_cast(&outputText[0]), outputLength, (U_SHAPE_LETTERS_SHAPE & U_SHAPE_LETTERS_MASK) | (U_SHAPE_TEXT_DIRECTION_LOGICAL & U_SHAPE_TEXT_DIRECTION_MASK), &errorCode); @@ -89,7 +91,7 @@ std::vector BiDi::processText(const std::u16string& input, std::set lineBreakPoints) { UErrorCode errorCode = U_ZERO_ERROR; - ubidi_setPara(impl->bidiText, input.c_str(), static_cast(input.size()), + ubidi_setPara(impl->bidiText, mbgl::utf16char_cast(input.c_str()), static_cast(input.size()), UBIDI_DEFAULT_LTR, NULL, &errorCode); if (U_FAILURE(errorCode)) { -- cgit v1.2.1 From a7b7f3d44297608121dba975586e838f03b6c3c5 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 20 Feb 2017 16:20:04 -0800 Subject: [core] Fix whitespace; no need for explicit on multi-parameter constructors --- src/mbgl/geometry/anchor.hpp | 8 ++- src/mbgl/layout/symbol_instance.cpp | 22 ++++++--- src/mbgl/layout/symbol_instance.hpp | 24 ++++++--- src/mbgl/layout/symbol_layout.hpp | 3 +- src/mbgl/text/check_max_angle.cpp | 10 ++-- src/mbgl/text/check_max_angle.hpp | 9 ++-- src/mbgl/text/collision_feature.cpp | 22 +++++---- src/mbgl/text/collision_feature.hpp | 98 +++++++++++++++++++++---------------- src/mbgl/text/get_anchors.cpp | 33 +++++++++---- src/mbgl/text/get_anchors.hpp | 15 ++++-- src/mbgl/text/quads.cpp | 38 +++++++------- src/mbgl/text/quads.hpp | 46 ++++++++++++----- 12 files changed, 204 insertions(+), 124 deletions(-) diff --git a/src/mbgl/geometry/anchor.hpp b/src/mbgl/geometry/anchor.hpp index 9bc979343e..3ed2b23e1b 100644 --- a/src/mbgl/geometry/anchor.hpp +++ b/src/mbgl/geometry/anchor.hpp @@ -6,17 +6,15 @@ namespace mbgl { -struct Anchor { +class Anchor { +public: Point point; float angle = 0.0f; float scale = 0.0f; int segment = -1; - explicit Anchor(float x_, float y_, float angle_, float scale_) - : point(x_, y_), angle(angle_), scale(scale_) {} - explicit Anchor(float x_, float y_, float angle_, float scale_, int segment_) + Anchor(float x_, float y_, float angle_, float scale_, int segment_ = -1) : point(x_, y_), angle(angle_), scale(scale_), segment(segment_) {} - }; typedef std::vector Anchors; diff --git a/src/mbgl/layout/symbol_instance.cpp b/src/mbgl/layout/symbol_instance.cpp index d81783b2f6..8bdc528bbb 100644 --- a/src/mbgl/layout/symbol_instance.cpp +++ b/src/mbgl/layout/symbol_instance.cpp @@ -5,12 +5,22 @@ namespace mbgl { using namespace style; -SymbolInstance::SymbolInstance(Anchor& anchor, const GeometryCoordinates& line, - const std::pair& shapedTextOrientations, const PositionedIcon& shapedIcon, - 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, const std::size_t featureIndex_) : +SymbolInstance::SymbolInstance(Anchor& anchor, + const GeometryCoordinates& line, + const std::pair& shapedTextOrientations, + const PositionedIcon& shapedIcon, + 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, + const std::size_t featureIndex_) : point(anchor.point), index(index_), hasText(shapedTextOrientations.first || shapedTextOrientations.second), diff --git a/src/mbgl/layout/symbol_instance.hpp b/src/mbgl/layout/symbol_instance.hpp index 532a4d30d8..70ebfeefa2 100644 --- a/src/mbgl/layout/symbol_instance.hpp +++ b/src/mbgl/layout/symbol_instance.hpp @@ -7,17 +7,27 @@ namespace mbgl { -struct Anchor; +class Anchor; class IndexedSubfeature; class SymbolInstance { public: - explicit SymbolInstance(Anchor& anchor, const GeometryCoordinates& line, - const std::pair& shapedTextOrientations, const PositionedIcon& shapedIcon, - 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, const std::size_t featureIndex); + SymbolInstance(Anchor& anchor, + const GeometryCoordinates& line, + const std::pair& shapedTextOrientations, + const PositionedIcon& shapedIcon, + 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&, + const std::size_t featureIndex); Point point; uint32_t index; diff --git a/src/mbgl/layout/symbol_layout.hpp b/src/mbgl/layout/symbol_layout.hpp index 491d0078da..c6e1743549 100644 --- a/src/mbgl/layout/symbol_layout.hpp +++ b/src/mbgl/layout/symbol_layout.hpp @@ -19,6 +19,7 @@ class CollisionTile; class SpriteAtlas; class GlyphAtlas; class SymbolBucket; +class Anchor; namespace style { class BucketParameters; @@ -26,8 +27,6 @@ class Filter; class Layer; } // namespace style -struct Anchor; - class SymbolLayout { public: SymbolLayout(const style::BucketParameters&, diff --git a/src/mbgl/text/check_max_angle.cpp b/src/mbgl/text/check_max_angle.cpp index 3ef13a0dd7..d13d28f822 100644 --- a/src/mbgl/text/check_max_angle.cpp +++ b/src/mbgl/text/check_max_angle.cpp @@ -13,9 +13,11 @@ struct Corner { float angleDelta; }; -bool checkMaxAngle(const GeometryCoordinates &line, Anchor &anchor, const float labelLength, - const float windowSize, const float maxAngle) { - +bool checkMaxAngle(const GeometryCoordinates& line, + Anchor& anchor, + const float labelLength, + const float windowSize, + const float maxAngle) { // horizontal labels always pass if (anchor.segment < 0) return true; @@ -74,8 +76,6 @@ bool checkMaxAngle(const GeometryCoordinates &line, Anchor &anchor, const float // no part of the line had an angle greater than the maximum allowed. check passes. return true; - - } } // namespace mbgl diff --git a/src/mbgl/text/check_max_angle.hpp b/src/mbgl/text/check_max_angle.hpp index 008e70b5da..8d53951e49 100644 --- a/src/mbgl/text/check_max_angle.hpp +++ b/src/mbgl/text/check_max_angle.hpp @@ -4,9 +4,12 @@ namespace mbgl { -struct Anchor; +class Anchor; -bool checkMaxAngle(const GeometryCoordinates &line, Anchor &anchor, const float labelLength, - const float windowSize, const float maxAngle); +bool checkMaxAngle(const GeometryCoordinates& line, + Anchor& anchor, + const float labelLength, + const float windowSize, + const float maxAngle); } // namespace mbgl diff --git a/src/mbgl/text/collision_feature.cpp b/src/mbgl/text/collision_feature.cpp index 661c44891f..67f669ab61 100644 --- a/src/mbgl/text/collision_feature.cpp +++ b/src/mbgl/text/collision_feature.cpp @@ -3,12 +3,18 @@ namespace mbgl { -CollisionFeature::CollisionFeature(const GeometryCoordinates &line, const Anchor &anchor, - const float top, const float bottom, const float left, const float right, - const float boxScale, const float padding, const style::SymbolPlacementType placement, IndexedSubfeature indexedFeature_, - const bool straight) +CollisionFeature::CollisionFeature(const GeometryCoordinates& line, + const Anchor& anchor, + const float top, + const float bottom, + const float left, + const float right, + const float boxScale, + const float padding, + const style::SymbolPlacementType placement, + IndexedSubfeature indexedFeature_, + const bool straight) : indexedFeature(std::move(indexedFeature_)) { - if (top == 0 && bottom == 0 && left == 0 && right == 0) return; const float y1 = top * boxScale - padding; @@ -40,9 +46,8 @@ CollisionFeature::CollisionFeature(const GeometryCoordinates &line, const Anchor } } -void CollisionFeature::bboxifyLabel(const GeometryCoordinates &line, - GeometryCoordinate &anchorPoint, const int segment, const float labelLength, const float boxSize) { - +void CollisionFeature::bboxifyLabel(const GeometryCoordinates& line, GeometryCoordinate& anchorPoint, + const int segment, const float labelLength, const float boxSize) { const float step = boxSize / 2; const unsigned int nBoxes = std::floor(labelLength / step); @@ -101,5 +106,4 @@ void CollisionFeature::bboxifyLabel(const GeometryCoordinates &line, } } - } // namespace mbgl diff --git a/src/mbgl/text/collision_feature.hpp b/src/mbgl/text/collision_feature.hpp index 12c14fe0c1..1436e0815b 100644 --- a/src/mbgl/text/collision_feature.hpp +++ b/src/mbgl/text/collision_feature.hpp @@ -8,57 +8,69 @@ #include namespace mbgl { - class CollisionBox { - public: - explicit CollisionBox(Point _anchor, float _x1, float _y1, float _x2, float _y2, float _maxScale) : - anchor(std::move(_anchor)), x1(_x1), y1(_y1), x2(_x2), y2(_y2), maxScale(_maxScale) {} - // the box is centered around the anchor point - Point anchor; +class CollisionBox { +public: + CollisionBox(Point _anchor, float _x1, float _y1, float _x2, float _y2, float _maxScale) : + anchor(std::move(_anchor)), x1(_x1), y1(_y1), x2(_x2), y2(_y2), maxScale(_maxScale) {} - // distances to the edges from the anchor - float x1; - float y1; - float x2; - float y2; + // the box is centered around the anchor point + Point anchor; - // the box is only valid for scales < maxScale. - // The box does not block other boxes at scales >= maxScale; - float maxScale; + // distances to the edges from the anchor + float x1; + float y1; + float x2; + float y2; - // the scale at which the label can first be shown - float placementScale = 0.0f; - }; + // the box is only valid for scales < maxScale. + // The box does not block other boxes at scales >= maxScale; + float maxScale; - class CollisionFeature { - public: - // for text - explicit CollisionFeature(const GeometryCoordinates &line, const Anchor &anchor, - const Shaping &shapedText, - const float boxScale, const float padding, const style::SymbolPlacementType placement, const IndexedSubfeature& indexedFeature_) - : CollisionFeature(line, anchor, - shapedText.top, shapedText.bottom, shapedText.left, shapedText.right, - boxScale, padding, placement, indexedFeature_, false) {} + // the scale at which the label can first be shown + float placementScale = 0.0f; +}; - // for icons - explicit CollisionFeature(const GeometryCoordinates &line, const Anchor &anchor, - const PositionedIcon &shapedIcon, - const float boxScale, const float padding, const style::SymbolPlacementType placement, const IndexedSubfeature& indexedFeature_) - : CollisionFeature(line, anchor, - shapedIcon.top, shapedIcon.bottom, shapedIcon.left, shapedIcon.right, - boxScale, padding, placement, indexedFeature_, true) {} +class CollisionFeature { +public: + // for text + CollisionFeature(const GeometryCoordinates& line, + const Anchor& anchor, + const Shaping& shapedText, + const float boxScale, + const float padding, + const style::SymbolPlacementType placement, + const IndexedSubfeature& indexedFeature_) + : CollisionFeature(line, anchor, shapedText.top, shapedText.bottom, shapedText.left, shapedText.right, boxScale, padding, placement, indexedFeature_, false) {} - explicit CollisionFeature(const GeometryCoordinates &line, const Anchor &anchor, - const float top, const float bottom, const float left, const float right, - const float boxScale, const float padding, const style::SymbolPlacementType placement, - IndexedSubfeature, const bool straight); + // for icons + CollisionFeature(const GeometryCoordinates& line, + const Anchor& anchor, + const PositionedIcon& shapedIcon, + const float boxScale, + const float padding, + const style::SymbolPlacementType placement, + const IndexedSubfeature& indexedFeature_) + : CollisionFeature(line, anchor, shapedIcon.top, shapedIcon.bottom, shapedIcon.left, shapedIcon.right, boxScale, padding, placement, indexedFeature_, true) {} + CollisionFeature(const GeometryCoordinates& line, + const Anchor& anchor, + const float top, + const float bottom, + const float left, + const float right, + const float boxScale, + const float padding, + const style::SymbolPlacementType placement, + IndexedSubfeature, + const bool straight); - std::vector boxes; - IndexedSubfeature indexedFeature; + std::vector boxes; + IndexedSubfeature indexedFeature; + +private: + void bboxifyLabel(const GeometryCoordinates& line, GeometryCoordinate& anchorPoint, + const int segment, const float length, const float height); +}; - private: - void bboxifyLabel(const GeometryCoordinates &line, GeometryCoordinate &anchorPoint, - const int segment, const float length, const float height); - }; } // namespace mbgl diff --git a/src/mbgl/text/get_anchors.cpp b/src/mbgl/text/get_anchors.cpp index b912c7763e..82702b20f0 100644 --- a/src/mbgl/text/get_anchors.cpp +++ b/src/mbgl/text/get_anchors.cpp @@ -8,9 +8,14 @@ namespace mbgl { -Anchors resample(const GeometryCoordinates &line, const float offset, const float spacing, - const float angleWindowSize, const float maxAngle, const float labelLength, const bool continuedLine, const bool placeAtMiddle) { - +static Anchors resample(const GeometryCoordinates& line, + const float offset, + const float spacing, + const float angleWindowSize, + const float maxAngle, + const float labelLength, + const bool continuedLine, + const bool placeAtMiddle) { const float halfLabelLength = labelLength / 2.0f; float lineLength = 0; for (auto it = line.begin(), end = line.end() - 1; it != end; it++) { @@ -26,8 +31,8 @@ Anchors resample(const GeometryCoordinates &line, const float offset, const floa int i = 0; for (auto it = line.begin(), end = line.end() - 1; it != end; it++, i++) { - const GeometryCoordinate &a = *(it); - const GeometryCoordinate &b = *(it + 1); + const GeometryCoordinate& a = *(it); + const GeometryCoordinate& b = *(it + 1); const float segmentDist = util::dist(a, b); const float angle = util::angle_to(b, a); @@ -68,11 +73,19 @@ Anchors resample(const GeometryCoordinates &line, const float offset, const floa return anchors; } -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 {}; +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/get_anchors.hpp b/src/mbgl/text/get_anchors.hpp index b61f8fe0dc..48f3013093 100644 --- a/src/mbgl/text/get_anchors.hpp +++ b/src/mbgl/text/get_anchors.hpp @@ -6,8 +6,15 @@ namespace mbgl { -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); +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); + } // namespace mbgl diff --git a/src/mbgl/text/quads.cpp b/src/mbgl/text/quads.cpp index 6113d1f5d4..6643621fdd 100644 --- a/src/mbgl/text/quads.cpp +++ b/src/mbgl/text/quads.cpp @@ -5,6 +5,7 @@ #include #include #include + #include namespace mbgl { @@ -13,10 +14,12 @@ using namespace style; const float globalMinScale = 0.5f; // underscale by 1 zoom level -SymbolQuad getIconQuad(Anchor& anchor, const PositionedIcon& shapedIcon, - const GeometryCoordinates& line, const SymbolLayoutProperties::Evaluated& layout, - const style::SymbolPlacementType placement, const Shaping& shapedText) { - +SymbolQuad getIconQuad(Anchor& anchor, + const PositionedIcon& shapedIcon, + const GeometryCoordinates& line, + const SymbolLayoutProperties::Evaluated& layout, + const style::SymbolPlacementType placement, + const Shaping& shapedText) { auto image = *(shapedIcon.image); const float border = 1.0; @@ -38,7 +41,7 @@ SymbolQuad getIconQuad(Anchor& anchor, const PositionedIcon& shapedIcon, auto textTop = shapedText.top * size; auto textBottom = shapedText.bottom * size; auto textWidth = textRight - textLeft; - auto textHeight = textBottom - textTop;; + auto textHeight = textBottom - textTop; auto padT = layout.get()[0]; auto padR = layout.get()[1]; auto padB = layout.get()[2]; @@ -75,7 +78,6 @@ SymbolQuad getIconQuad(Anchor& anchor, const PositionedIcon& shapedIcon, } } - if (angle) { // Compute the transformation matrix. float angle_sin = std::sin(angle); @@ -106,9 +108,12 @@ struct GlyphInstance { typedef std::vector GlyphInstances; -void getSegmentGlyphs(std::back_insert_iterator glyphs, Anchor &anchor, - float offset, const GeometryCoordinates &line, int segment, bool forward) { - +void getSegmentGlyphs(std::back_insert_iterator glyphs, + Anchor& anchor, + float offset, + const GeometryCoordinates& line, + int segment, + bool forward) { const bool upsideDown = !forward; if (offset < 0) @@ -162,10 +167,13 @@ void getSegmentGlyphs(std::back_insert_iterator glyphs, Anchor & } } -SymbolQuads getGlyphQuads(Anchor& anchor, const Shaping& shapedText, - const float boxScale, const GeometryCoordinates& line, const SymbolLayoutProperties::Evaluated& layout, - const style::SymbolPlacementType placement, const GlyphPositions& face) { - +SymbolQuads getGlyphQuads(Anchor& anchor, + const Shaping& shapedText, + const float boxScale, + const GeometryCoordinates& line, + const SymbolLayoutProperties::Evaluated& layout, + const style::SymbolPlacementType placement, + const GlyphPositions& face) { const float textRotate = layout.get() * util::DEG2RAD; const bool keepUpright = layout.get(); @@ -191,7 +199,6 @@ SymbolQuads getGlyphQuads(Anchor& anchor, const Shaping& shapedText, getSegmentGlyphs(std::back_inserter(glyphInstances), anchor, centerX, line, anchor.segment, true); if (keepUpright) getSegmentGlyphs(std::back_inserter(glyphInstances), anchor, centerX, line, anchor.segment, false); - } else { glyphInstances.emplace_back(GlyphInstance{anchor.point}); } @@ -220,7 +227,6 @@ SymbolQuads getGlyphQuads(Anchor& anchor, const Shaping& shapedText, } for (const GlyphInstance &instance : glyphInstances) { - Point tl = otl; Point tr = otr; Point bl = obl; @@ -244,9 +250,7 @@ SymbolQuads getGlyphQuads(Anchor& anchor, const Shaping& shapedText, const float anchorAngle = std::fmod((anchor.angle + instance.offset + 2 * M_PI), (2 * M_PI)); const float glyphAngle = std::fmod((instance.angle + instance.offset + 2 * M_PI), (2 * M_PI)); quads.emplace_back(tl, tr, bl, br, rect, anchorAngle, glyphAngle, instance.anchorPoint, glyphMinScale, instance.maxScale, shapedText.writingMode); - } - } return quads; diff --git a/src/mbgl/text/quads.hpp b/src/mbgl/text/quads.hpp index 07a94c763b..61c03f3201 100644 --- a/src/mbgl/text/quads.hpp +++ b/src/mbgl/text/quads.hpp @@ -9,13 +9,22 @@ namespace mbgl { -struct Anchor; +class Anchor; class PositionedIcon; -struct SymbolQuad { - explicit SymbolQuad(Point tl_, Point tr_, Point bl_, Point br_, - Rect tex_, float anchorAngle_, float glyphAngle_, Point anchorPoint_, - float minScale_, float maxScale_, WritingModeType writingMode_) +class SymbolQuad { +public: + SymbolQuad(Point tl_, + Point tr_, + Point bl_, + Point br_, + Rect tex_, + float anchorAngle_, + float glyphAngle_, + Point anchorPoint_, + float minScale_, + float maxScale_, + WritingModeType writingMode_) : tl(std::move(tl_)), tr(std::move(tr_)), bl(std::move(bl_)), @@ -28,22 +37,33 @@ struct SymbolQuad { maxScale(maxScale_), writingMode(writingMode_) {} - Point tl, tr, bl, br; + Point tl; + Point tr; + Point bl; + Point br; Rect tex; float anchorAngle, glyphAngle; Point anchorPoint; - float minScale, maxScale; + float minScale; + float maxScale; WritingModeType writingMode; }; typedef std::vector SymbolQuads; -SymbolQuad getIconQuad(Anchor& anchor, const PositionedIcon& shapedIcon, - const GeometryCoordinates& line, const style::SymbolLayoutProperties::Evaluated&, - style::SymbolPlacementType placement, const Shaping& shapedText); +SymbolQuad getIconQuad(Anchor& anchor, + const PositionedIcon& shapedIcon, + 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::Evaluated&, - style::SymbolPlacementType placement, const GlyphPositions& face); +SymbolQuads getGlyphQuads(Anchor& anchor, + const Shaping& shapedText, + const float boxScale, + const GeometryCoordinates& line, + const style::SymbolLayoutProperties::Evaluated&, + style::SymbolPlacementType placement, + const GlyphPositions& face); } // namespace mbgl -- cgit v1.2.1 From e1c85e8ec3c66efa6a5da987b639c7c32aa68169 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 20 Feb 2017 18:00:37 -0800 Subject: [core] const-correction --- src/mbgl/text/check_max_angle.cpp | 2 +- src/mbgl/text/check_max_angle.hpp | 2 +- src/mbgl/text/quads.cpp | 2 +- src/mbgl/text/quads.hpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mbgl/text/check_max_angle.cpp b/src/mbgl/text/check_max_angle.cpp index d13d28f822..9109235798 100644 --- a/src/mbgl/text/check_max_angle.cpp +++ b/src/mbgl/text/check_max_angle.cpp @@ -14,7 +14,7 @@ struct Corner { }; bool checkMaxAngle(const GeometryCoordinates& line, - Anchor& anchor, + const Anchor& anchor, const float labelLength, const float windowSize, const float maxAngle) { diff --git a/src/mbgl/text/check_max_angle.hpp b/src/mbgl/text/check_max_angle.hpp index 8d53951e49..c95661160c 100644 --- a/src/mbgl/text/check_max_angle.hpp +++ b/src/mbgl/text/check_max_angle.hpp @@ -7,7 +7,7 @@ namespace mbgl { class Anchor; bool checkMaxAngle(const GeometryCoordinates& line, - Anchor& anchor, + const Anchor& anchor, const float labelLength, const float windowSize, const float maxAngle); diff --git a/src/mbgl/text/quads.cpp b/src/mbgl/text/quads.cpp index 6643621fdd..a0742f5a4b 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 -SymbolQuad getIconQuad(Anchor& anchor, +SymbolQuad getIconQuad(const Anchor& anchor, const PositionedIcon& shapedIcon, const GeometryCoordinates& line, const SymbolLayoutProperties::Evaluated& layout, diff --git a/src/mbgl/text/quads.hpp b/src/mbgl/text/quads.hpp index 61c03f3201..f1529d8829 100644 --- a/src/mbgl/text/quads.hpp +++ b/src/mbgl/text/quads.hpp @@ -51,7 +51,7 @@ public: typedef std::vector SymbolQuads; -SymbolQuad getIconQuad(Anchor& anchor, +SymbolQuad getIconQuad(const Anchor& anchor, const PositionedIcon& shapedIcon, const GeometryCoordinates& line, const style::SymbolLayoutProperties::Evaluated&, -- cgit v1.2.1 From 8a5cc3560ac3ed5b2aa6273c7fbbd92a3692b1ec Mon Sep 17 00:00:00 2001 From: Fabian Guerra Soto Date: Thu, 2 Mar 2017 18:19:23 -0500 Subject: [ios] MGLAnnotationView annotation property made writable (#8139) --- platform/ios/src/MGLAnnotationView.h | 2 +- platform/ios/src/MGLAnnotationView.mm | 2 +- platform/ios/src/MGLAnnotationView_Private.h | 1 - platform/ios/src/MGLMapView.mm | 1 + 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/ios/src/MGLAnnotationView.h b/platform/ios/src/MGLAnnotationView.h index 532483350a..184efdb324 100644 --- a/platform/ios/src/MGLAnnotationView.h +++ b/platform/ios/src/MGLAnnotationView.h @@ -89,7 +89,7 @@ typedef NS_ENUM(NSUInteger, MGLAnnotationViewDragState) { contains a non-`nil` value while the annotation view is visible on the map. If the view is queued, waiting to be reused, the value is `nil`. */ -@property (nonatomic, readonly, nullable) id annotation; +@property (nonatomic, nullable) id annotation; /** The string that identifies that this annotation view is reusable. diff --git a/platform/ios/src/MGLAnnotationView.mm b/platform/ios/src/MGLAnnotationView.mm index 5b105cde72..0e904779d5 100644 --- a/platform/ios/src/MGLAnnotationView.mm +++ b/platform/ios/src/MGLAnnotationView.mm @@ -10,7 +10,6 @@ @interface MGLAnnotationView () @property (nonatomic, readwrite, nullable) NSString *reuseIdentifier; -@property (nonatomic, readwrite, nullable) id annotation; @property (nonatomic, readwrite) CATransform3D lastAppliedScaleTransform; @property (nonatomic, weak) UIPanGestureRecognizer *panGestureRecognizer; @property (nonatomic, weak) UILongPressGestureRecognizer *longPressRecognizer; @@ -240,6 +239,7 @@ } else if (dragState == MGLAnnotationViewDragStateCanceling) { + NSAssert(self.annotation, @"Annotation property should not be nil."); self.panGestureRecognizer.enabled = NO; self.longPressRecognizer.enabled = NO; self.center = [self.mapView convertCoordinate:self.annotation.coordinate toPointToView:self.mapView]; diff --git a/platform/ios/src/MGLAnnotationView_Private.h b/platform/ios/src/MGLAnnotationView_Private.h index 8a0af3565c..c4695051c5 100644 --- a/platform/ios/src/MGLAnnotationView_Private.h +++ b/platform/ios/src/MGLAnnotationView_Private.h @@ -8,7 +8,6 @@ NS_ASSUME_NONNULL_BEGIN @interface MGLAnnotationView (Private) @property (nonatomic, readwrite, nullable) NSString *reuseIdentifier; -@property (nonatomic, readwrite, nullable) id annotation; @property (nonatomic, weak) MGLMapView *mapView; @end diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index 7119544158..58f8f407e4 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -1516,6 +1516,7 @@ public: { if (view.centerOffset.dx != 0 || view.centerOffset.dy != 0) { if (CGRectContainsPoint(view.frame, tapPoint)) { + NSAssert(view.annotation, @"Annotation's view annotation property should not be nil."); CGPoint annotationPoint = [self convertCoordinate:view.annotation.coordinate toPointToView:self]; tapPoint = annotationPoint; } -- cgit v1.2.1 From 8742dc852c82ef40003a22a8e0a764616d8beed1 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Wed, 1 Mar 2017 21:52:38 -0800 Subject: [all] Build all release builds with -Os --- CMakeLists.txt | 1 + platform/android/config.cmake | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 90f5bf7e1c..123158e2eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,6 +66,7 @@ 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") endif() +set(CMAKE_CXX_FLAGS_RELEASE "-Os -DNDEBUG") if(CMAKE_COMPILER_IS_GNUCXX) # https://svn.boost.org/trac/boost/ticket/9240 diff --git a/platform/android/config.cmake b/platform/android/config.cmake index 18458deba6..c27e6e0b93 100644 --- a/platform/android/config.cmake +++ b/platform/android/config.cmake @@ -218,7 +218,6 @@ macro(mbgl_platform_core) PRIVATE -fvisibility=hidden PRIVATE -ffunction-sections PRIVATE -fdata-sections - PRIVATE -Os ) target_link_libraries(mbgl-core @@ -244,7 +243,6 @@ target_compile_options(mapbox-gl PRIVATE -fvisibility=hidden PRIVATE -ffunction-sections PRIVATE -fdata-sections - PRIVATE -Os ) target_link_libraries(mapbox-gl @@ -285,7 +283,6 @@ target_sources(mbgl-test target_compile_options(mbgl-test PRIVATE -fvisibility=hidden - PRIVATE -Os ) target_compile_definitions(mbgl-test @@ -329,7 +326,6 @@ target_compile_options(example-custom-layer PRIVATE -fvisibility=hidden PRIVATE -ffunction-sections PRIVATE -fdata-sections - PRIVATE -Os ) target_link_libraries(example-custom-layer -- cgit v1.2.1 From a5f6ee696367e3311334faa03fb55e215174997f Mon Sep 17 00:00:00 2001 From: Tobrun Date: Fri, 3 Mar 2017 17:36:40 -0500 Subject: [android] - update gradle and plugin for Android Studio 2.3 stable, update support library to latest version, add dexOptions to increase build times. (#8271) --- platform/android/MapboxGLAndroidSDKTestApp/build.gradle | 6 ++++++ platform/android/build.gradle | 2 +- platform/android/dependencies.gradle | 2 +- platform/android/gradle/wrapper/gradle-wrapper.properties | 4 ++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDKTestApp/build.gradle b/platform/android/MapboxGLAndroidSDKTestApp/build.gradle index 1b4d54106d..10baf2e108 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/build.gradle +++ b/platform/android/MapboxGLAndroidSDKTestApp/build.gradle @@ -46,6 +46,12 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } + + dexOptions { + maxProcessCount 8 + javaMaxHeapSize "2g" + preDexLibraries true + } } dependencies { diff --git a/platform/android/build.gradle b/platform/android/build.gradle index 69eb6616d1..4219f2bdee 100644 --- a/platform/android/build.gradle +++ b/platform/android/build.gradle @@ -3,7 +3,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.2.3' + classpath 'com.android.tools.build:gradle:2.3.0' classpath 'com.amazonaws:aws-devicefarm-gradle-plugin:1.2' classpath 'com.stanfy.spoon:spoon-gradle-plugin:1.2.1' } diff --git a/platform/android/dependencies.gradle b/platform/android/dependencies.gradle index 2cdb455190..3eb28452c6 100644 --- a/platform/android/dependencies.gradle +++ b/platform/android/dependencies.gradle @@ -7,7 +7,7 @@ ext { versionCode = 11 versionName = "5.0.0" - supportLibVersion = "25.1.1" + supportLibVersion = "25.2.0" leakCanaryVersion = '1.5' wearableVersion = '2.0.0' diff --git a/platform/android/gradle/wrapper/gradle-wrapper.properties b/platform/android/gradle/wrapper/gradle-wrapper.properties index 20b2b0894c..c7ad166b13 100644 --- a/platform/android/gradle/wrapper/gradle-wrapper.properties +++ b/platform/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Mon Dec 12 10:58:15 CET 2016 +#Fri Mar 03 10:22:19 EST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.2.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip -- cgit v1.2.1 From f6cd017f58f0e31d51c7e877b43aca3fc50d1866 Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Fri, 3 Mar 2017 14:31:46 -0800 Subject: [Qt] Remove legacy QOpenGL dependency from Qt5 build OpenGL on Qt5 is offered via QtGui. --- include/mbgl/gl/gl.hpp | 4 ++-- platform/qt/config.cmake | 2 +- platform/qt/qt4.cmake | 5 +++++ platform/qt/qt5.cmake | 9 +++++++-- platform/qt/test/headless_backend_qt.cpp | 3 ++- 5 files changed, 17 insertions(+), 6 deletions(-) diff --git a/include/mbgl/gl/gl.hpp b/include/mbgl/gl/gl.hpp index 7521b4c80d..3a577b289b 100644 --- a/include/mbgl/gl/gl.hpp +++ b/include/mbgl/gl/gl.hpp @@ -22,9 +22,9 @@ #define GL_GLEXT_PROTOTYPES #include #include -#elif __QT__ +#elif __QT_ && QT_VERSION >= 0x050000 #define GL_GLEXT_PROTOTYPES - #include + #include #else #define GL_GLEXT_PROTOTYPES #include diff --git a/platform/qt/config.cmake b/platform/qt/config.cmake index e97c6b340a..4563f03a9b 100644 --- a/platform/qt/config.cmake +++ b/platform/qt/config.cmake @@ -72,7 +72,7 @@ macro(mbgl_platform_test) target_link_libraries(mbgl-test PRIVATE qmapboxgl - ${MBGL_QT_LIBRARIES} + ${MBGL_QT_TEST_LIBRARIES} ) endmacro() diff --git a/platform/qt/qt4.cmake b/platform/qt/qt4.cmake index d6d7d89417..80fd4f00d3 100644 --- a/platform/qt/qt4.cmake +++ b/platform/qt/qt4.cmake @@ -8,6 +8,11 @@ set(MBGL_QT_LIBRARIES PRIVATE Qt4::QtSql ) +set(MBGL_QT_TEST_LIBRARIES + PRIVATE Qt4::QtCore + PRIVATE Qt4::QtOpenGL +) + target_link_libraries(qmapboxgl PRIVATE mbgl-core PRIVATE Qt4::QtCore diff --git a/platform/qt/qt5.cmake b/platform/qt/qt5.cmake index 7210a3d5f5..9a482f6d30 100644 --- a/platform/qt/qt5.cmake +++ b/platform/qt/qt5.cmake @@ -11,10 +11,16 @@ set(MBGL_QT_LIBRARIES PRIVATE Qt5::Core PRIVATE Qt5::Gui PRIVATE Qt5::Network - PRIVATE Qt5::OpenGL PRIVATE Qt5::Sql ) +set(MBGL_QT_TEST_LIBRARIES + PRIVATE Qt5::Core + PRIVATE Qt5::Gui + PRIVATE Qt5::Widgets + PRIVATE Qt5::OpenGL +) + target_sources(qmapboxgl PRIVATE platform/qt/include/qquickmapboxgl.hpp PRIVATE platform/qt/include/qquickmapboxglmapparameter.hpp @@ -29,7 +35,6 @@ target_link_libraries(qmapboxgl PRIVATE Qt5::Core PRIVATE Qt5::Gui PRIVATE Qt5::Location - PRIVATE Qt5::OpenGL PRIVATE Qt5::Quick PRIVATE Qt5::Sql ) diff --git a/platform/qt/test/headless_backend_qt.cpp b/platform/qt/test/headless_backend_qt.cpp index 00b519d5bf..401ce55a7f 100644 --- a/platform/qt/test/headless_backend_qt.cpp +++ b/platform/qt/test/headless_backend_qt.cpp @@ -1,10 +1,11 @@ #include -#include #include #if QT_VERSION >= 0x050000 #include +#else +#include #endif #include -- cgit v1.2.1 From 328d4f667271d36e74456d8ed731e8fe506d6cb0 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Sat, 4 Mar 2017 15:43:39 -0500 Subject: [android] - example on converting an Android SDK view to a Bitmap to be used as SymbolAnnotation (#8258) --- .../annotation/AddRemoveMarkerActivity.java | 43 ++++++++++++++++------ .../mapboxsdk/testapp/utils/ViewToBitmapUtil.java | 22 +++++++++++ .../src/main/res/layout/view_custom_marker.xml | 9 ++--- 3 files changed, 57 insertions(+), 17 deletions(-) create mode 100644 platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/ViewToBitmapUtil.java 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 abadc3e5d9..27958c3d0c 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 @@ -1,10 +1,18 @@ package com.mapbox.mapboxsdk.testapp.activity.annotation; +import android.annotation.SuppressLint; +import android.graphics.Bitmap; +import android.graphics.Color; import android.os.Bundle; -import android.support.v4.content.ContextCompat; +import android.support.annotation.DrawableRes; import android.support.v7.app.AppCompatActivity; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; import com.mapbox.mapboxsdk.annotations.Icon; +import com.mapbox.mapboxsdk.annotations.IconFactory; import com.mapbox.mapboxsdk.annotations.Marker; import com.mapbox.mapboxsdk.annotations.MarkerOptions; import com.mapbox.mapboxsdk.camera.CameraPosition; @@ -14,7 +22,7 @@ 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.mapboxsdk.testapp.utils.IconUtils; +import com.mapbox.mapboxsdk.testapp.utils.ViewToBitmapUtil; import timber.log.Timber; @@ -40,20 +48,20 @@ public class AddRemoveMarkerActivity extends AppCompatActivity { super.onCreate(savedInstanceState); setContentView(R.layout.activity_add_remove_marker); - // ShapeDrawable to Icon - final Icon shapeDrawableIcon = IconUtils.drawableToIcon(this, R.drawable.ic_circle, - ContextCompat.getColor(this, R.color.redAccent)); - - // VectorDrawable to Icon - final Icon vectorDrawableIcon = IconUtils.drawableToIcon(this, R.drawable.ic_layers, - ContextCompat.getColor(this, R.color.blueAccent)); + View lowThresholdView = generateView("Low", R.drawable.ic_circle); + Bitmap lowThresholdBitmap = ViewToBitmapUtil.convertToBitmap(lowThresholdView); + Icon lowThresholdIcon = IconFactory.getInstance(this).fromBitmap(lowThresholdBitmap); lowThresholdMarker = new MarkerOptions() - .icon(shapeDrawableIcon) - .position(new LatLng(-0.1, 0)); + .icon(lowThresholdIcon) + .position(new LatLng(0.1, 0)); + + View highThesholdView = generateView("High", R.drawable.ic_circle); + Bitmap highThresholdBitmap = ViewToBitmapUtil.convertToBitmap(highThesholdView); + Icon highThresholdIcon = IconFactory.getInstance(this).fromBitmap(highThresholdBitmap); highThresholdMarker = new MarkerOptions() - .icon(vectorDrawableIcon) + .icon(highThresholdIcon) .position(new LatLng(0.1, 0)); mapView = (MapView) findViewById(R.id.mapView); @@ -74,6 +82,17 @@ public class AddRemoveMarkerActivity extends AppCompatActivity { }); } + @SuppressLint("InflateParams") + private View generateView(String text, @DrawableRes int drawableRes) { + View view = LayoutInflater.from(this).inflate(R.layout.view_custom_marker, null); + TextView textView = (TextView) view.findViewById(R.id.textView); + textView.setText(text); + textView.setTextColor(Color.WHITE); + ImageView imageView = (ImageView) view.findViewById(R.id.imageView); + imageView.setImageResource(drawableRes); + return view; + } + private void updateZoom(double zoom) { if (lastZoom == zoom) { return; diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/ViewToBitmapUtil.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/ViewToBitmapUtil.java new file mode 100644 index 0000000000..e8091248f4 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/utils/ViewToBitmapUtil.java @@ -0,0 +1,22 @@ +package com.mapbox.mapboxsdk.testapp.utils; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.support.annotation.NonNull; +import android.view.View; + +/** + * Converts a View to a Bitmap so we can use an Android SDK View as a Symbol. + */ +public class ViewToBitmapUtil { + + public static Bitmap convertToBitmap(@NonNull View view) { + view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), + View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); + view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight()); + Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(bitmap); + view.draw(canvas); + return bitmap; + } +} diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/view_custom_marker.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/view_custom_marker.xml index c2bbdae775..324a4861c3 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/view_custom_marker.xml +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/view_custom_marker.xml @@ -11,11 +11,10 @@ + android:layout_centerInParent="true" + android:padding="2dp" + android:textColor="@android:color/white" + android:textStyle="bold"/> -- cgit v1.2.1 From ac4e13416a36905b35401fc1a982c680ca37a3d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguye=CC=82=CC=83n?= Date: Sat, 4 Mar 2017 11:01:37 -0800 Subject: [core] Enable debug events in Debug configuration --- include/mbgl/util/event.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mbgl/util/event.hpp b/include/mbgl/util/event.hpp index 7ad3d914e8..5fe0baae3c 100644 --- a/include/mbgl/util/event.hpp +++ b/include/mbgl/util/event.hpp @@ -40,7 +40,7 @@ struct EventPermutation { }; constexpr EventSeverity disabledEventSeverities[] = { -#ifdef NDEBUG +#ifndef NDEBUG EventSeverity(-1) // Avoid zero size array #else EventSeverity::Debug -- cgit v1.2.1 From 60d10dd27df38ac4e97214d1cd514198c381695c Mon Sep 17 00:00:00 2001 From: Asheem Mamoowala Date: Tue, 21 Feb 2017 18:34:45 -0800 Subject: [core] Add support for queryRenderedFeatures filter --- benchmark/api/query.benchmark.cpp | 4 +-- cmake/core-files.cmake | 2 +- include/mbgl/map/map.hpp | 8 +++--- include/mbgl/map/query.hpp | 19 ++++++++++++++ include/mbgl/style/filter.hpp | 3 +++ include/mbgl/style/filter_evaluator.hpp | 5 ++++ mapbox-gl-js | 2 +- platform/android/src/native_map_view.cpp | 4 +-- platform/ios/src/MGLMapView.mm | 4 +-- platform/macos/src/MGLMapView.mm | 4 +-- platform/node/src/node_map.cpp | 41 ++++++++++++++++++++++++++++-- platform/node/test/suite_implementation.js | 2 +- src/mbgl/geometry/feature_index.cpp | 19 +++++++++----- src/mbgl/geometry/feature_index.hpp | 6 +++-- src/mbgl/map/map.cpp | 21 +++++++-------- src/mbgl/style/query_parameters.hpp | 21 --------------- src/mbgl/style/source_impl.cpp | 16 +++++++----- src/mbgl/style/source_impl.hpp | 4 ++- src/mbgl/style/style.cpp | 12 +++++---- src/mbgl/style/style.hpp | 8 ++++-- src/mbgl/tile/geometry_tile.cpp | 5 ++-- src/mbgl/tile/geometry_tile.hpp | 2 +- src/mbgl/tile/tile.cpp | 3 ++- src/mbgl/tile/tile.hpp | 3 ++- test/api/annotations.test.cpp | 2 +- test/api/query.test.cpp | 29 +++++++++++++++++---- test/fixtures/api/query_style.json | 28 ++++++++++++++++++++ 27 files changed, 195 insertions(+), 82 deletions(-) create mode 100644 include/mbgl/map/query.hpp delete mode 100644 src/mbgl/style/query_parameters.hpp diff --git a/benchmark/api/query.benchmark.cpp b/benchmark/api/query.benchmark.cpp index f7474dd2ee..53a524b450 100644 --- a/benchmark/api/query.benchmark.cpp +++ b/benchmark/api/query.benchmark.cpp @@ -55,7 +55,7 @@ static void API_queryRenderedFeaturesLayerFromLowDensity(::benchmark::State& sta QueryBenchmark bench; while (state.KeepRunning()) { - bench.map.queryRenderedFeatures(bench.box, {{ "testlayer" }}); + bench.map.queryRenderedFeatures(bench.box, {{{ "testlayer" }}, {}}); } } @@ -63,7 +63,7 @@ static void API_queryRenderedFeaturesLayerFromHighDensity(::benchmark::State& st QueryBenchmark bench; while (state.KeepRunning()) { - bench.map.queryRenderedFeatures(bench.box, {{ "road-street" }}); + bench.map.queryRenderedFeatures(bench.box, {{{"road-street" }}, {}}); } } diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake index 5173b92c05..a9fe077db9 100644 --- a/cmake/core-files.cmake +++ b/cmake/core-files.cmake @@ -108,6 +108,7 @@ set(MBGL_CORE_FILES include/mbgl/map/camera.hpp include/mbgl/map/map.hpp include/mbgl/map/mode.hpp + include/mbgl/map/query.hpp include/mbgl/map/view.hpp src/mbgl/map/backend.cpp src/mbgl/map/backend_scope.cpp @@ -271,7 +272,6 @@ set(MBGL_CORE_FILES src/mbgl/style/property_evaluator.hpp src/mbgl/style/property_parsing.cpp src/mbgl/style/property_parsing.hpp - src/mbgl/style/query_parameters.hpp src/mbgl/style/rapidjson_conversion.hpp src/mbgl/style/source.cpp src/mbgl/style/source_impl.cpp diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp index 95a82ebd74..7e4eeb8d5b 100644 --- a/include/mbgl/map/map.hpp +++ b/include/mbgl/map/map.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -24,8 +25,6 @@ class View; class FileSource; class Scheduler; class SpriteImage; -struct CameraOptions; -struct AnimationOptions; namespace style { class Source; @@ -183,8 +182,9 @@ public: double getDefaultPitch() const; // Feature queries - std::vector queryRenderedFeatures(const ScreenCoordinate&, const optional>& layerIDs = {}); - std::vector queryRenderedFeatures(const ScreenBox&, const optional>& layerIDs = {}); + std::vector queryRenderedFeatures(const ScreenCoordinate&, const QueryOptions& options = {}); + std::vector queryRenderedFeatures(const ScreenBox&, const QueryOptions& options = {}); + AnnotationIDs queryPointAnnotations(const ScreenBox&); // Memory diff --git a/include/mbgl/map/query.hpp b/include/mbgl/map/query.hpp new file mode 100644 index 0000000000..e864dbaa67 --- /dev/null +++ b/include/mbgl/map/query.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include +#include + +namespace mbgl { + +/** + * Options for Map queries. + */ +class QueryOptions { +public: + /** layerIDs to include in the query */ + optional> layerIDs; + + optional filter; +}; + +} diff --git a/include/mbgl/style/filter.hpp b/include/mbgl/style/filter.hpp index 5e61adf064..a204a2b17a 100644 --- a/include/mbgl/style/filter.hpp +++ b/include/mbgl/style/filter.hpp @@ -266,6 +266,9 @@ public: bool operator()(const Feature&) const; + template + bool operator()(const GeometryTileFeature&) const; + template bool operator()(FeatureType type, optional id, PropertyAccessor accessor) const; }; diff --git a/include/mbgl/style/filter_evaluator.hpp b/include/mbgl/style/filter_evaluator.hpp index 370064445a..66223d7282 100644 --- a/include/mbgl/style/filter_evaluator.hpp +++ b/include/mbgl/style/filter_evaluator.hpp @@ -246,6 +246,11 @@ inline bool Filter::operator()(const Feature& feature) const { }); } +template +bool Filter::operator()(const GeometryTileFeature& feature) const { + return operator()(feature.getType(), feature.getID(), [&] (const auto& key) { return feature.getValue(key); }); +} + template bool Filter::operator()(FeatureType type, optional id, PropertyAccessor accessor) const { return FilterBase::visit(*this, FilterEvaluator { type, id, accessor }); diff --git a/mapbox-gl-js b/mapbox-gl-js index 7804faf897..f9c5c17592 160000 --- a/mapbox-gl-js +++ b/mapbox-gl-js @@ -1 +1 @@ -Subproject commit 7804faf89741cf7db90582d9e0881253cb9d4cd8 +Subproject commit f9c5c175926278a24f1b0d958867632023773ede diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp index 1930d1854d..73edc8e298 100755 --- a/platform/android/src/native_map_view.cpp +++ b/platform/android/src/native_map_view.cpp @@ -721,7 +721,7 @@ jni::Array> NativeMapView::queryRenderedFeaturesForPoint(JN } point point = {x, y}; - return *convert>, std::vector>(env, map->queryRenderedFeatures(point, layers)); + return *convert>, std::vector>(env, map->queryRenderedFeatures(point, { layers, {} })); } jni::Array> NativeMapView::queryRenderedFeaturesForBox(JNIEnv& env, jni::jfloat left, jni::jfloat top, jni::jfloat right, jni::jfloat bottom, jni::Array layerIds) { @@ -734,7 +734,7 @@ jni::Array> NativeMapView::queryRenderedFeaturesForBox(JNIE } box box = { point{ left, top}, point{ right, bottom } }; - return *convert>, std::vector>(env, map->queryRenderedFeatures(box, layers)); + return *convert>, std::vector>(env, map->queryRenderedFeatures(box, { layers, {} })); } jni::Array> NativeMapView::getLayers(JNIEnv& env) { diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index 58f8f407e4..2990a4e163 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -4621,7 +4621,7 @@ public: optionalLayerIDs = layerIDs; } - std::vector features = _mbglMap->queryRenderedFeatures(screenCoordinate, optionalLayerIDs); + std::vector features = _mbglMap->queryRenderedFeatures(screenCoordinate, { optionalLayerIDs, {} }); return MGLFeaturesFromMBGLFeatures(features); } @@ -4645,7 +4645,7 @@ public: optionalLayerIDs = layerIDs; } - std::vector features = _mbglMap->queryRenderedFeatures(screenBox, optionalLayerIDs); + std::vector features = _mbglMap->queryRenderedFeatures(screenBox, { optionalLayerIDs, {} }); return MGLFeaturesFromMBGLFeatures(features); } diff --git a/platform/macos/src/MGLMapView.mm b/platform/macos/src/MGLMapView.mm index 827da35076..ff98095e15 100644 --- a/platform/macos/src/MGLMapView.mm +++ b/platform/macos/src/MGLMapView.mm @@ -2533,7 +2533,7 @@ public: optionalLayerIDs = layerIDs; } - std::vector features = _mbglMap->queryRenderedFeatures(screenCoordinate, optionalLayerIDs); + std::vector features = _mbglMap->queryRenderedFeatures(screenCoordinate, { optionalLayerIDs }); return MGLFeaturesFromMBGLFeatures(features); } @@ -2558,7 +2558,7 @@ public: optionalLayerIDs = layerIDs; } - std::vector features = _mbglMap->queryRenderedFeatures(screenBox, optionalLayerIDs); + std::vector features = _mbglMap->queryRenderedFeatures(screenBox, { optionalLayerIDs }); return MGLFeaturesFromMBGLFeatures(features); } diff --git a/platform/node/src/node_map.cpp b/platform/node/src/node_map.cpp index 66cdb3eda7..174db7d737 100644 --- a/platform/node/src/node_map.cpp +++ b/platform/node/src/node_map.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include @@ -866,6 +867,9 @@ void NodeMap::DumpDebugLogs(const Nan::FunctionCallbackInfo& info) { } void NodeMap::QueryRenderedFeatures(const Nan::FunctionCallbackInfo& info) { + using namespace mbgl::style; + using namespace mbgl::style::conversion; + auto nodeMap = Nan::ObjectWrap::Unwrap(info.Holder()); if (!nodeMap->map) return Nan::ThrowError(releasedMessage()); @@ -878,6 +882,39 @@ void NodeMap::QueryRenderedFeatures(const Nan::FunctionCallbackInfo& return Nan::ThrowTypeError("First argument must have two components"); } + mbgl::QueryOptions queryOptions; + if (!info[1]->IsNull() && !info[1]->IsUndefined()) { + if (!info[1]->IsObject()) { + return Nan::ThrowTypeError("options argument must be an object"); + } + + auto options = Nan::To(info[1]).ToLocalChecked(); + + //Check if layers is set. If provided, it must be an array of strings + if (Nan::Has(options, Nan::New("layers").ToLocalChecked()).FromJust()) { + auto layersOption = Nan::Get(options, Nan::New("layers").ToLocalChecked()).ToLocalChecked(); + if (!layersOption->IsArray()) { + return Nan::ThrowTypeError("Requires options.layers property to be an array"); + } + auto layers = layersOption.As(); + std::vector layersVec; + for (uint32_t i=0; i < layers->Length(); i++) { + layersVec.push_back(*Nan::Utf8String(Nan::Get(layers,i).ToLocalChecked())); + } + queryOptions.layerIDs = layersVec; + } + + //Check if filter is provided. If set it must be a valid Filter object + if (Nan::Has(options, Nan::New("filter").ToLocalChecked()).FromJust()) { + auto filterOption = Nan::Get(options, Nan::New("filter").ToLocalChecked()).ToLocalChecked(); + Result converted = convert(filterOption); + if (!converted) { + return Nan::ThrowTypeError(converted.error().message.c_str()); + } + queryOptions.filter = std::move(*converted); + } + } + try { std::vector result; @@ -894,13 +931,13 @@ void NodeMap::QueryRenderedFeatures(const Nan::FunctionCallbackInfo& Nan::Get(pos1, 0).ToLocalChecked()->NumberValue(), Nan::Get(pos1, 1).ToLocalChecked()->NumberValue() } - }); + }, queryOptions); } else { result = nodeMap->map->queryRenderedFeatures(mbgl::ScreenCoordinate { Nan::Get(posOrBox, 0).ToLocalChecked()->NumberValue(), Nan::Get(posOrBox, 1).ToLocalChecked()->NumberValue() - }); + }, queryOptions); } auto array = Nan::New(); diff --git a/platform/node/test/suite_implementation.js b/platform/node/test/suite_implementation.js index 6648757a98..ef97652893 100644 --- a/platform/node/test/suite_implementation.js +++ b/platform/node/test/suite_implementation.js @@ -49,7 +49,7 @@ module.exports = function (style, options, callback) { applyOperations(options.operations, function() { map.render(options, function (err, pixels) { var results = options.queryGeometry ? - map.queryRenderedFeatures(options.queryGeometry) : + map.queryRenderedFeatures(options.queryGeometry, options.queryOptions || {}) : []; map.release(); if (timedOut) return; diff --git a/src/mbgl/geometry/feature_index.cpp b/src/mbgl/geometry/feature_index.cpp index 5019d888ca..64fb7bd247 100644 --- a/src/mbgl/geometry/feature_index.cpp +++ b/src/mbgl/geometry/feature_index.cpp @@ -7,6 +7,9 @@ #include #include #include +#include +#include +#include #include @@ -56,7 +59,7 @@ void FeatureIndex::query( const float bearing, const double tileSize, const double scale, - const optional>& filterLayerIDs, + const QueryOptions& queryOptions, const GeometryTileData& geometryTileData, const CanonicalTileID& tileID, const style::Style& style, @@ -76,7 +79,7 @@ void FeatureIndex::query( if (indexedFeature.sortIndex == previousSortIndex) continue; previousSortIndex = indexedFeature.sortIndex; - addFeature(result, indexedFeature, queryGeometry, filterLayerIDs, geometryTileData, tileID, style, bearing, pixelsToTileUnits); + addFeature(result, indexedFeature, queryGeometry, queryOptions, geometryTileData, tileID, style, bearing, pixelsToTileUnits); } // Query symbol features, if they've been placed. @@ -87,7 +90,7 @@ void FeatureIndex::query( std::vector symbolFeatures = collisionTile->queryRenderedSymbols(queryGeometry, scale); std::sort(symbolFeatures.begin(), symbolFeatures.end(), topDownSymbols); for (const auto& symbolFeature : symbolFeatures) { - addFeature(result, symbolFeature, queryGeometry, filterLayerIDs, geometryTileData, tileID, style, bearing, pixelsToTileUnits); + addFeature(result, symbolFeature, queryGeometry, queryOptions, geometryTileData, tileID, style, bearing, pixelsToTileUnits); } } @@ -95,7 +98,7 @@ void FeatureIndex::addFeature( std::unordered_map>& result, const IndexedSubfeature& indexedFeature, const GeometryCoordinates& queryGeometry, - const optional>& filterLayerIDs, + const QueryOptions& options, const GeometryTileData& geometryTileData, const CanonicalTileID& tileID, const style::Style& style, @@ -103,7 +106,7 @@ void FeatureIndex::addFeature( const float pixelsToTileUnits) const { auto& layerIDs = bucketLayerIDs.at(indexedFeature.bucketName); - if (filterLayerIDs && !vectorsIntersect(layerIDs, *filterLayerIDs)) { + if (options.layerIDs && !vectorsIntersect(layerIDs, *options.layerIDs)) { return; } @@ -114,7 +117,7 @@ void FeatureIndex::addFeature( assert(geometryTileFeature); for (const auto& layerID : layerIDs) { - if (filterLayerIDs && !vectorContains(*filterLayerIDs, layerID)) { + if (options.layerIDs && !vectorContains(*options.layerIDs, layerID)) { continue; } @@ -125,6 +128,10 @@ void FeatureIndex::addFeature( continue; } + if (options.filter && !(*options.filter)(*geometryTileFeature)) { + continue; + } + result[layerID].push_back(convertFeature(*geometryTileFeature, tileID)); } } diff --git a/src/mbgl/geometry/feature_index.hpp b/src/mbgl/geometry/feature_index.hpp index ca813f4b6b..d2f68fd103 100644 --- a/src/mbgl/geometry/feature_index.hpp +++ b/src/mbgl/geometry/feature_index.hpp @@ -11,6 +11,8 @@ namespace mbgl { +class QueryOptions; + namespace style { class Style; } // namespace style @@ -39,7 +41,7 @@ public: const float bearing, const double tileSize, const double scale, - const optional>& layerIDs, + const QueryOptions& options, const GeometryTileData&, const CanonicalTileID&, const style::Style&, @@ -59,7 +61,7 @@ private: std::unordered_map>& result, const IndexedSubfeature&, const GeometryCoordinates& queryGeometry, - const optional>& filterLayerIDs, + const QueryOptions& options, const GeometryTileData&, const CanonicalTileID&, const style::Style&, diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index 857f088b62..f4f4d67148 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -810,20 +809,20 @@ void Map::removeAnnotation(AnnotationID annotation) { #pragma mark - Feature query api -std::vector Map::queryRenderedFeatures(const ScreenCoordinate& point, const optional>& layerIDs) { +std::vector Map::queryRenderedFeatures(const ScreenCoordinate& point, const QueryOptions& options) { if (!impl->style) return {}; - return impl->style->queryRenderedFeatures({ + return impl->style->queryRenderedFeatures( { point }, impl->transform.getState(), - layerIDs - }); + options + ); } -std::vector Map::queryRenderedFeatures(const ScreenBox& box, const optional>& layerIDs) { +std::vector Map::queryRenderedFeatures(const ScreenBox& box, const QueryOptions& options) { if (!impl->style) return {}; - return impl->style->queryRenderedFeatures({ + return impl->style->queryRenderedFeatures( { box.min, { box.max.x, box.min.y }, @@ -832,12 +831,14 @@ std::vector Map::queryRenderedFeatures(const ScreenBox& box, const opti box.min }, impl->transform.getState(), - layerIDs - }); + options + ); } AnnotationIDs Map::queryPointAnnotations(const ScreenBox& box) { - auto features = queryRenderedFeatures(box, {{ AnnotationManager::PointLayerID }}); + QueryOptions options; + options.layerIDs = {{ AnnotationManager::PointLayerID }}; + auto features = queryRenderedFeatures(box, options); std::set set; for (auto &feature : features) { assert(feature.id); diff --git a/src/mbgl/style/query_parameters.hpp b/src/mbgl/style/query_parameters.hpp deleted file mode 100644 index 3c1abf3b70..0000000000 --- a/src/mbgl/style/query_parameters.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include - -#include - -namespace mbgl { - -class TransformState; - -namespace style { - -class QueryParameters { -public: - const ScreenLineString& geometry; - const TransformState& transformState; - const optional>& layerIDs; -}; - -} // namespace style -} // namespace mbgl diff --git a/src/mbgl/style/source_impl.cpp b/src/mbgl/style/source_impl.cpp index 003df4f6b1..22e51f8885 100644 --- a/src/mbgl/style/source_impl.cpp +++ b/src/mbgl/style/source_impl.cpp @@ -4,12 +4,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include @@ -200,17 +200,19 @@ void Source::Impl::reloadTiles() { } } -std::unordered_map> Source::Impl::queryRenderedFeatures(const QueryParameters& parameters) const { +std::unordered_map> Source::Impl::queryRenderedFeatures(const ScreenLineString& geometry, + const TransformState& transformState, + const QueryOptions& options) const { std::unordered_map> result; - if (renderTiles.empty() || parameters.geometry.empty()) { + if (renderTiles.empty() || geometry.empty()) { return result; } LineString queryGeometry; - for (const auto& p : parameters.geometry) { + for (const auto& p : geometry) { queryGeometry.push_back(TileCoordinate::fromScreenCoordinate( - parameters.transformState, 0, { p.x, parameters.transformState.getSize().height - p.y }).p); + transformState, 0, { p.x, transformState.getSize().height - p.y }).p); } mapbox::geometry::box box = mapbox::geometry::envelope(queryGeometry); @@ -245,8 +247,8 @@ std::unordered_map> Source::Impl::queryRendere renderTile.tile.queryRenderedFeatures(result, tileSpaceQueryGeometry, - parameters.transformState, - parameters.layerIDs); + transformState, + options); } return result; diff --git a/src/mbgl/style/source_impl.hpp b/src/mbgl/style/source_impl.hpp index e6340ae1cb..ea2135c3c1 100644 --- a/src/mbgl/style/source_impl.hpp +++ b/src/mbgl/style/source_impl.hpp @@ -66,7 +66,9 @@ public: std::map& getRenderTiles(); std::unordered_map> - queryRenderedFeatures(const QueryParameters&) const; + queryRenderedFeatures(const ScreenLineString& geometry, + const TransformState& transformState, + const QueryOptions& options) const; void setCacheSize(size_t); void onLowMemory(); diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp index b6f14ecf4b..aacf811f4d 100644 --- a/src/mbgl/style/style.cpp +++ b/src/mbgl/style/style.cpp @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -31,6 +30,7 @@ #include #include #include +#include #include @@ -502,11 +502,13 @@ RenderData Style::getRenderData(MapDebugOptions debugOptions, float angle) const return result; } -std::vector Style::queryRenderedFeatures(const QueryParameters& parameters) const { +std::vector Style::queryRenderedFeatures(const ScreenLineString& geometry, + const TransformState& transformState, + const QueryOptions& options) const { std::unordered_set sourceFilter; - if (parameters.layerIDs) { - for (const auto& layerID : *parameters.layerIDs) { + if (options.layerIDs) { + for (const auto& layerID : *options.layerIDs) { auto layer = getLayer(layerID); if (layer) sourceFilter.emplace(layer->baseImpl->source); } @@ -520,7 +522,7 @@ std::vector Style::queryRenderedFeatures(const QueryParameters& paramet continue; } - auto sourceResults = source->baseImpl->queryRenderedFeatures(parameters); + auto sourceResults = source->baseImpl->queryRenderedFeatures(geometry, transformState, options); std::move(sourceResults.begin(), sourceResults.end(), std::inserter(resultsByLayer, resultsByLayer.begin())); } diff --git a/src/mbgl/style/style.hpp b/src/mbgl/style/style.hpp index 4c4bcec63a..5246f6877d 100644 --- a/src/mbgl/style/style.hpp +++ b/src/mbgl/style/style.hpp @@ -28,6 +28,8 @@ class GlyphAtlas; class SpriteAtlas; class LineAtlas; class RenderData; +class TransformState; +class QueryOptions; namespace style { @@ -95,8 +97,10 @@ public: RenderData getRenderData(MapDebugOptions, float angle) const; - std::vector queryRenderedFeatures(const QueryParameters&) const; - + std::vector queryRenderedFeatures(const ScreenLineString& geometry, + const TransformState& transformState, + const QueryOptions& options) const; + float getQueryRadius() const; void setSourceTileCacheSize(size_t); diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp index 9aeb35c821..83d130841d 100644 --- a/src/mbgl/tile/geometry_tile.cpp +++ b/src/mbgl/tile/geometry_tile.cpp @@ -13,6 +13,7 @@ #include #include #include +#include namespace mbgl { @@ -141,7 +142,7 @@ void GeometryTile::queryRenderedFeatures( std::unordered_map>& result, const GeometryCoordinates& queryGeometry, const TransformState& transformState, - const optional>& layerIDs) { + const QueryOptions& options) { if (!featureIndex || !data) return; @@ -150,7 +151,7 @@ void GeometryTile::queryRenderedFeatures( transformState.getAngle(), util::tileSize * id.overscaleFactor(), std::pow(2, transformState.getZoom() - id.overscaledZ), - layerIDs, + options, *data, id.canonical, style, diff --git a/src/mbgl/tile/geometry_tile.hpp b/src/mbgl/tile/geometry_tile.hpp index c61a510311..85a068ee01 100644 --- a/src/mbgl/tile/geometry_tile.hpp +++ b/src/mbgl/tile/geometry_tile.hpp @@ -44,7 +44,7 @@ public: std::unordered_map>& result, const GeometryCoordinates& queryGeometry, const TransformState&, - const optional>& layerIDs) override; + const QueryOptions& options) override; void cancel() override; diff --git a/src/mbgl/tile/tile.cpp b/src/mbgl/tile/tile.cpp index e84eaaf780..4829ac8355 100644 --- a/src/mbgl/tile/tile.cpp +++ b/src/mbgl/tile/tile.cpp @@ -3,6 +3,7 @@ #include #include #include +#include namespace mbgl { @@ -32,6 +33,6 @@ void Tile::queryRenderedFeatures( std::unordered_map>&, const GeometryCoordinates&, const TransformState&, - const optional>&) {} + const QueryOptions&) {} } // namespace mbgl diff --git a/src/mbgl/tile/tile.hpp b/src/mbgl/tile/tile.hpp index cebf913f56..0f0babf085 100644 --- a/src/mbgl/tile/tile.hpp +++ b/src/mbgl/tile/tile.hpp @@ -21,6 +21,7 @@ class DebugBucket; class TransformState; class TileObserver; class PlacementConfig; +class QueryOptions; namespace style { class Layer; @@ -55,7 +56,7 @@ public: std::unordered_map>& result, const GeometryCoordinates& queryGeometry, const TransformState&, - const optional>& layerIDs); + const QueryOptions& options); void setTriedOptional(); diff --git a/test/api/annotations.test.cpp b/test/api/annotations.test.cpp index 6644e9c92c..30027d8610 100644 --- a/test/api/annotations.test.cpp +++ b/test/api/annotations.test.cpp @@ -401,7 +401,7 @@ TEST(Annotations, VisibleFeatures) { test.map.setBearing(45); test::render(test.map, test.view); - auto features = test.map.queryRenderedFeatures(box); + auto features = test.map.queryRenderedFeatures(box, {}); auto sortID = [](const Feature& lhs, const Feature& rhs) { return lhs.id < rhs.id; }; auto sameID = [](const Feature& lhs, const Feature& rhs) { return lhs.id == rhs.id; }; std::sort(features.begin(), features.end(), sortID); diff --git a/test/api/query.test.cpp b/test/api/query.test.cpp index 4d2bf00f67..b42046fb48 100644 --- a/test/api/query.test.cpp +++ b/test/api/query.test.cpp @@ -10,6 +10,7 @@ #include using namespace mbgl; +using namespace mbgl::style; namespace { @@ -39,7 +40,7 @@ TEST(Query, QueryRenderedFeatures) { QueryTest test; auto features1 = test.map.queryRenderedFeatures(test.map.pixelForLatLng({ 0, 0 })); - EXPECT_EQ(features1.size(), 3u); + EXPECT_EQ(features1.size(), 4u); auto features2 = test.map.queryRenderedFeatures(test.map.pixelForLatLng({ 9, 9 })); EXPECT_EQ(features2.size(), 0u); @@ -50,15 +51,33 @@ TEST(Query, QueryRenderedFeaturesFilterLayer) { auto zz = test.map.pixelForLatLng({ 0, 0 }); - auto features1 = test.map.queryRenderedFeatures(zz, {{ "layer1"}}); + auto features1 = test.map.queryRenderedFeatures(zz, {{{ "layer1"}}, {}}); EXPECT_EQ(features1.size(), 1u); - auto features2 = test.map.queryRenderedFeatures(zz, {{ "layer1", "layer2" }}); + auto features2 = test.map.queryRenderedFeatures(zz, {{{ "layer1", "layer2" }}, {}}); EXPECT_EQ(features2.size(), 2u); - auto features3 = test.map.queryRenderedFeatures(zz, {{ "foobar" }}); + auto features3 = test.map.queryRenderedFeatures(zz, {{{ "foobar" }}, {}}); EXPECT_EQ(features3.size(), 0u); - auto features4 = test.map.queryRenderedFeatures(zz, {{ "foobar", "layer3" }}); + auto features4 = test.map.queryRenderedFeatures(zz, {{{ "foobar", "layer3" }}, {}}); EXPECT_EQ(features4.size(), 1u); } + +TEST(Query, QueryRenderedFeaturesFilter) { + QueryTest test; + + auto zz = test.map.pixelForLatLng({ 0, 0 }); + + const EqualsFilter eqFilter = { "key1", std::string("value1") }; + auto features1 = test.map.queryRenderedFeatures(zz, {{}, { eqFilter }}); + EXPECT_EQ(features1.size(), 1u); + + const IdentifierNotEqualsFilter idNotEqFilter = { std::string("feature1") }; + auto features2 = test.map.queryRenderedFeatures(zz, {{{ "layer4" }}, { idNotEqFilter }}); + EXPECT_EQ(features2.size(), 0u); + + const GreaterThanFilter gtFilter = { "key2", 1.0 }; + auto features3 = test.map.queryRenderedFeatures(zz, {{ }, { gtFilter }}); + EXPECT_EQ(features3.size(), 1u); +} diff --git a/test/fixtures/api/query_style.json b/test/fixtures/api/query_style.json index 6978e1ba1b..4e11921775 100644 --- a/test/fixtures/api/query_style.json +++ b/test/fixtures/api/query_style.json @@ -30,6 +30,26 @@ 0 ] } + }, + "source4": { + "type": "geojson", + "data": { + "type": "Feature", + "id": "feature1", + "geometry": { + "type": "Point", + "coordinates": [ + 0.0, + 0.0 + ] + }, + "properties": { + "key1": "value1", + "key2": 1.5, + "key3": false, + "key4": 0.5 + } + } } }, "layers": [ @@ -56,6 +76,14 @@ "layout": { "icon-image": "test-icon" } + }, + { + "id": "layer4", + "type": "symbol", + "source": "source4", + "layout": { + "icon-image": "test-icon" + } } ] } -- cgit v1.2.1 From 161ae804c23ff76f6c25596e811ec5861833d960 Mon Sep 17 00:00:00 2001 From: Ivo van Dongen Date: Thu, 2 Mar 2017 18:36:44 -0800 Subject: [ios, macos] Add support for queryRenderedFeatures filter --- platform/ios/CHANGELOG.md | 1 + platform/ios/src/MGLMapView.h | 59 +++++++++++++++++++++---- platform/ios/src/MGLMapView.mm | 25 +++++++++-- platform/macos/CHANGELOG.md | 1 + platform/macos/src/MGLMapView.h | 94 ++++++++++++++++++++++++++++++---------- platform/macos/src/MGLMapView.mm | 23 +++++++--- 6 files changed, 163 insertions(+), 40 deletions(-) diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index 33da2715f2..79c9b59f7e 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -52,6 +52,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * Fixed an issue that sometimes caused crashes when the SDK interacted with the file system in the background. ([#8125](https://github.com/mapbox/mapbox-gl-native/pull/8125)) * Added a `MGLDistanceFormatter` class for formatting geographic distances. ([#7888](https://github.com/mapbox/mapbox-gl-native/pull/7888)) * Fixed an issue that was causing the system location indicator to stay on in background after telemetry was disabled. ([#7833](https://github.com/mapbox/mapbox-gl-native/pull/7833)) +* Added support for predicates in rendered feature querying [8256](https://github.com/mapbox/mapbox-gl-native/pull/8246) ## 3.4.2 - February 21, 2017 diff --git a/platform/ios/src/MGLMapView.h b/platform/ios/src/MGLMapView.h index 4a7ac308de..8fb58005de 100644 --- a/platform/ios/src/MGLMapView.h +++ b/platform/ios/src/MGLMapView.h @@ -1136,6 +1136,25 @@ IB_DESIGNABLE /** Returns an array of rendered map features that intersect with a given point, restricted to the given style layers. + + This method may return all features from the specified layers. To filter + the returned features, use the + `-visibleFeaturesAtPoint:inStyleLayersWithIdentifiers:predicate:` method. For more + information about searching for map features, see that method’s documentation. + + @param point A point expressed in the map view’s coordinate system. + @param styleLayerIdentifiers A set of strings that correspond to the names + of layers defined in the current style. Only the features contained in + these layers are included in the returned array. + @return An array of objects conforming to the `MGLFeature` protocol that + represent features in the sources used by the current style. + */ +- (NS_ARRAY_OF(id ) *)visibleFeaturesAtPoint:(CGPoint)point inStyleLayersWithIdentifiers:(nullable NS_SET_OF(NSString *) *)styleLayerIdentifiers NS_SWIFT_NAME(visibleFeatures(at:styleLayerIdentifiers:)); + +/** + Returns an array of rendered map features that intersect with a given point, + restricted to the given style layers and filtered by the given + predicate. Each object in the returned array represents a feature rendered by the current style and provides access to attributes specified by the relevant @@ -1183,10 +1202,11 @@ IB_DESIGNABLE @param styleLayerIdentifiers A set of strings that correspond to the names of layers defined in the current style. Only the features contained in these layers are included in the returned array. + @param predicate A predicate to filter the returned features. @return An array of objects conforming to the `MGLFeature` protocol that represent features in the sources used by the current style. */ -- (NS_ARRAY_OF(id ) *)visibleFeaturesAtPoint:(CGPoint)point inStyleLayersWithIdentifiers:(nullable NS_SET_OF(NSString *) *)styleLayerIdentifiers NS_SWIFT_NAME(visibleFeatures(at:styleLayerIdentifiers:)); +- (NS_ARRAY_OF(id ) *)visibleFeaturesAtPoint:(CGPoint)point inStyleLayersWithIdentifiers:(nullable NS_SET_OF(NSString *) *)styleLayerIdentifiers predicate:(nullable NSPredicate *)predicate NS_SWIFT_NAME(visibleFeatures(at:styleLayerIdentifiers:predicate:)); /** Returns an array of rendered map features that intersect with the given @@ -1206,7 +1226,27 @@ IB_DESIGNABLE /** Returns an array of rendered map features that intersect with the given rectangle, restricted to the given style layers. + + This method may return all features from the specified layers. To filter + the returned features, use the + `-visibleFeaturesAtPoint:inStyleLayersWithIdentifiers:predicate:` method. For + more information about searching for map features, see that method’s + documentation. + + @param rect A rectangle expressed in the map view’s coordinate system. + @param styleLayerIdentifiers A set of strings that correspond to the names of + layers defined in the current style. Only the features contained in these + layers are included in the returned array. + @return An array of objects conforming to the `MGLFeature` protocol that + represent features in the sources used by the current style. + */ +- (NS_ARRAY_OF(id ) *)visibleFeaturesInRect:(CGRect)rect inStyleLayersWithIdentifiers:(nullable NS_SET_OF(NSString *) *)styleLayerIdentifiers NS_SWIFT_NAME(visibleFeatures(in:styleLayerIdentifiers:)); +/** + Returns an array of rendered map features that intersect with the given + rectangle, restricted to the given style layers and filtered by the given + predicate. + Each object in the returned array represents a feature rendered by the current style and provides access to attributes specified by the relevant tile sources. @@ -1243,21 +1283,22 @@ IB_DESIGNABLE Mapbox Studio. @note Layer identifiers are not guaranteed to exist across styles or different - versions of the same style. Applications that use this API must first set the - style URL to an explicitly versioned style using a convenience method like - `+[MGLStyle outdoorsStyleURLWithVersion:]`, `MGLMapView`’s “Style URL” - inspectable in Interface Builder, or a manually constructed `NSURL`. This - approach also avoids layer identifer name changes that will occur in the default - style’s layers over time. - + versions of the same style. Applications that use this API must first set the + style URL to an explicitly versioned style using a convenience method like + `+[MGLStyle outdoorsStyleURLWithVersion:]`, `MGLMapView`’s “Style URL” + inspectable in Interface Builder, or a manually constructed `NSURL`. This + approach also avoids layer identifer name changes that will occur in the default + style’s layers over time. + @param rect A rectangle expressed in the map view’s coordinate system. @param styleLayerIdentifiers A set of strings that correspond to the names of layers defined in the current style. Only the features contained in these layers are included in the returned array. + @param predicate A predicate to filter the returned features. @return An array of objects conforming to the `MGLFeature` protocol that represent features in the sources used by the current style. */ -- (NS_ARRAY_OF(id ) *)visibleFeaturesInRect:(CGRect)rect inStyleLayersWithIdentifiers:(nullable NS_SET_OF(NSString *) *)styleLayerIdentifiers NS_SWIFT_NAME(visibleFeatures(in:styleLayerIdentifiers:)); +- (NS_ARRAY_OF(id ) *)visibleFeaturesInRect:(CGRect)rect inStyleLayersWithIdentifiers:(nullable NS_SET_OF(NSString *) *)styleLayerIdentifiers predicate:(nullable NSPredicate *)predicate NS_SWIFT_NAME(visibleFeatures(in:styleLayerIdentifiers:predicate:)); #pragma mark Debugging the Map diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index 2990a4e163..5b4f27da18 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -45,6 +45,7 @@ #import "NSException+MGLAdditions.h" #import "NSURL+MGLAdditions.h" #import "UIImage+MGLAdditions.h" +#import "NSPredicate+MGLAdditions.h" #import "MGLFaux3DUserLocationAnnotationView.h" #import "MGLUserLocationAnnotationView.h" @@ -4605,7 +4606,11 @@ public: return [self visibleFeaturesAtPoint:point inStyleLayersWithIdentifiers:nil]; } -- (NS_ARRAY_OF(id ) *)visibleFeaturesAtPoint:(CGPoint)point inStyleLayersWithIdentifiers:(NS_SET_OF(NSString *) *)styleLayerIdentifiers +- (NS_ARRAY_OF(id ) *)visibleFeaturesAtPoint:(CGPoint)point inStyleLayersWithIdentifiers:(NS_SET_OF(NSString *) *)styleLayerIdentifiers { + return [self visibleFeaturesAtPoint:point inStyleLayersWithIdentifiers:styleLayerIdentifiers predicate:nil]; +} + +- (NS_ARRAY_OF(id ) *)visibleFeaturesAtPoint:(CGPoint)point inStyleLayersWithIdentifiers:(NS_SET_OF(NSString *) *)styleLayerIdentifiers predicate:(NSPredicate *)predicate { mbgl::ScreenCoordinate screenCoordinate = { point.x, point.y }; @@ -4620,8 +4625,13 @@ public: }]; optionalLayerIDs = layerIDs; } + + mbgl::optional optionalFilter; + if (predicate) { + optionalFilter = predicate.mgl_filter; + } - std::vector features = _mbglMap->queryRenderedFeatures(screenCoordinate, { optionalLayerIDs, {} }); + std::vector features = _mbglMap->queryRenderedFeatures(screenCoordinate, { optionalLayerIDs, optionalFilter }); return MGLFeaturesFromMBGLFeatures(features); } @@ -4630,6 +4640,10 @@ public: } - (NS_ARRAY_OF(id ) *)visibleFeaturesInRect:(CGRect)rect inStyleLayersWithIdentifiers:(NS_SET_OF(NSString *) *)styleLayerIdentifiers { + return [self visibleFeaturesInRect:rect inStyleLayersWithIdentifiers:styleLayerIdentifiers predicate:nil]; +} + +- (NS_ARRAY_OF(id ) *)visibleFeaturesInRect:(CGRect)rect inStyleLayersWithIdentifiers:(NS_SET_OF(NSString *) *)styleLayerIdentifiers predicate:(NSPredicate *)predicate { mbgl::ScreenBox screenBox = { { CGRectGetMinX(rect), CGRectGetMinY(rect) }, { CGRectGetMaxX(rect), CGRectGetMaxY(rect) }, @@ -4644,8 +4658,13 @@ public: }]; optionalLayerIDs = layerIDs; } + + mbgl::optional optionalFilter; + if (predicate) { + optionalFilter = predicate.mgl_filter; + } - std::vector features = _mbglMap->queryRenderedFeatures(screenBox, { optionalLayerIDs, {} }); + std::vector features = _mbglMap->queryRenderedFeatures(screenBox, { optionalLayerIDs, optionalFilter }); return MGLFeaturesFromMBGLFeatures(features); } diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md index 38711b5202..5a10432ce4 100644 --- a/platform/macos/CHANGELOG.md +++ b/platform/macos/CHANGELOG.md @@ -47,6 +47,7 @@ * 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)) * Fixed flickering that occurred when panning past the antimeridian. ([#7574](https://github.com/mapbox/mapbox-gl-native/pull/7574)) * Added a `MGLDistanceFormatter` class for formatting geographic distances. ([#7888](https://github.com/mapbox/mapbox-gl-native/pull/7888)) +* Added support for predicates in rendered feature querying [8256](https://github.com/mapbox/mapbox-gl-native/pull/8246) ## 0.3.1 - February 21, 2017 diff --git a/platform/macos/src/MGLMapView.h b/platform/macos/src/MGLMapView.h index 4d1a2fc2c4..fa07821e19 100644 --- a/platform/macos/src/MGLMapView.h +++ b/platform/macos/src/MGLMapView.h @@ -789,6 +789,33 @@ MGL_EXPORT IB_DESIGNABLE Returns an array of rendered map features that intersect with a given point, restricted to the given style layers. + This method may return all features from the specified layers. To filter + the returned features, use the + `-visibleFeaturesAtPoint:inStyleLayersWithIdentifiers:predicate:` method. For more + information about searching for map features, see that method’s documentation. + + @note Layer identifiers are not guaranteed to exist across styles or different + versions of the same style. Applications that use this API must first set the + style URL to an explicitly versioned style using a convenience method like + `+[MGLStyle outdoorsStyleURLWithVersion:]`, `MGLMapView`’s “Style URL” + inspectable in Interface Builder, or a manually constructed `NSURL`. This + approach also avoids layer identifer name changes that will occur in the default + style’s layers over time. + + @param point A point expressed in the map view’s coordinate system. + @param styleLayerIdentifiers A set of strings that correspond to the names of + layers defined in the current style. Only the features contained in these + layers are included in the returned array. + @return An array of objects conforming to the `MGLFeature` protocol that + represent features in the sources used by the current style. + */ +- (NS_ARRAY_OF(id ) *)visibleFeaturesAtPoint:(NSPoint)point inStyleLayersWithIdentifiers:(nullable NS_SET_OF(NSString *) *)styleLayerIdentifiers NS_SWIFT_NAME(visibleFeatures(at:styleLayerIdentifiers:)); + +/** + Returns an array of rendered map features that intersect with a given point, + restricted to the given style layers and filtered by the given + predicate. + Each object in the returned array represents a feature rendered by the current style and provides access to attributes specified by the relevant tile sources. @@ -824,21 +851,22 @@ MGL_EXPORT IB_DESIGNABLE Mapbox Studio. @note Layer identifiers are not guaranteed to exist across styles or different - versions of the same style. Applications that use this API must first set the - style URL to an explicitly versioned style using a convenience method like - `+[MGLStyle outdoorsStyleURLWithVersion:]`, `MGLMapView`’s “Style URL” - inspectable in Interface Builder, or a manually constructed `NSURL`. This - approach also avoids layer identifer name changes that will occur in the default - style’s layers over time. - + versions of the same style. Applications that use this API must first set the + style URL to an explicitly versioned style using a convenience method like + `+[MGLStyle outdoorsStyleURLWithVersion:]`, `MGLMapView`’s “Style URL” + inspectable in Interface Builder, or a manually constructed `NSURL`. This + approach also avoids layer identifer name changes that will occur in the default + style’s layers over time. + @param point A point expressed in the map view’s coordinate system. @param styleLayerIdentifiers A set of strings that correspond to the names of - layers defined in the current style. Only the features contained in these - layers are included in the returned array. + layers defined in the current style. Only the features contained in these + layers are included in the returned array. + @param predicate A predicate to filter the returned features. @return An array of objects conforming to the `MGLFeature` protocol that - represent features in the sources used by the current style. + represent features in the sources used by the current style. */ -- (NS_ARRAY_OF(id ) *)visibleFeaturesAtPoint:(NSPoint)point inStyleLayersWithIdentifiers:(nullable NS_SET_OF(NSString *) *)styleLayerIdentifiers NS_SWIFT_NAME(visibleFeatures(_:styleLayerIdentifiers:)); +- (NS_ARRAY_OF(id ) *)visibleFeaturesAtPoint:(NSPoint)point inStyleLayersWithIdentifiers:(nullable NS_SET_OF(NSString *) *)styleLayerIdentifiers predicate:(nullable NSPredicate *)predicate NS_SWIFT_NAME(visibleFeatures(at:styleLayerIdentifiers:predicate:)); /** Returns an array of rendered map features that intersect with the given @@ -858,7 +886,28 @@ MGL_EXPORT IB_DESIGNABLE /** Returns an array of rendered map features that intersect with the given rectangle, restricted to the given style layers. + + This method may return all features from the specified layers. To filter + the returned features, use the + `-visibleFeaturesAtPoint:inStyleLayersWithIdentifiers:predicate:` method. For + more information about searching for map features, see that method’s + documentation. + @param rect A rectangle expressed in the map view’s coordinate system. + @param styleLayerIdentifiers A set of strings that correspond to the names of + layers defined in the current style. Only the features contained in these + layers are included in the returned array. + @return An array of objects conforming to the `MGLFeature` protocol that + represent features in the sources used by the current style. + */ +- (NS_ARRAY_OF(id ) *)visibleFeaturesInRect:(NSRect)rect inStyleLayersWithIdentifiers:(nullable NS_SET_OF(NSString *) *)styleLayerIdentifiers NS_SWIFT_NAME(visibleFeatures(at:styleLayerIdentifiers:)); + +/** + Returns an array of rendered map features that intersect with the given + rectangle, restricted to the given style layers and filtered by the given + predicate. + + Each object in the returned array represents a feature rendered by the current style and provides access to attributes specified by the relevant tile sources. @@ -895,21 +944,22 @@ MGL_EXPORT IB_DESIGNABLE Mapbox Studio. @note Layer identifiers are not guaranteed to exist across styles or different - versions of the same style. Applications that use this API must first set the - style URL to an explicitly versioned style using a convenience method like - `+[MGLStyle outdoorsStyleURLWithVersion:]`, `MGLMapView`’s “Style URL” - inspectable in Interface Builder, or a manually constructed `NSURL`. This - approach also avoids layer identifer name changes that will occur in the default - style’s layers over time. - + versions of the same style. Applications that use this API must first set the + style URL to an explicitly versioned style using a convenience method like + `+[MGLStyle outdoorsStyleURLWithVersion:]`, `MGLMapView`’s “Style URL” + inspectable in Interface Builder, or a manually constructed `NSURL`. This + approach also avoids layer identifer name changes that will occur in the default + style’s layers over time. + @param rect A rectangle expressed in the map view’s coordinate system. @param styleLayerIdentifiers A set of strings that correspond to the names of - layers defined in the current style. Only the features contained in these - layers are included in the returned array. + layers defined in the current style. Only the features contained in these + layers are included in the returned array. + @param predicate A predicate to filter the returned features. @return An array of objects conforming to the `MGLFeature` protocol that - represent features in the sources used by the current style. + represent features in the sources used by the current style. */ -- (NS_ARRAY_OF(id ) *)visibleFeaturesInRect:(NSRect)rect inStyleLayersWithIdentifiers:(nullable NS_SET_OF(NSString *) *)styleLayerIdentifiers NS_SWIFT_NAME(visibleFeatures(_:styleLayerIdentifiers:)); +- (NS_ARRAY_OF(id ) *)visibleFeaturesInRect:(NSRect)rect inStyleLayersWithIdentifiers:(nullable NS_SET_OF(NSString *) *)styleLayerIdentifiers predicate:(nullable NSPredicate *)predicate NS_SWIFT_NAME(visibleFeatures(in:styleLayerIdentifiers:predicate:)); #pragma mark Converting Geographic Coordinates diff --git a/platform/macos/src/MGLMapView.mm b/platform/macos/src/MGLMapView.mm index ff98095e15..e09daa1c18 100644 --- a/platform/macos/src/MGLMapView.mm +++ b/platform/macos/src/MGLMapView.mm @@ -50,6 +50,7 @@ #import "NSURL+MGLAdditions.h" #import "NSColor+MGLAdditions.h" #import "NSImage+MGLAdditions.h" +#import "NSPredicate+MGLAdditions.h" #import @@ -2519,7 +2520,7 @@ public: return [self visibleFeaturesAtPoint:point inStyleLayersWithIdentifiers:nil]; } -- (NS_ARRAY_OF(id ) *)visibleFeaturesAtPoint:(NSPoint)point inStyleLayersWithIdentifiers:(NS_SET_OF(NSString *) *)styleLayerIdentifiers { +- (NS_ARRAY_OF(id ) *)visibleFeaturesAtPoint:(NSPoint)point inStyleLayersWithIdentifiers:(NS_SET_OF(NSString *) *)styleLayerIdentifiers predicate:(NSPredicate *)predicate { // Cocoa origin is at the lower-left corner. mbgl::ScreenCoordinate screenCoordinate = { point.x, NSHeight(self.bounds) - point.y }; @@ -2532,8 +2533,13 @@ public: }]; optionalLayerIDs = layerIDs; } - - std::vector features = _mbglMap->queryRenderedFeatures(screenCoordinate, { optionalLayerIDs }); + + mbgl::optional optionalFilter; + if (predicate) { + optionalFilter = predicate.mgl_filter; + } + + std::vector features = _mbglMap->queryRenderedFeatures(screenCoordinate, { optionalLayerIDs, optionalFilter }); return MGLFeaturesFromMBGLFeatures(features); } @@ -2541,7 +2547,7 @@ public: return [self visibleFeaturesInRect:rect inStyleLayersWithIdentifiers:nil]; } -- (NS_ARRAY_OF(id ) *)visibleFeaturesInRect:(NSRect)rect inStyleLayersWithIdentifiers:(NS_SET_OF(NSString *) *)styleLayerIdentifiers { +- (NS_ARRAY_OF(id ) *)visibleFeaturesInRect:(NSRect)rect inStyleLayersWithIdentifiers:(NS_SET_OF(NSString *) *)styleLayerIdentifiers predicate:(NSPredicate *)predicate { // Cocoa origin is at the lower-left corner. mbgl::ScreenBox screenBox = { { NSMinX(rect), NSHeight(self.bounds) - NSMaxY(rect) }, @@ -2557,8 +2563,13 @@ public: }]; optionalLayerIDs = layerIDs; } - - std::vector features = _mbglMap->queryRenderedFeatures(screenBox, { optionalLayerIDs }); + + mbgl::optional optionalFilter; + if (predicate) { + optionalFilter = predicate.mgl_filter; + } + + std::vector features = _mbglMap->queryRenderedFeatures(screenBox, { optionalLayerIDs, optionalFilter }); return MGLFeaturesFromMBGLFeatures(features); } -- cgit v1.2.1 From b5d0a661c520716c6345aca6ea0207f5d49b6d54 Mon Sep 17 00:00:00 2001 From: Ivo van Dongen Date: Fri, 3 Mar 2017 15:31:14 -0800 Subject: [android] Add support for queryRenderedFeatures filter --- .../java/com/mapbox/mapboxsdk/maps/MapboxMap.java | 41 +++++++++++++++++++--- .../com/mapbox/mapboxsdk/maps/NativeMapView.java | 23 +++++++----- .../QueryRenderedFeaturesBoxHighlightActivity.java | 3 +- platform/android/src/native_map_view.cpp | 40 ++++++++++++++++++--- platform/android/src/native_map_view.hpp | 8 +++-- 5 files changed, 95 insertions(+), 20 deletions(-) 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 e3e33ec067..46c5e269c0 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 @@ -37,6 +37,7 @@ import com.mapbox.mapboxsdk.constants.MyLocationTracking; import com.mapbox.mapboxsdk.constants.Style; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.maps.widgets.MyLocationViewSettings; +import com.mapbox.mapboxsdk.style.layers.Filter; import com.mapbox.mapboxsdk.style.layers.Layer; import com.mapbox.mapboxsdk.style.sources.Source; import com.mapbox.services.commons.geojson.Feature; @@ -1674,7 +1675,23 @@ public final class MapboxMap { @NonNull public List queryRenderedFeatures(@NonNull PointF coordinates, @Nullable String... layerIds) { - return nativeMapView.queryRenderedFeatures(coordinates, layerIds); + return nativeMapView.queryRenderedFeatures(coordinates, layerIds, null); + } + + /** + * Queries the map for rendered features + * + * @param coordinates the point to query + * @param filter filters the returned features + * @param layerIds optionally - only query these layers + * @return the list of feature + */ + @UiThread + @NonNull + public List queryRenderedFeatures(@NonNull PointF coordinates, + @Nullable Filter.Statement filter, + @Nullable String... layerIds) { + return nativeMapView.queryRenderedFeatures(coordinates, layerIds, filter); } /** @@ -1686,9 +1703,25 @@ public final class MapboxMap { */ @UiThread @NonNull - public List queryRenderedFeatures(@NonNull RectF coordinates, @Nullable String... - layerIds) { - return nativeMapView.queryRenderedFeatures(coordinates, layerIds); + public List queryRenderedFeatures(@NonNull RectF coordinates, + @Nullable String... layerIds) { + return nativeMapView.queryRenderedFeatures(coordinates, layerIds, null); + } + + /** + * Queries the map for rendered features + * + * @param coordinates the box to query + * @param filter filters the returned features + * @param layerIds optionally - only query these layers + * @return the list of feature + */ + @UiThread + @NonNull + public List queryRenderedFeatures(@NonNull RectF coordinates, + @Nullable Filter.Statement filter, + @Nullable String... layerIds) { + return nativeMapView.queryRenderedFeatures(coordinates, layerIds, filter); } // 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 e02a0f3d36..7c68a48c4d 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 @@ -22,6 +22,7 @@ import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.geometry.ProjectedMeters; import com.mapbox.mapboxsdk.storage.FileSource; import com.mapbox.mapboxsdk.style.layers.CannotAddLayerException; +import com.mapbox.mapboxsdk.style.layers.Filter; import com.mapbox.mapboxsdk.style.layers.Layer; import com.mapbox.mapboxsdk.style.sources.CannotAddSourceException; import com.mapbox.mapboxsdk.style.sources.Source; @@ -881,27 +882,31 @@ final class NativeMapView { // Feature querying @NonNull - public List queryRenderedFeatures(PointF coordinates, String... layerIds) { + public List queryRenderedFeatures(@NonNull PointF coordinates, + @Nullable String[] layerIds, + @Nullable Filter.Statement filter) { if (isDestroyedOn("queryRenderedFeatures")) { return new ArrayList<>(); } Feature[] features = nativeQueryRenderedFeaturesForPoint(coordinates.x / pixelRatio, - coordinates.y / pixelRatio, layerIds); + coordinates.y / pixelRatio, layerIds, filter != null ? filter.toArray() : null); return features != null ? Arrays.asList(features) : new ArrayList(); } @NonNull - public List queryRenderedFeatures(RectF coordinates, String... layerIds) { + public List queryRenderedFeatures(@NonNull RectF coordinates, + @Nullable String[] layerIds, + @Nullable Filter.Statement filter) { if (isDestroyedOn("queryRenderedFeatures")) { return new ArrayList<>(); } Feature[] features = nativeQueryRenderedFeaturesForBox( - coordinates.left / pixelRatio, coordinates.top / pixelRatio, coordinates.right / pixelRatio, coordinates.bottom / pixelRatio, - layerIds); + layerIds, + filter != null ? filter.toArray() : null); return features != null ? Arrays.asList(features) : new ArrayList(); } @@ -1139,12 +1144,14 @@ final class NativeMapView { private native void nativeTakeSnapshot(); - private native Feature[] nativeQueryRenderedFeaturesForPoint(float x, float y, String[] - layerIds); + private native Feature[] nativeQueryRenderedFeaturesForPoint(float x, float y, + String[] layerIds, + Object[] filter); private native Feature[] nativeQueryRenderedFeaturesForBox(float left, float top, float right, float bottom, - String[] layerIds); + String[] layerIds, + Object[] filter); int getWidth() { if (isDestroyedOn("")) { 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 ca4fe4e4fd..1d15efef84 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 @@ -11,6 +11,7 @@ import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; import com.mapbox.mapboxsdk.style.layers.FillLayer; +import com.mapbox.mapboxsdk.style.layers.Filter; import com.mapbox.mapboxsdk.style.sources.GeoJsonSource; import com.mapbox.mapboxsdk.testapp.R; import com.mapbox.services.commons.geojson.Feature; @@ -53,7 +54,7 @@ public class QueryRenderedFeaturesBoxHighlightActivity extends AppCompatActivity 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 features = mapboxMap.queryRenderedFeatures(box, "building"); + List features = mapboxMap.queryRenderedFeatures(box, Filter.lt("height", 10), "building"); // Show count Toast.makeText( diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp index 73edc8e298..c97bdbbfe3 100755 --- a/platform/android/src/native_map_view.cpp +++ b/platform/android/src/native_map_view.cpp @@ -26,7 +26,14 @@ #include #include #include +#include +// Java -> C++ conversion +#include "style/android_conversion.hpp" +#include +#include + +// C++ -> Java conversion #include "conversion/conversion.hpp" #include "conversion/collection.hpp" #include "geometry/conversion/feature.hpp" @@ -694,6 +701,9 @@ void NativeMapView::setTransitionDelay(JNIEnv&, jlong delay) { } jni::Array NativeMapView::queryPointAnnotations(JNIEnv& env, jni::Object rect) { + using namespace mbgl::style; + using namespace mbgl::style::conversion; + // Convert input mbgl::ScreenBox box = { { RectF::getLeft(env, rect), RectF::getTop(env, rect) }, @@ -711,20 +721,40 @@ jni::Array NativeMapView::queryPointAnnotations(JNIEnv& env, jni::Object< return result; } -jni::Array> NativeMapView::queryRenderedFeaturesForPoint(JNIEnv& env, jni::jfloat x, jni::jfloat y, jni::Array layerIds) { +static inline optional toFilter(jni::JNIEnv& env, jni::Array> jfilter) { + using namespace mbgl::style; + using namespace mbgl::style::conversion; + + mbgl::optional filter; + if (jfilter) { + Value filterValue(env, jfilter); + auto converted = convert(filterValue); + if (!converted) { + mbgl::Log::Error(mbgl::Event::JNI, "Error setting filter: " + converted.error().message); + } + filter = std::move(*converted); + } + return filter; +} + +jni::Array> NativeMapView::queryRenderedFeaturesForPoint(JNIEnv& env, jni::jfloat x, jni::jfloat y, + jni::Array layerIds, + jni::Array> jfilter) { using namespace mbgl::android::conversion; using namespace mapbox::geometry; mbgl::optional> layers; if (layerIds != nullptr && layerIds.Length(env) > 0) { - layers = toVector(env, layerIds); + layers = android::conversion::toVector(env, layerIds); } point point = {x, y}; - return *convert>, std::vector>(env, map->queryRenderedFeatures(point, { layers, {} })); + return *convert>, std::vector>(env, map->queryRenderedFeatures(point, { layers, toFilter(env, jfilter) })); } -jni::Array> NativeMapView::queryRenderedFeaturesForBox(JNIEnv& env, jni::jfloat left, jni::jfloat top, jni::jfloat right, jni::jfloat bottom, jni::Array layerIds) { +jni::Array> NativeMapView::queryRenderedFeaturesForBox(JNIEnv& env, jni::jfloat left, jni::jfloat top, + jni::jfloat right, jni::jfloat bottom, jni::Array layerIds, + jni::Array> jfilter) { using namespace mbgl::android::conversion; using namespace mapbox::geometry; @@ -734,7 +764,7 @@ jni::Array> NativeMapView::queryRenderedFeaturesForBox(JNIE } box box = { point{ left, top}, point{ right, bottom } }; - return *convert>, std::vector>(env, map->queryRenderedFeatures(box, { layers, {} })); + return *convert>, std::vector>(env, map->queryRenderedFeatures(box, { layers, toFilter(env, jfilter) })); } jni::Array> NativeMapView::getLayers(JNIEnv& env) { diff --git a/platform/android/src/native_map_view.hpp b/platform/android/src/native_map_view.hpp index c38afd3e6c..b7bf03402e 100755 --- a/platform/android/src/native_map_view.hpp +++ b/platform/android/src/native_map_view.hpp @@ -197,9 +197,13 @@ public: jni::Array queryPointAnnotations(JNIEnv&, jni::Object); - jni::Array> queryRenderedFeaturesForPoint(JNIEnv&, jni::jfloat, jni::jfloat, jni::Array); + jni::Array> queryRenderedFeaturesForPoint(JNIEnv&, jni::jfloat, jni::jfloat, + jni::Array, + jni::Array> jfilter); - jni::Array> queryRenderedFeaturesForBox(JNIEnv&, jni::jfloat, jni::jfloat, jni::jfloat, jni::jfloat, jni::Array); + jni::Array> queryRenderedFeaturesForBox(JNIEnv&, jni::jfloat, jni::jfloat, jni::jfloat, + jni::jfloat, jni::Array, + jni::Array> jfilter); jni::Array> getLayers(JNIEnv&); -- cgit v1.2.1 From 2b7319d529e2335b355eacf602dda12c9e01dd9b Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Sat, 4 Mar 2017 09:06:04 -0800 Subject: [Qt] Remove the QML app We are now on Qt 5.9 and this is where the plugin will be developed from now on. --- .travis.yml | 1 - Makefile | 9 - platform/qt/README.md | 46 +- platform/qt/bitrise-qt5.yml | 1 - platform/qt/include/qquickmapboxgl.hpp | 176 -------- platform/qt/include/qquickmapboxglmapparameter.hpp | 34 -- platform/qt/qmlapp/main.cpp | 24 -- platform/qt/qmlapp/main.qml | 347 --------------- platform/qt/qmlapp/qml.qrc | 5 - platform/qt/qt5.cmake | 24 -- platform/qt/src/qquickmapboxgl.cpp | 469 --------------------- platform/qt/src/qquickmapboxglmapparameter.cpp | 35 -- platform/qt/src/qquickmapboxglrenderer.cpp | 120 ------ platform/qt/src/qquickmapboxglrenderer.hpp | 34 -- 14 files changed, 3 insertions(+), 1322 deletions(-) delete mode 100644 platform/qt/include/qquickmapboxgl.hpp delete mode 100644 platform/qt/include/qquickmapboxglmapparameter.hpp delete mode 100644 platform/qt/qmlapp/main.cpp delete mode 100644 platform/qt/qmlapp/main.qml delete mode 100644 platform/qt/qmlapp/qml.qrc delete mode 100644 platform/qt/src/qquickmapboxgl.cpp delete mode 100644 platform/qt/src/qquickmapboxglmapparameter.cpp delete mode 100644 platform/qt/src/qquickmapboxglrenderer.cpp delete mode 100644 platform/qt/src/qquickmapboxglrenderer.hpp diff --git a/.travis.yml b/.travis.yml index 3b13902776..391520319f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -189,7 +189,6 @@ matrix: - mapbox_export_mesa_library_path script: - make qt-app - - make qt-qml-app - make qt-test - make qt-docs - scripts/valgrind.sh build/qt-linux-x86_64/Release/mbgl-test --gtest_filter=-*.Load --gtest_filter=-Memory.Vector diff --git a/Makefile b/Makefile index 0da2dc159e..3f4f6e2d33 100644 --- a/Makefile +++ b/Makefile @@ -405,7 +405,6 @@ $(MACOS_QT_PROJ_PATH): $(BUILD_DEPS) @# Create Xcode schemes so that we can use xcodebuild from the command line. CMake doesn't @# create these automatically. XCODEPROJ=$(MACOS_QT_PROJ_PATH) SCHEME_NAME=mbgl-qt SCHEME_TYPE=executable platform/macos/scripts/create_scheme.sh - XCODEPROJ=$(MACOS_QT_PROJ_PATH) SCHEME_NAME=mbgl-qt-qml SCHEME_TYPE=executable platform/macos/scripts/create_scheme.sh XCODEPROJ=$(MACOS_QT_PROJ_PATH) SCHEME_NAME=mbgl-test SCHEME_TYPE=executable platform/macos/scripts/create_scheme.sh XCODEPROJ=$(MACOS_QT_PROJ_PATH) SCHEME_NAME=mbgl-benchmark SCHEME_TYPE=executable platform/macos/scripts/create_scheme.sh XCODEPROJ=$(MACOS_QT_PROJ_PATH) SCHEME_NAME=mbgl-core SCHEME_TYPE=library BUILDABLE_NAME=libmbgl-core.a BLUEPRINT_NAME=mbgl-core platform/macos/scripts/create_scheme.sh @@ -429,14 +428,6 @@ qt-app: $(QT_BUILD) run-qt-app: qt-app $(QT_OUTPUT_PATH)/mbgl-qt -.PHONY: qt-qml-app -qt-qml-app: $(QT_BUILD) - $(NINJA) $(NINJA_ARGS) -j$(JOBS) -C $(QT_OUTPUT_PATH) mbgl-qt-qml - -.PHONY: run-qt-qml-app -run-qt-qml-app: qt-qml-app - $(QT_OUTPUT_PATH)/mbgl-qt-qml - .PHONY: qt-test qt-test: $(QT_BUILD) $(NINJA) $(NINJA_ARGS) -j$(JOBS) -C $(QT_OUTPUT_PATH) mbgl-test diff --git a/platform/qt/README.md b/platform/qt/README.md index dc17d69903..22c06310c3 100644 --- a/platform/qt/README.md +++ b/platform/qt/README.md @@ -3,43 +3,10 @@ [![Travis](https://travis-ci.org/mapbox/mapbox-gl-native.svg?branch=master)](https://travis-ci.org/mapbox/mapbox-gl-native/builds) [![Bitrise](https://www.bitrise.io/app/96cfbc97e0245c22.svg?token=GxsqIOGPXhn0F23sSVSsYA&branch=master)](https://www.bitrise.io/app/96cfbc97e0245c22) -Provides [Qt](http://www.qt.io/) example applications and APIs via `QMapboxGL` -and `QQuickMapboxGL`: - -**QMapboxGL** - implements a C++03x-conformant API that has been tested from Qt -4.7 onwards (Travis CI currently builds it using both Qt 4 and Qt 5). - -**QQuickMapboxGL** - implements a Qt Quick (QML) item that can be added to a -scene. Because `QQuickFramebufferObject` has been added in Qt version 5.2, we -support this API from this version onwards. - -![Mapbox Qt QML -example](https://c2.staticflickr.com/8/7689/26247088394_01541b34de_o.png) - ### Developing -[Qt supports many platforms](https://www.qt.io/qt-framework/#section-4) - so far -we have been testing our code on Linux and macOS desktops, as well as embedded -devices such as Raspberry Pi 3. - -If you need to maintain backwards compatibility with prior releases of -Qt, chose `QMapboxGL`. Otherwise, go for `QQuickMapboxGL`. - -Both `QMapboxGL` and `QQuickMapboxGL` requires a [Mapbox access -token](https://www.mapbox.com/help/define-access-token/) at runtime - you need -to provide it by setting the environment variable `MAPBOX_ACCESS_TOKEN`: - - export MAPBOX_ACCESS_TOKEN=MYTOKEN - -Optionally, you can specify a custom style to the QMapboxGL example application: - - export MAPBOX_STYLE_URL=MYSTYLEURL - -#### Using QMapboxGL - -`QMapboxGL` is a [QObject](http://doc.qt.io/qt-5/qobject.html) - [MapWindow](https://github.com/mapbox/mapbox-gl-native/blob/master/platform/qt/app/mapwindow.hpp) provides an example [QGLWidget](http://doc.qt.io/qt-5/qglwidget.html) that contains a `QMapboxGL` object. If you use `QMapboxGL` in non-standard Qt widgets, make sure to initialize the GL extensions required by Mapbox whenever possible: - - QMapbox::initializeGLExtensions(); +This is the foundation for the Mapbox GL plugin available since Qt 5.9. Use the Qt bugtracker +for bugs related to the plugin and this GitHub repository for bugs related to Mapbox GL Native. #### Linux @@ -47,9 +14,7 @@ For Linux (Ubuntu) desktop, together with these [build instructions](https://github.com/mapbox/mapbox-gl-native/tree/master/platform/linux#build), you also need: - sudo apt-get install qt5-default qtlocation5-dev qtpositioning5-dev \ - qml-module-qtquick2 qml-module-qtpositioning qml-module-qtgraphicaleffects \ - qml-module-qtquick-layouts qml-module-qtquick-controls + sudo apt-get install qt5-default #### macOS @@ -74,8 +39,3 @@ can be found in [platform/qt/include](https://github.com/mapbox/mapbox-gl-native ```make qt-app``` or ```make run-qt-app``` to run the application at the end of build. - -#### QQuickMapboxGL example application: - -```make qt-qml-app``` or ```make run-qt-qml-app``` to run the application at the -end of build. diff --git a/platform/qt/bitrise-qt5.yml b/platform/qt/bitrise-qt5.yml index e0627f03e5..036ec044c5 100644 --- a/platform/qt/bitrise-qt5.yml +++ b/platform/qt/bitrise-qt5.yml @@ -39,7 +39,6 @@ workflows: ln -s /usr/local/Cellar/qt5/$HOMEBREW_QT5_VERSION/plugins /usr/local/plugins export BUILDTYPE=Debug make qt-app - make qt-qml-app make run-qt-test - is_debug: 'yes' - deploy-to-bitrise-io: diff --git a/platform/qt/include/qquickmapboxgl.hpp b/platform/qt/include/qquickmapboxgl.hpp deleted file mode 100644 index 39b4395bd6..0000000000 --- a/platform/qt/include/qquickmapboxgl.hpp +++ /dev/null @@ -1,176 +0,0 @@ -#pragma once - -#include "qmapbox.hpp" -#include "qmapboxgl.hpp" -#include "qquickmapboxglmapparameter.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class QDeclarativeGeoServiceProvider; -class QQuickMapboxGLRenderer; - -class Q_DECL_EXPORT QQuickMapboxGL : public QQuickFramebufferObject -{ - Q_OBJECT - - // Map QML Type interface. - Q_ENUMS(QGeoServiceProvider::Error) - Q_PROPERTY(QDeclarativeGeoServiceProvider *plugin READ plugin WRITE setPlugin NOTIFY pluginChanged) - Q_PROPERTY(qreal minimumZoomLevel READ minimumZoomLevel WRITE setMinimumZoomLevel NOTIFY minimumZoomLevelChanged) - Q_PROPERTY(qreal maximumZoomLevel READ maximumZoomLevel WRITE setMaximumZoomLevel NOTIFY maximumZoomLevelChanged) - Q_PROPERTY(qreal zoomLevel READ zoomLevel WRITE setZoomLevel NOTIFY zoomLevelChanged) - Q_PROPERTY(QGeoCoordinate center READ center WRITE setCenter NOTIFY centerChanged) - Q_PROPERTY(QGeoServiceProvider::Error error READ error NOTIFY errorChanged) - Q_PROPERTY(QString errorString READ errorString NOTIFY errorChanged) - Q_PROPERTY(QGeoShape visibleRegion READ visibleRegion WRITE setVisibleRegion) - Q_PROPERTY(bool copyrightsVisible READ copyrightsVisible WRITE setCopyrightsVisible NOTIFY copyrightsVisibleChanged) - Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) - - // Proposed Qt interface - based on the example documentation below: - // http://doc.qt.io/qt-5/qtqml-referenceexamples-properties-example.html - Q_PROPERTY(QQmlListProperty parameters READ parameters) - -public: - QQuickMapboxGL(QQuickItem *parent = 0); - virtual ~QQuickMapboxGL(); - - // QQuickFramebufferObject implementation. - virtual Renderer *createRenderer() const Q_DECL_FINAL; - - // Map QML Type interface implementation. - void setPlugin(QDeclarativeGeoServiceProvider *plugin); - QDeclarativeGeoServiceProvider *plugin() const; - - void setMinimumZoomLevel(qreal minimumZoomLevel); - qreal minimumZoomLevel() const; - - void setMaximumZoomLevel(qreal maximumZoomLevel); - qreal maximumZoomLevel() const; - - void setZoomLevel(qreal zoomLevel); - qreal zoomLevel() const; - - QGeoCoordinate center() const; - - QGeoServiceProvider::Error error() const; - QString errorString() const; - - void setVisibleRegion(const QGeoShape &shape); - QGeoShape visibleRegion() const; - - void setCopyrightsVisible(bool visible); - bool copyrightsVisible() const; - - void setColor(const QColor &color); - QColor color() const; - - Q_INVOKABLE void pan(int dx, int dy); - - // Proposed Qt interface implementation. - QQmlListProperty parameters(); - -protected: - // QQmlParserStatus implementation - void componentComplete() override; - -signals: - // Map QML Type signals. - void minimumZoomLevelChanged(); - void maximumZoomLevelChanged(); - void zoomLevelChanged(qreal zoomLevel); - void centerChanged(const QGeoCoordinate &coordinate); - void colorChanged(const QColor &color); - void errorChanged(); - - // Compatibility with Map QML Type, but no-op. - void pluginChanged(QDeclarativeGeoServiceProvider *plugin); - void copyrightLinkActivated(const QString &link); - void copyrightsVisibleChanged(bool visible); - -public slots: - void setCenter(const QGeoCoordinate ¢er); - -private slots: - void onMapChanged(QMapboxGL::MapChange); - void onParameterPropertyUpdated(const QString &name); - -private: - static void appendParameter(QQmlListProperty *prop, QQuickMapboxGLMapParameter *mapObject); - static int countParameters(QQmlListProperty *prop); - static QQuickMapboxGLMapParameter *parameterAt(QQmlListProperty *prop, int index); - static void clearParameter(QQmlListProperty *prop); - - enum SyncState { - NothingNeedsSync = 0, - ZoomNeedsSync = 1 << 0, - CenterNeedsSync = 1 << 1, - StyleNeedsSync = 1 << 2, - PanNeedsSync = 1 << 3, - BearingNeedsSync = 1 << 4, - PitchNeedsSync = 1 << 5, - }; - - struct Image { - QString name; - QImage sprite; - }; - - struct StyleProperty { - enum Type { - Paint = 0, - Layout - }; - - Type type; - QString layer; - QString property; - QVariant value; - QString klass; - }; - - void processMapParameter(QQuickMapboxGLMapParameter *); - bool parseImage(QQuickMapboxGLMapParameter *); - bool parseStyle(QQuickMapboxGLMapParameter *); - bool parseStyleProperty(QQuickMapboxGLMapParameter *, const QString &name); - bool parseStyleLayer(QQuickMapboxGLMapParameter *); - bool parseStyleSource(QQuickMapboxGLMapParameter *); - bool parseStyleFilter(QQuickMapboxGLMapParameter *); - bool parseBearing(QQuickMapboxGLMapParameter *); - bool parsePitch(QQuickMapboxGLMapParameter *); - - qreal m_minimumZoomLevel = 0; - qreal m_maximumZoomLevel = 20; - qreal m_zoomLevel = 20; - - QPointF m_pan; - - QGeoCoordinate m_center; - QGeoShape m_visibleRegion; - QColor m_color; - QString m_styleUrl; - QList m_imageChanges; - QList m_stylePropertyChanges; - QList m_layerChanges; - QList m_sourceChanges; - QList m_filterChanges; - QList m_parameters; - - QGeoServiceProvider::Error m_error = QGeoServiceProvider::NoError; - QString m_errorString; - - qreal m_bearing = 0; - qreal m_pitch = 0; - - int m_syncState = NothingNeedsSync; - bool m_styleLoaded = false; - - friend class QQuickMapboxGLRenderer; -}; diff --git a/platform/qt/include/qquickmapboxglmapparameter.hpp b/platform/qt/include/qquickmapboxglmapparameter.hpp deleted file mode 100644 index 1dca0cf55d..0000000000 --- a/platform/qt/include/qquickmapboxglmapparameter.hpp +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -class Q_DECL_EXPORT QQuickMapboxGLMapParameter : public QObject, public QQmlParserStatus -{ - Q_OBJECT - Q_INTERFACES(QQmlParserStatus) - -public: - QQuickMapboxGLMapParameter(QObject *parent = 0); - virtual ~QQuickMapboxGLMapParameter() {}; - - int propertyOffset() const { return m_metaPropertyOffset; } - -signals: - void propertyUpdated(const QString &name); - -protected: - // QQmlParserStatus implementation - void classBegin() override {} - void componentComplete() override; - -private slots: - void onPropertyUpdated(int index); - -private: - int m_metaPropertyOffset; -}; - -QML_DECLARE_TYPE(QQuickMapboxGLMapParameter) diff --git a/platform/qt/qmlapp/main.cpp b/platform/qt/qmlapp/main.cpp deleted file mode 100644 index 8606704002..0000000000 --- a/platform/qt/qmlapp/main.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include - -#include -#include -#include -#include - -int main(int argc, char *argv[]) -{ - QGuiApplication app(argc, argv); - -#if QT_VERSION >= 0x050300 - app.setWindowIcon(QIcon(":icon.png")); -#endif - - qmlRegisterType("QQuickMapboxGL", 1, 0, "MapboxMap"); - qmlRegisterType("QQuickMapboxGL", 1, 0, "MapParameter"); - - QQmlApplicationEngine engine; - engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); - - return app.exec(); -} diff --git a/platform/qt/qmlapp/main.qml b/platform/qt/qmlapp/main.qml deleted file mode 100644 index fd62193b42..0000000000 --- a/platform/qt/qmlapp/main.qml +++ /dev/null @@ -1,347 +0,0 @@ -import QtGraphicalEffects 1.0 -import QtPositioning 5.0 -import QtQuick 2.0 -import QtQuick.Controls 1.0 -import QtQuick.Dialogs 1.0 -import QtQuick.Layouts 1.0 - -import QQuickMapboxGL 1.0 - -ApplicationWindow { - title: "Mapbox GL QML example" - width: 1024 - height: 768 - visible: true - - MapboxMap { - id: map - anchors.fill: parent - - parameters: [ - MapParameter { - id: style - property var type: "style" - property var url: "mapbox://styles/mapbox/streets-v9" - }, - MapParameter { - id: waterPaint - property var type: "paint" - property var layer: "water" - property var fillColor: waterColorDialog.color - }, - MapParameter { - id: source - property var type: "source" - property var name: "routeSource" - property var sourceType: "geojson" - property var data: ":source1.geojson" - }, - MapParameter { - property var type: "layer" - property var name: "routeCase" - property var layerType: "line" - property var source: "routeSource" - }, - MapParameter { - property var type: "paint" - property var layer: "routeCase" - property var lineColor: "white" - property var lineWidth: 20.0 - }, - MapParameter { - property var type: "layout" - property var layer: "routeCase" - property var lineJoin: "round" - property var lineCap: lineJoin - property var visibility: toggleRoute.checked ? "visible" : "none" - }, - MapParameter { - property var type: "layer" - property var name: "route" - property var layerType: "line" - property var source: "routeSource" - }, - MapParameter { - id: linePaint - property var type: "paint" - property var layer: "route" - property var lineColor: "blue" - property var lineWidth: 8.0 - }, - MapParameter { - property var type: "layout" - property var layer: "route" - property var lineJoin: "round" - property var lineCap: "round" - property var visibility: toggleRoute.checked ? "visible" : "none" - }, - MapParameter { - property var type: "image" - property var name: "label-arrow" - property var sprite: ":label-arrow.svg" - }, - MapParameter { - property var type: "image" - property var name: "label-background" - property var sprite: ":label-background.svg" - }, - MapParameter { - property var type: "layer" - property var name: "markerArrow" - property var layerType: "symbol" - property var source: "routeSource" - }, - MapParameter { - property var type: "layout" - property var layer: "markerArrow" - property var iconImage: "label-arrow" - property var iconSize: 0.5 - property var iconIgnorePlacement: true - property var iconOffset: [ 0.0, -15.0 ] - property var visibility: toggleRoute.checked ? "visible" : "none" - }, - MapParameter { - property var type: "layer" - property var name: "markerBackground" - property var layerType: "symbol" - property var source: "routeSource" - }, - MapParameter { - property var type: "layout" - property var layer: "markerBackground" - property var iconImage: "label-background" - property var textField: "{name}" - property var iconTextFit: "both" - property var iconIgnorePlacement: true - property var textIgnorePlacement: true - property var textAnchor: "left" - property var textSize: 16.0 - property var textPadding: 0.0 - property var textLineHeight: 1.0 - property var textMaxWidth: 8.0 - property var iconTextFitPadding: [ 15.0, 10.0, 15.0, 10.0 ] - property var textOffset: [ -0.5, -1.5 ] - property var visibility: toggleRoute.checked ? "visible" : "none" - }, - MapParameter { - property var type: "paint" - property var layer: "markerBackground" - property var textColor: "white" - }, - MapParameter { - property var type: "filter" - property var layer: "markerArrow" - property var filter: [ "==", "$type", "Point" ] - }, - MapParameter { - property var type: "filter" - property var layer: "markerBackground" - property var filter: [ "==", "$type", "Point" ] - }, - MapParameter { - property var type: "bearing" - property var angle: bearingSlider.value - }, - MapParameter { - property var type: "pitch" - property var angle: pitchSlider.value - } - ] - - center: QtPositioning.coordinate(60.170448, 24.942046) // Helsinki - zoomLevel: 12.25 - minimumZoomLevel: 0 - maximumZoomLevel: 20 - - color: landColorDialog.color - copyrightsVisible: true - - states: State { - name: "moved"; when: mouseArea.pressed - PropertyChanges { target: linePaint; lineColor: "red"; } - } - - transitions: Transition { - ColorAnimation { properties: "lineColor"; easing.type: Easing.InOutQuad; duration: 500 } - } - - Image { - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.margins: 20 - - opacity: .75 - - sourceSize.width: 80 - sourceSize.height: 80 - - source: "icon.png" - } - - MouseArea { - id: mouseArea - anchors.fill: parent - - property var lastX: 0 - property var lastY: 0 - - onWheel: map.zoomLevel += 0.2 * wheel.angleDelta.y / 120 - - onPressed: { - lastX = mouse.x - lastY = mouse.y - } - - onPositionChanged: { - map.pan(mouse.x - lastX, mouse.y - lastY) - - lastX = mouse.x - lastY = mouse.y - } - } - } - - ColorDialog { - id: landColorDialog - title: "Land color" - color: "#e0ded8" - } - - ColorDialog { - id: waterColorDialog - title: "Water color" - color: "#63c5ee" - } - - Rectangle { - anchors.fill: menu - anchors.margins: -20 - radius: 30 - clip: true - } - - ColumnLayout { - id: menu - - anchors.right: parent.right - anchors.top: parent.top - anchors.margins: 30 - - Label { - text: "Bearing:" - } - - Slider { - id: bearingSlider - - anchors.left: parent.left - anchors.right: parent.right - maximumValue: 180 - } - - Label { - text: "Pitch:" - } - - Slider { - id: pitchSlider - - anchors.left: parent.left - anchors.right: parent.right - maximumValue: 60 - } - - GroupBox { - anchors.left: parent.left - anchors.right: parent.right - title: "Style:" - - ColumnLayout { - ExclusiveGroup { id: styleGroup } - RadioButton { - text: "Streets" - checked: true - exclusiveGroup: styleGroup - onClicked: { - style.url = "mapbox://styles/mapbox/streets-v9" - landColorDialog.color = "#e0ded8" - waterColorDialog.color = "#63c5ee" - } - } - RadioButton { - text: "Dark" - exclusiveGroup: styleGroup - onClicked: { - style.url = "mapbox://styles/mapbox/dark-v9" - landColorDialog.color = "#343332" - waterColorDialog.color = "#191a1a" - } - } - RadioButton { - text: "Satellite" - exclusiveGroup: styleGroup - onClicked: { - style.url = "mapbox://styles/mapbox/satellite-v9" - } - } - } - } - - Button { - anchors.left: parent.left - anchors.right: parent.right - text: "Select land color" - onClicked: landColorDialog.open() - } - - Button { - anchors.left: parent.left - anchors.right: parent.right - text: "Select water color" - 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 - anchors.right: parent.right - text: "Toggle route" - checked: true - } - } -} diff --git a/platform/qt/qmlapp/qml.qrc b/platform/qt/qmlapp/qml.qrc deleted file mode 100644 index 5f6483ac33..0000000000 --- a/platform/qt/qmlapp/qml.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - main.qml - - diff --git a/platform/qt/qt5.cmake b/platform/qt/qt5.cmake index 9a482f6d30..ed51051311 100644 --- a/platform/qt/qt5.cmake +++ b/platform/qt/qt5.cmake @@ -3,7 +3,6 @@ find_package(Qt5Gui REQUIRED) find_package(Qt5Location REQUIRED) find_package(Qt5Network REQUIRED) find_package(Qt5OpenGL REQUIRED) -find_package(Qt5Quick REQUIRED) find_package(Qt5Widgets REQUIRED) find_package(Qt5Sql REQUIRED) @@ -21,21 +20,11 @@ set(MBGL_QT_TEST_LIBRARIES PRIVATE Qt5::OpenGL ) -target_sources(qmapboxgl - PRIVATE platform/qt/include/qquickmapboxgl.hpp - PRIVATE platform/qt/include/qquickmapboxglmapparameter.hpp - PRIVATE platform/qt/src/qquickmapboxgl.cpp - PRIVATE platform/qt/src/qquickmapboxglmapparameter.cpp - PRIVATE platform/qt/src/qquickmapboxglrenderer.cpp - PRIVATE platform/qt/src/qquickmapboxglrenderer.hpp -) - target_link_libraries(qmapboxgl PRIVATE mbgl-core PRIVATE Qt5::Core PRIVATE Qt5::Gui PRIVATE Qt5::Location - PRIVATE Qt5::Quick PRIVATE Qt5::Sql ) @@ -44,16 +33,3 @@ target_link_libraries(mbgl-qt PRIVATE Qt5::OpenGL PRIVATE Qt5::Widgets ) - -# QtQuick app -add_executable(mbgl-qt-qml - platform/qt/qmlapp/main.cpp - platform/qt/qmlapp/qml.qrc - platform/qt/resources/common.qrc -) - -target_link_libraries(mbgl-qt-qml - PRIVATE qmapboxgl - PRIVATE Qt5::Location - PRIVATE Qt5::Quick -) diff --git a/platform/qt/src/qquickmapboxgl.cpp b/platform/qt/src/qquickmapboxgl.cpp deleted file mode 100644 index 7325bfe3c2..0000000000 --- a/platform/qt/src/qquickmapboxgl.cpp +++ /dev/null @@ -1,469 +0,0 @@ -#include "qquickmapboxgl.hpp" - -#include "qquickmapboxglmapparameter.hpp" -#include "qquickmapboxglrenderer.hpp" - -#include - -#include -#include -#include -#include -#include -#include -#include - -namespace { - -static const QRegularExpression s_camelCase {"([a-z0-9])([A-Z])"}; -static const QStringList s_parameterTypes = QStringList() - << "style" << "paint" << "layout" << "layer" << "source" << "filter" << "image" - << "bearing" << "pitch"; - -} // namespace - -QQuickMapboxGL::QQuickMapboxGL(QQuickItem *parent_) - : QQuickFramebufferObject(parent_) -{ -} - -QQuickMapboxGL::~QQuickMapboxGL() -{ -} - -QQuickFramebufferObject::Renderer *QQuickMapboxGL::createRenderer() const -{ - return new QQuickMapboxGLRenderer; -} - -void QQuickMapboxGL::setPlugin(QDeclarativeGeoServiceProvider *) -{ - m_error = QGeoServiceProvider::NotSupportedError; - m_errorString = "QQuickMapboxGL does not support plugins."; - emit errorChanged(); -} - -QDeclarativeGeoServiceProvider *QQuickMapboxGL::plugin() const -{ - return nullptr; -} - -void QQuickMapboxGL::componentComplete() -{ - QQuickFramebufferObject::componentComplete(); - - for (const auto& param : m_parameters) { - processMapParameter(param); - } -} - -void QQuickMapboxGL::setMinimumZoomLevel(qreal zoom) -{ - zoom = qMax(mbgl::util::MIN_ZOOM, zoom); - zoom = qMin(m_maximumZoomLevel, zoom); - - if (m_minimumZoomLevel == zoom) { - return; - } - - m_minimumZoomLevel = zoom; - setZoomLevel(m_zoomLevel); // Constrain. - - emit minimumZoomLevelChanged(); -} - -qreal QQuickMapboxGL::minimumZoomLevel() const -{ - return m_minimumZoomLevel; -} - -void QQuickMapboxGL::setMaximumZoomLevel(qreal zoom) -{ - zoom = qMin(mbgl::util::MAX_ZOOM, zoom); - zoom = qMax(m_minimumZoomLevel, zoom); - - if (m_maximumZoomLevel == zoom) { - return; - } - - m_maximumZoomLevel = zoom; - setZoomLevel(m_zoomLevel); // Constrain. - - emit maximumZoomLevelChanged(); -} - -qreal QQuickMapboxGL::maximumZoomLevel() const -{ - return m_maximumZoomLevel; -} - -void QQuickMapboxGL::setZoomLevel(qreal zoom) -{ - zoom = qMin(m_maximumZoomLevel, zoom); - zoom = qMax(m_minimumZoomLevel, zoom); - - if (m_zoomLevel == zoom) { - return; - } - - m_zoomLevel = zoom; - - m_syncState |= ZoomNeedsSync; - update(); - - emit zoomLevelChanged(m_zoomLevel); -} - -qreal QQuickMapboxGL::zoomLevel() const -{ - return m_zoomLevel; -} - -void QQuickMapboxGL::setCenter(const QGeoCoordinate &coordinate) -{ - if (m_center == coordinate) { - return; - } - - m_center = coordinate; - - m_syncState |= CenterNeedsSync; - update(); - - emit centerChanged(m_center); -} - -QGeoCoordinate QQuickMapboxGL::center() const -{ - return m_center; -} - -QGeoServiceProvider::Error QQuickMapboxGL::error() const -{ - return m_error; -} - -QString QQuickMapboxGL::errorString() const -{ - return m_errorString; -} - -void QQuickMapboxGL::setVisibleRegion(const QGeoShape &shape) -{ - m_visibleRegion = shape; -} - -QGeoShape QQuickMapboxGL::visibleRegion() const -{ - return m_visibleRegion; -} - -void QQuickMapboxGL::setCopyrightsVisible(bool) -{ - qWarning() << Q_FUNC_INFO << "Not implemented."; -} - -bool QQuickMapboxGL::copyrightsVisible() const -{ - return false; -} - -void QQuickMapboxGL::setColor(const QColor &color) -{ - if (m_color == color) { - return; - } - - m_color = color; - - StyleProperty change; - change.type = StyleProperty::Paint; - change.layer = "background"; - change.property = "background-color"; - change.value = color; - m_stylePropertyChanges << change; - - update(); - - emit colorChanged(m_color); -} - -QColor QQuickMapboxGL::color() const -{ - return m_color; -} - -void QQuickMapboxGL::pan(int dx, int dy) -{ - m_pan += QPointF(dx, -dy); - - m_syncState |= PanNeedsSync; - update(); -} - -void QQuickMapboxGL::onMapChanged(QMapboxGL::MapChange change) -{ - if (change == QMapboxGL::MapChangeDidFinishLoadingStyle) { - m_styleLoaded = true; - update(); - } -} - -bool QQuickMapboxGL::parseImage(QQuickMapboxGLMapParameter *param) -{ - m_imageChanges << Image { - param->property("name").toString(), - QImage(param->property("sprite").toString()) - }; - return true; -} - -bool QQuickMapboxGL::parseStyle(QQuickMapboxGLMapParameter *param) -{ - QString url = param->property("url").toString(); - if (m_styleUrl == url) { - return false; - } - - // Reload parameters if switching style URLs. - if (!m_styleUrl.isEmpty()) { - for (const auto& param_ : m_parameters) { - if (param_->property("type").toString() == "style") continue; - processMapParameter(param_); - } - } - - m_styleUrl = url; - m_styleLoaded = false; - m_syncState |= StyleNeedsSync; - - return true; -} - -bool QQuickMapboxGL::parseStyleProperty(QQuickMapboxGLMapParameter *param, const QString &name) -{ - // Ignore meta-properties "type", "layer" and "class". - if (name == "type" || name == "layer" || name == "class") { - return false; - } - - QString formattedName(name); - formattedName = formattedName.replace(s_camelCase, "\\1-\\2").toLower(); - - QVariant value = param->property(name.toLatin1()); - if (value.canConvert()) { - value = value.value().toVariant(); - } - - m_stylePropertyChanges << QQuickMapboxGL::StyleProperty { - param->property("type").toString().at(0) == 'p' ? StyleProperty::Paint : StyleProperty::Layout, - param->property("layer").toString(), - formattedName, - value, - param->property("class").toString() - }; - return true; -} - -bool QQuickMapboxGL::parseStyleLayer(QQuickMapboxGLMapParameter *param) -{ - QVariantMap layer; - layer["id"] = param->property("name"); - layer["source"] = param->property("source"); - layer["type"] = param->property("layerType"); - if (param->property("sourceLayer").isValid()) { - layer["source-layer"] = param->property("sourceLayer"); - } - m_layerChanges << layer; - return true; -} - -bool QQuickMapboxGL::parseStyleSource(QQuickMapboxGLMapParameter *param) -{ - QString sourceType = param->property("sourceType").toString(); - - QVariantMap source; - source["id"] = param->property("name"); - source["type"] = sourceType; - if (sourceType == "vector" || sourceType == "raster") { - source["url"] = param->property("url"); - m_sourceChanges << source; - } else if (sourceType == "geojson") { - 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; - m_errorString = "Invalid source type: " + sourceType; - emit errorChanged(); - return false; - } - return true; -} - -bool QQuickMapboxGL::parseStyleFilter(QQuickMapboxGLMapParameter *param) -{ - QVariantMap filter; - filter["layer"] = param->property("layer"); - filter["filter"] = param->property("filter"); - m_filterChanges << filter; - return true; -} - -bool QQuickMapboxGL::parseBearing(QQuickMapboxGLMapParameter *param) -{ - qreal angle = param->property("angle").toReal(); - if (m_bearing == angle) return false; - m_bearing = angle; - m_syncState |= BearingNeedsSync; - update(); - return true; -} - -bool QQuickMapboxGL::parsePitch(QQuickMapboxGLMapParameter *param) -{ - qreal angle = param->property("angle").toReal(); - angle = qMin(qMax(0., angle), mbgl::util::PITCH_MAX * mbgl::util::RAD2DEG); - if (m_pitch == angle) return false; - m_pitch = angle; - m_syncState |= PitchNeedsSync; - update(); - return true; -} - -void QQuickMapboxGL::processMapParameter(QQuickMapboxGLMapParameter *param) -{ - bool needsUpdate = false; - switch (s_parameterTypes.indexOf(param->property("type").toString())) { - case -1: - m_error = QGeoServiceProvider::UnknownParameterError; - m_errorString = "Invalid value for property 'type': " + param->property("type").toString(); - emit errorChanged(); - break; - case 0: // style - needsUpdate |= parseStyle(param); - break; - case 1: // paint - case 2: // layout - for (int i = param->propertyOffset(); i < param->metaObject()->propertyCount(); ++i) { - needsUpdate |= parseStyleProperty(param, QString(param->metaObject()->property(i).name())); - } - break; - case 3: // layer - needsUpdate |= parseStyleLayer(param); - break; - case 4: // source - needsUpdate |= parseStyleSource(param); - break; - case 5: // filter - needsUpdate |= parseStyleFilter(param); - break; - case 6: // image - needsUpdate |= parseImage(param); - break; - case 7: // bearing - needsUpdate |= parseBearing(param); - break; - case 8: // pitch - needsUpdate |= parsePitch(param); - break; - } - if (needsUpdate) update(); -} - -void QQuickMapboxGL::onParameterPropertyUpdated(const QString &propertyName) -{ - QQuickMapboxGLMapParameter *param = qobject_cast(sender()); - if (!param) { - m_error = QGeoServiceProvider::NotSupportedError; - m_errorString = "QQuickMapboxGL::onParameterPropertyUpdated should be called from a QQuickMapboxGLMapParameter."; - emit errorChanged(); - return; - } - - if (propertyName == "type") { - m_error = QGeoServiceProvider::NotSupportedError; - m_errorString = "Property 'type' is a write-once."; - emit errorChanged(); - return; - } - - bool needsUpdate = false; - switch (s_parameterTypes.indexOf(param->property("type").toString())) { - case -1: - m_error = QGeoServiceProvider::UnknownParameterError; - m_errorString = "Invalid value for property 'type': " + param->property("type").toString(); - emit errorChanged(); - break; - case 0: // style - needsUpdate |= parseStyle(param); - break; - case 1: // paint - case 2: // layout - needsUpdate |= parseStyleProperty(param, propertyName); - break; - case 3: // layer - needsUpdate |= parseStyleLayer(param); - break; - case 4: // source - needsUpdate |= parseStyleSource(param); - break; - case 5: // filter - needsUpdate |= parseStyleFilter(param); - break; - case 6: // image - needsUpdate |= parseImage(param); - break; - case 7: // bearing - needsUpdate |= parseBearing(param); - break; - case 8: // pitch - needsUpdate |= parsePitch(param); - break; - } - if (needsUpdate) update(); -} - -void QQuickMapboxGL::appendParameter(QQmlListProperty *prop, QQuickMapboxGLMapParameter *param) -{ - QQuickMapboxGL *map = static_cast(prop->object); - map->m_parameters.append(param); - QObject::connect(param, SIGNAL(propertyUpdated(QString)), map, SLOT(onParameterPropertyUpdated(QString))); -} - -int QQuickMapboxGL::countParameters(QQmlListProperty *prop) -{ - QQuickMapboxGL *map = static_cast(prop->object); - return map->m_parameters.count(); -} - -QQuickMapboxGLMapParameter *QQuickMapboxGL::parameterAt(QQmlListProperty *prop, int index) -{ - QQuickMapboxGL *map = static_cast(prop->object); - return map->m_parameters[index]; -} - -void QQuickMapboxGL::clearParameter(QQmlListProperty *prop) -{ - QQuickMapboxGL *map = static_cast(prop->object); - for (auto param : map->m_parameters) { - QObject::disconnect(param, SIGNAL(propertyUpdated(QString)), map, SLOT(onParameterPropertyUpdated(QString))); - } - map->m_parameters.clear(); -} - -QQmlListProperty QQuickMapboxGL::parameters() -{ - return QQmlListProperty(this, - nullptr, - appendParameter, - countParameters, - parameterAt, - clearParameter); -} diff --git a/platform/qt/src/qquickmapboxglmapparameter.cpp b/platform/qt/src/qquickmapboxglmapparameter.cpp deleted file mode 100644 index abf6e5ff1c..0000000000 --- a/platform/qt/src/qquickmapboxglmapparameter.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "qquickmapboxglmapparameter.hpp" - -#include -#include -#include -#include - -QQuickMapboxGLMapParameter::QQuickMapboxGLMapParameter(QObject *parent) - : QObject(parent) - , m_metaPropertyOffset(metaObject()->propertyCount()) -{ -} - -void QQuickMapboxGLMapParameter::componentComplete() -{ - for (int i = m_metaPropertyOffset; i < metaObject()->propertyCount(); ++i) { - QMetaProperty property = metaObject()->property(i); - - if (!property.hasNotifySignal()) { - return; - } - - auto mapper = new QSignalMapper(this); - mapper->setMapping(this, i); - - const QByteArray signalName = '2' + property.notifySignal().methodSignature(); - QObject::connect(this, signalName, mapper, SLOT(map())); - QObject::connect(mapper, SIGNAL(mapped(int)), this, SLOT(onPropertyUpdated(int))); - } -} - -void QQuickMapboxGLMapParameter::onPropertyUpdated(int index) -{ - emit propertyUpdated(metaObject()->property(index).name()); -} diff --git a/platform/qt/src/qquickmapboxglrenderer.cpp b/platform/qt/src/qquickmapboxglrenderer.cpp deleted file mode 100644 index 133bed40e2..0000000000 --- a/platform/qt/src/qquickmapboxglrenderer.cpp +++ /dev/null @@ -1,120 +0,0 @@ -#include "qquickmapboxglrenderer.hpp" - -#include "qmapboxgl.hpp" -#include "qquickmapboxgl.hpp" - -#include -#include -#include -#include -#include - -QQuickMapboxGLRenderer::QQuickMapboxGLRenderer() -{ - QMapbox::initializeGLExtensions(); - - QMapboxGLSettings settings; - settings.setAccessToken(qgetenv("MAPBOX_ACCESS_TOKEN")); - settings.setCacheDatabasePath("/tmp/mbgl-cache.db"); - settings.setCacheDatabaseMaximumSize(20 * 1024 * 1024); - settings.setViewportMode(QMapboxGLSettings::FlippedYViewport); - - m_map.reset(new QMapboxGL(nullptr, settings, QSize(256, 256), 1)); -} - -QQuickMapboxGLRenderer::~QQuickMapboxGLRenderer() -{ -} - -QOpenGLFramebufferObject* QQuickMapboxGLRenderer::createFramebufferObject(const QSize &size) -{ - m_map->resize(size / m_pixelRatio, size); - - QOpenGLFramebufferObjectFormat format; - format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); - - return new QOpenGLFramebufferObject(size, format); -} - -void QQuickMapboxGLRenderer::render() -{ - framebufferObject()->bind(); - m_map->render(); - framebufferObject()->release(); -} - -void QQuickMapboxGLRenderer::synchronize(QQuickFramebufferObject *item) -{ - auto quickMap = qobject_cast(item); - if (!m_initialized) { - QObject::connect(m_map.data(), &QMapboxGL::needsRendering, quickMap, &QQuickMapboxGL::update); - QObject::connect(m_map.data(), SIGNAL(mapChanged(QMapboxGL::MapChange)), quickMap, SLOT(onMapChanged(QMapboxGL::MapChange))); - QObject::connect(this, &QQuickMapboxGLRenderer::centerChanged, quickMap, &QQuickMapboxGL::setCenter); - m_initialized = true; - } - - if (auto window = quickMap->window()) { - m_pixelRatio = window->devicePixelRatio(); - } else { - m_pixelRatio = 1; - } - - auto syncStatus = quickMap->m_syncState; - quickMap->m_syncState = QQuickMapboxGL::NothingNeedsSync; - - if (syncStatus & QQuickMapboxGL::CenterNeedsSync || syncStatus & QQuickMapboxGL::ZoomNeedsSync) { - const auto& center = quickMap->center(); - m_map->setCoordinateZoom({ center.latitude(), center.longitude() }, quickMap->zoomLevel()); - } - - if (syncStatus & QQuickMapboxGL::StyleNeedsSync && !quickMap->m_styleUrl.isEmpty()) { - m_map->setStyleUrl(quickMap->m_styleUrl); - } - - if (syncStatus & QQuickMapboxGL::PanNeedsSync) { - m_map->moveBy(quickMap->m_pan); - quickMap->m_pan = QPointF(); - emit centerChanged(QGeoCoordinate(m_map->latitude(), m_map->longitude())); - } - - if (syncStatus & QQuickMapboxGL::BearingNeedsSync) { - m_map->setBearing(quickMap->m_bearing); - } - - if (syncStatus & QQuickMapboxGL::PitchNeedsSync) { - m_map->setPitch(quickMap->m_pitch); - } - - if (!quickMap->m_styleLoaded) { - return; - } - - for (const auto& change : quickMap->m_sourceChanges) { - m_map->updateSource(change.value("id").toString(), change); - } - quickMap->m_sourceChanges.clear(); - - for (const auto& change : quickMap->m_layerChanges) { - m_map->addLayer(change); - } - quickMap->m_layerChanges.clear(); - - for (const auto& change : quickMap->m_filterChanges) { - m_map->setFilter(change.value("layer").toString(), change.value("filter")); - } - quickMap->m_filterChanges.clear(); - - for (const auto& change : quickMap->m_imageChanges) { - m_map->addImage(change.name, change.sprite); - } - quickMap->m_imageChanges.clear(); - - for (const auto& change : quickMap->m_stylePropertyChanges) { - if (change.type == QQuickMapboxGL::StyleProperty::Paint) { - m_map->setPaintProperty(change.layer, change.property, change.value, change.klass); - } else { - m_map->setLayoutProperty(change.layer, change.property, change.value); - } - } - quickMap->m_stylePropertyChanges.clear(); -} diff --git a/platform/qt/src/qquickmapboxglrenderer.hpp b/platform/qt/src/qquickmapboxglrenderer.hpp deleted file mode 100644 index 1fb7a50f4a..0000000000 --- a/platform/qt/src/qquickmapboxglrenderer.hpp +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include "qmapbox.hpp" -#include "qmapboxgl.hpp" - -#include -#include -#include -#include -#include -#include - -class QQuickMapboxGLRenderer : public QObject, public QQuickFramebufferObject::Renderer -{ - Q_OBJECT - -public: - QQuickMapboxGLRenderer(); - virtual ~QQuickMapboxGLRenderer(); - - virtual QOpenGLFramebufferObject * createFramebufferObject(const QSize &); - - virtual void render(); - virtual void synchronize(QQuickFramebufferObject *); - -signals: - void centerChanged(const QGeoCoordinate &); - -private: - bool m_initialized = false; - qreal m_pixelRatio = 1; - - QScopedPointer m_map; -}; -- cgit v1.2.1 From 84f69bfcc0e276a2dc3fd515a2425069dd47f442 Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Mon, 6 Mar 2017 11:56:59 -0800 Subject: Update README.md Fix patch typo. --- platform/qt/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/qt/README.md b/platform/qt/README.md index 22c06310c3..0123e3bda0 100644 --- a/platform/qt/README.md +++ b/platform/qt/README.md @@ -24,7 +24,7 @@ For macOS desktop, you can install Qt 5 via [Homebrew](http://brew.sh): Since Homebrew doesn't add Qt to the path, you'll have to do that manually before running any Make target: - export PATH=/usr/local/opt/qt5:$PATH + export PATH=/usr/local/opt/qt5/bin:$PATH We provide the following build targets for our Qt SDK: -- cgit v1.2.1 From 0da6d8a646746831819525fd37cff3ed0af9589b Mon Sep 17 00:00:00 2001 From: Ivo van Dongen Date: Mon, 6 Mar 2017 17:19:38 -0800 Subject: [core] clear source when removed from style --- src/mbgl/style/source_impl.cpp | 4 ++++ src/mbgl/style/source_impl.hpp | 3 +++ src/mbgl/style/style.cpp | 1 + 3 files changed, 8 insertions(+) diff --git a/src/mbgl/style/source_impl.cpp b/src/mbgl/style/source_impl.cpp index 22e51f8885..fdacb00b4c 100644 --- a/src/mbgl/style/source_impl.cpp +++ b/src/mbgl/style/source_impl.cpp @@ -44,6 +44,10 @@ bool Source::Impl::isLoaded() const { return true; } + +void Source::Impl::detach() { + invalidateTiles(); +} void Source::Impl::invalidateTiles() { tiles.clear(); diff --git a/src/mbgl/style/source_impl.hpp b/src/mbgl/style/source_impl.hpp index ea2135c3c1..54af93c04f 100644 --- a/src/mbgl/style/source_impl.hpp +++ b/src/mbgl/style/source_impl.hpp @@ -87,6 +87,9 @@ public: // be initialized to true so that Style::isLoaded() does not produce false positives if // called before Style::recalculate(). bool enabled = true; + + // Detaches from the style + void detach(); protected: void invalidateTiles(); diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp index aacf811f4d..5b45ca27ef 100644 --- a/src/mbgl/style/style.cpp +++ b/src/mbgl/style/style.cpp @@ -166,6 +166,7 @@ std::unique_ptr Style::removeSource(const std::string& id) { sources.erase(it); updateBatch.sourceIDs.erase(id); + source->baseImpl->detach(); return source; } -- cgit v1.2.1 From 732cd8d20acfb9b97f76393962035d5374e84bb8 Mon Sep 17 00:00:00 2001 From: Ivo van Dongen Date: Sun, 5 Mar 2017 01:06:44 -0800 Subject: [android] use PropertyValue for default values in functions --- .../style/functions/CompositeFunction.java | 11 ++-- .../mapboxsdk/style/functions/SourceFunction.java | 11 ++-- .../mapboxsdk/style/layers/PropertyValue.java | 28 +++++++- .../mapboxsdk/testapp/style/CircleLayerTest.java | 50 +++++++++----- .../mapboxsdk/testapp/style/FillLayerTest.java | 18 +++-- .../mapboxsdk/testapp/style/LineLayerTest.java | 37 +++++++---- .../mapboxsdk/testapp/style/SymbolLayerTest.java | 76 +++++++++++++++------- .../mapbox/mapboxsdk/testapp/style/layer.junit.ejs | 14 ++-- 8 files changed, 169 insertions(+), 76 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/CompositeFunction.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/CompositeFunction.java index 1db14afc5f..8ded7ecd34 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/CompositeFunction.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/CompositeFunction.java @@ -8,6 +8,7 @@ import com.mapbox.mapboxsdk.style.functions.stops.ExponentialStops; import com.mapbox.mapboxsdk.style.functions.stops.IntervalStops; import com.mapbox.mapboxsdk.style.functions.stops.Stop; import com.mapbox.mapboxsdk.style.functions.stops.Stops; +import com.mapbox.mapboxsdk.style.layers.PropertyValue; import java.util.Map; @@ -27,7 +28,7 @@ import java.util.Map; public class CompositeFunction extends Function, O> { private final String property; - private O defaultValue; + private PropertyValue defaultValue; CompositeFunction(@NonNull String property, @NonNull CategoricalStops, O> stops) { @@ -51,7 +52,7 @@ public class CompositeFunction extends Function, O> stops) { super(stops); - this.defaultValue = defaultValue; + this.defaultValue = new PropertyValue<>(property, defaultValue); this.property = property; } @@ -61,7 +62,7 @@ public class CompositeFunction extends Function withDefaultValue(O defaultValue) { + public CompositeFunction withDefaultValue(PropertyValue defaultValue) { this.defaultValue = defaultValue; return this; } @@ -70,7 +71,7 @@ public class CompositeFunction extends Function getDefaultValue() { return defaultValue; } @@ -91,7 +92,7 @@ public class CompositeFunction extends Function valueObject = super.toValueObject(); valueObject.put(PROPERTY_KEY, property); if (defaultValue != null) { - valueObject.put(DEFAULT_VALUE_KEY, defaultValue); + valueObject.put(DEFAULT_VALUE_KEY, defaultValue.value); } return valueObject; } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/SourceFunction.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/SourceFunction.java index f0eed760a4..33f436ae71 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/SourceFunction.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/SourceFunction.java @@ -4,6 +4,7 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import com.mapbox.mapboxsdk.style.functions.stops.Stops; +import com.mapbox.mapboxsdk.style.layers.PropertyValue; import java.util.Map; @@ -25,7 +26,7 @@ import java.util.Map; public class SourceFunction extends Function { private final String property; - private O defaultValue; + private PropertyValue defaultValue; SourceFunction(@NonNull String property, @NonNull Stops stops) { this(null, property, stops); @@ -37,7 +38,7 @@ public class SourceFunction extends Function { private SourceFunction(@Nullable O defaultValue, @NonNull String property, @NonNull Stops stops) { super(stops); this.property = property; - this.defaultValue = defaultValue; + this.defaultValue = defaultValue != null ? new PropertyValue<>(property, defaultValue) : null; } @@ -56,7 +57,7 @@ public class SourceFunction extends Function { * @param defaultValue the default value to use when no other applies * @return this (for chaining) */ - public SourceFunction withDefaultValue(O defaultValue) { + public SourceFunction withDefaultValue(PropertyValue defaultValue) { this.defaultValue = defaultValue; return this; } @@ -65,7 +66,7 @@ public class SourceFunction extends Function { * @return the defaultValue */ @Nullable - public O getDefaultValue() { + public PropertyValue getDefaultValue() { return defaultValue; } @@ -77,7 +78,7 @@ public class SourceFunction extends Function { Map valueObject = super.toValueObject(); valueObject.put(PROPERTY_KEY, property); if (defaultValue != null) { - valueObject.put(DEFAULT_VALUE_KEY, defaultValue); + valueObject.put(DEFAULT_VALUE_KEY, defaultValue.value); } return valueObject; } 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 5286e6916d..68727c8a4f 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,9 +1,12 @@ package com.mapbox.mapboxsdk.style.layers; +import android.support.annotation.ColorInt; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import com.mapbox.mapboxsdk.exceptions.ConversionException; import com.mapbox.mapboxsdk.style.functions.Function; +import com.mapbox.mapboxsdk.utils.ColorUtils; import timber.log.Timber; @@ -15,7 +18,14 @@ public class PropertyValue { public final String name; public final T value; - /* package */ PropertyValue(@NonNull String name, T value) { + /** + * Not part of the public API. + * + * @param name the property name + * @param value the property value + * @see PropertyFactory for construction of {@link PropertyValue}s + */ + public PropertyValue(@NonNull String name, T value) { this.name = name; this.value = value; } @@ -54,6 +64,22 @@ public class PropertyValue { } } + @ColorInt + @Nullable + public Integer getColorInt() { + if (!isValue() || !(value instanceof String)) { + Timber.e("%s is not a String value and can not be converted to a color it", name); + return null; + } + + try { + return ColorUtils.rgbaToColor((String) value); + } catch (ConversionException ex) { + Timber.e("%s could not be converted to a Color int: %s", name, ex.getMessage()); + return null; + } + } + @Override public String toString() { return String.format("%s: %s", name, value); 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 c48a6f1d68..a8f35356b5 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 @@ -177,7 +177,7 @@ public class CircleLayerTest extends BaseStyleTest { categorical( stop(1.0f, circleRadius(0.3f)) ) - ).withDefaultValue(0.3f) + ).withDefaultValue(circleRadius(0.3f)) ) ); @@ -187,7 +187,9 @@ public class CircleLayerTest extends BaseStyleTest { assertEquals(SourceFunction.class, layer.getCircleRadius().getFunction().getClass()); assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleRadius().getFunction()).getProperty()); assertEquals(CategoricalStops.class, layer.getCircleRadius().getFunction().getStops().getClass()); - assertEquals(0.3f, ((SourceFunction) layer.getCircleRadius().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getCircleRadius().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getCircleRadius().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getCircleRadius().getFunction()).getDefaultValue().getValue()); } @Test @@ -204,7 +206,7 @@ public class CircleLayerTest extends BaseStyleTest { exponential( stop(0, 0.3f, circleRadius(0.9f)) ).withBase(0.5f) - ).withDefaultValue(0.3f) + ).withDefaultValue(circleRadius(0.3f)) ) ); @@ -320,7 +322,7 @@ public class CircleLayerTest extends BaseStyleTest { categorical( stop("valueA", circleColor(Color.RED)) ) - ) + ).withDefaultValue(circleColor(Color.GREEN)) ) ); @@ -330,6 +332,9 @@ public class CircleLayerTest extends BaseStyleTest { assertEquals(SourceFunction.class, layer.getCircleColor().getFunction().getClass()); assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleColor().getFunction()).getProperty()); assertEquals(CategoricalStops.class, layer.getCircleColor().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getCircleColor().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getCircleColor().getFunction()).getDefaultValue().getValue()); + assertEquals(Color.GREEN, (int) ((SourceFunction) layer.getCircleColor().getFunction()).getDefaultValue().getColorInt()); } @Test @@ -439,7 +444,7 @@ public class CircleLayerTest extends BaseStyleTest { categorical( stop(1.0f, circleBlur(0.3f)) ) - ).withDefaultValue(0.3f) + ).withDefaultValue(circleBlur(0.3f)) ) ); @@ -449,7 +454,9 @@ public class CircleLayerTest extends BaseStyleTest { assertEquals(SourceFunction.class, layer.getCircleBlur().getFunction().getClass()); assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleBlur().getFunction()).getProperty()); assertEquals(CategoricalStops.class, layer.getCircleBlur().getFunction().getStops().getClass()); - assertEquals(0.3f, ((SourceFunction) layer.getCircleBlur().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getCircleBlur().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getCircleBlur().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getCircleBlur().getFunction()).getDefaultValue().getValue()); } @Test @@ -466,7 +473,7 @@ public class CircleLayerTest extends BaseStyleTest { exponential( stop(0, 0.3f, circleBlur(0.9f)) ).withBase(0.5f) - ).withDefaultValue(0.3f) + ).withDefaultValue(circleBlur(0.3f)) ) ); @@ -582,7 +589,7 @@ public class CircleLayerTest extends BaseStyleTest { categorical( stop(1.0f, circleOpacity(0.3f)) ) - ).withDefaultValue(0.3f) + ).withDefaultValue(circleOpacity(0.3f)) ) ); @@ -592,7 +599,9 @@ public class CircleLayerTest extends BaseStyleTest { assertEquals(SourceFunction.class, layer.getCircleOpacity().getFunction().getClass()); assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleOpacity().getFunction()).getProperty()); assertEquals(CategoricalStops.class, layer.getCircleOpacity().getFunction().getStops().getClass()); - assertEquals(0.3f, ((SourceFunction) layer.getCircleOpacity().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getCircleOpacity().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getCircleOpacity().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getCircleOpacity().getFunction()).getDefaultValue().getValue()); } @Test @@ -609,7 +618,7 @@ public class CircleLayerTest extends BaseStyleTest { exponential( stop(0, 0.3f, circleOpacity(0.9f)) ).withBase(0.5f) - ).withDefaultValue(0.3f) + ).withDefaultValue(circleOpacity(0.3f)) ) ); @@ -834,7 +843,7 @@ public class CircleLayerTest extends BaseStyleTest { categorical( stop(1.0f, circleStrokeWidth(0.3f)) ) - ).withDefaultValue(0.3f) + ).withDefaultValue(circleStrokeWidth(0.3f)) ) ); @@ -844,7 +853,9 @@ public class CircleLayerTest extends BaseStyleTest { assertEquals(SourceFunction.class, layer.getCircleStrokeWidth().getFunction().getClass()); assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleStrokeWidth().getFunction()).getProperty()); assertEquals(CategoricalStops.class, layer.getCircleStrokeWidth().getFunction().getStops().getClass()); - assertEquals(0.3f, ((SourceFunction) layer.getCircleStrokeWidth().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getCircleStrokeWidth().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getCircleStrokeWidth().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getCircleStrokeWidth().getFunction()).getDefaultValue().getValue()); } @Test @@ -861,7 +872,7 @@ public class CircleLayerTest extends BaseStyleTest { exponential( stop(0, 0.3f, circleStrokeWidth(0.9f)) ).withBase(0.5f) - ).withDefaultValue(0.3f) + ).withDefaultValue(circleStrokeWidth(0.3f)) ) ); @@ -977,7 +988,7 @@ public class CircleLayerTest extends BaseStyleTest { categorical( stop("valueA", circleStrokeColor(Color.RED)) ) - ) + ).withDefaultValue(circleStrokeColor(Color.GREEN)) ) ); @@ -987,6 +998,9 @@ public class CircleLayerTest extends BaseStyleTest { assertEquals(SourceFunction.class, layer.getCircleStrokeColor().getFunction().getClass()); assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleStrokeColor().getFunction()).getProperty()); assertEquals(CategoricalStops.class, layer.getCircleStrokeColor().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getCircleStrokeColor().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getCircleStrokeColor().getFunction()).getDefaultValue().getValue()); + assertEquals(Color.GREEN, (int) ((SourceFunction) layer.getCircleStrokeColor().getFunction()).getDefaultValue().getColorInt()); } @Test @@ -1096,7 +1110,7 @@ public class CircleLayerTest extends BaseStyleTest { categorical( stop(1.0f, circleStrokeOpacity(0.3f)) ) - ).withDefaultValue(0.3f) + ).withDefaultValue(circleStrokeOpacity(0.3f)) ) ); @@ -1106,7 +1120,9 @@ public class CircleLayerTest extends BaseStyleTest { assertEquals(SourceFunction.class, layer.getCircleStrokeOpacity().getFunction().getClass()); assertEquals("FeaturePropertyA", ((SourceFunction) layer.getCircleStrokeOpacity().getFunction()).getProperty()); assertEquals(CategoricalStops.class, layer.getCircleStrokeOpacity().getFunction().getStops().getClass()); - assertEquals(0.3f, ((SourceFunction) layer.getCircleStrokeOpacity().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getCircleStrokeOpacity().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getCircleStrokeOpacity().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getCircleStrokeOpacity().getFunction()).getDefaultValue().getValue()); } @Test @@ -1123,7 +1139,7 @@ public class CircleLayerTest extends BaseStyleTest { exponential( stop(0, 0.3f, circleStrokeOpacity(0.9f)) ).withBase(0.5f) - ).withDefaultValue(0.3f) + ).withDefaultValue(circleStrokeOpacity(0.3f)) ) ); 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 dd59b97525..a1d362f0f9 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 @@ -213,7 +213,7 @@ public class FillLayerTest extends BaseStyleTest { categorical( stop(1.0f, fillOpacity(0.3f)) ) - ).withDefaultValue(0.3f) + ).withDefaultValue(fillOpacity(0.3f)) ) ); @@ -223,7 +223,9 @@ public class FillLayerTest extends BaseStyleTest { assertEquals(SourceFunction.class, layer.getFillOpacity().getFunction().getClass()); assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillOpacity().getFunction()).getProperty()); assertEquals(CategoricalStops.class, layer.getFillOpacity().getFunction().getStops().getClass()); - assertEquals(0.3f, ((SourceFunction) layer.getFillOpacity().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getFillOpacity().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getFillOpacity().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getFillOpacity().getFunction()).getDefaultValue().getValue()); } @Test @@ -240,7 +242,7 @@ public class FillLayerTest extends BaseStyleTest { exponential( stop(0, 0.3f, fillOpacity(0.9f)) ).withBase(0.5f) - ).withDefaultValue(0.3f) + ).withDefaultValue(fillOpacity(0.3f)) ) ); @@ -356,7 +358,7 @@ public class FillLayerTest extends BaseStyleTest { categorical( stop("valueA", fillColor(Color.RED)) ) - ) + ).withDefaultValue(fillColor(Color.GREEN)) ) ); @@ -366,6 +368,9 @@ public class FillLayerTest extends BaseStyleTest { assertEquals(SourceFunction.class, layer.getFillColor().getFunction().getClass()); assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillColor().getFunction()).getProperty()); assertEquals(CategoricalStops.class, layer.getFillColor().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getFillColor().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getFillColor().getFunction()).getDefaultValue().getValue()); + assertEquals(Color.GREEN, (int) ((SourceFunction) layer.getFillColor().getFunction()).getDefaultValue().getColorInt()); } @Test @@ -475,7 +480,7 @@ public class FillLayerTest extends BaseStyleTest { categorical( stop("valueA", fillOutlineColor(Color.RED)) ) - ) + ).withDefaultValue(fillOutlineColor(Color.GREEN)) ) ); @@ -485,6 +490,9 @@ public class FillLayerTest extends BaseStyleTest { assertEquals(SourceFunction.class, layer.getFillOutlineColor().getFunction().getClass()); assertEquals("FeaturePropertyA", ((SourceFunction) layer.getFillOutlineColor().getFunction()).getProperty()); assertEquals(CategoricalStops.class, layer.getFillOutlineColor().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getFillOutlineColor().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getFillOutlineColor().getFunction()).getDefaultValue().getValue()); + assertEquals(Color.GREEN, (int) ((SourceFunction) layer.getFillOutlineColor().getFunction()).getDefaultValue().getColorInt()); } @Test 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 740393ad36..466873f9e5 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 @@ -323,7 +323,7 @@ public class LineLayerTest extends BaseStyleTest { categorical( stop(1.0f, lineOpacity(0.3f)) ) - ).withDefaultValue(0.3f) + ).withDefaultValue(lineOpacity(0.3f)) ) ); @@ -333,7 +333,9 @@ public class LineLayerTest extends BaseStyleTest { assertEquals(SourceFunction.class, layer.getLineOpacity().getFunction().getClass()); assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineOpacity().getFunction()).getProperty()); assertEquals(CategoricalStops.class, layer.getLineOpacity().getFunction().getStops().getClass()); - assertEquals(0.3f, ((SourceFunction) layer.getLineOpacity().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getLineOpacity().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getLineOpacity().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getLineOpacity().getFunction()).getDefaultValue().getValue()); } @Test @@ -350,7 +352,7 @@ public class LineLayerTest extends BaseStyleTest { exponential( stop(0, 0.3f, lineOpacity(0.9f)) ).withBase(0.5f) - ).withDefaultValue(0.3f) + ).withDefaultValue(lineOpacity(0.3f)) ) ); @@ -466,7 +468,7 @@ public class LineLayerTest extends BaseStyleTest { categorical( stop("valueA", lineColor(Color.RED)) ) - ) + ).withDefaultValue(lineColor(Color.GREEN)) ) ); @@ -476,6 +478,9 @@ public class LineLayerTest extends BaseStyleTest { assertEquals(SourceFunction.class, layer.getLineColor().getFunction().getClass()); assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineColor().getFunction()).getProperty()); assertEquals(CategoricalStops.class, layer.getLineColor().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getLineColor().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getLineColor().getFunction()).getDefaultValue().getValue()); + assertEquals(Color.GREEN, (int) ((SourceFunction) layer.getLineColor().getFunction()).getDefaultValue().getColorInt()); } @Test @@ -695,7 +700,7 @@ public class LineLayerTest extends BaseStyleTest { categorical( stop(1.0f, lineGapWidth(0.3f)) ) - ).withDefaultValue(0.3f) + ).withDefaultValue(lineGapWidth(0.3f)) ) ); @@ -705,7 +710,9 @@ public class LineLayerTest extends BaseStyleTest { assertEquals(SourceFunction.class, layer.getLineGapWidth().getFunction().getClass()); assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineGapWidth().getFunction()).getProperty()); assertEquals(CategoricalStops.class, layer.getLineGapWidth().getFunction().getStops().getClass()); - assertEquals(0.3f, ((SourceFunction) layer.getLineGapWidth().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getLineGapWidth().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getLineGapWidth().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getLineGapWidth().getFunction()).getDefaultValue().getValue()); } @Test @@ -722,7 +729,7 @@ public class LineLayerTest extends BaseStyleTest { exponential( stop(0, 0.3f, lineGapWidth(0.9f)) ).withBase(0.5f) - ).withDefaultValue(0.3f) + ).withDefaultValue(lineGapWidth(0.3f)) ) ); @@ -838,7 +845,7 @@ public class LineLayerTest extends BaseStyleTest { categorical( stop(1.0f, lineOffset(0.3f)) ) - ).withDefaultValue(0.3f) + ).withDefaultValue(lineOffset(0.3f)) ) ); @@ -848,7 +855,9 @@ public class LineLayerTest extends BaseStyleTest { assertEquals(SourceFunction.class, layer.getLineOffset().getFunction().getClass()); assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineOffset().getFunction()).getProperty()); assertEquals(CategoricalStops.class, layer.getLineOffset().getFunction().getStops().getClass()); - assertEquals(0.3f, ((SourceFunction) layer.getLineOffset().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getLineOffset().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getLineOffset().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getLineOffset().getFunction()).getDefaultValue().getValue()); } @Test @@ -865,7 +874,7 @@ public class LineLayerTest extends BaseStyleTest { exponential( stop(0, 0.3f, lineOffset(0.9f)) ).withBase(0.5f) - ).withDefaultValue(0.3f) + ).withDefaultValue(lineOffset(0.3f)) ) ); @@ -981,7 +990,7 @@ public class LineLayerTest extends BaseStyleTest { categorical( stop(1.0f, lineBlur(0.3f)) ) - ).withDefaultValue(0.3f) + ).withDefaultValue(lineBlur(0.3f)) ) ); @@ -991,7 +1000,9 @@ public class LineLayerTest extends BaseStyleTest { assertEquals(SourceFunction.class, layer.getLineBlur().getFunction().getClass()); assertEquals("FeaturePropertyA", ((SourceFunction) layer.getLineBlur().getFunction()).getProperty()); assertEquals(CategoricalStops.class, layer.getLineBlur().getFunction().getStops().getClass()); - assertEquals(0.3f, ((SourceFunction) layer.getLineBlur().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getLineBlur().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getLineBlur().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getLineBlur().getFunction()).getDefaultValue().getValue()); } @Test @@ -1008,7 +1019,7 @@ public class LineLayerTest extends BaseStyleTest { exponential( stop(0, 0.3f, lineBlur(0.9f)) ).withBase(0.5f) - ).withDefaultValue(0.3f) + ).withDefaultValue(lineBlur(0.3f)) ) ); 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 3b3bc9c8b5..c90af339b1 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 @@ -576,7 +576,7 @@ public class SymbolLayerTest extends BaseStyleTest { categorical( stop(1.0f, iconRotate(0.3f)) ) - ).withDefaultValue(0.3f) + ).withDefaultValue(iconRotate(0.3f)) ) ); @@ -586,7 +586,9 @@ public class SymbolLayerTest extends BaseStyleTest { assertEquals(SourceFunction.class, layer.getIconRotate().getFunction().getClass()); assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconRotate().getFunction()).getProperty()); assertEquals(CategoricalStops.class, layer.getIconRotate().getFunction().getStops().getClass()); - assertEquals(0.3f, ((SourceFunction) layer.getIconRotate().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getIconRotate().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getIconRotate().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getIconRotate().getFunction()).getDefaultValue().getValue()); } @Test @@ -603,7 +605,7 @@ public class SymbolLayerTest extends BaseStyleTest { exponential( stop(0, 0.3f, iconRotate(0.9f)) ).withBase(0.5f) - ).withDefaultValue(0.3f) + ).withDefaultValue(iconRotate(0.3f)) ) ); @@ -1656,7 +1658,7 @@ public class SymbolLayerTest extends BaseStyleTest { categorical( stop(1.0f, iconOpacity(0.3f)) ) - ).withDefaultValue(0.3f) + ).withDefaultValue(iconOpacity(0.3f)) ) ); @@ -1666,7 +1668,9 @@ public class SymbolLayerTest extends BaseStyleTest { assertEquals(SourceFunction.class, layer.getIconOpacity().getFunction().getClass()); assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconOpacity().getFunction()).getProperty()); assertEquals(CategoricalStops.class, layer.getIconOpacity().getFunction().getStops().getClass()); - assertEquals(0.3f, ((SourceFunction) layer.getIconOpacity().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getIconOpacity().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getIconOpacity().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getIconOpacity().getFunction()).getDefaultValue().getValue()); } @Test @@ -1683,7 +1687,7 @@ public class SymbolLayerTest extends BaseStyleTest { exponential( stop(0, 0.3f, iconOpacity(0.9f)) ).withBase(0.5f) - ).withDefaultValue(0.3f) + ).withDefaultValue(iconOpacity(0.3f)) ) ); @@ -1799,7 +1803,7 @@ public class SymbolLayerTest extends BaseStyleTest { categorical( stop("valueA", iconColor(Color.RED)) ) - ) + ).withDefaultValue(iconColor(Color.GREEN)) ) ); @@ -1809,6 +1813,9 @@ public class SymbolLayerTest extends BaseStyleTest { assertEquals(SourceFunction.class, layer.getIconColor().getFunction().getClass()); assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconColor().getFunction()).getProperty()); assertEquals(CategoricalStops.class, layer.getIconColor().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getIconColor().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getIconColor().getFunction()).getDefaultValue().getValue()); + assertEquals(Color.GREEN, (int) ((SourceFunction) layer.getIconColor().getFunction()).getDefaultValue().getColorInt()); } @Test @@ -1918,7 +1925,7 @@ public class SymbolLayerTest extends BaseStyleTest { categorical( stop("valueA", iconHaloColor(Color.RED)) ) - ) + ).withDefaultValue(iconHaloColor(Color.GREEN)) ) ); @@ -1928,6 +1935,9 @@ public class SymbolLayerTest extends BaseStyleTest { assertEquals(SourceFunction.class, layer.getIconHaloColor().getFunction().getClass()); assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconHaloColor().getFunction()).getProperty()); assertEquals(CategoricalStops.class, layer.getIconHaloColor().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getIconHaloColor().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getIconHaloColor().getFunction()).getDefaultValue().getValue()); + assertEquals(Color.GREEN, (int) ((SourceFunction) layer.getIconHaloColor().getFunction()).getDefaultValue().getColorInt()); } @Test @@ -2037,7 +2047,7 @@ public class SymbolLayerTest extends BaseStyleTest { categorical( stop(1.0f, iconHaloWidth(0.3f)) ) - ).withDefaultValue(0.3f) + ).withDefaultValue(iconHaloWidth(0.3f)) ) ); @@ -2047,7 +2057,9 @@ public class SymbolLayerTest extends BaseStyleTest { assertEquals(SourceFunction.class, layer.getIconHaloWidth().getFunction().getClass()); assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconHaloWidth().getFunction()).getProperty()); assertEquals(CategoricalStops.class, layer.getIconHaloWidth().getFunction().getStops().getClass()); - assertEquals(0.3f, ((SourceFunction) layer.getIconHaloWidth().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getIconHaloWidth().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getIconHaloWidth().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getIconHaloWidth().getFunction()).getDefaultValue().getValue()); } @Test @@ -2064,7 +2076,7 @@ public class SymbolLayerTest extends BaseStyleTest { exponential( stop(0, 0.3f, iconHaloWidth(0.9f)) ).withBase(0.5f) - ).withDefaultValue(0.3f) + ).withDefaultValue(iconHaloWidth(0.3f)) ) ); @@ -2180,7 +2192,7 @@ public class SymbolLayerTest extends BaseStyleTest { categorical( stop(1.0f, iconHaloBlur(0.3f)) ) - ).withDefaultValue(0.3f) + ).withDefaultValue(iconHaloBlur(0.3f)) ) ); @@ -2190,7 +2202,9 @@ public class SymbolLayerTest extends BaseStyleTest { assertEquals(SourceFunction.class, layer.getIconHaloBlur().getFunction().getClass()); assertEquals("FeaturePropertyA", ((SourceFunction) layer.getIconHaloBlur().getFunction()).getProperty()); assertEquals(CategoricalStops.class, layer.getIconHaloBlur().getFunction().getStops().getClass()); - assertEquals(0.3f, ((SourceFunction) layer.getIconHaloBlur().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getIconHaloBlur().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getIconHaloBlur().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getIconHaloBlur().getFunction()).getDefaultValue().getValue()); } @Test @@ -2207,7 +2221,7 @@ public class SymbolLayerTest extends BaseStyleTest { exponential( stop(0, 0.3f, iconHaloBlur(0.9f)) ).withBase(0.5f) - ).withDefaultValue(0.3f) + ).withDefaultValue(iconHaloBlur(0.3f)) ) ); @@ -2396,7 +2410,7 @@ public class SymbolLayerTest extends BaseStyleTest { categorical( stop(1.0f, textOpacity(0.3f)) ) - ).withDefaultValue(0.3f) + ).withDefaultValue(textOpacity(0.3f)) ) ); @@ -2406,7 +2420,9 @@ public class SymbolLayerTest extends BaseStyleTest { assertEquals(SourceFunction.class, layer.getTextOpacity().getFunction().getClass()); assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextOpacity().getFunction()).getProperty()); assertEquals(CategoricalStops.class, layer.getTextOpacity().getFunction().getStops().getClass()); - assertEquals(0.3f, ((SourceFunction) layer.getTextOpacity().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getTextOpacity().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getTextOpacity().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getTextOpacity().getFunction()).getDefaultValue().getValue()); } @Test @@ -2423,7 +2439,7 @@ public class SymbolLayerTest extends BaseStyleTest { exponential( stop(0, 0.3f, textOpacity(0.9f)) ).withBase(0.5f) - ).withDefaultValue(0.3f) + ).withDefaultValue(textOpacity(0.3f)) ) ); @@ -2539,7 +2555,7 @@ public class SymbolLayerTest extends BaseStyleTest { categorical( stop("valueA", textColor(Color.RED)) ) - ) + ).withDefaultValue(textColor(Color.GREEN)) ) ); @@ -2549,6 +2565,9 @@ public class SymbolLayerTest extends BaseStyleTest { assertEquals(SourceFunction.class, layer.getTextColor().getFunction().getClass()); assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextColor().getFunction()).getProperty()); assertEquals(CategoricalStops.class, layer.getTextColor().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getTextColor().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getTextColor().getFunction()).getDefaultValue().getValue()); + assertEquals(Color.GREEN, (int) ((SourceFunction) layer.getTextColor().getFunction()).getDefaultValue().getColorInt()); } @Test @@ -2658,7 +2677,7 @@ public class SymbolLayerTest extends BaseStyleTest { categorical( stop("valueA", textHaloColor(Color.RED)) ) - ) + ).withDefaultValue(textHaloColor(Color.GREEN)) ) ); @@ -2668,6 +2687,9 @@ public class SymbolLayerTest extends BaseStyleTest { assertEquals(SourceFunction.class, layer.getTextHaloColor().getFunction().getClass()); assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextHaloColor().getFunction()).getProperty()); assertEquals(CategoricalStops.class, layer.getTextHaloColor().getFunction().getStops().getClass()); + assertNotNull(((SourceFunction) layer.getTextHaloColor().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getTextHaloColor().getFunction()).getDefaultValue().getValue()); + assertEquals(Color.GREEN, (int) ((SourceFunction) layer.getTextHaloColor().getFunction()).getDefaultValue().getColorInt()); } @Test @@ -2777,7 +2799,7 @@ public class SymbolLayerTest extends BaseStyleTest { categorical( stop(1.0f, textHaloWidth(0.3f)) ) - ).withDefaultValue(0.3f) + ).withDefaultValue(textHaloWidth(0.3f)) ) ); @@ -2787,7 +2809,9 @@ public class SymbolLayerTest extends BaseStyleTest { assertEquals(SourceFunction.class, layer.getTextHaloWidth().getFunction().getClass()); assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextHaloWidth().getFunction()).getProperty()); assertEquals(CategoricalStops.class, layer.getTextHaloWidth().getFunction().getStops().getClass()); - assertEquals(0.3f, ((SourceFunction) layer.getTextHaloWidth().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getTextHaloWidth().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getTextHaloWidth().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getTextHaloWidth().getFunction()).getDefaultValue().getValue()); } @Test @@ -2804,7 +2828,7 @@ public class SymbolLayerTest extends BaseStyleTest { exponential( stop(0, 0.3f, textHaloWidth(0.9f)) ).withBase(0.5f) - ).withDefaultValue(0.3f) + ).withDefaultValue(textHaloWidth(0.3f)) ) ); @@ -2920,7 +2944,7 @@ public class SymbolLayerTest extends BaseStyleTest { categorical( stop(1.0f, textHaloBlur(0.3f)) ) - ).withDefaultValue(0.3f) + ).withDefaultValue(textHaloBlur(0.3f)) ) ); @@ -2930,7 +2954,9 @@ public class SymbolLayerTest extends BaseStyleTest { assertEquals(SourceFunction.class, layer.getTextHaloBlur().getFunction().getClass()); assertEquals("FeaturePropertyA", ((SourceFunction) layer.getTextHaloBlur().getFunction()).getProperty()); assertEquals(CategoricalStops.class, layer.getTextHaloBlur().getFunction().getStops().getClass()); - assertEquals(0.3f, ((SourceFunction) layer.getTextHaloBlur().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getTextHaloBlur().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.getTextHaloBlur().getFunction()).getDefaultValue().getValue()); + assertEquals(0.3f, ((SourceFunction) layer.getTextHaloBlur().getFunction()).getDefaultValue().getValue()); } @Test @@ -2947,7 +2973,7 @@ public class SymbolLayerTest extends BaseStyleTest { exponential( stop(0, 0.3f, textHaloBlur(0.9f)) ).withBase(0.5f) - ).withDefaultValue(0.3f) + ).withDefaultValue(textHaloBlur(0.3f)) ) ); 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 f1d68caa24..3dc88d29bb 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 @@ -269,11 +269,11 @@ public class <%- camelize(type) %>LayerTest extends BaseStyleTest { <% if (property.type == 'color') { -%> stop("valueA", <%- camelizeWithLeadingLowercase(property.name) %>(Color.RED)) ) - ) + ).withDefaultValue(<%- camelizeWithLeadingLowercase(property.name) %>(Color.GREEN)) <% } else {-%> stop(1.0f, <%- camelizeWithLeadingLowercase(property.name) %>(<%- defaultValueJava(property) %>)) ) - ).withDefaultValue(<%- defaultValueJava(property) %>) + ).withDefaultValue(<%- camelizeWithLeadingLowercase(property.name) %>(<%- defaultValueJava(property) %>)) <% } -%> ) ); @@ -284,8 +284,12 @@ public class <%- camelize(type) %>LayerTest extends BaseStyleTest { assertEquals(SourceFunction.class, layer.get<%- camelize(property.name) %>().getFunction().getClass()); assertEquals("FeaturePropertyA", ((SourceFunction) layer.get<%- camelize(property.name) %>().getFunction()).getProperty()); assertEquals(CategoricalStops.class, layer.get<%- camelize(property.name) %>().getFunction().getStops().getClass()); -<% if (property.type !== 'color') { -%> - assertEquals(<%- defaultValueJava(property) %>, ((SourceFunction) layer.get<%- camelize(property.name) %>().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.get<%- camelize(property.name) %>().getFunction()).getDefaultValue()); + assertNotNull(((SourceFunction) layer.get<%- camelize(property.name) %>().getFunction()).getDefaultValue().getValue()); +<% if (property.type === 'color') { -%> + assertEquals(Color.GREEN, (int) ((SourceFunction) layer.get<%- camelize(property.name) %>().getFunction()).getDefaultValue().getColorInt()); +<% } else { -%> + assertEquals(<%- defaultValueJava(property) %>, ((SourceFunction) layer.get<%- camelize(property.name) %>().getFunction()).getDefaultValue().getValue()); <% } -%> } <% if (property.type !== 'color') { -%> @@ -305,7 +309,7 @@ public class <%- camelize(type) %>LayerTest extends BaseStyleTest { stop(0, 0.3f, <%- camelizeWithLeadingLowercase(property.name) %>(0.9f)) ).withBase(0.5f) <% if (property.type == 'number') { -%> - ).withDefaultValue(<%- defaultValueJava(property) %>) + ).withDefaultValue(<%- camelizeWithLeadingLowercase(property.name) %>(<%- defaultValueJava(property) %>)) <% } else { -%> ) <% } -%> -- cgit v1.2.1 From f591421aaaf698c23ccff37a03d03c87eaa0d988 Mon Sep 17 00:00:00 2001 From: Ivo van Dongen Date: Tue, 7 Mar 2017 17:32:20 -0800 Subject: [macos] add missing method declarations for visibleFeaturesX --- platform/macos/src/MGLMapView.mm | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/platform/macos/src/MGLMapView.mm b/platform/macos/src/MGLMapView.mm index e09daa1c18..4587296916 100644 --- a/platform/macos/src/MGLMapView.mm +++ b/platform/macos/src/MGLMapView.mm @@ -2520,6 +2520,10 @@ public: return [self visibleFeaturesAtPoint:point inStyleLayersWithIdentifiers:nil]; } +- (NS_ARRAY_OF(id ) *)visibleFeaturesAtPoint:(CGPoint)point inStyleLayersWithIdentifiers:(NS_SET_OF(NSString *) *)styleLayerIdentifiers { + return [self visibleFeaturesAtPoint:point inStyleLayersWithIdentifiers:styleLayerIdentifiers predicate:nil]; +} + - (NS_ARRAY_OF(id ) *)visibleFeaturesAtPoint:(NSPoint)point inStyleLayersWithIdentifiers:(NS_SET_OF(NSString *) *)styleLayerIdentifiers predicate:(NSPredicate *)predicate { // Cocoa origin is at the lower-left corner. mbgl::ScreenCoordinate screenCoordinate = { point.x, NSHeight(self.bounds) - point.y }; @@ -2547,6 +2551,10 @@ public: return [self visibleFeaturesInRect:rect inStyleLayersWithIdentifiers:nil]; } +- (NS_ARRAY_OF(id ) *)visibleFeaturesInRect:(CGRect)rect inStyleLayersWithIdentifiers:(NS_SET_OF(NSString *) *)styleLayerIdentifiers { + return [self visibleFeaturesInRect:rect inStyleLayersWithIdentifiers:styleLayerIdentifiers predicate:nil]; +} + - (NS_ARRAY_OF(id ) *)visibleFeaturesInRect:(NSRect)rect inStyleLayersWithIdentifiers:(NS_SET_OF(NSString *) *)styleLayerIdentifiers predicate:(NSPredicate *)predicate { // Cocoa origin is at the lower-left corner. mbgl::ScreenBox screenBox = { -- cgit v1.2.1 From bb846fd6cdff84e71741de9428a00137fd5f73a8 Mon Sep 17 00:00:00 2001 From: Anand Thakker Date: Wed, 8 Mar 2017 11:53:44 -0500 Subject: For data-driven paint setters, transition immediately to target value (#8306) Closes #8237 --- include/mbgl/style/property_value.hpp | 1 + src/mbgl/style/paint_property.hpp | 6 +++++ test/style/paint_property.test.cpp | 45 +++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/include/mbgl/style/property_value.hpp b/include/mbgl/style/property_value.hpp index e784633aa7..1b7429dae6 100644 --- a/include/mbgl/style/property_value.hpp +++ b/include/mbgl/style/property_value.hpp @@ -29,6 +29,7 @@ public: bool isUndefined() const { return value.which() == 0; } bool isConstant() const { return value.which() == 1; } bool isCameraFunction() const { return value.which() == 2; } + bool isDataDriven() const { return false; } const T & asConstant() const { return value.template get< T >(); } const CameraFunction& asCameraFunction() const { return value.template get>(); } diff --git a/src/mbgl/style/paint_property.hpp b/src/mbgl/style/paint_property.hpp index 1fa2390f33..599bbef1f4 100644 --- a/src/mbgl/style/paint_property.hpp +++ b/src/mbgl/style/paint_property.hpp @@ -51,6 +51,12 @@ public: // Transition from prior value is now complete. prior = {}; return finalValue; + } else if (value.isDataDriven()) { + // Transitions to data-driven properties are not supported. + // We snap immediately to the data-driven value so that, when we perform layout, + // we see the data-driven function and can use it to populate vertex buffers. + prior = {}; + return finalValue; } else if (now < begin) { // Transition hasn't started yet. return prior->get().evaluate(evaluator, now); diff --git a/test/style/paint_property.test.cpp b/test/style/paint_property.test.cpp index c70fa101ca..39d31068c1 100644 --- a/test/style/paint_property.test.cpp +++ b/test/style/paint_property.test.cpp @@ -22,6 +22,22 @@ float evaluate(UnevaluatedPaintProperty>& property, Duratio return property.evaluate(evaluator, parameters.now); } +PossiblyEvaluatedPropertyValue evaluate(UnevaluatedPaintProperty>& property, Duration delta = Duration::zero()) { + PropertyEvaluationParameters parameters { + 0, + TimePoint::min() + delta, + ZoomHistory(), + Duration::zero() + }; + + DataDrivenPropertyEvaluator evaluator { + parameters, + 0.0f + }; + + return property.evaluate(evaluator, parameters.now); +} + TEST(UnevaluatedPaintProperty, EvaluateDefaultValue) { UnevaluatedPaintProperty> property; ASSERT_EQ(0.0f, evaluate(property)); @@ -86,3 +102,32 @@ TEST(UnevaluatedPaintProperty, EvaluateTransitionedConstantWithDelay) { ASSERT_FLOAT_EQ(0.823099f, evaluate(t1, 1500ms)); ASSERT_FLOAT_EQ(1.0f, evaluate(t1, 2500ms)); } + +TEST(UnevaluatedPaintProperty, EvaluateDataDrivenValue) { + TransitionOptions transition; + transition.delay = { 1000ms }; + transition.duration = { 1000ms }; + + UnevaluatedPaintProperty> t0 { + DataDrivenPropertyValue(0.0f), + UnevaluatedPaintProperty>(), + TransitionOptions(), + TimePoint::min() + }; + + SourceFunction sourceFunction = { + "property_name", + IdentityStops() + }; + + UnevaluatedPaintProperty> t1 { + DataDrivenPropertyValue(sourceFunction), + t0, + transition, + TimePoint::min() + }; + + ASSERT_TRUE(evaluate(t0, 0ms).isConstant()); + ASSERT_FALSE(evaluate(t1, 0ms).isConstant()) << + "A paint property transition to a data-driven evaluates immediately to the final value (see https://github.com/mapbox/mapbox-gl-native/issues/8237)."; +} -- cgit v1.2.1 From a517323bfc77c33d40a0a43a1fb2f79a6761bbe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Wed, 8 Mar 2017 11:51:13 -0800 Subject: [build] increase binary size log duration to 60 days --- scripts/publish_binary_size.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/publish_binary_size.sh b/scripts/publish_binary_size.sh index d5ab71b8c4..e515de7c96 100755 --- a/scripts/publish_binary_size.sh +++ b/scripts/publish_binary_size.sh @@ -24,9 +24,9 @@ function publish_binary_size { 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}") + local DATE_BEGIN=$(date -jf "${DATE_FORMAT}" -v-60d "${DATE_END}" +"${DATE_FORMAT}") else # GNU date - local DATE_BEGIN=$(date --date="${DATE_END} - 30 days" +"${DATE_FORMAT}") + local DATE_BEGIN=$(date --date="${DATE_END} - 60 days" +"${DATE_FORMAT}") fi # Download the metrics, gzip, and upload to S3. -- cgit v1.2.1 From 84aac92b4eaf264de66c07b98e267364e34e14f0 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Wed, 8 Mar 2017 12:04:28 -0800 Subject: [test] Increase memory test ceiling slightly --- test/util/memory.test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/util/memory.test.cpp b/test/util/memory.test.cpp index d49c49018f..79a3c43dbd 100644 --- a/test/util/memory.test.cpp +++ b/test/util/memory.test.cpp @@ -157,8 +157,8 @@ TEST(Memory, Footprint) { RecordProperty("vectorFootprint", vectorFootprint); RecordProperty("rasterFootprint", rasterFootprint); - ASSERT_LT(vectorFootprint, 65 * 1024 * 1024) << "\ - mbgl::Map footprint over 65MB for vector styles."; + ASSERT_LT(vectorFootprint, 65.2 * 1024 * 1024) << "\ + mbgl::Map footprint over 65.2MB for vector styles."; ASSERT_LT(rasterFootprint, 25 * 1024 * 1024) << "\ mbgl::Map footprint over 25MB for raster styles."; -- cgit v1.2.1 From b83b14feb0b99d669fb84a52ab356051368de637 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Wed, 8 Mar 2017 08:55:55 -0800 Subject: [core] De-duplicate shader prelude source --- cmake/core-files.cmake | 2 + scripts/generate-shaders.js | 41 +++++++++++++-- src/mbgl/programs/program.hpp | 5 +- src/mbgl/shaders/circle.cpp | 71 ------------------------- src/mbgl/shaders/collision_box.cpp | 71 ------------------------- src/mbgl/shaders/debug.cpp | 71 ------------------------- src/mbgl/shaders/fill.cpp | 71 ------------------------- src/mbgl/shaders/fill_outline.cpp | 71 ------------------------- src/mbgl/shaders/fill_outline_pattern.cpp | 71 ------------------------- src/mbgl/shaders/fill_pattern.cpp | 71 ------------------------- src/mbgl/shaders/line.cpp | 71 ------------------------- src/mbgl/shaders/line_pattern.cpp | 71 ------------------------- src/mbgl/shaders/line_sdf.cpp | 71 ------------------------- src/mbgl/shaders/preludes.cpp | 87 +++++++++++++++++++++++++++++++ src/mbgl/shaders/preludes.hpp | 12 +++++ src/mbgl/shaders/raster.cpp | 71 ------------------------- src/mbgl/shaders/symbol_icon.cpp | 71 ------------------------- src/mbgl/shaders/symbol_sdf.cpp | 71 ------------------------- 18 files changed, 141 insertions(+), 929 deletions(-) create mode 100644 src/mbgl/shaders/preludes.cpp create mode 100644 src/mbgl/shaders/preludes.hpp diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake index a9fe077db9..b5baff264c 100644 --- a/cmake/core-files.cmake +++ b/cmake/core-files.cmake @@ -205,6 +205,8 @@ set(MBGL_CORE_FILES src/mbgl/shaders/line_pattern.hpp src/mbgl/shaders/line_sdf.cpp src/mbgl/shaders/line_sdf.hpp + src/mbgl/shaders/preludes.cpp + src/mbgl/shaders/preludes.hpp src/mbgl/shaders/raster.cpp src/mbgl/shaders/raster.hpp src/mbgl/shaders/symbol_icon.cpp diff --git a/scripts/generate-shaders.js b/scripts/generate-shaders.js index 2949ebd007..892620cf21 100755 --- a/scripts/generate-shaders.js +++ b/scripts/generate-shaders.js @@ -8,6 +8,41 @@ const outputPath = 'src/mbgl/shaders'; require('./style-code'); +const vertexPrelude = fs.readFileSync(path.join(inputPath, '_prelude.vertex.glsl')); +const fragmentPrelude = fs.readFileSync(path.join(inputPath, '_prelude.fragment.glsl')); + +writeIfModified(path.join(outputPath, 'preludes.hpp'), `// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. + +#pragma once + +namespace mbgl { +namespace shaders { + +extern const char* vertexPrelude; +extern const char* fragmentPrelude; + +} // namespace shaders +} // namespace mbgl +`); + +writeIfModified(path.join(outputPath, 'preludes.cpp'), `// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. + +#include + +namespace mbgl { +namespace shaders { + +const char* vertexPrelude = R"MBGL_SHADER( +${vertexPrelude} +)MBGL_SHADER"; +const char* fragmentPrelude = R"MBGL_SHADER( +${fragmentPrelude} +)MBGL_SHADER"; + +} // namespace shaders +} // namespace mbgl +`); + [ 'circle', 'collision_box', @@ -34,9 +69,8 @@ require('./style-code'); } function vertexSource() { - const prelude = fs.readFileSync(path.join(inputPath, '_prelude.vertex.glsl')); const source = fs.readFileSync(path.join(inputPath, shaderName + '.vertex.glsl'), 'utf8'); - return prelude + applyPragmas(source, { + return applyPragmas(source, { define: [ "uniform lowp float a_{name}_t;", "attribute {precision} {type} a_{name}_min;", @@ -50,9 +84,8 @@ require('./style-code'); } function fragmentSource() { - const prelude = fs.readFileSync(path.join(inputPath, '_prelude.fragment.glsl')); const source = fs.readFileSync(path.join(inputPath, shaderName + '.fragment.glsl'), 'utf8'); - return prelude + applyPragmas(source, { + return applyPragmas(source, { define: [ "varying {precision} {type} {name};" ], diff --git a/src/mbgl/programs/program.hpp b/src/mbgl/programs/program.hpp index e75dbebf18..ffad767c3a 100644 --- a/src/mbgl/programs/program.hpp +++ b/src/mbgl/programs/program.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -45,7 +46,7 @@ public: } static std::string fragmentSource(const ProgramParameters& parameters) { - std::string source = pixelRatioDefine(parameters) + Shaders::fragmentSource; + std::string source = pixelRatioDefine(parameters) + shaders::fragmentPrelude + 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"); @@ -54,7 +55,7 @@ public: } static std::string vertexSource(const ProgramParameters& parameters) { - return pixelRatioDefine(parameters) + Shaders::vertexSource; + return pixelRatioDefine(parameters) + shaders::vertexPrelude + Shaders::vertexSource; } template diff --git a/src/mbgl/shaders/circle.cpp b/src/mbgl/shaders/circle.cpp index 592a883fb3..4b2bb7cecf 100644 --- a/src/mbgl/shaders/circle.cpp +++ b/src/mbgl/shaders/circle.cpp @@ -7,60 +7,6 @@ namespace shaders { const char* circle::name = "circle"; const char* circle::vertexSource = R"MBGL_SHADER( -#ifdef GL_ES -precision highp float; -#else - -#if !defined(lowp) -#define lowp -#endif - -#if !defined(mediump) -#define mediump -#endif - -#if !defined(highp) -#define highp -#endif - -#endif - -float evaluate_zoom_function_1(const vec4 values, const float t) { - if (t < 1.0) { - return mix(values[0], values[1], t); - } else if (t < 2.0) { - return mix(values[1], values[2], t - 1.0); - } else { - return mix(values[2], values[3], t - 2.0); - } -} -vec4 evaluate_zoom_function_4(const vec4 value0, const vec4 value1, const vec4 value2, const vec4 value3, const float t) { - if (t < 1.0) { - return mix(value0, value1, t); - } else if (t < 2.0) { - return mix(value1, value2, t - 1.0); - } else { - return mix(value2, value3, t - 2.0); - } -} - -// The offset depends on how many pixels are between the world origin and the edge of the tile: -// vec2 offset = mod(pixel_coord, size) -// -// At high zoom levels there are a ton of pixels between the world origin and the edge of the tile. -// The glsl spec only guarantees 16 bits of precision for highp floats. We need more than that. -// -// The pixel_coord is passed in as two 16 bit values: -// pixel_coord_upper = floor(pixel_coord / 2^16) -// pixel_coord_lower = mod(pixel_coord, 2^16) -// -// The offset is calculated in a series of steps that should preserve this precision: -vec2 get_pattern_pos(const vec2 pixel_coord_upper, const vec2 pixel_coord_lower, - const vec2 pattern_size, const float tile_units_to_pixels, const vec2 pos) { - - vec2 offset = mod(mod(mod(pixel_coord_upper, pattern_size) * 256.0, pattern_size) * 256.0 + pixel_coord_lower, pattern_size); - return (tile_units_to_pixels * pos + offset) / pattern_size; -} uniform mat4 u_matrix; uniform bool u_scale_with_map; uniform vec2 u_extrude_scale; @@ -130,23 +76,6 @@ void main(void) { )MBGL_SHADER"; const char* circle::fragmentSource = R"MBGL_SHADER( -#ifdef GL_ES -precision mediump float; -#else - -#if !defined(lowp) -#define lowp -#endif - -#if !defined(mediump) -#define mediump -#endif - -#if !defined(highp) -#define highp -#endif - -#endif varying lowp vec4 color; varying mediump float radius; varying lowp float blur; diff --git a/src/mbgl/shaders/collision_box.cpp b/src/mbgl/shaders/collision_box.cpp index 6f2b9f3824..5f733c6a1e 100644 --- a/src/mbgl/shaders/collision_box.cpp +++ b/src/mbgl/shaders/collision_box.cpp @@ -7,60 +7,6 @@ namespace shaders { const char* collision_box::name = "collision_box"; const char* collision_box::vertexSource = R"MBGL_SHADER( -#ifdef GL_ES -precision highp float; -#else - -#if !defined(lowp) -#define lowp -#endif - -#if !defined(mediump) -#define mediump -#endif - -#if !defined(highp) -#define highp -#endif - -#endif - -float evaluate_zoom_function_1(const vec4 values, const float t) { - if (t < 1.0) { - return mix(values[0], values[1], t); - } else if (t < 2.0) { - return mix(values[1], values[2], t - 1.0); - } else { - return mix(values[2], values[3], t - 2.0); - } -} -vec4 evaluate_zoom_function_4(const vec4 value0, const vec4 value1, const vec4 value2, const vec4 value3, const float t) { - if (t < 1.0) { - return mix(value0, value1, t); - } else if (t < 2.0) { - return mix(value1, value2, t - 1.0); - } else { - return mix(value2, value3, t - 2.0); - } -} - -// The offset depends on how many pixels are between the world origin and the edge of the tile: -// vec2 offset = mod(pixel_coord, size) -// -// At high zoom levels there are a ton of pixels between the world origin and the edge of the tile. -// The glsl spec only guarantees 16 bits of precision for highp floats. We need more than that. -// -// The pixel_coord is passed in as two 16 bit values: -// pixel_coord_upper = floor(pixel_coord / 2^16) -// pixel_coord_lower = mod(pixel_coord, 2^16) -// -// The offset is calculated in a series of steps that should preserve this precision: -vec2 get_pattern_pos(const vec2 pixel_coord_upper, const vec2 pixel_coord_lower, - const vec2 pattern_size, const float tile_units_to_pixels, const vec2 pos) { - - vec2 offset = mod(mod(mod(pixel_coord_upper, pattern_size) * 256.0, pattern_size) * 256.0 + pixel_coord_lower, pattern_size); - return (tile_units_to_pixels * pos + offset) / pattern_size; -} attribute vec2 a_pos; attribute vec2 a_extrude; attribute vec2 a_data; @@ -80,23 +26,6 @@ void main() { )MBGL_SHADER"; const char* collision_box::fragmentSource = R"MBGL_SHADER( -#ifdef GL_ES -precision mediump float; -#else - -#if !defined(lowp) -#define lowp -#endif - -#if !defined(mediump) -#define mediump -#endif - -#if !defined(highp) -#define highp -#endif - -#endif uniform float u_zoom; uniform float u_maxzoom; diff --git a/src/mbgl/shaders/debug.cpp b/src/mbgl/shaders/debug.cpp index 2659b2ca79..27a15698d4 100644 --- a/src/mbgl/shaders/debug.cpp +++ b/src/mbgl/shaders/debug.cpp @@ -7,60 +7,6 @@ namespace shaders { const char* debug::name = "debug"; const char* debug::vertexSource = R"MBGL_SHADER( -#ifdef GL_ES -precision highp float; -#else - -#if !defined(lowp) -#define lowp -#endif - -#if !defined(mediump) -#define mediump -#endif - -#if !defined(highp) -#define highp -#endif - -#endif - -float evaluate_zoom_function_1(const vec4 values, const float t) { - if (t < 1.0) { - return mix(values[0], values[1], t); - } else if (t < 2.0) { - return mix(values[1], values[2], t - 1.0); - } else { - return mix(values[2], values[3], t - 2.0); - } -} -vec4 evaluate_zoom_function_4(const vec4 value0, const vec4 value1, const vec4 value2, const vec4 value3, const float t) { - if (t < 1.0) { - return mix(value0, value1, t); - } else if (t < 2.0) { - return mix(value1, value2, t - 1.0); - } else { - return mix(value2, value3, t - 2.0); - } -} - -// The offset depends on how many pixels are between the world origin and the edge of the tile: -// vec2 offset = mod(pixel_coord, size) -// -// At high zoom levels there are a ton of pixels between the world origin and the edge of the tile. -// The glsl spec only guarantees 16 bits of precision for highp floats. We need more than that. -// -// The pixel_coord is passed in as two 16 bit values: -// pixel_coord_upper = floor(pixel_coord / 2^16) -// pixel_coord_lower = mod(pixel_coord, 2^16) -// -// The offset is calculated in a series of steps that should preserve this precision: -vec2 get_pattern_pos(const vec2 pixel_coord_upper, const vec2 pixel_coord_lower, - const vec2 pattern_size, const float tile_units_to_pixels, const vec2 pos) { - - vec2 offset = mod(mod(mod(pixel_coord_upper, pattern_size) * 256.0, pattern_size) * 256.0 + pixel_coord_lower, pattern_size); - return (tile_units_to_pixels * pos + offset) / pattern_size; -} attribute vec2 a_pos; uniform mat4 u_matrix; @@ -71,23 +17,6 @@ void main() { )MBGL_SHADER"; const char* debug::fragmentSource = R"MBGL_SHADER( -#ifdef GL_ES -precision mediump float; -#else - -#if !defined(lowp) -#define lowp -#endif - -#if !defined(mediump) -#define mediump -#endif - -#if !defined(highp) -#define highp -#endif - -#endif uniform lowp vec4 u_color; void main() { diff --git a/src/mbgl/shaders/fill.cpp b/src/mbgl/shaders/fill.cpp index 066adee447..d0fc3a7033 100644 --- a/src/mbgl/shaders/fill.cpp +++ b/src/mbgl/shaders/fill.cpp @@ -7,60 +7,6 @@ namespace shaders { const char* fill::name = "fill"; const char* fill::vertexSource = R"MBGL_SHADER( -#ifdef GL_ES -precision highp float; -#else - -#if !defined(lowp) -#define lowp -#endif - -#if !defined(mediump) -#define mediump -#endif - -#if !defined(highp) -#define highp -#endif - -#endif - -float evaluate_zoom_function_1(const vec4 values, const float t) { - if (t < 1.0) { - return mix(values[0], values[1], t); - } else if (t < 2.0) { - return mix(values[1], values[2], t - 1.0); - } else { - return mix(values[2], values[3], t - 2.0); - } -} -vec4 evaluate_zoom_function_4(const vec4 value0, const vec4 value1, const vec4 value2, const vec4 value3, const float t) { - if (t < 1.0) { - return mix(value0, value1, t); - } else if (t < 2.0) { - return mix(value1, value2, t - 1.0); - } else { - return mix(value2, value3, t - 2.0); - } -} - -// The offset depends on how many pixels are between the world origin and the edge of the tile: -// vec2 offset = mod(pixel_coord, size) -// -// At high zoom levels there are a ton of pixels between the world origin and the edge of the tile. -// The glsl spec only guarantees 16 bits of precision for highp floats. We need more than that. -// -// The pixel_coord is passed in as two 16 bit values: -// pixel_coord_upper = floor(pixel_coord / 2^16) -// pixel_coord_lower = mod(pixel_coord, 2^16) -// -// The offset is calculated in a series of steps that should preserve this precision: -vec2 get_pattern_pos(const vec2 pixel_coord_upper, const vec2 pixel_coord_lower, - const vec2 pattern_size, const float tile_units_to_pixels, const vec2 pos) { - - vec2 offset = mod(mod(mod(pixel_coord_upper, pattern_size) * 256.0, pattern_size) * 256.0 + pixel_coord_lower, pattern_size); - return (tile_units_to_pixels * pos + offset) / pattern_size; -} attribute vec2 a_pos; uniform mat4 u_matrix; @@ -83,23 +29,6 @@ void main() { )MBGL_SHADER"; const char* fill::fragmentSource = R"MBGL_SHADER( -#ifdef GL_ES -precision mediump float; -#else - -#if !defined(lowp) -#define lowp -#endif - -#if !defined(mediump) -#define mediump -#endif - -#if !defined(highp) -#define highp -#endif - -#endif varying lowp vec4 color; varying lowp float opacity; diff --git a/src/mbgl/shaders/fill_outline.cpp b/src/mbgl/shaders/fill_outline.cpp index 0f0f3806a9..d6f8d63715 100644 --- a/src/mbgl/shaders/fill_outline.cpp +++ b/src/mbgl/shaders/fill_outline.cpp @@ -7,60 +7,6 @@ namespace shaders { const char* fill_outline::name = "fill_outline"; const char* fill_outline::vertexSource = R"MBGL_SHADER( -#ifdef GL_ES -precision highp float; -#else - -#if !defined(lowp) -#define lowp -#endif - -#if !defined(mediump) -#define mediump -#endif - -#if !defined(highp) -#define highp -#endif - -#endif - -float evaluate_zoom_function_1(const vec4 values, const float t) { - if (t < 1.0) { - return mix(values[0], values[1], t); - } else if (t < 2.0) { - return mix(values[1], values[2], t - 1.0); - } else { - return mix(values[2], values[3], t - 2.0); - } -} -vec4 evaluate_zoom_function_4(const vec4 value0, const vec4 value1, const vec4 value2, const vec4 value3, const float t) { - if (t < 1.0) { - return mix(value0, value1, t); - } else if (t < 2.0) { - return mix(value1, value2, t - 1.0); - } else { - return mix(value2, value3, t - 2.0); - } -} - -// The offset depends on how many pixels are between the world origin and the edge of the tile: -// vec2 offset = mod(pixel_coord, size) -// -// At high zoom levels there are a ton of pixels between the world origin and the edge of the tile. -// The glsl spec only guarantees 16 bits of precision for highp floats. We need more than that. -// -// The pixel_coord is passed in as two 16 bit values: -// pixel_coord_upper = floor(pixel_coord / 2^16) -// pixel_coord_lower = mod(pixel_coord, 2^16) -// -// The offset is calculated in a series of steps that should preserve this precision: -vec2 get_pattern_pos(const vec2 pixel_coord_upper, const vec2 pixel_coord_lower, - const vec2 pattern_size, const float tile_units_to_pixels, const vec2 pos) { - - vec2 offset = mod(mod(mod(pixel_coord_upper, pattern_size) * 256.0, pattern_size) * 256.0 + pixel_coord_lower, pattern_size); - return (tile_units_to_pixels * pos + offset) / pattern_size; -} attribute vec2 a_pos; uniform mat4 u_matrix; @@ -87,23 +33,6 @@ void main() { )MBGL_SHADER"; const char* fill_outline::fragmentSource = R"MBGL_SHADER( -#ifdef GL_ES -precision mediump float; -#else - -#if !defined(lowp) -#define lowp -#endif - -#if !defined(mediump) -#define mediump -#endif - -#if !defined(highp) -#define highp -#endif - -#endif varying lowp vec4 outline_color; varying lowp float opacity; diff --git a/src/mbgl/shaders/fill_outline_pattern.cpp b/src/mbgl/shaders/fill_outline_pattern.cpp index 3921a83e6b..6e9d6ad9a1 100644 --- a/src/mbgl/shaders/fill_outline_pattern.cpp +++ b/src/mbgl/shaders/fill_outline_pattern.cpp @@ -7,60 +7,6 @@ namespace shaders { const char* fill_outline_pattern::name = "fill_outline_pattern"; const char* fill_outline_pattern::vertexSource = R"MBGL_SHADER( -#ifdef GL_ES -precision highp float; -#else - -#if !defined(lowp) -#define lowp -#endif - -#if !defined(mediump) -#define mediump -#endif - -#if !defined(highp) -#define highp -#endif - -#endif - -float evaluate_zoom_function_1(const vec4 values, const float t) { - if (t < 1.0) { - return mix(values[0], values[1], t); - } else if (t < 2.0) { - return mix(values[1], values[2], t - 1.0); - } else { - return mix(values[2], values[3], t - 2.0); - } -} -vec4 evaluate_zoom_function_4(const vec4 value0, const vec4 value1, const vec4 value2, const vec4 value3, const float t) { - if (t < 1.0) { - return mix(value0, value1, t); - } else if (t < 2.0) { - return mix(value1, value2, t - 1.0); - } else { - return mix(value2, value3, t - 2.0); - } -} - -// The offset depends on how many pixels are between the world origin and the edge of the tile: -// vec2 offset = mod(pixel_coord, size) -// -// At high zoom levels there are a ton of pixels between the world origin and the edge of the tile. -// The glsl spec only guarantees 16 bits of precision for highp floats. We need more than that. -// -// The pixel_coord is passed in as two 16 bit values: -// pixel_coord_upper = floor(pixel_coord / 2^16) -// pixel_coord_lower = mod(pixel_coord, 2^16) -// -// The offset is calculated in a series of steps that should preserve this precision: -vec2 get_pattern_pos(const vec2 pixel_coord_upper, const vec2 pixel_coord_lower, - const vec2 pattern_size, const float tile_units_to_pixels, const vec2 pos) { - - vec2 offset = mod(mod(mod(pixel_coord_upper, pattern_size) * 256.0, pattern_size) * 256.0 + pixel_coord_lower, pattern_size); - return (tile_units_to_pixels * pos + offset) / pattern_size; -} uniform mat4 u_matrix; uniform vec2 u_world; uniform vec2 u_pattern_size_a; @@ -95,23 +41,6 @@ void main() { )MBGL_SHADER"; const char* fill_outline_pattern::fragmentSource = R"MBGL_SHADER( -#ifdef GL_ES -precision mediump float; -#else - -#if !defined(lowp) -#define lowp -#endif - -#if !defined(mediump) -#define mediump -#endif - -#if !defined(highp) -#define highp -#endif - -#endif uniform vec2 u_pattern_tl_a; uniform vec2 u_pattern_br_a; uniform vec2 u_pattern_tl_b; diff --git a/src/mbgl/shaders/fill_pattern.cpp b/src/mbgl/shaders/fill_pattern.cpp index 822a0f7b8f..329a292eed 100644 --- a/src/mbgl/shaders/fill_pattern.cpp +++ b/src/mbgl/shaders/fill_pattern.cpp @@ -7,60 +7,6 @@ namespace shaders { const char* fill_pattern::name = "fill_pattern"; const char* fill_pattern::vertexSource = R"MBGL_SHADER( -#ifdef GL_ES -precision highp float; -#else - -#if !defined(lowp) -#define lowp -#endif - -#if !defined(mediump) -#define mediump -#endif - -#if !defined(highp) -#define highp -#endif - -#endif - -float evaluate_zoom_function_1(const vec4 values, const float t) { - if (t < 1.0) { - return mix(values[0], values[1], t); - } else if (t < 2.0) { - return mix(values[1], values[2], t - 1.0); - } else { - return mix(values[2], values[3], t - 2.0); - } -} -vec4 evaluate_zoom_function_4(const vec4 value0, const vec4 value1, const vec4 value2, const vec4 value3, const float t) { - if (t < 1.0) { - return mix(value0, value1, t); - } else if (t < 2.0) { - return mix(value1, value2, t - 1.0); - } else { - return mix(value2, value3, t - 2.0); - } -} - -// The offset depends on how many pixels are between the world origin and the edge of the tile: -// vec2 offset = mod(pixel_coord, size) -// -// At high zoom levels there are a ton of pixels between the world origin and the edge of the tile. -// The glsl spec only guarantees 16 bits of precision for highp floats. We need more than that. -// -// The pixel_coord is passed in as two 16 bit values: -// pixel_coord_upper = floor(pixel_coord / 2^16) -// pixel_coord_lower = mod(pixel_coord, 2^16) -// -// The offset is calculated in a series of steps that should preserve this precision: -vec2 get_pattern_pos(const vec2 pixel_coord_upper, const vec2 pixel_coord_lower, - const vec2 pattern_size, const float tile_units_to_pixels, const vec2 pos) { - - vec2 offset = mod(mod(mod(pixel_coord_upper, pattern_size) * 256.0, pattern_size) * 256.0 + pixel_coord_lower, pattern_size); - return (tile_units_to_pixels * pos + offset) / pattern_size; -} uniform mat4 u_matrix; uniform vec2 u_pattern_size_a; uniform vec2 u_pattern_size_b; @@ -91,23 +37,6 @@ void main() { )MBGL_SHADER"; const char* fill_pattern::fragmentSource = R"MBGL_SHADER( -#ifdef GL_ES -precision mediump float; -#else - -#if !defined(lowp) -#define lowp -#endif - -#if !defined(mediump) -#define mediump -#endif - -#if !defined(highp) -#define highp -#endif - -#endif uniform vec2 u_pattern_tl_a; uniform vec2 u_pattern_br_a; uniform vec2 u_pattern_tl_b; diff --git a/src/mbgl/shaders/line.cpp b/src/mbgl/shaders/line.cpp index 59fa9f0cf2..bd3256ad3b 100644 --- a/src/mbgl/shaders/line.cpp +++ b/src/mbgl/shaders/line.cpp @@ -7,60 +7,6 @@ namespace shaders { const char* line::name = "line"; const char* line::vertexSource = R"MBGL_SHADER( -#ifdef GL_ES -precision highp float; -#else - -#if !defined(lowp) -#define lowp -#endif - -#if !defined(mediump) -#define mediump -#endif - -#if !defined(highp) -#define highp -#endif - -#endif - -float evaluate_zoom_function_1(const vec4 values, const float t) { - if (t < 1.0) { - return mix(values[0], values[1], t); - } else if (t < 2.0) { - return mix(values[1], values[2], t - 1.0); - } else { - return mix(values[2], values[3], t - 2.0); - } -} -vec4 evaluate_zoom_function_4(const vec4 value0, const vec4 value1, const vec4 value2, const vec4 value3, const float t) { - if (t < 1.0) { - return mix(value0, value1, t); - } else if (t < 2.0) { - return mix(value1, value2, t - 1.0); - } else { - return mix(value2, value3, t - 2.0); - } -} - -// The offset depends on how many pixels are between the world origin and the edge of the tile: -// vec2 offset = mod(pixel_coord, size) -// -// At high zoom levels there are a ton of pixels between the world origin and the edge of the tile. -// The glsl spec only guarantees 16 bits of precision for highp floats. We need more than that. -// -// The pixel_coord is passed in as two 16 bit values: -// pixel_coord_upper = floor(pixel_coord / 2^16) -// pixel_coord_lower = mod(pixel_coord, 2^16) -// -// The offset is calculated in a series of steps that should preserve this precision: -vec2 get_pattern_pos(const vec2 pixel_coord_upper, const vec2 pixel_coord_lower, - const vec2 pattern_size, const float tile_units_to_pixels, const vec2 pos) { - - vec2 offset = mod(mod(mod(pixel_coord_upper, pattern_size) * 256.0, pattern_size) * 256.0 + pixel_coord_lower, pattern_size); - return (tile_units_to_pixels * pos + offset) / pattern_size; -} // the distance over which the line edge fades out. @@ -164,23 +110,6 @@ void main() { )MBGL_SHADER"; const char* line::fragmentSource = R"MBGL_SHADER( -#ifdef GL_ES -precision mediump float; -#else - -#if !defined(lowp) -#define lowp -#endif - -#if !defined(mediump) -#define mediump -#endif - -#if !defined(highp) -#define highp -#endif - -#endif varying lowp vec4 color; varying lowp float blur; varying lowp float opacity; diff --git a/src/mbgl/shaders/line_pattern.cpp b/src/mbgl/shaders/line_pattern.cpp index 7f2a31ee44..2be98deab3 100644 --- a/src/mbgl/shaders/line_pattern.cpp +++ b/src/mbgl/shaders/line_pattern.cpp @@ -7,60 +7,6 @@ namespace shaders { const char* line_pattern::name = "line_pattern"; const char* line_pattern::vertexSource = R"MBGL_SHADER( -#ifdef GL_ES -precision highp float; -#else - -#if !defined(lowp) -#define lowp -#endif - -#if !defined(mediump) -#define mediump -#endif - -#if !defined(highp) -#define highp -#endif - -#endif - -float evaluate_zoom_function_1(const vec4 values, const float t) { - if (t < 1.0) { - return mix(values[0], values[1], t); - } else if (t < 2.0) { - return mix(values[1], values[2], t - 1.0); - } else { - return mix(values[2], values[3], t - 2.0); - } -} -vec4 evaluate_zoom_function_4(const vec4 value0, const vec4 value1, const vec4 value2, const vec4 value3, const float t) { - if (t < 1.0) { - return mix(value0, value1, t); - } else if (t < 2.0) { - return mix(value1, value2, t - 1.0); - } else { - return mix(value2, value3, t - 2.0); - } -} - -// The offset depends on how many pixels are between the world origin and the edge of the tile: -// vec2 offset = mod(pixel_coord, size) -// -// At high zoom levels there are a ton of pixels between the world origin and the edge of the tile. -// The glsl spec only guarantees 16 bits of precision for highp floats. We need more than that. -// -// The pixel_coord is passed in as two 16 bit values: -// pixel_coord_upper = floor(pixel_coord / 2^16) -// pixel_coord_lower = mod(pixel_coord, 2^16) -// -// The offset is calculated in a series of steps that should preserve this precision: -vec2 get_pattern_pos(const vec2 pixel_coord_upper, const vec2 pixel_coord_lower, - const vec2 pattern_size, const float tile_units_to_pixels, const vec2 pos) { - - vec2 offset = mod(mod(mod(pixel_coord_upper, pattern_size) * 256.0, pattern_size) * 256.0 + pixel_coord_lower, pattern_size); - return (tile_units_to_pixels * pos + offset) / pattern_size; -} // floor(127 / 2) == 63.0 // the maximum allowed miter limit is 2.0 at the moment. the extrude normal is // stored in a byte (-128..127). we scale regular normals up to length 63, but @@ -163,23 +109,6 @@ void main() { )MBGL_SHADER"; const char* line_pattern::fragmentSource = R"MBGL_SHADER( -#ifdef GL_ES -precision mediump float; -#else - -#if !defined(lowp) -#define lowp -#endif - -#if !defined(mediump) -#define mediump -#endif - -#if !defined(highp) -#define highp -#endif - -#endif uniform vec2 u_pattern_size_a; uniform vec2 u_pattern_size_b; uniform vec2 u_pattern_tl_a; diff --git a/src/mbgl/shaders/line_sdf.cpp b/src/mbgl/shaders/line_sdf.cpp index 011c1c3738..5f01cf00c0 100644 --- a/src/mbgl/shaders/line_sdf.cpp +++ b/src/mbgl/shaders/line_sdf.cpp @@ -7,60 +7,6 @@ namespace shaders { const char* line_sdf::name = "line_sdf"; const char* line_sdf::vertexSource = R"MBGL_SHADER( -#ifdef GL_ES -precision highp float; -#else - -#if !defined(lowp) -#define lowp -#endif - -#if !defined(mediump) -#define mediump -#endif - -#if !defined(highp) -#define highp -#endif - -#endif - -float evaluate_zoom_function_1(const vec4 values, const float t) { - if (t < 1.0) { - return mix(values[0], values[1], t); - } else if (t < 2.0) { - return mix(values[1], values[2], t - 1.0); - } else { - return mix(values[2], values[3], t - 2.0); - } -} -vec4 evaluate_zoom_function_4(const vec4 value0, const vec4 value1, const vec4 value2, const vec4 value3, const float t) { - if (t < 1.0) { - return mix(value0, value1, t); - } else if (t < 2.0) { - return mix(value1, value2, t - 1.0); - } else { - return mix(value2, value3, t - 2.0); - } -} - -// The offset depends on how many pixels are between the world origin and the edge of the tile: -// vec2 offset = mod(pixel_coord, size) -// -// At high zoom levels there are a ton of pixels between the world origin and the edge of the tile. -// The glsl spec only guarantees 16 bits of precision for highp floats. We need more than that. -// -// The pixel_coord is passed in as two 16 bit values: -// pixel_coord_upper = floor(pixel_coord / 2^16) -// pixel_coord_lower = mod(pixel_coord, 2^16) -// -// The offset is calculated in a series of steps that should preserve this precision: -vec2 get_pattern_pos(const vec2 pixel_coord_upper, const vec2 pixel_coord_lower, - const vec2 pattern_size, const float tile_units_to_pixels, const vec2 pos) { - - vec2 offset = mod(mod(mod(pixel_coord_upper, pattern_size) * 256.0, pattern_size) * 256.0 + pixel_coord_lower, pattern_size); - return (tile_units_to_pixels * pos + offset) / pattern_size; -} // floor(127 / 2) == 63.0 // the maximum allowed miter limit is 2.0 at the moment. the extrude normal is // stored in a byte (-128..127). we scale regular normals up to length 63, but @@ -175,23 +121,6 @@ void main() { )MBGL_SHADER"; const char* line_sdf::fragmentSource = R"MBGL_SHADER( -#ifdef GL_ES -precision mediump float; -#else - -#if !defined(lowp) -#define lowp -#endif - -#if !defined(mediump) -#define mediump -#endif - -#if !defined(highp) -#define highp -#endif - -#endif uniform sampler2D u_image; uniform float u_sdfgamma; diff --git a/src/mbgl/shaders/preludes.cpp b/src/mbgl/shaders/preludes.cpp new file mode 100644 index 0000000000..a0e9414ceb --- /dev/null +++ b/src/mbgl/shaders/preludes.cpp @@ -0,0 +1,87 @@ +// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. + +#include + +namespace mbgl { +namespace shaders { + +const char* vertexPrelude = R"MBGL_SHADER( +#ifdef GL_ES +precision highp float; +#else + +#if !defined(lowp) +#define lowp +#endif + +#if !defined(mediump) +#define mediump +#endif + +#if !defined(highp) +#define highp +#endif + +#endif + +float evaluate_zoom_function_1(const vec4 values, const float t) { + if (t < 1.0) { + return mix(values[0], values[1], t); + } else if (t < 2.0) { + return mix(values[1], values[2], t - 1.0); + } else { + return mix(values[2], values[3], t - 2.0); + } +} +vec4 evaluate_zoom_function_4(const vec4 value0, const vec4 value1, const vec4 value2, const vec4 value3, const float t) { + if (t < 1.0) { + return mix(value0, value1, t); + } else if (t < 2.0) { + return mix(value1, value2, t - 1.0); + } else { + return mix(value2, value3, t - 2.0); + } +} + +// The offset depends on how many pixels are between the world origin and the edge of the tile: +// vec2 offset = mod(pixel_coord, size) +// +// At high zoom levels there are a ton of pixels between the world origin and the edge of the tile. +// The glsl spec only guarantees 16 bits of precision for highp floats. We need more than that. +// +// The pixel_coord is passed in as two 16 bit values: +// pixel_coord_upper = floor(pixel_coord / 2^16) +// pixel_coord_lower = mod(pixel_coord, 2^16) +// +// The offset is calculated in a series of steps that should preserve this precision: +vec2 get_pattern_pos(const vec2 pixel_coord_upper, const vec2 pixel_coord_lower, + const vec2 pattern_size, const float tile_units_to_pixels, const vec2 pos) { + + vec2 offset = mod(mod(mod(pixel_coord_upper, pattern_size) * 256.0, pattern_size) * 256.0 + pixel_coord_lower, pattern_size); + return (tile_units_to_pixels * pos + offset) / pattern_size; +} + +)MBGL_SHADER"; +const char* fragmentPrelude = R"MBGL_SHADER( +#ifdef GL_ES +precision mediump float; +#else + +#if !defined(lowp) +#define lowp +#endif + +#if !defined(mediump) +#define mediump +#endif + +#if !defined(highp) +#define highp +#endif + +#endif + +)MBGL_SHADER"; + +} // namespace shaders +} // namespace mbgl diff --git a/src/mbgl/shaders/preludes.hpp b/src/mbgl/shaders/preludes.hpp new file mode 100644 index 0000000000..a3abc9001f --- /dev/null +++ b/src/mbgl/shaders/preludes.hpp @@ -0,0 +1,12 @@ +// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. + +#pragma once + +namespace mbgl { +namespace shaders { + +extern const char* vertexPrelude; +extern const char* fragmentPrelude; + +} // namespace shaders +} // namespace mbgl diff --git a/src/mbgl/shaders/raster.cpp b/src/mbgl/shaders/raster.cpp index ba0aa5cd05..eb7a2db240 100644 --- a/src/mbgl/shaders/raster.cpp +++ b/src/mbgl/shaders/raster.cpp @@ -7,60 +7,6 @@ namespace shaders { const char* raster::name = "raster"; const char* raster::vertexSource = R"MBGL_SHADER( -#ifdef GL_ES -precision highp float; -#else - -#if !defined(lowp) -#define lowp -#endif - -#if !defined(mediump) -#define mediump -#endif - -#if !defined(highp) -#define highp -#endif - -#endif - -float evaluate_zoom_function_1(const vec4 values, const float t) { - if (t < 1.0) { - return mix(values[0], values[1], t); - } else if (t < 2.0) { - return mix(values[1], values[2], t - 1.0); - } else { - return mix(values[2], values[3], t - 2.0); - } -} -vec4 evaluate_zoom_function_4(const vec4 value0, const vec4 value1, const vec4 value2, const vec4 value3, const float t) { - if (t < 1.0) { - return mix(value0, value1, t); - } else if (t < 2.0) { - return mix(value1, value2, t - 1.0); - } else { - return mix(value2, value3, t - 2.0); - } -} - -// The offset depends on how many pixels are between the world origin and the edge of the tile: -// vec2 offset = mod(pixel_coord, size) -// -// At high zoom levels there are a ton of pixels between the world origin and the edge of the tile. -// The glsl spec only guarantees 16 bits of precision for highp floats. We need more than that. -// -// The pixel_coord is passed in as two 16 bit values: -// pixel_coord_upper = floor(pixel_coord / 2^16) -// pixel_coord_lower = mod(pixel_coord, 2^16) -// -// The offset is calculated in a series of steps that should preserve this precision: -vec2 get_pattern_pos(const vec2 pixel_coord_upper, const vec2 pixel_coord_lower, - const vec2 pattern_size, const float tile_units_to_pixels, const vec2 pos) { - - vec2 offset = mod(mod(mod(pixel_coord_upper, pattern_size) * 256.0, pattern_size) * 256.0 + pixel_coord_lower, pattern_size); - return (tile_units_to_pixels * pos + offset) / pattern_size; -} uniform mat4 u_matrix; uniform vec2 u_tl_parent; uniform float u_scale_parent; @@ -80,23 +26,6 @@ void main() { )MBGL_SHADER"; const char* raster::fragmentSource = R"MBGL_SHADER( -#ifdef GL_ES -precision mediump float; -#else - -#if !defined(lowp) -#define lowp -#endif - -#if !defined(mediump) -#define mediump -#endif - -#if !defined(highp) -#define highp -#endif - -#endif uniform float u_fade_t; uniform float u_opacity; uniform sampler2D u_image0; diff --git a/src/mbgl/shaders/symbol_icon.cpp b/src/mbgl/shaders/symbol_icon.cpp index e6728e15de..5945f1f3b1 100644 --- a/src/mbgl/shaders/symbol_icon.cpp +++ b/src/mbgl/shaders/symbol_icon.cpp @@ -7,60 +7,6 @@ namespace shaders { const char* symbol_icon::name = "symbol_icon"; const char* symbol_icon::vertexSource = R"MBGL_SHADER( -#ifdef GL_ES -precision highp float; -#else - -#if !defined(lowp) -#define lowp -#endif - -#if !defined(mediump) -#define mediump -#endif - -#if !defined(highp) -#define highp -#endif - -#endif - -float evaluate_zoom_function_1(const vec4 values, const float t) { - if (t < 1.0) { - return mix(values[0], values[1], t); - } else if (t < 2.0) { - return mix(values[1], values[2], t - 1.0); - } else { - return mix(values[2], values[3], t - 2.0); - } -} -vec4 evaluate_zoom_function_4(const vec4 value0, const vec4 value1, const vec4 value2, const vec4 value3, const float t) { - if (t < 1.0) { - return mix(value0, value1, t); - } else if (t < 2.0) { - return mix(value1, value2, t - 1.0); - } else { - return mix(value2, value3, t - 2.0); - } -} - -// The offset depends on how many pixels are between the world origin and the edge of the tile: -// vec2 offset = mod(pixel_coord, size) -// -// At high zoom levels there are a ton of pixels between the world origin and the edge of the tile. -// The glsl spec only guarantees 16 bits of precision for highp floats. We need more than that. -// -// The pixel_coord is passed in as two 16 bit values: -// pixel_coord_upper = floor(pixel_coord / 2^16) -// pixel_coord_lower = mod(pixel_coord, 2^16) -// -// The offset is calculated in a series of steps that should preserve this precision: -vec2 get_pattern_pos(const vec2 pixel_coord_upper, const vec2 pixel_coord_lower, - const vec2 pattern_size, const float tile_units_to_pixels, const vec2 pos) { - - vec2 offset = mod(mod(mod(pixel_coord_upper, pattern_size) * 256.0, pattern_size) * 256.0 + pixel_coord_lower, pattern_size); - return (tile_units_to_pixels * pos + offset) / pattern_size; -} attribute vec2 a_pos; attribute vec2 a_offset; attribute vec2 a_texture_pos; @@ -109,23 +55,6 @@ void main() { )MBGL_SHADER"; const char* symbol_icon::fragmentSource = R"MBGL_SHADER( -#ifdef GL_ES -precision mediump float; -#else - -#if !defined(lowp) -#define lowp -#endif - -#if !defined(mediump) -#define mediump -#endif - -#if !defined(highp) -#define highp -#endif - -#endif uniform sampler2D u_texture; uniform sampler2D u_fadetexture; diff --git a/src/mbgl/shaders/symbol_sdf.cpp b/src/mbgl/shaders/symbol_sdf.cpp index e087242bf8..ccb4b9cee6 100644 --- a/src/mbgl/shaders/symbol_sdf.cpp +++ b/src/mbgl/shaders/symbol_sdf.cpp @@ -7,60 +7,6 @@ namespace shaders { const char* symbol_sdf::name = "symbol_sdf"; const char* symbol_sdf::vertexSource = R"MBGL_SHADER( -#ifdef GL_ES -precision highp float; -#else - -#if !defined(lowp) -#define lowp -#endif - -#if !defined(mediump) -#define mediump -#endif - -#if !defined(highp) -#define highp -#endif - -#endif - -float evaluate_zoom_function_1(const vec4 values, const float t) { - if (t < 1.0) { - return mix(values[0], values[1], t); - } else if (t < 2.0) { - return mix(values[1], values[2], t - 1.0); - } else { - return mix(values[2], values[3], t - 2.0); - } -} -vec4 evaluate_zoom_function_4(const vec4 value0, const vec4 value1, const vec4 value2, const vec4 value3, const float t) { - if (t < 1.0) { - return mix(value0, value1, t); - } else if (t < 2.0) { - return mix(value1, value2, t - 1.0); - } else { - return mix(value2, value3, t - 2.0); - } -} - -// The offset depends on how many pixels are between the world origin and the edge of the tile: -// vec2 offset = mod(pixel_coord, size) -// -// At high zoom levels there are a ton of pixels between the world origin and the edge of the tile. -// The glsl spec only guarantees 16 bits of precision for highp floats. We need more than that. -// -// The pixel_coord is passed in as two 16 bit values: -// pixel_coord_upper = floor(pixel_coord / 2^16) -// pixel_coord_lower = mod(pixel_coord, 2^16) -// -// The offset is calculated in a series of steps that should preserve this precision: -vec2 get_pattern_pos(const vec2 pixel_coord_upper, const vec2 pixel_coord_lower, - const vec2 pattern_size, const float tile_units_to_pixels, const vec2 pos) { - - vec2 offset = mod(mod(mod(pixel_coord_upper, pattern_size) * 256.0, pattern_size) * 256.0 + pixel_coord_lower, pattern_size); - return (tile_units_to_pixels * pos + offset) / pattern_size; -} const float PI = 3.141592653589793; attribute vec2 a_pos; @@ -172,23 +118,6 @@ void main() { )MBGL_SHADER"; const char* symbol_sdf::fragmentSource = R"MBGL_SHADER( -#ifdef GL_ES -precision mediump float; -#else - -#if !defined(lowp) -#define lowp -#endif - -#if !defined(mediump) -#define mediump -#endif - -#if !defined(highp) -#define highp -#endif - -#endif #define SDF_PX 8.0 #define EDGE_GAMMA 0.105/DEVICE_PIXEL_RATIO -- cgit v1.2.1 From 3afae825c7b2f95e58cbcb85c59857f2253c945e Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Tue, 7 Mar 2017 16:41:23 -0800 Subject: Use ICU compiled with -Os --- platform/android/config.cmake | 2 +- platform/ios/config.cmake | 2 +- platform/linux/config.cmake | 2 +- platform/macos/config.cmake | 2 +- platform/qt/config.cmake | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/android/config.cmake b/platform/android/config.cmake index c27e6e0b93..3dd8e7f67d 100644 --- a/platform/android/config.cmake +++ b/platform/android/config.cmake @@ -20,7 +20,7 @@ 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.8.0) -mason_use(icu VERSION 58.1) +mason_use(icu VERSION 58.1-min-size) set(ANDROID_SDK_PROJECT_DIR ${CMAKE_SOURCE_DIR}/platform/android/MapboxGLAndroidSDK) set(ANDROID_JNI_TARGET_DIR ${ANDROID_SDK_PROJECT_DIR}/src/main/jniLibs/${ANDROID_ABI}) diff --git a/platform/ios/config.cmake b/platform/ios/config.cmake index 72e1c88525..cab8fd1357 100644 --- a/platform/ios/config.cmake +++ b/platform/ios/config.cmake @@ -1,6 +1,6 @@ add_definitions(-DMBGL_USE_GLES2=1) -mason_use(icu VERSION 58.1) +mason_use(icu VERSION 58.1-min-size) macro(mbgl_platform_core) set_xcode_property(mbgl-core IPHONEOS_DEPLOYMENT_TARGET "8.0") diff --git a/platform/linux/config.cmake b/platform/linux/config.cmake index b2366540ae..ff2dcf4cfa 100644 --- a/platform/linux/config.cmake +++ b/platform/linux/config.cmake @@ -9,7 +9,7 @@ mason_use(libjpeg-turbo VERSION 1.5.0) mason_use(webp VERSION 0.5.1) mason_use(gtest VERSION 1.8.0${MASON_CXXABI_SUFFIX}) mason_use(benchmark VERSION 1.0.0-1) -mason_use(icu VERSION 58.1) +mason_use(icu VERSION 58.1-min-size) include(cmake/loop-uv.cmake) diff --git a/platform/macos/config.cmake b/platform/macos/config.cmake index 309d8e82f3..cbaf3d492e 100644 --- a/platform/macos/config.cmake +++ b/platform/macos/config.cmake @@ -4,7 +4,7 @@ mason_use(glfw VERSION 2017-02-09-77a8f10) mason_use(boost_libprogram_options VERSION 1.62.0) mason_use(gtest VERSION 1.8.0) mason_use(benchmark VERSION 1.0.0-1) -mason_use(icu VERSION 58.1) +mason_use(icu VERSION 58.1-min-size) include(cmake/loop-darwin.cmake) diff --git a/platform/qt/config.cmake b/platform/qt/config.cmake index 4563f03a9b..0f2bab0516 100644 --- a/platform/qt/config.cmake +++ b/platform/qt/config.cmake @@ -10,7 +10,7 @@ if(NOT WITH_QT_DECODERS) endif() if(NOT WITH_QT_I18N) - mason_use(icu VERSION 58.1) + mason_use(icu VERSION 58.1-min-size) endif() macro(mbgl_platform_core) -- cgit v1.2.1 From 692f5e0a9f5321ee2932a976a8eb9e0a83fc3352 Mon Sep 17 00:00:00 2001 From: Molly Lloyd Date: Wed, 1 Mar 2017 11:28:31 -0800 Subject: Pack min + max into one attribute :muscle: Some devices supported by Mapbox GL provide only 8 vertex attributes; this change packs existing attributes to get us just under that limit. For properties using a composite function, pack the min and max values into a single attribute with two logical components instead of using two separate attributes and buffers. Special logic is included for color attributes, whose integer components must be packed into the available bits of floating-point attributes. (We don't have access to ivec types in GL ES 2.0.) For source functions, continue to bind just a one-component attribute even though the GLSL type is vec2 (or vec4 for colors). The type-checking done by gl::Attribute is relaxed slightly to accommodate this. --- mapbox-gl-js | 2 +- scripts/generate-shaders.js | 7 +- src/mbgl/gl/attribute.cpp | 2 +- src/mbgl/gl/attribute.hpp | 46 ++++++++--- src/mbgl/programs/attributes.hpp | 96 ++++++++++++----------- src/mbgl/programs/symbol_program.hpp | 8 +- src/mbgl/shaders/circle.cpp | 35 ++++----- src/mbgl/shaders/fill.cpp | 10 +-- src/mbgl/shaders/fill_outline.cpp | 10 +-- src/mbgl/shaders/fill_outline_pattern.cpp | 5 +- src/mbgl/shaders/fill_pattern.cpp | 5 +- src/mbgl/shaders/line.cpp | 25 +++--- src/mbgl/shaders/line_pattern.cpp | 20 ++--- src/mbgl/shaders/line_sdf.cpp | 25 +++--- src/mbgl/shaders/preludes.cpp | 25 ++++++ src/mbgl/shaders/symbol_icon.cpp | 12 +-- src/mbgl/shaders/symbol_sdf.cpp | 31 ++++---- src/mbgl/style/paint_property_binder.hpp | 123 +++++++++++------------------- 18 files changed, 239 insertions(+), 248 deletions(-) diff --git a/mapbox-gl-js b/mapbox-gl-js index f9c5c17592..69bb05cef2 160000 --- a/mapbox-gl-js +++ b/mapbox-gl-js @@ -1 +1 @@ -Subproject commit f9c5c175926278a24f1b0d958867632023773ede +Subproject commit 69bb05cef27c99722f6616867032d64b5f12ee57 diff --git a/scripts/generate-shaders.js b/scripts/generate-shaders.js index 892620cf21..cffe9d3854 100755 --- a/scripts/generate-shaders.js +++ b/scripts/generate-shaders.js @@ -60,9 +60,11 @@ ${fragmentPrelude} ].forEach(function (shaderName) { function applyPragmas(source, pragmas) { return source.replace(/#pragma mapbox: ([\w]+) ([\w]+) ([\w]+) ([\w]+)/g, (match, operation, precision, type, name) => { + const a_type = type === "float" ? "vec2" : "vec4"; return pragmas[operation] .join("\n") .replace(/\{type\}/g, type) + .replace(/\{a_type}/g, a_type) .replace(/\{precision\}/g, precision) .replace(/\{name\}/g, name); }); @@ -73,12 +75,11 @@ ${fragmentPrelude} return applyPragmas(source, { define: [ "uniform lowp float a_{name}_t;", - "attribute {precision} {type} a_{name}_min;", - "attribute {precision} {type} a_{name}_max;", + "attribute {precision} {a_type} a_{name};", "varying {precision} {type} {name};" ], initialize: [ - "{name} = mix(a_{name}_min, a_{name}_max, a_{name}_t);" + "{name} = unpack_mix_{a_type}(a_{name}, a_{name}_t);" ] }); } diff --git a/src/mbgl/gl/attribute.cpp b/src/mbgl/gl/attribute.cpp index 2c16dac3fc..ff313fdcd0 100644 --- a/src/mbgl/gl/attribute.cpp +++ b/src/mbgl/gl/attribute.cpp @@ -38,7 +38,7 @@ void VariableAttributeBinding::bind(Context& context, MBGL_CHECK_ERROR(glEnableVertexAttribArray(location)); MBGL_CHECK_ERROR(glVertexAttribPointer( location, - static_cast(N), + static_cast(attributeSize), static_cast(DataTypeOf), static_cast(IsNormalized), static_cast(vertexSize), diff --git a/src/mbgl/gl/attribute.hpp b/src/mbgl/gl/attribute.hpp index 6300ebb56b..43e2c2d794 100644 --- a/src/mbgl/gl/attribute.hpp +++ b/src/mbgl/gl/attribute.hpp @@ -17,10 +17,12 @@ class VariableAttributeBinding { public: VariableAttributeBinding(BufferID vertexBuffer_, std::size_t vertexSize_, - std::size_t attributeOffset_) + std::size_t attributeOffset_, + std::size_t attributeSize_ = N) : vertexBuffer(vertexBuffer_), vertexSize(vertexSize_), - attributeOffset(attributeOffset_) + attributeOffset(attributeOffset_), + attributeSize(attributeSize_) {} void bind(Context&, AttributeLocation, optional>&, std::size_t vertexOffset) const; @@ -29,13 +31,15 @@ public: const VariableAttributeBinding& rhs) { return lhs.vertexBuffer == rhs.vertexBuffer && lhs.vertexSize == rhs.vertexSize - && lhs.attributeOffset == rhs.attributeOffset; + && lhs.attributeOffset == rhs.attributeOffset + && lhs.attributeSize == rhs.attributeSize; } private: BufferID vertexBuffer; std::size_t vertexSize; std::size_t attributeOffset; + std::size_t attributeSize; }; template @@ -58,9 +62,16 @@ private: std::array value; }; +/* + gl::Attribute manages the binding of a constant value or vertex buffer to a GL program attribute. + - T is the underlying primitive type (exposed as Attribute::ValueType) + - N is the number of components in the attribute declared in the shader (exposed as Attribute::Dimensions) +*/ template class Attribute { public: + using ValueType = T; + static constexpr size_t Dimensions = N; using Value = std::array; using VariableBinding = VariableAttributeBinding; @@ -72,6 +83,25 @@ public: ConstantBinding, VariableBinding>; + /* + Create a variable (i.e. data-driven) binding for this attribute. The `attributeSize` + parameter may be used to override the number of components available in the buffer for + each vertex. Thus, a buffer with only one float for each vertex can be bound to a + `vec2` attribute + */ + template + static VariableBinding variableBinding(const VertexBuffer& buffer, + std::size_t attributeIndex, + std::size_t attributeSize = N) { + static_assert(std::is_standard_layout::value, "vertex type must use standard layout"); + return VariableBinding { + buffer.buffer, + sizeof(Vertex), + Vertex::attributeOffsets[attributeIndex], + attributeSize + }; + } + static void bind(Context& context, const Location& location, optional& oldBinding, @@ -223,15 +253,7 @@ public: template static Bindings allVariableBindings(const VertexBuffer& buffer) { - static_assert(std::is_standard_layout::value, "vertex type must use standard layout"); - - return Bindings { - typename As::VariableBinding { - buffer.buffer, - sizeof(Vertex), - Vertex::attributeOffsets[Index] - }... - }; + return Bindings { As::variableBinding(buffer, Index)... }; } static void bind(Context& context, diff --git a/src/mbgl/programs/attributes.hpp b/src/mbgl/programs/attributes.hpp index bb90f2c13c..a2e0772762 100644 --- a/src/mbgl/programs/attributes.hpp +++ b/src/mbgl/programs/attributes.hpp @@ -13,6 +13,7 @@ namespace attributes { MBGL_DEFINE_ATTRIBUTE(int16_t, 2, a_pos); MBGL_DEFINE_ATTRIBUTE(int16_t, 2, a_extrude); +MBGL_DEFINE_ATTRIBUTE(int16_t, 4, a_pos_offset); MBGL_DEFINE_ATTRIBUTE(uint16_t, 2, a_texture_pos); template @@ -27,19 +28,30 @@ struct a_offset : gl::Attribute { // Paint attributes +/* + ZoomInterpolatedAttribute is a 'compound' attribute, representing two values of the + the base attribute Attr. These two values are provided to the shader to allow interpolation + between zoom levels, without the need to repopulate vertex buffers each frame as the map is + being zoomed. +*/ template -struct Min : Attr { - static auto name() { - static const std::string name = Attr::name() + std::string("_min"); - return name.c_str(); - } -}; +struct ZoomInterpolatedAttribute : gl::Attribute { + using Value = typename gl::Attribute::Value; -template -struct Max : Attr { static auto name() { - static const std::string name = Attr::name() + std::string("_max"); - return name.c_str(); + return Attr::name(); + } + + template + static Value value(const InputType& min, const InputType& max){ + auto minValue = Attr::value(min); + auto maxValue = Attr::value(max); + Value result = {{}}; + for (size_t i = 0; i < Attr::Dimensions; i++) { + result[i] = minValue[i]; + result[Attr::Dimensions+i] = maxValue[i]; + } + return result; } }; @@ -51,70 +63,62 @@ struct InterpolationUniform : gl::UniformScalar, floa } }; -struct a_color : gl::Attribute, 4> { +/* + Encode a four-component color value into a pair of floats. Since csscolorparser + uses 8-bit precision for each color component, for each float we use the upper 8 + bits for one component (e.g. (color.r * 255) * 256), and the lower 8 for another. + + Also note: + - Colors come in as floats 0..1, so we scale by 255. + - Casting the scaled values to ints is important: without doing this, e.g., the + fractional part of the `r` component would corrupt the lower-8 bits of the encoded + value, which must be reserved for the `g` component. +*/ +static std::array encodeColor (const Color& color) { + const auto v1 = static_cast( static_cast(color.r*255)*256 + color.g*255); + const auto v2 = static_cast( static_cast(color.b*255)*256 + color.a*255); + return {{ static_cast(v1), static_cast(v2) }}; +} + +struct a_color : gl::Attribute { static auto name() { return "a_color"; } static Value value(const Color& color) { - return {{ - gl::Normalized(color.r), - gl::Normalized(color.g), - gl::Normalized(color.b), - gl::Normalized(color.a) - }}; + return encodeColor(color); } }; // used in the symbol sdf shader -struct a_fill_color : gl::Attribute, 4> { +struct a_fill_color : gl::Attribute { static auto name() { return "a_fill_color"; } static Value value(const Color& color) { - return {{ - gl::Normalized(color.r), - gl::Normalized(color.g), - gl::Normalized(color.b), - gl::Normalized(color.a) - }}; + return encodeColor(color); } }; // used in the symbol sdf shader -struct a_halo_color : gl::Attribute, 4> { +struct a_halo_color : gl::Attribute { static auto name() { return "a_halo_color"; } - static Value value(const Color& color) { - return {{ - gl::Normalized(color.r), - gl::Normalized(color.g), - gl::Normalized(color.b), - gl::Normalized(color.a) - }}; + static Value value(const Color& color) { + return encodeColor(color); } }; -struct a_stroke_color : gl::Attribute, 4> { +struct a_stroke_color : gl::Attribute { static auto name() { return "a_stroke_color"; } static Value value(const Color& color) { - return {{ - gl::Normalized(color.r), - gl::Normalized(color.g), - gl::Normalized(color.b), - gl::Normalized(color.a) - }}; + return encodeColor(color); } }; -struct a_outline_color : gl::Attribute, 4> { +struct a_outline_color : gl::Attribute { static auto name() { return "a_outline_color"; } static Value value(const Color& color) { - return {{ - gl::Normalized(color.r), - gl::Normalized(color.g), - gl::Normalized(color.b), - gl::Normalized(color.a) - }}; + return encodeColor(color); } }; diff --git a/src/mbgl/programs/symbol_program.hpp b/src/mbgl/programs/symbol_program.hpp index 0537c25a2c..fdd1aa5c3b 100644 --- a/src/mbgl/programs/symbol_program.hpp +++ b/src/mbgl/programs/symbol_program.hpp @@ -35,8 +35,7 @@ MBGL_DEFINE_UNIFORM_SCALAR(float, u_gamma_scale); } // namespace uniforms struct SymbolLayoutAttributes : gl::Attributes< - attributes::a_pos, - attributes::a_offset<2>, + attributes::a_pos_offset, attributes::a_texture_pos, attributes::a_data<4>> { @@ -49,11 +48,10 @@ struct SymbolLayoutAttributes : gl::Attributes< float labelminzoom, uint8_t labelangle) { return Vertex { + // combining pos and offset to reduce number of vertex attributes passed to shader (8 max for some devices) {{ static_cast(a.x), - static_cast(a.y) - }}, - {{ + static_cast(a.y), static_cast(::round(o.x * 64)), // use 1/64 pixels for placement static_cast(::round(o.y * 64)) }}, diff --git a/src/mbgl/shaders/circle.cpp b/src/mbgl/shaders/circle.cpp index 4b2bb7cecf..b479f1d40c 100644 --- a/src/mbgl/shaders/circle.cpp +++ b/src/mbgl/shaders/circle.cpp @@ -14,45 +14,38 @@ uniform vec2 u_extrude_scale; attribute vec2 a_pos; uniform lowp float a_color_t; -attribute lowp vec4 a_color_min; -attribute lowp vec4 a_color_max; +attribute lowp vec4 a_color; varying lowp vec4 color; uniform lowp float a_radius_t; -attribute mediump float a_radius_min; -attribute mediump float a_radius_max; +attribute mediump vec2 a_radius; varying mediump float radius; uniform lowp float a_blur_t; -attribute lowp float a_blur_min; -attribute lowp float a_blur_max; +attribute lowp vec2 a_blur; varying lowp float blur; uniform lowp float a_opacity_t; -attribute lowp float a_opacity_min; -attribute lowp float a_opacity_max; +attribute lowp vec2 a_opacity; varying lowp float opacity; uniform lowp float a_stroke_color_t; -attribute lowp vec4 a_stroke_color_min; -attribute lowp vec4 a_stroke_color_max; +attribute lowp vec4 a_stroke_color; varying lowp vec4 stroke_color; uniform lowp float a_stroke_width_t; -attribute mediump float a_stroke_width_min; -attribute mediump float a_stroke_width_max; +attribute mediump vec2 a_stroke_width; varying mediump float stroke_width; uniform lowp float a_stroke_opacity_t; -attribute lowp float a_stroke_opacity_min; -attribute lowp float a_stroke_opacity_max; +attribute lowp vec2 a_stroke_opacity; varying lowp float stroke_opacity; varying vec2 v_extrude; varying lowp float v_antialiasblur; void main(void) { - color = mix(a_color_min, a_color_max, a_color_t); - radius = mix(a_radius_min, a_radius_max, a_radius_t); - blur = mix(a_blur_min, a_blur_max, a_blur_t); - opacity = mix(a_opacity_min, a_opacity_max, a_opacity_t); - stroke_color = mix(a_stroke_color_min, a_stroke_color_max, a_stroke_color_t); - stroke_width = mix(a_stroke_width_min, a_stroke_width_max, a_stroke_width_t); - stroke_opacity = mix(a_stroke_opacity_min, a_stroke_opacity_max, a_stroke_opacity_t); + color = unpack_mix_vec4(a_color, a_color_t); + radius = unpack_mix_vec2(a_radius, a_radius_t); + blur = unpack_mix_vec2(a_blur, a_blur_t); + opacity = unpack_mix_vec2(a_opacity, a_opacity_t); + stroke_color = unpack_mix_vec4(a_stroke_color, a_stroke_color_t); + stroke_width = unpack_mix_vec2(a_stroke_width, a_stroke_width_t); + stroke_opacity = unpack_mix_vec2(a_stroke_opacity, a_stroke_opacity_t); // unencode the extrusion vector that we snuck into the a_pos vector v_extrude = vec2(mod(a_pos, 2.0) * 2.0 - 1.0); diff --git a/src/mbgl/shaders/fill.cpp b/src/mbgl/shaders/fill.cpp index d0fc3a7033..a1fba4d749 100644 --- a/src/mbgl/shaders/fill.cpp +++ b/src/mbgl/shaders/fill.cpp @@ -12,17 +12,15 @@ attribute vec2 a_pos; uniform mat4 u_matrix; uniform lowp float a_color_t; -attribute lowp vec4 a_color_min; -attribute lowp vec4 a_color_max; +attribute lowp vec4 a_color; varying lowp vec4 color; uniform lowp float a_opacity_t; -attribute lowp float a_opacity_min; -attribute lowp float a_opacity_max; +attribute lowp vec2 a_opacity; varying lowp float opacity; void main() { - color = mix(a_color_min, a_color_max, a_color_t); - opacity = mix(a_opacity_min, a_opacity_max, a_opacity_t); + color = unpack_mix_vec4(a_color, a_color_t); + opacity = unpack_mix_vec2(a_opacity, a_opacity_t); gl_Position = u_matrix * vec4(a_pos, 0, 1); } diff --git a/src/mbgl/shaders/fill_outline.cpp b/src/mbgl/shaders/fill_outline.cpp index d6f8d63715..74201b518d 100644 --- a/src/mbgl/shaders/fill_outline.cpp +++ b/src/mbgl/shaders/fill_outline.cpp @@ -15,17 +15,15 @@ uniform vec2 u_world; varying vec2 v_pos; uniform lowp float a_outline_color_t; -attribute lowp vec4 a_outline_color_min; -attribute lowp vec4 a_outline_color_max; +attribute lowp vec4 a_outline_color; varying lowp vec4 outline_color; uniform lowp float a_opacity_t; -attribute lowp float a_opacity_min; -attribute lowp float a_opacity_max; +attribute lowp vec2 a_opacity; varying lowp float opacity; void main() { - outline_color = mix(a_outline_color_min, a_outline_color_max, a_outline_color_t); - opacity = mix(a_opacity_min, a_opacity_max, a_opacity_t); + outline_color = unpack_mix_vec4(a_outline_color, a_outline_color_t); + opacity = unpack_mix_vec2(a_opacity, a_opacity_t); gl_Position = u_matrix * vec4(a_pos, 0, 1); v_pos = (gl_Position.xy / gl_Position.w + 1.0) / 2.0 * u_world; diff --git a/src/mbgl/shaders/fill_outline_pattern.cpp b/src/mbgl/shaders/fill_outline_pattern.cpp index 6e9d6ad9a1..5e38023382 100644 --- a/src/mbgl/shaders/fill_outline_pattern.cpp +++ b/src/mbgl/shaders/fill_outline_pattern.cpp @@ -24,12 +24,11 @@ varying vec2 v_pos_b; varying vec2 v_pos; uniform lowp float a_opacity_t; -attribute lowp float a_opacity_min; -attribute lowp float a_opacity_max; +attribute lowp vec2 a_opacity; varying lowp float opacity; void main() { - opacity = mix(a_opacity_min, a_opacity_max, a_opacity_t); + opacity = unpack_mix_vec2(a_opacity, a_opacity_t); gl_Position = u_matrix * vec4(a_pos, 0, 1); diff --git a/src/mbgl/shaders/fill_pattern.cpp b/src/mbgl/shaders/fill_pattern.cpp index 329a292eed..0357fed40e 100644 --- a/src/mbgl/shaders/fill_pattern.cpp +++ b/src/mbgl/shaders/fill_pattern.cpp @@ -22,12 +22,11 @@ varying vec2 v_pos_a; varying vec2 v_pos_b; uniform lowp float a_opacity_t; -attribute lowp float a_opacity_min; -attribute lowp float a_opacity_max; +attribute lowp vec2 a_opacity; varying lowp float opacity; void main() { - opacity = mix(a_opacity_min, a_opacity_max, a_opacity_t); + opacity = unpack_mix_vec2(a_opacity, a_opacity_t); gl_Position = u_matrix * vec4(a_pos, 0, 1); diff --git a/src/mbgl/shaders/line.cpp b/src/mbgl/shaders/line.cpp index bd3256ad3b..dc4aa774dc 100644 --- a/src/mbgl/shaders/line.cpp +++ b/src/mbgl/shaders/line.cpp @@ -34,32 +34,27 @@ varying vec2 v_width2; varying float v_gamma_scale; uniform lowp float a_color_t; -attribute lowp vec4 a_color_min; -attribute lowp vec4 a_color_max; +attribute lowp vec4 a_color; varying lowp vec4 color; uniform lowp float a_blur_t; -attribute lowp float a_blur_min; -attribute lowp float a_blur_max; +attribute lowp vec2 a_blur; varying lowp float blur; uniform lowp float a_opacity_t; -attribute lowp float a_opacity_min; -attribute lowp float a_opacity_max; +attribute lowp vec2 a_opacity; varying lowp float opacity; uniform lowp float a_gapwidth_t; -attribute mediump float a_gapwidth_min; -attribute mediump float a_gapwidth_max; +attribute mediump vec2 a_gapwidth; varying mediump float gapwidth; uniform lowp float a_offset_t; -attribute lowp float a_offset_min; -attribute lowp float a_offset_max; +attribute lowp vec2 a_offset; varying lowp float offset; void main() { - color = mix(a_color_min, a_color_max, a_color_t); - blur = mix(a_blur_min, a_blur_max, a_blur_t); - opacity = mix(a_opacity_min, a_opacity_max, a_opacity_t); - gapwidth = mix(a_gapwidth_min, a_gapwidth_max, a_gapwidth_t); - offset = mix(a_offset_min, a_offset_max, a_offset_t); + color = unpack_mix_vec4(a_color, a_color_t); + blur = unpack_mix_vec2(a_blur, a_blur_t); + opacity = unpack_mix_vec2(a_opacity, a_opacity_t); + gapwidth = unpack_mix_vec2(a_gapwidth, a_gapwidth_t); + offset = unpack_mix_vec2(a_offset, a_offset_t); vec2 a_extrude = a_data.xy - 128.0; float a_direction = mod(a_data.z, 4.0) - 1.0; diff --git a/src/mbgl/shaders/line_pattern.cpp b/src/mbgl/shaders/line_pattern.cpp index 2be98deab3..f52a8e2157 100644 --- a/src/mbgl/shaders/line_pattern.cpp +++ b/src/mbgl/shaders/line_pattern.cpp @@ -37,27 +37,23 @@ varying float v_linesofar; varying float v_gamma_scale; uniform lowp float a_blur_t; -attribute lowp float a_blur_min; -attribute lowp float a_blur_max; +attribute lowp vec2 a_blur; varying lowp float blur; uniform lowp float a_opacity_t; -attribute lowp float a_opacity_min; -attribute lowp float a_opacity_max; +attribute lowp vec2 a_opacity; varying lowp float opacity; uniform lowp float a_offset_t; -attribute lowp float a_offset_min; -attribute lowp float a_offset_max; +attribute lowp vec2 a_offset; varying lowp float offset; uniform lowp float a_gapwidth_t; -attribute mediump float a_gapwidth_min; -attribute mediump float a_gapwidth_max; +attribute mediump vec2 a_gapwidth; varying mediump float gapwidth; void main() { - blur = mix(a_blur_min, a_blur_max, a_blur_t); - opacity = mix(a_opacity_min, a_opacity_max, a_opacity_t); - offset = mix(a_offset_min, a_offset_max, a_offset_t); - gapwidth = mix(a_gapwidth_min, a_gapwidth_max, a_gapwidth_t); + blur = unpack_mix_vec2(a_blur, a_blur_t); + opacity = unpack_mix_vec2(a_opacity, a_opacity_t); + offset = unpack_mix_vec2(a_offset, a_offset_t); + gapwidth = unpack_mix_vec2(a_gapwidth, a_gapwidth_t); vec2 a_extrude = a_data.xy - 128.0; float a_direction = mod(a_data.z, 4.0) - 1.0; diff --git a/src/mbgl/shaders/line_sdf.cpp b/src/mbgl/shaders/line_sdf.cpp index 5f01cf00c0..cd0d4ac318 100644 --- a/src/mbgl/shaders/line_sdf.cpp +++ b/src/mbgl/shaders/line_sdf.cpp @@ -42,32 +42,27 @@ varying vec2 v_tex_b; varying float v_gamma_scale; uniform lowp float a_color_t; -attribute lowp vec4 a_color_min; -attribute lowp vec4 a_color_max; +attribute lowp vec4 a_color; varying lowp vec4 color; uniform lowp float a_blur_t; -attribute lowp float a_blur_min; -attribute lowp float a_blur_max; +attribute lowp vec2 a_blur; varying lowp float blur; uniform lowp float a_opacity_t; -attribute lowp float a_opacity_min; -attribute lowp float a_opacity_max; +attribute lowp vec2 a_opacity; varying lowp float opacity; uniform lowp float a_gapwidth_t; -attribute mediump float a_gapwidth_min; -attribute mediump float a_gapwidth_max; +attribute mediump vec2 a_gapwidth; varying mediump float gapwidth; uniform lowp float a_offset_t; -attribute lowp float a_offset_min; -attribute lowp float a_offset_max; +attribute lowp vec2 a_offset; varying lowp float offset; void main() { - color = mix(a_color_min, a_color_max, a_color_t); - blur = mix(a_blur_min, a_blur_max, a_blur_t); - opacity = mix(a_opacity_min, a_opacity_max, a_opacity_t); - gapwidth = mix(a_gapwidth_min, a_gapwidth_max, a_gapwidth_t); - offset = mix(a_offset_min, a_offset_max, a_offset_t); + color = unpack_mix_vec4(a_color, a_color_t); + blur = unpack_mix_vec2(a_blur, a_blur_t); + opacity = unpack_mix_vec2(a_opacity, a_opacity_t); + gapwidth = unpack_mix_vec2(a_gapwidth, a_gapwidth_t); + offset = unpack_mix_vec2(a_offset, a_offset_t); vec2 a_extrude = a_data.xy - 128.0; float a_direction = mod(a_data.z, 4.0) - 1.0; diff --git a/src/mbgl/shaders/preludes.cpp b/src/mbgl/shaders/preludes.cpp index a0e9414ceb..806e655285 100644 --- a/src/mbgl/shaders/preludes.cpp +++ b/src/mbgl/shaders/preludes.cpp @@ -43,6 +43,31 @@ vec4 evaluate_zoom_function_4(const vec4 value0, const vec4 value1, const vec4 v } } + +// To minimize the number of attributes needed in the mapbox-gl-native shaders, +// we encode a 4-component color into a pair of floats (i.e. a vec2) as follows: +// [ floor(color.r * 255) * 256 + color.g * 255, +// floor(color.b * 255) * 256 + color.g * 255 ] +vec4 decode_color(const vec2 encodedColor) { + float r = floor(encodedColor[0]/256.0)/255.0; + float g = (encodedColor[0] - r*256.0*255.0)/255.0; + float b = floor(encodedColor[1]/256.0)/255.0; + float a = (encodedColor[1] - b*256.0*255.0)/255.0; + return vec4(r, g, b, a); +} + +// Unpack a pair of paint values and interpolate between them. +float unpack_mix_vec2(const vec2 packedValue, const float t) { + return mix(packedValue[0], packedValue[1], t); +} + +// Unpack a pair of paint values and interpolate between them. +vec4 unpack_mix_vec4(const vec4 packedColors, const float t) { + vec4 minColor = decode_color(vec2(packedColors[0], packedColors[1])); + vec4 maxColor = decode_color(vec2(packedColors[2], packedColors[3])); + return mix(minColor, maxColor, t); +} + // The offset depends on how many pixels are between the world origin and the edge of the tile: // vec2 offset = mod(pixel_coord, size) // diff --git a/src/mbgl/shaders/symbol_icon.cpp b/src/mbgl/shaders/symbol_icon.cpp index 5945f1f3b1..9adda0ba16 100644 --- a/src/mbgl/shaders/symbol_icon.cpp +++ b/src/mbgl/shaders/symbol_icon.cpp @@ -7,14 +7,13 @@ namespace shaders { const char* symbol_icon::name = "symbol_icon"; const char* symbol_icon::vertexSource = R"MBGL_SHADER( -attribute vec2 a_pos; -attribute vec2 a_offset; + +attribute vec4 a_pos_offset; attribute vec2 a_texture_pos; attribute vec4 a_data; uniform lowp float a_opacity_t; -attribute lowp float a_opacity_min; -attribute lowp float a_opacity_max; +attribute lowp vec2 a_opacity; varying lowp float opacity; // matrix is for the vertex position. @@ -30,7 +29,10 @@ varying vec2 v_tex; varying vec2 v_fade_tex; void main() { - opacity = mix(a_opacity_min, a_opacity_max, a_opacity_t); + opacity = unpack_mix_vec2(a_opacity, a_opacity_t); + + vec2 a_pos = a_pos_offset.xy; + vec2 a_offset = a_pos_offset.zw; vec2 a_tex = a_texture_pos.xy; mediump float a_labelminzoom = a_data[0]; diff --git a/src/mbgl/shaders/symbol_sdf.cpp b/src/mbgl/shaders/symbol_sdf.cpp index ccb4b9cee6..76399dbb55 100644 --- a/src/mbgl/shaders/symbol_sdf.cpp +++ b/src/mbgl/shaders/symbol_sdf.cpp @@ -9,30 +9,24 @@ const char* symbol_sdf::name = "symbol_sdf"; const char* symbol_sdf::vertexSource = R"MBGL_SHADER( const float PI = 3.141592653589793; -attribute vec2 a_pos; -attribute vec2 a_offset; +attribute vec4 a_pos_offset; attribute vec2 a_texture_pos; attribute vec4 a_data; uniform lowp float a_fill_color_t; -attribute lowp vec4 a_fill_color_min; -attribute lowp vec4 a_fill_color_max; +attribute lowp vec4 a_fill_color; varying lowp vec4 fill_color; uniform lowp float a_halo_color_t; -attribute lowp vec4 a_halo_color_min; -attribute lowp vec4 a_halo_color_max; +attribute lowp vec4 a_halo_color; varying lowp vec4 halo_color; uniform lowp float a_opacity_t; -attribute lowp float a_opacity_min; -attribute lowp float a_opacity_max; +attribute lowp vec2 a_opacity; varying lowp float opacity; uniform lowp float a_halo_width_t; -attribute lowp float a_halo_width_min; -attribute lowp float a_halo_width_max; +attribute lowp vec2 a_halo_width; varying lowp float halo_width; uniform lowp float a_halo_blur_t; -attribute lowp float a_halo_blur_min; -attribute lowp float a_halo_blur_max; +attribute lowp vec2 a_halo_blur; varying lowp float halo_blur; // matrix is for the vertex position. @@ -53,11 +47,14 @@ varying vec2 v_fade_tex; varying float v_gamma_scale; void main() { - fill_color = mix(a_fill_color_min, a_fill_color_max, a_fill_color_t); - halo_color = mix(a_halo_color_min, a_halo_color_max, a_halo_color_t); - opacity = mix(a_opacity_min, a_opacity_max, a_opacity_t); - halo_width = mix(a_halo_width_min, a_halo_width_max, a_halo_width_t); - halo_blur = mix(a_halo_blur_min, a_halo_blur_max, a_halo_blur_t); + fill_color = unpack_mix_vec4(a_fill_color, a_fill_color_t); + halo_color = unpack_mix_vec4(a_halo_color, a_halo_color_t); + opacity = unpack_mix_vec2(a_opacity, a_opacity_t); + halo_width = unpack_mix_vec2(a_halo_width, a_halo_width_t); + halo_blur = unpack_mix_vec2(a_halo_blur, a_halo_blur_t); + + vec2 a_pos = a_pos_offset.xy; + vec2 a_offset = a_pos_offset.zw; vec2 a_tex = a_texture_pos.xy; mediump float a_labelminzoom = a_data[0]; diff --git a/src/mbgl/style/paint_property_binder.hpp b/src/mbgl/style/paint_property_binder.hpp index 79c7692b2f..17c99fe1d9 100644 --- a/src/mbgl/style/paint_property_binder.hpp +++ b/src/mbgl/style/paint_property_binder.hpp @@ -11,8 +11,11 @@ namespace style { template class ConstantPaintPropertyBinder { public: - using Attribute = A; - using AttributeValue = typename Attribute::Value; + using BaseAttribute = A; + using BaseAttributeValue = typename BaseAttribute::Value; + using BaseAttributeBinding = typename BaseAttribute::Binding; + + using Attribute = attributes::ZoomInterpolatedAttribute; using AttributeBinding = typename Attribute::Binding; ConstantPaintPropertyBinder(T constant_) @@ -22,16 +25,13 @@ public: void populateVertexVector(const GeometryTileFeature&, std::size_t) {} void upload(gl::Context&) {} - AttributeBinding minAttributeBinding(const PossiblyEvaluatedPropertyValue& currentValue) const { + AttributeBinding attributeBinding(const PossiblyEvaluatedPropertyValue& currentValue) const { + auto val = currentValue.constantOr(constant); return typename Attribute::ConstantBinding { - Attribute::value(currentValue.constantOr(constant)) + Attribute::value(val, val) }; } - AttributeBinding maxAttributeBinding(const PossiblyEvaluatedPropertyValue&) const { - return AttributeBinding(); - } - float interpolationFactor(float) const { return 0.0f; } @@ -43,12 +43,13 @@ private: template class SourceFunctionPaintPropertyBinder { public: - using Attribute = A; - using AttributeValue = typename Attribute::Value; - using AttributeBinding = typename Attribute::Binding; + using BaseAttribute = A; + using BaseAttributeValue = typename BaseAttribute::Value; + using BaseAttributeBinding = typename BaseAttribute::Binding; + using BaseVertex = typename gl::Attributes::Vertex; - using Attributes = gl::Attributes; - using Vertex = typename Attributes::Vertex; + using Attribute = attributes::ZoomInterpolatedAttribute; + using AttributeBinding = typename Attribute::Binding; SourceFunctionPaintPropertyBinder(SourceFunction function_, T defaultValue_) : function(std::move(function_)), @@ -56,9 +57,10 @@ public: } void populateVertexVector(const GeometryTileFeature& feature, std::size_t length) { - AttributeValue value = Attribute::value(function.evaluate(feature, defaultValue)); + auto val = function.evaluate(feature, defaultValue); + BaseAttributeValue value = BaseAttribute::value(val); for (std::size_t i = vertexVector.vertexSize(); i < length; ++i) { - vertexVector.emplace_back(Vertex { value }); + vertexVector.emplace_back(BaseVertex { value }); } } @@ -66,21 +68,17 @@ public: vertexBuffer = context.createVertexBuffer(std::move(vertexVector)); } - AttributeBinding minAttributeBinding(const PossiblyEvaluatedPropertyValue& currentValue) const { + AttributeBinding attributeBinding(const PossiblyEvaluatedPropertyValue& currentValue) const { if (currentValue.isConstant()) { + auto val = *currentValue.constant(); return typename Attribute::ConstantBinding { - Attribute::value(*currentValue.constant()) + Attribute::value(val, val) }; } else { - return Attributes::allVariableBindings(*vertexBuffer) - .template get(); + return Attribute::variableBinding(*vertexBuffer, 0, BaseAttribute::Dimensions); } } - AttributeBinding maxAttributeBinding(const PossiblyEvaluatedPropertyValue&) const { - return AttributeBinding(); - } - float interpolationFactor(float) const { return 0.0f; } @@ -88,22 +86,17 @@ public: private: SourceFunction function; T defaultValue; - gl::VertexVector vertexVector; - optional> vertexBuffer; + gl::VertexVector vertexVector; + optional> vertexBuffer; }; template class CompositeFunctionPaintPropertyBinder { public: - using Attribute = A; + using Attribute = attributes::ZoomInterpolatedAttribute; using AttributeValue = typename Attribute::Value; using AttributeBinding = typename Attribute::Binding; - - using MinAttribute = attributes::Min; - using MaxAttribute = attributes::Max; - - using Attributes = gl::Attributes; - using Vertex = typename Attributes::Vertex; + using Vertex = typename gl::Attributes::Vertex; CompositeFunctionPaintPropertyBinder(CompositeFunction function_, float zoom, T defaultValue_) : function(std::move(function_)), @@ -113,10 +106,9 @@ public: void populateVertexVector(const GeometryTileFeature& feature, std::size_t length) { Range range = function.evaluate(std::get<1>(coveringRanges), feature, defaultValue); - AttributeValue min = Attribute::value(range.min); - AttributeValue max = Attribute::value(range.max); + AttributeValue minMax = Attribute::value(range.min, range.max); for (std::size_t i = vertexVector.vertexSize(); i < length; ++i) { - vertexVector.emplace_back(Vertex { min, max }); + vertexVector.emplace_back(Vertex { minMax }); } } @@ -124,23 +116,14 @@ public: vertexBuffer = context.createVertexBuffer(std::move(vertexVector)); } - AttributeBinding minAttributeBinding(const PossiblyEvaluatedPropertyValue& currentValue) const { + AttributeBinding attributeBinding(const PossiblyEvaluatedPropertyValue& currentValue) const { if (currentValue.isConstant()) { + auto val = *currentValue.constant(); return typename Attribute::ConstantBinding { - Attribute::value(*currentValue.constant()) + Attribute::value(val, val) }; } else { - return Attributes::allVariableBindings(*vertexBuffer) - .template get(); - } - } - - AttributeBinding maxAttributeBinding(const PossiblyEvaluatedPropertyValue& currentValue) const { - if (currentValue.isConstant()) { - return AttributeBinding(); - } else { - return Attributes::allVariableBindings(*vertexBuffer) - .template get(); + return Attribute::variableBinding(*vertexBuffer, 0); } } @@ -161,24 +144,27 @@ template class PaintPropertyBinder { public: using Type = typename PaintProperty::Type; - using Attribute = typename PaintProperty::Attribute; using PropertyValue = typename PaintProperty::EvaluatedType; + using BaseAttribute = typename PaintProperty::Attribute; + using Attribute = attributes::ZoomInterpolatedAttribute; + using AttributeBinding = typename Attribute::Binding; + using Binder = variant< - ConstantPaintPropertyBinder, - SourceFunctionPaintPropertyBinder, - CompositeFunctionPaintPropertyBinder>; + ConstantPaintPropertyBinder, + SourceFunctionPaintPropertyBinder, + CompositeFunctionPaintPropertyBinder>; PaintPropertyBinder(const PropertyValue& value, float zoom) : binder(value.match( [&] (const Type& constant) -> Binder { - return ConstantPaintPropertyBinder(constant); + return ConstantPaintPropertyBinder(constant); }, [&] (const SourceFunction& function) { - return SourceFunctionPaintPropertyBinder(function, PaintProperty::defaultValue()); + return SourceFunctionPaintPropertyBinder(function, PaintProperty::defaultValue()); }, [&] (const CompositeFunction& function) { - return CompositeFunctionPaintPropertyBinder(function, zoom, PaintProperty::defaultValue()); + return CompositeFunctionPaintPropertyBinder(function, zoom, PaintProperty::defaultValue()); } )) { } @@ -195,19 +181,9 @@ public: }); } - using MinAttribute = attributes::Min; - using MaxAttribute = attributes::Max; - using AttributeBinding = typename Attribute::Binding; - - AttributeBinding minAttributeBinding(const PropertyValue& currentValue) const { - return binder.match([&] (const auto& b) { - return b.minAttributeBinding(currentValue); - }); - } - - AttributeBinding maxAttributeBinding(const PropertyValue& currentValue) const { + AttributeBinding attributeBinding(const PropertyValue& currentValue) const { return binder.match([&] (const auto& b) { - return b.maxAttributeBinding(currentValue); + return b.attributeBinding(currentValue); }); } @@ -252,21 +228,14 @@ public: }); } - using MinAttributes = gl::Attributes::MinAttribute...>; - using MaxAttributes = gl::Attributes::MaxAttribute...>; - - using Attributes = gl::ConcatenateAttributes; + using Attributes = gl::Attributes::Attribute...>; using AttributeBindings = typename Attributes::Bindings; template AttributeBindings attributeBindings(const EvaluatedProperties& currentProperties) const { - const typename MinAttributes::Bindings min { - binders.template get().minAttributeBinding(currentProperties.template get())... - }; - const typename MaxAttributes::Bindings max { - binders.template get().maxAttributeBinding(currentProperties.template get())... + return typename Attributes::Bindings { + binders.template get().attributeBinding(currentProperties.template get())... }; - return min.concat(max); } using Uniforms = gl::Uniforms::InterpolationUniform...>; -- cgit v1.2.1 From e044e0aab9f63883e935d94e0cf9aceb37f4e6eb Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Tue, 28 Feb 2017 17:17:45 -0800 Subject: [core] Avoid using std::function in property_setter.hpp --- .../style/conversion/make_property_setters.hpp | 322 ++++++++++----------- .../style/conversion/make_property_setters.hpp.ejs | 6 +- include/mbgl/style/conversion/property_setter.hpp | 79 ++--- 3 files changed, 209 insertions(+), 198 deletions(-) diff --git a/include/mbgl/style/conversion/make_property_setters.hpp b/include/mbgl/style/conversion/make_property_setters.hpp index 32fa810f0b..623cc09098 100644 --- a/include/mbgl/style/conversion/make_property_setters.hpp +++ b/include/mbgl/style/conversion/make_property_setters.hpp @@ -25,45 +25,45 @@ auto makeLayoutPropertySetters() { result["visibility"] = &setVisibility; - result["line-cap"] = makePropertySetter(&LineLayer::setLineCap); - result["line-join"] = makePropertySetter(&LineLayer::setLineJoin); - result["line-miter-limit"] = makePropertySetter(&LineLayer::setLineMiterLimit); - result["line-round-limit"] = makePropertySetter(&LineLayer::setLineRoundLimit); - - result["symbol-placement"] = makePropertySetter(&SymbolLayer::setSymbolPlacement); - result["symbol-spacing"] = makePropertySetter(&SymbolLayer::setSymbolSpacing); - result["symbol-avoid-edges"] = makePropertySetter(&SymbolLayer::setSymbolAvoidEdges); - result["icon-allow-overlap"] = makePropertySetter(&SymbolLayer::setIconAllowOverlap); - result["icon-ignore-placement"] = makePropertySetter(&SymbolLayer::setIconIgnorePlacement); - result["icon-optional"] = makePropertySetter(&SymbolLayer::setIconOptional); - result["icon-rotation-alignment"] = makePropertySetter(&SymbolLayer::setIconRotationAlignment); - result["icon-size"] = makePropertySetter(&SymbolLayer::setIconSize); - result["icon-text-fit"] = makePropertySetter(&SymbolLayer::setIconTextFit); - result["icon-text-fit-padding"] = makePropertySetter(&SymbolLayer::setIconTextFitPadding); - result["icon-image"] = makePropertySetter(&SymbolLayer::setIconImage); - result["icon-rotate"] = makePropertySetter(&SymbolLayer::setIconRotate); - result["icon-padding"] = makePropertySetter(&SymbolLayer::setIconPadding); - result["icon-keep-upright"] = makePropertySetter(&SymbolLayer::setIconKeepUpright); - result["icon-offset"] = makePropertySetter(&SymbolLayer::setIconOffset); - result["text-pitch-alignment"] = makePropertySetter(&SymbolLayer::setTextPitchAlignment); - result["text-rotation-alignment"] = makePropertySetter(&SymbolLayer::setTextRotationAlignment); - result["text-field"] = makePropertySetter(&SymbolLayer::setTextField); - result["text-font"] = makePropertySetter(&SymbolLayer::setTextFont); - result["text-size"] = makePropertySetter(&SymbolLayer::setTextSize); - result["text-max-width"] = makePropertySetter(&SymbolLayer::setTextMaxWidth); - result["text-line-height"] = makePropertySetter(&SymbolLayer::setTextLineHeight); - result["text-letter-spacing"] = makePropertySetter(&SymbolLayer::setTextLetterSpacing); - result["text-justify"] = makePropertySetter(&SymbolLayer::setTextJustify); - result["text-anchor"] = makePropertySetter(&SymbolLayer::setTextAnchor); - result["text-max-angle"] = makePropertySetter(&SymbolLayer::setTextMaxAngle); - result["text-rotate"] = makePropertySetter(&SymbolLayer::setTextRotate); - result["text-padding"] = makePropertySetter(&SymbolLayer::setTextPadding); - result["text-keep-upright"] = makePropertySetter(&SymbolLayer::setTextKeepUpright); - result["text-transform"] = makePropertySetter(&SymbolLayer::setTextTransform); - result["text-offset"] = makePropertySetter(&SymbolLayer::setTextOffset); - result["text-allow-overlap"] = makePropertySetter(&SymbolLayer::setTextAllowOverlap); - result["text-ignore-placement"] = makePropertySetter(&SymbolLayer::setTextIgnorePlacement); - result["text-optional"] = makePropertySetter(&SymbolLayer::setTextOptional); + result["line-cap"] = &setLayoutProperty, &LineLayer::setLineCap>; + result["line-join"] = &setLayoutProperty, &LineLayer::setLineJoin>; + result["line-miter-limit"] = &setLayoutProperty, &LineLayer::setLineMiterLimit>; + result["line-round-limit"] = &setLayoutProperty, &LineLayer::setLineRoundLimit>; + + result["symbol-placement"] = &setLayoutProperty, &SymbolLayer::setSymbolPlacement>; + result["symbol-spacing"] = &setLayoutProperty, &SymbolLayer::setSymbolSpacing>; + result["symbol-avoid-edges"] = &setLayoutProperty, &SymbolLayer::setSymbolAvoidEdges>; + result["icon-allow-overlap"] = &setLayoutProperty, &SymbolLayer::setIconAllowOverlap>; + result["icon-ignore-placement"] = &setLayoutProperty, &SymbolLayer::setIconIgnorePlacement>; + result["icon-optional"] = &setLayoutProperty, &SymbolLayer::setIconOptional>; + result["icon-rotation-alignment"] = &setLayoutProperty, &SymbolLayer::setIconRotationAlignment>; + result["icon-size"] = &setLayoutProperty, &SymbolLayer::setIconSize>; + result["icon-text-fit"] = &setLayoutProperty, &SymbolLayer::setIconTextFit>; + result["icon-text-fit-padding"] = &setLayoutProperty>, &SymbolLayer::setIconTextFitPadding>; + result["icon-image"] = &setLayoutProperty, &SymbolLayer::setIconImage>; + result["icon-rotate"] = &setLayoutProperty, &SymbolLayer::setIconRotate>; + result["icon-padding"] = &setLayoutProperty, &SymbolLayer::setIconPadding>; + result["icon-keep-upright"] = &setLayoutProperty, &SymbolLayer::setIconKeepUpright>; + result["icon-offset"] = &setLayoutProperty>, &SymbolLayer::setIconOffset>; + result["text-pitch-alignment"] = &setLayoutProperty, &SymbolLayer::setTextPitchAlignment>; + result["text-rotation-alignment"] = &setLayoutProperty, &SymbolLayer::setTextRotationAlignment>; + result["text-field"] = &setLayoutProperty, &SymbolLayer::setTextField>; + result["text-font"] = &setLayoutProperty>, &SymbolLayer::setTextFont>; + result["text-size"] = &setLayoutProperty, &SymbolLayer::setTextSize>; + result["text-max-width"] = &setLayoutProperty, &SymbolLayer::setTextMaxWidth>; + result["text-line-height"] = &setLayoutProperty, &SymbolLayer::setTextLineHeight>; + result["text-letter-spacing"] = &setLayoutProperty, &SymbolLayer::setTextLetterSpacing>; + result["text-justify"] = &setLayoutProperty, &SymbolLayer::setTextJustify>; + result["text-anchor"] = &setLayoutProperty, &SymbolLayer::setTextAnchor>; + result["text-max-angle"] = &setLayoutProperty, &SymbolLayer::setTextMaxAngle>; + result["text-rotate"] = &setLayoutProperty, &SymbolLayer::setTextRotate>; + result["text-padding"] = &setLayoutProperty, &SymbolLayer::setTextPadding>; + result["text-keep-upright"] = &setLayoutProperty, &SymbolLayer::setTextKeepUpright>; + result["text-transform"] = &setLayoutProperty, &SymbolLayer::setTextTransform>; + result["text-offset"] = &setLayoutProperty>, &SymbolLayer::setTextOffset>; + result["text-allow-overlap"] = &setLayoutProperty, &SymbolLayer::setTextAllowOverlap>; + result["text-ignore-placement"] = &setLayoutProperty, &SymbolLayer::setTextIgnorePlacement>; + result["text-optional"] = &setLayoutProperty, &SymbolLayer::setTextOptional>; @@ -76,128 +76,128 @@ template auto makePaintPropertySetters() { std::unordered_map> result; - result["fill-antialias"] = makePropertySetter(&FillLayer::setFillAntialias); - result["fill-antialias-transition"] = makeTransitionSetter(&FillLayer::setFillAntialiasTransition); - result["fill-opacity"] = makePropertySetter(&FillLayer::setFillOpacity); - result["fill-opacity-transition"] = makeTransitionSetter(&FillLayer::setFillOpacityTransition); - result["fill-color"] = makePropertySetter(&FillLayer::setFillColor); - result["fill-color-transition"] = makeTransitionSetter(&FillLayer::setFillColorTransition); - result["fill-outline-color"] = makePropertySetter(&FillLayer::setFillOutlineColor); - result["fill-outline-color-transition"] = makeTransitionSetter(&FillLayer::setFillOutlineColorTransition); - result["fill-translate"] = makePropertySetter(&FillLayer::setFillTranslate); - result["fill-translate-transition"] = makeTransitionSetter(&FillLayer::setFillTranslateTransition); - result["fill-translate-anchor"] = makePropertySetter(&FillLayer::setFillTranslateAnchor); - result["fill-translate-anchor-transition"] = makeTransitionSetter(&FillLayer::setFillTranslateAnchorTransition); - result["fill-pattern"] = makePropertySetter(&FillLayer::setFillPattern); - result["fill-pattern-transition"] = makeTransitionSetter(&FillLayer::setFillPatternTransition); - - result["line-opacity"] = makePropertySetter(&LineLayer::setLineOpacity); - result["line-opacity-transition"] = makeTransitionSetter(&LineLayer::setLineOpacityTransition); - result["line-color"] = makePropertySetter(&LineLayer::setLineColor); - result["line-color-transition"] = makeTransitionSetter(&LineLayer::setLineColorTransition); - result["line-translate"] = makePropertySetter(&LineLayer::setLineTranslate); - result["line-translate-transition"] = makeTransitionSetter(&LineLayer::setLineTranslateTransition); - result["line-translate-anchor"] = makePropertySetter(&LineLayer::setLineTranslateAnchor); - result["line-translate-anchor-transition"] = makeTransitionSetter(&LineLayer::setLineTranslateAnchorTransition); - result["line-width"] = makePropertySetter(&LineLayer::setLineWidth); - result["line-width-transition"] = makeTransitionSetter(&LineLayer::setLineWidthTransition); - result["line-gap-width"] = makePropertySetter(&LineLayer::setLineGapWidth); - result["line-gap-width-transition"] = makeTransitionSetter(&LineLayer::setLineGapWidthTransition); - result["line-offset"] = makePropertySetter(&LineLayer::setLineOffset); - result["line-offset-transition"] = makeTransitionSetter(&LineLayer::setLineOffsetTransition); - result["line-blur"] = makePropertySetter(&LineLayer::setLineBlur); - result["line-blur-transition"] = makeTransitionSetter(&LineLayer::setLineBlurTransition); - result["line-dasharray"] = makePropertySetter(&LineLayer::setLineDasharray); - result["line-dasharray-transition"] = makeTransitionSetter(&LineLayer::setLineDasharrayTransition); - result["line-pattern"] = makePropertySetter(&LineLayer::setLinePattern); - result["line-pattern-transition"] = makeTransitionSetter(&LineLayer::setLinePatternTransition); - - result["icon-opacity"] = makePropertySetter(&SymbolLayer::setIconOpacity); - result["icon-opacity-transition"] = makeTransitionSetter(&SymbolLayer::setIconOpacityTransition); - result["icon-color"] = makePropertySetter(&SymbolLayer::setIconColor); - result["icon-color-transition"] = makeTransitionSetter(&SymbolLayer::setIconColorTransition); - result["icon-halo-color"] = makePropertySetter(&SymbolLayer::setIconHaloColor); - result["icon-halo-color-transition"] = makeTransitionSetter(&SymbolLayer::setIconHaloColorTransition); - result["icon-halo-width"] = makePropertySetter(&SymbolLayer::setIconHaloWidth); - result["icon-halo-width-transition"] = makeTransitionSetter(&SymbolLayer::setIconHaloWidthTransition); - result["icon-halo-blur"] = makePropertySetter(&SymbolLayer::setIconHaloBlur); - result["icon-halo-blur-transition"] = makeTransitionSetter(&SymbolLayer::setIconHaloBlurTransition); - result["icon-translate"] = makePropertySetter(&SymbolLayer::setIconTranslate); - result["icon-translate-transition"] = makeTransitionSetter(&SymbolLayer::setIconTranslateTransition); - result["icon-translate-anchor"] = makePropertySetter(&SymbolLayer::setIconTranslateAnchor); - result["icon-translate-anchor-transition"] = makeTransitionSetter(&SymbolLayer::setIconTranslateAnchorTransition); - result["text-opacity"] = makePropertySetter(&SymbolLayer::setTextOpacity); - result["text-opacity-transition"] = makeTransitionSetter(&SymbolLayer::setTextOpacityTransition); - result["text-color"] = makePropertySetter(&SymbolLayer::setTextColor); - result["text-color-transition"] = makeTransitionSetter(&SymbolLayer::setTextColorTransition); - result["text-halo-color"] = makePropertySetter(&SymbolLayer::setTextHaloColor); - result["text-halo-color-transition"] = makeTransitionSetter(&SymbolLayer::setTextHaloColorTransition); - result["text-halo-width"] = makePropertySetter(&SymbolLayer::setTextHaloWidth); - result["text-halo-width-transition"] = makeTransitionSetter(&SymbolLayer::setTextHaloWidthTransition); - result["text-halo-blur"] = makePropertySetter(&SymbolLayer::setTextHaloBlur); - result["text-halo-blur-transition"] = makeTransitionSetter(&SymbolLayer::setTextHaloBlurTransition); - result["text-translate"] = makePropertySetter(&SymbolLayer::setTextTranslate); - result["text-translate-transition"] = makeTransitionSetter(&SymbolLayer::setTextTranslateTransition); - result["text-translate-anchor"] = makePropertySetter(&SymbolLayer::setTextTranslateAnchor); - result["text-translate-anchor-transition"] = makeTransitionSetter(&SymbolLayer::setTextTranslateAnchorTransition); - - result["circle-radius"] = makePropertySetter(&CircleLayer::setCircleRadius); - result["circle-radius-transition"] = makeTransitionSetter(&CircleLayer::setCircleRadiusTransition); - result["circle-color"] = makePropertySetter(&CircleLayer::setCircleColor); - result["circle-color-transition"] = makeTransitionSetter(&CircleLayer::setCircleColorTransition); - result["circle-blur"] = makePropertySetter(&CircleLayer::setCircleBlur); - result["circle-blur-transition"] = makeTransitionSetter(&CircleLayer::setCircleBlurTransition); - result["circle-opacity"] = makePropertySetter(&CircleLayer::setCircleOpacity); - result["circle-opacity-transition"] = makeTransitionSetter(&CircleLayer::setCircleOpacityTransition); - result["circle-translate"] = makePropertySetter(&CircleLayer::setCircleTranslate); - result["circle-translate-transition"] = makeTransitionSetter(&CircleLayer::setCircleTranslateTransition); - result["circle-translate-anchor"] = makePropertySetter(&CircleLayer::setCircleTranslateAnchor); - result["circle-translate-anchor-transition"] = makeTransitionSetter(&CircleLayer::setCircleTranslateAnchorTransition); - result["circle-pitch-scale"] = makePropertySetter(&CircleLayer::setCirclePitchScale); - result["circle-pitch-scale-transition"] = makeTransitionSetter(&CircleLayer::setCirclePitchScaleTransition); - result["circle-stroke-width"] = makePropertySetter(&CircleLayer::setCircleStrokeWidth); - result["circle-stroke-width-transition"] = makeTransitionSetter(&CircleLayer::setCircleStrokeWidthTransition); - result["circle-stroke-color"] = makePropertySetter(&CircleLayer::setCircleStrokeColor); - result["circle-stroke-color-transition"] = makeTransitionSetter(&CircleLayer::setCircleStrokeColorTransition); - result["circle-stroke-opacity"] = makePropertySetter(&CircleLayer::setCircleStrokeOpacity); - result["circle-stroke-opacity-transition"] = makeTransitionSetter(&CircleLayer::setCircleStrokeOpacityTransition); - - result["fill-extrusion-opacity"] = makePropertySetter(&FillExtrusionLayer::setFillExtrusionOpacity); - result["fill-extrusion-opacity-transition"] = makeTransitionSetter(&FillExtrusionLayer::setFillExtrusionOpacityTransition); - result["fill-extrusion-color"] = makePropertySetter(&FillExtrusionLayer::setFillExtrusionColor); - result["fill-extrusion-color-transition"] = makeTransitionSetter(&FillExtrusionLayer::setFillExtrusionColorTransition); - result["fill-extrusion-translate"] = makePropertySetter(&FillExtrusionLayer::setFillExtrusionTranslate); - result["fill-extrusion-translate-transition"] = makeTransitionSetter(&FillExtrusionLayer::setFillExtrusionTranslateTransition); - result["fill-extrusion-translate-anchor"] = makePropertySetter(&FillExtrusionLayer::setFillExtrusionTranslateAnchor); - result["fill-extrusion-translate-anchor-transition"] = makeTransitionSetter(&FillExtrusionLayer::setFillExtrusionTranslateAnchorTransition); - result["fill-extrusion-pattern"] = makePropertySetter(&FillExtrusionLayer::setFillExtrusionPattern); - result["fill-extrusion-pattern-transition"] = makeTransitionSetter(&FillExtrusionLayer::setFillExtrusionPatternTransition); - result["fill-extrusion-height"] = makePropertySetter(&FillExtrusionLayer::setFillExtrusionHeight); - result["fill-extrusion-height-transition"] = makeTransitionSetter(&FillExtrusionLayer::setFillExtrusionHeightTransition); - result["fill-extrusion-base"] = makePropertySetter(&FillExtrusionLayer::setFillExtrusionBase); - result["fill-extrusion-base-transition"] = makeTransitionSetter(&FillExtrusionLayer::setFillExtrusionBaseTransition); - - result["raster-opacity"] = makePropertySetter(&RasterLayer::setRasterOpacity); - result["raster-opacity-transition"] = makeTransitionSetter(&RasterLayer::setRasterOpacityTransition); - result["raster-hue-rotate"] = makePropertySetter(&RasterLayer::setRasterHueRotate); - result["raster-hue-rotate-transition"] = makeTransitionSetter(&RasterLayer::setRasterHueRotateTransition); - result["raster-brightness-min"] = makePropertySetter(&RasterLayer::setRasterBrightnessMin); - result["raster-brightness-min-transition"] = makeTransitionSetter(&RasterLayer::setRasterBrightnessMinTransition); - result["raster-brightness-max"] = makePropertySetter(&RasterLayer::setRasterBrightnessMax); - result["raster-brightness-max-transition"] = makeTransitionSetter(&RasterLayer::setRasterBrightnessMaxTransition); - result["raster-saturation"] = makePropertySetter(&RasterLayer::setRasterSaturation); - result["raster-saturation-transition"] = makeTransitionSetter(&RasterLayer::setRasterSaturationTransition); - result["raster-contrast"] = makePropertySetter(&RasterLayer::setRasterContrast); - result["raster-contrast-transition"] = makeTransitionSetter(&RasterLayer::setRasterContrastTransition); - result["raster-fade-duration"] = makePropertySetter(&RasterLayer::setRasterFadeDuration); - result["raster-fade-duration-transition"] = makeTransitionSetter(&RasterLayer::setRasterFadeDurationTransition); - - result["background-color"] = makePropertySetter(&BackgroundLayer::setBackgroundColor); - result["background-color-transition"] = makeTransitionSetter(&BackgroundLayer::setBackgroundColorTransition); - result["background-pattern"] = makePropertySetter(&BackgroundLayer::setBackgroundPattern); - result["background-pattern-transition"] = makeTransitionSetter(&BackgroundLayer::setBackgroundPatternTransition); - result["background-opacity"] = makePropertySetter(&BackgroundLayer::setBackgroundOpacity); - result["background-opacity-transition"] = makeTransitionSetter(&BackgroundLayer::setBackgroundOpacityTransition); + result["fill-antialias"] = &setPaintProperty, &FillLayer::setFillAntialias>; + result["fill-antialias-transition"] = &setTransition; + result["fill-opacity"] = &setPaintProperty, &FillLayer::setFillOpacity>; + result["fill-opacity-transition"] = &setTransition; + result["fill-color"] = &setPaintProperty, &FillLayer::setFillColor>; + result["fill-color-transition"] = &setTransition; + result["fill-outline-color"] = &setPaintProperty, &FillLayer::setFillOutlineColor>; + result["fill-outline-color-transition"] = &setTransition; + result["fill-translate"] = &setPaintProperty>, &FillLayer::setFillTranslate>; + result["fill-translate-transition"] = &setTransition; + result["fill-translate-anchor"] = &setPaintProperty, &FillLayer::setFillTranslateAnchor>; + result["fill-translate-anchor-transition"] = &setTransition; + result["fill-pattern"] = &setPaintProperty, &FillLayer::setFillPattern>; + result["fill-pattern-transition"] = &setTransition; + + result["line-opacity"] = &setPaintProperty, &LineLayer::setLineOpacity>; + result["line-opacity-transition"] = &setTransition; + result["line-color"] = &setPaintProperty, &LineLayer::setLineColor>; + result["line-color-transition"] = &setTransition; + result["line-translate"] = &setPaintProperty>, &LineLayer::setLineTranslate>; + result["line-translate-transition"] = &setTransition; + result["line-translate-anchor"] = &setPaintProperty, &LineLayer::setLineTranslateAnchor>; + result["line-translate-anchor-transition"] = &setTransition; + result["line-width"] = &setPaintProperty, &LineLayer::setLineWidth>; + result["line-width-transition"] = &setTransition; + result["line-gap-width"] = &setPaintProperty, &LineLayer::setLineGapWidth>; + result["line-gap-width-transition"] = &setTransition; + result["line-offset"] = &setPaintProperty, &LineLayer::setLineOffset>; + result["line-offset-transition"] = &setTransition; + result["line-blur"] = &setPaintProperty, &LineLayer::setLineBlur>; + result["line-blur-transition"] = &setTransition; + result["line-dasharray"] = &setPaintProperty>, &LineLayer::setLineDasharray>; + result["line-dasharray-transition"] = &setTransition; + result["line-pattern"] = &setPaintProperty, &LineLayer::setLinePattern>; + result["line-pattern-transition"] = &setTransition; + + result["icon-opacity"] = &setPaintProperty, &SymbolLayer::setIconOpacity>; + result["icon-opacity-transition"] = &setTransition; + result["icon-color"] = &setPaintProperty, &SymbolLayer::setIconColor>; + result["icon-color-transition"] = &setTransition; + result["icon-halo-color"] = &setPaintProperty, &SymbolLayer::setIconHaloColor>; + result["icon-halo-color-transition"] = &setTransition; + result["icon-halo-width"] = &setPaintProperty, &SymbolLayer::setIconHaloWidth>; + result["icon-halo-width-transition"] = &setTransition; + result["icon-halo-blur"] = &setPaintProperty, &SymbolLayer::setIconHaloBlur>; + result["icon-halo-blur-transition"] = &setTransition; + result["icon-translate"] = &setPaintProperty>, &SymbolLayer::setIconTranslate>; + result["icon-translate-transition"] = &setTransition; + result["icon-translate-anchor"] = &setPaintProperty, &SymbolLayer::setIconTranslateAnchor>; + result["icon-translate-anchor-transition"] = &setTransition; + result["text-opacity"] = &setPaintProperty, &SymbolLayer::setTextOpacity>; + result["text-opacity-transition"] = &setTransition; + result["text-color"] = &setPaintProperty, &SymbolLayer::setTextColor>; + result["text-color-transition"] = &setTransition; + result["text-halo-color"] = &setPaintProperty, &SymbolLayer::setTextHaloColor>; + result["text-halo-color-transition"] = &setTransition; + result["text-halo-width"] = &setPaintProperty, &SymbolLayer::setTextHaloWidth>; + result["text-halo-width-transition"] = &setTransition; + result["text-halo-blur"] = &setPaintProperty, &SymbolLayer::setTextHaloBlur>; + result["text-halo-blur-transition"] = &setTransition; + result["text-translate"] = &setPaintProperty>, &SymbolLayer::setTextTranslate>; + result["text-translate-transition"] = &setTransition; + result["text-translate-anchor"] = &setPaintProperty, &SymbolLayer::setTextTranslateAnchor>; + result["text-translate-anchor-transition"] = &setTransition; + + result["circle-radius"] = &setPaintProperty, &CircleLayer::setCircleRadius>; + result["circle-radius-transition"] = &setTransition; + result["circle-color"] = &setPaintProperty, &CircleLayer::setCircleColor>; + result["circle-color-transition"] = &setTransition; + result["circle-blur"] = &setPaintProperty, &CircleLayer::setCircleBlur>; + result["circle-blur-transition"] = &setTransition; + result["circle-opacity"] = &setPaintProperty, &CircleLayer::setCircleOpacity>; + result["circle-opacity-transition"] = &setTransition; + result["circle-translate"] = &setPaintProperty>, &CircleLayer::setCircleTranslate>; + result["circle-translate-transition"] = &setTransition; + result["circle-translate-anchor"] = &setPaintProperty, &CircleLayer::setCircleTranslateAnchor>; + result["circle-translate-anchor-transition"] = &setTransition; + result["circle-pitch-scale"] = &setPaintProperty, &CircleLayer::setCirclePitchScale>; + result["circle-pitch-scale-transition"] = &setTransition; + result["circle-stroke-width"] = &setPaintProperty, &CircleLayer::setCircleStrokeWidth>; + result["circle-stroke-width-transition"] = &setTransition; + result["circle-stroke-color"] = &setPaintProperty, &CircleLayer::setCircleStrokeColor>; + result["circle-stroke-color-transition"] = &setTransition; + result["circle-stroke-opacity"] = &setPaintProperty, &CircleLayer::setCircleStrokeOpacity>; + result["circle-stroke-opacity-transition"] = &setTransition; + + result["fill-extrusion-opacity"] = &setPaintProperty, &FillExtrusionLayer::setFillExtrusionOpacity>; + result["fill-extrusion-opacity-transition"] = &setTransition; + result["fill-extrusion-color"] = &setPaintProperty, &FillExtrusionLayer::setFillExtrusionColor>; + result["fill-extrusion-color-transition"] = &setTransition; + result["fill-extrusion-translate"] = &setPaintProperty>, &FillExtrusionLayer::setFillExtrusionTranslate>; + result["fill-extrusion-translate-transition"] = &setTransition; + result["fill-extrusion-translate-anchor"] = &setPaintProperty, &FillExtrusionLayer::setFillExtrusionTranslateAnchor>; + result["fill-extrusion-translate-anchor-transition"] = &setTransition; + result["fill-extrusion-pattern"] = &setPaintProperty, &FillExtrusionLayer::setFillExtrusionPattern>; + result["fill-extrusion-pattern-transition"] = &setTransition; + result["fill-extrusion-height"] = &setPaintProperty, &FillExtrusionLayer::setFillExtrusionHeight>; + result["fill-extrusion-height-transition"] = &setTransition; + result["fill-extrusion-base"] = &setPaintProperty, &FillExtrusionLayer::setFillExtrusionBase>; + result["fill-extrusion-base-transition"] = &setTransition; + + result["raster-opacity"] = &setPaintProperty, &RasterLayer::setRasterOpacity>; + result["raster-opacity-transition"] = &setTransition; + result["raster-hue-rotate"] = &setPaintProperty, &RasterLayer::setRasterHueRotate>; + result["raster-hue-rotate-transition"] = &setTransition; + result["raster-brightness-min"] = &setPaintProperty, &RasterLayer::setRasterBrightnessMin>; + result["raster-brightness-min-transition"] = &setTransition; + result["raster-brightness-max"] = &setPaintProperty, &RasterLayer::setRasterBrightnessMax>; + result["raster-brightness-max-transition"] = &setTransition; + result["raster-saturation"] = &setPaintProperty, &RasterLayer::setRasterSaturation>; + result["raster-saturation-transition"] = &setTransition; + result["raster-contrast"] = &setPaintProperty, &RasterLayer::setRasterContrast>; + result["raster-contrast-transition"] = &setTransition; + result["raster-fade-duration"] = &setPaintProperty, &RasterLayer::setRasterFadeDuration>; + result["raster-fade-duration-transition"] = &setTransition; + + result["background-color"] = &setPaintProperty, &BackgroundLayer::setBackgroundColor>; + result["background-color-transition"] = &setTransition; + result["background-pattern"] = &setPaintProperty, &BackgroundLayer::setBackgroundPattern>; + result["background-pattern-transition"] = &setTransition; + result["background-opacity"] = &setPaintProperty, &BackgroundLayer::setBackgroundOpacity>; + result["background-opacity-transition"] = &setTransition; return result; } diff --git a/include/mbgl/style/conversion/make_property_setters.hpp.ejs b/include/mbgl/style/conversion/make_property_setters.hpp.ejs index 65fbdea63e..a99e75aec7 100644 --- a/include/mbgl/style/conversion/make_property_setters.hpp.ejs +++ b/include/mbgl/style/conversion/make_property_setters.hpp.ejs @@ -22,7 +22,7 @@ auto makeLayoutPropertySetters() { <% for (const layer of locals.layers) { -%> <% for (const property of layer.layoutProperties) { -%> - result["<%- property.name %>"] = makePropertySetter(&<%- camelize(layer.type) %>Layer::set<%- camelize(property.name) %>); + result["<%- property.name %>"] = &setLayoutPropertyLayer, <%- propertyValueType(property) %>, &<%- camelize(layer.type) %>Layer::set<%- camelize(property.name) %>>; <% } -%> <% } -%> @@ -35,8 +35,8 @@ auto makePaintPropertySetters() { <% for (const layer of locals.layers) { -%> <% for (const property of layer.paintProperties) { -%> - result["<%- property.name %>"] = makePropertySetter(&<%- camelize(layer.type) %>Layer::set<%- camelize(property.name) %>); - result["<%- property.name %>-transition"] = makeTransitionSetter(&<%- camelize(layer.type) %>Layer::set<%- camelize(property.name) %>Transition); + result["<%- property.name %>"] = &setPaintPropertyLayer, <%- propertyValueType(property) %>, &<%- camelize(layer.type) %>Layer::set<%- camelize(property.name) %>>; + result["<%- property.name %>-transition"] = &setTransitionLayer, &<%- camelize(layer.type) %>Layer::set<%- camelize(property.name) %>Transition>; <% } -%> <% } -%> diff --git a/include/mbgl/style/conversion/property_setter.hpp b/include/mbgl/style/conversion/property_setter.hpp index 6a15c64026..51ec4778d9 100644 --- a/include/mbgl/style/conversion/property_setter.hpp +++ b/include/mbgl/style/conversion/property_setter.hpp @@ -7,7 +7,6 @@ #include #include -#include #include namespace mbgl { @@ -15,45 +14,57 @@ namespace style { namespace conversion { template -using LayoutPropertySetter = std::function (Layer&, const V&)>; +using LayoutPropertySetter = optional (*) (Layer&, const V&); template -using PaintPropertySetter = std::function (Layer&, const V&, const optional&)>; - -template -auto makePropertySetter(void (L::*setter)(PropertyValue, const Args&...args)) { - return [setter] (Layer& layer, const V& value, const Args&...args) -> optional { - L* typedLayer = layer.as(); - if (!typedLayer) { - return Error { "layer doesn't support this property" }; - } - - Result typedValue = convert(value); - if (!typedValue) { - return typedValue.error(); - } - - (typedLayer->*setter)(*typedValue, args...); - return {}; - }; +using PaintPropertySetter = optional (*) (Layer&, const V&, const optional&); + +template +optional setLayoutProperty(Layer& layer, const V& value) { + L* typedLayer = layer.as(); + if (!typedLayer) { + return Error { "layer doesn't support this property" }; + } + + Result typedValue = convert(value); + if (!typedValue) { + return typedValue.error(); + } + + (typedLayer->*setter)(*typedValue); + return {}; +} + +template &)> +optional setPaintProperty(Layer& layer, const V& value, const optional& klass) { + L* typedLayer = layer.as(); + if (!typedLayer) { + return Error { "layer doesn't support this property" }; + } + + Result typedValue = convert(value); + if (!typedValue) { + return typedValue.error(); + } + + (typedLayer->*setter)(*typedValue, klass); + return {}; } -template -auto makeTransitionSetter(void (L::*setter)(const TransitionOptions&, const Args&...args)) { - return [setter] (Layer& layer, const V& value, const Args&...args) -> optional { - L* typedLayer = layer.as(); - if (!typedLayer) { - return Error { "layer doesn't support this property" }; - } +template &)> +optional setTransition(Layer& layer, const V& value, const optional& klass) { + L* typedLayer = layer.as(); + if (!typedLayer) { + return Error { "layer doesn't support this property" }; + } - Result transition = convert(value); - if (!transition) { - return transition.error(); - } + Result transition = convert(value); + if (!transition) { + return transition.error(); + } - (typedLayer->*setter)(*transition, args...); - return {}; - }; + (typedLayer->*setter)(*transition, klass); + return {}; } template -- cgit v1.2.1