1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
#include <mbgl/map/map.hpp>
#include <mbgl/util/image.hpp>
#include <mbgl/util/io.hpp>
#include <mbgl/util/run_loop.hpp>
#include <mbgl/gl/headless_backend.hpp>
#include <mbgl/gl/offscreen_view.hpp>
#include <mbgl/util/default_thread_pool.hpp>
#include <mbgl/storage/default_file_source.hpp>
#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;
#include <cstdlib>
#include <iostream>
int main(int argc, char *argv[]) {
std::string style_path;
double lat = 0, lon = 0;
double zoom = 0;
double bearing = 0;
double pitch = 0;
uint32_t width = 512;
uint32_t height = 512;
static std::string output = "out.png";
std::string cache_file = "cache.sqlite";
std::string asset_root = ".";
std::vector<std::string> classes;
std::string token;
bool debug = false;
po::options_description desc("Allowed options");
desc.add_options()
("style,s", po::value(&style_path)->required()->value_name("json"), "Map stylesheet")
("lon,x", po::value(&lon)->value_name("degrees")->default_value(lon), "Longitude")
("lat,y", po::value(&lat)->value_name("degrees")->default_value(lat), "Latitude in degrees")
("zoom,z", po::value(&zoom)->value_name("number")->default_value(zoom), "Zoom level")
("bearing,b", po::value(&bearing)->value_name("degrees")->default_value(bearing), "Bearing")
("pitch,p", po::value(&pitch)->value_name("degrees")->default_value(pitch), "Pitch")
("width,w", po::value(&width)->value_name("pixels")->default_value(width), "Image width")
("height,h", po::value(&height)->value_name("pixels")->default_value(height), "Image height")
("class,c", po::value(&classes)->value_name("name"), "Class name")
("token,t", po::value(&token)->value_name("key")->default_value(token), "Mapbox access token")
("debug", po::bool_switch(&debug)->default_value(debug), "Debug mode")
("output,o", po::value(&output)->value_name("file")->default_value(output), "Output file name")
("cache,d", po::value(&cache_file)->value_name("file")->default_value(cache_file), "Cache database file name")
("assets,d", po::value(&asset_root)->value_name("file")->default_value(asset_root), "Directory to which asset:// URLs will resolve")
;
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);
}
std::string style = mbgl::util::read_file(style_path);
using namespace mbgl;
util::RunLoop loop;
DefaultFileSource fileSource(cache_file, asset_root);
// Try to load the token from the environment.
if (!token.size()) {
const char *token_ptr = getenv("MAPBOX_ACCESS_TOKEN");
if (token_ptr) {
token = token_ptr;
}
}
// Set access token if present
if (token.size()) {
fileSource.setAccessToken(std::string(token));
}
HeadlessBackend backend;
OffscreenView view(backend.getContext(), { width, height });
ThreadPool threadPool(4);
Map map(backend, view.size, 1, fileSource, threadPool, MapMode::Still);
map.setStyleJSON(style);
map.setClasses(classes);
map.setLatLngZoom({ lat, lon }, zoom);
map.setBearing(bearing);
map.setPitch(pitch);
if (debug) {
map.setDebug(debug ? mbgl::MapDebugOptions::TileBorders | mbgl::MapDebugOptions::ParseStatus : mbgl::MapDebugOptions::NoDebug);
}
map.renderStill(view, [&](std::exception_ptr error) {
try {
if (error) {
std::rethrow_exception(error);
}
} catch(std::exception& e) {
std::cout << "Error: " << e.what() << std::endl;
exit(1);
}
util::write_file(output, encodePNG(view.readStillImage()));
loop.stop();
});
loop.run();
return 0;
}
|