示例#1
0
void tst_QGeoCircle::assignment()
{
    QGeoCircle c1 = QGeoCircle(QGeoCoordinate(10.0, 0.0), 20.0);
    QGeoCircle c2 = QGeoCircle(QGeoCoordinate(20.0, 0.0), 30.0);

    QVERIFY(c1 != c2);

    c2 = c1;
    QCOMPARE(c2.center(), QGeoCoordinate(10.0, 0.0));
    QCOMPARE(c2.radius(), 20.0);
    QCOMPARE(c1, c2);

    c2.setCenter(QGeoCoordinate(30.0, 0.0));
    c2.setRadius(15.0);
    QCOMPARE(c1.center(), QGeoCoordinate(10.0, 0.0));
    QCOMPARE(c1.radius(), 20.0);

    // Assign c1 to an area
    QGeoShape area = c1;
    QCOMPARE(area.type(), c1.type());
    QVERIFY(area == c1);

    // Assign the area back to a bounding circle
    QGeoCircle ca = area;
    QCOMPARE(ca.center(), c1.center());
    QCOMPARE(ca.radius(), c1.radius());

    // Check that the copy is not modified when modifying the original.
    c1.setCenter(QGeoCoordinate(15.0, 15.0));
    QVERIFY(ca.center() != c1.center());
    QVERIFY(ca != c1);
}
void QGeoCodeReplyNokia::networkFinished()
{
    if (!m_reply)
        return;

    if (m_reply->error() != QNetworkReply::NoError) {
        // Removed because this is already done in networkError, which previously caused _two_ errors to be raised for every error.
        //setError(QGeoCodeReply::CommunicationError, m_reply->errorString());
        //m_reply->deleteLater();
        //m_reply = 0;
        return;
    }

    QGeoCodeXmlParser parser;
    if (parser.parse(m_reply)) {
        QList<QGeoLocation> locations = parser.results();
        QGeoShape bounds = viewport();
        if (bounds.isValid()) {
            for (int i = locations.size() - 1; i >= 0; --i) {
                if (!bounds.contains(locations[i].coordinate()))
                    locations.removeAt(i);
            }
        }
        setLocations(locations);
        setFinished(true);
    } else {
        setError(QGeoCodeReply::ParseError, parser.errorString());
    }

    m_reply->deleteLater();
    m_reply = 0;
}
/*!
    \internal
*/
QVariant QDeclarativeSearchModelBase::searchArea() const
{
    QGeoShape s = m_request.searchArea();
    if (s.type() == QGeoShape::RectangleType)
        return QVariant::fromValue(QGeoRectangle(s));
    else if (s.type() == QGeoShape::CircleType)
        return QVariant::fromValue(QGeoCircle(s));
    else
        return QVariant::fromValue(s);
}
/*!
    Returns true if the \a other geo shape is equivalent to this geo shape, otherwise returns
    false.
*/
bool QGeoShape::operator==(const QGeoShape &other) const
{
    Q_D(const QGeoShape);

    if (d == other.d_func())
        return true;

    if (!d || !(other.d_func()))
        return false;

    return *d == *other.d_func();
}
示例#5
0
void tst_QGeoCircle::empty()
{
    QFETCH(QGeoCoordinate, center);
    QFETCH(qreal, radius);
    QFETCH(bool, empty);

    QGeoCircle c(center, radius);
    QCOMPARE(c.isEmpty(), empty);

    QGeoShape area = c;
    QCOMPARE(area.isEmpty(), empty);
}
示例#6
0
void tst_QGeoCircle::contains()
{
    QFETCH(QGeoCoordinate, center);
    QFETCH(qreal, radius);
    QFETCH(QGeoCoordinate, probe);
    QFETCH(bool, result);

    QGeoCircle c(center, radius);
    QCOMPARE(c.contains(probe), result);

    QGeoShape area = c;
    QCOMPARE(area.contains(probe), result);
}
static bool addAtForBoundingArea(const QGeoShape &area,
                                 QUrlQuery *queryItems)
{
    QGeoCoordinate center;
    switch (area.type()) {
    case QGeoShape::RectangleType:
        center = QGeoRectangle(area).center();
        break;
    case QGeoShape::CircleType:
        center = QGeoCircle(area).center();
        break;
    case QGeoShape::UnknownType:
        break;
    }

    if (!center.isValid()) {
        return false;
    } else {
        queryItems->addQueryItem(QLatin1String("at"),
                                 QString::number(center.latitude()) +
                                 QLatin1Char(',') +
                                 QString::number(center.longitude()));
        return true;
    }
}
/*!
    \qmlproperty geoshape QtLocation::Map::visibleRegion

    This property holds the region which occupies the viewport of
    the map. The camera is positioned in the center of the shape, and
    at the largest integral zoom level possible which allows the
    whole shape to be visible on the screen. This implies that
    reading this property back shortly after having been set the
    returned area is equal or larger than the set area.

    Setting this property implicitly changes the \l center and
    \l zoomLevel of the map. Any previously set value to those
    properties will be overridden.

    This property does not provide any change notifications.

    \since 5.6
*/
void QDeclarativeGeoMap::setVisibleRegion(const QGeoShape &shape)
{
    if (shape == m_region && m_validRegion)
        return;

    m_region = shape;
    if (!shape.isValid()) {
        // shape invalidated -> nothing to fit anymore
        m_pendingFitViewport = false;
        return;
    }

    if (!width() || !height()) {
        m_pendingFitViewport = true;
        return;
    }

    fitViewportToGeoShape();
}
QDebug operator<<(QDebug dbg, const QGeoShape &shape)
{
    //dbg << *shape.d_func();
    dbg.nospace() << "QGeoShape(";
    switch (shape.type()) {
    case QGeoShape::UnknownType:
        dbg.nospace() << "Unknown";
        break;
    case QGeoShape::RectangleType:
        dbg.nospace() << "Rectangle";
        break;
    case QGeoShape::CircleType:
        dbg.nospace() << "Circle";
    }

    dbg.nospace() << ')';

    return dbg;
}
示例#10
0
/*!
    \qmlmethod QtLocation::Map::fitViewportToGeoShape(QGeoShape shape)

    Fits the current viewport to the boundary of the shape. The camera is positioned
    in the center of the shape, and at the largest integral zoom level possible which
    allows the whole shape to be visible on screen

*/
void QDeclarativeGeoMap::fitViewportToGeoShape(const QVariant &variantShape)
{
    if (!map_ || !mappingManagerInitialized_)
        return;

    QGeoShape shape;

    if (variantShape.userType() == qMetaTypeId<QGeoRectangle>())
        shape = variantShape.value<QGeoRectangle>();
    else if (variantShape.userType() == qMetaTypeId<QGeoCircle>())
        shape = variantShape.value<QGeoCircle>();
    else if (variantShape.userType() == qMetaTypeId<QGeoShape>())
        shape = variantShape.value<QGeoShape>();

    if (!shape.isValid())
        return;

    double bboxWidth;
    double bboxHeight;
    QGeoCoordinate centerCoordinate;

    switch (shape.type()) {
    case QGeoShape::RectangleType:
    {
        QGeoRectangle rect = shape;
        QDoubleVector2D topLeftPoint = map_->coordinateToScreenPosition(rect.topLeft(), false);
        QDoubleVector2D botRightPoint = map_->coordinateToScreenPosition(rect.bottomRight(), false);
        bboxWidth = qAbs(topLeftPoint.x() - botRightPoint.x());
        bboxHeight = qAbs(topLeftPoint.y() - botRightPoint.y());
        centerCoordinate = rect.center();
        break;
    }
    case QGeoShape::CircleType:
    {
        QGeoCircle circle = shape;
        centerCoordinate = circle.center();
        QGeoCoordinate edge = centerCoordinate.atDistanceAndAzimuth(circle.radius(), 90);
        QDoubleVector2D centerPoint = map_->coordinateToScreenPosition(centerCoordinate, false);
        QDoubleVector2D edgePoint = map_->coordinateToScreenPosition(edge, false);
        bboxWidth = qAbs(centerPoint.x() - edgePoint.x()) * 2;
        bboxHeight = bboxWidth;
        break;
    }
    case QGeoShape::UnknownType:
        //Fallthrough to default
    default:
        return;
    }

    // position camera to the center of bounding box
    setProperty("center", QVariant::fromValue(centerCoordinate));

    //If the shape is empty we just change centerposition, not zoom
    if (bboxHeight == 0 && bboxWidth == 0)
        return;

    // adjust zoom
    double bboxWidthRatio = bboxWidth / (bboxWidth + bboxHeight);
    double mapWidthRatio = width() / (width() + height());
    double zoomRatio;

    if (bboxWidthRatio > mapWidthRatio)
        zoomRatio = bboxWidth / width();
    else
        zoomRatio = bboxHeight / height();

    qreal newZoom = log10(zoomRatio) / log10(0.5);
    newZoom = floor(qMax(minimumZoomLevel(), (map_->mapController()->zoom() + newZoom)));
    setProperty("zoomLevel", QVariant::fromValue(newZoom));
}
QPlaceSearchReply *QPlaceManagerEngineOsm::search(const QPlaceSearchRequest &request)
{
    bool unsupported = false;

    // Only public visibility supported
    unsupported |= request.visibilityScope() != QLocation::UnspecifiedVisibility &&
                   request.visibilityScope() != QLocation::PublicVisibility;
    unsupported |= request.searchTerm().isEmpty() && request.categories().isEmpty();

    if (unsupported)
        return QPlaceManagerEngine::search(request);

    QUrlQuery queryItems;

    queryItems.addQueryItem(QStringLiteral("format"), QStringLiteral("jsonv2"));

    //queryItems.addQueryItem(QStringLiteral("accept-language"), QStringLiteral("en"));

    QGeoRectangle boundingBox;
    QGeoShape searchArea = request.searchArea();
    switch (searchArea.type()) {
    case QGeoShape::CircleType: {
        QGeoCircle c(searchArea);
        qreal radius = c.radius();
        if (radius < 0)
            radius = 50000;

        boundingBox = QGeoRectangle(c.center().atDistanceAndAzimuth(radius, -45),
                                    c.center().atDistanceAndAzimuth(radius, 135));
        break;
    }
    case QGeoShape::RectangleType:
        boundingBox = searchArea;
        break;
    default:
        ;
    }

    if (!boundingBox.isEmpty()) {
        queryItems.addQueryItem(QStringLiteral("bounded"), QStringLiteral("1"));
        QString coordinates;
        coordinates = QString::number(boundingBox.topLeft().longitude()) + QLatin1Char(',') +
                      QString::number(boundingBox.topLeft().latitude()) + QLatin1Char(',') +
                      QString::number(boundingBox.bottomRight().longitude()) + QLatin1Char(',') +
                      QString::number(boundingBox.bottomRight().latitude());
        queryItems.addQueryItem(QStringLiteral("viewbox"), coordinates);
    }

    QStringList queryParts;
    if (!request.searchTerm().isEmpty())
        queryParts.append(request.searchTerm());

    foreach (const QPlaceCategory &category, request.categories()) {
        QString id = category.categoryId();
        int index = id.indexOf(QLatin1Char('='));
        if (index != -1)
            id = id.mid(index+1);
        queryParts.append(QLatin1Char('[') + id + QLatin1Char(']'));
    }

    queryItems.addQueryItem(QStringLiteral("q"), queryParts.join(QLatin1Char('+')));

    QVariantMap parameters = request.searchContext().toMap();

    QStringList placeIds = parameters.value(QStringLiteral("ExcludePlaceIds")).toStringList();
    if (!placeIds.isEmpty())
        queryItems.addQueryItem(QStringLiteral("exclude_place_ids"), placeIds.join(QLatin1Char(',')));

    queryItems.addQueryItem(QStringLiteral("addressdetails"), QStringLiteral("1"));

    QUrl requestUrl(m_urlPrefix);
    requestUrl.setQuery(queryItems);

    QNetworkReply *networkReply = m_networkManager->get(QNetworkRequest(requestUrl));

    QPlaceSearchReplyOsm *reply = new QPlaceSearchReplyOsm(request, networkReply, this);
    connect(reply, SIGNAL(finished()), this, SLOT(replyFinished()));
    connect(reply, SIGNAL(error(QPlaceReply::Error,QString)),
            this, SLOT(replyError(QPlaceReply::Error,QString)));

    return reply;
}