1 //*******************************************************************
2 //
3 // License: LGPL
4 //
5 // See LICENSE.txt file in the top level directory for more details.
6 //
7 // Author: Mingjie Su
8 //
9 //*******************************************************************
10 // $Id: ossim-src2src.cpp 2644 2011-05-26 15:20:11Z oscar.kramer $
11
12 #include <ossim/base/ossimArgumentParser.h>
13 #include <ossim/base/ossimApplicationUsage.h>
14 #include <ossim/base/ossimContainerProperty.h>
15 #include <ossim/base/ossimConstants.h>
16 #include <ossim/base/ossimFilename.h>
17 #include <ossim/base/ossimKeywordlist.h>
18 #include <ossim/base/ossimKeywordNames.h>
19 #include <ossim/base/ossimNotify.h>
20 #include <ossim/base/ossimObjectFactoryRegistry.h>
21 #include <ossim/base/ossimPreferences.h>
22 #include <ossim/base/ossimRefPtr.h>
23 #include <ossim/base/ossimString.h>
24 #include <ossim/imaging/ossimImageHandler.h>
25 #include <ossim/imaging/ossimImageHandlerRegistry.h>
26 #include <ossim/imaging/ossimImageWriterFactoryRegistry.h>
27 #include <ossim/imaging/ossimTilingPoly.h>
28 #include <ossim/init/ossimInit.h>
29 #include <ossim/plugin/ossimSharedPluginRegistry.h>
30 #include <ossim/projection/ossimMapProjection.h>
31 #include <ossim/projection/ossimMapProjectionInfo.h>
32 #include <ossim/projection/ossimProjection.h>
33 #include <ossim/projection/ossimProjectionFactoryRegistry.h>
34 #include <ossim/projection/ossimEquDistCylProjection.h>
35 #include <ossim/support_data/ossimInfoBase.h>
36 #include <ossim/support_data/ossimInfoFactoryRegistry.h>
37 #include <ossim/support_data/ossimSrcRecord.h>
38
39 #include <iostream>
40 #include <vector>
41 using namespace std;
42
43
44 //**************************************************************************
45 // usage()
46 //**************************************************************************
usage()47 void usage()
48 {
49 ossimNotify(ossimNotifyLevel_INFO)
50 << " examples:\n\n"
51 << " ossim-create-src --tiling-template ./mytemplate.template ./myfile.tif ./outdir\n"
52 << std::endl;;
53 }
54
55 //*****************************************************************************************
56 // Centralized point to capture all program exits (aids in debugging -- please leave)
57 //*****************************************************************************************
finalize(int exit_code)58 void finalize(int exit_code)
59 {
60 exit(exit_code);
61 }
62
parseSrcFile(const ossimFilename & srcFile,vector<ossimSrcRecord> & srcRecordFiles,ossimString & prefix)63 void parseSrcFile(const ossimFilename& srcFile, vector<ossimSrcRecord>& srcRecordFiles, ossimString& prefix)
64 {
65 if (!srcFile.isReadable())
66 return;
67
68 ossimKeywordlist src_kwl (srcFile);
69 unsigned int image_idx = 0;
70 ossimString lookup = src_kwl.find("dem0.file");
71 if (!lookup.empty())
72 {
73 prefix = "dem";
74 }
75
76 // Loop to read all image file entries:
77 while (true)
78 {
79 ossimSrcRecord srcRecord(src_kwl, image_idx++, prefix);
80 if (!srcRecord.valid())
81 break;
82
83 srcRecordFiles.push_back(srcRecord);
84 }
85 }
86
getTiling(const ossimFilename & templateFile)87 ossimRefPtr<ossimTilingPoly> getTiling(const ossimFilename& templateFile)
88 {
89 ossimKeywordlist templateKwl;
90 if (!templateKwl.addFile(templateFile))
91 {
92 return 0;
93 }
94
95 ossimString prefix ("igen.tiling.");
96 while (1)
97 {
98 if (templateKwl.find(prefix.chars(), "tile_source"))
99 {
100 break;
101 }
102 else
103 {
104 return 0;
105 }
106
107 // If we got here, then no matches were found in the template. Try again but without a prefix:
108 if (prefix.empty())
109 break;
110 prefix.clear();
111 }
112
113 // Initialize the tiling object if enabled:
114 ossimRefPtr<ossimTilingPoly> tiling = new ossimTilingPoly;
115
116 if (!tiling->loadState(templateKwl, prefix))
117 {
118 return 0;
119 }
120
121 return tiling;
122 }
123
getRect(ossimRefPtr<ossimMapProjection> mapProj,vector<ossimGpt> points)124 ossimDrect getRect(ossimRefPtr<ossimMapProjection> mapProj,
125 vector<ossimGpt> points)
126 {
127 std::vector<ossimDpt> rectTmp;
128 rectTmp.resize(points.size());
129
130 for(std::vector<ossimGpt>::size_type index=0; index < points.size(); ++index)
131 {
132 mapProj->worldToLineSample(points[(int)index], rectTmp[(int)index]);
133 }
134
135 if (rectTmp.size() > 3)
136 {
137 ossimDrect rect2 = ossimDrect(rectTmp[0],
138 rectTmp[1],
139 rectTmp[2],
140 rectTmp[3]);
141
142 return rect2;
143 }
144 return ossimDrect();
145 }
146
147 //**************************************************************************
148 // Main Application
149 //**************************************************************************
main(int argc,char * argv[])150 int main(int argc, char *argv[])
151 {
152 std::string tempString1;
153 ossimArgumentParser::ossimParameter stringParam1(tempString1);
154 std::string tempString2;
155 ossimArgumentParser::ossimParameter stringParam2(tempString2);
156
157 ossimArgumentParser argumentParser(&argc, argv);
158 ossimInit::instance()->addOptions(argumentParser);
159 ossimInit::instance()->initialize(argumentParser);
160
161 ossimApplicationUsage* appuse = argumentParser.getApplicationUsage();
162
163 appuse->setApplicationName(argumentParser.getApplicationName());
164
165 appuse->setDescription(argumentParser.getApplicationName()+
166 " generate src files for polygons.");
167
168 appuse->setCommandLineUsage(argumentParser.getApplicationName()+
169 "ossim-create-src [--tiling-template] <full path to template file>");
170
171 appuse->addCommandLineOption("--tiling-template", "Specify an external file that contains tiling information.");
172
173 ossimFilename templateFile = "";
174
175 if(argumentParser.read("--tiling-template", stringParam1))
176 {
177 templateFile = ossimFilename(tempString1);
178 }
179
180 // End of arg parsing.
181 argumentParser.reportRemainingOptionsAsUnrecognized();
182 if ( argumentParser.errors() )
183 {
184 argumentParser.writeErrorMessages(ossimNotify(ossimNotifyLevel_NOTICE));
185 finalize(1);
186 }
187
188 if (argc == 1)
189 {
190 ossimNotify(ossimNotifyLevel_WARN)<< "Must supply an input file or info option." << std::endl;
191 finalize(0);
192 }
193
194 ossim_uint32 idx = 0;
195 ossim_uint32 last_idx = argumentParser.argc()-1;
196 ossimFilename inputSrcFile = "";
197 ossimString prefixStr = "image";
198 vector<ossimSrcRecord> inputFiles;
199 while(argumentParser.argv()[idx] && (idx < last_idx))
200 {
201 ossimString file = argumentParser.argv()[idx];
202 if (file.contains(".src"))
203 {
204 // input file spec provided via src file. Need to parse it:
205 inputSrcFile = ossimFilename(file);
206 if (!inputSrcFile.exists() )
207 {
208 ossimNotify(ossimNotifyLevel_WARN) << "ossim-src2src: file does not exist: " << inputSrcFile
209 << std::endl;
210 finalize(1);
211 }
212 parseSrcFile(inputSrcFile, inputFiles, prefixStr);
213 }
214 ++idx;
215 }
216
217 // The last filename left on the command line should be the product filename:
218 ossimFilename outputFileDir = argumentParser.argv()[last_idx];
219 if (!outputFileDir.isDir())
220 {
221 outputFileDir = outputFileDir.path();
222 if (!outputFileDir.exists() )
223 {
224 ossimNotify(ossimNotifyLevel_WARN) << "ossim-src2src: output directory does not exist: " << outputFileDir
225 << std::endl;
226 finalize(1);
227 }
228 }
229
230 if (!templateFile.exists())
231 {
232 ossimNotify(ossimNotifyLevel_WARN) << "ossim-src2src: template file does not exist:: " << templateFile
233 << std::endl;
234 finalize(1);
235 }
236
237 ossimRefPtr<ossimTilingPoly> polyTiling = getTiling(templateFile);
238 if (!polyTiling.valid())
239 {
240 ossimNotify(ossimNotifyLevel_WARN) << "ossim-src2src: error generating tiling: " << templateFile
241 << std::endl;
242 finalize(1);
243 }
244
245 // Open up src file to get coordinate info from each file listed in src file.
246 ossim_float64 minLat = 90.0;
247 ossim_float64 maxLat = -90.0;
248 ossim_float64 minLon = 180.0;
249 ossim_float64 maxLon = -180.0;
250
251 ossimString tileName;
252 ossimIrect clipRect;
253 map<ossimString, ossimSrcRecord> infos;
254 ossimRefPtr<ossimMapProjection> mapProj = 0;
255
256 for (ossim_uint32 i = 0; i < inputFiles.size(); i++)
257 {
258 ossimFilename inputFile = inputFiles[i].getFilename();
259 vector<ossim_uint32> entryList;
260 ossimRefPtr<ossimImageHandler> ih = ossimImageHandlerRegistry::instance()->open(inputFile);
261 if (ih.valid() )
262 {
263 if(inputFiles[i].getEntryIndex() > -1 )
264 {
265 entryList.push_back(inputFiles[i].getEntryIndex());
266 }
267 else
268 {
269 ih->getEntryList(entryList);
270 }
271
272 for(ossim_uint32 entryIdx = 0; entryIdx < entryList.size(); ++entryIdx)
273 {
274 // Establish the image handler for this particular frame. This may be just
275 // the handler already opened in the case of single image per file:
276 ossimImageHandler* img_handler = 0;
277 if (entryList.size() == 1)
278 {
279 img_handler = ih.get();
280 }
281 else
282 {
283 img_handler = (ossimImageHandler*)ih->dup();
284 }
285
286 img_handler->setCurrentEntry(entryList[entryIdx]);
287
288 ossimDrect outputRect = img_handler->getBoundingRect();
289
290 ossimRefPtr<ossimImageGeometry> geom = img_handler->getImageGeometry();
291 if(geom.valid())
292 {
293 ossimGpt ulg;
294 ossimGpt llg;
295 ossimGpt lrg;
296 ossimGpt urg;
297
298 geom->localToWorld(outputRect.ul(), ulg);
299 geom->localToWorld(outputRect.ll(), llg);
300 geom->localToWorld(outputRect.lr(), lrg);
301 geom->localToWorld(outputRect.ur(), urg);
302
303 //find min and max lat, lon for whole src file
304 if (minLat > llg.lat)
305 {
306 minLat = llg.lat;
307 }
308
309 if (minLon > llg.lon)
310 {
311 minLon = llg.lon;
312 }
313
314 if (maxLat < urg.lat)
315 {
316 maxLat = urg.lat;
317 }
318
319 if (maxLon < urg.lon)
320 {
321 maxLon = urg.lon;
322 }
323
324 ossimString fileInfo = inputFile + "|" + ossimString::toString(entryIdx) + "|" +
325 ossimString::toString(ulg.lon) + "," + ossimString::toString(ulg.lat) + "," +
326 ossimString::toString(urg.lon) + "," + ossimString::toString(urg.lat) + "," +
327 ossimString::toString(lrg.lon) + "," + ossimString::toString(lrg.lat) + "," +
328 ossimString::toString(llg.lon) + "," + ossimString::toString(llg.lat);
329
330 infos[fileInfo] = inputFiles[i];
331
332 if (!mapProj.valid())
333 {
334 ossimRefPtr<ossimProjection> proj = geom->getProjection();
335 if (proj.valid())
336 {
337 mapProj = PTR_CAST(ossimMapProjection, proj->dup());
338 if (!mapProj.valid()) //default it to ossimEquDistCylProjection
339 {
340 mapProj = new ossimEquDistCylProjection;
341 mapProj->setMetersPerPixel(geom->getMetersPerPixel());
342 }
343 }
344 }
345 }
346 img_handler = 0;
347 }
348 ih = 0;
349 }
350 else
351 {
352 continue;
353 }
354 }
355 inputFiles.clear();
356
357 //get bounding rect for entire image
358 vector<ossimGpt> points;
359 if (points.size() == 0)
360 {
361 points.push_back(ossimGpt(maxLat, minLon));
362 points.push_back(ossimGpt(maxLat, maxLon));
363 points.push_back(ossimGpt(minLat, maxLon));
364 points.push_back(ossimGpt(minLat, minLon));
365 }
366
367 if(mapProj.valid())
368 {
369 ossimGpt tie(maxLat, minLon);
370 mapProj->setUlTiePoints(tie);
371 polyTiling->initialize(*(mapProj.get()), getRect(mapProj, points));
372 }
373
374 while(polyTiling->next(mapProj, clipRect, tileName))
375 {
376 ossimFilename outSrc = outputFileDir + "/" + ossimFilename(tileName).noExtension() + ".src";
377
378 map<ossimString, ossimSrcRecord>::iterator it = infos.begin();
379 ossim_int32 index = 0;
380 map<ossim_int32, ossimSrcRecord> srcList;
381 while (it != infos.end())
382 {
383 ossimString fileInfo = it->first;
384 vector<ossimString> fileInfos = fileInfo.split("|");
385 ossim_int32 entryId = fileInfos[1].toInt();
386 vector<ossimString> latlonInfo = fileInfos[2].split(",");
387
388 double ulgLon = latlonInfo[0].toDouble();
389 double ulgLat = latlonInfo[1].toDouble();
390 double urgLon = latlonInfo[2].toDouble();
391 double urgLat = latlonInfo[3].toDouble();
392 double lrgLon = latlonInfo[4].toDouble();
393 double lrgLat = latlonInfo[5].toDouble();
394 double llgLon = latlonInfo[6].toDouble();
395 double llgLat = latlonInfo[7].toDouble();
396
397 points.clear();
398 points.push_back(ossimGpt(ulgLat, ulgLon));
399 points.push_back(ossimGpt(urgLat, urgLon));
400 points.push_back(ossimGpt(lrgLat, lrgLon));
401 points.push_back(ossimGpt(llgLat, llgLon));
402
403 //get bounding for each image listed in src file
404 ossimDrect rect = getRect(mapProj, points);
405
406 //check if the rect of image intersect with the rect of tile
407 if (rect.intersects(clipRect))
408 {
409 ossimSrcRecord srcRecord = it->second;
410 srcRecord.setEntryIndex(entryId);
411 srcList[index] = srcRecord;
412 index++;
413 }
414 it++;
415 }
416
417 //write image files which intersect with the tile to a new src file
418 if (srcList.size() > 0)
419 {
420 ofstream outputSrcFile(outSrc.c_str());
421 map<ossim_int32, ossimSrcRecord>::iterator srcIt = srcList.begin();
422 while (srcIt != srcList.end())
423 {
424 ossimString prefix = prefixStr + ossimString::toString(srcIt->first) + ".";
425
426 ossimFilename newSrcFile = srcIt->second.getFilename();
427 ossim_int32 entryId = srcIt->second.getEntryIndex();
428 ossimFilename supportDir = srcIt->second.getSupportDir();
429 ossimString hisOp = srcIt->second.getHistogramOp();
430 vector<ossim_uint32> bands = srcIt->second.getBands();
431 double weight = srcIt->second.getWeight();
432 ossimFilename overviewPath = srcIt->second.getOverviewPath();
433 ossimFilename hisPath = srcIt->second.getHistogramPath();
434 ossimFilename maskPath = srcIt->second.getMaskPath();
435
436 if (!newSrcFile.empty())
437 {
438 ossimString str = prefix + "file: " + newSrcFile;
439 outputSrcFile << str << "\n";
440 }
441
442 if (entryId > -1)
443 {
444 ossimString str = prefix + "entry: " + ossimString::toString(entryId);
445 outputSrcFile << str << "\n";
446 }
447
448 if (!supportDir.empty())
449 {
450 ossimString str = prefix + "support: " + supportDir;
451 outputSrcFile << str << "\n";
452 }
453
454 if (!hisOp.empty())
455 {
456 ossimString str = prefix + "hist-op: " + hisOp;
457 outputSrcFile << str << "\n";
458 }
459
460 if (bands.size())
461 {
462 ossimString str = "";
463 for (ossim_uint32 bandIndex = 0; bandIndex < bands.size(); bandIndex++)
464 {
465 if (bandIndex == (bands.size()-1))
466 {
467 str = str + ossimString::toString(bands[bandIndex]+1);
468 }
469 else
470 {
471 str = str + ossimString::toString(bands[bandIndex]+1) + ",";
472 }
473 }
474 str = prefix + "rgb: " + str;
475 outputSrcFile << str << "\n";
476 }
477
478 if (weight > 0)
479 {
480 ossimString str = prefix + "opacity: " + ossimString::toString(weight);
481 outputSrcFile << str << "\n";
482 }
483
484 if (!overviewPath.empty())
485 {
486 ossimString str = prefix + "ovr: " + overviewPath;
487 outputSrcFile << str << "\n";
488 }
489
490 if (!hisPath.empty())
491 {
492 ossimString str = prefix + "hist: " + hisPath;
493 outputSrcFile << str << "\n";
494 }
495
496 if (!maskPath.empty())
497 {
498 ossimString str = prefix + "mask: " + maskPath;
499 outputSrcFile << str << "\n";
500 }
501 outputSrcFile << "\n";
502 srcIt++;
503 }
504 outputSrcFile.close();
505 srcList.clear();
506 }
507 }
508
509 if (polyTiling.valid())
510 {
511 polyTiling = 0;
512 }
513 if (mapProj.valid())
514 {
515 mapProj = 0;
516 }
517 points.clear();
518 infos.clear();
519
520 finalize(0);
521 return 0; // Never reached, but satisfies return type
522 }
523