region.c 9.8 KB

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