[pktools] 14/375: findSubstring in Optionpk.h and default interleave from input image

Bas Couwenberg sebastic at xs4all.nl
Wed Dec 3 21:53:53 UTC 2014


This is an automated email from the git hooks/post-receive script.

sebastic-guest pushed a commit to branch upstream-master
in repository pktools.

commit 8be6f568d25123f4ed045002f4cf4b8e1bb6c54a
Author: Pieter Kempeneers <kempenep at gmail.com>
Date:   Wed Oct 17 13:25:58 2012 +0200

    findSubstring in Optionpk.h and default interleave from input image
---
 src/algorithms/Filter2d.cc       | 66 +++++-----------------------------------
 src/algorithms/Filter2d.h        | 52 +++++++++++++++++++++++++++++++
 src/apps/Makefile.am             |  7 +++--
 src/apps/Makefile.in             | 35 +++++++++++++++------
 src/apps/pkascii2img.cc          |  2 +-
 src/apps/pkclassify_nn.cc        |  8 ++++-
 src/apps/pkcreatect.cc           |  6 ++++
 src/apps/pkcrop.cc               | 18 +++++++++--
 src/apps/pkdiff.cc               |  7 ++++-
 src/apps/pkfilter.cc             |  5 +++
 src/apps/pkgetmask.cc            |  5 +++
 src/apps/pkmosaic.cc             | 13 +++-----
 src/apps/pkndvi.cc               | 61 ++++++++++++++++++++++++++++++++-----
 src/apps/pkreclass.cc            |  7 ++++-
 src/apps/pksetmask.cc            |  7 ++++-
 src/apps/pkstatogr.cc            |  8 +++--
 src/base/Optionpk.h              | 25 ++++++++++-----
 src/imageclasses/ImgWriterGdal.h | 20 ++++++++++++
 18 files changed, 251 insertions(+), 101 deletions(-)

diff --git a/src/algorithms/Filter2d.cc b/src/algorithms/Filter2d.cc
index 8efb064..6675c8d 100644
--- a/src/algorithms/Filter2d.cc
+++ b/src/algorithms/Filter2d.cc
@@ -25,16 +25,6 @@ along with pktools.  If not, see <http://www.gnu.org/licenses/>.
 #include "Histogram.h"
 // #include "imageclasses/ImgUtils.h"
 
-#ifndef PI
-#define PI 3.1415926535897932384626433832795
-#endif
-
-#include <math.h>
-
-#ifndef DEG2RAD
-#define DEG2RAD(DEG) ((DEG)*((PI)/(180.0)))
-#endif
-
 Filter2d::Filter2d::Filter2d(void)
   : m_noValue(0)
 {
@@ -418,24 +408,16 @@ void Filter2d::Filter2d::doit(const ImgReaderGdal& input, ImgWriterGdal& output,
 
 void Filter2d::Filter2d::doit(const ImgReaderGdal& input, ImgWriterGdal& output, int method, int dimX, int dimY, short down, bool disc)
 {
-  // ImgReaderGdal input;
-  // ImgWriterGdal output;
-  // input.open(inputFilename);
-  // output.open(outputFilename,input);
   assert(dimX);
   assert(dimY);
   Histogram hist;
   for(int iband=0;iband<input.nrOfBand();++iband){
     Vector2d<double> inBuffer(dimY,input.nrOfCol());
-    // vector<double> outBuffer(input.nrOfCol());
     vector<double> outBuffer((input.nrOfCol()+down-1)/down);
     //initialize last half of inBuffer
     int indexI=0;
     int indexJ=0;
-    // for(int y=0;y<dimY;++y){
     for(int j=-dimY/2;j<(dimY+1)/2;++j){
-      // if(y<dimY/2)
-      //   continue;//skip first half
       try{
         input.readData(inBuffer[indexJ],GDT_Float64,abs(j),iband);
       }
@@ -449,7 +431,6 @@ void Filter2d::Filter2d::doit(const ImgReaderGdal& input, ImgWriterGdal& output,
     GDALProgressFunc pfnProgress=GDALTermProgress;
     double progress=0;
     pfnProgress(progress,pszMessage,pProgressArg);
-    // for(int y=0;y<input.nrOfRow();++y){
     for(int y=0;y<input.nrOfRow();++y){
       if(y){//inBuffer already initialized for y=0
 	//erase first line from inBuffer
@@ -478,7 +459,6 @@ void Filter2d::Filter2d::doit(const ImgReaderGdal& input, ImgWriterGdal& output,
       for(int x=0;x<input.nrOfCol();++x){
         if((x+1+down/2)%down)
           continue;
-	// outBuffer[x]=0;
 	outBuffer[x/down]=0;
 	vector<double> windowBuffer;
 	map<int,int> occurrence;
@@ -493,24 +473,12 @@ void Filter2d::Filter2d::doit(const ImgReaderGdal& input, ImgWriterGdal& output,
 	      indexI=-indexI;
 	    else if(indexI>=input.nrOfCol())
 	      indexI=input.nrOfCol()-i;
-	      // indexI=input.nrOfCol()-indexI;
 	    if(y+j<0)
 	      indexJ=-j;
 	    else if(y+j>=input.nrOfRow())
 	      indexJ=dimY/2-j;
 	    else
 	      indexJ=dimY/2+j;
-	    // if(method==HOMOG||method==DENSITY||method==MAJORITY||method==MIXED){
-	    //   bool masked=false;
-	    //   for(int imask=0;imask<m_mask.size();++imask){
-	    //     if(inBuffer[indexJ][indexI]==m_mask[imask]){
-	    //       masked=true;
-	    //       break;
-	    //     }
-	    //   }
-	    //   if(!masked)
-	    //     ++occurrence[inBuffer[indexJ][indexI]];
-	    // }
 	    bool masked=false;
 	    for(int imask=0;imask<m_mask.size();++imask){
 	      if(inBuffer[indexJ][indexI]==m_mask[imask]){
@@ -535,21 +503,17 @@ void Filter2d::Filter2d::doit(const ImgReaderGdal& input, ImgWriterGdal& output,
         }
         switch(method){
         case(MEDIAN):
-          // outBuffer[x]=hist.median(windowBuffer);
           outBuffer[x/down]=hist.median(windowBuffer);
           break;
         case(VAR):{
-          // outBuffer[x]=hist.var(windowBuffer);
           outBuffer[x/down]=hist.var(windowBuffer);
           break;
         }
         case(MEAN):{
-          // outBuffer[x]=hist.mean(windowBuffer);
           outBuffer[x/down]=hist.mean(windowBuffer);
           break;
         }
         case(MIN):{
-          // outBuffer[x]=hist.min(windowBuffer);
           outBuffer[x/down]=hist.min(windowBuffer);
           break;
         }
@@ -563,14 +527,11 @@ void Filter2d::Filter2d::doit(const ImgReaderGdal& input, ImgWriterGdal& output,
           hist.minmax(windowBuffer,windowBuffer.begin(),windowBuffer.end(),min,max);
           if(min!=max)
             outBuffer[x/down]=0;
-            // outBuffer[x]=0;
           else
             outBuffer[x/down]=windowBuffer[dimX*dimY/2];//centre pixels
-            // outBuffer[x]=windowBuffer[dimX*dimY/2];//centre pixels
           break;
         }
         case(MAX):{
-          // outBuffer[x]=hist.max(windowBuffer);
           outBuffer[x/down]=hist.max(windowBuffer);
           break;
         }
@@ -583,23 +544,19 @@ void Filter2d::Filter2d::doit(const ImgReaderGdal& input, ImgWriterGdal& output,
           double ubound=dimX*dimY;
           double theMin=hist.min(windowBuffer);
           double theMax=hist.max(windowBuffer);
-          // outBuffer[x]=hist.median(windowBuffer);
           double scale=(ubound-lbound)/(theMax-theMin);
           outBuffer[x/down]=static_cast<short>(scale*(windowBuffer[dimX*dimY/2]-theMin)+lbound);
           break;
         }
         case(SUM):{
-          // outBuffer[x]=hist.sum(windowBuffer);
           outBuffer[x/down]=hist.sum(windowBuffer);
           break;
         }
         case(HOMOG):
 	  if(occurrence.size()==1)//all values in window must be the same
 	    outBuffer[x/down]=inBuffer[dimY/2][x];
-	    // outBuffer[x]=inBuffer[dimY/2][x];
 	  else//favorize original value in case of ties
 	    outBuffer[x/down]=m_noValue;
-	    // outBuffer[x]=m_noValue;
           break;
         case(HETEROG):{
           for(vector<double>::const_iterator wit=windowBuffer.begin();wit!=windowBuffer.end();++wit){
@@ -619,11 +576,9 @@ void Filter2d::Filter2d::doit(const ImgReaderGdal& input, ImgWriterGdal& output,
 	    vector<short>::const_iterator vit=m_class.begin();
 	    while(vit!=m_class.end())
 	      outBuffer[x/down]+=100.0*occurrence[*(vit++)]/windowBuffer.size();
-	      // outBuffer[x]+=100.0*occurrence[*(vit++)]/windowBuffer.size();
 	  }
 	  else
 	    outBuffer[x/down]=0;
-	    // outBuffer[x]=0;
           break;
 	}
         case(MAJORITY):{
@@ -640,7 +595,6 @@ void Filter2d::Filter2d::doit(const ImgReaderGdal& input, ImgWriterGdal& output,
 	  }
 	  else
 	    outBuffer[x/down]=0;
-          // outBuffer[x]=0;
           break;
         }
         case(THRESHOLD):{
@@ -681,32 +635,25 @@ void Filter2d::Filter2d::doit(const ImgReaderGdal& input, ImgWriterGdal& output,
           }
 	  else
 	    outBuffer[x/down]=inBuffer[indexJ][indexI];
-            // outBuffer[x]=0;
           break;
         }
         default:
           break;
         }
       }
-      // progress=(1.0+y);
       progress=(1.0+y/down);
       progress+=(output.nrOfRow()*iband);
       progress/=output.nrOfBand()*output.nrOfRow();
-      // assert(progress>=0);
-      // assert(progress<=1);
       pfnProgress(progress,pszMessage,pProgressArg);
       //write outBuffer to file
       try{
         output.writeData(outBuffer,GDT_Float64,y/down,iband);
-        // output.writeData(outBuffer,GDT_Float64,y,iband);
       }
       catch(string errorstring){
 	cerr << errorstring << "in band " << iband << ", line " << y << endl;
       }
     }
   }
-  // input.close();
-  // output.close();
 }
 
 //todo: re-implement without dependency of CImg and reg libraries
@@ -858,7 +805,6 @@ void Filter2d::Filter2d::morphology(const ImgReaderGdal& input, ImgWriterGdal& o
 	}
       }
       for(int x=0;x<input.nrOfCol();++x){
-	// outBuffer[x]=0;
         double currentValue=inBuffer[dimY/2][x];
 	outBuffer[x]=currentValue;
 	vector<double> histBuffer;
@@ -966,10 +912,6 @@ void Filter2d::Filter2d::morphology(const ImgReaderGdal& input, ImgWriterGdal& o
           }
 	  if(outBuffer[x]&&m_class.size())
 	    outBuffer[x]=m_class[0];
-	  // else{
-	  //   assert(m_mask.size());
-	  //   outBuffer[x]=m_mask[0];
-	  // }
 	}
       }
       //write outBuffer to file
@@ -986,3 +928,11 @@ void Filter2d::Filter2d::morphology(const ImgReaderGdal& input, ImgWriterGdal& o
     }
   }
 }
+
+void Filter2d::Filter2d::shadowDsm(const ImgReaderGdal& input, ImgWriterGdal& output, double sza, double saa, double pixelSize, short shadowFlag){
+  Vector2d<float> inputBuffer;
+  Vector2d<float> outputBuffer;
+  input.readDataBlock(inputBuffer, GDT_Float32, 0, input.nrOfCol()-1, 0, input.nrOfRow()-1, 0);
+  shadowDsm(inputBuffer, outputBuffer, sza, saa, pixelSize, shadowFlag);
+  output.writeDataBlock(outputBuffer,GDT_Float32,0,output.nrOfCol()-1,0,output.nrOfRow()-1,0);
+}
diff --git a/src/algorithms/Filter2d.h b/src/algorithms/Filter2d.h
index 23debe5..1a4a870 100644
--- a/src/algorithms/Filter2d.h
+++ b/src/algorithms/Filter2d.h
@@ -20,7 +20,16 @@ along with pktools.  If not, see <http://www.gnu.org/licenses/>.
 #ifndef _MYFILTER2D_H_
 #define _MYFILTER2D_H_
 
+#ifndef PI
+#define PI 3.1415926535897932384626433832795
+#endif
+
+#ifndef DEG2RAD
+#define DEG2RAD(DEG) (DEG/180.0*PI)
+#endif
+
 #include <assert.h>
+#include <math.h>
 #include <limits>
 #include <vector>
 #include <string>
@@ -64,6 +73,8 @@ public:
   void var(const string& inputFilename, const string& outputFilename, int dim, bool disc=false);
   void morphology(const ImgReaderGdal& input, ImgWriterGdal& output, int method, int dimX, int dimY, bool disc=false, double angle=-190);
   template<class T> unsigned long int morphology(const Vector2d<T>& input, Vector2d<T>& output, int method, int dimX, int dimY, bool disc=false, double hThreshold=0);
+  template<class T> void shadowDsm(const Vector2d<T>& input, Vector2d<T>& output, double sza, double saa, double pixelSize, short shadowFlag=1);
+  void shadowDsm(const ImgReaderGdal& input, ImgWriterGdal& output, double sza, double saa, double pixelSize, short shadowFlag=1);
   void dwt_texture(const string& inputFilename, const string& outputFilename,int dim, int scale, int down=1, int iband=0, bool verbose=false);
   
 private:
@@ -272,6 +283,47 @@ template<class T> unsigned long int Filter2d::morphology(const Vector2d<T>& inpu
   return nchange;
 }
 
+  template<class T> void Filter2d::shadowDsm(const Vector2d<T>& input, Vector2d<T>& output, double sza, double saa, double pixelSize, short shadowFlag)
+{
+  unsigned int ncols=input.nCols();
+  output.clear();
+  output.resize(input.nRows(),ncols);
+  //do we need to initialize output?
+  // for(int y=0;y<output.nRows();++y)
+  //   for(int x=0;x<output.nCols();++x)
+  //     output[y][x]=0;
+  int indexI=0;
+  int indexJ=0;
+  const char* pszMessage;
+  void* pProgressArg=NULL;
+  GDALProgressFunc pfnProgress=GDALTermProgress;
+  double progress=0;
+  pfnProgress(progress,pszMessage,pProgressArg);
+  for(int y=0;y<input.nRows();++y){
+    for(int x=0;x<input.nCols();++x){
+      double currentValue=input[y][x];
+      int theDist=static_cast<int>(sqrt((currentValue*tan(DEG2RAD(sza))/pixelSize)*(currentValue*tan(DEG2RAD(sza))/pixelSize)));//in pixels
+      double theDir=DEG2RAD(saa)+PI/2.0;
+      if(theDir<0)
+        theDir+=2*PI;
+      for(int d=0;d<theDist;++d){//d in pixels
+        indexI=x+d*cos(theDir);//in pixels
+        indexJ=y+d*sin(theDir);//in pixels
+        if(indexJ<0||indexJ>=input.size())
+          continue;
+        if(indexI<0||indexI>=input[indexJ].size())
+          continue;
+        if(input[indexJ][indexI]<currentValue-d*pixelSize/tan(DEG2RAD(sza))){//in m
+          output[indexJ][indexI]=shadowFlag;
+        }
+      }
+    }
+    progress=(1.0+y);
+    progress/=output.nRows();
+    pfnProgress(progress,pszMessage,pProgressArg);
+  }
+}
+
 }
 
 #endif /* _MYFILTER_H_ */
diff --git a/src/apps/Makefile.am b/src/apps/Makefile.am
index 005a0b0..823577b 100644
--- a/src/apps/Makefile.am
+++ b/src/apps/Makefile.am
@@ -6,7 +6,7 @@ LDADD = $(GDAL_LDFLAGS) $(top_builddir)/src/algorithms/libalgorithms.a $(top_bui
 ###############################################################################
 
 # the program to build (the names of the final binaries)
-bin_PROGRAMS = pkinfo pkcrop pkreclass pkgetmask pksetmask pkcreatect pkdumpimg pkdumpogr pksieve pkstat pkstatogr pkegcs pkextract pkfillnodata pkfilter pkmosaic pkndvi pkpolygonize pkascii2img pkdiff
+bin_PROGRAMS = pkinfo pkcrop pkreclass pkgetmask pksetmask pkcreatect pkdumpimg pkdumpogr pksieve pkstat pkstatogr pkegcs pkextract pkfillnodata pkfilter pkveg2shadow pkmosaic pkndvi pkpolygonize pkascii2img pkdiff
 if USE_FANN
 bin_PROGRAMS += pkclassify_nn
 pkclassify_nn_SOURCES = $(top_srcdir)/src/algorithms/myfann_cpp.h pkclassify_nn.h pkclassify_nn.cc
@@ -32,11 +32,12 @@ pkstat_SOURCES = $(top_srcdir)/src/algorithms/Histogram.h pkstat.cc
 pkstat_LDADD = $(GSL_LIBS) $(AM_LDFLAGS)
 pkstatogr_SOURCES = pkstatogr.cc
 pkegcs_SOURCES = pkegcs.cc
-pkegcs_LDADD = -lgdal $(AM_LDFLAGS) -lgdal
+#pkegcs_LDADD = -lgdal $(AM_LDFLAGS) -lgdal
 pkextract_SOURCES = pkextract.cc
 pkfillnodata_SOURCES = pkfillnodata.cc
 pkfilter_SOURCES = pkfilter.cc
-pkfilter_LDADD = -lgdal $(AM_LDFLAGS) -lgdal
+#pkfilter_LDADD = -lgdal $(AM_LDFLAGS) -lgdal
+pkveg2shadow_SOURCES = pkveg2shadow.cc
 pkmosaic_SOURCES = pkmosaic.cc
 pkndvi_SOURCES = pkndvi.cc
 pkpolygonize_SOURCES = pkpolygonize.cc
diff --git a/src/apps/Makefile.in b/src/apps/Makefile.in
index de51310..7ae36e3 100644
--- a/src/apps/Makefile.in
+++ b/src/apps/Makefile.in
@@ -37,9 +37,9 @@ bin_PROGRAMS = pkinfo$(EXEEXT) pkcrop$(EXEEXT) pkreclass$(EXEEXT) \
 	pkdumpimg$(EXEEXT) pkdumpogr$(EXEEXT) pksieve$(EXEEXT) \
 	pkstat$(EXEEXT) pkstatogr$(EXEEXT) pkegcs$(EXEEXT) \
 	pkextract$(EXEEXT) pkfillnodata$(EXEEXT) pkfilter$(EXEEXT) \
-	pkmosaic$(EXEEXT) pkndvi$(EXEEXT) pkpolygonize$(EXEEXT) \
-	pkascii2img$(EXEEXT) pkdiff$(EXEEXT) $(am__EXEEXT_1) \
-	$(am__EXEEXT_2)
+	pkveg2shadow$(EXEEXT) pkmosaic$(EXEEXT) pkndvi$(EXEEXT) \
+	pkpolygonize$(EXEEXT) pkascii2img$(EXEEXT) pkdiff$(EXEEXT) \
+	$(am__EXEEXT_1) $(am__EXEEXT_2)
 @USE_FANN_TRUE at am__append_1 = pkclassify_nn
 @USE_LAS_TRUE at am__append_2 = pklas2img
 subdir = src/apps
@@ -109,7 +109,10 @@ pkdumpogr_DEPENDENCIES = $(am__DEPENDENCIES_1) \
 	$(top_builddir)/src/imageclasses/libimageClasses.a
 am_pkegcs_OBJECTS = pkegcs.$(OBJEXT)
 pkegcs_OBJECTS = $(am_pkegcs_OBJECTS)
-pkegcs_DEPENDENCIES = $(am__DEPENDENCIES_2)
+pkegcs_LDADD = $(LDADD)
+pkegcs_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+	$(top_builddir)/src/algorithms/libalgorithms.a \
+	$(top_builddir)/src/imageclasses/libimageClasses.a
 am_pkextract_OBJECTS = pkextract.$(OBJEXT)
 pkextract_OBJECTS = $(am_pkextract_OBJECTS)
 pkextract_LDADD = $(LDADD)
@@ -124,7 +127,10 @@ pkfillnodata_DEPENDENCIES = $(am__DEPENDENCIES_1) \
 	$(top_builddir)/src/imageclasses/libimageClasses.a
 am_pkfilter_OBJECTS = pkfilter.$(OBJEXT)
 pkfilter_OBJECTS = $(am_pkfilter_OBJECTS)
-pkfilter_DEPENDENCIES = $(am__DEPENDENCIES_2)
+pkfilter_LDADD = $(LDADD)
+pkfilter_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+	$(top_builddir)/src/algorithms/libalgorithms.a \
+	$(top_builddir)/src/imageclasses/libimageClasses.a
 am_pkgetmask_OBJECTS = pkgetmask.$(OBJEXT)
 pkgetmask_OBJECTS = $(am_pkgetmask_OBJECTS)
 pkgetmask_LDADD = $(LDADD)
@@ -186,6 +192,12 @@ pkstatogr_LDADD = $(LDADD)
 pkstatogr_DEPENDENCIES = $(am__DEPENDENCIES_1) \
 	$(top_builddir)/src/algorithms/libalgorithms.a \
 	$(top_builddir)/src/imageclasses/libimageClasses.a
+am_pkveg2shadow_OBJECTS = pkveg2shadow.$(OBJEXT)
+pkveg2shadow_OBJECTS = $(am_pkveg2shadow_OBJECTS)
+pkveg2shadow_LDADD = $(LDADD)
+pkveg2shadow_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+	$(top_builddir)/src/algorithms/libalgorithms.a \
+	$(top_builddir)/src/imageclasses/libimageClasses.a
 DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
@@ -207,7 +219,7 @@ SOURCES = $(pkascii2img_SOURCES) $(pkclassify_nn_SOURCES) \
 	$(pklas2img_SOURCES) $(pkmosaic_SOURCES) $(pkndvi_SOURCES) \
 	$(pkpolygonize_SOURCES) $(pkreclass_SOURCES) \
 	$(pksetmask_SOURCES) $(pksieve_SOURCES) $(pkstat_SOURCES) \
-	$(pkstatogr_SOURCES)
+	$(pkstatogr_SOURCES) $(pkveg2shadow_SOURCES)
 DIST_SOURCES = $(pkascii2img_SOURCES) \
 	$(am__pkclassify_nn_SOURCES_DIST) $(pkcreatect_SOURCES) \
 	$(pkcrop_SOURCES) $(pkdiff_SOURCES) $(pkdumpimg_SOURCES) \
@@ -217,7 +229,7 @@ DIST_SOURCES = $(pkascii2img_SOURCES) \
 	$(am__pklas2img_SOURCES_DIST) $(pkmosaic_SOURCES) \
 	$(pkndvi_SOURCES) $(pkpolygonize_SOURCES) $(pkreclass_SOURCES) \
 	$(pksetmask_SOURCES) $(pksieve_SOURCES) $(pkstat_SOURCES) \
-	$(pkstatogr_SOURCES)
+	$(pkstatogr_SOURCES) $(pkveg2shadow_SOURCES)
 ETAGS = etags
 CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -351,11 +363,12 @@ pkstat_SOURCES = $(top_srcdir)/src/algorithms/Histogram.h pkstat.cc
 pkstat_LDADD = $(GSL_LIBS) $(AM_LDFLAGS)
 pkstatogr_SOURCES = pkstatogr.cc
 pkegcs_SOURCES = pkegcs.cc
-pkegcs_LDADD = -lgdal $(AM_LDFLAGS) -lgdal
+#pkegcs_LDADD = -lgdal $(AM_LDFLAGS) -lgdal
 pkextract_SOURCES = pkextract.cc
 pkfillnodata_SOURCES = pkfillnodata.cc
 pkfilter_SOURCES = pkfilter.cc
-pkfilter_LDADD = -lgdal $(AM_LDFLAGS) -lgdal
+#pkfilter_LDADD = -lgdal $(AM_LDFLAGS) -lgdal
+pkveg2shadow_SOURCES = pkveg2shadow.cc
 pkmosaic_SOURCES = pkmosaic.cc
 pkndvi_SOURCES = pkndvi.cc
 pkpolygonize_SOURCES = pkpolygonize.cc
@@ -498,6 +511,9 @@ pkstat$(EXEEXT): $(pkstat_OBJECTS) $(pkstat_DEPENDENCIES)
 pkstatogr$(EXEEXT): $(pkstatogr_OBJECTS) $(pkstatogr_DEPENDENCIES) 
 	@rm -f pkstatogr$(EXEEXT)
 	$(CXXLINK) $(pkstatogr_OBJECTS) $(pkstatogr_LDADD) $(LIBS)
+pkveg2shadow$(EXEEXT): $(pkveg2shadow_OBJECTS) $(pkveg2shadow_DEPENDENCIES) 
+	@rm -f pkveg2shadow$(EXEEXT)
+	$(CXXLINK) $(pkveg2shadow_OBJECTS) $(pkveg2shadow_LDADD) $(LIBS)
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
@@ -527,6 +543,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/pksieve.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/pkstat.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/pkstatogr.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/pkveg2shadow.Po at am__quote@
 
 .cc.o:
 @am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
diff --git a/src/apps/pkascii2img.cc b/src/apps/pkascii2img.cc
index 5e56803..56490ad 100644
--- a/src/apps/pkascii2img.cc
+++ b/src/apps/pkascii2img.cc
@@ -43,7 +43,7 @@ int main(int argc, char *argv[])
   Optionpk<string> output_opt("o", "output", "Output image file", "");
   Optionpk<string> dataType_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", "");
   Optionpk<string> imageType_opt("of", "oformat", "image type string (default: GTiff, see also gdal_translate)", "GTiff");
-  Optionpk<string> option_opt("co", "co", "options: NAME=VALUE [-co COMPRESS=LZW] [-co INTERLEAVE=BAND]", "");
+  Optionpk<string> option_opt("co", "co", "options: NAME=VALUE [-co COMPRESS=LZW] [-co INTERLEAVE=BAND]");
   Optionpk<double> ulx_opt("ulx", "ulx", "Upper left x value bounding box (in geocoordinates if georef is true)", 0.0);
   Optionpk<double> uly_opt("uly", "uly", "Upper left y value bounding box (in geocoordinates if georef is true)", 0.0);
   Optionpk<double> dx_opt("dx", "dx", "Output resolution in x (in meter) (default is 0.0: keep original resolution)", 0.0);
diff --git a/src/apps/pkclassify_nn.cc b/src/apps/pkclassify_nn.cc
index 1920632..da4a53a 100644
--- a/src/apps/pkclassify_nn.cc
+++ b/src/apps/pkclassify_nn.cc
@@ -71,7 +71,7 @@ int main(int argc, char *argv[])
   Optionpk<string> output_opt("o", "output", "output classification image",""); 
   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", "");
   Optionpk<string>  oformat_opt("of", "oformat", "Output image format (see also gdal_translate). Empty string: inherit from input image", "");
-  Optionpk<string> option_opt("co", "co", "options: NAME=VALUE [-co COMPRESS=LZW] [-co INTERLEAVE=BAND]", "INTERLEAVE=BAND");
+  Optionpk<string> option_opt("co", "co", "options: NAME=VALUE [-co COMPRESS=LZW] [-co INTERLEAVE=BAND]");
   Optionpk<string> colorTable_opt("\0", "ct", "colour table in ascii format having 5 columns: id R G B ALFA (0: transparent, 255: solid)",""); 
   Optionpk<string> prob_opt("\0", "prob", "probability image. Default is no probability image",""); 
   Optionpk<short> verbose_opt("v", "verbose", "set to: 0 (results only), 1 (confusion matrix), 2 (debug)",0);
@@ -541,6 +541,11 @@ int main(int argc, char *argv[])
     }
     int nrow=testImage.nrOfRow();
     int ncol=testImage.nrOfCol();
+    if(option_opt.findSubstring("INTERLEAVE=")==option_opt.end()){
+      string theInterleave="INTERLEAVE=";
+      theInterleave+=testImage.getInterleave();
+      option_opt.push_back(theInterleave);
+    }
     vector<char> classOut(ncol);//classified line for writing to image file
 
     //   assert(nband==testImage.nrOfBand());
@@ -551,6 +556,7 @@ int main(int argc, char *argv[])
     if(oformat_opt[0]!="")//default
       imageType=oformat_opt[0];
     try{
+
       if(verbose_opt[0]>=1)
         cout << "opening class image for writing output " << output_opt[0] << endl;
       if(classBag_opt[0]!=""){
diff --git a/src/apps/pkcreatect.cc b/src/apps/pkcreatect.cc
index 69e33dc..ae9e59b 100644
--- a/src/apps/pkcreatect.cc
+++ b/src/apps/pkcreatect.cc
@@ -164,6 +164,12 @@ int main(int argc,char **argv) {
   if(input_opt[0]!=""&&output_opt[0]!=""){
     ImgReaderGdal imgReader(input_opt[0]);
     ImgWriterGdal imgWriter;
+    if(option_opt.findSubstring("INTERLEAVE=")==option_opt.end()){
+      string theInterleave="INTERLEAVE=";
+      theInterleave+=imgReader.getInterleave();
+      option_opt.push_back(theInterleave);
+    }
+
     imgWriter.open(output_opt[0],imgReader.nrOfCol(),imgReader.nrOfRow(),1,GDT_Byte,oformat_opt[0],option_opt);
 
     imgWriter.copyGeoTransform(imgReader);
diff --git a/src/apps/pkcrop.cc b/src/apps/pkcrop.cc
index 65a0475..562c179 100644
--- a/src/apps/pkcrop.cc
+++ b/src/apps/pkcrop.cc
@@ -21,6 +21,7 @@ along with pktools.  If not, see <http://www.gnu.org/licenses/>.
 #include <string>
 #include <list>
 #include <iostream>
+#include <algorithm>
 #include "imageclasses/ImgWriterGdal.h"
 #include "imageclasses/ImgReaderGdal.h"
 #include "imageclasses/ImgReaderOgr.h"
@@ -183,6 +184,12 @@ int main(int argc, char *argv[])
   //determine number of output bands
   int ncropband=0;//total number of bands to write
   int writeBand=0;//write band
+
+  while(scale_opt.size()<band_opt.size())
+    scale_opt.push_back(scale_opt[0]);
+  while(offset_opt.size()<band_opt.size())
+    offset_opt.push_back(offset_opt[0]);
+
   for(int iimg=0;iimg<input_opt.size();++iimg){
     imgReader.open(input_opt[iimg]);
     if(band_opt[0]>=0)
@@ -201,6 +208,11 @@ int main(int argc, char *argv[])
       if(verbose_opt[0])
         cout << "Using data type from input image: " << GDALGetDataTypeName(theType) << endl;
     }
+    if(option_opt.findSubstring("INTERLEAVE=")==option_opt.end()){
+      string theInterleave="INTERLEAVE=";
+      theInterleave+=imgReader.getInterleave();
+      option_opt.push_back(theInterleave);
+    }
     int nrow=imgReader.nrOfRow();
     int ncol=imgReader.nrOfCol();
     int ncropcol=0;
@@ -415,6 +427,8 @@ int main(int argc, char *argv[])
                 if(!valid)
                   writeBuffer.push_back(flag_opt[0]);
                 else{
+                  double theScale=(scale_opt.size()>1)?scale_opt[iband]:scale_opt[0];
+                  double theOffset=(offset_opt.size()>1)?offset_opt[iband]:offset_opt[0];
                   switch(theResample){
                   case(BILINEAR):
                     lowerCol=readCol-0.5;
@@ -425,12 +439,12 @@ int main(int argc, char *argv[])
                       lowerCol=0;
                     if(upperCol>=imgReader.nrOfCol())
                       upperCol=imgReader.nrOfCol()-1;
-                    writeBuffer.push_back((readCol-0.5-lowerCol)*(readBuffer[upperCol-startCol]*scale_opt[0]+offset_opt[0])+(1-readCol+0.5+lowerCol)*(readBuffer[lowerCol-startCol]*scale_opt[0]+offset_opt[0]));
+                    writeBuffer.push_back((readCol-0.5-lowerCol)*(readBuffer[upperCol-startCol]*theScale+theOffset)+(1-readCol+0.5+lowerCol)*(readBuffer[lowerCol-startCol]*theScale+theOffset));
                     break;
                   default:
                     readCol=static_cast<int>(readCol);
                     readCol-=startCol;//we only start reading from startCol
-                    writeBuffer.push_back(readBuffer[readCol]*scale_opt[0]+offset_opt[0]);
+                    writeBuffer.push_back(readBuffer[readCol]*theScale+theOffset);
                     break;
                   }
                 }
diff --git a/src/apps/pkdiff.cc b/src/apps/pkdiff.cc
index a68f6b3..e6b51b2 100644
--- a/src/apps/pkdiff.cc
+++ b/src/apps/pkdiff.cc
@@ -60,7 +60,7 @@ int main(int argc, char *argv[])
   Optionpk<short> boundary_opt("\0", "boundary", "boundary for selecting the sample (default: 1)", 1);
   Optionpk<bool> disc_opt("\0", "circular", "use circular disc kernel boundary)", false);
   Optionpk<bool> homogeneous_opt("\0", "homogeneous", "only take homogeneous regions into account", false);
-  Optionpk<string> option_opt("co", "co", "options: NAME=VALUE [-co COMPRESS=LZW] [-co INTERLEAVE=BAND]", "INTERLEAVE=BAND");
+  Optionpk<string> option_opt("co", "co", "options: NAME=VALUE [-co COMPRESS=LZW] [-co INTERLEAVE=BAND]");
   Optionpk<short> verbose_opt("v", "verbose", "verbose (default value is 0)", 0);
 
   version_opt.retrieveOption(argc,argv);
@@ -482,6 +482,11 @@ int main(int argc, char *argv[])
         if(verbose_opt[0])
           cout << "opening output image " << output_opt[0] << endl;
         string compression=(lzw_opt[0])? "LZW":"NONE";
+        if(option_opt.findSubstring("INTERLEAVE=")==option_opt.end()){
+          string theInterleave="INTERLEAVE=";
+          theInterleave+=inputReader.getInterleave();
+          option_opt.push_back(theInterleave);
+        }
         imgWriter.open(output_opt[0],inputReader.nrOfCol(),inputReader.nrOfRow(),1,inputReader.getDataType(),inputReader.getImageType(),option_opt);
 
         if(inputReader.isGeoRef()){
diff --git a/src/apps/pkfilter.cc b/src/apps/pkfilter.cc
index 4057d6b..88f86c3 100644
--- a/src/apps/pkfilter.cc
+++ b/src/apps/pkfilter.cc
@@ -134,6 +134,11 @@ int main(int argc,char **argv) {
   if(oformat_opt.size())
     imageType=oformat_opt[0];
 
+  if(option_opt.findSubstring("INTERLEAVE=")==option_opt.end()){
+    string theInterleave="INTERLEAVE=";
+    theInterleave+=input.getInterleave();
+    option_opt.push_back(theInterleave);
+  }
   try{
     output.open(output_opt[0],(input.nrOfCol()+down_opt[0]-1)/down_opt[0],(input.nrOfRow()+down_opt[0]-1)/down_opt[0],input.nrOfBand(),theType,imageType,option_opt);
   }
diff --git a/src/apps/pkgetmask.cc b/src/apps/pkgetmask.cc
index dddbede..fcc61c6 100644
--- a/src/apps/pkgetmask.cc
+++ b/src/apps/pkgetmask.cc
@@ -146,6 +146,11 @@ int main(int argc,char **argv) {
   string imageType=imgReader.getImageType();
   if(oformat_opt[0]!="")//default
     imageType=oformat_opt[0];
+  if(option_opt.findSubstring("INTERLEAVE=")==option_opt.end()){
+    string theInterleave="INTERLEAVE=";
+    theInterleave+=imgReader.getInterleave();
+    option_opt.push_back(theInterleave);
+  }
   imgWriter.open(output_opt[0],imgReader.nrOfCol(),imgReader.nrOfRow(),1,theType,imageType,option_opt);
   if(colorTable_opt[0]!=""){
     if(colorTable_opt[0]!="none")
diff --git a/src/apps/pkmosaic.cc b/src/apps/pkmosaic.cc
index 2091e23..1340409 100644
--- a/src/apps/pkmosaic.cc
+++ b/src/apps/pkmosaic.cc
@@ -186,14 +186,8 @@ int main(int argc, char *argv[])
   }
 
   ImgReaderGdal imgReader;
-  // GDALDataType dataType;
-  // string driverDescription;
   string theProjection="";
   GDALColorTable* theColorTable=NULL;
-  // string interleave;
-  // string compression;
-  string theCompression;
-  string theInterleave;
   string imageType;
   bool init=false;
   for(int ifile=0;ifile<input_opt.size();++ifile){
@@ -208,6 +202,11 @@ int main(int argc, char *argv[])
         theColorTable=(imgReader.getColorTable()->Clone());
     if(projection_opt[0]=="")
       theProjection=imgReader.getProjection();
+    if(option_opt.findSubstring("INTERLEAVE=")==option_opt.end()){
+      string theInterleave="INTERLEAVE=";
+      theInterleave+=imgReader.getInterleave();
+      option_opt.push_back(theInterleave);
+    }
 
     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]))){
       if(verbose_opt[0])
@@ -252,8 +251,6 @@ int main(int argc, char *argv[])
           break;
         }
       }
-//       nband=mrule_opt[0]!=6? imgReader.nrOfBand(): 2;//max voting: [winner class][number of votes]
-      // nband=imgReader.nrOfBand();
       if(band_opt[0]>=0){
 	nband=band_opt.size();
         bands.resize(band_opt.size());
diff --git a/src/apps/pkndvi.cc b/src/apps/pkndvi.cc
index 2db94e0..db40e7a 100644
--- a/src/apps/pkndvi.cc
+++ b/src/apps/pkndvi.cc
@@ -44,7 +44,7 @@ int main(int argc, char *argv[])
   Optionpk<string> input_opt("i","input","input image file","");
   Optionpk<string> output_opt("o","output","output image file containing ndvi","");
   Optionpk<short> band_opt("b", "band", "Bands to be used for vegetation index (see rule option)", 0);
-  Optionpk<string> rule_opt("r", "rule", "Rule for index. [ndvi (b1-b0)/(b1+b0)|gvmi (b0+0.1)-(b1+0.02))/((b0+0.1)+(b1+0.02)))|vari (b1-b2)/(b1+b2-b0)|osavi|mcari|tcari|diff (b1-b0)|scale|ratio.", "ndvi");
+  Optionpk<string> rule_opt("r", "rule", "Rule for index. [ndvi (b1-b0)/(b1+b0)|ndvi2 (b1-b0)/(b2+b3)|gvmi (b0+0.1)-(b1+0.02))/((b0+0.1)+(b1+0.02)))|vari (b1-b2)/(b1+b2-b0)|osavi|mcari|tcari|diff (b1-b0)|scale|ratio.", "ndvi");
   Optionpk<double> invalid_opt("t", "invalid", "Mask value where image is invalid.", 0);
   Optionpk<int> flag_opt("f", "flag", "Flag value to put in image if not valid (0)", 0);
   Optionpk<string> colorTable_opt("ct", "ct", "color table (file with 5 columns: id R G B ALFA (0: transparent, 255: solid)", "");
@@ -55,7 +55,7 @@ int main(int argc, char *argv[])
   Optionpk<double> offset_opt("off", "offset", "offset[0] is used for input, offset[1] is used for output (see also scale option", 0);
   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", "Byte");
   Optionpk<string> oformat_opt("of", "oformat", "Output image format (see also gdal_translate). Empty string: inherit from input image", "GTiff");
-  Optionpk<string> option_opt("co", "co", "options: NAME=VALUE [-co COMPRESS=LZW] [-co INTERLEAVE=BAND]", "INTERLEAVE=BAND");
+  Optionpk<string> option_opt("co", "co", "options: NAME=VALUE [-co COMPRESS=LZW] [-co INTERLEAVE=BAND]");
   Optionpk<short> verbose_opt("v", "verbose", "verbose mode if > 0", 0);
 
   version_opt.retrieveOption(argc,argv);
@@ -105,6 +105,7 @@ int main(int argc, char *argv[])
     else
       offset_opt.push_back(offset_opt[0]);
   }
+
   if(verbose_opt[0])
     std::cout << offset_opt;
   int reqBand=0;
@@ -112,10 +113,12 @@ int main(int argc, char *argv[])
     reqBand=1;
   else if(rule_opt[0]=="vari"||rule_opt[0]=="mcari"||rule_opt[0]=="tcari")
     reqBand=3;
+  else if(rule_opt[0]=="ndvi2")
+    reqBand=4;
   else
     reqBand=2;
-  while(band_opt.size()<reqBand)
-    band_opt.push_back(band_opt[0]);
+  while(band_opt.size()<reqBand)//bands can be explicitly provided by user or
+    band_opt.push_back(band_opt[0]);//default is to use band 0 for each input
   if(verbose_opt[0])
     std::cout << band_opt;
 
@@ -155,6 +158,12 @@ int main(int argc, char *argv[])
   ImgWriterGdal outputWriter;
   if(verbose_opt[0])
     cout << "opening output image file " << output_opt[0] << endl;
+
+  if(option_opt.findSubstring("INTERLEAVE=")==option_opt.end()){
+    string theInterleave="INTERLEAVE=";
+    theInterleave+=inputReader[0].getInterleave();
+    option_opt.push_back(theInterleave);
+  }
   outputWriter.open(output_opt[0],inputReader[0].nrOfCol(),inputReader[0].nrOfRow(),1,theType,oformat_opt[0],option_opt);
 
   if(description_opt[0]!="")
@@ -193,6 +202,12 @@ int main(int argc, char *argv[])
         inputReader[1].readData(lineInput[1],GDT_Float64,irow,band_opt[1]);
         inputReader[2].readData(lineInput[2],GDT_Float64,irow,band_opt[2]);
       }
+      else if(rule_opt[0]=="ndvi2"){
+        inputReader[0].readData(lineInput[0],GDT_Float64,irow,band_opt[0]);
+        inputReader[1].readData(lineInput[1],GDT_Float64,irow,band_opt[1]);
+        inputReader[2].readData(lineInput[2],GDT_Float64,irow,band_opt[2]);
+        inputReader[3].readData(lineInput[3],GDT_Float64,irow,band_opt[3]);
+      }
       else{
         inputReader[0].readData(lineInput[0],GDT_Float64,irow,band_opt[0]);
         inputReader[1].readData(lineInput[1],GDT_Float64,irow,band_opt[1]);
@@ -220,9 +235,28 @@ int main(int argc, char *argv[])
       double nom;
       if(valid){
         if(rule_opt[0]=="ndvi"){
+          //Example of indices addressed by ndvi:
+          //structural indices
+          //NDVI (Rouse1974): b0=b_680, b1=b_800
+          //Chlorophyll indices:
+          //Normalized Phaeophytinization index (NPQI Barnes1992): b0=R_435, b1=R_415
+          //Photochemical Reflectance index (PRI1 Gamon1992): b0=R_567, b1=R_528
+          //Photochemical Reflectance index (PRI2 Gamon1992): b0=R_570, b1=R_531
+          //Normalized Phaeophytinization index (NPQI Barnes1992): b0=R_435, b1=R_415
+          //Normalized Pigment Chlorophyll index (NPCI Penuelas1994): b0=R_430, b1=R_680
+          //Structure Intensive Pigment index (SIPI Penuelas 1995): b0=R_450, b1=R_800
+          //Lichtenthaler index 1 (Lic1 Lichtenthaler1996): b0=R_680, b2=R_800
           denom=(lineInput[1][icol]-offset_opt[0])/scale_opt[0]-(lineInput[0][icol]-offset_opt[0])/scale_opt[0];
           nom=(lineInput[1][icol]-offset_opt[0])/scale_opt[0]+(lineInput[0][icol]-offset_opt[0])/scale_opt[0];
         }
+        if(rule_opt[0]=="ndvi2"){//normalized difference with different wavelengths used in denom and nom
+          //Example of indices addressed by ndvi2
+          //Structure Intensive Pigment index (SIPI Penuelas 1995): b0=R_450, b1=R_800, b2=R_650, b=R_800
+          //Vogelmann index 2 (Vog2 Vogelmann1993): b0=R_747, b1=R_735, b2=R_715, b3=R_726
+          //Vogelmann index 3 (Vog3 Vogelmann1993): b0=R_747, b1=R_734, b2=R_715, b3=R_720
+          denom=(lineInput[1][icol]-offset_opt[0])/scale_opt[0]-(lineInput[0][icol]-offset_opt[0])/scale_opt[0];
+          nom=(lineInput[2][icol]-offset_opt[0])/scale_opt[0]+(lineInput[3][icol]-offset_opt[0])/scale_opt[0];
+        }
         else if(rule_opt[0]=="gvmi"){
           denom=((lineInput[0][icol]-offset_opt[0])/scale_opt[0]+0.1)-((lineInput[1][icol]-offset_opt[0])/scale_opt[0]+0.02);
           nom=((lineInput[0][icol]-offset_opt[0])/scale_opt[0]+0.1)+((lineInput[1][icol]-offset_opt[0])/scale_opt[0]+0.02);
@@ -231,15 +265,15 @@ int main(int argc, char *argv[])
           denom=(lineInput[1][icol]-offset_opt[0])/scale_opt[0]-(lineInput[2][icol]-offset_opt[0])/scale_opt[0];
           nom=(lineInput[1][icol]-offset_opt[0])/scale_opt[0]+(lineInput[2][icol]-offset_opt[0])/scale_opt[0]-(lineInput[0][icol]-offset_opt[0])/scale_opt[0];
         }
-        else if(rule_opt[0]=="osavi"){
+        else if(rule_opt[0]=="osavi"){//structural index (Rondeaux1996): //b0=R_670, b1=R_800
           denom=(1.0+0.16)*(lineInput[1][icol]-offset_opt[0])/scale_opt[0]-(lineInput[0][icol]-offset_opt[0])/scale_opt[0];
           nom=(lineInput[1][icol]-offset_opt[0])/scale_opt[0]+(lineInput[0][icol]-offset_opt[0])/scale_opt[0]+0.16;
         }
-        else if(rule_opt[0]=="mcari"){
+        else if(rule_opt[0]=="mcari"){//chlorophyll index (Daughtry2000): b0=R_550, b1=R_670, b2=R_700
           denom=((lineInput[2][icol]-offset_opt[0])/scale_opt[0]-(lineInput[1][icol]-offset_opt[0])/scale_opt[0]-0.2*((lineInput[2][icol]-offset_opt[0])/scale_opt[0]-(lineInput[0][icol]-offset_opt[0])/scale_opt[0]))*(lineInput[2][icol]-offset_opt[0])/scale_opt[0];
           nom=(lineInput[1][icol]-offset_opt[0])/scale_opt[0];
         }
-        else if(rule_opt[0]=="tcari"){
+        else if(rule_opt[0]=="tcari"){//chlorophyll index (Haboudane2002): b0=R_550, b1=R_670, B2=R_700
           denom=3*((lineInput[1][icol]-offset_opt[0])/scale_opt[0]*(lineInput[2][icol]-offset_opt[0])/scale_opt[0]-(lineInput[1][icol]-offset_opt[0])/scale_opt[0]-0.2*((lineInput[2][icol]-offset_opt[0])/scale_opt[0]-(lineInput[0][icol]-offset_opt[0])/scale_opt[0])*(lineInput[2][icol]-offset_opt[0])/scale_opt[0]);
           nom=(lineInput[1][icol]-offset_opt[0])/scale_opt[0];
         }
@@ -252,6 +286,19 @@ int main(int argc, char *argv[])
           nom=1.0;
         }
         else if(rule_opt[0]=="ratio"){
+          //Examples of indices addressed by ratio:
+          //structural indices:
+          //Simple Ratio Index (SR Jordan1969, Rouse1974): b0=R_NIR/R_RED
+          //chlorophyll indices:
+          //Greenness Index: b0=R_554, b1=R_677; 
+          //Zarco-Tejada&Miller (Zarco2001): b0=R_750,b1=R_710
+          //Simple Red Pigment Index (SRPI Penuelas1995): b0=R_430, b1=R_680
+          //Carter index 1 (Ctr1 Carter1994): b0=R_695, b1=R_420
+          //Carter index 2 (Ctr2 Carter1994): b0=R_695, b1=R_760
+          //Lichtenthaler index 2 (Lic2 Lichtenthaler1996): b0=R_440, b2=R_690
+          //Vogelmann index 1 (Vog1 Vogelmann1993): b0=R_740, b1=R_720
+          //Gitelson and Merzlyak 1 (GM1 Gitelson1997): b0=R_750 b1=R_550
+          //Gitelson and Merzlyak (GM2 Gitelson1997) b0=R_750 b1=R_700
           denom=(lineInput[0][icol]-offset_opt[0])/scale_opt[0];
           nom=(lineInput[1][icol]-offset_opt[0])/scale_opt[0];
         }
diff --git a/src/apps/pkreclass.cc b/src/apps/pkreclass.cc
index 44a0003..407b0c4 100644
--- a/src/apps/pkreclass.cc
+++ b/src/apps/pkreclass.cc
@@ -55,7 +55,7 @@ int main(int argc, char *argv[])
   Optionpk<string> class_opt("c", "class", "list of classes to reclass (in combination with reclass option)", "");
   Optionpk<string> reclass_opt("r", "reclass", "list of recoded class(es) (in combination with class option)", "");
   Optionpk<string> fieldname_opt("n", "fname", "field name of the shape file to be replaced", "label");
-  Optionpk<string> option_opt("co", "co", "options: NAME=VALUE [-co COMPRESS=LZW] [-co INTERLEAVE=BAND]", "INTERLEAVE=BAND");
+  Optionpk<string> option_opt("co", "co", "options: NAME=VALUE [-co COMPRESS=LZW] [-co INTERLEAVE=BAND]");
   Optionpk<string> description_opt("d", "description", "Set image description", "");
   Optionpk<short> verbose_opt("v", "verbose", "verbose", 0);
 
@@ -212,6 +212,11 @@ int main(int argc, char *argv[])
       theType=inputReader.getDataType();
     if(verbose_opt[0])
       cout << endl << "Output pixel type:  " << GDALGetDataTypeName(theType) << endl;
+    if(option_opt.findSubstring("INTERLEAVE=")==option_opt.end()){
+      string theInterleave="INTERLEAVE=";
+      theInterleave+=inputReader.getInterleave();
+      option_opt.push_back(theInterleave);
+    }
     outputWriter.open(output_opt[0],inputReader.nrOfCol(),inputReader.nrOfRow(),inputReader.nrOfBand(),theType,inputReader.getImageType(),option_opt);
     if(description_opt[0]!="")
       outputWriter.setImageDescription(description_opt[0]);
diff --git a/src/apps/pksetmask.cc b/src/apps/pksetmask.cc
index 356eddb..8b6f87d 100644
--- a/src/apps/pksetmask.cc
+++ b/src/apps/pksetmask.cc
@@ -50,7 +50,7 @@ int main(int argc, char *argv[])
   Optionpk<string> option_opt("co", "co", "options: NAME=VALUE [-co COMPRESS=LZW] [-co INTERLEAVE=BAND]");
   Optionpk<unsigned short> invalid_opt("t", "invalid", "Mask value(s) where image is invalid. Use one value for each mask, or multiple values for a single mask.", 1);
   Optionpk<char> operator_opt("p", "operator", "Operator: < = > !. Use operator for each invalid option", '=');
-  Optionpk<int> flag_opt("f", "flag", "Flag value to put in image if not valid (0)", 0);
+  Optionpk<int> flag_opt("f", "flag", "Flag value to put in image if not valid", 0);
   Optionpk<string> colorTable_opt("ct", "ct", "color table (file with 5 columns: id R G B ALFA (0: transparent, 255: solid)", "");
   Optionpk<short> verbose_opt("v", "verbose", "verbose", 0);
 
@@ -123,6 +123,11 @@ int main(int argc, char *argv[])
   }
   ImgWriterGdal outputWriter;
   try{
+    if(option_opt.findSubstring("INTERLEAVE=")==option_opt.end()){
+      string theInterleave="INTERLEAVE=";
+      theInterleave+=inputReader.getInterleave();
+      option_opt.push_back(theInterleave);
+    }
     outputWriter.open(output_opt[0],inputReader.nrOfCol(),inputReader.nrOfRow(),inputReader.nrOfBand(),theType,imageType,option_opt);
     outputWriter.setProjection(inputReader.getProjection());
     outputWriter.copyGeoTransform(inputReader);
diff --git a/src/apps/pkstatogr.cc b/src/apps/pkstatogr.cc
index 69df4ac..04862e1 100644
--- a/src/apps/pkstatogr.cc
+++ b/src/apps/pkstatogr.cc
@@ -47,6 +47,7 @@ int main(int argc, char *argv[])
   Optionpk<bool> min_opt("m","min","calculate minimum value",false);
   Optionpk<bool> max_opt("M","max","calculate maximum value",false);
   Optionpk<bool> mean_opt("mean","mean","calculate mean value",false);
+  Optionpk<bool> median_opt("median","median","calculate median value",false);
   Optionpk<bool> stdev_opt("stdev","stdev","calculate standard deviation",false);
   Optionpk<short> verbose_opt("v", "verbose", "verbose mode if > 0", 0);
 
@@ -61,6 +62,7 @@ int main(int argc, char *argv[])
   min_opt.retrieveOption(argc,argv);
   max_opt.retrieveOption(argc,argv);
   mean_opt.retrieveOption(argc,argv);
+  median_opt.retrieveOption(argc,argv);
   stdev_opt.retrieveOption(argc,argv);
   verbose_opt.retrieveOption(argc,argv);
 
@@ -74,7 +76,7 @@ int main(int argc, char *argv[])
     exit(0);
   }
   if(help_opt[0]){
-    std::cout << "usage: pkstatogr -i inputimage -n nbin -f field [-f field]" << std::endl;
+    std::cout << "usage: pkstatogr -i inputimage -n nbin -n fieldname [-n fieldname]" << std::endl;
     exit(0);
   }
 
@@ -104,7 +106,7 @@ int main(int argc, char *argv[])
     double theMean=0;
     double theVar=0;
     hist.meanVar(theData,theMean,theVar);
-    std::cout << " -f " << fieldname_opt[ifield];
+    std::cout << " --fname " << fieldname_opt[ifield];
     if(mean_opt[0])
       std::cout << " --mean " << theMean;
     if(stdev_opt[0])
@@ -113,6 +115,8 @@ int main(int argc, char *argv[])
       cout << " -m " << minimum;
     if(max_opt[0])
       cout << " -M " << maximum;
+    if(median_opt[0])
+      std::cout << " -median " << hist.median(theData);
     std::cout << std::endl;
     if(nbin_opt[0]>1){
       std::cout << std::endl;
diff --git a/src/base/Optionpk.h b/src/base/Optionpk.h
index 6547f99..baeabe5 100644
--- a/src/base/Optionpk.h
+++ b/src/base/Optionpk.h
@@ -120,8 +120,6 @@ public:
   Optionpk(const string& shortName, const string& longName, const string& helpInfo);
   Optionpk(const string& shortName, const string& longName, const string& helpInfo,const T& defaultValue);
   ~Optionpk();
-  void setAll(const string& shortName, const string& longName, const string& helpInfo);
-  void setAll(const string& shortName, const string& longName, const string& helpInfo,const T& defaultValue);
   void setHelp(const string& helpInfo){m_help=helpInfo;};
   string usage() const;
   static string getGPLv3License(){
@@ -139,19 +137,22 @@ public:
     You should have received a copy of the GNU General Public License\n\
     along with this program.  If not, see <http://www.gnu.org/licenses/>.\n");};
   string getHelp() const {return m_help;};
+  int retrieveOption(int argc, char ** argv);
+  std::vector<string>::const_iterator findSubstring(string argument) const;
+  template<class T1> friend ostream& operator<<(ostream & os, const Optionpk<T1>& theOption);
+private:
+  void setAll(const string& shortName, const string& longName, const string& helpInfo);
+  void setAll(const string& shortName, const string& longName, const string& helpInfo,const T& defaultValue);
   void setDefault(const T& defaultValue);
   string getDefaultValue() const {return m_defaultValue;};
   void setShortName(const string& shortName);
   void setLongName(const string& longName);
   string getShortName() const {return m_shortName;};
   string getLongName() const {return m_longName;};
-  bool hasArgument() const {return m_hasArgument;};
-  void hasArgument(bool flag){m_hasArgument=flag;};
+  bool hasArgument() const {return m_hasArgument;};//all options except bools should have arguments
   bool hasShortOption() const {return m_shortName.compare("\0");};
   bool hasLongOption() const {return m_longName.compare("\0");};
-  int retrieveOption(int argc, char ** argv);
-  template<class T1> friend ostream& operator<<(ostream & os, const Optionpk<T1>& theOption);
-private:
+
   string m_shortName;
   string m_longName;
   string m_help;
@@ -288,4 +289,14 @@ template<class T> int Optionpk<T>::retrieveOption(int argc, char **argv){
   return(this->size());
 }
 
+template<class T> std::vector<string>::const_iterator Optionpk<T>::findSubstring(string argument) const{
+  std::vector<string>::const_iterator opit=this->begin();
+  while(opit!=this->end()){
+    if(opit->find(argument)!=std::string::npos)
+      break;
+      ++opit;
+  }
+  return opit;
+}
+
 #endif
diff --git a/src/imageclasses/ImgWriterGdal.h b/src/imageclasses/ImgWriterGdal.h
index 59f70c9..fad06bc 100644
--- a/src/imageclasses/ImgWriterGdal.h
+++ b/src/imageclasses/ImgWriterGdal.h
@@ -67,6 +67,7 @@ public:
   template<typename T> bool writeData(vector<T>& buffer, const GDALDataType& dataType , int minCol, int maxCol, int row, int band=0) const;
   template<typename T> bool writeData(vector<T>& buffer, const GDALDataType& dataType, int row, int band=0) const;
   bool writeData(void* pdata, const GDALDataType& dataType, int band=0) const;
+  template<typename T> bool writeDataBlock(Vector2d<T>& buffer, const GDALDataType& dataType , int minCol, int maxCol, int minRow, int maxRow, int band=0) const;
   // string getInterleave(){return m_interleave;};
   // string getCompression(){return m_compression;};
   GDALDataType getDataType(int band=0) const;
@@ -128,6 +129,7 @@ template<typename T> bool ImgWriterGdal::writeData(T& value, const GDALDataType&
     throw(s.str());
   }
   poBand->RasterIO(GF_Write,col,row,1,1,&value,1,1,dataType,0,0);
+  return true;
 }
 
 template<typename T> bool ImgWriterGdal::writeData(vector<T>& buffer, const GDALDataType& dataType, int minCol, int maxCol, int row, int band) const
@@ -176,6 +178,7 @@ template<typename T> bool ImgWriterGdal::writeData(vector<T>& buffer, const GDAL
     throw(s.str());
   }
   poBand->RasterIO(GF_Write,minCol,row,buffer.size(),1,&(buffer[0]),buffer.size(),1,dataType,0,0);
+  return true;
 }
 
 template<typename T> bool ImgWriterGdal::writeData(vector<T>& buffer, const GDALDataType& dataType, int row, int band) const
@@ -198,6 +201,23 @@ template<typename T> bool ImgWriterGdal::writeData(vector<T>& buffer, const GDAL
     throw(s.str());
   }
   poBand->RasterIO(GF_Write,0,row,buffer.size(),1,&(buffer[0]),buffer.size(),1,dataType,0,0);
+  return true;
+}
+
+template<typename T> bool ImgWriterGdal::writeDataBlock(Vector2d<T>& buffer, const GDALDataType& dataType , int minCol, int maxCol, int minRow, int maxRow, int band) const
+{
+  //fetch raster band
+  GDALRasterBand  *poBand;
+  if(band>=nrOfBand()+1){
+    ostringstream s;
+    s << "band (" << band << ") exceeds nrOfBand (" << nrOfBand() << ")";
+    throw(s.str());
+  }
+  poBand = m_gds->GetRasterBand(band+1);//GDAL uses 1 based index
+  assert(buffer.size()==maxRow-minRow+1);
+  for(int irow=minRow;irow<=maxRow;++irow)
+    writeData(buffer[irow-minRow], dataType, minCol, maxCol, irow, band);
+  return true;
 }
 
 #endif // _IMGWRITERGDAL_H_

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/pktools.git



More information about the Pkg-grass-devel mailing list