/*! \brief Read header of GRASS ASCII vector format \param dascii pointer to the ASCII file \param Map pointer to Map_info structure \return 0 on success \return -1 on error */ int Vect_read_ascii_head(FILE *dascii, struct Map_info *Map) { char buff[1024]; char *ptr; for (;;) { if (0 == G_getl2(buff, sizeof(buff) - 1, dascii)) return (0); /* Last line of header */ if (strncmp(buff, "VERTI:", 6) == 0) return (0); if (!(ptr = strchr(buff, ':'))) { G_warning(_("Unexpected data in vector header:\n[%s]"), buff); return -1; } ptr++; /* Search for the start of text */ while (*ptr == ' ') ptr++; if (strncmp(buff, "ORGANIZATION:", 12) == 0) Vect_set_organization(Map, ptr); else if (strncmp(buff, "DIGIT DATE:", 11) == 0) Vect_set_date(Map, ptr); else if (strncmp(buff, "DIGIT NAME:", 11) == 0) Vect_set_person(Map, ptr); else if (strncmp(buff, "MAP NAME:", 9) == 0) Vect_set_map_name(Map, ptr); else if (strncmp(buff, "MAP DATE:", 9) == 0) Vect_set_map_date(Map, ptr); else if (strncmp(buff, "MAP SCALE:", 10) == 0) Vect_set_scale(Map, atoi(ptr)); else if (strncmp(buff, "OTHER INFO:", 11) == 0) Vect_set_comment(Map, ptr); else if (strncmp(buff, "ZONE:", 5) == 0 || strncmp(buff, "UTM ZONE:", 9) == 0) Vect_set_zone(Map, atoi(ptr)); else if (strncmp(buff, "WEST EDGE:", 10) == 0) { } else if (strncmp(buff, "EAST EDGE:", 10) == 0) { } else if (strncmp(buff, "SOUTH EDGE:", 11) == 0) { } else if (strncmp(buff, "NORTH EDGE:", 11) == 0) { } else if (strncmp(buff, "MAP THRESH:", 11) == 0) Vect_set_thresh(Map, atof(ptr)); else { G_warning(_("Unknown keyword <%s> in vector head"), buff); } } /* NOTREACHED */ }
/*! \brief Copy header data from one to another map \param from target vector map \param[out] to destination vector map \return 0 */ int Vect_copy_head_data(const struct Map_info *from, struct Map_info *to) { Vect_set_organization(to, Vect_get_organization(from)); Vect_set_date(to, Vect_get_date(from)); Vect_set_person(to, Vect_get_person(from)); Vect_set_map_name(to, Vect_get_map_name(from)); Vect_set_map_date(to, Vect_get_map_date(from)); Vect_set_comment(to, Vect_get_comment(from)); Vect_set_scale(to, Vect_get_scale(from)); Vect_set_zone(to, Vect_get_zone(from)); Vect_set_thresh(to, Vect_get_thresh(from)); return 0; }
/*! \brief Initialize Map_info head structure (dig_head) \param[in,out] Map pointer to Map_info structure */ void Vect__init_head(struct Map_info *Map) { char buf[64]; /* organization */ Map->head.organization = NULL; Vect_set_organization(Map, ""); /* date */ Map->head.date = NULL; Vect_set_date(Map, ""); /* user name */ Map->head.user_name = NULL; sprintf(buf, "%s", G_whoami()); Vect_set_person(Map, buf); /* map name */ Map->head.map_name = NULL; Vect_set_map_name(Map, ""); /* source date */ Map->head.source_date = NULL; sprintf(buf, "%s", G_date()); Vect_set_map_date(Map, buf); /* comments */ Map->head.comment = NULL; Vect_set_comment(Map, ""); /* scale, threshold */ Vect_set_scale(Map, 1); Vect_set_thresh(Map, 0.0); /* proj, zone */ Vect_set_proj(Map, -1); Vect_set_zone(Map, -1); /* support variables */ Map->plus.Spidx_built = 0; Map->plus.release_support = 0; Map->plus.update_cidx = 0; }
/* Create GRASS vector output map. Create attribute table. Calculate geometries and write them into the output map. Calculate attributes and write them into the output map's attribute table. */ void writeMap() { int i, j; double xlength, ylength, zlength; double length, flatLength, bailLength; double xoffset, yoffset, zoffset; double xys[12]; int ratio; double zRatio; /* attributes to be written to output map */ int boneID; int skelID; int unitID; int oldID; int cat; char *organization; char buf[MAXSTR]; if ( numPoints < 2 ) { G_fatal_error ("Less than two valid measurement points in input file"); } G_message (_("Constructing geometries for %i valid points:"), numPoints ); /* CREATE OUTPUT VECTOR MAP */ if (Vect_legal_filename(output->answer) < 0) { G_fatal_error(_("Use '%s' option to change vector map name"), output->key); } Map = (struct Map_info *) G_malloc (sizeof ( struct Map_info ) ); if (Vect_open_new(Map, output->answer, WITH_Z) < 0) { G_fatal_error(_("Unable to create vector map <%s>"), output->answer); } Vect_set_map_name(Map, output->answer); Vect_hist_command(Map); if ((organization = getenv("GRASS_ORGANIZATION"))) { Vect_set_organization(Map, organization); } else { Vect_set_organization(Map, "UNKNOWN ORGANIZATION"); } Vect_set_date(Map, G_date()); Vect_set_person(Map, G_whoami()); Vect_set_map_date(Map, ""); Vect_set_scale(Map, 2400); Vect_set_comment(Map, ""); Vect_set_zone(Map, 0); Vect_set_thresh(Map, 0.0); /* START DBMS INTERFACE */ /* prepare strings for use in db_* calls */ db_init_string(&sql); /* start default database driver */ Fi = Vect_default_field_info(Map, 1, NULL, GV_1TABLE); driver = db_start_driver_open_database(Fi->driver,Vect_subst_var(Fi->database, Map)); if (driver == NULL) { Vect_delete(output->answer); G_fatal_error(_("Unable to open database <%s> by driver <%s>"), Vect_subst_var(Fi->database, Map), Fi->driver); } /* create attribute table */ db_begin_transaction ( driver ); sprintf(buf, "create table %s (cat integer, skel_id integer, bone_id integer, unit_id integer, GRASSRGB varchar(11),BONERGB varchar(11));", Fi->table); if ( DEBUG ) { fprintf ( stderr, "Creating attribute table: %s\n", buf ); } db_set_string(&sql, buf); if (db_execute_immediate(driver, &sql) != DB_OK) { Vect_delete(output->answer); G_fatal_error(_("Unable to create attribute table: %s"), db_get_string(&sql)); } if (db_grant_on_table (driver, output->answer, DB_PRIV_SELECT, DB_GROUP | DB_PUBLIC) != DB_OK) { Vect_delete(output->answer); G_fatal_error(_("Unable to grant privileges on table <%s>"), output->answer); } if (db_create_index2(driver, output->answer, "cat") != DB_OK) { G_warning(_("Unable to create index for table <%s>, key <%s>"), output->answer, "cat"); } /* link vector map to attribute table */ if (Vect_map_add_dblink(Map, 1, NULL, Fi->table, "cat", Fi->database, Fi->driver) ) { Vect_delete(output->answer); G_fatal_error(_("Unable to add database link for vector map <%s>"), Vect_get_full_name(Map)); } /* PROCESS POINTS AND WRITE GEOMETRIES */ /* Now process point measurements and write geometries into output vector map. */ /* At this stage, the global points array has an even number of valid points. */ oldID = pointTable[0].SKEL_ID; unitID = 1; cat = 0; for ( i = 0; i < numPoints; i = i + 2 ) { /* This boneID is a generalized ID that does not differentiate between start and end measurement. */ boneID = (int) pointTable[i+1].BONE_ID / 2; skelID = pointTable[i+1].SKEL_ID; /* get coordinates for top and bottom of bone */ ax = pointTable[i].X; ay = pointTable[i].Y; az = pointTable[i].Z; bx = pointTable[i+1].X; by = pointTable[i+1].Y; bz = pointTable[i+1].Z; /* get vector lengths */ xlength = fabs (ax - bx); ylength = fabs (ay - by); zlength = fabs (az - bz); /* get real length */ length = sqrt ( (xlength*xlength) + (ylength*ylength) + (zlength*zlength) ); /* get length in x/y plane */ flatLength = sqrt ( (xlength*xlength) + (ylength*ylength) ); /* determine ratio for triangles, depending on bone type */ ratio = 12; /* default */ for ( j = 0; j < NUM_RATIOS; j ++ ) { if ( boneID == RATIO_ID[j] ) { ratio = RATIO_VAL[j]; } } /* get bail length */ bailLength = (double) ( length / (double) ratio); /* calculate bail offsets from top point (one bail is mirror of the other) */ xoffset = (bailLength * ylength) / flatLength; yoffset = ( (bailLength * xlength) / flatLength ) * (-1); zoffset = 0; xys[0]= ax + xoffset; xys[1]= ay + yoffset; xys[2]= az + zoffset; xys[6]= ax - xoffset; xys[7]= ay - yoffset; xys[8]= az - zoffset; /* get 3rd axis offsets */ zRatio = (zlength/ratio) / flatLength; xoffset = xlength * zRatio; yoffset = ylength * zRatio; zoffset = (flatLength/ratio) * (-1); xys[3]= ax + xoffset; xys[4]= ay + yoffset; xys[5]= az + zoffset; xys[9]= ax - xoffset; xys[10]= ay - yoffset; xys[11]= az - zoffset; /* Increase unit ID by "1", if we have another skeleton ID */ if ( oldID != pointTable[i+1].SKEL_ID ) { unitID ++; oldID = pointTable[i+1].SKEL_ID; /* switch to next colour for next geometry */ RGBNUM ++; if ( RGBNUM == RGBMAX ) { RGBNUM = 0; } } /* write geometries */ if ( MODE == MODE_DARTS ) { writeTriangle ( cat, skelID, boneID, unitID, xys, 0, 6 ); cat ++; writeTriangle ( cat, skelID, boneID, unitID, xys, 3, 9 ); cat ++; } if ( MODE == MODE_LINES ) { writeLine ( cat, skelID, boneID, unitID ); cat ++; } if ( MODE == MODE_PLANES_H ) { writeTriangle ( cat, skelID, boneID, unitID, xys, 0, 6 ); cat ++; } if ( MODE == MODE_PLANES_V ) { writeTriangle ( cat, skelID, boneID, unitID, xys, 3, 9 ); cat ++; } if ( MODE == MODE_POINTS ) { writePoints ( cat, skelID, boneID, unitID ); cat = cat + 2; } if ( MODE == MODE_PYRAMIDS ) { writeTriangle ( cat, skelID, boneID, unitID, xys, 0, 3 ); cat ++; writeTriangle ( cat, skelID, boneID, unitID, xys, 3, 6 ); cat ++; writeTriangle ( cat, skelID, boneID, unitID, xys, 6, 9 ); cat ++; writeTriangle ( cat, skelID, boneID, unitID, xys, 9, 0 ); cat ++; writeSquare ( cat, skelID, boneID, unitID, xys ); cat ++; } /* switch to next colour for bone colouring */ RGBNUM_BONE ++; if ( RGBNUM_BONE == RGBMAX ) { RGBNUM_BONE = 0; } G_percent ( i, numPoints - 2, 1 ); } fprintf ( stdout, "\n" ); /* commit DBMS actions */ db_commit_transaction(driver); db_close_database_shutdown_driver(driver); if (!Vect_build(Map)) { G_warning("Building topology failed"); } Vect_close(Map); db_free_string(&sql); }
/*! \brief Reads head information from text file (GV_HEAD_ELEMENT) - for internal use only \param Map pointer to Map_info structure \return 0 on success \return -1 on error */ int Vect__read_head(struct Map_info *Map) { FILE *head_fp; char buff[2000]; char *path, *ptr; /* Reset / init */ Vect__init_head(Map); G_debug(1, "Vect__read_head(): vector = %s@%s", Map->name, Map->mapset); path = Vect__get_path(Map); head_fp = G_fopen_old(path, GV_HEAD_ELEMENT, Map->mapset); G_free(path); if (head_fp == NULL) { G_warning(_("Unable to open header file of vector <%s>"), Vect_get_full_name(Map)); return -1; } while (G_getl2(buff, 2000, head_fp)) { if (!(ptr = strchr(buff, ':'))) { G_warning(_("Corrupted row in head: %s"), buff); continue; } ptr++; /* Search for the start of text */ while (*ptr == ' ') ptr++; if (strncmp(buff, "ORGANIZATION:", sizeof(char) * 12) == 0) Vect_set_organization(Map, ptr); else if (strncmp(buff, "DIGIT DATE:", sizeof(char) * 11) == 0) Vect_set_date(Map, ptr); else if (strncmp(buff, "DIGIT NAME:", sizeof(char) * 11) == 0) Vect_set_person(Map, ptr); else if (strncmp(buff, "MAP NAME:", sizeof(char) * 9) == 0) Vect_set_map_name(Map, ptr); else if (strncmp(buff, "MAP DATE:", sizeof(char) * 9) == 0) Vect_set_map_date(Map, ptr); else if (strncmp(buff, "MAP SCALE:", sizeof(char) * 10) == 0) Vect_set_scale(Map, atoi(ptr)); else if (strncmp(buff, "OTHER INFO:", sizeof(char) * 11) == 0) Vect_set_comment(Map, ptr); else if (strncmp(buff, "PROJ:", sizeof(char) * 5) == 0) Vect_set_proj(Map, atoi(ptr)); else if (strncmp(buff, "ZONE:", sizeof(char) * 5) == 0 || strncmp(buff, "UTM ZONE:", sizeof(char) * 9) == 0) Vect_set_zone(Map, atoi(ptr)); else if (strncmp(buff, "WEST EDGE:", sizeof(char) * 10) == 0) { } else if (strncmp(buff, "EAST EDGE:", sizeof(char) * 10) == 0) { } else if (strncmp(buff, "SOUTH EDGE:", sizeof(char) * 11) == 0) { } else if (strncmp(buff, "NORTH EDGE:", sizeof(char) * 11) == 0) { } else if (strncmp(buff, "MAP THRESH:", sizeof(char) * 11) == 0) Vect_set_thresh(Map, atof(ptr)); else G_warning(_("Unknown keyword '%s' in vector head"), buff); } fclose(head_fp); return 0; }
/* read old 3.0 or 4.0 dig file into array returns number of elements read into array or -1 on error */ int read_dig(FILE * Digin, struct Map_info *Mapout, struct Line **plines, int endian, int att) { char buf[100]; struct dig_head In_head; int lalloc, line = 0, type, portable = 1; int npoints = 0, nlines = 0, nbounds = 0; int ndpoints = 0, ndlines = 0, ndbounds = 0, nunknown = 0; struct Line *lines; struct line_pnts *nline; struct line_cats *cat_out; double dbuf; int ibuf; long lbuf; struct gvfile gvf; dig_file_init(&gvf); gvf.file = Digin; Vect__init_head(Mapout); /* set conversion matrices */ dig_init_portable(&(In_head.port), endian); /* Version 3 dig files were not portable and some version 4 * files may be also non portable */ G_message(_("Reading dig file...")); /* read and copy head */ dig_fseek(&gvf, 0L, SEEK_SET); /* set to beginning */ if (0 >= dig__fread_port_C(buf, DIG4_ORGAN_LEN, &gvf)) return -1; buf[DIG4_ORGAN_LEN - 1] = '\0'; Vect_set_organization(Mapout, buf); if (0 >= dig__fread_port_C(buf, DIG4_DATE_LEN, &gvf)) return -1; buf[DIG4_DATE_LEN - 1] = '\0'; Vect_set_date(Mapout, buf); if (0 >= dig__fread_port_C(buf, DIG4_YOUR_NAME_LEN, &gvf)) return -1; buf[DIG4_YOUR_NAME_LEN - 1] = '\0'; Vect_set_person(Mapout, buf); if (0 >= dig__fread_port_C(buf, DIG4_MAP_NAME_LEN, &gvf)) return -1; buf[DIG4_MAP_NAME_LEN - 1] = '\0'; Vect_set_map_name(Mapout, buf); if (0 >= dig__fread_port_C(buf, DIG4_SOURCE_DATE_LEN, &gvf)) return -1; buf[DIG4_SOURCE_DATE_LEN - 1] = '\0'; Vect_set_map_date(Mapout, buf); if (0 >= dig__fread_port_C(buf, DIG4_LINE_3_LEN, &gvf)) return -1; buf[DIG4_LINE_3_LEN - 1] = '\0'; Vect_set_comment(Mapout, buf); if (0 >= dig__fread_port_C(buf, VERS_4_DATA_SIZE, &gvf)) return -1; if (buf[0] != '%' || buf[1] != '%') { /* Version3.0 */ In_head.Version_Major = 3; portable = 0; /* input vector is not portable format */ G_message(_("Input file is version 3.")); } else { In_head.Version_Major = 4; G_message(_("Input file is version 4.")); /* determine if in portable format or not */ if (buf[6] == 1 && (~buf[6] & 0xff) == (buf[7] & 0xff)) { /* portable ? */ portable = 1; /* input vector is portable format */ } else { portable = 0; /* input vector is not portable format */ } } if (portable == 1) { G_message(_("Input file is portable.")); } else { G_warning(_("Input file is not portable. " "We will attempt to convert anyway but conversion may fail. " "Please read manual for detail information.")); } /* set Cur_Head because it is used by dig__*_convert() called by dig__fread_port_*() */ dig_set_cur_port(&(In_head.port)); if (0 >= dig__fread_port_L(&lbuf, 1, &gvf)) return -1; Vect_set_scale(Mapout, (int)lbuf); if (0 >= dig__fread_port_I(&ibuf, 1, &gvf)) return -1; Vect_set_zone(Mapout, ibuf); if (0 >= dig__fread_port_D(&dbuf, 1, &gvf)) return -1; /* W */ if (0 >= dig__fread_port_D(&dbuf, 1, &gvf)) return -1; /* E */ if (0 >= dig__fread_port_D(&dbuf, 1, &gvf)) return -1; /* S */ if (0 >= dig__fread_port_D(&dbuf, 1, &gvf)) return -1; /* N */ if (0 >= dig__fread_port_D(&dbuf, 1, &gvf)) return -1; Vect_set_thresh(Mapout, dbuf); /* reading dig file body (elements) */ nline = Vect_new_line_struct(); cat_out = Vect_new_cats_struct(); lalloc = 0; lines = NULL; line = 0; while (1) { type = read_line(&gvf, nline); G_debug(3, "read line = %d, type = %d", line, type); if (type == -2) break; /* EOF */ switch (type) { case GV_POINT: npoints++; break; case GV_LINE: nlines++; break; case GV_BOUNDARY: nbounds++; break; case 0: /* dead */ break; default: nunknown++; break; } if (!(type & (GV_POINT | GV_LINE | GV_BOUNDARY))) continue; if ((type & GV_BOUNDARY) || !att) { Vect_write_line(Mapout, type, nline, cat_out); /* reset In_head */ dig_set_cur_port(&(In_head.port)); } else { /* GV_POINT or GV_LINE */ if (line >= lalloc) { lalloc += 10000; lines = (struct Line *)G_realloc(lines, lalloc * sizeof(struct Line)); } lines[line].type = type; lines[line].n_points = nline->n_points; lines[line].cat = -1; lines[line].x = (double *)G_malloc(nline->n_points * sizeof(double)); lines[line].y = (double *)G_malloc(nline->n_points * sizeof(double)); memcpy((void *)lines[line].x, (void *)nline->x, nline->n_points * sizeof(double)); memcpy((void *)lines[line].y, (void *)nline->y, nline->n_points * sizeof(double)); line++; } } if (att) { G_message(_("[%d] points read to memory"), npoints); G_message(_("[%d] lines read to memory"), nlines); } else { G_message(_("[%d] points read and written to output"), npoints); G_message(_("[%d] lines read and written to output"), nlines); } G_message(_("[%d] area boundaries read and written to output"), nbounds); G_message(_("[%d] dead points skipped"), ndpoints); G_message(_("[%d] dead lines skipped"), ndlines); G_message(_("[%d] dead area boundaries skipped"), ndbounds); G_message(_("[%d] elements of unknown type skipped"), nunknown); G_message(_("[%d] elements read to memory"), line); *plines = lines; return (line); }