make_loc.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /******************************************************************************
  2. *
  3. * Project: libgrass
  4. * Purpose: Function to create a new location automatically given a
  5. * "Cell_head", PROJ_INFO and PROJ_UNITS information.
  6. * Author: Frank Warmerdam, warmerda@pobox.com
  7. *
  8. ******************************************************************************
  9. * Copyright (c) 2000, Frank Warmerdam
  10. *
  11. * This library is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU Library General Public
  13. * License as published by the Free Software Foundation; either
  14. * version 2 of the License, or (at your option) any later version.
  15. *
  16. * This library is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  19. * Library General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU Library General Public
  22. * License along with this library; if not, write to the
  23. * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  24. * Boston, MA 02111-1307, USA.
  25. ******************************************************************************
  26. *
  27. */
  28. #include <grass/gis.h>
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #include <unistd.h>
  32. #include <sys/stat.h>
  33. #include <math.h>
  34. /*
  35. * Returns 0 on success.
  36. * Returns -1 to indicate a system error (check errno).
  37. */
  38. int G__make_location(const char *location_name,
  39. struct Cell_head *wind,
  40. struct Key_Value *proj_info,
  41. struct Key_Value *proj_units, FILE * report_file)
  42. {
  43. char path[GPATH_MAX];
  44. int out_stat;
  45. /* Try to create the location directory, under the gisdbase. */
  46. sprintf(path, "%s/%s", G_gisdbase(), location_name);
  47. if (G_mkdir(path) != 0)
  48. return -1;
  49. /* Make the PERMANENT mapset. */
  50. sprintf(path, "%s/%s/%s", G_gisdbase(), location_name, "PERMANENT");
  51. if (G_mkdir(path) != 0)
  52. return -1;
  53. /* make these the new current location and mapset */
  54. G__setenv("LOCATION_NAME", location_name);
  55. G__setenv("MAPSET", "PERMANENT");
  56. /* Create the default, and current window files */
  57. G__put_window(wind, "", "DEFAULT_WIND");
  58. G__put_window(wind, "", "WIND");
  59. /* Write out the PROJ_INFO, and PROJ_UNITS if available. */
  60. if (proj_info != NULL) {
  61. G__file_name(path, "", "PROJ_INFO", "PERMANENT");
  62. G_write_key_value_file(path, proj_info, &out_stat);
  63. if (out_stat != 0)
  64. return -2;
  65. }
  66. if (proj_units != NULL) {
  67. G__file_name(path, "", "PROJ_UNITS", "PERMANENT");
  68. G_write_key_value_file(path, proj_units, &out_stat);
  69. if (out_stat != 0)
  70. return -2;
  71. }
  72. return 0;
  73. }
  74. /*!
  75. * \brief create a new location
  76. *
  77. * This function creates a new location in the current database,
  78. * initializes the projection, default window and current window.
  79. *
  80. * \param char * location_name
  81. * The name of the new location. Should not include
  82. * the full path, the location will be created within
  83. * the current database.
  84. * \param struct Cell_head *wind
  85. * Contains the default window setting for the
  86. * new location. All fields should be set in this
  87. * structure, and care should be taken to ensure that
  88. * the proj/zone fields match the definition in the
  89. * proj_info parameter (see G_set_cellhd_from_projinfo()).
  90. *
  91. * \param struct Key_Value *proj_info
  92. * Projection definition suitable to write to the
  93. * PROJ_INFO file, or NULL for PROJECTION_XY.
  94. *
  95. * \param struct Key_Value *proj_units
  96. * Projection units suitable to write to the PROJ_UNITS
  97. * file, or NULL.
  98. *
  99. * \param FILE *report_file
  100. * File to which creation information should be written
  101. * (can be stdout). Currently not used.
  102. *
  103. * \return Returns 0 on success, or generates a fatal error on failure.
  104. * The G__make_location() function operates the same, but returns a
  105. * non-zero error code on failure, instead of terminating.
  106. */
  107. int G_make_location(const char *location_name,
  108. struct Cell_head *wind,
  109. struct Key_Value *proj_info,
  110. struct Key_Value *proj_units, FILE * report_file)
  111. {
  112. int err;
  113. err = G__make_location(location_name, wind, proj_info, proj_units,
  114. report_file);
  115. if (err == 0)
  116. return 0;
  117. if (err == -1) {
  118. perror("G_make_location");
  119. }
  120. G_fatal_error("G_make_location failed.");
  121. return 1;
  122. }
  123. /************************************************************************/
  124. /* G_compare_projections() */
  125. /************************************************************************/
  126. /*!
  127. * \brief compare projections
  128. *
  129. * \param proj_info1
  130. * \param proj_units1
  131. * \param proj_info2
  132. * \param proj_units2
  133. * \return -1 if not the same projection, -2 if linear unit translation to
  134. * meters fails, -4 if not the same ellipsoid, -5 if UTM zone differs
  135. * else TRUE if projections match.
  136. *
  137. */
  138. int
  139. G_compare_projections(const struct Key_Value *proj_info1,
  140. const struct Key_Value *proj_units1,
  141. const struct Key_Value *proj_info2,
  142. const struct Key_Value *proj_units2)
  143. {
  144. const char *proj1, *proj2;
  145. if (proj_info1 == NULL && proj_info2 == NULL)
  146. return TRUE;
  147. /* -------------------------------------------------------------------- */
  148. /* Are they both in the same projection? */
  149. /* -------------------------------------------------------------------- */
  150. /* prevent seg fault in G_find_key_value */
  151. if (proj_info1 == NULL || proj_info2 == NULL)
  152. return -1;
  153. proj1 = G_find_key_value("proj", proj_info1);
  154. proj2 = G_find_key_value("proj", proj_info2);
  155. if (proj1 == NULL || proj2 == NULL || strcmp(proj1, proj2))
  156. return -1;
  157. /* -------------------------------------------------------------------- */
  158. /* Verify that the linear unit translation to meters is OK. */
  159. /* -------------------------------------------------------------------- */
  160. /* prevent seg fault in G_find_key_value */
  161. if (proj_units1 == NULL && proj_units2 == NULL)
  162. return TRUE;
  163. if (proj_units1 == NULL || proj_units2 == NULL)
  164. return -2;
  165. {
  166. double a1 = 0, a2 = 0;
  167. if (G_find_key_value("meters", proj_units1) != NULL)
  168. a1 = atof(G_find_key_value("meters", proj_units1));
  169. if (G_find_key_value("meters", proj_units2) != NULL)
  170. a2 = atof(G_find_key_value("meters", proj_units2));
  171. if (a1 && a2 && (fabs(a2 - a1) > 0.000001))
  172. return -2;
  173. }
  174. /* -------------------------------------------------------------------- */
  175. /* Do they both have the same ellipsoid? */
  176. /* Lets just check the semi-major axis for now to keep it simple */
  177. /* -------------------------------------------------------------------- */
  178. {
  179. double a1 = 0, a2 = 0;
  180. if (G_find_key_value("a", proj_info1) != NULL)
  181. a1 = atof(G_find_key_value("a", proj_info1));
  182. if (G_find_key_value("a", proj_info2) != NULL)
  183. a2 = atof(G_find_key_value("a", proj_info2));
  184. if (a1 && a2 && (fabs(a2 - a1) > 0.000001))
  185. return -4;
  186. }
  187. /* -------------------------------------------------------------------- */
  188. /* Zone check specially for UTM */
  189. /* -------------------------------------------------------------------- */
  190. if (!strcmp(proj1, "utm") && !strcmp(proj2, "utm")
  191. && atof(G_find_key_value("zone", proj_info1))
  192. != atof(G_find_key_value("zone", proj_info2)))
  193. return -5;
  194. /* -------------------------------------------------------------------- */
  195. /* Do they both have the same false easting? */
  196. /* -------------------------------------------------------------------- */
  197. {
  198. const char *x_0_1 = NULL, *x_0_2 = NULL;
  199. x_0_1 = G_find_key_value("x_0", proj_info1);
  200. x_0_2 = G_find_key_value("x_0", proj_info2);
  201. if (x_0_1 && x_0_2 && (fabs(atof(x_0_1) - atof(x_0_2)) > 0.000001))
  202. return -6;
  203. }
  204. /* -------------------------------------------------------------------- */
  205. /* Do they both have the same false northing? */
  206. /* -------------------------------------------------------------------- */
  207. {
  208. const char *y_0_1 = NULL, *y_0_2 = NULL;
  209. y_0_1 = G_find_key_value("y_0", proj_info1);
  210. y_0_2 = G_find_key_value("y_0", proj_info2);
  211. if (y_0_1 && y_0_2 && (fabs(atof(y_0_1) - atof(y_0_2)) > 0.000001))
  212. return -7;
  213. }
  214. /* -------------------------------------------------------------------- */
  215. /* Add more details in later. */
  216. /* -------------------------------------------------------------------- */
  217. return TRUE;
  218. }