Commit 513c0341c54e1d2ef6dbd1eeb624830faab35ad7

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

add chart

Showing 11 changed files with 670 additions and 55 deletions Inline Diff

src/main/kotlin/application/VisualisationChart.kt View file @ 513c034
File was created 1 package application
2
3 import javafx.scene.chart.Axis
4 import javafx.scene.chart.ScatterChart
5
src/main/kotlin/application/controller/DataPanelController.kt View file @ 513c034
File was created 1 package application.controller
2
3 import application.model.*
4 import javafx.collections.FXCollections
5 import javafx.collections.ObservableList
6 import javafx.fxml.FXML
7 import javafx.fxml.Initializable
8 import javafx.scene.chart.CategoryAxis
9 import javafx.scene.chart.NumberAxis
10 import javafx.scene.chart.ScatterChart
11 import javafx.scene.chart.XYChart.Data
12 import javafx.scene.chart.XYChart.Series
13 import javafx.scene.control.ListCell
14 import javafx.scene.control.ListView
15 import java.net.URL
16 import java.util.*
17
18
19 class DataPanelController : Initializable, SelectedVesselListener {
20 private var dataList: ObservableList<Pair<String, ArrayList<MessageData?>>> = FXCollections.observableArrayList()
21 private lateinit var timeData: ArrayList<MessageData?>
22
23 @FXML
24 var dataListView = ListView<Pair<String, ArrayList<MessageData?>>>()
25
26 @FXML
27 var xaxisNumber: CategoryAxis = CategoryAxis()
28
29 @FXML
30 var yaxisNumber: NumberAxis = NumberAxis()
31
32 @FXML
33 lateinit var scatterChartNumber: ScatterChart<String, Number>
34
35 @FXML
36 var xaxisCategory: CategoryAxis = CategoryAxis()
37
38 @FXML
39 var yaxisCategory: CategoryAxis = CategoryAxis()
40
41 @FXML
42 lateinit var scatterChartCategory: ScatterChart<String, String>
43
44 override fun initialize(location: URL?, resources: ResourceBundle?) {
45 xaxisNumber.animated = false
46 yaxisNumber.animated = false
47 xaxisCategory.animated = false
48 yaxisCategory.animated = false
49 setObservableSelectedVesselListener()
50 dataListView.items = dataList
51
52
53
54 dataListView.setCellFactory {
55 object : ListCell<Pair<String, ArrayList<MessageData?>>?>() {
56 override fun updateItem(item: Pair<String, ArrayList<MessageData?>>?, empty: Boolean) {
57 super.updateItem(item, empty)
58 text = if (empty) {
59 null
60 } else {
61 item?.first
62 }
63 }
64 }
65 }
66
67 dataListView.selectionModel.selectedItemProperty().addListener { _, _, newValue ->
68 if (newValue == null){
69 scatterChartCategory.data.clear()
70 scatterChartNumber.data.clear()
71 return@addListener
72 }
73 val serieNumber = Series<String, Number>()
74 val serieString = Series<String, String>()
75
76 val getValueVisitorX = GetValueVisitor()
77 val getValueVisitorY = GetValueVisitor()
78
79
80 for (x in 0 until newValue?.second?.size!!) {
81 timeData[x]?.accept(getValueVisitorX)
82 newValue.second[x]?.accept(getValueVisitorY)
83
84 if (getValueVisitorY.value.toDoubleOrNull() == null){
85 serieString.data.add(Data<String, String>(getValueVisitorX.value, getValueVisitorY.value))
86 } else{
87 serieNumber.data.add(Data<String, Number>(getValueVisitorX.value, getValueVisitorY.value.toDouble()))
88 }
89
90 }
91
92 scatterChartNumber.data.clear()
93 scatterChartCategory.data.clear()
94
95 if (getValueVisitorY.value.toDoubleOrNull() == null){
96 serieString.data.add(Data<String, String>(getValueVisitorX.value, getValueVisitorY.value))
97 scatterChartCategory.data.addAll(serieString)
98 setChartCategoryVisible()
99 xaxisCategory.label = "Date"
100 yaxisCategory.label = newValue.first
101 } else{
102 serieNumber.data.add(Data<String, Number>(getValueVisitorX.value, getValueVisitorY.value.toDouble()))
103 scatterChartNumber.data.addAll(serieNumber)
104 setChartNumberVisible()
105 xaxisNumber.label = "Date"
106 yaxisNumber.label = newValue.first
107 }
108
109 }
110
111 }
112
113 private fun setChartCategoryVisible(){
114 scatterChartCategory.isVisible = true
115 scatterChartNumber.isVisible = false
116 }
117
118 private fun setChartNumberVisible(){
119 scatterChartCategory.isVisible = false
120 scatterChartNumber.isVisible = true
121 }
122
123 private fun setObservableSelectedVesselListener() {
124 observableSelectedVessel.listeners.add(this)
125 }
126
127 private fun populateTime(vessel: Vessel): ArrayList<MessageData?> {
128 val allTime: ArrayList<MessageData?> = vessel.getAllTime()
129 allTime.sortBy { (it as Time).value }
130
131 return allTime
132 }
133
134 private fun populateLatitude(vessel: Vessel): ArrayList<MessageData?> {
135 val allLatitude: ArrayList<MessageData?> = vessel.getAllLatitude()
136 allLatitude.sortBy { (it as Latitude).value }
137
138 return allLatitude
139 }
140
141 private fun populateLongitude(vessel: Vessel): ArrayList<MessageData?> {
142 val allLongitude: ArrayList<MessageData?> = vessel.getAllLongitude()
143 allLongitude.sortBy { (it as Longitude).value }
144
145 return allLongitude
146 }
147
148 private fun populateSpeedOverGround(vessel: Vessel): ArrayList<MessageData?> {
149 val allSpeedOverGround: ArrayList<MessageData?> = vessel.getAllSpeedOverGround()
150 allSpeedOverGround.sortBy { (it as SpeedOverGround).value }
151
152 return allSpeedOverGround
153 }
154
155 private fun populateCourseOverGround(vessel: Vessel): ArrayList<MessageData?> {
156 val allCourseOverGround: ArrayList<MessageData?> = vessel.getAllCourseOverGround()
157 allCourseOverGround.sortBy { (it as CourseOverGround).value }
158
159 return allCourseOverGround
160 }
161
162 private fun populateHeading(vessel: Vessel): ArrayList<MessageData?> {
163 val allHeading: ArrayList<MessageData?> = vessel.getAllHeading()
164 allHeading.sortBy { (it as Heading).value }
165
166 return allHeading
167 }
168
169 private fun populatVesselName(vessel: Vessel): ArrayList<MessageData?> {
170 val allVesselName: ArrayList<MessageData?> = vessel.getAllVesselName()
171 allVesselName.sortBy { (it as VesselName).value }
172
173 return allVesselName
174 }
175
176 private fun populatIMO(vessel: Vessel): ArrayList<MessageData?> {
177 val allIMO: ArrayList<MessageData?> = vessel.getAllIMO()
178 allIMO.sortBy { (it as IMO).value }
179
180 return allIMO
181 }
182
183 private fun populatCallSign(vessel: Vessel): ArrayList<MessageData?> {
184 val allCallSign: ArrayList<MessageData?> = vessel.getAllCallSign()
185 allCallSign.sortBy { (it as CallSign).value }
186
187 return allCallSign
188 }
189
190 private fun populatVesselType(vessel: Vessel): ArrayList<MessageData?> {
191 val allVesselType: ArrayList<MessageData?> = vessel.getAllVesselType()
192 allVesselType.sortBy { (it as VesselType).value }
193
194 return allVesselType
195 }
196
197 private fun populatStatus(vessel: Vessel): ArrayList<MessageData?> {
src/main/kotlin/application/controller/VesselListPanelController.kt View file @ 513c034
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.observableVessel 5 5 import application.model.observableVessel
import application.model.observableSelectedVessel 6 6 import application.model.observableSelectedVessel
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.ListView 11 11 import javafx.scene.control.ListView
import java.net.URL 12 12 import java.net.URL
import java.util.* 13 13 import java.util.*
14 14
class VesselListPanelController : Initializable, MessageListener { 15 15 class VesselListPanelController : Initializable, MessageListener {
@FXML 16 16 @FXML
var shipListView: ListView<Int> = ListView() 17 17 var shipListView: ListView<Int> = ListView()
18 18
19 19
var shipList: ObservableList<Int> = FXCollections.observableArrayList() 20 20 private var shipList: ObservableList<Int> = FXCollections.observableArrayList()
21 21
override fun initialize(location: URL?, resources: ResourceBundle?) { 22 22 override fun initialize(location: URL?, resources: ResourceBundle?) {
shipListView.items = shipList 23 23 shipListView.items = shipList
observableVessel.listeners.add(this) 24 24 observableVessel.listeners.add(this)
shipListView.selectionModel.selectedItemProperty().addListener { _, _, newValue -> 25 25 shipListView.selectionModel.selectedItemProperty().addListener { _, _, newValue ->
observableSelectedVessel.vessel = observableVessel.vessels[newValue]!! 26 26 observableSelectedVessel.vessel = observableVessel.vessels[newValue]!!
} 27 27 }
} 28 28 }
29 29
src/main/kotlin/application/model/Message.kt View file @ 513c034
package application.model 1 1 package application.model
2 2
import java.time.LocalDateTime 3 3 import java.time.LocalDateTime
4 4
class Message(split: List<String>) { 5 5 class Message(split: List<String>) {
val mmsi: Int? = split[0].toIntOrNull() 6 6 val mmsi = MMSI(split[0].toIntOrNull())
val time: LocalDateTime = LocalDateTime.parse(split[1]) 7 7 val time = Time(LocalDateTime.parse(split[1]))
val latitude: Double? = split[2].toDoubleOrNull() 8 8 val latitude = Latitude(split[2].toDoubleOrNull())
val longitude: Double? = split[3].toDoubleOrNull() 9 9 val longitude = Longitude(split[3].toDoubleOrNull())
val speedOverGround: Double? = split[4].toDoubleOrNull() 10 10 val speedOverGround = SpeedOverGround(split[4].toDoubleOrNull())
val courseOverGround: Double? = split[5].toDoubleOrNull() 11 11 val courseOverGround = CourseOverGround(split[5].toDoubleOrNull())
val heading: Int? = split[6].toIntOrNull() 12 12 val heading = Heading(split[6].toDoubleOrNull())
val vesselName: String? = split[7] 13 13 val vesselName = VesselName(split[7])
val imo: String? = split[8] 14 14 val imo = IMO(split[8])
val callSign: String? = split[9] 15 15 val callSign = CallSign(split[9])
val vesselType: Int? = split[10].toIntOrNull() 16 16 val vesselType = VesselType(split[10].toIntOrNull())
val status: String? = split[11] 17 17 val status = Status(split[11])
val length: Double? = split[12].toDoubleOrNull() 18 18 val length = Length(split[12].toDoubleOrNull())
val width: Double? = split[13].toDoubleOrNull() 19 19 val width = Width(split[13].toDoubleOrNull())
val draft: Double? = split[14].toDoubleOrNull() 20 20 val draft = Draft(split[14].toDoubleOrNull())
val cargo: Int? = split[15].toIntOrNull() 21 21 val cargo = Cargo(split[15].toIntOrNull())
22 22
fun getHexColorStroke(): String{ 23
var hex = Integer.toHexString(this.mmsi!!) 24
if (hex.length > 6){ 25
hex = hex.substring(hex.length - 6) 26
} 27
return hex 28
} 29
30 23
fun getHexColorFill(): String{ 31 24 fun getHexColorStroke(): String {
var hex = Integer.toHexString(this.mmsi!! - 50) 32 25 var hex = Integer.toHexString(this.mmsi.value!!)
if (hex.length > 6){ 33 26 if (hex.length > 6) {
hex = hex.substring(hex.length - 6) 34 27 hex = hex.substring(hex.length - 6)
} 35 28 }
return hex 36 29 return hex
} 37 30 }
} 38 31 }
src/main/kotlin/application/model/MessageData.kt View file @ 513c034
File was created 1 package application.model
2
3 import java.time.LocalDateTime
4
5 interface MessageDataVisitor {
6 fun visit(messageData: MMSI)
7 fun visit(messageData: Time)
8 fun visit(messageData: Latitude)
9 fun visit(messageData: Longitude)
10 fun visit(messageData: SpeedOverGround)
11 fun visit(messageData: CourseOverGround)
12 fun visit(messageData: Heading)
13 fun visit(messageData: VesselName)
14 fun visit(messageData: IMO)
15 fun visit(messageData: CallSign)
16 fun visit(messageData: VesselType)
17 fun visit(messageData: Status)
18 fun visit(messageData: Length)
19 fun visit(messageData: Width)
20 fun visit(messageData: Draft)
21 fun visit(messageData: Cargo)
22 }
23
24 interface MessageData {
25
26 fun accept(visitor: MessageDataVisitor)
27
28 }
29
30 data class MMSI(val value: Int?) : MessageData {
31 override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this)
32 }
33
34 data class Time(val value: LocalDateTime) : MessageData {
35 override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this)
36 }
37
38 data class Latitude(val value: Double?) : MessageData {
39 override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this)
40 }
41
42 data class Longitude(val value: Double?) : MessageData {
43 override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this)
44 }
45
46 data class SpeedOverGround(val value: Double?) : MessageData {
47 override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this)
48 }
49
50 data class CourseOverGround(val value: Double?) : MessageData {
51 override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this)
52 }
53
54 data class Heading(val value: Double?) : MessageData {
55 override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this)
56 }
57
58 data class VesselName(val value: String?) : MessageData {
59 override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this)
60 }
61
62 data class IMO(val value: String?) : MessageData {
63 override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this)
64 }
65
66 data class CallSign(val value: String?) : MessageData {
67 override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this)
68 }
69
70 data class VesselType(val value: Int?) : MessageData {
71 override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this)
72 }
73
74 data class Status(val value: String?) : MessageData {
75 override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this)
76 }
77
78 data class Length(val value: Double?) : MessageData {
79 override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this)
80 }
81
82 data class Width(val value: Double?) : MessageData {
83 override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this)
84 }
85
86 data class Draft(val value: Double?) : MessageData {
87 override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this)
88 }
89
90 data class Cargo(val value: Int?) : MessageData {
91 override fun accept(visitor: MessageDataVisitor) = visitor.visit(messageData = this)
92 }
93
94 class GetValueVisitor() : MessageDataVisitor {
95 var value: String = ""
96
97 override fun visit(messageData: MMSI) {
98 value = messageData.value.toString()
99 }
100
101 override fun visit(messageData: Time) {
102 value = messageData.value.toString()
103 }
104
105 override fun visit(messageData: Latitude) {
106 value = messageData.value.toString()
107 }
108
109 override fun visit(messageData: Longitude) {
110 value = messageData.value.toString()
111 }
112
113 override fun visit(messageData: SpeedOverGround) {
114 value = messageData.value.toString()
115 }
116
117 override fun visit(messageData: CourseOverGround) {
118 value = messageData.value.toString()
119 }
120
121 override fun visit(messageData: Heading) {
122 value = messageData.value.toString()
src/main/kotlin/application/model/Vessel.kt View file @ 513c034
package application.model 1 1 package application.model
2 2
import java.time.LocalDateTime 3 3 import java.time.LocalDateTime
4 import java.time.ZoneOffset
import java.util.* 4 5 import java.util.*
5 6
6 7
class Vessel(val mmsi : Int?) { 7 8 class Vessel(val mmsi: Int?) {
val messages: SortedMap<LocalDateTime, Message> = sortedMapOf() 8 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
21 fun getAllTime(): ArrayList<MessageData?> {
22 val timeList = arrayListOf<MessageData?>()
23 messages.forEach {
24 timeList.add(it.value.time)
25 }
26
27 return timeList
28 }
29
30 fun getAllLatitude(): ArrayList<MessageData?> {
31 val latitudeList = arrayListOf<MessageData?>()
32 messages.forEach {
33 latitudeList.add(it.value.latitude)
34 }
35
36 return latitudeList
37 }
38
39 fun getAllLongitude(): ArrayList<MessageData?> {
40 val longitudeList = arrayListOf<MessageData?>()
41 messages.forEach {
42 longitudeList.add(it.value.longitude)
43 }
44
45 return longitudeList
46 }
47
48 fun getAllSpeedOverGround(): ArrayList<MessageData?> {
49 val speedOverGroundList = arrayListOf<MessageData?>()
50 messages.forEach {
51 speedOverGroundList.add(it.value.speedOverGround)
52 }
53
54 return speedOverGroundList
55 }
56
57 fun getAllCourseOverGround(): ArrayList<MessageData?> {
58 val res = arrayListOf<MessageData?>()
59 messages.forEach {
60 res.add(it.value.courseOverGround)
61 }
62
63 return res
64 }
65
66 fun getAllHeading(): ArrayList<MessageData?> {
67 val res = arrayListOf<MessageData?>()
68 messages.forEach {
69 res.add(it.value.heading)
70 }
71
72 return res
73 }
74
75 fun getAllVesselName(): ArrayList<MessageData?> {
76 val res = arrayListOf<MessageData?>()
77 messages.forEach {
78 res.add(it.value.vesselName)
79 }
80 return res
81 }
82
83 fun getAllIMO(): ArrayList<MessageData?> {
84 val res = arrayListOf<MessageData?>()
85 messages.forEach {
86 res.add(it.value.imo)
87 }
88 return res
89 }
90
91 fun getAllCallSign(): ArrayList<MessageData?> {
92 val res = arrayListOf<MessageData?>()
93 messages.forEach {
94 res.add(it.value.callSign)
95 }
96 return res
97 }
98
99 fun getAllVesselType(): ArrayList<MessageData?> {
100 val res = arrayListOf<MessageData?>()
101 messages.forEach {
102 res.add(it.value.vesselType)
103 }
104 return res
105 }
106
107 fun getAllStatus(): ArrayList<MessageData?> {
108 val res = arrayListOf<MessageData?>()
109 messages.forEach {
110 res.add(it.value.status)
111 }
112 return res
113 }
114
115 fun getAllLength(): ArrayList<MessageData?> {
116 val res = arrayListOf<MessageData?>()
117 messages.forEach {
118 res.add(it.value.length)
119 }
120 return res
121 }
122
123 fun getAllWidth(): ArrayList<MessageData?> {
124 val res = arrayListOf<MessageData?>()
125 messages.forEach {
126 res.add(it.value.width)
127 }
128 return res
129 }
130
131 fun getAllDraft(): ArrayList<MessageData?> {
132 val res = arrayListOf<MessageData?>()
133 messages.forEach {
134 res.add(it.value.draft)
135 }
136 return res
137 }
138
139 fun getAllCargo(): ArrayList<MessageData?> {
140 val res = arrayListOf<MessageData?>()
141 messages.forEach {
142 res.add(it.value.cargo)
143 }
144 return res
145 }
src/main/kotlin/application/model/VesselGenerator.kt View file @ 513c034
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.value)){
vessels[message.mmsi] = Vessel(message.mmsi!!) 17 17 vessels[message.mmsi.value] = Vessel(message.mmsi.value!!)
} 18 18 }
vessels[message.mmsi]?.messages?.set(message.time, message) 19 19 vessels[message.mmsi.value]?.messages?.set(message.time.value, message)
} 20 20 }
21 21
} 22 22 }
23 23
src/main/kotlin/map/MapDisplayer.kt View file @ 513c034
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)
} 9 9 }
10 10
fun clearMapCluster(map: LeafletMapView) { 11 11 fun clearMapCluster(map: LeafletMapView) {
map.execScript( 12 12 map.execScript(
""" 13 13 """
|myMap.removeLayer(markerClusters); 14 14 |myMap.removeLayer(markerClusters);
|var markerClusters = L.markerClusterGroup({spiderfyOnMaxZoom: false, disableClusteringAtZoom: 10}); 15 15 |var markerClusters = L.markerClusterGroup({spiderfyOnMaxZoom: false, disableClusteringAtZoom: 10});
""".trimMargin() 16 16 """.trimMargin()
) 17 17 )
} 18 18 }
19 19
fun clearMapCanvas(map: LeafletMapView) { 20 20 fun clearMapCanvas(map: LeafletMapView) {
map.execScript( 21 21 map.execScript(
""" 22 22 """
|myRenderer.removeFrom(myMap); 23 23 |myRenderer.removeFrom(myMap);
|var myRenderer = L.canvas({ padding: 0.5 }); 24 24 |var myRenderer = L.canvas({ padding: 0.5 });
""".trimMargin() 25 25 """.trimMargin()
) 26 26 )
} 27 27 }
28 28
fun clearHeatMap(map: LeafletMapView) { 29 29 fun clearHeatMap(map: LeafletMapView) {
map.execScript( 30 30 map.execScript(
""" 31 31 """
|heatLayer.removeFrom(myMap); 32 32 |heatLayer.removeFrom(myMap);
|var heatLayer = L.heatLayer([]).addTo(myMap); 33 33 |var heatLayer = L.heatLayer([]).addTo(myMap);
""".trimMargin() 34 34 """.trimMargin()
) 35 35 )
} 36 36 }
37 37
fun displayAllMessageOnMap(map: LeafletMapView) { 38 38 fun displayAllMessageOnMap(map: LeafletMapView) {
clearMap(map) 39 39 clearMap(map)
observableVessel.vessels.forEach { (_, value) -> 40 40 observableVessel.vessels.forEach { (_, value) ->
value.messages.forEach { (_, message) -> 41 41 value.messages.forEach { (_, message) ->
map.execScript("L.circleMarker([${message.latitude}, ${message.longitude}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}).addTo(myMap)") 42 42 map.execScript("L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}).addTo(myMap)")
} 43 43 }
} 44 44 }
} 45 45 }
46 46
fun displayAllMessageOnMap(map: LeafletMapView, selectedMMSI: Int) { 47 47 fun displayAllMessageOnMap(map: LeafletMapView, selectedMMSI: Int) {
clearMap(map) 48 48 clearMap(map)
observableVessel.vessels.forEach { (_, value) -> 49 49 observableVessel.vessels.forEach { (_, value) ->
value.messages.forEach { (_, message) -> 50 50 value.messages.forEach { (_, message) ->
if (selectedMMSI == message.mmsi) { 51 51 if (selectedMMSI == message.mmsi.value) {
map.execScript("L.circleMarker([${message.latitude}, ${message.longitude}], {renderer: myRenderer, radius: 2, color: '#ff4040'}).addTo(myMap)") 52 52 map.execScript("L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 2, color: '#ff4040'}).addTo(myMap)")
} else { 53 53 } else {
map.execScript("L.circleMarker([${message.latitude}, ${message.longitude}], {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 }
59 59
fun displayClusterMessageOnMap(map: LeafletMapView) { 60 60 fun displayClusterMessageOnMap(map: LeafletMapView) {
clearMap(map) 61 61 clearMap(map)
observableVessel.vessels.forEach { (_, value) -> 62 62 observableVessel.vessels.forEach { (_, value) ->
value.messages.forEach { (_, message) -> 63 63 value.messages.forEach { (_, message) ->
map.execScript("markerClusters.addLayer(L.circleMarker([${message.latitude}, ${message.longitude}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}));") 64 64 map.execScript("markerClusters.addLayer(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}));")
} 65 65 }
} 66 66 }
map.execScript("myMap.addLayer(markerClusters);") 67 67 map.execScript("myMap.addLayer(markerClusters);")
} 68 68 }
69 69
fun displayClusterMessageOnMap(map: LeafletMapView, selectedMMSI: Int) { 70 70 fun displayClusterMessageOnMap(map: LeafletMapView, selectedMMSI: Int) {
clearMap(map) 71 71 clearMap(map)
observableVessel.vessels.forEach { (_, value) -> 72 72 observableVessel.vessels.forEach { (_, value) ->
value.messages.forEach { (_, message) -> 73 73 value.messages.forEach { (_, message) ->
if (selectedMMSI == message.mmsi) { 74 74 if (selectedMMSI == message.mmsi.value) {
map.execScript("L.circleMarker([${message.latitude}, ${message.longitude}], {renderer: myRenderer, radius: 2, color: '#ff4040'}).addTo(myMap);") 75 75 map.execScript("L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 2, color: '#ff4040'}).addTo(myMap);")
} else { 76 76 } else {
map.execScript("markerClusters.addLayer(L.circleMarker([${message.latitude}, ${message.longitude}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}));") 77 77 map.execScript("markerClusters.addLayer(L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}));")
} 78 78 }
} 79 79 }
} 80 80 }
map.execScript("myMap.addLayer(markerClusters);") 81 81 map.execScript("myMap.addLayer(markerClusters);")
} 82 82 }
83 83
fun displayHeatMapOnMap(map: LeafletMapView) { 84 84 fun displayHeatMapOnMap(map: LeafletMapView) {
clearMap(map) 85 85 clearMap(map)
observableVessel.vessels.forEach { (_, value) -> 86 86 observableVessel.vessels.forEach { (_, value) ->
value.messages.forEach { (_, message) -> 87 87 value.messages.forEach { (_, message) ->
map.execScript("heatLayer.addLatLng([${message.latitude}, ${message.longitude}]);") 88 88 map.execScript("heatLayer.addLatLng([${message.latitude.value}, ${message.longitude.value}]);")
} 89 89 }
} 90 90 }
} 91 91 }
92 92
fun displayHeatMapOnMap(map: LeafletMapView, selectedMMSI: Int) { 93 93 fun displayHeatMapOnMap(map: LeafletMapView, selectedMMSI: Int) {
clearMap(map) 94 94 clearMap(map)
observableVessel.vessels.forEach { (_, value) -> 95 95 observableVessel.vessels.forEach { (_, value) ->
value.messages.forEach { (_, message) -> 96 96 value.messages.forEach { (_, message) ->
if (selectedMMSI == message.mmsi) { 97 97 if (selectedMMSI == message.mmsi.value) {
map.execScript("L.circleMarker([${message.latitude}, ${message.longitude}], {renderer: myRenderer, radius: 2, color: '#ff4040'}).addTo(myMap);") 98 98 map.execScript("L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 2, color: '#ff4040'}).addTo(myMap);")
} else { 99 99 } else {
map.execScript("heatLayer.addLatLng([${message.latitude}, ${message.longitude}]);") 100 100 map.execScript("heatLayer.addLatLng([${message.latitude.value}, ${message.longitude.value}]);")
} 101 101 }
} 102 102 }
} 103 103 }
map.execScript("myMap.addLayer(markerClusters);") 104 104 map.execScript("myMap.addLayer(markerClusters);")
} 105 105 }
src/main/resources/gui/dataPanel.fxml View file @ 513c034
File was created 1 <?xml version="1.0" encoding="UTF-8"?>
2
3 <?import javafx.scene.chart.*?>
4 <?import javafx.scene.control.*?>
5 <?import javafx.scene.layout.*?>
6
7 <AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.241" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.controller.DataPanelController">
8 <SplitPane dividerPositions="0.1705685618729097" prefHeight="212.0" prefWidth="254.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
9 <ListView fx:id="dataListView" layoutX="-73.0" layoutY="14.0" prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
10 <StackPane prefHeight="150.0" prefWidth="200.0">
11 <ScatterChart fx:id="scatterChartNumber">
12 <xAxis>
13 <CategoryAxis side="BOTTOM" fx:id="xaxisNumber" />
14 </xAxis>
15 <yAxis>
16 <NumberAxis fx:id="yaxisNumber" side="LEFT" />
17 </yAxis>
18 </ScatterChart>
19 <ScatterChart fx:id="scatterChartCategory" visible="false">
20 <xAxis>
21 <CategoryAxis side="BOTTOM" fx:id="xaxisCategory" />
22 </xAxis>
23 <yAxis>
24 <CategoryAxis fx:id="yaxisCategory" side="LEFT" />
25 </yAxis>
26 </ScatterChart>
27 </StackPane>
src/main/resources/gui/vesselListPanel.fxml View file @ 513c034
<?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.*?>
5 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.VesselListPanelController"> 6 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 7
<top> 8 8 <top>
<AnchorPane prefHeight="33.0" prefWidth="200.0" BorderPane.alignment="CENTER"> 9 9 <AnchorPane prefHeight="33.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<children> 10 10 <children>
<Button layoutX="74.0" layoutY="2.0" mnemonicParsing="false" text="Button" fx:id="buton" /> 11 11 <Button layoutX="74.0" layoutY="2.0" mnemonicParsing="false" text="Button" fx:id="button"/>
</children></AnchorPane> 12 12 </children></AnchorPane>
</top> 13 13 </top>
<center> 14 14 <center>
<ListView fx:id="shipListView" prefHeight="105.0" prefWidth="200.0" /> 15 15 <ListView fx:id="shipListView" prefHeight="105.0" prefWidth="200.0" />
src/main/resources/gui/windows.fxml View file @ 513c034
<?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.SplitPane?>
<?import javafx.scene.layout.*?> 4 4 <?import javafx.scene.layout.*?>
<?import javafx.scene.shape.*?> 5 5 <?import javafx.scene.shape.Line?>
6 6 <AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="900.0"
<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 prefWidth="1200.0" xmlns="http://javafx.com/javafx/8.0.241" 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"
<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 AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"/>
11 <SplitPane dividerPositions="0.13772954924874792" layoutY="39.0" prefHeight="865.0" prefWidth="1194.0"
12 AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
13 AnchorPane.topAnchor="35.0">
<items> 11 14 <items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0"> 12 15 <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children> 13 16 <children>
<fx:include source="vesselListPanel.fxml" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" /> 14 17 <fx:include source="vesselListPanel.fxml" AnchorPane.leftAnchor="0.0"
18 AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"/>
</children> 15 19 </children>
</AnchorPane> 16 20 </AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0"> 17 21 <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children> 18 22 <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 23 <SplitPane dividerPositions="0.536" layoutX="127.0" layoutY="74.0" orientation="VERTICAL"
24 prefHeight="200.0" prefWidth="160.0" AnchorPane.bottomAnchor="0.0"
25 AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<items> 20 26 <items>
<fx:include source="mapPanel.fxml" /> 21 27 <fx:include source="mapPanel.fxml"/>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0" /> 22 28 <fx:include source="dataPanel.fxml"/>
</items> 23 29 </items>
</SplitPane> 24 30 </SplitPane>
</children> 25 31 </children>
</AnchorPane> 26 32 </AnchorPane>
</items> 27 33 </items>
</SplitPane> 28 34 </SplitPane>
<Line endX="1101.0" endY="1.1444091796875E-5" layoutX="101.0" layoutY="35.0" startX="-100.0" /> 29 35 <Line endX="1101.0" endY="1.1444091796875E-5" layoutX="101.0" layoutY="35.0" startX="-100.0"/>
</children> 30 36 </children>
</AnchorPane> 31 37 </AnchorPane>
32 38