26 #include "iclass_local_proto.h"
31 struct Range rast_range;
43 static int get_cat_rast_header(
struct Cell_head *region,
char *header)
45 return sprintf(header,
"P5\n%d\n%d\n1\n", region->
cols, region->
rows);
62 char cat_rast_header[1024];
66 unsigned char *row_data;
68 f_cat_rast = fopen(cat_rast,
"wb");
70 G_warning(
"Unable to create category raster condition file <%s>.",
75 head_nchars = get_cat_rast_header(cat_rast_region, cat_rast_header);
77 fwrite(cat_rast_header,
sizeof(
char), head_nchars /
sizeof(
char),
79 if (ferror(f_cat_rast)) {
81 G_warning(
_(
"Unable to write header into category raster condition "
87 row_data = (
unsigned char *)
G_malloc(cat_rast_region->
cols *
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)
178 float ns_res, ew_res;
184 G_warning(
"'get_rows_and_cols_bounds' ns_res does not fit, A->ns_res: "
191 G_warning(
"'get_rows_and_cols_bounds' ew_res does not fit, A->ew_res: "
200 if (regions_intersecion(A, B, &intersec) == -1)
233 const char *cat_rast)
237 struct Cell_head patch_region, patch_bounds, cat_rast_bounds;
238 char cat_rast_header[1024];
239 int i_row, i_col, ncols, nrows, patch_col;
240 int head_nchars, ret;
241 int fd_patch_rast, init_shift, step_shift;
242 unsigned char *patch_data;
244 char *null_chunk_row;
248 f_cat_rast = fopen(cat_rast,
"rb+");
250 G_warning(
_(
"Unable to open category raster conditions file <%s>."),
255 head_nchars = get_cat_rast_header(cat_rast_region, cat_rast_header);
258 G_warning(
_(
"Unable to find patch raster <%s>."), patch_rast);
265 if ((fd_patch_rast =
Rast_open_old(patch_rast, mapset)) < 0) {
270 ret = get_rows_and_cols_bounds(cat_rast_region, &patch_region,
271 &cat_rast_bounds, &patch_bounds);
274 _(
"Resolutions of patch <%s> and patched file <%s> are not same."),
275 patch_rast, cat_rast);
282 else if (ret == -1) {
290 ncols = cat_rast_bounds.
east - cat_rast_bounds.
west;
291 nrows = cat_rast_bounds.
south - cat_rast_bounds.
north;
293 patch_data = (
unsigned char *)
G_malloc(ncols *
sizeof(
unsigned char));
295 init_shift = head_nchars + cat_rast_region->
cols * cat_rast_bounds.
north +
296 cat_rast_bounds.
west;
298 if (fseek(f_cat_rast, init_shift, SEEK_SET) != 0) {
300 _(
"Corrupted category raster conditions file <%s> (fseek failed)"),
309 step_shift = cat_rast_region->
cols - ncols;
313 for (i_row = 0; i_row < nrows; i_row++) {
315 i_row + patch_bounds.
north);
317 for (i_col = 0; i_col < ncols; i_col++) {
318 patch_col = patch_bounds.
west + i_col;
320 if (null_chunk_row[patch_col] != 1)
321 patch_data[i_col] = 1 & 255;
323 patch_data[i_col] = 0 & 255;
327 fwrite(patch_data,
sizeof(
unsigned char),
328 (ncols) /
sizeof(
unsigned char), f_cat_rast);
329 if (ferror(f_cat_rast)) {
331 _(
"Unable to write into category raster conditions file <%s>"),
340 if (fseek(f_cat_rast, step_shift, SEEK_CUR) != 0) {
341 G_warning(
_(
"Corrupted category raster conditions file <%s> "
370 static void update_cat_scatt_plts(
struct rast_row *bands_rows,
371 unsigned short *belongs_pix,
374 int i_scatt, array_idx, i_chunk_rows_pix, max_arr_idx;
378 char *b_1_null_row, *b_2_null_row;
379 struct rast_row b_1_rast_row, b_2_rast_row;
381 struct Range b_1_range, b_2_range;
388 for (i_scatt = 0; i_scatt < scatts->
n_a_scatts; i_scatt++) {
389 b_1_rast_row = bands_rows[scatts_bands[i_scatt * 2]];
390 b_2_rast_row = bands_rows[scatts_bands[i_scatt * 2 + 1]];
392 b_1_row = b_1_rast_row.row;
393 b_2_row = b_2_rast_row.row;
395 b_1_null_row = b_1_rast_row.null_row;
396 b_2_null_row = b_2_rast_row.null_row;
398 b_1_range = b_1_rast_row.rast_range;
399 b_2_range = b_2_rast_row.rast_range;
401 b_1_range_size = b_1_range.max - b_1_range.min + 1;
402 max_arr_idx = (b_1_range.max - b_1_range.min + 1) *
403 (b_2_range.max - b_2_range.min + 1);
405 for (i_chunk_rows_pix = 0; i_chunk_rows_pix < row_size;
406 i_chunk_rows_pix++) {
409 if (!belongs_pix[i_chunk_rows_pix] ||
410 b_1_null_row[i_chunk_rows_pix] == 1 ||
411 b_2_null_row[i_chunk_rows_pix] == 1)
416 b_1_row[i_chunk_rows_pix] - b_1_range.min +
417 (b_2_row[i_chunk_rows_pix] - b_2_range.min) * b_1_range_size;
419 if (array_idx < 0 || array_idx >= max_arr_idx) {
420 G_warning(
"Inconsistent data. Value computed for scatter plot "
421 "is out of initialized range.");
448 static int compute_scatts_from_chunk_row(
struct scCats *scatt_conds,
449 FILE **f_cats_rasts_conds,
450 struct rast_row *bands_rows,
455 int i_rows_pix, i_cat, i_scatt, n_pixs;
456 int cat_id, scatt_plts_cat_idx, array_idx, max_arr_idx;
457 char *b_1_null_row, *b_2_null_row;
458 struct rast_row b_1_rast_row, b_2_rast_row;
464 struct Range b_1_range, b_2_range;
471 unsigned char *i_scatt_conds;
475 unsigned short *belongs_pix =
476 (
unsigned short *)
G_malloc(row_size *
sizeof(
unsigned short));
477 unsigned char *rast_pixs =
478 (
unsigned char *)
G_malloc(row_size *
sizeof(
unsigned char));
481 for (i_cat = 0; i_cat < scatt_conds->
n_a_cats; i_cat++) {
482 scatts_conds = scatt_conds->
cats_arr[i_cat];
484 cat_id = scatt_conds->
cats_ids[i_cat];
486 scatt_plts_cat_idx = scatts->
cats_idxs[cat_id];
487 if (scatt_plts_cat_idx < 0)
489 scatts_scatt_plts = scatts->
cats_arr[scatt_plts_cat_idx];
491 G_zero(belongs_pix, row_size *
sizeof(
unsigned short));
495 if (!scatts_conds->
n_a_scatts && !f_cats_rasts_conds[i_cat]) {
496 for (i_scatt = 0; i_scatt < scatts_scatt_plts->
n_a_scatts;
499 for (i_rows_pix = 0; i_rows_pix < row_size; i_rows_pix++)
500 belongs_pix[i_rows_pix] = 1;
509 if (f_cats_rasts_conds[i_cat]) {
510 n_pixs = fread(rast_pixs,
sizeof(
unsigned char),
511 (row_size) /
sizeof(
unsigned char),
512 f_cats_rasts_conds[i_cat]);
514 if (ferror(f_cats_rasts_conds[i_cat])) {
518 "Unable to read from category raster condition file."));
521 if (n_pixs != (row_size) / (
int)
sizeof(
unsigned char)) {
525 _(
"Invalid size of category raster conditions file."));
529 for (i_rows_pix = 0; i_rows_pix < row_size; i_rows_pix++) {
530 if (rast_pixs[i_rows_pix] != (0 & 255))
531 belongs_pix[i_rows_pix] = 1;
536 for (i_scatt = 0; i_scatt < scatts_conds->
n_a_scatts; i_scatt++) {
537 b_1_rast_row = bands_rows[scatts_bands[i_scatt * 2]];
538 b_2_rast_row = bands_rows[scatts_bands[i_scatt * 2 + 1]];
540 b_1_row = b_1_rast_row.row;
541 b_2_row = b_2_rast_row.row;
543 b_1_null_row = b_1_rast_row.null_row;
544 b_2_null_row = b_2_rast_row.null_row;
546 b_1_range = b_1_rast_row.rast_range;
547 b_2_range = b_2_rast_row.rast_range;
549 b_1_range_size = b_1_range.max - b_1_range.min + 1;
550 max_arr_idx = (b_1_range.max - b_1_range.min + 1) *
551 (b_2_range.max - b_2_range.min + 1);
555 for (i_rows_pix = 0; i_rows_pix < row_size; i_rows_pix++) {
559 if (belongs_pix[i_rows_pix] ||
560 b_1_null_row[i_rows_pix] == 1 ||
561 b_2_null_row[i_rows_pix] == 1)
565 b_1_row[i_rows_pix] - b_1_range.min +
566 (b_2_row[i_rows_pix] - b_2_range.min) * b_1_range_size;
567 if (array_idx < 0 || array_idx >= max_arr_idx) {
569 "Value computed for scatter plot is out of "
570 "initialized range."));
575 if (i_scatt_conds[array_idx])
576 belongs_pix[i_rows_pix] = 1;
582 if (fd_cats_rasts[i_cat] >= 0) {
585 for (i_rows_pix = 0; i_rows_pix < row_size; i_rows_pix++)
586 if (belongs_pix[i_rows_pix])
587 cat_rast_row[i_rows_pix] = belongs_pix[i_rows_pix];
593 update_cat_scatt_plts(bands_rows, belongs_pix, scatts_scatt_plts);
606 static void get_needed_bands(
struct scCats *cats,
int *b_needed_bands)
612 for (i_cat = 0; i_cat < cats->
n_a_cats; i_cat++) {
615 G_debug(3,
"Active scatt %d in catt %d", i_scatt, i_cat);
619 b_needed_bands[cats->
cats_arr[i_cat]
629 static void free_compute_scatts_data(
int *fd_bands,
struct rast_row *bands_rows,
630 int n_a_bands,
int *bands_ids,
631 int *b_needed_bands,
int *fd_cats_rasts,
632 FILE **f_cats_rasts_conds,
int n_a_cats)
634 for (
int i = 0; i < n_a_bands; i++) {
635 int band_id = bands_ids[i];
638 G_free(bands_rows[band_id].row);
639 G_free(bands_rows[band_id].null_row);
643 for (
int i = 0; i < n_a_cats; i++)
644 if (f_cats_rasts_conds[i])
645 fclose(f_cats_rasts_conds[i]);
647 for (
int i = 0; i < n_a_cats; i++)
648 if (fd_cats_rasts[i] >= 0)
656 G_free(f_cats_rasts_conds);
686 const char **cats_rasts_conds,
const char **bands,
687 int n_bands,
struct scCats *scatts,
688 const char **cats_rasts)
694 FILE **f_cats_rasts_conds =
697 struct rast_row *bands_rows =
G_malloc(n_bands *
sizeof(
struct rast_row));
701 int nrows, i_band, n_a_bands, band_id;
702 int i_row, head_nchars, i_cat, id_cat;
704 int *fd_bands =
G_malloc(n_bands *
sizeof(
int));
705 int *bands_ids =
G_malloc(n_bands *
sizeof(
int));
706 int *b_needed_bands =
G_malloc(n_bands *
sizeof(
int));
710 for (i_band = 0; i_band < n_bands; i_band++)
711 fd_bands[i_band] = -1;
713 for (i_band = 0; i_band < n_bands; i_band++)
714 bands_ids[i_band] = -1;
716 if (n_bands != scatts->
n_bands || n_bands != scatt_conds->
n_bands)
719 for (i_cat = 0; i_cat < scatts->
n_a_cats; i_cat++)
720 fd_cats_rasts[i_cat] = -1;
722 G_zero(b_needed_bands, (
size_t)n_bands *
sizeof(
int));
724 get_needed_bands(scatt_conds, &b_needed_bands[0]);
725 get_needed_bands(scatts, &b_needed_bands[0]);
730 for (band_id = 0; band_id < n_bands; band_id++) {
731 if (b_needed_bands[band_id]) {
732 G_debug(3,
"Opening raster no. %d with name: %s", band_id,
736 free_compute_scatts_data(
737 fd_bands, bands_rows, n_a_bands, bands_ids, b_needed_bands,
738 fd_cats_rasts, f_cats_rasts_conds, scatt_conds->
n_a_cats);
739 G_warning(
_(
"Unable to find raster <%s>"), bands[band_id]);
743 if ((fd_bands[n_a_bands] =
Rast_open_old(bands[band_id], mapset)) <
745 free_compute_scatts_data(
746 fd_bands, bands_rows, n_a_bands, bands_ids, b_needed_bands,
747 fd_cats_rasts, f_cats_rasts_conds, scatt_conds->
n_a_cats);
748 G_warning(
_(
"Unable to open raster <%s>"), bands[band_id]);
754 G_warning(
_(
"Raster <%s> type is not <%s>"), bands[band_id],
763 &bands_rows[band_id].rast_range) != 1) {
764 free_compute_scatts_data(
765 fd_bands, bands_rows, n_a_bands, bands_ids, b_needed_bands,
766 fd_cats_rasts, f_cats_rasts_conds, scatt_conds->
n_a_cats);
767 G_warning(
_(
"Unable to read range of raster <%s>"),
772 bands_ids[n_a_bands] = band_id;
778 for (i_cat = 0; i_cat < scatts->
n_a_cats; i_cat++) {
780 if (cats_rasts[id_cat]) {
784 if (cats_rasts_conds[id_cat]) {
785 f_cats_rasts_conds[i_cat] = fopen(cats_rasts_conds[id_cat],
"r");
786 if (!f_cats_rasts_conds[i_cat]) {
787 free_compute_scatts_data(
788 fd_bands, bands_rows, n_a_bands, bands_ids, b_needed_bands,
789 fd_cats_rasts, f_cats_rasts_conds, scatt_conds->
n_a_cats);
791 _(
"Unable to open category raster condition file <%s>"),
797 f_cats_rasts_conds[i_cat] =
NULL;
800 head_nchars = get_cat_rast_header(region, header);
801 for (i_cat = 0; i_cat < scatt_conds->
n_a_cats; i_cat++)
802 if (f_cats_rasts_conds[i_cat])
803 if (fseek(f_cats_rasts_conds[i_cat], head_nchars, SEEK_SET) != 0) {
804 G_warning(
_(
"Corrupted category raster conditions file (fseek "
812 for (i_row = 0; i_row < nrows; i_row++) {
813 for (i_band = 0; i_band < n_a_bands; i_band++) {
814 band_id = bands_ids[i_band];
817 bands_rows[band_id].null_row, i_row);
819 if (compute_scatts_from_chunk_row(scatt_conds, f_cats_rasts_conds,
821 fd_cats_rasts) == -1) {
822 free_compute_scatts_data(fd_bands, bands_rows, n_a_bands, bands_ids,
823 b_needed_bands, fd_cats_rasts,
824 f_cats_rasts_conds, scatt_conds->
n_a_cats);
828 free_compute_scatts_data(fd_bands, bands_rows, n_a_bands, bands_ids,
829 b_needed_bands, fd_cats_rasts, f_cats_rasts_conds,
849 unsigned rows,
unsigned cols,
double alpha)
851 unsigned int i_row, i_col, i_b;
852 unsigned int row_idx, col_idx, idx;
853 unsigned int c_a_i, c_a;
855 for (i_row = 0; i_row < rows; i_row++) {
856 row_idx = i_row * cols;
857 for (i_col = 0; i_col < cols; i_col++) {
858 col_idx = 4 * (row_idx + i_col);
861 c_a = overlay_arr[idx] * alpha;
864 merged_arr[idx] = (c_a_i * (int)merged_arr[idx] + c_a * 255) / 255;
866 for (i_b = 0; i_b < 3; i_b++) {
868 merged_arr[idx] = (c_a_i * (int)merged_arr[idx] +
869 c_a * (
int)overlay_arr[idx]) /
892 unsigned nvals,
unsigned char *colmap,
893 unsigned char *col_vals)
898 for (i_val = 0; i_val < nvals; i_val++) {
903 if (vals_mask && vals_mask[i_val])
904 for (i = 0; i < 4; i++)
905 col_vals[i_cm + i] = colmap[258 * 4 + i];
907 for (i = 0; i < 4; i++)
908 col_vals[i_cm + i] = colmap[257 * 4 + i];
910 for (i = 0; i < 4; i++)
911 col_vals[i_cm + i] = colmap[256 * 4 + i];
913 for (i = 0; i < 4; i++) {
914 col_vals[i_cm + i] = colmap[v * 4 + i];
934 int I_rasterize(
double *polygon,
int pol_n_pts,
unsigned char val,
935 struct Cell_head *rast_region,
unsigned char *rast)
939 int row, row_idx, i_col;
941 IClass_perimeter perimeter;
947 for (i = 0; i < pol_n_pts; i++) {
954 for (i = 1; i < perimeter.npoints; i += 2) {
955 y = perimeter.points[i].y;
956 if (
y != perimeter.points[i - 1].y) {
958 _(
"prepare_signature: scan line %d has odd number of points."),
963 x0 = perimeter.points[i - 1].x;
964 x1 = perimeter.points[i].x;
967 G_warning(
_(
"signature: perimeter points out of order."));
971 row = (rast_region->
rows -
y);
972 if (row < 0 || row >= rast_region->
rows) {
976 row_idx = rast_region->
cols * row;
978 for (i_col = x0; i_col <= x1; i_col++) {
979 if (i_col < 0 || i_col >= rast_region->
cols) {
982 rast[row_idx + i_col] = val;
void G_zero(void *, int)
Zero out a buffer, buf, of length i.
void G_free(void *)
Free allocated memory.
void G_warning(const char *,...) __attribute__((format(printf
const char * G_find_raster2(const char *, const char *)
Find a raster map (look but don't touch)
const char * G_find_raster(char *, const char *)
Find a raster map.
int G_debug(int, const char *,...) __attribute__((format(printf
void Rast_close(int)
Close a raster map.
int Rast_open_old(const char *, const char *)
Open an existing integer raster map (cell)
void Rast_get_c_row(int, CELL *, int)
Get raster row (CELL type)
CELL * Rast_allocate_c_buf(void)
Allocate memory for a CELL type raster map.
int Rast_open_new(const char *, RASTER_MAP_TYPE)
Opens a new raster map.
char * Rast_allocate_null_buf(void)
Allocates memory for a null buffer.
int Rast_read_range(const char *, const char *, struct Range *)
Read raster range (CELL)
int Rast_window_cols(void)
Number of columns in active window.
int Rast_window_rows(void)
Number of rows in active window.
void Rast_set_null_value(void *, int, RASTER_MAP_TYPE)
To set one or more raster values to null.
void Rast_put_c_row(int, const CELL *)
Writes the next row for cell file (CELL version)
void Rast_set_window(struct Cell_head *)
Establishes 'window' as the current working window.
void Rast_get_cellhd(const char *, const char *, struct Cell_head *)
Read the raster header.
void Rast_get_null_value_row(int, char *, int)
Read or simulate null value row.
RASTER_MAP_TYPE Rast_get_map_type(int)
Determine raster type from descriptor.
void Vect_destroy_line_struct(struct line_pnts *)
Frees all memory associated with a line_pnts structure, including the structure itself.
struct line_pnts * Vect_new_line_struct(void)
Creates and initializes a line_pnts structure.
int Vect_append_point(struct line_pnts *, double, double, double)
Appends one point to the end of a line.
int make_perimeter(struct line_pnts *points, IClass_perimeter *perimeter, struct Cell_head *band_region)
Creates one perimeter from vector area.
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.
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....
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.
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).
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 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.
2D/3D raster map header (used also for region)
double ew_res
Resolution - east to west cell size for 2D data.
double north
Extent coordinates (north)
double east
Extent coordinates (east)
double ns_res
Resolution - north to south cell size for 2D data.
int rows
Number of rows for 2D data.
int cols
Number of columns for 2D data.
double south
Extent coordinates (south)
double west
Extent coordinates (west)
Feature geometry info - coordinates.
double * y
Array of Y coordinates.
struct scScatts ** cats_arr
struct scdScattData ** scatts_arr
unsigned int * scatt_vals_arr
unsigned char * b_conds_arr