Ejemplo n.º 1
0
int cyclic(unsigned char **sec) {
    int grid_template, nx, ny, res, scan, flag_3_3, no_dx, basic_ang, sub_ang;
    unsigned int npnts;
    unsigned char *gds;
    double dlon, units, lon1, lon2;

    get_nxny(sec, &nx, &ny, &npnts, &res, &scan);
    if (GDS_Scan_staggered(scan)) return 0;
    if (nx <= 1 || ny <= 0) return 0;

    grid_template = code_table_3_1(sec);
    gds = sec[3];

    flag_3_3 = flag_table_3_3(sec);
    no_dx =  0;
    if (flag_3_3 != -1) {
        if ((flag_3_3 & 0x20) == 0) no_dx = 1;
    }
    if (no_dx) return 0;

    if (grid_template == 0) {

        basic_ang = GDS_LatLon_basic_ang(gds);
        sub_ang = GDS_LatLon_sub_ang(gds);
        units = basic_ang == 0 ?  0.000001 : (double) basic_ang / (double) sub_ang;

	/* dlon has to be defined */
        dlon = units * GDS_LatLon_dlon(gds);
	return (fabs(nx*dlon-360.0) < ERROR);
    }
    if (grid_template == 10) {
	if (output_order != wesn) return 0;		// only works with we:sn order
	lon1 = GDS_Mercator_lon1(gds);
	lon2 = GDS_Mercator_lon2(gds);
	if (lon2 < lon1) lon2 += 360.0;
	dlon = (lon2-lon1)*nx/(nx-1.0);
        return (fabs(dlon-360.0) < ERROR);
    }

    if (grid_template == 40) {

        basic_ang = GDS_Gaussian_basic_ang(gds);
        sub_ang = GDS_Gaussian_sub_ang(gds);
        units = basic_ang == 0 ?  0.000001 : (double) basic_ang / (double) sub_ang;

	/* dlon has to be defined */
        dlon = units * GDS_Gaussian_dlon(gds);
        return (fabs(nx*dlon-360.0) < ERROR);
    }


    return 0;
}
Ejemplo n.º 2
0
Archivo: geo.c Proyecto: mmase/wgrib2
int mercator2ll(unsigned char **sec, double **lat, double **lon) {

    double dx, dy, lat1, lat2, lon1, lon2;
    double *llat, *llon;
    int i, j;
    unsigned int k;
    double dlon, circum;

    double n,s,e,w,tmp,error;
    unsigned char *gds;

    int nnx, nny, nres, nscan;
    unsigned int nnpnts;

    get_nxny(sec, &nnx, &nny, &nnpnts, &nres, &nscan);
    gds = sec[3];

    dy     = GDS_Mercator_dy(gds);
    dx     = GDS_Mercator_dx(gds);
    lat1 = GDS_Mercator_lat1(gds);
    lat2 = GDS_Mercator_lat2(gds);
    lon1 = GDS_Mercator_lon1(gds);
    lon2 = GDS_Mercator_lon2(gds);

    if (lon1 < 0.0 || lon2 < 0.0 || lon1 > 360.0 || lon2 > 360.0) fatal_error("BAD GDS lon","");
    if (lat1 < -90.0 || lat2 < -90.0 || lat1 > 90.0 || lat2 > 90.0) fatal_error("BAD GDS lat","");

    if (GDS_Mercator_ori_angle(gds) != 0.0) {
        fprintf(stderr,"cannot handle non-zero mercator orientation angle %f\n",
                GDS_Mercator_ori_angle(gds));
        return 0;
    }

    if (nnx == -1 || nny == -1) {
        fprintf(stderr,"Sorry geo/mercator code does not handle variable nx/ny yet\n");
        return 0;
    }

    if ((*lat = (double *) malloc(nnpnts * sizeof(double))) == NULL) {
        fatal_error("mercator2ll memory allocation failed","");
    }
    if ((*lon = (double *) malloc(nnpnts * sizeof(double))) == NULL) {
        fatal_error("mercator2ll memory allocation failed","");
    }

    /* now figure out the grid coordinates mucho silly grib specification */

    /* find S and N latitude */
    if (GDS_Scan_y(nscan)) {
        s = lat1;
        n = lat2;
    }
    else {
        s = lat2;
        n = lat1;
    }
    if (s > n) fatal_error("Mercator grid: lat1 and lat2","");

    /* find W and E longitude */

    if ( ((nscan & 16) == 16) && (nny % 2 == 0) && ((nres & 32) == 0) ) {
         fatal_error("grib GDS ambiguity","");
    }

    if ( ((nscan & 16) == 16) && (nny % 2 == 0) ) {
         fatal_error("more code needed to decode GDS","");
    }

    if (GDS_Scan_x(nscan)) {
        w = lon1;
        e = lon2;
    } else {
        w = lon2;
        e = lon1;
    }
    if (e <= w) e += 360.0;


    llat = *lat;
    llon = *lon;

    dlon = (e-w) / (nnx-1);
    circum = 2.0 * M_PI * radius_earth(sec) * cos(GDS_Mercator_latD(gds) * (M_PI/180.0));
    dx = dx * 360.0 / circum;

    // dlon should be almost == to dx
    // replace dx by dlon to get end points to match

    if (dx != 0.0) {
	error = fabs(dx-dlon) / fabs(dx);
	if (error >= 0.001) { fprintf(stderr,
           "\n*** Mercator grid error: inconsistent d-longitude, radius and grid domain\n"
		"*** d-longitude from grid domain %lf (used), d-longitude from dx %lf (not used)\n",
		dlon, dx);
	}
        dx = dlon;
    }

    s = log(tan((45+s/2)*M_PI/180));
    n = log(tan((45+n/2)*M_PI/180));
    dy = (n - s) / (nny - 1);

    for (j = 0; j < nny; j++) {
        tmp = (atan(exp(s+j*dy))*180/M_PI-45)*2;
        for (i = 0; i < nnx; i++) {
            *llat++ = tmp;
        }
    }

    for (j = 0; j < nnx; j++) {
        llon[j] = w + j*dx >= 360.0 ?  w + j*dx - 360.0 : w + j*dx;
    }
    for (k = nnx; k < nnpnts; k++) {
        llon[k] = llon[k-nnx];
    }
    return 0;
} /* end mercator2ll() */