diff --git a/src/main/kotlin/application/controller/MapPanelController.kt b/src/main/kotlin/application/controller/MapPanelController.kt index 92c838b..8c7713c 100644 --- a/src/main/kotlin/application/controller/MapPanelController.kt +++ b/src/main/kotlin/application/controller/MapPanelController.kt @@ -24,12 +24,6 @@ class MapPanelController : Initializable { setStateListener() observableCurrentTime() - /*val completeFutureMap: CompletableFuture = mapView.displayMap(MapConfig()) - completeFutureMap.whenComplete{ - workerState, _ -> - if (workerState == Worker.State.SUCCEEDED) { - } - }*/ map.children.add(mapView) map.children } @@ -47,16 +41,24 @@ class MapPanelController : Initializable { } private fun observableCurrentTime() { - observableCurrentTime.listeners.add(object : CurrentTime{ + observableCurrentTime.listeners.add(object : CurrentTime { override fun onValueChanged(newValue: Int) { - updateMap() + if (observableSelectedVessel.vessel.mmsi != null) { + updateMap(observableSelectedVessel.vessel.mmsi!!) + } else { + updateMap() + } } }) } private fun updateMap() { - if (observableIsReplayState.value){ - displayTargetedVessels(mapView) + if (observableIsReplayState.value) { + when (observableMapState.state) { + ALL_MESSAGES -> displayTimedAllMessageOnMap(mapView) + CLUSTERED_MESSAGES -> displayTimedClusterMessageOnMap(mapView) + HEAT_MAP -> displayTimedHeatMapOnMap(mapView) + } } else { when (observableMapState.state) { ALL_MESSAGES -> displayAllMessageOnMap(mapView) @@ -67,10 +69,18 @@ class MapPanelController : Initializable { } private fun updateMap(selectedMMSI: String) { - when (observableMapState.state) { - ALL_MESSAGES -> displayAllMessageOnMap(mapView, selectedMMSI) - CLUSTERED_MESSAGES -> displayClusterMessageOnMap(mapView, selectedMMSI) - HEAT_MAP -> displayHeatMapOnMap(mapView, selectedMMSI) + if (observableIsReplayState.value) { + when (observableMapState.state) { + ALL_MESSAGES -> displayTimedAllMessageOnMap(mapView, selectedMMSI) + CLUSTERED_MESSAGES -> displayTimedClusterMessageOnMap(mapView, selectedMMSI) + HEAT_MAP -> displayTimedHeatMapOnMap(mapView, selectedMMSI) + } + } else { + when (observableMapState.state) { + ALL_MESSAGES -> displayAllMessageOnMap(mapView, selectedMMSI) + CLUSTERED_MESSAGES -> displayClusterMessageOnMap(mapView, selectedMMSI) + HEAT_MAP -> displayHeatMapOnMap(mapView, selectedMMSI) + } } } @@ -85,14 +95,12 @@ class MapPanelController : Initializable { private fun setObservableSelectedVesselListener() { observableSelectedVessel.listeners.add(object : SelectedVesselListener { override fun onValueChanged(newValue: Vessel) { - if (newValue.mmsi != null){ + if (newValue.mmsi != null) { updateMap(newValue.mmsi) - }else { + } else { updateMap() } } }) } - - } \ No newline at end of file diff --git a/src/main/kotlin/application/controller/TimePanel.kt b/src/main/kotlin/application/controller/TimePanel.kt index 4e3a819..d18583a 100644 --- a/src/main/kotlin/application/controller/TimePanel.kt +++ b/src/main/kotlin/application/controller/TimePanel.kt @@ -29,6 +29,8 @@ class TimePanel : Initializable { } private fun setSliderMinMax() { + timeSlider.min = 0.0 + timeSlider.max = 0.0 observableVessel.listeners.add(object : MessageListener{ override fun onValueChanged(newValue: MutableMap) { timeSlider.max = Vessel.maxTime.toDouble() diff --git a/src/main/kotlin/application/controller/VesselListPanelController.kt b/src/main/kotlin/application/controller/VesselListPanelController.kt index 056ad86..01a316d 100644 --- a/src/main/kotlin/application/controller/VesselListPanelController.kt +++ b/src/main/kotlin/application/controller/VesselListPanelController.kt @@ -6,10 +6,12 @@ import application.model.observableSelectedVessel import application.model.observableVessel import javafx.collections.FXCollections import javafx.collections.ObservableList -import javafx.event.EventHandler import javafx.fxml.FXML import javafx.fxml.Initializable -import javafx.scene.control.* +import javafx.scene.control.ListCell +import javafx.scene.control.ListView +import javafx.scene.control.MultipleSelectionModel +import javafx.scene.control.SelectionMode import javafx.scene.input.MouseEvent import java.net.URL import java.util.* diff --git a/src/main/kotlin/application/model/Vessel.kt b/src/main/kotlin/application/model/Vessel.kt index bda8ad1..201bda7 100644 --- a/src/main/kotlin/application/model/Vessel.kt +++ b/src/main/kotlin/application/model/Vessel.kt @@ -7,32 +7,11 @@ class Vessel(val mmsi: String?) { val messages: SortedMap = sortedMapOf() var messageToDisplay: Message? = null get() { - // messages.forEach { (key, value) -> -// if(observableCurrentTime.value < key) { -// field = value -// return@forEach -// } -// } - field = messages.asSequence().map{ it }.firstOrNull {observableCurrentTime.value < it.key}.let { it?.value } + field = + messages.asSequence().map { it }.firstOrNull { observableCurrentTime.value < it.key }.let { it?.value } return field } - // val timesNormalized : SortedMap = sortedMapOf() - -// fun getAllNormalizedDate(): SortedMap { -// var offset: Long? = null -// if(timesNormalized.size == 0){ -// messages.keys.forEach { -// val currentTime = it.toEpochSecond(ZoneOffset.UTC) -// if(offset == null){ -// offset = currentTime -// } -// timesNormalized[currentTime - offset!!]= it -// } -// } -// return timesNormalized -// } - fun getAllTime(): ArrayList { val timeList = arrayListOf() messages.forEach { @@ -159,7 +138,7 @@ class Vessel(val mmsi: String?) { return res } - companion object{ + companion object { var maxTime: Long = 0 var minTime: Long = 0 } diff --git a/src/main/kotlin/map/LeafletMapView.kt b/src/main/kotlin/map/LeafletMapView.kt index 745d073..51406b9 100644 --- a/src/main/kotlin/map/LeafletMapView.kt +++ b/src/main/kotlin/map/LeafletMapView.kt @@ -93,6 +93,7 @@ class LeafletMapView : StackPane() { | layers: [layer1] |}); |L.control.scale().addTo(myMap); + |var markers = [] |var myRenderer = L.canvas({ padding: 0.5 }); |var markerClusters = L.markerClusterGroup({spiderfyOnMaxZoom: false, disableClusteringAtZoom: 10}); |var heatLayer = L.heatLayer([]).addTo(myMap);""".trimMargin() diff --git a/src/main/kotlin/map/MapDisplayer.kt b/src/main/kotlin/map/MapDisplayer.kt index cd9dd6c..f5987f1 100644 --- a/src/main/kotlin/map/MapDisplayer.kt +++ b/src/main/kotlin/map/MapDisplayer.kt @@ -6,6 +6,7 @@ fun clearMap(map: LeafletMapView) { clearMapCanvas(map) clearMapCluster(map) clearHeatMap(map) + clearMarker(map) } fun clearMapCluster(map: LeafletMapView) { @@ -35,6 +36,17 @@ fun clearHeatMap(map: LeafletMapView) { ) } +fun clearMarker(map: LeafletMapView) { + map.execScript( + """ + |for(var i = 0; i < markers.length; i++){ + |myMap.removeLayer(markers[i]); + |} + |markers = [] + """.trimMargin() + ) +} + fun displayAllMessageOnMap(map: LeafletMapView) { clearMap(map) observableVessel.vessels.forEach { (_, value) -> @@ -44,6 +56,14 @@ fun displayAllMessageOnMap(map: LeafletMapView) { } } +fun displayTimedAllMessageOnMap(map: LeafletMapView) { + clearMap(map) + observableVessel.vessels.forEach { (_, value) -> + val message = value.messageToDisplay ?: return@forEach + map.execScript("markers.push(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {radius: 0.01, color: '#${message.getHexColorStroke()}'}).addTo(myMap))") + } +} + fun displayAllMessageOnMap(map: LeafletMapView, selectedMMSI: String) { clearMap(map) observableVessel.vessels.forEach { (_, value) -> @@ -57,6 +77,18 @@ fun displayAllMessageOnMap(map: LeafletMapView, selectedMMSI: String) { } } +fun displayTimedAllMessageOnMap(map: LeafletMapView, selectedMMSI: String) { + clearMap(map) + observableVessel.vessels.forEach { (_, value) -> + val message = value.messageToDisplay ?: return@forEach + if (selectedMMSI == message.mmsi.value) { + map.execScript("markers.push(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 2, color: '#ff4040'}).addTo(myMap))") + } else { + map.execScript("markers.push(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}).addTo(myMap))") + } + } +} + fun displayClusterMessageOnMap(map: LeafletMapView) { clearMap(map) observableVessel.vessels.forEach { (_, value) -> @@ -67,11 +99,11 @@ fun displayClusterMessageOnMap(map: LeafletMapView) { map.execScript("myMap.addLayer(markerClusters);") } -fun displayTargetedVessels(map: LeafletMapView) { +fun displayTimedClusterMessageOnMap(map: LeafletMapView) { clearMap(map) observableVessel.vessels.forEach { (_, value) -> val message = value.messageToDisplay ?: return@forEach - map.execScript("markerClusters.addLayer(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}));") + map.execScript("markerClusters.addLayer(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {radius: 0.01, color: '#${message.getHexColorStroke()}'}));") } map.execScript("myMap.addLayer(markerClusters);") } @@ -90,6 +122,19 @@ fun displayClusterMessageOnMap(map: LeafletMapView, selectedMMSI: String) { map.execScript("myMap.addLayer(markerClusters);") } +fun displayTimedClusterMessageOnMap(map: LeafletMapView, selectedMMSI: String) { + clearMap(map) + observableVessel.vessels.forEach { (_, value) -> + val message = value.messageToDisplay ?: return@forEach + if (selectedMMSI == message.mmsi.value) { + map.execScript("markers.push(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {radius: 2, color: '#ff4040'}).addTo(myMap));") + } else { + map.execScript("markerClusters.addLayer(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {radius: 0.01, color: '#${message.getHexColorStroke()}'}));") + } + } + map.execScript("myMap.addLayer(markerClusters);") +} + fun displayHeatMapOnMap(map: LeafletMapView) { clearMap(map) observableVessel.vessels.forEach { (_, value) -> @@ -99,6 +144,14 @@ fun displayHeatMapOnMap(map: LeafletMapView) { } } +fun displayTimedHeatMapOnMap(map: LeafletMapView) { + clearMap(map) + observableVessel.vessels.forEach { (_, value) -> + val message = value.messageToDisplay ?: return@forEach + map.execScript("heatLayer.addLatLng([${message.latitude.value}, ${message.longitude.value}]);") + } +} + fun displayHeatMapOnMap(map: LeafletMapView, selectedMMSI: String) { clearMap(map) observableVessel.vessels.forEach { (_, value) -> @@ -111,4 +164,16 @@ fun displayHeatMapOnMap(map: LeafletMapView, selectedMMSI: String) { } } map.execScript("myMap.addLayer(markerClusters);") +} + +fun displayTimedHeatMapOnMap(map: LeafletMapView, selectedMMSI: String) { + clearMap(map) + observableVessel.vessels.forEach { (_, value) -> + val message = value.messageToDisplay ?: return@forEach + if (selectedMMSI == message.mmsi.value) { + map.execScript("markers.push(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {radius: 2, color: '#ff4040'}).addTo(myMap));") + } else { + map.execScript("heatLayer.addLatLng([${message.latitude.value}, ${message.longitude.value}]);") + } + } } \ No newline at end of file diff --git a/src/main/resources/gui/timePanel.fxml b/src/main/resources/gui/timePanel.fxml index f3f39bb..8cf2145 100644 --- a/src/main/resources/gui/timePanel.fxml +++ b/src/main/resources/gui/timePanel.fxml @@ -14,7 +14,7 @@ - +