SAGA API  v9.5
projections.cpp
Go to the documentation of this file.
1 
3 // //
4 // SAGA //
5 // //
6 // System for Automated Geoscientific Analyses //
7 // //
8 // Application Programming Interface //
9 // //
10 // Library: SAGA_API //
11 // //
12 //-------------------------------------------------------//
13 // //
14 // projections.cpp //
15 // //
16 // Copyright (C) 2009 by Olaf Conrad //
17 // //
18 //-------------------------------------------------------//
19 // //
20 // This file is part of 'SAGA - System for Automated //
21 // Geoscientific Analyses'. //
22 // //
23 // This library is free software; you can redistribute //
24 // it and/or modify it under the terms of the GNU Lesser //
25 // General Public License as published by the Free //
26 // Software Foundation, either version 2.1 of the //
27 // License, or (at your option) any later version. //
28 // //
29 // This library is distributed in the hope that it will //
30 // be useful, but WITHOUT ANY WARRANTY; without even the //
31 // implied warranty of MERCHANTABILITY or FITNESS FOR A //
32 // PARTICULAR PURPOSE. See the GNU Lesser General Public //
33 // License for more details. //
34 // //
35 // You should have received a copy of the GNU Lesser //
36 // General Public License along with this program; if //
37 // not, see <http://www.gnu.org/licenses/>. //
38 // //
39 //-------------------------------------------------------//
40 // //
41 // contact: Olaf Conrad //
42 // Institute of Geography //
43 // University of Hamburg //
44 // Germany //
45 // //
46 // e-mail: oconrad@saga-gis.org //
47 // //
49 
50 //---------------------------------------------------------
51 #include "geo_tools.h"
52 
53 #include "table.h"
54 #include "shapes.h"
55 #include "data_manager.h"
56 #include "tool_library.h"
57 
58 
60 // //
61 // //
62 // //
64 
65 //---------------------------------------------------------
67 
68 //---------------------------------------------------------
70 {
71  return( gSG_Projections );
72 }
73 
74 
76 // //
77 // //
78 // //
80 
81 //---------------------------------------------------------
83 {
84  Destroy();
85 }
86 
88 {}
89 
90 //---------------------------------------------------------
92 {
93  Create(Projection);
94 }
95 
96 bool CSG_Projection::Create(const CSG_Projection &Projection)
97 {
98  m_Name = Projection.m_Name;
99  m_Type = Projection.m_Type;
100  m_Unit = Projection.m_Unit;
101 
102  m_WKT1 = Projection.m_WKT1;
103  m_WKT2 = Projection.m_WKT2;
104  m_PROJ = Projection.m_PROJ;
105  m_ESRI = Projection.m_ESRI;
106  m_Authority = Projection.m_Authority;
107  m_Code = Projection.m_Code;
108 
109  return( true );
110 }
111 
112 //---------------------------------------------------------
113 CSG_Projection::CSG_Projection(const char *Definition)
114 {
115  Create(Definition);
116 }
117 
118 bool CSG_Projection::Create(const char *Definition)
119 {
120  if( Definition && *Definition)
121  {
122  return( Create(CSG_String(Definition)) );
123  }
124 
125  Destroy();
126 
127  return( false );
128 }
129 
130 //---------------------------------------------------------
131 CSG_Projection::CSG_Projection(const wchar_t *Definition)
132 {
133  Create(Definition);
134 }
135 
136 bool CSG_Projection::Create(const wchar_t *Definition)
137 {
138  if( Definition && *Definition )
139  {
140  return( Create(CSG_String(Definition)) );
141  }
142 
143  Destroy();
144 
145  return( false );
146 }
147 
148 //---------------------------------------------------------
150 {
151  Create(Definition);
152 }
153 
154 bool CSG_Projection::Create(const CSG_String &Definition)
155 {
156  Destroy();
157 
158  if( CSG_Projections::Parse(Definition, &m_WKT1, &m_WKT2, &m_PROJ, &m_ESRI) )
159  {
160  CSG_MetaData WKT(CSG_Projections::_WKT_to_MetaData(m_WKT1));
161 
162  m_Type = CSG_Projections::Get_CRS_Type(WKT.Get_Name());
163 
164  m_Name = WKT.Get_Property("name");
165 
166  if( WKT("UNIT") && WKT["UNIT"].Get_Property("name") )
167  {
168  m_Unit = CSG_Projections::Get_Unit(WKT["UNIT"].Get_Property("name"));
169  }
170 
171  CSG_String Authority; int Code;
172 
173  if( WKT.Get_Property("authority_name", Authority) && WKT.Get_Property("authority_code", Code) )
174  {
175  m_Authority = Authority; m_Code = Code;
176  }
177 
178  return( true );
179  }
180 
181  return( false );
182 }
183 
184 //---------------------------------------------------------
185 CSG_Projection::CSG_Projection(int Code, const SG_Char *Authority)
186 {
187  Create(Code, Authority);
188 }
189 
190 bool CSG_Projection::Create(int Code, const SG_Char *Authority)
191 {
192  if( Create(CSG_String::Format("%s:%d", Authority && *Authority ? Authority : SG_T("EPSG"), Code)) )
193  {
194  return( true );
195  }
196 
197  return( Create(gSG_Projections.Get_Projection(Code, Authority)) ); // request SAGA's internal CRS database (might provide definitions not included in PROJ's default database)
198 }
199 
200 //---------------------------------------------------------
202 {
203  m_Name = _TL("undefined");
204  m_Type = ESG_CRS_Type::Undefined;
205  m_Unit = ESG_Projection_Unit::Undefined;
206 
207  m_WKT1 .Clear();
208  m_WKT2 .Clear();
209  m_PROJ .Clear();
210  m_ESRI .Clear();
211  m_Authority .Clear();
212  m_Code = -1;
213 }
214 
215 
217 // //
219 
220 //---------------------------------------------------------
221 bool CSG_Projection::Load(const CSG_String &FileName)
222 {
223  CSG_File Stream(FileName, SG_FILE_R, false);
224 
225  return( Load(Stream) );
226 }
227 
228 //---------------------------------------------------------
229 bool CSG_Projection::Save(const CSG_String &FileName, ESG_CRS_Format Format) const
230 {
231  CSG_File Stream(FileName, SG_FILE_W, false);
232 
233  return( is_Okay() && Save(Stream, Format) );
234 }
235 
236 //---------------------------------------------------------
238 {
239  if( Stream.is_Reading() )
240  {
241  CSG_String s; Stream.Read(s, (size_t)Stream.Length());
242 
243  return( Create(s) );
244  }
245 
246  return( false );
247 }
248 
249 //---------------------------------------------------------
250 bool CSG_Projection::Save(CSG_File &Stream, ESG_CRS_Format Format) const
251 {
252  if( is_Okay() && Stream.is_Writing() )
253  {
254  switch( Format )
255  {
256  default:
257  case ESG_CRS_Format::WKT1: return( !m_WKT1.is_Empty() && Stream.Write(m_WKT1) == m_WKT1.Length() );
258  case ESG_CRS_Format::WKT2: return( !m_WKT2.is_Empty() && Stream.Write(m_WKT2) == m_WKT2.Length() );
259  case ESG_CRS_Format::PROJ: return( !m_PROJ.is_Empty() && Stream.Write(m_PROJ) == m_PROJ.Length() );
260  case ESG_CRS_Format::ESRI: return( !m_ESRI.is_Empty() && Stream.Write(m_ESRI) == m_ESRI.Length() );
261  case ESG_CRS_Format::CODE: return( !m_Authority.is_Empty() && m_Code > 0 && Stream.Printf("%s:%d", m_Authority.c_str(), m_Code) );
262  }
263  }
264 
265  return( false );
266 }
267 
268 //---------------------------------------------------------
269 bool CSG_Projection::Load(const CSG_MetaData &Projection)
270 {
271  if( Projection("WKT1") ) { return( Create(Projection["WKT1"].Get_Content()) ); }
272  if( Projection("PROJ") ) { return( Create(Projection["PROJ"].Get_Content()) ); }
273 
274  //-----------------------------------------------------
275  // >>> backward compatibilty
276 
277  if( Projection("OGC_WKT") ) { return( Create(Projection["OGC_WKT"].Get_Content()) ); }
278  if( Projection("PROJ4" ) ) { return( Create(Projection["PROJ4" ].Get_Content()) ); }
279 
280  // <<< backward compatibilty
281  //-----------------------------------------------------
282 
283  return( false );
284 }
285 
286 //---------------------------------------------------------
287 bool CSG_Projection::Save(CSG_MetaData &Projection) const
288 {
289  Projection.Del_Children();
290 
291  Projection.Add_Child("WKT1", m_WKT1);
292  Projection.Add_Child("PROJ", m_PROJ);
293  Projection.Add_Child("CODE", m_Code)->Add_Property("authority", m_Authority);
294 
295  return( true );
296 }
297 
298 
300 // //
302 
303 //---------------------------------------------------------
305 {
306  if( !is_Okay() )
307  {
308  return( _TL("Unknown Spatial Reference") );
309  }
310 
311  CSG_MetaData WKT(CSG_Projections::_WKT_to_MetaData(m_WKT1)), *pGCS = NULL;
312 
313  if( !bDetails )
314  {
315  CSG_String s;
316 
317  if( !m_Name.is_Empty() && m_Name.CmpNoCase("unknown") )
318  {
319  s = m_Name;
320  }
321  else if( WKT("PROJECTION") )
322  {
323  s.Printf("%s [%s]", WKT.Get_Content("PROJECTION"), _TL("user defined")); s.Replace("_", " ");
324  }
325  else
326  {
327  s.Printf("[%s]", _TL("user defined"));
328  }
329 
330  if( m_Code > 0 && !m_Authority.is_Empty() )
331  {
332  s += CSG_String::Format(" [%s:%d]", m_Authority.c_str(), m_Code);
333  }
334 
335  return( s );
336  }
337 
338  //-----------------------------------------------------
339  #define ADD_HEAD(name, value) { CSG_String n(name), v(value); n.Replace("_", " "); v.Replace("_", " "); s += CSG_String::Format("<tr><th>%s</th><th>%s</th></tr>", n.c_str(), v.c_str()); }
340  #define ADD_INFO(name, value) { CSG_String n(name), v(value); n.Replace("_", " "); v.Replace("_", " "); s += CSG_String::Format("<tr><td>%s</td><td>%s</td></tr>", n.c_str(), v.c_str()); }
341  #define ADD_CONT(name, entry) if( entry ) { ADD_INFO(name, entry->Get_Content() ); }
342  #define ADD_PROP(name, entry, prop) if( entry && entry->Get_Property(prop) ) { ADD_INFO(name, entry->Get_Property(prop)); }
343 
344  CSG_String s = "<table border=\"1\">";
345 
346  if( is_Projection() )
347  {
348  ADD_HEAD(_TL("Projected Coordinate System" ), WKT.Get_Property("name") && !WKT.Cmp_Property("name", "unknown", true) ? WKT.Get_Property("name") : SG_T(""));
349  ADD_CONT(_TL("Projection" ), WKT("PROJECTION"));
350  if( m_Code > 0 && !m_Authority.is_Empty() )
351  {
352  ADD_INFO(_TL("Authority Code" ), CSG_String::Format("%d", m_Code) );
353  ADD_INFO(_TL("Authority" ), m_Authority);
354  }
355  ADD_PROP(_TL("Linear Unit" ), WKT("UNIT"), "name");
356 
357  for(int i=0; i<WKT.Get_Children_Count(); i++)
358  {
359  if( WKT[i].Cmp_Name("PARAMETER") )
360  {
361  CSG_String Name(WKT[i].Get_Property("name")); Name.Replace("_", " ");
362  ADD_INFO(Name.c_str(), WKT[i].Get_Content().c_str());
363  }
364  }
365 
366  pGCS = WKT("GEOGCS");
367  }
368  else if( is_Geographic() )
369  {
370  pGCS = &WKT;
371  }
372 
373  if( pGCS && pGCS->Cmp_Name("GEOGCS") )
374  {
375  ADD_HEAD(_TL("Geographic Coordinate System"), pGCS->Get_Property("name") && !pGCS->Cmp_Property("name", "unknown", true) ? pGCS->Get_Property("name") : _TL(""));
376  ADD_PROP(_TL("Authority Code" ), pGCS, "authority_code");
377  ADD_PROP(_TL("Authority" ), pGCS, "authority_name");
378  ADD_PROP(_TL("Prime Meridian" ), (*pGCS)("PRIMEM" ), "name");
379  ADD_PROP(_TL("Angular Unit" ), (*pGCS)("UNIT" ), "name");
380  ADD_PROP(_TL("Datum" ), (*pGCS)("DATUM" ), "name");
381  ADD_PROP(_TL("Spheroid" ), (*pGCS)("DATUM.SPHEROID"), "name");
382  ADD_CONT(_TL("Semimajor Axis" ), (*pGCS)("DATUM.SPHEROID.a" ));
383  ADD_CONT(_TL("Inverse Flattening" ), (*pGCS)("DATUM.SPHEROID.rf"));
384  ADD_CONT(_TL("Extension" ), (*pGCS)("DATUM.EXTENSION"));
385 
386  ADD_CONT(CSG_String::Format("%s, %s [X]", _TL("Datum Shift"), _TL("Translation")), (*pGCS)("DATUM.TOWGS84.dx"));
387  ADD_CONT(CSG_String::Format("%s, %s [Y]", _TL("Datum Shift"), _TL("Translation")), (*pGCS)("DATUM.TOWGS84.dy"));
388  ADD_CONT(CSG_String::Format("%s, %s [Z]", _TL("Datum Shift"), _TL("Translation")), (*pGCS)("DATUM.TOWGS84.dz"));
389  ADD_CONT(CSG_String::Format("%s, %s [X]", _TL("Datum Shift"), _TL("Rotation" )), (*pGCS)("DATUM.TOWGS84.rx"));
390  ADD_CONT(CSG_String::Format("%s, %s [Y]", _TL("Datum Shift"), _TL("Rotation" )), (*pGCS)("DATUM.TOWGS84.ry"));
391  ADD_CONT(CSG_String::Format("%s, %s [Z]", _TL("Datum Shift"), _TL("Rotation" )), (*pGCS)("DATUM.TOWGS84.rz"));
392  ADD_CONT(CSG_String::Format("%s, %s [X]", _TL("Datum Shift"), _TL("Scaling" )), (*pGCS)("DATUM.TOWGS84.sc"));
393  }
394 
395  s += "</table>";
396 
397 // if( m_WKT1.Length() > 0 ) { s += "\n[" + m_WKT1 + "]"; }
398 // if( m_PROJ.Length() > 0 ) { s += "\n[" + m_PROJ + "]"; }
399 
400  return( s );
401 }
402 
403 
405 // //
407 
408 //---------------------------------------------------------
409 bool CSG_Projection::is_Equal(const CSG_Projection &Projection) const
410 {
411  if( Get_Type() != Projection.Get_Type() )
412  {
413  return( false );
414  }
415 
416  if( !is_Okay() ) // both are not valid => ESG_CRS_Type::Undefined
417  {
418  return( true );
419  }
420 
421  if( !m_Authority.is_Empty() && !m_Authority.CmpNoCase(Projection.m_Authority) && m_Code == Projection.m_Code )
422  {
423  return( true );
424  }
425 
426  if( !m_PROJ.CmpNoCase(Projection.m_PROJ) ) // the simple case, identical PROJ strings...
427  {
428  return( true );
429  }
430 
431  //-----------------------------------------------------
432  // okay, let's perform a more detailed check...
433 
434  #define CMP_CONTENT(a, b ) (a && b && a->Cmp_Content(b->Get_Content()))
435  #define CMP_PROPERTY(a, b, p) (a && b && a->Get_Property(p) && b->Cmp_Property(p, a->Get_Property(p), true))
436  #define CMP_PARAMETER(a, b ) (a && b && ((!a->Cmp_Name("PARAMETER") && !b->Cmp_Name("PARAMETER")) || CMP_PROPERTY(a, b, "name") && a->Cmp_Content(b->Get_Content())))
437 
438  CSG_MetaData WKT[2] = {
439  CSG_Projections::_WKT_to_MetaData( m_WKT1),
440  CSG_Projections::_WKT_to_MetaData(Projection.m_WKT1)
441  }, *pGCS[2] = { NULL, NULL };
442 
443  if( is_Projection() )
444  {
445 
446  if( !CMP_CONTENT (WKT[0]("PROJECTION"), WKT[1]("PROJECTION") ) ) { return( false ); }
447  if( !CMP_PROPERTY(WKT[0]("UNIT" ), WKT[1]("UNIT" ), "name") ) { return( false ); }
448 
449  for(int i=0; i<WKT[0].Get_Children_Count() && i<WKT[1].Get_Children_Count(); i++)
450  {
451  if( !CMP_PARAMETER(WKT[0](i), WKT[1](i)) ) { return( false ); }
452  }
453 
454  pGCS[0] = WKT[0]("GEOGCS");
455  pGCS[1] = WKT[1]("GEOGCS");
456  }
457  else if( is_Geographic() )
458  {
459  pGCS[0] = &WKT[0];
460  pGCS[1] = &WKT[1];
461  }
462 
463  if( !pGCS[0] || !pGCS[1] )
464  {
465  return( false );
466  }
467 
468  if( !CMP_CONTENT((*pGCS[0])("PRIMEM" ), (*pGCS[1])("PRIMEM" )) ) { return( false ); }
469  if( !CMP_CONTENT((*pGCS[0])("UNIT" ), (*pGCS[1])("UNIT" )) ) { return( false ); }
470  if( !CMP_CONTENT((*pGCS[0])("DATUM.SPHEROID.a" ), (*pGCS[1])("DATUM.SPHEROID.a" )) ) { return( false ); }
471  if( !CMP_CONTENT((*pGCS[0])("DATUM.SPHEROID.rf"), (*pGCS[1])("DATUM.SPHEROID.rf")) ) { return( false ); }
472 
473  if( (*pGCS[0])("DATUM.TOWGS84") || (*pGCS[1])("DATUM.TOWGS84") )
474  {
475  #define CMP_TOWGS84(id) (\
476  ((*pGCS[0])("DATUM.TOWGS84." id) ? (*pGCS[0])["DATUM.TOWGS84." id].Get_Content().asDouble() : 0.)\
477  == ((*pGCS[1])("DATUM.TOWGS84." id) ? (*pGCS[1])["DATUM.TOWGS84." id].Get_Content().asDouble() : 0.) )
478 
479  if( !CMP_TOWGS84("dx") ) { return( false ); }
480  if( !CMP_TOWGS84("dy") ) { return( false ); }
481  if( !CMP_TOWGS84("dz") ) { return( false ); }
482  if( !CMP_TOWGS84("rx") ) { return( false ); }
483  if( !CMP_TOWGS84("ry") ) { return( false ); }
484  if( !CMP_TOWGS84("rz") ) { return( false ); }
485  if( !CMP_TOWGS84("sc") ) { return( false ); }
486  }
487 
488  if( (*pGCS[0])("DATUM.EXTENSION") || (*pGCS[1])("DATUM.EXTENSION") )
489  {
490  if( !CMP_CONTENT((*pGCS[0])("DATUM.EXTENSION"), (*pGCS[1])("DATUM.EXTENSION")) ) { return( false ); }
491  }
492 
493  return( true );
494 }
495 
496 
498 // //
500 
501 //---------------------------------------------------------
503 {
505 }
506 
507 //---------------------------------------------------------
509 {
510  return( CSG_Projections::Get_CRS_Type_Name(m_Type) );
511 }
512 
513 //---------------------------------------------------------
515 {
516  return( CSG_Projections::Get_Unit_Identifier(m_Unit) );
517 }
518 
519 //---------------------------------------------------------
521 {
522  return( CSG_Projections::Get_Unit_Name(m_Unit) );
523 }
524 
525 //---------------------------------------------------------
527 {
528  return( CSG_Projections::Get_Unit_To_Meter(m_Unit) );
529 }
530 
531 
533 // //
535 
536 //---------------------------------------------------------
538 {
539  static CSG_Projection GCS_WGS84;
540 
541  if( !GCS_WGS84.is_Okay() )
542  {
543  GCS_WGS84.Set_GCS_WGS84();
544  }
545 
546  return( GCS_WGS84 );
547 }
548 
549 //---------------------------------------------------------
551 {
552  return( Create(4326) );
553 }
554 
555 //---------------------------------------------------------
557 {
558  CSG_Projection Projection;
559 
560  Projection.Set_UTM_WGS84(Zone, bSouth);
561 
562  return( Projection );
563 }
564 
565 //---------------------------------------------------------
566 bool CSG_Projection::Set_UTM_WGS84(int Zone, bool bSouth)
567 {
568  if( Zone < 1 || Zone > 60 )
569  {
570  return( false );
571  }
572 
573  int EPSG_ID = (bSouth ? 32700 : 32600) + Zone;
574 
575  if( Create(EPSG_ID) )
576  {
577  return( true );
578  }
579 
580  //-----------------------------------------------------
581  #define WKT_GCS_WGS84 "GEOGCS[\"WGS 84\",AUTHORITY[\"EPSG\",\"4326\"]],"\
582  "DATUM[\"WGS_1984\",AUTHORITY[\"EPSG\",\"6326\"]],"\
583  "SPHEROID[\"WGS 84\",6378137,298.257223563,AUTHORITY[\"EPSG\",\"7030\"]],"\
584  "PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],"\
585  "UNIT[\"degree\",0.0174532925199433,AUTHORITY[\"EPSG\",\"9122\"]]"
586 
587  CSG_String WKT;
588 
589  WKT.Printf("PROJCS[\"WGS 84 / UTM zone %d%c\",%s" // Zone, N/S, Datum
590  "PROJECTION[\"Transverse_Mercator\"],AUTHORITY[\"EPSG\",\"%d\"]]" // EPSG ID
591  "PARAMETER[\"latitude_of_origin\",0],"
592  "PARAMETER[\"central_meridian\",%d]," // Central Meridian
593  "PARAMETER[\"scale_factor\",0.9996],"
594  "PARAMETER[\"false_easting\",500000],"
595  "PARAMETER[\"false_northing\",%d]," // False Northing
596  "AXIS[\"Easting\",EAST],"
597  "AXIS[\"Northing\",NORTH],"
598  "UNIT[\"metre\",1,AUTHORITY[\"EPSG\",\"9001\"]]",
599  Zone, bSouth ? 'S' : 'N', CSG_String(WKT_GCS_WGS84).c_str(), EPSG_ID, 6 * (Zone - 1) - 177, bSouth ? 10000000 : 0
600  );
601 
602  return( Create(WKT) );
603 }
604 
605 
607 // //
608 // //
609 // //
611 
612 //---------------------------------------------------------
614 {
620 };
621 
622 
624 // //
626 
627 //---------------------------------------------------------
629 {
630  _On_Construction();
631 }
632 
633 //---------------------------------------------------------
635 {
636  _On_Construction();
637 
638  Create(LoadDefault);
639 }
640 
641 bool CSG_Projections::Create(bool LoadDefault)
642 {
643  Destroy();
644 
645  if( LoadDefault ) // load spatial reference system database and dictionary
646  {
647  #if defined(_SAGA_LINUX)
648  CSG_String Path_Shared = SHARE_PATH;
649  #else
650  CSG_String Path_Shared = SG_UI_Get_Application_Path(true);
651  #endif
652 
653  SG_UI_Msg_Lock(true);
654  Load(SG_File_Make_Path(Path_Shared, "saga_prj", "srs"));
655  SG_UI_Msg_Lock(false);
656  }
657 
658  return( true );
659 }
660 
661 //---------------------------------------------------------
663 {
664  _On_Construction();
665 
666  Create(File);
667 }
668 
670 {
671  SG_UI_Msg_Lock(true);
672  bool bResult = Load(File_DB);
673  SG_UI_Msg_Lock(false);
674 
675  return( bResult );
676 }
677 
678 //---------------------------------------------------------
679 void CSG_Projections::_On_Construction(void)
680 {
681  m_pProjections = new CSG_Table;
682 
683  m_pProjections->Add_Field("srid" , SG_DATATYPE_Int ); // PRJ_FIELD_SRID
684  m_pProjections->Add_Field("auth_name", SG_DATATYPE_String); // PRJ_FIELD_AUTH_NAME
685  m_pProjections->Add_Field("auth_srid", SG_DATATYPE_Int ); // PRJ_FIELD_AUTH_SRID
686  m_pProjections->Add_Field("srtext" , SG_DATATYPE_String); // PRJ_FIELD_SRTEXT
687  m_pProjections->Add_Field("proj4text", SG_DATATYPE_String); // PRJ_FIELD_PROJ4TEXT
688 
689  _Set_Dictionary();
690 }
691 
692 //---------------------------------------------------------
694 {
695  Destroy();
696 
697  delete(m_pProjections);
698 }
699 
700 //---------------------------------------------------------
702 {
703  if( m_pProjections )
704  {
705  m_pProjections->Del_Records();
706  }
707 }
708 
709 
711 // //
713 
714 //---------------------------------------------------------
716 {
717  return( m_pProjections->Get_Count() );
718 }
719 
720 //---------------------------------------------------------
721 bool CSG_Projections::Add(const CSG_Projection &Projection)
722 {
723  return( false );
724 }
725 
726 //---------------------------------------------------------
727 bool CSG_Projections::Add(const SG_Char *WKT, const SG_Char *Proj4, const SG_Char *Authority, int Authority_ID)
728 {
729  CSG_Table_Record *pProjection = m_pProjections->Add_Record();
730 
731  pProjection->Set_Value(PRJ_FIELD_SRID , (int)m_pProjections->Get_Count());
732  pProjection->Set_Value(PRJ_FIELD_AUTH_NAME, Authority);
733  pProjection->Set_Value(PRJ_FIELD_AUTH_SRID, Authority_ID);
734  pProjection->Set_Value(PRJ_FIELD_SRTEXT , WKT);
735  pProjection->Set_Value(PRJ_FIELD_PROJ4TEXT, Proj4);
736 
737  return( true );
738 }
739 
740 //---------------------------------------------------------
742 {
743  CSG_Projection Projection;
744 
745  if( Index >= 0 && Index < m_pProjections->Get_Count() )
746  {
747  CSG_Table_Record *pProjection = m_pProjections->Get_Record(Index);
748 
749  Projection.m_Authority = pProjection->asString(PRJ_FIELD_AUTH_NAME);
750  Projection.m_Code = pProjection->asInt (PRJ_FIELD_AUTH_SRID);
751  Projection.m_WKT1 = pProjection->asString(PRJ_FIELD_SRTEXT );
752  Projection.m_PROJ = pProjection->asString(PRJ_FIELD_PROJ4TEXT);
753 
754  CSG_MetaData WKT = _WKT_to_MetaData(Projection.m_WKT1);
755 
756  Projection.m_Name = WKT.Get_Property("name");
757  Projection.m_Type = Get_CRS_Type(WKT.Get_Name());
758  Projection.m_Unit = WKT("UNIT") && WKT["UNIT"].Get_Property("name") ?
759  Get_Unit(WKT["UNIT"].Get_Property("name")) : ESG_Projection_Unit::Undefined;
760  }
761 
762  return( Projection );
763 }
764 
765 //---------------------------------------------------------
766 const SG_Char * CSG_Projections::Get_Projection(int Code, const SG_Char *_Authority) const
767 {
768  CSG_String Authority(_Authority && *_Authority ? _Authority : SG_T("EPSG"));
769 
770  for(sLong i=0; i<m_pProjections->Get_Count(); i++)
771  {
772  CSG_Table_Record *pProjection = m_pProjections->Get_Record(i);
773 
774  if( Code == pProjection->asInt(PRJ_FIELD_AUTH_SRID) && !Authority.CmpNoCase(pProjection->asString(PRJ_FIELD_AUTH_NAME)) )
775  {
776  return( pProjection->asString(PRJ_FIELD_SRTEXT) );
777  }
778  }
779 
780  return( SG_T("") );
781 }
782 
783 //---------------------------------------------------------
784 bool CSG_Projections::Get_Projection(CSG_Projection &Projection, int Code, const SG_Char *_Authority) const
785 {
786  CSG_String Authority(_Authority && *_Authority ? _Authority : SG_T("EPSG"));
787 
788  for(sLong i=0; i<m_pProjections->Get_Count(); i++)
789  {
790  CSG_Table_Record *pProjection = m_pProjections->Get_Record(i);
791 
792  if( Code == pProjection->asInt(PRJ_FIELD_AUTH_SRID) && !Authority.CmpNoCase(pProjection->asString(PRJ_FIELD_AUTH_NAME)) )
793  {
794  Projection = Get_Projection(i);
795 
796  return( true );
797  }
798  }
799 
800  return( false );
801 }
802 
803 
805 // //
807 
808 //---------------------------------------------------------
809 bool CSG_Projections::Load(const CSG_String &File, bool bAppend)
810 {
811  CSG_Table Table;
812 
813  if( m_pProjections && SG_File_Exists(File) && Table.Create(File) )
814  {
816 
817  if( !bAppend )
818  {
819  m_pProjections->Del_Records();
820  }
821 
822  for(sLong i=0; i<Table.Get_Count() && SG_UI_Process_Set_Progress(i, Table.Get_Count()); i++)
823  {
824  m_pProjections->Add_Record(Table.Get_Record_byIndex(i));
825  }
826 
827  return( true );
828  }
829 
830  return( false );
831 }
832 
833 //---------------------------------------------------------
835 {
836  return( m_pProjections->Save(File) );
837 }
838 
839 
841 // //
843 
844 //---------------------------------------------------------
845 bool CSG_Projections::Parse(const CSG_String &Definition, CSG_String *WKT1, CSG_String *WKT2, CSG_String *PROJ, CSG_String *ESRI)
846 {
847  CSG_Tool *pTool = SG_Get_Tool_Library_Manager().Create_Tool("pj_proj4", 19); // Coordinate Reference System Format Conversion
848 
849  if( pTool )
850  {
851  pTool->Set_Parameter("DEFINITION", Definition);
852  pTool->Set_Parameter("MULTILINE" , false);
853  pTool->Set_Parameter("SIMPLIFIED", true);
854 
856  bool bResult = pTool->Execute();
858 
859  if( bResult )
860  {
861  if( WKT1 ) { *WKT1 = pTool->Get_Parameter("WKT1")->asString(); }
862  if( WKT2 ) { *WKT2 = pTool->Get_Parameter("WKT2")->asString(); }
863  if( PROJ ) { *PROJ = pTool->Get_Parameter("PROJ")->asString(); }
864  if( ESRI ) { *ESRI = pTool->Get_Parameter("ESRI")->asString(); }
865  }
866 
868 
869  return( bResult );
870  }
871 
872  //-----------------------------------------------------
873  else if( !Definition.is_Empty() ) // proj.lib parser not available ...fallback!
874  {
875  if( Definition.Find("+proj") == 0 )
876  {
877  CSG_String WKT;
878 
879  if( gSG_Projections._WKT_from_Proj4(WKT, Definition) )
880  {
881  if( WKT1 ) { *WKT1 = WKT ; }
882  if( PROJ ) { *PROJ = Definition; }
883 
884  return( true );
885  }
886 
887  return( false );
888  }
889 
890  //-------------------------------------------------
891  CSG_MetaData WKT(CSG_Projections::_WKT_to_MetaData(Definition));
892 
893  int Code; CSG_String Authority; CSG_Projection Projection;
894 
895  if( WKT.Get_Property("authority_name", Authority) && WKT.Get_Property("authority_code", Code)
896  && gSG_Projections.Get_Projection(Projection, Code, Authority) )
897  {
898  if( WKT1 ) { *WKT1 = Projection.Get_WKT1(); }
899  if( WKT2 ) { *WKT2 = Projection.Get_WKT2(); }
900  if( PROJ ) { *PROJ = Projection.Get_PROJ(); }
901  if( ESRI ) { *ESRI = Projection.Get_ESRI(); }
902 
903  return( true );
904  }
905 
906  //-------------------------------------------------
907  CSG_String Proj4;
908 
909  if( gSG_Projections._WKT_to_Proj4(Proj4, Definition) )
910  {
911  if( WKT1 ) { *WKT1 = Definition; }
912  if( PROJ ) { *PROJ = Proj4 ; }
913 
914  return( true );
915  }
916 
917  //-------------------------------------------------
918  Authority = Definition.BeforeFirst(':');
919 
920  if( !Authority.is_Empty() && Definition.AfterFirst(':').asInt(Code)
921  && gSG_Projections.Get_Projection(Projection, Code, Authority) )
922  {
923  if( WKT1 ) { *WKT1 = Projection.Get_WKT1(); }
924  if( WKT2 ) { *WKT2 = Projection.Get_WKT2(); }
925  if( PROJ ) { *PROJ = Projection.Get_PROJ(); }
926  if( ESRI ) { *ESRI = Projection.Get_ESRI(); }
927 
928  return( true );
929  }
930  }
931 
932  //-----------------------------------------------------
933  return( false );
934 }
935 
936 
938 // //
940 
941 //---------------------------------------------------------
942 bool CSG_Projections::_EPSG_to_Proj4(CSG_String &Proj4, int EPSG_Code) const
943 {
944  for(sLong i=0; i<m_pProjections->Get_Count(); i++)
945  {
946  if( m_pProjections->Get_Record(i)->asInt(PRJ_FIELD_AUTH_SRID) == EPSG_Code )
947  {
948  Proj4 = m_pProjections->Get_Record(i)->asString(PRJ_FIELD_PROJ4TEXT);
949 
950  return( true );
951  }
952  }
953 
954  Proj4.Printf("+init=epsg:%d ", EPSG_Code);
955 
956  return( false );
957 }
958 
959 //---------------------------------------------------------
960 bool CSG_Projections::_EPSG_to_WKT(CSG_String &WKT, int EPSG_Code) const
961 {
962  for(sLong i=0; i<m_pProjections->Get_Count(); i++)
963  {
964  if( m_pProjections->Get_Record(i)->asInt(PRJ_FIELD_AUTH_SRID) == EPSG_Code )
965  {
966  WKT = m_pProjections->Get_Record(i)->asString(PRJ_FIELD_SRTEXT);
967 
968  return( true );
969  }
970  }
971 
972  return( false );
973 }
974 
975 
977 // //
979 
980 //---------------------------------------------------------
982 {
983  CSG_String Names;
984 
985  if( bAddSelect )
986  {
987  Names.Printf("{}<%s>|", _TL("select"));
988  }
989 
990  for(int i=0; i<Get_Count(); i++)
991  {
992  CSG_Table_Record *pProjection = m_pProjections->Get_Record(i);
993 
994  CSG_String WKT = pProjection->asString(PRJ_FIELD_SRTEXT);
995 
996  ESG_CRS_Type _Type =
997  !WKT.BeforeFirst('[').Cmp("PROJCS") ? ESG_CRS_Type::Projection :
998  !WKT.BeforeFirst('[').Cmp("GEOGCS") ? ESG_CRS_Type::Geographic :
999  !WKT.BeforeFirst('[').Cmp("GEOCCS") ? ESG_CRS_Type::Geocentric : ESG_CRS_Type::Undefined;
1000 
1001  if( Type == ESG_CRS_Type::Undefined )
1002  {
1003  Names += CSG_String::Format("{%s:%d}%s: %s|",
1004  pProjection->asString(PRJ_FIELD_AUTH_NAME),
1005  pProjection->asInt (PRJ_FIELD_SRID ),
1007  WKT.AfterFirst('\"').BeforeFirst('\"').c_str()
1008  );
1009  }
1010  else if( Type == _Type )
1011  {
1012  Names += CSG_String::Format("{%s:%d}%s|",
1013  pProjection->asString(PRJ_FIELD_AUTH_NAME),
1014  pProjection->asInt (PRJ_FIELD_SRID ),
1015  WKT.AfterFirst('\"').BeforeFirst('\"').c_str()
1016  );
1017  }
1018  }
1019 
1020  return( Names );
1021 }
1022 
1023 
1025 // //
1027 
1028 //---------------------------------------------------------
1029 bool CSG_Projections::_WKT_to_MetaData(CSG_MetaData &MetaData, const CSG_String &WKT)
1030 {
1031  CSG_String Key; CSG_Strings Content; Content.Add("");
1032 
1033  for(int i=0, l=-1; l!=0 && i<(int)WKT.Length(); i++)
1034  {
1035  if( l < 0 ) // read key
1036  {
1037  switch( WKT[i] )
1038  {
1039  default : Key += WKT[i]; break;
1040  case ' ' : break;
1041  case '[': case '(': l = 1 ; break;
1042  case ')': case ']': return( false );
1043  }
1044  }
1045  else // read content
1046  {
1047  bool bAdd;
1048 
1049  switch( WKT[i] )
1050  {
1051  default : bAdd = true; break;
1052  case '\"' : bAdd = false; break;
1053  case '[' : case '(': bAdd = ++l > 1; break;
1054  case ']' : case ')': bAdd = l-- > 1; break;
1055  case ',' : if( !(bAdd = l > 1) ) Content.Add(""); break;
1056  }
1057 
1058  if( bAdd )
1059  {
1060  Content[Content.Get_Count() - 1] += WKT[i];
1061  }
1062  }
1063  }
1064 
1065  if( Key.is_Empty() || Content[0].is_Empty() )
1066  {
1067  return( false );
1068  }
1069 
1070  //-----------------------------------------------------
1071  if( !Key.Cmp("AUTHORITY") && Content.Get_Count() == 2 ) // AUTHORITY ["<name>", "<code>"]
1072  {
1073  MetaData.Add_Property("authority_name", Content[0]);
1074  MetaData.Add_Property("authority_code", Content[1]);
1075 
1076  return( true );
1077  }
1078 
1079  CSG_MetaData *pKey = MetaData.Add_Child(Key);
1080 
1081  if( (!Key.Cmp("GEOCCS" ) && Content.Get_Count() >= 4) // GEOCCS ["<name>", <datum>, <prime meridian>, <linear unit> {,<axis>, <axis>, <axis>} {,<authority>}]
1082  || (!Key.Cmp("GEOGCS" ) && Content.Get_Count() >= 4) // GEOGCS ["<name>", <datum>, <prime meridian>, <angular unit> {,<twin axes>} {,<authority>}]
1083  || (!Key.Cmp("PROJCS" ) && Content.Get_Count() >= 3) // PROJCS ["<name>", <geographic cs>, <projection>, {<parameter>,}* <linear unit> {,<twin axes>}{,<authority>}]
1084  || (!Key.Cmp("DATUM" ) && Content.Get_Count() >= 2) ) // DATUM ["<name>", <spheroid> {,<to wgs84>} {,<authority>}]
1085  {
1086  pKey->Add_Property("name", Content[0]);
1087  }
1088 
1089  if( (!Key.Cmp("PRIMEM" ) && Content.Get_Count() >= 2) // PRIMEM ["<name>", <longitude> {,<authority>}]
1090  || (!Key.Cmp("UNIT" ) && Content.Get_Count() >= 2) // UNIT ["<name>", <conversion factor> {,<authority>}]
1091  || (!Key.Cmp("AXIS" ) && Content.Get_Count() >= 2) // AXIS ["<name>", NORTH|SOUTH|EAST|WEST|UP|DOWN|OTHER]
1092  || (!Key.Cmp("PARAMETER" ) && Content.Get_Count() >= 2) ) // PARAMETER ["<name>", <value>]
1093  {
1094  pKey->Add_Property("name", Content[0]);
1095 
1096  pKey->Set_Content(Content[1]);
1097  }
1098 
1099  if( (!Key.Cmp("SPHEROID" ) && Content.Get_Count() >= 3) ) // SPHEROID ["<name>", <semi-major axis>, <inverse flattening> {,<authority>}]
1100  {
1101  pKey->Add_Property("name", Content[0]);
1102  pKey->Add_Child ("a" , Content[1]);
1103  pKey->Add_Child ("rf" , Content[2]);
1104  }
1105 
1106  if( (!Key.Cmp("TOWGS84" ) && Content.Get_Count() >= 7) ) // TOWGS84 [<dx>, <dy>, <dz>, <rx>, <ry>, <rz>, <sc>]
1107  {
1108  pKey->Add_Child("dx" , Content[0]);
1109  pKey->Add_Child("dy" , Content[1]);
1110  pKey->Add_Child("dz" , Content[2]);
1111  pKey->Add_Child("rx" , Content[3]);
1112  pKey->Add_Child("ry" , Content[4]);
1113  pKey->Add_Child("rz" , Content[5]);
1114  pKey->Add_Child("sc" , Content[6]);
1115  }
1116 
1117  if( (!Key.Cmp("EXTENSION" ) && Content.Get_Count() >= 2) ) // EXTENSION [<name>, <value>]
1118  {
1119  pKey->Add_Property("name", Content[0]);
1120  pKey->Set_Content( Content[1]);
1121  }
1122 
1123  if( (!Key.Cmp("PROJECTION") && Content.Get_Count() >= 1) ) // PROJECTION ["<name>" {,<authority>}]
1124  {
1125  pKey->Set_Content(Content[0]);
1126  }
1127 
1128  //-----------------------------------------------------
1129  for(int i=0; i<Content.Get_Count(); i++)
1130  {
1131  _WKT_to_MetaData(*pKey, Content[i]);
1132  }
1133 
1134  return( true );
1135 }
1136 
1137 //---------------------------------------------------------
1138 CSG_MetaData CSG_Projections::_WKT_to_MetaData(const CSG_String &WKT)
1139 {
1140  CSG_MetaData MetaData;
1141 
1142  _WKT_to_MetaData(MetaData, WKT);
1143 
1144  if( MetaData.Get_Children_Count() == 1 )
1145  {
1146  return( *MetaData.Get_Child(0) );
1147  }
1148 
1149  MetaData.Destroy();
1150 
1151  return( MetaData );
1152 }
1153 
1154 
1156 // //
1158 
1159 //---------------------------------------------------------
1160 // DATUM ["<name>",
1161 // SPHEROID["<name>", <semi-major axis>, <inverse flattening>]
1162 // *TOWGS84 [<dx>, <dy>, <dz>, <rx>, <ry>, <rz>, <sc>]
1163 // ]
1164 //---------------------------------------------------------
1165 bool CSG_Projections::_WKT_to_Proj4_Set_Datum(CSG_String &Proj4, const CSG_MetaData &WKT) const
1166 {
1167  if( WKT.Cmp_Property("name", "WGS84") )
1168  {
1169  Proj4 += " +datum=WGS84";
1170 
1171  return( true );
1172  }
1173 
1174  double a, b;
1175 
1176  if( !WKT("SPHEROID") || WKT["SPHEROID"].Get_Children_Count() != 2
1177  || !WKT["SPHEROID"][0].Get_Content().asDouble(a) || a <= 0.
1178  || !WKT["SPHEROID"][1].Get_Content().asDouble(b) || b < 0. )
1179  {
1180  return( false );
1181  }
1182 
1183  b = b > 0. ? a - a / b : a;
1184 
1185  Proj4 += CSG_String::Format(" +a=%f", a); // Semimajor radius of the ellipsoid axis
1186  Proj4 += CSG_String::Format(" +b=%f", b); // Semiminor radius of the ellipsoid axis
1187 
1188  if( WKT("TOWGS84") && WKT["TOWGS84"].Get_Children_Count() == 7 )
1189  {
1190  Proj4 += " +towgs84=";
1191 
1192  for(int i=0; i<7; i++)
1193  {
1194  if( i > 0 )
1195  {
1196  Proj4 += ",";
1197  }
1198 
1199  Proj4 += WKT["TOWGS84"][i].Get_Content();
1200  }
1201  }
1202 
1203  return( true );
1204 }
1205 
1206 //---------------------------------------------------------
1207 bool CSG_Projections::_WKT_to_Proj4(CSG_String &Proj4, const CSG_String &WKT) const
1208 {
1209  Proj4.Clear();
1210 
1211  CSG_MetaData m = _WKT_to_MetaData(WKT);
1212 
1213  if( m.Get_Children_Count() == 0 )
1214  {
1215  return( false );
1216  }
1217 
1218  //-----------------------------------------------------
1219  int Authority_Code; CSG_String Authority_Name;
1220 
1221  if( m.Get_Property("authority_name", Authority_Name) && Authority_Name.CmpNoCase("EPSG") == 0
1222  && m.Get_Property("authority_code", Authority_Code) && _EPSG_to_Proj4(Proj4, Authority_Code) )
1223  { // Proj4.Printf("+init=epsg:%d", Authority_Code);
1224  return( true );
1225  }
1226 
1227  //-----------------------------------------------------
1228  double d;
1229 
1230  //-----------------------------------------------------
1231  // GEOCCS["<name>",
1232  // DATUM ["<name>", ...],
1233  // PRIMEM ["<name>", <longitude>],
1234  // UNIT ["<name>", <conversion factor>],
1235  // *AXIS ["<name>", NORTH|SOUTH|EAST|WEST|UP|DOWN|OTHER], AXIS...
1236  // ]
1237  if( m.Cmp_Name("GEOCCS") )
1238  {
1239  Proj4 = CSG_String::Format("+proj=geocent");
1240 
1241  if( !m("DATUM") || !_WKT_to_Proj4_Set_Datum(Proj4, m["DATUM"]) )
1242  {
1243  return( false );
1244  }
1245 
1246  if( m("PRIMEM") && m["PRIMEM"].Get_Content().asDouble(d) && d != 0. )
1247  {
1248  Proj4 += CSG_String::Format(" +pm=%f", d);
1249  }
1250 
1251  Proj4 += CSG_String::Format(" +no_defs"); // Don't use the /usr/share/proj/proj_def.dat defaults file
1252 
1253  return( true );
1254  }
1255 
1256  //-----------------------------------------------------
1257  // GEOGCS["<name>,
1258  // DATUM ["<name>", ...],
1259  // PRIMEM ["<name>", <longitude>],
1260  // UNIT ["<name>", <conversion factor>],
1261  // *AXIS ["<name>", NORTH|SOUTH|EAST|WEST|UP|DOWN|OTHER], AXIS...
1262  // ]
1263  if( m.Cmp_Name("GEOGCS") )
1264  {
1265  Proj4 = "+proj=longlat";
1266 
1267  if( !m("DATUM") || !_WKT_to_Proj4_Set_Datum(Proj4, m["DATUM"]) )
1268  {
1269  return( false );
1270  }
1271 
1272  if( m("PRIMEM") && m["PRIMEM"].Get_Content().asDouble(d) && d != 0. )
1273  {
1274  Proj4 += CSG_String::Format(" +pm=%f", d);
1275  }
1276 
1277  Proj4 += CSG_String::Format(" +no_defs"); // Don't use the /usr/share/proj/proj_def.dat defaults file
1278 
1279  return( true );
1280  }
1281 
1282  //-----------------------------------------------------
1283  // PROJCS["<name>,
1284  // GEOGCS ["<name>, ...],
1285  // PROJECTION["<name>"],
1286  // *PARAMETER ["<name>", <value>], PARAMETER...
1287  // UNIT ["<name>", <conversion factor>],
1288  // *AXIS ["<name>", NORTH|SOUTH|EAST|WEST|UP|DOWN|OTHER], AXIS...
1289  // ]
1290  if( m.Cmp_Name("PROJCS") && m("GEOGCS") && m("PROJECTION") && m_WKT_to_Proj4.Get_Translation(m["PROJECTION"].Get_Content(), Proj4) )
1291  {
1292  if( m["PROJECTION"].Cmp_Content("Transverse_Mercator") ) // UTM ???
1293  {
1294  double Scale = -1., Easting = -1., Northing = -1., Meridian = -1., Latitude = -1.;
1295 
1296  for(int i=0; i<m.Get_Children_Count(); i++)
1297  {
1298  if( m[i].Cmp_Name("PARAMETER") )
1299  {
1300  double v;
1301 
1302  if( m[i].Cmp_Property("name", "central_meridian" , true) && m[i].Get_Content().asDouble(v) ) Meridian = v;
1303  if( m[i].Cmp_Property("name", "latitude_of_origin", true) && m[i].Get_Content().asDouble(v) ) Latitude = v;
1304  if( m[i].Cmp_Property("name", "scale_factor" , true) && m[i].Get_Content().asDouble(v) ) Scale = v;
1305  if( m[i].Cmp_Property("name", "false_easting" , true) && m[i].Get_Content().asDouble(v) ) Easting = v;
1306  if( m[i].Cmp_Property("name", "false_northing" , true) && m[i].Get_Content().asDouble(v) ) Northing = v;
1307  }
1308  }
1309 
1310  if( Latitude == 0. && Scale == 0.9996 && Easting == 500000. && (Northing == 0. || Northing == 10000000.) )
1311  {
1312  Proj4 = "+proj=utm";
1313 
1314  if( !m["GEOGCS"]("DATUM") || !_WKT_to_Proj4_Set_Datum(Proj4, m["GEOGCS"]["DATUM"]) )
1315  {
1316  return( false );
1317  }
1318 
1319  Proj4 += CSG_String::Format(" +zone=%d", (int)((183. + Meridian) / 6.));
1320 
1321  if( Northing == 10000000. )
1322  {
1323  Proj4 += " +south";
1324  }
1325 
1326  Proj4 += CSG_String::Format(" +no_defs"); // Don't use the /usr/share/proj/proj_def.dat defaults file
1327 
1328  return( true );
1329  }
1330  }
1331 
1332  //-------------------------------------------------
1333  Proj4 = "+proj=" + Proj4;
1334 
1335  if( !m["GEOGCS"]("DATUM") || !_WKT_to_Proj4_Set_Datum(Proj4, m["GEOGCS"]["DATUM"]) )
1336  {
1337  return( false );
1338  }
1339 
1340  if( m("PRIMEM") && m["PRIMEM"].Get_Content().asDouble(d) && d != 0. )
1341  {
1342  Proj4 += CSG_String::Format(" +pm=%f", d);
1343  }
1344 
1345  for(int i=0; i<m.Get_Children_Count(); i++)
1346  {
1347  if( m[i].Cmp_Name("PARAMETER") )
1348  {
1349  CSG_String Parameter;
1350 
1351  if( m_WKT_to_Proj4.Get_Translation(m[i].Get_Property("name"), Parameter) )
1352  {
1353  Proj4 += " +" + Parameter + "=" + m[i].Get_Content();
1354  }
1355  else
1356  {
1357  SG_UI_Msg_Add_Error(CSG_String::Format(">> WKT: %s [%s]", _TL("unknown parameter"), m[i].Get_Property("name")));
1358  }
1359  }
1360  }
1361 
1362  if( m("UNIT") && m["UNIT"].Get_Content().asDouble(d) && d != 0. && d != 1. )
1363  {
1364  Proj4 += CSG_String::Format(" +to_meter=%f", d);
1365  }
1366 
1367  Proj4 += CSG_String::Format(" +no_defs"); // Don't use the /usr/share/proj/proj_def.dat defaults file
1368 
1369  return( true );
1370  }
1371 
1372  //-----------------------------------------------------
1373  return( false );
1374 }
1375 
1376 
1378 // //
1380 
1381 //---------------------------------------------------------
1382 bool CSG_Projections::_Proj4_Find_Parameter(const CSG_String &Proj4, const CSG_String &Key)
1383 {
1384  return( Proj4.Find("+" + Key) >= 0 );
1385 }
1386 
1387 //---------------------------------------------------------
1388 bool CSG_Projections::_Proj4_Read_Parameter(CSG_String &Value, const CSG_String &Proj4, const CSG_String &Key)
1389 {
1390  Value.Clear();
1391 
1392  int l, i = Proj4.Find("+" + Key + "=");
1393 
1394  if( i >= 0 )
1395  {
1396  for(++i, l=0; l<2 && i<(int)Proj4.Length(); i++)
1397  {
1398  switch( Proj4[i] )
1399  {
1400  case '=': l++; break;
1401  case '+': l=2; break;
1402  case ' ': l=2; break;
1403  default :
1404  if( l == 1 )
1405  {
1406  Value += Proj4[i];
1407  }
1408  }
1409  }
1410  }
1411 
1412  return( Value.Length() > 0 );
1413 }
1414 
1415 //---------------------------------------------------------
1416 bool CSG_Projections::_Proj4_Get_Ellipsoid(CSG_String &Value, const CSG_String &Proj4)
1417 {
1418  const char ellipsoid[42][2][32] =
1419  { // ellipsoid a, b
1420  { "MERIT" , "6378137.0,298.257" }, // MERIT 1983
1421  { "SGS85" , "6378136.0,298.257" }, // Soviet Geodetic System 85
1422  { "GRS80" , "6378137.0,298.2572221" }, // GRS 1980 (IUGG, 1980)
1423  { "IAU76" , "6378140.0,298.257" }, // IAU 1976
1424  { "airy" , "6377563.396,299.3249753" }, // Airy 1830
1425  { "APL4.9" , "6378137.0,298.25" }, // Appl. Physics. 1965
1426  { "NWL9D" , "6378145.0,298.25" }, // Naval Weapons Lab., 1965
1427  { "mod_airy" , "6377340.189,299.3249374" }, // Modified Airy
1428  { "andrae" , "6377104.43,300" }, // Andrae 1876 (Den., Iclnd.)
1429  { "aust_SA" , "6378160.0,298.25" }, // Australian Natl & S. Amer. 1969
1430  { "GRS67" , "6378160.0,298.2471674" }, // GRS 67 (IUGG 1967)
1431  { "bessel" , "6377397.155,299.1528128" }, // Bessel 1841
1432  { "bess_nam" , "6377483.865,299.1528128" }, // Bessel 1841 (Namibia)
1433  { "clrk66" , "6378206.4,294.9786982" }, // Clarke 1866
1434  { "clrk80" , "6378249.145,293.4663" }, // Clarke 1880 mod.
1435  { "CPM" , "6375738.7,334.29" }, // Comm. des Poids et Mesures 1799
1436  { "delmbr" , "6376428.0,311.5" }, // Delambre 1810 (Belgium)
1437  { "engelis" , "6378136.05,298.2566" }, // Engelis 1985
1438  { "evrst30" , "6377276.345,300.8017" }, // Everest 1830
1439  { "evrst48" , "6377304.063,300.8017" }, // Everest 1948
1440  { "evrst56" , "6377301.243,300.8017" }, // Everest 1956
1441  { "evrst69" , "6377295.664,300.8017" }, // Everest 1969
1442  { "evrstSS" , "6377298.556,300.8017" }, // Everest (Sabah & Sarawak)
1443  { "fschr60" , "6378166.0,298.3" }, // Fischer (Mercury Datum) 1960
1444  { "fschr60m" , "6378155.0,298.3" }, // Modified Fischer 1960
1445  { "fschr68" , "6378150.0,298.3" }, // Fischer 1968
1446  { "helmert" , "6378200.0,298.3" }, // Helmert 1906
1447  { "hough" , "6378270.0,297" }, // Hough
1448  { "intl" , "6378388.0,297" }, // International 1909 (Hayford)
1449  { "krass" , "6378245.0,298.3" }, // Krassovsky, 1942
1450  { "kaula" , "6378163.0,298.24" }, // Kaula 1961
1451  { "lerch" , "6378139.0,298.257" }, // Lerch 1979
1452  { "mprts" , "6397300.0,191" }, // Maupertius 1738
1453  { "new_intl" , "6378157.5,298.2496154" }, // New International 1967
1454  { "plessis" , "6376523.0,308.6409971" }, // Plessis 1817 (France)
1455  { "SEasia" , "6378155.0,298.3000002" }, // Southeast Asia
1456  { "walbeck" , "6376896.0,302.7800002" }, // Walbeck
1457  { "WGS60" , "6378165.0,298.3" }, // WGS 60
1458  { "WGS66" , "6378145.0,298.25" }, // WGS 66
1459  { "WGS72" , "6378135.0,298.26" }, // WGS 72
1460  { "WGS84" , "6378137.0,298.2572236" }, // WGS 84
1461  { "sphere" , "6370997.0,-1" } // Normal Sphere (r=6370997)
1462  };
1463 
1464  //-----------------------------------------------------
1465  if( _Proj4_Read_Parameter(Value, Proj4, "ellps") )
1466  {
1467  for(int i=0; i<42; i++)
1468  {
1469  if( !Value.CmpNoCase(ellipsoid[i][0]) )
1470  {
1471  Value.Printf("SPHEROID[\"%s\",%s]", SG_STR_MBTOSG(ellipsoid[i][0]), SG_STR_MBTOSG(ellipsoid[i][1]));
1472 
1473  return( true );
1474  }
1475  }
1476  }
1477 
1478  //-----------------------------------------------------
1479  double a = _Proj4_Read_Parameter(Value, Proj4, "a" ) && Value.asDouble(a) ? a : 6378137.;
1480 
1481  double b = _Proj4_Read_Parameter(Value, Proj4, "b" ) && Value.asDouble(b) ? a / (a - b)
1482  : _Proj4_Read_Parameter(Value, Proj4, "rf") && Value.asDouble(b) ? b
1483  : _Proj4_Read_Parameter(Value, Proj4, "f" ) && Value.asDouble(b) ? 1. / b
1484  : _Proj4_Read_Parameter(Value, Proj4, "e" ) && Value.asDouble(b) ? a / (a - sqrt(b*b - a*a))
1485  : _Proj4_Read_Parameter(Value, Proj4, "es") && Value.asDouble(b) ? a / (a - sqrt( b - a*a))
1486  : 298.2572236;
1487 
1488  Value = CSG_String::Format("SPHEROID[\"Ellipsoid\",%f,%f]", a, b);
1489 
1490  return( true );
1491 }
1492 
1493 //---------------------------------------------------------
1494 bool CSG_Projections::_Proj4_Get_Datum(CSG_String &Value, const CSG_String &Proj4)
1495 {
1496  const char datum[9][3][64] =
1497  { // datum_id ellipse definition
1498  { "WGS84" , "WGS84" , "0,0,0,0,0,0,0" },
1499  { "GGRS87" , "GRS80" , "-199.87,74.79,246.62,0,0,0,0" }, // Greek_Geodetic_Reference_System_1987
1500  { "NAD83" , "GRS80" , "0,0,0,0,0,0,0" }, // North_American_Datum_1983
1501  // { "NAD27" , "clrk66" , "nadgrids=@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat" }, // North_American_Datum_1927
1502  { "potsdam" , "bessel" , "606.0,23.0,413.0,0,0,0,0" }, // Potsdam Rauenberg 1950 DHDN
1503  { "carthage" , "clark80" , "-263.0,6.0,431.0,0,0,0,0" }, // Carthage 1934 Tunisia
1504  { "hermannskogel" , "bessel" , "653.0,-212.0,449.0,0,0,0,0" }, // Hermannskogel
1505  { "ire65" , "mod_airy" , "482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15" }, // Ireland 1965
1506  { "nzgd49" , "intl" , "59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993" }, // New Zealand Geodetic Datum 1949
1507  { "OSGB36" , "airy" , "446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894" } // Airy 1830
1508  };
1509 
1510  CSG_String Spheroid, ToWGS84;
1511 
1512  //-----------------------------------------------------
1513  if( _Proj4_Read_Parameter(Value, Proj4, "datum") )
1514  {
1515  for(int i=0; i<9; i++)
1516  {
1517  if( !Value.CmpNoCase(datum[i][0]) && _Proj4_Get_Ellipsoid(Spheroid, CSG_String::Format("+ellps=%s", SG_STR_MBTOSG(datum[i][1]))) )
1518  {
1519  Value.Printf("DATUM[\"%s\",%s,TOWGS84[%s]]", SG_STR_MBTOSG(datum[i][0]), Spheroid.c_str(), SG_STR_MBTOSG(datum[i][2]));
1520 
1521  return( true );
1522  }
1523  }
1524  }
1525 
1526  //-----------------------------------------------------
1527  if( _Proj4_Get_Ellipsoid(Spheroid, Proj4) )
1528  {
1529  Value = "DATUM[\"Datum\","+ Spheroid;
1530 
1531  if( _Proj4_Read_Parameter(ToWGS84, Proj4, "towgs84") )
1532  {
1533  CSG_Strings s = SG_String_Tokenize(ToWGS84, ",");
1534 
1535  if( s.Get_Count() == 3 )
1536  {
1537  ToWGS84 += ",0,0,0,0";
1538  }
1539 
1540  Value += ",TOWGS84[" + ToWGS84 + "]";
1541  }
1542  else
1543  {
1544  Value += ",TOWGS84[0,0,0,0,0,0,0]";
1545  }
1546 
1547  Value += "]";
1548 
1549  return( true );
1550  }
1551 
1552  //-----------------------------------------------------
1553  Value = "DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\",6378137,298.257223563],TOWGS84[0,0,0,0,0,0,0]]";
1554 
1555  return( false );
1556 }
1557 
1558 //---------------------------------------------------------
1559 bool CSG_Projections::_Proj4_Get_Prime_Meridian(CSG_String &Value, const CSG_String &Proj4)
1560 {
1561  const char meridian[12][2][16] =
1562  {
1563  { "lisbon" , "-9.131906111" },
1564  { "paris" , "2.337229167" },
1565  { "bogota" , "74.08091667" },
1566  { "madrid" , "-3.687911111" },
1567  { "rome" , "12.45233333" },
1568  { "bern" , "7.439583333" },
1569  { "jakarta" , "106.8077194" },
1570  { "ferro" , "-17.66666667" },
1571  { "brussels" , "4.367975" },
1572  { "stockholm" , "18.05827778" },
1573  { "athens" , "23.7163375" },
1574  { "oslo" , "10.72291667" }
1575  };
1576 
1577  //-----------------------------------------------------
1578  if( _Proj4_Read_Parameter(Value, Proj4, "pm") )
1579  {
1580  for(int i=0; i<12; i++)
1581  {
1582  if( !Value.CmpNoCase(meridian[i][0]) )
1583  {
1584  Value.Printf("PRIMEM[\"%s\",%s]", SG_STR_MBTOSG(meridian[i][0]), SG_STR_MBTOSG(meridian[i][1]));
1585 
1586  return( true );
1587  }
1588  }
1589 
1590  double d;
1591 
1592  if( Value.asDouble(d) && d != 0. )
1593  {
1594  Value.Printf("PRIMEM[\"Prime_Meridian\",%f]", d);
1595 
1596  return( true );
1597  }
1598  }
1599 
1600  //-----------------------------------------------------
1601  Value = "PRIMEM[\"Greenwich\",0]";
1602 
1603  return( false );
1604 }
1605 
1606 //---------------------------------------------------------
1607 bool CSG_Projections::_Proj4_Get_Unit(CSG_String &Value, const CSG_String &Proj4)
1608 {
1609  ESG_Projection_Unit Unit = _Proj4_Read_Parameter(Value, Proj4, "units") ? CSG_Projections::Get_Unit(Value) : ESG_Projection_Unit::Undefined;
1610 
1611  if( Unit != ESG_Projection_Unit::Undefined )
1612  {
1613  Value = "UNIT[\"" + CSG_Projections::Get_Unit_Name(Unit) + "\"," + SG_Get_String(CSG_Projections::Get_Unit_To_Meter(Unit), -16) + "]";
1614 
1615  return( true );
1616  }
1617 
1618  //-----------------------------------------------------
1619  double d;
1620 
1621  if( _Proj4_Read_Parameter(Value, Proj4, "to_meter") && Value.asDouble(d) && d > 0. && d != 1. )
1622  {
1623  Value.Printf("UNIT[\"Unit\",%f]", d);
1624 
1625  return( true );
1626  }
1627 
1628  //-----------------------------------------------------
1629  Value = "UNIT[\"metre\",1]";
1630 // Value = "UNIT[\"degree\",0.01745329251994328]]";
1631 
1632  return( false );
1633 }
1634 
1635 //---------------------------------------------------------
1636 bool CSG_Projections::_WKT_from_Proj4(CSG_String &WKT, const CSG_String &Proj4) const
1637 {
1638  CSG_String Value, ProjCS;
1639 
1640  //-----------------------------------------------------
1641  if( !_Proj4_Read_Parameter(ProjCS, Proj4, "proj") )
1642  {
1643  SG_UI_Msg_Add_Error(CSG_String::Format("Proj4 >> WKT: %s", _TL("no projection type defined")));
1644 
1645  return( false );
1646  }
1647 
1648  //-----------------------------------------------------
1649  // GEOCCS["<name>
1650  // DATUM ["<name>
1651  // SPHEROID["<name>", <semi-major axis>, <inverse flattening>],
1652  // *TOWGS84 [<dx>, <dy>, <dz>, <rx>, <ry>, <rz>, <sc>]
1653  // ],
1654  // PRIMEM ["<name>", <longitude>],
1655  // UNIT ["<name>", <conversion factor>],
1656  // *AXIS ["<name>", NORTH|SOUTH|EAST|WEST|UP|DOWN|OTHER],
1657  // *AXIS ["<name>", NORTH|SOUTH|EAST|WEST|UP|DOWN|OTHER]
1658  // ]
1659 
1660  if( !ProjCS.CmpNoCase("geocent") )
1661  {
1662  WKT = "GEOGCS[\"GCS\"";
1663 
1664  if( _Proj4_Get_Datum (Value, Proj4) ) { WKT += "," + Value; }
1665  if( _Proj4_Get_Prime_Meridian(Value, Proj4) ) { WKT += "," + Value; }
1666  if( _Proj4_Get_Unit (Value, Proj4) ) { WKT += "," + Value; }
1667 
1668  WKT += "]";
1669 
1670  return( true );
1671  }
1672 
1673  //-----------------------------------------------------
1674  // GEOGCS["<name>
1675  // DATUM ["<name>
1676  // SPHEROID["<name>", <semi-major axis>, <inverse flattening>],
1677  // *TOWGS84 [<dx>, <dy>, <dz>, <rx>, <ry>, <rz>, <sc>]
1678  // ],
1679  // PRIMEM ["<name>", <longitude>],
1680  // UNIT ["<name>", <conversion factor>],
1681  // *AXIS ["<name>", NORTH|SOUTH|EAST|WEST|UP|DOWN|OTHER],
1682  // *AXIS ["<name>", NORTH|SOUTH|EAST|WEST|UP|DOWN|OTHER]
1683  // ]
1684 
1685  CSG_String GeogCS = "GEOGCS[\"GCS\"";
1686 
1687  if( _Proj4_Get_Datum (Value, Proj4) ) { GeogCS += "," + Value; }
1688  if( _Proj4_Get_Prime_Meridian(Value, Proj4) ) { GeogCS += "," + Value; }
1689  if( _Proj4_Get_Unit (Value, Proj4) ) { GeogCS += "," + Value; } else { GeogCS += "UNIT[\"degree\",0.01745329251994328]"; }
1690 
1691  GeogCS += "]";
1692 
1693  if( !ProjCS.CmpNoCase("lonlat") || !ProjCS.CmpNoCase("longlat")
1694  || !ProjCS.CmpNoCase("latlon") || !ProjCS.CmpNoCase("latlong") )
1695  {
1696  WKT = GeogCS;
1697 
1698  return( true );
1699  }
1700 
1701  //-----------------------------------------------------
1702  // PROJCS["<name>
1703  // GEOGCS [ ...... ],
1704  // PROJECTION["<name>"],
1705  // *PARAMETER ["<name>", <value>], ...
1706  // UNIT ["<name>", <conversion factor>],
1707  // *AXIS ["<name>", NORTH|SOUTH|EAST|WEST|UP|DOWN|OTHER],
1708  // *AXIS ["<name>", NORTH|SOUTH|EAST|WEST|UP|DOWN|OTHER]
1709  // ]
1710 
1711  if( !m_Proj4_to_WKT.Get_Translation(ProjCS, Value) )
1712  {
1713  SG_UI_Msg_Add_Error(CSG_String::Format("Proj4 >> WKT: %s [%s]", _TL("no translation available"), ProjCS.c_str()));
1714 
1715  // return( false );
1716  }
1717 
1718  //-----------------------------------------------------
1719  // UTM ...
1720 
1721  if( !ProjCS.CmpNoCase("utm") )
1722  {
1723  double Zone;
1724 
1725  if( !_Proj4_Read_Parameter(Value, Proj4, "zone") || !Value.asDouble(Zone) )
1726  {
1727  SG_UI_Msg_Add_Error(CSG_String::Format("Proj4 >> WKT: %s", _TL("invalid utm zone")));
1728 
1729  return( false );
1730  }
1731 
1732  bool South = _Proj4_Find_Parameter(Proj4, "south");
1733 
1734  WKT = CSG_String::Format("PROJCS[\"UTM zone %d%c\",%s,PROJECTION[Transverse_Mercator]", (int)Zone, South ? 'S' : 'N', GeogCS.c_str());
1735 
1736  WKT += CSG_String::Format(",PARAMETER[\"%s\",%d]", SG_T("latitude_of_origin"), 0);
1737  WKT += CSG_String::Format(",PARAMETER[\"%s\",%d]", SG_T("central_meridian" ), (int)(Zone * 6 - 183));
1738  WKT += CSG_String::Format(",PARAMETER[\"%s\",%f]", SG_T("scale_factor" ), 0.9996);
1739  WKT += CSG_String::Format(",PARAMETER[\"%s\",%d]", SG_T("false_easting" ), 500000);
1740  WKT += CSG_String::Format(",PARAMETER[\"%s\",%d]", SG_T("false_northing" ), South ? 10000000 : 0);
1741  WKT += ",UNIT[\"metre\",1]]";
1742 
1743  return( true );
1744  }
1745 
1746  //-----------------------------------------------------
1747  // Parameters ...
1748 
1749  WKT = CSG_String::Format("PROJCS[\"%s\",%s,PROJECTION[%s]", Value.c_str(), GeogCS.c_str(), Value.c_str());
1750 
1751  ProjCS = Proj4;
1752 
1753  while( ProjCS.Find('+') >= 0 )
1754  {
1755  CSG_String Key;
1756 
1757  ProjCS = ProjCS.AfterFirst ('+');
1758  Value = ProjCS.BeforeFirst('=');
1759 
1760  if( m_Proj4_to_WKT.Get_Translation(Value, Key) )
1761  {
1762  Value = ProjCS.AfterFirst('=');
1763 
1764  if( Value.Find('+') >= 0 )
1765  {
1766  Value = Value.BeforeFirst('+');
1767  }
1768 
1769  WKT += ",PARAMETER[\"" + Key + "\"," + Value + "]";
1770  }
1771  }
1772 
1773  //-----------------------------------------------------
1774  // Unit ...
1775 
1776  if( _Proj4_Get_Unit(Value, Proj4) ) { WKT += "," + Value; }
1777 
1778  //-----------------------------------------------------
1779  WKT += "]";
1780 
1781  return( true );
1782 }
1783 
1784 
1786 // //
1787 // //
1788 // //
1790 
1791 //---------------------------------------------------------
1793 {
1794  if( !Identifier.CmpNoCase("PROJCS") ) { return( ESG_CRS_Type::Projection ); }
1795  if( !Identifier.CmpNoCase("GEOGCS") ) { return( ESG_CRS_Type::Geographic ); }
1796  if( !Identifier.CmpNoCase("GEOCCS") ) { return( ESG_CRS_Type::Geocentric ); }
1797 
1798  return( ESG_CRS_Type::Undefined );
1799 }
1800 
1801 //---------------------------------------------------------
1803 {
1804  switch( Type )
1805  {
1806  case ESG_CRS_Type::Projection: return( "PROJCS" );
1807  case ESG_CRS_Type::Geographic: return( "GEOGCS" );
1808  case ESG_CRS_Type::Geocentric: return( "GEOCCS" );
1809  default : return( "UNDEFINED" );
1810  }
1811 }
1812 
1813 //---------------------------------------------------------
1815 {
1816  switch( Type )
1817  {
1818  case ESG_CRS_Type::Projection: return( _TL("Projected Coordinate System" ) );
1819  case ESG_CRS_Type::Geographic: return( _TL("Geographic Coordinate System") );
1820  case ESG_CRS_Type::Geocentric: return( _TL("Geocentric Coordinate System") );
1821  default : return( _TL("Undefined Coordinate System" ) );
1822  }
1823 }
1824 
1825 //---------------------------------------------------------
1827 {
1828  for(int i=0; i<(int)ESG_Projection_Unit::Undefined; i++)
1829  {
1831 
1832  if( !Identifier.CmpNoCase(Get_Unit_Identifier(Unit))
1833  || !Identifier.CmpNoCase(Get_Unit_Name (Unit)) )
1834  {
1835  return( Unit );
1836  }
1837  }
1838 
1839  return( !Identifier.CmpNoCase("metre") ? ESG_Projection_Unit::Meter : ESG_Projection_Unit::Undefined );
1840 }
1841 
1842 //---------------------------------------------------------
1844 {
1845  switch( Unit )
1846  {
1847  case ESG_Projection_Unit::Kilometer : return( "km" ); // Kilometers
1848  case ESG_Projection_Unit::Meter : return( "m" ); // Meters
1849  case ESG_Projection_Unit::Decimeter : return( "dm" ); // Decimeters
1850  case ESG_Projection_Unit::Centimeter : return( "cm" ); // Centimeters
1851  case ESG_Projection_Unit::Millimeter : return( "mm" ); // Millimeters
1852  case ESG_Projection_Unit::Int_Nautical_Mile: return( "kmi" ); // Miles
1853  case ESG_Projection_Unit::Int_Inch : return( "in" ); // Inches
1854  case ESG_Projection_Unit::Int_Foot : return( "ft" ); // Feet
1855  case ESG_Projection_Unit::Int_Yard : return( "yd" ); // Yards
1856  case ESG_Projection_Unit::Int_Statute_Mile : return( "mi" ); // Miles
1857  case ESG_Projection_Unit::Int_Fathom : return( "fath" ); // Fathoms
1858  case ESG_Projection_Unit::Int_Chain : return( "ch" ); // Chains
1859  case ESG_Projection_Unit::Int_Link : return( "link" ); // Links
1860  case ESG_Projection_Unit::US_Inch : return( "us-in" ); // Inches
1861  case ESG_Projection_Unit::US_Foot : return( "us-ft" ); // Feet
1862  case ESG_Projection_Unit::US_Yard : return( "us-yd" ); // Yards
1863  case ESG_Projection_Unit::US_Chain : return( "us-ch" ); // Chains
1864  case ESG_Projection_Unit::US_Statute_Mile : return( "us-mi" ); // Miles
1865  case ESG_Projection_Unit::Indian_Yard : return( "ind-yd" ); // Yards
1866  case ESG_Projection_Unit::Indian_Foot : return( "ind-ft" ); // Feet
1867  case ESG_Projection_Unit::Indian_Chain : return( "ind-ch" ); // Chains
1868  default: return( "" );
1869  };
1870 }
1871 
1872 //---------------------------------------------------------
1874 {
1875  switch( Unit )
1876  {
1877  case ESG_Projection_Unit::Kilometer : return( bSimple ? "Kilometers" : "Kilometer" );
1878  case ESG_Projection_Unit::Meter : return( bSimple ? "Meters" : "Meter" );
1879  case ESG_Projection_Unit::Decimeter : return( bSimple ? "Decimeters" : "Decimeter" );
1880  case ESG_Projection_Unit::Centimeter : return( bSimple ? "Centimeters" : "Centimeter" );
1881  case ESG_Projection_Unit::Millimeter : return( bSimple ? "Millimeters" : "Millimeter" );
1882  case ESG_Projection_Unit::Int_Nautical_Mile: return( bSimple ? "Miles" : "International Nautical Mile" );
1883  case ESG_Projection_Unit::Int_Inch : return( bSimple ? "Inches" : "International Inch" );
1884  case ESG_Projection_Unit::Int_Foot : return( bSimple ? "Feet" : "International Foot" );
1885  case ESG_Projection_Unit::Int_Yard : return( bSimple ? "Yards" : "International Yard" );
1886  case ESG_Projection_Unit::Int_Statute_Mile : return( bSimple ? "Miles" : "International Statute Mile" );
1887  case ESG_Projection_Unit::Int_Fathom : return( bSimple ? "Fathoms" : "International Fathom" );
1888  case ESG_Projection_Unit::Int_Chain : return( bSimple ? "Chains" : "International Chain" );
1889  case ESG_Projection_Unit::Int_Link : return( bSimple ? "Links" : "International Link" );
1890  case ESG_Projection_Unit::US_Inch : return( bSimple ? "Inches" : "U.S. Surveyor's Inch" );
1891  case ESG_Projection_Unit::US_Foot : return( bSimple ? "Feet" : "U.S. Surveyor's Foot" );
1892  case ESG_Projection_Unit::US_Yard : return( bSimple ? "Yards" : "U.S. Surveyor's Yard" );
1893  case ESG_Projection_Unit::US_Chain : return( bSimple ? "Chains" : "U.S. Surveyor's Chain" );
1894  case ESG_Projection_Unit::US_Statute_Mile : return( bSimple ? "Miles" : "U.S. Surveyor's Statute Mile" );
1895  case ESG_Projection_Unit::Indian_Yard : return( bSimple ? "Yards" : "Indian Yard" );
1896  case ESG_Projection_Unit::Indian_Foot : return( bSimple ? "Feet" : "Indian Foot" );
1897  case ESG_Projection_Unit::Indian_Chain : return( bSimple ? "Chains" : "Indian Chain" );
1898  default: return( "" );
1899  }
1900 }
1901 
1902 //---------------------------------------------------------
1904 {
1905  switch( Unit )
1906  {
1907  case ESG_Projection_Unit::Kilometer : return( 1000. );
1908  case ESG_Projection_Unit::Meter : return( 1. );
1909  case ESG_Projection_Unit::Decimeter : return( 0.1 );
1910  case ESG_Projection_Unit::Centimeter : return( 0.01 );
1911  case ESG_Projection_Unit::Millimeter : return( 0.001 );
1912  case ESG_Projection_Unit::Int_Nautical_Mile: return( 1852. );
1913  case ESG_Projection_Unit::Int_Inch : return( 0.0254 );
1914  case ESG_Projection_Unit::Int_Foot : return( 0.3048 );
1915  case ESG_Projection_Unit::Int_Yard : return( 0.9144 );
1916  case ESG_Projection_Unit::Int_Statute_Mile : return( 1609.344 );
1917  case ESG_Projection_Unit::Int_Fathom : return( 1.8288 );
1918  case ESG_Projection_Unit::Int_Chain : return( 20.1168 );
1919  case ESG_Projection_Unit::Int_Link : return( 0.201168 );
1920  case ESG_Projection_Unit::US_Inch : return( 1. / 39.37 );
1921  case ESG_Projection_Unit::US_Foot : return( 0.304800609601219 );
1922  case ESG_Projection_Unit::US_Yard : return( 0.914401828803658 );
1923  case ESG_Projection_Unit::US_Chain : return( 20.11684023368047 );
1924  case ESG_Projection_Unit::US_Statute_Mile : return( 1609.347218694437 );
1925  case ESG_Projection_Unit::Indian_Yard : return( 0.91439523 );
1926  case ESG_Projection_Unit::Indian_Foot : return( 0.30479841 );
1927  case ESG_Projection_Unit::Indian_Chain : return( 20.11669506 );
1928  default : return( 1. );
1929  }
1930 }
1931 
1932 
1934 // //
1935 // //
1936 // //
1938 
1939 //---------------------------------------------------------
1940 bool CSG_Projections::_Set_Dictionary(CSG_Table &Dictionary, int Direction)
1941 {
1942  const char Translation[][4][128] = {
1943 // { PROJ4 , DIR , WELL-KNOWN-TEXT , DESCRIPTION, *) projection type not verified
1944 
1945 // --- projection types ---
1946  { "aea" , " ", "Albers_Conic_Equal_Area" , "Albers Equal Area" },
1947  { "aea" , "<", "Albers" , "[ESRI] Albers Equal Area" },
1948  { "aeqd" , " ", "Azimuthal_Equidistant" , "Azimuthal Equidistant" },
1949  { "airy" , " ", "Airy 1830" , "Airy 1830" },
1950  { "aitoff" , " ", "Sphere_Aitoff" , "Aitoff" },
1951  { "alsk" , " ", "Mod_Stererographics_of_Alaska" , "*) Mod. Stererographics of Alaska" },
1952  { "Amersfoort" , "<", "D_Amersfoort" , "[ESRI] datum RD_NEW" },
1953  { "Amersfoort" , "<", "GCS_Amersfoort" , "[ESRI] GCS RD_NEW" },
1954  { "Amersfoort / RD New", "<", "Amersfoort_RD_New" , "[ESRI] RD_NEW" },
1955  { "apian" , " ", "Apian_Globular_I" , "*) Apian Globular I" },
1956  { "august" , " ", "August_Epicycloidal" , "*) August Epicycloidal" },
1957  { "bacon" , " ", "Bacon_Globular" , "*) Bacon Globular" },
1958  { "bipc" , " ", "Bipolar_conic_of_western_hemisphere" , "*) Bipolar conic of western hemisphere" },
1959  { "boggs" , " ", "Boggs_Eumorphic" , "*) Boggs Eumorphic" },
1960  { "bonne" , " ", "Bonne" , "Bonne (Werner lat_1=90)" },
1961  { "cass" , " ", "Cassini_Soldner" , "Cassini" },
1962  { "cass" , "<", "Cassini" , "[ESRI] Cassini" },
1963  { "cc" , " ", "Central_Cylindrical" , "*) Central Cylindrical" },
1964  { "cea" , " ", "Cylindrical_Equal_Area" , "Equal Area Cylindrical, alias: Lambert Cyl.Eq.A., Normal Authalic Cyl. (FME), Behrmann (SP=30), Gall Orthogr. (SP=45)" },
1965  { "cea" , "<", "Behrmann" , "[ESRI] Behrmann (standard parallel = 30)" },
1966  { "chamb" , " ", "Chamberlin_Trimetric" , "*) Chamberlin Trimetric" },
1967  { "collg" , " ", "Collignon" , "*) Collignon" },
1968  { "crast" , " ", "Craster_Parabolic" , "[ESRI] Craster Parabolic (Putnins P4)" },
1969  { "denoy" , " ", "Denoyer_Semi_Elliptical" , "*) Denoyer Semi-Elliptical" },
1970  { "eck1" , " ", "Eckert_I" , "*) Eckert I" },
1971  { "eck2" , " ", "Eckert_II" , "*) Eckert II" },
1972  { "eck3" , " ", "Eckert_III" , "*) Eckert III" },
1973  { "eck4" , " ", "Eckert_IV" , "Eckert IV" },
1974  { "eck5" , " ", "Eckert_V" , "*) Eckert V" },
1975  { "eck6" , " ", "Eckert_VI" , "Eckert VI" },
1976  { "eqearth" , " ", "Equal_Earth" , "*) Equal Earth" },
1977  { "eqc" , " ", "Equirectangular" , "Equidistant Cylindrical (Plate Caree)" },
1978  { "eqc" , "<", "Equidistant_Cylindrical" , "[ESRI] Equidistant Cylindrical (Plate Caree)" },
1979  { "eqc" , "<", "Plate_Carree" , "[ESRI] Equidistant Cylindrical (Plate Caree)" },
1980  { "eqdc" , " ", "Equidistant_Conic" , "*) Equidistant Conic" },
1981  { "euler" , " ", "Euler" , "*) Euler" },
1982  { "etmerc" , " ", "Extended_Transverse_Mercator" , "*) Extended Transverse Mercator" },
1983  { "fahey" , " ", "Fahey" , "*) Fahey" },
1984  { "fouc" , " ", "Foucault" , "*) Foucaut" },
1985  { "fouc_s" , " ", "Foucault_Sinusoidal" , "*) Foucaut Sinusoidal" },
1986  { "gall" , " ", "Gall_Stereographic" , "Gall (Gall Stereographic)" },
1987  { "geocent" , " ", "Geocentric" , "*) Geocentric" },
1988  { "geos" , " ", "GEOS" , "Geostationary Satellite View" },
1989  { "gins8" , " ", "Ginsburg_VIII" , "*) Ginsburg VIII (TsNIIGAiK)" },
1990  { "gn_sinu" , " ", "General_Sinusoidal_Series" , "*) General Sinusoidal Series" },
1991  { "gnom" , " ", "Gnomonic" , "Gnomonic" },
1992  { "goode" , " ", "Goode_Homolosine" , "*) Goode Homolosine" },
1993  { "gs48" , " ", "Mod_Stererographics_48" , "*) Mod. Stererographics of 48 U.S." },
1994  { "gs50" , " ", "Mod_Stererographics_50" , "*) Mod. Stererographics of 50 U.S." },
1995  { "hammer" , " ", "Hammer_Eckert_Greifendorff" , "*) Hammer & Eckert-Greifendorff" },
1996  { "hatano" , " ", "Hatano_Asymmetrical_Equal_Area" , "*) Hatano Asymmetrical Equal Area" },
1997  { "igh" , " ", "Interrupted_Goodes_Homolosine" , "*) Interrupted Goode's Homolosine" },
1998  { "igh_o" , " ", "Interrupted_Goodes_Homolosine_Ocean" , "*) Interrupted Goode's Homolosine (Ocean)" },
1999  { "imw_p" , " ", "International_Map_of_the_World_Polyconic" , "*) International Map of the World Polyconic" },
2000  { "kav5" , " ", "Kavraisky_V" , "*) Kavraisky V" },
2001  { "kav7" , " ", "Kavraisky_VII" , "*) Kavraisky VII" },
2002  { "krovak" , " ", "Krovak" , "Krovak" },
2003  { "labrd" , " ", "Laborde_Oblique_Mercator" , "*) Laborde" },
2004  { "laea" , " ", "Lambert_Azimuthal_Equal_Area" , "Lambert Azimuthal Equal Area" },
2005  { "lagrng" , " ", "Lagrange" , "*) Lagrange" },
2006  { "larr" , " ", "Larrivee" , "*) Larrivee" },
2007  { "lask" , " ", "Laskowski" , "*) Laskowski" },
2008  { "lcc" , "<", "Lambert_Conformal_Conic_1SP" , "Lambert Conformal Conic (1 standard parallel)" },
2009  { "lcc" , "<", "Lambert_Conformal_Conic_2SP" , "Lambert Conformal Conic (2 standard parallels)" },
2010  { "lcc" , " ", "Lambert_Conformal_Conic" , "Lambert Conformal Conic" },
2011  { "lcca" , " ", "Lambert_Conformal_Conic_Alternative" , "*) Lambert Conformal Conic Alternative" },
2012  { "leac" , " ", "Lambert_Equal_Area_Conic" , "*) Lambert Equal Area Conic" },
2013  { "lee_os" , " ", "Lee_Oblated_Stereographic" , "*) Lee Oblated Stereographic" },
2014  { "loxim" , " ", "Loximuthal" , "[ESRI] Loximuthal" },
2015  { "lsat" , " ", "Space_oblique_for_LANDSAT" , "*) Space oblique for LANDSAT" },
2016  { "mbt_s" , " ", "McBryde_Thomas_Flat_Polar_Sine" , "*) McBryde-Thomas Flat-Polar Sine" },
2017  { "mbt_fps" , " ", "McBryde_Thomas_Flat_Polar_Sine_2" , "*) McBryde-Thomas Flat-Pole Sine (No. 2)" },
2018  { "mbtfpp" , " ", "McBryde_Thomas_Flat_Polar_Parabolic" , "*) McBride-Thomas Flat-Polar Parabolic" },
2019  { "mbtfpq" , " ", "Flat_Polar_Quartic" , "[ESRI] McBryde-Thomas Flat-Polar Quartic" },
2020  { "mbtfps" , " ", "McBryde_Thomas_Flat_Polar_Sinusoidal" , "*) McBryde-Thomas Flat-Polar Sinusoidal" },
2021  { "merc" , " ", "Mercator" , "[ESRI] Mercator" },
2022  { "merc" , "<", "Mercator_1SP" , "Mercator (1 standard parallel)" },
2023  { "merc" , "<", "Mercator_2SP" , "Mercator (2 standard parallels)" },
2024  { "mil_os" , " ", "Miller_Oblated_Stereographic" , "*) Miller Oblated Stereographic" },
2025  { "mill" , " ", "Miller_Cylindrical" , "Miller Cylindrical" },
2026  { "moll" , " ", "Mollweide" , "Mollweide" },
2027  { "murd1" , " ", "Murdoch_I" , "*) Murdoch I" },
2028  { "murd2" , " ", "Murdoch_II" , "*) Murdoch II" },
2029  { "murd3" , " ", "Murdoch_III" , "*) Murdoch III" },
2030  { "nell" , " ", "Nell" , "*) Nell" },
2031  { "nell_h" , " ", "Nell_Hammer" , "*) Nell-Hammer" },
2032  { "nicol" , " ", "Nicolosi_Globular" , "*) Nicolosi Globular" },
2033  { "nsper" , " ", "Near_sided_perspective" , "*) Near-sided perspective" },
2034  { "nzmg" , " ", "New_Zealand_Map_Grid" , "New Zealand Map Grid" },
2035  { "ob_tran" , " ", "General_Oblique_Transformation" , "*) General Oblique Transformation" },
2036  { "ocea" , " ", "Oblique_Cylindrical_Equal_Area" , "*) Oblique Cylindrical Equal Area" },
2037  { "oea" , " ", "Oblated_Equal_Area" , "*) Oblated Equal Area" },
2038  { "omerc" , " ", "Hotine_Oblique_Mercator" , "Oblique Mercator" },
2039  { "omerc" , "<", "Oblique_Mercator" , "Oblique Mercator" },
2040  { "ortel" , " ", "Ortelius_Oval" , "*) Ortelius Oval" },
2041  { "ortho" , " ", "Orthographic" , "Orthographic (ESRI: World from Space)" },
2042  { "pconic" , " ", "Perspective_Conic" , "*) Perspective Conic" },
2043  { "poly" , " ", "Polyconic" , "*) Polyconic (American)" },
2044  { "putp1" , " ", "Putnins_P1" , "*) Putnins P1" },
2045  { "putp2" , " ", "Putnins_P2" , "*) Putnins P2" },
2046  { "putp3" , " ", "Putnins_P3" , "*) Putnins P3" },
2047  { "putp3p" , " ", "Putnins_P3'" , "*) Putnins P3'" },
2048  { "putp4p" , " ", "Putnins_P4'" , "*) Putnins P4'" },
2049  { "putp5" , " ", "Putnins_P5" , "*) Putnins P5" },
2050  { "putp5p" , " ", "Putnins_P5'" , "*) Putnins P5'" },
2051  { "putp6" , " ", "Putnins_P6" , "*) Putnins P6" },
2052  { "putp6p" , " ", "Putnins_P6'" , "*) Putnins P6'" },
2053  { "qua_aut" , " ", "Quartic_Authalic" , "[ESRI] Quart c Authalic" },
2054  { "robin" , " ", "Robinson" , "Robinson" },
2055  { "rouss" , " ", "Roussilhe_Stereographic" , "*) Roussilhe Stereographic" },
2056  { "rpoly" , " ", "Rectangular_Polyconic" , "*) Rectangular Polyconic" },
2057  { "sinu" , " ", "Sinusoidal" , "Sinusoidal (Sanson-Flamsteed)" },
2058  { "somerc" , " ", "Hotine_Oblique_Mercator" , "Swiss Oblique Mercator" },
2059  { "somerc" , "<", "Swiss_Oblique_Cylindrical" , "Swiss Oblique Cylindrical" },
2060  { "somerc" , "<", "Hotine_Oblique_Mercator_Azimuth_Center" , "[ESRI] Swiss Oblique Mercator/Cylindrical" },
2061  { "stere" , "<", "Polar_Stereographic" , "Stereographic" },
2062  { "stere" , " ", "Stereographic" , "[ESRI] Stereographic" },
2063  { "sterea" , " ", "Oblique_Stereographic" , "Oblique Stereographic Alternative" },
2064  { "sterea" , "<", "Double_Stereographic" , "[ESRI]" },
2065  { "gstmerc" , " ", "Gauss_Schreiber_Transverse_Mercator" , "*) Gauss-Schreiber Transverse Mercator (aka Gauss-Laborde Reunion)" },
2066  { "tcc" , " ", "Transverse_Central_Cylindrical" , "*) Transverse Central Cylindrical" },
2067  { "tcea" , " ", "Transverse_Cylindrical_Equal_Area" , "*) Transverse Cylindrical Equal Area" },
2068  { "tissot" , " ", "Tissot_Conic" , "*) Tissot Conic" },
2069  { "tmerc" , " ", "Transverse_Mercator" , "*) Transverse Mercator" },
2070  { "tmerc" , "<", "Gauss_Kruger" , "[ESRI] DHDN" },
2071  { "tpeqd" , " ", "Two_Point_Equidistant" , "*) Two Point Equidistant" },
2072  { "tpers" , " ", "Tilted_perspective" , "*) Tilted perspective" },
2073  { "ups" , " ", "Universal_Polar_Stereographic" , "*) Universal Polar Stereographic" },
2074  { "urm5" , " ", "Urmaev_V" , "*) Urmaev V" },
2075  { "urmfps" , " ", "Urmaev_Flat_Polar_Sinusoidal" , "*) Urmaev Flat-Polar Sinusoidal" },
2076  { "utm" , ">", "Transverse_Mercator" , "*) Universal Transverse Mercator (UTM)" },
2077  { "vandg" , "<", "Van_Der_Grinten_I" , "[ESRI] van der Grinten (I)" },
2078  { "vandg" , " ", "VanDerGrinten" , "van der Grinten (I)" },
2079  { "vandg2" , " ", "VanDerGrinten_II" , "*) van der Grinten II" },
2080  { "vandg3" , " ", "VanDerGrinten_III" , "*) van der Grinten III" },
2081  { "vandg4" , " ", "VanDerGrinten_IV" , "*) van der Grinten IV" },
2082  { "vitk1" , " ", "Vitkovsky_I" , "*) Vitkovsky I" },
2083  { "wag1" , " ", "Wagner_I" , "*) Wagner I (Kavraisky VI)" },
2084  { "wag2" , " ", "Wagner_II" , "*) Wagner II" },
2085  { "wag3" , " ", "Wagner_III" , "*) Wagner III" },
2086  { "wag4" , " ", "Wagner_IV" , "*) Wagner IV" },
2087  { "wag5" , " ", "Wagner_V" , "*) Wagner V" },
2088  { "wag6" , " ", "Wagner_VI" , "*) Wagner VI" },
2089  { "wag7" , " ", "Wagner_VII" , "*) Wagner VII" },
2090  { "webmerc" , " ", "Mercator_1SP" , "Web Mercator" },
2091  { "webmerc" , "<", "Mercator_Auxiliary_Sphere" , "[ESRI] Web Mercator" },
2092  { "weren" , " ", "Werenskiold_I" , "*) Werenskiold I" },
2093  { "wink1" , " ", "Winkel_I" , "[ESRI] Winkel I" },
2094  { "wink2" , " ", "Winkel_II" , "[ESRI] Winkel II" },
2095  { "wintri" , " ", "Winkel_Tripel" , "[ESRI] Winkel Tripel" },
2096 
2097 // --- general projection parameters ---
2098  { "alpha" , " ", "azimuth" , "? Used with Oblique Mercator and possibly a few others" },
2099  { "k" , ">", "scale_factor" , "Scaling factor (old name)" },
2100  { "K" , ">", "scale_factor" , "? Scaling factor (old name)" },
2101  { "k_0" , " ", "scale_factor" , "Scaling factor (new name)" },
2102  { "lat_0" , " ", "latitude_of_origin" , "Latitude of origin" },
2103  { "lat_0" , "<", "latitude_of_center" , "Latitude of center" },
2104  { "lat_0" , "<", "central_parallel" , "[ESRI] Latitude of center" },
2105  { "lat_1" , " ", "standard_parallel_1" , "Latitude of first standard parallel" },
2106  { "lat_2" , " ", "standard_parallel_2" , "Latitude of second standard parallel" },
2107  { "lat_ts" , ">", "latitude_of_origin" , "Latitude of true scale" },
2108  { "lon_0" , " ", "central_meridian" , "Central meridian" },
2109  { "lon_0" , "<", "longitude_of_center" , "Longitude of center" },
2110  { "lonc" , ">", "longitude_of_center" , "? Longitude used with Oblique Mercator and possibly a few others" },
2111  { "x_0" , " ", "false_easting" , "False easting" },
2112  { "y_0" , " ", "false_northing" , "False northing" },
2113 
2114 // --- special projection parameters ---
2115 // { "azi" , " ", "", "" },
2116 // { "belgium" , " ", "", "" },
2117 // { "beta" , " ", "", "" },
2118 // { "czech" , " ", "", "" },
2119 // { "gamma" , " ", "", "" },
2120 // { "geoc" , " ", "", "" },
2121 // { "guam" , " ", "", "" },
2122  { "h" , " ", "satellite_height", "Satellite height (geos - Geostationary Satellite View)" },
2123 // { "lat_b" , " ", "", "" },
2124 // { "lat_t" , " ", "", "" },
2125 // { "lon_1" , " ", "", "" },
2126 // { "lon_2" , " ", "", "" },
2127 // { "lsat" , " ", "", "" },
2128 // { "m" , " ", "", "" },
2129 // { "M" , " ", "", "" },
2130 // { "n" , " ", "", "" },
2131 // { "no_cut" , " ", "", "" },
2132 // { "no_off" , " ", "", "" },
2133 // { "no_rot" , " ", "", "" },
2134 // { "ns" , " ", "", "" },
2135 // { "o_alpha" , " ", "", "" },
2136 // { "o_lat_1" , " ", "", "" },
2137 // { "o_lat_2" , " ", "", "" },
2138 // { "o_lat_c" , " ", "", "" },
2139 // { "o_lat_p" , " ", "", "" },
2140 // { "o_lon_1" , " ", "", "" },
2141 // { "o_lon_2" , " ", "", "" },
2142 // { "o_lon_c" , " ", "", "" },
2143 // { "o_lon_p" , " ", "", "" },
2144 // { "o_proj" , " ", "", "" },
2145 // { "over" , " ", "", "" },
2146 // { "p" , " ", "", "" },
2147 // { "path" , " ", "", "" },
2148 // { "q" , " ", "", "" },
2149 // { "R" , " ", "", "" },
2150 // { "R_a" , " ", "", "" },
2151 // { "R_A" , " ", "", "" },
2152 // { "R_g" , " ", "", "" },
2153 // { "R_h" , " ", "", "" },
2154 // { "R_lat_a" , " ", "", "" },
2155 // { "R_lat_g" , " ", "", "" },
2156 // { "rot" , " ", "", "" },
2157 // { "R_V" , " ", "", "" },
2158 // { "s" , " ", "", "" },
2159 // { "sym" , " ", "", "" },
2160 // { "t" , " ", "", "" },
2161 // { "theta" , " ", "", "" },
2162 // { "tilt" , " ", "", "" },
2163 // { "vopt" , " ", "", "" },
2164 // { "W" , " ", "", "" },
2165 // { "westo" , " ", "", "" },
2166 
2167 // --- core projection types and parameters that don't require explicit translation ---
2168 // { "lonlat" , " ", "GEOGCS", "Lat/long (Geodetic)" },
2169 // { "latlon" , ">", "GEOGCS", "Lat/long (Geodetic alias)" },
2170 // { "latlong" , ">", "GEOGCS", "Lat/long (Geodetic alias)" },
2171 // { "longlat" , ">", "GEOGCS", "Lat/long (Geodetic alias)" },
2172 
2173 // { "a" , " ", "", "Semimajor radius of the ellipsoid axis" },
2174 // { "axis" , " ", "", "Axis orientation (new in 4.8.0)" },
2175 // { "b , " ", "", "Semiminor radius of the ellipsoid axis" },
2176 // { "datum , " ", "", "Datum name (see `proj -ld`)" },
2177 // { "ellps , " ", "", "Ellipsoid name (see `proj -le`)" },
2178 // { "nadgrids , " ", "", "Filename of NTv2 grid file to use for datum transforms (see below)" },
2179 // { "no_defs , " ", "", "Don't use the /usr/share/proj/proj_def.dat defaults file" },
2180 // { "pm , " ", "", "Alternate prime meridian (typically a city name, see below)" },
2181 // { "proj , " ", "", "Projection name (see `proj -l`)" },
2182 // { "to_meter , " ", "", "Multiplier to convert map units to 1.0m" },
2183 // { "towgs84 , " ", "", "3 or 7 term datum transform parameters (see below)" },
2184 // { "units , " ", "", "meters, US survey feet, etc." },
2185 // { "south , " ", "", "Denotes southern hemisphere UTM zone" },
2186 // { "zone , " ", "", "UTM zone" },
2187 // { "lon_wrap" , " ", "", "Center longitude to use for wrapping (see below)" },
2188 // { "over" , " ", "", "Allow longitude output outside -180 to 180 range, disables wrapping (see below)" },
2189  { "", "", "", "" } // end of records
2190 };
2191 
2192  //-----------------------------------------------------
2193  Dictionary.Destroy();
2194  Dictionary.Set_Name("Proj.4-WKT Dictionary");
2195 
2196  if( Direction == 0 )
2197  {
2198  Dictionary.Add_Field("PROJ4", SG_DATATYPE_String);
2199  Dictionary.Add_Field("DIR" , SG_DATATYPE_String);
2200  Dictionary.Add_Field("WKT" , SG_DATATYPE_String);
2201  Dictionary.Add_Field("DESC" , SG_DATATYPE_String);
2202 
2203  for(int i=0; *Translation[i][0]; i++)
2204  {
2205  CSG_Table_Record &Entry = *Dictionary.Add_Record();
2206 
2207  Entry.Set_Value(0, Translation[i][0]);
2208  Entry.Set_Value(1, Translation[i][1]);
2209  Entry.Set_Value(2, Translation[i][2]);
2210  Entry.Set_Value(3, Translation[i][3]);
2211  }
2212  }
2213  else if( Direction > 0 ) // Proj4 to WKT
2214  {
2215  Dictionary.Add_Field("PROJ4", SG_DATATYPE_String);
2216  Dictionary.Add_Field("WKT" , SG_DATATYPE_String);
2217 
2218  for(int i=0; *Translation[i][0]; i++)
2219  {
2220  if( Translation[i][1][0] != '<' ) // only WKT to Proj4
2221  {
2222  CSG_Table_Record &Entry = *Dictionary.Add_Record();
2223 
2224  Entry.Set_Value(0, Translation[i][0]);
2225  Entry.Set_Value(1, Translation[i][2]);
2226  }
2227  }
2228  }
2229  else if( Direction < 0 ) // WKT to Proj4
2230  {
2231  Dictionary.Add_Field("WKT" , SG_DATATYPE_String);
2232  Dictionary.Add_Field("PROJ4", SG_DATATYPE_String);
2233 
2234  for(int i=0; *Translation[i][0]; i++)
2235  {
2236  if( Translation[i][1][0] != '>' ) // only Proj4 to WKT
2237  {
2238  CSG_Table_Record &Entry = *Dictionary.Add_Record();
2239 
2240  Entry.Set_Value(0, Translation[i][2]);
2241  Entry.Set_Value(1, Translation[i][0]);
2242  }
2243  }
2244  }
2245 
2246  return( Dictionary.Get_Count() > 0 );
2247 }
2248 
2249 //---------------------------------------------------------
2250 bool CSG_Projections::_Set_Dictionary(void)
2251 {
2252  CSG_Table Table;
2253 
2254  return( _Set_Dictionary(Table, 1) && m_Proj4_to_WKT.Create(&Table, 0, 1, true)
2255  && _Set_Dictionary(Table, -1) && m_WKT_to_Proj4.Create(&Table, 0, 1, true)
2256  );
2257 }
2258 
2259 
2261 // //
2262 // //
2263 // //
2265 
2266 //---------------------------------------------------------
2267 bool SG_Get_Projected (CSG_Shapes *pSource, CSG_Shapes *pTarget, const CSG_Projection &Target)
2268 {
2269  if( pSource && pSource->is_Valid() && pSource->Get_Projection().is_Okay() && Target.is_Okay() )
2270  {
2271  if( pSource->Get_Projection() == Target )
2272  {
2273  return( pTarget ? pTarget->Create(*pSource) : true );
2274  }
2275 
2276  if( pTarget )
2277  {
2278  pTarget->Create(*pSource); pSource = pTarget;
2279  }
2280 
2281  CSG_Tool *pTool = SG_Get_Tool_Library_Manager().Create_Tool("pj_proj4", 2); // Coordinate Transformation (Shapes)
2282 
2283  if( pTool )
2284  {
2285  CSG_Data_Manager Data; Data.Add(pSource); pTool->Set_Manager(&Data);
2286 
2287  pTool->Set_Parameter("SOURCE" , pSource);
2288  pTool->Set_Parameter("CRS_STRING", Target.Get_WKT());
2289  pTool->Set_Parameter("COPY" , false);
2290  pTool->Set_Parameter("PARALLEL" , true);
2291 
2293  bool bResult = pTool->Execute();
2295 
2296  Data.Delete(pSource, true);
2298 
2299  return( bResult );
2300  }
2301  }
2302 
2303  return( false );
2304 }
2305 
2306 //---------------------------------------------------------
2307 bool SG_Get_Projected (const CSG_Projection &Source, const CSG_Projection &Target, TSG_Point &Point)
2308 {
2309  if( Source == Target )
2310  {
2311  return( true );
2312  }
2313 
2314  if( Source.is_Okay() && Target.is_Okay() )
2315  {
2316  CSG_Tool *pTool = SG_Get_Tool_Library_Manager().Create_Tool("pj_proj4", 29); // Single Coordinate Transformation
2317 
2318  if( pTool )
2319  {
2320  pTool->Set_Manager(NULL);
2321  pTool->Set_Parameter("TARGET_CRS", Target.Get_WKT());
2322  pTool->Set_Parameter("SOURCE_CRS", Source.Get_WKT());
2323  pTool->Set_Parameter("SOURCE_X" , Point.x);
2324  pTool->Set_Parameter("SOURCE_Y" , Point.y);
2325 
2327  bool bResult = pTool->Execute();
2329 
2330  if( bResult )
2331  {
2332  Point.x = pTool->Get_Parameter("TARGET_X")->asDouble();
2333  Point.y = pTool->Get_Parameter("TARGET_Y")->asDouble();
2334  }
2335 
2337 
2338  return( bResult );
2339  }
2340  }
2341 
2342  return( false );
2343 }
2344 
2345 //---------------------------------------------------------
2346 bool SG_Get_Projected (const CSG_Projection &Source, const CSG_Projection &Target, TSG_Rect &Rectangle)
2347 {
2348  if( Source == Target )
2349  {
2350  return( true );
2351  }
2352 
2353  if( Source.is_Okay() && Target.is_Okay() )
2354  {
2355  CSG_Shapes Points(SHAPE_TYPE_Point); Points.Get_Projection().Create(Source);
2356 
2357  Points.Add_Shape()->Add_Point(Rectangle.xMin, Rectangle.yMin);
2358  Points.Add_Shape()->Add_Point(Rectangle.xMin, Rectangle.yMax);
2359  Points.Add_Shape()->Add_Point(Rectangle.xMax, Rectangle.yMax);
2360  Points.Add_Shape()->Add_Point(Rectangle.xMax, Rectangle.yMin);
2361 
2362  if( SG_Get_Projected(&Points, NULL, Target) )
2363  {
2364  Rectangle = Points.Get_Extent();
2365 
2366  return( true );
2367  }
2368  }
2369 
2370  return( false );
2371 }
2372 
2373 
2375 // //
2376 // //
2377 // //
2379 
2380 //---------------------------------------------------------
2382 {
2383  bool bResult = false;
2384 
2385  if( pGrid && pGrid->is_Valid() && pGrid->Get_Projection().is_Okay() && (pLon || pLat) )
2386  {
2387  CSG_Grid Lon; if( !pLon ) { pLon = &Lon; } pLon->Create(pGrid->Get_System());
2388  CSG_Grid Lat; if( !pLat ) { pLat = &Lat; } pLat->Create(pGrid->Get_System());
2389 
2390  SG_RUN_TOOL(bResult, "pj_proj4", 17, // geographic coordinate grids
2391  SG_TOOL_PARAMETER_SET("GRID", pGrid)
2392  && SG_TOOL_PARAMETER_SET("LON" , pLon )
2393  && SG_TOOL_PARAMETER_SET("LAT" , pLat )
2394  )
2395  }
2396 
2397  return( bResult );
2398 }
2399 
2400 
2402 // //
2403 // //
2404 // //
2406 
2407 //---------------------------------------------------------
CSG_String::BeforeFirst
CSG_String BeforeFirst(char Character) const
Definition: api_string.cpp:666
CSG_MetaData::Destroy
void Destroy(void)
Definition: metadata.cpp:140
SG_DATATYPE_Int
@ SG_DATATYPE_Int
Definition: api_core.h:1000
CSG_Projection::Save
bool Save(const CSG_String &File, ESG_CRS_Format Format=ESG_CRS_Format::WKT) const
Definition: projections.cpp:229
SG_T
#define SG_T(s)
Definition: api_core.h:537
CMP_PARAMETER
#define CMP_PARAMETER(a, b)
CSG_String::Printf
int Printf(const char *Format,...)
Definition: api_string.cpp:308
SG_DATATYPE_String
@ SG_DATATYPE_String
Definition: api_core.h:1005
_TL
#define _TL(s)
Definition: api_core.h:1489
CSG_Table::Del_Records
virtual bool Del_Records(void)
Definition: table.cpp:908
CSG_String::Length
size_t Length(void) const
Definition: api_string.cpp:172
CSG_Projection::Get_ESRI
const CSG_String & Get_ESRI(void) const
Definition: geo_tools.h:885
CSG_MetaData::Get_Children_Count
int Get_Children_Count(void) const
Definition: metadata.h:147
CSG_Parameter::asString
const SG_Char * asString(void) const
Definition: parameters.h:285
CSG_MetaData::Get_Content
const CSG_String & Get_Content(void) const
Definition: metadata.h:132
CSG_Table_Record
Definition: table.h:130
CSG_MetaData::Set_Content
void Set_Content(const CSG_String &Content)
Definition: metadata.h:139
data_manager.h
CSG_Projection::Get_Unit_Name
CSG_String Get_Unit_Name(void) const
Definition: projections.cpp:520
SG_Get_String
SAGA_API_DLL_EXPORT CSG_String SG_Get_String(double Value, int Precision=-99)
Definition: api_string.cpp:1337
CSG_String::asInt
int asInt(void) const
Definition: api_string.cpp:722
CSG_Table::Get_Record
virtual CSG_Table_Record * Get_Record(sLong Index) const
Definition: table.h:394
CSG_Grid::Create
bool Create(const CSG_Grid &Grid)
Definition: grid.cpp:230
CSG_Shapes::Create
bool Create(const CSG_Shapes &Shapes)
Definition: shapes.cpp:204
CSG_Projection::~CSG_Projection
virtual ~CSG_Projection(void)
Definition: projections.cpp:87
CSG_Projection::Get_Description
CSG_String Get_Description(bool bDetails=false) const
Definition: projections.cpp:304
CSG_Projection::is_Okay
bool is_Okay(void) const
Definition: geo_tools.h:857
CSG_Tool
Definition: tool.h:151
CSG_Table::Destroy
virtual bool Destroy(void)
Definition: table.cpp:332
CSG_Projections::Get_Unit
static ESG_Projection_Unit Get_Unit(const CSG_String &Identifier)
Definition: projections.cpp:1826
CSG_Tool::Execute
bool Execute(bool bAddHistory=false)
Definition: tool.cpp:258
ADD_PROP
#define ADD_PROP(name, entry, prop)
CSG_Projection::is_Geographic
bool is_Geographic(void) const
Definition: geo_tools.h:893
CSG_Projection::Set_UTM_WGS84
bool Set_UTM_WGS84(int Zone, bool bSouth=false)
Definition: projections.cpp:566
SSG_Rect::xMax
double xMax
Definition: geo_tools.h:465
CSG_Projections::Get_Unit_To_Meter
static double Get_Unit_To_Meter(ESG_Projection_Unit Unit)
Definition: projections.cpp:1903
ESG_CRS_Format::WKT1
@ WKT1
ESG_Projection_Unit
ESG_Projection_Unit
Definition: geo_tools.h:792
PRJ_FIELD_AUTH_SRID
@ PRJ_FIELD_AUTH_SRID
Definition: projections.cpp:617
SG_RUN_TOOL
#define SG_RUN_TOOL(bRetVal, LIBRARY, TOOL, CONDITION)
Definition: tool_library.h:257
PRJ_FIELD_PROJ4TEXT
@ PRJ_FIELD_PROJ4TEXT
Definition: projections.cpp:619
SG_UI_Get_Application_Path
CSG_String SG_UI_Get_Application_Path(bool bPathOnly)
Definition: api_callback.cpp:799
CSG_MetaData::Get_Child
CSG_MetaData * Get_Child(int Index) const
Definition: metadata.h:148
SG_FILE_R
@ SG_FILE_R
Definition: api_core.h:1109
ESG_CRS_Type::Geographic
@ Geographic
CSG_Projections::Get_CRS_Type_Name
static CSG_String Get_CRS_Type_Name(ESG_CRS_Type Type)
Definition: projections.cpp:1814
CSG_Projection::Get_WKT
const CSG_String & Get_WKT(void) const
Definition: geo_tools.h:881
ADD_INFO
#define ADD_INFO(name, value)
SSG_Point
Definition: geo_tools.h:128
CSG_Shapes::is_Valid
virtual bool is_Valid(void) const
Definition: shapes.h:807
CSG_String::Replace
size_t Replace(const CSG_String &sOld, const CSG_String &sNew, bool bReplaceAll=true)
Definition: api_string.cpp:563
CSG_File::Read
size_t Read(void *Buffer, size_t Size, size_t Count=1) const
Definition: api_file.cpp:328
CSG_Projection::Destroy
void Destroy(void)
Definition: projections.cpp:201
CSG_Tool_Library_Manager::Delete_Tool
bool Delete_Tool(CSG_Tool *pTool) const
Definition: tool_library.cpp:725
CSG_Grid::Get_System
const CSG_Grid_System & Get_System(void) const
Definition: grid.h:531
CSG_File
Definition: api_core.h:1124
CSG_String::Cmp
int Cmp(const CSG_String &String) const
Definition: api_string.cpp:515
SSG_Rect::xMin
double xMin
Definition: geo_tools.h:465
CSG_Projection::Get_WKT1
const CSG_String & Get_WKT1(void) const
Definition: geo_tools.h:882
ADD_HEAD
#define ADD_HEAD(name, value)
SSG_Rect
Definition: geo_tools.h:464
CSG_Shapes::Add_Shape
virtual CSG_Shape * Add_Shape(CSG_Table_Record *pCopy=NULL, TSG_ADD_Shape_Copy_Mode mCopy=SHAPE_COPY)
Definition: shapes.cpp:418
CSG_Projections::Create
bool Create(bool LoadDefault=true)
Definition: projections.cpp:641
CSG_Tool::Set_Parameter
bool Set_Parameter(const CSG_String &ID, CSG_Parameter *pValue)
Definition: tool.cpp:1140
SG_File_Exists
SAGA_API_DLL_EXPORT bool SG_File_Exists(const CSG_String &FileName)
Definition: api_file.cpp:850
SG_TOOL_PARAMETER_SET
#define SG_TOOL_PARAMETER_SET(IDENTIFIER, VALUE)
Definition: tool_library.h:351
CSG_MetaData::Cmp_Name
bool Cmp_Name(const CSG_String &String, bool bNoCase=true) const
Definition: metadata.cpp:461
CSG_Projection::Set_GCS_WGS84
bool Set_GCS_WGS84(void)
Definition: projections.cpp:550
SG_STR_MBTOSG
#define SG_STR_MBTOSG(s)
Definition: api_core.h:545
CSG_Table_Record::asString
const SG_Char * asString(int Field, int Decimals=-99) const
Definition: table_record.cpp:461
CMP_TOWGS84
#define CMP_TOWGS84(id)
CSG_Grid::is_Valid
virtual bool is_Valid(void) const
Definition: grid.cpp:433
CSG_Strings::Add
bool Add(const CSG_Strings &Strings)
Definition: api_string.cpp:1022
CSG_Projection::is_Equal
bool is_Equal(const CSG_Projection &Projection) const
Definition: projections.cpp:409
CSG_Projection::Get_Unit_Identifier
CSG_String Get_Unit_Identifier(void) const
Definition: projections.cpp:514
CSG_MetaData::Del_Children
bool Del_Children(int Depth=0, const SG_Char *Name=NULL)
Definition: metadata.cpp:381
CSG_Projections::Get_CRS_Type
static ESG_CRS_Type Get_CRS_Type(const CSG_String &Identifier)
Definition: projections.cpp:1792
CSG_Tool_Library_Manager::Create_Tool
CSG_Tool * Create_Tool(const CSG_String &Library, int Index, bool bWithGUI=false) const
Definition: tool_library.cpp:696
ADD_CONT
#define ADD_CONT(name, entry)
CSG_File::is_Writing
bool is_Writing(void) const
Definition: api_core.h:1145
SG_UI_Msg_Lock
int SG_UI_Msg_Lock(bool bOn)
Definition: api_callback.cpp:472
sLong
signed long long sLong
Definition: api_core.h:158
CSG_Projections::Load
bool Load(const CSG_String &File, bool bAppend=false)
Definition: projections.cpp:809
SG_Get_Tool_Library_Manager
CSG_Tool_Library_Manager & SG_Get_Tool_Library_Manager(void)
Definition: tool_library.cpp:286
CSG_MetaData::Add_Property
bool Add_Property(const CSG_String &Name, const CSG_String &Value)
Definition: metadata.cpp:559
ESG_PROJ_FIELD_ID
ESG_PROJ_FIELD_ID
Definition: projections.cpp:614
CSG_Table::Get_Count
sLong Get_Count(void) const
Definition: table.h:392
CMP_PROPERTY
#define CMP_PROPERTY(a, b, p)
CSG_Projection::CSG_Projection
CSG_Projection(void)
Definition: projections.cpp:82
CSG_Projection::Get_Type
ESG_CRS_Type Get_Type(void) const
Definition: geo_tools.h:897
SG_String_Tokenize
SAGA_API_DLL_EXPORT CSG_Strings SG_String_Tokenize(const CSG_String &String, const CSG_String &Delimiters=SG_DEFAULT_DELIMITERS, TSG_String_Tokenizer_Mode Mode=SG_TOKEN_DEFAULT)
Definition: api_string.cpp:1559
CSG_Translator::Get_Translation
const SG_Char * Get_Translation(int i) const
Definition: api_core.h:1450
SG_Get_Projections
CSG_Projections & SG_Get_Projections(void)
Definition: projections.cpp:69
CSG_Shape::Add_Point
virtual int Add_Point(double x, double y, int iPart=0)=0
CSG_Data_Manager::Delete
bool Delete(CSG_Data_Object *pObject, bool bDetach=false)
Definition: data_manager.cpp:623
CSG_Projections::Get_Projection
CSG_Projection Get_Projection(sLong Index) const
Definition: projections.cpp:741
SG_FILE_W
@ SG_FILE_W
Definition: api_core.h:1110
CSG_Projections::Get_Count
sLong Get_Count(void) const
Definition: projections.cpp:715
SSG_Rect::yMax
double yMax
Definition: geo_tools.h:465
CSG_Projection::Load
bool Load(const CSG_String &File)
Definition: projections.cpp:221
CSG_Strings
Definition: api_core.h:699
CSG_Table::Get_Record_byIndex
CSG_Table_Record * Get_Record_byIndex(sLong Index) const
Definition: table.h:399
ESG_CRS_Format
ESG_CRS_Format
Definition: geo_tools.h:780
CSG_Projections::Parse
static bool Parse(const CSG_String &Definition, CSG_String *WKT1=NULL, CSG_String *WKT2=NULL, CSG_String *PROJ=NULL, CSG_String *ESRI=NULL)
Definition: projections.cpp:845
CSG_Shapes::Get_Extent
virtual const CSG_Rect & Get_Extent(void)
Definition: shapes.h:813
CSG_Data_Manager::Add
CSG_Data_Object * Add(CSG_Data_Object *pObject)
Definition: data_manager.cpp:310
CSG_Data_Object::Set_Name
void Set_Name(const CSG_String &Name)
Definition: dataobject.cpp:300
CSG_Projection::Get_PROJ
const CSG_String & Get_PROJ(void) const
Definition: geo_tools.h:884
CSG_String::Format
static CSG_String Format(const char *Format,...)
Definition: api_string.cpp:270
CSG_String::Find
int Find(char Character, bool fromEnd=false) const
Definition: api_string.cpp:616
CSG_Projection
Definition: geo_tools.h:824
SG_Get_Projected
bool SG_Get_Projected(CSG_Shapes *pSource, CSG_Shapes *pTarget, const CSG_Projection &Target)
Definition: projections.cpp:2267
CSG_Table::Add_Field
virtual bool Add_Field(const CSG_String &Name, TSG_Data_Type Type, int Position=-1)
Definition: table.cpp:481
CSG_Table
Definition: table.h:283
CSG_Translator::Create
bool Create(const CSG_String &File_Name, bool bSetExtension=true, int iText=0, int iTranslation=1, bool bCmpNoCase=false)
Definition: api_translator.cpp:157
CSG_Projection::Get_Type_Name
CSG_String Get_Type_Name(void) const
Definition: projections.cpp:508
CSG_MetaData::Cmp_Property
bool Cmp_Property(const CSG_String &Name, const CSG_String &String, bool bNoCase=false) const
Definition: metadata.cpp:671
PRJ_FIELD_AUTH_NAME
@ PRJ_FIELD_AUTH_NAME
Definition: projections.cpp:616
PRJ_FIELD_SRID
@ PRJ_FIELD_SRID
Definition: projections.cpp:615
CSG_File::Length
sLong Length(void) const
Definition: api_file.cpp:226
CSG_String::CmpNoCase
int CmpNoCase(const CSG_String &String) const
Definition: api_string.cpp:521
CSG_String::AfterFirst
CSG_String AfterFirst(char Character) const
Definition: api_string.cpp:644
CSG_String::Clear
void Clear(void)
Definition: api_string.cpp:259
CSG_Projection::Get_UTM_WGS84
static CSG_Projection Get_UTM_WGS84(int Zone, bool bSouth=false)
Definition: projections.cpp:556
CSG_Table_Record::asInt
int asInt(int Field) const
Definition: table_record.cpp:494
SG_Char
#define SG_Char
Definition: api_core.h:536
shapes.h
ESG_CRS_Type
ESG_CRS_Type
Definition: geo_tools.h:786
CSG_String
Definition: api_core.h:563
CSG_Tool::Set_Manager
bool Set_Manager(class CSG_Data_Manager *pManager)
Definition: tool.cpp:570
SHAPE_TYPE_Point
@ SHAPE_TYPE_Point
Definition: shapes.h:102
CSG_Data_Manager
Definition: data_manager.h:129
CSG_Projection::Get_WKT2
const CSG_String & Get_WKT2(void) const
Definition: geo_tools.h:883
CSG_MetaData
Definition: metadata.h:88
CSG_Projection::Get_Type_Identifier
CSG_String Get_Type_Identifier(void) const
Definition: projections.cpp:502
PRJ_FIELD_SRTEXT
@ PRJ_FIELD_SRTEXT
Definition: projections.cpp:618
CSG_File::Printf
int Printf(const char *Format,...)
Definition: api_file.cpp:277
CSG_String::is_Empty
bool is_Empty(void) const
Definition: api_string.cpp:178
SG_UI_Process_Set_Progress
bool SG_UI_Process_Set_Progress(int Position, int Range)
Definition: api_callback.cpp:256
CSG_Parameter::asDouble
double asDouble(void) const
Definition: parameters.h:284
SSG_Point::x
double x
Definition: geo_tools.h:129
CSG_Projections::Get_Unit_Name
static const CSG_String Get_Unit_Name(ESG_Projection_Unit Unit, bool bSimple=true)
Definition: projections.cpp:1873
CSG_Table_Record::Set_Value
bool Set_Value(int Field, const CSG_String &Value)
Definition: table_record.cpp:270
CSG_Projection::Get_Unit_To_Meter
double Get_Unit_To_Meter(void) const
Definition: projections.cpp:526
CSG_Projection::is_Projection
bool is_Projection(void) const
Definition: geo_tools.h:895
CSG_Projections::~CSG_Projections
virtual ~CSG_Projections(void)
Definition: projections.cpp:693
SSG_Rect::yMin
double yMin
Definition: geo_tools.h:465
CSG_Tool::Get_Parameter
CSG_Parameter * Get_Parameter(const CSG_String &ID) const
Definition: tool.h:187
WKT_GCS_WGS84
#define WKT_GCS_WGS84
CSG_Projection::Get_GCS_WGS84
static const CSG_Projection & Get_GCS_WGS84(void)
Definition: projections.cpp:537
CSG_Projections::CSG_Projections
CSG_Projections(void)
Definition: projections.cpp:628
SSG_Point::y
double y
Definition: geo_tools.h:129
CSG_Grid
Definition: grid.h:473
CSG_Projections::Get_Unit_Identifier
static const CSG_String Get_Unit_Identifier(ESG_Projection_Unit Unit)
Definition: projections.cpp:1843
TABLE_INDEX_Ascending
@ TABLE_INDEX_Ascending
Definition: table.h:105
CSG_Table::Create
bool Create(void)
Definition: table.cpp:139
CSG_String::asDouble
double asDouble(void) const
Definition: api_string.cpp:760
SG_File_Make_Path
SAGA_API_DLL_EXPORT CSG_String SG_File_Make_Path(const CSG_String &Directory, const CSG_String &Name)
Definition: api_file.cpp:919
CSG_Shapes
Definition: shapes.h:775
CSG_Table::Save
virtual bool Save(const CSG_String &File, int Format, SG_Char Separator, int Encoding=SG_FILE_ENCODING_UNDEFINED)
Definition: table_io.cpp:155
SG_UI_ProgressAndMsg_Lock
void SG_UI_ProgressAndMsg_Lock(bool bOn)
Definition: api_callback.cpp:590
CSG_String::c_str
const SG_Char * c_str(void) const
Definition: api_string.cpp:236
tool_library.h
CSG_Projections::Get_Names_List
CSG_String Get_Names_List(ESG_CRS_Type Type=ESG_CRS_Type::Undefined, bool bAddSelect=true) const
Definition: projections.cpp:981
CSG_File::Write
size_t Write(void *Buffer, size_t Size, size_t Count=1) const
Definition: api_file.cpp:360
CSG_Projections::Destroy
void Destroy(void)
Definition: projections.cpp:701
CSG_Strings::Get_Count
int Get_Count(void) const
Definition: api_core.h:712
CSG_Table::Set_Index
bool Set_Index(CSG_Index &Index, int Field, bool bAscending=true) const
Definition: table.cpp:1426
SG_UI_Msg_Add_Error
void SG_UI_Msg_Add_Error(const char *Message)
Definition: api_callback.cpp:557
CSG_MetaData::Add_Child
CSG_MetaData * Add_Child(void)
Definition: metadata.cpp:166
CSG_Projections::Save
bool Save(const CSG_String &File)
Definition: projections.cpp:834
CSG_Table::Add_Record
virtual CSG_Table_Record * Add_Record(CSG_Table_Record *pCopy=NULL)
Definition: table.cpp:795
CSG_Projection::Create
bool Create(const CSG_Projection &Projection)
Definition: projections.cpp:96
CSG_Projections::Add
bool Add(const CSG_Projection &Projection)
Definition: projections.cpp:721
CSG_Data_Object::Get_Projection
CSG_Projection & Get_Projection(void)
Definition: dataobject.cpp:637
table.h
SG_Grid_Get_Geographic_Coordinates
bool SG_Grid_Get_Geographic_Coordinates(CSG_Grid *pGrid, CSG_Grid *pLon, CSG_Grid *pLat)
Definition: projections.cpp:2381
CSG_MetaData::Get_Property
const SG_Char * Get_Property(int Index) const
Definition: metadata.h:180
CSG_File::is_Reading
bool is_Reading(void) const
Definition: api_core.h:1144
CSG_Projections
Definition: geo_tools.h:931
geo_tools.h
CSG_Projections::Get_CRS_Type_Identifier
static CSG_String Get_CRS_Type_Identifier(ESG_CRS_Type Type)
Definition: projections.cpp:1802
CMP_CONTENT
#define CMP_CONTENT(a, b)
gSG_Projections
CSG_Projections gSG_Projections
Definition: projections.cpp:66