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