[offline] Add option to pass geojson input file
This commit is contained in:
committed by
Ivo van Dongen
parent
ca0f2f925d
commit
fcb68041d5
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user