[GRASS-SVN] r53997 - in grass/trunk: include/defs lib/vector/Vlib

svn_grass at osgeo.org svn_grass at osgeo.org
Fri Nov 23 11:31:30 PST 2012


Author: mmetz
Date: 2012-11-23 11:31:30 -0800 (Fri, 23 Nov 2012)
New Revision: 53997

Modified:
   grass/trunk/include/defs/vector.h
   grass/trunk/lib/vector/Vlib/cats.c
Log:
Vlib: add cats constraint functions

Modified: grass/trunk/include/defs/vector.h
===================================================================
--- grass/trunk/include/defs/vector.h	2012-11-23 18:18:26 UTC (rev 53996)
+++ grass/trunk/include/defs/vector.h	2012-11-23 19:31:30 UTC (rev 53997)
@@ -66,6 +66,8 @@
 int Vect_get_area_cats(const struct Map_info *, int, struct line_cats *);
 int Vect_get_area_cat(const struct Map_info *, int, int);
 int Vect_get_line_cat(const struct Map_info *, int, int);
+struct cat_list *Vect_cats_set_constraint(struct Map_info *, int, char *, char *);
+int Vect_cats_in_constraint(struct line_cats *, int, struct cat_list *);
 
 /* List of categories */
 struct cat_list *Vect_new_cat_list(void);

Modified: grass/trunk/lib/vector/Vlib/cats.c
===================================================================
--- grass/trunk/lib/vector/Vlib/cats.c	2012-11-23 18:18:26 UTC (rev 53996)
+++ grass/trunk/lib/vector/Vlib/cats.c	2012-11-23 19:31:30 UTC (rev 53997)
@@ -5,20 +5,21 @@
  *
  * Higher level functions for reading/writing/manipulating vectors.
  *
- * (C) 2001-2009 by the GRASS Development Team
+ * (C) 2001-2012 by the GRASS Development Team
  *
  * This program is free software under the GNU General Public License
  * (>=v2).  Read the file COPYING that comes with GRASS for details.
  *
- * \author Original author CERL, probably Dave Gerdes or Mike
- * Higgins
+ * \author Original author CERL, probably Dave Gerdes or Mike Higgins
  * \author Update to GRASS 5.7 Radim Blazek and David D. Gray.
  * \author Various updates by Martin Landa <landa.martin gmail.com>
+ * \author Various updates by Markus Metz
  */
 
 #include <stdlib.h>
 #include <string.h>
 #include <grass/vector.h>
+#include <grass/dbmi.h>
 #include <grass/glocale.h>
 
 static int cmp(const void *pa, const void *pb);
@@ -91,7 +92,7 @@
    \brief Add new field/cat to category structure if doesn't exist
    yet.
 
-   \param[in] Cats line_cats structure
+   \param[in,out] Cats line_cats structure
    \param[in] field layer number
    \param[in] cat category number
 
@@ -156,17 +157,15 @@
 {
     int n, ret;
 
-    /* check input value */
-    /*
-      if (field < 1 || field > GV_FIELD_MAX)
-      return (0);
-    */
-    
     /* field was not found */    
     ret = 0;
     if (cat)
 	*cat = -1;
     
+    /* check input value */
+    if (field < 1 || field > GV_FIELD_MAX)
+	return (0);
+
     /* go through cats and find if field exist */
     for (n = 0; n < Cats->n_cats; n++) {
 	if (Cats->field[n] == field) {
@@ -302,8 +301,8 @@
 /*!
    \brief Allocate memory for cat_list structure.
 
-   \return poiter to allocated structure
-   \return NULL on out of memory
+   \return pointer to allocated structure
+   \return NULL if out of memory
  */
 struct cat_list *Vect_new_cat_list()
 {
@@ -354,18 +353,18 @@
    \code
    ...
    str = "2,3,5-9,20"
-   catList = Vect_new_cat_list()
+   cat_list = Vect_new_cat_list()
 
-   Vect_str_to_cat_list(str, catList)
+   Vect_str_to_cat_list(str, cat_list)
    \endcode
    \verbatim
-   catList.field = 0
-   catList.n_ranges = 4
-   catList.min = {2, 3, 5, 20}
-   catList.max = {2, 3, 9, 20}\endverbatim
+   cat_list->field = 0
+   cat_list->n_ranges = 4
+   cat_list->min = {2, 3, 5, 20}
+   cat_list->max = {2, 3, 9, 20}\endverbatim
 
    \param[in] str category list as a string
-   \param[out] list result cat_list structure
+   \param[in,out] list pointer to cat_list structure
 
    \return number of errors in ranges
  */
@@ -442,7 +441,7 @@
 
    \param vals array of integers
    \param nvals number of values
-   \param[out] list result cat_list structure
+   \param[in,out] list pointer to cat_list structure
 
    \return number of ranges
  */
@@ -484,7 +483,7 @@
    \param list cat_list structure
 
    \return TRUE if cat is in list
-   \return FALSE if it is not
+   \return FALSE if not
  */
 int Vect_cat_in_cat_list(int cat, const struct cat_list *list)
 {
@@ -498,6 +497,141 @@
 }
 
 /*!
+   \brief Set category constraints using 'where' or 'cats' option and layer number.
+
+   \param Map pointer to Map_info structure
+   \param layer layer number
+   \param where where statement
+   \param catstr category list as string
+
+   \return pointer to cat_list structure or NULL
+ */
+struct cat_list *Vect_cats_set_constraint(struct Map_info *Map, int layer,
+                                         char *where, char *catstr)
+{
+    struct cat_list *list = NULL;
+    int ret;
+
+    if (layer < 1) {
+	G_warning(_("Layer number must be > 0 for category constraints"));
+	/* no valid constraints, all categories qualify */
+	return list;
+    }
+
+    /* where has precedence over cats */
+    if (where) {
+	struct field_info *Fi = NULL;
+	dbDriver *driver = NULL;
+	int ncats, *cats = NULL;
+	int i, j;
+
+	if (catstr)
+	    G_warning(_("'%s' and '%s' parameters were supplied, cats will be ignored"), "where", "cats");
+
+	Fi = Vect_get_field(Map, layer);
+	if (!Fi) {
+	    G_fatal_error(_("Database connection not defined for layer %d"),
+			  layer);
+	}
+
+	G_verbose_message(_("Loading categories from table <%s>..."), Fi->table);
+
+	driver = db_start_driver_open_database(Fi->driver, Fi->database);
+	if (driver == NULL)
+	    G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
+			  Fi->database, Fi->driver);
+	
+	ncats = db_select_int(driver, Fi->table, Fi->key, where,
+			      &cats);
+	if (ncats == -1)
+		G_fatal_error(_("Unable select records from table <%s>"),
+			      Fi->table);
+	G_verbose_message(_("%d categories loaded"), ncats);
+	    
+	db_close_database_shutdown_driver(driver);
+
+	/* sort */
+	qsort(cats, ncats, sizeof(int), cmp);
+	
+	/* remove duplicates */
+	j = 1;
+	for (i = 1; i < ncats; i++) {
+	    if (cats[i] != cats[j - 1]) {
+		cats[j] = cats[i];
+		j++;
+	    }
+	}
+	ncats = j;
+	
+	/* convert to cat list */
+	list = Vect_new_cat_list();
+	
+	ret = Vect_array_to_cat_list(cats, ncats, list);
+	if (ret > 0)
+	    G_warning(_("%d errors in '%s' option"), ret, "where");
+	
+	if (cats)
+	    G_free(cats);
+    }
+    else if (catstr) {
+	list = Vect_new_cat_list();
+
+	ret = Vect_str_to_cat_list(catstr, list);
+	if (ret > 0)
+	    G_warning(_("%d errors in '%s' option"), ret, "cats");
+    }
+    
+    if (list) {
+	if (list->n_ranges < 1) {
+	    Vect_destroy_cat_list(list);
+	    list = NULL;
+	}
+    }
+	
+    return list;
+}
+
+/*!
+   \brief Check if categories match with category constraints.
+
+   \param Cats line_cats structure
+   \param layer layer number
+   \param list cat_list structure
+
+   \return 0 no match, categories are outside constraints
+   \return 1 match, categories are inside constraints
+ */
+int Vect_cats_in_constraint(struct line_cats *Cats, int layer,
+			      struct cat_list *list)
+{
+    int i;
+
+    if (layer < 1) {
+	G_warning(_("Layer number must be > 0 for category constraints"));
+	/* no valid constraint, all categories qualify */
+	return 1;
+    }
+
+    if (list) {
+	for (i = 0; i < Cats->n_cats; i++) {
+	    if (Cats->field[i] == layer &&
+		Vect_cat_in_cat_list(Cats->cat[i], list)) {
+		return 1;
+	    }
+	}
+	return 0;
+    }
+
+    for (i = 0; i < Cats->n_cats; i++) {
+	if (Cats->field[i] == layer)
+	    return 1;
+    }
+	
+    return 0;
+}
+
+
+/*!
    \brief Check if category is in ordered array of integers.
 
    \param cat category number



More information about the grass-commit mailing list