GRASS GIS 8 Programmer's Manual  8.5.0dev(2025)-091e758e18
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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  */
133 
135 {
136  switch (units) {
137  case U_METERS:
138  return 1;
139  case U_KILOMETERS:
140  return 1;
141  case U_HECTARES:
142  return 1;
143  case U_ACRES:
144  return 1;
145  case U_MILES:
146  return 1;
147  case U_FEET:
148  return 1;
149  case U_USFEET:
150  return 1;
151  case U_RADIANS:
152  return 1;
153  case U_DEGREES:
154  return 1;
155  }
156  return 0;
157 }
158 
159 /** \brief Check if the unit is of temporal type
160 
161  \param units units code from gis.h
162 
163  \return 1 if True, 0 otherwise
164  */
165 
167 {
168  switch (units) {
169  case U_YEARS:
170  return 1;
171  case U_MONTHS:
172  return 1;
173  case U_DAYS:
174  return 1;
175  case U_HOURS:
176  return 1;
177  case U_MINUTES:
178  return 1;
179  case U_SECONDS:
180  return 1;
181  }
182  return 0;
183 }
184 
185 /*!
186  \brief Get localized units name
187 
188  Units codes (gis.h):
189  - U_METERS
190  - U_KILOMETERS
191  - U_ACRES
192  - U_HECTARES
193  - U_MILES
194  - U_FEET
195  - U_USFEET
196 
197  \param units units code
198  \param plural plural form if true
199  \param square area units if true
200 
201  \return units name
202  \return NULL if units not found
203  */
204 const char *G_get_units_name(int units, int plural, int square)
205 {
206  switch (units) {
207  case U_UNKNOWN:
208  if (square)
209  return plural
210  // GTC: localized area units
211  ? _("square units")
212  // GTC: localized area units
213  : _("square unit");
214  else
215  return plural
216  // GTC: localized units
217  ? _("units")
218  // GTC: localized units
219  : _("unit");
220  break;
221 
222  case U_METERS:
223  if (square)
224  return plural
225  // GTC: localized area units
226  ? _("square meters")
227  // GTC: localized area units
228  : _("square meter");
229  else
230  return plural
231  // GTC: localized units
232  ? _("meters")
233  // GTC: localized units
234  : _("meter");
235  break;
236 
237  case U_KILOMETERS:
238  if (square)
239  return plural
240  // GTC: localized area units
241  ? _("square kilometers")
242  // GTC: localized area units
243  : _("square kilometer");
244  else
245  return plural
246  // GTC: localized units
247  ? _("kilometers")
248  // GTC: localized units
249  : _("kilometer");
250  break;
251 
252  case U_ACRES:
253  if (square)
254  return plural
255  // GTC: localized area units
256  ? _("acres")
257  // GTC: localized area units
258  : _("acre");
259  else
260  return G_get_units_name(G_units(G_database_unit_name(1)), plural,
261  square);
262  break;
263 
264  case U_HECTARES:
265  if (square)
266  return plural
267  // GTC: localized area units
268  ? _("hectares")
269  // GTC: localized area units
270  : _("hectare");
271  else
272  return G_get_units_name(G_units(G_database_unit_name(1)), plural,
273  square);
274  break;
275 
276  case U_MILES:
277  if (square)
278  return plural
279  // GTC: localized area units
280  ? _("square miles")
281  // GTC: localized area units
282  : _("square mile");
283  else
284  return plural
285  // GTC: localized units
286  ? _("miles")
287  // GTC: localized units
288  : _("mile");
289  break;
290 
291  case U_FEET:
292  if (square)
293  return plural
294  // GTC: localized area units, do not confuse with US feet
295  ? _("square feet")
296  // GTC: localized area units, do not confuse with US foot
297  : _("square foot");
298  else
299  return plural
300  // GTC: localized units, do not confuse with US feet
301  ? _("feet")
302  // GTC: localized units, do not confuse with US foot
303  : _("foot");
304  break;
305 
306  case U_USFEET:
307  if (square)
308  return plural
309  // GTC: localized area units, do not confuse with feet
310  ? _("square US feet")
311  // GTC: localized area units, do not confuse with foot
312  : _("square US foot");
313  else
314  return plural
315  // GTC: localized units, do not confuse with feet
316  ? _("US feet")
317  // GTC: localized units, do not confuse with foot
318  : _("US foot");
319  break;
320 
321  case U_DEGREES:
322  if (square)
323  return plural
324  // GTC: localized area units
325  ? _("square degrees")
326  // GTC: localized area units
327  : _("square degree");
328  else
329  return plural
330  // GTC: localized units
331  ? _("degrees")
332  // GTC: localized units
333  : _("degree");
334  break;
335 
336  case U_YEARS:
337  return plural
338  // GTC: localized time units
339  ? _("years")
340  // GTC: localized time units
341  : _("year");
342  break;
343 
344  case U_MONTHS:
345  return plural
346  // GTC: localized time units
347  ? _("months")
348  // GTC: localized time units
349  : _("month");
350  break;
351 
352  case U_DAYS:
353  return plural
354  // GTC: localized time units
355  ? _("days")
356  // GTC: localized time units
357  : _("day");
358  break;
359 
360  case U_HOURS:
361  return plural
362  // GTC: localized time units
363  ? _("hours")
364  // GTC: localized time units
365  : _("hour");
366  break;
367 
368  case U_MINUTES:
369  return plural
370  // GTC: localized time units
371  ? _("minutes")
372  // GTC: localized time units
373  : _("minute");
374  break;
375 
376  case U_SECONDS:
377  return plural
378  // GTC: localized time units
379  ? _("seconds")
380  // GTC: localized time units
381  : _("second");
382  break;
383  }
384 
385  return NULL;
386 }
387 
388 /*!
389  \brief Get units code by name
390 
391  Units codes (gis.h):
392  - U_METERS
393  - U_KILOMETERS
394  - U_ACRES
395  - U_HECTARES
396  - U_MILES
397  - U_FEET
398  - U_USFEET
399  - ...
400  - U_YEARS
401  - ...
402 
403  \param units_name units name (singular or plural form)
404 
405  \return units code
406  \return U_UNKNOWN if not found
407  */
408 int G_units(const char *units_name)
409 {
410  if (units_name == NULL) {
411  return G_units(G_database_unit_name(1));
412  }
413 
414  if (strcasecmp(units_name, "meter") == 0 ||
415  strcasecmp(units_name, "meters") == 0)
416  return U_METERS;
417  else if (strcasecmp(units_name, "kilometer") == 0 ||
418  strcasecmp(units_name, "kilometers") == 0)
419  return U_KILOMETERS;
420  else if (strcasecmp(units_name, "acre") == 0 ||
421  strcasecmp(units_name, "acres") == 0)
422  return U_ACRES;
423  else if (strcasecmp(units_name, "hectare") == 0 ||
424  strcasecmp(units_name, "hectares") == 0)
425  return U_HECTARES;
426  else if (strcasecmp(units_name, "mile") == 0 ||
427  strcasecmp(units_name, "miles") == 0)
428  return U_MILES;
429  else if (strcasecmp(units_name, "foot") == 0 ||
430  strcasecmp(units_name, "feet") == 0)
431  return U_FEET;
432  else if (strcasecmp(units_name, "foot_us") == 0 ||
433  strcasecmp(units_name, "foot_uss") == 0)
434  return U_USFEET;
435  else if (strcasecmp(units_name, "degree") == 0 ||
436  strcasecmp(units_name, "degrees") == 0)
437  return U_DEGREES;
438  else if (strcasecmp(units_name, "year") == 0 ||
439  strcasecmp(units_name, "years") == 0)
440  return U_YEARS;
441  else if (strcasecmp(units_name, "month") == 0 ||
442  strcasecmp(units_name, "months") == 0)
443  return U_MONTHS;
444  else if (strcasecmp(units_name, "day") == 0 ||
445  strcasecmp(units_name, "days") == 0)
446  return U_DAYS;
447  else if (strcasecmp(units_name, "hour") == 0 ||
448  strcasecmp(units_name, "hours") == 0)
449  return U_HOURS;
450  else if (strcasecmp(units_name, "minute") == 0 ||
451  strcasecmp(units_name, "minutes") == 0)
452  return U_MINUTES;
453  else if (strcasecmp(units_name, "second") == 0 ||
454  strcasecmp(units_name, "seconds") == 0)
455  return U_SECONDS;
456 
457  return U_UNKNOWN;
458 }
#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:204
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:134
int G_is_units_type_temporal(int units)
Check if the unit is of temporal type.
Definition: units.c:166
int G_units(const char *units_name)
Get units code by name.
Definition: units.c:408