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__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; }