diff options
author | Bruno de Oliveira Abinader <bruno@mapbox.com> | 2017-11-09 12:57:08 +0200 |
---|---|---|
committer | Bruno de Oliveira Abinader <bruno@mapbox.com> | 2017-11-09 13:53:10 +0200 |
commit | 92fe05657994e8f02b71dbb9027fdc20477a2ca4 (patch) | |
tree | 658186546b21a043b5f5a09c468d6281743bfda0 | |
parent | a71756ea8d62cb448963a59e215e1324cfd57d9f (diff) | |
download | qtlocation-mapboxgl-upstream/qt-offline.tar.gz |
[Qt] Add Qt platform-specific 'mbgl-offline' impl: 'qt-offline'upstream/qt-offline
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | circle.yml | 6 | ||||
-rw-r--r-- | cmake/offline.cmake | 12 | ||||
-rw-r--r-- | platform/qt/bitrise-qt4.yml | 1 | ||||
-rw-r--r-- | platform/qt/bitrise-qt5.yml | 1 | ||||
-rw-r--r-- | platform/qt/config.cmake | 23 | ||||
-rw-r--r-- | platform/qt/src/offline.cpp | 144 |
7 files changed, 192 insertions, 3 deletions
@@ -419,6 +419,14 @@ qt-app: $(QT_BUILD) run-qt-app: qt-app $(QT_OUTPUT_PATH)/mbgl-qt +.PHONY: qt-offline +qt-offline: $(QT_BUILD) + $(NINJA) $(NINJA_ARGS) -j$(JOBS) -C $(QT_OUTPUT_PATH) mbgl-offline + +.PHONY: run-qt-offline +run-qt-offline: qt-offline + $(QT_OUTPUT_PATH)/mbgl-offline + .PHONY: qt-test qt-test: $(QT_BUILD) $(NINJA) $(NINJA_ARGS) -j$(JOBS) -C $(QT_OUTPUT_PATH) mbgl-test diff --git a/circle.yml b/circle.yml index 69f5403d9c..61c88a8169 100644 --- a/circle.yml +++ b/circle.yml @@ -93,6 +93,10 @@ step-library: run: name: Build qt-app command: make qt-app + - &build-qt-offline + run: + name: Build qt-offline + command: make qt-offline - &build-qt-test run: name: Build qt-test @@ -549,6 +553,7 @@ jobs: - *restore-cache - *reset-ccache-stats - *build-qt-app + - *build-qt-offline - *build-qt-test - *show-ccache-stats - *save-cache @@ -576,6 +581,7 @@ jobs: - *restore-cache - *reset-ccache-stats - *build-qt-app + - *build-qt-offline - *build-qt-test - run: name: Build qt-docs diff --git a/cmake/offline.cmake b/cmake/offline.cmake index c9a3349792..2a432e9a3d 100644 --- a/cmake/offline.cmake +++ b/cmake/offline.cmake @@ -1,6 +1,12 @@ -add_executable(mbgl-offline - bin/offline.cpp -) +if (MBGL_OFFLINE_QT) + add_executable(mbgl-offline + platform/qt/src/offline.cpp + ) +else() + add_executable(mbgl-offline + bin/offline.cpp + ) +endif() target_sources(mbgl-offline PRIVATE platform/default/mbgl/util/default_styles.hpp diff --git a/platform/qt/bitrise-qt4.yml b/platform/qt/bitrise-qt4.yml index d8c7e0788e..30fdc24c23 100644 --- a/platform/qt/bitrise-qt4.yml +++ b/platform/qt/bitrise-qt4.yml @@ -20,6 +20,7 @@ workflows: brew linkapps qt export BUILDTYPE=Debug make qt-app + make qt-offline make run-qt-test - is_debug: 'yes' - slack: diff --git a/platform/qt/bitrise-qt5.yml b/platform/qt/bitrise-qt5.yml index 0ce964e43f..19cf498f4d 100644 --- a/platform/qt/bitrise-qt5.yml +++ b/platform/qt/bitrise-qt5.yml @@ -25,6 +25,7 @@ workflows: ln -s $HOMEBREW_QT5_CELLAR/$HOMEBREW_QT5_VERSION/plugins /usr/local/plugins export BUILDTYPE=Debug make qt-app + make qt-offline make run-qt-test - is_debug: 'yes' - deploy-to-bitrise-io: diff --git a/platform/qt/config.cmake b/platform/qt/config.cmake index e3b15fddfd..4602a96dfa 100644 --- a/platform/qt/config.cmake +++ b/platform/qt/config.cmake @@ -1,5 +1,6 @@ include(platform/qt/qt.cmake) +mason_use(boost_libprogram_options VERSION 1.62.0${MASON_CXXABI_SUFFIX}) mason_use(sqlite VERSION 3.14.2) mason_use(gtest VERSION 1.8.0${MASON_CXXABI_SUFFIX}) @@ -62,6 +63,28 @@ macro(mbgl_filesource) ) endmacro() +set(MBGL_OFFLINE_QT ON) +macro(mbgl_platform_offline) + target_sources(mbgl-offline + PRIVATE platform/default/mbgl/util/default_styles.hpp + ) + + target_compile_options(mbgl-offline + PRIVATE -fvisibility-inlines-hidden + ) + + target_include_directories(mbgl-offline + PRIVATE platform/default + ) + + target_add_mason_package(mbgl-offline PRIVATE boost) + target_add_mason_package(mbgl-offline PRIVATE boost_libprogram_options) + + target_link_libraries(mbgl-offline + PRIVATE mbgl-core + PRIVATE mbgl-filesource + ) +endmacro() macro(mbgl_platform_test) target_sources(mbgl-test diff --git a/platform/qt/src/offline.cpp b/platform/qt/src/offline.cpp new file mode 100644 index 0000000000..f6bb0a8fb5 --- /dev/null +++ b/platform/qt/src/offline.cpp @@ -0,0 +1,144 @@ +#include <mbgl/util/default_styles.hpp> +#include <mbgl/util/run_loop.hpp> +#include <mbgl/util/string.hpp> + +#include <mbgl/storage/default_file_source.hpp> + +#include <cstdlib> +#include <iostream> +#include <csignal> +#include <atomic> + +#include <QCoreApplication> + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunknown-pragmas" +#pragma GCC diagnostic ignored "-Wunused-local-typedefs" +#pragma GCC diagnostic ignored "-Wshadow" +#include <boost/program_options.hpp> +#pragma GCC diagnostic pop + +namespace po = boost::program_options; +using namespace std::literals::chrono_literals; + +int main(int argc, char *argv[]) { + QCoreApplication app(argc, argv); + + std::string style = mbgl::util::default_styles::streets.url; + double north = 37.2, west = -122.8, south = 38.1, east = -121.7; // Bay area + double minZoom = 0.0, maxZoom = 15.0, pixelRatio = 1.0; + std::string output = "offline.db"; + + const char* tokenEnv = getenv("MAPBOX_ACCESS_TOKEN"); + std::string token = tokenEnv ? tokenEnv : std::string(); + + po::options_description desc("Allowed options"); + desc.add_options() + ("style,s", po::value(&style)->value_name("URL"), "Map stylesheet") + ("north", po::value(&north)->value_name("degrees")->default_value(north), "North latitude") + ("west", po::value(&west)->value_name("degrees")->default_value(west), "West longitude") + ("south", po::value(&south)->value_name("degrees")->default_value(south), "South latitude") + ("east", po::value(&east)->value_name("degrees")->default_value(east), "East longitude") + ("minZoom", po::value(&minZoom)->value_name("number")->default_value(minZoom), "Min zoom level") + ("maxZoom", po::value(&maxZoom)->value_name("number")->default_value(maxZoom), "Max zoom level") + ("pixelRatio", po::value(&pixelRatio)->value_name("number")->default_value(pixelRatio), "Pixel ratio") + ("token,t", po::value(&token)->value_name("key")->default_value(token), "Mapbox access token") + ("output,o", po::value(&output)->value_name("file")->default_value(output), "Output database file name") + ; + + try { + po::variables_map vm; + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + } catch(std::exception& e) { + std::cout << "Error: " << e.what() << std::endl << desc; + exit(1); + } + + using namespace mbgl; + + util::RunLoop loop; + DefaultFileSource fileSource(output, "."); + std::unique_ptr<OfflineRegion> region; + + fileSource.setAccessToken(token); + + LatLngBounds boundingBox = LatLngBounds::hull(LatLng(north, west), LatLng(south, east)); + OfflineTilePyramidRegionDefinition definition(style, boundingBox, minZoom, maxZoom, pixelRatio); + OfflineRegionMetadata metadata; + + class Observer : public OfflineRegionObserver { + public: + Observer(OfflineRegion& region_, DefaultFileSource& fileSource_, util::RunLoop& loop_) + : region(region_), + fileSource(fileSource_), + loop(loop_), + start(util::now()) { + } + + void statusChanged(OfflineRegionStatus status) override { + if (status.downloadState == OfflineRegionDownloadState::Inactive) { + std::cout << "stopped" << std::endl; + loop.stop(); + return; + } + + std::string bytesPerSecond = "-"; + + auto elapsedSeconds = (util::now() - start) / 1s; + if (elapsedSeconds != 0) { + bytesPerSecond = util::toString(status.completedResourceSize / elapsedSeconds); + } + + std::cout << status.completedResourceCount << " / " << status.requiredResourceCount + << " resources" + << (status.requiredResourceCountIsPrecise ? "; " : " (indeterminate); ") + << status.completedResourceSize << " bytes downloaded" + << " (" << bytesPerSecond << " bytes/sec)" + << std::endl; + + if (status.complete()) { + std::cout << "Finished" << std::endl; + loop.stop(); + } + } + + void responseError(Response::Error error) override { + std::cerr << error.reason << " downloading resource: " << error.message << std::endl; + } + + void mapboxTileCountLimitExceeded(uint64_t limit) override { + std::cerr << "Error: reached limit of " << limit << " offline tiles" << std::endl; + } + + OfflineRegion& region; + DefaultFileSource& fileSource; + util::RunLoop& loop; + Timestamp start; + }; + + static auto stop = [&] { + if (region) { + std::cout << "Stopping download... "; + fileSource.setOfflineRegionDownloadState(*region, OfflineRegionDownloadState::Inactive); + } + }; + + std::signal(SIGINT, [] (int) { stop(); }); + + fileSource.createOfflineRegion(definition, metadata, [&] (std::exception_ptr error, optional<OfflineRegion> region_) { + if (error) { + std::cerr << "Error creating region: " << util::toString(error) << std::endl; + loop.stop(); + exit(1); + } else { + assert(region_); + region = std::make_unique<OfflineRegion>(std::move(*region_)); + fileSource.setOfflineRegionObserver(*region, std::make_unique<Observer>(*region, fileSource, loop)); + fileSource.setOfflineRegionDownloadState(*region, OfflineRegionDownloadState::Active); + } + }); + + loop.run(); + return 0; +} |