Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Support GeoJSON sources #2161

Merged
merged 7 commits into from
Dec 12, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
],
"devDependencies": {
"aws-sdk": "^2.2.21",
"mapbox-gl-test-suite": "mapbox/mapbox-gl-test-suite#6e2b48155ca651b37826942f2ca082be687b7a42",
"mapbox-gl-test-suite": "mapbox/mapbox-gl-test-suite#78bde0077848b4af0efd490d124bde3ea9f56ec9",
"node-gyp": "^3.2.1",
"request": "^2.67.0",
"tape": "^4.2.2"
Expand Down
2 changes: 1 addition & 1 deletion scripts/android/configure.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ LIBUV_VERSION=1.7.5
ZLIB_VERSION=system
NUNICODE_VERSION=1.6
LIBZIP_VERSION=0.11.2
GEOJSONVT_VERSION=3.0.0
GEOJSONVT_VERSION=3.0.1
VARIANT_VERSION=1.0
RAPIDJSON_VERSION=1.0.2

Expand Down
2 changes: 1 addition & 1 deletion scripts/ios/configure.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ BOOST_VERSION=1.59.0
SQLITE_VERSION=system
LIBUV_VERSION=1.7.5
ZLIB_VERSION=system
GEOJSONVT_VERSION=3.0.0
GEOJSONVT_VERSION=3.0.1
VARIANT_VERSION=1.0
RAPIDJSON_VERSION=1.0.2
2 changes: 1 addition & 1 deletion scripts/linux/configure.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ SQLITE_VERSION=3.9.1
LIBUV_VERSION=1.7.5
ZLIB_VERSION=system
NUNICODE_VERSION=1.6
GEOJSONVT_VERSION=3.0.0
GEOJSONVT_VERSION=3.0.1
VARIANT_VERSION=1.0
RAPIDJSON_VERSION=1.0.2
GTEST_VERSION=1.7.0
Expand Down
2 changes: 1 addition & 1 deletion scripts/main.mk
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ node/configure:
$(QUIET)$(ENV) $(NODE_PRE_GYP) configure --clang -- \
$(GYP_FLAGS) -Dlibuv_cflags= -Dlibuv_ldflags= -Dlibuv_static_libs=

node/xproj:
node/xproj: Xcode/__project__ node/configure
$(QUIET)$(ENV) $(NODE_PRE_GYP) configure --clang -- \
$(GYP_FLAGS) -f xcode -Dlibuv_cflags= -Dlibuv_ldflags= -Dlibuv_static_libs=
$(QUIET)$(ENV) ./scripts/node/create_node_scheme.sh "node test" "`npm bin tape`/tape platform/node/test/js/**/*.test.js"
Expand Down
2 changes: 1 addition & 1 deletion scripts/osx/configure.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ SQLITE_VERSION=3.9.1
LIBUV_VERSION=1.7.5
ZLIB_VERSION=system
NUNICODE_VERSION=1.6
GEOJSONVT_VERSION=3.0.0
GEOJSONVT_VERSION=3.0.1
VARIANT_VERSION=1.0
RAPIDJSON_VERSION=1.0.2
GTEST_VERSION=1.7.0
Expand Down
127 changes: 25 additions & 102 deletions src/mbgl/map/source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <mbgl/map/tile.hpp>
#include <mbgl/map/vector_tile.hpp>
#include <mbgl/annotation/annotation_tile.hpp>
#include <mbgl/tile/geojson_tile.hpp>
#include <mbgl/renderer/painter.hpp>
#include <mbgl/util/exception.hpp>
#include <mbgl/util/constants.hpp>
Expand Down Expand Up @@ -33,93 +34,6 @@

namespace mbgl {

void parse(const rapidjson::Value& value, std::vector<std::string>& target, const char *name) {
if (!value.HasMember(name))
return;

const rapidjson::Value& 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 rapidjson::Value& value, std::string& target, const char* name) {
if (!value.HasMember(name))
return;

const rapidjson::Value& property = value[name];
if (!property.IsString())
return;

target = { property.GetString(), property.GetStringLength() };
}

void parse(const rapidjson::Value& value, uint16_t& target, const char* name) {
if (!value.HasMember(name))
return;

const rapidjson::Value& 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 rapidjson::Value& value, std::array<float, N>& target, const char* name) {
if (!value.HasMember(name))
return;

const rapidjson::Value& 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();
}

void SourceInfo::parseTileJSONProperties(const rapidjson::Value& value) {
parse(value, tiles, "tiles");
parse(value, min_zoom, "minzoom");
parse(value, max_zoom, "maxzoom");
parse(value, attribution, "attribution");
parse(value, center, "center");
parse(value, bounds, "bounds");
}

std::string SourceInfo::tileURL(const TileID& id, float pixelRatio) const {
std::string result = tiles.at(0);
result = util::mapbox::normalizeTileURL(result, url, type);
result = util::replaceTokens(result, [&](const std::string &token) -> std::string {
if (token == "z") return util::toString(std::min(id.z, static_cast<int8_t>(max_zoom)));
if (token == "x") return util::toString(id.x);
if (token == "y") return util::toString(id.y);
if (token == "prefix") {
std::string prefix { 2 };
prefix[0] = "0123456789abcdef"[id.x % 16];
prefix[1] = "0123456789abcdef"[id.y % 16];
return prefix;
}
if (token == "ratio") return pixelRatio > 1.0 ? "@2x" : "";
return "";
});
return result;
}

Source::Source() {}

Source::~Source() = default;
Expand Down Expand Up @@ -147,6 +61,7 @@ void Source::load() {
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) {
if (res.stale) {
Expand All @@ -172,7 +87,12 @@ void Source::load() {
return;
}

info.parseTileJSONProperties(d);
if (info.type == SourceType::Vector || info.type == SourceType::Raster) {
info.parseTileJSONProperties(d);
} else if (info.type == SourceType::GeoJSON) {
info.parseGeoJSON(d);
}

loaded = true;

emitSourceLoaded();
Expand Down Expand Up @@ -254,9 +174,7 @@ TileData::State Source::addTile(const TileID& id, const StyleUpdateParameters& p
return state;
}

auto pos = tiles.emplace(id, std::make_unique<Tile>(id));

Tile& new_tile = *pos.first->second;
auto newTile = std::make_unique<Tile>(id);

// We couldn't find the tile in the list. Create a new one.
// Try to find the associated TileData object.
Expand All @@ -265,19 +183,19 @@ TileData::State Source::addTile(const TileID& id, const StyleUpdateParameters& p
auto it = tileDataMap.find(normalized_id);
if (it != tileDataMap.end()) {
// Create a shared_ptr handle. Note that this might be empty!
new_tile.data = it->second.lock();
newTile->data = it->second.lock();
}

if (new_tile.data && new_tile.data->getState() == TileData::State::obsolete) {
if (newTile->data && newTile->data->getState() == TileData::State::obsolete) {
// Do not consider the tile if it's already obsolete.
new_tile.data.reset();
newTile->data.reset();
}

if (!new_tile.data) {
new_tile.data = cache.get(normalized_id.to_uint64());
if (!newTile->data) {
newTile->data = cache.get(normalized_id.to_uint64());
}

if (!new_tile.data) {
if (!newTile->data) {
auto callback = std::bind(&Source::tileLoadingCompleteCallback, this, normalized_id, parameters.transformState, parameters.debugOptions & MapDebugOptions::Collision);

// If we don't find working tile data, we're just going to load it.
Expand All @@ -288,29 +206,34 @@ TileData::State Source::addTile(const TileID& id, const StyleUpdateParameters& p
parameters.worker);

tileData->request(parameters.pixelRatio, callback);
new_tile.data = tileData;
newTile->data = tileData;
} else {
std::unique_ptr<GeometryTileMonitor> monitor;

if (info.type == SourceType::Vector) {
monitor = std::make_unique<VectorTileMonitor>(info, normalized_id, parameters.pixelRatio);
} else if (info.type == SourceType::Annotations) {
monitor = std::make_unique<AnnotationTileMonitor>(normalized_id, parameters.data);
} else if (info.type == SourceType::GeoJSON) {
monitor = std::make_unique<GeoJSONTileMonitor>(info.geojsonvt.get(), normalized_id);
} else {
throw std::runtime_error("source type not implemented");
Log::Warning(Event::Style, "Source type '%s' is not implemented", SourceTypeClass(info.type).c_str());
return TileData::State::invalid;
}

new_tile.data = std::make_shared<VectorTileData>(normalized_id,
newTile->data = std::make_shared<VectorTileData>(normalized_id,
std::move(monitor),
info.source_id,
parameters.style,
callback);
}

tileDataMap.emplace(new_tile.data->id, new_tile.data);
tileDataMap.emplace(newTile->data->id, newTile->data);
}

return new_tile.data->getState();
const auto newState = newTile->data->getState();
tiles.emplace(id, std::move(newTile));
return newState;
}

double Source::getZoom(const TransformState& state) const {
Expand Down
30 changes: 1 addition & 29 deletions src/mbgl/map/source.hpp
Original file line number Diff line number Diff line change
@@ -1,24 +1,13 @@
#ifndef MBGL_MAP_SOURCE
#define MBGL_MAP_SOURCE

#include <mbgl/map/tile_id.hpp>
#include <mbgl/map/tile_data.hpp>
#include <mbgl/map/tile_cache.hpp>
#include <mbgl/style/types.hpp>
#include <mbgl/map/source_info.hpp>

#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/mat4.hpp>
#include <mbgl/util/ptr.hpp>
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/constants.hpp>

#include <rapidjson/document.h>

#include <cstdint>
#include <forward_list>
#include <iosfwd>
#include <map>
#include <unordered_set>

namespace mbgl {

Expand All @@ -30,23 +19,6 @@ class Tile;
struct ClipID;
struct box;

class SourceInfo : private util::noncopyable {
public:
SourceType type = SourceType::Vector;
std::string url;
std::vector<std::string> tiles;
uint16_t tile_size = util::tileSize;
uint16_t min_zoom = 0;
uint16_t max_zoom = 22;
std::string attribution;
std::array<float, 3> center = {{0, 0, 0}};
std::array<float, 4> bounds = {{-180, -90, 180, 90}};
std::string source_id = "";

void parseTileJSONProperties(const rapidjson::Value&);
std::string tileURL(const TileID& id, float pixelRatio) const;
};

class Source : private util::noncopyable {
public:
class Observer {
Expand Down
Loading