21#include <boost/unordered/unordered_flat_map.hpp>
24#include <ogrsf_frmts.h>
90 GDALDataType
type = GDT_Unknown;
142 GDALDataType *p_type,
147 *p_size =
sizeof(int8_t);
151 *p_size =
sizeof(int16_t);
155 *p_size =
sizeof(int32_t);
180 return static_cast<T
>(((int8_t *)p_data)[index]);
182 return static_cast<T
>(((uint16_t *)p_data)[index]);
184 return static_cast<T
>(((int16_t *)p_data)[index]);
186 return static_cast<T
>(((uint32_t *)p_data)[index]);
188 return static_cast<T
>(((int32_t *)p_data)[index]);
190 return static_cast<T
>(((
float *)p_data)[index]);
192 return static_cast<T
>(((
double *)p_data)[index]);
194 throw std::runtime_error(
"raster pixel data type not supported.");
222 reinterpret_cast<int8_t *
>(p_data)[index] = isNan ?
223 static_cast<int8_t
>(-1) :
224 static_cast<int8_t
>(strata);
227 reinterpret_cast<int16_t *
>(p_data)[index] = isNan ?
228 static_cast<int16_t
>(-1) :
229 static_cast<int16_t
>(strata);
232 reinterpret_cast<int32_t *
>(p_data)[index] = isNan ?
233 static_cast<int32_t
>(-1) :
234 static_cast<int32_t
>(strata);
237 throw std::runtime_error(
"strata pixel data type not supported.");
254 std::cout <<
"**warning** the pixel type of one of the bands given is an unsigned 32 bit integer. This may result in undefined behavior if the value is not castable to a 32-bit signed integer type." << std::endl;
257 std::cout <<
"**warning** the pixel type of one of the bands given is a 32 bit floating point value. This may result in undefined behavior if the value is not castable to a 32-bit signed integer type." << std::endl;
260 std::cout <<
"**warning** the pixel type of one of the bands given is a 64 bit floating point value. This may result in undefined behavior if the value is not castable to a 32-bit signed integer type." << std::endl;
295 std::string driverName,
298 double *geotransform,
299 std::string projection)
301 GDALDriver *p_driver = GetGDALDriverManager()->GetDriverByName(driverName.c_str());
303 throw std::runtime_error(
"unable to find dataset driver.");
306 GDALDataset *p_dataset = p_driver->Create(
315 throw std::runtime_error(
"unable to create dataset with driver.");
318 CPLErr err = p_dataset->SetGeoTransform(geotransform);
320 throw std::runtime_error(
"error setting geotransform.");
323 err = p_dataset->SetProjection(projection.c_str());
325 throw std::runtime_error(
"error setting projection.");
376 std::string filename,
377 std::string driverName,
380 double *geotransform,
381 std::string projection,
385 std::map<std::string, std::string>& driverOptions)
387 GDALDriver *p_driver = GetGDALDriverManager()->GetDriverByName(driverName.c_str());
389 throw std::runtime_error(
"unable to find dataset driver.");
392 char **papszOptions =
nullptr;
394 if (driverOptions.find(
"TILED") == driverOptions.end()) {
395 papszOptions = CSLSetNameValue(papszOptions,
"TILED",
"YES");
397 if (driverOptions.find(
"BLOCKXSIZE") == driverOptions.end()) {
398 const char *xBlockSizeOption = std::to_string(bands[0].xBlockSize).c_str();
399 papszOptions = CSLSetNameValue(papszOptions,
"BLOCKXSIZE", xBlockSizeOption);
401 if (driverOptions.find(
"BLOCKYSIZE") == driverOptions.end()) {
402 const char *yBlockSizeOption = std::to_string(bands[0].yBlockSize).c_str();
403 papszOptions = CSLSetNameValue(papszOptions,
"BLOCKYSIZE", yBlockSizeOption);
407 for (
auto const& [key, val] : driverOptions) {
408 papszOptions = CSLSetNameValue(papszOptions, key.c_str(), val.c_str());
411 GDALDataset *p_dataset = p_driver->Create(
419 CSLDestroy(papszOptions);
422 throw std::runtime_error(
"unable to create dataset with driver.");
425 CPLErr err = p_dataset->SetGeoTransform(geotransform);
427 throw std::runtime_error(
"error setting geotransform.");
430 err = p_dataset->SetProjection(projection.c_str());
432 throw std::runtime_error(
"error setting projection.");
435 for (
size_t band = 0; band < bandCount; band++) {
436 GDALRasterBand *p_band = p_dataset->GetRasterBand(band + 1);
437 p_band->SetDescription(bands[band].name.c_str());
438 p_band->SetNoDataValue(bands[band].nan);
439 p_band->GetBlockSize(&bands[band].xBlockSize, &bands[band].yBlockSize);
440 bands[band].
p_band = p_band;
468 GDALDataset *p_dataset,
474 p_dataset->GetRasterXSize(),
475 p_dataset->GetRasterYSize(),
481 char **papszOptions =
nullptr;
482 std::string datapointer = std::to_string((
size_t)band.
p_buffer);
483 papszOptions = CSLSetNameValue(papszOptions,
"DATAPOINTER", datapointer.c_str());
485 err = p_dataset->AddBand(band.
type, papszOptions);
486 CSLDestroy(papszOptions);
488 throw std::runtime_error(
"unable to add band to dataset.");
491 GDALRasterBand *p_band = p_dataset->GetRasterBand(p_dataset->GetRasterCount());
492 p_band->SetNoDataValue(band.
nan);
493 p_band->SetDescription(band.
name.c_str());
539 GDALDataset *p_dataset,
541 std::string tempFolder,
543 std::vector<VRTBandDatasetInfo>& VRTBandInfo,
544 std::map<std::string, std::string>& driverOptions)
546 std::filesystem::path tmpPath = tempFolder;
547 std::filesystem::path tmpName =
"strat_breaks_" + key +
".tif";
548 tmpPath = tmpPath / tmpName;
553 bool useTiles = band.
xBlockSize != p_dataset->GetRasterXSize() &&
554 band.
yBlockSize != p_dataset->GetRasterYSize();
556 double geotransform[6];
557 CPLErr err = p_dataset->GetGeoTransform(geotransform);
559 throw std::runtime_error(
"unable to get geotransform from dataset.");
565 p_dataset->GetRasterXSize(),
566 p_dataset->GetRasterYSize(),
568 std::string(p_dataset->GetProjectionRef()),
575 GDALRasterBand *p_band = info.
p_dataset->GetRasterBand(1);
576 p_band->SetDescription(band.
name.c_str());
577 p_band->SetNoDataValue(band.
nan);
581 VRTBandInfo.push_back(info);
600 GDALDataset *p_dataset,
604 char **papszOptions =
nullptr;
605 const char *filename = info.
filename.c_str();
606 papszOptions = CSLSetNameValue(papszOptions,
"subclass",
"VRTRawRasterBand");
607 papszOptions = CSLSetNameValue(papszOptions,
"SourceFilename", filename);
609 CPLErr err = p_dataset->AddBand(band.
type, papszOptions);
610 CSLDestroy(papszOptions);
612 throw std::runtime_error(
"unable to add band to dataset.");
615 GDALRasterBand *p_VRTBand = p_dataset->GetRasterBand(p_dataset->GetRasterCount());
616 p_VRTBand->SetDescription(band.
name.c_str());
617 p_VRTBand->SetNoDataValue(band.
nan);
653 bool threaded =
true)
656 bool useBlock = xBlockSize == band.
xBlockSize &&
662 if (useBlock && read) {
664 band.
p_band->ReadBlock(xBlock, yBlock, p_buffer) :
665 band.
p_band->WriteBlock(xBlock, yBlock, p_buffer);
668 err = band.
p_band->RasterIO(
669 read ? GF_Read : GF_Write,
687 std::runtime_error(
"unable to read block from raster.") :
688 std::runtime_error(
"unable to write block to raster.");
701 OGRFeature *p_feature = OGRFeature::CreateFeature(p_layer->GetLayerDefn());
702 p_feature->SetGeometry(p_point);
703 p_layer->CreateFeature(p_feature);
704 OGRFeature::DestroyFeature(p_feature);
716addPoint(
const OGRPoint *p_point, OGRLayer *p_layer) {
717 OGRFeature *p_feature = OGRFeature::CreateFeature(p_layer->GetLayerDefn());
718 p_feature->SetGeometry(p_point);
719 p_layer->CreateFeature(p_feature);
720 OGRFeature::DestroyFeature(p_feature);
733 OGRFeature *p_feature = OGRFeature::CreateFeature(p_layer->GetLayerDefn());
734 p_feature->SetGeometry(p_point);
735 p_feature->SetField(p_field->
fname.c_str(), p_field->
fval);
736 p_layer->CreateFeature(p_feature);
737 OGRFeature::DestroyFeature(p_feature);
751 OGRFeature *p_feature = OGRFeature::CreateFeature(p_layer->GetLayerDefn());
752 p_feature->SetGeometry(p_point);
753 p_feature->SetField(p_field->
fname.c_str(), p_field->
fval);
754 p_layer->CreateFeature(p_feature);
755 OGRFeature::DestroyFeature(p_feature);
767addPoint(OGRPoint *p_point, OGRLayer *p_layer, std::vector<Field *> *p_fields) {
768 OGRFeature *p_feature = OGRFeature::CreateFeature(p_layer->GetLayerDefn());
769 p_feature->SetGeometry(p_point);
770 for (
size_t i = 0; i < p_fields->size(); i++) {
771 p_feature->SetField((*p_fields)[i]->fname.c_str(), (*p_fields)[i]->fval);
773 p_layer->CreateFeature(p_feature);
774 OGRFeature::DestroyFeature(p_feature);
787addPoint(
const OGRPoint *p_point, OGRLayer *p_layer, std::vector<Field *> *p_fields) {
788 OGRFeature *p_feature = OGRFeature::CreateFeature(p_layer->GetLayerDefn());
789 p_feature->SetGeometry(p_point);
790 for (
size_t i = 0; i < p_fields->size(); i++) {
791 p_feature->SetField((*p_fields)[i]->fname.c_str(), (*p_fields)[i]->fval);
793 p_layer->CreateFeature(p_feature);
794 OGRFeature::DestroyFeature(p_feature);
813 T x =
static_cast<T
>(IGT[0] + xCoord * IGT[1] + yCoord * IGT[2]);
814 T y =
static_cast<T
>(IGT[3] + xCoord * IGT[4] + yCoord * IGT[5]);
816 T index = y * width + x;
851 M = M + (x - M) /
static_cast<double>(k);
854 S = S + (x - M) * (x - oldM);
875 double variance = S /
static_cast<double>(k);
876 return std::sqrt(variance);
940getProbabilityMultiplier(
double width,
double height,
double pixelWidth,
double pixelHeight,
int startMult,
int numSamples,
bool useMindist,
double accessibleArea) {
941 double numer =
static_cast<double>(numSamples * startMult * (useMindist ? 3 : 1));
942 double denom = height * width;
944 if (accessibleArea != -1) {
945 double totalArea = width * pixelWidth * height * pixelHeight;
946 numer *= (totalArea / accessibleArea);
953 uint8_t bits =
static_cast<uint8_t
>(std::ceil(std::log2(denom) - std::log2(numer)));
954 return (1 << bits) - 1;
978 std::vector<bool> randVals;
979 size_t randValIndex = 0;
980 uint64_t multiplier = 0;
981 xso::xoshiro_4x64_plus *p_rng =
nullptr;
982 bool alwaysTrue =
false;
994 RandValController(
int xBlockSize,
int yBlockSize, uint64_t multiplier, xso::xoshiro_4x64_plus *p_rng) {
995 if (multiplier == 0) {
996 this->alwaysTrue =
true;
999 this->randVals.resize(xBlockSize * yBlockSize);
1000 this->randValIndex =
static_cast<size_t>(xBlockSize * yBlockSize);
1001 this->multiplier = multiplier;
1002 this->p_rng = p_rng;
1024 for (
size_t i = 0; i < randValIndex; i++) {
1025 randVals[i] = (((*p_rng)() >> 11) & multiplier) == multiplier;
1039 bool retval = randVals[randValIndex];
1050 inline std::size_t
operator()(
const std::pair<int, int> &v)
const {
1051 std::size_t h1 = std::hash<int>{}(v.first);
1052 std::size_t h2 = std::hash<int>{}(v.second);
1053 return h1 ^ (h2 + 0x9e3779b9 + (h1 << 6) + (h1 >> 2));
1061typedef boost::unordered::unordered_flat_map<std::pair<int, int>, std::vector<std::pair<double, double>>,
PointHash>
NeighborMap;
1073 int cx =
static_cast<int>(std::floor(x / mindist));
1074 int cy =
static_cast<int>(std::floor(y / mindist));
1076 for (
int dx = -1; dx <= 1; dx++) {
1077 for (
int dy = -1; dy <= 1; dy++) {
1078 std::pair<int, int> neighbor = {cx + dx, cy + dy};
1080 auto it = neighbor_map.find(neighbor);
1081 if (it == neighbor_map.end())
1084 for (
const auto &[nx, ny] : it->second) {
1087 float dist_sq = dxp * dxp + dyp * dyp;
1089 if (dist_sq < mindist_sq) {
1097 neighbor_map[{cx, cy}].emplace_back(x, y);
1109 double px = index.
x + 0.5;
1110 double py = index.
y + 0.5;
1111 double x = GT[0] + px * GT[1] + py * GT[2];
1112 double y = GT[3] + px * GT[4] + py * GT[5];
1126 double px = xs + 0.5;
1127 double py = ys + 0.5;
1128 double x = GT[0] + px * GT[1] + py * GT[2];
1129 double y = GT[3] + px * GT[4] + py * GT[5];
void calculateRandValues(void)
Definition helper.h:1019
bool next(void)
Definition helper.h:1034
RandValController(int xBlockSize, int yBlockSize, uint64_t multiplier, xso::xoshiro_4x64_plus *p_rng)
Definition helper.h:994
int64_t getCount()
Definition helper.h:885
void update(double x)
Definition helper.h:846
double getStdev()
Definition helper.h:874
double getMean()
Definition helper.h:863
boost::unordered::unordered_flat_map< std::pair< int, int >, std::vector< std::pair< double, double > >, PointHash > NeighborMap
Definition helper.h:1061
uint64_t getProbabilityMultiplier(double width, double height, double pixelWidth, double pixelHeight, int startMult, int numSamples, bool useMindist, double accessibleArea)
Definition helper.h:940
void rasterBandIO(RasterBandMetaData &band, void *p_buffer, int xBlockSize, int yBlockSize, int xBlock, int yBlock, int xValid, int yValid, bool read, bool threaded=true)
Definition helper.h:643
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
std::pair< double, double > sample_to_point(double *GT, Index &index)
Definition helper.h:1108
void setStrataPixelDependingOnType(GDALDataType type, void *p_data, size_t index, bool isNan, size_t strata)
Definition helper.h:213
void addBandToMEMDataset(GDALDataset *p_dataset, RasterBandMetaData &band)
Definition helper.h:467
T getPixelValueDependingOnType(GDALDataType type, void *p_data, size_t index)
Definition helper.h:173
void printTypeWarningsForInt32Conversion(GDALDataType type)
Definition helper.h:251
bool is_valid_sample(double x, double y, NeighborMap &neighbor_map, float mindist, float mindist_sq)
Definition helper.h:1072
T point2index(double xCoord, double yCoord, double *IGT, T width)
Definition helper.h:812
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 addPoint(OGRPoint *p_point, OGRLayer *p_layer)
Definition helper.h:700
void setStratBandTypeAndSize(size_t maxStrata, GDALDataType *p_type, size_t *p_size)
Definition helper.h:140
#define MAXINT8
Definition helper.h:27
#define MAXINT16
Definition helper.h:28
int fval
Definition helper.h:48
std::string fname
Definition helper.h:47
int x
Definition helper.h:38
int y
Definition helper.h:39
std::size_t operator()(const std::pair< int, int > &v) const
Definition helper.h:1050
GDALDataset * p_dataset
Definition helper.h:123
std::string filename
Definition helper.h:124