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