v.to.rast

Olga Waupotitsch olga at zorro.cecer.army.mil
Fri Jan 14 11:13:37 EST 1994


Please replace file do_areas.c in v.to.rast directory
by the file

_______________-cut here-___________________________

#include "digit.h"
#include "gis.h"

static
struct list
{
    double size;
    int index;
    int equal;
    CELL cat;
} *list;
static int nareas ;

do_areas (Map, Points)
    struct Map_info *Map;
    struct line_pnts *Points;
{
    int i,index, k, equal;
    CELL cat, last_cat;
    static struct line_pnts *Last_Points = NULL, *tmp_Points = NULL;
    int comp_double();

    if (nareas <= 0) return 0;
    if(!Last_Points)
       Last_Points = Vect_new_line_struct();
    if(!tmp_Points)
       tmp_Points = Vect_new_line_struct();

    for (i = 0; i < nareas; i++)
    {
	index = list[i].index;
	cat   = list[i].cat;
	set_cat (cat);
	if(Vect_get_area_points (Map, index, Points) <= 0)
	{
	    fprintf (stderr, "*** Get area [%d] failed ***\n", index);
	    return -1;
	}
	if((list[i].equal<0) /* if we never checked area against previous area */
	    && (list[i].size == list[i-1].size) 
	    && (Points->n_points == Last_Points->n_points) )
        {
	/* check if the area is the same as the last area */
	   list[i].equal = 1;
	   /* copying Points to tmp_Points */
	   dig_alloc_points(tmp_Points, Points->n_points);
	   tmp_Points->n_points = Points->n_points;
	   for(k=0;k<Points->n_points; k++)
	   {
	      tmp_Points->y[k] = Points->y[k];
	      tmp_Points->x[k] = Points->x[k];
	      /*
		 printf("%f %f  %f %f\n", Last_Points->x[k], Last_Points->y[k], tmp_Points->x[k], tmp_Points->y[k]);
		 */
           }
	   if(G_projection() == PROJECTION_LL)
	      for(k=0;k<Points->n_points; k++)
	      {
	         tmp_Points->x[k] = 
			  G_adjust_east_longitude(tmp_Points->x[k], -180.);
	         Last_Points->x[k] = 
			  G_adjust_east_longitude(Last_Points->x[k], -180.);
              }
	   /* Adjusting eastings to be from -180 to 180 */
	   /* sorting because points might be in different order */
	   Last_Points->n_points = Points->n_points;
	   /* since areas might start and end with different point,
	      and since first and last points are the same, we skip the
	      first point in both areas */
	   qsort(Last_Points->x + 1, Last_Points->n_points - 1, sizeof (double), 
	      comp_double);
	   qsort(tmp_Points->x + 1, tmp_Points->n_points - 1, sizeof (double), 
	      comp_double);
	   qsort(Last_Points->y + 1, Last_Points->n_points - 1, sizeof (double), 
	      comp_double);
	   qsort(tmp_Points->y + 1, tmp_Points->n_points - 1, sizeof (double), 
	      comp_double);
	   for(k=0;k<Points->n_points; k++)
	   {
	      if(k>0)
	      {
	         if(Last_Points->y[k] != tmp_Points->y[k]) list[i].equal = 0;
	         if(Last_Points->x[k] != tmp_Points->x[k]) list[i].equal = 0;
	      }
	      Last_Points->y[k] = Points->y[k];
	      Last_Points->x[k] = Points->x[k];
           }
         } /* checking if area is the same as previous area */
	 else
	 {
	   list[i].equal = 0;
	   /* copying Points to tmp_Points */
	   dig_alloc_points(Last_Points, Points->n_points);
	   Last_Points->n_points = Points->n_points;
	   for(k=0;k<Points->n_points; k++)
	   {
	      Last_Points->y[k] = Points->y[k];
	      Last_Points->x[k] = Points->x[k];
           }
         }

	 if(list[i].equal == 1)
	 {
	    fprintf(stderr, "WARNING! There are 2 identical areas in your map\n");
	    if(!cat && !last_cat)
	    {
	       fprintf(stderr, "both of them unlabeled\n", cat);
	       continue;
            }
	    if(cat == last_cat)
	    {
	       fprintf(stderr, "both of them are labeled %d\n", cat);
	       continue;
            }
	    if(cat && last_cat)
	    {
	       fprintf(stderr, "one of them is labeled %d another one is labeled %d\n", last_cat, cat);
	       fprintf("ignoring the area labeled %d\n", cat);
	       continue;
            }
            if(last_cat)
	    {
	       fprintf(stderr, "one of them is labeled %d another one is unlabeled\n", last_cat);
	       printf("Ignoring the unlabeled area\n");
	       continue;
            }
 	    fprintf(stderr, "one of them is unlabeled another one is labeled %d\n", cat);
	    printf("Ignoring the unlabeled area\n");
	    /* don't skip here, go to drawing area */
        } /* processing equal areas */

        last_cat = cat;
	G_plot_polygon (Points->x, Points->y, Points->n_points);
    }
    return nareas;
}

sort_areas (Map, Points)
    struct Map_info *Map;
    struct line_pnts *Points;
{
    int i,index;
    CELL cat;
    int compare();
    double G_area_of_polygon();

    G_begin_polygon_area_calculations();

/* first count valid areas */
    for (nareas = 0, index = 1; index <= Map->n_areas; index++)
    {
	if (area_ok(Map, index, &cat))
	    nareas++;
    }
    if (nareas == 0) return 0;

/* allocate list to hold valid area info */
    list = (struct list *) G_calloc (nareas, sizeof (struct list));

/* store area size,cat,index in list */
    for (i = 0, index = 1; index <= Map->n_areas; index++)
    {
	if (area_ok(Map, index, &cat))
	{
	    list[i].index = index;
	    list[i].cat = cat;
	    if(Vect_get_area_points (Map, index, Points) <= 0)
	    {
		fprintf (stderr, "*** Get area [%d] failed ***\n", index);
		return -1;
	    }
	    list[i].size = G_area_of_polygon (Points->x, Points->y, Points->n_points);
	    i++;
	}
    }

/* sort the list by size */
    qsort (list, nareas, sizeof(struct list), compare);

    /* initialize equals */
    for (i = 0; i < nareas; i++)
    {
	    if(i==0) list[i].equal = 0;
	    else list[i].equal = -1;
    }
    return nareas;
}

static
compare (a, b)
    struct list *a, *b;
{
    if (a->size < b->size)
	return 1;
    if (a->size > b->size)
	return -1;
    return 0;
}

static int
comp_double(i, j)
   double *i, *j;
{
   if(*i < *j)
       return -1;

   if(*i > *j)
       return 1;

   return 0;
}

static
area_ok(Map, index, cat)
    struct Map_info *Map;
    CELL *cat;
{
    int att;

    if (!AREA_ALIVE(&Map->Area[index]))
	return 0;
    att = Map->Area[index].att;
    if (att == 0)
	*cat = 0; /* unlabeled */
    else
	*cat = Map->Att[att].cat;

    return 1;
}





More information about the grass-user mailing list