/*! \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 #include #include #include #include #include #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; }