int set_datum(char *datum) { struct gpj_datum dstruct; struct Key_Value *temp_projinfo; int i; if (cellhd.proj == PROJECTION_XY) return 0; if (!datum || GPJ_get_datum_by_name(datum, &dstruct) < 0) { G_fatal_error(_("Invalid datum code <%s>"), datum); return 0; } temp_projinfo = G_create_key_value(); /* Copy old PROJ_INFO, skipping out any keys related * to datum or ellipsoid parameters */ for (i = 0; i < projinfo->nitems; i++) { if (strcmp(projinfo->key[i], "datum") == 0 || strcmp(projinfo->key[i], "dx") == 0 || strcmp(projinfo->key[i], "dy") == 0 || strcmp(projinfo->key[i], "dz") == 0 || strcmp(projinfo->key[i], "datumparams") == 0 || strcmp(projinfo->key[i], "nadgrids") == 0 || strcmp(projinfo->key[i], "towgs84") == 0 || strcmp(projinfo->key[i], "ellps") == 0 || strcmp(projinfo->key[i], "a") == 0 || strcmp(projinfo->key[i], "b") == 0 || strcmp(projinfo->key[i], "es") == 0 || strcmp(projinfo->key[i], "f") == 0 || strcmp(projinfo->key[i], "rf") == 0) continue; G_set_key_value(projinfo->key[i], projinfo->value[i], temp_projinfo); } /* Finally add datum and ellipsoid names */ G_set_key_value("datum", dstruct.name, temp_projinfo); G_message(_("Datum set to <%s>"), dstruct.name); G_set_key_value("ellps", dstruct.ellps, temp_projinfo); G_message(_("Ellipsoid set to <%s>"), dstruct.ellps); /* Destroy original key/value structure and replace with new one */ G_free_key_value(projinfo); projinfo = temp_projinfo; return 1; }
void print_datuminfo(void) { char *datum, *params; struct gpj_datum dstruct; int validdatum = 0; if (check_xy(FALSE)) return; GPJ__get_datum_params(projinfo, &datum, ¶ms); if (datum) validdatum = GPJ_get_datum_by_name(datum, &dstruct); if (validdatum > 0) fprintf(stdout, "GRASS datum code: %s\nWKT Name: %s\n", dstruct.name, dstruct.longname); else if (datum) fprintf(stdout, "Invalid datum code: %s\n", datum); else fprintf(stdout, "Datum name not present\n"); if (params) fprintf(stdout, "Datum transformation parameters (PROJ.4 format):\n" "\t%s\n", params); else if (validdatum > 0) { char *defparams; GPJ_get_default_datum_params_by_name(dstruct.name, &defparams); fprintf(stdout, "Datum parameters not present; default for %s is:\n" "\t%s\n", dstruct.name, defparams); G_free(defparams); } else fprintf(stdout, "Datum parameters not present\n"); if (validdatum > 0) GPJ_free_datum(&dstruct); return; }
struct gpj_datum_transform_list *GPJ_get_datum_transform_by_name(const char *inputname) { FILE *fd; char file[GPATH_MAX]; char buf[1024]; int line; struct gpj_datum_transform_list *current = NULL, *outputlist = NULL; struct gpj_datum dstruct; int count = 0; GPJ_get_datum_by_name(inputname, &dstruct); if (dstruct.dx < 99999 && dstruct.dy < 99999 && dstruct.dz < 99999) { /* Include the old-style dx dy dz parameters from datum.table at the * start of the list, unless these have been set to all 99999 to * indicate only entries in datumtransform.table should be used */ if (current == NULL) current = outputlist = G_malloc(sizeof(struct gpj_datum_transform_list)); else current = current->next = G_malloc(sizeof(struct gpj_datum_transform_list)); G_asprintf(&(current->params), "towgs84=%.3f,%.3f,%.3f", dstruct.dx, dstruct.dy, dstruct.dz); G_asprintf(&(current->where_used), "whole %s region", inputname); G_asprintf(&(current->comment), "Default 3-Parameter Transformation (May not be optimum for " "older datums; use this only if no more appropriate options " "are available.)"); count++; current->count = count; current->next = NULL; } GPJ_free_datum(&dstruct); /* Now check for additional parameters in datumtransform.table */ sprintf(file, "%s%s", G_gisbase(), DATUMTRANSFORMTABLE); fd = fopen(file, "r"); if (!fd) { G_warning(_("Unable to open datum table file <%s>"), file); return outputlist; } for (line = 1; G_getl2(buf, sizeof(buf), fd); line++) { char name[100], params[1024], where_used[1024], comment[1024]; G_strip(buf); if (*buf == '\0' || *buf == '#') continue; if (sscanf(buf, "%99s \"%1023[^\"]\" \"%1023[^\"]\" \"%1023[^\"]\"", name, params, where_used, comment) != 4) { G_warning(_("Error in datum table file <%s>, line %d"), file, line); continue; } if (G_strcasecmp(inputname, name) == 0) { /* If the datum name in this line matches the one we are * looking for, add an entry to the linked list */ if (current == NULL) current = outputlist = G_malloc(sizeof(struct gpj_datum_transform_list)); else current = current->next = G_malloc(sizeof(struct gpj_datum_transform_list)); current->params = G_store(params); current->where_used = G_store(where_used); current->comment = G_store(comment); count++; current->count = count; current->next = NULL; } } fclose(fd); return outputlist; }
int set_datumtrans(int datumtrans, int force) { char *params, *datum = NULL; int paramsets, status; if (cellhd.proj == PROJECTION_XY) return 0; status = GPJ__get_datum_params(projinfo, &datum, ¶ms); G_debug(3, "set_datumtrans(): GPJ__get_datum_params() status=%d", status); G_free(params); if (datum) { /* A datum name is specified; need to determine if * there are parameters to choose from for this datum */ struct gpj_datum dstruct; if (GPJ_get_datum_by_name(datum, &dstruct) > 0) { char *defparams; paramsets = GPJ_get_default_datum_params_by_name(dstruct.name, &defparams); G_free(defparams); GPJ_free_datum(&dstruct); G_debug(3, "set_datumtrans(): datum transform terms found " "with %d options", paramsets); if (status == 1 && paramsets > 1) /* Parameters are missing and there is a choice to be made */ force = 1; } else { /* Datum name not found in table; can't do anything. */ G_debug(3, "set_datumtrans(): Datum name not found in table."); force = 0; } } else { /* No datum name; can't do anything. */ G_debug(3, "set_datumtrans(): Datum name either invalid or not supplied."); force = 0; } if (force) { char *chosenparams = NULL; char *paramkey, *paramvalue; struct Key_Value *temp_projinfo; int i; /* First of all obtain the new parameters * through the supplied transform number index */ { struct gpj_datum_transform_list *list; if (datumtrans > paramsets) G_fatal_error ("Invalid transformation number %d; valid range is 1 to %d", datumtrans, paramsets); G_debug(3, "set_datumtrans(): looking up available datum " "transforms for <%s>", datum); list = GPJ_get_datum_transform_by_name(datum); if (list != NULL) { if (datumtrans == -1) { do { struct gpj_datum_transform_list *old = list; fprintf(stdout, "---\n%d\nUsed in %s\n%s\n%s\n", list->count, list->where_used, list->params, list->comment); list = list->next; GPJ_free_datum_transform(old); } while (list != NULL); exit(EXIT_SUCCESS); } else { do { struct gpj_datum_transform_list *old = list; if (list->count == datumtrans) chosenparams = G_store(list->params); list = list->next; GPJ_free_datum_transform(old); } while (list != NULL); } } } temp_projinfo = G_create_key_value(); /* Copy old PROJ_INFO, skipping out any keys related * to datum parameters */ for (i = 0; i < projinfo->nitems; i++) { if (strcmp(projinfo->key[i], "dx") == 0 || strcmp(projinfo->key[i], "dy") == 0 || strcmp(projinfo->key[i], "dz") == 0 || strcmp(projinfo->key[i], "datumparams") == 0 || strcmp(projinfo->key[i], "nadgrids") == 0 || strcmp(projinfo->key[i], "towgs84") == 0) continue; G_set_key_value(projinfo->key[i], projinfo->value[i], temp_projinfo); } /* Finally add new parameters (if we have them) */ if (chosenparams != NULL) { /* Now split 'chosenparams' into key/value format */ paramkey = strtok(chosenparams, "="); paramvalue = chosenparams + strlen(paramkey) + 1; G_set_key_value(paramkey, paramvalue, temp_projinfo); G_free(chosenparams); } /* Destroy original key/value structure and replace with new one */ G_free_key_value(projinfo); projinfo = temp_projinfo; } G_free(datum); return force; }
OGRSpatialReferenceH GPJ_grass_to_osr(struct Key_Value * proj_info, struct Key_Value * proj_units) { struct pj_info pjinfo; char *proj4, *proj4mod, *wkt, *modwkt, *startmod, *lastpart; OGRSpatialReferenceH hSRS, hSRS2; OGRErr errcode; struct gpj_datum dstruct; struct gpj_ellps estruct; size_t len; const char *ellpskv, *unit, *unfact; char *ellps, *ellpslong, *datum, *params, *towgs84, *datumlongname, *start, *end; const char *sysname, *osrunit, *osrunfact; double a, es, rf; int haveparams = 0; if ((proj_info == NULL) || (proj_units == NULL)) return NULL; hSRS = OSRNewSpatialReference(NULL); if (pj_get_kv(&pjinfo, proj_info, proj_units) < 0) { G_warning(_("Unable parse GRASS PROJ_INFO file")); return NULL; } if ((proj4 = pj_get_def(pjinfo.pj, 0)) == NULL) { G_warning(_("Unable get PROJ.4-style parameter string")); return NULL; } pj_free(pjinfo.pj); unit = G_find_key_value("unit", proj_units); unfact = G_find_key_value("meters", proj_units); if (unfact != NULL && (strcmp(pjinfo.proj, "ll") != 0)) G_asprintf(&proj4mod, "%s +to_meter=%s", proj4, unfact); else proj4mod = G_store(proj4); pj_dalloc(proj4); if ((errcode = OSRImportFromProj4(hSRS, proj4mod)) != OGRERR_NONE) { G_warning(_("OGR can't parse PROJ.4-style parameter string: " "%s (OGR Error code was %d)"), proj4mod, errcode); return NULL; } G_free(proj4mod); if ((errcode = OSRExportToWkt(hSRS, &wkt)) != OGRERR_NONE) { G_warning(_("OGR can't get WKT-style parameter string " "(OGR Error code was %d)"), errcode); return NULL; } ellpskv = G_find_key_value("ellps", proj_info); GPJ__get_ellipsoid_params(proj_info, &a, &es, &rf); haveparams = GPJ__get_datum_params(proj_info, &datum, ¶ms); if(ellpskv != NULL) ellps = G_store(ellpskv); else ellps = NULL; if ((datum == NULL) || (GPJ_get_datum_by_name(datum, &dstruct) < 0)) { datumlongname = G_store("unknown"); if (ellps == NULL) ellps = G_store("unnamed"); } else { datumlongname = G_store(dstruct.longname); if (ellps == NULL) ellps = G_store(dstruct.ellps); GPJ_free_datum(&dstruct); } G_free(datum); if (GPJ_get_ellipsoid_by_name(ellps, &estruct) > 0) { ellpslong = G_store(estruct.longname); DatumNameMassage(&ellpslong); GPJ_free_ellps(&estruct); } else ellpslong = G_store(ellps); startmod = strstr(wkt, "GEOGCS"); lastpart = strstr(wkt, "PRIMEM"); len = strlen(wkt) - strlen(startmod); wkt[len] = '\0'; if (haveparams == 2) { /* Only put datum params into the WKT if they were specifically * specified in PROJ_INFO */ char *paramkey, *paramvalue; paramkey = strtok(params, "="); paramvalue = params + strlen(paramkey) + 1; if (G_strcasecmp(paramkey, "towgs84") == 0) G_asprintf(&towgs84, ",TOWGS84[%s]", paramvalue); else towgs84 = G_store(""); G_free(params); } else towgs84 = G_store(""); sysname = OSRGetAttrValue(hSRS, "PROJCS", 0); if (sysname == NULL) { /* Not a projected co-ordinate system */ start = G_store(""); end = G_store(""); } else { if ((strcmp(sysname, "unnamed") == 0) && (G_find_key_value("name", proj_info) != NULL)) G_asprintf(&start, "PROJCS[\"%s\",", G_find_key_value("name", proj_info)); else start = G_store(wkt); osrunit = OSRGetAttrValue(hSRS, "UNIT", 0); osrunfact = OSRGetAttrValue(hSRS, "UNIT", 1); if ((unfact == NULL) || (G_strcasecmp(osrunit, "unknown") != 0)) end = G_store(""); else { char *buff; double unfactf = atof(unfact); G_asprintf(&buff, ",UNIT[\"%s\",", osrunit); startmod = strstr(lastpart, buff); len = strlen(lastpart) - strlen(startmod); lastpart[len] = '\0'; G_free(buff); if (unit == NULL) unit = "unknown"; G_asprintf(&end, ",UNIT[\"%s\",%.16g]]", unit, unfactf); } } OSRDestroySpatialReference(hSRS); G_asprintf(&modwkt, "%sGEOGCS[\"%s\",DATUM[\"%s\",SPHEROID[\"%s\",%.16g,%.16g]%s],%s%s", start, ellps, datumlongname, ellpslong, a, rf, towgs84, lastpart, end); hSRS2 = OSRNewSpatialReference(modwkt); G_free(modwkt); CPLFree(wkt); G_free(start); G_free(ellps); G_free(datumlongname); G_free(ellpslong); G_free(towgs84); G_free(end); return hSRS2; }
int GPJ_osr_to_grass(struct Cell_head *cellhd, struct Key_Value **projinfo, struct Key_Value **projunits, OGRSpatialReferenceH hSRS, int datumtrans) { struct Key_Value *temp_projinfo; char *pszProj4 = NULL, *pszRemaining; char *pszProj = NULL; char *datum = NULL; struct gpj_datum dstruct; if (hSRS == NULL) goto default_to_xy; /* Set finder function for locating OGR csv co-ordinate system tables */ SetCSVFilenameHook(GPJ_set_csv_loc); /* Hopefully this doesn't do any harm if it wasn't in ESRI format * to start with... */ OSRMorphFromESRI(hSRS); /* -------------------------------------------------------------------- */ /* Set cellhd for well known coordinate systems. */ /* -------------------------------------------------------------------- */ if (!OSRIsGeographic(hSRS) && !OSRIsProjected(hSRS)) goto default_to_xy; if (cellhd) { int bNorth; if (OSRIsGeographic(hSRS)) { cellhd->proj = PROJECTION_LL; cellhd->zone = 0; } else if (OSRGetUTMZone(hSRS, &bNorth) != 0) { cellhd->proj = PROJECTION_UTM; cellhd->zone = OSRGetUTMZone(hSRS, &bNorth); if (!bNorth) cellhd->zone *= -1; } else { cellhd->proj = PROJECTION_OTHER; cellhd->zone = 0; } } /* -------------------------------------------------------------------- */ /* Get the coordinate system definition in PROJ.4 format. */ /* -------------------------------------------------------------------- */ if (OSRExportToProj4(hSRS, &pszProj4) != OGRERR_NONE) goto default_to_xy; /* -------------------------------------------------------------------- */ /* Parse the PROJ.4 string into key/value pairs. Do a bit of */ /* extra work to "GRASSify" the result. */ /* -------------------------------------------------------------------- */ temp_projinfo = G_create_key_value(); /* Create "local" copy of proj4 string so we can modify and free it * using GRASS functions */ pszRemaining = G_store(pszProj4); CPLFree(pszProj4); pszProj4 = pszRemaining; while ((pszRemaining = strstr(pszRemaining, "+")) != NULL) { char *pszToken, *pszValue; pszRemaining++; /* Advance pszRemaining to end of this token[=value] pair */ pszToken = pszRemaining; while (*pszRemaining != ' ' && *pszRemaining != '\0') pszRemaining++; if (*pszRemaining == ' ') { *pszRemaining = '\0'; pszRemaining++; } /* parse token, and value */ if (strstr(pszToken, "=") != NULL) { pszValue = strstr(pszToken, "="); *pszValue = '\0'; pszValue++; } else pszValue = "defined"; if (G_strcasecmp(pszToken, "proj") == 0) { /* The ll projection is known as longlat in PROJ.4 */ if (G_strcasecmp(pszValue, "longlat") == 0) pszValue = "ll"; pszProj = pszValue; continue; } /* Ellipsoid and datum handled separately below */ if (G_strcasecmp(pszToken, "ellps") == 0 || G_strcasecmp(pszToken, "a") == 0 || G_strcasecmp(pszToken, "b") == 0 || G_strcasecmp(pszToken, "es") == 0 || G_strcasecmp(pszToken, "rf") == 0 || G_strcasecmp(pszToken, "datum") == 0) continue; /* We will handle units separately */ if (G_strcasecmp(pszToken, "to_meter") == 0 || G_strcasecmp(pszToken, "units") == 0) continue; G_set_key_value(pszToken, pszValue, temp_projinfo); } *projinfo = G_create_key_value(); /* -------------------------------------------------------------------- */ /* Derive the user name for the projection. */ /* -------------------------------------------------------------------- */ if (pszProj) { char path[4095]; char name[80]; sprintf(path, "%s/etc/projections", G_gisbase()); if (G_lookup_key_value_from_file(path, pszProj, name, sizeof(name)) > 0) G_set_key_value("name", name, *projinfo); else G_set_key_value("name", pszProj, *projinfo); G_set_key_value("proj", pszProj, *projinfo); } else G_warning(_("No projection name! Projection parameters likely to be meaningless.")); /* -------------------------------------------------------------------- */ /* Find the GRASS datum name and choose parameters either */ /* interactively or not. */ /* -------------------------------------------------------------------- */ { const char *pszDatumNameConst = OSRGetAttrValue(hSRS, "DATUM", 0); struct datum_list *list, *listhead; char *dum1, *dum2, *pszDatumName; int paramspresent = GPJ__get_datum_params(temp_projinfo, &dum1, &dum2); if (pszDatumNameConst) { /* Need to make a new copy of the string so we don't mess * around with the memory inside the OGRSpatialReferenceH? */ pszDatumName = G_store(pszDatumNameConst); DatumNameMassage(&pszDatumName); list = listhead = read_datum_table(); while (list != NULL) { if (G_strcasecmp(pszDatumName, list->longname) == 0) { datum = G_store(list->name); break; } list = list->next; } free_datum_list(listhead); if (datum == NULL) { if (paramspresent < 2) /* Only give warning if no parameters present */ G_warning(_("Datum <%s> not recognised by GRASS and no parameters found"), pszDatumName); } else { G_set_key_value("datum", datum, *projinfo); if (paramspresent < 2) { /* If no datum parameters were imported from the OSR * object then we should use the set specified by datumtrans */ char *params, *chosenparams = NULL; int paramsets; paramsets = GPJ_get_default_datum_params_by_name(datum, ¶ms); if (paramsets < 0) G_warning(_("Datum <%s> apparently recognised by GRASS but no parameters found. " "You may want to look into this."), datum); else if (datumtrans > paramsets) { G_warning(_("Invalid transformation number %d; valid range is 1 to %d. " "Leaving datum transform parameters unspecified."), datumtrans, paramsets); datumtrans = 0; } if (paramsets > 0) { struct gpj_datum_transform_list *list, *old; list = GPJ_get_datum_transform_by_name(datum); if (list != NULL) { do { if (list->count == datumtrans) chosenparams = G_store(list->params); old = list; list = list->next; GPJ_free_datum_transform(old); } while (list != NULL); } } if (chosenparams != NULL) { char *paramkey, *paramvalue; paramkey = strtok(chosenparams, "="); paramvalue = chosenparams + strlen(paramkey) + 1; G_set_key_value(paramkey, paramvalue, *projinfo); G_free(chosenparams); } if (paramsets > 0) G_free(params); } } G_free(pszDatumName); } } /* -------------------------------------------------------------------- */ /* Determine an appropriate GRASS ellipsoid name if possible, or */ /* else just put a and es values into PROJ_INFO */ /* -------------------------------------------------------------------- */ if ((datum != NULL) && (GPJ_get_datum_by_name(datum, &dstruct) > 0)) { /* Use ellps name associated with datum */ G_set_key_value("ellps", dstruct.ellps, *projinfo); GPJ_free_datum(&dstruct); G_free(datum); } else { /* If we can't determine the ellipsoid from the datum, derive it * directly from "SPHEROID" parameters in WKT */ const char *pszSemiMajor = OSRGetAttrValue(hSRS, "SPHEROID", 1); const char *pszInvFlat = OSRGetAttrValue(hSRS, "SPHEROID", 2); if (pszSemiMajor != NULL && pszInvFlat != NULL) { char *ellps = NULL; struct ellps_list *list, *listhead; double a = atof(pszSemiMajor), invflat = atof(pszInvFlat), flat; double es; /* Allow for incorrect WKT describing a sphere where InvFlat * is given as 0 rather than inf */ if (invflat > 0) flat = 1 / invflat; else flat = 0; es = flat * (2.0 - flat); list = listhead = read_ellipsoid_table(0); while (list != NULL) { /* Try and match a and es against GRASS defined ellipsoids; * accept first one that matches. These numbers were found * by trial and error and could be fine-tuned, or possibly * a direct comparison of IEEE floating point values used. */ if ((a == list->a || fabs(a - list->a) < 0.1 || fabs(1 - a / list->a) < 0.0000001) && ((es == 0 && list->es == 0) || /* Special case for sphere */ (invflat == list->rf || fabs(invflat - list->rf) < 0.0000001))) { ellps = G_store(list->name); break; } list = list->next; } if (listhead != NULL) free_ellps_list(listhead); if (ellps == NULL) { /* If we weren't able to find a matching ellps name, set * a and es values directly from WKT-derived data */ char es_str[100]; G_set_key_value("a", (char *)pszSemiMajor, *projinfo); sprintf(es_str, "%.16g", es); G_set_key_value("es", es_str, *projinfo); } else { /* else specify the GRASS ellps name for readability */ G_set_key_value("ellps", ellps, *projinfo); G_free(ellps); } } } /* -------------------------------------------------------------------- */ /* Finally append the detailed projection parameters to the end */ /* -------------------------------------------------------------------- */ { int i; for (i = 0; i < temp_projinfo->nitems; i++) G_set_key_value(temp_projinfo->key[i], temp_projinfo->value[i], *projinfo); G_free_key_value(temp_projinfo); } G_free(pszProj4); /* -------------------------------------------------------------------- */ /* Set the linear units. */ /* -------------------------------------------------------------------- */ *projunits = G_create_key_value(); if (OSRIsGeographic(hSRS)) { /* We assume degrees ... someday we will be wrong! */ G_set_key_value("unit", "degree", *projunits); G_set_key_value("units", "degrees", *projunits); G_set_key_value("meters", "1.0", *projunits); } else { char szFormatBuf[256]; char *pszUnitsName = NULL; double dfToMeters; char *pszUnitsPlural, *pszStringEnd; dfToMeters = OSRGetLinearUnits(hSRS, &pszUnitsName); /* Workaround for the most obvious case when unit name is unknown */ if ((G_strcasecmp(pszUnitsName, "unknown") == 0) && (dfToMeters == 1.)) G_asprintf(&pszUnitsName, "meter"); G_set_key_value("unit", pszUnitsName, *projunits); /* Attempt at plural formation (WKT format doesn't store plural * form of unit name) */ pszUnitsPlural = G_malloc(strlen(pszUnitsName) + 3); strcpy(pszUnitsPlural, pszUnitsName); pszStringEnd = pszUnitsPlural + strlen(pszUnitsPlural) - 4; if (G_strcasecmp(pszStringEnd, "foot") == 0) { /* Special case for foot - change two o's to e's */ pszStringEnd[1] = 'e'; pszStringEnd[2] = 'e'; } else if (G_strcasecmp(pszStringEnd, "inch") == 0) { /* Special case for inch - add es */ pszStringEnd[4] = 'e'; pszStringEnd[5] = 's'; pszStringEnd[6] = '\0'; } else { /* For anything else add an s at the end */ pszStringEnd[4] = 's'; pszStringEnd[5] = '\0'; } G_set_key_value("units", pszUnitsPlural, *projunits); G_free(pszUnitsPlural); sprintf(szFormatBuf, "%.16g", dfToMeters); G_set_key_value("meters", szFormatBuf, *projunits); } return 2; /* -------------------------------------------------------------------- */ /* Fallback to returning an ungeoreferenced definition. */ /* -------------------------------------------------------------------- */ default_to_xy: if (cellhd != NULL) { cellhd->proj = PROJECTION_XY; cellhd->zone = 0; } *projinfo = NULL; *projunits = NULL; return 1; }
int GPJ__get_ellipsoid_params(const struct Key_Value *proj_keys, double *a, double *e2, double *rf) { struct gpj_ellps estruct; struct gpj_datum dstruct; const char *str, *str3; char *str1, *ellps; str = G_find_key_value("datum", proj_keys); if ((str != NULL) && (GPJ_get_datum_by_name(str, &dstruct) > 0)) { /* If 'datum' key is present, look up correct ellipsoid * from datum.table */ ellps = G_store(dstruct.ellps); GPJ_free_datum(&dstruct); } else /* else use ellipsoid defined in PROJ_INFO */ ellps = G_store(G_find_key_value("ellps", proj_keys)); if (ellps != NULL && *ellps) { if (GPJ_get_ellipsoid_by_name(ellps, &estruct) < 0) G_fatal_error(_("Invalid ellipsoid <%s> in file"), ellps); *a = estruct.a; *e2 = estruct.es; *rf = estruct.rf; GPJ_free_ellps(&estruct); G_free(ellps); return 1; } else { if (ellps) /* *ellps = '\0' */ G_free(ellps); str3 = G_find_key_value("a", proj_keys); if (str3 != NULL) { char *str4; G_asprintf(&str4, "a=%s", str3); if ((str3 = G_find_key_value("es", proj_keys)) != NULL) G_asprintf(&str1, "e=%s", str3); else if ((str3 = G_find_key_value("f", proj_keys)) != NULL) G_asprintf(&str1, "f=1/%s", str3); else if ((str3 = G_find_key_value("rf", proj_keys)) != NULL) G_asprintf(&str1, "f=1/%s", str3); else if ((str3 = G_find_key_value("b", proj_keys)) != NULL) G_asprintf(&str1, "b=%s", str3); else G_fatal_error(_("No secondary ellipsoid descriptor " "(rf, es or b) in file")); if (get_a_e2_rf(str4, str1, a, e2, rf) == 0) G_fatal_error(_("Invalid ellipsoid descriptors " "(a, rf, es or b) in file")); return 1; } else { str = G_find_key_value("proj", proj_keys); if ((str == NULL) || (strcmp(str, "ll") == 0)) { *a = 6378137.0; *e2 = .006694385; *rf = 298.257223563; return 0; } else { G_fatal_error(_("No ellipsoid info given in file")); } } } return 1; }