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"]
|
[submodule "vendor/filesystem"]
|
||||||
path = vendor/filesystem
|
path = vendor/filesystem
|
||||||
url = https://github.com/gulrak/filesystem.git
|
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"]
|
[submodule "vendor/kdbush.hpp"]
|
||||||
path = vendor/kdbush.hpp
|
path = vendor/kdbush.hpp
|
||||||
url = https://github.com/mourner/kdbush.hpp.git
|
url = https://github.com/mourner/kdbush.hpp.git
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ cc_library(
|
|||||||
"//vendor:eternal",
|
"//vendor:eternal",
|
||||||
"//vendor:expected-lite",
|
"//vendor:expected-lite",
|
||||||
"//vendor:maplibre-native-base",
|
"//vendor:maplibre-native-base",
|
||||||
|
"//vendor/maplibre-tile-spec/cpp:mlt_cpp",
|
||||||
"//vendor:parsedate",
|
"//vendor:parsedate",
|
||||||
"//vendor:pmtiles",
|
"//vendor:pmtiles",
|
||||||
"//vendor:polylabel",
|
"//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/light.hpp
|
||||||
${PROJECT_SOURCE_DIR}/include/mbgl/style/conversion/position.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/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/rotation.hpp
|
||||||
${PROJECT_SOURCE_DIR}/include/mbgl/style/conversion/source.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/tileset.hpp
|
||||||
${PROJECT_SOURCE_DIR}/include/mbgl/style/conversion/transition_options.hpp
|
${PROJECT_SOURCE_DIR}/include/mbgl/style/conversion/transition_options.hpp
|
||||||
${PROJECT_SOURCE_DIR}/include/mbgl/style/expression/assertion.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/light.cpp
|
||||||
${PROJECT_SOURCE_DIR}/src/mbgl/style/conversion/position.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/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/rotation.cpp
|
||||||
${PROJECT_SOURCE_DIR}/src/mbgl/style/conversion/source.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/stringify.hpp
|
||||||
${PROJECT_SOURCE_DIR}/src/mbgl/style/conversion/tileset.cpp
|
${PROJECT_SOURCE_DIR}/src/mbgl/style/conversion/tileset.cpp
|
||||||
${PROJECT_SOURCE_DIR}/src/mbgl/style/conversion/transition_options.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/tile_operation.cpp
|
||||||
${PROJECT_SOURCE_DIR}/src/mbgl/tile/vector_tile.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.hpp
|
||||||
${PROJECT_SOURCE_DIR}/src/mbgl/tile/vector_tile_data.cpp
|
${PROJECT_SOURCE_DIR}/src/mbgl/tile/vector_mlt_tile.cpp
|
||||||
${PROJECT_SOURCE_DIR}/src/mbgl/tile/vector_tile_data.hpp
|
${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.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/action_journal_impl.cpp
|
||||||
${PROJECT_SOURCE_DIR}/src/mbgl/util/camera.cpp
|
${PROJECT_SOURCE_DIR}/src/mbgl/util/camera.cpp
|
||||||
${PROJECT_SOURCE_DIR}/src/mbgl/util/bounding_volumes.hpp
|
${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/vector-tile.cmake)
|
||||||
include(${PROJECT_SOURCE_DIR}/vendor/wagyu.cmake)
|
include(${PROJECT_SOURCE_DIR}/vendor/wagyu.cmake)
|
||||||
include(${PROJECT_SOURCE_DIR}/vendor/metal-cpp.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/supercluster.cmake)
|
||||||
include(${PROJECT_SOURCE_DIR}/vendor/expected-lite.cmake)
|
include(${PROJECT_SOURCE_DIR}/vendor/expected-lite.cmake)
|
||||||
include(${PROJECT_SOURCE_DIR}/vendor/kdbush.cmake)
|
include(${PROJECT_SOURCE_DIR}/vendor/kdbush.cmake)
|
||||||
@@ -1581,6 +1587,7 @@ target_link_libraries(
|
|||||||
mbgl-vendor-unique_resource
|
mbgl-vendor-unique_resource
|
||||||
mbgl-vendor-vector-tile
|
mbgl-vendor-vector-tile
|
||||||
mbgl-vendor-wagyu
|
mbgl-vendor-wagyu
|
||||||
|
mlt-cpp
|
||||||
$<$<BOOL:${MLN_WITH_METAL}>:mbgl-vendor-metal-cpp>
|
$<$<BOOL:${MLN_WITH_METAL}>:mbgl-vendor-metal-cpp>
|
||||||
$<IF:$<BOOL:${MLN_USE_RUST}>,mbgl-rustutils,mbgl-vendor-csscolorparser>
|
$<IF:$<BOOL:${MLN_USE_RUST}>,mbgl-rustutils,mbgl-vendor-csscolorparser>
|
||||||
$<$<BOOL:${MLN_TEXT_SHAPING_HARFBUZZ}>:mbgl-freetype>
|
$<$<BOOL:${MLN_TEXT_SHAPING_HARFBUZZ}>:mbgl-freetype>
|
||||||
@@ -1614,6 +1621,8 @@ set(EXPORT_TARGETS
|
|||||||
mbgl-vendor-boost
|
mbgl-vendor-boost
|
||||||
mbgl-vendor-earcut.hpp
|
mbgl-vendor-earcut.hpp
|
||||||
mbgl-vendor-eternal
|
mbgl-vendor-eternal
|
||||||
|
mbgl-vendor-filesystem
|
||||||
|
mbgl-vendor-metal-cpp
|
||||||
mbgl-vendor-rapidjson
|
mbgl-vendor-rapidjson
|
||||||
mbgl-vendor-parsedate
|
mbgl-vendor-parsedate
|
||||||
mbgl-vendor-pmtiles
|
mbgl-vendor-pmtiles
|
||||||
@@ -1622,8 +1631,7 @@ set(EXPORT_TARGETS
|
|||||||
mbgl-vendor-unique_resource
|
mbgl-vendor-unique_resource
|
||||||
mbgl-vendor-vector-tile
|
mbgl-vendor-vector-tile
|
||||||
mbgl-vendor-wagyu
|
mbgl-vendor-wagyu
|
||||||
mbgl-vendor-metal-cpp
|
mlt-cpp
|
||||||
mbgl-vendor-filesystem
|
|
||||||
unordered_dense
|
unordered_dense
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -336,9 +336,9 @@ MLN_CORE_SOURCE = [
|
|||||||
"src/mbgl/style/conversion/light.cpp",
|
"src/mbgl/style/conversion/light.cpp",
|
||||||
"src/mbgl/style/conversion/position.cpp",
|
"src/mbgl/style/conversion/position.cpp",
|
||||||
"src/mbgl/style/conversion/property_value.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/rotation.cpp",
|
||||||
"src/mbgl/style/conversion/source.cpp",
|
"src/mbgl/style/conversion/source.cpp",
|
||||||
|
"src/mbgl/style/conversion/source_options.cpp",
|
||||||
"src/mbgl/style/conversion/stringify.hpp",
|
"src/mbgl/style/conversion/stringify.hpp",
|
||||||
"src/mbgl/style/conversion/tileset.cpp",
|
"src/mbgl/style/conversion/tileset.cpp",
|
||||||
"src/mbgl/style/conversion/transition_options.cpp",
|
"src/mbgl/style/conversion/transition_options.cpp",
|
||||||
@@ -514,8 +514,14 @@ MLN_CORE_SOURCE = [
|
|||||||
"src/mbgl/tile/tile_operation.cpp",
|
"src/mbgl/tile/tile_operation.cpp",
|
||||||
"src/mbgl/tile/vector_tile.cpp",
|
"src/mbgl/tile/vector_tile.cpp",
|
||||||
"src/mbgl/tile/vector_tile.hpp",
|
"src/mbgl/tile/vector_tile.hpp",
|
||||||
"src/mbgl/tile/vector_tile_data.cpp",
|
"src/mbgl/tile/vector_mlt_tile.cpp",
|
||||||
"src/mbgl/tile/vector_tile_data.hpp",
|
"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.cpp",
|
||||||
"src/mbgl/util/action_journal_impl.hpp",
|
"src/mbgl/util/action_journal_impl.hpp",
|
||||||
"src/mbgl/util/action_journal_impl.cpp",
|
"src/mbgl/util/action_journal_impl.cpp",
|
||||||
@@ -696,9 +702,9 @@ MLN_CORE_HEADERS = [
|
|||||||
"include/mbgl/style/conversion/light.hpp",
|
"include/mbgl/style/conversion/light.hpp",
|
||||||
"include/mbgl/style/conversion/position.hpp",
|
"include/mbgl/style/conversion/position.hpp",
|
||||||
"include/mbgl/style/conversion/property_value.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/rotation.hpp",
|
||||||
"include/mbgl/style/conversion/source.hpp",
|
"include/mbgl/style/conversion/source.hpp",
|
||||||
|
"include/mbgl/style/conversion/source_options.hpp",
|
||||||
"include/mbgl/style/conversion/tileset.hpp",
|
"include/mbgl/style/conversion/tileset.hpp",
|
||||||
"include/mbgl/style/conversion/transition_options.hpp",
|
"include/mbgl/style/conversion/transition_options.hpp",
|
||||||
"include/mbgl/style/conversion_impl.hpp",
|
"include/mbgl/style/conversion_impl.hpp",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include <benchmark/benchmark.h>
|
#include <benchmark/benchmark.h>
|
||||||
|
|
||||||
#include <mbgl/tile/vector_tile_data.hpp>
|
#include <mbgl/tile/vector_mvt_tile_data.hpp>
|
||||||
#include <mbgl/util/io.hpp>
|
#include <mbgl/util/io.hpp>
|
||||||
|
|
||||||
using namespace mbgl;
|
using namespace mbgl;
|
||||||
@@ -11,7 +11,7 @@ static void Parse_VectorTile(benchmark::State& state) {
|
|||||||
|
|
||||||
while (state.KeepRunning()) {
|
while (state.KeepRunning()) {
|
||||||
std::size_t length = 0;
|
std::size_t length = 0;
|
||||||
VectorTileData tile(data);
|
VectorMVTTileData tile(data);
|
||||||
for (const auto& name : tile.layerNames()) {
|
for (const auto& name : tile.layerNames()) {
|
||||||
if (auto layer = tile.getLayer(name)) {
|
if (auto layer = tile.getLayer(name)) {
|
||||||
const std::size_t count = layer->featureCount();
|
const std::size_t count = layer->featureCount();
|
||||||
|
|||||||
@@ -7,14 +7,13 @@
|
|||||||
#include <args.hxx>
|
#include <args.hxx>
|
||||||
#include <mapbox/io/io.hpp>
|
#include <mapbox/io/io.hpp>
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
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::HelpFlag helpFlag(p, "help", "Display this help menu", {'h'});
|
||||||
|
|
||||||
args::ValueFlag<std::string> urlValue(p, "URL", "Resource URL (required)", {'u'}, args::Options::Required);
|
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}};
|
{"tile", mbgl::Resource::Tile}};
|
||||||
|
|
||||||
std::string typeHelp("One of the following (required):");
|
std::string typeHelp("One of the following (required):");
|
||||||
for (auto key : typeMap) {
|
for (const auto& key : typeMap) {
|
||||||
typeHelp += " " + key.first;
|
typeHelp += " " + key.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,18 +52,18 @@ int main(int argc, char* argv[]) {
|
|||||||
std::cout << p;
|
std::cout << p;
|
||||||
exit(0);
|
exit(0);
|
||||||
} catch (const args::ParseError& e) {
|
} catch (const args::ParseError& e) {
|
||||||
std::cerr << e.what() << std::endl;
|
std::cerr << e.what() << '\n';
|
||||||
std::cerr << p;
|
std::cerr << p;
|
||||||
exit(1);
|
exit(1);
|
||||||
} catch (const args::ValidationError& e) {
|
} catch (const args::ValidationError& e) {
|
||||||
std::cerr << e.what() << std::endl;
|
std::cerr << e.what() << '\n';
|
||||||
std::cerr << p;
|
std::cerr << p;
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto file = mapbox::base::io::readFile(args::get(dataValue));
|
auto file = mapbox::base::io::readFile(args::get(dataValue));
|
||||||
if (!file) {
|
if (!file) {
|
||||||
std::cerr << file.error() << std::endl;
|
std::cerr << file.error() << '\n';
|
||||||
exit(3);
|
exit(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,15 +77,15 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
if (args::get(typeFlag) == mbgl::Resource::Tile) {
|
if (args::get(typeFlag) == mbgl::Resource::Tile) {
|
||||||
if (!xValueFlag || !yValueFlag || !zValueFlag) {
|
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);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
resource.tileData = {{args::get(urlValue),
|
resource.tileData = {{.urlTemplate = args::get(urlValue),
|
||||||
1,
|
.pixelRatio = 1,
|
||||||
args::get(xValueFlag),
|
.x = args::get(xValueFlag),
|
||||||
args::get(yValueFlag),
|
.y = args::get(yValueFlag),
|
||||||
static_cast<int8_t>(args::get(zValueFlag))}};
|
.z = static_cast<int8_t>(args::get(zValueFlag))}};
|
||||||
}
|
}
|
||||||
|
|
||||||
mbgl::util::RunLoop loop;
|
mbgl::util::RunLoop loop;
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ namespace style {
|
|||||||
namespace conversion {
|
namespace conversion {
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct Converter<RasterDEMOptions> {
|
struct Converter<SourceOptions> {
|
||||||
std::optional<RasterDEMOptions> operator()(const Convertible& value, Error& error) const;
|
std::optional<SourceOptions> operator()(const Convertible& value, Error& error) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace conversion
|
} // namespace conversion
|
||||||
@@ -7,8 +7,9 @@
|
|||||||
namespace mbgl {
|
namespace mbgl {
|
||||||
namespace style {
|
namespace style {
|
||||||
|
|
||||||
struct RasterDEMOptions {
|
struct SourceOptions {
|
||||||
std::optional<Tileset::DEMEncoding> encoding = std::nullopt;
|
std::optional<Tileset::RasterEncoding> rasterEncoding = std::nullopt;
|
||||||
|
std::optional<Tileset::VectorEncoding> vectorEncoding = std::nullopt;
|
||||||
};
|
};
|
||||||
|
|
||||||
// NOTE: Any derived class must invalidate `weakFactory` in the destructor
|
// NOTE: Any derived class must invalidate `weakFactory` in the destructor
|
||||||
@@ -17,7 +18,7 @@ public:
|
|||||||
RasterDEMSource(std::string id,
|
RasterDEMSource(std::string id,
|
||||||
variant<std::string, Tileset> urlOrTileset,
|
variant<std::string, Tileset> urlOrTileset,
|
||||||
uint16_t tileSize,
|
uint16_t tileSize,
|
||||||
std::optional<RasterDEMOptions> options = std::nullopt);
|
std::optional<SourceOptions> options = std::nullopt);
|
||||||
~RasterDEMSource() override;
|
~RasterDEMSource() override;
|
||||||
bool supportsLayerType(const mbgl::style::LayerTypeInfo*) const override;
|
bool supportsLayerType(const mbgl::style::LayerTypeInfo*) const override;
|
||||||
|
|
||||||
@@ -25,7 +26,7 @@ protected:
|
|||||||
void setTilesetOverrides(Tileset& tileset) override;
|
void setTilesetOverrides(Tileset& tileset) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::optional<RasterDEMOptions> options;
|
std::optional<SourceOptions> options;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ public:
|
|||||||
VectorSource(std::string id,
|
VectorSource(std::string id,
|
||||||
variant<std::string, Tileset> urlOrTileset,
|
variant<std::string, Tileset> urlOrTileset,
|
||||||
std::optional<float> maxZoom = std::nullopt,
|
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;
|
void setTilesetOverrides(Tileset& tileset) override;
|
||||||
|
|
||||||
@@ -30,11 +31,14 @@ public:
|
|||||||
|
|
||||||
bool supportsLayerType(const mbgl::style::LayerTypeInfo*) const override;
|
bool supportsLayerType(const mbgl::style::LayerTypeInfo*) const override;
|
||||||
|
|
||||||
|
Tileset::VectorEncoding getEncoding() const noexcept { return encoding; }
|
||||||
|
|
||||||
mapbox::base::WeakPtr<Source> makeWeakPtr() override { return weakFactory.makeWeakPtr(); }
|
mapbox::base::WeakPtr<Source> makeWeakPtr() override { return weakFactory.makeWeakPtr(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::optional<float> maxZoom;
|
std::optional<float> maxZoom;
|
||||||
std::optional<float> minZoom;
|
std::optional<float> minZoom;
|
||||||
|
Tileset::VectorEncoding encoding;
|
||||||
mapbox::base::WeakPtrFactory<Source> weakFactory{this}; // Must remain last
|
mapbox::base::WeakPtrFactory<Source> weakFactory{this}; // Must remain last
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -18,38 +18,40 @@ public:
|
|||||||
XYZ,
|
XYZ,
|
||||||
TMS
|
TMS
|
||||||
};
|
};
|
||||||
enum class DEMEncoding : bool {
|
enum class RasterEncoding : std::uint8_t {
|
||||||
Mapbox,
|
Mapbox, // Mapbox DEM
|
||||||
Terrarium
|
Terrarium, // Terrarium DEM
|
||||||
|
};
|
||||||
|
enum class VectorEncoding : std::uint8_t {
|
||||||
|
Mapbox, // Mapbox Vector Tiles (MVT)
|
||||||
|
MLT, // MapLibre Tiles
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<std::string> tiles;
|
std::vector<std::string> tiles;
|
||||||
Range<uint8_t> zoomRange;
|
Range<uint8_t> zoomRange;
|
||||||
std::string attribution;
|
std::string attribution;
|
||||||
Scheme scheme;
|
Scheme scheme;
|
||||||
// DEMEncoding is not supported by the TileJSON spec
|
std::optional<RasterEncoding> rasterEncoding;
|
||||||
DEMEncoding encoding;
|
std::optional<VectorEncoding> vectorEncoding;
|
||||||
std::optional<LatLngBounds> bounds;
|
std::optional<LatLngBounds> bounds;
|
||||||
|
|
||||||
Tileset(std::vector<std::string> tiles_ = std::vector<std::string>(),
|
Tileset(std::vector<std::string> tiles_ = std::vector<std::string>(),
|
||||||
Range<uint8_t> zoomRange_ = {0, util::DEFAULT_MAX_ZOOM},
|
Range<uint8_t> zoomRange_ = {0, util::DEFAULT_MAX_ZOOM},
|
||||||
std::string attribution_ = {},
|
std::string attribution_ = {},
|
||||||
Scheme scheme_ = Scheme::XYZ,
|
Scheme scheme_ = Scheme::XYZ,
|
||||||
DEMEncoding encoding_ = DEMEncoding::Mapbox)
|
std::optional<RasterEncoding> rasterEncoding_ = std::nullopt,
|
||||||
|
std::optional<VectorEncoding> encoding_ = std::nullopt)
|
||||||
: tiles(std::move(tiles_)),
|
: tiles(std::move(tiles_)),
|
||||||
zoomRange(zoomRange_),
|
zoomRange(zoomRange_),
|
||||||
attribution(std::move(attribution_)),
|
attribution(std::move(attribution_)),
|
||||||
scheme(scheme_),
|
scheme(scheme_),
|
||||||
encoding(encoding_) {};
|
rasterEncoding(rasterEncoding_),
|
||||||
|
vectorEncoding(encoding_) {}
|
||||||
|
|
||||||
// TileJSON also includes center and zoom but they are not used by mbgl.
|
// TileJSON also includes center and zoom but they are not used by mbgl.
|
||||||
|
|
||||||
friend bool operator==(const Tileset& lhs, const Tileset& rhs) noexcept {
|
bool operator==(const Tileset&) const = default;
|
||||||
return std::tie(lhs.tiles, lhs.zoomRange, lhs.attribution, lhs.scheme, lhs.bounds) ==
|
bool operator!=(const Tileset&) const = default;
|
||||||
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); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mbgl
|
} // namespace mbgl
|
||||||
|
|||||||
Binary file not shown.
@@ -2,7 +2,13 @@
|
|||||||
"version": 8,
|
"version": 8,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"test": {
|
"test": {
|
||||||
"allowed": 0.003
|
"allowed": 0.003,
|
||||||
|
"source-replace": [
|
||||||
|
{
|
||||||
|
"replace": "maplibre",
|
||||||
|
"with": "mlt"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"center": [
|
"center": [
|
||||||
@@ -19,6 +25,14 @@
|
|||||||
"tiles": [
|
"tiles": [
|
||||||
"local://tiles/extent1024-14-8802-5374.mvt"
|
"local://tiles/extent1024-14-8802-5374.mvt"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"mlt": {
|
||||||
|
"type": "vector",
|
||||||
|
"maxzoom": 14,
|
||||||
|
"tiles": [
|
||||||
|
"local://tiles/extent1024-14-8802-5374.mlt"
|
||||||
|
],
|
||||||
|
"encoding": "mlt"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"layers": [
|
"layers": [
|
||||||
|
|||||||
@@ -1,7 +1,14 @@
|
|||||||
{
|
{
|
||||||
"version": 8,
|
"version": 8,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"test": {}
|
"test": {
|
||||||
|
"source-replace": [
|
||||||
|
{
|
||||||
|
"replace": "maplibre",
|
||||||
|
"with": "mlt"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"zoom": 0.99,
|
"zoom": 0.99,
|
||||||
"center": [
|
"center": [
|
||||||
@@ -15,6 +22,14 @@
|
|||||||
"tiles": [
|
"tiles": [
|
||||||
"local://tiles/{z}-{x}-{y}.mvt"
|
"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",
|
"sprite": "local://sprites/solid-black",
|
||||||
|
|||||||
@@ -2,7 +2,11 @@
|
|||||||
"version": 8,
|
"version": 8,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"test": {
|
"test": {
|
||||||
"height": 256
|
"height": 256,
|
||||||
|
"source-replace": [{
|
||||||
|
"replace": "maplibre",
|
||||||
|
"with": "mlt"
|
||||||
|
}]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"center": [
|
"center": [
|
||||||
@@ -17,6 +21,14 @@
|
|||||||
"tiles": [
|
"tiles": [
|
||||||
"local://tiles/{z}-{x}-{y}.mvt"
|
"local://tiles/{z}-{x}-{y}.mvt"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"mlt": {
|
||||||
|
"type": "vector",
|
||||||
|
"maxzoom": 14,
|
||||||
|
"tiles": [
|
||||||
|
"local://tiles/{z}-{x}-{y}.mlt"
|
||||||
|
],
|
||||||
|
"encoding": "mlt"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sprite": "local://sprites/sprite",
|
"sprite": "local://sprites/sprite",
|
||||||
|
|||||||
@@ -1,5 +1,15 @@
|
|||||||
{
|
{
|
||||||
"version": 8,
|
"version": 8,
|
||||||
|
"metadata": {
|
||||||
|
"test": {
|
||||||
|
"source-replace": [
|
||||||
|
{
|
||||||
|
"replace": "maplibre",
|
||||||
|
"with": "mlt"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
"center": [
|
"center": [
|
||||||
-118.28162,
|
-118.28162,
|
||||||
33.86852
|
33.86852
|
||||||
@@ -14,6 +24,14 @@
|
|||||||
"tiles": [
|
"tiles": [
|
||||||
"local://tiles/mapbox.mapbox-streets-v7/16-11235-26208.mvt"
|
"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",
|
"glyphs": "local://glyphs/{fontstack}/{range}.pbf",
|
||||||
|
|||||||
@@ -1,7 +1,14 @@
|
|||||||
{
|
{
|
||||||
"version": 8,
|
"version": 8,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"test": {}
|
"test": {
|
||||||
|
"source-replace": [
|
||||||
|
{
|
||||||
|
"replace": "maplibre",
|
||||||
|
"with": "mlt"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"zoom": 2,
|
"zoom": 2,
|
||||||
"sources": {
|
"sources": {
|
||||||
@@ -12,6 +19,15 @@
|
|||||||
"tiles": [
|
"tiles": [
|
||||||
"local://tiles/{z}-{x}-{y}.tms.mvt"
|
"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": [
|
"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``.
|
The default value for this option is ``MLNDEMEncoding/MLNDEMEncodingMapbox``.
|
||||||
|
|
||||||
This option cannot be represented in a TileJSON or style JSON file. It is used
|
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.
|
``MLNRasterTileSource`` or ``MLNRasterTileSource`` object.
|
||||||
*/
|
*/
|
||||||
FOUNDATION_EXTERN MLN_EXPORT const MLNTileSourceOption MLNTileSourceOptionDEMEncoding;
|
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
|
``MLNRasterDEMSource`` is a map content source that supplies rasterized
|
||||||
<a href="https://en.wikipedia.org/wiki/Digital_elevation_model">digital elevation model</a>
|
<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>
|
#import <mbgl/style/sources/raster_dem_source.hpp>
|
||||||
|
|
||||||
|
const MLNTileSourceOption MLNTileSourceOptionDEMEncoding = @"MLNTileSourceOptionDEMEncoding";
|
||||||
|
|
||||||
@implementation MLNRasterDEMSource
|
@implementation MLNRasterDEMSource
|
||||||
|
|
||||||
- (std::unique_ptr<mbgl::style::RasterSource>)pendingSourceWithIdentifier:(NSString *)identifier urlOrTileset:(mbgl::variant<std::string, mbgl::Tileset>)urlOrTileset tileSize:(uint16_t)tileSize {
|
- (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
|
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
|
``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
|
the map. The location of and metadata about the tiles are defined either by an
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#import "MLNAttributionInfo_Private.h"
|
#import "MLNAttributionInfo_Private.h"
|
||||||
#import "MLNGeometry_Private.h"
|
#import "MLNGeometry_Private.h"
|
||||||
#import "MLNRasterDEMSource.h"
|
#import "MLNRasterDEMSource.h"
|
||||||
|
#import "MLNVectorTileSource.h"
|
||||||
#import "NSString+MLNAdditions.h"
|
#import "NSString+MLNAdditions.h"
|
||||||
#import "NSValue+MLNAdditions.h"
|
#import "NSValue+MLNAdditions.h"
|
||||||
|
|
||||||
@@ -20,7 +21,6 @@ const MLNTileSourceOption MLNTileSourceOptionCoordinateBounds = @"MLNTileSourceO
|
|||||||
const MLNTileSourceOption MLNTileSourceOptionAttributionHTMLString = @"MLNTileSourceOptionAttributionHTMLString";
|
const MLNTileSourceOption MLNTileSourceOptionAttributionHTMLString = @"MLNTileSourceOptionAttributionHTMLString";
|
||||||
const MLNTileSourceOption MLNTileSourceOptionAttributionInfos = @"MLNTileSourceOptionAttributionInfos";
|
const MLNTileSourceOption MLNTileSourceOptionAttributionInfos = @"MLNTileSourceOptionAttributionInfos";
|
||||||
const MLNTileSourceOption MLNTileSourceOptionTileCoordinateSystem = @"MLNTileSourceOptionTileCoordinateSystem";
|
const MLNTileSourceOption MLNTileSourceOptionTileCoordinateSystem = @"MLNTileSourceOptionTileCoordinateSystem";
|
||||||
const MLNTileSourceOption MLNTileSourceOptionDEMEncoding = @"MLNTileSourceOptionDEMEncoding";
|
|
||||||
|
|
||||||
@implementation MLNTileSource
|
@implementation MLNTileSource
|
||||||
|
|
||||||
@@ -131,19 +131,38 @@ mbgl::Tileset MLNTileSetFromTileURLTemplates(NSArray<NSString *> *tileURLTemplat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NSNumber *demEncodingNumber = options[MLNTileSourceOptionDEMEncoding]) {
|
NSNumber *encodingNumber = options[MLNTileSourceOptionDEMEncoding];
|
||||||
if (![demEncodingNumber isKindOfClass:[NSValue class]]) {
|
if (encodingNumber) {
|
||||||
|
if (![encodingNumber isKindOfClass:[NSValue class]]) {
|
||||||
[NSException raise:NSInvalidArgumentException
|
[NSException raise:NSInvalidArgumentException
|
||||||
format:@"MLNTileSourceOptionDEMEncoding must be set to an NSValue or NSNumber."];
|
format:@"MLNTileSourceOptionDEMEncoding must be set to an NSValue or NSNumber."];
|
||||||
}
|
}
|
||||||
MLNDEMEncoding demEncoding;
|
MLNDEMEncoding encoding;
|
||||||
[demEncodingNumber getValue:&demEncoding];
|
[encodingNumber getValue:&encoding];
|
||||||
switch (demEncoding) {
|
switch (encoding) {
|
||||||
case MLNDEMEncodingMapbox:
|
case MLNDEMEncodingMapbox:
|
||||||
tileSet.encoding = mbgl::Tileset::DEMEncoding::Mapbox;
|
tileSet.rasterEncoding = mbgl::Tileset::RasterEncoding::Mapbox;
|
||||||
break;
|
break;
|
||||||
case MLNDEMEncodingTerrarium:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,33 @@
|
|||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
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
|
``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
|
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/style/sources/vector_source.hpp>
|
||||||
#include <mbgl/renderer/renderer.hpp>
|
#include <mbgl/renderer/renderer.hpp>
|
||||||
|
|
||||||
|
const MLNTileSourceOption MLNVectorTileSourceOptionEncoding = @"MLNVectorTileSourceOptionEncoding";
|
||||||
|
|
||||||
@interface MLNVectorTileSource ()
|
@interface MLNVectorTileSource ()
|
||||||
|
|
||||||
@property (nonatomic, readonly) mbgl::style::VectorSource *rawSource;
|
@property (nonatomic, readonly) mbgl::style::VectorSource *rawSource;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#import <XCTest/XCTest.h>
|
#import <XCTest/XCTest.h>
|
||||||
|
|
||||||
#import <Mapbox.h>
|
#import <Mapbox.h>
|
||||||
|
#import "MLNVectorTileSource.h"
|
||||||
#import "MLNTileSource_Private.h"
|
#import "MLNTileSource_Private.h"
|
||||||
#import "MLNGeometry_Private.h"
|
#import "MLNGeometry_Private.h"
|
||||||
|
|
||||||
@@ -12,9 +13,13 @@
|
|||||||
|
|
||||||
@implementation MLNTileSetTests
|
@implementation MLNTileSetTests
|
||||||
|
|
||||||
- (void)testTileSetFromTileURLTemplates {
|
namespace {
|
||||||
// a tile set that provides an mbgl tile set
|
// a tile set that provides an mbgl tile set
|
||||||
NSArray *tileURLTemplates = @[@"tile.1", @"tile.2", @"tile.3"];
|
NSArray *tileURLTemplates = @[@"tile.1", @"tile.2", @"tile.3"];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)testTileSetFromTileURLTemplates {
|
||||||
mbgl::Tileset tileSet = MLNTileSetFromTileURLTemplates(tileURLTemplates, nil);
|
mbgl::Tileset tileSet = MLNTileSetFromTileURLTemplates(tileURLTemplates, nil);
|
||||||
|
|
||||||
// has the correct URL templates
|
// has the correct URL templates
|
||||||
@@ -120,23 +125,61 @@
|
|||||||
|
|
||||||
// the scheme is reflected by the mbgl tileset
|
// the scheme is reflected by the mbgl tileset
|
||||||
XCTAssertEqual(tileSet.scheme, mbgl::Tileset::Scheme::TMS);
|
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, @{
|
tileSet = MLNTileSetFromTileURLTemplates(tileURLTemplates, @{
|
||||||
MLNTileSourceOptionDEMEncoding: @(MLNDEMEncodingTerrarium),
|
MLNTileSourceOptionDEMEncoding: @(MLNDEMEncodingTerrarium),
|
||||||
});
|
});
|
||||||
|
|
||||||
// the encoding is reflected by the mbgl tileset
|
// 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;
|
MLNDEMEncoding terrarium = MLNDEMEncodingTerrarium;
|
||||||
tileSet = MLNTileSetFromTileURLTemplates(tileURLTemplates, @{
|
tileSet = MLNTileSetFromTileURLTemplates(tileURLTemplates, @{
|
||||||
MLNTileSourceOptionDEMEncoding: [NSValue value:&terrarium withObjCType:@encode(MLNDEMEncoding)],
|
MLNTileSourceOptionDEMEncoding: [NSValue value:&terrarium withObjCType:@encode(MLNDEMEncoding)],
|
||||||
});
|
});
|
||||||
|
|
||||||
// the encoding is reflected by the mbgl tileset
|
// 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 {
|
- (void)testInvalidTileSet {
|
||||||
|
|||||||
@@ -105,6 +105,11 @@ public:
|
|||||||
const auto format_ptr = values.find("format");
|
const auto format_ptr = values.find("format");
|
||||||
const std::string format = (format_ptr == values.end()) ? "png" : format_ptr->second;
|
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")) {
|
if (format != "pbf" && !values.contains("scale")) {
|
||||||
values["scale"] = "1";
|
values["scale"] = "1";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,11 @@ std::string extract_url(const std::string& url) {
|
|||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
// temporary, remove this when it's available in `pmtiles.hpp`
|
||||||
|
namespace pmtiles {
|
||||||
|
const uint8_t TILETYPE_MLT = 0x6;
|
||||||
|
} // namespace pmtiles
|
||||||
|
|
||||||
namespace mbgl {
|
namespace mbgl {
|
||||||
using namespace rapidjson;
|
using namespace rapidjson;
|
||||||
|
|
||||||
@@ -305,6 +310,11 @@ private:
|
|||||||
rapidjson::Value().SetString(std::string(util::PMTILES_PROTOCOL + url), allocator), allocator);
|
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")) {
|
if (!doc.HasMember("bounds")) {
|
||||||
doc.AddMember("bounds", rapidjson::Value(), allocator);
|
doc.AddMember("bounds", rapidjson::Value(), allocator);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,6 +131,57 @@ ArgumentsTuple parseArguments(int argc, char** argv) {
|
|||||||
updateResults,
|
updateResults,
|
||||||
std::move(testFilter)};
|
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
|
||||||
namespace mbgl {
|
namespace mbgl {
|
||||||
|
|
||||||
@@ -200,7 +251,7 @@ int runRenderTests(int argc, char** argv, std::function<void()> testStatus) {
|
|||||||
if (it != ignores.end()) {
|
if (it != ignores.end()) {
|
||||||
metadata.ignoredTest = shouldIgnore = true;
|
metadata.ignoredTest = shouldIgnore = true;
|
||||||
ignoreReason = it->second;
|
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());
|
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 + ")");
|
mbgl::Log::Info(mbgl::Event::General, "* skipped " + id + "(" + ignoreReason + ")");
|
||||||
continue;
|
continue;
|
||||||
@@ -217,6 +268,10 @@ int runRenderTests(int argc, char** argv, std::function<void()> testStatus) {
|
|||||||
bool errored = metadata.metricsErrored || metadata.renderErrored || metadata.labelCutOffFound;
|
bool errored = metadata.metricsErrored || metadata.renderErrored || metadata.labelCutOffFound;
|
||||||
bool passed = !errored && !metadata.metricsFailed && !metadata.renderFailed;
|
bool passed = !errored && !metadata.metricsFailed && !metadata.renderFailed;
|
||||||
|
|
||||||
|
if (passed) {
|
||||||
|
runWithAlternateSources(runner, metadata, errored, passed);
|
||||||
|
}
|
||||||
|
|
||||||
if (shouldIgnore) {
|
if (shouldIgnore) {
|
||||||
if (passed) {
|
if (passed) {
|
||||||
status = "ignored passed";
|
status = "ignored passed";
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
namespace mbgl {
|
namespace mbgl {
|
||||||
|
|
||||||
DEMData::DEMData(const PremultipliedImage& _image, Tileset::DEMEncoding _encoding)
|
DEMData::DEMData(const PremultipliedImage& _image, Tileset::RasterEncoding _encoding)
|
||||||
: dim(_image.size.height),
|
: dim(_image.size.height),
|
||||||
// extra two pixels per row for border backfilling on either edge
|
// extra two pixels per row for border backfilling on either edge
|
||||||
stride(dim + 2),
|
stride(dim + 2),
|
||||||
@@ -99,7 +99,7 @@ const std::array<float, 4>& DEMData::getUnpackVector() const {
|
|||||||
// https://aws.amazon.com/public-datasets/terrain/
|
// https://aws.amazon.com/public-datasets/terrain/
|
||||||
static const std::array<float, 4> unpackTerrarium = {{256.0f, 1.0f, 1.0f / 256.0f, 32768.0f}};
|
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
|
} // namespace mbgl
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace mbgl {
|
|||||||
|
|
||||||
class DEMData {
|
class DEMData {
|
||||||
public:
|
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);
|
void backfillBorder(const DEMData& borderTileData, int8_t dx, int8_t dy);
|
||||||
|
|
||||||
int32_t get(int32_t x, int32_t y) const;
|
int32_t get(int32_t x, int32_t y) const;
|
||||||
@@ -24,7 +24,7 @@ public:
|
|||||||
|
|
||||||
const int32_t dim;
|
const int32_t dim;
|
||||||
const int32_t stride;
|
const int32_t stride;
|
||||||
const Tileset::DEMEncoding encoding;
|
const Tileset::RasterEncoding encoding;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<PremultipliedImage> image;
|
std::shared_ptr<PremultipliedImage> image;
|
||||||
|
|||||||
@@ -54,10 +54,10 @@ std::size_t totalVerticesCheck(const GeometryCollection& polygon) {
|
|||||||
|
|
||||||
void addFillIndices(SegmentVector& fillSegments,
|
void addFillIndices(SegmentVector& fillSegments,
|
||||||
gfx::IndexVector<gfx::Triangles>& fillIndexes,
|
gfx::IndexVector<gfx::Triangles>& fillIndexes,
|
||||||
std::vector<uint32_t>& indices,
|
const std::span<const uint32_t>& indices,
|
||||||
std::size_t startVertices,
|
const std::size_t startVertices,
|
||||||
std::size_t totalVertices) {
|
const std::size_t totalVertices) {
|
||||||
std::size_t nIndices = indices.size();
|
const std::size_t nIndices = indices.size();
|
||||||
assert(nIndices % 3 == 0);
|
assert(nIndices % 3 == 0);
|
||||||
|
|
||||||
if (fillSegments.empty() ||
|
if (fillSegments.empty() ||
|
||||||
@@ -66,10 +66,13 @@ void addFillIndices(SegmentVector& fillSegments,
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto& triangleSegment = fillSegments.back();
|
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);
|
const auto triangleIndex = static_cast<uint16_t>(triangleSegment.vertexLength);
|
||||||
|
|
||||||
for (std::size_t i = 0; i < nIndices; i += 3) {
|
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(
|
fillIndexes.emplace_back(
|
||||||
triangleIndex + indices[i], triangleIndex + indices[i + 1], triangleIndex + indices[i + 2]);
|
triangleIndex + indices[i], triangleIndex + indices[i + 1], triangleIndex + indices[i + 2]);
|
||||||
}
|
}
|
||||||
@@ -78,8 +81,8 @@ void addFillIndices(SegmentVector& fillSegments,
|
|||||||
triangleSegment.indexLength += nIndices;
|
triangleSegment.indexLength += nIndices;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addOutlineIndices(std::size_t base,
|
void addOutlineIndices(const std::size_t base,
|
||||||
std::size_t nVertices,
|
const std::size_t nVertices,
|
||||||
SegmentVector& lineSegments,
|
SegmentVector& lineSegments,
|
||||||
gfx::IndexVector<gfx::Lines>& lineIndexes) {
|
gfx::IndexVector<gfx::Lines>& lineIndexes) {
|
||||||
if (nVertices == 0) return;
|
if (nVertices == 0) return;
|
||||||
@@ -206,21 +209,36 @@ void generateFillAndOutineBuffers(const GeometryCollection& geometry,
|
|||||||
gfx::PolylineGeneratorOptions lineOptions;
|
gfx::PolylineGeneratorOptions lineOptions;
|
||||||
lineOptions.type = FeatureType::Polygon;
|
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)) {
|
for (auto& polygon : classifyRings(geometry)) {
|
||||||
// Optimize polygons with many interior rings for earcut tesselation.
|
// Optimize polygons with many interior rings for earcut tesselation.
|
||||||
limitHoles(polygon, 500);
|
limitHoles(polygon, 500);
|
||||||
|
|
||||||
std::size_t totalVertices = totalVerticesCheck(polygon);
|
const std::size_t totalVertices = totalVerticesCheck(polygon);
|
||||||
std::size_t startVertices = fillVertices.elements();
|
const std::size_t startVertices = fillVertices.elements();
|
||||||
|
|
||||||
for (const auto& ring : polygon) {
|
for (const auto& ring : polygon) {
|
||||||
std::size_t base = fillVertices.elements();
|
const std::size_t base = fillVertices.elements();
|
||||||
std::size_t nVertices = addRingVertices(fillVertices, ring);
|
const std::size_t nVertices = addRingVertices(fillVertices, ring);
|
||||||
addOutlineIndices(base, nVertices, basicLineSegments, basicLineIndexes);
|
addOutlineIndices(base, nVertices, basicLineSegments, basicLineIndexes);
|
||||||
lineGenerator.generate(ring, lineOptions);
|
lineGenerator.generate(ring, lineOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tessellate, if no triangles are provided
|
||||||
std::vector<uint32_t> indices = mapbox::earcut(polygon);
|
std::vector<uint32_t> indices = mapbox::earcut(polygon);
|
||||||
|
|
||||||
addFillIndices(fillSegments, fillIndexes, indices, startVertices, totalVertices);
|
addFillIndices(fillSegments, fillIndexes, indices, startVertices, totalVertices);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,13 +11,13 @@ namespace gfx {
|
|||||||
|
|
||||||
class HillshadePrepareDrawableData : public DrawableData {
|
class HillshadePrepareDrawableData : public DrawableData {
|
||||||
public:
|
public:
|
||||||
HillshadePrepareDrawableData(int32_t stride_, Tileset::DEMEncoding encoding_, uint8_t maxzoom_)
|
HillshadePrepareDrawableData(int32_t stride_, Tileset::RasterEncoding encoding_, uint8_t maxzoom_)
|
||||||
: stride(stride_),
|
: stride(stride_),
|
||||||
encoding(encoding_),
|
encoding(encoding_),
|
||||||
maxzoom(maxzoom_) {}
|
maxzoom(maxzoom_) {}
|
||||||
|
|
||||||
int32_t stride;
|
int32_t stride;
|
||||||
Tileset::DEMEncoding encoding;
|
Tileset::RasterEncoding encoding;
|
||||||
uint8_t maxzoom;
|
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;
|
using namespace style;
|
||||||
|
|
||||||
HillshadeBucket::HillshadeBucket(PremultipliedImage&& image_, Tileset::DEMEncoding encoding)
|
HillshadeBucket::HillshadeBucket(PremultipliedImage&& image_, Tileset::RasterEncoding encoding)
|
||||||
: demdata(image_, encoding) {}
|
: demdata(image_, encoding) {}
|
||||||
|
|
||||||
HillshadeBucket::HillshadeBucket(DEMData&& demdata_)
|
HillshadeBucket::HillshadeBucket(DEMData&& demdata_)
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ using HillshadeLayoutVertex = gfx::Vertex<TypeList<attributes::pos, attributes::
|
|||||||
|
|
||||||
class HillshadeBucket final : public Bucket {
|
class HillshadeBucket final : public Bucket {
|
||||||
public:
|
public:
|
||||||
HillshadeBucket(PremultipliedImage&&, Tileset::DEMEncoding encoding);
|
HillshadeBucket(PremultipliedImage&&, Tileset::RasterEncoding encoding);
|
||||||
HillshadeBucket(std::shared_ptr<PremultipliedImage>, Tileset::DEMEncoding encoding);
|
HillshadeBucket(std::shared_ptr<PremultipliedImage>, Tileset::RasterEncoding encoding);
|
||||||
HillshadeBucket(DEMData&&);
|
HillshadeBucket(DEMData&&);
|
||||||
~HillshadeBucket() override;
|
~HillshadeBucket() override;
|
||||||
|
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates,
|
|||||||
const std::size_t first = [&coordinates, &len] {
|
const std::size_t first = [&coordinates, &len] {
|
||||||
std::size_t i = 0;
|
std::size_t i = 0;
|
||||||
// If the line has duplicate vertices at the start, adjust index to remove them.
|
// 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++;
|
i++;
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
@@ -102,17 +102,16 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& props = feature.getProperties();
|
const auto clip_start = feature.getValue("mapbox_clip_start");
|
||||||
auto clip_start_it = props.find("mapbox_clip_start");
|
const auto clip_end = feature.getValue("mapbox_clip_end");
|
||||||
auto clip_end_it = props.find("mapbox_clip_end");
|
if (clip_start && clip_end) {
|
||||||
if (clip_start_it != props.end() && clip_end_it != props.end()) {
|
|
||||||
double total_length = 0.0;
|
double total_length = 0.0;
|
||||||
for (std::size_t i = first; i < len - 1; ++i) {
|
for (std::size_t i = first; i < len - 1; ++i) {
|
||||||
total_length += util::dist<double>(coordinates[i], coordinates[i + 1]);
|
total_length += util::dist<double>(coordinates[i], coordinates[i + 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
options.clipDistances = gfx::PolylineGeneratorDistances{
|
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);
|
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/
|
// https://aws.amazon.com/public-datasets/terrain/
|
||||||
constexpr std::array<float, 4> unpackTerrarium = {{256.0f, 1.0f, 1.0f / 256.0f, 32768.0f}};
|
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) {
|
constexpr const std::array<float, 4>& getUnpackVector(const Tileset::RasterEncoding encoding) {
|
||||||
return (encoding == Tileset::DEMEncoding::Terrarium) ? unpackTerrarium : unpackMapbox;
|
return (encoding == Tileset::RasterEncoding::Terrarium) ? unpackTerrarium : unpackMapbox;
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ std::unique_ptr<RenderSource> RenderSource::create(const Immutable<Source::Impl>
|
|||||||
const TaggedScheduler& threadPool_) {
|
const TaggedScheduler& threadPool_) {
|
||||||
switch (impl->type) {
|
switch (impl->type) {
|
||||||
case SourceType::Vector:
|
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),
|
return std::make_unique<RenderVectorSource>(staticImmutableCast<TileSource::Impl>(impl),
|
||||||
std::move(threadPool_));
|
std::move(threadPool_));
|
||||||
case SourceType::Raster:
|
case SourceType::Raster:
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
#include <mbgl/renderer/sources/render_vector_source.hpp>
|
#include <mbgl/renderer/sources/render_vector_source.hpp>
|
||||||
|
|
||||||
#include <mbgl/renderer/render_tile.hpp>
|
#include <mbgl/renderer/render_tile.hpp>
|
||||||
#include <mbgl/renderer/paint_parameters.hpp>
|
#include <mbgl/renderer/paint_parameters.hpp>
|
||||||
#include <mbgl/tile/vector_tile.hpp>
|
|
||||||
#include <mbgl/renderer/tile_parameters.hpp>
|
#include <mbgl/renderer/tile_parameters.hpp>
|
||||||
|
#include <mbgl/tile/vector_mlt_tile.hpp>
|
||||||
|
#include <mbgl/tile/vector_mvt_tile.hpp>
|
||||||
|
|
||||||
namespace mbgl {
|
namespace mbgl {
|
||||||
|
|
||||||
@@ -20,17 +22,29 @@ void RenderVectorSource::updateInternal(const Tileset& tileset,
|
|||||||
const bool needsRendering,
|
const bool needsRendering,
|
||||||
const bool needsRelayout,
|
const bool needsRelayout,
|
||||||
const TileParameters& parameters) {
|
const TileParameters& parameters) {
|
||||||
tilePyramid.update(layers,
|
tilePyramid.update(
|
||||||
needsRendering,
|
layers,
|
||||||
needsRelayout,
|
needsRendering,
|
||||||
parameters,
|
needsRelayout,
|
||||||
*baseImpl,
|
parameters,
|
||||||
util::tileSize_I,
|
*baseImpl,
|
||||||
tileset.zoomRange,
|
util::tileSize_I,
|
||||||
tileset.bounds,
|
tileset.zoomRange,
|
||||||
[&](const OverscaledTileID& tileID, TileObserver* observer_) {
|
tileset.bounds,
|
||||||
return std::make_unique<VectorTile>(tileID, baseImpl->id, parameters, tileset, observer_);
|
[&](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
|
} // namespace mbgl
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ private:
|
|||||||
bool needsRelayout,
|
bool needsRelayout,
|
||||||
const TileParameters&) override;
|
const TileParameters&) override;
|
||||||
const std::optional<Tileset>& getTileset() const override;
|
const std::optional<Tileset>& getTileset() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::optional<bool> isMLT;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mbgl
|
} // 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/coordinate.hpp>
|
||||||
#include <mbgl/style/conversion/geojson.hpp>
|
#include <mbgl/style/conversion/geojson.hpp>
|
||||||
#include <mbgl/style/conversion/geojson_options.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/tileset.hpp>
|
||||||
#include <mbgl/style/conversion_impl.hpp>
|
#include <mbgl/style/conversion_impl.hpp>
|
||||||
#include <mbgl/style/sources/geojson_source.hpp>
|
#include <mbgl/style/sources/geojson_source.hpp>
|
||||||
@@ -16,8 +16,8 @@ namespace mbgl {
|
|||||||
namespace style {
|
namespace style {
|
||||||
namespace conversion {
|
namespace conversion {
|
||||||
|
|
||||||
// A tile source can either specify a URL to TileJSON, or inline TileJSON.
|
|
||||||
namespace {
|
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) {
|
std::optional<variant<std::string, Tileset>> convertURLOrTileset(const Convertible& value, Error& error) {
|
||||||
auto urlVal = objectMember(value, "url");
|
auto urlVal = objectMember(value, "url");
|
||||||
if (!urlVal) {
|
if (!urlVal) {
|
||||||
@@ -25,7 +25,7 @@ std::optional<variant<std::string, Tileset>> convertURLOrTileset(const Convertib
|
|||||||
if (!tileset) {
|
if (!tileset) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
return {*tileset};
|
return {std::move(*tileset)};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::string> url = toString(*urlVal);
|
std::optional<std::string> url = toString(*urlVal);
|
||||||
@@ -34,7 +34,7 @@ std::optional<variant<std::string, Tileset>> convertURLOrTileset(const Convertib
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {*url};
|
return {std::move(*url)};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::unique_ptr<Source>> convertRasterSource(const std::string& id,
|
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
|
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.
|
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)};
|
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,
|
std::optional<std::unique_ptr<Source>> convertVectorSource(const std::string& id,
|
||||||
const Convertible& value,
|
const Convertible& value,
|
||||||
Error& error) {
|
Error& error) {
|
||||||
std::optional<variant<std::string, Tileset>> urlOrTileset = convertURLOrTileset(value, error);
|
auto urlOrTileset = convertURLOrTileset(value, error);
|
||||||
if (!urlOrTileset) {
|
if (!urlOrTileset) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
auto maxzoomValue = objectMember(value, "maxzoom");
|
const auto maxzoomValue = objectMember(value, "maxzoom");
|
||||||
std::optional<float> maxzoom;
|
std::optional<float> maxzoom;
|
||||||
if (maxzoomValue) {
|
if (maxzoomValue) {
|
||||||
maxzoom = toNumber(*maxzoomValue);
|
maxzoom = toNumber(*maxzoomValue);
|
||||||
@@ -104,7 +104,7 @@ std::optional<std::unique_ptr<Source>> convertVectorSource(const std::string& id
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto minzoomValue = objectMember(value, "minzoom");
|
const auto minzoomValue = objectMember(value, "minzoom");
|
||||||
std::optional<float> minzoom;
|
std::optional<float> minzoom;
|
||||||
if (minzoomValue) {
|
if (minzoomValue) {
|
||||||
minzoom = toNumber(*minzoomValue);
|
minzoom = toNumber(*minzoomValue);
|
||||||
@@ -113,7 +113,20 @@ std::optional<std::unique_ptr<Source>> convertVectorSource(const std::string& id
|
|||||||
return std::nullopt;
|
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,
|
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/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/style/conversion_impl.hpp>
|
||||||
#include <mbgl/util/geo.hpp>
|
#include <mbgl/util/geo.hpp>
|
||||||
#include <mbgl/math/clamp.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);
|
auto options = convert<SourceOptions>(value, error);
|
||||||
if (rasterDEMOptions) {
|
if (options) {
|
||||||
if (std::optional<Tileset::DEMEncoding> encoding = rasterDEMOptions.value().encoding) {
|
if (const auto encoding = options->rasterEncoding) {
|
||||||
result.encoding = encoding.value();
|
result.rasterEncoding = encoding;
|
||||||
|
}
|
||||||
|
if (const auto encoding = options->vectorEncoding) {
|
||||||
|
result.vectorEncoding = encoding;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace style {
|
|||||||
RasterDEMSource::RasterDEMSource(std::string id,
|
RasterDEMSource::RasterDEMSource(std::string id,
|
||||||
variant<std::string, Tileset> urlOrTileset_,
|
variant<std::string, Tileset> urlOrTileset_,
|
||||||
uint16_t tileSize,
|
uint16_t tileSize,
|
||||||
std::optional<RasterDEMOptions> options_)
|
std::optional<SourceOptions> options_)
|
||||||
: RasterSource(std::move(id), std::move(urlOrTileset_), tileSize, SourceType::RasterDEM),
|
: RasterSource(std::move(id), std::move(urlOrTileset_), tileSize, SourceType::RasterDEM),
|
||||||
options(std::move(options_)) {}
|
options(std::move(options_)) {}
|
||||||
|
|
||||||
@@ -30,8 +30,8 @@ bool RasterDEMSource::supportsLayerType(const mbgl::style::LayerTypeInfo* info)
|
|||||||
|
|
||||||
void RasterDEMSource::setTilesetOverrides(Tileset& tileset) {
|
void RasterDEMSource::setTilesetOverrides(Tileset& tileset) {
|
||||||
if (options) {
|
if (options) {
|
||||||
if (std::optional<Tileset::DEMEncoding> encoding = options.value().encoding) {
|
if (const auto encoding = options->rasterEncoding) {
|
||||||
tileset.encoding = encoding.value();
|
tileset.rasterEncoding = encoding;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include <mbgl/util/constants.hpp>
|
#include <mbgl/util/constants.hpp>
|
||||||
#include <mbgl/util/exception.hpp>
|
#include <mbgl/util/exception.hpp>
|
||||||
#include <mbgl/util/mapbox.hpp>
|
#include <mbgl/util/mapbox.hpp>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace mbgl {
|
namespace mbgl {
|
||||||
namespace style {
|
namespace style {
|
||||||
@@ -17,10 +18,12 @@ namespace style {
|
|||||||
VectorSource::VectorSource(std::string id,
|
VectorSource::VectorSource(std::string id,
|
||||||
variant<std::string, Tileset> urlOrTileset_,
|
variant<std::string, Tileset> urlOrTileset_,
|
||||||
std::optional<float> maxZoom_,
|
std::optional<float> maxZoom_,
|
||||||
std::optional<float> minZoom_)
|
std::optional<float> minZoom_,
|
||||||
|
Tileset::VectorEncoding encoding_)
|
||||||
: TileSource(id, urlOrTileset_, util::tileSize_I, SourceType::Vector),
|
: TileSource(id, urlOrTileset_, util::tileSize_I, SourceType::Vector),
|
||||||
maxZoom(std::move(maxZoom_)),
|
maxZoom(std::move(maxZoom_)),
|
||||||
minZoom(std::move(minZoom_)) {}
|
minZoom(std::move(minZoom_)),
|
||||||
|
encoding(encoding_) {}
|
||||||
|
|
||||||
void VectorSource::setTilesetOverrides(Tileset& tileset) {
|
void VectorSource::setTilesetOverrides(Tileset& tileset) {
|
||||||
if (maxZoom) {
|
if (maxZoom) {
|
||||||
|
|||||||
@@ -4,11 +4,14 @@
|
|||||||
#include <mbgl/util/feature.hpp>
|
#include <mbgl/util/feature.hpp>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
|
#include <span>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
|
||||||
#include <optional>
|
|
||||||
|
|
||||||
|
namespace mlt {
|
||||||
|
class MapLibreTile;
|
||||||
|
}
|
||||||
namespace mbgl {
|
namespace mbgl {
|
||||||
|
|
||||||
class CanonicalTileID;
|
class CanonicalTileID;
|
||||||
@@ -44,8 +47,17 @@ public:
|
|||||||
|
|
||||||
GeometryCollection clone() const { return GeometryCollection(*this); }
|
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:
|
private:
|
||||||
GeometryCollection(const GeometryCollection&) = default;
|
GeometryCollection(const GeometryCollection&) = default;
|
||||||
|
|
||||||
|
std::shared_ptr<const mlt::MapLibreTile> triangleOwner;
|
||||||
|
std::span<const std::uint32_t> triangles = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
class GeometryTileFeature {
|
class GeometryTileFeature {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ RasterDEMTile::RasterDEMTile(const OverscaledTileID& id_,
|
|||||||
threadPool(parameters.threadPool),
|
threadPool(parameters.threadPool),
|
||||||
mailbox(std::make_shared<Mailbox>(*Scheduler::GetCurrent())),
|
mailbox(std::make_shared<Mailbox>(*Scheduler::GetCurrent())),
|
||||||
worker(parameters.threadPool, ActorRef<RasterDEMTile>(*this, mailbox)) {
|
worker(parameters.threadPool, ActorRef<RasterDEMTile>(*this, mailbox)) {
|
||||||
encoding = tileset.encoding;
|
encoding = tileset.rasterEncoding.value_or(Tileset::RasterEncoding::Mapbox);
|
||||||
if (id.canonical.y == 0) {
|
if (id.canonical.y == 0) {
|
||||||
// this tile doesn't have upper neighboring tiles so marked those as backfilled
|
// this tile doesn't have upper neighboring tiles so marked those as backfilled
|
||||||
neighboringTiles = neighboringTiles | DEMTileNeighbors::NoUpper;
|
neighboringTiles = neighboringTiles | DEMTileNeighbors::NoUpper;
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ private:
|
|||||||
Actor<RasterDEMTileWorker> worker;
|
Actor<RasterDEMTileWorker> worker;
|
||||||
|
|
||||||
uint64_t correlationID = 0;
|
uint64_t correlationID = 0;
|
||||||
Tileset::DEMEncoding encoding;
|
Tileset::RasterEncoding encoding;
|
||||||
|
|
||||||
// Contains the Bucket object for the tile. Buckets are render
|
// Contains the Bucket object for the tile. Buckets are render
|
||||||
// objects and they get added by tile parsing operations.
|
// 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,
|
void RasterDEMTileWorker::parse(const std::shared_ptr<const std::string>& data,
|
||||||
uint64_t correlationID,
|
uint64_t correlationID,
|
||||||
Tileset::DEMEncoding encoding) {
|
Tileset::RasterEncoding encoding) {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
parent.invoke(&RasterDEMTile::onParsed, nullptr,
|
parent.invoke(&RasterDEMTile::onParsed, nullptr,
|
||||||
correlationID); // No data; empty tile.
|
correlationID); // No data; empty tile.
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ class RasterDEMTileWorker {
|
|||||||
public:
|
public:
|
||||||
RasterDEMTileWorker(const ActorRef<RasterDEMTileWorker>&, ActorRef<RasterDEMTile>);
|
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:
|
private:
|
||||||
ActorRef<RasterDEMTile> parent;
|
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/constants.hpp>
|
||||||
#include <mbgl/util/instrumentation.hpp>
|
#include <mbgl/util/instrumentation.hpp>
|
||||||
#include <mbgl/util/logging.hpp>
|
#include <mbgl/util/logging.hpp>
|
||||||
|
|
||||||
|
#if ANDROID
|
||||||
|
#include <mlt/decoder.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace mbgl {
|
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) {}
|
: feature(view, layer) {}
|
||||||
|
|
||||||
FeatureType VectorTileFeature::getType() const {
|
FeatureType VectorMVTTileFeature::getType() const {
|
||||||
switch (feature.getType()) {
|
switch (feature.getType()) {
|
||||||
case mapbox::vector_tile::GeomType::POINT:
|
case mapbox::vector_tile::GeomType::POINT:
|
||||||
return FeatureType::Point;
|
return FeatureType::Point;
|
||||||
@@ -21,23 +26,23 @@ FeatureType VectorTileFeature::getType() const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<Value> VectorTileFeature::getValue(const std::string& key) const {
|
std::optional<Value> VectorMVTTileFeature::getValue(const std::string& key) const {
|
||||||
const std::optional<Value> value(feature.getValue(key));
|
const auto value = feature.getValue(key);
|
||||||
return value->is<NullValue>() ? std::nullopt : value;
|
return value.is<NullValue>() ? std::nullopt : std::optional<Value>{std::move(value)};
|
||||||
}
|
}
|
||||||
|
|
||||||
const PropertyMap& VectorTileFeature::getProperties() const {
|
const PropertyMap& VectorMVTTileFeature::getProperties() const {
|
||||||
if (!properties) {
|
if (!properties) {
|
||||||
properties = feature.getProperties();
|
properties = feature.getProperties();
|
||||||
}
|
}
|
||||||
return *properties;
|
return *properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
FeatureIdentifier VectorTileFeature::getID() const {
|
FeatureIdentifier VectorMVTTileFeature::getID() const {
|
||||||
return feature.getID();
|
return feature.getID();
|
||||||
}
|
}
|
||||||
|
|
||||||
const GeometryCollection& VectorTileFeature::getGeometries() const {
|
const GeometryCollection& VectorMVTTileFeature::getGeometries() const {
|
||||||
MLN_TRACE_FUNC();
|
MLN_TRACE_FUNC();
|
||||||
|
|
||||||
if (!lines) {
|
if (!lines) {
|
||||||
@@ -57,30 +62,30 @@ const GeometryCollection& VectorTileFeature::getGeometries() const {
|
|||||||
return *lines;
|
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_)),
|
: data(std::move(data_)),
|
||||||
layer(view) {}
|
layer(view) {}
|
||||||
|
|
||||||
std::size_t VectorTileLayer::featureCount() const {
|
std::size_t VectorMVTTileLayer::featureCount() const {
|
||||||
return layer.featureCount();
|
return layer.featureCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<GeometryTileFeature> VectorTileLayer::getFeature(std::size_t i) const {
|
std::unique_ptr<GeometryTileFeature> VectorMVTTileLayer::getFeature(std::size_t i) const {
|
||||||
return std::make_unique<VectorTileFeature>(layer, layer.getFeature(i));
|
return std::make_unique<VectorMVTTileFeature>(layer, layer.getFeature(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string VectorTileLayer::getName() const {
|
std::string VectorMVTTileLayer::getName() const {
|
||||||
return layer.getName();
|
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_)) {}
|
: data(std::move(data_)) {}
|
||||||
|
|
||||||
std::unique_ptr<GeometryTileData> VectorTileData::clone() const {
|
std::unique_ptr<GeometryTileData> VectorMVTTileData::clone() const {
|
||||||
return std::make_unique<VectorTileData>(data);
|
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();
|
MLN_TRACE_FUNC();
|
||||||
|
|
||||||
if (!parsed) {
|
if (!parsed) {
|
||||||
@@ -93,12 +98,12 @@ std::unique_ptr<GeometryTileLayer> VectorTileData::getLayer(const std::string& n
|
|||||||
|
|
||||||
auto it = layers.find(name);
|
auto it = layers.find(name);
|
||||||
if (it != layers.end()) {
|
if (it != layers.end()) {
|
||||||
return std::make_unique<VectorTileLayer>(data, it->second);
|
return std::make_unique<VectorMVTTileLayer>(data, it->second);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> VectorTileData::layerNames() const {
|
std::vector<std::string> VectorMVTTileData::layerNames() const {
|
||||||
return mapbox::vector_tile::buffer(*data).layerNames();
|
return mapbox::vector_tile::buffer(*data).layerNames();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,9 +20,9 @@
|
|||||||
|
|
||||||
namespace mbgl {
|
namespace mbgl {
|
||||||
|
|
||||||
class VectorTileFeature : public GeometryTileFeature {
|
class VectorMVTTileFeature : public GeometryTileFeature {
|
||||||
public:
|
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;
|
FeatureType getType() const override;
|
||||||
std::optional<Value> getValue(const std::string& key) const override;
|
std::optional<Value> getValue(const std::string& key) const override;
|
||||||
@@ -36,9 +36,9 @@ private:
|
|||||||
mutable std::optional<PropertyMap> properties;
|
mutable std::optional<PropertyMap> properties;
|
||||||
};
|
};
|
||||||
|
|
||||||
class VectorTileLayer : public GeometryTileLayer {
|
class VectorMVTTileLayer : public GeometryTileLayer {
|
||||||
public:
|
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::size_t featureCount() const override;
|
||||||
std::unique_ptr<GeometryTileFeature> getFeature(std::size_t i) const override;
|
std::unique_ptr<GeometryTileFeature> getFeature(std::size_t i) const override;
|
||||||
@@ -49,9 +49,9 @@ private:
|
|||||||
mapbox::vector_tile::layer layer;
|
mapbox::vector_tile::layer layer;
|
||||||
};
|
};
|
||||||
|
|
||||||
class VectorTileData : public GeometryTileData {
|
class VectorMVTTileData : public GeometryTileData {
|
||||||
public:
|
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<GeometryTileData> clone() const override;
|
||||||
std::unique_ptr<GeometryTileLayer> getLayer(const std::string& name) 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/renderer/tile_parameters.hpp>
|
||||||
#include <mbgl/tile/tile_loader_impl.hpp>
|
#include <mbgl/tile/tile_loader_impl.hpp>
|
||||||
#include <mbgl/tile/vector_tile.hpp>
|
|
||||||
#include <mbgl/tile/vector_tile_data.hpp>
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace mbgl {
|
namespace mbgl {
|
||||||
|
|
||||||
VectorTile::VectorTile(const OverscaledTileID& id_,
|
VectorTile::VectorTile(const OverscaledTileID& id_,
|
||||||
std::string sourceID_,
|
std::string sourceID_,
|
||||||
const TileParameters& parameters,
|
const TileParameters& parameters_,
|
||||||
const Tileset& tileset,
|
const Tileset& tileset,
|
||||||
TileObserver* observer_)
|
TileObserver* observer_)
|
||||||
: GeometryTile(id_, std::move(sourceID_), parameters, observer_),
|
: GeometryTile(id_, std::move(sourceID_), parameters_, observer_),
|
||||||
loader(*this, id_, parameters, tileset) {}
|
loader(*this, id_, parameters_, tileset) {}
|
||||||
|
|
||||||
VectorTile::~VectorTile() {
|
VectorTile::~VectorTile() {
|
||||||
// Don't rely on `~TileLoader` to close, it's not safe to call there.
|
// 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_);
|
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
|
} // namespace mbgl
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ public:
|
|||||||
void setNecessity(TileNecessity) final;
|
void setNecessity(TileNecessity) final;
|
||||||
void setUpdateParameters(const TileUpdateParameters&) final;
|
void setUpdateParameters(const TileUpdateParameters&) final;
|
||||||
void setMetadata(std::optional<Timestamp> modified, std::optional<Timestamp> expires);
|
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:
|
private:
|
||||||
TileLoader<VectorTile> loader;
|
TileLoader<VectorTile> loader;
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ add_library(
|
|||||||
${PROJECT_SOURCE_DIR}/test/style/conversion/light.test.cpp
|
${PROJECT_SOURCE_DIR}/test/style/conversion/light.test.cpp
|
||||||
${PROJECT_SOURCE_DIR}/test/style/conversion/padding.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/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/stringify.test.cpp
|
||||||
${PROJECT_SOURCE_DIR}/test/style/conversion/tileset.test.cpp
|
${PROJECT_SOURCE_DIR}/test/style/conversion/tileset.test.cpp
|
||||||
${PROJECT_SOURCE_DIR}/test/style/expression/dependency.test.cpp
|
${PROJECT_SOURCE_DIR}/test/style/expression/dependency.test.cpp
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ auto fakeImage = [](Size s) {
|
|||||||
|
|
||||||
TEST(DEMData, ConstructorMapbox) {
|
TEST(DEMData, ConstructorMapbox) {
|
||||||
PremultipliedImage image = fakeImage({16, 16});
|
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.dim, 16);
|
||||||
EXPECT_EQ(demdata.stride, 18);
|
EXPECT_EQ(demdata.stride, 18);
|
||||||
@@ -26,7 +26,7 @@ TEST(DEMData, ConstructorMapbox) {
|
|||||||
|
|
||||||
TEST(DEMData, ConstructorTerrarium) {
|
TEST(DEMData, ConstructorTerrarium) {
|
||||||
PremultipliedImage image = fakeImage({16, 16});
|
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.dim, 16);
|
||||||
EXPECT_EQ(demdata.stride, 18);
|
EXPECT_EQ(demdata.stride, 18);
|
||||||
@@ -35,7 +35,7 @@ TEST(DEMData, ConstructorTerrarium) {
|
|||||||
|
|
||||||
TEST(DEMData, InitialBackfill) {
|
TEST(DEMData, InitialBackfill) {
|
||||||
PremultipliedImage image1 = fakeImage({4, 4});
|
PremultipliedImage image1 = fakeImage({4, 4});
|
||||||
DEMData dem1(image1, Tileset::DEMEncoding::Mapbox);
|
DEMData dem1(image1, Tileset::RasterEncoding::Mapbox);
|
||||||
|
|
||||||
bool nonempty = true;
|
bool nonempty = true;
|
||||||
// checking that a 1 px border around the fake image has been populated
|
// checking that a 1 px border around the fake image has been populated
|
||||||
@@ -89,10 +89,10 @@ TEST(DEMData, InitialBackfill) {
|
|||||||
|
|
||||||
TEST(DEMData, BackfillNeighbor) {
|
TEST(DEMData, BackfillNeighbor) {
|
||||||
PremultipliedImage image1 = fakeImage({4, 4});
|
PremultipliedImage image1 = fakeImage({4, 4});
|
||||||
DEMData dem0(image1, Tileset::DEMEncoding::Mapbox);
|
DEMData dem0(image1, Tileset::RasterEncoding::Mapbox);
|
||||||
|
|
||||||
PremultipliedImage image2 = fakeImage({4, 4});
|
PremultipliedImage image2 = fakeImage({4, 4});
|
||||||
DEMData dem1(image2, Tileset::DEMEncoding::Mapbox);
|
DEMData dem1(image2, Tileset::RasterEncoding::Mapbox);
|
||||||
|
|
||||||
dem0.backfillBorder(dem1, -1, 0);
|
dem0.backfillBorder(dem1, -1, 0);
|
||||||
for (int y = 0; y < 4; y++) {
|
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) {
|
TEST(RasterDEMTile, onParsed) {
|
||||||
RasterDEMTileTest test;
|
RasterDEMTileTest test;
|
||||||
RasterDEMTile tile(OverscaledTileID(0, 0, 0), "testSource", test.tileParameters, test.tileset);
|
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.isRenderable());
|
||||||
EXPECT_TRUE(tile.isLoaded());
|
EXPECT_TRUE(tile.isLoaded());
|
||||||
EXPECT_TRUE(tile.isComplete());
|
EXPECT_TRUE(tile.isComplete());
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
#include <mbgl/test/fake_file_source.hpp>
|
#include <mbgl/test/fake_file_source.hpp>
|
||||||
#include <mbgl/tile/tile_loader_impl.hpp>
|
#include <mbgl/tile/tile_loader_impl.hpp>
|
||||||
#include <mbgl/tile/vector_tile.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/actor/scheduler.hpp>
|
||||||
#include <mbgl/annotation/annotation_manager.hpp>
|
#include <mbgl/annotation/annotation_manager.hpp>
|
||||||
@@ -38,6 +38,8 @@ public:
|
|||||||
renderable = true;
|
renderable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setData(const std::shared_ptr<const std::string>&) override {}
|
||||||
|
|
||||||
util::SimpleIdentity uniqueId;
|
util::SimpleIdentity uniqueId;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include <mbgl/test/util.hpp>
|
#include <mbgl/test/util.hpp>
|
||||||
#include <mbgl/test/fake_file_source.hpp>
|
#include <mbgl/test/fake_file_source.hpp>
|
||||||
#include <mbgl/tile/vector_tile.hpp>
|
#include <mbgl/tile/vector_mvt_tile.hpp>
|
||||||
#include <mbgl/tile/vector_tile_data.hpp>
|
#include <mbgl/tile/vector_mvt_tile_data.hpp>
|
||||||
#include <mbgl/tile/tile_loader_impl.hpp>
|
#include <mbgl/tile/tile_loader_impl.hpp>
|
||||||
#include <mbgl/storage/resource_options.hpp>
|
#include <mbgl/storage/resource_options.hpp>
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ using namespace mbgl;
|
|||||||
|
|
||||||
TEST(VectorTile, setError) {
|
TEST(VectorTile, setError) {
|
||||||
VectorTileTest test;
|
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")));
|
tile.setError(std::make_exception_ptr(std::runtime_error("test")));
|
||||||
EXPECT_FALSE(tile.isRenderable());
|
EXPECT_FALSE(tile.isRenderable());
|
||||||
EXPECT_TRUE(tile.isLoaded());
|
EXPECT_TRUE(tile.isLoaded());
|
||||||
@@ -34,7 +34,7 @@ TEST(VectorTile, setError) {
|
|||||||
|
|
||||||
TEST(VectorTile, onError) {
|
TEST(VectorTile, onError) {
|
||||||
VectorTileTest test;
|
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);
|
tile.onError(std::make_exception_ptr(std::runtime_error("test")), 0);
|
||||||
|
|
||||||
EXPECT_FALSE(tile.isRenderable());
|
EXPECT_FALSE(tile.isRenderable());
|
||||||
@@ -44,7 +44,7 @@ TEST(VectorTile, onError) {
|
|||||||
|
|
||||||
TEST(VectorTile, Issue8542) {
|
TEST(VectorTile, Issue8542) {
|
||||||
VectorTileTest test;
|
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
|
// Query before data is set
|
||||||
std::vector<Feature> result;
|
std::vector<Feature> result;
|
||||||
@@ -52,7 +52,7 @@ TEST(VectorTile, Issue8542) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(VectorTileData, ParseResults) {
|
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();
|
std::vector<std::string> layerNames = data.layerNames();
|
||||||
ASSERT_EQ(layerNames.size(), 2u);
|
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