SAGA API Version 9.14
Loading...
Searching...
No Matches
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//---------------------------------------------------------
73
74
76// //
77// //
78// //
80
81//---------------------------------------------------------
86
89
90//---------------------------------------------------------
95
97{
98 m_Name = Projection.m_Name;
99 m_Type = Projection.m_Type;
100 m_Unit = Projection.m_Unit;
101
102 m_WKT2 = Projection.m_WKT2;
103 m_PROJ = Projection.m_PROJ;
104 m_Authority = Projection.m_Authority;
105 m_Code = Projection.m_Code;
106
107 return( true );
108}
109
110//---------------------------------------------------------
111CSG_Projection::CSG_Projection(const char *Definition)
112{
113 Create(Definition);
114}
115
116bool CSG_Projection::Create(const char *Definition)
117{
118 if( Definition && *Definition)
119 {
120 return( Create(CSG_String(Definition)) );
121 }
122
123 Destroy();
124
125 return( false );
126}
127
128//---------------------------------------------------------
129CSG_Projection::CSG_Projection(const wchar_t *Definition)
130{
131 Create(Definition);
132}
133
134bool CSG_Projection::Create(const wchar_t *Definition)
135{
136 if( Definition && *Definition )
137 {
138 return( Create(CSG_String(Definition)) );
139 }
140
141 Destroy();
142
143 return( false );
144}
145
146//---------------------------------------------------------
148{
149 Create(Definition);
150}
151
152bool CSG_Projection::Create(const CSG_String &Definition)
153{
154 Destroy();
155
156 if( CSG_Projections::Parse(Definition, &m_PROJ, &m_WKT2) )
157 {
158 CSG_MetaData WKT(CSG_Projections::_WKT2_to_MetaData(m_WKT2, true));
159
160 m_Type = CSG_Projections::Get_CRS_Type(WKT.Get_Name());
161
162 if( m_Type != ESG_CRS_Type::Undefined )
163 {
164 m_Name = WKT.Get_Property("NAME"); if( m_Name.is_Empty() ) { m_Name = "unnamed"; }
165
166 if( !WKT("ID") || !WKT["ID"].Get_Content("VAL1", m_Code) || !WKT["ID"].Get_Property("NAME", m_Authority) )
167 {
168 CSG_Strings Tokens = SG_String_Tokenize(Definition, ":");
169
170 if( Tokens.Get_Count() == 2 && !Tokens[0].is_Empty() && Tokens[1].asInt(m_Code) )
171 {
172 m_Authority = Tokens[0]; m_Authority.Make_Upper();
173 }
174 else
175 {
176 m_Authority.Clear(); m_Code = -1;
177 }
178 }
179
180 return( true );
181 }
182 }
183
184 Destroy();
185
186 return( false );
187}
188
189//---------------------------------------------------------
190CSG_Projection::CSG_Projection(int Code, const SG_Char *Authority)
191{
192 Create(Code, Authority);
193}
194
195bool CSG_Projection::Create(int Code, const SG_Char *Authority)
196{
197 if( Create(CSG_String::Format("%s:%d", Authority && *Authority ? Authority : SG_T("EPSG"), Code)) )
198 {
199 return( true );
200 }
201
202 return( Create(gSG_Projections.Get_Projection(Code, Authority)) ); // request SAGA's internal CRS database (might provide definitions not included in PROJ's default database)
203}
204
205//---------------------------------------------------------
210
212{
213 if( PROJ.is_Empty() )
214 {
215 return( Create(WKT2) );
216 }
217
218 m_PROJ = PROJ;
219 m_WKT2 = WKT2;
220
221 CSG_MetaData WKT(CSG_Projections::_WKT2_to_MetaData(m_WKT2, true));
222
223 m_Type = CSG_Projections::Get_CRS_Type(WKT.Get_Name());
224 m_Name = WKT.Get_Property("NAME"); if( m_Name.is_Empty() ) { m_Name = "unnamed"; }
225
226 if( !WKT("ID") || !WKT["ID"].Get_Content("VAL1", m_Code) || !WKT["ID"].Get_Property("NAME", m_Authority) )
227 {
228 m_Authority.Clear(); m_Code = -1;
229 }
230
231 return( true );
232}
233
234//---------------------------------------------------------
236{
237 m_Name = _TL("undefined");
238 m_Type = ESG_CRS_Type ::Undefined;
240
241 m_WKT2 .Clear();
242 m_PROJ .Clear();
243 m_Authority .Clear();
244 m_Code = -1;
245}
246
247
249// //
251
252//---------------------------------------------------------
253bool CSG_Projection::Load(const CSG_String &FileName)
254{
255 CSG_File Stream(FileName, SG_FILE_R, false);
256
257 return( Load(Stream) );
258}
259
260//---------------------------------------------------------
261bool CSG_Projection::Save(const CSG_String &FileName, ESG_CRS_Format Format) const
262{
263 if( is_Okay() )
264 {
265 CSG_File Stream(FileName, SG_FILE_W, false);
266
267 return( Save(Stream, Format) );
268 }
269
270 if( SG_File_Exists(FileName) )
271 {
272 SG_File_Delete(FileName);
273 }
274
275 return( false );
276}
277
278//---------------------------------------------------------
280{
281 if( Stream.is_Reading() )
282 {
283 CSG_String s; Stream.Read(s, (size_t)Stream.Length());
284
285 return( Create(s) );
286 }
287
288 return( false );
289}
290
291//---------------------------------------------------------
293{
294 if( is_Okay() && Stream.is_Writing() )
295 {
296 CSG_String Definition;
297
298 switch( Format )
299 {
300 default:
301 case ESG_CRS_Format::WKT1: Definition = Get_WKT1(); break;
302 case ESG_CRS_Format::WKT2: Definition = Get_WKT2(); break;
303 case ESG_CRS_Format::PROJ: Definition = Get_PROJ(); break;
304 case ESG_CRS_Format::JSON: Definition = Get_JSON(); break;
305 case ESG_CRS_Format::ESRI: Definition = Get_ESRI(); break;
306 case ESG_CRS_Format::CODE: if( !m_Authority.is_Empty() && m_Code > 0 ) { Definition.Printf("%s:%d", m_Authority.c_str(), m_Code); } break;
307 }
308
309 return( !Definition.is_Empty() && Stream.Write(Definition) == Definition.Length() );
310 }
311
312 return( false );
313}
314
315//---------------------------------------------------------
317{
318 if( Projection("WKT2") && Projection("PROJ") && Create(Projection["WKT2"].Get_Content(), Projection["PROJ"].Get_Content()) ) { return( true ); }
319
320 if( Projection("WKT2") && Create(Projection["WKT2"].Get_Content()) ) { return( true ); }
321 if( Projection("PROJ") && Create(Projection["PROJ"].Get_Content()) ) { return( true ); }
322
323 //-----------------------------------------------------
324 // >>> backward compatibility
325
326 if( Projection("WKT1" ) && Create(Projection["WKT1" ].Get_Content()) ) { return( true ); }
327 if( Projection("OGC_WKT") && Create(Projection["OGC_WKT"].Get_Content()) ) { return( true ); }
328 if( Projection("PROJ4" ) && Create(Projection["PROJ4" ].Get_Content()) ) { return( true ); }
329
330 // <<< backward compatibility
331 //-----------------------------------------------------
332
333 return( false );
334}
335
336//---------------------------------------------------------
338{
339 Projection.Del_Children();
340
341 Projection.Add_Child("WKT2", m_WKT2);
342 Projection.Add_Child("PROJ", m_PROJ);
343 Projection.Add_Child("CODE", m_Code)->Add_Property("authority", m_Authority);
344
345 return( true );
346}
347
348
350// //
352
353//---------------------------------------------------------
358
359//---------------------------------------------------------
364
365//---------------------------------------------------------
370
371//---------------------------------------------------------
373{
374 return( CSG_Projections::_WKT2_to_MetaData(m_WKT2, false).asText(1) );
375}
376
377
379// //
381
382//---------------------------------------------------------
384{
385 if( !is_Okay() )
386 {
387 return( _TL("Unknown Spatial Reference") );
388 }
389
390 if( !bDetails )
391 {
393
394 if( !m_Name.is_Empty() && m_Name.CmpNoCase("<custom>") )
395 {
396 s += "\n" + m_Name;
397 }
398
399 if( m_Code > 0 && !m_Authority.is_Empty() )
400 {
401 s += CSG_String::Format(" [%s:%d]", m_Authority.c_str(), m_Code);
402 }
403
404 return( s );
405 }
406
407 //-----------------------------------------------------
408 #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()); }
409 #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()); }
410 #define ADD_CONT(name, entry) if( entry ) { ADD_INFO(name, entry->Get_Content() ); }
411 #define ADD_PROP(name, entry, prop) if( entry && entry->Get_Property(prop) ) { ADD_INFO(name, entry->Get_Property(prop)); }
412
413 CSG_MetaData WKT(CSG_Projections::_WKT2_to_MetaData(Get_WKT2(), false)), *pGCS = NULL;
414
415 CSG_String s = "<table border=\"1\">";
416
417 if( is_Projection() )
418 {
419 CSG_MetaData &PRJ = WKT.Cmp_Name("PROJCRS") ? WKT : WKT[0].Cmp_Name("PROJCRS") ? WKT[0] : WKT[0][0];
420
421 ADD_HEAD(_TL("Projected Coordinate System" ), PRJ.Get_Property("NAME") && !PRJ.Cmp_Property("NAME", "unknown", true) ? PRJ.Get_Property("NAME") : SG_T(""));
422 ADD_PROP(_TL("Projection" ), PRJ("CONVERSION.METHOD"), "NAME");
423
424 if( m_Code > 0 && !m_Authority.is_Empty() )
425 {
426 ADD_INFO(_TL("Authority Code" ), CSG_String::Format("%d", m_Code) );
427 ADD_INFO(_TL("Authority" ), m_Authority);
428 }
429
430 ADD_PROP(_TL("Linear Unit" ), PRJ("UNIT"), "NAME");
431
432 if( PRJ("CONVERSION") )
433 {
434 for(int i=0; i<PRJ["CONVERSION"].Get_Children_Count(); i++)
435 {
436 CSG_MetaData &Parameter = PRJ["CONVERSION"][i];
437
438 if( Parameter.Cmp_Name("PARAMETER") && Parameter("VAL1") )
439 {
440 CSG_String Name(Parameter.Get_Property("NAME")); Name.Replace("_", " ");
441
442 ADD_INFO(Name.c_str(), Parameter["VAL1"].Get_Content().c_str());
443 }
444 }
445 }
446
447 pGCS = PRJ("BASEGEODCRS");
448 }
449 else if( is_Geographic() )
450 {
451 pGCS = WKT .Cmp_Name("GEOGCRS") || WKT .Cmp_Name("GEODCRS") ? &WKT
452 : WKT[0].Cmp_Name("GEOGCRS") || WKT[0].Cmp_Name("GEODCRS") ? &WKT[0] : &WKT[0][0];
453 }
454
455 if( pGCS )
456 {
457 CSG_MetaData &GCS = *pGCS;
458
459 ADD_HEAD(_TL("Geographic Coordinate System"), GCS.Get_Property("NAME") && !GCS.Cmp_Property("NAME", "unknown", true) ? GCS.Get_Property("NAME") : _TL(""));
460 ADD_CONT(_TL("Authority Code" ), GCS("ID.VAL1"));
461 ADD_PROP(_TL("Authority" ), GCS("ID" ), "NAME");
462 ADD_PROP(_TL("Prime Meridian" ), GCS("PRIMEM" ), "NAME");
463 ADD_PROP(_TL("Angular Unit" ), GCS("PRIMEM.LENGTHUNIT"), "NAME");
464 ADD_PROP(_TL("Datum" ), GCS("DATUM" ), "NAME");
465 ADD_PROP(_TL("Spheroid" ), GCS("DATUM.ELLIPSOID" ), "NAME");
466 ADD_CONT(_TL("Semimajor Axis" ), GCS("DATUM.ELLIPSOID.VAL1"));
467 ADD_CONT(_TL("Inverse Flattening" ), GCS("DATUM.ELLIPSOID.VAL2"));
468 ADD_CONT(_TL("Extension" ), GCS("DATUM.EXTENSION" ));
469
470 if( WKT("ABRIDGEDTRANSFORMATION") )
471 {
472 CSG_MetaData &Transformation = WKT["ABRIDGEDTRANSFORMATION"];
473
474 ADD_HEAD(_TL("Transformation"), Transformation.Get_Property("NAME"));
475
476 for(int i=0; i<Transformation.Get_Children_Count(); i++)
477 {
478 CSG_MetaData &Parameter = Transformation[i];
479
480 if( Parameter.Cmp_Name("PARAMETER") && Parameter("VAL1") )
481 {
482 CSG_String Name(Parameter.Get_Property("NAME")); Name.Replace("_", " ");
483
484 ADD_INFO(Name.c_str(), Parameter["VAL1"].Get_Content().c_str());
485 }
486 }
487 }
488 }
489
490 s += "</table>";
491
492 return( s );
493}
494
495
497// //
499
500//---------------------------------------------------------
502{
503 if( Get_Type() != Projection.Get_Type() && !(is_Geographic() && Projection.is_Geographic()) )
504 {
505 return( false );
506 }
507
508 if( !is_Okay() ) // both are not valid => ESG_CRS_Type::Undefined
509 {
510 return( true );
511 }
512
513 if( !m_Authority.is_Empty() && !m_Authority.CmpNoCase(Projection.m_Authority) && m_Code == Projection.m_Code )
514 {
515 return( true );
516 }
517
518 //-----------------------------------------------------
519 // the simple case, identical PROJ strings...
520
521 CSG_String proj[2] = { m_PROJ, Projection.m_PROJ };
522
523 for(int i=0; i<2; i++)
524 {
525 proj[i].Make_Lower(); proj[i].Replace("+no_defs", ""); proj[i].Trim_Both();
526 }
527
528 if( !proj[0].CmpNoCase(proj[1]) )
529 {
530 return( true );
531 }
532
533 //-----------------------------------------------------
534 // okay, let's perform a more detailed check...
535
536 #define CMP_CONTENT(a, b ) (a && b && a->Cmp_Content(b->Get_Content()))
537 #define CMP_PROPERTY(a, b, p) (a && b && a->Get_Property(p) && b->Cmp_Property(p, a->Get_Property(p), true))
538 #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()))))
539
540 CSG_MetaData WKT[2] = {
541 CSG_Projections::_WKT1_to_MetaData( Get_WKT1()),
542 CSG_Projections::_WKT1_to_MetaData(Projection.Get_WKT1())
543 }, *pGCS[2] = { NULL, NULL };
544
545 if( is_Projection() )
546 {
547
548 if( !CMP_CONTENT (WKT[0]("PROJECTION"), WKT[1]("PROJECTION") ) ) { return( false ); }
549 if( !CMP_PROPERTY(WKT[0]("UNIT" ), WKT[1]("UNIT" ), "name") ) { return( false ); }
550
551 for(int i=0; i<WKT[0].Get_Children_Count() && i<WKT[1].Get_Children_Count(); i++)
552 {
553 if( !CMP_PARAMETER(WKT[0](i), WKT[1](i)) ) { return( false ); }
554 }
555
556 pGCS[0] = WKT[0]("GEOGCS");
557 pGCS[1] = WKT[1]("GEOGCS");
558 }
559 else if( is_Geographic() )
560 {
561 pGCS[0] = &WKT[0];
562 pGCS[1] = &WKT[1];
563 }
564
565 if( !pGCS[0] || !pGCS[1] )
566 {
567 return( false );
568 }
569
570 if( !CMP_CONTENT((*pGCS[0])("PRIMEM" ), (*pGCS[1])("PRIMEM" )) ) { return( false ); }
571 if( !CMP_CONTENT((*pGCS[0])("UNIT" ), (*pGCS[1])("UNIT" )) ) { return( false ); }
572 if( !CMP_CONTENT((*pGCS[0])("DATUM.SPHEROID.a" ), (*pGCS[1])("DATUM.SPHEROID.a" )) ) { return( false ); }
573 if( !CMP_CONTENT((*pGCS[0])("DATUM.SPHEROID.rf"), (*pGCS[1])("DATUM.SPHEROID.rf")) ) { return( false ); }
574
575 if( (*pGCS[0])("DATUM.TOWGS84") || (*pGCS[1])("DATUM.TOWGS84") )
576 {
577 #define CMP_TOWGS84(id) (\
578 ((*pGCS[0])("DATUM.TOWGS84." id) ? (*pGCS[0])["DATUM.TOWGS84." id].Get_Content().asDouble() : 0.)\
579 == ((*pGCS[1])("DATUM.TOWGS84." id) ? (*pGCS[1])["DATUM.TOWGS84." id].Get_Content().asDouble() : 0.) )
580
581 if( !CMP_TOWGS84("dx") ) { return( false ); }
582 if( !CMP_TOWGS84("dy") ) { return( false ); }
583 if( !CMP_TOWGS84("dz") ) { return( false ); }
584 if( !CMP_TOWGS84("rx") ) { return( false ); }
585 if( !CMP_TOWGS84("ry") ) { return( false ); }
586 if( !CMP_TOWGS84("rz") ) { return( false ); }
587 if( !CMP_TOWGS84("sc") ) { return( false ); }
588 }
589
590 if( (*pGCS[0])("DATUM.EXTENSION") || (*pGCS[1])("DATUM.EXTENSION") )
591 {
592 if( !CMP_CONTENT((*pGCS[0])("DATUM.EXTENSION"), (*pGCS[1])("DATUM.EXTENSION")) ) { return( false ); }
593 }
594
595 return( true );
596}
597
598
600// //
602
603//---------------------------------------------------------
608
609//---------------------------------------------------------
614
615//---------------------------------------------------------
620
621//---------------------------------------------------------
626
627//---------------------------------------------------------
629{
630 return( CSG_Projections::Get_Unit_To_Meter(m_Unit) );
631}
632
634// //
636
637//---------------------------------------------------------
639{
640 double d = 0.;
641
642 if( is_Okay() && m_PROJ.Find("+lon_0") >= 0 )
643 {
644 CSG_String s(m_PROJ.Right(m_PROJ.Length() - m_PROJ.Find("+lon_0")).AfterFirst('='));
645
646 if( s.asDouble(d) && d != 0. )
647 {
648 d = fmod(d - 180., 360.); if( d < -180. ) { d += 360.; } else if( d >= 180. ) { d -= 360.; }
649 }
650 }
651
652 return( d );
653}
654
655//---------------------------------------------------------
657{
658 double d = 0.;
659
660 if( is_Okay() && m_PROJ.Find("+lat_0") >= 0 )
661 {
662 CSG_String s(m_PROJ.Right(m_PROJ.Length() - m_PROJ.Find("+lat_0")).AfterFirst('='));
663
664 if( s.asDouble(d) && d != 0. )
665 {
666 d = fmod(d - 90., 180.); if( d < -90. ) { d += 180.; } else if( d >= 90. ) { d -= 180.; }
667 }
668 }
669
670 return( d );
671}
672
673
675// //
677
678//---------------------------------------------------------
680{
681 static CSG_Projection GCS_WGS84;
682
683 if( !GCS_WGS84.is_Okay() )
684 {
685 GCS_WGS84.Set_GCS_WGS84();
686 }
687
688 return( GCS_WGS84 );
689}
690
691//---------------------------------------------------------
693{
694 m_Name = "WGS 84";
697 m_Authority = "EPSG";
698 m_Code = 4326;
699 m_PROJ = "+proj=longlat +datum=WGS84 +no_defs";
700 m_WKT2 =
701 "GEODCRS[\"WGS 84\","
702 " DATUM[\"World Geodetic System 1984\","
703 " ELLIPSOID[\"WGS 84\",6378137,298.257223563]],"
704 " CS[ellipsoidal,2],"
705 " AXIS[\"geodetic latitude (Lat)\",north],"
706 " AXIS[\"geodetic longitude (Lon)\",east],"
707 " UNIT[\"degree\",0.0174532925199433],"
708 " SCOPE[\"Horizontal component of 3D system.\"],"
709 " AREA[\"World.\"],"
710 " BBOX[-90,-180,90,180],"
711 " ID[\"EPSG\",4326]]";
712
713// m_WKT2 =
714// "GEODCRS[\"WGS 84\","
715// " DATUM[\"World Geodetic System 1984\","
716// " ELLIPSOID[\"WGS 84\",6378137,298.257223563,"
717// " LENGTHUNIT[\"metre\",1]]],"
718// " PRIMEM[\"Greenwich\",0,"
719// " ANGLEUNIT[\"degree\",0.0174532925199433]],"
720// " CS[ellipsoidal,2],"
721// " AXIS[\"geodetic latitude (Lat)\",north,"
722// " ORDER[1],"
723// " ANGLEUNIT[\"degree\",0.0174532925199433]],"
724// " AXIS[\"geodetic longitude (Lon)\",east,"
725// " ORDER[2],"
726// " ANGLEUNIT[\"degree\",0.0174532925199433]],"
727// " SCOPE[\"Horizontal component of 3D system.\"],"
728// " AREA[\"World.\"],"
729// " BBOX[-90,-180,90,180],"
730// " ID[\"EPSG\",4326]]";
731
732 return( true ); // return( Create(4326) );
733}
734
735//---------------------------------------------------------
737{
739
740 Projection.Set_UTM_WGS84(Zone, bSouth);
741
742 return( Projection );
743}
744
745//---------------------------------------------------------
746bool CSG_Projection::Set_UTM_WGS84(int Zone, bool bSouth)
747{
748 if( Zone < 1 || Zone > 60 )
749 {
750 return( false );
751 }
752
753 int EPSG_ID = (bSouth ? 32700 : 32600) + Zone;
754
755 if( Create(EPSG_ID) )
756 {
757 return( true );
758 }
759
760 //-----------------------------------------------------
761 CSG_String WKT; WKT.Printf(
762 "PROJCRS[\"WGS 84 / UTM zone %d%c\"," // Zone, N/S
763 " BASEGEODCRS[\"WGS 84\","
764 " DATUM[\"World Geodetic System 1984\","
765 " ELLIPSOID[\"WGS 84\",6378137,298.257223563,"
766 " LENGTHUNIT[\"metre\",1]]],"
767 " PRIMEM[\"Greenwich\",0,"
768 " ANGLEUNIT[\"degree\",0.0174532925199433]]],"
769 " CONVERSION[\"UTM zone 32N\","
770 " METHOD[\"Transverse Mercator\","
771 " ID[\"EPSG\",9807]],"
772 " PARAMETER[\"Latitude of natural origin\",0,"
773 " ANGLEUNIT[\"degree\",0.0174532925199433],"
774 " ID[\"EPSG\",8801]],"
775 " PARAMETER[\"Longitude of natural origin\",%d," // Central Meridian
776 " ANGLEUNIT[\"degree\",0.0174532925199433],"
777 " ID[\"EPSG\",8802]],"
778 " PARAMETER[\"Scale factor at natural origin\",0.9996,"
779 " SCALEUNIT[\"unity\",1],"
780 " ID[\"EPSG\",8805]],"
781 " PARAMETER[\"False easting\",500000,"
782 " LENGTHUNIT[\"metre\",1],"
783 " ID[\"EPSG\",8806]],"
784 " PARAMETER[\"False northing\",%d," // False Northing
785 " LENGTHUNIT[\"metre\",1],"
786 " ID[\"EPSG\",8807]]],"
787 " CS[Cartesian,2],"
788 " AXIS[\"(E)\",east,"
789 " ORDER[1],"
790 " LENGTHUNIT[\"metre\",1]],"
791 " AXIS[\"(N)\",north,"
792 " ORDER[2],"
793 " LENGTHUNIT[\"metre\",1]],"
794 " ID[\"EPSG\",32632]]", // EPSG ID
795 Zone, bSouth ? 'S' : 'N', 6 * (Zone - 1) - 177, bSouth ? 10000000 : 0, EPSG_ID
796 );
797
798 return( Create(WKT) );
799}
800
801
803// //
804// //
805// //
807
808//---------------------------------------------------------
817
818
820// //
822
823//---------------------------------------------------------
825{
826 _On_Construction();
827}
828
829//---------------------------------------------------------
831{
832 _On_Construction();
833
834 Create(LoadCodeList);
835}
836
837bool CSG_Projections::Create(bool LoadCodeList)
838{
839 Destroy();
840
841 if( LoadCodeList ) // load spatial reference system database
842 {
843 _Load(m_pProjections, SG_File_Make_Path(CSG_Environment::Get_Share_Path(), "saga", "srs"));
844 }
845
846 if( _Load(m_pPreferences, SG_File_Make_Path(CSG_Environment::Get_Share_Path(), "saga_preferences", "srs")) ) // always try to load preferences!
847 {
848 _Add_Preferences();
849 }
850
851 return( true );
852}
853
854//---------------------------------------------------------
855void CSG_Projections::_On_Construction(void)
856{
857 m_pProjections = new CSG_Table;
858
859 m_pProjections->Add_Field("srid" , SG_DATATYPE_Int ); // PRJ_FIELD_SRID
860 m_pProjections->Add_Field("auth_name", SG_DATATYPE_String); // PRJ_FIELD_AUTH_NAME
861 m_pProjections->Add_Field("auth_srid", SG_DATATYPE_Int ); // PRJ_FIELD_AUTH_SRID
862 m_pProjections->Add_Field("srtext" , SG_DATATYPE_String); // PRJ_FIELD_SRTEXT
863 m_pProjections->Add_Field("proj4text", SG_DATATYPE_String); // PRJ_FIELD_PROJ4TEXT
864
865 m_pPreferences = new CSG_Table(m_pProjections);
866
867 _Set_Dictionary();
868}
869
870//---------------------------------------------------------
872{
873 Destroy();
874
875 delete(m_pProjections);
876 delete(m_pPreferences);
877}
878
879//---------------------------------------------------------
881{
882 if( m_pProjections ) { m_pProjections->Del_Records(); }
883 if( m_pPreferences ) { m_pPreferences->Del_Records(); }
884}
885
886
888// //
890
891//---------------------------------------------------------
893{
894 return( m_pProjections->Get_Count() );
895}
896
897//---------------------------------------------------------
899{
900 return( false );
901}
902
903//---------------------------------------------------------
904bool CSG_Projections::Add(const SG_Char *WKT, const SG_Char *Proj4, const SG_Char *Authority, int Authority_ID)
905{
906 CSG_Table_Record *pProjection = m_pProjections->Add_Record();
907
908 pProjection->Set_Value(PRJ_FIELD_SRID , (int)m_pProjections->Get_Count());
909 pProjection->Set_Value(PRJ_FIELD_AUTH_NAME, Authority);
910 pProjection->Set_Value(PRJ_FIELD_AUTH_SRID, Authority_ID);
911 pProjection->Set_Value(PRJ_FIELD_SRTEXT , WKT);
912 pProjection->Set_Value(PRJ_FIELD_PROJ4TEXT, Proj4);
913
914 return( true );
915}
916
917//---------------------------------------------------------
918CSG_Projection CSG_Projections::_Get_Projection(CSG_Table_Record *pProjection)
919{
921
922 if( pProjection )
923 {
924 Projection.m_Authority = pProjection->asString(PRJ_FIELD_AUTH_NAME);
925 Projection.m_Code = pProjection->asInt (PRJ_FIELD_AUTH_SRID);
926 Projection.m_PROJ = pProjection->asString(PRJ_FIELD_PROJ4TEXT);
927 Projection.m_WKT2 = pProjection->asString(PRJ_FIELD_SRTEXT );
928
929 Projection.m_WKT2.Trim_Both();
930
931 if( Projection.m_WKT2.Find("GEOGCS") == 0 // WKT-1 !
932 || Projection.m_WKT2.Find("GEOCCS") == 0
933 || Projection.m_WKT2.Find("GEODCS") == 0
934 || Projection.m_WKT2.Find("PROJCS") == 0 )
935 {
937 }
938
939 //-------------------------------------------------
940 CSG_MetaData WKT = _WKT1_to_MetaData(Projection.Get_WKT1());
941
942 Projection.m_Name = WKT.Get_Property("name");
943 Projection.m_Type = Get_CRS_Type(WKT.Get_Name());
944 Projection.m_Unit = WKT("UNIT") && WKT["UNIT"].Get_Property("name") ?
945 Get_Unit(WKT["UNIT"].Get_Property("name")) : ESG_Projection_Unit::Undefined;
946 }
947
948 return( Projection );
949}
950
951//---------------------------------------------------------
953{
954 return( _Get_Projection(m_pProjections->Get_Record(Index)) );
955}
956
957//---------------------------------------------------------
958const SG_Char * CSG_Projections::Get_Projection(int Code, const SG_Char *_Authority) const
959{
960 CSG_String Authority(_Authority && *_Authority ? _Authority : SG_T("EPSG"));
961
962 for(sLong i=0; i<m_pProjections->Get_Count(); i++)
963 {
964 CSG_Table_Record *pProjection = m_pProjections->Get_Record(i);
965
966 if( Code == pProjection->asInt(PRJ_FIELD_AUTH_SRID) && !Authority.CmpNoCase(pProjection->asString(PRJ_FIELD_AUTH_NAME)) )
967 {
968 return( pProjection->asString(PRJ_FIELD_SRTEXT) );
969 }
970 }
971
972 return( SG_T("") );
973}
974
975//---------------------------------------------------------
976bool CSG_Projections::Get_Projection(CSG_Projection &Projection, int Code, const SG_Char *_Authority) const
977{
978 CSG_String Authority(_Authority && *_Authority ? _Authority : SG_T("EPSG"));
979
980 for(sLong i=0; i<m_pProjections->Get_Count(); i++)
981 {
982 CSG_Table_Record *pProjection = m_pProjections->Get_Record(i);
983
984 if( Code == pProjection->asInt(PRJ_FIELD_AUTH_SRID) && !Authority.CmpNoCase(pProjection->asString(PRJ_FIELD_AUTH_NAME)) )
985 {
986 Projection = _Get_Projection(pProjection);
987
988 return( Projection.is_Okay() );
989 }
990 }
991
992 return( false );
993}
994
995
997// //
999
1000//---------------------------------------------------------
1001bool CSG_Projections::_Add_Preferences(void)
1002{
1003 if( !m_pProjections || !m_pPreferences || m_pPreferences->Get_Count() < 1 )
1004 {
1005 return( false );
1006 }
1007
1010
1011 for(sLong iPreference=0, iProjection=0; iPreference<m_pPreferences->Get_Count() && iProjection<m_pProjections->Get_Count(); )
1012 {
1013 CSG_Table_Record *pPreference = m_pPreferences->Get_Record_byIndex(iPreference);
1014 CSG_Table_Record *pProjection = m_pProjections->Get_Record_byIndex(iProjection);
1015
1016 CSG_String Authority = pProjection->asString(PRJ_FIELD_AUTH_NAME);
1017
1018 int Comparison = Authority.CmpNoCase(pPreference->asString(PRJ_FIELD_AUTH_NAME));
1019
1020 if( Comparison < 0 ) { iProjection++; } else if( Comparison > 0 ) { iPreference++; } else
1021 {
1022 Comparison = pProjection->asInt(PRJ_FIELD_AUTH_SRID) - pPreference->asInt(PRJ_FIELD_AUTH_SRID);
1023
1024 if( Comparison < 0 ) { iProjection++; } else if( Comparison > 0 ) { iPreference++; } else
1025 {
1026 pProjection->Set_Value(PRJ_FIELD_SRTEXT , pPreference->asString(PRJ_FIELD_SRTEXT ));
1027 pProjection->Set_Value(PRJ_FIELD_PROJ4TEXT, pPreference->asString(PRJ_FIELD_PROJ4TEXT));
1028
1029 m_pPreferences->Select(pPreference, true);
1030
1031 iProjection++; iPreference++;
1032 }
1033 }
1034 }
1035
1036 m_pProjections->Del_Index();
1037 m_pPreferences->Del_Index();
1038
1039 if( m_pPreferences->Get_Selection_Count() < m_pPreferences->Get_Count() )
1040 {
1041 for(sLong iPreference=0; iPreference<m_pPreferences->Get_Count(); iPreference++)
1042 {
1043 CSG_Table_Record *pPreference = m_pPreferences->Get_Record(iPreference);
1044
1045 if( !pPreference->is_Selected() )
1046 {
1047 m_pProjections->Add_Record(pPreference);
1048 }
1049 }
1050 }
1051
1052 m_pPreferences->Select(); // unselect all records
1053
1054 return( true );
1055}
1056
1057//---------------------------------------------------------
1059{
1060 for(sLong i=0; i<m_pPreferences->Get_Count(); i++)
1061 {
1062 CSG_Table_Record *pProjection = m_pPreferences->Get_Record(i);
1063
1064 if( Code == pProjection->asInt(PRJ_FIELD_AUTH_SRID) && !Authority.CmpNoCase(pProjection->asString(PRJ_FIELD_AUTH_NAME)) )
1065 {
1066 Projection = _Get_Projection(pProjection);
1067
1068 return( Projection.is_Okay() );
1069 }
1070 }
1071
1072 if( m_bUseInternalDB )
1073 {
1074 for(sLong i=0; i<m_pProjections->Get_Count(); i++)
1075 {
1076 CSG_Table_Record *pProjection = m_pProjections->Get_Record(i);
1077
1078 if( Code == pProjection->asInt(PRJ_FIELD_AUTH_SRID) && !Authority.CmpNoCase(pProjection->asString(PRJ_FIELD_AUTH_NAME)) )
1079 {
1080 Projection = _Get_Projection(pProjection);
1081
1082 return( Projection.is_Okay() );
1083 }
1084 }
1085 }
1086
1087 return( false );
1088}
1089
1090//---------------------------------------------------------
1092{
1093 int i = Authority_Code.Find(':');
1094
1095 if( i > 1 && i < (int)Authority_Code.Length() - 2 )
1096 {
1097 int Code; CSG_String Authority(Authority_Code.BeforeFirst(':'));
1098
1099 if( !Authority.is_Empty() && Authority_Code.AfterFirst(':').asInt(Code) )
1100 {
1101 return( Get_Preference(Projection, Code, Authority) );
1102 }
1103 }
1104
1105 return( false );
1106}
1107
1108
1110// //
1112
1113//---------------------------------------------------------
1114bool CSG_Projections::_Load(CSG_Table *pTable, const CSG_String &File, bool bAppend) const
1115{
1116 CSG_Table Table;
1117
1118 SG_UI_Msg_Lock(true);
1119
1120 if( pTable && Table.Create(File) && Table.Get_Count() > 0 && Table.Get_Field_Count() >= 5 )
1121 {
1122 if( bAppend )
1123 {
1124 for(sLong i=0; i<pTable->Get_Count(); i++)
1125 {
1126 Table.Add_Record(pTable->Get_Record(i));
1127 }
1128 }
1129
1130 pTable->Del_Records();
1131
1133
1134 for(sLong i=0; i<Table.Get_Count(); i++)
1135 {
1136 pTable->Add_Record(Table.Get_Record_byIndex(i));
1137 }
1138
1139 SG_UI_Msg_Lock(false);
1140
1141 return( true );
1142 }
1143
1144 SG_UI_Msg_Lock(false);
1145
1146 return( false );
1147}
1148
1149//---------------------------------------------------------
1150bool CSG_Projections::Load(const CSG_String &File, bool bAppend)
1151{
1152 return( _Load(m_pProjections, File, bAppend) );
1153}
1154
1155//---------------------------------------------------------
1157{
1158 return( m_pProjections->Save(File) );
1159}
1160
1161
1163// //
1165
1166//---------------------------------------------------------
1168{
1169 if( Definition.is_Empty() )
1170 {
1171 return( "" );
1172 }
1173
1174 //-----------------------------------------------------
1175 CSG_Projection Projection; // check white list first !
1176
1177 if( SG_Get_Projections().Get_Preference(Projection, Definition) )
1178 {
1179 switch( Format )
1180 {
1181 case ESG_CRS_Format::PROJ: return( Projection.Get_PROJ() );
1182 case ESG_CRS_Format::WKT2: return( Projection.Get_WKT2() );
1183 default:
1184 return( Parse(Projection.Get_WKT2(), Format) );
1185 }
1186 }
1187
1188 //-----------------------------------------------------
1189 CSG_String s; CSG_Tool *pTool = SG_Get_Tool_Library_Manager().Create_Tool("pj_proj4", 19); // Coordinate Reference System Format Conversion
1190
1191 if( pTool ) // check proj.lib, ...will check white list first !
1192 {
1193 pTool->Set_Callback(false);
1194 pTool->Set_Parameter("DEFINITION", Definition);
1195 pTool->Set_Parameter("MULTILINE" , false);
1196 pTool->Set_Parameter("SIMPLIFIED", false);
1197
1199
1200 switch( Format )
1201 {
1202 case ESG_CRS_Format::PROJ: pTool->Set_Parameter("FORMAT", 0); if( pTool->Execute() ) { s = pTool->Get_Parameter("PROJ")->asString(); } break;
1203 case ESG_CRS_Format::WKT1: pTool->Set_Parameter("FORMAT", 1); if( pTool->Execute() ) { s = pTool->Get_Parameter("WKT1")->asString(); } break;
1204 case ESG_CRS_Format::WKT2: pTool->Set_Parameter("FORMAT", 2); if( pTool->Execute() ) { s = pTool->Get_Parameter("WKT2")->asString(); } break;
1205 case ESG_CRS_Format::JSON: pTool->Set_Parameter("FORMAT", 3); if( pTool->Execute() ) { s = pTool->Get_Parameter("JSON")->asString(); } break;
1206 case ESG_CRS_Format::ESRI: pTool->Set_Parameter("FORMAT", 4); if( pTool->Execute() ) { s = pTool->Get_Parameter("ESRI")->asString(); } break;
1207 default: break;
1208 }
1209
1211
1213 }
1214
1215 return( s );
1216}
1217
1218//---------------------------------------------------------
1220{
1221 if( Definition.is_Empty() )
1222 {
1223 return( false );
1224 }
1225
1226 //-----------------------------------------------------
1227 CSG_Projection Projection; // check white list first !
1228
1229 if( SG_Get_Projections().Get_Preference(Projection, Definition) )
1230 {
1231 if( PROJ ) { *PROJ = Projection.Get_PROJ(); }
1232 if( WKT2 ) { *WKT2 = Projection.Get_WKT2(); }
1233
1234 return( (!WKT1 && !JSON && !ESRI) || Parse(Projection.Get_WKT2(), NULL, NULL, WKT1, JSON, ESRI) );
1235 }
1236
1237 //-----------------------------------------------------
1238 CSG_Tool *pTool = SG_Get_Tool_Library_Manager().Create_Tool("pj_proj4", 19); // Coordinate Reference System Format Conversion
1239
1240 if( pTool ) // check proj.lib, ...will check white list first !
1241 {
1242 pTool->Set_Callback(false);
1243 pTool->Set_Parameter("DEFINITION", Definition);
1244 pTool->Set_Parameter("MULTILINE" , false);
1245 pTool->Set_Parameter("SIMPLIFIED", false);
1246 pTool->Set_Parameter("FORMAT" , WKT1 || ESRI || JSON ? 5 : 6); // all : PROJ + WKT-2
1247
1249
1250 if( pTool->Execute() )
1251 {
1252 if( PROJ ) { *PROJ = pTool->Get_Parameter("PROJ")->asString(); }
1253 if( WKT1 ) { *WKT1 = pTool->Get_Parameter("WKT1")->asString(); }
1254 if( WKT2 ) { *WKT2 = pTool->Get_Parameter("WKT2")->asString(); }
1255 if( ESRI ) { *ESRI = pTool->Get_Parameter("ESRI")->asString(); }
1256 }
1257
1259
1261
1262 return( !(PROJ && PROJ->is_Empty()) && !(WKT1 && WKT1->is_Empty()) && !(WKT2 && WKT2->is_Empty()) && !(ESRI && ESRI->is_Empty()) );
1263 }
1264
1265 //-----------------------------------------------------
1266 else // proj.lib parser not available ...fallback!
1267 {
1268 int Code = -1; CSG_String Authority(Definition.BeforeFirst(':'));
1269
1270 if( Authority.is_Empty() || Definition.AfterFirst(':').asInt(Code) == false )
1271 {
1272 CSG_MetaData WKT(CSG_Projections::_WKT1_to_MetaData(Definition));
1273
1274 WKT.Get_Property("authority_name", Authority);
1275 WKT.Get_Property("authority_code", Code);
1276 }
1277
1278 if( !Authority.is_Empty() && Code > 0 )
1279 {
1281
1282 if( gSG_Projections.Get_Projection(Projection, Code, Authority) )
1283 {
1284 if( WKT1 ) { *WKT1 = Projection.Get_WKT1(); }
1285 if( WKT2 ) { *WKT2 = Projection.Get_WKT2(); }
1286 if( PROJ ) { *PROJ = Projection.Get_PROJ(); }
1287 if( ESRI ) { *ESRI = Projection.Get_ESRI(); }
1288
1289 return( true );
1290 }
1291 }
1292
1293 //-------------------------------------------------
1294 CSG_String Proj4;
1295
1296 if( gSG_Projections._WKT1_to_Proj4(Proj4, Definition) )
1297 {
1298 if( WKT1 ) { *WKT1 = Definition; }
1299 if( PROJ ) { *PROJ = Proj4 ; }
1300
1301 return( !WKT2 || !ESRI );
1302 }
1303
1304 //-------------------------------------------------
1306
1307 if( gSG_Projections._WKT1_from_Proj4(WKT, Definition) )
1308 {
1309 if( WKT1 ) { *WKT1 = WKT ; }
1310 if( PROJ ) { *PROJ = Definition; }
1311
1312 return( !WKT2 || !ESRI );
1313 }
1314 }
1315
1316 //-----------------------------------------------------
1317 return( false );
1318}
1319
1320
1322// //
1324
1325//---------------------------------------------------------
1327{
1328 CSG_Table Projections;
1329
1330 Projections.Add_Field("NAME", SG_DATATYPE_String);
1331 Projections.Add_Field("AUTH", SG_DATATYPE_String);
1332 Projections.Add_Field("CODE", SG_DATATYPE_Int );
1333 Projections.Add_Field("TYPE", SG_DATATYPE_String);
1334
1335 for(int i=0; i<m_pProjections->Get_Count(); i++)
1336 {
1337 CSG_Table_Record *pProjection = m_pProjections->Get_Record(i);
1338
1339 CSG_String WKT = pProjection->asString(PRJ_FIELD_SRTEXT);
1340
1341 if( WKT.Length() == 0 )
1342 {
1343 continue;
1344 }
1345
1346 ESG_CRS_Type _Type = Get_CRS_Type(WKT.BeforeFirst('['));
1347
1348 for(int j=0; _Type == ESG_CRS_Type::Undefined && j<2; j++)
1349 {
1350 WKT = WKT.AfterFirst('['); // check nested keys like "COMPOUNDRDS[..., GEOGCRS[" or "BOUNDCRS[SOURCECRS[GEODCRS["...
1351
1352 _Type = Get_CRS_Type(WKT.BeforeFirst('['));
1353 }
1354
1355 if( _Type != ESG_CRS_Type::Undefined && (Type == ESG_CRS_Type::Undefined || Type == _Type) )
1356 {
1357 CSG_Table_Record &Projection = *Projections.Add_Record();
1358
1359 Projection.Set_Value(0, WKT.AfterFirst('\"').BeforeFirst('\"'));
1360 Projection.Set_Value(1, pProjection->asString(PRJ_FIELD_AUTH_NAME));
1361 Projection.Set_Value(2, pProjection->asInt (PRJ_FIELD_AUTH_SRID));
1363 }
1364 }
1365
1366 CSG_String Names;
1367
1368 if( bAddSelect )
1369 {
1370 Names.Printf("{}<%s>|", _TL("select"));
1371 }
1372
1374
1375 for(int i=0; i<Projections.Get_Count(); i++)
1376 {
1377 if( Type == ESG_CRS_Type::Undefined )
1378 {
1379 Names += CSG_String::Format("{%s:%d}%s: %s|",
1380 Projections[i].asString(1),
1381 Projections[i].asInt (2),
1382 Projections[i].asString(3),
1383 Projections[i].asString(0)
1384 );
1385 }
1386 else
1387 {
1388 Names += CSG_String::Format("{%s:%d}%s|",
1389 Projections[i].asString(1),
1390 Projections[i].asInt (2),
1391 Projections[i].asString(0)
1392 );
1393 }
1394 }
1395
1396 return( Names );
1397}
1398
1399
1401// //
1403
1404//---------------------------------------------------------
1405bool CSG_Projections::_WKT2_to_MetaData(CSG_MetaData &MetaData, const CSG_String &WKT)
1406{
1407 if( WKT.is_Empty() )
1408 {
1409 return( false );
1410 }
1411
1412 int Colon = -1, Bracket = -1;
1413
1414 for(int i=0, bracket=0, quota=0; Colon<0 && i<(int)WKT.Length(); i++)
1415 {
1416 switch( WKT[i] )
1417 {
1418 case '[':
1419 bracket++; if( bracket == 1 ) { Bracket = i; }
1420 break;
1421
1422 case ']':
1423 bracket--; if( bracket < 0 ) { return( false ); }
1424 break;
1425
1426 case '\"':
1427 if( bracket == 0 )
1428 {
1429 quota = quota ? 0 : 1;
1430 }
1431 break;
1432
1433 case ',':
1434 if( bracket == 0 && quota == 0 )
1435 {
1436 Colon = i;
1437 }
1438 break;
1439 }
1440 }
1441
1442 CSG_String Value = Colon < 0 ? WKT : WKT.Left(Colon);
1443
1444 if( Bracket < 0 )
1445 {
1446 Value.Trim_Both();
1447
1448 if( Value.Find('\"') == 0 )
1449 {
1450 Value = Value.AfterFirst('\"').BeforeLast('\"'); Value.Trim_Both();
1451
1452 MetaData.Add_Property("NAME" , Value);
1453 }
1454 else
1455 {
1456 MetaData.Add_Child(CSG_String::Format("VAL%d", 1 + MetaData.Get_Children_Count()), Value);
1457 }
1458 }
1459 else
1460 {
1461 CSG_String Key(Value.Left(Bracket)); Key.Trim_Both();
1462
1463 CSG_String Content(Value.AfterFirst('[').BeforeLast(']')); Content.Trim_Both(); Content.Replace("\n", "");
1464
1465 _WKT2_to_MetaData(*MetaData.Add_Child(Key), Content);
1466 }
1467
1468 if( Colon > 0 )
1469 {
1470 _WKT2_to_MetaData(MetaData, WKT.Right(WKT.Length() - Colon - 1));
1471 }
1472
1473 return( true );
1474}
1475
1476//---------------------------------------------------------
1477CSG_MetaData CSG_Projections::_WKT2_to_MetaData(const CSG_String &WKT, bool bTrim)
1478{
1479 CSG_MetaData MetaData; _WKT2_to_MetaData(MetaData, WKT);
1480
1481 if( MetaData.Get_Children_Count() == 1 )
1482 {
1483 CSG_MetaData *pMetaData = MetaData.Get_Child(0);
1484
1485 if( bTrim ) // check nested keys like "COMPOUNDRDS[..., GEOGCRS[..." or "BOUNDCRS[SOURCECRS[GEODCRS[..."
1486 {
1488
1489 for(int j=0; Type == ESG_CRS_Type::Undefined && pMetaData->Get_Child(0) && j<2; j++)
1490 {
1491 pMetaData = pMetaData->Get_Child(0);
1492
1493 Type = CSG_Projections::Get_CRS_Type(pMetaData->Get_Name());
1494 }
1495 }
1496
1497 return( *pMetaData );
1498 }
1499
1500 MetaData.Destroy();
1501
1502 return( MetaData );
1503}
1504
1505//---------------------------------------------------------
1507{
1508 CSG_String XML;
1509
1510 if( !WKT.is_Empty() )
1511 {
1512 XML = _WKT2_to_MetaData(WKT, false).asText(1);
1513 }
1514
1515 return( XML );
1516}
1517
1518
1520// //
1522
1523//---------------------------------------------------------
1524bool CSG_Projections::_WKT1_to_MetaData(CSG_MetaData &MetaData, const CSG_String &WKT)
1525{
1526 CSG_String Key; CSG_Strings Content; Content.Add("");
1527
1528 for(int i=0, l=-1; l!=0 && i<(int)WKT.Length(); i++)
1529 {
1530 if( l < 0 ) // read key
1531 {
1532 switch( WKT[i] )
1533 {
1534 default : Key += WKT[i]; break;
1535 case ' ' : break;
1536 case '[': case '(': l = 1 ; break;
1537 case ')': case ']': return( false );
1538 }
1539 }
1540 else // read content
1541 {
1542 bool bAdd;
1543
1544 switch( WKT[i] )
1545 {
1546 default : bAdd = true; break;
1547 case '\"' : bAdd = false; break;
1548 case '[' : case '(': bAdd = ++l > 1; break;
1549 case ']' : case ')': bAdd = l-- > 1; break;
1550 case ',' : if( !(bAdd = l > 1) ) Content.Add(""); break;
1551 }
1552
1553 if( bAdd )
1554 {
1555 Content[Content.Get_Count() - 1] += WKT[i];
1556 }
1557 }
1558 }
1559
1560 if( Key.is_Empty() || Content[0].is_Empty() )
1561 {
1562 return( false );
1563 }
1564
1565 //-----------------------------------------------------
1566 if( !Key.Cmp("AUTHORITY") && Content.Get_Count() == 2 ) // AUTHORITY ["<name>", "<code>"]
1567 {
1568 MetaData.Add_Property("authority_name", Content[0]);
1569 MetaData.Add_Property("authority_code", Content[1]);
1570
1571 return( true );
1572 }
1573
1574 CSG_MetaData *pKey = MetaData.Add_Child(Key);
1575
1576 if( (!Key.Cmp("GEOCCS" ) && Content.Get_Count() >= 4) // GEOCCS ["<name>", <datum>, <prime meridian>, <linear unit> {,<axis>, <axis>, <axis>} {,<authority>}]
1577 || (!Key.Cmp("GEOGCS" ) && Content.Get_Count() >= 4) // GEOGCS ["<name>", <datum>, <prime meridian>, <angular unit> {,<twin axes>} {,<authority>}]
1578 || (!Key.Cmp("PROJCS" ) && Content.Get_Count() >= 3) // PROJCS ["<name>", <geographic cs>, <projection>, {<parameter>,}* <linear unit> {,<twin axes>}{,<authority>}]
1579 || (!Key.Cmp("DATUM" ) && Content.Get_Count() >= 2) ) // DATUM ["<name>", <spheroid> {,<to wgs84>} {,<authority>}]
1580 {
1581 pKey->Add_Property("name", Content[0]);
1582 }
1583
1584 if( (!Key.Cmp("PRIMEM" ) && Content.Get_Count() >= 2) // PRIMEM ["<name>", <longitude> {,<authority>}]
1585 || (!Key.Cmp("UNIT" ) && Content.Get_Count() >= 2) // UNIT ["<name>", <conversion factor> {,<authority>}]
1586 || (!Key.Cmp("AXIS" ) && Content.Get_Count() >= 2) // AXIS ["<name>", NORTH|SOUTH|EAST|WEST|UP|DOWN|OTHER]
1587 || (!Key.Cmp("PARAMETER" ) && Content.Get_Count() >= 2) ) // PARAMETER ["<name>", <value>]
1588 {
1589 pKey->Add_Property("name", Content[0]);
1590
1591 pKey->Set_Content(Content[1]);
1592 }
1593
1594 if( (!Key.Cmp("SPHEROID" ) && Content.Get_Count() >= 3) ) // SPHEROID ["<name>", <semi-major axis>, <inverse flattening> {,<authority>}]
1595 {
1596 pKey->Add_Property("name", Content[0]);
1597 pKey->Add_Child ("a" , Content[1]);
1598 pKey->Add_Child ("rf" , Content[2]);
1599 }
1600
1601 if( (!Key.Cmp("TOWGS84" ) && Content.Get_Count() >= 7) ) // TOWGS84 [<dx>, <dy>, <dz>, <rx>, <ry>, <rz>, <sc>]
1602 {
1603 pKey->Add_Child("dx" , Content[0]);
1604 pKey->Add_Child("dy" , Content[1]);
1605 pKey->Add_Child("dz" , Content[2]);
1606 pKey->Add_Child("rx" , Content[3]);
1607 pKey->Add_Child("ry" , Content[4]);
1608 pKey->Add_Child("rz" , Content[5]);
1609 pKey->Add_Child("sc" , Content[6]);
1610 }
1611
1612 if( (!Key.Cmp("EXTENSION" ) && Content.Get_Count() >= 2) ) // EXTENSION [<name>, <value>]
1613 {
1614 pKey->Add_Property("name", Content[0]);
1615 pKey->Set_Content( Content[1]);
1616 }
1617
1618 if( (!Key.Cmp("PROJECTION") && Content.Get_Count() >= 1) ) // PROJECTION ["<name>" {,<authority>}]
1619 {
1620 pKey->Set_Content(Content[0]);
1621 }
1622
1623 //-----------------------------------------------------
1624 for(int i=0; i<Content.Get_Count(); i++)
1625 {
1626 _WKT1_to_MetaData(*pKey, Content[i]);
1627 }
1628
1629 return( true );
1630}
1631
1632//---------------------------------------------------------
1633CSG_MetaData CSG_Projections::_WKT1_to_MetaData(const CSG_String &WKT)
1634{
1635 CSG_MetaData MetaData;
1636
1637 _WKT1_to_MetaData(MetaData, WKT);
1638
1639 if( MetaData.Get_Children_Count() == 1 )
1640 {
1641 return( *MetaData.Get_Child(0) );
1642 }
1643
1644 MetaData.Destroy();
1645
1646 return( MetaData );
1647}
1648
1649
1651// //
1653
1654//---------------------------------------------------------
1655// DATUM ["<name>",
1656// SPHEROID["<name>", <semi-major axis>, <inverse flattening>]
1657// *TOWGS84 [<dx>, <dy>, <dz>, <rx>, <ry>, <rz>, <sc>]
1658// ]
1659//---------------------------------------------------------
1660bool CSG_Projections::_WKT1_to_Proj4_Set_Datum(CSG_String &Proj4, const CSG_MetaData &WKT) const
1661{
1662 if( WKT.Cmp_Property("name", "WGS84") )
1663 {
1664 Proj4 += " +datum=WGS84";
1665
1666 return( true );
1667 }
1668
1669 double a, b;
1670
1671 if( !WKT("SPHEROID") || WKT["SPHEROID"].Get_Children_Count() != 2
1672 || !WKT["SPHEROID"][0].Get_Content().asDouble(a) || a <= 0.
1673 || !WKT["SPHEROID"][1].Get_Content().asDouble(b) || b < 0. )
1674 {
1675 return( false );
1676 }
1677
1678 b = b > 0. ? a - a / b : a;
1679
1680 Proj4 += CSG_String::Format(" +a=%f", a); // Semimajor radius of the ellipsoid axis
1681 Proj4 += CSG_String::Format(" +b=%f", b); // Semiminor radius of the ellipsoid axis
1682
1683 if( WKT("TOWGS84") && WKT["TOWGS84"].Get_Children_Count() == 7 )
1684 {
1685 Proj4 += " +towgs84=";
1686
1687 for(int i=0; i<7; i++)
1688 {
1689 if( i > 0 )
1690 {
1691 Proj4 += ",";
1692 }
1693
1694 Proj4 += WKT["TOWGS84"][i].Get_Content();
1695 }
1696 }
1697
1698 return( true );
1699}
1700
1701//---------------------------------------------------------
1702bool CSG_Projections::_WKT1_to_Proj4(CSG_String &Proj4, const CSG_String &WKT) const
1703{
1704 Proj4.Clear();
1705
1706 CSG_MetaData m = _WKT1_to_MetaData(WKT);
1707
1708 if( m.Get_Children_Count() == 0 )
1709 {
1710 return( false );
1711 }
1712
1713 //-----------------------------------------------------
1714 int Authority_Code; CSG_String Authority_Name;
1715
1716 if( m.Get_Property("authority_name", Authority_Name)
1717 && m.Get_Property("authority_code", Authority_Code) )
1718 {
1720
1721 if( Get_Projection(Projection, Authority_Code, Authority_Name) )
1722 {
1723 Proj4 = Projection.Get_PROJ();
1724
1725 return( true );
1726 }
1727 }
1728
1729 //-----------------------------------------------------
1730 double d;
1731
1732 //-----------------------------------------------------
1733 // GEOCCS["<name>",
1734 // DATUM ["<name>", ...],
1735 // PRIMEM ["<name>", <longitude>],
1736 // UNIT ["<name>", <conversion factor>],
1737 // *AXIS ["<name>", NORTH|SOUTH|EAST|WEST|UP|DOWN|OTHER], AXIS...
1738 // ]
1739 if( m.Cmp_Name("GEOCCS") )
1740 {
1741 Proj4 = CSG_String::Format("+proj=geocent");
1742
1743 if( !m("DATUM") || !_WKT1_to_Proj4_Set_Datum(Proj4, m["DATUM"]) )
1744 {
1745 return( false );
1746 }
1747
1748 if( m("PRIMEM") && m["PRIMEM"].Get_Content().asDouble(d) && d != 0. )
1749 {
1750 Proj4 += CSG_String::Format(" +pm=%f", d);
1751 }
1752
1753 Proj4 += CSG_String::Format(" +no_defs"); // Don't use the /usr/share/proj/proj_def.dat defaults file
1754
1755 return( true );
1756 }
1757
1758 //-----------------------------------------------------
1759 // GEOGCS["<name>,
1760 // DATUM ["<name>", ...],
1761 // PRIMEM ["<name>", <longitude>],
1762 // UNIT ["<name>", <conversion factor>],
1763 // *AXIS ["<name>", NORTH|SOUTH|EAST|WEST|UP|DOWN|OTHER], AXIS...
1764 // ]
1765 if( m.Cmp_Name("GEOGCS") )
1766 {
1767 Proj4 = "+proj=longlat";
1768
1769 if( !m("DATUM") || !_WKT1_to_Proj4_Set_Datum(Proj4, m["DATUM"]) )
1770 {
1771 return( false );
1772 }
1773
1774 if( m("PRIMEM") && m["PRIMEM"].Get_Content().asDouble(d) && d != 0. )
1775 {
1776 Proj4 += CSG_String::Format(" +pm=%f", d);
1777 }
1778
1779 Proj4 += CSG_String::Format(" +no_defs"); // Don't use the /usr/share/proj/proj_def.dat defaults file
1780
1781 return( true );
1782 }
1783
1784 //-----------------------------------------------------
1785 // PROJCS["<name>,
1786 // GEOGCS ["<name>, ...],
1787 // PROJECTION["<name>"],
1788 // *PARAMETER ["<name>", <value>], PARAMETER...
1789 // UNIT ["<name>", <conversion factor>],
1790 // *AXIS ["<name>", NORTH|SOUTH|EAST|WEST|UP|DOWN|OTHER], AXIS...
1791 // ]
1792 if( m.Cmp_Name("PROJCS") && m("GEOGCS") && m("PROJECTION") && m_WKT1_to_Proj4.Get_Translation(m["PROJECTION"].Get_Content(), Proj4) )
1793 {
1794 if( m["PROJECTION"].Cmp_Content("Transverse_Mercator") ) // UTM ???
1795 {
1796 double Scale = -1., Easting = -1., Northing = -1., Meridian = -1., Latitude = -1.;
1797
1798 for(int i=0; i<m.Get_Children_Count(); i++)
1799 {
1800 if( m[i].Cmp_Name("PARAMETER") )
1801 {
1802 double v;
1803
1804 if( m[i].Cmp_Property("name", "central_meridian" , true) && m[i].Get_Content().asDouble(v) ) Meridian = v;
1805 if( m[i].Cmp_Property("name", "latitude_of_origin", true) && m[i].Get_Content().asDouble(v) ) Latitude = v;
1806 if( m[i].Cmp_Property("name", "scale_factor" , true) && m[i].Get_Content().asDouble(v) ) Scale = v;
1807 if( m[i].Cmp_Property("name", "false_easting" , true) && m[i].Get_Content().asDouble(v) ) Easting = v;
1808 if( m[i].Cmp_Property("name", "false_northing" , true) && m[i].Get_Content().asDouble(v) ) Northing = v;
1809 }
1810 }
1811
1812 if( Latitude == 0. && Scale == 0.9996 && Easting == 500000. && (Northing == 0. || Northing == 10000000.) )
1813 {
1814 Proj4 = "+proj=utm";
1815
1816 if( !m["GEOGCS"]("DATUM") || !_WKT1_to_Proj4_Set_Datum(Proj4, m["GEOGCS"]["DATUM"]) )
1817 {
1818 return( false );
1819 }
1820
1821 Proj4 += CSG_String::Format(" +zone=%d", (int)((183. + Meridian) / 6.));
1822
1823 if( Northing == 10000000. )
1824 {
1825 Proj4 += " +south";
1826 }
1827
1828 Proj4 += CSG_String::Format(" +no_defs"); // Don't use the /usr/share/proj/proj_def.dat defaults file
1829
1830 return( true );
1831 }
1832 }
1833
1834 //-------------------------------------------------
1835 Proj4 = "+proj=" + Proj4;
1836
1837 if( !m["GEOGCS"]("DATUM") || !_WKT1_to_Proj4_Set_Datum(Proj4, m["GEOGCS"]["DATUM"]) )
1838 {
1839 return( false );
1840 }
1841
1842 if( m("PRIMEM") && m["PRIMEM"].Get_Content().asDouble(d) && d != 0. )
1843 {
1844 Proj4 += CSG_String::Format(" +pm=%f", d);
1845 }
1846
1847 for(int i=0; i<m.Get_Children_Count(); i++)
1848 {
1849 if( m[i].Cmp_Name("PARAMETER") )
1850 {
1851 CSG_String Parameter;
1852
1853 if( m_WKT1_to_Proj4.Get_Translation(m[i].Get_Property("name"), Parameter) )
1854 {
1855 Proj4 += " +" + Parameter + "=" + m[i].Get_Content();
1856 }
1857 else
1858 {
1859 SG_UI_Msg_Add_Error(CSG_String::Format(">> WKT: %s [%s]", _TL("unknown parameter"), m[i].Get_Property("name")));
1860 }
1861 }
1862 }
1863
1864 if( m("UNIT") && m["UNIT"].Get_Content().asDouble(d) && d != 0. && d != 1. )
1865 {
1866 Proj4 += CSG_String::Format(" +to_meter=%f", d);
1867 }
1868
1869 Proj4 += CSG_String::Format(" +no_defs"); // Don't use the /usr/share/proj/proj_def.dat defaults file
1870
1871 return( true );
1872 }
1873
1874 //-----------------------------------------------------
1875 return( false );
1876}
1877
1878
1880// //
1882
1883//---------------------------------------------------------
1884bool CSG_Projections::_Proj4_Find_Parameter(const CSG_String &Proj4, const CSG_String &Key)
1885{
1886 return( Proj4.Find("+" + Key) >= 0 );
1887}
1888
1889//---------------------------------------------------------
1890bool CSG_Projections::_Proj4_Read_Parameter(CSG_String &Value, const CSG_String &Proj4, const CSG_String &Key)
1891{
1892 Value.Clear();
1893
1894 int l, i = Proj4.Find("+" + Key + "=");
1895
1896 if( i >= 0 )
1897 {
1898 for(++i, l=0; l<2 && i<(int)Proj4.Length(); i++)
1899 {
1900 switch( Proj4[i] )
1901 {
1902 case '=': l++; break;
1903 case '+': l=2; break;
1904 case ' ': l=2; break;
1905 default :
1906 if( l == 1 )
1907 {
1908 Value += Proj4[i];
1909 }
1910 }
1911 }
1912 }
1913
1914 return( Value.Length() > 0 );
1915}
1916
1917//---------------------------------------------------------
1918bool CSG_Projections::_Proj4_Get_Ellipsoid(CSG_String &Value, const CSG_String &Proj4)
1919{
1920 const char ellipsoid[42][2][32] =
1921 { // ellipsoid a, b
1922 { "MERIT" , "6378137.0,298.257" }, // MERIT 1983
1923 { "SGS85" , "6378136.0,298.257" }, // Soviet Geodetic System 85
1924 { "GRS80" , "6378137.0,298.2572221" }, // GRS 1980 (IUGG, 1980)
1925 { "IAU76" , "6378140.0,298.257" }, // IAU 1976
1926 { "airy" , "6377563.396,299.3249753" }, // Airy 1830
1927 { "APL4.9" , "6378137.0,298.25" }, // Appl. Physics. 1965
1928 { "NWL9D" , "6378145.0,298.25" }, // Naval Weapons Lab., 1965
1929 { "mod_airy" , "6377340.189,299.3249374" }, // Modified Airy
1930 { "andrae" , "6377104.43,300" }, // Andrae 1876 (Den., Iclnd.)
1931 { "aust_SA" , "6378160.0,298.25" }, // Australian Natl & S. Amer. 1969
1932 { "GRS67" , "6378160.0,298.2471674" }, // GRS 67 (IUGG 1967)
1933 { "bessel" , "6377397.155,299.1528128" }, // Bessel 1841
1934 { "bess_nam" , "6377483.865,299.1528128" }, // Bessel 1841 (Namibia)
1935 { "clrk66" , "6378206.4,294.9786982" }, // Clarke 1866
1936 { "clrk80" , "6378249.145,293.4663" }, // Clarke 1880 mod.
1937 { "CPM" , "6375738.7,334.29" }, // Comm. des Poids et Mesures 1799
1938 { "delmbr" , "6376428.0,311.5" }, // Delambre 1810 (Belgium)
1939 { "engelis" , "6378136.05,298.2566" }, // Engelis 1985
1940 { "evrst30" , "6377276.345,300.8017" }, // Everest 1830
1941 { "evrst48" , "6377304.063,300.8017" }, // Everest 1948
1942 { "evrst56" , "6377301.243,300.8017" }, // Everest 1956
1943 { "evrst69" , "6377295.664,300.8017" }, // Everest 1969
1944 { "evrstSS" , "6377298.556,300.8017" }, // Everest (Sabah & Sarawak)
1945 { "fschr60" , "6378166.0,298.3" }, // Fischer (Mercury Datum) 1960
1946 { "fschr60m" , "6378155.0,298.3" }, // Modified Fischer 1960
1947 { "fschr68" , "6378150.0,298.3" }, // Fischer 1968
1948 { "helmert" , "6378200.0,298.3" }, // Helmert 1906
1949 { "hough" , "6378270.0,297" }, // Hough
1950 { "intl" , "6378388.0,297" }, // International 1909 (Hayford)
1951 { "krass" , "6378245.0,298.3" }, // Krassovsky, 1942
1952 { "kaula" , "6378163.0,298.24" }, // Kaula 1961
1953 { "lerch" , "6378139.0,298.257" }, // Lerch 1979
1954 { "mprts" , "6397300.0,191" }, // Maupertius 1738
1955 { "new_intl" , "6378157.5,298.2496154" }, // New International 1967
1956 { "plessis" , "6376523.0,308.6409971" }, // Plessis 1817 (France)
1957 { "SEasia" , "6378155.0,298.3000002" }, // Southeast Asia
1958 { "walbeck" , "6376896.0,302.7800002" }, // Walbeck
1959 { "WGS60" , "6378165.0,298.3" }, // WGS 60
1960 { "WGS66" , "6378145.0,298.25" }, // WGS 66
1961 { "WGS72" , "6378135.0,298.26" }, // WGS 72
1962 { "WGS84" , "6378137.0,298.2572236" }, // WGS 84
1963 { "sphere" , "6370997.0,-1" } // Normal Sphere (r=6370997)
1964 };
1965
1966 //-----------------------------------------------------
1967 if( _Proj4_Read_Parameter(Value, Proj4, "ellps") )
1968 {
1969 for(int i=0; i<42; i++)
1970 {
1971 if( !Value.CmpNoCase(ellipsoid[i][0]) )
1972 {
1973 Value.Printf("SPHEROID[\"%s\",%s]", SG_STR_MBTOSG(ellipsoid[i][0]), SG_STR_MBTOSG(ellipsoid[i][1]));
1974
1975 return( true );
1976 }
1977 }
1978 }
1979
1980 //-----------------------------------------------------
1981 double a = _Proj4_Read_Parameter(Value, Proj4, "a" ) && Value.asDouble(a) ? a : 6378137.;
1982
1983 double b = _Proj4_Read_Parameter(Value, Proj4, "b" ) && Value.asDouble(b) ? a / (a - b)
1984 : _Proj4_Read_Parameter(Value, Proj4, "rf") && Value.asDouble(b) ? b
1985 : _Proj4_Read_Parameter(Value, Proj4, "f" ) && Value.asDouble(b) ? 1. / b
1986 : _Proj4_Read_Parameter(Value, Proj4, "e" ) && Value.asDouble(b) ? a / (a - sqrt(b*b - a*a))
1987 : _Proj4_Read_Parameter(Value, Proj4, "es") && Value.asDouble(b) ? a / (a - sqrt( b - a*a))
1988 : 298.2572236;
1989
1990 Value = CSG_String::Format("SPHEROID[\"Ellipsoid\",%f,%f]", a, b);
1991
1992 return( true );
1993}
1994
1995//---------------------------------------------------------
1996bool CSG_Projections::_Proj4_Get_Datum(CSG_String &Value, const CSG_String &Proj4)
1997{
1998 const char datum[9][3][64] =
1999 { // datum_id ellipse definition
2000 { "WGS84" , "WGS84" , "0,0,0,0,0,0,0" },
2001 { "GGRS87" , "GRS80" , "-199.87,74.79,246.62,0,0,0,0" }, // Greek_Geodetic_Reference_System_1987
2002 { "NAD83" , "GRS80" , "0,0,0,0,0,0,0" }, // North_American_Datum_1983
2003 // { "NAD27" , "clrk66" , "nadgrids=@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat" }, // North_American_Datum_1927
2004 { "potsdam" , "bessel" , "606.0,23.0,413.0,0,0,0,0" }, // Potsdam Rauenberg 1950 DHDN
2005 { "carthage" , "clark80" , "-263.0,6.0,431.0,0,0,0,0" }, // Carthage 1934 Tunisia
2006 { "hermannskogel" , "bessel" , "653.0,-212.0,449.0,0,0,0,0" }, // Hermannskogel
2007 { "ire65" , "mod_airy" , "482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15" }, // Ireland 1965
2008 { "nzgd49" , "intl" , "59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993" }, // New Zealand Geodetic Datum 1949
2009 { "OSGB36" , "airy" , "446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894" } // Airy 1830
2010 };
2011
2012 CSG_String Spheroid, ToWGS84;
2013
2014 //-----------------------------------------------------
2015 if( _Proj4_Read_Parameter(Value, Proj4, "datum") )
2016 {
2017 for(int i=0; i<9; i++)
2018 {
2019 if( !Value.CmpNoCase(datum[i][0]) && _Proj4_Get_Ellipsoid(Spheroid, CSG_String::Format("+ellps=%s", SG_STR_MBTOSG(datum[i][1]))) )
2020 {
2021 Value.Printf("DATUM[\"%s\",%s,TOWGS84[%s]]", SG_STR_MBTOSG(datum[i][0]), Spheroid.c_str(), SG_STR_MBTOSG(datum[i][2]));
2022
2023 return( true );
2024 }
2025 }
2026 }
2027
2028 //-----------------------------------------------------
2029 if( _Proj4_Get_Ellipsoid(Spheroid, Proj4) )
2030 {
2031 Value = "DATUM[\"Datum\","+ Spheroid;
2032
2033 if( _Proj4_Read_Parameter(ToWGS84, Proj4, "towgs84") )
2034 {
2035 CSG_Strings s = SG_String_Tokenize(ToWGS84, ",");
2036
2037 if( s.Get_Count() == 3 )
2038 {
2039 ToWGS84 += ",0,0,0,0";
2040 }
2041
2042 Value += ",TOWGS84[" + ToWGS84 + "]";
2043 }
2044 else
2045 {
2046 Value += ",TOWGS84[0,0,0,0,0,0,0]";
2047 }
2048
2049 Value += "]";
2050
2051 return( true );
2052 }
2053
2054 //-----------------------------------------------------
2055 Value = "DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\",6378137,298.257223563],TOWGS84[0,0,0,0,0,0,0]]";
2056
2057 return( false );
2058}
2059
2060//---------------------------------------------------------
2061bool CSG_Projections::_Proj4_Get_Prime_Meridian(CSG_String &Value, const CSG_String &Proj4)
2062{
2063 const char meridian[12][2][16] =
2064 {
2065 { "lisbon" , "-9.131906111" },
2066 { "paris" , "2.337229167" },
2067 { "bogota" , "74.08091667" },
2068 { "madrid" , "-3.687911111" },
2069 { "rome" , "12.45233333" },
2070 { "bern" , "7.439583333" },
2071 { "jakarta" , "106.8077194" },
2072 { "ferro" , "-17.66666667" },
2073 { "brussels" , "4.367975" },
2074 { "stockholm" , "18.05827778" },
2075 { "athens" , "23.7163375" },
2076 { "oslo" , "10.72291667" }
2077 };
2078
2079 //-----------------------------------------------------
2080 if( _Proj4_Read_Parameter(Value, Proj4, "pm") )
2081 {
2082 for(int i=0; i<12; i++)
2083 {
2084 if( !Value.CmpNoCase(meridian[i][0]) )
2085 {
2086 Value.Printf("PRIMEM[\"%s\",%s]", SG_STR_MBTOSG(meridian[i][0]), SG_STR_MBTOSG(meridian[i][1]));
2087
2088 return( true );
2089 }
2090 }
2091
2092 double d;
2093
2094 if( Value.asDouble(d) && d != 0. )
2095 {
2096 Value.Printf("PRIMEM[\"Prime_Meridian\",%f]", d);
2097
2098 return( true );
2099 }
2100 }
2101
2102 //-----------------------------------------------------
2103 Value = "PRIMEM[\"Greenwich\",0]";
2104
2105 return( false );
2106}
2107
2108//---------------------------------------------------------
2109bool CSG_Projections::_Proj4_Get_Unit(CSG_String &Value, const CSG_String &Proj4)
2110{
2111 ESG_Projection_Unit Unit = _Proj4_Read_Parameter(Value, Proj4, "units") ? CSG_Projections::Get_Unit(Value) : ESG_Projection_Unit::Undefined;
2112
2113 if( Unit != ESG_Projection_Unit::Undefined )
2114 {
2115 Value = "UNIT[\"" + CSG_Projections::Get_Unit_Name(Unit) + "\"," + SG_Get_String(CSG_Projections::Get_Unit_To_Meter(Unit), -16) + "]";
2116
2117 return( true );
2118 }
2119
2120 //-----------------------------------------------------
2121 double d;
2122
2123 if( _Proj4_Read_Parameter(Value, Proj4, "to_meter") && Value.asDouble(d) && d > 0. && d != 1. )
2124 {
2125 Value.Printf("UNIT[\"Unit\",%f]", d);
2126
2127 return( true );
2128 }
2129
2130 //-----------------------------------------------------
2131 Value = "UNIT[\"metre\",1]";
2132// Value = "UNIT[\"degree\",0.01745329251994328]]";
2133
2134 return( false );
2135}
2136
2137//---------------------------------------------------------
2138bool CSG_Projections::_WKT1_from_Proj4(CSG_String &WKT, const CSG_String &Proj4) const
2139{
2140 CSG_String Value, ProjCS;
2141
2142 //-----------------------------------------------------
2143 if( !_Proj4_Read_Parameter(ProjCS, Proj4, "proj") )
2144 {
2145 SG_UI_Msg_Add_Error(CSG_String::Format("Proj4 >> WKT: %s", _TL("no projection type defined")));
2146
2147 return( false );
2148 }
2149
2150 //-----------------------------------------------------
2151 // GEOCCS["<name>
2152 // DATUM ["<name>
2153 // SPHEROID["<name>", <semi-major axis>, <inverse flattening>],
2154 // *TOWGS84 [<dx>, <dy>, <dz>, <rx>, <ry>, <rz>, <sc>]
2155 // ],
2156 // PRIMEM ["<name>", <longitude>],
2157 // UNIT ["<name>", <conversion factor>],
2158 // *AXIS ["<name>", NORTH|SOUTH|EAST|WEST|UP|DOWN|OTHER],
2159 // *AXIS ["<name>", NORTH|SOUTH|EAST|WEST|UP|DOWN|OTHER]
2160 // ]
2161
2162 if( !ProjCS.CmpNoCase("geocent") )
2163 {
2164 WKT = "GEOGCS[\"GCS\"";
2165
2166 if( _Proj4_Get_Datum (Value, Proj4) ) { WKT += "," + Value; }
2167 if( _Proj4_Get_Prime_Meridian(Value, Proj4) ) { WKT += "," + Value; }
2168 if( _Proj4_Get_Unit (Value, Proj4) ) { WKT += "," + Value; }
2169
2170 WKT += "]";
2171
2172 return( true );
2173 }
2174
2175 //-----------------------------------------------------
2176 // GEOGCS["<name>
2177 // DATUM ["<name>
2178 // SPHEROID["<name>", <semi-major axis>, <inverse flattening>],
2179 // *TOWGS84 [<dx>, <dy>, <dz>, <rx>, <ry>, <rz>, <sc>]
2180 // ],
2181 // PRIMEM ["<name>", <longitude>],
2182 // UNIT ["<name>", <conversion factor>],
2183 // *AXIS ["<name>", NORTH|SOUTH|EAST|WEST|UP|DOWN|OTHER],
2184 // *AXIS ["<name>", NORTH|SOUTH|EAST|WEST|UP|DOWN|OTHER]
2185 // ]
2186
2187 CSG_String GeogCS = "GEOGCS[\"GCS\"";
2188
2189 if( _Proj4_Get_Datum (Value, Proj4) ) { GeogCS += "," + Value; }
2190 if( _Proj4_Get_Prime_Meridian(Value, Proj4) ) { GeogCS += "," + Value; }
2191 if( _Proj4_Get_Unit (Value, Proj4) ) { GeogCS += "," + Value; } else { GeogCS += "UNIT[\"degree\",0.01745329251994328]"; }
2192
2193 GeogCS += "]";
2194
2195 if( !ProjCS.CmpNoCase("lonlat") || !ProjCS.CmpNoCase("longlat")
2196 || !ProjCS.CmpNoCase("latlon") || !ProjCS.CmpNoCase("latlong") )
2197 {
2198 WKT = GeogCS;
2199
2200 return( true );
2201 }
2202
2203 //-----------------------------------------------------
2204 // PROJCS["<name>
2205 // GEOGCS [ ...... ],
2206 // PROJECTION["<name>"],
2207 // *PARAMETER ["<name>", <value>], ...
2208 // UNIT ["<name>", <conversion factor>],
2209 // *AXIS ["<name>", NORTH|SOUTH|EAST|WEST|UP|DOWN|OTHER],
2210 // *AXIS ["<name>", NORTH|SOUTH|EAST|WEST|UP|DOWN|OTHER]
2211 // ]
2212
2213 if( !m_Proj4_to_WKT1.Get_Translation(ProjCS, Value) )
2214 {
2215 SG_UI_Msg_Add_Error(CSG_String::Format("Proj4 >> WKT: %s [%s]", _TL("no translation available"), ProjCS.c_str()));
2216
2217 // return( false );
2218 }
2219
2220 //-----------------------------------------------------
2221 // UTM ...
2222
2223 if( !ProjCS.CmpNoCase("utm") )
2224 {
2225 double Zone;
2226
2227 if( !_Proj4_Read_Parameter(Value, Proj4, "zone") || !Value.asDouble(Zone) )
2228 {
2229 SG_UI_Msg_Add_Error(CSG_String::Format("Proj4 >> WKT: %s", _TL("invalid utm zone")));
2230
2231 return( false );
2232 }
2233
2234 bool South = _Proj4_Find_Parameter(Proj4, "south");
2235
2236 WKT = CSG_String::Format("PROJCS[\"UTM zone %d%c\",%s,PROJECTION[Transverse_Mercator]", (int)Zone, South ? 'S' : 'N', GeogCS.c_str());
2237
2238 WKT += CSG_String::Format(",PARAMETER[\"%s\",%d]", SG_T("latitude_of_origin"), 0);
2239 WKT += CSG_String::Format(",PARAMETER[\"%s\",%d]", SG_T("central_meridian" ), (int)(Zone * 6 - 183));
2240 WKT += CSG_String::Format(",PARAMETER[\"%s\",%f]", SG_T("scale_factor" ), 0.9996);
2241 WKT += CSG_String::Format(",PARAMETER[\"%s\",%d]", SG_T("false_easting" ), 500000);
2242 WKT += CSG_String::Format(",PARAMETER[\"%s\",%d]", SG_T("false_northing" ), South ? 10000000 : 0);
2243 WKT += ",UNIT[\"metre\",1]]";
2244
2245 return( true );
2246 }
2247
2248 //-----------------------------------------------------
2249 // Parameters ...
2250
2251 WKT = CSG_String::Format("PROJCS[\"%s\",%s,PROJECTION[%s]", Value.c_str(), GeogCS.c_str(), Value.c_str());
2252
2253 ProjCS = Proj4;
2254
2255 while( ProjCS.Find('+') >= 0 )
2256 {
2257 CSG_String Key;
2258
2259 ProjCS = ProjCS.AfterFirst ('+');
2260 Value = ProjCS.BeforeFirst('=');
2261
2262 if( m_Proj4_to_WKT1.Get_Translation(Value, Key) )
2263 {
2264 Value = ProjCS.AfterFirst('=');
2265
2266 if( Value.Find('+') >= 0 )
2267 {
2268 Value = Value.BeforeFirst('+');
2269 }
2270
2271 WKT += ",PARAMETER[\"" + Key + "\"," + Value + "]";
2272 }
2273 }
2274
2275 //-----------------------------------------------------
2276 // Unit ...
2277
2278 if( _Proj4_Get_Unit(Value, Proj4) ) { WKT += "," + Value; }
2279
2280 //-----------------------------------------------------
2281 WKT += "]";
2282
2283 return( true );
2284}
2285
2286
2288// //
2289// //
2290// //
2292
2293//---------------------------------------------------------
2295{
2296 if( !Identifier.CmpNoCase("PROJCS") || !Identifier.CmpNoCase("PROJCRS") ) { return( ESG_CRS_Type::Projection ); }
2297 if( !Identifier.CmpNoCase("GEOGCS") || !Identifier.CmpNoCase("GEOGCRS") ) { return( ESG_CRS_Type::Geographic ); }
2298 if( !Identifier.CmpNoCase("GEOCCS") || !Identifier.CmpNoCase("GEOCCRS") ) { return( ESG_CRS_Type::Geocentric ); }
2299 if( !Identifier.CmpNoCase("GEODCS") || !Identifier.CmpNoCase("GEODCRS") ) { return( ESG_CRS_Type::Geodetic ); }
2300
2301 return( ESG_CRS_Type::Undefined );
2302}
2303
2304//---------------------------------------------------------
2306{
2307 switch( Type )
2308 {
2309 case ESG_CRS_Type::Projection: return( "PROJCRS" );
2310 case ESG_CRS_Type::Geographic: return( "GEOGCRS" );
2311 case ESG_CRS_Type::Geocentric: return( "GEOCCRS" );
2312 case ESG_CRS_Type::Geodetic : return( "GEODCRS" );
2313 default : return( "UNDEFINED" );
2314 }
2315}
2316
2317//---------------------------------------------------------
2319{
2320 switch( Type )
2321 {
2322 case ESG_CRS_Type::Projection: return( _TL("Projected Coordinate System" ) );
2323 case ESG_CRS_Type::Geographic: return( _TL("Geographic Coordinate System") );
2324 case ESG_CRS_Type::Geocentric: return( _TL("Geocentric Coordinate System") );
2325 case ESG_CRS_Type::Geodetic : return( _TL("Geodetic Coordinate System" ) );
2326 default : return( _TL("Unknown Coordinate System" ) );
2327 }
2328}
2329
2330//---------------------------------------------------------
2332{
2333 for(int i=0; i<(int)ESG_Projection_Unit::Undefined; i++)
2334 {
2336
2337 if( !Identifier.CmpNoCase(Get_Unit_Identifier(Unit))
2338 || !Identifier.CmpNoCase(Get_Unit_Name (Unit)) )
2339 {
2340 return( Unit );
2341 }
2342 }
2343
2344 return( !Identifier.CmpNoCase("metre") ? ESG_Projection_Unit::Meter : ESG_Projection_Unit::Undefined );
2345}
2346
2347//---------------------------------------------------------
2349{
2350 switch( Unit )
2351 {
2352 case ESG_Projection_Unit::Kilometer : return( "km" ); // Kilometers
2353 case ESG_Projection_Unit::Meter : return( "m" ); // Meters
2354 case ESG_Projection_Unit::Decimeter : return( "dm" ); // Decimeters
2355 case ESG_Projection_Unit::Centimeter : return( "cm" ); // Centimeters
2356 case ESG_Projection_Unit::Millimeter : return( "mm" ); // Millimeters
2357 case ESG_Projection_Unit::Int_Nautical_Mile: return( "kmi" ); // Miles
2358 case ESG_Projection_Unit::Int_Inch : return( "in" ); // Inches
2359 case ESG_Projection_Unit::Int_Foot : return( "ft" ); // Feet
2360 case ESG_Projection_Unit::Int_Yard : return( "yd" ); // Yards
2361 case ESG_Projection_Unit::Int_Statute_Mile : return( "mi" ); // Miles
2362 case ESG_Projection_Unit::Int_Fathom : return( "fath" ); // Fathoms
2363 case ESG_Projection_Unit::Int_Chain : return( "ch" ); // Chains
2364 case ESG_Projection_Unit::Int_Link : return( "link" ); // Links
2365 case ESG_Projection_Unit::US_Inch : return( "us-in" ); // Inches
2366 case ESG_Projection_Unit::US_Foot : return( "us-ft" ); // Feet
2367 case ESG_Projection_Unit::US_Yard : return( "us-yd" ); // Yards
2368 case ESG_Projection_Unit::US_Chain : return( "us-ch" ); // Chains
2369 case ESG_Projection_Unit::US_Statute_Mile : return( "us-mi" ); // Miles
2370 case ESG_Projection_Unit::Indian_Yard : return( "ind-yd" ); // Yards
2371 case ESG_Projection_Unit::Indian_Foot : return( "ind-ft" ); // Feet
2372 case ESG_Projection_Unit::Indian_Chain : return( "ind-ch" ); // Chains
2373 default: return( "" );
2374 };
2375}
2376
2377//---------------------------------------------------------
2379{
2380 switch( Unit )
2381 {
2382 case ESG_Projection_Unit::Kilometer : return( bSimple ? "Kilometers" : "Kilometer" );
2383 case ESG_Projection_Unit::Meter : return( bSimple ? "Meters" : "Meter" );
2384 case ESG_Projection_Unit::Decimeter : return( bSimple ? "Decimeters" : "Decimeter" );
2385 case ESG_Projection_Unit::Centimeter : return( bSimple ? "Centimeters" : "Centimeter" );
2386 case ESG_Projection_Unit::Millimeter : return( bSimple ? "Millimeters" : "Millimeter" );
2387 case ESG_Projection_Unit::Int_Nautical_Mile: return( bSimple ? "Miles" : "International Nautical Mile" );
2388 case ESG_Projection_Unit::Int_Inch : return( bSimple ? "Inches" : "International Inch" );
2389 case ESG_Projection_Unit::Int_Foot : return( bSimple ? "Feet" : "International Foot" );
2390 case ESG_Projection_Unit::Int_Yard : return( bSimple ? "Yards" : "International Yard" );
2391 case ESG_Projection_Unit::Int_Statute_Mile : return( bSimple ? "Miles" : "International Statute Mile" );
2392 case ESG_Projection_Unit::Int_Fathom : return( bSimple ? "Fathoms" : "International Fathom" );
2393 case ESG_Projection_Unit::Int_Chain : return( bSimple ? "Chains" : "International Chain" );
2394 case ESG_Projection_Unit::Int_Link : return( bSimple ? "Links" : "International Link" );
2395 case ESG_Projection_Unit::US_Inch : return( bSimple ? "Inches" : "U.S. Surveyor's Inch" );
2396 case ESG_Projection_Unit::US_Foot : return( bSimple ? "Feet" : "U.S. Surveyor's Foot" );
2397 case ESG_Projection_Unit::US_Yard : return( bSimple ? "Yards" : "U.S. Surveyor's Yard" );
2398 case ESG_Projection_Unit::US_Chain : return( bSimple ? "Chains" : "U.S. Surveyor's Chain" );
2399 case ESG_Projection_Unit::US_Statute_Mile : return( bSimple ? "Miles" : "U.S. Surveyor's Statute Mile" );
2400 case ESG_Projection_Unit::Indian_Yard : return( bSimple ? "Yards" : "Indian Yard" );
2401 case ESG_Projection_Unit::Indian_Foot : return( bSimple ? "Feet" : "Indian Foot" );
2402 case ESG_Projection_Unit::Indian_Chain : return( bSimple ? "Chains" : "Indian Chain" );
2403 default: return( "" );
2404 }
2405}
2406
2407//---------------------------------------------------------
2409{
2410 switch( Unit )
2411 {
2412 case ESG_Projection_Unit::Kilometer : return( 1000. );
2413 case ESG_Projection_Unit::Meter : return( 1. );
2414 case ESG_Projection_Unit::Decimeter : return( 0.1 );
2415 case ESG_Projection_Unit::Centimeter : return( 0.01 );
2416 case ESG_Projection_Unit::Millimeter : return( 0.001 );
2417 case ESG_Projection_Unit::Int_Nautical_Mile: return( 1852. );
2418 case ESG_Projection_Unit::Int_Inch : return( 0.0254 );
2419 case ESG_Projection_Unit::Int_Foot : return( 0.3048 );
2420 case ESG_Projection_Unit::Int_Yard : return( 0.9144 );
2421 case ESG_Projection_Unit::Int_Statute_Mile : return( 1609.344 );
2422 case ESG_Projection_Unit::Int_Fathom : return( 1.8288 );
2423 case ESG_Projection_Unit::Int_Chain : return( 20.1168 );
2424 case ESG_Projection_Unit::Int_Link : return( 0.201168 );
2425 case ESG_Projection_Unit::US_Inch : return( 1. / 39.37 );
2426 case ESG_Projection_Unit::US_Foot : return( 0.304800609601219 );
2427 case ESG_Projection_Unit::US_Yard : return( 0.914401828803658 );
2428 case ESG_Projection_Unit::US_Chain : return( 20.11684023368047 );
2429 case ESG_Projection_Unit::US_Statute_Mile : return( 1609.347218694437 );
2430 case ESG_Projection_Unit::Indian_Yard : return( 0.91439523 );
2431 case ESG_Projection_Unit::Indian_Foot : return( 0.30479841 );
2432 case ESG_Projection_Unit::Indian_Chain : return( 20.11669506 );
2433 default : return( 1. );
2434 }
2435}
2436
2437
2439// //
2440// //
2441// //
2443
2444//---------------------------------------------------------
2445bool CSG_Projections::_Set_Dictionary(CSG_Table &Dictionary, int Direction)
2446{
2447 const char Translation[][4][128] = {
2448// { PROJ4 , DIR , WELL-KNOWN-TEXT , DESCRIPTION, *) projection type not verified
2449
2450// --- projection types ---
2451 { "aea" , " ", "Albers_Conic_Equal_Area" , "Albers Equal Area" },
2452 { "aea" , "<", "Albers" , "[ESRI] Albers Equal Area" },
2453 { "aeqd" , " ", "Azimuthal_Equidistant" , "Azimuthal Equidistant" },
2454 { "airy" , " ", "Airy 1830" , "Airy 1830" },
2455 { "aitoff" , " ", "Sphere_Aitoff" , "Aitoff" },
2456 { "alsk" , " ", "Mod_Stererographics_of_Alaska" , "*) Mod. Stererographics of Alaska" },
2457 { "Amersfoort" , "<", "D_Amersfoort" , "[ESRI] datum RD_NEW" },
2458 { "Amersfoort" , "<", "GCS_Amersfoort" , "[ESRI] GCS RD_NEW" },
2459 { "Amersfoort / RD New", "<", "Amersfoort_RD_New" , "[ESRI] RD_NEW" },
2460 { "apian" , " ", "Apian_Globular_I" , "*) Apian Globular I" },
2461 { "august" , " ", "August_Epicycloidal" , "*) August Epicycloidal" },
2462 { "bacon" , " ", "Bacon_Globular" , "*) Bacon Globular" },
2463 { "bipc" , " ", "Bipolar_conic_of_western_hemisphere" , "*) Bipolar conic of western hemisphere" },
2464 { "boggs" , " ", "Boggs_Eumorphic" , "*) Boggs Eumorphic" },
2465 { "bonne" , " ", "Bonne" , "Bonne (Werner lat_1=90)" },
2466 { "cass" , " ", "Cassini_Soldner" , "Cassini" },
2467 { "cass" , "<", "Cassini" , "[ESRI] Cassini" },
2468 { "cc" , " ", "Central_Cylindrical" , "*) Central Cylindrical" },
2469 { "cea" , " ", "Cylindrical_Equal_Area" , "Equal Area Cylindrical, alias: Lambert Cyl.Eq.A., Normal Authalic Cyl. (FME), Behrmann (SP=30), Gall Orthogr. (SP=45)" },
2470 { "cea" , "<", "Behrmann" , "[ESRI] Behrmann (standard parallel = 30)" },
2471 { "chamb" , " ", "Chamberlin_Trimetric" , "*) Chamberlin Trimetric" },
2472 { "collg" , " ", "Collignon" , "*) Collignon" },
2473 { "crast" , " ", "Craster_Parabolic" , "[ESRI] Craster Parabolic (Putnins P4)" },
2474 { "denoy" , " ", "Denoyer_Semi_Elliptical" , "*) Denoyer Semi-Elliptical" },
2475 { "eck1" , " ", "Eckert_I" , "*) Eckert I" },
2476 { "eck2" , " ", "Eckert_II" , "*) Eckert II" },
2477 { "eck3" , " ", "Eckert_III" , "*) Eckert III" },
2478 { "eck4" , " ", "Eckert_IV" , "Eckert IV" },
2479 { "eck5" , " ", "Eckert_V" , "*) Eckert V" },
2480 { "eck6" , " ", "Eckert_VI" , "Eckert VI" },
2481 { "eqearth" , " ", "Equal_Earth" , "*) Equal Earth" },
2482 { "eqc" , " ", "Equirectangular" , "Equidistant Cylindrical (Plate Caree)" },
2483 { "eqc" , "<", "Equidistant_Cylindrical" , "[ESRI] Equidistant Cylindrical (Plate Caree)" },
2484 { "eqc" , "<", "Plate_Carree" , "[ESRI] Equidistant Cylindrical (Plate Caree)" },
2485 { "eqdc" , " ", "Equidistant_Conic" , "*) Equidistant Conic" },
2486 { "euler" , " ", "Euler" , "*) Euler" },
2487 { "etmerc" , " ", "Extended_Transverse_Mercator" , "*) Extended Transverse Mercator" },
2488 { "fahey" , " ", "Fahey" , "*) Fahey" },
2489 { "fouc" , " ", "Foucault" , "*) Foucaut" },
2490 { "fouc_s" , " ", "Foucault_Sinusoidal" , "*) Foucaut Sinusoidal" },
2491 { "gall" , " ", "Gall_Stereographic" , "Gall (Gall Stereographic)" },
2492 { "geocent" , " ", "Geocentric" , "*) Geocentric" },
2493 { "geos" , " ", "GEOS" , "Geostationary Satellite View" },
2494 { "gins8" , " ", "Ginsburg_VIII" , "*) Ginsburg VIII (TsNIIGAiK)" },
2495 { "gn_sinu" , " ", "General_Sinusoidal_Series" , "*) General Sinusoidal Series" },
2496 { "gnom" , " ", "Gnomonic" , "Gnomonic" },
2497 { "goode" , " ", "Goode_Homolosine" , "*) Goode Homolosine" },
2498 { "gs48" , " ", "Mod_Stererographics_48" , "*) Mod. Stererographics of 48 U.S." },
2499 { "gs50" , " ", "Mod_Stererographics_50" , "*) Mod. Stererographics of 50 U.S." },
2500 { "hammer" , " ", "Hammer_Eckert_Greifendorff" , "*) Hammer & Eckert-Greifendorff" },
2501 { "hatano" , " ", "Hatano_Asymmetrical_Equal_Area" , "*) Hatano Asymmetrical Equal Area" },
2502 { "igh" , " ", "Interrupted_Goodes_Homolosine" , "*) Interrupted Goode's Homolosine" },
2503 { "igh_o" , " ", "Interrupted_Goodes_Homolosine_Ocean" , "*) Interrupted Goode's Homolosine (Ocean)" },
2504 { "imw_p" , " ", "International_Map_of_the_World_Polyconic" , "*) International Map of the World Polyconic" },
2505 { "kav5" , " ", "Kavraisky_V" , "*) Kavraisky V" },
2506 { "kav7" , " ", "Kavraisky_VII" , "*) Kavraisky VII" },
2507 { "krovak" , " ", "Krovak" , "Krovak" },
2508 { "labrd" , " ", "Laborde_Oblique_Mercator" , "*) Laborde" },
2509 { "laea" , " ", "Lambert_Azimuthal_Equal_Area" , "Lambert Azimuthal Equal Area" },
2510 { "lagrng" , " ", "Lagrange" , "*) Lagrange" },
2511 { "larr" , " ", "Larrivee" , "*) Larrivee" },
2512 { "lask" , " ", "Laskowski" , "*) Laskowski" },
2513 { "lcc" , "<", "Lambert_Conformal_Conic_1SP" , "Lambert Conformal Conic (1 standard parallel)" },
2514 { "lcc" , "<", "Lambert_Conformal_Conic_2SP" , "Lambert Conformal Conic (2 standard parallels)" },
2515 { "lcc" , " ", "Lambert_Conformal_Conic" , "Lambert Conformal Conic" },
2516 { "lcca" , " ", "Lambert_Conformal_Conic_Alternative" , "*) Lambert Conformal Conic Alternative" },
2517 { "leac" , " ", "Lambert_Equal_Area_Conic" , "*) Lambert Equal Area Conic" },
2518 { "lee_os" , " ", "Lee_Oblated_Stereographic" , "*) Lee Oblated Stereographic" },
2519 { "loxim" , " ", "Loximuthal" , "[ESRI] Loximuthal" },
2520 { "lsat" , " ", "Space_oblique_for_LANDSAT" , "*) Space oblique for LANDSAT" },
2521 { "mbt_s" , " ", "McBryde_Thomas_Flat_Polar_Sine" , "*) McBryde-Thomas Flat-Polar Sine" },
2522 { "mbt_fps" , " ", "McBryde_Thomas_Flat_Polar_Sine_2" , "*) McBryde-Thomas Flat-Pole Sine (No. 2)" },
2523 { "mbtfpp" , " ", "McBryde_Thomas_Flat_Polar_Parabolic" , "*) McBride-Thomas Flat-Polar Parabolic" },
2524 { "mbtfpq" , " ", "Flat_Polar_Quartic" , "[ESRI] McBryde-Thomas Flat-Polar Quartic" },
2525 { "mbtfps" , " ", "McBryde_Thomas_Flat_Polar_Sinusoidal" , "*) McBryde-Thomas Flat-Polar Sinusoidal" },
2526 { "merc" , " ", "Mercator" , "[ESRI] Mercator" },
2527 { "merc" , "<", "Mercator_1SP" , "Mercator (1 standard parallel)" },
2528 { "merc" , "<", "Mercator_2SP" , "Mercator (2 standard parallels)" },
2529 { "mil_os" , " ", "Miller_Oblated_Stereographic" , "*) Miller Oblated Stereographic" },
2530 { "mill" , " ", "Miller_Cylindrical" , "Miller Cylindrical" },
2531 { "moll" , " ", "Mollweide" , "Mollweide" },
2532 { "murd1" , " ", "Murdoch_I" , "*) Murdoch I" },
2533 { "murd2" , " ", "Murdoch_II" , "*) Murdoch II" },
2534 { "murd3" , " ", "Murdoch_III" , "*) Murdoch III" },
2535 { "nell" , " ", "Nell" , "*) Nell" },
2536 { "nell_h" , " ", "Nell_Hammer" , "*) Nell-Hammer" },
2537 { "nicol" , " ", "Nicolosi_Globular" , "*) Nicolosi Globular" },
2538 { "nsper" , " ", "Near_sided_perspective" , "*) Near-sided perspective" },
2539 { "nzmg" , " ", "New_Zealand_Map_Grid" , "New Zealand Map Grid" },
2540 { "ob_tran" , " ", "General_Oblique_Transformation" , "*) General Oblique Transformation" },
2541 { "ocea" , " ", "Oblique_Cylindrical_Equal_Area" , "*) Oblique Cylindrical Equal Area" },
2542 { "oea" , " ", "Oblated_Equal_Area" , "*) Oblated Equal Area" },
2543 { "omerc" , " ", "Hotine_Oblique_Mercator" , "Oblique Mercator" },
2544 { "omerc" , "<", "Oblique_Mercator" , "Oblique Mercator" },
2545 { "ortel" , " ", "Ortelius_Oval" , "*) Ortelius Oval" },
2546 { "ortho" , " ", "Orthographic" , "Orthographic (ESRI: World from Space)" },
2547 { "pconic" , " ", "Perspective_Conic" , "*) Perspective Conic" },
2548 { "poly" , " ", "Polyconic" , "*) Polyconic (American)" },
2549 { "putp1" , " ", "Putnins_P1" , "*) Putnins P1" },
2550 { "putp2" , " ", "Putnins_P2" , "*) Putnins P2" },
2551 { "putp3" , " ", "Putnins_P3" , "*) Putnins P3" },
2552 { "putp3p" , " ", "Putnins_P3'" , "*) Putnins P3'" },
2553 { "putp4p" , " ", "Putnins_P4'" , "*) Putnins P4'" },
2554 { "putp5" , " ", "Putnins_P5" , "*) Putnins P5" },
2555 { "putp5p" , " ", "Putnins_P5'" , "*) Putnins P5'" },
2556 { "putp6" , " ", "Putnins_P6" , "*) Putnins P6" },
2557 { "putp6p" , " ", "Putnins_P6'" , "*) Putnins P6'" },
2558 { "qua_aut" , " ", "Quartic_Authalic" , "[ESRI] Quart c Authalic" },
2559 { "robin" , " ", "Robinson" , "Robinson" },
2560 { "rouss" , " ", "Roussilhe_Stereographic" , "*) Roussilhe Stereographic" },
2561 { "rpoly" , " ", "Rectangular_Polyconic" , "*) Rectangular Polyconic" },
2562 { "sinu" , " ", "Sinusoidal" , "Sinusoidal (Sanson-Flamsteed)" },
2563 { "somerc" , " ", "Hotine_Oblique_Mercator" , "Swiss Oblique Mercator" },
2564 { "somerc" , "<", "Swiss_Oblique_Cylindrical" , "Swiss Oblique Cylindrical" },
2565 { "somerc" , "<", "Hotine_Oblique_Mercator_Azimuth_Center" , "[ESRI] Swiss Oblique Mercator/Cylindrical" },
2566 { "stere" , "<", "Polar_Stereographic" , "Stereographic" },
2567 { "stere" , " ", "Stereographic" , "[ESRI] Stereographic" },
2568 { "sterea" , " ", "Oblique_Stereographic" , "Oblique Stereographic Alternative" },
2569 { "sterea" , "<", "Double_Stereographic" , "[ESRI]" },
2570 { "gstmerc" , " ", "Gauss_Schreiber_Transverse_Mercator" , "*) Gauss-Schreiber Transverse Mercator (aka Gauss-Laborde Reunion)" },
2571 { "tcc" , " ", "Transverse_Central_Cylindrical" , "*) Transverse Central Cylindrical" },
2572 { "tcea" , " ", "Transverse_Cylindrical_Equal_Area" , "*) Transverse Cylindrical Equal Area" },
2573 { "tissot" , " ", "Tissot_Conic" , "*) Tissot Conic" },
2574 { "tmerc" , " ", "Transverse_Mercator" , "*) Transverse Mercator" },
2575 { "tmerc" , "<", "Gauss_Kruger" , "[ESRI] DHDN" },
2576 { "tpeqd" , " ", "Two_Point_Equidistant" , "*) Two Point Equidistant" },
2577 { "tpers" , " ", "Tilted_perspective" , "*) Tilted perspective" },
2578 { "ups" , " ", "Universal_Polar_Stereographic" , "*) Universal Polar Stereographic" },
2579 { "urm5" , " ", "Urmaev_V" , "*) Urmaev V" },
2580 { "urmfps" , " ", "Urmaev_Flat_Polar_Sinusoidal" , "*) Urmaev Flat-Polar Sinusoidal" },
2581 { "utm" , ">", "Transverse_Mercator" , "*) Universal Transverse Mercator (UTM)" },
2582 { "vandg" , "<", "Van_Der_Grinten_I" , "[ESRI] van der Grinten (I)" },
2583 { "vandg" , " ", "VanDerGrinten" , "van der Grinten (I)" },
2584 { "vandg2" , " ", "VanDerGrinten_II" , "*) van der Grinten II" },
2585 { "vandg3" , " ", "VanDerGrinten_III" , "*) van der Grinten III" },
2586 { "vandg4" , " ", "VanDerGrinten_IV" , "*) van der Grinten IV" },
2587 { "vitk1" , " ", "Vitkovsky_I" , "*) Vitkovsky I" },
2588 { "wag1" , " ", "Wagner_I" , "*) Wagner I (Kavraisky VI)" },
2589 { "wag2" , " ", "Wagner_II" , "*) Wagner II" },
2590 { "wag3" , " ", "Wagner_III" , "*) Wagner III" },
2591 { "wag4" , " ", "Wagner_IV" , "*) Wagner IV" },
2592 { "wag5" , " ", "Wagner_V" , "*) Wagner V" },
2593 { "wag6" , " ", "Wagner_VI" , "*) Wagner VI" },
2594 { "wag7" , " ", "Wagner_VII" , "*) Wagner VII" },
2595 { "webmerc" , " ", "Mercator_1SP" , "Web Mercator" },
2596 { "webmerc" , "<", "Mercator_Auxiliary_Sphere" , "[ESRI] Web Mercator" },
2597 { "weren" , " ", "Werenskiold_I" , "*) Werenskiold I" },
2598 { "wink1" , " ", "Winkel_I" , "[ESRI] Winkel I" },
2599 { "wink2" , " ", "Winkel_II" , "[ESRI] Winkel II" },
2600 { "wintri" , " ", "Winkel_Tripel" , "[ESRI] Winkel Tripel" },
2601
2602// --- general projection parameters ---
2603 { "alpha" , " ", "azimuth" , "? Used with Oblique Mercator and possibly a few others" },
2604 { "k" , ">", "scale_factor" , "Scaling factor (old name)" },
2605 { "K" , ">", "scale_factor" , "? Scaling factor (old name)" },
2606 { "k_0" , " ", "scale_factor" , "Scaling factor (new name)" },
2607 { "lat_0" , " ", "latitude_of_origin" , "Latitude of origin" },
2608 { "lat_0" , "<", "latitude_of_center" , "Latitude of center" },
2609 { "lat_0" , "<", "central_parallel" , "[ESRI] Latitude of center" },
2610 { "lat_1" , " ", "standard_parallel_1" , "Latitude of first standard parallel" },
2611 { "lat_2" , " ", "standard_parallel_2" , "Latitude of second standard parallel" },
2612 { "lat_ts" , ">", "latitude_of_origin" , "Latitude of true scale" },
2613 { "lon_0" , " ", "central_meridian" , "Central meridian" },
2614 { "lon_0" , "<", "longitude_of_center" , "Longitude of center" },
2615 { "lonc" , ">", "longitude_of_center" , "? Longitude used with Oblique Mercator and possibly a few others" },
2616 { "x_0" , " ", "false_easting" , "False easting" },
2617 { "y_0" , " ", "false_northing" , "False northing" },
2618
2619// --- special projection parameters ---
2620// { "azi" , " ", "", "" },
2621// { "belgium" , " ", "", "" },
2622// { "beta" , " ", "", "" },
2623// { "czech" , " ", "", "" },
2624// { "gamma" , " ", "", "" },
2625// { "geoc" , " ", "", "" },
2626// { "guam" , " ", "", "" },
2627 { "h" , " ", "satellite_height", "Satellite height (geos - Geostationary Satellite View)" },
2628// { "lat_b" , " ", "", "" },
2629// { "lat_t" , " ", "", "" },
2630// { "lon_1" , " ", "", "" },
2631// { "lon_2" , " ", "", "" },
2632// { "lsat" , " ", "", "" },
2633// { "m" , " ", "", "" },
2634// { "M" , " ", "", "" },
2635// { "n" , " ", "", "" },
2636// { "no_cut" , " ", "", "" },
2637// { "no_off" , " ", "", "" },
2638// { "no_rot" , " ", "", "" },
2639// { "ns" , " ", "", "" },
2640// { "o_alpha" , " ", "", "" },
2641// { "o_lat_1" , " ", "", "" },
2642// { "o_lat_2" , " ", "", "" },
2643// { "o_lat_c" , " ", "", "" },
2644// { "o_lat_p" , " ", "", "" },
2645// { "o_lon_1" , " ", "", "" },
2646// { "o_lon_2" , " ", "", "" },
2647// { "o_lon_c" , " ", "", "" },
2648// { "o_lon_p" , " ", "", "" },
2649// { "o_proj" , " ", "", "" },
2650// { "over" , " ", "", "" },
2651// { "p" , " ", "", "" },
2652// { "path" , " ", "", "" },
2653// { "q" , " ", "", "" },
2654// { "R" , " ", "", "" },
2655// { "R_a" , " ", "", "" },
2656// { "R_A" , " ", "", "" },
2657// { "R_g" , " ", "", "" },
2658// { "R_h" , " ", "", "" },
2659// { "R_lat_a" , " ", "", "" },
2660// { "R_lat_g" , " ", "", "" },
2661// { "rot" , " ", "", "" },
2662// { "R_V" , " ", "", "" },
2663// { "s" , " ", "", "" },
2664// { "sym" , " ", "", "" },
2665// { "t" , " ", "", "" },
2666// { "theta" , " ", "", "" },
2667// { "tilt" , " ", "", "" },
2668// { "vopt" , " ", "", "" },
2669// { "W" , " ", "", "" },
2670// { "westo" , " ", "", "" },
2671
2672// --- core projection types and parameters that don't require explicit translation ---
2673// { "lonlat" , " ", "GEOGCS", "Lat/long (Geodetic)" },
2674// { "latlon" , ">", "GEOGCS", "Lat/long (Geodetic alias)" },
2675// { "latlong" , ">", "GEOGCS", "Lat/long (Geodetic alias)" },
2676// { "longlat" , ">", "GEOGCS", "Lat/long (Geodetic alias)" },
2677
2678// { "a" , " ", "", "Semimajor radius of the ellipsoid axis" },
2679// { "axis" , " ", "", "Axis orientation (new in 4.8.0)" },
2680// { "b , " ", "", "Semiminor radius of the ellipsoid axis" },
2681// { "datum , " ", "", "Datum name (see `proj -ld`)" },
2682// { "ellps , " ", "", "Ellipsoid name (see `proj -le`)" },
2683// { "nadgrids , " ", "", "Filename of NTv2 grid file to use for datum transforms (see below)" },
2684// { "no_defs , " ", "", "Don't use the /usr/share/proj/proj_def.dat defaults file" },
2685// { "pm , " ", "", "Alternate prime meridian (typically a city name, see below)" },
2686// { "proj , " ", "", "Projection name (see `proj -l`)" },
2687// { "to_meter , " ", "", "Multiplier to convert map units to 1.0m" },
2688// { "towgs84 , " ", "", "3 or 7 term datum transform parameters (see below)" },
2689// { "units , " ", "", "meters, US survey feet, etc." },
2690// { "south , " ", "", "Denotes southern hemisphere UTM zone" },
2691// { "zone , " ", "", "UTM zone" },
2692// { "lon_wrap" , " ", "", "Center longitude to use for wrapping (see below)" },
2693// { "over" , " ", "", "Allow longitude output outside -180 to 180 range, disables wrapping (see below)" },
2694 { "", "", "", "" } // end of records
2695};
2696
2697 //-----------------------------------------------------
2698 Dictionary.Destroy();
2699 Dictionary.Set_Name("Proj.4-WKT Dictionary");
2700
2701 if( Direction == 0 )
2702 {
2703 Dictionary.Add_Field("PROJ4", SG_DATATYPE_String);
2704 Dictionary.Add_Field("DIR" , SG_DATATYPE_String);
2705 Dictionary.Add_Field("WKT" , SG_DATATYPE_String);
2706 Dictionary.Add_Field("DESC" , SG_DATATYPE_String);
2707
2708 for(int i=0; *Translation[i][0]; i++)
2709 {
2710 CSG_Table_Record &Entry = *Dictionary.Add_Record();
2711
2712 Entry.Set_Value(0, Translation[i][0]);
2713 Entry.Set_Value(1, Translation[i][1]);
2714 Entry.Set_Value(2, Translation[i][2]);
2715 Entry.Set_Value(3, Translation[i][3]);
2716 }
2717 }
2718 else if( Direction > 0 ) // Proj4 to WKT
2719 {
2720 Dictionary.Add_Field("PROJ4", SG_DATATYPE_String);
2721 Dictionary.Add_Field("WKT" , SG_DATATYPE_String);
2722
2723 for(int i=0; *Translation[i][0]; i++)
2724 {
2725 if( Translation[i][1][0] != '<' ) // only WKT to Proj4
2726 {
2727 CSG_Table_Record &Entry = *Dictionary.Add_Record();
2728
2729 Entry.Set_Value(0, Translation[i][0]);
2730 Entry.Set_Value(1, Translation[i][2]);
2731 }
2732 }
2733 }
2734 else if( Direction < 0 ) // WKT to Proj4
2735 {
2736 Dictionary.Add_Field("WKT" , SG_DATATYPE_String);
2737 Dictionary.Add_Field("PROJ4", SG_DATATYPE_String);
2738
2739 for(int i=0; *Translation[i][0]; i++)
2740 {
2741 if( Translation[i][1][0] != '>' ) // only Proj4 to WKT
2742 {
2743 CSG_Table_Record &Entry = *Dictionary.Add_Record();
2744
2745 Entry.Set_Value(0, Translation[i][2]);
2746 Entry.Set_Value(1, Translation[i][0]);
2747 }
2748 }
2749 }
2750
2751 return( Dictionary.Get_Count() > 0 );
2752}
2753
2754//---------------------------------------------------------
2755bool CSG_Projections::_Set_Dictionary(void)
2756{
2757 CSG_Table Table;
2758
2759 return( _Set_Dictionary(Table, 1) && m_Proj4_to_WKT1.Create(&Table, 0, 1, true)
2760 && _Set_Dictionary(Table, -1) && m_WKT1_to_Proj4.Create(&Table, 0, 1, true)
2761 );
2762}
2763
2764
2766// //
2767// //
2768// //
2770
2771//---------------------------------------------------------
2772bool SG_Get_Projected (CSG_Shapes *pSource, CSG_Shapes *pTarget, const CSG_Projection &Target)
2773{
2774 if( pSource && pSource->is_Valid() && pSource->Get_Projection().is_Okay() && Target.is_Okay() )
2775 {
2776 if( pSource->Get_Projection() == Target )
2777 {
2778 return( pTarget ? pTarget->Create(*pSource) : true );
2779 }
2780
2781 if( pTarget )
2782 {
2783 pTarget->Create(*pSource); pSource = pTarget;
2784 }
2785
2786 CSG_Tool *pTool = SG_Get_Tool_Library_Manager().Create_Tool("pj_proj4", 2); // Coordinate Transformation (Shapes)
2787
2788 if( pTool )
2789 {
2790 CSG_Data_Manager Data; Data.Add(pSource); pTool->Set_Manager(&Data);
2791
2792 pTool->Set_Callback(false);
2793 pTool->Set_Parameter("CRS_WKT" , Target.Get_WKT2());
2794 pTool->Set_Parameter("CRS_PROJ", Target.Get_PROJ());
2795 pTool->Set_Parameter("SOURCE" , pSource);
2796 pTool->Set_Parameter("COPY" , false);
2797 pTool->Set_Parameter("PARALLEL", true);
2798
2800 bool bResult = pTool->Execute();
2802
2803 Data.Delete(pSource, true);
2805
2806 return( bResult );
2807 }
2808 }
2809
2810 return( false );
2811}
2812
2813//---------------------------------------------------------
2814bool SG_Get_Projected (const CSG_Projection &Source, const CSG_Projection &Target, TSG_Point &Point)
2815{
2816 if( Source == Target )
2817 {
2818 return( true );
2819 }
2820
2821 if( Source.is_Okay() && Target.is_Okay() )
2822 {
2823 CSG_Tool *pTool = SG_Get_Tool_Library_Manager().Create_Tool("pj_proj4", 29); // Single Coordinate Transformation
2824
2825 if( pTool )
2826 {
2827 pTool->Set_Manager(NULL);
2828 pTool->Set_Callback(false);
2829 pTool->Set_Parameter("TARGET_WKT2", Target.Get_WKT2());
2830 pTool->Set_Parameter("TARGET_PROJ", Target.Get_PROJ());
2831 pTool->Set_Parameter("SOURCE_WKT2", Source.Get_WKT2());
2832 pTool->Set_Parameter("SOURCE_PROJ", Source.Get_PROJ());
2833 pTool->Set_Parameter("SOURCE_X" , Point.x);
2834 pTool->Set_Parameter("SOURCE_Y" , Point.y);
2835
2837 bool bResult = pTool->Execute();
2839
2840 if( bResult )
2841 {
2842 Point.x = pTool->Get_Parameter("TARGET_X")->asDouble();
2843 Point.y = pTool->Get_Parameter("TARGET_Y")->asDouble();
2844 }
2845
2847
2848 return( bResult );
2849 }
2850 }
2851
2852 return( false );
2853}
2854
2855//---------------------------------------------------------
2856bool SG_Get_Projected (const CSG_Projection &Source, const CSG_Projection &Target, TSG_Rect &Rectangle)
2857{
2858 if( Source == Target )
2859 {
2860 return( true );
2861 }
2862
2863 if( Source.is_Okay() && Target.is_Okay() )
2864 {
2865 CSG_Shapes Points(SHAPE_TYPE_Point); Points.Get_Projection().Create(Source);
2866
2867 Points.Add_Shape()->Add_Point(Rectangle.xMin, Rectangle.yMin);
2868 Points.Add_Shape()->Add_Point(Rectangle.xMin, Rectangle.yMax);
2869 Points.Add_Shape()->Add_Point(Rectangle.xMax, Rectangle.yMax);
2870 Points.Add_Shape()->Add_Point(Rectangle.xMax, Rectangle.yMin);
2871
2872 if( SG_Get_Projected(&Points, NULL, Target) )
2873 {
2874 Rectangle = Points.Get_Extent();
2875
2876 return( true );
2877 }
2878 }
2879
2880 return( false );
2881}
2882
2883
2885// //
2886// //
2887// //
2889
2890//---------------------------------------------------------
2892{
2893 bool bResult = false;
2894
2895 if( pGrid && pGrid->is_Valid() && pGrid->Get_Projection().is_Okay() && (pLon || pLat) )
2896 {
2897 CSG_Grid Lon; if( !pLon ) { pLon = &Lon; } pLon->Create(pGrid->Get_System());
2898 CSG_Grid Lat; if( !pLat ) { pLat = &Lat; } pLat->Create(pGrid->Get_System());
2899
2900 SG_RUN_TOOL(bResult, "pj_proj4", 17, // geographic coordinate grids
2901 SG_TOOL_PARAMETER_SET("GRID", pGrid)
2902 && SG_TOOL_PARAMETER_SET("LON" , pLon )
2903 && SG_TOOL_PARAMETER_SET("LAT" , pLat )
2904 )
2905 }
2906
2907 return( bResult );
2908}
2909
2910
2912// //
2913// //
2914// //
2916
2917//---------------------------------------------------------
void SG_UI_Msg_Add_Error(const char *Message)
int SG_UI_Msg_Lock(bool bOn)
void SG_UI_ProgressAndMsg_Lock(bool bOn)
SAGA_API_DLL_EXPORT bool SG_File_Exists(const CSG_String &FileName)
signed long long sLong
Definition api_core.h:158
#define SG_T(s)
Definition api_core.h:537
SAGA_API_DLL_EXPORT CSG_String SG_File_Make_Path(const CSG_String &Directory, const CSG_String &Name)
SAGA_API_DLL_EXPORT bool SG_File_Delete(const CSG_String &FileName)
#define SG_STR_MBTOSG(s)
Definition api_core.h:545
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)
@ SG_DATATYPE_Int
Definition api_core.h:1050
@ SG_DATATYPE_String
Definition api_core.h:1055
#define SG_Char
Definition api_core.h:536
#define _TL(s)
Definition api_core.h:1619
SAGA_API_DLL_EXPORT CSG_String SG_Get_String(double Value, int Precision=-99)
@ SG_FILE_W
Definition api_core.h:1161
@ SG_FILE_R
Definition api_core.h:1160
CSG_Data_Object * Add(CSG_Data_Object *pObject)
bool Delete(CSG_Data_Object *pObject, bool bDetach=false)
void Set_Name(const CSG_String &Name)
CSG_Projection & Get_Projection(void)
static CSG_String Get_Share_Path(const CSG_String &AddPath="")
Definition api_core.cpp:491
sLong Length(void) const
Definition api_file.cpp:230
size_t Write(void *Buffer, size_t Size, size_t Count=1) const
Definition api_file.cpp:382
size_t Read(void *Buffer, size_t Size, size_t Count=1) const
Definition api_file.cpp:338
bool is_Writing(void) const
Definition api_core.h:1197
bool is_Reading(void) const
Definition api_core.h:1196
virtual bool is_Valid(void) const
Definition grid.cpp:441
bool Create(const CSG_Grid &Grid)
Definition grid.cpp:235
const CSG_Grid_System & Get_System(void) const
Definition grid.h:559
bool Cmp_Name(const CSG_String &String, bool bNoCase=true) const
Definition metadata.cpp:487
const CSG_String & Get_Name(void) const
Definition metadata.h:138
int Get_Children_Count(void) const
Definition metadata.h:154
CSG_MetaData * Get_Child(int Index) const
Definition metadata.h:155
bool Cmp_Property(const CSG_String &Name, const CSG_String &String, bool bNoCase=false) const
Definition metadata.cpp:697
const CSG_String & Get_Content(void) const
Definition metadata.h:139
const SG_Char * Get_Property(int Index) const
Definition metadata.h:188
void Set_Content(const CSG_String &Content)
Definition metadata.h:146
CSG_MetaData * Add_Child(void)
Definition metadata.cpp:169
void Destroy(void)
Definition metadata.cpp:143
bool Add_Property(const CSG_String &Name, const CSG_String &Value)
Definition metadata.cpp:585
double asDouble(void) const
Definition parameters.h:289
const SG_Char * asString(void) const
Definition parameters.h:290
virtual ~CSG_Projection(void)
CSG_String Get_Type_Identifier(void) const
bool is_Geographic(void) const
Definition geo_tools.h:901
static const CSG_Projection & Get_GCS_WGS84(void)
CSG_String Get_Unit_Name(void) const
CSG_String Get_JSON(void) const
bool Set_GCS_WGS84(void)
static CSG_Projection Get_UTM_WGS84(int Zone, bool bSouth=false)
double Get_Central_Meridian(void) const
bool is_Projection(void) const
Definition geo_tools.h:904
const CSG_String & Get_PROJ(void) const
Definition geo_tools.h:890
void Destroy(void)
ESG_CRS_Type Get_Type(void) const
Definition geo_tools.h:906
CSG_String Get_ESRI(void) const
double Get_Parallel_of_Origin(void) const
const CSG_String & Get_WKT2(void) const
Definition geo_tools.h:889
bool is_Equal(const CSG_Projection &Projection) const
bool Set_UTM_WGS84(int Zone, bool bSouth=false)
CSG_String Get_XML(void) const
bool Save(const CSG_String &File, ESG_CRS_Format Format=ESG_CRS_Format::WKT) const
CSG_String Get_Description(bool bDetails=false) const
CSG_String Get_Unit_Identifier(void) const
bool Create(const CSG_Projection &Projection)
bool is_Okay(void) const
Definition geo_tools.h:863
CSG_String Get_Type_Name(void) const
double Get_Unit_To_Meter(void) const
bool Load(const CSG_String &File)
CSG_String Get_WKT1(void) const
static ESG_Projection_Unit Get_Unit(const CSG_String &Identifier)
CSG_String Get_Names_List(ESG_CRS_Type Type=ESG_CRS_Type::Undefined, bool bAddSelect=true) const
bool Create(bool LoadCodeList=true)
bool Save(const CSG_String &File)
CSG_Projection Get_Projection(sLong Index) const
static bool Parse(const CSG_String &Definition, CSG_String *PROJ=NULL, CSG_String *WKT2=NULL, CSG_String *WKT1=NULL, CSG_String *JSON=NULL, CSG_String *ESRI=NULL)
virtual ~CSG_Projections(void)
void Destroy(void)
static CSG_String Get_CRS_Type_Identifier(ESG_CRS_Type Type)
static const CSG_String Get_Unit_Name(ESG_Projection_Unit Unit, bool bSimple=true)
static const CSG_String Get_Unit_Identifier(ESG_Projection_Unit Unit)
static CSG_String Convert_WKT2_to_XML(const CSG_String &WKT)
sLong Get_Count(void) const
static ESG_CRS_Type Get_CRS_Type(const CSG_String &Identifier)
bool Add(const CSG_Projection &Projection)
bool Load(const CSG_String &File, bool bAppend=false)
bool Get_Preference(CSG_Projection &Projection, int Code, const CSG_String &Authority) const
static CSG_String Get_CRS_Type_Name(ESG_CRS_Type Type)
static double Get_Unit_To_Meter(ESG_Projection_Unit Unit)
friend class CSG_Projection
Definition geo_tools.h:943
virtual int Add_Point(double x, double y, int iPart=0)=0
virtual bool is_Valid(void) const
Definition shapes.h:812
virtual CSG_Shape * Add_Shape(CSG_Table_Record *pCopy=NULL, TSG_ADD_Shape_Copy_Mode mCopy=SHAPE_COPY)
Definition shapes.cpp:402
virtual const CSG_Rect & Get_Extent(void)
Definition shapes.h:818
bool Create(const CSG_Shapes &Shapes)
Definition shapes.cpp:209
size_t Length(void) const
CSG_String AfterFirst(char Character) const
bool asInt(int &Value) const
int CmpNoCase(const CSG_String &String) const
int Cmp(const CSG_String &String) const
void Clear(void)
CSG_String BeforeFirst(char Character) const
size_t Replace(const CSG_String &Old, const CSG_String &New, bool bReplaceAll=true)
CSG_String BeforeLast(char Character) const
static CSG_String Format(const char *Format,...)
int Find(char Character, bool fromEnd=false) const
bool asDouble(double &Value) const
const SG_Char * c_str(void) const
CSG_String & Make_Lower(void)
int Trim_Both(void)
int Printf(const char *Format,...)
bool is_Empty(void) const
CSG_String Left(size_t count) const
bool Add(const CSG_Strings &Strings)
int Get_Count(void) const
Definition api_core.h:725
bool Set_Value(int Field, const CSG_String &Value)
int asInt(int Field) const
Definition table.h:219
bool is_Selected(void) const
Definition table.h:254
const SG_Char * asString(int Field, int Decimals=-99) const
bool Create(void)
Definition table.cpp:153
sLong Get_Count(void) const
Definition table.h:410
virtual bool Destroy(void)
Definition table.cpp:314
virtual bool Del_Records(void)
Definition table.cpp:936
virtual CSG_Table_Record * Add_Record(CSG_Table_Record *pCopy=NULL)
Definition table.cpp:823
bool Set_Index(CSG_Index &Index, int Field, bool bAscending=true) const
Definition table.cpp:1546
virtual CSG_Table_Record * Get_Record(sLong Index) const
Definition table.h:412
int Get_Field_Count(void) const
Definition table.h:371
virtual bool Add_Field(const CSG_String &Name, TSG_Data_Type Type, int Position=-1)
Definition table.cpp:479
CSG_Table_Record * Get_Record_byIndex(sLong Index) const
Definition table.h:417
bool Delete_Tool(CSG_Tool *pTool) const
CSG_Tool * Create_Tool(const CSG_String &Library, int Index, bool bWithGUI=false, bool bWithCMD=true) const
bool Set_Manager(class CSG_Data_Manager *pManager)
Definition tool.cpp:874
bool Set_Parameter(const CSG_String &ID, CSG_Parameter *pValue)
Definition tool.cpp:1659
CSG_Parameter * Get_Parameter(const CSG_String &ID) const
Definition tool.cpp:1642
void Set_Callback(bool bActive=true)
Definition tool.cpp:863
bool Execute(bool bAddHistory=false)
Definition tool.cpp:560
ESG_CRS_Type
Definition geo_tools.h:789
struct SSG_Point TSG_Point
SAGA_API_DLL_EXPORT CSG_Projections & SG_Get_Projections(void)
ESG_Projection_Unit
Definition geo_tools.h:795
ESG_CRS_Format
Definition geo_tools.h:783
struct SSG_Rect TSG_Rect
#define asDouble(i)
CSG_Projections gSG_Projections
bool SG_Get_Projected(CSG_Shapes *pSource, CSG_Shapes *pTarget, const CSG_Projection &Target)
#define CMP_PARAMETER(a, b)
#define CMP_PROPERTY(a, b, p)
bool SG_Grid_Get_Geographic_Coordinates(CSG_Grid *pGrid, CSG_Grid *pLon, CSG_Grid *pLat)
#define ADD_INFO(name, value)
#define ADD_HEAD(name, value)
#define ADD_PROP(name, entry, prop)
#define CMP_TOWGS84(id)
#define ADD_CONT(name, entry)
#define CMP_CONTENT(a, b)
ESG_PROJ_FIELD_ID
@ PRJ_FIELD_AUTH_NAME
@ PRJ_FIELD_AUTH_SRID
@ PRJ_FIELD_SRID
@ PRJ_FIELD_SRTEXT
@ PRJ_FIELD_PROJ4TEXT
CSG_Projections & SG_Get_Projections(void)
@ SHAPE_TYPE_Point
Definition shapes.h:102
double x
Definition geo_tools.h:129
double y
Definition geo_tools.h:129
double xMin
Definition geo_tools.h:468
double xMax
Definition geo_tools.h:468
double yMin
Definition geo_tools.h:468
double yMax
Definition geo_tools.h:468
@ TABLE_INDEX_Ascending
Definition table.h:105
CSG_Tool_Library_Manager & SG_Get_Tool_Library_Manager(void)
#define SG_TOOL_PARAMETER_SET(IDENTIFIER, VALUE)
#define SG_RUN_TOOL(bRetVal, LIBRARY, TOOL, CONDITION)