make_loc.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*!
  2. * \file lib/gis/make_loc.c
  3. *
  4. * \brief GIS Library - Functions to create a new location
  5. *
  6. * Creates a new location automatically given a "Cell_head", PROJ_INFO
  7. * and PROJ_UNITS information.
  8. *
  9. * (C) 2000-2013 by the GRASS Development Team
  10. *
  11. * This program is free software under the GNU General Public License
  12. * (>=v2). Read the file COPYING that comes with GRASS for details.
  13. *
  14. * \author Frank Warmerdam
  15. */
  16. #include <grass/gis.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <unistd.h>
  20. #include <sys/stat.h>
  21. #include <math.h>
  22. /*!
  23. * \brief Create a new location
  24. *
  25. * This function creates a new location in the current database,
  26. * initializes the projection, default window and current window.
  27. *
  28. * \param location_name Name of the new location. Should not include
  29. * the full path, the location will be created within
  30. * the current database.
  31. * \param wind default window setting for the new location.
  32. * All fields should be set in this
  33. * structure, and care should be taken to ensure that
  34. * the proj/zone fields match the definition in the
  35. * proj_info parameter(see G_set_cellhd_from_projinfo()).
  36. *
  37. * \param proj_info projection definition suitable to write to the
  38. * PROJ_INFO file, or NULL for PROJECTION_XY.
  39. *
  40. * \param proj_units projection units suitable to write to the PROJ_UNITS
  41. * file, or NULL.
  42. *
  43. * \return 0 on success
  44. * \return -1 to indicate a system error (check errno).
  45. * \return -2 failed to create projection file (currently not used)
  46. * \return -3 illegal name
  47. */
  48. int G_make_location(const char *location_name,
  49. struct Cell_head *wind,
  50. const struct Key_Value *proj_info,
  51. const struct Key_Value *proj_units)
  52. {
  53. char path[GPATH_MAX];
  54. /* check if location name is legal */
  55. if (G_legal_filename(location_name) != 1)
  56. return -3;
  57. /* Try to create the location directory, under the gisdbase. */
  58. sprintf(path, "%s/%s", G_gisdbase(), location_name);
  59. if (G_mkdir(path) != 0)
  60. return -1;
  61. /* Make the PERMANENT mapset. */
  62. sprintf(path, "%s/%s/%s", G_gisdbase(), location_name, "PERMANENT");
  63. if (G_mkdir(path) != 0) {
  64. return -1;
  65. }
  66. /* make these the new current location and mapset */
  67. G_setenv_nogisrc("LOCATION_NAME", location_name);
  68. G_setenv_nogisrc("MAPSET", "PERMANENT");
  69. /* Create the default, and current window files */
  70. G_put_element_window(wind, "", "DEFAULT_WIND");
  71. G_put_element_window(wind, "", "WIND");
  72. /* Write out the PROJ_INFO, and PROJ_UNITS if available. */
  73. if (proj_info != NULL) {
  74. G_file_name(path, "", "PROJ_INFO", "PERMANENT");
  75. G_write_key_value_file(path, proj_info);
  76. }
  77. if (proj_units != NULL) {
  78. G_file_name(path, "", "PROJ_UNITS", "PERMANENT");
  79. G_write_key_value_file(path, proj_units);
  80. }
  81. return 0;
  82. }
  83. /*!
  84. * \brief Compare projections including units
  85. *
  86. * \param proj_info1 projection info to compare
  87. * \param proj_units1 projection units to compare
  88. * \param proj_info2 projection info to compare
  89. * \param proj_units2 projection units to compare
  90. * \return -1 if not the same projection
  91. * \return -2 if linear unit translation to meters fails
  92. * \return -4 if not the same ellipsoid,
  93. * \return -5 if UTM zone differs
  94. * \return -6 if UTM hemisphere differs,
  95. * \return -7 if false easting differs
  96. * \return -8 if false northing differs,
  97. * \return 1 if projections match.
  98. */
  99. int G_compare_projections(const struct Key_Value *proj_info1,
  100. const struct Key_Value *proj_units1,
  101. const struct Key_Value *proj_info2,
  102. const struct Key_Value *proj_units2)
  103. {
  104. const char *proj1, *proj2;
  105. if (proj_info1 == NULL && proj_info2 == NULL)
  106. return TRUE;
  107. /* -------------------------------------------------------------------- */
  108. /* Are they both in the same projection? */
  109. /* -------------------------------------------------------------------- */
  110. /* prevent seg fault in G_find_key_value */
  111. if (proj_info1 == NULL || proj_info2 == NULL)
  112. return -1;
  113. proj1 = G_find_key_value("proj", proj_info1);
  114. proj2 = G_find_key_value("proj", proj_info2);
  115. if (proj1 == NULL || proj2 == NULL || strcmp(proj1, proj2))
  116. return -1;
  117. /* -------------------------------------------------------------------- */
  118. /* Verify that the linear unit translation to meters is OK. */
  119. /* -------------------------------------------------------------------- */
  120. /* prevent seg fault in G_find_key_value */
  121. if (proj_units1 == NULL && proj_units2 == NULL)
  122. return 1;
  123. if (proj_units1 == NULL || proj_units2 == NULL)
  124. return -2;
  125. {
  126. double a1 = 0, a2 = 0;
  127. if (G_find_key_value("meters", proj_units1) != NULL)
  128. a1 = atof(G_find_key_value("meters", proj_units1));
  129. if (G_find_key_value("meters", proj_units2) != NULL)
  130. a2 = atof(G_find_key_value("meters", proj_units2));
  131. if (a1 && a2 && (fabs(a2 - a1) > 0.000001))
  132. return -2;
  133. }
  134. /* -------------------------------------------------------------------- */
  135. /* Do they both have the same ellipsoid? */
  136. /* Lets just check the semi-major axis for now to keep it simple */
  137. /* -------------------------------------------------------------------- */
  138. {
  139. double a1 = 0, a2 = 0;
  140. if (G_find_key_value("a", proj_info1) != NULL)
  141. a1 = atof(G_find_key_value("a", proj_info1));
  142. if (G_find_key_value("a", proj_info2) != NULL)
  143. a2 = atof(G_find_key_value("a", proj_info2));
  144. if (a1 && a2 && (fabs(a2 - a1) > 0.000001))
  145. return -4;
  146. }
  147. /* -------------------------------------------------------------------- */
  148. /* Zone check specially for UTM */
  149. /* -------------------------------------------------------------------- */
  150. if (!strcmp(proj1, "utm") && !strcmp(proj2, "utm")
  151. && atof(G_find_key_value("zone", proj_info1))
  152. != atof(G_find_key_value("zone", proj_info2)))
  153. return -5;
  154. /* -------------------------------------------------------------------- */
  155. /* Hemisphere check specially for UTM */
  156. /* -------------------------------------------------------------------- */
  157. if (!strcmp(proj1, "utm") && !strcmp(proj2, "utm")
  158. && !!G_find_key_value("south", proj_info1)
  159. != !!G_find_key_value("south", proj_info2))
  160. return -6;
  161. /* -------------------------------------------------------------------- */
  162. /* Do they both have the same false easting? */
  163. /* -------------------------------------------------------------------- */
  164. {
  165. const char *x_0_1 = NULL, *x_0_2 = NULL;
  166. x_0_1 = G_find_key_value("x_0", proj_info1);
  167. x_0_2 = G_find_key_value("x_0", proj_info2);
  168. if (x_0_1 && x_0_2 && (fabs(atof(x_0_1) - atof(x_0_2)) > 0.000001))
  169. return -7;
  170. }
  171. /* -------------------------------------------------------------------- */
  172. /* Do they both have the same false northing? */
  173. /* -------------------------------------------------------------------- */
  174. {
  175. const char *y_0_1 = NULL, *y_0_2 = NULL;
  176. y_0_1 = G_find_key_value("y_0", proj_info1);
  177. y_0_2 = G_find_key_value("y_0", proj_info2);
  178. if (y_0_1 && y_0_2 && (fabs(atof(y_0_1) - atof(y_0_2)) > 0.000001))
  179. return -8;
  180. }
  181. /* -------------------------------------------------------------------- */
  182. /* Add more details in later. */
  183. /* -------------------------------------------------------------------- */
  184. return 1;
  185. }