Esempio n. 1
0
/*------------------------------------------------------------------------------
  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);
}
Esempio n. 2
0
/*------------------------------------------------------------------------------
  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);
}
Esempio n. 3
0
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);

}
Esempio n. 4
0
/*------------------------------------------------------------------------------
  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);
}
Esempio n. 5
0
/*------------------------------------------------------------------------------
  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);
}