31#ifndef CCGL_DATA_RASTER_H
32#define CCGL_DATA_RASTER_H
58#ifndef HAS_VARIADIC_TEMPLATES
61using std::setprecision;
64#define CONST_CHARS static const char*
68using namespace utils_string;
69using namespace utils_filesystem;
70using namespace utils_array;
71using namespace utils_math;
73using namespace db_mongoc;
80namespace data_raster {
107CONST_CHARS PARAM_ABSTRACTION_TYPE_PHYSICAL =
"PHYSICAL";
110typedef std::pair<int, int> ROW_COL;
173 if (header.find(key) == header.end()) {
174#ifdef HAS_VARIADIC_TEMPLATES
175 header.emplace(key,
CVT_DBL(val));
177 header.insert(make_pair(key,
CVT_DBL(val)));
180 else { header.at(key) =
CVT_DBL(val); }
212 vector<string> content_strs;
214 if (content_strs.size() < 7) {
215 StatusMessage(
"Error: ASCII raster data requires at least 7 lines!");
218 double cellsize = -1.;
222 bool xllcorner =
false;
223 bool yllcorner =
false;
227 for (
auto iter = content_strs.begin(); iter != content_strs.end(); ++iter) {
229 if (tokens.empty()) {
continue; }
230 bool str2value =
false;
232 if (tokens.size() < 2) {
return false; }
234 if (!str2value) {
return false; }
237 if (tokens.size() < 2) {
return false; }
239 if (!str2value) {
return false; }
243 if (tokens.size() < 2) {
return false; }
244 xll =
IsDouble(tokens[1], str2value);
246 if (!str2value) {
return false; }
250 if (tokens.size() < 2) {
return false; }
251 yll =
IsDouble(tokens[1], str2value);
253 if (!str2value) {
return false; }
256 if (tokens.size() < 2) {
return false; }
257 cellsize =
IsDouble(tokens[1], str2value);
258 if (!str2value) {
return false; }
260 else if (
StringMatch(tokens[0], HEADER_RS_NODATA)) {
261 if (tokens.size() < 2) {
return false; }
262 nodata =
IsDouble(tokens[1], str2value);
263 if (!str2value) {
return false; }
266 if (rows < 0 || cols < 0) {
267 StatusMessage(
"Warning: NCOLS and NROWS should be defined first!");
270 for (
auto it_value = tokens.begin(); it_value != tokens.end(); ++it_value) {
271 double tmpv =
IsDouble(*it_value, str2value);
273 StatusMessage(
"Error: No value occurred in Raster data matrix!");
277 if (vidx == rows * cols) {
278 StatusMessage(
"Error: Count of values MUST equal to rows * cols!");
282 values[vidx++] =
static_cast<T
>(tmpv);
286 if (rows < 0 || cols < 0 || cellsize < 0 ||
292 if (xllcorner) { xll += 0.5 * cellsize; }
293 if (yllcorner) { yll += 0.5 * cellsize; }
325 std::ofstream raster_file(abs_filename.c_str(), std::ios::app | std::ios::out);
326 if (!raster_file.is_open()) {
332 for (
int i = 0; i < rows; i++) {
333 for (
int j = 0; j < cols; j++) {
334 raster_file << setprecision(6) << values[i * cols + j] <<
" ";
357 GDALRasterDSHandle po_dataset(OpenRaster(filename.c_str()));
360 if (
nullptr == po_dataset) {
364 GDALRasterBand* po_band = po_dataset->GetRasterBand(1);
365 int n_rows = po_band->GetYSize();
366 int n_cols = po_band->GetXSize();
367 int get_value_flag =
false;
368 double nodata = po_band->GetNoDataValue(&get_value_flag);
369 int approx_minmax =
false;
371 T* tmprasterdata =
nullptr;
372 bool read_as_signedbyte =
false;
373 unsigned char* uchar_data =
nullptr;
374 signed char* char_data =
nullptr;
375 vuint16_t* uint16_data =
nullptr;
376 vint16_t* int16_data =
nullptr;
377 vuint32_t* uint32_data =
nullptr;
378 vint32_t* int32_data =
nullptr;
379 vuint64_t* uint64_data =
nullptr;
380 vint64_t* int64_data =
nullptr;
381 float* float_data =
nullptr;
382 double* double_data =
nullptr;
384 switch (po_band->GetRasterDataType()) {
397 po_band->ComputeRasterMinMax(approx_minmax, minmax);
398 if ((minmax[1] <= 127 && minmax[0] < 0)
399 || (minmax[1] <= 127 && minmax[0] >= 0 && (!get_value_flag || (get_value_flag && nodata < 0)))) {
400 read_as_signedbyte =
true;
402 uchar_data =
static_cast<unsigned char*
>(CPLMalloc(
sizeof(
unsigned char) * n_cols * n_rows));
403 result = po_band->RasterIO(GF_Read, 0, 0, n_cols, n_rows, uchar_data,
404 n_cols, n_rows, GDT_Byte, 0, 0);
405 if (result != CE_None) {
406 StatusMessage(
"RaterIO trouble: " +
string(CPLGetLastErrorMsg()));
410 if (read_as_signedbyte) {
423#if GDAL_VERSION_MAJOR >= 3 && GDAL_VERSION_MINOR >= 7
425 char_data =
static_cast<signed char*
>(CPLMalloc(
sizeof(
signed char) * n_cols * n_rows));
426 result = po_band->RasterIO(GF_Read, 0, 0, n_cols, n_rows, char_data,
427 n_cols, n_rows, GDT_Int8, 0, 0);
428 if (result != CE_None) {
429 StatusMessage(
"RaterIO trouble: " +
string(CPLGetLastErrorMsg()));
439 uint16_data =
static_cast<vuint16_t*
>(CPLMalloc(
sizeof(vuint16_t) * n_cols * n_rows));
440 result = po_band->RasterIO(GF_Read, 0, 0, n_cols, n_rows, uint16_data,
441 n_cols, n_rows, GDT_UInt16, 0, 0);
442 if (result != CE_None) {
443 StatusMessage(
"RaterIO trouble: " +
string(CPLGetLastErrorMsg()));
448 CPLFree(uint16_data);
452 int16_data =
static_cast<vint16_t*
>(CPLMalloc(
sizeof(vint16_t) * n_cols * n_rows));
453 result = po_band->RasterIO(GF_Read, 0, 0, n_cols, n_rows, int16_data,
454 n_cols, n_rows, GDT_Int16, 0, 0);
455 if (result != CE_None) {
456 StatusMessage(
"RaterIO trouble: " +
string(CPLGetLastErrorMsg()));
465 uint32_data =
static_cast<vuint32_t*
>(CPLMalloc(
sizeof(vuint32_t) * n_cols * n_rows));
466 result = po_band->RasterIO(GF_Read, 0, 0, n_cols, n_rows, uint32_data,
467 n_cols, n_rows, GDT_UInt32, 0, 0);
468 if (result != CE_None) {
469 StatusMessage(
"RaterIO trouble: " +
string(CPLGetLastErrorMsg()));
474 CPLFree(uint32_data);
478 int32_data =
static_cast<vint32_t*
>(CPLMalloc(
sizeof(vint32_t) * n_cols * n_rows));
479 result = po_band->RasterIO(GF_Read, 0, 0, n_cols, n_rows, int32_data,
480 n_cols, n_rows, GDT_Int32, 0, 0);
481 if (result != CE_None) {
482 StatusMessage(
"RaterIO trouble: " +
string(CPLGetLastErrorMsg()));
490#if GDAL_VERSION_MAJOR >= 3 && GDAL_VERSION_MINOR >= 5
492 uint64_data =
static_cast<vuint64_t*
>(CPLMalloc(
sizeof(vuint64_t) * n_cols * n_rows));
493 result = po_band->RasterIO(GF_Read, 0, 0, n_cols, n_rows, uint64_data,
494 n_cols, n_rows, GDT_UInt64, 0, 0);
495 if (result != CE_None) {
496 StatusMessage(
"RaterIO trouble: " +
string(CPLGetLastErrorMsg()));
501 CPLFree(uint64_data);
505 int64_data =
static_cast<vint64_t*
>(CPLMalloc(
sizeof(vint64_t) * n_cols * n_rows));
506 result = po_band->RasterIO(GF_Read, 0, 0, n_cols, n_rows, int64_data,
507 n_cols, n_rows, GDT_Int64, 0, 0);
508 if (result != CE_None) {
509 StatusMessage(
"RaterIO trouble: " +
string(CPLGetLastErrorMsg()));
519 float_data =
static_cast<float*
>(CPLMalloc(
sizeof(
float) * n_cols * n_rows));
520 result = po_band->RasterIO(GF_Read, 0, 0, n_cols, n_rows, float_data,
521 n_cols, n_rows, GDT_Float32, 0, 0);
522 if (result != CE_None) {
523 StatusMessage(
"RaterIO trouble: " +
string(CPLGetLastErrorMsg()));
532 double_data =
static_cast<double*
>(CPLMalloc(
sizeof(
double) * n_cols * n_rows));
533 result = po_band->RasterIO(GF_Read, 0, 0, n_cols, n_rows, double_data,
534 n_cols, n_rows, GDT_Float64, 0, 0);
535 if (result != CE_None) {
536 StatusMessage(
"RaterIO trouble: " +
string(CPLGetLastErrorMsg()));
541 CPLFree(double_data);
550 if (!get_value_flag) {
555 po_dataset->GetGeoTransform(geo_trans);
564 srs = string(po_dataset->GetProjectionRef());
568 values = tmprasterdata;
585 char** papsz_options =
nullptr;
586 void* new_values =
nullptr;
587 bool recreate_flag =
true;
588 double old_nodata = header.at(HEADER_RS_NODATA);
589 bool change_nodata =
false;
590 double new_nodata = old_nodata;
591 bool convert_permit =
true;
596 recreate_flag =
false;
598 else if (outtype == tmptype && outtype !=
RDT_Int8) {
599 recreate_flag =
false;
603 new_values =
static_cast<unsigned char*
>(CPLMalloc(
sizeof(
unsigned char) * n_cols * n_rows));
604 unsigned char* values_uchar =
static_cast<unsigned char*
>(new_values);
605 if (old_nodata < 0 || old_nodata > UINT8_MAX) {
606 new_nodata = UINT8_MAX;
607 change_nodata =
true;
609 int illegal_count = 0;
610#pragma omp parallel for reduction(+:illegal_count)
611 for (
int i = 0; i < n_cols * n_rows; i++) {
612 if (
FloatEqual(values[i], old_nodata) && change_nodata) {
613 values_uchar[i] = UINT8_MAX;
616 if (values[i] < 0 || values[i] > UINT8_MAX) illegal_count += 1;
617 values_uchar[i] =
static_cast<unsigned char>(values[i]);
619 if (illegal_count > 0) convert_permit =
false;
623#if GDAL_VERSION_MAJOR < 3 || (GDAL_VERSION_MAJOR == 3 && GDAL_VERSION_MINOR < 7)
624 papsz_options = CSLSetNameValue(papsz_options,
"PIXELTYPE",
"SIGNEDBYTE");
626 new_values =
static_cast<signed char*
>(CPLMalloc(
sizeof(
signed char) * n_cols * n_rows));
627 signed char* values_char =
static_cast<signed char*
>(new_values);
628 if (old_nodata < INT8_MIN || old_nodata > INT8_MAX) {
629 new_nodata = INT8_MIN;
630 change_nodata =
true;
632 int illegal_count = 0;
633#pragma omp parallel for reduction(+:illegal_count)
634 for (
int i = 0; i < n_cols * n_rows; i++) {
635 if (
FloatEqual(values[i], old_nodata) && change_nodata) {
636 values_char[i] = INT8_MIN;
639 if (values[i] < INT8_MIN || values[i] > INT8_MAX) { illegal_count += 1; }
640 values_char[i] =
static_cast<signed char>(values[i]);
642 if (illegal_count > 0) convert_permit =
false;
645 new_values =
static_cast<vuint16_t*
>(CPLMalloc(
sizeof(vuint16_t) * n_cols * n_rows));
646 vuint16_t* values_uint16 =
static_cast<vuint16_t*
>(new_values);
647 if (old_nodata < 0 || old_nodata > UINT16_MAX) {
648 new_nodata = UINT16_MAX;
649 change_nodata =
true;
651 int illegal_count = 0;
652#pragma omp parallel for reduction(+:illegal_count)
653 for (
int i = 0; i < n_cols * n_rows; i++) {
654 if (
FloatEqual(values[i], old_nodata) && change_nodata) {
655 values_uint16[i] = UINT16_MAX;
658 if (values[i] < 0 || values[i] > UINT16_MAX) illegal_count += 1;
659 values_uint16[i] =
static_cast<vuint16_t
>(values[i]);
661 if (illegal_count > 0) convert_permit =
false;
664 new_values =
static_cast<vint16_t*
>(CPLMalloc(
sizeof(vint16_t) * n_cols * n_rows));
665 vint16_t* values_int16 =
static_cast<vint16_t*
>(new_values);
666 if (old_nodata < INT16_MIN || old_nodata > INT16_MAX) {
667 new_nodata = INT16_MIN;
668 change_nodata =
true;
670 int illegal_count = 0;
671#pragma omp parallel for reduction(+:illegal_count)
672 for (
int i = 0; i < n_cols * n_rows; i++) {
673 if (
FloatEqual(values[i], old_nodata) && change_nodata) {
674 values_int16[i] = INT16_MIN;
677 if (values[i] < INT16_MIN || values[i] > INT16_MAX) illegal_count += 1;
678 values_int16[i] =
static_cast<vint16_t
>(values[i]);
680 if (illegal_count > 0) convert_permit =
false;
683 new_values =
static_cast<vuint32_t*
>(CPLMalloc(
sizeof(vuint32_t) * n_cols * n_rows));
684 vuint32_t* values_uint32 =
static_cast<vuint32_t*
>(new_values);
685 if (old_nodata < 0 || old_nodata > UINT32_MAX) {
686 new_nodata = UINT32_MAX;
687 change_nodata =
true;
689 int illegal_count = 0;
690#pragma omp parallel for reduction(+:illegal_count)
691 for (
int i = 0; i < n_cols * n_rows; i++) {
692 if (
FloatEqual(values[i], old_nodata) && change_nodata) {
693 values_uint32[i] = UINT32_MAX;
696 if (values[i] < 0 || values[i] > UINT32_MAX) illegal_count += 1;
697 values_uint32[i] =
static_cast<vuint32_t
>(values[i]);
699 if (illegal_count > 0) convert_permit =
false;
702 new_values =
static_cast<vint32_t*
>(CPLMalloc(
sizeof(vint32_t) * n_cols * n_rows));
703 vint32_t* values_int32 =
static_cast<vint32_t*
>(new_values);
704 if (old_nodata < INT32_MIN || old_nodata > INT32_MAX) {
705 new_nodata = INT32_MIN;
706 change_nodata =
true;
708 int illegal_count = 0;
709#pragma omp parallel for reduction(+:illegal_count)
710 for (
int i = 0; i < n_cols * n_rows; i++) {
711 if (
FloatEqual(values[i], old_nodata) && change_nodata) {
712 values_int32[i] = INT32_MIN;
715 if (values[i] < INT32_MIN || values[i] > INT32_MAX) illegal_count += 1;
716 values_int32[i] =
static_cast<vint32_t
>(values[i]);
718 if (illegal_count > 0) convert_permit =
false;
720#if GDAL_VERSION_MAJOR >= 3 && GDAL_VERSION_MINOR >=5
722 new_values =
static_cast<vuint64_t*
>(CPLMalloc(
sizeof(vuint64_t) * n_cols * n_rows));
723 vuint64_t* values_uint64 =
static_cast<vuint64_t*
>(new_values);
724 if (old_nodata < 0 || old_nodata > UINT64_MAX) {
725 new_nodata = UINT64_MAX;
726 change_nodata =
true;
728 int illegal_count = 0;
729#pragma omp parallel for reduction(+:illegal_count)
730 for (
int i = 0; i < n_cols * n_rows; i++) {
731 if (
FloatEqual(values[i], old_nodata) && change_nodata) {
732 values_uint64[i] = UINT64_MAX;
735 if (values[i] < 0 || values[i] > UINT64_MAX) illegal_count += 1;
736 values_uint64[i] =
static_cast<vuint64_t
>(values[i]);
738 if (illegal_count > 0) convert_permit =
false;
741 new_values =
static_cast<vint64_t*
>(CPLMalloc(
sizeof(vint64_t) * n_cols * n_rows));
742 vint64_t* values_int64 =
static_cast<vint64_t*
>(new_values);
743 if (old_nodata < INT64_MIN || old_nodata > INT64_MAX) {
744 new_nodata = INT64_MIN;
745 change_nodata =
true;
747 int illegal_count = 0;
748#pragma omp parallel for reduction(+:illegal_count)
749 for (
int i = 0; i < n_cols * n_rows; i++) {
750 if (
FloatEqual(values[i], old_nodata) && change_nodata) {
751 values_int64[i] = INT64_MIN;
754 if (values[i] < INT64_MIN || values[i] > INT64_MAX) illegal_count += 1;
755 values_int64[i] =
static_cast<vint64_t
>(values[i]);
757 if (illegal_count > 0) convert_permit =
false;
761 new_values =
static_cast<float*
>(CPLMalloc(
sizeof(
float) * n_cols * n_rows));
762 float* values_float =
static_cast<float*
>(new_values);
763#pragma omp parallel for
764 for (
int i = 0; i < n_cols * n_rows; i++) values_float[i] = static_cast<float>(values[i]);
767 new_values =
static_cast<double*
>(CPLMalloc(
sizeof(
double) * n_cols * n_rows));
768 double* values_double =
static_cast<double*
>(new_values);
769#pragma omp parallel for
770 for (
int i = 0; i < n_cols * n_rows; i++) values_double[i] = static_cast<double>(values[i]);
773 if ((outtype ==
RDT_Unknown || (recreate_flag &&
nullptr == new_values))
774 || (!convert_permit)) {
775 cout <<
"Error: The specific raster output data type is not allowed!\n";
776 if (papsz_options !=
nullptr) { CSLDestroy(papsz_options); }
777 if (new_values !=
nullptr) { CPLFree(new_values); }
782 GDALRasterDSHandle po_dst_ds(CreateRaster(
"GTiff", filename.c_str(),
784 CvtToGDALDataType(outtype), papsz_options));
789 if (
nullptr == po_dst_ds) {
return false; }
790 GDALRasterBand* po_dst_band = po_dst_ds->GetRasterBand(1);
791 CPLErr result = CE_None;
792 if (!recreate_flag) {
793 result = po_dst_band->RasterIO(GF_Write, 0, 0, n_cols, n_rows, values,
794 n_cols, n_rows, CvtToGDALDataType(outtype), 0, 0);
797 result = po_dst_band->RasterIO(GF_Write, 0, 0, n_cols, n_rows, new_values,
798 n_cols, n_rows, CvtToGDALDataType(outtype), 0, 0);
800 if (result != CE_None ||
nullptr == po_dst_band) {
801 StatusMessage(
"RaterIO Error: " +
string(CPLGetLastErrorMsg()));
802 if (papsz_options !=
nullptr) { CSLDestroy(papsz_options); }
803 if (new_values !=
nullptr) { CPLFree(new_values); }
807 po_dst_band->SetNoDataValue(new_nodata);
816 po_dst_ds->SetGeoTransform(geo_trans);
818 po_dst_ds->SetProjection(
"");
822 if (papsz_options !=
nullptr) { CSLDestroy(papsz_options); }
823 if (new_values !=
nullptr) { CPLFree(new_values); }
851 header, opts, values);
853 StatusMessage(
"Warning: Without GDAL, ASC file will be exported as default!");
876 if (!gfs->
GetStreamData(filename, buf, length,
nullptr, &opts) ||
884 if (
nullptr != bmeta && bson_iter_init(&iter, bmeta)) {
885 while (bson_iter_next(&iter)) {
886 const char* key = bson_iter_key(&iter);
887 if (header.find(key) != header.end()) {
901 if (n_rows < 0 || n_cols < 0 || n_lyrs < 0) {
905 int value_count = n_cells * n_lyrs;
906 size_t size_dtype = length / value_count;
918 if (rstype ==
RDT_Double && size_dtype ==
sizeof(
double)) {
919 double* data_dbl =
reinterpret_cast<double*
>(buf);
923 else if (rstype ==
RDT_Float && size_dtype ==
sizeof(
float)) {
924 float* data_flt =
reinterpret_cast<float*
>(buf);
928 else if (rstype ==
RDT_Int32 && size_dtype ==
sizeof(vint32_t)) {
929 vint32_t* data_int32 =
reinterpret_cast<vint32_t*
>(buf);
933 else if (rstype ==
RDT_UInt32 && size_dtype ==
sizeof(vuint32_t)) {
934 vuint32_t* data_uint32 =
reinterpret_cast<vuint32_t*
>(buf);
938 else if (rstype ==
RDT_Int64 && size_dtype ==
sizeof(vint64_t)) {
939 vint64_t* data_int64 =
reinterpret_cast<vint64_t*
>(buf);
943 else if (rstype ==
RDT_UInt64 && size_dtype ==
sizeof(vuint64_t)) {
944 vuint64_t* data_uint64 =
reinterpret_cast<vuint64_t*
>(buf);
948 else if (rstype ==
RDT_Int16 && size_dtype ==
sizeof(vint16_t)) {
949 vint16_t* data_int16 =
reinterpret_cast<vint16_t*
>(buf);
953 else if (rstype ==
RDT_UInt16 && size_dtype ==
sizeof(vuint16_t)) {
954 vuint16_t* data_uint16 =
reinterpret_cast<vuint16_t*
>(buf);
958 else if (rstype ==
RDT_Int8 && size_dtype ==
sizeof(vint8_t)) {
959 vint8_t* data_int8 =
reinterpret_cast<vint8_t*
>(buf);
963 else if (rstype ==
RDT_UInt8 && size_dtype ==
sizeof(vuint8_t)) {
964 vuint8_t* data_uint8 =
reinterpret_cast<vuint8_t*
>(buf);
989 STRDBL_MAP& header, T* values,
const int datalength,
998 bson_t p = BSON_INITIALIZER;
1000 for (
auto iter = header.begin(); iter != header.end(); ++iter) {
1002 && std::modf(iter->second, &intpart) == 0.0) {
1005 BSON_APPEND_INT32(&p, iter->first.c_str(),
CVT_INT(iter->second));
1008 BSON_APPEND_DOUBLE(&p, iter->first.c_str(), iter->second);
1012 char* buf =
nullptr;
1013 vint buflength = -1;
1014 bool transformed =
true;
1016 if (opt_type == temp_type) {
1017 buf =
reinterpret_cast<char*
>(values);
1018 buflength = datalength *
sizeof(T);
1019 transformed =
false;
1022 vuint8_t* newdata =
nullptr;
1024 buf =
reinterpret_cast<char*
>(newdata);
1025 buflength = datalength *
sizeof(vuint8_t);
1027 vint8_t* newdata =
nullptr;
1029 buf =
reinterpret_cast<char*
>(newdata);
1030 buflength = datalength *
sizeof(vint8_t);
1032 vuint16_t* newdata =
nullptr;
1034 buf =
reinterpret_cast<char*
>(newdata);
1035 buflength = datalength *
sizeof(vuint16_t);
1037 vint16_t* newdata =
nullptr;
1039 buf =
reinterpret_cast<char*
>(newdata);
1040 buflength = datalength *
sizeof(vint16_t);
1042 vuint32_t* newdata =
nullptr;
1044 buf =
reinterpret_cast<char*
>(newdata);
1045 buflength = datalength *
sizeof(vuint32_t);
1047 vint32_t* newdata =
nullptr;
1049 buf =
reinterpret_cast<char*
>(newdata);
1050 buflength = datalength *
sizeof(vint32_t);
1052 float* newdata =
nullptr;
1054 buf =
reinterpret_cast<char*
>(newdata);
1055 buflength = datalength *
sizeof(float);
1057 double* newdata =
nullptr;
1059 buf =
reinterpret_cast<char*
>(newdata);
1060 buflength = datalength *
sizeof(double);
1067 bool gstatus =
false;
1068 while (try_times <= 3) {
1070 if (gstatus) {
break; }
1075 if (transformed) {
delete[] buf; }
1095 bool Initialization();
1097 template <
typename T>
1098 bool SetData(
const int n, T* data) {
1099 if (n !=
n_cells) {
return false; }
1100 if (
nullptr == data) {
return false; }
1102 if (
nullptr !=
data_) {
1111 template <
typename T>
1112 bool Set2DData(
const int n,
const int lyr, T** data2d) {
1113 if (n !=
n_cells) {
return false; }
1114 if (
nullptr == data2d) {
return false; }
1117 for (
int i = 0; i <
n_cells; i++) {
1118 for (
int j = 0; j <
n_lyrs; j++) {
1129 bool ReadFromMongoDB(
MongoGridFs* gfs,
const string& fname,
1132 void GetHeader(
double gxll,
double gyll,
int gnrows,
double cellsize,
1134 template <
typename T>
1135 void Output(T nodata, vector<T*>& fulldata) {
1136 if (
nullptr ==
data_ &&
nullptr ==
data2d_) {
return; }
1139 int fullsize = nrows * ncols;
1140 for (
int ilyr = 0; ilyr <
n_lyrs; ilyr++) {
1141 T* tmpdata =
nullptr;
1143 for (
int vi = 0; vi <
n_cells; vi++) {
1147 tmpdata[j] =
static_cast<T
>(
data2d_[vi][ilyr]);
1150 tmpdata[j] =
static_cast<T
>(
data_[vi]);
1153 fulldata.emplace_back(tmpdata);
1177template <
typename T,
typename MASK_T = T>
1190 clsRasterData(T* data,
int cols,
int rows, T nodata,
double dx,
double xll,
1197 clsRasterData(T* data,
int cols,
int rows, T nodata,
double dx,
double xll,
1198 double yll,
const string& srs);
1203 clsRasterData(T** data2d,
int cols,
int rows,
int nlayers, T nodata,
1210 clsRasterData(T** data2d,
int cols,
int rows,
int nlayers, T nodata,
1211 double dx,
double xll,
double yll,
const string& srs);
1224 explicit clsRasterData(
const string& filename,
bool calc_pos =
false,
1256 explicit clsRasterData(vector<string>& filenames,
bool calc_pos =
false,
1314 bool use_mask_ext =
true,
double default_value =
NODATA_VALUE,
1348 bool use_mask_ext =
true,
double default_value =
NODATA_VALUE,
1355 bool use_mask_ext =
true,
double default_value =
NODATA_VALUE,
1382 bool OutputToFile(
const string& filename,
bool out_origin =
true);
1393 const string& outname =
string(),
1394 const map<vint, vector<double> >& recls = map<vint, vector<double> >(),
1421 bool include_nodata =
true,
1422 bool out_origin =
true);
1441 bool include_nodata =
true,
1442 bool out_origin =
false,
bool out_combined =
true,
1443 const map<vint, vector<double> >& recls = map<vint, vector<double> >(),
1460 void SetValue(
int row,
int col, T value,
int lyr = 1);
1498 bool BuildSubSet(map<int, int> groups = map<int, int>());
1547 void GetStatistics(
string sindex,
int* lyrnum,
double** values);
1624 int GetCellNumber()
const {
return n_cells_; }
1626 int GetDataLength()
const {
return n_cells_ < 0 || n_lyrs_ < 0 ? -1 : n_cells_ * n_lyrs_; }
1653 int GetLayers()
const {
return n_lyrs_; }
1710 T* GetRasterDataPointer()
const {
return raster_; }
1736 T
GetValue(
int row,
int col,
int lyr = 1);
1744 void GetValue(
int row,
int col, T*& values);
1750 bool IsNoData(
const int row,
const int col,
const int lyr = 1) {
1754 bool Is2DRaster()
const {
return is_2draster; }
1765 if ((!is_2draster &&
nullptr != raster_) ||
1766 (is_2draster &&
nullptr != raster_2d_))
1768 StatusMessage(
"Error: Please initialize the raster object first.");
1776 if ((row < 0 || row >=
GetRows()) || (col < 0 || col >= GetCols())) {
1778 ", and the col must between 0 and " +
ValueToString(GetCols() - 1));
1788 if (lyr <= 0 || lyr > n_lyrs_) {
1801 if (idx < 0 || idx >= n_cells_) {
1854 void InitializeRasterClass(
bool is_2d =
false);
1859 void InitializeReadFunction(
const string& filename,
bool calc_pos =
false,
clsRasterData<MASK_T>* mask =
nullptr,
1860 bool use_mask_ext =
true,
double default_value =
NODATA_VALUE,
1874 bool ConstructFromSingleFile(
const string& filename,
bool calc_pos =
false,
clsRasterData<MASK_T>* mask =
nullptr,
1875 bool use_mask_ext =
true,
double default_value =
NODATA_VALUE,
1886 int MaskAndCalculateValidPosition();
1893 void CalculateValidPositionsFromGridData();
1898 bool PrepareCombSubsetData(T**values,
int* datalen,
int* datalyrs,
1899 bool out_origin =
false,
bool include_nodata =
true,
1900 const map<vint, vector<double> >&recls = map<vint, vector<double> >(),
1907 T** values,
int* datalen,
int* datalyrs,
1908 bool out_origin =
false,
bool include_nodata =
true,
1909 const map<vint, vector<double> >& recls = map<vint, vector<double> >(),
1915 bool OutputFullsizeToFiles(T* fullsizedata,
int fsize,
int datalyrs,
1916 const string& fullfilename,
const STRDBL_MAP& header,
1928 void AddOtherLayerRasterData(
int row,
int col,
int cellidx,
int lyr,
1934 void CheckDefaultValue() {
1936 default_value_ =
CVT_DBL(no_data_value_);
1961 double default_value_;
1981 map<string, double *> stats_2d_;
1983 clsRasterData<MASK_T>* mask_;
1985 map<int, SubsetPositions*> subset_;
1997 bool stats_calculated_;
2002#define IntRaster clsRasterData<int>
2005#define FltRaster clsRasterData<float>
2008#define DblRaster clsRasterData<double>
2011#define IntIntRaster clsRasterData<int, int>
2014#define FltIntRaster clsRasterData<float, int>
2017#define DblIntRaster clsRasterData<double, int>
2026template <
typename T,
typename MASK_T>
2027void clsRasterData<T, MASK_T>::InitializeRasterClass(
bool is_2d ) {
2037 pos_data_ =
nullptr;
2040 subset_ = map<int, SubsetPositions*>();
2042 is_2draster = is_2d;
2043 raster_2d_ =
nullptr;
2046 use_mask_ext_ =
false;
2047 stats_calculated_ =
false;
2051 initialized_ =
true;
2054template <
typename T,
typename MASK_T>
2055void clsRasterData<T, MASK_T>::InitializeReadFunction(
const string& filename,
const bool calc_pos ,
2056 clsRasterData<MASK_T>* mask ,
2057 const bool use_mask_ext ,
2058 double default_value ,
2060 if (!initialized_) { InitializeRasterClass(); }
2061 full_path_ = filename;
2063 calc_pos_ = calc_pos;
2064 use_mask_ext_ = use_mask_ext;
2065 if (
nullptr == mask_) { use_mask_ext_ =
false; }
2066 default_value_ = default_value;
2072template <
typename T,
typename MASK_T>
2074 InitializeRasterClass(is_2d);
2077template <
typename T,
typename MASK_T>
2079 double dx,
double xll,
double yll,
2080 const string& srs) {
2083 clsRasterData(data, cols, rows, nodata, dx, xll, yll, opts);
2086template <
typename T,
typename MASK_T>
2088 const double dx,
const double xll,
const double yll,
2090 InitializeRasterClass(
false);
2093 no_data_value_ = nodata;
2095 n_cells_ = cols * rows;
2107template <
typename T,
typename MASK_T>
2109 T nodata,
const double dx,
const double xll,
const double yll,
2110 const string& srs) {
2113 clsRasterData(data2d, cols, rows, nlayers, nodata, dx, xll, yll, opts);
2116template <
typename T,
typename MASK_T>
2118 T nodata,
const double dx,
const double xll,
const double yll,
2120 InitializeRasterClass(
true);
2122 raster_2d_ = data2d;
2123 no_data_value_ = nodata;
2125 n_cells_ = cols * rows;
2132 headers_[HEADER_RS_NODATA] = no_data_value_;
2137template <
typename T,
typename MASK_T>
2140 const bool use_mask_ext ,
2141 double default_value ,
2143 InitializeRasterClass();
2145 ReadFromFile(filename, calc_pos, mask, use_mask_ext, default_value, opts);
2148template <
typename T,
typename MASK_T>
2150 const bool calc_pos ,
2152 const bool use_mask_ext ,
2153 double default_value ,
2155 if (!
FileExists(filename)) {
return nullptr; }
2158 if (!rs->
ReadFromFile(filename, calc_pos, mask, use_mask_ext, default_value, opts)) {
2165template <
typename T,
typename MASK_T>
2167 const bool calc_pos ,
2169 const bool use_mask_ext ,
2170 double default_value ,
2176 if (filenames.size() == 1) {
2177 ReadFromFile(filenames[0], calc_pos, mask,
2178 use_mask_ext, default_value, opts);
2180 ReadFromFiles(filenames, calc_pos, mask,
2181 use_mask_ext, default_value, opts);
2184template <
typename T,
typename MASK_T>
2189 double default_value ,
2195 if (filenames.size() == 1) {
2197 default_value, opts);
2201 if (!rs2d->
ReadFromFiles(filenames, calc_pos, mask, use_mask_ext, default_value, opts)) {
2208template <
typename T,
typename MASK_T>
2211 InitializeRasterClass(
false);
2215 use_mask_ext_ =
true;
2219 if (n_cells_ != len) {
2220 StatusMessage(
"Input data length MUST EQUALS TO valid cell's number of mask!");
2221 initialized_ =
false;
2225 default_value_ = mask_->GetDefaultValue();
2226 CopyHeader(mask_->GetRasterHeader(), headers_);
2227 no_data_value_ =
static_cast<T
>(mask_->GetNoDataValue());
2232template <
typename T,
typename MASK_T>
2235 InitializeRasterClass(
true);
2238 use_mask_ext_ =
true;
2242 if (n_cells_ != len) {
2243 StatusMessage(
"Input data length MUST EQUALS TO valid cell's number of mask!");
2244 initialized_ =
false;
2248 CopyHeader(mask_->GetRasterHeader(), headers_);
2249 no_data_value_ =
static_cast<T
>(mask_->GetNoDataValue());
2257template <
typename T,
typename MASK_T>
2259 const bool calc_pos ,
2261 const bool use_mask_ext ,
2262 double default_value ,
2264 InitializeRasterClass();
2266 ReadFromMongoDB(gfs, remote_filename, calc_pos, mask, use_mask_ext, default_value, opts);
2269template <
typename T,
typename MASK_T>
2271 const bool calc_pos ,
2273 const bool use_mask_ext ,
2274 double default_value ,
2278 if (!rs_mongo->
ReadFromMongoDB(gfs, remote_filename, calc_pos, mask, use_mask_ext, default_value, opts)) {
2287template <
typename T,
typename MASK_T>
2289 const bool calc_pos ,
2291 const bool use_mask_ext ,
2292 double default_value ,
2294 InitializeReadFunction(filename, calc_pos, mask, use_mask_ext, default_value, opts);
2296 bool readflag =
false;
2297 string srs = string();
2299 readflag =
ReadAscFile(full_path_, headers_, raster_);
2304 StatusMessage(
"Warning: Only ASC format is supported without GDAL!");
2309 no_data_value_ =
static_cast<T
>(headers_.at(HEADER_RS_NODATA));
2312 if (rs_type_out_ == 0) {
2313 rs_type_out_ = rs_type_;
2316 CheckDefaultValue();
2318 if (n_lyrs_ < 0) { n_lyrs_ = 1; }
2319 if (is_2draster) { is_2draster =
false; }
2320 return MaskAndCalculateValidPosition() >= 0;
2325template <
typename T,
typename MASK_T>
2327 if (!core_name_.empty()) {
StatusMessage((
"Release raster: " + core_name_).c_str()); }
2329 if (
nullptr != pos_data_ && store_pos_) {
Release2DArray(pos_data_); }
2330 if (
nullptr != pos_idx_ && store_pos_) {
Release1DArray(pos_idx_); }
2331 if (
nullptr != raster_2d_ && is_2draster) {
Release2DArray(raster_2d_); }
2332 if (is_2draster && stats_calculated_) { ReleaseStatsMap2D(); }
2336template <
typename T,
typename MASK_T>
2338 if (!ValidateRasterData()) {
return false; }
2339 if (
nullptr == pos_data_ ||
nullptr == pos_idx_) {
2340 if (!SetCalcPositions()) {
return false; }
2342 if (!subset_.empty()) {
return true; }
2344 int global_ncols = GetCols();
2345 map<int, vector<int> > global_idx;
2346 for (
int vi = 0; vi < n_cells_; vi++) {
2347 T curv = GetValueByIndex(vi);
2348 if (
FloatEqual(curv, no_data_value_)) {
continue; }
2350 if (!groups.empty() && groups.find(groupv) != groups.end()) {
2351 groupv = groups.at(groupv);
2355 int currow = pos_idx_[vi] / global_ncols;
2356 int curcol = pos_idx_[vi] % global_ncols;
2357 if (subset_.find(groupv) == subset_.end()) {
2358#ifdef HAS_VARIADIC_TEMPLATES
2359 subset_.emplace(groupv,
new SubsetPositions(currow, currow, curcol, curcol));
2361 subset_.insert(make_pair(groupv,
new SubsetPositions(currow, currow, curcol, curcol)));
2365 if (currow > cursubset->
g_erow) { cursubset->
g_erow = currow; }
2366 if (currow < cursubset->g_srow) { cursubset->
g_srow = currow; }
2367 if (curcol > cursubset->
g_ecol) { cursubset->
g_ecol = curcol; }
2368 if (curcol < cursubset->g_scol) { cursubset->
g_scol = curcol; }
2369 if (global_idx.find(groupv) == global_idx.end()) {
2370#ifdef HAS_VARIADIC_TEMPLATES
2371 global_idx.emplace(groupv, vector<int>());
2373 global_idx.insert(make_pair(groupv, vector<int>()));
2376 global_idx[groupv].emplace_back(vi);
2379 for (
auto it = subset_.begin(); it != subset_.end(); ++it) {
2381 for (
auto it2 = global_idx[it->first].begin(); it2 != global_idx[it->first].end(); ++it2) {
2382 it->second->global_[it2 - global_idx[it->first].begin()] = *it2;
2385 for (
auto it = subset_.begin(); it != subset_.end(); ++it) {
2389 int nrows = it->second->g_erow - it->second->g_srow + 1;
2390 int local_ncols = it->second->g_ecol - it->second->g_scol + 1;
2391 for (
int gidx = 0; gidx < it->second->n_cells; gidx++) {
2394 int local_row = pos_idx_[it->second->global_[gidx]] / global_ncols - it->second->g_srow;
2395 int local_col = pos_idx_[it->second->global_[gidx]] % global_ncols - it->second->g_scol;
2396 it->second->local_pos_[gidx][0] = local_row;
2397 it->second->local_pos_[gidx][1] = local_col;
2398 it->second->local_posidx_[gidx] = local_row * local_ncols + local_col;
2400 it->second->alloc_ =
true;
2405template <
typename T,
typename MASK_T>
2407 if (!subset_.empty()) {
2408 for (
auto it = subset_.begin(); it != subset_.end(); ++it) {
2410 it->second =
nullptr;
2417template <
typename T,
typename MASK_T>
2419 return ReleaseSubset() && BuildSubSet(groups);
2424template <
typename T,
typename MASK_T>
2426 rs_type_out_ = type;
2430template <
typename T,
typename MASK_T>
2437template <
typename T,
typename MASK_T>
2439 if (stats_calculated_) {
return; }
2440 if (stats_.empty() || stats_2d_.empty()) {
InitialStatsMap(stats_, stats_2d_); }
2441 if (is_2draster &&
nullptr != raster_2d_) {
2442 double** derivedvs =
nullptr;
2443 BasicStatistics(raster_2d_, n_cells_, n_lyrs_, &derivedvs, no_data_value_);
2453 double* derivedv =
nullptr;
2463 stats_calculated_ =
true;
2466template <
typename T,
typename MASK_T>
2468 for (
auto it = stats_2d_.begin(); it != stats_2d_.end(); ++it) {
2469 if (
nullptr != it->second) {
2476template <
typename T,
typename MASK_T>
2478 if (is_2draster && stats_calculated_) ReleaseStatsMap2D();
2479 stats_calculated_ =
false;
2480 CalculateStatistics();
2483template <
typename T,
typename MASK_T>
2486 if (!ValidateRasterData() || !ValidateLayer(lyr)) {
2488 return CVT_DBL(default_value_);
2490 if (is_2draster &&
nullptr != raster_2d_) {
2492 auto it = stats_2d_.find(sindex);
2493 if (it != stats_2d_.end()) {
2494 if (
nullptr == it->second) {
2495 stats_calculated_ =
false;
2496 CalculateStatistics();
2498 return stats_2d_.at(sindex)[lyr - 1];
2501 return CVT_DBL(default_value_);
2504 auto it = stats_.find(sindex);
2505 if (it != stats_.end()) {
2507 CalculateStatistics();
2509 return stats_.at(sindex);
2512 return CVT_DBL(default_value_);
2515template <
typename T,
typename MASK_T>
2517 if (!is_2draster ||
nullptr != raster_2d_) {
2518 StatusMessage(
"Please initialize the raster object first.");
2524 auto it = stats_2d_.find(sindex);
2525 if (!Is2DRaster()) {
2529 if (it == stats_2d_.end()) {
2534 if (
nullptr == it->second || !stats_calculated_) {
2535 CalculateStatistics();
2537 *values = it->second;
2540template <
typename T,
typename MASK_T>
2542 if (!ValidateRasterData() || !ValidateRowCol(row, col)) {
2545 int pos_idx = GetCols() * row + col;
2546 if (!calc_pos_ ||
nullptr == pos_data_ ||
nullptr == pos_idx_) {
2558 int right = n_cells_ - 1;
2559 while (left <= right) {
2560 int middle = left + ((right - left) / 2);
2561 if (pos_idx_[middle] > pos_idx) {
2563 }
else if (pos_idx_[middle] < pos_idx) {
2572template <
typename T,
typename MASK_T>
2577template <
typename T,
typename MASK_T>
2579 if (!initialized_)
return -2;
2580 double xll_center = GetXllCenter();
2581 double yll_center = GetYllCenter();
2582 double dx = GetCellWidth();
2583 double dy = GetCellWidth();
2584 int n_rows = GetRows();
2585 int n_cols = GetCols();
2590 || n_rows < 0 || n_cols < 0) {
2595 double x_min = xll_center - dx / 2.;
2596 double x_max = x_min + dx * n_cols;
2597 if (x > x_max || x < x_min) {
2601 double y_min = yll_center - dy / 2.;
2602 double y_max = y_min + dy * n_rows;
2603 if (y > y_max || y < y_min) {
2607 int n_row =
CVT_INT((y_max - y) / dy);
2608 int n_col =
CVT_INT((x - x_min) / dx);
2610 return GetPosition(n_row, n_col);
2613template <
typename T,
typename MASK_T>
2615 if (ValidateRasterData() && !is_2draster) {
2616 *n_cells = n_cells_;
2625template <
typename T,
typename MASK_T>
2627 if (ValidateRasterData() && is_2draster) {
2628 *n_cells = n_cells_;
2639template <
typename T,
typename MASK_T>
2641 if (
nullptr != pos_data_) {
2642 *datalength = n_cells_;
2643 *positiondata = pos_data_;
2646 if (!ValidateRasterData()) {
2648 *positiondata =
nullptr;
2651 CalculateValidPositionsFromGridData();
2652 *datalength = n_cells_;
2653 *positiondata = pos_data_;
2657template <
typename T,
typename MASK_T>
2659 if (
nullptr != pos_idx_) {
2660 *datalength = n_cells_;
2661 *positiondata = pos_idx_;
2664 if (!ValidateRasterData()) {
2666 *positiondata =
nullptr;
2669 CalculateValidPositionsFromGridData();
2670 *datalength = n_cells_;
2671 *positiondata = pos_idx_;
2675template <
typename T,
typename MASK_T>
2677 return GetSrsString().c_str();
2680template <
typename T,
typename MASK_T>
2685template <
typename T,
typename MASK_T>
2687 if (options_.find(key) == options_.end()) {
2688 StatusMessage((
string(key) +
" is not existed in the options of the raster data!").c_str());
2691 return options_.at(key);
2694template <
typename T,
typename MASK_T>
2696 if (!ValidateRasterData() || !ValidateIndex(cell_index) || !ValidateLayer(lyr)) {
2697 return no_data_value_;
2700 return raster_2d_[cell_index][lyr - 1];
2702 return raster_[cell_index];
2705template <
typename T,
typename MASK_T>
2707 if (!ValidateRasterData() || !ValidateIndex(cell_index)) {
2712 if (
nullptr == values) {
2716 for (
int i = 0; i < n_lyrs_; i++) {
2717 values[i] = raster_2d_[cell_index][i];
2720 values[0] = raster_[cell_index];
2724template <
typename T,
typename MASK_T>
2726 if (!ValidateRasterData() || !ValidateRowCol(row, col) || !ValidateLayer(lyr)) {
2727 return no_data_value_;
2730 if (calc_pos_ && (
nullptr != pos_data_ ||
nullptr != pos_idx_)) {
2731 int valid_cell_index = GetPosition(row, col);
2732 if (valid_cell_index < 0) {
return no_data_value_; }
2733 return GetValueByIndex(valid_cell_index, lyr);
2736 if (is_2draster) {
return raster_2d_[row * GetCols() + col][lyr - 1]; }
2737 return raster_[row * GetCols() + col];
2740template <
typename T,
typename MASK_T>
2742 if (!ValidateRasterData() || !ValidateRowCol(row, col)) {
2747 if (
nullptr == values) {
2750 if (calc_pos_ && (
nullptr != pos_data_ ||
nullptr != pos_idx_)) {
2751 int valid_cell_index = GetPosition(row, col);
2752 if (valid_cell_index == -1) {
2753 for (
int i = 0; i < n_lyrs_; i++) {
2754 values[i] = no_data_value_;
2757 GetValueByIndex(valid_cell_index, values);
2762 for (
int i = 0; i < n_lyrs_; i++) {
2763 values[i] = raster_2d_[row * GetCols() + col][i];
2766 values[0] = raster_[row * GetCols() + col];
2771template <
typename T,
typename MASK_T>
2776 if (it != headers_.end()) { n_cells_ =
CVT_INT(it->second); }
2778 if (it != headers_.end()) { n_lyrs_ =
CVT_INT(it->second); }
2779 it = headers_.find(HEADER_RS_NODATA);
2780 if (it != headers_.end()) { no_data_value_ =
static_cast<T
>(it->second); }
2784template <
typename T,
typename MASK_T>
2786 if (!ValidateRasterData() || !ValidateRowCol(row, col) || !ValidateLayer(lyr)) {
2790 int idx = GetPosition(row, col);
2793 StatusMessage(
"Current version do not support to setting value to NoDATA location!");
2796 raster_2d_[idx][lyr - 1] = value;
2798 raster_[idx] = value;
2803template <
typename T,
typename MASK_T>
2805 if (!ValidateRasterData()) {
return false; }
2806 if (calc_pos_ && (
nullptr != pos_data_ ||
nullptr != pos_idx_)) {
2811 return MaskAndCalculateValidPosition() >= 0;
2814template <
typename T,
typename MASK_T>
2816 if (
nullptr != pos_data_) {
2817 if (len != n_cells_) {
return false; }
2826template <
typename T,
typename MASK_T>
2828 if (
nullptr != pos_idx_) {
2829 if (len != n_cells_) {
return false; }
2838template <
typename T,
typename MASK_T>
2840 if (!ValidateRasterData())
return false;
2841 if (
nullptr == mask_)
return false;
2842 if (use_mask_ext_)
return false;
2843 use_mask_ext_ =
true;
2844 return MaskAndCalculateValidPosition() >= 0;
2849template <
typename T,
typename MASK_T>
2853 if (!ValidateRasterData()) {
return false; }
2854 if (!out_origin) {
return OutputSubsetToFile(
false,
true, filename); }
2857 return OutputAscFile(abs_filename);
2861 return OutputFileByGdal(abs_filename);
2865 StatusMessage(
"Warning: Without GDAL, ASC file will be exported as default!");
2870template <
typename T,
typename MASK_T>
2872 const bool out_combined ,
2873 const string& outname ,
2874 const map<vint, vector<double> >& recls ,
2875 const double default_value ) {
2876 if (!ValidateRasterData()) {
return false; }
2877 if (subset_.empty()) {
return false; }
2878 string outpathact = outname.empty() ? full_path_ : outname;
2880 bool out_comb = out_combined;
2882 T* data1d =
nullptr;
2885 if (!PrepareCombSubsetData(&data1d, &sublen, &sublyrs,
2886 out_origin,
true, recls, default_value)) {
2893 bool combflag = OutputFullsizeToFiles(data1d, sublen / sublyrs, sublyrs,
2895 tmpheader, options_);
2901 for (
auto it = subset_.begin(); it != subset_.end(); ++it) {
2902 if (!it->second->usable) {
continue; }
2903 it->second->GetHeader(GetXllCenter(), GetYllCenter(), GetRows(),
2904 GetCellWidth(),
CVT_DBL(no_data_value_), subheader);
2905 T* tmpdata1d =
nullptr;
2908 if (!PrepareSubsetData(it->first, it->second, &tmpdata1d, &tmpdatalen, &tmplyrs,
2909 out_origin,
true, recls, default_value)) {
2914 flag = flag && OutputFullsizeToFiles(tmpdata1d, tmpdatalen / tmplyrs, tmplyrs,
2916 subheader, options_);
2922template <
typename T,
typename MASK_T>
2924 bool out_origin ,
bool include_nodata ,
2925 const map<vint, vector<double> >& recls ,
2926 double default_value ) {
2927 if (subset_.empty()) {
return false; }
2928 T* data1d =
nullptr;
2930 if (!recls.empty()) {
2931 for (
auto it = recls.begin(); it != recls.end(); ++it) {
2932 if (lyr_recls < 0) { lyr_recls =
CVT_INT(it->second.size()); }
2933 else if (lyr_recls != it->second.size()) {
2934 StatusMessage(
"Error: Reclassification layer count MUST be consistent!");
2939 int lyrs_subset = -1;
2940 for (
auto it = subset_.begin(); it != subset_.end(); ++it) {
2941 if (!it->second->usable) {
continue; }
2942 if (!(
nullptr != it->second->data_
2943 ||
nullptr != it->second->data2d_
2944 || !recls.empty())) {
2947 if (lyrs_subset < 0) { lyrs_subset = it->second->n_lyrs; }
2948 else if (it->second->n_lyrs != lyrs_subset) {
2949 StatusMessage(
"Error: Subset's layer count MUST be consistent!");
2956 if (lyr_recls > 0) { lyrs = lyr_recls; }
2959 if (lyrs < 0 && lyr_recls > 0) {
2964 StatusMessage(
"Error: Cannot determine valid layer count!");
2968 int gnrows = GetRows();
2969 int gncols = GetCols();
2971 default_value = default_value_;
2973 int gncells = include_nodata ? gnrows * gncols : n_cells_;
2974 int data_length = gncells * lyrs;
2976 for (
auto it = subset_.begin(); it != subset_.end(); ++it) {
2977 bool use_defaultv_directly =
false;
2978 if (!it->second->usable) {
2979 if (!
FloatEqual(no_data_value_, default_value)) {
2980 use_defaultv_directly =
true;
2985 for (
int vi = 0; vi < it->second->n_cells; vi++) {
2986 for (
int ilyr = 0; ilyr < lyrs; ilyr++) {
2987 int gidx = it->second->global_[vi];
2991 int tmprc = pos_idx_[gidx];
2992 if (!include_nodata) { tmprc = gidx; }
2993 if (!recls.empty()) {
2994 double uniqe_value = default_value;
2995 int recls_key = it->first;
2997 if (
nullptr != raster_) { recls_key =
CVT_INT(raster_[gidx]); }
2998 else if (
nullptr != raster_2d_) {
2999 recls_key =
CVT_INT(raster_2d_[gidx][ilyr]);
3002 if (recls.count(recls_key) > 0 && recls.at(recls_key).size() > ilyr) {
3003 uniqe_value = recls.at(recls_key).at(ilyr);
3005 data1d[tmprc * lyrs + ilyr] =
static_cast<T
>(uniqe_value);
3007 else if (use_defaultv_directly) {
3008 data1d[tmprc * lyrs + ilyr] =
static_cast<T
>(default_value);
3010 else if (!out_origin && lyrs > 1 &&
nullptr != it->second->data2d_) {
3011 data1d[tmprc * lyrs + ilyr] =
static_cast<T
>(it->second->data2d_[vi][ilyr]);
3013 else if (!out_origin && lyrs == 1 &&
nullptr != it->second->data_) {
3014 data1d[tmprc * lyrs + ilyr] =
static_cast<T
>(it->second->data_[vi]);
3017 StatusMessage(
"Error: No subset or reclassification map can be output!");
3025 *datalen = data_length;
3030template <
typename T,
typename MASK_T>
3031bool clsRasterData<T, MASK_T>::PrepareSubsetData(
const int sub_id, SubsetPositions* sub,
3032 T** values,
int* datalen,
int* datalyrs,
3033 bool out_origin ,
bool include_nodata ,
3034 const map<vint, vector<double> >& recls ,
3035 double default_value ) {
3036 if (
nullptr == sub) {
return false; }
3037 T* data1d =
nullptr;
3039 if (!recls.empty()) {
3040 for (
auto it = recls.begin(); it != recls.end(); ++it) {
3041 if (lyr_recls < 0) { lyr_recls =
CVT_INT(it->second.size()); }
3042 else if (lyr_recls != it->second.size()) {
3043 StatusMessage(
"Error: Reclassification layer count MUST be consistent!");
3051 if (lyr_recls > 0) { lyrs = lyr_recls; }
3056 StatusMessage(
"Error: Cannot determine valid layer count!");
3059 int nrows = sub->g_erow - sub->g_srow + 1;
3060 int ncols = sub->g_ecol - sub->g_scol + 1;
3062 default_value = default_value_;
3064 int ncells = include_nodata ? nrows * ncols : sub->n_cells;
3065 int data_length = ncells * lyrs;
3067 for (
int vi = 0; vi < sub->n_cells; vi++) {
3068 for (
int ilyr = 0; ilyr < lyrs; ilyr++) {
3070 int j = sub->local_posidx_[vi];
3071 int gidx = sub->global_[vi];
3072 if (!include_nodata) { j = vi; }
3073 if (!recls.empty()) {
3074 double uniqe_value = default_value;
3075 int recls_key = sub_id;
3077 if (
nullptr != raster_) { recls_key =
CVT_INT(raster_[gidx]); }
3078 else if (
nullptr != raster_2d_) {
3079 recls_key =
CVT_INT(raster_2d_[gidx][ilyr]);
3082 if (recls.count(recls_key) > 0 && recls.at(recls_key).size() > ilyr) {
3083 uniqe_value = recls.at(recls_key).at(ilyr);
3085 data1d[j * lyrs + ilyr] =
static_cast<T
>(uniqe_value);
3087 else if (out_origin && lyrs > 1 &&
nullptr != raster_2d_) {
3088 data1d[j * lyrs + ilyr] = raster_2d_[gidx][ilyr];
3090 else if (out_origin && lyrs == 1 &&
nullptr != raster_) {
3091 data1d[j * lyrs + ilyr] = raster_[gidx];
3093 else if (!out_origin && lyrs > 1 &&
nullptr != sub->data2d_) {
3094 data1d[j * lyrs + ilyr] =
static_cast<T
>(sub->data2d_[vi][ilyr]);
3096 else if (!out_origin && lyrs == 1 &&
nullptr != sub->data_) {
3097 data1d[j * lyrs + ilyr] =
static_cast<T
>(sub->data_[vi]);
3100 StatusMessage(
"Error: No subset or reclassification map can be output!");
3107 *datalen = data_length;
3112template <
typename T,
typename MASK_T>
3113bool clsRasterData<T, MASK_T>::OutputFullsizeToFiles(T* fullsizedata,
const int fsize,
const int datalyrs,
3114 const string& fullfilename,
3116 if (
nullptr == fullsizedata) {
return false; }
3117 if (datalyrs < 1) {
return false; }
3118 if (datalyrs == 1) {
3121 T* tmpdata1d =
nullptr;
3124 for (
int ilyr = 0; ilyr < datalyrs; ilyr++) {
3125 for (
int gi = 0; gi < fsize; gi++) {
3126 tmpdata1d[gi] = fullsizedata[gi * datalyrs + ilyr];
3129 header, opts, tmpdata1d);
3135template <
typename T,
typename MASK_T>
3140 int** position =
nullptr;
3141 int* position_idx =
nullptr;
3142 bool outputdirectly =
true;
3143 if ((
nullptr != pos_data_ ||
nullptr != pos_idx_)) {
3144 GetRasterPositionData(&count, &position);
3145 GetRasterPositionData(&count, &position_idx);
3146 outputdirectly =
false;
3147 assert(
nullptr != position);
3148 assert(
nullptr != position_idx);
3156 for (
int lyr = 0; lyr < n_lyrs_; lyr++) {
3159 std::ofstream raster_file(tmpfilename.c_str(), std::ios::app | std::ios::out);
3160 if (!raster_file.is_open()) {
3165 for (
int i = 0; i < rows; ++i) {
3166 for (
int j = 0; j < cols; ++j) {
3167 if (outputdirectly) {
3168 index = i * cols + j;
3169 raster_file << setprecision(6) << raster_2d_[index][lyr] <<
" ";
3172 if (index < n_cells_ && (position[index][0] == i && position[index][1] == j)) {
3173 raster_file << setprecision(6) << raster_2d_[index][lyr] <<
" ";
3175 }
else { raster_file << setprecision(6) <<
NODATA_VALUE <<
" "; }
3177 raster_file << endl;
3179 raster_file.close();
3183 std::ofstream raster_file(filename.c_str(), std::ios::app | std::ios::out);
3184 if (!raster_file.is_open()) {
3189 for (
int i = 0; i < rows; ++i) {
3190 for (
int j = 0; j < cols; ++j) {
3191 if (outputdirectly) {
3192 index = i * cols + j;
3193 raster_file << setprecision(6) << raster_[index] <<
" ";
3196 if (index < n_cells_) {
3197 if (position[index][0] == i && position[index][1] == j) {
3198 raster_file << setprecision(6) << raster_[index] <<
" ";
3200 }
else { raster_file << setprecision(6) << no_data_value_ <<
" "; }
3201 }
else { raster_file << setprecision(6) << no_data_value_ <<
" "; }
3203 raster_file << endl;
3205 raster_file.close();
3212template <
typename T,
typename MASK_T>
3215 bool outputdirectly = (
nullptr == pos_data_ ||
nullptr == pos_idx_);
3218 bool outflag =
false;
3219 T* data_1d =
nullptr;
3223 for (
int lyr = 0; lyr < n_lyrs_; lyr++) {
3225 if (outputdirectly) {
3226 if (
nullptr == data_1d) {
3229 for (
int gi = 0; gi < n_rows * n_cols; gi++) {
3230 data_1d[gi] = raster_2d_[gi][lyr];
3233 if (
nullptr == data_1d) {
3236 for (
int vi = 0; vi < n_cells_; vi++) {
3238 data_1d[pos_idx_[vi]] = raster_2d_[vi][lyr];
3249 if (outputdirectly) {
3253 for (
int vi = 0; vi < n_cells_; vi++) {
3255 data_1d[pos_idx_[vi]] = raster_[vi];
3260 if (!outflag) {
return false; }
3267template <
typename T,
typename MASK_T>
3270 bool include_nodata ,
3272 if (
nullptr == gfs) {
return false; }
3274 return OutputSubsetToMongoDB(gfs, filename, opts, include_nodata,
false,
true);
3286 bool outputdirectly =
true;
3288 int** pos =
nullptr;
3289 if ((
nullptr != pos_data_ ||
nullptr != pos_idx_) && include_nodata) {
3290 outputdirectly =
false;
3291 GetRasterPositionData(&cnt, &pos);
3293 if ((
nullptr == pos_data_ ||
nullptr == pos_idx_) && !include_nodata) {
3295 GetRasterPositionData(&cnt, &pos);
3297 int n_rows = GetRows();
3298 int n_cols = GetCols();
3299 int n_fullsize = n_rows * n_cols;
3300 if (include_nodata) {
3306 T* data_1d =
nullptr;
3307 T no_data_value = GetNoDataValue();
3309 string core_name = filename.empty() ? core_name_ : filename;
3311 if (outputdirectly) {
3312 data_1d = raster_2d_[0];
3313 datalength = n_lyrs_ * n_cells_;
3315 datalength = n_lyrs_ * n_fullsize;
3317 for (
int idx = 0; idx < n_cells_; idx++) {
3318 int rowcol_index = pos[idx][0] * n_cols + pos[idx][1];
3319 for (
int k = 0; k < n_lyrs_; k++) {
3320 data_1d[n_lyrs_ * rowcol_index + k] = raster_2d_[idx][k];
3325 if (outputdirectly) {
3327 datalength = n_cells_;
3329 datalength = n_fullsize;
3331 for (
int idx = 0; idx < n_cells_; idx++) {
3332 data_1d[pos[idx][0] * n_cols + pos[idx][1]] = raster_[idx];
3340 data_1d, datalength, options_);
3341 if (outputdirectly) {
3349template <
typename T,
typename MASK_T>
3351 const string& filename ,
3353 bool include_nodata ,
3356 const map<vint, vector<double> >& recls ,
3357 double default_value ) {
3358 if (!ValidateRasterData()) {
return false; }
3359 if (
nullptr == gfs) {
return false; }
3360 if (subset_.empty()) {
return false; }
3364 if (include_nodata) {
3377 int grows = GetRows();
3378 string outnameact = filename.empty() ? core_name_ : filename;
3379 bool out_comb = out_combined;
3381 T* data1d =
nullptr;
3384 bool flag = PrepareCombSubsetData(&data1d, &sublen, &sublyrs,
3385 out_origin, include_nodata, recls, default_value);
3391 tmpheader, data1d, sublen, options_);
3398 for (
auto it = subset_.begin(); it != subset_.end(); ++it) {
3399 if (!it->second->usable) {
continue; }
3400 it->second->GetHeader(GetXllCenter(), GetYllCenter(), grows,
3401 GetCellWidth(),
CVT_DBL(no_data_value_), subheader);
3402 T* tmpdata1d =
nullptr;
3405 if (!PrepareSubsetData(it->first, it->second, &tmpdata1d, &tmpdatalen, &tmplyrs,
3406 out_origin, include_nodata, recls, default_value)) {
3411 string tmpfname =
itoa(
CVT_VINT(it->first)) +
"_" + outnameact;
3421template <
typename T,
typename MASK_T>
3424 const bool use_mask_ext ,
3425 double default_value ,
3428 if (!initialized_) { InitializeRasterClass(); }
3430 return ConstructFromSingleFile(filename, calc_pos, mask, use_mask_ext, default_value, opts);
3433template <
typename T,
typename MASK_T>
3436 const bool use_mask_ext ,
3437 double default_value ,
3439 if (!
FilesExist(filenames)) {
return false; }
3440 n_lyrs_ =
CVT_INT(filenames.size());
3441 if (n_lyrs_ == 1) {
return ReadFromFile(filenames[0], calc_pos, mask, use_mask_ext, default_value, opts); }
3442 if (!initialized_) { InitializeRasterClass(
true); }
3445 if (!ConstructFromSingleFile(filenames[0], calc_pos, mask, use_mask_ext, default_value, opts)) {
3450 string::size_type last_underline = core_name_.find_last_of(
'_');
3451 if (last_underline == string::npos) {
3452 last_underline = core_name_.length();
3454 core_name_ = core_name_.substr(0, last_underline);
3459#pragma omp parallel for
3460 for (
int i = 0; i < n_cells_; i++) {
3461 raster_2d_[i][0] = raster_[i];
3464 int rows = GetRows();
3465 int cols = GetCols();
3467 for (
int fileidx = 1; fileidx <
CVT_INT(filenames.size()); fileidx++) {
3469 T* tmplyrdata =
nullptr;
3470 string curfilename = filenames[fileidx];
3480 StatusMessage(
"Warning: Only ASC format is supported without GDAL!");
3484 if (
nullptr != pos_data_ ||
nullptr != pos_idx_) {
3485#pragma omp parallel for
3486 for (
int i = 0; i < n_cells_; ++i) {
3489 int tmp_row = pos_idx_[i] / cols;
3490 int tmp_col = pos_idx_[i] % cols;
3491 AddOtherLayerRasterData(tmp_row, tmp_col, i, fileidx, tmpheader, tmplyrdata);
3495#pragma omp parallel for
3496 for (
int i = 0; i < rows; i++) {
3497 for (
int j = 0; j < cols; j++) {
3498 int cellidx = i * cols + j;
3499 if (
FloatEqual(no_data_value_, raster_2d_[cellidx][0])) {
3500 raster_2d_[cellidx][fileidx] = no_data_value_;
3503 AddOtherLayerRasterData(i, j, cellidx, fileidx, tmpheader, tmplyrdata);
3509 if(!is_2draster) is_2draster =
true;
3516template <
typename T,
typename MASK_T>
3518 const string& filename,
3519 const bool calc_pos ,
3521 const bool use_mask_ext ,
3522 double default_value ,
3524 InitializeReadFunction(filename, calc_pos, mask, use_mask_ext, default_value, opts);
3525 T* dbdata =
nullptr;
3538 if (!
ReadGridFsFile(gfs, filename, dbdata, header_dbl, header_str, opts_upd)) {
return false; }
3561 int fullsize = n_rows * n_cols;
3562 no_data_value_ =
static_cast<T
>(headers_.at(HEADER_RS_NODATA));
3565 if (include_nodata && n_cells_ != fullsize) {
return false; }
3566 if (n_cells_ != fullsize) { calc_pos_ =
true; }
3569 bool mask_pos_subset =
true;
3570 if (
nullptr != mask_ && calc_pos_ && use_mask_ext_ && n_cells_ == mask_->GetValidNumber()) {
3572 mask_->GetRasterPositionData(&n_cells_, &pos_data_);
3573 mask_->GetRasterPositionData(&n_cells_, &pos_idx_);
3575 map<int, SubsetPositions*>& mask_subset = mask_->GetSubset();
3576 for (
auto it = mask_subset.begin(); it != mask_subset.end(); ++it) {
3579#ifdef HAS_VARIADIC_TEMPLATES
3580 subset_.emplace(it->first, tmp);
3582 subset_.insert(make_pair(it->first, tmp));
3586 mask_pos_subset =
false;
3589 if (!include_nodata && (
nullptr == pos_data_ ||
nullptr == pos_idx_)) {
return false; }
3592 is_2draster =
false;
3593 if (include_nodata && !mask_pos_subset) {
3595#pragma omp parallel for
3596 for (
int i = 0; i < n_cells_; i++) {
3598 int tmpidx = pos_idx_[i];
3599 raster_[i] =
static_cast<T
>(dbdata[tmpidx]);
3607#pragma omp parallel for
3608 for (
int i = 0; i < n_cells_; i++) {
3610 if (include_nodata && !mask_pos_subset) {
3612 tmpidx = pos_idx_[i];
3614 for (
int j = 0; j < n_lyrs_; j++) {
3615 int idx = tmpidx * n_lyrs_ + j;
3616 raster_2d_[i][j] = dbdata[idx];
3622 CheckDefaultValue();
3623 if (include_nodata && mask_pos_subset) {
3624 return MaskAndCalculateValidPosition() >= 0;
3631template <
typename T,
typename MASK_T>
3633 const int cellidx,
const int lyr,
3636 double tmpnodata = lyrheader.at(HEADER_RS_NODATA);
3637 XY_COOR tmp_xy = GetCoordinateByRowCol(row, col);
3639 ROW_COL tmp_pos = GetPositionByCoordinate(tmp_xy.first, tmp_xy.second, &lyrheader);
3640 if (tmp_pos.first == -1 || tmp_pos.second == -1) {
3641 raster_2d_[cellidx][lyr] = no_data_value_;
3643 T tmpvalue = lyrdata[tmp_pos.first * tmpcols + tmp_pos.second];
3644 raster_2d_[cellidx][lyr] =
FloatEqual(tmpvalue, tmpnodata) ? no_data_value_ : tmpvalue;
3648template <
typename T,
typename MASK_T>
3650 InitializeRasterClass();
3654template <
typename T,
typename MASK_T>
3657 if (is_2draster &&
nullptr != raster_2d_ && n_cells_ > 0) {
3660 if (!is_2draster &&
nullptr != raster_) {
3663 if (
nullptr != pos_data_) {
3666 if (
nullptr != pos_idx_) {
3669 if (stats_calculated_) {
3670 ReleaseStatsMap2D();
3671 stats_calculated_ =
false;
3673 if (!subset_.empty()) {
3680 n_cells_ = orgraster->GetCellNumber();
3681 n_lyrs_ = orgraster->GetLayers();
3685 if (orgraster->Is2DRaster()) {
3698 if (stats_calculated_) {
3701 for (
auto iter = stats2D.begin(); iter != stats2D.end(); ++iter) {
3702 double* tmpstatvalues =
nullptr;
3704 stats_2d_.at(iter->first) = tmpstatvalues;
3708 for (
auto iter = stats.begin(); iter != stats.end(); ++iter) {
3709 stats_[iter->first] = iter->second;
3716 for (
auto it = orgraster->
GetSubset().begin(); it != orgraster->
GetSubset().end(); ++it) {
3718#ifdef HAS_VARIADIC_TEMPLATES
3719 subset_.emplace(it->first, tmp);
3721 subset_.insert(make_pair(it->first, tmp));
3727template <
typename T,
typename MASK_T>
3729#pragma omp parallel for
3730 for (
int i = 0; i < n_cells_; i++) {
3731 for (
int lyr = 0; lyr < n_lyrs_; lyr++) {
3732 bool flag = is_2draster &&
nullptr != raster_2d_
3733 ?
FloatEqual(raster_2d_[i][lyr], no_data_value_)
3735 if (!flag) {
continue; }
3736 if (is_2draster &&
nullptr != raster_2d_) {
3737 raster_2d_[i][lyr] = replacedv;
3738 }
else if (
nullptr != raster_) {
3739 raster_[i] = replacedv;
3743 no_data_value_ = replacedv;
3744 default_value_ =
CVT_DBL(replacedv);
3748template <
typename T,
typename MASK_T>
3751 for(
auto it = reclass_map.begin(); it != reclass_map.end(); ++it) {
3752#ifdef HAS_VARIADIC_TEMPLATES
3753 recls.emplace(it->first, it->second);
3755 recls.insert(make_pair(it->first, it->second));
3758 for (
int i = 0; i < n_cells_; i++) {
3759 for (
int lyr = 0; lyr < n_lyrs_; lyr++) {
3760 T curv = is_2draster &&
nullptr != raster_2d_
3763 if (recls.count(curv) < 0) {
3764#ifdef HAS_VARIADIC_TEMPLATES
3765 recls.emplace(curv, no_data_value_);
3767 recls.insert(make_pair(curv, no_data_value_));
3770 if (is_2draster &&
nullptr != raster_2d_) {
3771 raster_2d_[i][lyr] = recls.at(curv);
3772 }
else if (
nullptr != raster_) {
3773 raster_[i] = recls.at(curv);
3781template <
typename T,
typename MASK_T>
3783 return XY_COOR(GetXllCenter() + col * GetCellWidth(),
3784 GetYllCenter() + (GetRows() - row - 1) * GetCellWidth());
3787template <
typename T,
typename MASK_T>
3790 if (
nullptr == header) { header = &headers_; }
3798 double x_min = xll_center - dx / 2.;
3799 double x_max = x_min + dx * n_cols;
3801 double y_min = yll_center - dy / 2.;
3802 double y_max = y_min + dy * n_rows;
3803 if ((x > x_max || x < xll_center) || (y > y_max || y < yll_center)) {
3804 return ROW_COL(-1, -1);
3806 return ROW_COL(
CVT_INT((y_max - y) / dy),
CVT_INT((x - x_min) / dx));
3809template <
typename T,
typename MASK_T>
3812 vector<vector<T> > values_2d;
3813 vector<int> pos_rows;
3814 vector<int> pos_cols;
3818 for (
int i = 0; i < nrows; ++i) {
3819 for (
int j = 0; j < ncols; ++j) {
3820 int idx = i * ncols + j;
3823 tmp_value = raster_2d_[idx][0];
3825 tmp_value = raster_[idx];
3827 if (
FloatEqual(tmp_value,
static_cast<T
>(no_data_value_)))
continue;
3828 values.emplace_back(tmp_value);
3829 if (is_2draster && n_lyrs_ > 1) {
3830 vector<T> tmpv(n_lyrs_ - 1);
3831 for (
int lyr = 1; lyr < n_lyrs_; lyr++) {
3832 tmpv[lyr - 1] = raster_2d_[idx][lyr];
3834 values_2d.emplace_back(tmpv);
3836 pos_rows.emplace_back(i);
3837 pos_cols.emplace_back(j);
3840 vector<T>(values).swap(values);
3841 if (is_2draster && n_lyrs_ > 1) {
3842 vector<vector<T> >(values_2d).swap(values_2d);
3844 vector<int>(pos_rows).swap(pos_rows);
3845 vector<int>(pos_cols).swap(pos_cols);
3847 n_cells_ =
CVT_INT(values.size());
3860#pragma omp parallel for
3861 for (
int i = 0; i < n_cells_; ++i) {
3863 raster_2d_[i][0] = values.at(i);
3865 for (
int lyr = 1; lyr < n_lyrs_; lyr++) {
3866 raster_2d_[i][lyr] = values_2d[i][lyr - 1];
3870 raster_[i] = values.at(i);
3872 pos_data_[i][0] = pos_rows.at(i);
3873 pos_data_[i][1] = pos_cols.at(i);
3874 pos_idx_[i] = pos_rows.at(i) * ncols + pos_cols.at(i);
3879template <
typename T,
typename MASK_T>
3880int clsRasterData<T, MASK_T>::MaskAndCalculateValidPosition() {
3881 int old_fullsize = GetRows() * GetCols();
3882 if (
nullptr == mask_) {
3884 if (
nullptr == pos_data_ ||
nullptr == pos_idx_) {
3885 CalculateValidPositionsFromGridData();
3890 n_cells_ = old_fullsize;
3898 int** valid_pos =
nullptr;
3899 int mask_rows = mask_->GetRows();
3900 int mask_cols = mask_->GetCols();
3902 if (!mask_->PositionsCalculated()) { mask_->SetCalcPositions(); }
3903 mask_->GetRasterPositionData(&mask_ncells, &valid_pos);
3905 vector<T> values(mask_ncells);
3906 vector<vector<T> > values_2d(mask_ncells);
3907 vector<int> pos_rows(mask_ncells);
3908 vector<int> pos_cols(mask_ncells);
3911 int min_row = mask_rows;
3913 int min_col = mask_cols;
3914 int masked_count = 0;
3915 int matched_count = 0;
3917 for (
int i = 0; i < mask_ncells; i++) {
3918 int tmp_row = valid_pos[i][0];
3919 int tmp_col = valid_pos[i][1];
3920 XY_COOR tmp_xy = mask_->GetCoordinateByRowCol(tmp_row, tmp_col);
3921 ROW_COL tmp_pos = GetPositionByCoordinate(tmp_xy.first, tmp_xy.second);
3923 if (tmp_pos.first == -1 || tmp_pos.second == -1) {
3924 tmp_value = no_data_value_;
3925 if (is_2draster && n_lyrs_ > 1) {
3926 vector<T> tmp_values(n_lyrs_ - 1);
3927 for (
int lyr = 1; lyr < n_lyrs_; lyr++) { tmp_values[lyr - 1] = no_data_value_; }
3928 values_2d[i] = tmp_values;
3930 values[i] = tmp_value;
3931 pos_rows[i] = tmp_row;
3932 pos_cols[i] = tmp_col;
3935 tmp_value = GetValue(tmp_pos.first, tmp_pos.second, 1);
3937 if (!
FloatEqual(default_value_, no_data_value_)) {
3938 tmp_value =
static_cast<T
>(default_value_);
3939 SetValue(tmp_pos.first, tmp_pos.second, tmp_value);
3943 if (max_row < tmp_row) max_row = tmp_row;
3944 if (min_row > tmp_row) min_row = tmp_row;
3945 if (max_col < tmp_col) max_col = tmp_col;
3946 if (min_col > tmp_col) min_col = tmp_col;
3948 if (is_2draster && n_lyrs_ > 1) {
3949 vector<T> tmp_values(n_lyrs_ - 1);
3950 for (
int lyr = 1; lyr < n_lyrs_; lyr++) {
3951 tmp_values[lyr - 1] = GetValue(tmp_pos.first, tmp_pos.second, lyr + 1);
3952 if (
FloatEqual(tmp_values[lyr - 1], no_data_value_)
3953 && !
FloatEqual(default_value_, no_data_value_)) {
3954 tmp_values[lyr - 1] =
static_cast<T
>(default_value_);
3955 SetValue(tmp_pos.first, tmp_pos.second, tmp_values[lyr - 1], lyr - 1);
3958 values_2d[i] = tmp_values;
3960 values[i] = tmp_value;
3961 pos_rows[i] = tmp_row;
3962 pos_cols[i] = tmp_col;
3965 if (masked_count == 0) {
return -1; }
3966 n_cells_ = masked_count;
3969 CopyHeader(mask_->GetRasterHeader(), headers_);
3970 UpdateHeader(headers_, HEADER_RS_NODATA, no_data_value_);
3975 map<int, SubsetPositions*>& mask_subset = mask_->GetSubset();
3976 bool mask_has_subset = !mask_subset.empty();
3977 if (mask_has_subset) {
3979 for (
auto it = mask_subset.begin(); it != mask_subset.end(); ++it) {
3980 SubsetPositions* tmp =
new SubsetPositions(it->second,
true);
3981 tmp->n_lyrs = n_lyrs_;
3982#ifdef HAS_VARIADIC_TEMPLATES
3983 subset_.emplace(it->first, tmp);
3985 subset_.insert(make_pair(it->first, tmp));
3992 bool match_exactly = matched_count == mask_ncells;
3995 bool within_ext =
true;
3996 int new_rows = max_row - min_row + 1;
3997 int new_cols = max_col - min_col + 1;
3998 if (new_rows != mask_rows || new_cols != mask_cols) {
4002 assert(masked_count == mask_ncells);
4004 bool upd_header_rowcol =
false;
4005 bool recalc_pos =
false;
4006 bool upd_header_valid_num =
false;
4007 bool store_fullsize =
false;
4008 bool recalc_subset =
false;
4012 upd_header_rowcol =
false;
4013 if (use_mask_ext_) {
4015 recalc_pos = !match_exactly;
4016 upd_header_valid_num = recalc_pos;
4017 store_fullsize =
false;
4021 upd_header_valid_num =
false;
4022 store_fullsize =
false;
4028 recalc_pos = !match_exactly;
4029 upd_header_valid_num = recalc_pos;
4030 store_fullsize =
false;
4034 upd_header_valid_num =
true;
4035 store_fullsize =
false;
4041 if (use_mask_ext_) {
4042 upd_header_rowcol =
false;
4044 recalc_pos = !match_exactly;
4045 upd_header_valid_num = recalc_pos;
4046 store_fullsize =
false;
4050 upd_header_valid_num =
false;
4051 store_fullsize =
false;
4056 upd_header_rowcol =
true;
4057 upd_header_valid_num =
true;
4060 store_fullsize =
false;
4064 store_fullsize =
true;
4069 if (mask_has_subset && !match_exactly && upd_header_rowcol) {
4070 recalc_subset =
true;
4073 if (upd_header_rowcol) {
4076 headers_.at(
HEADER_RS_XLL) += min_col * mask_->GetCellWidth();
4077 headers_.at(
HEADER_RS_YLL) += (mask_rows - max_row - 1) * mask_->GetCellWidth();
4084 auto rit = pos_rows.begin();
4085 auto cit = pos_cols.begin();
4086 auto vit = values.begin();
4087 auto data2dit = values_2d.begin();
4088 for (
auto it = values.begin(); it != values.end();) {
4089 size_t idx = distance(vit, it);
4090 int tmpr = pos_rows.at(idx);
4091 int tmpc = pos_cols.at(idx);
4092 if (tmpr > max_row || tmpr < min_row || tmpc > max_col || tmpc < min_col
4093 ||
FloatEqual(
static_cast<T
>(*it), no_data_value_)) {
4094 it = values.erase(it);
4095 if (is_2draster && n_lyrs_ > 1) {
4096 values_2d.erase(data2dit + idx);
4097 data2dit = values_2d.begin();
4099 pos_cols.erase(cit + idx);
4100 pos_rows.erase(rit + idx);
4101 rit = pos_rows.begin();
4102 cit = pos_cols.begin();
4103 vit = values.begin();
4105 pos_rows[idx] -= min_row;
4106 pos_cols[idx] -= min_col;
4110 vector<T>(values).swap(values);
4111 if (is_2draster && n_lyrs_ > 1) { vector<vector<T> >(values_2d).swap(values_2d); }
4112 vector<int>(pos_rows).swap(pos_rows);
4113 vector<int>(pos_cols).swap(pos_cols);
4116 n_cells_ =
CVT_INT(values.size());
4121 for (
size_t k = 0; k < pos_rows.size(); ++k) {
4122 pos_data_[k][0] = pos_rows.at(k);
4123 pos_data_[k][1] = pos_cols.at(k);
4124 if (upd_header_rowcol) {
4125 pos_idx_[k] = pos_rows.at(k) * new_cols + pos_cols.at(k);
4127 pos_idx_[k] = pos_rows.at(k) * mask_cols + pos_cols.at(k);
4134 mask_->GetRasterPositionData(&n_cells_, &pos_data_);
4135 mask_->GetRasterPositionData(&n_cells_, &pos_idx_);
4142 assert(ValidateRasterData());
4145 if (store_fullsize) {
4146 n_cells_ = ncols * nrows;
4148 bool release_origin =
true;
4149 if (store_fullsize && old_fullsize == n_cells_) {
4150 release_origin =
false;
4152 if (release_origin) {
4153 if (is_2draster &&
nullptr != raster_2d_) {
4161 size_t synthesis_idx = 0;
4162 for (
size_t k = 0; k < pos_rows.size(); ++k) {
4164 int tmpr = pos_rows.at(k);
4165 int tmpc = pos_cols.at(k);
4166 if (store_fullsize) {
4167 if (tmpr > max_row || tmpr < min_row || tmpc > max_col || tmpc < min_col) {
4170 synthesis_idx = (tmpr - min_row) * ncols + tmpc - min_col;
4171 if (synthesis_idx > n_cells_ - 1) {
4176 raster_2d_[synthesis_idx][0] = values.at(k);
4178 for (
int lyr = 1; lyr < n_lyrs_; lyr++) {
4179 raster_2d_[synthesis_idx][lyr] = values_2d[k][lyr - 1];
4183 raster_[synthesis_idx] = values.at(k);
4188 if (upd_header_valid_num) {
4192 if (mask_has_subset) {
4193 for (
auto it = subset_.begin(); it != subset_.end();) {
4199 vector<int> globalpos;
4200 for (
int i = 0; i < it->second->n_cells; i++) {
4201 int gi = it->second->global_[i];
4202 int tmprow = valid_pos[gi][0];
4203 int tmpcol = valid_pos[gi][1];
4204 XY_COOR tmpxy = mask_->GetCoordinateByRowCol(tmprow, tmpcol);
4205 if (GetPosition(tmpxy.first, tmpxy.second) < 0) {
continue; }
4206 ROW_COL tmppos = GetPositionByCoordinate(tmpxy.first, tmpxy.second);
4207 if (IsNoData(tmppos.first, tmppos.second)) {
continue; }
4208 if (tmppos.first < srow) { srow = tmppos.first; }
4209 if (tmppos.first > erow) { erow = tmppos.first; }
4210 if (tmppos.second < scol) { scol = tmppos.second; }
4211 if (tmppos.second > ecol) { ecol = tmppos.second; }
4212 globalpos.emplace_back(GetPosition(tmppos.first, tmppos.second));
4217 subset_.erase(it++);
4220 if (recalc_subset) {
4221 it->second->g_srow = srow;
4222 it->second->g_erow = erow;
4223 it->second->g_scol = scol;
4224 it->second->g_ecol = ecol;
4225 it->second->n_cells = count;
4226 it->second->n_lyrs = n_lyrs_;
4227 int local_ncols = ecol - scol + 1;
4228 if (it->second->alloc_) {
4233 it->second->global_ =
nullptr;
4234 it->second->local_pos_ =
nullptr;
4235 it->second->local_posidx_ =
nullptr;
4236 it->second->alloc_ =
true;
4240 for (
int ii = 0; ii < count; ii++) {
4241 it->second->global_[ii] = globalpos[ii];
4244 if (
nullptr == pos_data_ ||
nullptr == pos_idx_) {
4245 local_row = globalpos[ii] / ncols - it->second->g_srow;
4246 local_col = globalpos[ii] % ncols - it->second->g_scol;
4250 local_row = pos_idx_[globalpos[ii]] / ncols - it->second->g_srow;
4251 local_col = pos_idx_[globalpos[ii]] % ncols - it->second->g_scol;
4253 it->second->local_pos_[ii][0] = local_row;
4254 it->second->local_pos_[ii][1] = local_col;
4255 it->second->local_posidx_[ii] = local_row * local_ncols + local_col;
4257 it->second->data_ =
nullptr;
4258 it->second->data2d_ =
nullptr;
4259 it->second->alloc_ =
true;
4264 if (store_fullsize || recalc_pos) {
#define CVT_INT(param)
A reference to the postfix of executable file for RELWITHDEBINFO mode.
Definition: basic.h:325
#define MISSINGFLOAT
Missing float value.
Definition: basic.h:250
#define CVT_DBL(param)
Convert to double double
Definition: basic.h:331
#define CVT_VINT(param)
Convert to 8-byte (64-bit) signed integer vint
Definition: basic.h:340
#define NODATA_VALUE
Global utility definitions.
Definition: basic.h:245
Base class for classes that cannot be copied.
Definition: basic.h:385
Subset positions of raster data.
Definition: data_raster.hpp:1085
int * global_
global position index
Definition: data_raster.hpp:1167
int * local_posidx_
local position index
Definition: data_raster.hpp:1166
double ** data2d_
valid 2d data array
Definition: data_raster.hpp:1169
int n_cells
valid cell count
Definition: data_raster.hpp:1158
int g_erow
end row in global data
Definition: data_raster.hpp:1161
bool alloc_
local_pos_ and global_ are allocated?
Definition: data_raster.hpp:1164
bool usable
flag for usable subset data
Definition: data_raster.hpp:1157
int g_ecol
end col in global data
Definition: data_raster.hpp:1163
int ** local_pos_
local position data
Definition: data_raster.hpp:1165
double * data_
valid data array
Definition: data_raster.hpp:1168
int g_srow
start row in global data
Definition: data_raster.hpp:1160
int n_lyrs
layer count
Definition: data_raster.hpp:1159
int g_scol
start col in global data
Definition: data_raster.hpp:1162
Raster data (1D and 2D) I/O class Support I/O among ASCII file, TIFF, and MongoDB database.
Definition: data_raster.hpp:1178
const STRDBL_MAP & GetRasterHeader() const
Get raster header information.
Definition: data_raster.hpp:1687
clsRasterData(bool is_2d=false)
Constructor an empty clsRasterData instance for 1D or 2D raster.
Definition: data_raster.hpp:2073
bool OutputFileByGdal(const string &filename)
Write 1D or 2D raster data into TIFF file by GDAL.
Definition: data_raster.hpp:3213
RasterDataType GetOutDataType() const
Get data type of source.
Definition: data_raster.hpp:1655
XY_COOR GetCoordinateByRowCol(int row, int col)
Calculate XY coordinates by given row and col number.
Definition: data_raster.hpp:3782
bool SetUseMaskExt()
Set the flag of use_mask_ext_ to true and recalculate positions and stored raster data if necessary.
Definition: data_raster.hpp:2839
~clsRasterData()
Destructor.
Definition: data_raster.hpp:2326
bool ReleaseSubset()
Release subsets.
Definition: data_raster.hpp:2406
bool MaskExtented() const
position data is allocated or a pointer
Definition: data_raster.hpp:1757
string GetFullFileName() const
Get full filename.
Definition: data_raster.hpp:1809
double GetCellWidth() const
Get row number.
Definition: data_raster.hpp:1629
int ** GetRasterPositionDataPointer() const
Get pointer of raster 1D data.
Definition: data_raster.hpp:1711
bool SetPositions(int len, int **pdata)
Set valid positions data, without mask raster layer.
Definition: data_raster.hpp:2815
int * GetRasterPositionIndexPointer() const
Get pointer of position data.
Definition: data_raster.hpp:1712
double GetYllCenter() const
Get Y coordinate of left lower center of raster data.
Definition: data_raster.hpp:1643
string GetCoreName() const
Get core name.
Definition: data_raster.hpp:1699
bool OutputAscFile(const string &filename)
Write 1D or 2D raster data into ASC file(s)
Definition: data_raster.hpp:3136
bool ReadFromMongoDB(MongoGridFs *gfs, const string &filename, bool calc_pos=false, clsRasterData< MASK_T > *mask=nullptr, bool use_mask_ext=true, double default_value=NODATA_VALUE, const STRING_MAP &opts=STRING_MAP())
Read raster data from MongoDB.
Definition: data_raster.hpp:3517
int GetDataLength() const
Get the first dimension size.
Definition: data_raster.hpp:1626
bool GetRasterData(int *n_cells, T **data)
Get raster data, include valid cell number and data.
Definition: data_raster.hpp:2614
bool StatisticsCalculated() const
Use mask extent or not.
Definition: data_raster.hpp:1758
string GetFilePath() const
Get full path name.
Definition: data_raster.hpp:1696
double GetRange(const int lyr=1)
Get the range of raster data.
Definition: data_raster.hpp:1578
string GetSrsString()
Get the spatial reference (char*)
Definition: data_raster.hpp:2681
void SetDataType(RasterDataType const type)
Set raster data type.
Definition: data_raster.hpp:1481
static clsRasterData< T, MASK_T > * Init(const string &filename, bool calc_pos=false, clsRasterData< MASK_T > *mask=nullptr, bool use_mask_ext=true, double default_value=NODATA_VALUE, const STRING_MAP &opts=STRING_MAP())
Validation check before the construction of clsRasterData, i.e., the raster file is existed and the d...
Definition: data_raster.hpp:2149
double GetStatistics(string sindex, int lyr=1)
Get basic statistics value Mean, Max, Min, STD, Range, etc.
Definition: data_raster.hpp:2484
void GetStd(int *lyrnum, double **values)
Get the standard derivation of 2D raster data.
Definition: data_raster.hpp:1603
clsRasterData< MASK_T > * GetMask() const
Get mask data pointer.
Definition: data_raster.hpp:1812
void SetDefaultValue(const double defaultv)
Set default value.
Definition: data_raster.hpp:1493
double GetMinimum(const int lyr=1)
Get the minimum of raster data.
Definition: data_raster.hpp:1565
bool ValidateRowCol(const int row, const int col)
Validate the input row and col.
Definition: data_raster.hpp:1775
int GetPosition(int row, int col)
Get default value.
Definition: data_raster.hpp:2541
bool OutputToMongoDB(MongoGridFs *gfs, const string &filename=string(), const STRING_MAP &opts=STRING_MAP(), bool include_nodata=true, bool out_origin=true)
Write the whole raster data to MongoDB, name format: corename__LyrNum.
Definition: data_raster.hpp:3268
const STRDBL_MAP & GetStatistics() const
Get raster statistics information.
Definition: data_raster.hpp:1690
void SetValue(int row, int col, T value, int lyr=1)
Set value to the given position and layer.
Definition: data_raster.hpp:2785
T ** Get2DRasterDataPointer() const
Get pointer of position data.
Definition: data_raster.hpp:1713
void ReleaseStatsMap2D()
Release statistics map of 2D raster data.
Definition: data_raster.hpp:2467
bool ValidateLayer(const int lyr)
Validate the input layer number.
Definition: data_raster.hpp:1787
ROW_COL GetPositionByCoordinate(double x, double y, STRDBL_MAP *header=nullptr)
Calculate position by given coordinate.
Definition: data_raster.hpp:3788
bool PositionsAllocated() const
Calculate positions or not.
Definition: data_raster.hpp:1756
void Reclassify(map< int, T > reclass_map)
classify raster
Definition: data_raster.hpp:3749
const map< string, double * > & GetStatistics2D() const
Get raster statistics information of 2D raster.
Definition: data_raster.hpp:1693
double GetAverage(const int lyr=1)
Get the average of raster data.
Definition: data_raster.hpp:1553
T GetValueByIndex(int cell_index, int lyr=1)
Get options.
Definition: data_raster.hpp:2695
void GetAverage(int *lyrnum, double **values)
Get the average of 2D raster data.
Definition: data_raster.hpp:1585
void SetDataType(const string &strtype)
Set raster data type.
Definition: data_raster.hpp:1484
bool RebuildSubSet(map< int, int > groups=map< int, int >())
Re-build subsets by given groups (cell value->group ID) or by discrete values.
Definition: data_raster.hpp:2418
const char * GetSrs()
Get pointer of raster 2D data.
Definition: data_raster.hpp:2676
int GetValidNumber(const int lyr=1)
Get the non-NoDATA cells number of the given raster layer data.
Definition: data_raster.hpp:1622
void UpdateStatistics()
Force to update basic statistics values Mean, Max, Min, STD, Range, etc.
Definition: data_raster.hpp:2477
int GetRows() const
Get column number.
Definition: data_raster.hpp:1628
void ReplaceNoData(T replacedv)
Replace NoData value by the given value.
Definition: data_raster.hpp:3728
void SetOutDataType(RasterDataType type)
Set output raster data type.
Definition: data_raster.hpp:2425
T GetNoDataValue() const
Get data type of output.
Definition: data_raster.hpp:1656
map< int, SubsetPositions * > & GetSubset()
Get subset.
Definition: data_raster.hpp:1673
RasterDataType GetDataType() const
Get layer number.
Definition: data_raster.hpp:1654
bool ReadFromFiles(vector< string > &filenames, bool calc_pos=false, clsRasterData< MASK_T > *mask=nullptr, bool use_mask_ext=true, double default_value=NODATA_VALUE, const STRING_MAP &opts=STRING_MAP())
Read raster data from two or more files, mask data is optional.
Definition: data_raster.hpp:3434
bool OutputToFile(const string &filename, bool out_origin=true)
Write the whole raster to raster file, if 2D raster, output name will be corename_LyrNum.
Definition: data_raster.hpp:2850
void GetValidNumber(int *lyrnum, double **values)
Get the non-NoDATA number of 2D raster data.
Definition: data_raster.hpp:1615
double GetMaximum(const int lyr=1)
Get the maximum of raster data.
Definition: data_raster.hpp:1559
void Copy(clsRasterData< T, MASK_T > *orgraster)
Copy clsRasterData object.
Definition: data_raster.hpp:3655
bool OutputSubsetToFile(bool out_origin=false, bool out_combined=true, const string &outname=string(), const map< vint, vector< double > > &recls=map< vint, vector< double > >(), double default_value=NODATA_VALUE)
Write one or more raster's subset to files, default name format: corename_SubID_LyrNum.
Definition: data_raster.hpp:2871
bool ValidateIndex(const int idx)
Validate the input index.
Definition: data_raster.hpp:1800
double GetXllCenter() const
Get cell size.
Definition: data_raster.hpp:1632
void GetRange(int *lyrnum, double **values)
Get the range of 2D raster data.
Definition: data_raster.hpp:1609
double GetDefaultValue() const
Get NoDATA value.
Definition: data_raster.hpp:1657
const STRING_MAP & GetOptions() const
Get option by key, including the spatial reference by "SRS".
Definition: data_raster.hpp:1717
bool Get2DRasterData(int *n_cells, int *n_lyrs, T ***data)
Get 2D raster data, include valid cell number of each layer, layer number, and data.
Definition: data_raster.hpp:2626
T GetValue(int row, int col, int lyr=1)
Get raster data via row and col The default lyr is 1, which means the 1D raster data,...
Definition: data_raster.hpp:2725
string GetOption(const char *key)
Get the spatial reference (string)
Definition: data_raster.hpp:2686
void CalculateStatistics()
Calculate basic statistics values in one time Mean, Max, Min, STD, Range, etc.
Definition: data_raster.hpp:2438
bool IsNoData(const int row, const int col, const int lyr=1)
Check if the raster data is NoData via row and col The default lyr is 1, which means the 1D raster da...
Definition: data_raster.hpp:1750
void GetMinimum(int *lyrnum, double **values)
Get the minimum of 2D raster data.
Definition: data_raster.hpp:1597
bool PositionsCalculated() const
Is 2D raster data?
Definition: data_raster.hpp:1755
bool Initialized() const
Basic statistics calculated?
Definition: data_raster.hpp:1759
bool ValidateRasterData()
Instance of clsRasterData initialized?
Definition: data_raster.hpp:1764
bool OutputSubsetToMongoDB(MongoGridFs *gfs, const string &filename=string(), const STRING_MAP &opts=STRING_MAP(), bool include_nodata=true, bool out_origin=false, bool out_combined=true, const map< vint, vector< double > > &recls=map< vint, vector< double > >(), double default_value=NODATA_VALUE)
Write one or more raster's subset to MongoDB,.
Definition: data_raster.hpp:3350
double GetStd(const int lyr=1)
Get the stand derivation of raster data.
Definition: data_raster.hpp:1571
void SetCoreName(const string &name)
Set new core file name.
Definition: data_raster.hpp:1455
void GetMaximum(int *lyrnum, double **values)
Get the maximum of 2D raster data.
Definition: data_raster.hpp:1591
bool SetCalcPositions()
Set the flag of calc_pos_ to true and recalculate positions and stored raster data if necessary.
Definition: data_raster.hpp:2804
bool BuildSubSet(map< int, int > groups=map< int, int >())
Build subsets by given groups (cell value->group ID) or by discrete values (default)
Definition: data_raster.hpp:2337
bool ReadFromFile(const string &filename, bool calc_pos=false, clsRasterData< MASK_T > *mask=nullptr, bool use_mask_ext=true, double default_value=NODATA_VALUE, const STRING_MAP &opts=STRING_MAP())
Read raster data from file, mask data is optional.
Definition: data_raster.hpp:3422
void GetRasterPositionData(int *datalength, int ***positiondata)
Get position index data and the data length.
Definition: data_raster.hpp:2640
A simple wrapper of the class of MongoDB database mongoc_gridfs_t.
Definition: db_mongoc.h:141
bool RemoveFile(string const &gfilename, mongoc_gridfs_t *gfs=NULL, STRING_MAP opts=STRING_MAP())
Remove GridFS all matching files and their data chunks.
Definition: db_mongoc.cpp:338
bool GetStreamData(string const &gfilename, char *&databuf, vint &datalength, mongoc_gridfs_t *gfs=NULL, const STRING_MAP *opts=nullptr)
Get stream data of a given GridFS file name.
Definition: db_mongoc.cpp:416
bool WriteStreamData(const string &gfilename, char *&buf, vint length, const bson_t *p, mongoc_gridfs_t *gfs=NULL)
Write stream data to a GridFS file.
Definition: db_mongoc.cpp:447
bson_t * GetFileMetadata(string const &gfilename, mongoc_gridfs_t *gfs=NULL, STRING_MAP opts=STRING_MAP())
Get metadata of a given GridFS file name, remember to destory bson_t after use.
Definition: db_mongoc.cpp:396
#define CONST_CHARS
const string
Definition: data_raster.hpp:64
Simple wrappers of the API of MongoDB C driver mongo-c-driver, see MongoDB C Driver for more informat...
Simple wrappers of GDAL API that compatible with all versions.
void UpdateStrHeader(STRING_MAP &strheader, const string &key, const string &val)
Update header information in string.
Definition: data_raster.cpp:155
CONST_CHARS HEADER_INC_NODATA
Desired output data type of raster.
Definition: data_raster.hpp:94
bool WriteStreamDataAsGridfs(MongoGridFs *gfs, const string &filename, STRDBL_MAP &header, T *values, const int datalength, const STRING_MAP &opts=STRING_MAP())
Write array data (both valid and full-sized raster data) as GridFS file.
Definition: data_raster.hpp:988
bool ReadRasterFileByGdal(const string &filename, STRDBL_MAP &header, T *&values, RasterDataType &in_type, string &srs)
Read single raster file by GDAL.
Definition: data_raster.hpp:354
bool WriteSingleGeotiff(const string &filename, const STRDBL_MAP &header, const STRING_MAP &opts, T *values)
Write single geotiff file If the file exists, delete it first.
Definition: data_raster.hpp:581
STRING_MAP InitialStrHeader()
Initialize header information in string.
Definition: data_raster.cpp:137
bool WriteRasterToFile(const string &filename, const STRDBL_MAP &header, const STRING_MAP &opts, T *values)
Write single raster file, if the file exists, delete it first.
Definition: data_raster.hpp:838
CONST_CHARS STATS_RS_MEAN
Valid cell number.
Definition: data_raster.hpp:97
CONST_CHARS HEADER_RS_CELLSNUM
Layers number.
Definition: data_raster.hpp:90
CONST_CHARS HEADER_RS_PARAM_ABSTRACTION_TYPE
GeoTIFF extension.
Definition: data_raster.hpp:105
CONST_CHARS HEADER_RS_YLL
X coordinate value of left low center.
Definition: data_raster.hpp:83
CONST_CHARS STATS_RS_VALIDNUM
Mask layer's name if only store valid values.
Definition: data_raster.hpp:96
RasterDataType
Coordinate pair.
Definition: data_raster.hpp:116
@ RDT_UInt16
GDT_UInt16.
Definition: data_raster.hpp:120
@ RDT_Int32
GDT_Int32.
Definition: data_raster.hpp:123
@ RDT_UInt32
GDT_UInt32.
Definition: data_raster.hpp:122
@ RDT_Int64
GDT_Int64, GDAL>=3.5.
Definition: data_raster.hpp:125
@ RDT_Float
GDT_Float32.
Definition: data_raster.hpp:126
@ RDT_UInt64
GDT_UInt64, GDAL>=3.5.
Definition: data_raster.hpp:124
@ RDT_Double
GDT_Float64.
Definition: data_raster.hpp:127
@ RDT_Int16
GDT_Int16.
Definition: data_raster.hpp:121
@ RDT_Unknown
GDT_Unknown.
Definition: data_raster.hpp:117
@ RDT_Int8
GDT_Int8, GDAL>=3.7.
Definition: data_raster.hpp:119
@ RDT_UInt8
GDT_Byte.
Definition: data_raster.hpp:118
void CopyHeader(const STRDBL_MAP &refers, STRDBL_MAP &dst)
Copy header information from one to another.
Definition: data_raster.cpp:121
bool WriteSingleAsc(const string &filename, const STRDBL_MAP &header, T *values)
Write raster data as a single ASC file.
Definition: data_raster.hpp:320
CONST_CHARS GTiffExtension
ASCII extension.
Definition: data_raster.hpp:103
STRDBL_MAP InitialHeader()
Initialize header information in double.
Definition: data_raster.cpp:105
double DefaultNoDataByType(const RasterDataType type)
Default NoData value by data type.
Definition: data_raster.cpp:62
CONST_CHARS HEADER_RS_DATATYPE
SRS.
Definition: data_raster.hpp:92
CONST_CHARS STATS_RS_MIN
Mean value.
Definition: data_raster.hpp:98
RasterDataType TypeToRasterDataType(const std::type_info &t)
Convert C++ data type to RasterDataType.
Definition: data_raster.cpp:48
CONST_CHARS HEADER_RS_LAYERS
Cell size (length)
Definition: data_raster.hpp:89
CONST_CHARS STATS_RS_RANGE
Standard derivation value.
Definition: data_raster.hpp:101
CONST_CHARS ASCIIExtension
Range value.
Definition: data_raster.hpp:102
CONST_CHARS HEADER_RSOUT_DATATYPE
Data type of original raster.
Definition: data_raster.hpp:93
CONST_CHARS HEADER_RS_SRS
Number of the first layer's valid cells.
Definition: data_raster.hpp:91
void InitialStatsMap(STRDBL_MAP &stats, map< string, double * > &stats2d)
Initialize statistics values for 1D and 2D raster data.
Definition: data_raster.cpp:173
bool WriteAscHeaders(const string &filename, const STRDBL_MAP &header)
Write raster header information into a ASC file.
Definition: data_raster.cpp:189
CONST_CHARS STATS_RS_STD
Maximum value.
Definition: data_raster.hpp:100
CONST_CHARS HEADER_RS_CELLSIZE
Column number.
Definition: data_raster.hpp:88
RasterDataType StringToRasterDataType(const string &stype)
Convert string to RasterDataType.
Definition: data_raster.cpp:32
string RasterDataTypeToString(const int type)
Common functions independent to clsRasterData.
Definition: data_raster.cpp:16
CONST_CHARS HEADER_RS_YLLCOR
X coordinate value of left low center.
Definition: data_raster.hpp:85
CONST_CHARS PARAM_ABSTRACTION_TYPE_CONEPTUAL
spatial parameter type, physical or conceptual
Definition: data_raster.hpp:106
CONST_CHARS HEADER_MASK_NAME
Include nodata ("TRUE") or not ("FALSE"), for DB only.
Definition: data_raster.hpp:95
CONST_CHARS STATS_RS_MAX
Minimum value.
Definition: data_raster.hpp:99
std::pair< double, double > XY_COOR
Row and Col pair.
Definition: data_raster.hpp:111
void UpdateHeader(STRDBL_MAP &header, const string &key, T val)
Update value in header information.
Definition: data_raster.hpp:172
bool ReadGridFsFile(MongoGridFs *gfs, const string &filename, T *&data, STRDBL_MAP &header, STRING_MAP &header_str, const STRING_MAP &opts)
Read GridFs file from MongoDB.
Definition: data_raster.hpp:869
CONST_CHARS HEADER_RS_NCOLS
Rows number.
Definition: data_raster.hpp:87
CONST_CHARS HEADER_RS_XLLCOR
Y coordinate value of left low center.
Definition: data_raster.hpp:84
CONST_CHARS HEADER_RS_NROWS
Y coordinate value of left low center.
Definition: data_raster.hpp:86
bool ReadAscFile(const string &filename, STRDBL_MAP &header, T *&values)
Read raster data from ASC file, the simply usage.
Definition: data_raster.hpp:210
RasterDataType RasterDataTypeInOptionals(const STRING_MAP &opts)
Get output raster data type from optional inputs.
Definition: data_raster.cpp:166
CONST_CHARS HEADER_RS_XLL
NoData value.
Definition: data_raster.hpp:82
void AppendStringOptionsToBson(bson_t *bson_opts, const STRING_MAP &opts, const string &prefix)
Append options to bson_t
Definition: db_mongoc.cpp:486
string GetStringFromBsonIterator(bson_iter_t *iter)
Get String from the iterator (bson_iter_t) of bson_t
Definition: db_mongoc.cpp:508
bool GetNumericFromBsonIterator(bson_iter_t *iter, T &numericvalue)
Get numeric value from the iterator (bson_iter_t) of bson_taccording to a given key.
Definition: db_mongoc.h:192
void Release1DArray(T *&data)
Release DT_Array1D data.
Definition: utils_array.h:476
bool Initialize1DArray(int row, T *&data, INI_T init_value)
Initialize DT_Array1D data.
Definition: utils_array.h:344
bool Initialize2DArray(int row, int col, T **&data, INI_T init_value)
Initialize DT_Array2D data.
Definition: utils_array.h:394
void Release2DArray(T **&data)
Release DT_Array2D data.
Definition: utils_array.h:484
bool FileExists(string const &filename)
Return a flag indicating if the given file exists.
Definition: utils_filesystem.cpp:23
string GetSuffix(string const &full_filename)
Return the suffix of a given file's path without dot, e.g., "tif", "asc".
Definition: utils_filesystem.cpp:312
string GetAbsolutePath(string const &full_filename)
Return the absolute file path from a given file path.
Definition: utils_filesystem.cpp:284
bool PathExists(string const &fullpath)
Return a flag indicating if the given path (directory or file) exists.
Definition: utils_filesystem.cpp:43
string AppendCoreFileName(string const &full_filename, string const &endstr, char deli)
Append a given string to the core filename.
Definition: utils_filesystem.cpp:329
string GetPathFromFullName(string const &full_filename)
Get Path From full file path string.
Definition: utils_filesystem.cpp:351
string ReplaceSuffix(string const &full_filename, string const &new_suffix)
Replace the suffix by a given suffix.
Definition: utils_filesystem.cpp:321
string GetCoreFileName(string const &full_filename)
Return the file name from a given file's path.
Definition: utils_filesystem.cpp:297
string PrefixCoreFileName(string const &full_filename, string const &prestr, char deli)
Add a prefix to the core filename.
Definition: utils_filesystem.cpp:340
bool FilesExist(vector< string > &filenames)
Return a flag indicating if given files exist.
Definition: utils_filesystem.cpp:35
bool MakeDirectory(const string &dirpath)
Make directory if not exists.
Definition: utils_filesystem.cpp:140
bool LoadPlainTextFile(const string &filepath, vector< string > &content_strs)
Load short plain text file as string vector, ignore comments begin with '#' and empty lines.
Definition: utils_filesystem.cpp:373
void BasicStatistics(const T *values, int num, double **derivedvalues, T exclude=static_cast< T >(NODATA_VALUE))
calculate basic statistics at one time_funcs
Definition: utils_math.h:416
bool FloatEqual(T1 v1, T2 v2)
Whether v1 is equal to v2.
Definition: utils_math.h:145
string ValueToString(const T &val)
Convert value to string.
Definition: utils_string.h:88
void CopyStringMap(const STRING_MAP &in_opts, STRING_MAP &out_opts)
Copy string map.
Definition: utils_string.cpp:78
void UpdateStringMap(STRING_MAP &opts, const string &key, const string &value)
Add or modify element in a string map.
Definition: utils_string.cpp:94
string itoa(vint number)
Convert a signed integer to a string.
Definition: utils_string.cpp:162
vint IsInt(const string &num_str, bool &success)
Check if a string is an signed integer, if ture, return the converted integer.
Definition: utils_string.cpp:260
string GetUpper(const string &str)
Get Uppercase of given string.
Definition: utils_string.cpp:16
vector< string > SplitString(const string &item, const char delimiter)
Splits the given string based on the given delimiter.
Definition: utils_string.cpp:35
bool StringMatch(const char *a, const char *b)
Match char ignore cases.
Definition: utils_string.cpp:61
double IsDouble(const string &num_str, bool &success)
Convert an Ansi string to 64-bits floating point number.
Definition: utils_string.cpp:316
Common Cross-platform Geographic Library (CCGL)
Definition: basic.cpp:17
std::map< string, string > STRING_MAP
Map of string key and string value.
Definition: basic.h:349
void StatusMessage(const char *msg)
Print status messages for Debug.
Definition: basic.cpp:136
std::map< string, double > STRDBL_MAP
Map of string key and double value.
Definition: basic.h:352
void SleepMs(const int millisecs)
Sleep milliseconds.
Definition: basic.h:491
Template functions to initialize and release arrays.
File system related functions in CCGL.
Useful math equations in CCGL.
Handling string related issues in CCGL.