File indexing completed on 2024-04-28 03:50:17
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2009 Torsten Rahn <tackat@kde.org> 0004 // 0005 0006 #include "GraticulePlugin.h" 0007 #include "ui_GraticuleConfigWidget.h" 0008 0009 #include "MarbleDebug.h" 0010 #include "MarbleDirs.h" 0011 #include "GeoPainter.h" 0012 #include "GeoDataLineString.h" 0013 #include "Planet.h" 0014 #include "MarbleModel.h" 0015 #include "PluginAboutDialog.h" 0016 0017 #include "ViewportParams.h" 0018 0019 // Qt 0020 #include <QPushButton> 0021 #include <QRect> 0022 #include <QColor> 0023 #include <QBrush> 0024 #include <QDebug> 0025 0026 0027 0028 namespace Marble 0029 { 0030 0031 GraticulePlugin::GraticulePlugin() 0032 : RenderPlugin( nullptr ), 0033 m_showPrimaryLabels( true ), 0034 m_showSecondaryLabels( true ), 0035 m_isInitialized( false ), 0036 ui_configWidget( nullptr ), 0037 m_configDialog( nullptr ) 0038 { 0039 } 0040 0041 GraticulePlugin::GraticulePlugin( const MarbleModel *marbleModel ) 0042 : RenderPlugin( marbleModel ), 0043 m_equatorCirclePen( Qt::yellow ), 0044 m_tropicsCirclePen( Qt::yellow ), 0045 m_gridCirclePen( Qt::white ), 0046 m_showPrimaryLabels( true ), 0047 m_showSecondaryLabels( true ), 0048 m_isInitialized( false ), 0049 ui_configWidget( nullptr ), 0050 m_configDialog( nullptr ) 0051 { 0052 } 0053 0054 QStringList GraticulePlugin::backendTypes() const 0055 { 0056 return QStringList(QStringLiteral("graticule")); 0057 } 0058 0059 QString GraticulePlugin::renderPolicy() const 0060 { 0061 return QStringLiteral("ALWAYS"); 0062 } 0063 0064 QStringList GraticulePlugin::renderPosition() const 0065 { 0066 return QStringList(QStringLiteral("GRATICULE")); 0067 } 0068 0069 QString GraticulePlugin::name() const 0070 { 0071 return tr( "Coordinate Grid" ); 0072 } 0073 0074 QString GraticulePlugin::guiString() const 0075 { 0076 return tr( "Coordinate &Grid" ); 0077 } 0078 0079 QString GraticulePlugin::nameId() const 0080 { 0081 return QStringLiteral("coordinate-grid"); 0082 } 0083 0084 QString GraticulePlugin::version() const 0085 { 0086 return QStringLiteral("1.0"); 0087 } 0088 0089 QString GraticulePlugin::description() const 0090 { 0091 return tr( "A plugin that shows a coordinate grid." ); 0092 } 0093 0094 QString GraticulePlugin::copyrightYears() const 0095 { 0096 return QStringLiteral("2009"); 0097 } 0098 0099 QVector<PluginAuthor> GraticulePlugin::pluginAuthors() const 0100 { 0101 return QVector<PluginAuthor>() 0102 << PluginAuthor(QStringLiteral("Torsten Rahn"), QStringLiteral("tackat@kde.org")); 0103 } 0104 0105 QIcon GraticulePlugin::icon () const 0106 { 0107 return QIcon(QStringLiteral(":/icons/coordinate.png")); 0108 } 0109 0110 void GraticulePlugin::initialize () 0111 { 0112 // Initialize range maps that map the zoom to the number of coordinate grid lines. 0113 0114 initLineMaps( GeoDataCoordinates::defaultNotation() ); 0115 0116 m_isInitialized = true; 0117 } 0118 0119 bool GraticulePlugin::isInitialized () const 0120 { 0121 return m_isInitialized; 0122 } 0123 0124 QDialog *GraticulePlugin::configDialog() 0125 { 0126 if ( !m_configDialog ) { 0127 m_configDialog = new QDialog(); 0128 ui_configWidget = new Ui::GraticuleConfigWidget; 0129 ui_configWidget->setupUi( m_configDialog ); 0130 0131 connect( ui_configWidget->gridPushButton, SIGNAL(clicked()), this, 0132 SLOT(gridGetColor()) ); 0133 connect( ui_configWidget->tropicsPushButton, SIGNAL(clicked()), this, 0134 SLOT(tropicsGetColor()) ); 0135 connect( ui_configWidget->equatorPushButton, SIGNAL(clicked()), this, 0136 SLOT(equatorGetColor()) ); 0137 0138 0139 connect( ui_configWidget->m_buttonBox, SIGNAL(accepted()), this, 0140 SLOT(writeSettings()) ); 0141 connect( ui_configWidget->m_buttonBox->button( QDialogButtonBox::Reset ), SIGNAL(clicked()), 0142 SLOT(restoreDefaultSettings()) ); 0143 QPushButton *applyButton = ui_configWidget->m_buttonBox->button( QDialogButtonBox::Apply ); 0144 connect( applyButton, SIGNAL(clicked()), 0145 this, SLOT(writeSettings()) ); 0146 } 0147 0148 readSettings(); 0149 0150 return m_configDialog; 0151 } 0152 0153 0154 QHash<QString,QVariant> GraticulePlugin::settings() const 0155 { 0156 QHash<QString, QVariant> settings = RenderPlugin::settings(); 0157 0158 settings.insert(QStringLiteral("gridColor"), m_gridCirclePen.color().name()); 0159 settings.insert(QStringLiteral("tropicsColor"), m_tropicsCirclePen.color().name()); 0160 settings.insert(QStringLiteral("equatorColor"), m_equatorCirclePen.color().name()); 0161 settings.insert(QStringLiteral("primaryLabels"), m_showPrimaryLabels); 0162 settings.insert(QStringLiteral("secondaryLabels"), m_showSecondaryLabels); 0163 0164 return settings; 0165 } 0166 0167 void GraticulePlugin::setSettings( const QHash<QString,QVariant> &settings ) 0168 { 0169 RenderPlugin::setSettings( settings ); 0170 0171 const QColor gridColor = settings.value(QStringLiteral("gridColor"), QColor(Qt::white)).value<QColor>(); 0172 const QColor tropicsColor = settings.value(QStringLiteral("tropicsColor"), QColor(Qt::yellow)).value<QColor>(); 0173 const QColor equatorColor = settings.value(QStringLiteral("equatorColor"), QColor(Qt::yellow)).value<QColor>(); 0174 bool primaryLabels = settings.value(QStringLiteral("primaryLabels"), true).toBool(); 0175 bool secondaryLabels = settings.value(QStringLiteral("secondaryLabels"), true).toBool(); 0176 0177 m_gridCirclePen.setColor( gridColor ); 0178 m_tropicsCirclePen.setColor( tropicsColor ); 0179 m_equatorCirclePen.setColor( equatorColor ); 0180 0181 m_showPrimaryLabels = primaryLabels; 0182 m_showSecondaryLabels = secondaryLabels; 0183 0184 readSettings(); 0185 } 0186 0187 0188 void GraticulePlugin::readSettings() 0189 { 0190 if ( !m_configDialog ) 0191 return; 0192 0193 QPalette gridPalette; 0194 gridPalette.setColor( QPalette::Button, m_gridCirclePen.color() ); 0195 ui_configWidget->gridPushButton->setPalette( gridPalette ); 0196 0197 QPalette tropicsPalette; 0198 tropicsPalette.setColor( QPalette::Button, m_tropicsCirclePen.color() ); 0199 ui_configWidget->tropicsPushButton->setPalette( tropicsPalette ); 0200 0201 0202 QPalette equatorPalette; 0203 equatorPalette.setColor( QPalette::Button, m_equatorCirclePen.color() ); 0204 ui_configWidget->equatorPushButton->setPalette( equatorPalette ); 0205 ui_configWidget->primaryCheckBox->setChecked( m_showPrimaryLabels ); 0206 ui_configWidget->secondaryCheckBox->setChecked( m_showSecondaryLabels ); 0207 } 0208 0209 void GraticulePlugin::gridGetColor() 0210 { 0211 const QColor c = QColorDialog::getColor( m_gridCirclePen.color(), nullptr, tr("Please choose the color for the coordinate grid.") ); 0212 0213 if ( c.isValid() ) { 0214 QPalette palette = ui_configWidget->gridPushButton->palette(); 0215 palette.setColor( QPalette::Button, c ); 0216 ui_configWidget->gridPushButton->setPalette( palette ); 0217 } 0218 } 0219 0220 void GraticulePlugin::tropicsGetColor() 0221 { 0222 const QColor c = QColorDialog::getColor( m_tropicsCirclePen.color(), nullptr, tr("Please choose the color for the tropic circles.") ); 0223 0224 if ( c.isValid() ) { 0225 QPalette palette = ui_configWidget->tropicsPushButton->palette(); 0226 palette.setColor( QPalette::Button, c ); 0227 ui_configWidget->tropicsPushButton->setPalette( palette ); 0228 } 0229 } 0230 0231 void GraticulePlugin::equatorGetColor() 0232 { 0233 const QColor c = QColorDialog::getColor( m_equatorCirclePen.color(), nullptr, tr("Please choose the color for the equator.") ); 0234 0235 if ( c.isValid() ) { 0236 QPalette palette = ui_configWidget->equatorPushButton->palette(); 0237 palette.setColor( QPalette::Button, c ); 0238 ui_configWidget->equatorPushButton->setPalette( palette ); 0239 } 0240 } 0241 0242 void GraticulePlugin::writeSettings() 0243 { 0244 m_equatorCirclePen.setColor( ui_configWidget->equatorPushButton->palette().color( QPalette::Button ) ); 0245 m_tropicsCirclePen.setColor( ui_configWidget->tropicsPushButton->palette().color( QPalette::Button ) ); 0246 m_gridCirclePen.setColor( ui_configWidget->gridPushButton->palette().color( QPalette::Button) ); 0247 m_showPrimaryLabels = ui_configWidget->primaryCheckBox->isChecked(); 0248 m_showSecondaryLabels = ui_configWidget->secondaryCheckBox->isChecked(); 0249 0250 emit settingsChanged( nameId() ); 0251 } 0252 0253 bool GraticulePlugin::render( GeoPainter *painter, ViewportParams *viewport, 0254 const QString& renderPos, 0255 GeoSceneLayer * layer ) 0256 { 0257 Q_UNUSED( layer ) 0258 Q_UNUSED( renderPos ) 0259 0260 if ( m_currentNotation != GeoDataCoordinates::defaultNotation() ) { 0261 initLineMaps( GeoDataCoordinates::defaultNotation() ); 0262 } 0263 0264 // Setting the label font for the coordinate lines. 0265 #ifdef Q_OS_MACX 0266 int defaultFontSize = 10; 0267 #else 0268 int defaultFontSize = 8; 0269 #endif 0270 0271 QFont gridFont("Sans Serif"); 0272 gridFont.setPointSize( defaultFontSize ); 0273 gridFont.setBold( true ); 0274 0275 painter->save(); 0276 0277 painter->setFont( gridFont ); 0278 0279 renderGrid( painter, viewport, m_equatorCirclePen, m_tropicsCirclePen, m_gridCirclePen ); 0280 0281 painter->restore(); 0282 0283 return true; 0284 } 0285 0286 qreal GraticulePlugin::zValue() const 0287 { 0288 return 1.0; 0289 } 0290 0291 void GraticulePlugin::renderGrid( GeoPainter *painter, ViewportParams *viewport, 0292 const QPen& equatorCirclePen, 0293 const QPen& tropicsCirclePen, 0294 const QPen& gridCirclePen ) 0295 { 0296 GeoDataLatLonAltBox viewLatLonAltBox = viewport->viewLatLonAltBox(); 0297 0298 painter->setPen( equatorCirclePen ); 0299 0300 LabelPositionFlags mainPosition(NoLabel); 0301 if ( m_showPrimaryLabels ) { 0302 mainPosition = LineCenter; 0303 } 0304 // Render the equator 0305 renderLatitudeLine( painter, 0.0, viewLatLonAltBox, tr( "Equator" ), mainPosition ); 0306 0307 // Render the Prime Meridian and Antimeridian 0308 GeoDataCoordinates::Notation notation = GeoDataCoordinates::defaultNotation(); 0309 if (marbleModel()->planet()->id() != QLatin1String("sky") && notation != GeoDataCoordinates::Astro) { 0310 renderLongitudeLine( painter, 0.0, viewLatLonAltBox, 0.0, 0.0, tr( "Prime Meridian" ), mainPosition ); 0311 renderLongitudeLine( painter, 180.0, viewLatLonAltBox, 0.0, 0.0, tr( "Antimeridian" ), mainPosition ); 0312 } 0313 0314 painter->setPen( gridCirclePen ); 0315 // painter->setPen( QPen( QBrush( Qt::white ), 0.75 ) ); 0316 0317 // Render UTM grid zones 0318 if ( m_currentNotation == GeoDataCoordinates::UTM ) { 0319 renderLatitudeLine( painter, 84.0, viewLatLonAltBox ); 0320 0321 renderLongitudeLines( painter, viewLatLonAltBox, 0322 6.0, 0.0, 0323 18.0, 154.0, LineEnd | IgnoreXMargin ); 0324 renderLongitudeLines( painter, viewLatLonAltBox, 0325 6.0, 0.0, 0326 34.0, 10.0, LineStart | IgnoreXMargin ); 0327 0328 // Paint longitudes with exceptions 0329 renderLongitudeLines( painter, viewLatLonAltBox, 0330 6.0, 0.0, 0331 6.0, 162.0, LineEnd | IgnoreXMargin ); 0332 renderLongitudeLines( painter, viewLatLonAltBox, 0333 6.0, 0.0, 0334 26.0, 146.0, LineEnd | IgnoreXMargin ); 0335 0336 renderLatitudeLines( painter, viewLatLonAltBox, 8.0, 0.0 /*, 0337 LineStart | IgnoreYMargin */ ); 0338 0339 return; 0340 } 0341 0342 // Render the normal grid 0343 0344 // calculate the angular distance between coordinate lines of the normal grid 0345 qreal normalDegreeStep = 360.0 / m_normalLineMap.lowerBound(viewport->radius()).value(); 0346 0347 LabelPositionFlags labelXPosition(NoLabel), labelYPosition(NoLabel); 0348 if ( m_showSecondaryLabels ) { 0349 labelXPosition = LineStart | IgnoreXMargin; 0350 labelYPosition = LineStart | IgnoreYMargin; 0351 } 0352 qreal boldDegreeStep = 360.0 / m_boldLineMap.lowerBound(viewport->radius()).value(); 0353 renderLongitudeLines( painter, viewLatLonAltBox, 0354 normalDegreeStep, boldDegreeStep, 0355 normalDegreeStep, normalDegreeStep, 0356 labelXPosition ); 0357 renderLatitudeLines( painter, viewLatLonAltBox, normalDegreeStep, boldDegreeStep, 0358 labelYPosition ); 0359 0360 // Render some non-cut off longitude lines .. 0361 renderLongitudeLine( painter, +90.0, viewLatLonAltBox ); 0362 renderLongitudeLine( painter, -90.0, viewLatLonAltBox ); 0363 0364 // Render the bold grid 0365 0366 if ( painter->mapQuality() == HighQuality 0367 || painter->mapQuality() == PrintQuality ) { 0368 0369 QPen boldPen = gridCirclePen; 0370 boldPen.setWidthF( 2.0 ); 0371 painter->setPen( boldPen ); 0372 } 0373 0374 // calculate the angular distance between coordinate lines of the bold grid 0375 0376 renderLongitudeLines( painter, viewLatLonAltBox, 0377 boldDegreeStep, 0.0, 0378 normalDegreeStep, normalDegreeStep, 0379 NoLabel 0380 ); 0381 0382 renderLatitudeLines( painter, viewLatLonAltBox, boldDegreeStep, 0.0, 0383 NoLabel ); 0384 0385 QPen tropicsPen = tropicsCirclePen; 0386 if ( painter->mapQuality() != OutlineQuality 0387 && painter->mapQuality() != LowQuality ) { 0388 tropicsPen.setStyle( Qt::DotLine ); 0389 } 0390 painter->setPen( tropicsPen ); 0391 0392 // Determine the planet's axial tilt 0393 qreal axialTilt = RAD2DEG * marbleModel()->planet()->epsilon(); 0394 0395 if ( axialTilt > 0 ) { 0396 // Render the tropics 0397 renderLatitudeLine( painter, +axialTilt, viewLatLonAltBox, tr( "Tropic of Cancer" ), mainPosition ); 0398 renderLatitudeLine( painter, -axialTilt, viewLatLonAltBox, tr( "Tropic of Capricorn" ), mainPosition ); 0399 0400 // Render the arctics 0401 renderLatitudeLine( painter, +90.0 - axialTilt, viewLatLonAltBox, tr( "Arctic Circle" ), mainPosition ); 0402 renderLatitudeLine( painter, -90.0 + axialTilt, viewLatLonAltBox, tr( "Antarctic Circle" ), mainPosition ); 0403 } 0404 } 0405 0406 void GraticulePlugin::renderLatitudeLine( GeoPainter *painter, qreal latitude, 0407 const GeoDataLatLonAltBox& viewLatLonAltBox, 0408 const QString& lineLabel, 0409 LabelPositionFlags labelPositionFlags ) 0410 { 0411 qreal fromSouthLat = viewLatLonAltBox.south( GeoDataCoordinates::Degree ); 0412 qreal toNorthLat = viewLatLonAltBox.north( GeoDataCoordinates::Degree ); 0413 0414 // Coordinate line is not displayed inside the viewport 0415 if ( latitude < fromSouthLat || toNorthLat < latitude ) { 0416 // mDebug() << "Lat: Out of View"; 0417 return; 0418 } 0419 0420 GeoDataLineString line( Tessellate | RespectLatitudeCircle ) ; 0421 0422 qreal fromWestLon = viewLatLonAltBox.west( GeoDataCoordinates::Degree ); 0423 qreal toEastLon = viewLatLonAltBox.east( GeoDataCoordinates::Degree ); 0424 0425 if ( fromWestLon < toEastLon ) { 0426 qreal step = ( toEastLon - fromWestLon ) * 0.25; 0427 0428 for ( int i = 0; i < 5; ++i ) { 0429 line << GeoDataCoordinates( fromWestLon + i * step, latitude, 0.0, GeoDataCoordinates::Degree ); 0430 } 0431 } 0432 else { 0433 qreal step = ( +180.0 - toEastLon ) * 0.25; 0434 0435 for ( int i = 0; i < 5; ++i ) { 0436 line << GeoDataCoordinates( toEastLon + i * step, latitude, 0.0, GeoDataCoordinates::Degree ); 0437 } 0438 0439 step = ( +180 + fromWestLon ) * 0.25; 0440 0441 for ( int i = 0; i < 5; ++i ) { 0442 line << GeoDataCoordinates( -180 + i * step, latitude, 0.0, GeoDataCoordinates::Degree ); 0443 } 0444 } 0445 0446 painter->drawPolyline( line, lineLabel, labelPositionFlags, painter->pen().color() ); 0447 } 0448 0449 void GraticulePlugin::renderLongitudeLine( GeoPainter *painter, qreal longitude, 0450 const GeoDataLatLonAltBox& viewLatLonAltBox, 0451 qreal northPolarGap, qreal southPolarGap, 0452 const QString& lineLabel, 0453 LabelPositionFlags labelPositionFlags ) 0454 { 0455 const qreal fromWestLon = viewLatLonAltBox.west(); 0456 const qreal toEastLon = viewLatLonAltBox.east(); 0457 0458 // Coordinate line is not displayed inside the viewport 0459 if ( ( !viewLatLonAltBox.crossesDateLine() 0460 && ( longitude * DEG2RAD < fromWestLon || toEastLon < longitude * DEG2RAD ) ) || 0461 ( viewLatLonAltBox.crossesDateLine() && 0462 longitude * DEG2RAD < toEastLon && fromWestLon < longitude * DEG2RAD && 0463 fromWestLon != -M_PI && toEastLon != +M_PI ) 0464 ) { 0465 // mDebug() << "Lon: Out of View:" << viewLatLonAltBox.toString() << " Crossing: "<< viewLatLonAltBox.crossesDateLine() << "Longitude: " << longitude; 0466 return; 0467 } 0468 0469 qreal fromSouthLat = viewLatLonAltBox.south( GeoDataCoordinates::Degree ); 0470 qreal toNorthLat = viewLatLonAltBox.north( GeoDataCoordinates::Degree ); 0471 0472 qreal southLat = ( fromSouthLat < -90.0 + southPolarGap ) ? -90.0 + southPolarGap : fromSouthLat; 0473 qreal northLat = ( toNorthLat > +90.0 - northPolarGap ) ? +90.0 - northPolarGap : toNorthLat; 0474 0475 GeoDataCoordinates n1( longitude, southLat, 0.0, GeoDataCoordinates::Degree ); 0476 GeoDataCoordinates n3( longitude, northLat, 0.0, GeoDataCoordinates::Degree ); 0477 0478 GeoDataLineString line( Tessellate ); 0479 0480 if ( northLat > 0 && southLat < 0 ) 0481 { 0482 GeoDataCoordinates n2( longitude, 0.0, 0.0, GeoDataCoordinates::Degree ); 0483 line << n1 << n2 << n3; 0484 } 0485 else { 0486 line << n1 << n3; 0487 } 0488 0489 painter->drawPolyline( line, lineLabel, labelPositionFlags, painter->pen().color() ); 0490 } 0491 0492 void GraticulePlugin::renderLatitudeLines( GeoPainter *painter, 0493 const GeoDataLatLonAltBox& viewLatLonAltBox, 0494 qreal step, qreal skipStep, 0495 LabelPositionFlags labelPositionFlags 0496 ) 0497 { 0498 if ( step <= 0 ) { 0499 return; 0500 } 0501 0502 // Latitude 0503 qreal southLat = viewLatLonAltBox.south( GeoDataCoordinates::Degree ); 0504 qreal northLat = viewLatLonAltBox.north( GeoDataCoordinates::Degree ); 0505 0506 qreal southLineLat = step * static_cast<int>( southLat / step ); 0507 qreal northLineLat = step * ( static_cast<int>( northLat / step ) + 1 ); 0508 0509 if ( m_currentNotation == GeoDataCoordinates::UTM ) { 0510 if ( northLineLat > 84.0 ) { 0511 northLineLat = 76.0; 0512 } 0513 0514 if ( southLineLat < -80.0 ) { 0515 southLineLat = -80.0; 0516 } 0517 } 0518 0519 qreal itStep = southLineLat; 0520 0521 GeoDataCoordinates::Notation notation = GeoDataCoordinates::defaultNotation(); 0522 0523 while ( itStep < northLineLat ) { 0524 // Create a matching label 0525 QString label = GeoDataCoordinates::latToString( itStep, notation, 0526 GeoDataCoordinates::Degree, -1, 'g' ); 0527 0528 // No additional labels for the equator 0529 if ( labelPositionFlags.testFlag( LineCenter ) && itStep == 0.0 ) { 0530 label.clear(); 0531 } 0532 0533 // Paint all latitude coordinate lines except for the equator 0534 if ( itStep != 0.0 && fmod(itStep, skipStep) != 0 ) { 0535 renderLatitudeLine( painter, itStep, viewLatLonAltBox, label, labelPositionFlags ); 0536 } 0537 0538 itStep += step; 0539 } 0540 } 0541 0542 0543 void GraticulePlugin::renderUtmExceptions( GeoPainter *painter, 0544 const GeoDataLatLonAltBox& viewLatLonAltBox, 0545 qreal itStep, qreal northPolarGap, qreal southPolarGap, 0546 const QString & label, 0547 LabelPositionFlags labelPositionFlags ) 0548 { 0549 // This code renders the so called "exceptions" in the UTM coordinate grid 0550 // See: https://en.wikipedia.org/wiki/Universal_Transverse_Mercator_coordinate_system#Exceptions 0551 if ( northPolarGap == 6.0 && southPolarGap == 162.0) { 0552 if (label == QLatin1String("33")) { 0553 renderLongitudeLine( painter, itStep-3.0, viewLatLonAltBox, northPolarGap, 0554 southPolarGap, label, labelPositionFlags ); 0555 } else if (label == QLatin1String("35")) { 0556 renderLongitudeLine( painter, itStep-3.0, viewLatLonAltBox, northPolarGap, 0557 southPolarGap, label, labelPositionFlags ); 0558 } else if (label == QLatin1String("37")) { 0559 renderLongitudeLine( painter, itStep-3.0, viewLatLonAltBox, northPolarGap, 0560 southPolarGap, label, labelPositionFlags ); 0561 } else if (label == QLatin1String("32") || label == QLatin1String("34") || label == QLatin1String("36")) { 0562 // paint nothing 0563 } else { 0564 renderLongitudeLine( painter, itStep, viewLatLonAltBox, northPolarGap, 0565 southPolarGap, label, labelPositionFlags ); 0566 } 0567 } 0568 else if ( northPolarGap == 26.0 && southPolarGap == 146.0 ) { 0569 if (label == QLatin1String("32")) { 0570 renderLongitudeLine( painter, itStep-3.0, viewLatLonAltBox, northPolarGap, 0571 southPolarGap, label, labelPositionFlags ); 0572 } else { 0573 renderLongitudeLine( painter, itStep, viewLatLonAltBox, northPolarGap, 0574 southPolarGap, label, labelPositionFlags ); 0575 } 0576 } 0577 else { 0578 renderLongitudeLine( painter, itStep, viewLatLonAltBox, northPolarGap, 0579 southPolarGap, label, labelPositionFlags ); 0580 } 0581 } 0582 0583 void GraticulePlugin::renderLongitudeLines( GeoPainter *painter, 0584 const GeoDataLatLonAltBox& viewLatLonAltBox, 0585 qreal step, qreal skipStep, 0586 qreal northPolarGap, qreal southPolarGap, 0587 LabelPositionFlags labelPositionFlags) const 0588 { 0589 if ( step <= 0 ) { 0590 return; 0591 } 0592 0593 const bool isSky = (marbleModel()->planet()->id() == QLatin1String("sky")); 0594 const GeoDataCoordinates::Notation notation = isSky ? GeoDataCoordinates::Astro : GeoDataCoordinates::defaultNotation(); 0595 0596 // Set precision to 0 in UTM in order to show only zone number. 0597 int precision = (notation == GeoDataCoordinates::UTM) ? 0 : -1; 0598 0599 // Longitude 0600 qreal westLon = viewLatLonAltBox.west( GeoDataCoordinates::Degree ); 0601 qreal eastLon = viewLatLonAltBox.east( GeoDataCoordinates::Degree ); 0602 0603 qreal westLineLon = step * static_cast<int>( westLon / step ); 0604 qreal eastLineLon = step * ( static_cast<int>( eastLon / step ) + 1 ); 0605 0606 if ( !viewLatLonAltBox.crossesDateLine() || 0607 ( westLon == -180.0 && eastLon == +180.0 ) ) { 0608 qreal itStep = westLineLon; 0609 0610 while ( itStep < eastLineLon ) { 0611 // Create a matching label 0612 QString label = GeoDataCoordinates::lonToString( itStep, 0613 notation, GeoDataCoordinates::Degree, 0614 precision, 'g' ); 0615 0616 // No additional labels for the prime meridian and the antimeridian 0617 0618 if ( labelPositionFlags.testFlag( LineCenter ) && ( itStep == 0.0 || itStep == 180.0 || itStep == -180.0 ) ) 0619 { 0620 label.clear(); 0621 } 0622 0623 // Paint all longitude coordinate lines (except for the meridians in non-UTM mode) 0624 if (notation == GeoDataCoordinates::UTM ) { 0625 renderUtmExceptions( painter, viewLatLonAltBox, itStep, northPolarGap, 0626 southPolarGap, label, labelPositionFlags ); 0627 } else if ( itStep != 0.0 && itStep != 180.0 && itStep != -180.0 ) { 0628 if (fmod(itStep, skipStep) != 0 || skipStep == 0.0) { 0629 renderLongitudeLine( painter, itStep, viewLatLonAltBox, northPolarGap, 0630 southPolarGap, label, labelPositionFlags ); 0631 } 0632 } 0633 itStep += step; 0634 } 0635 } 0636 else { 0637 qreal itStep = eastLineLon; 0638 0639 while ( itStep < 180.0 ) { 0640 // Create a matching label 0641 QString label = GeoDataCoordinates::lonToString( itStep, 0642 notation, GeoDataCoordinates::Degree, 0643 precision, 'g' ); 0644 0645 // No additional labels for the prime meridian and the antimeridian 0646 0647 if ( labelPositionFlags.testFlag( LineCenter ) && ( itStep == 0.0 || itStep == 180.0 || itStep == -180.0 ) ) 0648 { 0649 label.clear(); 0650 } 0651 0652 // Paint all longitude coordinate lines (except for the meridians in non-UTM mode) 0653 if (notation == GeoDataCoordinates::UTM ) { 0654 renderUtmExceptions( painter, viewLatLonAltBox, itStep, northPolarGap, 0655 southPolarGap, label, labelPositionFlags ); 0656 } else if ( itStep != 0.0 && itStep != 180.0 && itStep != -180.0 ) { 0657 if (fmod((itStep), skipStep) != 0 || skipStep == 0.0) { 0658 renderLongitudeLine( painter, itStep, viewLatLonAltBox, northPolarGap, 0659 southPolarGap, label, labelPositionFlags ); 0660 } 0661 } 0662 itStep += step; 0663 } 0664 0665 itStep = -180.0; 0666 0667 while ( itStep < westLineLon ) { 0668 // Create a matching label 0669 QString label = GeoDataCoordinates::lonToString( itStep, 0670 notation, GeoDataCoordinates::Degree, 0671 precision, 'g' ); 0672 0673 // No additional labels for the prime meridian and the antimeridian 0674 if ( labelPositionFlags.testFlag( LineCenter ) && ( itStep == 0.0 || itStep == 180.0 || itStep == -180.0 ) ) 0675 { 0676 label.clear(); 0677 } 0678 0679 // Paint all longitude coordinate lines (except for the meridians in non-UTM mode) 0680 if (notation == GeoDataCoordinates::UTM ) { 0681 renderUtmExceptions( painter, viewLatLonAltBox, itStep, northPolarGap, 0682 southPolarGap, label, labelPositionFlags ); 0683 } else if ( itStep != 0.0 && itStep != 180.0 && itStep != -180.0 ) { 0684 if (fmod((itStep+180), skipStep) != 0 || skipStep == 0.0) { 0685 renderLongitudeLine( painter, itStep, viewLatLonAltBox, northPolarGap, 0686 southPolarGap, label, labelPositionFlags ); 0687 } 0688 } 0689 itStep += step; 0690 } 0691 } 0692 } 0693 0694 void GraticulePlugin::initLineMaps( GeoDataCoordinates::Notation notation) 0695 { 0696 /* Define Upper Bound keys and associated values: 0697 The key number is the globe radius in pixel. 0698 The value number is the amount of grid lines for the full range. 0699 0700 Example: up to a 100 pixel radius the globe is covered 0701 with 4 longitude lines (4 half-circles). 0702 */ 0703 0704 if (marbleModel()->planet()->id() == QLatin1String("sky") || 0705 notation == GeoDataCoordinates::Astro) { 0706 m_normalLineMap[100] = 4; // 6h 0707 m_normalLineMap[1000] = 12; // 2h 0708 m_normalLineMap[2000] = 24; // 1h 0709 m_normalLineMap[4000] = 48; // 30 min 0710 m_normalLineMap[8000] = 96; // 15 min 0711 m_normalLineMap[16000] = 288; // 5 min 0712 m_normalLineMap[100000] = 24 * 60; // 1 min 0713 m_normalLineMap[200000] = 24 * 60 * 2; // 30 sec 0714 m_normalLineMap[400000] = 24 * 60 * 4; // 15 sec 0715 m_normalLineMap[1200000] = 24 * 60 * 12; // 5 sec 0716 m_normalLineMap[6000000] = 24 * 60 * 60; // 1 sec 0717 m_normalLineMap[12000000] = 24 * 60 * 60 * 2; // 0.5 sec 0718 m_normalLineMap[24000000] = 24 * 60 * 60 * 4; // 0.25 sec 0719 0720 m_boldLineMap[1000] = 0; // 0h 0721 m_boldLineMap[2000] = 4; // 6h 0722 m_boldLineMap[16000] = 24; // 30 deg 0723 return; 0724 } 0725 0726 m_normalLineMap[100] = 4; // 90 deg 0727 m_normalLineMap[1000] = 12; // 30 deg 0728 m_normalLineMap[4000] = 36; // 10 deg 0729 m_normalLineMap[16000] = 72; // 5 deg 0730 m_normalLineMap[64000] = 360; // 1 deg 0731 m_normalLineMap[128000] = 720; // 0.5 deg 0732 0733 m_boldLineMap[1000] = 0; // 0 deg 0734 m_boldLineMap[4000] = 12; // 30 deg 0735 m_boldLineMap[16000] = 36; // 10 deg 0736 0737 switch ( notation ) 0738 { 0739 case GeoDataCoordinates::Decimal : 0740 0741 m_normalLineMap[512000] = 360 * 10; // 0.1 deg 0742 m_normalLineMap[2048000] = 360 * 20; // 0.05 deg 0743 m_normalLineMap[8192000] = 360 * 100; // 0.01 deg 0744 m_normalLineMap[16384000] = 360 * 200; // 0.005 deg 0745 m_normalLineMap[32768000] = 360 * 1000; // 0.001 deg 0746 m_normalLineMap[131072000] = 360 * 2000; // 0.0005 deg 0747 m_normalLineMap[524288000] = 360 * 10000; // 0.00001 deg 0748 0749 m_boldLineMap[512000] = 360; // 0.1 deg 0750 m_boldLineMap[2048000] = 720; // 0.05 deg 0751 m_boldLineMap[8192000] = 360 * 10; // 0.01 deg 0752 m_boldLineMap[1638400] = 360 * 20; // 0.005 deg 0753 m_boldLineMap[32768000] = 360 * 100; // 0.001 deg 0754 m_boldLineMap[131072000] = 360 * 200; // 0.0005 deg 0755 m_boldLineMap[524288000] = 360 * 1000; // 0.00001 deg 0756 0757 break; 0758 default: 0759 case GeoDataCoordinates::DMS : 0760 m_normalLineMap[512000] = 360 * 6; // 10' 0761 m_normalLineMap[1024000] = 360 * 12; // 5' 0762 m_normalLineMap[4096000] = 360 * 60; // 1' 0763 m_normalLineMap[8192000] = 360 * 60 * 2; // 30" 0764 m_normalLineMap[16384000] = 360 * 60 * 6; // 10" 0765 m_normalLineMap[65535000] = 360 * 60 * 12; // 5" 0766 m_normalLineMap[524288000] = 360 * 60 * 60; // 1" 0767 0768 m_boldLineMap[512000] = 360; // 10' 0769 m_boldLineMap[1024000] = 720; // 5' 0770 m_boldLineMap[4096000] = 360 * 6; // 1' 0771 m_boldLineMap[8192000] = 360 * 12; // 30" 0772 m_boldLineMap[16384000] = 360 * 60; // 10" 0773 m_boldLineMap[65535000] = 360 * 60 * 2; // 5" 0774 m_boldLineMap[524288000] = 360 * 60 * 6; // 1" 0775 0776 break; 0777 } 0778 m_normalLineMap[999999999] = m_normalLineMap.value(262144000); // last 0779 m_boldLineMap[999999999] = m_boldLineMap.value(262144000); // last 0780 0781 m_currentNotation = notation; 0782 } 0783 0784 } 0785 0786 #include "moc_GraticulePlugin.cpp"