152 lines
5.5 KiB
Python
152 lines
5.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Gera constellations.js com os signos zodiacais em coordenadas J2000.
|
|
|
|
Os traçados são da cultura ``modern`` do Stellarium. As coordenadas J2000
|
|
dos respectivos identificadores Hipparcos vêm do d3-celestial. Os dados são
|
|
compactados para uso offline pelo wallpaper.
|
|
"""
|
|
|
|
import json
|
|
import urllib.request
|
|
from pathlib import Path
|
|
|
|
|
|
STELLARIUM_URL = (
|
|
"https://raw.githubusercontent.com/Stellarium/stellarium/master/"
|
|
"skycultures/modern/index.json"
|
|
)
|
|
STELLARIUM_ST_URL = (
|
|
"https://raw.githubusercontent.com/Stellarium/stellarium/master/"
|
|
"skycultures/modern_st/index.json"
|
|
)
|
|
D3_BASE = "https://raw.githubusercontent.com/ofrohn/d3-celestial/master/data/"
|
|
OUT = Path(__file__).resolve().parent.parent / "plugin/contents/ui/constellations.js"
|
|
|
|
ZODIAC = {
|
|
"Ari": "Áries",
|
|
"Tau": "Touro",
|
|
"Gem": "Gêmeos",
|
|
"Cnc": "Câncer",
|
|
"Leo": "Leão",
|
|
"Vir": "Virgem",
|
|
"Lib": "Libra",
|
|
"Sco": "Escorpião",
|
|
"Sgr": "Sagitário",
|
|
"Cap": "Capricórnio",
|
|
"Aqr": "Aquário",
|
|
"Psc": "Peixes",
|
|
}
|
|
|
|
# Avaliados signo a signo. S&T costuma usar traçados mais ricos e próximos
|
|
# aos mapas populares, enquanto a arte continua vindo do conjunto Modern.
|
|
LINE_OVERRIDES = {"Lib": "modern_st"}
|
|
|
|
LICENSE = """Constellation lines: Stellarium Modern and Modern (S&T) sky cultures,
|
|
CC BY-SA 4.0.
|
|
https://github.com/Stellarium/stellarium/tree/master/skycultures/modern
|
|
https://github.com/Stellarium/stellarium/tree/master/skycultures/modern_st
|
|
|
|
Hipparcos J2000 coordinates: d3-celestial.
|
|
Copyright (c) 2015, Olaf Frohn
|
|
All rights reserved.
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions are met:
|
|
1. Redistributions of source code must retain the above copyright notice,
|
|
this list of conditions and the following disclaimer.
|
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
this list of conditions and the following disclaimer in the documentation
|
|
and/or other materials provided with the distribution.
|
|
3. Neither the name of the copyright holder nor contributors may be used to
|
|
endorse or promote products derived from this software without permission.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
AND ANY EXPRESS OR IMPLIED WARRANTIES ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DAMAGES ARISING IN ANY WAY
|
|
OUT OF THE USE OF THIS SOFTWARE.
|
|
"""
|
|
|
|
|
|
def fetch(url: str) -> dict:
|
|
req = urllib.request.Request(url, headers={"User-Agent": "skeledance-build/1.0"})
|
|
return json.loads(urllib.request.urlopen(req, timeout=30).read())
|
|
|
|
|
|
def rounded_point(point: list[float]) -> list[float]:
|
|
return [round(float(point[0]), 4), round(float(point[1]), 4)]
|
|
|
|
|
|
def main() -> None:
|
|
sky_culture = fetch(STELLARIUM_URL)
|
|
sky_culture_st = fetch(STELLARIUM_ST_URL)
|
|
st_constellations = {
|
|
item["id"].split()[-1]: item for item in sky_culture_st["constellations"]
|
|
}
|
|
star_data = fetch(D3_BASE + "stars.8.json")["features"]
|
|
name_data = fetch(D3_BASE + "constellations.json")["features"]
|
|
stars = {
|
|
int(feature["id"]): rounded_point(feature["geometry"]["coordinates"])
|
|
for feature in star_data
|
|
}
|
|
metadata = {
|
|
feature["id"]: {
|
|
"name": feature["properties"].get("name", feature["id"]),
|
|
"label": rounded_point(feature["geometry"]["coordinates"]),
|
|
}
|
|
for feature in name_data
|
|
}
|
|
|
|
merged: dict[str, dict] = {}
|
|
for constellation in sky_culture["constellations"]:
|
|
ident = constellation["id"].split()[-1]
|
|
if ident not in ZODIAC:
|
|
continue
|
|
line_source = (st_constellations[ident]
|
|
if LINE_OVERRIDES.get(ident) == "modern_st"
|
|
else constellation)
|
|
lines = []
|
|
for hip_line in line_source.get("lines", []):
|
|
missing = [hip for hip in hip_line if hip not in stars]
|
|
if missing:
|
|
raise RuntimeError(f"{ident}: HIP ausente no catálogo: {missing}")
|
|
lines.append([stars[hip] for hip in hip_line])
|
|
image = constellation.get("image")
|
|
art = None
|
|
if image:
|
|
anchors = []
|
|
for anchor in image["anchors"]:
|
|
hip = int(anchor["hip"])
|
|
if hip not in stars:
|
|
raise RuntimeError(f"{ident}: âncora HIP ausente: {hip}")
|
|
anchors.append({"pos": anchor["pos"], "sky": stars[hip]})
|
|
art = {
|
|
"file": "constellation-art/" + Path(image["file"]).name,
|
|
"size": image["size"],
|
|
"anchors": anchors,
|
|
}
|
|
merged[ident] = {
|
|
"id": ident,
|
|
"name": ZODIAC[ident],
|
|
"rank": 1 if ident in {"Ari", "Tau", "Gem", "Leo", "Vir", "Sco", "Sgr"} else 2,
|
|
"label": metadata.get(ident, {}).get("label"),
|
|
"lines": lines,
|
|
"art": art,
|
|
}
|
|
|
|
payload = json.dumps(
|
|
[merged[ident] for ident in ZODIAC],
|
|
ensure_ascii=False,
|
|
separators=(",", ":"),
|
|
)
|
|
OUT.write_text(
|
|
"/* Gerado por tools/build_constellations.py.\n"
|
|
" Stellarium Modern/S&T constellation lines, coordenadas Hipparcos J2000.\n\n"
|
|
+ "\n".join((" " + line) if line else "" for line in LICENSE.rstrip().splitlines())
|
|
+ " */\nconst CONSTELLATIONS=" + payload + ";\n",
|
|
encoding="utf-8",
|
|
)
|
|
print(f"{len(merged)} signos -> {OUT} ({OUT.stat().st_size / 1024:.0f} KB)")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|