Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
tiagohm committed Aug 21, 2024
2 parents 29f4e50 + 83aadd9 commit 92e0fd1
Show file tree
Hide file tree
Showing 21 changed files with 223 additions and 126 deletions.
2 changes: 1 addition & 1 deletion api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ dependencies {
implementation("org.springframework.boot:spring-boot-starter-undertow")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
kapt("org.springframework:spring-context-indexer:6.1.11")
kapt("org.springframework:spring-context-indexer:6.1.12")
testImplementation(project(":nebulosa-astrobin-api"))
testImplementation(project(":nebulosa-skycatalog-stellarium"))
testImplementation(project(":nebulosa-test"))
Expand Down
23 changes: 23 additions & 0 deletions api/src/main/kotlin/nebulosa/api/atlas/MoonPhase.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package nebulosa.api.atlas

import com.fasterxml.jackson.annotation.JsonAlias
import com.fasterxml.jackson.annotation.JsonProperty

data class MoonPhase(
@field:JsonProperty("phase") @JvmField val phase: Double = 0.0,
@field:JsonProperty("obscuration") @JvmField val obscuration: Double = 0.0,
@field:JsonProperty("age") @JvmField val age: Double = 0.0,
@field:JsonProperty("diameter") @JvmField val diameter: Double = 0.0,
@field:JsonProperty("distance") @JvmField val distance: Double = 0.0,
@field:JsonAlias("subsolar_lon") @JvmField val subSolarLon: Double = 0.0,
@field:JsonAlias("subsolar_lat") @JvmField val subSolarLat: Double = 0.0,
@field:JsonAlias("subearth_lon") @JvmField val subEarthLon: Double = 0.0,
@field:JsonAlias("subearth_lat") @JvmField val subEarthLat: Double = 0.0,
@field:JsonAlias("posangle") @JvmField val posAngle: Double = 0.0,
) {

companion object {

@JvmStatic val EMPTY = MoonPhase()
}
}
30 changes: 18 additions & 12 deletions api/src/main/kotlin/nebulosa/api/atlas/SkyAtlasController.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ class SkyAtlasController(
@GetMapping("sun/altitude-points")
fun altitudePointsOfSun(
@LocationParam location: Location,
@DateAndTimeParam dateTime: LocalDate,
@DateAndTimeParam date: LocalDate,
@RequestParam(required = false, defaultValue = "1") @Valid @Min(1) stepSize: Int,
@RequestParam(required = false, defaultValue = "false") fast: Boolean,
) = skyAtlasService.altitudePointsOfSun(location, dateTime, stepSize, fast)
) = skyAtlasService.altitudePointsOfSun(location, date, stepSize, fast)

@GetMapping("moon/position")
fun positionOfMoon(
Expand All @@ -53,10 +53,10 @@ class SkyAtlasController(
@GetMapping("moon/altitude-points")
fun altitudePointsOfMoon(
@LocationParam location: Location,
@DateAndTimeParam dateTime: LocalDate,
@DateAndTimeParam date: LocalDate,
@RequestParam(required = false, defaultValue = "1") @Valid @Min(1) stepSize: Int,
@RequestParam(required = false, defaultValue = "false") fast: Boolean,
) = skyAtlasService.altitudePointsOfMoon(location, dateTime, stepSize, fast)
) = skyAtlasService.altitudePointsOfMoon(location, date, stepSize, fast)

@GetMapping("planets/{code}/position")
fun positionOfPlanet(
Expand All @@ -70,10 +70,10 @@ class SkyAtlasController(
fun altitudePointsOfPlanet(
@PathVariable code: String,
@LocationParam location: Location,
@DateAndTimeParam dateTime: LocalDate,
@DateAndTimeParam date: LocalDate,
@RequestParam(required = false, defaultValue = "1") @Valid @Min(1) stepSize: Int,
@RequestParam(required = false, defaultValue = "false") fast: Boolean,
) = skyAtlasService.altitudePointsOfPlanet(location, code, dateTime, stepSize, fast)
) = skyAtlasService.altitudePointsOfPlanet(location, code, date, stepSize, fast)

@GetMapping("minor-planets")
fun searchMinorPlanet(@RequestParam @Valid @NotBlank text: String) = skyAtlasService.searchMinorPlanet(text)
Expand All @@ -96,9 +96,9 @@ class SkyAtlasController(
fun altitudePointsOfSkyObject(
@PathVariable id: Long,
@LocationParam location: Location,
@DateAndTimeParam dateTime: LocalDate,
@DateAndTimeParam date: LocalDate,
@RequestParam(required = false, defaultValue = "1") @Valid @Min(1) stepSize: Int,
) = skyAtlasService.altitudePointsOfSkyObject(location, id, dateTime, stepSize)
) = skyAtlasService.altitudePointsOfSkyObject(location, id, date, stepSize)

@GetMapping("sky-objects")
fun searchSkyObject(
Expand Down Expand Up @@ -130,9 +130,9 @@ class SkyAtlasController(
fun altitudePointsOfSatellite(
satellite: SatelliteEntity,
@LocationParam location: Location,
@DateAndTimeParam dateTime: LocalDate,
@DateAndTimeParam date: LocalDate,
@RequestParam(required = false, defaultValue = "1") @Valid @Min(1) stepSize: Int,
) = skyAtlasService.altitudePointsOfSatellite(location, satellite, dateTime, stepSize)
) = skyAtlasService.altitudePointsOfSatellite(location, satellite, date, stepSize)

@GetMapping("satellites")
fun searchSatellites(
Expand All @@ -144,7 +144,13 @@ class SkyAtlasController(
@GetMapping("twilight")
fun twilight(
@LocationParam location: Location,
@DateAndTimeParam dateTime: LocalDate,
@DateAndTimeParam date: LocalDate,
@RequestParam(required = false, defaultValue = "false") fast: Boolean,
) = skyAtlasService.twilight(location, dateTime, fast)
) = skyAtlasService.twilight(location, date, fast)

@GetMapping("moon/phase")
fun moonPhase(
@LocationParam location: Location,
@DateAndTimeParam dateTime: LocalDateTime,
) = skyAtlasService.moonPhase(location, dateTime)
}
38 changes: 31 additions & 7 deletions api/src/main/kotlin/nebulosa/api/atlas/SkyAtlasService.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package nebulosa.api.atlas

import com.fasterxml.jackson.databind.ObjectMapper
import jakarta.servlet.http.HttpServletResponse
import nebulosa.api.atlas.ephemeris.BodyEphemerisProvider
import nebulosa.api.atlas.ephemeris.HorizonsEphemerisProvider
Expand Down Expand Up @@ -33,8 +34,11 @@ import java.io.ByteArrayOutputStream
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.LocalTime
import java.time.format.DateTimeFormatter
import java.time.temporal.ChronoUnit
import java.util.concurrent.TimeUnit
import javax.imageio.ImageIO
import kotlin.math.abs
import kotlin.math.hypot

@Service
Expand All @@ -46,12 +50,15 @@ class SkyAtlasService(
private val satelliteRepository: SatelliteRepository,
private val simbadEntityRepository: SimbadEntityRepository,
private val httpClient: OkHttpClient,
private val objectMapper: ObjectMapper,
) {

private val positions = HashMap<GeographicCoordinate, GeographicPosition>()
private val cachedSimbadEntities = HashMap<Long, SimbadEntity>()
private val targetLocks = HashMap<Any, Any>()

@Volatile private var sunImage = ByteArray(0)
@Volatile private var moonPhase: Pair<LocalDateTime, MoonPhase>? = null

val objectTypes: Collection<SkyObjectType> by lazy { simbadEntityRepository.findAll().map { it.type }.toSortedSet() }

Expand Down Expand Up @@ -225,14 +232,38 @@ class SkyAtlasService(
sunImage = bytes.toByteArray()
}

fun moonPhase(location: GeographicCoordinate, dateTime: LocalDateTime): MoonPhase? {
val now = LocalDateTime.now(SystemClock)

if (moonPhase == null || abs(ChronoUnit.HOURS.between(moonPhase!!.first, now)) >= 1) {
val request = Request.Builder()
.url(MOON_PHASE_URL.format(dateTime.minusMinutes(location.offsetInMinutes().toLong()).format(MOON_PHASE_DATE_TIME_FORMAT)))
.build()

val body = try {
httpClient.newCall(request).execute()
.body?.byteStream()
?.use { objectMapper.readValue(it, MoonPhase::class.java) }
} catch (_: Throwable) {
null
}

moonPhase = now.withMinute(0).withSecond(0).withNano(0) to (body ?: return null)
}

return moonPhase?.second
}

companion object {

private const val SUN_IMAGE_URL = "https://sdo.gsfc.nasa.gov/assets/img/latest/latest_256_HMIIC.jpg"
private const val MOON_PHASE_URL = "https://svs.gsfc.nasa.gov/api/dialamoon/%s"

private const val SUN = "10"
private const val MOON = "301"

@JvmStatic private val FAST_MOON = VSOP87E.EARTH + ELPMPP02
@JvmStatic private val MOON_PHASE_DATE_TIME_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:00")

@JvmStatic
private fun GeographicCoordinate.geographicPosition() = when (this) {
Expand All @@ -252,13 +283,6 @@ class SkyAtlasService(
else -> offsetInSeconds() / 60
}

@JvmStatic
private fun Double.clampMagnitude(): Double {
return if (this in SkyObject.MAGNITUDE_RANGE) this
else if (this < SkyObject.MAGNITUDE_MIN) SkyObject.MAGNITUDE_MIN
else SkyObject.MAGNITUDE_MAX
}

@JvmStatic
private fun List<HorizonsElement>.withLocationAndDateTime(location: GeographicCoordinate, dateTime: LocalDateTime): HorizonsElement? {
val offsetInMinutes = location.offsetInMinutes().toLong()
Expand Down
2 changes: 1 addition & 1 deletion api/src/main/kotlin/nebulosa/api/image/ImageBucket.kt
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class ImageBucket : AutoCloseable {

synchronized(this) {
for ((path, image) in bucket) {
if (currentTime - image.openedAt >= IMAGES_MAX_TIME) {
if (image.image != null && currentTime - image.openedAt >= IMAGES_MAX_TIME) {
image.image = null
LOG.info("image at {} has been disposed", path)
}
Expand Down
10 changes: 0 additions & 10 deletions api/src/main/kotlin/nebulosa/api/system/GitHubLatestRelease.kt

This file was deleted.

13 changes: 0 additions & 13 deletions api/src/main/kotlin/nebulosa/api/system/SystemController.kt

This file was deleted.

35 changes: 0 additions & 35 deletions api/src/main/kotlin/nebulosa/api/system/SystemService.kt

This file was deleted.

9 changes: 8 additions & 1 deletion api/src/test/kotlin/SkyAtlasServiceTest.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import SatelliteEntityRepositoryTest.Companion.ISS_TLE
import SatelliteEntityRepositoryTest.Companion.save
import SimbadEntityRepositoryTest.Companion.save
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.module.kotlin.jsonMapper
import io.kotest.matchers.collections.shouldContainAll
import io.kotest.matchers.collections.shouldHaveAtLeastSize
import io.kotest.matchers.collections.shouldHaveSize
Expand Down Expand Up @@ -158,6 +160,11 @@ class SkyAtlasServiceTest {
@JvmStatic private val SATELLITE_BOX = BOX_STORE.boxFor<SatelliteEntity>()
@JvmStatic private val SIMBAD_BOX = BOX_STORE.boxFor<SimbadEntity>()

@JvmStatic private val OBJECT_MAPPER = jsonMapper {
disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
disable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
}

@JvmStatic private val SIMBAD_ENTITY_REPOSITORY = SimbadEntityRepository(SIMBAD_BOX).apply {
save("Sirius", SkyObjectType.STAR, Constellation.CMA, -1.45, "06 45 06".hours, "-16 43 33".deg)
save("75 Tucanae", SkyObjectType.GLOBULAR_CLUSTER, Constellation.TUC, 6.58, "01 03 12".hours, "-70 50 39".deg)
Expand All @@ -169,7 +176,7 @@ class SkyAtlasServiceTest {

@JvmStatic private val SERVICE = SkyAtlasService(
HORIZONS_EPHEMERIS_PROVIDER, BODY_EPHEMERIS_PROVIDER, SMALL_BODY_DATABASE_SERVICE,
SATELLITE_REPOSITORY, SIMBAD_ENTITY_REPOSITORY, HTTP_CLIENT
SATELLITE_REPOSITORY, SIMBAD_ENTITY_REPOSITORY, HTTP_CLIENT, OBJECT_MAPPER
)

@JvmStatic private val LOCATION = Location("-19.846616".deg, "-43.96872".deg, 852.0.m, -180)
Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ buildscript {
dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.10")
classpath("org.jetbrains.kotlin:kotlin-allopen:2.0.10")
classpath("io.objectbox:objectbox-gradle-plugin:4.0.1")
classpath("io.objectbox:objectbox-gradle-plugin:4.0.2")
}

repositories {
Expand Down
19 changes: 14 additions & 5 deletions desktop/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,15 @@ export class AppComponent implements OnDestroy {

if (!window.preference.resizable && window.preference.autoResizable !== false) {
this.resizeObserver = new ResizeObserver((entries) => {
const height = entries[0].target.clientHeight

if (height) {
void this.electronService.resizeWindow(height)
}
this.resizeWindowFromElement(entries[0].target)
})

this.resizeObserver.observe(hostElementRef.nativeElement)

setTimeout(() => {
const root = document.getElementsByTagName('neb-root')[0]
this.resizeWindowFromElement(root)
}, 1000)
} else {
this.resizeObserver = undefined
}
Expand All @@ -72,6 +73,14 @@ export class AppComponent implements OnDestroy {
this.resizeObserver?.disconnect()
}

private resizeWindowFromElement(element: Element) {
const height = element.clientHeight

if (height) {
void this.electronService.resizeWindow(height)
}
}

pin() {
this.pinned = !this.pinned
if (this.pinned) return this.electronService.pinWindow()
Expand Down
Loading

0 comments on commit 92e0fd1

Please sign in to comment.