void GeoDataLatLonAltBoxTest::fromLineStringTest() { qreal west = randomLon(); qreal east = randomLon(); qreal lat1 = randomLat(); qreal lat2 = randomLat(); GeoDataLatLonAltBox sourceBox; if ( lat1 >= lat2 ) { sourceBox = GeoDataLatLonBox( lat1, lat2, east, west, GeoDataCoordinates::Degree ); } else { sourceBox = GeoDataLatLonBox( lat2, lat1, east, west, GeoDataCoordinates::Degree ); } GeoDataLinearRing ring; // SouthWest ring << GeoDataCoordinates( sourceBox.west(), sourceBox.south() ); // SouthEast ring << GeoDataCoordinates( sourceBox.east(), sourceBox.south() ); // NorthEast ring << GeoDataCoordinates( sourceBox.east(), sourceBox.north() ); // NorthWest ring << GeoDataCoordinates( sourceBox.west(), sourceBox.north() ); QCOMPARE( GeoDataLatLonAltBox::fromLineString( ring ).toString(), sourceBox.toString() ); }
void OpenCachingComModel::getAdditionalItems( const GeoDataLatLonAltBox& box, qint32 number ) { if( marbleModel()->planetId() != "earth" ) { return; } if ( m_previousbox.contains( box ) ) { return; } QString url("http://www.opencaching.com/api/geocache/?Authorization="); url += AUTHKEY + QString("&bbox=%1,%2,%3,%4") .arg( box.south( GeoDataCoordinates::Degree ) ) .arg( box.west(GeoDataCoordinates::Degree ) ) .arg( box.north(GeoDataCoordinates::Degree ) ) .arg( box.east(GeoDataCoordinates::Degree ) ); if(!m_previousbox.isNull()) { url += QString("&exclude_bbox=%1,%2,%3,%4") .arg( m_previousbox.south( GeoDataCoordinates::Degree ) ) .arg( m_previousbox.west(GeoDataCoordinates::Degree ) ) .arg( m_previousbox.north(GeoDataCoordinates::Degree ) ) .arg( m_previousbox.east(GeoDataCoordinates::Degree ) ); } url += "&limit=" + QString::number( number ); // TODO Limit to user set tags/types/difficulty - when there is a config dialog... m_previousbox = box; // qDebug()<<"Fetching more caches: "<<url; downloadDescriptionFile( QUrl( url ) ); }
void OsmNominatimRunner::search( const QString &searchTerm, const GeoDataLatLonAltBox &preferred ) { QString base = "http://nominatim.openstreetmap.org/search?"; QString query = "q=%1&format=xml&addressdetails=1&accept-language=%2"; QString url = QString(base + query).arg(searchTerm).arg(MarbleLocale::languageCode()); if( !preferred.isEmpty() ) { GeoDataCoordinates::Unit deg = GeoDataCoordinates::Degree; QString viewbox( "&viewbox=%1,%2,%3,%4&bounded=1" ); // left, top, right, bottom url += viewbox.arg(preferred.west(deg)) .arg(preferred.north(deg)) .arg(preferred.east(deg)) .arg(preferred.south(deg)); } m_request.setUrl(QUrl(url)); m_request.setRawHeader("User-Agent", TinyWebBrowser::userAgent("Browser", "OsmNominatimRunner") ); QEventLoop eventLoop; QTimer timer; timer.setSingleShot( true ); timer.setInterval( 15000 ); connect( &timer, SIGNAL(timeout()), &eventLoop, SLOT(quit())); connect( this, SIGNAL(searchFinished(QVector<GeoDataPlacemark*>)), &eventLoop, SLOT(quit()) ); // @todo FIXME Must currently be done in the main thread, see bug 257376 QTimer::singleShot( 0, this, SLOT(startSearch()) ); timer.start(); eventLoop.exec(); }
void BBCItemGetter::work() { if ( m_items.isEmpty() ) { sleep( 1 ); return; } m_scheduleMutex.lock(); GeoDataLatLonAltBox box = m_scheduledBox; qint32 number = m_scheduledNumber; m_scheduledBox = GeoDataLatLonAltBox(); m_scheduledNumber = 0; m_scheduleMutex.unlock(); qint32 fetched = 0; QList<BBCStation>::ConstIterator it = m_items.constBegin(); QList<BBCStation>::ConstIterator end = m_items.constEnd(); while ( fetched < number && it != end ) { if ( box.contains( it->coordinate() ) ) { emit foundStation( (*it) ); fetched++; } ++it; } }
void LocalDatabaseRunner::search( const QString &searchTerm, const GeoDataLatLonAltBox &preferred ) { QVector<GeoDataPlacemark*> vector; if (model()) { const QAbstractItemModel * placemarkModel = model()->placemarkModel(); if (placemarkModel) { QModelIndexList resultList; QModelIndex firstIndex = placemarkModel->index( 0, 0 ); resultList = placemarkModel->match( firstIndex, Qt::DisplayRole, searchTerm, -1, Qt::MatchStartsWith ); foreach ( const QModelIndex& index, resultList ) { if( !index.isValid() ) { mDebug() << "invalid index!!!"; continue; } GeoDataPlacemark *placemark = dynamic_cast<GeoDataPlacemark*>(qvariant_cast<GeoDataObject*>( index.data( MarblePlacemarkModel::ObjectPointerRole ))); if ( placemark && ( preferred.isEmpty() || preferred.contains( placemark->coordinate() ) ) ) { vector.append( new GeoDataPlacemark( *placemark )); } } } } emit searchFinished( vector ); }
void TestGeoDataLatLonAltBox::testFromLineString() { QFETCH(GeoDataLineString, string); QFETCH(GeoDataLatLonBox, expected); GeoDataLatLonAltBox const result = GeoDataLatLonAltBox::fromLineString(string); QCOMPARE(result.north(), expected.north()); QCOMPARE(result.south(), expected.south()); QCOMPARE(result.east(), expected.east()); QCOMPARE(result.west(), expected.west()); }
void TestGeoDataLatLonAltBox::testAltitude() { QFETCH(qreal, alt); GeoDataLatLonAltBox box; box.setMinAltitude(alt); QCOMPARE(box.minAltitude(), alt); box.setMaxAltitude(alt); QCOMPARE(box.maxAltitude(), alt); }
bool GeoDataLatLonAltBox::contains( const GeoDataLatLonAltBox &other ) const { // check the contain criterion for the altitude first as this is trivial: // mDebug() << "this " << this->toString(GeoDataCoordinates::Degree); // mDebug() << "other" << other.toString(GeoDataCoordinates::Degree); if ( d->m_maxAltitude >= other.maxAltitude() && d->m_minAltitude <= other.minAltitude() ) { return GeoDataLatLonBox::contains( other ); } return false; }
void GeoNamesWeatherService::getAdditionalItems( const GeoDataLatLonAltBox& box, qint32 number ) { if( marbleModel()->planetId() != "earth" ) { return; } QUrl geonamesUrl( "http://ws.geonames.org/weatherJSON" ); #if QT_VERSION < 0x050000 geonamesUrl.addQueryItem( "north", QString::number( box.north( GeoDataCoordinates::Degree ) ) ); geonamesUrl.addQueryItem( "south", QString::number( box.south( GeoDataCoordinates::Degree ) ) ); geonamesUrl.addQueryItem( "east", QString::number( box.east( GeoDataCoordinates::Degree ) ) ); geonamesUrl.addQueryItem( "west", QString::number( box.west( GeoDataCoordinates::Degree ) ) ); geonamesUrl.addQueryItem( "maxRows", QString::number( number ) ); geonamesUrl.addQueryItem( "username", "marble" ); #else QUrlQuery urlQuery; urlQuery.addQueryItem( "north", QString::number( box.north( GeoDataCoordinates::Degree ) ) ); urlQuery.addQueryItem( "south", QString::number( box.south( GeoDataCoordinates::Degree ) ) ); urlQuery.addQueryItem( "east", QString::number( box.east( GeoDataCoordinates::Degree ) ) ); urlQuery.addQueryItem( "west", QString::number( box.west( GeoDataCoordinates::Degree ) ) ); urlQuery.addQueryItem( "maxRows", QString::number( number ) ); urlQuery.addQueryItem( "username", "marble" ); geonamesUrl.setQuery( urlQuery ); #endif emit downloadDescriptionFileRequested( geonamesUrl ); }
void EarthquakeModel::getAdditionalItems( const GeoDataLatLonAltBox& box, qint32 number ) { if (marbleModel()->planetId() != QLatin1String("earth")) { return; } const QString geonamesUrl( QLatin1String("http://ws.geonames.org/earthquakesJSON") + QLatin1String("?north=") + QString::number(box.north() * RAD2DEG) + QLatin1String("&south=") + QString::number(box.south() * RAD2DEG) + QLatin1String("&east=") + QString::number(box.east() * RAD2DEG) + QLatin1String("&west=") + QString::number(box.west() * RAD2DEG) + QLatin1String("&date=") + m_endDate.toString("yyyy-MM-dd") + QLatin1String("&maxRows=") + QString::number(number) + QLatin1String("&username=marble") + QLatin1String("&formatted=true")); downloadDescriptionFile( QUrl( geonamesUrl ) ); }
void GeoNamesWeatherService::getAdditionalItems( const GeoDataLatLonAltBox& box, const MarbleModel *model, qint32 number ) { if( model->planetId() != "earth" ) { return; } QUrl geonamesUrl( "http://ws.geonames.org/weatherJSON" ); geonamesUrl.addQueryItem( "north", QString::number( box.north( GeoDataCoordinates::Degree ) ) ); geonamesUrl.addQueryItem( "south", QString::number( box.south( GeoDataCoordinates::Degree ) ) ); geonamesUrl.addQueryItem( "east", QString::number( box.east( GeoDataCoordinates::Degree ) ) ); geonamesUrl.addQueryItem( "west", QString::number( box.west( GeoDataCoordinates::Degree ) ) ); geonamesUrl.addQueryItem( "maxRows", QString::number( number ) ); emit downloadDescriptionFileRequested( geonamesUrl ); }
void FoursquareModel::getAdditionalItems( const GeoDataLatLonAltBox& box, qint32 number ) { if( marbleModel()->planetId() != "earth" ) { return; } QString clientId = "YPRWSYFW1RVL4PJQ2XS5G14RTOGTHOKZVHC1EP5KCCCYQPZF"; QString clientSecret = "5L2JDCAYQCEJWY5FNDU4A1RWATE4E5FIIXXRM41YBTFSERUH"; QString apiUrl( "https://api.foursquare.com/v2/venues/search" ); qreal const distanceLon = marbleModel()->planetRadius() * distanceSphere( box.west(), box.north(), box.east(), box.north() ); qreal const distanceLat = marbleModel()->planetRadius() * distanceSphere( box.west(), box.north(), box.west(), box.south() ); qreal const area = distanceLon * distanceLat; if ( area > 10 * 1000 * KM2METER * KM2METER ) { // Large area (> 10.000 km^2) => too large for bbox queries apiUrl += "?ll=" + QString::number( box.center().latitude(Marble::GeoDataCoordinates::Degree) ); apiUrl += ',' + QString::number( box.center().longitude(Marble::GeoDataCoordinates::Degree) ); apiUrl += "&intent=checkin"; } else { apiUrl += "?ne=" + QString::number( box.north(Marble::GeoDataCoordinates::Degree) ); apiUrl += ',' + QString::number( box.east(Marble::GeoDataCoordinates::Degree) ); apiUrl += "&sw=" + QString::number( box.south(Marble::GeoDataCoordinates::Degree) ); apiUrl += ',' + QString::number( box.west(Marble::GeoDataCoordinates::Degree) ); apiUrl += "&intent=browse"; } apiUrl += "&limit=" + QString::number( number ); apiUrl += "&client_id=" + clientId; apiUrl += "&client_secret=" + clientSecret; apiUrl += "&v=20120601"; downloadDescriptionFile( QUrl( apiUrl ) ); }
void OpenCachingModel::getAdditionalItems( const GeoDataLatLonAltBox& box, const MarbleModel *model, qint32 number ) { Q_UNUSED( number ); if( model->planetId() != "earth" ) { return; } // http://www.opencaching.de/doc/xml/xml11.htm QString openCachingUrl( "http://www.opencaching.de/xml/ocxml11.php" ); openCachingUrl += "?modifiedsince=" + m_startDate.toString( "yyyyMMddhhmmss" ); openCachingUrl += "&cache=1&cachedesc=1&picture=0&cachelog=1&removedobject=0"; openCachingUrl += "&lat=" + QString::number( box.center().latitude() * RAD2DEG ); openCachingUrl += "&lon=" + QString::number( box.center().longitude() * RAD2DEG ); openCachingUrl += "&distance=" + QString::number( m_maxDistance ); openCachingUrl += "&charset=utf-8&cdata=0&session=0&zip=0"; downloadDescriptionFile( QUrl( openCachingUrl ) ); }
GeoDataLatLonAltBox GeoDataMultiGeometry::latLonAltBox() const { QVector<GeoDataGeometry*>::const_iterator it = p()->m_vector.constBegin(); QVector<GeoDataGeometry*>::const_iterator end = p()->m_vector.constEnd(); GeoDataLatLonAltBox box; for (; it != end; ++it) { if ( !(*it)->latLonAltBox().isEmpty() ) { if ( box.isEmpty() ) { box = (*it)->latLonAltBox(); } else { box |= (*it)->latLonAltBox(); } } } return box; }
void WikipediaModel::getAdditionalItems( const GeoDataLatLonAltBox& box, qint32 number ) { // Geonames only supports wikipedia articles for earth if (marbleModel()->planetId() != QLatin1String("earth")) { return; } QUrl geonamesUrl( "http://ws.geonames.org/wikipediaBoundingBox" ); QUrlQuery urlQuery; urlQuery.addQueryItem( "north", QString::number( box.north( GeoDataCoordinates::Degree ) ) ); urlQuery.addQueryItem( "south", QString::number( box.south( GeoDataCoordinates::Degree ) ) ); urlQuery.addQueryItem( "east", QString::number( box.east( GeoDataCoordinates::Degree ) ) ); urlQuery.addQueryItem( "west", QString::number( box.west( GeoDataCoordinates::Degree ) ) ); urlQuery.addQueryItem( "maxRows", QString::number( number ) ); urlQuery.addQueryItem( "lang", m_languageCode ); urlQuery.addQueryItem( "username", "marble" ); geonamesUrl.setQuery( urlQuery ); downloadDescriptionFile( geonamesUrl ); }
void PostalCodeModel::getAdditionalItems( const GeoDataLatLonAltBox& box, const MarbleModel *model, qint32 number ) { Q_UNUSED( number ); if( model->planetId() != "earth" ) { return; } double const lat = box.center().latitude( GeoDataCoordinates::Degree ); double const lon = box.center().longitude( GeoDataCoordinates::Degree ); double const radius = qMin<double>( 30.0, box.height() * model->planet()->radius() * METER2KM ); QUrl geonamesUrl( "http://ws.geonames.org/findNearbyPostalCodesJSON" ); geonamesUrl.addQueryItem( "lat", QString::number( lat ) ); geonamesUrl.addQueryItem( "lng", QString::number( lon ) ); geonamesUrl.addQueryItem( "radius", QString::number( radius ) ); geonamesUrl.addQueryItem( "maxRows", QString::number( numberOfItemsOnScreen ) ); downloadDescriptionFile( QUrl( geonamesUrl ) ); }
void PanoramioModel::getAdditionalItems( const GeoDataLatLonAltBox &box, qint32 number ) { if ( marbleModel()->planetId() != "earth" ) { return; } // FIXME: Download a list of constant number, because the parser doesn't support // loading a file of an unknown length. QUrl jsonUrl( "http://www.panoramio.com/map/get_panoramas.php?from=" + QString::number( 0 ) + "&order=upload_date" + "&set=public" + "&to=" + QString::number( number ) // + "&to=" + QString::number( number ) + "&minx=" + QString::number( box.west() * RAD2DEG ) + "&miny=" + QString::number( box.south() * RAD2DEG ) + "&maxx=" + QString::number( box.east() * RAD2DEG ) + "&maxy=" + QString::number( box.north() * RAD2DEG ) + "&size=small"); downloadDescriptionFile( jsonUrl ); }
GeoDataLatLonAltBox GeoDataLatLonAltBox::fromLineString( const GeoDataLineString& lineString ) { // If the line string is empty return a boundingbox that contains everything if ( lineString.size() == 0 ) { return GeoDataLatLonAltBox(); } const qreal altitude = lineString.first().altitude(); GeoDataLatLonAltBox temp ( GeoDataLatLonBox::fromLineString( lineString ), altitude, altitude ); qreal maxAltitude = altitude; qreal minAltitude = altitude; // If there's only a single node stored then the boundingbox only contains that point if ( lineString.size() == 1 ) { temp.setMinAltitude( minAltitude ); temp.setMaxAltitude( maxAltitude ); return temp; } QVector<GeoDataCoordinates>::ConstIterator it( lineString.constBegin() ); QVector<GeoDataCoordinates>::ConstIterator itEnd( lineString.constEnd() ); for ( ; it != itEnd; ++it ) { // Get coordinates and normalize them to the desired range. const qreal altitude = (it)->altitude(); // Determining the maximum and minimum latitude if ( altitude > maxAltitude ) maxAltitude = altitude; if ( altitude < minAltitude ) minAltitude = altitude; } temp.setMinAltitude( minAltitude ); temp.setMaxAltitude( maxAltitude ); return temp; }
GeoDataLatLonAltBox GeoDataContainer::latLonAltBox() const { Q_D(const GeoDataContainer); GeoDataLatLonAltBox result; QVector<GeoDataFeature*>::const_iterator it = d->m_vector.constBegin(); QVector<GeoDataFeature*>::const_iterator end = d->m_vector.constEnd(); for (; it != end; ++it) { // Get all the placemarks from GeoDataContainer if ( (*it)->nodeType() == GeoDataTypes::GeoDataPlacemarkType ) { GeoDataPlacemark *placemark = static_cast<GeoDataPlacemark*>(*it); // Only use visible placemarks for extracting their latLonAltBox and // making an union with the global latLonAltBox Marble will fit its // zoom to if (placemark->isVisible()) { if (result.isEmpty()) { result = placemark->geometry()->latLonAltBox(); } else { result |= placemark->geometry()->latLonAltBox(); } } } else if ( (*it)->nodeType() == GeoDataTypes::GeoDataFolderType || (*it)->nodeType() == GeoDataTypes::GeoDataDocumentType ) { GeoDataContainer *container = static_cast<GeoDataContainer*>(*it); if (result.isEmpty()) { result = container->latLonAltBox(); } else { result |= container->latLonAltBox(); } } } return result; }
void TestGeoDataLatLonAltBox::testContainerBox() { QFETCH(qreal, lon1); QFETCH(qreal, lat1); QFETCH(qreal, lon2); QFETCH(qreal, lat2); QFETCH(qreal, lon3); QFETCH(qreal, lat3); GeoDataPlacemark p1, p2, p3; p1.setCoordinate(lon1, lat1, GeoDataCoordinates::Degree); p2.setCoordinate(lon2, lat2, GeoDataCoordinates::Degree); p3.setCoordinate(lon3, lat3, GeoDataCoordinates::Degree); GeoDataFolder f1, f2; f1.append(new GeoDataPlacemark(p1)); f2.append(new GeoDataPlacemark(p2)); f2.append(new GeoDataPlacemark(p3)); f1.append(new GeoDataFolder(f2)); GeoDataLatLonAltBox box = f1.latLonAltBox(); QCOMPARE(box.north(), qMax(qMax(lat1, lat2), lat3)); QCOMPARE(box.east(), qMax(qMax(lon1, lon2), lon3)); QCOMPARE(box.south(), qMin(qMin(lat1, lat2), lat3)); QCOMPARE(box.west(), qMin(qMin(lon1, lon2), lon3)); }
void TestGeoDataLatLonAltBox::testContains() { GeoDataLatLonAltBox const largeBox = GeoDataLatLonAltBox::fromLineString( GeoDataLineString() << GeoDataCoordinates( -20.0, +10.0, 15.0, GeoDataCoordinates::Degree ) << GeoDataCoordinates( +20.0, -10.0, 25.0, GeoDataCoordinates::Degree ) ); GeoDataLatLonAltBox const smallBox = GeoDataLatLonAltBox::fromLineString( GeoDataLineString() << GeoDataCoordinates( -2.0, +1.0, 18.0, GeoDataCoordinates::Degree ) << GeoDataCoordinates( +2.0, -1.0, 22.0, GeoDataCoordinates::Degree ) ); QVERIFY( largeBox.contains( GeoDataCoordinates( 5.0, 5.0, 20.0, GeoDataCoordinates::Degree ) ) ); QVERIFY( largeBox.contains( smallBox ) ); QVERIFY( largeBox.contains( largeBox ) ); QVERIFY( !smallBox.contains( largeBox ) ); QVERIFY( smallBox.contains( GeoDataCoordinates( 0.0, 0.0, 20.0, GeoDataCoordinates::Degree ) ) ); QVERIFY( !largeBox.contains( GeoDataCoordinates( 5.0, 5.0, 30.0, GeoDataCoordinates::Degree ) ) ); QVERIFY( !largeBox.contains( GeoDataCoordinates( 5.0, 5.0, 10.0, GeoDataCoordinates::Degree ) ) ); QVERIFY( !largeBox.contains( GeoDataCoordinates( 35.0, 5.0, 20.0, GeoDataCoordinates::Degree ) ) ); QVERIFY( !largeBox.contains( GeoDataCoordinates( -35.0, 5.0, 20.0, GeoDataCoordinates::Degree ) ) ); QVERIFY( !largeBox.contains( GeoDataCoordinates( 5.0, 35.0, 20.0, GeoDataCoordinates::Degree ) ) ); QVERIFY( !largeBox.contains( GeoDataCoordinates( 5.0, -35.0, 20.0, GeoDataCoordinates::Degree ) ) ); }
bool GeoDataLatLonAltBox::intersects( const GeoDataLatLonAltBox &other ) const { // Case 1: maximum altitude of other box intersects: if ( ( d->m_maxAltitude >= other.maxAltitude() && d->m_minAltitude <= other.maxAltitude() ) // Case 2: maximum altitude of this box intersects: || ( other.maxAltitude() >= d->m_maxAltitude && other.minAltitude() <= d->m_maxAltitude ) // Case 3: minimum altitude of other box intersects: || ( d->m_maxAltitude >= other.minAltitude() && d->m_minAltitude <= other.minAltitude() ) // Case 4: minimum altitude of this box intersects: || ( other.maxAltitude() >= d->m_minAltitude && other.minAltitude() <= d->m_minAltitude ) ) { if ( GeoDataLatLonBox::intersects( other ) ) return true; } return false; }
QVector<TileCoordsPyramid> DownloadRegion::region( const TextureLayer *textureLayer, const GeoDataLatLonAltBox &downloadRegion ) const { Q_ASSERT( textureLayer ); int const westX = d->rad2PixelX( downloadRegion.west(), textureLayer ); int const northY = d->rad2PixelY( downloadRegion.north(), textureLayer ); int const eastX = d->rad2PixelX( downloadRegion.east(), textureLayer ); int const southY = d->rad2PixelY( downloadRegion.south(), textureLayer ); // FIXME: remove this stuff mDebug() << "DownloadRegionDialog downloadRegion:" << "north:" << downloadRegion.north() << "south:" << downloadRegion.south() << "east:" << downloadRegion.east() << "west:" << downloadRegion.west(); mDebug() << "north/west (x/y):" << westX << northY; mDebug() << "south/east (x/y):" << eastX << southY; int const tileWidth = textureLayer->tileSize().width(); int const tileHeight = textureLayer->tileSize().height(); mDebug() << "DownloadRegionDialog downloadRegion: tileSize:" << tileWidth << tileHeight; int const visibleLevelX1 = qMin( westX, eastX ); int const visibleLevelY1 = qMin( northY, southY ); int const visibleLevelX2 = qMax( westX, eastX ); int const visibleLevelY2 = qMax( northY, southY ); mDebug() << "visible level pixel coords (level/x1/y1/x2/y2):" << d->m_visibleTileLevel << visibleLevelX1 << visibleLevelY1 << visibleLevelX2 << visibleLevelY2; int bottomLevelX1, bottomLevelY1, bottomLevelX2, bottomLevelY2; // the pixel coords calculated above are referring to the visible tile level, // if the bottom level is a different level, we have to take it into account if ( d->m_visibleTileLevel > d->m_tileLevelRange.second ) { int const deltaLevel = d->m_visibleTileLevel - d->m_tileLevelRange.second; bottomLevelX1 = visibleLevelX1 >> deltaLevel; bottomLevelY1 = visibleLevelY1 >> deltaLevel; bottomLevelX2 = visibleLevelX2 >> deltaLevel; bottomLevelY2 = visibleLevelY2 >> deltaLevel; }
void TestGeoDataLatLonAltBox::testDefaultConstruction() { GeoDataLatLonBox const latLonBox; QCOMPARE( latLonBox.north(), 0.0 ); QCOMPARE( latLonBox.south(), 0.0 ); QCOMPARE( latLonBox.east(), 0.0 ); QCOMPARE( latLonBox.west(), 0.0 ); QCOMPARE( latLonBox.rotation(), 0.0 ); QCOMPARE( latLonBox.width(), 0.0 ); QCOMPARE( latLonBox.height(), 0.0 ); QVERIFY( !latLonBox.crossesDateLine() ); QCOMPARE( latLonBox.center(), GeoDataCoordinates( 0, 0 ) ); QVERIFY( latLonBox.isNull() ); QVERIFY( latLonBox.isEmpty() ); QVERIFY( (latLonBox|latLonBox).isNull() ); QVERIFY( (latLonBox|latLonBox).isEmpty() ); QVERIFY( !latLonBox.intersects( latLonBox ) ); GeoDataLatLonAltBox const latLonAltBox; QCOMPARE( latLonAltBox.north(), 0.0 ); QCOMPARE( latLonAltBox.south(), 0.0 ); QCOMPARE( latLonAltBox.east(), 0.0 ); QCOMPARE( latLonAltBox.west(), 0.0 ); QCOMPARE( latLonAltBox.rotation(), 0.0 ); QCOMPARE( latLonAltBox.width(), 0.0 ); QCOMPARE( latLonAltBox.height(), 0.0 ); QVERIFY( !latLonAltBox.crossesDateLine() ); QCOMPARE( latLonAltBox.center(), GeoDataCoordinates( 0, 0, 0 ) ); QVERIFY( latLonAltBox.isNull() ); QVERIFY( latLonAltBox.isEmpty() ); QCOMPARE( latLonAltBox.minAltitude(), 0.0 ); QCOMPARE( latLonAltBox.maxAltitude(), 0.0 ); QCOMPARE( latLonAltBox.altitudeMode(), ClampToGround ); QVERIFY( (latLonAltBox|latLonAltBox).isNull() ); QVERIFY( (latLonAltBox|latLonAltBox).isEmpty() ); QVERIFY( !latLonAltBox.intersects( latLonAltBox ) ); }
bool ViewportParams::resolves ( const GeoDataLatLonAltBox &latLonAltBox ) const { return latLonAltBox.width() + latLonAltBox.height() > 2.0 * angularResolution() || latLonAltBox.maxAltitude() - latLonAltBox.minAltitude() > 10000; }
GeoDataLatLonAltBox EquirectProjection::latLonAltBox( const QRect& screenRect, const ViewportParams *viewport ) const { qreal west; qreal north = 90*DEG2RAD; geoCoordinates( screenRect.left(), screenRect.top(), viewport, west, north, GeoDataCoordinates::Radian ); qreal east; qreal south = -90*DEG2RAD; geoCoordinates( screenRect.right(), screenRect.bottom(), viewport, east, south, GeoDataCoordinates::Radian ); // For the case where the whole viewport gets covered there is a // pretty dirty and generic detection algorithm: GeoDataLatLonAltBox latLonAltBox; latLonAltBox.setNorth( north, GeoDataCoordinates::Radian ); latLonAltBox.setSouth( south, GeoDataCoordinates::Radian ); latLonAltBox.setWest( west, GeoDataCoordinates::Radian ); latLonAltBox.setEast( east, GeoDataCoordinates::Radian ); latLonAltBox.setMinAltitude( -100000000.0 ); latLonAltBox.setMaxAltitude( 100000000000000.0 ); // Convenience variables int radius = viewport->radius(); int width = viewport->width(); // The remaining algorithm should be pretty generic for all kinds of // flat projections: int xRepeatDistance = 4 * radius; if ( width >= xRepeatDistance ) { latLonAltBox.setWest( -M_PI ); latLonAltBox.setEast( +M_PI ); } // Now we need to check whether maxLat (e.g. the north pole) gets displayed // inside the viewport. // We need a point on the screen at maxLat that definitely gets displayed: qreal averageLongitude = latLonAltBox.east(); GeoDataCoordinates maxLatPoint( averageLongitude, maxLat(), 0.0, GeoDataCoordinates::Radian ); GeoDataCoordinates minLatPoint( averageLongitude, minLat(), 0.0, GeoDataCoordinates::Radian ); qreal dummyX, dummyY; // not needed if ( screenCoordinates( maxLatPoint, viewport, dummyX, dummyY ) ) { latLonAltBox.setEast( +M_PI ); latLonAltBox.setWest( -M_PI ); } if ( screenCoordinates( minLatPoint, viewport, dummyX, dummyY ) ) { latLonAltBox.setEast( +M_PI ); latLonAltBox.setWest( -M_PI ); } return latLonAltBox; }
void PhotoPluginModel::getAdditionalItems( const GeoDataLatLonAltBox& box, qint32 number ) { // Flickr only supports images for earth if (marbleModel()->planetId() != QLatin1String("earth")) { return; } if( box.west() <= box.east() ) { const QString bbox = QString::number(box.west() * RAD2DEG) + QLatin1Char(',') + QString::number(box.south() * RAD2DEG) + QLatin1Char(',') + QString::number(box.east() * RAD2DEG) + QLatin1Char(',') + QString::number(box.north() * RAD2DEG); QHash<QString,QString> options; options.insert( "per_page", QString::number( number ) ); options.insert( "bbox", bbox ); options.insert( "sort", "interestingness-desc" ); options.insert( "license", m_licenses ); downloadDescriptionFile( generateUrl( "flickr", "flickr.photos.search", options ) ); } else { // Flickr api doesn't support bboxes with west > east so we have to split in two boxes const QString bboxWest = QString::number(box.west() * RAD2DEG) + QLatin1Char(',') + QString::number(box.south() * RAD2DEG) + QLatin1Char(',') + QString::number(180 ) + QLatin1Char(',') + QString::number(box.north() * RAD2DEG); QHash<QString,QString> optionsWest; optionsWest.insert( "per_page", QString::number( number/2 ) ); optionsWest.insert( "bbox", bboxWest ); optionsWest.insert( "sort", "interestingness-desc" ); optionsWest.insert( "license", m_licenses ); downloadDescriptionFile( generateUrl( "flickr", "flickr.photos.search", optionsWest ) ); const QString bboxEast = QString::number(-180) +QLatin1Char( ',') + QString::number(box.south() * RAD2DEG) + QLatin1Char(',') + QString::number(box.east() * RAD2DEG) + QLatin1Char(',') + QString::number(box.north() * RAD2DEG); QHash<QString,QString> optionsEast; optionsEast.insert( "per_page", QString::number( number/2 ) ); optionsEast.insert( "bbox", bboxEast ); optionsEast.insert( "sort", "interestingness-desc" ); optionsEast.insert( "license", m_licenses ); downloadDescriptionFile( generateUrl( "flickr", "flickr.photos.search", optionsEast ) ); } }
void TestGeoDataLatLonAltBox::testPack() { QFETCH(GeoDataCoordinates, coordinates); GeoDataLatLonAltBox const original = GeoDataLatLonAltBox(coordinates); QBuffer buffer; bool const isOpenForWriting = buffer.open(QBuffer::WriteOnly); QVERIFY(isOpenForWriting); QDataStream out(&buffer); original.pack(out); buffer.close(); bool const isOpenForReading = buffer.open(QBuffer::ReadOnly); QVERIFY(isOpenForReading); QDataStream in(&buffer); GeoDataLatLonAltBox unpacked; unpacked.unpack(in); buffer.close(); #if 0 QCOMPARE(unpacked.north(), original.north()); QCOMPARE(unpacked.south(), original.south()); QCOMPARE(unpacked.east(), original.east()); QCOMPARE(unpacked.west(), original.west()); #endif QCOMPARE(unpacked.maxAltitude(), original.maxAltitude()); QCOMPARE(unpacked.minAltitude(), original.minAltitude()); QCOMPARE(unpacked.altitudeMode(), original.altitudeMode()); }