sgsPy
structurally guided sampling
Loading...
Searching...
No Matches
poly.h
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * Project: sgs
4 * Purpose: C++ implementation of raster stratification using quantiles
5 * Author: Joseph Meyer
6 * Date: June, 2025
7 *
8 ******************************************************************************/
9
14
15#include "utils/helper.h"
16#include "utils/raster.h"
17#include "utils/vector.h"
18
19#include "gdal_utils.h"
20
21namespace sgs {
22namespace poly {
23
63 size_t numStrata,
64 std::string layerName,
65 std::string query,
66 std::string filename,
67 bool largeRaster,
68 std::string tempFolder,
69 std::map<std::string, std::string> driverOptions)
70{
71 GDALAllRegister();
72
73 //step 1: get required info from vector and raster objects
74 GDALDataset *p_vectorDS = p_vector->getDataset();
75 GDALDataset *p_rasterDS = p_raster->getDataset();
76
77 int width = p_raster->getWidth();
78 int height = p_raster->getHeight();
79 double *geotransform = p_raster->getGeotransform();
80 std::string projection = std::string(p_rasterDS->GetProjectionRef());
81
82 OGRLayer *p_layer = p_vector->getLayer(layerName);
83 if (!p_layer) {
84 std::string errmsg = "could not find layer associated with " + layerName;
85 throw std::runtime_error(errmsg);
86 }
87 const OGRSpatialReference *p_layerSrs = p_layer->GetSpatialRef();
88 if (!p_layerSrs) {
89 throw std::runtime_error("vector layer does not have a projection.");
90 }
91 if (projection == "") {
92 throw std::runtime_error("raster does not have a projection.");
93 }
94 if (!OGRSpatialReference(projection.c_str()).IsSame(p_layerSrs)) {
95 throw std::runtime_error("raster and vector projections don't match.");
96 }
97
98 bool isMEMDataset = !largeRaster && filename == "";
99 bool isVRTDataset = largeRaster && filename == "";
100
102 helper::setStratBandTypeAndSize(numStrata - 1, &band.type, &band.size);
103 p_rasterDS->GetRasterBand(1)->GetBlockSize(&band.xBlockSize, &band.yBlockSize);
104 band.name = "strat_" + layerName;
105 std::vector<helper::VRTBandDatasetInfo> VRTBandInfo;
106
107 //step 2: create dataset
108 GDALDataset *p_dataset = nullptr;
109 if (isMEMDataset) {
110 p_dataset = helper::createVirtualDataset("MEM", width, height, geotransform, projection);
111 helper::addBandToMEMDataset(p_dataset, band);
112 }
113 else if (isVRTDataset) {
114 p_dataset = helper::createVirtualDataset("VRT", width, height, geotransform, projection);
115 helper::createVRTBandDataset(p_dataset, band, tempFolder, layerName + ".tif", VRTBandInfo, driverOptions);
116 }
117 else {
118 std::string driver;
119 std::filesystem::path filepath = filename;
120 std::string extension = filepath.extension().string();
121
122 if (extension == ".tif") {
123 driver = "Gtiff";
124 }
125 else {
126 throw std::runtime_error("sgs only supports .tif files right now");
127 }
128
129 p_dataset = helper::createDataset(filename, driver, width, height, geotransform, projection, &band, 1, false, driverOptions);
130 }
131
132 band.p_band->Fill(band.nan);
133
134 //step 4: generate options list for GDALRasterize()
135 char ** argv = nullptr;
136
137 //specify the vector attribute to 'strata', which is created by the sql query
138 argv = CSLAddString(argv, "-a");
139 argv = CSLAddString(argv, "strata");
140
141 //specify sql query
142 argv = CSLAddString(argv, "-sql");
143 argv = CSLAddString(argv, query.c_str());
144
145 //specify sql dialect
146 argv = CSLAddString(argv, "-dialect");
147 argv = CSLAddString(argv, "SQLITE");
148
149 GDALRasterizeOptions *options = GDALRasterizeOptionsNew(argv, nullptr);
150 //step 5: rasterize vector to in-memory dataset
151 GDALRasterize(
152 nullptr,
153 !isVRTDataset ? p_dataset : VRTBandInfo[0].p_dataset,
154 p_vectorDS,
155 options,
156 nullptr
157 );
158
159 //step 6: free dynamically allocated rasterization options
160 GDALRasterizeOptionsFree(options);
161 CSLDestroy(argv);
162
163 if (isVRTDataset) {
164 GDALClose(VRTBandInfo[0].p_dataset);
165 helper::addBandToVRTDataset(p_dataset, band, VRTBandInfo[0]);
166 }
167
168 //step 7: create new GDALRasterWrapper using dataset pointer
169 //this dynamically allocated object will be cleaned up by python
170 return isMEMDataset ?
171 new raster::GDALRasterWrapper(p_dataset, {band.p_buffer}) :
172 new raster::GDALRasterWrapper(p_dataset);
173}
174
175} //namespace poly
176} //namespace sgs
Definition raster.h:57
GDALDataset * getDataset()
Definition raster.h:429
int getWidth()
Definition raster.h:467
double * getGeotransform()
Definition raster.h:590
int getHeight()
Definition raster.h:476
Definition vector.h:46
OGRLayer * getLayer(std::string layerName)
Definition vector.h:246
GDALDataset * getDataset()
Definition vector.h:185
void addBandToVRTDataset(GDALDataset *p_dataset, RasterBandMetaData &band, VRTBandDatasetInfo &info)
Definition helper.h:599
GDALDataset * createDataset(std::string filename, std::string driverName, int width, int height, double *geotransform, std::string projection, RasterBandMetaData *bands, size_t bandCount, bool useTiles, std::map< std::string, std::string > &driverOptions)
Definition helper.h:375
void addBandToMEMDataset(GDALDataset *p_dataset, RasterBandMetaData &band)
Definition helper.h:467
void createVRTBandDataset(GDALDataset *p_dataset, RasterBandMetaData &band, std::string tempFolder, std::string key, std::vector< VRTBandDatasetInfo > &VRTBandInfo, std::map< std::string, std::string > &driverOptions)
Definition helper.h:538
GDALDataset * createVirtualDataset(std::string driverName, int width, int height, double *geotransform, std::string projection)
Definition helper.h:294
void setStratBandTypeAndSize(size_t maxStrata, GDALDataType *p_type, size_t *p_size)
Definition helper.h:140
raster::GDALRasterWrapper * poly(vector::GDALVectorWrapper *p_vector, raster::GDALRasterWrapper *p_raster, size_t numStrata, std::string layerName, std::string query, std::string filename, bool largeRaster, std::string tempFolder, std::map< std::string, std::string > driverOptions)
Definition poly.h:60
Definition pca.h:23
Definition helper.h:87
int xBlockSize
Definition helper.h:94
void * p_buffer
Definition helper.h:89
int yBlockSize
Definition helper.h:95
size_t size
Definition helper.h:91
GDALDataType type
Definition helper.h:90
double nan
Definition helper.h:93
std::string name
Definition helper.h:92
GDALRasterBand * p_band
Definition helper.h:88