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