123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329 |
- /*!
- \file lib/gis/get_projinfo.c
- \brief GIS Library - Get projection info
- (C) 1999-2014 by the GRASS Development Team
- This program is free software under the GNU General Public License
- (>=v2). Read the file COPYING that comes with GRASS for details.
- */
- #include <string.h>
- #include <errno.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <grass/gis.h>
- #include <grass/glocale.h>
- #define PERMANENT "PERMANENT"
- /*!
- \brief Gets units information for location
- Note: Allocated Key_Value structure should be freed by
- G_free_key_value().
- Prints a warning if no units information available.
- \return pointer to Key_Value structure with key/value pairs
- \return NULL on failure
- */
- struct Key_Value *G_get_projunits(void)
- {
- struct Key_Value *in_units_keys;
- char path[GPATH_MAX];
- G_file_name(path, "", UNIT_FILE, PERMANENT);
- if (access(path, 0) != 0) {
- if (G_projection() != PROJECTION_XY) {
- G_warning(_("<%s> file not found for location <%s>"),
- UNIT_FILE, G_location());
- }
- return NULL;
- }
- in_units_keys = G_read_key_value_file(path);
- return in_units_keys;
- }
- /*!
- \brief Gets projection information for location
- Note: Allocated Key_Value structure should be freed by
- G_free_key_value().
- Prints a warning if no projection information available.
- \return pointer to Key_Value structure with key/value pairs
- \return NULL on failure
- */
- struct Key_Value *G_get_projinfo(void)
- {
- struct Key_Value *in_proj_keys, *in_epsg_keys;
- char path[GPATH_MAX];
- G_file_name(path, "", PROJECTION_FILE, PERMANENT);
- if (access(path, 0) != 0) {
- if (G_projection() != PROJECTION_XY) {
- G_warning(_("<%s> file not found for location <%s>"),
- PROJECTION_FILE, G_location());
- }
- return NULL;
- }
- in_proj_keys = G_read_key_value_file(path);
- /* TODO: do not restrict to EPSG as the only authority */
- if ((in_epsg_keys = G_get_projepsg()) != NULL) {
- const char *epsgstr = G_find_key_value("epsg", in_epsg_keys);
- char buf[4096];
- sprintf(buf, "EPSG:%s", epsgstr);
- G_set_key_value("init", buf, in_proj_keys);
- G_free_key_value(in_epsg_keys);
- }
- return in_proj_keys;
- }
- /*!
- \brief Gets EPSG information for the current location
- DEPRECATED: Use G_get_projsrid() instead.
- Note: Allocated Key_Value structure should be freed by
- G_free_key_value().
- \return pointer to Key_Value structure with key/value pairs
- \return NULL when EPSG code is not defined for location
- */
- /* superseded by G_get_projsrid(), keep for backwards compatibility */
- struct Key_Value *G_get_projepsg(void)
- {
- struct Key_Value *in_epsg_keys;
- char path[GPATH_MAX];
- G_file_name(path, "", EPSG_FILE, PERMANENT);
- if (access(path, 0) != 0) {
- if (G_projection() != PROJECTION_XY) {
- G_debug(1, "<%s> file not found for location <%s>",
- EPSG_FILE, G_location());
- }
- return NULL;
- }
- in_epsg_keys = G_read_key_value_file(path);
- return in_epsg_keys;
- }
- /*!
- \brief Get WKT information for the current location
- \return pointer to WKT string
- \return NULL when WKT is not available for the current location
- */
- char *G_get_projwkt(void)
- {
- char *wktstring = NULL;
- char path[GPATH_MAX];
- FILE *fp;
- int n, nalloc;
- int c;
- G_file_name(path, "", WKT_FILE, "PERMANENT");
- if (access(path, 0) != 0) {
- if (G_projection() != PROJECTION_XY) {
- G_debug(1, "<%s> file not found for location <%s>",
- WKT_FILE, G_location());
- }
- return NULL;
- }
- fp = fopen(path, "r");
- if (!fp)
- G_fatal_error(_("Unable to open input file <%s>: %s"), path, strerror(errno));
- wktstring = G_malloc(1024 * sizeof(char));
- nalloc = 1024;
- n = 0;
- while (1) {
- c = fgetc(fp);
- if (c == EOF) {
- break;
- }
- if (c == '\r') { /* DOS or MacOS9 */
- c = fgetc(fp);
- if (c != EOF) {
- if (c != '\n') { /* MacOS9 - we have to return the char to stream */
- ungetc(c, fp);
- c = '\n';
- }
- }
- else { /* MacOS9 - we have to return the char to stream */
- ungetc(c, fp);
- c = '\n';
- }
- }
- if (n == nalloc) {
- wktstring = G_realloc(wktstring, nalloc + 1024);
- nalloc += 1024;
- }
- wktstring[n] = c;
- n++;
- }
- if (n > 0) {
- if (n == nalloc) {
- wktstring = G_realloc(wktstring, nalloc + 1);
- nalloc += 1;
- }
- wktstring[n] = '\0';
- }
- else {
- G_free(wktstring);
- wktstring = NULL;
- }
- if (fclose(fp) != 0)
- G_fatal_error(_("Error closing output file <%s>: %s"), path, strerror(errno));
- if (wktstring && *wktstring)
- G_chop(wktstring);
- if (wktstring && *wktstring == '\0') {
- G_free(wktstring);
- wktstring = NULL;
- }
- return wktstring;
- }
- /*!
- \brief Get srid (spatial reference id) for the current location
- Typically an srid will be of the form authority NAME:CODE,
- e.g. EPSG:4326
- This srid is passed to proj_create() using PROJ or
- OSRSetFromUserInput() using GDAL. Therefore various other forms of
- srid are possible, e.g. in OSRSetFromUserInput():
- 1. Well Known Text definition - passed on to importFromWkt().
- 2. "EPSG:n" - number passed on to importFromEPSG().
- 3. "EPSGA:n" - number passed on to importFromEPSGA().
- 4. "AUTO:proj_id,unit_id,lon0,lat0" - WMS auto projections.
- 5. "urn:ogc:def:crs:EPSG::n" - ogc urns
- 6. PROJ.4 definitions - passed on to importFromProj4().
- 7. filename - file read for WKT, XML or PROJ.4 definition.
- 8. well known name accepted by SetWellKnownGeogCS(), such as NAD27, NAD83, WGS84 or WGS72.
- 9. "IGNF:xxxx", "ESRI:xxxx", etc. from definitions from the PROJ database;
- 10. PROJJSON (PROJ >= 6.2)
- \return pointer to srid string
- \return NULL when srid is not available for the current location
- */
- char *G_get_projsrid(void)
- {
- char *sridstring = NULL;
- char path[GPATH_MAX];
- FILE *fp;
- int n, nalloc;
- int c;
- G_file_name(path, "", SRID_FILE, "PERMANENT");
- if (access(path, 0) != 0) {
- if (G_projection() != PROJECTION_XY) {
- struct Key_Value *projepsg;
- const char *epsg_num;
- G_debug(1, "<%s> file not found for location <%s>",
- SRID_FILE, G_location());
- /* for backwards compatibility, check if PROJ_EPSG exists */
- if ((projepsg = G_get_projepsg()) != NULL) {
- epsg_num = G_find_key_value("epsg", projepsg);
- if (*epsg_num) {
- G_debug(1, "Using <%s> file instead for location <%s>",
- EPSG_FILE, G_location());
- G_asprintf(&sridstring, "EPSG:%s", epsg_num);
- G_free_key_value(projepsg);
- return sridstring;
- }
- }
- }
- return NULL;
- }
- fp = fopen(path, "r");
- if (!fp)
- G_fatal_error(_("Unable to open input file <%s>: %s"), path, strerror(errno));
- sridstring = G_malloc(1024 * sizeof(char));
- nalloc = 1024;
- n = 0;
- while (1) {
- c = fgetc(fp);
- if (c == EOF) {
- break;
- }
- if (c == '\r') { /* DOS or MacOS9 */
- c = fgetc(fp);
- if (c != EOF) {
- if (c != '\n') { /* MacOS9 - we have to return the char to stream */
- ungetc(c, fp);
- c = '\n';
- }
- }
- else { /* MacOS9 - we have to return the char to stream */
- ungetc(c, fp);
- c = '\n';
- }
- }
- if (n == nalloc) {
- sridstring = G_realloc(sridstring, nalloc + 1024);
- nalloc += 1024;
- }
- sridstring[n] = c;
- n++;
- }
- if (n > 0) {
- if (n == nalloc) {
- sridstring = G_realloc(sridstring, nalloc + 1);
- nalloc += 1;
- }
- sridstring[n] = '\0';
- }
- else {
- G_free(sridstring);
- sridstring = NULL;
- }
- if (fclose(fp) != 0)
- G_fatal_error(_("Error closing output file <%s>: %s"), path, strerror(errno));
- if (sridstring && *sridstring)
- G_chop(sridstring);
- if (sridstring && *sridstring == '\0') {
- G_free(sridstring);
- sridstring = NULL;
- }
- return sridstring;
- }
|