24 #include "iclass_local_proto.h" 30 struct Range rast_range;
42 static int get_cat_rast_header(
struct Cell_head *region,
char *header)
44 return sprintf(header,
"P5\n%d\n%d\n1\n", region->
cols, region->
rows);
61 char cat_rast_header[1024];
65 unsigned char *row_data;
67 f_cat_rast = fopen(cat_rast,
"wb");
69 G_warning(
"Unable to create category raster condition file <%s>.",
74 head_nchars = get_cat_rast_header(cat_rast_region, cat_rast_header);
76 fwrite(cat_rast_header,
sizeof(
char), head_nchars /
sizeof(
char),
78 if (ferror(f_cat_rast)) {
81 (
"Unable to write header into category raster condition file <%s>."),
88 sizeof(
unsigned char));
89 for (i_col = 0; i_col < cat_rast_region->
cols; i_col++)
90 row_data[i_col] = 0 & 255;
92 for (i_row = 0; i_row < cat_rast_region->
rows; i_row++) {
93 fwrite(row_data,
sizeof(
unsigned char),
94 (cat_rast_region->
cols) /
sizeof(
unsigned char), f_cat_rast);
95 if (ferror(f_cat_rast)) {
98 (
"Unable to write into category raster condition file <%s>."),
154 if (intersec->
east == intersec->
west)
179 float ns_res, ew_res;
186 "'get_rows_and_cols_bounds' ns_res does not fit, A->ns_res: %f B->ns_res: %f",
193 "'get_rows_and_cols_bounds' ew_res does not fit, A->ew_res: %f B->ew_res: %f",
201 if (regions_intersecion(A, B, &intersec) == -1)
205 ceil((A->
north - intersec.
north - ns_res * 0.5) / ns_res);
207 ceil((A->
north - intersec.
south - ns_res * 0.5) / ns_res);
209 A_bounds->
east = ceil((intersec.
east - A->
west - ew_res * 0.5) / ew_res);
210 A_bounds->
west = ceil((intersec.
west - A->
west - ew_res * 0.5) / ew_res);
213 ceil((B->
north - intersec.
north - ns_res * 0.5) / ns_res);
215 ceil((B->
north - intersec.
south - ns_res * 0.5) / ns_res);
217 B_bounds->
east = ceil((intersec.
east - B->
west - ew_res * 0.5) / ew_res);
218 B_bounds->
west = ceil((intersec.
west - B->
west - ew_res * 0.5) / ew_res);
238 const char *cat_rast)
242 struct Cell_head patch_region, patch_bounds, cat_rast_bounds;
243 char cat_rast_header[1024];
244 int i_row, i_col, ncols, nrows, patch_col;
245 int head_nchars, ret;
246 int fd_patch_rast, init_shift, step_shift;
247 unsigned char *patch_data;
249 char *null_chunk_row;
253 f_cat_rast = fopen(cat_rast,
"rb+");
255 G_warning(
_(
"Unable to open category raster conditions file <%s>."),
260 head_nchars = get_cat_rast_header(cat_rast_region, cat_rast_header);
263 G_warning(
_(
"Unable to find patch raster <%s>."), patch_rast);
270 if ((fd_patch_rast =
Rast_open_old(patch_rast, mapset)) < 0) {
276 get_rows_and_cols_bounds(cat_rast_region, &patch_region,
277 &cat_rast_bounds, &patch_bounds);
280 (
"Resolutions of patch <%s> and patched file <%s> are not same."),
281 patch_rast, cat_rast);
288 else if (ret == -1) {
296 ncols = cat_rast_bounds.
east - cat_rast_bounds.
west;
297 nrows = cat_rast_bounds.
south - cat_rast_bounds.
north;
299 patch_data = (
unsigned char *)
G_malloc(ncols *
sizeof(
unsigned char));
302 head_nchars + cat_rast_region->
cols * cat_rast_bounds.
north +
303 cat_rast_bounds.
west;
305 if (fseek(f_cat_rast, init_shift, SEEK_SET) != 0) {
307 (
"Corrupted category raster conditions file <%s> (fseek failed)"),
316 step_shift = cat_rast_region->
cols - ncols;
320 for (i_row = 0; i_row < nrows; i_row++) {
322 i_row + patch_bounds.
north);
324 for (i_col = 0; i_col < ncols; i_col++) {
325 patch_col = patch_bounds.
west + i_col;
327 if (null_chunk_row[patch_col] != 1)
328 patch_data[i_col] = 1 & 255;
330 patch_data[i_col] = 0 & 255;
334 fwrite(patch_data,
sizeof(
unsigned char),
335 (ncols) /
sizeof(
unsigned char), f_cat_rast);
336 if (ferror(f_cat_rast)) {
338 (
"Unable to write into category raster conditions file <%s>"),
347 if (fseek(f_cat_rast, step_shift, SEEK_CUR) != 0) {
349 (
"Corrupted category raster conditions file <%s> (fseek failed)"),
376 static void update_cat_scatt_plts(
struct rast_row *bands_rows,
377 unsigned short *belongs_pix,
380 int i_scatt, array_idx, i_chunk_rows_pix, max_arr_idx;
384 char *b_1_null_row, *b_2_null_row;
385 struct rast_row b_1_rast_row, b_2_rast_row;
387 struct Range b_1_range, b_2_range;
394 for (i_scatt = 0; i_scatt < scatts->
n_a_scatts; i_scatt++) {
395 b_1_rast_row = bands_rows[scatts_bands[i_scatt * 2]];
396 b_2_rast_row = bands_rows[scatts_bands[i_scatt * 2 + 1]];
398 b_1_row = b_1_rast_row.row;
399 b_2_row = b_2_rast_row.row;
401 b_1_null_row = b_1_rast_row.null_row;
402 b_2_null_row = b_2_rast_row.null_row;
404 b_1_range = b_1_rast_row.rast_range;
405 b_2_range = b_2_rast_row.rast_range;
407 b_1_range_size = b_1_range.
max - b_1_range.
min + 1;
409 (b_1_range.
max - b_1_range.
min + 1) * (b_2_range.
max -
412 for (i_chunk_rows_pix = 0; i_chunk_rows_pix < row_size;
413 i_chunk_rows_pix++) {
415 if (!belongs_pix[i_chunk_rows_pix] ||
416 b_1_null_row[i_chunk_rows_pix] == 1 ||
417 b_2_null_row[i_chunk_rows_pix] == 1)
422 b_1_row[i_chunk_rows_pix] - b_1_range.
min +
423 (b_2_row[i_chunk_rows_pix] - b_2_range.
min) * b_1_range_size;
425 if (array_idx < 0 || array_idx >= max_arr_idx) {
427 (
"Inconsistent data. Value computed for scatter plot is out of initialized range.");
454 static int compute_scatts_from_chunk_row(
struct scCats *scatt_conds,
455 FILE ** f_cats_rasts_conds,
456 struct rast_row *bands_rows,
461 int i_rows_pix, i_cat, i_scatt, n_pixs;
462 int cat_id, scatt_plts_cat_idx, array_idx, max_arr_idx;
463 char *b_1_null_row, *b_2_null_row;
464 struct rast_row b_1_rast_row, b_2_rast_row;
470 struct Range b_1_range, b_2_range;
477 unsigned char *i_scatt_conds;
481 unsigned short *belongs_pix =
482 (
unsigned short *)
G_malloc(row_size *
sizeof(
unsigned short));
483 unsigned char *rast_pixs =
484 (
unsigned char *)
G_malloc(row_size *
sizeof(
unsigned char));
488 for (i_cat = 0; i_cat < scatt_conds->
n_a_cats; i_cat++) {
489 scatts_conds = scatt_conds->
cats_arr[i_cat];
491 cat_id = scatt_conds->
cats_ids[i_cat];
493 scatt_plts_cat_idx = scatts->
cats_idxs[cat_id];
494 if (scatt_plts_cat_idx < 0)
496 scatts_scatt_plts = scatts->
cats_arr[scatt_plts_cat_idx];
498 G_zero(belongs_pix, row_size *
sizeof(
unsigned short));
502 if (!scatts_conds->
n_a_scatts && !f_cats_rasts_conds[i_cat]) {
503 for (i_scatt = 0; i_scatt < scatts_scatt_plts->
n_a_scatts;
506 for (i_rows_pix = 0; i_rows_pix < row_size; i_rows_pix++)
507 belongs_pix[i_rows_pix] = 1;
516 if (f_cats_rasts_conds[i_cat]) {
518 fread(rast_pixs,
sizeof(
unsigned char),
519 (row_size) /
sizeof(
unsigned char),
520 f_cats_rasts_conds[i_cat]);
522 if (ferror(f_cats_rasts_conds[i_cat])) {
526 (
"Unable to read from category raster condition file."));
529 if (n_pixs != (row_size) /
sizeof(
unsigned char)) {
533 (
"Invalid size of category raster conditions file."));
538 for (i_rows_pix = 0; i_rows_pix < row_size; i_rows_pix++) {
539 if (rast_pixs[i_rows_pix] != (0 & 255))
540 belongs_pix[i_rows_pix] = 1;
545 for (i_scatt = 0; i_scatt < scatts_conds->
n_a_scatts; i_scatt++) {
546 b_1_rast_row = bands_rows[scatts_bands[i_scatt * 2]];
547 b_2_rast_row = bands_rows[scatts_bands[i_scatt * 2 + 1]];
549 b_1_row = b_1_rast_row.row;
550 b_2_row = b_2_rast_row.row;
552 b_1_null_row = b_1_rast_row.null_row;
553 b_2_null_row = b_2_rast_row.null_row;
555 b_1_range = b_1_rast_row.rast_range;
556 b_2_range = b_2_rast_row.rast_range;
558 b_1_range_size = b_1_range.
max - b_1_range.
min + 1;
560 (b_1_range.
max - b_1_range.
min + 1) * (b_2_range.
max -
566 for (i_rows_pix = 0; i_rows_pix < row_size; i_rows_pix++) {
569 if (belongs_pix[i_rows_pix] ||
570 b_1_null_row[i_rows_pix] == 1 ||
571 b_2_null_row[i_rows_pix] == 1)
575 b_1_row[i_rows_pix] - b_1_range.
min +
576 (b_2_row[i_rows_pix] -
577 b_2_range.
min) * b_1_range_size;
578 if (array_idx < 0 || array_idx >= max_arr_idx) {
580 "Value computed for scatter plot is out of initialized range."));
585 if (i_scatt_conds[array_idx])
586 belongs_pix[i_rows_pix] = 1;
592 if (fd_cats_rasts[i_cat] >= 0) {
595 for (i_rows_pix = 0; i_rows_pix < row_size; i_rows_pix++)
596 if (belongs_pix[i_rows_pix])
597 cat_rast_row[i_rows_pix] = belongs_pix[i_rows_pix];
603 update_cat_scatt_plts(bands_rows, belongs_pix, scatts_scatt_plts);
616 static void get_needed_bands(
struct scCats *cats,
int *b_needed_bands)
622 for (i_cat = 0; i_cat < cats->
n_a_cats; i_cat++) {
625 G_debug(3,
"Active scatt %d in catt %d", i_scatt, i_cat);
629 b_needed_bands[cats->
cats_arr[i_cat]->
630 scatts_bands[i_scatt * 2 + 1]] = 1;
639 static void free_compute_scatts_data(
int *fd_bands,
640 struct rast_row *bands_rows,
641 int n_a_bands,
int *bands_ids,
643 FILE ** f_cats_rasts_conds,
int n_a_cats)
647 for (i = 0; i < n_a_bands; i++) {
648 band_id = bands_ids[i];
651 G_free(bands_rows[band_id].row);
652 G_free(bands_rows[band_id].null_row);
656 if (f_cats_rasts_conds)
657 for (i = 0; i < n_a_cats; i++)
658 if (f_cats_rasts_conds[i])
659 fclose(f_cats_rasts_conds[i]);
662 for (i = 0; i < n_a_cats; i++)
663 if (fd_cats_rasts[i] >= 0)
696 const char **cats_rasts_conds,
const char **bands,
697 int n_bands,
struct scCats *scatts,
698 const char **cats_rasts)
703 int fd_cats_rasts[scatt_conds->
n_a_cats];
704 FILE *f_cats_rasts_conds[scatt_conds->
n_a_cats];
706 struct rast_row bands_rows[n_bands];
710 int nrows, i_band, n_a_bands, band_id;
711 int i_row, head_nchars, i_cat, id_cat;
713 int fd_bands[n_bands];
714 int bands_ids[n_bands];
715 int b_needed_bands[n_bands];
719 for (i_band = 0; i_band < n_bands; i_band++)
720 fd_bands[i_band] = -1;
722 for (i_band = 0; i_band < n_bands; i_band++)
723 bands_ids[i_band] = -1;
725 if (n_bands != scatts->
n_bands || n_bands != scatt_conds->
n_bands)
728 G_zero(b_needed_bands, (
size_t) n_bands *
sizeof(
int));
730 get_needed_bands(scatt_conds, &b_needed_bands[0]);
731 get_needed_bands(scatts, &b_needed_bands[0]);
736 for (band_id = 0; band_id < n_bands; band_id++) {
737 if (b_needed_bands[band_id]) {
738 G_debug(3,
"Opening raster no. %d with name: %s", band_id,
742 free_compute_scatts_data(fd_bands, bands_rows, n_a_bands,
750 if ((fd_bands[n_a_bands] =
752 free_compute_scatts_data(fd_bands, bands_rows, n_a_bands,
755 G_warning(
_(
"Unable to open raster <%s>"), bands[band_id]);
761 G_warning(
_(
"Raster <%s> type is not <%s>"), bands[band_id],
770 (bands[band_id], mapset,
771 &bands_rows[band_id].rast_range) != 1) {
772 free_compute_scatts_data(fd_bands, bands_rows, n_a_bands,
775 G_warning(
_(
"Unable to read range of raster <%s>"),
780 bands_ids[n_a_bands] = band_id;
786 for (i_cat = 0; i_cat < scatts->
n_a_cats; i_cat++) {
788 if (cats_rasts[id_cat]) {
789 fd_cats_rasts[i_cat] =
793 fd_cats_rasts[i_cat] = -1;
795 if (cats_rasts_conds[id_cat]) {
796 f_cats_rasts_conds[i_cat] = fopen(cats_rasts_conds[id_cat],
"r");
797 if (!f_cats_rasts_conds[i_cat]) {
798 free_compute_scatts_data(fd_bands, bands_rows, n_a_bands,
799 bands_ids, fd_cats_rasts,
803 (
"Unable to open category raster condition file <%s>"),
809 f_cats_rasts_conds[i_cat] =
NULL;
812 head_nchars = get_cat_rast_header(region, header);
813 for (i_cat = 0; i_cat < scatt_conds->
n_a_cats; i_cat++)
814 if (f_cats_rasts_conds[i_cat])
815 if (fseek(f_cats_rasts_conds[i_cat], head_nchars, SEEK_SET) != 0) {
817 (
"Corrupted category raster conditions file (fseek failed)"));
824 for (i_row = 0; i_row < nrows; i_row++) {
825 for (i_band = 0; i_band < n_a_bands; i_band++) {
826 band_id = bands_ids[i_band];
829 bands_rows[band_id].null_row, i_row);
831 if (compute_scatts_from_chunk_row
832 (scatt_conds, f_cats_rasts_conds, bands_rows, scatts,
833 fd_cats_rasts) == -1) {
834 free_compute_scatts_data(fd_bands, bands_rows, n_a_bands,
835 bands_ids, fd_cats_rasts,
842 free_compute_scatts_data(fd_bands, bands_rows, n_a_bands, bands_ids,
843 fd_cats_rasts, f_cats_rasts_conds,
863 unsigned rows,
unsigned cols,
double alpha)
865 unsigned int i_row, i_col, i_b;
866 unsigned int row_idx, col_idx, idx;
867 unsigned int c_a_i, c_a;
869 for (i_row = 0; i_row < rows; i_row++) {
870 row_idx = i_row * cols;
871 for (i_col = 0; i_col < cols; i_col++) {
872 col_idx = 4 * (row_idx + i_col);
875 c_a = overlay_arr[idx] * alpha;
879 (c_a_i * (int)merged_arr[idx] + c_a * 255) / 255;
881 for (i_b = 0; i_b < 3; i_b++) {
884 (c_a_i * (int)merged_arr[idx] +
885 c_a * (
int)overlay_arr[idx]) / 255;
906 unsigned nvals,
unsigned char *colmap,
907 unsigned char *col_vals)
912 for (i_val = 0; i_val < nvals; i_val++) {
917 if (vals_mask && vals_mask[i_val])
918 for (i = 0; i < 4; i++)
919 col_vals[i_cm + i] = colmap[258 * 4 + i];
921 for (i = 0; i < 4; i++)
922 col_vals[i_cm + i] = colmap[257 * 4 + i];
924 for (i = 0; i < 4; i++)
925 col_vals[i_cm + i] = colmap[256 * 4 + i];
927 for (i = 0; i < 4; i++) {
928 col_vals[i_cm + i] = colmap[v * 4 + i];
948 int I_rasterize(
double *polygon,
int pol_n_pts,
unsigned char val,
949 struct Cell_head *rast_region,
unsigned char *rast)
953 int row, row_idx, i_col;
955 IClass_perimeter perimeter;
961 for (i = 0; i < pol_n_pts; i++) {
968 for (i = 1; i < perimeter.npoints; i += 2) {
969 y = perimeter.points[i].y;
970 if (y != perimeter.points[i - 1].y) {
972 (
"prepare_signature: scan line %d has odd number of points."),
977 x0 = perimeter.points[i - 1].x;
978 x1 = perimeter.points[i].x;
981 G_warning(
_(
"signature: perimeter points out of order."));
985 row = (rast_region->
rows -
y);
986 if (row < 0 || row >= rast_region->
rows) {
990 row_idx = rast_region->
cols * row;
992 for (i_col = x0; i_col <= x1; i_col++) {
993 if (i_col < 0 || i_col >= rast_region->
cols) {
996 rast[row_idx + i_col] = val;
1001 G_free(perimeter.points);
void Rast_get_null_value_row(int, char *, int)
Read or simulate null value row.
int I_compute_scatts(struct Cell_head *region, struct scCats *scatt_conds, const char **cats_rasts_conds, const char **bands, int n_bands, struct scCats *scatts, const char **cats_rasts)
Compute scatter plots data.
void Rast_set_null_value(void *, int, RASTER_MAP_TYPE)
To set one or more raster values to null.
int I_rasterize(double *polygon, int pol_n_pts, unsigned char val, struct Cell_head *rast_region, unsigned char *rast)
Wrapper for using of iclass perimeter rasterization by scatter plot. Warning: calls Rast_set_window...
int make_perimeter(struct line_pnts *points, IClass_perimeter *perimeter, struct Cell_head *band_region)
Creates one perimeter from vector area.
2D/3D raster map header (used also for region)
double west
Extent coordinates (west)
void G_free(void *)
Free allocated memory.
int I_insert_patch_to_cat_rast(const char *patch_rast, struct Cell_head *cat_rast_region, const char *cat_rast)
Insert raster map patch into pgm file.
int Rast_read_range(const char *, const char *, struct Range *)
Read raster range (CELL)
int I_apply_colormap(unsigned char *vals, unsigned char *vals_mask, unsigned nvals, unsigned char *colmap, unsigned char *col_vals)
Apply colromap to the raster.
void Rast_set_window(struct Cell_head *)
Establishes 'window' as the current working window.
void Rast_get_c_row(int, CELL *, int)
Get raster row (CELL type)
Feature geometry info - coordinates.
double north
Extent coordinates (north)
struct line_pnts * Vect_new_line_struct(void)
Creates and initializes a line_pnts structure.
int Rast_open_new(const char *, RASTER_MAP_TYPE)
Opens a new raster map.
double south
Extent coordinates (south)
int Vect_append_point(struct line_pnts *, double, double, double)
Appends one point to the end of a line.
struct scdScattData ** scatts_arr
int Rast_open_old(const char *, const char *)
Open an existing integer raster map (cell)
int I_create_cat_rast(struct Cell_head *cat_rast_region, const char *cat_rast)
Create category raster conditions file. The file is used for holding selected areas from mapwindow...
unsigned int * scatt_vals_arr
const char * G_find_raster(char *, const char *)
Find a raster map.
double * y
Array of Y coordinates.
int cols
Number of columns for 2D data.
void Rast_get_cellhd(const char *, const char *, struct Cell_head *)
Read the raster header.
void Rast_put_c_row(int, const CELL *)
Writes the next row for cell file (CELL version)
double ns_res
Resolution - north to south cell size for 2D data.
int Rast_window_rows(void)
Number of rows in active window.
void G_zero(void *, int)
Zero out a buffer, buf, of length i.
int Rast_window_cols(void)
Number of columns in active window.
void G_warning(const char *,...) __attribute__((format(printf
struct scScatts ** cats_arr
RASTER_MAP_TYPE Rast_get_map_type(int)
Determine raster type from descriptor.
double east
Extent coordinates (east)
char * Rast_allocate_null_buf(void)
Allocates memory for a null buffer.
const char * G_find_raster2(const char *, const char *)
Find a raster map (look but don't touch)
double ew_res
Resolution - east to west cell size for 2D data.
unsigned char * b_conds_arr
void Vect_destroy_line_struct(struct line_pnts *)
Frees all memory associated with a line_pnts structure, including the structure itself.
int rows
Number of rows for 2D data.
int G_debug(int, const char *,...) __attribute__((format(printf
CELL * Rast_allocate_c_buf(void)
Allocate memory for a CELL type raster map.
int I_merge_arrays(unsigned char *merged_arr, unsigned char *overlay_arr, unsigned rows, unsigned cols, double alpha)
Merge arrays according to opacity. Every pixel in array must be represented by 4 values (RGBA)...
void Rast_close(int)
Close a raster map.