Warning, file /education/marble/tests/ViewportParamsTest.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2012 Thibaut Gridel <tgridel@free.fr> 0004 // SPDX-FileCopyrightText: 2012, 2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de> 0005 // 0006 0007 #include "TestUtils.h" 0008 0009 #include "ViewportParams.h" 0010 0011 #include "AbstractProjection.h" 0012 #include "GeoDataCoordinates.h" 0013 #include "GeoDataLineString.h" 0014 #include "GeoDataLinearRing.h" 0015 0016 Q_DECLARE_METATYPE( Marble::GeoDataLinearRing ) 0017 Q_DECLARE_METATYPE( Marble::Projection ) 0018 Q_DECLARE_METATYPE( Marble::TessellationFlag ) 0019 Q_DECLARE_METATYPE( Marble::TessellationFlags ) 0020 0021 namespace Marble 0022 { 0023 0024 class ViewportParamsTest : public QObject 0025 { 0026 Q_OBJECT 0027 0028 private Q_SLOTS: 0029 void constructorDefaultValues(); 0030 0031 void constructorValues_data(); 0032 void constructorValues(); 0033 0034 void screenCoordinates_GeoDataLineString_data(); 0035 void screenCoordinates_GeoDataLineString(); 0036 0037 void screenCoordinates_GeoDataLineString2(); 0038 0039 void screenCoordinates_GeoDataLinearRing(); 0040 0041 void geoDataLinearRing_data(); 0042 void geoDataLinearRing(); 0043 0044 void setInvalidRadius(); 0045 0046 void setFocusPoint(); 0047 }; 0048 0049 void ViewportParamsTest::constructorDefaultValues() 0050 { 0051 const ViewportParams viewport; 0052 0053 QCOMPARE( viewport.projection(), Spherical ); 0054 QCOMPARE( viewport.size(), QSize( 100, 100 ) ); 0055 QCOMPARE( viewport.width(), 100 ); 0056 QCOMPARE( viewport.height(), 100 ); 0057 QCOMPARE( viewport.centerLongitude(), 0. ); 0058 QCOMPARE( viewport.centerLatitude(), 0. ); 0059 QCOMPARE( viewport.polarity(), 1 ); 0060 QCOMPARE( viewport.radius(), 2000 ); 0061 QCOMPARE( viewport.mapCoversViewport(), true ); 0062 QCOMPARE( viewport.focusPoint(), GeoDataCoordinates( 0., 0., 0. ) ); 0063 0064 // invariants: 0065 QVERIFY( viewport.radius() > 0 ); // avoids divisions by zero 0066 QVERIFY( viewport.viewLatLonAltBox() == viewport.latLonAltBox( QRect( 0, 0, 100, 100 ) ) ); 0067 // FIXME QCOMPARE( viewport.viewLatLonAltBox().center().longitude(), viewport.centerLongitude() ); 0068 // FIXME QCOMPARE( viewport.viewLatLonAltBox().center().latitude(), viewport.centerLatitude() ); 0069 } 0070 0071 void ViewportParamsTest::constructorValues_data() 0072 { 0073 QTest::addColumn<Marble::Projection>( "projection" ); 0074 QTest::addColumn<qreal>( "lon" ); 0075 QTest::addColumn<qreal>( "lat" ); 0076 QTest::addColumn<int>( "radius" ); 0077 QTest::addColumn<QSize>( "size" ); 0078 0079 ViewportParams viewport; 0080 0081 viewport.setProjection( Spherical ); 0082 const AbstractProjection *const spherical = viewport.currentProjection(); 0083 0084 viewport.setProjection( Mercator); 0085 const AbstractProjection *const mercator = viewport.currentProjection(); 0086 0087 viewport.setProjection( Equirectangular ); 0088 const AbstractProjection *const equirectangular = viewport.currentProjection(); 0089 0090 addRow() << Spherical << qreal(0) << qreal(0) << 2000 << QSize( 100, 100 ); 0091 addRow() << Mercator << qreal(0) << qreal(0) << 2000 << QSize( 100, 100 ); 0092 addRow() << Equirectangular << qreal(0) << qreal(0) << 2000 << QSize( 100, 100 ); 0093 0094 addRow() << Spherical << qreal(205 * DEG2RAD) << spherical->maxValidLat() + qreal(1.0) << 2000 << QSize( 100, 100 ); 0095 addRow() << Mercator << qreal(205 * DEG2RAD) << mercator->maxValidLat() + qreal(1.0) << 2000 << QSize( 100, 100 ); 0096 addRow() << Equirectangular << qreal(205 * DEG2RAD) << equirectangular->maxValidLat() + qreal(1.0) << 2000 << QSize( 100, 100 ); 0097 } 0098 0099 void ViewportParamsTest::constructorValues() 0100 { 0101 QFETCH( Projection, projection ); 0102 QFETCH( qreal, lon ); 0103 QFETCH( qreal, lat ); 0104 QFETCH( int, radius ); 0105 QFETCH( QSize, size ); 0106 0107 const ViewportParams byConstructor( projection, lon, lat, radius, size ); 0108 0109 ViewportParams bySetters; 0110 bySetters.setProjection( projection ); 0111 bySetters.centerOn( lon, lat ); 0112 bySetters.setRadius( radius ); 0113 bySetters.setSize( size ); 0114 0115 QCOMPARE( byConstructor.projection(), bySetters.projection() ); 0116 QCOMPARE( byConstructor.currentProjection(), bySetters.currentProjection() ); 0117 QCOMPARE( byConstructor.centerLongitude(), bySetters.centerLongitude() ); 0118 QCOMPARE( byConstructor.centerLatitude(), bySetters.centerLatitude() ); 0119 QCOMPARE( byConstructor.planetAxis(), bySetters.planetAxis() ); 0120 QCOMPARE( byConstructor.angularResolution(), bySetters.angularResolution() ); 0121 QCOMPARE( byConstructor.radius(), bySetters.radius() ); 0122 QCOMPARE( byConstructor.size(), bySetters.size() ); 0123 } 0124 0125 void ViewportParamsTest::screenCoordinates_GeoDataLineString_data() 0126 { 0127 QTest::addColumn<Marble::Projection>( "projection" ); 0128 QTest::addColumn<Marble::TessellationFlags>( "tessellation" ); 0129 QTest::addColumn<GeoDataLineString>( "line" ); 0130 QTest::addColumn<int>( "size" ); 0131 0132 GeoDataCoordinates::Unit deg = GeoDataCoordinates::Degree; 0133 0134 GeoDataLineString longitudeLine; 0135 longitudeLine << GeoDataCoordinates(185, 5, 0, deg ) 0136 << GeoDataCoordinates(185, 15, 0, deg ); 0137 0138 GeoDataLineString diagonalLine; 0139 diagonalLine << GeoDataCoordinates(-185, 5, 0, deg ) 0140 << GeoDataCoordinates(185, 15, 0, deg ); 0141 0142 GeoDataLineString latitudeLine; 0143 latitudeLine << GeoDataCoordinates(-185, 5, 0, deg ) 0144 << GeoDataCoordinates(185, 5, 0, deg ); 0145 0146 Projection projection = Mercator; 0147 0148 TessellationFlags flags = NoTessellation; 0149 QTest::newRow("Mercator NoTesselation Longitude") 0150 << projection << flags << longitudeLine << 2; 0151 0152 QTest::newRow("Mercator NoTesselation Diagonal IDL") 0153 << projection << flags << diagonalLine << 2; 0154 0155 QTest::newRow("Mercator NoTesselation Latitude IDL") 0156 << projection << flags << latitudeLine << 2; 0157 0158 flags = Tessellate; 0159 QTest::newRow("Mercator Tesselate Longitude") 0160 << projection << flags << longitudeLine << 2; 0161 0162 QTest::newRow("Mercator Tesselate Diagonal IDL") 0163 << projection << flags << diagonalLine << 2; 0164 0165 QTest::newRow("Mercator Tesselate Latitude IDL") 0166 << projection << flags << latitudeLine << 2; 0167 0168 flags = Tessellate | RespectLatitudeCircle; 0169 QTest::newRow("Mercator LatitudeCircle Longitude") 0170 << projection << flags << longitudeLine << 2; 0171 0172 QTest::newRow("Mercator LatitudeCircle Diagonal IDL") 0173 << projection << flags << diagonalLine << 2; 0174 0175 QTest::newRow("Mercator LatitudeCircle Latitude IDL") 0176 << projection << flags << latitudeLine << 2; 0177 0178 projection = Equirectangular; 0179 0180 flags = NoTessellation; 0181 QTest::newRow("Equirect NoTesselation Longitude") 0182 << projection << flags << longitudeLine << 2; 0183 0184 QTest::newRow("Equirect NoTesselation Diagonal IDL") 0185 << projection << flags << diagonalLine << 2; 0186 0187 QTest::newRow("Equirect NoTesselation Latitude IDL") 0188 << projection << flags << latitudeLine << 2; 0189 0190 flags = Tessellate; 0191 QTest::newRow("Equirect Tesselate Longitude") 0192 << projection << flags << longitudeLine << 2; 0193 0194 QTest::newRow("Equirect Tesselate Diagonal IDL") 0195 << projection << flags << diagonalLine << 2; 0196 0197 QTest::newRow("Equirect Tesselate Latitude IDL") 0198 << projection << flags << latitudeLine << 2; 0199 0200 flags = Tessellate | RespectLatitudeCircle; 0201 QTest::newRow("Equirect LatitudeCircle Longitude") 0202 << projection << flags << longitudeLine << 2; 0203 0204 QTest::newRow("Equirect LatitudeCircle Diagonal IDL") 0205 << projection << flags << diagonalLine << 2; 0206 0207 QTest::newRow("Equirect LatitudeCircle Latitude IDL") 0208 << projection << flags << latitudeLine << 2; 0209 0210 0211 projection = Spherical; 0212 0213 flags = NoTessellation; 0214 QTest::newRow("Spherical NoTesselation Longitude") 0215 << projection << flags << longitudeLine << 1; 0216 0217 QTest::newRow("Spherical NoTesselation Diagonal IDL") 0218 << projection << flags << diagonalLine << 1; 0219 0220 QTest::newRow("Spherical NoTesselation Latitude IDL") 0221 << projection << flags << latitudeLine << 1; 0222 0223 flags = Tessellate; 0224 QTest::newRow("Spherical Tesselate Longitude") 0225 << projection << flags << longitudeLine << 1; 0226 0227 QTest::newRow("Spherical Tesselate Diagonal IDL") 0228 << projection << flags << diagonalLine << 1; 0229 0230 QTest::newRow("Spherical Tesselate Latitude IDL") 0231 << projection << flags << latitudeLine << 1; 0232 0233 flags = Tessellate | RespectLatitudeCircle; 0234 QTest::newRow("Spherical LatitudeCircle Longitude") 0235 << projection << flags << longitudeLine << 1; 0236 0237 QTest::newRow("Spherical LatitudeCircle Diagonal IDL") 0238 << projection << flags << diagonalLine << 1; 0239 0240 QTest::newRow("Spherical LatitudeCircle Latitude IDL") 0241 << projection << flags << latitudeLine << 1; 0242 0243 } 0244 0245 void ViewportParamsTest::screenCoordinates_GeoDataLineString() 0246 { 0247 QFETCH( Marble::Projection, projection ); 0248 QFETCH( Marble::TessellationFlags, tessellation ); 0249 QFETCH( GeoDataLineString, line ); 0250 QFETCH( int, size ); 0251 0252 ViewportParams viewport; 0253 viewport.setProjection( projection ); 0254 viewport.setRadius( 360 / 4 ); // for easy mapping of lon <-> x 0255 viewport.centerOn(185 * DEG2RAD, 0); 0256 0257 line.setTessellationFlags( tessellation ); 0258 QVector<QPolygonF*> polys; 0259 viewport.screenCoordinates(line, polys); 0260 0261 foreach (QPolygonF* poly, polys) { 0262 // at least 2 points in one poly 0263 QVERIFY( poly->size() > 1 ); 0264 QPointF oldCoord = poly->first(); 0265 poly->pop_front(); 0266 0267 foreach(const QPointF &coord, *poly) { 0268 // no 2 same points 0269 QVERIFY( (coord-oldCoord) != QPointF() ); 0270 0271 // no 2 consecutive points should be more than 90° apart 0272 QVERIFY( (coord-oldCoord).manhattanLength() < viewport.radius() ); 0273 oldCoord = coord; 0274 } 0275 } 0276 0277 // check the provided number of polys 0278 QCOMPARE( polys.size(), size ); 0279 } 0280 0281 void ViewportParamsTest::screenCoordinates_GeoDataLineString2() 0282 { 0283 const ViewportParams viewport( Spherical, 90 * DEG2RAD, 38 * DEG2RAD, 256, QSize( 1165, 833 ) ); 0284 0285 const GeoDataCoordinates coordinates( -90, 23.44, 0.0, GeoDataCoordinates::Degree ); 0286 qreal x, y; 0287 bool globeHidesPoint; 0288 viewport.screenCoordinates( coordinates, x, y, globeHidesPoint ); 0289 0290 QCOMPARE( globeHidesPoint, true ); 0291 0292 GeoDataLineString line( Tessellate | RespectLatitudeCircle ); 0293 line << GeoDataCoordinates( -180, 23.4400, 0.0, GeoDataCoordinates::Degree ); 0294 line << GeoDataCoordinates( 0, 23.4400, 0.0, GeoDataCoordinates::Degree ); 0295 0296 QVector<QPolygonF*> polys; 0297 viewport.screenCoordinates( line, polys ); 0298 0299 QCOMPARE( polys.size(), 2 ); 0300 } 0301 0302 void ViewportParamsTest::screenCoordinates_GeoDataLinearRing() 0303 { 0304 // Creates a Rectangle on the eastern southern hemisphere 0305 // with the planet rotated so that only the western half 0306 // of the rectangle is visible. As a result only a single 0307 // screen polygon should be rendered. 0308 0309 const ViewportParams viewport( Spherical, -15 * DEG2RAD, 0 * DEG2RAD, 350, QSize( 1000, 750 ) ); 0310 0311 GeoDataLinearRing line( Tessellate ); 0312 GeoDataCoordinates coord1 ( 30, -10, 0.0, GeoDataCoordinates::Degree ); 0313 GeoDataCoordinates coord2 ( 30, -45, 0.0, GeoDataCoordinates::Degree ); 0314 GeoDataCoordinates coord3 ( 100, -45, 0.0, GeoDataCoordinates::Degree ); 0315 GeoDataCoordinates coord4 ( 100, -10, 0.0, GeoDataCoordinates::Degree ); 0316 0317 qreal x, y; 0318 bool globeHidesPoint; 0319 viewport.screenCoordinates( coord1, x, y, globeHidesPoint ); 0320 QCOMPARE( globeHidesPoint, false ); 0321 viewport.screenCoordinates( coord2, x, y, globeHidesPoint ); 0322 QCOMPARE( globeHidesPoint, false ); 0323 viewport.screenCoordinates( coord3, x, y, globeHidesPoint ); 0324 QCOMPARE( globeHidesPoint, true ); 0325 viewport.screenCoordinates( coord4, x, y, globeHidesPoint ); 0326 QCOMPARE( globeHidesPoint, true ); 0327 0328 line << coord1 << coord2 << coord3 << coord4; 0329 0330 QVector<QPolygonF*> polys; 0331 viewport.screenCoordinates( line, polys ); 0332 0333 QCOMPARE( polys.size(), 1 ); 0334 } 0335 0336 void ViewportParamsTest::geoDataLinearRing_data() 0337 { 0338 QTest::addColumn<Marble::Projection>( "projection" ); 0339 QTest::addColumn<Marble::TessellationFlags>( "tessellation" ); 0340 QTest::addColumn<GeoDataLinearRing>( "ring" ); 0341 QTest::addColumn<int>( "size" ); 0342 0343 GeoDataCoordinates::Unit deg = GeoDataCoordinates::Degree; 0344 0345 GeoDataLinearRing normalRing; 0346 normalRing << GeoDataCoordinates(175, 5, 0, deg ) 0347 << GeoDataCoordinates(175, 15, 0, deg ) 0348 << GeoDataCoordinates(170, 15, 0, deg ); 0349 0350 GeoDataLinearRing acrossIDLRing; 0351 acrossIDLRing << GeoDataCoordinates(-175, 5, 0, deg ) 0352 << GeoDataCoordinates(175, 5, 0, deg ) 0353 << GeoDataCoordinates(175, 15, 0, deg ); 0354 0355 GeoDataLinearRing aroundSPoleRing; 0356 aroundSPoleRing << GeoDataCoordinates(-175, -65, 0, deg ) 0357 << GeoDataCoordinates(-55, -70, 0, deg ) 0358 << GeoDataCoordinates(65, -75, 0, deg ); 0359 0360 Projection projection = Mercator; 0361 0362 TessellationFlags flags = NoTessellation; 0363 QTest::newRow("Mercator NoTesselation normalRing") 0364 << projection << flags << normalRing << 2; 0365 0366 QTest::newRow("Mercator NoTesselation acrossIDLRing") 0367 << projection << flags << acrossIDLRing << 2; 0368 0369 #ifdef BUG_357540_IS_FIXED 0370 QTest::newRow("Mercator NoTesselation aroundSPoleRing") 0371 << projection << flags << aroundSPoleRing << 2; 0372 #endif 0373 0374 flags = Tessellate; 0375 QTest::newRow("Mercator Tesselate normalRing") 0376 << projection << flags << normalRing << 2; 0377 0378 QTest::newRow("Mercator Tesselate acrossIDLRing") 0379 << projection << flags << acrossIDLRing << 2; 0380 0381 #ifdef BUG_357540_IS_FIXED 0382 QTest::newRow("Mercator Tesselate aroundSPoleRing") 0383 << projection << flags << aroundSPoleRing << 2; 0384 #endif 0385 0386 flags = Tessellate | RespectLatitudeCircle; 0387 QTest::newRow("Mercator LatitudeCircle normalRing") 0388 << projection << flags << normalRing << 2; 0389 0390 QTest::newRow("Mercator LatitudeCircle acrossIDLRing") 0391 << projection << flags << acrossIDLRing << 2; 0392 0393 #ifdef BUG_357540_IS_FIXED 0394 QTest::newRow("Mercator LatitudeCircle aroundSPoleRing") 0395 << projection << flags << aroundSPoleRing << 2; 0396 #endif 0397 0398 projection = Equirectangular; 0399 0400 flags = NoTessellation; 0401 QTest::newRow("Equirect NoTesselation normalRing") 0402 << projection << flags << normalRing << 2; 0403 0404 QTest::newRow("Equirect NoTesselation acrossIDLRing") 0405 << projection << flags << acrossIDLRing << 2; 0406 0407 #ifdef BUG_357540_IS_FIXED 0408 QTest::newRow("Equirect NoTesselation aroundSPoleRing") 0409 << projection << flags << aroundSPoleRing << 2; 0410 #endif 0411 0412 flags = Tessellate; 0413 QTest::newRow("Equirect Tesselate normalRing") 0414 << projection << flags << normalRing << 2; 0415 0416 QTest::newRow("Equirect Tesselate acrossIDLRing") 0417 << projection << flags << acrossIDLRing << 2; 0418 0419 #ifdef BUG_357540_IS_FIXED 0420 QTest::newRow("Equirect Tesselate aroundSPoleRing") 0421 << projection << flags << aroundSPoleRing << 2; 0422 #endif 0423 0424 flags = Tessellate | RespectLatitudeCircle; 0425 QTest::newRow("Equirect LatitudeCircle normalRing") 0426 << projection << flags << normalRing << 2; 0427 0428 QTest::newRow("Equirect LatitudeCircle acrossIDLRing") 0429 << projection << flags << acrossIDLRing << 2; 0430 0431 #ifdef BUG_357540_IS_FIXED 0432 QTest::newRow("Equirect LatitudeCircle aroundSPoleRing") 0433 << projection << flags << aroundSPoleRing << 2; 0434 #endif 0435 0436 projection = Spherical; 0437 0438 flags = NoTessellation; 0439 QTest::newRow("Spherical NoTesselation normalRing") 0440 << projection << flags << normalRing << 1; 0441 0442 QTest::newRow("Spherical NoTesselation acrossIDLRing") 0443 << projection << flags << acrossIDLRing << 1; 0444 0445 QTest::newRow("Spherical NoTesselation aroundSPoleRing") 0446 << projection << flags << aroundSPoleRing << 1; 0447 0448 flags = Tessellate; 0449 QTest::newRow("Spherical Tesselate normalRing") 0450 << projection << flags << normalRing << 1; 0451 0452 QTest::newRow("Spherical Tesselate acrossIDLRing") 0453 << projection << flags << acrossIDLRing << 1; 0454 0455 /* QTest::newRow("Spherical Tesselate aroundSPoleRing") 0456 << projection << flags << aroundSPoleRing << 1;*/ 0457 0458 flags = Tessellate | RespectLatitudeCircle; 0459 QTest::newRow("Spherical LatitudeCircle normalRing") 0460 << projection << flags << normalRing << 1; 0461 0462 QTest::newRow("Spherical LatitudeCircle acrossIDLRing") 0463 << projection << flags << acrossIDLRing << 1; 0464 0465 /* QTest::newRow("Spherical LatitudeCircle aroundSPoleRing") 0466 << projection << flags << aroundSPoleRing << 1;*/ 0467 0468 } 0469 0470 void ViewportParamsTest::geoDataLinearRing() 0471 { 0472 QFETCH( Marble::Projection, projection ); 0473 QFETCH( Marble::TessellationFlags, tessellation ); 0474 QFETCH( GeoDataLinearRing, ring ); 0475 QFETCH( int, size ); 0476 0477 ViewportParams viewport; 0478 viewport.setProjection( projection ); 0479 viewport.setRadius( 360 / 4 ); // for easy mapping of lon <-> x 0480 viewport.centerOn(175 * DEG2RAD, 0); 0481 0482 ring.setTessellationFlags( tessellation ); 0483 QVector<QPolygonF*> polys; 0484 viewport.screenCoordinates(ring, polys); 0485 0486 foreach (QPolygonF* poly, polys) { 0487 // at least 3 points in one poly 0488 QVERIFY( poly->size() > 2 ); 0489 QPointF oldCoord = poly->first(); 0490 // polygon comes back to same point 0491 QVERIFY( poly->isClosed() ); 0492 poly->pop_front(); 0493 0494 foreach(const QPointF &coord, *poly) { 0495 // no 2 same points 0496 QVERIFY( (coord-oldCoord) != QPointF() ); 0497 0498 // no 2 consecutive points should be more than 90° apart 0499 // QVERIFY( (coord-oldCoord).manhattanLength() < viewport.radius() ); 0500 oldCoord = coord; 0501 } 0502 } 0503 0504 // check the provided number of polys 0505 QCOMPARE( polys.size(), size ); 0506 } 0507 0508 void ViewportParamsTest::setInvalidRadius() 0509 { 0510 ViewportParams viewport; 0511 0512 // QVERIFY( viewport.radius() > 0 ); already verified above 0513 0514 const int radius = viewport.radius(); 0515 viewport.setRadius( 0 ); 0516 0517 QCOMPARE( viewport.radius(), radius ); 0518 } 0519 0520 void ViewportParamsTest::setFocusPoint() 0521 { 0522 const GeoDataCoordinates focusPoint1( 10, 13, 0, GeoDataCoordinates::Degree ); 0523 const GeoDataCoordinates focusPoint2( 14.3, 20.5, 0, GeoDataCoordinates::Degree ); 0524 0525 ViewportParams viewport; 0526 0527 const GeoDataCoordinates center = viewport.focusPoint(); 0528 0529 QVERIFY( center != focusPoint1 ); 0530 QVERIFY( center != focusPoint2 ); 0531 0532 viewport.setFocusPoint( focusPoint1 ); 0533 QCOMPARE( viewport.focusPoint(), focusPoint1 ); 0534 0535 viewport.resetFocusPoint(); 0536 QCOMPARE( viewport.focusPoint(), center ); 0537 0538 viewport.setFocusPoint( focusPoint2 ); 0539 QCOMPARE( viewport.focusPoint(), focusPoint2 ); 0540 0541 viewport.setFocusPoint( focusPoint1 ); 0542 QCOMPARE( viewport.focusPoint(), focusPoint1 ); 0543 0544 viewport.resetFocusPoint(); 0545 QCOMPARE( viewport.focusPoint(), center ); 0546 } 0547 0548 } 0549 0550 QTEST_MAIN( Marble::ViewportParamsTest ) 0551 0552 #include "ViewportParamsTest.moc"