• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

marble

  • sources
  • kde-4.14
  • kdeedu
  • marble
  • src
  • lib
  • marble
VectorTileModel.cpp
Go to the documentation of this file.
1 /*
2  This file is part of the Marble Virtual Globe.
3 
4  This program is free software licensed under the GNU LGPL. You can
5  find a copy of this license in LICENSE.txt in the top directory of
6  the source code.
7 
8  Copyright 2012 Ander Pijoan <ander.pijoan@deusto.es>
9  Copyright 2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
10 */
11 
12 #include "VectorTileModel.h"
13 
14 #include "GeoDataDocument.h"
15 #include "GeoDataLatLonBox.h"
16 #include "GeoDataTreeModel.h"
17 #include "GeoSceneVectorTile.h"
18 #include "MarbleGlobal.h"
19 #include "MarbleDebug.h"
20 #include "MathHelper.h"
21 #include "TileId.h"
22 #include "TileLoader.h"
23 
24 #include <qmath.h>
25 #include <QThreadPool>
26 
27 using namespace Marble;
28 
29 TileRunner::TileRunner( TileLoader *loader, const GeoSceneVectorTile *texture, const TileId &id ) :
30  m_loader( loader ),
31  m_texture( texture ),
32  m_id( id )
33 {
34 }
35 
36 void TileRunner::run()
37 {
38  GeoDataDocument *const document = m_loader->loadTileVectorData( m_texture, m_id, DownloadBrowse );
39 
40  emit documentLoaded( m_id, document );
41 }
42 
43 VectorTileModel::CacheDocument::CacheDocument( GeoDataDocument *doc, GeoDataTreeModel *model ) :
44  m_document( doc ),
45  m_treeModel( model )
46 {
47  // nothing to do
48 }
49 
50 VectorTileModel::CacheDocument::~CacheDocument()
51 {
52  Q_ASSERT( m_treeModel );
53  m_treeModel->removeDocument( m_document );
54  delete m_document;
55 }
56 
57 VectorTileModel::VectorTileModel( TileLoader *loader, const GeoSceneVectorTile *layer, GeoDataTreeModel *treeModel, QThreadPool *threadPool ) :
58  m_loader( loader ),
59  m_layer( layer ),
60  m_treeModel( treeModel ),
61  m_threadPool( threadPool ),
62  m_tileZoomLevel( -1 )
63 {
64 }
65 
66 void VectorTileModel::setViewport( const GeoDataLatLonBox &bbox, int radius )
67 {
68  // choose the smaller dimension for selecting the tile level, leading to higher-resolution results
69  const int levelZeroWidth = m_layer->tileSize().width() * m_layer->levelZeroColumns();
70  const int levelZeroHight = m_layer->tileSize().height() * m_layer->levelZeroRows();
71  const int levelZeroMinDimension = qMin( levelZeroWidth, levelZeroHight );
72 
73  qreal linearLevel = ( 4.0 * (qreal)( radius ) / (qreal)( levelZeroMinDimension ) );
74 
75  if ( linearLevel < 1.0 )
76  linearLevel = 1.0; // Dirty fix for invalid entry linearLevel
77 
78  // As our tile resolution doubles with each level we calculate
79  // the tile level from tilesize and the globe radius via log(2)
80 
81  qreal tileLevelF = qLn( linearLevel ) / qLn( 2.0 );
82  int tileZoomLevel = (int)( tileLevelF * 1.00001 );
83  // snap to the sharper tile level a tiny bit earlier
84  // to work around rounding errors when the radius
85  // roughly equals the global texture width
86 
87 
88  if ( tileZoomLevel > m_layer->maximumTileLevel() )
89  tileZoomLevel = m_layer->maximumTileLevel();
90 
91  // if zoom level has changed, empty vectortile cache
92  if ( tileZoomLevel != m_tileZoomLevel ) {
93  m_tileZoomLevel = tileZoomLevel;
94  m_documents.clear();
95  }
96 
97  const unsigned int maxTileX = ( 1 << tileZoomLevel ) * m_layer->levelZeroColumns();
98  const unsigned int maxTileY = ( 1 << tileZoomLevel ) * m_layer->levelZeroRows();
99 
102  // New tiles X and Y for moved screen coordinates
103  // More info: http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Subtiles
104  // More info: http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#C.2FC.2B.2B
105  // Sometimes the formula returns wrong huge values, x and y have to be between 0 and 2^ZoomLevel
106  unsigned int minX = qMin<unsigned int>( maxTileX,
107  qMax<unsigned int>( lon2tileX( bbox.west(GeoDataCoordinates::Degree), maxTileX ),
108  0 ) );
109 
110  unsigned int minY = qMin<unsigned int>( maxTileY,
111  qMax<unsigned int>( lat2tileY( bbox.north(GeoDataCoordinates::Degree), maxTileY ),
112  0 ) );
113 
114  unsigned int maxX = qMax<unsigned int>( 0,
115  qMin<unsigned int>( lon2tileX( bbox.east(GeoDataCoordinates::Degree), maxTileX ),
116  maxTileX ) );
117 
118  unsigned int maxY = qMax<unsigned int>( 0,
119  qMin<unsigned int>( lat2tileY( bbox.south(GeoDataCoordinates::Degree), maxTileY ),
120  maxTileY ) );
121 
122  bool left = minX < maxTileX;
123  bool right = maxX > 0;
124  bool up = minY < maxTileY;
125  bool down = maxY > 0 ;
126 
127  // Download tiles and send them to VectorTileLayer
128  // When changing zoom, download everything inside the screen
129  if ( left && right && up && down )
130 
131  setViewport( tileZoomLevel, minX, minY, maxX, maxY );
132 
133  // When only moving screen, just download the new tiles
134  else if ( left || right || up || down ){
135 
136  if ( left )
137  setViewport( tileZoomLevel, minX, maxTileY, maxTileX, 0 );
138  if ( right )
139  setViewport( tileZoomLevel, 0, maxTileY, maxX, 0 );
140  if ( up )
141  setViewport( tileZoomLevel, maxTileX, minY, 0, maxTileY );
142  if ( down )
143  setViewport( tileZoomLevel, maxTileX, 0, 0, maxY );
144 
145  // During testing discovered that this code above does not request the "corner" tiles
146 
147  }
148 }
149 
150 QString VectorTileModel::name() const
151 {
152  return m_layer->name();
153 }
154 
155 void VectorTileModel::updateTile( const TileId &id, GeoDataDocument *document )
156 {
157  if ( m_tileZoomLevel != id.zoomLevel() ) {
158  delete document;
159  return;
160  }
161 
162  m_treeModel->addDocument( document );
163  m_documents.insert( id, new CacheDocument( document, m_treeModel ) );
164 }
165 
166 void VectorTileModel::clear()
167 {
168  m_documents.clear();
169 }
170 
171 void VectorTileModel::setViewport( int tileZoomLevel,
172  unsigned int minTileX, unsigned int minTileY, unsigned int maxTileX, unsigned int maxTileY )
173 {
174  // Download all the tiles inside the given indexes
175  for ( unsigned int x = minTileX; x <= maxTileX; ++x ) {
176  for ( unsigned int y = minTileY; y <= maxTileY; ++y ) {
177  const TileId tileId = TileId( 0, tileZoomLevel, x, y );
178 
179  if ( !m_documents.contains( tileId ) ) {
180  GeoDataDocument *const document = new GeoDataDocument;
181 
182  TileRunner *job = new TileRunner( m_loader, m_layer, tileId );
183  connect( job, SIGNAL(documentLoaded(TileId,GeoDataDocument*)), this, SLOT(updateTile(TileId,GeoDataDocument*)) );
184  m_threadPool->start( job );
185 
186  m_treeModel->addDocument( document );
187  m_documents.insert( tileId, new CacheDocument( document, m_treeModel ) );
188  }
189  }
190  }
191 }
192 
193 unsigned int VectorTileModel::lon2tileX( qreal lon, unsigned int maxTileX )
194 {
195  return (unsigned int)floor((lon + 180.0) / 360.0 * maxTileX);
196 }
197 
198 unsigned int VectorTileModel::lat2tileY( qreal lat, unsigned int maxTileY )
199 {
200  return (unsigned int)floor((1.0 - log( tan(lat * M_PI/180.0) + 1.0 / cos(lat * M_PI/180.0)) / M_PI) / 2.0 * maxTileY);
201 }
202 
203 #include "VectorTileModel.moc"
GeoDataDocument.h
TileLoader.h
TileId.h
Marble::GeoDataDocument
A container for Features, Styles and in the future Schemas.
Definition: GeoDataDocument.h:65
QSize::width
int width() const
Marble::GeoSceneVectorTile
Definition: GeoSceneVectorTile.h:23
Marble::GeoDataTreeModel
The representation of GeoData in a model This class represents all available data given by kml-data f...
Definition: GeoDataTreeModel.h:32
Marble::TileRunner::documentLoaded
void documentLoaded(const TileId &id, GeoDataDocument *document)
Marble::VectorTileModel::setViewport
void setViewport(const GeoDataLatLonBox &bbox, int radius)
Definition: VectorTileModel.cpp:66
QThreadPool
Marble::GeoSceneTiled::levelZeroColumns
int levelZeroColumns() const
Definition: GeoSceneTiled.cpp:97
Marble::DownloadBrowse
Browsing mode, normal operation of Marble, like a web browser.
Definition: MarbleGlobal.h:166
Marble::TileLoader::loadTileVectorData
GeoDataDocument * loadTileVectorData(GeoSceneVectorTile const *textureLayer, TileId const &tileId, DownloadUsage const usage)
Definition: TileLoader.cpp:90
Marble::TileRunner::run
void run()
Definition: VectorTileModel.cpp:36
MarbleDebug.h
Marble::GeoDataTreeModel::addDocument
int addDocument(GeoDataDocument *document)
Definition: GeoDataTreeModel.cpp:821
Marble::GeoDataCoordinates::Degree
Definition: GeoDataCoordinates.h:66
Marble::GeoSceneTiled::maximumTileLevel
int maximumTileLevel() const
Definition: GeoSceneTiled.cpp:117
Marble::GeoSceneAbstractDataset::name
QString name() const
Definition: GeoSceneAbstractDataset.cpp:38
Marble::GeoDataLatLonBox::north
qreal north(GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian) const
Get the northern boundary of the bounding box.
Definition: GeoDataLatLonBox.cpp:93
Marble::GeoDataLatLonBox::east
qreal east(GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian) const
Get the eastern boundary of the bounding box.
Definition: GeoDataLatLonBox.cpp:135
Marble::TileRunner
Definition: VectorTileModel.h:33
MathHelper.h
Marble::radius
static qreal radius(qreal zoom)
Definition: thumbnailer.cpp:99
Marble::VectorTileModel::VectorTileModel
VectorTileModel(TileLoader *loader, const GeoSceneVectorTile *layer, GeoDataTreeModel *treeModel, QThreadPool *threadPool)
Definition: VectorTileModel.cpp:57
Marble::VectorTileModel::updateTile
void updateTile(const TileId &id, GeoDataDocument *document)
Definition: VectorTileModel.cpp:155
QString
MarbleGlobal.h
GeoDataTreeModel.h
Marble::GeoSceneTiled::levelZeroRows
int levelZeroRows() const
Definition: GeoSceneTiled.cpp:107
GeoSceneVectorTile.h
GeoDataLatLonBox.h
Marble::GeoSceneTiled::tileSize
const QSize tileSize() const
Definition: GeoSceneTiled.cpp:132
Marble::GeoDataLatLonBox::west
qreal west(GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian) const
Get the western boundary of the bounding box.
Definition: GeoDataLatLonBox.cpp:156
Marble::TileRunner::TileRunner
TileRunner(TileLoader *loader, const GeoSceneVectorTile *texture, const TileId &id)
Definition: VectorTileModel.cpp:29
Marble::TileId
Definition: TileId.h:27
Marble::GeoDataLatLonBox::south
qreal south(GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian) const
Get the southern boundary of the bounding box.
Definition: GeoDataLatLonBox.cpp:114
QSize::height
int height() const
M_PI
#define M_PI
Definition: GeoDataCoordinates.h:26
Marble::VectorTileModel::name
QString name() const
Definition: VectorTileModel.cpp:150
Marble::VectorTileModel::clear
void clear()
Definition: VectorTileModel.cpp:166
QThreadPool::start
void start(QRunnable *runnable, int priority)
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
Marble::GeoDataLatLonBox
A class that defines a 2D bounding box for geographic data.
Definition: GeoDataLatLonBox.h:51
VectorTileModel.h
Marble::TileLoader
Definition: TileLoader.h:44
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:13:42 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

marble

Skip menu "marble"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal