OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimKmlSuperOverlayReader.cpp
Go to the documentation of this file.
1 //*******************************************************************
2 //
3 // License: See top level LICENSE.txt file.
4 //
5 // Author: Mingjie Su, Harsh Govind
6 //
7 // Description:
8 //
9 // Contains class implementation for the class "ossimKmlSuperOverlayReader".
10 //
11 //*******************************************************************
12 // $Id: ossimKmlSuperOverlayReader.cpp 2178 2011-02-17 18:38:30Z ming.su $
13 
15 
16 //Std Includes
17 #include <cstring> /* strdup */
18 #include <iostream>
19 #include <sstream>
20 #include <string>
21 
22 //Minizip Includes
23 #include <minizip/unzip.h>
24 
25 //Ossim Includes
26 #include <ossim/base/ossimTrace.h>
27 #include <ossim/base/ossimNotify.h>
28 #include <ossim/base/ossimIpt.h>
29 #include <ossim/base/ossimDpt.h>
37 
38 RTTI_DEF1(ossimKmlSuperOverlayReader, "ossimKmlSuperOverlayReader", ossimImageHandler);
39 
40 static ossimTrace traceDebug("ossimKmlSuperOverlayReader:debug");
41 
42 //*******************************************************************
43 // Public Constructor:
44 //*******************************************************************
47  m_xmlDocument(0),
48  theImageBound()
49 {
50 }
51 
52 //*******************************************************************
53 // Destructor:
54 //*******************************************************************
56 {
57  close();
58 }
59 
60 //*******************************************************************
61 // Public Method:
62 //*******************************************************************
64 {
65  // const char* MODULE = "ossimKmlSuperOverlayReader::open";
66  bool result = false;
67 
68  if(isOpen())
69  {
70  close();
71  }
72 
73  if (theImageFile.ext().downcase() == "kmz")
74  {
75  result = getTopLevelKmlFileInfo();
76  if (result == false)
77  {
78  return result;
79  }
80  }
81  else
82  {
84  }
85 
86  if ( m_xmlDocument.valid() )
87  {
89  if (rootNode.valid())
90  {
91  std::vector<ossimRefPtr<ossimXmlNode> > nodes = rootNode->getChildNodes();
92  result = isKmlSuperOverlayFile(nodes);
93 
94  if (result == false) //let gdal kml handle vector kml file
95  {
96  return result;
97  }
98 
99  ossim_float64 north = 0.0;
100  ossim_float64 south = 0.0;
101  ossim_float64 east = 0.0;
102  ossim_float64 west = 0.0;
103  result = getCoordinate(nodes, north, south, east, west);
104 
105  if (result == false)
106  {
107  return result;
108  }
109 
110  if (!theImageGeometry.valid())
111  {
112  theImageGeometry = new ossimImageGeometry(0, createDefaultProj(north, south, east, west));
113  if (theImageGeometry.valid())
114  {
115  result = true;
116 
118 
119  //if the projection is default or geographic, uses the bounding of the OGR Layer
120  vector<ossimGpt> points;
121  points.push_back(ossimGpt(north, west));
122  points.push_back(ossimGpt(north, east));
123  points.push_back(ossimGpt(south, east));
124  points.push_back(ossimGpt(south, west));
125 
126 
127  std::vector<ossimDpt> rectTmp;
128  rectTmp.resize(points.size());
129  for(std::vector<ossimGpt>::size_type index=0; index < points.size(); ++index)
130  {
131  theImageGeometry->worldToLocal(points[(int)index], rectTmp[(int)index]);
132  }
133 
134  ossimDrect rect = ossimDrect(rectTmp[0],
135  rectTmp[1],
136  rectTmp[2],
137  rectTmp[3]);
138 
139  theImageBound = rect;
140  }
141  else
142  {
143  result = false;
144  }
145  }
146  }
147  else
148  {
149  result = false;
150  }
151  }
152  else
153  {
154  result = false;
155  }
156 
157  return result;
158 }
159 
160 //*******************************************************************
161 // Public method:
162 //*******************************************************************
164  const char* prefix) const
165 {
166  return ossimImageHandler::saveState(kwl, prefix);
167 }
168 
169 //*******************************************************************
170 // Public method:
171 //*******************************************************************
172 bool ossimKmlSuperOverlayReader::loadState(const ossimKeywordlist& kwl, const char* prefix)
173 {
174  return ossimImageHandler::loadState(kwl, prefix);
175 }
176 
178 {
179  return theImageGeometry;
180 }
181 
183 {
184  if (theImageGeometry.valid())
185  {
186  theImageGeometry = 0;
187  }
188  if (m_xmlDocument.valid())
189  {
190  m_xmlDocument = 0;
191  }
192 }
193 
195  const ossimIrect& /* tileRect */, ossim_uint32 /* resLevel */)
196 {
197  return 0;
198 }
199 
201 {
202  return 0;
203 }
204 
206 {
207  return 0;
208 }
209 
211 {
212  return 0;
213 }
214 
216 {
217  return 0;
218 }
219 
221 {
222  return theImageBound.height();
223 }
224 
226 {
227  return theImageBound.width();
228 }
229 
231 {
232  return theImageBound;
233 }
234 
236 {
237  return theImageGeometry;
238 }
239 
241 {
242  return OSSIM_SCALAR_UNKNOWN;
243 }
244 
246 {
247  if (theImageFile.empty())
248  {
249  return false;
250  }
251  return true;
252 }
253 
255 {
256  for (ossim_uint32 i = 0; i < nodes.size(); i++)
257  {
258  if (nodes[i]->getTag().downcase() == "placemark") //means vector kml file with point, polygon, or lines
259  {
260  return false;
261  }
262 
263  if (nodes[i]->getTag().downcase() == "region" || nodes[i]->getTag().downcase() == "networkLink") //means super overlay kml file
264  {
265  return true;
266  }
267  }
268  for (ossim_uint32 i = 0; i < nodes.size(); i++)
269  {
270  return isKmlSuperOverlayFile(nodes[i]->getChildNodes());
271  }
272  return false;
273 }
274 
276 {
277  ossimRefPtr<ossimXmlNode> latlonNode = 0;
278  for (ossim_uint32 i = 0; i < nodes.size(); i++)
279  {
280  if (nodes[i]->getTag().downcase() == "latlonaltbox")
281  {
282  return nodes[i];
283  }
284  }
285  for (ossim_uint32 j = 0; j < nodes.size(); j++)
286  {
287  latlonNode = findLatLonNode(nodes[j]->getChildNodes());
288  if (latlonNode.valid())
289  {
290  return latlonNode;
291  }
292  }
293  return latlonNode;
294 }
295 
297  ossim_float64& north,
298  ossim_float64& south,
299  ossim_float64& east,
300  ossim_float64& west)
301 {
302  ossimRefPtr<ossimXmlNode> latlonNode = findLatLonNode(nodes);
303  if (!latlonNode.valid())
304  {
305  return false;
306  }
307 
308  std::vector<ossimRefPtr<ossimXmlNode> > latlonNodes = latlonNode->getChildNodes();
309  if (latlonNodes.size() != 4)
310  {
311  return false;
312  }
313  for (ossim_uint32 i = 0; i < latlonNodes.size(); i++)
314  {
315  ossimString str = latlonNodes[i]->getTag().downcase();
316  if (str == "north")
317  {
318  north = latlonNodes[i]->getText().toFloat64();
319  }
320  else if (str == "south")
321  {
322  south = latlonNodes[i]->getText().toFloat64();
323  }
324  else if (str == "east")
325  {
326  east = latlonNodes[i]->getText().toFloat64();
327  }
328  else if (str == "west")
329  {
330  west = latlonNodes[i]->getText().toFloat64();
331  }
332  }
333  return true;
334 }
335 
337  ossim_float64 south,
338  ossim_float64 east,
339  ossim_float64 west)
340 {
342 
343  ossim_float64 centerLat = (south + north) / 2.0;
344  ossim_float64 centerLon = (west + east) / 2.0;
345  ossim_float64 deltaLat = north - south;
346 
347  // Scale that gives 1024 pixel in the latitude direction.
348  ossim_float64 scaleLat = deltaLat / 1024.0;
349  ossim_float64 scaleLon = scaleLat*ossim::cosd(std::fabs(centerLat));
350  ossimGpt origin(centerLat, centerLon, 0.0);
351  ossimDpt scale(scaleLon, scaleLat);
352 
353  // Set the origin.
354  proj->setOrigin(origin);
355 
356  // Set the tie point.
357  proj->setUlGpt( ossimGpt(north, west));
358 
359  // Set the scale. Note this will handle computing meters per pixel.
360  proj->setDecimalDegreesPerPixel(scale);
361 
362  return proj;
363 }
364 
366 {
368  ossimFilename tmpZipfile = ossimString(theImageFile.noExtension() + ".zip");
369  unzFile unzipfile = unzOpen(tmpZipfile.c_str());
370  if (!unzipfile)
371  {
374  "Unable to open target zip file..");
375 
376  tmpZipfile.rename(ossimString(tmpZipfile.noExtension() + ".kmz"));//if open fails, rename the file back to .kmz
377  return false;
378  }
379 
380  std::string kmzStringBuffer;
381 
382  if (unzGoToFirstFile(unzipfile) == UNZ_OK)
383  {
384  if (unzOpenCurrentFile(unzipfile) == UNZ_OK)
385  {
386  unsigned char buffer[4096] = {0};
387  int bytesRead = 0;
388  int read = 1;
389  while (read > 0)
390  {
391  read = unzReadCurrentFile(unzipfile, buffer, 4096);
392  bytesRead += read;
393  }
394  if ( bytesRead )
395  {
396  for (int i = 0; i < bytesRead; ++i)
397  {
398  // Copy to string casting to char.
399  kmzStringBuffer.push_back( static_cast<char>(buffer[i]) );
400  }
401  }
402  }
403  else
404  {
405  tmpZipfile.rename(ossimString(tmpZipfile.noExtension() + ".kmz"));//if read fails, rename the file back to .kmz
406  unzCloseCurrentFile(unzipfile);
407  unzClose(unzipfile);
408  return false;
409  }
410  }
411  else
412  {
413  tmpZipfile.rename(ossimString(tmpZipfile.noExtension() + ".kmz"));
414  unzClose(unzipfile);
415  return false;
416  }
417  unzCloseCurrentFile(unzipfile);
418  unzClose(unzipfile);
419 
420  std::istringstream in(kmzStringBuffer);
421  if ( in.good() )
422  {
424  m_xmlDocument->read( in );
425  }
426  else
427  {
428  tmpZipfile.rename(ossimString(tmpZipfile.noExtension() + ".kmz"));
429  return false;
430  }
431 
432  tmpZipfile.rename(ossimString(tmpZipfile.noExtension() + ".kmz"));
433 
434  return true;
435 }
436 
437 
438 
OSSIMDLLEXPORT void ossimSetError(const char *className, ossim_int32 error, const char *fmtString=0,...)
void makeNan()
Definition: ossimDrect.h:388
ossimRefPtr< ossimImageGeometry > theImageGeometry
ossimFilename noExtension() const
ossimFilename theImageFile
ossim_float64 width() const
Definition: ossimDrect.h:522
virtual ossimRefPtr< ossimImageData > getTile(const ossimIrect &tileRect, ossim_uint32 resLevel=0)
Represents serializable keyword/value map.
bool valid() const
Definition: ossimRefPtr.h:75
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Method to the load (recreate) the state of an object from a keyword list.
const ossimXmlNode::ChildListType & getChildNodes() const
static const ossimErrorCode OSSIM_ERROR
virtual ossimString getClassName() const
Definition: ossimObject.cpp:64
virtual void setDecimalDegreesPerPixel(const ossimDpt &gsd)
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
virtual void setUlGpt(const ossimGpt &ulGpt)
virtual ossimIrect getImageRectangle(ossim_uint32 reduced_res_level=0) const
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
virtual ossim_uint32 getNumberOfOutputBands() const
double ossim_float64
virtual ossim_uint32 getImageTileHeight() const
ossimScalarType getOutputScalarType() const
This will be used to query the output pixel type of the tile source.
ossimRefPtr< ossimXmlNode > findLatLonNode(std::vector< ossimRefPtr< ossimXmlNode > >nodes)
virtual ossimRefPtr< ossimImageGeometry > getImageGeometry()
Returns the image geometry object associated with this tile source or NULL if non defined...
virtual ossim_uint32 getNumberOfLines(ossim_uint32 reduced_res_level=0) const
unsigned int ossim_uint32
ossim_float64 toFloat64() const
virtual void setOrigin(const ossimGpt &origin)
static ossimString downcase(const ossimString &aString)
Definition: ossimString.cpp:48
double cosd(double x)
Definition: ossimCommon.h:259
ossim_float64 height() const
Definition: ossimDrect.h:517
ossimMapProjection * createDefaultProj(ossim_float64 north, ossim_float64 south, ossim_float64 east, ossim_float64 west)
Container class that holds both 2D transform and 3D projection information for an image Only one inst...
ossimScalarType
virtual bool isOpen() const
Derived classes must implement this method to be concrete.
virtual ossim_uint32 getNumberOfInputBands() const
This class defines an abstract Handler which all image handlers(loaders) should derive from...
ossimRefPtr< ossimXmlDocument > m_xmlDocument
const char * c_str() const
Returns a pointer to a null-terminated array of characters representing the string&#39;s contents...
Definition: ossimString.h:396
bool empty() const
Definition: ossimString.h:411
bool read(std::istream &in)
ossimString ext() const
bool worldToLocal(const ossimGpt &world_pt, ossimDpt &local_pt) const
Exposes the 3D world-to-local image coordinate reverse projection.
virtual ossim_uint32 getImageTileWidth() const
std::basic_istringstream< char > istringstream
Class for char input memory streams.
Definition: ossimIosFwd.h:32
ossimRefPtr< ossimXmlNode > getRoot()
virtual ossim_uint32 getNumberOfSamples(ossim_uint32 reduced_res_level=0) const
virtual ossimRefPtr< ossimImageGeometry > getInternalImageGeometry() const
Returns the image geometry object associated with this tile source or NULL if non defined...
bool getCoordinate(std::vector< ossimRefPtr< ossimXmlNode > > nodes, ossim_float64 &north, ossim_float64 &south, ossim_float64 &east, ossim_float64 &west)
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Method to save the state of an object to a keyword list.
bool rename(const ossimFilename &destFile, bool overwriteDestinationFlag=true) const
virtual void close()
Deletes the overview and clears the valid image vertices.
RTTI_DEF1(ossimKmlSuperOverlayReader, "ossimKmlSuperOverlayReader", ossimImageHandler)
bool isKmlSuperOverlayFile(std::vector< ossimRefPtr< ossimXmlNode > > nodes)