/* Written by Bill Brown, USA-CERL Thu Jul 27, 1995 */ #include #include #include typedef int FILEDESC; int main( int argc, char *argv[]) { struct GModule *module; struct Option *rastin, *rastout; struct Option *eastoff, *northoff; char *inmap; FILEDESC infile = (FILEDESC)NULL, outfile = (FILEDESC)NULL; DCELL *inbuf1, *inbuf2; DCELL *outbuf; int row, col; struct Cell_head w, mapw; float o_east, o_north; G_gisinit (argv[0]); module = G_define_module(); module->keywords = _("raster"); module->description = _("Bilinear interpolation utility for raster map layers."); rastin = G_define_standard_option(G_OPT_R_INPUT); rastout = G_define_standard_option(G_OPT_R_OUTPUT); northoff = G_define_option(); northoff->key = "north"; northoff->type = TYPE_DOUBLE; northoff->description = _("specific input value to be assigned to the north and/or south poles for longitude-latitude grids"); northoff->required = NO; eastoff = G_define_option(); eastoff->key = "east"; eastoff->type = TYPE_DOUBLE; eastoff->description = _("specific input value to be assigned to the north and/or south poles for longitude-latitude grids"); eastoff->required = NO; if (G_parser (argc, argv)) exit (EXIT_FAILURE); o_east = o_north = 0.0; if(northoff->answer) sscanf(northoff->answer, "%f", &o_north); if(eastoff->answer) sscanf(eastoff->answer, "%f", &o_east); G_get_set_window (&w); inmap = G_find_file2 ("cell", rastin->answer, ""); if(!inmap){ G_fatal_error(_("Couldn't find raster file %s"), rastin->answer); } /* set window to old map */ G_get_cellhd(rastin->answer, inmap, &mapw); G_set_window(&mapw); /* G_malloc 2 buffers for input rows */ inbuf1 = G_allocate_d_raster_buf(); inbuf2 = G_allocate_d_raster_buf(); /* open old map */ if ((infile = G_open_cell_old(rastin->answer, inmap)) == -1) { G_fatal_error(_("Not able to open cellfile for [%s]"), rastin->answer); } /* reset window to current region */ G_set_window(&w); outbuf = G_allocate_d_raster_buf(); /* open new map */ if ((outfile = G_open_raster_new(rastout->answer, DCELL_TYPE)) < 0) { G_fatal_error(_("Not able to open cellfile for [%s]"), rastout->answer); } G_suppress_warnings(1); /* otherwise get complaints about window changes */ { double east, north, mapeast, mapnorth, t, u, new; DCELL *tmp, c1, c2, c3, c4; int maprow1, mapcol1, maprow2, mapcol2; int bufrow1, bufrow2; double maprow_f, mapcol_f; bufrow1 = bufrow2 = -1; for (row = 0; row < w.rows; row++) { G_percent(row, w.rows - 1, 2); north = G_row_to_northing((double)(row +.5), &w); north += o_north; /* in region? */ if(north > mapw.north || north <= mapw.south){ G_set_d_null_value(outbuf, w.cols); G_put_d_raster_row(outfile, outbuf); continue; } /* on edges? */ if (north >= (mapw.north - mapw.ns_res/2.)){ maprow1 = 0; maprow2 = 1; u = 0.0; } else if (north <= (mapw.south + mapw.ns_res/2.)){ maprow2 = mapw.rows - 1; maprow1 = maprow2 - 1; u = 1.0; } else{ maprow_f = G_northing_to_row(north,&mapw); if((int)(maprow_f + .5) == (int)maprow_f){ maprow2 = (int)maprow_f; maprow1 = maprow2 - 1; } else{ maprow1 = (int)maprow_f; maprow2 = maprow1 + 1; } mapnorth=G_row_to_northing((double)(maprow1 +.5), &mapw); u = (mapnorth - north)/mapw.ns_res; } /* fprintf(stderr,"row %d maprow1 %d maprow2 %d\n", row, maprow1, maprow2); */ if(bufrow1 < 0){ /* read both */ G_set_window(&mapw); G_get_d_raster_row(infile, inbuf1, maprow1); bufrow1 = maprow1; G_get_d_raster_row(infile, inbuf2, maprow2); bufrow2 = maprow2; G_set_window(&w); } else if(maprow1 != bufrow1 || maprow2 != bufrow2){ /* still might be able to reuse row2 */ if(maprow1 == bufrow2){ tmp = inbuf1; inbuf1 = inbuf2; inbuf2 = tmp; bufrow1 = maprow1; G_set_window(&mapw); G_get_d_raster_row(infile, inbuf2, maprow2); bufrow2 = maprow2; G_set_window(&w); } else{ /* need to read both */ G_set_window(&mapw); G_get_d_raster_row(infile, inbuf1, maprow1); bufrow1 = maprow1; G_get_d_raster_row(infile, inbuf2, maprow2); bufrow2 = maprow2; G_set_window(&w); } } for(col=0; col < w.cols; col++){ east = G_col_to_easting((double)(col +.5), &w); east += o_east; /* in region? */ if(east < mapw.west || east >= mapw.east){ G_set_d_null_value(&outbuf[col], 1); continue; } /* on edges? */ if (east <= (mapw.west + mapw.ew_res/2.)){ mapcol1 = 0; mapcol2 = 1; t = 0.0; } else if (east >= (mapw.east - mapw.ew_res/2.)){ mapcol2 = mapw.cols - 1; mapcol1 = mapcol2 - 1; t = 1.0; } else{ mapcol_f = G_easting_to_col(east,&mapw); if((int)(mapcol_f + .5) == (int)mapcol_f){ mapcol2 = (int)mapcol_f; mapcol1 = mapcol2 - 1; } else{ mapcol1 = (int)mapcol_f; mapcol2 = mapcol1 + 1; } mapeast=G_col_to_easting((double)(mapcol1 +.5), &mapw); t = (east - mapeast)/mapw.ew_res; } c1 = inbuf1[mapcol1]; c2 = inbuf1[mapcol2]; c3 = inbuf2[mapcol1]; c4 = inbuf2[mapcol2]; if (G_is_d_null_value(&c1) || G_is_d_null_value(&c2) || G_is_d_null_value(&c3) || G_is_d_null_value(&c4)) { G_set_d_null_value(&outbuf[col], 1); } else { new = (1.0 - t) * (1.0 - u) * c1 + t * (1.0 - u) * c2 + t * u * c4 + u * (1.0 - t) * c3; outbuf[col] = new; } } G_put_d_raster_row(outfile, outbuf); } } G_free(inbuf1); G_free(inbuf2); G_free(outbuf); G_close_cell(infile); G_close_cell(outfile); return(EXIT_SUCCESS); }