123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- #include <stdlib.h>
- #include <grass/gis.h>
- #include <grass/raster.h>
- #include <grass/vector.h>
- #include <grass/dbmi.h>
- #include <grass/glocale.h>
- #include "local.h"
- static struct list
- {
- double size;
- int index;
- CELL cat;
- } *list;
- static int nareas;
- /* function prototypes */
- static int compare(const void *, const void *);
- int do_areas(struct Map_info *Map, struct line_pnts *Points,
- dbCatValArray * Cvarr, int ctype, int use,
- double value, int value_type)
- {
- int i;
- CELL cval, cat;
- DCELL dval;
- if (nareas <= 0)
- return 0;
- G_important_message(_("Reading areas..."));
- for (i = 0; i < nareas; i++) {
- /* Note: in old version (grass5.0) there was a check here if the current area
- * is identical to previous one. I don't see any reason for this in topological vectors */
- G_percent(i, nareas, 2);
- cat = list[i].cat;
- G_debug(3, "Area cat = %d", cat);
- if (ISNULL(&cat)) { /* No centroid or no category */
- set_cat(cat);
- }
- else {
- if (use == USE_ATTR) {
- if (ctype == DB_C_TYPE_INT) {
- if ((db_CatValArray_get_value_int(Cvarr, cat, &cval)) !=
- DB_OK) {
- G_warning(_("No record for area (cat = %d)"), cat);
- SETNULL(&cval);
- }
- set_cat(cval);
- }
- else if (ctype == DB_C_TYPE_DOUBLE) {
- if ((db_CatValArray_get_value_double(Cvarr, cat, &dval))
- != DB_OK) {
- G_warning(_("No record for area (cat = %d)"), cat);
- SETDNULL(&dval);
- }
- set_dcat(dval);
- }
- else {
- G_fatal_error(_("Unable to use column specified"));
- }
- }
- else if (use == USE_CAT) {
- set_cat(cat);
- }
- else {
- if (value_type == CELL_TYPE)
- set_cat((int)value);
- else
- set_dcat(value);
- }
- }
- if (Vect_get_area_points(Map, list[i].index, Points) <= 0) {
- G_warning(_("Get area %d failed"), list[i].index);
- return -1;
- }
- G_plot_polygon(Points->x, Points->y, Points->n_points);
- }
- G_percent(1, 1, 1);
-
- return nareas;
- }
- int sort_areas(struct Map_info *Map, struct line_pnts *Points,
- int field, struct cat_list *cat_list)
- {
- int i, centroid, nareas_selected;
- struct line_cats *Cats;
- CELL cat;
- G_begin_polygon_area_calculations();
- Cats = Vect_new_cats_struct();
- /* first count valid areas */
- nareas = Vect_get_num_areas(Map);
- if (nareas == 0)
- return 0;
- /* allocate list to hold valid area info */
- list =
- (struct list *)G_calloc(nareas * sizeof(char), sizeof(struct list));
- /* store area size,cat,index in list */
- nareas_selected = 0;
- for (i = 0; i < nareas; i++) {
- centroid = Vect_get_area_centroid(Map, i + 1);
- SETNULL(&cat);
- if (centroid <= 0) {
- G_debug(2,_("Area without centroid (OK for island)"));
- }
- else {
- Vect_read_line(Map, NULL, Cats, centroid);
- if (field > 0) {
- if (Vect_cats_in_constraint(Cats, field, cat_list)) {
- Vect_cat_get(Cats, field, &cat);
- nareas_selected++;
- }
- else {
- G_debug(2, _("Area centroid without category"));
- }
- }
- else {
- /* field < 1, process all areas with centroid */
- cat = 0;
- nareas_selected++;
- }
- }
- list[i].index = i + 1;
- Vect_get_area_points(Map, i + 1, Points);
- list[i].size =
- G_area_of_polygon(Points->x, Points->y, Points->n_points);
- list[i].cat = cat;
- }
- if (nareas_selected > 0) {
- /* sort the list by size */
- qsort(list, nareas * sizeof(char), sizeof(struct list), compare);
- }
- return nareas_selected;
- }
- static int compare(const void *aa, const void *bb)
- {
- const struct list *a = aa, *b = bb;
- if (a->size < b->size)
- return 1;
- if (a->size > b->size)
- return -1;
- return 0;
- }
|