Skip to content

Commit

Permalink
✨ Add support for region list in add_overlay method
Browse files Browse the repository at this point in the history
  • Loading branch information
Xen0Xys committed May 16, 2024
1 parent 616b699 commit 797dfbc
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 66 deletions.
61 changes: 40 additions & 21 deletions js/models/message_handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,28 +30,47 @@ export default class MessageHandler {
}

handleAddOverlay(msg) {
const infos = msg["infos"];
const options = convertOptionNamesToCamelCase(msg["options"] || {});
const overlay = A.graphicOverlay(options);
const regions = msg["regions_infos"];
const graphic_options = convertOptionNamesToCamelCase(
msg["graphic_options"] || {},
);
if (!graphic_options["color"]) graphic_options["color"] = "red";
const overlay = A.graphicOverlay(graphic_options);
this.aladin.addOverlay(overlay);
switch (msg["region_type"]) {
case "stcs":
overlay.addFootprints(A.footprintsFromSTCS(infos.stcs));
break;
case "circle":
overlay.add(A.circle(infos.ra, infos.dec, infos.radius));
break;
case "ellipse":
overlay.add(
A.ellipse(infos.ra, infos.dec, infos.a, infos.b, infos.theta),
);
break;
case "line":
overlay.add(A.line(infos.ra1, infos.dec1, infos.ra2, infos.dec2));
break;
case "polygon":
overlay.add(A.polygon(infos.vertices));
break;
for (const region of regions) {
const infos = region["infos"];
switch (region["region_type"]) {
case "stcs":
overlay.addFootprints(
A.footprintsFromSTCS(infos.stcs, region.options),
);
break;
case "circle":
overlay.add(
A.circle(infos.ra, infos.dec, infos.radius, region.options),
);
break;
case "ellipse":
overlay.add(
A.ellipse(infos.ra, infos.dec, infos.a, infos.b, infos.theta),
region.options,
);
break;
case "line":
overlay.add(
A.line(
infos.ra1,
infos.dec1,
infos.ra2,
infos.dec2,
region.options,
),
);
break;
case "polygon":
overlay.add(A.polygon(infos.vertices, region.options));
break;
}
}
}

Expand Down
81 changes: 44 additions & 37 deletions src/ipyaladin/aladin.py
Original file line number Diff line number Diff line change
Expand Up @@ -356,63 +356,70 @@ def add_table(self, table: Union[QTable, Table], **table_options: any) -> None:
def add_overlay(
self,
region: Union[
typing.List[
Union[
str,
CircleSkyRegion,
EllipseSkyRegion,
LineSkyRegion,
PolygonSkyRegion,
RectangleSkyRegion,
]
],
str,
CircleSkyRegion,
EllipseSkyRegion,
LineSkyRegion,
PolygonSkyRegion,
RectangleSkyRegion,
],
**overlay_options: any,
**graphic_options: any,
) -> None:
"""Add an overlay layer to the Aladin Lite widget.
Parameters
----------
region: str, CircleSkyRegion, EllipseSkyRegion, LineSkyRegion
The region to overlay. It can be a string, a CircleSkyRegion,
an EllipseSkyRegion, a LineSkyRegion or a RectangleSkyRegion.
overlay_options: keyword arguments
region: str, `~CircleSkyRegion`, `~EllipseSkyRegion`, `~LineSkyRegion`,
`~PolygonSkyRegion`, `~RectangleSkyRegion`
The region to add in Aladin Lite. It can be given
as a string or one of the supported regions
graphic_options: keyword arguments
The options for the graphic overlay. Use Region visual for region options.
"""
# Check if the regions library is installed and raise an error if not
if (
not isinstance(region, str) and CircleSkyRegion is None
): # Only need to check one of the imports
raise ValueError(
"A region can be given as an STC-S string or a regions "
"object. To read regions objects, you need to install the regions "
"library with 'pip install regions'."
)

if not isinstance(region, str) and not isinstance(region, Region):
raise ValueError(
"region must be a string or a regions object. See the documentation "
"for the supported region types."
)

from .region_converter import RegionInfos
if not isinstance(region, list):
region = [region]

regions_infos = []
for region_element in region:
# Check if the regions library is installed and raise an error if not
if (
not isinstance(region_element, str) and Region is None
): # Only need to check one of the imports
raise ValueError(
"A region can be given as an STC-S string or a regions "
"object. To read regions objects, you need to install the regions "
"library with 'pip install regions'."
)

if not isinstance(region_element, str) and not isinstance(
region_element, Region
):
raise ValueError(
"region must be a string or a regions object. See the "
"documentation for the supported region types."
)

# Visual mapping to Aladin Lite overlay options
if isinstance(region, Region):
visual = dict(region.visual)
if "linewidth" in visual:
visual["line_width"] = visual.pop("linewidth")
if "facecolor" in visual:
visual["fill_color"] = visual.pop("facecolor")
if "edgecolor" in visual:
visual["color"] = visual.pop("edgecolor")
overlay_options = {**overlay_options, **region.visual}
from .region_converter import RegionInfos

# Define behavior for each region type
region_infos = RegionInfos(region)
# Define behavior for each region type
regions_infos.append(RegionInfos(region_element).to_clean_dict())

self.send(
{
"event_name": "add_overlay",
"region_type": region_infos.region_type,
"infos": region_infos.infos,
"options": overlay_options,
"regions_infos": regions_infos,
"graphic_options": graphic_options,
}
)

Expand Down
52 changes: 44 additions & 8 deletions src/ipyaladin/region_converter.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
import math
from regions import (
RectangleSkyRegion,
PolygonSkyRegion,
Region,
CircleSkyRegion,
EllipseSkyRegion,
LineSkyRegion,
)

try:
from regions import (
RectangleSkyRegion,
PolygonSkyRegion,
Region,
CircleSkyRegion,
EllipseSkyRegion,
LineSkyRegion,
)
except ImportError:
RectangleSkyRegion = None
PolygonSkyRegion = None
Region = None
CircleSkyRegion = None
EllipseSkyRegion = None
LineSkyRegion = None
from astropy.coordinates import SkyCoord
from typing import Union

Expand Down Expand Up @@ -220,6 +229,8 @@ def from_region(self, region: Union[str, Region]) -> None:
raise ValueError(f"Unsupported region type: {type(region).__name__}")
region_parser = self._region_parsers[type(region).__name__]
region_parser(region)
if isinstance(region, Region):
self._parse_visuals(region)

def _from_stcs(self, stcs: str) -> None:
self.region_type = "stcs"
Expand Down Expand Up @@ -260,3 +271,28 @@ def _from_polygon_sky_region(self, region: PolygonSkyRegion) -> None:
def _from_rectangle_sky_region(self, region: RectangleSkyRegion) -> None:
# Rectangle is interpreted as a polygon in Aladin Lite
self._from_polygon_sky_region(rectangle_to_polygon_region(region))

def _parse_visuals(self, region: Region) -> None:
visual = dict(region.visual)
if "linewidth" in visual:
visual["line_width"] = visual.pop("linewidth")
if "facecolor" in visual:
visual["fill_color"] = visual.pop("facecolor")
if "edgecolor" in visual:
visual["color"] = visual.pop("edgecolor")
self.options = visual

def to_clean_dict(self) -> dict:
"""Return a clean dictionary representation of the region.
Returns
-------
dict
The dictionary representation of the region.
"""
return {
"region_type": self.region_type,
"infos": self.infos,
"options": self.options,
}

0 comments on commit 797dfbc

Please sign in to comment.