From 7dfa1163e98989868fa8a8776a2b91319ee13415 Mon Sep 17 00:00:00 2001 From: emelianov Date: Thu, 28 May 2026 16:47:43 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B0=D1=81=D1=87=D0=B5=D1=82=20=D1=81?= =?UTF-8?q?=D1=80=D0=B5=D0=B4=D0=BD=D0=B8=D1=85=20=D0=97=D0=A0=D0=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rest/RequestRestController.kt | 7 ++- .../pcp/slots_service/service/CZMLService.kt | 8 ++-- .../main/resources/static/requests_scripts.js | 13 ++++- .../src/main/resources/templates/map.html | 47 +++++++++++++------ .../MapControllerComplexPlanTest.kt | 37 +++++++++++++++ 5 files changed, 91 insertions(+), 21 deletions(-) diff --git a/services/pcp-ui-service/src/main/kotlin/space/nstart/pcp/slots_service/rest/RequestRestController.kt b/services/pcp-ui-service/src/main/kotlin/space/nstart/pcp/slots_service/rest/RequestRestController.kt index 6f53aa9..ef03223 100644 --- a/services/pcp-ui-service/src/main/kotlin/space/nstart/pcp/slots_service/rest/RequestRestController.kt +++ b/services/pcp-ui-service/src/main/kotlin/space/nstart/pcp/slots_service/rest/RequestRestController.kt @@ -65,8 +65,11 @@ class RequestRestController { @PostMapping("/station/{station_id}") - fun sat(@PathVariable("station_id") id : String, @RequestParam view : Boolean) = - czmlService.station(id, view) + fun sat( + @PathVariable("station_id") id : String, + @RequestParam view : Boolean, + @RequestParam(required = false) orbitHeightKm : Double? + ) = czmlService.station(id, view, orbitHeightKm) diff --git a/services/pcp-ui-service/src/main/kotlin/space/nstart/pcp/slots_service/service/CZMLService.kt b/services/pcp-ui-service/src/main/kotlin/space/nstart/pcp/slots_service/service/CZMLService.kt index b884714..cd97520 100644 --- a/services/pcp-ui-service/src/main/kotlin/space/nstart/pcp/slots_service/service/CZMLService.kt +++ b/services/pcp-ui-service/src/main/kotlin/space/nstart/pcp/slots_service/service/CZMLService.kt @@ -50,6 +50,7 @@ class CZMLService { private val docStationName = "station_" private val entityStationName = "station_" private val docReqCovName ="req_cov_" + private val DEFAULT_STATION_ORBIT_HEIGHT_KM = 500.0 @Autowired private lateinit var stationService: StationService @@ -378,9 +379,10 @@ private val docReqCovName ="req_cov_" } - fun station(id : String, view : Boolean) : Iterable{ + fun station(id : String, view : Boolean, orbitHeightKm: Double? = null) : Iterable{ val req = stationService.station(id).block()?:return listOf() - val radius = ellipseAx( (500.0 * 1000.0), req.elevationMin * PI / 180) + val normalizedOrbitHeightKm = orbitHeightKm?.takeIf { it > 0 } ?: DEFAULT_STATION_ORBIT_HEIGHT_KM + val radius = ellipseAx((normalizedOrbitHeightKm * 1000.0), req.elevationMin * PI / 180) val r: MutableList = mutableListOf(CZMLEntity("document", docStationName+id , "1.1")) r.add( @@ -401,7 +403,7 @@ private val docReqCovName ="req_cov_" extrudedHeight = 1000.0, height = 1000.0 ), - description = "Станция ${req.name}", + description = "Станция ${req.name}
Высота орбиты для зоны видимости: ${normalizedOrbitHeightKm} км", model = CZMLModel( gltf = "/model/station.glb", show = !view diff --git a/services/pcp-ui-service/src/main/resources/static/requests_scripts.js b/services/pcp-ui-service/src/main/resources/static/requests_scripts.js index 4e56978..0fa3bf7 100644 --- a/services/pcp-ui-service/src/main/resources/static/requests_scripts.js +++ b/services/pcp-ui-service/src/main/resources/static/requests_scripts.js @@ -79,7 +79,8 @@ checkModels(); } else{ var sceneMode = (viewer.scene.mode == Cesium.SceneMode.SCENE2D); - var u = '/requests/station/'+req.id+'?view='+sceneMode + var u = '/requests/station/'+req.id+'?view='+sceneMode+ + '&orbitHeightKm='+encodeURIComponent(selectedStationOrbitHeightKm()) fetch(u, { method: "post", headers: { @@ -115,6 +116,16 @@ } } + function selectedStationOrbitHeightKm() { + const input = document.getElementById('stationOrbitHeightKm'); + const value = Number(input?.value || 500); + if (!Number.isFinite(value) || value <= 0) { + if (input) input.value = '500'; + return 500; + } + return value; + } + function drawSat(show, req, startInput, endInput, runId){ if (req){ diff --git a/services/pcp-ui-service/src/main/resources/templates/map.html b/services/pcp-ui-service/src/main/resources/templates/map.html index d41cf2c..1193fe8 100644 --- a/services/pcp-ui-service/src/main/resources/templates/map.html +++ b/services/pcp-ui-service/src/main/resources/templates/map.html @@ -288,13 +288,23 @@ -
- - -
- + + +
+ + +
+ @@ -1701,16 +1711,23 @@ } - function checkStation(show, st_id) { - const sts = [[${stations}]]; - const req = sts.find(function(element) { - return element.id == st_id; - }); + function checkStation(show, st_id) { + const sts = [[${stations}]]; + const req = sts.find(function(element) { + return element.id == st_id; + }); if (req) { console.log('изменить видимость станции ' + req.id) - drawSt(show, req); - } - } + drawSt(show, req); + } + } + + function handleStationOrbitHeightChange() { + document.querySelectorAll('#stationsTableBody input[type="checkbox"]:checked').forEach(function(checkbox) { + checkStation(false, checkbox.value); + checkStation(true, checkbox.value); + }); + } // Функция для обработки запросов diff --git a/services/pcp-ui-service/src/test/kotlin/space/nstart/pcp/slots_service/controller/MapControllerComplexPlanTest.kt b/services/pcp-ui-service/src/test/kotlin/space/nstart/pcp/slots_service/controller/MapControllerComplexPlanTest.kt index e302828..117b814 100644 --- a/services/pcp-ui-service/src/test/kotlin/space/nstart/pcp/slots_service/controller/MapControllerComplexPlanTest.kt +++ b/services/pcp-ui-service/src/test/kotlin/space/nstart/pcp/slots_service/controller/MapControllerComplexPlanTest.kt @@ -10,6 +10,8 @@ import org.springframework.boot.test.web.server.LocalServerPort import org.springframework.test.context.bean.override.mockito.MockitoBean import org.springframework.web.reactive.function.client.WebClient import reactor.core.publisher.Flux +import reactor.core.publisher.Mono +import space.nstart.pcp.pcp_types_lib.dto.ballistics.PositionDTO import space.nstart.pcp.pcp_types_lib.dto.ballistics.RevolutionSign import space.nstart.pcp.pcp_types_lib.dto.ballistics.StationDTO import space.nstart.pcp.pcp_types_lib.dto.requests.ComplexPlanProcessRequestDTO @@ -61,6 +63,18 @@ class MapControllerComplexPlanTest { private val objectMapper = ObjectMapper() + private fun stationEllipseRadius(stationId: String, orbitHeightKm: Double): Double { + val actual = WebClient.create("http://localhost:$port") + .post() + .uri("/requests/station/$stationId?view=true&orbitHeightKm=$orbitHeightKm") + .retrieve() + .bodyToMono(String::class.java) + .map(objectMapper::readTree) + .block()!! + + return actual[1]["ellipse"]["semiMajorAxis"].asDouble() + } + @Test fun `local post api requests delegates to earth service facade`() { val responseId = UUID.fromString("11111111-1111-4111-8111-111111111111") @@ -256,11 +270,34 @@ class MapControllerComplexPlanTest { .block()!! assertTrue(body.contains("cesiumContainer")) + assertTrue(body.contains("stationOrbitHeightKm")) + assertTrue(body.contains("Высота орбиты, км")) assertTrue(body.contains("dynamic_plan_map_layers.js")) assertTrue(body.contains("PcpDynamicPlanMapLayers")) verify(earthService).reqs() } + @Test + fun `station czml endpoint uses orbit height for visibility zone`() { + val stationId = "11111111-1111-4111-8111-111111111111" + doReturn( + Mono.just( + StationDTO( + id = UUID.fromString(stationId), + number = 1, + name = "Station 1", + position = PositionDTO(lat = 55.0, long = 37.0, height = 200.0), + elevationMin = 5.0 + ) + ) + ).`when`(stationService).station(stationId) + + val baseRadius = stationEllipseRadius(stationId, 500.0) + val higherOrbitRadius = stationEllipseRadius(stationId, 700.0) + + assertTrue(higherOrbitRadius > baseRadius) + } + @Test fun `dynamic plan map layer keeps only one visible run`() { val body = WebClient.create("http://localhost:$port")