summaryrefslogtreecommitdiff
path: root/src/location/maps
diff options
context:
space:
mode:
authorIan Chen <ian.1.chen@nokia.com>2012-03-28 16:43:50 +1000
committerQt by Nokia <qt-info@nokia.com>2012-03-29 03:36:29 +0200
commit2106a31b66afc25917935046d2e3be14488d4dc5 (patch)
tree703403e90cc537b36b2ff551dbef90a4682e7f5d /src/location/maps
parent66f381098a27421978a739334f23794de0e4768d (diff)
downloadqtlocation-2106a31b66afc25917935046d2e3be14488d4dc5.tar.gz
Internal documentation for map geometry and camera tiles
Change-Id: I9191b903471a2b3bf3999e8a3582ee8c90f95eef Reviewed-by: Alex Wilson <alex.wilson@nokia.com>
Diffstat (limited to 'src/location/maps')
-rw-r--r--src/location/maps/qgeocameratiles.cpp35
-rw-r--r--src/location/maps/qgeomapgeometry.cpp22
2 files changed, 55 insertions, 2 deletions
diff --git a/src/location/maps/qgeocameratiles.cpp b/src/location/maps/qgeocameratiles.cpp
index 15a1d0b0..edef8392 100644
--- a/src/location/maps/qgeocameratiles.cpp
+++ b/src/location/maps/qgeocameratiles.cpp
@@ -663,6 +663,7 @@ QSet<QGeoTileSpec> QGeoCameraTilesPrivate::tilesFromPolygon(const Polygon &polyg
QVector<int> tilesX(polygon.size());
QVector<int> tilesY(polygon.size());
+ // grab tiles at the corners of the polygon
for (int i = 0; i < numPoints; ++i) {
QDoubleVector2D p = polygon.at(i).toVector2D();
@@ -692,6 +693,7 @@ QSet<QGeoTileSpec> QGeoCameraTilesPrivate::tilesFromPolygon(const Polygon &polyg
QGeoCameraTilesPrivate::TileMap map;
+ // walk along the edges of the polygon and add all tiles covered by them
for (int i1 = 0; i1 < numPoints; ++i1) {
int i2 = (i1 + 1) % numPoints;
@@ -722,6 +724,33 @@ QSet<QGeoTileSpec> QGeoCameraTilesPrivate::tilesFromPolygon(const Polygon &polyg
int x = xIntersects.takeFirst().second;
int y = yIntersects.takeFirst().second;
+
+ /*
+ If the polygon coincides with the tile edges we must be
+ inclusive and grab all tiles on both sides. We also need
+ to handle tiles with corners coindent with the
+ corners of the polygon.
+ e.g. all tiles marked with 'x' will be added
+
+ "+" - tile boundaries
+ "O" - polygon boundary
+
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ + + x + x + x + +
+ + + + + + +
+ + + + + + + + + O O O O O + + + + + + + +
+ + + O 0 + +
+ + + x O x 0 x + +
+ + + O 0 + +
+ + + + + + + + + O 0 0 0 0 + + + + + + + +
+ + + + + + +
+ + + x + x + x + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ */
+
+
int xOther = x;
int yOther = y;
@@ -750,7 +779,7 @@ QSet<QGeoTileSpec> QGeoCameraTilesPrivate::tilesFromPolygon(const Polygon &polyg
map.add(x,y);
- // corner case
+ // top left corner
int iPrev = (i1 + numPoints - 1 ) % numPoints;
double xPrevious = polygon.at(iPrev).get(0);
double yPrevious = polygon.at(iPrev).get(1);
@@ -764,6 +793,10 @@ QSet<QGeoTileSpec> QGeoCameraTilesPrivate::tilesFromPolygon(const Polygon &polyg
}
}
+ // for the simple case where intersections do not coincide with
+ // the boundaries, we move along the edge and add tiles until
+ // the x and y intersection lists are exhausted
+
while (!xIntersects.isEmpty() && !yIntersects.isEmpty()) {
QPair<double, int> nextX = xIntersects.first();
QPair<double, int> nextY = yIntersects.first();
diff --git a/src/location/maps/qgeomapgeometry.cpp b/src/location/maps/qgeomapgeometry.cpp
index 3a10ca03..a0585b03 100644
--- a/src/location/maps/qgeomapgeometry.cpp
+++ b/src/location/maps/qgeomapgeometry.cpp
@@ -421,6 +421,9 @@ void QGeoMapGeometryPrivate::setVisibleTiles(const QSet<QGeoTileSpec> &tiles)
// set up the gl camera for the new geometry
setupCamera();
+ // geometry update is currently done by destroying old scene nodes
+ // then creating new ones.
+ // TODO reuse geometry information
QSet<QGeoTileSpec> toRemove = visibleTiles_ - tiles;
QSet<QGeoTileSpec> toUpdate = visibleTiles_ - toRemove;
if (!toRemove.isEmpty())
@@ -446,7 +449,6 @@ void QGeoMapGeometryPrivate::updateTiles(const QSet<QGeoTileSpec> &tiles)
sceneNode_->removeNode(node);
// TODO: re-use more of the geometry calculations?
QGLSceneNode *newNode = buildGeometry(tile);
-
if (newNode) {
QGLMaterial *mat = new QGLMaterial(newNode);
mat->setTexture(textures_[tile]->texture);
@@ -499,6 +501,8 @@ void QGeoMapGeometryPrivate::setTileBounds(const QSet<QGeoTileSpec> &tiles)
tileZ_ = i->zoom();
+ // determine whether the set of map tiles crosses the dateline.
+ // A gap in the tiles indicates dateline crossing
bool hasFarLeft = false;
bool hasFarRight = false;
bool hasMidLeft = false;
@@ -517,6 +521,8 @@ void QGeoMapGeometryPrivate::setTileBounds(const QSet<QGeoTileSpec> &tiles)
}
}
+ // if dateline crossing is detected we wrap all x pos of tiles
+ // that are in the left half of the map.
tileXWrapsBelow_ = 0;
if (hasFarLeft && hasFarRight) {
@@ -527,6 +533,7 @@ void QGeoMapGeometryPrivate::setTileBounds(const QSet<QGeoTileSpec> &tiles)
}
}
+ // finally, determine the min and max bounds
i = tiles.constBegin();
QGeoTileSpec tile = *i;
@@ -557,16 +564,25 @@ void QGeoMapGeometryPrivate::setTileBounds(const QSet<QGeoTileSpec> &tiles)
void QGeoMapGeometryPrivate::setupCamera()
{
+
double f = 1.0 * qMin(screenSize_.width(), screenSize_.height());
+ // fraction of zoom level
double z = pow(2.0, cameraData_.zoomLevel() - intZoomLevel_);
+ // calculate altitdue that allows the visible map tiles
+ // to fit in the screen correctly (note that a larger f will cause
+ // the camera be higher, resulting in gray areas displayed around
+ // the tiles)
double altitude = scaleFactor_ * f / (2.0 * z);
double aspectRatio = 1.0 * screenSize_.width() / screenSize_.height();
double a = f / (z * tileSize_);
+ // mercatorWidth_ and mercatorHeight_ define the ratio for
+ // mercator and screen coordinate conversion,
+ // see mercatorToScreenPosition() and screenPositionToMercator()
if (aspectRatio > 1.0) {
mercatorHeight_ = a;
mercatorWidth_ = a * aspectRatio;
@@ -579,14 +595,17 @@ void QGeoMapGeometryPrivate::setupCamera()
double edge = scaleFactor_ * tileSize_;
+ // first calculate the camera center in map space in the range of 0 <-> sideLength (2^z)
QDoubleVector3D center = (sideLength_ * QGeoProjection::coordToMercator(cameraData_.center()));
+ // wrap the center if necessary (due to dateline crossing)
if (center.x() < tileXWrapsBelow_)
center.setX(center.x() + 1.0 * sideLength_);
mercatorCenterX_ = center.x();
mercatorCenterY_ = center.y();
+ // work out where the camera center is w.r.t mininum tile bounds
center.setX(center.x() - 1.0 * minTileX_);
center.setY(1.0 * minTileY_ - center.y());
@@ -613,6 +632,7 @@ void QGeoMapGeometryPrivate::setupCamera()
screenWidth_ = screenSize_.width();
}
+ // apply necessary scaling to the camera center
center *= edge;
// calculate eye