From 8a283b030629abb00367929d047731c3974bc3d6 Mon Sep 17 00:00:00 2001 From: Molly Lloyd Date: Wed, 14 Feb 2018 13:17:55 -0800 Subject: [core] add support for mapzen terrarium (#11154) * add support for mapzen terrarium * Encoding --> DEMEncoding, avoid if statement when unpacking elevation values * add Terrarium test * update submodule * remove redundant checks --- src/mbgl/geometry/dem_data.cpp | 16 ++++++++++++++-- src/mbgl/geometry/dem_data.hpp | 3 ++- src/mbgl/renderer/buckets/hillshade_bucket.cpp | 2 +- src/mbgl/renderer/buckets/hillshade_bucket.hpp | 5 +++-- src/mbgl/style/conversion/tileset.cpp | 10 ++++++++++ src/mbgl/tile/raster_dem_tile.cpp | 3 ++- src/mbgl/tile/raster_dem_tile.hpp | 1 + src/mbgl/tile/raster_dem_tile_worker.cpp | 4 ++-- src/mbgl/tile/raster_dem_tile_worker.hpp | 3 ++- 9 files changed, 37 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/mbgl/geometry/dem_data.cpp b/src/mbgl/geometry/dem_data.cpp index 78134dadc1..7fa98950ea 100644 --- a/src/mbgl/geometry/dem_data.cpp +++ b/src/mbgl/geometry/dem_data.cpp @@ -3,7 +3,7 @@ namespace mbgl { -DEMData::DEMData(const PremultipliedImage& _image): +DEMData::DEMData(const PremultipliedImage& _image, Tileset::DEMEncoding encoding): dim(_image.size.height), border(std::max(std::ceil(_image.size.height / 2), 1)), stride(dim + 2 * border), @@ -13,13 +13,25 @@ DEMData::DEMData(const PremultipliedImage& _image): throw std::runtime_error("raster-dem tiles must be square."); } + auto decodeMapbox = [] (const uint8_t r, const uint8_t g, const uint8_t b){ + // https://www.mapbox.com/help/access-elevation-data/#mapbox-terrain-rgb + return (r * 256 * 256 + g * 256 + b)/10 - 10000; + }; + + auto decodeTerrarium = [] (const uint8_t r, const uint8_t g, const uint8_t b){ + // https://aws.amazon.com/public-datasets/terrain/ + return ((r * 256 + g + b / 256) - 32768); + }; + + auto decodeRGB = encoding == Tileset::DEMEncoding::Terrarium ? decodeTerrarium : decodeMapbox; + std::memset(image.data.get(), 0, image.bytes()); for (int32_t y = 0; y < dim; y++) { for (int32_t x = 0; x < dim; x++) { const int32_t i = y * dim + x; const int32_t j = i * 4; - set(x, y, (_image.data[j] * 256 * 256 + _image.data[j+1] * 256 + _image.data[j+2])/10 - 10000); + set(x, y, decodeRGB(_image.data[j], _image.data[j+1], _image.data[j+2])); } } diff --git a/src/mbgl/geometry/dem_data.hpp b/src/mbgl/geometry/dem_data.hpp index 507a51661d..817d3cc9c9 100644 --- a/src/mbgl/geometry/dem_data.hpp +++ b/src/mbgl/geometry/dem_data.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -12,7 +13,7 @@ namespace mbgl { class DEMData { public: - DEMData(const PremultipliedImage& image); + DEMData(const PremultipliedImage& image, Tileset::DEMEncoding encoding); void backfillBorder(const DEMData& borderTileData, int8_t dx, int8_t dy); void set(const int32_t x, const int32_t y, const int32_t value) { diff --git a/src/mbgl/renderer/buckets/hillshade_bucket.cpp b/src/mbgl/renderer/buckets/hillshade_bucket.cpp index 8011681ee0..00b9536894 100644 --- a/src/mbgl/renderer/buckets/hillshade_bucket.cpp +++ b/src/mbgl/renderer/buckets/hillshade_bucket.cpp @@ -8,7 +8,7 @@ namespace mbgl { using namespace style; -HillshadeBucket::HillshadeBucket(PremultipliedImage&& image_): demdata(image_) { +HillshadeBucket::HillshadeBucket(PremultipliedImage&& image_, Tileset::DEMEncoding encoding): demdata(image_, encoding) { } HillshadeBucket::HillshadeBucket(DEMData&& demdata_) : demdata(std::move(demdata_)) { diff --git a/src/mbgl/renderer/buckets/hillshade_bucket.hpp b/src/mbgl/renderer/buckets/hillshade_bucket.hpp index 3d9f6c61af..5335f7ceda 100644 --- a/src/mbgl/renderer/buckets/hillshade_bucket.hpp +++ b/src/mbgl/renderer/buckets/hillshade_bucket.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -16,8 +17,8 @@ namespace mbgl { class HillshadeBucket : public Bucket { public: - HillshadeBucket(PremultipliedImage&&); - HillshadeBucket(std::shared_ptr); + HillshadeBucket(PremultipliedImage&&, Tileset::DEMEncoding encoding); + HillshadeBucket(std::shared_ptr, Tileset::DEMEncoding encoding); HillshadeBucket(DEMData&&); diff --git a/src/mbgl/style/conversion/tileset.cpp b/src/mbgl/style/conversion/tileset.cpp index 88e78b1a83..6d89cef944 100644 --- a/src/mbgl/style/conversion/tileset.cpp +++ b/src/mbgl/style/conversion/tileset.cpp @@ -40,6 +40,16 @@ optional Converter::operator()(const Convertible& value, Error } } + auto encodingValue = objectMember(value, "encoding"); + if (encodingValue) { + optional encoding = toString(*encodingValue); + if (encoding && *encoding == "terrarium") { + result.encoding = Tileset::DEMEncoding::Terrarium; + } else if (encoding && *encoding != "mapbox") { + error = { "invalid raster-dem encoding type - valid types are 'mapbox' and 'terrarium' " }; + } + } + auto minzoomValue = objectMember(value, "minzoom"); if (minzoomValue) { optional minzoom = toNumber(*minzoomValue); diff --git a/src/mbgl/tile/raster_dem_tile.cpp b/src/mbgl/tile/raster_dem_tile.cpp index b270378ece..5db298cf4c 100644 --- a/src/mbgl/tile/raster_dem_tile.cpp +++ b/src/mbgl/tile/raster_dem_tile.cpp @@ -21,6 +21,7 @@ RasterDEMTile::RasterDEMTile(const OverscaledTileID& id_, worker(parameters.workerScheduler, ActorRef(*this, mailbox)) { + encoding = tileset.encoding; if ( id.canonical.y == 0 ){ // this tile doesn't have upper neighboring tiles so marked those as backfilled neighboringTiles = neighboringTiles | DEMTileNeighbors::NoUpper; @@ -47,7 +48,7 @@ void RasterDEMTile::setMetadata(optional modified_, optional data) { pending = true; ++correlationID; - worker.invoke(&RasterDEMTileWorker::parse, data, correlationID); + worker.invoke(&RasterDEMTileWorker::parse, data, correlationID, encoding); } void RasterDEMTile::onParsed(std::unique_ptr result, const uint64_t resultCorrelationID) { diff --git a/src/mbgl/tile/raster_dem_tile.hpp b/src/mbgl/tile/raster_dem_tile.hpp index 68f8a91e00..0c8dd75961 100644 --- a/src/mbgl/tile/raster_dem_tile.hpp +++ b/src/mbgl/tile/raster_dem_tile.hpp @@ -94,6 +94,7 @@ private: Actor worker; uint64_t correlationID = 0; + Tileset::DEMEncoding encoding; // Contains the Bucket object for the tile. Buckets are render // objects and they get added by tile parsing operations. diff --git a/src/mbgl/tile/raster_dem_tile_worker.cpp b/src/mbgl/tile/raster_dem_tile_worker.cpp index ed8573788f..7338e578c7 100644 --- a/src/mbgl/tile/raster_dem_tile_worker.cpp +++ b/src/mbgl/tile/raster_dem_tile_worker.cpp @@ -10,14 +10,14 @@ RasterDEMTileWorker::RasterDEMTileWorker(ActorRef, ActorRef : parent(std::move(parent_)) { } -void RasterDEMTileWorker::parse(std::shared_ptr data, uint64_t correlationID) { +void RasterDEMTileWorker::parse(std::shared_ptr data, uint64_t correlationID, Tileset::DEMEncoding encoding) { if (!data) { parent.invoke(&RasterDEMTile::onParsed, nullptr, correlationID); // No data; empty tile. return; } try { - auto bucket = std::make_unique(decodeImage(*data)); + auto bucket = std::make_unique(decodeImage(*data), encoding); parent.invoke(&RasterDEMTile::onParsed, std::move(bucket), correlationID); } catch (...) { parent.invoke(&RasterDEMTile::onError, std::current_exception(), correlationID); diff --git a/src/mbgl/tile/raster_dem_tile_worker.hpp b/src/mbgl/tile/raster_dem_tile_worker.hpp index 14fd1f43b5..5a8222bc2d 100644 --- a/src/mbgl/tile/raster_dem_tile_worker.hpp +++ b/src/mbgl/tile/raster_dem_tile_worker.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -13,7 +14,7 @@ class RasterDEMTileWorker { public: RasterDEMTileWorker(ActorRef, ActorRef); - void parse(std::shared_ptr data, uint64_t correlationID); + void parse(std::shared_ptr data, uint64_t correlationID, Tileset::DEMEncoding encoding); private: ActorRef parent; -- cgit v1.2.1