pktools 2.6.7
Processing Kernel for geospatial data
pkcreatect.cc
1/**********************************************************************
2pkcreatect.cc: program to create and import colour table to GTiff image
3Copyright (C) 2008-2014 Pieter Kempeneers
4
5This file is part of pktools
6
7pktools is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation, either version 3 of the License, or
10(at your option) any later version.
11
12pktools is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along 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/******************************************************************************/
71using namespace std;
72
73int 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
int nrOfRow(void) const
Get the number of rows of this dataset.
void copyGeoTransform(const ImgRasterGdal &imgSrc)
Copy geotransform information from another georeferenced image.
int nrOfCol(void) const
Get the number of columns of this dataset.
Definition: ImgRasterGdal.h:98
std::string getInterleave() const
Get the band coding (interleave)
void close(void)
Close the 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...
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)
void setImageDescription(const std::string &imageDescription)
Set the image description (only for GeoTiff format: TIFFTAG_IMAGEDESCRIPTION)
Definition: ImgWriterGdal.h:55
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