pktools  2.6.3
Processing Kernel for geospatial data
pkstatogr.cc
1 /**********************************************************************
2 pkstatogr.cc: program to calculate basic statistics from vector file
3 Copyright (C) 2008-2012 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 <math.h>
21 #include <string>
22 #include <fstream>
23 #include <assert.h>
24 #include "base/Optionpk.h"
25 #include "imageclasses/ImgReaderOgr.h"
26 #include "algorithms/StatFactory.h"
27 
28 using namespace std;
29 
30 int main(int argc, char *argv[])
31 {
32  Optionpk<string> input_opt("i", "input", "Input OGR vector file", "");
33  Optionpk<string> layer_opt("ln", "lname", "Layer name(s) in sample (leave empty to select all)");
34  Optionpk<string> fieldname_opt("n", "fname", "Fields on which to calculate statistics", "");
35  Optionpk<double> nodata_opt("nodata","nodata","Set nodata value(s)");
36  Optionpk<double> src_min_opt("src_min","src_min","Set minimum value for histogram");
37  Optionpk<double> src_max_opt("src_max","src_max","Set maximum value for histogram");
38  Optionpk<bool> size_opt("s","size","Sample size (number of points)",false);
39  Optionpk<bool> minmax_opt("mm","minmax","Calculate minimum and maximum value",false);
40  Optionpk<bool> min_opt("min","min","Calculate minimum value",0);
41  Optionpk<bool> max_opt("max","max","Calculate maximum value",0);
42  Optionpk<bool> mean_opt("mean","mean","Calculate mean value",false);
43  Optionpk<bool> median_opt("median","median","Calculate median value",false);
44  Optionpk<bool> stdev_opt("stdev","stdev","Calculate standard deviation",false);
45  Optionpk<bool> histogram_opt("hist","hist","Calculate histogram",false);
46  Optionpk<unsigned int> nbin_opt("nbin", "nbin", "Number of bins");
47  Optionpk<bool> relative_opt("rel","relative","Use percentiles for histogram to calculate histogram",false);
48  Optionpk<bool> kde_opt("kde","kde","Use Kernel density estimation when producing histogram. The standard deviation is estimated based on Silverman's rule of thumb",false);
49  Optionpk<short> verbose_opt("v", "verbose", "Verbose level", 0,2);
50 
51  bool doProcess;//stop process when program was invoked with help option (-h --help)
52  try{
53  doProcess=input_opt.retrieveOption(argc,argv);
54  fieldname_opt.retrieveOption(argc,argv);
55  layer_opt.retrieveOption(argc,argv);
56  nodata_opt.retrieveOption(argc,argv);
57  src_min_opt.retrieveOption(argc,argv);
58  src_max_opt.retrieveOption(argc,argv);
59  size_opt.retrieveOption(argc,argv);
60  minmax_opt.retrieveOption(argc,argv);
61  min_opt.retrieveOption(argc,argv);
62  max_opt.retrieveOption(argc,argv);
63  mean_opt.retrieveOption(argc,argv);
64  median_opt.retrieveOption(argc,argv);
65  stdev_opt.retrieveOption(argc,argv);
66  histogram_opt.retrieveOption(argc,argv);
67  nbin_opt.retrieveOption(argc,argv);
68  relative_opt.retrieveOption(argc,argv);
69  kde_opt.retrieveOption(argc,argv);
70  verbose_opt.retrieveOption(argc,argv);
71  }
72  catch(string predefinedString){
73  cout << predefinedString << endl;
74  exit(0);
75  }
76  if(!doProcess){
77  cout << endl;
78  cout << "Usage: pkstatogr -i input [-n attribute]*" << endl;
79  cout << endl;
80  cout << "short option -h shows basic options only, use long option --help to show all options" << endl;
81  exit(0);//help was invoked, stop processing
82  }
83 
84  ImgReaderOgr imgReader;
85  try{
86  imgReader.open(input_opt[0]);
87  }
88  catch(string errorstring){
89  cerr << errorstring << endl;
90  }
91 
92  ImgReaderOgr inputReader(input_opt[0]);
93  vector<double> theData;
95  //todo: implement ALL
96 
97  stat.setNoDataValues(nodata_opt);
98 
99  //support multiple layers
100  int nlayerRead=inputReader.getDataSource()->GetLayerCount();
101  if(verbose_opt[0])
102  cout << "number of layers: " << nlayerRead << endl;
103 
104  for(int ilayer=0;ilayer<nlayerRead;++ilayer){
105  OGRLayer *readLayer=inputReader.getLayer(ilayer);
106  string currentLayername=readLayer->GetName();
107  if(layer_opt.size())
108  if(find(layer_opt.begin(),layer_opt.end(),currentLayername)==layer_opt.end())
109  continue;
110  if(verbose_opt[0])
111  cout << "processing layer " << currentLayername << endl;
112  if(layer_opt.size())
113  cout << " --lname " << currentLayername;
114 
115  for(int ifield=0;ifield<fieldname_opt.size();++ifield){
116  if(verbose_opt[0])
117  cout << "field: " << ifield << endl;
118  theData.clear();
119  inputReader.readData(theData,OFTReal,fieldname_opt[ifield],ilayer,verbose_opt[0]);
120  vector<double> binData;
121  double minValue=0;
122  double maxValue=0;
123  stat.minmax(theData,theData.begin(),theData.end(),minValue,maxValue);
124  if(src_min_opt.size())
125  minValue=src_min_opt[0];
126  if(src_max_opt.size())
127  maxValue=src_max_opt[0];
128  unsigned int nbin=(nbin_opt.size())? nbin_opt[0]:0;
129 
130  if(histogram_opt[0]){
131  double sigma=0;
132  if(kde_opt[0]){
133  // if(kde_opt[0]>0)
134  // sigma=kde_opt[0];
135  // else
136  sigma=1.06*sqrt(stat.var(theData))*pow(theData.size(),-0.2);
137  }
138  if(nbin<1)
139  nbin=(maxValue-minValue+1);
140  try{
141  stat.distribution(theData,theData.begin(),theData.end(),binData,nbin,minValue,maxValue,sigma);
142  }
143  catch(string theError){
144  cerr << "Warning: all identical values in data" << endl;
145  exit(1);
146  }
147  }
148  // int nbin=(nbin_opt[0]>1)? nbin_opt[0] : 2;
149  cout << " --fname " << fieldname_opt[ifield];
150  try{
151  double theMean=0;
152  double theVar=0;
153  stat.meanVar(theData,theMean,theVar);
154  if(mean_opt[0])
155  cout << " --mean " << theMean;
156  if(stdev_opt[0])
157  cout << " --stdev " << sqrt(theVar);
158  if(minmax_opt[0]||min_opt[0]||max_opt[0]){
159  if(minmax_opt[0])
160  cout << " --min " << minValue << " --max " << maxValue << " ";
161  else{
162  if(min_opt[0])
163  cout << " --min " << minValue << " ";
164  if(max_opt[0])
165  cout << " --max " << maxValue << " ";
166  }
167  }
168  if(median_opt[0])
169  cout << " -median " << stat.median(theData);
170  if(size_opt[0])
171  cout << " -size " << theData.size();
172  cout << endl;
173  if(histogram_opt[0]){
174  for(int ibin=0;ibin<nbin;++ibin){
175  double binValue=0;
176  if(nbin==maxValue-minValue+1)
177  binValue=minValue+ibin;
178  else
179  binValue=minValue+static_cast<double>(maxValue-minValue)*(ibin+0.5)/nbin;
180  cout << binValue << " ";
181  if(relative_opt[0]||kde_opt[0])
182  cout << 100.0*static_cast<double>(binData[ibin])/theData.size() << endl;
183  else
184  cout << binData[ibin] << endl;
185  }
186  }
187  }
188  catch(string theError){
189  if(mean_opt[0])
190  cout << " --mean " << theData.back();
191  if(stdev_opt[0])
192  cout << " --stdev " << "0";
193  if(min_opt[0])
194  cout << " -min " << theData.back();
195  if(max_opt[0])
196  cout << " -max " << theData.back();
197  if(median_opt[0])
198  cout << " -median " << theData.back();
199  if(size_opt[0])
200  cout << " -size " << theData.size();
201  cout << endl;
202  cerr << "Warning: all identical values in data" << endl;
203  }
204  }
205  }
206  imgReader.close();
207 }
208