GRASS GIS 8 Programmer's Manual  8.5.0dev(2024)-36359e2344
cnversions.c
Go to the documentation of this file.
1 #include <math.h>
2 #include <grass/gis.h>
3 #include <grass/display.h>
4 
5 /****** OLD CODE
6  * #include "windround.h"
7  **********/
8 /* D_do_conversions(window, t, b, l, r)
9  * struct Cell_head *window ;
10  * int t, b, l, r ;
11  *
12  * Sets up conversion coefficients to translate between three
13  * coordinate systems:
14  *
15  * 1. Screen coordinates (given by t, b, l, r values)
16  * 2. UTM coordinates (given by values in window structure)
17  * 3. Window array coors (given by values in window structure)
18  *
19  * Once D_do_conversions is called, lots of conversion coefficients
20  * and conversion routines are available.
21  *
22  * Calls to convert row and column (x and y) values in one system to
23  * another system are available. In addition calls which return the
24  * conversion coefficients are also provided.
25  */
26 
27 struct vector {
28  double x, y;
29 };
30 
31 struct rect {
32  double west;
33  double east;
34  double south;
35  double north;
36  struct vector size;
37 };
38 
39 /* Bounding rectangles */
40 static struct rect D; /* Display coordinates, pixels, (0,0) towards NW */
41 static struct rect A; /* Map array coordinates, integers, (0,0) towards NW */
42 static struct rect U; /* UTM coordinates, meters, (0,0) towards SW */
43 
44 /* Conversion factors */
45 static struct vector D_to_A_conv; /* Display to Array */
46 static struct vector A_to_U_conv; /* Array to UTM */
47 static struct vector U_to_D_conv; /* UTM to Display */
48 
49 /* others */
50 static int is_lat_lon;
51 
52 static void calc_size(struct rect *rect)
53 {
54  rect->size.x = rect->east - rect->west;
55  rect->size.y = rect->south - rect->north;
56 }
57 
58 static void calc_conv(struct vector *conv, const struct vector *src,
59  const struct vector *dst)
60 {
61  conv->x = dst->x / src->x;
62  conv->y = dst->y / src->y;
63 }
64 
65 static void fit_aspect(struct rect *rect, const struct rect *ref)
66 {
67  struct vector conv;
68  double scale, size, delta;
69 
70  calc_conv(&conv, &rect->size, &ref->size);
71 
72  if (fabs(conv.y) > fabs(conv.x)) {
73  scale = fabs(conv.y) / fabs(conv.x);
74  size = rect->size.x / scale;
75  delta = rect->size.x - size;
76  rect->west += delta / 2;
77  rect->east -= delta / 2;
78  rect->size.x = size;
79  }
80  else {
81  scale = fabs(conv.x) / fabs(conv.y);
82  size = rect->size.y / scale;
83  delta = rect->size.y - size;
84  rect->north += delta / 2;
85  rect->south -= delta / 2;
86  rect->size.y = size;
87  }
88 }
89 
91 {
92  calc_conv(&D_to_A_conv, &D.size, &A.size);
93  calc_conv(&A_to_U_conv, &A.size, &U.size);
94  calc_conv(&U_to_D_conv, &U.size, &D.size);
95 }
96 
97 void D_fit_d_to_u(void)
98 {
99  fit_aspect(&D, &U);
100 }
101 
102 void D_fit_u_to_d(void)
103 {
104  fit_aspect(&U, &D);
105 }
106 
108 {
109  fprintf(stderr, " D_w %10.1f D_e %10.1f D_s %10.1f D_n %10.1f\n", D.west,
110  D.east, D.south, D.north);
111  fprintf(stderr, " A_w %10.1f A_e %10.1f A_s %10.1f A_n %10.1f\n", A.west,
112  A.east, A.south, A.north);
113  fprintf(stderr, " U_w %10.1f U_e %10.1f U_s %10.1f U_n %10.1f\n\n",
114  U.west, U.east, U.south, U.north);
115 
116  fprintf(stderr, " D_x %10.1f D_y %10.1f\n", D.size.x, D.size.y);
117  fprintf(stderr, " A_x %10.1f A_y %10.1f\n", A.size.x, A.size.y);
118  fprintf(stderr, " U_x %10.1f U_y %10.1f\n\n", U.size.x, U.size.y);
119 
120  fprintf(stderr, " D_to_A_conv.x %10.1f D_to_A_conv.y %10.1f\n",
121  D_to_A_conv.x, D_to_A_conv.y);
122  fprintf(stderr, " A_to_U_conv.x %10.1f A_to_U_conv.y %10.1f\n",
123  A_to_U_conv.x, A_to_U_conv.y);
124  fprintf(stderr, " U_to_D_conv.x %10.1g U_to_D_conv.y %10.1g\n",
125  U_to_D_conv.x, U_to_D_conv.y);
126 }
127 
128 /*!
129  * \brief initialize conversions
130  *
131  * The relationship between the earth <b>region</b> and the <b>top, bottom,
132  * left</b>, and <b>right</b> screen coordinates is established, which then
133  * allows conversions between all three coordinate systems to be performed.
134  * Note this routine is called by <i>D_setup</i>.
135  *
136  * \param window region
137  * \param t top
138  * \param b bottom
139  * \param l left
140  * \param r right
141  * \return none
142  */
143 void D_do_conversions(const struct Cell_head *window, double t, double b,
144  double l, double r)
145 {
146  D_set_region(window);
147  D_set_dst(t, b, l, r);
148  D_fit_d_to_u();
150 #ifdef DEBUG
152 #endif /* DEBUG */
153 }
154 
155 int D_is_lat_lon(void)
156 {
157  return (is_lat_lon);
158 }
159 
160 double D_get_d_to_a_xconv(void)
161 {
162  return (D_to_A_conv.x);
163 }
164 double D_get_d_to_a_yconv(void)
165 {
166  return (D_to_A_conv.y);
167 }
168 double D_get_d_to_u_xconv(void)
169 {
170  return (1 / U_to_D_conv.x);
171 }
172 double D_get_d_to_u_yconv(void)
173 {
174  return (1 / U_to_D_conv.y);
175 }
176 double D_get_a_to_u_xconv(void)
177 {
178  return (A_to_U_conv.x);
179 }
180 double D_get_a_to_u_yconv(void)
181 {
182  return (A_to_U_conv.y);
183 }
184 double D_get_a_to_d_xconv(void)
185 {
186  return (1 / D_to_A_conv.x);
187 }
188 double D_get_a_to_d_yconv(void)
189 {
190  return (1 / D_to_A_conv.y);
191 }
192 double D_get_u_to_d_xconv(void)
193 {
194  return (U_to_D_conv.x);
195 }
196 double D_get_u_to_d_yconv(void)
197 {
198  return (U_to_D_conv.y);
199 }
200 double D_get_u_to_a_xconv(void)
201 {
202  return (1 / A_to_U_conv.x);
203 }
204 double D_get_u_to_a_yconv(void)
205 {
206  return (1 / A_to_U_conv.y);
207 }
208 
210 {
211  return D_get_a_to_u_yconv();
212 }
214 {
215  return D_get_a_to_u_xconv();
216 }
217 
218 double D_get_u_west(void)
219 {
220  return (U.west);
221 }
222 double D_get_u_east(void)
223 {
224  return (U.east);
225 }
226 double D_get_u_north(void)
227 {
228  return (U.north);
229 }
230 double D_get_u_south(void)
231 {
232  return (U.south);
233 }
234 
235 double D_get_a_west(void)
236 {
237  return (A.west);
238 }
239 double D_get_a_east(void)
240 {
241  return (A.east);
242 }
243 double D_get_a_north(void)
244 {
245  return (A.north);
246 }
247 double D_get_a_south(void)
248 {
249  return (A.south);
250 }
251 
252 double D_get_d_west(void)
253 {
254  return (D.west);
255 }
256 double D_get_d_east(void)
257 {
258  return (D.east);
259 }
260 double D_get_d_north(void)
261 {
262  return (D.north);
263 }
264 double D_get_d_south(void)
265 {
266  return (D.south);
267 }
268 
269 void D_set_region(const struct Cell_head *window)
270 {
271  D_set_src(window->north, window->south, window->west, window->east);
272  D_set_grid(0, window->rows, 0, window->cols);
273  is_lat_lon = (window->proj == PROJECTION_LL);
274 }
275 
276 void D_set_src(double t, double b, double l, double r)
277 {
278  U.north = t;
279  U.south = b;
280  U.west = l;
281  U.east = r;
282  calc_size(&U);
283 }
284 
285 /*!
286  * \brief returns frame bounds in source coordinate system
287  *
288  * D_get_src() returns the frame bounds in the source coordinate system
289  * (used by D_* functions)
290  *
291  * \param t top
292  * \param b bottom
293  * \param l left
294  * \param r right
295  * \return void
296  */
297 void D_get_src(double *t, double *b, double *l, double *r)
298 {
299  *t = U.north;
300  *b = U.south;
301  *l = U.west;
302  *r = U.east;
303 }
304 
305 void D_set_grid(int t, int b, int l, int r)
306 {
307  A.north = t;
308  A.south = b;
309  A.west = l;
310  A.east = r;
311  calc_size(&A);
312 }
313 
314 void D_get_grid(int *t, int *b, int *l, int *r)
315 {
316  *t = A.north;
317  *b = A.south;
318  *l = A.west;
319  *r = A.east;
320 }
321 
322 void D_set_dst(double t, double b, double l, double r)
323 {
324  D.north = t;
325  D.south = b;
326  D.west = l;
327  D.east = r;
328  calc_size(&D);
329 }
330 
331 /*!
332  * \brief returns frame bounds in destination coordinate system
333  *
334  * D_get_dst() returns the frame bounds in the destination coordinate system
335  * (used by R_* commands).
336  * The various D_setup() commands all set the destination coordinate
337  * system to the current frame reported by R_get_window().
338  *
339  * \param t top
340  * \param b bottom
341  * \param l left
342  * \param r right
343  * \return none
344  */
345 void D_get_dst(double *t, double *b, double *l, double *r)
346 {
347  *t = D.north;
348  *b = D.south;
349  *l = D.west;
350  *r = D.east;
351 }
352 
353 void D_get_u(double x[2][2])
354 {
355  x[0][0] = U.west;
356  x[0][1] = U.east;
357  x[1][0] = U.north;
358  x[1][1] = U.south;
359 }
360 
361 void D_get_a(int x[2][2])
362 {
363  x[0][0] = (int)A.west;
364  x[0][1] = (int)A.east;
365  x[1][0] = (int)A.north;
366  x[1][1] = (int)A.south;
367 }
368 
369 void D_get_d(double x[2][2])
370 {
371  x[0][0] = D.west;
372  x[0][1] = D.east;
373  x[1][0] = D.north;
374  x[1][1] = D.south;
375 }
376 
377 /*!
378  * \brief screen to array (y)
379  *
380  * Returns a <i>row</i> value in the array coordinate system when provided the
381  * corresponding <b>y</b> value in the screen coordinate system.
382  *
383  * \param D_row y
384  * \return double
385  */
386 
387 double D_d_to_a_row(double D_row)
388 {
389  return A.north + (D_row - D.north) * D_to_A_conv.y;
390 }
391 
392 /*!
393  * \brief screen to array (x)
394  *
395  * Returns a <i>column</i> value in the array coordinate system when provided
396  * the corresponding <b>x</b> value in the screen coordinate system.
397  *
398  * \param D_col x
399  * \return double
400  */
401 
402 double D_d_to_a_col(double D_col)
403 {
404  return A.west + (D_col - D.west) * D_to_A_conv.x;
405 }
406 
407 /*!
408  * \brief screen to earth (y)
409  *
410  * Returns a <i>north</i> value in the earth coordinate system when provided the
411  * corresponding <b>y</b> value in the screen coordinate system.
412  *
413  * \param D_row y
414  * \return double
415  */
416 
417 double D_d_to_u_row(double D_row)
418 {
419  return U.north + (D_row - D.north) / U_to_D_conv.y;
420 }
421 
422 /*!
423  * \brief screen to earth (x)
424  *
425  * Returns an <i>east</i> value in the earth coordinate system when provided the
426  * corresponding <b>x</b> value in the screen coordinate system.
427  *
428  * \param D_col x
429  * \return double
430  */
431 
432 double D_d_to_u_col(double D_col)
433 {
434  return U.west + (D_col - D.west) / U_to_D_conv.x;
435 }
436 
437 /*!
438  * \brief array to earth (row)
439  *
440  * Returns a <i>y</i> value in the earth coordinate system when provided the
441  * corresponding <b>row</b> value in the array coordinate system.
442  *
443  * \param A_row row
444  * \return double
445  */
446 
447 double D_a_to_u_row(double A_row)
448 {
449  return U.north + (A_row - A.north) * A_to_U_conv.y;
450 }
451 
452 /*!
453  * \brief array to earth (column)
454  *
455  * Returns an <i>x</i> value in the earth coordinate system when
456  * provided the corresponding <b>column</b> value in the array coordinate
457  * system.
458  *
459  * \param A_col column
460  * \return double
461  */
462 
463 double D_a_to_u_col(double A_col)
464 {
465  return U.west + (A_col - A.west) * A_to_U_conv.x;
466 }
467 
468 /*!
469  * \brief array to screen (row)
470  *
471  * Returns a <i>y</i> value in the screen coordinate system when provided the
472  * corresponding <b>row</b> value in the array coordinate system.
473  *
474  * \param A_row row
475  * \return double
476  */
477 
478 double D_a_to_d_row(double A_row)
479 {
480  return D.north + (A_row - A.north) / D_to_A_conv.y;
481 }
482 
483 /*!
484  * \brief array to screen (column)
485  *
486  * Returns an <i>x</i> value in the screen coordinate system when
487  * provided the corresponding <b>column</b> value in the array coordinate
488  * system.
489  *
490  * \param A_col column
491  * \return double
492  */
493 
494 double D_a_to_d_col(double A_col)
495 {
496  return D.west + (A_col - A.west) / D_to_A_conv.x;
497 }
498 
499 /*!
500  * \brief earth to screen (north)
501  *
502  * Returns a <i>y</i> value in the screen coordinate system when provided the
503  * corresponding <b>north</b> value in the earth coordinate system.
504  *
505  * \param U_row north
506  * \return double
507  */
508 
509 double D_u_to_d_row(double U_row)
510 {
511  return D.north + (U_row - U.north) * U_to_D_conv.y;
512 }
513 
514 /*!
515  * \brief earth to screen (east)
516  *
517  * Returns an <i>x</i> value in the screen coordinate system when provided the
518  * corresponding <b>east</b> value in the earth coordinate system.
519  *
520  * \param U_col east
521  * \return double
522  */
523 
524 double D_u_to_d_col(double U_col)
525 {
526  return D.west + (U_col - U.west) * U_to_D_conv.x;
527 }
528 
529 /*!
530  * \brief earth to array (north)
531  *
532  * Returns a <i>row</i> value in the array coordinate system when provided the
533  * corresponding <b>north</b> value in the earth coordinate system.
534  *
535  * \param U_row north
536  * \return double
537  */
538 
539 double D_u_to_a_row(double U_row)
540 {
541  return A.north + (U_row - U.north) / A_to_U_conv.y;
542 }
543 
544 /*!
545  * \brief earth to array (east
546  *
547  * Returns a <i>column</i> value in the array coordinate system when provided
548  * the corresponding <b>east</b> value in the earth coordinate system.
549  *
550  * \param U_col east
551  * \return double
552  */
553 
554 double D_u_to_a_col(double U_col)
555 {
556  return A.west + (U_col - U.west) / A_to_U_conv.x;
557 }
void D_get_src(double *t, double *b, double *l, double *r)
returns frame bounds in source coordinate system
Definition: cnversions.c:297
double D_get_a_south(void)
Definition: cnversions.c:247
double D_get_d_to_u_yconv(void)
Definition: cnversions.c:172
double D_get_d_to_a_xconv(void)
Definition: cnversions.c:160
double D_get_a_north(void)
Definition: cnversions.c:243
double D_get_u_to_d_yconv(void)
Definition: cnversions.c:196
double D_u_to_a_col(double U_col)
earth to array (east
Definition: cnversions.c:554
void D_get_grid(int *t, int *b, int *l, int *r)
Definition: cnversions.c:314
double D_d_to_a_col(double D_col)
screen to array (x)
Definition: cnversions.c:402
double D_a_to_d_col(double A_col)
array to screen (column)
Definition: cnversions.c:494
double D_d_to_u_col(double D_col)
screen to earth (x)
Definition: cnversions.c:432
void D_fit_d_to_u(void)
Definition: cnversions.c:97
double D_u_to_a_row(double U_row)
earth to array (north)
Definition: cnversions.c:539
double D_get_u_south(void)
Definition: cnversions.c:230
double D_get_d_south(void)
Definition: cnversions.c:264
double D_a_to_u_col(double A_col)
array to earth (column)
Definition: cnversions.c:463
double D_get_u_to_a_yconv(void)
Definition: cnversions.c:204
double D_get_ns_resolution(void)
Definition: cnversions.c:209
void D_set_dst(double t, double b, double l, double r)
Definition: cnversions.c:322
double D_get_a_west(void)
Definition: cnversions.c:235
void D_set_grid(int t, int b, int l, int r)
Definition: cnversions.c:305
double D_get_d_west(void)
Definition: cnversions.c:252
double D_get_a_to_d_xconv(void)
Definition: cnversions.c:184
double D_u_to_d_col(double U_col)
earth to screen (east)
Definition: cnversions.c:524
double D_a_to_d_row(double A_row)
array to screen (row)
Definition: cnversions.c:478
double D_get_ew_resolution(void)
Definition: cnversions.c:213
void D_get_u(double x[2][2])
Definition: cnversions.c:353
void D_show_conversions(void)
Definition: cnversions.c:107
int D_is_lat_lon(void)
Definition: cnversions.c:155
double D_get_d_north(void)
Definition: cnversions.c:260
double D_get_u_east(void)
Definition: cnversions.c:222
void D_get_dst(double *t, double *b, double *l, double *r)
returns frame bounds in destination coordinate system
Definition: cnversions.c:345
void D_set_src(double t, double b, double l, double r)
Definition: cnversions.c:276
void D_update_conversions(void)
Definition: cnversions.c:90
double D_get_a_east(void)
Definition: cnversions.c:239
double D_get_a_to_u_yconv(void)
Definition: cnversions.c:180
double D_get_u_to_a_xconv(void)
Definition: cnversions.c:200
double D_d_to_a_row(double D_row)
screen to array (y)
Definition: cnversions.c:387
double D_get_u_north(void)
Definition: cnversions.c:226
double D_get_u_to_d_xconv(void)
Definition: cnversions.c:192
void D_get_d(double x[2][2])
Definition: cnversions.c:369
void D_do_conversions(const struct Cell_head *window, double t, double b, double l, double r)
initialize conversions
Definition: cnversions.c:143
double D_get_d_east(void)
Definition: cnversions.c:256
void D_fit_u_to_d(void)
Definition: cnversions.c:102
double D_get_a_to_u_xconv(void)
Definition: cnversions.c:176
double D_get_a_to_d_yconv(void)
Definition: cnversions.c:188
void D_get_a(int x[2][2])
Definition: cnversions.c:361
void D_set_region(const struct Cell_head *window)
Definition: cnversions.c:269
double D_a_to_u_row(double A_row)
array to earth (row)
Definition: cnversions.c:447
double D_get_u_west(void)
Definition: cnversions.c:218
double D_u_to_d_row(double U_row)
earth to screen (north)
Definition: cnversions.c:509
double D_get_d_to_a_yconv(void)
Definition: cnversions.c:164
double D_d_to_u_row(double D_row)
screen to earth (y)
Definition: cnversions.c:417
double D_get_d_to_u_xconv(void)
Definition: cnversions.c:168
#define D
Definition: gis/intersect.c:72
#define PROJECTION_LL
Projection code - Latitude-Longitude.
Definition: gis.h:130
char * dst
Definition: lz4.h:981
const char * src
Definition: lz4.h:989
double b
Definition: r_raster.c:39
double l
Definition: r_raster.c:39
double t
Definition: r_raster.c:39
double r
Definition: r_raster.c:39
2D/3D raster map header (used also for region)
Definition: gis.h:440
double north
Extent coordinates (north)
Definition: gis.h:486
double east
Extent coordinates (east)
Definition: gis.h:490
int rows
Number of rows for 2D data.
Definition: gis.h:455
int cols
Number of columns for 2D data.
Definition: gis.h:459
int proj
Projection code.
Definition: gis.h:472
double south
Extent coordinates (south)
Definition: gis.h:488
double west
Extent coordinates (west)
Definition: gis.h:492
#define x