Add support for parsing MLT-format vector tile sources (#3246)
Co-authored-by: Bart Louwers <bart@emeel.net> Co-authored-by: Bart Louwers <bart.louwers@gmail.com>
This commit is contained in:
4
.gitmodules
vendored
4
.gitmodules
vendored
@@ -100,6 +100,10 @@
|
||||
[submodule "vendor/filesystem"]
|
||||
path = vendor/filesystem
|
||||
url = https://github.com/gulrak/filesystem.git
|
||||
[submodule "vendor/maplibre-tile-spec"]
|
||||
path = vendor/maplibre-tile-spec
|
||||
url = https://github.com/maplibre/maplibre-tile-spec.git
|
||||
branch = cpp
|
||||
[submodule "vendor/kdbush.hpp"]
|
||||
path = vendor/kdbush.hpp
|
||||
url = https://github.com/mourner/kdbush.hpp.git
|
||||
|
||||
@@ -144,6 +144,7 @@ cc_library(
|
||||
"//vendor:eternal",
|
||||
"//vendor:expected-lite",
|
||||
"//vendor:maplibre-native-base",
|
||||
"//vendor/maplibre-tile-spec/cpp:mlt_cpp",
|
||||
"//vendor:parsedate",
|
||||
"//vendor:pmtiles",
|
||||
"//vendor:polylabel",
|
||||
|
||||
@@ -302,9 +302,9 @@ list(APPEND INCLUDE_FILES
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/style/conversion/light.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/style/conversion/position.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/style/conversion/property_value.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/style/conversion/raster_dem_options.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/style/conversion/rotation.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/style/conversion/source.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/style/conversion/source_options.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/style/conversion/tileset.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/style/conversion/transition_options.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/style/expression/assertion.hpp
|
||||
@@ -676,9 +676,9 @@ list(APPEND SRC_FILES
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/style/conversion/light.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/style/conversion/position.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/style/conversion/property_value.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/style/conversion/raster_dem_options.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/style/conversion/rotation.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/style/conversion/source.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/style/conversion/source_options.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/style/conversion/stringify.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/style/conversion/tileset.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/style/conversion/transition_options.cpp
|
||||
@@ -879,10 +879,15 @@ list(APPEND SRC_FILES
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/tile/tile_operation.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/tile/vector_tile.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/tile/vector_tile.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/tile/vector_tile_data.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/tile/vector_tile_data.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/tile/vector_mlt_tile.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/tile/vector_mlt_tile.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/tile/vector_mlt_tile_data.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/tile/vector_mlt_tile_data.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/tile/vector_mvt_tile.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/tile/vector_mvt_tile.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/tile/vector_mvt_tile_data.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/tile/vector_mvt_tile_data.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/util/action_journal.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/util/action_journal_impl.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/util/action_journal_impl.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/util/camera.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/util/bounding_volumes.hpp
|
||||
@@ -1553,6 +1558,7 @@ include(${PROJECT_SOURCE_DIR}/vendor/unordered_dense.cmake)
|
||||
include(${PROJECT_SOURCE_DIR}/vendor/vector-tile.cmake)
|
||||
include(${PROJECT_SOURCE_DIR}/vendor/wagyu.cmake)
|
||||
include(${PROJECT_SOURCE_DIR}/vendor/metal-cpp.cmake)
|
||||
include(${PROJECT_SOURCE_DIR}/vendor/maplibre-tile-spec.cmake)
|
||||
include(${PROJECT_SOURCE_DIR}/vendor/supercluster.cmake)
|
||||
include(${PROJECT_SOURCE_DIR}/vendor/expected-lite.cmake)
|
||||
include(${PROJECT_SOURCE_DIR}/vendor/kdbush.cmake)
|
||||
@@ -1581,6 +1587,7 @@ target_link_libraries(
|
||||
mbgl-vendor-unique_resource
|
||||
mbgl-vendor-vector-tile
|
||||
mbgl-vendor-wagyu
|
||||
mlt-cpp
|
||||
$<$<BOOL:${MLN_WITH_METAL}>:mbgl-vendor-metal-cpp>
|
||||
$<IF:$<BOOL:${MLN_USE_RUST}>,mbgl-rustutils,mbgl-vendor-csscolorparser>
|
||||
$<$<BOOL:${MLN_TEXT_SHAPING_HARFBUZZ}>:mbgl-freetype>
|
||||
@@ -1614,6 +1621,8 @@ set(EXPORT_TARGETS
|
||||
mbgl-vendor-boost
|
||||
mbgl-vendor-earcut.hpp
|
||||
mbgl-vendor-eternal
|
||||
mbgl-vendor-filesystem
|
||||
mbgl-vendor-metal-cpp
|
||||
mbgl-vendor-rapidjson
|
||||
mbgl-vendor-parsedate
|
||||
mbgl-vendor-pmtiles
|
||||
@@ -1622,8 +1631,7 @@ set(EXPORT_TARGETS
|
||||
mbgl-vendor-unique_resource
|
||||
mbgl-vendor-vector-tile
|
||||
mbgl-vendor-wagyu
|
||||
mbgl-vendor-metal-cpp
|
||||
mbgl-vendor-filesystem
|
||||
mlt-cpp
|
||||
unordered_dense
|
||||
)
|
||||
|
||||
|
||||
@@ -336,9 +336,9 @@ MLN_CORE_SOURCE = [
|
||||
"src/mbgl/style/conversion/light.cpp",
|
||||
"src/mbgl/style/conversion/position.cpp",
|
||||
"src/mbgl/style/conversion/property_value.cpp",
|
||||
"src/mbgl/style/conversion/raster_dem_options.cpp",
|
||||
"src/mbgl/style/conversion/rotation.cpp",
|
||||
"src/mbgl/style/conversion/source.cpp",
|
||||
"src/mbgl/style/conversion/source_options.cpp",
|
||||
"src/mbgl/style/conversion/stringify.hpp",
|
||||
"src/mbgl/style/conversion/tileset.cpp",
|
||||
"src/mbgl/style/conversion/transition_options.cpp",
|
||||
@@ -514,8 +514,14 @@ MLN_CORE_SOURCE = [
|
||||
"src/mbgl/tile/tile_operation.cpp",
|
||||
"src/mbgl/tile/vector_tile.cpp",
|
||||
"src/mbgl/tile/vector_tile.hpp",
|
||||
"src/mbgl/tile/vector_tile_data.cpp",
|
||||
"src/mbgl/tile/vector_tile_data.hpp",
|
||||
"src/mbgl/tile/vector_mlt_tile.cpp",
|
||||
"src/mbgl/tile/vector_mlt_tile.hpp",
|
||||
"src/mbgl/tile/vector_mlt_tile_data.cpp",
|
||||
"src/mbgl/tile/vector_mlt_tile_data.hpp",
|
||||
"src/mbgl/tile/vector_mvt_tile.cpp",
|
||||
"src/mbgl/tile/vector_mvt_tile.hpp",
|
||||
"src/mbgl/tile/vector_mvt_tile_data.cpp",
|
||||
"src/mbgl/tile/vector_mvt_tile_data.hpp",
|
||||
"src/mbgl/util/action_journal.cpp",
|
||||
"src/mbgl/util/action_journal_impl.hpp",
|
||||
"src/mbgl/util/action_journal_impl.cpp",
|
||||
@@ -696,9 +702,9 @@ MLN_CORE_HEADERS = [
|
||||
"include/mbgl/style/conversion/light.hpp",
|
||||
"include/mbgl/style/conversion/position.hpp",
|
||||
"include/mbgl/style/conversion/property_value.hpp",
|
||||
"include/mbgl/style/conversion/raster_dem_options.hpp",
|
||||
"include/mbgl/style/conversion/rotation.hpp",
|
||||
"include/mbgl/style/conversion/source.hpp",
|
||||
"include/mbgl/style/conversion/source_options.hpp",
|
||||
"include/mbgl/style/conversion/tileset.hpp",
|
||||
"include/mbgl/style/conversion/transition_options.hpp",
|
||||
"include/mbgl/style/conversion_impl.hpp",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <benchmark/benchmark.h>
|
||||
|
||||
#include <mbgl/tile/vector_tile_data.hpp>
|
||||
#include <mbgl/tile/vector_mvt_tile_data.hpp>
|
||||
#include <mbgl/util/io.hpp>
|
||||
|
||||
using namespace mbgl;
|
||||
@@ -11,7 +11,7 @@ static void Parse_VectorTile(benchmark::State& state) {
|
||||
|
||||
while (state.KeepRunning()) {
|
||||
std::size_t length = 0;
|
||||
VectorTileData tile(data);
|
||||
VectorMVTTileData tile(data);
|
||||
for (const auto& name : tile.layerNames()) {
|
||||
if (auto layer = tile.getLayer(name)) {
|
||||
const std::size_t count = layer->featureCount();
|
||||
|
||||
@@ -7,14 +7,13 @@
|
||||
#include <args.hxx>
|
||||
#include <mapbox/io/io.hpp>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
args::ArgumentParser p("Mapbox GL cache tool", "");
|
||||
args::ArgumentParser p("MapLibre cache tool", "");
|
||||
args::HelpFlag helpFlag(p, "help", "Display this help menu", {'h'});
|
||||
|
||||
args::ValueFlag<std::string> urlValue(p, "URL", "Resource URL (required)", {'u'}, args::Options::Required);
|
||||
@@ -35,7 +34,7 @@ int main(int argc, char* argv[]) {
|
||||
{"tile", mbgl::Resource::Tile}};
|
||||
|
||||
std::string typeHelp("One of the following (required):");
|
||||
for (auto key : typeMap) {
|
||||
for (const auto& key : typeMap) {
|
||||
typeHelp += " " + key.first;
|
||||
}
|
||||
|
||||
@@ -53,18 +52,18 @@ int main(int argc, char* argv[]) {
|
||||
std::cout << p;
|
||||
exit(0);
|
||||
} catch (const args::ParseError& e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
std::cerr << e.what() << '\n';
|
||||
std::cerr << p;
|
||||
exit(1);
|
||||
} catch (const args::ValidationError& e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
std::cerr << e.what() << '\n';
|
||||
std::cerr << p;
|
||||
exit(2);
|
||||
}
|
||||
|
||||
auto file = mapbox::base::io::readFile(args::get(dataValue));
|
||||
if (!file) {
|
||||
std::cerr << file.error() << std::endl;
|
||||
std::cerr << file.error() << '\n';
|
||||
exit(3);
|
||||
}
|
||||
|
||||
@@ -78,15 +77,15 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
if (args::get(typeFlag) == mbgl::Resource::Tile) {
|
||||
if (!xValueFlag || !yValueFlag || !zValueFlag) {
|
||||
std::cerr << "Error: -x, -y and -z must be provided for tiles" << std::endl;
|
||||
std::cerr << "Error: -x, -y and -z must be provided for tiles" << '\n';
|
||||
exit(1);
|
||||
}
|
||||
|
||||
resource.tileData = {{args::get(urlValue),
|
||||
1,
|
||||
args::get(xValueFlag),
|
||||
args::get(yValueFlag),
|
||||
static_cast<int8_t>(args::get(zValueFlag))}};
|
||||
resource.tileData = {{.urlTemplate = args::get(urlValue),
|
||||
.pixelRatio = 1,
|
||||
.x = args::get(xValueFlag),
|
||||
.y = args::get(yValueFlag),
|
||||
.z = static_cast<int8_t>(args::get(zValueFlag))}};
|
||||
}
|
||||
|
||||
mbgl::util::RunLoop loop;
|
||||
|
||||
@@ -8,8 +8,8 @@ namespace style {
|
||||
namespace conversion {
|
||||
|
||||
template <>
|
||||
struct Converter<RasterDEMOptions> {
|
||||
std::optional<RasterDEMOptions> operator()(const Convertible& value, Error& error) const;
|
||||
struct Converter<SourceOptions> {
|
||||
std::optional<SourceOptions> operator()(const Convertible& value, Error& error) const;
|
||||
};
|
||||
|
||||
} // namespace conversion
|
||||
@@ -7,8 +7,9 @@
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
|
||||
struct RasterDEMOptions {
|
||||
std::optional<Tileset::DEMEncoding> encoding = std::nullopt;
|
||||
struct SourceOptions {
|
||||
std::optional<Tileset::RasterEncoding> rasterEncoding = std::nullopt;
|
||||
std::optional<Tileset::VectorEncoding> vectorEncoding = std::nullopt;
|
||||
};
|
||||
|
||||
// NOTE: Any derived class must invalidate `weakFactory` in the destructor
|
||||
@@ -17,7 +18,7 @@ public:
|
||||
RasterDEMSource(std::string id,
|
||||
variant<std::string, Tileset> urlOrTileset,
|
||||
uint16_t tileSize,
|
||||
std::optional<RasterDEMOptions> options = std::nullopt);
|
||||
std::optional<SourceOptions> options = std::nullopt);
|
||||
~RasterDEMSource() override;
|
||||
bool supportsLayerType(const mbgl::style::LayerTypeInfo*) const override;
|
||||
|
||||
@@ -25,7 +26,7 @@ protected:
|
||||
void setTilesetOverrides(Tileset& tileset) override;
|
||||
|
||||
private:
|
||||
std::optional<RasterDEMOptions> options;
|
||||
std::optional<SourceOptions> options;
|
||||
};
|
||||
|
||||
template <>
|
||||
|
||||
@@ -16,7 +16,8 @@ public:
|
||||
VectorSource(std::string id,
|
||||
variant<std::string, Tileset> urlOrTileset,
|
||||
std::optional<float> maxZoom = std::nullopt,
|
||||
std::optional<float> minZoom = std::nullopt);
|
||||
std::optional<float> minZoom = std::nullopt,
|
||||
Tileset::VectorEncoding encoding = Tileset::VectorEncoding::Mapbox);
|
||||
|
||||
void setTilesetOverrides(Tileset& tileset) override;
|
||||
|
||||
@@ -30,11 +31,14 @@ public:
|
||||
|
||||
bool supportsLayerType(const mbgl::style::LayerTypeInfo*) const override;
|
||||
|
||||
Tileset::VectorEncoding getEncoding() const noexcept { return encoding; }
|
||||
|
||||
mapbox::base::WeakPtr<Source> makeWeakPtr() override { return weakFactory.makeWeakPtr(); }
|
||||
|
||||
private:
|
||||
std::optional<float> maxZoom;
|
||||
std::optional<float> minZoom;
|
||||
Tileset::VectorEncoding encoding;
|
||||
mapbox::base::WeakPtrFactory<Source> weakFactory{this}; // Must remain last
|
||||
};
|
||||
|
||||
|
||||
@@ -18,38 +18,40 @@ public:
|
||||
XYZ,
|
||||
TMS
|
||||
};
|
||||
enum class DEMEncoding : bool {
|
||||
Mapbox,
|
||||
Terrarium
|
||||
enum class RasterEncoding : std::uint8_t {
|
||||
Mapbox, // Mapbox DEM
|
||||
Terrarium, // Terrarium DEM
|
||||
};
|
||||
enum class VectorEncoding : std::uint8_t {
|
||||
Mapbox, // Mapbox Vector Tiles (MVT)
|
||||
MLT, // MapLibre Tiles
|
||||
};
|
||||
|
||||
std::vector<std::string> tiles;
|
||||
Range<uint8_t> zoomRange;
|
||||
std::string attribution;
|
||||
Scheme scheme;
|
||||
// DEMEncoding is not supported by the TileJSON spec
|
||||
DEMEncoding encoding;
|
||||
std::optional<RasterEncoding> rasterEncoding;
|
||||
std::optional<VectorEncoding> vectorEncoding;
|
||||
std::optional<LatLngBounds> bounds;
|
||||
|
||||
Tileset(std::vector<std::string> tiles_ = std::vector<std::string>(),
|
||||
Range<uint8_t> zoomRange_ = {0, util::DEFAULT_MAX_ZOOM},
|
||||
std::string attribution_ = {},
|
||||
Scheme scheme_ = Scheme::XYZ,
|
||||
DEMEncoding encoding_ = DEMEncoding::Mapbox)
|
||||
std::optional<RasterEncoding> rasterEncoding_ = std::nullopt,
|
||||
std::optional<VectorEncoding> encoding_ = std::nullopt)
|
||||
: tiles(std::move(tiles_)),
|
||||
zoomRange(zoomRange_),
|
||||
attribution(std::move(attribution_)),
|
||||
scheme(scheme_),
|
||||
encoding(encoding_) {};
|
||||
rasterEncoding(rasterEncoding_),
|
||||
vectorEncoding(encoding_) {}
|
||||
|
||||
// TileJSON also includes center and zoom but they are not used by mbgl.
|
||||
|
||||
friend bool operator==(const Tileset& lhs, const Tileset& rhs) noexcept {
|
||||
return std::tie(lhs.tiles, lhs.zoomRange, lhs.attribution, lhs.scheme, lhs.bounds) ==
|
||||
std::tie(rhs.tiles, rhs.zoomRange, rhs.attribution, rhs.scheme, rhs.bounds);
|
||||
}
|
||||
|
||||
friend bool operator!=(const Tileset& lhs, const Tileset& rhs) noexcept { return !(lhs == rhs); }
|
||||
bool operator==(const Tileset&) const = default;
|
||||
bool operator!=(const Tileset&) const = default;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
Binary file not shown.
@@ -2,7 +2,13 @@
|
||||
"version": 8,
|
||||
"metadata": {
|
||||
"test": {
|
||||
"allowed": 0.003
|
||||
"allowed": 0.003,
|
||||
"source-replace": [
|
||||
{
|
||||
"replace": "maplibre",
|
||||
"with": "mlt"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"center": [
|
||||
@@ -19,6 +25,14 @@
|
||||
"tiles": [
|
||||
"local://tiles/extent1024-14-8802-5374.mvt"
|
||||
]
|
||||
},
|
||||
"mlt": {
|
||||
"type": "vector",
|
||||
"maxzoom": 14,
|
||||
"tiles": [
|
||||
"local://tiles/extent1024-14-8802-5374.mlt"
|
||||
],
|
||||
"encoding": "mlt"
|
||||
}
|
||||
},
|
||||
"layers": [
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
{
|
||||
"version": 8,
|
||||
"metadata": {
|
||||
"test": {}
|
||||
"test": {
|
||||
"source-replace": [
|
||||
{
|
||||
"replace": "maplibre",
|
||||
"with": "mlt"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"zoom": 0.99,
|
||||
"center": [
|
||||
@@ -15,6 +22,14 @@
|
||||
"tiles": [
|
||||
"local://tiles/{z}-{x}-{y}.mvt"
|
||||
]
|
||||
},
|
||||
"mlt": {
|
||||
"type": "vector",
|
||||
"maxzoom": 14,
|
||||
"tiles": [
|
||||
"local://tiles/{z}-{x}-{y}.mlt"
|
||||
],
|
||||
"encoding": "mlt"
|
||||
}
|
||||
},
|
||||
"sprite": "local://sprites/solid-black",
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
"version": 8,
|
||||
"metadata": {
|
||||
"test": {
|
||||
"height": 256
|
||||
"height": 256,
|
||||
"source-replace": [{
|
||||
"replace": "maplibre",
|
||||
"with": "mlt"
|
||||
}]
|
||||
}
|
||||
},
|
||||
"center": [
|
||||
@@ -17,6 +21,14 @@
|
||||
"tiles": [
|
||||
"local://tiles/{z}-{x}-{y}.mvt"
|
||||
]
|
||||
},
|
||||
"mlt": {
|
||||
"type": "vector",
|
||||
"maxzoom": 14,
|
||||
"tiles": [
|
||||
"local://tiles/{z}-{x}-{y}.mlt"
|
||||
],
|
||||
"encoding": "mlt"
|
||||
}
|
||||
},
|
||||
"sprite": "local://sprites/sprite",
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
{
|
||||
"version": 8,
|
||||
"metadata": {
|
||||
"test": {
|
||||
"source-replace": [
|
||||
{
|
||||
"replace": "maplibre",
|
||||
"with": "mlt"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"center": [
|
||||
-118.28162,
|
||||
33.86852
|
||||
@@ -14,6 +24,14 @@
|
||||
"tiles": [
|
||||
"local://tiles/mapbox.mapbox-streets-v7/16-11235-26208.mvt"
|
||||
]
|
||||
},
|
||||
"mlt": {
|
||||
"type": "vector",
|
||||
"maxzoom": 16,
|
||||
"tiles": [
|
||||
"local://tiles/mapbox.mapbox-streets-v7/16-11235-26208.mlt"
|
||||
],
|
||||
"encoding": "mlt"
|
||||
}
|
||||
},
|
||||
"glyphs": "local://glyphs/{fontstack}/{range}.pbf",
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
{
|
||||
"version": 8,
|
||||
"metadata": {
|
||||
"test": {}
|
||||
"test": {
|
||||
"source-replace": [
|
||||
{
|
||||
"replace": "maplibre",
|
||||
"with": "mlt"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"zoom": 2,
|
||||
"sources": {
|
||||
@@ -12,6 +19,15 @@
|
||||
"tiles": [
|
||||
"local://tiles/{z}-{x}-{y}.tms.mvt"
|
||||
]
|
||||
},
|
||||
"mlt": {
|
||||
"type": "vector",
|
||||
"maxzoom": 14,
|
||||
"scheme": "tms",
|
||||
"tiles": [
|
||||
"local://tiles/{z}-{x}-{y}.tms.mlt"
|
||||
],
|
||||
"encoding": "mlt"
|
||||
}
|
||||
},
|
||||
"layers": [
|
||||
|
||||
BIN
metrics/integration/tiles/0-0-0.mlt
Normal file
BIN
metrics/integration/tiles/0-0-0.mlt
Normal file
Binary file not shown.
BIN
metrics/integration/tiles/14-4357-6245.mlt
Normal file
BIN
metrics/integration/tiles/14-4357-6245.mlt
Normal file
Binary file not shown.
BIN
metrics/integration/tiles/14-8802-5374.mlt
Normal file
BIN
metrics/integration/tiles/14-8802-5374.mlt
Normal file
Binary file not shown.
BIN
metrics/integration/tiles/14-8802-5375.mlt
Normal file
BIN
metrics/integration/tiles/14-8802-5375.mlt
Normal file
Binary file not shown.
BIN
metrics/integration/tiles/14-8803-5374.mlt
Normal file
BIN
metrics/integration/tiles/14-8803-5374.mlt
Normal file
Binary file not shown.
BIN
metrics/integration/tiles/14-8803-5375.mlt
Normal file
BIN
metrics/integration/tiles/14-8803-5375.mlt
Normal file
Binary file not shown.
BIN
metrics/integration/tiles/2-1-1.mlt
Normal file
BIN
metrics/integration/tiles/2-1-1.mlt
Normal file
Binary file not shown.
BIN
metrics/integration/tiles/2-1-1.tms.mlt
Normal file
BIN
metrics/integration/tiles/2-1-1.tms.mlt
Normal file
Binary file not shown.
BIN
metrics/integration/tiles/2-1-2.mlt
Normal file
BIN
metrics/integration/tiles/2-1-2.mlt
Normal file
Binary file not shown.
BIN
metrics/integration/tiles/2-1-2.tms.mlt
Normal file
BIN
metrics/integration/tiles/2-1-2.tms.mlt
Normal file
Binary file not shown.
BIN
metrics/integration/tiles/2-2-1.mlt
Normal file
BIN
metrics/integration/tiles/2-2-1.mlt
Normal file
Binary file not shown.
BIN
metrics/integration/tiles/2-2-1.tms.mlt
Normal file
BIN
metrics/integration/tiles/2-2-1.tms.mlt
Normal file
Binary file not shown.
BIN
metrics/integration/tiles/2-2-2.mlt
Normal file
BIN
metrics/integration/tiles/2-2-2.mlt
Normal file
Binary file not shown.
BIN
metrics/integration/tiles/2-2-2.tms.mlt
Normal file
BIN
metrics/integration/tiles/2-2-2.tms.mlt
Normal file
Binary file not shown.
BIN
metrics/integration/tiles/counties-7-37-48.mlt
Normal file
BIN
metrics/integration/tiles/counties-7-37-48.mlt
Normal file
Binary file not shown.
BIN
metrics/integration/tiles/extent1024-14-8802-5374.mlt
Normal file
BIN
metrics/integration/tiles/extent1024-14-8802-5374.mlt
Normal file
Binary file not shown.
BIN
metrics/integration/tiles/mapbox.mapbox-streets-v7/0-0-0.mlt
Normal file
BIN
metrics/integration/tiles/mapbox.mapbox-streets-v7/0-0-0.mlt
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
metrics/integration/tiles/mapbox.mapbox-streets-v7/4-4-7.mlt
Normal file
BIN
metrics/integration/tiles/mapbox.mapbox-streets-v7/4-4-7.mlt
Normal file
Binary file not shown.
BIN
metrics/integration/tiles/mapbox.mapbox-streets-v7/4-5-7.mlt
Normal file
BIN
metrics/integration/tiles/mapbox.mapbox-streets-v7/4-5-7.mlt
Normal file
Binary file not shown.
@@ -10,11 +10,30 @@
|
||||
The default value for this option is ``MLNDEMEncoding/MLNDEMEncodingMapbox``.
|
||||
|
||||
This option cannot be represented in a TileJSON or style JSON file. It is used
|
||||
with the ``MLNRasterDEMSource`` class and is ignored when creating an
|
||||
with the ``MLNRasterDEMSource`` class and is ignored when creating a
|
||||
``MLNRasterTileSource`` or ``MLNRasterTileSource`` object.
|
||||
*/
|
||||
FOUNDATION_EXTERN MLN_EXPORT const MLNTileSourceOption MLNTileSourceOptionDEMEncoding;
|
||||
|
||||
/**
|
||||
The encoding formula used to generate the raster tileset
|
||||
*/
|
||||
|
||||
typedef NS_ENUM(NSUInteger, MLNDEMEncoding) {
|
||||
|
||||
/**
|
||||
Raster tiles generated with the [Mapbox encoding
|
||||
formula](https://docs.mapbox.com/help/troubleshooting/access-elevation-data/#mapbox-terrain-rgb)
|
||||
*/
|
||||
MLNDEMEncodingMapbox = 0,
|
||||
|
||||
/**
|
||||
Raster tiles generated with the [Mapzen Terrarium encoding
|
||||
formula](https://aws.amazon.com/public-datasets/terrain/).
|
||||
*/
|
||||
MLNDEMEncodingTerrarium = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
``MLNRasterDEMSource`` is a map content source that supplies rasterized
|
||||
<a href="https://en.wikipedia.org/wiki/Digital_elevation_model">digital elevation model</a>
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#import <mbgl/style/sources/raster_dem_source.hpp>
|
||||
|
||||
const MLNTileSourceOption MLNTileSourceOptionDEMEncoding = @"MLNTileSourceOptionDEMEncoding";
|
||||
|
||||
@implementation MLNRasterDEMSource
|
||||
|
||||
- (std::unique_ptr<mbgl::style::RasterSource>)pendingSourceWithIdentifier:(NSString *)identifier urlOrTileset:(mbgl::variant<std::string, mbgl::Tileset>)urlOrTileset tileSize:(uint16_t)tileSize {
|
||||
|
||||
@@ -142,25 +142,6 @@ typedef NS_ENUM(NSUInteger, MLNTileCoordinateSystem) {
|
||||
MLNTileCoordinateSystemTMS
|
||||
};
|
||||
|
||||
/**
|
||||
The encoding formula used to generate the raster-dem tileset
|
||||
*/
|
||||
|
||||
typedef NS_ENUM(NSUInteger, MLNDEMEncoding) {
|
||||
|
||||
/**
|
||||
Raster tiles generated with the [Mapbox encoding
|
||||
formula](https://docs.mapbox.com/help/troubleshooting/access-elevation-data/#mapbox-terrain-rgb).
|
||||
*/
|
||||
MLNDEMEncodingMapbox = 0,
|
||||
|
||||
/**
|
||||
Raster tiles generated with the [Mapzen Terrarium encoding
|
||||
formula](https://aws.amazon.com/public-datasets/terrain/).
|
||||
*/
|
||||
MLNDEMEncodingTerrarium
|
||||
};
|
||||
|
||||
/**
|
||||
``MLNTileSource`` is a map content source that supplies map tiles to be shown on
|
||||
the map. The location of and metadata about the tiles are defined either by an
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#import "MLNAttributionInfo_Private.h"
|
||||
#import "MLNGeometry_Private.h"
|
||||
#import "MLNRasterDEMSource.h"
|
||||
#import "MLNVectorTileSource.h"
|
||||
#import "NSString+MLNAdditions.h"
|
||||
#import "NSValue+MLNAdditions.h"
|
||||
|
||||
@@ -20,7 +21,6 @@ const MLNTileSourceOption MLNTileSourceOptionCoordinateBounds = @"MLNTileSourceO
|
||||
const MLNTileSourceOption MLNTileSourceOptionAttributionHTMLString = @"MLNTileSourceOptionAttributionHTMLString";
|
||||
const MLNTileSourceOption MLNTileSourceOptionAttributionInfos = @"MLNTileSourceOptionAttributionInfos";
|
||||
const MLNTileSourceOption MLNTileSourceOptionTileCoordinateSystem = @"MLNTileSourceOptionTileCoordinateSystem";
|
||||
const MLNTileSourceOption MLNTileSourceOptionDEMEncoding = @"MLNTileSourceOptionDEMEncoding";
|
||||
|
||||
@implementation MLNTileSource
|
||||
|
||||
@@ -131,19 +131,38 @@ mbgl::Tileset MLNTileSetFromTileURLTemplates(NSArray<NSString *> *tileURLTemplat
|
||||
}
|
||||
}
|
||||
|
||||
if (NSNumber *demEncodingNumber = options[MLNTileSourceOptionDEMEncoding]) {
|
||||
if (![demEncodingNumber isKindOfClass:[NSValue class]]) {
|
||||
NSNumber *encodingNumber = options[MLNTileSourceOptionDEMEncoding];
|
||||
if (encodingNumber) {
|
||||
if (![encodingNumber isKindOfClass:[NSValue class]]) {
|
||||
[NSException raise:NSInvalidArgumentException
|
||||
format:@"MLNTileSourceOptionDEMEncoding must be set to an NSValue or NSNumber."];
|
||||
}
|
||||
MLNDEMEncoding demEncoding;
|
||||
[demEncodingNumber getValue:&demEncoding];
|
||||
switch (demEncoding) {
|
||||
MLNDEMEncoding encoding;
|
||||
[encodingNumber getValue:&encoding];
|
||||
switch (encoding) {
|
||||
case MLNDEMEncodingMapbox:
|
||||
tileSet.encoding = mbgl::Tileset::DEMEncoding::Mapbox;
|
||||
tileSet.rasterEncoding = mbgl::Tileset::RasterEncoding::Mapbox;
|
||||
break;
|
||||
case MLNDEMEncodingTerrarium:
|
||||
tileSet.encoding = mbgl::Tileset::DEMEncoding::Terrarium;
|
||||
tileSet.rasterEncoding = mbgl::Tileset::RasterEncoding::Terrarium;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
encodingNumber = options[MLNVectorTileSourceOptionEncoding];
|
||||
if (encodingNumber) {
|
||||
if (![encodingNumber isKindOfClass:[NSValue class]]) {
|
||||
[NSException raise:NSInvalidArgumentException
|
||||
format:@"MLNTileSourceOptionVectorEncoding must be set to an NSValue or NSNumber."];
|
||||
}
|
||||
MLNVectorTileSourceEncoding encoding;
|
||||
[encodingNumber getValue:&encoding];
|
||||
switch (encoding) {
|
||||
case MLNVectorTileSourceEncodingMapbox:
|
||||
tileSet.vectorEncoding = mbgl::Tileset::VectorEncoding::Mapbox;
|
||||
break;
|
||||
case MLNVectorTileSourceEncodingMLT:
|
||||
tileSet.vectorEncoding = mbgl::Tileset::VectorEncoding::MLT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,33 @@
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
An `NSNumber` object containing an unsigned integer that specifies the encoding
|
||||
formula for vector tilesets. The integer corresponds to one of the constants in
|
||||
``MLNVectorTileSourceEncoding``.
|
||||
|
||||
The default value for this option is
|
||||
``MLNVectorTileSourceEncoding/MLNVectorTileSourceEncodingMapbox``.
|
||||
*/
|
||||
FOUNDATION_EXTERN MLN_EXPORT const MLNTileSourceOption MLNVectorTileSourceOptionEncoding;
|
||||
|
||||
/**
|
||||
The encoding formula used to generate the raster-dem tileset
|
||||
*/
|
||||
|
||||
typedef NS_ENUM(NSUInteger, MLNVectorTileSourceEncoding) {
|
||||
|
||||
/**
|
||||
Vector tiles in [MVT format](https://github.com/mapbox/vector-tile-spec).
|
||||
*/
|
||||
MLNVectorTileSourceEncodingMapbox = 0,
|
||||
|
||||
/**
|
||||
Vector tiles in [MLT format](https://github.com/maplibre/maplibre-tile-spec).
|
||||
*/
|
||||
MLNVectorTileSourceEncodingMLT = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
``MLNVectorTileSource`` is a map content source that supplies tiled vector data
|
||||
in <a href="https://www.mapbox.com/vector-tiles/">Mapbox Vector Tile</a> format
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
#include <mbgl/style/sources/vector_source.hpp>
|
||||
#include <mbgl/renderer/renderer.hpp>
|
||||
|
||||
const MLNTileSourceOption MLNVectorTileSourceOptionEncoding = @"MLNVectorTileSourceOptionEncoding";
|
||||
|
||||
@interface MLNVectorTileSource ()
|
||||
|
||||
@property (nonatomic, readonly) mbgl::style::VectorSource *rawSource;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#import <Mapbox.h>
|
||||
#import "MLNVectorTileSource.h"
|
||||
#import "MLNTileSource_Private.h"
|
||||
#import "MLNGeometry_Private.h"
|
||||
|
||||
@@ -12,9 +13,13 @@
|
||||
|
||||
@implementation MLNTileSetTests
|
||||
|
||||
- (void)testTileSetFromTileURLTemplates {
|
||||
namespace {
|
||||
// a tile set that provides an mbgl tile set
|
||||
NSArray *tileURLTemplates = @[@"tile.1", @"tile.2", @"tile.3"];
|
||||
|
||||
}
|
||||
|
||||
- (void)testTileSetFromTileURLTemplates {
|
||||
mbgl::Tileset tileSet = MLNTileSetFromTileURLTemplates(tileURLTemplates, nil);
|
||||
|
||||
// has the correct URL templates
|
||||
@@ -120,23 +125,61 @@
|
||||
|
||||
// the scheme is reflected by the mbgl tileset
|
||||
XCTAssertEqual(tileSet.scheme, mbgl::Tileset::Scheme::TMS);
|
||||
}
|
||||
|
||||
// when the dem encoding is changed using an NSNumber
|
||||
- (void)testTileSetFromTileURLTemplatesRasterEncodings {
|
||||
mbgl::Tileset tileSet;
|
||||
|
||||
// when the DEM encoding is changed using an NSNumber
|
||||
tileSet = MLNTileSetFromTileURLTemplates(tileURLTemplates, @{
|
||||
MLNTileSourceOptionDEMEncoding: @(MLNDEMEncodingTerrarium),
|
||||
});
|
||||
|
||||
// the encoding is reflected by the mbgl tileset
|
||||
XCTAssertEqual(tileSet.encoding, mbgl::Tileset::DEMEncoding::Terrarium);
|
||||
XCTAssertEqual(tileSet.rasterEncoding, mbgl::Tileset::RasterEncoding::Terrarium);
|
||||
XCTAssertFalse(tileSet.vectorEncoding);
|
||||
|
||||
// when the dem encoding is changed using an NSValue
|
||||
// when the raster encoding is changed using an NSValue
|
||||
MLNDEMEncoding terrarium = MLNDEMEncodingTerrarium;
|
||||
tileSet = MLNTileSetFromTileURLTemplates(tileURLTemplates, @{
|
||||
MLNTileSourceOptionDEMEncoding: [NSValue value:&terrarium withObjCType:@encode(MLNDEMEncoding)],
|
||||
});
|
||||
|
||||
// the encoding is reflected by the mbgl tileset
|
||||
XCTAssertEqual(tileSet.encoding, mbgl::Tileset::DEMEncoding::Terrarium);
|
||||
XCTAssertEqual(tileSet.rasterEncoding, mbgl::Tileset::RasterEncoding::Terrarium);
|
||||
XCTAssertFalse(tileSet.vectorEncoding);
|
||||
}
|
||||
|
||||
- (void)testTileSetFromTileURLTemplatesVectorEncodings {
|
||||
mbgl::Tileset tileSet;
|
||||
|
||||
// when the raster encoding is changed using an NSNumber
|
||||
tileSet = MLNTileSetFromTileURLTemplates(tileURLTemplates, @{
|
||||
MLNVectorTileSourceOptionEncoding: @(MLNVectorTileSourceEncodingMapbox),
|
||||
});
|
||||
|
||||
// the encoding is reflected by the mbgl tileset
|
||||
XCTAssertEqual(tileSet.vectorEncoding, mbgl::Tileset::VectorEncoding::Mapbox);
|
||||
XCTAssertFalse(tileSet.rasterEncoding);
|
||||
|
||||
// when the raster encoding is changed using an NSNumber
|
||||
tileSet = MLNTileSetFromTileURLTemplates(tileURLTemplates, @{
|
||||
MLNVectorTileSourceOptionEncoding: @(MLNVectorTileSourceEncodingMLT),
|
||||
});
|
||||
|
||||
// the encoding is reflected by the mbgl tileset
|
||||
XCTAssertEqual(tileSet.vectorEncoding, mbgl::Tileset::VectorEncoding::MLT);
|
||||
XCTAssertFalse(tileSet.rasterEncoding);
|
||||
|
||||
// when the raster encoding is changed using an NSValue
|
||||
MLNVectorTileSourceEncoding mlt = MLNVectorTileSourceEncodingMLT;
|
||||
tileSet = MLNTileSetFromTileURLTemplates(tileURLTemplates, @{
|
||||
MLNVectorTileSourceOptionEncoding: [NSValue value:&mlt withObjCType:@encode(MLNVectorTileSourceEncoding)],
|
||||
});
|
||||
|
||||
// the encoding is reflected by the mbgl tileset
|
||||
XCTAssertEqual(tileSet.vectorEncoding, mbgl::Tileset::VectorEncoding::MLT);
|
||||
XCTAssertFalse(tileSet.rasterEncoding);
|
||||
}
|
||||
|
||||
- (void)testInvalidTileSet {
|
||||
|
||||
@@ -105,6 +105,11 @@ public:
|
||||
const auto format_ptr = values.find("format");
|
||||
const std::string format = (format_ptr == values.end()) ? "png" : format_ptr->second;
|
||||
|
||||
// Translate MIME type field to source encoding.
|
||||
if (format == "mlt" || format == "application/vnd.maplibre-vector-tile") {
|
||||
doc.AddMember("encoding", "mlt", allocator);
|
||||
}
|
||||
|
||||
if (format != "pbf" && !values.contains("scale")) {
|
||||
values["scale"] = "1";
|
||||
}
|
||||
|
||||
@@ -47,6 +47,11 @@ std::string extract_url(const std::string& url) {
|
||||
}
|
||||
} // namespace
|
||||
|
||||
// temporary, remove this when it's available in `pmtiles.hpp`
|
||||
namespace pmtiles {
|
||||
const uint8_t TILETYPE_MLT = 0x6;
|
||||
} // namespace pmtiles
|
||||
|
||||
namespace mbgl {
|
||||
using namespace rapidjson;
|
||||
|
||||
@@ -305,6 +310,11 @@ private:
|
||||
rapidjson::Value().SetString(std::string(util::PMTILES_PROTOCOL + url), allocator), allocator);
|
||||
}
|
||||
|
||||
// Translate tile type field to source encoding.
|
||||
if (header.tile_type == pmtiles::TILETYPE_MLT) {
|
||||
doc.AddMember("encoding", "mlt", allocator);
|
||||
}
|
||||
|
||||
if (!doc.HasMember("bounds")) {
|
||||
doc.AddMember("bounds", rapidjson::Value(), allocator);
|
||||
}
|
||||
|
||||
@@ -131,6 +131,57 @@ ArgumentsTuple parseArguments(int argc, char** argv) {
|
||||
updateResults,
|
||||
std::move(testFilter)};
|
||||
}
|
||||
|
||||
void runWithAlternateSources(TestRunner& runner, TestMetadata& metadata, bool& errored, bool& passed) {
|
||||
constexpr auto replacementsKey = "source-replace";
|
||||
constexpr auto targetKey = "replace";
|
||||
constexpr auto sourceKey = "with";
|
||||
constexpr auto sourcesKey = "sources";
|
||||
|
||||
if (!metadata.document.HasMember("metadata") || !metadata.document["metadata"].HasMember("test")) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto& testElement = metadata.document["metadata"]["test"];
|
||||
if (!testElement.HasMember(replacementsKey) || !testElement[replacementsKey].IsArray()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& replacesElement = testElement[replacementsKey];
|
||||
if (!replacesElement.IsArray() || replacesElement.Empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto& sources = metadata.document[sourcesKey];
|
||||
|
||||
// Each item in the source replacements array...
|
||||
for (auto i = replacesElement.Begin(); i != replacesElement.End(); ++i) {
|
||||
const auto& entry = *i;
|
||||
if (entry.IsObject() && entry.HasMember(targetKey) && entry.HasMember(sourceKey) &&
|
||||
entry[targetKey].IsString() && entry[sourceKey].IsString()) {
|
||||
const auto* targetName = entry[targetKey].GetString();
|
||||
const auto* sourceName = entry[sourceKey].GetString();
|
||||
if (sources.HasMember(targetName) && sources[targetName].IsObject() && sources.HasMember(sourceName) &&
|
||||
sources[sourceName].IsObject()) {
|
||||
// Swap the named sources
|
||||
sources[targetName].Swap(sources[sourceName]);
|
||||
|
||||
// run the test again with the new source
|
||||
runner.run(metadata);
|
||||
|
||||
// Restore the original source
|
||||
sources[targetName].Swap(sources[sourceName]);
|
||||
|
||||
// stop if the test fails
|
||||
errored = metadata.metricsErrored || metadata.renderErrored || metadata.labelCutOffFound;
|
||||
passed = !errored && !metadata.metricsFailed && !metadata.renderFailed;
|
||||
if (!passed) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
namespace mbgl {
|
||||
|
||||
@@ -200,7 +251,7 @@ int runRenderTests(int argc, char** argv, std::function<void()> testStatus) {
|
||||
if (it != ignores.end()) {
|
||||
metadata.ignoredTest = shouldIgnore = true;
|
||||
ignoreReason = it->second;
|
||||
if (ignoreReason.rfind("skip", 0) == 0) {
|
||||
if (ignoreReason.starts_with("skip")) {
|
||||
printf(ANSI_COLOR_GRAY "* skipped %s (%s)" ANSI_COLOR_RESET "\n", id.c_str(), ignoreReason.c_str());
|
||||
mbgl::Log::Info(mbgl::Event::General, "* skipped " + id + "(" + ignoreReason + ")");
|
||||
continue;
|
||||
@@ -217,6 +268,10 @@ int runRenderTests(int argc, char** argv, std::function<void()> testStatus) {
|
||||
bool errored = metadata.metricsErrored || metadata.renderErrored || metadata.labelCutOffFound;
|
||||
bool passed = !errored && !metadata.metricsFailed && !metadata.renderFailed;
|
||||
|
||||
if (passed) {
|
||||
runWithAlternateSources(runner, metadata, errored, passed);
|
||||
}
|
||||
|
||||
if (shouldIgnore) {
|
||||
if (passed) {
|
||||
status = "ignored passed";
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
DEMData::DEMData(const PremultipliedImage& _image, Tileset::DEMEncoding _encoding)
|
||||
DEMData::DEMData(const PremultipliedImage& _image, Tileset::RasterEncoding _encoding)
|
||||
: dim(_image.size.height),
|
||||
// extra two pixels per row for border backfilling on either edge
|
||||
stride(dim + 2),
|
||||
@@ -99,7 +99,7 @@ const std::array<float, 4>& DEMData::getUnpackVector() const {
|
||||
// https://aws.amazon.com/public-datasets/terrain/
|
||||
static const std::array<float, 4> unpackTerrarium = {{256.0f, 1.0f, 1.0f / 256.0f, 32768.0f}};
|
||||
|
||||
return encoding == Tileset::DEMEncoding::Terrarium ? unpackTerrarium : unpackMapbox;
|
||||
return encoding == Tileset::RasterEncoding::Terrarium ? unpackTerrarium : unpackMapbox;
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace mbgl {
|
||||
|
||||
class DEMData {
|
||||
public:
|
||||
DEMData(const PremultipliedImage& image, Tileset::DEMEncoding encoding);
|
||||
DEMData(const PremultipliedImage& image, Tileset::RasterEncoding encoding);
|
||||
void backfillBorder(const DEMData& borderTileData, int8_t dx, int8_t dy);
|
||||
|
||||
int32_t get(int32_t x, int32_t y) const;
|
||||
@@ -24,7 +24,7 @@ public:
|
||||
|
||||
const int32_t dim;
|
||||
const int32_t stride;
|
||||
const Tileset::DEMEncoding encoding;
|
||||
const Tileset::RasterEncoding encoding;
|
||||
|
||||
private:
|
||||
std::shared_ptr<PremultipliedImage> image;
|
||||
|
||||
@@ -54,10 +54,10 @@ std::size_t totalVerticesCheck(const GeometryCollection& polygon) {
|
||||
|
||||
void addFillIndices(SegmentVector& fillSegments,
|
||||
gfx::IndexVector<gfx::Triangles>& fillIndexes,
|
||||
std::vector<uint32_t>& indices,
|
||||
std::size_t startVertices,
|
||||
std::size_t totalVertices) {
|
||||
std::size_t nIndices = indices.size();
|
||||
const std::span<const uint32_t>& indices,
|
||||
const std::size_t startVertices,
|
||||
const std::size_t totalVertices) {
|
||||
const std::size_t nIndices = indices.size();
|
||||
assert(nIndices % 3 == 0);
|
||||
|
||||
if (fillSegments.empty() ||
|
||||
@@ -66,10 +66,13 @@ void addFillIndices(SegmentVector& fillSegments,
|
||||
}
|
||||
|
||||
auto& triangleSegment = fillSegments.back();
|
||||
assert(triangleSegment.vertexLength <= std::numeric_limits<uint16_t>::max());
|
||||
assert(triangleSegment.vertexLength + totalVertices <= std::numeric_limits<uint16_t>::max());
|
||||
const auto triangleIndex = static_cast<uint16_t>(triangleSegment.vertexLength);
|
||||
|
||||
for (std::size_t i = 0; i < nIndices; i += 3) {
|
||||
assert(
|
||||
std::max({triangleIndex + indices[i + 0], triangleIndex + indices[i + 1], triangleIndex + indices[i + 2]}) <
|
||||
triangleIndex + totalVertices);
|
||||
fillIndexes.emplace_back(
|
||||
triangleIndex + indices[i], triangleIndex + indices[i + 1], triangleIndex + indices[i + 2]);
|
||||
}
|
||||
@@ -78,8 +81,8 @@ void addFillIndices(SegmentVector& fillSegments,
|
||||
triangleSegment.indexLength += nIndices;
|
||||
}
|
||||
|
||||
void addOutlineIndices(std::size_t base,
|
||||
std::size_t nVertices,
|
||||
void addOutlineIndices(const std::size_t base,
|
||||
const std::size_t nVertices,
|
||||
SegmentVector& lineSegments,
|
||||
gfx::IndexVector<gfx::Lines>& lineIndexes) {
|
||||
if (nVertices == 0) return;
|
||||
@@ -206,21 +209,36 @@ void generateFillAndOutineBuffers(const GeometryCollection& geometry,
|
||||
gfx::PolylineGeneratorOptions lineOptions;
|
||||
lineOptions.type = FeatureType::Polygon;
|
||||
|
||||
// If we have pre-tessellated geometry, multi-polygons are tessellated
|
||||
// together, so we need to add them to the fill segment all at once.
|
||||
if (!geometry.getTriangles().empty()) {
|
||||
const std::size_t startVertices = fillVertices.elements();
|
||||
std::size_t totalVertices = 0;
|
||||
for (const auto& polygon : geometry) {
|
||||
totalVertices += polygon.size();
|
||||
addRingVertices(fillVertices, polygon);
|
||||
}
|
||||
addFillIndices(fillSegments, fillIndexes, geometry.getTriangles(), startVertices, totalVertices);
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& polygon : classifyRings(geometry)) {
|
||||
// Optimize polygons with many interior rings for earcut tesselation.
|
||||
limitHoles(polygon, 500);
|
||||
|
||||
std::size_t totalVertices = totalVerticesCheck(polygon);
|
||||
std::size_t startVertices = fillVertices.elements();
|
||||
const std::size_t totalVertices = totalVerticesCheck(polygon);
|
||||
const std::size_t startVertices = fillVertices.elements();
|
||||
|
||||
for (const auto& ring : polygon) {
|
||||
std::size_t base = fillVertices.elements();
|
||||
std::size_t nVertices = addRingVertices(fillVertices, ring);
|
||||
const std::size_t base = fillVertices.elements();
|
||||
const std::size_t nVertices = addRingVertices(fillVertices, ring);
|
||||
addOutlineIndices(base, nVertices, basicLineSegments, basicLineIndexes);
|
||||
lineGenerator.generate(ring, lineOptions);
|
||||
}
|
||||
|
||||
// tessellate, if no triangles are provided
|
||||
std::vector<uint32_t> indices = mapbox::earcut(polygon);
|
||||
|
||||
addFillIndices(fillSegments, fillIndexes, indices, startVertices, totalVertices);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,13 +11,13 @@ namespace gfx {
|
||||
|
||||
class HillshadePrepareDrawableData : public DrawableData {
|
||||
public:
|
||||
HillshadePrepareDrawableData(int32_t stride_, Tileset::DEMEncoding encoding_, uint8_t maxzoom_)
|
||||
HillshadePrepareDrawableData(int32_t stride_, Tileset::RasterEncoding encoding_, uint8_t maxzoom_)
|
||||
: stride(stride_),
|
||||
encoding(encoding_),
|
||||
maxzoom(maxzoom_) {}
|
||||
|
||||
int32_t stride;
|
||||
Tileset::DEMEncoding encoding;
|
||||
Tileset::RasterEncoding encoding;
|
||||
uint8_t maxzoom;
|
||||
};
|
||||
|
||||
|
||||
78
src/mbgl/programs/programs.cpp
Normal file
78
src/mbgl/programs/programs.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
#include <mbgl/programs/programs.hpp>
|
||||
#include <mbgl/programs/background_program.hpp>
|
||||
#include <mbgl/programs/circle_program.hpp>
|
||||
#include <mbgl/programs/heatmap_program.hpp>
|
||||
#include <mbgl/programs/hillshade_program.hpp>
|
||||
#include <mbgl/programs/fill_extrusion_program.hpp>
|
||||
#include <mbgl/programs/fill_program.hpp>
|
||||
#include <mbgl/programs/line_program.hpp>
|
||||
#include <mbgl/programs/raster_program.hpp>
|
||||
#include <mbgl/programs/symbol_program.hpp>
|
||||
#include <mbgl/util/logging.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
Programs::Programs(const ProgramParameters& programParameters_)
|
||||
: programParameters(programParameters_) {}
|
||||
|
||||
Programs::~Programs() = default;
|
||||
|
||||
namespace {
|
||||
/// @brief Register a list of types with a shader registry instance
|
||||
/// @tparam ...T Type list parameter pack
|
||||
/// @param registry A shader registry instance
|
||||
/// programParameters_ ProgramParameters used to initialize each instance
|
||||
template <typename... T>
|
||||
void registerTypes(gfx::ShaderRegistry& registry, const ProgramParameters& programParameters_) {
|
||||
/// The following fold expression will create a shared_ptr for every type
|
||||
/// in the parameter pack and register it with the shader registry.
|
||||
|
||||
/// Registration calls are wrapped in a lambda that throws on registration
|
||||
/// failure, we shouldn't expect registration to faill unless the shader
|
||||
/// registry instance provided already has conflicting programs present.
|
||||
(
|
||||
[](bool expr) {
|
||||
if (!expr) {
|
||||
throw std::runtime_error("Failed to register " + std::string(T::Name) + " with shader registry!");
|
||||
}
|
||||
}(registry.getLegacyGroup().registerShader(std::make_shared<T>(programParameters_))),
|
||||
...);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void Programs::registerWith(gfx::ShaderRegistry& registry) {
|
||||
#if MLN_LEGACY_RENDERER
|
||||
/// The following types will be registered
|
||||
registerTypes<BackgroundProgram,
|
||||
BackgroundPatternProgram,
|
||||
RasterProgram,
|
||||
HeatmapProgram,
|
||||
HeatmapTextureProgram,
|
||||
HillshadeProgram,
|
||||
HillshadePrepareProgram,
|
||||
FillProgram,
|
||||
FillPatternProgram,
|
||||
FillOutlineProgram,
|
||||
FillOutlinePatternProgram,
|
||||
FillExtrusionProgram,
|
||||
FillExtrusionPatternProgram,
|
||||
CircleProgram,
|
||||
LineProgram,
|
||||
LineGradientProgram,
|
||||
LineSDFProgram,
|
||||
LinePatternProgram,
|
||||
SymbolIconProgram,
|
||||
SymbolSDFIconProgram,
|
||||
SymbolSDFTextProgram,
|
||||
SymbolTextAndIconProgram,
|
||||
CollisionBoxProgram,
|
||||
CollisionCircleProgram,
|
||||
DebugProgram,
|
||||
ClippingMaskProgram>(registry, programParameters);
|
||||
#else
|
||||
/// The following types will be registered
|
||||
registerTypes<DebugProgram, ClippingMaskProgram>(registry, programParameters);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
@@ -6,7 +6,7 @@ namespace mbgl {
|
||||
|
||||
using namespace style;
|
||||
|
||||
HillshadeBucket::HillshadeBucket(PremultipliedImage&& image_, Tileset::DEMEncoding encoding)
|
||||
HillshadeBucket::HillshadeBucket(PremultipliedImage&& image_, Tileset::RasterEncoding encoding)
|
||||
: demdata(image_, encoding) {}
|
||||
|
||||
HillshadeBucket::HillshadeBucket(DEMData&& demdata_)
|
||||
|
||||
@@ -19,8 +19,8 @@ using HillshadeLayoutVertex = gfx::Vertex<TypeList<attributes::pos, attributes::
|
||||
|
||||
class HillshadeBucket final : public Bucket {
|
||||
public:
|
||||
HillshadeBucket(PremultipliedImage&&, Tileset::DEMEncoding encoding);
|
||||
HillshadeBucket(std::shared_ptr<PremultipliedImage>, Tileset::DEMEncoding encoding);
|
||||
HillshadeBucket(PremultipliedImage&&, Tileset::RasterEncoding encoding);
|
||||
HillshadeBucket(std::shared_ptr<PremultipliedImage>, Tileset::RasterEncoding encoding);
|
||||
HillshadeBucket(DEMData&&);
|
||||
~HillshadeBucket() override;
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates,
|
||||
const std::size_t first = [&coordinates, &len] {
|
||||
std::size_t i = 0;
|
||||
// If the line has duplicate vertices at the start, adjust index to remove them.
|
||||
while (i < len - 1 && coordinates[i] == coordinates[i + 1]) {
|
||||
while (i + 1 < len && coordinates[i] == coordinates[i + 1]) {
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
@@ -102,17 +102,16 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates,
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& props = feature.getProperties();
|
||||
auto clip_start_it = props.find("mapbox_clip_start");
|
||||
auto clip_end_it = props.find("mapbox_clip_end");
|
||||
if (clip_start_it != props.end() && clip_end_it != props.end()) {
|
||||
const auto clip_start = feature.getValue("mapbox_clip_start");
|
||||
const auto clip_end = feature.getValue("mapbox_clip_end");
|
||||
if (clip_start && clip_end) {
|
||||
double total_length = 0.0;
|
||||
for (std::size_t i = first; i < len - 1; ++i) {
|
||||
total_length += util::dist<double>(coordinates[i], coordinates[i + 1]);
|
||||
}
|
||||
|
||||
options.clipDistances = gfx::PolylineGeneratorDistances{
|
||||
*numericValue<double>(clip_start_it->second), *numericValue<double>(clip_end_it->second), total_length};
|
||||
*numericValue<double>(*clip_start), *numericValue<double>(*clip_end), total_length};
|
||||
}
|
||||
|
||||
options.joinType = layout.evaluate<LineJoin>(zoom, feature, canonical);
|
||||
|
||||
@@ -22,8 +22,8 @@ constexpr std::array<float, 4> unpackMapbox = {{6553.6f, 25.6f, 0.1f, 10000.0f}}
|
||||
// https://aws.amazon.com/public-datasets/terrain/
|
||||
constexpr std::array<float, 4> unpackTerrarium = {{256.0f, 1.0f, 1.0f / 256.0f, 32768.0f}};
|
||||
|
||||
constexpr const std::array<float, 4>& getUnpackVector(const Tileset::DEMEncoding encoding) {
|
||||
return (encoding == Tileset::DEMEncoding::Terrarium) ? unpackTerrarium : unpackMapbox;
|
||||
constexpr const std::array<float, 4>& getUnpackVector(const Tileset::RasterEncoding encoding) {
|
||||
return (encoding == Tileset::RasterEncoding::Terrarium) ? unpackTerrarium : unpackMapbox;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ std::unique_ptr<RenderSource> RenderSource::create(const Immutable<Source::Impl>
|
||||
const TaggedScheduler& threadPool_) {
|
||||
switch (impl->type) {
|
||||
case SourceType::Vector:
|
||||
// the TileSet isn't available yet, so we can't make different sources by format
|
||||
return std::make_unique<RenderVectorSource>(staticImmutableCast<TileSource::Impl>(impl),
|
||||
std::move(threadPool_));
|
||||
case SourceType::Raster:
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
#include <mbgl/renderer/sources/render_vector_source.hpp>
|
||||
|
||||
#include <mbgl/renderer/render_tile.hpp>
|
||||
#include <mbgl/renderer/paint_parameters.hpp>
|
||||
#include <mbgl/tile/vector_tile.hpp>
|
||||
#include <mbgl/renderer/tile_parameters.hpp>
|
||||
#include <mbgl/tile/vector_mlt_tile.hpp>
|
||||
#include <mbgl/tile/vector_mvt_tile.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -20,17 +22,29 @@ void RenderVectorSource::updateInternal(const Tileset& tileset,
|
||||
const bool needsRendering,
|
||||
const bool needsRelayout,
|
||||
const TileParameters& parameters) {
|
||||
tilePyramid.update(layers,
|
||||
needsRendering,
|
||||
needsRelayout,
|
||||
parameters,
|
||||
*baseImpl,
|
||||
util::tileSize_I,
|
||||
tileset.zoomRange,
|
||||
tileset.bounds,
|
||||
[&](const OverscaledTileID& tileID, TileObserver* observer_) {
|
||||
return std::make_unique<VectorTile>(tileID, baseImpl->id, parameters, tileset, observer_);
|
||||
});
|
||||
tilePyramid.update(
|
||||
layers,
|
||||
needsRendering,
|
||||
needsRelayout,
|
||||
parameters,
|
||||
*baseImpl,
|
||||
util::tileSize_I,
|
||||
tileset.zoomRange,
|
||||
tileset.bounds,
|
||||
[&](const OverscaledTileID& tileID, TileObserver* observer_) -> std::unique_ptr<VectorTile> {
|
||||
if (!isMLT.has_value()) {
|
||||
auto impl = staticImmutableCast<style::TileSource::Impl>(baseImpl);
|
||||
assert(impl->tileset); // we should have one by now
|
||||
if (impl->tileset) {
|
||||
isMLT = (impl->tileset->vectorEncoding == Tileset::VectorEncoding::MLT);
|
||||
}
|
||||
}
|
||||
if (isMLT && *isMLT) {
|
||||
return std::make_unique<VectorMLTTile>(tileID, baseImpl->id, parameters, tileset, observer_);
|
||||
} else {
|
||||
return std::make_unique<VectorMVTTile>(tileID, baseImpl->id, parameters, tileset, observer_);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -17,6 +17,9 @@ private:
|
||||
bool needsRelayout,
|
||||
const TileParameters&) override;
|
||||
const std::optional<Tileset>& getTileset() const override;
|
||||
|
||||
private:
|
||||
std::optional<bool> isMLT;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
#include <mbgl/style/conversion/raster_dem_options.hpp>
|
||||
#include <mbgl/style/conversion_impl.hpp>
|
||||
#include <mbgl/style/expression/dsl.hpp>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace conversion {
|
||||
|
||||
std::optional<RasterDEMOptions> Converter<RasterDEMOptions>::operator()(const Convertible& value, Error& error) const {
|
||||
RasterDEMOptions options;
|
||||
|
||||
auto encodingValue = objectMember(value, "encoding");
|
||||
if (encodingValue) {
|
||||
std::optional<std::string> encoding = toString(*encodingValue);
|
||||
if (encoding && *encoding == "terrarium") {
|
||||
options.encoding = {Tileset::DEMEncoding::Terrarium};
|
||||
} else if (encoding && *encoding == "mapbox") {
|
||||
options.encoding = {Tileset::DEMEncoding::Mapbox};
|
||||
} else {
|
||||
error.message =
|
||||
"invalid raster-dem encoding type - valid types are 'mapbox' "
|
||||
"and 'terrarium'";
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
return {std::move(options)};
|
||||
}
|
||||
|
||||
} // namespace conversion
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <mbgl/style/conversion/coordinate.hpp>
|
||||
#include <mbgl/style/conversion/geojson.hpp>
|
||||
#include <mbgl/style/conversion/geojson_options.hpp>
|
||||
#include <mbgl/style/conversion/raster_dem_options.hpp>
|
||||
#include <mbgl/style/conversion/source_options.hpp>
|
||||
#include <mbgl/style/conversion/tileset.hpp>
|
||||
#include <mbgl/style/conversion_impl.hpp>
|
||||
#include <mbgl/style/sources/geojson_source.hpp>
|
||||
@@ -16,8 +16,8 @@ namespace mbgl {
|
||||
namespace style {
|
||||
namespace conversion {
|
||||
|
||||
// A tile source can either specify a URL to TileJSON, or inline TileJSON.
|
||||
namespace {
|
||||
// A tile source can either specify a URL to TileJSON, or inline TileJSON.
|
||||
std::optional<variant<std::string, Tileset>> convertURLOrTileset(const Convertible& value, Error& error) {
|
||||
auto urlVal = objectMember(value, "url");
|
||||
if (!urlVal) {
|
||||
@@ -25,7 +25,7 @@ std::optional<variant<std::string, Tileset>> convertURLOrTileset(const Convertib
|
||||
if (!tileset) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return {*tileset};
|
||||
return {std::move(*tileset)};
|
||||
}
|
||||
|
||||
std::optional<std::string> url = toString(*urlVal);
|
||||
@@ -34,7 +34,7 @@ std::optional<variant<std::string, Tileset>> convertURLOrTileset(const Convertib
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return {*url};
|
||||
return {std::move(*url)};
|
||||
}
|
||||
|
||||
std::optional<std::unique_ptr<Source>> convertRasterSource(const std::string& id,
|
||||
@@ -83,7 +83,7 @@ std::optional<std::unique_ptr<Source>> convertRasterDEMSource(const std::string&
|
||||
parameters. Since style.json can contain TileJSON parameter overrides or non-TileJSON spec parameters, a
|
||||
separate mechanism is needed. Ideally these two pathways share parsing logic.
|
||||
*/
|
||||
std::optional<RasterDEMOptions> options = convert<RasterDEMOptions>(value, error);
|
||||
auto options = convert<SourceOptions>(value, error);
|
||||
|
||||
return {std::make_unique<RasterDEMSource>(id, std::move(*urlOrTileset), tileSize, options)};
|
||||
}
|
||||
@@ -91,11 +91,11 @@ std::optional<std::unique_ptr<Source>> convertRasterDEMSource(const std::string&
|
||||
std::optional<std::unique_ptr<Source>> convertVectorSource(const std::string& id,
|
||||
const Convertible& value,
|
||||
Error& error) {
|
||||
std::optional<variant<std::string, Tileset>> urlOrTileset = convertURLOrTileset(value, error);
|
||||
auto urlOrTileset = convertURLOrTileset(value, error);
|
||||
if (!urlOrTileset) {
|
||||
return std::nullopt;
|
||||
}
|
||||
auto maxzoomValue = objectMember(value, "maxzoom");
|
||||
const auto maxzoomValue = objectMember(value, "maxzoom");
|
||||
std::optional<float> maxzoom;
|
||||
if (maxzoomValue) {
|
||||
maxzoom = toNumber(*maxzoomValue);
|
||||
@@ -104,7 +104,7 @@ std::optional<std::unique_ptr<Source>> convertVectorSource(const std::string& id
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
auto minzoomValue = objectMember(value, "minzoom");
|
||||
const auto minzoomValue = objectMember(value, "minzoom");
|
||||
std::optional<float> minzoom;
|
||||
if (minzoomValue) {
|
||||
minzoom = toNumber(*minzoomValue);
|
||||
@@ -113,7 +113,20 @@ std::optional<std::unique_ptr<Source>> convertVectorSource(const std::string& id
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
return {std::make_unique<VectorSource>(id, std::move(*urlOrTileset), std::move(maxzoom), std::move(minzoom))};
|
||||
const auto encodingValue = objectMember(value, "encoding");
|
||||
auto encoding = Tileset::VectorEncoding::Mapbox;
|
||||
if (encodingValue) {
|
||||
const auto encodingStr = toString(*encodingValue);
|
||||
if (encodingStr && encodingStr == "mvt") {
|
||||
encoding = Tileset::VectorEncoding::Mapbox;
|
||||
} else if (encodingStr && encodingStr == "mlt") {
|
||||
encoding = Tileset::VectorEncoding::MLT;
|
||||
} else {
|
||||
error.message = "invalid encoding";
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
return {std::make_unique<VectorSource>(id, std::move(*urlOrTileset), maxzoom, minzoom, encoding)};
|
||||
}
|
||||
|
||||
std::optional<std::unique_ptr<Source>> convertGeoJSONSource(const std::string& id,
|
||||
|
||||
33
src/mbgl/style/conversion/source_options.cpp
Normal file
33
src/mbgl/style/conversion/source_options.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#include <mbgl/style/conversion/source_options.hpp>
|
||||
#include <mbgl/style/conversion_impl.hpp>
|
||||
#include <mbgl/style/expression/dsl.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace conversion {
|
||||
|
||||
std::optional<SourceOptions> Converter<SourceOptions>::operator()(const Convertible& value, Error& error) const {
|
||||
const auto encodingValue = objectMember(value, "encoding");
|
||||
if (encodingValue) {
|
||||
const auto encoding = toString(*encodingValue);
|
||||
if (encoding && *encoding == "terrarium") {
|
||||
return {{.rasterEncoding = Tileset::RasterEncoding::Terrarium}};
|
||||
} else if (encoding && *encoding == "mapbox") {
|
||||
return {{.rasterEncoding = Tileset::RasterEncoding::Mapbox}};
|
||||
} else if (encoding && *encoding == "mvt") {
|
||||
return {{.vectorEncoding = Tileset::VectorEncoding::Mapbox}};
|
||||
} else if (encoding && *encoding == "mlt") {
|
||||
return {{.vectorEncoding = Tileset::VectorEncoding::MLT}};
|
||||
} else {
|
||||
error.message =
|
||||
"invalid encoding - valid types are 'mapbox' and 'terrarium' for raster sources, 'mvt' and 'mlt' for "
|
||||
"vector sources";
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace conversion
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <mbgl/style/conversion/tileset.hpp>
|
||||
#include <mbgl/style/conversion/raster_dem_options.hpp>
|
||||
#include <mbgl/style/conversion/source_options.hpp>
|
||||
#include <mbgl/style/conversion_impl.hpp>
|
||||
#include <mbgl/util/geo.hpp>
|
||||
#include <mbgl/math/clamp.hpp>
|
||||
@@ -39,10 +39,13 @@ std::optional<Tileset> Converter<Tileset>::operator()(const Convertible& value,
|
||||
}
|
||||
}
|
||||
|
||||
auto rasterDEMOptions = convert<RasterDEMOptions>(value, error);
|
||||
if (rasterDEMOptions) {
|
||||
if (std::optional<Tileset::DEMEncoding> encoding = rasterDEMOptions.value().encoding) {
|
||||
result.encoding = encoding.value();
|
||||
auto options = convert<SourceOptions>(value, error);
|
||||
if (options) {
|
||||
if (const auto encoding = options->rasterEncoding) {
|
||||
result.rasterEncoding = encoding;
|
||||
}
|
||||
if (const auto encoding = options->vectorEncoding) {
|
||||
result.vectorEncoding = encoding;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace style {
|
||||
RasterDEMSource::RasterDEMSource(std::string id,
|
||||
variant<std::string, Tileset> urlOrTileset_,
|
||||
uint16_t tileSize,
|
||||
std::optional<RasterDEMOptions> options_)
|
||||
std::optional<SourceOptions> options_)
|
||||
: RasterSource(std::move(id), std::move(urlOrTileset_), tileSize, SourceType::RasterDEM),
|
||||
options(std::move(options_)) {}
|
||||
|
||||
@@ -30,8 +30,8 @@ bool RasterDEMSource::supportsLayerType(const mbgl::style::LayerTypeInfo* info)
|
||||
|
||||
void RasterDEMSource::setTilesetOverrides(Tileset& tileset) {
|
||||
if (options) {
|
||||
if (std::optional<Tileset::DEMEncoding> encoding = options.value().encoding) {
|
||||
tileset.encoding = encoding.value();
|
||||
if (const auto encoding = options->rasterEncoding) {
|
||||
tileset.rasterEncoding = encoding;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <mbgl/util/constants.hpp>
|
||||
#include <mbgl/util/exception.hpp>
|
||||
#include <mbgl/util/mapbox.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
@@ -17,10 +18,12 @@ namespace style {
|
||||
VectorSource::VectorSource(std::string id,
|
||||
variant<std::string, Tileset> urlOrTileset_,
|
||||
std::optional<float> maxZoom_,
|
||||
std::optional<float> minZoom_)
|
||||
std::optional<float> minZoom_,
|
||||
Tileset::VectorEncoding encoding_)
|
||||
: TileSource(id, urlOrTileset_, util::tileSize_I, SourceType::Vector),
|
||||
maxZoom(std::move(maxZoom_)),
|
||||
minZoom(std::move(minZoom_)) {}
|
||||
minZoom(std::move(minZoom_)),
|
||||
encoding(encoding_) {}
|
||||
|
||||
void VectorSource::setTilesetOverrides(Tileset& tileset) {
|
||||
if (maxZoom) {
|
||||
|
||||
@@ -4,11 +4,14 @@
|
||||
#include <mbgl/util/feature.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
namespace mlt {
|
||||
class MapLibreTile;
|
||||
}
|
||||
namespace mbgl {
|
||||
|
||||
class CanonicalTileID;
|
||||
@@ -44,8 +47,17 @@ public:
|
||||
|
||||
GeometryCollection clone() const { return GeometryCollection(*this); }
|
||||
|
||||
const auto& getTriangles() const { return triangles; }
|
||||
void setTriangles(std::shared_ptr<const mlt::MapLibreTile> owner, std::span<const std::uint32_t> triangles_) {
|
||||
triangleOwner = std::move(owner);
|
||||
triangles = triangles_;
|
||||
}
|
||||
|
||||
private:
|
||||
GeometryCollection(const GeometryCollection&) = default;
|
||||
|
||||
std::shared_ptr<const mlt::MapLibreTile> triangleOwner;
|
||||
std::span<const std::uint32_t> triangles = {};
|
||||
};
|
||||
|
||||
class GeometryTileFeature {
|
||||
|
||||
@@ -24,7 +24,7 @@ RasterDEMTile::RasterDEMTile(const OverscaledTileID& id_,
|
||||
threadPool(parameters.threadPool),
|
||||
mailbox(std::make_shared<Mailbox>(*Scheduler::GetCurrent())),
|
||||
worker(parameters.threadPool, ActorRef<RasterDEMTile>(*this, mailbox)) {
|
||||
encoding = tileset.encoding;
|
||||
encoding = tileset.rasterEncoding.value_or(Tileset::RasterEncoding::Mapbox);
|
||||
if (id.canonical.y == 0) {
|
||||
// this tile doesn't have upper neighboring tiles so marked those as backfilled
|
||||
neighboringTiles = neighboringTiles | DEMTileNeighbors::NoUpper;
|
||||
|
||||
@@ -99,7 +99,7 @@ private:
|
||||
Actor<RasterDEMTileWorker> worker;
|
||||
|
||||
uint64_t correlationID = 0;
|
||||
Tileset::DEMEncoding encoding;
|
||||
Tileset::RasterEncoding encoding;
|
||||
|
||||
// Contains the Bucket object for the tile. Buckets are render
|
||||
// objects and they get added by tile parsing operations.
|
||||
|
||||
@@ -11,7 +11,7 @@ RasterDEMTileWorker::RasterDEMTileWorker(const ActorRef<RasterDEMTileWorker>&, A
|
||||
|
||||
void RasterDEMTileWorker::parse(const std::shared_ptr<const std::string>& data,
|
||||
uint64_t correlationID,
|
||||
Tileset::DEMEncoding encoding) {
|
||||
Tileset::RasterEncoding encoding) {
|
||||
if (!data) {
|
||||
parent.invoke(&RasterDEMTile::onParsed, nullptr,
|
||||
correlationID); // No data; empty tile.
|
||||
|
||||
@@ -14,7 +14,9 @@ class RasterDEMTileWorker {
|
||||
public:
|
||||
RasterDEMTileWorker(const ActorRef<RasterDEMTileWorker>&, ActorRef<RasterDEMTile>);
|
||||
|
||||
void parse(const std::shared_ptr<const std::string>& data, uint64_t correlationID, Tileset::DEMEncoding encoding);
|
||||
void parse(const std::shared_ptr<const std::string>& data,
|
||||
uint64_t correlationID,
|
||||
Tileset::RasterEncoding encoding);
|
||||
|
||||
private:
|
||||
ActorRef<RasterDEMTile> parent;
|
||||
|
||||
24
src/mbgl/tile/vector_mlt_tile.cpp
Normal file
24
src/mbgl/tile/vector_mlt_tile.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#include <mbgl/tile/vector_mlt_tile.hpp>
|
||||
|
||||
#include <mbgl/renderer/tile_parameters.hpp>
|
||||
#include <mbgl/tile/tile_loader_impl.hpp>
|
||||
#include <mbgl/tile/vector_mlt_tile_data.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
VectorMLTTile::VectorMLTTile(const OverscaledTileID& id_,
|
||||
std::string sourceID_,
|
||||
const TileParameters& parameters_,
|
||||
const Tileset& tileset_,
|
||||
TileObserver* observer_)
|
||||
: VectorTile(id_, std::move(sourceID_), parameters_, tileset_, observer_) {}
|
||||
|
||||
void VectorMLTTile::setData(const std::shared_ptr<const std::string>& data_) {
|
||||
if (!obsolete) {
|
||||
GeometryTile::setData(data_ ? std::make_unique<VectorMLTTileData>(data_) : nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
23
src/mbgl/tile/vector_mlt_tile.hpp
Normal file
23
src/mbgl/tile/vector_mlt_tile.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/tile_loader.hpp>
|
||||
#include <mbgl/tile/vector_tile.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class Tileset;
|
||||
class TileParameters;
|
||||
|
||||
class VectorMLTTile : public VectorTile {
|
||||
public:
|
||||
VectorMLTTile(const OverscaledTileID&,
|
||||
std::string sourceID,
|
||||
const TileParameters&,
|
||||
const Tileset&,
|
||||
TileObserver* observer = nullptr);
|
||||
|
||||
void setData(const std::shared_ptr<const std::string>& data) override;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
220
src/mbgl/tile/vector_mlt_tile_data.cpp
Normal file
220
src/mbgl/tile/vector_mlt_tile_data.cpp
Normal file
@@ -0,0 +1,220 @@
|
||||
#include <mapbox/feature.hpp>
|
||||
#include <mbgl/tile/vector_mlt_tile_data.hpp>
|
||||
|
||||
#include <mbgl/util/constants.hpp>
|
||||
#include <mbgl/util/instrumentation.hpp>
|
||||
#include <mbgl/util/logging.hpp>
|
||||
|
||||
#include <mlt/decoder.hpp>
|
||||
#include <mlt/layer.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
using GeometryType = mlt::metadata::tileset::GeometryType;
|
||||
|
||||
VectorMLTTileFeature::VectorMLTTileFeature(std::shared_ptr<const MapLibreTile> tile_,
|
||||
const mlt::Layer& layer_,
|
||||
const mlt::Feature& feature_,
|
||||
std::uint32_t extent_)
|
||||
: tile(std::move(tile_)),
|
||||
layer(layer_),
|
||||
feature(feature_),
|
||||
extent(extent_) {}
|
||||
|
||||
FeatureType VectorMLTTileFeature::getType() const {
|
||||
switch (feature.getGeometry().type) {
|
||||
case GeometryType::POINT:
|
||||
return FeatureType::Point;
|
||||
case GeometryType::MULTIPOINT:
|
||||
case GeometryType::MULTILINESTRING:
|
||||
case GeometryType::LINESTRING:
|
||||
return FeatureType::LineString;
|
||||
case GeometryType::POLYGON:
|
||||
case GeometryType::MULTIPOLYGON:
|
||||
return FeatureType::Polygon;
|
||||
default:
|
||||
return FeatureType::Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct PropertyVisitor {
|
||||
Value operator()(std::nullptr_t) const { return mapbox::feature::null_value; }
|
||||
Value operator()(bool value) const { return value; }
|
||||
Value operator()(std::uint32_t value) const { return value; }
|
||||
Value operator()(std::uint64_t value) const { return value; }
|
||||
Value operator()(float value) const { return value; }
|
||||
Value operator()(double value) const { return value; }
|
||||
Value operator()(std::string_view value) const { return std::string(value); }
|
||||
|
||||
template <typename T>
|
||||
Value operator()(std::optional<T> value) const {
|
||||
return value ? operator()(*value) : NullValue();
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
|
||||
std::optional<Value> VectorMLTTileFeature::getValue(const std::string& key) const {
|
||||
if (auto prop = feature.getProperty(key, layer)) {
|
||||
return std::visit(PropertyVisitor(), *prop);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const PropertyMap& VectorMLTTileFeature::getProperties() const {
|
||||
if (!properties) {
|
||||
const PropertyVisitor visitor;
|
||||
properties.emplace();
|
||||
properties->reserve(layer.getProperties().size());
|
||||
for (const auto& [key, props] : layer.getProperties()) {
|
||||
auto value = props.getProperty(feature.getIndex());
|
||||
auto prop = value ? std::visit(visitor, std::move(*value)) : mapbox::feature::null_value;
|
||||
properties->emplace(key, std::move(prop));
|
||||
}
|
||||
}
|
||||
return *properties;
|
||||
}
|
||||
|
||||
FeatureIdentifier VectorMLTTileFeature::getID() const {
|
||||
return feature.getID();
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct PointConverter {
|
||||
double scale;
|
||||
inline constexpr static GeometryCoordinate convert(double scale, const mlt::Coordinate& coord) {
|
||||
return {static_cast<std::int16_t>(std::round(coord.x * scale)),
|
||||
static_cast<std::int16_t>(std::round(coord.y * scale))};
|
||||
}
|
||||
GeometryCoordinate operator()(const mlt::Coordinate& coord) const { return convert(scale, coord); }
|
||||
GeometryCoordinates operator()(const mlt::CoordVec& coords) const {
|
||||
GeometryCoordinates result(coords.size());
|
||||
std::ranges::transform(coords, result.begin(), *this);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
|
||||
const GeometryCollection& VectorMLTTileFeature::getGeometries() const {
|
||||
MLN_TRACE_FUNC();
|
||||
|
||||
if (!lines) {
|
||||
const auto scale = static_cast<double>(util::EXTENT) / extent;
|
||||
const auto& geometry = feature.getGeometry();
|
||||
const PointConverter convert{scale};
|
||||
switch (geometry.type) {
|
||||
case GeometryType::POINT: {
|
||||
const auto& geom = static_cast<const mlt::geometry::Point&>(geometry);
|
||||
lines = GeometryCollection{{convert(geom.getCoordinate())}};
|
||||
break;
|
||||
}
|
||||
case GeometryType::MULTIPOINT:
|
||||
case GeometryType::LINESTRING: {
|
||||
const auto& geom = static_cast<const mlt::geometry::MultiPoint&>(geometry);
|
||||
lines = GeometryCollection{convert(geom.getCoordinates())};
|
||||
break;
|
||||
}
|
||||
case GeometryType::POLYGON: {
|
||||
const auto& geom = static_cast<const mlt::geometry::Polygon&>(geometry);
|
||||
lines.emplace(geom.getRings().size());
|
||||
std::ranges::transform(geom.getRings(), lines->begin(), convert);
|
||||
if (!geometry.getTriangles().empty()) {
|
||||
lines->setTriangles(tile, geometry.getTriangles());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GeometryType::MULTILINESTRING: {
|
||||
const auto& geom = static_cast<const mlt::geometry::MultiLineString&>(geometry);
|
||||
lines.emplace(geom.getLineStrings().size());
|
||||
std::ranges::transform(geom.getLineStrings(), lines->begin(), convert);
|
||||
break;
|
||||
}
|
||||
case GeometryType::MULTIPOLYGON: {
|
||||
const auto& geom = static_cast<const mlt::geometry::MultiPolygon&>(geometry);
|
||||
const auto& polygons = geom.getPolygons();
|
||||
using RingVec = mlt::geometry::MultiPolygon::RingVec;
|
||||
lines.emplace(std::accumulate(
|
||||
polygons.begin(), polygons.end(), static_cast<std::size_t>(0), [](std::size_t a, const RingVec& b) {
|
||||
return a + b.size();
|
||||
}));
|
||||
for (const auto& poly : polygons) {
|
||||
std::ranges::transform(poly, std::back_inserter(*lines), convert);
|
||||
}
|
||||
if (!geometry.getTriangles().empty()) {
|
||||
lines->setTriangles(tile, geometry.getTriangles());
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
lines.emplace();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return *lines;
|
||||
}
|
||||
|
||||
VectorMLTTileLayer::VectorMLTTileLayer(std::shared_ptr<const MapLibreTile> tile_, const mlt::Layer& layer_)
|
||||
: tile(std::move(tile_)),
|
||||
layer(layer_) {}
|
||||
|
||||
std::size_t VectorMLTTileLayer::featureCount() const {
|
||||
return layer.getFeatures().size();
|
||||
}
|
||||
|
||||
std::unique_ptr<GeometryTileFeature> VectorMLTTileLayer::getFeature(std::size_t index) const {
|
||||
const auto& features = layer.getFeatures();
|
||||
const mlt::Feature* targetFeature = nullptr;
|
||||
targetFeature = &features[index];
|
||||
return std::make_unique<VectorMLTTileFeature>(tile, layer, *targetFeature, layer.getExtent());
|
||||
}
|
||||
|
||||
std::string VectorMLTTileLayer::getName() const {
|
||||
return layer.getName();
|
||||
}
|
||||
|
||||
VectorMLTTileData::VectorMLTTileData(std::shared_ptr<const std::string> data_)
|
||||
: data(std::move(data_)) {}
|
||||
|
||||
VectorMLTTileData::VectorMLTTileData(const VectorMLTTileData& other)
|
||||
: data(other.data),
|
||||
tile(other.tile) {}
|
||||
|
||||
std::unique_ptr<GeometryTileData> VectorMLTTileData::clone() const {
|
||||
return std::make_unique<VectorMLTTileData>(*this);
|
||||
}
|
||||
|
||||
std::unique_ptr<GeometryTileLayer> VectorMLTTileData::getLayer(const std::string& name) const {
|
||||
MLN_TRACE_FUNC();
|
||||
|
||||
if (data && !tile) {
|
||||
try {
|
||||
mlt::DataView tileData{data->data(), data->size()};
|
||||
tile = std::make_shared<MapLibreTile>(mlt::Decoder().decode(tileData));
|
||||
} catch (const std::exception& ex) {
|
||||
Log::Warning(Event::ParseTile, "MLT parse failed: " + std::string(ex.what()));
|
||||
}
|
||||
// We don't need the raw data anymore
|
||||
data.reset();
|
||||
}
|
||||
|
||||
if (tile) {
|
||||
if (const auto* layer = tile->getLayer(name)) {
|
||||
return std::make_unique<VectorMLTTileLayer>(tile, *layer);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<std::string> VectorMLTTileData::layerNames() const {
|
||||
if (data && !data->empty() && !tile) {
|
||||
getLayer({});
|
||||
}
|
||||
if (tile) {
|
||||
std::vector<std::string> result(tile->getLayers().size());
|
||||
std::ranges::transform(tile->getLayers(), result.begin(), [](const auto& layer) { return layer.getName(); });
|
||||
return result;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
85
src/mbgl/tile/vector_mlt_tile_data.hpp
Normal file
85
src/mbgl/tile/vector_mlt_tile_data.hpp
Normal file
@@ -0,0 +1,85 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
#include <mbgl/util/containers.hpp>
|
||||
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
|
||||
namespace mlt {
|
||||
class MapLibreTile;
|
||||
class Feature;
|
||||
class Layer;
|
||||
} // namespace mlt
|
||||
|
||||
namespace mbgl {
|
||||
using MapLibreTile = mlt::MapLibreTile;
|
||||
|
||||
class VectorMLTTileFeature : public GeometryTileFeature {
|
||||
public:
|
||||
VectorMLTTileFeature(std::shared_ptr<const MapLibreTile>,
|
||||
const mlt::Layer& layer_,
|
||||
const mlt::Feature&,
|
||||
std::uint32_t extent);
|
||||
VectorMLTTileFeature(const VectorMLTTileFeature&) = delete;
|
||||
VectorMLTTileFeature(VectorMLTTileFeature&& other)
|
||||
: tile(std::move(other.tile)),
|
||||
layer(other.layer),
|
||||
feature(other.feature),
|
||||
extent(other.extent),
|
||||
version(other.version),
|
||||
lines(std::move(other.lines)),
|
||||
properties(std::move(other.properties)) {}
|
||||
|
||||
VectorMLTTileFeature& operator=(VectorMLTTileFeature&&) = delete;
|
||||
VectorMLTTileFeature& operator=(const VectorMLTTileFeature&) = delete;
|
||||
|
||||
FeatureType getType() const override;
|
||||
std::optional<Value> getValue(const std::string& key) const override;
|
||||
const PropertyMap& getProperties() const override;
|
||||
FeatureIdentifier getID() const override;
|
||||
const GeometryCollection& getGeometries() const override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<const MapLibreTile> tile;
|
||||
const mlt::Layer& layer;
|
||||
mlt::Feature const& feature;
|
||||
std::uint32_t extent;
|
||||
int version;
|
||||
|
||||
// lazy init
|
||||
mutable std::optional<GeometryCollection> lines;
|
||||
mutable std::optional<PropertyMap> properties;
|
||||
};
|
||||
|
||||
class VectorMLTTileLayer : public GeometryTileLayer {
|
||||
public:
|
||||
VectorMLTTileLayer(std::shared_ptr<const MapLibreTile>, const mlt::Layer&);
|
||||
|
||||
std::size_t featureCount() const override;
|
||||
std::unique_ptr<GeometryTileFeature> getFeature(std::size_t i) const override;
|
||||
std::string getName() const override;
|
||||
|
||||
private:
|
||||
const std::shared_ptr<const MapLibreTile> tile;
|
||||
const mlt::Layer& layer;
|
||||
};
|
||||
|
||||
class VectorMLTTileData : public GeometryTileData {
|
||||
public:
|
||||
VectorMLTTileData(std::shared_ptr<const std::string> data);
|
||||
VectorMLTTileData(const VectorMLTTileData&);
|
||||
VectorMLTTileData(VectorMLTTileData&&) = default;
|
||||
|
||||
std::unique_ptr<GeometryTileData> clone() const override;
|
||||
std::unique_ptr<GeometryTileLayer> getLayer(const std::string& name) const override;
|
||||
|
||||
std::vector<std::string> layerNames() const;
|
||||
|
||||
private:
|
||||
mutable std::shared_ptr<const std::string> data;
|
||||
mutable std::shared_ptr<const MapLibreTile> tile;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
24
src/mbgl/tile/vector_mvt_tile.cpp
Normal file
24
src/mbgl/tile/vector_mvt_tile.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#include <mbgl/tile/vector_mvt_tile.hpp>
|
||||
|
||||
#include <mbgl/renderer/tile_parameters.hpp>
|
||||
#include <mbgl/tile/tile_loader_impl.hpp>
|
||||
#include <mbgl/tile/vector_mvt_tile_data.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
VectorMVTTile::VectorMVTTile(const OverscaledTileID& id_,
|
||||
std::string sourceID_,
|
||||
const TileParameters& parameters_,
|
||||
const Tileset& tileset_,
|
||||
TileObserver* observer_)
|
||||
: VectorTile(id_, std::move(sourceID_), parameters_, tileset_, observer_) {}
|
||||
|
||||
void VectorMVTTile::setData(const std::shared_ptr<const std::string>& data_) {
|
||||
if (!obsolete) {
|
||||
GeometryTile::setData(data_ ? std::make_unique<VectorMVTTileData>(data_) : nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
23
src/mbgl/tile/vector_mvt_tile.hpp
Normal file
23
src/mbgl/tile/vector_mvt_tile.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/tile_loader.hpp>
|
||||
#include <mbgl/tile/vector_tile.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class Tileset;
|
||||
class TileParameters;
|
||||
|
||||
class VectorMVTTile : public VectorTile {
|
||||
public:
|
||||
VectorMVTTile(const OverscaledTileID&,
|
||||
std::string sourceID,
|
||||
const TileParameters&,
|
||||
const Tileset&,
|
||||
TileObserver* observer = nullptr);
|
||||
|
||||
void setData(const std::shared_ptr<const std::string>& data) override;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
@@ -1,14 +1,19 @@
|
||||
#include <mbgl/tile/vector_tile_data.hpp>
|
||||
#include <mbgl/tile/vector_mvt_tile_data.hpp>
|
||||
|
||||
#include <mbgl/util/constants.hpp>
|
||||
#include <mbgl/util/instrumentation.hpp>
|
||||
#include <mbgl/util/logging.hpp>
|
||||
|
||||
#if ANDROID
|
||||
#include <mlt/decoder.hpp>
|
||||
#endif
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
VectorTileFeature::VectorTileFeature(const mapbox::vector_tile::layer& layer, const protozero::data_view& view)
|
||||
VectorMVTTileFeature::VectorMVTTileFeature(const mapbox::vector_tile::layer& layer, const protozero::data_view& view)
|
||||
: feature(view, layer) {}
|
||||
|
||||
FeatureType VectorTileFeature::getType() const {
|
||||
FeatureType VectorMVTTileFeature::getType() const {
|
||||
switch (feature.getType()) {
|
||||
case mapbox::vector_tile::GeomType::POINT:
|
||||
return FeatureType::Point;
|
||||
@@ -21,23 +26,23 @@ FeatureType VectorTileFeature::getType() const {
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<Value> VectorTileFeature::getValue(const std::string& key) const {
|
||||
const std::optional<Value> value(feature.getValue(key));
|
||||
return value->is<NullValue>() ? std::nullopt : value;
|
||||
std::optional<Value> VectorMVTTileFeature::getValue(const std::string& key) const {
|
||||
const auto value = feature.getValue(key);
|
||||
return value.is<NullValue>() ? std::nullopt : std::optional<Value>{std::move(value)};
|
||||
}
|
||||
|
||||
const PropertyMap& VectorTileFeature::getProperties() const {
|
||||
const PropertyMap& VectorMVTTileFeature::getProperties() const {
|
||||
if (!properties) {
|
||||
properties = feature.getProperties();
|
||||
}
|
||||
return *properties;
|
||||
}
|
||||
|
||||
FeatureIdentifier VectorTileFeature::getID() const {
|
||||
FeatureIdentifier VectorMVTTileFeature::getID() const {
|
||||
return feature.getID();
|
||||
}
|
||||
|
||||
const GeometryCollection& VectorTileFeature::getGeometries() const {
|
||||
const GeometryCollection& VectorMVTTileFeature::getGeometries() const {
|
||||
MLN_TRACE_FUNC();
|
||||
|
||||
if (!lines) {
|
||||
@@ -57,30 +62,30 @@ const GeometryCollection& VectorTileFeature::getGeometries() const {
|
||||
return *lines;
|
||||
}
|
||||
|
||||
VectorTileLayer::VectorTileLayer(std::shared_ptr<const std::string> data_, const protozero::data_view& view)
|
||||
VectorMVTTileLayer::VectorMVTTileLayer(std::shared_ptr<const std::string> data_, const protozero::data_view& view)
|
||||
: data(std::move(data_)),
|
||||
layer(view) {}
|
||||
|
||||
std::size_t VectorTileLayer::featureCount() const {
|
||||
std::size_t VectorMVTTileLayer::featureCount() const {
|
||||
return layer.featureCount();
|
||||
}
|
||||
|
||||
std::unique_ptr<GeometryTileFeature> VectorTileLayer::getFeature(std::size_t i) const {
|
||||
return std::make_unique<VectorTileFeature>(layer, layer.getFeature(i));
|
||||
std::unique_ptr<GeometryTileFeature> VectorMVTTileLayer::getFeature(std::size_t i) const {
|
||||
return std::make_unique<VectorMVTTileFeature>(layer, layer.getFeature(i));
|
||||
}
|
||||
|
||||
std::string VectorTileLayer::getName() const {
|
||||
std::string VectorMVTTileLayer::getName() const {
|
||||
return layer.getName();
|
||||
}
|
||||
|
||||
VectorTileData::VectorTileData(std::shared_ptr<const std::string> data_)
|
||||
VectorMVTTileData::VectorMVTTileData(std::shared_ptr<const std::string> data_)
|
||||
: data(std::move(data_)) {}
|
||||
|
||||
std::unique_ptr<GeometryTileData> VectorTileData::clone() const {
|
||||
return std::make_unique<VectorTileData>(data);
|
||||
std::unique_ptr<GeometryTileData> VectorMVTTileData::clone() const {
|
||||
return std::make_unique<VectorMVTTileData>(data);
|
||||
}
|
||||
|
||||
std::unique_ptr<GeometryTileLayer> VectorTileData::getLayer(const std::string& name) const {
|
||||
std::unique_ptr<GeometryTileLayer> VectorMVTTileData::getLayer(const std::string& name) const {
|
||||
MLN_TRACE_FUNC();
|
||||
|
||||
if (!parsed) {
|
||||
@@ -93,12 +98,12 @@ std::unique_ptr<GeometryTileLayer> VectorTileData::getLayer(const std::string& n
|
||||
|
||||
auto it = layers.find(name);
|
||||
if (it != layers.end()) {
|
||||
return std::make_unique<VectorTileLayer>(data, it->second);
|
||||
return std::make_unique<VectorMVTTileLayer>(data, it->second);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<std::string> VectorTileData::layerNames() const {
|
||||
std::vector<std::string> VectorMVTTileData::layerNames() const {
|
||||
return mapbox::vector_tile::buffer(*data).layerNames();
|
||||
}
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class VectorTileFeature : public GeometryTileFeature {
|
||||
class VectorMVTTileFeature : public GeometryTileFeature {
|
||||
public:
|
||||
VectorTileFeature(const mapbox::vector_tile::layer&, const protozero::data_view&);
|
||||
VectorMVTTileFeature(const mapbox::vector_tile::layer&, const protozero::data_view&);
|
||||
|
||||
FeatureType getType() const override;
|
||||
std::optional<Value> getValue(const std::string& key) const override;
|
||||
@@ -36,9 +36,9 @@ private:
|
||||
mutable std::optional<PropertyMap> properties;
|
||||
};
|
||||
|
||||
class VectorTileLayer : public GeometryTileLayer {
|
||||
class VectorMVTTileLayer : public GeometryTileLayer {
|
||||
public:
|
||||
VectorTileLayer(std::shared_ptr<const std::string> data, const protozero::data_view&);
|
||||
VectorMVTTileLayer(std::shared_ptr<const std::string> data, const protozero::data_view&);
|
||||
|
||||
std::size_t featureCount() const override;
|
||||
std::unique_ptr<GeometryTileFeature> getFeature(std::size_t i) const override;
|
||||
@@ -49,9 +49,9 @@ private:
|
||||
mapbox::vector_tile::layer layer;
|
||||
};
|
||||
|
||||
class VectorTileData : public GeometryTileData {
|
||||
class VectorMVTTileData : public GeometryTileData {
|
||||
public:
|
||||
VectorTileData(std::shared_ptr<const std::string> data);
|
||||
VectorMVTTileData(std::shared_ptr<const std::string> data);
|
||||
|
||||
std::unique_ptr<GeometryTileData> clone() const override;
|
||||
std::unique_ptr<GeometryTileLayer> getLayer(const std::string& name) const override;
|
||||
@@ -1,18 +1,19 @@
|
||||
#include <mbgl/tile/vector_mvt_tile.hpp>
|
||||
|
||||
#include <mbgl/renderer/tile_parameters.hpp>
|
||||
#include <mbgl/tile/tile_loader_impl.hpp>
|
||||
#include <mbgl/tile/vector_tile.hpp>
|
||||
#include <mbgl/tile/vector_tile_data.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
VectorTile::VectorTile(const OverscaledTileID& id_,
|
||||
std::string sourceID_,
|
||||
const TileParameters& parameters,
|
||||
const TileParameters& parameters_,
|
||||
const Tileset& tileset,
|
||||
TileObserver* observer_)
|
||||
: GeometryTile(id_, std::move(sourceID_), parameters, observer_),
|
||||
loader(*this, id_, parameters, tileset) {}
|
||||
: GeometryTile(id_, std::move(sourceID_), parameters_, observer_),
|
||||
loader(*this, id_, parameters_, tileset) {}
|
||||
|
||||
VectorTile::~VectorTile() {
|
||||
// Don't rely on `~TileLoader` to close, it's not safe to call there.
|
||||
@@ -33,12 +34,4 @@ void VectorTile::setMetadata(std::optional<Timestamp> modified_, std::optional<T
|
||||
expires = std::move(expires_);
|
||||
}
|
||||
|
||||
void VectorTile::setData(const std::shared_ptr<const std::string>& data_) {
|
||||
if (obsolete) {
|
||||
return;
|
||||
}
|
||||
|
||||
GeometryTile::setData(data_ ? std::make_unique<VectorTileData>(data_) : nullptr);
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -20,7 +20,8 @@ public:
|
||||
void setNecessity(TileNecessity) final;
|
||||
void setUpdateParameters(const TileUpdateParameters&) final;
|
||||
void setMetadata(std::optional<Timestamp> modified, std::optional<Timestamp> expires);
|
||||
void setData(const std::shared_ptr<const std::string>& data);
|
||||
|
||||
virtual void setData(const std::shared_ptr<const std::string>&) = 0;
|
||||
|
||||
private:
|
||||
TileLoader<VectorTile> loader;
|
||||
|
||||
@@ -52,7 +52,7 @@ add_library(
|
||||
${PROJECT_SOURCE_DIR}/test/style/conversion/light.test.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/style/conversion/padding.test.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/style/conversion/property_value.test.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/style/conversion/raster_dem_options.test.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/style/conversion/source_options.test.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/style/conversion/stringify.test.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/style/conversion/tileset.test.cpp
|
||||
${PROJECT_SOURCE_DIR}/test/style/expression/dependency.test.cpp
|
||||
|
||||
@@ -17,7 +17,7 @@ auto fakeImage = [](Size s) {
|
||||
|
||||
TEST(DEMData, ConstructorMapbox) {
|
||||
PremultipliedImage image = fakeImage({16, 16});
|
||||
DEMData demdata(image, Tileset::DEMEncoding::Mapbox);
|
||||
DEMData demdata(image, Tileset::RasterEncoding::Mapbox);
|
||||
|
||||
EXPECT_EQ(demdata.dim, 16);
|
||||
EXPECT_EQ(demdata.stride, 18);
|
||||
@@ -26,7 +26,7 @@ TEST(DEMData, ConstructorMapbox) {
|
||||
|
||||
TEST(DEMData, ConstructorTerrarium) {
|
||||
PremultipliedImage image = fakeImage({16, 16});
|
||||
DEMData demdata(image, Tileset::DEMEncoding::Terrarium);
|
||||
DEMData demdata(image, Tileset::RasterEncoding::Terrarium);
|
||||
|
||||
EXPECT_EQ(demdata.dim, 16);
|
||||
EXPECT_EQ(demdata.stride, 18);
|
||||
@@ -35,7 +35,7 @@ TEST(DEMData, ConstructorTerrarium) {
|
||||
|
||||
TEST(DEMData, InitialBackfill) {
|
||||
PremultipliedImage image1 = fakeImage({4, 4});
|
||||
DEMData dem1(image1, Tileset::DEMEncoding::Mapbox);
|
||||
DEMData dem1(image1, Tileset::RasterEncoding::Mapbox);
|
||||
|
||||
bool nonempty = true;
|
||||
// checking that a 1 px border around the fake image has been populated
|
||||
@@ -89,10 +89,10 @@ TEST(DEMData, InitialBackfill) {
|
||||
|
||||
TEST(DEMData, BackfillNeighbor) {
|
||||
PremultipliedImage image1 = fakeImage({4, 4});
|
||||
DEMData dem0(image1, Tileset::DEMEncoding::Mapbox);
|
||||
DEMData dem0(image1, Tileset::RasterEncoding::Mapbox);
|
||||
|
||||
PremultipliedImage image2 = fakeImage({4, 4});
|
||||
DEMData dem1(image2, Tileset::DEMEncoding::Mapbox);
|
||||
DEMData dem1(image2, Tileset::RasterEncoding::Mapbox);
|
||||
|
||||
dem0.backfillBorder(dem1, -1, 0);
|
||||
for (int y = 0; y < 4; y++) {
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
#include <mbgl/test/util.hpp>
|
||||
|
||||
#include <mbgl/style/conversion/json.hpp>
|
||||
#include <mbgl/style/conversion/raster_dem_options.hpp>
|
||||
#include <mbgl/util/tileset.hpp>
|
||||
|
||||
#include <mbgl/util/logging.hpp>
|
||||
|
||||
using namespace mbgl;
|
||||
using namespace mbgl::style;
|
||||
using namespace mbgl::style::conversion;
|
||||
|
||||
TEST(RasterDEMOptions, Basic) {
|
||||
Error error;
|
||||
std::optional<RasterDEMOptions> converted = convertJSON<RasterDEMOptions>("{}", error);
|
||||
ASSERT_TRUE((bool)converted);
|
||||
}
|
||||
|
||||
TEST(RasterDEMOptions, ErrorHandling) {
|
||||
Error error;
|
||||
std::optional<RasterDEMOptions> converted = convertJSON<RasterDEMOptions>(
|
||||
R"JSON({
|
||||
"encoding": "this isn't a valid encoding"
|
||||
})JSON",
|
||||
error);
|
||||
ASSERT_FALSE(converted);
|
||||
ASSERT_EQ(error.message, "invalid raster-dem encoding type - valid types are 'mapbox' and 'terrarium'");
|
||||
}
|
||||
|
||||
TEST(RasterDEMOptions, TerrariumEncodingParsed) {
|
||||
Error error;
|
||||
std::optional<RasterDEMOptions> converted = convertJSON<RasterDEMOptions>(
|
||||
R"JSON({
|
||||
"encoding": "terrarium"
|
||||
})JSON",
|
||||
error);
|
||||
ASSERT_EQ(converted.value().encoding, Tileset::DEMEncoding::Terrarium);
|
||||
}
|
||||
|
||||
TEST(RasterDEMOptions, MapboxEncodingParsed) {
|
||||
Error error;
|
||||
std::optional<RasterDEMOptions> converted = convertJSON<RasterDEMOptions>(
|
||||
R"JSON({
|
||||
"encoding": "mapbox"
|
||||
})JSON",
|
||||
error);
|
||||
ASSERT_EQ(converted.value().encoding, Tileset::DEMEncoding::Mapbox);
|
||||
}
|
||||
72
test/style/conversion/source_options.test.cpp
Normal file
72
test/style/conversion/source_options.test.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
#include <mbgl/test/util.hpp>
|
||||
|
||||
#include <mbgl/style/conversion/json.hpp>
|
||||
#include <mbgl/style/conversion/source_options.hpp>
|
||||
#include <mbgl/util/tileset.hpp>
|
||||
|
||||
#include <mbgl/util/logging.hpp>
|
||||
|
||||
using namespace mbgl;
|
||||
using namespace mbgl::style;
|
||||
using namespace mbgl::style::conversion;
|
||||
|
||||
TEST(SourceOptions, Basic) {
|
||||
Error error;
|
||||
auto converted = convertJSON<SourceOptions>("{}", error);
|
||||
ASSERT_FALSE(converted);
|
||||
}
|
||||
|
||||
TEST(SourceOptions, ErrorHandling) {
|
||||
Error error;
|
||||
auto converted = convertJSON<SourceOptions>(
|
||||
R"JSON({
|
||||
"encoding": "this isn't a valid encoding"
|
||||
})JSON",
|
||||
error);
|
||||
ASSERT_FALSE(converted);
|
||||
ASSERT_EQ(0, error.message.find("invalid encoding"));
|
||||
}
|
||||
|
||||
TEST(SourceOptions, TerrariumEncodingParsed) {
|
||||
Error error;
|
||||
auto converted = convertJSON<SourceOptions>(
|
||||
R"JSON({
|
||||
"encoding": "terrarium"
|
||||
})JSON",
|
||||
error);
|
||||
ASSERT_EQ(converted.value().rasterEncoding, Tileset::RasterEncoding::Terrarium);
|
||||
ASSERT_FALSE(converted.value().vectorEncoding);
|
||||
}
|
||||
|
||||
TEST(SourceOptions, MapboxEncodingParsed) {
|
||||
Error error;
|
||||
auto converted = convertJSON<SourceOptions>(
|
||||
R"JSON({
|
||||
"encoding": "mapbox"
|
||||
})JSON",
|
||||
error);
|
||||
ASSERT_EQ(converted.value().rasterEncoding, Tileset::RasterEncoding::Mapbox);
|
||||
ASSERT_FALSE(converted.value().vectorEncoding);
|
||||
}
|
||||
|
||||
TEST(SourceOptions, MVTEncodingParsed) {
|
||||
Error error;
|
||||
auto converted = convertJSON<SourceOptions>(
|
||||
R"JSON({
|
||||
"encoding": "mvt"
|
||||
})JSON",
|
||||
error);
|
||||
ASSERT_EQ(converted.value().vectorEncoding, Tileset::VectorEncoding::Mapbox);
|
||||
ASSERT_FALSE(converted.value().rasterEncoding);
|
||||
}
|
||||
|
||||
TEST(SourceOptions, MLTEncodingParsed) {
|
||||
Error error;
|
||||
auto converted = convertJSON<SourceOptions>(
|
||||
R"JSON({
|
||||
"encoding": "mlt"
|
||||
})JSON",
|
||||
error);
|
||||
ASSERT_EQ(converted.value().vectorEncoding, Tileset::VectorEncoding::MLT);
|
||||
ASSERT_FALSE(converted.value().rasterEncoding);
|
||||
}
|
||||
@@ -66,7 +66,7 @@ TEST(RasterDEMTile, onError) {
|
||||
TEST(RasterDEMTile, onParsed) {
|
||||
RasterDEMTileTest test;
|
||||
RasterDEMTile tile(OverscaledTileID(0, 0, 0), "testSource", test.tileParameters, test.tileset);
|
||||
tile.onParsed(std::make_unique<HillshadeBucket>(PremultipliedImage({16, 16}), Tileset::DEMEncoding::Mapbox), 0);
|
||||
tile.onParsed(std::make_unique<HillshadeBucket>(PremultipliedImage({16, 16}), Tileset::RasterEncoding::Mapbox), 0);
|
||||
EXPECT_TRUE(tile.isRenderable());
|
||||
EXPECT_TRUE(tile.isLoaded());
|
||||
EXPECT_TRUE(tile.isComplete());
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <mbgl/test/fake_file_source.hpp>
|
||||
#include <mbgl/tile/tile_loader_impl.hpp>
|
||||
#include <mbgl/tile/vector_tile.hpp>
|
||||
#include <mbgl/tile/vector_tile_data.hpp>
|
||||
#include <mbgl/tile/vector_mvt_tile_data.hpp>
|
||||
|
||||
#include <mbgl/actor/scheduler.hpp>
|
||||
#include <mbgl/annotation/annotation_manager.hpp>
|
||||
@@ -38,6 +38,8 @@ public:
|
||||
renderable = true;
|
||||
}
|
||||
|
||||
void setData(const std::shared_ptr<const std::string>&) override {}
|
||||
|
||||
util::SimpleIdentity uniqueId;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <mbgl/test/util.hpp>
|
||||
#include <mbgl/test/fake_file_source.hpp>
|
||||
#include <mbgl/tile/vector_tile.hpp>
|
||||
#include <mbgl/tile/vector_tile_data.hpp>
|
||||
#include <mbgl/tile/vector_mvt_tile.hpp>
|
||||
#include <mbgl/tile/vector_mvt_tile_data.hpp>
|
||||
#include <mbgl/tile/tile_loader_impl.hpp>
|
||||
#include <mbgl/storage/resource_options.hpp>
|
||||
|
||||
@@ -25,7 +25,7 @@ using namespace mbgl;
|
||||
|
||||
TEST(VectorTile, setError) {
|
||||
VectorTileTest test;
|
||||
VectorTile tile(OverscaledTileID(0, 0, 0), "source", test.tileParameters, test.tileset);
|
||||
VectorMVTTile tile(OverscaledTileID(0, 0, 0), "source", test.tileParameters, test.tileset);
|
||||
tile.setError(std::make_exception_ptr(std::runtime_error("test")));
|
||||
EXPECT_FALSE(tile.isRenderable());
|
||||
EXPECT_TRUE(tile.isLoaded());
|
||||
@@ -34,7 +34,7 @@ TEST(VectorTile, setError) {
|
||||
|
||||
TEST(VectorTile, onError) {
|
||||
VectorTileTest test;
|
||||
VectorTile tile(OverscaledTileID(0, 0, 0), "source", test.tileParameters, test.tileset);
|
||||
VectorMVTTile tile(OverscaledTileID(0, 0, 0), "source", test.tileParameters, test.tileset);
|
||||
tile.onError(std::make_exception_ptr(std::runtime_error("test")), 0);
|
||||
|
||||
EXPECT_FALSE(tile.isRenderable());
|
||||
@@ -44,7 +44,7 @@ TEST(VectorTile, onError) {
|
||||
|
||||
TEST(VectorTile, Issue8542) {
|
||||
VectorTileTest test;
|
||||
VectorTile tile(OverscaledTileID(0, 0, 0), "source", test.tileParameters, test.tileset);
|
||||
VectorMVTTile tile(OverscaledTileID(0, 0, 0), "source", test.tileParameters, test.tileset);
|
||||
|
||||
// Query before data is set
|
||||
std::vector<Feature> result;
|
||||
@@ -52,7 +52,7 @@ TEST(VectorTile, Issue8542) {
|
||||
}
|
||||
|
||||
TEST(VectorTileData, ParseResults) {
|
||||
VectorTileData data(std::make_shared<std::string>(util::read_file("test/fixtures/map/issue12432/0-0-0.mvt")));
|
||||
VectorMVTTileData data(std::make_shared<std::string>(util::read_file("test/fixtures/map/issue12432/0-0-0.mvt")));
|
||||
|
||||
std::vector<std::string> layerNames = data.layerNames();
|
||||
ASSERT_EQ(layerNames.size(), 2u);
|
||||
|
||||
2
vendor/PMTiles
vendored
2
vendor/PMTiles
vendored
Submodule vendor/PMTiles updated: 60f3331ca9...e232df5574
2
vendor/glslang
vendored
2
vendor/glslang
vendored
Submodule vendor/glslang updated: 8a85691a07...a92c61f845
1
vendor/maplibre-tile-spec
vendored
Submodule
1
vendor/maplibre-tile-spec
vendored
Submodule
Submodule vendor/maplibre-tile-spec added at 7e3cfe2251
15
vendor/maplibre-tile-spec.cmake
vendored
Normal file
15
vendor/maplibre-tile-spec.cmake
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
set(MLT_WITH_JSON OFF CACHE BOOL "No JSON support" FORCE)
|
||||
set(MLT_WITH_PROTOZERO OFF CACHE BOOL "No protozero" FORCE)
|
||||
set(MLT_WITH_FASTPFOR OFF CACHE BOOL "disabled for lack of support for ARMv7 in SIMDE and requirement for SSE on x86" FORCE)
|
||||
set(MLT_WITH_TESTS OFF CACHE BOOL "Google Test conflicts with Dawn")
|
||||
set(MLT_WITH_TOOLS OFF CACHE BOOL "Not used")
|
||||
|
||||
# This is set by the platform CMakeLists.txt after vendor libraries. If it was set earlier, we could just use it.
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 14.3)
|
||||
set(MLT_OSX_DEPLOYMENT_TARGET ${CMAKE_OSX_DEPLOYMENT_TARGET} CACHE STRING "Inherited MacOS/iOS target" FORCE)
|
||||
|
||||
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.25")
|
||||
add_subdirectory(${PROJECT_SOURCE_DIR}/vendor/maplibre-tile-spec/cpp SYSTEM)
|
||||
else()
|
||||
add_subdirectory(${PROJECT_SOURCE_DIR}/vendor/maplibre-tile-spec/cpp)
|
||||
endif()
|
||||
Reference in New Issue
Block a user