#include #include "defs.h" void print_edge_info (struct Map *map) { int i; fprintf (stdout,"%s: %d edge cells\n", map->fullname, map->edges.count); for (i = 0; i < map->edges.ncats; i++) fprintf (stdout," %d", map->edges.catlist[i].cat); fprintf (stdout,"\n"); } void find_edge_cells (struct Map *map, int verbose) { void init_edge_list(); void add_edge_cell(); void sort_edge_list(); int nrows,ncols,row,col; int fd; CELL *buf0, *buf1, *buf2, *tmp; if (verbose) fprintf (stderr, "Reading map %s ...", map->fullname); ncols = G_window_cols(); nrows = G_window_rows(); buf0 = (CELL *)G_calloc( ncols+2, sizeof(CELL) ); buf1 = (CELL *)G_calloc( ncols+2, sizeof(CELL) ); buf2 = (CELL *)G_calloc( ncols+2, sizeof(CELL) ); for (col = 0; col < (ncols+2); col++) { buf0[col] = 0; buf1[col] = 0; buf2[col] = 0; } fd = G_open_cell_old (map->name, map->mapset); if (fd < 0) exit(1); init_edge_list (map); for (row = 0; row < nrows; row++) { if (verbose) G_percent (row, nrows, 2); /* rotate the input buffers */ tmp = buf0; buf0 = buf1; buf1 = buf2; buf2 = tmp; /* read a row */ if (G_get_map_row (fd, &buf1[1], row) < 0) exit(1); for (col = 1; col <= ncols; col++) { if (buf1[col] /* is a valid category */ && (buf1[col-1] != buf1[col] /* 4 neighbors not the same? */ || buf1[col+1] != buf1[col] || buf0[col] != buf1[col] || buf2[col] != buf1[col])) add_edge_cell (map, buf1[col], row, col-1); } } if (verbose) G_percent (row, nrows, 2); G_close_cell (fd); G_free (buf0); G_free (buf1); G_free (buf2); sort_edge_list(map); } void add_edge_cell (struct Map *map, CELL cat, int row, int col) { int i,k; /* search for this cat (note: sequential search for now) */ for (i = 0; i < map->edges.ncats; i++) if (cat == map->edges.catlist[i].cat) break; if (i == map->edges.ncats) /* new category */ { map->edges.ncats += 1; if (map->edges.nalloc < map->edges.ncats) { map->edges.nalloc += 32; map->edges.catlist = (struct CatEdgeList *) G_realloc (map->edges.catlist, map->edges.nalloc * sizeof (struct CatEdgeList)); } map->edges.catlist[i].ncells = 0; map->edges.catlist[i].nalloc = 0; map->edges.catlist[i].row = NULL; map->edges.catlist[i].col = NULL; map->edges.catlist[i].cat = cat; } /* new edge cell insert */ k = map->edges.catlist[i].ncells; map->edges.catlist[i].ncells += 1; if (map->edges.catlist[i].nalloc < map->edges.catlist[i].ncells) { map->edges.catlist[i].nalloc += 256; map->edges.catlist[i].row = (int *) G_realloc (map->edges.catlist[i].row, map->edges.catlist[i].nalloc * sizeof (int)); map->edges.catlist[i].col = (int *) G_realloc (map->edges.catlist[i].col, map->edges.catlist[i].nalloc * sizeof (int)); } map->edges.catlist[i].row[k] = row; map->edges.catlist[i].col[k] = col; /* for good measure, count the total edge cells */ map->edges.count++; } void init_edge_list (struct Map *map) { map->edges.count = 0; map->edges.ncats = 0; map->edges.nalloc = 0; map->edges.catlist = NULL; } static int cmp (const void *aa, const void *bb) { const struct CatEdgeList *a = aa, *b = bb; return (int) ( a->cat - b->cat ); } void sort_edge_list (struct Map *map) { if (map->edges.ncats > 0) qsort (map->edges.catlist, map->edges.ncats, sizeof (struct CatEdgeList), cmp); }