diff options
Diffstat (limited to 'platform/node/src/node_map.cpp')
-rw-r--r-- | platform/node/src/node_map.cpp | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/platform/node/src/node_map.cpp b/platform/node/src/node_map.cpp index 641816dc00..7450f461f8 100644 --- a/platform/node/src/node_map.cpp +++ b/platform/node/src/node_map.cpp @@ -117,6 +117,9 @@ ParseError)JS").ToLocalChecked()).ToLocalChecked(); Nan::SetPrototypeMethod(tpl, "setAxonometric", SetAxonometric); Nan::SetPrototypeMethod(tpl, "setXSkew", SetXSkew); Nan::SetPrototypeMethod(tpl, "setYSkew", SetYSkew); + Nan::SetPrototypeMethod(tpl, "setFeatureState", SetFeatureState); + Nan::SetPrototypeMethod(tpl, "getFeatureState", GetFeatureState); + Nan::SetPrototypeMethod(tpl, "removeFeatureState", RemoveFeatureState); Nan::SetPrototypeMethod(tpl, "dumpDebugLogs", DumpDebugLogs); Nan::SetPrototypeMethod(tpl, "queryRenderedFeatures", QueryRenderedFeatures); @@ -1099,6 +1102,224 @@ void NodeMap::SetYSkew(const Nan::FunctionCallbackInfo<v8::Value>& info) { info.GetReturnValue().SetUndefined(); } +void NodeMap::SetFeatureState(const Nan::FunctionCallbackInfo<v8::Value>& info) { + using namespace mbgl; + using namespace mbgl::style::conversion; + + auto nodeMap = Nan::ObjectWrap::Unwrap<NodeMap>(info.Holder()); + if (!nodeMap->map) return Nan::ThrowError(releasedMessage()); + + if (info.Length() < 2) { + return Nan::ThrowTypeError("Two arguments required"); + } + + if (!info[0]->IsObject() || !info[1]->IsObject()) { + return Nan::ThrowTypeError("Both arguments must be objects"); + } + + std::string sourceID, featureID; + mbgl::optional<std::string> sourceLayerID; + auto feature = Nan::To<v8::Object>(info[0]).ToLocalChecked(); + if (Nan::Has(feature, Nan::New("source").ToLocalChecked()).FromJust()) { + auto sourceOption = Nan::Get(feature, Nan::New("source").ToLocalChecked()).ToLocalChecked(); + if (!sourceOption->IsString()) { + return Nan::ThrowTypeError("Requires feature.source property to be a string"); + } + sourceID = *Nan::Utf8String(sourceOption); + } else { + return Nan::ThrowTypeError("SetFeatureState: Requires feature.source property"); + } + + if (Nan::Has(feature, Nan::New("sourceLayer").ToLocalChecked()).FromJust()) { + auto sourceLayerOption = Nan::Get(feature, Nan::New("sourceLayer").ToLocalChecked()).ToLocalChecked(); + if (!sourceLayerOption->IsString()) { + return Nan::ThrowTypeError("SetFeatureState: Requires feature.sourceLayer property to be a string"); + } + sourceLayerID = {*Nan::Utf8String(sourceLayerOption)}; + } + + if (Nan::Has(feature, Nan::New("id").ToLocalChecked()).FromJust()) { + auto idOption = Nan::Get(feature, Nan::New("id").ToLocalChecked()).ToLocalChecked(); + if (!idOption->IsString() && !(idOption->IsNumber() || idOption->IsString())) { + return Nan::ThrowTypeError("Requires feature.id property to be a string or a number"); + } + featureID = *Nan::Utf8String(idOption); + } else { + return Nan::ThrowTypeError("SetFeatureState: Requires feature.id property"); + } + + Convertible state(info[1]); + + if (!isObject(state)) { + return Nan::ThrowTypeError("Feature state must be an object"); + } + + std::string sourceLayer = sourceLayerID.value_or(std::string()); + std::string stateKey; + Value stateValue; + bool valueParsed = false; + FeatureState newState; + + const std::function<optional<Error>(const std::string&, const Convertible&)> convertFn = + [&](const std::string& k, const Convertible& v) -> optional<Error> { + optional<Value> value = toValue(v); + if (value) { + stateValue = std::move(*value); + valueParsed = true; + } else if (isArray(v)) { + std::vector<Value> array; + std::size_t length = arrayLength(v); + array.reserve(length); + for (size_t i = 0; i < length; ++i) { + optional<Value> arrayVal = toValue(arrayMember(v, i)); + if (arrayVal) { + array.emplace_back(*arrayVal); + } + } + std::unordered_map<std::string, Value> result; + result[k] = std::move(array); + stateValue = std::move(result); + valueParsed = true; + return {}; + + } else if (isObject(v)) { + eachMember(v, convertFn); + } + if (!valueParsed) { + Nan::ThrowTypeError("Could not get feature state value"); + return nullopt; + } + stateKey = k; + newState[stateKey] = stateValue; + return nullopt; + }; + + eachMember(state, convertFn); + + try { + nodeMap->frontend->getRenderer()->setFeatureState(sourceID, sourceLayerID, featureID, newState); + } catch (const std::exception& ex) { + return Nan::ThrowError(ex.what()); + } + + info.GetReturnValue().SetUndefined(); +} + +void NodeMap::GetFeatureState(const Nan::FunctionCallbackInfo<v8::Value>& info) { + auto nodeMap = Nan::ObjectWrap::Unwrap<NodeMap>(info.Holder()); + if (!nodeMap->map) return Nan::ThrowError(releasedMessage()); + + if (info.Length() < 1) { + return Nan::ThrowTypeError("One argument required"); + } + + if (!info[0]->IsObject() || !info[1]->IsObject()) { + return Nan::ThrowTypeError("Argument must be object"); + } + + std::string sourceID, featureID; + mbgl::optional<std::string> sourceLayerID; + auto feature = Nan::To<v8::Object>(info[0]).ToLocalChecked(); + if (Nan::Has(feature, Nan::New("source").ToLocalChecked()).FromJust()) { + auto sourceOption = Nan::Get(feature, Nan::New("source").ToLocalChecked()).ToLocalChecked(); + if (!sourceOption->IsString()) { + return Nan::ThrowTypeError("Requires feature.source property to be a string"); + } + sourceID = *Nan::Utf8String(sourceOption); + } else { + return Nan::ThrowTypeError("GetFeatureState: Requires feature.source property"); + } + + if (Nan::Has(feature, Nan::New("sourceLayer").ToLocalChecked()).FromJust()) { + auto sourceLayerOption = Nan::Get(feature, Nan::New("sourceLayer").ToLocalChecked()).ToLocalChecked(); + if (!sourceLayerOption->IsString()) { + return Nan::ThrowTypeError("GetFeatureState: Requires feature.sourceLayer property to be a string"); + } + sourceLayerID = {*Nan::Utf8String(sourceLayerOption)}; + } + + if (Nan::Has(feature, Nan::New("id").ToLocalChecked()).FromJust()) { + auto idOption = Nan::Get(feature, Nan::New("id").ToLocalChecked()).ToLocalChecked(); + if (!idOption->IsString() && !(idOption->IsNumber() || idOption->IsString())) { + return Nan::ThrowTypeError("Requires feature.id property to be a string or a number"); + } + featureID = *Nan::Utf8String(idOption); + } else { + return Nan::ThrowTypeError("GetFeatureState: Requires feature.id property"); + } + + mbgl::FeatureState state; + try { + nodeMap->frontend->getRenderer()->getFeatureState(state, sourceID, sourceLayerID, featureID); + } catch (const std::exception& ex) { + return Nan::ThrowError(ex.what()); + } + + info.GetReturnValue().SetUndefined(); +} + +void NodeMap::RemoveFeatureState(const Nan::FunctionCallbackInfo<v8::Value>& info) { + auto nodeMap = Nan::ObjectWrap::Unwrap<NodeMap>(info.Holder()); + if (!nodeMap->map) return Nan::ThrowError(releasedMessage()); + + if (info.Length() < 1) { + return Nan::ThrowTypeError("At least one argument required"); + } + + if (!info[0]->IsObject()) { + return Nan::ThrowTypeError("Argument 1 must be object"); + } + + if (info.Length() == 2 && !info[1]->IsString()) { + return Nan::ThrowTypeError("argument 2 must be string"); + } + + std::string sourceID; + mbgl::optional<std::string> sourceLayerID, featureID, stateKey; + auto feature = Nan::To<v8::Object>(info[0]).ToLocalChecked(); + if (Nan::Has(feature, Nan::New("source").ToLocalChecked()).FromJust()) { + auto sourceOption = Nan::Get(feature, Nan::New("source").ToLocalChecked()).ToLocalChecked(); + if (!sourceOption->IsString()) { + return Nan::ThrowTypeError("Requires feature.source property to be a string"); + } + sourceID = *Nan::Utf8String(sourceOption); + } else { + return Nan::ThrowTypeError("RemoveFeatureState: Requires feature.source property"); + } + + if (Nan::Has(feature, Nan::New("sourceLayer").ToLocalChecked()).FromJust()) { + auto sourceLayerOption = Nan::Get(feature, Nan::New("sourceLayer").ToLocalChecked()).ToLocalChecked(); + if (!sourceLayerOption->IsString()) { + return Nan::ThrowTypeError("RemoveFeatureState: Requires feature.sourceLayer property to be a string"); + } + sourceLayerID = {*Nan::Utf8String(sourceLayerOption)}; + } + + if (Nan::Has(feature, Nan::New("id").ToLocalChecked()).FromJust()) { + auto idOption = Nan::Get(feature, Nan::New("id").ToLocalChecked()).ToLocalChecked(); + if (!idOption->IsString() && !(idOption->IsNumber() || idOption->IsString())) { + return Nan::ThrowTypeError("Requires feature.id property to be a string or a number"); + } + featureID = {*Nan::Utf8String(idOption)}; + } + + if (info.Length() == 2) { + auto keyParam = Nan::To<v8::String>(info[1]).ToLocalChecked(); + if (!keyParam->IsString()) { + return Nan::ThrowTypeError("RemoveFeatureState: Requires feature key property to be a string"); + } + stateKey = {*Nan::Utf8String(keyParam)}; + } + + try { + nodeMap->frontend->getRenderer()->removeFeatureState(sourceID, sourceLayerID, featureID, stateKey); + } catch (const std::exception& ex) { + return Nan::ThrowError(ex.what()); + } + + info.GetReturnValue().SetUndefined(); +} + void NodeMap::DumpDebugLogs(const Nan::FunctionCallbackInfo<v8::Value>& info) { auto nodeMap = Nan::ObjectWrap::Unwrap<NodeMap>(info.Holder()); if (!nodeMap->map) return Nan::ThrowError(releasedMessage()); |