pktools  2.6.3
Processing Kernel for geospatial data
ImgReaderOgr.cc
1 /**********************************************************************
2 ImgReaderOgr.cc: class to read vector files using OGR API library
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 <iostream>
21 #include <fstream>
22 #include "ImgReaderOgr.h"
23 #include "ImgWriterOgr.h"
24 #include "cpl_string.h"
25 //---------------------------------------------------------------------------
26 ImgReaderOgr::ImgReaderOgr(void)
27 {}
28 
29 ImgReaderOgr::ImgReaderOgr(const std::string& filename)
30 {
31  open(filename);
32 }
33 
34 ImgReaderOgr::~ImgReaderOgr(void)
35 {
36 }
37 
38 //---------------------------------------------------------------------------
39 
40 void ImgReaderOgr::open(const std::string& filename)
41 {
42  m_filename = filename;
43  setCodec();
44 }
45 
46 //---------------------------------------------------------------------------
47 void ImgReaderOgr::close(void)
48 {
49  OGRDataSource::DestroyDataSource(m_datasource);
50 }
51 
52 //---------------------------------------------------------------------------
53 void ImgReaderOgr::setCodec(void){
54  //register the drivers
55  OGRRegisterAll();
56  //open the input OGR datasource. Datasources can be files, RDBMSes, directories full of files, or even remote web services depending on the driver being used. However, the datasource name is always a single string.
57  m_datasource = OGRSFDriverRegistrar::Open(m_filename.c_str(), FALSE);//FAlSE: do not update
58  if( m_datasource == NULL ){
59  std::string errorString="Open failed";
60  throw(errorString);
61  }
62 }
63 
64 bool ImgReaderOgr::getExtent(double& ulx, double& uly, double& lrx, double& lry, int layer)
65 {
66  OGREnvelope oExt;
67  if(getLayer(layer)->GetExtent(&oExt,TRUE)==OGRERR_NONE){
68  ulx=oExt.MinX;
69  uly=oExt.MaxY;
70  lrx=oExt.MaxX;
71  lry=oExt.MinY;
72  return true;
73  }
74  else
75  return false;
76 }
77 
78 unsigned long int ImgReaderOgr::getFeatureCount(int layer) const
79 {
80  return(m_datasource->GetLayer(layer)->GetFeatureCount());
81 }
82 
83 int ImgReaderOgr::getFieldCount(int layer) const
84 {
85  if(layer<0)
86  layer=m_datasource->GetLayerCount()-1;
87  assert(m_datasource->GetLayerCount()>layer);
88  OGRLayer *poLayer;
89  if((poLayer = m_datasource->GetLayer(layer))==NULL){
90  std::string errorstring="Could not get layer";
91  throw(errorstring);
92  }
93  OGRFeatureDefn *poFDefn = poLayer->GetLayerDefn();
94  return(poFDefn->GetFieldCount());
95 }
96 
97 int ImgReaderOgr::getFields(std::vector<std::string>& fields, int layer) const
98 {
99  if(layer<0)
100  layer=m_datasource->GetLayerCount()-1;
101  assert(m_datasource->GetLayerCount()>layer);
102  OGRLayer *poLayer;
103  if((poLayer = m_datasource->GetLayer(layer))==NULL){
104  std::string errorstring="Could not get layer";
105  throw(errorstring);
106  }
107  OGRFeatureDefn *poFDefn = poLayer->GetLayerDefn();
108  fields.clear();
109  fields.resize(poFDefn->GetFieldCount());
110  for(int iField=0;iField<poFDefn->GetFieldCount();++iField){
111  OGRFieldDefn *poFieldDefn = poFDefn->GetFieldDefn(iField);
112  fields[iField]=poFieldDefn->GetNameRef();
113  }
114  return(fields.size());
115 }
116 
117 int ImgReaderOgr::getFields(std::vector<OGRFieldDefn*>& fields, int layer) const
118 {
119  if(layer<0)
120  layer=m_datasource->GetLayerCount()-1;
121  assert(m_datasource->GetLayerCount()>layer);
122  OGRLayer *poLayer;
123  if((poLayer = m_datasource->GetLayer(layer))==NULL){
124  std::string errorstring="Could not get layer";
125  throw(errorstring);
126  }
127  OGRFeatureDefn *poFDefn = poLayer->GetLayerDefn();
128  fields.clear();
129  fields.resize(poFDefn->GetFieldCount());
130  for(int iField=0;iField<poFDefn->GetFieldCount();++iField){
131  OGRFieldDefn *poFieldDefn = poFDefn->GetFieldDefn(iField);
132  fields[iField]=poFDefn->GetFieldDefn(iField);
133  }
134  assert(fields.size()==getFieldCount(layer));
135  return(fields.size());
136 }
137 
138 std::string ImgReaderOgr::getProjection(int layer) const
139 {
140  if(m_datasource->GetLayer(layer)->GetSpatialRef()){
141  char* ppszResult;
142  m_datasource->GetLayer(layer)->GetSpatialRef()->exportToWkt(&ppszResult);
143  return(ppszResult);
144  }
145  else
146  return "";
147 }
148 
149 OGRwkbGeometryType ImgReaderOgr::getGeometryType(int layer) const
150 {
151  return m_datasource->GetLayer(layer)->GetLayerDefn()->GetGeomType();
152 }
153 
154 std::ostream& operator<<(std::ostream& theOstream, ImgReaderOgr& theImageReader){
155  //An OGRDataSource can potentially have many layers associated with it. The number of layers available can be queried with OGRDataSource::GetLayerCount() and individual layers fetched by index using OGRDataSource::GetLayer(). However, we wil just fetch the layer by name.
156  //todo: try to open and catch if failure...
157  // ofstream fpoints(filename.c_str(),ios::out);
158  OGRLayer *poLayer;
159  poLayer = theImageReader.getDataSource()->GetLayer(0);
160  OGRFeatureDefn *poFDefn = poLayer->GetLayerDefn();
161 
162  poLayer->ResetReading();
163 
164  theOstream << "#";
165  int iField=0;
166  // theOstream << "X" << " " << "Y" << " ";
167  for(int iField=0;iField<poFDefn->GetFieldCount();++iField){
168  OGRFieldDefn *poFieldDefn = poFDefn->GetFieldDefn(iField);
169  std::string fieldname=poFieldDefn->GetNameRef();
170  theOstream << fieldname << " ";
171  }
172  theOstream << std::endl;
173 
174  poLayer->ResetReading();
175 
176  //start reading features from the layer
177  OGRFeature *poFeature;
178  unsigned long int ifeature=0;
179  while( (poFeature = poLayer->GetNextFeature()) != NULL ){
180  OGRGeometry *poGeometry;
181  poGeometry = poFeature->GetGeometryRef();
182  assert(poGeometry != NULL);
183  double x,y;
184  if(wkbFlatten(poGeometry->getGeometryType()) == wkbPoint){
185  OGRPoint *poPoint = (OGRPoint *) poGeometry;
186  x=poPoint->getX();
187  y=poPoint->getY();
188  }
189  std::vector<std::string> vfields(poFDefn->GetFieldCount());
190  std::string featurename;
191  std::vector<std::string>::iterator fit=vfields.begin();
192  for(int iField=0;iField<poFDefn->GetFieldCount();++iField){
193  *(fit++)=poFeature->GetFieldAsString(iField);
194  }
195  theOstream.precision(12);
196  if(wkbFlatten(poGeometry->getGeometryType()) == wkbPoint)
197  theOstream << x << " " << y;
198  for(fit=vfields.begin();fit!=vfields.end();++fit)
199  theOstream << " " << *fit;
200  theOstream << std::endl;
201  ++ifeature;
202  }
203  return(theOstream);
204 }
205 
206 // OGRLayer * ImgReaderOgr::executeSql(const std::string& output, const std::string& sqlStatement, OGRGeometry* spatialFilter)
207 // {
208 // OGRLayer *poResultSet;
209 // poResultSet = m_datasource->ExecuteSQL(sqlStatement.c_str(), spatialFilter,NULL );
210 
211 // if( poResultSet != NULL ){
212 // ImgWriterOgr imgWriter;
213 // imgWriter.open(output);
214 // imgWriter.copyLayer(poResultSet,output);
215 // m_datasource->ReleaseResultSet( poResultSet );
216 // imgWriter.close();
217 // }
218 // }
219 
220 unsigned int ImgReaderOgr::readDataImageOgr(std::map<std::string,Vector2d<float> > &mapPixels, //[classNr][pixelNr][bandNr],
221  std::vector<std::string>& fields,
222  const std::vector<short>& bands,
223  const std::string& label,
224  const std::vector<std::string>& layers,
225  int verbose)
226 {
227  mapPixels.clear();
228  int nsample=0;
229  int totalSamples=0;
230  int nband=0;
231  if(verbose)
232  std::cout << "reading OGR dataset " << m_filename << std::endl;
233  for(int ilayer=0;ilayer<getLayerCount();++ilayer){
234  std::string currentLayername=getLayer(ilayer)->GetName();
235  if(layers.size())
236  if(find(layers.begin(),layers.end(),currentLayername)==layers.end())
237  continue;
238  try{
239  //only retain bands in fields
240  getFields(fields,ilayer);
241  std::vector<std::string>::iterator fit=fields.begin();
242  if(verbose>1)
243  std::cout << "reading fields: ";
244  while(fit!=fields.end()){
245  if(verbose)
246  std::cout << *fit << " ";
247  // size_t pos=(*fit).find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_ ");
248  if((*fit).substr(0,1)=="B"||(*fit).substr(0,1)=="b"){
249  if((*fit).substr(1).find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_ ")!=std::string::npos){
250  int theBand=atoi((*fit).substr(1).c_str());
251  if(bands.size()){
252  bool validBand=false;
253  for(int iband=0;iband<bands.size();++iband){
254  if(theBand==bands[iband])
255  validBand=true;
256  }
257  if(validBand)
258  ++fit;
259  else
260  fields.erase(fit);
261  }
262  else
263  ++fit;
264  }
265  else if((*fit)=="B" || (*fit)=="b" || (*fit)=="Band")//B is only band
266  ++fit;
267  }
268  else
269  fields.erase(fit);
270  }
271  if(verbose)
272  std::cout << std::endl;
273  if(verbose){
274  std::cout << "fields:";
275  for(std::vector<std::string>::iterator fit=fields.begin();fit!=fields.end();++fit)
276  std::cout << " " << *fit;
277  std::cout << std::endl;
278  }
279  if(!nband){
280  if(verbose)
281  std::cout << "reading data" << std::endl;
282  nband=readData(mapPixels,OFTReal,fields,label,ilayer,true,verbose==2);
283  }
284  else{
285  assert(nband==readData(mapPixels,OFTReal,fields,label,ilayer,true,false));
286  }
287  nsample=getFeatureCount(ilayer);
288  totalSamples+=nsample;
289  if(verbose)
290  std::cout << ": " << nsample << " samples read with " << nband << " bands" << std::endl;
291  }
292  catch(std::string e){
293  std::ostringstream estr;
294  estr << e << " " << m_filename;
295  throw(estr.str());
296  }
297  }
298  if(verbose)
299  std::cout << "total number of samples read " << totalSamples << std::endl;
300  return totalSamples;
301 }
302 
303 unsigned int ImgReaderOgr::readDataImageOgr(std::map<std::string,Vector2d<float> > &mapPixels, //[classNr][pixelNr][bandNr],
304  std::vector<std::string>& fields,
305  double start,
306  double end,
307  const std::string& label,
308  const std::vector<std::string>& layers,
309  int verbose)
310 {
311  mapPixels.clear();
312  int nsample=0;
313  int totalSamples=0;
314  int nband=0;
315  if(verbose)
316  std::cout << "reading OGR dataset file " << m_filename << std::endl;
317  for(int ilayer=0;ilayer<getLayerCount();++ilayer){
318  std::string currentLayername=getLayer(ilayer)->GetName();
319  if(layers.size())
320  if(find(layers.begin(),layers.end(),currentLayername)==layers.end())
321  continue;
322  try{
323  //only retain bands in fields
324  getFields(fields,ilayer);
325  std::vector<std::string>::iterator fit=fields.begin();
326  if(verbose)
327  std::cout << "reading fields: ";
328  while(fit!=fields.end()){
329  if(verbose)
330  std::cout << *fit << " ";
331  // size_t pos=(*fit).find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_ ");
332  if((*fit).substr(0,1)=="B"||(*fit).substr(0,1)=="b"){
333  if((*fit).substr(1).find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_ ")!=std::string::npos){
334  int iband=atoi((*fit).substr(1).c_str());
335  if((start||end)&&(iband<start||iband>end))
336  fields.erase(fit);
337  else
338  ++fit;
339  }
340  else if(*fit=="B" || *fit=="b"|| *fit=="Band")
341  ++fit;
342  }
343  else
344  fields.erase(fit);
345  }
346  if(verbose)
347  std::cout << std::endl;
348  if(verbose){
349  std::cout << "fields:";
350  for(std::vector<std::string>::iterator fit=fields.begin();fit!=fields.end();++fit)
351  std::cout << " " << *fit;
352  std::cout << std::endl;
353  }
354  if(!nband){
355  if(verbose)
356  std::cout << "reading data" << std::endl;
357  nband=readData(mapPixels,OFTReal,fields,label,ilayer,true,verbose==2);
358  }
359  else{
360  assert(nband==readData(mapPixels,OFTReal,fields,label,ilayer,true,false));
361  }
362  nsample=getFeatureCount(ilayer);
363  totalSamples+=nsample;
364  if(verbose)
365  std::cout << ": " << nsample << " samples read with " << nband << " bands" << std::endl;
366  }
367  catch(std::string e){
368  std::ostringstream estr;
369  estr << e << " " << m_filename;
370  throw(estr.str());
371  }
372  if(verbose)
373  std::cout << ": " << nsample << " samples read with " << nband << " bands" << std::endl;
374  }
375  if(verbose)
376  std::cout << "total number of samples read " << totalSamples << std::endl;
377  return totalSamples;
378 }