pktools  2.6.3
Processing Kernel for geospatial data
pksieve.cc
1 /**********************************************************************
2 pksieve.cc: program to sieve filter raster image
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 "cpl_string.h"
21 #include "gdal_priv.h"
22 #include "gdal.h"
23 #include "imageclasses/ImgReaderGdal.h"
24 #include "imageclasses/ImgWriterGdal.h"
25 // #include "imageclasses/ImgWriterOgr.h"
26 #include "base/Optionpk.h"
27 #include "ogrsf_frmts.h"
28 extern "C" {
29 #include "gdal_alg.h"
30 #include "ogr_api.h"
31 }
32 
33 using namespace std;
34 
35 int main(int argc,char **argv) {
36  Optionpk<string> input_opt("i", "input", "Input image file");
37  Optionpk<string> mask_opt("m", "mask", "Use the first band of the specified file as a validity mask (zero is invalid, non-zero is valid).");
38  Optionpk<string> output_opt("o", "output", "Output image file");
39  Optionpk<int> band_opt("b", "band", "the band to be used from input file", 0);
40  Optionpk<int> connect_opt("c", "connect", "the connectedness: 4 directions or 8 directions", 8);
41  Optionpk<int> size_opt("s", "size", "raster polygons with sizes smaller than this will be merged into their largest neighbour. No sieve is performed if size = 0", 0);
42  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", "");
43  Optionpk<string> option_opt("co", "co", "Creation option for output file. Multiple options can be specified.");
44  Optionpk<string> colorTable_opt("ct", "ct", "color table (file with 5 columns: id R G B ALFA (0: transparent, 255: solid)");
45  Optionpk<short> verbose_opt("v", "verbose", "verbose mode if > 0", 0,2);
46 
47  bool doProcess;//stop process when program was invoked with help option (-h --help)
48  try{
49  doProcess=input_opt.retrieveOption(argc,argv);
50  size_opt.retrieveOption(argc,argv);
51  output_opt.retrieveOption(argc,argv);
52  connect_opt.retrieveOption(argc,argv);
53  band_opt.retrieveOption(argc,argv);
54  mask_opt.retrieveOption(argc,argv);
55  otype_opt.retrieveOption(argc,argv);
56  option_opt.retrieveOption(argc,argv);
57  colorTable_opt.retrieveOption(argc,argv);
58  verbose_opt.retrieveOption(argc,argv);
59  }
60  catch(string predefinedString){
61  std::cout << predefinedString << std::endl;
62  exit(0);
63  }
64  if(!doProcess){
65  cout << endl;
66  cout << "Usage: pksieve -i input [-s size] -o output" << endl;
67  cout << endl;
68  std::cout << "short option -h shows basic options only, use long option --help to show all options" << std::endl;
69  exit(0);//help was invoked, stop processing
70  }
71 
72  GDALAllRegister();
73 
74  double dfComplete=0.0;
75  const char* pszMessage;
76  void* pProgressArg=NULL;
77  GDALProgressFunc pfnProgress=GDALTermProgress;
78  pfnProgress(dfComplete,pszMessage,pProgressArg);
79 
80  ImgReaderGdal maskReader;
81  GDALRasterBand *maskBand=NULL;
82  if(mask_opt.size()){
83  if(verbose_opt[0])
84  cout << "opening mask file " << mask_opt[0] << endl;
85  maskReader.open(mask_opt[0]);
86  maskBand = maskReader.getRasterBand(0);
87  }
88 
89  assert(input_opt.size());
90  assert(output_opt.size());
91  ImgReaderGdal inputReader(input_opt[0]);
92  GDALRasterBand *inputBand;
93  inputBand=inputReader.getRasterBand(band_opt[0]);
94 
95  ImgWriterGdal outputWriter;
96  GDALRasterBand *outputBand=NULL;
97  if(verbose_opt[0])
98  cout << "opening output file " << output_opt[0] << endl;
99  outputWriter.open(output_opt[0],inputReader);
100  if(colorTable_opt.size()){
101  if(colorTable_opt[0]!="none")
102  outputWriter.setColorTable(colorTable_opt[0]);
103  }
104  else if (inputReader.getColorTable()!=NULL)//copy colorTable from input image
105  outputWriter.setColorTable(inputReader.getColorTable());
106  outputBand = outputWriter.getRasterBand(0);
107  //sieve filter to remove small raster elements (overwrite input band)
108  if(size_opt[0]){
109  if(GDALSieveFilter((GDALRasterBandH)inputBand, (GDALRasterBandH)maskBand, (GDALRasterBandH)outputBand, size_opt[0], connect_opt[0],NULL,pfnProgress,pProgressArg)!=CE_None)
110  cerr << CPLGetLastErrorMsg() << endl;
111  else{
112  dfComplete=1.0;
113  pfnProgress(dfComplete,pszMessage,pProgressArg);
114  }
115  }
116  inputReader.close();
117  if(mask_opt.size())
118  maskReader.close();
119  outputWriter.close();
120 }
121