123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- /******************************************************************************
- *
- * Project: libgrass
- * Purpose: Function to create a new location automatically given a
- * "Cell_head", PROJ_INFO and PROJ_UNITS information.
- * Author: Frank Warmerdam, warmerda@pobox.com
- *
- ******************************************************************************
- * Copyright (c) 2000, Frank Warmerdam
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- ******************************************************************************
- *
- */
- #include <grass/gis.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <sys/stat.h>
- #include <math.h>
- /*
- * Returns 0 on success.
- * Returns -1 to indicate a system error (check errno).
- */
- int G__make_location(const char *location_name,
- struct Cell_head *wind,
- struct Key_Value *proj_info,
- struct Key_Value *proj_units, FILE * report_file)
- {
- char path[GPATH_MAX];
- /* Try to create the location directory, under the gisdbase. */
- sprintf(path, "%s/%s", G_gisdbase(), location_name);
- if (G_mkdir(path) != 0)
- return -1;
- /* Make the PERMANENT mapset. */
- sprintf(path, "%s/%s/%s", G_gisdbase(), location_name, "PERMANENT");
- if (G_mkdir(path) != 0)
- return -1;
- /* make these the new current location and mapset */
- G__setenv("LOCATION_NAME", location_name);
- G__setenv("MAPSET", "PERMANENT");
- /* Create the default, and current window files */
- G__put_window(wind, "", "DEFAULT_WIND");
- G__put_window(wind, "", "WIND");
- /* Write out the PROJ_INFO, and PROJ_UNITS if available. */
- if (proj_info != NULL) {
- G_file_name(path, "", "PROJ_INFO", "PERMANENT");
- G_write_key_value_file(path, proj_info);
- }
- if (proj_units != NULL) {
- G_file_name(path, "", "PROJ_UNITS", "PERMANENT");
- G_write_key_value_file(path, proj_units);
- }
- return 0;
- }
- /*!
- * \brief create a new location
- *
- * This function creates a new location in the current database,
- * initializes the projection, default window and current window.
- *
- * \param location_name
- * The name of the new location. Should not include
- * the full path, the location will be created within
- * the current database.
- * \param wind
- * Contains the default window setting for the
- * new location. All fields should be set in this
- * structure, and care should be taken to ensure that
- * the proj/zone fields match the definition in the
- * proj_info parameter (see G_set_cellhd_from_projinfo()).
- *
- * \param proj_info
- * Projection definition suitable to write to the
- * PROJ_INFO file, or NULL for PROJECTION_XY.
- *
- * \param proj_units
- * Projection units suitable to write to the PROJ_UNITS
- * file, or NULL.
- *
- * \param report_file
- * File to which creation information should be written
- * (can be stdout). Currently not used.
- *
- * \return Returns 0 on success, or generates a fatal error on failure.
- * The G__make_location() function operates the same, but returns a
- * non-zero error code on failure, instead of terminating.
- */
- int G_make_location(const char *location_name,
- struct Cell_head *wind,
- struct Key_Value *proj_info,
- struct Key_Value *proj_units, FILE * report_file)
- {
- int err;
- err = G__make_location(location_name, wind, proj_info, proj_units,
- report_file);
- if (err == 0)
- return 0;
- if (err == -1) {
- perror("G_make_location");
- }
- G_fatal_error("G_make_location failed.");
- return 1;
- }
- /************************************************************************/
- /* G_compare_projections() */
- /************************************************************************/
- /*!
- * \brief compare projections
- *
- * \param proj_info1
- * \param proj_units1
- * \param proj_info2
- * \param proj_units2
- * \return -1 if not the same projection, -2 if linear unit translation to
- * meters fails, -4 if not the same ellipsoid, -5 if UTM zone differs
- * else TRUE if projections match.
- *
- */
- int
- G_compare_projections(const struct Key_Value *proj_info1,
- const struct Key_Value *proj_units1,
- const struct Key_Value *proj_info2,
- const struct Key_Value *proj_units2)
- {
- const char *proj1, *proj2;
- if (proj_info1 == NULL && proj_info2 == NULL)
- return TRUE;
- /* -------------------------------------------------------------------- */
- /* Are they both in the same projection? */
- /* -------------------------------------------------------------------- */
- /* prevent seg fault in G_find_key_value */
- if (proj_info1 == NULL || proj_info2 == NULL)
- return -1;
- proj1 = G_find_key_value("proj", proj_info1);
- proj2 = G_find_key_value("proj", proj_info2);
- if (proj1 == NULL || proj2 == NULL || strcmp(proj1, proj2))
- return -1;
- /* -------------------------------------------------------------------- */
- /* Verify that the linear unit translation to meters is OK. */
- /* -------------------------------------------------------------------- */
- /* prevent seg fault in G_find_key_value */
- if (proj_units1 == NULL && proj_units2 == NULL)
- return TRUE;
- if (proj_units1 == NULL || proj_units2 == NULL)
- return -2;
- {
- double a1 = 0, a2 = 0;
- if (G_find_key_value("meters", proj_units1) != NULL)
- a1 = atof(G_find_key_value("meters", proj_units1));
- if (G_find_key_value("meters", proj_units2) != NULL)
- a2 = atof(G_find_key_value("meters", proj_units2));
- if (a1 && a2 && (fabs(a2 - a1) > 0.000001))
- return -2;
- }
- /* -------------------------------------------------------------------- */
- /* Do they both have the same ellipsoid? */
- /* Lets just check the semi-major axis for now to keep it simple */
- /* -------------------------------------------------------------------- */
- {
- double a1 = 0, a2 = 0;
- if (G_find_key_value("a", proj_info1) != NULL)
- a1 = atof(G_find_key_value("a", proj_info1));
- if (G_find_key_value("a", proj_info2) != NULL)
- a2 = atof(G_find_key_value("a", proj_info2));
- if (a1 && a2 && (fabs(a2 - a1) > 0.000001))
- return -4;
- }
- /* -------------------------------------------------------------------- */
- /* Zone check specially for UTM */
- /* -------------------------------------------------------------------- */
- if (!strcmp(proj1, "utm") && !strcmp(proj2, "utm")
- && atof(G_find_key_value("zone", proj_info1))
- != atof(G_find_key_value("zone", proj_info2)))
- return -5;
- /* -------------------------------------------------------------------- */
- /* Do they both have the same false easting? */
- /* -------------------------------------------------------------------- */
- {
- const char *x_0_1 = NULL, *x_0_2 = NULL;
- x_0_1 = G_find_key_value("x_0", proj_info1);
- x_0_2 = G_find_key_value("x_0", proj_info2);
- if (x_0_1 && x_0_2 && (fabs(atof(x_0_1) - atof(x_0_2)) > 0.000001))
- return -6;
- }
- /* -------------------------------------------------------------------- */
- /* Do they both have the same false northing? */
- /* -------------------------------------------------------------------- */
- {
- const char *y_0_1 = NULL, *y_0_2 = NULL;
- y_0_1 = G_find_key_value("y_0", proj_info1);
- y_0_2 = G_find_key_value("y_0", proj_info2);
- if (y_0_1 && y_0_2 && (fabs(atof(y_0_1) - atof(y_0_2)) > 0.000001))
- return -7;
- }
- /* -------------------------------------------------------------------- */
- /* Add more details in later. */
- /* -------------------------------------------------------------------- */
- return TRUE;
- }
|