summaryrefslogtreecommitdiff
path: root/src/location/maps/qgeomap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/location/maps/qgeomap.cpp')
-rw-r--r--src/location/maps/qgeomap.cpp790
1 files changed, 54 insertions, 736 deletions
diff --git a/src/location/maps/qgeomap.cpp b/src/location/maps/qgeomap.cpp
index 7f98902c..81f249c6 100644
--- a/src/location/maps/qgeomap.cpp
+++ b/src/location/maps/qgeomap.cpp
@@ -47,6 +47,10 @@
#include "qgeoprojection2d_p.h"
#include "qgeotile_p.h"
#include "qgeomapcontroller_p.h"
+#include "qdoublevector2d_p.h"
+#include "qdoublevector3d_p.h"
+
+#include "qgeocameratiles_p.h"
#include "qgeomappingmanager.h"
@@ -199,124 +203,6 @@ const QGeoMapType QGeoMap::activeMapType() const
return d->activeMapType();
}
-//------------------------------------------------------------//
-
-TileMap::TileMap(int minY, int maxY)
- : size(0),
- minY(minY),
- maxY(maxY),
- minX(maxY - minY + 1, -1),
- maxX(maxY - minY + 1, -1)
-{}
-
-void TileMap::adjust(int tileX, int tileY)
-{
- int index = tileY - minY;
- int min = minX.at(index);
- int max = maxX.at(index);
-
- if (min == -1) {
- min = tileX;
- max = tileX;
- minX[index] = min;
- maxX[index] = max;
- size += 1;
- } else {
- int oldSize = (max - min);
- int min2 = qMin(min, tileX);
- if (min2 != min)
- minX[index] = min2;
- int max2 = qMax(max, tileX);
- if (max2 != max)
- maxX[index] = max2;
- int newSize = (max2 - min2);
- size += (newSize - oldSize);
- }
-}
-
-IntersectGenerator::IntersectGenerator(const QGeoMapPrivate *mp,
- double p1,
- double p2,
- int t1,
- int t2,
- IntersectGenerator::Axis axis,
- int zoomLevel)
- : mp_(mp),
- axis_(axis),
- zoomLevel_(zoomLevel)
-{
- if (t1 == t2) {
- hasNext_ = false;
- return;
- }
-
- bool inc = true;
- if (axis_ == IntersectGenerator::XAxis) {
- inc = (0 < (p2 - p1));
- } else {
- inc = (0 < (p1 - p2));
- }
-
- step_ = 1;
- adjust_ = 0;
- if (!inc) {
- step_ = -1;
- adjust_ = -1;
- }
-
- first_ = p1;
- denom_ = p2 - p1;
-
- current_ = t1;
- end_ = t2 + step_;
-
- hasNext_ = true;
-
- generateValue();
-}
-
-bool IntersectGenerator::hasNext() const
-{
- return hasNext_;
-}
-
-QPair<double, int> IntersectGenerator::value() const
-{
- return value_;
-}
-
-void IntersectGenerator::next()
-{
- generateValue();
-}
-
-void IntersectGenerator::generateValue()
-{
- while (current_ != end_) {
- double alpha = 0.0;
-
- if (axis_ == IntersectGenerator::XAxis) {
- double x = mp_->tileXIntersectToPoint(zoomLevel_, current_).x();
- alpha = (x - first_) / denom_;
- } else {
- double y = mp_->tileYIntersectToPoint(zoomLevel_, current_).y();
- alpha = (y - first_) / denom_;
- }
-
- if ((0.0 < alpha) && (alpha < 1.0)) {
- value_ = QPair<double,int>(alpha, current_ + adjust_);
- current_ += step_;
- if (current_ == end_)
- hasNext_ = false;
- return;
- }
- current_ += step_;
- }
- hasNext_ = false;
-}
-
-//------------------------------------------------------------//
-
QGeoMapPrivate::QGeoMapPrivate(QGeoMap *parent, QGeoTileCache *cache, int maxZoom, int tileSize)
: map_(parent),
cache_(cache),
@@ -333,28 +219,18 @@ QGeoMapPrivate::QGeoMapPrivate(QGeoMap *parent, QGeoTileCache *cache, int maxZoo
sideLength_ = pow(2.0, 1.0 * maxZoom_) * tileSize;
projection_ = QSharedPointer<QGeoProjection>(new QGeoProjection2D(baseHeight_, sideLength_));
- screenPoly_.resize(4);
- screenPoly_[0] = QPointF(0.0, 0.0);
- screenPoly_[1] = QPointF(0.0, sideLength_);
- screenPoly_[2] = QPointF(sideLength_, sideLength_);
- screenPoly_[3] = QPointF(sideLength_, 0.0);
-
- screenPolyLeft_.resize(4);
- screenPolyLeft_[0] = QPointF(0.0, 0.0);
- screenPolyLeft_[1] = QPointF(0.0, sideLength_);
- screenPolyLeft_[2] = QPointF(sideLength_ / 2.0, sideLength_);
- screenPolyLeft_[3] = QPointF(sideLength_ / 2.0, 0.0);
-
- screenPolyRight_.resize(4);
- screenPolyRight_[0] = QPointF(sideLength_ / 2.0, 0.0);
- screenPolyRight_[1] = QPointF(sideLength_ / 2.0, sideLength_);
- screenPolyRight_[2] = QPointF(sideLength_, sideLength_);
- screenPolyRight_[3] = QPointF(sideLength_, 0.0);
+
+ cameraTiles_ = new QGeoCameraTiles(projection_);
+ cameraTiles_->setTileSize(tileSize_);
+ cameraTiles_->setMaximumZoomLevel(maxZoom_);
}
QGeoMapPrivate::~QGeoMapPrivate()
{
// controller_ is a child of map_, don't need to delete it here
+
+ delete cameraTiles_;
+
manager_->deregisterMap(map_);
delete sphere_;
delete glCamera_;
@@ -384,6 +260,7 @@ void QGeoMapPrivate::setMappingManager(QGeoMappingManager *manager)
if (manager) {
manager->registerMap(map_);
pluginString_ = manager->managerName() + QLatin1String("_") + QString::number(manager->managerVersion());
+ cameraTiles_->setPluginString(pluginString_);
sphere_->setMappingManager(manager);
} else {
manager->deregisterMap(map_);
@@ -410,8 +287,11 @@ void QGeoMapPrivate::setCameraData(const QGeoCameraData &cameraData)
cameraData_.setProjection(projection_.toWeakRef());
updateGlCamera(glCamera_);
updateFrustum(frustum_);
- visibleTiles_ = updateVisibleTiles();
- sphere_->update(visibleTiles_);
+
+ cameraTiles_->setCamera(cameraData_);
+ visibleTiles_ = cameraTiles_->tiles();
+
+ sphere_->update(visibleTiles_.toList());
}
QGeoCameraData QGeoMapPrivate::cameraData() const
@@ -421,7 +301,7 @@ QGeoCameraData QGeoMapPrivate::cameraData() const
void QGeoMapPrivate::update()
{
- sphere_->update(visibleTiles_);
+ sphere_->update(visibleTiles_.toList());
}
void QGeoMapPrivate::resize(int width, int height)
@@ -429,45 +309,10 @@ void QGeoMapPrivate::resize(int width, int height)
width_ = width;
height_ = height;
aspectRatio_ = 1.0 * width_ / height_;
+ cameraTiles_->setScreenSize(QSize(width, height));
setCameraData(cameraData_);
}
-QVector2D QGeoMapPrivate::pointToTile(const QVector3D &point, int zoom, bool roundUp) const
-{
- QVector2D p = projection_->pointToMercator(point);
-
- int z = 1 << zoom;
- int x = 0;
- int y = 0;
-
- if (p.y() == 1.0)
- y = z - 1;
- else
- y = static_cast<int>(z * p.y()) % z;
-
- if ((qAbs(p.x()) < 1e-6) || (qAbs(p.x() - 1) < 1e-6))
- if (roundUp)
- x = z - 1;
- else
- x = 0;
- else
- x = static_cast<int>(z * p.x()) % z;
-
- return QVector2D(x, y);
-}
-
-QVector3D QGeoMapPrivate::tileXIntersectToPoint(int zoomLevel, int x) const
-{
- int zpow2 = 1 << zoomLevel;
- return projection_->mercatorToPoint(QVector2D(x * 1.0 / zpow2, zpow2 / 2.0));
-}
-
-QVector3D QGeoMapPrivate::tileYIntersectToPoint(int zoomLevel, int y) const
-{
- int zpow2 = 1 << zoomLevel;
- return projection_->mercatorToPoint(QVector2D(zpow2 / 2.0, y * 1.0 / zpow2));
-}
-
int QGeoMapPrivate::width() const
{
return width_;
@@ -483,18 +328,11 @@ double QGeoMapPrivate::aspectRatio() const
return aspectRatio_;
}
-void QGeoMapPrivate::setActiveMapType(const QGeoMapType type)
+void QGeoMapPrivate::setActiveMapType(const QGeoMapType &type)
{
activeMapType_ = type;
- //TODO: check if this shared
- //make it more optimal
- //rewrite current specs
- QList<QGeoTileSpec> temp = visibleTiles_;
- visibleTiles_.clear();
- foreach (QGeoTileSpec spec,temp) {
- spec.setMapId(type.mapId());
- visibleTiles_ << spec;
- }
+ cameraTiles_->setMapType(type);
+ visibleTiles_ = cameraTiles_->tiles();
map_->update();
}
@@ -528,10 +366,10 @@ QRect QGeoMapPrivate::specToRect(const QGeoTileSpec &tileSpec) const
double y1 = y * 1.0 / z;
double y2 = (y + 1) * 1.0 / z;
- QVector3D tl = projection_->mercatorToPoint(QVector2D(x1, y1));
- QVector3D tr = projection_->mercatorToPoint(QVector2D(x2, y1));
- QVector3D bl = projection_->mercatorToPoint(QVector2D(x1, y2));
- QVector3D br = projection_->mercatorToPoint(QVector2D(x2, y2));
+ QDoubleVector3D tl = projection_->mercatorToPoint(QDoubleVector2D(x1, y1));
+ QDoubleVector3D tr = projection_->mercatorToPoint(QDoubleVector2D(x2, y1));
+ QDoubleVector3D bl = projection_->mercatorToPoint(QDoubleVector2D(x1, y2));
+ QDoubleVector3D br = projection_->mercatorToPoint(QDoubleVector2D(x2, y2));
if (rightEdge) {
tr.setX(sideLength_);
@@ -563,10 +401,10 @@ QGLSceneNode* QGeoMapPrivate::createTileSpecNode(const QGeoTileSpec &tileSpec)
double y1 = y * 1.0 / z;
double y2 = (y + 1) * 1.0 / z;
- QVector3D tl = projection_->mercatorToPoint(QVector2D(x1, y1));
- QVector3D tr = projection_->mercatorToPoint(QVector2D(x2, y1));
- QVector3D bl = projection_->mercatorToPoint(QVector2D(x1, y2));
- QVector3D br = projection_->mercatorToPoint(QVector2D(x2, y2));
+ QDoubleVector3D tl = projection_->mercatorToPoint(QDoubleVector2D(x1, y1));
+ QDoubleVector3D tr = projection_->mercatorToPoint(QDoubleVector2D(x2, y1));
+ QDoubleVector3D bl = projection_->mercatorToPoint(QDoubleVector2D(x1, y2));
+ QDoubleVector3D br = projection_->mercatorToPoint(QDoubleVector2D(x2, y2));
if (rightEdge) {
tr.setX(sideLength_);
@@ -592,23 +430,23 @@ QGLSceneNode* QGeoMapPrivate::createTileSpecNode(const QGeoTileSpec &tileSpec)
QGeometryData g;
- QVector3D n = QVector3D(0, 0, 1);
+ QDoubleVector3D n = QDoubleVector3D(0, 0, 1);
g.appendVertex(tl);
g.appendNormal(n);
- g.appendTexCoord(QVector2D(tx1 * 1.0 / dz, ty1 * 1.0 / dz));
+ g.appendTexCoord(QDoubleVector2D(tx1 * 1.0 / dz, ty1 * 1.0 / dz));
g.appendVertex(bl);
g.appendNormal(n);
- g.appendTexCoord(QVector2D(tx1 * 1.0 / dz, ty2 * 1.0 / dz));
+ g.appendTexCoord(QDoubleVector2D(tx1 * 1.0 / dz, ty2 * 1.0 / dz));
g.appendVertex(br);
g.appendNormal(n);
- g.appendTexCoord(QVector2D(tx2 * 1.0 / dz, ty2 * 1.0 / dz));
+ g.appendTexCoord(QDoubleVector2D(tx2 * 1.0 / dz, ty2 * 1.0 / dz));
g.appendVertex(tr);
g.appendNormal(n);
- g.appendTexCoord(QVector2D(tx2 * 1.0 / dz, ty1 * 1.0 / dz));
+ g.appendTexCoord(QDoubleVector2D(tx2 * 1.0 / dz, ty1 * 1.0 / dz));
builder.addQuads(g);
@@ -643,11 +481,11 @@ void QGeoMapPrivate::paintGL(QGLPainter *painter)
glDisable(GL_DEPTH_TEST);
- QVector3D c = camera->center();
+ QDoubleVector3D c = QDoubleVector3D(camera->center());
c.setX(c.x() + sideLength_);
camera->setCenter(c);
- QVector3D e = camera->eye();
+ QDoubleVector3D e = QDoubleVector3D(camera->eye());
e.setX(e.x() + sideLength_);
camera->setEye(e);
@@ -690,35 +528,37 @@ void QGeoMapPrivate::updateGlCamera(QGLCamera* glCamera)
QGeoCoordinate coord = camera.center();
coord.setAltitude(0.0);
- QVector3D center = projection_->coordToPoint(coord);
+ QDoubleVector3D center = projection_->coordToPoint(coord);
coord.setAltitude(altitude);
- QVector3D eye = projection_->coordToPoint(coord);
+ QDoubleVector3D eye = projection_->coordToPoint(coord);
// if (pow(2.0, cameraData_.zoomFactor()) * tileSize_ < height_) {
// center.setY(sideLength_ / 2.0);
// eye.setY(sideLength_ / 2.0);
// }
- QVector3D view = eye - center;
- QVector3D side = QVector3D::normal(view, QVector3D(0.0, 1.0, 0.0));
- QVector3D up = QVector3D::normal(side, view);
+ QDoubleVector3D view = eye - center;
+ QDoubleVector3D side = QDoubleVector3D::normal(view, QDoubleVector3D(0.0, 1.0, 0.0));
+ QDoubleVector3D up = QDoubleVector3D::normal(side, view);
+/*
QMatrix4x4 mBearing;
mBearing.rotate(-1.0 * camera.bearing(), view);
up = mBearing * up;
- QVector3D side2 = QVector3D::normal(up, view);
+ QDoubleVector3D side2 = QDoubleVector3D::normal(up, view);
QMatrix4x4 mTilt;
mTilt.rotate(camera.tilt(), side2);
eye = (mTilt * view) + center;
view = eye - center;
- side = QVector3D::normal(view, QVector3D(0.0, 1.0, 0.0));
- up = QVector3D::normal(view, side2);
+ side = QDoubleVector3D::normal(view, QDoubleVector3D(0.0, 1.0, 0.0));
+ up = QDoubleVector3D::normal(view, side2);
QMatrix4x4 mRoll;
mRoll.rotate(camera.roll(), view);
up = mRoll * up;
+*/
double nearPlane = 1.0;
double farPlane = 2.0 * altitude;
@@ -776,25 +616,25 @@ QGeoCoordinate QGeoMapPrivate::screenPositionToCoordinate(const QPointF &pos) co
x = (x + 1.0) / 2.0;
y = (y + 1.0) / 2.0;
- QVector3D tl = frustum_.topLeftFar();
- QVector3D tr = frustum_.topRightFar();
- QVector3D bl = frustum_.bottomLeftFar();
+ QDoubleVector3D tl = frustum_.topLeftFar();
+ QDoubleVector3D tr = frustum_.topRightFar();
+ QDoubleVector3D bl = frustum_.bottomLeftFar();
- QVector3D n = (1 - x - y) * tl + x * tr + y * bl;
+ QDoubleVector3D n = (1 - x - y) * tl + x * tr + y * bl;
if (eye_.z() == n.z())
return QGeoCoordinate();
double alpha = eye_.z() / (eye_.z() - n.z());
- QVector3D c = (1 - alpha) * eye_ + alpha * n;
+ QDoubleVector3D c = (1 - alpha) * eye_ + alpha * n;
return projection_->pointToCoord(c);
}
QPointF QGeoMapPrivate::coordinateToScreenPosition(const QGeoCoordinate &coordinate) const
{
- QVector3D c = projection_->coordToPoint(coordinate);
- QVector3D d = projectionMatrix_.map(c);
+ QDoubleVector3D c = projection_->coordToPoint(coordinate);
+ QDoubleVector3D d = QDoubleVector3D(projectionMatrix_.map(c));
QPointF point = QPointF((d.x() + 1.0) * width() / 2.0, (-d.y() + 1.0) * height() / 2.0);
double side = pow(2.0, cameraData_.zoomFactor()) * tileSize_;
@@ -836,526 +676,4 @@ void QGeoMapPrivate::updateFrustum(QGeoFrustum &frustum)
frustum.update(glCamera(), cameraData().aspectRatio());
}
-QList<QGeoTileSpec> QGeoMapPrivate::updateVisibleTiles()
-{
- QList<QVector3D> points;
-
- points.append(pointsOnLineWithZ(frustum_.topLeftNear(), frustum_.topLeftFar(), baseHeight_));
- points.append(pointsOnLineWithZ(frustum_.topRightNear(), frustum_.topRightFar(), baseHeight_));
- points.append(pointsOnLineWithZ(frustum_.bottomLeftNear(), frustum_.bottomLeftFar(), baseHeight_));
- points.append(pointsOnLineWithZ(frustum_.bottomRightNear(), frustum_.bottomRightFar(), baseHeight_));
-
- points.append(pointsOnLineWithZ(frustum_.topLeftNear(), frustum_.bottomLeftNear(), baseHeight_));
- points.append(pointsOnLineWithZ(frustum_.bottomLeftNear(), frustum_.bottomRightNear(), baseHeight_));
- points.append(pointsOnLineWithZ(frustum_.bottomRightNear(), frustum_.topRightNear(), baseHeight_));
- points.append(pointsOnLineWithZ(frustum_.topRightNear(), frustum_.topLeftNear(), baseHeight_));
-
- points.append(pointsOnLineWithZ(frustum_.topLeftFar(), frustum_.bottomLeftFar(), baseHeight_));
- points.append(pointsOnLineWithZ(frustum_.bottomLeftFar(), frustum_.bottomRightFar(), baseHeight_));
- points.append(pointsOnLineWithZ(frustum_.bottomRightFar(), frustum_.topRightFar(), baseHeight_));
- points.append(pointsOnLineWithZ(frustum_.topRightFar(), frustum_.topLeftFar(), baseHeight_));
-
- QList<QGeoTileSpec> tiles;
-
- if (points.isEmpty())
- return tiles;
-
- // sort points into a right handed polygon
-
- LengthSorter sorter;
-
- // - initial sort to remove duplicates
- sorter.base = points.first();
- qSort(points.begin(), points.end(), sorter);
- for (int i = points.size() - 1; i > 0; --i) {
- if (points.at(i) == points.at(i - 1))
- points.removeAt(i);
- }
-
- // - proper sort
- // - start with the first point, put it in the sorted part of the list
- // - add the nearest unsorted point to the last sorted point to the end
- // of the sorted points
- QList<QVector3D>::iterator i;
- for (i = points.begin(); i != points.end(); ++i) {
- sorter.base = *i;
- if (i + 1 != points.end())
- qSort(i + 1, points.end(), sorter);
- }
-
- // - determine if what we have is right handed
- if (points.size() >= 3) {
- QVector3D normal = QVector3D::normal(points.at(1) - points.at(0),
- points.at(2) - points.at(1));
- // - if not, reverse the list
- if (normal.z() < 0.0) {
- int s = points.size();
- int s2 = s / 2;
- for (int i = 0; i < s2; ++i) {
- points.swap(i, s - 1 - i);
- }
- }
- }
-
- // work out if the polygon needs clipping
- // - if we go off the far right edge we need to clip into
- // two regions - one which rounds down now and one which rounds up
- // - otherwise if we cross an edge of the map we just need to clip
- // to the map square
-
- bool round = false;
- bool clip = false;
- for (int i = 0; i < points.size(); ++i) {
- QVector3D p = points.at(i);
- if (p.x() >= sideLength_) {
- round = true;
- break;
- }
- if ((p.x() < 0)
- || (sideLength_ < p.x())
- || (p.y() < 0)
- || (sideLength_ < p.y())) {
- clip = true;
- }
- }
-
- if (!round) {
- if (!clip) {
- tiles.append(tilesFromPoints(points.toVector(), false));
- } else {
- QPair<QList<QVector3D>,QList<QVector3D> > pair = clipPolygonToMap(points);
- if (!pair.first.isEmpty())
- tiles.append(tilesFromPoints(pair.first.toVector(), true));
- if (!pair.second.isEmpty())
- tiles.append(tilesFromPoints(pair.second.toVector(), false));
- }
- } else {
- QPair<QList<QVector3D>,QList<QVector3D> > pair = clipPolygonToMap(points);
- if (!pair.first.isEmpty()) {
- QPair<QList<QVector3D>, QList<QVector3D> > split = splitPolygonX(pair.first, sideLength_ / 2.0);
- if (!split.first.isEmpty()) {
- tiles.append(tilesFromPoints(split.first.toVector(), false));
- }
- if (!split.second.isEmpty()) {
- tiles.append(tilesFromPoints(split.second.toVector(), true));
- }
- }
- if (!pair.second.isEmpty()) {
- QPair<QList<QVector3D>, QList<QVector3D> > split = splitPolygonX(pair.second, sideLength_ / 2.0);
- if (!split.first.isEmpty()) {
- tiles.append(tilesFromPoints(split.first.toVector(), false));
- }
- if (!split.second.isEmpty()) {
- tiles.append(tilesFromPoints(split.second.toVector(), true));
- }
- }
- }
-
- return tiles;
-}
-
-QList<QGeoTileSpec> QGeoMapPrivate::tilesFromPoints(const QVector<QVector3D> &points, bool roundUp) const
-{
- int numPoints = points.size();
-
- if (numPoints == 0)
- return QList<QGeoTileSpec>();
-
- int zoomLevel = cameraData().zoomLevel();
-
- int minY = -1;
- int maxY = -1;
-
- QVector<QVector2D> tiles(points.size());
- for (int i = 0; i < numPoints; ++i) {
- QVector2D t = pointToTile(points.at(i), zoomLevel, roundUp);
- if (minY == -1) {
- minY = t.y();
- maxY = t.y();
- } else {
- minY = qMin(minY, static_cast<int>(t.y()));
- maxY = qMax(maxY, static_cast<int>(t.y()));
- }
- tiles[i] = t;
- }
-
- TileMap map(minY, maxY);
-
- for (int i1 = 0; i1 < numPoints; ++i1) {
- int i2 = (i1 + 1) % numPoints;
- tilesFromLine(points.at(i1), points.at(i2), tiles.at(i1), tiles.at(i2), zoomLevel, map);
- }
-
- QList<QGeoTileSpec> results;
-
- results.reserve(map.size);
-
- int size = map.minX.size();
- for (int i = 0; i < size; ++i) {
- int y = map.minY + i;
- int minX = map.minX[i];
- int maxX = map.maxX[i];
- for (int x = minX; x <= maxX; ++x)
- results << QGeoTileSpec(pluginString_, activeMapType().mapId(), zoomLevel, x, y);
- }
-
- return results;
-}
-
-void QGeoMapPrivate::tilesFromLine(const QVector3D &p1,
- const QVector3D &p2,
- const QVector2D &t1,
- const QVector2D &t2,
- int zoomLevel,
- TileMap &map) const
-{
- IntersectGenerator xGen = IntersectGenerator(this, p1.x(), p2.x(), t1.x(), t2.x(),
- IntersectGenerator::XAxis, zoomLevel);
- IntersectGenerator yGen = IntersectGenerator(this, p1.y(), p2.y(), t1.y(), t2.y(),
- IntersectGenerator::YAxis, zoomLevel);
-
- int tileX = t1.x();
- int tileY = t1.y();
-
- map.adjust(tileX, tileY);
-
- while (xGen.hasNext() && yGen.hasNext()) {
- QPair<double, int> x = xGen.value();
- QPair<double, int> y = yGen.value();
- if (x.first < y.first) {
- tileX = x.second;
- map.adjust(tileX, tileY);
- xGen.next();
- } else if (x.first > y.first) {
- tileY = y.second;
- map.adjust(tileX, tileY);
- yGen.next();
- } else {
- map.adjust(tileX, y.second);
- map.adjust(x.second, tileY);
- tileX = x.second;
- tileY = y.second;
- map.adjust(tileX, tileY);
- xGen.next();
- yGen.next();
- }
- }
-
- while (xGen.hasNext()) {
- tileX = xGen.value().second;
- map.adjust(tileX, tileY);
- xGen.next();
- }
-
- while (yGen.hasNext()) {
- tileY = yGen.value().second;
- map.adjust(tileX, tileY);
- yGen.next();
- }
-}
-
-QPair<QList<QVector3D>,QList<QVector3D> > QGeoMapPrivate::clipPolygonToMap(const QList<QVector3D> &points) const
-{
- bool clipX0 = false;
- bool clipX1 = false;
- bool clipY0 = false;
- bool clipY1 = false;
- int size = points.size();
- for (int i = 0; i < size; ++i) {
- QVector3D p = points.at(i);
- if (p.x() < 0.0)
- clipX0 = true;
- if (sideLength_ < p.x())
- clipX1 = true;
- if (p.y() < 0.0)
- clipY0 = true;
- if (sideLength_ < p.y())
- clipY1 = true;
-
- }
-
- QList<QVector3D> results = points;
-
- if (clipY0) {
- results = splitPolygonY(results, 0.0).second;
- }
-
- if (clipY1) {
- results = splitPolygonY(results, sideLength_).first;
- }
-
- if (clipX0) {
- if (clipX1) {
- results = splitPolygonX(results, 0.0).second;
- results = splitPolygonX(results, sideLength_).first;
- return QPair<QList<QVector3D>,QList<QVector3D> >(results, QList<QVector3D>());
- } else {
- QPair<QList<QVector3D>,QList<QVector3D> > pair = splitPolygonX(results, 0.0);
- for (int i = 0; i < pair.first.size(); ++i) {
- pair.first[i].setX(pair.first.at(i).x() + sideLength_);
- }
- return pair;
- }
- } else {
- if (clipX1) {
- QPair<QList<QVector3D>,QList<QVector3D> > pair = splitPolygonX(results, sideLength_);
- for (int i = 0; i < pair.second.size(); ++i) {
- pair.second[i].setX(pair.second.at(i).x() - sideLength_);
- }
- return pair;
- } else {
- return QPair<QList<QVector3D>,QList<QVector3D> >(results, QList<QVector3D>());
- }
- }
-}
-
-QPair<QList<QVector3D>,QList<QVector3D> > QGeoMapPrivate::splitPolygonY(const QList<QVector3D> &points, double y) const
-{
- QList<QVector3D> pointsBelow;
- QList<QVector3D> pointsAbove;
-
- int size = points.size();
-
- if (size == 0) {
- return QPair<QList<QVector3D>,QList<QVector3D> >(pointsBelow, pointsAbove);
- }
-
- bool allAbove = true;
- bool allBelow = true;
-
- for (int i = 0; i < size; ++i) {
- double py = points.at(i).y();
- if (py < y)
- allAbove = false;
- if (y < py)
- allBelow = false;
- }
-
- if (allAbove) {
- if (allBelow) {
- return QPair<QList<QVector3D>,QList<QVector3D> >(pointsBelow, pointsAbove);
- } else {
- return QPair<QList<QVector3D>,QList<QVector3D> >(pointsBelow, points);
- }
- } else {
- if (allBelow) {
- return QPair<QList<QVector3D>,QList<QVector3D> >(points, pointsAbove);
- }
- }
-
-
- int intersect1 = -1;
- int intersect2 = -1;
-
- // add intersects
-
- QList<QVector3D> tmpPoints = points;
-
- for (int i1 = 0; i1 < size; ++i1) {
- int i2 = (i1 + 1) % size;
-
- QVector3D p1 = tmpPoints.at(i1);
- QVector3D p2 = tmpPoints.at(i2);
-
- if (p1.y() == y) {
- if (intersect1 == -1)
- intersect1 = i1;
- else if (intersect2 == -1)
- intersect2 = i1;
- else
- qDebug() << __FUNCTION__ << " more than 2 intersections";
- }
-
- if (((p1.y() < y) && (y < p2.y()))
- || ((p2.y() < y) && (y < p1.y()))) {
- QList<QVector3D> newPoints = pointsOnLineWithY(p1, p2, y);
- if (newPoints.size() == 1) {
- tmpPoints.insert(i1 + 1, newPoints.at(0));
- ++size;
- // will get added to intersect1 or intersect 2 in next iteration
- }
- }
- }
-
- // split at intersects
- if ((intersect1 != -1) && (intersect2 != -1)) {
-
- size = tmpPoints.size();
-
- bool firstBelow = true;
-
- for (int i = intersect1; i <= intersect2; ++i) {
- QVector3D p = tmpPoints.at(i);
- if (y < p.y())
- firstBelow = false;
- pointsBelow.append(p);
- }
-
- for (int i = intersect2; i <= intersect1 + size; ++i) {
- pointsAbove.append(tmpPoints.at(i % size));
- }
-
- if (firstBelow)
- return QPair<QList<QVector3D>,QList<QVector3D> >(pointsBelow, pointsAbove);
- else
- return QPair<QList<QVector3D>,QList<QVector3D> >(pointsAbove, pointsBelow);
-
- } else {
- qDebug() << __FUNCTION__ << " less than 2 intersections";
- }
-
- return QPair<QList<QVector3D>,QList<QVector3D> >(pointsBelow, pointsAbove);
-}
-
-QPair<QList<QVector3D>,QList<QVector3D> > QGeoMapPrivate::splitPolygonX(const QList<QVector3D> &points, double x) const
-{
- QList<QVector3D> pointsBelow;
- QList<QVector3D> pointsAbove;
-
- int size = points.size();
-
- if (size == 0) {
- return QPair<QList<QVector3D>,QList<QVector3D> >(pointsBelow, pointsAbove);
- }
-
- bool allAbove = true;
- bool allBelow = true;
-
- for (int i = 0; i < size; ++i) {
- double px = points.at(i).x();
- if (px < x)
- allAbove = false;
- if (x < px)
- allBelow = false;
- }
-
- if (allAbove) {
- if (allBelow) {
- return QPair<QList<QVector3D>,QList<QVector3D> >(pointsBelow, pointsAbove);
- } else {
- return QPair<QList<QVector3D>,QList<QVector3D> >(pointsBelow, points);
- }
- } else {
- if (allBelow) {
- return QPair<QList<QVector3D>,QList<QVector3D> >(points, pointsAbove);
- }
- }
-
- int intersect1 = -1;
- int intersect2 = -1;
-
- // add intersects
-
- QList<QVector3D> tmpPoints = points;
-
- for (int i1 = 0; i1 < size; ++i1) {
- int i2 = (i1 + 1) % size;
-
- QVector3D p1 = tmpPoints.at(i1);
- QVector3D p2 = tmpPoints.at(i2);
-
- if (p1.x() == x) {
- if (intersect1 == -1)
- intersect1 = i1;
- else if (intersect2 == -1)
- intersect2 = i1;
- else
- qDebug() << __FUNCTION__ << " more than 2 intersections";
- }
-
- if (((p1.x() < x) && (x < p2.x()))
- || ((p2.x() < x) && (x < p1.x()))) {
- QList<QVector3D> newPoints = pointsOnLineWithX(p1, p2, x);
- if (newPoints.size() == 1) {
- tmpPoints.insert(i1 + 1, newPoints.at(0));
- ++size;
- // will get added to intersect1 or intersect 2 in next iteration
- }
- }
- }
-
- // split at intersects
- if ((intersect1 != -1) && (intersect2 != -1)) {
-
- size = tmpPoints.size();
-
- bool firstBelow = true;
-
- for (int i = intersect1; i <= intersect2; ++i) {
- QVector3D p = tmpPoints.at(i);
- if (x < p.x())
- firstBelow = false;
- pointsBelow.append(p);
- }
-
- for (int i = intersect2; i <= intersect1 + size; ++i) {
- pointsAbove.append(tmpPoints.at(i % size));
- }
-
- if (firstBelow)
- return QPair<QList<QVector3D>,QList<QVector3D> >(pointsBelow, pointsAbove);
- else
- return QPair<QList<QVector3D>,QList<QVector3D> >(pointsAbove, pointsBelow);
-
- } else {
- qDebug() << __FUNCTION__ << " less than 2 intersections";
- }
-
- return QPair<QList<QVector3D>,QList<QVector3D> >(pointsBelow, pointsAbove);
-}
-
-QList<QVector3D> QGeoMapPrivate::pointsOnLineWithX(const QVector3D &p1, const QVector3D &p2, double x) const
-{
- QList<QVector3D> results;
-
- if (p1.x() == p2.x()) {
- if (p1.x() == x) {
- results.append(p1);
- results.append(p2);
- }
- } else {
- double f = (p1.x() - x) / (p1.x() - p2.x());
- if ((0 <= f) && (f <= 1.0))
- results.append((1 - f) * p1 + f * p2);
- }
-
- return results;
-}
-
-QList<QVector3D> QGeoMapPrivate::pointsOnLineWithY(const QVector3D &p1, const QVector3D &p2, double y) const
-{
- QList<QVector3D> results;
-
- if (p1.y() == p2.y()) {
- if (p1.y() == y) {
- results.append(p1);
- results.append(p2);
- }
- } else {
- double f = (p1.y() - y) / (p1.y() - p2.y());
- if ((0 <= f) && (f <= 1.0))
- results.append((1 - f) * p1 + f * p2);
- }
-
- return results;
-}
-
-QList<QVector3D> QGeoMapPrivate::pointsOnLineWithZ(const QVector3D &p1, const QVector3D &p2, double z) const
-{
- QList<QVector3D> results;
-
- if (p1.z() == p2.z()) {
- if (p1.z() == z) {
- results.append(p1);
- results.append(p2);
- }
- } else {
- double f = (p1.z() - z) / (p1.z() - p2.z());
- if ((0 <= f) && (f <= 1.0))
- results.append((1 - f) * p1 + f * p2);
- }
-
- return results;
-}
-
QT_END_NAMESPACE