pktools 2.6.7
Processing Kernel for geospatial data
pkreclassogr.cc
1/**********************************************************************
2pkreclassogr.cc: program to replace field values of attributes in vector dataset
3Copyright (C) 2008-2017 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 <assert.h>
21#include <map>
22#include "base/Optionpk.h"
23#include "imageclasses/ImgReaderOgr.h"
24#include "imageclasses/ImgWriterOgr.h"
25#include "imageclasses/ImgReaderGdal.h"
26#include "imageclasses/ImgWriterGdal.h"
27
28/******************************************************************************/
59using namespace std;
60
61int main(int argc, char *argv[])
62{
63 Optionpk<string> input_opt("i", "input", "Input vector dataset");
64 Optionpk<string> output_opt("o", "output", "Output file");
65 Optionpk<int> nodata_opt("nodata", "nodata", "nodata value to put in vector dataset if not valid (0)", 0);
66 Optionpk<string> code_opt("code", "code", "Recode text file (2 columns: from to)");
67 Optionpk<string> class_opt("c", "class", "list of classes to reclass (in combination with reclass option)");
68 Optionpk<string> reclass_opt("r", "reclass", "list of recoded classes (in combination with class option)");
69 Optionpk<string> fieldname_opt("n", "fname", "field name of the shape file to be replaced", "label");
70 Optionpk<short> verbose_opt("v", "verbose", "verbose", 0);
71
72 bool doProcess;//stop process when program was invoked with help option (-h --help)
73 try{
74 doProcess=input_opt.retrieveOption(argc,argv);
75 nodata_opt.retrieveOption(argc,argv);
76 code_opt.retrieveOption(argc,argv);
77 class_opt.retrieveOption(argc,argv);
78 reclass_opt.retrieveOption(argc,argv);
79 output_opt.retrieveOption(argc,argv);
80 fieldname_opt.retrieveOption(argc,argv);
81 verbose_opt.retrieveOption(argc,argv);
82 }
83 catch(string predefinedString){
84 std::cout << predefinedString << std::endl;
85 exit(0);
86 }
87 if(!doProcess){
88 cout << endl;
89 cout << "Usage: pkreclassogr -i input [-c from -r to]* -o output" << endl;
90 cout << endl;
91 std::cout << "short option -h shows basic options only, use long option --help to show all options" << std::endl;
92 exit(0);//help was invoked, stop processing
93 }
94
95 if(input_opt.empty()){
96 std::cerr << "No input file provided (use option -i). Use --help for help information" << std::endl;
97 exit(0);
98 }
99 if(output_opt.empty()){
100 std::cerr << "No output file provided (use option -o). Use --help for help information" << std::endl;
101 exit(0);
102 }
103
104 // vector<short> bandVector;
105 map<string,string> codemapString;//map with codes: codemapString[theKey(from)]=theValue(to)
106 map<double,double> codemap;//map with codes: codemap[theKey(from)]=theValue(to)
107 if(code_opt.size()){
108 if(verbose_opt[0])
109 cout << "opening code text file " << code_opt[0] << endl;
110 ifstream codefile;
111 codefile.open(code_opt[0].c_str());
112 string theKey;
113 string theValue;
114 while(codefile>>theKey){
115 codefile >> theValue;
116 codemapString[theKey]=theValue;
117 codemap[string2type<double>(theKey)]=string2type<double>(theValue);
118 }
119 codefile.close();
120 }
121 else{//use combination of class_opt and reclass_opt
122 assert(class_opt.size()==reclass_opt.size());
123 for(int iclass=0;iclass<class_opt.size();++iclass){
124 codemapString[class_opt[iclass]]=reclass_opt[iclass];
125 codemap[string2type<double>(class_opt[iclass])]=string2type<double>(reclass_opt[iclass]);
126 }
127 }
128 assert(codemapString.size());
129 assert(codemap.size());
130 //if verbose true, print the codes to screen
131 if(verbose_opt[0]){
132 map<string,string>::iterator mit;
133 cout << codemapString.size() << " codes used: " << endl;
134 for(mit=codemapString.begin();mit!=codemapString.end();++mit)
135 cout << (*mit).first << " " << (*mit).second << endl;
136 }
137 bool refIsRaster=false;
138 ImgReaderOgr ogrReader;
139 try{
140 ogrReader.open(input_opt[0]);
141 }
142 catch(string errorString){
143 refIsRaster=true;
144 }
145 if(!refIsRaster){
146 if(verbose_opt[0])
147 cout << "opening " << input_opt[0] << " for reading " << endl;
148 // ImgReaderOgr ogrReader(input_opt[0]);
149 if(verbose_opt[0])
150 cout << "opening " << output_opt[0] << " for writing " << endl;
151 ImgWriterOgr ogrWriter(output_opt[0],ogrReader);
152 if(verbose_opt[0])
153 cout << "copied layer from " << input_opt[0] << endl << flush;
154 OGRFeatureDefn *poFDefn = ogrWriter.getLayer()->GetLayerDefn();
155 //start reading features from the layer
156 if(verbose_opt[0])
157 cout << "reset reading" << endl;
158 ogrReader.getLayer()->ResetReading();
159 unsigned long int ifeature=0;
160 if(verbose_opt[0])
161 cout << "going through features" << endl << flush;
162 while(true){
163 // while( (poFeature = ogrWriter.getLayer()->GetNextFeature()) != NULL ){
164 OGRFeature *poFeature;
165 poFeature=ogrReader.getLayer()->GetNextFeature();
166 if(poFeature== NULL)
167 break;
168 OGRFeatureDefn *poFDefn = ogrWriter.getLayer()->GetLayerDefn();
169 string featurename;
170 for(int iField=0;iField<poFDefn->GetFieldCount();++iField){
171 OGRFieldDefn *poFieldDefn = poFDefn->GetFieldDefn(iField);
172 string fieldname=poFieldDefn->GetNameRef();
173 if(fieldname==fieldname_opt[0]){
174 string fromClass=poFeature->GetFieldAsString(iField);
175 string toClass=fromClass;
176 if(codemapString.find(fromClass)!=codemapString.end())
177 toClass=codemapString[fromClass];
178 poFeature->SetField(iField,toClass.c_str());
179 if(verbose_opt[0])
180 cout << "feature " << ifeature << ": " << fromClass << "->" << poFeature->GetFieldAsInteger(iField) << endl << flush;
181 // cout << "feature " << ifeature << ": " << fromClass << "->" << toClass << endl << flush;
182 }
183 }
184 //do not forget to actually write feature to file!!!
185 ogrWriter.createFeature(poFeature);
186 OGRFeature::DestroyFeature( poFeature );
187 ++ifeature;
188 }
189 if(verbose_opt[0])
190 cout << "replaced " << ifeature << " features" << endl;
191 ogrReader.close();
192 ogrWriter.close();
193 }
194}