GRASS GIS 8 Programmer's Manual  8.5.0dev(2025)-299a28a7d0
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  G_warning(_("Unable to create header file for vector map <%s>"),
88  Vect_get_full_name(Map));
89  return -1;
90  }
91 
92  fprintf(head_fp, "ORGANIZATION: %s\n", Vect_get_organization(Map));
93  fprintf(head_fp, "DIGIT DATE: %s\n", Vect_get_date(Map));
94  fprintf(head_fp, "DIGIT NAME: %s\n", Vect_get_person(Map));
95  fprintf(head_fp, "MAP NAME: %s\n", Vect_get_map_name(Map));
96  fprintf(head_fp, "MAP DATE: %s\n", Vect_get_map_date(Map));
97  fprintf(head_fp, "MAP SCALE: %d\n", Vect_get_scale(Map));
98  fprintf(head_fp, "OTHER INFO: %s\n", Vect_get_comment(Map));
99  if (Vect_get_proj(Map) > 0)
100  fprintf(head_fp, "PROJ: %d\n", Vect_get_proj(Map));
101  fprintf(head_fp, "ZONE: %d\n", Vect_get_zone(Map));
102  fprintf(head_fp, "MAP THRESH: %f\n", Vect_get_thresh(Map));
103 
104  fclose(head_fp);
105 
106  return 0;
107 }
108 
109 /*!
110  \brief Reads head information from text file (GV_HEAD_ELEMENT) - for internal
111  use only
112 
113  \param Map pointer to Map_info structure
114 
115  \return 0 on success
116  \return -1 on error
117  */
118 int Vect__read_head(struct Map_info *Map)
119 {
120  FILE *head_fp;
121  char buff[2000];
122  char path[GPATH_MAX], *ptr;
123 
124  /* Reset / init */
125  Vect__init_head(Map);
126 
127  G_debug(1, "Vect__read_head(): vector = %s@%s", Map->name, Map->mapset);
128  Vect__get_path(path, Map);
129  head_fp = G_fopen_old(path, GV_HEAD_ELEMENT, Map->mapset);
130  if (head_fp == NULL) {
131  G_warning(_("Unable to open header file of vector <%s>"),
132  Vect_get_full_name(Map));
133  return -1;
134  }
135 
136  while (G_getl2(buff, 2000, head_fp)) {
137 
138  if (!(ptr = strchr(buff, ':'))) {
139  G_warning(_("Corrupted row in head: %s"), buff);
140  continue;
141  }
142 
143  ptr++; /* Search for the start of text */
144  while (*ptr == ' ')
145  ptr++;
146 
147  if (strncmp(buff, "ORGANIZATION:", sizeof(char) * 13) == 0)
148  Vect_set_organization(Map, ptr);
149  else if (strncmp(buff, "DIGIT DATE:", sizeof(char) * 11) == 0)
150  Vect_set_date(Map, ptr);
151  else if (strncmp(buff, "DIGIT NAME:", sizeof(char) * 11) == 0)
152  Vect_set_person(Map, ptr);
153  else if (strncmp(buff, "MAP NAME:", sizeof(char) * 9) == 0)
154  Vect_set_map_name(Map, ptr);
155  else if (strncmp(buff, "MAP DATE:", sizeof(char) * 9) == 0)
156  Vect_set_map_date(Map, ptr);
157  else if (strncmp(buff, "MAP SCALE:", sizeof(char) * 10) == 0)
158  Vect_set_scale(Map, atoi(ptr));
159  else if (strncmp(buff, "OTHER INFO:", sizeof(char) * 11) == 0)
160  Vect_set_comment(Map, ptr);
161  else if (strncmp(buff, "PROJ:", sizeof(char) * 5) == 0)
162  Vect_set_proj(Map, atoi(ptr));
163  else if (strncmp(buff, "ZONE:", sizeof(char) * 5) == 0 ||
164  strncmp(buff, "UTM ZONE:", sizeof(char) * 9) == 0)
165  Vect_set_zone(Map, atoi(ptr));
166  else if (strncmp(buff, "WEST EDGE:", sizeof(char) * 10) == 0) {
167  }
168  else if (strncmp(buff, "EAST EDGE:", sizeof(char) * 10) == 0) {
169  }
170  else if (strncmp(buff, "SOUTH EDGE:", sizeof(char) * 11) == 0) {
171  }
172  else if (strncmp(buff, "NORTH EDGE:", sizeof(char) * 11) == 0) {
173  }
174  else if (strncmp(buff, "MAP THRESH:", sizeof(char) * 11) == 0)
175  Vect_set_thresh(Map, atof(ptr));
176  else
177  G_warning(_("Unknown keyword '%s' in vector head"), buff);
178  }
179 
180  fclose(head_fp);
181 
182  return 0;
183 }
184 
185 /*!
186  \brief Get name of vector map
187 
188  \param Map pointer to Map_info structure
189 
190  \return string containing name
191  */
192 const char *Vect_get_name(struct Map_info *Map)
193 {
194  return Map->name;
195 }
196 
197 /*!
198  \brief Get name of mapset where vector map lives
199 
200  \param Map pointer to Map_info structure
201 
202  \return string containing mapset name
203  */
204 const char *Vect_get_mapset(struct Map_info *Map)
205 {
206  return Map->mapset;
207 }
208 
209 /*!
210  \brief Get fully qualified name of vector map
211 
212  - for GV_FORMAT_NATIVE and GV_FORMAT_OGR returns "map@mapset"
213  - for GV_FORMAT_OGR_DIRECT returns "layer@datasourse"
214 
215  Allocated string should be freed by G_free().
216 
217  \param Map pointer to Map_info structure
218 
219  \return allocated string "name@mapset"
220  */
221 const char *Vect_get_full_name(struct Map_info *Map)
222 {
223  char *ptr;
224  size_t len;
225 
226  if (Map->format == GV_FORMAT_OGR_DIRECT && Map->fInfo.ogr.dsn &&
227  Map->fInfo.ogr.layer_name) {
228  len =
229  strlen(Map->fInfo.ogr.layer_name) + strlen(Map->fInfo.ogr.dsn) + 2;
230  ptr = (char *)G_malloc(len);
231  snprintf(ptr, len, "%s@%s", Map->fInfo.ogr.layer_name,
232  Map->fInfo.ogr.dsn);
233 
234  return ptr;
235  }
236 
237  len = strlen(Map->name) + strlen(Map->mapset) + 2;
238  ptr = (char *)G_malloc(len);
239  if (strlen(Map->mapset) > 0) {
240  snprintf(ptr, len, "%s@%s", Map->name, Map->mapset);
241  }
242  else {
243  snprintf(ptr, len, "%s", Map->name);
244  }
245 
246  return ptr;
247 }
248 
249 /*!
250  \brief Check if vector map is 3D
251 
252  Check vector map header.
253 
254  \param Map pointer to Map_info structure
255 
256  \return TRUE vector map is 3D
257  \return FALSE vector map is not 3D
258  */
259 int Vect_is_3d(struct Map_info *Map)
260 {
261  return Map->head.with_z;
262 }
263 
264 /*!
265  \brief Set organization string in map header
266 
267  \param Map pointer to Map_info structure
268  \param str organization name
269 
270  \return 0
271  */
272 int Vect_set_organization(struct Map_info *Map, const char *str)
273 {
274  G_free(Map->head.organization);
275  Map->head.organization = G_store(str);
276 
277  return 0;
278 }
279 
280 /*!
281  \brief Get organization string from map header
282 
283  \param Map pointer to Map_info structure
284 
285  \return string containing organization name
286  */
287 const char *Vect_get_organization(struct Map_info *Map)
288 {
289  return Map->head.organization;
290 }
291 
292 /*!
293  \brief Set date of digitization in map header
294 
295  \todo This should be coupled to DateTime functions to support
296  time series
297 
298  \param Map pointer to Map_info structure
299  \param str date given as string
300 
301  \return 0
302  */
303 int Vect_set_date(struct Map_info *Map, const char *str)
304 {
305  G_free(Map->head.date);
306  Map->head.date = G_store(str);
307 
308  return 0;
309 }
310 
311 /*!
312  \brief Get date of digitization from map header
313 
314  \param Map pointer to Map_info structure
315 
316  \return date of digitization string
317  */
318 const char *Vect_get_date(struct Map_info *Map)
319 {
320  return (Map->head.date);
321 }
322 
323 /*!
324  \brief Set name of user who digitized the map in map header
325 
326  \param Map pointer to Map_info structure
327  \param str user name
328 
329  \return 0
330  */
331 int Vect_set_person(struct Map_info *Map, const char *str)
332 {
333  G_free(Map->head.user_name);
334  Map->head.user_name = G_store(str);
335 
336  return 0;
337 }
338 
339 /*!
340  \brief Get user name string who digitized the map from map header
341 
342  \param Map pointer to Map_info structure
343 
344  \return string containing user name
345  */
346 const char *Vect_get_person(struct Map_info *Map)
347 {
348  return (Map->head.user_name);
349 }
350 
351 /*!
352  \brief Set map name in map header
353 
354  \param Map pointer to Map_info structure
355  \param str map name to be set
356 
357  \return 0
358  */
359 int Vect_set_map_name(struct Map_info *Map, const char *str)
360 {
361  G_free(Map->head.map_name);
362  Map->head.map_name = G_store(str);
363 
364  return 0;
365 }
366 
367 /*!
368  \brief Get map name from map header
369 
370  \param Map pointer to Map_info structure
371 
372  \return string containing map name
373  */
374 const char *Vect_get_map_name(struct Map_info *Map)
375 {
376  return Map->head.map_name;
377 }
378 
379 /*!
380  \brief Set date when the source map was originally produced in map header
381 
382  \param Map pointer to Map_info structure
383  \param str date given as a string
384 
385  \return 0
386  */
387 int Vect_set_map_date(struct Map_info *Map, const char *str)
388 {
389  G_free(Map->head.source_date);
390  Map->head.source_date = G_store(str);
391 
392  return 0;
393 }
394 
395 /*!
396  \brief Get date when the source map was originally produced from map header
397 
398  \param Map pointer to Map_info structure
399 
400  \return string containing a date
401  */
402 const char *Vect_get_map_date(struct Map_info *Map)
403 {
404  return Map->head.source_date;
405 }
406 
407 /*!
408  \brief Set map scale in map header
409 
410  \param Map pointer to Map_info structure
411  \param scale map scale
412 
413  \return 0
414  */
415 int Vect_set_scale(struct Map_info *Map, int scale)
416 {
417  Map->head.orig_scale = scale;
418 
419  return 0;
420 }
421 
422 /*!
423  \brief Get map scale from map header
424 
425  \param Map pointer to Map_info structure
426 
427  \return map scale
428  */
429 int Vect_get_scale(struct Map_info *Map)
430 {
431  return (int)Map->head.orig_scale;
432 }
433 
434 /*!
435  \brief Set comment or other info string in map header
436 
437  \param Map pointer to Map_info structure
438  \param str comment or other info string
439 
440  \return 0
441  */
442 int Vect_set_comment(struct Map_info *Map, const char *str)
443 {
444  G_free(Map->head.comment);
445  Map->head.comment = G_store(str);
446 
447  return 0;
448 }
449 
450 /*!
451  \brief Get comment or other info string from map header
452 
453  \param Map pointer to Map_info structure
454 
455  \return comment or other info string
456  */
457 const char *Vect_get_comment(struct Map_info *Map)
458 {
459  return (Map->head.comment);
460 }
461 
462 /*!
463  \brief Set projection zone in map header
464 
465  \param Map pointer to Map_info structure
466  \param zone projection zone
467 
468  \return 0
469  */
470 int Vect_set_zone(struct Map_info *Map, int zone)
471 {
472  Map->head.plani_zone = zone;
473 
474  return 0;
475 }
476 
477 /*!
478  \brief Get projection zone from map header
479 
480  \param Map pointer to Map_info structure (unused, returns the zone for
481  the active region)
482 
483  \return projection zone
484  */
485 int Vect_get_zone(struct Map_info *Map UNUSED)
486 {
487  /* return Map->head.plani_zone; */
488 
489  /* use utm zone of current location,
490  * a vector in a given location can not be in a different CRS */
491  return G_zone();
492 }
493 
494 /*!
495  \brief Set projection in map header
496 
497  Supported projections:
498  - PROJECTION_XY 0 - x,y (Raw imagery),
499  - PROJECTION_UTM 1 - UTM Universal Transverse Mercator,
500  - PROJECTION_LL 3 - Latitude-Longitude
501 
502  \param Map pointer to Map_info structure
503  \param proj projection code
504 
505  \return 0
506  */
507 int Vect_set_proj(struct Map_info *Map, int proj)
508 {
509  Map->head.proj = proj;
510 
511  return 0;
512 }
513 
514 /*!
515  \brief Get projection from map header
516 
517  \param Map pointer to Map_info structure
518 
519  \return PROJECTION_XY 0 - x,y (Raw imagery),
520  \return PROJECTION_UTM 1 - UTM Universal Transverse Mercator,
521  \return PROJECTION_LL 3 - Latitude-Longitude
522  */
523 int Vect_get_proj(struct Map_info *Map)
524 {
525  return (Map->head.proj);
526 }
527 
528 /*!
529  \brief Query cartographic projection name of pointer to Map_info structure
530 
531  Returns a pointer to a string which is a printable name for
532  projection code <em>proj</em> (as returned by Vect_get_proj()).
533 
534  \param Map pointer to Map_info structure
535 
536  \return allocated string containing projection name
537  \return NULL if <em>proj</em> is not a valid projection
538  */
539 
540 const char *Vect_get_proj_name(struct Map_info *Map)
541 {
542  char name[256];
543  int n;
544 
545  switch (n = Vect_get_proj(Map)) {
546  case PROJECTION_XY:
547  case PROJECTION_UTM:
548  case PROJECTION_LL:
549  return G_projection_name(n);
550  case PROJECTION_OTHER:
551  /* this won't protect against differing "other" projections, so
552  better to just include P_OTHER in the above list so we return the
553  strictly more correct, but less nice, string: "Other projection" ? */
555  default:
556  G_debug(1,
557  "Vect_get_proj_name(): "
558  "Vect_get_proj() returned an invalid result (%d)",
559  n);
560  break;
561  }
562 
563  strcpy(name, _("Unknown projection"));
564  return G_store(name);
565 }
566 
567 /*!
568  \brief Set threshold used for digitization in map header
569 
570  \param Map pointer to Map_info structure
571  \param thresh threshold used for digitization
572 
573  \return 0
574  */
575 int Vect_set_thresh(struct Map_info *Map, double thresh)
576 {
577  G_debug(1, "Vect_set_thresh(): thresh = %f", thresh);
578  Map->head.digit_thresh = thresh;
579  return 0;
580 }
581 
582 /*!
583  \brief Get threshold used for digitization from map header
584 
585  \param Map pointer to Map_info structure
586 
587  \return threshold used for digitization
588  */
589 double Vect_get_thresh(struct Map_info *Map)
590 {
591  return Map->head.digit_thresh;
592 }
#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:193
#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)