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