diff options
author | Ivo van Dongen <info@ivovandongen.nl> | 2018-04-11 10:59:32 +0300 |
---|---|---|
committer | Ivo van Dongen <ivovandongen@users.noreply.github.com> | 2018-08-20 22:49:01 +0300 |
commit | fcb68041d51990a4cf67d88fa1eeb0f5d882305c (patch) | |
tree | 771197c6a6e80739dca30e2b2904cef939618ccf | |
parent | ca0f2f925d38c190957241f7fa2375a90fa87f45 (diff) | |
download | qtlocation-mapboxgl-fcb68041d51990a4cf67d88fa1eeb0f5d882305c.tar.gz |
[offline] Add option to pass geojson input file
-rw-r--r-- | bin/offline.cpp | 90 | ||||
-rw-r--r-- | platform/linux/config.cmake | 1 |
2 files changed, 77 insertions, 14 deletions
diff --git a/bin/offline.cpp b/bin/offline.cpp index 603f0b848a..2da47a4476 100644 --- a/bin/offline.cpp +++ b/bin/offline.cpp @@ -1,6 +1,7 @@ #include <mbgl/util/default_styles.hpp> #include <mbgl/util/run_loop.hpp> #include <mbgl/util/string.hpp> +#include <mbgl/util/geojson.hpp> #include <mbgl/storage/default_file_source.hpp> @@ -11,9 +12,47 @@ #include <csignal> #include <atomic> #include <sstream> +#include <fstream> using namespace std::literals::chrono_literals; +std::string readFile(const std::string& fileName) { + std::ifstream stream(fileName.c_str()); + if (!stream.good()) { + throw std::runtime_error("Cannot read file: " + fileName); + } + + std::stringstream buffer; + buffer << stream.rdbuf(); + stream.close(); + + return buffer.str(); +} + +mapbox::geometry::geometry<double> parseGeometry(const std::string& json) { + using namespace mapbox::geojson; + auto geojson = parse(json); + return geojson.match( + [](const geometry& geom) { + return geom; + }, + [](const feature& feature) { + return feature.geometry; + }, + [](const feature_collection& featureCollection) { + if (featureCollection.size() < 1) { + throw std::runtime_error("No features in feature collection"); + } + geometry_collection geometries; + + for (auto feature : featureCollection) { + geometries.push_back(feature.geometry); + } + + return geometries; + }); +} + int main(int argc, char *argv[]) { args::ArgumentParser argumentParser("Mapbox GL offline tool"); args::HelpFlag helpFlag(argumentParser, "help", "Display this help menu", {'h', "help"}); @@ -22,11 +61,19 @@ int main(int argc, char *argv[]) { args::ValueFlag<std::string> styleValue(argumentParser, "URL", "Map stylesheet", {'s', "style"}); args::ValueFlag<std::string> outputValue(argumentParser, "file", "Output database file name", {'o', "output"}); args::ValueFlag<std::string> apiBaseValue(argumentParser, "URL", "API Base URL", {'a', "apiBaseURL"}); - - args::ValueFlag<double> northValue(argumentParser, "degrees", "North latitude", {"north"}); - args::ValueFlag<double> westValue(argumentParser, "degrees", "West longitude", {"west"}); - args::ValueFlag<double> southValue(argumentParser, "degrees", "South latitude", {"south"}); - args::ValueFlag<double> eastValue(argumentParser, "degrees", "East longitude", {"east"}); + + // LatLngBounds + args::Group latLngBoundsGroup(argumentParser, "LatLng bounds:", args::Group::Validators::AllOrNone); + args::ValueFlag<double> northValue(latLngBoundsGroup, "degrees", "North latitude", {"north"}); + args::ValueFlag<double> westValue(latLngBoundsGroup, "degrees", "West longitude", {"west"}); + args::ValueFlag<double> southValue(latLngBoundsGroup, "degrees", "South latitude", {"south"}); + args::ValueFlag<double> eastValue(latLngBoundsGroup, "degrees", "East longitude", {"east"}); + + // Geometry + args::Group geoJSONGroup(argumentParser, "GeoJson geometry:", args::Group::Validators::AllOrNone); + args::ValueFlag<std::string> geometryValue(geoJSONGroup, "file", "GeoJSON file containing the region geometry", {"geojson"}); + + args::ValueFlag<double> minZoomValue(argumentParser, "number", "Min zoom level", {"minZoom"}); args::ValueFlag<double> maxZoomValue(argumentParser, "number", "Max zoom level", {"maxZoom"}); args::ValueFlag<double> pixelRatioValue(argumentParser, "number", "Pixel ratio", {"pixelRatio"}); @@ -48,23 +95,39 @@ int main(int argc, char *argv[]) { std::string style = styleValue ? args::get(styleValue) : mbgl::util::default_styles::streets.url; - // Bay area - const double north = northValue ? args::get(northValue) : 37.2; - const double west = westValue ? args::get(westValue) : -122.8; - const double south = southValue ? args::get(southValue) : 38.1; - const double east = eastValue ? args::get(eastValue) : -121.7; - const double minZoom = minZoomValue ? args::get(minZoomValue) : 0.0; const double maxZoom = maxZoomValue ? args::get(maxZoomValue) : 15.0; const double pixelRatio = pixelRatioValue ? args::get(pixelRatioValue) : 1.0; const std::string output = outputValue ? args::get(outputValue) : "offline.db"; + + using namespace mbgl; + + OfflineRegionDefinition definition = [&]() { + if (geometryValue) { + try { + std::string json = readFile(geometryValue.Get()); + auto geometry = parseGeometry(json); + return OfflineRegionDefinition{ OfflineGeometryRegionDefinition(style, geometry, minZoom, maxZoom, pixelRatio) }; + } catch(std::runtime_error e) { + std::cerr << "Could not parse geojson file " << geometryValue.Get() << ": " << e.what() << std::endl; + exit(1); + } + } else { + // Bay area + const double north = northValue ? args::get(northValue) : 37.2; + const double west = westValue ? args::get(westValue) : -122.8; + const double south = southValue ? args::get(southValue) : 38.1; + const double east = eastValue ? args::get(eastValue) : -121.7; + LatLngBounds boundingBox = LatLngBounds::hull(LatLng(north, west), LatLng(south, east)); + return OfflineRegionDefinition{ OfflineTilePyramidRegionDefinition(style, boundingBox, minZoom, maxZoom, pixelRatio) }; + } + }(); const char* tokenEnv = getenv("MAPBOX_ACCESS_TOKEN"); const std::string token = tokenValue ? args::get(tokenValue) : (tokenEnv ? tokenEnv : std::string()); const std::string apiBaseURL = apiBaseValue ? args::get(apiBaseValue) : mbgl::util::API_BASE_URL; - using namespace mbgl; util::RunLoop loop; DefaultFileSource fileSource(output, "."); @@ -73,8 +136,7 @@ int main(int argc, char *argv[]) { fileSource.setAccessToken(token); fileSource.setAPIBaseURL(apiBaseURL); - LatLngBounds boundingBox = LatLngBounds::hull(LatLng(north, west), LatLng(south, east)); - OfflineTilePyramidRegionDefinition definition(style, boundingBox, minZoom, maxZoom, pixelRatio); + OfflineRegionMetadata metadata; class Observer : public OfflineRegionObserver { diff --git a/platform/linux/config.cmake b/platform/linux/config.cmake index c1eb4bfe12..b55cedcacb 100644 --- a/platform/linux/config.cmake +++ b/platform/linux/config.cmake @@ -81,6 +81,7 @@ macro(mbgl_platform_core) target_add_mason_package(mbgl-core PUBLIC libjpeg-turbo) target_add_mason_package(mbgl-core PUBLIC webp) target_add_mason_package(mbgl-core PRIVATE icu) + target_add_mason_package(mbgl-core PUBLIC geojson) target_link_libraries(mbgl-core PRIVATE nunicode |