File indexing completed on 2024-04-14 14:16:32

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2011 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
0004 //
0005 
0006 #include "MercatorProjection.h"
0007 #include "ViewportParams.h"
0008 #include "TestUtils.h"
0009 
0010 namespace Marble
0011 {
0012 
0013 class MercatorProjectionTest : public QObject
0014 {
0015     Q_OBJECT
0016 
0017 private Q_SLOTS:
0018     void screenCoordinatesValidLat_data();
0019     void screenCoordinatesValidLat();
0020 
0021     void screenCoordinatesOfCenter_data();
0022     void screenCoordinatesOfCenter();
0023 
0024     void setInvalidRadius();
0025 };
0026 
0027 void MercatorProjectionTest::screenCoordinatesValidLat_data()
0028 {
0029     ViewportParams mercator;
0030     mercator.setProjection( Mercator );
0031 
0032     QTest::addColumn<qreal>( "lon" );
0033     QTest::addColumn<qreal>( "lat" );
0034     QTest::addColumn<bool>( "validLat" );
0035 
0036     addRow() << qreal(0.0) << qreal(0.0) << true;
0037 
0038     addRow() << qreal(-180.0) << qreal(0.0) << true;
0039     addRow() <<  qreal(180.0) << qreal(0.0) << true;
0040 
0041     addRow() << qreal(0.0) << mercator.currentProjection()->minValidLat() * RAD2DEG << true;
0042     addRow() << qreal(0.0) << mercator.currentProjection()->maxValidLat() * RAD2DEG << true;
0043 
0044     addRow() << qreal(0.0) << mercator.currentProjection()->minValidLat() * RAD2DEG - qreal(0.0001) << false;
0045     addRow() << qreal(0.0) << mercator.currentProjection()->maxValidLat() * RAD2DEG + qreal(0.0001) << false;
0046 
0047     addRow() << qreal(-180.0) << mercator.currentProjection()->minValidLat() * RAD2DEG << true;
0048     addRow() <<  qreal(180.0) << mercator.currentProjection()->minValidLat() * RAD2DEG << true;
0049 
0050     addRow() << qreal(-180.0) << mercator.currentProjection()->maxValidLat() * RAD2DEG << true;
0051     addRow() <<  qreal(180.0) << mercator.currentProjection()->maxValidLat() * RAD2DEG << true;
0052 
0053     addRow() << qreal(-180.0) << mercator.currentProjection()->minValidLat() * RAD2DEG - qreal(0.0001) << false;
0054     addRow() <<  qreal(180.0) << mercator.currentProjection()->minValidLat() * RAD2DEG - qreal(0.0001) << false;
0055 
0056     addRow() << qreal(-180.0) << mercator.currentProjection()->maxValidLat() * RAD2DEG + qreal(0.0001) << false;
0057     addRow() <<  qreal(180.0) << mercator.currentProjection()->maxValidLat() * RAD2DEG + qreal(0.0001) << false;
0058 }
0059 
0060 void MercatorProjectionTest::screenCoordinatesValidLat()
0061 {
0062     QFETCH( qreal, lon );
0063     QFETCH( qreal, lat );
0064     QFETCH( bool, validLat );
0065 
0066     const GeoDataCoordinates coordinates( lon, lat, 0, GeoDataCoordinates::Degree );
0067 
0068     ViewportParams viewport;
0069     viewport.setProjection( Mercator );
0070     viewport.setRadius( 360 / 4 ); // for easy mapping of lon <-> x
0071     viewport.centerOn( 0.0, 0.0 );
0072     viewport.setSize( QSize( 360, 361 ) ); // TODO: check why height == 360 doesn't hold
0073 
0074     {
0075         qreal x;
0076         qreal y;
0077 
0078         const bool retval = viewport.screenCoordinates( lon * DEG2RAD, lat * DEG2RAD, x, y );
0079 
0080         QVERIFY( retval == validLat );
0081     }
0082 
0083     {
0084         qreal x;
0085         qreal y;
0086         bool globeHidesPoint = true;
0087 
0088         const bool retval = viewport.screenCoordinates( coordinates, x, y, globeHidesPoint );
0089 
0090         QVERIFY( retval == validLat );
0091         QVERIFY( !globeHidesPoint );
0092     }
0093 
0094     QVERIFY( viewport.currentProjection()->repeatableX() );
0095 
0096     {
0097         qreal x[2];
0098         qreal y;
0099         int pointRepeatNum = 1000;
0100         bool globeHidesPoint = true;
0101 
0102         const bool retval = viewport.screenCoordinates( coordinates, x, y, pointRepeatNum, QSizeF( 0, 0 ), globeHidesPoint );
0103 
0104         QVERIFY( retval == validLat );
0105         QCOMPARE( pointRepeatNum, 1 );
0106         QVERIFY( !globeHidesPoint );
0107     }
0108 }
0109 
0110 void MercatorProjectionTest::screenCoordinatesOfCenter_data()
0111 {
0112     ViewportParams mercator;
0113     mercator.setProjection( Mercator );
0114 
0115     QTest::addColumn<qreal>( "lon" );
0116     QTest::addColumn<qreal>( "lat" );
0117 
0118     addRow() << qreal(0.0) << qreal(0.0);
0119 
0120     addRow() << qreal(-180.0) << qreal(0.0);
0121     addRow() <<  qreal(180.0) << qreal(0.0);
0122 
0123     addRow() << qreal(-360.0) << qreal(0.0);
0124     addRow() <<  qreal(360.0) << qreal(0.0);
0125 
0126     addRow() << qreal(-540.0) << qreal(0.0);
0127     addRow() <<  qreal(540.0) << qreal(0.0);
0128 
0129     addRow() << qreal(0.0) << mercator.currentProjection()->minValidLat() * RAD2DEG;
0130     addRow() << qreal(0.0) << mercator.currentProjection()->maxValidLat() * RAD2DEG;
0131 
0132     addRow() << qreal(-180.0) << mercator.currentProjection()->minValidLat() * RAD2DEG;
0133     addRow() << qreal(-180.0) << mercator.currentProjection()->maxValidLat() * RAD2DEG;
0134 
0135     addRow() <<  qreal(180.0) << mercator.currentProjection()->minValidLat() * RAD2DEG;
0136     addRow() <<  qreal(180.0) << mercator.currentProjection()->maxValidLat() * RAD2DEG;
0137 
0138     // FIXME: the following tests should succeed
0139 #if 0
0140     addRow() << qreal(-541.0) << qreal(0.0);
0141     addRow() <<  qreal(541.0) << qreal(0.0);
0142 
0143     addRow() << qreal(-1000000.0) << qreal(0.0);
0144     addRow() <<  qreal(1000000.0) << qreal(0.0);
0145 #endif
0146 }
0147 
0148 void MercatorProjectionTest::screenCoordinatesOfCenter()
0149 {
0150     QFETCH( qreal, lon );
0151     QFETCH( qreal, lat );
0152 
0153     const GeoDataCoordinates coordinates( lon, lat, 0, GeoDataCoordinates::Degree );
0154 
0155     ViewportParams viewport;
0156     viewport.setProjection( Mercator );
0157     viewport.setRadius( 360 / 4 ); // for easy mapping of lon <-> x
0158     viewport.setSize( QSize( 2, 2 ) );
0159     viewport.centerOn( lon * DEG2RAD, lat * DEG2RAD );
0160 
0161     {
0162         qreal x;
0163         qreal y;
0164 
0165         const bool retval = viewport.screenCoordinates( lon * DEG2RAD, lat * DEG2RAD, x, y );
0166 
0167         QVERIFY( retval ); // FIXME: this should fail for lon < -180 || 180 < lon
0168         QCOMPARE( x, lon - viewport.centerLongitude() * RAD2DEG + 1.0 );
0169         QCOMPARE( y, 1.0 );
0170     }
0171 
0172     {
0173         qreal x;
0174         qreal y;
0175         bool globeHidesPoint = true;
0176 
0177         const bool retval = viewport.screenCoordinates( coordinates, x, y, globeHidesPoint );
0178 
0179         QVERIFY( retval ); // FIXME: this should fail for lon < -180 || 180 < lon
0180         QVERIFY( !globeHidesPoint );
0181         QCOMPARE( x, lon - viewport.centerLongitude() * RAD2DEG + 1.0 );
0182         QCOMPARE( y, 1.0 );
0183     }
0184 
0185     QVERIFY( viewport.currentProjection()->repeatableX() );
0186 
0187     {
0188         qreal x[2];
0189         qreal y;
0190         int pointRepeatNum = 1000;
0191         bool globeHidesPoint = true;
0192 
0193         const bool retval = viewport.screenCoordinates( coordinates, x, y, pointRepeatNum, QSizeF( 0, 0 ), globeHidesPoint );
0194 
0195         QVERIFY( retval );
0196         QCOMPARE( pointRepeatNum, 1 );
0197         QVERIFY( !globeHidesPoint );
0198         QCOMPARE( x[0], 1.0 );
0199         QCOMPARE( y, 1.0 );
0200     }
0201 }
0202 
0203 void MercatorProjectionTest::setInvalidRadius()
0204 {
0205     ViewportParams viewport;
0206     viewport.setProjection( Mercator );
0207     viewport.setRadius( 0 );
0208     qreal lon, lat;
0209     viewport.geoCoordinates( 23, 42, lon, lat );
0210 }
0211 
0212 }
0213 
0214 QTEST_MAIN( Marble::MercatorProjectionTest )
0215 
0216 #include "MercatorProjectionTest.moc"