140 lines
3.2 KiB
C++
140 lines
3.2 KiB
C++
#include "imageinfo.h"
|
|
#include <QSettings>
|
|
#include <QTime>
|
|
#include <QHeaderView>
|
|
#include <wcslib/wcshdr.h>
|
|
#include <wcslib/wcsfix.h>
|
|
|
|
static const QVector<QByteArray> noEditableKey = {"SIMPLE", "BITPIX", "NAXIS", "NAXIS1", "NAXIS2", "NAXIS3", "EXTEND", "BZERO", "BSCALE"};
|
|
|
|
bool FITSRecord::editable() const
|
|
{
|
|
return noEditableKey.count(key);
|
|
}
|
|
|
|
ImageInfo::ImageInfo(QWidget *parent) : QTreeWidget(parent)
|
|
{
|
|
setColumnCount(3);
|
|
setHeaderLabels({tr("Property"), tr("Value"), tr("Comment")});
|
|
setIndentation(5);
|
|
QSettings settings;
|
|
header()->restoreState(settings.value("imageinfo/headerstate").toByteArray());
|
|
}
|
|
|
|
ImageInfo::~ImageInfo()
|
|
{
|
|
QSettings settings;
|
|
settings.setValue("imageinfo/headerstate", header()->saveState());
|
|
}
|
|
|
|
void ImageInfo::setInfo(const ImageInfoData &info)
|
|
{
|
|
clear();
|
|
if(info.fitsHeader.size())
|
|
{
|
|
QTreeWidgetItem *fitsHeader = new QTreeWidgetItem({tr("FITS Header")});
|
|
for(const FITSRecord &record : info.fitsHeader)
|
|
{
|
|
new QTreeWidgetItem(fitsHeader, {record.key, record.value.toString(), record.comment});
|
|
}
|
|
addTopLevelItem(fitsHeader);
|
|
}
|
|
if(info.info.size())
|
|
{
|
|
QTreeWidgetItem *infoHeader = new QTreeWidgetItem({tr("Image info")});
|
|
for(auto &item : info.info)
|
|
{
|
|
new QTreeWidgetItem(infoHeader, {item.first, item.second});
|
|
}
|
|
addTopLevelItem(infoHeader);
|
|
}
|
|
expandAll();
|
|
}
|
|
|
|
void WCSData::freeWCS()
|
|
{
|
|
wcsvfree(&nwcs, &wcs);
|
|
nwcs = 0;
|
|
wcs = nullptr;
|
|
}
|
|
|
|
WCSData::WCSData(char *header, int nrec)
|
|
{
|
|
int stat[NWCSFIX];
|
|
int nreject = 0;
|
|
int status = wcspih(header, nrec, 1, 0, &nreject, &nwcs, &wcs);
|
|
if(status != 0)
|
|
{
|
|
freeWCS();
|
|
return;
|
|
}
|
|
status = wcsfix(0, 0, wcs, stat);
|
|
if(status != 0 || wcs->crpix[0] == 0)
|
|
freeWCS();
|
|
}
|
|
|
|
WCSData::~WCSData()
|
|
{
|
|
if(wcs)
|
|
freeWCS();
|
|
}
|
|
|
|
SkyPoint WCSData::pixelToWorld(QPointF pixel) const
|
|
{
|
|
if(wcs == nullptr)return SkyPoint();
|
|
double pixcrd[2] = {pixel.x(), pixel.y()};
|
|
double imgcrd[8] = {0};
|
|
double phi = 0;
|
|
double theta = 0;
|
|
double world[8] = {0};
|
|
int stat[NWCSFIX] = {0};
|
|
int status = wcsp2s(wcs, 1, 2, pixcrd, imgcrd, &phi, &theta, world, stat);
|
|
if(status == 0)
|
|
{
|
|
return SkyPoint(world[0], world[1]);
|
|
}
|
|
return SkyPoint();
|
|
}
|
|
|
|
QPointF WCSData::worldToPixel(SkyPoint point) const
|
|
{
|
|
return QPointF();
|
|
}
|
|
|
|
void WCSData::calculateBounds(double &minRa, double &maxRa, double &minDec, double &maxDec)
|
|
{
|
|
minRa = -1000;
|
|
maxRa = 1000;
|
|
minDec = -1000;
|
|
maxDec = 1000;
|
|
}
|
|
|
|
SkyPoint::SkyPoint() : ra(NAN), dec(NAN)
|
|
{
|
|
|
|
}
|
|
|
|
SkyPoint::SkyPoint(double ra, double dec) : ra(ra), dec(dec)
|
|
{
|
|
}
|
|
|
|
void SkyPoint::set(double ra, double dec)
|
|
{
|
|
this->ra = ra;
|
|
this->dec = dec;
|
|
}
|
|
|
|
QString SkyPoint::toString() const
|
|
{
|
|
if(std::isnan(ra) || std::isnan(dec))
|
|
return QString();
|
|
|
|
QTime t(0, 0);
|
|
t = t.addSecs(ra * 240);
|
|
|
|
double deg, min, sec;
|
|
min = std::modf(dec, °) * 60;
|
|
sec = std::modf(min, &min) * 60;
|
|
return QString("RA: %1 DEC: %2° %3' %4\"").arg(t.toString("HH'h' mm'm' ss's'")).arg(deg, 2, 'f', 0, '0').arg(min, 2, 'f', 0, '0').arg(sec, 2, 'f', 0, '0');
|
|
}
|