diff options
Diffstat (limited to 'platform/android/src/style')
27 files changed, 366 insertions, 174 deletions
diff --git a/platform/android/src/style/android_conversion.hpp b/platform/android/src/style/android_conversion.hpp index e2b2685928..082fe411e2 100644 --- a/platform/android/src/style/android_conversion.hpp +++ b/platform/android/src/style/android_conversion.hpp @@ -2,6 +2,7 @@ #include "value.hpp" +#include <mbgl/util/feature.hpp> #include <mbgl/util/logging.hpp> #include <mbgl/style/conversion.hpp> #include <mbgl/util/optional.hpp> @@ -66,6 +67,14 @@ inline optional<float> toNumber(const mbgl::android::Value& value) { } } +inline optional<double> toDouble(const mbgl::android::Value& value) { + if (value.isNumber()) { + return value.toDouble(); + } else { + return {}; + } +} + inline optional<std::string> toString(const mbgl::android::Value& value) { if (value.isString()) { return value.toString(); diff --git a/platform/android/src/style/conversion/latlngquad.hpp b/platform/android/src/style/conversion/latlngquad.hpp new file mode 100644 index 0000000000..9d1a83e164 --- /dev/null +++ b/platform/android/src/style/conversion/latlngquad.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include <mapbox/geojson.hpp> +#include <mbgl/style/conversion.hpp> +#include <mbgl/style/conversion/geojson.hpp> +#include <jni/jni.hpp> + +namespace mbgl { +namespace style { +namespace conversion { + +template <> +optional<std::array<LatLng, 4>> Converter<std::array<LatLng, 4>>::operator()(const mbgl::android::Value& value, Error& error) const { + if (value.isNull() || !value.isArray()) { + error = { "value cannot be converted to LatLng array" }; + return {}; + } + + return convert<GeoJSON>(value.toString(), error); +} + +} // namespace conversion +} // namespace style +} // namespace mbgl diff --git a/platform/android/src/style/conversion/transition_options.hpp b/platform/android/src/style/conversion/transition_options.hpp index 3614878f43..ae65a32194 100644 --- a/platform/android/src/style/conversion/transition_options.hpp +++ b/platform/android/src/style/conversion/transition_options.hpp @@ -3,6 +3,7 @@ #include "../../conversion/conversion.hpp" #include <jni/jni.hpp> +#include <mbgl/style/transition_options.hpp> #include "../../jni/local_object.hpp" #include "../transition_options.hpp" diff --git a/platform/android/src/style/conversion/types.hpp b/platform/android/src/style/conversion/types.hpp index a00f668c24..375d1a33aa 100644 --- a/platform/android/src/style/conversion/types.hpp +++ b/platform/android/src/style/conversion/types.hpp @@ -58,15 +58,15 @@ struct Converter<jni::jobject*, mbgl::style::IconTextFitType> { }; template <> -struct Converter<jni::jobject*, mbgl::style::TextJustifyType> { - Result<jni::jobject*> operator()(jni::JNIEnv& env, const mbgl::style::TextJustifyType& value) const { +struct Converter<jni::jobject*, mbgl::style::SymbolAnchorType> { + Result<jni::jobject*> operator()(jni::JNIEnv& env, const mbgl::style::SymbolAnchorType& value) const { return convert<jni::jobject*, std::string>(env, toString(value)); } }; template <> -struct Converter<jni::jobject*, mbgl::style::TextAnchorType> { - Result<jni::jobject*> operator()(jni::JNIEnv& env, const mbgl::style::TextAnchorType& value) const { +struct Converter<jni::jobject*, mbgl::style::TextJustifyType> { + Result<jni::jobject*> operator()(jni::JNIEnv& env, const mbgl::style::TextJustifyType& value) const { return convert<jni::jobject*, std::string>(env, toString(value)); } }; diff --git a/platform/android/src/style/conversion/types_string_values.hpp b/platform/android/src/style/conversion/types_string_values.hpp index e96de3b01e..a19ca33a2f 100644 --- a/platform/android/src/style/conversion/types_string_values.hpp +++ b/platform/android/src/style/conversion/types_string_values.hpp @@ -109,51 +109,34 @@ namespace conversion { } } - // text-justify - inline std::string toString(mbgl::style::TextJustifyType value) { - switch (value) { - case mbgl::style::TextJustifyType::Left: - return "left"; - break; - case mbgl::style::TextJustifyType::Center: - return "center"; - break; - case mbgl::style::TextJustifyType::Right: - return "right"; - break; - default: - throw std::runtime_error("Not implemented"); - } - } - - // text-anchor - inline std::string toString(mbgl::style::TextAnchorType value) { + // icon-anchor + inline std::string toString(mbgl::style::SymbolAnchorType value) { switch (value) { - case mbgl::style::TextAnchorType::Center: + case mbgl::style::SymbolAnchorType::Center: return "center"; break; - case mbgl::style::TextAnchorType::Left: + case mbgl::style::SymbolAnchorType::Left: return "left"; break; - case mbgl::style::TextAnchorType::Right: + case mbgl::style::SymbolAnchorType::Right: return "right"; break; - case mbgl::style::TextAnchorType::Top: + case mbgl::style::SymbolAnchorType::Top: return "top"; break; - case mbgl::style::TextAnchorType::Bottom: + case mbgl::style::SymbolAnchorType::Bottom: return "bottom"; break; - case mbgl::style::TextAnchorType::TopLeft: + case mbgl::style::SymbolAnchorType::TopLeft: return "top-left"; break; - case mbgl::style::TextAnchorType::TopRight: + case mbgl::style::SymbolAnchorType::TopRight: return "top-right"; break; - case mbgl::style::TextAnchorType::BottomLeft: + case mbgl::style::SymbolAnchorType::BottomLeft: return "bottom-left"; break; - case mbgl::style::TextAnchorType::BottomRight: + case mbgl::style::SymbolAnchorType::BottomRight: return "bottom-right"; break; default: @@ -161,6 +144,23 @@ namespace conversion { } } + // text-justify + inline std::string toString(mbgl::style::TextJustifyType value) { + switch (value) { + case mbgl::style::TextJustifyType::Left: + return "left"; + break; + case mbgl::style::TextJustifyType::Center: + return "center"; + break; + case mbgl::style::TextJustifyType::Right: + return "right"; + break; + default: + throw std::runtime_error("Not implemented"); + } + } + // text-transform inline std::string toString(mbgl::style::TextTransformType value) { switch (value) { diff --git a/platform/android/src/style/layers/circle_layer.cpp b/platform/android/src/style/layers/circle_layer.cpp index 96a9356679..4c7f69e956 100644 --- a/platform/android/src/style/layers/circle_layer.cpp +++ b/platform/android/src/style/layers/circle_layer.cpp @@ -142,6 +142,12 @@ namespace android { return jni::Object<jni::ObjectTag>(*converted); } + jni::Object<jni::ObjectTag> CircleLayer::getCirclePitchAlignment(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result<jni::jobject*> converted = convert<jni::jobject*>(env, layer.as<mbgl::style::CircleLayer>()->CircleLayer::getCirclePitchAlignment()); + return jni::Object<jni::ObjectTag>(*converted); + } + jni::Object<jni::ObjectTag> CircleLayer::getCircleStrokeWidth(jni::JNIEnv& env) { using namespace mbgl::android::conversion; Result<jni::jobject*> converted = convert<jni::jobject*>(env, layer.as<mbgl::style::CircleLayer>()->CircleLayer::getCircleStrokeWidth()); @@ -236,6 +242,7 @@ namespace android { METHOD(&CircleLayer::getCircleTranslate, "nativeGetCircleTranslate"), METHOD(&CircleLayer::getCircleTranslateAnchor, "nativeGetCircleTranslateAnchor"), METHOD(&CircleLayer::getCirclePitchScale, "nativeGetCirclePitchScale"), + METHOD(&CircleLayer::getCirclePitchAlignment, "nativeGetCirclePitchAlignment"), METHOD(&CircleLayer::getCircleStrokeWidthTransition, "nativeGetCircleStrokeWidthTransition"), METHOD(&CircleLayer::setCircleStrokeWidthTransition, "nativeSetCircleStrokeWidthTransition"), METHOD(&CircleLayer::getCircleStrokeWidth, "nativeGetCircleStrokeWidth"), diff --git a/platform/android/src/style/layers/circle_layer.hpp b/platform/android/src/style/layers/circle_layer.hpp index 81737e8996..9d323e92bb 100644 --- a/platform/android/src/style/layers/circle_layer.hpp +++ b/platform/android/src/style/layers/circle_layer.hpp @@ -53,6 +53,8 @@ public: jni::Object<jni::ObjectTag> getCirclePitchScale(jni::JNIEnv&); + jni::Object<jni::ObjectTag> getCirclePitchAlignment(jni::JNIEnv&); + jni::Object<jni::ObjectTag> getCircleStrokeWidth(jni::JNIEnv&); void setCircleStrokeWidthTransition(jni::JNIEnv&, jlong duration, jlong delay); jni::Object<TransitionOptions> getCircleStrokeWidthTransition(jni::JNIEnv&); diff --git a/platform/android/src/style/layers/custom_layer.cpp b/platform/android/src/style/layers/custom_layer.cpp index 9bdc308d85..51a48520bf 100644 --- a/platform/android/src/style/layers/custom_layer.cpp +++ b/platform/android/src/style/layers/custom_layer.cpp @@ -7,11 +7,12 @@ namespace mbgl { namespace android { - CustomLayer::CustomLayer(jni::JNIEnv& env, jni::String layerId, jni::jlong initializeFunction, jni::jlong renderFunction, jni::jlong deinitializeFunction, jni::jlong context) + CustomLayer::CustomLayer(jni::JNIEnv& env, jni::String layerId, jni::jlong initializeFunction, jni::jlong renderFunction, jni::jlong contextLostFunction, jni::jlong deinitializeFunction, jni::jlong context) : Layer(env, std::make_unique<mbgl::style::CustomLayer>( jni::Make<std::string>(env, layerId), reinterpret_cast<mbgl::style::CustomLayerInitializeFunction>(initializeFunction), reinterpret_cast<mbgl::style::CustomLayerRenderFunction>(renderFunction), + reinterpret_cast<mbgl::style::CustomLayerContextLostFunction>(contextLostFunction), reinterpret_cast<mbgl::style::CustomLayerDeinitializeFunction>(deinitializeFunction), reinterpret_cast<void*>(context)) ) { @@ -21,6 +22,10 @@ namespace android { : Layer(map, coreLayer) { } + CustomLayer::CustomLayer(mbgl::Map& map, std::unique_ptr<mbgl::style::CustomLayer> coreLayer) + : Layer(map, std::move(coreLayer)) { + } + CustomLayer::~CustomLayer() = default; void CustomLayer::update(jni::JNIEnv&) { @@ -48,7 +53,7 @@ namespace android { // Register the peer jni::RegisterNativePeer<CustomLayer>( env, CustomLayer::javaClass, "nativePtr", - std::make_unique<CustomLayer, JNIEnv&, jni::String, jni::jlong, jni::jlong, jni::jlong, jni::jlong>, + std::make_unique<CustomLayer, JNIEnv&, jni::String, jni::jlong, jni::jlong, jni::jlong, jni::jlong, jni::jlong>, "initialize", "finalize", METHOD(&CustomLayer::update, "nativeUpdate")); diff --git a/platform/android/src/style/layers/custom_layer.hpp b/platform/android/src/style/layers/custom_layer.hpp index 1173d21bfd..9e079c1288 100644 --- a/platform/android/src/style/layers/custom_layer.hpp +++ b/platform/android/src/style/layers/custom_layer.hpp @@ -16,10 +16,12 @@ public: static void registerNative(jni::JNIEnv&); - CustomLayer(jni::JNIEnv&, jni::String, jni::jlong, jni::jlong, jni::jlong, jni::jlong); + CustomLayer(jni::JNIEnv&, jni::String, jni::jlong, jni::jlong, jni::jlong, jni::jlong, jni::jlong); CustomLayer(mbgl::Map&, mbgl::style::CustomLayer&); + CustomLayer(mbgl::Map&, std::unique_ptr<mbgl::style::CustomLayer>); + ~CustomLayer(); void update(jni::JNIEnv&); diff --git a/platform/android/src/style/layers/layer.cpp b/platform/android/src/style/layers/layer.cpp index d571c3fd2e..02a1f0be82 100644 --- a/platform/android/src/style/layers/layer.cpp +++ b/platform/android/src/style/layers/layer.cpp @@ -3,6 +3,7 @@ #include <jni/jni.hpp> +#include <mbgl/style/style.hpp> #include <mbgl/style/transition_options.hpp> #include <mbgl/util/logging.hpp> @@ -53,7 +54,7 @@ namespace android { } // Add layer to map - _map.addLayer(releaseCoreLayer(), before); + _map.getStyle().addLayer(releaseCoreLayer(), before); // Save pointer to the map this->map = &_map; @@ -91,19 +92,31 @@ namespace android { Value value(env, jvalue); // Convert and set property - optional<mbgl::style::conversion::Error> error = mbgl::style::conversion::setPaintProperty(layer, jni::Make<std::string>(env, jname), value, mbgl::optional<std::string>()); + optional<mbgl::style::conversion::Error> error = mbgl::style::conversion::setPaintProperty(layer, jni::Make<std::string>(env, jname), value); if (error) { mbgl::Log::Error(mbgl::Event::JNI, "Error setting property: " + jni::Make<std::string>(env, jname) + " " + error->message); return; } } + struct SetFilterEvaluator { + style::Filter filter; + + void operator()(style::BackgroundLayer&) { Log::Warning(mbgl::Event::JNI, "BackgroundLayer doesn't support filters"); } + void operator()(style::CustomLayer&) { Log::Warning(mbgl::Event::JNI, "CustomLayer doesn't support filters"); } + void operator()(style::RasterLayer&) { Log::Warning(mbgl::Event::JNI, "RasterLayer doesn't support filters"); } + + template <class LayerType> + void operator()(LayerType& layer) { + layer.setFilter(filter); + } + }; + void Layer::setFilter(jni::JNIEnv& env, jni::Array<jni::Object<>> jfilter) { using namespace mbgl::style; using namespace mbgl::style::conversion; Value wrapped(env, jfilter); - Filter filter; Error error; optional<Filter> converted = convert<Filter>(wrapped, error); @@ -111,62 +124,45 @@ namespace android { mbgl::Log::Error(mbgl::Event::JNI, "Error setting filter: " + error.message); return; } - filter = std::move(*converted); - - if (layer.is<FillLayer>()) { - layer.as<FillLayer>()->setFilter(filter); - } else if (layer.is<LineLayer>()) { - layer.as<LineLayer>()->setFilter(filter); - } else if (layer.is<SymbolLayer>()) { - layer.as<SymbolLayer>()->setFilter(filter); - } else if (layer.is<CircleLayer>()) { - layer.as<CircleLayer>()->setFilter(filter); - } else if (layer.is<FillExtrusionLayer>()){ - layer.as<FillExtrusionLayer>()->setFilter(filter); - } else { - mbgl::Log::Warning(mbgl::Event::JNI, "Layer doesn't support filters"); - } + + layer.accept(SetFilterEvaluator {std::move(*converted)}); } - void Layer::setSourceLayer(jni::JNIEnv& env, jni::String sourceLayer) { - using namespace mbgl::style; + struct SetSourceLayerEvaluator { + std::string sourceLayer; - std::string layerId = jni::Make<std::string>(env, sourceLayer); - - if (layer.is<FillLayer>()) { - layer.as<FillLayer>()->setSourceLayer(layerId); - } else if (layer.is<LineLayer>()) { - layer.as<LineLayer>()->setSourceLayer(layerId); - } else if (layer.is<SymbolLayer>()) { - layer.as<SymbolLayer>()->setSourceLayer(layerId); - } else if (layer.is<CircleLayer>()) { - layer.as<CircleLayer>()->setSourceLayer(layerId); - } else if(layer.is<FillExtrusionLayer>()) { - layer.as<FillExtrusionLayer>()->setSourceLayer(layerId); - } else { - mbgl::Log::Warning(mbgl::Event::JNI, "Layer doesn't support source layer"); + void operator()(style::BackgroundLayer&) { Log::Warning(mbgl::Event::JNI, "BackgroundLayer doesn't support source layer"); } + void operator()(style::CustomLayer&) { Log::Warning(mbgl::Event::JNI, "CustomLayer doesn't support source layer"); } + void operator()(style::RasterLayer&) { Log::Warning(mbgl::Event::JNI, "RasterLayer doesn't support source layer"); } + + template <class LayerType> + void operator()(LayerType& layer) { + layer.setSourceLayer(sourceLayer); } + }; + + void Layer::setSourceLayer(jni::JNIEnv& env, jni::String sourceLayer) { + layer.accept(SetSourceLayerEvaluator {jni::Make<std::string>(env, sourceLayer)}); } - jni::String Layer::getSourceLayer(jni::JNIEnv& env) { - using namespace mbgl::style; + struct GetSourceLayerEvaluator { + std::string noop(std::string layerType) { + Log::Warning(mbgl::Event::JNI, "%s doesn't support source layer", layerType.c_str()); + return {}; + } - std::string sourceLayerId; - if (layer.is<FillLayer>()) { - sourceLayerId = layer.as<FillLayer>()->getSourceLayer(); - } else if (layer.is<LineLayer>()) { - sourceLayerId = layer.as<LineLayer>()->getSourceLayer(); - } else if (layer.is<SymbolLayer>()) { - sourceLayerId = layer.as<SymbolLayer>()->getSourceLayer(); - } else if (layer.is<CircleLayer>()) { - sourceLayerId = layer.as<CircleLayer>()->getSourceLayer(); - } else if (layer.is<FillExtrusionLayer>()) { - sourceLayerId = layer.as<FillExtrusionLayer>()->getSourceLayer(); - } else { - mbgl::Log::Warning(mbgl::Event::JNI, "Layer doesn't support source layer"); + std::string operator()(style::BackgroundLayer&) { return noop("BackgroundLayer"); } + std::string operator()(style::CustomLayer&) { return noop("CustomLayer"); } + std::string operator()(style::RasterLayer&) { return noop("RasterLayer"); } + + template <class LayerType> + std::string operator()(LayerType& layer) { + return layer.getSourceLayer(); } + }; - return jni::Make<jni::String>(env, sourceLayerId); + jni::String Layer::getSourceLayer(jni::JNIEnv& env) { + return jni::Make<jni::String>(env, layer.accept(GetSourceLayerEvaluator())); } jni::jfloat Layer::getMinZoom(jni::JNIEnv&){ diff --git a/platform/android/src/style/layers/layers.cpp b/platform/android/src/style/layers/layers.cpp index 5c49f875ee..9803b6f841 100644 --- a/platform/android/src/style/layers/layers.cpp +++ b/platform/android/src/style/layers/layers.cpp @@ -24,53 +24,51 @@ namespace mbgl { namespace android { -static Layer* initializeLayerPeer(mbgl::Map& map, mbgl::style::Layer& coreLayer) { - if (coreLayer.is<mbgl::style::BackgroundLayer>()) { - return new BackgroundLayer(map, *coreLayer.as<mbgl::style::BackgroundLayer>()); - } else if (coreLayer.is<mbgl::style::CircleLayer>()) { - return new CircleLayer(map, *coreLayer.as<mbgl::style::CircleLayer>()); - } else if (coreLayer.is<mbgl::style::FillExtrusionLayer>()) { - return new FillExtrusionLayer(map, *coreLayer.as<mbgl::style::FillExtrusionLayer>()); - } else if (coreLayer.is<mbgl::style::FillLayer>()) { - return new FillLayer(map, *coreLayer.as<mbgl::style::FillLayer>()); - } else if (coreLayer.is<mbgl::style::LineLayer>()) { - return new LineLayer(map, *coreLayer.as<mbgl::style::LineLayer>()); - } else if (coreLayer.is<mbgl::style::RasterLayer>()) { - return new RasterLayer(map, *coreLayer.as<mbgl::style::RasterLayer>()); - } else if (coreLayer.is<mbgl::style::SymbolLayer>()) { - return new SymbolLayer(map, *coreLayer.as<mbgl::style::SymbolLayer>()); - } else if (coreLayer.is<mbgl::style::CustomLayer>()) { - return new CustomLayer(map, *coreLayer.as<mbgl::style::CustomLayer>()); - } else { - return new UnknownLayer(map, coreLayer); +// Mapping from style layers to peer classes +template <class> struct PeerType {}; +template <> struct PeerType<style::BackgroundLayer> { using Type = android::BackgroundLayer; }; +template <> struct PeerType<style::CircleLayer> { using Type = android::CircleLayer; }; +template <> struct PeerType<style::FillExtrusionLayer> { using Type = android::FillExtrusionLayer; }; +template <> struct PeerType<style::FillLayer> { using Type = android::FillLayer; }; +template <> struct PeerType<style::LineLayer> { using Type = android::LineLayer; }; +template <> struct PeerType<style::RasterLayer> { using Type = android::RasterLayer; }; +template <> struct PeerType<style::SymbolLayer> { using Type = android::SymbolLayer; }; +template <> struct PeerType<style::CustomLayer> { using Type = android::CustomLayer; }; + +// Inititalizes a non-owning peer +struct LayerPeerIntitializer { + mbgl::Map& map; + + template <class LayerType> + Layer* operator()(LayerType& layer) { + return new typename PeerType<LayerType>::Type(map, layer); } -} +}; -template <class LayerType, class PeerType> -static PeerType* createPeer(Map& map, std::unique_ptr<mbgl::style::Layer> layer) { - return new PeerType(map, std::move(std::unique_ptr<LayerType>(layer.release()->as<LayerType>()))); +static Layer* initializeLayerPeer(mbgl::Map& map, mbgl::style::Layer& coreLayer) { + Layer* layer = coreLayer.accept(LayerPeerIntitializer {map}); + return layer ? layer : new UnknownLayer(map, coreLayer); } -static Layer* initializeLayerPeer(Map& map, std::unique_ptr<mbgl::style::Layer> coreLayer) { - if (coreLayer->is<style::BackgroundLayer>()) { - return createPeer<style::BackgroundLayer, BackgroundLayer>(map, std::move(coreLayer)); - } else if (coreLayer->is<style::CircleLayer>()) { - return createPeer<style::CircleLayer, CircleLayer>(map, std::move(coreLayer)); - } else if (coreLayer->is<style::FillExtrusionLayer>()) { - return createPeer<style::FillExtrusionLayer, FillExtrusionLayer>(map, std::move(coreLayer)); - } else if (coreLayer->is<style::FillLayer>()) { - return createPeer<style::FillLayer, FillLayer>(map, std::move(coreLayer)); - } else if (coreLayer->is<style::LineLayer>()) { - return createPeer<style::LineLayer, LineLayer>(map, std::move(coreLayer)); - } else if (coreLayer->is<style::RasterLayer>()) { - return createPeer<style::RasterLayer, RasterLayer>(map, std::move(coreLayer)); - } else if (coreLayer->is<style::SymbolLayer>()) { - return createPeer<style::SymbolLayer, SymbolLayer>(map, std::move(coreLayer)); - } else if (coreLayer->is<mbgl::style::CustomLayer>()) { - return createPeer<style::SymbolLayer, SymbolLayer>(map, std::move(coreLayer)); - } else { - return new UnknownLayer(map, std::move(coreLayer)); +// Initializes an owning peer +// Only usable once since it needs to pass on ownership +// of the given layer and thus enforced to be an rvalue +struct UniqueLayerPeerIntitializer { + mbgl::Map& map; + std::unique_ptr<style::Layer> layer; + + template <class LayerType> + Layer* operator()(LayerType&) && { + return new typename PeerType<LayerType>::Type( + map, + std::unique_ptr<LayerType>(layer.release()->as<LayerType>()) + ); } +}; + +static Layer* initializeLayerPeer(Map& map, std::unique_ptr<mbgl::style::Layer> coreLayer) { + Layer* layer = coreLayer->accept(UniqueLayerPeerIntitializer {map, std::move(coreLayer)}); + return layer ? layer : new UnknownLayer(map, std::move(coreLayer)); } jni::jobject* createJavaLayerPeer(jni::JNIEnv& env, Map& map, style::Layer& coreLayer) { diff --git a/platform/android/src/style/layers/symbol_layer.cpp b/platform/android/src/style/layers/symbol_layer.cpp index 3a560a5deb..d44744a6cf 100644 --- a/platform/android/src/style/layers/symbol_layer.cpp +++ b/platform/android/src/style/layers/symbol_layer.cpp @@ -125,6 +125,18 @@ namespace android { return jni::Object<jni::ObjectTag>(*converted); } + jni::Object<jni::ObjectTag> SymbolLayer::getIconAnchor(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result<jni::jobject*> converted = convert<jni::jobject*>(env, layer.as<mbgl::style::SymbolLayer>()->SymbolLayer::getIconAnchor()); + return jni::Object<jni::ObjectTag>(*converted); + } + + jni::Object<jni::ObjectTag> SymbolLayer::getIconPitchAlignment(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result<jni::jobject*> converted = convert<jni::jobject*>(env, layer.as<mbgl::style::SymbolLayer>()->SymbolLayer::getIconPitchAlignment()); + return jni::Object<jni::ObjectTag>(*converted); + } + jni::Object<jni::ObjectTag> SymbolLayer::getTextPitchAlignment(jni::JNIEnv& env) { using namespace mbgl::android::conversion; Result<jni::jobject*> converted = convert<jni::jobject*>(env, layer.as<mbgl::style::SymbolLayer>()->SymbolLayer::getTextPitchAlignment()); @@ -514,6 +526,8 @@ namespace android { METHOD(&SymbolLayer::getIconPadding, "nativeGetIconPadding"), METHOD(&SymbolLayer::getIconKeepUpright, "nativeGetIconKeepUpright"), METHOD(&SymbolLayer::getIconOffset, "nativeGetIconOffset"), + METHOD(&SymbolLayer::getIconAnchor, "nativeGetIconAnchor"), + METHOD(&SymbolLayer::getIconPitchAlignment, "nativeGetIconPitchAlignment"), METHOD(&SymbolLayer::getTextPitchAlignment, "nativeGetTextPitchAlignment"), METHOD(&SymbolLayer::getTextRotationAlignment, "nativeGetTextRotationAlignment"), METHOD(&SymbolLayer::getTextField, "nativeGetTextField"), diff --git a/platform/android/src/style/layers/symbol_layer.hpp b/platform/android/src/style/layers/symbol_layer.hpp index 8366051c6e..417e5e143f 100644 --- a/platform/android/src/style/layers/symbol_layer.hpp +++ b/platform/android/src/style/layers/symbol_layer.hpp @@ -59,6 +59,10 @@ public: jni::Object<jni::ObjectTag> getIconOffset(jni::JNIEnv&); + jni::Object<jni::ObjectTag> getIconAnchor(jni::JNIEnv&); + + jni::Object<jni::ObjectTag> getIconPitchAlignment(jni::JNIEnv&); + jni::Object<jni::ObjectTag> getTextPitchAlignment(jni::JNIEnv&); jni::Object<jni::ObjectTag> getTextRotationAlignment(jni::JNIEnv&); diff --git a/platform/android/src/style/sources/geojson_source.cpp b/platform/android/src/style/sources/geojson_source.cpp index 780cc4b6f6..90ef851eba 100644 --- a/platform/android/src/style/sources/geojson_source.cpp +++ b/platform/android/src/style/sources/geojson_source.cpp @@ -1,5 +1,7 @@ #include "geojson_source.hpp" +#include <mbgl/renderer/query.hpp> + // Java -> C++ conversion #include "../android_conversion.hpp" #include "../conversion/filter.hpp" @@ -41,8 +43,8 @@ namespace android { ) { } - GeoJSONSource::GeoJSONSource(mbgl::Map& map, mbgl::style::GeoJSONSource& coreSource) - : Source(map, coreSource) { + GeoJSONSource::GeoJSONSource(mbgl::style::GeoJSONSource& coreSource) + : Source(coreSource) { } GeoJSONSource::~GeoJSONSource() = default; @@ -108,8 +110,8 @@ namespace android { using namespace mbgl::android::geojson; std::vector<mbgl::Feature> features; - if (map) { - features = map->querySourceFeatures(source.getID(), { {}, toFilter(env, jfilter) }); + if (rendererFrontend) { + features = rendererFrontend->querySourceFeatures(source.getID(), { {}, toFilter(env, jfilter) }); } return *convert<jni::Array<jni::Object<Feature>>, std::vector<mbgl::Feature>>(env, features); } diff --git a/platform/android/src/style/sources/geojson_source.hpp b/platform/android/src/style/sources/geojson_source.hpp index 938a20612c..52dd632bfa 100644 --- a/platform/android/src/style/sources/geojson_source.hpp +++ b/platform/android/src/style/sources/geojson_source.hpp @@ -21,7 +21,7 @@ public: GeoJSONSource(jni::JNIEnv&, jni::String, jni::Object<>); - GeoJSONSource(mbgl::Map&, mbgl::style::GeoJSONSource&); + GeoJSONSource(mbgl::style::GeoJSONSource&); ~GeoJSONSource(); diff --git a/platform/android/src/style/sources/image_source.cpp b/platform/android/src/style/sources/image_source.cpp new file mode 100644 index 0000000000..d46b367c53 --- /dev/null +++ b/platform/android/src/style/sources/image_source.cpp @@ -0,0 +1,72 @@ +#include "image_source.hpp" + +// Java -> C++ conversion +#include "../android_conversion.hpp" + +// C++ -> Java conversion +#include "../../conversion/conversion.hpp" +#include <mbgl/style/conversion.hpp> +#include <mbgl/util/premultiply.hpp> + +#include "../../bitmap.hpp" +#include <string> +#include <array> + +namespace mbgl { +namespace android { + + ImageSource::ImageSource(jni::JNIEnv& env, jni::String sourceId, jni::Object<LatLngQuad> coordinatesObject) + : Source(env, std::make_unique<mbgl::style::ImageSource>( + jni::Make<std::string>(env, sourceId), + LatLngQuad::getLatLngArray(env, coordinatesObject) + ) + ) { + } + + ImageSource::ImageSource(mbgl::style::ImageSource& coreSource) + : Source(coreSource) { + } + + ImageSource::~ImageSource() = default; + + void ImageSource::setURL(jni::JNIEnv& env, jni::String url) { + // Update the core source + source.as<mbgl::style::ImageSource>()->ImageSource::setURL(jni::Make<std::string>(env, url)); + } + + jni::String ImageSource::getURL(jni::JNIEnv& env) { + optional<std::string> url = source.as<mbgl::style::ImageSource>()->ImageSource::getURL(); + return url ? jni::Make<jni::String>(env, *url) : jni::String(); + } + + void ImageSource::setImage(jni::JNIEnv& env, jni::Object<Bitmap> bitmap) { + source.as<mbgl::style::ImageSource>()->setImage(Bitmap::GetImage(env, bitmap)); + } + + jni::Class<ImageSource> ImageSource::javaClass; + + jni::jobject* ImageSource::createJavaPeer(jni::JNIEnv& env) { + static auto constructor = ImageSource::javaClass.template GetConstructor<jni::jlong>(env); + return ImageSource::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this)); + } + + void ImageSource::registerNative(jni::JNIEnv& env) { + // Lookup the class + ImageSource::javaClass = *jni::Class<ImageSource>::Find(env).NewGlobalRef(env).release(); + + #define METHOD(MethodPtr, name) jni::MakeNativePeerMethod<decltype(MethodPtr), (MethodPtr)>(name) + + // Register the peer + jni::RegisterNativePeer<ImageSource>( + env, ImageSource::javaClass, "nativePtr", + std::make_unique<ImageSource, JNIEnv&, jni::String, jni::Object<LatLngQuad>>, + "initialize", + "finalize", + METHOD(&ImageSource::setURL, "nativeSetUrl"), + METHOD(&ImageSource::getURL, "nativeGetUrl"), + METHOD(&ImageSource::setImage, "nativeSetImage") + ); + } + +} // namespace android +} // namespace mbgl diff --git a/platform/android/src/style/sources/image_source.hpp b/platform/android/src/style/sources/image_source.hpp new file mode 100644 index 0000000000..9787a7294f --- /dev/null +++ b/platform/android/src/style/sources/image_source.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include "source.hpp" +#include "../../geometry/lat_lng_quad.hpp" +#include <mbgl/style/sources/image_source.hpp> +#include <jni/jni.hpp> + +namespace mbgl { +namespace android { + +class Bitmap; + +class ImageSource : public Source { +public: + + static constexpr auto Name() { return "com/mapbox/mapboxsdk/style/sources/ImageSource"; }; + + static jni::Class<ImageSource> javaClass; + + static void registerNative(jni::JNIEnv&); + + ImageSource(jni::JNIEnv&, jni::String, jni::Object<LatLngQuad>); + + ImageSource(mbgl::style::ImageSource&); + + ~ImageSource(); + + void setURL(jni::JNIEnv&, jni::String); + jni::String getURL(jni::JNIEnv&); + + void setImage(jni::JNIEnv&, jni::Object<Bitmap>); + + jni::jobject* createJavaPeer(jni::JNIEnv&); + +}; // class ImageSource + +} // namespace android +} // namespace mbgl diff --git a/platform/android/src/style/sources/raster_source.cpp b/platform/android/src/style/sources/raster_source.cpp index 32fdb163b0..d45342a1ad 100644 --- a/platform/android/src/style/sources/raster_source.cpp +++ b/platform/android/src/style/sources/raster_source.cpp @@ -22,8 +22,8 @@ namespace android { ) { } - RasterSource::RasterSource(mbgl::Map& map, mbgl::style::RasterSource& coreSource) - : Source(map, coreSource) { + RasterSource::RasterSource(mbgl::style::RasterSource& coreSource) + : Source(coreSource) { } RasterSource::~RasterSource() = default; diff --git a/platform/android/src/style/sources/raster_source.hpp b/platform/android/src/style/sources/raster_source.hpp index a79ccc10a4..84c49d7381 100644 --- a/platform/android/src/style/sources/raster_source.hpp +++ b/platform/android/src/style/sources/raster_source.hpp @@ -18,7 +18,7 @@ public: RasterSource(jni::JNIEnv&, jni::String, jni::Object<>, jni::jint); - RasterSource(mbgl::Map&, mbgl::style::RasterSource&); + RasterSource(mbgl::style::RasterSource&); ~RasterSource(); diff --git a/platform/android/src/style/sources/source.cpp b/platform/android/src/style/sources/source.cpp index e0e9bb9870..447b13019d 100644 --- a/platform/android/src/style/sources/source.cpp +++ b/platform/android/src/style/sources/source.cpp @@ -3,6 +3,7 @@ #include <jni/jni.hpp> +#include <mbgl/style/style.hpp> #include <mbgl/util/logging.hpp> // Java -> C++ conversion @@ -25,11 +26,11 @@ namespace android { , source(*ownedSource) { } - Source::Source(mbgl::Map& coreMap, mbgl::style::Source& coreSource) : source(coreSource) , map(&coreMap) { + Source::Source(mbgl::style::Source& coreSource) + : source(coreSource) { } - Source::~Source() { - } + Source::~Source() = default; style::Source& Source::get() { return source; @@ -55,10 +56,11 @@ namespace android { } // Add source to map - _map.addSource(releaseCoreSource()); + _map.getStyle().addSource(releaseCoreSource()); + } - // Save pointer to the map - this->map = &_map; + void Source::setRendererFrontend(AndroidRendererFrontend& frontend_) { + rendererFrontend = &frontend_; } std::unique_ptr<mbgl::style::Source> Source::releaseCoreSource() { diff --git a/platform/android/src/style/sources/source.hpp b/platform/android/src/style/sources/source.hpp index 49fc50d754..383017b66f 100644 --- a/platform/android/src/style/sources/source.hpp +++ b/platform/android/src/style/sources/source.hpp @@ -5,6 +5,7 @@ #include <mbgl/style/source.hpp> #include "../value.hpp" +#include "../../android_renderer_frontend.hpp" #include <jni/jni.hpp> @@ -23,7 +24,7 @@ public: /* * Called when a Java object is created on the c++ side */ - Source(mbgl::Map&, mbgl::style::Source&); + Source(mbgl::style::Source&); /* * Called when a Java object was created from the jvm side @@ -41,6 +42,8 @@ public: void addToMap(mbgl::Map&); + void setRendererFrontend(AndroidRendererFrontend&); + virtual jni::jobject* createJavaPeer(jni::JNIEnv&) = 0; jni::String getId(jni::JNIEnv&); @@ -57,8 +60,9 @@ protected: // Raw pointer that is valid until the source is removed from the map mbgl::style::Source& source; - // Map pointer is valid for newly created sources only after adding to the map - mbgl::Map* map; + // RendererFrontend pointer is valid only when + // added to the map + AndroidRendererFrontend* rendererFrontend; }; } // namespace android diff --git a/platform/android/src/style/sources/sources.cpp b/platform/android/src/style/sources/sources.cpp index b4e70202b4..9ab3ca8e84 100644 --- a/platform/android/src/style/sources/sources.cpp +++ b/platform/android/src/style/sources/sources.cpp @@ -2,35 +2,46 @@ #include <mbgl/style/source.hpp> #include <mbgl/style/sources/geojson_source.hpp> +#include <mbgl/style/sources/image_source.hpp> #include <mbgl/style/sources/raster_source.hpp> #include <mbgl/style/sources/vector_source.hpp> #include "source.hpp" #include "geojson_source.hpp" +#include "image_source.hpp" #include "raster_source.hpp" #include "unknown_source.hpp" #include "vector_source.hpp" +namespace { + + using namespace mbgl::android; + + Source* initializeSourcePeer(mbgl::style::Source& coreSource) { + Source* source; + if (coreSource.is<mbgl::style::VectorSource>()) { + source = new VectorSource(*coreSource.as<mbgl::style::VectorSource>()); + } else if (coreSource.is<mbgl::style::RasterSource>()) { + source = new RasterSource(*coreSource.as<mbgl::style::RasterSource>()); + } else if (coreSource.is<mbgl::style::GeoJSONSource>()) { + source = new GeoJSONSource(*coreSource.as<mbgl::style::GeoJSONSource>()); + } else if (coreSource.is<mbgl::style::ImageSource>()) { + source = new ImageSource(*coreSource.as<mbgl::style::ImageSource>()); + } else { + source = new UnknownSource(coreSource); + } + + return source; + } +} // namespace + namespace mbgl { namespace android { -Source* initializeSourcePeer(mbgl::Map& map, mbgl::style::Source& coreSource) { - Source* source; - if (coreSource.is<mbgl::style::VectorSource>()) { - source = new VectorSource(map, *coreSource.as<mbgl::style::VectorSource>()); - } else if (coreSource.is<mbgl::style::RasterSource>()) { - source = new RasterSource(map, *coreSource.as<mbgl::style::RasterSource>()); - } else if (coreSource.is<mbgl::style::GeoJSONSource>()) { - source = new GeoJSONSource(map, *coreSource.as<mbgl::style::GeoJSONSource>()); - } else { - source = new UnknownSource(map, coreSource); - } - - return source; -} -jni::jobject* createJavaSourcePeer(jni::JNIEnv& env, mbgl::Map& map, mbgl::style::Source& coreSource) { - std::unique_ptr<Source> peerSource = std::unique_ptr<Source>(initializeSourcePeer(map, coreSource)); +jni::jobject* createJavaSourcePeer(jni::JNIEnv& env, AndroidRendererFrontend& frontend, mbgl::style::Source& coreSource) { + std::unique_ptr<Source> peerSource = std::unique_ptr<Source>(initializeSourcePeer(coreSource)); + peerSource->setRendererFrontend(frontend); jni::jobject* result = peerSource->createJavaPeer(env); peerSource.release(); return result; @@ -39,6 +50,7 @@ jni::jobject* createJavaSourcePeer(jni::JNIEnv& env, mbgl::Map& map, mbgl::style void registerNativeSources(jni::JNIEnv& env) { Source::registerNative(env); GeoJSONSource::registerNative(env); + ImageSource::registerNative(env); RasterSource::registerNative(env); UnknownSource::registerNative(env); VectorSource::registerNative(env); diff --git a/platform/android/src/style/sources/sources.hpp b/platform/android/src/style/sources/sources.hpp index 09a8b35067..c7b36818b2 100644 --- a/platform/android/src/style/sources/sources.hpp +++ b/platform/android/src/style/sources/sources.hpp @@ -1,20 +1,18 @@ #pragma once -#include <mbgl/map/map.hpp> #include <mbgl/style/source.hpp> #include "source.hpp" +#include "../../android_renderer_frontend.hpp" #include <jni/jni.hpp> namespace mbgl { namespace android { - mbgl::android::Source* initializeSourcePeer(mbgl::Map&, mbgl::style::Source&); - - jni::jobject* createJavaSourcePeer(jni::JNIEnv&, mbgl::Map&, mbgl::style::Source&); + jni::jobject* createJavaSourcePeer(jni::JNIEnv&, AndroidRendererFrontend&, mbgl::style::Source&); void registerNativeSources(jni::JNIEnv&); -} -} +} // namespace android +} // namespace mbgl diff --git a/platform/android/src/style/sources/unknown_source.cpp b/platform/android/src/style/sources/unknown_source.cpp index 86736597c3..79f27bdfbf 100644 --- a/platform/android/src/style/sources/unknown_source.cpp +++ b/platform/android/src/style/sources/unknown_source.cpp @@ -12,8 +12,8 @@ namespace { namespace mbgl { namespace android { - UnknownSource::UnknownSource(mbgl::Map& map, mbgl::style::Source& coreSource) - : Source(map, coreSource) { + UnknownSource::UnknownSource(mbgl::style::Source& coreSource) + : Source(coreSource) { } jni::Class<UnknownSource> UnknownSource::javaClass; diff --git a/platform/android/src/style/sources/unknown_source.hpp b/platform/android/src/style/sources/unknown_source.hpp index 3c37239792..4a003c9a7f 100644 --- a/platform/android/src/style/sources/unknown_source.hpp +++ b/platform/android/src/style/sources/unknown_source.hpp @@ -16,7 +16,7 @@ public: static void registerNative(jni::JNIEnv&); - UnknownSource(mbgl::Map&, mbgl::style::Source&); + UnknownSource(mbgl::style::Source&); ~UnknownSource() = default; diff --git a/platform/android/src/style/sources/vector_source.cpp b/platform/android/src/style/sources/vector_source.cpp index e2d9f60dec..7fe45441bd 100644 --- a/platform/android/src/style/sources/vector_source.cpp +++ b/platform/android/src/style/sources/vector_source.cpp @@ -1,5 +1,7 @@ #include "vector_source.hpp" +#include <mbgl/renderer/query.hpp> + // Java -> C++ conversion #include "../android_conversion.hpp" #include "../conversion/filter.hpp" @@ -28,8 +30,8 @@ namespace android { ) { } - VectorSource::VectorSource(mbgl::Map& map, mbgl::style::VectorSource& coreSource) - : Source(map, coreSource) { + VectorSource::VectorSource(mbgl::style::VectorSource& coreSource) + : Source(coreSource) { } VectorSource::~VectorSource() = default; @@ -46,8 +48,8 @@ namespace android { using namespace mbgl::android::geojson; std::vector<mbgl::Feature> features; - if (map) { - features = map->querySourceFeatures(source.getID(), { toVector(env, jSourceLayerIds), toFilter(env, jfilter) }); + if (rendererFrontend) { + features = rendererFrontend->querySourceFeatures(source.getID(), { toVector(env, jSourceLayerIds), toFilter(env, jfilter) }); } return *convert<jni::Array<jni::Object<Feature>>, std::vector<mbgl::Feature>>(env, features); } diff --git a/platform/android/src/style/sources/vector_source.hpp b/platform/android/src/style/sources/vector_source.hpp index 643b468338..509fe068d1 100644 --- a/platform/android/src/style/sources/vector_source.hpp +++ b/platform/android/src/style/sources/vector_source.hpp @@ -19,7 +19,7 @@ public: VectorSource(jni::JNIEnv&, jni::String, jni::Object<>); - VectorSource(mbgl::Map&, mbgl::style::VectorSource&); + VectorSource(mbgl::style::VectorSource&); ~VectorSource(); |