[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