20 #include <grass/gis.h>
21 #include <grass/site.h>
22 #include <grass/dbmi.h>
23 #include <grass/Vect.h>
24 #include <grass/glocale.h>
32 #define ispipe(c) (c==PIPE)
33 #define isnull(c) (c=='\0')
34 #define isquote(c) (c==DQUOTE)
35 #define isbslash(c) (c==BSLASH)
37 static int format_double(
double,
char *);
38 static char *next_att(
const char *);
39 static int cleanse_string(
char *);
41 static int site_att_cmp(
const void *pa,
const void *pb)
43 const SITE_ATT *a = pa, *
b = pb;
45 return a->cat - b->cat;
58 static struct line_pnts *Points =
NULL;
59 static struct line_cats *Cats =
NULL;
79 G_debug(4,
"Site: %f|%f|%f|#%d", Points->x[0], Points->y[0],
82 s->east = Points->x[0];
83 s->north = Points->y[0];
85 s->dim[0] = Points->z[0];
91 if (Map->n_site_att > 0) {
92 sa = (SITE_ATT *) bsearch((
void *)&
cat, (
void *)Map->site_att,
93 Map->n_site_att,
sizeof(SITE_ATT),
97 G_warning(_(
"Attributes for category %d not found"), cat);
98 for (i = 0; i < Map->n_site_dbl; i++)
100 for (i = 0; i < Map->n_site_str; i++)
101 G_strncpy(s->str_att[i],
"", MAX_SITE_STRING);
104 for (i = 0; i < Map->n_site_dbl; i++)
105 s->dbl_att[i] = sa->dbl[i];
106 for (i = 0; i < Map->n_site_str; i++)
107 G_strncpy(s->str_att[i], sa->str[i], MAX_SITE_STRING);
119 static struct line_pnts *Points =
NULL;
120 static struct line_cats *Cats =
NULL;
133 G_debug(4,
"cattype = %d", s->cattype);
135 if (s->cattype == FCELL_TYPE || s->cattype == DCELL_TYPE)
138 if (s->cattype == CELL_TYPE)
159 G_debug(1,
"Vector is 3D -> number of site dimensions is 3");
163 G_debug(1,
"Vector is 2D -> number of site dimensions is 2");
170 *dbls = Map->n_site_dbl;
171 *strs = Map->n_site_str;
182 static char buf[128];
184 if (head->name !=
NULL)
200 if (head->stime !=
NULL || head->time !=
NULL) {
201 if (head->time !=
NULL) {
205 else if (head->stime !=
NULL) {
206 if (head->time ==
NULL) {
208 (
struct TimeStamp *)G_malloc(
sizeof(
struct TimeStamp)))
212 G_warning(_(
"Illegal TimeStamp string"));
238 if (head->stime && strlen(head->stime) > 0) {
240 (
struct TimeStamp *)G_malloc(
sizeof(
struct TimeStamp))) ==
NULL)
311 return G_ask_new(prompt, name,
"vector",
"vector");
317 return G_ask_old(prompt, name,
"vector",
"vector");
323 return G_ask_any(prompt, name,
"vector",
"vector", 1);
335 struct Map_info *
Map;
336 struct field_info *fi;
337 int more, nrows, row, ncols, col, ndbl, nstr, adbl, astr, ctype;
348 _(
"Dev note: Adapted sites library used for vector points. "
349 "(module should be updated to GRASS 6 vector library)"));
351 Map = (
struct Map_info *)G_malloc(
sizeof(
struct Map_info));
356 G_debug(1,
"Vector map opened");
359 Map->site_att =
NULL;
366 G_debug(1,
"No attribute table");
372 G_fatal_error(_(
"Unable to open database <%s> by driver <%s>"),
385 G_debug(1,
"%d rows selected from vector attribute table", nrows);
387 Map->site_att = (SITE_ATT *)
malloc(nrows *
sizeof(SITE_ATT));
388 Map->n_site_att = nrows;
396 if (
db_fetch(&cursor, DB_NEXT, &more) != DB_OK)
404 for (col = 0; col < ncols; col++) {
413 case DB_C_TYPE_DOUBLE:
416 case DB_C_TYPE_STRING:
417 case DB_C_TYPE_DATETIME:
422 Map->n_site_dbl = adbl;
423 Map->n_site_str = astr;
424 G_debug(1,
"adbl = %d astr = %d", adbl, astr);
427 sa = &(Map->site_att[row]);
428 sa->dbl = (
double *)
malloc(adbl *
sizeof(
double));
429 sa->str = (
char **)
malloc(astr *
sizeof(
char *));
432 for (col = 0; col < ncols; col++) {
446 case DB_C_TYPE_DOUBLE:
450 case DB_C_TYPE_STRING:
454 case DB_C_TYPE_DATETIME:
466 qsort((
void *)Map->site_att, Map->n_site_att,
sizeof(SITE_ATT),
475 struct Map_info *
Map;
478 _(
"Dev note: Adapted sites library used for vector points. "
479 "(module should be updated to GRASS 6 vector library)"));
480 G_warning(
"Site/vector attributes ignored.");
482 Map = (
struct Map_info *)G_malloc(
sizeof(
struct Map_info));
486 G_debug(1,
"New vector map opened");
496 if (Map->mode == GV_MODE_WRITE || Map->mode == GV_MODE_RW)
501 for (i = 0; i < Map->n_site_att; i++) {
502 free(Map->site_att[i].dbl);
504 for (j = 0; j < Map->n_site_str; j++)
505 free(Map->site_att[i].str[j]);
507 free(Map->site_att[i].str);
533 int G_get_site(
struct Map_info *
fd,
double *east,
double *north,
char **desc)
569 int n_dim,
int n_s_att,
int n_d_att)
578 if (n_dim < 2 || n_s_att < 0 || n_d_att < 0)
579 G_fatal_error(_(
"G_oldsite_new_struct: invalid # dims or fields"));
581 if ((s = (Site *) G_malloc(
sizeof(Site))) ==
NULL)
582 return (Site *)
NULL;
584 s->cattype = cattype;
585 s->ccat = s->fcat = s->dcat = 0;
589 (
double *)G_malloc((n_dim - 2) *
sizeof(
double))) ==
NULL) {
591 return (Site *)
NULL;
594 s->dim_alloc = n_dim - 2;
598 (
double *)G_malloc(n_d_att *
sizeof(
double))) ==
NULL) {
602 return (Site *)
NULL;
605 s->dbl_alloc = n_d_att;
609 (
char **)G_malloc(n_s_att *
sizeof(
char *))) ==
NULL) {
615 return (Site *)
NULL;
618 for (i = 0; i < n_s_att; ++i)
620 (
char *)G_malloc(MAX_SITE_STRING *
sizeof(
char))) ==
630 return (Site *)
NULL;
633 s->str_alloc = n_s_att;
638 #define FOUND_ALL(s,n,dim,c,d) (((s->cattype != -1 && !n) || \
639 (dim < s->dim_alloc) || \
640 (c < s->str_alloc) || \
641 (d < s->dbl_alloc))?0:1)
659 char sbuf[MAX_SITE_LEN], *
buf, *last, *p1, *p2;
660 char ebuf[128], nbuf[128];
661 int n = 0, d = 0, c = 0, dim = 0,
err = 0, tmp;
665 if ((buf = fgets(sbuf, 1024, ptr)) == (
char *)
NULL)
668 while ((*buf ==
'#' || !isdigit(*buf)) && *buf !=
'-' && *buf !=
'+')
669 if ((buf = fgets(sbuf, 1024, ptr)) == (
char *)
NULL)
672 if (buf[strlen(buf) - 1] ==
'\n')
673 buf[strlen(buf) - 1] =
'\0';
675 if (sscanf(buf,
"%[^|]|%[^|]|%*[^\n]", ebuf, nbuf) < 2) {
676 fprintf(stderr,
"ERROR: ebuf %s nbuf %s\n", ebuf, nbuf);
682 fprintf(stderr,
"ERROR: ebuf %s nbuf %s\n", ebuf, nbuf);
696 return (
FOUND_ALL(s, n, dim, c, d) ? 0 : -2);
698 if (dim < s->dim_alloc) {
699 if (sscanf(buf,
"%lf|", &(s->dim[dim++])) < 1)
705 else if (strlen(p1) > strlen(p2))
716 switch (s->cattype) {
718 if (sscanf(buf,
"#%d", &s->ccat) == 1)
722 if (sscanf(buf,
"#%f", &s->fcat) == 1)
726 if (sscanf(buf,
"#%lf", &s->dcat) == 1)
739 if ((buf = next_att(buf)) == (
char *)
NULL)
744 if (d < s->dbl_alloc) {
747 s->dbl_att[d++] = strtod(buf, &p1);
748 if (p1 == buf ||
errno == ERANGE) {
761 if ((buf = next_att(buf)) == (
char *)
NULL) {
772 if (c < s->str_alloc) {
773 if ((tmp = cleanse_string(buf)) > 0) {
780 if ((buf = next_att(buf)) == (
char *)
NULL) {
801 char sbuf[MAX_SITE_LEN], *
buf;
802 char ebuf[128], nbuf[128];
807 if (ftell(ptr) != 0L) {
809 "\nPROGRAMMER ERROR: G_oldsite_describe() must be called\n");
810 fprintf(stderr,
" immediately after G_fopen_sites_old()\n");
814 *dims = *strs = *dbls = 0;
818 if ((buf = fgets(sbuf, 1024, ptr)) == (
char *)
NULL) {
823 while ((*buf ==
'#' || !isdigit(*buf)) && *buf !=
'-' && *buf !=
'+')
824 if ((buf = fgets(sbuf, 1024, ptr)) == (
char *)
NULL) {
829 if (buf[strlen(buf) - 1] ==
'\n')
830 buf[strlen(buf) - 1] =
'\0';
832 if ((err = sscanf(buf,
"%[^|]|%[^|]|%*[^\n]", ebuf, nbuf)) < 2) {
833 fprintf(stderr,
"ERROR: ebuf %s nbuf %s\n", ebuf, nbuf);
878 sscanf(buf,
"#%s ", ebuf);
879 if (
G_strstr(ebuf,
".") ==
NULL && sscanf(ebuf,
"%d", &itmp) == 1)
882 sscanf(ebuf,
"%f", &ftmp) == 1)
888 while (!isspace(*buf) && !
isnull(*buf))
900 while (!isspace(*buf) && !
isnull(*buf))
918 if ((err = cleanse_string(buf)) > 0) {
924 while (!isspace(*buf) && !
isnull(*buf))
947 if (e_ing >= region->west &&
948 e_ing < region->east &&
949 site->north <= region->north && site->north > region->south)
955 static int format_double(
double value,
char *
buf)
962 int cleanse_string(
char *
buf)
976 if (stop == (
char *)
NULL)
979 return (
int)(stop -
buf);
985 while (*p != (
char)
NULL) {
991 while (*(stop - 1) ==
BSLASH)
1000 while (*p != (
char)
NULL) {
1008 return (
int)(stop -
buf);
1011 static char *next_att(
const char *buf)
1013 while (!isspace(*buf) && !
isnull(*buf))
1018 while (isspace(*(buf + 1)) && !
isnull(*(buf + 1)))
1031 switch ((*(Site **) a)->cattype) {
1033 diff = (double)(*(Site **) a)->ccat - (*(Site **)
b)->ccat;
1036 diff = (double)(*(Site **) a)->fcat - (*(Site **)
b)->fcat;
1039 diff = (double)(*(Site **) a)->dcat - (*(Site **)
b)->dcat;
1044 else if (diff > 0.0)
1056 diff = (*(Site **) a)->dbl_att[0] - (*(Site **) b)->dbl_att[0];
1059 else if (diff > 0.0)
1068 return strcmp((*(
char **)((*(Site **) a)->str_att)),
1069 (*(
char **)((*(Site **) b)->str_att)));
1106 char ebuf[MAX_SITE_STRING], nbuf[MAX_SITE_STRING];
1107 char xbuf[MAX_SITE_STRING];
1112 buf = (
char *)G_malloc(MAX_SITE_LEN *
sizeof(
char));
1119 nfs = (
char *)((fs == (
char *)
NULL) ?
"|" :
fs);
1121 sprintf(buf,
"%s%s%s", ebuf, nfs, nbuf);
1123 for (i = 0; i < s->dim_alloc; ++i) {
1124 format_double(s->dim[i], nbuf);
1125 sprintf(xbuf,
"%s%s", nfs, nbuf);
1129 nfs = (fs ==
NULL) ?
" " : fs;
1131 switch (s->cattype) {
1133 sprintf(xbuf,
"%s%s%d ", nfs, ((
id == 0) ?
"" :
"#"), (
int)s->ccat);
1138 sprintf(xbuf,
"%s%s%g ", nfs, ((
id == 0) ?
"" :
"#"), (
float)s->fcat);
1143 for (i = 0; i < s->dbl_alloc; ++i) {
1144 format_double(s->dbl_att[i], nbuf);
1145 sprintf(xbuf,
"%s%s%s", nfs, ((
id == 0) ?
"" :
"%"), nbuf);
1149 for (i = 0; i < s->str_alloc; ++i) {
1150 if (strlen(s->str_att[i]) != 0) {
1180 sprintf(xbuf,
"%s%s\"%s\"", nfs, ((
id == 0) ?
"" :
"@"),
1183 sprintf(xbuf,
"%s%s%s", nfs, ((
id == 0) ?
"" :
"@"),
1208 return (SITE_ATT *) bsearch((
void *)cat, (
void *)Map->site_att,
1209 Map->n_site_att,
sizeof(SITE_ATT),
1221 struct field_info *fi;
1222 int nrows, row, ncols, col, ndbl, nstr, ctype;
1243 G_debug(1,
"No attribute table");
1249 G_fatal_error(_(
"Cannot open database %s by driver %s"), fi->database,
1260 G_debug(1,
"%d rows selected from vector attribute table", nrows);
1273 *cnames = (
char **)
malloc(ncols *
sizeof(
char *));
1274 *ctypes = (
int *)
malloc(ncols *
sizeof(
int));
1275 *ndx = (
int *)
malloc(ncols *
sizeof(
int));
1277 for (col = 0; col < ncols; col++) {
1283 *(*cnames + col) = (
char *)
malloc(strlen(name) + 1);
1287 if (strcmp(name, fi->key) == 0) {
1288 *(*ctypes + col) =
'c';
1294 case DB_C_TYPE_DOUBLE:
1295 *(*ctypes + col) =
'd';
1296 *(*ndx + col) = ndbl;
1299 case DB_C_TYPE_STRING:
1300 case DB_C_TYPE_DATETIME:
1301 *(*ctypes + col) =
's';
1302 *(*ndx + col) = nstr;
1317 for (; ncols > 0; ncols--)
1318 free(*(cnames + ncols - 1));
dbDriver * db_start_driver_open_database(const char *drvname, const char *dbname)
Open driver/database connection.
dbColumn * db_get_table_column(dbTable *table, int n)
returns column structure for given table and column number
sprintf(buf2,"%s", G3D_CATS_ELEMENT)
void G_free(void *buf)
Free allocated memory.
char * G_find_vector(char *name, const char *mapset)
struct field_info * Vect_get_field(struct Map_info *Map, int field)
Get information about link to database.
char * G_store(const char *s)
Copy string to allocated memory.
const char * db_get_column_name(dbColumn *column)
returns column name for given column
int G_site_put(struct Map_info *Map, const Site *s)
int G_site_describe(struct Map_info *Map, int *dims, int *cat, int *strs, int *dbls)
int G_site_c_cmp(const void *a, const void *b)
int Vect_read_next_line(struct Map_info *Map, struct line_pnts *line_p, struct line_cats *line_c)
Read next vector feature (level 1 and 2)
char * G_strcat(char *T, const char *F)
This copies characters from the string F into the string T.
int db_close_database_shutdown_driver(dbDriver *driver)
Close driver/database connection.
char * G_index(const char *str, int delim)
delimiter
struct line_pnts * Vect_new_line_struct()
Creates and initializes a struct line_pnts.
void G_sites_free_fields(int ncols, char **cnames, int *ctypes, int *ndx)
char * G_ask_in_mapset(const char *prompt, char *name, char *element, char *desc)
prompt for existing database file
FILE * G_oldsites_open_old(const char *name, const char *mapset)
int G_site_get_head(struct Map_info *Map, Site_head *head)
int G_scan_timestamp(struct TimeStamp *ts, const char *buf)
Fill a TimeStamp structure from a datetime string.
int Vect_reset_line(struct line_pnts *Points)
Reset line.
char * G_ask_sites_old(const char *prompt, char *name)
int G_oldsite_s_cmp(const void *a, const void *b)
int Vect_reset_cats(struct line_cats *Cats)
Reset category structure to make sure cats structure is clean to be re-used.
struct Map_info * G_sites_open_new(const char *name)
char * G_find_vector2(const char *name, const char *mapset)
find a vector map (look but don't touch)
struct Map_info * G_fopen_sites_new(const char *name)
int G_trim_decimal(char *buf)
Removes trailing zeros from decimal number.
Site * G_site_new_struct(RASTER_MAP_TYPE cattype, int n_dim, int n_s_att, int n_d_att)
char * G_ask_new(const char *prompt, char *name, char *element, char *desc)
prompt for new database file
char * G_strcpy(char *T, const char *F)
Copies characters from the string F into the string T.
struct Map_info * G_sites_open_old(const char *name, const char *mapset)
int G_sites_get_fields(struct Map_info *Map, char ***cnames, int **ctypes, int **ndx)
int Vect_append_point(struct line_pnts *Points, double x, double y, double z)
Appends one point to the end of a line.
int db_append_string(dbString *x, const char *s)
int db_sqltype_to_Ctype(int sqltype)
int Vect_cat_set(struct line_cats *Cats, int field, int cat)
Add new field/cat to category structure if doesn't exist yet.
int db_fetch(dbCursor *cursor, int position, int *more)
Fetch data.
dbTable * db_get_cursor_table(dbCursor *cursor)
#define FOUND_ALL(s, n, dim, c, d)
double db_get_value_double(dbValue *value)
int G_site_put_head(struct Map_info *Map, Site_head *head)
int db_get_column_sqltype(dbColumn *column)
returns column sqltype for column (the function db_sqltype_name() returns sqltype description) ...
int Vect_set_open_level(int level)
Predetermine level at which a map will be opened for reading.
int Vect_build(struct Map_info *Map)
Build topology for vector map.
int G_site_get(struct Map_info *Map, Site *s)
int db_get_table_number_of_columns(dbTable *table)
void G_message(const char *msg,...)
Print a message to stderr.
char * G_ask_old(const char *prompt, char *name, char *element, char *desc)
prompt for existing database file
struct Map_info * G_fopen_sites_old(const char *name, const char *mapset)
dbValue * db_get_column_value(dbColumn *column)
returns column value for given column structure
FILE * G_oldsites_open_new(const char *name)
int G_oldsite_describe(FILE *ptr, int *dims, int *cat, int *strs, int *dbls)
int db_get_num_rows(dbCursor *cursor)
Get number of selected rows.
char * G_strncpy(char *T, const char *F, int n)
This function is similar to G_chrcpy() but always copies at least n characters into the string T...
SITE_ATT * G_sites_get_atts(struct Map_info *Map, int *cat)
char * datetime_error_msg(void)
returns an error message
char * G_ask_sites_in_mapset(const char *prompt, char *name)
int Vect_open_old(struct Map_info *Map, const char *name, const char *mapset)
Open existing vector for reading.
char * G_ask_sites_new(const char *prompt, char *name)
char buf[GNAME_MAX+sizeof(G3D_DIRECTORY)+2]
int Vect_close(struct Map_info *Map)
Close vector data file.
int G_get_site(struct Map_info *fd, double *east, double *north, char **desc)
int G_scan_northing(const char *buf, double *northing, int projection)
ASCII northing to double.
FILE * G_fopen_new(const char *element, const char *name)
Open a new database file.
struct line_cats * Vect_new_cats_struct()
Creates and initializes line_cats structure.
char * G_find_sites2(const char *name, const char *mapset)
void G_site_free_struct(Site *s)
char * G_ask_any(const char *prompt, char *name, char *element, char *desc, int warn)
prompt for any valid file name
G_warning("category support for [%s] in mapset [%s] %s", name, mapset, type)
int G__oldsite_get(FILE *ptr, Site *s, int fmt)
char * G_strstr(const char *mainString, const char *subString)
Finds the first occurrence of the character C in the null-terminated string beginning at mainString...
char * db_get_string(dbString *x)
int G_debug(int level, const char *msg,...)
Print debugging message.
char * G_ask_sites_any(const char *prompt, char *name)
int db_set_string(dbString *x, const char *s)
char * G_site_format(const Site *s, const char *fs, int id)
int db_get_value_int(dbValue *value)
long Vect_write_line(struct Map_info *Map, int type, struct line_pnts *points, struct line_cats *cats)
Writes new feature to the end of file (table)
int G_oldsite_get(FILE *fptr, Site *s)
int Vect_open_new(struct Map_info *Map, const char *name, int with_z)
Open new vector for reading/writing.
char * G_find_sites(char *name, const char *mapset)
FILE * G_fopen_old(const char *element, const char *name, const char *mapset)
Open a database file for reading.
int G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
int G_put_site(struct Map_info *fd, double east, double north, const char *desc)
int G_site_in_region(const Site *site, const struct Cell_head *region)
int G_site_d_cmp(const void *a, const void *b)
int G_format_timestamp(const struct TimeStamp *ts, char *buf)
Create text string from TimeStamp structure.
int G_scan_easting(const char *buf, double *easting, int projection)
ASCII easting to double.
double G_adjust_easting(double east, const struct Cell_head *window)
Returns east larger than west.
int G_projection(void)
query cartographic projection
const char * db_get_value_string(dbValue *value)
void G_sites_close(struct Map_info *Map)
int db_open_select_cursor(dbDriver *driver, dbString *select, dbCursor *cursor, int mode)
Open select cursor.
void db_init_string(dbString *x)
int Vect_cat_get(struct line_cats *Cats, int field, int *cat)
Get first found category of given field.