00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <ctype.h>
00015 #include <string.h>
00016 #include <stdio.h>
00017 #include <stdlib.h>
00018 #include <errno.h>
00019 #include "gis.h"
00020 #include "site.h"
00021
00022 #define DQUOTE '"'
00023 #define SPACE ' '
00024 #define BSLASH 92
00025 #define PIPE '|'
00026
00027 #define ispipe(c) (c==PIPE)
00028 #define isnull(c) (c==(char)NULL)
00029 #define isquote(c) (c==DQUOTE)
00030 #define isbslash(c) (c==BSLASH)
00031
00032 static int format_double ( double , char *);
00033 char *next_att (char *);
00034
00035 void G_site_free_struct (Site *s)
00036
00037 {
00038 if(s->dim_alloc)
00039 G_free(s->dim);
00040 if(s->str_alloc)
00041 G_free(s->str_att);
00042 if(s->dbl_alloc)
00043 G_free(s->dbl_att);
00044 G_free(s);
00045
00046 return;
00047 }
00048
00049 Site *G_site_new_struct (RASTER_MAP_TYPE cattype,
00050 int n_dim,int n_s_att,int n_d_att)
00051
00052
00053
00054
00055 {
00056 int i;
00057 Site *s;
00058
00059 if (n_dim < 2 || n_s_att < 0 || n_d_att < 0)
00060 G_fatal_error ("G_oldsite_new_struct: invalid # dims or fields\n");
00061
00062 if ((s = (Site *) G_malloc (sizeof (Site))) == NULL)
00063 return (Site *) NULL;
00064
00065 s->cattype=cattype;
00066 s->ccat=s->fcat=s->dcat=0;
00067
00068 if (n_dim > 2)
00069 {
00070 if ((s->dim =
00071 (double *) G_malloc ((n_dim - 2) * sizeof (double))) == NULL) {
00072 G_free(s);
00073 return (Site *) NULL;
00074 }
00075 }
00076 s->dim_alloc = n_dim - 2;
00077
00078 if (n_d_att > 0)
00079 {
00080 if ((s->dbl_att =
00081 (double *) G_malloc (n_d_att * sizeof (double))) == NULL) {
00082 if (n_dim > 2) G_free(s->dim);
00083 G_free(s);
00084 return (Site *) NULL;
00085 }
00086 }
00087 s->dbl_alloc = n_d_att;
00088
00089 if (n_s_att > 0)
00090 {
00091 if ((s->str_att =
00092 (char **) G_malloc (n_s_att * sizeof (char *))) == NULL) {
00093 if (n_d_att > 0) G_free(s->dbl_att);
00094 if (n_dim > 2) G_free(s->dim);
00095 G_free(s);
00096 return (Site *) NULL;
00097 }
00098 else
00099 for (i = 0; i < n_s_att; ++i)
00100 if ((s->str_att[i] =
00101 (char *) G_malloc (MAX_SITE_STRING * sizeof (char))) == NULL) {
00102 while (--i) G_free(s->str_att[i]);
00103 G_free(s->str_att);
00104 if (n_d_att > 0) G_free(s->dbl_att);
00105 if (n_dim > 2) G_free(s->dim);
00106 G_free(s);
00107 return (Site *) NULL;
00108 }
00109 }
00110 s->str_alloc = n_s_att;
00111
00112 return s;
00113 }
00114
00115 #define FOUND_ALL(s,n,dim,c,d) (((s->cattype != -1 && !n) || \
00116 (dim < s->dim_alloc) || \
00117 (c < s->str_alloc) || \
00118 (d < s->dbl_alloc))?0:1)
00119
00120 int G_oldsite_get ( FILE *fptr, Site *s)
00121
00122 {
00123 return G__oldsite_get (fptr, s, G_projection() );
00124 }
00125
00126
00127 int G__oldsite_get ( FILE *ptr, Site *s, int fmt)
00128
00129
00130
00131
00132
00133
00134 {
00135 char sbuf[MAX_SITE_LEN], *buf, *last, *p1, *p2;
00136 char ebuf[128], nbuf[128];
00137 int n = 0, d = 0, c = 0, dim = 0, err = 0, tmp;
00138
00139 buf = sbuf;
00140
00141 if ((buf = fgets (sbuf, 1024, ptr)) == (char *) NULL)
00142 return EOF;
00143
00144 while ((*buf == '#' || !isdigit(*buf)) && *buf != '-' && *buf != '+')
00145 if ((buf = fgets (sbuf, 1024, ptr)) == (char *) NULL)
00146 return EOF;
00147
00148 if (buf[strlen (buf) - 1] == '\n')
00149 buf[strlen (buf) - 1] = (char) NULL;
00150
00151 if (sscanf (buf, "%[^|]|%[^|]|%*[^\n]", ebuf, nbuf) < 2)
00152 {
00153 fprintf (stderr, "ERROR: ebuf %s nbuf %s\n", ebuf, nbuf);
00154 return -2;
00155 }
00156
00157 if (!G_scan_northing (nbuf, &(s->north), fmt) ||
00158 !G_scan_easting (ebuf, &(s->east), fmt))
00159 {
00160 fprintf (stderr, "ERROR: ebuf %s nbuf %s\n", ebuf, nbuf);
00161 return -2;
00162 }
00163
00164
00165 if (NULL == (buf = G_index(buf, PIPE)))
00166 return -2;
00167 if (NULL == (buf = G_index(buf+1, PIPE)))
00168 return -2;
00169
00170
00171 do {
00172 buf++;
00173 if (isnull(*buf)) return (FOUND_ALL(s,n,dim,c,d)? 0: -2);
00174 last = buf;
00175 if (dim < s->dim_alloc)
00176 {
00177 if (sscanf (buf, "%lf|", &(s->dim[dim++])) < 1)
00178 return -2;
00179 }
00180 else if (NULL != (p1 = G_index(buf, PIPE)))
00181 {
00182 if (NULL == (p2 = G_index(buf, DQUOTE)))
00183 err = 1;
00184 else if (strlen(p1) > strlen(p2))
00185 err = 1;
00186 }
00187 } while ((buf = G_index (buf, PIPE)) != NULL);
00188 buf = last;
00189
00190
00191 while (!isnull(*buf))
00192 {
00193 switch (*buf)
00194 {
00195 case '#':
00196 if (n == 0)
00197 {
00198 switch(s->cattype)
00199 {
00200 case CELL_TYPE:
00201 if(sscanf (buf, "#%d", &s->ccat)==1)
00202 n++;
00203 break;
00204 case FCELL_TYPE:
00205 if(sscanf (buf, "#%f", &s->fcat)==1)
00206 n++;
00207 break;
00208 case DCELL_TYPE:
00209 if(sscanf (buf, "#%lf", &s->dcat)==1)
00210 n++;
00211 break;
00212 default:
00213 err = 1;
00214 break;
00215 }
00216 }
00217 else{
00218 err = 1;
00219 }
00220
00221
00222 if ((buf = next_att (buf)) == (char *) NULL)
00223 return (FOUND_ALL(s,n,dim,c,d)? err: -2);
00224 break;
00225
00226 case '%':
00227 if (d < s->dbl_alloc) {
00228 p1 = ++buf;
00229 errno = 0;
00230 s->dbl_att[d++] = strtod(buf, &p1);
00231 if (p1 == buf || errno == ERANGE) {
00232
00233
00234
00235
00236 return -2;
00237 }
00238
00239 } else {
00240 err = 1;
00241 }
00242
00243 if ((buf = next_att (buf)) == (char *) NULL) {
00244 return (FOUND_ALL(s,n,dim,c,d)) ? err : -2;
00245 }
00246 break;
00247 case '@':
00248 if (isnull(*buf) || isnull(*(buf + 1)))
00249 return (FOUND_ALL(s,n,dim,c,d)? err: -2);
00250 else
00251 buf++;
00252 default:
00253
00254 if (c < s->str_alloc)
00255 {
00256 if ((tmp = cleanse_string (buf)) > 0)
00257 {
00258 G_strncpy (s->str_att[c++], buf, tmp);
00259 buf += tmp;
00260 }
00261 else
00262 return (FOUND_ALL(s,n,dim,c,d)? err: -2);
00263 }
00264 if ((buf = next_att (buf)) == (char *) NULL) {
00265 return (FOUND_ALL(s,n,dim,c,d)? err: -2);
00266 }
00267 break;
00268 }
00269 }
00270
00271 return (FOUND_ALL(s,n,dim,c,d)? err: -2);
00272 }
00273
00274 int G_oldsite_describe ( FILE *ptr,
00275 int *dims,int *cat,int *strs,int *dbls)
00276
00277
00278
00279
00280
00281
00282
00283
00284 {
00285 char sbuf[MAX_SITE_LEN], *buf;
00286 char ebuf[128], nbuf[128];
00287 int err;
00288 int itmp;
00289 float ftmp;
00290
00291 if (ftell (ptr) != 0L)
00292 {
00293 fprintf (stderr, "\nPROGRAMMER ERROR: G_oldsite_describe() must be called\n");
00294 fprintf (stderr, " immediately after G_fopen_sites_old()\n");
00295 return -2;
00296 }
00297
00298 *dims = *strs = *dbls = 0;
00299 *cat = -1;
00300 buf = sbuf;
00301
00302 if ((buf = fgets (sbuf, 1024, ptr)) == (char *) NULL)
00303 {
00304 rewind (ptr);
00305 return EOF;
00306 }
00307
00308 while ((*buf == '#' || !isdigit(*buf)) && *buf != '-' && *buf != '+')
00309 if ((buf = fgets (sbuf, 1024, ptr)) == (char *) NULL)
00310 {
00311 rewind (ptr);
00312 return EOF;
00313 }
00314
00315 if (buf[strlen (buf) - 1] == '\n')
00316 buf[strlen (buf) - 1] = '\0' ;
00317
00318 if ((err = sscanf (buf, "%[^|]|%[^|]|%*[^\n]", ebuf, nbuf)) < 2)
00319 {
00320 fprintf (stderr, "ERROR: ebuf %s nbuf %s\n", ebuf, nbuf);
00321 rewind (ptr);
00322 return -2;
00323 }
00324 *dims = 2;
00325
00326
00327 while (!ispipe(*buf) && !isnull(*buf))
00328 buf++;
00329 if (!isnull(*buf) && !isnull(*(buf + 1)))
00330 buf++;
00331 else
00332 {
00333 rewind (ptr);
00334 return -2;
00335 }
00336 while (!ispipe(*buf) && !isnull(*buf))
00337 buf++;
00338 if (!isnull(*buf) && !isnull(*(buf + 1)))
00339 buf++;
00340 else
00341 {
00342 rewind (ptr);
00343 return 0;
00344 }
00345
00346
00347 while (G_index (buf, PIPE) != (char *) NULL)
00348 {
00349 (*dims)++;
00350 while (!ispipe(*buf) && !isnull(*buf))
00351 buf++;
00352 if (isnull(*buf) || isnull(*(buf+1)))
00353 {
00354 rewind (ptr);
00355 return 0;
00356 }
00357 if (!isnull(*(buf + 1)))
00358 buf++;
00359 else
00360 {
00361 rewind (ptr);
00362 return -2;
00363 }
00364 }
00365
00366
00367 while (!isnull(*buf))
00368 {
00369 switch (*buf)
00370 {
00371 case '#':
00372 sscanf(buf,"#%s ",ebuf);
00373 if(G_strstr(ebuf,".")==NULL && sscanf(ebuf,"%d", &itmp) ==1)
00374 *cat=CELL_TYPE;
00375 else if(G_strstr(ebuf,".")!=NULL && sscanf(ebuf,"%f", &ftmp) ==1)
00376 *cat=FCELL_TYPE;
00377 else
00378 *cat=-1;
00379
00380
00381 while (!isspace (*buf) && !isnull(*buf))
00382 buf++;
00383 if (isnull(*buf) || isnull(*(buf + 1)))
00384 {
00385 rewind (ptr);
00386 return 0;
00387 }
00388 else
00389 buf++;
00390 break;
00391 case '%':
00392 (*dbls)++;
00393
00394 while (!isspace (*buf) && !isnull(*buf))
00395 buf++;
00396 if (isnull(*buf) || isnull(*(buf + 1)))
00397 {
00398 rewind (ptr);
00399 return 0;
00400 }
00401 else
00402 buf++;
00403 break;
00404 case '@':
00405 if (isnull(*buf) || isnull(*(buf + 1)))
00406 {
00407 rewind (ptr);
00408 return 0;
00409 }
00410 else
00411 buf++;
00412 default:
00413
00414 if ((err = cleanse_string (buf)) > 0)
00415 {
00416 (*strs)++;
00417 buf += err;
00418 }
00419
00420
00421 while (!isspace (*buf) && !isnull(*buf))
00422 buf++;
00423 if (isnull(*buf) || isnull(*(buf + 1)))
00424 {
00425 rewind (ptr);
00426 return 0;
00427 }
00428 else
00429 buf++;
00430 break;
00431 }
00432 }
00433
00434 rewind (ptr);
00435 return 0;
00436 }
00437
00438 int G_site_in_region ( Site *site, struct Cell_head *region)
00439
00440 {
00441
00442 double e_ing;
00443 double G_adjust_easting();
00444
00445 e_ing = G_adjust_easting (site->east, region);
00446 if (e_ing >= region->west &&
00447 e_ing < region->east &&
00448 site->north <= region->north &&
00449 site->north > region->south)
00450 return 1;
00451
00452 return 0;
00453 }
00454
00455 static int format_double ( double value, char *buf)
00456 {
00457 sprintf (buf, "%.8f", value);
00458 G_trim_decimal (buf);
00459 return 0;
00460 }
00461
00462 int cleanse_string (char *buf)
00463 {
00464 char *stop, *p, *p2;
00465
00466 p = buf;
00467
00468
00469
00470
00471
00472
00473
00474 if ( *buf != DQUOTE)
00475 {
00476 stop = G_index (buf, SPACE);
00477 if (stop == (char *) NULL)
00478 return strlen (buf);
00479 else
00480 return (int) (stop - buf);
00481 }
00482 else
00483 {
00484
00485 if (*p == DQUOTE)
00486 {
00487 while (*p != (char) NULL)
00488 {
00489 *p = *(p + 1);
00490 p++;
00491 }
00492 p = buf;
00493 stop = G_index (p + 1, DQUOTE);
00494 while (*(stop - 1) == BSLASH)
00495 stop = G_index (++stop, DQUOTE);
00496 }
00497 }
00498
00499 p = buf;
00500 while ((p = G_index (p, BSLASH)) != (char *) NULL && p <= stop)
00501 {
00502 p2 = p + 1;
00503 if (*p2 != (char) NULL && (*p2 == DQUOTE || *p2 == BSLASH))
00504 {
00505 while (*p != (char) NULL)
00506 {
00507 *p = *(p + 1);
00508 p++;
00509 }
00510 stop--;
00511 }
00512 p = p2;
00513 }
00514 return (int) (stop - buf);
00515 }
00516
00517 char *next_att (char *buf)
00518 {
00519 while (!isspace (*buf) && !isnull(*buf))
00520 buf++;
00521 if (isnull(*buf) || isnull(*(buf + 1)))
00522 return NULL;
00523 else
00524 while (isspace (*(buf + 1)) && !isnull(*(buf + 1)))
00525 buf++;
00526 buf++;
00527 return buf;
00528 }
00529
00530 int G_site_c_cmp (const void *a, const void *b)
00531
00532
00533 {
00534 int result = 0;
00535 double diff;
00536
00537 switch((*(Site **)a)->cattype)
00538 {
00539 case CELL_TYPE:
00540 diff = (double) (*(Site **) a)->ccat - (*(Site **) b)->ccat;
00541 break;
00542 case FCELL_TYPE:
00543 diff = (double) (*(Site **) a)->fcat - (*(Site **) b)->fcat;
00544 break;
00545 case DCELL_TYPE:
00546 diff = (double) (*(Site **) a)->dcat - (*(Site **) b)->dcat;
00547 break;
00548 }
00549 if (diff < 0.0 )
00550 result = -1;
00551 else if (diff > 0.0)
00552 result = 1;
00553 return result;
00554 }
00555
00556 int G_site_d_cmp (const void *a, const void *b)
00557
00558
00559 {
00560 int result = 0;
00561 double diff;
00562
00563 diff = (*(Site **) a)->dbl_att[0] - (*(Site **) b)->dbl_att[0];
00564 if (diff < 0.0 )
00565 result = -1;
00566 else if (diff > 0.0)
00567 result = 1;
00568 return result;
00569 }
00570
00571 int G_oldsite_s_cmp (const void *a, const void *b)
00572
00573
00574 {
00575 return strcmp((*(char **)((*(Site **) a)->str_att)),
00576 (*(char **)((*(Site **) b)->str_att)));
00577 }
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591 FILE * G_oldsites_open_old (char *name,char *mapset)
00592 {
00593 return G_fopen_old ("site_lists", name, mapset);
00594 }
00595
00596 FILE * G_oldsites_open_new (char *name)
00597 {
00598 return G_fopen_new ("site_lists", name);
00599 }
00600
00601
00602
00603
00604
00605
00606
00607 char *G_site_format (Site *s, char *fs, int id)
00608
00609
00610
00611 {
00612 char ebuf[MAX_SITE_STRING], nbuf[MAX_SITE_STRING];
00613 char xbuf[MAX_SITE_STRING];
00614 char *nfs, *buf;
00615 int fmt, i, j, k;
00616
00617 buf=(char *)G_malloc(MAX_SITE_LEN*sizeof(char));
00618
00619 fmt = G_projection ();
00620
00621 G_format_northing (s->north, nbuf, fmt);
00622 G_format_easting (s->east, ebuf, fmt);
00623
00624 nfs = (char *) ((fs == (char *) NULL) ? "|" : fs);
00625
00626 sprintf (buf, "%s%s%s", ebuf, nfs, nbuf);
00627
00628 for (i = 0; i < s->dim_alloc; ++i)
00629 {
00630 format_double (s->dim[i], nbuf);
00631 sprintf (xbuf, "%s%s", nfs, nbuf);
00632 G_strcat (buf, xbuf);
00633 }
00634
00635 nfs= (fs == NULL) ? " " : fs;
00636
00637 switch(s->cattype)
00638 {
00639 case CELL_TYPE:
00640 sprintf (xbuf, "%s%s%d ", nfs, ((id==0) ? "" : "#"), (int)s->ccat);
00641 G_strcat (buf, xbuf);
00642 break;
00643 case FCELL_TYPE:
00644 case DCELL_TYPE:
00645 sprintf (xbuf, "%s%s%g ", nfs, ((id==0) ? "" : "#"), (float)s->fcat);
00646 G_strcat (buf, xbuf);
00647 break;
00648 }
00649
00650 for (i = 0; i < s->dbl_alloc; ++i)
00651 {
00652 format_double (s->dbl_att[i], nbuf);
00653 sprintf (xbuf, "%s%s%s", nfs, ((id==0) ? "" : "%"), nbuf);
00654 G_strcat (buf, xbuf);
00655 }
00656
00657 for (i = 0; i < s->str_alloc; ++i)
00658 {
00659 if (strlen (s->str_att[i]) != 0)
00660 {
00661
00662 j = k = 0;
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685 G_strcpy (xbuf, s->str_att[i]);
00686
00687 G_strcpy (s->str_att[i], xbuf);
00688
00689 if (G_index (s->str_att[i], SPACE) != (char *) NULL)
00690 sprintf (xbuf, "%s%s\"%s\"", nfs, ((id==0) ? "" : "@"), s->str_att[i]);
00691 else
00692 sprintf (xbuf, "%s%s%s", nfs, ((id==0) ? "" : "@"), s->str_att[i]);
00693 G_strcat (buf, xbuf);
00694 }
00695 }
00696 return buf;
00697 }
00698