1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372 |
- /*
- ************************************************************
- * MODULE: r.le.pixel/texture.c *
- * Version 5.0 Nov. 1, 2001 *
- * *
- * AUTHOR: W.L. Baker, University of Wyoming *
- * BAKERWL@UWYO.EDU *
- * *
- * PURPOSE: To analyze pixel-scale landscape properties *
- * texture.c calculates the measures for r.le.pixel *
- * *
- * COPYRIGHT: (C) 2001 by W.L. Baker *
- * *
- * This program is free software under the GNU General *
- * Public License(>=v2). Read the file COPYING that comes *
- * with GRASS for details *
- * *
- ************************************************************/
- #include <grass/gis.h>
- #include <grass/config.h>
- #include <grass/raster.h>
- #include "pixel.h"
- /* set the maximum number of categories
- that can be in the input map */
- #define NO_OF_CATEGORIES cats.num
- /* set external pointers and routines */
- extern struct CHOICE *choice;
- extern int g_scale, g_unit;
- /* define a structure used to read in
- info about categories in the map */
- struct Categories cats;
- /* declare a counter for the number
- of pixels with non-null values
- (total) in cal_edge and a flag for
- pixels with null attribute in
- cal_divers */
- int total, nullflag;
- /* MOVING WINDOW ANALYSIS DRIVER */
- void mv_texture(int nrows, int ncols, double **buf, double **null_buf,
- double **value, int index, double *rich, int cnt,
- int cntwhole)
- {
- int lc;
- register int i, j;
- double *atts, *edgeatts, attr[4], diver[4], edge[4], tex[5], **weight,
- **edgemat;
- /* set the contents of the arrays used
- used to stored the results of the
- diversity, texture, and edge
- calculations to zero */
- attr[0] = attr[1] = attr[2] = attr[3] = 0;
- diver[0] = diver[1] = diver[2] = diver[3] = 0;
- tex[0] = tex[1] = tex[2] = tex[3] = tex[4] = 0;
- edge[0] = edge[1] = edge[2] = edge[3] = 0;
- /*************************/
- /* The weight matrix in */
- /* "r.le.para/weight" */
- /* must have the follow- */
- /* ing format: a, b, c */
- /* = category values */
- /* */
- /* a b c */
- /* a 0.0 0.1 0.1 */
- /* b 0.1 0.1 0.1 */
- /* c 0.2 0.2 0.3 */
- /*************************/
- /* If juxtaposition is to be
- calculated, then dynamically
- allocate memory for the atts
- array and the weight matrix */
- if (choice->jux[0]) {
- atts = (double *)G_calloc(cntwhole, sizeof(double));
- weight = (double **)G_calloc(cntwhole, sizeof(double *));
- for (i = 0; i < cntwhole; i++)
- weight[i] = (double *)G_calloc(cntwhole, sizeof(double));
- /* read in the weight matrix */
- read_weight(cntwhole, atts, weight);
- total = 0;
- }
- /*************************/
- /* The edge matrix in */
- /* "r.le.para/edge" */
- /* must have the follow- */
- /* ing format: a, b, c */
- /* = category values */
- /* */
- /* a b c */
- /* a 0 1 1 */
- /* b 1 0 1 */
- /* c 1 1 0 */
- /*************************/
- /* If edge by type is to be
- calculated, then dynamically
- allocate memory for the edgeatts
- array and the edgemat matrix */
- if (choice->edg[2]) {
- edgeatts = (double *)G_malloc(cntwhole * sizeof(double));
- edgemat = (double **)G_malloc(cntwhole * sizeof(double *));
- for (i = 0; i < cntwhole; i++)
- edgemat[i] = (double *)G_malloc(cntwhole * sizeof(double));
- /* read in the edge matrix */
- read_edge(cntwhole, edgeatts, edgemat);
- }
- /* main calculation loop. Do the
- calculations for each pixel in
- the sampling area */
- for (i = 1; i < nrows + 1; i++) {
- for (j = 1; j < ncols + 1; j++) {
- /* find the sequence number of the
- attribute in the richness array */
- if ((buf[i][j] || buf[i][j] == 0.0) && null_buf[i][j] == 0.0)
- lc = check_order(buf[i][j], rich);
- /* based on the choices made, call
- the appropriate calc. routine */
- if (choice->att[0])
- cal_att(buf, null_buf, i, j, nrows, ncols, attr);
- if (choice->te2[0])
- cal_tex(buf, null_buf, i, j, nrows, ncols, lc, rich, cnt,
- tex);
- if (choice->edg[0] || choice->jux[0])
- cal_edge(buf, null_buf, i, j, nrows, ncols, lc, edge,
- cntwhole, atts, weight, edgeatts, edgemat, 0, 0);
- if (choice->div[0])
- cal_divers(buf, null_buf, i, j, nrows, ncols, lc, cnt, diver);
- }
- }
- if (choice->jux[0]) {
- G_free(atts);
- for (i = 0; i < cntwhole; i++)
- G_free(weight[i]);
- G_free(weight);
- }
- if (choice->edg[2]) {
- G_free(edgeatts);
- for (i = 0; i < cntwhole; i++)
- G_free(edgemat[i]);
- G_free(edgemat);
- }
- /* put the calculated value for the
- selected measure into the
- corresponding pixel in the output
- map */
- if (choice->att[0]) { /* ATTRIBUTE MEASURES */
- if (choice->att[1])
- value[index][0] = attr[0]; /* Mean */
- if (choice->att[2])
- value[index][1] = attr[1]; /* St. dev. */
- if (choice->att[3])
- value[index][2] = attr[2]; /* Min. */
- if (choice->att[4])
- value[index][3] = attr[3]; /* Max. */
- }
- if (choice->div[0]) { /* DIVERSITY MEASURES */
- if (choice->div[1])
- value[index][4] = diver[0]; /* Richness */
- if (choice->div[2])
- value[index][5] = diver[1]; /* Shannon */
- if (choice->div[3])
- value[index][6] = diver[2]; /* Dominance */
- if (choice->div[4])
- value[index][7] = diver[3]; /* Inv. Simpson */
- }
- if (choice->te2) { /* TEXTURE MEASURES */
- if (choice->te2[1]) /* Contagion */
- value[index][8] = tex[0];
- if (choice->te2[2]) /* ASM */
- value[index][9] = tex[1];
- if (choice->te2[3]) /* IDM */
- value[index][10] = tex[2];
- if (choice->te2[4]) /* Entropy */
- value[index][11] = tex[3];
- if (choice->te2[5]) /* Contrast */
- value[index][12] = tex[4];
- }
- if (choice->jux[0]) { /* JUXTA. MEASURES */
- if (choice->jux[1])
- value[index][13] = edge[0]; /* Mean jux. */
- if (choice->jux[2])
- value[index][14] = edge[2]; /* St.dev. jux. */
- }
- if (choice->edg[0]) { /* EDGE MEASURES */
- if (choice->edg[1])
- value[index][15] = edge[1]; /* Sum of edges */
- if (choice->edg[2])
- value[index][16] = edge[3]; /* Sum of edges
- by type */
- }
- return;
- }
- /* WHOLE MAP, UNITS, OR REGIONS
- DRIVER */
- void df_texture(int nrows, int ncols, double **buf, double **null_buf,
- double *rich, int cnt, int cntwhole)
- {
- FILE *fp0, *fp1, *fp2, *fp3, *fp4, *fp5;
- int lc, fd, *edge1, *edge2, fc, **edgenull;
- register int i, j;
- double *atts, *edgeatts, attr[4], diver[4], edge[4], tex[5], **weight,
- **edgemat;
- CELL **edgemap_c, *edge_buf_c;
- FCELL **edgemap_f, *edge_buf_f;
- DCELL **edgemap_d, *edge_buf_d, *zscor_buf;
- RASTER_MAP_TYPE data_type;
- data_type = Rast_map_type(choice->fn, G_mapset());
- /* set the contents of the arrays
- used to stored the results of the
- diversity, texture, and edge
- calculations to zero */
- attr[0] = attr[1] = attr[2] = attr[3] = 0;
- diver[0] = diver[1] = diver[2] = diver[3] = 0;
- edge[0] = edge[1] = edge[2] = edge[3] = 0;
- tex[0] = tex[1] = tex[2] = tex[3] = tex[4] = 0;
- /*************************/
- /* The weight matrix in */
- /* "r.le.para/weight" */
- /* must have the follow- */
- /* ing format: a, b, c */
- /* = category values */
- /* */
- /* a b c */
- /* a 0.0 0.1 0.1 */
- /* b 0.1 0.1 0.1 */
- /* c 0.2 0.2 0.3 */
- /*************************/
- /* If juxtaposition is to be
- calculated, then dynamically
- allocate memory for the atts
- array and the weight matrix */
- if (choice->jux[0]) {
- atts = (double *)G_calloc(cntwhole, sizeof(double));
- weight = (double **)G_calloc(cntwhole, sizeof(double *));
- for (i = 0; i < cntwhole; i++)
- weight[i] = (double *)G_calloc(cntwhole, sizeof(double));
- /* read in the weight matrix */
- read_weight(cntwhole, atts, weight);
- total = 0;
- }
- /*************************/
- /* The edge matrix in */
- /* "r.le.para/edge" */
- /* must have the follow- */
- /* ing format: a, b, c */
- /* = category values */
- /* */
- /* a b c */
- /* a 0 1 1 */
- /* b 1 0 1 */
- /* c 1 1 0 */
- /*************************/
- /* If edge by type is to be
- calculated, then dynamically
- allocate memory for the edgeatts
- array and the edgemat matrix */
- if (choice->edg[2]) {
- edgeatts = (double *)G_calloc(cntwhole, sizeof(double));
- edgemat = (double **)G_calloc(cntwhole, sizeof(double *));
- for (i = 0; i < cntwhole; i++) {
- edgemat[i] = (double *)G_calloc(cntwhole, sizeof(double));
- }
- /* read in the edge matrix */
- read_edge(cntwhole, edgeatts, edgemat);
- }
- /* dynamically allocate storage for the
- buffer that will hold the map of the
- edges and for the edgenull array */
- if (choice->edgemap) {
- switch (data_type) {
- case (CELL_TYPE):
- edgemap_c = (CELL **) G_calloc(nrows + 3, sizeof(CELL *));
- for (i = 0; i < nrows + 3; i++)
- edgemap_c[i] = (CELL *) G_calloc(ncols + 3, sizeof(CELL));
- break;
- case (FCELL_TYPE):
- edgemap_f = (FCELL **) G_calloc(nrows + 3, sizeof(FCELL *));
- for (i = 0; i < nrows + 3; i++)
- edgemap_f[i] = (FCELL *) G_calloc(ncols + 3, sizeof(FCELL));
- break;
- case (DCELL_TYPE):
- edgemap_d = (DCELL **) G_calloc(nrows + 3, sizeof(DCELL *));
- for (i = 0; i < nrows + 3; i++)
- edgemap_d[i] = (DCELL *) G_calloc(ncols + 3, sizeof(DCELL));
- break;
- }
- edgenull = (int **)G_calloc(nrows + 3, sizeof(int *));
- for (i = 0; i < nrows + 3; i++) {
- edgenull[i] = (int *)G_calloc(ncols + 3, sizeof(int));
- }
- for (i = 1; i < nrows + 1; i++)
- for (j = 1; j < ncols + 1; j++)
- *(*(edgenull + i) + j) = 1;
- }
- /* main calculation loop. Do the
- calculations for each pixel in
- the map */
- for (i = 1; i < nrows + 1; i++) {
- for (j = 1; j < ncols + 1; j++) {
- /* find the sequence number of the
- attribute in the richness array */
- if ((buf[i][j] || buf[i][j] == 0.0) && null_buf[i][j] == 0.0)
- lc = check_order(buf[i][j], rich);
- /* based on the choices made, call
- the appropriate calc. routine */
- if (choice->att[0])
- cal_att(buf, null_buf, i, j, nrows, ncols, attr);
- if (choice->div[0])
- cal_divers(buf, null_buf, i, j, nrows, ncols, lc, cnt, diver);
- if (choice->jux[0] || choice->edg[0]) {
- edge1 = edge2 = 0;
- cal_edge(buf, null_buf, i, j, nrows, ncols, lc, edge,
- cntwhole, atts, weight, edgeatts, edgemat, &edge1,
- &edge2);
- if (choice->edgemap) {
- if (edge1) {
- switch (data_type) {
- case (CELL_TYPE):
- *(*(edgemap_c + i) + j) = *(*(buf + i) + j);
- *(*(edgemap_c + i + 1) + j) =
- *(*(buf + i + 1) + j);
- break;
- case (FCELL_TYPE):
- *(*(edgemap_f + i) + j) = *(*(buf + i) + j);
- *(*(edgemap_f + i + 1) + j) =
- *(*(buf + i + 1) + j);
- break;
- case (DCELL_TYPE):
- *(*(edgemap_d + i) + j) = *(*(buf + i) + j);
- *(*(edgemap_d + i + 1) + j) =
- *(*(buf + i + 1) + j);
- break;
- }
- *(*(edgenull + i) + j) = 0;
- *(*(edgenull + i + 1) + j) = 0;
- }
- if (edge2) {
- switch (data_type) {
- case (CELL_TYPE):
- *(*(edgemap_c + i) + j) = *(*(buf + i) + j);
- *(*(edgemap_c + i) + j + 1) =
- *(*(buf + i) + j + 1);
- break;
- case (FCELL_TYPE):
- *(*(edgemap_f + i) + j) = *(*(buf + i) + j);
- *(*(edgemap_f + i) + j + 1) =
- *(*(buf + i) + j + 1);
- break;
- case (DCELL_TYPE):
- *(*(edgemap_d + i) + j) = *(*(buf + i) + j);
- *(*(edgemap_d + i) + j + 1) =
- *(*(buf + i) + j + 1);
- break;
- }
- *(*(edgenull + i) + j) = 0;
- *(*(edgenull + i) + j + 1) = 0;
- }
- }
- }
- if (choice->te2[0])
- cal_tex(buf, null_buf, i, j, nrows, ncols, lc, rich, cnt,
- tex);
- }
- }
- if (choice->jux[0]) {
- G_free(atts);
- for (i = 0; i < cntwhole; i++)
- G_free(weight[i]);
- G_free(weight);
- }
- if (choice->edg[2]) {
- G_free(edgeatts);
- for (i = 0; i < cntwhole; i++)
- G_free(edgemat[i]);
- G_free(edgemat);
- }
- /* if the edge map was requested */
- if (choice->edgemap) {
- fc = Rast_open_new("edge", data_type);
- switch (data_type) {
- case (CELL_TYPE):
- edge_buf_c = Rast_allocate_buf(CELL_TYPE);
- for (i = 1; i < nrows + 1; i++) {
- Rast_zero_buf(edge_buf_c, CELL_TYPE);
- Rast_set_null_value(edge_buf_c, ncols + 1, CELL_TYPE);
- for (j = 1; j < ncols + 1; j++) {
- if (*(*(edgenull + i) + j) == 0)
- *(edge_buf_c + j - 1) = edgemap_c[i][j];
- }
- Rast_put_row(fc, edge_buf_c, CELL_TYPE);
- }
- break;
- case (FCELL_TYPE):
- edge_buf_f = Rast_allocate_buf(FCELL_TYPE);
- for (i = 1; i < nrows + 1; i++) {
- Rast_zero_buf(edge_buf_f, FCELL_TYPE);
- Rast_set_null_value(edge_buf_f, ncols + 1, FCELL_TYPE);
- for (j = 1; j < ncols + 1; j++) {
- if (*(*(edgenull + i) + j) == 0)
- *(edge_buf_f + j - 1) = edgemap_f[i][j];
- }
- Rast_put_row(fc, edge_buf_f, FCELL_TYPE);
- }
- break;
- case (DCELL_TYPE):
- edge_buf_d = Rast_allocate_buf(DCELL_TYPE);
- for (i = 1; i < nrows + 1; i++) {
- Rast_zero_buf(edge_buf_d, DCELL_TYPE);
- Rast_set_null_value(edge_buf_d, ncols + 1, DCELL_TYPE);
- for (j = 1; j < ncols + 1; j++) {
- if (*(*(edgenull + i) + j) == 0)
- *(edge_buf_d + j - 1) = edgemap_d[i][j];
- }
- Rast_put_row(fc, edge_buf_d, DCELL_TYPE);
- }
- break;
- }
- switch (data_type) {
- case (CELL_TYPE):
- G_free(edge_buf_c);
- for (i = 0; i < nrows + 3; i++)
- G_free(edgemap_c[i]);
- G_free(edgemap_c);
- break;
- case (FCELL_TYPE):
- G_free(edge_buf_f);
- for (i = 0; i < nrows + 3; i++)
- G_free(edgemap_f[i]);
- G_free(edgemap_f);
- break;
- case (DCELL_TYPE):
- G_free(edge_buf_d);
- for (i = 0; i < nrows + 3; i++)
- G_free(edgemap_d[i]);
- G_free(edgemap_d);
- break;
- }
- for (i = 0; i < nrows + 3; i++)
- G_free(edgenull[i]);
- G_free(edgenull);
- Rast_close(fc);
- }
- /* if the zscore map was requested */
- if (choice->z) {
- fd = Rast_open_new("zscores", DCELL_TYPE);
- zscor_buf = Rast_allocate_buf(DCELL_TYPE);
- for (i = 1; i < nrows + 1; i++) {
- Rast_zero_buf(zscor_buf, DCELL_TYPE);
- Rast_set_null_value(zscor_buf, ncols + 1, DCELL_TYPE);
- for (j = 1; j < ncols + 1; j++) {
- if (attr[1] > 0.0)
- if ((buf[i][j] || buf[i][j] == 0) &&
- null_buf[i][j] == 0.0)
- *(zscor_buf + j - 1) =
- (buf[i][j] - attr[0]) / attr[1];
- }
- Rast_put_row(fd, zscor_buf, DCELL_TYPE);
- }
- G_free(zscor_buf);
- Rast_close(fd);
- }
- /* open the output files and
- save the calculated values */
- if (choice->att[0]) {
- fp0 = fopen0("r.le.out/b1-4.out", "a");
- fprintf(fp0, "%5d%5d", g_scale, g_unit);
- fprintf(fp0, " %10.3f %10.3f %10.3f %10.3f\n",
- attr[0], attr[1], attr[2], attr[3]);
- fclose(fp0);
- }
- if (choice->div[0]) {
- fp1 = fopen0("r.le.out/d1-4.out", "a");
- fprintf(fp1, "%5d%5d", g_scale, g_unit);
- fprintf(fp1, " %10.3f %10.3f %10.3f %10.3f\n",
- diver[0], diver[1], diver[2], diver[3]);
- fclose(fp1);
- }
- if (choice->te2[0]) {
- fp2 = fopen0("r.le.out/t1-5.out", "a");
- fprintf(fp2, "%5d%5d", g_scale, g_unit);
- fprintf(fp2, " %10.3f %10.3f %10.3f %10.3f %10.3f\n",
- tex[0], tex[1], tex[2], tex[3], tex[4]);
- fclose(fp2);
- }
- if (choice->jux[0]) {
- fp3 = fopen0("r.le.out/j1-2.out", "a");
- fprintf(fp3, "%5d%5d", g_scale, g_unit);
- fprintf(fp3, " %10.3f %10.3f\n", edge[0], edge[2]);
- fclose(fp3);
- }
- if (choice->edg[1]) {
- fp4 = fopen0("r.le.out/e1.out", "a");
- fprintf(fp4, "%5d%5d", g_scale, g_unit);
- fprintf(fp4, " %10.0f\n", edge[1]);
- fclose(fp4);
- }
- if (choice->edg[2]) {
- fp5 = fopen0("r.le.out/e2.out", "a");
- fprintf(fp5, "%5d%5d", g_scale, g_unit);
- fprintf(fp5, " %10.0f\n", edge[3]);
- fclose(fp5);
- }
- return;
- }
- /* ATTRIBUTE CALC. */
- void cal_att(double **buf, double **null_buf, int i0, int j0, int nr, int nc,
- double *attr)
- {
- static int count;
- static double mini, maxi;
- double mean, stdv;
- static double sum, sum2;
- if (i0 == 1 && j0 == 1) {
- sum = 0.0;
- sum2 = 0.0;
- count = 0;
- maxi = 0.0;
- mini = BIG;
- mean = 0.0;
- stdv = 0.0;
- }
- if ((buf[i0][j0] || buf[i0][j0] == 0.0) && null_buf[i0][j0] == 0.0) {
- count++;
- sum += buf[i0][j0];
- sum2 += buf[i0][j0] * buf[i0][j0];
- if (buf[i0][j0] > maxi)
- maxi = buf[i0][j0];
- if (buf[i0][j0] < mini)
- mini = buf[i0][j0];
- }
- if (i0 == nr && j0 == nc) {
- /* calc. b1 = mean pixel attr. */
- attr[0] = mean = sum / count;
- /* calc. b2 = st. dev. pixel attr. */
- stdv = sum2 / count - mean * mean;
- if (stdv > 0)
- attr[1] = sqrt(stdv);
- /* calc. b3 = min. pixel attr. */
- attr[2] = mini;
- /* calc. b4 = max. pixel attr. */
- attr[3] = maxi;
- }
- return;
- }
- /* DIVERSITY CALC. */
- void cal_divers(double **buf, double **null_buf, int i0, int j0, int nr,
- int nc, int lc, int cnt, double *diver)
- {
- int tot;
- static int *density;
- register int i;
- double p, entr;
- /* if this is the first pixel,
- dynamically allocate memory for
- the density array */
- if (1 == i0 && 1 == j0)
- density = (int *)G_calloc(cnt, sizeof(int));
- /* if the pixel has a non-null
- attribute */
- if ((buf[i0][j0] || buf[i0][j0] == 0) && null_buf[i0][j0] == 0.0) {
- /* increment the density count for
- the right element of the density
- array */
- density[lc]++;
- }
- /* if this is the last pixel in the
- sampling area, do the calc. */
- if (i0 == nr && j0 == nc) {
- /* initialize the counter for the
- total number of pixels */
- tot = 0;
- diver[0] = cnt; /* richness */
- if (cnt > 1)
- entr = log((double)(cnt));
- else
- entr = 0.0;
- /* calculate the total # of pixels */
- for (i = 0; i < cnt; i++) {
- /*printf("i=%d tot=%d density[%d]=%d\n",i,tot,i,density[i]); */
- tot = tot + density[i];
- }
- for (i = 0; i < cnt; i++) {
- if (density[i] > 0 && tot > 0) {
- p = density[i] / (double)(tot);
- diver[1] += -(p * log(p)); /* Shannon */
- /*printf("i=%d p=%f shann=%f\n", i, p, diver[1]); */
- diver[3] += p * p;
- }
- }
- diver[2] = entr - diver[1]; /* dominance */
- diver[3] = 1 / diver[3]; /* recip. Simpson */
- G_free(density);
- }
- return;
- }
- /* TEXTURE CALC. */
- void cal_tex(double **buf, double **null_buf, int i0, int j0, int nr, int nc,
- int lc, double *rich, int cnt, double *tex)
- {
- int r, ln;
- double p;
- static int **GLCM;
- register int i, j;
- int GLCM_sum = 0;
- /* setup the GLCM matrix */
- if ((i0 == 1 && j0 == 1)) {
- GLCM = (int **)G_calloc(cnt, sizeof(int *));
- for (i = 0; i < cnt; i++)
- GLCM[i] = (int *)G_calloc(cnt, sizeof(int));
- }
- /* calculate the GLCM, using
- the appropriate one of the
- seven texture methods
- (parameter te1) */
- if ((buf[i0][j0] || buf[i0][j0] == 0.0) && null_buf[i0][j0] == 0.0) {
- if (i0 > 1) {
- if (choice->tex == 3 || choice->tex == 5 || choice->tex == 7) {
- if ((buf[i0 - 1][j0] ||
- buf[i0 - 1][j0] == 0.0) && null_buf[i0 - 1][j0] == 0.0) {
- ln = check_order(buf[i0 - 1][j0], rich);
- GLCM[lc][ln]++;
- }
- }
- if (j0 > 1 && (choice->tex == 4 ||
- choice->tex == 6 || choice->tex == 7)) {
- if ((buf[i0 - 1][j0 - 1] ||
- buf[i0 - 1][j0 - 1] == 0.0) &&
- null_buf[i0 - 1][j0 - 1] == 0.0) {
- ln = check_order(buf[i0 - 1][j0 - 1], rich);
- GLCM[lc][ln]++;
- }
- }
- if (j0 < nc && (choice->tex == 2 ||
- choice->tex == 6 || choice->tex == 7)) {
- if ((buf[i0 - 1][j0 + 1] ||
- buf[i0 - 1][j0 + 1] == 0.0) &&
- null_buf[i0 - 1][j0 + 1] == 0.0) {
- ln = check_order(buf[i0 - 1][j0 + 1], rich);
- GLCM[lc][ln]++;
- }
- }
- }
- if (i0 < nr) {
- if (choice->tex == 3 || choice->tex == 5 || choice->tex == 7) {
- if ((buf[i0 + 1][j0] ||
- buf[i0 + 1][j0] == 0.0) && null_buf[i0 + 1][j0] == 0.0) {
- ln = check_order(buf[i0 + 1][j0], rich);
- GLCM[lc][ln]++;
- }
- }
- if (j0 > 1 && (choice->tex == 2 ||
- choice->tex == 6 || choice->tex == 7)) {
- if ((buf[i0 + 1][j0 - 1] ||
- buf[i0 + 1][j0 - 1] == 0.0) &&
- null_buf[i0 + 1][j0 - 1] == 0.0) {
- ln = check_order(buf[i0 + 1][j0 - 1], rich);
- GLCM[lc][ln]++;
- }
- }
- if (j0 < nc && (choice->tex == 4 ||
- choice->tex == 6 || choice->tex == 7)) {
- if ((buf[i0 + 1][j0 + 1] ||
- buf[i0 + 1][j0 + 1] == 0.0) &&
- null_buf[i0 + 1][j0 + 1] == 0.0) {
- ln = check_order(buf[i0 + 1][j0 + 1], rich);
- GLCM[lc][ln]++;
- }
- }
- }
- if (j0 > 1 && (choice->tex == 1 ||
- choice->tex == 5 || choice->tex == 7)) {
- if ((buf[i0][j0 - 1] ||
- buf[i0][j0 - 1] == 0.0) && null_buf[i0][j0 - 1] == 0.0) {
- ln = check_order(buf[i0][j0 - 1], rich);
- GLCM[lc][ln]++;
- }
- }
- if (j0 < nc && (choice->tex == 1 ||
- choice->tex == 5 || choice->tex == 7)) {
- if ((buf[i0][j0 + 1] ||
- buf[i0][j0 + 1] == 0.0) && null_buf[i0][j0 + 1] == 0.0) {
- ln = check_order(buf[i0][j0 + 1], rich);
- GLCM[lc][ln]++;
- }
- }
- }
- /* once the end of the buffer
- has been reached, sum up the
- contents of the GLCM */
- if (i0 == nr && j0 == nc) {
- for (i = 0; i < cnt; i++) {
- /*printf("%3d %3d %3d %3d %3d\n",GLCM[i][0],GLCM[i][1],GLCM[i][2],
- GLCM[i][3],GLCM[i][4]); */
- for (j = 0; j < cnt; j++)
- GLCM_sum = GLCM_sum + GLCM[i][j];
- }
- r = GLCM_sum;
- /* for each category, compute the
- Pij and the measures */
- for (i = 0; i < cnt; i++)
- for (j = 0; j < cnt; j++)
- if (p = GLCM[i][j] / (double)(r)) {
- tex[3] += p * log(p);
- tex[1] += p * p; /* ASM */
- tex[2] += p / (1 + (rich[i] - rich[j]) * (rich[i] - rich[j])); /* IDM */
- tex[4] += p * (rich[i] - rich[j]) * (rich[i] - rich[j]); /* Contrast */
- }
- if (tex[3])
- tex[3] = -1.0 * tex[3]; /* Entropy */
- tex[0] = 2 * log((double)(cnt)) - tex[3]; /* Contagion */
- for (i = 0; i < cnt; i++)
- G_free(GLCM[i]);
- G_free(GLCM);
- }
- return;
- }
- /* EDGE, JUXTAPOSITION CALC. */
- void cal_edge(double **buf, double **null_buf, int i0, int j0, int nr, int nc,
- int lc, double *edge, int cntwhole, double *atts,
- double **weight, double *edgeatts, double **edgemat, int *edge1,
- int *edge2)
- {
- int ln, lr, cnt, fr, to;
- double juxta, sum, stdv;
- static double sum2 = 0;
- /* VARIABLES:
- atts = an array of the attributes; read from weight file.
- weight = weight from the weight file.
- edgeatts =
- edgemat =
- cntwhole = richness (total number of attributes)
- ln = sequence number, for the neighbor pixel, in the atts
- array
- lc = sequence number for an attribute in the richness
- array (NO LONGER USED)
- lr = sequence number, for the current pixel, in the atts
- array
- edge1 = sum of edges requested
- edge2 = sum of edges by type requested
- edge[0] = running total of juxtaposition values
- edge[1] = sum of edges
- edge[2] = st. dev. juxtaposition
- edge[3] = sum of edges by type
- */
- /* initialize variables */
- sum = cnt = 0;
- /* juxtaposition calc. step 1:
- each 4 line loop checks first
- that the pixel has non-null
- attribute, second finds the
- sequence number for the
- pixel's attribute in the
- attribute array, third sums
- the quantity and weight, and
- fourth sums the correct cnt */
- /* if this pixel has a non-null
- attribute, do the calculations */
- if ((buf[i0][j0] || buf[i0][j0] == 0) && null_buf[i0][j0] == 0.0) { /*1 */
- /* increment the count of non-zero
- pixels */
- total++;
- if (choice->jux[0])
- lr = find_loc(cntwhole, atts, buf[i0][j0]);
- /* if this pixel is not on the
- edge of the map in the first
- row, and if juxt. was chosen */
- if (i0 > 1 && choice->jux[0]) {
- /* neighbor 1: i0-1,j0 */
- if ((buf[i0 - 1][j0] || buf[i0 - 1][j0] == 0.0) &&
- null_buf[i0 - 1][j0] == 0.0) {
- ln = find_loc(cntwhole, atts, buf[i0 - 1][j0]);
- sum += 2 * weight[lr][ln];
- cnt += 2;
- }
- /* if this pixel is not on the
- edge of the map in the first
- col */
- if (j0 > 1) {
- /* neighbor 2: i0-1,j0-1 */
- if ((buf[i0 - 1][j0 - 1] || buf[i0 - 1][j0 - 1] == 0.0) &&
- null_buf[i0 - 1][j0 - 1] == 0.0) {
- ln = find_loc(cntwhole, atts, buf[i0 - 1][j0 - 1]);
- sum += weight[lr][ln];
- cnt++;
- }
- }
- /* if this pixel is not on the
- edge of the map in the last
- col */
- if (j0 < nc) {
- /* neighbor 3: i0-1,j0+1 */
- if ((buf[i0 - 1][j0 + 1] || buf[i0 - 1][j0 + 1] == 0.0) &&
- null_buf[i0 - 1][j0 + 1] == 0.0) {
- ln = find_loc(cntwhole, atts, buf[i0 - 1][j0 + 1]);
- sum += weight[lr][ln];
- cnt++;
- }
- }
- }
- /* if this pixel is not on the
- edge of the map in the last
- row and if juxta. was chosen */
- if (i0 < nr) {
- if (choice->jux[0]) {
- /* neighbor 4: i0+1,j0 */
- if ((buf[i0 + 1][j0] || buf[i0 + 1][j0] == 0.0) &&
- null_buf[i0 + 1][j0] == 0.0) {
- ln = find_loc(cntwhole, atts, buf[i0 + 1][j0]);
- sum += 2 * weight[lr][ln];
- cnt += 2;
- }
- /* if this pixel is not on the
- edge of the map in the first
- col */
- if (j0 > 1) {
- /* neighbor 5: i0+1,j0-1 */
- if ((buf[i0 + 1][j0 - 1] || buf[i0 + 1][j0 - 1] == 0.0) &&
- null_buf[i0 + 1][j0 - 1] == 0.0) {
- ln = find_loc(cntwhole, atts, buf[i0 + 1][j0 - 1]);
- sum += weight[lr][ln];
- cnt++;
- }
- }
- /* if this pixel is not on the
- edge of the map in the last
- col */
- if (j0 < nc) {
- /* neighbor 6: i0+1,j0+1 */
- if ((buf[i0 + 1][j0 + 1] || buf[i0 + 1][j0 + 1] == 0.0) &&
- null_buf[i0 + 1][j0 + 1] == 0.0) {
- ln = find_loc(cntwhole, atts, buf[i0 + 1][j0 + 1]);
- sum += weight[lr][ln];
- cnt++;
- }
- }
- }
- /* if the i0+1, j0 pixel is different,
- and both pixels have non-null
- attributes */
- if (choice->edg[0] && (buf[i0][j0] != buf[i0 + 1][j0]) &&
- (buf[i0 + 1][j0] || buf[i0 + 1][j0] == 0.0) &&
- null_buf[i0 + 1][j0] == 0.0) {
- /* then increment edge[1] to
- indicate that an edge has been
- found if sum of edges requested */
- if (choice->edg[1])
- edge[1]++;
- /* then increment edge[2] to
- indicate that an edge has been
- found if the edge is one of the
- types requested and if sum of
- edges by type requested */
- if (choice->edg[2]) {
- fr = find_edge(cntwhole, edgeatts, buf[i0][j0]);
- to = find_edge(cntwhole, edgeatts, buf[i0 + 1][j0]);
- if (edgemat[fr][to]) {
- edge[3]++;
- if (choice->edgemap)
- *edge1 = 1;
- }
- }
- }
- }
- /* regardless which row this pixel
- is in (even if edge row); if
- this pixel is not on the edge
- of the map in the first col, and
- if juxta. was chosen */
- if (j0 > 1 && choice->jux[0]) {
- /* neighbor 7: i0,j0-1 */
- if ((buf[i0][j0 - 1] || buf[i0][j0 - 1] == 0.0) &&
- null_buf[i0][j0 - 1] == 0.0) {
- ln = find_loc(cntwhole, atts, buf[i0][j0 - 1]);
- sum += 2 * weight[lr][ln];
- cnt += 2;
- }
- }
- /* regardless which row this pixel
- is in (even if edge row); if
- this pixel is not on the edge
- of the map in the last col, and
- if juxta. was chosen */
- if (j0 < nc) {
- if (choice->jux[0]) {
- /* neighbor 8: i0,j0+1 */
- if ((buf[i0][j0 + 1] || buf[i0][j0 + 1] == 0.0) &&
- null_buf[i0][j0 + 1] == 0.0) {
- ln = find_loc(cntwhole, atts, buf[i0][j0 + 1]);
- sum += 2 * weight[lr][ln];
- cnt += 2;
- }
- }
- /* if the i0, j0+1 pixel is different,
- and both pixels have non-zero
- attributes */
- if (choice->edg[0] && (buf[i0][j0] != buf[i0][j0 + 1]) &&
- (buf[i0][j0 + 1] || buf[i0][j0 + 1] == 0.0) &&
- null_buf[i0][j0 + 1] == 0.0) {
- /* then increment edge[1] to
- indicate that an edge has been
- found if sum of edges requested */
- if (choice->edg[1])
- edge[1]++;
- /* then increment edge[2] to
- indicate that an edge has been
- found if the edge is one of the
- types requested and if sum of
- edges by type requested */
- if (choice->edg[2]) {
- fr = find_edge(cntwhole, edgeatts, buf[i0][j0]);
- to = find_edge(cntwhole, edgeatts, buf[i0][j0 + 1]);
- if (edgemat[fr][to]) {
- edge[3]++;
- if (choice->edgemap)
- *edge2 = 1;
- }
- }
- }
- }
- }
- /* calculate juxtaposition and
- add it to the running total
- in edge[0] */
- if (choice->jux[0]) {
- if (cnt)
- juxta = sum / cnt;
- else
- juxta = 0.0;
- edge[0] += juxta;
- sum2 += juxta * juxta;
- }
- /* if this is the last pixel in
- the sampling area and juxta-
- position was chosen */
- if (choice->jux[0] && i0 == nr && j0 == nc) {
- edge[0] /= total;
- stdv = (double)sum2 / total - edge[0] * edge[0];
- if (stdv > 0)
- edge[2] = sqrt(stdv);
- sum2 = 0;
- }
- return;
- }
- /* READ THE WEIGHT FILE */
- void read_weight(int richcount, double atts[], double **weight, int *attcnt)
- {
- FILE *fp;
- register int i, j;
- float tmp;
- /* open the weight file */
- fp = fopen2("r.le.para/weight", "r");
- /* read the attributes into
- the atts array */
- for (i = 0; i < richcount; i++) {
- fscanf(fp, "%f", &tmp);
- atts[i] = tmp;
- }
- while (fgetc(fp) != '\n')
- if (fgetc(fp) != ' ') {
- fprintf(stdout, "\n");
- fprintf(stdout,
- " *************************************************\n");
- fprintf(stdout,
- " The weight file (r.le.para/weight) is incorrect \n");
- fprintf(stdout,
- " since more/less than the %d attributes found \n",
- richcount);
- fprintf(stdout,
- " in the map are listed in the weight file \n");
- fprintf(stdout,
- " *************************************************\n");
- exit(1);
- }
- /* read the weights, skipping
- the first column, which
- contains the attribute again */
- for (i = 0; i < richcount; i++) {
- fscanf(fp, "%f", &tmp);
- for (j = 0; j < i; j++) {
- weight[i][j] = weight[j][i];
- }
- for (j = 0; j < richcount; j++) {
- fscanf(fp, "%f", &tmp);
- weight[i][j] = tmp;
- }
- while (fgetc(fp) != '\n') ;
- }
- fclose(fp);
- return;
- }
- /* READ THE EDGE FILE */
- void read_edge(int richcount, double atts[], double **edge)
- {
- FILE *fp;
- register int i, j;
- float tmp;
- /* open the edge file */
- fp = fopen3("r.le.para/edge", "r");
- /* read the attributes into
- the atts array */
- for (i = 0; i < richcount; i++) {
- fscanf(fp, "%f", &tmp);
- atts[i] = tmp;
- }
- while (fgetc(fp) != '\n')
- if (fgetc(fp) != ' ') {
- fprintf(stdout, "\n");
- fprintf(stdout,
- " *************************************************\n");
- fprintf(stdout,
- " The edge file (r.le.para/edge) is incorrect \n");
- fprintf(stdout,
- " since more/less than the %d attributes found \n",
- richcount);
- fprintf(stdout,
- " in the map are listed in the edge file \n");
- fprintf(stdout,
- " *************************************************\n");
- exit(1);
- }
- /* read the edge weights, skipping
- the first column, which
- contains the attribute again */
- for (i = 0; i < richcount; i++) {
- fscanf(fp, "%f", &tmp);
- for (j = 0; j < i; j++) {
- edge[i][j] = edge[j][i];
- }
- for (j = 0; j < richcount; j++) {
- fscanf(fp, "%f", &tmp);
- edge[i][j] = tmp;
- }
- while (fgetc(fp) != '\n') ;
- }
- fclose(fp);
- return;
- }
- /* FIND THE SEQUENCE NUMBER FOR
- AN ATTRIBUTE IN THE ATTRIBUTE
- ARRAY WHICH IS READ FROM THE
- WEIGHT FILE */
- int find_loc(int richcount, double atts[], double test)
- {
- register int i;
- G_sleep_on_error(0);
- for (i = 0; i < richcount; i++) {
- if (test == atts[i])
- return i;
- }
- G_fatal_error("The weight file in r.le.para is incorrect, exit\n");
- return (0);
- }
- /* FIND THE SEQUENCE NUMBER FOR
- AN ATTRIBUTE IN THE ATTRIBUTE
- ARRAY WHICH IS READ FROM THE
- EDGE FILE */
- int find_edge(int richcount, double atts[], double test)
- {
- register int i;
- G_sleep_on_error(0);
- for (i = 0; i < richcount; i++) {
- if (test == atts[i]) {
- return i;
- }
- }
- G_fatal_error("The edge file in r.le.para is incorrect, exit\n");
- return (0);
- }
- /* FIND THE SEQUENCE NO. OF AN
- ATTRIBUTE IN THE RICHNESS ARRAY */
- int check_order(double att, double *rich)
- {
- int i = 0;
- while (att != rich[i])
- i++;
- return i;
- }
|