summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvo van Dongen <info@ivovandongen.nl>2018-04-11 10:59:32 +0300
committerIvo van Dongen <info@ivovandongen.nl>2018-08-20 19:58:27 +0300
commit27ce802e521516ad65046f5d1e1361d536b70916 (patch)
tree0e7251bd6bf321ae553eb393b5b450e6ae682806
parent7140cf5b65ad6af5c8996680bbc3398f42dcbf49 (diff)
downloadqtlocation-mapboxgl-upstream/ivd-arbitrary-offline-region-shapes.tar.gz
[offline] Add option to pass geojson input fileupstream/ivd-arbitrary-offline-region-shapes
-rw-r--r--bin/offline.cpp90
-rw-r--r--platform/linux/config.cmake1
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