5#include <rapidjson/document.h>
6#include <rapidjson/stringbuffer.h>
7#include <rapidjson/writer.h>
12inline std::string withCityWeatherStyle(
const std::string& style) {
13 rapidjson::Document document;
14 document.Parse(style.c_str());
15 if (document.HasParseError() || !document.IsObject() ||
16 !document.HasMember(
"sources") || !document[
"sources"].IsObject() ||
17 !document.HasMember(
"layers") || !document[
"layers"].IsArray()) {
18 throw std::runtime_error(
"map style has invalid sources or layers");
20 rapidjson::Document additions;
22 "source":{"type":"geojson","data":{"type":"FeatureCollection","features":[]}},
24 {"id":"city-weather-points","type":"circle","source":"city-weather",
25 "paint":{"circle-radius":3,"circle-color":"#ffffff",
26 "circle-stroke-color":"#141d26","circle-stroke-width":1}},
27 {"id":"city-weather-labels","type":"symbol","source":"city-weather",
28 "layout":{"text-field":["format",["get","value"],{"font-scale":1.8},
29 "\n",{},["get","name"],{"font-scale":0.9}],
30 "text-size":14,"text-font":["KlokanTech Noto Sans CJK Regular"],
31 "text-anchor":"bottom","text-offset":[0,-0.6],
32 "text-allow-overlap":false},
33 "paint":{"text-color":["get","color"],"text-halo-color":"#101820","text-halo-width":2}},
34 {"id":"city-weather-hover-glow","type":"circle","source":"city-weather-hover",
35 "paint":{"circle-radius":10,"circle-color":"#fff3a6","circle-opacity":0.3,"circle-blur":0.8}},
36 {"id":"city-weather-hover-label","type":"symbol","source":"city-weather-hover",
37 "layout":{"text-field":["format",["get","value"],{"font-scale":1.8},
38 "\n",{},["get","name"],{"font-scale":0.9}],
39 "text-size":14,"text-font":["KlokanTech Noto Sans CJK Regular"],
40 "text-anchor":"bottom","text-offset":[0,-0.6],
41 "text-allow-overlap":true,"text-ignore-placement":true},
42 "paint":{"text-color":"#fffbd9","text-halo-color":"#101820",
43 "text-halo-width":2,"text-halo-blur":0}}
45 auto& allocator = document.GetAllocator();
46 for (
const char* sourceId : {
"city-weather",
"city-weather-hover"}) {
47 if (!document[
"sources"].HasMember(sourceId)) {
48 rapidjson::Value source;
49 source.CopyFrom(additions[
"source"], allocator);
50 document[
"sources"].AddMember(rapidjson::Value(sourceId, allocator), source, allocator);
53 for (
const auto& layer : additions[
"layers"].GetArray()) {
55 for (
const auto& installed : document[
"layers"].GetArray()) {
56 if (installed.IsObject() && installed.HasMember(
"id") && installed[
"id"].IsString() &&
57 std::string(installed[
"id"].GetString()) == layer[
"id"].GetString()) {
63 rapidjson::Value copy;
64 copy.CopyFrom(layer, allocator);
65 document[
"layers"].PushBack(copy, allocator);
68 rapidjson::StringBuffer buffer;
69 rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
70 document.Accept(writer);
71 return buffer.GetString();