1 /*!
2    \file args.c
3 
4    \brief Parse command
5 
6    (C) 2008, 2010-2011 by the GRASS Development Team
7 
8    This program is free software under the GNU General Public
9    License (>=v2). Read the file COPYING that comes with GRASS
10    for details.
11 
12    \author Martin Landa <landa.martin gmail.com> (Google SoC 2008/2010)
13  */
14 
15 #include <stdlib.h>
16 #include <string.h>
17 
18 #include <grass/gis.h>
19 #include <grass/glocale.h>
20 
21 #include "local_proto.h"
22 
23 static void print_error(int, int, int,
24 			const char *, const char *,
25 			const char *, const char *);
26 
27 static void args_surface(struct GParams *);
28 static void args_vline(struct GParams *);
29 static void args_vpoint(struct GParams *);
30 static void args_viewpoint(struct GParams *);
31 static void args_volume(struct GParams *);
32 static void args_lighting(struct GParams *);
33 static void args_fringe(struct GParams *);
34 static void args_cplane(struct GParams *);
35 static void args_arrow(struct GParams *);
36 
37 /*!
38    \brief Parse command
39 
40    \param argc number of arguments
41    \param argv arguments array
42    \param params GRASS parameters
43 
44    \return 1
45  */
parse_command(int argc,char * argv[],struct GParams * params)46 void parse_command(int argc, char *argv[], struct GParams *params)
47 {
48     params->mode_all = G_define_flag();
49     params->mode_all->key = 'a';
50     params->mode_all->description =
51 	_("Use draw mode for all loaded surfaces");
52     params->mode_all->guisection = _("Surfaces");
53 
54     /*** surface attributes ***/
55     args_surface(params);
56 
57     /*** vector lines ***/
58     args_vline(params);
59 
60     /*** vector points ***/
61     args_vpoint(params);
62 
63     /*** volumes ***/
64     args_volume(params);
65 
66     /*** misc ***/
67     /* background color */
68     params->bgcolor = G_define_standard_option(G_OPT_C);
69     params->bgcolor->key = "bgcolor";
70     params->bgcolor->label = _("Background color");
71     params->bgcolor->answer = DEFAULT_BG_COLOR;
72 
73     /*** viewpoint ***/
74     args_viewpoint(params);
75 
76     /*** lighting ***/
77     args_lighting(params);
78 
79     /*** fringe ***/
80     args_fringe(params);
81 
82     /*** cutting plane ***/
83     args_cplane(params);
84 
85     /*** north arrow ***/
86     args_arrow(params);
87 
88     /*** output image ***/
89     /* output */
90     params->output = G_define_standard_option(G_OPT_F_OUTPUT);
91     params->output->description =
92 	_("Name for output image file (without extension)");
93     params->output->guisection = _("Image");
94 
95     /* format */
96     params->format = G_define_option();
97     params->format->key = "format";
98     params->format->type = TYPE_STRING;
99 #ifdef HAVE_TIFFIO_H
100     params->format->options = "ppm,tif";	/* TODO: png */
101 #else
102     params->format->options = "ppm";
103 #endif
104     params->format->answer = "ppm";
105     params->format->description = _("Graphics file format");
106     params->format->required = YES;
107     params->format->guisection = _("Image");
108 
109     /* size */
110     params->size = G_define_option();
111     params->size->key = "size";
112     params->size->type = TYPE_INTEGER;
113     params->size->key_desc = "width,height";
114     params->size->answer = "640,480";
115     params->size->description = _("Size (width, height) of output image");
116     params->size->required = YES;
117     params->size->guisection = _("Image");
118 
119     if (G_parser(argc, argv))
120 	exit(EXIT_FAILURE);
121 
122     return;
123 }
124 
args_surface(struct GParams * params)125 void args_surface(struct GParams *params)
126 {
127     /* topography */
128     params->elev_map = G_define_standard_option(G_OPT_R_ELEV);
129     params->elev_map->key = "elevation_map";
130     params->elev_map->required = NO;
131     params->elev_map->multiple = YES;
132     params->elev_map->description = _("Name of raster map(s) for elevation");
133     params->elev_map->guisection = _("Surfaces");
134 
135     params->elev_const = G_define_option();
136     params->elev_const->key = "elevation_value";
137     params->elev_const->key_desc = "value";
138     params->elev_const->type = TYPE_INTEGER;
139     params->elev_const->required = NO;
140     params->elev_const->multiple = YES;
141     params->elev_const->description =
142 	_("Constant elevation value(s) to use instead of a raster DEM");
143     params->elev_const->guisection = _("Surfaces");
144 
145     /* color */
146     params->color_map = G_define_standard_option(G_OPT_R_MAP);
147     params->color_map->multiple = YES;
148     params->color_map->required = NO;
149     params->color_map->description = _("Name of raster map(s) for color");
150     params->color_map->guisection = _("Surfaces");
151     params->color_map->key = "color_map";
152 
153     params->color_const = G_define_standard_option(G_OPT_C);
154     params->color_const->multiple = YES;
155     params->color_const->label = _("Color value(s)");
156     params->color_const->guisection = _("Surfaces");
157     params->color_const->answer = NULL;
158 
159     /* mask */
160     params->mask_map = G_define_standard_option(G_OPT_R_MAP);
161     params->mask_map->multiple = YES;
162     params->mask_map->required = NO;
163     params->mask_map->description = _("Name of raster map(s) for mask");
164     params->mask_map->guisection = _("Surfaces");
165     params->mask_map->key = "mask_map";
166 
167     /* transparency */
168     params->transp_map = G_define_standard_option(G_OPT_R_MAP);
169     params->transp_map->multiple = YES;
170     params->transp_map->required = NO;
171     params->transp_map->description =
172 	_("Name of raster map(s) for transparency");
173     params->transp_map->guisection = _("Surfaces");
174     params->transp_map->key = "transparency_map";
175 
176     params->transp_const = G_define_option();
177     params->transp_const->key = "transparency_value";
178     params->transp_const->key_desc = "value";
179     params->transp_const->type = TYPE_INTEGER;
180     params->transp_const->required = NO;
181     params->transp_const->multiple = YES;
182     params->transp_const->description = _("Transparency value(s)");
183     params->transp_const->guisection = _("Surfaces");
184     params->transp_const->options = "0-255";
185 
186     /* shininess */
187     params->shine_map = G_define_standard_option(G_OPT_R_MAP);
188     params->shine_map->multiple = YES;
189     params->shine_map->required = NO;
190     params->shine_map->description = _("Name of raster map(s) for shininess");
191     params->shine_map->guisection = _("Surfaces");
192     params->shine_map->key = "shininess_map";
193 
194     params->shine_const = G_define_option();
195     params->shine_const->key = "shininess_value";
196     params->shine_const->key_desc = "value";
197     params->shine_const->type = TYPE_INTEGER;
198     params->shine_const->required = NO;
199     params->shine_const->multiple = YES;
200     params->shine_const->description = _("Shininess value(s)");
201     params->shine_const->guisection = _("Surfaces");
202     params->shine_const->options = "0-255";
203 
204     /* emission */
205     params->emit_map = G_define_standard_option(G_OPT_R_MAP);
206     params->emit_map->multiple = YES;
207     params->emit_map->required = NO;
208     params->emit_map->description = _("Name of raster map(s) for emission");
209     params->emit_map->guisection = _("Surfaces");
210     params->emit_map->key = "emission_map";
211 
212     params->emit_const = G_define_option();
213     params->emit_const->key = "emission_value";
214     params->emit_const->key_desc = "value";
215     params->emit_const->type = TYPE_INTEGER;
216     params->emit_const->required = NO;
217     params->emit_const->multiple = YES;
218     params->emit_const->description = _("Emission value(s)");
219     params->emit_const->guisection = _("Surfaces");
220     params->emit_const->options = "0-255";
221 
222     /* draw */
223     /* mode */
224     params->mode = G_define_option();
225     params->mode->key = "mode";
226     params->mode->key_desc = "string";
227     params->mode->type = TYPE_STRING;
228     params->mode->required = NO;
229     params->mode->multiple = YES;
230     params->mode->description = _("Draw mode");
231     params->mode->options = "coarse,fine,both";
232     params->mode->answer = "fine";
233     params->mode->guisection = _("Draw");
234 
235     /* resolution fine */
236     params->res_fine = G_define_option();
237     params->res_fine->key = "resolution_fine";
238     params->res_fine->key_desc = "value";
239     params->res_fine->type = TYPE_INTEGER;
240     params->res_fine->required = NO;
241     params->res_fine->multiple = YES;
242     params->res_fine->description = _("Fine resolution");
243     params->res_fine->answer = "6";
244     params->res_fine->guisection = _("Draw");
245 
246     /* resolution coarse */
247     params->res_coarse = G_define_option();
248     params->res_coarse->key = "resolution_coarse";
249     params->res_coarse->key_desc = "value";
250     params->res_coarse->type = TYPE_INTEGER;
251     params->res_coarse->required = NO;
252     params->res_coarse->multiple = YES;
253     params->res_coarse->description = _("Coarse resolution");
254     params->res_coarse->answer = "9";
255     params->res_coarse->guisection = _("Draw");
256 
257     /* style */
258     params->style = G_define_option();
259     params->style->key = "style";
260     params->style->key_desc = "string";
261     params->style->type = TYPE_STRING;
262     params->style->required = NO;
263     params->style->multiple = YES;
264     params->style->description = _("Draw style");
265     params->style->options = "wire,surface";
266     params->style->answer = "surface";
267     params->style->guisection = _("Draw");
268 
269     /* shading */
270     params->shade = G_define_option();
271     params->shade->key = "shading";
272     params->shade->key_desc = "string";
273     params->shade->type = TYPE_STRING;
274     params->shade->required = NO;
275     params->shade->multiple = YES;
276     params->shade->description = _("Shading");
277     params->shade->options = "flat,gouraud";
278     params->shade->answer = "gouraud";
279     params->shade->guisection = _("Draw");
280 
281     /* wire color */
282     params->wire_color = G_define_standard_option(G_OPT_C);
283     params->wire_color->multiple = YES;
284     params->wire_color->required = NO;
285     params->wire_color->label = _("Wire color");
286     params->wire_color->key = "wire_color";
287     params->wire_color->answer = "136:136:136";
288     params->wire_color->guisection = _("Draw");
289 
290     /* position */
291     params->surface_pos = G_define_option();
292     params->surface_pos->key = "surface_position";
293     params->surface_pos->key_desc = "x,y,z";
294     params->surface_pos->type = TYPE_INTEGER;
295     params->surface_pos->required = NO;
296     params->surface_pos->multiple = YES;
297     params->surface_pos->description = _("Surface position");
298     params->surface_pos->guisection = _("Draw");
299     params->surface_pos->answer = "0,0,0";
300 
301     return;
302 }
303 
args_vline(struct GParams * params)304 void args_vline(struct GParams *params)
305 {
306     params->vlines = G_define_standard_option(G_OPT_V_MAP);
307     params->vlines->multiple = YES;
308     params->vlines->required = NO;
309     params->vlines->description = _("Name of line vector overlay map(s)");
310     params->vlines->guisection = _("Vector lines");
311     params->vlines->key = "vline";
312 
313     params->vline_layer = G_define_standard_option(G_OPT_V_FIELD);
314     params->vline_layer->multiple = YES;
315     params->vline_layer->required = NO;
316     params->vline_layer->description =
317 	_("Layer number or name for thematic mapping");
318     params->vline_layer->guisection = _("Vector lines");
319     params->vline_layer->key = "vline_layer";
320     params->vline_layer->answer = "1";
321 
322     /* line width */
323     params->vline_width = G_define_option();
324     params->vline_width->key = "vline_width";
325     params->vline_width->key_desc = "value";
326     params->vline_width->type = TYPE_INTEGER;
327     params->vline_width->required = NO;
328     params->vline_width->multiple = YES;
329     params->vline_width->description = _("Vector line width");
330     params->vline_width->guisection = _("Vector lines");
331     params->vline_width->options = "1-100";
332     params->vline_width->answer = "2";
333 
334     params->vline_width_column = G_define_standard_option(G_OPT_DB_COLUMN);
335     params->vline_width_column->multiple = YES;
336     params->vline_width_column->required = NO;
337     params->vline_width_column->label = _("Name of width definition column");
338     params->vline_width_column->key = "vline_width_column";
339     params->vline_width_column->guisection = _("Vector lines");
340 
341     /* line color */
342     params->vline_color = G_define_standard_option(G_OPT_C);
343     params->vline_color->multiple = YES;
344     params->vline_color->required = NO;
345     params->vline_color->label = _("Vector line color");
346     params->vline_color->key = "vline_color";
347     params->vline_color->answer = "blue";
348     params->vline_color->guisection = _("Vector lines");
349 
350     params->vline_color_column = G_define_standard_option(G_OPT_DB_COLUMN);
351     params->vline_color_column->multiple = YES;
352     params->vline_color_column->required = NO;
353     params->vline_color_column->label = _("Name of color definition column");
354     params->vline_color_column->key = "vline_color_column";
355     params->vline_color_column->guisection = _("Vector lines");
356 
357     /* line mode */
358     params->vline_mode = G_define_option();
359     params->vline_mode->key = "vline_mode";
360     params->vline_mode->key_desc = "string";
361     params->vline_mode->type = TYPE_STRING;
362     params->vline_mode->required = NO;
363     params->vline_mode->multiple = YES;
364     params->vline_mode->description = _("Vector line display mode");
365     params->vline_mode->options = "surface,flat";
366     params->vline_mode->descriptions = _("surface;drape on raster surface;"
367 					 "flat;draw at constant elevation");
368     params->vline_mode->answer = "surface";
369     params->vline_mode->guisection = _("Vector lines");
370 
371     /* line height */
372     params->vline_height = G_define_option();
373     params->vline_height->key = "vline_height";
374     params->vline_height->key_desc = "value";
375     params->vline_height->type = TYPE_INTEGER;
376     params->vline_height->required = NO;
377     params->vline_height->multiple = YES;
378     params->vline_height->description = _("Vector line height");
379     params->vline_height->guisection = _("Vector lines");
380     params->vline_height->options = "0-1000";
381     params->vline_height->answer = "0";
382 
383     /* position */
384     params->vline_pos = G_define_option();
385     params->vline_pos->key = "vline_position";
386     params->vline_pos->key_desc = "x,y,z";
387     params->vline_pos->type = TYPE_INTEGER;
388     params->vline_pos->required = NO;
389     params->vline_pos->multiple = YES;
390     params->vline_pos->description = _("Vector lines position");
391     params->vline_pos->guisection = _("Vector lines");
392     params->vline_pos->answer = "0,0,0";
393 
394     return;
395 }
396 
args_vpoint(struct GParams * params)397 void args_vpoint(struct GParams *params)
398 {
399     params->vpoints = G_define_standard_option(G_OPT_V_MAP);
400     params->vpoints->multiple = YES;
401     params->vpoints->required = NO;
402     params->vpoints->description = _("Name of point vector overlay map(s)");
403     params->vpoints->guisection = _("Vector points");
404     params->vpoints->key = "vpoint";
405 
406     params->vpoint_layer = G_define_standard_option(G_OPT_V_FIELD);
407     params->vpoint_layer->multiple = YES;
408     params->vpoint_layer->required = NO;
409     params->vpoint_layer->description =
410 	_("Layer number or name for thematic mapping");
411     params->vpoint_layer->guisection = _("Vector points");
412     params->vpoint_layer->key = "vpoint_layer";
413     params->vpoint_layer->answer = "1";
414 
415     /* point size */
416     params->vpoint_size = G_define_option();
417     params->vpoint_size->key = "vpoint_size";
418     params->vpoint_size->key_desc = "value";
419     params->vpoint_size->type = TYPE_DOUBLE;
420     params->vpoint_size->required = NO;
421     params->vpoint_size->multiple = YES;
422     params->vpoint_size->description = _("Icon size (map units)");
423     params->vpoint_size->guisection = _("Vector points");
424     params->vpoint_size->options = "0-1000";
425     params->vpoint_size->answer = "100";
426 
427     params->vpoint_size_column = G_define_standard_option(G_OPT_DB_COLUMN);
428     params->vpoint_size_column->multiple = YES;
429     params->vpoint_size_column->required = NO;
430     params->vpoint_size_column->label = _("Name of size definition column");
431     params->vpoint_size_column->key = "vpoint_size_column";
432     params->vpoint_size_column->guisection = _("Vector points");
433 
434     /* point width */
435     params->vpoint_width = G_define_option();
436     params->vpoint_width->key = "vpoint_width";
437     params->vpoint_width->key_desc = "value";
438     params->vpoint_width->type = TYPE_INTEGER;
439     params->vpoint_width->required = NO;
440     params->vpoint_width->multiple = YES;
441     params->vpoint_width->description = _("Icon width");
442     params->vpoint_width->guisection = _("Vector points");
443     params->vpoint_width->options = "1-1000";
444     params->vpoint_width->answer = "2";
445 
446     params->vpoint_width_column = G_define_standard_option(G_OPT_DB_COLUMN);
447     params->vpoint_width_column->multiple = YES;
448     params->vpoint_width_column->required = NO;
449     params->vpoint_width_column->label = _("Name of width definition column");
450     params->vpoint_width_column->key = "vpoint_width_column";
451     params->vpoint_width_column->guisection = _("Vector points");
452 
453     /* point color */
454     params->vpoint_color = G_define_standard_option(G_OPT_C);
455     params->vpoint_color->multiple = YES;
456     params->vpoint_color->required = NO;
457     params->vpoint_color->label = _("Icon color");
458     params->vpoint_color->key = "vpoint_color";
459     params->vpoint_color->answer = "blue";
460     params->vpoint_color->guisection = _("Vector points");
461 
462     params->vpoint_color_column = G_define_standard_option(G_OPT_DB_COLUMN);
463     params->vpoint_color_column->multiple = YES;
464     params->vpoint_color_column->required = NO;
465     params->vpoint_color_column->label = _("Name of color definition column");
466     params->vpoint_color_column->key = "vpoint_color_column";
467     params->vpoint_color_column->guisection = _("Vector points");
468 
469     /* point icon type */
470     params->vpoint_marker = G_define_option();
471     params->vpoint_marker->key = "vpoint_marker";
472     params->vpoint_marker->key_desc = "string";
473     params->vpoint_marker->type = TYPE_STRING;
474     params->vpoint_marker->required = NO;
475     params->vpoint_marker->multiple = YES;
476     params->vpoint_marker->description = _("Icon marker");
477     params->vpoint_marker->options =
478 	"x,box,sphere,cube,diamond,dec_tree,con_tree,aster,gyro,histogram";
479     params->vpoint_marker->answer = "sphere";
480     params->vpoint_marker->guisection = _("Vector points");
481 
482     params->vpoint_marker_column = G_define_standard_option(G_OPT_DB_COLUMN);
483     params->vpoint_marker_column->multiple = YES;
484     params->vpoint_marker_column->required = NO;
485     params->vpoint_marker_column->label =
486 	_("Name of marker definition column");
487     params->vpoint_marker_column->key = "vpoint_marker_column";
488     params->vpoint_marker_column->guisection = _("Vector points");
489 
490     /* point mode */
491     params->vpoint_mode = G_define_option();
492     params->vpoint_mode->key = "vpoint_mode";
493     params->vpoint_mode->key_desc = "string";
494     params->vpoint_mode->type = TYPE_STRING;
495     params->vpoint_mode->required = NO;
496     params->vpoint_mode->multiple = YES;
497     params->vpoint_mode->description = _("3D vector point display mode");
498     params->vpoint_mode->options = "surface,3D";
499     params->vpoint_mode->descriptions = _("surface;drape on raster surface;"
500 					  "3D;place at 3D point's z-elevation");
501     /* TODO: "flat", place at a constant elevation */
502     params->vpoint_mode->answer = "3D";
503     params->vpoint_mode->guisection = _("Vector points");
504 
505     /* position */
506     params->vpoint_pos = G_define_option();
507     params->vpoint_pos->key = "vpoint_position";
508     params->vpoint_pos->key_desc = "x,y,z";
509     params->vpoint_pos->type = TYPE_DOUBLE;
510     params->vpoint_pos->required = NO;
511     params->vpoint_pos->multiple = YES;
512     params->vpoint_pos->description = _("Vector points position");
513     params->vpoint_pos->guisection = _("Vector points");
514     params->vpoint_pos->answer = "0,0,0";
515 
516     return;
517 }
518 
args_viewpoint(struct GParams * params)519 void args_viewpoint(struct GParams *params)
520 {
521     /* position */
522     params->pos = G_define_option();
523     params->pos->key = "position";
524     params->pos->key_desc = "x,y";
525     params->pos->type = TYPE_DOUBLE;
526     params->pos->required = NO;
527     params->pos->multiple = NO;
528     params->pos->description =
529 	_("Viewpoint position (x,y model coordinates)");
530     params->pos->guisection = _("Viewpoint");
531     params->pos->answer = "0.84,0.16";
532     params->pos->options = "0.0-1.0";
533 
534     /* height */
535     params->height = G_define_option();
536     params->height->key = "height";
537     params->height->key_desc = "value";
538     params->height->type = TYPE_INTEGER;
539     params->height->required = NO;
540     params->height->multiple = NO;
541     params->height->description = _("Viewpoint height (in map units)");
542     params->height->guisection = _("Viewpoint");
543 
544     /* perspective */
545     params->persp = G_define_option();
546     params->persp->key = "perspective";
547     params->persp->key_desc = "value";
548     params->persp->type = TYPE_INTEGER;
549     params->persp->required = NO;
550     params->persp->multiple = NO;
551     params->persp->description = _("Viewpoint field of view (in degrees)");
552     params->persp->guisection = _("Viewpoint");
553     params->persp->answer = "40";
554     params->persp->options = "1-180";
555 
556     /* twist */
557     params->twist = G_define_option();
558     params->twist->key = "twist";
559     params->twist->key_desc = "value";
560     params->twist->type = TYPE_INTEGER;
561     params->twist->required = NO;
562     params->twist->multiple = NO;
563     params->twist->description = _("Viewpoint twist angle (in degrees)");
564     params->twist->guisection = _("Viewpoint");
565     params->twist->answer = "0";
566     params->twist->options = "-180-180";
567 
568     /* z-exag */
569     params->exag = G_define_option();
570     params->exag->key = "zexag";
571     params->exag->key_desc = "value";
572     params->exag->type = TYPE_DOUBLE;
573     params->exag->required = NO;
574     params->exag->multiple = NO;
575     params->exag->description = _("Vertical exaggeration");
576 
577     /* focus */
578     params->focus = G_define_option();
579     params->focus->key = "focus";
580     params->focus->key_desc = "x,y,z";
581     params->focus->type = TYPE_DOUBLE;
582     params->focus->required = NO;
583     params->focus->multiple = NO;
584     params->focus->description =
585 	_("Focus to point on surface (from SW corner in map units)");
586     params->focus->guisection = _("Viewpoint");
587 
588     return;
589 }
590 
args_volume(struct GParams * params)591 void args_volume(struct GParams *params)
592 {
593     params->volume = G_define_standard_option(G_OPT_R3_MAPS);
594     params->volume->required = NO;
595     params->volume->guisection = _("Volumes");
596     params->volume->key = "volume";
597 
598     /* mode */
599     params->volume_mode = G_define_option();
600     params->volume_mode->key = "volume_mode";
601     params->volume_mode->key_desc = "string";
602     params->volume_mode->type = TYPE_STRING;
603     params->volume_mode->required = NO;
604     params->volume_mode->multiple = YES;
605     params->volume_mode->description = _("Volume draw mode");
606     params->volume_mode->options = "isosurface,slice";
607     params->volume_mode->answer = "isosurface";
608     params->volume_mode->guisection = _("Draw");
609 
610     /* shading */
611     params->volume_shade = G_define_option();
612     params->volume_shade->key = "volume_shading";
613     params->volume_shade->key_desc = "string";
614     params->volume_shade->type = TYPE_STRING;
615     params->volume_shade->required = NO;
616     params->volume_shade->multiple = YES;
617     params->volume_shade->description = _("Volume shading");
618     params->volume_shade->options = "flat,gouraud";
619     params->volume_shade->answer = "gouraud";
620     params->volume_shade->guisection = _("Draw");
621 
622     /* position */
623     params->volume_pos = G_define_option();
624     params->volume_pos->key = "volume_position";
625     params->volume_pos->key_desc = "x,y,z";
626     params->volume_pos->type = TYPE_INTEGER;
627     params->volume_pos->required = NO;
628     params->volume_pos->multiple = YES;
629     params->volume_pos->description = _("Volume position");
630     params->volume_pos->guisection = _("Volumes");
631     params->volume_pos->answer = "0,0,0";
632 
633     /* resolution  */
634     params->volume_res = G_define_option();
635     params->volume_res->key = "volume_resolution";
636     params->volume_res->key_desc = "value";
637     params->volume_res->type = TYPE_INTEGER;
638     params->volume_res->required = NO;
639     params->volume_res->multiple = YES;
640     params->volume_res->description = _("Volume resolution");
641     params->volume_res->answer = "3";
642     params->volume_res->guisection = _("Volumes");
643 
644     /* isosurface level */
645     params->isosurf_level = G_define_option();
646     params->isosurf_level->key = "isosurf_level";
647     params->isosurf_level->key_desc = "volume:value";
648     params->isosurf_level->type = TYPE_STRING;
649     params->isosurf_level->required = NO;
650     params->isosurf_level->multiple = YES;
651     params->isosurf_level->description = _("Isosurface level");
652     params->isosurf_level->guisection = _("Volumes");
653 
654     /* isosurface color map */
655     params->isosurf_color_map = G_define_standard_option(G_OPT_R3_MAPS);
656     params->isosurf_color_map->key = "isosurf_color_map";
657     params->isosurf_color_map->required = NO;
658     params->isosurf_color_map->multiple = YES;
659     params->isosurf_color_map->description =
660 	_("Name of volume for isosurface color");
661     params->isosurf_color_map->guisection = _("Volumes");
662 
663     /* isosurface color value */
664     params->isosurf_color_const = G_define_standard_option(G_OPT_C);
665     params->isosurf_color_const->key = "isosurf_color_value";
666     params->isosurf_color_const->required = NO;
667     params->isosurf_color_const->multiple = YES;
668     params->isosurf_color_const->label = _("Isosurface color");
669     params->isosurf_color_const->guisection = _("Volumes");
670     params->isosurf_color_const->answer = NULL;
671 
672     /* isosurface transparency */
673     params->isosurf_transp_map = G_define_standard_option(G_OPT_R3_MAP);
674     params->isosurf_transp_map->multiple = YES;
675     params->isosurf_transp_map->required = NO;
676     params->isosurf_transp_map->description =
677 	_("Name of 3D raster map(s) for isosurface transparency");
678     params->isosurf_transp_map->guisection = _("Volumes");
679     params->isosurf_transp_map->key = "isosurf_transparency_map";
680 
681     params->isosurf_transp_const = G_define_option();
682     params->isosurf_transp_const->key = "isosurf_transparency_value";
683     params->isosurf_transp_const->key_desc = "value";
684     params->isosurf_transp_const->type = TYPE_INTEGER;
685     params->isosurf_transp_const->required = NO;
686     params->isosurf_transp_const->multiple = YES;
687     params->isosurf_transp_const->description =
688 	_("Transparency value(s)for isosurfaces");
689     params->isosurf_transp_const->guisection = _("Volumes");
690     params->isosurf_transp_const->options = "0-255";
691 
692     /* isosurface shininess */
693     params->isosurf_shine_map = G_define_standard_option(G_OPT_R3_MAP);
694     params->isosurf_shine_map->multiple = YES;
695     params->isosurf_shine_map->required = NO;
696     params->isosurf_shine_map->description =
697 	_("Name of 3D raster map(s) for shininess");
698     params->isosurf_shine_map->guisection = _("Volumes");
699     params->isosurf_shine_map->key = "isosurf_shininess_map";
700 
701     params->isosurf_shine_const = G_define_option();
702     params->isosurf_shine_const->key = "isosurf_shininess_value";
703     params->isosurf_shine_const->key_desc = "value";
704     params->isosurf_shine_const->type = TYPE_INTEGER;
705     params->isosurf_shine_const->required = NO;
706     params->isosurf_shine_const->multiple = YES;
707     params->isosurf_shine_const->description =
708 	_("Shininess value(s) for isosurfaces");
709     params->isosurf_shine_const->guisection = _("Volumes");
710     params->isosurf_shine_const->options = "0-255";
711 
712     params->isosurf_toggle_norm_dir = G_define_flag();
713     params->isosurf_toggle_norm_dir->key = 'n';
714     params->isosurf_toggle_norm_dir->description =
715 	_("Toggles normal direction of all isosurfaces (changes light effect)");
716     params->isosurf_toggle_norm_dir->guisection = _("Volumes");
717 
718     params->draw_volume_box = G_define_flag();
719     params->draw_volume_box->key = 'b';
720     params->draw_volume_box->description =
721 	_("Draw volume box");
722     params->draw_volume_box->guisection = _("Volumes");
723 
724     /* slices */
725     /* slice axis */
726     params->slice = G_define_option();
727     params->slice->key = "slice";
728     params->slice->key_desc = "volume:axis";
729     params->slice->type = TYPE_STRING;
730     params->slice->required = NO;
731     params->slice->multiple = YES;
732     params->slice->description =
733 	_("Volume slice parallel to given axis (x, y, z)");
734     params->slice->guisection = _("Volumes");
735 
736     /* slice position */
737     params->slice_pos = G_define_option();
738     params->slice_pos->key = "slice_position";
739     params->slice_pos->key_desc = "x1,x2,y1,y2,z1,z2";
740     params->slice_pos->type = TYPE_DOUBLE;
741     params->slice_pos->required = NO;
742     params->slice_pos->multiple = YES;
743     params->slice_pos->description = _("Volume slice position");
744     params->slice_pos->guisection = _("Volumes");
745     params->slice_pos->answer = "0,1,0,1,0,1";
746 
747     /* slice transparency */
748     params->slice_transp = G_define_option();
749     params->slice_transp->key = "slice_transparency";
750     params->slice_transp->key_desc = "value";
751     params->slice_transp->type = TYPE_INTEGER;
752     params->slice_transp->required = NO;
753     params->slice_transp->multiple = YES;
754     params->slice_transp->description = _("Volume slice transparency");
755     params->slice_transp->guisection = _("Volumes");
756     params->slice_transp->answer = "0";
757     params->slice_transp->options = "0-255";
758 
759     return;
760 }
761 
args_lighting(struct GParams * params)762 void args_lighting(struct GParams *params)
763 {
764     params->light_pos = G_define_option();
765     params->light_pos->key = "light_position";
766     params->light_pos->key_desc = "x,y,z";
767     params->light_pos->type = TYPE_DOUBLE;
768     params->light_pos->required = NO;
769     params->light_pos->multiple = NO;
770     params->light_pos->description =
771 	_("Light position (x,y,z model coordinates)");
772     params->light_pos->guisection = _("Lighting");
773     params->light_pos->answer = "0.68,-0.68,0.80";
774 
775     params->light_color = G_define_standard_option(G_OPT_C);
776     params->light_color->key = "light_color";
777     params->light_color->label = _("Light color");
778     params->light_color->guisection = _("Lighting");
779     params->light_color->answer = "white";
780 
781     params->light_bright = G_define_option();
782     params->light_bright->key = "light_brightness";
783     params->light_bright->type = TYPE_INTEGER;
784     params->light_bright->required = NO;
785     params->light_bright->multiple = NO;
786     params->light_bright->description = _("Light brightness");
787     params->light_bright->guisection = _("Lighting");
788     params->light_bright->answer = "80";
789     params->light_bright->options = "0-100";
790 
791     params->light_ambient = G_define_option();
792     params->light_ambient->key = "light_ambient";
793     params->light_ambient->type = TYPE_INTEGER;
794     params->light_ambient->required = NO;
795     params->light_ambient->multiple = NO;
796     params->light_ambient->description = _("Light ambient");
797     params->light_ambient->guisection = _("Lighting");
798     params->light_ambient->answer = "20";
799     params->light_ambient->options = "0-100";
800 }
801 
args_cplane(struct GParams * params)802 void args_cplane(struct GParams *params)
803 {
804     params->cplane = G_define_option();
805     params->cplane->key = "cplane";
806     params->cplane->key_desc = "value";
807     params->cplane->type = TYPE_INTEGER;
808     params->cplane->required = NO;
809     params->cplane->multiple = YES;
810     params->cplane->description = _("Cutting plane index (0-5)");
811     params->cplane->guisection = _("Cutting planes");
812 
813     params->cplane_pos = G_define_option();
814     params->cplane_pos->key = "cplane_position";
815     params->cplane_pos->key_desc = "x,y,z";
816     params->cplane_pos->type = TYPE_DOUBLE;
817     params->cplane_pos->required = NO;
818     params->cplane_pos->multiple = YES;
819     params->cplane_pos->description = _("Cutting plane x,y,z coordinates");
820     params->cplane_pos->guisection = _("Cutting planes");
821     params->cplane_pos->answer = "0,0,0";
822 
823     params->cplane_rot = G_define_option();
824     params->cplane_rot->key = "cplane_rotation";
825     params->cplane_rot->key_desc = "value";
826     params->cplane_rot->type = TYPE_DOUBLE;
827     params->cplane_rot->multiple = YES;
828     params->cplane_rot->required = NO;
829     params->cplane_rot->guisection = _("Cutting planes");
830     params->cplane_rot->description =
831 	_("Cutting plane rotation along the vertical axis");
832     params->cplane_rot->answer = "0";
833     params->cplane_rot->options = "0-360";
834 
835     params->cplane_tilt = G_define_option();
836     params->cplane_tilt->key = "cplane_tilt";
837     params->cplane_tilt->key_desc = "value";
838     params->cplane_tilt->type = TYPE_DOUBLE;
839     params->cplane_tilt->multiple = YES;
840     params->cplane_tilt->required = NO;
841     params->cplane_tilt->guisection = _("Cutting planes");
842     params->cplane_tilt->description = _("Cutting plane tilt");
843     params->cplane_tilt->answer = "0";
844     params->cplane_tilt->options = "0-360";
845 
846     params->cplane_shading = G_define_option();
847     params->cplane_shading->key = "cplane_shading";
848     params->cplane_shading->key_desc = "string";
849     params->cplane_shading->type = TYPE_STRING;
850     params->cplane_shading->multiple = NO;
851     params->cplane_shading->required = NO;
852     params->cplane_shading->guisection = _("Cutting planes");
853     params->cplane_shading->description =
854 	_("Cutting plane color (between two surfaces)");
855     params->cplane_shading->answer = "clear";
856     params->cplane_shading->options = "clear,top,bottom,blend,shaded";
857 }
858 
args_fringe(struct GParams * params)859 void args_fringe(struct GParams *params)
860 {
861     char *desc;
862 
863     params->fringe = G_define_option();
864     params->fringe->key = "fringe";
865     params->fringe->type = TYPE_STRING;
866     params->fringe->options = "nw,ne,sw,se";
867     desc = NULL;
868     G_asprintf(&desc,
869 	       "nw;%s;ne;%s;sw;%s;se;%s",
870 	       _("North-West edge"),
871 	       _("North-East edge"),
872 	       _("South-West edge"), _("South-East edge"));
873     params->fringe->descriptions = desc;
874     params->fringe->description = _("Fringe edges");
875     params->fringe->guisection = _("Fringe");
876     params->fringe->multiple = YES;
877 
878     params->fringe_color = G_define_standard_option(G_OPT_C);
879     params->fringe_color->key = "fringe_color";
880     params->fringe_color->label = _("Fringe color");
881     params->fringe_color->guisection = _("Fringe");
882     params->fringe_color->answer = "grey";
883 
884     params->fringe_elev = G_define_option();
885     params->fringe_elev->key = "fringe_elevation";
886     params->fringe_elev->type = TYPE_INTEGER;
887     params->fringe_elev->required = NO;
888     params->fringe_elev->multiple = NO;
889     params->fringe_elev->description = _("Fringe elevation");
890     params->fringe_elev->guisection = _("Fringe");
891     params->fringe_elev->answer = "55";
892 }
893 
args_arrow(struct GParams * params)894 void args_arrow(struct GParams *params)
895 {
896     params->north_arrow = G_define_option();
897     params->north_arrow->key = "arrow_position";
898     params->north_arrow->key_desc = "x,y";
899     params->north_arrow->type = TYPE_INTEGER;
900     params->north_arrow->required = NO;
901     params->north_arrow->multiple = NO;
902     params->north_arrow->description =
903 	_("Place north arrow at given position \
904 	(in screen coordinates from bottom left corner)");
905     params->north_arrow->guisection = _("Decoration");
906 
907     params->north_arrow_size = G_define_option();
908     params->north_arrow_size->key = "arrow_size";
909     params->north_arrow_size->key_desc = "value";
910     params->north_arrow_size->type = TYPE_DOUBLE;
911     params->north_arrow_size->required = NO;
912     params->north_arrow_size->multiple = NO;
913     params->north_arrow_size->description =
914 	_("North arrow size (in map units)");
915     params->north_arrow_size->guisection = _("Decoration");
916 
917     params->north_arrow_color = G_define_standard_option(G_OPT_C);
918     params->north_arrow_color->key = "arrow_color";
919     params->north_arrow_color->required = NO;
920     params->north_arrow_color->multiple = NO;
921     params->north_arrow_color->label = _("North arrow color");
922     params->north_arrow_color->guisection = _("Decoration");
923     params->north_arrow_color->answer = "black";
924 }
925 
926 /*!
927    \brief Get number of answers of given option
928 
929    \param pointer to option
930 
931    \return number of arguments
932  */
opt_get_num_answers(const struct Option * opt)933 int opt_get_num_answers(const struct Option *opt)
934 {
935     int i;
936 
937     i = 0;
938 
939     if (opt->answer) {
940 	while (opt->answers[i]) {
941 	    i++;
942 	}
943     }
944 
945     G_debug(3, "opt_get_num_answers(): opt=%s num=%d", opt->key, i);
946 
947     return i;
948 }
949 
950 /*!
951    \brief Check parameters consistency
952 
953    \param params module parameters
954  */
check_parameters(const struct GParams * params)955 void check_parameters(const struct GParams *params)
956 {
957     int nelev_map, nelev_const, nelevs;
958     int nmaps, nconsts, ncoords, ncplanes;
959 
960     int nvlines;
961 
962     int nvpoints, nvpoints_pos, nvpoints_layer;
963 
964     int nvolumes, nisosurf, nslices;
965 
966     /* topography */
967     nelev_map = opt_get_num_answers(params->elev_map);
968     nelev_const = opt_get_num_answers(params->elev_const);
969     nelevs = nelev_map + nelev_const;
970 
971 #if 0
972     if (nelevs < 1)
973 	G_fatal_error(_("At least one <%s> or <%s> required"),
974 		      params->elev_map->key, params->elev_const->key);
975 #endif
976     /* color */
977     nmaps = opt_get_num_answers(params->color_map);
978     nconsts = opt_get_num_answers(params->color_const);
979 
980     print_error(nmaps, nconsts, nelevs,
981 		params->elev_map->key, params->elev_const->key,
982 		params->color_map->key, params->color_const->key);
983 
984     /* mask */
985     nmaps = opt_get_num_answers(params->mask_map);
986     if (nmaps > 0 && nelevs != nmaps)
987 	G_fatal_error(_("Inconsistent number of attributes (<%s/%s>: %d vs. <%s>: %d)"),
988 		      params->elev_map->key, params->elev_const->key, nelevs,
989 		      params->mask_map->key, nmaps);
990 
991 
992     /* transparency */
993     nmaps = opt_get_num_answers(params->transp_map);
994     nconsts = opt_get_num_answers(params->transp_const);
995     print_error(nmaps, nconsts, nelevs,
996 		params->elev_map->key, params->elev_const->key,
997 		params->transp_map->key, params->transp_const->key);
998 
999     /* shininess */
1000     nmaps = opt_get_num_answers(params->shine_map);
1001     nconsts = opt_get_num_answers(params->shine_const);
1002     print_error(nmaps, nconsts, nelevs,
1003 		params->elev_map->key, params->elev_const->key,
1004 		params->shine_map->key, params->shine_const->key);
1005 
1006     /* emit */
1007     nmaps = opt_get_num_answers(params->emit_map);
1008     nconsts = opt_get_num_answers(params->emit_const);
1009     print_error(nmaps, nconsts, nelevs,
1010 		params->elev_map->key, params->elev_const->key,
1011 		params->emit_map->key, params->emit_const->key);
1012 
1013     /* draw mode */
1014     if (!params->mode_all->answer) {	/* use one mode for all surfaces */
1015 	nconsts = opt_get_num_answers(params->mode);
1016 	if (nconsts > 0 && nelevs > 0 && nconsts != nelevs)
1017 	    G_fatal_error(_("Inconsistent number of attributes (<%s/%s>: %d vs. <%s>: %d)"),
1018 			  params->elev_map->key, params->elev_const->key,
1019 			  nelevs, params->mode->key, nconsts);
1020 
1021 	nconsts = opt_get_num_answers(params->res_fine);
1022 	if (nconsts > 0 && nelevs > 0 && nconsts != nelevs)
1023 	    G_fatal_error(_("Inconsistent number of attributes (<%s/%s>: %d vs. <%s>: %d)"),
1024 			  params->elev_map->key, params->elev_const->key,
1025 			  nelevs, params->res_fine->key, nconsts);
1026 
1027 	nconsts = opt_get_num_answers(params->res_coarse);
1028 	if (nconsts > 0 && nelevs > 0 && nconsts != nelevs)
1029 	    G_fatal_error(_("Inconsistent number of attributes (<%s/%s>: %d vs. <%s>: %d)"),
1030 			  params->elev_map->key, params->elev_const->key,
1031 			  nelevs, params->res_coarse->key, nconsts);
1032 
1033 	nconsts = opt_get_num_answers(params->style);
1034 	if (nconsts > 0 && nelevs > 0 && nconsts != nelevs)
1035 	    G_fatal_error(_("Inconsistent number of attributes (<%s/%s>: %d vs. <%s>: %d)"),
1036 			  params->elev_map->key, params->elev_const->key,
1037 			  nelevs, params->style->key, nconsts);
1038 
1039 	nconsts = opt_get_num_answers(params->shade);
1040 	if (nconsts > 0 && nelevs > 0 && nconsts != nelevs)
1041 	    G_fatal_error(_("Inconsistent number of attributes (<%s/%s>: %d vs. <%s>: %d)"),
1042 			  params->elev_map->key, params->elev_const->key,
1043 			  nelevs, params->shade->key, nconsts);
1044 
1045 	nconsts = opt_get_num_answers(params->wire_color);
1046 	if (nconsts > 0 && nelevs > 0 && nconsts != nelevs)
1047 	    G_fatal_error(_("Inconsistent number of attributes (<%s/%s>: %d vs. <%s>: %d)"),
1048 			  params->elev_map->key, params->elev_const->key,
1049 			  nelevs, params->wire_color->key, nconsts);
1050     }
1051 
1052     /*
1053      * Cutting planes
1054      */
1055     ncplanes = opt_get_num_answers(params->cplane);
1056     ncoords = opt_get_num_answers(params->cplane_pos);
1057     if (ncplanes > 0 && ncplanes * 3 != ncoords)
1058 	G_fatal_error(_("Inconsistent number of attributes (<%s>: %d vs. <%s>: %d x 3)"),
1059 		      params->cplane->key, ncplanes, params->cplane_pos->key,
1060 		      ncoords / 3);
1061 
1062     nconsts = opt_get_num_answers(params->cplane_rot);
1063     if (ncplanes > 0 && ncplanes != nconsts)
1064 	G_fatal_error(_("Inconsistent number of attributes (<%s>: %d vs. <%s>: %d)"),
1065 		      params->cplane->key, ncplanes, params->cplane_rot->key,
1066 		      nconsts);
1067 
1068     nconsts = opt_get_num_answers(params->cplane_tilt);
1069     if (ncplanes > 0 && ncplanes != nconsts)
1070 	G_fatal_error(_("Inconsistent number of attributes (<%s>: %d vs. <%s>: %d)"),
1071 		      params->cplane->key, ncplanes, params->cplane_tilt->key,
1072 		      nconsts);
1073 
1074     /*
1075      * vector lines
1076      */
1077     nvlines = opt_get_num_answers(params->vlines);
1078 
1079     /* width */
1080     nconsts = opt_get_num_answers(params->vline_width);
1081     if (nvlines > 0 && nconsts != nvlines)
1082 	G_fatal_error(_("Inconsistent number of attributes (<%s>: %d vs. <%s>: %d)"),
1083 		      params->vlines->key, nvlines, params->vline_width->key,
1084 		      nconsts);
1085 
1086     /* color */
1087     nconsts = opt_get_num_answers(params->vline_color);
1088     if (nvlines > 0 && nconsts != nvlines)
1089 	G_fatal_error(_("Inconsistent number of attributes (<%s>: %d vs. <%s>: %d)"),
1090 		      params->vlines->key, nvlines, params->vline_color->key,
1091 		      nconsts);
1092 
1093     /* mode */
1094     nconsts = opt_get_num_answers(params->vline_mode);
1095     if (nvlines > 0 && nconsts != nvlines)
1096 	G_fatal_error(_("Inconsistent number of attributes (<%s>: %d vs. <%s>: %d)"),
1097 		      params->vlines->key, nvlines, params->vline_mode->key,
1098 		      nconsts);
1099 
1100     /* height */
1101     nconsts = opt_get_num_answers(params->vline_height);
1102     if (nvlines > 0 && nconsts != nvlines)
1103 	G_fatal_error(_("Inconsistent number of attributes (<%s>: %d vs. <%s>: %d)"),
1104 		      params->vlines->key, nvlines, params->vline_height->key,
1105 		      nconsts);
1106 
1107     /* position */
1108     nconsts = opt_get_num_answers(params->vline_pos);
1109     if (nvlines > 0 && nconsts != 3 * nvlines)
1110 	G_fatal_error(_("Inconsistent number of attributes (<%s>: %d vs. <%s>: %d)"),
1111 		      params->vlines->key, nvlines, params->vline_pos->key,
1112 		      nconsts);
1113 
1114     /*
1115      * vector points
1116      */
1117     nvpoints = opt_get_num_answers(params->vpoints);
1118     nvpoints_pos = opt_get_num_answers(params->vpoint_pos);
1119     nvpoints_layer = opt_get_num_answers(params->vpoint_layer);
1120 
1121     if (nvpoints && (nvpoints * 3 != nvpoints_pos))
1122 	G_fatal_error(_("Inconsistent number of attributes (<%s>: %d vs. <%s>: %d)"),
1123 		      params->vpoints->key, nvpoints, params->vpoint_pos->key,
1124 		      nvpoints_pos);
1125 
1126     if (nvpoints && (nvpoints != nvpoints_layer))
1127 	G_fatal_error(_("Inconsistent number of attributes (<%s>: %d vs. <%s>: %d)"),
1128 		      params->vpoints->key, nvpoints,
1129 		      params->vpoint_layer->key, nvpoints_layer);
1130 
1131 
1132     /* TODO */
1133 
1134     /*
1135      * volumes
1136      */
1137     nvolumes = opt_get_num_answers(params->volume);
1138     nisosurf = opt_get_num_answers(params->isosurf_level);
1139     nslices = opt_get_num_answers(params->slice);
1140 
1141     /* isosurface transparency */
1142     nmaps = opt_get_num_answers(params->isosurf_transp_map);
1143     nconsts = opt_get_num_answers(params->isosurf_transp_const);
1144 
1145     if ((nmaps + nconsts > 0) && (nisosurf != nmaps + nconsts))
1146 	G_fatal_error(_("Inconsistent number of attributes (<%s>: %d vs. <%s>: %d, <%s>: %d)"),
1147 		      params->isosurf_level->key, nisosurf,
1148 		      params->isosurf_transp_map->key, nmaps,
1149 		      params->isosurf_transp_const->key, nconsts);
1150 
1151     /* isosurface shininess */
1152     nmaps = opt_get_num_answers(params->isosurf_shine_map);
1153     nconsts = opt_get_num_answers(params->isosurf_shine_const);
1154 
1155     if ((nmaps + nconsts > 0) && (nisosurf != nmaps + nconsts))
1156 	G_fatal_error(_("Inconsistent number of attributes (<%s>: %d vs. <%s>: %d, <%s>: %d)"),
1157 		      params->isosurf_level->key, nisosurf,
1158 		      params->isosurf_shine_map->key, nmaps,
1159 		      params->isosurf_shine_const->key, nconsts);
1160 
1161     /* slice transparency */
1162     nconsts = opt_get_num_answers(params->slice_transp);
1163     if (nslices > 0 && nslices != nconsts)
1164 	G_fatal_error(_("Inconsistent number of attributes (<%s>: %d vs. <%s>: %d)"),
1165 		      params->slice->key, nslices, params->slice_transp->key,
1166 		      nconsts);
1167 
1168     /* slice position */
1169     ncoords = opt_get_num_answers(params->slice_pos);
1170     if (nslices > 0 && ncoords != 6 * nslices)
1171 	G_fatal_error(_("Inconsistent number of attributes (<%s>: %d vs. <%s>: %d x 6)"),
1172 		      params->slice->key, nslices, params->slice_pos->key,
1173 		      ncoords / 6);
1174 
1175     return;
1176 }
1177 
print_error(int nmaps,int nconsts,int nelevs,const char * elev_map,const char * elev_const,const char * map_name,const char * const_name)1178 void print_error(int nmaps, int nconsts, int nelevs,
1179 		 const char *elev_map, const char *elev_const,
1180 		 const char *map_name, const char *const_name)
1181 {
1182     if ((nmaps + nconsts > 0) && (nelevs != nmaps + nconsts))
1183 	G_fatal_error(_("Inconsistent number of attributes (<%s/%s>: %d vs. <%s>: %d, <%s>: %d)"),
1184 		      elev_map, elev_const, nelevs, map_name, nmaps,
1185 		      const_name, nconsts);
1186 
1187     return;
1188 }
1189