pktools  2.6.5
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  int theBand=atoi((*fit).substr(1).c_str());
295  if(bands.size()){
296  bool validBand=false;
297  for(int iband=0;iband<bands.size();++iband){
298  if(theBand==bands[iband])
299  validBand=true;
300  }
301  if(validBand)
302  ++fit;
303  else
304  fields.erase(fit);
305  }
306  else
307  ++fit;
308  }
309  else if((*fit)=="B" || (*fit)=="b" || (*fit)=="Band")//B is only band
310  ++fit;
311  }
312  else
313  fields.erase(fit);
314  }
315  if(verbose)
316  std::cout << std::endl;
317  if(verbose){
318  std::cout << "fields:";
319  for(std::vector<std::string>::iterator fit=fields.begin();fit!=fields.end();++fit)
320  std::cout << " " << *fit;
321  std::cout << std::endl;
322  }
323  if(!nband){
324  if(verbose)
325  std::cout << "reading data" << std::endl;
326  nband=readData(mapPixels,OFTReal,fields,label,ilayer,true,verbose==2);
327  }
328  else{
329  assert(nband==readData(mapPixels,OFTReal,fields,label,ilayer,true,false));
330  }
331  nsample=getFeatureCount(ilayer);
332  totalSamples+=nsample;
333  if(verbose)
334  std::cout << ": " << nsample << " samples read with " << nband << " bands" << std::endl;
335  }
336  catch(std::string e){
337  std::ostringstream estr;
338  estr << e << " " << m_filename;
339  throw(estr.str());
340  }
341  }
342  if(verbose)
343  std::cout << "total number of samples read " << totalSamples << std::endl;
344  return totalSamples;
345 }
346 
347 unsigned int ImgReaderOgr::readDataImageOgr(std::map<std::string,Vector2d<float> > &mapPixels, //[classNr][pixelNr][bandNr],
348  std::vector<std::string>& fields,
349  double start,
350  double end,
351  const std::string& label,
352  const std::vector<std::string>& layers,
353  int verbose)
354 {
355  mapPixels.clear();
356  int nsample=0;
357  int totalSamples=0;
358  int nband=0;
359  if(verbose)
360  std::cout << "reading OGR dataset file " << m_filename << std::endl;
361  for(int ilayer=0;ilayer<getLayerCount();++ilayer){
362  std::string currentLayername=getLayer(ilayer)->GetName();
363  if(layers.size())
364  if(find(layers.begin(),layers.end(),currentLayername)==layers.end())
365  continue;
366  try{
367  //only retain bands in fields
368  getFields(fields,ilayer);
369  std::vector<std::string>::iterator fit=fields.begin();
370  if(verbose)
371  std::cout << "reading fields: ";
372  while(fit!=fields.end()){
373  if(verbose)
374  std::cout << *fit << " ";
375  // size_t pos=(*fit).find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_ ");
376  if((*fit).substr(0,1)=="B"||(*fit).substr(0,1)=="b"){
377  if((*fit).substr(1).find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_ ")!=std::string::npos){
378  int iband=atoi((*fit).substr(1).c_str());
379  if((start||end)&&(iband<start||iband>end))
380  fields.erase(fit);
381  else
382  ++fit;
383  }
384  else if(*fit=="B" || *fit=="b"|| *fit=="Band")
385  ++fit;
386  }
387  else
388  fields.erase(fit);
389  }
390  if(verbose)
391  std::cout << std::endl;
392  if(verbose){
393  std::cout << "fields:";
394  for(std::vector<std::string>::iterator fit=fields.begin();fit!=fields.end();++fit)
395  std::cout << " " << *fit;
396  std::cout << std::endl;
397  }
398  if(!nband){
399  if(verbose)
400  std::cout << "reading data" << std::endl;
401  nband=readData(mapPixels,OFTReal,fields,label,ilayer,true,verbose==2);
402  }
403  else{
404  assert(nband==readData(mapPixels,OFTReal,fields,label,ilayer,true,false));
405  }
406  nsample=getFeatureCount(ilayer);
407  totalSamples+=nsample;
408  if(verbose)
409  std::cout << ": " << nsample << " samples read with " << nband << " bands" << std::endl;
410  }
411  catch(std::string e){
412  std::ostringstream estr;
413  estr << e << " " << m_filename;
414  throw(estr.str());
415  }
416  if(verbose)
417  std::cout << ": " << nsample << " samples read with " << nband << " bands" << std::endl;
418  }
419  if(verbose)
420  std::cout << "total number of samples read " << totalSamples << std::endl;
421  return totalSamples;
422 }