00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <stdlib.h>
00017 #include "gis.h"
00018 #include "dbmi.h"
00019 #include "Vect.h"
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 VARRAY *
00030 Vect_new_varray (int size)
00031 {
00032 VARRAY *p;
00033
00034 p = (VARRAY *) G_malloc (sizeof (VARRAY));
00035
00036 if ( p == NULL ) return NULL;
00037
00038 p->size = size;
00039 p->c = (int *) G_calloc ( size + 1, sizeof(int) );
00040
00041 if ( p->c == NULL ) {
00042 G_free (p);
00043 return NULL;
00044 }
00045
00046 return p;
00047 }
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 int
00061 Vect_set_varray_from_cat_string ( struct Map_info *Map, int field, char *cstring,
00062 int type, int value, VARRAY *varray )
00063 {
00064 int ret;
00065 struct cat_list *Clist;
00066
00067 G_debug (4, "Vect_set_varray_from_cat_string(): cstring = '%s'", cstring);
00068
00069 Clist = Vect_new_cat_list ();
00070
00071 ret = Vect_str_to_cat_list ( cstring, Clist);
00072
00073 if ( ret > 0 ) G_warning ( "%d errors in category string.", ret);
00074
00075 G_debug (4, " %d ranges in clist", Clist->n_ranges);
00076
00077 ret = Vect_set_varray_from_cat_list ( Map, field, Clist, type, value, varray );
00078
00079 Vect_destroy_cat_list (Clist);
00080
00081 return ret;
00082 }
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 int
00095 Vect_set_varray_from_cat_list ( struct Map_info *Map, int field, struct cat_list *clist,
00096 int type, int value, VARRAY *varray )
00097 {
00098 int i, n, centr, cat;
00099 int ni = 0;
00100 int ltype;
00101 struct line_cats *Cats;
00102
00103 G_debug (4, "Vect_set_varray_from_cat_list(): field = %d", field);
00104
00105
00106 if ( (type & GV_AREA) && (type & (GV_POINTS | GV_LINES)) ) {
00107 G_warning ("Mixed area and other type requested for vector array.");
00108 return 0;
00109 }
00110
00111 Cats = Vect_new_cats_struct ();
00112
00113 if ( type & GV_AREA ) {
00114 n = Vect_get_num_areas (Map);
00115
00116 if ( n > varray->size ) {
00117 G_warning ("Not enough space in vector array.");
00118 return 0;
00119 }
00120
00121 for ( i = 1; i <= n; i++ ) {
00122 centr = Vect_get_area_centroid ( Map, i );
00123 if ( centr <= 0 ) continue;
00124
00125 Vect_read_line (Map, NULL, Cats, centr);
00126 if ( !Vect_cat_get(Cats, field, &cat) ) continue;
00127
00128 if ( Vect_cat_in_cat_list (cat, clist) ) {
00129 varray->c[i] = value;
00130 ni++;
00131 }
00132 }
00133 } else {
00134 n = Vect_get_num_lines (Map);
00135
00136 if ( n > varray->size ) {
00137 G_warning ("Not enough space in vector array.");
00138 return 0;
00139 }
00140
00141 for ( i = 1; i <= n; i++ ) {
00142 ltype = Vect_read_line (Map, NULL, Cats, i);
00143
00144 if ( !(ltype & type) ) continue;
00145
00146 if ( !Vect_cat_get(Cats, field, &cat) ) continue;
00147
00148 if ( Vect_cat_in_cat_list (cat, clist) ) {
00149 varray->c[i] = value;
00150 ni++;
00151 }
00152 }
00153
00154 }
00155
00156 Vect_destroy_cats_struct (Cats);
00157
00158 return ni;
00159 }
00160
00161
00162 int cmp ( const void *pa, const void *pb)
00163 {
00164 int *p1 = (int *) pa;
00165 int *p2 = (int *) pb;
00166
00167 if( *p1 < *p2 ) return -1;
00168 if( *p1 > *p2 ) return 1;
00169 return 0;
00170 }
00171
00172
00173 int
00174 in_array ( int *cats, int ncats, int cat )
00175 {
00176 int *p;
00177
00178 p = (int *) bsearch((void *) &cat, cats, ncats, sizeof(int), cmp);
00179
00180 if ( p == NULL ) return 0;
00181 return 1;
00182 }
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 int
00196 Vect_set_varray_from_db ( struct Map_info *Map, int field, char *where,
00197 int type, int value, VARRAY *varray )
00198 {
00199 int i, n, c, centr, cat, *cats, ncats;
00200 int ni = 0;
00201 int ltype;
00202 struct line_cats *Cats;
00203 struct field_info *Fi;
00204 dbDriver *driver;
00205
00206 G_debug (4, "Vect_set_varray_from_db(): field = %d where = '%s'", field, where);
00207
00208
00209
00210
00211 if ( (type & GV_AREA) && (type & (GV_POINTS | GV_LINES)) ) {
00212 G_warning ("Mixed area and other type requested for vector array.");
00213 return 0;
00214 }
00215
00216 Cats = Vect_new_cats_struct ();
00217
00218
00219 Fi = Vect_get_field ( Map, field);
00220 if ( Fi == NULL ) {
00221 G_warning ( "Cannot get field info" );
00222 return -1;
00223 }
00224
00225 driver = db_start_driver_open_database ( Fi->driver, Fi->database );
00226 if ( driver == NULL ) {
00227 G_warning ( "Cannot open database" );
00228 return -1;
00229 }
00230
00231 ncats = db_select_int( driver, Fi->table, Fi->key, where, &cats);
00232
00233 db_close_database_shutdown_driver ( driver );
00234
00235 if ( type & GV_AREA ) {
00236 n = Vect_get_num_areas (Map);
00237
00238 if ( n > varray->size ) {
00239 G_warning ("Not enough space in vector array.");
00240 return 0;
00241 }
00242
00243 for ( i = 1; i <= n; i++ ) {
00244 centr = Vect_get_area_centroid ( Map, i );
00245 if ( centr <= 0 ) continue;
00246
00247 Vect_read_line (Map, NULL, Cats, centr);
00248
00249 for (c = 0; c < Cats->n_cats; c++) {
00250 if (Cats->field[c] == field && in_array ( cats, ncats, Cats->cat[c] )) {
00251 cat = Cats->cat[c];
00252 varray->c[i] = value;
00253 ni++;
00254 break;
00255 }
00256 }
00257
00258
00259
00260
00261
00262
00263
00264 }
00265 } else {
00266 n = Vect_get_num_lines (Map);
00267
00268 if ( n > varray->size ) {
00269 G_warning ("Not enough space in vector array.");
00270 return 0;
00271 }
00272
00273 for ( i = 1; i <= n; i++ ) {
00274 ltype = Vect_read_line (Map, NULL, Cats, i);
00275
00276 if ( !(ltype & type) ) continue;
00277
00278
00279 for (c = 0; c < Cats->n_cats; c++) {
00280 if (Cats->field[c] == field && in_array ( cats, ncats, Cats->cat[c] )) {
00281 cat = Cats->cat[c];
00282 varray->c[i] = value;
00283 ni++;
00284 break;
00285 }
00286 }
00287
00288
00289
00290
00291
00292
00293 }
00294
00295 }
00296
00297 G_free ( cats );
00298 Vect_destroy_cats_struct (Cats);
00299
00300 return ni;
00301 }
00302