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