[Kstars-devel] [kstars] kstars: Add dialog to export eyepiece view, w/ annotations to help orient chart
Akarsh Simha
akarsh at kde.org
Mon Jan 18 10:20:34 UTC 2016
Git commit 1313fda1f2f9e78aecdab1f02912137b8d42ae4d by Akarsh Simha.
Committed on 18/01/2016 at 10:23.
Pushed by asimha into branch 'master'.
Add dialog to export eyepiece view, w/ annotations to help orient chart
This commit adds an "Export" button to Eyepiece View which opens a
dialog where one may add a bunch of markings helping the user to
orient the produced eyepiece view for various times of observation.
This feature has not been field tested.
Example output:
http://wstaw.org/m/2016/01/18/M81.png
The markings indicate how to orient the chart for various (local)
times in Austin, TX when viewing through a Dobsonian with a focuser
parallel to the ground. If observing at 3:50 AM, the chart is used as
it is, but for example, at 2:20 AM, the chart needs to be rotated by
about 45 degrees so that the tick corresponding to 2:20 AM points
upwards.
CCMAIL: kstars-devel at kde.org
M +2 -0 kstars/CMakeLists.txt
A +188 -0 kstars/tools/exporteyepieceview.cpp [License: GPL (v2+)]
A +94 -0 kstars/tools/exporteyepieceview.h [License: GPL (v2+)]
M +9 -1 kstars/tools/eyepiecefield.cpp
M +5 -0 kstars/tools/eyepiecefield.h
http://commits.kde.org/kstars/1313fda1f2f9e78aecdab1f02912137b8d42ae4d
diff --git a/kstars/CMakeLists.txt b/kstars/CMakeLists.txt
index 6ce1d79..ef2227a 100644
--- a/kstars/CMakeLists.txt
+++ b/kstars/CMakeLists.txt
@@ -195,8 +195,10 @@ set(libkstarstools_SRCS
#FIXME Port to KF5
#tools/moonphasetool.cpp
+
tools/starhopper.cpp
tools/eyepiecefield.cpp
+ tools/exporteyepieceview.cpp
tools/starhopperdialog.cpp
)
diff --git a/kstars/tools/exporteyepieceview.cpp b/kstars/tools/exporteyepieceview.cpp
new file mode 100644
index 0000000..4838d24
--- /dev/null
+++ b/kstars/tools/exporteyepieceview.cpp
@@ -0,0 +1,188 @@
+/***************************************************************************
+ exporteyepieceview.cpp - K Desktop Planetarium
+ -------------------
+ begin : Sun 17 Jan 2016 21:35:49 CST
+ copyright : (c) 2016 by Akarsh Simha
+ email : akarsh at kde.org
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+
+/* Project Includes */
+#include "exporteyepieceview.h"
+#include "eyepiecefield.h"
+#include "skypoint.h"
+#include "kstarsdatetime.h"
+#include "dms.h"
+#include "kstarsdata.h"
+#include "Options.h"
+
+/* KDE Includes */
+
+/* Qt Includes */
+#include <QWidget>
+#include <QComboBox>
+#include <QPixmap>
+#include <QDialogButtonBox>
+#include <QPainter>
+#include <QFileDialog>
+
+ExportEyepieceView::ExportEyepieceView( const SkyPoint *_sp, const KStarsDateTime &dt, const QPixmap *renderImage, const QPixmap *renderChart,
+ QWidget *parent ) : QDialog( parent ), m_dt( dt ) {
+ m_sp = new SkyPoint( *_sp ); // Work on a copy.
+
+ Q_ASSERT( renderChart );
+ m_renderChart = new QPixmap( *renderChart );
+
+ if( renderImage )
+ m_renderImage = new QPixmap( *renderImage );
+ else
+ m_renderImage = 0;
+
+ setWindowTitle( i18n( "Export eyepiece view" ) );
+
+ QWidget *mainWidget = new QWidget( this );
+ QVBoxLayout *mainLayout = new QVBoxLayout;
+ mainLayout->addWidget(mainWidget);
+ setLayout(mainLayout);
+
+ QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::Cancel);
+ mainLayout->addWidget(buttonBox);
+ connect(buttonBox, SIGNAL(rejected()), this, SLOT(slotCloseDialog()));
+ connect(buttonBox, SIGNAL(accepted()), this, SLOT(slotSaveImage()));
+
+ QVBoxLayout *rows = new QVBoxLayout;
+ mainWidget->setLayout( rows );
+
+ QLabel *tickInfoLabel = new QLabel( i18n( "Overlay orientation vs. time ticks: " ), this );
+ m_tickConfigCombo = new QComboBox( this );
+ m_tickConfigCombo->addItem( i18n( "None" ) );
+ m_tickConfigCombo->addItem( i18n( "Towards Zenith" ) );
+ m_tickConfigCombo->addItem( i18n( "Dobsonian View" ) );
+
+ QHBoxLayout *optionsLayout = new QHBoxLayout;
+ optionsLayout->addWidget( tickInfoLabel );
+ optionsLayout->addWidget( m_tickConfigCombo );
+ optionsLayout->addStretch();
+ rows->addLayout( optionsLayout );
+
+ m_tickWarningLabel = new QLabel( this );
+ rows->addWidget( m_tickWarningLabel );
+
+ m_outputDisplay = new QLabel;
+ m_outputDisplay->setBackgroundRole( QPalette::Base );
+ m_outputDisplay->setScaledContents( false );
+ m_outputDisplay->setMinimumWidth( 400 );
+ m_outputDisplay->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Expanding );
+ rows->addWidget( m_outputDisplay );
+
+ connect( m_tickConfigCombo, SIGNAL( currentIndexChanged( int ) ), this, SLOT( slotOverlayTicks( int ) ) );
+ connect( m_tickConfigCombo, SIGNAL( activated( int ) ), this, SLOT( slotOverlayTicks( int ) ) );
+
+ render();
+ show();
+}
+
+ExportEyepieceView::~ExportEyepieceView() {
+ delete m_sp;
+ delete m_renderChart;
+ delete m_renderImage;
+}
+
+void ExportEyepieceView::slotOverlayTicks( int tickConfig ) {
+ m_tickConfig = tickConfig;
+ if( tickConfig == 0 )
+ m_tickWarningLabel->setText( QString() );
+ else if( tickConfig == 1 )
+ m_tickWarningLabel->setText( i18n( "Note: This overlay makes sense only if the view was generated in alt/az mode with a preset such as Refractor or Vanilla" ) );
+ else if( tickConfig == 2 )
+ m_tickWarningLabel->setText( i18n( "Note: This overlay makes sense only if the view was generated in alt/az mode with a preset such as Dobsonian" ) );
+ render();
+}
+
+void ExportEyepieceView::render() {
+ float baseWidth = m_renderChart->width();
+ float baseHeight = m_renderChart->height();
+
+ if( m_renderImage )
+ m_output = QImage( int(baseWidth * 2.25), int(baseHeight), QImage::Format_ARGB32 ); // 0.25 * baseWidth gap between the images
+ else
+ m_output = QImage( int(baseWidth), int(baseHeight), QImage::Format_ARGB32 );
+
+ m_output.fill( Qt::white );
+ QPainter op( &m_output );
+ op.drawPixmap( QPointF(0,0), *m_renderChart );
+ if( m_renderImage )
+ op.drawPixmap( QPointF(baseWidth * 1.25,0), *m_renderImage );
+
+ if( m_tickConfig != 0 && Options::useAltAz() ) { // FIXME: this is very skymap-state-heavy for my happiness --asimha
+ // we must draw ticks
+ QImage tickOverlay( baseWidth, baseHeight, QImage::Format_ARGB32 );
+ tickOverlay.fill( Qt::transparent );
+
+ QPainter p( &tickOverlay );
+ p.setPen( Qt::red ); // FIXME: Determine color depending on situation, or make it configurable
+ double rEnd = 0.85 * ( baseWidth / 2.);
+ double rStart = 0.8 * ( baseWidth / 2.);
+ QFont font;
+ font.setPixelSize( ( rEnd - rStart ) );
+ p.setFont( font );
+
+ GeoLocation *geo = KStarsData::Instance()->geo();
+ double alt0 = m_sp->alt().Degrees(); // altitude when hour = 0, i.e. at m_dt (see below).
+ dms northAngle0 = EyepieceField::findNorthAngle( m_sp, geo->lat() );
+
+ for( float hour = -3.5; hour <= 3.5; hour += 0.5 ) {
+ dms rotation; // rotation
+
+ // FIXME: Code duplication : code duplicated from EyepieceField. This should really be a member of SkyPoint or something.
+ SkyPoint sp = SkyPoint::timeTransformed( m_sp, m_dt, geo, hour );
+ double alt = sp.alt().Degrees();
+ dms northAngle = EyepieceField::findNorthAngle( &sp, geo->lat() );
+
+ rotation = ( northAngle - northAngle0 );
+ if( m_tickConfig == 2 ) {
+ // Dobsonian: add additional CW rotation by altitude, but compensate for the fact that we've already rotated by alt0
+ rotation = rotation - dms( ( alt - alt0 ) );
+ }
+ rotation = rotation.reduce();
+ p.save();
+ p.translate( baseWidth/2.0, baseHeight/2.0 );
+ p.rotate( -( rotation.Degrees() + 90.0 ) );
+ p.drawLine( QPointF( rStart, 0 ), QPointF( rEnd, 0 ) );
+ QTime ct = geo->UTtoLT( m_dt.addSecs( 3600.0 * hour ) ).time();
+ p.drawText( QPointF( rEnd + 0.01 * baseWidth, 0 ), QString().sprintf( "%02d:%02d", ct.hour(), ct.minute() ) );
+ p.restore();
+ }
+ p.end();
+ op.drawImage( QPointF(0,0), tickOverlay );
+ if( m_renderImage ) {
+ op.drawImage( QPointF(baseWidth * 1.25, 0), tickOverlay );
+ }
+ }
+ op.end();
+
+ m_outputDisplay->setPixmap( (QPixmap::fromImage( m_output )).scaled( m_outputDisplay->width(), m_outputDisplay->height(), Qt::KeepAspectRatio, Qt::SmoothTransformation ) );
+}
+
+void ExportEyepieceView::slotSaveImage() {
+ // does nothing at the moment. TODO: Implement.
+ QString fileName = QFileDialog::getSaveFileName( this, i18n("Save image as"), QString(), i18n( "Image files (*.png *.jpg *.xpm *.bmp *.gif)" ) );
+ if( !fileName.isEmpty() ) {
+ m_output.save( fileName );
+ slotCloseDialog();
+ }
+}
+
+void ExportEyepieceView::slotCloseDialog() {
+ hide();
+ deleteLater();
+}
diff --git a/kstars/tools/exporteyepieceview.h b/kstars/tools/exporteyepieceview.h
new file mode 100644
index 0000000..c544ca7
--- /dev/null
+++ b/kstars/tools/exporteyepieceview.h
@@ -0,0 +1,94 @@
+/***************************************************************************
+ exporteyepieceview.h - K Desktop Planetarium
+ -------------------
+ begin : Sun 17 Jan 2016 21:36:25 CST
+ copyright : (c) 2016 by Akarsh Simha
+ email : akarsh.simha at kdemail.net
+***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+
+
+#ifndef EXPORTEYEPIECEVIEW_H
+#define EXPORTEYEPIECEVIEW_H
+
+#include "kstarsdatetime.h"
+
+#include <QDialog>
+#include <QImage>
+
+class SkyPoint;
+class QLabel;
+class QComboBox;
+class QPixmap;
+
+/**
+ * @class ExportEyepieceView
+ * @short Dialog to export the eyepiece view as an image, with some annotations for field-use
+ * @author Akarsh Simha <akarsh at kde.org>
+ */
+
+class ExportEyepieceView : public QDialog {
+
+ Q_OBJECT;
+
+ public:
+
+ /**
+ * @short Constructor
+ * @note Class self-destructs (commits suicide). Invoke and forget.
+ */
+ ExportEyepieceView( const SkyPoint *_sp, const KStarsDateTime &dt, const QPixmap *renderImage, const QPixmap *renderChart, QWidget *parent = 0 );
+
+ /**
+ * @short Destructor
+ */
+ ~ExportEyepieceView();
+
+public slots:
+
+ /**
+ * @short Change the tick overlay scheme
+ */
+ void slotOverlayTicks( int overlayType );
+
+ /**
+ * @short Save the image (export), and then close the dialog by calling slotCloseDialog()
+ */
+ void slotSaveImage();
+
+ /**
+ * @short Closes the dialog, and sets up deleteLater() so that the dialog is destructed.
+ */
+ void slotCloseDialog();
+
+private slots:
+
+ /**
+ * @short render the output
+ */
+ void render();
+
+ private:
+
+ QLabel *m_outputDisplay;
+ QLabel *m_tickWarningLabel;
+ QComboBox *m_tickConfigCombo;
+
+ KStarsDateTime m_dt;
+ SkyPoint *m_sp;
+ QPixmap *m_renderImage;
+ QPixmap *m_renderChart;
+ QImage m_output;
+ int m_tickConfig;
+};
+
+#endif
diff --git a/kstars/tools/eyepiecefield.cpp b/kstars/tools/eyepiecefield.cpp
index e6fb06f..c527eff 100644
--- a/kstars/tools/eyepiecefield.cpp
+++ b/kstars/tools/eyepiecefield.cpp
@@ -18,6 +18,7 @@
/* Project Includes */
#include "eyepiecefield.h"
+#include "exporteyepieceview.h"
#include "fov.h"
#include "skypoint.h"
#include "skymap.h"
@@ -60,9 +61,11 @@ EyepieceField::EyepieceField( QWidget *parent ) : QDialog( parent ) {
mainLayout->addWidget(mainWidget);
setLayout(mainLayout);
- QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close);
+ QDialogButtonBox *buttonBox = new QDialogButtonBox( QDialogButtonBox::Close );
+ buttonBox->addButton( i18nc("Export image", "Export"), QDialogButtonBox::AcceptRole );
mainLayout->addWidget(buttonBox);
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+ connect(buttonBox, SIGNAL(accepted()), this, SLOT(slotExport()));
QVBoxLayout *rows = new QVBoxLayout;
mainWidget->setLayout( rows );
@@ -549,6 +552,11 @@ EyepieceField::~EyepieceField() {
delete m_skyImage;
}
+void EyepieceField::slotExport() {
+ bool overlay = m_overlay->isChecked() && m_skyImage;
+ ExportEyepieceView *eev = new ExportEyepieceView( m_sp, *m_dt, ((m_skyImage && !overlay) ? &m_renderImage : 0), &m_renderChart, this );
+}
+
dms EyepieceField::findNorthAngle( const SkyPoint *sp, const dms *lat ) {
Q_ASSERT( sp && lat );
// FIXME: This procedure does not account for precession and nutation. Need to figure out how to incorporate these effects.
diff --git a/kstars/tools/eyepiecefield.h b/kstars/tools/eyepiecefield.h
index 8f00229..20af314 100644
--- a/kstars/tools/eyepiecefield.h
+++ b/kstars/tools/eyepiecefield.h
@@ -148,6 +148,11 @@ class EyepieceField : public QDialog { // FIXME: Rename to EyepieceView
*/
void slotEnforcePreset( int index = -1 );
+ /**
+ * @short save image
+ */
+ void slotExport();
+
private slots:
/**
* @short downloads a DSS image
More information about the Kstars-devel
mailing list