Include ngc db

This commit is contained in:
2025-05-29 17:39:13 +02:00
parent 6069ebbbac
commit f016500f12
9 changed files with 170 additions and 13 deletions
+55 -2
View File
@@ -16,10 +16,29 @@ bool Database::init(const QLatin1String &connectionName)
QDir dir(path); QDir dir(path);
database = QSqlDatabase::addDatabase("QSQLITE", connectionName); database = QSqlDatabase::addDatabase("QSQLITE", connectionName);
ngc = QSqlDatabase::addDatabase("QSQLITE", connectionName + "ngc");
if(!dir.mkpath(".")) if(!dir.mkpath("."))
return false; return false;
if(ngc.isValid())
{
QString ngcDb = dir.absoluteFilePath("ngc.db");
if(!QFile::exists(ngcDb))
QFile::copy(":/ngc.db", ngcDb);
ngc.setDatabaseName(ngcDb);
if(ngc.open())
{
m_getNgc = QSqlQuery(ngc);
m_getNgc.prepare("SELECT *,IIF(V_Mag IS NULL, B_Mag, V_Mag) AS mag FROM ngc WHERE RA_deg BETWEEN ? AND ? AND DEC_deg BETWEEN ? AND ?");
}
else
{
qDebug() << "Could not open NGC database";
}
}
if(database.isValid()) if(database.isValid())
{ {
database.setDatabaseName(dir.absoluteFilePath("database2.db")); database.setDatabaseName(dir.absoluteFilePath("database2.db"));
@@ -182,7 +201,6 @@ void Database::indexDir(const QDir &dir, QProgressDialog *progress)
QStringList scannedDirs; QStringList scannedDirs;
int count = countFiles(dir, scannedDirs); int count = countFiles(dir, scannedDirs);
progress->setMaximum(count); progress->setMaximum(count);
QSqlDatabase database = QSqlDatabase::database();
database.transaction(); database.transaction();
scannedDirs.clear(); scannedDirs.clear();
@@ -200,7 +218,6 @@ void Database::indexDir(const QDir &dir, QProgressDialog *progress)
void Database::reindex(QProgressDialog *progress) void Database::reindex(QProgressDialog *progress)
{ {
QVariantList deleteids; QVariantList deleteids;
QSqlDatabase database = QSqlDatabase::database();
database.transaction(); database.transaction();
QSqlQuery size("SELECT COUNT(*) FROM fits_files", database); QSqlQuery size("SELECT COUNT(*) FROM fits_files", database);
size.next(); size.next();
@@ -239,6 +256,42 @@ QStringList Database::getFitsKeywords()
return keywords; return keywords;
} }
QVector<SkyObject> Database::getObjects(double minRa, double maxRa, double minDec, double maxDec)
{
QVector<SkyObject> objects;
if(!ngc.isOpen())return objects;
m_getNgc.bindValue(0, minRa);
m_getNgc.bindValue(1, maxRa);
m_getNgc.bindValue(2, minDec);
m_getNgc.bindValue(3, maxDec);
if(m_getNgc.exec())
{
while(m_getNgc.next())
{
QString name;
QString m = m_getNgc.value("M").toString();
QString ic = m_getNgc.value("IC").toString();
if(!m.isEmpty())name = "M" + m + " ";
if(!ic.isEmpty())name += "IC" + ic + " ";
name += m_getNgc.value("Name").toString();
objects.append({
name,
m_getNgc.value("Common names").toString(),
{m_getNgc.value("RA_deg").toDouble(), m_getNgc.value("DEC_deg").toDouble()},
m_getNgc.value("MajAx").toDouble(),
m_getNgc.value("MinAx").toDouble(),
m_getNgc.value("PosAng").toDouble(),
m_getNgc.value("mag").toDouble(),
{0, 0},
});
}
}
return objects;
}
bool Database::indexDir2(const QDir &dir, QProgressDialog *progress, QStringList &scannedDirs) bool Database::indexDir2(const QDir &dir, QProgressDialog *progress, QStringList &scannedDirs)
{ {
if(scannedDirs.contains(dir.canonicalPath()))return true; if(scannedDirs.contains(dir.canonicalPath()))return true;
+5
View File
@@ -6,11 +6,13 @@
#include <QSqlQuery> #include <QSqlQuery>
#include <QDir> #include <QDir>
#include <QProgressDialog> #include <QProgressDialog>
#include "imageinfodata.h"
class Database : public QObject class Database : public QObject
{ {
Q_OBJECT Q_OBJECT
QSqlDatabase database; QSqlDatabase database;
QSqlDatabase ngc;
QSqlQuery m_markQuery; QSqlQuery m_markQuery;
QSqlQuery m_unmarkQuery; QSqlQuery m_unmarkQuery;
QSqlQuery m_isMarkedQuery; QSqlQuery m_isMarkedQuery;
@@ -22,6 +24,8 @@ class Database : public QObject
QSqlQuery m_headerKeywords; QSqlQuery m_headerKeywords;
QSqlQuery m_deleteFile; QSqlQuery m_deleteFile;
QSqlQuery m_getNgc;
int m_progress; int m_progress;
public: public:
explicit Database(QObject *parent = 0); explicit Database(QObject *parent = 0);
@@ -37,6 +41,7 @@ public:
void indexDir(const QDir &dir, QProgressDialog *progress); void indexDir(const QDir &dir, QProgressDialog *progress);
void reindex(QProgressDialog *progress); void reindex(QProgressDialog *progress);
QStringList getFitsKeywords(); QStringList getFitsKeywords();
QVector<SkyObject> getObjects(double minRa, double maxRa, double minDec, double maxDec);
protected: protected:
bool indexDir2(const QDir &dir, QProgressDialog *progress, QStringList &scannedDirs); bool indexDir2(const QDir &dir, QProgressDialog *progress, QStringList &scannedDirs);
bool indexFile(const QFileInfo &file); bool indexFile(const QFileInfo &file);
+46 -3
View File
@@ -4,6 +4,7 @@
#include <QRegularExpression> #include <QRegularExpression>
#include <wcslib/wcshdr.h> #include <wcslib/wcshdr.h>
#include <wcslib/wcsfix.h> #include <wcslib/wcsfix.h>
#include "database.h"
#include "libxisf.h" #include "libxisf.h"
static const QVector<QByteArray> noEditableKey = {"SIMPLE", "BITPIX", "NAXIS", "NAXIS1", "NAXIS2", "NAXIS3", "EXTEND", "BZERO", "BSCALE"}; static const QVector<QByteArray> noEditableKey = {"SIMPLE", "BITPIX", "NAXIS", "NAXIS1", "NAXIS2", "NAXIS3", "EXTEND", "BZERO", "BSCALE"};
@@ -153,9 +154,9 @@ bool WCSDataT::worldToPixel(const SkyPoint &point, QPointF &pixel) const
return false; return false;
} }
void WCSDataT::calculateBounds(double &minRa, double &maxRa, double &minDec, double &maxDec, double &crVal1, double &crVal2) const bool WCSDataT::calculateBounds(double &minRa, double &maxRa, double &minDec, double &maxDec, double &crVal1, double &crVal2) const
{ {
if(wcs == nullptr)return; if(wcs == nullptr)return false;
minRa = 1000; minRa = 1000;
maxRa = -1000; maxRa = -1000;
@@ -208,6 +209,7 @@ void WCSDataT::calculateBounds(double &minRa, double &maxRa, double &minDec, dou
if(s.contains(scp)) if(s.contains(scp))
minDec = -90; minDec = -90;
} }
return true;
} }
double hav(double x) double hav(double x)
@@ -327,6 +329,14 @@ QString SkyPoint::toDMS(double deg)
return QString("%1˚ %2' %3\"").arg((int)d * sign, 2, 10, QChar('0')).arg((int)m, 2, 10, QChar('0')).arg((int)s, 2, 10, QChar('0')); return QString("%1˚ %2' %3\"").arg((int)d * sign, 2, 10, QChar('0')).arg((int)m, 2, 10, QChar('0')).arg((int)s, 2, 10, QChar('0'));
} }
SkyPoint SkyPoint::operator+(const SkyPoint &p)
{
SkyPoint ret;
ret.ra = ra + p.ra;
ret.dec = dec + p.dec;
return ret;
}
SkyPointScale ImageInfoData::getCenterRaDec() const SkyPointScale ImageInfoData::getCenterRaDec() const
{ {
SkyPointScale ret; SkyPointScale ret;
@@ -416,7 +426,18 @@ SkyPointScale ImageInfoData::getCenterRaDec() const
return ret; return ret;
} }
SkyGrid WCSDataT::prepareGrid(uint32_t w, uint32_t h) SkyPoint greatCircle(SkyPoint &p, double dist, double azm)
{
dist = dist * M_PI / 180;
azm = azm * M_PI / 180;
double dec0 = p.DEC() * M_PI / 180;
double ra0 = p.RA() * M_PI / 180;
double dec1 = std::asin(std::sin(dec0) * std::cos(dist) + std::cos(dec0) * std::sin(dist) * std::cos(azm));
double ra1 = ra0 + std::atan2(std::sin(azm) * std::sin(dist) * std::cos(dec0), std::cos(dist) - std::sin(dec0) * std::sin(dec1));
return SkyPoint(ra1 * 180 / M_PI, dec1 * 180 / M_PI);
}
SkyGrid WCSDataT::prepareGrid(uint32_t w, uint32_t h, Database *database)
{ {
SkyGrid skyGrid; SkyGrid skyGrid;
if(!wcs)return skyGrid; if(!wcs)return skyGrid;
@@ -424,6 +445,27 @@ SkyGrid WCSDataT::prepareGrid(uint32_t w, uint32_t h)
double minRa, maxRa, minDec, maxDec, crVal1, crVal2; double minRa, maxRa, minDec, maxDec, crVal1, crVal2;
calculateBounds(minRa, maxRa, minDec, maxDec, crVal1, crVal2); calculateBounds(minRa, maxRa, minDec, maxDec, crVal1, crVal2);
QPointF a,b;
worldToPixel(SkyPoint(crVal1, crVal2), a);
worldToPixel(SkyPoint(crVal1 + 0.01, crVal2), b);
skyGrid.rot_ang = std::atan2(b.y() - a.y(), b.x() - a.x()) / M_PI * -180.0;
if(database)
{
skyGrid.objects = database->getObjects(minRa, maxRa, minDec, maxDec);
for(auto &object : skyGrid.objects)
{
QPointF p;
if(worldToPixel(object.skyPoint, p))
object.pixel = p;
QPointF majax;
worldToPixel(greatCircle(object.skyPoint, (object.min_ax + object.maj_ax) / 120.0, object.pos_ang), majax);
majax -= p;
object.maj_ax = std::sqrt(QPointF::dotProduct(majax, majax));
}
}
double raStep = 15; double raStep = 15;
double decStep = 15; double decStep = 15;
double raRange = maxRa - minRa; double raRange = maxRa - minRa;
@@ -526,4 +568,5 @@ void SkyGrid::clear()
empty = true; empty = true;
grid.clear(); grid.clear();
text.clear(); text.clear();
objects.clear();
} }
+19 -2
View File
@@ -12,6 +12,8 @@
namespace LibXISF { struct FITSKeyword; struct Property; } namespace LibXISF { struct FITSKeyword; struct Property; }
class Database;
struct FITSRecord struct FITSRecord
{ {
QByteArray key; QByteArray key;
@@ -43,6 +45,7 @@ public:
static double fromDMS(const QString &dms); static double fromDMS(const QString &dms);
static QString toHMS(double decHour); static QString toHMS(double decHour);
static QString toDMS(double deg); static QString toDMS(double deg);
SkyPoint operator+(const SkyPoint &p);
}; };
struct SkyPointScale struct SkyPointScale
@@ -54,11 +57,25 @@ struct SkyPointScale
double scaleHigh = 10000.0; double scaleHigh = 10000.0;
}; };
struct SkyObject
{
QString name;
QString name2;
SkyPoint skyPoint;
double maj_ax;
double min_ax;
double pos_ang;
double vmag;
QPointF pixel;
};
struct SkyGrid struct SkyGrid
{ {
bool empty = true; bool empty = true;
QPainterPath grid; QPainterPath grid;
QVector<QPair<QPointF, QString>> text; QVector<QPair<QPointF, QString>> text;
QVector<SkyObject> objects;
double rot_ang = 0;
void clear(); void clear();
}; };
@@ -76,10 +93,10 @@ public:
~WCSDataT(); ~WCSDataT();
bool pixelToWorld(const QPointF &pixel, SkyPoint &point) const; bool pixelToWorld(const QPointF &pixel, SkyPoint &point) const;
bool worldToPixel(const SkyPoint &point, QPointF &pixel) const; bool worldToPixel(const SkyPoint &point, QPointF &pixel) const;
void calculateBounds(double &minRa, double &maxRa, double &minDec, double &maxDec, double &crVal1, double &crVal2) const; bool calculateBounds(double &minRa, double &maxRa, double &minDec, double &maxDec, double &crVal1, double &crVal2) const;
bool valid() const { return wcs; }; bool valid() const { return wcs; };
SkyPointScale getRaDecScale() const; SkyPointScale getRaDecScale() const;
SkyGrid prepareGrid(uint32_t w, uint32_t h); SkyGrid prepareGrid(uint32_t w, uint32_t h, Database *database);
}; };
struct ImageInfoData struct ImageInfoData
+23 -8
View File
@@ -182,8 +182,8 @@ void ImageWidgetGL::setWCS(std::shared_ptr<WCSDataT> wcs)
m_wcs = wcs; m_wcs = wcs;
m_grid.clear(); m_grid.clear();
if(m_drawGrid) if(m_drawGrid && m_wcs)
m_grid = m_wcs->prepareGrid(m_imgWidth, m_imgHeight); m_grid = m_wcs->prepareGrid(m_imgWidth, m_imgHeight, m_database);
} }
void ImageWidgetGL::zoom(int zoom, const QPointF &mousePos) void ImageWidgetGL::zoom(int zoom, const QPointF &mousePos)
@@ -502,8 +502,8 @@ void swPaint(std::shared_ptr<RawImage> &rawImage, float dx, float dy, float scal
void ImageWidgetGL::drawGrid(bool enable) void ImageWidgetGL::drawGrid(bool enable)
{ {
if(m_grid.empty) if(m_grid.empty && m_wcs)
m_grid = m_wcs->prepareGrid(m_imgWidth, m_imgHeight); m_grid = m_wcs->prepareGrid(m_imgWidth, m_imgHeight, m_database);
if(enable != m_drawGrid) if(enable != m_drawGrid)
{ {
@@ -644,13 +644,28 @@ void ImageWidgetGL::paintGL()
painter.setClipRect(0, 0, m_imgWidth, m_imgHeight); painter.setClipRect(0, 0, m_imgWidth, m_imgHeight);
painter.drawPath(m_grid.grid); painter.drawPath(m_grid.grid);
painter.setPen(Qt::yellow); painter.setPen(Qt::yellow);
painter.setFont(QFont({"Arial", "Sans"}, 12 / m_scale)); QFont font({"Arial", "serif-sans"});
font.setPointSizeF(12 / m_scale);
painter.setFont(font);
for(auto &text : m_grid.text) for(auto &text : m_grid.text)
painter.drawText(QRectF(text.first, QSizeF(4000, 4000)), text.second); painter.drawText(QRectF(text.first, QSizeF(4000, 4000)), text.second);
}
}
}
painter.setPen(QPen(Qt::green, 1.0 / m_scale));
QFontMetricsF fontMetric = QFontMetricsF(font);
for(auto &object : m_grid.objects)
{
QRectF rect = fontMetric.boundingRect(object.name);
rect.moveCenter(object.pixel);
painter.setTransform(tran);
painter.drawText(rect, Qt::TextDontClip, object.name);
painter.translate(object.pixel);
painter.rotate(object.pos_ang);
painter.drawEllipse(QPointF(0, 0), object.maj_ax, object.maj_ax);
}
}
}
}
} }
void ImageWidgetGL::resizeGL(int w, int h) void ImageWidgetGL::resizeGL(int w, int h)
BIN
View File
Binary file not shown.
+1
View File
@@ -19,6 +19,7 @@
<file>../translations/tenmon_pt_BR.qm</file> <file>../translations/tenmon_pt_BR.qm</file>
<file alias="help">../about/help_en</file> <file alias="help">../about/help_en</file>
<file>colormap.png</file> <file>colormap.png</file>
<file>ngc.db</file>
</qresource> </qresource>
<qresource prefix="/" lang="en"> <qresource prefix="/" lang="en">
<file alias="help">../about/help_en</file> <file alias="help">../about/help_en</file>
+22
View File
@@ -92,6 +92,28 @@ bool ScriptEngine::isMarked(const File *file)
return ret; return ret;
} }
QJSValue ScriptEngine::getObjects(double ra, double dec, double distance)
{
QVector<SkyObject> objects;
QMetaObject::invokeMethod(_database, [this, ra, dec, distance](){
return _database->getObjects(ra - distance, ra + distance, dec - distance, dec + distance); }, Qt::BlockingQueuedConnection, &objects);
QJSValue ret = newArray(objects.size());
qint32 i = 0;
for(auto &object : objects)
{
QJSValue jsObj = newObject();
jsObj.setProperty("name", object.name);
jsObj.setProperty("name2", object.name2);
jsObj.setProperty("ra", object.skyPoint.RA());
jsObj.setProperty("dec", object.skyPoint.DEC());
jsObj.setProperty("vmag", object.vmag);
ret.setProperty(i++, jsObj);
}
return ret;
}
void ScriptEngine::setMaxThread(int maxthread) void ScriptEngine::setMaxThread(int maxthread)
{ {
int newval = std::max(std::min(QThread::idealThreadCount(), maxthread), 1); int newval = std::max(std::min(QThread::idealThreadCount(), maxthread), 1);
+1
View File
@@ -41,6 +41,7 @@ public:
Q_INVOKABLE void mark(File *file); Q_INVOKABLE void mark(File *file);
Q_INVOKABLE void unmark(File *file); Q_INVOKABLE void unmark(File *file);
Q_INVOKABLE bool isMarked(const File *file); Q_INVOKABLE bool isMarked(const File *file);
Q_INVOKABLE QJSValue getObjects(double ra, double dec, double distance);
Q_INVOKABLE void setMaxThread(int maxthread); Q_INVOKABLE void setMaxThread(int maxthread);
Q_INVOKABLE void sync(); Q_INVOKABLE void sync();
Q_INVOKABLE QJSValue getString(const QString &label = QString(), const QString &text = QString()) const; Q_INVOKABLE QJSValue getString(const QString &label = QString(), const QString &text = QString()) const;