/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtLocation module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qgeoprojection_p.h"
#include <QtPositioning/private/qwebmercator_p.h>
#include <QtPositioning/private/qlocationutils_p.h>
#include <QtPositioning/private/qclipperutils_p.h>
#include <QtPositioning/QGeoPolygon>
#include <QtPositioning/QGeoRectangle>
#include <QSize>
#include <QtGui/QMatrix4x4>
#include <cmath>

namespace {
    static const double defaultTileSize = 256.0;
    static const QDoubleVector3D xyNormal(0.0, 0.0, 1.0);
    static const QGeoProjectionWebMercator::Plane xyPlane(QDoubleVector3D(0,0,0), QDoubleVector3D(0,0,1));
    static const QList<QDoubleVector2D> mercatorGeometry = {
                                                QDoubleVector2D(-1.0,0.0),
                                                QDoubleVector2D( 2.0,0.0),
                                                QDoubleVector2D( 2.0,1.0),
                                                QDoubleVector2D(-1.0,1.0) };
}

static QMatrix4x4 toMatrix4x4(const QDoubleMatrix4x4 &m)
{
    return QMatrix4x4(m(0,0), m(0,1), m(0,2), m(0,3),
                      m(1,0), m(1,1), m(1,2), m(1,3),
                      m(2,0), m(2,1), m(2,2), m(2,3),
                      m(3,0), m(3,1), m(3,2), m(3,3));
}

static QPointF centerOffset(const QSizeF &screenSize, const QRectF &visibleArea)
{
    QRectF va = visibleArea;
    if (va.isNull())
        va = QRectF(0, 0, screenSize.width(), screenSize.height());

    QRectF screen = QRectF(QPointF(0,0),screenSize);
    QPointF vaCenter = va.center();

    QPointF screenCenter = screen.center();
    QPointF diff = screenCenter - vaCenter;

    return diff;
}

static QPointF marginsOffset(const QSizeF &screenSize, const QRectF &visibleArea)
{
    QPointF diff = centerOffset(screenSize, visibleArea);
    qreal xdiffpct = diff.x() / qMax<double>(screenSize.width() - 1, 1);
    qreal ydiffpct = diff.y() / qMax<double>(screenSize.height() - 1, 1);

    return QPointF(-xdiffpct, -ydiffpct);
}

QT_BEGIN_NAMESPACE

QGeoProjection::QGeoProjection()
{

}

QGeoProjection::~QGeoProjection()
{

}

QGeoCoordinate QGeoProjection::anchorCoordinateToPoint(const QGeoCoordinate &coordinate, const QPointF &anchorPoint) const
{
    Q_UNUSED(coordinate);
    Q_UNUSED(anchorPoint);
    return QGeoCoordinate();
}

QGeoShape QGeoProjection::visibleRegion() const
{
    return QGeoShape();
}

bool QGeoProjection::setBearing(qreal bearing, const QGeoCoordinate &coordinate)
{
    Q_UNUSED(bearing);
    Q_UNUSED(coordinate);
    return false;
}


/*
 * QGeoProjectionWebMercator implementation
*/

QGeoCoordinate QGeoProjectionWebMercator::anchorCoordinateToPoint(const QGeoCoordinate &coordinate, const QPointF &anchorPoint) const
{
    // Approach: find the displacement in (wrapped) mercator space, and apply that to the center
    QDoubleVector2D centerProj = geoToWrappedMapProjection(cameraData().center());
    QDoubleVector2D coordProj  = geoToWrappedMapProjection(coordinate);

    QDoubleVector2D anchorProj = itemPositionToWrappedMapProjection(QDoubleVector2D(anchorPoint));
    // Y-clamping done in mercatorToCoord
    return wrappedMapProjectionToGeo(centerProj + coordProj - anchorProj);
}

bool QGeoProjectionWebMercator::setBearing(qreal bearing, const QGeoCoordinate &coordinate)
{
    const QDoubleVector2D coordWrapped = geoToWrappedMapProjection(coordinate);
    if (!isProjectable(coordWrapped))
        return false;
    const QPointF rotationPoint = wrappedMapProjectionToItemPosition(coordWrapped).toPointF();

    QGeoCameraData camera = cameraData();
    // first set bearing
    camera.setBearing(bearing);
    setCameraData(camera);
    camera = cameraData();

    // then reanchor
    const QGeoCoordinate center = anchorCoordinateToPoint(coordinate, rotationPoint);
    camera.setCenter(center);
    setCameraData(camera);
    return true;
}

QGeoProjectionWebMercator::QGeoProjectionWebMercator()
    : QGeoProjection(),
      m_mapEdgeSize(256), // at zl 0
      m_minimumZoom(0),
      m_cameraCenterXMercator(0),
      m_cameraCenterYMercator(0),
      m_viewportWidth(1),
      m_viewportHeight(1),
      m_1_viewportWidth(0),
      m_1_viewportHeight(0),
      m_sideLengthPixels(256),
      m_aperture(0.0),
      m_nearPlane(0.0),
      m_farPlane(0.0),
      m_halfWidth(0.0),
      m_halfHeight(0.0),
      m_minimumUnprojectableY(0.0),
      m_verticalEstateToSkip(0.0),
      m_visibleRegionDirty(false)
{
}

QGeoProjectionWebMercator::~QGeoProjectionWebMercator()
{

}

// This method returns the minimum zoom level that this specific qgeomap type allows
// at the current viewport size and for the default tile size of 256^2.
double QGeoProjectionWebMercator::minimumZoom() const
{
    return m_minimumZoom;
}

// This method recalculates the "no-trespassing" limits for the map center.
// This has to be used when:
// 1) the map is resized, because the meters per pixel remain the same, but
//    the amount of pixels between the center and the borders changes
// 2) when the zoom level changes, because the amount of pixels between the center
//    and the borders stays the same, but the meters per pixel change
double QGeoProjectionWebMercator::maximumCenterLatitudeAtZoom(const QGeoCameraData &cameraData) const
{
    double mapEdgeSize = std::pow(2.0, cameraData.zoomLevel()) * defaultTileSize;

    // At init time weird things happen
    int clampedWindowHeight = (m_viewportHeight > mapEdgeSize) ? mapEdgeSize : m_viewportHeight;
    QPointF offsetPct = centerOffset(QSizeF(m_viewportWidth, m_viewportHeight), m_visibleArea);
    double hpct = offsetPct.y() / qMax<double>(m_viewportHeight - 1, 1);

    // Use the window height divided by 2 as the topmost allowed center, with respect to the map size in pixels
    double mercatorTopmost = (clampedWindowHeight * (0.5 - hpct)) /  mapEdgeSize ;
    QGeoCoordinate topMost = QWebMercator::mercatorToCoord(QDoubleVector2D(0.0, mercatorTopmost));
    return topMost.latitude();
}

double QGeoProjectionWebMercator::minimumCenterLatitudeAtZoom(const QGeoCameraData &cameraData) const
{
    double mapEdgeSize = std::pow(2.0, cameraData.zoomLevel()) * defaultTileSize;

    // At init time weird things happen
    int clampedWindowHeight = (m_viewportHeight > mapEdgeSize) ? mapEdgeSize : m_viewportHeight;
    QPointF offsetPct = centerOffset(QSizeF(m_viewportWidth, m_viewportHeight), m_visibleArea);
    double hpct = offsetPct.y() / qMax<double>(m_viewportHeight - 1, 1);

    // Use the window height divided by 2 as the topmost allowed center, with respect to the map size in pixels
    double mercatorTopmost = (clampedWindowHeight * (0.5 + hpct)) /  mapEdgeSize ;
    QGeoCoordinate topMost = QWebMercator::mercatorToCoord(QDoubleVector2D(0.0, mercatorTopmost));
    return -topMost.latitude();
}

void QGeoProjectionWebMercator::setVisibleArea(const QRectF &visibleArea)
{
    m_visibleArea = visibleArea;
    setupCamera();
}

double QGeoProjectionWebMercator::mapWidth() const
{
    return m_mapEdgeSize;
}

double QGeoProjectionWebMercator::mapHeight() const
{
    return m_mapEdgeSize;
}

void QGeoProjectionWebMercator::setViewportSize(const QSize &size)
{
    if (int(m_viewportWidth) ==  size.width() && int(m_viewportHeight) == size.height())
        return;

    m_viewportWidth = size.width();
    m_viewportHeight = size.height();
    m_1_viewportWidth = 1.0 / m_viewportWidth;
    m_1_viewportHeight = 1.0 / m_viewportHeight;
    m_minimumZoom =  std::log(qMax(m_viewportWidth, m_viewportHeight) / defaultTileSize) / std::log(2.0);
    setupCamera();
}

void QGeoProjectionWebMercator::setCameraData(const QGeoCameraData &cameraData, bool force)
{
    if (m_cameraData == cameraData && !force)
        return;

    m_cameraData = cameraData;
    m_mapEdgeSize = std::pow(2.0, cameraData.zoomLevel()) * defaultTileSize;
    setupCamera();
}

QDoubleVector2D QGeoProjectionWebMercator::geoToMapProjection(const QGeoCoordinate &coordinate) const
{
    return QWebMercator::coordToMercator(coordinate);
}

QGeoCoordinate QGeoProjectionWebMercator::mapProjectionToGeo(const QDoubleVector2D &projection) const
{
    return QWebMercator::mercatorToCoord(projection);
}

//wraps around center
QDoubleVector2D QGeoProjectionWebMercator::wrapMapProjection(const QDoubleVector2D &projection) const
{
    double x = projection.x();
    if (m_cameraCenterXMercator < 0.5) {
        if (x - m_cameraCenterXMercator > 0.5 )
            x -= 1.0;
    } else if (m_cameraCenterXMercator > 0.5) {
        if (x - m_cameraCenterXMercator < -0.5 )
            x += 1.0;
    }

    return QDoubleVector2D(x, projection.y());
}

QDoubleVector2D QGeoProjectionWebMercator::unwrapMapProjection(const QDoubleVector2D &wrappedProjection) const
{
    double x = wrappedProjection.x();
    if (x > 1.0)
        return QDoubleVector2D(x - 1.0, wrappedProjection.y());
    if (x <= 0.0)
        return QDoubleVector2D(x + 1.0, wrappedProjection.y());
    return wrappedProjection;
}

QDoubleVector2D QGeoProjectionWebMercator::wrappedMapProjectionToItemPosition(const QDoubleVector2D &wrappedProjection) const
{
    return (m_transformation * wrappedProjection).toVector2D();
}

QDoubleVector2D QGeoProjectionWebMercator::itemPositionToWrappedMapProjection(const QDoubleVector2D &itemPosition) const
{
    const QPointF centerOff = centerOffset(QSizeF(m_viewportWidth, m_viewportHeight), m_visibleArea);
    QDoubleVector2D pos = itemPosition + QDoubleVector2D(centerOff);
    pos *= QDoubleVector2D(m_1_viewportWidth, m_1_viewportHeight);
    pos *= 2.0;
    pos -= QDoubleVector2D(1.0,1.0);

    double s;
    QDoubleVector2D res = viewportToWrappedMapProjection(pos, s);

    // a positive s means a point behind the camera. So do it again, after clamping Y. See QTBUG-61813
    if (s > 0.0) {
        pos = itemPosition;
        // when the camera is tilted, picking a point above the horizon returns a coordinate behind the camera
        pos.setY(m_minimumUnprojectableY);
        pos *= QDoubleVector2D(m_1_viewportWidth, m_1_viewportHeight);
        pos *= 2.0;
        pos -= QDoubleVector2D(1.0,1.0);
        res = viewportToWrappedMapProjection(pos, s);
    }

    return res;
}

/* Default implementations */
QGeoCoordinate QGeoProjectionWebMercator::itemPositionToCoordinate(const QDoubleVector2D &pos, bool clipToViewport) const
{
    if (qIsNaN(pos.x()) || qIsNaN(pos.y()))
        return QGeoCoordinate();

    if (clipToViewport) {
        int w = m_viewportWidth;
        int h = m_viewportHeight;

        if ((pos.x() < 0) || (w < pos.x()) || (pos.y() < 0) || (h < pos.y()))
            return QGeoCoordinate();
    }

    QDoubleVector2D wrappedMapProjection = itemPositionToWrappedMapProjection(pos);
    // With rotation/tilting, a screen position might end up outside the projection space.
    if (!isProjectable(wrappedMapProjection))
        return QGeoCoordinate();
    return mapProjectionToGeo(unwrapMapProjection(wrappedMapProjection));
}

QDoubleVector2D QGeoProjectionWebMercator::coordinateToItemPosition(const QGeoCoordinate &coordinate, bool clipToViewport) const
{
    if (!coordinate.isValid())
        return QDoubleVector2D(qQNaN(), qQNaN());

    QDoubleVector2D wrappedProjection = wrapMapProjection(geoToMapProjection(coordinate));
    if (!isProjectable(wrappedProjection))
        return QDoubleVector2D(qQNaN(), qQNaN());

    QDoubleVector2D pos = wrappedMapProjectionToItemPosition(wrappedProjection);

    if (clipToViewport) {
        int w = m_viewportWidth;
        int h = m_viewportHeight;
        double x = pos.x();
        double y = pos.y();
        if ((x < -0.5) || (x > w + 0.5) || (y < -0.5) || (y > h + 0.5) || qIsNaN(x) || qIsNaN(y))
            return QDoubleVector2D(qQNaN(), qQNaN());
    }
    return pos;
}

QDoubleVector2D QGeoProjectionWebMercator::geoToWrappedMapProjection(const QGeoCoordinate &coordinate) const
{
    return wrapMapProjection(geoToMapProjection(coordinate));
}

QGeoCoordinate QGeoProjectionWebMercator::wrappedMapProjectionToGeo(const QDoubleVector2D &wrappedProjection) const
{
    return mapProjectionToGeo(unwrapMapProjection(wrappedProjection));
}

QMatrix4x4 QGeoProjectionWebMercator::quickItemTransformation(const QGeoCoordinate &coordinate, const QPointF &anchorPoint, qreal zoomLevel) const
{
    const QDoubleVector2D coordWrapped = geoToWrappedMapProjection(coordinate);
    double scale = std::pow(0.5, zoomLevel - m_cameraData.zoomLevel());
    const QDoubleVector2D anchorScaled = QDoubleVector2D(anchorPoint.x(), anchorPoint.y()) * scale;
    const QDoubleVector2D anchorMercator = anchorScaled / mapWidth();

    const QDoubleVector2D coordAnchored = coordWrapped - anchorMercator;
    const QDoubleVector2D coordAnchoredScaled = coordAnchored * m_sideLengthPixels;
    QDoubleMatrix4x4 matTranslateScale;
    matTranslateScale.translate(coordAnchoredScaled.x(), coordAnchoredScaled.y(), 0.0);

    scale = std::pow(0.5, (zoomLevel - std::floor(zoomLevel)) +
                     (std::floor(zoomLevel) - std::floor(m_cameraData.zoomLevel())));
    matTranslateScale.scale(scale);

    /*
     *  The full transformation chain for quickItemTransformation() would be:
     *  matScreenShift * m_quickItemTransformation * matTranslate * matScale
     *  where:
     *  matScreenShift = translate(-coordOnScreen.x(), -coordOnScreen.y(), 0)
     *  matTranslate = translate(coordAnchoredScaled.x(), coordAnchoredScaled.y(), 0.0)
     *  matScale = scale(scale)
     *
     *  However, matScreenShift is removed, as setPosition(0,0) is used in place of setPositionOnScreen.
     */

    return toMatrix4x4(m_quickItemTransformation * matTranslateScale);
}

bool QGeoProjectionWebMercator::isProjectable(const QDoubleVector2D &wrappedProjection) const
{
    if (m_cameraData.tilt() == 0.0)
        return true;

    QDoubleVector3D pos = wrappedProjection * m_sideLengthPixels;
    // use m_centerNearPlane in order to add an offset to m_eye.
    QDoubleVector3D p = m_centerNearPlane - pos;
    double dot = QDoubleVector3D::dotProduct(p , m_viewNormalized);

    if (dot < 0.0) // behind the near plane
        return false;
    return true;
}

QList<QDoubleVector2D> QGeoProjectionWebMercator::visibleGeometry() const
{
    if (m_visibleRegionDirty)
        const_cast<QGeoProjectionWebMercator *>(this)->updateVisibleRegion();
    return m_visibleRegion;
}

QList<QDoubleVector2D> QGeoProjectionWebMercator::visibleGeometryExpanded() const
{
    if (m_visibleRegionDirty)
        const_cast<QGeoProjectionWebMercator *>(this)->updateVisibleRegion();
    return m_visibleRegionExpanded;
}

QList<QDoubleVector2D> QGeoProjectionWebMercator::projectableGeometry() const
{
    if (m_visibleRegionDirty)
        const_cast<QGeoProjectionWebMercator *>(this)->updateVisibleRegion();
    return m_projectableRegion;
}

QGeoShape QGeoProjectionWebMercator::visibleRegion() const
{
    const QList<QDoubleVector2D> &visibleRegion = visibleGeometry();
    QGeoPolygon poly;
    for (int i = 0; i < visibleRegion.size(); ++i) {
         const QDoubleVector2D &c = visibleRegion.at(i);
        // If a segment spans more than half of the map longitudinally, split in 2.
        if (i && qAbs(visibleRegion.at(i-1).x() - c.x()) >= 0.5) { // This assumes a segment is never >= 1.0 (whole map span)
            QDoubleVector2D extraPoint = (visibleRegion.at(i-1) + c) * 0.5;
            poly.addCoordinate(wrappedMapProjectionToGeo(extraPoint));
        }
        poly.addCoordinate(wrappedMapProjectionToGeo(c));
    }
    if (visibleRegion.size() >= 2 && qAbs(visibleRegion.last().x() - visibleRegion.first().x()) >= 0.5) {
        QDoubleVector2D extraPoint = (visibleRegion.last() + visibleRegion.first()) * 0.5;
        poly.addCoordinate(wrappedMapProjectionToGeo(extraPoint));
    }

    return poly;
}

QDoubleVector2D QGeoProjectionWebMercator::viewportToWrappedMapProjection(const QDoubleVector2D &itemPosition) const
{
    double s;
    return viewportToWrappedMapProjection(itemPosition, s);
}

/*
    actual implementation of itemPositionToWrappedMapProjection
*/
QDoubleVector2D QGeoProjectionWebMercator::viewportToWrappedMapProjection(const QDoubleVector2D &itemPosition, double &s) const
{
    QDoubleVector2D pos = itemPosition;
    pos *= QDoubleVector2D(m_halfWidth, m_halfHeight);

    // determine itemPosition on the near plane
    QDoubleVector3D p = m_centerNearPlane;
    p += m_up * pos.y();
    p += m_side * pos.x();

    // compute the ray using the eye position
    QDoubleVector3D ray = m_eye - p;
    ray.normalize();

    return (xyPlane.lineIntersection(m_eye, ray, s) / m_sideLengthPixels).toVector2D();
}

/*
    Returns a pair of <newCenter, newZoom>
*/
QPair<QGeoCoordinate, qreal> QGeoProjectionWebMercator::fitViewportToGeoRectangle(const QGeoRectangle &rectangle,
                                                                                  const QMargins &m) const
{
    QPair<QGeoCoordinate, qreal> res;
    res.second = qQNaN();
    if (m_viewportWidth <= m.left() + m.right() || m_viewportHeight <= m.top() + m.bottom())
        return res;

    QDoubleVector2D topLeftPoint = geoToMapProjection(rectangle.topLeft());
    QDoubleVector2D bottomRightPoint = geoToMapProjection(rectangle.bottomRight());
    if (bottomRightPoint.x() < topLeftPoint.x()) // crossing the dateline
        bottomRightPoint.setX(bottomRightPoint.x() + 1.0);

    // find center of the bounding box
    QDoubleVector2D center = (topLeftPoint + bottomRightPoint) * 0.5;
    center.setX(center.x() > 1.0 ? center.x() - 1.0 : center.x());
    res.first = mapProjectionToGeo(center);

    // if the shape is empty we just change center position, not zoom
    double bboxWidth  = (bottomRightPoint.x() - topLeftPoint.x()) * mapWidth();
    double bboxHeight = (bottomRightPoint.y() - topLeftPoint.y()) * mapHeight();

    if (bboxHeight == 0.0 && bboxWidth == 0.0)
        return res;

    double zoomRatio = qMax(bboxWidth / (m_viewportWidth - m.left() - m.right()),
                            bboxHeight / (m_viewportHeight - m.top() - m.bottom()));
    zoomRatio = std::log(zoomRatio) / std::log(2.0);
    res.second = m_cameraData.zoomLevel() - zoomRatio;

    return  res;
}

QGeoProjection::ProjectionGroup QGeoProjectionWebMercator::projectionGroup() const
{
    return QGeoProjection::ProjectionCylindrical;
}

QGeoProjection::Datum QGeoProjectionWebMercator::datum() const
{
    return QGeoProjection::DatumWGS84;
}

QGeoProjection::ProjectionType QGeoProjectionWebMercator::projectionType() const
{
    return QGeoProjection::ProjectionWebMercator;
}

void QGeoProjectionWebMercator::setupCamera()
{
    m_centerMercator = geoToMapProjection(m_cameraData.center());
    m_cameraCenterXMercator = m_centerMercator.x();
    m_cameraCenterYMercator = m_centerMercator.y();

    int intZoomLevel = static_cast<int>(std::floor(m_cameraData.zoomLevel()));
    m_sideLengthPixels = (1 << intZoomLevel) * defaultTileSize;
    m_center = m_centerMercator * m_sideLengthPixels;
    //aperture(90 / 2) = 1
    m_aperture = tan(QLocationUtils::radians(m_cameraData.fieldOfView()) * 0.5);

    double f = m_viewportHeight;
    double z = std::pow(2.0, m_cameraData.zoomLevel() - intZoomLevel) * defaultTileSize;
    double altitude = f / (2.0 * z);
    // Also in mercator space
    double z_mercator = std::pow(2.0, m_cameraData.zoomLevel()) * defaultTileSize;
    double altitude_mercator = f / (2.0 * z_mercator);

    // calculate eye
    m_eye = m_center;
    m_eye.setZ(altitude * defaultTileSize / m_aperture);

    // And in mercator space
    m_eyeMercator = m_centerMercator;
    m_eyeMercator.setZ(altitude_mercator  / m_aperture);

    m_view = m_eye - m_center;
    QDoubleVector3D side = QDoubleVector3D::normal(m_view, QDoubleVector3D(0.0, 1.0, 0.0));
    m_up = QDoubleVector3D::normal(side, m_view);

    // In mercator space too
    m_viewMercator = m_eyeMercator - m_centerMercator;
    QDoubleVector3D sideMercator = QDoubleVector3D::normal(m_viewMercator, QDoubleVector3D(0.0, 1.0, 0.0));
    m_upMercator = QDoubleVector3D::normal(sideMercator, m_viewMercator);

    if (m_cameraData.bearing() > 0.0) {
        QDoubleMatrix4x4 mBearing;
        mBearing.rotate(m_cameraData.bearing(), m_view);
        m_up = mBearing * m_up;

        // In mercator space too
        QDoubleMatrix4x4 mBearingMercator;
        mBearingMercator.rotate(m_cameraData.bearing(), m_viewMercator);
        m_upMercator = mBearingMercator * m_upMercator;
    }

    m_side = QDoubleVector3D::normal(m_up, m_view);
    m_sideMercator = QDoubleVector3D::normal(m_upMercator, m_viewMercator);

    if (m_cameraData.tilt() > 0.0) { // tilt has been already thresholded by QGeoCameraData::setTilt
        QDoubleMatrix4x4 mTilt;
        mTilt.rotate(-m_cameraData.tilt(), m_side);
        m_eye = mTilt * m_view + m_center;

        // In mercator space too
        QDoubleMatrix4x4 mTiltMercator;
        mTiltMercator.rotate(-m_cameraData.tilt(), m_sideMercator);
        m_eyeMercator = mTiltMercator * m_viewMercator + m_centerMercator;
    }

    m_view = m_eye - m_center; // ToDo: this should be inverted (center - eye), and the rest should follow
    m_viewNormalized = m_view.normalized();
    m_up = QDoubleVector3D::normal(m_view, m_side);

    m_nearPlane = 1.0;
    // At ZL 20 the map has 2^20 tiles per side. That is 1048576.
    // Placing the camera on one corner of the map, rotated toward the opposite corner, and tilted
    // at almost 90 degrees would  require a frustum that can span the whole size of this map.
    // For this reason, the far plane is set to 2 * 2^20 * defaultTileSize.
    // That is, in order to make sure that the whole map would fit in the frustum at this ZL.
    // Since we are using a double matrix, and since the largest value in the matrix is going to be
    // 2 * m_farPlane (as near plane is 1.0), there should be sufficient precision left.
    //
    // TODO: extend this to support clip distance.
    m_farPlane =  (altitude + 2097152.0) * defaultTileSize;

    m_viewMercator = m_eyeMercator - m_centerMercator;
    m_upMercator = QDoubleVector3D::normal(m_viewMercator, m_sideMercator);
    m_nearPlaneMercator = 0.000002; // this value works until ZL 18. Above that, a better progressive formula is needed, or
                                    // else, this clips too much.

    double aspectRatio = 1.0 * m_viewportWidth / m_viewportHeight;

    m_halfWidth = m_aperture * aspectRatio;
    m_halfHeight = m_aperture;

    double verticalHalfFOV = QLocationUtils::degrees(atan(m_aperture));

    QDoubleMatrix4x4 cameraMatrix;
    cameraMatrix.lookAt(m_eye, m_center, m_up);

    QDoubleMatrix4x4 projectionMatrix;
    projectionMatrix.frustum(-m_halfWidth, m_halfWidth, -m_halfHeight, m_halfHeight, m_nearPlane, m_farPlane);

    /*
     * The full transformation chain for m_transformation is:
     * matScreen * matScreenFit * matShift *  projectionMatrix * cameraMatrix * matZoomLevelScale
     * where:
     * matZoomLevelScale = scale(m_sideLength, m_sideLength, 1.0)
     * matShift = translate(1.0, 1.0, 0.0)
     * matScreenFit = scale(0.5, 0.5, 1.0)
     * matScreen = scale(m_viewportWidth, m_viewportHeight, 1.0)
     */

    QPointF offsetPct = marginsOffset(QSizeF(m_viewportWidth, m_viewportHeight), m_visibleArea);
    QDoubleMatrix4x4 matScreenTransformation;
    matScreenTransformation.scale(0.5 * m_viewportWidth, 0.5 * m_viewportHeight, 1.0);
    matScreenTransformation(0,3) = (0.5 + offsetPct.x()) * m_viewportWidth;
    matScreenTransformation(1,3) = (0.5 + offsetPct.y()) * m_viewportHeight;

    m_transformation = matScreenTransformation *  projectionMatrix * cameraMatrix;
    m_quickItemTransformation = m_transformation;
    m_transformation.scale(m_sideLengthPixels, m_sideLengthPixels, 1.0);

    m_centerNearPlane = m_eye - m_viewNormalized;
    m_centerNearPlaneMercator = m_eyeMercator - m_viewNormalized * m_nearPlaneMercator;

    // The method does not support tilting angles >= 90.0 or < 0.

    // The following formula is used to have a growing epsilon with the zoom level,
    // in order not to have too large values at low zl, which would overflow when converted to Clipper::cInt.
    const double upperBoundEpsilon = 1.0 / std::pow(10, 1.0 + m_cameraData.zoomLevel() / 5.0);
    const double elevationUpperBound = 90.0 - upperBoundEpsilon;
    const double maxRayElevation = qMin(elevationUpperBound - m_cameraData.tilt(), verticalHalfFOV);
    double maxHalfAperture = 0;
    m_verticalEstateToSkip = 0;
    if (maxRayElevation < verticalHalfFOV) {
        maxHalfAperture = tan(QLocationUtils::radians(maxRayElevation));
        m_verticalEstateToSkip = 1.0 - maxHalfAperture / m_aperture;
    }

    m_minimumUnprojectableY = m_verticalEstateToSkip * 0.5 * m_viewportHeight; // m_verticalEstateToSkip is relative to half aperture
    m_visibleRegionDirty = true;
}

void QGeoProjectionWebMercator::updateVisibleRegion()
{
    m_visibleRegionDirty = false;

    double viewportHalfWidth  = (!m_visibleArea.isEmpty()) ? m_visibleArea.width() / m_viewportWidth : 1.0;
    double viewportHalfHeight = (!m_visibleArea.isEmpty()) ? m_visibleArea.height() / m_viewportHeight : 1.0;

    double top = qMax<double>(-viewportHalfHeight, -1 + m_verticalEstateToSkip);
    double bottom = viewportHalfHeight;
    double left = -viewportHalfWidth;
    double right = viewportHalfWidth;

    QDoubleVector2D tl = viewportToWrappedMapProjection(QDoubleVector2D(left, top ));
    QDoubleVector2D tr = viewportToWrappedMapProjection(QDoubleVector2D(right, top ));
    QDoubleVector2D bl = viewportToWrappedMapProjection(QDoubleVector2D(left,  bottom ));
    QDoubleVector2D br = viewportToWrappedMapProjection(QDoubleVector2D(right, bottom ));

    // To make sure that what is returned can be safely converted back to lat/lon without risking overlaps
    double mapLeftLongitude = QLocationUtils::mapLeftLongitude(m_cameraData.center().longitude());
    double mapRightLongitude = QLocationUtils::mapRightLongitude(m_cameraData.center().longitude());
    double leftX = geoToWrappedMapProjection(QGeoCoordinate(0, mapLeftLongitude)).x();
    double rightX = geoToWrappedMapProjection(QGeoCoordinate(0, mapRightLongitude)).x();

    QList<QDoubleVector2D> mapRect;
    mapRect.push_back(QDoubleVector2D(leftX, 1.0));
    mapRect.push_back(QDoubleVector2D(rightX, 1.0));
    mapRect.push_back(QDoubleVector2D(rightX, 0.0));
    mapRect.push_back(QDoubleVector2D(leftX, 0.0));

    QList<QDoubleVector2D> viewportRect;
    viewportRect.push_back(bl);
    viewportRect.push_back(br);
    viewportRect.push_back(tr);
    viewportRect.push_back(tl);

    c2t::clip2tri clipper;
    clipper.clearClipper();
    clipper.addSubjectPath(QClipperUtils::qListToPath(mapRect), true);
    clipper.addClipPolygon(QClipperUtils::qListToPath(viewportRect));

    Paths res = clipper.execute(c2t::clip2tri::Intersection);
    m_visibleRegion.clear();
    if (res.size())
        m_visibleRegion = QClipperUtils::pathToQList(res[0]); // Intersection between two convex quadrilaterals should always be a single polygon

    m_projectableRegion.clear();
    mapRect.clear();
    // The full map rectangle in extended mercator space
    mapRect.push_back(QDoubleVector2D(-1.0, 1.0));
    mapRect.push_back(QDoubleVector2D( 2.0, 1.0));
    mapRect.push_back(QDoubleVector2D( 2.0, 0.0));
    mapRect.push_back(QDoubleVector2D(-1.0, 0.0));
    if (m_cameraData.tilt() == 0) {
        m_projectableRegion = mapRect;
    } else {
        QGeoProjectionWebMercator::Plane nearPlane(m_centerNearPlaneMercator, m_viewNormalized);
        Line2D nearPlaneXYIntersection = nearPlane.planeXYIntersection();
        double squareHalfSide = qMax(5.0, nearPlaneXYIntersection.m_point.length());
        QDoubleVector2D viewDirectionProjected = -m_viewNormalized.toVector2D().normalized();


        QDoubleVector2D tl = nearPlaneXYIntersection.m_point
                            - squareHalfSide * nearPlaneXYIntersection.m_direction
                            + 2 * squareHalfSide * viewDirectionProjected;
        QDoubleVector2D tr = nearPlaneXYIntersection.m_point
                            + squareHalfSide * nearPlaneXYIntersection.m_direction
                            + 2 * squareHalfSide * viewDirectionProjected;
        QDoubleVector2D bl = nearPlaneXYIntersection.m_point
                            - squareHalfSide * nearPlaneXYIntersection.m_direction;
        QDoubleVector2D br = nearPlaneXYIntersection.m_point
                            + squareHalfSide * nearPlaneXYIntersection.m_direction;

        QList<QDoubleVector2D> projectableRect;
        projectableRect.push_back(bl);
        projectableRect.push_back(br);
        projectableRect.push_back(tr);
        projectableRect.push_back(tl);


        c2t::clip2tri clipperProjectable;
        clipperProjectable.clearClipper();
        clipperProjectable.addSubjectPath(QClipperUtils::qListToPath(mapRect), true);
        clipperProjectable.addClipPolygon(QClipperUtils::qListToPath(projectableRect));

        Paths resProjectable = clipperProjectable.execute(c2t::clip2tri::Intersection);
        if (resProjectable.size())
            m_projectableRegion = QClipperUtils::pathToQList(resProjectable[0]); // Intersection between two convex quadrilaterals should always be a single polygon
        else
            m_projectableRegion = viewportRect;
    }

    // Compute m_visibleRegionExpanded as a clipped expanded version of m_visibleRegion
    QDoubleVector2D centroid;
    for (const QDoubleVector2D &v: qAsConst(m_visibleRegion))
        centroid += v;
    centroid /= m_visibleRegion.size();

    m_visibleRegionExpanded.clear();
    for (const QDoubleVector2D &v: qAsConst(m_visibleRegion)) {
        const QDoubleVector2D vc = v - centroid;
        m_visibleRegionExpanded.push_back(centroid + vc * 1.2); // fixing expansion factor to 1.2
    }

    c2t::clip2tri clipperExpanded;
    clipperExpanded.clearClipper();
    clipperExpanded.addSubjectPath(QClipperUtils::qListToPath(m_visibleRegionExpanded), true);
    clipperExpanded.addClipPolygon(QClipperUtils::qListToPath(m_projectableRegion));
    Paths resVisibleExpanded = clipperExpanded.execute(c2t::clip2tri::Intersection);
    if (resVisibleExpanded.size())
        m_visibleRegionExpanded = QClipperUtils::pathToQList(resVisibleExpanded[0]); // Intersection between two convex quadrilaterals should always be a single polygon
    else
        m_visibleRegionExpanded = m_visibleRegion;
}

QGeoCameraData QGeoProjectionWebMercator::cameraData() const
{
    return m_cameraData;
}

/*
 *
 *  Line implementation
 *
 */

QGeoProjectionWebMercator::Line2D::Line2D()
{

}

QGeoProjectionWebMercator::Line2D::Line2D(const QDoubleVector2D &linePoint, const QDoubleVector2D &lineDirection)
    :   m_point(linePoint), m_direction(lineDirection.normalized())
{

}

bool QGeoProjectionWebMercator::Line2D::isValid() const
{
    return (m_direction.length() > 0.5);
}

/*
 *
 *  Plane implementation
 *
 */

QGeoProjectionWebMercator::Plane::Plane()
{

}

QGeoProjectionWebMercator::Plane::Plane(const QDoubleVector3D &planePoint, const QDoubleVector3D &planeNormal)
    :   m_point(planePoint), m_normal(planeNormal.normalized()) { }

QDoubleVector3D QGeoProjectionWebMercator::Plane::lineIntersection(const QDoubleVector3D &linePoint, const QDoubleVector3D &lineDirection) const
{
    double s;
    return lineIntersection(linePoint, lineDirection, s);
}

QDoubleVector3D QGeoProjectionWebMercator::Plane::lineIntersection(const QDoubleVector3D &linePoint, const QDoubleVector3D &lineDirection, double &s) const
{
    QDoubleVector3D w = linePoint - m_point;
    // s = -n.dot(w) / n.dot(u).  p = p0 + su; u is lineDirection
    s = QDoubleVector3D::dotProduct(-m_normal, w) / QDoubleVector3D::dotProduct(m_normal, lineDirection);
    return linePoint + lineDirection * s;
}

QGeoProjectionWebMercator::Line2D QGeoProjectionWebMercator::Plane::planeXYIntersection() const
{
    // cross product of the two normals for the line direction
    QDoubleVector3D lineDirection = QDoubleVector3D::crossProduct(m_normal, xyNormal);
    lineDirection.setZ(0.0);
    lineDirection.normalize();

    // cross product of the line direction and the plane normal to find the direction on the plane
    // intersecting the xy plane
    QDoubleVector3D directionToXY = QDoubleVector3D::crossProduct(m_normal, lineDirection);
    QDoubleVector3D p = xyPlane.lineIntersection(m_point, directionToXY);
    return Line2D(p.toVector2D(), lineDirection.toVector2D());
}

bool QGeoProjectionWebMercator::Plane::isValid() const
{
    return (m_normal.length() > 0.5);
}

QT_END_NAMESPACE
