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 gmail.com>
16 */
17
18 #include <stdlib.h>
19 #include <string.h>
20 #include <grass/vector.h>
21 #include <grass/glocale.h>
22
23 #include "local_proto.h"
24
25 /*!
26 \brief Print vector map header to stdout
27
28 \param Map pointer to Map_info structure
29
30 \return 0 on success
31 */
Vect_print_header(const struct Map_info * Map)32 int Vect_print_header(const struct Map_info *Map)
33 {
34 fprintf(stdout, "\nSelected information from dig header\n");
35 fprintf(stdout, " Organization: %s\n", Vect_get_organization(Map));
36 fprintf(stdout, " Map Name: %s\n", Vect_get_map_name(Map));
37 fprintf(stdout, " Source Date: %s\n", Vect_get_map_date(Map));
38 fprintf(stdout, " Orig. Scale: %d\n", Vect_get_scale(Map));
39
40 return 0;
41 }
42
43 /*!
44 \brief Read vector map header from map head file
45
46 \param Map pointrt to Map_info structure
47
48 \return 0
49 */
Vect_read_header(struct Map_info * Map)50 int Vect_read_header(struct Map_info *Map)
51 {
52 Vect__read_head(Map);
53 return 0;
54 }
55
56 /*!
57 \brief Write vector map header to map head file
58
59 \param Map pointer to Map_info structure
60
61 \return 0
62 */
Vect_write_header(const struct Map_info * Map)63 int Vect_write_header(const struct Map_info *Map)
64 {
65 /* do some sanity checking here */
66 Vect__write_head(Map);
67 return 0;
68 }
69
70 /*!
71 \brief Writes head information to text file (GV_HEAD_ELEMENT)
72
73 \param Map pointer to Map_info structure
74
75 \return 0 on success
76 \return -1 on error
77 */
Vect__write_head(const struct Map_info * Map)78 int Vect__write_head(const struct Map_info *Map)
79 {
80 char path[GPATH_MAX];
81 FILE *head_fp;
82
83 Vect__get_path(path, Map);
84 head_fp = G_fopen_new(path, GV_HEAD_ELEMENT);
85 if (head_fp == NULL) {
86 G_warning(_("Unable to create header file for vector map <%s>"),
87 Vect_get_full_name(Map));
88 return -1;
89 }
90
91 fprintf(head_fp, "ORGANIZATION: %s\n", Vect_get_organization(Map));
92 fprintf(head_fp, "DIGIT DATE: %s\n", Vect_get_date(Map));
93 fprintf(head_fp, "DIGIT NAME: %s\n", Vect_get_person(Map));
94 fprintf(head_fp, "MAP NAME: %s\n", Vect_get_map_name(Map));
95 fprintf(head_fp, "MAP DATE: %s\n", Vect_get_map_date(Map));
96 fprintf(head_fp, "MAP SCALE: %d\n", Vect_get_scale(Map));
97 fprintf(head_fp, "OTHER INFO: %s\n", Vect_get_comment(Map));
98 if (Vect_get_proj(Map) > 0)
99 fprintf(head_fp, "PROJ: %d\n", Vect_get_proj(Map));
100 fprintf(head_fp, "ZONE: %d\n", Vect_get_zone(Map));
101 fprintf(head_fp, "MAP THRESH: %f\n", Vect_get_thresh(Map));
102
103 fclose(head_fp);
104
105 return 0;
106 }
107
108 /*!
109 \brief Reads head information from text file (GV_HEAD_ELEMENT) - for internal use only
110
111 \param Map pointer to Map_info structure
112
113 \return 0 on success
114 \return -1 on error
115 */
Vect__read_head(struct Map_info * Map)116 int Vect__read_head(struct Map_info *Map)
117 {
118 FILE *head_fp;
119 char buff[2000];
120 char path[GPATH_MAX], *ptr;
121
122 /* Reset / init */
123 Vect__init_head(Map);
124
125 G_debug(1, "Vect__read_head(): vector = %s@%s", Map->name, Map->mapset);
126 Vect__get_path(path, Map);
127 head_fp = G_fopen_old(path, GV_HEAD_ELEMENT, Map->mapset);
128 if (head_fp == NULL) {
129 G_warning(_("Unable to open header file of vector <%s>"),
130 Vect_get_full_name(Map));
131 return -1;
132 }
133
134 while (G_getl2(buff, 2000, head_fp)) {
135
136 if (!(ptr = strchr(buff, ':'))) {
137 G_warning(_("Corrupted row in head: %s"), buff);
138 continue;
139 }
140
141 ptr++; /* Search for the start of text */
142 while (*ptr == ' ')
143 ptr++;
144
145 if (strncmp(buff, "ORGANIZATION:", sizeof(char) * 13) == 0)
146 Vect_set_organization(Map, ptr);
147 else if (strncmp(buff, "DIGIT DATE:", sizeof(char) * 11) == 0)
148 Vect_set_date(Map, ptr);
149 else if (strncmp(buff, "DIGIT NAME:", sizeof(char) * 11) == 0)
150 Vect_set_person(Map, ptr);
151 else if (strncmp(buff, "MAP NAME:", sizeof(char) * 9) == 0)
152 Vect_set_map_name(Map, ptr);
153 else if (strncmp(buff, "MAP DATE:", sizeof(char) * 9) == 0)
154 Vect_set_map_date(Map, ptr);
155 else if (strncmp(buff, "MAP SCALE:", sizeof(char) * 10) == 0)
156 Vect_set_scale(Map, atoi(ptr));
157 else if (strncmp(buff, "OTHER INFO:", sizeof(char) * 11) == 0)
158 Vect_set_comment(Map, ptr);
159 else if (strncmp(buff, "PROJ:", sizeof(char) * 5) == 0)
160 Vect_set_proj(Map, atoi(ptr));
161 else if (strncmp(buff, "ZONE:", sizeof(char) * 5) == 0 ||
162 strncmp(buff, "UTM ZONE:", sizeof(char) * 9) == 0)
163 Vect_set_zone(Map, atoi(ptr));
164 else if (strncmp(buff, "WEST EDGE:", sizeof(char) * 10) == 0) {
165 }
166 else if (strncmp(buff, "EAST EDGE:", sizeof(char) * 10) == 0) {
167 }
168 else if (strncmp(buff, "SOUTH EDGE:", sizeof(char) * 11) == 0) {
169 }
170 else if (strncmp(buff, "NORTH EDGE:", sizeof(char) * 11) == 0) {
171 }
172 else if (strncmp(buff, "MAP THRESH:", sizeof(char) * 11) == 0)
173 Vect_set_thresh(Map, atof(ptr));
174 else
175 G_warning(_("Unknown keyword '%s' in vector head"), buff);
176 }
177
178 fclose(head_fp);
179
180 return 0;
181 }
182
183 /*!
184 \brief Get name of vector map
185
186 \param Map pointer to Map_info structure
187
188 \return string containing name
189 */
Vect_get_name(const struct Map_info * Map)190 const char *Vect_get_name(const struct Map_info *Map)
191 {
192 return Map->name;
193 }
194
195 /*!
196 \brief Get name of mapset where vector map lives
197
198 \param Map pointer to Map_info structure
199
200 \return string containing mapset name
201 */
Vect_get_mapset(const struct Map_info * Map)202 const char *Vect_get_mapset(const struct Map_info *Map)
203 {
204 return Map->mapset;
205 }
206
207 /*!
208 \brief Get fully qualified name of vector map
209
210 - for GV_FORMAT_NATIVE and GV_FORMAT_OGR returns "map@mapset"
211 - for GV_FORMAT_OGR_DIRECT returns "layer@datasourse"
212
213 Allocated string should be freed by G_free().
214
215 \param Map pointer to Map_info structure
216
217 \return allocated string "name@mapset"
218 */
Vect_get_full_name(const struct Map_info * Map)219 const char *Vect_get_full_name(const struct Map_info *Map)
220 {
221 char *ptr;
222
223 if (Map->format == GV_FORMAT_OGR_DIRECT &&
224 Map->fInfo.ogr.dsn &&
225 Map->fInfo.ogr.layer_name) {
226 ptr = (char *) G_malloc(strlen(Map->fInfo.ogr.layer_name) +
227 strlen(Map->fInfo.ogr.dsn) + 2);
228 sprintf(ptr, "%s@%s", Map->fInfo.ogr.layer_name,
229 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 */
Vect_is_3d(const struct Map_info * Map)255 int Vect_is_3d(const 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 */
Vect_set_organization(struct Map_info * Map,const char * str)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 */
Vect_get_organization(const struct Map_info * Map)283 const char *Vect_get_organization(const 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 */
Vect_set_date(struct Map_info * Map,const char * str)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 */
Vect_get_date(const struct Map_info * Map)314 const char *Vect_get_date(const 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 */
Vect_set_person(struct Map_info * Map,const char * str)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 */
Vect_get_person(const struct Map_info * Map)342 const char *Vect_get_person(const 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 */
Vect_set_map_name(struct Map_info * Map,const char * str)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 */
Vect_get_map_name(const struct Map_info * Map)370 const char *Vect_get_map_name(const 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 */
Vect_set_map_date(struct Map_info * Map,const char * str)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 */
Vect_get_map_date(const struct Map_info * Map)398 const char *Vect_get_map_date(const 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 */
Vect_set_scale(struct Map_info * Map,int scale)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 */
Vect_get_scale(const struct Map_info * Map)425 int Vect_get_scale(const 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 */
Vect_set_comment(struct Map_info * Map,const char * str)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 */
Vect_get_comment(const struct Map_info * Map)453 const char *Vect_get_comment(const 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 */
Vect_set_zone(struct Map_info * Map,int zone)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
477
478 \return projection zone
479 */
Vect_get_zone(const struct Map_info * Map)480 int Vect_get_zone(const struct Map_info *Map)
481 {
482 /* return Map->head.plani_zone; */
483
484 /* use utm zone of current location,
485 * a vector in a given location can not be in a different CRS */
486 return G_zone();
487 }
488
489 /*!
490 \brief Set projection in map header
491
492 Supported projections:
493 - PROJECTION_XY 0 - x,y (Raw imagery),
494 - PROJECTION_UTM 1 - UTM Universal Transverse Mercator,
495 - PROJECTION_LL 3 - Latitude-Longitude
496
497 \param Map pointer to Map_info structure
498 \param proj projection code
499
500 \return 0
501 */
Vect_set_proj(struct Map_info * Map,int proj)502 int Vect_set_proj(struct Map_info *Map, int proj)
503 {
504 Map->head.proj = proj;
505
506 return 0;
507 }
508
509 /*!
510 \brief Get projection from map header
511
512 \param Map pointer to Map_info structure
513
514 \return PROJECTION_XY 0 - x,y (Raw imagery),
515 \return PROJECTION_UTM 1 - UTM Universal Transverse Mercator,
516 \return PROJECTION_LL 3 - Latitude-Longitude
517 */
Vect_get_proj(const struct Map_info * Map)518 int Vect_get_proj(const struct Map_info *Map)
519 {
520 return (Map->head.proj);
521 }
522
523 /*!
524 \brief Query cartographic projection name of pointer to Map_info structure
525
526 Returns a pointer to a string which is a printable name for
527 projection code <em>proj</em> (as returned by Vect_get_proj()).
528
529 \param Map pointer to Map_info structure
530
531 \return allocated string containing projection name
532 \return NULL if <em>proj</em> is not a valid projection
533 */
534
Vect_get_proj_name(const struct Map_info * Map)535 const char *Vect_get_proj_name(const struct Map_info *Map)
536 {
537 char name[256];
538 int n;
539
540 switch (n = Vect_get_proj(Map)) {
541 case PROJECTION_XY:
542 case PROJECTION_UTM:
543 case PROJECTION_LL:
544 return G_projection_name(n);
545 case PROJECTION_OTHER:
546 /* this won't protect against differing "other" projections, so
547 better to just include P_OTHER in the above list so we return the
548 strictly more correct, but less nice, string: "Other projection" ? */
549 return G_database_projection_name();
550 default:
551 G_debug(1, "Vect_get_proj_name(): "
552 "Vect_get_proj() returned an invalid result (%d)", n);
553 break;
554 }
555
556 strcpy(name, _("Unknown projection"));
557 return G_store(name);
558 }
559
560 /*!
561 \brief Set threshold used for digitization in map header
562
563 \param Map pointer to Map_info structure
564 \param thresh threshold used for digitization
565
566 \return 0
567 */
Vect_set_thresh(struct Map_info * Map,double thresh)568 int Vect_set_thresh(struct Map_info *Map, double thresh)
569 {
570 G_debug(1, "Vect_set_thresh(): thresh = %f", thresh);
571 Map->head.digit_thresh = thresh;
572 return 0;
573 }
574
575 /*!
576 \brief Get threshold used for digitization from map header
577
578 \param Map pointer to Map_info structure
579
580 \return threshold used for digitization
581 */
Vect_get_thresh(const struct Map_info * Map)582 double Vect_get_thresh(const struct Map_info *Map)
583 {
584 return Map->head.digit_thresh;
585 }
586