1 #include <stdlib.h>
2 #include "grib2.h"
3 #include "gridtemplates.h"
4 
5 /* GDAL: in original g2clib, this is in gridtemplates.h */
6 static const struct gridtemplate templatesgrid[MAXGRIDTEMP] = {
7              // 3.0: Lat/Lon grid
8          { 0, 19, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1} },
9              // 3.1: Rotated Lat/Lon grid
10          { 1, 22, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1,-4,4,4} },
11              // 3.2: Stretched Lat/Lon grid
12          { 2, 22, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1,-4,4,-4} },
13              // 3.3: Stretched & Rotated Lat/Lon grid
14          { 3, 25, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1,-4,4,4,-4,4,-4} },
15 // Added GDT 3.4,3.5    (08/05/2013)
16              // 3.4: Variable resolution Latitude/Longitude
17          { 4, 13, 1, {1,1,4,1,4,1,4,4,4,4,4,1,1} },
18              // 3.5: Variable resolution rotate Latitude/Longitude
19          { 5, 16, 1, {1,1,4,1,4,1,4,4,4,4,4,1,1,-4,4,4} },
20              // 3.12: Transverse Mercator
21          {12, 22, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,-4,4,4,1,4,4,-4,-4,-4,-4} },
22              // 3.101: General unstructured grid
23          {101, 4, 0, {1,4,1,-4} },
24              // 3.140: Lambert Azimuthal Equal Area Projection
25          {140, 17, 0, {1,1,4,1,4,1,4,4,4,-4,4,4,4,1,4,4,1} },
26 //
27              // 3.10: Mercator
28          {10, 19, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,-4,-4,4,1,4,4,4} },
29              // 3.20: Polar Stereographic Projection
30          {20, 18, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,-4,4,4,4,1,1} },
31              // 3.30: Lambert Conformal
32          {30, 22, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,-4,4,4,4,1,1,-4,-4,-4,4} },
33              // 3.31: Albers equal area
34          {31, 22, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,-4,4,4,4,1,1,-4,-4,-4,4} },
35              // 3.40: Gaussian Lat/Lon
36          {40, 19, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1} },
37              // 3.41: Rotated Gaussian Lat/Lon
38          {41, 22, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1,-4,4,4} },
39              // 3.42: Stretched Gaussian Lat/Lon
40          {42, 22, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1,-4,4,-4} },
41              // 3.43: Stretched and Rotated Gaussian Lat/Lon
42          {43, 25, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1,-4,4,4,-4,4,-4} },
43              // 3.50: Spherical Harmonic Coefficients
44          {50, 5, 0, {4,4,4,1,1} },
45              // 3.51: Rotated Spherical Harmonic Coefficients
46          {51, 8, 0, {4,4,4,1,1,-4,4,4} },
47              // 3.52: Stretched Spherical Harmonic Coefficients
48          {52, 8, 0, {4,4,4,1,1,-4,4,-4} },
49              // 3.53: Stretched and Rotated Spherical Harmonic Coefficients
50          {53, 11, 0, {4,4,4,1,1,-4,4,4,-4,4,-4} },
51              // 3.90: Space View Perspective or orthographic
52          {90, 21, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,4,4,4,4,1,4,4,4,4} },
53              // 3.100: Triangular grid based on an icosahedron
54          {100, 11, 0, {1,1,2,1,-4,4,4,1,1,1,4} },
55              // 3.110: Equatorial Azimuthal equidistant
56          {110, 16, 0, {1,1,4,1,4,1,4,4,4,-4,4,1,4,4,1,1} },
57              // 3.120: Azimuth-range projection
58          {120, 7, 1, {4,4,-4,4,4,4,1} },
59              // 3.204: Curvilinear Orthogonal Grid
60          {204, 19, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1} },
61              // 3.32768: Rot Lat/Lon E-grid (Arakawa)
62          {32768, 19, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1} },
63              // 3.32769: Rot Lat/Lon Non-E Staggered grid (Arakawa)
64          {32769, 21, 0, {1,1,4,1,4,1,4,4,4,4,4,-4,4,1,-4,4,4,4,1,4,4} },
65              // 3.1000: Cross Section Grid
66          {1000, 20, 1, {1,1,4,1,4,1,4,4,4,4,-4,4,1,4,4,1,2,1,1,2} },
67              // 3.1100: Hovmoller Diagram Grid
68          {1100, 28, 0, {1,1,4,1,4,1,4,4,4,4,-4,4,1,-4,4,1,4,1,-4,1,1,-4,2,1,1,1,1,1} },
69              // 3.1200: Time Section Grid
70          {1200, 16, 1, {4,1,-4,1,1,-4,2,1,1,1,1,1,2,1,1,2} }
71 
72       } ;
73 
74 const struct gridtemplate *get_templatesgrid()
75 
76 {
77     return templatesgrid;
78 }
79 
80 g2int getgridindex(g2int number)
81 /*!$$$  SUBPROGRAM DOCUMENTATION BLOCK
82 !                .      .    .                                       .
83 ! SUBPROGRAM:    getgridindex
84 !   PRGMMR: Gilbert         ORG: W/NP11    DATE: 2001-06-28
85 !
86 ! ABSTRACT: This function returns the index of specified Grid
87 !   Definition Template 3.NN (NN=number) in array templates.
88 !
89 ! PROGRAM HISTORY LOG:
90 ! 2001-06-28  Gilbert
91 ! 2007-08-16  Vuong     -  Added GDT 3.204  Curvilinear Orthogonal Grid
92 ! 2008-07-08  Vuong     -  Added GDT 3.32768 Rotate Lat/Lon E-grid (Arakawa)
93 ! 2009-01-14  Vuong     -  Changed structure name template to gtemplate
94 ! 2010-05-11  Vuong     -  Added GDT 3.32769 Rotate Lat/Lon Non-E Staggered grid (Arakawa)
95 ! 2013-08-06  Vuong     -  Added GDT 3.4,3.5,3.12,3.101,3.140
96 !
97 ! USAGE:    index=getgridindex(number)
98 !   INPUT ARGUMENT LIST:
99 !     number   - NN, indicating the number of the Grid Definition
100 !                Template 3.NN that is being requested.
101 !
102 ! RETURNS:  Index of GDT 3.NN in array templates, if template exists.
103 !           = -1, otherwise.
104 !
105 ! REMARKS: None
106 !
107 ! ATTRIBUTES:
108 !   LANGUAGE: C
109 !   MACHINE:  IBM SP
110 !
111 !$$$*/
112 {
113            g2int j,l_getgridindex=-1;
114 
115            for (j=0;j<MAXGRIDTEMP;j++) {
116               if (number == templatesgrid[j].template_num) {
117                  l_getgridindex=j;
118                  return(l_getgridindex);
119               }
120            }
121 
122            return(l_getgridindex);
123 }
124 
125 gtemplate *getgridtemplate(g2int number)
126 /*!$$$  SUBPROGRAM DOCUMENTATION BLOCK
127 !                .      .    .                                       .
128 ! SUBPROGRAM:    getgridtemplate
129 !   PRGMMR: Gilbert         ORG: W/NP11    DATE: 2000-05-09
130 !
131 ! ABSTRACT: This subroutine returns grid template information for a
132 !   specified Grid Definition Template 3.NN.
133 !   The number of entries in the template is returned along with a map
134 !   of the number of octets occupied by each entry.  Also, a flag is
135 !   returned to indicate whether the template would need to be extended.
136 !
137 ! PROGRAM HISTORY LOG:
138 ! 2000-05-09  Gilbert
139 ! 2007-08-16  Vuong     -  Added GDT 3.204  Curvilinear Orthogonal Grid
140 ! 2008-07-08  Vuong     -  Added GDT 3.32768 Rotate Lat/Lon E-grid (Arakawa)
141 ! 2010-05-11  Vuong     -  Added GDT 3.32769 Rotate Lat/Lon Non-E Staggered grid (Arakawa)
142 ! 2009-01-14  Vuong     -  Changed structure name template to gtemplate
143 !
144 ! USAGE:    template *getgridtemplate(number)
145 !   INPUT ARGUMENT LIST:
146 !     number   - NN, indicating the number of the Grid Definition
147 !                Template 3.NN that is being requested.
148 !
149 !   RETURN VALUE:
150 !        - Pointer to the returned template struct.
151 !          Returns NULL pointer, if template not found.
152 !
153 ! REMARKS: None
154 !
155 ! ATTRIBUTES:
156 !   LANGUAGE: C
157 !   MACHINE:  IBM SP
158 !
159 !$$$*/
160 {
161            g2int l_index;
162            gtemplate *new;
163 
164            l_index=getgridindex(number);
165 
166            if (l_index != -1) {
167               new=(gtemplate *)malloc(sizeof(gtemplate));
168               new->type=3;
169               new->num=templatesgrid[l_index].template_num;
170               new->maplen=templatesgrid[l_index].mapgridlen;
171               new->needext=templatesgrid[l_index].needext;
172               new->map=(g2int *)templatesgrid[l_index].mapgrid;
173               new->extlen=0;
174               new->ext=0;        //NULL
175               return(new);
176            }
177            else {
178              printf("getgridtemplate: GDT Template 3.%d not defined.\n",(int)number);
179              return(0);        //NULL
180            }
181 
182          return(0);        //NULL
183 }
184 
185 
186 gtemplate *extgridtemplate(g2int number,g2int *list)
187 /*!$$$  SUBPROGRAM DOCUMENTATION BLOCK
188 !                .      .    .                                       .
189 ! SUBPROGRAM:    extgridtemplate
190 !   PRGMMR: Gilbert         ORG: W/NP11    DATE: 2000-05-09
191 !
192 ! ABSTRACT: This subroutine generates the remaining octet map for a
193 !   given Grid Definition Template, if required.  Some Templates can
194 !   vary depending on data values given in an earlier part of the
195 !   Template, and it is necessary to know some of the earlier entry
196 !   values to generate the full octet map of the Template.
197 !
198 ! PROGRAM HISTORY LOG:
199 ! 2000-05-09  Gilbert
200 ! 2008-07-08  Vuong     -  Added GDT 3.32768 Rotate Lat/Lon E-grid (Arakawa)
201 ! 2009-01-14  Vuong     -  Changed structure name template to gtemplate
202 ! 2010-05-11  Vuong     -  Added GDT 3.32769 Rotate Lat/Lon Non-E Staggered grid (Arakawa)
203 ! 2013-08-06  Vuong     -  Added GDT 3.4,3.5,3.12,3.101,3.140
204 !
205 ! USAGE:    CALL extgridtemplate(number,list)
206 !   INPUT ARGUMENT LIST:
207 !     number   - NN, indicating the number of the Grid Definition
208 !                Template 3.NN that is being requested.
209 !     list()   - The list of values for each entry in
210 !                the Grid Definition Template.
211 !
212 !   RETURN VALUE:
213 !        - Pointer to the returned template struct.
214 !          Returns NULL pointer, if template not found.
215 !
216 ! ATTRIBUTES:
217 !   LANGUAGE: C
218 !   MACHINE:  IBM SP
219 !
220 !$$$*/
221 {
222            gtemplate *new;
223            g2int l_index,i;
224 
225            l_index=getgridindex(number);
226            if (l_index == -1) return(0);
227 
228            new=getgridtemplate(number);
229            if( new == NULL ) return(NULL);
230 
231            if ( ! new->needext ) return(new);
232 
233            if ( number == 120 ) {
234               /* Not sure of the threshold, but 100000 looks to be large */
235               /* enough */
236               if( list[1] < 0 || list[1] > 100000 )
237                 return new;
238               new->extlen=list[1]*2;
239               new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen);
240               for (i=0;i<new->extlen;i++) {
241                  if ( i%2 == 0 ) {
242                     new->ext[i]=2;
243                  }
244                  else {
245                     new->ext[i]=-2;
246                  }
247               }
248            }
249 #if 0
250            /* Commented out by GDAL: memory leaks... */
251            else if ( number == 4 ) {
252               new->extlen=list[7];
253               new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen);
254               for (i=0;i<new->extlen;i++) {
255                  new->ext[i]=4;
256               }
257               new->extlen=list[8];
258               new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen);
259               for (i=0;i<new->extlen;i++) {
260                  new->ext[i]=-4;
261               }
262            }
263            else if ( number == 5 ) {
264               new->extlen=list[7];
265               new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen);
266               for (i=0;i<new->extlen;i++) {
267                  new->ext[i]=4;
268               }
269               new->extlen=list[8];
270               new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen);
271               for (i=0;i<new->extlen;i++) {
272                  new->ext[i]=-4;
273               }
274            }
275 #endif
276            else if ( number == 1000 ) {
277                /* Not sure of the threshold, but 100000 looks to be large */
278               /* enough */
279               if( list[19] < 0 || list[19] > 100000 )
280                 return new;
281               new->extlen=list[19];
282               new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen);
283               for (i=0;i<new->extlen;i++) {
284                  new->ext[i]=4;
285               }
286            }
287            else if ( number == 1200 ) {
288               /* Not sure of the threshold, but 100000 looks to be large */
289               /* enough */
290               if( list[15] < 0 || list[15] > 100000 )
291                 return new;
292               new->extlen=list[15];
293               new->ext=(g2int *)malloc(sizeof(g2int)*new->extlen);
294               for (i=0;i<new->extlen;i++) {
295                  new->ext[i]=4;
296               }
297            }
298 
299            return(new);
300 
301 }
302