pktools  2.6.3
Processing Kernel for geospatial data
pkcrop.cc
1 /**********************************************************************
2 pkcrop.cc: perform raster data operations on image such as crop, extract and stack bands
3 Copyright (C) 2008-2014 Pieter Kempeneers
4 
5 This file is part of pktools
6 
7 pktools is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11 
12 pktools is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with pktools. If not, see <http://www.gnu.org/licenses/>.
19  ***********************************************************************/
20 #include <assert.h>
21 #include <cstdlib>
22 #include <string>
23 #include <list>
24 #include <iostream>
25 #include <algorithm>
26 #include "imageclasses/ImgWriterGdal.h"
27 #include "imageclasses/ImgReaderGdal.h"
28 #include "imageclasses/ImgReaderOgr.h"
29 #include "base/Optionpk.h"
30 #include "algorithms/Egcs.h"
31 
32 using namespace std;
33 
34 int main(int argc, char *argv[])
35 {
36  Optionpk<string> input_opt("i", "input", "Input image file(s). If input contains multiple images, a multi-band output is created");
37  Optionpk<string> output_opt("o", "output", "Output image file");
38  Optionpk<string> projection_opt("a_srs", "a_srs", "Override the projection for the output file (leave blank to copy from input file, use epsg:3035 to use European projection and force to European grid");
39  Optionpk<string> extent_opt("e", "extent", "get boundary from extent from polygons in vector file");
40  Optionpk<bool> mask_opt("m","mask","mask values out of polygon in extent file to flag option (tip: for better performance, use gdal_rasterize -i -burn 0 -l extent extent.shp output (with output the result of pkcrop)",false);
41  Optionpk<double> ulx_opt("ulx", "ulx", "Upper left x value bounding box", 0.0);
42  Optionpk<double> uly_opt("uly", "uly", "Upper left y value bounding box", 0.0);
43  Optionpk<double> lrx_opt("lrx", "lrx", "Lower right x value bounding box", 0.0);
44  Optionpk<double> lry_opt("lry", "lry", "Lower right y value bounding box", 0.0);
45  Optionpk<double> dx_opt("dx", "dx", "Output resolution in x (in meter) (empty: keep original resolution)");
46  Optionpk<double> dy_opt("dy", "dy", "Output resolution in y (in meter) (empty: keep original resolution)");
47  Optionpk<double> cx_opt("x", "x", "x-coordinate of image center to crop (in meter)");
48  Optionpk<double> cy_opt("y", "y", "y-coordinate of image center to crop (in meter)");
49  Optionpk<double> nx_opt("nx", "nx", "image size in x to crop (in meter)");
50  Optionpk<double> ny_opt("ny", "ny", "image size in y to crop (in meter)");
51  Optionpk<int> ns_opt("ns", "ns", "number of samples to crop (in pixels)");
52  Optionpk<int> nl_opt("nl", "nl", "number of lines to crop (in pixels)");
53  Optionpk<int> band_opt("b", "band", "band index to crop (leave empty to retain all bands)");
54  Optionpk<double> autoscale_opt("as", "autoscale", "scale output to min and max, e.g., --autoscale 0 --autoscale 255");
55  Optionpk<double> scale_opt("s", "scale", "output=scale*input+offset");
56  Optionpk<double> offset_opt("off", "offset", "output=scale*input+offset");
57  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","");
58  Optionpk<string> oformat_opt("of", "oformat", "Output image format (see also gdal_translate). Empty string: inherit from input image");
59  Optionpk<string> option_opt("co", "co", "Creation option for output file. Multiple options can be specified.");
60  Optionpk<string> colorTable_opt("ct", "ct", "color table (file with 5 columns: id R G B ALFA (0: transparent, 255: solid)");
61  Optionpk<double> nodata_opt("nodata", "nodata", "Nodata value to put in image if out of bounds.");
62  Optionpk<string> resample_opt("r", "resampling-method", "Resampling method (near: nearest neighbor, bilinear: bi-linear interpolation).", "near");
63  Optionpk<string> description_opt("d", "description", "Set image description");
64  Optionpk<short> verbose_opt("v", "verbose", "verbose", 0,2);
65 
66  extent_opt.setHide(1);
67  mask_opt.setHide(1);
68  option_opt.setHide(1);
69  cx_opt.setHide(1);
70  cy_opt.setHide(1);
71  nx_opt.setHide(1);
72  ny_opt.setHide(1);
73  ns_opt.setHide(1);
74  nl_opt.setHide(1);
75  scale_opt.setHide(1);
76  offset_opt.setHide(1);
77  nodata_opt.setHide(1);
78  description_opt.setHide(1);
79 
80  bool doProcess;//stop process when program was invoked with help option (-h --help)
81  try{
82  doProcess=input_opt.retrieveOption(argc,argv);
83  output_opt.retrieveOption(argc,argv);
84  projection_opt.retrieveOption(argc,argv);
85  ulx_opt.retrieveOption(argc,argv);
86  uly_opt.retrieveOption(argc,argv);
87  lrx_opt.retrieveOption(argc,argv);
88  lry_opt.retrieveOption(argc,argv);
89  band_opt.retrieveOption(argc,argv);
90  autoscale_opt.retrieveOption(argc,argv);
91  otype_opt.retrieveOption(argc,argv);
92  oformat_opt.retrieveOption(argc,argv);
93  colorTable_opt.retrieveOption(argc,argv);
94  dx_opt.retrieveOption(argc,argv);
95  dy_opt.retrieveOption(argc,argv);
96  resample_opt.retrieveOption(argc,argv);
97  extent_opt.retrieveOption(argc,argv);
98  mask_opt.retrieveOption(argc,argv);
99  option_opt.retrieveOption(argc,argv);
100  cx_opt.retrieveOption(argc,argv);
101  cy_opt.retrieveOption(argc,argv);
102  nx_opt.retrieveOption(argc,argv);
103  ny_opt.retrieveOption(argc,argv);
104  ns_opt.retrieveOption(argc,argv);
105  nl_opt.retrieveOption(argc,argv);
106  scale_opt.retrieveOption(argc,argv);
107  offset_opt.retrieveOption(argc,argv);
108  nodata_opt.retrieveOption(argc,argv);
109  description_opt.retrieveOption(argc,argv);
110  verbose_opt.retrieveOption(argc,argv);
111  }
112  catch(string predefinedString){
113  std::cout << predefinedString << std::endl;
114  exit(0);
115  }
116  //test
117  if(verbose_opt[0])
118  cout << setprecision(12) << "--ulx=" << ulx_opt[0] << " --uly=" << uly_opt[0] << " --lrx=" << lrx_opt[0] << " --lry=" << lry_opt[0] << endl;
119 
120  if(!doProcess){
121  cout << endl;
122  cout << "Usage: pkcrop -i input -o output" << endl;
123  cout << endl;
124  std::cout << "short option -h shows basic options only, use long option --help to show all options" << std::endl;
125  exit(0);//help was invoked, stop processing
126  }
127  if(input_opt.empty()){
128  std::cerr << "No input file provided (use option -i). Use --help for help information" << std::endl;
129  exit(0);
130  }
131  if(output_opt.empty()){
132  std::cerr << "No output file provided (use option -o). Use --help for help information" << std::endl;
133  exit(0);
134  }
135 
136  double nodataValue=nodata_opt.size()? nodata_opt[0] : 0;
137  RESAMPLE theResample;
138  if(resample_opt[0]=="near"){
139  theResample=NEAR;
140  if(verbose_opt[0])
141  cout << "resampling: nearest neighbor" << endl;
142  }
143  else if(resample_opt[0]=="bilinear"){
144  theResample=BILINEAR;
145  if(verbose_opt[0])
146  cout << "resampling: bilinear interpolation" << endl;
147  }
148  else{
149  std::cout << "Error: resampling method " << resample_opt[0] << " not supported" << std::endl;
150  exit(1);
151  }
152 
153  const char* pszMessage;
154  void* pProgressArg=NULL;
155  GDALProgressFunc pfnProgress=GDALTermProgress;
156  double progress=0;
157  pfnProgress(progress,pszMessage,pProgressArg);
158  ImgReaderGdal imgReader;
159  ImgWriterGdal imgWriter;
160  //open input images to extract number of bands and spatial resolution
161  int ncropband=0;//total number of bands to write
162  double dx=0;
163  double dy=0;
164  if(dx_opt.size())
165  dx=dx_opt[0];
166  if(dy_opt.size())
167  dy=dy_opt[0];
168 
169  bool isGeoRef=false;
170  for(int iimg=0;iimg<input_opt.size();++iimg){
171  imgReader.open(input_opt[iimg]);
172  if(!isGeoRef)
173  isGeoRef=imgReader.isGeoRef();
174  if(dx_opt.empty()){
175  if(!iimg||imgReader.getDeltaX()<dx)
176  dx=imgReader.getDeltaX();
177  }
178  if(dy_opt.empty()){
179  if(!iimg||imgReader.getDeltaY()<dy)
180  dy=imgReader.getDeltaY();
181  }
182  if(band_opt.size())
183  ncropband+=band_opt.size();
184  else
185  ncropband+=imgReader.nrOfBand();
186  imgReader.close();
187  }
188 
189  GDALDataType theType=GDT_Unknown;
190  if(verbose_opt[0])
191  cout << "possible output data types: ";
192  for(int iType = 0; iType < GDT_TypeCount; ++iType){
193  if(verbose_opt[0])
194  cout << " " << GDALGetDataTypeName((GDALDataType)iType);
195  if( GDALGetDataTypeName((GDALDataType)iType) != NULL
196  && EQUAL(GDALGetDataTypeName((GDALDataType)iType),
197  otype_opt[0].c_str()))
198  theType=(GDALDataType) iType;
199  }
200  if(verbose_opt[0]){
201  cout << endl;
202  if(theType==GDT_Unknown)
203  cout << "Unknown output pixel type: " << otype_opt[0] << endl;
204  else
205  cout << "Output pixel type: " << GDALGetDataTypeName(theType) << endl;
206  }
207  //bounding box of cropped image
208  double cropulx=ulx_opt[0];
209  double cropuly=uly_opt[0];
210  double croplrx=lrx_opt[0];
211  double croplry=lry_opt[0];
212  //get bounding box from extentReader if defined
213  ImgReaderOgr extentReader;
214  //test
215  if(verbose_opt[0])
216  cout << "--ulx=" << ulx_opt[0] << " --uly=" << uly_opt[0] << " --lrx=" << lrx_opt[0] << " --lry=" << lry_opt[0] << endl;
217 
218  if(extent_opt.size()){
219  for(int iextent=0;iextent<extent_opt.size();++iextent){
220  extentReader.open(extent_opt[iextent]);
221  if(!(extentReader.getExtent(ulx_opt[0],uly_opt[0],lrx_opt[0],lry_opt[0]))){
222  cerr << "Error: could not get extent from " << extent_opt[0] << endl;
223  exit(1);
224  }
225  extentReader.close();
226  }
227  if(mask_opt[0])
228  extentReader.open(extent_opt[0]);
229  }
230  else if(cx_opt.size()&&cy_opt.size()&&nx_opt.size()&&ny_opt.size()){
231  ulx_opt[0]=cx_opt[0]-nx_opt[0]/2.0;
232  uly_opt[0]=(isGeoRef) ? cy_opt[0]+ny_opt[0]/2.0 : cy_opt[0]-ny_opt[0]/2.0;
233  lrx_opt[0]=cx_opt[0]+nx_opt[0]/2.0;
234  lry_opt[0]=(isGeoRef) ? cy_opt[0]-ny_opt[0]/2.0 : cy_opt[0]+ny_opt[0]/2.0;
235  }
236  else if(cx_opt.size()&&cy_opt.size()&&ns_opt.size()&&nl_opt.size()){
237  ulx_opt[0]=cx_opt[0]-ns_opt[0]*dx/2.0;
238  uly_opt[0]=(isGeoRef) ? cy_opt[0]+nl_opt[0]*dy/2.0 : cy_opt[0]-nl_opt[0]*dy/2.0;
239  lrx_opt[0]=cx_opt[0]+ns_opt[0]*dx/2.0;
240  lry_opt[0]=(isGeoRef) ? cy_opt[0]-nl_opt[0]*dy/2.0 : cy_opt[0]+nl_opt[0]*dy/2.0;
241  }
242  //test
243  if(verbose_opt[0])
244  cout << "--ulx=" << ulx_opt[0] << " --uly=" << uly_opt[0] << " --lrx=" << lrx_opt[0] << " --lry=" << lry_opt[0] << endl;
245  if(ulx_opt[0]<cropulx)
246  cropulx=ulx_opt[0];
247  if(uly_opt[0]>cropuly)
248  cropuly=uly_opt[0];
249  if(lry_opt[0]<croplry)
250  croplry=lry_opt[0];
251  if(lrx_opt[0]>croplrx)
252  croplrx=lrx_opt[0];
253  if(verbose_opt[0])
254  cout << "--ulx=" << ulx_opt[0] << " --uly=" << uly_opt[0] << " --lrx=" << lrx_opt[0] << " --lry=" << lry_opt[0] << endl;
255  //determine number of output bands
256  int writeBand=0;//write band
257 
258  if(scale_opt.size()){
259  while(scale_opt.size()<band_opt.size())
260  scale_opt.push_back(scale_opt[0]);
261  }
262  if(offset_opt.size()){
263  while(offset_opt.size()<band_opt.size())
264  offset_opt.push_back(offset_opt[0]);
265  }
266  if(autoscale_opt.size()){
267  assert(autoscale_opt.size()%2==0);
268  // while(autoscale_opt.size()<band_opt.size()*2){
269  // autoscale_opt.push_back(autoscale_opt[0]);
270  // autoscale_opt.push_back(autoscale_opt[1]);
271  // }
272  }
273 
274  for(int iimg=0;iimg<input_opt.size();++iimg){
275  if(verbose_opt[0])
276  cout << "opening image " << input_opt[iimg] << endl;
277  imgReader.open(input_opt[iimg]);
278  //if output type not set, get type from input image
279  if(theType==GDT_Unknown){
280  theType=imgReader.getDataType();
281  if(verbose_opt[0])
282  cout << "Using data type from input image: " << GDALGetDataTypeName(theType) << endl;
283  }
284  if(option_opt.findSubstring("INTERLEAVE=")==option_opt.end()){
285  string theInterleave="INTERLEAVE=";
286  theInterleave+=imgReader.getInterleave();
287  option_opt.push_back(theInterleave);
288  }
289  int nrow=imgReader.nrOfRow();
290  int ncol=imgReader.nrOfCol();
291  int ncropcol=0;
292  int ncroprow=0;
293  // if(!dx||!dy){
294  // dx=imgReader.getDeltaX();
295  // dy=imgReader.getDeltaY();
296  // }
297  if(verbose_opt[0])
298  cout << "size of " << input_opt[iimg] << ": " << ncol << " cols, "<< nrow << " rows" << endl;
299  double uli,ulj,lri,lrj;//image coordinates
300  bool forceEUgrid=false;
301  if(projection_opt.size())
302  forceEUgrid=(!(projection_opt[0].compare("EPSG:3035"))||!(projection_opt[0].compare("EPSG:3035"))||projection_opt[0].find("ETRS-LAEA")!=string::npos);
303  if(ulx_opt[0]>=lrx_opt[0]){//default bounding box: no cropping
304  uli=0;
305  lri=imgReader.nrOfCol()-1;
306  ulj=0;
307  lrj=imgReader.nrOfRow()-1;
308  ncropcol=imgReader.nrOfCol();
309  ncroprow=imgReader.nrOfRow();
310  imgReader.getBoundingBox(cropulx,cropuly,croplrx,croplry);
311  double magicX=1,magicY=1;
312  // imgReader.getMagicPixel(magicX,magicY);
313  if(forceEUgrid){
314  //force to LAEA grid
315  Egcs egcs;
316  egcs.setLevel(egcs.res2level(dx));
317  egcs.force2grid(cropulx,cropuly,croplrx,croplry);
318  imgReader.geo2image(cropulx+(magicX-1.0)*imgReader.getDeltaX(),cropuly-(magicY-1.0)*imgReader.getDeltaY(),uli,ulj);
319  imgReader.geo2image(croplrx+(magicX-2.0)*imgReader.getDeltaX(),croplry-(magicY-2.0)*imgReader.getDeltaY(),lri,lrj);
320  }
321  imgReader.geo2image(cropulx+(magicX-1.0)*imgReader.getDeltaX(),cropuly-(magicY-1.0)*imgReader.getDeltaY(),uli,ulj);
322  imgReader.geo2image(croplrx+(magicX-2.0)*imgReader.getDeltaX(),croplry-(magicY-2.0)*imgReader.getDeltaY(),lri,lrj);
323  //test
324  ncropcol=abs(static_cast<int>(ceil((croplrx-cropulx)/dx)));
325  ncroprow=abs(static_cast<int>(ceil((cropuly-croplry)/dy)));
326  }
327  else{
328  double magicX=1,magicY=1;
329  // imgReader.getMagicPixel(magicX,magicY);
330  cropulx=ulx_opt[0];
331  cropuly=uly_opt[0];
332  croplrx=lrx_opt[0];
333  croplry=lry_opt[0];
334  if(forceEUgrid){
335  //force to LAEA grid
336  Egcs egcs;
337  egcs.setLevel(egcs.res2level(dx));
338  egcs.force2grid(cropulx,cropuly,croplrx,croplry);
339  imgReader.geo2image(cropulx+(magicX-1.0)*imgReader.getDeltaX(),cropuly-(magicY-1.0)*imgReader.getDeltaY(),uli,ulj);
340  imgReader.geo2image(croplrx+(magicX-2.0)*imgReader.getDeltaX(),croplry-(magicY-2.0)*imgReader.getDeltaY(),lri,lrj);
341  }
342  imgReader.geo2image(cropulx+(magicX-1.0)*imgReader.getDeltaX(),cropuly-(magicY-1.0)*imgReader.getDeltaY(),uli,ulj);
343  imgReader.geo2image(croplrx+(magicX-2.0)*imgReader.getDeltaX(),croplry-(magicY-2.0)*imgReader.getDeltaY(),lri,lrj);
344 
345  ncropcol=abs(static_cast<int>(ceil((croplrx-cropulx)/dx)));
346  ncroprow=abs(static_cast<int>(ceil((cropuly-croplry)/dy)));
347  uli=floor(uli);
348  ulj=floor(ulj);
349  lri=floor(lri);
350  lrj=floor(lrj);
351  }
352 
353  double dcropcol=0;
354  double dcroprow=0;
355  double deltaX=imgReader.getDeltaX();
356  double deltaY=imgReader.getDeltaY();
357  dcropcol=(lri-uli+1)/(dx/deltaX);
358  dcroprow=(lrj-ulj+1)/(dy/deltaY);
359  if(!imgWriter.nrOfBand()){//not opened yet
360  if(verbose_opt[0]){
361  cout << "cropulx: " << cropulx << endl;
362  cout << "cropuly: " << cropuly << endl;
363  cout << "croplrx: " << croplrx << endl;
364  cout << "croplry: " << croplry << endl;
365  cout << "ncropcol: " << ncropcol << endl;
366  cout << "ncroprow: " << ncroprow << endl;
367  cout << "cropulx+ncropcol*dx: " << cropulx+ncropcol*dx << endl;
368  cout << "cropuly-ncroprow*dy: " << cropuly-ncroprow*dy << endl;
369  cout << "upper left column of input image: " << uli << endl;
370  cout << "upper left row of input image: " << ulj << endl;
371  cout << "lower right column of input image: " << lri << endl;
372  cout << "lower right row of input image: " << lrj << endl;
373  cout << "new number of cols: " << ncropcol << endl;
374  cout << "new number of rows: " << ncroprow << endl;
375  cout << "new number of bands: " << ncropband << endl;
376  }
377  // string theCompression;
378  // if(compress_opt[0]!="")//default
379  // theCompression=compress_opt[0];
380  // else
381  // theCompression=imgReader.getCompression();
382  // string theInterleave;
383  // if(interleave_opt[0]!="")//default
384  // theInterleave=interleave_opt[0];
385  // else
386  // theInterleave=imgReader.getInterleave();
387  string imageType=imgReader.getImageType();
388  if(oformat_opt.size())//default
389  imageType=oformat_opt[0];
390  try{
391  imgWriter.open(output_opt[0],ncropcol,ncroprow,ncropband,theType,imageType,option_opt);
392  if(nodata_opt.size()){
393  for(int iband=0;iband<ncropband;++iband)
394  imgWriter.GDALSetNoDataValue(nodata_opt[0],iband);
395  }
396  }
397  catch(string errorstring){
398  cout << errorstring << endl;
399  exit(4);
400  }
401  if(description_opt.size())
402  imgWriter.setImageDescription(description_opt[0]);
403  double gt[6];
404  gt[0]=cropulx;
405  gt[1]=dx;
406  gt[2]=0;
407  gt[3]=cropuly;
408  gt[4]=0;
409  gt[5]=(imgReader.isGeoRef())? -dy : dy;
410  imgWriter.setGeoTransform(gt);
411  if(projection_opt.size()){
412  if(verbose_opt[0])
413  cout << "projection: " << projection_opt[0] << endl;
414  imgWriter.setProjectionProj4(projection_opt[0]);
415  }
416  else
417  imgWriter.setProjection(imgReader.getProjection());
418  if(imgWriter.getDataType()==GDT_Byte){
419  if(colorTable_opt.size()){
420  if(colorTable_opt[0]!="none")
421  imgWriter.setColorTable(colorTable_opt[0]);
422  }
423  else if (imgReader.getColorTable()!=NULL)//copy colorTable from input image
424  imgWriter.setColorTable(imgReader.getColorTable());
425  }
426  }
427  double startCol=uli;
428  double endCol=lri;
429  if(uli<0)
430  startCol=0;
431  else if(uli>=imgReader.nrOfCol())
432  startCol=imgReader.nrOfCol()-1;
433  if(lri<0)
434  endCol=0;
435  else if(lri>=imgReader.nrOfCol())
436  endCol=imgReader.nrOfCol()-1;
437  double startRow=ulj;
438  double endRow=lrj;
439  if(ulj<0)
440  startRow=0;
441  else if(ulj>=imgReader.nrOfRow())
442  startRow=imgReader.nrOfRow()-1;
443  if(lrj<0)
444  endRow=0;
445  else if(lrj>=imgReader.nrOfRow())
446  endRow=imgReader.nrOfRow()-1;
447 
448  int readncol=endCol-startCol+1;
449  vector<double> readBuffer(readncol+1);
450  int nband=(band_opt.size())?band_opt.size() : imgReader.nrOfBand();
451  for(int iband=0;iband<nband;++iband){
452  int readBand=(band_opt.size()>iband)?band_opt[iband]:iband;
453  if(verbose_opt[0]){
454  cout << "extracting band " << readBand << endl;
455  pfnProgress(progress,pszMessage,pProgressArg);
456  }
457  double theMin=0;
458  double theMax=0;
459  if(autoscale_opt.size()){
460  try{
461  imgReader.getMinMax(static_cast<int>(startCol),static_cast<int>(endCol),static_cast<int>(startRow),static_cast<int>(endRow),readBand,theMin,theMax);
462  }
463  catch(string errorString){
464  cout << errorString << endl;
465  }
466  if(verbose_opt[0])
467  cout << "minmax: " << theMin << ", " << theMax << endl;
468  double theScale=(autoscale_opt[1]-autoscale_opt[0])/(theMax-theMin);
469  double theOffset=autoscale_opt[0]-theScale*theMin;
470  imgReader.setScale(theScale,readBand);
471  imgReader.setOffset(theOffset,readBand);
472  }
473  else{
474  if(scale_opt.size()){
475  if(scale_opt.size()>iband)
476  imgReader.setScale(scale_opt[iband],readBand);
477  else
478  imgReader.setScale(scale_opt[0],readBand);
479  }
480  if(offset_opt.size()){
481  if(offset_opt.size()>iband)
482  imgReader.setOffset(offset_opt[iband],readBand);
483  else
484  imgReader.setOffset(offset_opt[0],readBand);
485  }
486  }
487 
488  double readRow=0;
489  double readCol=0;
490  double lowerCol=0;
491  double upperCol=0;
492  for(int irow=0;irow<imgWriter.nrOfRow();++irow){
493  double x=0;
494  double y=0;
495  //convert irow to geo
496  imgWriter.image2geo(0,irow,x,y);
497  //lookup corresponding row for irow in this file
498  //test
499  // cout << "x: " << x << ", y: " << y << endl;
500  imgReader.geo2image(x,y,readCol,readRow);
501  //test
502  // cout << "readRow: " << readRow << ", readCol: " << readCol << flush << endl;
503  // double lowerCol=0;
504  // double upperCol=0;
505  vector<double> writeBuffer;
506  if(readRow<0||readRow>=imgReader.nrOfRow()){
507  //if(readRow<0)
508  //readRow=0;
509  //else if(readRow>=imgReader.nrOfRow())
510  //readRow=imgReader.nrOfRow()-1;
511  for(int ib=0;ib<imgWriter.nrOfCol();++ib)
512  writeBuffer.push_back(nodataValue);
513  }
514  else{
515  if(verbose_opt[0]>1)
516  cout << "reading row: " << readRow << endl;
517  try{
518  if(endCol<imgReader.nrOfCol()-1)
519  imgReader.readData(readBuffer,GDT_Float64,startCol,endCol+1,readRow,readBand,theResample);
520  else
521  imgReader.readData(readBuffer,GDT_Float64,startCol,endCol,readRow,readBand,theResample);
522  // for(int ib=0;ib<ncropcol;++ib){
523  for(int ib=0;ib<imgWriter.nrOfCol();++ib){
524  imgWriter.image2geo(ib,irow,x,y);
525  //lookup corresponding row for irow in this file
526  imgReader.geo2image(x,y,readCol,readRow);
527  if(readCol<0||readCol>=imgReader.nrOfCol()){
528  // if(readCol<0||readCol>=imgReader.nrOfCol()){
529  // if(readCol<0)
530  // readCol=0;
531  // else if(readCol>=imgReader.nrOfCol())
532  // readCol=imgReader.nrOfCol()-1;
533  writeBuffer.push_back(nodataValue);
534  }
535  else{
536  bool valid=true;
537  if(mask_opt[0]&&extent_opt.size()){
538  valid=false;
539  OGRPoint thePoint;
540  thePoint.setX(x);
541  thePoint.setY(y);
542  OGRLayer *readLayer;
543  readLayer = extentReader.getDataSource()->GetLayer(0);
544  readLayer->ResetReading();
545  OGRFeature *readFeature;
546  while( (readFeature = readLayer->GetNextFeature()) != NULL ){
547  OGRGeometry *poGeometry;
548  poGeometry = readFeature->GetGeometryRef();
549  assert(poGeometry!=NULL);
550  //check if point is on surface
551  OGRPolygon readPolygon = *((OGRPolygon *) poGeometry);
552  readPolygon.closeRings();
553  if(readPolygon.Contains(&thePoint)){
554  valid=true;
555  break;
556  }
557  else
558  continue;
559  }
560  }
561  if(!valid)
562  writeBuffer.push_back(nodataValue);
563  else{
564  // double theScale=1;
565  // double theOffset=0;
566  // if(autoscale_opt.size()){
567  // theScale=(autoscale_opt[1]-autoscale_opt[0])/(theMax-theMin);
568  // theOffset=autoscale_opt[0]-theScale*theMin;
569  // }
570  // else{
571  // theScale=(scale_opt.size()>1)?scale_opt[iband]:scale_opt[0];
572  // theOffset=(offset_opt.size()>1)?offset_opt[iband]:offset_opt[0];
573  // }
574  switch(theResample){
575  case(BILINEAR):
576  lowerCol=readCol-0.5;
577  lowerCol=static_cast<int>(lowerCol);
578  upperCol=readCol+0.5;
579  upperCol=static_cast<int>(upperCol);
580  if(lowerCol<0)
581  lowerCol=0;
582  if(upperCol>=imgReader.nrOfCol())
583  upperCol=imgReader.nrOfCol()-1;
584  // writeBuffer.push_back((readCol-0.5-lowerCol)*(readBuffer[upperCol-startCol]*theScale+theOffset)+(1-readCol+0.5+lowerCol)*(readBuffer[lowerCol-startCol]*theScale+theOffset));
585  writeBuffer.push_back((readCol-0.5-lowerCol)*readBuffer[upperCol-startCol]+(1-readCol+0.5+lowerCol)*readBuffer[lowerCol-startCol]);
586  break;
587  default:
588  readCol=static_cast<int>(readCol);
589  readCol-=startCol;//we only start reading from startCol
590  // writeBuffer.push_back(readBuffer[readCol]*theScale+theOffset);
591  writeBuffer.push_back(readBuffer[readCol]);
592  break;
593  }
594  }
595  }
596  }
597  }
598  catch(string errorstring){
599  cout << errorstring << endl;
600  exit(2);
601  }
602  }
603  if(writeBuffer.size()!=imgWriter.nrOfCol())
604  cout << "writeBuffer.size()=" << writeBuffer.size() << ", imgWriter.nrOfCol()=" << imgWriter.nrOfCol() << endl;
605  assert(writeBuffer.size()==imgWriter.nrOfCol());
606  try{
607  imgWriter.writeData(writeBuffer,GDT_Float64,irow,writeBand);
608  }
609  catch(string errorstring){
610  cout << errorstring << endl;
611  exit(3);
612  }
613  if(verbose_opt[0]){
614  progress=(1.0+irow);
615  progress/=imgWriter.nrOfRow();
616  pfnProgress(progress,pszMessage,pProgressArg);
617  }
618  else{
619  progress=(1.0+irow);
620  progress+=(imgWriter.nrOfRow()*writeBand);
621  progress/=imgWriter.nrOfBand()*imgWriter.nrOfRow();
622  assert(progress>=0);
623  assert(progress<=1);
624  pfnProgress(progress,pszMessage,pProgressArg);
625  }
626  }
627  ++writeBand;
628  }
629  imgReader.close();
630  }
631  if(extent_opt.size()&&mask_opt[0]){
632  extentReader.close();
633  }
634  imgWriter.close();
635 }
Definition: Egcs.h:26