diff options
author | Ian Chen <ian.1.chen@nokia.com> | 2012-03-28 16:43:50 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-03-29 03:36:29 +0200 |
commit | 2106a31b66afc25917935046d2e3be14488d4dc5 (patch) | |
tree | 703403e90cc537b36b2ff551dbef90a4682e7f5d /src/location/maps | |
parent | 66f381098a27421978a739334f23794de0e4768d (diff) | |
download | qtlocation-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.cpp | 35 | ||||
-rw-r--r-- | src/location/maps/qgeomapgeometry.cpp | 22 |
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 |