GRASS GIS 8 Programmer's Manual  8.5.0dev(2025)-27f6b88e55
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
vector/Vlib/header.c
Go to the documentation of this file.
1 /*!
2  \file lib/vector/Vlib/header.c
3 
4  \brief Vector library - header manipulation
5 
6  Higher level functions for reading/writing/manipulating vectors.
7 
8  (C) 2001-2010 by the GRASS Development Team
9 
10  This program is free software under the GNU General Public License
11  (>=v2). Read the file COPYING that comes with GRASS for details.
12 
13  \author Original author CERL, probably Dave Gerdes or Mike Higgins.
14  \author Update to GRASS 5.7 Radim Blazek and David D. Gray.
15  \author Update to GRASS 7 (OGR support) by Martin Landa <landa.martin
16  gmail.com>
17  */
18 
19 #include <stdlib.h>
20 #include <string.h>
21 #include <grass/vector.h>
22 #include <grass/glocale.h>
23 
24 #include "local_proto.h"
25 
26 /*!
27  \brief Print vector map header to stdout
28 
29  \param Map pointer to Map_info structure
30 
31  \return 0 on success
32  */
33 int Vect_print_header(struct Map_info *Map)
34 {
35  fprintf(stdout, "\nSelected information from dig header\n");
36  fprintf(stdout, " Organization: %s\n", Vect_get_organization(Map));
37  fprintf(stdout, " Map Name: %s\n", Vect_get_map_name(Map));
38  fprintf(stdout, " Source Date: %s\n", Vect_get_map_date(Map));
39  fprintf(stdout, " Orig. Scale: %d\n", Vect_get_scale(Map));
40 
41  return 0;
42 }
43 
44 /*!
45  \brief Read vector map header from map head file
46 
47  \param Map pointrt to Map_info structure
48 
49  \return 0
50  */
51 int Vect_read_header(struct Map_info *Map)
52 {
53  Vect__read_head(Map);
54  return 0;
55 }
56 
57 /*!
58  \brief Write vector map header to map head file
59 
60  \param Map pointer to Map_info structure
61 
62  \return 0
63  */
64 int Vect_write_header(struct Map_info *Map)
65 {
66  /* do some sanity checking here */
67  Vect__write_head(Map);
68  return 0;
69 }
70 
71 /*!
72  \brief Writes head information to text file (GV_HEAD_ELEMENT)
73 
74  \param Map pointer to Map_info structure
75 
76  \return 0 on success
77  \return -1 on error
78  */
79 int Vect__write_head(struct Map_info *Map)
80 {
81  char path[GPATH_MAX];
82  FILE *head_fp;
83 
84  Vect__get_path(path, Map);
85  head_fp = G_fopen_new(path, GV_HEAD_ELEMENT);
86  if (head_fp == NULL) {
87  const char *map_name = Vect_get_full_name(Map);
88  G_warning(_("Unable to create header file for vector map <%s>"),
89  map_name);
90  G_free((void *)map_name);
91  return -1;
92  }
93 
94  fprintf(head_fp, "ORGANIZATION: %s\n", Vect_get_organization(Map));
95  fprintf(head_fp, "DIGIT DATE: %s\n", Vect_get_date(Map));
96  fprintf(head_fp, "DIGIT NAME: %s\n", Vect_get_person(Map));
97  fprintf(head_fp, "MAP NAME: %s\n", Vect_get_map_name(Map));
98  fprintf(head_fp, "MAP DATE: %s\n", Vect_get_map_date(Map));
99  fprintf(head_fp, "MAP SCALE: %d\n", Vect_get_scale(Map));
100  fprintf(head_fp, "OTHER INFO: %s\n", Vect_get_comment(Map));
101  if (Vect_get_proj(Map) > 0)
102  fprintf(head_fp, "PROJ: %d\n", Vect_get_proj(Map));
103  fprintf(head_fp, "ZONE: %d\n", Vect_get_zone(Map));
104  fprintf(head_fp, "MAP THRESH: %f\n", Vect_get_thresh(Map));
105 
106  fclose(head_fp);
107 
108  return 0;
109 }
110 
111 /*!
112  \brief Reads head information from text file (GV_HEAD_ELEMENT) - for internal
113  use only
114 
115  \param Map pointer to Map_info structure
116 
117  \return 0 on success
118  \return -1 on error
119  */
120 int Vect__read_head(struct Map_info *Map)
121 {
122  FILE *head_fp;
123  char buff[2000];
124  char path[GPATH_MAX], *ptr;
125 
126  /* Reset / init */
127  Vect__init_head(Map);
128 
129  G_debug(1, "Vect__read_head(): vector = %s@%s", Map->name, Map->mapset);
130  Vect__get_path(path, Map);
131  head_fp = G_fopen_old(path, GV_HEAD_ELEMENT, Map->mapset);
132  if (head_fp == NULL) {
133  const char *map_name = Vect_get_full_name(Map);
134  G_warning(_("Unable to open header file of vector <%s>"), map_name);
135  G_free((void *)map_name);
136  return -1;
137  }
138 
139  while (G_getl2(buff, 2000, head_fp)) {
140 
141  if (!(ptr = strchr(buff, ':'))) {
142  G_warning(_("Corrupted row in head: %s"), buff);
143  continue;
144  }
145 
146  ptr++; /* Search for the start of text */
147  while (*ptr == ' ')
148  ptr++;
149 
150  if (strncmp(buff, "ORGANIZATION:", sizeof(char) * 13) == 0)
151  Vect_set_organization(Map, ptr);
152  else if (strncmp(buff, "DIGIT DATE:", sizeof(char) * 11) == 0)
153  Vect_set_date(Map, ptr);
154  else if (strncmp(buff, "DIGIT NAME:", sizeof(char) * 11) == 0)
155  Vect_set_person(Map, ptr);
156  else if (strncmp(buff, "MAP NAME:", sizeof(char) * 9) == 0)
157  Vect_set_map_name(Map, ptr);
158  else if (strncmp(buff, "MAP DATE:", sizeof(char) * 9) == 0)
159  Vect_set_map_date(Map, ptr);
160  else if (strncmp(buff, "MAP SCALE:", sizeof(char) * 10) == 0)
161  Vect_set_scale(Map, atoi(ptr));
162  else if (strncmp(buff, "OTHER INFO:", sizeof(char) * 11) == 0)
163  Vect_set_comment(Map, ptr);
164  else if (strncmp(buff, "PROJ:", sizeof(char) * 5) == 0)
165  Vect_set_proj(Map, atoi(ptr));
166  else if (strncmp(buff, "ZONE:", sizeof(char) * 5) == 0 ||
167  strncmp(buff, "UTM ZONE:", sizeof(char) * 9) == 0)
168  Vect_set_zone(Map, atoi(ptr));
169  else if (strncmp(buff, "WEST EDGE:", sizeof(char) * 10) == 0) {
170  }
171  else if (strncmp(buff, "EAST EDGE:", sizeof(char) * 10) == 0) {
172  }
173  else if (strncmp(buff, "SOUTH EDGE:", sizeof(char) * 11) == 0) {
174  }
175  else if (strncmp(buff, "NORTH EDGE:", sizeof(char) * 11) == 0) {
176  }
177  else if (strncmp(buff, "MAP THRESH:", sizeof(char) * 11) == 0)
178  Vect_set_thresh(Map, atof(ptr));
179  else
180  G_warning(_("Unknown keyword '%s' in vector head"), buff);
181  }
182 
183  fclose(head_fp);
184 
185  return 0;
186 }
187 
188 /*!
189  \brief Get name of vector map
190 
191  \param Map pointer to Map_info structure
192 
193  \return string containing name
194  */
195 const char *Vect_get_name(struct Map_info *Map)
196 {
197  return Map->name;
198 }
199 
200 /*!
201  \brief Get name of mapset where vector map lives
202 
203  \param Map pointer to Map_info structure
204 
205  \return string containing mapset name
206  */
207 const char *Vect_get_mapset(struct Map_info *Map)
208 {
209  return Map->mapset;
210 }
211 
212 /*!
213  \brief Get fully qualified name of vector map
214 
215  - for GV_FORMAT_NATIVE and GV_FORMAT_OGR returns "map@mapset"
216  - for GV_FORMAT_OGR_DIRECT returns "layer@datasourse"
217 
218  Allocated string should be freed by G_free().
219 
220  \param Map pointer to Map_info structure
221 
222  \return allocated string "name@mapset"
223  */
224 const char *Vect_get_full_name(struct Map_info *Map)
225 {
226  char *ptr;
227  size_t len;
228 
229  if (Map->format == GV_FORMAT_OGR_DIRECT && Map->fInfo.ogr.dsn &&
230  Map->fInfo.ogr.layer_name) {
231  len =
232  strlen(Map->fInfo.ogr.layer_name) + strlen(Map->fInfo.ogr.dsn) + 2;
233  ptr = (char *)G_malloc(len);
234  snprintf(ptr, len, "%s@%s", Map->fInfo.ogr.layer_name,
235  Map->fInfo.ogr.dsn);
236 
237  return ptr;
238  }
239 
240  len = strlen(Map->name) + strlen(Map->mapset) + 2;
241  ptr = (char *)G_malloc(len);
242  if (strlen(Map->mapset) > 0) {
243  snprintf(ptr, len, "%s@%s", Map->name, Map->mapset);
244  }
245  else {
246  snprintf(ptr, len, "%s", Map->name);
247  }
248 
249  return ptr;
250 }
251 
252 /*!
253  \brief Check if vector map is 3D
254 
255  Check vector map header.
256 
257  \param Map pointer to Map_info structure
258 
259  \return TRUE vector map is 3D
260  \return FALSE vector map is not 3D
261  */
262 int Vect_is_3d(struct Map_info *Map)
263 {
264  return Map->head.with_z;
265 }
266 
267 /*!
268  \brief Set organization string in map header
269 
270  \param Map pointer to Map_info structure
271  \param str organization name
272 
273  \return 0
274  */
275 int Vect_set_organization(struct Map_info *Map, const char *str)
276 {
277  G_free(Map->head.organization);
278  Map->head.organization = G_store(str);
279 
280  return 0;
281 }
282 
283 /*!
284  \brief Get organization string from map header
285 
286  \param Map pointer to Map_info structure
287 
288  \return string containing organization name
289  */
290 const char *Vect_get_organization(struct Map_info *Map)
291 {
292  return Map->head.organization;
293 }
294 
295 /*!
296  \brief Set date of digitization in map header
297 
298  \todo This should be coupled to DateTime functions to support
299  time series
300 
301  \param Map pointer to Map_info structure
302  \param str date given as string
303 
304  \return 0
305  */
306 int Vect_set_date(struct Map_info *Map, const char *str)
307 {
308  G_free(Map->head.date);
309  Map->head.date = G_store(str);
310 
311  return 0;
312 }
313 
314 /*!
315  \brief Get date of digitization from map header
316 
317  \param Map pointer to Map_info structure
318 
319  \return date of digitization string
320  */
321 const char *Vect_get_date(struct Map_info *Map)
322 {
323  return (Map->head.date);
324 }
325 
326 /*!
327  \brief Set name of user who digitized the map in map header
328 
329  \param Map pointer to Map_info structure
330  \param str user name
331 
332  \return 0
333  */
334 int Vect_set_person(struct Map_info *Map, const char *str)
335 {
336  G_free(Map->head.user_name);
337  Map->head.user_name = G_store(str);
338 
339  return 0;
340 }
341 
342 /*!
343  \brief Get user name string who digitized the map from map header
344 
345  \param Map pointer to Map_info structure
346 
347  \return string containing user name
348  */
349 const char *Vect_get_person(struct Map_info *Map)
350 {
351  return (Map->head.user_name);
352 }
353 
354 /*!
355  \brief Set map name in map header
356 
357  \param Map pointer to Map_info structure
358  \param str map name to be set
359 
360  \return 0
361  */
362 int Vect_set_map_name(struct Map_info *Map, const char *str)
363 {
364  G_free(Map->head.map_name);
365  Map->head.map_name = G_store(str);
366 
367  return 0;
368 }
369 
370 /*!
371  \brief Get map name from map header
372 
373  \param Map pointer to Map_info structure
374 
375  \return string containing map name
376  */
377 const char *Vect_get_map_name(struct Map_info *Map)
378 {
379  return Map->head.map_name;
380 }
381 
382 /*!
383  \brief Set date when the source map was originally produced in map header
384 
385  \param Map pointer to Map_info structure
386  \param str date given as a string
387 
388  \return 0
389  */
390 int Vect_set_map_date(struct Map_info *Map, const char *str)
391 {
392  G_free(Map->head.source_date);
393  Map->head.source_date = G_store(str);
394 
395  return 0;
396 }
397 
398 /*!
399  \brief Get date when the source map was originally produced from map header
400 
401  \param Map pointer to Map_info structure
402 
403  \return string containing a date
404  */
405 const char *Vect_get_map_date(struct Map_info *Map)
406 {
407  return Map->head.source_date;
408 }
409 
410 /*!
411  \brief Set map scale in map header
412 
413  \param Map pointer to Map_info structure
414  \param scale map scale
415 
416  \return 0
417  */
418 int Vect_set_scale(struct Map_info *Map, int scale)
419 {
420  Map->head.orig_scale = scale;
421 
422  return 0;
423 }
424 
425 /*!
426  \brief Get map scale from map header
427 
428  \param Map pointer to Map_info structure
429 
430  \return map scale
431  */
432 int Vect_get_scale(struct Map_info *Map)
433 {
434  return (int)Map->head.orig_scale;
435 }
436 
437 /*!
438  \brief Set comment or other info string in map header
439 
440  \param Map pointer to Map_info structure
441  \param str comment or other info string
442 
443  \return 0
444  */
445 int Vect_set_comment(struct Map_info *Map, const char *str)
446 {
447  G_free(Map->head.comment);
448  Map->head.comment = G_store(str);
449 
450  return 0;
451 }
452 
453 /*!
454  \brief Get comment or other info string from map header
455 
456  \param Map pointer to Map_info structure
457 
458  \return comment or other info string
459  */
460 const char *Vect_get_comment(struct Map_info *Map)
461 {
462  return (Map->head.comment);
463 }
464 
465 /*!
466  \brief Set projection zone in map header
467 
468  \param Map pointer to Map_info structure
469  \param zone projection zone
470 
471  \return 0
472  */
473 int Vect_set_zone(struct Map_info *Map, int zone)
474 {
475  Map->head.plani_zone = zone;
476 
477  return 0;
478 }
479 
480 /*!
481  \brief Get projection zone from map header
482 
483  \param Map pointer to Map_info structure (unused, returns the zone for
484  the active region)
485 
486  \return projection zone
487  */
488 int Vect_get_zone(struct Map_info *Map UNUSED)
489 {
490  /* return Map->head.plani_zone; */
491 
492  /* use utm zone of current location,
493  * a vector in a given location can not be in a different CRS */
494  return G_zone();
495 }
496 
497 /*!
498  \brief Set projection in map header
499 
500  Supported projections:
501  - PROJECTION_XY 0 - x,y (Raw imagery),
502  - PROJECTION_UTM 1 - UTM Universal Transverse Mercator,
503  - PROJECTION_LL 3 - Latitude-Longitude
504 
505  \param Map pointer to Map_info structure
506  \param proj projection code
507 
508  \return 0
509  */
510 int Vect_set_proj(struct Map_info *Map, int proj)
511 {
512  Map->head.proj = proj;
513 
514  return 0;
515 }
516 
517 /*!
518  \brief Get projection from map header
519 
520  \param Map pointer to Map_info structure
521 
522  \return PROJECTION_XY 0 - x,y (Raw imagery),
523  \return PROJECTION_UTM 1 - UTM Universal Transverse Mercator,
524  \return PROJECTION_LL 3 - Latitude-Longitude
525  */
526 int Vect_get_proj(struct Map_info *Map)
527 {
528  return (Map->head.proj);
529 }
530 
531 /*!
532  \brief Query cartographic projection name of pointer to Map_info structure
533 
534  Returns a pointer to a string which is a printable name for
535  projection code <em>proj</em> (as returned by Vect_get_proj()).
536 
537  \param Map pointer to Map_info structure
538 
539  \return allocated string containing projection name
540  \return NULL if <em>proj</em> is not a valid projection
541  */
542 
543 const char *Vect_get_proj_name(struct Map_info *Map)
544 {
545  char name[256];
546  int n;
547 
548  switch (n = Vect_get_proj(Map)) {
549  case PROJECTION_XY:
550  case PROJECTION_UTM:
551  case PROJECTION_LL:
552  return G_projection_name(n);
553  case PROJECTION_OTHER:
554  /* this won't protect against differing "other" projections, so
555  better to just include P_OTHER in the above list so we return the
556  strictly more correct, but less nice, string: "Other projection" ? */
558  default:
559  G_debug(1,
560  "Vect_get_proj_name(): "
561  "Vect_get_proj() returned an invalid result (%d)",
562  n);
563  break;
564  }
565 
566  strcpy(name, _("Unknown projection"));
567  return G_store(name);
568 }
569 
570 /*!
571  \brief Set threshold used for digitization in map header
572 
573  \param Map pointer to Map_info structure
574  \param thresh threshold used for digitization
575 
576  \return 0
577  */
578 int Vect_set_thresh(struct Map_info *Map, double thresh)
579 {
580  G_debug(1, "Vect_set_thresh(): thresh = %f", thresh);
581  Map->head.digit_thresh = thresh;
582  return 0;
583 }
584 
585 /*!
586  \brief Get threshold used for digitization from map header
587 
588  \param Map pointer to Map_info structure
589 
590  \return threshold used for digitization
591  */
592 double Vect_get_thresh(struct Map_info *Map)
593 {
594  return Map->head.digit_thresh;
595 }
#define NULL
Definition: ccmath.h:32
FILE * G_fopen_old(const char *, const char *, const char *)
Open a database file for reading.
Definition: gis/open.c:251
int G_getl2(char *, int, FILE *)
Gets a line of text from a file of any pedigree.
Definition: getl.c:60
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:150
const char * G_database_projection_name(void)
Query cartographic projection for the current location.
Definition: proj3.c:118
void G_warning(const char *,...) __attribute__((format(printf
#define G_malloc(n)
Definition: defs/gis.h:94
const char * G_projection_name(int)
Get projection name.
Definition: proj2.c:55
int G_zone(void)
Query cartographic zone.
Definition: zone.c:24
int G_debug(int, const char *,...) __attribute__((format(printf
char * G_store(const char *)
Copy string to allocated memory.
Definition: strings.c:87
FILE * G_fopen_new(const char *, const char *)
Open a new database file.
Definition: gis/open.c:219
void Vect__init_head(struct Map_info *)
Initialize Map_info head structure (dig_head)
Definition: init_head.c:29
#define GV_FORMAT_OGR_DIRECT
OGR format (direct access)
Definition: dig_defines.h:87
#define GV_HEAD_ELEMENT
Native format, header information.
Definition: dig_defines.h:14
#define PROJECTION_OTHER
Projection code - other projection (other then noted above)
Definition: gis.h:131
#define PROJECTION_XY
Projection code - XY coordinate system (unreferenced data)
Definition: gis.h:123
#define GPATH_MAX
Definition: gis.h:199
#define PROJECTION_UTM
Projection code - UTM.
Definition: gis.h:125
#define PROJECTION_LL
Projection code - Latitude-Longitude.
Definition: gis.h:129
#define UNUSED
A macro for an attribute, if attached to a variable, indicating that the variable is not used.
Definition: gis.h:46
#define _(str)
Definition: glocale.h:10
const char * name
Definition: named_colr.c:6
#define strcpy
Definition: parson.c:62
char * dsn
OGR datasource name.
Definition: dig_structs.h:513
char * layer_name
OGR layer name.
Definition: dig_structs.h:517
struct Format_info_ogr ogr
OGR info.
Definition: dig_structs.h:708
Vector map info.
Definition: dig_structs.h:1243
char * mapset
Mapset name.
Definition: dig_structs.h:1320
struct dig_head head
Header info.
Definition: dig_structs.h:1388
char * name
Map name (for 4.0)
Definition: dig_structs.h:1316
int format
Map format (native, ogr, postgis)
Definition: dig_structs.h:1255
struct Format_info fInfo
Format info for non-native formats.
Definition: dig_structs.h:1400
char * date
Map date.
Definition: dig_structs.h:295
long orig_scale
Original scale.
Definition: dig_structs.h:311
int plani_zone
Zone (UTM only)
Definition: dig_structs.h:321
double digit_thresh
Threshold for digitization.
Definition: dig_structs.h:325
char * organization
Organization name.
Definition: dig_structs.h:291
int with_z
2D/3D vector data
Definition: dig_structs.h:339
char * comment
Comments.
Definition: dig_structs.h:315
char * user_name
User name.
Definition: dig_structs.h:299
char * source_date
Source date.
Definition: dig_structs.h:307
char * map_name
Map name.
Definition: dig_structs.h:303
Definition: path.h:15
int Vect_set_person(struct Map_info *Map, const char *str)
Set name of user who digitized the map in map header.
const char * Vect_get_name(struct Map_info *Map)
Get name of vector map.
int Vect_print_header(struct Map_info *Map)
Print vector map header to stdout.
const char * Vect_get_map_name(struct Map_info *Map)
Get map name from map header.
int Vect_set_map_date(struct Map_info *Map, const char *str)
Set date when the source map was originally produced in map header.
int Vect_is_3d(struct Map_info *Map)
Check if vector map is 3D.
const char * Vect_get_comment(struct Map_info *Map)
Get comment or other info string from map header.
const char * Vect_get_mapset(struct Map_info *Map)
Get name of mapset where vector map lives.
int Vect_set_organization(struct Map_info *Map, const char *str)
Set organization string in map header.
const char * Vect_get_organization(struct Map_info *Map)
Get organization string from map header.
const char * Vect_get_person(struct Map_info *Map)
Get user name string who digitized the map from map header.
const char * Vect_get_map_date(struct Map_info *Map)
Get date when the source map was originally produced from map header.
int Vect_set_thresh(struct Map_info *Map, double thresh)
Set threshold used for digitization in map header.
int Vect__read_head(struct Map_info *Map)
Reads head information from text file (GV_HEAD_ELEMENT) - for internal use only.
int Vect_set_map_name(struct Map_info *Map, const char *str)
Set map name in map header.
int Vect_set_comment(struct Map_info *Map, const char *str)
Set comment or other info string in map header.
int Vect_get_proj(struct Map_info *Map)
Get projection from map header.
int Vect_set_scale(struct Map_info *Map, int scale)
Set map scale in map header.
int Vect_set_zone(struct Map_info *Map, int zone)
Set projection zone in map header.
int Vect_set_proj(struct Map_info *Map, int proj)
Set projection in map header.
const char * Vect_get_proj_name(struct Map_info *Map)
Query cartographic projection name of pointer to Map_info structure.
int Vect_read_header(struct Map_info *Map)
Read vector map header from map head file.
int Vect_set_date(struct Map_info *Map, const char *str)
Set date of digitization in map header.
const char * Vect_get_full_name(struct Map_info *Map)
Get fully qualified name of vector map.
int Vect_write_header(struct Map_info *Map)
Write vector map header to map head file.
int Vect__write_head(struct Map_info *Map)
Writes head information to text file (GV_HEAD_ELEMENT)
const char * Vect_get_date(struct Map_info *Map)
Get date of digitization from map header.
int Vect_get_zone(struct Map_info *Map UNUSED)
Get projection zone from map header.
double Vect_get_thresh(struct Map_info *Map)
Get threshold used for digitization from map header.
int Vect_get_scale(struct Map_info *Map)
Get map scale from map header.
char * Vect__get_path(char *path, struct Map_info *Map)
Get map directory name (internal use only)