1 //*******************************************************************
2 //
3 // License:  See top level LICENSE.txt file.
4 //
5 // Author: Garrett Potts
6 //
7 // Description:
8 //
9 // This holds the class definition of DatumFactory.
10 //*******************************************************************
11 //  $Id: ossimDatumFactory.cpp 22851 2014-08-05 12:02:55Z gpotts $
12 
13 #include <ossim/base/ossimDatumFactory.h>
14 #include <ossim/base/ossimEllipsoidFactory.h>
15 #include <ossim/base/ossimDatum.h>
16 #include <ossim/base/ossimThreeParamDatum.h>
17 #include <ossim/base/ossimSevenParamDatum.h>
18 #include <ossim/base/ossimWgs84Datum.h>
19 #include <ossim/base/ossimWgs72Datum.h>
20 #include <ossim/base/ossimNadconNarDatum.h>
21 #include <ossim/base/ossimNadconNasDatum.h>
22 #include <ossim/base/ossimFilename.h>
23 #include <ossim/base/ossimKeywordlist.h>
24 #include <ossim/base/ossimKeywordNames.h>
25 #include <ossim/base/ossimPreferences.h>
26 #include "ossimDatumFactory.inc"
27 
28 #include <cstring> /* for strlen */
29 #include <utility> /* for std::make_pair */
30 
31 
32 static ossimString WGE = "WGE";
33 static ossimString WGD = "WGD";
34 
35 
36 
ossimDatumFactory()37 ossimDatumFactory::ossimDatumFactory()
38    :theWgs84Datum(0),
39     theWgs72Datum(0)
40 {
41    // datum depends on the creation of an ellipsoid factory
42    // so make sure an instance exists
43    ossimEllipsoidFactory::instance();
44    initializeDefaults();
45    theWgs84Datum = create(WGE);
46    theWgs72Datum = create(WGD);
47 
48 }
49 
~ossimDatumFactory()50 ossimDatumFactory::~ossimDatumFactory()
51 {
52    deleteAll();
53 }
54 
instance()55 ossimDatumFactory* ossimDatumFactory::instance()
56 {
57    static ossimDatumFactory inst;
58 
59    return &inst;
60 }
61 
create(const ossimString & code) const62 const ossimDatum* ossimDatumFactory::create(const ossimString &code)const
63 {
64    if ( code.size() )
65    {
66       std::map<std::string, const ossimDatum*>::const_iterator datum = theDatumTable.find(code);
67 
68       if(datum != theDatumTable.end())
69       {
70          return (*datum).second;
71       }
72 
73       if(code == "NAR") // User did not set "datum_grids" so map to NAR-C.
74       {
75          datum = theDatumTable.find("NAR-C");
76          if(datum != theDatumTable.end())
77          {
78             return (*datum).second;
79          }
80       }
81       else if(code == "NAS") // User did not set "datum_grids" so map to NAS-C."
82       {
83          datum = theDatumTable.find("NAS-C");
84          if(datum != theDatumTable.end())
85          {
86             return (*datum).second;
87          }
88       }
89    }
90 
91    return 0;
92 }
93 
create(const ossimKeywordlist & kwl,const char * prefix) const94 const ossimDatum* ossimDatumFactory::create(const ossimKeywordlist& kwl, const char *prefix) const
95 {
96    ossimString alpha_code = kwl.find(prefix, ossimKeywordNames::DATUM_KW);
97    if(!alpha_code.empty())
98       return create(alpha_code);
99    return 0;
100 }
101 
create(const ossimDatum * aDatum) const102 const ossimDatum* ossimDatumFactory::create(const ossimDatum* aDatum)const
103 {
104    if (aDatum)
105       return create (aDatum->code());
106    else
107       return 0;
108 }
109 
getList() const110 std::vector<ossimString> ossimDatumFactory::getList()const
111 {
112    std::map<std::string, const ossimDatum*>::const_iterator datum = theDatumTable.begin();
113    std::vector<ossimString> result;
114 
115    while(datum != theDatumTable.end())
116    {
117       result.push_back(ossimString((*datum).first) );
118       ++datum;
119    }
120    return result;
121 }
122 
getList(std::vector<ossimString> & list) const123 void ossimDatumFactory::getList(std::vector<ossimString>& list) const
124 {
125    std::map<std::string, const ossimDatum*>::const_iterator datum =
126       theDatumTable.begin();
127 
128    while(datum != theDatumTable.end())
129    {
130       list.push_back( ossimString((*datum).first) );
131       ++datum;
132    }
133 }
134 
deleteAll()135 void ossimDatumFactory::deleteAll()
136 {
137    std::map<std::string, const ossimDatum*>::iterator datum;
138 
139    datum = theDatumTable.begin();
140    while(datum != theDatumTable.end())
141    {
142       delete ((*datum).second);
143       ++datum;
144    }
145 
146    theDatumTable.clear();
147 
148 }
149 
initializeDefaults()150 void ossimDatumFactory::initializeDefaults()
151 {
152    //make the standards
153    theDatumTable.insert(std::make_pair(WGE.string(), new ossimWgs84Datum));
154    theDatumTable.insert(std::make_pair(WGD.string(), new ossimWgs72Datum));
155 
156    ossim_uint32 idx = 0;
157    while( std::strlen(threeParamDatum[idx].theCode) )
158    {
159       if( (threeParamDatum[idx].theCode != WGE) &&
160           (threeParamDatum[idx].theCode != WGD) )
161       {
162          theDatumTable.insert(std::make_pair(std::string(threeParamDatum[idx].theCode),
163             new ossimThreeParamDatum(threeParamDatum[idx].theCode,
164             threeParamDatum[idx].theName,
165             ossimEllipsoidFactory::instance()->create(ossimString(threeParamDatum[idx].theEllipsoidCode)),
166             threeParamDatum[idx].theSigmaX,
167             threeParamDatum[idx].theSigmaY,
168             threeParamDatum[idx].theSigmaZ,
169             threeParamDatum[idx].theWestLongitude,
170             threeParamDatum[idx].theEastLongitude,
171             threeParamDatum[idx].theSouthLatitude,
172             threeParamDatum[idx].theNorthLatitude,
173             threeParamDatum[idx].theParam1,
174             threeParamDatum[idx].theParam2,
175             threeParamDatum[idx].theParam3)));
176       }
177 
178       ++idx;
179    }
180    idx = 0;
181    while( std::strlen(sevenParamDatum[idx].theCode) )
182    {
183       theDatumTable.insert(std::make_pair(std::string(sevenParamDatum[idx].theCode),
184          new ossimSevenParamDatum(sevenParamDatum[idx].theCode,
185          sevenParamDatum[idx].theName,
186          ossimEllipsoidFactory::instance()->create(ossimString(sevenParamDatum[idx].theEllipsoidCode)),
187          sevenParamDatum[idx].theSigmaX,
188          sevenParamDatum[idx].theSigmaY,
189          sevenParamDatum[idx].theSigmaZ,
190          sevenParamDatum[idx].theWestLongitude,
191          sevenParamDatum[idx].theEastLongitude,
192          sevenParamDatum[idx].theSouthLatitude,
193          sevenParamDatum[idx].theNorthLatitude,
194          sevenParamDatum[idx].theParam1,
195          sevenParamDatum[idx].theParam2,
196          sevenParamDatum[idx].theParam3,
197          sevenParamDatum[idx].theParam4,
198          sevenParamDatum[idx].theParam5,
199          sevenParamDatum[idx].theParam6,
200          sevenParamDatum[idx].theParam7)));
201       ++idx;
202    }
203 
204    // Fetch the HARN grid filenames and add these datums to the table:
205    ossimFilename file = ossimPreferences::instance()->findPreference("datum_grids");
206 
207    if(file != "")
208    {
209       if(!file.isDir())
210       {
211          file = file.path();
212       }
213 
214       ossimFilename fileTest1 = file.dirCat("conus.las");
215       ossimFilename fileTest2 = file.dirCat("conus.los");
216 
217       if (fileTest1.exists() && fileTest2.exists())
218       {
219          theDatumTable.insert(std::make_pair(std::string("NAS"), new ossimNadconNasDatum(file)));
220          theDatumTable.insert(std::make_pair(std::string("NAR"), new ossimNadconNarDatum(file)));
221       }
222    }
223 }
224 
writeCStructure(const ossimFilename &)225 void ossimDatumFactory::writeCStructure(const ossimFilename& /*file*/)
226 {
227 #if 0
228    std::ofstream out(file.c_str());
229 
230    if(!out) return;
231 
232    out << "typedef struct ossimSevenParamDatumType" << std::endl
233       << "{" << std::endl
234       << "   ossimString theCode;\n"
235       << "   ossimString theName;\n"
236       << "   ossimString theEllipsoidCode;\n"
237       << "   ossim_float64 theSigmaX;\n"
238       << "   ossim_float64 theSigmaY;\n"
239       << "   ossim_float64 theSigmaZ;\n"
240       << "   ossim_float64 theWestLongitude;\n"
241       << "   ossim_float64 theEastLongitude;\n"
242       << "   ossim_float64 theSouthLatitude;\n"
243       << "   ossim_float64 theNorthLatitude;\n"
244       << "   ossim_float64 theParam1;\n"
245       << "   ossim_float64 theParam2;\n"
246       << "   ossim_float64 theParam3;\n"
247       << "   ossim_float64 theParam4;\n"
248       << "   ossim_float64 theParam5;\n"
249       << "   ossim_float64 theParam6;\n"
250       << "   ossim_float64 theParam7;\n"
251       << "};\n";
252 
253    out << "typedef struct ossimThreeParamDatumType" << std::endl
254       << "{" << std::endl
255       << "   ossimString theCode;\n"
256       << "   ossimString theName;\n"
257       << "   ossimString theEllipsoidCode;\n"
258       << "   ossim_float64 theSigmaX;\n"
259       << "   ossim_float64 theSigmaY;\n"
260       << "   ossim_float64 theSigmaZ;\n"
261       << "   ossim_float64 theWestLongitude;\n"
262       << "   ossim_float64 theEastLongitude;\n"
263       << "   ossim_float64 theSouthLatitude;\n"
264       << "   ossim_float64 theNorthLatitude;\n"
265       << "   ossim_float64 theParam1;\n"
266       << "   ossim_float64 theParam2;\n"
267       << "   ossim_float64 theParam3;\n"
268       << "};\n";
269    out << "#define NUMBER_OF_SEVEN_PARAM_DATUMS " << 2 << std::endl;
270    if(out)
271    {
272       std::map<std::string, const ossimDatum*>::iterator datum;
273       out << "static ossimThreeParamDatumType threeParamDatum[] = {\n";
274       datum = theDatumTable.begin();
275       ossim_uint32 datumCount = 0;
276       while(datum != theDatumTable.end())
277       {
278          bool written = false;
279          if( ((*datum).first != "NAS") &&
280             ((*datum).first != "NAR")&&
281             ((*datum).first != "EUR-7")&&
282             ((*datum).first != "OGB-7"))
283          {
284             written = true;
285             const ossimDatum* d = (*datum).second;
286 
287             out << "{\"" << d->code() << "\", "
288                << "\"" << d->name() << "\", "
289                << "\"" << d->ellipsoid()->code() << "\", "
290                << d->sigmaX() << ", "
291                << d->sigmaY() << ", "
292                << d->sigmaZ() << ", "
293                << d->westLongitude()*DEG_PER_RAD << ", "
294                << d->eastLongitude()*DEG_PER_RAD << ", "
295                << d->southLatitude()*DEG_PER_RAD << ", "
296                << d->northLatitude()*DEG_PER_RAD << ", "
297                << d->param1() << ", "
298                << d->param2() << ", "
299                << d->param3() << "}";
300             ++datumCount;
301          }
302          ++datum;
303          if(datum != theDatumTable.end()&&written)
304          {
305 
306             out << "," << std::endl;
307          }
308          else if(datum == theDatumTable.end())
309          {
310             out << std::endl;
311          }
312       }
313       out << "};" << std::endl;
314 
315       out << "#define NUMBER_OF_THREE_PARAM_DATUMS " << datumCount << std::endl;
316       out << "static ossimSevenParamDatumType sevenParamDatum[] = {\n";
317       const ossimDatum* d = create("EUR-7");
318       if(d)
319       {
320          out << "{\"" << d->code() << "\", "
321             << "\"" << d->name() << "\", "
322             << "\"" << d->ellipsoid()->code() << "\", "
323             << d->sigmaX() << ", "
324             << d->sigmaY() << ", "
325             << d->sigmaZ() << ", "
326             << d->westLongitude()*DEG_PER_RAD << ", "
327             << d->eastLongitude()*DEG_PER_RAD << ", "
328             << d->southLatitude()*DEG_PER_RAD << ", "
329             << d->northLatitude()*DEG_PER_RAD << ", "
330             << d->param1() << ", "
331             << d->param2() << ", "
332             << d->param3() << ", "
333             << d->param4() << ", "
334             << d->param5() << ", "
335             << d->param6() << ", "
336             << d->param7() << "},\n";
337       }
338       d = create("OGB-7");
339       if(d)
340       {
341          out << "{\"" << d->code() << "\", "
342             << "\"" << d->name() << "\", "
343             << "\"" << d->ellipsoid()->code() << "\", "
344             << d->sigmaX() << ", "
345             << d->sigmaY() << ", "
346             << d->sigmaZ() << ", "
347             << d->westLongitude()*DEG_PER_RAD << ", "
348             << d->eastLongitude()*DEG_PER_RAD << ", "
349             << d->southLatitude()*DEG_PER_RAD << ", "
350             << d->northLatitude()*DEG_PER_RAD << ", "
351             << d->param1() << ", "
352             << d->param2() << ", "
353             << d->param3() << ", "
354             << d->param4() << ", "
355             << d->param5() << ", "
356             << d->param6() << ", "
357             << d->param7() << "}\n";
358       }
359       out << "};" << std::endl;
360    }
361 #endif
362 }
363 
364