Kstars

flagcomponent.cpp
1/*
2 SPDX-FileCopyrightText: 2009 Jerome SONRIER <jsid@emor3j.fr.eu.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include "flagcomponent.h"
8
9#include "ksfilereader.h"
10#include "kstarsdata.h"
11#include "Options.h"
12#ifdef KSTARS_LITE
13#include "skymaplite.h"
14#else
15#include "skymap.h"
16#endif
17#include "skypainter.h"
18#include "auxiliary/kspaths.h"
19#include "projections/projector.h"
20#include "skyobjects/skypoint.h"
21
22#include <KLocalizedString>
23
24#include <QDir>
25#include <QtMath>
26#include <QStandardPaths>
27
29{
30 // Add the default flag images to available images list
31 m_Names.append(i18n("No icon"));
32 m_Images.append(QImage());
33 m_Names.append(i18n("Default"));
34 m_Images.append(QImage(KSPaths::locate(QStandardPaths::AppLocalDataLocation, "defaultflag.gif")));
35
36 QDir appDir(KSPaths::writableLocation(QStandardPaths::AppLocalDataLocation));
37 appDir.setNameFilters(QStringList() << "flag*");
38 // Add all other images found in user appdata directory
39 for (auto &item : appDir.entryList())
40 {
41 QString path = appDir.absoluteFilePath(item);
42 m_Images.append(QImage(path));
43
44 QString fileName = item.replace(QRegularExpression("\\.[^.]*$"), QString()).replace(QRegularExpression("^flag"), QString()).replace('_', ' ');
45
46 m_Names.append(fileName);
47 }
48
50}
51
53{
54 // Return if flags must not be draw
55 if (!selected())
56 return;
57
58 // Return if no images are available
59 if (m_Names.size() < 1)
60 return;
61
62 // Draw all flags
63 skyp->drawFlags();
64}
65
67{
68 return Options::showFlags();
69}
70
72{
73 bool imageFound = false;
74 QList<QStringList> flagList;
75 KStarsData::Instance()->userdb()->GetAllFlags(flagList);
76
77 for (auto &flagEntry : flagList)
78 {
79 // Read coordinates
80 dms r(flagEntry.at(0));
81 dms d(flagEntry.at(1));
82
83 m_EpochCoords.append(qMakePair(r.Degrees(), d.Degrees()));
84
85 std::shared_ptr<SkyPoint> flagPoint(new SkyPoint(r, d));
86
87 // Convert to JNow
88 toJ2000(flagPoint.get(), flagEntry.at(2));
89
90 flagPoint->updateCoordsNow(KStarsData::Instance()->updateNum());
91
92 pointList().append(std::move(flagPoint));
93
94 // Read epoch
95 m_Epoch.append(flagEntry.at(2));
96
97 // Read image name
98 QString str = flagEntry.at(3);
99 str = str.replace('_', ' ');
100 for (int i = 0; i < m_Names.size(); ++i)
101 {
102 if (str == m_Names.at(i))
103 {
104 m_FlagImages.append(i);
105 imageFound = true;
106 }
107 }
108
109 // If the image specified in db does not exist,
110 // use the default one
111 if (!imageFound)
112 m_FlagImages.append(0);
113
114 imageFound = false;
115
116 // If there is no label, use an empty string, red color and continue.
117 m_Labels.append(flagEntry.at(4));
118
119 // color label
120
121 QRegularExpression rxLabelColor("^#[a-fA-F0-9]{6}$");
122 if (rxLabelColor.match(flagEntry.at(5)).hasMatch())
123 {
124 m_LabelColors.append(QColor(flagEntry.at(5)));
125 }
126 else
127 {
128 m_LabelColors.append(QColor("red"));
129 }
130 }
131}
132
134{
135 /*
136 TODO: This is a really bad way of storing things. Adding one flag shouldn't
137 involve writing a new file/table every time. Needs fixing.
138 */
139 KStarsData::Instance()->userdb()->DeleteAllFlags();
140
141 for (int i = 0; i < size(); ++i)
142 {
143 KStarsData::Instance()->userdb()->AddFlag(QString::number(epochCoords(i).first),
144 QString::number(epochCoords(i).second), epoch(i),
145 imageName(i).replace(' ', '_'), label(i), labelColor(i).name());
146 }
147}
148
149void FlagComponent::add(const SkyPoint &flagPoint, QString epoch, QString image, QString label, QColor labelColor)
150{
151 //JM 2015-02-21: Insert original coords in list and convert skypint to JNow
152 // JM 2017-02-07: Discard above! We add RAW epoch coordinates to list.
153 // If not J2000, we convert to J2000
154 m_EpochCoords.append(qMakePair(flagPoint.ra().Degrees(), flagPoint.dec().Degrees()));
155
156 std::shared_ptr<SkyPoint> newFlagPoint(new SkyPoint(flagPoint.ra(), flagPoint.dec()));
157
158 toJ2000(newFlagPoint.get(), epoch);
159
160 newFlagPoint->updateCoordsNow(KStarsData::Instance()->updateNum());
161
162 pointList().append(std::move(newFlagPoint));
163 m_Epoch.append(epoch);
164
165 for (int i = 0; i < m_Names.size(); i++)
166 {
167 if (image == m_Names.at(i))
168 m_FlagImages.append(i);
169 }
170
171 m_Labels.append(label);
172 m_LabelColors.append(labelColor);
173}
174
176{
177 // check if flag of required index exists
178 if (index > pointList().size() - 1)
179 {
180 return;
181 }
182
183 pointList().removeAt(index);
184 m_EpochCoords.removeAt(index);
185 m_Epoch.removeAt(index);
186 m_FlagImages.removeAt(index);
187 m_Labels.removeAt(index);
188 m_LabelColors.removeAt(index);
189
190 // request SkyMap update
191#ifndef KSTARS_LITE
192 SkyMap::Instance()->forceUpdate();
193#endif
194}
195
196void FlagComponent::updateFlag(int index, const SkyPoint &flagPoint, QString epoch, QString image, QString label,
197 QColor labelColor)
198{
199 if (index < 0 || index > pointList().size() - 1)
200 return;
201
202 std::shared_ptr<SkyPoint> existingFlag = pointList().at(index);
203
204 existingFlag->setRA0(flagPoint.ra());
205 existingFlag->setDec0(flagPoint.dec());
206
207 // If epoch not J2000, to convert to J2000
208 toJ2000(existingFlag.get(), epoch);
209
210 existingFlag->updateCoordsNow(KStarsData::Instance()->updateNum());
211
212 m_EpochCoords.replace(index, qMakePair(flagPoint.ra().Degrees(), flagPoint.dec().Degrees()));
213
214 m_Epoch.replace(index, epoch);
215
216 for (int i = 0; i < m_Names.size(); i++)
217 {
218 if (image == m_Names.at(i))
219 m_FlagImages.replace(index, i);
220 }
221
222 m_Labels.replace(index, label);
223 m_LabelColors.replace(index, labelColor);
224}
225
227{
228 return m_Names;
229}
230
232{
233 return pointList().size();
234}
235
237{
238 if (index > m_Epoch.size() - 1)
239 {
240 return QString();
241 }
242
243 return m_Epoch.at(index);
244}
245
247{
248 if (index > m_Labels.size() - 1)
249 {
250 return QString();
251 }
252
253 return m_Labels.at(index);
254}
255
257{
258 if (index > m_LabelColors.size() - 1)
259 {
260 return QColor();
261 }
262
263 return m_LabelColors.at(index);
264}
265
267{
268 if (index > m_FlagImages.size() - 1)
269 {
270 return QImage();
271 }
272
273 if (m_FlagImages.at(index) > m_Images.size() - 1)
274 {
275 return QImage();
276 }
277
278 return m_Images.at(m_FlagImages.at(index));
279}
280
282{
283 if (index > m_FlagImages.size() - 1)
284 {
285 return QString();
286 }
287
288 if (m_FlagImages.at(index) > m_Names.size() - 1)
289 {
290 return QString();
291 }
292
293 return m_Names.at(m_FlagImages.at(index));
294}
295
297{
298 return m_Images;
299}
300
302{
303#ifdef KSTARS_LITE
304 const Projector *proj = SkyMapLite::Instance()->projector();
305#else
306 const Projector *proj = SkyMap::Instance()->projector();
307#endif
308 QPointF pos = proj->toScreen(point);
309 QList<int> retVal;
310 int ptr = 0;
311
312 for (auto &cp : pointList())
313 {
314 if (std::isnan(cp->ra().Degrees()) || std::isnan(cp->dec().Degrees()))
315 continue;
316 cp->EquatorialToHorizontal(KStarsData::Instance()->lst(), KStarsData::Instance()->geo()->lat());
317 QPointF pos2 = proj->toScreen(cp.get());
318 int dx = (pos2 - pos).x();
319 int dy = (pos2 - pos).y();
320
321 if (qSqrt(dx * dx + dy * dy) <= pixelRadius)
322 {
323 //point is inside pixelRadius circle
324 retVal.append(ptr);
325 }
326
327 ptr++;
328 }
329
330 return retVal;
331}
332
334{
335 if (index < 0 || index > m_Images.size() - 1)
336 {
337 return QImage();
338 }
339
340 return m_Images.at(index);
341}
342
343void FlagComponent::toJ2000(SkyPoint *p, QString epoch)
344{
347
348 if (dt.djd() == J2000)
349 return;
350
351 p->catalogueCoord(dt.djd());
352
353 // Store J2000 coords in RA0, DEC0
354 p->setRA0(p->ra());
355 p->setDec0(p->dec());
356}
357
358QPair<double, double> FlagComponent::epochCoords(int index)
359{
360 if (index > m_FlagImages.size() - 1)
361 {
362 QPair<double, double> coord = qMakePair(0, 0);
363 return coord;
364 }
365
366 return m_EpochCoords.at(index);
367}
368
370{
371 if (!selected())
372 return;
373 KStarsData *data = KStarsData::Instance();
374
375 for (auto &p : pointList())
376 {
377 if (num)
378 p->updateCoordsNow(num);
379
380 p->EquatorialToHorizontal(data->lst(), data->geo()->lat());
381 }
382}
void saveToFile()
Save flags to flags.dat file.
FlagComponent(SkyComposite *)
Constructor.
QColor labelColor(int index)
Get label color.
int size()
Return the numbers of flags.
void remove(int index)
Remove a flag.
QList< QImage > imageList()
Get images.
QString label(int index)
Get label.
void add(const SkyPoint &flagPoint, QString epoch, QString image, QString label, QColor labelColor)
Add a flag.
QString epoch(int index)
Get epoch.
void update(KSNumbers *num=nullptr) override
Update the sky position(s) of this component.
QString imageName(int index)
Get image name.
QStringList getNames()
Return image names.
void loadFromFile()
Load flags from flags.dat file.
bool selected() override
QPair< double, double > epochCoords(int index)
epochCoords return coordinates recorded in original epoch
void updateFlag(int index, const SkyPoint &flagPoint, QString epoch, QString image, QString label, QColor labelColor)
Update a flag.
QList< int > getFlagsNearPix(SkyPoint *point, int pixelRadius)
Get list of flag indexes near specified SkyPoint with radius specified in pixels.
void draw(SkyPainter *skyp) override
Draw the object on the SkyMap skyp a pointer to the SkyPainter to use.
QImage image(int index)
Get image.
const CachingDms * lat() const
Definition geolocation.h:70
There are several time-dependent values used in position calculations, that are not specific to an ob...
Definition ksnumbers.h:43
bool DeleteAllFlags()
Erases all the flags from the database.
bool AddFlag(const QString &ra, const QString &dec, const QString &epoch, const QString &image_name, const QString &label, const QString &labelColor)
Add a new Flag with given parameters.
bool GetAllFlags(QList< QStringList > &flagList)
Returns a QList populated with all stored flags Order: const QString &ra, const QString &dec,...
KStarsData is the backbone of KStars.
Definition kstarsdata.h:72
CachingDms * lst()
Definition kstarsdata.h:224
KSUserDB * userdb()
Definition kstarsdata.h:215
GeoLocation * geo()
Definition kstarsdata.h:230
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
bool setFromEpoch(double e, EpochType type)
Set the Date/Time from an epoch value, represented as a double.
long double djd() const
An abstract parent class, to be inherited by SkyComponents that store a QList of SkyPoints.
The Projector class is the primary class that serves as an interface to handle projections.
Definition projector.h:58
QPointF toScreen(const SkyPoint *o, bool oRefract=true, bool *onVisibleHemisphere=nullptr) const
This is exactly the same as toScreenVec but it returns a QPointF.
Definition projector.cpp:93
SkyComposite is a kind of container class for SkyComponent objects.
const Projector * projector() const
Get the current projector.
Definition skymaplite.h:323
const Projector * projector() const
Get the current projector.
Definition skymap.h:300
void forceUpdate(bool now=false)
Recalculates the positions of objects in the sky, and then repaints the sky map.
Definition skymap.cpp:1177
Draws things on the sky, without regard to backend.
Definition skypainter.h:40
virtual void drawFlags()=0
Draw flags.
The sky coordinates of a point in the sky.
Definition skypoint.h:45
const CachingDms & dec() const
Definition skypoint.h:269
virtual void updateCoordsNow(const KSNumbers *num)
updateCoordsNow Shortcut for updateCoords( const KSNumbers *num, false, nullptr, nullptr,...
Definition skypoint.h:391
const CachingDms & ra() const
Definition skypoint.h:263
void EquatorialToHorizontal(const CachingDms *LST, const CachingDms *lat)
Determine the (Altitude, Azimuth) coordinates of the SkyPoint from its (RA, Dec) coordinates,...
Definition skypoint.cpp:77
void setRA0(dms r)
Sets RA0, the catalog Right Ascension.
Definition skypoint.h:94
void setDec0(dms d)
Sets Dec0, the catalog Declination.
Definition skypoint.h:119
SkyPoint catalogueCoord(long double jdf)
Computes the J2000.0 catalogue coordinates for this SkyPoint using the epoch removing aberration,...
Definition skypoint.cpp:710
An angle, stored as degrees, but expressible in many ways.
Definition dms.h:38
const double & Degrees() const
Definition dms.h:141
QString i18n(const char *text, const TYPE &arg...)
QString absoluteFilePath(const QString &fileName) const const
QStringList entryList(Filters filters, SortFlags sort) const const
void setNameFilters(const QStringList &nameFilters)
void append(QList< T > &&value)
const_reference at(qsizetype i) const const
void removeAt(qsizetype i)
void replace(qsizetype i, parameter_type value)
qsizetype size() const const
QRegularExpressionMatch match(QStringView subjectView, qsizetype offset, MatchType matchType, MatchOptions matchOptions) const const
bool hasMatch() const const
const QChar at(qsizetype position) const const
QString number(double n, char format, int precision)
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Oct 11 2024 12:15:12 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.