OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimGpkgTileEntry.cpp
Go to the documentation of this file.
1 //----------------------------------------------------------------------------
2 //
3 // File: ossimGpkgTileEntry.cpp
4 //
5 // License: LGPL
6 //
7 // See LICENSE.txt file in the top level directory for more details.
8 //
9 // Description: Container class for GeoPackage tile entry.
10 //
11 // Holds a gpkg_tile_matrix_set and a vector of gpkg_tile_matrix.
12 //
13 //----------------------------------------------------------------------------
14 // $Id$
15 
16 #include "ossimGpkgTileEntry.h"
17 
18 #include <ossim/base/ossimDpt.h>
19 #include <ossim/base/ossimIpt.h>
21 #include <ossim/base/ossimString.h>
22 
28 
29 #include <algorithm> /* for std::sort */
30 #include <iomanip>
31 #include <ostream>
32 
33 static bool tileMatrixSort( const ossimGpkgTileMatrixRecord& i,
34  const ossimGpkgTileMatrixRecord& j )
35 {
36  // This is backwards, want the highest zoom level should be at lowest index.
37  return ( i.m_zoom_level > j.m_zoom_level );
38 }
39 
40 static bool tileMatrixExtentSort(
43 {
44  // This is backwards, want the highest zoom level should be at lowest index.
45  return ( i.m_zoom_level > j.m_zoom_level );
46 }
47 
49  :
50  m_srs(),
51  m_tileMatrixSet(),
52  m_tileMatrix(0),
53  m_tileMatrixExtents(0)
54 {
55 }
56 
58  :
59  m_srs(obj.m_srs),
60  m_tileMatrixSet(obj.m_tileMatrixSet),
61  m_tileMatrix(obj.m_tileMatrix),
62  m_tileMatrixExtents(obj.m_tileMatrixExtents)
63 {
64 }
65 
67 {
68  if ( this != &obj )
69  {
70  m_srs = obj.m_srs;
74  }
75  return *this;
76 }
77 
79 {
80 }
81 
83 {
84  m_tileMatrixSet = set;
85 }
86 
88 {
89  return m_tileMatrixSet;
90 }
91 
93 {
94  m_srs = srs;
95 }
96 
98 {
99  return m_srs;
100 }
101 
103 {
104  m_tileMatrix.push_back( level );
105 }
106 
107 const std::vector<ossimGpkgTileMatrixRecord>& ossimGpkgTileEntry::getTileMatrix() const
108 {
109  return m_tileMatrix;
110 }
111 
113 {
114  m_tileMatrixExtents.push_back( record );
115 }
116 
117 const std::vector<ossimGpkgNsgTileMatrixExtentRecord>&
119 {
120  return m_tileMatrixExtents;
121 }
122 
124 {
125  std::sort(m_tileMatrix.begin(), m_tileMatrix.end(), tileMatrixSort);
126 }
127 
129 {
130  std::sort(m_tileMatrixExtents.begin(),
131  m_tileMatrixExtents.end(),
132  tileMatrixExtentSort);
133 }
134 
136  const std::string& prefix ) const
137 {
138  m_srs.saveState( kwl, prefix );
139  m_tileMatrixSet.saveState( kwl, prefix );
140  std::string myPrefix = prefix;
141  myPrefix += "gpkg_tile_matrix";
142  for ( ossim_uint32 i = 0; i < (ossim_uint32)m_tileMatrix.size(); ++i )
143  {
144  std::string p = myPrefix;
145  p += ossimString::toString(i).string();
146  p += ".";
147  m_tileMatrix[i].saveState( kwl, p );
148  }
149 }
150 
152 {
153  ossimKeywordlist kwl;
154  saveState(kwl, std::string(""));
155  out << kwl;
156  return out;
157 }
158 
160 {
161  m_tileMatrixSet.print( out );
162 
163  // Capture the original flags.
164  std::ios_base::fmtflags f = out.flags();
165 
166  // Set the new precision capturing old.
167  std::streamsize oldPrecision = out.precision(15);
168 
171 
172  out << setiosflags(ios::fixed)
173  << "gpkg_tile_matrix_set.width: " << w << "\n"
174  << "gpkg_tile_matrix_set.height: " << h << "\n";
175 
176 
177  for ( ossim_uint32 i = 0; i < (ossim_uint32)m_tileMatrix.size(); ++i )
178  {
179  ossim_float64 computedX =
180  w / m_tileMatrix[i].m_matrix_width / m_tileMatrix[i].m_tile_width;
181  ossim_float64 computedY =
182  h / m_tileMatrix[i].m_matrix_height / m_tileMatrix[i].m_tile_height;
183 
184  cout << "gpkg_tile_matrix[" << i << "].zoom_level: "
185  << m_tileMatrix[i].m_zoom_level
186  << "\ngpkg_tile_matrix[" << i << "].pixel_x_size: "
187  << m_tileMatrix[i].m_pixel_x_size
188  << "\ngpkg_tile_matrix[" << i << "].pixel_x_size_computed: "
189  << computedX
190  << "\ngpkg_tile_matrix[" << i << "].pixel_x_size_delta: "
191  << m_tileMatrix[i].m_pixel_x_size - computedX
192  << "\ngpkg_tile_matrix[" << i << "].pixel_y_size: "
193  << m_tileMatrix[i].m_pixel_y_size
194  << "\ngpkg_tile_matrix[" << i << "].pixel_y_size_computed: "
195  << computedY
196  << "\ngpkg_tile_matrix[" << i << "].pixel_y_size_delta: "
197  << m_tileMatrix[i].m_pixel_y_size - computedY
198  << "\n";
199  }
200 
201  // Reset flags and precision.
202  out.setf(f);
203  out.precision(oldPrecision);
204 
205  return out;
206 }
207 
209  const ossimGpkgTileEntry& obj)
210 {
211  return obj.print( out );
212 }
213 
215 {
216  ossim_uint32 result = 0;
217 
218  if ( resLevel < m_tileMatrix.size() )
219  {
220  // m_tileMatrixExtents may or may not be there.
221  if ( ( resLevel < m_tileMatrixExtents.size() ) &&
222  ( m_tileMatrixExtents[resLevel].m_zoom_level == m_tileMatrix[resLevel].m_zoom_level ) )
223  {
224  result = m_tileMatrixExtents[resLevel].m_max_row -
225  m_tileMatrixExtents[resLevel].m_min_row + 1;
226  }
227  else
228  {
229  ossim_float64 lines =
231  m_tileMatrix[resLevel].m_pixel_y_size;
232  if ( lines > 0.0 )
233  {
234  result = (ossim_uint32)(lines + 0.5);
235  }
236  }
237  }
238 
239  return result;
240 }
241 
243 {
244  ossim_uint32 result = 0;
245 
246  if ( resLevel < m_tileMatrix.size() )
247  {
248  // m_tileMatrixExtents may or may not be there.
249  if ( ( resLevel < m_tileMatrixExtents.size() ) &&
250  ( m_tileMatrixExtents[resLevel].m_zoom_level == m_tileMatrix[resLevel].m_zoom_level ) )
251  {
252  result = m_tileMatrixExtents[resLevel].m_max_column -
253  m_tileMatrixExtents[resLevel].m_min_column + 1;
254  }
255  else
256  {
257  ossim_float64 samples =
259  m_tileMatrix[resLevel].m_pixel_x_size;
260  if ( samples > 0.0 )
261  {
262  result = (ossim_uint32)(samples + 0.5);
263  }
264  }
265  }
266 
267  return result;
268 }
269 
271 {
272  // m_tileMatrixExtents may or may not be there.
273  if ( ( resLevel < m_tileMatrix.size() ) &&
274  ( resLevel < m_tileMatrixExtents.size() ) &&
275  ( m_tileMatrixExtents[resLevel].m_zoom_level == m_tileMatrix[resLevel].m_zoom_level ) )
276  {
277  offset.x = m_tileMatrixExtents[resLevel].m_min_column;
278  offset.y = m_tileMatrixExtents[resLevel].m_min_row;
279  }
280  else
281  {
282  offset.x = 0;
283  offset.y = 0;
284  }
285 }
286 
288 {
289  // m_tileMatrixExtents may or may not be there.
290  if ( m_tileMatrix.size() && m_tileMatrixExtents.size() &&
291  ( m_tileMatrixExtents[0].m_zoom_level == m_tileMatrix[0].m_zoom_level ) )
292  {
293  tie.x = m_tileMatrixExtents[0].m_min_x;
294  tie.y = m_tileMatrixExtents[0].m_max_y;
295  }
296  else
297  {
298  tie.x = m_tileMatrixSet.m_min_x;
299  tie.y = m_tileMatrixSet.m_max_y;
300  }
301 }
302 
304 {
305  if ( index < m_tileMatrix.size() )
306  {
307  gsd.x = m_tileMatrix[index].m_pixel_x_size;
308  gsd.y = m_tileMatrix[index].m_pixel_y_size;
309  }
310  else
311  {
312  gsd.makeNan();
313  }
314 }
315 
316 void ossimGpkgTileEntry::getZoomLevels( std::vector<ossim_int32>& zoomLevels ) const
317 {
318  zoomLevels.clear();
319  std::vector<ossimGpkgTileMatrixRecord>::const_iterator i = m_tileMatrix.begin();
320  while ( i != m_tileMatrix.end() )
321  {
322  zoomLevels.push_back( (*i).m_zoom_level );
323  ++i;
324  }
325 }
326 
328  std::vector<ossimIpt>& zoomLevelMatrixSizes ) const
329 {
330  zoomLevelMatrixSizes.clear();
331  std::vector<ossimGpkgTileMatrixRecord>::const_iterator i = m_tileMatrix.begin();
332  while ( i != m_tileMatrix.end() )
333  {
334  zoomLevelMatrixSizes.push_back( ossimIpt((*i).m_matrix_width, (*i).m_matrix_height) );
335  ++i;
336  }
337 }
338 
340 {
342 
343  if ( m_tileMatrix.size() )
344  {
345  // Must have code, and scale to continue:
347  m_tileMatrix[0].m_pixel_x_size &&
348  m_tileMatrix[0].m_pixel_y_size )
349  {
350  std::string org = ossimString(m_srs.m_organization).upcase().string();
351 
352  if ( org == "EPSG" )
353  {
355 
356  ossimDpt gsd;
357  getGsd( 0, gsd );
358 
359  // Avoid factory call for two most common projections.
360  if ( code == 4326 )
361  {
362  // Geographic, WGS 84
363 
364  //---
365  // ossimEquDistCylProjection uses the origin_latitude for meters per pixel
366  // (gsd) computation. Compute to achieve the proper horizontal sccaling.
367  //---
368  ossimGpt origin(0.0, 0.0);
369  ossim_float64 tmpDbl = ossim::acosd(gsd.y/gsd.x);
370  if ( !ossim::isnan(tmpDbl) )
371  {
372  origin.lat = tmpDbl;
373  }
374  mapProj = new ossimEquDistCylProjection(ossimEllipsoid(), origin);
375  }
376  else if ( ( code == 3857 ) || ( code == 900913) )
377  {
378  mapProj = new ossimGoogleProjection();
379  }
380  else
381  {
382  ossimString name = "EPSG:";
383  name += ossimString::toString(code);
386  if ( proj.valid() )
387  {
388  mapProj = dynamic_cast<ossimMapProjection*>( proj.get() );
389  }
390  }
391 
392  if ( mapProj.valid() )
393  {
394  //---
395  // Set the tie and scale. NOTE the tie is center of the upper left
396  // pixel; hence, the half pixel shif.
397  //---
398  ossimDpt tie;
399  getTiePoint( tie );
400 
401  if ( mapProj->isGeographic() )
402  {
403  mapProj->setDecimalDegreesPerPixel(gsd);
404 
405  // Tie latitude, longitude:
406  ossimGpt tiePoint( tie.y, tie.x );
407  ossimDpt half_pixel_shift = gsd * 0.5;
408  tiePoint.lat -= half_pixel_shift.lat;
409  tiePoint.lon += half_pixel_shift.lon;
410 
411  mapProj->setUlTiePoints(tiePoint);
412  }
413  else
414  {
415  mapProj->setMetersPerPixel(gsd);
416 
417  // Tie Easting Northing:
418  ossimDpt half_pixel_shift = gsd * 0.5;
419  tie.y -= half_pixel_shift.y;
420  tie.x += half_pixel_shift.x;
421 
422  mapProj->setUlTiePoints(tie);
423  }
424  }
425 
426  } // Matches: if ( org == "epsg" )
427 
428  } // Matches: if ( m_srs.m_organization_coordsys_id && ...
429 
430  } // Matches: if ( m_tileMatrix.size() )
431 
432  return mapProj;
433 
434 } // End: ossimGpkgTileEntry::getNewMapProjection()
void addTileMatrixExtent(const ossimGpkgNsgTileMatrixExtentRecord &record)
Adds a tile matrix extent level to array.
static ossimString upcase(const ossimString &aString)
Definition: ossimString.cpp:34
Represents serializable keyword/value map.
bool valid() const
Definition: ossimRefPtr.h:75
const ossimGpkgTileMatrixSetRecord & getTileMatrixSet() const
ossim_uint32 getNumberOfSamples(ossim_uint32 resLevel) const
void setTileMatrixSet(const ossimGpkgTileMatrixSetRecord &set)
Sets the tile matrix set.
double y
Definition: ossimDpt.h:165
static ossimString toString(bool aValue)
Numeric to string methods.
void saveState(ossimKeywordlist &kwl, const std::string &prefix) const
Saves the state of object.
void getZoomLevelMatrixSizes(std::vector< ossimIpt > &zoomLevelMatrixSizes) const
Gets zoom level matrix of all tile matrixes.
virtual bool isGeographic() const
void getGsd(ossim_uint32 index, ossimDpt &gsd) const
Gets the gsd from tile matrix.
double acosd(double x)
Definition: ossimCommon.h:264
virtual void setDecimalDegreesPerPixel(const ossimDpt &gsd)
std::ostream & printValidate(std::ostream &out) const
Validate method.
virtual void saveState(ossimKeywordlist &kwl, const std::string &prefix) const
Saves the state of object.
virtual void setMetersPerPixel(const ossimDpt &gsd)
double ossim_float64
double lat
Definition: ossimDpt.h:165
ossim_float64 lon
Definition: ossimGpt.h:266
void sortTileMatrix()
Sorts the m_tileMatrix by zoom levels with the highest zoom level being at the lowest array index...
unsigned int ossim_uint32
std::vector< ossimGpkgNsgTileMatrixExtentRecord > m_tileMatrixExtents
ossimGpkgTileEntry()
default constructor
void addTileMatrix(const ossimGpkgTileMatrixRecord &level)
Adds a tile matrix level to array.
ossimGpkgTileMatrixSetRecord m_tileMatrixSet
const ossimGpkgSpatialRefSysRecord & getSrs() const
Spatial ref sys.
const ossimGpkgTileEntry & operator=(const ossimGpkgTileEntry &obj)
double lon
Definition: ossimDpt.h:164
void sortTileMatrixExtents()
Sorts the m_tileMatrixExtents by zoom levels with the highest zoom level being at the lowest array in...
virtual std::ostream & print(std::ostream &out) const
Print method.
virtual void saveState(ossimKeywordlist &kwl, const std::string &prefix) const
Saves the state of object.
void getTiePoint(ossimDpt &offset) const
Gets the tie point from the first tile matrix extents if initialized else from the tile matrix extent...
void setSrs(const ossimGpkgSpatialRefSysRecord &srs)
Sets the spatial ref sys.
ossimGpkgSpatialRefSysRecord m_srs
const std::vector< ossimGpkgTileMatrixRecord > & getTileMatrix() const
ossim_int32 y
Definition: ossimIpt.h:142
~ossimGpkgTileEntry()
destructor
ossimRefPtr< ossimMapProjection > getNewMapProjection() const
Gets the map projection to include setting the tie and scale.
void getSubImageOffset(ossim_uint32 resLevel, ossimIpt &offset) const
double x
Definition: ossimDpt.h:164
virtual ossimProjection * createProjection(const ossimFilename &filename, ossim_uint32 entryIdx) const
STUB. Not implemented.
std::ostream & print(std::ostream &out) const
Print method.
virtual void setUlTiePoints(const ossimGpt &gpt)
ossim_int32 x
Definition: ossimIpt.h:141
ossim_float64 lat
Definition: ossimGpt.h:265
std::vector< ossimGpkgTileMatrixRecord > m_tileMatrix
void getZoomLevels(std::vector< ossim_int32 > &zoomLevels) const
Gets zoom levels of all tile matrixes.
ossim_uint32 getNumberOfLines(ossim_uint32 resLevel) const
std::ostream & operator<<(std::ostream &out, const ossimGpkgTileEntry &obj)
static ossimEpsgProjectionFactory * instance()
Implements singleton pattern.
void makeNan()
Definition: ossimDpt.h:65
std::basic_ostream< char > ostream
Base class for char output streams.
Definition: ossimIosFwd.h:23
const std::string & string() const
Definition: ossimString.h:414
bool isnan(const float &v)
isnan Test for floating point Not A Number (NAN) value.
Definition: ossimCommon.h:91
const std::vector< ossimGpkgNsgTileMatrixExtentRecord > & getTileMatrixExtent() const