GRASS 8 Programmer's Manual  8.5.0dev(2025)-c070206eb1
units.c
Go to the documentation of this file.
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
14  googlemail.com> (2012)
15  */
16 
17 #include <string.h>
18 
19 #include <grass/gis.h>
20 #include <grass/glocale.h>
21 
22 /*!
23  \brief Units conversion from meters to units
24 
25  Units codes (gis.h):
26  - U_METERS
27  - U_KILOMETERS
28  - U_MILES
29  - U_FEET
30  - U_USFEET
31 
32  Returns a factor which converts meters to units (by multiplication).
33 
34  \param units units code
35 
36  \return factor
37  */
38 double G_meters_to_units_factor(int units)
39 {
40  switch (units) {
41  case U_METERS:
42  return 1.0;
43  break;
44 
45  case U_KILOMETERS:
46  return 1.0e-3;
47  break;
48 
49  case U_MILES:
50  return 6.21371192237334e-4; /* 1 / (0.0254 * 12 * 5280) */
51  break;
52 
53  case U_FEET:
54  return 3.28083989501312; /* 1 / (0.0254 * 12) */
55  break;
56 
57  case U_USFEET:
58  return 3.28083333333333; /* 1 / (1200/3937) */
59  break;
60 
61  default:
62  return 1.0;
63  break;
64  }
65 
66  return 1.0;
67 }
68 
69 /*!
70  \brief Units conversion from square meters to square units
71 
72  Units codes (gis.h):
73  - U_METERS
74  - U_KILOMETERS
75  - U_ACRES
76  - U_HECTARES
77  - U_MILES
78  - U_FEET
79  - U_USFEET
80 
81  Returns a factor which converts square meters to square units (by
82  multiplication).
83 
84  \param units units code
85 
86  \return factor
87  */
88 double G_meters_to_units_factor_sq(int units)
89 {
90  switch (units) {
91  case U_METERS:
92  return 1.0;
93  break;
94 
95  case U_KILOMETERS:
96  return 1.0e-6;
97  break;
98 
99  case U_ACRES:
100  return 2.47105381467165e-4; /* 640 acres in a sq mile */
101  break;
102 
103  case U_HECTARES:
104  return 1.0e-4;
105  break;
106 
107  case U_MILES:
108  return 3.86102158542446e-7; /* 1 / (0.0254 * 12 * 5280)^2 */
109  break;
110 
111  case U_FEET:
112  return 10.7639104167097; /* 1 / (0.0254 * 12)^2 */
113  break;
114 
115  case U_USFEET:
116  return 10.7638673611111; /* 1 / (1200/3937)^2 */
117  break;
118 
119  default:
120  return 1.0;
121  break;
122  }
123 
124  return 1.0;
125 }
126 
127 /** \brief Check if the unit is of spatial type
128 
129  \param units units code from gis.h
130 
131  \return 1 if True, 0 otherwise
132  */
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  */
165 {
166  switch (units) {
167  case U_YEARS:
168  return 1;
169  case U_MONTHS:
170  return 1;
171  case U_DAYS:
172  return 1;
173  case U_HOURS:
174  return 1;
175  case U_MINUTES:
176  return 1;
177  case U_SECONDS:
178  return 1;
179  }
180  return 0;
181 }
182 
183 /*!
184  \brief Get localized units name
185 
186  Units codes (gis.h):
187  - U_METERS
188  - U_KILOMETERS
189  - U_ACRES
190  - U_HECTARES
191  - U_MILES
192  - U_FEET
193  - U_USFEET
194 
195  \param units units code
196  \param plural plural form if true
197  \param square area units if true
198 
199  \return units name
200  \return NULL if units not found
201  */
202 const char *G_get_units_name(int units, int plural, int square)
203 {
204  switch (units) {
205  case U_UNKNOWN:
206  if (square)
207  return plural
208  // GTC: localized area units
209  ? _("square units")
210  // GTC: localized area units
211  : _("square unit");
212  else
213  return plural
214  // GTC: localized units
215  ? _("units")
216  // GTC: localized units
217  : _("unit");
218  break;
219 
220  case U_METERS:
221  if (square)
222  return plural
223  // GTC: localized area units
224  ? _("square meters")
225  // GTC: localized area units
226  : _("square meter");
227  else
228  return plural
229  // GTC: localized units
230  ? _("meters")
231  // GTC: localized units
232  : _("meter");
233  break;
234 
235  case U_KILOMETERS:
236  if (square)
237  return plural
238  // GTC: localized area units
239  ? _("square kilometers")
240  // GTC: localized area units
241  : _("square kilometer");
242  else
243  return plural
244  // GTC: localized units
245  ? _("kilometers")
246  // GTC: localized units
247  : _("kilometer");
248  break;
249 
250  case U_ACRES:
251  if (square)
252  return plural
253  // GTC: localized area units
254  ? _("acres")
255  // GTC: localized area units
256  : _("acre");
257  else
258  return G_get_units_name(G_units(G_database_unit_name(1)), plural,
259  square);
260  break;
261 
262  case U_HECTARES:
263  if (square)
264  return plural
265  // GTC: localized area units
266  ? _("hectares")
267  // GTC: localized area units
268  : _("hectare");
269  else
270  return G_get_units_name(G_units(G_database_unit_name(1)), plural,
271  square);
272  break;
273 
274  case U_MILES:
275  if (square)
276  return plural
277  // GTC: localized area units
278  ? _("square miles")
279  // GTC: localized area units
280  : _("square mile");
281  else
282  return plural
283  // GTC: localized units
284  ? _("miles")
285  // GTC: localized units
286  : _("mile");
287  break;
288 
289  case U_FEET:
290  if (square)
291  return plural
292  // GTC: localized area units, do not confuse with US feet
293  ? _("square feet")
294  // GTC: localized area units, do not confuse with US foot
295  : _("square foot");
296  else
297  return plural
298  // GTC: localized units, do not confuse with US feet
299  ? _("feet")
300  // GTC: localized units, do not confuse with US foot
301  : _("foot");
302  break;
303 
304  case U_USFEET:
305  if (square)
306  return plural
307  // GTC: localized area units, do not confuse with feet
308  ? _("square US feet")
309  // GTC: localized area units, do not confuse with foot
310  : _("square US foot");
311  else
312  return plural
313  // GTC: localized units, do not confuse with feet
314  ? _("US feet")
315  // GTC: localized units, do not confuse with foot
316  : _("US foot");
317  break;
318 
319  case U_DEGREES:
320  if (square)
321  return plural
322  // GTC: localized area units
323  ? _("square degrees")
324  // GTC: localized area units
325  : _("square degree");
326  else
327  return plural
328  // GTC: localized units
329  ? _("degrees")
330  // GTC: localized units
331  : _("degree");
332  break;
333 
334  case U_YEARS:
335  return plural
336  // GTC: localized time units
337  ? _("years")
338  // GTC: localized time units
339  : _("year");
340  break;
341 
342  case U_MONTHS:
343  return plural
344  // GTC: localized time units
345  ? _("months")
346  // GTC: localized time units
347  : _("month");
348  break;
349 
350  case U_DAYS:
351  return plural
352  // GTC: localized time units
353  ? _("days")
354  // GTC: localized time units
355  : _("day");
356  break;
357 
358  case U_HOURS:
359  return plural
360  // GTC: localized time units
361  ? _("hours")
362  // GTC: localized time units
363  : _("hour");
364  break;
365 
366  case U_MINUTES:
367  return plural
368  // GTC: localized time units
369  ? _("minutes")
370  // GTC: localized time units
371  : _("minute");
372  break;
373 
374  case U_SECONDS:
375  return plural
376  // GTC: localized time units
377  ? _("seconds")
378  // GTC: localized time units
379  : _("second");
380  break;
381  }
382 
383  return NULL;
384 }
385 
386 /*!
387  \brief Get units code by name
388 
389  Units codes (gis.h):
390  - U_METERS
391  - U_KILOMETERS
392  - U_ACRES
393  - U_HECTARES
394  - U_MILES
395  - U_FEET
396  - U_USFEET
397  - ...
398  - U_YEARS
399  - ...
400 
401  \param units_name units name (singular or plural form)
402 
403  \return units code
404  \return U_UNKNOWN if not found
405  */
406 int G_units(const char *units_name)
407 {
408  if (units_name == NULL) {
409  return G_units(G_database_unit_name(1));
410  }
411 
412  if (strcasecmp(units_name, "meter") == 0 ||
413  strcasecmp(units_name, "meters") == 0)
414  return U_METERS;
415  else if (strcasecmp(units_name, "kilometer") == 0 ||
416  strcasecmp(units_name, "kilometers") == 0)
417  return U_KILOMETERS;
418  else if (strcasecmp(units_name, "acre") == 0 ||
419  strcasecmp(units_name, "acres") == 0)
420  return U_ACRES;
421  else if (strcasecmp(units_name, "hectare") == 0 ||
422  strcasecmp(units_name, "hectares") == 0)
423  return U_HECTARES;
424  else if (strcasecmp(units_name, "mile") == 0 ||
425  strcasecmp(units_name, "miles") == 0)
426  return U_MILES;
427  else if (strcasecmp(units_name, "foot") == 0 ||
428  strcasecmp(units_name, "feet") == 0)
429  return U_FEET;
430  else if (strcasecmp(units_name, "foot_us") == 0 ||
431  strcasecmp(units_name, "foot_uss") == 0)
432  return U_USFEET;
433  else if (strcasecmp(units_name, "degree") == 0 ||
434  strcasecmp(units_name, "degrees") == 0)
435  return U_DEGREES;
436  else if (strcasecmp(units_name, "year") == 0 ||
437  strcasecmp(units_name, "years") == 0)
438  return U_YEARS;
439  else if (strcasecmp(units_name, "month") == 0 ||
440  strcasecmp(units_name, "months") == 0)
441  return U_MONTHS;
442  else if (strcasecmp(units_name, "day") == 0 ||
443  strcasecmp(units_name, "days") == 0)
444  return U_DAYS;
445  else if (strcasecmp(units_name, "hour") == 0 ||
446  strcasecmp(units_name, "hours") == 0)
447  return U_HOURS;
448  else if (strcasecmp(units_name, "minute") == 0 ||
449  strcasecmp(units_name, "minutes") == 0)
450  return U_MINUTES;
451  else if (strcasecmp(units_name, "second") == 0 ||
452  strcasecmp(units_name, "seconds") == 0)
453  return U_SECONDS;
454 
455  return U_UNKNOWN;
456 }
#define NULL
Definition: ccmath.h:32
const char * G_database_unit_name(int)
Get units (localized) name for the current location.
Definition: proj3.c:53
#define U_SECONDS
Definition: gis.h:120
#define U_HOURS
Definition: gis.h:118
#define U_MINUTES
Definition: gis.h:119
#define U_DAYS
Definition: gis.h:117
#define U_FEET
Definition: gis.h:110
#define U_ACRES
Definition: gis.h:105
#define U_MONTHS
Definition: gis.h:116
#define U_RADIANS
Definition: gis.h:111
#define U_METERS
Definition: gis.h:108
#define U_DEGREES
Definition: gis.h:112
#define U_YEARS
Definition: gis.h:115
#define U_UNKNOWN
Definition: gis.h:104
#define U_HECTARES
Definition: gis.h:106
#define U_USFEET
Definition: gis.h:113
#define U_MILES
Definition: gis.h:109
#define U_KILOMETERS
Definition: gis.h:107
#define _(str)
Definition: glocale.h:10
#define strcasecmp
Definition: strings.h:8
double G_meters_to_units_factor(int units)
Units conversion from meters to units.
Definition: units.c:38
const char * G_get_units_name(int units, int plural, int square)
Get localized units name.
Definition: units.c:202
double G_meters_to_units_factor_sq(int units)
Units conversion from square meters to square units.
Definition: units.c:88
int G_is_units_type_spatial(int units)
Check if the unit is of spatial type.
Definition: units.c:133
int G_is_units_type_temporal(int units)
Check if the unit is of temporal type.
Definition: units.c:164
int G_units(const char *units_name)
Get units code by name.
Definition: units.c:406