Commit dd1ce7fe83362fb902f85183684bac14c6d6ed9c

Authored by lsagona
1 parent 78935bd622
Exists in master and in 1 other branch dev

add button to switch between real time and static mode

Showing 9 changed files with 70 additions and 25 deletions Inline Diff

src/main/kotlin/application/controller/MapPanelController.kt View file @ dd1ce7f
package application.controller 1 1 package application.controller
2 2
import application.model.* 3 3 import application.model.*
import application.model.MapState.* 4 4 import application.model.MapState.*
import javafx.fxml.FXML 5 5 import javafx.fxml.FXML
import javafx.fxml.Initializable 6 6 import javafx.fxml.Initializable
import javafx.scene.layout.StackPane 7 7 import javafx.scene.layout.StackPane
import map.* 8 8 import map.*
import java.net.URL 9 9 import java.net.URL
import java.util.* 10 10 import java.util.*
11 11
class MapPanelController : Initializable { 12 12 class MapPanelController : Initializable {
13 13
@FXML 14 14 @FXML
private lateinit var map: StackPane 15 15 private lateinit var map: StackPane
16 16
private val mapView = LeafletMapView() 17 17 private val mapView = LeafletMapView()
18 18
19
override fun initialize(location: URL?, resources: ResourceBundle?) { 20 19 override fun initialize(location: URL?, resources: ResourceBundle?) {
mapView.displayMap(MapConfig()) 21 20 mapView.displayMap(MapConfig())
setObservableVesselListener() 22 21 setObservableVesselListener()
setObservableSelectedVesselListener() 23 22 setObservableSelectedVesselListener()
setStateListener() 24 23 setStateListener()
24 setObservableIsReplayState()
observableCurrentTime() 25 25 observableCurrentTime()
26 26
map.children.add(mapView) 27 27 map.children.add(mapView)
map.children 28 28 map.children
} 29 29 }
30 30
private fun setStateListener() { 31 31 private fun setStateListener() {
observableMapState.listeners.add(object : StateListener { 32 32 observableMapState.listeners.add(object : StateListener {
override fun onValueChanged(newValue: MapState) { 33 33 override fun onValueChanged(newValue: MapState) {
if (observableSelectedVessel.vessel.mmsi != null) { 34 34 if (observableSelectedVessel.value.mmsi != null) {
updateMap(observableSelectedVessel.vessel.mmsi!!) 35 35 updateMap(observableSelectedVessel.value.mmsi!!)
} else { 36 36 } else {
updateMap() 37 37 updateMap()
} 38 38 }
} 39 39 }
}) 40 40 })
} 41 41 }
42 42
private fun observableCurrentTime() { 43 43 private fun observableCurrentTime() {
observableCurrentTime.listeners.add(object : CurrentTime { 44 44 observableCurrentTime.listeners.add(object : CurrentTime {
override fun onValueChanged(newValue: Int) { 45 45 override fun onValueChanged(newValue: Int) {
if (observableSelectedVessel.vessel.mmsi != null) { 46 46 if (observableSelectedVessel.value.mmsi != null) {
updateMap(observableSelectedVessel.vessel.mmsi!!) 47 47 updateMap(observableSelectedVessel.value.mmsi!!)
} else { 48 48 } else {
updateMap() 49 49 updateMap()
} 50 50 }
} 51 51 }
}) 52 52 })
} 53 53 }
54 54
private fun updateMap() { 55 55 private fun updateMap() {
if (observableIsReplayState.value) { 56 56 if (observableIsReplayState.value) {
when (observableMapState.state) { 57 57 when (observableMapState.state) {
ALL_MESSAGES -> displayTimedAllMessageOnMap(mapView) 58 58 ALL_MESSAGES -> displayTimedAllMessageOnMap(mapView)
CLUSTERED_MESSAGES -> displayTimedClusterMessageOnMap(mapView) 59 59 CLUSTERED_MESSAGES -> displayTimedClusterMessageOnMap(mapView)
HEAT_MAP -> displayTimedHeatMapOnMap(mapView) 60 60 HEAT_MAP -> displayTimedHeatMapOnMap(mapView)
} 61 61 }
} else { 62 62 } else {
when (observableMapState.state) { 63 63 when (observableMapState.state) {
ALL_MESSAGES -> displayAllMessageOnMap(mapView) 64 64 ALL_MESSAGES -> displayAllMessageOnMap(mapView)
CLUSTERED_MESSAGES -> displayClusterMessageOnMap(mapView) 65 65 CLUSTERED_MESSAGES -> displayClusterMessageOnMap(mapView)
HEAT_MAP -> displayHeatMapOnMap(mapView) 66 66 HEAT_MAP -> displayHeatMapOnMap(mapView)
} 67 67 }
} 68 68 }
} 69 69 }
70 70
private fun updateMap(selectedMMSI: String) { 71 71 private fun updateMap(selectedMMSI: String) {
if (observableIsReplayState.value) { 72 72 if (observableIsReplayState.value) {
when (observableMapState.state) { 73 73 when (observableMapState.state) {
ALL_MESSAGES -> displayTimedAllMessageOnMap(mapView, selectedMMSI) 74 74 ALL_MESSAGES -> displayTimedAllMessageOnMap(mapView, selectedMMSI)
CLUSTERED_MESSAGES -> displayTimedClusterMessageOnMap(mapView, selectedMMSI) 75 75 CLUSTERED_MESSAGES -> displayTimedClusterMessageOnMap(mapView, selectedMMSI)
HEAT_MAP -> displayTimedHeatMapOnMap(mapView, selectedMMSI) 76 76 HEAT_MAP -> displayTimedHeatMapOnMap(mapView, selectedMMSI)
} 77 77 }
} else { 78 78 } else {
when (observableMapState.state) { 79 79 when (observableMapState.state) {
ALL_MESSAGES -> displayAllMessageOnMap(mapView, selectedMMSI) 80 80 ALL_MESSAGES -> displayAllMessageOnMap(mapView, selectedMMSI)
CLUSTERED_MESSAGES -> displayClusterMessageOnMap(mapView, selectedMMSI) 81 81 CLUSTERED_MESSAGES -> displayClusterMessageOnMap(mapView, selectedMMSI)
HEAT_MAP -> displayHeatMapOnMap(mapView, selectedMMSI) 82 82 HEAT_MAP -> displayHeatMapOnMap(mapView, selectedMMSI)
} 83 83 }
} 84 84 }
} 85 85 }
86 86
private fun setObservableVesselListener() { 87 87 private fun setObservableVesselListener() {
observableVessel.listeners.add(object : MessageListener { 88 88 observableVessel.listeners.add(object : MessageListener {
override fun onValueChanged(newValue: MutableMap<String?, Vessel>) { 89 89 override fun onValueChanged(newValue: MutableMap<String?, Vessel>) {
updateMap() 90 90 updateMap()
91 }
92 })
93 }
94
95 private fun setObservableIsReplayState() {
96 observableIsReplayState.listeners.add(object: ReplayState {
97 override fun onValueChanged(newValue: Boolean) {
98 if (observableSelectedVessel.value.mmsi != null) {
99 updateMap(observableSelectedVessel.value.mmsi!!)
100 } else {
101 updateMap()
102 }
} 91 103 }
}) 92 104 })
} 93 105 }
94 106
private fun setObservableSelectedVesselListener() { 95 107 private fun setObservableSelectedVesselListener() {
observableSelectedVessel.listeners.add(object : SelectedVesselListener { 96 108 observableSelectedVessel.listeners.add(object : SelectedVesselListener {
override fun onValueChanged(newValue: Vessel) { 97 109 override fun onValueChanged(newValue: Vessel) {
src/main/kotlin/application/controller/MenuBarController.kt View file @ dd1ce7f
package application.controller 1 1 package application.controller
2 2
import application.model.MapState.* 3 3 import application.model.MapState.*
import application.model.createVesselCollection 4 4 import application.model.createVesselCollection
5 import application.model.observableIsReplayState
import application.model.observableMapState 5 6 import application.model.observableMapState
import application.model.observableVessel 6 7 import application.model.observableVessel
import javafx.event.EventHandler 7 8 import javafx.event.EventHandler
import javafx.fxml.FXML 8 9 import javafx.fxml.FXML
import javafx.fxml.Initializable 9 10 import javafx.fxml.Initializable
import javafx.scene.control.Alert 10 11 import javafx.scene.control.*
import javafx.scene.control.CheckMenuItem 11
import javafx.scene.control.MenuBar 12
import javafx.scene.control.MenuItem 13
import javafx.stage.FileChooser 14 12 import javafx.stage.FileChooser
import java.net.URL 15 13 import java.net.URL
import java.util.* 16 14 import java.util.*
17 15
class MenuBarController : Initializable { 18 16 class MenuBarController : Initializable {
19 17
@FXML 20 18 @FXML
var menuBar: MenuBar = MenuBar() 21 19 var menuBar: MenuBar = MenuBar()
22 20
@FXML 23 21 @FXML
var import: MenuItem = MenuItem() 24 22 var import: MenuItem = MenuItem()
25 23
@FXML 26 24 @FXML
var allMessages: CheckMenuItem = CheckMenuItem() 27 25 var allMessages: CheckMenuItem = CheckMenuItem()
28 26
@FXML 29 27 @FXML
var clusteredMessage: CheckMenuItem = CheckMenuItem() 30 28 var clusteredMessage: CheckMenuItem = CheckMenuItem()
31 29
@FXML 32 30 @FXML
var heatMap: CheckMenuItem = CheckMenuItem() 33 31 var heatMap: CheckMenuItem = CheckMenuItem()
34 32
33 @FXML
34 var activateReplayButton: RadioMenuItem = RadioMenuItem()
35
override fun initialize(location: URL?, resources: ResourceBundle?) { 35 36 override fun initialize(location: URL?, resources: ResourceBundle?) {
36 37
setOnActionImportButton() 37 38 setOnActionImportButton()
38 39
setOnActionAllMessageButton() 39 40 setOnActionAllMessageButton()
setOnActionClusteredMessageButton() 40 41 setOnActionClusteredMessageButton()
setOnActionHeatMapButton() 41 42 setOnActionHeatMapButton()
43 setOnActionActivateReplayButton()
observableMapState.state = CLUSTERED_MESSAGES 42 44 observableMapState.state = CLUSTERED_MESSAGES
allMessages.isSelected = false 43 45 allMessages.isSelected = false
clusteredMessage.isSelected = true 44 46 clusteredMessage.isSelected = true
heatMap.isSelected = false 45 47 heatMap.isSelected = false
46 48
49 }
50
51 private fun setOnActionActivateReplayButton() {
52 activateReplayButton.onAction = EventHandler {
53 observableIsReplayState.value = activateReplayButton.isSelected
54 }
} 47 55 }
48 56
private fun setOnActionImportButton() { 49 57 private fun setOnActionImportButton() {
import.onAction = EventHandler { 50 58 import.onAction = EventHandler {
val fileChooser = FileChooser() 51 59 val fileChooser = FileChooser()
fileChooser.title = "Choose a file to import" 52 60 fileChooser.title = "Choose a file to import"
val window = menuBar.scene.window 53 61 val window = menuBar.scene.window
val file = fileChooser.showOpenDialog(window) 54 62 val file = fileChooser.showOpenDialog(window)
try { 55 63 try {
if (file.extension != "csv") { 56 64 if (file.extension != "csv") {
val alert = Alert(Alert.AlertType.WARNING) 57 65 val alert = Alert(Alert.AlertType.WARNING)
alert.title = "Warning Alert" 58 66 alert.title = "Warning Alert"
alert.headerText = "Wrong file format." 59 67 alert.headerText = "Wrong file format."
alert.contentText = "Please choose à .csv file." 60 68 alert.contentText = "Please choose à .csv file."
alert.showAndWait() 61 69 alert.showAndWait()
} 62 70 }
val vessels = createVesselCollection(file) 63 71 val vessels = createVesselCollection(file)
observableVessel.vessels.clear() 64 72 observableVessel.vessels.clear()
observableVessel.vessels = vessels 65 73 observableVessel.vessels = vessels
} catch (ignore: IllegalStateException) { 66 74 } catch (ignore: IllegalStateException) {
67 75
} 68 76 }
} 69 77 }
} 70 78 }
71 79
private fun setOnActionAllMessageButton() { 72 80 private fun setOnActionAllMessageButton() {
allMessages.onAction = EventHandler { 73 81 allMessages.onAction = EventHandler {
observableMapState.state = ALL_MESSAGES 74 82 observableMapState.state = ALL_MESSAGES
allMessages.isSelected = true 75 83 allMessages.isSelected = true
clusteredMessage.isSelected = false 76 84 clusteredMessage.isSelected = false
heatMap.isSelected = false 77 85 heatMap.isSelected = false
} 78 86 }
} 79 87 }
80 88
private fun setOnActionClusteredMessageButton() { 81 89 private fun setOnActionClusteredMessageButton() {
clusteredMessage.onAction = EventHandler { 82 90 clusteredMessage.onAction = EventHandler {
observableMapState.state = CLUSTERED_MESSAGES 83 91 observableMapState.state = CLUSTERED_MESSAGES
src/main/kotlin/application/controller/TimePanel.kt View file @ dd1ce7f
package application.controller 1 1 package application.controller
2 2
import application.model.* 3 3 import application.model.*
import javafx.fxml.FXML 4 4 import javafx.fxml.FXML
import javafx.fxml.Initializable 5 5 import javafx.fxml.Initializable
import javafx.scene.control.Button 6 6 import javafx.scene.control.Button
import javafx.scene.control.Slider 7 7 import javafx.scene.control.Slider
import java.net.URL 8 8 import java.net.URL
import java.util.* 9 9 import java.util.*
10 10
11 11
class TimePanel : Initializable { 12 12 class TimePanel : Initializable {
13 13
@FXML 14 14 @FXML
var timeSlider = Slider() 15 15 var timeSlider = Slider()
16 16
@FXML 17 17 @FXML
var timeStop = Button() 18 18 var timeStop = Button()
19 19
@FXML 20 20 @FXML
var timePlay = Button() 21 21 var timePlay = Button()
22 22
23 23
override fun initialize(location: URL?, resources: ResourceBundle?) { 24 24 override fun initialize(location: URL?, resources: ResourceBundle?) {
setSliderMinMax() 25 25 setSliderMinMax()
setSliderListener() 26 26 setSliderListener()
27 27 disableAllButton()
28 28 setDisable()
} 29 29 }
30 30
private fun setSliderMinMax() { 31 31 private fun setSliderMinMax() {
timeSlider.min = 0.0 32 32 timeSlider.min = 0.0
timeSlider.max = 0.0 33 33 timeSlider.max = 0.0
observableVessel.listeners.add(object : MessageListener{ 34 34 observableVessel.listeners.add(object : MessageListener {
override fun onValueChanged(newValue: MutableMap<String?, Vessel>) { 35 35 override fun onValueChanged(newValue: MutableMap<String?, Vessel>) {
timeSlider.max = Vessel.maxTime.toDouble() 36 36 timeSlider.max = Vessel.maxTime.toDouble()
timeSlider.min = Vessel.minTime.toDouble() 37 37 timeSlider.min = Vessel.minTime.toDouble()
} 38 38 }
}) 39 39 })
} 40 40 }
41 41
private fun setSliderListener() { 42 42 private fun setSliderListener() {
timeSlider.valueProperty().addListener { _, _, newValue -> 43 43 timeSlider.valueProperty().addListener { _, _, newValue ->
observableCurrentTime.value = newValue.toInt() 44 44 observableCurrentTime.value = newValue.toInt()
} 45 45 }
46 }
47
48 private fun disableAllButton() {
49 timeStop.isDisable = true
50 timeSlider.isDisable = true
51 timePlay.isDisable = true
52 }
53
54 private fun unableAllButton() {
55 timeStop.isDisable = false
56 timeSlider.isDisable = false
57 timePlay.isDisable = false
58 }
59
60 private fun setDisable() {
61 observableIsReplayState.listeners.add(object : ReplayState {
62 override fun onValueChanged(newValue: Boolean) {
src/main/kotlin/application/controller/VesselListPanelController.kt View file @ dd1ce7f
package application.controller 1 1 package application.controller
2 2
import application.model.MessageListener 3 3 import application.model.MessageListener
import application.model.Vessel 4 4 import application.model.Vessel
import application.model.observableSelectedVessel 5 5 import application.model.observableSelectedVessel
import application.model.observableVessel 6 6 import application.model.observableVessel
import javafx.collections.FXCollections 7 7 import javafx.collections.FXCollections
import javafx.collections.ObservableList 8 8 import javafx.collections.ObservableList
import javafx.fxml.FXML 9 9 import javafx.fxml.FXML
import javafx.fxml.Initializable 10 10 import javafx.fxml.Initializable
import javafx.scene.control.ListCell 11 11 import javafx.scene.control.ListCell
import javafx.scene.control.ListView 12 12 import javafx.scene.control.ListView
import javafx.scene.control.MultipleSelectionModel 13 13 import javafx.scene.control.MultipleSelectionModel
import javafx.scene.control.SelectionMode 14 14 import javafx.scene.control.SelectionMode
import javafx.scene.input.MouseEvent 15 15 import javafx.scene.input.MouseEvent
import java.net.URL 16 16 import java.net.URL
import java.util.* 17 17 import java.util.*
18 18
19 19
class VesselListPanelController : Initializable, MessageListener { 20 20 class VesselListPanelController : Initializable, MessageListener {
@FXML 21 21 @FXML
var shipListView: ListView<String?> = ListView() 22 22 var shipListView: ListView<String?> = ListView()
23 23
private var shipList: ObservableList<String?> = FXCollections.observableArrayList() 24 24 private var shipList: ObservableList<String?> = FXCollections.observableArrayList()
25 25
override fun initialize(location: URL?, resources: ResourceBundle?) { 26 26 override fun initialize(location: URL?, resources: ResourceBundle?) {
27 27
28 28
shipListView.items = shipList 29 29 shipListView.items = shipList
observableVessel.listeners.add(this) 30 30 observableVessel.listeners.add(this)
shipListView.selectionModel.selectedItemProperty().addListener { _, _, newValue -> 31 31 shipListView.selectionModel.selectedItemProperty().addListener { _, _, newValue ->
if (newValue == null) { 32 32 if (newValue == null) {
observableSelectedVessel.vessel = Vessel(null) 33 33 observableSelectedVessel.value = Vessel(null)
} else { 34 34 } else {
observableSelectedVessel.vessel = observableVessel.vessels[newValue]!! 35 35 observableSelectedVessel.value = observableVessel.vessels[newValue]!!
} 36 36 }
} 37 37 }
setCellFactory() 38 38 setCellFactory()
} 39 39 }
40 40
override fun onValueChanged(newValue: MutableMap<String?, Vessel>) { 41 41 override fun onValueChanged(newValue: MutableMap<String?, Vessel>) {
shipList.clear() 42 42 shipList.clear()
shipList.addAll(newValue.keys) 43 43 shipList.addAll(newValue.keys)
} 44 44 }
45 45
private fun setCellFactory() { 46 46 private fun setCellFactory() {
val selectionModel: MultipleSelectionModel<String?>? = shipListView.selectionModel 47 47 val selectionModel: MultipleSelectionModel<String?>? = shipListView.selectionModel
selectionModel?.selectionMode = SelectionMode.SINGLE 48 48 selectionModel?.selectionMode = SelectionMode.SINGLE
shipListView.setCellFactory { 49 49 shipListView.setCellFactory {
val cell = ListCell<String?>() 50 50 val cell = ListCell<String?>()
cell.textProperty().bind(cell.itemProperty()) 51 51 cell.textProperty().bind(cell.itemProperty())
cell.addEventFilter(MouseEvent.MOUSE_PRESSED) { event: MouseEvent -> 52 52 cell.addEventFilter(MouseEvent.MOUSE_PRESSED) { event: MouseEvent ->
shipListView.requestFocus() 53 53 shipListView.requestFocus()
if (!cell.isEmpty) { 54 54 if (!cell.isEmpty) {
val index = cell.index 55 55 val index = cell.index
if (selectionModel!!.selectedIndices.contains(index)) { 56 56 if (selectionModel!!.selectedIndices.contains(index)) {
selectionModel.clearSelection() 57 57 selectionModel.clearSelection()
} else { 58 58 } else {
selectionModel.select(index) 59 59 selectionModel.select(index)
} 60 60 }
src/main/kotlin/application/model/ObservableReplayState.kt View file @ dd1ce7f
package application.model 1 1 package application.model
2 2
import kotlin.properties.Delegates 3 3 import kotlin.properties.Delegates
4 4
class ObservableReplayState { 5 5 class ObservableReplayState {
6 6
val listeners: MutableList<ReplayState> = mutableListOf() 7 7 val listeners: MutableList<ReplayState> = mutableListOf()
8 8
var value: Boolean by Delegates.observable( 9 9 var value: Boolean by Delegates.observable(
initialValue = true, 10 10 initialValue = false,
onChange = { _, _, new -> 11 11 onChange = { _, _, new ->
run { 12 12 run {
listeners.forEach { 13 13 listeners.forEach {
it.onValueChanged(new) 14 14 it.onValueChanged(new)
} 15 15 }
} 16 16 }
src/main/kotlin/application/model/ObservableSelectedVessel.kt View file @ dd1ce7f
package application.model 1 1 package application.model
2 2
import kotlin.properties.Delegates 3 3 import kotlin.properties.Delegates
4 4
class ObservableSelectedVessel { 5 5 class ObservableSelectedVessel {
val listeners: MutableList<SelectedVesselListener> = mutableListOf() 6 6 val listeners: MutableList<SelectedVesselListener> = mutableListOf()
7 7
var vessel: Vessel by Delegates.observable( 8 8 var value: Vessel by Delegates.observable(
initialValue = Vessel(null), 9 9 initialValue = Vessel(null),
onChange = { _, _, new -> 10 10 onChange = { _, _, new ->
run { 11 11 run {
listeners.forEach { 12 12 listeners.forEach {
it.onValueChanged(new) 13 13 it.onValueChanged(new)
} 14 14 }
} 15 15 }
} 16 16 }
src/main/kotlin/application/model/ObservableVessel.kt View file @ dd1ce7f
package application.model 1 1 package application.model
2 2
import kotlin.properties.Delegates 3 3 import kotlin.properties.Delegates
4 4
class ObservableVessel { 5 5 class ObservableVessel {
val listeners: MutableList<MessageListener> = mutableListOf() 6 6 val listeners: MutableList<MessageListener> = mutableListOf()
7 7
var vessels: MutableMap<String?, Vessel> by Delegates.observable( 8 8 var vessels: MutableMap<String?, Vessel> by Delegates.observable(
initialValue = mutableMapOf(), 9 9 initialValue = mutableMapOf(),
onChange = { _, _, new -> 10 10 onChange = { _, _, new ->
run { 11 11 run {
observableSelectedVessel.vessel = Vessel(null) 12 12 observableSelectedVessel.value = Vessel(null)
listeners.forEach { 13 13 listeners.forEach {
it.onValueChanged(new) 14 14 it.onValueChanged(new)
} 15 15 }
} 16 16 }
} 17 17 }
src/main/kotlin/map/MapDisplayer.kt View file @ dd1ce7f
package map 1 1 package map
2 2
import application.model.observableVessel 3 3 import application.model.observableVessel
4 4
fun clearMap(map: LeafletMapView) { 5 5 fun clearMap(map: LeafletMapView) {
clearMapCanvas(map) 6 6 clearMapCanvas(map)
clearMapCluster(map) 7 7 clearMapCluster(map)
clearHeatMap(map) 8 8 clearHeatMap(map)
clearMarker(map) 9 9 clearMarker(map)
} 10 10 }
11 11
fun clearMapCluster(map: LeafletMapView) { 12 12 fun clearMapCluster(map: LeafletMapView) {
map.execScript( 13 13 map.execScript(
""" 14 14 """
|myMap.removeLayer(markerClusters); 15 15 |myMap.removeLayer(markerClusters);
|var markerClusters = L.markerClusterGroup({spiderfyOnMaxZoom: false, disableClusteringAtZoom: 10}); 16 16 |var markerClusters = L.markerClusterGroup({spiderfyOnMaxZoom: false, disableClusteringAtZoom: 10});
""".trimMargin() 17 17 """.trimMargin()
) 18 18 )
} 19 19 }
20 20
fun clearMapCanvas(map: LeafletMapView) { 21 21 fun clearMapCanvas(map: LeafletMapView) {
map.execScript( 22 22 map.execScript(
""" 23 23 """
|myRenderer.removeFrom(myMap); 24 24 |myRenderer.removeFrom(myMap);
|var myRenderer = L.canvas({ padding: 0.5 }); 25 25 |var myRenderer = L.canvas({ padding: 0.5 });
""".trimMargin() 26 26 """.trimMargin()
) 27 27 )
} 28 28 }
29 29
fun clearHeatMap(map: LeafletMapView) { 30 30 fun clearHeatMap(map: LeafletMapView) {
map.execScript( 31 31 map.execScript(
""" 32 32 """
|heatLayer.removeFrom(myMap); 33 33 |heatLayer.removeFrom(myMap);
|var heatLayer = L.heatLayer([]).addTo(myMap); 34 34 |var heatLayer = L.heatLayer([]).addTo(myMap);
""".trimMargin() 35 35 """.trimMargin()
) 36 36 )
} 37 37 }
38 38
fun clearMarker(map: LeafletMapView) { 39 39 fun clearMarker(map: LeafletMapView) {
map.execScript( 40 40 map.execScript(
""" 41 41 """
|for(var i = 0; i < markers.length; i++){ 42 42 |for(var i = 0; i < markers.length; i++){
|myMap.removeLayer(markers[i]); 43 43 |myMap.removeLayer(markers[i]);
|} 44 44 |}
|markers = [] 45 45 |markers = []
""".trimMargin() 46 46 """.trimMargin()
) 47 47 )
} 48 48 }
49 49
fun displayAllMessageOnMap(map: LeafletMapView) { 50 50 fun displayAllMessageOnMap(map: LeafletMapView) {
clearMap(map) 51 51 clearMap(map)
observableVessel.vessels.forEach { (_, value) -> 52 52 observableVessel.vessels.forEach { (_, value) ->
value.messages.forEach { (_, message) -> 53 53 value.messages.forEach { (_, message) ->
map.execScript("L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}).addTo(myMap)") 54 54 map.execScript("L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}).addTo(myMap)")
} 55 55 }
} 56 56 }
} 57 57 }
58 58
fun displayTimedAllMessageOnMap(map: LeafletMapView) { 59 59 fun displayTimedAllMessageOnMap(map: LeafletMapView) {
clearMap(map) 60 60 clearMap(map)
observableVessel.vessels.forEach { (_, value) -> 61 61 observableVessel.vessels.forEach { (_, value) ->
val message = value.messageToDisplay ?: return@forEach 62 62 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))") 63 63 map.execScript("markers.push(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {radius: 0.01, color: '#${message.getHexColorStroke()}'}).addTo(myMap))")
} 64 64 }
} 65 65 }
66 66
fun displayAllMessageOnMap(map: LeafletMapView, selectedMMSI: String) { 67 67 fun displayAllMessageOnMap(map: LeafletMapView, selectedMMSI: String) {
clearMap(map) 68 68 clearMap(map)
observableVessel.vessels.forEach { (_, value) -> 69 69 observableVessel.vessels.forEach { (_, value) ->
value.messages.forEach { (_, message) -> 70 70 value.messages.forEach { (_, message) ->
if (selectedMMSI == message.mmsi.value) { 71 71 if (selectedMMSI == message.mmsi.value) {
map.execScript("L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 2, color: '#ff4040'}).addTo(myMap)") 72 72 map.execScript("markers.push(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {radius: 2, color: '#ff4040'}).addTo(myMap))")
} else { 73 73 } else {
map.execScript("L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}).addTo(myMap)") 74 74 map.execScript("markers.push(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}).addTo(myMap))")
} 75 75 }
} 76 76 }
} 77 77 }
} 78 78 }
79 79
fun displayTimedAllMessageOnMap(map: LeafletMapView, selectedMMSI: String) { 80 80 fun displayTimedAllMessageOnMap(map: LeafletMapView, selectedMMSI: String) {
clearMap(map) 81 81 clearMap(map)
observableVessel.vessels.forEach { (_, value) -> 82 82 observableVessel.vessels.forEach { (_, value) ->
val message = value.messageToDisplay ?: return@forEach 83 83 val message = value.messageToDisplay ?: return@forEach
if (selectedMMSI == message.mmsi.value) { 84 84 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))") 85 85 map.execScript("markers.push(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 2, color: '#ff4040'}).addTo(myMap))")
} else { 86 86 } else {
map.execScript("markers.push(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}).addTo(myMap))") 87 87 map.execScript("markers.push(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}).addTo(myMap))")
} 88 88 }
} 89 89 }
} 90 90 }
91 91
fun displayClusterMessageOnMap(map: LeafletMapView) { 92 92 fun displayClusterMessageOnMap(map: LeafletMapView) {
clearMap(map) 93 93 clearMap(map)
observableVessel.vessels.forEach { (_, value) -> 94 94 observableVessel.vessels.forEach { (_, value) ->
value.messages.forEach { (_, message) -> 95 95 value.messages.forEach { (_, message) ->
map.execScript("markerClusters.addLayer(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}));") 96 96 map.execScript("markerClusters.addLayer(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}));")
} 97 97 }
} 98 98 }
map.execScript("myMap.addLayer(markerClusters);") 99 99 map.execScript("myMap.addLayer(markerClusters);")
} 100 100 }
101 101
fun displayTimedClusterMessageOnMap(map: LeafletMapView) { 102 102 fun displayTimedClusterMessageOnMap(map: LeafletMapView) {
clearMap(map) 103 103 clearMap(map)
observableVessel.vessels.forEach { (_, value) -> 104 104 observableVessel.vessels.forEach { (_, value) ->
val message = value.messageToDisplay ?: return@forEach 105 105 val message = value.messageToDisplay ?: return@forEach
map.execScript("markerClusters.addLayer(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {radius: 0.01, color: '#${message.getHexColorStroke()}'}));") 106 106 map.execScript("markerClusters.addLayer(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {radius: 0.01, color: '#${message.getHexColorStroke()}'}));")
} 107 107 }
map.execScript("myMap.addLayer(markerClusters);") 108 108 map.execScript("myMap.addLayer(markerClusters);")
} 109 109 }
110 110
fun displayClusterMessageOnMap(map: LeafletMapView, selectedMMSI: String) { 111 111 fun displayClusterMessageOnMap(map: LeafletMapView, selectedMMSI: String) {
clearMap(map) 112 112 clearMap(map)
observableVessel.vessels.forEach { (_, value) -> 113 113 observableVessel.vessels.forEach { (_, value) ->
value.messages.forEach { (_, message) -> 114 114 value.messages.forEach { (_, message) ->
if (selectedMMSI == message.mmsi.value) { 115 115 if (selectedMMSI == message.mmsi.value) {
map.execScript("L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 2, color: '#ff4040'}).addTo(myMap);") 116 116 map.execScript("markers.push(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {radius: 2, color: '#ff4040'}).addTo(myMap));")
} else { 117 117 } else {
map.execScript("markerClusters.addLayer(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}));") 118 118 map.execScript("markerClusters.addLayer(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}));")
} 119 119 }
} 120 120 }
} 121 121 }
map.execScript("myMap.addLayer(markerClusters);") 122 122 map.execScript("myMap.addLayer(markerClusters);")
} 123 123 }
124 124
fun displayTimedClusterMessageOnMap(map: LeafletMapView, selectedMMSI: String) { 125 125 fun displayTimedClusterMessageOnMap(map: LeafletMapView, selectedMMSI: String) {
clearMap(map) 126 126 clearMap(map)
observableVessel.vessels.forEach { (_, value) -> 127 127 observableVessel.vessels.forEach { (_, value) ->
val message = value.messageToDisplay ?: return@forEach 128 128 val message = value.messageToDisplay ?: return@forEach
if (selectedMMSI == message.mmsi.value) { 129 129 if (selectedMMSI == message.mmsi.value) {
map.execScript("markers.push(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {radius: 2, color: '#ff4040'}).addTo(myMap));") 130 130 map.execScript("markers.push(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {radius: 2, color: '#ff4040'}).addTo(myMap));")
} else { 131 131 } else {
map.execScript("markerClusters.addLayer(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {radius: 0.01, color: '#${message.getHexColorStroke()}'}));") 132 132 map.execScript("markerClusters.addLayer(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {radius: 0.01, color: '#${message.getHexColorStroke()}'}));")
} 133 133 }
} 134 134 }
map.execScript("myMap.addLayer(markerClusters);") 135 135 map.execScript("myMap.addLayer(markerClusters);")
} 136 136 }
137 137
fun displayHeatMapOnMap(map: LeafletMapView) { 138 138 fun displayHeatMapOnMap(map: LeafletMapView) {
clearMap(map) 139 139 clearMap(map)
observableVessel.vessels.forEach { (_, value) -> 140 140 observableVessel.vessels.forEach { (_, value) ->
value.messages.forEach { (_, message) -> 141 141 value.messages.forEach { (_, message) ->
map.execScript("heatLayer.addLatLng([${message.latitude.value}, ${message.longitude.value}]);") 142 142 map.execScript("heatLayer.addLatLng([${message.latitude.value}, ${message.longitude.value}]);")
} 143 143 }
} 144 144 }
} 145 145 }
146 146
fun displayTimedHeatMapOnMap(map: LeafletMapView) { 147 147 fun displayTimedHeatMapOnMap(map: LeafletMapView) {
clearMap(map) 148 148 clearMap(map)
observableVessel.vessels.forEach { (_, value) -> 149 149 observableVessel.vessels.forEach { (_, value) ->
val message = value.messageToDisplay ?: return@forEach 150 150 val message = value.messageToDisplay ?: return@forEach
map.execScript("heatLayer.addLatLng([${message.latitude.value}, ${message.longitude.value}]);") 151 151 map.execScript("heatLayer.addLatLng([${message.latitude.value}, ${message.longitude.value}]);")
} 152 152 }
} 153 153 }
154 154
fun displayHeatMapOnMap(map: LeafletMapView, selectedMMSI: String) { 155 155 fun displayHeatMapOnMap(map: LeafletMapView, selectedMMSI: String) {
clearMap(map) 156 156 clearMap(map)
observableVessel.vessels.forEach { (_, value) -> 157 157 observableVessel.vessels.forEach { (_, value) ->
value.messages.forEach { (_, message) -> 158 158 value.messages.forEach { (_, message) ->
if (selectedMMSI == message.mmsi.value) { 159 159 if (selectedMMSI == message.mmsi.value) {
map.execScript("L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 2, color: '#ff4040'}).addTo(myMap);") 160 160 map.execScript("markers.push(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {radius: 2, color: '#ff4040'}).addTo(myMap));")
} else { 161 161 } else {
map.execScript("heatLayer.addLatLng([${message.latitude.value}, ${message.longitude.value}]);") 162 162 map.execScript("heatLayer.addLatLng([${message.latitude.value}, ${message.longitude.value}]);")
} 163 163 }
} 164 164 }
} 165 165 }
src/main/resources/gui/menuBar.fxml View file @ dd1ce7f
<?xml version="1.0" encoding="UTF-8"?> 1 1 <?xml version="1.0" encoding="UTF-8"?>
2 2
<?import javafx.scene.control.*?> 3 3 <?import javafx.scene.control.*?>
4 4
<MenuBar fx:id="menuBar" prefHeight="25.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.controller.MenuBarController"> 5 5 <MenuBar fx:id="menuBar" prefHeight="25.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.controller.MenuBarController">
<menus> 6 6 <menus>
<Menu mnemonicParsing="false" text="File"> 7 7 <Menu mnemonicParsing="false" text="File">
<items> 8 8 <items>
<MenuItem fx:id="import" mnemonicParsing="false" text="Import" /> 9 9 <MenuItem fx:id="import" mnemonicParsing="false" text="Import" />
</items> 10 10 </items>
</Menu> 11 11 </Menu>
<Menu mnemonicParsing="false" text="Settings"> 12 12 <Menu mnemonicParsing="false" text="Settings">
<items> 13 13 <items>
<Menu mnemonicParsing="false" text="Map selected"> 14 14 <Menu mnemonicParsing="false" text="Map selected">
<items> 15 15 <items>
<CheckMenuItem mnemonicParsing="false" text="All messages" fx:id="allMessages"/> 16 16 <CheckMenuItem fx:id="allMessages" mnemonicParsing="false" text="All messages" />
<CheckMenuItem mnemonicParsing="false" text="Clustered messages" fx:id="clusteredMessage"/> 17 17 <CheckMenuItem fx:id="clusteredMessage" mnemonicParsing="false" text="Clustered messages" />
<CheckMenuItem mnemonicParsing="false" text="Heat map" fx:id="heatMap"/> 18 18 <CheckMenuItem fx:id="heatMap" mnemonicParsing="false" text="Heat map" />
</items> 19 19 </items>
</Menu> 20 20 </Menu>
21 <RadioMenuItem fx:id="activateReplayButton" mnemonicParsing="false" text="Unspecified Action" />
</items> 21 22 </items>
</Menu> 22 23 </Menu>
<Menu mnemonicParsing="false" text="Help"> 23 24 <Menu mnemonicParsing="false" text="Help">
<items> 24 25 <items>
<MenuItem mnemonicParsing="false" text="About" /> 25 26 <MenuItem mnemonicParsing="false" text="About" />
</items> 26 27 </items>
</Menu> 27 28 </Menu>
</menus> 28 29 </menus>
</MenuBar> 29 30 </MenuBar>
30 31