[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