Esempio n. 1
0
/*!
   \brief Load raster map as floating point map

   Calling function must have already allocated space in buff for
   wind->rows * wind->cols floats.

   This routine simply loads the map into a 2d array by repetitve calls
   to get_f_raster_row.

   \param wind current window
   \param map_name raster map name
   \param[out] buff data buffer
   \param[out] nullmap null map buffer
   \param[out] has_null indicates if raster map contains null-data

   \return 1 on success
   \return 0 on failure
 */
int Gs_loadmap_as_float(struct Cell_head *wind, const char *map_name,
			float *buff, struct BM *nullmap, int *has_null)
{
    FILEDESC cellfile;
    const char *map_set;
    char *nullflags;
    int offset, row, col;

    G_debug(3, "Gs_loadmap_as_float(): name=%s", map_name);

    map_set = G_find_cell2(map_name, "");
    if (!map_set) {
	G_warning(_("Raster map <%s> not found"), map_name);
	return 0;
    }
    *has_null = 0;

    nullflags = G_allocate_null_buf();	/* G_fatal_error */
    if (!nullflags) {
	G_fatal_error(_("Unable to allocate memory for a null buffer"));
    }

    if ((cellfile = G_open_cell_old(map_name, map_set)) == -1) {
	G_fatal_error(_("Unable to open raster map <%s>"), map_name);
    }

    G_message(_("Loading raster map <%s>..."),
	      G_fully_qualified_name(map_name, map_set));

    for (row = 0; row < wind->rows; row++) {
	offset = row * wind->cols;
	G_get_f_raster_row(cellfile, &(buff[offset]), row);
	G_get_null_value_row(cellfile, nullflags, row);

	G_percent(row, wind->rows, 2);

	for (col = 0; col < wind->cols; col++) {
	    if (nullflags[col] || G_is_f_null_value(buff + offset + col)) {
		*has_null = 1;
		BM_set(nullmap, col, row, 1);
	    }
	    /* set nm */
	}
    }
    G_percent(1, 1, 1);

    G_debug(4, "  has_null=%d", *has_null);

    G_close_cell(cellfile);

    G_free(nullflags);

    return (1);
}
Esempio n. 2
0
CPLErr GRASSRasterBand::IReadBlock( int /*nBlockXOff*/, int nBlockYOff,
                                    void *pImage )

{
    if ( ! this->valid ) return CE_Failure;

    // Reset window because IRasterIO could be previously called.
    if ( ResetReading ( &(((GRASSDataset *)poDS)->sCellInfo) ) != CE_None ) {
       return CE_Failure;
    }

    if ( eDataType == GDT_Byte || eDataType == GDT_UInt16 ) {
        CELL *cbuf = G_allocate_c_raster_buf();
        G_get_c_raster_row ( hCell, cbuf, nBlockYOff );

        /* Reset NULLs */
        for ( int col = 0; col < nBlockXSize; col++ ) {
            if ( G_is_c_null_value(&(cbuf[col])) )
                cbuf[col] = (CELL) dfNoData;
        }

        GDALCopyWords ( (void *) cbuf, GDT_Int32, sizeof(CELL),
                        pImage, eDataType, GDALGetDataTypeSize(eDataType)/8,
                        nBlockXSize );

        G_free ( cbuf );
    }
    else if ( eDataType == GDT_Int32 )
    {
        G_get_c_raster_row ( hCell, (CELL *) pImage, nBlockYOff );
    }
    else if ( eDataType == GDT_Float32 )
    {
        G_get_f_raster_row ( hCell, (FCELL *) pImage, nBlockYOff );
    }
    else if ( eDataType == GDT_Float64 )
    {
        G_get_d_raster_row ( hCell, (DCELL *) pImage, nBlockYOff );
    }

    return CE_None;
}
Esempio n. 3
0
CPLErr GRASSRasterBand::IRasterIO ( GDALRWFlag eRWFlag,
	                           int nXOff, int nYOff, int nXSize, int nYSize,
				   void * pData, int nBufXSize, int nBufYSize,
				   GDALDataType eBufType,
				   int nPixelSpace, int nLineSpace )
{
    /* GRASS library does that, we have only calculate and reset the region in map units
     * and if the region has changed, reopen the raster */
    
    /* Calculate the region */
    struct Cell_head sWindow;
    struct Cell_head *psDsWindow;
    
    if ( ! this->valid ) return CE_Failure;

    psDsWindow = &(((GRASSDataset *)poDS)->sCellInfo);
    
    sWindow.north = psDsWindow->north - nYOff * psDsWindow->ns_res; 
    sWindow.south = sWindow.north - nYSize * psDsWindow->ns_res; 
    sWindow.west = psDsWindow->west + nXOff * psDsWindow->ew_res; 
    sWindow.east = sWindow.west + nXSize * psDsWindow->ew_res; 
    sWindow.proj = psDsWindow->proj;
    sWindow.zone = psDsWindow->zone;

    sWindow.cols = nBufXSize;
    sWindow.rows = nBufYSize;
     
    /* Reset resolution */
    G_adjust_Cell_head ( &sWindow, 1, 1);

    if ( ResetReading ( &sWindow ) != CE_None )
    {
        return CE_Failure;
    }
    
    /* Read Data */
    CELL  *cbuf = NULL;
    FCELL *fbuf = NULL;
    DCELL *dbuf = NULL;
    bool  direct = false;

    /* Reset space if default (0) */
    if ( nPixelSpace == 0 )
	nPixelSpace = GDALGetDataTypeSize ( eBufType ) / 8;

    if ( nLineSpace == 0 )
	nLineSpace = nBufXSize * nPixelSpace;

    if ( nGRSType == CELL_TYPE && ( !nativeNulls || eBufType != GDT_Int32 || sizeof(CELL) != 4 ||
		                    nPixelSpace != sizeof(CELL) )  ) 
    {
	cbuf = G_allocate_c_raster_buf();
    } else if( nGRSType == FCELL_TYPE && ( eBufType != GDT_Float32 || nPixelSpace != sizeof(FCELL) ) ) {
	fbuf = G_allocate_f_raster_buf();
    } else if( nGRSType == DCELL_TYPE && ( eBufType != GDT_Float64 || nPixelSpace != sizeof(DCELL) ) ) {
	dbuf = G_allocate_d_raster_buf();
    } else {
	direct = true;
    }

    for ( int row = 0; row < nBufYSize; row++ ) {
        char *pnt = (char *)pData + row * nLineSpace;
	
	if ( nGRSType == CELL_TYPE ) {
	    if ( direct ) {
		G_get_c_raster_row ( hCell, (CELL *) pnt, row );
	    } else {
		G_get_c_raster_row ( hCell, cbuf, row );
		
		/* Reset NULLs */
		for ( int col = 0; col < nBufXSize; col++ ) {
		    if ( G_is_c_null_value(&(cbuf[col])) ) 
			cbuf[col] = (CELL) dfNoData;
		}

		GDALCopyWords ( (void *) cbuf, GDT_Int32, sizeof(CELL), 
			        (void *)  pnt,  eBufType, nPixelSpace,
				nBufXSize ); 
	    }
	} else if( nGRSType == FCELL_TYPE ) {
	    if ( direct ) {
		G_get_f_raster_row ( hCell, (FCELL *) pnt, row );
	    } else {
		G_get_f_raster_row ( hCell, fbuf, row );
		
		GDALCopyWords ( (void *) fbuf, GDT_Float32, sizeof(FCELL), 
			        (void *)  pnt,  eBufType, nPixelSpace,
				nBufXSize ); 
	    }
	} else if( nGRSType == DCELL_TYPE ) {
	    if ( direct ) {
		G_get_d_raster_row ( hCell, (DCELL *) pnt, row );
	    } else {
		G_get_d_raster_row ( hCell, dbuf, row );
		
		GDALCopyWords ( (void *) dbuf, GDT_Float64, sizeof(DCELL), 
			        (void *)  pnt,  eBufType, nPixelSpace,
				nBufXSize ); 
	    }
	}
    }

    if ( cbuf ) G_free ( cbuf );
    if ( fbuf ) G_free ( fbuf );
    if ( dbuf ) G_free ( dbuf );
    
    return CE_None;
}
Esempio n. 4
0
int main(int argc, char *argv[])
{
    char *terrainmap, *seedmap, *lakemap, *mapset;
    int rows, cols, in_terran_fd, out_fd, lake_fd, row, col, pases, pass;
    int lastcount, curcount, start_col = 0, start_row = 0;
    double east, north, area = 0, volume = 0;
    FCELL **in_terran, **out_water, water_level, max_depth = 0, min_depth = 0;
    FCELL water_window[3][3];
    struct Option *tmap_opt, *smap_opt, *wlvl_opt, *lake_opt, *sdxy_opt;
    struct Flag *negative_flag, *overwrite_flag;
    struct GModule *module;
    struct Colors colr;
    struct Cell_head window;
    struct History history;

    G_gisinit(argv[0]);
    
    module = G_define_module();
    module->keywords = _("raster, hydrology");
    module->description = _("Fills lake at given point to given level.");

    tmap_opt = G_define_option();
    tmap_opt->key = "dem";
    tmap_opt->key_desc = "name";
    tmap_opt->description = _("Name of terrain raster map (DEM)");
    tmap_opt->type = TYPE_STRING;
    tmap_opt->gisprompt = "old,cell,raster";
    tmap_opt->required = YES;

    wlvl_opt = G_define_option();
    wlvl_opt->key = "wl";
    wlvl_opt->description = _("Water level");
    wlvl_opt->type = TYPE_DOUBLE;
    wlvl_opt->required = YES;

    lake_opt = G_define_option();
    lake_opt->key = "lake";
    lake_opt->key_desc = "name";
    lake_opt->description = _("Name for output raster map with lake");
    lake_opt->type = TYPE_STRING;
    lake_opt->gisprompt = "new,cell,raster";
    lake_opt->required = NO;

    sdxy_opt = G_define_option();
    sdxy_opt->key = "xy";
    sdxy_opt->description = _("Seed point coordinates");
    sdxy_opt->type = TYPE_DOUBLE;
    sdxy_opt->key_desc = "east,north";
    sdxy_opt->required = NO;
    sdxy_opt->multiple = NO;

    smap_opt = G_define_option();
    smap_opt->key = "seed";
    smap_opt->key_desc = "name";
    smap_opt->description =
	_("Name of raster map with given starting point(s) (at least 1 cell > 0)");
    smap_opt->type = TYPE_STRING;
    smap_opt->gisprompt = "old,cell,raster";
    smap_opt->required = NO;

    negative_flag = G_define_flag();
    negative_flag->key = 'n';
    negative_flag->description =
	_("Use negative depth values for lake raster map");

    overwrite_flag = G_define_flag();
    overwrite_flag->key = 'o';
    overwrite_flag->description =
	_("Overwrite seed map with result (lake) map");

    if (G_parser(argc, argv))	/* Returns 0 if successful, non-zero otherwise */
	exit(EXIT_FAILURE);

    if (smap_opt->answer && sdxy_opt->answer)
	G_fatal_error(_("Both seed map and coordinates cannot be specified"));

    if (!smap_opt->answer && !sdxy_opt->answer)
	G_fatal_error(_("Seed map or seed coordinates must be set!"));

    if (sdxy_opt->answer && !lake_opt->answer)
	G_fatal_error(_("Seed coordinates and output map lake= must be set!"));

    if (lake_opt->answer && overwrite_flag->answer)
	G_fatal_error(_("Both lake and overwrite cannot be specified"));

    if (!lake_opt->answer && !overwrite_flag->answer)
	G_fatal_error(_("Output lake map or overwrite flag must be set!"));

    terrainmap = tmap_opt->answer;
    seedmap = smap_opt->answer;
    sscanf(wlvl_opt->answer, "%f", &water_level);
    lakemap = lake_opt->answer;

    /* If lakemap is set, write to it, else is set overwrite flag and we should write to seedmap. */
    if (lakemap) {
	lake_fd = G_open_raster_new(lakemap, 1);
	if (lake_fd < 0)
	    G_fatal_error(_("Unable to create raster map <%s>"), lakemap);
    }

    rows = G_window_rows();
    cols = G_window_cols();

    /* If we use x,y as seed... */
    if (sdxy_opt->answer) {
	G_get_window(&window);
	east = window.east;
	north = window.north;

	G_scan_easting(sdxy_opt->answers[0], &east, G_projection());
	G_scan_northing(sdxy_opt->answers[1], &north, G_projection());
	start_col = (int)G_easting_to_col(east, &window);
	start_row = (int)G_northing_to_row(north, &window);

	if (start_row < 0 || start_row > rows ||
	    start_col < 0 || start_col > cols)
	    G_fatal_error(_("Seed point outside the current region"));
    }

    /* Open terran map */
    mapset = G_find_cell2(terrainmap, "");
    if (mapset == NULL)
	G_fatal_error(_("Raster map <%s> not found"), terrainmap);

    in_terran_fd = G_open_cell_old(terrainmap, mapset);
    if (in_terran_fd < 0)
	G_fatal_error(_("Unable to open raster map <%s>"),
		      G_fully_qualified_name(terrainmap, mapset));

    /* Open seed map */
    if (smap_opt->answer) {
	mapset = G_find_cell2(seedmap, "");
	if (mapset == NULL)
	    G_fatal_error(_("Raster map <%s> not found"), seedmap);

	out_fd = G_open_cell_old(seedmap, mapset);
	if (out_fd < 0)
	    G_fatal_error(_("Unable to open raster map <%s>"),
			  G_fully_qualified_name(seedmap, mapset));
    }

    /* Pointers to rows. Row = ptr to 'col' size array. */
    in_terran = (FCELL **) G_malloc(rows * sizeof(FCELL *));
    out_water = (FCELL **) G_malloc(rows * sizeof(FCELL *));
    if (in_terran == NULL || out_water == NULL)
	G_fatal_error(_("G_malloc: out of memory"));


    G_debug(1, "Loading maps...");
    /* foo_rows[row] == array with data (2d array). */
    for (row = 0; row < rows; row++) {
	in_terran[row] = (FCELL *) G_malloc(cols * sizeof(FCELL));
	out_water[row] = (FCELL *) G_calloc(cols, sizeof(FCELL));

	/* In newly created space load data from file. */
	if (G_get_f_raster_row(in_terran_fd, in_terran[row], row) != 1)
	    G_fatal_error(_("Unable to read raster map <%s> row %d"),
			  terrainmap, row);

	if (smap_opt->answer)
	    if (G_get_f_raster_row(out_fd, out_water[row], row) != 1)
		G_fatal_error(_("Unable to read raster map <%s> row %d"),
			      seedmap, row);

	G_percent(row + 1, rows, 5);
    }

    /* Set seed point */
    if (sdxy_opt->answer)
	/* Check is water level higher than seed point */
	if (in_terran[start_row][start_col] >= water_level)
	    G_fatal_error(_("Given water level at seed point is below earth surface. "
			   "Increase water level or move seed point."));
    out_water[start_row][start_col] = 1;

    /* Close seed map for reading. */
    if (smap_opt->answer)
	G_close_cell(out_fd);

    /* Open output map for writing. */
    if (lakemap) {
	out_fd = lake_fd;
    }
    else {
	out_fd = G_open_raster_new(seedmap, 1);
	if (out_fd < 0)
	    G_fatal_error(_("Unable to create raster map <%s>"), seedmap);
    }

    /* More pases are renudant. Real pases count is controled by altered cell count. */
    pases = (int)(rows * cols) / 2;

    G_debug(1,
	    "Starting lake filling at level of %8.4f in %d passes. Percent done:",
	    water_level, pases);

    lastcount = 0;

    for (pass = 0; pass < pases; pass++) {
	G_debug(3, "Pass: %d", pass);
	curcount = 0;
	/* Move from left upper corner to right lower corner. */
	for (row = 0; row < rows; row++) {
	    for (col = 0; col < cols; col++) {
		/* Loading water data into window. */
		load_window_values(out_water, water_window, rows, cols, row,
				   col);

		/* Cheking presence of water. */
		if (is_near_water(water_window) == 1) {
		    if (in_terran[row][col] < water_level) {
			out_water[row][col] =
			    water_level - in_terran[row][col];
			curcount++;
		    }
		    else {
			out_water[row][col] = 0;	/* Cell is higher than water level -> NULL. */
		    }
		}
	    }
	}
	if (curcount == lastcount)
	    break;		/* We done. */
	lastcount = curcount;
	curcount = 0;
	/* Move backwards - from lower right corner to upper left corner. */
	for (row = rows - 1; row >= 0; row--) {
	    for (col = cols - 1; col >= 0; col--) {
		load_window_values(out_water, water_window, rows, cols, row,
				   col);

		if (is_near_water(water_window) == 1) {
		    if (in_terran[row][col] < water_level) {
			out_water[row][col] =
			    water_level - in_terran[row][col];
			curcount++;
		    }
		    else {
			out_water[row][col] = 0;
		    }
		}
	    }
	}
	G_percent(pass + 1, pases, 10);
	if (curcount == lastcount)
	    break;		/* We done. */
	lastcount = curcount;
    }				/*pases */

    G_percent(pases, pases, 10);	/* Show 100%. */

    save_map(out_water, out_fd, rows, cols, negative_flag->answer, &min_depth,
	     &max_depth, &area, &volume);

    G_message(_("Lake depth from %f to %f"), min_depth, max_depth);
    G_message(_("Lake area %f square meters"), area);
    G_message(_("Lake volume %f cubic meters"), volume);
    G_warning(_("Volume is correct only if lake depth (terrain raster map) is in meters"));

    /* Close all files. Lake map gets written only now. */
    G_close_cell(in_terran_fd);
    G_close_cell(out_fd);

    /* Add blue color gradient from light bank to dark depth */
    G_init_colors(&colr);
    if (negative_flag->answer == 1) {
	G_add_f_raster_color_rule(&max_depth, 0, 240, 255,
				  &min_depth, 0, 50, 170, &colr);
    }
    else {
	G_add_f_raster_color_rule(&min_depth, 0, 240, 255,
				  &max_depth, 0, 50, 170, &colr);
    }

    if (G_write_colors(lakemap, G_mapset(), &colr) != 1)
	G_fatal_error(_("Unable to read color file of raster map <%s>"),
		      lakemap);

    G_short_history(lakemap, "raster", &history);
    G_command_history(&history);
    G_write_history(lakemap, &history);

    return EXIT_SUCCESS;
}