182 OGRwkbGeometryType ogr_geometry_type = wkbUnknown;
183 int num_geo_columns = 0;
184 int geo_column_srid = 0;
185 uint32_t num_columns = 0;
186 std::string geo_column_name;
187 for (
auto const& column_info : column_infos) {
188 auto const& type_info = column_info.get_type_info();
189 if (type_info.is_geometry()) {
190 switch (type_info.get_type()) {
192 ogr_geometry_type = wkbPoint;
195 ogr_geometry_type = wkbMultiPoint;
198 ogr_geometry_type = wkbLineString;
201 ogr_geometry_type = wkbMultiLineString;
204 ogr_geometry_type = wkbPolygon;
207 ogr_geometry_type = wkbMultiPolygon;
212 geo_column_srid = type_info.get_output_srid();
213 geo_column_name =
safeColumnName(column_info.get_resname(), num_columns + 1);
216 auto column_name =
safeColumnName(column_info.get_resname(), num_columns + 1);
222 if (num_geo_columns != 1) {
223 throw std::runtime_error(
"File type '" +
225 "' requires exactly one geo column in query results");
229 if (geo_column_srid <= 0) {
230 throw std::runtime_error(
"Geo column '" + geo_column_name +
"' has invalid SRID (" +
232 "). Use ST_SetSRID() in query to override.");
237 auto gdal_driver = GetGDALDriverManager()->GetDriverByName(driver_name);
238 if (gdal_driver ==
nullptr) {
239 throw std::runtime_error(
"Failed to find Driver '" + std::string(driver_name) +
244 auto gdal_file_path{file_path};
245 auto user_file_path{file_path};
250 throw std::runtime_error(
251 "Selected file compression option not yet supported for file type '" +
261 auto remove_file = [](
const std::string&
filename) {
262 if (boost::filesystem::exists(
filename)) {
264 boost::filesystem::remove(
filename);
267 remove_file(file_path);
268 remove_file(user_file_path);
270 LOG(
INFO) <<
"Exporting to file '" << user_file_path <<
"'";
274 gdal_driver->Create(gdal_file_path.c_str(), 0, 0, 0, GDT_Unknown, NULL);
276 throw std::runtime_error(
"Failed to create File '" + file_path +
"'");
280 OGRSpatialReference ogr_spatial_reference;
281 if (ogr_spatial_reference.importFromEPSG(geo_column_srid)) {
282 throw std::runtime_error(
"Failed to create Spatial Reference for SRID " +
285 #if GDAL_VERSION_MAJOR >= 3
286 ogr_spatial_reference.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
291 layer_name.c_str(), &ogr_spatial_reference, ogr_geometry_type, NULL);
293 throw std::runtime_error(
"Failed to create Layer '" + layer_name +
"'");
297 int column_index = 0;
300 for (
auto const& column_info : column_infos) {
301 auto column_name =
safeColumnName(column_info.get_resname(), column_index + 1);
303 auto const& type_info = column_info.get_type_info();
304 if (!type_info.is_geometry()) {
305 OGRFieldDefn field_defn(
308 if (
ogr_layer_->CreateField(&field_defn) != OGRERR_NONE) {
309 throw std::runtime_error(
"Failed to create Field '" + column_name +
"'");
318 }
catch (std::exception& e) {
319 LOG(
INFO) <<
"GDAL Query Export failed to start: " << e.what();
static constexpr std::array< const char *, 5 > file_type_names
const FileType file_type_
static constexpr std::array< std::array< bool, 3 >, 5 > compression_implemented
std::string safeColumnName(const std::string &resname, const int column_index)
static std::array< std::unordered_set< std::string >, 5 > file_type_valid_extensions
ArrayNullHandling array_null_handling_
static constexpr std::array< const char *, 3 > compression_prefix
OGRFieldType sql_type_info_to_ogr_field_type(const std::string &name, const SQLTypeInfo &type_info, const QueryExporter::FileType file_type)
static constexpr std::array< const char *, 3 > compression_suffix
std::vector< int > field_indices_
std::string filename(char const *path)
void validateFileExtensions(const std::string &file_path, const std::string &file_type, const std::unordered_set< std::string > &valid_extensions) const
static constexpr std::array< const char *, 5 > driver_names
GDALDataset * gdal_dataset_