16 #include <grass/config.h> 22 #include <grass/gis.h> 23 #include <grass/gprojects.h> 24 #include <grass/glocale.h> 28 #include "local_proto.h" 31 #define CSVDIR "/etc/proj/ogr_csv" 33 static void DatumNameMassage(
char **);
36 static char *grass_to_wkt(
const struct Key_Value *proj_info,
37 const struct Key_Value *proj_units,
38 const struct Key_Value *proj_epsg,
39 int esri_style,
int prettify)
42 OGRSpatialReferenceH hSRS;
43 char *wkt, *local_wkt;
54 OSRExportToPrettyWkt(hSRS, &wkt, 0);
56 OSRExportToWkt(hSRS, &wkt);
60 OSRDestroySpatialReference(hSRS);
64 G_warning(_(
"GRASS is not compiled with OGR support"));
88 const struct Key_Value *proj_units,
89 int esri_style,
int prettify)
91 return grass_to_wkt(proj_info, proj_units,
NULL, esri_style, prettify);
119 const struct Key_Value *proj_units,
120 const struct Key_Value *proj_epsg,
121 int esri_style,
int prettify)
123 return grass_to_wkt(proj_info, proj_units, proj_epsg, esri_style, prettify);
137 const struct Key_Value * proj_units)
139 struct pj_info pjinfo;
140 char *proj4, *proj4mod, *wkt, *modwkt, *startmod, *lastpart;
141 OGRSpatialReferenceH hSRS, hSRS2;
143 struct gpj_datum dstruct;
144 struct gpj_ellps estruct;
146 const char *ellpskv, *unit, *unfact;
147 char *ellps, *ellpslong, *datum, *params, *towgs84, *datumlongname,
149 const char *sysname, *osrunit, *osrunfact;
153 if ((proj_info ==
NULL) || (proj_units ==
NULL))
156 hSRS = OSRNewSpatialReference(
NULL);
158 if (
pj_get_kv(&pjinfo, proj_info, proj_units) < 0) {
159 G_warning(_(
"Unable parse GRASS PROJ_INFO file"));
163 if ((proj4 = pj_get_def(pjinfo.pj, 0)) ==
NULL) {
164 G_warning(_(
"Unable get PROJ.4-style parameter string"));
171 if (unfact !=
NULL && (strcmp(pjinfo.proj,
"ll") != 0))
172 G_asprintf(&proj4mod,
"%s +to_meter=%s", proj4, unfact);
177 if ((errcode = OSRImportFromProj4(hSRS, proj4mod)) != OGRERR_NONE) {
178 G_warning(_(
"OGR can't parse PROJ.4-style parameter string: " 179 "%s (OGR Error code was %d)"), proj4mod, errcode);
190 if ((errcode = OSRExportToWkt(hSRS, &wkt)) != OGRERR_NONE) {
191 G_warning(_(
"OGR can't get WKT-style parameter string " 192 "(OGR Error code was %d)"), errcode);
206 datumlongname =
G_store(
"unknown");
211 datumlongname =
G_store(dstruct.longname);
213 ellps =
G_store(dstruct.ellps);
216 G_debug(3,
"GPJ_grass_to_osr: datum: <%s>", datum);
219 ellpslong =
G_store(estruct.longname);
220 DatumNameMassage(&ellpslong);
226 startmod = strstr(wkt,
"GEOGCS");
227 lastpart = strstr(wkt,
"PRIMEM");
228 len = strlen(wkt) - strlen(startmod);
230 if (haveparams == 2) {
233 char *paramkey, *paramvalue;
235 paramkey = strtok(params,
"=");
236 paramvalue = params + strlen(paramkey) + 1;
238 G_asprintf(&towgs84,
",TOWGS84[%s]", paramvalue);
246 sysname = OSRGetAttrValue(hSRS,
"PROJCS", 0);
247 if (sysname ==
NULL) {
253 if ((strcmp(sysname,
"unnamed") == 0) &&
260 osrunit = OSRGetAttrValue(hSRS,
"UNIT", 0);
261 osrunfact = OSRGetAttrValue(hSRS,
"UNIT", 1);
267 double unfactf = atof(unfact);
271 startmod = strstr(lastpart, buff);
272 len = strlen(lastpart) - strlen(startmod);
273 lastpart[len] =
'\0';
278 G_asprintf(&end,
",UNIT[\"%s\",%.16g]]", unit, unfactf);
282 OSRDestroySpatialReference(hSRS);
284 "%sGEOGCS[\"%s\",DATUM[\"%s\",SPHEROID[\"%s\",%.16g,%.16g]%s],%s%s",
285 start, ellps, datumlongname, ellpslong, a, rf, towgs84,
287 hSRS2 = OSRNewSpatialReference(modwkt);
321 const struct Key_Value * proj_units,
322 const struct Key_Value * proj_epsg)
329 epsgcode = atoi(epsgstr);
334 OGRSpatialReferenceH hSRS;
336 hSRS = OSRNewSpatialReference(
NULL);
338 OSRImportFromEPSG(hSRS, epsgcode);
345 double df[] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
350 df[i] = atof(tokens[i]);
353 OSRSetTOWGS84(hSRS, df[0], df[1], df[2], df[3], df[4], df[5], df[6]);
382 struct Key_Value **projunits, OGRSpatialReferenceH hSRS1,
385 struct Key_Value *temp_projinfo;
386 char *pszProj4 =
NULL, *pszRemaining;
387 char *pszProj =
NULL;
388 const char *pszProjCS =
NULL;
390 struct gpj_datum dstruct;
392 OGRSpatialReferenceH hSRS;
407 OSRMorphFromESRI(hSRS);
412 ograttr = OSRGetAttrValue(hSRS,
"EXTENSION", 0);
413 if (ograttr && *ograttr && strcmp(ograttr,
"PROJ4") == 0) {
414 ograttr = OSRGetAttrValue(hSRS,
"EXTENSION", 1);
415 G_debug(3,
"proj4 extension:");
418 if (ograttr && *ograttr) {
420 OGRSpatialReferenceH hSRS2;
422 hSRS2 = OSRNewSpatialReference(
NULL);
426 if (OSRImportFromProj4(hSRS2, proj4ext) != OGRERR_NONE) {
427 G_warning(_(
"Updating spatial reference with embedded proj4 definition failed. " 428 "Proj4 definition: <%s>"), proj4ext);
429 OSRDestroySpatialReference(hSRS2);
434 G_warning(_(
"Updating spatial reference with embedded proj4 definition"));
439 pszProjCS = OSRGetAttrValue(hSRS,
"PROJCS", 0);
441 pszProjCS = OSRGetAttrValue(hSRS,
"GEOGCS", 0);
452 sprintf(path,
"%s/etc/proj/projections",
G_gisbase());
470 if (!OSRIsGeographic(hSRS) && !OSRIsProjected(hSRS))
476 if (OSRIsGeographic(hSRS)) {
477 cellhd->proj = PROJECTION_LL;
480 else if (OSRGetUTMZone(hSRS, &bNorth) != 0) {
481 cellhd->proj = PROJECTION_UTM;
482 cellhd->zone = OSRGetUTMZone(hSRS, &bNorth);
487 cellhd->proj = PROJECTION_OTHER;
495 if (OSRExportToProj4(hSRS, &pszProj4) != OGRERR_NONE)
506 pszRemaining =
G_store(pszProj4);
508 pszProj4 = pszRemaining;
509 while ((pszRemaining = strstr(pszRemaining,
"+")) !=
NULL) {
510 char *pszToken, *pszValue;
515 pszToken = pszRemaining;
516 while (*pszRemaining !=
' ' && *pszRemaining !=
'\0')
519 if (*pszRemaining ==
' ') {
520 *pszRemaining =
'\0';
525 if (strstr(pszToken,
"=") !=
NULL) {
526 pszValue = strstr(pszToken,
"=");
531 pszValue =
"defined";
564 G_warning(_(
"No projection name! Projection parameters likely to be meaningless."));
570 pszProjCS = OSRGetAttrValue(hSRS,
"PROJCS", 0);
572 pszProjCS = OSRGetAttrValue(hSRS,
"GEOGCS", 0);
583 sprintf(path,
"%s/etc/proj/projections",
G_gisbase());
598 const char *pszDatumNameConst = OSRGetAttrValue(hSRS,
"DATUM", 0);
599 struct datum_list *
list, *listhead;
600 char *dum1, *dum2, *pszDatumName;
604 if (pszDatumNameConst) {
608 pszDatumName =
G_store(pszDatumNameConst);
609 DatumNameMassage(&pszDatumName);
610 G_debug(3,
"GPJ_osr_to_grass: pszDatumNameConst: <%s>", pszDatumName);
614 while (list !=
NULL) {
624 if (paramspresent < 2)
626 G_warning(_(
"Datum <%s> not recognised by GRASS and no parameters found"),
632 if (paramspresent < 2) {
635 char *params, *chosenparams =
NULL;
642 G_warning(_(
"Datum <%s> apparently recognised by GRASS but no parameters found. " 643 "You may want to look into this."), datum);
644 else if (datumtrans > paramsets) {
646 G_warning(_(
"Invalid transformation number %d; valid range is 1 to %d. " 647 "Leaving datum transform parameters unspecified."),
648 datumtrans, paramsets);
653 struct gpj_datum_transform_list *tlist, *old;
659 if (tlist->count == datumtrans)
660 chosenparams =
G_store(tlist->params);
664 }
while (tlist !=
NULL);
668 if (chosenparams !=
NULL) {
669 char *paramkey, *paramvalue;
671 paramkey = strtok(chosenparams,
"=");
672 paramvalue = chosenparams + strlen(paramkey) + 1;
700 const char *pszSemiMajor = OSRGetAttrValue(hSRS,
"SPHEROID", 1);
701 const char *pszInvFlat = OSRGetAttrValue(hSRS,
"SPHEROID", 2);
703 if (pszSemiMajor !=
NULL && pszInvFlat !=
NULL) {
705 struct ellps_list *
list, *listhead;
706 double a = atof(pszSemiMajor), invflat = atof(pszInvFlat), flat;
716 es = flat * (2.0 - flat);
720 while (list !=
NULL) {
725 if ((a == list->a || fabs(a - list->a) < 0.1 || fabs(1 - a / list->a) < 0.0000001) &&
726 ((es == 0 && list->es == 0) ||
728 (invflat == list->rf || fabs(invflat - list->rf) < 0.0000001))) {
734 if (listhead !=
NULL)
744 sprintf(es_str,
"%.16g", es);
764 for (i = 0; i < temp_projinfo->nitems; i++)
766 temp_projinfo->value[i], *projinfo);
778 if (OSRIsGeographic(hSRS)) {
785 char szFormatBuf[256];
786 char *pszUnitsName =
NULL;
788 char *pszUnitsPlural, *pszStringEnd;
790 dfToMeters = OSRGetLinearUnits(hSRS, &pszUnitsName);
806 pszUnitsPlural = G_malloc(strlen(pszUnitsName) + 3);
807 strcpy(pszUnitsPlural, pszUnitsName);
808 pszStringEnd = pszUnitsPlural + strlen(pszUnitsPlural) - 4;
811 pszStringEnd[1] =
'e';
812 pszStringEnd[2] =
'e';
816 pszStringEnd[4] =
'e';
817 pszStringEnd[5] =
's';
818 pszStringEnd[6] =
'\0';
822 pszStringEnd[4] =
's';
823 pszStringEnd[5] =
'\0';
829 sprintf(szFormatBuf,
"%.16g", dfToMeters);
835 OSRDestroySpatialReference(hSRS);
843 if (cellhd !=
NULL) {
844 cellhd->proj = PROJECTION_XY;
854 OSRDestroySpatialReference(hSRS);
881 struct Key_Value **projunits,
const char *wkt,
891 OGRSpatialReferenceH hSRS;
896 hSRS = OSRNewSpatialReference(wkt);
899 OSRDestroySpatialReference(hSRS);
915 static char *buf =
NULL;
949 static const char *papszDatumEquiv[] = {
950 "Militar_Geographische_Institute",
951 "Militar_Geographische_Institut",
952 "World_Geodetic_System_1984",
954 "World_Geodetic_System_1972",
956 "European_Terrestrial_Reference_System_89",
957 "European_Terrestrial_Reference_System_1989",
958 "European_Reference_System_1989",
959 "European_Terrestrial_Reference_System_1989",
961 "European_Terrestrial_Reference_System_1989",
963 "European_Terrestrial_Reference_System_1989",
965 "European_Terrestrial_Reference_System_1989",
967 "New_Zealand_Geodetic_Datum_2000",
972 "Campo_Inchauspe_1969",
975 "System_Jednotne_Trigonometricke_Site_Katastralni",
977 "Militar_Geographische_Institut",
979 "Deutsches_Hauptdreiecksnetz",
980 "South_American_1969",
981 "South_American_Datum_1969",
995 static void DatumNameMassage(
char **ppszDatum)
998 char *pszDatum = *ppszDatum;
1000 G_debug(3,
"DatumNameMassage: Raw string found <%s>", (
char *)pszDatum);
1004 for (i = 0; pszDatum[i] !=
'\0'; i++) {
1005 if (!(pszDatum[i] >=
'A' && pszDatum[i] <=
'Z')
1006 && !(pszDatum[i] >=
'a' && pszDatum[i] <=
'z')
1007 && !(pszDatum[i] >=
'0' && pszDatum[i] <=
'9')) {
1015 for (i = 1, j = 0; pszDatum[i] !=
'\0'; i++) {
1016 if (pszDatum[j] ==
'_' && pszDatum[i] ==
'_')
1019 pszDatum[++j] = pszDatum[i];
1021 if (pszDatum[j] ==
'_')
1024 pszDatum[j + 1] =
'\0';
1030 G_debug(3,
"DatumNameMassage: Search for datum equivalences of <%s>", (
char *)pszDatum);
1031 for (i = 0; papszDatumEquiv[i] !=
NULL; i += 2) {
1032 if (
EQUAL(*ppszDatum, papszDatumEquiv[i])) {
1034 *ppszDatum =
G_store(papszDatumEquiv[i + 1]);
int GPJ_wkt_to_grass(struct Cell_head *cellhd, struct Key_Value **projinfo, struct Key_Value **projunits, const char *wkt, int datumtrans)
Converts a WKT projection description to a GRASS co-ordinate system.
int G_strcasecmp(const char *x, const char *y)
String compare ignoring case (upper or lower)
const char * G_find_key_value(const char *key, const struct Key_Value *kv)
Find given key (case sensitive)
void GPJ_free_datum(struct gpj_datum *dstruct)
Free the memory used for the strings in a gpj_datum struct.
int GPJ__get_datum_params(const struct Key_Value *projinfo, char **datumname, char **params)
Extract the datum transformation-related parameters from a set of general PROJ_INFO parameters...
void GPJ_free_datum_transform(struct gpj_datum_transform_list *item)
Free the memory used by a gpj_datum_transform_list struct.
struct ellps_list * read_ellipsoid_table(int fatal)
char * GPJ_grass_to_wkt(const struct Key_Value *proj_info, const struct Key_Value *proj_units, int esri_style, int prettify)
Converts a GRASS co-ordinate system representation to WKT style.
char * G_store(const char *s)
Copy string to allocated memory.
int G_asprintf(char **out, const char *fmt,...)
char * GPJ_grass_to_wkt2(const struct Key_Value *proj_info, const struct Key_Value *proj_units, const struct Key_Value *proj_epsg, int esri_style, int prettify)
Converts a GRASS co-ordinate system representation to WKT style. EPSG code is preferred if available...
struct gpj_datum_transform_list * GPJ_get_datum_transform_by_name(const char *inputname)
Internal function to find all possible sets of transformation parameters for a particular datum...
int GPJ_get_datum_by_name(const char *name, struct gpj_datum *dstruct)
Look up a string in datum.table file to see if it is a valid datum name and if so place its informati...
void G_free_key_value(struct Key_Value *kv)
Free allocated Key_Value structure.
int GPJ__get_ellipsoid_params(const struct Key_Value *proj_keys, double *a, double *e2, double *rf)
Get the ellipsoid parameters from proj keys structure.
int G_lookup_key_value_from_file(const char *file, const char *key, char value[], int n)
Look up for key in file.
int G_number_of_tokens(char **tokens)
Return number of tokens.
void free_datum_list(struct datum_list *dstruct)
Free the memory used by a datum_list linked list structure.
const char * GPJ_set_csv_loc(const char *name)
int G_debug(int level, const char *msg,...)
Print debugging message.
void GPJ_free_ellps(struct gpj_ellps *estruct)
Free ellipsoid data structure.
OGRSpatialReferenceH GPJ_grass_to_osr(const struct Key_Value *proj_info, const struct Key_Value *proj_units)
Converts a GRASS co-ordinate system to an OGRSpatialReferenceH object.
OGRSpatialReferenceH GPJ_grass_to_osr2(const struct Key_Value *proj_info, const struct Key_Value *proj_units, const struct Key_Value *proj_epsg)
Converts a GRASS co-ordinate system to an OGRSpatialReferenceH object. EPSG code is preferred if avai...
void G_free_tokens(char **tokens)
Free memory allocated to tokens.
struct datum_list * read_datum_table(void)
Read the current GRASS datum.table from disk and store in memory.
int pj_get_kv(struct pj_info *info, const struct Key_Value *in_proj_keys, const struct Key_Value *in_units_keys)
Create a pj_info struct Co-ordinate System definition from a set of PROJ_INFO / PROJ_UNITS-style key-...
int GPJ_get_default_datum_params_by_name(const char *name, char **params)
"Last resort" function to retrieve a "default" set of datum parameters for a datum (N...
char ** G_tokenize(const char *buf, const char *delim)
Tokenize string.
void G_set_key_value(const char *key, const char *value, struct Key_Value *kv)
Set value for given key.
int GPJ_get_ellipsoid_by_name(const char *name, struct gpj_ellps *estruct)
Looks up ellipsoid in ellipsoid table and returns the a, e2 parameters for the ellipsoid.
void G_free(void *buf)
Free allocated memory.
int GPJ_osr_to_grass(struct Cell_head *cellhd, struct Key_Value **projinfo, struct Key_Value **projunits, OGRSpatialReferenceH hSRS1, int datumtrans)
Converts an OGRSpatialReferenceH object to a GRASS co-ordinate system.
const char * G_gisbase(void)
Get full path name of the top level module directory.
void G_warning(const char *msg,...)
Print a warning message to stderr.
struct Key_Value * G_create_key_value(void)
Allocate and initialize Key_Value structure.
void free_ellps_list(struct ellps_list *elist)