103
99
return RLI_ERRORE;
106
103
if (ris != RLI_OK) {
107
104
return RLI_ERRORE;
110
107
*result = indice;
116
int calculate(int fd, area_des ad, struct Cell_head hd, double *result)
126
int mask_fd = -1, *mask_buf;
138
long *mask_patch_sup;
139
long *mask_patch_corr;
142
double area = 0; /*if all cells are null area=0 */
143
double areaCorrect = 0;
144
double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
146
avlID_tree albero = NULL;
152
/* open mask if needed */
154
if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
156
mask_buf = G_malloc(ad->cl * sizeof(int));
157
if (mask_buf == NULL) {
158
G_fatal_error("malloc mask_buf failed");
164
mask_patch_sup = G_malloc(ad->cl * sizeof(long));
165
if (mask_patch_sup == NULL) {
166
G_fatal_error("malloc mask_patch_sup failed");
170
mask_patch_corr = G_malloc(ad->cl * sizeof(long));
171
if (mask_patch_corr == NULL) {
172
G_fatal_error("malloc mask_patch_corr failed");
176
buf_sup = G_allocate_cell_buf();
177
if (buf_sup == NULL) {
178
G_fatal_error("malloc buf_sup failed");
182
buf = G_allocate_cell_buf();
184
G_fatal_error("malloc buf failed");
188
G_set_c_null_value(buf_sup + ad->x, ad->cl); /*the first time buf_sup is all null */
190
for (i = 0; i < ad->cl; i++) {
191
mask_patch_sup[i] = 0;
192
mask_patch_corr[i] = 0;
195
/*for each raster row */
197
for (j = 0; j < ad->rl; j++) {
199
buf_sup = RLI_get_cell_raster_row(fd, j - 1 + ad->y, ad);
201
buf = RLI_get_cell_raster_row(fd, j + ad->y, ad);
203
if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
204
G_fatal_error("mask read failed");
208
G_set_c_null_value(&precCell, 1);
209
for (i = 0; i < ad->cl; i++) { /*for each cell in the row */
211
corrCell = buf[i + ad->x];
213
if ((masked) && (mask_buf[i + ad->x] == 0)) {
214
G_set_c_null_value(&corrCell, 1);
218
if (!(G_is_null_value(&corrCell, CELL_TYPE))) {
221
precCell = buf[i - 1 + ad->x];
224
G_set_c_null_value(&supCell, 1);
226
supCell = buf_sup[i + ad->x];
229
if (corrCell != precCell) {
230
if (corrCell != supCell) {
232
if (idCorr == 0) { /*first patch */
235
mask_patch_corr[i] = idCorr;
237
else { /*not first patch */
238
/* put in the tree previous values */
239
if (albero == NULL) {
240
albero = avlID_make(idCorr, uno);
241
if (albero == NULL) {
242
G_fatal_error("avlID_make error");
248
else { /* tree not null */
250
ris = avlID_add(&albero, idCorr, uno);
254
G_fatal_error("avlID_add error");
269
("avlID_add unknown error");
277
mask_patch_corr[i] = idCorr;
280
else { /*current cell and upper cell are equal */
282
if ((corrCell == precCell) &&
283
(mask_patch_sup[i] != mask_patch_corr[i - 1])) {
285
long del = mask_patch_sup[i];
287
r = avlID_sub(&albero, del);
289
G_fatal_error("avlID_sub error");
292
/*Remove one patch because it makes part of a patch already found */
293
ris = avlID_add(&albero, idCorr, uno);
297
G_fatal_error("avlID_add error");
311
G_fatal_error("avlID_add unknown error");
317
if (mask_patch_sup[r] == del) {
318
mask_patch_sup[r] = idCorr;
326
if (albero == NULL) {
327
albero = avlID_make(idCorr, uno);
328
if (albero == NULL) {
329
G_fatal_error("avlID_make error");
334
else { /* tree not null */
336
ris = avlID_add(&albero, idCorr, uno);
340
G_fatal_error("avlID_add error");
354
G_fatal_error("avlID_add unknown error");
360
idCorr = mask_patch_sup[i];
361
mask_patch_corr[i] = idCorr;
364
else { /*current cell and previous cell are equal */
367
if ((corrCell == supCell) &&
368
(mask_patch_sup[i] != mask_patch_corr[i - 1])) {
371
mask_patch_corr[i] = mask_patch_sup[i];
374
if (mask_patch_corr[l] == idCorr) {
375
mask_patch_corr[l] = mask_patch_sup[i];
383
idCorr = mask_patch_sup[i];
386
mask_patch_corr[i] = idCorr;
391
else { /*cell not to consider or cell is null */
393
mask_patch_corr[i] = 0;
396
mask_patch_sup = mask_patch_corr;
402
if (albero == NULL) {
403
albero = avlID_make(idCorr, uno);
404
if (albero == NULL) {
405
G_fatal_error("avlID_make error");
411
ris = avlID_add(&albero, idCorr, uno);
415
G_fatal_error("avlID_add error");
429
G_fatal_error("avlID_add unknown error");
436
array = G_malloc(npatch * sizeof(avlID_tableRow));
438
G_fatal_error("malloc array failed");
441
tot = avlID_to_array(albero, zero, array);
445
("avlID_to_array unaspected value. the result could be wrong");
449
for (i = 0; i < npatch; i++) {
450
if (array[i]->tot == 0)
453
npatch = npatch - doppi;
455
/*calculate distance */
456
G_begin_distance_calculations();
457
/* EW Dist at North edge */
458
EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north);
459
/* EW Dist at South Edge */
460
EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south);
461
/* NS Dist at East edge */
462
NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south);
463
/* NS Dist at West edge */
464
NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south);
466
areaCorrect = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) *
467
(((NS_DIST1 + NS_DIST2) / 2) / hd.rows) * (area);
468
indice = areaCorrect / npatch;
472
indice = (double)(0);
481
G_free(mask_patch_corr);
488
int calculateD(int fd, area_des ad, struct Cell_head hd, double *result)
498
int mask_fd = -1, *mask_buf;
509
long *mask_patch_sup;
510
long *mask_patch_corr;
513
double area = 0; /*if all cells are null area=0 */
514
double areaCorrect = 0;
515
double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
517
avlID_tree albero = NULL;
523
/* open mask if needed */
525
if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
527
mask_buf = G_malloc(ad->cl * sizeof(int));
528
if (mask_buf == NULL) {
529
G_fatal_error("malloc mask_buf failed");
535
mask_patch_sup = G_malloc(ad->cl * sizeof(long));
536
if (mask_patch_sup == NULL) {
537
G_fatal_error("malloc mask_patch_sup failed");
541
mask_patch_corr = G_malloc(ad->cl * sizeof(long));
542
if (mask_patch_corr == NULL) {
543
G_fatal_error("malloc mask_patch_corr failed");
547
buf_sup = G_allocate_d_raster_buf();
548
if (buf_sup == NULL) {
549
G_fatal_error("malloc buf_sup failed");
553
buf = G_allocate_d_raster_buf();
555
G_fatal_error("malloc buf failed");
559
G_set_d_null_value(buf_sup + ad->x, ad->cl); /*the first time buf_sup is all null */
561
for (i = 0; i < ad->cl; i++) {
562
mask_patch_sup[i] = 0;
563
mask_patch_corr[i] = 0;
566
/*read each row and put in an avlId tree cell value with the number of cells which have that value */
567
for (j = 0; j < ad->rl; j++) {
569
buf_sup = RLI_get_dcell_raster_row(fd, j - 1 + ad->y, ad);
571
buf = RLI_get_dcell_raster_row(fd, j + ad->y, ad);
573
if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
574
G_fatal_error("mask read failed");
578
G_set_d_null_value(&precCell, 1);
579
for (i = 0; i < ad->cl; i++) { /*for each cell in the row */
581
corrCell = buf[i + ad->x];
583
if ((masked) && (mask_buf[i + ad->x] == 0)) {
584
G_set_d_null_value(&corrCell, 1);
587
if (!(G_is_null_value(&corrCell, DCELL_TYPE))) {
590
precCell = buf[i - 1 + ad->x];
593
G_set_d_null_value(&supCell, 1);
595
supCell = buf_sup[i + ad->x];
597
if (corrCell != precCell) {
598
if (corrCell != supCell) {
600
if (idCorr == 0) { /*first patch */
603
mask_patch_corr[i] = idCorr;
605
else { /*not first patch */
606
/* put in the tree previous value */
607
if (albero == NULL) {
608
albero = avlID_make(idCorr, uno);
609
if (albero == NULL) {
610
G_fatal_error("avlID_make error");
616
else { /* tree not null */
618
ris = avlID_add(&albero, idCorr, uno);
622
G_fatal_error("avlID_add error");
637
("avlID_add unknown error");
645
mask_patch_corr[i] = idCorr;
648
else { /*current cell and upper cell are equal */
650
if ((corrCell == precCell) &&
651
(mask_patch_sup[i] != mask_patch_corr[i - 1])) {
653
long del = mask_patch_sup[i];
655
/*Remove one patch because it makes part of a patch already found */
656
r = avlID_sub(&albero, del);
658
G_fatal_error("avlID_sub error");
662
ris = avlID_add(&albero, idCorr, uno);
666
G_fatal_error("avlID_add error");
680
G_fatal_error("avlID_add unknown error");
686
if (mask_patch_sup[r] == del) {
687
mask_patch_sup[r] = idCorr;
695
if (albero == NULL) {
696
albero = avlID_make(idCorr, uno);
697
if (albero == NULL) {
698
G_fatal_error("avlID_make error");
703
else { /*tree not null */
705
ris = avlID_add(&albero, idCorr, uno);
709
G_fatal_error("avlID_add error");
723
G_fatal_error("avlID_add unknown error");
729
idCorr = mask_patch_sup[i];
730
mask_patch_corr[i] = idCorr;
733
else { /*current cell and previous cell are equals */
736
if ((corrCell == supCell) &&
737
(mask_patch_sup[i] != mask_patch_corr[i - 1])) {
740
mask_patch_corr[i] = mask_patch_sup[i];
743
if (mask_patch_corr[l] == idCorr) {
744
mask_patch_corr[l] = mask_patch_sup[i];
752
idCorr = mask_patch_sup[i];
755
mask_patch_corr[i] = idCorr;
760
else { /*cell null or not to consider */
762
mask_patch_corr[i] = 0;
765
mask_patch_sup = mask_patch_corr;
771
if (albero == NULL) {
772
albero = avlID_make(idCorr, uno);
773
if (albero == NULL) {
774
G_fatal_error("avlID_make error");
780
ris = avlID_add(&albero, idCorr, uno);
784
G_fatal_error("avlID_add error");
798
G_fatal_error("avlID_add unknown error");
805
array = G_malloc(npatch * sizeof(avlID_tableRow));
807
G_fatal_error("malloc array failed");
810
tot = avlID_to_array(albero, zero, array);
814
("avlID_to_array unaspected value. the result could be wrong");
818
for (i = 0; i < npatch; i++) {
819
if (array[i]->tot == 0)
823
npatch = npatch - doppi;
825
/*calculate distance */
826
G_begin_distance_calculations();
827
/* EW Dist at North edge */
828
EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north);
829
/* EW Dist at South Edge */
830
EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south);
831
/* NS Dist at East edge */
832
NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south);
833
/* NS Dist at West edge */
834
NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south);
836
areaCorrect = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) *
837
(((NS_DIST1 + NS_DIST2) / 2) / hd.rows) * (area);
838
indice = areaCorrect / npatch;
842
indice = (double)(0);
851
G_free(mask_patch_corr);
857
int calculateF(int fd, area_des ad, struct Cell_head hd, double *result)
867
int mask_fd = -1, *mask_buf;
879
long *mask_patch_sup;
880
long *mask_patch_corr;
883
double area = 0; /*if all cells are null area=0 */
884
double areaCorrect = 0;
885
double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
887
avlID_tree albero = NULL;
893
/* open mask if needed */
895
if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
897
mask_buf = G_malloc(ad->cl * sizeof(int));
898
if (mask_buf == NULL) {
899
G_fatal_error("malloc mask_buf failed");
905
mask_patch_sup = G_malloc(ad->cl * sizeof(long));
906
if (mask_patch_sup == NULL) {
907
G_fatal_error("malloc mask_patch_sup failed");
911
mask_patch_corr = G_malloc(ad->cl * sizeof(long));
912
if (mask_patch_corr == NULL) {
913
G_fatal_error("malloc mask_patch_corr failed");
917
buf_sup = G_allocate_f_raster_buf();
918
if (buf_sup == NULL) {
919
G_fatal_error("malloc buf_sup failed");
924
buf = G_allocate_f_raster_buf();
926
G_fatal_error("malloc buf failed");
930
G_set_f_null_value(buf_sup + ad->x, ad->cl); /*the first time buf_sup is all null */
932
for (i = 0; i < ad->cl; i++) {
933
mask_patch_sup[i] = 0;
934
mask_patch_corr[i] = 0;
936
/*for each raster row */
938
for (j = 0; j < ad->rl; j++) {
940
buf_sup = RLI_get_fcell_raster_row(fd, j - 1 + ad->y, ad);
942
buf = RLI_get_fcell_raster_row(fd, j + ad->y, ad);
944
if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0) {
945
G_fatal_error("mask read failed");
949
G_set_f_null_value(&precCell, 1);
950
for (i = 0; i < ad->cl; i++) { /*for each cell in the row */
953
corrCell = buf[i + ad->x];
954
if (((masked) && (mask_buf[i + ad->x] == 0))) {
955
G_set_f_null_value(&corrCell, 1);
957
if (!(G_is_null_value(&corrCell, FCELL_TYPE))) {
960
precCell = buf[i - 1 + ad->x];
962
G_set_f_null_value(&supCell, 1);
964
supCell = buf_sup[i + ad->x];
967
if (corrCell != precCell) {
968
if (corrCell != supCell) {
970
if (idCorr == 0) { /*first patch */
973
mask_patch_corr[i] = idCorr;
975
else { /*not first patch */
976
/* put in the tree previous value */
977
if (albero == NULL) {
978
albero = avlID_make(idCorr, uno);
979
if (albero == NULL) {
980
G_fatal_error("avlID_make error");
986
else { /*tree not empty */
988
ris = avlID_add(&albero, idCorr, uno);
992
G_fatal_error("avlID_add error");
1007
("avlID_add unknown error");
1015
mask_patch_corr[i] = idCorr;
1018
else { /*current cell and upper cell are equal */
1020
if ((corrCell == precCell) &&
1021
(mask_patch_sup[i] != mask_patch_corr[i - 1])) {
1023
long del = mask_patch_sup[i];
1025
r = avlID_sub(&albero, del);
1027
G_fatal_error("avlID_sub error");
1030
/*Remove one patch because it makes part of a patch already found */
1031
ris = avlID_add(&albero, idCorr, uno);
1035
G_fatal_error("avlID_add error");
1049
G_fatal_error("avlID_add unknown error");
1054
while (i < ad->cl) {
1055
if (mask_patch_sup[r] == del) {
1056
mask_patch_sup[r] = idCorr;
1064
if (albero == NULL) {
1065
albero = avlID_make(idCorr, uno);
1066
if (albero == NULL) {
1067
G_fatal_error("avlID_make error");
1072
else { /*the tree (albero) isn't null */
1074
ris = avlID_add(&albero, idCorr, uno);
1078
G_fatal_error("avlID_add error");
1092
G_fatal_error("avlID_add unknown error");
1098
idCorr = mask_patch_sup[i];
1099
mask_patch_corr[i] = idCorr;
1102
else { /*current cell and previous cell are equal */
1104
if ((corrCell == supCell) &&
1105
(mask_patch_sup[i] != mask_patch_corr[i - 1])) {
1108
mask_patch_corr[i] = mask_patch_sup[i];
1111
if (mask_patch_corr[l] == idCorr) {
1112
mask_patch_corr[l] = mask_patch_sup[i];
1120
idCorr = mask_patch_sup[i];
1123
mask_patch_corr[i] = idCorr;
1128
else { /*null cell or cell not to consider */
1130
mask_patch_corr[i] = 0;
1133
mask_patch_sup = mask_patch_corr;
1139
if (albero == NULL) {
1140
albero = avlID_make(idCorr, uno);
1141
if (albero == NULL) {
1142
G_fatal_error("avlID_make error");
1148
ris = avlID_add(&albero, idCorr, uno);
1152
G_fatal_error("avlID_add error");
1166
G_fatal_error("avlID_add unknown error");
1173
array = G_malloc(npatch * sizeof(avlID_tableRow));
1174
if (array == NULL) {
1175
G_fatal_error("malloc array failed");
1178
tot = avlID_to_array(albero, zero, array);
1180
if (tot != npatch) {
1182
("avlID_to_array unaspected value. the result could be wrong");
1186
for (i = 0; i < npatch; i++) {
1187
if (array[i]->tot == 0)
1191
npatch = npatch - doppi;
1193
/*calculate distance */
1194
G_begin_distance_calculations();
1195
/* EW Dist at North edge */
1196
EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north);
1197
/* EW Dist at South Edge */
1198
EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south);
1199
/* NS Dist at East edge */
1200
NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south);
1201
/* NS Dist at West edge */
1202
NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south);
1204
areaCorrect = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) *
1205
(((NS_DIST1 + NS_DIST2) / 2) / hd.rows) * (area);
1206
indice = areaCorrect / npatch;
1210
indice = (double)(0);
1219
G_free(mask_patch_corr);
113
int calculate(int fd, struct area_entry *ad, double *result)
115
CELL *buf, *buf_sup, *buf_null;
116
CELL corrCell, precCell, supCell;
118
long pid, old_pid, new_pid, *pid_corr, *pid_sup, *ltmp;
123
int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked;
126
Rast_get_window(&hd);
128
buf_null = Rast_allocate_c_buf();
129
Rast_set_c_null_value(buf_null, Rast_window_cols());
132
/* initialize patch ids */
133
pid_corr = G_malloc(ad->cl * sizeof(long));
134
pid_sup = G_malloc(ad->cl * sizeof(long));
136
for (j = 0; j < ad->cl; j++) {
141
/* open mask if needed */
143
mask_buf = mask_sup = NULL;
146
if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
148
mask_buf = G_malloc(ad->cl * sizeof(int));
149
if (mask_buf == NULL) {
150
G_fatal_error("malloc mask_buf failed");
153
mask_sup = G_malloc(ad->cl * sizeof(int));
154
if (mask_sup == NULL) {
155
G_fatal_error("malloc mask_buf failed");
158
for (j = 0; j < ad->cl; j++)
164
/* calculate number of patches */
169
/* patch size and type */
178
pst = G_malloc(nalloc * sizeof(struct pst));
179
for (k = 0; k < nalloc; k++) {
183
for (i = 0; i < ad->rl; i++) {
184
buf = RLI_get_cell_raster_row(fd, i + ad->y, ad);
186
buf_sup = RLI_get_cell_raster_row(fd, i - 1 + ad->y, ad);
193
if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
201
Rast_set_c_null_value(&precCell, 1);
204
for (j = 0; j < ad->cl; j++) {
207
corrCell = buf[j + ad->x];
208
if (masked && (mask_buf[j] == 0)) {
209
Rast_set_c_null_value(&corrCell, 1);
212
if (Rast_is_c_null_value(&corrCell)) {
220
supCell = buf_sup[j + ad->x];
221
if (masked && (mask_sup[j] == 0)) {
222
Rast_set_c_null_value(&supCell, 1);
225
if (!Rast_is_c_null_value(&precCell) && corrCell == precCell) {
226
pid_corr[j] = pid_corr[j - 1];
228
pst[pid_corr[j]].count++;
234
if (!Rast_is_c_null_value(&supCell) && corrCell == supCell) {
236
if (pid_corr[j] != pid_sup[j]) {
237
/* connect or merge */
243
G_fatal_error("npatch == 0 at row %d, col %d", i, j);
247
old_pid = pid_corr[j];
248
new_pid = pid_sup[j];
249
pid_corr[j] = new_pid;
252
/* update left side of the current row */
253
for (k = 0; k < j; k++) {
254
if (pid_corr[k] == old_pid)
255
pid_corr[k] = new_pid;
257
/* update right side of the previous row */
258
for (k = j + 1; k < ad->cl; k++) {
259
if (pid_sup[k] == old_pid)
260
pid_sup[k] = new_pid;
262
pst[new_pid].count += pst[old_pid].count;
263
pst[old_pid].count = 0;
269
pst[new_pid].count++;
276
/* start new patch */
282
pst = (struct pst *)G_realloc(pst, (pid + incr) * sizeof(struct pst));
284
for (k = nalloc; k < pid + incr; k++)
291
pst[pid].type.t = CELL_TYPE;
292
pst[pid].type.val.c = corrCell;
299
double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
302
/* calculate distance */
303
G_begin_distance_calculations();
304
/* EW Dist at North edge */
305
EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north);
306
/* EW Dist at South Edge */
307
EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south);
308
/* NS Dist at East edge */
309
NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south);
310
/* NS Dist at West edge */
311
NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south);
313
area_units = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) *
314
(((NS_DIST1 + NS_DIST2) / 2) / hd.rows) * area;
316
*result = area_units / (npatch * 10000);
336
int calculateD(int fd, struct area_entry *ad, double *result)
338
DCELL *buf, *buf_sup, *buf_null;
339
DCELL corrCell, precCell, supCell;
341
long pid, old_pid, new_pid, *pid_corr, *pid_sup, *ltmp;
346
int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked;
349
Rast_get_window(&hd);
351
buf_null = Rast_allocate_d_buf();
352
Rast_set_d_null_value(buf_null, Rast_window_cols());
355
/* initialize patch ids */
356
pid_corr = G_malloc(ad->cl * sizeof(long));
357
pid_sup = G_malloc(ad->cl * sizeof(long));
359
for (j = 0; j < ad->cl; j++) {
364
/* open mask if needed */
366
mask_buf = mask_sup = NULL;
369
if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
371
mask_buf = G_malloc(ad->cl * sizeof(int));
372
if (mask_buf == NULL) {
373
G_fatal_error("malloc mask_buf failed");
376
mask_sup = G_malloc(ad->cl * sizeof(int));
377
if (mask_sup == NULL) {
378
G_fatal_error("malloc mask_buf failed");
381
for (j = 0; j < ad->cl; j++)
387
/* calculate number of patches */
392
/* patch size and type */
401
pst = G_malloc(nalloc * sizeof(struct pst));
402
for (k = 0; k < nalloc; k++) {
406
for (i = 0; i < ad->rl; i++) {
407
buf = RLI_get_dcell_raster_row(fd, i + ad->y, ad);
409
buf_sup = RLI_get_dcell_raster_row(fd, i - 1 + ad->y, ad);
416
if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
424
Rast_set_d_null_value(&precCell, 1);
427
for (j = 0; j < ad->cl; j++) {
430
corrCell = buf[j + ad->x];
431
if (masked && (mask_buf[j] == 0)) {
432
Rast_set_d_null_value(&corrCell, 1);
435
if (Rast_is_d_null_value(&corrCell)) {
443
supCell = buf_sup[j + ad->x];
444
if (masked && (mask_sup[j] == 0)) {
445
Rast_set_d_null_value(&supCell, 1);
448
if (!Rast_is_d_null_value(&precCell) && corrCell == precCell) {
449
pid_corr[j] = pid_corr[j - 1];
451
pst[pid_corr[j]].count++;
457
if (!Rast_is_d_null_value(&supCell) && corrCell == supCell) {
459
if (pid_corr[j] != pid_sup[j]) {
460
/* connect or merge */
466
G_fatal_error("npatch == 0 at row %d, col %d", i, j);
470
old_pid = pid_corr[j];
471
new_pid = pid_sup[j];
472
pid_corr[j] = new_pid;
475
/* update left side of the current row */
476
for (k = 0; k < j; k++) {
477
if (pid_corr[k] == old_pid)
478
pid_corr[k] = new_pid;
480
/* update right side of the previous row */
481
for (k = j + 1; k < ad->cl; k++) {
482
if (pid_sup[k] == old_pid)
483
pid_sup[k] = new_pid;
485
pst[new_pid].count += pst[old_pid].count;
486
pst[old_pid].count = 0;
492
pst[new_pid].count++;
499
/* start new patch */
505
pst = (struct pst *)G_realloc(pst, (pid + incr) * sizeof(struct pst));
507
for (k = nalloc; k < pid + incr; k++)
514
pst[pid].type.t = CELL_TYPE;
515
pst[pid].type.val.c = corrCell;
522
double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
525
/* calculate distance */
526
G_begin_distance_calculations();
527
/* EW Dist at North edge */
528
EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north);
529
/* EW Dist at South Edge */
530
EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south);
531
/* NS Dist at East edge */
532
NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south);
533
/* NS Dist at West edge */
534
NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south);
536
area_units = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) *
537
(((NS_DIST1 + NS_DIST2) / 2) / hd.rows) * area;
539
*result = area_units / (npatch * 10000);
559
int calculateF(int fd, struct area_entry *ad, double *result)
561
FCELL *buf, *buf_sup, *buf_null;
562
FCELL corrCell, precCell, supCell;
564
long pid, old_pid, new_pid, *pid_corr, *pid_sup, *ltmp;
569
int mask_fd, *mask_buf, *mask_sup, *mask_tmp, masked;
572
Rast_get_window(&hd);
574
buf_null = Rast_allocate_f_buf();
575
Rast_set_f_null_value(buf_null, Rast_window_cols());
578
/* initialize patch ids */
579
pid_corr = G_malloc(ad->cl * sizeof(long));
580
pid_sup = G_malloc(ad->cl * sizeof(long));
582
for (j = 0; j < ad->cl; j++) {
587
/* open mask if needed */
589
mask_buf = mask_sup = NULL;
592
if ((mask_fd = open(ad->mask_name, O_RDONLY, 0755)) < 0)
594
mask_buf = G_malloc(ad->cl * sizeof(int));
595
if (mask_buf == NULL) {
596
G_fatal_error("malloc mask_buf failed");
599
mask_sup = G_malloc(ad->cl * sizeof(int));
600
if (mask_sup == NULL) {
601
G_fatal_error("malloc mask_buf failed");
604
for (j = 0; j < ad->cl; j++)
610
/* calculate number of patches */
615
/* patch size and type */
624
pst = G_malloc(nalloc * sizeof(struct pst));
625
for (k = 0; k < nalloc; k++) {
629
for (i = 0; i < ad->rl; i++) {
630
buf = RLI_get_fcell_raster_row(fd, i + ad->y, ad);
632
buf_sup = RLI_get_fcell_raster_row(fd, i - 1 + ad->y, ad);
639
if (read(mask_fd, mask_buf, (ad->cl * sizeof(int))) < 0)
647
Rast_set_f_null_value(&precCell, 1);
650
for (j = 0; j < ad->cl; j++) {
653
corrCell = buf[j + ad->x];
654
if (masked && (mask_buf[j] == 0)) {
655
Rast_set_f_null_value(&corrCell, 1);
658
if (Rast_is_f_null_value(&corrCell)) {
666
supCell = buf_sup[j + ad->x];
667
if (masked && (mask_sup[j] == 0)) {
668
Rast_set_f_null_value(&supCell, 1);
671
if (!Rast_is_f_null_value(&precCell) && corrCell == precCell) {
672
pid_corr[j] = pid_corr[j - 1];
674
pst[pid_corr[j]].count++;
680
if (!Rast_is_f_null_value(&supCell) && corrCell == supCell) {
682
if (pid_corr[j] != pid_sup[j]) {
683
/* connect or merge */
689
G_fatal_error("npatch == 0 at row %d, col %d", i, j);
693
old_pid = pid_corr[j];
694
new_pid = pid_sup[j];
695
pid_corr[j] = new_pid;
698
/* update left side of the current row */
699
for (k = 0; k < j; k++) {
700
if (pid_corr[k] == old_pid)
701
pid_corr[k] = new_pid;
703
/* update right side of the previous row */
704
for (k = j + 1; k < ad->cl; k++) {
705
if (pid_sup[k] == old_pid)
706
pid_sup[k] = new_pid;
708
pst[new_pid].count += pst[old_pid].count;
709
pst[old_pid].count = 0;
715
pst[new_pid].count++;
722
/* start new patch */
728
pst = (struct pst *)G_realloc(pst, (pid + incr) * sizeof(struct pst));
730
for (k = nalloc; k < pid + incr; k++)
737
pst[pid].type.t = CELL_TYPE;
738
pst[pid].type.val.c = corrCell;
745
double EW_DIST1, EW_DIST2, NS_DIST1, NS_DIST2;
748
/* calculate distance */
749
G_begin_distance_calculations();
750
/* EW Dist at North edge */
751
EW_DIST1 = G_distance(hd.east, hd.north, hd.west, hd.north);
752
/* EW Dist at South Edge */
753
EW_DIST2 = G_distance(hd.east, hd.south, hd.west, hd.south);
754
/* NS Dist at East edge */
755
NS_DIST1 = G_distance(hd.east, hd.north, hd.east, hd.south);
756
/* NS Dist at West edge */
757
NS_DIST2 = G_distance(hd.west, hd.north, hd.west, hd.south);
759
area_units = (((EW_DIST1 + EW_DIST2) / 2) / hd.cols) *
760
(((NS_DIST1 + NS_DIST2) / 2) / hd.rows) * area;
762
*result = area_units / (npatch * 10000);