Kstars

flagcomponent.cpp
1 /*
2  SPDX-FileCopyrightText: 2009 Jerome SONRIER <[email protected]>
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(QRegExp("\\.[^.]*$"), QString()).replace(QRegExp("^flag"), QString()).replace('_', ' ');
45 
46  m_Names.append(fileName);
47  }
48 
49  loadFromFile();
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  QRegExp rxLabelColor("^#[a-fA-F0-9]{6}$");
122  if (rxLabelColor.exactMatch(flagEntry.at(5)))
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 
149 void 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 
175 void FlagComponent::remove(int index)
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 
196 void 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 
343 void FlagComponent::toJ2000(SkyPoint *p, QString epoch)
344 {
345  KStarsDateTime dt;
346  dt.setFromEpoch(epoch);
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 
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 append(const T &value)
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
long double djd() const
QString number(int n, int base)
QImage image(int index)
Get image.
void loadFromFile()
Load flags from flags.dat file.
Stores dms coordinates for a point in the sky. for converting between coordinate systems.
Definition: skypoint.h:44
void setDec0(dms d)
Sets Dec0, the catalog Declination.
Definition: skypoint.h:119
void remove(int index)
Remove a flag.
CachingDms * lst()
Definition: kstarsdata.h:224
KSUserDB * userdb()
Definition: kstarsdata.h:215
int size()
Return the numbers of flags.
QColor labelColor(int index)
Get label color.
QList< QImage > imageList()
Get images.
void setRA0(dms r)
Sets RA0, the catalog Right Ascension.
Definition: skypoint.h:94
void replace(int i, const T &value)
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 draw(SkyPainter *skyp) override
Draw the object on the SkyMap skyp a pointer to the SkyPainter to use.
void saveToFile()
Save flags to flags.dat file.
void removeAt(int i)
int size() const const
bool setFromEpoch(double e, EpochType type)
Set the Date/Time from an epoch value, represented as a double.
QStringList getNames()
Return image names.
QString i18n(const char *text, const TYPE &arg...)
void update(KSNumbers *num=nullptr) override
Update the sky position(s) of this component.
Store several time-dependent astronomical quantities.
Definition: ksnumbers.h:42
const Projector * projector() const
Get the current projector.
Definition: skymaplite.h:323
const CachingDms & dec() const
Definition: skypoint.h:269
const CachingDms * lat() const
Definition: geolocation.h:70
GeoLocation * geo()
Definition: kstarsdata.h:230
void add(const SkyPoint &flagPoint, QString epoch, QString image, QString label, QColor labelColor)
Add a flag.
const T & at(int i) const const
void setNameFilters(const QStringList &nameFilters)
virtual void updateCoordsNow(const KSNumbers *num)
updateCoordsNow Shortcut for updateCoords( const KSNumbers *num, false, nullptr, nullptr,...
Definition: skypoint.h:382
Draws things on the sky, without regard to backend.
Definition: skypainter.h:39
QString epoch(int index)
Get epoch.
bool exactMatch(const QString &str) const const
QString & replace(int position, int n, QChar after)
An angle, stored as degrees, but expressible in many ways.
Definition: dms.h:37
const CachingDms & ra() const
Definition: skypoint.h:263
QString absoluteFilePath(const QString &fileName) const const
void updateFlag(int index, const SkyPoint &flagPoint, QString epoch, QString image, QString label, QColor labelColor)
Update a flag.
FlagComponent(SkyComposite *)
Constructor.
QList< int > getFlagsNearPix(SkyPoint *point, int pixelRadius)
Get list of flag indexes near specified SkyPoint with radius specified in pixels.
bool selected() override
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.
Definition: ksuserdb.cpp:1347
bool GetAllFlags(QList< QStringList > &flagList)
Returns a QList populated with all stored flags Order: const QString &ra, const QString &dec,...
Definition: ksuserdb.cpp:1377
const double & Degrees() const
Definition: dms.h:141
QString label(int index)
Get label.
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
QString imageName(int index)
Get image name.
const QChar at(int position) const const
bool DeleteAllFlags()
Erases all the flags from the database.
Definition: ksuserdb.cpp:1322
void forceUpdate(bool now=false)
Recalculates the positions of objects in the sky, and then repaints the sky map.
Definition: skymap.cpp:1176
const Projector * projector() const
Get the current projector.
Definition: skymap.h:300
QStringList entryList(QDir::Filters filters, QDir::SortFlags sort) const const
virtual void drawFlags()=0
Draw flags.
SkyPoint catalogueCoord(long double jdf)
Computes the J2000.0 catalogue coordinates for this SkyPoint using the epoch removing aberration,...
Definition: skypoint.cpp:710
QPair< double, double > epochCoords(int index)
epochCoords return coordinates recorded in original epoch
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Tue Dec 5 2023 03:58:27 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.