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)) {
99 _(
"Unable to write into category raster condition file <%s>."),
156 if (intersec->
east == intersec->
west)
180 float ns_res, ew_res;
186 G_warning(
"'get_rows_and_cols_bounds' ns_res does not fit, A->ns_res: "
193 G_warning(
"'get_rows_and_cols_bounds' ew_res does not fit, A->ew_res: "
202 if (regions_intersecion(A, B, &intersec) == -1)
235 const char *cat_rast)
239 struct Cell_head patch_region, patch_bounds, cat_rast_bounds;
240 char cat_rast_header[1024];
241 int i_row, i_col, ncols, nrows, patch_col;
242 int head_nchars, ret;
243 int fd_patch_rast, init_shift, step_shift;
244 unsigned char *patch_data;
246 char *null_chunk_row;
250 f_cat_rast = fopen(cat_rast,
"rb+");
252 G_warning(
_(
"Unable to open category raster conditions file <%s>."),
257 head_nchars = get_cat_rast_header(cat_rast_region, cat_rast_header);
260 G_warning(
_(
"Unable to find patch raster <%s>."), patch_rast);
267 if ((fd_patch_rast =
Rast_open_old(patch_rast, mapset)) < 0) {
272 ret = get_rows_and_cols_bounds(cat_rast_region, &patch_region,
273 &cat_rast_bounds, &patch_bounds);
276 _(
"Resolutions of patch <%s> and patched file <%s> are not same."),
277 patch_rast, cat_rast);
284 else if (ret == -1) {
292 ncols = cat_rast_bounds.
east - cat_rast_bounds.
west;
293 nrows = cat_rast_bounds.
south - cat_rast_bounds.
north;
295 patch_data = (
unsigned char *)
G_malloc(ncols *
sizeof(
unsigned char));
297 init_shift = head_nchars + cat_rast_region->
cols * cat_rast_bounds.
north +
298 cat_rast_bounds.
west;
300 if (fseek(f_cat_rast, init_shift, SEEK_SET) != 0) {
302 _(
"Corrupted category raster conditions file <%s> (fseek failed)"),
312 step_shift = cat_rast_region->
cols - ncols;
316 for (i_row = 0; i_row < nrows; i_row++) {
318 i_row + patch_bounds.
north);
320 for (i_col = 0; i_col < ncols; i_col++) {
321 patch_col = patch_bounds.
west + i_col;
323 if (null_chunk_row[patch_col] != 1)
324 patch_data[i_col] = 1 & 255;
326 patch_data[i_col] = 0 & 255;
330 fwrite(patch_data,
sizeof(
unsigned char),
331 (ncols) /
sizeof(
unsigned char), f_cat_rast);
332 if (ferror(f_cat_rast)) {
334 _(
"Unable to write into category raster conditions file <%s>"),
344 if (fseek(f_cat_rast, step_shift, SEEK_CUR) != 0) {
345 G_warning(
_(
"Corrupted category raster conditions file <%s> "
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;
408 max_arr_idx = (b_1_range.max - b_1_range.min + 1) *
409 (b_2_range.max - b_2_range.min + 1);
411 for (i_chunk_rows_pix = 0; i_chunk_rows_pix < row_size;
412 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) {
426 G_warning(
"Inconsistent data. Value computed for scatter plot "
427 "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));
487 for (i_cat = 0; i_cat < scatt_conds->
n_a_cats; i_cat++) {
488 scatts_conds = scatt_conds->
cats_arr[i_cat];
490 cat_id = scatt_conds->
cats_ids[i_cat];
492 scatt_plts_cat_idx = scatts->
cats_idxs[cat_id];
493 if (scatt_plts_cat_idx < 0)
495 scatts_scatt_plts = scatts->
cats_arr[scatt_plts_cat_idx];
497 G_zero(belongs_pix, row_size *
sizeof(
unsigned short));
501 if (!scatts_conds->
n_a_scatts && !f_cats_rasts_conds[i_cat]) {
502 for (i_scatt = 0; i_scatt < scatts_scatt_plts->
n_a_scatts;
505 for (i_rows_pix = 0; i_rows_pix < row_size; i_rows_pix++)
506 belongs_pix[i_rows_pix] = 1;
515 if (f_cats_rasts_conds[i_cat]) {
516 n_pixs = fread(rast_pixs,
sizeof(
unsigned char),
517 (row_size) /
sizeof(
unsigned char),
518 f_cats_rasts_conds[i_cat]);
520 if (ferror(f_cats_rasts_conds[i_cat])) {
524 "Unable to read from category raster condition file."));
527 if (n_pixs != (row_size) / (
int)
sizeof(
unsigned char)) {
531 _(
"Invalid size of category raster conditions file."));
535 for (i_rows_pix = 0; i_rows_pix < row_size; i_rows_pix++) {
536 if (rast_pixs[i_rows_pix] != (0 & 255))
537 belongs_pix[i_rows_pix] = 1;
542 for (i_scatt = 0; i_scatt < scatts_conds->
n_a_scatts; i_scatt++) {
543 b_1_rast_row = bands_rows[scatts_bands[i_scatt * 2]];
544 b_2_rast_row = bands_rows[scatts_bands[i_scatt * 2 + 1]];
546 b_1_row = b_1_rast_row.row;
547 b_2_row = b_2_rast_row.row;
549 b_1_null_row = b_1_rast_row.null_row;
550 b_2_null_row = b_2_rast_row.null_row;
552 b_1_range = b_1_rast_row.rast_range;
553 b_2_range = b_2_rast_row.rast_range;
555 b_1_range_size = b_1_range.max - b_1_range.min + 1;
556 max_arr_idx = (b_1_range.max - b_1_range.min + 1) *
557 (b_2_range.max - b_2_range.min + 1);
561 for (i_rows_pix = 0; i_rows_pix < row_size; i_rows_pix++) {
565 if (belongs_pix[i_rows_pix] ||
566 b_1_null_row[i_rows_pix] == 1 ||
567 b_2_null_row[i_rows_pix] == 1)
571 b_1_row[i_rows_pix] - b_1_range.min +
572 (b_2_row[i_rows_pix] - b_2_range.min) * b_1_range_size;
573 if (array_idx < 0 || array_idx >= max_arr_idx) {
575 "Value computed for scatter plot is out of "
576 "initialized range."));
581 if (i_scatt_conds[array_idx])
582 belongs_pix[i_rows_pix] = 1;
588 if (fd_cats_rasts[i_cat] >= 0) {
591 for (i_rows_pix = 0; i_rows_pix < row_size; i_rows_pix++)
592 if (belongs_pix[i_rows_pix])
593 cat_rast_row[i_rows_pix] = belongs_pix[i_rows_pix];
599 update_cat_scatt_plts(bands_rows, belongs_pix, scatts_scatt_plts);
612 static void get_needed_bands(
struct scCats *cats,
int *b_needed_bands)
618 for (i_cat = 0; i_cat < cats->
n_a_cats; i_cat++) {
621 G_debug(3,
"Active scatt %d in catt %d", i_scatt, i_cat);
625 b_needed_bands[cats->
cats_arr[i_cat]
635 static void free_compute_scatts_data(
int *fd_bands,
struct rast_row *bands_rows,
636 int n_a_bands,
int *bands_ids,
637 int *b_needed_bands,
int *fd_cats_rasts,
638 FILE **f_cats_rasts_conds,
int n_a_cats)
640 for (
int i = 0; i < n_a_bands; i++) {
641 int band_id = bands_ids[i];
644 G_free(bands_rows[band_id].row);
645 G_free(bands_rows[band_id].null_row);
649 for (
int i = 0; i < n_a_cats; i++)
650 if (f_cats_rasts_conds[i])
651 fclose(f_cats_rasts_conds[i]);
653 for (
int i = 0; i < n_a_cats; i++)
654 if (fd_cats_rasts[i] >= 0)
662 G_free(f_cats_rasts_conds);
692 const char **cats_rasts_conds,
const char **bands,
693 int n_bands,
struct scCats *scatts,
694 const char **cats_rasts)
698 if (n_bands != scatts->
n_bands || n_bands != scatt_conds->
n_bands) {
703 FILE **f_cats_rasts_conds =
706 struct rast_row *bands_rows =
G_malloc(n_bands *
sizeof(
struct rast_row));
709 int nrows, i_band, n_a_bands = 0, band_id;
710 int i_row, head_nchars, i_cat, id_cat;
712 int *fd_bands =
G_malloc(n_bands *
sizeof(
int));
713 int *bands_ids =
G_malloc(n_bands *
sizeof(
int));
714 int *b_needed_bands =
G_malloc(n_bands *
sizeof(
int));
718 for (i_band = 0; i_band < n_bands; i_band++)
719 fd_bands[i_band] = -1;
721 for (i_band = 0; i_band < n_bands; i_band++)
722 bands_ids[i_band] = -1;
723 for (i_cat = 0; i_cat < scatts->
n_a_cats; i_cat++)
724 fd_cats_rasts[i_cat] = -1;
726 G_zero(b_needed_bands, (
size_t)n_bands *
sizeof(
int));
728 get_needed_bands(scatt_conds, &b_needed_bands[0]);
729 get_needed_bands(scatts, &b_needed_bands[0]);
732 for (band_id = 0; band_id < n_bands; band_id++) {
733 if (b_needed_bands[band_id]) {
734 G_debug(3,
"Opening raster no. %d with name: %s", band_id,
738 free_compute_scatts_data(
739 fd_bands, bands_rows, n_a_bands, bands_ids, b_needed_bands,
740 fd_cats_rasts, f_cats_rasts_conds, scatt_conds->
n_a_cats);
741 G_warning(
_(
"Unable to find raster <%s>"), bands[band_id]);
745 if ((fd_bands[n_a_bands] =
Rast_open_old(bands[band_id], mapset)) <
747 free_compute_scatts_data(
748 fd_bands, bands_rows, n_a_bands, bands_ids, b_needed_bands,
749 fd_cats_rasts, f_cats_rasts_conds, scatt_conds->
n_a_cats);
750 G_warning(
_(
"Unable to open raster <%s>"), bands[band_id]);
756 free_compute_scatts_data(
757 fd_bands, bands_rows, n_a_bands, bands_ids, b_needed_bands,
758 fd_cats_rasts, f_cats_rasts_conds, scatt_conds->
n_a_cats);
759 G_warning(
_(
"Raster <%s> type is not <%s>"), bands[band_id],
768 &bands_rows[band_id].rast_range) != 1) {
769 free_compute_scatts_data(
770 fd_bands, bands_rows, n_a_bands, bands_ids, b_needed_bands,
771 fd_cats_rasts, f_cats_rasts_conds, scatt_conds->
n_a_cats);
772 G_warning(
_(
"Unable to read range of raster <%s>"),
777 bands_ids[n_a_bands] = band_id;
783 for (i_cat = 0; i_cat < scatts->
n_a_cats; i_cat++) {
785 if (cats_rasts[id_cat]) {
789 if (cats_rasts_conds[id_cat]) {
790 f_cats_rasts_conds[i_cat] = fopen(cats_rasts_conds[id_cat],
"r");
791 if (!f_cats_rasts_conds[i_cat]) {
792 free_compute_scatts_data(
793 fd_bands, bands_rows, n_a_bands, bands_ids, b_needed_bands,
794 fd_cats_rasts, f_cats_rasts_conds, scatt_conds->
n_a_cats);
796 _(
"Unable to open category raster condition file <%s>"),
802 f_cats_rasts_conds[i_cat] =
NULL;
805 head_nchars = get_cat_rast_header(region, header);
806 for (i_cat = 0; i_cat < scatt_conds->
n_a_cats; i_cat++)
807 if (f_cats_rasts_conds[i_cat])
808 if (fseek(f_cats_rasts_conds[i_cat], head_nchars, SEEK_SET) != 0) {
809 free_compute_scatts_data(
810 fd_bands, bands_rows, n_a_bands, bands_ids, b_needed_bands,
811 fd_cats_rasts, f_cats_rasts_conds, scatt_conds->
n_a_cats);
812 G_warning(
_(
"Corrupted category raster conditions file (fseek "
820 for (i_row = 0; i_row < nrows; i_row++) {
821 for (i_band = 0; i_band < n_a_bands; i_band++) {
822 band_id = bands_ids[i_band];
825 bands_rows[band_id].null_row, i_row);
827 if (compute_scatts_from_chunk_row(scatt_conds, f_cats_rasts_conds,
829 fd_cats_rasts) == -1) {
830 free_compute_scatts_data(fd_bands, bands_rows, n_a_bands, bands_ids,
831 b_needed_bands, fd_cats_rasts,
832 f_cats_rasts_conds, scatt_conds->
n_a_cats);
836 free_compute_scatts_data(fd_bands, bands_rows, n_a_bands, bands_ids,
837 b_needed_bands, fd_cats_rasts, f_cats_rasts_conds,
857 unsigned rows,
unsigned cols,
double alpha)
859 unsigned int i_row, i_col, i_b;
860 unsigned int row_idx, col_idx, idx;
861 unsigned int c_a_i, c_a;
863 for (i_row = 0; i_row < rows; i_row++) {
864 row_idx = i_row * cols;
865 for (i_col = 0; i_col < cols; i_col++) {
866 col_idx = 4 * (row_idx + i_col);
869 c_a = overlay_arr[idx] * alpha;
872 merged_arr[idx] = (c_a_i * (int)merged_arr[idx] + c_a * 255) / 255;
874 for (i_b = 0; i_b < 3; i_b++) {
876 merged_arr[idx] = (c_a_i * (int)merged_arr[idx] +
877 c_a * (
int)overlay_arr[idx]) /
900 unsigned nvals,
unsigned char *colmap,
901 unsigned char *col_vals)
906 for (i_val = 0; i_val < nvals; i_val++) {
911 if (vals_mask && vals_mask[i_val])
912 for (i = 0; i < 4; i++)
913 col_vals[i_cm + i] = colmap[258 * 4 + i];
915 for (i = 0; i < 4; i++)
916 col_vals[i_cm + i] = colmap[257 * 4 + i];
918 for (i = 0; i < 4; i++)
919 col_vals[i_cm + i] = colmap[256 * 4 + i];
921 for (i = 0; i < 4; i++) {
922 col_vals[i_cm + i] = colmap[v * 4 + i];
941 int I_rasterize(
double *polygon,
int pol_n_pts,
unsigned char val,
942 struct Cell_head *rast_region,
unsigned char *rast)
946 int row, row_idx, i_col;
948 IClass_perimeter perimeter;
954 for (i = 0; i < pol_n_pts; i++) {
961 for (i = 1; i < perimeter.npoints; i += 2) {
962 y = perimeter.points[i].y;
963 if (
y != perimeter.points[i - 1].y) {
965 _(
"prepare_signature: scan line %d has odd number of points."),
972 x0 = perimeter.points[i - 1].x;
973 x1 = perimeter.points[i].x;
976 G_warning(
_(
"signature: perimeter points out of order."));
982 row = (rast_region->
rows -
y);
983 if (row < 0 || row >= rast_region->
rows) {
987 row_idx = rast_region->
cols * row;
989 for (i_col = x0; i_col <= x1; i_col++) {
990 if (i_col < 0 || i_col >= rast_region->
cols) {
993 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