GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
array.c
Go to the documentation of this file.
1 
20 #include <stdlib.h>
21 #include <grass/gis.h>
22 #include <grass/dbmi.h>
23 #include <grass/Vect.h>
24 #include <grass/glocale.h>
25 
26 
27 /* function prototypes */
28 static int cmp(const void *pa, const void *pb);
29 static int in_array(int *cats, size_t ncats, int cat);
30 
31 
44 VARRAY *Vect_new_varray(int size)
45 {
46  VARRAY *p;
47 
48  p = (VARRAY *) G_malloc(sizeof(VARRAY));
49 
50  if (p == NULL)
51  return NULL;
52 
53  p->size = size;
54  p->c = (int *)G_calloc(sizeof(char) * size + 1, sizeof(int));
55 
56  if (p->c == NULL) {
57  G_free(p);
58  return NULL;
59  }
60 
61  return p;
62 }
63 
84 int
85 Vect_set_varray_from_cat_string(struct Map_info *Map, int field,
86  const char *cstring, int type, int value,
87  VARRAY * varray)
88 {
89  int ret;
90  struct cat_list *Clist;
91 
92  G_debug(4, "Vect_set_varray_from_cat_string(): cstring = '%s'", cstring);
93 
94  Clist = Vect_new_cat_list();
95 
96  ret = Vect_str_to_cat_list(cstring, Clist);
97 
98  if (ret > 0)
99  G_warning(_("%d errors in category string."), ret);
100 
101  G_debug(4, " %d ranges in clist", Clist->n_ranges);
102 
103  ret =
104  Vect_set_varray_from_cat_list(Map, field, Clist, type, value, varray);
105 
106  Vect_destroy_cat_list(Clist);
107 
108  return ret;
109 }
110 
131 int
132 Vect_set_varray_from_cat_list(struct Map_info *Map, int field,
133  struct cat_list *clist, int type, int value,
134  VARRAY * varray)
135 {
136  int i, n, centr, cat;
137  int ni = 0; /* number of items set */
138  int ltype; /* line type */
139  struct line_cats *Cats;
140 
141  G_debug(4, "Vect_set_varray_from_cat_list(): field = %d", field);
142 
143  /* Check type */
144  if ((type & GV_AREA) && (type & (GV_POINTS | GV_LINES))) {
145  G_warning(_("Mixed area and other type requested for vector array"));
146  return 0;
147  }
148 
149  Cats = Vect_new_cats_struct();
150 
151  if (type & GV_AREA) { /* Areas */
152  n = Vect_get_num_areas(Map);
153 
154  if (n > varray->size) { /* not enough space */
155  G_warning(_("Not enough space in vector array"));
156  return 0;
157  }
158 
159  for (i = 1; i <= n; i++) {
160  centr = Vect_get_area_centroid(Map, i);
161  if (centr <= 0)
162  continue; /* No centroid */
163 
164  Vect_read_line(Map, NULL, Cats, centr);
165  if (!Vect_cat_get(Cats, field, &cat))
166  continue; /* No such field */
167 
168  if (Vect_cat_in_cat_list(cat, clist)) { /* cat is in list */
169  varray->c[i] = value;
170  ni++;
171  }
172  }
173  }
174  else { /* Lines */
175  n = Vect_get_num_lines(Map);
176 
177  if (n > varray->size) { /* not enough space */
178  G_warning(_("Not enough space in vector array"));
179  return 0;
180  }
181 
182  for (i = 1; i <= n; i++) {
183  ltype = Vect_read_line(Map, NULL, Cats, i);
184 
185  if (!(ltype & type))
186  continue; /* is not specified type */
187 
188  if (!Vect_cat_get(Cats, field, &cat))
189  continue; /* No such field */
190 
191  if (Vect_cat_in_cat_list(cat, clist)) { /* cat is in list */
192  varray->c[i] = value;
193  ni++;
194  }
195  }
196 
197  }
198 
200 
201  return ni;
202 }
203 
204 /* compare 2 integers in array */
205 static int cmp(const void *pa, const void *pb)
206 {
207  int *p1 = (int *)pa;
208  int *p2 = (int *)pb;
209 
210  if (*p1 < *p2)
211  return -1;
212  if (*p1 > *p2)
213  return 1;
214  return 0;
215 }
216 
217 /* check if cat is in array */
218 static int in_array(int *cats, size_t ncats, int cat)
219 {
220  int *p;
221 
222  p = (int *)bsearch((void *)&cat, cats, ncats, sizeof(int), cmp);
223 
224  if (p == NULL)
225  return 0;
226 
227  return 1;
228 }
229 
250 int
251 Vect_set_varray_from_db(struct Map_info *Map, int field, const char *where,
252  int type, int value, VARRAY * varray)
253 {
254  int i, n, c, centr, cat, *cats;
255  int ncats;
256  int ni = 0; /* number of items set */
257  int ltype; /* line type */
258  struct line_cats *Cats;
259  struct field_info *Fi;
260  dbDriver *driver;
261 
262  G_debug(4, "Vect_set_varray_from_db(): field = %d where = '%s'", field,
263  where);
264 
265  /* Note: use category index once available */
266 
267  /* Check type */
268  if ((type & GV_AREA) && (type & (GV_POINTS | GV_LINES))) {
269  G_warning(_("Mixed area and other type requested for vector array"));
270  return 0;
271  }
272 
273  Cats = Vect_new_cats_struct();
274 
275  /* Select categories from DB to array */
276  Fi = Vect_get_field(Map, field);
277  if (Fi == NULL) {
278  G_warning(_("Database connection not defined for layer %d"), field);
279  return -1;
280  }
281 
282  driver = db_start_driver_open_database(Fi->driver, Fi->database);
283  if (driver == NULL) {
284  G_warning(_("Unable to open database <%s> by driver <%s>"),
285  Fi->database, Fi->driver);
286  return -1;
287  }
288 
289  ncats = db_select_int(driver, Fi->table, Fi->key, where, &cats);
290 
292 
293  if (ncats == -1) {
294  G_warning(_("Unable to select record from table <%s> (key %s, where %s)"),
295  Fi->table, Fi->key, where);
296  return -1;
297  }
298 
299  if (type & GV_AREA) { /* Areas */
300  n = Vect_get_num_areas(Map);
301 
302  /* IMHO varray should be allocated only when it's required AND only as large as required
303  as WHERE will create a small subset of all vector features and thus on large datasets
304  it's waste of memory to allocate it for all features. */
305  if (n > varray->size) { /* not enough space */
306  G_warning(_("Not enough space in vector array"));
307  return 0;
308  }
309 
310  for (i = 1; i <= n; i++) {
311  centr = Vect_get_area_centroid(Map, i);
312  if (centr <= 0)
313  continue; /* No centroid */
314 
315  Vect_read_line(Map, NULL, Cats, centr);
316  /*if ( !Vect_cat_get(Cats, field, &cat) ) continue; No such field */
317  for (c = 0; c < Cats->n_cats; c++) {
318  if (Cats->field[c] == field &&
319  in_array(cats, ncats, Cats->cat[c])) {
320  cat = Cats->cat[c];
321  varray->c[i] = value;
322  ni++;
323  break;
324  }
325  }
326 
327  /*
328  if ( in_array ( cats, ncats, cat ) ) {
329  varray->c[i] = value;
330  ni++;
331  }
332  */
333  }
334  }
335  else { /* Lines */
336  n = Vect_get_num_lines(Map);
337 
338  if (n > varray->size) { /* not enough space */
339  G_warning(_("Not enough space in vector array"));
340  return 0;
341  }
342 
343  for (i = 1; i <= n; i++) {
344  ltype = Vect_read_line(Map, NULL, Cats, i);
345 
346  if (!(ltype & type))
347  continue; /* is not specified type */
348 
349  /* if ( !Vect_cat_get(Cats, field, &cat) ) continue; No such field */
350  for (c = 0; c < Cats->n_cats; c++) {
351  if (Cats->field[c] == field &&
352  in_array(cats, ncats, Cats->cat[c])) {
353  cat = Cats->cat[c];
354  varray->c[i] = value;
355  ni++;
356  break;
357  }
358  }
359  /*
360  if ( in_array ( cats, ncats, cat ) ) {
361  varray->c[i] = value;
362  ni++;
363  }
364  */
365  }
366 
367  }
368 
369  G_free(cats);
371 
372  return ni;
373 }
dbDriver * db_start_driver_open_database(const char *drvname, const char *dbname)
Open driver/database connection.
Definition: db.c:28
struct driver * driver
Definition: driver/init.c:26
void G_free(void *buf)
Free allocated memory.
Definition: gis/alloc.c:142
int Vect_get_area_centroid(struct Map_info *Map, int area)
Returns centroid number of area.
struct field_info * Vect_get_field(struct Map_info *Map, int field)
Get information about link to database.
Definition: field.c:404
int Vect_set_varray_from_db(struct Map_info *Map, int field, const char *where, int type, int value, VARRAY *varray)
Set values in &#39;varray&#39; to &#39;value&#39;.
Definition: array.c:251
int Vect_destroy_cat_list(struct cat_list *p)
Frees allocated cat_list memory.
int db_close_database_shutdown_driver(dbDriver *driver)
Close driver/database connection.
Definition: db.c:62
int Vect_set_varray_from_cat_list(struct Map_info *Map, int field, struct cat_list *clist, int type, int value, VARRAY *varray)
Set values in &#39;varray&#39; to &#39;value&#39;.
Definition: array.c:132
int Vect_get_num_areas(struct Map_info *map)
Get number of areas in vector map.
Definition: level_two.c:81
int db_select_int(dbDriver *driver, const char *tab, const char *col, const char *where, int **pval)
Select array of ordered integers from table/column.
int Vect_cat_in_cat_list(int cat, struct cat_list *list)
Check if category number is in list.
tuple size
value.Bind(wx.EVT_TEXT, self.OnVolumeIsosurfMap)
Definition: tools.py:2334
int Vect_set_varray_from_cat_string(struct Map_info *Map, int field, const char *cstring, int type, int value, VARRAY *varray)
Set values in &#39;varray&#39; to &#39;value&#39;.
Definition: array.c:85
struct cat_list * Vect_new_cat_list()
Allocate memory for cat_list structure.
VARRAY * Vect_new_varray(int size)
Create new VARRAY and allocate space for given number of items.
Definition: array.c:44
int GV_LINES
Definition: vdigit/main.py:24
int Vect_destroy_cats_struct(struct line_cats *p)
Frees all memory associated with line_cats structure, including the struct itself.
int
Definition: g3dcolor.c:48
char * value
Definition: env.c:30
struct line_cats * Vect_new_cats_struct()
Creates and initializes line_cats structure.
return NULL
Definition: dbfopen.c:1394
G_warning("category support for [%s] in mapset [%s] %s", name, mapset, type)
int Vect_get_num_lines(struct Map_info *map)
Fetch number of features (points, lines, boundaries, centroids) in vector map.
Definition: level_two.c:69
tuple Map
Definition: render.py:1310
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: gis/debug.c:51
int Vect_str_to_cat_list(const char *str, struct cat_list *list)
Convert string of categories and cat ranges separated by commas to cat_list.
CELL cat
Definition: g3dcats.c:90
int n
Definition: dataquad.c:291
int Vect_read_line(struct Map_info *Map, struct line_pnts *line_p, struct line_cats *line_c, int line)
Read vector feature.
int Vect_cat_get(struct line_cats *Cats, int field, int *cat)
Get first found category of given field.