GRASS GIS 8 Programmer's Manual  8.5.0dev(2024)-602118adcc
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 
225  if (Map->format == GV_FORMAT_OGR_DIRECT && Map->fInfo.ogr.dsn &&
226  Map->fInfo.ogr.layer_name) {
227  ptr = (char *)G_malloc(strlen(Map->fInfo.ogr.layer_name) +
228  strlen(Map->fInfo.ogr.dsn) + 2);
229  sprintf(ptr, "%s@%s", Map->fInfo.ogr.layer_name, Map->fInfo.ogr.dsn);
230 
231  return ptr;
232  }
233 
234  ptr = (char *)G_malloc(strlen(Map->name) + strlen(Map->mapset) + 2);
235  if (strlen(Map->mapset) > 0) {
236  sprintf(ptr, "%s@%s", Map->name, Map->mapset);
237  }
238  else {
239  sprintf(ptr, "%s", Map->name);
240  }
241 
242  return ptr;
243 }
244 
245 /*!
246  \brief Check if vector map is 3D
247 
248  Check vector map header.
249 
250  \param Map pointer to Map_info structure
251 
252  \return TRUE vector map is 3D
253  \return FALSE vector map is not 3D
254  */
255 int Vect_is_3d(struct Map_info *Map)
256 {
257  return Map->head.with_z;
258 }
259 
260 /*!
261  \brief Set organization string in map header
262 
263  \param Map pointer to Map_info structure
264  \param str organization name
265 
266  \return 0
267  */
268 int Vect_set_organization(struct Map_info *Map, const char *str)
269 {
270  G_free(Map->head.organization);
271  Map->head.organization = G_store(str);
272 
273  return 0;
274 }
275 
276 /*!
277  \brief Get organization string from map header
278 
279  \param Map pointer to Map_info structure
280 
281  \return string containing organization name
282  */
283 const char *Vect_get_organization(struct Map_info *Map)
284 {
285  return Map->head.organization;
286 }
287 
288 /*!
289  \brief Set date of digitization in map header
290 
291  \todo This should be coupled to DateTime functions to support
292  time series
293 
294  \param Map pointer to Map_info structure
295  \param str date given as string
296 
297  \return 0
298  */
299 int Vect_set_date(struct Map_info *Map, const char *str)
300 {
301  G_free(Map->head.date);
302  Map->head.date = G_store(str);
303 
304  return 0;
305 }
306 
307 /*!
308  \brief Get date of digitization from map header
309 
310  \param Map pointer to Map_info structure
311 
312  \return date of digitization string
313  */
314 const char *Vect_get_date(struct Map_info *Map)
315 {
316  return (Map->head.date);
317 }
318 
319 /*!
320  \brief Set name of user who digitized the map in map header
321 
322  \param Map pointer to Map_info structure
323  \param str user name
324 
325  \return 0
326  */
327 int Vect_set_person(struct Map_info *Map, const char *str)
328 {
329  G_free(Map->head.user_name);
330  Map->head.user_name = G_store(str);
331 
332  return 0;
333 }
334 
335 /*!
336  \brief Get user name string who digitized the map from map header
337 
338  \param Map pointer to Map_info structure
339 
340  \return string containing user name
341  */
342 const char *Vect_get_person(struct Map_info *Map)
343 {
344  return (Map->head.user_name);
345 }
346 
347 /*!
348  \brief Set map name in map header
349 
350  \param Map pointer to Map_info structure
351  \param str map name to be set
352 
353  \return 0
354  */
355 int Vect_set_map_name(struct Map_info *Map, const char *str)
356 {
357  G_free(Map->head.map_name);
358  Map->head.map_name = G_store(str);
359 
360  return 0;
361 }
362 
363 /*!
364  \brief Get map name from map header
365 
366  \param Map pointer to Map_info structure
367 
368  \return string containing map name
369  */
370 const char *Vect_get_map_name(struct Map_info *Map)
371 {
372  return Map->head.map_name;
373 }
374 
375 /*!
376  \brief Set date when the source map was originally produced in map header
377 
378  \param Map pointer to Map_info structure
379  \param str date given as a string
380 
381  \return 0
382  */
383 int Vect_set_map_date(struct Map_info *Map, const char *str)
384 {
385  G_free(Map->head.source_date);
386  Map->head.source_date = G_store(str);
387 
388  return 0;
389 }
390 
391 /*!
392  \brief Get date when the source map was originally produced from map header
393 
394  \param Map pointer to Map_info structure
395 
396  \return string containing a date
397  */
398 const char *Vect_get_map_date(struct Map_info *Map)
399 {
400  return Map->head.source_date;
401 }
402 
403 /*!
404  \brief Set map scale in map header
405 
406  \param Map pointer to Map_info structure
407  \param scale map scale
408 
409  \return 0
410  */
411 int Vect_set_scale(struct Map_info *Map, int scale)
412 {
413  Map->head.orig_scale = scale;
414 
415  return 0;
416 }
417 
418 /*!
419  \brief Get map scale from map header
420 
421  \param Map pointer to Map_info structure
422 
423  \return map scale
424  */
425 int Vect_get_scale(struct Map_info *Map)
426 {
427  return (int)Map->head.orig_scale;
428 }
429 
430 /*!
431  \brief Set comment or other info string in map header
432 
433  \param Map pointer to Map_info structure
434  \param str comment or other info string
435 
436  \return 0
437  */
438 int Vect_set_comment(struct Map_info *Map, const char *str)
439 {
440  G_free(Map->head.comment);
441  Map->head.comment = G_store(str);
442 
443  return 0;
444 }
445 
446 /*!
447  \brief Get comment or other info string from map header
448 
449  \param Map pointer to Map_info structure
450 
451  \return comment or other info string
452  */
453 const char *Vect_get_comment(struct Map_info *Map)
454 {
455  return (Map->head.comment);
456 }
457 
458 /*!
459  \brief Set projection zone in map header
460 
461  \param Map pointer to Map_info structure
462  \param zone projection zone
463 
464  \return 0
465  */
466 int Vect_set_zone(struct Map_info *Map, int zone)
467 {
468  Map->head.plani_zone = zone;
469 
470  return 0;
471 }
472 
473 /*!
474  \brief Get projection zone from map header
475 
476  \param Map pointer to Map_info structure (unused, returns the zone for
477  the active region)
478 
479  \return projection zone
480  */
481 int Vect_get_zone(struct Map_info *Map UNUSED)
482 {
483  /* return Map->head.plani_zone; */
484 
485  /* use utm zone of current location,
486  * a vector in a given location can not be in a different CRS */
487  return G_zone();
488 }
489 
490 /*!
491  \brief Set projection in map header
492 
493  Supported projections:
494  - PROJECTION_XY 0 - x,y (Raw imagery),
495  - PROJECTION_UTM 1 - UTM Universal Transverse Mercator,
496  - PROJECTION_LL 3 - Latitude-Longitude
497 
498  \param Map pointer to Map_info structure
499  \param proj projection code
500 
501  \return 0
502  */
503 int Vect_set_proj(struct Map_info *Map, int proj)
504 {
505  Map->head.proj = proj;
506 
507  return 0;
508 }
509 
510 /*!
511  \brief Get projection from map header
512 
513  \param Map pointer to Map_info structure
514 
515  \return PROJECTION_XY 0 - x,y (Raw imagery),
516  \return PROJECTION_UTM 1 - UTM Universal Transverse Mercator,
517  \return PROJECTION_LL 3 - Latitude-Longitude
518  */
519 int Vect_get_proj(struct Map_info *Map)
520 {
521  return (Map->head.proj);
522 }
523 
524 /*!
525  \brief Query cartographic projection name of pointer to Map_info structure
526 
527  Returns a pointer to a string which is a printable name for
528  projection code <em>proj</em> (as returned by Vect_get_proj()).
529 
530  \param Map pointer to Map_info structure
531 
532  \return allocated string containing projection name
533  \return NULL if <em>proj</em> is not a valid projection
534  */
535 
536 const char *Vect_get_proj_name(struct Map_info *Map)
537 {
538  char name[256];
539  int n;
540 
541  switch (n = Vect_get_proj(Map)) {
542  case PROJECTION_XY:
543  case PROJECTION_UTM:
544  case PROJECTION_LL:
545  return G_projection_name(n);
546  case PROJECTION_OTHER:
547  /* this won't protect against differing "other" projections, so
548  better to just include P_OTHER in the above list so we return the
549  strictly more correct, but less nice, string: "Other projection" ? */
551  default:
552  G_debug(1,
553  "Vect_get_proj_name(): "
554  "Vect_get_proj() returned an invalid result (%d)",
555  n);
556  break;
557  }
558 
559  strcpy(name, _("Unknown projection"));
560  return G_store(name);
561 }
562 
563 /*!
564  \brief Set threshold used for digitization in map header
565 
566  \param Map pointer to Map_info structure
567  \param thresh threshold used for digitization
568 
569  \return 0
570  */
571 int Vect_set_thresh(struct Map_info *Map, double thresh)
572 {
573  G_debug(1, "Vect_set_thresh(): thresh = %f", thresh);
574  Map->head.digit_thresh = thresh;
575  return 0;
576 }
577 
578 /*!
579  \brief Get threshold used for digitization from map header
580 
581  \param Map pointer to Map_info structure
582 
583  \return threshold used for digitization
584  */
585 double Vect_get_thresh(struct Map_info *Map)
586 {
587  return Map->head.digit_thresh;
588 }
#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:132
#define PROJECTION_XY
Projection code - XY coordinate system (unreferenced data)
Definition: gis.h:124
#define GPATH_MAX
Definition: gis.h:194
#define PROJECTION_UTM
Projection code - UTM.
Definition: gis.h:126
#define PROJECTION_LL
Projection code - Latitude-Longitude.
Definition: gis.h:130
#define UNUSED
A macro for an attribute, if attached to a variable, indicating that the variable is not used.
Definition: gis.h:47
#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)