Sfoglia il codice sorgente

vlib: added new subrouties to the public API
* Vect_cat_list_to_array()
* Vect_copy_table_by_cat_list()


git-svn-id: https://svn.osgeo.org/grass/grass/trunk@56233 15284696-431f-4ddb-bdfa-cd5b030d7da7

Martin Landa 12 anni fa
parent
commit
7eb882569c
3 ha cambiato i file con 112 aggiunte e 12 eliminazioni
  1. 3 0
      include/defs/vector.h
  2. 66 10
      lib/vector/Vlib/cats.c
  3. 43 2
      lib/vector/Vlib/copy.c

+ 3 - 0
include/defs/vector.h

@@ -73,6 +73,7 @@ int Vect_cats_in_constraint(struct line_cats *, int, struct cat_list *);
 struct cat_list *Vect_new_cat_list(void);
 int Vect_str_to_cat_list(const char *, struct cat_list *);
 int Vect_array_to_cat_list(const int *, int, struct cat_list *);
+int Vect_cat_list_to_array(const struct cat_list *, int **, int *);
 int Vect_cat_in_cat_list(int, const struct cat_list *);
 void Vect_destroy_cat_list(struct cat_list *);
 
@@ -416,6 +417,8 @@ int Vect_copy(const char *, const char *, const char *);
 int Vect_rename(const char *, const char *);
 int Vect_copy_table(const struct Map_info *, struct Map_info *, int, int,
                     const char *, int);
+int Vect_copy_table_by_cat_list(const struct Map_info *, struct Map_info *, int, int,
+                                const char *, int, const struct cat_list *);
 int Vect_copy_table_by_cats(const struct Map_info *, struct Map_info *, int, int,
                             const char *, int, int *, int);
 int Vect_copy_tables(const struct Map_info *, struct Map_info *, int);

+ 66 - 10
lib/vector/Vlib/cats.c

@@ -311,14 +311,9 @@ struct cat_list *Vect_new_cat_list()
     p = (struct cat_list *)G_malloc(sizeof(struct cat_list));
 
     /* n_ranges MUST be initialized to zero */
-    if (p) {
-	p->n_ranges = 0;
-	p->alloc_ranges = 0;
-	p->field = 0;
-	p->min = NULL;
-	p->max = NULL;
-    }
-
+    if (p)
+        G_zero(p, sizeof(struct cat_list));
+    
     return p;
 }
 
@@ -361,9 +356,10 @@ void Vect_destroy_cat_list(struct cat_list *p)
    cat_list->field = 0
    cat_list->n_ranges = 4
    cat_list->min = {2, 3, 5, 20}
-   cat_list->max = {2, 3, 9, 20}\endverbatim
+   cat_list->max = {2, 3, 9, 20}
+   \endverbatim
 
-   \param[in] str category list as a string
+   \param str category list as a string
    \param[in,out] list pointer to cat_list structure
 
    \return number of errors in ranges
@@ -477,6 +473,66 @@ int Vect_array_to_cat_list(const int *vals, int nvals, struct cat_list *list)
 }
 
 /*!
+   \brief Convert cat_list struct to ordered array of unique integers.
+   
+   Output array do not contain duplicate items.
+
+   Allocated array should be freed by G_free().
+   
+   \param cat_list pointer to cat_list struct
+   \param[out] vals array of integers
+   \param[out] nvals number of values
+
+   \return 0 on success
+   \return -1 on failure
+ */
+int Vect_cat_list_to_array(const struct cat_list *list, int **vals, int *nvals)
+{
+    int i, j, k, n, n_cats, n_ucats, last_cat;
+    int *cats, *ucats;
+    
+    G_debug(1, "Vect_cat_list_to_array()");
+
+    *nvals = n_cats = 0;
+    cats = NULL;
+    for (i = 0; i < list->n_ranges; i++) {
+        n = list->max[i] - list->min[i] + 1;
+        if (n < 1)
+            return -1;
+        
+        /* realloc array */
+        cats = (int *) G_realloc(cats, sizeof(int) * (n_cats + n));
+
+        for (j = n_cats, k = 0; j < n_cats + n; j++, k++) {
+            cats[j] = list->min[i] + k;
+        }
+        n_cats += n;
+    }
+
+    /* sort array */
+    qsort(cats, n_cats, sizeof(int), cmp);
+
+    /* skip duplicated values */
+    ucats = G_malloc(sizeof(int) * n_cats);
+    last_cat = ucats[0] = cats[0];
+    n_ucats = 1;
+    for (i = 1; i < n_cats; i++) {
+        if (last_cat == cats[i])
+            continue;
+        last_cat = ucats[n_ucats++] = cats[i];
+    }
+    G_free(cats);
+    
+    /* reallocate array for unique values */
+    ucats = (int *) G_realloc(ucats, sizeof(int) * n_ucats);
+    
+    *nvals = n_ucats;
+    *vals = ucats;
+    
+    return 0;
+}
+
+/*!
    \brief Check if category number is in list.
 
    \param cat category number

+ 43 - 2
lib/vector/Vlib/copy.c

@@ -566,7 +566,7 @@ int Vect_copy_tables(const struct Map_info *In, struct Map_info *Out,
    \param[out] Out output vector map
    \param field_in input layer number
    \param field_out output layer number
-   \param field_name layer name
+   \param field_name layer name (can be NULL)
    \param type how many tables are linked to map: GV_1TABLE / GV_MTABLE
 
    \return 0 on success
@@ -581,13 +581,54 @@ int Vect_copy_table(const struct Map_info *In, struct Map_info *Out, int field_i
 
 /*!
    \brief Copy attribute table linked to vector map based on category
+   list.
+
+   If <em>cat_list</em> is NULL, then Vect_copy_table() is called.
+
+   \param In input vector map
+   \param[out] Out output vector map
+   \param field_in input layer number
+   \param field_out output layer number
+   \param field_name layer name (can be NULL)
+   \param type how many tables are linked to map: GV_1TABLE / GV_MTABLE
+   \param cat_list pointer to cat_list struct (can be NULL)
+
+   \return 0 on success
+   \return -1 on error
+*/
+int Vect_copy_table_by_cat_list(const struct Map_info *In, struct Map_info *Out,
+                                int field_in, int field_out, const char *field_name,
+                                int type, const struct cat_list *cat_list)
+{
+    int *cats;
+    int ncats, ret;
+
+    if (cat_list) {
+        if (Vect_cat_list_to_array(cat_list, &cats, &ncats) != 0)
+            return -1;
+        
+        ret = Vect_copy_table_by_cats(In, Out, field_in, field_out, field_name,
+                                      type, cats, ncats);
+        
+        G_free(cats);
+    }
+    else {
+        ret = Vect_copy_table(In, Out, field_in, field_out, field_name,
+                              type);
+    }
+
+    return ret;
+}
+
+/*!
+   \brief Copy attribute table linked to vector map based on category
    numbers.
 
    \param In input vector map
    \param[out] Out output vector map
    \param field_in input layer number
    \param field_out output layer number
-   \param field_name layer name
+   \param field_name layer name (can be NULL)
    \param type how many tables are linked to map: GV_1TABLE / GV_MTABLE
    \param cats pointer to array of cats or NULL
    \param ncats number of cats in 'cats'