summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2016-01-13 12:07:33 +0100
committerJohn Firebaugh <john.firebaugh@gmail.com>2016-01-13 13:04:59 -0800
commite8705d535d56415ff8f97db1ad6b5a77ed3fcd4a (patch)
tree7c825e483be49a7b069fc30cf79fa83bfa8b1a39
parentcef05b9017d4e54e61354a278120ff67879f2acb (diff)
downloadqtlocation-mapboxgl-e8705d535d56415ff8f97db1ad6b5a77ed3fcd4a.tar.gz
[core] move SourceInfo parsing to StyleParser
-rw-r--r--src/mbgl/annotation/annotation_manager.cpp2
-rw-r--r--src/mbgl/map/source.cpp157
-rw-r--r--src/mbgl/map/source.hpp14
-rw-r--r--src/mbgl/map/source_info.hpp1
-rw-r--r--src/mbgl/style/style_parser.cpp230
-rw-r--r--src/mbgl/style/style_parser.hpp6
-rw-r--r--test/fixtures/style_parser/geojson-missing-data.info.json2
7 files changed, 201 insertions, 211 deletions
diff --git a/src/mbgl/annotation/annotation_manager.cpp b/src/mbgl/annotation/annotation_manager.cpp
index 41bebbbdea..4884ae446f 100644
--- a/src/mbgl/annotation/annotation_manager.cpp
+++ b/src/mbgl/annotation/annotation_manager.cpp
@@ -112,7 +112,7 @@ std::unique_ptr<AnnotationTile> AnnotationManager::getTile(const TileID& tileID)
void AnnotationManager::updateStyle(Style& style) {
// Create annotation source, point layer, and point bucket
if (!style.getSource(SourceID)) {
- std::unique_ptr<Source> source = std::make_unique<Source>(SourceType::Annotations, SourceID);
+ std::unique_ptr<Source> source = std::make_unique<Source>(SourceType::Annotations, SourceID, "", std::make_unique<SourceInfo>(), nullptr);
source->enabled = true;
style.addSource(std::move(source));
diff --git a/src/mbgl/map/source.cpp b/src/mbgl/map/source.cpp
index f4c3f877ed..ed57ddce0b 100644
--- a/src/mbgl/map/source.cpp
+++ b/src/mbgl/map/source.cpp
@@ -27,6 +27,7 @@
#include <mbgl/map/vector_tile_data.hpp>
#include <mbgl/map/raster_tile_data.hpp>
#include <mbgl/style/style.hpp>
+#include <mbgl/style/style_parser.hpp>
#include <mbgl/gl/debugging.hpp>
#include <mapbox/geojsonvt.hpp>
@@ -39,86 +40,18 @@
namespace mbgl {
-namespace {
-
-void parse(const JSValue& value, std::vector<std::string>& target, const char* name) {
- if (!value.HasMember(name)) {
- return;
- }
-
- const JSValue& property = value[name];
- if (!property.IsArray()) {
- return;
- }
-
- for (rapidjson::SizeType i = 0; i < property.Size(); i++) {
- if (!property[i].IsString()) {
- return;
- }
- }
-
- for (rapidjson::SizeType i = 0; i < property.Size(); i++) {
- target.emplace_back(std::string(property[i].GetString(), property[i].GetStringLength()));
- }
-}
-
-void parse(const JSValue& value, std::string& target, const char* name) {
- if (!value.HasMember(name)) {
- return;
- }
-
- const JSValue& property = value[name];
- if (!property.IsString()) {
- return;
- }
-
- target = { property.GetString(), property.GetStringLength() };
+Source::Source(SourceType type_,
+ const std::string& id_,
+ const std::string& url_,
+ std::unique_ptr<SourceInfo>&& info_,
+ std::unique_ptr<mapbox::geojsonvt::GeoJSONVT>&& geojsonvt_)
+ : type(type_),
+ id(id_),
+ url(url_),
+ info(std::move(info_)),
+ geojsonvt(std::move(geojsonvt_)) {
}
-void parse(const JSValue& value, uint16_t& target, const char* name) {
- if (!value.HasMember(name)) {
- return;
- }
-
- const JSValue& property = value[name];
- if (!property.IsUint()) {
- return;
- }
-
- unsigned int uint = property.GetUint();
- if (uint > std::numeric_limits<uint16_t>::max()) {
- return;
- }
-
- target = uint;
-}
-
-template <size_t N>
-void parse(const JSValue& value, std::array<float, N>& target, const char* name) {
- if (!value.HasMember(name)) {
- return;
- }
-
- const JSValue& property = value[name];
- if (!property.IsArray() || property.Size() != N) {
- return;
- }
-
- for (rapidjson::SizeType i = 0; i < property.Size(); i++) {
- if (!property[i].IsNumber()) {
- return;
- }
- }
-
- for (rapidjson::SizeType i = 0; i < property.Size(); i++) {
- target[i] = property[i].GetDouble();
- }
-}
-
-} // end namespace
-
-Source::Source(SourceType type_, const std::string& id_) : type(type_), id(id_) {}
-
Source::~Source() = default;
bool Source::isLoaded() const {
@@ -141,16 +74,22 @@ bool Source::isLoading() const {
// The reason this isn't part of the constructor is that calling shared_from_this() in
// the constructor fails.
void Source::load() {
- if (info.url.empty()) {
+ if (url.empty()) {
+ // In case there is no URL set, we assume that we already have all of the data because the
+ // TileJSON was specified inline in the stylesheet.
loaded = true;
return;
}
- if (req) return;
+ if (req) {
+ // We don't have a SourceInfo object yet, but there's already a request underway to load
+ // the data.
+ return;
+ }
// URL may either be a TileJSON file, or a GeoJSON file.
FileSource* fs = util::ThreadContext::getFileSource();
- req = fs->request({ Resource::Kind::Source, info.url }, [this](Response res) {
+ req = fs->request({ Resource::Kind::Source, url }, [this](Response res) {
if (res.stale) {
// Only handle fresh responses.
return;
@@ -173,17 +112,22 @@ void Source::load() {
}
if (type == SourceType::Vector || type == SourceType::Raster) {
- parseTileJSON(d);
+ // Create a new copy of the SourceInfo object that holds the base values we've parsed
+ // from the stylesheet. Then merge in the values parsed from the TileJSON we retrieved
+ // via the URL.
+ auto newInfo = StyleParser::parseTileJSON(d);
// TODO: Remove this hack by delivering proper URLs in the TileJSON to begin with.
- if (type == SourceType::Raster && util::mapbox::isMapboxURL(info.url)) {
+ if (type == SourceType::Raster && util::mapbox::isMapboxURL(url)) {
// We need to insert {ratio} into raster source URLs that are loaded from mapbox://
// TileJSONs.
- std::transform(info.tiles.begin(), info.tiles.end(), info.tiles.begin(),
+ std::transform(newInfo->tiles.begin(), newInfo->tiles.end(), newInfo->tiles.begin(),
util::mapbox::normalizeRasterTileURL);
}
+ info = std::move(newInfo);
} else if (type == SourceType::GeoJSON) {
- parseGeoJSON(d);
+ info = std::make_unique<SourceInfo>();
+ geojsonvt = StyleParser::parseGeoJSON(d);
}
loaded = true;
@@ -191,32 +135,10 @@ void Source::load() {
});
}
-void Source::parseTileJSON(const JSValue& value) {
- parse(value, info.tiles, "tiles");
- parse(value, info.min_zoom, "minzoom");
- parse(value, info.max_zoom, "maxzoom");
- parse(value, info.attribution, "attribution");
- parse(value, info.center, "center");
- parse(value, info.bounds, "bounds");
-}
-
-void Source::parseGeoJSON(const JSValue& value) {
- using namespace mapbox::geojsonvt;
-
- try {
- geojsonvt = std::make_unique<GeoJSONVT>(Convert::convert(value, 0));
- } catch (const std::exception& ex) {
- Log::Error(Event::ParseStyle, "Failed to parse GeoJSON data: %s", ex.what());
- // Create an empty GeoJSON VT object to make sure we're not infinitely waiting for
- // tiles to load.
- geojsonvt = std::make_unique<GeoJSONVT>(std::vector<ProjectedFeature>{});
- }
-}
-
void Source::updateMatrices(const mat4 &projMatrix, const TransformState &transform) {
for (const auto& pair : tiles) {
Tile &tile = *pair.second;
- transform.matrixFor(tile.matrix, tile.id, std::min(static_cast<int8_t>(info.max_zoom), tile.id.z));
+ transform.matrixFor(tile.matrix, tile.id, std::min(static_cast<int8_t>(info->max_zoom), tile.id.z));
matrix::multiply(tile.matrix, projMatrix, tile.matrix);
}
}
@@ -315,14 +237,13 @@ TileData::State Source::addTile(const TileID& tileID, const StyleUpdateParameter
auto tileData = std::make_shared<RasterTileData>(normalizedID,
parameters.texturePool,
parameters.worker);
-
- tileData->request(util::templateTileURL(info.tiles.at(0), normalizedID, parameters.pixelRatio), callback);
+ tileData->request(util::templateTileURL(info->tiles.at(0), normalizedID, parameters.pixelRatio), callback);
newTile->data = tileData;
} else {
std::unique_ptr<GeometryTileMonitor> monitor;
if (type == SourceType::Vector) {
- monitor = std::make_unique<VectorTileMonitor>(normalizedID, info.tiles.at(0));
+ monitor = std::make_unique<VectorTileMonitor>(normalizedID, info->tiles.at(0));
} else if (type == SourceType::Annotations) {
monitor = std::make_unique<AnnotationTileMonitor>(normalizedID, parameters.data);
} else if (type == SourceType::GeoJSON) {
@@ -349,7 +270,7 @@ TileData::State Source::addTile(const TileID& tileID, const StyleUpdateParameter
}
double Source::getZoom(const TransformState& state) const {
- double offset = std::log(util::tileSize / info.tile_size) / std::log(2);
+ double offset = std::log(util::tileSize / info->tile_size) / std::log(2);
return state.getZoom() + offset;
}
@@ -371,8 +292,8 @@ std::forward_list<TileID> Source::coveringTiles(const TransformState& state) con
type == SourceType::Vector ||
type == SourceType::Annotations;
- if (z < info.min_zoom) return {{}};
- if (z > info.max_zoom) z = info.max_zoom;
+ if (z < info->min_zoom) return {{}};
+ if (z > info->max_zoom) z = info->max_zoom;
// Map four viewport corners to pixel coordinates
box points = state.cornersToBox(z);
@@ -401,7 +322,7 @@ std::forward_list<TileID> Source::coveringTiles(const TransformState& state) con
bool Source::findLoadedChildren(const TileID& tileID, int32_t maxCoveringZoom, std::forward_list<TileID>& retain) {
bool complete = true;
int32_t z = tileID.z;
- auto ids = tileID.children(info.max_zoom);
+ auto ids = tileID.children(info->max_zoom);
for (const auto& child_id : ids) {
const TileData::State state = hasTile(child_id);
if (TileData::isReadyState(state)) {
@@ -429,7 +350,7 @@ bool Source::findLoadedChildren(const TileID& tileID, int32_t maxCoveringZoom, s
*/
void Source::findLoadedParent(const TileID& tileID, int32_t minCoveringZoom, std::forward_list<TileID>& retain) {
for (int32_t z = tileID.z - 1; z >= minCoveringZoom; --z) {
- const TileID parent_id = tileID.parent(z, info.max_zoom);
+ const TileID parent_id = tileID.parent(z, info->max_zoom);
const TileData::State state = hasTile(parent_id);
if (TileData::isReadyState(state)) {
retain.emplace_front(parent_id);
@@ -451,8 +372,8 @@ bool Source::update(const StyleUpdateParameters& parameters) {
std::forward_list<TileID> required = coveringTiles(parameters.transformState);
// Determine the overzooming/underzooming amounts.
- int32_t minCoveringZoom = util::clamp<int32_t>(zoom - 10, info.min_zoom, info.max_zoom);
- int32_t maxCoveringZoom = util::clamp<int32_t>(zoom + 1, info.min_zoom, info.max_zoom);
+ int32_t minCoveringZoom = util::clamp<int32_t>(zoom - 10, info->min_zoom, info->max_zoom);
+ int32_t maxCoveringZoom = util::clamp<int32_t>(zoom + 1, info->min_zoom, info->max_zoom);
// Retain is a list of tiles that we shouldn't delete, even if they are not
// the most ideal tile for the current viewport. This may include tiles like
diff --git a/src/mbgl/map/source.hpp b/src/mbgl/map/source.hpp
index 079ac5c2db..f3688ed9e8 100644
--- a/src/mbgl/map/source.hpp
+++ b/src/mbgl/map/source.hpp
@@ -39,12 +39,13 @@ public:
virtual void onTileError(Source&, const TileID&, std::exception_ptr) {};
};
- Source(SourceType, const std::string& id);
+ Source(SourceType,
+ const std::string& id,
+ const std::string& url,
+ std::unique_ptr<SourceInfo>&&,
+ std::unique_ptr<mapbox::geojsonvt::GeoJSONVT>&&);
~Source();
- void parseTileJSON(const JSValue&);
- void parseGeoJSON(const JSValue&);
-
bool loaded = false;
void load();
bool isLoading() const;
@@ -71,7 +72,7 @@ public:
const SourceType type;
const std::string id;
- SourceInfo info;
+ const std::string url;
bool enabled = false;
private:
@@ -88,6 +89,9 @@ private:
double getZoom(const TransformState &state) const;
+private:
+ std::unique_ptr<const SourceInfo> info;
+
std::unique_ptr<mapbox::geojsonvt::GeoJSONVT> geojsonvt;
// Stores the time when this source was most recently updated.
diff --git a/src/mbgl/map/source_info.hpp b/src/mbgl/map/source_info.hpp
index 1b8c7a40f9..0f0ee1cad4 100644
--- a/src/mbgl/map/source_info.hpp
+++ b/src/mbgl/map/source_info.hpp
@@ -15,7 +15,6 @@ class TileID;
class SourceInfo {
public:
- std::string url;
std::vector<std::string> tiles;
uint16_t tile_size = util::tileSize;
uint16_t min_zoom = 0;
diff --git a/src/mbgl/style/style_parser.cpp b/src/mbgl/style/style_parser.cpp
index 6878907cd1..3a94160710 100644
--- a/src/mbgl/style/style_parser.cpp
+++ b/src/mbgl/style/style_parser.cpp
@@ -8,10 +8,92 @@
#include <mbgl/platform/log.hpp>
+#include <mapbox/geojsonvt.hpp>
+#include <mapbox/geojsonvt/convert.hpp>
+
#include <algorithm>
namespace mbgl {
+
+namespace {
+
+void parseTileJSONMember(const JSValue& value, std::vector<std::string>& target, const char* name) {
+ if (!value.HasMember(name)) {
+ return;
+ }
+
+ const JSValue& property = value[name];
+ if (!property.IsArray()) {
+ return;
+ }
+
+ for (rapidjson::SizeType i = 0; i < property.Size(); i++) {
+ if (!property[i].IsString()) {
+ return;
+ }
+ }
+
+ for (rapidjson::SizeType i = 0; i < property.Size(); i++) {
+ target.emplace_back(std::string(property[i].GetString(), property[i].GetStringLength()));
+ }
+}
+
+void parseTileJSONMember(const JSValue& value, std::string& target, const char* name) {
+ if (!value.HasMember(name)) {
+ return;
+ }
+
+ const JSValue& property = value[name];
+ if (!property.IsString()) {
+ return;
+ }
+
+ target = { property.GetString(), property.GetStringLength() };
+}
+
+void parseTileJSONMember(const JSValue& value, uint16_t& target, const char* name) {
+ if (!value.HasMember(name)) {
+ return;
+ }
+
+ const JSValue& property = value[name];
+ if (!property.IsUint()) {
+ return;
+ }
+
+ unsigned int uint = property.GetUint();
+ if (uint > std::numeric_limits<uint16_t>::max()) {
+ return;
+ }
+
+ target = uint;
+}
+
+template <size_t N>
+void parseTileJSONMember(const JSValue& value, std::array<float, N>& target, const char* name) {
+ if (!value.HasMember(name)) {
+ return;
+ }
+
+ const JSValue& property = value[name];
+ if (!property.IsArray() || property.Size() != N) {
+ return;
+ }
+
+ for (rapidjson::SizeType i = 0; i < property.Size(); i++) {
+ if (!property[i].IsNumber()) {
+ return;
+ }
+ }
+
+ for (rapidjson::SizeType i = 0; i < property.Size(); i++) {
+ target[i] = property[i].GetDouble();
+ }
+}
+
+} // end namespace
+
StyleParser::~StyleParser() = default;
void StyleParser::parse(const JSValue& document) {
@@ -68,110 +150,94 @@ void StyleParser::parseSources(const JSValue& value) {
}
const auto type = SourceTypeClass({ typeVal.GetString(), typeVal.GetStringLength() });
- const std::string id { nameVal.GetString(), nameVal.GetStringLength() };
- std::unique_ptr<Source> source = std::make_unique<Source>(type, id);
+
+ // Sources can have URLs, either because they reference an external TileJSON file, or
+ // because reference a GeoJSON file. They don't have to have one though when all source
+ // parameters are specified inline.
+ std::string url;
+
+ std::unique_ptr<SourceInfo> info;
+ std::unique_ptr<mapbox::geojsonvt::GeoJSONVT> geojsonvt;
switch (type) {
case SourceType::Vector:
- if (!parseVectorSource(*source, sourceVal)) {
- continue;
- }
- break;
case SourceType::Raster:
- if (!parseRasterSource(*source, sourceVal)) {
- continue;
+ if (sourceVal.HasMember("url")) {
+ const JSValue& urlVal = sourceVal["url"];
+ if (urlVal.IsString()) {
+ url = { urlVal.GetString(), urlVal.GetStringLength() };
+ } else {
+ Log::Error(Event::ParseStyle, "source url must be a string");
+ continue;
+ }
+ } else {
+ info = parseTileJSON(sourceVal);
}
break;
+
case SourceType::GeoJSON:
- if (!parseGeoJSONSource(*source, sourceVal)) {
+ // We should probably split this up to have URLs in the url property, and actual data
+ // in the data property. Until then, we're going to detect the content based on the
+ // object type.
+ if (sourceVal.HasMember("data")) {
+ const JSValue& dataVal = sourceVal["data"];
+ if (dataVal.IsString()) {
+ // We need to load an external GeoJSON file
+ url = { dataVal.GetString(), dataVal.GetStringLength() };
+ } else if (dataVal.IsObject()) {
+ // We need to parse dataVal as a GeoJSON object
+ // TODO: parse GeoJSON data
+ geojsonvt = parseGeoJSON(dataVal);
+ } else {
+ Log::Error(Event::ParseStyle, "GeoJSON data must be a URL or an object");
+ continue;
+ }
+ } else {
+ Log::Error(Event::ParseStyle, "GeoJSON source must have a data value");
continue;
}
- break;
- default:
- Log::Warning(Event::ParseStyle, "source type %s is not supported", type.c_str());
- }
- sourcesMap.emplace(id, source.get());
- sources.emplace_back(std::move(source));
- }
-}
+ // We always assume the default configuration for GeoJSON sources.
+ info = std::make_unique<SourceInfo>();
-bool StyleParser::parseVectorSource(Source& source, const JSValue& sourceVal) {
- // A vector tile source either specifies the URL of a TileJSON file...
- if (sourceVal.HasMember("url")) {
- const JSValue& urlVal = sourceVal["url"];
+ break;
- if (!urlVal.IsString()) {
- Log::Warning(Event::ParseStyle, "source url must be a string");
- return false;
+ default:
+ Log::Error(Event::ParseStyle, "source type '%s' is not supported", typeVal.GetString());
+ continue;
}
- source.info.url = { urlVal.GetString(), urlVal.GetStringLength() };
+ const std::string id { nameVal.GetString(), nameVal.GetStringLength() };
+ std::unique_ptr<Source> source = std::make_unique<Source>(type, id, url, std::move(info), std::move(geojsonvt));
- } else {
- // ...or the TileJSON directly.
- source.parseTileJSON(sourceVal);
+ sourcesMap.emplace(id, source.get());
+ sources.emplace_back(std::move(source));
}
-
- return true;
}
-bool StyleParser::parseRasterSource(Source& source, const JSValue& sourceVal) {
- if (sourceVal.HasMember("tileSize")) {
- const JSValue& tileSizeVal = sourceVal["tileSize"];
+std::unique_ptr<mapbox::geojsonvt::GeoJSONVT> StyleParser::parseGeoJSON(const JSValue& value) {
+ using namespace mapbox::geojsonvt;
- if (!tileSizeVal.IsUint()) {
- Log::Warning(Event::ParseStyle, "source tileSize must be an unsigned integer");
- return false;
- }
-
- unsigned int intValue = tileSizeVal.GetUint();
- if (intValue > std::numeric_limits<uint16_t>::max()) {
- Log::Warning(Event::ParseStyle, "values for tileSize that are larger than %d are not supported", std::numeric_limits<uint16_t>::max());
- return false;
- }
-
- source.info.tile_size = intValue;
+ try {
+ return std::make_unique<GeoJSONVT>(Convert::convert(value, 0));
+ } catch (const std::exception& ex) {
+ Log::Error(Event::ParseStyle, "Failed to parse GeoJSON data: %s", ex.what());
+ // Create an empty GeoJSON VT object to make sure we're not infinitely waiting for
+ // tiles to load.
+ return std::make_unique<GeoJSONVT>(std::vector<ProjectedFeature>{});
}
-
- // A raster tile source either specifies the URL of a TileJSON file...
- if (sourceVal.HasMember("url")) {
- const JSValue& urlVal = sourceVal["url"];
-
- if (!urlVal.IsString()) {
- Log::Warning(Event::ParseStyle, "source url must be a string");
- return false;
- }
-
- source.info.url = { urlVal.GetString(), urlVal.GetStringLength() };
-
- } else {
- // ...or the TileJSON directly.
- source.parseTileJSON(sourceVal);
- }
-
- return true;
}
-bool StyleParser::parseGeoJSONSource(Source& source, const JSValue& sourceVal) {
- if (!sourceVal.HasMember("data")) {
- Log::Warning(Event::ParseStyle, "GeoJSON source must have a data value");
- return false;
- }
-
- const JSValue& dataVal = sourceVal["data"];
- if (dataVal.IsString()) {
- // We need to load an external GeoJSON file
- source.info.url = { dataVal.GetString(), dataVal.GetStringLength() };
- } else if (dataVal.IsObject()) {
- // We need to parse dataVal as a GeoJSON object
- source.parseGeoJSON(dataVal);
- } else {
- Log::Error(Event::ParseStyle, "GeoJSON data must be a URL or an object");
- return false;
- }
-
- return true;
+std::unique_ptr<SourceInfo> StyleParser::parseTileJSON(const JSValue& value) {
+ auto info = std::make_unique<SourceInfo>();
+ parseTileJSONMember(value, info->tiles, "tiles");
+ parseTileJSONMember(value, info->tile_size, "tileSize");
+ parseTileJSONMember(value, info->min_zoom, "minzoom");
+ parseTileJSONMember(value, info->max_zoom, "maxzoom");
+ parseTileJSONMember(value, info->attribution, "attribution");
+ parseTileJSONMember(value, info->center, "center");
+ parseTileJSONMember(value, info->bounds, "bounds");
+ return std::move(info);
}
void StyleParser::parseLayers(const JSValue& value) {
diff --git a/src/mbgl/style/style_parser.hpp b/src/mbgl/style/style_parser.hpp
index 6242945c46..d3bb401d44 100644
--- a/src/mbgl/style/style_parser.hpp
+++ b/src/mbgl/style/style_parser.hpp
@@ -28,11 +28,11 @@ public:
std::vector<std::unique_ptr<Source>> sources;
std::vector<std::unique_ptr<StyleLayer>> layers;
+ static std::unique_ptr<mapbox::geojsonvt::GeoJSONVT> parseGeoJSON(const JSValue&);
+ static std::unique_ptr<SourceInfo> parseTileJSON(const JSValue&);
+
private:
void parseSources(const JSValue&);
- bool parseVectorSource(Source&, const JSValue&);
- bool parseRasterSource(Source&, const JSValue&);
- bool parseGeoJSONSource(Source&, const JSValue&);
void parseLayers(const JSValue&);
void parseLayer(const std::string& id, const JSValue&, std::unique_ptr<StyleLayer>&);
void parseVisibility(StyleLayer&, const JSValue& value);
diff --git a/test/fixtures/style_parser/geojson-missing-data.info.json b/test/fixtures/style_parser/geojson-missing-data.info.json
index 594d01d19d..2c4806c3cf 100644
--- a/test/fixtures/style_parser/geojson-missing-data.info.json
+++ b/test/fixtures/style_parser/geojson-missing-data.info.json
@@ -1,7 +1,7 @@
{
"default": {
"log": [
- [1, "WARNING", "ParseStyle", "GeoJSON source must have a data value"]
+ [1, "ERROR", "ParseStyle", "GeoJSON source must have a data value"]
]
}
}