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