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) {
113 char **paths =
nullptr;
114 paths = CSLAddString(paths, projDBPath.c_str());
115 OSRSetPROJSearchPaths(paths);
121 GDALDataset *p_indataset = GDALDataset::FromHandle(GDALOpenEx(bytes.c_str(), GDAL_OF_VECTOR,
nullptr,
nullptr,
nullptr));
122 OGRLayer *p_inlayer = p_indataset->GetLayerByName(
"OGRGeoJSON");
125 OGRErr err = this->srs.importFromWkt(projection.c_str());
127 throw std::runtime_error(
"unable to get Spatial Reference System from projection string.");
129 this->haveSRS =
true;
132 GDALDriver *p_driver = GetGDALDriverManager()->GetDriverByName(
"MEM");
134 throw std::runtime_error(
"unable to create dataset driver.");
136 GDALDataset *p_dataset = p_driver->Create(
"", 0, 0, 0, GDT_Unknown,
nullptr);
138 throw std::runtime_error(
"unable to create dataset from driver.");
140 OGRLayer *p_outlayer = p_dataset->CreateLayer(name.c_str(), &this->srs, wkbUnknown,
nullptr);
142 throw std::runtime_error(
"unable to create dataset layer.");
144 this->p_dataset = GDALDatasetUniquePtr(p_dataset);
156 OGRFeatureDefn *p_featdef = p_inlayer->GetLayerDefn();
157 int fcount = p_featdef->GetFieldCount();
158 for (
int i = 0; i < fcount; i++) {
159 OGRFieldDefn *p_fielddef = p_featdef->GetFieldDefn(i);
160 OGRErr err = p_outlayer->CreateField(p_fielddef);
162 std::cout <<
"unable to copy field definition." << std::endl;
167 for (
auto& p_infeature : p_inlayer) {
168 OGRFeature *p_outfeature = OGRFeature::CreateFeature(p_featdef);
169 for (
int i = 0; i < fcount; i++) {
170 p_outfeature->SetField(i, p_infeature->GetRawFieldRef(i));
172 OGRGeometry *p_geom = p_infeature->GetGeometryRef();
173 p_geom->assignSpatialReference(&this->srs);
174 p_outfeature->SetGeometry(p_geom);
175 p_outlayer->CreateFeature(p_outfeature);
176 OGRFeature::DestroyFeature(p_outfeature);
217 std::unordered_map<std::string, std::string>
getLayerInfo(std::string layerName) {
218 std::unordered_map<std::string, std::string> retval;
220 OGRLayer *p_layer = this->p_dataset->GetLayerByName(layerName.c_str());
221 std::unique_ptr<OGREnvelope> extent = std::unique_ptr<OGREnvelope>(
new OGREnvelope);
222 p_layer->GetExtent(extent.get());
224 retval.emplace(
"feature_count", std::to_string(p_layer->GetFeatureCount()));
225 retval.emplace(
"field_count", std::to_string(p_layer->GetLayerDefn()->GetFieldCount()));
226 retval.emplace(
"geometry_type", OGRGeometryTypeToName(p_layer->GetGeomType()));
227 retval.emplace(
"xmin", std::to_string(extent->MinX));
228 retval.emplace(
"xmax", std::to_string(extent->MaxX));
229 retval.emplace(
"ymin", std::to_string(extent->MinY));
230 retval.emplace(
"ymax", std::to_string(extent->MaxY));
231 if (!p_layer->GetSpatialRef()) {
232 std::cout <<
"WARNING: cannot get spatial reference for layer " << layerName <<
"." << std::endl;
235 retval.emplace(
"crs", std::string(p_layer->GetSpatialRef()->GetName()));
268 std::vector<std::vector<double>>
getPoints(std::string layerName) {
269 OGRLayer *p_layer = this->p_dataset->GetLayerByName(layerName.c_str());
270 std::vector<double> xCoords;
271 std::vector<double> yCoords;
273 for (
const auto& p_feature : *p_layer) {
274 OGRGeometry *p_geometry = p_feature->GetGeometryRef();
275 switch (wkbFlatten(p_geometry->getGeometryType())) {
276 case OGRwkbGeometryType::wkbPoint: {
277 OGRPoint *p_point = p_geometry->toPoint();
278 xCoords.push_back(p_point->getX());
279 yCoords.push_back(p_point->getY());
282 case OGRwkbGeometryType::wkbMultiPoint: {
283 for (
const auto& p_point : *p_geometry->toMultiPoint()) {
284 xCoords.push_back(p_point->getX());
285 yCoords.push_back(p_point->getY());
290 throw std::runtime_error(
"encountered a geometry which was not of type Point or MultiPoint.");
294 return {xCoords, yCoords};
307 OGRLayer *p_layer = this->p_dataset->GetLayerByName(layerName.c_str());
308 std::vector<std::string> retval;
310 for (
const auto& p_feature : *p_layer) {
311 OGRGeometry *p_geometry = p_feature->GetGeometryRef();
312 switch (wkbFlatten(p_geometry->getGeometryType())) {
313 case OGRwkbGeometryType::wkbPoint: {
314 OGRPoint *p_point = p_geometry->toPoint();
315 retval.push_back(p_point->exportToWkt());
318 case OGRwkbGeometryType::wkbMultiPoint: {
319 for (
const auto& p_point : *p_geometry->toMultiPoint()) {
320 retval.push_back(p_point->exportToWkt());
325 throw std::runtime_error(
"encountered a geometry which was not of type Point or MultiPoint.");
351 std::vector<std::vector<std::vector<double>>>
getLineStrings(std::string layerName){
352 OGRLayer *p_layer = this->p_dataset->GetLayerByName(layerName.c_str());
353 std::vector<std::vector<std::vector<double>>> retval;
355 for (
const auto& p_feature : *p_layer) {
356 OGRGeometry *p_geometry = p_feature->GetGeometryRef();
357 switch (wkbFlatten(p_geometry->getGeometryType())) {
358 case OGRwkbGeometryType::wkbLineString: {
359 std::vector<double> xCoords;
360 std::vector<double> yCoords;
361 for (
const auto& p_point : *p_geometry->toLineString()) {
362 xCoords.push_back(p_point.getX());
363 yCoords.push_back(p_point.getY());
365 retval.push_back({xCoords, yCoords});
368 case OGRwkbGeometryType::wkbMultiLineString: {
369 for (
const auto& p_lineString : *p_geometry->toMultiLineString()) {
370 std::vector<double> xCoords;
371 std::vector<double> yCoords;
372 for (
const auto& p_point : *p_lineString) {
373 xCoords.push_back(p_point.getX());
374 yCoords.push_back(p_point.getY());
376 retval.push_back({xCoords, yCoords});
381 throw std::runtime_error(
"encountered a point which was not of type LineString or MultiLineString");
398 std::filesystem::path filepath = filename;
399 std::string extension = filepath.extension().string();
402 GDALDriver *p_driver;
403 if (extension ==
".geojson") {
404 p_driver = GetGDALDriverManager()->GetDriverByName(
"GeoJSON");
406 else if (extension ==
".shp") {
407 p_driver = GetGDALDriverManager()->GetDriverByName(
"ESRI Shapefile");
410 throw std::runtime_error(
"file extension must be one of : .geojson, .shp");
413 GDALDataset *datasetCopy = p_driver->CreateCopy(
415 this->p_dataset.get(),
423 std::cout <<
"failed to create dataset with filename " << filename <<
"." << std::endl;
426 CPLErr err = GDALClose(datasetCopy);
428 if (err != CE_None) {
429 std::cout <<
"failed to close dataset of file " << filename <<
". The file output may not be correct." << std::endl;