summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Lancaster <rlancaste@gmail.com>2016-10-21 08:26:13 (GMT)
committerJasem Mutlaq <mutlaqja@ikarustech.com>2016-10-21 08:26:13 (GMT)
commit816026d08b41b8c04cec5b27521aaab77b4df9ae (patch)
tree2c6b34b7f425b931a54d72bd4fd2b880988723e6
parentc5862ad311343ff0f56fc7742dc58c1011cf2749 (diff)
Add support to identifying objects within a WCS enabled image
-rw-r--r--kstars/fitsviewer/fitsdata.cpp153
-rw-r--r--kstars/fitsviewer/fitsdata.h30
-rw-r--r--kstars/fitsviewer/fitsview.cpp25
-rw-r--r--kstars/fitsviewer/fitsview.h2
4 files changed, 205 insertions, 5 deletions
diff --git a/kstars/fitsviewer/fitsdata.cpp b/kstars/fitsviewer/fitsdata.cpp
index 873d168..194142c 100644
--- a/kstars/fitsviewer/fitsdata.cpp
+++ b/kstars/fitsviewer/fitsdata.cpp
@@ -19,14 +19,18 @@
#include <config-kstars.h>
#include "fitsdata.h"
+#include "skymapcomposite.h"
+#include "kstarsdata.h"
#include <cmath>
#include <cstdlib>
#include <climits>
#include <QApplication>
+#include <QStringList>
#include <QLocale>
#include <QFile>
+#include <QTime>
#include <QProgressDialog>
#ifndef KSTARS_LITE
@@ -100,6 +104,9 @@ FITSData::~FITSData()
delete[] wcs_coord;
+ if (objList.count() > 0)
+ qDeleteAll(objList);
+
if (fptr)
{
fits_close_file(fptr, &status);
@@ -1754,8 +1761,7 @@ void FITSData::checkWCS()
if ((status = wcsp2s(wcs, 1, 2, &pixcrd[0], &imgcrd[0], &phi, &theta, &world[0], &stat[0])))
{
- fprintf(stderr, "wcsp2s ERROR %d: %s.\n", status,
- wcs_errmsg[status]);
+ fprintf(stderr, "wcsp2s ERROR %d: %s.\n", status, wcs_errmsg[status]);
}
else
{
@@ -1766,10 +1772,153 @@ void FITSData::checkWCS()
}
}
}
+ findObjectsInImage(wcs, &world[0], phi, theta, &imgcrd[0], &pixcrd[0], &stat[0]);
#endif
}
+void FITSData::findObjectsInImage(struct wcsprm *wcs, double world[], double phi, double theta, double imgcrd[], double pixcrd[], int stat[]){
+ int width=getWidth();
+ int height=getHeight();
+ int status=0;
+
+ char date[64];
+ KSNumbers *num = NULL;
+
+ if (fits_read_keyword(fptr, "DATE-OBS", date, NULL, &status) == 0)
+ {
+ QString tsString(date);
+ tsString = tsString.remove("'").trimmed();
+
+ QDateTime ts = QDateTime::fromString(tsString, Qt::ISODate);
+ /*QString dateTime=QString(date).remove(QChar('\''), Qt::CaseInsensitive);
+ QStringList dateTimeStringList=dateTime.split("T", QString::SkipEmptyParts );
+ if(dateTimeStringList.size()>1){
+ QTime t = QTime::fromString(dateTimeStringList[1],Qt::TextDate);
+ QDate d = QDate::fromString(dateTimeStringList[0],"yyyy-MM-dd");
+ num=new KSNumbers(KStarsDateTime(d,t).djd());*/
+ if (ts.isValid())
+ num = new KSNumbers(KStarsDateTime(ts).djd());
+ //}
+ }
+ if (num == NULL)
+ num=new KSNumbers(KStarsData::Instance()->ut().djd());//Set to current time if the above does not work.
+
+ int sampleSize=100;
+
+ SkyMapComposite *map=KStarsData::Instance()->skyComposite();
+
+ wcs_point * wcs_coord = getWCSCoord();
+ if (wcs_coord)
+ {
+ int size=width*height;
+
+ if(sampleSize>width)//Should also check if the wcs_coord is not big enough!
+ return;
+
+ double decSample=wcs_coord[sampleSize].dec-wcs_coord[0].dec;
+ double raSample=wcs_coord[sampleSize].ra-wcs_coord[0].ra;
+ double defaultSearchRadius=sqrt(decSample*decSample+raSample*raSample)*2;//Doubling it just to cast a wider net
+
+ objList.clear();
+
+ for(int i=0;i<(size);i+=sampleSize)//This makes the x go in increments of the sample size
+ {
+ if ((i>width) && (i % width < sampleSize))
+ {//This checks if it is just on the next row.
+ i+=(sampleSize)*width;//This makes it skip a few rows so the y goes in increments of the sample size.
+ i-=i % width;//This corrects for diagonal drift when the image width is not divisible by the sample size
+ }
+
+ if(i>size)
+ break;
+
+ double ra = wcs_coord[i].ra;
+ double dec = wcs_coord[i].dec;
+ double searchRadius=defaultSearchRadius;//Because searchRadius gets reset each time you run Object Nearest!
+
+ SkyPoint point;// = new SkyPoint();
+ point.setRA0(dms(ra));
+ point.setDec0(dms(dec));
+ point.updateCoordsNow(num);
+ SkyObject *object=(map->objectNearest(&point,searchRadius));
+
+ if(object)
+ {
+
+ bool objInList=false;
+ foreach(FITSSkyObject *listObject, objList)
+ {
+ if(listObject->skyObject()->getUID()==object->getUID())
+ objInList=true;
+ }
+
+ int type=object->type();
+ if(type==SkyObject::PLANET||type==SkyObject::ASTEROID||type==SkyObject::COMET||type==SkyObject::SUPERNOVA||type==SkyObject::MOON||type==SkyObject::SATELLITE){
+ //DO NOT DISPLAY, at least for now, becaus these things move and change.
+ }
+ else if(!objInList)
+ {
+ int x=(i % width);//If the coordinate transform doesn't work, we will use the position we found.
+ int y=(i / width);
+
+ world[0]=object->ra0().Degrees();
+ world[1]=object->dec0().Degrees();
+
+ if ((status = wcss2p(wcs, 1, 2, &world[0], &phi, &theta, &imgcrd[0], &pixcrd[0], &stat[0])))
+ {
+ fprintf(stderr, "wcsp2s ERROR %d: %s.\n", status, wcs_errmsg[status]);
+ }
+ else
+ {
+ x = pixcrd[0];//The X and Y are set to the found position if it does work.
+ y = pixcrd[1];
+ }
+
+ //objList.insert(objList.size(),new FITSSkyObject(object,x,y));
+ objList.append(new FITSSkyObject(object,x,y));
+ }
+ }
+ }
+
+ }
+
+ delete (num);
+
+}
+
+QList<FITSSkyObject *> FITSData::getSkyObjects(){
+ return objList;
+}
+
+
+FITSSkyObject::FITSSkyObject(SkyObject *object, int xPos, int yPos) : QObject()
+{
+ skyObjectStored=object;
+ xLoc=xPos;
+ yLoc=yPos;
+}
+
+SkyObject *FITSSkyObject::skyObject(){
+ return skyObjectStored;
+}
+
+int FITSSkyObject::x(){
+ return xLoc;
+}
+
+int FITSSkyObject::y(){
+ return yLoc;
+}
+
+void FITSSkyObject::setX(int xPos){
+ xLoc=xPos;
+}
+
+void FITSSkyObject::setY(int yPos){
+ yLoc=yPos;
+}
+
int FITSData::getFlipVCounter() const
{
return flipVCounter;
diff --git a/kstars/fitsviewer/fitsdata.h b/kstars/fitsviewer/fitsdata.h
index 986e2ad..750015e 100644
--- a/kstars/fitsviewer/fitsdata.h
+++ b/kstars/fitsviewer/fitsdata.h
@@ -20,6 +20,7 @@
#ifndef FITSDATA_H_
#define FITSDATA_H_
+#include "skyobject.h"
#include <QFrame>
#include <QImage>
#include <QPixmap>
@@ -28,6 +29,11 @@
#include <QPaintEvent>
#include <QScrollArea>
#include <QLabel>
+#include <QStringList>
+
+#ifdef HAVE_WCSLIB
+#include <wcs.h>
+#endif
#ifndef KSTARS_LITE
#include <kxmlguiwindow.h>
@@ -69,6 +75,24 @@ public:
float sum;
};
+class FITSSkyObject : public QObject{
+ Q_OBJECT
+public:
+ explicit FITSSkyObject(SkyObject *skyObject, int xPos, int yPos);
+ SkyObject *skyObject();
+ int x();
+ int y();
+ void setX(int xPos);
+ void setY(int yPos);
+
+private:
+ SkyObject *skyObjectStored;
+ int xLoc;
+ int yLoc;
+
+};
+
+
class FITSData
{
public:
@@ -179,6 +203,10 @@ public:
int getFlipVCounter() const;
void setFlipVCounter(int value);
+ void findObjectsInImage(struct wcsprm *wcs, double world[], double phi, double theta, double imgcrd[], double pixcrd[], int stat[]);
+ QList<FITSSkyObject *> getSkyObjects();
+ QList<FITSSkyObject*> objList;//Does this need to be public??
+
private:
bool rotFITS (int rotate, int mirror);
@@ -245,6 +273,8 @@ private:
uint16_t height;
} stats;
+
+
};
#endif
diff --git a/kstars/fitsviewer/fitsview.cpp b/kstars/fitsviewer/fitsview.cpp
index d167115..b0200df 100644
--- a/kstars/fitsviewer/fitsview.cpp
+++ b/kstars/fitsviewer/fitsview.cpp
@@ -204,6 +204,13 @@ void FITSLabel::mouseMoveEvent(QMouseEvent *e)
emit newStatus(QString("%1 , %2").arg( ra.toHMSString()).arg(dec.toDMSString()), FITS_WCS);
}
+
+ foreach(FITSSkyObject *listObject, image_data->objList){
+ if((abs(listObject->x()-x)<50)&&(abs(listObject->y()-y)<50)){
+ QToolTip::showText(e->globalPos(), listObject->skyObject()->name(), this);
+ break;
+ }
+ }
}
//setCursor(Qt::CrossCursor);
@@ -996,6 +1003,17 @@ bool FITSView::imageHasWCS(){
return hasWCS;
}
+void FITSView::drawObjectNames(QPainter *painter)
+{
+ painter->setPen( QPen( Qt::green) );
+ float scale=(currentZoom / ZOOM_DEFAULT);
+ foreach(FITSSkyObject *listObject, image_data->getSkyObjects())
+ {
+ if (listObject->skyObject()->name() != i18n("star"))
+ painter->drawText(listObject->x()*scale,listObject->y()*scale,listObject->skyObject()->name());
+ }
+}
+
/**
This method will paint EQ Gridlines in an overlay if there is WCS data present.
It determines the minimum and maximum RA and DEC, then it uses that information to
@@ -1005,6 +1023,8 @@ to draw gridlines at those specific RA and Dec values.
void FITSView::drawEQGrid(QPainter *painter){
+ drawObjectNames(painter);
+
if (image_data->hasWCS())
{
wcs_point * wcs_coord = image_data->getWCSCoord();
@@ -1028,7 +1048,6 @@ void FITSView::drawEQGrid(QPainter *painter){
}
painter->setPen( QPen( Qt::yellow) );
-
if (maxDec>80){
int minRAMinutes=(int)(minRA/15);//This will force the scale to whole hours of RA near the pole
int maxRAMinutes=(int)(maxRA/15);
@@ -1227,11 +1246,11 @@ int FITSView::findStars(StarAlgorithm algorithm)
break;
}
}
- /*else if (algorithm == ALGORITHM_GRADIENT)
+ else if (algorithm == ALGORITHM_GRADIENT)
{
QRect boundary(0,0, image_data->getWidth(), image_data->getHeight());
count = FITSData::findCannyStar(image_data, boundary);
- }*/
+ }
else
{
count = image_data->findStars();
diff --git a/kstars/fitsviewer/fitsview.h b/kstars/fitsviewer/fitsview.h
index 00185c3..90e45b3 100644
--- a/kstars/fitsviewer/fitsview.h
+++ b/kstars/fitsviewer/fitsview.h
@@ -126,8 +126,10 @@ public:
bool isPixelGridShown();
bool imageHasWCS();
+
void drawCrosshair(QPainter *);
void drawEQGrid(QPainter *);
+ void drawObjectNames(QPainter *painter);
void drawPixelGrid(QPainter *painter);
void updateFrame();