64 char **paths =
nullptr;
65 paths = CSLAddString(paths, projDBPath.c_str());
66 OSRSetPROJSearchPaths(paths);
73 this->p_dataset = GDALDatasetUniquePtr(GDALDataset::Open(filename.c_str(), GDAL_OF_VECTOR));
74 if (!this->p_dataset) {
75 throw std::runtime_error(
"dataset pointer is null after initialization, dataset unable to be initialized.");
111 GDALVectorWrapper(std::string bytes, std::string projection, std::string name, std::string projDBPath) {
114 std::cout <<
"in GDALVectorWrapper constructor" << std::endl;
115 char **paths =
nullptr;
116 paths = CSLAddString(paths, projDBPath.c_str());
117 OSRSetPROJSearchPaths(paths);
123 GDALDataset *p_indataset = GDALDataset::FromHandle(GDALOpenEx(bytes.c_str(), GDAL_OF_VECTOR,
nullptr,
nullptr,
nullptr));
124 OGRLayer *p_inlayer = p_indataset->GetLayerByName(
"OGRGeoJSON");
127 OGRErr err = this->srs.importFromWkt(projection.c_str());
129 throw std::runtime_error(
"unable to get Spatial Reference System from projection string.");
131 this->haveSRS =
true;
134 GDALDriver *p_driver = GetGDALDriverManager()->GetDriverByName(
"MEM");
136 throw std::runtime_error(
"unable to create dataset driver.");
138 GDALDataset *p_dataset = p_driver->Create(
"", 0, 0, 0, GDT_Unknown,
nullptr);
140 throw std::runtime_error(
"unable to create dataset from driver.");
142 OGRLayer *p_outlayer = p_dataset->CreateLayer(name.c_str(), &this->srs, wkbUnknown,
nullptr);
144 throw std::runtime_error(
"unable to create dataset layer.");
146 this->p_dataset = GDALDatasetUniquePtr(p_dataset);
157 OGRFeatureDefn *p_featdef = p_inlayer->GetLayerDefn();
158 int fcount = p_featdef->GetFieldCount();
159 for (
int i = 0; i < fcount; i++) {
160 OGRFieldDefn *p_fielddef = p_featdef->GetFieldDefn(i);
161 OGRErr err = p_outlayer->CreateField(p_fielddef);
163 std::cout <<
"unable to copy field definition." << std::endl;
168 for (
auto& p_infeature : p_inlayer) {
169 OGRFeature *p_outfeature = OGRFeature::CreateFeature(p_featdef);
170 for (
int i = 0; i < fcount; i++) {
171 p_outfeature->SetField(i, p_infeature->GetRawFieldRef(i));
173 OGRGeometry *p_geom = p_infeature->GetGeometryRef();
175 throw std::runtime_error(
"an invalid geometry was encountered in the vector file.");
177 p_geom->assignSpatialReference(&this->srs);
178 p_outfeature->SetGeometry(p_geom);
179 p_outlayer->CreateFeature(p_outfeature);
180 OGRFeature::DestroyFeature(p_outfeature);
221 std::unordered_map<std::string, std::string>
getLayerInfo(std::string layerName) {
222 std::unordered_map<std::string, std::string> retval;
224 OGRLayer *p_layer = this->p_dataset->GetLayerByName(layerName.c_str());
225 std::unique_ptr<OGREnvelope> extent = std::unique_ptr<OGREnvelope>(
new OGREnvelope);
226 p_layer->GetExtent(extent.get());
228 retval.emplace(
"feature_count", std::to_string(p_layer->GetFeatureCount()));
229 retval.emplace(
"field_count", std::to_string(p_layer->GetLayerDefn()->GetFieldCount()));
230 retval.emplace(
"geometry_type", OGRGeometryTypeToName(p_layer->GetGeomType()));
231 retval.emplace(
"xmin", std::to_string(extent->MinX));
232 retval.emplace(
"xmax", std::to_string(extent->MaxX));
233 retval.emplace(
"ymin", std::to_string(extent->MinY));
234 retval.emplace(
"ymax", std::to_string(extent->MaxY));
235 if (!p_layer->GetSpatialRef()) {
236 std::cout <<
"WARNING: cannot get spatial reference for layer " << layerName <<
"." << std::endl;
239 retval.emplace(
"crs", std::string(p_layer->GetSpatialRef()->GetName()));
272 std::vector<std::vector<double>>
getPoints(std::string layerName) {
273 OGRLayer *p_layer = this->p_dataset->GetLayerByName(layerName.c_str());
274 std::vector<double> xCoords;
275 std::vector<double> yCoords;
277 for (
const auto& p_feature : *p_layer) {
278 OGRGeometry *p_geometry = p_feature->GetGeometryRef();
280 throw std::runtime_error(std::format(
"an invalid geometry was encountered in the {} layer.", layerName));
282 switch (wkbFlatten(p_geometry->getGeometryType())) {
283 case OGRwkbGeometryType::wkbPoint: {
284 OGRPoint *p_point = p_geometry->toPoint();
285 xCoords.push_back(p_point->getX());
286 yCoords.push_back(p_point->getY());
289 case OGRwkbGeometryType::wkbMultiPoint: {
290 for (
const auto& p_point : *p_geometry->toMultiPoint()) {
291 xCoords.push_back(p_point->getX());
292 yCoords.push_back(p_point->getY());
297 throw std::runtime_error(
"encountered a geometry which was not of type Point or MultiPoint.");
301 return {xCoords, yCoords};
314 OGRLayer *p_layer = this->p_dataset->GetLayerByName(layerName.c_str());
315 std::vector<std::string> retval;
317 for (
const auto& p_feature : *p_layer) {
318 OGRGeometry *p_geometry = p_feature->GetGeometryRef();
320 throw std::runtime_error(std::format(
"an invalid geometry was encountered in the {} layer.", layerName));
322 switch (wkbFlatten(p_geometry->getGeometryType())) {
323 case OGRwkbGeometryType::wkbPoint: {
324 OGRPoint *p_point = p_geometry->toPoint();
325 retval.push_back(p_point->exportToWkt());
328 case OGRwkbGeometryType::wkbMultiPoint: {
329 for (
const auto& p_point : *p_geometry->toMultiPoint()) {
330 retval.push_back(p_point->exportToWkt());
335 throw std::runtime_error(
"encountered a geometry which was not of type Point or MultiPoint.");
361 std::vector<std::vector<std::vector<double>>>
getLineStrings(std::string layerName){
362 OGRLayer *p_layer = this->p_dataset->GetLayerByName(layerName.c_str());
363 std::vector<std::vector<std::vector<double>>> retval;
365 for (
const auto& p_feature : *p_layer) {
366 OGRGeometry *p_geometry = p_feature->GetGeometryRef();
368 throw std::runtime_error(std::format(
"an invalid geometry was encountered in the {} layer.", layerName));
370 switch (wkbFlatten(p_geometry->getGeometryType())) {
371 case OGRwkbGeometryType::wkbLineString: {
372 std::vector<double> xCoords;
373 std::vector<double> yCoords;
374 for (
const auto& p_point : *p_geometry->toLineString()) {
375 xCoords.push_back(p_point.getX());
376 yCoords.push_back(p_point.getY());
378 retval.push_back({xCoords, yCoords});
381 case OGRwkbGeometryType::wkbMultiLineString: {
382 for (
const auto& p_lineString : *p_geometry->toMultiLineString()) {
383 std::vector<double> xCoords;
384 std::vector<double> yCoords;
385 for (
const auto& p_point : *p_lineString) {
386 xCoords.push_back(p_point.getX());
387 yCoords.push_back(p_point.getY());
389 retval.push_back({xCoords, yCoords});
394 throw std::runtime_error(
"encountered a point which was not of type LineString or MultiLineString");
411 std::filesystem::path filepath = filename;
412 std::string extension = filepath.extension().string();
415 GDALDriver *p_driver;
416 if (extension ==
".geojson") {
417 p_driver = GetGDALDriverManager()->GetDriverByName(
"GeoJSON");
419 else if (extension ==
".shp") {
420 p_driver = GetGDALDriverManager()->GetDriverByName(
"ESRI Shapefile");
423 throw std::runtime_error(
"file extension must be one of : .geojson, .shp");
426 GDALDataset *datasetCopy = p_driver->CreateCopy(
428 this->p_dataset.get(),
436 std::cout <<
"failed to create dataset with filename " << filename <<
"." << std::endl;
439 CPLErr err = GDALClose(datasetCopy);
441 if (err != CE_None) {
442 std::cout <<
"failed to close dataset of file " << filename <<
". The file output may not be correct." << std::endl;