OmniSciDB  6686921089
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GDAL.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2020 OmniSci, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "Geospatial/GDAL.h"
18 #include <array>
19 #include <string>
20 
21 #include <gdal.h>
22 #include <gdal_priv.h>
23 
24 #include "Logger/Logger.h"
26 
27 #ifdef _WIN32
28 #include "Shared/clean_windows.h"
29 #endif
30 
31 namespace Geospatial {
32 
33 namespace {
34 
35 void gdal_error_handler(CPLErr err_class, int err_no, const char* err_msg) {
36  CHECK(err_class >= CE_None && err_class <= CE_Fatal);
37  static constexpr std::array<const char*, 5> err_class_strings{
38  "Info",
39  "Debug",
40  "Warning",
41  "Failure",
42  "Fatal",
43  };
44  std::string log_msg = std::string("GDAL ") + err_class_strings[err_class] + ": " +
45  err_msg + " (" + std::to_string(err_no) + ")";
46  if (err_class >= CE_Failure) {
47  throw std::runtime_error(log_msg);
48  } else {
49  LOG(INFO) << log_msg;
50  }
51 }
52 
53 } // namespace
54 
55 bool GDAL::initialized_ = false;
56 
57 std::mutex GDAL::init_mutex_;
58 
59 void GDAL::init() {
60  // this should not be called from multiple threads, but...
61  std::lock_guard<std::mutex> guard(init_mutex_);
62 
63  // init under mutex
64  if (!initialized_) {
65  // FIXME(andrewseidl): investigate if CPLPushFinderLocation can be public
66 #ifdef _MSC_VER
67  SetEnvironmentVariable(
68  L"GDAL_DATA",
69  reinterpret_cast<LPCWSTR>(
70  std::string(omnisci::get_root_abs_path() + "/ThirdParty/gdal-data").c_str()));
71  SetEnvironmentVariable(
72  L"PROJ_LIB",
73  reinterpret_cast<LPCWSTR>(
74  std::string(omnisci::get_root_abs_path() + "/ThirdParty/gdal-data/proj")
75  .c_str()));
76 #else
77  setenv("GDAL_DATA",
78  std::string(omnisci::get_root_abs_path() + "/ThirdParty/gdal-data").c_str(),
79  true);
80  setenv(
81  "PROJ_LIB",
82  std::string(omnisci::get_root_abs_path() + "/ThirdParty/gdal-data/proj").c_str(),
83  true);
84 #endif
85 
86 #ifndef _MSC_VER // TODO
87  // configure SSL certificate path (per S3Archive::init_for_read)
88  // in a production build, GDAL and Curl will have been built on
89  // CentOS, so the baked-in system path will be wrong for Ubuntu
90  // and other Linux distros. Unless the user is deliberately
91  // overriding it by setting SSL_CERT_FILE explicitly in the server
92  // environment, we set it to whichever CA bundle directory exists
93  // on the machine we're running on
94  static constexpr std::array<const char*, 6> known_ca_paths{
95  "/etc/ssl/certs/ca-certificates.crt",
96  "/etc/pki/tls/certs/ca-bundle.crt",
97  "/usr/share/ssl/certs/ca-bundle.crt",
98  "/usr/local/share/certs/ca-root.crt",
99  "/etc/ssl/cert.pem",
100  "/etc/ssl/ca-bundle.pem"};
101  for (const auto& known_ca_path : known_ca_paths) {
102  if (boost::filesystem::exists(known_ca_path)) {
103  LOG(INFO) << "GDAL SSL Certificate path: " << known_ca_path;
104  setenv("SSL_CERT_FILE", known_ca_path, false); // no overwrite
105  break;
106  }
107  }
108 #endif
109 
110  GDALAllRegister();
111  OGRRegisterAll();
112  CPLSetErrorHandler(*gdal_error_handler);
113  LOG(INFO) << "GDAL Initialized: " << GDALVersionInfo("--version");
114  initialized_ = true;
115  }
116 }
117 
119 #if (GDAL_VERSION_MAJOR > 2) || (GDAL_VERSION_MAJOR == 2 && GDAL_VERSION_MINOR >= 2)
120  return true;
121 #else
122  return false;
123 #endif
124 }
125 
126 bool GDAL::supportsDriver(const char* driver_name) {
127  init();
128  return GetGDALDriverManager()->GetDriverByName(driver_name) != nullptr;
129 }
130 
131 } // namespace Geospatial
void gdal_error_handler(CPLErr err_class, int err_no, const char *err_msg)
Definition: GDAL.cpp:35
#define LOG(tag)
Definition: Logger.h:203
static void init()
Definition: GDAL.cpp:59
std::string to_string(char const *&&v)
static bool initialized_
Definition: GDAL.h:30
static bool supportsDriver(const char *driver_name)
Definition: GDAL.cpp:126
static bool supportsNetworkFileAccess()
Definition: GDAL.cpp:118
static std::mutex init_mutex_
Definition: GDAL.h:31
#define CHECK(condition)
Definition: Logger.h:209
std::string get_root_abs_path()