#include #include #include #include "raster3d_intern.h" /*---------------------------------------------------------------------------*/ /*! * \brief * * Returns in region2d the 2d portion of region3d. * * \param region3d * \param region2d * \return void */ void Rast3d_extract2d_region(RASTER3D_Region * region3d, struct Cell_head *region2d) { region2d->proj = region3d->proj; region2d->zone = region3d->zone; region2d->north = region3d->north; region2d->south = region3d->south; region2d->east = region3d->east; region2d->west = region3d->west; region2d->rows = region3d->rows; region2d->cols = region3d->cols; region2d->ns_res = region3d->ns_res; region2d->ew_res = region3d->ew_res; } /*! * \brief * * Returns in region2d the 2d portion of region3d. * * \param region3d * \param region2d * \return void */ void Rast3d_region_to_cell_head(RASTER3D_Region * region3d, struct Cell_head *region2d) { region2d->proj = region3d->proj; region2d->zone = region3d->zone; region2d->north = region3d->north; region2d->south = region3d->south; region2d->east = region3d->east; region2d->west = region3d->west; region2d->top = region3d->top; region2d->bottom = region3d->bottom; region2d->rows = region3d->rows; region2d->rows3 = region3d->rows; region2d->cols = region3d->cols; region2d->cols3 = region3d->cols; region2d->depths = region3d->depths; region2d->ns_res = region3d->ns_res; region2d->ns_res3 = region3d->ns_res; region2d->ew_res = region3d->ew_res; region2d->ew_res3 = region3d->ew_res; region2d->tb_res = region3d->tb_res; } /*---------------------------------------------------------------------------*/ /*! * \brief * * Replaces the 2d portion of region3d with the * values stored in region2d. * * \param region2d * \param region3d * \return void */ void Rast3d_incorporate2d_region(struct Cell_head *region2d, RASTER3D_Region * region3d) { region3d->proj = region2d->proj; region3d->zone = region2d->zone; region3d->north = region2d->north; region3d->south = region2d->south; region3d->east = region2d->east; region3d->west = region2d->west; region3d->rows = region2d->rows; region3d->cols = region2d->cols; region3d->ns_res = region2d->ns_res; region3d->ew_res = region2d->ew_res; } /*! * \brief * * Replaces the 2d portion of region3d with the * values stored in region2d. * * \param region2d * \param region3d * \return void */ void Rast3d_region_from_to_cell_head(struct Cell_head *region2d, RASTER3D_Region * region3d) { region3d->proj = region2d->proj; region3d->zone = region2d->zone; region3d->north = region2d->north; region3d->south = region2d->south; region3d->east = region2d->east; region3d->west = region2d->west; region3d->top = region2d->top; region3d->bottom = region2d->bottom; region3d->rows = region2d->rows3; region3d->cols = region2d->cols3; region3d->depths = region2d->depths; region3d->ns_res = region2d->ns_res3; region3d->ew_res = region2d->ew_res3; region3d->tb_res = region2d->tb_res; } /*---------------------------------------------------------------------------*/ /*! * \brief * * Computes an adjusts the resolutions in the region structure from the region * boundaries and number of cells per dimension. * * \param region * \return void */ void Rast3d_adjust_region(RASTER3D_Region * region) { struct Cell_head region2d; Rast3d_region_to_cell_head(region, ®ion2d); G_adjust_Cell_head3(®ion2d, 1, 1, 1); Rast3d_region_from_to_cell_head(®ion2d, region); if (region->depths <= 0) Rast3d_fatal_error("Rast3d_adjust_region: depths <= 0"); region->tb_res = (region->top - region->bottom) / region->depths; } /*---------------------------------------------------------------------------*/ /*! * \brief * * Computes an adjusts the number of cells per dimension in the region * structure from the region boundaries and resolutions. * * \param region * \return void */ void Rast3d_adjust_region_res(RASTER3D_Region * region) { struct Cell_head region2d; Rast3d_region_to_cell_head(region, ®ion2d); G_adjust_Cell_head3(®ion2d, 1, 1, 1); Rast3d_region_from_to_cell_head(®ion2d, region); if (region->tb_res <= 0) Rast3d_fatal_error("Rast3d_adjust_region_res: tb_res <= 0"); region->depths = (region->top - region->bottom + region->tb_res / 2.0) / region->tb_res; if (region->depths == 0) region->depths = 1; } /*---------------------------------------------------------------------------*/ /*! * \brief * * Copies the values of regionSrc into regionDst. * * \param regionDest * \param regionSrc * \return void */ void Rast3d_region_copy(RASTER3D_Region * regionDest, RASTER3D_Region * regionSrc) { regionDest->proj = regionSrc->proj; regionDest->zone = regionSrc->zone; regionDest->north = regionSrc->north; regionDest->south = regionSrc->south; regionDest->east = regionSrc->east; regionDest->west = regionSrc->west; regionDest->top = regionSrc->top; regionDest->bottom = regionSrc->bottom; regionDest->rows = regionSrc->rows; regionDest->cols = regionSrc->cols; regionDest->depths = regionSrc->depths; regionDest->ns_res = regionSrc->ns_res; regionDest->ew_res = regionSrc->ew_res; regionDest->tb_res = regionSrc->tb_res; } /*---------------------------------------------------------------------------*/ int Rast3d_read_region_map(const char *name, const char *mapset, RASTER3D_Region * region) { char fullName[GPATH_MAX]; char xname[GNAME_MAX], xmapset[GMAPSET_MAX]; if (G_name_is_fully_qualified(name, xname, xmapset)) Rast3d_filename(fullName, RASTER3D_HEADER_ELEMENT, xname, xmapset); else { if (!mapset || !*mapset) mapset = G_find_raster3d(name, ""); Rast3d_filename(fullName, RASTER3D_HEADER_ELEMENT, name, mapset); } return Rast3d_read_window(region, fullName); } /*---------------------------------------------------------------------------*/ /*! * \brief * * Returns 1 if region-coordinates (north, east, top) are * inside the region of map. Returns 0 otherwise. * * \param region * \param north * \param east * \param top * \return int */ int Rast3d_is_valid_location(RASTER3D_Region *region, double north, double east, double top) { return ((north >= region->south) && (north <= region->north) && (east >= region->west) && (east <= region->east) && (((top >= region->bottom) && (top <= region->top)) || ((top <= region->bottom) && (top >= region->top)))); } /*---------------------------------------------------------------------------*/ /*! * \brief * * Converts region-coordinates (north, east, * top) into cell-coordinates (x, y, z). * * \param region * \param north * \param east * \param top * \param x * \param y * \param z * \return void */ void Rast3d_location2coord(RASTER3D_Region *region, double north, double east, double top, int *x, int *y, int *z) { double col, row, depth; LOCATION_TO_COORD(region, north, east, top, &col, &row, &depth); *x = (int)floor(col); *y = (int)floor(row); *z = (int)floor(depth); } /*! * \brief * * Converts region-coordinates (north, east, * top) into cell-coordinates (x, y, z). * * Note: The results are double numbers. Casting them to * int will give the column, row and depth number. * * \param region * \param north * \param east * \param top * \param x * \param y * \param z * \return void */ void Rast3d_location2coord_double(RASTER3D_Region *region, double north, double east, double top, double *x, double *y, double *z) { LOCATION_TO_COORD(region, north, east, top, x, y, z); G_debug(4, "Rast3d_location2coord_double x %f y %f z %f\n", *x, *y, *z); } /*! * \brief * * Converts region-coordinates (north, east, * top) into cell-coordinates (x, y, z). * This function calls Rast3d_fatal_error in case location is not in window. * * \param region * \param north * \param east * \param top * \param x * \param y * \param z * \return void */ void Rast3d_location2coord2(RASTER3D_Region *region, double north, double east, double top, int *x, int *y, int *z) { if (!Rast3d_is_valid_location(region, north, east, top)) Rast3d_fatal_error("Rast3d_location2coord2: location not in region"); double col, row, depth; LOCATION_TO_COORD(region, north, east, top, &col, &row, &depth); *x = (int)floor(col); *y = (int)floor(row); *z = (int)floor(depth); } /*! * \brief * * Converts cell-coordinates (x, y, z) into region-coordinates * (north, east, top). * * * Note: x, y and z is a double: * - x+0.0 will return the easting for the western edge of the column. * - x+0.5 will return the easting for the center of the column. * - x+1.0 will return the easting for the eastern edge of the column. * * - y+0.0 will return the northing for the northern edge of the row. * - y+0.5 will return the northing for the center of the row. * - y+1.0 will return the northing for the southern edge of the row. * * - z+0.0 will return the top for the lower edge of the depth. * - z+0.5 will return the top for the center of the depth. * - z+1.0 will return the top for the upper edge of the column. * * * \param region * \param x * \param y * \param z * \param north * \param east * \param top * \return void */ void Rast3d_coord2location(RASTER3D_Region * region, double x, double y, double z, double *north, double *east, double *top) { COORD_TO_LOCATION(region, x, y, z, north, east, top); G_debug(4, "Rast3d_coord2location north %g east %g top %g\n", *north, *east, *top); }