25 #include "imageclasses/ImgReaderGdal.h" 26 #include "imageclasses/ImgWriterGdal.h" 27 #include "imageclasses/ImgReaderOgr.h" 28 #include "base/Vector2d.h" 29 #include "base/Optionpk.h" 30 #include "algorithms/StatFactory.h" 140 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};
145 int main(
int argc,
char *argv[])
147 Optionpk<string> input_opt(
"i",
"input",
"Input image file(s). If input contains multiple images, a multi-band output is created");
149 Optionpk<int> band_opt(
"b",
"band",
"band index(es) to crop (leave empty if all bands must be retained)");
150 Optionpk<double> dx_opt(
"dx",
"dx",
"Output resolution in x (in meter) (empty: keep original resolution)");
151 Optionpk<double> dy_opt(
"dy",
"dy",
"Output resolution in y (in meter) (empty: keep original resolution)");
152 Optionpk<string> extent_opt(
"e",
"extent",
"get boundary from extent from polygons in vector file");
153 Optionpk<bool> cut_opt(
"cut",
"crop_to_cutline",
"Crop the extent of the target dataset to the extent of the cutline.",
false);
154 Optionpk<string> eoption_opt(
"eo",
"eo",
"special extent options controlling rasterization: ATTRIBUTE|CHUNKYSIZE|ALL_TOUCHED|BURN_VALUE_FROM|MERGE_ALG, e.g., -eo ATTRIBUTE=fieldname");
155 Optionpk<string> mask_opt(
"m",
"mask",
"Use the first band of the specified file as a validity mask (0 is nodata).");
156 Optionpk<float> msknodata_opt(
"msknodata",
"msknodata",
"Mask value not to consider for composite.", 0);
157 Optionpk<short> mskband_opt(
"mskband",
"mskband",
"Mask band to read (0 indexed)", 0);
158 Optionpk<double> ulx_opt(
"ulx",
"ulx",
"Upper left x value bounding box", 0.0);
159 Optionpk<double> uly_opt(
"uly",
"uly",
"Upper left y value bounding box", 0.0);
160 Optionpk<double> lrx_opt(
"lrx",
"lrx",
"Lower right x value bounding box", 0.0);
161 Optionpk<double> lry_opt(
"lry",
"lry",
"Lower right y value bounding box", 0.0);
162 Optionpk<string> crule_opt(
"cr",
"crule",
"Composite rule (overwrite, maxndvi, maxband, minband, mean, mode (only for byte images), median, sum, maxallbands, minallbands, stdev",
"overwrite");
163 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);
164 Optionpk<double> srcnodata_opt(
"srcnodata",
"srcnodata",
"invalid value(s) for input raster dataset");
165 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);
166 Optionpk<double> minValue_opt(
"min",
"min",
"flag values smaller or equal to this value as invalid.");
167 Optionpk<double> maxValue_opt(
"max",
"max",
"flag values larger or equal to this value as invalid.");
168 Optionpk<double> dstnodata_opt(
"dstnodata",
"dstnodata",
"nodata value to put in output raster dataset if not valid or out of bounds.", 0);
169 Optionpk<string> resample_opt(
"r",
"resampling-method",
"Resampling method (near: nearest neighbor, bilinear: bi-linear interpolation).",
"near");
170 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",
"");
171 Optionpk<string> oformat_opt(
"of",
"oformat",
"Output image format (see also gdal_translate).",
"GTiff");
172 Optionpk<string> option_opt(
"co",
"co",
"Creation option for output file. Multiple options can be specified.");
173 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");
174 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);
175 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);
176 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);
177 Optionpk<string> colorTable_opt(
"ct",
"ct",
"color table file with 5 columns: id R G B ALFA (0: transparent, 255: solid)");
178 Optionpk<string> description_opt(
"d",
"description",
"Set image description");
179 Optionpk<bool> align_opt(
"align",
"align",
"Align output bounding box to input image",
false);
181 Optionpk<double> offset_opt(
"offset",
"offset",
"output=scale*input+offset");
184 extent_opt.setHide(1);
186 eoption_opt.setHide(1);
188 msknodata_opt.setHide(1);
189 mskband_opt.setHide(1);
190 option_opt.setHide(1);
192 weight_opt.setHide(1);
193 class_opt.setHide(1);
194 colorTable_opt.setHide(1);
195 description_opt.setHide(1);
196 scale_opt.setHide(1);
197 offset_opt.setHide(1);
201 doProcess=input_opt.retrieveOption(argc,argv);
202 output_opt.retrieveOption(argc,argv);
203 band_opt.retrieveOption(argc,argv);
204 dx_opt.retrieveOption(argc,argv);
205 dy_opt.retrieveOption(argc,argv);
206 extent_opt.retrieveOption(argc,argv);
207 cut_opt.retrieveOption(argc,argv);
208 eoption_opt.retrieveOption(argc,argv);
209 mask_opt.retrieveOption(argc,argv);
210 msknodata_opt.retrieveOption(argc,argv);
211 mskband_opt.retrieveOption(argc,argv);
212 ulx_opt.retrieveOption(argc,argv);
213 uly_opt.retrieveOption(argc,argv);
214 lrx_opt.retrieveOption(argc,argv);
215 lry_opt.retrieveOption(argc,argv);
216 crule_opt.retrieveOption(argc,argv);
217 ruleBand_opt.retrieveOption(argc,argv);
218 srcnodata_opt.retrieveOption(argc,argv);
219 bndnodata_opt.retrieveOption(argc,argv);
220 minValue_opt.retrieveOption(argc,argv);
221 maxValue_opt.retrieveOption(argc,argv);
222 dstnodata_opt.retrieveOption(argc,argv);
223 resample_opt.retrieveOption(argc,argv);
224 otype_opt.retrieveOption(argc,argv);
225 oformat_opt.retrieveOption(argc,argv);
226 option_opt.retrieveOption(argc,argv);
227 projection_opt.retrieveOption(argc,argv);
228 file_opt.retrieveOption(argc,argv);
229 weight_opt.retrieveOption(argc,argv);
230 class_opt.retrieveOption(argc,argv);
231 colorTable_opt.retrieveOption(argc,argv);
232 description_opt.retrieveOption(argc,argv);
233 align_opt.retrieveOption(argc,argv);
234 scale_opt.retrieveOption(argc,argv);
235 offset_opt.retrieveOption(argc,argv);
236 verbose_opt.retrieveOption(argc,argv);
238 catch(
string predefinedString){
239 std::cout << predefinedString << std::endl;
244 cout <<
"Usage: pkcomposite -i input [-i input]* -o output" << endl;
246 std::cout <<
"short option -h shows basic options only, use long option --help to show all options" << std::endl;
250 std::map<std::string, crule::CRULE_TYPE> cruleMap;
254 cruleMap[
"overwrite"]=crule::overwrite;
255 cruleMap[
"maxndvi"]=crule::maxndvi;
256 cruleMap[
"maxband"]=crule::maxband;
257 cruleMap[
"minband"]=crule::minband;
258 cruleMap[
"validband"]=crule::validband;
259 cruleMap[
"mean"]=crule::mean;
260 cruleMap[
"mode"]=crule::mode;
261 cruleMap[
"median"]=crule::median;
262 cruleMap[
"sum"]=crule::sum;
263 cruleMap[
"maxallbands"]=crule::maxallbands;
264 cruleMap[
"minallbands"]=crule::minallbands;
265 cruleMap[
"stdev"]=crule::stdev;
267 if(srcnodata_opt.size()){
268 while(srcnodata_opt.size()<bndnodata_opt.size())
269 srcnodata_opt.push_back(srcnodata_opt[0]);
271 while(bndnodata_opt.size()<srcnodata_opt.size())
272 bndnodata_opt.push_back(bndnodata_opt[0]);
273 if(minValue_opt.size()){
274 while(minValue_opt.size()<bndnodata_opt.size())
275 minValue_opt.push_back(minValue_opt[0]);
276 while(bndnodata_opt.size()<minValue_opt.size())
277 bndnodata_opt.push_back(bndnodata_opt[0]);
279 if(maxValue_opt.size()){
280 while(maxValue_opt.size()<bndnodata_opt.size())
281 maxValue_opt.push_back(maxValue_opt[0]);
282 while(bndnodata_opt.size()<maxValue_opt.size())
283 bndnodata_opt.push_back(bndnodata_opt[0]);
286 RESAMPLE theResample;
287 if(resample_opt[0]==
"near"){
290 cout <<
"resampling: nearest neighbor" << endl;
292 else if(resample_opt[0]==
"bilinear"){
293 theResample=BILINEAR;
295 cout <<
"resampling: bilinear interpolation" << endl;
298 std::cout <<
"Error: resampling method " << resample_opt[0] <<
" not supported" << std::endl;
302 if(input_opt.empty()){
303 std::cerr <<
"No input file provided (use option -i). Use --help for help information" << std::endl;
312 double maxLRX=lrx_opt[0];
313 double maxULY=uly_opt[0];
314 double minULX=ulx_opt[0];
315 double minLRY=lry_opt[0];
316 double magic_x=1,magic_y=1;
318 GDALDataType theType=GDT_Unknown;
320 cout <<
"possible output data types: ";
321 for(
int iType = 0; iType < GDT_TypeCount; ++iType){
323 cout <<
" " << GDALGetDataTypeName((GDALDataType)iType);
324 if( GDALGetDataTypeName((GDALDataType)iType) != NULL
325 && EQUAL(GDALGetDataTypeName((GDALDataType)iType),
326 otype_opt[0].c_str()))
327 theType=(GDALDataType) iType;
331 if(theType==GDT_Unknown)
332 cout <<
"Unknown output pixel type: " << otype_opt[0] << endl;
334 cout <<
"Output pixel type: " << GDALGetDataTypeName(theType) << endl;
341 if(extent_opt.size()){
346 for(
int iextent=0;iextent<extent_opt.size();++iextent){
347 extentReader.open(extent_opt[iextent]);
348 if(!(extentReader.getExtent(e_ulx,e_uly,e_lrx,e_lry))){
349 cerr <<
"Error: could not get extent from " << extent_opt[0] << endl;
368 extentReader.close();
370 if(maxLRX>minULX&&minULX>ulx_opt[0])
372 if(maxLRX>minULX&&maxLRX<lrx_opt[0])
374 if(maxULY>minLRY&&maxULY<uly_opt[0])
376 if(minLRY<maxULY&&minLRY>lry_opt[0])
378 if(cut_opt.size()||eoption_opt.size())
379 extentReader.open(extent_opt[0]);
383 cout <<
"--ulx=" << ulx_opt[0] <<
" --uly=" << uly_opt[0] <<
" --lrx=" << lrx_opt[0] <<
" --lry=" << lry_opt[0] << endl;
385 vector<ImgReaderGdal> imgReader(input_opt.size());
387 string theProjection=
"";
388 GDALColorTable* theColorTable=NULL;
391 for(
int ifile=0;ifile<input_opt.size();++ifile){
393 imgReader[ifile].open(input_opt[ifile],GA_ReadOnly);
395 for(
int iband=0;iband<scale_opt.size();++iband)
396 imgReader[ifile].setScale(scale_opt[iband],iband);
397 for(
int iband=0;iband<offset_opt.size();++iband)
398 imgReader[ifile].setOffset(offset_opt[iband],iband);
400 catch(
string errorstring){
401 cerr << errorstring <<
" " << input_opt[ifile] << endl;
404 if(colorTable_opt.empty())
405 if(imgReader[ifile].getColorTable())
406 theColorTable=(imgReader[ifile].getColorTable()->Clone());
407 if(projection_opt.empty())
408 theProjection=imgReader[ifile].getProjection();
409 if(option_opt.findSubstring(
"INTERLEAVE=")==option_opt.end()){
410 string theInterleave=
"INTERLEAVE=";
411 theInterleave+=imgReader[ifile].getInterleave();
412 option_opt.push_back(theInterleave);
415 if((ulx_opt[0]||uly_opt[0]||lrx_opt[0]||lry_opt[0])&&(!imgReader[ifile].covers(ulx_opt[0],uly_opt[0],lrx_opt[0],lry_opt[0]))){
417 cout << input_opt[ifile] <<
" not within bounding box, skipping..." << endl;
420 double theULX, theULY, theLRX, theLRY;
421 imgReader[ifile].getBoundingBox(theULX,theULY,theLRX,theLRY);
423 cerr <<
"Error: " << input_opt[ifile] <<
" is not georeferenced, only referenced images are supported for pkcomposite " << endl;
427 cout <<
"Bounding Box (ULX ULY LRX LRY): " << fixed << setprecision(6) << theULX <<
" " << theULY <<
" " << theLRX <<
" " << theLRY << endl;
430 switch(cruleMap[crule_opt[0]]){
432 case(crule::overwrite):
433 cout <<
"Composite rule: overwrite" << endl;
435 case(crule::maxndvi):
436 cout <<
"Composite rule: max ndvi" << endl;
438 case(crule::maxband):
439 cout <<
"Composite rule: max band" << endl;
441 case(crule::minband):
442 cout <<
"Composite rule: min band" << endl;
444 case(crule::validband):
445 cout <<
"Composite rule: valid band" << endl;
448 cout <<
"Composite rule: mean value" << endl;
451 cout <<
"Composite rule: max voting (only for byte images)" << endl;
454 cout <<
"Composite rule: median" << endl;
457 cout <<
"Composite rule: stdev" << endl;
460 cout <<
"Composite rule: sum" << endl;
462 case(crule::minallbands):
463 cout <<
"Composite rule: minallbands" << endl;
465 case(crule::maxallbands):
466 cout <<
"Composite rule: maxallbands" << endl;
471 nband=band_opt.size();
472 bands.resize(band_opt.size());
473 for(
int iband=0;iband<band_opt.size();++iband){
474 bands[iband]=band_opt[iband];
475 assert(bands[iband]<imgReader[ifile].nrOfBand());
479 nband=imgReader[ifile].nrOfBand();
481 for(
int iband=0;iband<nband;++iband)
484 for(
int iband=0;iband<bndnodata_opt.size();++iband){
485 assert(bndnodata_opt[iband]>=0&&bndnodata_opt[iband]<nband);
488 if(theType==GDT_Unknown){
489 theType=imgReader[ifile].getDataType();
491 cout <<
"Using data type from input image: " << GDALGetDataTypeName(theType) << endl;
494 if(oformat_opt.size())
495 imageType=oformat_opt[0];
497 imageType=imgReader[ifile].getImageType();
500 cout <<
"type of data for " << input_opt[ifile] <<
": " << theType << endl;
501 cout <<
"nband: " << nband << endl;
511 dx=imgReader[ifile].getDeltaX();
515 dy=imgReader[ifile].getDeltaY();
519 maxLRX=(theLRX>maxLRX)?theLRX:maxLRX;
520 maxULY=(theULY>maxULY)?theULY:maxULY;
521 minULX=(theULX<minULX)?theULX:minULX;
522 minLRY=(theLRY<minLRY)?theLRY:minLRY;
527 cout <<
"bounding box input images (ULX ULY LRX LRY): " << fixed << setprecision(6) << minULX <<
" " << maxULY <<
" " << maxLRX <<
" " << minLRY << endl;
528 if(ulx_opt[0]||uly_opt[0]||lrx_opt[0]||lry_opt[0]){
535 bool forceEUgrid=
false;
536 if(projection_opt.size())
537 forceEUgrid=(!(projection_opt[0].compare(
"EPSG:3035"))||!(projection_opt[0].compare(
"EPSG:3035"))||projection_opt[0].find(
"ETRS-LAEA")!=string::npos);
540 minULX=floor(minULX);
541 minULX-=
static_cast<int>(minULX)%(static_cast<int>(dx));
543 if(static_cast<int>(maxULY)%static_cast<int>(dy))
545 maxULY-=
static_cast<int>(maxULY)%(static_cast<int>(dy));
547 if(static_cast<int>(maxLRX)%static_cast<int>(dx))
549 maxLRX-=
static_cast<int>(maxLRX)%(static_cast<int>(dx));
550 minLRY=floor(minLRY);
551 minLRY-=
static_cast<int>(minLRY)%(static_cast<int>(dy));
553 else if(align_opt[0]){
554 if(minULX>imgReader[0].getUlx())
555 minULX-=fmod(minULX-imgReader[0].getUlx(),dx);
556 else if(minULX<imgReader[0].getUlx())
557 minULX+=fmod(imgReader[0].getUlx()-minULX,dx)-dx;
558 if(maxLRX<imgReader[0].getLrx())
559 maxLRX+=fmod(imgReader[0].getLrx()-maxLRX,dx);
560 else if(maxLRX>imgReader[0].getLrx())
561 maxLRX-=fmod(maxLRX-imgReader[0].getLrx(),dx)+dx;
562 if(minLRY>imgReader[0].getLry())
563 minLRY-=fmod(minLRY-imgReader[0].getLry(),dy);
564 else if(minLRY<imgReader[0].getLry())
565 minLRY+=fmod(imgReader[0].getLry()-minLRY,dy)-dy;
566 if(maxULY<imgReader[0].getUly())
567 maxULY+=fmod(imgReader[0].getUly()-maxULY,dy);
568 else if(maxULY>imgReader[0].getUly())
569 maxULY-=fmod(maxULY-imgReader[0].getUly(),dy)+dy;
573 cout <<
"bounding box composite image (ULX ULY LRX LRY): " << fixed << setprecision(6) << minULX <<
" " << maxULY <<
" " << maxLRX <<
" " << minLRY << endl;
576 cout <<
"initializing composite image..." << endl;
582 int ncol=abs(static_cast<int>(ceil((maxLRX-minULX)/dx)));
583 int nrow=abs(static_cast<int>(ceil((maxULY-minLRY)/dy)));
587 cout <<
"composite image dim (nrow x ncol): " << nrow <<
" x " << ncol << endl;
589 while(weight_opt.size()<input_opt.size())
590 weight_opt.push_back(weight_opt[0]);
592 std::cout << weight_opt << std::endl;
594 if(cruleMap[crule_opt[0]]==crule::mode){
595 nwriteBand=(file_opt[0])? class_opt.size()+1:class_opt.size();
598 nwriteBand=(file_opt[0])? bands.size()+1:bands.size();
599 if(output_opt.empty()){
600 std::cerr <<
"No output file provided (use option -o). Use --help for help information" << std::endl;
604 cout <<
"open output image " << output_opt[0] <<
" with " << nwriteBand <<
" bands" << endl << flush;
607 imgWriter.
open(output_opt[0],ncol,nrow,nwriteBand,theType,imageType,option_opt);
611 cout << error << endl;
613 if(description_opt.size())
624 if(projection_opt.size()){
626 cout <<
"projection: " << projection_opt[0] << endl;
629 else if(theProjection!=
""){
631 cout <<
"projection: " << theProjection << endl;
635 if(colorTable_opt.size()){
636 if(colorTable_opt[0]!=
"none")
639 else if(theColorTable)
644 if(extent_opt.size()&&(cut_opt[0]||eoption_opt.size())){
646 maskWriter.
open(
"/vsimem/mask.tif",ncol,nrow,1,GDT_Float32,
"GTiff",option_opt);
655 if(projection_opt.size())
657 else if(theProjection!=
""){
659 cout <<
"projection: " << theProjection << endl;
662 vector<double> burnValues(1,1);
663 maskWriter.
rasterizeOgr(extentReader,burnValues,eoption_opt);
667 cerr << error << std::endl;
671 cerr <<
"error caught" << std::endl;
676 mask_opt.push_back(
"/vsimem/mask.tif");
681 if(verbose_opt[0]>=1)
682 std::cout <<
"opening mask image file " << mask_opt[0] << std::endl;
683 maskReader.
open(mask_opt[0],GA_ReadOnly);
684 if(mskband_opt[0]>=maskReader.
nrOfBand()){
685 string errorString=
"Error: illegal mask band";
690 cerr << error << std::endl;
694 cerr <<
"error caught" << std::endl;
701 cout <<
"creating composite image" << endl;
703 vector<short> fileBuffer(ncol);
706 vector<Vector2d<double> > readBuffer(input_opt.size());
707 for(
int ifile=0;ifile<input_opt.size();++ifile)
708 readBuffer[ifile].resize(imgReader[ifile].nrOfBand());
710 if(cruleMap[crule_opt[0]]==crule::maxndvi)
711 assert(ruleBand_opt.size()==2);
712 if(cruleMap[crule_opt[0]]==crule::mode){
713 maxBuffer.resize(imgWriter.
nrOfCol(),256);
714 for(
int iclass=0;iclass<class_opt.size();++iclass)
715 assert(class_opt[iclass]<maxBuffer.size());
722 const char* pszMessage;
723 void* pProgressArg=NULL;
724 GDALProgressFunc pfnProgress=GDALTermProgress;
726 pfnProgress(progress,pszMessage,pProgressArg);
727 for(
int irow=0;irow<imgWriter.
nrOfRow();++irow){
728 vector<float> lineMask;
730 vector<bool> writeValid(ncol);
738 if(cruleMap[crule_opt[0]]==crule::mean ||
739 cruleMap[crule_opt[0]]==crule::median ||
740 cruleMap[crule_opt[0]]==crule::sum ||
741 cruleMap[crule_opt[0]]==crule::minallbands ||
742 cruleMap[crule_opt[0]]==crule::maxallbands ||
743 cruleMap[crule_opt[0]]==crule::stdev)
744 storeBuffer.resize(nband,ncol);
745 for(
int icol=0;icol<imgWriter.
nrOfCol();++icol){
746 writeValid[icol]=
false;
748 if(cruleMap[crule_opt[0]]==crule::mode){
749 for(
int iclass=0;iclass<256;++iclass)
750 maxBuffer[icol][iclass]=0;
753 for(
int iband=0;iband<nband;++iband)
754 writeBuffer[iband][icol]=dstnodata_opt[0];
758 double oldRowMask=-1;
760 for(
int ifile=0;ifile<input_opt.size();++ifile){
769 assert(imgReader[ifile].nrOfBand()>=nband);
770 if(!imgReader[ifile].covers(minULX,maxULY,maxLRX,minLRY)){
774 double uli,ulj,lri,lrj;
775 imgReader[ifile].geo2image(minULX+(magic_x-1.0)*imgReader[ifile].getDeltaX(),maxULY-(magic_y-1.0)*imgReader[ifile].getDeltaY(),uli,ulj);
776 imgReader[ifile].geo2image(maxLRX+(magic_x-2.0)*imgReader[ifile].getDeltaX(),minLRY-(magic_y-2.0)*imgReader[ifile].getDeltaY(),lri,lrj);
785 else if(uli>=imgReader[ifile].nrOfCol())
786 startCol=imgReader[ifile].nrOfCol()-1;
789 else if(lri>=imgReader[ifile].nrOfCol())
790 endCol=imgReader[ifile].nrOfCol()-1;
794 imgReader[ifile].geo2image(x,y,readCol,readRow);
795 if(readRow<0||readRow>=imgReader[ifile].nrOfRow()){
800 for(
int iband=0;iband<nband;++iband){
801 int readBand=(band_opt.size()>iband)? band_opt[iband] : iband;
804 imgReader[ifile].readData(readBuffer[ifile][iband],startCol,endCol,readRow,readBand,theResample);
814 cerr <<
"error reading image " << input_opt[ifile] <<
": " << endl;
818 for(
int ib=0;ib<ncol;++ib){
827 maskReader.
geo2image(x,y,colMask,rowMask);
828 colMask=
static_cast<int>(colMask);
829 rowMask=
static_cast<int>(rowMask);
830 if(rowMask>=0&&rowMask<maskReader.
nrOfRow()&&colMask>=0&&colMask<maskReader.
nrOfCol()){
831 if(static_cast<int>(rowMask)!=
static_cast<int>(oldRowMask)){
833 assert(rowMask>=0&&rowMask<maskReader.
nrOfRow());
835 maskReader.
readData(lineMask,static_cast<int>(rowMask),mskband_opt[0]);
837 catch(
string errorstring){
838 cerr << errorstring << endl;
842 cerr <<
"error caught" << std::endl;
847 if(lineMask[colMask]==msknodata_opt[0])
856 imgReader[ifile].geo2image(x,y,readCol,readRow);
857 if(readCol<0||readCol>=imgReader[ifile].nrOfCol())
859 double val_current=0;
864 lowerCol=readCol-0.5;
865 lowerCol=
static_cast<int>(lowerCol);
866 upperCol=readCol+0.5;
867 upperCol=
static_cast<int>(upperCol);
870 if(upperCol>=imgReader[ifile].nrOfCol())
871 upperCol=imgReader[ifile].nrOfCol()-1;
872 for(
int vband=0;vband<bndnodata_opt.size();++vband){
873 val_new=(readCol-0.5-lowerCol)*readBuffer[ifile][bndnodata_opt[vband]][upperCol-startCol]+(1-readCol+0.5+lowerCol)*readBuffer[ifile][bndnodata_opt[vband]][lowerCol-startCol];
874 if(minValue_opt.size()>vband){
875 if(val_new<=minValue_opt[vband]){
880 if(maxValue_opt.size()>vband){
881 if(val_new>=maxValue_opt[vband]){
886 if(srcnodata_opt.size()>vband){
887 if(val_new==srcnodata_opt[vband]){
895 readCol=
static_cast<int>(readCol);
896 for(
int vband=0;vband<bndnodata_opt.size();++vband){
897 val_new=readBuffer[ifile][bndnodata_opt[vband]][readCol-startCol];
898 if(minValue_opt.size()>vband){
899 if(val_new<=minValue_opt[vband]){
904 if(maxValue_opt.size()>vband){
905 if(val_new>=maxValue_opt[vband]){
910 if(srcnodata_opt.size()>vband){
911 if(val_new==srcnodata_opt[vband]){
924 switch(cruleMap[crule_opt[0]]){
925 case(crule::maxndvi):{
926 double red_current=writeBuffer[ruleBand_opt[0]][ib];
927 double nir_current=writeBuffer[ruleBand_opt[1]][ib];
928 double ndvi_current=0;
929 if(red_current+nir_current>0&&red_current>=0&&nir_current>=0)
930 ndvi_current=(nir_current-red_current)/(nir_current+red_current);
936 lowerCol=readCol-0.5;
937 lowerCol=
static_cast<int>(lowerCol);
938 upperCol=readCol+0.5;
939 upperCol=
static_cast<int>(upperCol);
942 if(upperCol>=imgReader[ifile].nrOfCol())
943 upperCol=imgReader[ifile].nrOfCol()-1;
944 red_new=(readCol-0.5-lowerCol)*readBuffer[ifile][ruleBand_opt[0]][upperCol-startCol]+(1-readCol+0.5+lowerCol)*readBuffer[ifile][ruleBand_opt[0]][lowerCol-startCol];
945 nir_new=(readCol-0.5-lowerCol)*readBuffer[ifile][ruleBand_opt[1]][upperCol-startCol]+(1-readCol+0.5+lowerCol)*readBuffer[ifile][ruleBand_opt[1]][lowerCol-startCol];
946 if(red_new+nir_new>0&&red_new>=0&&nir_new>=0)
947 ndvi_new=(nir_new-red_new)/(nir_new+red_new);
948 if(ndvi_new>=ndvi_current){
949 for(iband=0;iband<nband;++iband){
950 val_new=(readCol-0.5-lowerCol)*readBuffer[ifile][iband][upperCol-startCol]+(1-readCol+0.5+lowerCol)*readBuffer[ifile][iband][lowerCol-startCol];
951 writeBuffer[iband][ib]=val_new;
954 fileBuffer[ib]=ifile;
958 readCol=
static_cast<int>(readCol);
959 red_new=readBuffer[ifile][ruleBand_opt[0]][readCol-startCol];
960 nir_new=readBuffer[ifile][ruleBand_opt[1]][readCol-startCol];
961 if(red_new+nir_new>0&&red_new>=0&&nir_new>=0)
962 ndvi_new=(nir_new-red_new)/(nir_new+red_new);
963 if(ndvi_new>=ndvi_current){
964 for(iband=0;iband<nband;++iband){
965 val_new=readBuffer[ifile][iband][readCol-startCol];
966 writeBuffer[iband][ib]=val_new;
969 fileBuffer[ib]=ifile;
975 case(crule::maxband):
976 case(crule::minband):
977 case(crule::validband):
978 val_current=writeBuffer[ruleBand_opt[0]][ib];
981 lowerCol=readCol-0.5;
982 lowerCol=
static_cast<int>(lowerCol);
983 upperCol=readCol+0.5;
984 upperCol=
static_cast<int>(upperCol);
987 if(upperCol>=imgReader[ifile].nrOfCol())
988 upperCol=imgReader[ifile].nrOfCol()-1;
989 val_new=(readCol-0.5-lowerCol)*readBuffer[ifile][ruleBand_opt[0]][upperCol-startCol]+(1-readCol+0.5+lowerCol)*readBuffer[ifile][ruleBand_opt[0]][lowerCol-startCol];
990 val_new*=weight_opt[ifile];
991 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)){
992 for(iband=0;iband<nband;++iband){
993 val_new=(readCol-0.5-lowerCol)*readBuffer[ifile][iband][upperCol-startCol]+(1-readCol+0.5+lowerCol)*readBuffer[ifile][iband][lowerCol-startCol];
994 val_new*=weight_opt[ifile];
995 writeBuffer[iband][ib]=val_new;
998 fileBuffer[ib]=ifile;
1002 readCol=
static_cast<int>(readCol);
1003 val_new=readBuffer[ifile][ruleBand_opt[0]][readCol-startCol];
1004 val_new*=weight_opt[ifile];
1005 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)){
1006 for(iband=0;iband<nband;++iband){
1007 val_new=readBuffer[ifile][iband][readCol-startCol];
1008 val_new*=weight_opt[ifile];
1009 writeBuffer[iband][ib]=val_new;
1012 fileBuffer[ib]=ifile;
1018 switch(theResample){
1020 lowerCol=readCol-0.5;
1021 lowerCol=
static_cast<int>(lowerCol);
1022 upperCol=readCol+0.5;
1023 upperCol=
static_cast<int>(upperCol);
1026 if(upperCol>=imgReader[ifile].nrOfCol())
1027 upperCol=imgReader[ifile].nrOfCol()-1;
1028 for(iband=0;iband<nband;++iband){
1029 val_new=(readCol-0.5-lowerCol)*readBuffer[ifile][iband][upperCol-startCol]+(1-readCol+0.5+lowerCol)*readBuffer[ifile][iband][lowerCol-startCol];
1030 maxBuffer[ib][val_new]=maxBuffer[ib][val_new]+weight_opt[ifile];
1035 readCol=
static_cast<int>(readCol);
1036 for(iband=0;iband<nband;++iband){
1037 val_new=readBuffer[ifile][iband][readCol-startCol];
1038 maxBuffer[ib][val_new]=maxBuffer[ib][val_new]+weight_opt[ifile];
1044 case(crule::median):
1046 case(crule::minallbands):
1047 case(crule::maxallbands):
1049 switch(theResample){
1051 lowerCol=readCol-0.5;
1052 lowerCol=
static_cast<int>(lowerCol);
1053 upperCol=readCol+0.5;
1054 upperCol=
static_cast<int>(upperCol);
1057 if(upperCol>=imgReader[ifile].nrOfCol())
1058 upperCol=imgReader[ifile].nrOfCol()-1;
1059 for(iband=0;iband<nband;++iband){
1060 val_new=(readCol-0.5-lowerCol)*readBuffer[ifile][iband][upperCol-startCol]+(1-readCol+0.5+lowerCol)*readBuffer[ifile][iband][lowerCol-startCol];
1061 val_new*=weight_opt[ifile];
1062 storeBuffer[iband][ib].push_back(val_new);
1066 readCol=
static_cast<int>(readCol);
1067 for(iband=0;iband<nband;++iband){
1068 val_new=readBuffer[ifile][iband][readCol-startCol];
1069 val_new*=weight_opt[ifile];
1070 storeBuffer[iband][ib].push_back(val_new);
1078 fileBuffer[ib]=ifile;
1080 case(crule::overwrite):
1082 switch(theResample){
1084 lowerCol=readCol-0.5;
1085 lowerCol=
static_cast<int>(lowerCol);
1086 upperCol=readCol+0.5;
1087 upperCol=
static_cast<int>(upperCol);
1090 if(upperCol>=imgReader[ifile].nrOfCol())
1091 upperCol=imgReader[ifile].nrOfCol()-1;
1092 for(iband=0;iband<nband;++iband){
1093 val_new=(readCol-0.5-lowerCol)*readBuffer[ifile][iband][upperCol-startCol]+(1-readCol+0.5+lowerCol)*readBuffer[ifile][iband][lowerCol-startCol];
1094 val_new*=weight_opt[ifile];
1095 writeBuffer[iband][ib]=val_new;
1099 readCol=
static_cast<int>(readCol);
1100 for(iband=0;iband<nband;++iband){
1101 val_new=readBuffer[ifile][iband][readCol-startCol];
1102 val_new*=weight_opt[ifile];
1103 writeBuffer[iband][ib]=val_new;
1108 fileBuffer[ib]=ifile;
1118 writeValid[ib]=
true;
1120 switch(cruleMap[crule_opt[0]]){
1122 case(crule::median):
1124 case(crule::minallbands):
1125 case(crule::maxallbands):
1127 switch(theResample){
1129 lowerCol=readCol-0.5;
1130 lowerCol=
static_cast<int>(lowerCol);
1131 upperCol=readCol+0.5;
1132 upperCol=
static_cast<int>(upperCol);
1135 if(upperCol>=imgReader[ifile].nrOfCol())
1136 upperCol=imgReader[ifile].nrOfCol()-1;
1137 for(iband=0;iband<nband;++iband){
1138 val_new=(readCol-0.5-lowerCol)*readBuffer[ifile][iband][upperCol-startCol]+(1-readCol+0.5+lowerCol)*readBuffer[ifile][iband][lowerCol-startCol];
1139 val_new*=weight_opt[ifile];
1140 storeBuffer[iband][ib].push_back(val_new);
1144 readCol=
static_cast<int>(readCol);
1145 for(iband=0;iband<nband;++iband){
1146 val_new=readBuffer[ifile][iband][readCol-startCol];
1147 val_new*=weight_opt[ifile];
1148 storeBuffer[iband][ib].push_back(val_new);
1153 fileBuffer[ib]=ifile;
1156 switch(theResample){
1158 lowerCol=readCol-0.5;
1159 lowerCol=
static_cast<int>(lowerCol);
1160 upperCol=readCol+0.5;
1161 upperCol=
static_cast<int>(upperCol);
1164 if(upperCol>=imgReader[ifile].nrOfCol())
1165 upperCol=imgReader[ifile].nrOfCol()-1;
1166 for(iband=0;iband<nband;++iband){
1167 val_new=(readCol-0.5-lowerCol)*readBuffer[ifile][iband][upperCol-startCol]+(1-readCol+0.5+lowerCol)*readBuffer[ifile][iband][lowerCol-startCol];
1168 maxBuffer[ib][val_new]=maxBuffer[ib][val_new]+weight_opt[ifile];
1173 readCol=
static_cast<int>(readCol);
1174 for(iband=0;iband<nband;++iband){
1175 val_new=readBuffer[ifile][iband][readCol-startCol];
1176 maxBuffer[ib][val_new]=maxBuffer[ib][val_new]+weight_opt[ifile];
1183 switch(theResample){
1185 lowerCol=readCol-0.5;
1186 lowerCol=
static_cast<int>(lowerCol);
1187 upperCol=readCol+0.5;
1188 upperCol=
static_cast<int>(upperCol);
1191 if(upperCol>=imgReader[ifile].nrOfCol())
1192 upperCol=imgReader[ifile].nrOfCol()-1;
1193 for(iband=0;iband<nband;++iband){
1194 val_new=(readCol-0.5-lowerCol)*readBuffer[ifile][iband][upperCol-startCol]+(1-readCol+0.5+lowerCol)*readBuffer[ifile][iband][lowerCol-startCol];
1195 val_new*=weight_opt[ifile];
1196 writeBuffer[iband][ib]=val_new;
1200 readCol=
static_cast<int>(readCol);
1201 for(iband=0;iband<nband;++iband){
1202 val_new=readBuffer[ifile][iband][readCol-startCol];
1203 val_new*=weight_opt[ifile];
1204 writeBuffer[iband][ib]=val_new;
1209 fileBuffer[ib]=ifile;
1217 if(cruleMap[crule_opt[0]]==crule::mode){
1218 vector<short> classBuffer(imgWriter.
nrOfCol());
1219 if(class_opt.size()>1){
1220 for(
int iclass=0;iclass<class_opt.size();++iclass){
1221 for(
int icol=0;icol<imgWriter.
nrOfCol();++icol)
1222 classBuffer[icol]=maxBuffer[icol][class_opt[iclass]];
1224 imgWriter.
writeData(classBuffer,irow,iclass);
1226 catch(
string error){
1227 cerr <<
"error writing image file " << output_opt[0] <<
": " << error << endl;
1233 for(
int icol=0;icol<imgWriter.
nrOfCol();++icol){
1234 vector<short>::iterator maxit=maxBuffer[icol].begin();
1235 maxit=stat.mymax(maxBuffer[icol],maxBuffer[icol].begin(),maxBuffer[icol].end());
1236 writeBuffer[0][icol]=distance(maxBuffer[icol].begin(),maxit);
1238 fileBuffer[icol]=*(maxit);
1241 imgWriter.
writeData(writeBuffer[0],irow,0);
1245 catch(
string error){
1246 cerr <<
"error writing image file " << output_opt[0] <<
": " << error << endl;
1252 for(
int iband=0;iband<bands.size();++iband){
1254 assert(writeBuffer[iband].size()==imgWriter.
nrOfCol());
1255 for(
int icol=0;icol<imgWriter.
nrOfCol();++icol){
1257 switch(cruleMap[crule_opt[0]]){
1260 writeBuffer[iband][icol]=stat.mean(storeBuffer[iband][icol]);
1262 case(crule::median):
1264 writeBuffer[iband][icol]=stat.median(storeBuffer[iband][icol]);
1268 writeBuffer[iband][icol]=stat.sum(storeBuffer[iband][icol]);
1270 case(crule::minallbands):
1272 writeBuffer[iband][icol]=stat.mymin(storeBuffer[iband][icol]);
1274 case(crule::maxallbands):
1276 writeBuffer[iband][icol]=stat.mymax(storeBuffer[iband][icol]);
1280 writeBuffer[iband][icol]=sqrt(stat.var(storeBuffer[iband][icol]));
1286 catch(
string error){
1288 cerr << error << endl;
1289 writeBuffer[iband][icol]=dstnodata_opt[0];
1294 imgWriter.
writeData(writeBuffer[iband],irow,iband);
1296 catch(
string error){
1297 cerr << error <<
" in " << output_opt[0] << endl;
1303 imgWriter.
writeData(fileBuffer,irow,bands.size());
1305 catch(
string error){
1306 cerr << error <<
" in " << output_opt[0] << endl;
1311 progress=
static_cast<float>(irow+1.0)/imgWriter.
nrOfRow();
1312 pfnProgress(progress,pszMessage,pProgressArg);
1314 if(extent_opt.size()&&(cut_opt[0]||eoption_opt.size())){
1315 extentReader.close();
1317 for(
int ifile=0;ifile<input_opt.size();++ifile){
1318 imgReader[ifile].close();
void rasterizeOgr(ImgReaderOgr &ogrReader, const std::vector< double > &burnValues, const std::vector< std::string > &controlOptions=std::vector< std::string >(), const std::vector< std::string > &layernames=std::vector< std::string >())
Rasterize an OGR vector dataset using the gdal algorithm "GDALRasterizeLayers".
void setImageDescription(const std::string &imageDescription)
Set the image description (only for GeoTiff format: TIFFTAG_IMAGEDESCRIPTION)
bool geo2image(double x, double y, double &i, double &j) const
Convert georeferenced coordinates (x and y) to image coordinates (column and row) ...
CPLErr setProjectionProj4(const std::string &projection)
Set the projection for this dataset from user input (supports epsg:<number> format) ...
void close(void)
Set the memory (in MB) to cache a number of rows in memory.
int nrOfCol(void) const
Get the number of columns of this dataset.
void setColorTable(const std::string &filename, int band=0)
Set the color table using an (ASCII) file with 5 columns (value R G B alpha)
void readData(T &value, int col, int row, int band=0)
Read a single pixel cell value at a specific column and row for a specific band (all indices start co...
int nrOfRow(void) const
Get the number of rows of this dataset.
bool image2geo(double i, double j, double &x, double &y) const
Convert image coordinates (column and row) to georeferenced coordinates (x and y) ...
CPLErr setGeoTransform(double *gt)
Set the geotransform data for this dataset.
bool writeData(T &value, int col, int row, int band=0)
Write a single pixel cell value at a specific column and row for a specific band (all indices start c...
int setNoData(const std::vector< double > nodata)
Set the no data values of this dataset using a standard template library (stl) vector as input...
void open(const std::string &filename, const ImgReaderGdal &imgSrc, const std::vector< std::string > &options=std::vector< std::string >())
Open an image for writing, copying image attributes from a source image. Image is directly written to...
GDALDataType getDataType(int band=0) const
Get the GDAL datatype for this dataset.
CPLErr setProjection(const std::string &projection)
Set the projection for this dataset in well known text (wkt) format.
void close(void)
Close the image.
void open(const std::string &filename, const GDALAccess &readMode=GA_ReadOnly)
Open an image.
int nrOfBand(void) const
Get the number of bands of this dataset.