00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <stdlib.h>
00017 #include <grass/gis.h>
00018 #include <grass/dbmi.h>
00019 #include <grass/Vect.h>
00020
00021
00022
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;
00112 int ltype;
00113 struct line_cats *Cats;
00114
00115 G_debug (4, "Vect_set_varray_from_cat_list(): field = %d", field);
00116
00117
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 ) {
00126 n = Vect_get_num_areas (Map);
00127
00128 if ( n > varray->size ) {
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;
00136
00137 Vect_read_line (Map, NULL, Cats, centr);
00138 if ( !Vect_cat_get(Cats, field, &cat) ) continue;
00139
00140 if ( Vect_cat_in_cat_list (cat, clist) ) {
00141 varray->c[i] = value;
00142 ni++;
00143 }
00144 }
00145 } else {
00146 n = Vect_get_num_lines (Map);
00147
00148 if ( n > varray->size ) {
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;
00157
00158 if ( !Vect_cat_get(Cats, field, &cat) ) continue;
00159
00160 if ( Vect_cat_in_cat_list (cat, clist) ) {
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
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
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;
00216 int ltype;
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
00224
00225
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
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 ) {
00256 n = Vect_get_num_areas (Map);
00257
00258 if ( n > varray->size ) {
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;
00266
00267 Vect_read_line (Map, NULL, Cats, centr);
00268
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
00280
00281
00282
00283
00284 }
00285 } else {
00286 n = Vect_get_num_lines (Map);
00287
00288 if ( n > varray->size ) {
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;
00297
00298
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
00309
00310
00311
00312
00313 }
00314
00315 }
00316
00317 G_free ( cats );
00318 Vect_destroy_cats_struct (Cats);
00319
00320 return ni;
00321 }
00322