31#ifndef CCGL_DATA_RASTER_H
32#define CCGL_DATA_RASTER_H
51#include "cpl_string.h"
52#include "ogr_spatialref.h"
67#ifndef HAS_VARIADIC_TEMPLATES
70using std::setprecision;
73#define CONST_CHARS static const char*
77using namespace utils_string;
78using namespace utils_filesystem;
79using namespace utils_array;
80using namespace utils_math;
82using namespace db_mongoc;
89namespace data_raster {
178 if (header.find(key) == header.end()) {
179#ifdef HAS_VARIADIC_TEMPLATES
180 header.emplace(key,
CVT_DBL(val));
182 header.insert(make_pair(key,
CVT_DBL(val)));
185 else { header.at(key) =
CVT_DBL(val); }
217 vector<string> content_strs;
219 if (content_strs.size() < 7) {
220 StatusMessage(
"Error: ASCII raster data requires at least 7 lines!");
223 double cellsize = -1.;
227 bool xllcorner =
false;
228 bool yllcorner =
false;
232 for (
auto iter = content_strs.begin(); iter != content_strs.end(); ++iter) {
234 if (tokens.empty()) {
continue; }
235 bool str2value =
false;
237 if (tokens.size() < 2) {
return false; }
239 if (!str2value) {
return false; }
242 if (tokens.size() < 2) {
return false; }
244 if (!str2value) {
return false; }
248 if (tokens.size() < 2) {
return false; }
249 xll =
IsDouble(tokens[1], str2value);
251 if (!str2value) {
return false; }
255 if (tokens.size() < 2) {
return false; }
256 yll =
IsDouble(tokens[1], str2value);
258 if (!str2value) {
return false; }
261 if (tokens.size() < 2) {
return false; }
262 cellsize =
IsDouble(tokens[1], str2value);
263 if (!str2value) {
return false; }
265 else if (
StringMatch(tokens[0], HEADER_RS_NODATA)) {
266 if (tokens.size() < 2) {
return false; }
267 nodata =
IsDouble(tokens[1], str2value);
268 if (!str2value) {
return false; }
271 if (rows < 0 || cols < 0) {
272 StatusMessage(
"Warning: NCOLS and NROWS should be defined first!");
275 for (
auto it_value = tokens.begin(); it_value != tokens.end(); ++it_value) {
276 double tmpv =
IsDouble(*it_value, str2value);
278 StatusMessage(
"Error: No value occurred in Raster data matrix!");
282 if (vidx == rows * cols) {
283 StatusMessage(
"Error: Count of values MUST equal to rows * cols!");
287 values[vidx++] =
static_cast<T
>(tmpv);
291 if (rows < 0 || cols < 0 || cellsize < 0 ||
297 if (xllcorner) { xll += 0.5 * cellsize; }
298 if (yllcorner) { yll += 0.5 * cellsize; }
330 std::ofstream raster_file(abs_filename.c_str(), std::ios::app | std::ios::out);
331 if (!raster_file.is_open()) {
337 for (
int i = 0; i < rows; i++) {
338 for (
int j = 0; j < cols; j++) {
339 raster_file << setprecision(6) << values[i * cols + j] <<
" ";
362 GDALDataset* po_dataset =
static_cast<GDALDataset*
>(GDALOpen(filename.c_str(),
364 if (
nullptr == po_dataset) {
368 GDALRasterBand* po_band = po_dataset->GetRasterBand(1);
369 int n_rows = po_band->GetYSize();
370 int n_cols = po_band->GetXSize();
371 int get_value_flag =
false;
372 double nodata = po_band->GetNoDataValue(&get_value_flag);
373 int approx_minmax =
false;
375 T* tmprasterdata =
nullptr;
376 bool read_as_signedbyte =
false;
377 unsigned char* uchar_data =
nullptr;
378 signed char* char_data =
nullptr;
379 vuint16_t* uint16_data =
nullptr;
380 vint16_t* int16_data =
nullptr;
381 vuint32_t* uint32_data =
nullptr;
382 vint32_t* int32_data =
nullptr;
383 vuint64_t* uint64_data =
nullptr;
384 vint64_t* int64_data =
nullptr;
385 float* float_data =
nullptr;
386 double* double_data =
nullptr;
388 switch (po_band->GetRasterDataType()) {
401 po_band->ComputeRasterMinMax(approx_minmax, minmax);
402 if ((minmax[1] <= 127 && minmax[0] < 0)
403 || (minmax[1] <= 127 && minmax[0] >= 0 && (!get_value_flag || (get_value_flag && nodata < 0)))) {
404 read_as_signedbyte =
true;
406 uchar_data =
static_cast<unsigned char*
>(CPLMalloc(
sizeof(
unsigned char) * n_cols * n_rows));
407 result = po_band->RasterIO(GF_Read, 0, 0, n_cols, n_rows, uchar_data,
408 n_cols, n_rows, GDT_Byte, 0, 0);
409 if (result != CE_None) {
410 StatusMessage(
"RaterIO trouble: " +
string(CPLGetLastErrorMsg()));
411 GDALClose(po_dataset);
414 if (read_as_signedbyte) {
427#if GDAL_VERSION_MAJOR >= 3 && GDAL_VERSION_MINOR >= 7
429 char_data =
static_cast<signed char*
>(CPLMalloc(
sizeof(
signed char) * n_cols * n_rows));
430 result = po_band->RasterIO(GF_Read, 0, 0, n_cols, n_rows, char_data,
431 n_cols, n_rows, GDT_Int8, 0, 0);
432 if (result != CE_None) {
433 StatusMessage(
"RaterIO trouble: " +
string(CPLGetLastErrorMsg()));
434 GDALClose(po_dataset);
443 uint16_data =
static_cast<vuint16_t*
>(CPLMalloc(
sizeof(vuint16_t) * n_cols * n_rows));
444 result = po_band->RasterIO(GF_Read, 0, 0, n_cols, n_rows, uint16_data,
445 n_cols, n_rows, GDT_UInt16, 0, 0);
446 if (result != CE_None) {
447 StatusMessage(
"RaterIO trouble: " +
string(CPLGetLastErrorMsg()));
448 GDALClose(po_dataset);
452 CPLFree(uint16_data);
456 int16_data =
static_cast<vint16_t*
>(CPLMalloc(
sizeof(vint16_t) * n_cols * n_rows));
457 result = po_band->RasterIO(GF_Read, 0, 0, n_cols, n_rows, int16_data,
458 n_cols, n_rows, GDT_Int16, 0, 0);
459 if (result != CE_None) {
460 StatusMessage(
"RaterIO trouble: " +
string(CPLGetLastErrorMsg()));
461 GDALClose(po_dataset);
469 uint32_data =
static_cast<vuint32_t*
>(CPLMalloc(
sizeof(vuint32_t) * n_cols * n_rows));
470 result = po_band->RasterIO(GF_Read, 0, 0, n_cols, n_rows, uint32_data,
471 n_cols, n_rows, GDT_UInt32, 0, 0);
472 if (result != CE_None) {
473 StatusMessage(
"RaterIO trouble: " +
string(CPLGetLastErrorMsg()));
474 GDALClose(po_dataset);
478 CPLFree(uint32_data);
482 int32_data =
static_cast<vint32_t*
>(CPLMalloc(
sizeof(vint32_t) * n_cols * n_rows));
483 result = po_band->RasterIO(GF_Read, 0, 0, n_cols, n_rows, int32_data,
484 n_cols, n_rows, GDT_Int32, 0, 0);
485 if (result != CE_None) {
486 StatusMessage(
"RaterIO trouble: " +
string(CPLGetLastErrorMsg()));
487 GDALClose(po_dataset);
494#if GDAL_VERSION_MAJOR >= 3 && GDAL_VERSION_MINOR >= 5
496 uint64_data =
static_cast<vuint64_t*
>(CPLMalloc(
sizeof(vuint64_t) * n_cols * n_rows));
497 result = po_band->RasterIO(GF_Read, 0, 0, n_cols, n_rows, uint64_data,
498 n_cols, n_rows, GDT_UInt64, 0, 0);
499 if (result != CE_None) {
500 StatusMessage(
"RaterIO trouble: " +
string(CPLGetLastErrorMsg()));
501 GDALClose(po_dataset);
505 CPLFree(uint64_data);
509 int64_data =
static_cast<vint64_t*
>(CPLMalloc(
sizeof(vint64_t) * n_cols * n_rows));
510 result = po_band->RasterIO(GF_Read, 0, 0, n_cols, n_rows, int64_data,
511 n_cols, n_rows, GDT_Int64, 0, 0);
512 if (result != CE_None) {
513 StatusMessage(
"RaterIO trouble: " +
string(CPLGetLastErrorMsg()));
514 GDALClose(po_dataset);
523 float_data =
static_cast<float*
>(CPLMalloc(
sizeof(
float) * n_cols * n_rows));
524 result = po_band->RasterIO(GF_Read, 0, 0, n_cols, n_rows, float_data,
525 n_cols, n_rows, GDT_Float32, 0, 0);
526 if (result != CE_None) {
527 StatusMessage(
"RaterIO trouble: " +
string(CPLGetLastErrorMsg()));
528 GDALClose(po_dataset);
536 double_data =
static_cast<double*
>(CPLMalloc(
sizeof(
double) * n_cols * n_rows));
537 result = po_band->RasterIO(GF_Read, 0, 0, n_cols, n_rows, double_data,
538 n_cols, n_rows, GDT_Float64, 0, 0);
539 if (result != CE_None) {
540 StatusMessage(
"RaterIO trouble: " +
string(CPLGetLastErrorMsg()));
541 GDALClose(po_dataset);
545 CPLFree(double_data);
550 GDALClose(po_dataset);
554 if (!get_value_flag) {
559 po_dataset->GetGeoTransform(geo_trans);
568 srs = string(po_dataset->GetProjectionRef());
570 GDALClose(po_dataset);
572 values = tmprasterdata;
589 char** papsz_options =
nullptr;
590 void* new_values =
nullptr;
591 bool recreate_flag =
true;
592 double old_nodata = header.at(HEADER_RS_NODATA);
593 bool change_nodata =
false;
594 double new_nodata = old_nodata;
595 bool convert_permit =
true;
600 recreate_flag =
false;
602 else if (outtype == tmptype && outtype !=
RDT_Int8) {
603 recreate_flag =
false;
607 new_values =
static_cast<unsigned char*
>(CPLMalloc(
sizeof(
unsigned char) * n_cols * n_rows));
608 unsigned char* values_uchar =
static_cast<unsigned char*
>(new_values);
609 if (old_nodata < 0 || old_nodata > UINT8_MAX) {
610 new_nodata = UINT8_MAX;
611 change_nodata =
true;
613 int illegal_count = 0;
614#pragma omp parallel for reduction(+:illegal_count)
615 for (
int i = 0; i < n_cols * n_rows; i++) {
616 if (
FloatEqual(values[i], old_nodata) && change_nodata) {
617 values_uchar[i] = UINT8_MAX;
620 if (values[i] < 0 || values[i] > UINT8_MAX) illegal_count += 1;
621 values_uchar[i] =
static_cast<unsigned char>(values[i]);
623 if (illegal_count > 0) convert_permit =
false;
627#if GDAL_VERSION_MAJOR < 3 || (GDAL_VERSION_MAJOR == 3 && GDAL_VERSION_MINOR < 7)
628 papsz_options = CSLSetNameValue(papsz_options,
"PIXELTYPE",
"SIGNEDBYTE");
630 new_values =
static_cast<signed char*
>(CPLMalloc(
sizeof(
signed char) * n_cols * n_rows));
631 signed char* values_char =
static_cast<signed char*
>(new_values);
632 if (old_nodata < INT8_MIN || old_nodata > INT8_MAX) {
633 new_nodata = INT8_MIN;
634 change_nodata =
true;
636 int illegal_count = 0;
637#pragma omp parallel for reduction(+:illegal_count)
638 for (
int i = 0; i < n_cols * n_rows; i++) {
639 if (
FloatEqual(values[i], old_nodata) && change_nodata) {
640 values_char[i] = INT8_MIN;
643 if (values[i] < INT8_MIN || values[i] > INT8_MAX) { illegal_count += 1; }
644 values_char[i] =
static_cast<signed char>(values[i]);
646 if (illegal_count > 0) convert_permit =
false;
649 new_values =
static_cast<vuint16_t*
>(CPLMalloc(
sizeof(vuint16_t) * n_cols * n_rows));
650 vuint16_t* values_uint16 =
static_cast<vuint16_t*
>(new_values);
651 if (old_nodata < 0 || old_nodata > UINT16_MAX) {
652 new_nodata = UINT16_MAX;
653 change_nodata =
true;
655 int illegal_count = 0;
656#pragma omp parallel for reduction(+:illegal_count)
657 for (
int i = 0; i < n_cols * n_rows; i++) {
658 if (
FloatEqual(values[i], old_nodata) && change_nodata) {
659 values_uint16[i] = UINT16_MAX;
662 if (values[i] < 0 || values[i] > UINT16_MAX) illegal_count += 1;
663 values_uint16[i] =
static_cast<vuint16_t
>(values[i]);
665 if (illegal_count > 0) convert_permit =
false;
668 new_values =
static_cast<vint16_t*
>(CPLMalloc(
sizeof(vint16_t) * n_cols * n_rows));
669 vint16_t* values_int16 =
static_cast<vint16_t*
>(new_values);
670 if (old_nodata < INT16_MIN || old_nodata > INT16_MAX) {
671 new_nodata = INT16_MIN;
672 change_nodata =
true;
674 int illegal_count = 0;
675#pragma omp parallel for reduction(+:illegal_count)
676 for (
int i = 0; i < n_cols * n_rows; i++) {
677 if (
FloatEqual(values[i], old_nodata) && change_nodata) {
678 values_int16[i] = INT16_MIN;
681 if (values[i] < INT16_MIN || values[i] > INT16_MAX) illegal_count += 1;
682 values_int16[i] =
static_cast<vint16_t
>(values[i]);
684 if (illegal_count > 0) convert_permit =
false;
687 new_values =
static_cast<vuint32_t*
>(CPLMalloc(
sizeof(vuint32_t) * n_cols * n_rows));
688 vuint32_t* values_uint32 =
static_cast<vuint32_t*
>(new_values);
689 if (old_nodata < 0 || old_nodata > UINT32_MAX) {
690 new_nodata = UINT32_MAX;
691 change_nodata =
true;
693 int illegal_count = 0;
694#pragma omp parallel for reduction(+:illegal_count)
695 for (
int i = 0; i < n_cols * n_rows; i++) {
696 if (
FloatEqual(values[i], old_nodata) && change_nodata) {
697 values_uint32[i] = UINT32_MAX;
700 if (values[i] < 0 || values[i] > UINT32_MAX) illegal_count += 1;
701 values_uint32[i] =
static_cast<vuint32_t
>(values[i]);
703 if (illegal_count > 0) convert_permit =
false;
706 new_values =
static_cast<vint32_t*
>(CPLMalloc(
sizeof(vint32_t) * n_cols * n_rows));
707 vint32_t* values_int32 =
static_cast<vint32_t*
>(new_values);
708 if (old_nodata < INT32_MIN || old_nodata > INT32_MAX) {
709 new_nodata = INT32_MIN;
710 change_nodata =
true;
712 int illegal_count = 0;
713#pragma omp parallel for reduction(+:illegal_count)
714 for (
int i = 0; i < n_cols * n_rows; i++) {
715 if (
FloatEqual(values[i], old_nodata) && change_nodata) {
716 values_int32[i] = INT32_MIN;
719 if (values[i] < INT32_MIN || values[i] > INT32_MAX) illegal_count += 1;
720 values_int32[i] =
static_cast<vint32_t
>(values[i]);
722 if (illegal_count > 0) convert_permit =
false;
724#if GDAL_VERSION_MAJOR >= 3 && GDAL_VERSION_MINOR >=5
726 new_values =
static_cast<vuint64_t*
>(CPLMalloc(
sizeof(vuint64_t) * n_cols * n_rows));
727 vuint64_t* values_uint64 =
static_cast<vuint64_t*
>(new_values);
728 if (old_nodata < 0 || old_nodata > UINT64_MAX) {
729 new_nodata = UINT64_MAX;
730 change_nodata =
true;
732 int illegal_count = 0;
733#pragma omp parallel for reduction(+:illegal_count)
734 for (
int i = 0; i < n_cols * n_rows; i++) {
735 if (
FloatEqual(values[i], old_nodata) && change_nodata) {
736 values_uint64[i] = UINT64_MAX;
739 if (values[i] < 0 || values[i] > UINT64_MAX) illegal_count += 1;
740 values_uint64[i] =
static_cast<vuint64_t
>(values[i]);
742 if (illegal_count > 0) convert_permit =
false;
745 new_values =
static_cast<vint64_t*
>(CPLMalloc(
sizeof(vint64_t) * n_cols * n_rows));
746 vint64_t* values_int64 =
static_cast<vint64_t*
>(new_values);
747 if (old_nodata < INT64_MIN || old_nodata > INT64_MAX) {
748 new_nodata = INT64_MIN;
749 change_nodata =
true;
751 int illegal_count = 0;
752#pragma omp parallel for reduction(+:illegal_count)
753 for (
int i = 0; i < n_cols * n_rows; i++) {
754 if (
FloatEqual(values[i], old_nodata) && change_nodata) {
755 values_int64[i] = INT64_MIN;
758 if (values[i] < INT64_MIN || values[i] > INT64_MAX) illegal_count += 1;
759 values_int64[i] =
static_cast<vint64_t
>(values[i]);
761 if (illegal_count > 0) convert_permit =
false;
765 new_values =
static_cast<float*
>(CPLMalloc(
sizeof(
float) * n_cols * n_rows));
766 float* values_float =
static_cast<float*
>(new_values);
767#pragma omp parallel for
768 for (
int i = 0; i < n_cols * n_rows; i++) values_float[i] = static_cast<float>(values[i]);
771 new_values =
static_cast<double*
>(CPLMalloc(
sizeof(
double) * n_cols * n_rows));
772 double* values_double =
static_cast<double*
>(new_values);
773#pragma omp parallel for
774 for (
int i = 0; i < n_cols * n_rows; i++) values_double[i] = static_cast<double>(values[i]);
777 if ((outtype ==
RDT_Unknown || (recreate_flag &&
nullptr == new_values))
778 || (!convert_permit)) {
779 cout <<
"Error: The specific raster output data type is not allowed!\n";
780 if (papsz_options !=
nullptr) { CSLDestroy(papsz_options); }
781 if (new_values !=
nullptr) { CPLFree(new_values); }
784 GDALDriver* po_driver = GetGDALDriverManager()->GetDriverByName(
"GTiff");
785 if (
nullptr == po_driver) {
return false; }
788 GDALDataset* po_dst_ds = po_driver->Create(filename.c_str(), n_cols, n_rows, 1,
789 CvtToGDALDataType(outtype), papsz_options);
790 if (
nullptr == po_dst_ds) {
return false; }
791 GDALRasterBand* po_dst_band = po_dst_ds->GetRasterBand(1);
792 CPLErr result = CE_None;
793 if (!recreate_flag) {
794 result = po_dst_band->RasterIO(GF_Write, 0, 0, n_cols, n_rows, values,
795 n_cols, n_rows, CvtToGDALDataType(outtype), 0, 0);
798 result = po_dst_band->RasterIO(GF_Write, 0, 0, n_cols, n_rows, new_values,
799 n_cols, n_rows, CvtToGDALDataType(outtype), 0, 0);
801 if (result != CE_None ||
nullptr == po_dst_band) {
802 StatusMessage(
"RaterIO Error: " +
string(CPLGetLastErrorMsg()));
803 if (papsz_options !=
nullptr) { CSLDestroy(papsz_options); }
804 if (new_values !=
nullptr) { CPLFree(new_values); }
805 GDALClose(po_dst_ds);
808 po_dst_band->SetNoDataValue(new_nodata);
817 po_dst_ds->SetGeoTransform(geo_trans);
819 po_dst_ds->SetProjection(
"");
823 if (papsz_options !=
nullptr) { CSLDestroy(papsz_options); }
824 if (new_values !=
nullptr) { CPLFree(new_values); }
825 GDALClose(po_dst_ds);
852 header, opts, values);
854 StatusMessage(
"Warning: Without GDAL, ASC file will be exported as default!");
877 if (!gfs->
GetStreamData(filename, buf, length,
nullptr, &opts) ||
885 if (
nullptr != bmeta && bson_iter_init(&iter, bmeta)) {
886 while (bson_iter_next(&iter)) {
887 const char* key = bson_iter_key(&iter);
888 if (header.find(key) != header.end()) {
902 if (n_rows < 0 || n_cols < 0 || n_lyrs < 0) {
906 int value_count = n_cells * n_lyrs;
907 size_t size_dtype = length / value_count;
919 if (rstype ==
RDT_Double && size_dtype ==
sizeof(
double)) {
920 double* data_dbl =
reinterpret_cast<double*
>(buf);
924 else if (rstype ==
RDT_Float && size_dtype ==
sizeof(
float)) {
925 float* data_flt =
reinterpret_cast<float*
>(buf);
929 else if (rstype ==
RDT_Int32 && size_dtype ==
sizeof(vint32_t)) {
930 vint32_t* data_int32 =
reinterpret_cast<vint32_t*
>(buf);
934 else if (rstype ==
RDT_UInt32 && size_dtype ==
sizeof(vuint32_t)) {
935 vuint32_t* data_uint32 =
reinterpret_cast<vuint32_t*
>(buf);
939 else if (rstype ==
RDT_Int64 && size_dtype ==
sizeof(vint64_t)) {
940 vint64_t* data_int64 =
reinterpret_cast<vint64_t*
>(buf);
944 else if (rstype ==
RDT_UInt64 && size_dtype ==
sizeof(vuint64_t)) {
945 vuint64_t* data_uint64 =
reinterpret_cast<vuint64_t*
>(buf);
949 else if (rstype ==
RDT_Int16 && size_dtype ==
sizeof(vint16_t)) {
950 vint16_t* data_int16 =
reinterpret_cast<vint16_t*
>(buf);
954 else if (rstype ==
RDT_UInt16 && size_dtype ==
sizeof(vuint16_t)) {
955 vuint16_t* data_uint16 =
reinterpret_cast<vuint16_t*
>(buf);
959 else if (rstype ==
RDT_Int8 && size_dtype ==
sizeof(vint8_t)) {
960 vint8_t* data_int8 =
reinterpret_cast<vint8_t*
>(buf);
964 else if (rstype ==
RDT_UInt8 && size_dtype ==
sizeof(vuint8_t)) {
965 vuint8_t* data_uint8 =
reinterpret_cast<vuint8_t*
>(buf);
990 STRDBL_MAP& header, T* values,
const int datalength,
999 bson_t p = BSON_INITIALIZER;
1001 for (
auto iter = header.begin(); iter != header.end(); ++iter) {
1003 && std::modf(iter->second, &intpart) == 0.0) {
1006 BSON_APPEND_INT32(&p, iter->first.c_str(),
CVT_INT(iter->second));
1009 BSON_APPEND_DOUBLE(&p, iter->first.c_str(), iter->second);
1013 char* buf =
nullptr;
1014 vint buflength = -1;
1015 bool transformed =
true;
1017 if (opt_type == temp_type) {
1018 buf =
reinterpret_cast<char*
>(values);
1019 buflength = datalength *
sizeof(T);
1020 transformed =
false;
1023 vuint8_t* newdata =
nullptr;
1025 buf =
reinterpret_cast<char*
>(newdata);
1026 buflength = datalength *
sizeof(vuint8_t);
1028 vint8_t* newdata =
nullptr;
1030 buf =
reinterpret_cast<char*
>(newdata);
1031 buflength = datalength *
sizeof(vint8_t);
1033 vuint16_t* newdata =
nullptr;
1035 buf =
reinterpret_cast<char*
>(newdata);
1036 buflength = datalength *
sizeof(vuint16_t);
1038 vint16_t* newdata =
nullptr;
1040 buf =
reinterpret_cast<char*
>(newdata);
1041 buflength = datalength *
sizeof(vint16_t);
1043 vuint32_t* newdata =
nullptr;
1045 buf =
reinterpret_cast<char*
>(newdata);
1046 buflength = datalength *
sizeof(vuint32_t);
1048 vint32_t* newdata =
nullptr;
1050 buf =
reinterpret_cast<char*
>(newdata);
1051 buflength = datalength *
sizeof(vint32_t);
1053 float* newdata =
nullptr;
1055 buf =
reinterpret_cast<char*
>(newdata);
1056 buflength = datalength *
sizeof(float);
1058 double* newdata =
nullptr;
1060 buf =
reinterpret_cast<char*
>(newdata);
1061 buflength = datalength *
sizeof(double);
1068 bool gstatus =
false;
1069 while (try_times <= 3) {
1071 if (gstatus) {
break; }
1076 if (transformed) {
delete[] buf; }
1096 bool Initialization();
1098 template <
typename T>
1099 bool SetData(
const int n, T* data) {
1100 if (n !=
n_cells) {
return false; }
1101 if (
nullptr == data) {
return false; }
1103 if (
nullptr !=
data_) {
1112 template <
typename T>
1113 bool Set2DData(
const int n,
const int lyr, T** data2d) {
1114 if (n !=
n_cells) {
return false; }
1115 if (
nullptr == data2d) {
return false; }
1118 for (
int i = 0; i <
n_cells; i++) {
1119 for (
int j = 0; j <
n_lyrs; j++) {
1130 bool ReadFromMongoDB(
MongoGridFs* gfs,
const string& fname,
1133 void GetHeader(
double gxll,
double gyll,
int gnrows,
double cellsize,
1135 template <
typename T>
1136 void Output(T nodata, vector<T*>& fulldata) {
1137 if (
nullptr ==
data_ &&
nullptr ==
data2d_) {
return; }
1140 int fullsize = nrows * ncols;
1141 for (
int ilyr = 0; ilyr <
n_lyrs; ilyr++) {
1142 T* tmpdata =
nullptr;
1144 for (
int vi = 0; vi <
n_cells; vi++) {
1148 tmpdata[j] =
static_cast<T
>(
data2d_[vi][ilyr]);
1151 tmpdata[j] =
static_cast<T
>(
data_[vi]);
1154 fulldata.emplace_back(tmpdata);
1178template <
typename T,
typename MASK_T = T>
1191 clsRasterData(T* data,
int cols,
int rows, T nodata,
double dx,
double xll,
1198 clsRasterData(T* data,
int cols,
int rows, T nodata,
double dx,
double xll,
1199 double yll,
const string& srs);
1204 clsRasterData(T** data2d,
int cols,
int rows,
int nlayers, T nodata,
1211 clsRasterData(T** data2d,
int cols,
int rows,
int nlayers, T nodata,
1212 double dx,
double xll,
double yll,
const string& srs);
1225 explicit clsRasterData(
const string& filename,
bool calc_pos =
false,
1257 explicit clsRasterData(vector<string>& filenames,
bool calc_pos =
false,
1315 bool use_mask_ext =
true,
double default_value =
NODATA_VALUE,
1349 bool use_mask_ext =
true,
double default_value =
NODATA_VALUE,
1356 bool use_mask_ext =
true,
double default_value =
NODATA_VALUE,
1383 bool OutputToFile(
const string& filename,
bool out_origin =
true);
1394 const string& outname =
string(),
1395 const map<vint, vector<double> >& recls = map<vint, vector<double> >(),
1422 bool include_nodata =
true,
1423 bool out_origin =
true);
1442 bool include_nodata =
true,
1443 bool out_origin =
false,
bool out_combined =
true,
1444 const map<vint, vector<double> >& recls = map<vint, vector<double> >(),
1461 void SetValue(
int row,
int col, T value,
int lyr = 1);
1499 bool BuildSubSet(map<int, int> groups = map<int, int>());
1548 void GetStatistics(
string sindex,
int* lyrnum,
double** values);
1625 int GetCellNumber()
const {
return n_cells_; }
1627 int GetDataLength()
const {
return n_cells_ < 0 || n_lyrs_ < 0 ? -1 : n_cells_ * n_lyrs_; }
1654 int GetLayers()
const {
return n_lyrs_; }
1711 T* GetRasterDataPointer()
const {
return raster_; }
1737 T
GetValue(
int row,
int col,
int lyr = 1);
1745 void GetValue(
int row,
int col, T*& values);
1751 bool IsNoData(
const int row,
const int col,
const int lyr = 1) {
1755 bool Is2DRaster()
const {
return is_2draster; }
1766 if ((!is_2draster &&
nullptr != raster_) ||
1767 (is_2draster &&
nullptr != raster_2d_))
1769 StatusMessage(
"Error: Please initialize the raster object first.");
1777 if ((row < 0 || row >=
GetRows()) || (col < 0 || col >= GetCols())) {
1779 ", and the col must between 0 and " +
ValueToString(GetCols() - 1));
1789 if (lyr <= 0 || lyr > n_lyrs_) {
1802 if (idx < 0 || idx >= n_cells_) {
1855 void InitializeRasterClass(
bool is_2d =
false);
1860 void InitializeReadFunction(
const string& filename,
bool calc_pos =
false,
clsRasterData<MASK_T>* mask =
nullptr,
1861 bool use_mask_ext =
true,
double default_value =
NODATA_VALUE,
1875 bool ConstructFromSingleFile(
const string& filename,
bool calc_pos =
false,
clsRasterData<MASK_T>* mask =
nullptr,
1876 bool use_mask_ext =
true,
double default_value =
NODATA_VALUE,
1887 int MaskAndCalculateValidPosition();
1894 void CalculateValidPositionsFromGridData();
1899 bool PrepareCombSubsetData(T**values,
int* datalen,
int* datalyrs,
1900 bool out_origin =
false,
bool include_nodata =
true,
1901 const map<vint, vector<double> >&recls = map<vint, vector<double> >(),
1908 T** values,
int* datalen,
int* datalyrs,
1909 bool out_origin =
false,
bool include_nodata =
true,
1910 const map<vint, vector<double> >& recls = map<vint, vector<double> >(),
1916 bool OutputFullsizeToFiles(T* fullsizedata,
int fsize,
int datalyrs,
1917 const string& fullfilename,
const STRDBL_MAP& header,
1929 void AddOtherLayerRasterData(
int row,
int col,
int cellidx,
int lyr,
1935 void CheckDefaultValue() {
1937 default_value_ =
CVT_DBL(no_data_value_);
1962 double default_value_;
1982 map<string, double *> stats_2d_;
1984 clsRasterData<MASK_T>* mask_;
1986 map<int, SubsetPositions*> subset_;
1998 bool stats_calculated_;
2003#define IntRaster clsRasterData<int>
2006#define FltRaster clsRasterData<float>
2009#define DblRaster clsRasterData<double>
2012#define IntIntRaster clsRasterData<int, int>
2015#define FltIntRaster clsRasterData<float, int>
2018#define DblIntRaster clsRasterData<double, int>
2027template <
typename T,
typename MASK_T>
2028void clsRasterData<T, MASK_T>::InitializeRasterClass(
bool is_2d ) {
2038 pos_data_ =
nullptr;
2041 subset_ = map<int, SubsetPositions*>();
2043 is_2draster = is_2d;
2044 raster_2d_ =
nullptr;
2047 use_mask_ext_ =
false;
2048 stats_calculated_ =
false;
2052 initialized_ =
true;
2055template <
typename T,
typename MASK_T>
2056void clsRasterData<T, MASK_T>::InitializeReadFunction(
const string& filename,
const bool calc_pos ,
2057 clsRasterData<MASK_T>* mask ,
2058 const bool use_mask_ext ,
2059 double default_value ,
2061 if (!initialized_) { InitializeRasterClass(); }
2062 full_path_ = filename;
2064 calc_pos_ = calc_pos;
2065 use_mask_ext_ = use_mask_ext;
2066 if (
nullptr == mask_) { use_mask_ext_ =
false; }
2067 default_value_ = default_value;
2073template <
typename T,
typename MASK_T>
2075 InitializeRasterClass(is_2d);
2078template <
typename T,
typename MASK_T>
2080 double dx,
double xll,
double yll,
2081 const string& srs) {
2084 clsRasterData(data, cols, rows, nodata, dx, xll, yll, opts);
2087template <
typename T,
typename MASK_T>
2089 const double dx,
const double xll,
const double yll,
2091 InitializeRasterClass(
false);
2094 no_data_value_ = nodata;
2096 n_cells_ = cols * rows;
2108template <
typename T,
typename MASK_T>
2110 T nodata,
const double dx,
const double xll,
const double yll,
2111 const string& srs) {
2114 clsRasterData(data2d, cols, rows, nlayers, nodata, dx, xll, yll, opts);
2117template <
typename T,
typename MASK_T>
2119 T nodata,
const double dx,
const double xll,
const double yll,
2121 InitializeRasterClass(
true);
2123 raster_2d_ = data2d;
2124 no_data_value_ = nodata;
2126 n_cells_ = cols * rows;
2133 headers_[HEADER_RS_NODATA] = no_data_value_;
2138template <
typename T,
typename MASK_T>
2141 const bool use_mask_ext ,
2142 double default_value ,
2144 InitializeRasterClass();
2146 ReadFromFile(filename, calc_pos, mask, use_mask_ext, default_value, opts);
2149template <
typename T,
typename MASK_T>
2151 const bool calc_pos ,
2153 const bool use_mask_ext ,
2154 double default_value ,
2156 if (!
FileExists(filename)) {
return nullptr; }
2159 if (!rs->
ReadFromFile(filename, calc_pos, mask, use_mask_ext, default_value, opts)) {
2166template <
typename T,
typename MASK_T>
2168 const bool calc_pos ,
2170 const bool use_mask_ext ,
2171 double default_value ,
2177 if (filenames.size() == 1) {
2178 ReadFromFile(filenames[0], calc_pos, mask,
2179 use_mask_ext, default_value, opts);
2181 ReadFromFiles(filenames, calc_pos, mask,
2182 use_mask_ext, default_value, opts);
2185template <
typename T,
typename MASK_T>
2190 double default_value ,
2196 if (filenames.size() == 1) {
2198 default_value, opts);
2202 if (!rs2d->
ReadFromFiles(filenames, calc_pos, mask, use_mask_ext, default_value, opts)) {
2209template <
typename T,
typename MASK_T>
2212 InitializeRasterClass(
false);
2216 use_mask_ext_ =
true;
2220 if (n_cells_ != len) {
2221 StatusMessage(
"Input data length MUST EQUALS TO valid cell's number of mask!");
2222 initialized_ =
false;
2226 default_value_ = mask_->GetDefaultValue();
2227 CopyHeader(mask_->GetRasterHeader(), headers_);
2228 no_data_value_ =
static_cast<T
>(mask_->GetNoDataValue());
2233template <
typename T,
typename MASK_T>
2236 InitializeRasterClass(
true);
2239 use_mask_ext_ =
true;
2243 if (n_cells_ != len) {
2244 StatusMessage(
"Input data length MUST EQUALS TO valid cell's number of mask!");
2245 initialized_ =
false;
2249 CopyHeader(mask_->GetRasterHeader(), headers_);
2250 no_data_value_ =
static_cast<T
>(mask_->GetNoDataValue());
2258template <
typename T,
typename MASK_T>
2260 const bool calc_pos ,
2262 const bool use_mask_ext ,
2263 double default_value ,
2265 InitializeRasterClass();
2267 ReadFromMongoDB(gfs, remote_filename, calc_pos, mask, use_mask_ext, default_value, opts);
2270template <
typename T,
typename MASK_T>
2272 const bool calc_pos ,
2274 const bool use_mask_ext ,
2275 double default_value ,
2279 if (!rs_mongo->
ReadFromMongoDB(gfs, remote_filename, calc_pos, mask, use_mask_ext, default_value, opts)) {
2288template <
typename T,
typename MASK_T>
2290 const bool calc_pos ,
2292 const bool use_mask_ext ,
2293 double default_value ,
2295 InitializeReadFunction(filename, calc_pos, mask, use_mask_ext, default_value, opts);
2297 bool readflag =
false;
2298 string srs = string();
2300 readflag =
ReadAscFile(full_path_, headers_, raster_);
2305 StatusMessage(
"Warning: Only ASC format is supported without GDAL!");
2310 no_data_value_ =
static_cast<T
>(headers_.at(HEADER_RS_NODATA));
2313 if (rs_type_out_ == 0) {
2314 rs_type_out_ = rs_type_;
2317 CheckDefaultValue();
2319 if (n_lyrs_ < 0) { n_lyrs_ = 1; }
2320 if (is_2draster) { is_2draster =
false; }
2321 return MaskAndCalculateValidPosition() >= 0;
2326template <
typename T,
typename MASK_T>
2328 if (!core_name_.empty()) {
StatusMessage((
"Release raster: " + core_name_).c_str()); }
2330 if (
nullptr != pos_data_ && store_pos_) {
Release2DArray(pos_data_); }
2331 if (
nullptr != pos_idx_ && store_pos_) {
Release1DArray(pos_idx_); }
2332 if (
nullptr != raster_2d_ && is_2draster) {
Release2DArray(raster_2d_); }
2333 if (is_2draster && stats_calculated_) { ReleaseStatsMap2D(); }
2337template <
typename T,
typename MASK_T>
2339 if (!ValidateRasterData()) {
return false; }
2340 if (
nullptr == pos_data_ ||
nullptr == pos_idx_) {
2341 if (!SetCalcPositions()) {
return false; }
2343 if (!subset_.empty()) {
return true; }
2345 int global_ncols = GetCols();
2346 map<int, vector<int> > global_idx;
2347 for (
int vi = 0; vi < n_cells_; vi++) {
2348 T curv = GetValueByIndex(vi);
2349 if (
FloatEqual(curv, no_data_value_)) {
continue; }
2351 if (!groups.empty() && groups.find(groupv) != groups.end()) {
2352 groupv = groups.at(groupv);
2356 int currow = pos_idx_[vi] / global_ncols;
2357 int curcol = pos_idx_[vi] % global_ncols;
2358 if (subset_.find(groupv) == subset_.end()) {
2359#ifdef HAS_VARIADIC_TEMPLATES
2360 subset_.emplace(groupv,
new SubsetPositions(currow, currow, curcol, curcol));
2362 subset_.insert(make_pair(groupv,
new SubsetPositions(currow, currow, curcol, curcol)));
2366 if (currow > cursubset->
g_erow) { cursubset->
g_erow = currow; }
2367 if (currow < cursubset->g_srow) { cursubset->
g_srow = currow; }
2368 if (curcol > cursubset->
g_ecol) { cursubset->
g_ecol = curcol; }
2369 if (curcol < cursubset->g_scol) { cursubset->
g_scol = curcol; }
2370 if (global_idx.find(groupv) == global_idx.end()) {
2371#ifdef HAS_VARIADIC_TEMPLATES
2372 global_idx.emplace(groupv, vector<int>());
2374 global_idx.insert(make_pair(groupv, vector<int>()));
2377 global_idx[groupv].emplace_back(vi);
2380 for (
auto it = subset_.begin(); it != subset_.end(); ++it) {
2382 for (
auto it2 = global_idx[it->first].begin(); it2 != global_idx[it->first].end(); ++it2) {
2383 it->second->global_[it2 - global_idx[it->first].begin()] = *it2;
2386 for (
auto it = subset_.begin(); it != subset_.end(); ++it) {
2390 int nrows = it->second->g_erow - it->second->g_srow + 1;
2391 int local_ncols = it->second->g_ecol - it->second->g_scol + 1;
2392 for (
int gidx = 0; gidx < it->second->n_cells; gidx++) {
2395 int local_row = pos_idx_[it->second->global_[gidx]] / global_ncols - it->second->g_srow;
2396 int local_col = pos_idx_[it->second->global_[gidx]] % global_ncols - it->second->g_scol;
2397 it->second->local_pos_[gidx][0] = local_row;
2398 it->second->local_pos_[gidx][1] = local_col;
2399 it->second->local_posidx_[gidx] = local_row * local_ncols + local_col;
2401 it->second->alloc_ =
true;
2406template <
typename T,
typename MASK_T>
2408 if (!subset_.empty()) {
2409 for (
auto it = subset_.begin(); it != subset_.end(); ++it) {
2411 it->second =
nullptr;
2418template <
typename T,
typename MASK_T>
2420 return ReleaseSubset() && BuildSubSet(groups);
2425template <
typename T,
typename MASK_T>
2427 rs_type_out_ = type;
2431template <
typename T,
typename MASK_T>
2438template <
typename T,
typename MASK_T>
2440 if (stats_calculated_) {
return; }
2441 if (stats_.empty() || stats_2d_.empty()) {
InitialStatsMap(stats_, stats_2d_); }
2442 if (is_2draster &&
nullptr != raster_2d_) {
2443 double** derivedvs =
nullptr;
2444 BasicStatistics(raster_2d_, n_cells_, n_lyrs_, &derivedvs, no_data_value_);
2454 double* derivedv =
nullptr;
2464 stats_calculated_ =
true;
2467template <
typename T,
typename MASK_T>
2469 for (
auto it = stats_2d_.begin(); it != stats_2d_.end(); ++it) {
2470 if (
nullptr != it->second) {
2477template <
typename T,
typename MASK_T>
2479 if (is_2draster && stats_calculated_) ReleaseStatsMap2D();
2480 stats_calculated_ =
false;
2481 CalculateStatistics();
2484template <
typename T,
typename MASK_T>
2487 if (!ValidateRasterData() || !ValidateLayer(lyr)) {
2489 return CVT_DBL(default_value_);
2491 if (is_2draster &&
nullptr != raster_2d_) {
2493 auto it = stats_2d_.find(sindex);
2494 if (it != stats_2d_.end()) {
2495 if (
nullptr == it->second) {
2496 stats_calculated_ =
false;
2497 CalculateStatistics();
2499 return stats_2d_.at(sindex)[lyr - 1];
2502 return CVT_DBL(default_value_);
2505 auto it = stats_.find(sindex);
2506 if (it != stats_.end()) {
2508 CalculateStatistics();
2510 return stats_.at(sindex);
2513 return CVT_DBL(default_value_);
2516template <
typename T,
typename MASK_T>
2518 if (!is_2draster ||
nullptr != raster_2d_) {
2519 StatusMessage(
"Please initialize the raster object first.");
2525 auto it = stats_2d_.find(sindex);
2526 if (!Is2DRaster()) {
2530 if (it == stats_2d_.end()) {
2535 if (
nullptr == it->second || !stats_calculated_) {
2536 CalculateStatistics();
2538 *values = it->second;
2541template <
typename T,
typename MASK_T>
2543 if (!ValidateRasterData() || !ValidateRowCol(row, col)) {
2546 int pos_idx = GetCols() * row + col;
2547 if (!calc_pos_ ||
nullptr == pos_data_ ||
nullptr == pos_idx_) {
2559 int right = n_cells_ - 1;
2560 while (left <= right) {
2561 int middle = left + ((right - left) / 2);
2562 if (pos_idx_[middle] > pos_idx) {
2564 }
else if (pos_idx_[middle] < pos_idx) {
2573template <
typename T,
typename MASK_T>
2578template <
typename T,
typename MASK_T>
2580 if (!initialized_)
return -2;
2581 double xll_center = GetXllCenter();
2582 double yll_center = GetYllCenter();
2583 double dx = GetCellWidth();
2584 double dy = GetCellWidth();
2585 int n_rows = GetRows();
2586 int n_cols = GetCols();
2591 || n_rows < 0 || n_cols < 0) {
2596 double x_min = xll_center - dx / 2.;
2597 double x_max = x_min + dx * n_cols;
2598 if (x > x_max || x < x_min) {
2602 double y_min = yll_center - dy / 2.;
2603 double y_max = y_min + dy * n_rows;
2604 if (y > y_max || y < y_min) {
2608 int n_row =
CVT_INT((y_max - y) / dy);
2609 int n_col =
CVT_INT((x - x_min) / dx);
2611 return GetPosition(n_row, n_col);
2614template <
typename T,
typename MASK_T>
2616 if (ValidateRasterData() && !is_2draster) {
2617 *n_cells = n_cells_;
2626template <
typename T,
typename MASK_T>
2628 if (ValidateRasterData() && is_2draster) {
2629 *n_cells = n_cells_;
2640template <
typename T,
typename MASK_T>
2642 if (
nullptr != pos_data_) {
2643 *datalength = n_cells_;
2644 *positiondata = pos_data_;
2647 if (!ValidateRasterData()) {
2649 *positiondata =
nullptr;
2652 CalculateValidPositionsFromGridData();
2653 *datalength = n_cells_;
2654 *positiondata = pos_data_;
2658template <
typename T,
typename MASK_T>
2660 if (
nullptr != pos_idx_) {
2661 *datalength = n_cells_;
2662 *positiondata = pos_idx_;
2665 if (!ValidateRasterData()) {
2667 *positiondata =
nullptr;
2670 CalculateValidPositionsFromGridData();
2671 *datalength = n_cells_;
2672 *positiondata = pos_idx_;
2676template <
typename T,
typename MASK_T>
2678 return GetSrsString().c_str();
2681template <
typename T,
typename MASK_T>
2686template <
typename T,
typename MASK_T>
2688 if (options_.find(key) == options_.end()) {
2689 StatusMessage((
string(key) +
" is not existed in the options of the raster data!").c_str());
2692 return options_.at(key);
2695template <
typename T,
typename MASK_T>
2697 if (!ValidateRasterData() || !ValidateIndex(cell_index) || !ValidateLayer(lyr)) {
2698 return no_data_value_;
2701 return raster_2d_[cell_index][lyr - 1];
2703 return raster_[cell_index];
2706template <
typename T,
typename MASK_T>
2708 if (!ValidateRasterData() || !ValidateIndex(cell_index)) {
2713 if (
nullptr == values) {
2717 for (
int i = 0; i < n_lyrs_; i++) {
2718 values[i] = raster_2d_[cell_index][i];
2721 values[0] = raster_[cell_index];
2725template <
typename T,
typename MASK_T>
2727 if (!ValidateRasterData() || !ValidateRowCol(row, col) || !ValidateLayer(lyr)) {
2728 return no_data_value_;
2731 if (calc_pos_ && (
nullptr != pos_data_ ||
nullptr != pos_idx_)) {
2732 int valid_cell_index = GetPosition(row, col);
2733 if (valid_cell_index < 0) {
return no_data_value_; }
2734 return GetValueByIndex(valid_cell_index, lyr);
2737 if (is_2draster) {
return raster_2d_[row * GetCols() + col][lyr - 1]; }
2738 return raster_[row * GetCols() + col];
2741template <
typename T,
typename MASK_T>
2743 if (!ValidateRasterData() || !ValidateRowCol(row, col)) {
2748 if (
nullptr == values) {
2751 if (calc_pos_ && (
nullptr != pos_data_ ||
nullptr != pos_idx_)) {
2752 int valid_cell_index = GetPosition(row, col);
2753 if (valid_cell_index == -1) {
2754 for (
int i = 0; i < n_lyrs_; i++) {
2755 values[i] = no_data_value_;
2758 GetValueByIndex(valid_cell_index, values);
2763 for (
int i = 0; i < n_lyrs_; i++) {
2764 values[i] = raster_2d_[row * GetCols() + col][i];
2767 values[0] = raster_[row * GetCols() + col];
2772template <
typename T,
typename MASK_T>
2777 if (it != headers_.end()) { n_cells_ =
CVT_INT(it->second); }
2779 if (it != headers_.end()) { n_lyrs_ =
CVT_INT(it->second); }
2780 it = headers_.find(HEADER_RS_NODATA);
2781 if (it != headers_.end()) { no_data_value_ =
static_cast<T
>(it->second); }
2785template <
typename T,
typename MASK_T>
2787 if (!ValidateRasterData() || !ValidateRowCol(row, col) || !ValidateLayer(lyr)) {
2791 int idx = GetPosition(row, col);
2794 StatusMessage(
"Current version do not support to setting value to NoDATA location!");
2797 raster_2d_[idx][lyr - 1] = value;
2799 raster_[idx] = value;
2804template <
typename T,
typename MASK_T>
2806 if (!ValidateRasterData()) {
return false; }
2807 if (calc_pos_ && (
nullptr != pos_data_ ||
nullptr != pos_idx_)) {
2812 return MaskAndCalculateValidPosition() >= 0;
2815template <
typename T,
typename MASK_T>
2817 if (
nullptr != pos_data_) {
2818 if (len != n_cells_) {
return false; }
2827template <
typename T,
typename MASK_T>
2829 if (
nullptr != pos_idx_) {
2830 if (len != n_cells_) {
return false; }
2839template <
typename T,
typename MASK_T>
2841 if (!ValidateRasterData())
return false;
2842 if (
nullptr == mask_)
return false;
2843 if (use_mask_ext_)
return false;
2844 use_mask_ext_ =
true;
2845 return MaskAndCalculateValidPosition() >= 0;
2850template <
typename T,
typename MASK_T>
2854 if (!ValidateRasterData()) {
return false; }
2855 if (!out_origin) {
return OutputSubsetToFile(
false,
true, filename); }
2858 return OutputAscFile(abs_filename);
2862 return OutputFileByGdal(abs_filename);
2866 StatusMessage(
"Warning: Without GDAL, ASC file will be exported as default!");
2871template <
typename T,
typename MASK_T>
2873 const bool out_combined ,
2874 const string& outname ,
2875 const map<vint, vector<double> >& recls ,
2876 const double default_value ) {
2877 if (!ValidateRasterData()) {
return false; }
2878 if (subset_.empty()) {
return false; }
2879 string outpathact = outname.empty() ? full_path_ : outname;
2881 bool out_comb = out_combined;
2883 T* data1d =
nullptr;
2886 if (!PrepareCombSubsetData(&data1d, &sublen, &sublyrs,
2887 out_origin,
true, recls, default_value)) {
2894 bool combflag = OutputFullsizeToFiles(data1d, sublen / sublyrs, sublyrs,
2896 tmpheader, options_);
2902 for (
auto it = subset_.begin(); it != subset_.end(); ++it) {
2903 if (!it->second->usable) {
continue; }
2904 it->second->GetHeader(GetXllCenter(), GetYllCenter(), GetRows(),
2905 GetCellWidth(),
CVT_DBL(no_data_value_), subheader);
2906 T* tmpdata1d =
nullptr;
2909 if (!PrepareSubsetData(it->first, it->second, &tmpdata1d, &tmpdatalen, &tmplyrs,
2910 out_origin,
true, recls, default_value)) {
2915 flag = flag && OutputFullsizeToFiles(tmpdata1d, tmpdatalen / tmplyrs, tmplyrs,
2917 subheader, options_);
2923template <
typename T,
typename MASK_T>
2925 bool out_origin ,
bool include_nodata ,
2926 const map<vint, vector<double> >& recls ,
2927 double default_value ) {
2928 if (subset_.empty()) {
return false; }
2929 T* data1d =
nullptr;
2931 if (!recls.empty()) {
2932 for (
auto it = recls.begin(); it != recls.end(); ++it) {
2933 if (lyr_recls < 0) { lyr_recls =
CVT_INT(it->second.size()); }
2934 else if (lyr_recls != it->second.size()) {
2935 StatusMessage(
"Error: Reclassification layer count MUST be consistent!");
2940 int lyrs_subset = -1;
2941 for (
auto it = subset_.begin(); it != subset_.end(); ++it) {
2942 if (!it->second->usable) {
continue; }
2943 if (!(
nullptr != it->second->data_
2944 ||
nullptr != it->second->data2d_
2945 || !recls.empty())) {
2948 if (lyrs_subset < 0) { lyrs_subset = it->second->n_lyrs; }
2949 else if (it->second->n_lyrs != lyrs_subset) {
2950 StatusMessage(
"Error: Subset's layer count MUST be consistent!");
2957 if (lyr_recls > 0) { lyrs = lyr_recls; }
2960 if (lyrs < 0 && lyr_recls > 0) {
2965 StatusMessage(
"Error: Cannot determine valid layer count!");
2969 int gnrows = GetRows();
2970 int gncols = GetCols();
2972 default_value = default_value_;
2974 int gncells = include_nodata ? gnrows * gncols : n_cells_;
2975 int data_length = gncells * lyrs;
2977 for (
auto it = subset_.begin(); it != subset_.end(); ++it) {
2978 bool use_defaultv_directly =
false;
2979 if (!it->second->usable) {
2980 if (!
FloatEqual(no_data_value_, default_value)) {
2981 use_defaultv_directly =
true;
2986 for (
int vi = 0; vi < it->second->n_cells; vi++) {
2987 for (
int ilyr = 0; ilyr < lyrs; ilyr++) {
2988 int gidx = it->second->global_[vi];
2992 int tmprc = pos_idx_[gidx];
2993 if (!include_nodata) { tmprc = gidx; }
2994 if (!recls.empty()) {
2995 double uniqe_value = default_value;
2996 int recls_key = it->first;
2998 if (
nullptr != raster_) { recls_key =
CVT_INT(raster_[gidx]); }
2999 else if (
nullptr != raster_2d_) {
3000 recls_key =
CVT_INT(raster_2d_[gidx][ilyr]);
3003 if (recls.count(recls_key) > 0 && recls.at(recls_key).size() > ilyr) {
3004 uniqe_value = recls.at(recls_key).at(ilyr);
3006 data1d[tmprc * lyrs + ilyr] =
static_cast<T
>(uniqe_value);
3008 else if (use_defaultv_directly) {
3009 data1d[tmprc * lyrs + ilyr] =
static_cast<T
>(default_value);
3011 else if (!out_origin && lyrs > 1 &&
nullptr != it->second->data2d_) {
3012 data1d[tmprc * lyrs + ilyr] =
static_cast<T
>(it->second->data2d_[vi][ilyr]);
3014 else if (!out_origin && lyrs == 1 &&
nullptr != it->second->data_) {
3015 data1d[tmprc * lyrs + ilyr] =
static_cast<T
>(it->second->data_[vi]);
3018 StatusMessage(
"Error: No subset or reclassification map can be output!");
3026 *datalen = data_length;
3031template <
typename T,
typename MASK_T>
3032bool clsRasterData<T, MASK_T>::PrepareSubsetData(
const int sub_id, SubsetPositions* sub,
3033 T** values,
int* datalen,
int* datalyrs,
3034 bool out_origin ,
bool include_nodata ,
3035 const map<vint, vector<double> >& recls ,
3036 double default_value ) {
3037 if (
nullptr == sub) {
return false; }
3038 T* data1d =
nullptr;
3040 if (!recls.empty()) {
3041 for (
auto it = recls.begin(); it != recls.end(); ++it) {
3042 if (lyr_recls < 0) { lyr_recls =
CVT_INT(it->second.size()); }
3043 else if (lyr_recls != it->second.size()) {
3044 StatusMessage(
"Error: Reclassification layer count MUST be consistent!");
3052 if (lyr_recls > 0) { lyrs = lyr_recls; }
3057 StatusMessage(
"Error: Cannot determine valid layer count!");
3060 int nrows = sub->g_erow - sub->g_srow + 1;
3061 int ncols = sub->g_ecol - sub->g_scol + 1;
3063 default_value = default_value_;
3065 int ncells = include_nodata ? nrows * ncols : sub->n_cells;
3066 int data_length = ncells * lyrs;
3068 for (
int vi = 0; vi < sub->n_cells; vi++) {
3069 for (
int ilyr = 0; ilyr < lyrs; ilyr++) {
3071 int j = sub->local_posidx_[vi];
3072 int gidx = sub->global_[vi];
3073 if (!include_nodata) { j = vi; }
3074 if (!recls.empty()) {
3075 double uniqe_value = default_value;
3076 int recls_key = sub_id;
3078 if (
nullptr != raster_) { recls_key =
CVT_INT(raster_[gidx]); }
3079 else if (
nullptr != raster_2d_) {
3080 recls_key =
CVT_INT(raster_2d_[gidx][ilyr]);
3083 if (recls.count(recls_key) > 0 && recls.at(recls_key).size() > ilyr) {
3084 uniqe_value = recls.at(recls_key).at(ilyr);
3086 data1d[j * lyrs + ilyr] =
static_cast<T
>(uniqe_value);
3088 else if (out_origin && lyrs > 1 &&
nullptr != raster_2d_) {
3089 data1d[j * lyrs + ilyr] = raster_2d_[gidx][ilyr];
3091 else if (out_origin && lyrs == 1 &&
nullptr != raster_) {
3092 data1d[j * lyrs + ilyr] = raster_[gidx];
3094 else if (!out_origin && lyrs > 1 &&
nullptr != sub->data2d_) {
3095 data1d[j * lyrs + ilyr] =
static_cast<T
>(sub->data2d_[vi][ilyr]);
3097 else if (!out_origin && lyrs == 1 &&
nullptr != sub->data_) {
3098 data1d[j * lyrs + ilyr] =
static_cast<T
>(sub->data_[vi]);
3101 StatusMessage(
"Error: No subset or reclassification map can be output!");
3108 *datalen = data_length;
3113template <
typename T,
typename MASK_T>
3114bool clsRasterData<T, MASK_T>::OutputFullsizeToFiles(T* fullsizedata,
const int fsize,
const int datalyrs,
3115 const string& fullfilename,
3117 if (
nullptr == fullsizedata) {
return false; }
3118 if (datalyrs < 1) {
return false; }
3119 if (datalyrs == 1) {
3122 T* tmpdata1d =
nullptr;
3125 for (
int ilyr = 0; ilyr < datalyrs; ilyr++) {
3126 for (
int gi = 0; gi < fsize; gi++) {
3127 tmpdata1d[gi] = fullsizedata[gi * datalyrs + ilyr];
3130 header, opts, tmpdata1d);
3136template <
typename T,
typename MASK_T>
3141 int** position =
nullptr;
3142 int* position_idx =
nullptr;
3143 bool outputdirectly =
true;
3144 if ((
nullptr != pos_data_ ||
nullptr != pos_idx_)) {
3145 GetRasterPositionData(&count, &position);
3146 GetRasterPositionData(&count, &position_idx);
3147 outputdirectly =
false;
3148 assert(
nullptr != position);
3149 assert(
nullptr != position_idx);
3157 for (
int lyr = 0; lyr < n_lyrs_; lyr++) {
3160 std::ofstream raster_file(tmpfilename.c_str(), std::ios::app | std::ios::out);
3161 if (!raster_file.is_open()) {
3166 for (
int i = 0; i < rows; ++i) {
3167 for (
int j = 0; j < cols; ++j) {
3168 if (outputdirectly) {
3169 index = i * cols + j;
3170 raster_file << setprecision(6) << raster_2d_[index][lyr] <<
" ";
3173 if (index < n_cells_ && (position[index][0] == i && position[index][1] == j)) {
3174 raster_file << setprecision(6) << raster_2d_[index][lyr] <<
" ";
3176 }
else { raster_file << setprecision(6) <<
NODATA_VALUE <<
" "; }
3178 raster_file << endl;
3180 raster_file.close();
3184 std::ofstream raster_file(filename.c_str(), std::ios::app | std::ios::out);
3185 if (!raster_file.is_open()) {
3190 for (
int i = 0; i < rows; ++i) {
3191 for (
int j = 0; j < cols; ++j) {
3192 if (outputdirectly) {
3193 index = i * cols + j;
3194 raster_file << setprecision(6) << raster_[index] <<
" ";
3197 if (index < n_cells_) {
3198 if (position[index][0] == i && position[index][1] == j) {
3199 raster_file << setprecision(6) << raster_[index] <<
" ";
3201 }
else { raster_file << setprecision(6) << no_data_value_ <<
" "; }
3202 }
else { raster_file << setprecision(6) << no_data_value_ <<
" "; }
3204 raster_file << endl;
3206 raster_file.close();
3213template <
typename T,
typename MASK_T>
3216 bool outputdirectly = (
nullptr == pos_data_ ||
nullptr == pos_idx_);
3219 bool outflag =
false;
3220 T* data_1d =
nullptr;
3224 for (
int lyr = 0; lyr < n_lyrs_; lyr++) {
3226 if (outputdirectly) {
3227 if (
nullptr == data_1d) {
3230 for (
int gi = 0; gi < n_rows * n_cols; gi++) {
3231 data_1d[gi] = raster_2d_[gi][lyr];
3234 if (
nullptr == data_1d) {
3237 for (
int vi = 0; vi < n_cells_; vi++) {
3239 data_1d[pos_idx_[vi]] = raster_2d_[vi][lyr];
3250 if (outputdirectly) {
3254 for (
int vi = 0; vi < n_cells_; vi++) {
3256 data_1d[pos_idx_[vi]] = raster_[vi];
3261 if (!outflag) {
return false; }
3268template <
typename T,
typename MASK_T>
3271 bool include_nodata ,
3273 if (
nullptr == gfs) {
return false; }
3275 return OutputSubsetToMongoDB(gfs, filename, opts, include_nodata,
false,
true);
3285 bool outputdirectly =
true;
3287 int** pos =
nullptr;
3288 if ((
nullptr != pos_data_ ||
nullptr != pos_idx_) && include_nodata) {
3289 outputdirectly =
false;
3290 GetRasterPositionData(&cnt, &pos);
3292 if ((
nullptr == pos_data_ ||
nullptr == pos_idx_) && !include_nodata) {
3294 GetRasterPositionData(&cnt, &pos);
3296 int n_rows = GetRows();
3297 int n_cols = GetCols();
3298 int n_fullsize = n_rows * n_cols;
3299 if (include_nodata) {
3305 T* data_1d =
nullptr;
3306 T no_data_value = GetNoDataValue();
3308 string core_name = filename.empty() ? core_name_ : filename;
3310 if (outputdirectly) {
3311 data_1d = raster_2d_[0];
3312 datalength = n_lyrs_ * n_cells_;
3314 datalength = n_lyrs_ * n_fullsize;
3316 for (
int idx = 0; idx < n_cells_; idx++) {
3317 int rowcol_index = pos[idx][0] * n_cols + pos[idx][1];
3318 for (
int k = 0; k < n_lyrs_; k++) {
3319 data_1d[n_lyrs_ * rowcol_index + k] = raster_2d_[idx][k];
3324 if (outputdirectly) {
3326 datalength = n_cells_;
3328 datalength = n_fullsize;
3330 for (
int idx = 0; idx < n_cells_; idx++) {
3331 data_1d[pos[idx][0] * n_cols + pos[idx][1]] = raster_[idx];
3339 data_1d, datalength, options_);
3340 if (outputdirectly) {
3348template <
typename T,
typename MASK_T>
3350 const string& filename ,
3352 bool include_nodata ,
3355 const map<vint, vector<double> >& recls ,
3356 double default_value ) {
3357 if (!ValidateRasterData()) {
return false; }
3358 if (
nullptr == gfs) {
return false; }
3359 if (subset_.empty()) {
return false; }
3361 if (include_nodata) {
3374 int grows = GetRows();
3375 string outnameact = filename.empty() ? core_name_ : filename;
3376 bool out_comb = out_combined;
3378 T* data1d =
nullptr;
3381 bool flag = PrepareCombSubsetData(&data1d, &sublen, &sublyrs,
3382 out_origin, include_nodata, recls, default_value);
3388 tmpheader, data1d, sublen, options_);
3395 for (
auto it = subset_.begin(); it != subset_.end(); ++it) {
3396 if (!it->second->usable) {
continue; }
3397 it->second->GetHeader(GetXllCenter(), GetYllCenter(), grows,
3398 GetCellWidth(),
CVT_DBL(no_data_value_), subheader);
3399 T* tmpdata1d =
nullptr;
3402 if (!PrepareSubsetData(it->first, it->second, &tmpdata1d, &tmpdatalen, &tmplyrs,
3403 out_origin, include_nodata, recls, default_value)) {
3408 string tmpfname =
itoa(
CVT_VINT(it->first)) +
"_" + outnameact;
3418template <
typename T,
typename MASK_T>
3421 const bool use_mask_ext ,
3422 double default_value ,
3425 if (!initialized_) { InitializeRasterClass(); }
3427 return ConstructFromSingleFile(filename, calc_pos, mask, use_mask_ext, default_value, opts);
3430template <
typename T,
typename MASK_T>
3433 const bool use_mask_ext ,
3434 double default_value ,
3436 if (!
FilesExist(filenames)) {
return false; }
3437 n_lyrs_ =
CVT_INT(filenames.size());
3438 if (n_lyrs_ == 1) {
return ReadFromFile(filenames[0], calc_pos, mask, use_mask_ext, default_value, opts); }
3439 if (!initialized_) { InitializeRasterClass(
true); }
3442 if (!ConstructFromSingleFile(filenames[0], calc_pos, mask, use_mask_ext, default_value, opts)) {
3447 string::size_type last_underline = core_name_.find_last_of(
'_');
3448 if (last_underline == string::npos) {
3449 last_underline = core_name_.length();
3451 core_name_ = core_name_.substr(0, last_underline);
3456#pragma omp parallel for
3457 for (
int i = 0; i < n_cells_; i++) {
3458 raster_2d_[i][0] = raster_[i];
3461 int rows = GetRows();
3462 int cols = GetCols();
3464 for (
int fileidx = 1; fileidx <
CVT_INT(filenames.size()); fileidx++) {
3466 T* tmplyrdata =
nullptr;
3467 string curfilename = filenames[fileidx];
3477 StatusMessage(
"Warning: Only ASC format is supported without GDAL!");
3481 if (
nullptr != pos_data_ ||
nullptr != pos_idx_) {
3482#pragma omp parallel for
3483 for (
int i = 0; i < n_cells_; ++i) {
3486 int tmp_row = pos_idx_[i] / cols;
3487 int tmp_col = pos_idx_[i] % cols;
3488 AddOtherLayerRasterData(tmp_row, tmp_col, i, fileidx, tmpheader, tmplyrdata);
3492#pragma omp parallel for
3493 for (
int i = 0; i < rows; i++) {
3494 for (
int j = 0; j < cols; j++) {
3495 int cellidx = i * cols + j;
3496 if (
FloatEqual(no_data_value_, raster_2d_[cellidx][0])) {
3497 raster_2d_[cellidx][fileidx] = no_data_value_;
3500 AddOtherLayerRasterData(i, j, cellidx, fileidx, tmpheader, tmplyrdata);
3506 if(!is_2draster) is_2draster =
true;
3513template <
typename T,
typename MASK_T>
3515 const string& filename,
3516 const bool calc_pos ,
3518 const bool use_mask_ext ,
3519 double default_value ,
3521 InitializeReadFunction(filename, calc_pos, mask, use_mask_ext, default_value, opts);
3522 T* dbdata =
nullptr;
3530 if (!
ReadGridFsFile(gfs, filename, dbdata, header_dbl, header_str, opts_upd)) {
return false; }
3553 int fullsize = n_rows * n_cols;
3554 no_data_value_ =
static_cast<T
>(headers_.at(HEADER_RS_NODATA));
3557 if (include_nodata && n_cells_ != fullsize) {
return false; }
3558 if (n_cells_ != fullsize) { calc_pos_ =
true; }
3561 bool mask_pos_subset =
true;
3562 if (
nullptr != mask_ && calc_pos_ && use_mask_ext_ && n_cells_ == mask_->GetValidNumber()) {
3564 mask_->GetRasterPositionData(&n_cells_, &pos_data_);
3565 mask_->GetRasterPositionData(&n_cells_, &pos_idx_);
3567 map<int, SubsetPositions*>& mask_subset = mask_->GetSubset();
3568 for (
auto it = mask_subset.begin(); it != mask_subset.end(); ++it) {
3571#ifdef HAS_VARIADIC_TEMPLATES
3572 subset_.emplace(it->first, tmp);
3574 subset_.insert(make_pair(it->first, tmp));
3578 mask_pos_subset =
false;
3581 if (!include_nodata && (
nullptr == pos_data_ ||
nullptr == pos_idx_)) {
return false; }
3584 is_2draster =
false;
3585 if (include_nodata && !mask_pos_subset) {
3587#pragma omp parallel for
3588 for (
int i = 0; i < n_cells_; i++) {
3590 int tmpidx = pos_idx_[i];
3591 raster_[i] =
static_cast<T
>(dbdata[tmpidx]);
3599#pragma omp parallel for
3600 for (
int i = 0; i < n_cells_; i++) {
3602 if (include_nodata && !mask_pos_subset) {
3604 tmpidx = pos_idx_[i];
3606 for (
int j = 0; j < n_lyrs_; j++) {
3607 int idx = tmpidx * n_lyrs_ + j;
3608 raster_2d_[i][j] = dbdata[idx];
3614 CheckDefaultValue();
3615 if (include_nodata && mask_pos_subset) {
3616 return MaskAndCalculateValidPosition() >= 0;
3623template <
typename T,
typename MASK_T>
3625 const int cellidx,
const int lyr,
3628 double tmpnodata = lyrheader.at(HEADER_RS_NODATA);
3629 XY_COOR tmp_xy = GetCoordinateByRowCol(row, col);
3631 ROW_COL tmp_pos = GetPositionByCoordinate(tmp_xy.first, tmp_xy.second, &lyrheader);
3632 if (tmp_pos.first == -1 || tmp_pos.second == -1) {
3633 raster_2d_[cellidx][lyr] = no_data_value_;
3635 T tmpvalue = lyrdata[tmp_pos.first * tmpcols + tmp_pos.second];
3636 raster_2d_[cellidx][lyr] =
FloatEqual(tmpvalue, tmpnodata) ? no_data_value_ : tmpvalue;
3640template <
typename T,
typename MASK_T>
3642 InitializeRasterClass();
3646template <
typename T,
typename MASK_T>
3649 if (is_2draster &&
nullptr != raster_2d_ && n_cells_ > 0) {
3652 if (!is_2draster &&
nullptr != raster_) {
3655 if (
nullptr != pos_data_) {
3658 if (
nullptr != pos_idx_) {
3661 if (stats_calculated_) {
3662 ReleaseStatsMap2D();
3663 stats_calculated_ =
false;
3665 if (!subset_.empty()) {
3672 n_cells_ = orgraster->GetCellNumber();
3673 n_lyrs_ = orgraster->GetLayers();
3677 if (orgraster->Is2DRaster()) {
3690 if (stats_calculated_) {
3693 for (
auto iter = stats2D.begin(); iter != stats2D.end(); ++iter) {
3694 double* tmpstatvalues =
nullptr;
3696 stats_2d_.at(iter->first) = tmpstatvalues;
3700 for (
auto iter = stats.begin(); iter != stats.end(); ++iter) {
3701 stats_[iter->first] = iter->second;
3708 for (
auto it = orgraster->
GetSubset().begin(); it != orgraster->
GetSubset().end(); ++it) {
3710#ifdef HAS_VARIADIC_TEMPLATES
3711 subset_.emplace(it->first, tmp);
3713 subset_.insert(make_pair(it->first, tmp));
3719template <
typename T,
typename MASK_T>
3721#pragma omp parallel for
3722 for (
int i = 0; i < n_cells_; i++) {
3723 for (
int lyr = 0; lyr < n_lyrs_; lyr++) {
3724 bool flag = is_2draster &&
nullptr != raster_2d_
3725 ?
FloatEqual(raster_2d_[i][lyr], no_data_value_)
3727 if (!flag) {
continue; }
3728 if (is_2draster &&
nullptr != raster_2d_) {
3729 raster_2d_[i][lyr] = replacedv;
3730 }
else if (
nullptr != raster_) {
3731 raster_[i] = replacedv;
3735 no_data_value_ = replacedv;
3736 default_value_ =
CVT_DBL(replacedv);
3740template <
typename T,
typename MASK_T>
3743 for(
auto it = reclass_map.begin(); it != reclass_map.end(); ++it) {
3744#ifdef HAS_VARIADIC_TEMPLATES
3745 recls.emplace(it->first, it->second);
3747 recls.insert(make_pair(it->first, it->second));
3750 for (
int i = 0; i < n_cells_; i++) {
3751 for (
int lyr = 0; lyr < n_lyrs_; lyr++) {
3752 T curv = is_2draster &&
nullptr != raster_2d_
3755 if (recls.count(curv) < 0) {
3756#ifdef HAS_VARIADIC_TEMPLATES
3757 recls.emplace(curv, no_data_value_);
3759 recls.insert(make_pair(curv, no_data_value_));
3762 if (is_2draster &&
nullptr != raster_2d_) {
3763 raster_2d_[i][lyr] = recls.at(curv);
3764 }
else if (
nullptr != raster_) {
3765 raster_[i] = recls.at(curv);
3773template <
typename T,
typename MASK_T>
3775 return XY_COOR(GetXllCenter() + col * GetCellWidth(),
3776 GetYllCenter() + (GetRows() - row - 1) * GetCellWidth());
3779template <
typename T,
typename MASK_T>
3782 if (
nullptr == header) { header = &headers_; }
3790 double x_min = xll_center - dx / 2.;
3791 double x_max = x_min + dx * n_cols;
3793 double y_min = yll_center - dy / 2.;
3794 double y_max = y_min + dy * n_rows;
3795 if ((x > x_max || x < xll_center) || (y > y_max || y < yll_center)) {
3801template <
typename T,
typename MASK_T>
3804 vector<vector<T> > values_2d;
3805 vector<int> pos_rows;
3806 vector<int> pos_cols;
3810 for (
int i = 0; i < nrows; ++i) {
3811 for (
int j = 0; j < ncols; ++j) {
3812 int idx = i * ncols + j;
3815 tmp_value = raster_2d_[idx][0];
3817 tmp_value = raster_[idx];
3819 if (
FloatEqual(tmp_value,
static_cast<T
>(no_data_value_)))
continue;
3820 values.emplace_back(tmp_value);
3821 if (is_2draster && n_lyrs_ > 1) {
3822 vector<T> tmpv(n_lyrs_ - 1);
3823 for (
int lyr = 1; lyr < n_lyrs_; lyr++) {
3824 tmpv[lyr - 1] = raster_2d_[idx][lyr];
3826 values_2d.emplace_back(tmpv);
3828 pos_rows.emplace_back(i);
3829 pos_cols.emplace_back(j);
3832 vector<T>(values).swap(values);
3833 if (is_2draster && n_lyrs_ > 1) {
3834 vector<vector<T> >(values_2d).swap(values_2d);
3836 vector<int>(pos_rows).swap(pos_rows);
3837 vector<int>(pos_cols).swap(pos_cols);
3839 n_cells_ =
CVT_INT(values.size());
3852#pragma omp parallel for
3853 for (
int i = 0; i < n_cells_; ++i) {
3855 raster_2d_[i][0] = values.at(i);
3857 for (
int lyr = 1; lyr < n_lyrs_; lyr++) {
3858 raster_2d_[i][lyr] = values_2d[i][lyr - 1];
3862 raster_[i] = values.at(i);
3864 pos_data_[i][0] = pos_rows.at(i);
3865 pos_data_[i][1] = pos_cols.at(i);
3866 pos_idx_[i] = pos_rows.at(i) * ncols + pos_cols.at(i);
3871template <
typename T,
typename MASK_T>
3872int clsRasterData<T, MASK_T>::MaskAndCalculateValidPosition() {
3873 int old_fullsize = GetRows() * GetCols();
3874 if (
nullptr == mask_) {
3876 if (
nullptr == pos_data_ ||
nullptr == pos_idx_) {
3877 CalculateValidPositionsFromGridData();
3882 n_cells_ = old_fullsize;
3890 int** valid_pos =
nullptr;
3891 int mask_rows = mask_->GetRows();
3892 int mask_cols = mask_->GetCols();
3894 if (!mask_->PositionsCalculated()) { mask_->SetCalcPositions(); }
3895 mask_->GetRasterPositionData(&mask_ncells, &valid_pos);
3897 vector<T> values(mask_ncells);
3898 vector<vector<T> > values_2d(mask_ncells);
3899 vector<int> pos_rows(mask_ncells);
3900 vector<int> pos_cols(mask_ncells);
3903 int min_row = mask_rows;
3905 int min_col = mask_cols;
3906 int masked_count = 0;
3907 int matched_count = 0;
3909 for (
int i = 0; i < mask_ncells; i++) {
3910 int tmp_row = valid_pos[i][0];
3911 int tmp_col = valid_pos[i][1];
3912 XY_COOR tmp_xy = mask_->GetCoordinateByRowCol(tmp_row, tmp_col);
3913 ROW_COL tmp_pos = GetPositionByCoordinate(tmp_xy.first, tmp_xy.second);
3915 if (tmp_pos.first == -1 || tmp_pos.second == -1) {
3916 tmp_value = no_data_value_;
3917 if (is_2draster && n_lyrs_ > 1) {
3918 vector<T> tmp_values(n_lyrs_ - 1);
3919 for (
int lyr = 1; lyr < n_lyrs_; lyr++) { tmp_values[lyr - 1] = no_data_value_; }
3920 values_2d[i] = tmp_values;
3922 values[i] = tmp_value;
3923 pos_rows[i] = tmp_row;
3924 pos_cols[i] = tmp_col;
3927 tmp_value = GetValue(tmp_pos.first, tmp_pos.second, 1);
3929 if (!
FloatEqual(default_value_, no_data_value_)) {
3930 tmp_value =
static_cast<T
>(default_value_);
3931 SetValue(tmp_pos.first, tmp_pos.second, tmp_value);
3935 if (max_row < tmp_row) max_row = tmp_row;
3936 if (min_row > tmp_row) min_row = tmp_row;
3937 if (max_col < tmp_col) max_col = tmp_col;
3938 if (min_col > tmp_col) min_col = tmp_col;
3940 if (is_2draster && n_lyrs_ > 1) {
3941 vector<T> tmp_values(n_lyrs_ - 1);
3942 for (
int lyr = 1; lyr < n_lyrs_; lyr++) {
3943 tmp_values[lyr - 1] = GetValue(tmp_pos.first, tmp_pos.second, lyr + 1);
3944 if (
FloatEqual(tmp_values[lyr - 1], no_data_value_)
3945 && !
FloatEqual(default_value_, no_data_value_)) {
3946 tmp_values[lyr - 1] =
static_cast<T
>(default_value_);
3947 SetValue(tmp_pos.first, tmp_pos.second, tmp_values[lyr - 1], lyr - 1);
3950 values_2d[i] = tmp_values;
3952 values[i] = tmp_value;
3953 pos_rows[i] = tmp_row;
3954 pos_cols[i] = tmp_col;
3957 if (masked_count == 0) {
return -1; }
3958 n_cells_ = masked_count;
3961 CopyHeader(mask_->GetRasterHeader(), headers_);
3962 UpdateHeader(headers_, HEADER_RS_NODATA, no_data_value_);
3967 map<int, SubsetPositions*>& mask_subset = mask_->GetSubset();
3968 bool mask_has_subset = !mask_subset.empty();
3969 if (mask_has_subset) {
3971 for (
auto it = mask_subset.begin(); it != mask_subset.end(); ++it) {
3972 SubsetPositions* tmp =
new SubsetPositions(it->second,
true);
3973 tmp->n_lyrs = n_lyrs_;
3974#ifdef HAS_VARIADIC_TEMPLATES
3975 subset_.emplace(it->first, tmp);
3977 subset_.insert(make_pair(it->first, tmp));
3984 bool match_exactly = matched_count == mask_ncells;
3987 bool within_ext =
true;
3988 int new_rows = max_row - min_row + 1;
3989 int new_cols = max_col - min_col + 1;
3990 if (new_rows != mask_rows || new_cols != mask_cols) {
3994 assert(masked_count == mask_ncells);
3996 bool upd_header_rowcol =
false;
3997 bool recalc_pos =
false;
3998 bool upd_header_valid_num =
false;
3999 bool store_fullsize =
false;
4000 bool recalc_subset =
false;
4004 upd_header_rowcol =
false;
4005 if (use_mask_ext_) {
4007 recalc_pos = !match_exactly;
4008 upd_header_valid_num = recalc_pos;
4009 store_fullsize =
false;
4013 upd_header_valid_num =
false;
4014 store_fullsize =
false;
4020 recalc_pos = !match_exactly;
4021 upd_header_valid_num = recalc_pos;
4022 store_fullsize =
false;
4026 upd_header_valid_num =
true;
4027 store_fullsize =
false;
4033 if (use_mask_ext_) {
4034 upd_header_rowcol =
false;
4036 recalc_pos = !match_exactly;
4037 upd_header_valid_num = recalc_pos;
4038 store_fullsize =
false;
4042 upd_header_valid_num =
false;
4043 store_fullsize =
false;
4048 upd_header_rowcol =
true;
4049 upd_header_valid_num =
true;
4052 store_fullsize =
false;
4056 store_fullsize =
true;
4061 if (mask_has_subset && !match_exactly && upd_header_rowcol) {
4062 recalc_subset =
true;
4065 if (upd_header_rowcol) {
4068 headers_.at(
HEADER_RS_XLL) += min_col * mask_->GetCellWidth();
4069 headers_.at(
HEADER_RS_YLL) += (mask_rows - max_row - 1) * mask_->GetCellWidth();
4076 auto rit = pos_rows.begin();
4077 auto cit = pos_cols.begin();
4078 auto vit = values.begin();
4079 auto data2dit = values_2d.begin();
4080 for (
auto it = values.begin(); it != values.end();) {
4081 size_t idx = distance(vit, it);
4082 int tmpr = pos_rows.at(idx);
4083 int tmpc = pos_cols.at(idx);
4084 if (tmpr > max_row || tmpr < min_row || tmpc > max_col || tmpc < min_col
4085 ||
FloatEqual(
static_cast<T
>(*it), no_data_value_)) {
4086 it = values.erase(it);
4087 if (is_2draster && n_lyrs_ > 1) {
4088 values_2d.erase(data2dit + idx);
4089 data2dit = values_2d.begin();
4091 pos_cols.erase(cit + idx);
4092 pos_rows.erase(rit + idx);
4093 rit = pos_rows.begin();
4094 cit = pos_cols.begin();
4095 vit = values.begin();
4097 pos_rows[idx] -= min_row;
4098 pos_cols[idx] -= min_col;
4102 vector<T>(values).swap(values);
4103 if (is_2draster && n_lyrs_ > 1) { vector<vector<T> >(values_2d).swap(values_2d); }
4104 vector<int>(pos_rows).swap(pos_rows);
4105 vector<int>(pos_cols).swap(pos_cols);
4108 n_cells_ =
CVT_INT(values.size());
4113 for (
size_t k = 0; k < pos_rows.size(); ++k) {
4114 pos_data_[k][0] = pos_rows.at(k);
4115 pos_data_[k][1] = pos_cols.at(k);
4116 if (upd_header_rowcol) {
4117 pos_idx_[k] = pos_rows.at(k) * new_cols + pos_cols.at(k);
4119 pos_idx_[k] = pos_rows.at(k) * mask_cols + pos_cols.at(k);
4126 mask_->GetRasterPositionData(&n_cells_, &pos_data_);
4127 mask_->GetRasterPositionData(&n_cells_, &pos_idx_);
4134 assert(ValidateRasterData());
4137 if (store_fullsize) {
4138 n_cells_ = ncols * nrows;
4140 bool release_origin =
true;
4141 if (store_fullsize && old_fullsize == n_cells_) {
4142 release_origin =
false;
4144 if (release_origin) {
4145 if (is_2draster &&
nullptr != raster_2d_) {
4153 size_t synthesis_idx = 0;
4154 for (
size_t k = 0; k < pos_rows.size(); ++k) {
4156 int tmpr = pos_rows.at(k);
4157 int tmpc = pos_cols.at(k);
4158 if (store_fullsize) {
4159 if (tmpr > max_row || tmpr < min_row || tmpc > max_col || tmpc < min_col) {
4162 synthesis_idx = (tmpr - min_row) * ncols + tmpc - min_col;
4163 if (synthesis_idx > n_cells_ - 1) {
4168 raster_2d_[synthesis_idx][0] = values.at(k);
4170 for (
int lyr = 1; lyr < n_lyrs_; lyr++) {
4171 raster_2d_[synthesis_idx][lyr] = values_2d[k][lyr - 1];
4175 raster_[synthesis_idx] = values.at(k);
4180 if (upd_header_valid_num) {
4184 if (mask_has_subset) {
4185 for (
auto it = subset_.begin(); it != subset_.end();) {
4191 vector<int> globalpos;
4192 for (
int i = 0; i < it->second->n_cells; i++) {
4193 int gi = it->second->global_[i];
4194 int tmprow = valid_pos[gi][0];
4195 int tmpcol = valid_pos[gi][1];
4196 XY_COOR tmpxy = mask_->GetCoordinateByRowCol(tmprow, tmpcol);
4197 if (GetPosition(tmpxy.first, tmpxy.second) < 0) {
continue; }
4198 ROW_COL tmppos = GetPositionByCoordinate(tmpxy.first, tmpxy.second);
4199 if (IsNoData(tmppos.first, tmppos.second)) {
continue; }
4200 if (tmppos.first < srow) { srow = tmppos.first; }
4201 if (tmppos.first > erow) { erow = tmppos.first; }
4202 if (tmppos.second < scol) { scol = tmppos.second; }
4203 if (tmppos.second > ecol) { ecol = tmppos.second; }
4204 globalpos.emplace_back(GetPosition(tmppos.first, tmppos.second));
4209 subset_.erase(it++);
4212 if (recalc_subset) {
4213 it->second->g_srow = srow;
4214 it->second->g_erow = erow;
4215 it->second->g_scol = scol;
4216 it->second->g_ecol = ecol;
4217 it->second->n_cells = count;
4218 it->second->n_lyrs = n_lyrs_;
4219 int local_ncols = ecol - scol + 1;
4220 if (it->second->alloc_) {
4225 it->second->global_ =
nullptr;
4226 it->second->local_pos_ =
nullptr;
4227 it->second->local_posidx_ =
nullptr;
4228 it->second->alloc_ =
true;
4232 for (
int ii = 0; ii < count; ii++) {
4233 it->second->global_[ii] = globalpos[ii];
4236 if (
nullptr == pos_data_ ||
nullptr == pos_idx_) {
4237 local_row = globalpos[ii] / ncols - it->second->g_srow;
4238 local_col = globalpos[ii] % ncols - it->second->g_scol;
4242 local_row = pos_idx_[globalpos[ii]] / ncols - it->second->g_srow;
4243 local_col = pos_idx_[globalpos[ii]] % ncols - it->second->g_scol;
4245 it->second->local_pos_[ii][0] = local_row;
4246 it->second->local_pos_[ii][1] = local_col;
4247 it->second->local_posidx_[ii] = local_row * local_ncols + local_col;
4249 it->second->data_ =
nullptr;
4250 it->second->data2d_ =
nullptr;
4251 it->second->alloc_ =
true;
4256 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:1086
int * global_
global position index
Definition: data_raster.hpp:1168
int * local_posidx_
local position index
Definition: data_raster.hpp:1167
double ** data2d_
valid 2d data array
Definition: data_raster.hpp:1170
int n_cells
valid cell count
Definition: data_raster.hpp:1159
int g_erow
end row in global data
Definition: data_raster.hpp:1162
bool alloc_
local_pos_ and global_ are allocated?
Definition: data_raster.hpp:1165
bool usable
flag for usable subset data
Definition: data_raster.hpp:1158
int g_ecol
end col in global data
Definition: data_raster.hpp:1164
int ** local_pos_
local position data
Definition: data_raster.hpp:1166
double * data_
valid data array
Definition: data_raster.hpp:1169
int g_srow
start row in global data
Definition: data_raster.hpp:1161
int n_lyrs
layer count
Definition: data_raster.hpp:1160
int g_scol
start col in global data
Definition: data_raster.hpp:1163
Raster data (1D and 2D) I/O class Support I/O among ASCII file, TIFF, and MongoDB database.
Definition: data_raster.hpp:1179
const STRDBL_MAP & GetRasterHeader() const
Get raster header information.
Definition: data_raster.hpp:1688
clsRasterData(bool is_2d=false)
Constructor an empty clsRasterData instance for 1D or 2D raster.
Definition: data_raster.hpp:2074
bool OutputFileByGdal(const string &filename)
Write 1D or 2D raster data into TIFF file by GDAL.
Definition: data_raster.hpp:3214
RasterDataType GetOutDataType() const
Get data type of source.
Definition: data_raster.hpp:1656
XY_COOR GetCoordinateByRowCol(int row, int col)
Calculate XY coordinates by given row and col number.
Definition: data_raster.hpp:3774
bool SetUseMaskExt()
Set the flag of use_mask_ext_ to true and recalculate positions and stored raster data if necessary.
Definition: data_raster.hpp:2840
~clsRasterData()
Destructor.
Definition: data_raster.hpp:2327
bool ReleaseSubset()
Release subsets.
Definition: data_raster.hpp:2407
bool MaskExtented() const
position data is allocated or a pointer
Definition: data_raster.hpp:1758
string GetFullFileName() const
Get full filename.
Definition: data_raster.hpp:1810
double GetCellWidth() const
Get row number.
Definition: data_raster.hpp:1630
int ** GetRasterPositionDataPointer() const
Get pointer of raster 1D data.
Definition: data_raster.hpp:1712
bool SetPositions(int len, int **pdata)
Set valid positions data, without mask raster layer.
Definition: data_raster.hpp:2816
int * GetRasterPositionIndexPointer() const
Get pointer of position data.
Definition: data_raster.hpp:1713
double GetYllCenter() const
Get Y coordinate of left lower center of raster data.
Definition: data_raster.hpp:1644
string GetCoreName() const
Get core name.
Definition: data_raster.hpp:1700
bool OutputAscFile(const string &filename)
Write 1D or 2D raster data into ASC file(s)
Definition: data_raster.hpp:3137
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:3514
int GetDataLength() const
Get the first dimension size.
Definition: data_raster.hpp:1627
bool GetRasterData(int *n_cells, T **data)
Get raster data, include valid cell number and data.
Definition: data_raster.hpp:2615
bool StatisticsCalculated() const
Use mask extent or not.
Definition: data_raster.hpp:1759
string GetFilePath() const
Get full path name.
Definition: data_raster.hpp:1697
double GetRange(const int lyr=1)
Get the range of raster data.
Definition: data_raster.hpp:1579
string GetSrsString()
Get the spatial reference (char*)
Definition: data_raster.hpp:2682
void SetDataType(RasterDataType const type)
Set raster data type.
Definition: data_raster.hpp:1482
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:2150
double GetStatistics(string sindex, int lyr=1)
Get basic statistics value Mean, Max, Min, STD, Range, etc.
Definition: data_raster.hpp:2485
void GetStd(int *lyrnum, double **values)
Get the standard derivation of 2D raster data.
Definition: data_raster.hpp:1604
clsRasterData< MASK_T > * GetMask() const
Get mask data pointer.
Definition: data_raster.hpp:1813
void SetDefaultValue(const double defaultv)
Set default value.
Definition: data_raster.hpp:1494
double GetMinimum(const int lyr=1)
Get the minimum of raster data.
Definition: data_raster.hpp:1566
bool ValidateRowCol(const int row, const int col)
Validate the input row and col.
Definition: data_raster.hpp:1776
int GetPosition(int row, int col)
Get default value.
Definition: data_raster.hpp:2542
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:3269
const STRDBL_MAP & GetStatistics() const
Get raster statistics information.
Definition: data_raster.hpp:1691
void SetValue(int row, int col, T value, int lyr=1)
Set value to the given position and layer.
Definition: data_raster.hpp:2786
T ** Get2DRasterDataPointer() const
Get pointer of position data.
Definition: data_raster.hpp:1714
void ReleaseStatsMap2D()
Release statistics map of 2D raster data.
Definition: data_raster.hpp:2468
bool ValidateLayer(const int lyr)
Validate the input layer number.
Definition: data_raster.hpp:1788
ROW_COL GetPositionByCoordinate(double x, double y, STRDBL_MAP *header=nullptr)
Calculate position by given coordinate.
Definition: data_raster.hpp:3780
bool PositionsAllocated() const
Calculate positions or not.
Definition: data_raster.hpp:1757
void Reclassify(map< int, T > reclass_map)
classify raster
Definition: data_raster.hpp:3741
const map< string, double * > & GetStatistics2D() const
Get raster statistics information of 2D raster.
Definition: data_raster.hpp:1694
double GetAverage(const int lyr=1)
Get the average of raster data.
Definition: data_raster.hpp:1554
T GetValueByIndex(int cell_index, int lyr=1)
Get options.
Definition: data_raster.hpp:2696
void GetAverage(int *lyrnum, double **values)
Get the average of 2D raster data.
Definition: data_raster.hpp:1586
void SetDataType(const string &strtype)
Set raster data type.
Definition: data_raster.hpp:1485
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:2419
const char * GetSrs()
Get pointer of raster 2D data.
Definition: data_raster.hpp:2677
int GetValidNumber(const int lyr=1)
Get the non-NoDATA cells number of the given raster layer data.
Definition: data_raster.hpp:1623
void UpdateStatistics()
Force to update basic statistics values Mean, Max, Min, STD, Range, etc.
Definition: data_raster.hpp:2478
int GetRows() const
Get column number.
Definition: data_raster.hpp:1629
void ReplaceNoData(T replacedv)
Replace NoData value by the given value.
Definition: data_raster.hpp:3720
void SetOutDataType(RasterDataType type)
Set output raster data type.
Definition: data_raster.hpp:2426
T GetNoDataValue() const
Get data type of output.
Definition: data_raster.hpp:1657
map< int, SubsetPositions * > & GetSubset()
Get subset.
Definition: data_raster.hpp:1674
RasterDataType GetDataType() const
Get layer number.
Definition: data_raster.hpp:1655
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:3431
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:2851
void GetValidNumber(int *lyrnum, double **values)
Get the non-NoDATA number of 2D raster data.
Definition: data_raster.hpp:1616
double GetMaximum(const int lyr=1)
Get the maximum of raster data.
Definition: data_raster.hpp:1560
void Copy(clsRasterData< T, MASK_T > *orgraster)
Copy clsRasterData object.
Definition: data_raster.hpp:3647
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:2872
bool ValidateIndex(const int idx)
Validate the input index.
Definition: data_raster.hpp:1801
double GetXllCenter() const
Get cell size.
Definition: data_raster.hpp:1633
void GetRange(int *lyrnum, double **values)
Get the range of 2D raster data.
Definition: data_raster.hpp:1610
double GetDefaultValue() const
Get NoDATA value.
Definition: data_raster.hpp:1658
const STRING_MAP & GetOptions() const
Get option by key, including the spatial reference by "SRS".
Definition: data_raster.hpp:1718
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:2627
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:2726
string GetOption(const char *key)
Get the spatial reference (string)
Definition: data_raster.hpp:2687
void CalculateStatistics()
Calculate basic statistics values in one time Mean, Max, Min, STD, Range, etc.
Definition: data_raster.hpp:2439
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:1751
void GetMinimum(int *lyrnum, double **values)
Get the minimum of 2D raster data.
Definition: data_raster.hpp:1598
bool PositionsCalculated() const
Is 2D raster data?
Definition: data_raster.hpp:1756
bool Initialized() const
Basic statistics calculated?
Definition: data_raster.hpp:1760
bool ValidateRasterData()
Instance of clsRasterData initialized?
Definition: data_raster.hpp:1765
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:3349
double GetStd(const int lyr=1)
Get the stand derivation of raster data.
Definition: data_raster.hpp:1572
void SetCoreName(const string &name)
Set new core file name.
Definition: data_raster.hpp:1456
void GetMaximum(int *lyrnum, double **values)
Get the maximum of 2D raster data.
Definition: data_raster.hpp:1592
bool SetCalcPositions()
Set the flag of calc_pos_ to true and recalculate positions and stored raster data if necessary.
Definition: data_raster.hpp:2805
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:2338
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:3419
void GetRasterPositionData(int *datalength, int ***positiondata)
Get position index data and the data length.
Definition: data_raster.hpp:2641
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:336
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:411
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:442
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:391
#define CONST_CHARS
const string
Definition: data_raster.hpp:73
Simple wrappers of the API of MongoDB C driver mongo-c-driver, see MongoDB C Driver for more informat...
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:104
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:989
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:359
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:585
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:839
CONST_CHARS STATS_RS_MEAN
Valid cell number.
Definition: data_raster.hpp:107
CONST_CHARS HEADER_RS_CELLSNUM
Layers number.
Definition: data_raster.hpp:99
CONST_CHARS HEADER_RS_PARAM_ABSTRACTION_TYPE
SRS.
Definition: data_raster.hpp:101
CONST_CHARS HEADER_RS_YLL
X coordinate value of left low center.
Definition: data_raster.hpp:92
CONST_CHARS STATS_RS_VALIDNUM
Mask layer's name if only store valid values.
Definition: data_raster.hpp:106
RasterDataType
Coordinate pair.
Definition: data_raster.hpp:121
@ RDT_UInt16
GDT_UInt16.
Definition: data_raster.hpp:125
@ RDT_Int32
GDT_Int32.
Definition: data_raster.hpp:128
@ RDT_UInt32
GDT_UInt32.
Definition: data_raster.hpp:127
@ RDT_Int64
GDT_Int64, GDAL>=3.5.
Definition: data_raster.hpp:130
@ RDT_Float
GDT_Float32.
Definition: data_raster.hpp:131
@ RDT_UInt64
GDT_UInt64, GDAL>=3.5.
Definition: data_raster.hpp:129
@ RDT_Double
GDT_Float64.
Definition: data_raster.hpp:132
@ RDT_Int16
GDT_Int16.
Definition: data_raster.hpp:126
@ RDT_Unknown
GDT_Unknown.
Definition: data_raster.hpp:122
@ RDT_Int8
GDT_Int8, GDAL>=3.7.
Definition: data_raster.hpp:124
@ RDT_UInt8
GDT_Byte.
Definition: data_raster.hpp:123
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:325
CONST_CHARS GTiffExtension
ASCII extension.
Definition: data_raster.hpp:113
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
spatial parameter type, physical or conceptual
Definition: data_raster.hpp:102
CONST_CHARS STATS_RS_MIN
Mean value.
Definition: data_raster.hpp:108
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:98
CONST_CHARS STATS_RS_RANGE
Standard derivation value.
Definition: data_raster.hpp:111
CONST_CHARS ASCIIExtension
Range value.
Definition: data_raster.hpp:112
CONST_CHARS HEADER_RSOUT_DATATYPE
Data type of original raster.
Definition: data_raster.hpp:103
CONST_CHARS HEADER_RS_SRS
Number of the first layer's valid cells.
Definition: data_raster.hpp:100
void InitialStatsMap(STRDBL_MAP &stats, map< string, double * > &stats2d)
Initialize statistics values for 1D and 2D raster data.
Definition: data_raster.cpp:173
std::pair< int, int > ROW_COL
GeoTIFF extension.
Definition: data_raster.hpp:115
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:110
CONST_CHARS HEADER_RS_CELLSIZE
Column number.
Definition: data_raster.hpp:97
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:94
CONST_CHARS HEADER_MASK_NAME
Include nodata ("TRUE") or not ("FALSE"), for DB only.
Definition: data_raster.hpp:105
CONST_CHARS STATS_RS_MAX
Minimum value.
Definition: data_raster.hpp:109
std::pair< double, double > XY_COOR
Row and Col pair.
Definition: data_raster.hpp:116
void UpdateHeader(STRDBL_MAP &header, const string &key, T val)
Update value in header information.
Definition: data_raster.hpp:177
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:870
CONST_CHARS HEADER_RS_NCOLS
Rows number.
Definition: data_raster.hpp:96
CONST_CHARS HEADER_RS_XLLCOR
Y coordinate value of left low center.
Definition: data_raster.hpp:93
CONST_CHARS HEADER_RS_NROWS
Y coordinate value of left low center.
Definition: data_raster.hpp:95
bool ReadAscFile(const string &filename, STRDBL_MAP &header, T *&values)
Read raster data from ASC file, the simply usage.
Definition: data_raster.hpp:215
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:91
void AppendStringOptionsToBson(bson_t *bson_opts, const STRING_MAP &opts, const string &prefix)
Append options to bson_t
Definition: db_mongoc.cpp:481
string GetStringFromBsonIterator(bson_iter_t *iter)
Get String from the iterator (bson_iter_t) of bson_t
Definition: db_mongoc.cpp:503
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:191
void Release1DArray(T *&data)
Release DT_Array1D data.
Definition: utils_array.h:460
bool Initialize1DArray(int row, T *&data, INI_T init_value)
Initialize DT_Array1D data.
Definition: utils_array.h:331
bool Initialize2DArray(int row, int col, T **&data, INI_T init_value)
Initialize DT_Array2D data.
Definition: utils_array.h:381
void Release2DArray(T **&data)
Release DT_Array2D data.
Definition: utils_array.h:468
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:311
string GetAbsolutePath(string const &full_filename)
Return the absolute file path from a given file path.
Definition: utils_filesystem.cpp:283
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:328
string GetPathFromFullName(string const &full_filename)
Get Path From full file path string.
Definition: utils_filesystem.cpp:350
string ReplaceSuffix(string const &full_filename, string const &new_suffix)
Replace the suffix by a given suffix.
Definition: utils_filesystem.cpp:320
string GetCoreFileName(string const &full_filename)
Return the file name from a given file's path.
Definition: utils_filesystem.cpp:296
string PrefixCoreFileName(string const &full_filename, string const &prestr, char deli)
Add a prefix to the core filename.
Definition: utils_filesystem.cpp:339
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:139
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:372
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:382
bool FloatEqual(T1 v1, T2 v2)
Whether v1 is equal to v2.
Definition: utils_math.h:141
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:152
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:250
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:306
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.