Compare View

switch
from
...
to
 
Commits (7)

Diff

Showing 13 changed files Side-by-side Diff

src/main/kotlin/application/App.kt View file @ 5250f69
... ... @@ -13,6 +13,7 @@ import jfxtras.styles.jmetro.JMetro
13 13 import jfxtras.styles.jmetro.Style
14 14 import kotlin.system.exitProcess
15 15  
  16 +
16 17 class App : Application() {
17 18 var style: Style = Style.LIGHT
18 19  
... ... @@ -29,7 +30,6 @@ class App : Application() {
29 30 }
30 31  
31 32 private fun closeApplication() {
32   -
33 33 Platform.exit()
34 34 exitProcess(0)
35 35 }
src/main/kotlin/application/controller/DataPanelController.kt View file @ 5250f69
... ... @@ -20,35 +20,34 @@ import java.util.*
20 20  
21 21  
22 22 class DataPanelController : Initializable, SelectedVesselListener {
23   - private var dataList: ObservableList<Pair<String, ArrayList<MessageData?>>> = FXCollections.observableArrayList()
24   - private lateinit var timeData: ArrayList<MessageData?>
25   -
26   - private val latitude: ArrayList<MessageData?> = arrayListOf()
27   - private val longitude: ArrayList<MessageData?> = arrayListOf()
28   - private val speedOverGround: ArrayList<MessageData?> = arrayListOf()
29   - private val courseOverGround: ArrayList<MessageData?> = arrayListOf()
30   - private val heading: ArrayList<MessageData?> = arrayListOf()
31   - private val vesselName: ArrayList<MessageData?> = arrayListOf()
32   - private val imo: ArrayList<MessageData?> = arrayListOf()
33   - private val callSign: ArrayList<MessageData?> = arrayListOf()
34   - private val vesselType: ArrayList<MessageData?> = arrayListOf()
35   - private val status: ArrayList<MessageData?> = arrayListOf()
36   - private val length: ArrayList<MessageData?> = arrayListOf()
37   - private val width: ArrayList<MessageData?> = arrayListOf()
38   - private val draft: ArrayList<MessageData?> = arrayListOf()
39   - private val cargo: ArrayList<MessageData?> = arrayListOf()
40   -
41   - private var selectedItem: Pair<String, ArrayList<MessageData?>>? = null
  23 + private var dataList: ObservableList<String> = FXCollections.observableArrayList()
  24 + private lateinit var timeData: ArrayList<String>
  25 +
  26 + private val latitude: ArrayList<Double> = arrayListOf()
  27 + private val longitude: ArrayList<Double> = arrayListOf()
  28 + private val speedOverGround: ArrayList<Double> = arrayListOf()
  29 + private val courseOverGround: ArrayList<Double> = arrayListOf()
  30 + private val heading: ArrayList<Double> = arrayListOf()
  31 + private val vesselName: ArrayList<String> = arrayListOf()
  32 + private val imo: ArrayList<String> = arrayListOf()
  33 + private val callSign: ArrayList<String> = arrayListOf()
  34 + private val vesselType: ArrayList<Double> = arrayListOf()
  35 + private val status: ArrayList<String> = arrayListOf()
  36 + private val length: ArrayList<Double> = arrayListOf()
  37 + private val width: ArrayList<Double> = arrayListOf()
  38 + private val draft: ArrayList<Double> = arrayListOf()
  39 + private val cargo: ArrayList<Double> = arrayListOf()
  40 +
  41 + private var selectedItem: String? = null
42 42  
43 43 @FXML
44   - var dataListView = ListView<Pair<String, ArrayList<MessageData?>>>()
  44 + var dataListView = ListView<String>()
45 45  
46 46 @FXML
47 47 var dataViewer = JavaFxDataViewer()
48 48  
49 49 private val plotData = PlotData()
50 50 private val config = DataViewerConfiguration()
51   -
52 51 override fun initialize(location: URL?, resources: ResourceBundle?) {
53 52 setObservableSelectedVesselListener()
54 53 dataListView.items = dataList
... ... @@ -61,13 +60,13 @@ class DataPanelController : Initializable, SelectedVesselListener {
61 60 setObservableCurrentTimeListener()
62 61  
63 62 dataListView.setCellFactory {
64   - object : ListCell<Pair<String, ArrayList<MessageData?>>?>() {
65   - override fun updateItem(item: Pair<String, ArrayList<MessageData?>>?, empty: Boolean) {
  63 + object : ListCell<String?>() {
  64 + override fun updateItem(item: String?, empty: Boolean) {
66 65 super.updateItem(item, empty)
67 66 text = if (empty) {
68 67 null
69 68 } else {
70   - item?.first
  69 + item
71 70 }
72 71 }
73 72 }
... ... @@ -87,18 +86,17 @@ class DataPanelController : Initializable, SelectedVesselListener {
87 86 dataViewer.updatePlot(plotData)
88 87 initDataList()
89 88  
90   -
91 89 }
92 90  
93 91 private fun plot() {
94   - if (selectedItem != null || observableSelectedVessel.value == Vessel(null)) {
  92 + if (selectedItem != null && observableSelectedVessel.value.messages.size != 0) {
95 93 GlobalScope.launch {
96 94 plot(selectedItem)
97 95 }
98 96 }
99 97 }
100 98  
101   - private fun plot(data: Pair<String, ArrayList<MessageData?>>?) {
  99 + private fun plot(data: String?) {
102 100 if (data == null) {
103 101 plotData.allTraces.clear()
104 102 config.setxAxisTitle("")
... ... @@ -108,39 +106,62 @@ class DataPanelController : Initializable, SelectedVesselListener {
108 106 dataViewer.resetPlot()
109 107  
110 108 return
111   - }else if (data.second.size < timeData.size) return
112   -
113   - val getValueVisitorX = GetValueVisitor()
114   - val getValueVisitorY = GetValueVisitor()
115   -
116   - val arrayListStringX = arrayListOf<String>()
117   -// val arrayListDoubleX = arrayListOf<Double>()
118   - val arrayListStringY = arrayListOf<String>()
119   - val arrayListDoubleY = arrayListOf<Double>()
120   -
121   - for (x in 0 until timeData.size) {
122   - timeData[x]?.accept(getValueVisitorX)
123   - data.second[x]?.accept(getValueVisitorY)
124   -
125   - if (getValueVisitorY.value.toDoubleOrNull() == null) {
126   - arrayListStringX.add(getValueVisitorX.value)
127   - arrayListStringY.add(getValueVisitorY.value)
128   - } else {
129   - arrayListStringX.add(getValueVisitorX.value)
130   - arrayListDoubleY.add(getValueVisitorY.value.toDouble())
131   - }
132 109 }
133 110  
134 111 val scatterTrace = ScatterTrace<Any>()
135 112 scatterTrace.traceColour = TraceColour.RED
136 113 scatterTrace.traceVisibility = TraceVisibility.TRUE
137 114  
138   - val serieStringX: Array<String> = arrayListStringX.toTypedArray()
  115 + val serieStringX: Array<String> = timeData.toTypedArray()
139 116 // val serieDoubleX: Array<Double> = arrayListDoubleX.toTypedArray()
140   - val serieStringY: Array<String> = arrayListStringY.toTypedArray()
141   - val serieDoubleY: Array<Double> = arrayListDoubleY.toTypedArray()
  117 + var serieStringY: Array<String> = arrayOf()
  118 + var serieDoubleY: Array<Double> = arrayOf()
  119 + when (data) {
  120 + "Latitude" -> {
  121 + serieDoubleY = latitude.toTypedArray()
  122 + }
  123 + "Longitude" -> {
  124 + serieDoubleY = longitude.toTypedArray()
  125 + }
  126 + "Speed Over Ground" -> {
  127 + serieDoubleY = speedOverGround.toTypedArray()
  128 + }
  129 + "Course Over Ground" -> {
  130 + serieDoubleY = courseOverGround.toTypedArray()
  131 + }
  132 + "Heading" -> {
  133 + serieDoubleY = heading.toTypedArray()
  134 + }
  135 + "Vessel Name" -> {
  136 + serieStringY = vesselName.toTypedArray()
  137 + }
  138 + "IMO" -> {
  139 + serieStringY = imo.toTypedArray()
  140 + }
  141 + "Call Sign" -> {
  142 + serieStringY = callSign.toTypedArray()
  143 + }
  144 + "Vessel Type" -> {
  145 + serieDoubleY = vesselType.toTypedArray()
  146 + }
  147 + "Status" -> {
  148 + serieStringY = status.toTypedArray()
  149 + }
  150 + "Length" -> {
  151 + serieDoubleY = length.toTypedArray()
  152 + }
  153 + "Width" -> {
  154 + serieDoubleY = width.toTypedArray()
  155 + }
  156 + "Draft" -> {
  157 + serieDoubleY = draft.toTypedArray()
  158 + }
  159 + "Cargo" -> {
  160 + serieDoubleY = cargo.toTypedArray()
  161 + }
  162 + }
142 163  
143   - if (getValueVisitorY.value.toDoubleOrNull() == null) {
  164 + if (serieStringY.isNotEmpty()) {
144 165 scatterTrace.setxArray(serieStringX)
145 166 scatterTrace.setyArray(serieStringY)
146 167 } else {
... ... @@ -150,7 +171,7 @@ class DataPanelController : Initializable, SelectedVesselListener {
150 171  
151 172 config.plotTitle = ""
152 173 config.setxAxisTitle("Time (s)")
153   - config.setyAxisTitle(data.first)
  174 + config.setyAxisTitle(data)
154 175 dataViewer.resetPlot()
155 176 plotData.allTraces.clear()
156 177 plotData.addTrace(scatterTrace)
... ... @@ -159,12 +180,11 @@ class DataPanelController : Initializable, SelectedVesselListener {
159 180  
160 181 }
161 182  
162   -
163 183 private fun setObservableSelectedVesselListener() {
164 184 observableSelectedVessel.listeners.add(this)
165 185 }
166 186  
167   - private fun populateTime(vessel: Vessel): ArrayList<MessageData?> {
  187 + private fun populateTime(vessel: Vessel): ArrayList<String> {
168 188 return if (observableIsReplayState.value) {
169 189 vessel.getAllTimeBeforeSelectedTime()
170 190 } else {
... ... @@ -172,8 +192,7 @@ class DataPanelController : Initializable, SelectedVesselListener {
172 192 }
173 193 }
174 194  
175   -
176   - private fun populateLatitude(vessel: Vessel): ArrayList<MessageData?> {
  195 + private fun populateLatitude(vessel: Vessel): ArrayList<Double> {
177 196 return if (observableIsReplayState.value) {
178 197 vessel.getAllLatitudeBeforeSelectedTime()
179 198 } else {
... ... @@ -181,7 +200,7 @@ class DataPanelController : Initializable, SelectedVesselListener {
181 200 }
182 201 }
183 202  
184   - private fun populateLongitude(vessel: Vessel): ArrayList<MessageData?> {
  203 + private fun populateLongitude(vessel: Vessel): ArrayList<Double> {
185 204 return if (observableIsReplayState.value) {
186 205 vessel.getAllLongitudeBeforeSelectedTime()
187 206 } else {
... ... @@ -189,7 +208,7 @@ class DataPanelController : Initializable, SelectedVesselListener {
189 208 }
190 209 }
191 210  
192   - private fun populateSpeedOverGround(vessel: Vessel): ArrayList<MessageData?> {
  211 + private fun populateSpeedOverGround(vessel: Vessel): ArrayList<Double> {
193 212 return if (observableIsReplayState.value) {
194 213 vessel.getAllSpeedOverGroundBeforeSelectedTime()
195 214 } else {
... ... @@ -197,7 +216,7 @@ class DataPanelController : Initializable, SelectedVesselListener {
197 216 }
198 217 }
199 218  
200   - private fun populateCourseOverGround(vessel: Vessel): ArrayList<MessageData?> {
  219 + private fun populateCourseOverGround(vessel: Vessel): ArrayList<Double> {
201 220 return if (observableIsReplayState.value) {
202 221 vessel.getAllCourseOverGroundBeforeSelectedTime()
203 222 } else {
... ... @@ -205,7 +224,7 @@ class DataPanelController : Initializable, SelectedVesselListener {
205 224 }
206 225 }
207 226  
208   - private fun populateHeading(vessel: Vessel): ArrayList<MessageData?> {
  227 + private fun populateHeading(vessel: Vessel): ArrayList<Double> {
209 228 return if (observableIsReplayState.value) {
210 229 vessel.getAllHeadingBeforeSelectedTime()
211 230 } else {
... ... @@ -213,7 +232,7 @@ class DataPanelController : Initializable, SelectedVesselListener {
213 232 }
214 233 }
215 234  
216   - private fun populateVesselName(vessel: Vessel): ArrayList<MessageData?> {
  235 + private fun populateVesselName(vessel: Vessel): ArrayList<String> {
217 236 return if (observableIsReplayState.value) {
218 237 vessel.getAllVesselNameBeforeSelectedTime()
219 238 } else {
... ... @@ -221,7 +240,7 @@ class DataPanelController : Initializable, SelectedVesselListener {
221 240 }
222 241 }
223 242  
224   - private fun populateIMO(vessel: Vessel): ArrayList<MessageData?> {
  243 + private fun populateIMO(vessel: Vessel): ArrayList<String> {
225 244 return if (observableIsReplayState.value) {
226 245 vessel.getAllIMOBeforeSelectedTime()
227 246 } else {
... ... @@ -229,7 +248,7 @@ class DataPanelController : Initializable, SelectedVesselListener {
229 248 }
230 249 }
231 250  
232   - private fun populateCallSign(vessel: Vessel): ArrayList<MessageData?> {
  251 + private fun populateCallSign(vessel: Vessel): ArrayList<String> {
233 252 return if (observableIsReplayState.value) {
234 253 vessel.getAllCallSignBeforeSelectedTime()
235 254 } else {
... ... @@ -237,7 +256,7 @@ class DataPanelController : Initializable, SelectedVesselListener {
237 256 }
238 257 }
239 258  
240   - private fun populateVesselType(vessel: Vessel): ArrayList<MessageData?> {
  259 + private fun populateVesselType(vessel: Vessel): ArrayList<Double> {
241 260 return if (observableIsReplayState.value) {
242 261 vessel.getAllVesselTypeBeforeSelectedTime()
243 262 } else {
... ... @@ -245,7 +264,7 @@ class DataPanelController : Initializable, SelectedVesselListener {
245 264 }
246 265 }
247 266  
248   - private fun populateStatus(vessel: Vessel): ArrayList<MessageData?> {
  267 + private fun populateStatus(vessel: Vessel): ArrayList<String> {
249 268 return if (observableIsReplayState.value) {
250 269 vessel.getAllStatusBeforeSelectedTime()
251 270 } else {
... ... @@ -253,7 +272,7 @@ class DataPanelController : Initializable, SelectedVesselListener {
253 272 }
254 273 }
255 274  
256   - private fun populateLength(vessel: Vessel): ArrayList<MessageData?> {
  275 + private fun populateLength(vessel: Vessel): ArrayList<Double> {
257 276 return if (observableIsReplayState.value) {
258 277 vessel.getAllLengthBeforeSelectedTime()
259 278 } else {
... ... @@ -261,7 +280,7 @@ class DataPanelController : Initializable, SelectedVesselListener {
261 280 }
262 281 }
263 282  
264   - private fun populateWidth(vessel: Vessel): ArrayList<MessageData?> {
  283 + private fun populateWidth(vessel: Vessel): ArrayList<Double> {
265 284 return if (observableIsReplayState.value) {
266 285 vessel.getAllWidthBeforeSelectedTime()
267 286 } else {
... ... @@ -269,7 +288,7 @@ class DataPanelController : Initializable, SelectedVesselListener {
269 288 }
270 289 }
271 290  
272   - private fun populateDraft(vessel: Vessel): ArrayList<MessageData?> {
  291 + private fun populateDraft(vessel: Vessel): ArrayList<Double> {
273 292 return if (observableIsReplayState.value) {
274 293 vessel.getAllDraftBeforeSelectedTime()
275 294 } else {
... ... @@ -277,7 +296,7 @@ class DataPanelController : Initializable, SelectedVesselListener {
277 296 }
278 297 }
279 298  
280   - private fun populateCargo(vessel: Vessel): ArrayList<MessageData?> {
  299 + private fun populateCargo(vessel: Vessel): ArrayList<Double> {
281 300 return if (observableIsReplayState.value) {
282 301 vessel.getAllCargoBeforeSelectedTime()
283 302 } else {
... ... @@ -286,22 +305,22 @@ class DataPanelController : Initializable, SelectedVesselListener {
286 305 }
287 306  
288 307 private fun initDataList() {
289   - val data = arrayListOf<Pair<String, ArrayList<MessageData?>>>()
290   -
291   - data.add(Pair("Latitude", latitude))
292   - data.add(Pair("Longitude", longitude))
293   - data.add(Pair("Speed Over Ground", speedOverGround))
294   - data.add(Pair("Course Over Ground", courseOverGround))
295   - data.add(Pair("Heading", heading))
296   - data.add(Pair("Vessel Name", vesselName))
297   - data.add(Pair("IMO", imo))
298   - data.add(Pair("Call Sign", callSign))
299   - data.add(Pair("Vessel Type", vesselType))
300   - data.add(Pair("Status", status))
301   - data.add(Pair("Length", length))
302   - data.add(Pair("Width", width))
303   - data.add(Pair("Draft", draft))
304   - data.add(Pair("Cargo", cargo))
  308 + val data = arrayListOf<String>()
  309 +
  310 + data.add("Latitude")
  311 + data.add("Longitude")
  312 + data.add("Speed Over Ground")
  313 + data.add("Course Over Ground")
  314 + data.add("Heading")
  315 + data.add("Vessel Name")
  316 + data.add("IMO")
  317 + data.add("Call Sign")
  318 + data.add("Vessel Type")
  319 + data.add("Status")
  320 + data.add("Length")
  321 + data.add("Width")
  322 + data.add("Draft")
  323 + data.add("Cargo")
305 324  
306 325 dataList.addAll(data)
307 326 }
... ... @@ -309,9 +328,9 @@ class DataPanelController : Initializable, SelectedVesselListener {
309 328 private fun updateDataList(vessel: Vessel) {
310 329 timeData = populateTime(vessel)
311 330  
312   - if(dataListView.selectionModel.selectedItem == null) return
  331 + if (dataListView.selectionModel.selectedItem == null) return
313 332  
314   - when (dataListView.selectionModel.selectedItem.first) {
  333 + when (dataListView.selectionModel.selectedItem) {
315 334 "Latitude" -> {
316 335 latitude.clear()
317 336 latitude.addAll(populateLatitude(vessel))
src/main/kotlin/application/controller/MenuBarController.kt View file @ 5250f69
... ... @@ -10,9 +10,11 @@ import javafx.fxml.FXML
10 10 import javafx.fxml.Initializable
11 11 import javafx.scene.control.*
12 12 import javafx.stage.FileChooser
  13 +import java.io.*
13 14 import java.net.URL
14 15 import java.util.*
15 16  
  17 +
16 18 class MenuBarController : Initializable {
17 19  
18 20 @FXML
... ... @@ -31,7 +33,7 @@ class MenuBarController : Initializable {
31 33 var heatMap: CheckMenuItem = CheckMenuItem()
32 34  
33 35 @FXML
34   - var activateReplayButton: RadioMenuItem = RadioMenuItem()
  36 + var activateTimeSliderButton: RadioMenuItem = RadioMenuItem()
35 37  
36 38 override fun initialize(location: URL?, resources: ResourceBundle?) {
37 39  
... ... @@ -49,8 +51,8 @@ class MenuBarController : Initializable {
49 51 }
50 52  
51 53 private fun setOnActionActivateReplayButton() {
52   - activateReplayButton.onAction = EventHandler {
53   - observableIsReplayState.value = activateReplayButton.isSelected
  54 + activateTimeSliderButton.onAction = EventHandler {
  55 + observableIsReplayState.value = activateTimeSliderButton.isSelected
54 56 }
55 57 }
56 58  
... ... @@ -60,6 +62,7 @@ class MenuBarController : Initializable {
60 62 fileChooser.title = "Choose a file to import"
61 63 val window = menuBar.scene.window
62 64 val file = fileChooser.showOpenDialog(window)
  65 +
63 66 try {
64 67 if (file.extension != "csv") {
65 68 val alert = Alert(Alert.AlertType.WARNING)
... ... @@ -68,15 +71,36 @@ class MenuBarController : Initializable {
68 71 alert.contentText = "Please choose à .csv file."
69 72 alert.showAndWait()
70 73 }
71   - val vessels = createVesselCollection(file)
72 74 observableVessel.vessels.clear()
73   - observableVessel.vessels = vessels
  75 + if(toMuchVessel(file)){
  76 + observableVessel.vessels = mutableMapOf()
  77 + }else {
  78 + val vessels = createVesselCollection(file)
  79 + observableVessel.vessels = vessels
  80 + }
74 81 } catch (ignore: IllegalStateException) {
75 82  
76 83 }
77 84 }
78 85 }
79 86  
  87 + private fun toMuchVessel(file: File): Boolean {
  88 + val nbLine = file.readLines().size
  89 + if (nbLine > 50000) {
  90 + val alert = Alert(Alert.AlertType.CONFIRMATION)
  91 + alert.title = "Warning!!"
  92 + alert.headerText = "Warning: This file contain a lot of messages."
  93 + alert.contentText = "Are you sure you want to continue."
  94 + val buttonTypeYes = ButtonType("Yes")
  95 + val buttonTypeNo = ButtonType("No ")
  96 + alert.buttonTypes.setAll(buttonTypeYes, buttonTypeNo)
  97 + val result = alert.showAndWait()
  98 +
  99 + return result.get() != buttonTypeYes
  100 + }
  101 + return false
  102 + }
  103 +
80 104 private fun setOnActionAllMessageButton() {
81 105 allMessages.onAction = EventHandler {
82 106 observableMapState.state = ALL_MESSAGES
src/main/kotlin/application/controller/VesselListPanelController.kt View file @ 5250f69
... ... @@ -6,27 +6,32 @@ import application.model.observableSelectedVessel
6 6 import application.model.observableVessel
7 7 import javafx.collections.FXCollections
8 8 import javafx.collections.ObservableList
  9 +import javafx.collections.transformation.FilteredList
9 10 import javafx.fxml.FXML
10 11 import javafx.fxml.Initializable
11   -import javafx.scene.control.ListCell
12   -import javafx.scene.control.ListView
13   -import javafx.scene.control.MultipleSelectionModel
14   -import javafx.scene.control.SelectionMode
  12 +import javafx.scene.control.*
15 13 import javafx.scene.input.MouseEvent
16 14 import java.net.URL
17 15 import java.util.*
18 16  
19 17  
20 18 class VesselListPanelController : Initializable, MessageListener {
  19 +
21 20 @FXML
22 21 var shipListView: ListView<String?> = ListView()
23 22  
  23 + @FXML
  24 + var filterInput: TextField = TextField()
  25 +
24 26 private var shipList: ObservableList<String?> = FXCollections.observableArrayList()
25 27  
  28 + private val filterMMSI = FilteredList(shipList)
  29 +
26 30 override fun initialize(location: URL?, resources: ResourceBundle?) {
27 31  
28 32  
29   - shipListView.items = shipList
  33 + shipListView.items = filterMMSI
  34 +
30 35 observableVessel.listeners.add(this)
31 36 shipListView.selectionModel.selectedItemProperty().addListener { _, _, newValue ->
32 37 if (newValue == null) {
... ... @@ -35,7 +40,10 @@ class VesselListPanelController : Initializable, MessageListener {
35 40 observableSelectedVessel.value = observableVessel.vessels[newValue]!!
36 41 }
37 42 }
  43 +
  44 +
38 45 setCellFactory()
  46 + setFilterTextListener()
39 47 }
40 48  
41 49 override fun onValueChanged(newValue: MutableMap<String?, Vessel>) {
... ... @@ -43,6 +51,17 @@ class VesselListPanelController : Initializable, MessageListener {
43 51 shipList.addAll(newValue.keys)
44 52 }
45 53  
  54 + private fun setFilterTextListener() {
  55 + filterInput.textProperty().addListener { _ ->
  56 + val filter: String = filterInput.text
  57 + if (filter.isEmpty()) {
  58 + filterMMSI.setPredicate { true }
  59 + } else {
  60 + filterMMSI.setPredicate { s: String? -> s!!.contains(filter) }
  61 + }
  62 + }
  63 + }
  64 +
46 65 private fun setCellFactory() {
47 66 val selectionModel: MultipleSelectionModel<String?>? = shipListView.selectionModel
48 67 selectionModel?.selectionMode = SelectionMode.SINGLE
src/main/kotlin/application/model/Message.kt View file @ 5250f69
... ... @@ -13,12 +13,12 @@ class Message(split: List&lt;String&gt;) {
13 13 val vesselName = VesselName(if (split[7] == "") null else split[7])
14 14 val imo = IMO(if (split[8] == "") null else split[8])
15 15 val callSign = CallSign(if (split[9] == "") null else split[9])
16   - val vesselType = VesselType(split[10].toIntOrNull())
  16 + val vesselType = VesselType(split[10].toDoubleOrNull())
17 17 val status = Status(if (split[11] == "") null else split[11])
18 18 val length = Length(split[12].toDoubleOrNull())
19 19 val width = Width(split[13].toDoubleOrNull())
20 20 val draft = Draft(split[14].toDoubleOrNull())
21   - val cargo = Cargo(split[15].toIntOrNull())
  21 + val cargo = Cargo(split[15].toDoubleOrNull())
22 22  
23 23 fun getHexColorStroke(): String {
24 24 var hex = Integer.toHexString(this.mmsi.value?.toInt()!!)
src/main/kotlin/application/model/MessageData.kt View file @ 5250f69
... ... @@ -31,7 +31,13 @@ data class MMSI(val value: String?) : MessageData {
31 31 override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this)
32 32 }
33 33  
34   -data class Time(val value: LocalDateTime) : MessageData {
  34 +data class Time(val date: LocalDateTime) : MessageData {
  35 + val value: String?
  36 +
  37 + init {
  38 + value = date.toString()
  39 + }
  40 +
35 41 override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this)
36 42 }
37 43  
... ... @@ -67,7 +73,7 @@ data class CallSign(val value: String?) : MessageData {
67 73 override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this)
68 74 }
69 75  
70   -data class VesselType(val value: Int?) : MessageData {
  76 +data class VesselType(val value: Double?) : MessageData {
71 77 override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this)
72 78 }
73 79  
... ... @@ -87,7 +93,7 @@ data class Draft(val value: Double?) : MessageData {
87 93 override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this)
88 94 }
89 95  
90   -data class Cargo(val value: Int?) : MessageData {
  96 +data class Cargo(val value: Double?) : MessageData {
91 97 override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this)
92 98 }
93 99  
src/main/kotlin/application/model/Vessel.kt View file @ 5250f69
... ... @@ -16,254 +16,285 @@ class Vessel(val mmsi: String?) {
16 16 return field
17 17 }
18 18  
19   - fun getAllTimeBeforeSelectedTime(): ArrayList<MessageData?> {
20   - val timeList = arrayListOf<MessageData?>()
  19 + fun getAllTimeBeforeSelectedTime(): ArrayList<String> {
  20 + val timeList = arrayListOf<String>()
21 21 messageBeforeSelectedTime.forEach {
22   - timeList.add(it.value.time)
  22 + if (it.value.time.value != null)
  23 + timeList.add(it.value.time.value!!)
23 24 }
24 25  
25 26 return timeList
26 27 }
27 28  
28   - fun getAllLatitudeBeforeSelectedTime(): ArrayList<MessageData?> {
29   - val latitudeList = arrayListOf<MessageData?>()
  29 + fun getAllLatitudeBeforeSelectedTime(): ArrayList<Double> {
  30 + val latitudeList = arrayListOf<Double>()
30 31 messageBeforeSelectedTime.forEach {
31   - latitudeList.add(it.value.latitude)
  32 + if (it.value.latitude.value != null)
  33 + latitudeList.add(it.value.latitude.value!!)
32 34 }
33 35  
34 36 return latitudeList
35 37 }
36 38  
37   - fun getAllLongitudeBeforeSelectedTime(): ArrayList<MessageData?> {
38   - val longitudeList = arrayListOf<MessageData?>()
  39 + fun getAllLongitudeBeforeSelectedTime(): ArrayList<Double> {
  40 + val longitudeList = arrayListOf<Double>()
39 41 messageBeforeSelectedTime.forEach {
40   - longitudeList.add(it.value.longitude)
  42 + if (it.value.longitude.value != null)
  43 + longitudeList.add(it.value.longitude.value!!)
41 44 }
42 45  
43 46 return longitudeList
44 47 }
45 48  
46   - fun getAllSpeedOverGroundBeforeSelectedTime(): ArrayList<MessageData?> {
47   - val speedOverGroundList = arrayListOf<MessageData?>()
  49 + fun getAllSpeedOverGroundBeforeSelectedTime(): ArrayList<Double> {
  50 + val speedOverGroundList = arrayListOf<Double>()
48 51 messageBeforeSelectedTime.forEach {
49   - speedOverGroundList.add(it.value.speedOverGround)
  52 + if (it.value.speedOverGround.value != null)
  53 + speedOverGroundList.add(it.value.speedOverGround.value!!)
50 54 }
51 55  
52 56 return speedOverGroundList
53 57 }
54 58  
55   - fun getAllCourseOverGroundBeforeSelectedTime(): ArrayList<MessageData?> {
56   - val res = arrayListOf<MessageData?>()
  59 + fun getAllCourseOverGroundBeforeSelectedTime(): ArrayList<Double> {
  60 + val res = arrayListOf<Double>()
57 61 messageBeforeSelectedTime.forEach {
58   - res.add(it.value.courseOverGround)
  62 + if (it.value.courseOverGround.value != null)
  63 + res.add(it.value.courseOverGround.value!!)
59 64 }
60 65  
61 66 return res
62 67 }
63 68  
64   - fun getAllHeadingBeforeSelectedTime(): ArrayList<MessageData?> {
65   - val res = arrayListOf<MessageData?>()
  69 + fun getAllHeadingBeforeSelectedTime(): ArrayList<Double> {
  70 + val res = arrayListOf<Double>()
66 71 messageBeforeSelectedTime.forEach {
67   - res.add(it.value.heading)
  72 + if (it.value.heading.value != null)
  73 + res.add(it.value.heading.value!!)
68 74 }
69 75  
70 76 return res
71 77 }
72 78  
73   - fun getAllVesselNameBeforeSelectedTime(): ArrayList<MessageData?> {
74   - val res = arrayListOf<MessageData?>()
  79 + fun getAllVesselNameBeforeSelectedTime(): ArrayList<String> {
  80 + val res = arrayListOf<String>()
75 81 messageBeforeSelectedTime.forEach {
76   - res.add(it.value.vesselName)
  82 + if (it.value.vesselName.value != null)
  83 + res.add(it.value.vesselName.value!!)
77 84 }
78 85 return res
79 86 }
80 87  
81   - fun getAllIMOBeforeSelectedTime(): ArrayList<MessageData?> {
82   - val res = arrayListOf<MessageData?>()
  88 + fun getAllIMOBeforeSelectedTime(): ArrayList<String> {
  89 + val res = arrayListOf<String>()
83 90 messageBeforeSelectedTime.forEach {
84   - res.add(it.value.imo)
  91 + if (it.value.imo.value != null)
  92 + res.add(it.value.imo.value!!)
85 93 }
86 94 return res
87 95 }
88 96  
89   - fun getAllCallSignBeforeSelectedTime(): ArrayList<MessageData?> {
90   - val res = arrayListOf<MessageData?>()
  97 + fun getAllCallSignBeforeSelectedTime(): ArrayList<String> {
  98 + val res = arrayListOf<String>()
91 99 messageBeforeSelectedTime.forEach {
92   - res.add(it.value.callSign)
  100 + if (it.value.callSign.value != null)
  101 + res.add(it.value.callSign.value!!)
93 102 }
94 103 return res
95 104 }
96 105  
97   - fun getAllVesselTypeBeforeSelectedTime(): ArrayList<MessageData?> {
98   - val res = arrayListOf<MessageData?>()
  106 + fun getAllVesselTypeBeforeSelectedTime(): ArrayList<Double> {
  107 + val res = arrayListOf<Double>()
99 108 messageBeforeSelectedTime.forEach {
100   - res.add(it.value.vesselType)
  109 + if (it.value.vesselType.value != null)
  110 + res.add(it.value.vesselType.value!!)
101 111 }
102 112 return res
103 113 }
104 114  
105   - fun getAllStatusBeforeSelectedTime(): ArrayList<MessageData?> {
106   - val res = arrayListOf<MessageData?>()
  115 + fun getAllStatusBeforeSelectedTime(): ArrayList<String> {
  116 + val res = arrayListOf<String>()
107 117 messageBeforeSelectedTime.forEach {
108   - res.add(it.value.status)
  118 + if (it.value.status.value != null)
  119 + res.add(it.value.status.value!!)
109 120 }
110 121 return res
111 122 }
112 123  
113   - fun getAllLengthBeforeSelectedTime(): ArrayList<MessageData?> {
114   - val res = arrayListOf<MessageData?>()
  124 + fun getAllLengthBeforeSelectedTime(): ArrayList<Double> {
  125 + val res = arrayListOf<Double>()
115 126 messageBeforeSelectedTime.forEach {
116   - res.add(it.value.length)
  127 + if (it.value.length.value != null)
  128 + res.add(it.value.length.value!!)
117 129 }
118 130 return res
119 131 }
120 132  
121   - fun getAllWidthBeforeSelectedTime(): ArrayList<MessageData?> {
122   - val res = arrayListOf<MessageData?>()
  133 + fun getAllWidthBeforeSelectedTime(): ArrayList<Double> {
  134 + val res = arrayListOf<Double>()
123 135 messageBeforeSelectedTime.forEach {
124   - res.add(it.value.width)
  136 + if (it.value.width.value != null)
  137 + res.add(it.value.width.value!!)
125 138 }
126 139 return res
127 140 }
128 141  
129   - fun getAllDraftBeforeSelectedTime(): ArrayList<MessageData?> {
130   - val res = arrayListOf<MessageData?>()
  142 + fun getAllDraftBeforeSelectedTime(): ArrayList<Double> {
  143 + val res = arrayListOf<Double>()
131 144 messageBeforeSelectedTime.forEach {
132   - res.add(it.value.draft)
  145 + if (it.value.draft.value != null)
  146 + res.add(it.value.draft.value!!)
133 147 }
134 148 return res
135 149 }
136 150  
137   - fun getAllCargoBeforeSelectedTime(): ArrayList<MessageData?> {
138   - val res = arrayListOf<MessageData?>()
  151 + fun getAllCargoBeforeSelectedTime(): ArrayList<Double> {
  152 + val res = arrayListOf<Double>()
139 153 messageBeforeSelectedTime.forEach {
140   - res.add(it.value.cargo)
  154 + if (it.value.cargo.value != null)
  155 + res.add(it.value.cargo.value!!)
141 156 }
142 157 return res
143 158 }
144 159  
145   - fun getAllTime(): ArrayList<MessageData?> {
146   - val timeList = arrayListOf<MessageData?>()
  160 + fun getAllTime(): ArrayList<String> {
  161 + val timeList = arrayListOf<String>()
147 162 messages.forEach {
148   - timeList.add(it.value.time)
  163 + if (it.value.time.value != null)
  164 + timeList.add(it.value.time.value!!)
149 165 }
150 166  
151 167 return timeList
152 168 }
153 169  
154   - fun getAllLatitude(): ArrayList<MessageData?> {
155   - val latitudeList = arrayListOf<MessageData?>()
  170 + fun getAllLatitude(): ArrayList<Double> {
  171 + val latitudeList = arrayListOf<Double>()
156 172 messages.forEach {
157   - latitudeList.add(it.value.latitude)
  173 + if (it.value.latitude.value != null)
  174 + latitudeList.add(it.value.latitude.value!!)
158 175 }
159 176  
160 177 return latitudeList
161 178 }
162 179  
163   - fun getAllLongitude(): ArrayList<MessageData?> {
164   - val longitudeList = arrayListOf<MessageData?>()
  180 + fun getAllLongitude(): ArrayList<Double> {
  181 + val longitudeList = arrayListOf<Double>()
165 182 messages.forEach {
166   - longitudeList.add(it.value.longitude)
  183 + if (it.value.longitude.value != null)
  184 + longitudeList.add(it.value.longitude.value!!)
167 185 }
168 186  
169 187 return longitudeList
170 188 }
171 189  
172   - fun getAllSpeedOverGround(): ArrayList<MessageData?> {
173   - val speedOverGroundList = arrayListOf<MessageData?>()
  190 + fun getAllSpeedOverGround(): ArrayList<Double> {
  191 + val speedOverGroundList = arrayListOf<Double>()
174 192 messages.forEach {
175   - speedOverGroundList.add(it.value.speedOverGround)
  193 + if (it.value.speedOverGround.value != null)
  194 + speedOverGroundList.add(it.value.speedOverGround.value!!)
176 195 }
177 196  
178 197 return speedOverGroundList
179 198 }
180 199  
181   - fun getAllCourseOverGround(): ArrayList<MessageData?> {
182   - val res = arrayListOf<MessageData?>()
  200 + fun getAllCourseOverGround(): ArrayList<Double> {
  201 + val res = arrayListOf<Double>()
183 202 messages.forEach {
184   - res.add(it.value.courseOverGround)
  203 + if (it.value.courseOverGround.value != null)
  204 + res.add(it.value.courseOverGround.value!!)
185 205 }
186 206  
187 207 return res
188 208 }
189 209  
190   - fun getAllHeading(): ArrayList<MessageData?> {
191   - val res = arrayListOf<MessageData?>()
  210 + fun getAllHeading(): ArrayList<Double> {
  211 + val res = arrayListOf<Double>()
192 212 messages.forEach {
193   - res.add(it.value.heading)
  213 + if (it.value.heading.value != null)
  214 + res.add(it.value.heading.value!!)
194 215 }
195 216  
196 217 return res
197 218 }
198 219  
199   - fun getAllVesselName(): ArrayList<MessageData?> {
200   - val res = arrayListOf<MessageData?>()
  220 + fun getAllVesselName(): ArrayList<String> {
  221 + val res = arrayListOf<String>()
201 222 messages.forEach {
202   - res.add(it.value.vesselName)
  223 + if (it.value.vesselName.value != null)
  224 + res.add(it.value.vesselName.value!!)
203 225 }
204 226 return res
205 227 }
206 228  
207   - fun getAllIMO(): ArrayList<MessageData?> {
208   - val res = arrayListOf<MessageData?>()
  229 + fun getAllIMO(): ArrayList<String> {
  230 + val res = arrayListOf<String>()
209 231 messages.forEach {
210   - res.add(it.value.imo)
  232 + if (it.value.imo.value != null)
  233 + res.add(it.value.imo.value!!)
211 234 }
212 235 return res
213 236 }
214 237  
215   - fun getAllCallSign(): ArrayList<MessageData?> {
216   - val res = arrayListOf<MessageData?>()
  238 + fun getAllCallSign(): ArrayList<String> {
  239 + val res = arrayListOf<String>()
217 240 messages.forEach {
218   - res.add(it.value.callSign)
  241 + if (it.value.callSign.value != null)
  242 + res.add(it.value.callSign.value!!)
219 243 }
220 244 return res
221 245 }
222 246  
223   - fun getAllVesselType(): ArrayList<MessageData?> {
224   - val res = arrayListOf<MessageData?>()
  247 + fun getAllVesselType(): ArrayList<Double> {
  248 + val res = arrayListOf<Double>()
225 249 messages.forEach {
226   - res.add(it.value.vesselType)
  250 + if (it.value.vesselType.value != null)
  251 + res.add(it.value.vesselType.value!!)
227 252 }
228 253 return res
229 254 }
230 255  
231   - fun getAllStatus(): ArrayList<MessageData?> {
232   - val res = arrayListOf<MessageData?>()
  256 + fun getAllStatus(): ArrayList<String> {
  257 + val res = arrayListOf<String>()
233 258 messages.forEach {
234   - res.add(it.value.status)
  259 + if (it.value.status.value != null)
  260 + res.add(it.value.status.value!!)
235 261 }
236 262 return res
237 263 }
238 264  
239   - fun getAllLength(): ArrayList<MessageData?> {
240   - val res = arrayListOf<MessageData?>()
  265 + fun getAllLength(): ArrayList<Double> {
  266 + val res = arrayListOf<Double>()
241 267 messages.forEach {
242   - res.add(it.value.length)
  268 + if (it.value.length.value != null)
  269 + res.add(it.value.length.value!!)
243 270 }
244 271 return res
245 272 }
246 273  
247   - fun getAllWidth(): ArrayList<MessageData?> {
248   - val res = arrayListOf<MessageData?>()
  274 + fun getAllWidth(): ArrayList<Double> {
  275 + val res = arrayListOf<Double>()
249 276 messages.forEach {
250   - res.add(it.value.width)
  277 + if (it.value.width.value != null)
  278 + res.add(it.value.width.value!!)
251 279 }
252 280 return res
253 281 }
254 282  
255   - fun getAllDraft(): ArrayList<MessageData?> {
256   - val res = arrayListOf<MessageData?>()
  283 + fun getAllDraft(): ArrayList<Double> {
  284 + val res = arrayListOf<Double>()
257 285 messages.forEach {
258   - res.add(it.value.draft)
  286 + if (it.value.draft.value != null)
  287 + res.add(it.value.draft.value!!)
259 288 }
260 289 return res
261 290 }
262 291  
263   - fun getAllCargo(): ArrayList<MessageData?> {
264   - val res = arrayListOf<MessageData?>()
  292 + fun getAllCargo(): ArrayList<Double> {
  293 + val res = arrayListOf<Double>()
265 294 messages.forEach {
266   - res.add(it.value.cargo)
  295 + if (it.value.cargo.value != null)
  296 + res.add(it.value.cargo.value!!)
  297 +
267 298 }
268 299 return res
269 300 }
src/main/kotlin/application/model/VesselGenerator.kt View file @ 5250f69
... ... @@ -18,7 +18,7 @@ fun createVesselCollection(file: File): SortedMap&lt;String, Vessel&gt; {
18 18 if (!vessels.containsKey(message.mmsi.value)) {
19 19 vessels[message.mmsi.value] = Vessel(message.mmsi.value!!)
20 20 }
21   - val time = message.time.value.toEpochSecond(ZoneOffset.UTC)
  21 + val time = message.time.date.toEpochSecond(ZoneOffset.UTC)
22 22 vessels[message.mmsi.value]?.messages?.set(time, message)
23 23 if (time > maxTime) {
24 24 maxTime = time
src/main/resources/gui/mapPanel.fxml View file @ 5250f69
... ... @@ -2,7 +2,7 @@
2 2  
3 3 <?import javafx.scene.layout.*?>
4 4  
5   -<VBox prefHeight="150.0" prefWidth="371.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.controller.MapPanelController">
  5 +<VBox prefHeight="150.0" prefWidth="371.0" xmlns="http://javafx.com/javafx/8.0.241" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.controller.MapPanelController">
6 6 <StackPane fx:id="map" />
7 7 <fx:include source="timePanel.fxml" />
8 8 </VBox>
src/main/resources/gui/menuBar.fxml View file @ 5250f69
... ... @@ -2,7 +2,7 @@
2 2  
3 3 <?import javafx.scene.control.*?>
4 4  
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">
  5 +<MenuBar fx:id="menuBar" prefHeight="25.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.241" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.controller.MenuBarController">
6 6 <menus>
7 7 <Menu mnemonicParsing="false" text="File">
8 8 <items>
... ... @@ -18,7 +18,7 @@
18 18 <CheckMenuItem fx:id="heatMap" mnemonicParsing="false" text="Heat map" />
19 19 </items>
20 20 </Menu>
21   - <RadioMenuItem fx:id="activateReplayButton" mnemonicParsing="false" text="Unspecified Action" />
  21 + <RadioMenuItem fx:id="activateTimeSliderButton" mnemonicParsing="false" text="Time Slider" />
22 22 </items>
23 23 </Menu>
24 24 <Menu mnemonicParsing="false" text="Help">
src/main/resources/gui/timePanel.fxml View file @ 5250f69
... ... @@ -4,7 +4,7 @@
4 4 <?import javafx.scene.control.*?>
5 5 <?import javafx.scene.layout.*?>
6 6  
7   -<HBox alignment="CENTER" prefHeight="65.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.controller.TimePanel">
  7 +<HBox alignment="CENTER" prefHeight="65.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.241" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.controller.TimePanel">
8 8 <children>
9 9 <Slider fx:id="timeSlider" prefHeight="14.0" prefWidth="538.0">
10 10 <HBox.margin>
src/main/resources/gui/vesselListPanel.fxml View file @ 5250f69
1 1 <?xml version="1.0" encoding="UTF-8"?>
2 2  
3   -<?import javafx.geometry.*?>
4 3 <?import javafx.scene.control.*?>
5 4 <?import javafx.scene.layout.*?>
6   -<?import javafx.scene.text.*?>
7 5  
8 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/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.controller.VesselListPanelController">
9 7 <center>
10 8 <ListView fx:id="shipListView" prefHeight="50.0" prefWidth="200.0" />
11 9 </center>
12 10 <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>
  11 + <TextField fx:id="filterInput" promptText="MMSI" BorderPane.alignment="CENTER" />
24 12 </top>
25 13 </BorderPane>
src/main/resources/gui/windows.fxml View file @ 5250f69
... ... @@ -4,7 +4,7 @@
4 4 <?import javafx.scene.layout.*?>
5 5 <?import javafx.scene.shape.*?>
6 6  
7   -<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="900.0" prefWidth="1200.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
  7 +<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="900.0" prefWidth="1200.0" xmlns="http://javafx.com/javafx/8.0.241" xmlns:fx="http://javafx.com/fxml/1">
8 8 <children>
9 9 <fx:include source="menuBar.fxml" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
10 10 <SplitPane dividerPositions="0.13772954924874792" layoutY="39.0" prefHeight="865.0" prefWidth="1194.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="35.0">