openModeller  Version 1.5.0
om_layer_utils.cpp
Go to the documentation of this file.
1 
27 #include <om_layer_utils.hh>
28 
29 #include <string>
30 
31 #include <dirent.h>
32 
33 #include "gdal_priv.h"
34 
35 #include <openmodeller/Log.hh>
37 
38 /***********************/
39 /**** readDirectory ****/
40 bool
41 readDirectory( const char* dir, const char* label, ostream &xml, int depth, int* seq )
42 {
43  bool r = true;
44 
45  if ( depth == 0 ) {
46 
47  GDALAllRegister();
48 
49  CPLSetErrorHandler( CPLQuietErrorHandler );
50  }
51 
52  ++depth;
53 
54  // Maximum depth level to recurse on directories
55  if ( depth > 20 )
56  {
57  return false;
58  }
59 
60  // Create copy of dir and add slash to the end if necessary
61  string myDir( dir );
62 
63  //skip hidden dirs
64  if ( myDir.find( "." ) == 1 ) {
65  return false;
66  }
67  if ( myDir.find_first_of( ".",0 ) == 1 ) {
68  return false;
69  }
70 
71  if ( myDir.find_last_of( "/" ) != myDir.size() - 1 ) {
72 
73  myDir.append( "/" );
74  }
75 
76  // Open directory
77  struct dirent **nameList;
78  int n;
79  struct stat buf;
80 
81  n = scandir( myDir.c_str(), &nameList, 0, alphasort );
82 
83  if ( n < 0 ) {
84 
85  // Problems opening directory
86  return false;
87  }
88  else if ( n == 0 ) {
89 
90  // Empty directories are useless
91  return true;
92  }
93 
94  xml << "<LayersGroup Id=\"" << *seq << "\">";
95 
96  ++*seq;
97 
98  xml << "<Label>" << label << "</Label>";
99 
100  string xmlFiles;
101 
102  for ( int i = 0; i < n; i++ ) {
103 
104  // Skip "." and ".." directories
105  if ( strcmp( nameList[i]->d_name, "." ) == 0 || strcmp( nameList[i]->d_name, ".." ) == 0 ) {
106 
107  continue;
108  }
109 
110  // Skip ".aux" files
111  if ( strstr( nameList[i]->d_name, ".aux" ) != 0 ) {
112 
113  continue;
114  }
115 
116  // Need the full name to "stat"
117  string fullName( myDir );
118  fullName.append( nameList[i]->d_name );
119 
120  // Get file attributes (skip on failure)
121  if ( stat( fullName.c_str(), &buf ) == -1 ) {
122 
123  continue;
124  }
125 
126  // Directory
127  if ( S_ISDIR( buf.st_mode ) ) {
128 
129  Log::instance()->debug( "Checking directory: %s\n", fullName.c_str() );
130 
131  if ( isValidGdalFile( fullName.c_str() ) ) {
132 
133  string hasProj = ( hasValidGdalProjection( fullName.c_str() ) ) ? "1" : "0";
134 
135  string label = getLayerLabel( myDir, nameList[i]->d_name, true );
136 
137  xmlFiles.append( "<Layer Id=\"" );
138  xmlFiles.append( fullName );
139  xmlFiles.append( "\" HasProjection=\"");
140  xmlFiles.append( hasProj );
141  xmlFiles.append( "\">" );
142  xmlFiles.append( "<Label>" );
143  xmlFiles.append( label );
144  xmlFiles.append( "</Label>" );
145  xmlFiles.append( "</Layer>" );
146  }
147  else {
148 
149  r = readDirectory( fullName.c_str(), nameList[i]->d_name, xml, depth, seq );
150  }
151  }
152  // Regular file
153  else if ( S_ISREG( buf.st_mode ) ) {
154 
155  Log::instance()->debug( "Checking file: %s\n", fullName.c_str() );
156 
157  if ( isValidGdalFile( fullName.c_str() ) ) {
158 
159  string hasProj = ( hasValidGdalProjection( fullName.c_str() ) ) ? "1" : "0";
160 
161  string label = getLayerLabel( myDir, nameList[i]->d_name, false );
162 
163  xmlFiles.append( "<Layer Id=\"" );
164  xmlFiles.append( fullName );
165  xmlFiles.append( "\" HasProjection=\"");
166  xmlFiles.append( hasProj );
167  xmlFiles.append( "\">" );
168  xmlFiles.append( "<Label>" );
169  xmlFiles.append( label );
170  xmlFiles.append( "</Label>" );
171  xmlFiles.append( "</Layer>" );
172  }
173  }
174  // Symbolic link
175  //else if ( S_ISLNK( buf.st_mode ) ) {
176 
177  // What should we do with symlinks?
178  //readDirectory( fullName.c_str(), nameList[i]->d_name, xml, depth, seq );
179  //}
180  }
181 
182  // openModeller.xsd mandates that files should always come after directories
183  xml << xmlFiles;
184 
185  xml << "</LayersGroup>";
186 
187  return r;
188 }
189 
190 /***********************/
191 /**** getLayerLabel ****/
192 string
193 getLayerLabel( const string path, const string name, bool isDir )
194 {
195  string metaFile = path;
196 
197  // It is a directory
198  if ( isDir ) {
199 
200  // append last dir name and ".meta"
201  metaFile = metaFile.append(name).append(".meta");
202  }
203  // It is a file
204  else {
205 
206  size_t pos = name.find_last_of( "." );
207 
208  if ( pos != string::npos ) {
209 
210  // replace extension with ".meta"
211  string metaName = name.substr( 0, pos ).append(".meta");
212  metaFile = metaFile.append( metaName );
213  }
214  else {
215 
216  // try just appending name and ".meta"
217  metaFile = metaFile.append(name).append(".meta");
218  }
219  }
220 
221  FILE * file = fopen( metaFile.c_str(), "r" );
222 
223  if ( file != NULL ) {
224 
225  fclose( file );
226 
227  FileParser fParser( metaFile.c_str() );
228 
229  return fParser.get( "LABEL" );
230  }
231 
232  return name;
233 }
234 
235 /*************************/
236 /**** isValidGdalFile ****/
237 bool
238 isValidGdalFile( const char* fileName )
239 {
240  // test whether the file is GDAL compatible
241  GDALDataset * testFile = (GDALDataset *)GDALOpen( fileName, GA_ReadOnly );
242 
243  if ( testFile == NULL ) {
244 
245  // not GDAL compatible
246  return false;
247  }
248  else {
249 
250  // is GDAL compatible
251  GDALClose( testFile );
252  return true;
253  }
254 }
255 
256 /********************************/
257 /**** hasValidGdalProjection ****/
258 bool
259 hasValidGdalProjection( const char* fileName )
260 {
261  // test whether the file has GDAL projection info
262  GDALDataset * testFile = (GDALDataset *)GDALOpen( fileName, GA_ReadOnly );
263 
264  const char *projectionString = testFile->GetProjectionRef();
265 
266  GDALClose( testFile );
267 
268  if ( projectionString ) {
269 
270  // has projection info
271  return true;
272  }
273 
274  // does not have projection info
275  return false;
276 }
static Log * instance()
Returns the instance pointer, creating the object on the first call.
Definition: Log.cpp:45
string getLayerLabel(const string path, const string name, bool isDir)
bool isValidGdalFile(const char *fileName)
bool readDirectory(const char *dir, const char *label, ostream &xml, int depth, int *seq)
bool hasValidGdalProjection(const char *fileName)
std::string get(const std::string &key) const
Definition: FileParser.cpp:145
void debug(const char *format,...)
'Debug' level.
Definition: Log.cpp:237