GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
convert.c
Go to the documentation of this file.
1 
16 #include <grass/config.h>
17 
18 #ifdef HAVE_OGR
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <math.h>
23 #include <grass/gis.h>
24 #include <grass/gprojects.h>
25 #include <grass/glocale.h>
26 #include <cpl_csv.h>
27 #include "local_proto.h"
28 
29 /* GRASS relative location of OGR co-ordinate system lookup tables */
30 #define CSVDIR "/etc/ogr_csv"
31 
32 static void DatumNameMassage(char **);
33 
52 char *GPJ_grass_to_wkt(struct Key_Value *proj_info,
53  struct Key_Value *proj_units,
54  int esri_style, int prettify)
55 {
56  OGRSpatialReferenceH hSRS;
57  char *wkt, *local_wkt;
58 
59  hSRS = GPJ_grass_to_osr(proj_info, proj_units);
60 
61  if (hSRS == NULL)
62  return NULL;
63 
64  if (esri_style)
65  OSRMorphToESRI(hSRS);
66 
67  if (prettify)
68  OSRExportToPrettyWkt(hSRS, &wkt, 0);
69  else
70  OSRExportToWkt(hSRS, &wkt);
71 
72  local_wkt = G_store(wkt);
73  CPLFree(wkt);
74  OSRDestroySpatialReference(hSRS);
75  return local_wkt;
76 }
77 
88 OGRSpatialReferenceH GPJ_grass_to_osr(struct Key_Value * proj_info,
89  struct Key_Value * proj_units)
90 {
91  struct pj_info pjinfo;
92  char *proj4, *proj4mod, *wkt, *modwkt, *startmod, *lastpart;
93  OGRSpatialReferenceH hSRS, hSRS2;
94  OGRErr errcode;
95  struct gpj_datum dstruct;
96  struct gpj_ellps estruct;
97  size_t len;
98  char *ellps, *ellpslong, *datum, *params, *towgs84, *datumlongname,
99  *start, *end, *unit, *unfact, *buff;
100  const char *sysname, *osrunit, *osrunfact;
101  double a, es, rf;
102  int haveparams = 0;
103 
104  if ((proj_info == NULL) || (proj_units == NULL))
105  return NULL;
106 
107  hSRS = OSRNewSpatialReference(NULL);
108 
109  if (pj_get_kv(&pjinfo, proj_info, proj_units) < 0) {
110  G_warning(_("Unable parse GRASS PROJ_INFO file"));
111  return NULL;
112  }
113 
114  if ((proj4 = pj_get_def(pjinfo.pj, 0)) == NULL) {
115  G_warning(_("Unable get PROJ.4-style parameter string"));
116  return NULL;
117  }
118 
119  unit = G_find_key_value("unit", proj_units);
120  unfact = G_find_key_value("meters", proj_units);
121  if (unfact != NULL && (strcmp(pjinfo.proj, "ll") != 0))
122  G_asprintf(&proj4mod, "%s +to_meter=%s", proj4, unfact);
123  else
124  proj4mod = proj4;
125 
126  if ((errcode = OSRImportFromProj4(hSRS, proj4mod)) != OGRERR_NONE) {
127  G_warning(_("OGR can't parse PROJ.4-style parameter string: "
128  "%s (OGR Error code was %d)"), proj4mod, errcode);
129  return NULL;
130  }
131 
132  if ((errcode = OSRExportToWkt(hSRS, &wkt)) != OGRERR_NONE) {
133  G_warning(_("OGR can't get WKT-style parameter string "
134  "(OGR Error code was %d)"), errcode);
135  return NULL;
136  }
137 
138  ellps = G_find_key_value("ellps", proj_info);
139  GPJ__get_ellipsoid_params(proj_info, &a, &es, &rf);
140  haveparams = GPJ__get_datum_params(proj_info, &datum, &params);
141 
142  if ((datum == NULL) || (GPJ_get_datum_by_name(datum, &dstruct) < 0)) {
143  G_asprintf(&datumlongname, "unknown");
144  if (ellps == NULL)
145  G_asprintf(&ellps, "unnamed");
146  }
147  else {
148  datumlongname = G_store(dstruct.longname);
149  if (ellps == NULL)
150  ellps = G_store(dstruct.ellps);
151  GPJ_free_datum(&dstruct);
152  }
153  if (GPJ_get_ellipsoid_by_name(ellps, &estruct) > 0) {
154  ellpslong = G_store(estruct.longname);
155  DatumNameMassage(&ellpslong);
156  GPJ_free_ellps(&estruct);
157  }
158  else
159  ellpslong = G_store(ellps);
160 
161  startmod = G_strstr(wkt, "GEOGCS");
162  lastpart = G_strstr(wkt, "PRIMEM");
163  len = strlen(wkt) - strlen(startmod);
164  wkt[len] = '\0';
165  if (haveparams == 2) {
166  /* Only put datum params into the WKT if they were specifically
167  * specified in PROJ_INFO */
168  char *paramkey, *paramvalue;
169 
170  paramkey = strtok(params, "=");
171  paramvalue = params + strlen(paramkey) + 1;
172  if (G_strcasecmp(paramkey, "towgs84") == 0)
173  G_asprintf(&towgs84, ",TOWGS84[%s]", paramvalue);
174  else
175  towgs84 = "";
176  }
177  else
178  towgs84 = "";
179 
180  sysname = OSRGetAttrValue(hSRS, "PROJCS", 0);
181  if (sysname == NULL) {
182  /* Not a projected co-ordinate system */
183  start = "";
184  end = "";
185  }
186  else {
187  if ((strcmp(sysname, "unnamed") == 0) &&
188  (G_find_key_value("name", proj_info) != NULL))
189  G_asprintf(&start, "PROJCS[\"%s\",",
190  G_find_key_value("name", proj_info));
191  else
192  start = G_store(wkt);
193 
194  osrunit = OSRGetAttrValue(hSRS, "UNIT", 0);
195  osrunfact = OSRGetAttrValue(hSRS, "UNIT", 1);
196 
197  if ((unfact == NULL) || (G_strcasecmp(osrunit, "unknown") != 0))
198  end = "";
199  else {
200  double unfactf = atof(unfact);
201 
202  G_asprintf(&buff, ",UNIT[\"%s\",", osrunit);
203 
204  startmod = G_strstr(lastpart, buff);
205  len = strlen(lastpart) - strlen(startmod);
206  lastpart[len] = '\0';
207 
208  if (unit == NULL)
209  G_asprintf(&unit, "unknown");
210  G_asprintf(&end, ",UNIT[\"%s\",%.16g]]", unit, unfactf);
211  }
212 
213  }
214 
215  G_asprintf(&modwkt,
216  "%sGEOGCS[\"%s\",DATUM[\"%s\",SPHEROID[\"%s\",%.16g,%.16g]%s],%s%s",
217  start, ellps, datumlongname, ellpslong, a, rf, towgs84,
218  lastpart, end);
219 
220  hSRS2 = OSRNewSpatialReference(modwkt);
221 
222  OSRDestroySpatialReference(hSRS);
223  G_free(modwkt);
224  CPLFree(wkt);
225  pj_dalloc(proj4);
226  if (proj4 != proj4mod)
227  G_free(proj4mod);
228  G_free(datum);
229  G_free(params);
230  G_free(datumlongname);
231  pj_free(pjinfo.pj);
232  G_free(ellpslong);
233  /* Other string pointers may or may not need to be freed depending
234  * on sequence of execution so just leave them. */
235 
236  return hSRS2;
237 }
238 
258 int GPJ_osr_to_grass(struct Cell_head *cellhd, struct Key_Value **projinfo,
259  struct Key_Value **projunits, OGRSpatialReferenceH hSRS,
260  int datumtrans)
261 {
262  struct Key_Value *temp_projinfo;
263  char *pszProj4 = NULL, *pszRemaining;
264  char *pszProj = NULL;
265  char *datum = NULL;
266  struct gpj_datum dstruct;
267 
268  if (hSRS == NULL)
269  goto default_to_xy;
270 
271  /* Set finder function for locating OGR csv co-ordinate system tables */
272  SetCSVFilenameHook(GPJ_set_csv_loc);
273 
274  /* Hopefully this doesn't do any harm if it wasn't in ESRI format
275  * to start with... */
276  OSRMorphFromESRI(hSRS);
277 
278  /* -------------------------------------------------------------------- */
279  /* Set cellhd for well known coordinate systems. */
280  /* -------------------------------------------------------------------- */
281  if (!OSRIsGeographic(hSRS) && !OSRIsProjected(hSRS))
282  goto default_to_xy;
283 
284  if (cellhd) {
285  int bNorth;
286 
287  if (OSRIsGeographic(hSRS)) {
288  cellhd->proj = PROJECTION_LL;
289  cellhd->zone = 0;
290  }
291  else if (OSRGetUTMZone(hSRS, &bNorth) != 0) {
292  cellhd->proj = PROJECTION_UTM;
293  cellhd->zone = OSRGetUTMZone(hSRS, &bNorth);
294  if (!bNorth)
295  cellhd->zone *= -1;
296  }
297  else {
298  cellhd->proj = PROJECTION_OTHER;
299  cellhd->zone = 0;
300  }
301  }
302 
303  /* -------------------------------------------------------------------- */
304  /* Get the coordinate system definition in PROJ.4 format. */
305  /* -------------------------------------------------------------------- */
306  if (OSRExportToProj4(hSRS, &pszProj4) != OGRERR_NONE)
307  goto default_to_xy;
308 
309  /* -------------------------------------------------------------------- */
310  /* Parse the PROJ.4 string into key/value pairs. Do a bit of */
311  /* extra work to "GRASSify" the result. */
312  /* -------------------------------------------------------------------- */
313  temp_projinfo = G_create_key_value();
314 
315  /* Create "local" copy of proj4 string so we can modify and free it
316  * using GRASS functions */
317  pszRemaining = G_store(pszProj4);
318  CPLFree(pszProj4);
319  pszProj4 = pszRemaining;
320  while ((pszRemaining = strstr(pszRemaining, "+")) != NULL) {
321  char *pszToken, *pszValue;
322 
323  pszRemaining++;
324 
325  /* Advance pszRemaining to end of this token[=value] pair */
326  pszToken = pszRemaining;
327  while (*pszRemaining != ' ' && *pszRemaining != '\0')
328  pszRemaining++;
329 
330  if (*pszRemaining == ' ') {
331  *pszRemaining = '\0';
332  pszRemaining++;
333  }
334 
335  /* parse token, and value */
336  if (strstr(pszToken, "=") != NULL) {
337  pszValue = strstr(pszToken, "=");
338  *pszValue = '\0';
339  pszValue++;
340  }
341  else
342  pszValue = "defined";
343 
344 
345  if (G_strcasecmp(pszToken, "proj") == 0) {
346  /* The ll projection is known as longlat in PROJ.4 */
347  if (G_strcasecmp(pszValue, "longlat") == 0)
348  pszValue = "ll";
349 
350  pszProj = pszValue;
351  continue;
352  }
353 
354  /* Ellipsoid and datum handled separately below */
355  if (G_strcasecmp(pszToken, "ellps") == 0
356  || G_strcasecmp(pszToken, "a") == 0
357  || G_strcasecmp(pszToken, "b") == 0
358  || G_strcasecmp(pszToken, "es") == 0
359  || G_strcasecmp(pszToken, "rf") == 0
360  || G_strcasecmp(pszToken, "datum") == 0)
361  continue;
362 
363  /* We will handle units separately */
364  if (G_strcasecmp(pszToken, "to_meter") == 0
365  || G_strcasecmp(pszToken, "units") == 0)
366  continue;
367 
368  G_set_key_value(pszToken, pszValue, temp_projinfo);
369  }
370 
371  *projinfo = G_create_key_value();
372 
373  /* -------------------------------------------------------------------- */
374  /* Derive the user name for the projection. */
375  /* -------------------------------------------------------------------- */
376  if (pszProj) {
377  char path[4095];
378  char name[80];
379 
380  sprintf(path, "%s/etc/projections", G_gisbase());
381  if (G_lookup_key_value_from_file(path, pszProj, name, sizeof(name)) >
382  0)
383  G_set_key_value("name", name, *projinfo);
384  else
385  G_set_key_value("name", pszProj, *projinfo);
386 
387  G_set_key_value("proj", pszProj, *projinfo);
388  }
389  else
390  G_warning(_("No projection name! Projection parameters likely to be meaningless."));
391 
392 
393  /* -------------------------------------------------------------------- */
394  /* Find the GRASS datum name and choose parameters either */
395  /* interactively or not. */
396  /* -------------------------------------------------------------------- */
397 
398  {
399  const char *pszDatumNameConst = OSRGetAttrValue(hSRS, "DATUM", 0);
400  struct datum_list *list, *listhead;
401  char *dum1, *dum2, *pszDatumName;
402  int paramspresent =
403  GPJ__get_datum_params(temp_projinfo, &dum1, &dum2);
404 
405  if (pszDatumNameConst) {
406  /* Need to make a new copy of the string so we don't mess
407  * around with the memory inside the OGRSpatialReferenceH? */
408 
409  pszDatumName = G_store(pszDatumNameConst);
410  DatumNameMassage(&pszDatumName);
411 
412  list = listhead = read_datum_table();
413 
414  while (list != NULL) {
415  if (G_strcasecmp(pszDatumName, list->longname) == 0) {
416  datum = G_store(list->name);
417  break;
418  }
419  list = list->next;
420  }
421  free_datum_list(listhead);
422 
423  if (datum == NULL) {
424  if (paramspresent < 2)
425  /* Only give warning if no parameters present */
426  G_warning(_("Datum <%s> not recognised by GRASS and no parameters found"),
427  pszDatumName);
428  }
429  else {
430  G_set_key_value("datum", datum, *projinfo);
431 
432  if (paramspresent < 2) {
433  /* If no datum parameters were imported from the OSR
434  * object then we should use the set specified by datumtrans */
435  char *params, *chosenparams = NULL;
436  int paramsets;
437 
438  paramsets =
439  GPJ_get_default_datum_params_by_name(datum, &params);
440 
441  if (paramsets < 0)
442  G_warning(_("Datum <%s> apparently recognised by GRASS but no parameters found. "
443  "You may want to look into this."), datum);
444  else if (datumtrans > paramsets) {
445 
446  G_warning(_("Invalid transformation number %d; valid range is 1 to %d. "
447  "Leaving datum transform parameters unspecified."),
448  datumtrans, paramsets);
449  datumtrans = 0;
450  }
451 
452  if (paramsets > 0) {
453  struct gpj_datum_transform_list *list, *old;
454 
455  list = GPJ_get_datum_transform_by_name(datum);
456 
457  if (list != NULL) {
458  do {
459  if (list->count == datumtrans) {
460  chosenparams = G_store(list->params);
461  break;
462  }
463  old = list;
464  list = list->next;
465  G_free(old);
466  } while (list != NULL);
467  }
468  }
469 
470  if (chosenparams != NULL) {
471  char *paramkey, *paramvalue;
472 
473  paramkey = strtok(chosenparams, "=");
474  paramvalue = chosenparams + strlen(paramkey) + 1;
475  G_set_key_value(paramkey, paramvalue, *projinfo);
476  G_free(chosenparams);
477  }
478 
479  if (paramsets > 0)
480  G_free(params);
481  }
482 
483  }
484  }
485  }
486 
487  /* -------------------------------------------------------------------- */
488  /* Determine an appropriate GRASS ellipsoid name if possible, or */
489  /* else just put a and es values into PROJ_INFO */
490  /* -------------------------------------------------------------------- */
491 
492  if ((datum != NULL) && (GPJ_get_datum_by_name(datum, &dstruct) > 0)) {
493  /* Use ellps name associated with datum */
494  G_set_key_value("ellps", dstruct.ellps, *projinfo);
495  GPJ_free_datum(&dstruct);
496  G_free(datum);
497  }
498  else {
499  /* If we can't determine the ellipsoid from the datum, derive it
500  * directly from "SPHEROID" parameters in WKT */
501  const char *pszSemiMajor = OSRGetAttrValue(hSRS, "SPHEROID", 1);
502  const char *pszInvFlat = OSRGetAttrValue(hSRS, "SPHEROID", 2);
503 
504  if (pszSemiMajor != NULL && pszInvFlat != NULL) {
505  char *ellps = NULL;
506  struct ellps_list *list, *listhead;
507  double a = atof(pszSemiMajor), invflat = atof(pszInvFlat), flat;
508  double es;
509 
510  /* Allow for incorrect WKT describing a sphere where InvFlat
511  * is given as 0 rather than inf */
512  if (invflat > 0)
513  flat = 1 / invflat;
514  else
515  flat = 0;
516 
517  es = flat * (2.0 - flat);
518 
519  list = listhead = read_ellipsoid_table(0);
520 
521  while (list != NULL) {
522  /* Try and match a and es against GRASS defined ellipsoids;
523  * accept first one that matches. These numbers were found
524  * by trial and error and could be fine-tuned, or possibly
525  * a direct comparison of IEEE floating point values used. */
526  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 */
527  (invflat == list->rf || fabs(invflat - list->rf) < 0.0000001))) {
528  ellps = G_store(list->name);
529  break;
530  }
531  list = list->next;
532  }
533  if (listhead != NULL)
534  free_ellps_list(listhead);
535 
536  if (ellps == NULL) {
537  /* If we weren't able to find a matching ellps name, set
538  * a and es values directly from WKT-derived data */
539  char es_str[100];
540 
541  G_set_key_value("a", (char *)pszSemiMajor, *projinfo);
542 
543  sprintf(es_str, "%.16g", es);
544  G_set_key_value("es", es_str, *projinfo);
545  }
546  else {
547  /* else specify the GRASS ellps name for readability */
548  G_set_key_value("ellps", ellps, *projinfo);
549  G_free(ellps);
550  }
551 
552  }
553 
554  }
555 
556  /* -------------------------------------------------------------------- */
557  /* Finally append the detailed projection parameters to the end */
558  /* -------------------------------------------------------------------- */
559 
560  {
561  int i;
562 
563  for (i = 0; i < temp_projinfo->nitems; i++)
564  G_set_key_value(temp_projinfo->key[i],
565  temp_projinfo->value[i], *projinfo);
566 
567  G_free_key_value(temp_projinfo);
568  }
569 
570  G_free(pszProj4);
571 
572  /* -------------------------------------------------------------------- */
573  /* Set the linear units. */
574  /* -------------------------------------------------------------------- */
575  *projunits = G_create_key_value();
576 
577  if (OSRIsGeographic(hSRS)) {
578  /* We assume degrees ... someday we will be wrong! */
579  G_set_key_value("unit", "degree", *projunits);
580  G_set_key_value("units", "degrees", *projunits);
581  G_set_key_value("meters", "1.0", *projunits);
582  }
583  else {
584  char szFormatBuf[256];
585  char *pszUnitsName = NULL;
586  double dfToMeters;
587  char *pszUnitsPlural, *pszStringEnd;
588 
589  dfToMeters = OSRGetLinearUnits(hSRS, &pszUnitsName);
590 
591  /* Workaround for the most obvious case when unit name is unknown */
592  if ((G_strcasecmp(pszUnitsName, "unknown") == 0) &&
593  (dfToMeters == 1.))
594  G_asprintf(&pszUnitsName, "meter");
595 
596  G_set_key_value("unit", pszUnitsName, *projunits);
597 
598  /* Attempt at plural formation (WKT format doesn't store plural
599  * form of unit name) */
600  pszUnitsPlural = G_malloc(strlen(pszUnitsName) + 3);
601  strcpy(pszUnitsPlural, pszUnitsName);
602  pszStringEnd = pszUnitsPlural + strlen(pszUnitsPlural) - 4;
603  if (G_strcasecmp(pszStringEnd, "foot") == 0) {
604  /* Special case for foot - change two o's to e's */
605  pszStringEnd[1] = 'e';
606  pszStringEnd[2] = 'e';
607  }
608  else if (G_strcasecmp(pszStringEnd, "inch") == 0) {
609  /* Special case for inch - add es */
610  pszStringEnd[4] = 'e';
611  pszStringEnd[5] = 's';
612  pszStringEnd[6] = '\0';
613  }
614  else {
615  /* For anything else add an s at the end */
616  pszStringEnd[4] = 's';
617  pszStringEnd[5] = '\0';
618  }
619 
620  G_set_key_value("units", pszUnitsPlural, *projunits);
621  G_free(pszUnitsPlural);
622 
623  sprintf(szFormatBuf, "%.16g", dfToMeters);
624  G_set_key_value("meters", szFormatBuf, *projunits);
625 
626  }
627 
628  return 2;
629 
630  /* -------------------------------------------------------------------- */
631  /* Fallback to returning an ungeoreferenced definition. */
632  /* -------------------------------------------------------------------- */
633  default_to_xy:
634  if (cellhd != NULL) {
635  cellhd->proj = PROJECTION_XY;
636  cellhd->zone = 0;
637  }
638 
639  *projinfo = NULL;
640  *projunits = NULL;
641 
642  return 1;
643 }
644 
645 
665 int GPJ_wkt_to_grass(struct Cell_head *cellhd, struct Key_Value **projinfo,
666  struct Key_Value **projunits, const char *wkt,
667  int datumtrans)
668 {
669  int retval;
670 
671  if (wkt == NULL)
672  retval =
673  GPJ_osr_to_grass(cellhd, projinfo, projunits, NULL, datumtrans);
674  else {
675  OGRSpatialReferenceH hSRS;
676 
677  /* Set finder function for locating OGR csv co-ordinate system tables */
678  SetCSVFilenameHook(GPJ_set_csv_loc);
679 
680  hSRS = OSRNewSpatialReference(wkt);
681  retval =
682  GPJ_osr_to_grass(cellhd, projinfo, projunits, hSRS, datumtrans);
683  OSRDestroySpatialReference(hSRS);
684  }
685 
686  return retval;
687 }
688 
689 
690 /* GPJ_set_csv_loc()
691  * 'finder function' for use with OGR SetCSVFilenameHook() function */
692 
693 const char *GPJ_set_csv_loc(const char *name)
694 {
695  const char *gisbase = G_gisbase();
696  static char *buf = NULL;
697 
698  if (buf != NULL)
699  G_free(buf);
700 
701  G_asprintf(&buf, "%s%s/%s", gisbase, CSVDIR, name);
702 
703  return buf;
704 }
705 
706 
707 /* The list below is only for files that use a non-standard name for a
708  * datum that is already supported in GRASS. The number of entries must be even;
709  * they are all in pairs. The first one in the pair is the non-standard name;
710  * the second is the GRASS name. If a name appears more than once (as for
711  * European_Terrestrial_Reference_System_1989) then it means there was more
712  * than one non-standard name for it that needs to be accounted for.
713  *
714  * N.B. The order of these pairs is different from that in
715  * ogr/ogrfromepsg.cpp in the GDAL source tree! GRASS uses the EPSG
716  * names in its WKT representation except WGS_1984 and WGS_1972 as
717  * these shortened versions seem to be standard
718  */
719 
720 static const char *papszDatumEquiv[] = {
721  "Militar_Geographische_Institute",
722  "Militar_Geographische_Institut",
723  "World_Geodetic_System_1984",
724  "WGS_1984",
725  "World_Geodetic_System_1972",
726  "WGS_1972",
727  "European_Terrestrial_Reference_System_89",
728  "European_Terrestrial_Reference_System_1989",
729  "European_Reference_System_1989",
730  "European_Terrestrial_Reference_System_1989",
731  "ETRS_1989",
732  "European_Terrestrial_Reference_System_1989",
733  "ETRS89",
734  "European_Terrestrial_Reference_System_1989",
735  "ETRF_1989",
736  "European_Terrestrial_Reference_System_1989",
737  "NZGD_2000",
738  "New_Zealand_Geodetic_Datum_2000",
739  "Monte_Mario_Rome",
740  "Monte_Mario",
741  "MONTROME",
742  "Monte_Mario",
743  "Campo_Inchauspe_1969",
744  "Campo_Inchauspe",
745  "S_JTSK_Ferro",
746  "Militar_Geographische_Institut",
747  "Potsdam_Datum_83",
748  "Deutsches_Hauptdreiecksnetz",
749  "South_American_1969",
750  "South_American_Datum_1969",
751  "ITRF_1992",
752  "ITRF92",
753  NULL
754 };
755 
756 /************************************************************************/
757 /* OGREPSGDatumNameMassage() */
758 /* */
759 /* Massage an EPSG datum name into WMT format. Also transform */
760 /* specific exception cases into WKT versions. */
761 
762 /************************************************************************/
763 
764 static void DatumNameMassage(char **ppszDatum)
765 {
766  int i, j;
767  char *pszDatum = *ppszDatum;
768 
769  /* -------------------------------------------------------------------- */
770  /* Translate non-alphanumeric values to underscores. */
771  /* -------------------------------------------------------------------- */
772  for (i = 0; pszDatum[i] != '\0'; i++) {
773  if (!(pszDatum[i] >= 'A' && pszDatum[i] <= 'Z')
774  && !(pszDatum[i] >= 'a' && pszDatum[i] <= 'z')
775  && !(pszDatum[i] >= '0' && pszDatum[i] <= '9')) {
776  pszDatum[i] = '_';
777  }
778  }
779 
780  /* -------------------------------------------------------------------- */
781  /* Remove repeated and trailing underscores. */
782  /* -------------------------------------------------------------------- */
783  for (i = 1, j = 0; pszDatum[i] != '\0'; i++) {
784  if (pszDatum[j] == '_' && pszDatum[i] == '_')
785  continue;
786 
787  pszDatum[++j] = pszDatum[i];
788  }
789  if (pszDatum[j] == '_')
790  pszDatum[j] = '\0';
791  else
792  pszDatum[j + 1] = '\0';
793 
794  /* -------------------------------------------------------------------- */
795  /* Search for datum equivalences. Specific massaged names get */
796  /* mapped to OpenGIS specified names. */
797  /* -------------------------------------------------------------------- */
798  for (i = 0; papszDatumEquiv[i] != NULL; i += 2) {
799  if (EQUAL(*ppszDatum, papszDatumEquiv[i])) {
800  G_free(*ppszDatum);
801  *ppszDatum = G_store(papszDatumEquiv[i + 1]);
802  break;
803  }
804  }
805 }
806 
807 #endif /* HAVE_OGR */
char * G_find_key_value(const char *key, const struct Key_Value *kv)
Find given key.
Definition: key_value1.c:128
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.
Definition: convert.c:665
int G_strcasecmp(const char *x, const char *y)
String compare ignoring case (upper or lower)
Definition: strings.c:192
sprintf(buf2,"%s", G3D_CATS_ELEMENT)
void G_free(void *buf)
Free allocated memory.
Definition: gis/alloc.c:142
int pj_get_kv(struct pj_info *info, struct Key_Value *in_proj_keys, 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-...
Definition: get_proj.c:61
void GPJ_free_datum(struct gpj_datum *dstruct)
Free the memory used for the strings in a gpj_datum struct.
Definition: proj/datum.c:543
char * G_store(const char *s)
Copy string to allocated memory.
Definition: store.c:32
string name
Definition: render.py:1314
struct ellps_list * read_ellipsoid_table(int fatal)
Definition: ellipse.c:196
int GPJ_osr_to_grass(struct Cell_head *cellhd, struct Key_Value **projinfo, struct Key_Value **projunits, OGRSpatialReferenceH hSRS, int datumtrans)
Converts an OGRSpatialReferenceH object to a GRASS co-ordinate system.
Definition: convert.c:258
int G_free_key_value(struct Key_Value *kv)
Free allocated Key_Value structure.
Definition: key_value1.c:145
int G_asprintf(char **out, const char *fmt,...)
Definition: asprintf.c:116
#define EQUAL
Definition: y.tab.c:159
char * GPJ_grass_to_wkt(struct Key_Value *proj_info, struct Key_Value *proj_units, int esri_style, int prettify)
Converts a GRASS co-ordinate system representation to WKT style.
Definition: convert.c:52
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...
Definition: proj/datum.c:377
tuple gisbase
Definition: forms.py:59
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...
Definition: proj/datum.c:37
int G_lookup_key_value_from_file(const char *file, const char *key, char value[], int n)
Look up for key in file.
Definition: key_value4.c:64
char buff[1024]
Definition: g3dcats.c:89
OGRSpatialReferenceH GPJ_grass_to_osr(struct Key_Value *proj_info, struct Key_Value *proj_units)
Converts a GRASS co-ordinate system to an OGRSpatialReferenceH object.
Definition: convert.c:88
int GPJ__get_ellipsoid_params(struct Key_Value *proj_keys, double *a, double *e2, double *rf)
Definition: ellipse.c:52
void free_datum_list(struct datum_list *dstruct)
Free the memory used by a datum_list linked list structure.
Definition: proj/datum.c:557
#define CSVDIR
Definition: convert.c:30
const char * GPJ_set_csv_loc(const char *name)
Definition: convert.c:693
void GPJ_free_ellps(struct gpj_ellps *estruct)
Definition: ellipse.c:275
tuple unit
struct datum_list * read_datum_table(void)
Read the current GRASS datum.table from disk and store in memory.
Definition: proj/datum.c:485
char buf[GNAME_MAX+sizeof(G3D_DIRECTORY)+2]
Definition: g3drange.c:62
return NULL
Definition: dbfopen.c:1394
int GPJ__get_datum_params(struct Key_Value *projinfo, char **datumname, char **params)
Extract the datum transformation-related parameters from a set of general PROJ_INFO parameters...
Definition: proj/datum.c:173
G_warning("category support for [%s] in mapset [%s] %s", name, mapset, type)
char * G_strstr(const char *mainString, const char *subString)
Finds the first occurrence of the character C in the null-terminated string beginning at mainString...
Definition: strings.c:230
int GPJ_get_default_datum_params_by_name(const char *name, char **params)
&quot;Last resort&quot; function to retrieve a &quot;default&quot; set of datum parameters for a datum (N...
Definition: proj/datum.c:85
struct datum_list * next
char * G_gisbase(void)
top level module directory
Definition: gisbase.c:42
int old
Definition: g3dcats.c:92
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 ...
Definition: ellipse.c:131
int G_set_key_value(const char *key, const char *value, struct Key_Value *kv)
Set value for given key.
Definition: key_value1.c:55
struct Key_Value * G_create_key_value(void)
Allocate and initialize Key_Value structure.
Definition: key_value1.c:25
void free_ellps_list(struct ellps_list *elist)
Definition: ellipse.c:282