OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimChipperUtil.cpp
Go to the documentation of this file.
1 //---
2 //
3 // File: ossimChipperUtil.cpp
4 //
5 // License: MIT
6 //
7 // Author: David Burken
8 //
9 // Description: Utility class definition processing digital elevation
10 // models(dems).
11 //
12 //---
13 // $Id: ossimChipperUtil.cpp 23675 2015-12-22 18:16:28Z dburken $
14 
16 
23 #include <ossim/base/ossimIrect.h>
26 #include <ossim/base/ossimNotify.h>
28 #include <ossim/base/ossimRefPtr.h>
33 #include <ossim/base/ossimTrace.h>
35 
60 #include <ossim/init/ossimInit.h>
61 
68 
70 
71 #include <cmath>
72 #include <sstream>
73 #include <string>
74 
75 static ossimTrace traceDebug("ossimChipperUtil:debug");
76 static ossimTrace traceLog("ossimChipperUtil:log");
77 static ossimTrace traceOptions("ossimChipperUtil:options");
78 
79 static const std::string BRIGHTNESS_KW = "brightness";
80 static const std::string COLOR_BLUE_KW = "color_blue";
81 static const std::string COLOR_GREEN_KW = "color_green";
82 static const std::string COLOR_RED_KW = "color_red";
83 static const std::string CONTRAST_KW = "contrast";
84 static const std::string CLIP_WMS_BBOX_LL_KW = "clip_wms_bbox_ll";
85 static const std::string CLIP_POLY_LAT_LON_KW = "clip_poly_lat_lon";
86 static const std::string CUT_BBOX_XYWH_KW = "cut_bbox_xywh";
87 static const std::string CUT_WMS_BBOX_KW = "cut_wms_bbox";
88 static const std::string CUT_WMS_BBOX_LL_KW = "cut_wms_bbox_ll";
89 static const std::string CUT_CENTER_LAT_KW = "cut_center_lat";
90 static const std::string CUT_CENTER_LON_KW = "cut_center_lon";
91 static const std::string CUT_RADIUS_KW = "cut_radius"; // meters
92 static const std::string CUT_HEIGHT_KW = "cut_height"; // pixels
93 static const std::string CUT_MAX_LAT_KW = "cut_max_lat";
94 static const std::string CUT_MAX_LON_KW = "cut_max_lon";
95 static const std::string CUT_MIN_LAT_KW = "cut_min_lat";
96 static const std::string CUT_MIN_LON_KW = "cut_min_lon";
97 static const std::string CUT_WIDTH_KW = "cut_width"; // pixels
98 static const std::string DEM_KW = "dem";
99 static const std::string GAIN_KW = "gain";
100 static const std::string FILE_KW = "file";
101 static const std::string FULLRES_XYS_KW = "fullres_xys";
102 static const std::string HIST_AOI_KW = "hist_aoi";
103 static const std::string HIST_CENTER_KW = "hist_center";
104 static const std::string HIST_LLWH_KW = "hist_llwh";
105 static const std::string HIST_OP_KW = "hist_op";
106 static const std::string IMAGE_SPACE_SCALE_X_KW = "image_space_scale_x";
107 static const std::string IMAGE_SPACE_SCALE_Y_KW = "image_space_scale_y";
108 static const std::string IMG_KW = "image";
109 static const std::string LUT_FILE_KW = "lut_file";
110 static const std::string DEGREES_X_KW = "degrees_x";
111 static const std::string DEGREES_Y_KW = "degrees_y";
112 static const std::string METERS_KW = "meters";
113 static const std::string NORTH_UP_KW = "north_up"; // bool
114 static const std::string OP_KW = "operation";
115 static const std::string OUTPUT_RADIOMETRY_KW = "output_radiometry";
116 static const std::string PAD_THUMBNAIL_KW = "pad_thumbnail"; // bool
117 static const std::string READER_PROPERTY_KW = "reader_property";
118 static const std::string RESAMPLER_FILTER_KW = "resampler_filter";
119 static const std::string ROTATION_KW = "rotation";
120 static const std::string RRDS_KW = "rrds";
121 static const std::string SCALE_2_8_BIT_KW = "scale_2_8_bit";
122 static const std::string SHARPEN_MODE_KW = "sharpen_mode";
123 static const std::string SNAP_TIE_TO_ORIGIN_KW = "snap_tie_to_origin";
124 static const std::string SRC_FILE_KW = "src_file";
125 static const std::string SRS_KW = "srs";
126 static const std::string THREE_BAND_OUT_KW = "three_band_out"; // bool
127 static const std::string THUMBNAIL_RESOLUTION_KW = "thumbnail_resolution"; // pixels
128 static const std::string TILE_SIZE_KW = "tile_size"; // pixels
129 static const std::string TRUE_KW = "true";
130 static const std::string UP_IS_UP_KW = "up_is_up"; // bool
131 static const std::string WRITER_KW = "writer";
132 static const std::string WRITER_PROPERTY_KW = "writer_property";
133 static const std::string COMBINER_TYPE_KW = "combiner_type";
134 static const std::string NULL_PIXEL_FLIP_KW = "null_pixel_flip";
135 
136 static const std::string TWOCMV_OLD_INPUT_BAND_KW = "2cmv_old_input_band";
137 static const std::string TWOCMV_NEW_INPUT_BAND_KW = "2cmv_new_input_band";
138 static const std::string TWOCMV_RED_OUTPUT_SOURCE_KW = "2cmv_red_output_source";
139 static const std::string TWOCMV_GREEN_OUTPUT_SOURCE_KW = "2cmv_green_output_source";
140 static const std::string TWOCMV_BLUE_OUTPUT_SOURCE_KW = "2cmv_blue_output_source";
141 
143  : ossimReferenced(),
144  m_operation(OSSIM_CHIPPER_OP_UNKNOWN),
145  m_kwl(new ossimKeywordlist()),
146  m_srcKwl(0),
147  m_geom(0),
148  m_ivt(0),
149  m_demLayer(0),
150  m_imgLayer(0)
151 {
152  // traceDebug.setTraceFlag(true);
153 
155 }
156 
157 // Private/hidden from use.
159 : m_operation(OSSIM_CHIPPER_OP_UNKNOWN)
160 {
161 }
162 
163 // Private/hidden from use.
165 {
166  return *this;
167 }
168 
170 {
172  ossimString combinerType = m_kwl->find(COMBINER_TYPE_KW.c_str());
173  if(combinerType.empty())
174  {
175  combinerType = "ossimImageMosaic";
176  }
177 
179  if(!result.valid())
180  {
181  result = new ossimImageMosaic();
182  }
183 
184  return result;
185 }
186 
188 {
189  clear();
190 }
191 
193 {
194  ossimString usageString = ap.getApplicationName();
195  usageString += " [option]... [input-option]... <input-file(s)> <output-file>\nNote at least one input is required either from one of the input options, e.g. --input-dem <my-dem.hgt> or adding to command line in front of the output file in which case the code will try to ascertain what type of input it is.\n\nAvailable traces:\n-T \"ossimChipperUtil:debug\" - General debug trace to standard out.\n-T \"ossimChipperUtil:log\" - Writes a log file to output-file.log.\n-T \"ossimChipperUtil:options\" - Writes the options to output-file-options.kwl.";
196 
198 
199  au->setCommandLineUsage(usageString);
200 
201  au->setDescription(ap.getApplicationName()+" Utility application for generating elevation products from dem data.");
202 
203  au->addCommandLineOption("--azimuth", "<azimuth>\nhillshade option - Light source azimuth angle for bump shade.\nRange: 0 to 360, Default = 180.0");
204 
205  au->addCommandLineOption( "-b or --bands <n,n...>", "Use the specified bands in given order: e.g. \"3,2,1\" will select bands 3, 2 and 1 of the input image.\nNote: it is 1 based" );
206 
207  au->addCommandLineOption( "--brightness", "<brightness>\nApply brightness to input image(s). Valid range: -1.0 to 1.0" );
208 
209  au->addCommandLineOption("--central-meridian","<central_meridian_in_decimal_degrees>\nNote if set this will be used for the central meridian of the projection. This can be used to lock the utm zone.");
210 
211  au->addCommandLineOption("--color","<r> <g> <b>\nhillshade option - Set the red, green and blue color values to be used with hillshade.\nThis option can be used with or without an image source for color.\nRange 0 to 255, Defualt r=255, g=255, b=255");
212 
213  au->addCommandLineOption("--color-table","<color-table.kwl>\nhillshade or color-relief option - Keyword list containing color table for color-relief option.");
214 
215  au->addCommandLineOption( "--contrast", "<constrast>\nApply constrast to input image(s). Valid range: -1.0 to 1.0" );
216 
217  au->addCommandLineOption("--cut-bbox-xywh", "<x>,<y>,<width>,<height>\nSpecify a comma separated bounding box.");
218 
219  au->addCommandLineOption("--cut-wms-bbox", "<minx>,<miny>,<maxx>,<maxy>\nSpecify a comma separated list in the format of a WMS BBOX.\nThe units are in the units of the projector defined by the --srs key");
220 
221  au->addCommandLineOption("--cut-wms-bbox-ll", "<minx>,<miny>,<maxx>,<maxy>\nSpecify a comma separated list in the format of a WMS BBOX.\nThe units are always decimal degrees");
222 
223  au->addCommandLineOption("--cut-width", "<width>\nSpecify the cut width in pixel");
224 
225  au->addCommandLineOption("--cut-height", "<height>\nSpecify the cut height in pixel");
226 
227  au->addCommandLineOption("--clip-wms-bbox-ll", "<minx>,<miny>,<maxx>,<maxy>\nSpecify a comma separated list in the format of a WMS BBOX.\nThe units are always decimal degrees");
228 
229  au->addCommandLineOption("--clip-poly-lat-lon", "Polygon in the form of a string: (lat,lon),(lat,lon),...(lat,lon)");
230 
231  au->addCommandLineOption("--cut-bbox-ll", "<min_lat> <min_lon> <max_lat> <max_lon>\nSpecify a bounding box with the minimum latitude/longitude and max latitude/longitude in decimal degrees.\nNote coordinates are edge to edge.");
232 
233  au->addCommandLineOption("--cut-bbox-llwh", "<min_lat> <min_lon> <max_lat> <max_lon> <width> <height>\nSpecify a bounding box with the minimum latitude/longitude, max latitude/longitude in decimal degrees and width/height in pixels.\nNote coordinates are edge to edge.");
234 
235  au->addCommandLineOption("--cut-center-llwh","<latitude> <longitude> <width> <height>\nSpecify the center cut in latitude longitude space with width and height in pixels.");
236 
237  au->addCommandLineOption("--cut-center-llr","<latitude> <longitude> <radius_in_meters>\nSpecify the center cut in latitude longitude space with radius in meters.");
238 
239  au->addCommandLineOption("--degrees","<dpp_xy> | <dpp_x> <dpp_y>\nSpecifies an override for degrees per pixel. Takes either a single value applied equally to x and y directions, or two values applied correspondingly to x then y. This option takes precedence over the \"--meters\" option.");
240 
241  au->addCommandLineOption("--enable-null-pixel-flip", "Will add to the start of the chain and will flip interior pixels that are null to valid.");
242  au->addCommandLineOption("--elevation", "<elevation>\nhillshade option - Light source elevation angle for bumb shade.\nRange: 0 to 90, Default = 45.0");
243 
244  au->addCommandLineOption("-e or --entry", "<entry> For multi image handlers which entry do you wish to extract. For list of entries use: \"ossim-info -i <your_image>\" ");
245 
246  au->addCommandLineOption("--exaggeration", "<factor>\nMultiplier for elevation values when computing surface normals. Has the effect of lengthening shadows for oblique lighting.\nRange: .0001 to 50000, Default = 1.0");
247 
248  au->addCommandLineOption("--fullres-xys", "<full res center x>,<full res center y>,<scale>[,<scale>]\nSpecify a full resolution x,y point (Used as pivot and center cut) and scale, comma seperated with no spaces. If two scales are specified then first is x and second is y else x and y are set to equal scales");
249 
250  au->addCommandLineOption("-h or --help", "Display this help and exit.");
251 
252  au->addCommandLineOption("--hemisphere", "<hemisphere>\nSpecify a projection hemisphere if supported. E.g. UTM projection. This will lock the hemisphere even if input scene center is the other hemisphere. Valid values for UTM are \"N\" and \"S\"");
253 
254  au->addCommandLineOption("--histogram-aoi", "<x>,<y>,<width>,<height>\nSets single image region of interest(roi) to compute histogram from. Coordinates are zero based image space. Single image operation only. Comma separated, no spaces.");
255 
256  au->addCommandLineOption("--histogram-center-tile", "Will compute histogram from center tile of image.");
257 
258  au->addCommandLineOption("--histogram-llwh", "<latitude>,<longitude>,<width>,<height>\nSpecify the region of interest(roi) to compute histogram from. Latitude and longitude will be roi center space with width and height in pixels. Comma separated, no spaces.");
259 
260  au->addCommandLineOption("--histogram-op", "<operation>\nHistogram operation to perform. Valid operations are \"auto-minmax\", \"auto-percentile\", \"std-stretch-1\", \"std-stretch-2\" and \"std-stretch-3\".");
261 
262  au->addCommandLineOption("--image-space-scale","<x> <y>\nSpecifies an image space scale for x and y direction. \"chip\" operation only.");
263 
264  au->addCommandLineOption("--input-dem", "<dem> Input dem to process.");
265 
266  au->addCommandLineOption("--input-img", "<image> Input image to process.");
267 
268  au->addCommandLineOption("--input-src","<file.src> Input source file list keyword list with list of dems or images or both to process.");
269 
270  au->addCommandLineOption("--meters", "<meters>\nSpecifies an override for the meters per pixel");
271 
272  au->addCommandLineOption("-n or --north-up", "Rotates image North up. \"chip\" operation only.");
273 
274  au->addCommandLineOption( "--op", "<operation>\nOperation to perform. Valid operations are \"chip\", \"color-relief\", \"hillshade\", \"psm\"(pan sharpened multispectral), \"2cmv\"(two color multi view) and \"ortho\".\nchip = input projection = output projection(image space), single image operation only." );
275 
276  au->addCommandLineOption("--options","<options.kwl> This can be all or part of the application options. To get a template you can turn on trace to the ossimChipperUtil class by adding \"-T ossimChipperUtil\" to your command.");
277 
278  au->addCommandLineOption("--origin-latitude","<latidude_in_decimal_degrees>\nNote if set this will be used for the origin latitude of the projection. Setting this to something other than 0.0 with a geographic projection creates a scaled geographic projection.");
279 
280  au->addCommandLineOption("--output-radiometry", "<R>\nSpecifies the desired product's pixel radiometry type. Possible values for <R> are: U8, U11, U16, S16, F32. Note this overrides the deprecated option \"scale-to-8-bit\".");
281 
282  au->addCommandLineOption("--pad-thumbnail", "<boolean>\nIf true, output thumbnail dimensions will be padded in width or height to make square; else, it will have the aspect ratio of input, Default=false");
283 
284  au->addCommandLineOption("--projection", "<output_projection> Valid projections: geo, geo-scaled, input or utm\ngeo = Equidistant Cylindrical, origin latitude = 0.0\ngeo-scaled = Equidistant Cylindrical, origin latitude = image center\ninput Use first images projection. Must be a map projecion.\nutm = Universal Tranverse Mercator\nIf input and multiple sources the projection of the first image will be used.\nIf utm the zone will be set from the scene center of first image.\nNOTE: --srs takes precedence over this option.");
285 
286  au->addCommandLineOption("--resample-filter","<type>\nSpecify what resampler filter to use, e.g. nearest neighbor, bilinear, cubic, sinc.\nSee ossim-info --resampler-filters");
287 
288  au->addCommandLineOption("-r or --rotate", "<degrees>\nRotate image by degrees. \"chip\" operation only.");
289 
290  au->addCommandLineOption("--reader-prop", "<string>Adds a property to send to the reader. format is name=value");
291 
292  au->addCommandLineOption("--rrds", "<rrds> Reduced resolution data set where 0 is full resolution. \"chip\" operation only.");
293 
294  au->addCommandLineOption("--scale-to-8-bit", "Scales the output to unsigned eight bits per band. This option has been deprecated by the newer \"--output-radiometry\" option.");
295 
296  au->addCommandLineOption("--sharpen-mode", "<mode> Applies sharpness to image chain(s). Valid modes: \"light\", \"heavy\"");
297 
298  au->addCommandLineOption("--snap-tie-to-origin",
299  "Snaps tie point to projection origin so that (tie-origin)/gsd come out on an even integer boundary.");
300 
301  au->addCommandLineOption("--srs","<src_code>\nSpecify a spatial reference system(srs) code for the output projection. Example: --srs EPSG:4326");
302 
303  au->addCommandLineOption("-t or --thumbnail", "<max_dimension>\nSpecify a thumbnail resolution.\nScale will be adjusted so the maximum dimension = argument given.");
304 
305  au->addCommandLineOption("--three-band-out", "Force three band output even if input is not. Attempts to map bands to RGB if possible.");
306 
307  au->addCommandLineOption("--tile-size", "<size_in_pixels>\nSets the output tile size if supported by writer. Notes: This sets both dimensions. Must be a multiple of 16, e.g. 1024.");
308 
309  au->addCommandLineOption("-u or --up-is-up", "Rotates image to up is up. \"chip\" operation only.");
310 
311  au->addCommandLineOption("-w or --writer","<writer>\nSpecifies the output writer. Default uses output file extension to determine writer. For valid output writer types use: \"ossim-info --writers\"\n");
312 
313  au->addCommandLineOption("--writer-prop", "<writer-property>\nPasses a name=value pair to the writer for setting it's property. Any number of these can appear on the line.");
314 
315  au->addCommandLineOption("--zone", "<zone>\nSpecify a projection zone if supported. E.g. UTM projection. This will lock the zone even if input scene center is in another zone. Valid values for UTM are \"1\" to \"60\"");
316 
317  au->addCommandLineOption("--2cmv-old-input-band", "<band>\nBand to use for two color multi view old input.\n");
318  au->addCommandLineOption("--2cmv-new-input-band", "<band>\nBand to use for two color multi view new input.\n");
319 
320  au->addCommandLineOption("--2cmv-red-output-source", "<source>\nTwo color multi view source input for red output. Either, old, new, or mp(min pix). Default=old.\n");
321 
322  au->addCommandLineOption("--2cmv-green-output-source", "<source>\nTwo color multi view source input for green output. Either, old, new, or mp(min pix). Default=new.\n");
323 
324  au->addCommandLineOption("--2cmv-blue-output-source", "<source>\nTwo color multi view source input for blue output. Either, old, new, or mp(min pix). Default=new.\n");
325  au->addCommandLineOption("--combiner-type", "<type>\nossimBlendMosaic, ossimFeatherMosaic, ossimImageMosaic. Default: ossimImageMosaic. Example --combiner-type ossimImageMosaic\n");
326 
327 } // End: ossimChipperUtil::addArguments
328 
330 {
331  // Must disonnect chains so that they destroy.
332  std::vector< ossimRefPtr<ossimSingleImageChain> >::iterator i = m_imgLayer.begin();
333  while ( i != m_imgLayer.end() )
334  {
335  (*i)->disconnect();
336  (*i) = 0;
337  ++i;
338  }
339  m_imgLayer.clear();
340 
341  i = m_demLayer.begin();
342  while ( i != m_demLayer.end() )
343  {
344  (*i)->disconnect();
345  (*i) = 0;
346  ++i;
347  }
348  m_demLayer.clear();
349 
350  if(m_writer.valid())
351  {
352  m_writer->disconnect();
353  m_writer = 0;
354  }
355 }
356 
358 {
359  static const char MODULE[] = "ossimChipperUtil::initialize(ossimArgumentParser&)";
360 
361  if ( traceDebug() )
362  {
363  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
364  }
365 
366  clear();
367  if( ap.read("-h") || ap.read("--help") || (ap.argc() == 1) )
368  {
369  usage(ap);
370 
371  return false; // Indicates process should be terminated to caller.
372  }
373 
374  // Start with clean options keyword list.
375  m_kwl->clear();
376 
377  std::string tempString1;
378  ossimArgumentParser::ossimParameter stringParam1(tempString1);
379  std::string tempString2;
380  ossimArgumentParser::ossimParameter stringParam2(tempString2);
381  std::string tempString3;
382  ossimArgumentParser::ossimParameter stringParam3(tempString3);
383  std::string tempString4;
384  ossimArgumentParser::ossimParameter stringParam4(tempString4);
385  std::string tempString5;
386  ossimArgumentParser::ossimParameter stringParam5(tempString5);
387  std::string tempString6;
388  ossimArgumentParser::ossimParameter stringParam6(tempString6);
389  double tempDouble1;
390  ossimArgumentParser::ossimParameter doubleParam1(tempDouble1);
391  double tempDouble2;
392  ossimArgumentParser::ossimParameter doubleParam2(tempDouble2);
393 
394  ossim_uint32 demIdx = 0;
395  ossim_uint32 imgIdx = 0;
396  ossim_uint32 readerPropIdx = 0;
397  ossim_uint32 writerPropIdx = 0;
398  ossimString key = "";
399 
400  // Extract optional arguments and stuff them in a keyword list.
401  if( ap.read("--azimuth", stringParam1) )
402  {
403  m_kwl->addPair( std::string(ossimKeywordNames::AZIMUTH_ANGLE_KW), tempString1 );
404  }
405 
406  if (ap.read("-b", stringParam1) || ap.read("--bands", stringParam1))
407  {
408  m_kwl->addPair( std::string(ossimKeywordNames::BANDS_KW), tempString1 );
409  }
410 
411  if( ap.read("--brightness", stringParam1) )
412  {
413  m_kwl->addPair( BRIGHTNESS_KW, tempString1 );
414  }
415 
416  if( ap.read("--central-meridian", stringParam1) )
417  {
418  m_kwl->addPair( std::string(ossimKeywordNames::CENTRAL_MERIDIAN_KW), tempString1 );
419  }
420 
421  if( ap.read("--color", stringParam1, stringParam2, stringParam3) )
422  {
423  m_kwl->addPair( COLOR_RED_KW, tempString1 );
424  m_kwl->addPair( COLOR_GREEN_KW, tempString2 );
425  m_kwl->addPair( COLOR_BLUE_KW, tempString3 );
426  }
427 
428  if( ap.read("--color-table", stringParam1) )
429  {
430  m_kwl->addPair( LUT_FILE_KW, tempString1 );
431  }
432 
433  if( ap.read("--contrast", stringParam1) )
434  {
435  m_kwl->addPair( CONTRAST_KW, tempString1 );
436  }
437 
438  if( ap.read("--cut-width", stringParam1) )
439  {
440  m_kwl->addPair( CUT_WIDTH_KW, tempString1 );
441  }
442  if( ap.read("--cut-height", stringParam1) )
443  {
444  m_kwl->addPair( CUT_HEIGHT_KW, tempString1 );
445  }
446  if( ap.read("--cut-bbox-xywh", stringParam1) )
447  {
448  m_kwl->addPair(CUT_BBOX_XYWH_KW, tempString1);
449  }
450  if( ap.read("--cut-wms-bbox", stringParam1) )
451  {
452  m_kwl->addPair(CUT_WMS_BBOX_KW, tempString1);
453  }
454  if( ap.read("--cut-wms-bbox-ll", stringParam1) )
455  {
456  m_kwl->addPair(CUT_WMS_BBOX_LL_KW, tempString1);
457  }
458 
459  if( ap.read("--clip-wms-bbox-ll", stringParam1) )
460  {
461  m_kwl->addPair(CLIP_WMS_BBOX_LL_KW, tempString1);
462  }
463 
464  if( ap.read("--clip-poly-lat-lon", stringParam1) )
465  {
466  //std::vector<ossimGpt> result;
467  //ossim::toVector(result, ossimString(tempString1));
468  //std::cout << result[0] << std::endl;
469  //std::cout <<tempString1<<std::endl;
470  //exit(0);
471  m_kwl->addPair(CLIP_POLY_LAT_LON_KW, tempString1);
472  }
473 
474  if( ap.read("--cut-bbox-ll", stringParam1, stringParam2, stringParam3, stringParam4) )
475  {
476  m_kwl->addPair( CUT_MIN_LAT_KW, tempString1 );
477  m_kwl->addPair( CUT_MIN_LON_KW, tempString2 );
478  m_kwl->addPair( CUT_MAX_LAT_KW, tempString3 );
479  m_kwl->addPair( CUT_MAX_LON_KW, tempString4 );
480  }
481 
482  if( ap.read("--cut-bbox-llwh", stringParam1, stringParam2, stringParam3,
483  stringParam4, stringParam5, stringParam6) )
484  {
485  m_kwl->addPair( CUT_MIN_LAT_KW, tempString1 );
486  m_kwl->addPair( CUT_MIN_LON_KW, tempString2 );
487  m_kwl->addPair( CUT_MAX_LAT_KW, tempString3 );
488  m_kwl->addPair( CUT_MAX_LON_KW, tempString4 );
489  m_kwl->addPair( CUT_WIDTH_KW, tempString5 );
490  m_kwl->addPair( CUT_HEIGHT_KW, tempString6 );
491  }
492 
493  if( ap.read("--cut-center-llwh", stringParam1, stringParam2, stringParam3, stringParam4) )
494  {
495  m_kwl->addPair( CUT_CENTER_LAT_KW, tempString1 );
496  m_kwl->addPair( CUT_CENTER_LON_KW, tempString2 );
497  m_kwl->addPair( CUT_WIDTH_KW, tempString3 );
498  m_kwl->addPair( CUT_HEIGHT_KW, tempString4 );
499  }
500 
501  if( ap.read("--cut-center-llr", stringParam1, stringParam2, stringParam3) )
502  {
503  m_kwl->addPair( CUT_CENTER_LAT_KW, tempString1 );
504  m_kwl->addPair( CUT_CENTER_LON_KW, tempString2 );
505  m_kwl->addPair( CUT_RADIUS_KW, tempString3 );
506  }
507 
508  int num_params = ap.numberOfParams("--degrees", doubleParam1);
509  if (num_params == 1)
510  {
511  ap.read("--degrees", doubleParam1);
512  m_kwl->add( DEGREES_X_KW.c_str(), tempDouble1 );
513  m_kwl->add( DEGREES_Y_KW.c_str(), tempDouble1 );
514  }
515  else if (num_params == 2)
516  {
517  ap.read("--degrees", doubleParam1, doubleParam2);
518  m_kwl->add( DEGREES_X_KW.c_str(), tempDouble1 );
519  m_kwl->add( DEGREES_Y_KW.c_str(), tempDouble2 );
520  }
521 
522  if ( ap.read("--elevation", stringParam1) )
523  {
524  m_kwl->addPair( std::string(ossimKeywordNames::ELEVATION_ANGLE_KW), tempString1 );
525  }
526 
527  if ( ap.read("-e", stringParam1) || ap.read("--entry", stringParam1) )
528  {
529  m_kwl->addPair( std::string(ossimKeywordNames::ENTRY_KW), tempString1 );
530  }
531 
532  if (ap.read("--exaggeration", stringParam1))
533  {
534  m_kwl->addPair(GAIN_KW, tempString1);
535  }
536 
537  if (ap.read("--fullres-xys", stringParam1))
538  {
539  m_kwl->addPair(FULLRES_XYS_KW, tempString1);
540 
541  std::vector<ossimString> values;
542  ossimString(tempString1).split(values, ",");
543  double sx,sy;
544  if(values.size() > 2)
545  {
546  sx = values[2].toDouble();
547  sy = sx;
548  if(values.size() > 3)
549  {
550  sy = values[3].toDouble();
551  }
552  m_kwl->add(IMAGE_SPACE_SCALE_X_KW.c_str(), sx);
553  m_kwl->add(IMAGE_SPACE_SCALE_Y_KW.c_str(), sy);
554  }
555  }
556 
557  if ( ap.read("--hemisphere", stringParam1) )
558  {
559  m_kwl->addPair( std::string(ossimKeywordNames::HEMISPHERE_KW), tempString1 );
560  }
561 
562  if ( ap.read("--histogram-aoi", stringParam1) )
563  {
564  m_kwl->addPair( HIST_AOI_KW, tempString1 );
565  }
566 
567  if(ap.read("--enable-null-pixel-flip"))
568  {
569  m_kwl->addPair(NULL_PIXEL_FLIP_KW, TRUE_KW);
570  }
571 
572  if ( ap.read( "--histogram-center-tile" ) )
573  {
574  m_kwl->addPair( HIST_CENTER_KW, TRUE_KW );
575  }
576 
577  if ( ap.read("--histogram-llwh", stringParam1) )
578  {
579  m_kwl->addPair( HIST_LLWH_KW, tempString1 );
580  }
581 
582  if ( ap.read("--histogram-op", stringParam1) )
583  {
584  m_kwl->addPair( HIST_OP_KW, tempString1 );
585  }
586 
587  if ( ap.read("--image-space-scale", doubleParam1, doubleParam2) )
588  {
589  m_kwl->add( IMAGE_SPACE_SCALE_X_KW.c_str(), tempDouble1 );
590  m_kwl->add( IMAGE_SPACE_SCALE_Y_KW.c_str(), tempDouble2 );
591  }
592 
593  while( ap.read("--input-dem", stringParam1) )
594  {
595  key = DEM_KW;
596  key += ossimString::toString(demIdx);
597  key += ".";
598  key += FILE_KW;
599  m_kwl->addPair( key.string(), tempString1 );
600  ++demIdx;
601  }
602 
603  while( ap.read("--input-img", stringParam1) )
604  {
605  key = IMG_KW;
606  key += ossimString::toString(imgIdx);
607  key += ".";
608  key += FILE_KW;
609  m_kwl->addPair(key.string(), tempString1 );
610  ++imgIdx;
611  }
612 
613  if( ap.read("--input-src", stringParam1) )
614  {
615  m_kwl->addPair( SRC_FILE_KW, tempString1 );
616  }
617 
618  if( ap.read("--meters", stringParam1) )
619  {
620  m_kwl->addPair( METERS_KW, tempString1 );
621  }
622 
623  if ( ap.read("-n") || ap.read("--north-up") )
624  {
625  m_kwl->addPair( NORTH_UP_KW, TRUE_KW);
626  }
627 
628  if( ap.read("--op", stringParam1) )
629  {
630  m_kwl->addPair( OP_KW, tempString1 );
631  }
632 
633  //---
634  // Deprecated: "--options-keyword-list"
635  //---
636  if( ap.read("--options", stringParam1) )
637  {
638  ossimFilename optionsKwl = tempString1;
639  if ( optionsKwl.exists() )
640  {
641  if ( m_kwl->addFile(optionsKwl) == false )
642  {
643  std::string errMsg = "ERROR could not open options keyword list file: ";
644  errMsg += optionsKwl.string();
645  throw ossimException(errMsg);
646  }
647  }
648  else
649  {
650  std::string errMsg = "ERROR options keyword list file does not exists: ";
651  errMsg += optionsKwl.string();
652  throw ossimException(errMsg);
653  }
654  }
655 
656  if( ap.read("--origin-latitude", stringParam1) )
657  {
658  m_kwl->addPair( std::string(ossimKeywordNames::ORIGIN_LATITUDE_KW), tempString1 );
659  }
660 
661  if(ap.read("--output-radiometry", stringParam1))
662  {
663  m_kwl->addPair( OUTPUT_RADIOMETRY_KW, tempString1 );
664  }
665 
666  if ( ap.read("--pad-thumbnail", stringParam1) )
667  {
668  m_kwl->addPair( PAD_THUMBNAIL_KW, tempString1 );
669  }
670 
671  if( ap.read("--projection", stringParam1) )
672  {
673  m_kwl->addPair( std::string(ossimKeywordNames::PROJECTION_KW), tempString1 );
674  }
675 
676  if( ap.read("--resample-filter", stringParam1) )
677  {
678  m_kwl->addPair( RESAMPLER_FILTER_KW, tempString1 );
679  }
680 
681  if ( ap.read("-r", stringParam1) || ap.read("--rotate", stringParam1) )
682  {
683  m_kwl->addPair( ROTATION_KW, tempString1 );
684  }
685 
686  while (ap.read("--reader-prop", stringParam1))
687  {
688  key = READER_PROPERTY_KW;
689  key += ossimString::toString(readerPropIdx);
690  m_kwl->addPair(key.string(), tempString1 );
691  ++readerPropIdx;
692  }
693 
694  if ( ap.read("--rrds", stringParam1) )
695  {
696  m_kwl->addPair( RRDS_KW, tempString1);
697  }
698 
699  if ( ap.read("--scale-to-8-bit") )
700  {
701  m_kwl->addPair( SCALE_2_8_BIT_KW, TRUE_KW);
702  }
703 
704  if ( ap.read("--sharpen-mode", stringParam1) )
705  {
706  m_kwl->addPair( SHARPEN_MODE_KW, tempString1 );
707  }
708 
709  if ( ap.read("--snap-tie-to-origin") )
710  {
711  m_kwl->addPair( SNAP_TIE_TO_ORIGIN_KW, TRUE_KW);
712  }
713 
714  if( ap.read("--srs", stringParam1) )
715  {
716  ossimString os = tempString1;
717  if ( os.contains("EPSG:") )
718  {
719  os.gsub( ossimString("EPSG:"), ossimString("") );
720  }
721  m_kwl->addPair( SRS_KW, os.string() );
722  }
723 
724  if( ap.read("-t", stringParam1) || ap.read("--thumbnail", stringParam1) )
725  {
726  m_kwl->addPair( THUMBNAIL_RESOLUTION_KW, tempString1 );
727  }
728 
729  if ( ap.read("--three-band-out") )
730  {
731  m_kwl->addPair( THREE_BAND_OUT_KW, TRUE_KW);
732  }
733 
734  if( ap.read("--tile-size", stringParam1) )
735  {
736  m_kwl->addPair( TILE_SIZE_KW, tempString1 );
737  }
738 
739  if ( ap.read("-u") || ap.read("--up-is-up") )
740  {
741  m_kwl->addPair( UP_IS_UP_KW, TRUE_KW);
742  }
743 
744  if( ap.read("-w", stringParam1) || ap.read("--writer", stringParam1) )
745  {
746  m_kwl->addPair( WRITER_KW, tempString1);
747  }
748 
749  while (ap.read("--writer-prop", stringParam1))
750  {
751  key = WRITER_PROPERTY_KW;
752  key += ossimString::toString(writerPropIdx);
753  m_kwl->addPair(key.string(), tempString1 );
754  ++writerPropIdx;
755  }
756 
757  if( ap.read("--zone", stringParam1) )
758  {
759  m_kwl->addPair( std::string(ossimKeywordNames::ZONE_KW), tempString1);
760  }
761 
762  if( ap.read("--2cmv-old-input-band", stringParam1) )
763  {
764  m_kwl->addPair( TWOCMV_OLD_INPUT_BAND_KW, tempString1 );
765  }
766 
767  if( ap.read("--2cmv-new-input-band", stringParam1) )
768  {
769  m_kwl->addPair( TWOCMV_NEW_INPUT_BAND_KW, tempString1 );
770  }
771  if( ap.read("--2cmv-red-output-source", stringParam1) )
772  {
773  m_kwl->addPair( TWOCMV_RED_OUTPUT_SOURCE_KW, tempString1 );
774  }
775 
776  if( ap.read("--2cmv-green-output-source", stringParam1) )
777  {
778  m_kwl->addPair( TWOCMV_GREEN_OUTPUT_SOURCE_KW, tempString1 );
779  }
780 
781  if( ap.read("--2cmv-blue-output-source", stringParam1) )
782  {
783  m_kwl->addPair( TWOCMV_BLUE_OUTPUT_SOURCE_KW, tempString1 );
784  }
785  if(ap.read("--combiner-type", stringParam1))
786  {
787  m_kwl->addPair(COMBINER_TYPE_KW, tempString1);
788  }
789  // End of arg parsing.
791  if ( ap.errors() )
792  {
794  std::string errMsg = "Unknown option...";
795  throw ossimException(errMsg);
796  }
797 
798  if ( ap.argc() >= 2 )
799  {
800  // Output file is last arg:
802  }
803  else
804  {
806  {
808  std::string errMsg = "Must supply an output file.";
809  throw ossimException(errMsg);
810  }
811  }
812 
813  if ( ap.argc() > 2 ) // User passed inputs in front of output file.
814  {
815  int pos = 1; // ap.argv[0] is application name.
816  while ( pos < (ap.argc()-1) )
817  {
818  ossimFilename file = ap[pos];
819  if ( traceDebug() )
820  {
822  << "argv[" << pos << "]: " << file << "\n";
823  }
824 
825  if ( isDemFile(file) )
826  {
827  key = DEM_KW;
828  key += ossimString::toString(demIdx);
829  key += ".";
830  key += FILE_KW;
831  m_kwl->addPair( key, file.string() );
832  ++demIdx;
833  }
834  else if ( isSrcFile(file) )
835  {
836  if ( m_kwl->find( SRC_FILE_KW.c_str() ) ) // --input-src used also
837  {
838  std::string errMsg = MODULE;
839  errMsg += "ERROR Multiple src files passed in. Please combine into one.";
840  throw ossimException(errMsg);
841  }
842 
843  m_kwl->addPair( SRC_FILE_KW, file.string() );
844  }
845  else // Add as an input image.
846  {
847  key = IMG_KW;
848  key += ossimString::toString(imgIdx);
849  key += ".";
850  key += FILE_KW;
851  m_kwl->addPair(key.string(), file.string() );
852  ++imgIdx;
853  }
854 
855  ++pos; // Go to next arg...
856 
857  } // End: while ( pos < (ap.argc()-1) )
858 
859  } // End: if ( ap.argc() > 2 )
860 
861  initialize();
862 
863  if ( traceDebug() )
864  {
865  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exited..." << std::endl;
866  }
867  return true;
868 
869 } // End: void ossimChipperUtil::initialize(ossimArgumentParser& ap)
870 
872 {
873  clear();
874 
875  // Start with clean options keyword list.
876  m_kwl->clear();
877 
878  m_kwl->addList( kwl, true );
879 
880  initialize();
881 }
882 
884 {
885  static const char MODULE[] = "ossimChipperUtil::initialize()";
886 
887  if ( traceDebug() )
888  {
889  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
890  }
891 
892  if ( traceOptions() )
893  {
894  ossimFilename optionsFile;
895  getOutputFilename(optionsFile);
896  optionsFile = optionsFile.noExtension();
897  optionsFile += "-options.kwl";
898  ossimString comment = " Can be use for --options argument.";
899  m_kwl->write( optionsFile.c_str(), comment.c_str() );
900  }
901 
902  // Determine the operation to do.
903  std::string op = m_kwl->findKey( OP_KW );
904  if ( op.size() )
905  {
906  ossimString s = op;
907  s.downcase();
908 
909  if ( s == "chip" )
910  {
912  }
913  else if ( s == "hillshade" )
914  {
916  }
917 
918  else if ( s == "color-relief" )
919  {
921  }
922  else if ( s == "ortho" )
923  {
925  }
926  else if ( s == "psm" )
927  {
929  }
930  else if ( s == "2cmv" )
931  {
933  }
934  else
935  {
936  std::string errMsg = "unknown operation: ";
937  errMsg += s.string();
938  throw ossimException(errMsg);
939  }
940  }
941  else
942  {
943  std::string errMsg = "keyword not found: ";
944  errMsg += OP_KW;
945  errMsg += "\nUse --op option to specify operation.\n";
946  throw ossimException(errMsg);
947  }
948 
949  //---
950  // Populate the m_srcKwl if --src option was set.
951  // Note do this before creating chains.
952  //---
954 
955  // Check for required inputs. Do this after initializeSrcKwl.
957  {
958  if ( getNumberOfInputs() != 1 )
959  {
960  std::ostringstream errMsg;
961  errMsg << op << " operation takes one input.";
962  throw ossimException( errMsg.str() );
963  }
964  }
965 
967  {
968  if ( getNumberOfInputs() != 2 )
969  {
970  std::ostringstream errMsg;
971  errMsg << op << " operation requires two inputs.";
972  throw ossimException( errMsg.str() );
973  }
974  }
975 
976  // Sanity check rotation options.
977  if ( upIsUp() || northUp() || hasRotation() )
978  {
979  std::string option;
980  ossim_uint32 rotationOptionCount = 0;
981  if ( upIsUp() )
982  {
983  option = UP_IS_UP_KW;
984  ++rotationOptionCount;
985  }
986  if ( northUp() )
987  {
988  option = NORTH_UP_KW;
989  ++rotationOptionCount;
990  }
991  if ( hasRotation() )
992  {
993  option = ROTATION_KW;
994  ++rotationOptionCount;
995  }
996 
997  // Can only do ONE rotation option.
998  if ( rotationOptionCount > 1 )
999  {
1000  std::ostringstream errMsg;
1001  if ( upIsUp() )
1002  {
1003  errMsg << UP_IS_UP_KW << " is on.\n";
1004  }
1005  if ( northUp() )
1006  {
1007  errMsg << NORTH_UP_KW << " is on.\n";
1008  }
1009  if ( hasRotation() )
1010  {
1011  errMsg << ROTATION_KW << " is on.\n";
1012  }
1013  errMsg << "Multiple rotation options do not make sense!";
1014  throw ossimException( errMsg.str() );
1015  }
1016 
1017  // One input, chip operation only.
1018  if ( getNumberOfInputs() != 1 )
1019  {
1020  std::ostringstream errMsg;
1021  errMsg << option << " option takes one input.";
1022  throw ossimException( errMsg.str() );
1023  }
1024 
1026  {
1027  std::ostringstream errMsg;
1028  errMsg << option << " option only valid with \"chip\" operation.";
1029  throw ossimException( errMsg.str() );
1030  }
1031  }
1032 
1033  // Create chains for any dem sources.
1034  addDemSources();
1035 
1036  // Create chains for any image sources.
1037  addImgSources();
1038 
1039  // Initialize projection and propagate to chains.
1041 
1042  if ( traceDebug() )
1043  {
1045  << "options keyword list:\n"
1046  << *(m_kwl.get()) << "\n";
1047 
1048  if ( m_srcKwl.valid() )
1049  {
1051  << "support record keyword list:\n"
1052  << *(m_srcKwl.get()) << "\n";
1053  }
1054 
1055  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exited...\n";
1056  }
1057 
1058 } // End: void ossimChipperUtil::initialize()
1059 
1061 {
1062  static const char MODULE[] = "ossimChipperUtil::initializeChain";
1063  if ( traceDebug() )
1064  {
1065  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
1066  }
1067 
1068  ossimString lookup; // used throughout...
1069 
1070  ossimRefPtr<ossimImageSource> source = 0;
1071 
1072  if ( hasBumpShadeArg() )
1073  {
1074  // Create chain:
1075  source = initializeBumpShadeChain();
1076  }
1078  {
1079  source = initializeColorReliefChain();
1080  }
1081  else if ( ( m_operation == OSSIM_CHIPPER_OP_CHIP ) ||
1083  {
1084  source = combineLayers();
1085  }
1086  else if ( m_operation == OSSIM_CHIPPER_OP_2CMV )
1087  {
1088  source = initialize2CmvChain(); // Two Color Multiview.
1089  }
1090  else if ( m_operation == OSSIM_CHIPPER_OP_PSM )
1091  {
1092  source = initializePsmChain(); // Pan sharpened multispectral.
1093  }
1094 
1095  if ( source.valid() )
1096  {
1097  //---
1098  // This is conditional. Output radiometry may of may not be set. This can also be set at
1099  // the ossimSingleImageChain level.
1100  //---
1102  ( source->getOutputScalarType() != getOutputScalarType() ) )
1103  {
1104  source = addScalarRemapper( source, getOutputScalarType() );
1105  }
1106 
1107  //---
1108  // Get the area of interest. This will be the scene bounding rect if not
1109  // explicitly set by user with one of the --cut options.
1110  // Need to get this before the thumbnail code.
1111  //---
1112  getAreaOfInterest(source.get(), aoi);
1113 
1114  //---
1115  // Set the image size here. Note must be set after combineLayers. This is needed for
1116  // the ossimImageGeometry::worldToLocal call for a geographic projection to handle wrapping
1117  // accross the date line.
1118  //---
1119  if(m_geom.valid())
1120  {
1121  m_geom->setImageSize( aoi.size() );
1122  }
1123 
1124  if ( hasThumbnailResolution() )
1125  {
1126  //---
1127  // Adjust the projection scale and get the new rect.
1128  // Note this will resize the ossimImageGeometry::m_imageSize is scale changes.
1129  //---
1130  initializeThumbnailProjection( aoi, aoi );
1131 
1132  // Reset the source bounding rect if it changed.
1133  source->initialize();
1134  }
1135 
1136  if ( source.valid() && !aoi.hasNans() )
1137  {
1138  //---
1139  // Add a cut filter. This will:
1140  // 1) Null out/clip any data pulled in.
1141  // 2) Speed up by not propagating get tile request outside the cut or "aoi"
1142  // to the left hand side(input).
1143  //---
1145 
1146  // Set the cut rectangle:
1147  cutter->setRectangle( aoi );
1148 
1149  // Null outside.
1151 
1152  // Connect cutter input to source chain.
1153  cutter->connectMyInputTo( 0, source.get() );
1154 
1155  source = cutter.get();
1156 
1157  // Dependent on correct aoi so place after the cutter.
1158  if ( hasAnnotations() )
1159  {
1160  // Put annotations after scalar remapper.
1161  ossimRefPtr<ossimImageSource> result = addAnnotations( source );
1162  if ( result.valid() )
1163  {
1164  source = result.get();
1165  }
1166  }
1167  }
1168  }
1169 
1170  if ( traceDebug() )
1171  {
1172  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exited...\n";
1173  }
1174 
1175  return source;
1176 }
1177 
1179  ossimIrect& aoi, const ossimKeywordlist& /* kwl */ )
1180 {
1181  getAreaOfInterest(m_source.get(), aoi);
1182 }
1183 
1185 {
1186  static const char MODULE[] = "ossimChipperUtil::initializeBumpShadeChain";
1187  if ( traceDebug() )
1188  {
1189  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
1190  }
1191 
1192  ossimString lookup;
1193  ossimRefPtr<ossimImageSource> source = 0;
1194 
1195  // Combine the dems.
1197 
1198  // Set up the normal source.
1200 
1201  //---
1202  // Set the track scale flag to true. This enables scaling the surface
1203  // normals by the GSD in order to maintain terrain proportions.
1204  //---
1205  normSource->setTrackScaleFlag(true);
1206 
1207  // Connect to dems.
1208  normSource->connectMyInputTo( demSource.get() );
1209 
1210  // Set the smoothness factor.
1211  ossim_float64 gain = 1.0;
1212  lookup = m_kwl->findKey( GAIN_KW );
1213  if ( lookup.size() )
1214  {
1215  gain = lookup.toFloat64();
1216  }
1217  normSource->setSmoothnessFactor(gain);
1218 
1219  ossimRefPtr<ossimImageSource> colorSource = 0;
1220  if ( hasLutFile() )
1221  {
1222  if ( m_imgLayer.size() )
1223  {
1225  << MODULE << " WARNING:"
1226  << "\nBoth a color table and image(s) have been provided for a color source.\n"
1227  << "Choosing color table of image(s).\n";
1228  }
1229 
1230  colorSource = addIndexToRgbLutFilter( demSource );
1231  }
1232  else
1233  {
1234  // Combine the images and set as color source for bump shade.
1235  colorSource = combineLayers( m_imgLayer );
1236  }
1237 
1238  // Create the bump shade.
1240 
1241  // Set the azimuth angle.
1242  ossim_float64 azimuthAngle = 180;
1244  if ( lookup.size() )
1245  {
1246  ossim_float64 f = lookup.toFloat64();
1247  if ( (f >= 0) && (f <= 360) )
1248  {
1249  azimuthAngle = f;
1250  }
1251  }
1252  bumpShade->setAzimuthAngle(azimuthAngle);
1253 
1254  // Set the elevation angle.
1255  ossim_float64 elevationAngle = 45.0;
1257  if ( lookup.size() )
1258  {
1259  ossim_float64 f = lookup.toFloat64();
1260  if ( (f >= 0.0) && (f <= 90) )
1261  {
1262  elevationAngle = f;
1263  }
1264  }
1265  bumpShade->setElevationAngle(elevationAngle);
1266 
1267  if ( !hasLutFile() )
1268  {
1269  // Set the color.
1270  ossim_uint8 r = 0xff;
1271  ossim_uint8 g = 0xff;
1272  ossim_uint8 b = 0xff;
1273  lookup = m_kwl->findKey( COLOR_RED_KW );
1274  if ( lookup.size() )
1275  {
1276  r = lookup.toUInt8();
1277  }
1278  lookup = m_kwl->findKey( COLOR_GREEN_KW );
1279  if ( lookup.size() )
1280  {
1281  g = lookup.toUInt8();
1282  }
1283  lookup = m_kwl->findKey( COLOR_BLUE_KW );
1284  if ( lookup.size() )
1285  {
1286  b = lookup.toUInt8();
1287  }
1288  bumpShade->setRgbColorSource(r, g, b);
1289  }
1290 
1291  // Connect the two sources.
1292  bumpShade->connectMyInputTo(0, normSource.get());
1293  bumpShade->connectMyInputTo(1, colorSource.get());
1294 
1295  if ( traceDebug() )
1296  {
1297  ossim_uint8 r = 0xff;
1298  ossim_uint8 g = 0xff;
1299  ossim_uint8 b = 0xff;
1300  bumpShade->getRgbColorSource(r, g, b);
1302  << "\nazimuthAngle: " << azimuthAngle
1303  << "\nelevation angle: " << elevationAngle
1304  << "\ngain factor: " << gain
1305  << "\nr: " << int(r)
1306  << "\ng: " << int(g)
1307  << "\nb: " << int(b)
1308  << "\n";
1309  }
1310 
1311  // Capture the pointer to give to the writer.
1312  source = bumpShade.get();
1313 
1314  return source;
1315 
1316 } // End: ossimChipperUtil::initializeBumpShadeChain()
1317 
1319 {
1321  if ( hasLutFile() )
1322  {
1323  result = addIndexToRgbLutFilter( result );
1324  }
1325  else
1326  {
1327  // No LUT file provided, so doing the default 8-bit linear stretch:
1328  if ( result->getOutputScalarType() != OSSIM_UINT8 )
1329  {
1330  result = addScalarRemapper( result, OSSIM_UINT8 );
1331  }
1332  }
1333  return result;
1334 }
1335 
1337 {
1338  ossimRefPtr<ossimImageSource> result = 0;
1339 
1340  ossim_uint32 layerCount = (ossim_uint32) (m_demLayer.size() + m_imgLayer.size());
1341 
1342  // Must have two and only two inputs.
1343  if ( layerCount == 2 )
1344  {
1345  ossimRefPtr<ossimSingleImageChain> input1 = 0; // First input should be color.
1346  ossimRefPtr<ossimSingleImageChain> input2 = 0; // Second input should be pan.
1347 
1348  // Most likely case, two image layers.
1349  if ( m_imgLayer.size() )
1350  {
1351  input1 = m_imgLayer[0].get();
1352 
1353  if ( m_imgLayer.size() == 2 )
1354  {
1355  input2 = m_imgLayer[1].get();
1356  }
1357  }
1358 
1359  if ( m_demLayer.size() )
1360  {
1361  if ( !input1.valid() )
1362  {
1363  input1 = m_demLayer[0].get();
1364  }
1365 
1366  if ( !input2.valid() )
1367  {
1368  if ( m_demLayer.size() == 1 )
1369  {
1370  input2 = m_demLayer[0].get();
1371  }
1372  else if ( m_demLayer.size() == 2 )
1373  {
1374  input2 = m_demLayer[1].get();
1375  }
1376  }
1377  }
1378 
1379  if ( input1.valid() && input2.valid() )
1380  {
1381  // Make the color input the first connection to the combiner.
1382  if ( input1->getNumberOfOutputBands() == 1 )
1383  {
1384  // Swap:
1385  ossimRefPtr<ossimSingleImageChain> tmpChain = input1;
1386  input1 = input2;
1387  input2 = tmpChain;
1388  }
1389 
1390  //---
1391  // Check the pan source for one band:
1392  // This really shouldn't happen, i.e. caller should typically pass a
1393  // one band pan image that is higher resolution than the color source.
1394  //---
1395  if ( input2->getNumberOfOutputBands() > 1 )
1396  {
1397  // Note this will add a band selector if there isn't one in chain.
1398  std::vector<ossim_uint32> bandList(1);
1399  bandList[0] = 0;
1400  input2->setBandSelection( bandList );
1401  }
1402 
1403  // TODO: Make dynamic by type.
1405  psm->connectMyInputTo(0, input1.get());
1406  psm->connectMyInputTo(1, input2.get());
1407  psm->initialize();
1408  result = dynamic_cast<ossimImageSource*>(psm.get());
1409  }
1410 
1411  } // Matches: if ( layerCount == 2 )
1412 
1413  return result;
1414 
1415 } // End: ossimChipperUtil::initializePsmChain()
1416 
1418 {
1419  if ( isChipMode() )
1420  {
1422  }
1423  else
1424  {
1425  // Create the output projection.
1427 
1428  // Setup the view in all the chains.
1430  }
1431 }
1432 
1434 {
1435  static const char MODULE[] = "ossimChipperUtil::execute";
1436 
1437  if ( traceDebug() )
1438  {
1439  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
1440  }
1441 
1442  ossimIrect aoi;
1444 
1445  if ( source.valid() && !aoi.hasNans() )
1446  {
1447  // Set up the writer.
1449 
1450  // Connect the writer to the cutter.
1451  m_writer->connectMyInputTo(0, source.get());
1452 
1453  //---
1454  // Set the area of interest.
1455  // NOTE: This must be called after the writer->connectMyInputTo as
1456  // ossimImageFileWriter::initialize incorrectly resets theAreaOfInterest
1457  // back to the bounding rect.
1458  //---
1460 
1462  {
1463  // Add a listener to get percent complete.
1464  ossimStdOutProgress prog(0, true);
1465  m_writer->addListener(&prog);
1466 
1467  if ( traceLog() )
1468  {
1469  ossimKeywordlist logKwl;
1470  m_writer->saveStateOfAllInputs(logKwl);
1471 
1472  ossimFilename logFile;
1473  getOutputFilename(logFile);
1474  logFile.setExtension("log");
1475 
1476  logKwl.write( logFile.c_str() );
1477  }
1478 
1479  // Write the file:
1480  m_writer->execute();
1481 
1482  m_writer->removeListener(&prog);
1483 
1484  if(m_writer->isAborted())
1485  {
1486  throw ossimException( "Writer Process aborted!" );
1487  }
1488  }
1489  else
1490  {
1491  throw ossimException( "Unable to initialize writer for execution" );
1492  }
1493  }
1494 
1495  if ( traceDebug() )
1496  {
1497  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exited...\n";
1498  }
1499 }
1501 {
1502  if(m_writer.valid())
1503  {
1504  m_writer->abort();
1505  }
1506 }
1507 
1509 {
1510  ossimRefPtr<ossimImageData> result = 0;
1511 
1512  ossimIrect aoi;
1513 
1514  if( optionsKwl.getSize() > 0 )
1515  {
1516  m_kwl->addList(optionsKwl, true);
1517  }
1518 
1519  // (GP)
1520  // Until we add more ellaborate code to check for scale changes
1521  // as well as moving windows we will just always initialize
1522  // the output projection
1523  //
1524 
1526  if(!m_source.valid())
1527  {
1528  m_source = initializeChain( aoi );
1529  }
1530 
1531  if ( optionsKwl.getSize() > 0 )
1532  {
1533  //---
1534  // Only do this if new options were passed in. This was causing an off by
1535  // one error when now options were passed in using thumbnail option.
1536  // The m_source->getBoundingRect(...) was returning 257 instead of 256.
1537  // Need to hunt that down but for right now this fixes problem.
1538  // (drb 20151222)
1539  //---
1540  getAreaOfInterest(m_source.get(), aoi);
1541 
1542  m_geom->setImageSize( aoi.size() );
1543  }
1544 
1545  if ( m_source.valid() )
1546  {
1547  result = m_source->getTile( aoi, 0 );
1548  }
1549 
1550  return result;
1551 }
1552 
1554 {
1555  static const char MODULE[] = "ossimChipperUtil::addDemSources";
1556 
1557  if ( traceDebug() )
1558  {
1559  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
1560  }
1561 
1562  std::vector<ossimString> sortedList;
1563  m_kwl->getSortedList(sortedList, DEM_KW);
1564  for(auto record:sortedList)
1565  {
1566  ossimString key = record + ".";
1567  ossimString file = key + FILE_KW;
1569  ossimFilename f = m_kwl->findKey( file.string() );
1570  if ( f.size() )
1571  {
1572  // Look for the entry key, e.g. dem0.entry: 10
1573  ossim_uint32 entryIndex = 0;
1574  std::string value = m_kwl->findKey( entry.string() );
1575  if ( value.size() )
1576  {
1577  entryIndex = ossimString(value).toUInt32();
1578  }
1579  else
1580  {
1581  // Get global entry. Set by "-e" on command line apps.
1582  entryIndex = getEntryNumber();
1583  }
1584  ossimSrcRecord srcRecord;
1585  srcRecord.setFilename(f);
1586  srcRecord.setEntryIndex(entryIndex);
1587  // addDemSource( f, entryIndex );
1588  addDemSource( srcRecord );
1589  }
1590  }
1591  sortedList.clear();
1592  if ( m_srcKwl.valid() )
1593  {
1594  // Add stuff from src keyword list.
1595  m_srcKwl->getSortedList(sortedList, DEM_KW);
1596  for(auto record:sortedList)
1597  {
1598  ossimString prefix = record+".";
1599  ossimSrcRecord src;
1600  if ( src.loadState( *(m_srcKwl.get()), prefix ) )
1601  {
1602  addDemSource(src);
1603  }
1604  }
1605  }
1606 
1607  if ( traceDebug() )
1608  {
1609  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exited...\n";
1610  }
1611 }
1612 
1614 {
1615  static const char MODULE[] = "ossimChipperUtil::addDemSource(const ossimFilename&)";
1616 
1617  if ( traceDebug() )
1618  {
1619  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
1620  }
1621 
1622  ossimRefPtr<ossimSingleImageChain> ic = createChain(file, entryIndex, true);
1623  if ( ic.valid() )
1624  {
1625  m_demLayer.push_back(ic);
1626  }
1627 
1628  if ( traceDebug() )
1629  {
1630  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exiting...\n";
1631  }
1632 }
1633 
1635 {
1636  static const char MODULE[] = "ossimChipperUtil::addDemSource(const ossimSrcRecord&)";
1637 
1638  if ( traceDebug() )
1639  {
1640  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
1641  }
1642 
1644  if ( ic.valid() )
1645  {
1646  m_demLayer.push_back(ic);
1647  }
1648 
1649  if ( traceDebug() )
1650  {
1651  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exiting...\n";
1652  }
1653 }
1654 
1656 {
1657  static const char MODULE[] = "ossimChipperUtil::addImgSources";
1658 
1659  if ( traceDebug() )
1660  {
1661  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
1662  }
1663  std::vector<ossimString> sortedList;
1664  m_kwl->getSortedList(sortedList, IMG_KW);
1665  for(auto record:sortedList)
1666  {
1667  ossimString fileKey = record + "." + FILE_KW;
1668  ossimFilename f = m_kwl->findKey( fileKey.string() );
1669  if ( !f.empty())
1670  {
1671  ossimString imagePrefix = record+".";
1672  std::shared_ptr<ossimSrcRecord> srcRecord = std::make_shared<ossimSrcRecord>();
1673  if(srcRecord->loadState(*m_kwl, imagePrefix.c_str()))
1674  {
1675  addImgSource(*srcRecord);
1676  }
1677  }
1678  }
1679  sortedList.clear();
1680  if ( m_srcKwl.valid() )
1681  {
1682  m_srcKwl->getSortedList(sortedList, IMG_KW);
1683  for(auto record:sortedList)
1684  {
1685  ossimString prefix = record+".";
1686  std::shared_ptr<ossimSrcRecord> src = std::make_shared<ossimSrcRecord>();
1687  if ( src->loadState( *(m_srcKwl.get()), prefix ) )
1688  {
1689  addImgSource(*src);
1690  }
1691  }
1692  }
1693 
1694  if ( traceDebug() )
1695  {
1696  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exited...\n";
1697  }
1698 }
1699 
1701 {
1702  static const char MODULE[] = "ossimChipperUtil::addImgSource";
1703 
1704  if ( traceDebug() )
1705  {
1707  << MODULE << " entered...\nFile: " << file << "\n";
1708  }
1709 
1710  ossimRefPtr<ossimSingleImageChain> ic = createChain(file, entryIndex, false);
1711  if ( ic.valid() )
1712  {
1713  m_imgLayer.push_back(ic);
1714  }
1715 
1716  if ( traceDebug() )
1717  {
1718  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exiting...\n";
1719  }
1720 }
1721 
1723 {
1724  static const char MODULE[] = "ossimChipperUtil::addImgSource(const ossimSrcRecord&)";
1725 
1726  if ( traceDebug() )
1727  {
1728  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
1729  }
1730 
1732  if ( ic.valid() )
1733  {
1734  m_imgLayer.push_back(ic);
1735  }
1736 
1737  if ( traceDebug() )
1738  {
1739  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exiting...\n";
1740  }
1741 }
1742 
1744  ossim_uint32 entryIndex,
1745  bool isDemSource) const
1746 {
1747  static const char MODULE[] = "ossimChipperUtil::createChain(const ossimFilename&";
1748 
1749  if ( traceDebug() )
1750  {
1752  << MODULE << " entered..."
1753  << "\nfile: " << file
1754  << "\nentry: " << entryIndex
1755  << "\nisDemSource: " << (isDemSource?"true":"false")
1756  << "\n";
1757  }
1758 
1760 
1761  if ( !file.empty()&&file.exists() )
1762  {
1763  ic = new ossimSingleImageChain;
1764  if ( ic->open( file ) )
1765  {
1766  // Set any reader props:
1767  setReaderProps( ic->getImageHandler().get() );
1768 
1769  // we can't guarantee the state of the image handler at this point so
1770  // let's make sure that the entry is always set to the requested location
1771  // On Cib/Cadrg we were having problems. Removed the compare for entry 0
1772  //
1773 
1774  if ( setChainEntry( ic, entryIndex ) == false )
1775  {
1776  std::ostringstream errMsg;
1777  errMsg << MODULE << " ERROR:\nEntry " << entryIndex << " out of range!"
1778  << std::endl;
1779  throw ossimException( errMsg.str() );
1780  }
1781 
1782  //---
1783  // If PSM (pan sharpening) operation and this input is one band, don't
1784  // mess with its bands.
1785  //---
1786  bool psmPanInput = false;
1787  if ( ( m_operation == OSSIM_CHIPPER_OP_PSM ) && ( ic->getNumberOfOutputBands() == 1 ) )
1788  {
1789  psmPanInput = true;
1790  }
1791 
1792  // Bands selection. Note: Not performed on PSM pan band.
1793  if ( !psmPanInput )
1794  {
1795  if ( isThreeBandOut() )
1796  {
1797  //---
1798  // This will guarantee three bands out. Will put band
1799  // selector at the end of the chain if input is one band. If input image
1800  // handler has implemented a getRgbBandlist(...) it will also set the
1801  // rgb band order.
1802  //---
1803  ic->setThreeBandFlag( true );
1804  }
1805 
1806  if ( hasBandSelection() )
1807  {
1808  // User entered band list.
1809  std::vector<ossim_uint32> bandList(0);
1810  getBandList( bandList );
1811  if ( bandList.size() )
1812  {
1813  ic->setBandSelection( bandList );
1814  }
1815  else
1816  {
1817  ic->setDefaultBandSelection();
1818  }
1819  }
1820  }
1821 
1822  ossimString nullPixelFlip = m_kwl->find(NULL_PIXEL_FLIP_KW.c_str());
1823  if(nullPixelFlip.toBool())
1824  {
1825  ic->setAddNullPixelFlipFlag(true);
1826  }
1827  //---
1828  // If multiple inputs and scaleToEightBit do it at the end of the processing
1829  // chain to alleviate un-even stretches between inputs.
1830  //---
1831  const ossim_uint32 INPUT_COUNT = getNumberOfInputs();
1832  bool scaleFlag = ( scaleToEightBit() && (INPUT_COUNT == 1) );
1833  ic->setRemapToEightBitFlag( scaleFlag );
1834 
1835  // Always have resampler cache.
1836  ic->setAddResamplerCacheFlag(true);
1837 
1838  //---
1839  // Don't need a chain cache as we're doing a sequential write. So the same tile
1840  // should never be visited more than once.
1841  //---
1842  ic->setAddChainCacheFlag(false);
1843 
1844  //---
1845  // Histogram:
1846  // Don't apply histogram stretch to dem sources for hill shade
1847  // operation.
1848  //---
1849  if ( ( isDemSource == false ) ||
1850  ( isDemSource && (m_operation != OSSIM_CHIPPER_OP_HILL_SHADE) ) )
1851  {
1853  }
1854 
1855  // Brightness, contrast. Note in same filter.
1857  {
1858  ic->setBrightnessContrastFlag(true);
1859  }
1860 
1861  std::string sharpnessMode = getSharpenMode();
1862  if ( sharpnessMode.size() )
1863  {
1864  ic->setSharpenFlag(true);
1865  }
1866 
1867  // Create the chain.
1868  ic->createRenderedChain();
1869 
1870  // Set the filter type if needed.
1871  ossimString lookup = m_kwl->findKey( RESAMPLER_FILTER_KW );
1872  if ( lookup.size() )
1873  {
1874  // Assumption image renderer is in chain:
1875  ic->getImageRenderer()->getResampler()->setFilterType( lookup );
1876  }
1877 
1878  // Histogram setup.
1879  if ( hasHistogramOperation() )
1880  {
1881  setupChainHistogram( ic );
1882  }
1883 
1884  // Brightness constrast setup:
1886  {
1887  // Assumption bright contrast filter in chain:
1888 
1889  ossim_float64 value = getBrightness();
1890  ic->getBrightnessContrast()->setBrightness( value );
1891 
1892  value = getContrast();
1893  ic->getBrightnessContrast()->setContrast( value );
1894  }
1895 
1896  // Sharpness:
1897  if ( sharpnessMode.size() )
1898  {
1899  if ( sharpnessMode == "light" )
1900  {
1901  ic->getSharpenFilter()->setWidthAndSigma( 3, 0.5 );
1902  }
1903  else if ( sharpnessMode == "heavy" )
1904  {
1905  ic->getSharpenFilter()->setWidthAndSigma( 5, 1.0 );
1906  }
1907  }
1908 
1910  {
1911  ossimGeoPolygon polygon;
1912  getClipPolygon(polygon);
1913  if(polygon.size()>0)
1914  {
1915  ic->addGeoPolyCutterPolygon(polygon);
1916  }
1917  }
1918  }
1919  else
1920  {
1921  ic = 0;
1922  }
1923  }
1924 
1925  if ( !ic.valid())
1926  {
1927  std::string errMsg = "Could not open: ";
1928  errMsg += file.string();
1929  throw ossimException(errMsg);
1930  }
1931 
1932  if ( traceDebug() )
1933  {
1934  ossimKeywordlist kwl;
1935  ic->saveState(kwl, 0);
1936 
1938  << "chain:\n" << kwl << "\n"
1939  << MODULE << " exiting...\n";
1940  }
1941 
1942  return ic;
1943 }
1944 
1946  bool isDemSource) const
1947 {
1948  static const char MODULE[] = "ossimChipperUtil::createChain(const ossimSrcRecord&)";
1949  if ( traceDebug() )
1950  {
1951  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
1952  }
1953 
1955  if ( ic->open(rec) )
1956  {
1957  // Set any reader props:
1958  setReaderProps( ic->getImageHandler().get() );
1959 
1960  // Entry is set in ossimSingleImageChain::open(src)
1961 
1962  //---
1963  // If PSM (pan sharpening) operation and this input is one band, don't
1964  // mess with its bands.
1965  //---
1966  bool psmPanInput = false;
1967  if ( ( m_operation == OSSIM_CHIPPER_OP_PSM ) && ( ic->getNumberOfOutputBands() == 1 ) )
1968  {
1969  psmPanInput = true;
1970  }
1971 
1972  // Bands selection. Note: Not performed on PSM pan band.
1973  if ( !psmPanInput )
1974  {
1975  if ( isThreeBandOut() )
1976  {
1977  //---
1978  // This will guarantee three bands out. Will put band
1979  // selector at the end of the chain if input is one band. If input image
1980  // handler has implemented a getRgbBandlist(...) it will also set the
1981  // rgb band order.
1982  //---
1983  ic->setThreeBandFlag( true );
1984  }
1985 
1986  if ( hasBandSelection() )
1987  {
1988  // User entered band list.
1989  std::vector<ossim_uint32> bandList(0);
1990  getBandList( bandList );
1991  if ( bandList.size() )
1992  {
1993  ic->setBandSelection( bandList );
1994  }
1995  else
1996  {
1997  ic->setDefaultBandSelection();
1998  }
1999  }
2000  }
2001  ossimString nullPixelFlip = m_kwl->find(NULL_PIXEL_FLIP_KW.c_str());
2002  if (nullPixelFlip.toBool())
2003  {
2004  ic->setAddNullPixelFlipFlag(true);
2005  }
2006 
2007  //---
2008  // If multiple inputs and scaleToEightBit do it at the end of the processing
2009  // chain to alleviate un-even stretches between inputs.
2010  //---
2011  const ossim_uint32 INPUT_COUNT = getNumberOfInputs();
2012  bool scaleFlag = ( scaleToEightBit() && (INPUT_COUNT == 1) );
2013  ic->setRemapToEightBitFlag( scaleFlag );
2014 
2015  // Always have resampler cache.
2016  ic->setAddResamplerCacheFlag(true);
2017 
2018  //---
2019  // Don't need a chain cache as we're doing a sequential write. So the same tile
2020  // should never be visited more than once.
2021  //---
2022  ic->setAddChainCacheFlag(false);
2023 
2024  //---
2025  // Histogram:
2026  // Don't apply histogram stretch to dem sources for hill shade
2027  // operation.
2028  //---
2029  if ( ( isDemSource == false ) ||
2030  ( isDemSource && (m_operation != OSSIM_CHIPPER_OP_HILL_SHADE) ) )
2031  {
2033  }
2034 
2035  // Brightness, contrast. Note in same filter.
2037  {
2038  ic->setBrightnessContrastFlag(true);
2039  }
2040 
2041  std::string sharpnessMode = getSharpenMode();
2042  if ( sharpnessMode.size() )
2043  {
2044  ic->setSharpenFlag(true);
2045  }
2046 
2047  //---
2048  // Create the chain.
2049  //
2050  // NOTE: Histogram and band selector can be set in ic->createRenderedChain(rec)
2051  // if the right keywords are there.
2052  //---
2053  ic->createRenderedChain(rec);
2054 
2055  // Set the filter type if needed.
2056  ossimString lookup = m_kwl->findKey( RESAMPLER_FILTER_KW );
2057  if ( lookup.size() )
2058  {
2059  // Assumption image renderer is in chain:
2060  ic->getImageRenderer()->getResampler()->setFilterType( lookup );
2061  }
2062 
2063  // Histogram setup.
2064  if ( hasHistogramOperation() )
2065  {
2066  setupChainHistogram( ic , std::make_shared<ossimSrcRecord>(rec));
2067  }
2068 
2069  // Brightness constrast setup:
2071  {
2072  // Assumption bright contrast filter in chain:
2073 
2074  ossim_float64 value = getBrightness();
2075  ic->getBrightnessContrast()->setBrightness( value );
2076 
2077  value = getContrast();
2078  ic->getBrightnessContrast()->setContrast( value );
2079  }
2080 
2081  // Sharpness:
2082  if ( sharpnessMode.size() )
2083  {
2084  if ( sharpnessMode == "light" )
2085  {
2086  ic->getSharpenFilter()->setWidthAndSigma( 3, 0.5 );
2087  }
2088  else if ( sharpnessMode == "heavy" )
2089  {
2090  ic->getSharpenFilter()->setWidthAndSigma( 5, 1.0 );
2091  }
2092  }
2093 
2095  {
2096  ossimGeoPolygon polygon;
2097  getClipPolygon(polygon);
2098  if(polygon.size()>0)
2099  {
2100  ic->addGeoPolyCutterPolygon(polygon);
2101  }
2102  }
2103  }
2104  else // Open failed.
2105  {
2106  std::string errMsg = "Could not open from src record!";
2107  throw ossimException(errMsg);
2108  }
2109 
2110  if ( traceDebug() )
2111  {
2112  ossimKeywordlist kwl;
2113  ic->saveState(kwl, 0);
2114 
2116  << "chain:\n" << kwl << "\n"
2117  << MODULE << " exiting...\n";
2118  }
2119 
2120  return ic;
2121 }
2122 
2124 {
2125  static const char MODULE[] = "ossimChipperUtil::createOutputProjection";
2126 
2127  if ( traceDebug() )
2128  {
2129  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
2130  }
2131 
2132  std::string op = m_kwl->findKey( std::string(ossimKeywordNames::PROJECTION_KW) );
2133  std::string srs = m_kwl->findKey( SRS_KW );
2134 
2135  if ( op.size() && srs.size() )
2136  {
2138  << MODULE << " WARNING:"
2139  << "\nBoth " << SRS_KW << " and " << ossimKeywordNames::PROJECTION_KW
2140  << " keywords are set!"
2141  << "\nsrs: " << srs
2142  << "\noutput_projection: " << op
2143  << "\nTaking " << srs << " over " << op << "\n";
2144  }
2145 
2146  bool usingInput = false;
2149 
2150  // If an srs code use that first.
2151  if ( srs.size() )
2152  {
2153  proj = getNewProjectionFromSrsCode( srs );
2154  }
2155  else if ( op.size() )
2156  {
2157  switch ( projType )
2158  {
2160  {
2161  proj = getNewGeoProjection();
2162  break;
2163  }
2165  {
2166  proj = getNewGeoScaledProjection();
2167  break;
2168  }
2170  {
2171  proj = getFirstInputProjection();
2172  usingInput = true;
2173  break;
2174  }
2176  {
2177  proj = getNewUtmProjection();
2178  break;
2179  }
2180  default:
2181  {
2182  break; // Just for un-handled type warning.
2183  }
2184  }
2185  }
2186 
2187  // Check for identity projection:
2189  if ( proj.valid() && inputProj.valid() )
2190  {
2191  if ( *(inputProj.get()) == *(proj.get()) )
2192  {
2193  if ( projType == OSSIM_CHIPPER_PROJ_GEO_SCALED )
2194  {
2195  // Get the origin used for scaling.
2196  ossimGpt origin = proj->getOrigin();
2197 
2198  // Copy the input projection to our projection. Has the tie and scale we need.
2199  proj = inputProj;
2200 
2201  // Set the origin for scaling.
2202  proj->setOrigin(origin);
2203  }
2204  else
2205  {
2206  proj = inputProj;
2207  }
2208  usingInput = true;
2209  }
2210  }
2211 
2212  if ( !proj.valid() )
2213  {
2214  // Try first input. If map projected use that.
2215  if ( inputProj.valid() )
2216  {
2217  proj = inputProj;
2218  usingInput = true;
2219  if ( traceDebug() )
2220  {
2222  << "WARNING: No projection set!"
2223  << "\nDefaulting to first input's projection.\n";
2224  }
2225  }
2226  else
2227  {
2228  proj = getNewGeoScaledProjection();
2229  if ( traceDebug() )
2230  {
2232  << "WARNING: No projection set!"
2233  << "\nDefaulting to scaled geographic at scene center.\n";
2234  }
2235  }
2236  }
2237 
2238  // Create our ossimImageGeometry with projection (no transform).
2239  m_geom = new ossimImageGeometry( 0, proj.get() );
2240 
2241  //---
2242  // If the input is the same as output projection do not modify; else, set
2243  // the gsd to user selected "METERS_KW" or the best resolution of the inputs,
2244  // set the tie and then snap it to the projection origin.
2245  //---
2246  if ( !usingInput || hasScaleOption() )
2247  {
2248  // Set the scale.
2250  }
2251 
2252  // Set the tie.
2254 
2255  if ( snapTieToOrigin() )
2256  {
2257  // Adjust the projection tie to the origin.
2258  proj->snapTiePointToOrigin();
2259  }
2260 
2261  if ( traceDebug() )
2262  {
2264  << "using input projection: " << (usingInput?"true":"false")
2265  << "\noutput image geometry:\n";
2266 
2268 
2269  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exited...\n";
2270  }
2271 
2272 } // End: ossimChipperUtil::createOutputProjection()
2273 
2275 {
2276  static const char MODULE[] = "ossimChipperUtil::createIdentityProjection";
2277 
2278  if ( traceDebug() )
2279  {
2280  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
2281  }
2282 
2283  // Get the singe image chain. Sould be only one.
2285  if ( m_demLayer.size() )
2286  {
2287  sic = m_demLayer[0];
2288  }
2289  else if ( m_imgLayer.size() )
2290  {
2291  sic = m_imgLayer[0];
2292  }
2293 
2294  if ( sic.valid() )
2295  {
2296  // Get the image handler.
2298 
2299  // Resampler:
2301 
2302  if ( ih.valid() )
2303  {
2304  //---
2305  // Get the geometry from the image handler. Since we're in "identity"
2306  // mode use the inputs for the outputs.
2307  //---
2308  m_geom = ih->getImageGeometry();
2309 
2310  if ( m_geom.valid() )
2311  {
2312  ossim_float64 rotation = 0.0;
2313 
2314  if ( upIsUp() )
2315  {
2317  if ( proj.valid() )
2318  {
2319  rotation = m_geom->upIsUpAngle();
2320  }
2321  else
2322  {
2324  << "WARNING: No projection to compute the up is up angle!" << std::endl;
2325  }
2326  }
2327  else if ( northUp() )
2328  {
2330  if ( proj.valid() )
2331  {
2332  rotation = m_geom->northUpAngle();
2333  }
2334  else
2335  {
2337  << "WARNING: No projection to compute the North up angle!" << std::endl;
2338  }
2339  }
2340  else if ( hasRotation() )
2341  {
2342  rotation = getRotation();
2343  }
2344 
2345  if ( ossim::isnan( rotation ) )
2346  {
2347  rotation = 0.0;
2348  }
2349 
2350  ossimDpt imageSpaceScale;
2351  getImageSpaceScale( imageSpaceScale );
2352 
2353 
2354  //ossimDrect rect;
2355  //m_geom->getBoundingRect(rect);
2356  ossimDpt midPt;// = rect.midPoint();
2357 
2358  getImageSpacePivot(midPt);
2359 
2360  if ( traceDebug() )
2361  {
2363  << MODULE
2364  << "\nAffine transform parameters:"
2365  << "\nrotation: " << rotation
2366  << "\nmid point: " << midPt << std::endl;
2367  }
2368 
2369  m_ivt = new ossimImageViewAffineTransform(-rotation,
2370  imageSpaceScale.x, // image space scale x
2371  imageSpaceScale.y, // image space scale y
2372  1.0,1.0, //scale x and y
2373  0.0, 0.0, // translate x,y
2374  midPt.x*imageSpaceScale.x,
2375  midPt.y*imageSpaceScale.y); // pivot point
2376 
2377  if ( m_kwl->hasKey( METERS_KW ) ||
2378  m_kwl->hasKey( DEGREES_X_KW ) ||
2379  m_kwl->hasKey( RRDS_KW ) )
2380  {
2381  // Set the image view transform scale.
2383  }
2384 
2385 
2386  resampler->setImageViewTransform( m_ivt.get() );
2387 
2388  } // Matches: if ( m_geom.valid() )
2389 
2390  } // Matches: if ( ih.valid() )
2391 
2392  } // Matches: if ( sic.valid()
2393 
2394 } // End: createIdentityProjection()
2395 
2397 {
2398  if ( isChipMode() && m_ivt.valid() && m_geom.valid() )
2399  {
2400  ossimDpt scale;
2401  scale.makeNan();
2402 
2403  // Check for GSD spec. Degrees/pixel takes priority over meters/pixel:
2404  ossimString lookup;
2405  lookup.string() = m_kwl->findKey( DEGREES_X_KW );
2406  if ( lookup.size() )
2407  {
2408  ossimDpt outputDpp;
2409  outputDpp.makeNan();
2410 
2411  outputDpp.x = lookup.toFloat64();
2412 
2413  lookup.string() = m_kwl->findKey( DEGREES_Y_KW );
2414  if ( lookup.size() )
2415  {
2416  outputDpp.y = lookup.toFloat64();
2417  }
2418 
2419  if ( !outputDpp.hasNans() )
2420  {
2421  // Input degress per pixel. Consider this a scale of 1.0.
2422  ossimDpt inputDpp;
2423  m_geom->getDegreesPerPixel( inputDpp );
2424 
2425  if ( !inputDpp.hasNans() )
2426  {
2427  scale.x = inputDpp.x/outputDpp.x;
2428  scale.y = inputDpp.y/outputDpp.y;
2429  }
2430  }
2431  }
2432 
2433  if ( scale.hasNans() )
2434  {
2435  lookup = m_kwl->findKey( METERS_KW );
2436  if ( lookup.size() )
2437  {
2438  ossimDpt outputMpp;
2439  outputMpp.makeNan();
2440  outputMpp.x = lookup.toFloat64();
2441  outputMpp.y = outputMpp.x;
2442 
2443  if ( !outputMpp.hasNans() )
2444  {
2445  // Input meters per pixel. Consider this a scale of 1.0.
2446  ossimDpt inputMpp;
2447  m_geom->getMetersPerPixel( inputMpp );
2448 
2449  if ( !inputMpp.hasNans() )
2450  {
2451  scale.x = inputMpp.x/outputMpp.x;
2452  scale.y = inputMpp.y/outputMpp.y;
2453  }
2454  }
2455  }
2456  }
2457 
2458  if ( scale.hasNans() )
2459  {
2460  lookup = m_kwl->findKey( RRDS_KW );
2461  if ( lookup.size() )
2462  {
2463  ossim_float64 d = lookup.toInt32();
2464  if ( d == 0.0 )
2465  {
2466  scale.x = 1.0;
2467  }
2468  else
2469  {
2470  scale.x = 1.0 / std::pow(2.0, d);
2471  }
2472  scale.y = scale.x;
2473  }
2474  }
2475 
2476  if ( !scale.hasNans() )
2477  {
2478  m_ivt->scale( scale.x, scale.y );
2479  }
2480  else
2481  {
2482  std::string errMsg = "ossimChipperUtil::initializeIvtScale failed!";
2483  throw ossimException(errMsg);
2484  }
2485 
2486  } // Matches: if ( isChipMode() && ... )
2487 
2488 } // End: ossimChipperUtil::initializeIvtScale()
2489 
2491 {
2492  static const char MODULE[] = "ossimChipperUtil::initializeProjectionTiePoint()";
2493  if ( traceDebug() )
2494  {
2495  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
2496  }
2497 
2498  // Get the map projection from the output geometry:
2500 
2501  if ( mapProj.valid() )
2502  {
2503  //---
2504  // If the output is geographic of there are sensor model inputs, get the tie
2505  // using the ground point.
2506  //---
2507  if ( mapProj->isGeographic() || hasSensorModelInput() )
2508  {
2509  ossimGpt tiePoint;
2510  tiePoint.makeNan();
2511  getTiePoint(tiePoint);
2512 
2513  if ( !tiePoint.hasNans() )
2514  {
2515  //---
2516  // The tie point coordinates currently reflect the UL edge of the UL pixel.
2517  // We'll need to shift the tie point bac from the edge to the center base on the
2518  // output gsd.
2519  //---
2520  ossimDpt half_pixel_shift = m_geom->getDegreesPerPixel() * 0.5;
2521  tiePoint.lat -= half_pixel_shift.lat;
2522  tiePoint.lon += half_pixel_shift.lon;
2523  mapProj->setUlTiePoints(tiePoint);
2524  }
2525  else
2526  {
2527  std::string errMsg = MODULE;
2528  errMsg += " tie point has nans!";
2529  throw( ossimException(errMsg) );
2530  }
2531 
2532  if ( traceDebug() )
2533  {
2535  << "projection tie point: " << tiePoint << "\n" << MODULE << " exited...\n";
2536  }
2537  }
2538  else
2539  {
2540  //---
2541  // TODO: Add test for like input projections and use above geographic tie
2542  // code if not.
2543  //---
2544  ossimDpt tiePoint;
2545  tiePoint.makeNan();
2546  getTiePoint(tiePoint);
2547 
2548  if ( !tiePoint.hasNans() )
2549  {
2550  //---
2551  // The tie point coordinates currently reflect the UL edge of the UL pixel.
2552  // We'll need to shift the tie point bac from the edge to the center base on the
2553  // output gsd.
2554  //---
2555  ossimDpt half_pixel_shift = m_geom->getMetersPerPixel() * 0.5;
2556  tiePoint.y -= half_pixel_shift.y;
2557  tiePoint.x += half_pixel_shift.x;
2558  mapProj->setUlTiePoints(tiePoint);
2559  }
2560  else
2561  {
2562  std::string errMsg = MODULE;
2563  errMsg += " tie point has nans!";
2564  throw( ossimException(errMsg) );
2565  }
2566 
2567  if ( traceDebug() )
2568  {
2570  << "projection tie point: " << tiePoint << "\n" << MODULE << " exited...\n";
2571  }
2572  }
2573 
2574  } // Matches: if ( mapProj.valid() )
2575  else
2576  {
2577  std::string errMsg = MODULE;
2578  errMsg += "m_projection is null!";
2579  throw( ossimException(errMsg) );
2580  }
2581 }
2582 
2584 {
2585  static const char MODULE[] = "ossimChipperUtil::initializeProjectionGsd()";
2586  if ( traceDebug() )
2587  {
2588  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
2589  }
2590 
2592  if ( !mapProj.valid() )
2593  {
2594  std::string errMsg = MODULE;
2595  errMsg += " projection is null!";
2596  throw( ossimException(errMsg) );
2597  }
2598 
2599  ossimDpt gsd;
2600  gsd.makeNan();
2601 
2602  ossimString degreesX;
2603  ossimString degreesY;
2604  ossimString meters;
2605  degreesX.string() = m_kwl->findKey( DEGREES_X_KW );
2606  degreesY.string() = m_kwl->findKey( DEGREES_Y_KW );
2607  meters.string() = m_kwl->findKey( METERS_KW );
2608 
2609  if ( hasCutBoxWidthHeight() )
2610  {
2611  // --cut-bbox-llwh Implies a scale...
2612  if ( degreesX.size() || degreesY.size() || meters.size() )
2613  {
2614  std::ostringstream errMsg;
2615  errMsg << MODULE << " ERROR: Ambiguous scale keywords!\n"
2616  << "Do not combine meters or degrees with cut box with a width and height.\n";
2617  throw( ossimException( errMsg.str() ) );
2618  }
2619 
2620  ossimString cutMinLat;
2621  ossimString cutMinLon;
2622  ossimString cutMaxLat;
2623  ossimString cutMaxLon;
2624  ossimString cutWidth;
2625  ossimString cutHeight;
2626  cutMinLat.string() = m_kwl->findKey( CUT_MIN_LAT_KW );
2627  cutMinLon.string() = m_kwl->findKey( CUT_MIN_LON_KW );
2628  cutMaxLat.string() = m_kwl->findKey( CUT_MAX_LAT_KW );
2629  cutMaxLon.string() = m_kwl->findKey( CUT_MAX_LON_KW );
2630  cutWidth.string() = m_kwl->findKey( CUT_WIDTH_KW );
2631  cutHeight.string() = m_kwl->findKey( CUT_HEIGHT_KW );
2632  if ( cutMinLat.size() && cutMinLon.size() && cutMaxLat.size() &&
2633  cutMaxLon.size() && cutWidth.size() && cutHeight.size() )
2634  {
2635  ossim_float64 minLat = cutMinLat.toFloat64();
2636  ossim_float64 minLon = cutMinLon.toFloat64();
2637  ossim_float64 maxLat = cutMaxLat.toFloat64();
2638  ossim_float64 maxLon = cutMaxLon.toFloat64();
2639  ossim_float64 width = cutWidth.toFloat64();
2640  ossim_float64 height = cutHeight.toFloat64();
2641  if ( !ossim::isnan(minLat) && !ossim::isnan(minLon) && !ossim::isnan(maxLat) &&
2642  !ossim::isnan(maxLon) && !ossim::isnan(width) && !ossim::isnan(height) )
2643  {
2644  gsd.x = std::fabs( maxLon - minLon ) / width;
2645  gsd.y = std::fabs( maxLat - minLat ) / height;
2646 
2647  mapProj->setDecimalDegreesPerPixel(gsd);
2648  }
2649  }
2650  }
2651  else if(hasWmsBboxCutWidthHeight())
2652  {
2653  ossimString cutWidth;
2654  ossimString cutHeight;
2655  ossimString cutWmsBbox;
2656 
2657  cutWidth.string() = m_kwl->findKey( CUT_WIDTH_KW );
2658  cutHeight.string() = m_kwl->findKey( CUT_HEIGHT_KW );
2659  cutWmsBbox.string() = m_kwl->findKey( CUT_WMS_BBOX_KW );
2660 
2661  cutWmsBbox = cutWmsBbox.upcase().replaceAllThatMatch("BBOX:","");
2662  std::vector<ossimString> cutBox = cutWmsBbox.split(",");
2663  if(cutBox.size()==4)
2664  {
2665  ossim_float64 minx = cutBox[0].toFloat64();
2666  ossim_float64 miny = cutBox[1].toFloat64();
2667  ossim_float64 maxx = cutBox[2].toFloat64();
2668  ossim_float64 maxy = cutBox[3].toFloat64();
2669  ossim_float64 width = cutWidth.toFloat64();
2670  ossim_float64 height = cutHeight.toFloat64();
2671  gsd.x = std::fabs( maxx - minx ) / width;
2672  gsd.y = std::fabs( maxy - miny ) / height;
2673 
2674  // bbox is in the units of the projector
2675  if(mapProj->isGeographic())
2676  {
2677 
2678  mapProj->setDecimalDegreesPerPixel(gsd);
2679  }
2680  else
2681  {
2682  mapProj->setMetersPerPixel(gsd);
2683  }
2684  }
2685  else
2686  {
2687  std::ostringstream errMsg;
2688  errMsg << MODULE << " ERROR: cut box does not have 4 values!\n";
2689  throw( ossimException( errMsg.str() ) );
2690  }
2691  }
2692  else
2693  {
2694  if ( meters.size() && ( degreesX.size() || degreesY.size() ) )
2695  {
2696  std::ostringstream errMsg;
2697  errMsg << MODULE << " ERROR: Ambiguous scale keywords!\n"
2698  << "Do not combine meters with degrees.\n";
2699  throw( ossimException( errMsg.str() ) );
2700  }
2701 
2702  if ( degreesX.size() )
2703  {
2704  // --degrees
2705  gsd.x = degreesX.toFloat64();
2706 
2707  if ( degreesY.size() )
2708  {
2709  gsd.y = degreesY.toFloat64();
2710  }
2711  if ( !gsd.hasNans() )
2712  {
2713  mapProj->setDecimalDegreesPerPixel(gsd);
2714  }
2715  }
2716  else if ( meters.size() )
2717  {
2718  // --meters
2719  gsd.x = meters.toFloat64();
2720  gsd.y = gsd.x;
2721  if ( !gsd.hasNans() )
2722  {
2723  mapProj->setMetersPerPixel(gsd);
2724  }
2725  }
2726  }
2727 
2728  if ( gsd.hasNans() )
2729  {
2730  // Get the best resolution from the inputs.
2731  getMetersPerPixel(gsd);
2732 
2733  // See if the output projection is geo-scaled; if so, make the pixels square in meters.
2735  {
2736  // Pick the best resolution and make them both the same.
2737  gsd.x = ossim::min<ossim_float64>(gsd.x, gsd.y);
2738  gsd.y = gsd.x;
2739  }
2740 
2741  // Set to input gsd.
2742  mapProj->setMetersPerPixel(gsd);
2743  }
2744 
2745  if ( traceDebug() )
2746  {
2748  << "projection gsd: " << gsd << "\n" << MODULE << " exited...\n";
2749  }
2750 }
2751 
2753 {
2754  static const char MODULE[] = "ossimChipperUtil::getTiePoint(ossimGpt&)";
2755  if ( traceDebug() )
2756  {
2757  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
2758  }
2759 
2760  std::vector< ossimRefPtr<ossimSingleImageChain> >::iterator chainIdx;
2761 
2762  tie.lat = ossim::nan();
2763  tie.lon = ossim::nan();
2764  tie.hgt = 0.0;
2765 
2766  // Loop through dem layers.
2767  ossimGpt chainTiePoint;
2768  chainIdx = m_demLayer.begin();
2769  while ( chainIdx != m_demLayer.end() )
2770  {
2771  getTiePoint( (*chainIdx).get(), chainTiePoint );
2772  if ( tie.hasNans() )
2773  {
2774  tie = chainTiePoint;
2775  }
2776  else
2777  {
2778  if ( chainTiePoint.lat > tie.lat )
2779  {
2780  tie.lat = chainTiePoint.lat;
2781  }
2782  if ( chainTiePoint.lon < tie.lon )
2783  {
2784  tie.lon = chainTiePoint.lon;
2785  }
2786  }
2787  ++chainIdx;
2788  }
2789 
2790  // Loop through image layers.
2791  chainIdx = m_imgLayer.begin();
2792  while ( chainIdx != m_imgLayer.end() )
2793  {
2794  getTiePoint( (*chainIdx).get(), chainTiePoint );
2795  if ( tie.hasNans() )
2796  {
2797  tie = chainTiePoint;
2798  }
2799  else
2800  {
2801  if ( chainTiePoint.lat > tie.lat )
2802  {
2803  tie.lat = chainTiePoint.lat;
2804  }
2805  if ( chainTiePoint.lon < tie.lon )
2806  {
2807  tie.lon = chainTiePoint.lon;
2808  }
2809  }
2810  ++chainIdx;
2811  }
2812 
2813  if ( traceDebug() )
2814  {
2816  << "tie point: " << tie << "\n" << MODULE << " exited...\n";
2817  }
2818 }
2819 
2821 {
2822  static const char MODULE[] = "ossimChipperUtil::getTiePoint(ossimSingleImageChain*,ossimGpt&)";
2823  if ( traceDebug() )
2824  {
2825  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
2826  }
2827 
2828  if (chain && m_geom.valid() )
2829  {
2830  //---
2831  // The view is not set yet in the chain so we get the tie point from the
2832  // image handler geometry not from the chain which will come from the
2833  // ossimImageRenderer.
2834  //---
2836  if ( ih.valid() )
2837  {
2839  if ( geom.valid() )
2840  {
2841  geom->getTiePoint( tie, true );
2842  }
2843 
2844 
2845  // Set height to 0.0 even though it's not used so hasNans test works.
2846  tie.hgt = 0.0;
2847 
2848  if ( tie.hasNans() )
2849  {
2850  std::string errMsg = MODULE;
2851  errMsg += "\ngeom->localToWorld returned nan for chain.";
2852  errMsg += "\nChain: ";
2853  errMsg += chain->getFilename().string();
2854  throw ossimException(errMsg);
2855  }
2856  }
2857  else
2858  {
2859  std::string errMsg = MODULE;
2860  errMsg += "\nNo geometry for chain: ";
2861  errMsg += chain->getFilename().string();
2862  throw ossimException(errMsg);
2863  }
2864  }
2865  else
2866  {
2867  std::string errMsg = MODULE;
2868  errMsg += " ERROR: Null chain passed to method!";
2869  throw ossimException(errMsg);
2870  }
2871 
2872  if ( traceDebug() )
2873  {
2875  << "chain name: " << chain->getFilename()
2876  << "\ntie point: " << tie << "\n"
2877  << MODULE << " exited...\n";
2878  }
2879 }
2880 
2882 {
2883  static const char MODULE[] = "ossimChipperUtil::getTiePoint(ossimDpt&)";
2884  if ( traceDebug() )
2885  {
2886  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
2887  }
2888 
2889  std::vector< ossimRefPtr<ossimSingleImageChain> >::iterator chainIdx;
2890 
2891  tie.makeNan();
2892 
2893  // Loop through dem layers.
2894  ossimDpt chainTiePoint;
2895  chainIdx = m_demLayer.begin();
2896  while ( chainIdx != m_demLayer.end() )
2897  {
2898  getTiePoint( (*chainIdx).get(), chainTiePoint );
2899  if ( tie.hasNans() )
2900  {
2901  tie = chainTiePoint;
2902  }
2903  else
2904  {
2905  if ( chainTiePoint.y > tie.y )
2906  {
2907  tie.y = chainTiePoint.y;
2908  }
2909  if ( chainTiePoint.x < tie.x )
2910  {
2911  tie.x = chainTiePoint.x;
2912  }
2913  }
2914  ++chainIdx;
2915  }
2916 
2917  // Loop through image layers.
2918  chainIdx = m_imgLayer.begin();
2919  while ( chainIdx != m_imgLayer.end() )
2920  {
2921  getTiePoint( (*chainIdx).get(), chainTiePoint );
2922  if ( tie.hasNans() )
2923  {
2924  tie = chainTiePoint;
2925  }
2926  else
2927  {
2928  if ( chainTiePoint.y > tie.y )
2929  {
2930  tie.y = chainTiePoint.y;
2931  }
2932  if ( chainTiePoint.x < tie.x )
2933  {
2934  tie.x = chainTiePoint.x;
2935  }
2936  }
2937  ++chainIdx;
2938  }
2939 
2940  if ( traceDebug() )
2941  {
2943  << "tie point: " << tie << "\n" << MODULE << " exited...\n";
2944  }
2945 }
2946 
2948 {
2949  static const char MODULE[] = "ossimChipperUtil::getTiePoint(ossimSingleImageChain*,ossimDpt&)";
2950  if ( traceDebug() )
2951  {
2952  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
2953  }
2954 
2955  if (chain && m_geom.valid() )
2956  {
2957  //---
2958  // The view is not set yet in the chain so we get the tie point from the
2959  // image handler geometry not from the chain which will come from the
2960  // ossimImageRenderer.
2961  //---
2963  if ( ih.valid() )
2964  {
2966  if ( geom.valid() )
2967  {
2968  geom->getTiePoint( tie, true );
2969  }
2970 
2971  if ( tie.hasNans() )
2972  {
2973  std::string errMsg = MODULE;
2974  errMsg += "\ngeom->localToWorld returned nan for chain.";
2975  errMsg += "\nChain: ";
2976  errMsg += chain->getFilename().string();
2977  throw ossimException(errMsg);
2978  }
2979  }
2980  else
2981  {
2982  std::string errMsg = MODULE;
2983  errMsg += "\nNo geometry for chain: ";
2984  errMsg += chain->getFilename().string();
2985  throw ossimException(errMsg);
2986  }
2987  }
2988  else
2989  {
2990  std::string errMsg = MODULE;
2991  errMsg += " ERROR: Null chain passed to method!";
2992  throw ossimException(errMsg);
2993  }
2994 
2995  if ( traceDebug() )
2996  {
2998  << "chain name: " << chain->getFilename()
2999  << "\ntie point: " << tie << "\n"
3000  << MODULE << " exited...\n";
3001  }
3002 }
3003 
3005 {
3006  static const char MODULE[] = "ossimChipperUtil::getMetersPerPixel(ossimDpt&)";
3007  if ( traceDebug() )
3008  {
3009  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
3010  }
3011 
3012  gsd.makeNan();
3013 
3014  ossimDpt chainGsd;
3015  std::vector< ossimRefPtr<ossimSingleImageChain> >::iterator chainIdx;
3016 
3017  // Loop through dem layers.
3018  chainIdx = m_demLayer.begin();
3019  while ( chainIdx != m_demLayer.end() )
3020  {
3021  getMetersPerPixel( (*chainIdx).get(), chainGsd);
3022  if ( gsd.hasNans() || ( chainGsd.x < gsd.x ) )
3023  {
3024  gsd = chainGsd;
3025  }
3026  ++chainIdx;
3027  }
3028 
3029  // Loop through image layers.
3030  chainIdx = m_imgLayer.begin();
3031  while ( chainIdx != m_imgLayer.end() )
3032  {
3033  getMetersPerPixel( (*chainIdx).get(), chainGsd);
3034  if ( gsd.hasNans() || ( chainGsd.x < gsd.x ) )
3035  {
3036  gsd = chainGsd;
3037  }
3038  ++chainIdx;
3039  }
3040 
3041  if ( traceDebug() )
3042  {
3044  << "gsd: " << gsd << "\n" << MODULE << " exited...\n";
3045  }
3046 }
3047 
3049 {
3050  static const char MODULE[] = "ossimChipperUtil::getMetersPerPixel(ossimSingleImageChain*,ossimDpt&)";
3051  if ( traceDebug() )
3052  {
3053  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
3054  }
3055 
3056  if (chain)
3057  {
3059  if ( geom.valid() )
3060  {
3061  geom->getMetersPerPixel( gsd );
3062  if ( gsd.hasNans() )
3063  {
3064  std::string errMsg = MODULE;
3065  errMsg += "\ngeom->getMetersPerPixel returned nan for chain.";
3066  errMsg += "\nChain: ";
3067  errMsg += chain->getFilename().string();
3068  throw ossimException(errMsg);
3069  }
3070  }
3071  else
3072  {
3073  std::string errMsg = MODULE;
3074  errMsg += "\nNo geometry for chain: ";
3075  errMsg += chain->getFilename().string();
3076  throw ossimException(errMsg);
3077  }
3078  }
3079  else
3080  {
3081  std::string errMsg = MODULE;
3082  errMsg += " ERROR: Null chain passed to method!";
3083  throw ossimException(errMsg);
3084  }
3085 
3086  if ( traceDebug() )
3087  {
3089  << "chain name: " << chain->getFilename()
3090  << "\nmeters per pixel: " << gsd << "\n" << MODULE << " exited...\n";
3091  }
3092 }
3093 
3095 {
3096  ossim_float64 result = ossim::nan();
3098  if ( lookup.size() )
3099  {
3100  result = lookup.toFloat64();
3101  if ( (result < -180.0) || (result > 180.0) )
3102  {
3103  std::string errMsg = "central meridian range error!";
3104  errMsg += " Valid range: -180 to 180";
3105  throw ossimException(errMsg);
3106  }
3107  }
3108  return result;
3109 }
3110 
3112 {
3113  ossim_float64 result = ossim::nan();
3115  if ( lookup.size() )
3116  {
3117  result = lookup.toFloat64();
3118  if ( (result < -90) || (result > 90.0) )
3119  {
3120  std::string errMsg = "origin latitude range error!";
3121  errMsg += " Valid range: -90 to 90";
3122  throw ossimException(errMsg);
3123  }
3124  }
3125  return result;
3126 }
3127 
3129 {
3130  static const char MODULE[] = "ossimChipperUtil::getSceneCenter(ossimGpt&)";
3131  if ( traceDebug() )
3132  {
3133  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
3134  }
3135 
3136  std::vector<ossimGpt> centerGptArray;
3137  ossimGpt centerGpt;
3138 
3139  std::vector< ossimRefPtr<ossimSingleImageChain> >::iterator chainIdx;
3140 
3141  // Loop through dem layers.
3142  chainIdx = m_demLayer.begin();
3143  while ( chainIdx != m_demLayer.end() )
3144  {
3145  getSceneCenter( (*chainIdx).get(), centerGpt);
3146  if ( !centerGpt.hasNans() )
3147  {
3148  centerGptArray.push_back( centerGpt );
3149  }
3150  ++chainIdx;
3151  }
3152 
3153  // Loop through image layers.
3154  chainIdx = m_imgLayer.begin();
3155  while ( chainIdx != m_imgLayer.end() )
3156  {
3157  getSceneCenter( (*chainIdx).get(), centerGpt);
3158  if ( !centerGpt.hasNans() )
3159  {
3160  centerGptArray.push_back( centerGpt );
3161  }
3162  ++chainIdx;
3163  }
3164 
3165  ossim_float64 lat = 0.0;
3166  ossim_float64 lon = 0.0;
3167 
3168  std::vector<ossimGpt>::const_iterator pointIdx = centerGptArray.begin();
3169  while ( pointIdx != centerGptArray.end() )
3170  {
3171  lat += (*pointIdx).lat;
3172  lon += (*pointIdx).lon;
3173  ++pointIdx;
3174  }
3175 
3176  lat /= centerGptArray.size();
3177  lon /= centerGptArray.size();
3178 
3179  if ( (lat >= -90.0) && (lat <= 90.0) && (lon >= -180.0) && (lon <= 180.0) )
3180  {
3181  gpt.lat = lat;
3182  gpt.lon = lon;
3183  }
3184  else
3185  {
3186  std::ostringstream errMsg;
3187  errMsg << MODULE << " range error!\nlatitude = "
3188  << ossimString::toString(lat).string()
3189  << "\nlongitude = "
3190  << ossimString::toString(lon).string();
3191  throw ossimException( errMsg.str() );
3192  }
3193 
3194  if ( traceDebug() )
3195  {
3197  << "scene center: " << gpt << "\n" << MODULE << " exited...\n";
3198  }
3199 }
3200 
3202 {
3203  static const char MODULE[] =
3204  "ossimChipperUtil::getSceneCenter(const ossimSingleImageChain*,ossimGpt&)";
3205 
3206  if ( traceDebug() )
3207  {
3208  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
3209  }
3210 
3211  if (chain)
3212  {
3214  if ( geom.valid() )
3215  {
3216  ossimIrect boundingRect = chain->getBoundingRect();
3217  ossimDpt midPoint = boundingRect.midPoint();
3218  geom->localToWorld(midPoint, gpt);
3219  gpt.hgt = 0.0;
3220 
3221  if ( gpt.hasNans() )
3222  {
3223  std::string errMsg = MODULE;
3224  errMsg += "\ngeom->localToWorld returned nan for chain.";
3225  errMsg += "\nChain: ";
3226  errMsg += chain->getFilename().string();
3227  throw ossimException(errMsg);
3228  }
3229  }
3230  else
3231  {
3232  std::string errMsg = MODULE;
3233  errMsg += "\nNo geometry for chain: ";
3234  errMsg += chain->getFilename().string();
3235  throw ossimException(errMsg);
3236  }
3237  }
3238  else
3239  {
3240  std::string errMsg = MODULE;
3241  errMsg += " ERROR: Null chain passed to method!";
3242  throw ossimException(errMsg);
3243  }
3244 
3245  if ( traceDebug() )
3246  {
3248  << "chain name: " << chain->getFilename()
3249  << "\nscene center: " << gpt << "\n"
3250  << MODULE << " exited...\n";
3251  }
3252 }
3253 
3255 {
3256  static const char MODULE[] = "ossimChipperUtil::getFirstInputProjection";
3257  if ( traceDebug() )
3258  {
3259  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
3260  }
3261 
3264 
3265  // Get the first image handler.
3266  if ( m_demLayer.size() )
3267  {
3268  ih = m_demLayer[0]->getImageHandler();
3269  }
3270  else if ( m_imgLayer.size() )
3271  {
3272  ih = m_imgLayer[0]->getImageHandler();
3273  }
3274 
3275  if ( ih.valid() )
3276  {
3277  // Get the geometry from the first image handler.
3279  if ( geom.valid() )
3280  {
3281  // Get the image projection.
3283  if ( proj.valid() )
3284  {
3285  // Cast and assign to result.
3286  ossimMapProjection* mapProj = PTR_CAST( ossimMapProjection, proj.get() );
3287  if (mapProj)
3288  {
3289  // Must duplicate in case the output projection gets modified.
3290  result = (ossimMapProjection*) mapProj->dup();
3291  }
3292  if ( !result.valid() && traceDebug() )
3293  {
3294  ossimNotify(ossimNotifyLevel_WARN) << "Could not cast to map projection.\n";
3295  }
3296  }
3297  else if ( traceDebug() )
3298  {
3299  ossimNotify(ossimNotifyLevel_WARN) << "No projection in first chain...\n";
3300  }
3301  }
3302  }
3303  else if ( traceDebug() )
3304  {
3305  ossimNotify(ossimNotifyLevel_WARN) << "No image handler in first chain...\n";
3306  }
3307 
3308  if ( traceDebug() )
3309  {
3310  if ( result.valid() )
3311  {
3313  }
3314  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exited...\n";
3315  }
3316 
3317  return result;
3318 }
3319 
3321 {
3323 }
3324 
3326 {
3327  // Make projection:
3329 
3330  // Set the origin for scaling:
3331 
3332  // First check for user set "central_meridian" and "origin_latitude":
3333  ossimGpt origin;
3334  origin.lat = getOriginLatitude();
3335  origin.lon = getCentralMeridian();
3336  origin.hgt = 0.0;
3337 
3338  if ( origin.hasNans() )
3339  {
3340  // Use the scene center from the input.
3341  getSceneCenter( origin );
3342 
3343  //---
3344  // Note only latitude used for scaling, origin kept at 0.0.
3345  // This is a fix/hack for ossimEquDistCylProjection wrapping issues.
3346  //---
3347  origin.lon = 0.0;
3348  }
3349 
3350  if ( !origin.hasNans() )
3351  {
3352  result->setOrigin(origin);
3353  }
3354  else
3355  {
3356  std::string errMsg = "ossimChipperUtil::getNewGeoScaledProjection ERROR";
3357  errMsg += "\nOrigin has nans!";
3358  throw ossimException(errMsg);
3359  }
3360 
3361  return result;
3362 }
3363 
3365  const std::string& code)
3366 {
3368 
3369  ossimString os = code;
3370  os.downcase();
3371 
3372  if ( ( os == "epsg:4326" ) || ( code == "4326" ) )
3373  {
3374  // Avoid factory call for this.
3375  result = new ossimEquDistCylProjection();
3376  }
3377  else
3378  {
3380  createProjection(code);
3381  if ( proj.valid() )
3382  {
3383  result = PTR_CAST( ossimMapProjection, proj.get() );
3384  }
3385  }
3386  return result;
3387 }
3388 
3390 {
3391  // Make projection:
3393 
3394  // Set the zone from keyword option:
3395  bool setZone = false;
3396  ossim_int32 zone = getZone();
3397  if ( (zone > 0 ) && ( zone < 61 ) )
3398  {
3399  utm->setZone( zone );
3400  setZone = true;
3401  }
3402 
3403  // Set the hemisphere from keyword option:
3404  bool setHemisphere = false;
3405  std::string hemisphere = getHemisphere();
3406  if ( hemisphere.size() )
3407  {
3408  ossimString h(hemisphere);
3409  h.upcase();
3410  if ( ( h == "N" ) || ( h == "NORTH" ) )
3411  {
3412  char c = 'N';
3413  utm->setHemisphere( c );
3414  setHemisphere = true;
3415  }
3416  if ( ( h == "S" ) || ( h == "SOUTH" ) )
3417  {
3418  char c = 'S';
3419  utm->setHemisphere( c );
3420  setHemisphere = true;
3421  }
3422  }
3423 
3424  if ( !setZone || !setHemisphere )
3425  {
3426  // First check for user set "central_meridian" and "origin_latitude":
3427  ossimGpt origin;
3428  origin.lat = getOriginLatitude();
3429  origin.lon = getCentralMeridian();
3430  origin.hgt = 0.0;
3431 
3432  if ( origin.hasNans() )
3433  {
3434  // Use the scene center from the input.
3435  getSceneCenter( origin );
3436  }
3437 
3438  if ( !origin.hasNans() )
3439  {
3440  if ( !setZone )
3441  {
3442  utm->setZone(origin);
3443  }
3444  if ( !setHemisphere )
3445  {
3446  utm->setHemisphere(origin);
3447  }
3448  }
3449  else
3450  {
3451  std::string errMsg = "ossimChipperUtil::getNewUtmProjection ERROR";
3452  errMsg += "\nOrigin has nans!";
3453  throw ossimException(errMsg);
3454  }
3455  }
3456 
3457  return ossimRefPtr<ossimMapProjection>(utm.get());
3458 }
3459 
3461 {
3463  if ( m_geom.valid() )
3464  {
3465  mp = dynamic_cast<ossimMapProjection*>( m_geom->getProjection() );
3466  }
3467  return mp;
3468 }
3469 
3471 {
3472  static const char MODULE[] = "ossimChipperUtil::createNewWriter()";
3473  if ( traceDebug() )
3474  {
3475  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
3476  }
3477 
3478  ossimFilename outputFile;
3479  getOutputFilename(outputFile);
3480 
3481  if ( outputFile == ossimFilename::NIL)
3482  {
3483  std::string errMsg = MODULE;
3484  errMsg += " ERROR no output file name!";
3485  throw ossimException(errMsg);
3486  }
3487 
3489 
3490  ossimString lookup = m_kwl->findKey( WRITER_KW );
3491  if ( lookup.size() )
3492  {
3494  if ( !writer.valid() )
3495  {
3496  std::string errMsg = MODULE;
3497  errMsg += " ERROR creating writer: ";
3498  errMsg += lookup.string();
3499  throw ossimException(errMsg);
3500  }
3501  }
3502  else // Create from output file extension.
3503  {
3505  createWriterFromExtension( outputFile.ext() );
3506 
3507  if ( !writer.valid() )
3508  {
3509  std::string errMsg = MODULE;
3510  errMsg += " ERROR creating writer from extension: ";
3511  errMsg += outputFile.ext().string();
3512  throw ossimException(errMsg);
3513  }
3514  }
3515 
3516  // Set the output name.
3517  writer->setFilename( outputFile );
3518 
3519  // Add any writer props.
3520  ossim_uint32 count = m_kwl->numberOf( WRITER_PROPERTY_KW.c_str() );
3521  for (ossim_uint32 i = 0; i < count; ++i)
3522  {
3523  ossimString key = WRITER_PROPERTY_KW;
3524  key += ossimString::toString(i);
3525  lookup = m_kwl->findKey( key.string() );
3526  if ( lookup.size() )
3527  {
3528  std::vector<ossimString> splitArray;
3529  lookup.split(splitArray, "=");
3530  if(splitArray.size() == 2)
3531  {
3533  new ossimStringProperty(splitArray[0], splitArray[1]);
3534 
3535  if ( traceDebug() )
3536  {
3538  << "Setting writer prop: " << splitArray[0] << "=" << splitArray[1] << "\n";
3539  }
3540 
3541  writer->setProperty( prop );
3542  }
3543  }
3544  }
3545 
3546  // Output tile size:
3547  lookup = m_kwl->findKey( TILE_SIZE_KW );
3548  if ( lookup.size() )
3549  {
3550  ossimIpt tileSize;
3551  tileSize.x = lookup.toInt32();
3552  if ( (tileSize.x % 16) == 0 )
3553  {
3554  tileSize.y = tileSize.x;
3555  writer->setTileSize( tileSize );
3556  }
3557  else if ( traceDebug() )
3558  {
3560  << MODULE << " NOTICE:"
3561  << "\nTile width must be a multiple of 16! Using default.."
3562  << std::endl;
3563  }
3564  }
3565 
3566  if ( traceDebug() )
3567  {
3569  << "writer name: " << writer->getClassName() << "\n"
3570  << MODULE << " exited...\n";
3571  }
3572 
3573  return writer;
3574 }
3575 
3577 {
3578  static const char MODULE[] = "ossimChipperUtil::propagateOutputProjectionToChains()";
3579  if ( traceDebug() )
3580  {
3581  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
3582  }
3583 
3584  std::vector< ossimRefPtr<ossimSingleImageChain> >::iterator chainIdx;
3585 
3586  // we need to make sure the outputs are refreshed so they can reset themselves
3587  // Needed when we are doing interactive update to the GSD and clip window
3589  ossimEventVisitor eventVisitor(refreshEvent.get());
3590  ossimViewInterfaceVisitor viewVisitor(m_geom.get());
3591  // Loop through dem layers.
3592  chainIdx = m_demLayer.begin();
3593  while ( chainIdx != m_demLayer.end() )
3594  {
3595  viewVisitor.reset();
3596  eventVisitor.reset();
3597  (*chainIdx)->accept(viewVisitor);
3598  (*chainIdx)->accept(eventVisitor);
3599 
3600  ossimRefPtr<ossimImageRenderer> resampler = (*chainIdx)->getImageRenderer();
3601  if ( resampler.valid() )
3602  {
3603  //resampler->setView( m_geom.get() );
3604  // resampler->propagateEventToOutputs(refreshEvent);
3605  }
3606  else
3607  {
3608  std::string errMsg = MODULE;
3609  errMsg += " chain has no resampler!";
3610  throw( ossimException(errMsg) );
3611  }
3612  ++chainIdx;
3613  }
3614 
3615  // Loop through image layers.
3616  chainIdx = m_imgLayer.begin();
3617  while ( chainIdx != m_imgLayer.end() )
3618  {
3619  ossimRefPtr<ossimImageRenderer> resampler = (*chainIdx)->getImageRenderer();
3620  eventVisitor.reset();
3621  viewVisitor.reset();
3622  (*chainIdx)->accept(viewVisitor);
3623  (*chainIdx)->accept(eventVisitor);
3624 
3625  if ( resampler.valid() )
3626  {
3627  //resampler->setView( m_geom.get() );
3628  //resampler->propagateEventToOutputs(refreshEvent);
3629  }
3630  else
3631  {
3632  std::string errMsg = MODULE;
3633  errMsg += " chain has no resampler!";
3634  throw( ossimException(errMsg) );
3635  }
3636  ++chainIdx;
3637  }
3638 
3639  if ( traceDebug() )
3640  {
3641  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exited...\n";
3642  }
3643 }
3644 
3646  std::vector< ossimRefPtr<ossimSingleImageChain> >& layers) const
3647 {
3648  static const char MODULE[] = "ossimChipperUtil::combineLayers(layers)";
3649  if ( traceDebug() )
3650  {
3651  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
3652  }
3653 
3654  ossimRefPtr<ossimImageSource> result = 0;
3655 
3656  if ( layers.size() == 1 )
3657  {
3658  result = layers[0].get();
3659  }
3660  else if ( layers.size() > 1 )
3661  {
3662 
3663  result = createCombiner();//new ossimImageMosaic;
3664 
3665  std::vector< ossimRefPtr<ossimSingleImageChain> >::iterator chainIdx = layers.begin();
3666  while ( chainIdx != layers.end() )
3667  {
3668  result->connectMyInputTo( (*chainIdx).get() );
3669  ++chainIdx;
3670  }
3671  }
3672 
3673  if ( traceDebug() )
3674  {
3675  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exited...\n";
3676  }
3677 
3678  return result;
3679 }
3680 
3682 {
3683  static const char MODULE[] = "ossimChipperUtil::combineLayers()";
3684  if ( traceDebug() )
3685  {
3686  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
3687  }
3688 
3689  ossimRefPtr<ossimImageSource> result = 0;
3690 
3691  ossim_uint32 layerCount = (ossim_uint32) (m_demLayer.size() + m_imgLayer.size());
3692 
3693  if ( layerCount )
3694  {
3695  if ( layerCount == 1 )
3696  {
3697  if ( m_imgLayer.size() )
3698  {
3699  result = m_imgLayer[0].get();
3700  }
3701  else
3702  {
3703  result = m_demLayer[0].get();
3704  }
3705  }
3706  else
3707  {
3708  result = createCombiner();//new ossimImageMosaic;
3709 
3710  // Combine the images. Note we'll put the images on top of the dems.
3711  if ( m_imgLayer.size() )
3712  {
3713  std::vector< ossimRefPtr<ossimSingleImageChain> >::iterator chainIdx =
3714  m_imgLayer.begin();
3715  while ( chainIdx != m_imgLayer.end() )
3716  {
3717  result->connectMyInputTo( (*chainIdx).get() );
3718  ++chainIdx;
3719  }
3720  }
3721  if ( m_demLayer.size() ) // Combine any dem layers.
3722  {
3723  std::vector< ossimRefPtr<ossimSingleImageChain> >::iterator chainIdx =
3724  m_demLayer.begin();
3725  while ( chainIdx != m_demLayer.end() )
3726  {
3727  result->connectMyInputTo( (*chainIdx).get() );
3728  ++chainIdx;
3729  }
3730  }
3731  }
3732  }
3733 
3734  if ( traceDebug() )
3735  {
3736  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exited...\n";
3737  }
3738 
3739  return result;
3740 
3741 } // End: ossimChipperUtil::combineLayers
3742 
3744 {
3745  ossimRefPtr<ossimImageSource> result = 0;
3746 
3747  ossim_uint32 layerCount = (ossim_uint32) (m_demLayer.size() + m_imgLayer.size());
3748 
3749  // Must have two and only two inputs.
3750  if ( layerCount == 2 )
3751  {
3754 
3755  //---
3756  // Expecting two image layers. We'll code it for flexabilty though...
3757  // - Take old and new from m_imgLayer if present.
3758  // - Use m_demLayer only if missing.
3759  // - Using first image found as old, second new.
3760  //---
3761 
3762  // Most likely case, two image layers.
3763  if ( m_imgLayer.size() )
3764  {
3765  oldImg = m_imgLayer[0].get();
3766 
3767  if ( m_imgLayer.size() == 2 )
3768  {
3769  newImg = m_imgLayer[1].get();
3770  }
3771  }
3772 
3773  if ( m_demLayer.size() )
3774  {
3775  if ( !oldImg.valid() )
3776  {
3777  oldImg = m_demLayer[0].get();
3778  }
3779 
3780  if ( !newImg.valid() )
3781  {
3782  if ( m_demLayer.size() == 1 )
3783  {
3784  newImg = m_demLayer[0].get();
3785  }
3786  else if ( m_demLayer.size() == 2 )
3787  {
3788  newImg = m_demLayer[1].get();
3789  }
3790  }
3791  }
3792 
3793  if ( newImg.valid() && oldImg.valid() )
3794  {
3795  // Input 0 is old, 1 is new.
3797  tcmv->connectMyInputTo( 0, oldImg.get() );
3798  tcmv->connectMyInputTo( 1, newImg.get() );
3799 
3800  // Look for 2cmv options.
3801  ossim_uint32 oldInputBandIndex = 0;
3802  ossim_uint32 newInputBandIndex = 0;
3809 
3810  ossimString os;
3811  std::string key = TWOCMV_OLD_INPUT_BAND_KW;
3812  std::string val = m_kwl->findKey( key );
3813 
3814  if ( val.size() )
3815  {
3816  os = val;
3817  oldInputBandIndex = os.toUInt32();
3818  }
3819 
3820  key = TWOCMV_NEW_INPUT_BAND_KW;
3821  val = m_kwl->findKey( key );
3822  if ( val.size() )
3823  {
3824  os = val;
3825  newInputBandIndex = os.toUInt32();
3826  }
3827 
3828  key = TWOCMV_RED_OUTPUT_SOURCE_KW;
3829  val = m_kwl->findKey( key );
3830  if ( val.size() )
3831  {
3832  os = val;
3833  os.downcase();
3834 
3835  if ( os == "new" )
3836  {
3837  redOutputSource = ossimTwoColorView::NEW;
3838  }
3839  else if ( os == "MIN" )
3840  {
3841  redOutputSource = ossimTwoColorView::MIN;
3842  }
3843  }
3844 
3845  key = TWOCMV_GREEN_OUTPUT_SOURCE_KW;
3846  val = m_kwl->findKey( key );
3847  if ( val.size() )
3848  {
3849  os = val;
3850  os.downcase();
3851 
3852  if ( os == "old" )
3853  {
3854  grnOutputSource = ossimTwoColorView::OLD;
3855  }
3856  else if ( os == "MIN" )
3857  {
3858  grnOutputSource = ossimTwoColorView::MIN;
3859  }
3860  }
3861 
3862  key = TWOCMV_BLUE_OUTPUT_SOURCE_KW;
3863  val = m_kwl->findKey( key );
3864  if ( val.size() )
3865  {
3866  os = val;
3867  os.downcase();
3868 
3869  if ( os == "old" )
3870  {
3871  bluOutputSource = ossimTwoColorView::OLD;
3872  }
3873  else if ( os == "MIN" )
3874  {
3875  bluOutputSource = ossimTwoColorView::MIN;
3876  }
3877  }
3878 
3879  // Set options.
3880  tcmv->setBandIndexMapping( oldInputBandIndex,
3881  newInputBandIndex,
3882  redOutputSource,
3883  grnOutputSource,
3884  bluOutputSource );
3885  tcmv->initialize();
3886 
3887  result = tcmv.get();
3888  }
3889  }
3890 
3891  return result;
3892 
3893 } // ossimChipperUtil::initialize2CmvChain()
3894 
3896  ossimRefPtr<ossimImageSource> &source) const
3897 {
3898  static const char MODULE[] = "ossimChipperUtil::addIndexToRgbLutFilter(source)";
3899  if ( traceDebug() )
3900  {
3901  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
3902  }
3903 
3904  ossimRefPtr<ossimImageSource> result = 0;
3905 
3906  if ( source.valid() )
3907  {
3909  ossimFilename lutFile;
3910  lutFile.string() = m_kwl->findKey( LUT_FILE_KW );
3911  if ( lutFile.exists() )
3912  {
3913  //---
3914  // Connect to dems:
3915  // Must do this first so that the min and max get set from the input
3916  // connection prior to initializing the lut.
3917  //---
3918  lut->connectMyInputTo( source.get() );
3919 
3920  // Note sure about this. Make option maybe? (drb)
3922 
3923  lut->setLut(lutFile);
3924 
3925  // Set as color source for bump shade.
3926  result = lut.get();
3927  }
3928  else
3929  {
3930  std::string errMsg = MODULE;
3931  errMsg += " color table does not exists: ";
3932  errMsg += lutFile.string();
3933  throw ossimException(errMsg);
3934  }
3935  }
3936  else
3937  {
3938  std::string errMsg = MODULE;
3939  errMsg += " ERROR: Null source passed to method!";
3940  throw ossimException(errMsg);
3941  }
3942 
3943  if ( traceDebug() )
3944  {
3945  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exited...\n";
3946  }
3947 
3948  return result;
3949 }
3950 
3952  ossimRefPtr<ossimImageSource> &source, ossimScalarType scalar) const
3953 {
3954  static const char MODULE[] = "ossimChipperUtil::addScalarRemapper(source)";
3955  if ( traceDebug() )
3956  {
3957  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
3958  }
3959 
3960  ossimRefPtr<ossimImageSource> result = 0;
3961 
3962  if ( source.valid() )
3963  {
3964  if ( ( scalar != OSSIM_SCALAR_UNKNOWN ) && ( source->getOutputScalarType() != scalar ) )
3965  {
3967  remapper->setOutputScalarType(scalar);
3968  remapper->connectMyInputTo( source.get() );
3969  result = remapper.get();
3970 
3971  if ( traceDebug() )
3972  {
3974  << "\nOutput remapped to: "
3975  << ossimScalarTypeLut::instance()->getEntryString(scalar) << "\n";
3976  }
3977  }
3978  else
3979  {
3980  result = source;
3981  }
3982  }
3983  else
3984  {
3985  std::string errMsg = MODULE;
3986  errMsg += " ERROR: Null source passed to method!";
3987  throw ossimException(errMsg);
3988  }
3989 
3990  if ( traceDebug() )
3991  {
3993  << MODULE << " exited...\n";
3994  }
3995 
3996  return result;
3997 }
3998 
4000  ossimRefPtr<ossimImageSource>& source ) const
4001 {
4002  static const char MODULE[] = "ossimChipperUtil::addAnnotations(source)";
4003  if ( traceDebug() )
4004  {
4005  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
4006  }
4007 
4008  ossimRefPtr<ossimImageSource> result = 0;
4009 
4010  if ( source.valid() & m_geom.valid() )
4011  {
4012  ossimString regularExpression = "annotation[0-9]*\\.type";
4013  const ossim_uint32 COUNT = m_kwl->getNumberOfKeysThatMatch( regularExpression );
4014  if ( COUNT > 0 )
4015  {
4016  // Create annotator:
4018 
4019  // Connect it up:
4020  annotator->connectMyInputTo( source.get() );
4021 
4022  // Loop through keyword list and add all annotation objects.
4023  ossim_uint32 i = 0;
4024  ossim_uint32 found = 0;
4025  std::string prefixBase = "annotation";
4026  std::string prefix;
4027  std::string key;
4028  std::string value;
4029  while ( (found < COUNT) && ( i < (COUNT+100) ) )
4030  {
4031  prefix = prefixBase + ossimString::toString( i ).string() + ".";
4032  key = "type";
4033  value = m_kwl->findKey( prefix, key );
4034  if ( value.size() )
4035  {
4036  ++found;
4037 
4038  if ( value == "cross_hair" )
4039  {
4040  addCrossHairAnnotation( annotator, prefix );
4041  }
4042  }
4043  ++i;
4044  }
4045 
4046  annotator->initialize();
4047 
4048  // Assign return result:
4049  result = annotator.get();
4050  }
4051  }
4052  else
4053  {
4054  std::string errMsg = MODULE;
4055  errMsg += " ERROR: Null source passed to method!";
4056  throw ossimException(errMsg);
4057  }
4058 
4059  if ( traceDebug() )
4060  {
4061  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exited...\n";
4062  }
4063 
4064  return result;
4065 }
4066 
4068  ossimRefPtr<ossimAnnotationSource> annotator, const std::string& prefix ) const
4069 {
4070  if ( annotator.valid() && prefix.size() )
4071  {
4072  std::string linePrefix = prefix + std::string("line.");
4073  std::string textPrefix = prefix + std::string("text.");
4074  ossimDpt centerPt;
4075  centerPt.makeNan();
4076  ossim_float64 lineSize = 8.0;
4077  ossimDpt start;
4078  ossimDpt end;
4079 
4080  // Cross hair line location:
4081  std::string key = "location";
4082  std::string value = m_kwl->findKey( linePrefix, key );
4083  if ( value.size() )
4084  {
4085  if (value == "scene_center")
4086  {
4087  ossimIrect boundingRect = annotator->getBoundingRect( 0 );
4088  centerPt = boundingRect.midPoint();
4089  }
4090  }
4091  else
4092  {
4093  key = "location.gpt";
4094  value = m_kwl->findKey( linePrefix, key );
4095  if ( value.size() )
4096  {
4097  ossimGpt gpt;
4098  gpt.toPoint( value );
4099  if ( gpt.hasNans() == false )
4100  {
4101  // Convert to view coordinate.
4102  ossimDpt imgPt;
4103  m_geom->worldToLocal( gpt, imgPt );
4104  if ( m_ivt.valid() )
4105  {
4106  m_ivt->imageToView( imgPt, centerPt );
4107  }
4108  else
4109  {
4110  centerPt = imgPt;
4111  }
4112  }
4113  }
4114  }
4115 
4116  if ( centerPt.hasNans() == false )
4117  {
4118  // Cross hair size:
4119  key = "size";
4120  value = m_kwl->findKey( linePrefix, key );
4121  if ( value.size() )
4122  {
4123  lineSize = ossimString::toInt32( ossimString(value) );
4124  }
4125  ossim_float64 halfLine = lineSize/2.0;
4126 
4127  // Create lines.
4129 
4130  // Pick up r,g,b,thickness.
4131  line1->loadState( *(m_kwl.get()), linePrefix.c_str() );
4132 
4133  start.x = centerPt.x;
4134  start.y = centerPt.y-halfLine;
4135  end.x = centerPt.x;
4136  end.y = centerPt.y+halfLine;
4137 
4138  // ossimAnnotationLineObject::setLine recomputes the bounding box.
4139  line1->setLine( start, end );
4140 
4141  annotator->addObject( line1.get() );
4142 
4144 
4145  // This will pick up r,g,b,thickness.
4146  line2->loadState( *(m_kwl.get()), linePrefix.c_str() );
4147 
4148  start.x = centerPt.x-halfLine;
4149  start.y = centerPt.y;
4150  end.x = centerPt.x+halfLine;
4151  end.y = centerPt.y;
4152 
4153  // ossimAnnotationLineObject::setLine recomputes the bounding box.
4154  line2->setLine( start, end );
4155 
4156  annotator->addObject( line2.get() );
4157 
4158  // Set text if any:
4159  key = "string";
4160  value = m_kwl->findKey( textPrefix, key );
4161  if ( value.size() )
4162  {
4164  text->loadState( *(m_kwl.get()), textPrefix.c_str() );
4165 
4166  text->setString( ossimString(value) );
4167 
4168  // text scale:
4169  key = "scale";
4170  value = m_kwl->findKey( textPrefix, key );
4171  if ( value.size() )
4172  {
4173  ossimDpt scale;
4174  scale.toPoint( value );
4175  text->setScale( scale );
4176  }
4177 
4178  // text point size:
4179  key = "point_size";
4180  value = m_kwl->findKey( textPrefix, key );
4181  if ( value.size() )
4182  {
4183  ossimIpt ptSize;
4184  ptSize.toPoint( value );
4185  text->setPointSize( ptSize );
4186  }
4187 
4188  // text location:
4189  key = "location";
4190  value = m_kwl->findKey( textPrefix, key );
4191  if ( value.size() )
4192  {
4193  if ( value == "bottom" )
4194  {
4195  ossimIpt ipt;
4196  ipt.x = (ossim_int32)centerPt.x;
4197  ipt.y = (ossim_int32)(centerPt.y+halfLine+10);
4198  text->setUpperLeftPosition( ipt );
4199 
4200  ossimDrect rect;
4201  text->getBoundingRect( rect );
4202  ipt.x = ipt.x - rect.width()/2;
4203  text->setUpperLeftPosition( ipt );
4204  }
4205  }
4206 
4207  annotator->addObject( text.get() );
4208  }
4209  }
4210  }
4211 
4212 } // End: ossimChipperUtil::addCrossHairAnnotations( ... )
4213 
4215  std::shared_ptr<ossimSrcRecord> srcRecordPtr) const
4216 {
4217  static const char MODULE[] = "ossimChipperUtil::setupChainHistogram(chain)";
4218  if ( traceDebug() )
4219  {
4220  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
4221  }
4222 
4223  bool result = false;
4224 
4227 
4228  if ( chain.valid() )
4229  {
4232 
4233  if ( ih.valid() && remapper.valid() &&
4235  {
4236  result = true;
4237  ossimString histCenterKw = m_kwl->findKey(HIST_CENTER_KW);
4238  if(histCenterKw.empty())
4239  {
4240  histCenterKw = "false";
4241  }
4242  bool roiStretch = ( m_kwl->hasKey( HIST_AOI_KW ) || m_kwl->hasKey( HIST_LLWH_KW ) ||
4243  histCenterKw.toBool() );
4244 
4245  if ( !roiStretch )
4246  {
4247  bool openedHistogram = false;
4248  if ( remapper->getHistogramFile() == ossimFilename::NIL )
4249  {
4250  ossimFilename f;
4251  if(srcRecordPtr)
4252  {
4253  f = srcRecordPtr->getHistogramPath();
4254  }
4255  // Open histogram file.
4256  if(f.empty() || !f.exists())
4257  {
4258  f = ih->getFilenameWithThisExtension( ossimString("his") );
4259  if ( f.empty() || (f.exists() == false) )
4260  {
4261  // For backward compatibility check if single entry and _e0.his
4262  f = ih->getFilenameWithThisExtension( ossimString("his"), true );
4263  if(!f.exists()) f.clear();
4264  }
4265  }
4266 
4267  if ( !f.empty() )
4268  {
4269  openedHistogram = remapper->openHistogram( f );
4270  if ( !openedHistogram && traceDebug() )
4271  {
4273  << MODULE << " WARNING:"
4274  << "\nCould not open: " << f << "\n";
4275  }
4276  }
4277 
4278  if ( !openedHistogram )
4279  {
4280  //---
4281  // User requested a histogram operation but does not have
4282  // external histogram file. This will cause downstream code
4283  // to computer from center tile of image.
4284  //---
4285  roiStretch = true;
4286  }
4287  }
4288  }
4289 
4290  // Enable and set mode:
4291  remapper->setEnableFlag(true);
4292  remapper->setStretchMode( mode );
4293 
4294  if ( roiStretch )
4295  {
4296  ossimIrect aoi;
4297 
4298  std::string value = m_kwl->findKey( HIST_AOI_KW );
4299  if ( value.size() )
4300  {
4301  result = getIrect( value, aoi );
4302  }
4303  else
4304  {
4305  value = m_kwl->findKey( HIST_LLWH_KW );
4306  if ( value.size() )
4307  {
4308  result = getIrect( chain, value, aoi );
4309  }
4310  else // Use center of image.
4311  {
4312  result = getIrect( chain, aoi );
4313  }
4314  }
4315 
4316  if ( traceDebug() )
4317  {
4319  << "ROI of histogram: " << aoi << std::endl;
4320  }
4321 
4322  if ( result )
4323  {
4324  //---
4325  // Note: both of these sections work.
4326  // Going with separate connection for now. drb - 20 Feb. 2016
4327  //---
4328 #if 1
4331  ihist->setAreaOfInterest( aoi );
4332  ihist->connectMyInputTo( remapper->getInput() );//ih.get());
4333  remapper->connectMyInputTo( ihist.get() );
4334 #else
4335  remapper->computeHistogram( aoi );
4336 #endif
4337  }
4338  }
4339 
4340  if ( !result )
4341  {
4342  remapper->setEnableFlag(false);
4343  }
4344 
4345  } // Matches: if ( ih.valid() && remapper.valid() && mode... )
4346 
4347  } // Matches: if ( chain.valid() )
4348 
4349  if ( traceDebug() )
4350  {
4351  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exited...\n";
4352  }
4353 
4354  return result;
4355 }
4356 
4358  ossimRefPtr<ossimSingleImageChain>& chain, ossim_uint32 entryIndex ) const
4359 {
4360  bool result = false;
4361  if ( chain.valid() )
4362  {
4364  if ( ih.valid() )
4365  {
4366  result = ih->setCurrentEntry( entryIndex );
4367  }
4368  }
4369  return result;
4370 }
4371 
4373 {
4374  f.string() = m_kwl->findKey( std::string(ossimKeywordNames::OUTPUT_FILE_KW) );
4375 }
4376 
4378 {
4379  static const char MODULE[] = "ossimChipperUtil::getAreaOfInterest()";
4380  if ( traceDebug() )
4381  {
4382  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " entered...\n";
4383  }
4384 
4385  // Nan rect for starters.
4386  rect.makeNan();
4387 
4388  if ( source )
4389  {
4390  source->initialize(); // Ensure all bounding rectangles are set.
4391 
4392  if ( m_kwl->hasKey( CUT_BBOX_XYWH_KW ) )
4393  {
4394  // <x>,<y>,<w>,<h>
4395  std::string cutBbox = m_kwl->findKey( CUT_BBOX_XYWH_KW );
4396  getIrect( cutBbox, rect );
4397  }
4398  if (rect.hasNans() &&
4399  m_kwl->hasKey(FULLRES_XYS_KW) &&
4400  m_kwl->hasKey(CUT_WIDTH_KW) &&
4401  m_kwl->hasKey(CUT_HEIGHT_KW))
4402  {
4403  ossimString tempFullXys = m_kwl->findKey(FULLRES_XYS_KW);
4404  ossimString tempWidth = m_kwl->findKey(CUT_WIDTH_KW);
4405  ossimString tempHeight = m_kwl->findKey(CUT_HEIGHT_KW);
4406  double w = tempWidth.toDouble();
4407  double h = tempHeight.toDouble();
4408  if (m_geom && m_ivt)
4409  {
4410  std::vector<ossimString> values;
4411  tempFullXys.split(values, ",");
4412  ossimDpt scale;
4413  ossimDpt location;
4414  scale.makeNan();
4415  location.makeNan();
4416  double w = tempWidth.toDouble();
4417  double h = tempHeight.toDouble();
4418  if (values.size() > 2)
4419  {
4420  location.x = values[0].toDouble();
4421  location.y = values[1].toDouble();
4422  // ossimDrect r;
4423  // m_geom->getBoundingRect(r);
4424  // r = m_ivt->getImageToViewBounds(r);
4425  ossimDpt mid;
4426  m_ivt->imageToView(location, mid);
4427  ossimIpt ul(ossim::round<int>(mid.x - (w / 2)),
4428  ossim::round<int>(mid.y - (h / 2)));
4429  ossimIpt lr((ul.x + w - 1), ul.y + h - 1);
4430  //rect = resampler->getBoundingRect();
4431  rect = ossimIrect(ul, lr);
4432  }
4433  }
4434  }
4435  if (rect.hasNans())
4436  {
4437  if ( m_geom.valid() )
4438  {
4439  if ( m_kwl->find( CUT_CENTER_LAT_KW.c_str() ) )
4440  {
4441  // "Cut Center" with: --cut-center-llwh or --cut-center-llr:
4442 
4443  ossimString latStr = m_kwl->findKey( CUT_CENTER_LAT_KW );
4444  ossimString lonStr = m_kwl->findKey( CUT_CENTER_LON_KW );
4445  if ( latStr.size() && lonStr.size() )
4446  {
4447  ossimGpt centerGpt;
4448 
4449  //---
4450  // Want the height nan going into worldToLocal call so it gets picked
4451  // up by the elevation manager.
4452  //---
4453  centerGpt.makeNan();
4454 
4455  centerGpt.lat = latStr.toFloat64();
4456  centerGpt.lon = lonStr.toFloat64();
4457 
4458  if ( !centerGpt.isLatNan() && !centerGpt.isLonNan() )
4459  {
4460  // Ground "cut center" to view:
4461  ossimDpt centerDpt(0.0, 0.0);
4462  m_geom->worldToLocal(centerGpt, centerDpt);
4463 
4464  if ( !centerDpt.hasNans() )
4465  {
4466  if ( isChipMode() && m_ivt.valid() ) // Chipping in image space.
4467  {
4468  // Tranform image center point to view:
4469  ossimDpt ipt = centerDpt;
4470  m_ivt->imageToView( ipt, centerDpt );
4471  }
4472 
4473  // --cut-center-llwh:
4474  ossimString widthStr = m_kwl->findKey( CUT_WIDTH_KW );
4475  ossimString heightStr = m_kwl->findKey( CUT_HEIGHT_KW );
4476  if ( widthStr.size() && heightStr.size() )
4477  {
4478  ossim_int32 width = widthStr.toInt32();
4479  ossim_int32 height = heightStr.toInt32();
4480  if ( width && height )
4481  {
4482  ossimIpt ul( ossim::round<int>(centerDpt.x - (width/2)),
4483  ossim::round<int>(centerDpt.y - (height/2)) );
4484  ossimIpt lr( (ul.x + width - 1), ul.y + height - 1);
4485  rect = ossimIrect(ul, lr);
4486  }
4487  }
4488  else // --cut-center-llr:
4489  {
4490  ossimString radiusStr = m_kwl->findKey( CUT_RADIUS_KW );
4491  if ( radiusStr.size() )
4492  {
4493  ossim_float64 radius = radiusStr.toFloat64();
4494  if ( radius )
4495  {
4496  ossimDpt mpp;
4497  m_geom->getMetersPerPixel( mpp );
4498 
4499  if ( !mpp.hasNans() )
4500  {
4501  ossim_float64 rx = radius/mpp.x;
4502  ossim_float64 ry = radius/mpp.y;
4503 
4504  ossimIpt ul( ossim::round<int>( centerDpt.x - rx ),
4505  ossim::round<int>( centerDpt.y - ry ) );
4506  ossimIpt lr( ossim::round<int>( centerDpt.x + rx ),
4507  ossim::round<int>( centerDpt.y + ry ) );
4508  rect = ossimIrect(ul, lr);
4509  }
4510  }
4511  }
4512  }
4513  }
4514 
4515  } // Matches: if ( !centerGpt.hasNans() )
4516 
4517  } // Matches: if ( latStr && lonStr )
4518 
4519  } // Matches: if ( m_kwl->find( CUT_CENTER_LAT_KW ) )
4520 
4521  else if ( (m_kwl->find( CUT_MAX_LAT_KW.c_str() ) ||
4522  (m_kwl->find( CUT_WMS_BBOX_LL_KW.c_str() ))))
4523  {
4524  ossimString maxLat;
4525  ossimString maxLon;
4526  ossimString minLat;
4527  ossimString minLon;
4528 
4529  // --cut-bbox-ll or --cut-bbox-llwh
4530  if(m_kwl->find( CUT_MAX_LAT_KW.c_str() ))
4531  {
4532  maxLat = m_kwl->findKey( CUT_MAX_LAT_KW );
4533  maxLon = m_kwl->findKey( CUT_MAX_LON_KW );
4534  minLat = m_kwl->findKey( CUT_MIN_LAT_KW );
4535  minLon = m_kwl->findKey( CUT_MIN_LON_KW );
4536  }
4537  else
4538  {
4539  ossimString cutBbox = m_kwl->findKey( CUT_WMS_BBOX_LL_KW );
4540 
4541  cutBbox = cutBbox.upcase().replaceAllThatMatch("BBOX:");
4542  std::vector<ossimString> cutBox = cutBbox.split(",");
4543  if(cutBox.size() >3)
4544  {
4545  minLon = cutBox[0];
4546  minLat = cutBox[1];
4547  maxLon = cutBox[2];
4548  maxLat = cutBox[3];
4549  }
4550  }
4551 
4552  if ( maxLat.size() && maxLon.size() && minLat.size() && minLon.size() )
4553  {
4554  ossim_float64 minLatF = minLat.toFloat64();
4555  ossim_float64 maxLatF = maxLat.toFloat64();
4556  ossim_float64 minLonF = minLon.toFloat64();
4557  ossim_float64 maxLonF = maxLon.toFloat64();
4558 
4559  //---
4560  // Check for swap so we don't get a negative height.
4561  // Note no swap check for longitude as box could cross date line.
4562  //---
4563  if ( minLatF > maxLatF )
4564  {
4565  ossim_float64 tmpF = minLatF;
4566  minLatF = maxLatF;
4567  maxLatF = tmpF;
4568  }
4569 
4570  //---
4571  // Assume cut box is edge to edge or "Pixel Is Area". Our
4572  // AOI(area of interest) uses center of pixel or "Pixel Is Point"
4573  // so get the degrees per pixel and shift AOI to center.
4574  //---
4575  ossimDpt halfDpp;
4576  m_geom->getDegreesPerPixel( halfDpp );
4577  halfDpp = halfDpp/2.0;
4578 
4579  ossimGpt gpt(0.0, 0.0, 0.0);
4580  ossimDpt ulPt;
4581  ossimDpt lrPt;
4582 
4583  // Upper left:
4584  gpt.lat = maxLatF - halfDpp.y;
4585  gpt.lon = minLonF + halfDpp.x;
4586  m_geom->worldToLocal(gpt, ulPt);
4587 
4588  // Lower right:
4589  gpt.lat = minLatF + halfDpp.y;
4590  gpt.lon = maxLonF - halfDpp.x;
4591  m_geom->worldToLocal(gpt, lrPt);
4592 
4593  if ( isChipMode() && m_ivt.valid() )
4594  {
4595  // Chipping in image space:
4596 
4597  // Tranform image ul point to view:
4598  ossimDpt ipt = ulPt;
4599  m_ivt->imageToView( ipt, ulPt );
4600 
4601  // Tranform image lr point to view:
4602  ipt = lrPt;
4603  m_ivt->imageToView( ipt, lrPt );
4604  }
4605 
4606  rect = ossimIrect( ossimIpt(ulPt), ossimIpt(lrPt) );
4607  }
4608  }
4609  else if ( m_kwl->find( CUT_WMS_BBOX_KW.c_str() ) )
4610  {
4611  ossimString cutBbox = m_kwl->findKey( CUT_WMS_BBOX_KW );
4612 
4613  cutBbox = cutBbox.upcase().replaceAllThatMatch("BBOX:");
4614  std::vector<ossimString> cutBox = cutBbox.split(",");
4615  if(cutBox.size()==4)
4616  {
4617 
4618  ossim_float64 minx=cutBox[0].toFloat64();
4619  ossim_float64 miny=cutBox[1].toFloat64();
4620  ossim_float64 maxx=cutBox[2].toFloat64();
4621  ossim_float64 maxy=cutBox[3].toFloat64();
4622 
4623  const ossimMapProjection* mapProj = m_geom->getAsMapProjection();
4624  if(mapProj)
4625  {
4626  std::vector<ossimDpt> pts(4);
4627  ossimDpt* ptsArray = &pts.front();
4628  if(mapProj->isGeographic())
4629  {
4630  ossimDpt halfDpp;
4631  m_geom->getDegreesPerPixel( halfDpp );
4632  halfDpp = halfDpp/2.0;
4633 
4634  ossimGpt gpt(0.0, 0.0, 0.0);
4635  ossimDpt ulPt;
4636  ossimDpt lrPt;
4637 
4638  // Upper left:
4639  gpt.lat = maxy - halfDpp.y;
4640  gpt.lon = minx + halfDpp.x;
4641  m_geom->worldToLocal(gpt, ptsArray[0]);
4642  // Upper right:
4643  gpt.lat = maxy - halfDpp.y;
4644  gpt.lon = maxx - halfDpp.x;
4645  m_geom->worldToLocal(gpt, ptsArray[1]);
4646 
4647  // Lower right:
4648  gpt.lat = miny + halfDpp.y;
4649  gpt.lon = maxx - halfDpp.x;
4650  m_geom->worldToLocal(gpt, ptsArray[2]);
4651 
4652  //Lower left
4653  gpt.lat = miny + halfDpp.y;
4654  gpt.lon = minx + halfDpp.x;
4655  m_geom->worldToLocal(gpt, ptsArray[3]);
4656  //m_geom->worldToLocal(ossimGpt(miny,minx), ptsArray[0]);
4657  //m_geom->worldToLocal(ossimGpt(maxy,minx), ptsArray[1]);
4658  //m_geom->worldToLocal(ossimGpt(maxy,maxx), ptsArray[2]);
4659  //m_geom->worldToLocal(ossimGpt(miny,maxx), ptsArray[3]);
4660 
4661  }
4662  else
4663  {
4664  ossimDpt halfMpp;
4665  ossimDpt eastingNorthing;
4666  m_geom->getMetersPerPixel( halfMpp );
4667  halfMpp = halfMpp/2.0;
4668 
4669  eastingNorthing.x = minx+halfMpp.x;
4670  eastingNorthing.y = miny+halfMpp.y;
4671  mapProj->eastingNorthingToLineSample(eastingNorthing, ptsArray[0]);
4672  eastingNorthing.x = minx+halfMpp.x;
4673  eastingNorthing.y = maxy-halfMpp.y;
4674  mapProj->eastingNorthingToLineSample(eastingNorthing, ptsArray[1]);
4675  eastingNorthing.x = maxx-halfMpp.x;
4676  eastingNorthing.y = maxy-halfMpp.y;
4677  mapProj->eastingNorthingToLineSample(eastingNorthing, ptsArray[2]);
4678  eastingNorthing.x = maxx-halfMpp.x;
4679  eastingNorthing.y = miny+halfMpp.y;
4680  mapProj->eastingNorthingToLineSample(eastingNorthing, ptsArray[3]);
4681  }
4682  rect = ossimIrect(pts);
4683  }
4684  }
4685  }
4686 
4687  } // if ( m_getOutputGeometry.valid() )
4688  else
4689  {
4690  // Should never happer...
4691  std::string errMsg = MODULE;
4692  if ( !source )
4693  {
4694  errMsg += " image source null!";
4695  }
4696  else
4697  {
4698  errMsg += " output projection null!";
4699  }
4700  throw( ossimException(errMsg) );
4701  }
4702 
4703  // If no user defined rect set to scene bounding rect.
4704  if ( rect.hasNans() )
4705  {
4706  // Get the rectangle from the input chain:
4707  rect = source->getBoundingRect(0);
4708  }
4709 
4710  } // if ( rect.hasNans() )
4711 
4712  } // if ( source )
4713 
4714  if ( traceDebug() )
4715  {
4717  << "aoi: " << rect << "\n"
4718  << MODULE << " exited...\n";
4719  }
4720 
4721 } // End: ossimChipperUtil::getAreaOfInterest
4722 
4723 bool ossimChipperUtil::getIrect( const std::string& s, ossimIrect& rect ) const
4724 {
4725  bool result = false;
4726  if ( s.size() )
4727  {
4728  // <x>,<y>,<w>,<h>
4729  ossimString cutBbox = s;
4730  std::vector<ossimString> keys;
4731  cutBbox.split(keys, ",");
4732  if( keys.size() > 3 )
4733  {
4734  ossimIpt ul;
4735  ossimIpt lr;
4736  ul.x = keys[0].toInt32();
4737  ul.y = keys[1].toInt32();
4738  lr.x = ul.x + keys[2].toInt32() - 1;
4739  lr.y = ul.y + keys[3].toInt32() - 1;
4740  rect = ossimIrect(ul, lr);
4741  result = true;
4742  }
4743  }
4744  return result;
4745 }
4746 
4748  const std::string& s,
4749  ossimIrect& rect ) const
4750 {
4751  bool result = false;
4752 
4753  if ( chain.valid() )
4754  {
4756  if ( ih.valid() )
4757  {
4758  // Get the geometry from the image handler.
4760  if ( geom.valid() )
4761  {
4762  // <lat>,<lon>,<w>,<h>
4763  ossimString cutBbox = s;
4764  std::vector<ossimString> keys;
4765  cutBbox.split(keys, ",");
4766  if( keys.size() > 3 )
4767  {
4768  ossimGpt gpt;
4769  gpt.lat = keys[0].toFloat64();
4770  gpt.lon = keys[1].toFloat64();
4771  ossim_int32 w = keys[2].toInt32();
4772  ossim_int32 h = keys[3].toInt32();
4773  ossimDpt dpt;
4774  geom->worldToLocal( gpt, dpt );
4775  ossimIpt ul = dpt;
4776  ul.x -= w/2;
4777  ul.y -= h/2;
4778  ossimIpt lr( ul.x + w - 1, ul.y + h - 1);
4779  rect = ossimIrect(ul, lr);
4780  result = true;
4781  }
4782  }
4783  }
4784  }
4785 
4786  return result;
4787 }
4788 
4790  ossimIrect& rect ) const
4791 {
4792  bool result = false;
4793  if ( chain.valid() )
4794  {
4796  if ( ih.valid() )
4797  {
4798  const ossim_int32 MAX = 512;
4799  ossimIrect r = ih->getImageRectangle();
4800  ossimIpt size = r.size();
4801  ossim_int32 w = ossim::min( MAX, size.x );
4802  ossim_int32 h = ossim::min( MAX, size.y );
4803  ossimIpt ul = r.midPoint();
4804  ul.x -= w/2;
4805  ul.y -= h/2;
4806  ossimIpt lr( ul.x + w - 1, ul.y + h -1 );
4807  rect = ossimIrect(ul, lr);
4808  result = true;
4809  }
4810  }
4811  return result;
4812 }
4813 
4815  ossimIrect& adjustedRect)
4816 {
4817  static const char MODULE[] = "ossimChipperUtil::initializeThumbnailProjection";
4818  if ( traceDebug() )
4819  {
4821  << MODULE << " entered...\n"
4822  << "origial rect: " << originalRect << "\n";
4823 
4824  if (m_geom.valid())
4825  {
4827  }
4828  }
4829 
4830  if ( !originalRect.hasNans() && m_geom.valid() )
4831  {
4832  //---
4833  // Thumbnail setup:
4834  //---
4835  ossimString thumbRes = m_kwl->findKey( THUMBNAIL_RESOLUTION_KW );
4836  if ( thumbRes.size() )
4837  {
4838  ossim_float64 thumbSize = thumbRes.toFloat64();
4839  ossim_float64 maxRectDimension =
4840  ossim::max( originalRect.width(), originalRect.height() );
4841  ossim_uint32 tw = originalRect.width();
4842  ossim_uint32 th = originalRect.height();
4843  ossim_float64 scale = 1.0;
4844  if ( maxRectDimension > thumbSize )
4845  {
4846  // Need to adjust scale:
4847 
4848  // Get the corners before the scale change:
4849  ossimGpt ulGpt;
4850  ossimGpt lrGpt;
4851 
4852  m_geom->localToWorld(ossimDpt(originalRect.ul()), ulGpt);
4853  m_geom->localToWorld(ossimDpt(originalRect.lr()), lrGpt);
4854 
4855  if ( isChipMode() && m_ivt.valid() ) // Chipping in image space.)
4856  {
4857  scale = thumbSize / maxRectDimension;
4858  if ( m_ivt->getScale().hasNans() )
4859  {
4860  m_ivt->scale( scale, scale );
4861  }
4862  else
4863  {
4864  m_ivt->scale( m_ivt->getScale().x*scale,m_ivt->getScale().y*scale );
4865  }
4866  }
4867  else
4868  {
4869  scale = maxRectDimension / thumbSize;
4870 
4871  //---
4872  // Adjust the projection scale. Note the "true" is to recenter
4873  // the tie point so it falls relative to the projection origin.
4874  //
4875  // This call also scales: ossimImageGeometry::m_imageSize
4876  //---
4877  m_geom->applyScale(ossimDpt(scale, scale), true);
4878  }
4879  tw *= scale;
4880  th *= scale;
4881  if(tw < 1) tw = 1;
4882  if(th < 1) th = 1;
4883  // Must call to reset the ossimImageRenderer's bounding rect for each input.
4885 
4886  // Get the new upper left in view space.
4887  ossimDpt dpt;
4888  m_geom->worldToLocal(ulGpt, dpt);
4889  ossimIpt ul(dpt);
4890 
4891  // Get the new lower right in view space.
4892  m_geom->worldToLocal(lrGpt, dpt);
4893  ossimIpt lr(dpt);
4894 
4895  //---
4896  // Clamp to thumbnail bounds with padding if turned on.
4897  // Padding is optional. If padding turned on alway make square.
4898  //---
4899  ossim_int32 ts = thumbSize;
4900  bool pad = padThumbnail();
4901  if(pad)
4902  {
4903  lr.x = ul.x + ts - 1;
4904  lr.y = ul.y + ts - 1;
4905  }
4906  else // let it vary
4907  {
4908  lr.x = ul.x + tw - 1;
4909  lr.y = ul.y + th - 1;
4910  }
4911 
4912  adjustedRect = ossimIrect(ul, lr);
4913  }
4914  }
4915 
4916  } // if ( !originalRect.hasNans() && m_geom.valid() )
4917  else
4918  {
4919  // Should never happer...
4920  std::string errMsg = MODULE;
4921  if ( originalRect.hasNans() )
4922  {
4923  errMsg += " passed in rect has nans!";
4924  }
4925  else
4926  {
4927  errMsg += " output projection null!";
4928  }
4929  throw( ossimException(errMsg) );
4930  }
4931 
4932  if ( traceDebug() )
4933  {
4934  ossimNotify(ossimNotifyLevel_DEBUG) << "\nadjusted rect: " << adjustedRect << "\n";
4935  if (m_geom.valid())
4936  {
4938  }
4939  ossimNotify(ossimNotifyLevel_DEBUG) << MODULE << " exited...\n";
4940  }
4941 }
4942 
4944 {
4945  bool result = false;
4946  if ( m_kwl.valid() )
4947  {
4948  result = m_kwl->hasKey( std::string(ossimKeywordNames::BANDS_KW) );
4949  }
4950  return result;
4951 }
4952 
4954 {
4955  bool result = false;
4956 
4957  if(m_kwl.valid())
4958  {
4959  result = (m_kwl->hasKey( CUT_HEIGHT_KW )&&
4960  m_kwl->hasKey( CUT_WIDTH_KW ) &&
4961  (m_kwl->hasKey( CUT_WMS_BBOX_KW )||
4962  m_kwl->hasKey(CUT_WMS_BBOX_LL_KW)));
4963  }
4964 
4965  return result;
4966 }
4967 
4969 {
4970  bool result = false;
4971  if ( m_kwl.valid() )
4972  {
4973  if ( m_kwl->hasKey( CUT_HEIGHT_KW ) )
4974  {
4975  if ( m_kwl->hasKey( CUT_WIDTH_KW ) )
4976  {
4977  if ( m_kwl->hasKey( CUT_MIN_LAT_KW ) )
4978  {
4979  if ( m_kwl->hasKey( CUT_MIN_LON_KW ) )
4980  {
4981  if ( m_kwl->hasKey( CUT_MAX_LAT_KW ) )
4982  {
4983  if ( m_kwl->hasKey( CUT_MAX_LON_KW ) )
4984  {
4985  result = true;
4986  }
4987  }
4988  }
4989  } // if lat and lon WMS style bbox is specified then we will behave the same as above
4990  else if( m_kwl->hasKey(CUT_WMS_BBOX_LL_KW))
4991  {
4992  result = true;
4993  }
4994  }
4995  }
4996  }
4997  return result;
4998 }
4999 
5001 {
5002  bool result = false;
5003  if ( m_kwl.valid() )
5004  {
5005  if ( m_kwl->hasKey( METERS_KW.c_str() ) ||
5006  m_kwl->hasKey( DEGREES_X_KW.c_str() ) ||
5009  {
5010  result = true;
5011  }
5012  }
5013  return result;
5014 }
5015 
5017 {
5018  return keyIsTrue( THREE_BAND_OUT_KW );
5019 }
5020 
5022 {
5023  return keyIsTrue( PAD_THUMBNAIL_KW );
5024 }
5025 
5027 {
5028  if ( ih && m_kwl.valid() )
5029  {
5030  ossim_uint32 count = m_kwl->numberOf( READER_PROPERTY_KW.c_str() );
5031  for (ossim_uint32 i = 0; i < count; ++i)
5032  {
5033  ossimString key = READER_PROPERTY_KW;
5034  key += ossimString::toString(i);
5035  ossimString value = m_kwl->findKey( key.string() );
5036  if ( value.size() )
5037  {
5038  std::vector<ossimString> splitArray;
5039  value.split(splitArray, "=");
5040  if(splitArray.size() == 2)
5041  {
5043  new ossimStringProperty(splitArray[0], splitArray[1]);
5044 
5045  ih->setProperty( prop );
5046  }
5047  }
5048  }
5049  }
5050 }
5051 
5052 void ossimChipperUtil::getBandList( std::vector<ossim_uint32>& bandList ) const
5053 {
5054  bandList.clear();
5055  if ( m_kwl.valid() )
5056  {
5057  ossimString os;
5058  os.string() = m_kwl->findKey( std::string( ossimKeywordNames::BANDS_KW ) );
5059  if ( os.size() &&(os!="default"))
5060  {
5061  std::vector<ossimString> band_list(0);
5062  os.split( band_list, ossimString(","), false );
5063  if ( band_list.size() )
5064  {
5065  std::vector<ossimString>::const_iterator i = band_list.begin();
5066  while ( i != band_list.end() )
5067  {
5068  ossim_uint32 band = (*i).toUInt32();
5069  if ( band ) // One based so we need to subtract.
5070  {
5071  bandList.push_back( band - 1 );
5072  }
5073  ++i;
5074  }
5075  }
5076  }
5077  }
5078 
5079 } // End: ossimChipperUtil::getBandList
5080 
5082 {
5083  bool result = false;
5084  if ( m_kwl.valid() )
5085  {
5086  ossimString regularExpression = "annotation[0-9]*\\.type";
5087  ossim_uint32 count = m_kwl->getNumberOfKeysThatMatch( regularExpression );
5088  if ( count > 0 )
5089  {
5090  result = true;
5091  }
5092  }
5093  return result;
5094 }
5095 
5097 {
5098  bool result = false;
5099  if ( m_kwl.valid() )
5100  {
5101  result = ( m_kwl->find( LUT_FILE_KW.c_str() ) != 0 );
5102  }
5103  return result;
5104 }
5105 
5107 {
5108  bool result = false;
5109  std::string value = m_kwl->findKey( BRIGHTNESS_KW );
5110  if ( value.size() )
5111  {
5112  result = true;
5113  }
5114  else
5115  {
5116  value = m_kwl->findKey( CONTRAST_KW );
5117  if ( value.size() )
5118  {
5119  result = true;
5120  }
5121  }
5122  return result;
5123 }
5124 
5126 {
5127  bool result = (m_kwl->find(CLIP_WMS_BBOX_LL_KW.c_str())||
5128  m_kwl->find(CLIP_POLY_LAT_LON_KW.c_str()));
5129 
5130  return result;
5131 }
5132 
5134 {
5135  bool result = ( m_operation == OSSIM_CHIPPER_OP_HILL_SHADE );
5136  if ( !result && m_kwl.valid() )
5137  {
5139  m_kwl->find( COLOR_RED_KW.c_str() ) ||
5140  m_kwl->find( COLOR_GREEN_KW.c_str() ) ||
5141  m_kwl->find( COLOR_BLUE_KW.c_str() ) ||
5143  m_kwl->find( GAIN_KW.c_str() ) );
5144  }
5145  return result;
5146 }
5147 
5149 {
5150  bool result = false;
5151  if ( m_kwl.valid() )
5152  {
5153  result = ( m_kwl->find( THUMBNAIL_RESOLUTION_KW.c_str() ) != 0 );
5154  }
5155  return result;
5156 }
5157 
5159 {
5160  bool result = false;
5161  if ( m_kwl.valid() )
5162  {
5163  result = m_kwl->hasKey( HIST_OP_KW );
5164  }
5165  return result;
5166 }
5167 
5169 {
5170  bool result = false;
5171  ossimString ext = file.ext();
5172  if ( ext.size() >= 2 )
5173  {
5174  ext.downcase();
5175  if ( ( ext == "hgt" ) || ( ext == "dem" ) ||
5176  ( ( (*ext.begin()) == 'd' ) && ( (*(ext.begin()+1)) == 't' ) ) )
5177  {
5178  result = true;
5179  }
5180  }
5181  return result;
5182 }
5183 
5185 {
5186  bool result = false;
5187  ossimString ext = file.ext();
5188  ext.downcase();
5189  if ( ext == "src" )
5190  {
5191  result = true;
5192  }
5193  return result;
5194 }
5195 
5197 {
5199  ossimString lookup = m_kwl->findKey( OUTPUT_RADIOMETRY_KW );
5200  if ( lookup.size() )
5201  {
5203  }
5204  if ( scalar == OSSIM_SCALAR_UNKNOWN )
5205  {
5206  // deprecated keyword...
5207  if ( keyIsTrue( std::string(SCALE_2_8_BIT_KW) ) )
5208  {
5209  scalar = OSSIM_UINT8;
5210  }
5211  }
5212  return scalar;
5213 }
5214 
5216 {
5217  bool result = false;
5218  if ( getOutputScalarType() == OSSIM_UINT8 )
5219  {
5220  result = true;
5221  }
5222  return result;
5223 }
5224 
5226 {
5227  return keyIsTrue( SNAP_TIE_TO_ORIGIN_KW );
5228 }
5229 
5230 void ossimChipperUtil::getImageSpaceScale( ossimDpt& imageSpaceScale ) const
5231 {
5232  imageSpaceScale.x = 1.0;
5233  imageSpaceScale.y = 1.0;
5234  ossimString lookup;
5235 
5236  if (m_kwl->hasKey(FULLRES_XYS_KW))
5237  {
5238  lookup = m_kwl->findKey(FULLRES_XYS_KW);
5239  std::vector<ossimString> values;
5240  lookup.trim().split(values, ",");
5241  if (values.size() > 2)
5242  {
5243  imageSpaceScale.x = values[2].toDouble();
5244  imageSpaceScale.y = imageSpaceScale.x;
5245  if (values.size() > 3)
5246  {
5247  imageSpaceScale.y = values[3].toDouble();
5248  }
5249  }
5250  }
5251  else
5252  {
5253  std::string value = m_kwl->findKey(IMAGE_SPACE_SCALE_X_KW);
5254  if (value.size())
5255  {
5256  imageSpaceScale.x = ossimString(value).toFloat64();
5257  }
5258  else
5259  {
5260  imageSpaceScale.x = 1.0;
5261  }
5262  value = m_kwl->findKey(IMAGE_SPACE_SCALE_Y_KW);
5263  if (value.size())
5264  {
5265  imageSpaceScale.y = ossimString(value).toFloat64();
5266  }
5267  else
5268  {
5269  imageSpaceScale.y = 1.0;
5270  }
5271  }
5272 }
5273 
5275 {
5276  ossimString lookup;
5277  imageSpacePivot.makeNan();
5278  if (m_kwl->hasKey(FULLRES_XYS_KW))
5279  {
5280  lookup = m_kwl->findKey(FULLRES_XYS_KW);
5281  std::vector<ossimString> values;
5282  lookup.trim().split(values, ",");
5283 
5284  if(values.size() > 1)
5285  {
5286  imageSpacePivot.x = values[0].toDouble();
5287  imageSpacePivot.y = values[1].toDouble();
5288  }
5289  }
5290  else
5291  {
5292  if (m_geom)
5293  {
5294  ossimDrect rect;
5295  m_geom->getBoundingRect(rect);
5296  imageSpacePivot = rect.midPoint();
5297  }
5298  }
5299 }
5300 
5302 {
5303  ossim_float64 result = ossim::nan();
5304  if ( m_kwl.valid() )
5305  {
5306  std::string value = m_kwl->findKey( ROTATION_KW);
5307  if ( value.size() )
5308  {
5309  result = ossimString(value).toFloat64();
5310  if ( result < 0 )
5311  {
5312  result += 360.0;
5313  }
5314 
5315  // Range check:
5316  if ( ( result < 0.0 ) || ( result > 360.0 ) )
5317  {
5318  std::ostringstream errMsg;
5319  errMsg << "ossimChipperUtil::getRotation range error!\n"
5320  << "rotation = " << result
5321  << "\nMust be between 0 and 360.";
5322  throw ossimException( errMsg.str() );
5323  }
5324  }
5325  }
5326  return result;
5327 }
5328 
5330 {
5331  return keyIsTrue( std::string(UP_IS_UP_KW) );
5332 }
5333 
5335 {
5336  bool result = false;
5337  std::string value = m_kwl->findKey(std::string(ROTATION_KW));
5338  if ( value.size() )
5339  {
5340  result = true;
5341  }
5342  return result;
5343 }
5344 
5346 {
5347  return keyIsTrue( std::string(NORTH_UP_KW) );
5348 }
5349 
5351 {
5352  return (m_operation == OSSIM_CHIPPER_OP_CHIP);
5353 }
5354 
5355 bool ossimChipperUtil::keyIsTrue( const std::string& key ) const
5356 {
5357  bool result = false;
5358  if ( m_kwl.valid() )
5359  {
5360  std::string value = m_kwl->findKey( key );
5361  if ( value.size() )
5362  {
5363  result = ossimString(value).toBool();
5364  }
5365  }
5366  return result;
5367 }
5368 
5370 {
5371  ossim_uint32 result = 0;
5372  if ( m_kwl.valid() )
5373  {
5374  std::string value = m_kwl->findKey( std::string( ossimKeywordNames::ENTRY_KW ) );
5375  if ( value.size() )
5376  {
5377  result = ossimString(value).toUInt32();
5378  }
5379  }
5380  return result;
5381 }
5382 
5384 {
5385  ossim_int32 result = 0;
5386  if ( m_kwl.valid() )
5387  {
5388  std::string value = m_kwl->findKey( std::string( ossimKeywordNames::ZONE_KW ) );
5389  if ( value.size() )
5390  {
5391  result = ossimString(value).toUInt32();
5392  }
5393  }
5394  return result;
5395 }
5396 
5397 
5399 {
5400  std::string result;
5401  if ( m_kwl.valid() )
5402  {
5403  result = m_kwl->findKey( std::string( ossimKeywordNames::HEMISPHERE_KW ) );
5404  }
5405  return result;
5406 }
5407 
5409 {
5410  bool result = false;
5411 
5412  // Test image layers.
5413  std::vector< ossimRefPtr<ossimSingleImageChain> >::iterator chainIdx = m_imgLayer.begin();
5414  while ( chainIdx != m_imgLayer.end() )
5415  {
5416  // Get the image handler:
5417  ossimRefPtr<ossimImageHandler> ih = (*chainIdx)->getImageHandler();
5418  if ( ih.valid() )
5419  {
5420  // Get the geometry from the first image handler.
5422  if ( geom.valid() )
5423  {
5424  // Get the image projection.
5426  if ( proj.valid() )
5427  {
5428  // Cast and assign to result.
5429  ossimMapProjection* mapProj = PTR_CAST( ossimMapProjection, proj.get() );
5430  if ( !mapProj )
5431  {
5432  result = true;
5433  break;
5434  }
5435  }
5436  }
5437  }
5438  ++chainIdx;
5439  }
5440 
5441  if ( !result )
5442  {
5443  // Test dem layers.
5444  chainIdx = m_demLayer.begin();
5445  while ( chainIdx != m_demLayer.end() )
5446  {
5447  // Get the image handler:
5448  ossimRefPtr<ossimImageHandler> ih = (*chainIdx)->getImageHandler();
5449  if ( ih.valid() )
5450  {
5451  // Get the geometry from the first image handler.
5453  if ( geom.valid() )
5454  {
5455  // Get the image projection.
5457  if ( proj.valid() )
5458  {
5459  // Cast and assign to result.
5460  ossimMapProjection* mapProj = PTR_CAST( ossimMapProjection, proj.get() );
5461  if ( !mapProj )
5462  {
5463  result = true;
5464  break;
5465  }
5466  }
5467  }
5468  }
5469  ++chainIdx;
5470  }
5471  }
5472 
5473  return result;
5474 }
5475 
5477 {
5478  static const char MODULE[] = "ossimChipperUtil::initializeSrcKwl";
5479  if ( traceDebug() )
5480  {
5482  << MODULE << " entered...\n";
5483  }
5484 
5485  std::string value = m_kwl->findKey(std::string(SRC_FILE_KW));
5486  if ( value.size() )
5487  {
5488  m_srcKwl = new ossimKeywordlist();
5490  if ( m_srcKwl->addFile( value.c_str() ) == false )
5491  {
5492  m_srcKwl = 0;
5493  }
5494  }
5495  else
5496  {
5497  m_srcKwl = 0;
5498  }
5499 
5500  if ( traceDebug() )
5501  {
5502  if ( m_srcKwl.valid() )
5503  {
5505  << "src keyword list:\n" << *(m_srcKwl.get()) << "\n";
5506  }
5508  << MODULE << " exited...\n";
5509  }
5510 }
5511 
5513 {
5514  ossim_uint32 result = 0;
5515 
5516  ossimString demRegExpr = "dem[0-9]*\\.file";
5517  ossimString imgRegExpr = "image[0-9]*\\.file";
5518 
5519  if ( m_kwl.valid() )
5520  {
5521  // Look for dems, e.g. dem0.file: foo.tif
5522  result = m_kwl->getNumberOfKeysThatMatch( demRegExpr );
5523 
5524  // Look for images, e.g. image0.file: foo.tif
5525  result += m_kwl->getNumberOfKeysThatMatch( imgRegExpr );
5526  }
5527 
5528  if ( m_srcKwl.valid() )
5529  {
5530  // Look for dems, e.g. dem0.file: foo.tif
5531  result += m_srcKwl->getNumberOfKeysThatMatch( demRegExpr );
5532 
5533  // Look for images, e.g. image0.file: foo.tif
5534  result += m_srcKwl->getNumberOfKeysThatMatch( imgRegExpr );
5535  }
5536 
5537  return result;
5538 }
5539 
5541 {
5543  const char* op = m_kwl->find(ossimKeywordNames::PROJECTION_KW);
5544  if ( op )
5545  {
5546  ossimString os = op;
5547  os.downcase();
5548  if (os == "geo")
5549  {
5551  }
5552  else if (os == "geo-scaled")
5553  {
5555  }
5556  else if ( os == "input" )
5557  {
5559  }
5560  else if ( (os == "utm") || (os == "ossimutmprojection") )
5561  {
5563  }
5564  }
5565  return result;
5566 }
5567 
5569 {
5570  ossimString param = m_kwl->find(CLIP_WMS_BBOX_LL_KW.c_str());
5571  if(!param.empty())
5572  {
5573  if(!polygon.addWmsBbox(param))
5574  {
5575  polygon.clear();
5576  }
5577  }
5578  else
5579  {
5580  param = m_kwl->find(CLIP_POLY_LAT_LON_KW.c_str());
5581  if(!param.empty())
5582  {
5583  std::vector<ossimGpt> points;
5584  ossim::toVector(points, param);
5585  if(!points.empty())
5586  {
5587  polygon = points;
5588  }
5589  }
5590  }
5591 }
5592 
5594 {
5595  ossim_float64 brightness = 0.0;
5596  std::string value = m_kwl->findKey( BRIGHTNESS_KW );
5597  if ( value.size() )
5598  {
5599  brightness = ossimString(value).toFloat64();
5600 
5601  // Range check it:
5602  if ( ( brightness < -1.0 ) || ( brightness > 1.0 ) )
5603  {
5605  << "ossimChipperUtil::getBrightness range error!"
5606  << "\nbrightness: " << brightness
5607  << "\nvalid range: -1.0 to 1.0"
5608  << "\nReturned brightness has been reset to: 0.0"
5609  << std::endl;
5610 
5611  brightness = 0.0;
5612  }
5613  }
5614  return brightness;
5615 
5616 }
5617 
5619 {
5620  ossim_float64 contrast = 1.0;
5621  std::string value = m_kwl->findKey( CONTRAST_KW );
5622  if ( value.size() )
5623  {
5624  contrast = ossimString(value).toFloat64();
5625 
5626  // Range check it:
5627  if ( ( contrast < 0.0 ) || ( contrast > 20.0 ) )
5628  {
5630  << "ossimChipperUtil::getContrast range error!"
5631  << "\ncontrast: " << contrast
5632  << "\nvalid range: 0 to 20.0"
5633  << "\nReturned contrast has been reset to: 1.0"
5634  << std::endl;
5635 
5636  contrast = 1.0;
5637  }
5638  }
5639  return contrast;
5640 
5641 }
5642 
5644 {
5645  ossimString mode = m_kwl->findKey( SHARPEN_MODE_KW );
5646  if ( mode.size() )
5647  {
5648  mode.downcase();
5649  if ( (mode != "light") && (mode != "heavy") && (mode != "none") )
5650  {
5652  << "ossimChipperUtil::getSharpnessMode WARNING!"
5653  << "\nInvalid sharpness mode: " << mode
5654  << "\nValid modes: \"light\" and \"heavy\""
5655  << std::endl;
5656  mode = "";
5657  }
5658  if(mode=="none") mode = "";
5659  }
5660  return mode.string();
5661 }
5662 
5664 {
5666 
5667  ossimString op = m_kwl->findKey( HIST_OP_KW );
5668  op.downcase();
5669 
5670  if ( ( op.string() == "auto-minmax" ) )
5671  {
5673  }
5674  else if ( ( op.string() == "auto-percentile" ) )
5675  {
5677  }
5678  else if ( (op == "std-stretch-1") || (op == "std-stretch 1") )
5679  {
5681  }
5682  else if ( (op == "std-stretch-2") || (op == "std-stretch 2") )
5683  {
5685  }
5686  else if ( (op == "std-stretch-3") || (op == "std-stretch 3") )
5687  {
5689  }
5690  else if( traceDebug() )
5691  {
5693  << "ossimChipperUtil::getHistoMode: Unhandled operation: " << op << "\n";
5694  }
5695 
5696  return result;
5697 }
5698 
5700 {
5701  // Add global usage options.
5703 
5704  // Set app name.
5705  std::string appName = ap.getApplicationName();
5707 
5708  // Add options.
5709  addArguments(ap);
5710 
5711  // Write usage.
5713 
5714  // Keeping single line in tact for examples for cut and paste purposes.
5716 
5717  << "NOTES:\n"
5718  << "1) Never use same base name in the same directory! Example is you have a Chicago.tif\n"
5719  << " and you want a Chicago.jp2, output Chicago.jp2 to its own directory.\n"
5720 
5721  << "\nExample commands:\n"
5722 
5723  << "\n// File conversion: Convert geotiff to a jp2 file.\n"
5724  << appName << " --op chip -w ossim_kakadu_jp2 Chicago.tif outputs/Chicago.jp2\n"
5725 
5726  << "\n// Orthorectification: Orthorectify a nitf with RPC model out to a geotiff.\n"
5727  << appName << " --op ortho 5V090205P0001912264B220000100282M_001508507.ntf outputs/ortho.tif\n"
5728 
5729  << "\n// Mosaic: Mosaic multiple images together and output to a geotiff.\n"
5730  << appName << " --combiner-type ossimImageMosaic --op ortho f1.tif f2.tif f3.tif outputs/mosaic.tif\n"
5731 
5732  << "\n// Mosaic: Feather Mosaic multiple images together and output to a geotiff.\n"
5733  << appName << " --combiner-type ossimFeatherMosaic --op ortho f1.tif f2.tif f3.tif outputs/feather.tif\n"
5734 
5735  << "\n// Color relief: Colorize two DEMs from a lut, output to a geotiff.\n"
5736  << appName << " --op color-relief --color-table ossim-dem-color-table-template.kwl N37W123.hgt N38W123.hgt outputs/color-relief.tif\n"
5737 
5738  << "\n// Color relief: Colorize two DEMs from a lut, output to a png thumbnail.\n"
5739  << appName << " --op color-relief --color-table ossim-dem-color-table-template.kwl -t 1024 -w ossim_png N37W123.hgt N38W123.hgt outputs/color-relief.png\n"
5740 
5741  << "\n// Hill shade: Hill shade two DEMs, output to a geotiff.\n"
5742  << appName << " --color 255 255 255 --azimuth 270 --elevation 45 --exaggeration 2.0 --op hillshade N37W123.hgt N38W123.hgt outputs/hillshade.tif\n"
5743 
5744  << "\n// Two color multi view with cut box. First image is old, second image is new:\n"
5745  << appName << " --cut-bbox-ll 28.092885092033352 -80.664539599998633 28.109128691071547 -80.626914963229325 --op 2cmv oldMLB.tif newMLB.tif outputs/2cmv-test1.tif\n"
5746 
5747  << "\n// Ortho about point, 512x512, with histogram stretch, and 3,2,1 band order:\n"
5748  << appName << " --op ortho -b 3,2,1 --histogram-op auto-minmax --cut-center-llwh -42.819784401784275 147.265811350983 512 512 5V090205M0001912264B220000100072M_001508507.ntf orth.tif\n"
5749 
5750  << "\n// Chip, in image space, about point, 512x512, with histogram stretch, and 3,2,1 band order:\n"
5751  << appName << " --op chip -b 3,2,1 --histogram-op auto-minmax --cut-center-llwh -42.819784401784275 147.265811350983 512 512 5V090205M0001912264B220000100072M_001508507.ntf chip.tif\n"
5752 
5753  << "\n// Chip in image space, rotate \"up is up\"(-u option) about point, 512x512 with histogram stretch and 3,2,1 band order:\n"
5754  << appName << " --op chip -u -b 3,2,1 --histogram-op auto-minmax --cut-center-llwh -42.819784401784275 147.265811350983 512 512 5V090205M0001912264B220000100072M_001508507.ntf up-is-up-chip.tif\n"
5755 
5756  << "\n// Chip in image space, rotate 39 degrees (-r option) about point, 1024x1024, scaled to eight bit:\n"
5757  << appName << " --op chip -r 39 --histogram-op auto-minmax --cut-center-llwh -42.883809539602893 147.331984112985765 1024 1024 --output-radiometry ossim_uint8 5V090205P0001912264B220000100282M_001508507.ntf outputs/r39.png\n"
5758 
5759  << "\n// Above command where all options are in a keyword list:\n"
5760  << appName << " --options r39-options.kwl\n"
5761  << std::endl;
5762 }
std::string getSharpenMode() const
Gets the sharpen mode.
void setRectangle(const ossimIrect &rect)
ossimRefPtr< ossimImageSource > addIndexToRgbLutFilter(ossimRefPtr< ossimImageSource > &source) const
Creates ossimIndexToRgbLutFilter and connects to source.
bool hasAnnotations() const
Class used for parsing the command line *.src files.
void clear()
Erases the entire container.
Definition: ossimString.h:432
ossimRefPtr< ossimImageSource > initializeChain(ossimIrect &aoi)
Builds image chains returns ref pointer to image source and initializes area of interest(aoi).
void write(std::ostream &output, const UsageMap &um, unsigned int widthOfOutput=80)
virtual void initialize()
void getSceneCenter(ossimGpt &gpt)
Loops through all layers to get the scene center ground point.
void getOutputFilename(ossimFilename &f) const
Gets the output file name.
virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0) const
This will return the bounding rect of the source.
std::string getApplicationName() const
return the application name, as specified by argv[0]
ossimRefPtr< ossimImageSource > addScalarRemapper(ossimRefPtr< ossimImageSource > &source, ossimScalarType scalar) const
Creates ossimScalarRemapper and connects to source.
ossimRefPtr< ossimMapProjection > getMapProjection()
Convenience method to get a pointer to the output map projection.
void addCommandLineOption(const ossimString &option, const ossimString &explanation)
virtual ossimObject * dup() const =0
bool hasGeoPolyCutterOption() const
bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Initializes record from an in-memory KWL and prefix.
void setAddResamplerCacheFlag(bool flag)
If flag is true a resampler cache will be added to the chain at create time.
void propagateOutputProjectionToChains()
loops through all chains and sets the output projection.
static const char * PROJECTION_KW
ossimFilename noExtension() const
void setAddNullPixelFlipFlag(bool flag)
If flag is true a null pixel flip will be added to the chain at create time.
This uses a derivative of Blinn&#39;s bump function to compute a 3-D looking image.
void getMetersPerPixel(ossimDpt &gsd)
Loops through all layers to get the best gsd.
static ossimString upcase(const ossimString &aString)
Definition: ossimString.cpp:34
ossim_uint32 numberOf(const char *str) const
std::basic_ostringstream< char > ostringstream
Class for char output memory streams.
Definition: ossimIosFwd.h:35
T max(T a, T b)
Definition: ossimCommon.h:236
ossimScalarType getScalarTypeFromString(const ossimString &s) const
bool getIrect(const std::string &s, ossimIrect &rect) const
Gets rect from string in the form of <x>,<y>,<w>,<h>.
This is a 2 color view of the input.
static const char * OUTPUT_FILE_KW
ossim_float64 width() const
Definition: ossimDrect.h:522
static const ossimFilename NIL
This was taken from Wx widgets for performing touch and access date stamps.
Definition: ossimFilename.h:40
ossimRefPtr< ossimImageSource > initializeColorReliefChain()
Initializes a color relief chain.
virtual void disconnect(ossimConnectableObject *object=0)
Will disconnect the object passed in.
void getImageSpaceScale(ossimDpt &imageSpaceScale) const
Gets the image space scale.
static const char * CENTRAL_MERIDIAN_KW
ossimRefPtr< const ossimImageSharpenFilter > getSharpenFilter() const
bool setChainEntry(ossimRefPtr< ossimSingleImageChain > &chain, ossim_uint32 entryIndex) const
Sets entry for a chain.
virtual ~ossimChipperUtil()
virtual destructor
Represents serializable keyword/value map.
bool addFile(const char *file)
const std::string & findKey(const std::string &key) const
Find methods that take std::string(s).
bool isLonNan() const
Definition: ossimGpt.h:140
void setOptionsToChain(ossimIrect &aoi, const ossimKeywordlist &kwl)
virtual ossimRefPtr< ossimImageGeometry > getImageGeometry()
Returns the image geometry object associated with this tile source or NULL if not defined...
ossimRefPtr< const ossimImageHandler > getImageHandler() const
static const ossimErrorCode OSSIM_OK
ossim_uint8 toUInt8() const
virtual ossim_uint32 getNumberOfOutputBands() const
Returns the number of bands in a tile returned from this TileSource.
ossimRefPtr< ossimSingleImageChain > createChain(const ossimFilename &file, ossim_uint32 entryIndex, bool isDemSource) const
Creates a ossimSingleImageChain from file.
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=NULL) const
Will save the state of the chain.
bool valid() const
Definition: ossimRefPtr.h:75
void setSharpenFlag(bool flag)
Sets the sharpenflag.
const char * find(const char *key) const
virtual bool addListener(ossimListener *listener)
Overrides base "addListener" this will capture the pointer and then call the base class "addListener"...
ossimRefPtr< ossimImageSource > initializeBumpShadeChain()
Initializes a bump shade chain.
#define MAX(x, y)
void addOptions(ossimArgumentParser &parser)
Definition: ossimInit.cpp:100
const ossimMapProjection * getAsMapProjection() const
ossimReferenced allows for shared object ref counting if the reference count ever gets to 0 or less i...
virtual ossimString getEntryString(ossim_int32 entry_number) const
bool read(const std::string &str)
search for an occurance of a string in the argument list, on sucess remove that occurance from the li...
std::ostream & print(std::ostream &out) const
Prints contents to output stream.
ossimFilename getHistogramFile() const
Returns the currently opened histogram.
double nan()
Method to return ieee floating point double precision NAN.
Definition: ossimCommon.h:135
void addArguments(ossimArgumentParser &ap)
Adds application arguments to the argument parser.
ossimRefPtr< ossimImageFileWriter > m_writer
We need access to the writer so we can support aborting.
void getBoundingRect(ossimIrect &bounding_rect) const
Get the bounding rect of (0, 0) to (imageSize.x-1, imageSize.y-1).
bool computeHistogram(const ossimIrect &roi)
Compute the histogram from input connection and region of interest.
double y
Definition: ossimDpt.h:165
virtual void setOrigin(const ossimGpt &origin)
Sets theOrigin to origin.
void addDemSource(const ossimFilename &file, ossim_uint32 entryIndex)
Method to create a chain and add to dem layers from file.
ossimFilename getFilename() const
ossim_uint32 height() const
Definition: ossimIrect.h:487
bool contains(char aChar) const
Definition: ossimString.h:58
bool hasKey(const std::string &key) const
Checks for key in map.
static ossimImageWriterFactoryRegistry * instance()
void addList(const ossimKeywordlist &src, bool overwrite=true)
Visitor to update view and then propagate property event to outputs.
Definition: ossimVisitor.h:179
void makeNan()
Definition: ossimGpt.h:130
void createRenderedChain()
Create a rendered image chain.
static ossimString toString(bool aValue)
Numeric to string methods.
bool hasBumpShadeArg() const
virtual void setTileSize(const ossimIpt &tileSize)
Sets the output image tiling size if supported by the writer.
virtual bool isGeographic() const
ossimRefPtr< ossimImageSource > initializePsmChain()
Initializes a psm (pan sharpening multispectra) chain.
const ossimIpt & ul() const
Definition: ossimIrect.h:274
void split(std::vector< ossimString > &result, const ossimString &separatorList, bool skipBlankFields=false) const
Splits this string into a vector of strings (fields) using the delimiter list specified.
virtual void setPointSize(const ossimIpt &size)
void addPair(const std::string &key, const std::string &value, bool overwrite=true)
ossim_float64 hgt
Height in meters above the ellipsiod.
Definition: ossimGpt.h:274
virtual ossimString getClassName() const
Definition: ossimObject.cpp:64
virtual void setDecimalDegreesPerPixel(const ossimDpt &gsd)
ossim_uint32 toUInt32() const
virtual ossim_uint32 saveStateOfAllInputs(ossimKeywordlist &kwl, bool saveThisStateFlag=true, ossim_uint32 objectIndex=1, const char *prefix=0) const
Save the state of all inputs to a keyword list.
bool keyIsTrue(const std::string &key) const
void setCommandLineUsage(const ossimString &explanation)
void initializeProjectionGsd()
Initializes the projection gsd.
ossimDpt getDegreesPerPixel() const
Returns the resolution of this image in degrees/pixel.
ossimApplicationUsage * getApplicationUsage()
void getBandList(std::vector< ossim_uint32 > &bandList) const
Gets the band list if BANDS keyword is set.
virtual void setProperty(ossimRefPtr< ossimProperty > property)
This class imlements the fusion algorithm from the paper:
ossim_float64 getRotation() const
Gets rotation.
ossimRefPtr< ossimKeywordlist > m_srcKwl
Hold contents of src file if –src is used.
void setImageSize(const ossimIpt &size)
An image mosaic is a simple combiner that will just do a simple mosaic.
bool hasBrightnesContrastOperation() const
virtual void imageToView(const ossimDpt &imagePoint, ossimDpt &viewPoint) const
virtual bool write(const char *file, const char *comment=0) const
Methods to dump the ossimKeywordlist to a file on disk.
bool isLatNan() const
Definition: ossimGpt.h:139
void setBandIndexMapping(ossim_uint32 oldInputBandIndex, ossim_uint32 newInputBandIndex, ossimTwoColorMultiViewOutputSource redOutputSource, ossimTwoColorMultiViewOutputSource grnOutputSource, ossimTwoColorMultiViewOutputSource bluOutputSource)
Sets which bands to use from inputs, and which inputs to use for output red, green and blue channels...
void setBrightnessContrastFlag(bool flag)
Sets the brightness contrast flag.
void initializeSrcKwl()
Initializes m_srcKwl if option was set.
ossimRefPtr< ossimImageSource > addAnnotations(ossimRefPtr< ossimImageSource > &source) const
Add annotation source to chain.
ossimIpt size() const
Definition: ossimIrect.h:510
bool hasRotation() const
virtual void setUpperLeftPosition(const ossimIpt &position)
void setImageViewTransform(ossimImageViewTransform *transform)
void setBandSelection(const std::vector< ossim_uint32 > &bandList)
method to set band selector.
ossim_uint32 getNumberOfInputs() const
int numberOfParams(const std::string &str, const ossimParameter value) const
ossim_uint32 getNumberOfKeysThatMatch(const ossimString &regularExpression) const
Gets number keys that match regular expression.
Single image chain class.
virtual void setMetersPerPixel(const ossimDpt &gsd)
std::vector< ossimRefPtr< ossimSingleImageChain > > m_imgLayer
Array of image source chains.
virtual void setElevationAngle(double angle)
ossimRefPtr< ossimMapProjection > getFirstInputProjection()
Gets the first input projection.
virtual bool addObject(ossimAnnotationObject *anObject)
ossimConnectableObject * getInput(ossim_uint32 index=0)
returns the object at the specified index.
ossim_int32 toInt32() const
ossim_int32 getZone() const
void clear()
Disconnects and clears the dem and image layers.
void reportRemainingOptionsAsUnrecognized(ossimErrorSeverity severity=OSSIM_BENIGN)
for each remaining option report it as an unrecongnized.
void setStretchMode(StretchMode mode, bool rebuildTableFlag=false)
Sets remap mode to mode.
double ossim_float64
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
void setCutType(ossimRectangleCutType cutType)
static const char * ZONE_KW
void createIdentityProjection()
Sets the single image chain for identity operations view to a ossimImageViewAffineTransform.
ossimChipperUtil()
default constructor
static ossimScalarTypeLut * instance()
Returns the static instance of an ossimScalarTypeLut object.
virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0) const
ossimRefPtr< ossimImageSource > createCombiner() const
ossim_float64 getBrightness() const
Gets the brightness level.
void getImageSpacePivot(ossimDpt &imageSpacePivot) const
Gets the image space pivot.
ossimString replaceAllThatMatch(const char *regularExpressionPattern, const char *value="") const
void setEntryIndex(ossim_int32 i)
double lat
Definition: ossimDpt.h:165
void initializeOutputProjection()
Initializes the output projection and propagates to image chains.
bool errors(ossimErrorSeverity severity=OSSIM_BENIGN) const
virtual void setOutputScalarType(ossimScalarType scalarType)
Sets the output scalar type.
void setFilename(const ossimFilename &f)
bool addWmsBbox(const ossimString &wmsBbox)
OSSIM_DLL void toVector(std::vector< ossimDpt > &result, const ossimString &stringOfPoints)
Will take a string list separated by spaces and convert to a vector of ossimDpts. ...
yy_size_t size
bool exists() const
ossim_float64 lon
Definition: ossimGpt.h:266
void toPoint(const std::string &s)
Initializes this point from string.
Definition: ossimGpt.cpp:116
virtual ossimRefPtr< ossimImageGeometry > getImageGeometry()
Returns the image geometry object associated with this tile source or NULL if non defined...
bool localToWorld(const ossimDpt &local_pt, ossimGpt &world_pt) const
Exposes the 3D projection from image to world coordinates.
virtual void setScale(const ossimDpt &scale)
void initializeIvtScale()
Initializes the image view transform(IVT) scale.
void setLine(const ossimDpt &start, const ossimDpt &end)
std::string::size_type size() const
Definition: ossimString.h:405
ossimIpt midPoint() const
Definition: ossimIrect.h:750
virtual void setString(const ossimString &s)
bool toBool() const
String to numeric methods.
std::string::iterator begin()
Definition: ossimString.h:420
ossimRefPtr< ossimImageSource > combineLayers()
Combines dems(m_demLayer) and images(m_imgLayer).
void setLut(const ossimFilename &file)
Set lookup table(lut) method.
ossim_float64 getCentralMeridian() const
Gets value of key "central_meridan" if set, nan if not.
bool hasThumbnailResolution() const
unsigned int ossim_uint32
ossimDpt getMetersPerPixel() const
Returns the GSD associated with this image in the active projection.
ossimString trim(const ossimString &valueToTrim=ossimString(" \\)) const
this will strip lead and trailing character passed in.
void toPoint(const std::string &s)
Initializes this point from string.
Definition: ossimDpt.cpp:192
void getRgbColorSource(ossim_uint8 &r, ossim_uint8 &g, ossim_uint8 &b) const
Gets the red, green and blue color source values.
bool setupChainHistogram(ossimRefPtr< ossimSingleImageChain > &chain, std::shared_ptr< ossimSrcRecord > srcRecordPtr=0) const
Set up ossimHistogramRemapper for a chain.
void setRgbColorSource(ossim_uint8 r, ossim_uint8 g, ossim_uint8 b)
Set the red, green and blue color source values.
double toDouble() const
ossim_float64 toFloat64() const
#define PTR_CAST(T, p)
Definition: ossimRtti.h:321
ossimChipperOutputProjection
emumerated output projections
virtual void setAzimuthAngle(double angle)
ossim_float64 getContrast() const
Gets the contrast level.
ossimRefPtr< ossimKeywordlist > m_kwl
Hold all options passed into intialize.
void setApplicationName(const ossimString &name)
void getTiePoint(ossimGpt &tie)
Loops through all layers to get the upper left tie point.
ossimChipperOutputProjection getOutputProjectionType() const
Gets the emumerated output projection type.
const ossimIpt & lr() const
Definition: ossimIrect.h:276
static ossimString downcase(const ossimString &aString)
Definition: ossimString.cpp:48
virtual ossimIrect getImageRectangle(ossim_uint32 resLevel=0) const
Returns zero-based bounding rectangle of the image.
ossimRefPtr< ossimMapProjection > getNewGeoProjection()
Convenience method to get geographic projection.
virtual ossim_int32 connectMyInputTo(ossimConnectableObject *inputObject, bool makeOutputConnection=true, bool createEventFlag=true)
Will try to connect this objects input to the passed in object.
Class to draw fonts onto an image.
static const char * AZIMUTH_ANGLE_KW
T min(T a, T b)
Definition: ossimCommon.h:203
ossimChipperUtil class.
ossim_uint32 width() const
Definition: ossimIrect.h:500
static const char * BANDS_KW
bool hasNans() const
Definition: ossimDpt.h:67
double lon
Definition: ossimDpt.h:164
void getAreaOfInterest(ossimImageSource *source, ossimIrect &rect) const
Initializes "rect" with the output area of interest.
void addImgSources()
Creates chains for all images.
ossimRefPtr< ossimImageGeometry > m_geom
The image geometry.
virtual void setEnableFlag(bool flag)
Definition: ossimSource.cpp:99
void toPoint(const std::string &s)
Initializes this point from string.
Definition: ossimIpt.cpp:170
ossim_uint32 size() const
void intiailizeProjectionTiePoint()
Sets the projection tie point to the scene bounding rect corner.
ossimScalarType getOutputScalarType() const
Returns the scalar type from OUTPUT_RADIOMETRY_KW keyword if present.
Container class that holds both 2D transform and 3D projection information for an image Only one inst...
ossimScalarType
void addCrossHairAnnotation(ossimRefPtr< ossimAnnotationSource > annotator, const std::string &prefix) const
Adds cross hair graphic to annotation source.
const ossimGpt & getOrigin() const
void setZone(const ossimGpt &ground)
static ossimProjectionFactoryRegistry * instance()
ossimRefPtr< const ossimHistogramRemapper > getHistogramRemapper() const
ossimRefPtr< ossimImageFileWriter > createNewWriter() const
Creates a new writer.
void setAddHistogramFlag(bool flag)
If flag is true a histogram will be added to the chain at create time.
ossimChipperOperation m_operation
Enumerated operation to perform.
std::string getHemisphere() const
bool hasScaleOption() const
bool isSrcFile(const ossimFilename &file) const
static const char * ORIGIN_LATITUDE_KW
static const char * ENTRY_KW
virtual ossimIrect getBoundingRect(ossim_uint32 resLevel=0) const
Will pass this call to the head of the list.
void applyScale(const ossimDpt &scale, bool recenterTiePoint)
Changes the GSD and image size to reflect the scale provided.
virtual void setFilename(const ossimFilename &file)
ossimRefPtr< ossimImageSource > m_source
We need to support changing clips without doing a full initilization.
void initializeThumbnailProjection(const ossimIrect &originalRect, ossimIrect &adjustedRect)
Method to calculate and initialize scale and area of interest for making a thumbnail.
bool hasWmsBboxCutWidthHeight() const
const ossimProjection * getProjection() const
Access methods for projection (may be NULL pointer).
ossimRefPtr< ossimImageViewAffineTransform > m_ivt
Image view transform(IVT).
virtual ossimImageSource * createImageSource(const ossimString &name) const
void getTiePoint(ossimGpt &tie, bool edge) const
Get the latitude, longitude of the tie point.
virtual ossimScalarType getOutputScalarType() const
This will be used to query the output pixel type of the tile source.
This class defines an abstract Handler which all image handlers(loaders) should derive from...
virtual void setProperty(ossimRefPtr< ossimProperty > property)
virtual ossimErrorCode getErrorStatus() const
bool hasBandSelection() const
ossimDpt midPoint() const
Definition: ossimDrect.h:817
void getSortedList(std::vector< ossimString > &prefixValues, const ossimString &prefixKey) const
This return the sorted keys if you have a list.
void usage(ossimArgumentParser &ap)
Initializes arg parser and outputs usage.
bool hasNans() const
Definition: ossimGpt.h:135
ossim_int32 y
Definition: ossimIpt.h:142
void setDescription(const ossimString &desc)
void makeNan()
Definition: ossimIrect.h:329
void createOutputProjection()
Creates the output or view projection.
void addImgSource(const ossimFilename &file, ossim_uint32 entryIndex)
Method to create a chain and add to img layers from file.
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Method to the load (recreate) the state of an object from a keyword list.
ossim_uint32 getEntryNumber() const
virtual void setAreaOfInterest(const ossimIrect &inputRect)
static const char * HEMISPHERE_KW
double x
Definition: ossimDpt.h:164
void setRemapToEightBitFlag(bool flag)
Sets remap to eigth bit flag.
bool open(const ossimFilename &file, bool openOverview=true)
open method that takes an image file.
const ossimChipperUtil & operator=(const ossimChipperUtil &rhs)
Hidden from use assignment operator.
ossim_uint32 getSize() const
const char * c_str() const
Returns a pointer to a null-terminated array of characters representing the string&#39;s contents...
Definition: ossimString.h:396
bool empty() const
Definition: ossimString.h:411
virtual void eastingNorthingToLineSample(const ossimDpt &eastingNorthing, ossimDpt &lineSample) const
void setReaderProps(ossimImageHandler *ih) const
Passes reader properties to single image handler if any.
bool hasCutBoxWidthHeight() const
ossimRefPtr< ossimImageSource > initialize2CmvChain()
Combines two images into a two color multi view chain.
static ossimInit * instance()
Definition: ossimInit.cpp:89
ossim_float64 upIsUpAngle(const ossimDpt &) const
bool hasNans() const
Definition: ossimIrect.h:337
ossim_float64 getOriginLatitude() const
Gets value of key "origin_latitude" if set, nan if not.
void initialize()
Initial method to be ran prior to execute.
ossimImageFileWriter * createWriter(const ossimFilename &filename) const
virtual void setUlTiePoints(const ossimGpt &gpt)
ossimString ext() const
bool worldToLocal(const ossimGpt &world_pt, ossimDpt &local_pt) const
Exposes the 3D world-to-local image coordinate reverse projection.
bool isThreeBandOut() const
virtual void accept(ossimVisitor &visitor)
We will add a visitor interface for all connectable objects.
ossim_int32 x
Definition: ossimIpt.h:141
ossimRefPtr< ossimMapProjection > getNewGeoScaledProjection()
Convenience method to get geographic projection.
ossim_float64 lat
Definition: ossimGpt.h:265
ossimRefPtr< ossimMapProjection > getNewProjectionFromSrsCode(const std::string &code)
Convenience method to get a projection from an srs code.
ossimRefPtr< const ossimImageRenderer > getImageRenderer() const
ossimRefPtr< ossimImageData > getChip(const ossimKeywordlist &optionsKwl=ossimKeywordlist())
Gets initialized area of interest(aoi) from chain.
virtual void initialize()=0
8 bit unsigned integer
virtual void scale(double x, double y)
ossimString & gsub(const ossimString &searchKey, const ossimString &replacementValue, bool replaceAll=false)
Substitutes searchKey string with replacementValue and returns a reference to *this.
static const char * ELEVATION_ANGLE_KW
void setAreaOfInterest(const ossimIrect &rect)
ossimTwoColorMultiViewOutputSource
Enumerations for mapping inputs to red, green and blue output channels.
void getClipPolygon(ossimGeoPolygon &polygon) const
ossimFilename & setExtension(const ossimString &e)
Sets the extension of a file name.
bool hasHistogramOperation() const
virtual bool removeListener(ossimListener *listener)
Overrides base "removeListener".
virtual bool setCurrentEntry(ossim_uint32 entryIdx)
ossim_float64 northUpAngle() const
bool scaleToEightBit() const
void execute()
execute method.
void addDemSources()
Create chains for all dems.
ossimFilename getFilenameWithThisExtension(const ossimString &ext, bool set_e0_prefix=false) const
Returns the image file with extension set using supplentary directory for dirname if set...
int & argc()
return the argument count.
void setHemisphere(const ossimGpt &ground)
virtual std::ostream & print(std::ostream &out) const
Prints data members to stream.
void setExpandEnvVarsFlag(bool flag)
bool snapTieToOrigin() const
void setThreeBandFlag(bool flag)
Sets the three band flag.
bool padThumbnail() const
virtual void getBoundingRect(ossimDrect &rect) const
unsigned char ossim_uint8
static ossimImageSourceFactoryRegistry * instance()
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
void makeNan()
Definition: ossimDpt.h:65
bool openHistogram(const ossimFilename &histogram_file)
Open the histogram file.
ossimRefPtr< ossimMapProjection > getNewUtmProjection()
Convenience method to get a utm projection.
virtual bool execute()
Calls: writeFile() writeMetaDataFiles()
void addGeoPolyCutterPolygon(const vector< ossimGpt > &polygon)
bool isDemFile(const ossimFilename &file) const
ossimRefPtr< const ossimBrightnessContrastSource > getBrightnessContrast() const
int ossim_int32
void writeErrorMessages(std::ostream &output, ossimErrorSeverity sevrity=OSSIM_BENIGN)
write out error messages at an above specified .
const std::string & string() const
Definition: ossimString.h:414
virtual ossimRefPtr< ossimImageData > getTile(const ossimIpt &origin, ossim_uint32 resLevel=0)
void setAddChainCacheFlag(bool flag)
If flag is true a chain cache will be added to the chain at create time.
std::vector< ossimRefPtr< ossimSingleImageChain > > m_demLayer
Array of dem chains.
bool isnan(const float &v)
isnan Test for floating point Not A Number (NAN) value.
Definition: ossimCommon.h:91
ossim_float64 min< ossim_float64 >(ossim_float64 a, ossim_float64 b)
Definition: ossimCommon.h:223