/*------------------------------------------------------------------------------ Make almost coincident caps of polygons coincide. Input: npoly = number of polygons to snap. *poly[npoly] = array of npoly pointers to polygon structures. Return value: number of caps adjusted. */ int snap(int npoly, polygon *poly[/*npoly*/]) { #define WARNMAX 8 int i, j, ip, inull, iprune, nadj, dnadj, warnmax; int *start; int *total; int p, max_pixel, ier; long double r; /* start by sorting polygons by pixel number*/ poly_sort(npoly,poly,'p'); /* allocate memory for pixel info arrays start and total */ /* if only self-snapping, don't use pixelization */ max_pixel=(selfsnap)? 1 : poly[npoly-1]->pixel+1; start = (int *) malloc(sizeof(int) * max_pixel); if (!start) { fprintf(stderr, "snap_polys: failed to allocate memory for %d integers\n", max_pixel); return(-1); } total = (int *) malloc(sizeof(int) * max_pixel); if (!total) { fprintf(stderr, "snap_polys: failed to allocate memory for %d integers\n", max_pixel); return(-1); } /* if we're only doing self-snapping, don't use the pixelization info */ if(selfsnap){ start[0]=0; total[0]=npoly; } else{ /* build lists of starting indices of each pixel and total number of polygons in each pixel*/ ier=pixel_list(npoly, poly, max_pixel, start, total); if (ier == -1) { fprintf(stderr, "snap: error building pixel index lists\n"); return(-1); } } /*turn off warning messages if using more than one pixel*/ warnmax= (max_pixel<=1) ? WARNMAX : 0; /* ensure that rp is a unit vector for all polygon caps*/ for (i = 0; i < npoly; i++) { for(ip=0; ip<poly[i]->np; ip++){ r = 0.; for (j = 0; j < 3; j++) r += poly[i]->rp[ip][j] * poly[i]->rp[ip][j]; if (r != 1.) { r = sqrt(r); for (j = 0; j < 3; j++) poly[i]->rp[ip][j] /= r; } } } /* snap edges of polygons to each other */ nadj=0; for(p=0;p<max_pixel;p++){ if(total[p]==0) continue; dnadj=snap_polys(&fmt, total[p], &poly[start[p]], selfsnap, axtol, btol, thtol, ytol, mtol,((selfsnap)? warnmax : warnmax/2),0x0); if(dnadj==-1) return(-1); nadj+=dnadj; } /* prune polygons */ inull = 0; for (i = 0; i < npoly; i++) { iprune = prune_poly(poly[i], mtol); if (iprune >= 2) { if (WARNMAX > 0 && inull == 0) msg("warning from snap: the following polygons have zero area:\n"); if (inull < WARNMAX) { msg(" %d", (fmt.newid == 'o')? poly[i]->id : i); } else if (inull == WARNMAX) { msg(" ... more\n"); } inull++; } } if (WARNMAX > 0 && inull > 0 && inull <= WARNMAX) msg("\n"); if (inull > 0) msg("snap: %d snapped polygons have zero area (but are being retained)\n", inull); /* assign new polygon id numbers */ if (fmt.newid == 'n') { for (i = 0; i < npoly; i++) { poly[i]->id = i; } } if (fmt.newid == 'p') { for (i = 0; i < npoly; i++) { poly[i]->id = poly[i]->pixel; } } msg("snap: total of %d caps adjusted\n", nadj); return(nadj); }
/*------------------------------------------------------------------------------ Balkanize overlapping polygons into many disjoint connected polygons. Input: npoly = number of polygons. poly = array of pointers to polygons. npolys = maximum number of output polygons. mtol = tolerance angle for multiple intersections. fmt = pointer to format structure. axtol, btol, thtol, ytol = tolerance angles (see documentation). Output: polys = array of pointers to polygons. Return value: number of disjoint connected polygons, or -1 if error occurred. */ int balkanize(int npoly, polygon *poly[/*npoly*/], int npolys, polygon *polys[/*npolys*/], long double mtol, format *fmt, long double axtol, long double btol, long double thtol, long double ytol) { /* part_poly should lasso one-boundary polygons only if they have too many caps */ #define ALL_ONEBOUNDARY 1 /* how part_poly should tighten lasso */ #define ADJUST_LASSO 1 /* part_poly should force polygon to be split even if no part can be lassoed */ #define FORCE_SPLIT 1 /* partition_poly should overwrite all original polygons */ #define OVERWRITE_ORIGINAL 2 #define WARNMAX 8 char *snapped_polys = 0x0; int discard, dm, dn, dnp, failed, i, ier, inull, isnap, ip, iprune, j, k, m, n, nadj, np, selfsnap; int *start; int *total; int begin, end, p, max_pixel; long double tol; poly_sort(npoly, poly, 'p'); /* allocate memory for pixel info arrays start and total */ max_pixel=poly[npoly-1]->pixel+1; start = (int *) malloc(sizeof(int) * max_pixel); if (!start) { fprintf(stderr, "balkanize: failed to allocate memory for %d integers\n", max_pixel); return(-1); } total = (int *) malloc(sizeof(int) * max_pixel); if (!total) { fprintf(stderr, "balkanize: failed to allocate memory for %d integers\n", max_pixel); return(-1); } /* build lists of starting indices of each pixel and total number of polygons in each pixel*/ ier=pixel_list(npoly, poly, max_pixel, start, total); if (ier == -1) { fprintf(stderr, "balkanize: error building pixel index lists\n"); return(-1); } /* start by pruning all input polygons */ np = 0; inull = 0; for (i = 0; i < npoly; i++) { tol = mtol; iprune = prune_poly(poly[i], tol); /* error */ if (iprune == -1) { fprintf(stderr, "balkanize: initial prune failed at polygon %d\n", poly[i]->id); return(-1); } /* zero area polygon */ if (iprune >= 2) { if (WARNMAX > 0 && inull == 0) msg("warning from balkanize: following polygons have zero area & are being discarded:\n"); if (inull < WARNMAX) { msg(" %lld", (fmt->newid == 'o')? poly[i]->id : (long long)i); } else if (inull == WARNMAX) { msg(" ... more\n"); } inull++; } else { np++; } } if (WARNMAX > 0 && inull > 0 && inull <= WARNMAX) msg("\n"); if (inull > 0) { msg("balkanize: %d polygons with zero area are being discarded;\n", inull); } /* number of polygons */ msg("balkanizing %d polygons ...\n", np); /* nullify all output polygons */ for (i = 0; i < npolys; i++) { polys[i] = 0x0; } /* m = starting index of current set of fragments of i'th polygon dm = number of current set of fragments of i'th polygon n = starting index of new subset of fragments of i'th polygon dn = number of new subset of fragments of i'th polygon */ msg("balkanize stage 1 (fragment into non-overlapping polygons):\n"); n = 0; dnp = 0; ip = 0; /* go through each pixel and fragment each polygon against the other polygons in its pixel */ for(p=0;p<max_pixel;p++){ begin=start[p]; end=start[p]+total[p]; /* too many polygons */ if (n >= npolys) break; /* fragment each polygon in turn */ for (i = begin; i < end; i++) { /* skip null polygons */ if (poly[i]->np > 0 && poly[i]->cm[0] == 0.) continue; /* update indices */ m = n; dm = 1; n = m + dm; /* make sure output polygon has enough room */ ier = room_poly(&polys[m], poly[i]->np, DNP, 0); if (ier == -1) { fprintf(stderr, "balkanize: failed to allocate memory for polygon of %d caps\n", poly[i]->np + DNP); return(-1); } /* copy polygon i into output polygon */ copy_poly(poly[i], polys[m]); /* fragment successively against other polygons */ for (j = begin; j < end; j++) { /* skip self, or null polygons */ if (j == i || (poly[j]->np > 0 && poly[j]->cm[0] == 0.)) continue; /* keep only one copy of the intersection of i & j */ /* intersection inherits weight of polygon being fragmented, so keeping later polygon ensures intersection inherits weight of later polygon */ if (i < j) { discard = 1; } else { discard = 0; } /* fragment each part of i'th polygon */ for (k = m; k < m + dm; k++) { /* skip null polygons */ if (!polys[k] || (polys[k]->np > 0 && polys[k]->cm[0] == 0.)) continue; /* fragment */ tol = mtol; dn = fragment_poly(&polys[k], poly[j], discard, npolys - n, &polys[n], tol, bmethod); /* error */ if (dn == -1) { fprintf(stderr, "balkanize: UHOH at polygon %lld; continuing ...\n", (fmt->newid == 'o')? polys[i]->id : (long long)ip); continue; /* return(-1); */ } /* increment index of next subset of fragments */ n += dn; /* increment polygon count */ np += dn; dnp += dn; if (!polys[k]) { np--; dnp--; } /* check whether exceeded maximum number of polygons */ //printf("(1) n = %d\n", n); if (n > npolys) { fprintf(stderr, "(1) balkanize: total number of polygons (= %d) exceeded maximum %d\n", npoly + n, npoly + npolys); fprintf(stderr, "if you need more space, enlarge NPOLYSMAX in defines.h, and recompile\n"); fprintf(stderr, "currently, dn = %d, np = %d, dnp = %d, poly[%d]->id = %lld, poly[%d]->pixel = %d\n", dn, np, dnp, i, poly[i]->id, i, poly[i]->pixel); n = npolys; #ifdef CARRY_ON_REGARDLESS break; #else return(-1); #endif } } /* copy down non-null polygons */ dm = 0; for (k = m; k < n; k++) { if (polys[k]) { polys[m + dm] = polys[k]; dm++; } } /* nullify but don't free, because freeing polys[k] will free polys[m + dm] */ for (k = m + dm; k < n; k++) { polys[k] = 0x0; } n = m + dm; if (dm == 0) break; } /* too many polygons */ if (n >= npolys) break; ip++; } } free(start); free(total); msg("added %d polygons to make %d\n", dnp, np); // partition disconnected polygons into connected parts msg("balkanize stage 2 (partition disconnected polygons into connected parts):\n"); m = n; dnp = 0; ip = 0; failed = 0; for (i = 0; i < m; i++) { // skip null polygons if (!polys[i] || (polys[i]->np > 0 && polys[i]->cm[0] == 0.)) continue; // partition disconnected polygons tol = mtol; ier = partition_poly(&polys[i], npolys - n, &polys[n], tol, ALL_ONEBOUNDARY, ADJUST_LASSO, FORCE_SPLIT, OVERWRITE_ORIGINAL, &dn); // error if (ier == -1) { fprintf(stderr, "balkanize: UHOH at polygon %lld; continuing ...\n", (fmt->newid == 'o')? polys[i]->id : (long long)ip); continue; // return(-1); // failed to partition polygon into desired number of parts } else if (ier == 1) { fprintf(stderr, "balkanize: failed to partition polygon %lld fully; partitioned it into %d parts\n", (fmt->newid == 'o')? polys[i]->id : (long long)ip, dn + 1); failed++; } // increment index of next subset of fragments n += dn; // increment polygon count np += dn; dnp += dn; // check whether exceeded maximum number of polygons //printf("(2) n = %d\n", n); if (n > npolys) { fprintf(stderr, "(2) balkanize: total number of polygons (= %d) exceeded maximum %d\n", n + npoly, npoly + npolys); fprintf(stderr, "if you need more space, enlarge NPOLYSMAX in defines.h, and recompile\n"); n = npolys; #ifdef CARRY_ON_REGARDLESS break; #else return(-1); #endif } ip++; } msg("added %d polygons to make %d\n", dnp, np); if (failed > 0) { msg("balkanize: failed to split %d polygons into desired number of connected parts\n", failed); msg(".............................................................................\n"); msg("Failure to split polygon probably means:\n"); msg("either (1) you forgot to run snap on all your input polygon files;\n"); msg(" or (2) the polygon is too small for the numerics to cope with;\n"); msg(" or (3) you have a weird-shaped polygon.\n"); msg("You may ignore this warning message if the weights of polygons in the input\n"); msg("polygon file(s) are already correct, and you do not want to reweight them.\n"); msg("Similarly, you may ignore this warning message if you do want to reweight the\n"); msg("polygons, but the weights of the different parts of each unsplit polygon are\n"); msg("the same. If you want to reweight the different parts of an unsplit polygon\n"); msg("with different weights, then you will need to split that polygon by hand.\n"); msg("Whatever the case, the output file of balkanized polygons constitutes\n"); msg("a valid mask of non-overlapping polygons, which is safe to use.\n"); msg(".............................................................................\n"); } /* prune */ j = 0; inull = 0; for (i = 0; i < n; i++) { tol = mtol; iprune = prune_poly(polys[i], tol); if (iprune == -1) { fprintf(stderr, "balkanize: failed to prune polygon %lld; continuing ...\n", (fmt->newid == 'o')? polys[i]->id : (long long)j); /* return(-1); */ } if (iprune >= 2) { free_poly(polys[i]); polys[i] = 0x0; inull++; } else { polys[j] = polys[i]; j++; } } if (inull > 0) msg("balkanize: %d balkanized polygons have zero area, and are being discarded\n", inull); n = j; /* // allocate snapped_polys array snapped_polys = (char *) malloc(sizeof(char) * n); if (!snapped_polys) { fprintf(stderr, "balkanize: failed to allocate memory for %d characters\n", n); return(-1); } //snap edges of each polygon selfsnap = 1; nadj = snap_polys(fmt, n, polys, selfsnap, axtol, btol, thtol, ytol, mtol, WARNMAX, snapped_polys); if(nadj==-1){ msg("balkanize: error snapping balkanized polygons\n"); return(-1); } // number of polygons whose edges were snapped isnap = 0; for (i = 0; i < n; i++) if (snapped_polys[i]) isnap++; if (isnap > 0) msg("balkanize: edges of %d balkanized polygons were snapped\n", isnap); // prune snapped polygons j = 0; inull = 0; for (i = 0; i < n; i++) { if (snapped_polys[i]) { iprune = prune_poly(polys[i], mtol); if (iprune == -1) { fprintf(stderr, "balkanize: failed to prune polygon %lld; continuing ...\n", (fmt->newid == 'o')? polys[i]->id : (long long)j); // return(-1); } if (iprune >= 2) { free_poly(polys[i]); polys[i] = 0x0; inull++; } else { polys[j] = polys[i]; j++; } } else { polys[j] = polys[i]; j++; } } if (inull > 0) msg("balkanize: %d snapped polygons have zero area, and are being discarded\n", inull); n = j; // free snapped_polys array free(snapped_polys); */ if(n!=-1){ /* sort polygons by pixel number */ poly_sort(n, polys,'p'); msg("balkanize: balkans contain %d polygons\n", n); } /* assign new polygon id numbers in place of inherited ids */ if (fmt->newid == 'n') { for (i = 0; i < n; i++) { polys[i]->id = (long long)i; } } if (fmt->newid == 'p') { for (i = 0; i < n; i++) { polys[i]->id = (long long)polys[i]->pixel; } } return(n); }
int rasterize(int nhealpix_poly, int npoly, polygon *polys[/*npoly*/], int nweights, long double weights[/*nweights*/]) { int min_pixel, max_pixel, ier, ier_h, ier_i, i, j, ipix, ipoly, begin_r, end_r, begin_m, end_m, verb, np, iprune; int *start_r, *start_m, *total_r, *total_m; long double *areas, area_h, area_i, tol; static polygon *polyint = 0x0; /* make sure weights are all zero for rasterizer pixels */ for (i = 0; i < nhealpix_poly; i++) { polys[i]->weight = 0.; } /* allocate memory for rasterizer areas array */ areas = (long double *) malloc(sizeof(long double) * (nweights)); if (!areas) { fprintf(stderr, "rasterize: failed to allocate memory for %d long doubles\n", nweights); exit(1); } /* initialize rasterizer areas array to 0 */ for (i = 0; i < nweights; i++) areas[i] = 0.; /* allow error messages from garea */ verb = 1; /* find areas of rasterizer pixels for later use */ for (i = 1; i <= nweights; i++) { for (j = 0; j < nhealpix_poly; j++) { if (polys[j]->id == i) { tol = mtol; ier_h = garea(polys[j], &tol, verb, &area_h); if (ier_h == 1) { fprintf(stderr, "fatal error in garea\n"); exit(1); } if (ier_h == -1) { fprintf(stderr, "failed to allocate memory in garea\n"); exit(1); } areas[i-1] += area_h; } } } /* sort arrays by pixel number */ poly_sort(nhealpix_poly, polys, 'p'); poly_sort(npoly-nhealpix_poly, &(polys[nhealpix_poly]), 'p'); /* allocate memory for pixel info arrays start_r, start_m, total_r, and total_m */ min_pixel = polys[0]->pixel; max_pixel = (polys[nhealpix_poly-1]->pixel+1>polys[npoly-1]->pixel+1)?(polys[nhealpix_poly-1]->pixel+1):(polys[npoly-1]->pixel+1); start_r = (int *) malloc(sizeof(int) * max_pixel); if (!start_r) { fprintf(stderr, "rasterize: failed to allocate memory for %d integers\n", max_pixel); return(-1); } start_m = (int *) malloc(sizeof(int) * max_pixel); if (!start_m) { fprintf(stderr, "rasterize: failed to allocate memory for %d integers\n", max_pixel); return(-1); } total_r = (int *) malloc(sizeof(int) * max_pixel); if (!total_r) { fprintf(stderr, "rasterize: failed to allocate memory for %d integers\n", max_pixel); return(-1); } total_m = (int *) malloc(sizeof(int) * max_pixel); if (!total_m) { fprintf(stderr, "rasterize: failed to allocate memory for %d integers\n", max_pixel); return(-1); } /* build lists of starting indices of each pixel and total number of polygons in each pixel */ ier = pixel_list(nhealpix_poly, polys, max_pixel, start_r, total_r); if (ier == -1) { fprintf(stderr, "rasterize: error building pixel index lists for rasterizer polygons\n"); return(-1); } ier = pixel_list(npoly-nhealpix_poly, &(polys[nhealpix_poly]), max_pixel, start_m, total_m); if (ier == -1) { fprintf(stderr, "rasterize: error building pixel index lists for input mask polygons\n"); return(-1); } /* correction due to the start_m array's offset */ for (i = min_pixel; i < max_pixel; i++) { start_m[i] += nhealpix_poly; } /* compute intersection of each input mask polygon with each rasterizer polygon */ for (ipix = min_pixel; ipix < max_pixel; ipix++) { begin_r = start_r[ipix]; end_r = start_r[ipix] + total_r[ipix]; begin_m = start_m[ipix]; end_m = start_m[ipix] + total_m[ipix]; for (ipoly = begin_m; ipoly < end_m; ipoly++) { /* disregard any null polygons */ if (!polys[ipoly]) continue; for (i = begin_r; i < end_r; i++) { /* make sure polyint contains enough space for intersection */ np = polys[ipoly]->np + polys[i]->np; ier = room_poly(&polyint, np, DNP, 0); if (ier == -1) goto out_of_memory; poly_poly(polys[ipoly], polys[i], polyint); /* suppress coincident boundaries, to make garea happy */ iprune = trim_poly(polyint); /* intersection of polys[ipoly] and polys[i] is null polygon */ if (iprune >= 2) area_i = 0.; else { tol = mtol; ier_i = garea(polyint, &tol, verb, &area_i); if (ier_i == 1) { fprintf(stderr, "fatal error in garea\n"); return(-1); } if (ier_i == -1) { fprintf(stderr, "failed to allocate memory in garea\n"); return(-1); } } weights[(polys[i]->id)-1] += (area_i)*(polys[ipoly]->weight); } } } for (i=0; i<nweights; i++) { if(areas[i]!=0){ weights[i] = weights[i]/areas[i]; } else{ weights[i]=0; fprintf(stderr,"WARNING: rasterize: area of rasterizer polygon %d is zero. Assigning zero weight.\n",i); } } return(i+1); /* ----- error return ----- */ out_of_memory: fprintf(stderr, "rasterize: failed to allocate memory for polygon of %d caps\n", np + DNP); return(-1); }
/*------------------------------------------------------------------------------ Id numbers of polygons containing az, el positions. The az, el positions are read from in_filename, and the results are written to out_filename. Implemented as interpretive read/write, to permit interactive behaviour. Input: in_filename = name of file to read from; "" or "-" means read from standard input. out_filename = name of file to write to; "" or "-" means write to standard output. fmt = pointer to format structure. poly = array of pointers to polygons. npoly = number of polygons in poly array. Return value: number of lines written, or -1 if error occurred. */ int poly_ids(char *in_filename, char *out_filename, format *fmt, int npoly, polygon *poly[/*npoly*/]) { #define AZEL_STR_LEN 32 char input[] = "input", output[] = "output"; char *word, *next; char az_str[AZEL_STR_LEN], el_str[AZEL_STR_LEN]; int i, idwidth, ird, len, nid, nids, nid0, nid2, np; long long idmin, idmax; long long *id; long double *weight; azel v; char *out_fn; FILE *outfile; int *start; int *total; int *parent_pixels; int p, res, max_pixel, ier, sorted; ier=-1; sorted=0; while(ier!=0){ max_pixel= poly[npoly-1]->pixel; res_max=get_res(max_pixel, scheme); max_pixel=pixel_start(res_max+1,scheme); /* allocate memory for pixel info arrays start and total */ msg("res_max=%d, max_pixel=%d\n",res_max,max_pixel); start = (int *) malloc(sizeof(int) * max_pixel); if (!start) { fprintf(stderr, "polyid: failed to allocate memory for %d integers\n", max_pixel); return(-1); } total = (int *) malloc(sizeof(int) * max_pixel); if (!total) { fprintf(stderr, "polyid: failed to allocate memory for %d integers\n", max_pixel); return(-1); } parent_pixels = (int *) malloc(sizeof(int) * (res_max+1)); if (!parent_pixels) { fprintf(stderr, "polyid: failed to allocate memory for %d integers\n", res_max+1); return(-1); } /* build lists of starting indices of each pixel and total number of polygons in each pixel*/ ier=pixel_list(npoly, poly, max_pixel, start, total); if (ier == -1) { // if pixel_list returns an error, try sorting the polygons and trying again if(!sorted){ msg("sorting polygons...\n"); poly_sort(npoly,poly,'p'); sorted=1; } else{ fprintf(stderr, "poly_ids: error building pixel index lists\n"); return(-1); } } } /* open in_filename for reading */ if (!in_filename || strcmp(in_filename, "-") == 0) { file.file = stdin; file.name = input; } else { file.file = fopen(in_filename, "r"); if (!file.file) { fprintf(stderr, "cannot open %s for reading\n", in_filename); return(-1); } file.name = in_filename; } file.line_number = 0; /* open out_filename for writing */ if (!out_filename || strcmp(out_filename, "-") == 0) { outfile = stdout; out_fn = output; } else { outfile = fopen(out_filename, "w"); if (!outfile) { fprintf(stderr, "cannot open %s for writing\n", out_filename); return(-1); } out_fn = out_filename; } /* advise angular units */ msg("will take units of input az, el angles in %s to be ", file.name); switch (fmt->inunit) { #include "angunit.h" } msg("\n"); if (fmt->outunit != fmt->inunit) { msg("units of output az, el angles will be "); switch (fmt->outunit) { #include "angunit.h" } msg("\n"); } /* largest width of polygon id number */ idmin = 0; idmax = 0; for (i = 0; i < npoly; i++) { if (!poly[i]) continue; if (poly[i]->id < idmin) idmin = poly[i]->id; if (poly[i]->id > idmax) idmax = poly[i]->id; } idmin = ((idmin < 0)? floorl(log10l((long double)-idmin)) + 2 : 1); idmax = ((idmax > 0)? floorl(log10l((long double)idmax)) + 1 : 1); idwidth = ((idmin > idmax)? idmin : idmax); /* write header */ v.az = 0.; wrangle(v.az, fmt->outunit, fmt->outprecision, AZEL_STR_LEN, az_str); len = strlen(az_str); if (fmt->outunit == 'h') { sprintf(az_str, "az(hms)"); sprintf(el_str, "el(dms)"); } else { sprintf(az_str, "az(%c)", fmt->outunit); sprintf(el_str, "el(%c)", fmt->outunit); } fprintf(outfile, "%*s %*s", len, az_str, len, el_str); if (npoly > 0){ if(polyid_weight==1){ fprintf(outfile, " polygon_weights"); } else{ fprintf(outfile, " polygon_ids"); } } fprintf(outfile, "\n"); /* interpretive read/write loop */ np = 0; nid = 0; nids = 0; nid0 = 0; nid2 = 0; while (1) { /* read line */ ird = rdline(&file); /* serious error */ if (ird == -1) return(-1); /* EOF */ if (ird == 0) break; /* read <az> */ word = file.line; ird = rdangle(word, &next, fmt->inunit, &v.az); /* skip header */ if (ird != 1 && np == 0) continue; /* otherwise exit on unrecognized characters */ if (ird != 1) break; /* read <el> */ word = next; ird = rdangle(word, &next, fmt->inunit, &v.el); /* skip header */ if (ird != 1 && np == 0) continue; /* otherwise exit on unrecognized characters */ if (ird != 1) break; /* convert az and el from input units to radians */ scale_azel(&v, fmt->inunit, 'r'); //find out what pixel the az el point is in at the maximum resolution p=which_pixel(v.az, v.el, res_max, scheme); //get the list of all the possible parent pixels get_parent_pixels(p, parent_pixels, scheme); nid=0; for(res=res_max;res>=0;res--){ p=parent_pixels[res]; //if this pixel isn't in the polygon list, go to next parent pixel if(total[p]==0) continue; // id numbers of the polygons containing position az, el nid = poly_id(total[p], &poly[start[p]], v.az, v.el, &id, &weight); } /* convert az and el from radians to output units */ scale_azel(&v, 'r', fmt->outunit); /* write result */ wrangle(v.az, fmt->outunit, fmt->outprecision, AZEL_STR_LEN, az_str); wrangle(v.el, fmt->outunit, fmt->outprecision, AZEL_STR_LEN, el_str); fprintf(outfile, "%s %s", az_str, el_str); for (i = 0; i < nid; i++) { if(polyid_weight==1){ fprintf(outfile, " %.18Lg", weight[i]); } else{ fprintf(outfile, " %*lld", idwidth, id[i]); } } fprintf(outfile, "\n"); fflush(outfile); /* increment counters of results */ np++; nids += nid; if (nid == 0) { nid0++; } else if (nid >= 2) { nid2++; } } /* advise */ if (nid0 > 0) msg("%d points were not inside any polygon\n", nid0); if (nid2 > 0) msg("%d points were inside >= 2 polygons\n", nid2); if (outfile != stdout) { if(polyid_weight==1){ msg("polyid: %d weights at %d positions written to %s\n", nids, np, out_fn); } else { msg("polyid: %d id numbers at %d positions written to %s\n", nids, np, out_fn); } } free(start); free(total); free(parent_pixels); return(np); }
/*------------------------------------------------------------------------------ Take pixelized polygons, find the average weight within each pixel, and return a set of polygons consisting of the pixels weighted with the average weight. Input: poly = array of pointers to polygons. npoly = pointer to number of polygons. Output: polys = array of pointers to polygons; Return value: number of polygons discarded by pixelmapping, or -1 if error occurred. */ int pixelmap(int *npoly, polygon *poly[/**npoly*/]) { int i, j, nadj, k, kstart,kend,numpix; int *start; int *total; int *parent_pixels; int begin, end, p,max_pixel,min_pixel, ier, verb,res1,res2; long double tol,area, tot_area; long double *av_weight; long double *av_weight0; poly_sort(*npoly,poly,'p'); min_pixel = poly[0]->pixel; max_pixel = poly[*npoly-1]->pixel+1; res1=get_res(min_pixel,scheme); res2=get_res(max_pixel,scheme); if(res1<res_max){ fprintf(stderr,"pixelmap: there are pixels in the mask with a lower resolution than the desired pixelmap resolution %d. The desired pixelmap resolution can be set with the -P option.\n",res_max); fprintf(stderr,"Before using pixelmap, use pixelize with the -P0,r option to pixelize the entire mask to the desired resolution r.\n"); return(-1); } /* allocate memory for pixel info arrays start and total */ start = (int *) malloc(sizeof(int) * max_pixel); if (!start) { fprintf(stderr, "pixelmap: failed to allocate memory for %d integers\n", max_pixel); return(-1); } total = (int *) malloc(sizeof(int) * max_pixel); if (!total) { fprintf(stderr, "pixelmap: failed to allocate memory for %d integers\n", max_pixel); return(-1); } /* build lists of starting indices of each pixel and total number of polygons in each pixel*/ ier=pixel_list(*npoly, poly, max_pixel, start, total); if (ier == -1) { fprintf(stderr, "pixelmap: error building pixel index lists\n"); return(-1); } //allocate memory for parent pixels array parent_pixels = (int *) malloc(sizeof(int) * (res2+1)); if (!parent_pixels) { fprintf(stderr, "pixelmap: failed to allocate memory for %d integers\n", res2+1); return(-1); } //kstart=number of first pixel at desired output resolution //kend=number of last pixel at desired output resolution if(res_max==-1){ kstart=pixel_start(res1,scheme); kend=pixel_start(res2+1,scheme)-1; } else{ kstart=pixel_start(res_max,scheme); kend=pixel_start(res_max+1,scheme)-1; } av_weight0= (long double *) malloc(sizeof(long double) * (kend-kstart+1) ); if (!av_weight0) { fprintf(stderr, "pixelmap: failed to allocate memory for %d integers\n", kend-kstart+1 ); return(-1); } //make av_weight an array indexed by the pixel number av_weight=av_weight0-kstart; //set av_weight array to 0 initially for(k=kstart;k<=kend;k++){ av_weight[k]=0; } nadj = 0; verb=1; /*find average weight of polygons within each pixel*/ for(p=min_pixel;p<max_pixel;p++){ begin=start[p]; end=start[p]+total[p]; ier=get_parent_pixels(p,parent_pixels,scheme); if(ier) return(-1); //set k to the pixel at the desired output resolution, or to the pixel number if using //existing resolution k=(res_max==-1) ? p : parent_pixels[res_max]; for (i = begin; i < end; i++) { if (!poly[i]) continue; tol=mtol; ier = garea(poly[i], &tol, verb, &area); if(ier==1 || ier == -1){ fprintf(stderr, "error %d in garea in polygon %d\n", ier, poly[i]->id); continue; } av_weight[k]+=poly[i]->weight * area; } } //replace polygons in input array with non-zero weight pixels j=0; for(k=kstart;k<=kend;k++){ if(av_weight[k]==0) continue; free_poly(poly[j]); poly[j]=get_pixel(k,scheme); tol=mtol; ier = garea(poly[j], &tol, verb, &tot_area); if(ier==1 || ier == -1){ fprintf(stderr, "pixelmap: error in garea in pixel %d\n",p); continue; } poly[j]->weight=av_weight[k]/tot_area; j++; if(j> *npoly ){ fprintf(stderr,"pixelmap: number of pixels with non-zero weight exceeds number of polygons.\n"); fprintf(stderr, "Try running unify on your mask to remove zero-weight polygons before using pixelmap.\n"); } } numpix=j; for(j=numpix; j< *npoly; j++){ free_poly(poly[j]); poly[j] = 0x0; nadj++; } *npoly=numpix; free(start); free(total); free(parent_pixels); free(av_weight0); /* assign new polygon id numbers */ if (fmt.newid == 'n') { for (i = 0; i < *npoly; i++) { poly[i]->id = i; } } if (fmt.newid == 'p') { for (i = 0; i < *npoly; i++) { poly[i]->id = poly[i]->pixel; } } /* advise */ msg("pixelmap: %d pixels in map\n", numpix); return(nadj); }