region.c 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. #include <stdio.h>
  2. #include <math.h>
  3. #include <grass/raster.h>
  4. #include "raster3d_intern.h"
  5. /*---------------------------------------------------------------------------*/
  6. /*!
  7. * \brief
  8. *
  9. * Returns in <em>region2d</em> the <em>2d</em> portion of <em>region3d</em>.
  10. *
  11. * \param region3d
  12. * \param region2d
  13. * \return void
  14. */
  15. void Rast3d_extract2d_region(RASTER3D_Region * region3d, struct Cell_head *region2d)
  16. {
  17. region2d->proj = region3d->proj;
  18. region2d->zone = region3d->zone;
  19. region2d->north = region3d->north;
  20. region2d->south = region3d->south;
  21. region2d->east = region3d->east;
  22. region2d->west = region3d->west;
  23. region2d->rows = region3d->rows;
  24. region2d->cols = region3d->cols;
  25. region2d->ns_res = region3d->ns_res;
  26. region2d->ew_res = region3d->ew_res;
  27. }
  28. /*!
  29. * \brief
  30. *
  31. * Returns in <em>region2d</em> the <em>2d</em> portion of <em>region3d</em>.
  32. *
  33. * \param region3d
  34. * \param region2d
  35. * \return void
  36. */
  37. void Rast3d_region_to_cell_head(RASTER3D_Region * region3d, struct Cell_head *region2d)
  38. {
  39. region2d->proj = region3d->proj;
  40. region2d->zone = region3d->zone;
  41. region2d->north = region3d->north;
  42. region2d->south = region3d->south;
  43. region2d->east = region3d->east;
  44. region2d->west = region3d->west;
  45. region2d->top = region3d->top;
  46. region2d->bottom = region3d->bottom;
  47. region2d->rows = region3d->rows;
  48. region2d->rows3 = region3d->rows;
  49. region2d->cols = region3d->cols;
  50. region2d->cols3 = region3d->cols;
  51. region2d->depths = region3d->depths;
  52. region2d->ns_res = region3d->ns_res;
  53. region2d->ns_res3 = region3d->ns_res;
  54. region2d->ew_res = region3d->ew_res;
  55. region2d->ew_res3 = region3d->ew_res;
  56. region2d->tb_res = region3d->tb_res;
  57. }
  58. /*---------------------------------------------------------------------------*/
  59. /*!
  60. * \brief
  61. *
  62. * Replaces the <em>2d</em> portion of <em>region3d</em> with the
  63. * values stored in <em>region2d</em>.
  64. *
  65. * \param region2d
  66. * \param region3d
  67. * \return void
  68. */
  69. void
  70. Rast3d_incorporate2d_region(struct Cell_head *region2d, RASTER3D_Region * region3d)
  71. {
  72. region3d->proj = region2d->proj;
  73. region3d->zone = region2d->zone;
  74. region3d->north = region2d->north;
  75. region3d->south = region2d->south;
  76. region3d->east = region2d->east;
  77. region3d->west = region2d->west;
  78. region3d->rows = region2d->rows;
  79. region3d->cols = region2d->cols;
  80. region3d->ns_res = region2d->ns_res;
  81. region3d->ew_res = region2d->ew_res;
  82. }
  83. /*!
  84. * \brief
  85. *
  86. * Replaces the <em>2d</em> portion of <em>region3d</em> with the
  87. * values stored in <em>region2d</em>.
  88. *
  89. * \param region2d
  90. * \param region3d
  91. * \return void
  92. */
  93. void
  94. Rast3d_region_from_to_cell_head(struct Cell_head *region2d, RASTER3D_Region * region3d)
  95. {
  96. region3d->proj = region2d->proj;
  97. region3d->zone = region2d->zone;
  98. region3d->north = region2d->north;
  99. region3d->south = region2d->south;
  100. region3d->east = region2d->east;
  101. region3d->west = region2d->west;
  102. region3d->top = region2d->top;
  103. region3d->bottom = region2d->bottom;
  104. region3d->rows = region2d->rows3;
  105. region3d->cols = region2d->cols3;
  106. region3d->depths = region2d->depths;
  107. region3d->ns_res = region2d->ns_res3;
  108. region3d->ew_res = region2d->ew_res3;
  109. region3d->tb_res = region2d->tb_res;
  110. }
  111. /*---------------------------------------------------------------------------*/
  112. /*!
  113. * \brief
  114. *
  115. * Computes an adjusts the resolutions in the region structure from the region
  116. * boundaries and number of cells per dimension.
  117. *
  118. * \param region
  119. * \return void
  120. */
  121. void Rast3d_adjust_region(RASTER3D_Region * region)
  122. {
  123. struct Cell_head region2d;
  124. Rast3d_region_to_cell_head(region, &region2d);
  125. G_adjust_Cell_head3(&region2d, 1, 1, 1);
  126. Rast3d_region_from_to_cell_head(&region2d, region);
  127. if (region->depths <= 0)
  128. Rast3d_fatal_error("Rast3d_adjust_region: depths <= 0");
  129. region->tb_res = (region->top - region->bottom) / region->depths;
  130. }
  131. /*---------------------------------------------------------------------------*/
  132. /*!
  133. * \brief
  134. *
  135. * Computes an adjusts the number of cells per dimension in the region
  136. * structure from the region boundaries and resolutions.
  137. *
  138. * \param region
  139. * \return void
  140. */
  141. void Rast3d_adjust_region_res(RASTER3D_Region * region)
  142. {
  143. struct Cell_head region2d;
  144. Rast3d_region_to_cell_head(region, &region2d);
  145. G_adjust_Cell_head3(&region2d, 1, 1, 1);
  146. Rast3d_region_from_to_cell_head(&region2d, region);
  147. if (region->tb_res <= 0)
  148. Rast3d_fatal_error("Rast3d_adjust_region_res: tb_res <= 0");
  149. region->depths = (region->top - region->bottom + region->tb_res / 2.0) /
  150. region->tb_res;
  151. if (region->depths == 0)
  152. region->depths = 1;
  153. }
  154. /*---------------------------------------------------------------------------*/
  155. /*!
  156. * \brief
  157. *
  158. * Copies the values of <em>regionSrc</em> into <em>regionDst</em>.
  159. *
  160. * \param regionDest
  161. * \param regionSrc
  162. * \return void
  163. */
  164. void Rast3d_region_copy(RASTER3D_Region * regionDest, RASTER3D_Region * regionSrc)
  165. {
  166. regionDest->proj = regionSrc->proj;
  167. regionDest->zone = regionSrc->zone;
  168. regionDest->north = regionSrc->north;
  169. regionDest->south = regionSrc->south;
  170. regionDest->east = regionSrc->east;
  171. regionDest->west = regionSrc->west;
  172. regionDest->top = regionSrc->top;
  173. regionDest->bottom = regionSrc->bottom;
  174. regionDest->rows = regionSrc->rows;
  175. regionDest->cols = regionSrc->cols;
  176. regionDest->depths = regionSrc->depths;
  177. regionDest->ns_res = regionSrc->ns_res;
  178. regionDest->ew_res = regionSrc->ew_res;
  179. regionDest->tb_res = regionSrc->tb_res;
  180. }
  181. /*---------------------------------------------------------------------------*/
  182. int
  183. Rast3d_read_region_map(const char *name, const char *mapset, RASTER3D_Region * region)
  184. {
  185. char fullName[GPATH_MAX];
  186. char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
  187. if (G_name_is_fully_qualified(name, xname, xmapset))
  188. Rast3d_filename(fullName, RASTER3D_HEADER_ELEMENT, xname, xmapset);
  189. else {
  190. if (!mapset || !*mapset)
  191. mapset = G_find_raster3d(name, "");
  192. Rast3d_filename(fullName, RASTER3D_HEADER_ELEMENT, name, mapset);
  193. }
  194. return Rast3d_read_window(region, fullName);
  195. }
  196. /*---------------------------------------------------------------------------*/
  197. /*!
  198. * \brief
  199. *
  200. * Returns 1 if region-coordinates <em>(north, east, top)</em> are
  201. * inside the region of <em>map</em>. Returns 0 otherwise.
  202. *
  203. * \param region
  204. * \param north
  205. * \param east
  206. * \param top
  207. * \return int
  208. */
  209. int Rast3d_is_valid_location(RASTER3D_Region *region, double north, double east, double top)
  210. {
  211. return ((north >= region->south) && (north <= region->north) &&
  212. (east >= region->west) && (east <= region->east) &&
  213. (((top >= region->bottom) && (top <= region->top)) ||
  214. ((top <= region->bottom) && (top >= region->top))));
  215. }
  216. /*---------------------------------------------------------------------------*/
  217. /*!
  218. * \brief
  219. *
  220. * Converts region-coordinates <em>(north, east,
  221. * top)</em> into cell-coordinates <em>(x, y, z)</em>.
  222. *
  223. * \param region
  224. * \param north
  225. * \param east
  226. * \param top
  227. * \param x
  228. * \param y
  229. * \param z
  230. * \return void
  231. */
  232. void
  233. Rast3d_location2coord(RASTER3D_Region *region, double north, double east, double top,
  234. int *x, int *y, int *z)
  235. {
  236. double col, row, depth;
  237. LOCATION_TO_COORD(region, north, east, top, &col, &row, &depth);
  238. *x = (int)floor(col);
  239. *y = (int)floor(row);
  240. *z = (int)floor(depth);
  241. }
  242. /*!
  243. * \brief
  244. *
  245. * Converts region-coordinates <em>(north, east,
  246. * top)</em> into cell-coordinates <em>(x, y, z)</em>.
  247. *
  248. * <b>Note:</b> The results are <i>double</i> numbers. Casting them to
  249. * <i>int</i> will give the column, row and depth number.
  250. *
  251. * \param region
  252. * \param north
  253. * \param east
  254. * \param top
  255. * \param x
  256. * \param y
  257. * \param z
  258. * \return void
  259. */
  260. void
  261. Rast3d_location2coord_double(RASTER3D_Region *region, double north, double east, double top,
  262. double *x, double *y, double *z)
  263. {
  264. LOCATION_TO_COORD(region, north, east, top, x, y, z);
  265. G_debug(4, "Rast3d_location2coord_double x %f y %f z %f\n", *x, *y, *z);
  266. }
  267. /*!
  268. * \brief
  269. *
  270. * Converts region-coordinates <em>(north, east,
  271. * top)</em> into cell-coordinates <em>(x, y, z)</em>.
  272. * This function calls Rast3d_fatal_error in case location is not in window.
  273. *
  274. * \param region
  275. * \param north
  276. * \param east
  277. * \param top
  278. * \param x
  279. * \param y
  280. * \param z
  281. * \return void
  282. */
  283. void
  284. Rast3d_location2coord2(RASTER3D_Region *region, double north, double east, double top,
  285. int *x, int *y, int *z)
  286. {
  287. if (!Rast3d_is_valid_location(region, north, east, top))
  288. Rast3d_fatal_error("Rast3d_location2coord2: location not in region");
  289. double col, row, depth;
  290. LOCATION_TO_COORD(region, north, east, top, &col, &row, &depth);
  291. *x = (int)floor(col);
  292. *y = (int)floor(row);
  293. *z = (int)floor(depth);
  294. }
  295. /*!
  296. * \brief
  297. *
  298. * Converts cell-coordinates <em>(x, y, z)</em> into region-coordinates
  299. * <em>(north, east, top)</em>.
  300. *
  301. * * <b>Note:</b> x, y and z is a double:
  302. * - x+0.0 will return the easting for the western edge of the column.
  303. * - x+0.5 will return the easting for the center of the column.
  304. * - x+1.0 will return the easting for the eastern edge of the column.
  305. *
  306. * - y+0.0 will return the northing for the northern edge of the row.
  307. * - y+0.5 will return the northing for the center of the row.
  308. * - y+1.0 will return the northing for the southern edge of the row.
  309. *
  310. * - z+0.0 will return the top for the lower edge of the depth.
  311. * - z+0.5 will return the top for the center of the depth.
  312. * - z+1.0 will return the top for the upper edge of the column.
  313. *
  314. *
  315. * \param region
  316. * \param x
  317. * \param y
  318. * \param z
  319. * \param north
  320. * \param east
  321. * \param top
  322. * \return void
  323. */
  324. void
  325. Rast3d_coord2location(RASTER3D_Region * region, double x, double y, double z, double *north, double *east, double *top)
  326. {
  327. COORD_TO_LOCATION(region, x, y, z, north, east, top);
  328. G_debug(4, "Rast3d_coord2location north %g east %g top %g\n", *north, *east, *top);
  329. }