text: #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>
  #include <mbgl/util/url.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 pixelRatio = 1;
      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")
          ("ratio,r", po::value(&pixelRatio)->value_name("number")->default_value(pixelRatio), "Image scale factor")
          ("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);
      }
  
      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 * pixelRatio, height * pixelRatio });
      ThreadPool threadPool(4);
      Map map(backend, mbgl::Size { width, height }, pixelRatio, fileSource, threadPool, MapMode::Still);
  
      if (util::isURL(style_path)) {
          map.setStyleURL(style_path);
      } else {
          map.setStyleJSON(mbgl::util::read_file(style_path));
      }
  
      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;
  }
  