• 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
ElevationModel.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 2011 Niko Sams <niko.sams@gmail.com>
9 //
10 
11 #include "ElevationModel.h"
12 #include "GeoSceneHead.h"
13 #include "GeoSceneLayer.h"
14 #include "GeoSceneMap.h"
15 #include "GeoSceneDocument.h"
16 #include "GeoSceneTextureTile.h"
17 #include "Tile.h"
18 #include "TileLoader.h"
19 #include "TileLoaderHelper.h"
20 #include "MarbleModel.h"
21 #include "MarbleDebug.h"
22 #include "MapThemeManager.h"
23 #include "TileId.h"
24 
25 #include <QLabel>
26 #include <qmath.h>
27 
28 namespace Marble
29 {
30 
31 class ElevationModelPrivate
32 {
33 public:
34  ElevationModelPrivate( ElevationModel *_q, MarbleModel *const model )
35  : q( _q ),
36  m_tileLoader( model->downloadManager(), model->pluginManager() ),
37  m_textureLayer( 0 )
38  {
39  m_cache.setMaxCost( 10 ); //keep 10 tiles in memory (~17MB)
40 
41  const GeoSceneDocument *srtmTheme = MapThemeManager::loadMapTheme( "earth/srtm2/srtm2.dgml" );
42  if ( !srtmTheme ) {
43  mDebug() << "Failed to load map theme earth/srtm2/srtm2.dgml. Check your installation. No elevation will be returned.";
44  return;
45  }
46 
47  const GeoSceneHead *head = srtmTheme->head();
48  Q_ASSERT( head );
49 
50  const GeoSceneMap *map = srtmTheme->map();
51  Q_ASSERT( map );
52 
53  const GeoSceneLayer *sceneLayer = map->layer( head->theme() );
54  Q_ASSERT( sceneLayer );
55 
56  m_textureLayer = dynamic_cast<GeoSceneTextureTile*>( sceneLayer->datasets().first() );
57  Q_ASSERT( m_textureLayer );
58  }
59 
60  void tileCompleted( const TileId & tileId, const QImage &image )
61  {
62  m_cache.insert( tileId, new QImage( image ) );
63  emit q->updateAvailable();
64  }
65 
66 public:
67  ElevationModel *q;
68 
69  TileLoader m_tileLoader;
70  const GeoSceneTextureTile *m_textureLayer;
71  QCache<TileId, const QImage> m_cache;
72 };
73 
74 ElevationModel::ElevationModel( MarbleModel *const model )
75  : QObject( 0 ),
76  d( new ElevationModelPrivate( this, model ) )
77 {
78  connect( &d->m_tileLoader, SIGNAL(tileCompleted(TileId,QImage)),
79  this, SLOT(tileCompleted(TileId,QImage)) );
80 }
81 
82 
83 qreal ElevationModel::height( qreal lon, qreal lat ) const
84 {
85  if ( !d->m_textureLayer ) {
86  return invalidElevationData;
87  }
88 
89  const int tileZoomLevel = d->m_tileLoader.maximumTileLevel( *( d->m_textureLayer ) );
90  Q_ASSERT( tileZoomLevel == 9 );
91 
92  const int width = d->m_textureLayer->tileSize().width();
93  const int height = d->m_textureLayer->tileSize().height();
94 
95  const int numTilesX = TileLoaderHelper::levelToColumn( d->m_textureLayer->levelZeroColumns(), tileZoomLevel );
96  const int numTilesY = TileLoaderHelper::levelToRow( d->m_textureLayer->levelZeroRows(), tileZoomLevel );
97  Q_ASSERT( numTilesX > 0 );
98  Q_ASSERT( numTilesY > 0 );
99 
100  qreal textureX = 180 + lon;
101  textureX *= numTilesX * width / 360;
102 
103  qreal textureY = 90 - lat;
104  textureY *= numTilesY * height / 180;
105 
106  qreal ret = 0;
107  bool hasHeight = false;
108  qreal noData = 0;
109 
110  for ( int i = 0; i < 4; ++i ) {
111  const int x = static_cast<int>( textureX + ( i % 2 ) );
112  const int y = static_cast<int>( textureY + ( i / 2 ) );
113 
114  //mDebug() << "x" << x << ( x / width );
115  //mDebug() << "y" << y << ( y / height );
116 
117  const TileId id( 0, tileZoomLevel, ( x % ( numTilesX * width ) ) / width, ( y % ( numTilesY * height ) ) / height );
118  //mDebug() << "LAT" << lat << "LON" << lon << "tile" << ( x % ( numTilesX * width ) ) / width << ( y % ( numTilesY * height ) ) / height;
119 
120  const QImage *image = d->m_cache[id];
121  if ( image == 0 ) {
122  image = new QImage( d->m_tileLoader.loadTileImage( d->m_textureLayer, id, DownloadBrowse ) );
123  d->m_cache.insert( id, image );
124  }
125  Q_ASSERT( image );
126  Q_ASSERT( !image->isNull() );
127  Q_ASSERT( width == image->width() );
128  Q_ASSERT( height == image->height() );
129 
130  const qreal dx = ( textureX > ( qreal )x ) ? textureX - ( qreal )x : ( qreal )x - textureX;
131  const qreal dy = ( textureY > ( qreal )y ) ? textureY - ( qreal )y : ( qreal )y - textureY;
132 
133  Q_ASSERT( 0 <= dx && dx <= 1 );
134  Q_ASSERT( 0 <= dy && dy <= 1 );
135  unsigned int pixel;
136  pixel = image->pixel( x % width, y % height );
137  pixel -= 0xFF000000; //fully opaque
138  //mDebug() << "(1-dx)" << (1-dx) << "(1-dy)" << (1-dy);
139  if ( pixel != invalidElevationData ) { //no data?
140  //mDebug() << "got at x" << x % width << "y" << y % height << "a height of" << pixel << "** RGB" << qRed(pixel) << qGreen(pixel) << qBlue(pixel);
141  ret += ( qreal )pixel * ( 1 - dx ) * ( 1 - dy );
142  hasHeight = true;
143  } else {
144  //mDebug() << "no data at" << x % width << "y" << y % height;
145  noData += ( 1 - dx ) * ( 1 - dy );
146  }
147  }
148 
149  if ( !hasHeight ) {
150  ret = invalidElevationData; //no data
151  } else {
152  if ( noData ) {
153  //mDebug() << "NO DATA" << noData;
154  ret += ( ret / ( 1 - noData ) ) * noData;
155  }
156  }
157 
158  //mDebug() << ">>>" << lat << lon << "returning an elevation of" << ret;
159  return ret;
160 }
161 
162 QList<GeoDataCoordinates> ElevationModel::heightProfile( qreal fromLon, qreal fromLat, qreal toLon, qreal toLat ) const
163 {
164  if ( !d->m_textureLayer ) {
165  return QList<GeoDataCoordinates>();
166  }
167 
168  const int tileZoomLevel = d->m_tileLoader.maximumTileLevel( *( d->m_textureLayer ) );
169  const int width = d->m_textureLayer->tileSize().width();
170  const int numTilesX = TileLoaderHelper::levelToColumn( d->m_textureLayer->levelZeroColumns(), tileZoomLevel );
171 
172  qreal distPerPixel = ( qreal )360 / ( width * numTilesX );
173  //mDebug() << "heightProfile" << fromLat << fromLon << toLat << toLon << "distPerPixel" << distPerPixel;
174 
175  qreal lat = fromLat;
176  qreal lon = fromLon;
177  char dirLat = fromLat < toLat ? 1 : -1;
178  char dirLon = fromLon < toLon ? 1 : -1;
179  qreal k = qAbs( ( fromLat - toLat ) / ( fromLon - toLon ) );
180  //mDebug() << "fromLon" << fromLon << "fromLat" << fromLat;
181  //mDebug() << "diff lon" << ( fromLon - toLon ) << "diff lat" << ( fromLat - toLat );
182  //mDebug() << "dirLon" << QString::number(dirLon) << "dirLat" << QString::number(dirLat) << "k" << k;
183  QList<GeoDataCoordinates> ret;
184  while ( lat*dirLat <= toLat*dirLat && lon*dirLon <= toLon * dirLon ) {
185  //mDebug() << lat << lon;
186  qreal h = height( lon, lat );
187  if ( h < 32000 ) {
188  ret << GeoDataCoordinates( lon, lat, h, GeoDataCoordinates::Degree );
189  }
190  if ( k < 0.5 ) {
191  //mDebug() << "lon(x) += distPerPixel";
192  lat += distPerPixel * k * dirLat;
193  lon += distPerPixel * dirLon;
194  } else {
195  //mDebug() << "lat(y) += distPerPixel";
196  lat += distPerPixel * dirLat;
197  lon += distPerPixel / k * dirLon;
198  }
199  }
200  //mDebug() << ret;
201  return ret;
202 }
203 
204 }
205 
206 
207 
208 #include "ElevationModel.moc"
GeoSceneHead.h
TileLoader.h
TileId.h
Marble::GeoDataCoordinates
A 3d point representation.
Definition: GeoDataCoordinates.h:52
MarbleModel.h
This file contains the headers for MarbleModel.
Marble::DownloadBrowse
Browsing mode, normal operation of Marble, like a web browser.
Definition: MarbleGlobal.h:166
GeoSceneDocument.h
QImage::isNull
bool isNull() const
MarbleDebug.h
Marble::GeoDataCoordinates::Degree
Definition: GeoDataCoordinates.h:66
QImage::pixel
QRgb pixel(int x, int y) const
Marble::ElevationModel::heightProfile
QList< GeoDataCoordinates > heightProfile(qreal fromLon, qreal fromLat, qreal toLon, qreal toLat) const
Definition: ElevationModel.cpp:162
QObject
QImage::width
int width() const
Marble::ElevationModel::ElevationModel
ElevationModel(MarbleModel *const model)
Definition: ElevationModel.cpp:74
Marble::MapThemeManager::loadMapTheme
static GeoSceneDocument * loadMapTheme(const QString &mapThemeStringID)
Returns the map theme as a GeoSceneDocument object.
Definition: MapThemeManager.cpp:155
QList
QtConcurrent::map
QFuture< void > map(Sequence &sequence, MapFunction function)
Marble::ElevationModel::height
qreal height(qreal lon, qreal lat) const
Definition: ElevationModel.cpp:83
QCache
Tile.h
QImage
Marble::MarbleModel
The data model (not based on QAbstractModel) for a MarbleWidget.
Definition: MarbleModel.h:97
Marble::TileId
Definition: TileId.h:27
ElevationModel.h
Marble::TileLoaderHelper::levelToRow
MARBLE_EXPORT int levelToRow(int levelZeroRows, int level)
Get the maximum number of tile rows for a given tile level.
Definition: TileLoaderHelper.cpp:36
Marble::TileLoaderHelper::levelToColumn
MARBLE_EXPORT int levelToColumn(int levelZeroColumns, int level)
Get the maximum number of tile columns for a given tile level.
Definition: TileLoaderHelper.cpp:46
QImage::height
int height() const
GeoSceneTextureTile.h
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
TileLoaderHelper.h
Marble::mDebug
QDebug mDebug()
a function to replace qDebug() in Marble library code
Definition: MarbleDebug.cpp:36
GeoSceneMap.h
MapThemeManager.h
GeoSceneLayer.h
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:13:39 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