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