Line data Source code
1 : /*****************************************************************************
2 : * scan.c
3 : *
4 : * DESCRIPTION
5 : * This file contains the code that is used to assist with handling the
6 : * possible scan values of the grid.
7 : *
8 : * HISTORY
9 : * 10/2002 Arthur Taylor (MDL / RSIS): Created.
10 : *
11 : * NOTES
12 : *****************************************************************************
13 : */
14 : #include "scan.h"
15 :
16 : /*****************************************************************************
17 : * ScanIndex2XY() --
18 : *
19 : * Arthur Taylor / MDL
20 : *
21 : * PURPOSE
22 : * To convert from the index of the GRIB2 message which is defined by the
23 : * scan parameter, to one that seemed reasonable. The choice for internal
24 : * array orientation boiled down to either (scan = 0000) (start from upper
25 : * left and across similar to a CRT screen) or (scan = 0100) (start at lower
26 : * left and go up ).
27 : * It was decided that (scan 0100) was what people expected. The only catch
28 : * is that Spatial Analyst requires (scan = 0000), so when writing to that
29 : * format we have to switch.
30 : * For more info on scan flags: see Grib2 "Flag" Table 3.4
31 : *
32 : * ARGUMENTS
33 : * row = The index in the scanned in data. (Input)
34 : * X, Y = The x,y position in a scan == 0100 world. (Output)
35 : * scan = The orientation of the GRIB2 grid. (Input)
36 : * Nx, Ny = The Dimensions of the grid (Input).
37 : *
38 : * FILES/DATABASES: None
39 : *
40 : * RETURNS: void
41 : * Returns x, y, in bounds of [1..Nx], [1..Ny]
42 : * Assuming row is in [0..Nx*Ny)
43 : *
44 : * HISTORY
45 : * 10/2002 Arthur Taylor (MDL/RSIS): Created.
46 : * 7/2003 AAT: Switched to x, y [1..Nx] because that is what the map
47 : * routines give.
48 : *
49 : * NOTES
50 : * scan based on Grib2 "Flag" Table 3.4
51 : * scan & GRIB2BIT_1 => decrease x
52 : * scan & GRIB2BIT_2 => increase y
53 : * scan & GRIB2BIT_3 => adjacent points in y direction consecutive.
54 : * scan & GRIB2BIT_4 => adjacent rows scan in opposite directions.
55 : *****************************************************************************
56 : */
57 5431920 : void ScanIndex2XY (sInt4 row, sInt4 *X, sInt4 *Y, uChar scan, sInt4 Nx,
58 : sInt4 Ny)
59 : {
60 : sInt4 x; /* local copy of x */
61 : sInt4 y; /* local copy of y */
62 :
63 5431920 : if (scan & GRIB2BIT_3) {
64 0 : x = row / Ny;
65 0 : if ((scan & GRIB2BIT_4) && ((x % 2) == 1)) {
66 0 : y = (Ny - 1) - (row % Ny);
67 : } else {
68 0 : y = row % Ny;
69 : }
70 : } else {
71 5431920 : y = row / Nx;
72 5431920 : if ((scan & GRIB2BIT_4) && ((y % 2) == 1)) {
73 124608 : x = (Nx - 1) - (row % Nx);
74 : } else {
75 5307310 : x = row % Nx;
76 : }
77 : }
78 5431920 : if (scan & GRIB2BIT_1) {
79 0 : x = (Nx - 1 - x);
80 : }
81 5431920 : if (!(scan & GRIB2BIT_2)) {
82 5179960 : y = (Ny - 1 - y);
83 : }
84 : /* Changed following two lines (with the + 1) on 7/22/2003 */
85 5431920 : *X = x + 1;
86 5431920 : *Y = y + 1;
87 5431920 : }
88 :
89 : /*****************************************************************************
90 : * XY2ScanIndex() --
91 : *
92 : * Arthur Taylor / MDL
93 : *
94 : * PURPOSE
95 : * To convert from an x,y coordinate system that matches scan = 0100 to the
96 : * scan index of the GRIB2 message as defined by the scan parameter.
97 : * This tends to be less important than ScanIndex2XY, but is provided for
98 : * testing purposes, and in case it is useful.
99 : *
100 : * ARGUMENTS
101 : * Row = The index in the scanned in data. (Output)
102 : * x, y = The x,y position in a (scan = 0100) world. (Input)
103 : * scan = The orientation of the GRIB2 grid. (Input)
104 : * Nx, Ny = The Dimensions of the grid (Input).
105 : *
106 : * FILES/DATABASES: None
107 : *
108 : * RETURNS: void
109 : * Returns row in [0..Nx*Ny)
110 : * Assuming x, y, is in bounds of [1..Nx], [1..Ny]
111 : *
112 : * HISTORY
113 : * 10/2002 Arthur Taylor (MDL/RSIS): Created.
114 : * 7/2003 AAT: Switched to x, y [1..Nx] because that is what the map
115 : * routines give.
116 : *
117 : * NOTES
118 : * scan based on Grib2 "Flag" Table 3.4
119 : * scan & GRIB2BIT_1 => decrease x
120 : * scan & GRIB2BIT_2 => increase y
121 : * scan & GRIB2BIT_3 => adjacent points in y direction consecutive.
122 : * scan & GRIB2BIT_4 => adjacent rows scan in opposite directions.
123 : *****************************************************************************
124 : */
125 : #ifdef unused_by_GDAL
126 : void XY2ScanIndex (sInt4 *Row, sInt4 x, sInt4 y, uChar scan, sInt4 Nx,
127 : sInt4 Ny)
128 : {
129 : sInt4 row; /* local copy of row */
130 :
131 : /* Added following two lines on 7/22/2003 */
132 : x = x - 1;
133 : y = y - 1;
134 : if (scan & GRIB2BIT_1) {
135 : x = (Nx - 1 - x);
136 : }
137 : if (!(scan & GRIB2BIT_2)) {
138 : y = (Ny - 1 - y);
139 : }
140 : if (scan & GRIB2BIT_3) {
141 : if ((scan & GRIB2BIT_4) && ((x % 2) == 1)) {
142 : row = Ny - 1 - y + x * Ny;
143 : } else {
144 : row = y + x * Ny;
145 : }
146 : } else {
147 : if ((scan & GRIB2BIT_4) && ((y % 2) == 1)) {
148 : row = Nx - 1 - x + y * Nx;
149 : } else {
150 : row = x + y * Nx;
151 : }
152 : }
153 : *Row = row;
154 : }
155 : #endif // unused_by_GDAL
156 :
157 : /*****************************************************************************
158 : * main() --
159 : *
160 : * Arthur Taylor / MDL
161 : *
162 : * PURPOSE
163 : * To test the ScanIndex2XY, and XY2ScanIndex routines, to make sure that
164 : * they are inverses of each other, for all possible scan values. Also to
165 : * see what a sample array looks like in the various scans, and to make sure
166 : * that we are generating (scan = 0100) data.
167 : *
168 : * ARGUMENTS
169 : * argc = The number of arguments on the command line. (Input)
170 : * argv = The arguments on the command line. (Input)
171 : *
172 : * FILES/DATABASES: None
173 : *
174 : * RETURNS: void
175 : *
176 : * HISTORY
177 : * 10/2002 Arthur Taylor (MDL/RSIS): Created.
178 : *
179 : * NOTES
180 : *****************************************************************************
181 : */
182 : #ifdef TEST_SCAN
183 : #include <stdio.h>
184 : int main (int argc, char **argv)
185 : {
186 : int data[3][4];
187 : int ray1[6];
188 : int ray2[6];
189 : sInt4 Nx = 2, Ny = 3;
190 : sInt4 NxNy = 6;
191 : sInt4 row, x, y;
192 : sInt4 x1, y1;
193 : int i;
194 : int scan;
195 :
196 : /* Set up sample data. */
197 : for (x = 1; x <= Nx; x++) {
198 : for (y = 1; y <= Ny; y++) {
199 : data[x][y] = 1 + x + (y * 2);
200 : }
201 : }
202 : for (i = 0; i < 16; i++) {
203 : scan = i << 4;
204 : /* Print scan info. */
205 : printf ("Checking xy2row -> row2xy for scan %d ", i);
206 : if (scan & GRIB2BIT_1)
207 : printf ("-1");
208 : else
209 : printf ("-0");
210 : if (scan & GRIB2BIT_2)
211 : printf ("-1");
212 : else
213 : printf ("-0");
214 : if (scan & GRIB2BIT_3)
215 : printf ("-1");
216 : else
217 : printf ("-0");
218 : if (scan & GRIB2BIT_4)
219 : printf ("-1");
220 : else
221 : printf ("-0");
222 : printf ("\n");
223 :
224 : /* Test invertiblity of functions. */
225 : for (x = 1; x <= Nx; x++) {
226 : for (y = 1; y <= Ny; y++) {
227 : XY2ScanIndex (&row, x, y, scan, Nx, Ny);
228 : ScanIndex2XY (row, &x1, &y1, scan, Nx, Ny);
229 : if ((x1 != x) || (y1 != y)) {
230 : printf (" %ld %ld .. %ld .. %ld %ld \n", x, y, row, x1, y1);
231 : }
232 : }
233 : }
234 :
235 : /* Set up sample scan data. */
236 : for (x = 1; x <= Nx; x++) {
237 : for (y = 1; y <= Ny; y++) {
238 : XY2ScanIndex (&row, x, y, scan, Nx, Ny);
239 : ray1[row] = data[x][y];
240 : }
241 : }
242 :
243 : /* Convert from ray1[] to ray2[] where ray2[] is scan value 0100. */
244 : for (x = 0; x < NxNy; x++) {
245 : printf ("%d ", ray1[x]);
246 : ScanIndex2XY (x, &x1, &y1, scan, Nx, Ny);
247 : /*
248 : * To get scan 0000 do the following:
249 : * row = x1 + ((Ny-1) - y1) * Nx;
250 : */
251 : row = (x1 - 1) + (y1 - 1) * Nx;
252 : ray2[row] = ray1[x];
253 : }
254 : printf ("\n");
255 : for (x = 0; x < NxNy; x++) {
256 : printf ("%d ", ray2[x]);
257 : }
258 : printf ("\n");
259 : }
260 : return 0;
261 : }
262 : #endif
|