Commit f39d90e6068c17e06645704f2f102d47aa985a59

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

Select/deselect MMSI

Showing 14 changed files with 76 additions and 120 deletions Side-by-side Diff

src/main/kotlin/application/App.kt View file @ f39d90e
  1 +@file:JvmName("App")
  2 +
1 3 package application
2 4  
3 5 import javafx.application.Application
4 6  
... ... @@ -7,13 +9,12 @@
7 9 import javafx.scene.Parent
8 10 import javafx.scene.Scene
9 11 import javafx.stage.Stage
10   -import javafx.stage.WindowEvent
11 12 import jfxtras.styles.jmetro.JMetro
12 13 import jfxtras.styles.jmetro.Style
13 14 import kotlin.system.exitProcess
14 15  
15 16 class App : Application() {
16   - var style : Style = Style.LIGHT
  17 + var style: Style = Style.LIGHT
17 18  
18 19 override fun start(primaryStage: Stage?) {
19 20  
src/main/kotlin/application/Logger.kt View file @ f39d90e
1   -package application
2   -
3   -import org.slf4j.Logger
4   -import org.slf4j.LoggerFactory
5   -
6   -fun getLogger(): Logger = LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME)
src/main/kotlin/application/VisualisationChart.kt View file @ f39d90e
1   -package application
2   -
3   -import javafx.scene.chart.Axis
4   -import javafx.scene.chart.ScatterChart
5   -
6   -class VisualisationChart<X, Y>(xAxis: Axis<X>?, yAxis: Axis<Y>?) : ScatterChart<X, Y>(xAxis, yAxis) {
7   -
8   -
9   -
10   -}
src/main/kotlin/application/controller/DataPanelController.kt View file @ f39d90e
... ... @@ -7,14 +7,11 @@
7 7 import javafx.fxml.Initializable
8 8 import javafx.scene.control.ListCell
9 9 import javafx.scene.control.ListView
10   -import javafx.scene.layout.StackPane
11 10 import org.charts.dataviewer.api.config.DataViewerConfiguration
12 11 import org.charts.dataviewer.api.data.PlotData
13   -import org.charts.dataviewer.api.trace.LineTrace
14 12 import org.charts.dataviewer.api.trace.ScatterTrace
15 13 import org.charts.dataviewer.javafx.JavaFxDataViewer
16 14 import org.charts.dataviewer.utils.TraceColour
17   -import org.charts.dataviewer.utils.TraceMode
18 15 import org.charts.dataviewer.utils.TraceVisibility
19 16 import java.net.URL
20 17 import java.util.*
21 18  
22 19  
23 20  
... ... @@ -28,41 +25,16 @@
28 25 @FXML
29 26 var dataListView = ListView<Pair<String, ArrayList<MessageData?>>>()
30 27  
31   -// @FXML
32   -// var stackPanePlot = StackPane()
33   -
34 28 @FXML
35 29 var dataViewer = JavaFxDataViewer()
36 30  
37   -// @FXML
38   -// var xaxisNumber: CategoryAxis = CategoryAxis()
39   -//
40   -// @FXML
41   -// var yaxisNumber: NumberAxis = NumberAxis()
42   -//
43   -// @FXML
44   -// lateinit var scatterChartNumber: ScatterChart<String, Number>
45   -//
46   -// @FXML
47   -// var xaxisCategory: CategoryAxis = CategoryAxis()
48   -//
49   -// @FXML
50   -// var yaxisCategory: CategoryAxis = CategoryAxis()
51   -//
52   -// @FXML
53   -// lateinit var scatterChartCategory: ScatterChart<String, String>
54 31  
55 32 override fun initialize(location: URL?, resources: ResourceBundle?) {
56   -// xaxisNumber.animated = false
57   -// yaxisNumber.animated = false
58   -// xaxisCategory.animated = false
59   -// yaxisCategory.animated = false
60 33 setObservableSelectedVesselListener()
61 34 dataListView.items = dataList
62 35  
63 36  
64 37 val plotData = PlotData()
65   - plotData.addTrace(createScatterTrace())
66 38 val config = DataViewerConfiguration()
67 39 config.showLegend(true)
68 40 config.setLegendInsidePlot(false)
... ... @@ -85,6 +57,8 @@
85 57 plotData.allTraces.clear()
86 58 config.setxAxisTitle("")
87 59 config.setyAxisTitle("")
  60 + dataViewer.updateConfiguration(config)
  61 +
88 62 dataViewer.resetPlot()
89 63  
90 64 return@addListener
91 65  
92 66  
93 67  
... ... @@ -139,45 +113,12 @@
139 113 }
140 114  
141 115 plotData.allTraces.clear()
142   -// plotData.addTrace(createScatterTrace())
143 116 config.setxAxisTitle("")
144 117 config.setyAxisTitle("")
145   - config.plotTitle = "No data selected"
146 118 dataViewer.updateConfiguration(config)
147 119 dataViewer.updatePlot(plotData)
148 120  
149   -// stackPanePlot.children.add(dataViewer)
150   -
151 121 }
152   -
153   - private fun createScatterTrace(): ScatterTrace<*>? {
154   - val scatterTrace = ScatterTrace<Any>()
155   - scatterTrace.setxArray(arrayOf("asdf", "fdsa", "asdfffe", "asdfe", "asfee3"))
156   - scatterTrace.setyArray(arrayOf("pppp", "koojoi", "pp", "ii", "rty", "ert"))
157   - scatterTrace.traceName = "MyScatterTrace"
158   - scatterTrace.traceColour = TraceColour.PURPLE
159   - scatterTrace.traceMode = TraceMode.MARKERS
160   - return scatterTrace
161   - }
162   -
163   - fun createLineTrace(): LineTrace<*>? {
164   - val lineTrace = LineTrace<Any>()
165   - lineTrace.setxArray(arrayOf("asdf", "fdsa", "asdfffe", "asdfe", "asfee3"))
166   - lineTrace.setyArray(arrayOf(0.0, 1.0, 2.0, 3.0, 4.0, 5.0))
167   - lineTrace.traceName = "MyLineTrace"
168   - lineTrace.traceColour = TraceColour.PURPLE
169   - return lineTrace
170   - }
171   -
172   -// private fun setChartCategoryVisible() {
173   -// scatterChartCategory.isVisible = true
174   -// scatterChartNumber.isVisible = false
175   -// }
176   -//
177   -// private fun setChartNumberVisible() {
178   -// scatterChartCategory.isVisible = false
179   -// scatterChartNumber.isVisible = true
180   -// }
181 122  
182 123 private fun setObservableSelectedVesselListener() {
183 124 observableSelectedVessel.listeners.add(this)
src/main/kotlin/application/controller/MapPanelController.kt View file @ f39d90e
... ... @@ -52,7 +52,7 @@
52 52 }
53 53 }
54 54  
55   - private fun updateMap(selectedMMSI: Int) {
  55 + private fun updateMap(selectedMMSI: String) {
56 56 when (observableState.state) {
57 57 ALL_MESSAGES -> displayAllMessageOnMap(mapView, selectedMMSI)
58 58 CLUSTERED_MESSAGES -> displayClusterMessageOnMap(mapView, selectedMMSI)
... ... @@ -62,7 +62,7 @@
62 62  
63 63 private fun setObservableVesselListener() {
64 64 observableVessel.listeners.add(object : MessageListener {
65   - override fun onValueChanged(newValue: MutableMap<Int?, Vessel>) {
  65 + override fun onValueChanged(newValue: MutableMap<String?, Vessel>) {
66 66 updateMap()
67 67 }
68 68 })
... ... @@ -73,6 +73,8 @@
73 73 override fun onValueChanged(newValue: Vessel) {
74 74 if (newValue.mmsi != null){
75 75 updateMap(newValue.mmsi)
  76 + }else {
  77 + updateMap()
76 78 }
77 79 }
78 80 })
src/main/kotlin/application/controller/VesselListPanelController.kt View file @ f39d90e
... ... @@ -2,35 +2,65 @@
2 2  
3 3 import application.model.MessageListener
4 4 import application.model.Vessel
5   -import application.model.observableVessel
6 5 import application.model.observableSelectedVessel
  6 +import application.model.observableVessel
7 7 import javafx.collections.FXCollections
8 8 import javafx.collections.ObservableList
  9 +import javafx.event.EventHandler
9 10 import javafx.fxml.FXML
10 11 import javafx.fxml.Initializable
11   -import javafx.scene.control.ListView
  12 +import javafx.scene.control.*
  13 +import javafx.scene.input.MouseEvent
12 14 import java.net.URL
13 15 import java.util.*
14 16  
  17 +
15 18 class VesselListPanelController : Initializable, MessageListener {
16 19 @FXML
17   - var shipListView: ListView<Int> = ListView()
  20 + var shipListView: ListView<String?> = ListView()
18 21  
  22 + private var shipList: ObservableList<String?> = FXCollections.observableArrayList()
19 23  
20   - private var shipList: ObservableList<Int> = FXCollections.observableArrayList()
21   -
22 24 override fun initialize(location: URL?, resources: ResourceBundle?) {
  25 +
  26 +
23 27 shipListView.items = shipList
24 28 observableVessel.listeners.add(this)
25 29 shipListView.selectionModel.selectedItemProperty().addListener { _, _, newValue ->
26   - observableSelectedVessel.vessel = observableVessel.vessels[newValue]!!
  30 + if (newValue == null) {
  31 + observableSelectedVessel.vessel = Vessel(null)
  32 + } else {
  33 + observableSelectedVessel.vessel = observableVessel.vessels[newValue]!!
  34 + }
27 35 }
  36 + setCellFactory()
28 37 }
29 38  
30   - override fun onValueChanged(newValue: MutableMap<Int?, Vessel>) {
  39 + override fun onValueChanged(newValue: MutableMap<String?, Vessel>) {
31 40 shipList.clear()
32 41 shipList.addAll(newValue.keys)
33 42 }
34 43  
  44 + private fun setCellFactory() {
  45 + val selectionModel: MultipleSelectionModel<String?>? = shipListView.selectionModel
  46 + selectionModel?.selectionMode = SelectionMode.SINGLE
  47 + shipListView.setCellFactory {
  48 + val cell = ListCell<String?>()
  49 + cell.textProperty().bind(cell.itemProperty())
  50 + cell.addEventFilter(MouseEvent.MOUSE_PRESSED) { event: MouseEvent ->
  51 + shipListView.requestFocus()
  52 + if (!cell.isEmpty) {
  53 + val index = cell.index
  54 + if (selectionModel!!.selectedIndices.contains(index)) {
  55 + selectionModel.clearSelection()
  56 + } else {
  57 + selectionModel.select(index)
  58 + }
  59 + event.consume()
  60 + }
  61 + }
  62 + cell
  63 + }
  64 + }
35 65 }
src/main/kotlin/application/model/Message.kt View file @ f39d90e
... ... @@ -3,7 +3,7 @@
3 3 import java.time.LocalDateTime
4 4  
5 5 class Message(split: List<String>) {
6   - val mmsi = MMSI(split[0].toIntOrNull())
  6 + val mmsi = MMSI(if (split[0] == "") null else split[0])
7 7 val time = Time(LocalDateTime.parse(split[1]))
8 8 val latitude = Latitude(split[2].toDoubleOrNull())
9 9 val longitude = Longitude(split[3].toDoubleOrNull())
10 10  
... ... @@ -20,9 +20,8 @@
20 20 val draft = Draft(split[14].toDoubleOrNull())
21 21 val cargo = Cargo(split[15].toIntOrNull())
22 22  
23   -
24 23 fun getHexColorStroke(): String {
25   - var hex = Integer.toHexString(this.mmsi.value!!)
  24 + var hex = Integer.toHexString(this.mmsi.value?.toInt()!!)
26 25 if (hex.length > 6) {
27 26 hex = hex.substring(hex.length - 6)
28 27 }
src/main/kotlin/application/model/MessageData.kt View file @ f39d90e
... ... @@ -27,7 +27,7 @@
27 27  
28 28 }
29 29  
30   -data class MMSI(val value: Int?) : MessageData {
  30 +data class MMSI(val value: String?) : MessageData {
31 31 override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this)
32 32 }
33 33  
src/main/kotlin/application/model/MessageListener.kt View file @ f39d90e
1 1 package application.model
2 2  
3 3 interface MessageListener {
4   - fun onValueChanged(newValue: MutableMap<Int?, Vessel>)
  4 + fun onValueChanged(newValue: MutableMap<String?, Vessel>)
5 5 }
src/main/kotlin/application/model/ObservableVessel.kt View file @ f39d90e
... ... @@ -5,7 +5,7 @@
5 5 class ObservableVessel {
6 6 val listeners: MutableList<MessageListener> = mutableListOf()
7 7  
8   - var vessels: MutableMap<Int?, Vessel> by Delegates.observable(
  8 + var vessels: MutableMap<String?, Vessel> by Delegates.observable(
9 9 initialValue = mutableMapOf(),
10 10 onChange = { _, _, new ->
11 11 run {
src/main/kotlin/application/model/Vessel.kt View file @ f39d90e
... ... @@ -5,18 +5,8 @@
5 5 import java.util.*
6 6  
7 7  
8   -class Vessel(val mmsi: Int?) {
  8 +class Vessel(val mmsi: String?) {
9 9 val messages: SortedMap<LocalDateTime, Message> = sortedMapOf()
10   -
11   - fun getAllTimeInMilliSeconde(): ArrayList<Long> {
12   - val timeList = arrayListOf<Long>()
13   - var timeInMilliSeconde: Long
14   - messages.forEach {
15   - timeInMilliSeconde = it.value.time.value.toEpochSecond(ZoneOffset.UTC).toInt().toLong()
16   - timeList.add(timeInMilliSeconde)
17   - }
18   - return timeList
19   - }
20 10  
21 11 fun getAllTime(): ArrayList<MessageData?> {
22 12 val timeList = arrayListOf<MessageData?>()
src/main/kotlin/application/model/VesselGenerator.kt View file @ f39d90e
... ... @@ -4,9 +4,9 @@
4 4 import java.util.*
5 5 import kotlin.collections.ArrayList
6 6  
7   -fun createVesselCollection(file: File) : SortedMap<Int, Vessel> {
  7 +fun createVesselCollection(file: File) : SortedMap<String, Vessel> {
8 8 val messages : ArrayList<Message> = arrayListOf()
9   - val vessels: SortedMap<Int, Vessel> = sortedMapOf()
  9 + val vessels: SortedMap<String, Vessel> = sortedMapOf()
10 10  
11 11 file.forEachLine {
12 12 val arrayMessage = it.split(",")
src/main/kotlin/map/MapDisplayer.kt View file @ f39d90e
... ... @@ -44,7 +44,7 @@
44 44 }
45 45 }
46 46  
47   -fun displayAllMessageOnMap(map: LeafletMapView, selectedMMSI: Int) {
  47 +fun displayAllMessageOnMap(map: LeafletMapView, selectedMMSI: String) {
48 48 clearMap(map)
49 49 observableVessel.vessels.forEach { (_, value) ->
50 50 value.messages.forEach { (_, message) ->
... ... @@ -67,7 +67,7 @@
67 67 map.execScript("myMap.addLayer(markerClusters);")
68 68 }
69 69  
70   -fun displayClusterMessageOnMap(map: LeafletMapView, selectedMMSI: Int) {
  70 +fun displayClusterMessageOnMap(map: LeafletMapView, selectedMMSI: String) {
71 71 clearMap(map)
72 72 observableVessel.vessels.forEach { (_, value) ->
73 73 value.messages.forEach { (_, message) ->
... ... @@ -90,7 +90,7 @@
90 90 }
91 91 }
92 92  
93   -fun displayHeatMapOnMap(map: LeafletMapView, selectedMMSI: Int) {
  93 +fun displayHeatMapOnMap(map: LeafletMapView, selectedMMSI: String) {
94 94 clearMap(map)
95 95 observableVessel.vessels.forEach { (_, value) ->
96 96 value.messages.forEach { (_, message) ->
src/main/resources/gui/vesselListPanel.fxml View file @ f39d90e
1 1 <?xml version="1.0" encoding="UTF-8"?>
2 2  
  3 +<?import javafx.geometry.*?>
3 4 <?import javafx.scene.control.*?>
4 5 <?import javafx.scene.layout.*?>
  6 +<?import javafx.scene.text.*?>
5 7  
6   -<BorderPane prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.controller.VesselListPanelController">
7   -
8   - <top>
9   - <AnchorPane prefHeight="33.0" prefWidth="200.0" BorderPane.alignment="CENTER">
10   - <children>
11   - <Button layoutX="74.0" layoutY="2.0" mnemonicParsing="false" text="Button" fx:id="button"/>
12   - </children></AnchorPane>
13   - </top>
  8 +<BorderPane prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.controller.VesselListPanelController">
14 9 <center>
15   - <ListView fx:id="shipListView" prefHeight="105.0" prefWidth="200.0" />
  10 + <ListView fx:id="shipListView" prefHeight="50.0" prefWidth="200.0" />
16 11 </center>
  12 + <top>
  13 + <TextFlow prefHeight="28.0" prefWidth="200.0" style="-fx-font-weight: bold;" textAlignment="CENTER" BorderPane.alignment="CENTER">
  14 + <children>
  15 + <Text scaleX="1.5" scaleY="1.5" strokeType="OUTSIDE" strokeWidth="0.0" text="MMSI" textAlignment="CENTER" />
  16 + </children>
  17 + <BorderPane.margin>
  18 + <Insets />
  19 + </BorderPane.margin>
  20 + <padding>
  21 + <Insets top="5.0" />
  22 + </padding>
  23 + </TextFlow>
  24 + </top>
17 25 </BorderPane>