Exemplo 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;
}
Exemplo n.º 2
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;

    get_nxny(sec, &nx, &ny, &npnts, &res, &scan);
    if ((unsigned) (nx * ny) != npnts) return 0;
    if (nx <= 0 || 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 (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 = units * GDS_LatLon_dlon(gds);
        if (no_dx) dlon = 0.0;

	dlon = nx * dlon;
	return (fabs(dlon-360.0) < ERROR);
    }

    if (grid_template == 10) {
        dlon = GDS_Mercator_dx(gds);
        if (no_dx) dlon = 0.0;
	dlon = nx * dlon;
	return (fabs(dlon-360.0) < ERROR);
    }

// need to add gaussian grid - a bit more complicated

    return 0;
}
Exemplo n.º 3
0
Arquivo: geo.c Projeto: mmase/wgrib2
int regular2ll(unsigned char **sec, double **lat, double **lon) {
 
    int basic_ang, sub_ang;
    double units, dlat, dlon, lat1, lat2, lon1, lon2;
    double e, w, n, s, dx, dy;
 
    int i, j;
    double *llat, *llon;
    unsigned char *gds;
    int nnx, nny, nres, nscan;
    unsigned int nnpnts;

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

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

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

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

    basic_ang = GDS_LatLon_basic_ang(gds);
    sub_ang = GDS_LatLon_sub_ang(gds);
    if (basic_ang != 0) {
        units = (double) basic_ang / (double) sub_ang;
    }
    else {
        units = 0.000001;
    }

    dlat = GDS_LatLon_dlat(gds) * units;
    dlon = GDS_LatLon_dlon(gds) * units;
    lat1 = GDS_LatLon_lat1(gds) * units;
    lat2 = GDS_LatLon_lat2(gds) * units;
    lon1 = GDS_LatLon_lon1(gds) * units;
    lon2 = GDS_LatLon_lon2(gds) * units;

    if (lon1 < 0.0 || lon2 < 0.0) fatal_error("BAD grid definition lon < zero","");
    if (lon1 > 360.0 || lon2 > 360.0) fatal_error("BAD grid definition lon >= 360","");
    if (lat1 < -90.0 || lat2 < -90.0 || lat1 > 90.0 || lat2 > 90.0) fatal_error("BAD grid definition lat","");


    /* find S latitude and dy */
    if (GDS_Scan_y(nscan)) {
        s = lat1;
        n = lat2;
    }
    else {
        s = lat2;
        n = lat1;
    }
    if (s > n) fatal_error("lat-lon grid: lat1 and lat2 inconsistent with scan order","");

    if (nny != 1) {
        dy = (n - s) / (nny - 1);
        if (nres & 16) { /* lat increment is valid */
            if (fabs(dy - dlat) > 0.001) fatal_error("lat-lon grid: dlat is inconsistent","");
        }
    }
    else { 
        dy = 0.0;
    }
// fprintf(stderr,">>> geo:  dy %lf dlat %lf nres %d has dy %d has dx %d\n", dy, dlat, nres, nres & 16, nres & 32);

    /* find W latitude and dx */

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

    if (GDS_Scan_x(nscan)) {
        w = lon1;
        e = lon2;
        if (GDS_Scan_row_rev(nscan) && ((nres & 32) == 0)) {
            e = lon1 + (nnx-1) * dlon;
        }
    } else {
        w = lon2;
        e = lon1;
        if (GDS_Scan_row_rev(nscan) && ((nres & 32) == 0)) {
            w = lon1 - (nnx-1) * dlon;
        }
    }

    if (e <= w) e += 360.0;
    if (e-w > 360.0) e -= 360.0;
    if (w < 0) {
        w += 360.0;
        e += 360.0;
    }

    /* lat-lon should be in a WE:SN order */

    if (nnx > 0 && nny > 0) {			/* non-thinned, potentially staggered grid */
	/* put x[] and y[] values in lon[] and lat[] */
        llat = *lat;
        llon = *lon;
	if (stagger(sec, nnpnts,llon,llat)) fatal_error("geo: stagger problem","");

        if (nnx != 1) {
	    dx = (e-w) / (nnx - 1);
	    dx = fabs(dx);
            if (nres & 32) { /* lon increment is valid */
                if (fabs(dx - fabs(dlon)) > 0.001) fatal_error("lat-lon grid: dlon is inconsistent","");
	    }
        }
        else {
	    dx = 0.0;
	}
	dy = fabs(dy);

#pragma omp parallel for private(j)
	for (j = 0; j < nnpnts; j++) {
            llon[j] = lon1 + llon[j]*dx;
	    llon[j] = llon[j] >= 360.0 ? llon[j] - 360.0 : llon[j];
	    llon[j] = llon[j] < 0.0 ? llon[j] + 360.0 : llon[j];
	    llat[j] = lat1 + llat[j]*dy;
	}
	return 0;
    }

    /* must be thinned grid */

    llat = *lat;
        /* quasi-regular grid */
        for (j = 0; j < nny; j++) {
            for (i = 0; i < variable_dim[j];  i++) {
                *llat++ = s + j*dy;
            }
        }

    llon = *lon;
        /* quasi-regular grid */
        for (j = 0; j < nny; j++) {
            dx = (e-w) / (variable_dim[j]-1);
            for (i = 0; i < variable_dim[j]; i++) {
                *llon++ = w + i*dx >= 360.0 ? w + i*dx - 360.0: w + i*dx;
            }
        }
    return 0;
} /* end regular2ll() */