array.c

Go to the documentation of this file.
00001 /*****************************************************************************
00002 *
00003 * MODULE:       Vector library 
00004 *               
00005 * AUTHOR(S):    Radim Blazek
00006 *
00007 * PURPOSE:      Higher level functions for reading/writing/manipulating vectors.
00008 *
00009 * COPYRIGHT:    (C) 2001 by the GRASS Development Team
00010 *
00011 *               This program is free software under the GNU General Public
00012 *               License (>=v2). Read the file COPYING that comes with GRASS
00013 *               for details.
00014 *
00015 *****************************************************************************/
00016 #include <stdlib.h>
00017 #include <grass/gis.h>
00018 #include <grass/dbmi.h>
00019 #include <grass/Vect.h>
00020 
00021 
00022 /* function prototypes */
00023 static int cmp(const void *pa, const void *pb);
00024 static int in_array(int *cats, size_t ncats, int cat);
00025 
00026 
00036 VARRAY *
00037 Vect_new_varray (int size)
00038 {
00039     VARRAY *p;
00040 
00041     p = (VARRAY *) G_malloc (sizeof (VARRAY));
00042  
00043     if ( p == NULL ) return NULL;
00044   
00045     p->size = size;
00046     p->c = (int *) G_calloc(sizeof(char)*size + 1, sizeof(int));
00047     
00048     if ( p->c == NULL ) {
00049         G_free (p);
00050         return NULL;
00051     }
00052   
00053     return p;
00054 }
00055 
00069 int 
00070 Vect_set_varray_from_cat_string ( struct Map_info *Map, int field, char *cstring,
00071                                 int type, int value, VARRAY *varray )
00072 {
00073     int ret;
00074     struct cat_list *Clist;
00075     
00076     G_debug (4, "Vect_set_varray_from_cat_string(): cstring = '%s'", cstring);
00077 
00078     Clist = Vect_new_cat_list ();
00079         
00080     ret = Vect_str_to_cat_list ( cstring, Clist);
00081 
00082     if ( ret > 0 ) G_warning ( "%d errors in category string.", ret);
00083     
00084     G_debug (4, "  %d ranges in clist", Clist->n_ranges);
00085 
00086     ret = Vect_set_varray_from_cat_list ( Map, field, Clist, type, value, varray );
00087     
00088     Vect_destroy_cat_list (Clist);
00089 
00090     return ret;
00091 }
00092 
00106 int 
00107 Vect_set_varray_from_cat_list ( struct Map_info *Map, int field, struct cat_list *clist,
00108                                 int type, int value, VARRAY *varray )
00109 {
00110     int i, n, centr, cat;
00111     int ni = 0; /* number of items set */
00112     int ltype; /* line type */
00113     struct line_cats *Cats;
00114 
00115     G_debug (4, "Vect_set_varray_from_cat_list(): field = %d", field);
00116     
00117     /* Check type */
00118     if ( (type & GV_AREA) && (type & (GV_POINTS | GV_LINES)) ) {
00119         G_warning ("Mixed area and other type requested for vector array.");
00120         return 0;
00121     }
00122     
00123     Cats = Vect_new_cats_struct ();
00124     
00125     if ( type & GV_AREA ) { /* Areas */
00126         n = Vect_get_num_areas (Map);
00127         
00128         if ( n > varray->size ) { /* not enough space */
00129             G_warning ("Not enough space in vector array.");
00130             return 0;
00131         }
00132             
00133         for ( i = 1; i <= n; i++ ) {
00134             centr = Vect_get_area_centroid ( Map, i );
00135             if ( centr <= 0 ) continue; /* No centroid */
00136             
00137             Vect_read_line (Map, NULL, Cats, centr);
00138             if ( !Vect_cat_get(Cats, field, &cat) ) continue; /* No such field */
00139             
00140             if ( Vect_cat_in_cat_list (cat, clist) ) { /* cat is in list */
00141                 varray->c[i] = value;
00142                 ni++;
00143             }
00144         }
00145     } else { /* Lines */
00146         n = Vect_get_num_lines (Map);
00147         
00148         if ( n > varray->size ) { /* not enough space */
00149             G_warning ("Not enough space in vector array.");
00150             return 0;
00151         }
00152             
00153         for ( i = 1; i <= n; i++ ) {
00154             ltype = Vect_read_line (Map, NULL, Cats, i);
00155         
00156             if ( !(ltype & type) ) continue; /* is not specified type */
00157             
00158             if ( !Vect_cat_get(Cats, field, &cat) ) continue; /* No such field */
00159 
00160             if ( Vect_cat_in_cat_list (cat, clist) ) { /* cat is in list */
00161                 varray->c[i] = value;
00162                 ni++;
00163             }
00164         }
00165 
00166     }
00167 
00168     Vect_destroy_cats_struct (Cats);
00169 
00170     return ni;
00171 }
00172 
00173 /* compare 2 integers in array */
00174 static int cmp ( const void *pa, const void *pb)
00175 {
00176     int *p1 = (int *) pa;
00177     int *p2 = (int *) pb;
00178              
00179     if( *p1 < *p2 ) return -1;
00180     if( *p1 > *p2 ) return 1;
00181     return 0;
00182 }
00183 
00184 /* check if cat is in array */
00185 static int in_array (int *cats, size_t ncats, int cat)
00186 {
00187     int *p;
00188     
00189     p = (int *) bsearch((void *) &cat, cats, ncats, sizeof(int), cmp); 
00190 
00191     if ( p == NULL ) return 0;
00192 
00193     return 1;
00194 }
00195 
00209 int 
00210 Vect_set_varray_from_db ( struct Map_info *Map, int field, char *where,
00211                                 int type, int value, VARRAY *varray )
00212 {
00213     int i, n, c, centr, cat, *cats;
00214     size_t ncats;
00215     int ni = 0; /* number of items set */
00216     int ltype; /* line type */
00217     struct line_cats *Cats;
00218     struct field_info *Fi;
00219     dbDriver *driver;
00220 
00221     G_debug (4, "Vect_set_varray_from_db(): field = %d where = '%s'", field, where);
00222 
00223     /* Note: use category index once available */
00224     
00225     /* Check type */
00226     if ( (type & GV_AREA) && (type & (GV_POINTS | GV_LINES)) ) {
00227         G_warning ("Mixed area and other type requested for vector array.");
00228         return 0;
00229     }
00230     
00231     Cats = Vect_new_cats_struct ();
00232 
00233     /* Select categories from DB to array */
00234     Fi = Vect_get_field ( Map, field);
00235     if ( Fi == NULL ) {
00236         G_warning ( "Cannot get field info" );
00237         return -1;
00238     }
00239     
00240     driver = db_start_driver_open_database ( Fi->driver, Fi->database );
00241     if ( driver == NULL ) {
00242         G_warning ( "Cannot open database" );
00243         return -1;
00244     }
00245         
00246     ncats = db_select_int( driver, Fi->table, Fi->key, where, &cats);
00247 
00248     db_close_database_shutdown_driver ( driver );
00249 
00250     if(ncats == -1) {
00251         G_warning("Could not select from table/column");
00252         return -1;
00253     }
00254 
00255     if ( type & GV_AREA ) { /* Areas */
00256         n = Vect_get_num_areas (Map);
00257         
00258         if ( n > varray->size ) { /* not enough space */
00259             G_warning ("Not enough space in vector array.");
00260             return 0;
00261         }
00262             
00263         for ( i = 1; i <= n; i++ ) {
00264             centr = Vect_get_area_centroid ( Map, i );
00265             if ( centr <= 0 ) continue; /* No centroid */
00266             
00267             Vect_read_line (Map, NULL, Cats, centr);
00268             /*if ( !Vect_cat_get(Cats, field, &cat) ) continue; No such field */
00269             for (c = 0; c < Cats->n_cats; c++) {
00270               if (Cats->field[c] == field && in_array ( cats, ncats, Cats->cat[c] )) {
00271                 cat = Cats->cat[c];
00272                 varray->c[i] = value;
00273                 ni++;
00274                 break;
00275               }
00276             }
00277 
00278             /*
00279             if ( in_array ( cats, ncats, cat ) ) {
00280                 varray->c[i] = value;
00281                 ni++;
00282             }
00283             */
00284         }
00285     } else { /* Lines */
00286         n = Vect_get_num_lines (Map);
00287         
00288         if ( n > varray->size ) { /* not enough space */
00289             G_warning ("Not enough space in vector array.");
00290             return 0;
00291         }
00292             
00293         for ( i = 1; i <= n; i++ ) {
00294             ltype = Vect_read_line (Map, NULL, Cats, i);
00295         
00296             if ( !(ltype & type) ) continue; /* is not specified type */
00297             
00298             /* if ( !Vect_cat_get(Cats, field, &cat) ) continue;  No such field */
00299             for (c = 0; c < Cats->n_cats; c++) {
00300               if (Cats->field[c] == field && in_array ( cats, ncats, Cats->cat[c] )) {
00301                 cat = Cats->cat[c];
00302                 varray->c[i] = value;
00303                 ni++;
00304                 break;
00305               }
00306             }
00307             /*
00308             if ( in_array ( cats, ncats, cat ) ) {
00309                 varray->c[i] = value;
00310                 ni++;
00311             }
00312             */
00313         }
00314 
00315     }
00316 
00317     G_free ( cats );
00318     Vect_destroy_cats_struct (Cats);
00319 
00320     return ni;
00321 }
00322 

Generated on Sun Apr 6 17:32:44 2008 for GRASS by  doxygen 1.5.5