#pragma once #include #include #include #include #include #include #include #include #include #include #include namespace mbgl { namespace style { template ::value>> optional parseConstant(const char* name, const JSValue&); template <> optional parseConstant(const char*, const JSValue&); template <> optional parseConstant(const char*, const JSValue&); template <> optional parseConstant(const char*, const JSValue&); template <> optional parseConstant(const char*, const JSValue&); template <> optional> parseConstant(const char*, const JSValue&); template <> optional> parseConstant(const char*, const JSValue&); template <> optional> parseConstant(const char*, const JSValue&); template optional parseConstant(const char* name, const JSValue& value, typename std::enable_if_t::value, void*> = nullptr) { if (!value.IsString()) { Log::Warning(Event::ParseStyle, "value of '%s' must be a string", name); return {}; } const auto result = Enum::toEnum({ value.GetString(), value.GetStringLength() }); if (!result) { Log::Warning(Event::ParseStyle, "value of '%s' must be a valid enumeration value", name); } return result; } template PropertyValue parseProperty(const char* name, const JSValue& value) { if (!value.IsObject()) { auto constant = parseConstant(name, value); if (!constant) { return {}; } return *constant; } if (!value.HasMember("stops")) { Log::Warning(Event::ParseStyle, "function must specify a function type"); return {}; } float base = 1.0f; if (value.HasMember("base")) { const JSValue& value_base = value["base"]; if (!value_base.IsNumber()) { Log::Warning(Event::ParseStyle, "base must be numeric"); return {}; } base = value_base.GetDouble(); } const JSValue& stopsValue = value["stops"]; if (!stopsValue.IsArray()) { Log::Warning(Event::ParseStyle, "stops function must specify a stops array"); return {}; } std::vector> stops; for (rapidjson::SizeType i = 0; i < stopsValue.Size(); ++i) { const JSValue& stop = stopsValue[i]; if (!stop.IsArray()) { Log::Warning(Event::ParseStyle, "function argument must be a numeric value"); return {}; } if (stop.Size() != 2) { Log::Warning(Event::ParseStyle, "stop must have zoom level and value specification"); return {}; } const JSValue& z = stop[rapidjson::SizeType(0)]; if (!z.IsNumber()) { Log::Warning(Event::ParseStyle, "zoom level in stop must be a number"); return {}; } optional v = parseConstant(name, stop[rapidjson::SizeType(1)]); if (!v) { return {}; } stops.emplace_back(z.GetDouble(), *v); } return Function(stops, base); } optional parseTransitionOptions(const char * name, const JSValue&); } // namespace style } // namespace mbgl