starplot 0.14.0__py2.py3-none-any.whl → 0.15.1__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of starplot might be problematic. Click here for more details.
- starplot/__init__.py +3 -1
- starplot/base.py +149 -37
- starplot/cli.py +33 -0
- starplot/data/__init__.py +6 -24
- starplot/data/bigsky.py +58 -40
- starplot/data/constellation_lines.py +827 -0
- starplot/data/constellation_stars.py +1501 -0
- starplot/data/constellations.py +43 -32
- starplot/data/db.py +17 -0
- starplot/data/dsos.py +24 -141
- starplot/data/library/{stars.bigsky.mag11.parquet → bigsky.0.4.0.stars.mag11.parquet} +0 -0
- starplot/data/library/sky.db +0 -0
- starplot/data/stars.py +45 -24
- starplot/geod.py +0 -6
- starplot/geometry.py +105 -6
- starplot/horizon.py +118 -107
- starplot/map.py +45 -96
- starplot/mixins.py +75 -14
- starplot/models/__init__.py +1 -1
- starplot/models/base.py +10 -128
- starplot/models/constellation.py +55 -32
- starplot/models/dso.py +132 -67
- starplot/models/moon.py +57 -78
- starplot/models/planet.py +44 -69
- starplot/models/star.py +91 -60
- starplot/models/sun.py +32 -53
- starplot/optic.py +14 -17
- starplot/plotters/constellations.py +81 -78
- starplot/plotters/dsos.py +49 -68
- starplot/plotters/experimental.py +1 -1
- starplot/plotters/milkyway.py +18 -20
- starplot/plotters/stars.py +91 -116
- starplot/profile.py +16 -0
- starplot/settings.py +26 -0
- starplot/styles/__init__.py +2 -0
- starplot/styles/base.py +7 -17
- starplot/styles/ext/blue_gold.yml +135 -0
- starplot/styles/ext/blue_light.yml +5 -4
- starplot/styles/ext/blue_medium.yml +11 -7
- starplot/styles/extensions.py +1 -0
- starplot/warnings.py +5 -0
- {starplot-0.14.0.dist-info → starplot-0.15.1.dist-info}/METADATA +11 -11
- {starplot-0.14.0.dist-info → starplot-0.15.1.dist-info}/RECORD +46 -54
- starplot-0.15.1.dist-info/entry_points.txt +3 -0
- starplot/data/bayer.py +0 -3499
- starplot/data/flamsteed.py +0 -2682
- starplot/data/library/constellation_borders_inv.gpkg +0 -0
- starplot/data/library/constellation_lines_hips.json +0 -709
- starplot/data/library/constellation_lines_inv.gpkg +0 -0
- starplot/data/library/constellations.gpkg +0 -0
- starplot/data/library/constellations_hip.fab +0 -88
- starplot/data/library/milkyway.gpkg +0 -0
- starplot/data/library/milkyway_inv.gpkg +0 -0
- starplot/data/library/ongc.gpkg.zip +0 -0
- starplot/data/library/stars.hipparcos.parquet +0 -0
- starplot/data/messier.py +0 -111
- starplot/data/prep/__init__.py +0 -0
- starplot/data/prep/constellations.py +0 -108
- starplot/data/prep/dsos.py +0 -299
- starplot/data/prep/utils.py +0 -16
- starplot/models/geometry.py +0 -44
- {starplot-0.14.0.dist-info → starplot-0.15.1.dist-info}/LICENSE +0 -0
- {starplot-0.14.0.dist-info → starplot-0.15.1.dist-info}/WHEEL +0 -0
starplot/mixins.py
CHANGED
|
@@ -1,34 +1,95 @@
|
|
|
1
|
+
from functools import cache
|
|
2
|
+
|
|
1
3
|
from shapely import Polygon, MultiPolygon
|
|
2
4
|
|
|
3
5
|
|
|
4
6
|
class ExtentMaskMixin:
|
|
7
|
+
@cache
|
|
5
8
|
def _extent_mask(self):
|
|
6
9
|
"""
|
|
7
10
|
Returns shapely geometry objects of extent (RA = 0...360)
|
|
8
11
|
|
|
9
|
-
If the extent crosses equinox, then
|
|
12
|
+
If the extent crosses equinox, then a MultiPolygon will be returned
|
|
10
13
|
"""
|
|
11
|
-
if self.ra_max
|
|
14
|
+
if self.ra_max <= 360:
|
|
12
15
|
coords = [
|
|
13
|
-
[self.ra_min
|
|
14
|
-
[self.ra_max
|
|
15
|
-
[self.
|
|
16
|
-
[self.
|
|
16
|
+
[self.ra_min, self.dec_min],
|
|
17
|
+
[self.ra_max, self.dec_min],
|
|
18
|
+
[self.ra_max, self.dec_max],
|
|
19
|
+
[self.ra_min, self.dec_max],
|
|
20
|
+
[self.ra_min, self.dec_min],
|
|
17
21
|
]
|
|
18
22
|
return Polygon(coords)
|
|
19
23
|
|
|
20
24
|
else:
|
|
21
25
|
coords_1 = [
|
|
22
|
-
[self.ra_min
|
|
26
|
+
[self.ra_min, self.dec_min],
|
|
23
27
|
[360, self.dec_min],
|
|
24
|
-
[self.ra_min * 15, self.dec_max],
|
|
25
28
|
[360, self.dec_max],
|
|
29
|
+
[self.ra_min, self.dec_max],
|
|
30
|
+
[self.ra_min, self.dec_min],
|
|
26
31
|
]
|
|
27
32
|
coords_2 = [
|
|
28
33
|
[0, self.dec_min],
|
|
29
|
-
[(self.ra_max -
|
|
34
|
+
[(self.ra_max - 360), self.dec_min],
|
|
35
|
+
[(self.ra_max - 360), self.dec_max],
|
|
30
36
|
[0, self.dec_max],
|
|
31
|
-
[
|
|
37
|
+
[0, self.dec_min],
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
return MultiPolygon(
|
|
41
|
+
[
|
|
42
|
+
Polygon(coords_1),
|
|
43
|
+
Polygon(coords_2),
|
|
44
|
+
]
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
@cache
|
|
48
|
+
def _extent_mask_altaz(self):
|
|
49
|
+
"""
|
|
50
|
+
Returns shapely geometry objects of the alt/az extent
|
|
51
|
+
|
|
52
|
+
If the extent crosses North cardinal direction, then a MultiPolygon will be returned
|
|
53
|
+
"""
|
|
54
|
+
extent = list(self.ax.get_extent(crs=self._plate_carree))
|
|
55
|
+
alt_min, alt_max = extent[2], extent[3]
|
|
56
|
+
az_min, az_max = extent[0], extent[1]
|
|
57
|
+
|
|
58
|
+
if az_min < 0:
|
|
59
|
+
az_min += 360
|
|
60
|
+
if az_max < 0:
|
|
61
|
+
az_max += 360
|
|
62
|
+
|
|
63
|
+
if az_min >= az_max:
|
|
64
|
+
az_max += 360
|
|
65
|
+
|
|
66
|
+
self.az = (az_min, az_max)
|
|
67
|
+
self.alt = (alt_min, alt_max)
|
|
68
|
+
|
|
69
|
+
if az_max <= 360:
|
|
70
|
+
coords = [
|
|
71
|
+
[az_min, alt_min],
|
|
72
|
+
[az_max, alt_min],
|
|
73
|
+
[az_max, alt_max],
|
|
74
|
+
[az_min, alt_max],
|
|
75
|
+
[az_min, alt_min],
|
|
76
|
+
]
|
|
77
|
+
return Polygon(coords)
|
|
78
|
+
|
|
79
|
+
else:
|
|
80
|
+
coords_1 = [
|
|
81
|
+
[az_min, alt_min],
|
|
82
|
+
[360, alt_min],
|
|
83
|
+
[360, alt_max],
|
|
84
|
+
[az_min, alt_max],
|
|
85
|
+
[az_min, alt_min],
|
|
86
|
+
]
|
|
87
|
+
coords_2 = [
|
|
88
|
+
[0, alt_min],
|
|
89
|
+
[az_max - 360, alt_min],
|
|
90
|
+
[az_max - 360, alt_max],
|
|
91
|
+
[0, alt_max],
|
|
92
|
+
[0, alt_min],
|
|
32
93
|
]
|
|
33
94
|
|
|
34
95
|
return MultiPolygon(
|
|
@@ -43,7 +104,7 @@ class ExtentMaskMixin:
|
|
|
43
104
|
return all(
|
|
44
105
|
[
|
|
45
106
|
self.ra_min == 0,
|
|
46
|
-
self.ra_max ==
|
|
107
|
+
self.ra_max == 360,
|
|
47
108
|
self.dec_min == -90,
|
|
48
109
|
self.dec_max == 90,
|
|
49
110
|
]
|
|
@@ -71,14 +132,14 @@ class CreateMapMixin:
|
|
|
71
132
|
height_degrees=height_degrees,
|
|
72
133
|
width_degrees=width_degrees,
|
|
73
134
|
)
|
|
74
|
-
ra_min = ex[0][0]
|
|
75
|
-
ra_max = ex[2][0]
|
|
135
|
+
ra_min = ex[0][0]
|
|
136
|
+
ra_max = ex[2][0]
|
|
76
137
|
dec_min = ex[0][1]
|
|
77
138
|
dec_max = ex[2][1]
|
|
78
139
|
|
|
79
140
|
# handle wrapping
|
|
80
141
|
if ra_max < ra_min:
|
|
81
|
-
ra_max +=
|
|
142
|
+
ra_max += 360
|
|
82
143
|
|
|
83
144
|
p = MapPlot(
|
|
84
145
|
ra_min=ra_min,
|
starplot/models/__init__.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from .constellation import Constellation # noqa: F401,F403
|
|
2
|
-
from .dso import DSO # noqa: F401,F403
|
|
2
|
+
from .dso import DSO, DsoType # noqa: F401,F403
|
|
3
3
|
from .star import Star # noqa: F401,F403
|
|
4
4
|
from .planet import Planet # noqa: F401,F403
|
|
5
5
|
from .moon import Moon # noqa: F401,F403
|
starplot/models/base.py
CHANGED
|
@@ -1,114 +1,23 @@
|
|
|
1
|
+
from functools import cache
|
|
1
2
|
from typing import Optional
|
|
2
|
-
from abc import ABC, abstractmethod
|
|
3
3
|
|
|
4
4
|
from skyfield.api import position_of_radec, load_constellation_map
|
|
5
5
|
|
|
6
6
|
from starplot.mixins import CreateMapMixin, CreateOpticMixin
|
|
7
7
|
|
|
8
|
-
constellation_at = load_constellation_map()
|
|
9
8
|
|
|
9
|
+
@cache
|
|
10
|
+
def constellation_at():
|
|
11
|
+
return load_constellation_map()
|
|
10
12
|
|
|
11
|
-
class Expression:
|
|
12
|
-
def __init__(self, func=None) -> None:
|
|
13
|
-
self.func = func
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
return self.func(obj)
|
|
17
|
-
|
|
18
|
-
def __or__(self, other):
|
|
19
|
-
return Expression(func=lambda d: self.evaluate(d) or other.evaluate(d))
|
|
20
|
-
|
|
21
|
-
def __and__(self, other):
|
|
22
|
-
return Expression(func=lambda d: self.evaluate(d) and other.evaluate(d))
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class Term:
|
|
26
|
-
def _factory(self, func):
|
|
27
|
-
def exp(c):
|
|
28
|
-
value = getattr(c, self.attr)
|
|
29
|
-
|
|
30
|
-
if value is None:
|
|
31
|
-
return False
|
|
32
|
-
|
|
33
|
-
return func(value)
|
|
34
|
-
|
|
35
|
-
return Expression(func=exp)
|
|
36
|
-
|
|
37
|
-
def __init__(self, attr):
|
|
38
|
-
self.attr = attr
|
|
39
|
-
|
|
40
|
-
def __eq__(self, other):
|
|
41
|
-
return Expression(
|
|
42
|
-
func=lambda c: getattr(c, self.attr) == other
|
|
43
|
-
if other is not None
|
|
44
|
-
else getattr(c, self.attr) is None
|
|
45
|
-
)
|
|
46
|
-
|
|
47
|
-
def __ne__(self, other):
|
|
48
|
-
return Expression(
|
|
49
|
-
func=lambda c: getattr(c, self.attr) != other
|
|
50
|
-
if other is not None
|
|
51
|
-
else getattr(c, self.attr) is not None
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
def __lt__(self, other):
|
|
55
|
-
return self._factory(lambda value: value < other)
|
|
56
|
-
|
|
57
|
-
def __le__(self, other):
|
|
58
|
-
return self._factory(lambda value: value <= other)
|
|
59
|
-
|
|
60
|
-
def __gt__(self, other):
|
|
61
|
-
return self._factory(lambda value: value > other)
|
|
62
|
-
|
|
63
|
-
def __ge__(self, other):
|
|
64
|
-
return self._factory(lambda value: value >= other)
|
|
65
|
-
|
|
66
|
-
def is_in(self, other):
|
|
67
|
-
"""Returns `True` if the field's value is in `other`"""
|
|
68
|
-
return Expression(func=lambda c: getattr(c, self.attr) in other)
|
|
69
|
-
|
|
70
|
-
def is_not_in(self, other):
|
|
71
|
-
"""Returns `True` if the field's value is NOT in `other`"""
|
|
72
|
-
return Expression(func=lambda c: getattr(c, self.attr) not in other)
|
|
73
|
-
|
|
74
|
-
def is_null(self):
|
|
75
|
-
"""Returns `True` if the field value is `None`"""
|
|
76
|
-
return Expression(func=lambda c: getattr(c, self.attr) is None)
|
|
77
|
-
|
|
78
|
-
def is_not_null(self):
|
|
79
|
-
"""Returns `True` if the field value is NOT `None`"""
|
|
80
|
-
return Expression(func=lambda c: getattr(c, self.attr) is not None)
|
|
81
|
-
|
|
82
|
-
def intersects(self, other):
|
|
83
|
-
"""Returns `True` if the field's value intersects `other`. Only available for geometry-type fields."""
|
|
84
|
-
return Expression(func=lambda c: getattr(c, self.attr).intersects(other))
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
class Meta(type):
|
|
88
|
-
managers = {}
|
|
89
|
-
|
|
90
|
-
def __new__(cls, name, bases, attrs):
|
|
91
|
-
new_cls = super().__new__(cls, name, bases, attrs)
|
|
92
|
-
|
|
93
|
-
if "_manager" in attrs:
|
|
94
|
-
Meta.managers[new_cls] = attrs["_manager"]
|
|
95
|
-
|
|
96
|
-
return new_cls
|
|
97
|
-
|
|
98
|
-
def __getattribute__(cls, attr):
|
|
99
|
-
if attr in ["get", "find", "all"]:
|
|
100
|
-
return getattr(Meta.managers[cls], attr)
|
|
101
|
-
|
|
102
|
-
return Term(attr)
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
class SkyObject(CreateMapMixin, CreateOpticMixin, metaclass=Meta):
|
|
14
|
+
class SkyObject(CreateMapMixin, CreateOpticMixin):
|
|
106
15
|
"""
|
|
107
16
|
Basic sky object model.
|
|
108
17
|
"""
|
|
109
18
|
|
|
110
19
|
ra: float
|
|
111
|
-
"""Right Ascension, in
|
|
20
|
+
"""Right Ascension, in degrees (0...360)"""
|
|
112
21
|
|
|
113
22
|
dec: float
|
|
114
23
|
"""Declination, in degrees (-90...90)"""
|
|
@@ -118,16 +27,18 @@ class SkyObject(CreateMapMixin, CreateOpticMixin, metaclass=Meta):
|
|
|
118
27
|
constellation_id: Optional[str] = None
|
|
119
28
|
"""Identifier of the constellation that contains this object. The ID is the three-letter (all lowercase) abbreviation from the International Astronomical Union (IAU)."""
|
|
120
29
|
|
|
121
|
-
def __init__(self, ra: float, dec: float) -> None:
|
|
30
|
+
def __init__(self, ra: float, dec: float, constellation_id: str = None) -> None:
|
|
122
31
|
self.ra = ra
|
|
123
32
|
self.dec = dec
|
|
33
|
+
if constellation_id:
|
|
34
|
+
self._constellation_id = constellation_id
|
|
124
35
|
|
|
125
36
|
@property
|
|
126
37
|
def constellation_id(self):
|
|
127
38
|
"""Identifier of the constellation that contains this object. The ID is the three-letter (all lowercase) abbreviation from the International Astronomical Union (IAU)."""
|
|
128
39
|
if not self._constellation_id:
|
|
129
40
|
pos = position_of_radec(self.ra, self.dec)
|
|
130
|
-
self._constellation_id = constellation_at(pos).lower()
|
|
41
|
+
self._constellation_id = constellation_at()(pos).lower()
|
|
131
42
|
return self._constellation_id
|
|
132
43
|
|
|
133
44
|
def constellation(self):
|
|
@@ -135,32 +46,3 @@ class SkyObject(CreateMapMixin, CreateOpticMixin, metaclass=Meta):
|
|
|
135
46
|
from starplot.models import Constellation
|
|
136
47
|
|
|
137
48
|
return Constellation.get(iau_id=self.constellation_id)
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
class SkyObjectManager(ABC):
|
|
141
|
-
@abstractmethod
|
|
142
|
-
def all(cls, *args, **kwargs):
|
|
143
|
-
raise NotImplementedError
|
|
144
|
-
|
|
145
|
-
@classmethod
|
|
146
|
-
def find(cls, where, **kwargs):
|
|
147
|
-
all_objects = kwargs.pop("all_objects", None) or cls.all()
|
|
148
|
-
return [s for s in all_objects if all([e.evaluate(s) for e in where])]
|
|
149
|
-
|
|
150
|
-
@classmethod
|
|
151
|
-
def get(cls, **kwargs):
|
|
152
|
-
all_objects = kwargs.pop("all_objects", None) or cls.all()
|
|
153
|
-
matches = [
|
|
154
|
-
s
|
|
155
|
-
for s in all_objects
|
|
156
|
-
if all([getattr(s, kw) == value for kw, value in kwargs.items()])
|
|
157
|
-
]
|
|
158
|
-
|
|
159
|
-
if len(matches) == 1:
|
|
160
|
-
return matches[0]
|
|
161
|
-
elif len(matches) > 1:
|
|
162
|
-
raise ValueError(
|
|
163
|
-
"More than one match. Use find() instead or narrow your search."
|
|
164
|
-
)
|
|
165
|
-
else:
|
|
166
|
-
return None
|
starplot/models/constellation.py
CHANGED
|
@@ -1,16 +1,10 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
3
|
-
from starplot.models.base import SkyObject, SkyObjectManager
|
|
4
|
-
from starplot.models.geometry import to_24h
|
|
5
|
-
from starplot.data import constellations
|
|
1
|
+
from typing import Union, Iterator
|
|
6
2
|
|
|
3
|
+
from ibis import _
|
|
4
|
+
from shapely import Polygon, MultiPolygon
|
|
7
5
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
def all(cls):
|
|
11
|
-
all_constellations = constellations.load()
|
|
12
|
-
for constellation in all_constellations.itertuples():
|
|
13
|
-
yield from_tuple(constellation)
|
|
6
|
+
from starplot.models.base import SkyObject
|
|
7
|
+
from starplot.data import constellations
|
|
14
8
|
|
|
15
9
|
|
|
16
10
|
class Constellation(SkyObject):
|
|
@@ -18,16 +12,22 @@ class Constellation(SkyObject):
|
|
|
18
12
|
Constellation model.
|
|
19
13
|
"""
|
|
20
14
|
|
|
21
|
-
_manager = ConstellationManager
|
|
22
|
-
|
|
23
15
|
iau_id: str = None
|
|
24
|
-
"""
|
|
16
|
+
"""
|
|
17
|
+
International Astronomical Union (IAU) three-letter designation, all lowercase.
|
|
18
|
+
|
|
19
|
+
**Important**: Starplot treats Serpens as two separate constellations to make them easier to work with programatically.
|
|
20
|
+
Serpens Caput has the `iau_id` of `ser1` and Serpens Cauda is `ser2`
|
|
21
|
+
"""
|
|
25
22
|
|
|
26
23
|
name: str = None
|
|
27
24
|
"""Name"""
|
|
28
25
|
|
|
29
|
-
|
|
30
|
-
"""
|
|
26
|
+
star_hip_ids: list[int] = None
|
|
27
|
+
"""List of HIP ids for stars that are part of the _lines_ for this constellation."""
|
|
28
|
+
|
|
29
|
+
boundary: Union[Polygon, MultiPolygon] = None
|
|
30
|
+
"""Shapely Polygon of the constellation's boundary. Right ascension coordinates are in degrees (0...360)."""
|
|
31
31
|
|
|
32
32
|
def __init__(
|
|
33
33
|
self,
|
|
@@ -35,33 +35,59 @@ class Constellation(SkyObject):
|
|
|
35
35
|
dec: float,
|
|
36
36
|
iau_id: str,
|
|
37
37
|
name: str = None,
|
|
38
|
+
star_hip_ids: list[int] = None,
|
|
38
39
|
boundary: Polygon = None,
|
|
39
40
|
) -> None:
|
|
40
|
-
super().__init__(ra, dec)
|
|
41
|
+
super().__init__(ra, dec, constellation_id=iau_id.lower())
|
|
41
42
|
self.iau_id = iau_id.lower()
|
|
42
|
-
self._constellation_id = self.iau_id # override from super()
|
|
43
43
|
self.name = name
|
|
44
|
+
self.star_hip_ids = star_hip_ids
|
|
44
45
|
self.boundary = boundary
|
|
45
46
|
|
|
46
47
|
def __repr__(self) -> str:
|
|
47
48
|
return f"Constellation(iau_id={self.iau_id}, name={self.name}, ra={self.ra}, dec={self.dec})"
|
|
48
49
|
|
|
49
50
|
@classmethod
|
|
50
|
-
def
|
|
51
|
+
def all(cls) -> Iterator["Constellation"]:
|
|
52
|
+
df = constellations.load().to_pandas()
|
|
53
|
+
|
|
54
|
+
for c in df.itertuples():
|
|
55
|
+
yield from_tuple(c)
|
|
56
|
+
|
|
57
|
+
@classmethod
|
|
58
|
+
def get(cls, **kwargs) -> "Constellation":
|
|
51
59
|
"""
|
|
52
60
|
Get a Constellation, by matching its attributes.
|
|
53
61
|
|
|
54
|
-
Example:
|
|
62
|
+
Example:
|
|
63
|
+
|
|
64
|
+
hercules = Constellation.get(name="Hercules")
|
|
55
65
|
|
|
56
66
|
Args:
|
|
57
67
|
**kwargs: Attributes on the constellation you want to match
|
|
58
68
|
|
|
59
69
|
Raises: `ValueError` if more than one constellation is matched
|
|
60
70
|
"""
|
|
61
|
-
|
|
71
|
+
filters = []
|
|
72
|
+
|
|
73
|
+
for k, v in kwargs.items():
|
|
74
|
+
filters.append(getattr(_, k) == v)
|
|
75
|
+
|
|
76
|
+
df = constellations.load(filters=filters).to_pandas()
|
|
77
|
+
results = [from_tuple(c) for c in df.itertuples()]
|
|
78
|
+
|
|
79
|
+
if len(results) == 1:
|
|
80
|
+
return results[0]
|
|
81
|
+
|
|
82
|
+
if len(results) > 1:
|
|
83
|
+
raise ValueError(
|
|
84
|
+
"More than one match. Use find() instead or narrow your search."
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
return None
|
|
62
88
|
|
|
63
89
|
@classmethod
|
|
64
|
-
def find(where: list) -> list["Constellation"]:
|
|
90
|
+
def find(cls, where: list) -> list["Constellation"]:
|
|
65
91
|
"""
|
|
66
92
|
Find Constellations
|
|
67
93
|
|
|
@@ -72,7 +98,9 @@ class Constellation(SkyObject):
|
|
|
72
98
|
List of Constellations that match all `where` expressions
|
|
73
99
|
|
|
74
100
|
"""
|
|
75
|
-
|
|
101
|
+
df = constellations.load(filters=where).to_pandas()
|
|
102
|
+
|
|
103
|
+
return [from_tuple(c) for c in df.itertuples()]
|
|
76
104
|
|
|
77
105
|
def constellation(self):
|
|
78
106
|
"""Not applicable to Constellation model, raises `NotImplementedError`"""
|
|
@@ -80,16 +108,11 @@ class Constellation(SkyObject):
|
|
|
80
108
|
|
|
81
109
|
|
|
82
110
|
def from_tuple(c: tuple) -> Constellation:
|
|
83
|
-
geometry = c.geometry
|
|
84
|
-
if len(c.geometry.geoms) == 1:
|
|
85
|
-
geometry = c.geometry.geoms[0]
|
|
86
|
-
|
|
87
|
-
geometry = to_24h(geometry)
|
|
88
|
-
|
|
89
111
|
return Constellation(
|
|
90
|
-
ra=c.
|
|
91
|
-
dec=c.
|
|
112
|
+
ra=c.ra,
|
|
113
|
+
dec=c.dec,
|
|
92
114
|
iau_id=c.iau_id,
|
|
93
115
|
name=c.name,
|
|
94
|
-
|
|
116
|
+
star_hip_ids=c.star_hip_ids,
|
|
117
|
+
boundary=c.geometry,
|
|
95
118
|
)
|