diff --git a/include/mbgl/style/conversion.hpp b/include/mbgl/style/conversion.hpp index d6fb3a6dd..27504a89b 100644 --- a/include/mbgl/style/conversion.hpp +++ b/include/mbgl/style/conversion.hpp @@ -46,6 +46,7 @@ namespace conversion { * `toBool(v)` -- returns `optional`, absence indicating `v` is not a JSON boolean * `toNumber(v)` -- returns `optional`, absence indicating `v` is not a JSON number + * `toDouble(v)` -- returns `optional`, absence indicating `v` is not a JSON number * `toString(v)` -- returns `optional`, absence indicating `v` is not a JSON string * `toValue(v)` -- returns `optional`, a variant type, for generic conversion, absence indicating `v` is not a boolean, number, or string. Numbers should be converted to diff --git a/include/mbgl/style/conversion/coordinate.hpp b/include/mbgl/style/conversion/coordinate.hpp index 0adbb9a7e..736f5e94a 100644 --- a/include/mbgl/style/conversion/coordinate.hpp +++ b/include/mbgl/style/conversion/coordinate.hpp @@ -8,17 +8,17 @@ namespace style { namespace conversion { template<> -struct Converter> { +struct Converter { public: template - optional> operator() (const V& value, Error& error) const { + optional operator() (const V& value, Error& error) const { if (!isArray(value) || arrayLength(value) < 2 ) { error = { "coordinate array must contain numeric longtitude and latitude values" }; return {}; } //Style spec uses GeoJSON convention for specifying coordinates - optional latitude = toNumber(arrayMember(value, 1)); - optional longitude = toNumber(arrayMember(value, 0)); + optional latitude = toDouble(arrayMember(value, 1)); + optional longitude = toDouble(arrayMember(value, 0)); if (!latitude || !longitude) { error = { "coordinate array must contain numeric longtitude and latitude values" }; @@ -28,7 +28,7 @@ public: error = { "coordinate latitude must be between -90 and 90" }; return {}; } - return { std::make_unique(*latitude, *longitude) }; + return LatLng(*latitude, *longitude); } }; diff --git a/platform/android/src/style/android_conversion.hpp b/platform/android/src/style/android_conversion.hpp index e2b268592..790c82a1c 100644 --- a/platform/android/src/style/android_conversion.hpp +++ b/platform/android/src/style/android_conversion.hpp @@ -66,6 +66,15 @@ inline optional toNumber(const mbgl::android::Value& value) { } } +inline optional toDouble(const mbgl::android::Value& value) { + if (value.isNumber()) { + auto num = value.toDouble(); + return num; + } else { + return {}; + } +} + inline optional toString(const mbgl::android::Value& value) { if (value.isString()) { return value.toString(); diff --git a/platform/darwin/src/MGLConversion.h b/platform/darwin/src/MGLConversion.h index d51ebd775..d6363b28e 100644 --- a/platform/darwin/src/MGLConversion.h +++ b/platform/darwin/src/MGLConversion.h @@ -104,6 +104,14 @@ inline optional toNumber(const id value) { } } +inline optional toDouble(const id value) { + if (_isNumber(value)) { + return ((NSNumber *)value).doubleValue; + } else { + return {}; + } +} + inline optional toString(const id value) { if (_isString(value)) { return std::string(static_cast([value UTF8String])); diff --git a/platform/node/src/node_conversion.hpp b/platform/node/src/node_conversion.hpp index 22daedef6..d26674554 100644 --- a/platform/node/src/node_conversion.hpp +++ b/platform/node/src/node_conversion.hpp @@ -82,6 +82,14 @@ inline optional toNumber(v8::Local value) { return value->NumberValue(); } +inline optional toDouble(v8::Local value) { + Nan::HandleScope scope; + if (!value->IsNumber()) { + return {}; + } + return value->NumberValue(); +} + inline optional toString(v8::Local value) { Nan::HandleScope scope; if (!value->IsString()) { diff --git a/platform/qt/src/qt_conversion.hpp b/platform/qt/src/qt_conversion.hpp index 4b93ca742..40d7e5b92 100644 --- a/platform/qt/src/qt_conversion.hpp +++ b/platform/qt/src/qt_conversion.hpp @@ -83,6 +83,13 @@ inline optional toNumber(const QVariant& value) { return {}; } } +inline optional toDouble(const QVariant& value) { + if (value.type() == QVariant::Int || value.type() == QVariant::Double) { + return value.toDouble(); + } else { + return {}; + } +} inline optional toString(const QVariant& value) { if (value.type() == QVariant::String) { diff --git a/src/mbgl/style/rapidjson_conversion.hpp b/src/mbgl/style/rapidjson_conversion.hpp index 101fe67ec..48a764ccb 100644 --- a/src/mbgl/style/rapidjson_conversion.hpp +++ b/src/mbgl/style/rapidjson_conversion.hpp @@ -62,6 +62,13 @@ inline optional toNumber(const JSValue& value) { return value.GetDouble(); } +inline optional toDouble(const JSValue& value) { + if (!value.IsNumber()) { + return {}; + } + return value.GetDouble(); +} + inline optional toString(const JSValue& value) { if (!value.IsString()) { return {}; diff --git a/test/src/mbgl/test/conversion_stubs.hpp b/test/src/mbgl/test/conversion_stubs.hpp index e6581c5e5..30395ddb9 100644 --- a/test/src/mbgl/test/conversion_stubs.hpp +++ b/test/src/mbgl/test/conversion_stubs.hpp @@ -17,6 +17,7 @@ using ValueMap = std::unordered_map; using ValueVector = std::vector; class Value : public mbgl::variant, mapbox::util::recursive_wrapper> { @@ -90,6 +91,14 @@ inline optional toNumber(const Value& value) { return {}; } + +inline optional toDouble(const Value& value) { + if (value.is()) { + return value.get(); + } + return {}; +} + inline optional toString(const Value& value) { if (value.is()) { return value.get();