pktools  2.6.7
Processing Kernel for geospatial data
pkcreatect.cc
1 /**********************************************************************
2 pkcreatect.cc: program to create and import colour table to GTiff 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 <iostream>
21 #include "imageclasses/ImgReaderGdal.h"
22 #include "imageclasses/ImgWriterGdal.h"
23 #include "base/Optionpk.h"
24 
25 /******************************************************************************/
71 using namespace std;
72 
73 int main(int argc,char **argv) {
74 
75  short red=-1;
76  short green=-1;
77  short blue=-1;
78 
79  Optionpk<string> input_opt("i", "input", "Input image file");
80  Optionpk<string> output_opt("o", "output", "Output image file");
81  Optionpk<string> legend_opt("l", "legend", "Create legend as png file");
82  Optionpk<short> dim_opt("dim", "dim", "number of columns and rows in legend.", 100);
83  Optionpk<double> min_opt("min", "min", "minimum value", 0);
84  Optionpk<double> max_opt("max", "max", "maximum value", 100);
85  Optionpk<bool> grey_opt("g", "grey", "grey scale", false);
86  Optionpk<string> colorTable_opt("ct", "ct", "color table (file with 5 columns: id R G B ALFA (0: transparent, 255: solid)");
87  Optionpk<string> oformat_opt("of", "oformat", "Output image format (see also gdal_translate).", "GTiff");
88  Optionpk<string> option_opt("co", "co", "Creation option for output file. Multiple options can be specified.");
89  Optionpk<string> description_opt("d", "description", "Set image description");
90  Optionpk<bool> verbose_opt("v", "verbose", "verbose", false,2);
91 
92  legend_opt.setHide(1);
93  dim_opt.setHide(1);
94 
95  bool doProcess;//stop process when program was invoked with help option (-h --help)
96  try{
97  doProcess=input_opt.retrieveOption(argc,argv);
98  output_opt.retrieveOption(argc,argv);
99  legend_opt.retrieveOption(argc,argv);
100  dim_opt.retrieveOption(argc,argv);
101  min_opt.retrieveOption(argc,argv);
102  max_opt.retrieveOption(argc,argv);
103  grey_opt.retrieveOption(argc,argv);
104  colorTable_opt.retrieveOption(argc,argv);
105  description_opt.retrieveOption(argc,argv);
106  oformat_opt.retrieveOption(argc,argv);
107  option_opt.retrieveOption(argc,argv);
108  verbose_opt.retrieveOption(argc,argv);
109  }
110  catch(string predefinedString){
111  std::cout << predefinedString << std::endl;
112  exit(0);
113  }
114  if(!doProcess){
115  cout << endl;
116  cout << "Usage: pkcreatect -i input.txt -o output [-ct colortable | -min value -max value]" << endl;
117  cout << endl;
118  std::cout << "short option -h shows basic options only, use long option --help to show all options" << std::endl;
119  exit(0);//help was invoked, stop processing
120  }
121 
122  GDALColorTable colorTable;
123  GDALColorEntry sEntry;
124  if(colorTable_opt.empty()){
125  sEntry.c4=255;
126  for(int i=min_opt[0];i<=max_opt[0];++i){
127  if(grey_opt[0]){
128  sEntry.c1=255*(i-min_opt[0])/(max_opt[0]-min_opt[0]);
129  sEntry.c2=255*(i-min_opt[0])/(max_opt[0]-min_opt[0]);
130  sEntry.c3=255*(i-min_opt[0])/(max_opt[0]-min_opt[0]);
131  }
132  else{//hot to cold colour ramp
133  sEntry.c1=255;
134  sEntry.c2=255;
135  sEntry.c3=255;
136  double delta=max_opt[0]-min_opt[0];
137  if(i<(min_opt[0]+0.25*delta)){
138  sEntry.c1=0;
139  sEntry.c2=255*4*(i-min_opt[0])/delta;
140  }
141  else if(i<(min_opt[0]+0.5*delta)){
142  sEntry.c1=0;
143  sEntry.c3=255*(1+4*(min_opt[0]+0.25*delta-i)/delta);
144  }
145  else if(i<(min_opt[0]+0.75*delta)){
146  sEntry.c1=255*4*(i-min_opt[0]-0.5*delta)/delta;
147  sEntry.c3=0;
148  }
149  else{
150  sEntry.c2=255*(1+4*(min_opt[0]+0.75*delta-i)/delta);
151  sEntry.c3=0;
152  }
153  }
154  colorTable.SetColorEntry(i,&sEntry);
155  if(output_opt.empty())
156  cout << i << " " << sEntry.c1 << " " << sEntry.c2 << " " << sEntry.c3 << " " << sEntry.c4 << endl;
157  }
158  }
159  ImgWriterGdal legendWriter;
160  short ncol=dim_opt[0];
161  short nrow;
162  if(legend_opt.size()){
163  if(dim_opt.size()>1)
164  nrow=dim_opt[1];
165  else{
166  nrow=max_opt[0]-min_opt[0]+1;
167  ncol=dim_opt[0];
168  }
169  vector<string> pngOption;
170  // pngOption.push_back("-co worldfile=no");
171  pngOption.push_back("");
172  legendWriter.open(legend_opt[0],ncol,nrow,1,GDT_Byte,oformat_opt[0],option_opt);
173  if(colorTable_opt.size()){
174  if(colorTable_opt[0]!="none")
175  legendWriter.setColorTable(colorTable_opt[0]);
176  }
177  else
178  legendWriter.setColorTable(&colorTable);
179  if(legend_opt.size()){
180  for(int irow=0;irow<legendWriter.nrOfRow();++irow){
181  vector<char> buffer(legendWriter.nrOfCol());
182  for(int icol=0;icol<legendWriter.nrOfCol();++icol)
183  buffer[icol]=min_opt[0]+irow*static_cast<short>(max_opt[0]-min_opt[0]+1)/legendWriter.nrOfRow();
184  legendWriter.writeData(buffer,legendWriter.nrOfRow()-1-irow);
185  }
186  }
187  }
188 
189  // const char* pszMessage;
190  // void* pProgressArg=NULL;
191  // GDALProgressFunc pfnProgress=GDALTermProgress;
192  // double progress=0;
193  // pfnProgress(progress,pszMessage,pProgressArg);
194  if(input_opt.size()&&output_opt.size()){
195  ImgReaderGdal imgReader(input_opt[0]);
196  ImgWriterGdal imgWriter;
197  if(option_opt.findSubstring("INTERLEAVE=")==option_opt.end()){
198  string theInterleave="INTERLEAVE=";
199  theInterleave+=imgReader.getInterleave();
200  option_opt.push_back(theInterleave);
201  }
202 
203  imgWriter.open(output_opt[0],imgReader.nrOfCol(),imgReader.nrOfRow(),1,GDT_Byte,oformat_opt[0],option_opt);
204 
205  imgWriter.copyGeoTransform(imgReader);
206  if(colorTable_opt.size()){
207  if(colorTable_opt[0]!="none")
208  imgWriter.setColorTable(colorTable_opt[0]);
209  }
210  else
211  imgWriter.setColorTable(&colorTable);
212  if(description_opt.size())
213  imgWriter.setImageDescription(description_opt[0]);
214  switch(imgReader.getDataType()){
215  case(GDT_Byte):{
216  vector<char> buffer;
217  for(int irow=0;irow<imgReader.nrOfRow();++irow){
218  imgReader.readData(buffer,irow);
219  imgWriter.writeData(buffer,irow);
220  }
221  break;
222  }
223  case(GDT_Int16):{
224  vector<short> buffer;
225  cout << "Warning: copying short to unsigned short without conversion, use gdal_translate -scale if needed..." << endl;
226  for(int irow=0;irow<imgReader.nrOfRow();++irow){
227  imgReader.readData(buffer,irow,0);
228  imgWriter.writeData(buffer,irow,0);
229  }
230  break;
231  }
232  case(GDT_UInt16):{
233  vector<unsigned short> buffer;
234  for(int irow=0;irow<imgReader.nrOfRow();++irow){
235  imgReader.readData(buffer,irow,0);
236  imgWriter.writeData(buffer,irow,0);
237  }
238  break;
239  }
240  default:
241  cerr << "data type " << imgReader.getDataType() << " not supported for adding a colortable" << endl;
242  break;
243  }
244  imgReader.close();
245  imgWriter.close();
246  }
247  if(legend_opt.size())
248  legendWriter.close();
249 }
250 
void setImageDescription(const std::string &imageDescription)
Set the image description (only for GeoTiff format: TIFFTAG_IMAGEDESCRIPTION)
Definition: ImgWriterGdal.h:55
STL namespace.
int nrOfRow(void) const
Get the number of rows 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)
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...
Definition: ImgWriterGdal.h:96
void copyGeoTransform(const ImgRasterGdal &imgSrc)
Copy geotransform information from another georeferenced image.
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...
std::string getInterleave() const
Get the band coding (interleave)
void close(void)
Close the image.
int nrOfCol(void) const
Get the number of columns of this dataset.
Definition: ImgRasterGdal.h:98