24 #include "imageclasses/ImgReaderGdal.h"
25 #include "imageclasses/ImgWriterGdal.h"
26 #include "imageclasses/ImgReaderOgr.h"
27 #include "base/Vector2d.h"
28 #include "base/Optionpk.h"
29 #include "algorithms/StatFactory.h"
112 enum CRULE_TYPE {overwrite=0, maxndvi=1, maxband=2, minband=3, validband=4, mean=5, mode=6, median=7,sum=8,minallbands=9,maxallbands=10,stdev=11};
117 int main(
int argc,
char *argv[])
119 Optionpk<string> input_opt(
"i",
"input",
"Input image file(s). If input contains multiple images, a multi-band output is created");
121 Optionpk<int> band_opt(
"b",
"band",
"band index(es) to crop (leave empty if all bands must be retained)");
122 Optionpk<double> dx_opt(
"dx",
"dx",
"Output resolution in x (in meter) (empty: keep original resolution)");
123 Optionpk<double> dy_opt(
"dy",
"dy",
"Output resolution in y (in meter) (empty: keep original resolution)");
124 Optionpk<string> extent_opt(
"e",
"extent",
"get boundary from extent from polygons in vector file");
125 Optionpk<double> ulx_opt(
"ulx",
"ulx",
"Upper left x value bounding box", 0.0);
126 Optionpk<double> uly_opt(
"uly",
"uly",
"Upper left y value bounding box", 0.0);
127 Optionpk<double> lrx_opt(
"lrx",
"lrx",
"Lower right x value bounding box", 0.0);
128 Optionpk<double> lry_opt(
"lry",
"lry",
"Lower right y value bounding box", 0.0);
129 Optionpk<string> crule_opt(
"cr",
"crule",
"Composite rule (overwrite, maxndvi, maxband, minband, mean, mode (only for byte images), median, sum, maxallbands, minallbands, stdev",
"overwrite");
130 Optionpk<int> ruleBand_opt(
"cb",
"cband",
"band index used for the composite rule (e.g., for ndvi, use --cband=0 --cband=1 with 0 and 1 indices for red and nir band respectively", 0);
131 Optionpk<double> srcnodata_opt(
"srcnodata",
"srcnodata",
"invalid value(s) for input raster dataset");
132 Optionpk<int> bndnodata_opt(
"bndnodata",
"bndnodata",
"Band(s) in input image to check if pixel is valid (used for srcnodata, min and max options)", 0);
133 Optionpk<double> minValue_opt(
"min",
"min",
"flag values smaller or equal to this value as invalid.");
134 Optionpk<double> maxValue_opt(
"max",
"max",
"flag values larger or equal to this value as invalid.");
135 Optionpk<double> dstnodata_opt(
"dstnodata",
"dstnodata",
"nodata value to put in output raster dataset if not valid or out of bounds.", 0);
136 Optionpk<string> resample_opt(
"r",
"resampling-method",
"Resampling method (near: nearest neighbor, bilinear: bi-linear interpolation).",
"near");
137 Optionpk<string> otype_opt(
"ot",
"otype",
"Data type for output image ({Byte/Int16/UInt16/UInt32/Int32/Float32/Float64/CInt16/CInt32/CFloat32/CFloat64}). Empty string: inherit type from input image",
"");
138 Optionpk<string> oformat_opt(
"of",
"oformat",
"Output image format (see also gdal_translate). Empty string: inherit from input image");
139 Optionpk<string> option_opt(
"co",
"co",
"Creation option for output file. Multiple options can be specified.");
140 Optionpk<string> projection_opt(
"a_srs",
"a_srs",
"Override the spatial reference for the output file (leave blank to copy from input file, use epsg:3035 to use European projection and force to European grid");
141 Optionpk<short> file_opt(
"file",
"file",
"write number of observations (1) or sequence nr of selected file (2) for each pixels as additional layer in composite", 0);
142 Optionpk<short> weight_opt(
"w",
"weight",
"Weights (type: short) for the composite, use one weight for each input file in same order as input files are provided). Use value 1 for equal weights.", 1);
143 Optionpk<short> class_opt(
"c",
"class",
"classes for multi-band output image: each band represents the number of observations for one specific class. Use value 0 for no multi-band output image.", 0);
144 Optionpk<string> colorTable_opt(
"ct",
"ct",
"color table file with 5 columns: id R G B ALFA (0: transparent, 255: solid)");
145 Optionpk<string> description_opt(
"d",
"description",
"Set image description");
149 weight_opt.setHide(1);
150 class_opt.setHide(1);
151 colorTable_opt.setHide(1);
152 description_opt.setHide(1);
156 doProcess=input_opt.retrieveOption(argc,argv);
157 output_opt.retrieveOption(argc,argv);
158 band_opt.retrieveOption(argc,argv);
159 dx_opt.retrieveOption(argc,argv);
160 dy_opt.retrieveOption(argc,argv);
161 extent_opt.retrieveOption(argc,argv);
162 ulx_opt.retrieveOption(argc,argv);
163 uly_opt.retrieveOption(argc,argv);
164 lrx_opt.retrieveOption(argc,argv);
165 lry_opt.retrieveOption(argc,argv);
166 crule_opt.retrieveOption(argc,argv);
167 ruleBand_opt.retrieveOption(argc,argv);
168 srcnodata_opt.retrieveOption(argc,argv);
169 bndnodata_opt.retrieveOption(argc,argv);
170 minValue_opt.retrieveOption(argc,argv);
171 maxValue_opt.retrieveOption(argc,argv);
172 dstnodata_opt.retrieveOption(argc,argv);
173 resample_opt.retrieveOption(argc,argv);
174 otype_opt.retrieveOption(argc,argv);
175 oformat_opt.retrieveOption(argc,argv);
176 option_opt.retrieveOption(argc,argv);
177 projection_opt.retrieveOption(argc,argv);
178 file_opt.retrieveOption(argc,argv);
179 weight_opt.retrieveOption(argc,argv);
180 class_opt.retrieveOption(argc,argv);
181 colorTable_opt.retrieveOption(argc,argv);
182 description_opt.retrieveOption(argc,argv);
183 verbose_opt.retrieveOption(argc,argv);
185 catch(
string predefinedString){
186 std::cout << predefinedString << std::endl;
191 cout <<
"Usage: pkcomposite -i input [-i input]* -o output" << endl;
193 std::cout <<
"short option -h shows basic options only, use long option --help to show all options" << std::endl;
197 std::map<std::string, crule::CRULE_TYPE> cruleMap;
201 cruleMap[
"overwrite"]=crule::overwrite;
202 cruleMap[
"maxndvi"]=crule::maxndvi;
203 cruleMap[
"maxband"]=crule::maxband;
204 cruleMap[
"minband"]=crule::minband;
205 cruleMap[
"validband"]=crule::validband;
206 cruleMap[
"mean"]=crule::mean;
207 cruleMap[
"mode"]=crule::mode;
208 cruleMap[
"median"]=crule::median;
209 cruleMap[
"sum"]=crule::sum;
210 cruleMap[
"maxallbands"]=crule::maxallbands;
211 cruleMap[
"minallbands"]=crule::minallbands;
212 cruleMap[
"stdev"]=crule::stdev;
214 if(srcnodata_opt.size()){
215 while(srcnodata_opt.size()<bndnodata_opt.size())
216 srcnodata_opt.push_back(srcnodata_opt[0]);
218 while(bndnodata_opt.size()<srcnodata_opt.size())
219 bndnodata_opt.push_back(bndnodata_opt[0]);
220 if(minValue_opt.size()){
221 while(minValue_opt.size()<bndnodata_opt.size())
222 minValue_opt.push_back(minValue_opt[0]);
223 while(bndnodata_opt.size()<minValue_opt.size())
224 bndnodata_opt.push_back(bndnodata_opt[0]);
226 if(maxValue_opt.size()){
227 while(maxValue_opt.size()<bndnodata_opt.size())
228 maxValue_opt.push_back(maxValue_opt[0]);
229 while(bndnodata_opt.size()<maxValue_opt.size())
230 bndnodata_opt.push_back(bndnodata_opt[0]);
232 RESAMPLE theResample;
233 if(resample_opt[0]==
"near"){
236 cout <<
"resampling: nearest neighbor" << endl;
238 else if(resample_opt[0]==
"bilinear"){
239 theResample=BILINEAR;
241 cout <<
"resampling: bilinear interpolation" << endl;
244 std::cout <<
"Error: resampling method " << resample_opt[0] <<
" not supported" << std::endl;
248 if(input_opt.empty()){
249 std::cerr <<
"No input file provided (use option -i). Use --help for help information" << std::endl;
262 double magic_x=1,magic_y=1;
264 GDALDataType theType=GDT_Unknown;
266 cout <<
"possible output data types: ";
267 for(
int iType = 0; iType < GDT_TypeCount; ++iType){
269 cout <<
" " << GDALGetDataTypeName((GDALDataType)iType);
270 if( GDALGetDataTypeName((GDALDataType)iType) != NULL
271 && EQUAL(GDALGetDataTypeName((GDALDataType)iType),
272 otype_opt[0].c_str()))
273 theType=(GDALDataType) iType;
277 if(theType==GDT_Unknown)
278 cout <<
"Unknown output pixel type: " << otype_opt[0] << endl;
280 cout <<
"Output pixel type: " << GDALGetDataTypeName(theType) << endl;
287 if(extent_opt.size()){
288 extentReader.open(extent_opt[0]);
289 if(!(extentReader.getExtent(ulx_opt[0],uly_opt[0],lrx_opt[0],lry_opt[0]))){
290 cerr <<
"Error: could not get extent from " << extent_opt[0] << endl;
293 else if(verbose_opt[0])
294 cout <<
"--ulx=" << ulx_opt[0] <<
" --uly=" << uly_opt[0] <<
" --lrx=" << lrx_opt[0] <<
" --lry=" << lry_opt[0] << endl;
298 string theProjection=
"";
299 GDALColorTable* theColorTable=NULL;
302 for(
int ifile=0;ifile<input_opt.size();++ifile){
304 imgReader.open(input_opt[ifile]);
306 catch(
string errorstring){
307 cerr << errorstring <<
" " << input_opt[ifile] << endl;
309 if(colorTable_opt.empty())
310 if(imgReader.getColorTable())
311 theColorTable=(imgReader.getColorTable()->Clone());
312 if(projection_opt.empty())
313 theProjection=imgReader.getProjection();
314 if(option_opt.findSubstring(
"INTERLEAVE=")==option_opt.end()){
315 string theInterleave=
"INTERLEAVE=";
316 theInterleave+=imgReader.getInterleave();
317 option_opt.push_back(theInterleave);
320 if((ulx_opt[0]||uly_opt[0]||lrx_opt[0]||lry_opt[0])&&(!imgReader.covers(ulx_opt[0],uly_opt[0],lrx_opt[0],lry_opt[0]))){
322 cout << input_opt[ifile] <<
" not within bounding box, skipping..." << endl;
326 double theULX, theULY, theLRX, theLRY;
327 imgReader.getBoundingBox(theULX,theULY,theLRX,theLRY);
329 cerr <<
"Error: " << input_opt[ifile] <<
" is not georeferenced, only referenced images are supported for pkcomposite " << endl;
333 cout <<
"Bounding Box (ULX ULY LRX LRY): " << fixed << setprecision(6) << theULX <<
" " << theULY <<
" " << theLRX <<
" " << theLRY << endl;
336 switch(cruleMap[crule_opt[0]]){
338 case(crule::overwrite):
339 cout <<
"Composite rule: overwrite" << endl;
341 case(crule::maxndvi):
342 cout <<
"Composite rule: max ndvi" << endl;
344 case(crule::maxband):
345 cout <<
"Composite rule: max band" << endl;
347 case(crule::minband):
348 cout <<
"Composite rule: min band" << endl;
350 case(crule::validband):
351 cout <<
"Composite rule: valid band" << endl;
354 cout <<
"Composite rule: mean value" << endl;
357 cout <<
"Composite rule: max voting (only for byte images)" << endl;
360 cout <<
"Composite rule: median" << endl;
363 cout <<
"Composite rule: stdev" << endl;
366 cout <<
"Composite rule: sum" << endl;
368 case(crule::minallbands):
369 cout <<
"Composite rule: minallbands" << endl;
371 case(crule::maxallbands):
372 cout <<
"Composite rule: maxallbands" << endl;
377 nband=band_opt.size();
378 bands.resize(band_opt.size());
379 for(
int iband=0;iband<band_opt.size();++iband){
380 bands[iband]=band_opt[iband];
381 assert(bands[iband]<imgReader.nrOfBand());
385 nband=imgReader.nrOfBand();
387 for(
int iband=0;iband<nband;++iband)
390 for(
int iband=0;iband<bndnodata_opt.size();++iband){
391 assert(bndnodata_opt[iband]>=0&&bndnodata_opt[iband]<nband);
394 if(theType==GDT_Unknown){
395 theType=imgReader.getDataType();
397 cout <<
"Using data type from input image: " << GDALGetDataTypeName(theType) << endl;
400 if(oformat_opt.size())
401 imageType=oformat_opt[0];
403 imageType=imgReader.getImageType();
407 cout <<
"type of data for " << input_opt[ifile] <<
": " << theType << endl;
408 cout <<
"nband: " << nband << endl;
418 dx=imgReader.getDeltaX();
422 dy=imgReader.getDeltaY();
436 maxLRX=(theLRX>maxLRX)?theLRX:maxLRX;
437 maxULY=(theULY>maxULY)?theULY:maxULY;
438 minULX=(theULX<minULX)?theULX:minULX;
439 minLRY=(theLRY<minLRY)?theLRY:minLRY;
444 cout <<
"bounding box input images (ULX ULY LRX LRY): " << fixed << setprecision(6) << minULX <<
" " << maxULY <<
" " << maxLRX <<
" " << minLRY << endl;
445 if(ulx_opt[0]||uly_opt[0]||lrx_opt[0]||lry_opt[0]){
452 bool forceEUgrid=
false;
453 if(projection_opt.size())
454 forceEUgrid=(!(projection_opt[0].compare(
"EPSG:3035"))||!(projection_opt[0].compare(
"EPSG:3035"))||projection_opt[0].find(
"ETRS-LAEA")!=string::npos);
457 minULX=floor(minULX);
458 minULX-=
static_cast<int>(minULX)%(static_cast<int>(dx));
460 if(static_cast<int>(maxULY)%static_cast<int>(dy))
462 maxULY-=
static_cast<int>(maxULY)%(static_cast<int>(dy));
464 if(static_cast<int>(maxLRX)%static_cast<int>(dx))
466 maxLRX-=
static_cast<int>(maxLRX)%(static_cast<int>(dx));
467 minLRY=floor(minLRY);
468 minLRY-=
static_cast<int>(minLRY)%(static_cast<int>(dy));
472 cout <<
"bounding box composite image (ULX ULY LRX LRY): " << fixed << setprecision(6) << minULX <<
" " << maxULY <<
" " << maxLRX <<
" " << minLRY << endl;
475 cout <<
"initializing composite image..." << endl;
481 int ncol=ceil((maxLRX-minULX)/dx);
482 int nrow=ceil((maxULY-minLRY)/dy);
485 cout <<
"composite image dim (nrow x ncol): " << nrow <<
" x " << ncol << endl;
487 while(weight_opt.size()<input_opt.size())
488 weight_opt.push_back(weight_opt[0]);
490 std::cout << weight_opt << std::endl;
492 if(cruleMap[crule_opt[0]]==crule::mode){
493 nwriteBand=(file_opt[0])? class_opt.size()+1:class_opt.size();
496 nwriteBand=(file_opt[0])? bands.size()+1:bands.size();
497 if(output_opt.empty()){
498 std::cerr <<
"No output file provided (use option -o). Use --help for help information" << std::endl;
502 cout <<
"open output image " << output_opt[0] <<
" with " << nwriteBand <<
" bands" << endl << flush;
504 imgWriter.open(output_opt[0],ncol,nrow,nwriteBand,theType,imageType,option_opt);
505 for(
int iband=0;iband<nwriteBand;++iband)
506 imgWriter.GDALSetNoDataValue(dstnodata_opt[0],iband);
509 cout << error << endl;
511 if(description_opt.size())
512 imgWriter.setImageDescription(description_opt[0]);
520 imgWriter.setGeoTransform(gt);
522 if(projection_opt.size()){
524 cout <<
"projection: " << projection_opt[0] << endl;
525 imgWriter.setProjectionProj4(projection_opt[0]);
527 else if(theProjection!=
""){
529 cout <<
"projection: " << theProjection << endl;
530 imgWriter.setProjection(theProjection);
532 if(imgWriter.getDataType()==GDT_Byte){
533 if(colorTable_opt.size()){
534 if(colorTable_opt[0]!=
"none")
535 imgWriter.setColorTable(colorTable_opt[0]);
537 else if(theColorTable)
538 imgWriter.setColorTable(theColorTable);
542 cout <<
"creating composite image" << endl;
544 vector<short> fileBuffer(ncol);
548 if(cruleMap[crule_opt[0]]==crule::maxndvi)
549 assert(ruleBand_opt.size()==2);
550 if(cruleMap[crule_opt[0]]==crule::mode){
551 maxBuffer.resize(imgWriter.nrOfCol(),256);
552 for(
int iclass=0;iclass<class_opt.size();++iclass)
553 assert(class_opt[iclass]<maxBuffer.size());
560 const char* pszMessage;
561 void* pProgressArg=NULL;
562 GDALProgressFunc pfnProgress=GDALTermProgress;
564 pfnProgress(progress,pszMessage,pProgressArg);
565 for(
int irow=0;irow<imgWriter.nrOfRow();++irow){
567 vector<bool> writeValid(ncol);
569 if(cruleMap[crule_opt[0]]==crule::mean ||
570 cruleMap[crule_opt[0]]==crule::median ||
571 cruleMap[crule_opt[0]]==crule::sum ||
572 cruleMap[crule_opt[0]]==crule::minallbands ||
573 cruleMap[crule_opt[0]]==crule::maxallbands ||
574 cruleMap[crule_opt[0]]==crule::stdev)
575 storeBuffer.resize(nband,ncol);
576 for(
int icol=0;icol<imgWriter.nrOfCol();++icol){
577 writeValid[icol]=
false;
579 if(cruleMap[crule_opt[0]]==crule::mode){
580 for(
int iclass=0;iclass<256;++iclass)
581 maxBuffer[icol][iclass]=0;
584 for(
int iband=0;iband<nband;++iband)
585 writeBuffer[iband][icol]=dstnodata_opt[0];
588 for(
int ifile=0;ifile<input_opt.size();++ifile){
590 imgReader.open(input_opt[ifile]);
593 cout << error << endl;
596 assert(imgReader.nrOfBand()>=nband);
597 if(!imgReader.covers(minULX,maxULY,maxLRX,minLRY)){
601 double uli,ulj,lri,lrj;
602 imgReader.geo2image(minULX+(magic_x-1.0)*imgReader.getDeltaX(),maxULY-(magic_y-1.0)*imgReader.getDeltaY(),uli,ulj);
603 imgReader.geo2image(maxLRX+(magic_x-2.0)*imgReader.getDeltaX(),minLRY-(magic_y-2.0)*imgReader.getDeltaY(),lri,lrj);
613 else if(uli>=imgReader.nrOfCol())
614 startCol=imgReader.nrOfCol()-1;
617 else if(lri>=imgReader.nrOfCol())
618 endCol=imgReader.nrOfCol()-1;
619 int readncol=endCol-startCol+1;
624 imgWriter.image2geo(0,irow,x,y);
626 imgReader.geo2image(x,y,readCol,readRow);
627 if(readRow<0||readRow>=imgReader.nrOfRow()){
632 for(
int iband=0;iband<nband;++iband){
633 int readBand=(band_opt.size()>iband)? band_opt[iband] : iband;
634 readBuffer[iband].resize(readncol);
636 imgReader.readData(readBuffer[iband],GDT_Float64,startCol,endCol,readRow,readBand,theResample);
639 cerr <<
"error reading image " << input_opt[ifile] <<
": " << endl;
644 for(
int ib=0;ib<ncol;++ib){
645 assert(imgWriter.image2geo(ib,irow,x,y));
647 imgReader.geo2image(x,y,readCol,readRow);
648 if(readCol<0||readCol>=imgReader.nrOfCol())
650 double val_current=0;
655 lowerCol=readCol-0.5;
656 lowerCol=
static_cast<int>(lowerCol);
657 upperCol=readCol+0.5;
658 upperCol=
static_cast<int>(upperCol);
661 if(upperCol>=imgReader.nrOfCol())
662 upperCol=imgReader.nrOfCol()-1;
663 for(
int vband=0;vband<bndnodata_opt.size();++vband){
664 val_new=(readCol-0.5-lowerCol)*readBuffer[bndnodata_opt[vband]][upperCol-startCol]+(1-readCol+0.5+lowerCol)*readBuffer[bndnodata_opt[vband]][lowerCol-startCol];
665 if(minValue_opt.size()>vband){
666 if(val_new<=minValue_opt[vband]){
671 if(maxValue_opt.size()>vband){
672 if(val_new>=maxValue_opt[vband]){
677 if(srcnodata_opt.size()>vband){
678 if(val_new==srcnodata_opt[vband]){
686 readCol=
static_cast<int>(readCol);
687 for(
int vband=0;vband<bndnodata_opt.size();++vband){
688 val_new=readBuffer[bndnodata_opt[vband]][readCol-startCol];
689 if(minValue_opt.size()>vband){
690 if(val_new<=minValue_opt[vband]){
695 if(maxValue_opt.size()>vband){
696 if(val_new>=maxValue_opt[vband]){
701 if(srcnodata_opt.size()>vband){
702 if(val_new==srcnodata_opt[vband]){
715 switch(cruleMap[crule_opt[0]]){
716 case(crule::maxndvi):{
717 double red_current=writeBuffer[ruleBand_opt[0]][ib];
718 double nir_current=writeBuffer[ruleBand_opt[1]][ib];
719 double ndvi_current=0;
720 if(red_current+nir_current>0&&red_current>=0&&nir_current>=0)
721 ndvi_current=(nir_current-red_current)/(nir_current+red_current);
727 lowerCol=readCol-0.5;
728 lowerCol=
static_cast<int>(lowerCol);
729 upperCol=readCol+0.5;
730 upperCol=
static_cast<int>(upperCol);
733 if(upperCol>=imgReader.nrOfCol())
734 upperCol=imgReader.nrOfCol()-1;
735 red_new=(readCol-0.5-lowerCol)*readBuffer[ruleBand_opt[0]][upperCol-startCol]+(1-readCol+0.5+lowerCol)*readBuffer[ruleBand_opt[0]][lowerCol-startCol];
736 nir_new=(readCol-0.5-lowerCol)*readBuffer[ruleBand_opt[1]][upperCol-startCol]+(1-readCol+0.5+lowerCol)*readBuffer[ruleBand_opt[1]][lowerCol-startCol];
737 if(red_new+nir_new>0&&red_new>=0&&nir_new>=0)
738 ndvi_new=(nir_new-red_new)/(nir_new+red_new);
739 if(ndvi_new>=ndvi_current){
740 for(iband=0;iband<nband;++iband){
741 val_new=(readCol-0.5-lowerCol)*readBuffer[iband][upperCol-startCol]+(1-readCol+0.5+lowerCol)*readBuffer[iband][lowerCol-startCol];
742 writeBuffer[iband][ib]=val_new;
745 fileBuffer[ib]=ifile;
749 readCol=
static_cast<int>(readCol);
750 red_new=readBuffer[ruleBand_opt[0]][readCol-startCol];
751 nir_new=readBuffer[ruleBand_opt[1]][readCol-startCol];
752 if(red_new+nir_new>0&&red_new>=0&&nir_new>=0)
753 ndvi_new=(nir_new-red_new)/(nir_new+red_new);
754 if(ndvi_new>=ndvi_current){
755 for(iband=0;iband<nband;++iband){
756 val_new=readBuffer[iband][readCol-startCol];
757 writeBuffer[iband][ib]=val_new;
760 fileBuffer[ib]=ifile;
766 case(crule::maxband):
767 case(crule::minband):
768 case(crule::validband):
769 val_current=writeBuffer[ruleBand_opt[0]][ib];
772 lowerCol=readCol-0.5;
773 lowerCol=
static_cast<int>(lowerCol);
774 upperCol=readCol+0.5;
775 upperCol=
static_cast<int>(upperCol);
778 if(upperCol>=imgReader.nrOfCol())
779 upperCol=imgReader.nrOfCol()-1;
780 val_new=(readCol-0.5-lowerCol)*readBuffer[ruleBand_opt[0]][upperCol-startCol]+(1-readCol+0.5+lowerCol)*readBuffer[ruleBand_opt[0]][lowerCol-startCol];
781 val_new*=weight_opt[ifile];
782 if((cruleMap[crule_opt[0]]==crule::maxband&&val_new>val_current)||(cruleMap[crule_opt[0]]==crule::minband&&val_new<val_current)||(cruleMap[crule_opt[0]]==crule::validband)){
783 for(iband=0;iband<nband;++iband){
784 val_new=(readCol-0.5-lowerCol)*readBuffer[iband][upperCol-startCol]+(1-readCol+0.5+lowerCol)*readBuffer[iband][lowerCol-startCol];
785 val_new*=weight_opt[ifile];
786 writeBuffer[iband][ib]=val_new;
789 fileBuffer[ib]=ifile;
793 readCol=
static_cast<int>(readCol);
794 val_new=readBuffer[ruleBand_opt[0]][readCol-startCol];
795 val_new*=weight_opt[ifile];
796 if((cruleMap[crule_opt[0]]==crule::maxband&&val_new>val_current)||(cruleMap[crule_opt[0]]==crule::minband&&val_new<val_current)||(cruleMap[crule_opt[0]]==crule::validband)){
797 for(iband=0;iband<nband;++iband){
798 val_new=readBuffer[iband][readCol-startCol];
799 val_new*=weight_opt[ifile];
800 writeBuffer[iband][ib]=val_new;
803 fileBuffer[ib]=ifile;
811 lowerCol=readCol-0.5;
812 lowerCol=
static_cast<int>(lowerCol);
813 upperCol=readCol+0.5;
814 upperCol=
static_cast<int>(upperCol);
817 if(upperCol>=imgReader.nrOfCol())
818 upperCol=imgReader.nrOfCol()-1;
819 for(iband=0;iband<nband;++iband){
820 val_new=(readCol-0.5-lowerCol)*readBuffer[iband][upperCol-startCol]+(1-readCol+0.5+lowerCol)*readBuffer[iband][lowerCol-startCol];
821 maxBuffer[ib][val_new]=maxBuffer[ib][val_new]+weight_opt[ifile];
826 readCol=
static_cast<int>(readCol);
827 for(iband=0;iband<nband;++iband){
828 val_new=readBuffer[iband][readCol-startCol];
829 maxBuffer[ib][val_new]=maxBuffer[ib][val_new]+weight_opt[ifile];
837 case(crule::minallbands):
838 case(crule::maxallbands):
842 lowerCol=readCol-0.5;
843 lowerCol=
static_cast<int>(lowerCol);
844 upperCol=readCol+0.5;
845 upperCol=
static_cast<int>(upperCol);
848 if(upperCol>=imgReader.nrOfCol())
849 upperCol=imgReader.nrOfCol()-1;
850 for(iband=0;iband<nband;++iband){
851 val_new=(readCol-0.5-lowerCol)*readBuffer[iband][upperCol-startCol]+(1-readCol+0.5+lowerCol)*readBuffer[iband][lowerCol-startCol];
852 val_new*=weight_opt[ifile];
853 storeBuffer[iband][ib].push_back(val_new);
857 readCol=
static_cast<int>(readCol);
858 for(iband=0;iband<nband;++iband){
859 val_new=readBuffer[iband][readCol-startCol];
860 val_new*=weight_opt[ifile];
861 storeBuffer[iband][ib].push_back(val_new);
869 fileBuffer[ib]=ifile;
871 case(crule::overwrite):
875 lowerCol=readCol-0.5;
876 lowerCol=
static_cast<int>(lowerCol);
877 upperCol=readCol+0.5;
878 upperCol=
static_cast<int>(upperCol);
881 if(upperCol>=imgReader.nrOfCol())
882 upperCol=imgReader.nrOfCol()-1;
883 for(iband=0;iband<nband;++iband){
884 val_new=(readCol-0.5-lowerCol)*readBuffer[iband][upperCol-startCol]+(1-readCol+0.5+lowerCol)*readBuffer[iband][lowerCol-startCol];
885 val_new*=weight_opt[ifile];
886 writeBuffer[iband][ib]=val_new;
890 readCol=
static_cast<int>(readCol);
891 for(iband=0;iband<nband;++iband){
892 val_new=readBuffer[iband][readCol-startCol];
893 val_new*=weight_opt[ifile];
894 writeBuffer[iband][ib]=val_new;
899 fileBuffer[ib]=ifile;
906 switch(cruleMap[crule_opt[0]]){
910 case(crule::minallbands):
911 case(crule::maxallbands):
915 lowerCol=readCol-0.5;
916 lowerCol=
static_cast<int>(lowerCol);
917 upperCol=readCol+0.5;
918 upperCol=
static_cast<int>(upperCol);
921 if(upperCol>=imgReader.nrOfCol())
922 upperCol=imgReader.nrOfCol()-1;
923 for(iband=0;iband<nband;++iband){
924 val_new=(readCol-0.5-lowerCol)*readBuffer[iband][upperCol-startCol]+(1-readCol+0.5+lowerCol)*readBuffer[iband][lowerCol-startCol];
925 val_new*=weight_opt[ifile];
926 storeBuffer[iband][ib].push_back(val_new);
930 readCol=
static_cast<int>(readCol);
931 for(iband=0;iband<nband;++iband){
932 val_new=readBuffer[iband][readCol-startCol];
933 val_new*=weight_opt[ifile];
934 storeBuffer[iband][ib].push_back(val_new);
939 fileBuffer[ib]=ifile;
944 lowerCol=readCol-0.5;
945 lowerCol=
static_cast<int>(lowerCol);
946 upperCol=readCol+0.5;
947 upperCol=
static_cast<int>(upperCol);
950 if(upperCol>=imgReader.nrOfCol())
951 upperCol=imgReader.nrOfCol()-1;
952 for(iband=0;iband<nband;++iband){
953 val_new=(readCol-0.5-lowerCol)*readBuffer[iband][upperCol-startCol]+(1-readCol+0.5+lowerCol)*readBuffer[iband][lowerCol-startCol];
954 maxBuffer[ib][val_new]=maxBuffer[ib][val_new]+weight_opt[ifile];
959 readCol=
static_cast<int>(readCol);
960 for(iband=0;iband<nband;++iband){
961 val_new=readBuffer[iband][readCol-startCol];
962 maxBuffer[ib][val_new]=maxBuffer[ib][val_new]+weight_opt[ifile];
971 lowerCol=readCol-0.5;
972 lowerCol=
static_cast<int>(lowerCol);
973 upperCol=readCol+0.5;
974 upperCol=
static_cast<int>(upperCol);
977 if(upperCol>=imgReader.nrOfCol())
978 upperCol=imgReader.nrOfCol()-1;
979 for(iband=0;iband<nband;++iband){
980 val_new=(readCol-0.5-lowerCol)*readBuffer[iband][upperCol-startCol]+(1-readCol+0.5+lowerCol)*readBuffer[iband][lowerCol-startCol];
981 val_new*=weight_opt[ifile];
982 writeBuffer[iband][ib]=val_new;
986 readCol=
static_cast<int>(readCol);
987 for(iband=0;iband<nband;++iband){
988 val_new=readBuffer[iband][readCol-startCol];
989 val_new*=weight_opt[ifile];
990 writeBuffer[iband][ib]=val_new;
995 fileBuffer[ib]=ifile;
1003 if(cruleMap[crule_opt[0]]==crule::mode){
1004 vector<short> classBuffer(imgWriter.nrOfCol());
1005 if(class_opt.size()>1){
1006 for(
int iclass=0;iclass<class_opt.size();++iclass){
1007 for(
int icol=0;icol<imgWriter.nrOfCol();++icol)
1008 classBuffer[icol]=maxBuffer[icol][class_opt[iclass]];
1010 imgWriter.writeData(classBuffer,GDT_Int16,irow,iclass);
1012 catch(
string error){
1013 cerr <<
"error writing image file " << output_opt[0] <<
": " << error << endl;
1019 for(
int icol=0;icol<imgWriter.nrOfCol();++icol){
1020 vector<short>::iterator maxit=maxBuffer[icol].begin();
1021 maxit=stat.mymax(maxBuffer[icol],maxBuffer[icol].begin(),maxBuffer[icol].end());
1022 writeBuffer[0][icol]=distance(maxBuffer[icol].begin(),maxit);
1024 fileBuffer[icol]=*(maxit);
1027 imgWriter.writeData(writeBuffer[0],GDT_Float64,irow,0);
1029 imgWriter.writeData(fileBuffer,GDT_Int16,irow,1);
1031 catch(
string error){
1032 cerr <<
"error writing image file " << output_opt[0] <<
": " << error << endl;
1038 for(
int iband=0;iband<bands.size();++iband){
1040 assert(writeBuffer[iband].size()==imgWriter.nrOfCol());
1041 for(
int icol=0;icol<imgWriter.nrOfCol();++icol){
1043 switch(cruleMap[crule_opt[0]]){
1046 writeBuffer[iband][icol]=stat.mean(storeBuffer[iband][icol]);
1048 case(crule::median):
1050 writeBuffer[iband][icol]=stat.median(storeBuffer[iband][icol]);
1054 writeBuffer[iband][icol]=stat.sum(storeBuffer[iband][icol]);
1056 case(crule::minallbands):
1058 writeBuffer[iband][icol]=stat.mymin(storeBuffer[iband][icol]);
1060 case(crule::maxallbands):
1062 writeBuffer[iband][icol]=stat.mymax(storeBuffer[iband][icol]);
1066 writeBuffer[iband][icol]=sqrt(stat.var(storeBuffer[iband][icol]));
1072 catch(
string error){
1074 cerr << error << endl;
1075 writeBuffer[iband][icol]=dstnodata_opt[0];
1080 imgWriter.writeData(writeBuffer[iband],GDT_Float64,irow,iband);
1082 catch(
string error){
1083 cerr << error <<
" in " << output_opt[0] << endl;
1089 imgWriter.writeData(fileBuffer,GDT_Int16,irow,bands.size());
1091 catch(
string error){
1092 cerr << error <<
" in " << output_opt[0] << endl;
1097 progress=
static_cast<float>(irow+1.0)/imgWriter.nrOfRow();
1098 pfnProgress(progress,pszMessage,pProgressArg);