00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <stdlib.h>
00017 #include <string.h>
00018 #include <grass/gis.h>
00019 #include <grass/Vect.h>
00020
00021
00022
00023
00024
00025
00026
00027
00028 int
00029 dig_cidx_init ( struct Plus_head *Plus)
00030 {
00031 G_debug(3, "dig_cidx_init()");
00032
00033 Plus->n_cidx = 0;
00034 Plus->a_cidx = 5;
00035 Plus->cidx = (struct Cat_index*) G_malloc( Plus->a_cidx * sizeof( struct Cat_index ) );
00036 if (!Plus->cidx ) return 0;
00037 Plus->cidx_up_to_date = 0;
00038 return 1;
00039 }
00040
00041
00042 void
00043 dig_cidx_free ( struct Plus_head *Plus)
00044 {
00045 int i;
00046 struct Cat_index *ci;
00047
00048 G_debug(2, "dig_cidx_free()");
00049 for ( i = 0; i < Plus->n_cidx; i++ ) {
00050 ci = &(Plus->cidx[0]);
00051 free ( ci->cat);
00052 ci->cat = NULL;
00053 ci->field = ci->n_cats = ci->a_cats = ci->n_types = 0;
00054 }
00055 Plus->n_cidx = 0;
00056 Plus->cidx_up_to_date = 0;
00057 }
00058
00059
00060
00061
00062
00063
00064
00065
00066 int
00067 dig_cidx_add_cat ( struct Plus_head *Plus, int field, int cat, int line, int type)
00068 {
00069 int i, si, found;
00070 struct Cat_index *ci;
00071
00072 G_debug(3, "dig_cidx_add_cat(): field = %d cat = %d line = %d type = %d", field, cat, line, type);
00073
00074
00075 si = -1;
00076 for ( i = 0; i < Plus->n_cidx; i++ ) {
00077 if ( Plus->cidx[i].field == field ) {
00078 si = i;
00079 }
00080 }
00081 if ( si == -1 ) {
00082 if ( Plus->n_cidx == Plus->a_cidx ) {
00083 Plus->a_cidx += 10;
00084 Plus->cidx = (struct Cat_index*) G_realloc ( Plus->cidx, Plus->a_cidx * sizeof( struct Cat_index ) );
00085 if (!Plus->cidx) return 0;
00086 }
00087 si = Plus->n_cidx;
00088 ci = &(Plus->cidx[si]);
00089 ci->field = field;
00090 ci->n_cats = ci->a_cats = 0;
00091 ci->cat = NULL;
00092 ci->n_types = 0;
00093 ci->offset = 0;
00094 Plus->n_cidx++;
00095 }
00096
00097
00098 ci = &(Plus->cidx[si]);
00099 if ( ci->n_cats == ci->a_cats ) {
00100 ci->a_cats += 5000;
00101 ci->cat = G_realloc ( ci->cat, ci->a_cats * 3 * sizeof(int) );
00102 }
00103
00104 ci->cat[ci->n_cats][0] = cat;
00105 ci->cat[ci->n_cats][1] = type;
00106 ci->cat[ci->n_cats][2] = line;
00107 ci->n_cats++;
00108
00109
00110 found = 0;
00111 for ( i = 0; i < ci->n_types; i++ ) {
00112 if ( ci->type[i][0] == type ) {
00113 ci->type[i][1]++;
00114 found = 1;
00115 }
00116 }
00117 if ( ! found ) {
00118 ci->type[ci->n_types][0] = type;
00119 ci->type[ci->n_types][1] = 1;
00120 ci->n_types++;
00121 }
00122
00123 return 1;
00124 }
00125
00126
00127 static int cmp_cat ( const void *pa, const void *pb )
00128 {
00129 int *p1 = (int*) pa;
00130 int *p2 = (int*) pb;
00131
00132 if ( p1[0] < p2[0] ) return -1;
00133 if ( p1[0] > p2[0] ) return 1;
00134 return 0;
00135 }
00136
00137
00138 static int cmp_field ( const void *pa, const void *pb )
00139 {
00140 struct Cat_index *p1 = (struct Cat_index*) pa;
00141 struct Cat_index *p2 = (struct Cat_index*) pb;
00142
00143 if ( p1->field < p2->field ) return -1;
00144 if ( p1->field > p2->field ) return 1;
00145 return 0;
00146 }
00147
00148
00149
00150
00151
00152
00153
00154
00155 int
00156 dig_cidx_add_cat_sorted ( struct Plus_head *Plus, int field, int cat, int line, int type)
00157 {
00158 int i, si, found, position;
00159 struct Cat_index *ci;
00160
00161 G_debug(3, "dig_cidx_add_cat_sorted(): field = %d cat = %d line = %d type = %d", field, cat, line, type);
00162
00163
00164 si = -1;
00165 for ( i = 0; i < Plus->n_cidx; i++ ) {
00166 if ( Plus->cidx[i].field == field ) {
00167 si = i;
00168 }
00169 }
00170 if ( si == -1 ) {
00171 if ( Plus->n_cidx == Plus->a_cidx ) {
00172 Plus->a_cidx += 10;
00173 Plus->cidx = (struct Cat_index*) G_realloc ( Plus->cidx, Plus->a_cidx * sizeof( struct Cat_index ) );
00174 if (!Plus->cidx) return 0;
00175 }
00176 si = Plus->n_cidx;
00177 ci = &(Plus->cidx[si]);
00178 ci->field = field;
00179 ci->n_cats = ci->a_cats = 0;
00180 ci->cat = NULL;
00181 ci->n_types = 0;
00182 ci->offset = 0;
00183 Plus->n_cidx++;
00184 }
00185
00186
00187 ci = &(Plus->cidx[si]);
00188 if ( ci->n_cats == ci->a_cats ) {
00189 ci->a_cats += 5000;
00190 ci->cat = G_realloc ( ci->cat, ci->a_cats * 3 * sizeof(int) );
00191 }
00192
00193
00194 for ( position = 0; position < ci->n_cats; position++ ) {
00195 if ( ci->cat[position][0] >= cat ) {
00196 break;
00197 }
00198 }
00199
00200 G_debug (4, "position = %d", position );
00201
00202
00203 for ( i = ci->n_cats; i > position; i-- ) {
00204 ci->cat[i][0] = ci->cat[i-1][0];
00205 ci->cat[i][1] = ci->cat[i-1][1];
00206 ci->cat[i][2] = ci->cat[i-1][2];
00207 }
00208
00209 ci->cat[position][0] = cat;
00210 ci->cat[position][1] = type;
00211 ci->cat[position][2] = line;
00212 ci->n_cats++;
00213
00214
00215 found = 0;
00216 for ( i = 0; i < ci->n_types; i++ ) {
00217 if ( ci->type[i][0] == type ) {
00218 ci->type[i][1]++;
00219 found = 1;
00220 }
00221 }
00222 if ( ! found ) {
00223 ci->type[ci->n_types][0] = type;
00224 ci->type[ci->n_types][1] = 1;
00225 ci->n_types++;
00226 }
00227
00228
00229 qsort ( Plus->cidx, Plus->n_cidx, sizeof(struct Cat_index), cmp_field );
00230
00231 G_debug (3, "Added new category to index" );
00232
00233 return 1;
00234 }
00235
00236
00237
00238
00239
00240
00241
00242
00243 int
00244 dig_cidx_del_cat ( struct Plus_head *Plus, int field, int cat, int line, int type )
00245 {
00246 int i, position;
00247 struct Cat_index *ci;
00248
00249 G_debug(3, "dig_cidx_del_cat(): field = %d cat = %d line = %d", field, cat, line);
00250
00251
00252 ci = NULL;
00253 for ( i = 0; i < Plus->n_cidx; i++ ) {
00254 if ( Plus->cidx[i].field == field ) {
00255 ci = &(Plus->cidx[i]);
00256 }
00257 }
00258 if ( ci == NULL ) {
00259 G_warning ( "BUG: Category index not found for field %d.", field );
00260 return 0;
00261 }
00262
00263
00264 G_debug(3, "n_cats = %d", ci->n_cats );
00265 for ( position = 0; position < ci->n_cats; position++ ) {
00266 if ( ci->cat[position][0] == cat && ci->cat[position][1] == type && ci->cat[position][2] == line ) {
00267 break;
00268 }
00269 }
00270
00271 G_debug (4, "position = %d" );
00272
00273 if ( position == ci->n_cats ) {
00274 G_warning ( "BUG: Category not found in category index." );
00275 return 0;
00276 }
00277
00278
00279 for ( i = position; i < ci->n_cats-1; i++ ) {
00280 ci->cat[i][0] = ci->cat[i+1][0];
00281 ci->cat[i][1] = ci->cat[i+1][1];
00282 ci->cat[i][2] = ci->cat[i+1][2];
00283 }
00284
00285 ci->n_cats--;
00286
00287 for ( i = 0; i < ci->n_types; i++ ) {
00288 if ( ci->type[i][0] == type ) {
00289 ci->type[i][1]--;
00290 }
00291 }
00292
00293 G_debug (3, "Deleted from category index" );
00294 return 1;
00295 }
00296
00297
00298
00299
00300
00301
00302 void
00303 dig_cidx_sort ( struct Plus_head *Plus )
00304 {
00305 int f;
00306 struct Cat_index *ci;
00307
00308 G_debug(2, "dig_cidx_sort()" );
00309
00310 for ( f = 0; f < Plus->n_cidx; f++ ) {
00311 int c, nucats = 0;
00312
00313 ci = &(Plus->cidx[f]);
00314
00315
00316 qsort ( ci->cat, ci->n_cats, 3*sizeof(int), cmp_cat );
00317
00318
00319 if ( ci->n_cats > 0 ) nucats++;
00320 for ( c = 1; c < ci->n_cats; c++ ) {
00321 if ( ci->cat[c][0] != ci->cat[c-1][0] ) nucats++;
00322 }
00323 ci->n_ucats = nucats;
00324 }
00325
00326
00327 qsort ( Plus->cidx, Plus->n_cidx, sizeof(struct Cat_index), cmp_field );
00328 }
00329