Commit 2bbe36a1be826b47c824114b471c6a1e5de02983

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

addd the possibility to select a ship

Showing 13 changed files with 112 additions and 68 deletions Inline Diff

src/main/kotlin/application/controller/ControlPanelController.kt View file @ 2bbe36a
package application.controller 1 File was deleted
2
import application.model.MessageListener 3
import application.model.Vessel 4
import application.model.observableMessages 5
import javafx.collections.FXCollections 6
import javafx.collections.ObservableList 7
import javafx.event.EventHandler 8
import javafx.fxml.FXML 9
import javafx.fxml.Initializable 10
import javafx.scene.control.Button 11
import javafx.scene.control.ListView 12
import java.net.URL 13
import java.util.* 14
15
class ControlPanelController : Initializable, MessageListener { 16
@FXML 17
var shipListView: ListView<Int> = ListView() 18
19
20
var shipList: ObservableList<Int> = FXCollections.observableArrayList() 21
22
override fun initialize(location: URL?, resources: ResourceBundle?) { 23
shipListView.items = shipList 24
observableMessages.listeners.add(this) 25
} 26
src/main/kotlin/application/controller/MapPanelController.kt View file @ 2bbe36a
package application.controller 1 1 package application.controller
2 2
import application.model.MessageListener 3 3 import application.model.*
import application.model.Vessel 4
import application.model.observableMessages 5
import javafx.concurrent.Worker 6 4 import javafx.concurrent.Worker
import javafx.fxml.FXML 7 5 import javafx.fxml.FXML
import javafx.fxml.Initializable 8 6 import javafx.fxml.Initializable
import javafx.scene.layout.StackPane 9 7 import javafx.scene.layout.StackPane
import map.LeafletMapView 10 8 import map.LeafletMapView
import map.MapConfig 11 9 import map.MapConfig
import map.displayMessageOnMap 12 10 import map.displayMessageOnMap
import java.net.URL 13 11 import java.net.URL
import java.util.* 14 12 import java.util.*
import java.util.concurrent.CompletableFuture 15 13 import java.util.concurrent.CompletableFuture
16 14
class MapPanelController : Initializable, MessageListener { 17 15 class MapPanelController : Initializable {
18 16
@FXML 19 17 @FXML
private lateinit var map: StackPane 20 18 private lateinit var map: StackPane
21 19
private val mapView = LeafletMapView() 22 20 private val mapView = LeafletMapView()
23 21
24 22
override fun initialize(location: URL?, resources: ResourceBundle?) { 25 23 override fun initialize(location: URL?, resources: ResourceBundle?) {
val completeFutureMap: CompletableFuture<Worker.State> = mapView.displayMap(MapConfig()) 26 24 val completeFutureMap: CompletableFuture<Worker.State> = mapView.displayMap(MapConfig())
observableMessages.listeners.add(this) 27 25 observableVessel.listeners.add(object : MessageListener {
26 override fun onValueChanged(newValue: MutableMap<Int?, Vessel>) {
27 displayMessageOnMap(mapView)
28 }
29 })
28 30
31 observableSelectedVessel.listeners.add(object : SelectedVesselListener {
32 override fun onValueChanged(newValue: Vessel) {
33 displayMessageOnMap(mapView, newValue.mmsi!!)
34 }
35 })
36
/*completeFutureMap.whenComplete{ 29 37 /*completeFutureMap.whenComplete{
workerState, _ -> 30 38 workerState, _ ->
if (workerState == Worker.State.SUCCEEDED) { 31 39 if (workerState == Worker.State.SUCCEEDED) {
} 32 40 }
}*/ 33 41 }*/
map.children.add(mapView) 34 42 map.children.add(mapView)
} 35
src/main/kotlin/application/controller/MenuBarController.kt View file @ 2bbe36a
package application.controller 1 1 package application.controller
2 2
import application.model.createVesselCollection 3 3 import application.model.createVesselCollection
import application.model.observableMessages 4 4 import application.model.observableVessel
import javafx.event.EventHandler 5 5 import javafx.event.EventHandler
import javafx.fxml.FXML 6 6 import javafx.fxml.FXML
import javafx.fxml.Initializable 7 7 import javafx.fxml.Initializable
import javafx.scene.control.MenuBar 8 8 import javafx.scene.control.MenuBar
import javafx.scene.control.MenuItem 9 9 import javafx.scene.control.MenuItem
import javafx.stage.FileChooser 10 10 import javafx.stage.FileChooser
import java.net.URL 11 11 import java.net.URL
import java.util.* 12 12 import java.util.*
13 13
class MenuBarController : Initializable { 14 14 class MenuBarController : Initializable {
15 15
@FXML 16 16 @FXML
var menuBar: MenuBar = MenuBar() 17 17 var menuBar: MenuBar = MenuBar()
18 18
@FXML 19 19 @FXML
var import: MenuItem = MenuItem() 20 20 var import: MenuItem = MenuItem()
21 21
override fun initialize(location: URL?, resources: ResourceBundle?) { 22 22 override fun initialize(location: URL?, resources: ResourceBundle?) {
23 23
import.onAction = EventHandler { 24 24 import.onAction = EventHandler {
val fileChooser = FileChooser() 25 25 val fileChooser = FileChooser()
fileChooser.title = "Choose a file to import" 26 26 fileChooser.title = "Choose a file to import"
val window = menuBar.scene.window 27 27 val window = menuBar.scene.window
val file = fileChooser.showOpenDialog(window) 28 28 val file = fileChooser.showOpenDialog(window)
val vessels = createVesselCollection(file) 29 29 val vessels = createVesselCollection(file)
observableMessages.vessels.clear() 30 30 observableVessel.vessels.clear()
observableMessages.vessels = vessels 31 31 observableVessel.vessels = vessels
src/main/kotlin/application/controller/VesselListPanelController.kt View file @ 2bbe36a
File was created 1 package application.controller
2
3 import application.model.MessageListener
4 import application.model.Vessel
5 import application.model.observableVessel
6 import application.model.observableSelectedVessel
7 import javafx.collections.FXCollections
8 import javafx.collections.ObservableList
9 import javafx.fxml.FXML
10 import javafx.fxml.Initializable
11 import javafx.scene.control.ListView
12 import java.net.URL
13 import java.util.*
14
15 class VesselListPanelController : Initializable, MessageListener {
16 @FXML
17 var shipListView: ListView<Int> = ListView()
18
19
20 var shipList: ObservableList<Int> = FXCollections.observableArrayList()
21
22 override fun initialize(location: URL?, resources: ResourceBundle?) {
23 shipListView.items = shipList
24 observableVessel.listeners.add(this)
25 shipListView.selectionModel.selectedItemProperty().addListener { _, _, newValue ->
26 observableSelectedVessel.vessel = observableVessel.vessels[newValue]!!
27 }
28 }
src/main/kotlin/application/model/Context.kt View file @ 2bbe36a
package application.model 1 1 package application.model
2 2
val observableMessages : ObservableVessel = ObservableVessel() 3 3 val observableVessel: ObservableVessel = ObservableVessel()
4
5 val observableSelectedVessel: ObservableSelectedVessel = ObservableSelectedVessel()
src/main/kotlin/application/model/ObservableSelectedVessel.kt View file @ 2bbe36a
File was created 1 package application.model
2
3 import kotlin.properties.Delegates
4
5 class ObservableSelectedVessel {
6 val listeners: MutableList<SelectedVesselListener> = mutableListOf()
7
8 var vessel: Vessel by Delegates.observable(
9 initialValue = Vessel(null),
10 onChange = { _, _, new ->
11 run {
12 listeners.forEach {
13 it.onValueChanged(new)
14 }
15 }
src/main/kotlin/application/model/SelectedVesselListener.kt View file @ 2bbe36a
File was created 1 package application.model
2
3 interface SelectedVesselListener {
4 fun onValueChanged(newValue: Vessel)
src/main/kotlin/application/model/Vessel.kt View file @ 2bbe36a
package application.model 1 1 package application.model
2 2
import java.time.LocalDateTime 3 3 import java.time.LocalDateTime
import java.util.* 4 4 import java.util.*
5 5
6 6
class Vessel { 7 7 class Vessel(val mmsi : Int?) {
src/main/kotlin/application/model/VesselGenerator.kt View file @ 2bbe36a
package application.model 1 1 package application.model
2 2
import java.io.File 3 3 import java.io.File
import java.util.* 4 4 import java.util.*
import kotlin.collections.ArrayList 5 5 import kotlin.collections.ArrayList
6 6
fun createVesselCollection(file: File) : SortedMap<Int, Vessel> { 7 7 fun createVesselCollection(file: File) : SortedMap<Int, Vessel> {
val messages : ArrayList<Message> = arrayListOf() 8 8 val messages : ArrayList<Message> = arrayListOf()
val vessels: SortedMap<Int, Vessel> = sortedMapOf() 9 9 val vessels: SortedMap<Int, Vessel> = sortedMapOf()
10 10
file.forEachLine { 11 11 file.forEachLine {
val arrayMessage = it.split(",") 12 12 val arrayMessage = it.split(",")
if (arrayMessage[0].toIntOrNull() !== null) { 13 13 if (arrayMessage[0].toIntOrNull() !== null) {
val message = Message(arrayMessage) 14 14 val message = Message(arrayMessage)
messages.add(message) 15 15 messages.add(message)
if (!vessels.containsKey(message.mmsi)){ 16 16 if (!vessels.containsKey(message.mmsi)){
vessels[message.mmsi] = Vessel() 17 17 vessels[message.mmsi] = Vessel(message.mmsi!!)
} 18 18 }
vessels[message.mmsi]?.messages?.set(message.time, message) 19 19 vessels[message.mmsi]?.messages?.set(message.time, message)
} 20 20 }
21 21
src/main/kotlin/map/CircleMarkerGenerator.kt View file @ 2bbe36a
package map 1 1 package map
2 2
import application.model.observableMessages 3 3 import application.model.observableVessel
4 4
fun clearMapCanvas(map: LeafletMapView) { 5 5 fun clearMapCanvas(map: LeafletMapView) {
map.execScript(""" 6 6 map.execScript("""
|myRenderer.removeFrom(myMap) 7 7 |myRenderer.removeFrom(myMap)
|var myRenderer = L.canvas({ padding: 0.5 }); 8 8 |var myRenderer = L.canvas({ padding: 0.5 });
""".trimMargin()) 9 9 """.trimMargin())
} 10 10 }
11 11
fun displayMessageOnMap(map: LeafletMapView) { 12 12 fun displayMessageOnMap(map: LeafletMapView) {
clearMapCanvas(map) 13 13 clearMapCanvas(map)
observableMessages.vessels.forEach { (_, value) -> 14 14 observableVessel.vessels.forEach { (_, value) ->
value.messages.forEach { (_, message) -> 15 15 value.messages.forEach { (_, message) ->
map.execScript("L.circleMarker([${message.latitude}, ${message.longitude}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColor()}'}).addTo(myMap)") 16 16 map.execScript("L.circleMarker([${message.latitude}, ${message.longitude}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColor()}'}).addTo(myMap)")
17 }
18 }
19 }
20
21 fun displayMessageOnMap(map: LeafletMapView, selectedMMSI: Int) {
22 clearMapCanvas(map)
23 observableVessel.vessels.forEach { (_, value) ->
24 value.messages.forEach { (_, message) ->
25 if(selectedMMSI == message.mmsi){
26 map.execScript("L.circleMarker([${message.latitude}, ${message.longitude}], {renderer: myRenderer, radius: 4, color: '#ff001e'}).addTo(myMap)")
27 }else{
28 map.execScript("L.circleMarker([${message.latitude}, ${message.longitude}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColor()}'}).addTo(myMap)")
29 }
} 17 30 }
} 18 31 }
src/main/resources/gui/controlPanel.fxml View file @ 2bbe36a
<?xml version="1.0" encoding="UTF-8"?> 1 File was deleted
2
<?import javafx.scene.control.*?> 3
<?import javafx.scene.layout.*?> 4
5
<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.ControlPanelController"> 6
7
<top> 8
<AnchorPane prefHeight="33.0" prefWidth="200.0" BorderPane.alignment="CENTER"> 9
<children> 10
<Button layoutX="74.0" layoutY="2.0" mnemonicParsing="false" text="Button" fx:id="buton" /> 11
</children></AnchorPane> 12
</top> 13
<center> 14
src/main/resources/gui/vesselListPanel.fxml View file @ 2bbe36a
File was created 1 <?xml version="1.0" encoding="UTF-8"?>
2
3 <?import javafx.scene.control.*?>
4 <?import javafx.scene.layout.*?>
5
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="buton" />
12 </children></AnchorPane>
13 </top>
14 <center>
src/main/resources/gui/windows.fxml View file @ 2bbe36a
<?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.*?>
<?import javafx.scene.layout.*?> 4 4 <?import javafx.scene.layout.*?>
<?import javafx.scene.shape.*?> 5 5 <?import javafx.scene.shape.*?>
6 6
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="900.0" prefWidth="1200.0" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1"> 7 7 <AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="900.0" prefWidth="1200.0" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1">
<children> 8 8 <children>
<fx:include source="menuBar.fxml" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" /> 9 9 <fx:include source="menuBar.fxml" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
<SplitPane dividerPositions="0.29797979797979796" 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"> 10 10 <SplitPane dividerPositions="0.29797979797979796" 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">
<items> 11 11 <items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0"> 12 12 <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children> 13 13 <children>
<fx:include source="controlPanel.fxml" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" /> 14 14 <fx:include source="vesselListPanel.fxml" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children> 15 15 </children>
</AnchorPane> 16 16 </AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0"> 17 17 <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children> 18 18 <children>
<SplitPane dividerPositions="0.536" layoutX="127.0" layoutY="74.0" orientation="VERTICAL" prefHeight="200.0" prefWidth="160.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> 19 19 <SplitPane dividerPositions="0.536" layoutX="127.0" layoutY="74.0" orientation="VERTICAL" prefHeight="200.0" prefWidth="160.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<items> 20 20 <items>
<fx:include source="mapPanel.fxml" /> 21 21 <fx:include source="mapPanel.fxml" />
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0" /> 22 22 <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0" />
</items> 23 23 </items>
</SplitPane> 24 24 </SplitPane>
</children> 25 25 </children>
</AnchorPane> 26 26 </AnchorPane>
</items> 27 27 </items>
</SplitPane> 28 28 </SplitPane>
<Line endX="1101.0" endY="1.1444091796875E-5" layoutX="101.0" layoutY="35.0" startX="-100.0" /> 29 29 <Line endX="1101.0" endY="1.1444091796875E-5" layoutX="101.0" layoutY="35.0" startX="-100.0" />
</children> 30 30 </children>