mirror of https://github.com/ecmwf/eccodes.git
Merge pull request #195 from ecmwf/bugfix/ECC-1364-LambertSouthern
Bugfix/ECC-1364 lambert southern
This commit is contained in:
commit
08d09ead58
|
@ -162,7 +162,32 @@ static double calculate_eccentricity(double minor, double major)
|
|||
return sqrt(1.0 - temp * temp);
|
||||
}
|
||||
|
||||
static int init_sphere(grib_handle* h,
|
||||
static void xy2latlon(double radius, double n, double f, double rho0_bare, double LoVInRadians,
|
||||
double x, double y,
|
||||
double* latDeg, double* lonDeg)
|
||||
{
|
||||
x /= radius;
|
||||
y /= radius;
|
||||
y = rho0_bare - y;
|
||||
double rho = hypot(x, y);
|
||||
if (rho != 0.0) {
|
||||
if (n < 0.0) {
|
||||
rho = -rho;
|
||||
x = -x;
|
||||
y = -y;
|
||||
}
|
||||
double lp_phi = 2. * atan(pow(f / rho, 1.0/n)) - M_PI_2;
|
||||
double lp_lam = atan2(x, y) / n;
|
||||
*lonDeg = lp_lam*RAD2DEG + LoVInRadians*RAD2DEG;
|
||||
*latDeg = lp_phi*RAD2DEG;
|
||||
}
|
||||
else {
|
||||
*lonDeg = 0.0;
|
||||
*latDeg = (n > 0.0 ? M_PI_2 : -M_PI_2) * RAD2DEG;
|
||||
}
|
||||
}
|
||||
|
||||
static int init_sphere(const grib_handle* h,
|
||||
grib_iterator_lambert_conformal* self,
|
||||
size_t nv, long nx, long ny,
|
||||
double LoVInDegrees,
|
||||
|
@ -171,9 +196,7 @@ static int init_sphere(grib_handle* h,
|
|||
double LoVInRadians, double Latin1InRadians, double Latin2InRadians,
|
||||
double LaDInRadians)
|
||||
{
|
||||
int i, j;
|
||||
double f, n, rho, rho0, angle, x0, y0, x, y, tmp, tmp2;
|
||||
double latDeg, lonDeg, lonDiff;
|
||||
double n, angle, x0, y0, x, y;
|
||||
|
||||
if (fabs(Latin1InRadians - Latin2InRadians) < 1E-09) {
|
||||
n = sin(Latin1InRadians);
|
||||
|
@ -182,12 +205,14 @@ static int init_sphere(grib_handle* h,
|
|||
log(tan(M_PI_4 + Latin2InRadians / 2.0) / tan(M_PI_4 + Latin1InRadians / 2.0));
|
||||
}
|
||||
|
||||
f = (cos(Latin1InRadians) * pow(tan(M_PI_4 + Latin1InRadians / 2.0), n)) / n;
|
||||
rho = radius * f * pow(tan(M_PI_4 + latFirstInRadians / 2.0), -n);
|
||||
rho0 = radius * f * pow(tan(M_PI_4 + LaDInRadians / 2.0), -n);
|
||||
if (n < 0) /* adjustment for southern hemisphere */
|
||||
rho0 = -rho0;
|
||||
lonDiff = lonFirstInRadians - LoVInRadians;
|
||||
double f = (cos(Latin1InRadians) * pow(tan(M_PI_4 + Latin1InRadians / 2.0), n)) / n;
|
||||
double rho = radius * f * pow(tan(M_PI_4 + latFirstInRadians / 2.0), -n);
|
||||
double rho0_bare = f * pow(tan(M_PI_4 + LaDInRadians / 2.0), -n);
|
||||
double rho0 = radius * rho0_bare;
|
||||
|
||||
//if (n < 0) /* adjustment for southern hemisphere */
|
||||
// rho0 = -rho0;
|
||||
double lonDiff = lonFirstInRadians - LoVInRadians;
|
||||
|
||||
/* Adjust longitude to range -180 to 180 */
|
||||
if (lonDiff > M_PI)
|
||||
|
@ -213,20 +238,33 @@ static int init_sphere(grib_handle* h,
|
|||
return GRIB_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
double latDeg = 0, lonDeg = 0;
|
||||
for (long j = 0; j < ny; j++) {
|
||||
y = y0 + j * Dy;
|
||||
for (long i = 0; i < nx; i++) {
|
||||
const long index = i + j * nx;
|
||||
x = x0 + i * Dx;
|
||||
xy2latlon(radius, n, f, rho0_bare, LoVInRadians, x, y, &latDeg, &lonDeg);
|
||||
self->lons[index] = lonDeg;
|
||||
self->lats[index] = latDeg;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
/* Populate our arrays */
|
||||
for (j = 0; j < ny; j++) {
|
||||
y = y0 + j * Dy;
|
||||
if (n < 0) { /* adjustment for southern hemisphere */
|
||||
y = -y;
|
||||
}
|
||||
//if (n < 0) { /* adjustment for southern hemisphere */
|
||||
// y = -y;
|
||||
//}
|
||||
tmp = rho0 - y;
|
||||
tmp2 = tmp * tmp;
|
||||
for (i = 0; i < nx; i++) {
|
||||
int index = i + j * nx;
|
||||
x = x0 + i * Dx;
|
||||
if (n < 0) { /* adjustment for southern hemisphere */
|
||||
x = -x;
|
||||
}
|
||||
//printf("j=%d i=%d xy= %.6f %.6f\t",j,i,x,y);
|
||||
//if (n < 0) { /* adjustment for southern hemisphere */
|
||||
// x = -x;
|
||||
//}
|
||||
angle = atan2(x, tmp); /* See ECC-524 */
|
||||
rho = sqrt(x * x + tmp2);
|
||||
if (n <= 0) rho = -rho;
|
||||
|
@ -237,12 +275,12 @@ static int init_sphere(grib_handle* h,
|
|||
self->lats[index] = latDeg;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
/* Oblate spheroid */
|
||||
static int init_oblate(grib_handle* h,
|
||||
static int init_oblate(const grib_handle* h,
|
||||
grib_iterator_lambert_conformal* self,
|
||||
size_t nv, long nx, long ny,
|
||||
double LoVInDegrees,
|
||||
|
|
|
@ -254,6 +254,7 @@ if( HAVE_BUILD_TOOLS )
|
|||
grib_ecc-1000
|
||||
grib_ecc-1001
|
||||
grib_ecc-1030
|
||||
grib_ecc-1364
|
||||
grib_ecc-1397
|
||||
grib_ecc-1425
|
||||
grib_ecc-1467
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
#!/bin/sh
|
||||
# (C) Copyright 2005- ECMWF.
|
||||
#
|
||||
# This software is licensed under the terms of the Apache Licence Version 2.0
|
||||
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
|
||||
#
|
||||
# In applying this licence, ECMWF does not waive the privileges and immunities granted to it by
|
||||
# virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
|
||||
#
|
||||
|
||||
. ./include.ctest.sh
|
||||
|
||||
|
||||
# ECC-1364: GRIB: Geoiterator for Lambert Conformal in the southern hemisphere
|
||||
|
||||
label="grib_ecc-1364_test"
|
||||
tempGrib=temp.$label.grib
|
||||
tempFilt=temp.$label.filt
|
||||
tempLog=temp.$label.log
|
||||
tempRef=temp.$label.ref
|
||||
|
||||
sample_grib1=$ECCODES_SAMPLES_PATH/GRIB1.tmpl
|
||||
|
||||
# Create a GRIB with a similar grid to the one in the JIRA issue
|
||||
cat >$tempFilt<<EOF
|
||||
set dataRepresentationType = 3; # lambert conformal conic
|
||||
set resolutionAndComponentFlags = 136;
|
||||
set Nx = 999;
|
||||
set Ny = 1249;
|
||||
set latitudeOfFirstGridPoint = -54387;
|
||||
set longitudeOfFirstGridPoint = 265669;
|
||||
set LoV = 295000;
|
||||
set DxInMetres = 4000;
|
||||
set DyInMetres = 4000;
|
||||
set projectionCentreFlag = 128;
|
||||
set Latin1 = -35000;
|
||||
set Latin2 = -35000;
|
||||
set latitudeOfSouthernPole = -90000;
|
||||
set scanningMode = 64; # +i +j
|
||||
write;
|
||||
EOF
|
||||
${tools_dir}/grib_filter -o $tempGrib $tempFilt $sample_grib1
|
||||
|
||||
${tools_dir}/grib_get_data $tempGrib > $tempLog
|
||||
|
||||
${tools_dir}/grib_ls -l -11.6277,-47.9583,1 $tempGrib > $tempLog
|
||||
grep -q "Grid Point chosen #1 index=1247750 " $tempLog
|
||||
grep -q "index=1247750 .* distance=0.01 " $tempLog
|
||||
|
||||
|
||||
# Clean up
|
||||
rm -f $tempGrib $tempFilt $tempLog $tempRef
|
Loading…
Reference in New Issue