GRASS GIS 8 Programmer's Manual  8.4.0dev(2024)-6c790bf5c0
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", U.west,
114  U.east, U.south, U.north);
115 
116  fprintf(stderr,
117  " D_x %10.1f D_y %10.1f\n"
118  "\n",
119  D.size.x, D.size.y);
120  fprintf(stderr,
121  " A_x %10.1f A_y %10.1f\n"
122  "\n",
123  A.size.x, A.size.y);
124  fprintf(stderr,
125  " U_x %10.1f U_y %10.1f\n"
126  "\n",
127  U.size.x, U.size.y);
128 
129  fprintf(stderr, " D_to_A_conv.x %10.1f D_to_A_conv.y %10.1f \n",
130  D_to_A_conv.x, D_to_A_conv.y);
131  fprintf(stderr, " A_to_U_conv.x %10.1f A_to_U_conv.y %10.1f \n",
132  A_to_U_conv.x, A_to_U_conv.y);
133  fprintf(stderr, " U_to_D_conv.x %10.1f U_to_D_conv.y %10.1f \n",
134  U_to_D_conv.x, U_to_D_conv.y);
135 }
136 
137 /*!
138  * \brief initialize conversions
139  *
140  * The relationship between the earth <b>region</b> and the <b>top, bottom,
141  * left</b>, and <b>right</b> screen coordinates is established, which then
142  * allows conversions between all three coordinate systems to be performed.
143  * Note this routine is called by <i>D_setup</i>.
144  *
145  * \param window region
146  * \param t top
147  * \param b bottom
148  * \param l left
149  * \param r right
150  * \return none
151  */
152 void D_do_conversions(const struct Cell_head *window, double t, double b,
153  double l, double r)
154 {
155  D_set_region(window);
156  D_set_dst(t, b, l, r);
157  D_fit_d_to_u();
159 #ifdef DEBUG
161 #endif /* DEBUG */
162 }
163 
164 int D_is_lat_lon(void)
165 {
166  return (is_lat_lon);
167 }
168 
169 double D_get_d_to_a_xconv(void)
170 {
171  return (D_to_A_conv.x);
172 }
173 double D_get_d_to_a_yconv(void)
174 {
175  return (D_to_A_conv.y);
176 }
177 double D_get_d_to_u_xconv(void)
178 {
179  return (1 / U_to_D_conv.x);
180 }
181 double D_get_d_to_u_yconv(void)
182 {
183  return (1 / U_to_D_conv.y);
184 }
185 double D_get_a_to_u_xconv(void)
186 {
187  return (A_to_U_conv.x);
188 }
189 double D_get_a_to_u_yconv(void)
190 {
191  return (A_to_U_conv.y);
192 }
193 double D_get_a_to_d_xconv(void)
194 {
195  return (1 / D_to_A_conv.x);
196 }
197 double D_get_a_to_d_yconv(void)
198 {
199  return (1 / D_to_A_conv.y);
200 }
201 double D_get_u_to_d_xconv(void)
202 {
203  return (U_to_D_conv.x);
204 }
205 double D_get_u_to_d_yconv(void)
206 {
207  return (U_to_D_conv.y);
208 }
209 double D_get_u_to_a_xconv(void)
210 {
211  return (1 / A_to_U_conv.x);
212 }
213 double D_get_u_to_a_yconv(void)
214 {
215  return (1 / A_to_U_conv.y);
216 }
217 
219 {
220  return D_get_a_to_u_yconv();
221 }
223 {
224  return D_get_a_to_u_xconv();
225 }
226 
227 double D_get_u_west(void)
228 {
229  return (U.west);
230 }
231 double D_get_u_east(void)
232 {
233  return (U.east);
234 }
235 double D_get_u_north(void)
236 {
237  return (U.north);
238 }
239 double D_get_u_south(void)
240 {
241  return (U.south);
242 }
243 
244 double D_get_a_west(void)
245 {
246  return (A.west);
247 }
248 double D_get_a_east(void)
249 {
250  return (A.east);
251 }
252 double D_get_a_north(void)
253 {
254  return (A.north);
255 }
256 double D_get_a_south(void)
257 {
258  return (A.south);
259 }
260 
261 double D_get_d_west(void)
262 {
263  return (D.west);
264 }
265 double D_get_d_east(void)
266 {
267  return (D.east);
268 }
269 double D_get_d_north(void)
270 {
271  return (D.north);
272 }
273 double D_get_d_south(void)
274 {
275  return (D.south);
276 }
277 
278 void D_set_region(const struct Cell_head *window)
279 {
280  D_set_src(window->north, window->south, window->west, window->east);
281  D_set_grid(0, window->rows, 0, window->cols);
282  is_lat_lon = (window->proj == PROJECTION_LL);
283 }
284 
285 void D_set_src(double t, double b, double l, double r)
286 {
287  U.north = t;
288  U.south = b;
289  U.west = l;
290  U.east = r;
291  calc_size(&U);
292 }
293 
294 /*!
295  * \brief returns frame bounds in source coordinate system
296  *
297  * D_get_src() returns the frame bounds in the source coordinate system
298  * (used by D_* functions)
299  *
300  * \param t top
301  * \param b bottom
302  * \param l left
303  * \param r right
304  * \return void
305  */
306 void D_get_src(double *t, double *b, double *l, double *r)
307 {
308  *t = U.north;
309  *b = U.south;
310  *l = U.west;
311  *r = U.east;
312 }
313 
314 void D_set_grid(int t, int b, int l, int r)
315 {
316  A.north = t;
317  A.south = b;
318  A.west = l;
319  A.east = r;
320  calc_size(&A);
321 }
322 
323 void D_get_grid(int *t, int *b, int *l, int *r)
324 {
325  *t = A.north;
326  *b = A.south;
327  *l = A.west;
328  *r = A.east;
329 }
330 
331 void D_set_dst(double t, double b, double l, double r)
332 {
333  D.north = t;
334  D.south = b;
335  D.west = l;
336  D.east = r;
337  calc_size(&D);
338 }
339 
340 /*!
341  * \brief returns frame bounds in destination coordinate system
342  *
343  * D_get_dst() returns the frame bounds in the destination coordinate system
344  * (used by R_* commands).
345  * The various D_setup() commands all set the destination coordinate
346  * system to the current frame reported by R_get_window().
347  *
348  * \param t top
349  * \param b bottom
350  * \param l left
351  * \param r right
352  * \return none
353  */
354 void D_get_dst(double *t, double *b, double *l, double *r)
355 {
356  *t = D.north;
357  *b = D.south;
358  *l = D.west;
359  *r = D.east;
360 }
361 
362 void D_get_u(double x[2][2])
363 {
364  x[0][0] = U.west;
365  x[0][1] = U.east;
366  x[1][0] = U.north;
367  x[1][1] = U.south;
368 }
369 
370 void D_get_a(int x[2][2])
371 {
372  x[0][0] = (int)A.west;
373  x[0][1] = (int)A.east;
374  x[1][0] = (int)A.north;
375  x[1][1] = (int)A.south;
376 }
377 
378 void D_get_d(double x[2][2])
379 {
380  x[0][0] = D.west;
381  x[0][1] = D.east;
382  x[1][0] = D.north;
383  x[1][1] = D.south;
384 }
385 
386 /*!
387  * \brief screen to array (y)
388  *
389  * Returns a <i>row</i> value in the array coordinate system when provided the
390  * corresponding <b>y</b> value in the screen coordinate system.
391  *
392  * \param D_row y
393  * \return double
394  */
395 
396 double D_d_to_a_row(double D_row)
397 {
398  return A.north + (D_row - D.north) * D_to_A_conv.y;
399 }
400 
401 /*!
402  * \brief screen to array (x)
403  *
404  * Returns a <i>column</i> value in the array coordinate system when provided
405  * the corresponding <b>x</b> value in the screen coordinate system.
406  *
407  * \param D_col x
408  * \return double
409  */
410 
411 double D_d_to_a_col(double D_col)
412 {
413  return A.west + (D_col - D.west) * D_to_A_conv.x;
414 }
415 
416 /*!
417  * \brief screen to earth (y)
418  *
419  * Returns a <i>north</i> value in the earth coordinate system when provided the
420  * corresponding <b>y</b> value in the screen coordinate system.
421  *
422  * \param D_row y
423  * \return double
424  */
425 
426 double D_d_to_u_row(double D_row)
427 {
428  return U.north + (D_row - D.north) / U_to_D_conv.y;
429 }
430 
431 /*!
432  * \brief screen to earth (x)
433  *
434  * Returns an <i>east</i> value in the earth coordinate system when provided the
435  * corresponding <b>x</b> value in the screen coordinate system.
436  *
437  * \param D_col x
438  * \return double
439  */
440 
441 double D_d_to_u_col(double D_col)
442 {
443  return U.west + (D_col - D.west) / U_to_D_conv.x;
444 }
445 
446 /*!
447  * \brief array to earth (row)
448  *
449  * Returns a <i>y</i> value in the earth coordinate system when provided the
450  * corresponding <b>row</b> value in the array coordinate system.
451  *
452  * \param A_row row
453  * \return double
454  */
455 
456 double D_a_to_u_row(double A_row)
457 {
458  return U.north + (A_row - A.north) * A_to_U_conv.y;
459 }
460 
461 /*!
462  * \brief array to earth (column)
463  *
464  * Returns an <i>x</i> value in the earth coordinate system when
465  * provided the corresponding <b>column</b> value in the array coordinate
466  * system.
467  *
468  * \param A_col column
469  * \return double
470  */
471 
472 double D_a_to_u_col(double A_col)
473 {
474  return U.west + (A_col - A.west) * A_to_U_conv.x;
475 }
476 
477 /*!
478  * \brief array to screen (row)
479  *
480  * Returns a <i>y</i> value in the screen coordinate system when provided the
481  * corresponding <b>row</b> value in the array coordinate system.
482  *
483  * \param A_row row
484  * \return double
485  */
486 
487 double D_a_to_d_row(double A_row)
488 {
489  return D.north + (A_row - A.north) / D_to_A_conv.y;
490 }
491 
492 /*!
493  * \brief array to screen (column)
494  *
495  * Returns an <i>x</i> value in the screen coordinate system when
496  * provided the corresponding <b>column</b> value in the array coordinate
497  * system.
498  *
499  * \param A_col column
500  * \return double
501  */
502 
503 double D_a_to_d_col(double A_col)
504 {
505  return D.west + (A_col - A.west) / D_to_A_conv.x;
506 }
507 
508 /*!
509  * \brief earth to screen (north)
510  *
511  * Returns a <i>y</i> value in the screen coordinate system when provided the
512  * corresponding <b>north</b> value in the earth coordinate system.
513  *
514  * \param U_row north
515  * \return double
516  */
517 
518 double D_u_to_d_row(double U_row)
519 {
520  return D.north + (U_row - U.north) * U_to_D_conv.y;
521 }
522 
523 /*!
524  * \brief earth to screen (east)
525  *
526  * Returns an <i>x</i> value in the screen coordinate system when provided the
527  * corresponding <b>east</b> value in the earth coordinate system.
528  *
529  * \param U_col east
530  * \return double
531  */
532 
533 double D_u_to_d_col(double U_col)
534 {
535  return D.west + (U_col - U.west) * U_to_D_conv.x;
536 }
537 
538 /*!
539  * \brief earth to array (north)
540  *
541  * Returns a <i>row</i> value in the array coordinate system when provided the
542  * corresponding <b>north</b> value in the earth coordinate system.
543  *
544  * \param U_row north
545  * \return double
546  */
547 
548 double D_u_to_a_row(double U_row)
549 {
550  return A.north + (U_row - U.north) / A_to_U_conv.y;
551 }
552 
553 /*!
554  * \brief earth to array (east
555  *
556  * Returns a <i>column</i> value in the array coordinate system when provided
557  * the corresponding <b>east</b> value in the earth coordinate system.
558  *
559  * \param U_col east
560  * \return double
561  */
562 
563 double D_u_to_a_col(double U_col)
564 {
565  return A.west + (U_col - U.west) / A_to_U_conv.x;
566 }
void D_get_src(double *t, double *b, double *l, double *r)
returns frame bounds in source coordinate system
Definition: cnversions.c:306
double D_get_a_south(void)
Definition: cnversions.c:256
double D_get_d_to_u_yconv(void)
Definition: cnversions.c:181
double D_get_d_to_a_xconv(void)
Definition: cnversions.c:169
double D_get_a_north(void)
Definition: cnversions.c:252
double D_get_u_to_d_yconv(void)
Definition: cnversions.c:205
double D_u_to_a_col(double U_col)
earth to array (east
Definition: cnversions.c:563
void D_get_grid(int *t, int *b, int *l, int *r)
Definition: cnversions.c:323
double D_d_to_a_col(double D_col)
screen to array (x)
Definition: cnversions.c:411
double D_a_to_d_col(double A_col)
array to screen (column)
Definition: cnversions.c:503
double D_d_to_u_col(double D_col)
screen to earth (x)
Definition: cnversions.c:441
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:548
double D_get_u_south(void)
Definition: cnversions.c:239
double D_get_d_south(void)
Definition: cnversions.c:273
double D_a_to_u_col(double A_col)
array to earth (column)
Definition: cnversions.c:472
double D_get_u_to_a_yconv(void)
Definition: cnversions.c:213
double D_get_ns_resolution(void)
Definition: cnversions.c:218
void D_set_dst(double t, double b, double l, double r)
Definition: cnversions.c:331
double D_get_a_west(void)
Definition: cnversions.c:244
void D_set_grid(int t, int b, int l, int r)
Definition: cnversions.c:314
double D_get_d_west(void)
Definition: cnversions.c:261
double D_get_a_to_d_xconv(void)
Definition: cnversions.c:193
double D_u_to_d_col(double U_col)
earth to screen (east)
Definition: cnversions.c:533
double D_a_to_d_row(double A_row)
array to screen (row)
Definition: cnversions.c:487
double D_get_ew_resolution(void)
Definition: cnversions.c:222
void D_get_u(double x[2][2])
Definition: cnversions.c:362
void D_show_conversions(void)
Definition: cnversions.c:107
int D_is_lat_lon(void)
Definition: cnversions.c:164
double D_get_d_north(void)
Definition: cnversions.c:269
double D_get_u_east(void)
Definition: cnversions.c:231
void D_get_dst(double *t, double *b, double *l, double *r)
returns frame bounds in destination coordinate system
Definition: cnversions.c:354
void D_set_src(double t, double b, double l, double r)
Definition: cnversions.c:285
void D_update_conversions(void)
Definition: cnversions.c:90
double D_get_a_east(void)
Definition: cnversions.c:248
double D_get_a_to_u_yconv(void)
Definition: cnversions.c:189
double D_get_u_to_a_xconv(void)
Definition: cnversions.c:209
double D_d_to_a_row(double D_row)
screen to array (y)
Definition: cnversions.c:396
double D_get_u_north(void)
Definition: cnversions.c:235
double D_get_u_to_d_xconv(void)
Definition: cnversions.c:201
void D_get_d(double x[2][2])
Definition: cnversions.c:378
void D_do_conversions(const struct Cell_head *window, double t, double b, double l, double r)
initialize conversions
Definition: cnversions.c:152
double D_get_d_east(void)
Definition: cnversions.c:265
void D_fit_u_to_d(void)
Definition: cnversions.c:102
double D_get_a_to_u_xconv(void)
Definition: cnversions.c:185
double D_get_a_to_d_yconv(void)
Definition: cnversions.c:197
void D_get_a(int x[2][2])
Definition: cnversions.c:370
void D_set_region(const struct Cell_head *window)
Definition: cnversions.c:278
double D_a_to_u_row(double A_row)
array to earth (row)
Definition: cnversions.c:456
double D_get_u_west(void)
Definition: cnversions.c:227
double D_u_to_d_row(double U_row)
earth to screen (north)
Definition: cnversions.c:518
double D_get_d_to_a_yconv(void)
Definition: cnversions.c:173
double D_d_to_u_row(double D_row)
screen to earth (y)
Definition: cnversions.c:426
double D_get_d_to_u_xconv(void)
Definition: cnversions.c:177
#define D
Definition: gis/intersect.c:72
#define PROJECTION_LL
Projection code - Latitude-Longitude.
Definition: gis.h:130
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:437
double north
Extent coordinates (north)
Definition: gis.h:483
double east
Extent coordinates (east)
Definition: gis.h:487
int rows
Number of rows for 2D data.
Definition: gis.h:452
int cols
Number of columns for 2D data.
Definition: gis.h:456
int proj
Projection code.
Definition: gis.h:469
double south
Extent coordinates (south)
Definition: gis.h:485
double west
Extent coordinates (west)
Definition: gis.h:489
#define x