1 /*!
2   \file lib/gis/units.c
3 
4   \brief GIS Library - Units management and conversion
5 
6   (C) 2001-2010 by the GRASS Development Team
7 
8   This program is free software under the GNU General Public License
9   (>=v2). Read the file COPYING that comes with GRASS for details.
10 
11   \author Original author CERL
12   \author Adopted for libgis by Martin Landa <landa.martin gmail.com> (2010)
13   \author Temporal units and unit type check from Soeren gebbert <soerengebbert googlemail.com> (2012)
14  */
15 
16 #include <string.h>
17 
18 #include <grass/gis.h>
19 #include <grass/glocale.h>
20 
21 /*!
22   \brief Units conversion from meters to units
23 
24   Units codes (gis.h):
25    - U_METERS
26    - U_KILOMETERS
27    - U_MILES
28    - U_FEET
29    - U_USFEET
30 
31   Returns a factor which converts meters to units (by multiplication).
32 
33   \param units units code
34 
35   \return factor
36 */
G_meters_to_units_factor(int units)37 double G_meters_to_units_factor(int units)
38 {
39     switch (units) {
40     case U_METERS:
41 	return 1.0;
42 	break;
43 
44     case U_KILOMETERS:
45 	return 1.0e-3;
46 	break;
47 
48     case U_MILES:
49 	return 6.21371192237334e-4;	        /*  1 / (0.0254 * 12 * 5280)    */
50 	break;
51 
52     case U_FEET:
53 	return 3.28083989501312;	        /*  1 / (0.0254 * 12)    */
54 	break;
55 
56     case U_USFEET:
57 	return 3.28083333333333;       	        /*  1 / (1200/3937)    */
58 	break;
59 
60     default:
61 	return 1.0;
62 	break;
63     }
64 
65     return 1.0;
66 }
67 
68 /*!
69   \brief Units conversion from square meters to square units
70 
71   Units codes (gis.h):
72    - U_METERS
73    - U_KILOMETERS
74    - U_ACRES
75    - U_HECTARES
76    - U_MILES
77    - U_FEET
78    - U_USFEET
79 
80   Returns a factor which converts square meters to square units (by
81   multiplication).
82 
83   \param units units code
84 
85   \return factor
86 */
G_meters_to_units_factor_sq(int units)87 double G_meters_to_units_factor_sq(int units)
88 {
89     switch (units) {
90     case U_METERS:
91 	return 1.0;
92 	break;
93 
94     case U_KILOMETERS:
95 	return 1.0e-6;
96 	break;
97 
98     case U_ACRES:
99 	return 2.47105381467165e-4;	/* 640 acres in a sq mile */
100 	break;
101 
102     case U_HECTARES:
103 	return 1.0e-4;
104 	break;
105 
106     case U_MILES:
107 	return 3.86102158542446e-7;	/*  1 / (0.0254 * 12 * 5280)^2  */
108 	break;
109 
110     case U_FEET:
111 	return 10.7639104167097;	/*  1 / (0.0254 * 12)^2  */
112 	break;
113 
114     case U_USFEET:
115 	return 10.7638673611111;       	/*  1 / (1200/3937)^2    */
116 	break;
117 
118     default:
119 	return 1.0;
120 	break;
121     }
122 
123     return 1.0;
124 }
125 
126 /** \brief Check if the unit is of spatial type
127 
128   \param units units code from gis.h
129 
130   \return 1 if True, 0 otherwise
131  */
132 
G_is_units_type_spatial(int units)133 int G_is_units_type_spatial(int units)
134 {
135     switch (units) {
136     case U_METERS:
137         return 1;
138     case U_KILOMETERS:
139         return 1;
140     case U_HECTARES:
141         return 1;
142     case U_ACRES:
143         return 1;
144     case U_MILES:
145         return 1;
146     case U_FEET:
147         return 1;
148     case U_USFEET:
149         return 1;
150     case U_RADIANS:
151         return 1;
152     case U_DEGREES:
153         return 1;
154     }
155     return 0;
156 }
157 
158 /** \brief Check if the unit is of temporal type
159 
160   \param units units code from gis.h
161 
162   \return 1 if True, 0 otherwise
163  */
164 
G_is_units_type_temporal(int units)165 int G_is_units_type_temporal(int units)
166 {
167     switch (units) {
168     case U_YEARS:
169         return 1;
170     case U_MONTHS:
171         return 1;
172     case U_DAYS:
173         return 1;
174     case U_HOURS:
175         return 1;
176     case U_MINUTES:
177         return 1;
178     case U_SECONDS:
179         return 1;
180     }
181     return 0;
182 }
183 
184 /*!
185   \brief Get localized units name
186 
187   Units codes (gis.h):
188    - U_METERS
189    - U_KILOMETERS
190    - U_ACRES
191    - U_HECTARES
192    - U_MILES
193    - U_FEET
194    - U_USFEET
195 
196   \param units units code
197   \param plural plural form if true
198   \param square area units if true
199 
200   \return units name
201   \return NULL if units not found
202 */
G_get_units_name(int units,int plural,int square)203 const char *G_get_units_name(int units, int plural, int square)
204 {
205     switch (units) {
206     case U_UNKNOWN:
207 	if (square)
208 	    return plural ? _("square units") : _("square unit");
209 	else
210 	    return plural ? _("units") : _("unit");
211 	break;
212 
213     case U_METERS:
214 	if (square)
215 	    return plural ? _("square meters") : _("square meter");
216 	else
217 	    return plural ? _("meters") : _("meter");
218 	break;
219 
220     case U_KILOMETERS:
221 	if (square)
222 	    return plural ? _("square kilometers") : _("square kilometer");
223 	else
224 	    return plural ? _("kilometers") : _("kilometer");
225 	break;
226 
227     case U_ACRES:
228 	if (square)
229 	    return plural ? _("acres") : _("acre");
230 	else
231 	    return G_get_units_name(G_units(G_database_unit_name(1)),
232 				    plural, square);
233 	break;
234 
235     case U_HECTARES:
236 	if (square)
237 	    return plural ? _("hectares") : _("hectare");
238 	else
239 	    return G_get_units_name(G_units(G_database_unit_name(1)),
240 				    plural, square);
241 	break;
242 
243     case U_MILES:
244 	if (square)
245 	    return plural ? _("square miles") : _("square mile");
246 	else
247 	    return plural ? _("miles") : _("mile");
248 	break;
249 
250     case U_FEET:
251 	if (square)
252 	    return plural ? _("square feet") : _("square foot");
253 	else
254 	    return plural ? _("feet") : _("foot");
255 	break;
256 
257     case U_USFEET:
258 	if (square)
259 	    return plural ? _("square US feet") : _("square US foot");
260 	else
261 	    return plural ? _("US feet") : _("US foot");
262 	break;
263 
264     case U_DEGREES:
265 	if (square)
266 	    return plural ? _("square degrees") : _("square degree");
267 	else
268 	    return plural ? _("degrees") : _("degree");
269 	break;
270 
271     case U_YEARS:
272 	return plural ? _("years") : _("year");
273 	break;
274 
275     case U_MONTHS:
276 	return plural ? _("months") : _("month");
277 	break;
278 
279     case U_DAYS:
280 	return plural ? _("days") : _("day");
281 	break;
282 
283     case U_HOURS:
284 	return plural ? _("hours") : _("hour");
285 	break;
286 
287     case U_MINUTES:
288 	return plural ? _("minutes") : _("minute");
289 	break;
290 
291     case U_SECONDS:
292 	return plural ? _("seconds") : _("second");
293 	break;
294     }
295 
296     return NULL;
297 }
298 
299 /*!
300   \brief Get units code by name
301 
302   Units codes (gis.h):
303    - U_METERS
304    - U_KILOMETERS
305    - U_ACRES
306    - U_HECTARES
307    - U_MILES
308    - U_FEET
309    - U_USFEET
310    - ...
311    - U_YEARS
312    - ...
313 
314   \param units_name units name (singular or plural form)
315 
316   \return units code
317   \return U_UNKNOWN if not found
318 */
G_units(const char * units_name)319 int G_units(const char *units_name)
320 {
321     if (units_name == NULL) {
322 	return G_units(G_database_unit_name(1));
323     }
324 
325     if (strcasecmp(units_name, "meter") == 0 ||
326 	strcasecmp(units_name, "meters") == 0)
327 	return U_METERS;
328     else if (strcasecmp(units_name, "kilometer") == 0 ||
329 	     strcasecmp(units_name, "kilometers") == 0)
330 	return U_KILOMETERS;
331     else if (strcasecmp(units_name, "acre") == 0 ||
332 	     strcasecmp(units_name, "acres") == 0)
333 	return U_ACRES;
334     else if (strcasecmp(units_name, "hectare") == 0 ||
335 	     strcasecmp(units_name, "hectares") == 0)
336 	return U_HECTARES;
337     else if (strcasecmp(units_name, "mile") == 0 ||
338 	     strcasecmp(units_name, "miles") == 0)
339 	return U_MILES;
340     else if (strcasecmp(units_name, "foot") == 0 ||
341 	     strcasecmp(units_name, "feet") == 0)
342 	return U_FEET;
343     else if (strcasecmp(units_name, "foot_us") == 0 ||
344 	     strcasecmp(units_name, "foot_uss") == 0)
345 	return U_USFEET;
346     else if (strcasecmp(units_name, "degree") == 0 ||
347 	     strcasecmp(units_name, "degrees") == 0)
348 	return U_DEGREES;
349     else if (strcasecmp(units_name, "year") == 0 ||
350 	     strcasecmp(units_name, "years") == 0)
351 	return U_YEARS;
352     else if (strcasecmp(units_name, "month") == 0 ||
353 	     strcasecmp(units_name, "months") == 0)
354 	return U_MONTHS;
355     else if (strcasecmp(units_name, "day") == 0 ||
356 	     strcasecmp(units_name, "days") == 0)
357 	return U_DAYS;
358     else if (strcasecmp(units_name, "hour") == 0 ||
359 	     strcasecmp(units_name, "hours") == 0)
360 	return U_HOURS;
361     else if (strcasecmp(units_name, "minute") == 0 ||
362 	     strcasecmp(units_name, "minutes") == 0)
363 	return U_MINUTES;
364     else if (strcasecmp(units_name, "secons") == 0 ||
365 	     strcasecmp(units_name, "seconds") == 0)
366 	return U_SECONDS;
367 
368     return U_UNKNOWN;
369 }
370