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