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 Side-by-side Diff

src/main/kotlin/application/VisualisationChart.kt View file @ 513c034
  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 @ 513c034
  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?> {
  198 + val allStatus: ArrayList<MessageData?> = vessel.getAllStatus()
  199 + allStatus.sortBy { (it as Status).value }
  200 +
  201 + return allStatus
  202 + }
  203 +
  204 + private fun populatLength(vessel: Vessel): ArrayList<MessageData?> {
  205 + val allLength: ArrayList<MessageData?> = vessel.getAllLength()
  206 + allLength.sortBy { (it as Length).value }
  207 +
  208 + return allLength
  209 + }
  210 +
  211 + private fun populatWidth(vessel: Vessel): ArrayList<MessageData?> {
  212 + val allWidth: ArrayList<MessageData?> = vessel.getAllWidth()
  213 + allWidth.sortBy { (it as Width).value }
  214 +
  215 + return allWidth
  216 + }
  217 +
  218 + private fun populatDraft(vessel: Vessel): ArrayList<MessageData?> {
  219 + val allDraft: ArrayList<MessageData?> = vessel.getAllDraft()
  220 + allDraft.sortBy { (it as Draft).value }
  221 +
  222 + return allDraft
  223 + }
  224 +
  225 + private fun populatCargo(vessel: Vessel): ArrayList<MessageData?> {
  226 + val allCargo: ArrayList<MessageData?> = vessel.getAllCargo()
  227 + allCargo.sortBy { (it as Cargo).value }
  228 +
  229 + return allCargo
  230 + }
  231 +
  232 + private fun populateDataList(vessel: Vessel) {
  233 + val data = arrayListOf<Pair<String, ArrayList<MessageData?>>>()
  234 +
  235 + timeData = populateTime(vessel)
  236 +
  237 + data.add(Pair("Latitude", populateLatitude(vessel)))
  238 +
  239 + data.add(Pair("Longitude", populateLongitude(vessel)))
  240 +
  241 + data.add(Pair("Speed Over Ground", populateSpeedOverGround(vessel)))
  242 +
  243 + data.add(Pair("Course Over Ground", populateCourseOverGround(vessel)))
  244 +
  245 + data.add(Pair("Heading", populateHeading(vessel)))
  246 +
  247 + data.add(Pair("Vessel Name", populatVesselName(vessel)))
  248 +
  249 + data.add(Pair("IMO", populatIMO(vessel)))
  250 +
  251 + data.add(Pair("Call Sign", populatCallSign(vessel)))
  252 +
  253 + data.add(Pair("Vessel Type", populatVesselType(vessel)))
  254 +
  255 + data.add(Pair("Status", populatStatus(vessel)))
  256 +
  257 + data.add(Pair("Length", populatLength(vessel)))
  258 +
  259 + data.add(Pair("Width", populatWidth(vessel)))
  260 +
  261 + data.add(Pair("Draft", populatDraft(vessel)))
  262 +
  263 + data.add(Pair("Cargo", populatCargo(vessel)))
  264 +
  265 + dataList.addAll(data)
  266 + }
  267 +
  268 + override fun onValueChanged(newValue: Vessel) {
  269 + dataList.clear()
  270 + populateDataList(newValue)
  271 +
  272 + }
  273 +
  274 +}
src/main/kotlin/application/controller/VesselListPanelController.kt View file @ 513c034
... ... @@ -17,7 +17,7 @@
17 17 var shipListView: ListView<Int> = ListView()
18 18  
19 19  
20   - var shipList: ObservableList<Int> = FXCollections.observableArrayList()
  20 + private var shipList: ObservableList<Int> = FXCollections.observableArrayList()
21 21  
22 22 override fun initialize(location: URL?, resources: ResourceBundle?) {
23 23 shipListView.items = shipList
src/main/kotlin/application/model/Message.kt View file @ 513c034
... ... @@ -3,34 +3,27 @@
3 3 import java.time.LocalDateTime
4 4  
5 5 class Message(split: List<String>) {
6   - val mmsi: Int? = split[0].toIntOrNull()
7   - val time: LocalDateTime = LocalDateTime.parse(split[1])
8   - val latitude: Double? = split[2].toDoubleOrNull()
9   - val longitude: Double? = split[3].toDoubleOrNull()
10   - val speedOverGround: Double? = split[4].toDoubleOrNull()
11   - val courseOverGround: Double? = split[5].toDoubleOrNull()
12   - val heading: Int? = split[6].toIntOrNull()
13   - val vesselName: String? = split[7]
14   - val imo: String? = split[8]
15   - val callSign: String? = split[9]
16   - val vesselType: Int? = split[10].toIntOrNull()
17   - val status: String? = split[11]
18   - val length: Double? = split[12].toDoubleOrNull()
19   - val width: Double? = split[13].toDoubleOrNull()
20   - val draft: Double? = split[14].toDoubleOrNull()
21   - val cargo: Int? = split[15].toIntOrNull()
  6 + val mmsi = MMSI(split[0].toIntOrNull())
  7 + val time = Time(LocalDateTime.parse(split[1]))
  8 + val latitude = Latitude(split[2].toDoubleOrNull())
  9 + val longitude = Longitude(split[3].toDoubleOrNull())
  10 + val speedOverGround = SpeedOverGround(split[4].toDoubleOrNull())
  11 + val courseOverGround = CourseOverGround(split[5].toDoubleOrNull())
  12 + val heading = Heading(split[6].toDoubleOrNull())
  13 + val vesselName = VesselName(split[7])
  14 + val imo = IMO(split[8])
  15 + val callSign = CallSign(split[9])
  16 + val vesselType = VesselType(split[10].toIntOrNull())
  17 + val status = Status(split[11])
  18 + val length = Length(split[12].toDoubleOrNull())
  19 + val width = Width(split[13].toDoubleOrNull())
  20 + val draft = Draft(split[14].toDoubleOrNull())
  21 + val cargo = Cargo(split[15].toIntOrNull())
22 22  
23   - fun getHexColorStroke(): String{
24   - var hex = Integer.toHexString(this.mmsi!!)
25   - if (hex.length > 6){
26   - hex = hex.substring(hex.length - 6)
27   - }
28   - return hex
29   - }
30 23  
31   - fun getHexColorFill(): String{
32   - var hex = Integer.toHexString(this.mmsi!! - 50)
33   - if (hex.length > 6){
  24 + fun getHexColorStroke(): String {
  25 + var hex = Integer.toHexString(this.mmsi.value!!)
  26 + if (hex.length > 6) {
34 27 hex = hex.substring(hex.length - 6)
35 28 }
36 29 return hex
src/main/kotlin/application/model/MessageData.kt View file @ 513c034
  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()
  123 + }
  124 +
  125 + override fun visit(messageData: VesselName) {
  126 + value = messageData.value.toString()
  127 + }
  128 +
  129 + override fun visit(messageData: IMO) {
  130 + value = messageData.value.toString()
  131 + }
  132 +
  133 + override fun visit(messageData: CallSign) {
  134 + value = messageData.value.toString()
  135 + }
  136 +
  137 + override fun visit(messageData: VesselType) {
  138 + value = messageData.value.toString()
  139 + }
  140 +
  141 + override fun visit(messageData: Status) {
  142 + value = messageData.value.toString()
  143 + }
  144 +
  145 + override fun visit(messageData: Length) {
  146 + value = messageData.value.toString()
  147 + }
  148 +
  149 + override fun visit(messageData: Width) {
  150 + value = messageData.value.toString()
  151 + }
  152 +
  153 + override fun visit(messageData: Draft) {
  154 + value = messageData.value.toString()
  155 + }
  156 +
  157 + override fun visit(messageData: Cargo) {
  158 + value = messageData.value.toString()
  159 + }
  160 +
  161 +}
src/main/kotlin/application/model/Vessel.kt View file @ 513c034
1 1 package application.model
2 2  
3 3 import java.time.LocalDateTime
  4 +import java.time.ZoneOffset
4 5 import java.util.*
5 6  
6 7  
7   -class Vessel(val mmsi : Int?) {
  8 +class Vessel(val mmsi: Int?) {
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 + }
  146 +
9 147 }
src/main/kotlin/application/model/VesselGenerator.kt View file @ 513c034
... ... @@ -13,10 +13,10 @@
13 13 if (arrayMessage[0].toIntOrNull() !== null) {
14 14 val message = Message(arrayMessage)
15 15 messages.add(message)
16   - if (!vessels.containsKey(message.mmsi)){
17   - vessels[message.mmsi] = Vessel(message.mmsi!!)
  16 + if (!vessels.containsKey(message.mmsi.value)){
  17 + vessels[message.mmsi.value] = Vessel(message.mmsi.value!!)
18 18 }
19   - vessels[message.mmsi]?.messages?.set(message.time, message)
  19 + vessels[message.mmsi.value]?.messages?.set(message.time.value, message)
20 20 }
21 21  
22 22 }
src/main/kotlin/map/MapDisplayer.kt View file @ 513c034
... ... @@ -39,7 +39,7 @@
39 39 clearMap(map)
40 40 observableVessel.vessels.forEach { (_, value) ->
41 41 value.messages.forEach { (_, message) ->
42   - map.execScript("L.circleMarker([${message.latitude}, ${message.longitude}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}).addTo(myMap)")
  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  
... ... @@ -48,10 +48,10 @@
48 48 clearMap(map)
49 49 observableVessel.vessels.forEach { (_, value) ->
50 50 value.messages.forEach { (_, message) ->
51   - if (selectedMMSI == message.mmsi) {
52   - map.execScript("L.circleMarker([${message.latitude}, ${message.longitude}], {renderer: myRenderer, radius: 2, color: '#ff4040'}).addTo(myMap)")
  51 + if (selectedMMSI == message.mmsi.value) {
  52 + map.execScript("L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 2, color: '#ff4040'}).addTo(myMap)")
53 53 } else {
54   - map.execScript("L.circleMarker([${message.latitude}, ${message.longitude}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}).addTo(myMap)")
  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 }
... ... @@ -61,7 +61,7 @@
61 61 clearMap(map)
62 62 observableVessel.vessels.forEach { (_, value) ->
63 63 value.messages.forEach { (_, message) ->
64   - map.execScript("markerClusters.addLayer(L.circleMarker([${message.latitude}, ${message.longitude}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}));")
  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 }
67 67 map.execScript("myMap.addLayer(markerClusters);")
68 68  
... ... @@ -71,10 +71,10 @@
71 71 clearMap(map)
72 72 observableVessel.vessels.forEach { (_, value) ->
73 73 value.messages.forEach { (_, message) ->
74   - if (selectedMMSI == message.mmsi) {
75   - map.execScript("L.circleMarker([${message.latitude}, ${message.longitude}], {renderer: myRenderer, radius: 2, color: '#ff4040'}).addTo(myMap);")
  74 + if (selectedMMSI == message.mmsi.value) {
  75 + map.execScript("L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 2, color: '#ff4040'}).addTo(myMap);")
76 76 } else {
77   - map.execScript("markerClusters.addLayer(L.circleMarker([${message.latitude}, ${message.longitude}], {renderer: myRenderer, radius: 0.01, color: '#${message.getHexColorStroke()}'}));")
  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 }
... ... @@ -85,7 +85,7 @@
85 85 clearMap(map)
86 86 observableVessel.vessels.forEach { (_, value) ->
87 87 value.messages.forEach { (_, message) ->
88   - map.execScript("heatLayer.addLatLng([${message.latitude}, ${message.longitude}]);")
  88 + map.execScript("heatLayer.addLatLng([${message.latitude.value}, ${message.longitude.value}]);")
89 89 }
90 90 }
91 91 }
92 92  
... ... @@ -94,10 +94,10 @@
94 94 clearMap(map)
95 95 observableVessel.vessels.forEach { (_, value) ->
96 96 value.messages.forEach { (_, message) ->
97   - if (selectedMMSI == message.mmsi) {
98   - map.execScript("L.circleMarker([${message.latitude}, ${message.longitude}], {renderer: myRenderer, radius: 2, color: '#ff4040'}).addTo(myMap);")
  97 + if (selectedMMSI == message.mmsi.value) {
  98 + map.execScript("L.circleMarker([${message.latitude.value}, ${message.longitude.value}], {renderer: myRenderer, radius: 2, color: '#ff4040'}).addTo(myMap);")
99 99 } else {
100   - map.execScript("heatLayer.addLatLng([${message.latitude}, ${message.longitude}]);")
  100 + map.execScript("heatLayer.addLatLng([${message.latitude.value}, ${message.longitude.value}]);")
101 101 }
102 102 }
103 103 }
src/main/resources/gui/dataPanel.fxml View file @ 513c034
  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>
  28 + </SplitPane>
  29 +</AnchorPane>
src/main/resources/gui/vesselListPanel.fxml View file @ 513c034
... ... @@ -8,7 +8,7 @@
8 8 <top>
9 9 <AnchorPane prefHeight="33.0" prefWidth="200.0" BorderPane.alignment="CENTER">
10 10 <children>
11   - <Button layoutX="74.0" layoutY="2.0" mnemonicParsing="false" text="Button" fx:id="buton" />
  11 + <Button layoutX="74.0" layoutY="2.0" mnemonicParsing="false" text="Button" fx:id="button"/>
12 12 </children></AnchorPane>
13 13 </top>
14 14 <center>
src/main/resources/gui/windows.fxml View file @ 513c034
1 1 <?xml version="1.0" encoding="UTF-8"?>
2 2  
3   -<?import javafx.scene.control.*?>
  3 +<?import javafx.scene.control.SplitPane?>
4 4 <?import javafx.scene.layout.*?>
5   -<?import javafx.scene.shape.*?>
6   -
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">
  5 +<?import javafx.scene.shape.Line?>
  6 +<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="900.0"
  7 + prefWidth="1200.0" xmlns="http://javafx.com/javafx/8.0.241" xmlns:fx="http://javafx.com/fxml/1">
8 8 <children>
9   - <fx:include source="menuBar.fxml" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
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">
  9 + <fx:include source="menuBar.fxml" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
  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">
11 14 <items>
12 15 <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
13 16 <children>
14   - <fx:include source="vesselListPanel.fxml" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
  17 + <fx:include source="vesselListPanel.fxml" AnchorPane.leftAnchor="0.0"
  18 + AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"/>
15 19 </children>
16 20 </AnchorPane>
17 21 <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
18 22 <children>
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">
  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">
20 26 <items>
21   - <fx:include source="mapPanel.fxml" />
22   - <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0" />
  27 + <fx:include source="mapPanel.fxml"/>
  28 + <fx:include source="dataPanel.fxml"/>
23 29 </items>
24 30 </SplitPane>
25 31 </children>
26 32 </AnchorPane>
27 33 </items>
28 34 </SplitPane>
29   - <Line endX="1101.0" endY="1.1444091796875E-5" layoutX="101.0" layoutY="35.0" startX="-100.0" />
  35 + <Line endX="1101.0" endY="1.1444091796875E-5" layoutX="101.0" layoutY="35.0" startX="-100.0"/>
30 36 </children>
31 37 </AnchorPane>